Skip to main content
Glama
focusDictionary.ts2.61 kB
import { effect, type Injector, type Signal, signal } from '@angular/core'; import { MessageKey } from '@intlayer/editor'; import type { KeyPath } from '@intlayer/types'; import { createSharedComposable } from './createSharedComposable'; import { useCrossFrameState } from './useCrossFrameState'; export type FileContent = { dictionaryKey: string; keyPath?: KeyPath[]; dictionaryPath?: string; }; type FocusDictionaryClient = { focusedContent: Signal<FileContent | null>; setFocusedContent: (focussedContent: FileContent | null) => void; setFocusedContentKeyPath: (keyPath: KeyPath[]) => void; }; /** * Singleton instance */ let instance: FocusDictionaryClient | null = null; /** * Creates a focus dictionary client */ export const createFocusDictionaryClient = () => { if (instance) return instance; const focusedContentSignal = signal<FileContent | null>(null); const setFocusedContent = (focussedContent: FileContent | null) => { focusedContentSignal.set(focussedContent); }; const setFocusedContentKeyPath = (keyPath: KeyPath[]) => { const current = focusedContentSignal(); if (!current) return; setFocusedContent({ ...current, keyPath }); }; instance = { focusedContent: focusedContentSignal.asReadonly(), setFocusedContent, setFocusedContentKeyPath, } as FocusDictionaryClient; return instance; }; /** * Helper to install the focus dictionary into the injector */ export const installFocusDictionary = (_injector: Injector) => { const _client = createFocusDictionaryClient(); // Angular doesn't have a direct equivalent to Vue's app.provide // The client is stored as a singleton and accessed via createFocusDictionaryClient }; /** consumer */ export const useFocusDictionary = createSharedComposable(() => { const client = createFocusDictionaryClient(); const [focusedContent, setFocusedContent] = useCrossFrameState<FileContent | null>( MessageKey.INTLAYER_FOCUSED_CONTENT_CHANGED ); if (!client) { throw new Error('FocusDictionary state not found'); } // Use Angular effects instead of Vue watchers // Watch local (client) and update cross-frame effect(() => { const newValue = client.focusedContent(); if (JSON.stringify(newValue) !== JSON.stringify(focusedContent())) { setFocusedContent(newValue); } }); // Watch cross-frame and update local effect(() => { const newValue = focusedContent(); if (JSON.stringify(newValue) !== JSON.stringify(client.focusedContent())) { client.setFocusedContent(newValue ?? null); } }); return client; });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aymericzip/intlayer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server