@stringpush/sdk 0.1.1 → 0.3.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.
package/dist/index.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  import {
2
+ adminOriginFromSignInUrl,
2
3
  decodeEditTokenClaims,
3
4
  isEditLauncherArmed,
4
5
  readEditTokenFromHash,
@@ -6,7 +7,7 @@ import {
6
7
  resolveEditToken,
7
8
  shouldAutoEnableEditMode,
8
9
  stripEditTokenFromUrl
9
- } from "./chunk-X3WTVBZ6.mjs";
10
+ } from "./chunk-YYR2BH3L.mjs";
10
11
 
11
12
  // src/resolve-key.ts
12
13
  var I18N_KEY_ATTR = "data-i18n-key";
@@ -83,7 +84,7 @@ var overlayHandle = null;
83
84
  var overlayLoadPromise = null;
84
85
  function loadOverlayModule() {
85
86
  if (!overlayLoadPromise) {
86
- overlayLoadPromise = import("./overlay-7KC2RRGB.mjs");
87
+ overlayLoadPromise = import("./overlay-Y3NQFQBI.mjs");
87
88
  }
88
89
  return overlayLoadPromise;
89
90
  }
@@ -128,6 +129,9 @@ async function enableEditMode(options = {}) {
128
129
  projectId: manifest.projectId,
129
130
  applicationId: manifest.applicationId,
130
131
  environmentId: editClaims.environmentId,
132
+ environmentName: editClaims.environmentName,
133
+ approvalEnabled: false,
134
+ adminWebOrigin: initOptions.editLauncher?.signInUrl ? adminOriginFromSignInUrl(initOptions.editLauncher.signInUrl) : void 0,
131
135
  realtimeUrl,
132
136
  editToken,
133
137
  apiBaseUrl,
@@ -158,7 +162,7 @@ var launcherHandle = null;
158
162
  var launcherLoadPromise = null;
159
163
  function loadLauncherModule() {
160
164
  if (!launcherLoadPromise) {
161
- launcherLoadPromise = import("./edit-launcher-PTZ5BIO2.mjs");
165
+ launcherLoadPromise = import("./edit-launcher-YJB2FBO7.mjs");
162
166
  }
163
167
  return launcherLoadPromise;
164
168
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/resolve-key.ts","../src/index.ts","../src/edit-mode.ts","../src/runtime.ts","../src/urls.ts","../src/edit-launcher-lifecycle.ts"],"sourcesContent":["/**\n * Maps DOM nodes to translation keys for overlay edit mode (M2-SDK-02).\n *\n * Intent: host `registerResolver` first; `data-i18n-key` on the element or an ancestor is the fallback.\n */\nimport type { KeyResolver } from \"./runtime.js\";\n\nexport const I18N_KEY_ATTR = \"data-i18n-key\";\n\n/**\n * Resolves a translation key for a DOM node by walking ancestors.\n */\nexport function resolveKeyForElement(\n start: Element,\n resolver: KeyResolver | null,\n): string | null {\n if (resolver) {\n let current: Element | null = start;\n while (current) {\n const resolved = resolver(current);\n if (resolved) {\n return resolved;\n }\n current = current.parentElement;\n }\n }\n\n let current: Element | null = start;\n while (current) {\n const fromAttr = current.getAttribute(I18N_KEY_ATTR);\n if (fromAttr) {\n return fromAttr;\n }\n current = current.parentElement;\n }\n\n return null;\n}\n","/**\n * @stringpush/sdk — plain JS runtime: load manifest + bundles, expose `t()` (ICU in M1-SDK-03).\n *\n * Intent: customer-facing surface; runtime catalog/manifest delegated to @stringpush/runtime-core.\n */\nexport { I18N_KEY_ATTR } from \"./resolve-key.js\";\n\nexport type {\n EditLauncherOptions,\n EnableEditModeOptions,\n Environment,\n InitOptions,\n ManifestLocaleEntry,\n MissingKeyFallback,\n RetryOptions,\n TranslateValues,\n TranslationCatalog,\n TranslationManifest,\n} from \"./types.js\";\n\nimport type { EnableEditModeOptions, InitOptions, TranslateValues } from \"./types.js\";\nimport {\n changeLocale,\n destroyRuntime,\n getRuntime,\n getRuntimeLocale,\n initializeRuntime,\n translateKey,\n} from \"@stringpush/runtime-core\";\nimport { teardownEditLauncher, mountEditLauncherIfNeeded } from \"./edit-launcher-lifecycle.js\";\nimport {\n readEditTokenFromHash,\n readEditTokenFromQuery,\n resolveEditToken,\n shouldAutoEnableEditMode,\n stripEditTokenFromUrl,\n} from \"./edit-token.js\";\nimport {\n disableEditMode as disableEditModeInternal,\n enableEditMode as enableEditModeInternal,\n teardownEditMode,\n} from \"./edit-mode.js\";\nimport { getKeyResolver, setKeyResolver } from \"./runtime.js\";\n\n/**\n * Initialize the SDK: fetch manifest and the active locale bundle into an in-memory catalog.\n *\n * Intent: entry point for customer apps; triggers `onTranslationsUpdated` when the first catalog is ready.\n */\nexport async function init(options: InitOptions): Promise<void> {\n await initializeRuntime(options);\n\n const tokenFromUrl = readEditTokenFromQuery() ?? readEditTokenFromHash();\n if (tokenFromUrl || options.editToken) {\n resolveEditToken(options);\n if (tokenFromUrl) {\n stripEditTokenFromUrl();\n }\n }\n\n if (shouldAutoEnableEditMode(options)) {\n await enableEditModeInternal();\n } else {\n await mountEditLauncherIfNeeded(options);\n }\n}\n\nexport function destroy(): void {\n teardownEditLauncher();\n teardownEditMode();\n setKeyResolver(null);\n destroyRuntime();\n}\n\nexport function getLocale(): string {\n return getRuntimeLocale();\n}\n\n/**\n * Switch active locale and reload its bundle from the manifest.\n */\nexport async function setLocale(locale: string): Promise<void> {\n await changeLocale(locale);\n}\n\n/**\n * Translate a key using the loaded catalog and ICU MessageFormat.\n */\nexport function t(key: string, values?: TranslateValues): string {\n // Intent: preserve @stringpush/sdk error text for public `t()` callers (runtime-core uses initializeRuntime wording).\n if (!getRuntime().options) {\n throw new Error(\"@stringpush/sdk: call init() before using the runtime\");\n }\n return translateKey(key, values);\n}\n\nexport function loadNamespace(_namespace: string): Promise<void> {\n return Promise.resolve();\n}\n\nexport async function enableEditMode(options?: EnableEditModeOptions): Promise<void> {\n await enableEditModeInternal(options);\n}\n\nexport function disableEditMode(): void {\n disableEditModeInternal();\n}\n\nexport function registerResolver(resolver: (element: Element) => string | null): () => void {\n setKeyResolver(resolver);\n return () => {\n if (getKeyResolver() === resolver) {\n setKeyResolver(null);\n }\n };\n}\n","/**\n * Edit-mode lifecycle: lazy overlay chunk load and teardown (M2-SDK-01).\n */\nimport {\n patchCatalogEntry,\n resolveApiBaseUrl,\n} from \"@stringpush/runtime-core\";\nimport { decodeEditTokenClaims } from \"./edit-token-decode.js\";\nimport { resolveEditToken } from \"./edit-token.js\";\nimport { resolveKeyForElement } from \"./resolve-key.js\";\nimport { assertInitialized, getKeyResolver, getRuntime } from \"./runtime.js\";\nimport type { EnableEditModeOptions } from \"./types.js\";\nimport { resolveRealtimeUrl } from \"./urls.js\";\n\ntype OverlayModule = typeof import(\"./overlay/index.js\");\n\nlet overlayHandle: { destroy: () => void } | null = null;\nlet overlayLoadPromise: Promise<OverlayModule> | null = null;\n\nfunction loadOverlayModule(): Promise<OverlayModule> {\n if (!overlayLoadPromise) {\n // Intent: dynamic import keeps overlay + WS client out of the default SDK bundle.\n overlayLoadPromise = import(\"./overlay/index.js\");\n }\n return overlayLoadPromise;\n}\n\nexport function isEditModeActive(): boolean {\n return overlayHandle !== null;\n}\n\n/**\n * Activates overlay edit mode when a valid edit JWT is available.\n */\nexport async function enableEditMode(options: EnableEditModeOptions = {}): Promise<void> {\n if (overlayHandle) {\n return;\n }\n\n const initOptions = assertInitialized();\n const state = getRuntime();\n const manifest = state.manifest;\n if (!manifest) {\n throw new Error(\"@stringpush/sdk: manifest is not loaded — call init() before enableEditMode()\");\n }\n\n const editToken = resolveEditToken(initOptions, options.editToken);\n if (!editToken) {\n throw new Error(\n \"@stringpush/sdk: edit token required — pass editToken, ?edit_token=, or sessionStorage\",\n );\n }\n\n const apiBaseUrl = resolveApiBaseUrl(initOptions.apiBaseUrl);\n const realtimeUrl = resolveRealtimeUrl(apiBaseUrl, initOptions.realtimeUrl);\n const overlay = await loadOverlayModule();\n const editClaims = decodeEditTokenClaims(editToken);\n if (!editClaims) {\n throw new Error(\"@stringpush/sdk: edit token is malformed\");\n }\n if (editClaims.projectId !== manifest.projectId) {\n throw new Error(\"@stringpush/sdk: edit token project does not match loaded manifest\");\n }\n if (editClaims.applicationId !== manifest.applicationId) {\n throw new Error(\"@stringpush/sdk: edit token application does not match init()\");\n }\n if (editClaims.environmentName !== initOptions.environment) {\n throw new Error(\n \"@stringpush/sdk: edit token environment does not match init() environment\",\n );\n }\n\n overlayHandle = overlay.mountOverlay({\n projectId: manifest.projectId,\n applicationId: manifest.applicationId,\n environmentId: editClaims.environmentId,\n realtimeUrl,\n editToken,\n apiBaseUrl,\n origin: initOptions.origin,\n activeLocaleCode: state.locale,\n resolveKey: (element) => resolveKeyForElement(element, getKeyResolver()),\n onCatalogPatched: (keyPath, localeCode, value, version) => {\n if (patchCatalogEntry(keyPath, localeCode, value, version)) {\n initOptions.onTranslationsUpdated?.();\n }\n },\n onTranslationsUpdated: () => {\n initOptions.onTranslationsUpdated?.();\n },\n });\n}\n\n/**\n * Tears down overlay DOM and closes the realtime WebSocket.\n */\nexport function disableEditMode(): void {\n overlayHandle?.destroy();\n overlayHandle = null;\n}\n\nexport function teardownEditMode(): void {\n disableEditMode();\n overlayLoadPromise = null;\n}\n","/**\n * DOM-specific runtime helpers (key resolver) atop @stringpush/runtime-core state.\n *\n * Intent: overlay `registerResolver` stays in sdk; catalog/manifest live in runtime-core.\n */\nimport {\n assertInitialized as assertCoreInitialized,\n getRuntime,\n resetRuntime,\n type SdkRuntime,\n} from \"@stringpush/runtime-core\";\nimport type { InitOptions } from \"./types.js\";\n\nexport { getRuntime, resetRuntime, type SdkRuntime };\n\n/** SDK init stores overlay fields on the same options object passed to runtime-core. */\nexport function assertInitialized(): InitOptions {\n return assertCoreInitialized() as InitOptions;\n}\n\nexport type KeyResolver = (element: Element) => string | null;\n\nlet keyResolver: KeyResolver | null = null;\n\nexport function setKeyResolver(resolver: KeyResolver | null): void {\n keyResolver = resolver;\n}\n\nexport function getKeyResolver(): KeyResolver | null {\n return keyResolver;\n}\n","/**\n * WebSocket URL helper for overlay realtime (M2-SDK-01).\n *\n * Intent: overlay-specific; runtime-core has no realtime dependency.\n */\nexport function resolveRealtimeUrl(apiBaseUrl: string, explicit?: string): string {\n if (explicit) {\n return explicit.replace(/\\/$/, \"\");\n }\n\n const api = new URL(apiBaseUrl);\n if (api.hostname === \"localhost\" && (api.port === \"3000\" || api.port === \"\")) {\n return \"ws://localhost:3001\";\n }\n\n const protocol = api.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n return `${protocol}//${api.host}`;\n}\n","/**\n * Edit launcher mount/teardown (M2-SDK-05).\n *\n * Intent: dynamic import keeps launcher UI out of the default SDK bundle.\n */\nimport { isEditLauncherArmed, shouldAutoEnableEditMode } from \"./edit-token.js\";\nimport {\n disableEditMode as disableEditModeInternal,\n enableEditMode as enableEditModeInternal,\n isEditModeActive,\n} from \"./edit-mode.js\";\nimport type { InitOptions } from \"./types.js\";\n\ntype EditLauncherModule = typeof import(\"./edit-launcher/index.js\");\n\nlet launcherHandle: { destroy: () => void } | null = null;\nlet launcherLoadPromise: Promise<EditLauncherModule> | null = null;\n\nfunction loadLauncherModule(): Promise<EditLauncherModule> {\n if (!launcherLoadPromise) {\n launcherLoadPromise = import(\"./edit-launcher/index.js\");\n }\n return launcherLoadPromise;\n}\n\nexport function shouldMountEditLauncher(options: InitOptions): boolean {\n if (!options.editLauncher) {\n return false;\n }\n if (options.environment !== \"staging\") {\n return false;\n }\n if (shouldAutoEnableEditMode(options)) {\n return false;\n }\n return isEditLauncherArmed(options.editLauncher);\n}\n\nexport async function mountEditLauncherIfNeeded(options: InitOptions): Promise<void> {\n if (!shouldMountEditLauncher(options)) {\n return;\n }\n\n const launcherOptions = options.editLauncher!;\n const mod = await loadLauncherModule();\n launcherHandle = mod.mountEditLauncher({\n initOptions: options,\n launcherOptions,\n isEditModeActive,\n enableEditMode: () => enableEditModeInternal(),\n disableEditMode: disableEditModeInternal,\n });\n}\n\nexport function teardownEditLauncher(): void {\n launcherHandle?.destroy();\n launcherHandle = null;\n launcherLoadPromise = null;\n}\n"],"mappings":"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","names":["current","getRuntime","getRuntime","enableEditMode","disableEditMode"]}
1
+ {"version":3,"sources":["../src/resolve-key.ts","../src/index.ts","../src/edit-mode.ts","../src/runtime.ts","../src/urls.ts","../src/edit-launcher-lifecycle.ts"],"sourcesContent":["/**\n * Maps DOM nodes to translation keys for overlay edit mode (M2-SDK-02).\n *\n * Intent: host `registerResolver` first; `data-i18n-key` on the element or an ancestor is the fallback.\n */\nimport type { KeyResolver } from \"./runtime.js\";\n\nexport const I18N_KEY_ATTR = \"data-i18n-key\";\n\n/**\n * Resolves a translation key for a DOM node by walking ancestors.\n */\nexport function resolveKeyForElement(\n start: Element,\n resolver: KeyResolver | null,\n): string | null {\n if (resolver) {\n let current: Element | null = start;\n while (current) {\n const resolved = resolver(current);\n if (resolved) {\n return resolved;\n }\n current = current.parentElement;\n }\n }\n\n let current: Element | null = start;\n while (current) {\n const fromAttr = current.getAttribute(I18N_KEY_ATTR);\n if (fromAttr) {\n return fromAttr;\n }\n current = current.parentElement;\n }\n\n return null;\n}\n","/**\n * @stringpush/sdk — plain JS runtime: load manifest + bundles, expose `t()` (ICU in M1-SDK-03).\n *\n * Intent: customer-facing surface; runtime catalog/manifest delegated to @stringpush/runtime-core.\n */\nexport { I18N_KEY_ATTR } from \"./resolve-key.js\";\n\nexport type {\n EditLauncherOptions,\n EnableEditModeOptions,\n Environment,\n InitOptions,\n ManifestLocaleEntry,\n MissingKeyFallback,\n RetryOptions,\n TranslateValues,\n TranslationCatalog,\n TranslationManifest,\n} from \"./types.js\";\n\nimport type { EnableEditModeOptions, InitOptions, TranslateValues } from \"./types.js\";\nimport {\n changeLocale,\n destroyRuntime,\n getRuntime,\n getRuntimeLocale,\n initializeRuntime,\n translateKey,\n} from \"@stringpush/runtime-core\";\nimport { teardownEditLauncher, mountEditLauncherIfNeeded } from \"./edit-launcher-lifecycle.js\";\nimport {\n readEditTokenFromHash,\n readEditTokenFromQuery,\n resolveEditToken,\n shouldAutoEnableEditMode,\n stripEditTokenFromUrl,\n} from \"./edit-token.js\";\nimport {\n disableEditMode as disableEditModeInternal,\n enableEditMode as enableEditModeInternal,\n teardownEditMode,\n} from \"./edit-mode.js\";\nimport { getKeyResolver, setKeyResolver } from \"./runtime.js\";\n\n/**\n * Initialize the SDK: fetch manifest and the active locale bundle into an in-memory catalog.\n *\n * Intent: entry point for customer apps; triggers `onTranslationsUpdated` when the first catalog is ready.\n */\nexport async function init(options: InitOptions): Promise<void> {\n await initializeRuntime(options);\n\n const tokenFromUrl = readEditTokenFromQuery() ?? readEditTokenFromHash();\n if (tokenFromUrl || options.editToken) {\n resolveEditToken(options);\n if (tokenFromUrl) {\n stripEditTokenFromUrl();\n }\n }\n\n if (shouldAutoEnableEditMode(options)) {\n await enableEditModeInternal();\n } else {\n await mountEditLauncherIfNeeded(options);\n }\n}\n\nexport function destroy(): void {\n teardownEditLauncher();\n teardownEditMode();\n setKeyResolver(null);\n destroyRuntime();\n}\n\nexport function getLocale(): string {\n return getRuntimeLocale();\n}\n\n/**\n * Switch active locale and reload its bundle from the manifest.\n */\nexport async function setLocale(locale: string): Promise<void> {\n await changeLocale(locale);\n}\n\n/**\n * Translate a key using the loaded catalog and ICU MessageFormat.\n */\nexport function t(key: string, values?: TranslateValues): string {\n // Intent: preserve @stringpush/sdk error text for public `t()` callers (runtime-core uses initializeRuntime wording).\n if (!getRuntime().options) {\n throw new Error(\"@stringpush/sdk: call init() before using the runtime\");\n }\n return translateKey(key, values);\n}\n\nexport function loadNamespace(_namespace: string): Promise<void> {\n return Promise.resolve();\n}\n\nexport async function enableEditMode(options?: EnableEditModeOptions): Promise<void> {\n await enableEditModeInternal(options);\n}\n\nexport function disableEditMode(): void {\n disableEditModeInternal();\n}\n\nexport function registerResolver(resolver: (element: Element) => string | null): () => void {\n setKeyResolver(resolver);\n return () => {\n if (getKeyResolver() === resolver) {\n setKeyResolver(null);\n }\n };\n}\n","/**\n * Edit-mode lifecycle: lazy overlay chunk load and teardown (M2-SDK-01).\n */\nimport {\n patchCatalogEntry,\n resolveApiBaseUrl,\n} from \"@stringpush/runtime-core\";\nimport { decodeEditTokenClaims } from \"./edit-token-decode.js\";\nimport { adminOriginFromSignInUrl } from \"./edit-launcher/sign-in-popup.js\";\nimport { resolveEditToken } from \"./edit-token.js\";\nimport { resolveKeyForElement } from \"./resolve-key.js\";\nimport { assertInitialized, getKeyResolver, getRuntime } from \"./runtime.js\";\nimport type { EnableEditModeOptions } from \"./types.js\";\nimport { resolveRealtimeUrl } from \"./urls.js\";\n\ntype OverlayModule = typeof import(\"./overlay/index.js\");\n\nlet overlayHandle: { destroy: () => void } | null = null;\nlet overlayLoadPromise: Promise<OverlayModule> | null = null;\n\nfunction loadOverlayModule(): Promise<OverlayModule> {\n if (!overlayLoadPromise) {\n // Intent: dynamic import keeps overlay + WS client out of the default SDK bundle.\n overlayLoadPromise = import(\"./overlay/index.js\");\n }\n return overlayLoadPromise;\n}\n\nexport function isEditModeActive(): boolean {\n return overlayHandle !== null;\n}\n\n/**\n * Activates overlay edit mode when a valid edit JWT is available.\n */\nexport async function enableEditMode(options: EnableEditModeOptions = {}): Promise<void> {\n if (overlayHandle) {\n return;\n }\n\n const initOptions = assertInitialized();\n const state = getRuntime();\n const manifest = state.manifest;\n if (!manifest) {\n throw new Error(\"@stringpush/sdk: manifest is not loaded — call init() before enableEditMode()\");\n }\n\n const editToken = resolveEditToken(initOptions, options.editToken);\n if (!editToken) {\n throw new Error(\n \"@stringpush/sdk: edit token required — pass editToken, ?edit_token=, or sessionStorage\",\n );\n }\n\n const apiBaseUrl = resolveApiBaseUrl(initOptions.apiBaseUrl);\n const realtimeUrl = resolveRealtimeUrl(apiBaseUrl, initOptions.realtimeUrl);\n const overlay = await loadOverlayModule();\n const editClaims = decodeEditTokenClaims(editToken);\n if (!editClaims) {\n throw new Error(\"@stringpush/sdk: edit token is malformed\");\n }\n if (editClaims.projectId !== manifest.projectId) {\n throw new Error(\"@stringpush/sdk: edit token project does not match loaded manifest\");\n }\n if (editClaims.applicationId !== manifest.applicationId) {\n throw new Error(\"@stringpush/sdk: edit token application does not match init()\");\n }\n if (editClaims.environmentName !== initOptions.environment) {\n throw new Error(\n \"@stringpush/sdk: edit token environment does not match init() environment\",\n );\n }\n\n overlayHandle = overlay.mountOverlay({\n projectId: manifest.projectId,\n applicationId: manifest.applicationId,\n environmentId: editClaims.environmentId,\n environmentName: editClaims.environmentName,\n approvalEnabled: false,\n adminWebOrigin: initOptions.editLauncher?.signInUrl\n ? adminOriginFromSignInUrl(initOptions.editLauncher.signInUrl)\n : undefined,\n realtimeUrl,\n editToken,\n apiBaseUrl,\n origin: initOptions.origin,\n activeLocaleCode: state.locale,\n resolveKey: (element) => resolveKeyForElement(element, getKeyResolver()),\n onCatalogPatched: (keyPath, localeCode, value, version) => {\n if (patchCatalogEntry(keyPath, localeCode, value, version)) {\n initOptions.onTranslationsUpdated?.();\n }\n },\n onTranslationsUpdated: () => {\n initOptions.onTranslationsUpdated?.();\n },\n });\n}\n\n/**\n * Tears down overlay DOM and closes the realtime WebSocket.\n */\nexport function disableEditMode(): void {\n overlayHandle?.destroy();\n overlayHandle = null;\n}\n\nexport function teardownEditMode(): void {\n disableEditMode();\n overlayLoadPromise = null;\n}\n","/**\n * DOM-specific runtime helpers (key resolver) atop @stringpush/runtime-core state.\n *\n * Intent: overlay `registerResolver` stays in sdk; catalog/manifest live in runtime-core.\n */\nimport {\n assertInitialized as assertCoreInitialized,\n getRuntime,\n resetRuntime,\n type SdkRuntime,\n} from \"@stringpush/runtime-core\";\nimport type { InitOptions } from \"./types.js\";\n\nexport { getRuntime, resetRuntime, type SdkRuntime };\n\n/** SDK init stores overlay fields on the same options object passed to runtime-core. */\nexport function assertInitialized(): InitOptions {\n return assertCoreInitialized() as InitOptions;\n}\n\nexport type KeyResolver = (element: Element) => string | null;\n\nlet keyResolver: KeyResolver | null = null;\n\nexport function setKeyResolver(resolver: KeyResolver | null): void {\n keyResolver = resolver;\n}\n\nexport function getKeyResolver(): KeyResolver | null {\n return keyResolver;\n}\n","/**\n * WebSocket URL helper for overlay realtime (M2-SDK-01).\n *\n * Intent: overlay-specific; runtime-core has no realtime dependency.\n */\nexport function resolveRealtimeUrl(apiBaseUrl: string, explicit?: string): string {\n if (explicit) {\n return explicit.replace(/\\/$/, \"\");\n }\n\n const api = new URL(apiBaseUrl);\n if (api.hostname === \"localhost\" && (api.port === \"3000\" || api.port === \"\")) {\n return \"ws://localhost:3001\";\n }\n\n const protocol = api.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n return `${protocol}//${api.host}`;\n}\n","/**\n * Edit launcher mount/teardown (M2-SDK-05).\n *\n * Intent: dynamic import keeps launcher UI out of the default SDK bundle.\n */\nimport { isEditLauncherArmed, shouldAutoEnableEditMode } from \"./edit-token.js\";\nimport {\n disableEditMode as disableEditModeInternal,\n enableEditMode as enableEditModeInternal,\n isEditModeActive,\n} from \"./edit-mode.js\";\nimport type { InitOptions } from \"./types.js\";\n\ntype EditLauncherModule = typeof import(\"./edit-launcher/index.js\");\n\nlet launcherHandle: { destroy: () => void } | null = null;\nlet launcherLoadPromise: Promise<EditLauncherModule> | null = null;\n\nfunction loadLauncherModule(): Promise<EditLauncherModule> {\n if (!launcherLoadPromise) {\n launcherLoadPromise = import(\"./edit-launcher/index.js\");\n }\n return launcherLoadPromise;\n}\n\nexport function shouldMountEditLauncher(options: InitOptions): boolean {\n if (!options.editLauncher) {\n return false;\n }\n if (options.environment !== \"staging\") {\n return false;\n }\n if (shouldAutoEnableEditMode(options)) {\n return false;\n }\n return isEditLauncherArmed(options.editLauncher);\n}\n\nexport async function mountEditLauncherIfNeeded(options: InitOptions): Promise<void> {\n if (!shouldMountEditLauncher(options)) {\n return;\n }\n\n const launcherOptions = options.editLauncher!;\n const mod = await loadLauncherModule();\n launcherHandle = mod.mountEditLauncher({\n initOptions: options,\n launcherOptions,\n isEditModeActive,\n enableEditMode: () => enableEditModeInternal(),\n disableEditMode: disableEditModeInternal,\n });\n}\n\nexport function teardownEditLauncher(): void {\n launcherHandle?.destroy();\n launcherHandle = null;\n launcherLoadPromise = null;\n}\n"],"mappings":"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","names":["current","getRuntime","getRuntime","enableEditMode","disableEditMode"]}
@@ -6,7 +6,8 @@
6
6
 
7
7
 
8
8
 
9
- var _chunkFROJCNV7umdcjs = require('./chunk-FROJCNV7.umd.cjs');
9
+
10
+ var _chunkD2H2PTN2umdcjs = require('./chunk-D2H2PTN2.umd.cjs');
10
11
 
11
12
  // src/resolve-key.ts
12
13
  var I18N_KEY_ATTR = "data-i18n-key";
@@ -83,7 +84,7 @@ var overlayHandle = null;
83
84
  var overlayLoadPromise = null;
84
85
  function loadOverlayModule() {
85
86
  if (!overlayLoadPromise) {
86
- overlayLoadPromise = Promise.resolve().then(() => _interopRequireWildcard(require("./overlay-MLOXYRPA.umd.cjs")));
87
+ overlayLoadPromise = Promise.resolve().then(() => _interopRequireWildcard(require("./overlay-WO46AIRO.umd.cjs")));
87
88
  }
88
89
  return overlayLoadPromise;
89
90
  }
@@ -100,7 +101,7 @@ async function enableEditMode(options = {}) {
100
101
  if (!manifest) {
101
102
  throw new Error("@stringpush/sdk: manifest is not loaded \u2014 call init() before enableEditMode()");
102
103
  }
103
- const editToken = _chunkFROJCNV7umdcjs.resolveEditToken.call(void 0, initOptions, options.editToken);
104
+ const editToken = _chunkD2H2PTN2umdcjs.resolveEditToken.call(void 0, initOptions, options.editToken);
104
105
  if (!editToken) {
105
106
  throw new Error(
106
107
  "@stringpush/sdk: edit token required \u2014 pass editToken, ?edit_token=, or sessionStorage"
@@ -109,7 +110,7 @@ async function enableEditMode(options = {}) {
109
110
  const apiBaseUrl = _runtimecore.resolveApiBaseUrl.call(void 0, initOptions.apiBaseUrl);
110
111
  const realtimeUrl = resolveRealtimeUrl(apiBaseUrl, initOptions.realtimeUrl);
111
112
  const overlay = await loadOverlayModule();
112
- const editClaims = _chunkFROJCNV7umdcjs.decodeEditTokenClaims.call(void 0, editToken);
113
+ const editClaims = _chunkD2H2PTN2umdcjs.decodeEditTokenClaims.call(void 0, editToken);
113
114
  if (!editClaims) {
114
115
  throw new Error("@stringpush/sdk: edit token is malformed");
115
116
  }
@@ -128,6 +129,9 @@ async function enableEditMode(options = {}) {
128
129
  projectId: manifest.projectId,
129
130
  applicationId: manifest.applicationId,
130
131
  environmentId: editClaims.environmentId,
132
+ environmentName: editClaims.environmentName,
133
+ approvalEnabled: false,
134
+ adminWebOrigin: _optionalChain([initOptions, 'access', _ => _.editLauncher, 'optionalAccess', _2 => _2.signInUrl]) ? _chunkD2H2PTN2umdcjs.adminOriginFromSignInUrl.call(void 0, initOptions.editLauncher.signInUrl) : void 0,
131
135
  realtimeUrl,
132
136
  editToken,
133
137
  apiBaseUrl,
@@ -136,16 +140,16 @@ async function enableEditMode(options = {}) {
136
140
  resolveKey: (element) => resolveKeyForElement(element, getKeyResolver()),
137
141
  onCatalogPatched: (keyPath, localeCode, value, version) => {
138
142
  if (_runtimecore.patchCatalogEntry.call(void 0, keyPath, localeCode, value, version)) {
139
- _optionalChain([initOptions, 'access', _ => _.onTranslationsUpdated, 'optionalCall', _2 => _2()]);
143
+ _optionalChain([initOptions, 'access', _3 => _3.onTranslationsUpdated, 'optionalCall', _4 => _4()]);
140
144
  }
141
145
  },
142
146
  onTranslationsUpdated: () => {
143
- _optionalChain([initOptions, 'access', _3 => _3.onTranslationsUpdated, 'optionalCall', _4 => _4()]);
147
+ _optionalChain([initOptions, 'access', _5 => _5.onTranslationsUpdated, 'optionalCall', _6 => _6()]);
144
148
  }
145
149
  });
146
150
  }
147
151
  function disableEditMode() {
148
- _optionalChain([overlayHandle, 'optionalAccess', _5 => _5.destroy, 'call', _6 => _6()]);
152
+ _optionalChain([overlayHandle, 'optionalAccess', _7 => _7.destroy, 'call', _8 => _8()]);
149
153
  overlayHandle = null;
150
154
  }
151
155
  function teardownEditMode() {
@@ -158,7 +162,7 @@ var launcherHandle = null;
158
162
  var launcherLoadPromise = null;
159
163
  function loadLauncherModule() {
160
164
  if (!launcherLoadPromise) {
161
- launcherLoadPromise = Promise.resolve().then(() => _interopRequireWildcard(require("./edit-launcher-DB2DJSQJ.umd.cjs")));
165
+ launcherLoadPromise = Promise.resolve().then(() => _interopRequireWildcard(require("./edit-launcher-Z5AGCAQB.umd.cjs")));
162
166
  }
163
167
  return launcherLoadPromise;
164
168
  }
@@ -169,10 +173,10 @@ function shouldMountEditLauncher(options) {
169
173
  if (options.environment !== "staging") {
170
174
  return false;
171
175
  }
172
- if (_chunkFROJCNV7umdcjs.shouldAutoEnableEditMode.call(void 0, options)) {
176
+ if (_chunkD2H2PTN2umdcjs.shouldAutoEnableEditMode.call(void 0, options)) {
173
177
  return false;
174
178
  }
175
- return _chunkFROJCNV7umdcjs.isEditLauncherArmed.call(void 0, options.editLauncher);
179
+ return _chunkD2H2PTN2umdcjs.isEditLauncherArmed.call(void 0, options.editLauncher);
176
180
  }
177
181
  async function mountEditLauncherIfNeeded(options) {
178
182
  if (!shouldMountEditLauncher(options)) {
@@ -189,7 +193,7 @@ async function mountEditLauncherIfNeeded(options) {
189
193
  });
190
194
  }
191
195
  function teardownEditLauncher() {
192
- _optionalChain([launcherHandle, 'optionalAccess', _7 => _7.destroy, 'call', _8 => _8()]);
196
+ _optionalChain([launcherHandle, 'optionalAccess', _9 => _9.destroy, 'call', _10 => _10()]);
193
197
  launcherHandle = null;
194
198
  launcherLoadPromise = null;
195
199
  }
@@ -197,14 +201,14 @@ function teardownEditLauncher() {
197
201
  // src/index.ts
198
202
  async function init(options) {
199
203
  await _runtimecore.initializeRuntime.call(void 0, options);
200
- const tokenFromUrl = _nullishCoalesce(_chunkFROJCNV7umdcjs.readEditTokenFromQuery.call(void 0, ), () => ( _chunkFROJCNV7umdcjs.readEditTokenFromHash.call(void 0, )));
204
+ const tokenFromUrl = _nullishCoalesce(_chunkD2H2PTN2umdcjs.readEditTokenFromQuery.call(void 0, ), () => ( _chunkD2H2PTN2umdcjs.readEditTokenFromHash.call(void 0, )));
201
205
  if (tokenFromUrl || options.editToken) {
202
- _chunkFROJCNV7umdcjs.resolveEditToken.call(void 0, options);
206
+ _chunkD2H2PTN2umdcjs.resolveEditToken.call(void 0, options);
203
207
  if (tokenFromUrl) {
204
- _chunkFROJCNV7umdcjs.stripEditTokenFromUrl.call(void 0, );
208
+ _chunkD2H2PTN2umdcjs.stripEditTokenFromUrl.call(void 0, );
205
209
  }
206
210
  }
207
- if (_chunkFROJCNV7umdcjs.shouldAutoEnableEditMode.call(void 0, options)) {
211
+ if (_chunkD2H2PTN2umdcjs.shouldAutoEnableEditMode.call(void 0, options)) {
208
212
  await enableEditMode();
209
213
  } else {
210
214
  await mountEditLauncherIfNeeded(options);
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/translations/translations/packages/sdk/dist/index.umd.cjs","../src/resolve-key.ts","../src/index.ts","../src/edit-mode.ts","../src/runtime.ts","../src/urls.ts","../src/edit-launcher-lifecycle.ts"],"names":["current","getRuntime","disableEditMode"],"mappings":"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","file":"/home/runner/work/translations/translations/packages/sdk/dist/index.umd.cjs","sourcesContent":[null,"/**\n * Maps DOM nodes to translation keys for overlay edit mode (M2-SDK-02).\n *\n * Intent: host `registerResolver` first; `data-i18n-key` on the element or an ancestor is the fallback.\n */\nimport type { KeyResolver } from \"./runtime.js\";\n\nexport const I18N_KEY_ATTR = \"data-i18n-key\";\n\n/**\n * Resolves a translation key for a DOM node by walking ancestors.\n */\nexport function resolveKeyForElement(\n start: Element,\n resolver: KeyResolver | null,\n): string | null {\n if (resolver) {\n let current: Element | null = start;\n while (current) {\n const resolved = resolver(current);\n if (resolved) {\n return resolved;\n }\n current = current.parentElement;\n }\n }\n\n let current: Element | null = start;\n while (current) {\n const fromAttr = current.getAttribute(I18N_KEY_ATTR);\n if (fromAttr) {\n return fromAttr;\n }\n current = current.parentElement;\n }\n\n return null;\n}\n","/**\n * @stringpush/sdk — plain JS runtime: load manifest + bundles, expose `t()` (ICU in M1-SDK-03).\n *\n * Intent: customer-facing surface; runtime catalog/manifest delegated to @stringpush/runtime-core.\n */\nexport { I18N_KEY_ATTR } from \"./resolve-key.js\";\n\nexport type {\n EditLauncherOptions,\n EnableEditModeOptions,\n Environment,\n InitOptions,\n ManifestLocaleEntry,\n MissingKeyFallback,\n RetryOptions,\n TranslateValues,\n TranslationCatalog,\n TranslationManifest,\n} from \"./types.js\";\n\nimport type { EnableEditModeOptions, InitOptions, TranslateValues } from \"./types.js\";\nimport {\n changeLocale,\n destroyRuntime,\n getRuntime,\n getRuntimeLocale,\n initializeRuntime,\n translateKey,\n} from \"@stringpush/runtime-core\";\nimport { teardownEditLauncher, mountEditLauncherIfNeeded } from \"./edit-launcher-lifecycle.js\";\nimport {\n readEditTokenFromHash,\n readEditTokenFromQuery,\n resolveEditToken,\n shouldAutoEnableEditMode,\n stripEditTokenFromUrl,\n} from \"./edit-token.js\";\nimport {\n disableEditMode as disableEditModeInternal,\n enableEditMode as enableEditModeInternal,\n teardownEditMode,\n} from \"./edit-mode.js\";\nimport { getKeyResolver, setKeyResolver } from \"./runtime.js\";\n\n/**\n * Initialize the SDK: fetch manifest and the active locale bundle into an in-memory catalog.\n *\n * Intent: entry point for customer apps; triggers `onTranslationsUpdated` when the first catalog is ready.\n */\nexport async function init(options: InitOptions): Promise<void> {\n await initializeRuntime(options);\n\n const tokenFromUrl = readEditTokenFromQuery() ?? readEditTokenFromHash();\n if (tokenFromUrl || options.editToken) {\n resolveEditToken(options);\n if (tokenFromUrl) {\n stripEditTokenFromUrl();\n }\n }\n\n if (shouldAutoEnableEditMode(options)) {\n await enableEditModeInternal();\n } else {\n await mountEditLauncherIfNeeded(options);\n }\n}\n\nexport function destroy(): void {\n teardownEditLauncher();\n teardownEditMode();\n setKeyResolver(null);\n destroyRuntime();\n}\n\nexport function getLocale(): string {\n return getRuntimeLocale();\n}\n\n/**\n * Switch active locale and reload its bundle from the manifest.\n */\nexport async function setLocale(locale: string): Promise<void> {\n await changeLocale(locale);\n}\n\n/**\n * Translate a key using the loaded catalog and ICU MessageFormat.\n */\nexport function t(key: string, values?: TranslateValues): string {\n // Intent: preserve @stringpush/sdk error text for public `t()` callers (runtime-core uses initializeRuntime wording).\n if (!getRuntime().options) {\n throw new Error(\"@stringpush/sdk: call init() before using the runtime\");\n }\n return translateKey(key, values);\n}\n\nexport function loadNamespace(_namespace: string): Promise<void> {\n return Promise.resolve();\n}\n\nexport async function enableEditMode(options?: EnableEditModeOptions): Promise<void> {\n await enableEditModeInternal(options);\n}\n\nexport function disableEditMode(): void {\n disableEditModeInternal();\n}\n\nexport function registerResolver(resolver: (element: Element) => string | null): () => void {\n setKeyResolver(resolver);\n return () => {\n if (getKeyResolver() === resolver) {\n setKeyResolver(null);\n }\n };\n}\n","/**\n * Edit-mode lifecycle: lazy overlay chunk load and teardown (M2-SDK-01).\n */\nimport {\n patchCatalogEntry,\n resolveApiBaseUrl,\n} from \"@stringpush/runtime-core\";\nimport { decodeEditTokenClaims } from \"./edit-token-decode.js\";\nimport { resolveEditToken } from \"./edit-token.js\";\nimport { resolveKeyForElement } from \"./resolve-key.js\";\nimport { assertInitialized, getKeyResolver, getRuntime } from \"./runtime.js\";\nimport type { EnableEditModeOptions } from \"./types.js\";\nimport { resolveRealtimeUrl } from \"./urls.js\";\n\ntype OverlayModule = typeof import(\"./overlay/index.js\");\n\nlet overlayHandle: { destroy: () => void } | null = null;\nlet overlayLoadPromise: Promise<OverlayModule> | null = null;\n\nfunction loadOverlayModule(): Promise<OverlayModule> {\n if (!overlayLoadPromise) {\n // Intent: dynamic import keeps overlay + WS client out of the default SDK bundle.\n overlayLoadPromise = import(\"./overlay/index.js\");\n }\n return overlayLoadPromise;\n}\n\nexport function isEditModeActive(): boolean {\n return overlayHandle !== null;\n}\n\n/**\n * Activates overlay edit mode when a valid edit JWT is available.\n */\nexport async function enableEditMode(options: EnableEditModeOptions = {}): Promise<void> {\n if (overlayHandle) {\n return;\n }\n\n const initOptions = assertInitialized();\n const state = getRuntime();\n const manifest = state.manifest;\n if (!manifest) {\n throw new Error(\"@stringpush/sdk: manifest is not loaded — call init() before enableEditMode()\");\n }\n\n const editToken = resolveEditToken(initOptions, options.editToken);\n if (!editToken) {\n throw new Error(\n \"@stringpush/sdk: edit token required — pass editToken, ?edit_token=, or sessionStorage\",\n );\n }\n\n const apiBaseUrl = resolveApiBaseUrl(initOptions.apiBaseUrl);\n const realtimeUrl = resolveRealtimeUrl(apiBaseUrl, initOptions.realtimeUrl);\n const overlay = await loadOverlayModule();\n const editClaims = decodeEditTokenClaims(editToken);\n if (!editClaims) {\n throw new Error(\"@stringpush/sdk: edit token is malformed\");\n }\n if (editClaims.projectId !== manifest.projectId) {\n throw new Error(\"@stringpush/sdk: edit token project does not match loaded manifest\");\n }\n if (editClaims.applicationId !== manifest.applicationId) {\n throw new Error(\"@stringpush/sdk: edit token application does not match init()\");\n }\n if (editClaims.environmentName !== initOptions.environment) {\n throw new Error(\n \"@stringpush/sdk: edit token environment does not match init() environment\",\n );\n }\n\n overlayHandle = overlay.mountOverlay({\n projectId: manifest.projectId,\n applicationId: manifest.applicationId,\n environmentId: editClaims.environmentId,\n realtimeUrl,\n editToken,\n apiBaseUrl,\n origin: initOptions.origin,\n activeLocaleCode: state.locale,\n resolveKey: (element) => resolveKeyForElement(element, getKeyResolver()),\n onCatalogPatched: (keyPath, localeCode, value, version) => {\n if (patchCatalogEntry(keyPath, localeCode, value, version)) {\n initOptions.onTranslationsUpdated?.();\n }\n },\n onTranslationsUpdated: () => {\n initOptions.onTranslationsUpdated?.();\n },\n });\n}\n\n/**\n * Tears down overlay DOM and closes the realtime WebSocket.\n */\nexport function disableEditMode(): void {\n overlayHandle?.destroy();\n overlayHandle = null;\n}\n\nexport function teardownEditMode(): void {\n disableEditMode();\n overlayLoadPromise = null;\n}\n","/**\n * DOM-specific runtime helpers (key resolver) atop @stringpush/runtime-core state.\n *\n * Intent: overlay `registerResolver` stays in sdk; catalog/manifest live in runtime-core.\n */\nimport {\n assertInitialized as assertCoreInitialized,\n getRuntime,\n resetRuntime,\n type SdkRuntime,\n} from \"@stringpush/runtime-core\";\nimport type { InitOptions } from \"./types.js\";\n\nexport { getRuntime, resetRuntime, type SdkRuntime };\n\n/** SDK init stores overlay fields on the same options object passed to runtime-core. */\nexport function assertInitialized(): InitOptions {\n return assertCoreInitialized() as InitOptions;\n}\n\nexport type KeyResolver = (element: Element) => string | null;\n\nlet keyResolver: KeyResolver | null = null;\n\nexport function setKeyResolver(resolver: KeyResolver | null): void {\n keyResolver = resolver;\n}\n\nexport function getKeyResolver(): KeyResolver | null {\n return keyResolver;\n}\n","/**\n * WebSocket URL helper for overlay realtime (M2-SDK-01).\n *\n * Intent: overlay-specific; runtime-core has no realtime dependency.\n */\nexport function resolveRealtimeUrl(apiBaseUrl: string, explicit?: string): string {\n if (explicit) {\n return explicit.replace(/\\/$/, \"\");\n }\n\n const api = new URL(apiBaseUrl);\n if (api.hostname === \"localhost\" && (api.port === \"3000\" || api.port === \"\")) {\n return \"ws://localhost:3001\";\n }\n\n const protocol = api.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n return `${protocol}//${api.host}`;\n}\n","/**\n * Edit launcher mount/teardown (M2-SDK-05).\n *\n * Intent: dynamic import keeps launcher UI out of the default SDK bundle.\n */\nimport { isEditLauncherArmed, shouldAutoEnableEditMode } from \"./edit-token.js\";\nimport {\n disableEditMode as disableEditModeInternal,\n enableEditMode as enableEditModeInternal,\n isEditModeActive,\n} from \"./edit-mode.js\";\nimport type { InitOptions } from \"./types.js\";\n\ntype EditLauncherModule = typeof import(\"./edit-launcher/index.js\");\n\nlet launcherHandle: { destroy: () => void } | null = null;\nlet launcherLoadPromise: Promise<EditLauncherModule> | null = null;\n\nfunction loadLauncherModule(): Promise<EditLauncherModule> {\n if (!launcherLoadPromise) {\n launcherLoadPromise = import(\"./edit-launcher/index.js\");\n }\n return launcherLoadPromise;\n}\n\nexport function shouldMountEditLauncher(options: InitOptions): boolean {\n if (!options.editLauncher) {\n return false;\n }\n if (options.environment !== \"staging\") {\n return false;\n }\n if (shouldAutoEnableEditMode(options)) {\n return false;\n }\n return isEditLauncherArmed(options.editLauncher);\n}\n\nexport async function mountEditLauncherIfNeeded(options: InitOptions): Promise<void> {\n if (!shouldMountEditLauncher(options)) {\n return;\n }\n\n const launcherOptions = options.editLauncher!;\n const mod = await loadLauncherModule();\n launcherHandle = mod.mountEditLauncher({\n initOptions: options,\n launcherOptions,\n isEditModeActive,\n enableEditMode: () => enableEditModeInternal(),\n disableEditMode: disableEditModeInternal,\n });\n}\n\nexport function teardownEditLauncher(): void {\n launcherHandle?.destroy();\n launcherHandle = null;\n launcherLoadPromise = null;\n}\n"]}
1
+ {"version":3,"sources":["/home/runner/work/translations/translations/packages/sdk/dist/index.umd.cjs","../src/resolve-key.ts","../src/index.ts","../src/edit-mode.ts","../src/runtime.ts","../src/urls.ts","../src/edit-launcher-lifecycle.ts"],"names":["current","getRuntime","disableEditMode"],"mappings":"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","file":"/home/runner/work/translations/translations/packages/sdk/dist/index.umd.cjs","sourcesContent":[null,"/**\n * Maps DOM nodes to translation keys for overlay edit mode (M2-SDK-02).\n *\n * Intent: host `registerResolver` first; `data-i18n-key` on the element or an ancestor is the fallback.\n */\nimport type { KeyResolver } from \"./runtime.js\";\n\nexport const I18N_KEY_ATTR = \"data-i18n-key\";\n\n/**\n * Resolves a translation key for a DOM node by walking ancestors.\n */\nexport function resolveKeyForElement(\n start: Element,\n resolver: KeyResolver | null,\n): string | null {\n if (resolver) {\n let current: Element | null = start;\n while (current) {\n const resolved = resolver(current);\n if (resolved) {\n return resolved;\n }\n current = current.parentElement;\n }\n }\n\n let current: Element | null = start;\n while (current) {\n const fromAttr = current.getAttribute(I18N_KEY_ATTR);\n if (fromAttr) {\n return fromAttr;\n }\n current = current.parentElement;\n }\n\n return null;\n}\n","/**\n * @stringpush/sdk — plain JS runtime: load manifest + bundles, expose `t()` (ICU in M1-SDK-03).\n *\n * Intent: customer-facing surface; runtime catalog/manifest delegated to @stringpush/runtime-core.\n */\nexport { I18N_KEY_ATTR } from \"./resolve-key.js\";\n\nexport type {\n EditLauncherOptions,\n EnableEditModeOptions,\n Environment,\n InitOptions,\n ManifestLocaleEntry,\n MissingKeyFallback,\n RetryOptions,\n TranslateValues,\n TranslationCatalog,\n TranslationManifest,\n} from \"./types.js\";\n\nimport type { EnableEditModeOptions, InitOptions, TranslateValues } from \"./types.js\";\nimport {\n changeLocale,\n destroyRuntime,\n getRuntime,\n getRuntimeLocale,\n initializeRuntime,\n translateKey,\n} from \"@stringpush/runtime-core\";\nimport { teardownEditLauncher, mountEditLauncherIfNeeded } from \"./edit-launcher-lifecycle.js\";\nimport {\n readEditTokenFromHash,\n readEditTokenFromQuery,\n resolveEditToken,\n shouldAutoEnableEditMode,\n stripEditTokenFromUrl,\n} from \"./edit-token.js\";\nimport {\n disableEditMode as disableEditModeInternal,\n enableEditMode as enableEditModeInternal,\n teardownEditMode,\n} from \"./edit-mode.js\";\nimport { getKeyResolver, setKeyResolver } from \"./runtime.js\";\n\n/**\n * Initialize the SDK: fetch manifest and the active locale bundle into an in-memory catalog.\n *\n * Intent: entry point for customer apps; triggers `onTranslationsUpdated` when the first catalog is ready.\n */\nexport async function init(options: InitOptions): Promise<void> {\n await initializeRuntime(options);\n\n const tokenFromUrl = readEditTokenFromQuery() ?? readEditTokenFromHash();\n if (tokenFromUrl || options.editToken) {\n resolveEditToken(options);\n if (tokenFromUrl) {\n stripEditTokenFromUrl();\n }\n }\n\n if (shouldAutoEnableEditMode(options)) {\n await enableEditModeInternal();\n } else {\n await mountEditLauncherIfNeeded(options);\n }\n}\n\nexport function destroy(): void {\n teardownEditLauncher();\n teardownEditMode();\n setKeyResolver(null);\n destroyRuntime();\n}\n\nexport function getLocale(): string {\n return getRuntimeLocale();\n}\n\n/**\n * Switch active locale and reload its bundle from the manifest.\n */\nexport async function setLocale(locale: string): Promise<void> {\n await changeLocale(locale);\n}\n\n/**\n * Translate a key using the loaded catalog and ICU MessageFormat.\n */\nexport function t(key: string, values?: TranslateValues): string {\n // Intent: preserve @stringpush/sdk error text for public `t()` callers (runtime-core uses initializeRuntime wording).\n if (!getRuntime().options) {\n throw new Error(\"@stringpush/sdk: call init() before using the runtime\");\n }\n return translateKey(key, values);\n}\n\nexport function loadNamespace(_namespace: string): Promise<void> {\n return Promise.resolve();\n}\n\nexport async function enableEditMode(options?: EnableEditModeOptions): Promise<void> {\n await enableEditModeInternal(options);\n}\n\nexport function disableEditMode(): void {\n disableEditModeInternal();\n}\n\nexport function registerResolver(resolver: (element: Element) => string | null): () => void {\n setKeyResolver(resolver);\n return () => {\n if (getKeyResolver() === resolver) {\n setKeyResolver(null);\n }\n };\n}\n","/**\n * Edit-mode lifecycle: lazy overlay chunk load and teardown (M2-SDK-01).\n */\nimport {\n patchCatalogEntry,\n resolveApiBaseUrl,\n} from \"@stringpush/runtime-core\";\nimport { decodeEditTokenClaims } from \"./edit-token-decode.js\";\nimport { adminOriginFromSignInUrl } from \"./edit-launcher/sign-in-popup.js\";\nimport { resolveEditToken } from \"./edit-token.js\";\nimport { resolveKeyForElement } from \"./resolve-key.js\";\nimport { assertInitialized, getKeyResolver, getRuntime } from \"./runtime.js\";\nimport type { EnableEditModeOptions } from \"./types.js\";\nimport { resolveRealtimeUrl } from \"./urls.js\";\n\ntype OverlayModule = typeof import(\"./overlay/index.js\");\n\nlet overlayHandle: { destroy: () => void } | null = null;\nlet overlayLoadPromise: Promise<OverlayModule> | null = null;\n\nfunction loadOverlayModule(): Promise<OverlayModule> {\n if (!overlayLoadPromise) {\n // Intent: dynamic import keeps overlay + WS client out of the default SDK bundle.\n overlayLoadPromise = import(\"./overlay/index.js\");\n }\n return overlayLoadPromise;\n}\n\nexport function isEditModeActive(): boolean {\n return overlayHandle !== null;\n}\n\n/**\n * Activates overlay edit mode when a valid edit JWT is available.\n */\nexport async function enableEditMode(options: EnableEditModeOptions = {}): Promise<void> {\n if (overlayHandle) {\n return;\n }\n\n const initOptions = assertInitialized();\n const state = getRuntime();\n const manifest = state.manifest;\n if (!manifest) {\n throw new Error(\"@stringpush/sdk: manifest is not loaded — call init() before enableEditMode()\");\n }\n\n const editToken = resolveEditToken(initOptions, options.editToken);\n if (!editToken) {\n throw new Error(\n \"@stringpush/sdk: edit token required — pass editToken, ?edit_token=, or sessionStorage\",\n );\n }\n\n const apiBaseUrl = resolveApiBaseUrl(initOptions.apiBaseUrl);\n const realtimeUrl = resolveRealtimeUrl(apiBaseUrl, initOptions.realtimeUrl);\n const overlay = await loadOverlayModule();\n const editClaims = decodeEditTokenClaims(editToken);\n if (!editClaims) {\n throw new Error(\"@stringpush/sdk: edit token is malformed\");\n }\n if (editClaims.projectId !== manifest.projectId) {\n throw new Error(\"@stringpush/sdk: edit token project does not match loaded manifest\");\n }\n if (editClaims.applicationId !== manifest.applicationId) {\n throw new Error(\"@stringpush/sdk: edit token application does not match init()\");\n }\n if (editClaims.environmentName !== initOptions.environment) {\n throw new Error(\n \"@stringpush/sdk: edit token environment does not match init() environment\",\n );\n }\n\n overlayHandle = overlay.mountOverlay({\n projectId: manifest.projectId,\n applicationId: manifest.applicationId,\n environmentId: editClaims.environmentId,\n environmentName: editClaims.environmentName,\n approvalEnabled: false,\n adminWebOrigin: initOptions.editLauncher?.signInUrl\n ? adminOriginFromSignInUrl(initOptions.editLauncher.signInUrl)\n : undefined,\n realtimeUrl,\n editToken,\n apiBaseUrl,\n origin: initOptions.origin,\n activeLocaleCode: state.locale,\n resolveKey: (element) => resolveKeyForElement(element, getKeyResolver()),\n onCatalogPatched: (keyPath, localeCode, value, version) => {\n if (patchCatalogEntry(keyPath, localeCode, value, version)) {\n initOptions.onTranslationsUpdated?.();\n }\n },\n onTranslationsUpdated: () => {\n initOptions.onTranslationsUpdated?.();\n },\n });\n}\n\n/**\n * Tears down overlay DOM and closes the realtime WebSocket.\n */\nexport function disableEditMode(): void {\n overlayHandle?.destroy();\n overlayHandle = null;\n}\n\nexport function teardownEditMode(): void {\n disableEditMode();\n overlayLoadPromise = null;\n}\n","/**\n * DOM-specific runtime helpers (key resolver) atop @stringpush/runtime-core state.\n *\n * Intent: overlay `registerResolver` stays in sdk; catalog/manifest live in runtime-core.\n */\nimport {\n assertInitialized as assertCoreInitialized,\n getRuntime,\n resetRuntime,\n type SdkRuntime,\n} from \"@stringpush/runtime-core\";\nimport type { InitOptions } from \"./types.js\";\n\nexport { getRuntime, resetRuntime, type SdkRuntime };\n\n/** SDK init stores overlay fields on the same options object passed to runtime-core. */\nexport function assertInitialized(): InitOptions {\n return assertCoreInitialized() as InitOptions;\n}\n\nexport type KeyResolver = (element: Element) => string | null;\n\nlet keyResolver: KeyResolver | null = null;\n\nexport function setKeyResolver(resolver: KeyResolver | null): void {\n keyResolver = resolver;\n}\n\nexport function getKeyResolver(): KeyResolver | null {\n return keyResolver;\n}\n","/**\n * WebSocket URL helper for overlay realtime (M2-SDK-01).\n *\n * Intent: overlay-specific; runtime-core has no realtime dependency.\n */\nexport function resolveRealtimeUrl(apiBaseUrl: string, explicit?: string): string {\n if (explicit) {\n return explicit.replace(/\\/$/, \"\");\n }\n\n const api = new URL(apiBaseUrl);\n if (api.hostname === \"localhost\" && (api.port === \"3000\" || api.port === \"\")) {\n return \"ws://localhost:3001\";\n }\n\n const protocol = api.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n return `${protocol}//${api.host}`;\n}\n","/**\n * Edit launcher mount/teardown (M2-SDK-05).\n *\n * Intent: dynamic import keeps launcher UI out of the default SDK bundle.\n */\nimport { isEditLauncherArmed, shouldAutoEnableEditMode } from \"./edit-token.js\";\nimport {\n disableEditMode as disableEditModeInternal,\n enableEditMode as enableEditModeInternal,\n isEditModeActive,\n} from \"./edit-mode.js\";\nimport type { InitOptions } from \"./types.js\";\n\ntype EditLauncherModule = typeof import(\"./edit-launcher/index.js\");\n\nlet launcherHandle: { destroy: () => void } | null = null;\nlet launcherLoadPromise: Promise<EditLauncherModule> | null = null;\n\nfunction loadLauncherModule(): Promise<EditLauncherModule> {\n if (!launcherLoadPromise) {\n launcherLoadPromise = import(\"./edit-launcher/index.js\");\n }\n return launcherLoadPromise;\n}\n\nexport function shouldMountEditLauncher(options: InitOptions): boolean {\n if (!options.editLauncher) {\n return false;\n }\n if (options.environment !== \"staging\") {\n return false;\n }\n if (shouldAutoEnableEditMode(options)) {\n return false;\n }\n return isEditLauncherArmed(options.editLauncher);\n}\n\nexport async function mountEditLauncherIfNeeded(options: InitOptions): Promise<void> {\n if (!shouldMountEditLauncher(options)) {\n return;\n }\n\n const launcherOptions = options.editLauncher!;\n const mod = await loadLauncherModule();\n launcherHandle = mod.mountEditLauncher({\n initOptions: options,\n launcherOptions,\n isEditModeActive,\n enableEditMode: () => enableEditModeInternal(),\n disableEditMode: disableEditModeInternal,\n });\n}\n\nexport function teardownEditLauncher(): void {\n launcherHandle?.destroy();\n launcherHandle = null;\n launcherLoadPromise = null;\n}\n"]}