@stringpush/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/overlay/constants.ts","../src/overlay/overlay-api.ts","../src/overlay/locale-display.ts","../src/overlay/edit-panel.ts","../src/overlay/edit-panel-remote.ts","../src/overlay/highlights.ts","../src/overlay/realtime-sync.ts","../src/overlay/realtime-reconnect.ts","../src/overlay/realtime-client.ts","../src/overlay/index.ts"],"sourcesContent":["/**\n * DOM and bundle-split markers for the lazy-loaded overlay chunk.\n *\n * Intent: stable ids/markers isolate overlay CSS/DOM and keep the main SDK chunk small.\n */\nexport const OVERLAY_ROOT_ID = \"translation-overlay-root\";\nexport const EDIT_PANEL_HOST_ID = \"translation-edit-panel-host\";\n/** Marker string used in bundle-split tests — must not appear in the main SDK chunk. */\nexport const OVERLAY_CHUNK_MARKER = \"translation-overlay-chunk-v1\";\n","/**\n * Overlay HTTP client (edit JWT) for locales, key values, and saves (M2-SDK-03).\n *\n * Intent: thin fetch wrapper shared by edit panel; maps 409 VERSION_CONFLICT for conflict UI.\n */\nimport { resolveRequestOrigin } from \"@stringpush/runtime-core\";\n\nexport type OverlayLocale = {\n id: string;\n code: string;\n};\n\nexport type OverlayKeyValueEntry = {\n localeId: string;\n localeCode: string;\n value: string;\n version: number | null;\n};\n\nexport type OverlayKeyValuesResponse = {\n keyId: string;\n keyPath: string;\n defaultMessage: string | null;\n entries: OverlayKeyValueEntry[];\n};\n\nexport type OverlayTranslationValue = {\n id: string;\n translationKeyId: string;\n localeId: string;\n environmentId: string;\n value: string;\n status: string;\n version: number;\n};\n\nexport type OverlayApiConfig = {\n apiBaseUrl: string;\n editToken: string;\n origin?: string;\n fetch?: typeof fetch;\n};\n\nexport class OverlayApiError extends Error {\n constructor(\n message: string,\n readonly status: number,\n readonly body: unknown,\n ) {\n super(message);\n this.name = \"OverlayApiError\";\n }\n\n get isVersionConflict(): boolean {\n return (\n this.status === 409 &&\n typeof this.body === \"object\" &&\n this.body !== null &&\n \"error\" in this.body &&\n (this.body as { error?: { code?: string } }).error?.code === \"VERSION_CONFLICT\"\n );\n }\n\n get isKeyNotFound(): boolean {\n return (\n this.status === 404 &&\n typeof this.body === \"object\" &&\n this.body !== null &&\n \"error\" in this.body &&\n (this.body as { error?: { code?: string } }).error?.code === \"NOT_FOUND\"\n );\n }\n}\n\nfunction overlayHeaders(config: OverlayApiConfig): HeadersInit {\n const headers: Record<string, string> = {\n Authorization: `Bearer ${config.editToken}`,\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n };\n const origin = resolveRequestOrigin(config.origin);\n if (origin) {\n headers.Origin = origin;\n }\n return headers;\n}\n\nasync function overlayFetch(\n config: OverlayApiConfig,\n path: string,\n init: RequestInit = {},\n): Promise<Response> {\n const fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);\n const url = `${config.apiBaseUrl.replace(/\\/$/, \"\")}${path}`;\n return fetchFn(url, {\n ...init,\n headers: {\n ...overlayHeaders(config),\n ...(init.headers as Record<string, string> | undefined),\n },\n });\n}\n\nasync function parseJson<T>(response: Response): Promise<T> {\n return (await response.json()) as T;\n}\n\nexport async function fetchOverlayLocales(config: OverlayApiConfig): Promise<OverlayLocale[]> {\n const response = await overlayFetch(config, \"/v1/overlay/locales\");\n const body = await parseJson<{ data: Array<{ id: string; code: string }> } | { error: unknown }>(\n response,\n );\n if (!response.ok) {\n throw new OverlayApiError(\n `Failed to load locales (HTTP ${response.status})`,\n response.status,\n body,\n );\n }\n return (body as { data: Array<{ id: string; code: string }> }).data.map((row) => ({\n id: row.id,\n code: row.code,\n }));\n}\n\nexport async function fetchOverlayKeyValues(\n config: OverlayApiConfig,\n keyPath: string,\n): Promise<OverlayKeyValuesResponse> {\n const params = new URLSearchParams({ key: keyPath });\n const response = await overlayFetch(config, `/v1/overlay/keys/values?${params}`);\n const body = await parseJson<OverlayKeyValuesResponse | { error: unknown }>(response);\n if (!response.ok) {\n throw new OverlayApiError(\n `Failed to load key values (HTTP ${response.status})`,\n response.status,\n body,\n );\n }\n return body as OverlayKeyValuesResponse;\n}\n\nexport async function createOverlayKey(\n config: OverlayApiConfig,\n input: { keyPath: string; defaultMessage?: string | null },\n): Promise<{ id: string; keyPath: string }> {\n const response = await overlayFetch(config, \"/v1/overlay/keys\", {\n method: \"POST\",\n body: JSON.stringify({\n keyPath: input.keyPath,\n defaultMessage: input.defaultMessage ?? null,\n }),\n });\n\n const body = await parseJson<\n | { id: string; key: string; namespace: string }\n | { error: unknown }\n >(response);\n if (!response.ok) {\n throw new OverlayApiError(\n `Failed to create translation key (HTTP ${response.status})`,\n response.status,\n body,\n );\n }\n const record = body as { id: string; key: string; namespace: string };\n const keyPath = record.namespace ? `${record.namespace}.${record.key}` : record.key;\n return { id: record.id, keyPath };\n}\n\nexport async function patchOverlayValue(\n config: OverlayApiConfig,\n input: { keyId: string; localeId: string; value: string; version: number | null },\n): Promise<OverlayTranslationValue> {\n const headers: Record<string, string> = {};\n if (input.version !== null) {\n headers[\"If-Match\"] = String(input.version);\n }\n\n const response = await overlayFetch(config, \"/v1/overlay/values\", {\n method: \"PATCH\",\n headers,\n body: JSON.stringify({\n keyId: input.keyId,\n localeId: input.localeId,\n value: input.value,\n }),\n });\n\n const body = await parseJson<OverlayTranslationValue | { error: unknown }>(response);\n if (!response.ok) {\n throw new OverlayApiError(\n `Failed to save translation (HTTP ${response.status})`,\n response.status,\n body,\n );\n }\n return body as OverlayTranslationValue;\n}\n","const LOCALE_FLAGS: Record<string, string> = {\n en: \"🇺🇸\",\n fr: \"🇫🇷\",\n de: \"🇩🇪\",\n \"de-DE\": \"🇩🇪\",\n es: \"🇪🇸\",\n};\n\nconst LOCALE_NAMES: Record<string, string> = {\n en: \"English\",\n fr: \"French\",\n de: \"German\",\n \"de-DE\": \"German\",\n es: \"Spanish\",\n};\n\nexport function overlayLocaleFlag(code: string): string {\n return LOCALE_FLAGS[code] ?? \"🌐\";\n}\n\nexport function overlayLocaleLabel(code: string): string {\n const name = LOCALE_NAMES[code] ?? code.toUpperCase();\n return `${name} (${code})`;\n}\n","/**\n * Side panel UI to edit all locales for one translation key (M2-SDK-03).\n *\n * Intent: opened from overlay click; loads locales/values via edit JWT; saves with If-Match and surfaces 409 reload.\n */\nimport {\n createOverlayKey,\n fetchOverlayKeyValues,\n fetchOverlayLocales,\n OverlayApiError,\n patchOverlayValue,\n type OverlayApiConfig,\n type OverlayKeyValueEntry,\n} from \"./overlay-api.js\";\nimport { overlayLocaleFlag, overlayLocaleLabel } from \"./locale-display.js\";\nimport { recordTranslationVersion, shouldApplyTranslationUpdate } from \"@stringpush/runtime-core\";\nimport { EDIT_PANEL_HOST_ID } from \"./constants.js\";\nimport {\n registerEditPanelRemoteHandler,\n type RemoteTranslationUpdate,\n} from \"./edit-panel-remote.js\";\n\nconst PANEL_STYLES = `\n:host {\n all: initial;\n font-family: system-ui, -apple-system, Segoe UI, sans-serif;\n --sp-bg: #ffffff;\n --sp-text: #0f172a;\n --sp-muted: #64748b;\n --sp-border: #e2e8f0;\n --sp-accent: #4338ca;\n --sp-accent-hover: #3730a3;\n --sp-warning-bg: #fef3c7;\n --sp-warning-text: #92400e;\n --sp-warning-border: #fcd34d;\n --sp-badge-draft-bg: #fef3c6;\n --sp-badge-draft-text: #973c00;\n --sp-badge-default-bg: #f1f5f9;\n --sp-badge-default-text: #475569;\n}\n.panel {\n position: fixed;\n top: 0;\n right: 0;\n width: 400px;\n max-width: 100vw;\n height: 100vh;\n background: var(--sp-bg);\n color: var(--sp-text);\n box-shadow: -8px 0 32px rgba(15, 23, 42, 0.12);\n display: flex;\n flex-direction: column;\n z-index: 2147483647;\n}\n.header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 12px;\n padding: 16px 16px 12px;\n border-bottom: 1px solid var(--sp-border);\n}\n.header-main {\n min-width: 0;\n}\n.brand {\n margin: 0 0 8px;\n font-size: 11px;\n font-weight: 700;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--sp-accent);\n}\n.title {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n}\n.key-path {\n margin: 4px 0 0;\n font: 12px/1.4 ui-monospace, Menlo, monospace;\n color: var(--sp-muted);\n word-break: break-all;\n}\n.close-btn {\n border: none;\n background: transparent;\n font-size: 22px;\n line-height: 1;\n cursor: pointer;\n color: var(--sp-muted);\n padding: 2px 4px;\n}\n.body {\n flex: 1;\n overflow: auto;\n padding: 12px 16px;\n}\n.locale-row {\n margin-bottom: 16px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--sp-border);\n}\n.locale-row:last-child {\n border-bottom: none;\n margin-bottom: 0;\n padding-bottom: 0;\n}\n.locale-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n margin-bottom: 8px;\n}\n.locale-label {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n font-weight: 600;\n color: var(--sp-text);\n}\n.locale-flag {\n font-size: 15px;\n line-height: 1;\n}\n.locale-badges {\n display: inline-flex;\n gap: 4px;\n}\n.badge {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 999px;\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 0.02em;\n}\n.badge-default {\n background: var(--sp-badge-default-bg);\n color: var(--sp-badge-default-text);\n}\n.badge-draft {\n background: var(--sp-badge-draft-bg);\n color: var(--sp-badge-draft-text);\n}\n.locale-row textarea {\n width: 100%;\n min-height: 80px;\n box-sizing: border-box;\n border: 1px solid #cbd5e1;\n border-radius: 8px;\n padding: 10px 12px;\n font: 14px/1.45 inherit;\n resize: vertical;\n color: var(--sp-text);\n}\n.locale-row textarea:focus-visible {\n outline: 2px solid var(--sp-accent);\n outline-offset: 1px;\n border-color: var(--sp-accent);\n}\n.banner {\n margin: 0 16px 12px;\n padding: 12px 14px;\n border-radius: 8px;\n border: 1px solid var(--sp-warning-border);\n background: var(--sp-warning-bg);\n color: var(--sp-warning-text);\n font-size: 13px;\n line-height: 1.45;\n}\n.banner p {\n margin: 0;\n}\n.banner button {\n margin-top: 10px;\n border: 1px solid #d97706;\n background: #fff;\n border-radius: 6px;\n padding: 6px 12px;\n cursor: pointer;\n font-size: 12px;\n font-weight: 600;\n color: var(--sp-warning-text);\n}\n.footer {\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n padding: 12px 16px 16px;\n border-top: 1px solid var(--sp-border);\n}\n.footer button {\n border-radius: 8px;\n padding: 9px 14px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n.footer .secondary {\n border: 1px solid #cbd5e1;\n background: #fff;\n color: #334155;\n}\n.footer .primary {\n border: none;\n background: var(--sp-accent);\n color: #fff;\n}\n.footer .primary:hover:not(:disabled) {\n background: var(--sp-accent-hover);\n}\n.footer .primary::before {\n content: \"\";\n width: 14px;\n height: 14px;\n background: currentColor;\n mask: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14' fill='none'%3E%3Cpath d='M11.667 3.5 5.25 9.917 2.333 7' stroke='white' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\")\n center / contain no-repeat;\n}\n.status {\n padding: 24px 16px;\n color: var(--sp-muted);\n font-size: 14px;\n}\n.create-panel {\n padding: 8px 0;\n}\n.create-panel p {\n margin: 0 0 12px;\n font-size: 14px;\n color: #334155;\n line-height: 1.5;\n}\n.create-panel label {\n display: block;\n font-size: 12px;\n font-weight: 600;\n color: #334155;\n margin-bottom: 6px;\n}\n.create-panel input {\n width: 100%;\n box-sizing: border-box;\n border: 1px solid #cbd5e1;\n border-radius: 8px;\n padding: 8px 10px;\n font: 14px/1.4 inherit;\n margin-bottom: 12px;\n}\n.create-panel .create-btn {\n border: none;\n border-radius: 8px;\n padding: 9px 14px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n background: var(--sp-accent);\n color: #fff;\n}\n.create-panel .error {\n margin: 0 0 12px;\n color: #b91c1c;\n font-size: 13px;\n}\n`;\n\nexport type EditPanelContext = OverlayApiConfig & {\n activeLocaleCode: string;\n suggestedDefaultMessage?: string;\n onSaved: (keyPath: string, localeCode: string, value: string, version: number) => void;\n};\n\nexport type EditPanelHandle = {\n destroy: () => void;\n};\n\ntype LocaleRowState = OverlayKeyValueEntry & {\n draftValue: string;\n};\n\nexport function openEditPanel(keyPath: string, context: EditPanelContext): EditPanelHandle {\n if (typeof document === \"undefined\") {\n return { destroy: () => {} };\n }\n\n closeEditPanel();\n\n const host = document.createElement(\"div\");\n host.id = EDIT_PANEL_HOST_ID;\n const shadow = host.attachShadow({ mode: \"open\" });\n\n const style = document.createElement(\"style\");\n style.textContent = PANEL_STYLES;\n\n const panel = document.createElement(\"div\");\n panel.className = \"panel\";\n panel.setAttribute(\"role\", \"dialog\");\n panel.setAttribute(\"aria-label\", \"Edit translation\");\n\n const header = document.createElement(\"header\");\n header.className = \"header\";\n const headerMain = document.createElement(\"div\");\n headerMain.className = \"header-main\";\n const brand = document.createElement(\"p\");\n brand.className = \"brand\";\n brand.textContent = \"StringPush\";\n const title = document.createElement(\"h2\");\n title.className = \"title\";\n title.textContent = \"Edit translation\";\n const keyEl = document.createElement(\"p\");\n keyEl.className = \"key-path\";\n keyEl.textContent = keyPath;\n headerMain.append(brand, title, keyEl);\n const closeBtn = document.createElement(\"button\");\n closeBtn.className = \"close-btn\";\n closeBtn.type = \"button\";\n closeBtn.setAttribute(\"aria-label\", \"Close\");\n closeBtn.textContent = \"×\";\n header.append(headerMain, closeBtn);\n\n const bodyEl = document.createElement(\"div\");\n bodyEl.className = \"body\";\n\n const status = document.createElement(\"div\");\n status.className = \"status\";\n status.textContent = \"Loading…\";\n bodyEl.append(status);\n\n const banner = document.createElement(\"div\");\n banner.className = \"banner\";\n banner.hidden = true;\n\n const footer = document.createElement(\"footer\");\n footer.className = \"footer\";\n const cancelBtn = document.createElement(\"button\");\n cancelBtn.type = \"button\";\n cancelBtn.className = \"secondary\";\n cancelBtn.textContent = \"Cancel\";\n const saveBtn = document.createElement(\"button\");\n saveBtn.type = \"button\";\n saveBtn.className = \"primary\";\n saveBtn.textContent = \"Save draft\";\n saveBtn.disabled = true;\n footer.append(cancelBtn, saveBtn);\n\n panel.append(header, banner, bodyEl, footer);\n shadow.append(style, panel);\n document.body.append(host);\n\n let destroyed = false;\n let rows: LocaleRowState[] = [];\n let keyId = \"\";\n\n const destroy = () => {\n if (destroyed) {\n return;\n }\n destroyed = true;\n registerEditPanelRemoteHandler(null);\n host.remove();\n };\n\n function applyRemoteUpdate(update: RemoteTranslationUpdate): boolean {\n if (!shouldApplyTranslationUpdate(update.keyPath, update.localeCode, update.version)) {\n return false;\n }\n\n const row = rows.find((entry) => entry.localeCode === update.localeCode);\n if (!row) {\n return false;\n }\n\n if ((row.version ?? 0) > update.version) {\n return false;\n }\n\n if (row.draftValue !== row.value) {\n showConflict(\n `${update.localeCode} was updated in another tab. Reload to merge your changes.`,\n );\n return true;\n }\n\n row.value = update.value;\n row.draftValue = update.value;\n row.version = update.version;\n recordTranslationVersion(update.keyPath, update.localeCode, update.version);\n renderRows();\n return true;\n }\n\n closeBtn.addEventListener(\"click\", destroy);\n cancelBtn.addEventListener(\"click\", destroy);\n\n function renderRows(): void {\n bodyEl.replaceChildren();\n for (const row of rows) {\n const wrap = document.createElement(\"div\");\n wrap.className = \"locale-row\";\n\n const localeHeader = document.createElement(\"div\");\n localeHeader.className = \"locale-header\";\n\n const label = document.createElement(\"span\");\n label.className = \"locale-label\";\n const flag = document.createElement(\"span\");\n flag.className = \"locale-flag\";\n flag.textContent = overlayLocaleFlag(row.localeCode);\n flag.setAttribute(\"aria-hidden\", \"true\");\n label.append(flag, document.createTextNode(overlayLocaleLabel(row.localeCode)));\n\n const badges = document.createElement(\"span\");\n badges.className = \"locale-badges\";\n if (row.localeCode === context.activeLocaleCode) {\n const defaultBadge = document.createElement(\"span\");\n defaultBadge.className = \"badge badge-default\";\n defaultBadge.textContent = \"Default\";\n badges.append(defaultBadge);\n }\n const draftBadge = document.createElement(\"span\");\n draftBadge.className = \"badge badge-draft\";\n draftBadge.textContent = row.draftValue !== row.value ? \"Unsaved\" : \"Draft\";\n badges.append(draftBadge);\n\n localeHeader.append(label, badges);\n\n const textarea = document.createElement(\"textarea\");\n textarea.id = `locale-${row.localeId}`;\n textarea.setAttribute(\"aria-label\", `${row.localeCode} translation`);\n textarea.value = row.draftValue;\n textarea.addEventListener(\"input\", () => {\n row.draftValue = textarea.value;\n draftBadge.textContent = row.draftValue !== row.value ? \"Unsaved\" : \"Draft\";\n });\n\n wrap.append(localeHeader, textarea);\n bodyEl.append(wrap);\n }\n saveBtn.disabled = false;\n }\n\n async function load(): Promise<void> {\n try {\n const [locales, keyValues] = await Promise.all([\n fetchOverlayLocales(context),\n fetchOverlayKeyValues(context, keyPath),\n ]);\n\n if (destroyed) {\n return;\n }\n\n keyId = keyValues.keyId;\n const localeCodes = new Set(locales.map((l) => l.code));\n rows = keyValues.entries\n .filter((entry) => localeCodes.has(entry.localeCode))\n .map((entry) => ({\n ...entry,\n draftValue: entry.value,\n }));\n\n for (const row of rows) {\n if (row.version !== null) {\n recordTranslationVersion(keyPath, row.localeCode, row.version);\n }\n }\n\n banner.hidden = true;\n footer.hidden = false;\n renderRows();\n } catch (error) {\n if (error instanceof OverlayApiError && error.isKeyNotFound) {\n showCreateKeyPrompt();\n return;\n }\n status.textContent =\n error instanceof Error ? error.message : \"Failed to load translations\";\n }\n }\n\n function showCreateKeyPrompt(): void {\n footer.hidden = true;\n bodyEl.replaceChildren();\n\n const wrap = document.createElement(\"div\");\n wrap.className = \"create-panel\";\n\n const intro = document.createElement(\"p\");\n intro.textContent =\n \"This key is not in your project yet. Create it to start editing translations for all locales.\";\n\n const label = document.createElement(\"label\");\n label.textContent = \"Default message (optional)\";\n label.htmlFor = \"create-default-message\";\n\n const input = document.createElement(\"input\");\n input.id = \"create-default-message\";\n input.type = \"text\";\n input.placeholder = \"Text shown when no translation is saved\";\n if (context.suggestedDefaultMessage) {\n input.value = context.suggestedDefaultMessage;\n }\n\n const errorEl = document.createElement(\"p\");\n errorEl.className = \"error\";\n errorEl.hidden = true;\n\n const createBtn = document.createElement(\"button\");\n createBtn.type = \"button\";\n createBtn.className = \"create-btn\";\n createBtn.textContent = \"Create key\";\n\n createBtn.addEventListener(\"click\", () => {\n void (async () => {\n createBtn.disabled = true;\n errorEl.hidden = true;\n\n try {\n await createOverlayKey(context, {\n keyPath,\n defaultMessage: input.value.trim() || null,\n });\n if (destroyed) {\n return;\n }\n status.textContent = \"Loading…\";\n bodyEl.replaceChildren(status);\n footer.hidden = false;\n saveBtn.disabled = true;\n await load();\n } catch (createError) {\n createBtn.disabled = false;\n errorEl.hidden = false;\n errorEl.textContent =\n createError instanceof Error ? createError.message : \"Failed to create key\";\n }\n })();\n });\n\n wrap.append(intro, label, input, errorEl, createBtn);\n bodyEl.append(wrap);\n }\n\n function showConflict(message: string): void {\n banner.hidden = false;\n banner.replaceChildren();\n const text = document.createElement(\"p\");\n text.textContent = message;\n banner.append(text);\n const reloadBtn = document.createElement(\"button\");\n reloadBtn.type = \"button\";\n reloadBtn.textContent = \"Reload\";\n reloadBtn.addEventListener(\"click\", () => {\n status.textContent = \"Loading…\";\n bodyEl.replaceChildren(status);\n saveBtn.disabled = true;\n void load();\n });\n banner.append(reloadBtn);\n }\n\n saveBtn.addEventListener(\"click\", () => {\n void (async () => {\n saveBtn.disabled = true;\n let hadConflict = false;\n\n for (const row of rows) {\n if (row.draftValue === row.value) {\n continue;\n }\n\n try {\n const saved = await patchOverlayValue(context, {\n keyId,\n localeId: row.localeId,\n value: row.draftValue,\n version: row.version,\n });\n row.value = saved.value;\n row.version = saved.version;\n row.draftValue = saved.value;\n context.onSaved(keyPath, row.localeCode, saved.value, saved.version);\n } catch (error) {\n if (error instanceof OverlayApiError && error.isVersionConflict) {\n hadConflict = true;\n showConflict(\n \"Someone else updated this key. Reload to fetch the latest versions, then try again.\",\n );\n break;\n }\n showConflict(error instanceof Error ? error.message : \"Save failed\");\n hadConflict = true;\n break;\n }\n }\n\n saveBtn.disabled = hadConflict;\n if (!hadConflict) {\n destroy();\n }\n })();\n });\n\n registerEditPanelRemoteHandler({ keyPath, applyRemoteUpdate });\n\n void load();\n\n return { destroy };\n}\n\nexport function closeEditPanel(): void {\n registerEditPanelRemoteHandler(null);\n document.getElementById(EDIT_PANEL_HOST_ID)?.remove();\n}\n","/**\n * Routes realtime `translation.updated` events to the open edit panel (M2-SDK-04).\n *\n * Intent: single active handler per key so concurrent editors see live value/version without full reload.\n */\nexport type RemoteTranslationUpdate = {\n keyPath: string;\n localeCode: string;\n value: string;\n version: number;\n};\n\nexport type EditPanelRemoteHandler = {\n keyPath: string;\n applyRemoteUpdate: (update: RemoteTranslationUpdate) => boolean;\n};\n\nlet activeHandler: EditPanelRemoteHandler | null = null;\n\nexport function registerEditPanelRemoteHandler(handler: EditPanelRemoteHandler | null): void {\n activeHandler = handler;\n}\n\nexport function notifyEditPanelRemoteUpdate(update: RemoteTranslationUpdate): boolean {\n if (!activeHandler || activeHandler.keyPath !== update.keyPath) {\n return false;\n }\n return activeHandler.applyRemoteUpdate(update);\n}\n","/**\n * Hover/focus highlights for translatable DOM nodes in edit mode (M2-SDK-02).\n *\n * Intent: pointer-events stay on the host page — only outlines and a read-only key tooltip are added.\n */\nimport { EDIT_PANEL_HOST_ID, OVERLAY_ROOT_ID } from \"./constants.js\";\n\nconst HIGHLIGHT_CLASS = \"translation-sdk-target-highlight\";\nconst STYLES_ID = \"translation-sdk-highlight-styles\";\nconst TOOLTIP_ID = \"translation-sdk-key-tooltip\";\n\nconst HIGHLIGHT_CSS = `\n.${HIGHLIGHT_CLASS} {\n outline: 2px solid #2563eb !important;\n outline-offset: 2px !important;\n box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.28) !important;\n}\n.${HIGHLIGHT_CLASS}:focus-visible {\n outline: 3px solid #1d4ed8 !important;\n outline-offset: 2px !important;\n}\n#${TOOLTIP_ID} {\n position: fixed;\n z-index: 2147483645;\n max-width: min(360px, 90vw);\n padding: 4px 8px;\n border-radius: 6px;\n font: 12px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace;\n color: #f8fafc;\n background: #0f172a;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.28);\n pointer-events: none;\n display: none;\n}\n#${TOOLTIP_ID}[data-visible=\"true\"] {\n display: block;\n}\n`;\n\nexport type HighlightControllerOptions = {\n resolveKey: (element: Element) => string | null;\n onActivateKey?: (keyPath: string, element: Element) => void;\n};\n\nexport type HighlightController = {\n destroy: () => void;\n};\n\nexport function createHighlightController(\n options: HighlightControllerOptions,\n): HighlightController {\n if (typeof document === \"undefined\") {\n return { destroy: () => {} };\n }\n\n const abort = new AbortController();\n const { signal } = abort;\n\n let highlighted: Element | null = null;\n\n const styleEl = document.createElement(\"style\");\n styleEl.id = STYLES_ID;\n styleEl.textContent = HIGHLIGHT_CSS;\n document.head.append(styleEl);\n\n const tip = document.createElement(\"div\");\n tip.id = TOOLTIP_ID;\n document.body.append(tip);\n\n function isInsideOverlay(node: Node | null): boolean {\n if (!node || !(node instanceof Element)) {\n return false;\n }\n return Boolean(\n node.closest(`#${OVERLAY_ROOT_ID}, #${EDIT_PANEL_HOST_ID}`),\n );\n }\n\n function clearHighlight(): void {\n if (highlighted) {\n highlighted.classList.remove(HIGHLIGHT_CLASS);\n highlighted = null;\n }\n tip.dataset.visible = \"false\";\n tip.textContent = \"\";\n }\n\n function positionTooltip(key: string, target: Element, clientX: number): void {\n tip.textContent = key;\n tip.dataset.visible = \"true\";\n\n const rect = target.getBoundingClientRect();\n const top = Math.min(rect.bottom + 8, window.innerHeight - 32);\n const left = Math.min(Math.max(clientX, 8), window.innerWidth - 200);\n tip.style.top = `${top}px`;\n tip.style.left = `${left}px`;\n }\n\n function applyHighlight(target: Element, key: string, clientX: number): void {\n if (highlighted !== target) {\n clearHighlight();\n highlighted = target;\n target.classList.add(HIGHLIGHT_CLASS);\n }\n positionTooltip(key, target, clientX);\n }\n\n function inspectTarget(target: Element | null, clientX: number, _clientY: number): void {\n if (!target || isInsideOverlay(target)) {\n clearHighlight();\n return;\n }\n\n const key = options.resolveKey(target);\n if (!key) {\n clearHighlight();\n return;\n }\n\n applyHighlight(target, key, clientX);\n }\n\n document.addEventListener(\n \"pointermove\",\n (event) => {\n const target = event.target instanceof Element ? event.target : null;\n inspectTarget(target, event.clientX, event.clientY);\n },\n { signal },\n );\n\n document.addEventListener(\n \"focusin\",\n (event) => {\n const target = event.target instanceof Element ? event.target : null;\n if (!target) {\n return;\n }\n const rect = target.getBoundingClientRect();\n inspectTarget(target, rect.left + rect.width / 2, rect.top);\n },\n { capture: true, signal },\n );\n\n document.addEventListener(\n \"click\",\n (event) => {\n const target = event.target instanceof Element ? event.target : null;\n if (!target || isInsideOverlay(target)) {\n return;\n }\n const key = options.resolveKey(target);\n if (!key) {\n return;\n }\n options.onActivateKey?.(key, target);\n },\n { capture: true, signal },\n );\n\n return {\n destroy: () => {\n abort.abort();\n clearHighlight();\n styleEl.remove();\n tip.remove();\n },\n };\n}\n","/**\n * Applies realtime gateway events to the in-memory SDK catalog (M2-SDK-04).\n */\nimport { patchCatalogEntry, reloadIfBundlePublishedNewer } from \"@stringpush/runtime-core\";\nimport type { RealtimeEvent } from \"@stringpush/realtime-protocol\";\nimport { parseRealtimeEvent } from \"@stringpush/realtime-protocol\";\nimport { notifyEditPanelRemoteUpdate } from \"./edit-panel-remote.js\";\n\nexport type RealtimeSyncContext = {\n projectId: string;\n applicationId: string;\n environmentId: string;\n notifyTranslationsUpdated: () => void;\n};\n\nexport function handleRealtimeWireMessage(raw: string, context: RealtimeSyncContext): void {\n let event: RealtimeEvent;\n try {\n event = parseRealtimeEvent(raw);\n } catch {\n return;\n }\n\n void applyRealtimeEvent(event, context).catch(() => {\n // Intent: network errors on bundle reload must not surface as unhandled rejections.\n });\n}\n\nasync function applyRealtimeEvent(\n event: RealtimeEvent,\n context: RealtimeSyncContext,\n): Promise<void> {\n if (event.type === \"translation.updated\") {\n const { payload } = event;\n if (\n payload.projectId !== context.projectId ||\n payload.environmentId !== context.environmentId\n ) {\n return;\n }\n\n notifyEditPanelRemoteUpdate({\n keyPath: payload.keyPath,\n localeCode: payload.localeCode,\n value: payload.value,\n version: payload.version,\n });\n\n if (\n patchCatalogEntry(\n payload.keyPath,\n payload.localeCode,\n payload.value,\n payload.version,\n )\n ) {\n context.notifyTranslationsUpdated();\n }\n return;\n }\n\n if (event.type === \"bundle.published\") {\n const { payload } = event;\n if (\n payload.projectId !== context.projectId ||\n payload.applicationId !== context.applicationId ||\n payload.environmentId !== context.environmentId\n ) {\n return;\n }\n\n const reloaded = await reloadIfBundlePublishedNewer(payload.releases);\n if (reloaded) {\n context.notifyTranslationsUpdated();\n }\n }\n}\n","/**\n * Exponential backoff for overlay WebSocket reconnect (M2-SDK-04).\n *\n * Intent: cap delay growth so transient disconnects recover without hammering the gateway.\n */\nexport const REALTIME_RECONNECT_INITIAL_MS = 1_000;\nexport const REALTIME_RECONNECT_MAX_MS = 30_000;\n\nexport function computeRealtimeReconnectDelayMs(\n attempt: number,\n initialMs = REALTIME_RECONNECT_INITIAL_MS,\n maxMs = REALTIME_RECONNECT_MAX_MS,\n): number {\n if (attempt <= 0) {\n return initialMs;\n }\n return Math.min(initialMs * 2 ** (attempt - 1), maxMs);\n}\n","/**\n * WebSocket client for the realtime gateway (M2-SDK-01, M2-SDK-04).\n *\n * Intent: lives only in the lazy overlay chunk — torn down by `disableEditMode()`; reconnects with backoff.\n */\nimport { handleRealtimeWireMessage, type RealtimeSyncContext } from \"./realtime-sync.js\";\nimport { computeRealtimeReconnectDelayMs } from \"./realtime-reconnect.js\";\n\nexport type RealtimeClientOptions = {\n realtimeUrl: string;\n editToken: string;\n projectId: string;\n sync: RealtimeSyncContext;\n};\n\nexport type RealtimeClient = {\n close: () => void;\n};\n\nexport function connectRealtime(options: RealtimeClientOptions): RealtimeClient | null {\n if (typeof globalThis === \"undefined\" || !(\"WebSocket\" in globalThis)) {\n return null;\n }\n\n const WebSocketCtor = (globalThis as typeof globalThis & { WebSocket: typeof WebSocket })\n .WebSocket;\n\n let intentionalClose = false;\n let reconnectAttempt = 0;\n let reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n let socket: WebSocket | null = null;\n\n const clearReconnectTimer = () => {\n if (reconnectTimer !== null) {\n clearTimeout(reconnectTimer);\n reconnectTimer = null;\n }\n };\n\n const sendAuth = (ws: WebSocket) => {\n ws.send(\n JSON.stringify({\n type: \"auth\",\n token: options.editToken,\n projectId: options.projectId,\n }),\n );\n };\n\n const attachSocket = (ws: WebSocket) => {\n ws.addEventListener(\"open\", () => {\n reconnectAttempt = 0;\n sendAuth(ws);\n });\n\n ws.addEventListener(\"message\", (event) => {\n const raw = typeof event.data === \"string\" ? event.data : null;\n if (!raw) {\n return;\n }\n handleRealtimeWireMessage(raw, options.sync);\n });\n\n ws.addEventListener(\"close\", () => {\n if (socket === ws) {\n socket = null;\n }\n if (!intentionalClose) {\n scheduleReconnect();\n }\n });\n };\n\n const scheduleReconnect = () => {\n if (intentionalClose) {\n return;\n }\n clearReconnectTimer();\n reconnectAttempt += 1;\n const delayMs = computeRealtimeReconnectDelayMs(reconnectAttempt);\n reconnectTimer = setTimeout(() => {\n reconnectTimer = null;\n openSocket();\n }, delayMs);\n };\n\n const openSocket = () => {\n if (intentionalClose) {\n return;\n }\n const ws = new WebSocketCtor(options.realtimeUrl);\n socket = ws;\n attachSocket(ws);\n };\n\n openSocket();\n\n return {\n close: () => {\n intentionalClose = true;\n clearReconnectTimer();\n if (\n socket &&\n (socket.readyState === WebSocketCtor.OPEN || socket.readyState === WebSocketCtor.CONNECTING)\n ) {\n socket.close();\n }\n socket = null;\n },\n };\n}\n","/**\n * Lazy-loaded overlay UI chunk (M2-SDK-01+).\n *\n * Intent: not imported by the default SDK entry — loaded via dynamic `import()` when edit mode starts.\n */\nimport { OVERLAY_CHUNK_MARKER, OVERLAY_ROOT_ID } from \"./constants.js\";\nimport { closeEditPanel, openEditPanel } from \"./edit-panel.js\";\nimport { createHighlightController } from \"./highlights.js\";\nimport { connectRealtime } from \"./realtime-client.js\";\n\nexport { OVERLAY_CHUNK_MARKER, OVERLAY_ROOT_ID } from \"./constants.js\";\n\nexport type OverlayMountContext = {\n projectId: string;\n applicationId: string;\n environmentId: string;\n realtimeUrl: string;\n editToken: string;\n apiBaseUrl: string;\n origin?: string;\n activeLocaleCode: string;\n resolveKey: (element: Element) => string | null;\n onCatalogPatched: (\n keyPath: string,\n localeCode: string,\n value: string,\n version: number,\n ) => void;\n onTranslationsUpdated: () => void;\n};\n\nexport type OverlayHandle = {\n destroy: () => void;\n};\n\n/**\n * Mounts overlay shell (shadow DOM), hover highlights, edit panel, and realtime WebSocket.\n */\nexport function mountOverlay(context: OverlayMountContext): OverlayHandle {\n if (typeof document === \"undefined\") {\n return { destroy: () => {} };\n }\n\n document.getElementById(OVERLAY_ROOT_ID)?.remove();\n closeEditPanel();\n\n const mountHost = document.createElement(\"div\");\n mountHost.id = OVERLAY_ROOT_ID;\n mountHost.setAttribute(\"data-translation-overlay\", \"true\");\n\n const shadow = mountHost.attachShadow({ mode: \"open\" });\n const label = document.createElement(\"div\");\n label.setAttribute(\"data-overlay-marker\", OVERLAY_CHUNK_MARKER);\n label.textContent = \"Translation edit mode — click text to edit\";\n label.style.cssText = [\n \"position:fixed\",\n \"bottom:16px\",\n \"right:16px\",\n \"z-index:2147483646\",\n \"padding:8px 12px\",\n \"border-radius:8px\",\n \"font:600 13px/1.4 system-ui,sans-serif\",\n \"color:#fff\",\n \"background:#1e3a5f\",\n \"box-shadow:0 4px 12px rgba(0,0,0,.25)\",\n \"pointer-events:none\",\n ].join(\";\");\n\n shadow.append(label);\n document.body.append(mountHost);\n\n let panelHandle: { destroy: () => void } | null = null;\n\n const highlights = createHighlightController({\n resolveKey: context.resolveKey,\n onActivateKey: (keyPath, element) => {\n panelHandle?.destroy();\n const suggestedDefaultMessage = element.textContent?.trim() || undefined;\n panelHandle = openEditPanel(keyPath, {\n apiBaseUrl: context.apiBaseUrl,\n editToken: context.editToken,\n origin: context.origin,\n activeLocaleCode: context.activeLocaleCode,\n suggestedDefaultMessage,\n onSaved: context.onCatalogPatched,\n });\n },\n });\n\n const realtime = connectRealtime({\n realtimeUrl: context.realtimeUrl,\n editToken: context.editToken,\n projectId: context.projectId,\n sync: {\n projectId: context.projectId,\n applicationId: context.applicationId,\n environmentId: context.environmentId,\n notifyTranslationsUpdated: context.onTranslationsUpdated,\n },\n });\n\n return {\n destroy: () => {\n panelHandle?.destroy();\n highlights.destroy();\n realtime?.close();\n mountHost.remove();\n },\n };\n}\n"],"mappings":"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","names":[]}