@contentstorage/i18next-plugin 2.0.14 → 2.1.0-2

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/README.md CHANGED
@@ -477,10 +477,6 @@ import type {
477
477
  - Ensure Contentstorage CDN allows your domain
478
478
  - Use custom `request` function to debug
479
479
 
480
- ## Contributing
481
-
482
- Contributions are welcome! Please see our [Contributing Guide](CONTRIBUTING.md).
483
-
484
480
  ## License
485
481
 
486
482
  MIT License - see [LICENSE](LICENSE) file for details.
package/dist/index.esm.js CHANGED
@@ -212,6 +212,8 @@ function extractUserVariables(options) {
212
212
  }
213
213
  return hasVariables ? variables : undefined;
214
214
  }
215
+ // Schedule clear for next frame (memory map cleanup)
216
+ let clearScheduled = false;
215
217
  /**
216
218
  * Tracks a translation in the memory map
217
219
  *
@@ -226,6 +228,18 @@ function trackTranslation(translationValue, translationKey, namespace, language,
226
228
  const memoryMap = getMemoryMap();
227
229
  if (!memoryMap)
228
230
  return;
231
+ // Schedule clear for next frame (only once per frame)
232
+ // This ensures only currently rendered translations remain in the map
233
+ if (!clearScheduled && isBrowser()) {
234
+ clearScheduled = true;
235
+ requestAnimationFrame(() => {
236
+ memoryMap.clear();
237
+ clearScheduled = false;
238
+ if (debug) {
239
+ console.log('[ContentStorage] Memory map cleared for new frame');
240
+ }
241
+ });
242
+ }
229
243
  // Normalize the key
230
244
  const normalizedKey = normalizeKey(translationKey);
231
245
  // Get or create entry
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/utils.ts","../src/post-processor.ts","../src/plugin.ts"],"sourcesContent":["import type { ContentstorageWindow, MemoryMap, MemoryMapEntry } from './types';\n\n/**\n * Checks if the code is running in a browser environment\n */\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\n/**\n * Gets the Contentstorage window object with type safety\n */\nexport function getContentstorageWindow(): ContentstorageWindow | null {\n if (!isBrowser()) return null;\n return window as ContentstorageWindow;\n}\n\n/**\n * Detects if the application is running in ContentStorage live editor mode\n *\n * @param liveEditorParam - Query parameter name to check\n * @param forceLiveMode - Force live mode regardless of environment\n * @returns true if in live editor mode\n */\nexport function detectLiveEditorMode(\n liveEditorParam: string = 'contentstorage_live_editor',\n forceLiveMode: boolean = false\n): boolean {\n if (forceLiveMode) return true;\n if (!isBrowser()) return false;\n\n try {\n const win = getContentstorageWindow();\n if (!win) return false;\n\n // Check 1: Running in an iframe\n const inIframe = win.self !== win.top;\n\n // Check 2: URL has the live editor marker\n const urlParams = new URLSearchParams(win.location.search);\n const hasMarker = urlParams.has(liveEditorParam);\n\n return !!(inIframe && hasMarker);\n } catch (e) {\n // Cross-origin restrictions might block window.top access\n // This is expected when not in live editor mode\n return false;\n }\n}\n\n/**\n * Initializes the global memory map if it doesn't exist\n */\nexport function initializeMemoryMap(): MemoryMap | null {\n const win = getContentstorageWindow();\n if (!win) return null;\n\n if (!win.memoryMap) {\n win.memoryMap = new Map<string, MemoryMapEntry>();\n }\n\n return win.memoryMap;\n}\n\n/**\n * Load the ContentStorage live editor script\n * This script enables the click-to-edit functionality in the live editor\n */\nlet liveEditorReadyPromise: Promise<boolean> | null = null;\n\nexport function loadLiveEditorScript(\n retries: number = 2,\n delay: number = 3000,\n debug: boolean = false,\n customScriptUrl?: string\n): Promise<boolean> {\n // Return existing promise if already loading\n if (liveEditorReadyPromise) {\n return liveEditorReadyPromise;\n }\n\n liveEditorReadyPromise = new Promise<boolean>((resolve) => {\n const win = getContentstorageWindow();\n if (!win) {\n resolve(false);\n return;\n }\n\n const cdnScriptUrl = customScriptUrl || 'https://cdn.contentstorage.app/live-editor.js?contentstorage-live-editor=true';\n\n const loadScript = (attempt: number = 1) => {\n if (debug) {\n console.log(`[ContentStorage] Attempting to load live editor script (attempt ${attempt}/${retries})`);\n }\n\n const scriptElement = win.document.createElement('script');\n scriptElement.type = 'text/javascript';\n scriptElement.src = cdnScriptUrl;\n\n scriptElement.onload = () => {\n if (debug) {\n console.log(`[ContentStorage] Live editor script loaded successfully`);\n }\n resolve(true);\n };\n\n scriptElement.onerror = (error) => {\n // Clean up the failed script element\n scriptElement.remove();\n\n if (debug) {\n console.error(`[ContentStorage] Failed to load live editor script (attempt ${attempt}/${retries})`, error);\n }\n\n if (attempt < retries) {\n setTimeout(() => loadScript(attempt + 1), delay);\n } else {\n console.error(`[ContentStorage] All ${retries} attempts to load live editor script failed`);\n resolve(false);\n }\n };\n\n win.document.head.appendChild(scriptElement);\n };\n\n loadScript();\n });\n\n return liveEditorReadyPromise;\n}\n\n/**\n * Gets the global memory map\n */\nexport function getMemoryMap(): MemoryMap | null {\n const win = getContentstorageWindow();\n return win?.memoryMap || null;\n}\n\n/**\n * Sets the current language code on the window object\n * This is used by the live editor to know which language is currently active\n *\n * @param languageCode - The language code to set (e.g., 'en', 'es', 'fr')\n */\nexport function setCurrentLanguageCode(languageCode: string): void {\n const win = getContentstorageWindow();\n if (win) {\n win.currentLanguageCode = languageCode;\n }\n}\n\n/**\n * Gets the current language code from the window object\n *\n * @returns The current language code, or null if not set\n */\nexport function getCurrentLanguageCode(): string | null {\n const win = getContentstorageWindow();\n return win?.currentLanguageCode || null;\n}\n\n/**\n * Normalizes i18next key format to consistent dot notation\n * Converts namespace:key format to namespace.key\n * Only adds namespace prefix if explicitly present in the key (colon notation)\n *\n * @param key - The translation key\n * @param namespace - Optional namespace (only used if not already in key)\n * @returns Normalized key in dot notation\n */\nexport function normalizeKey(key: string, namespace?: string): string {\n // namespace parameter kept for backward compatibility but not used\n void namespace;\n\n let normalizedKey = key;\n\n // Convert colon notation to dot notation (e.g., \"common:welcome\" -> \"common.welcome\")\n if (normalizedKey.includes(':')) {\n normalizedKey = normalizedKey.replace(':', '.');\n }\n\n // Don't automatically prepend namespace - only if key already had it via colon notation\n // This ensures keys match ContentStorage content IDs by default\n\n return normalizedKey;\n}\n\n/**\n * Extracts the base translation key without interpolation context\n * Handles plural forms, contexts, and other i18next features\n *\n * Examples:\n * - 'welcome' -> 'welcome'\n * - 'items_plural' -> 'items'\n * - 'friend_male' -> 'friend'\n *\n * @param key - The translation key\n * @returns Base key without suffixes\n */\nexport function extractBaseKey(key: string): string {\n // Remove plural suffixes (_zero, _one, _two, _few, _many, _other, _plural)\n let baseKey = key.replace(/_(zero|one|two|few|many|other|plural)$/, '');\n\n // Remove context suffixes (anything after last underscore that's not a nested key)\n // Be careful not to remove underscores that are part of the actual key\n // This is a heuristic - contexts usually come at the end\n const lastUnderscore = baseKey.lastIndexOf('_');\n if (lastUnderscore > 0) {\n // Only remove if it looks like a context (short suffix, typically lowercase)\n const suffix = baseKey.substring(lastUnderscore + 1);\n if (suffix.length < 10 && suffix.toLowerCase() === suffix) {\n // This might be a context, but we'll keep it for now to avoid false positives\n // Real context handling should be done at a higher level\n }\n }\n\n return baseKey;\n}\n\n/**\n * Removes interpolation variables from a translated string\n *\n * Examples:\n * - 'Hello {{name}}!' -> 'Hello !'\n * - 'You have {{count}} items' -> 'You have items'\n *\n * @param value - The translated string\n * @returns String with interpolations removed\n */\nexport function removeInterpolation(value: string): string {\n // Remove i18next interpolation syntax: {{variable}}\n return value.replace(/\\{\\{[^}]+\\}\\}/g, '').trim();\n}\n\n/**\n * i18next internal option keys that should not be treated as user variables\n * Note: 'count' and 'context' are included as they are often used in interpolation\n */\nconst I18NEXT_INTERNAL_KEYS = new Set([\n 'defaultValue',\n 'replace',\n 'lng',\n 'lngs',\n 'fallbackLng',\n 'ns',\n 'keySeparator',\n 'nsSeparator',\n 'returnObjects',\n 'returnDetails',\n 'returnedObjectHandler',\n 'joinArrays',\n 'postProcess',\n 'interpolation',\n 'skipInterpolation',\n 'appendNamespaceToMissingKey',\n 'missingKeyHandler',\n 'parseMissingKeyHandler',\n 'overloadTranslationOptionHandler',\n 'saveMissing',\n 'saveMissingTo',\n 'missingKeyNoValueFallbackToKey',\n 'missingInterpolationHandler',\n 'formatSeparator',\n 'ignoreJSONStructure',\n]);\n\n/**\n * Extracts user-provided variables from i18next options\n * Filters out i18next internal options to return only interpolation variables\n *\n * @param options - i18next options object\n * @returns Object containing only user variables, or undefined if none\n */\nexport function extractUserVariables(options?: any): Record<string, any> | undefined {\n if (!options || typeof options !== 'object') {\n return undefined;\n }\n\n const variables: Record<string, any> = {};\n let hasVariables = false;\n\n for (const key in options) {\n if (!Object.prototype.hasOwnProperty.call(options, key)) continue;\n\n // Skip i18next internal keys\n if (I18NEXT_INTERNAL_KEYS.has(key)) continue;\n\n // Skip keys starting with underscore (private i18next properties)\n if (key.startsWith('_')) continue;\n\n // Skip undefined values\n if (options[key] === undefined) continue;\n\n // This is a user variable\n variables[key] = options[key];\n hasVariables = true;\n }\n\n return hasVariables ? variables : undefined;\n}\n\n/**\n * Tracks a translation in the memory map\n *\n * @param translationValue - The actual translated text\n * @param translationKey - The content ID (i18next key)\n * @param namespace - Optional namespace\n * @param language - Optional language code\n * @param debug - Enable debug logging\n * @param variables - Optional interpolation variables used in the translation\n */\nexport function trackTranslation(\n translationValue: string,\n translationKey: string,\n namespace?: string,\n language?: string,\n debug: boolean = false,\n variables?: Record<string, any>\n): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap) return;\n\n // Normalize the key\n const normalizedKey = normalizeKey(translationKey, namespace);\n\n // Get or create entry\n const existingEntry = memoryMap.get(translationValue);\n const idSet = existingEntry ? existingEntry.ids : new Set<string>();\n idSet.add(normalizedKey);\n\n // Merge variables: prefer new variables if provided, otherwise keep existing\n // This ensures variables are preserved when backend tracks without them\n const mergedVariables = variables && Object.keys(variables).length > 0\n ? variables\n : existingEntry?.variables;\n\n const entry: MemoryMapEntry = {\n ids: idSet,\n type: 'text',\n ...(mergedVariables && Object.keys(mergedVariables).length > 0 && { variables: mergedVariables }),\n metadata: {\n namespace,\n language,\n trackedAt: Date.now(),\n },\n };\n\n memoryMap.set(translationValue, entry);\n\n if (debug) {\n console.log('[ContentStorage] Tracked translation:', {\n value: translationValue,\n key: normalizedKey,\n namespace,\n language,\n variables,\n });\n }\n}\n\n/**\n * Cleans up old entries from memory map when size exceeds limit\n * Removes oldest entries first (based on trackedAt timestamp)\n *\n * @param maxSize - Maximum number of entries to keep\n */\nexport function cleanupMemoryMap(maxSize: number): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap || memoryMap.size <= maxSize) return;\n\n // Convert to array with timestamps\n const entries = Array.from(memoryMap.entries()).map(([key, value]) => ({\n key,\n value,\n timestamp: value.metadata?.trackedAt || 0,\n }));\n\n // Sort by timestamp (oldest first)\n entries.sort((a, b) => a.timestamp - b.timestamp);\n\n // Calculate how many to remove\n const toRemove = memoryMap.size - maxSize;\n\n // Remove oldest entries\n for (let i = 0; i < toRemove; i++) {\n memoryMap.delete(entries[i].key);\n }\n}\n\n/**\n * Deeply traverses a translation object and extracts all string values with their keys\n *\n * @param obj - Translation object to traverse\n * @param prefix - Current key prefix (for nested objects)\n * @returns Array of [key, value] pairs\n */\nexport function flattenTranslations(\n obj: any,\n prefix: string = ''\n): Array<[string, string]> {\n const results: Array<[string, string]> = [];\n\n for (const key in obj) {\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n\n const value = obj[key];\n const fullKey = prefix ? `${prefix}.${key}` : key;\n\n if (typeof value === 'string') {\n results.push([fullKey, value]);\n } else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n // Recurse into nested objects\n results.push(...flattenTranslations(value, fullKey));\n }\n }\n\n return results;\n}\n\n/**\n * Debug helper to log memory map contents\n */\nexport function debugMemoryMap(): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap) {\n console.log('[ContentStorage] Memory map not initialized');\n return;\n }\n\n console.log('[ContentStorage] Memory map contents:');\n console.log(`Total entries: ${memoryMap.size}`);\n\n const entries = Array.from(memoryMap.entries()).slice(0, 10);\n console.table(\n entries.map(([value, entry]) => ({\n value: value.substring(0, 50),\n keys: Array.from(entry.ids).join(', '),\n namespace: entry.metadata?.namespace || 'N/A',\n }))\n );\n\n if (memoryMap.size > 10) {\n console.log(`... and ${memoryMap.size - 10} more entries`);\n }\n}\n","import type { PostProcessorModule } from 'i18next';\nimport type { ContentstoragePluginOptions } from './types';\nimport { trackTranslation, detectLiveEditorMode, initializeMemoryMap, loadLiveEditorScript, extractUserVariables, setCurrentLanguageCode } from './utils';\n\n/**\n * Contentstorage Live Editor Post-Processor\n *\n * This post-processor enables live editor functionality by tracking translations\n * at the point of resolution, capturing the actual values returned by i18next\n * including interpolations and plural forms.\n *\n * Use this to enable click-to-edit functionality in the Contentstorage live editor.\n * It works in addition to or instead of the backend plugin for more comprehensive\n * tracking, especially for dynamic translations.\n *\n * @example\n * ```typescript\n * import i18next from 'i18next';\n * import { ContentstorageLiveEditorPostProcessor } from '@contentstorage/i18next-plugin';\n *\n * i18next\n * .use(new ContentstorageLiveEditorPostProcessor({ debug: true }))\n * .init({\n * postProcess: ['contentstorage']\n * });\n * ```\n */\nexport class ContentstorageLiveEditorPostProcessor implements PostProcessorModule {\n static type: 'postProcessor' = 'postProcessor';\n type: 'postProcessor' = 'postProcessor';\n name: string = 'contentstorage';\n\n private options: ContentstoragePluginOptions;\n private isLiveMode: boolean = false;\n\n constructor(options: ContentstoragePluginOptions = {}) {\n this.options = {\n debug: false,\n liveEditorParam: 'contentstorage_live_editor',\n forceLiveMode: false,\n ...options,\n };\n\n // Detect live editor mode\n this.isLiveMode = detectLiveEditorMode(\n this.options.liveEditorParam,\n this.options.forceLiveMode\n );\n\n if (this.isLiveMode) {\n initializeMemoryMap();\n\n // Initialize current language code with browser language or fallback\n // This ensures window.currentLanguageCode is never undefined\n const browserLanguage = typeof navigator !== 'undefined' && navigator.language\n ? navigator.language.split('-')[0]\n : 'en';\n setCurrentLanguageCode(browserLanguage);\n\n // Load the live editor script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);\n\n if (this.options.debug) {\n console.log('[ContentStorage] Post-processor initialized in live mode');\n console.log(`[ContentStorage] Initial language code set to: ${browserLanguage}`);\n }\n }\n }\n\n /**\n * Process the translated value\n * Called by i18next after translation resolution\n */\n process(\n value: string,\n key: string | string[],\n options: any,\n translator: any\n ): string {\n // Only track in live mode\n if (!this.isLiveMode) {\n return value;\n }\n\n // Handle array of keys (fallback keys)\n const translationKey = Array.isArray(key) ? key[0] : key;\n\n // Only extract namespace if key explicitly uses colon notation\n // Don't pass namespace from options - let keys be clean by default\n let namespace: string | undefined;\n if (translationKey.includes(':')) {\n [namespace] = translationKey.split(':');\n }\n console.log('[Contentstorage plugin] ', {\n options,\n translator\n })\n // Extract language\n const language = options?.lng || translator?.language;\n\n // Set current language code for live editor\n if (language) {\n setCurrentLanguageCode(language);\n }\n\n // Extract user variables from options\n const variables = extractUserVariables(options);\n\n // Try to get the template (non-interpolated value) from the translator\n // This allows us to track the template with {{placeholders}} instead of resolved values\n let template = value;\n try {\n if (translator?.resourceStore) {\n const ns = namespace || options?.ns || translator.options?.defaultNS || 'translation';\n const lng = language || translator.language;\n\n // Try to get the raw translation template from the resource store\n const rawTranslation = translator.resourceStore.getResource(lng, ns, translationKey);\n if (rawTranslation && typeof rawTranslation === 'string') {\n template = rawTranslation;\n }\n }\n } catch (e) {\n // If we can't get the template, fall back to using the resolved value\n if (this.options.debug) {\n console.warn('[Contentstorage plugin] Could not retrieve template for:', translationKey, e);\n }\n }\n\n // Track the translation with the template\n trackTranslation(\n template,\n translationKey,\n namespace,\n language,\n this.options.debug,\n variables\n );\n\n return value;\n }\n}\n\n/**\n * Create a new instance of the Contentstorage Live Editor post-processor\n */\nexport function createContentstorageLiveEditorPostProcessor(\n options?: ContentstoragePluginOptions\n): ContentstorageLiveEditorPostProcessor {\n return new ContentstorageLiveEditorPostProcessor(options);\n}\n","import type {\n BackendModule,\n ReadCallback,\n Services,\n InitOptions,\n} from 'i18next';\nimport type {\n ContentstoragePluginOptions,\n TranslationData,\n} from './types';\nimport {\n detectLiveEditorMode,\n initializeMemoryMap,\n trackTranslation,\n cleanupMemoryMap,\n flattenTranslations,\n isBrowser,\n loadLiveEditorScript,\n} from './utils';\nimport { ContentstorageLiveEditorPostProcessor } from './post-processor';\n\n/**\n * Contentstorage i18next Backend Plugin\n *\n * This plugin enables translation tracking for the Contentstorage live editor\n * by maintaining a memory map of translations and their keys.\n *\n * Features:\n * - Automatic live editor mode detection\n * - Translation tracking with memory map\n * - Support for nested translations\n * - Memory management with size limits\n * - Custom CDN or load path support\n *\n * @example\n * ```typescript\n * import i18next from 'i18next';\n * import ContentstorageBackend from '@contentstorage/i18next-plugin';\n *\n * i18next\n * .use(ContentstorageBackend)\n * .init({\n * backend: {\n * contentKey: 'your-content-key',\n * debug: true\n * }\n * });\n * ```\n */\nexport class ContentstorageBackend implements BackendModule<ContentstoragePluginOptions> {\n static type: 'backend' = 'backend';\n type: 'backend' = 'backend';\n\n private options: ContentstoragePluginOptions;\n private isLiveMode: boolean = false;\n private postProcessor?: ContentstorageLiveEditorPostProcessor;\n\n constructor(_services?: Services, options?: ContentstoragePluginOptions, _i18nextOptions?: InitOptions) {\n this.options = options || {};\n\n // Initialize if services and i18nextOptions are provided\n // This allows i18next to initialize the plugin automatically\n if (_services && _i18nextOptions) {\n this.init(_services, options, _i18nextOptions);\n }\n }\n\n /**\n * Initialize the plugin\n * Called by i18next during initialization\n */\n init(\n services: Services,\n backendOptions: ContentstoragePluginOptions = {},\n i18nextOptions: InitOptions = {}\n ): void {\n\n this.options = {\n debug: false,\n maxMemoryMapSize: 10000,\n liveEditorParam: 'contentstorage_live_editor',\n forceLiveMode: false,\n ...backendOptions,\n };\n\n // Detect live editor mode\n this.isLiveMode = detectLiveEditorMode(\n this.options.liveEditorParam,\n this.options.forceLiveMode\n );\n\n if (this.isLiveMode) {\n // Initialize memory map\n initializeMemoryMap();\n\n // Load the live editor script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl).then((loaded) => {\n if (loaded) {\n if (this.options.debug) {\n console.log('[ContentStorage] Live editor ready');\n }\n } else {\n console.warn('[ContentStorage] Failed to load live editor script');\n }\n });\n\n // Auto-register the post-processor for live editor tracking\n this.registerPostProcessor(services, i18nextOptions);\n\n if (this.options.debug) {\n console.log('[ContentStorage] Live editor mode enabled');\n console.log('[ContentStorage] Post-processor auto-registered');\n console.log('[ContentStorage] Plugin initialized with options:', this.options);\n }\n } else if (this.options.debug) {\n console.log('[ContentStorage] Running in normal mode (not live editor)');\n }\n }\n\n /**\n * Auto-register the live editor post-processor\n * This allows dynamic translation tracking without requiring explicit postProcess config\n */\n private registerPostProcessor(services: Services, i18nextOptions: InitOptions): void {\n // Create post-processor instance\n this.postProcessor = new ContentstorageLiveEditorPostProcessor(this.options);\n\n // Register with i18next\n services.languageUtils?.addPostProcessor(this.postProcessor);\n\n // Add to postProcess array if it exists, otherwise create it\n const initOptions = i18nextOptions as any;\n if (!initOptions.postProcess) {\n initOptions.postProcess = [];\n }\n\n // Ensure postProcess is an array\n if (!Array.isArray(initOptions.postProcess)) {\n initOptions.postProcess = [initOptions.postProcess];\n }\n\n // Add our post-processor if not already present\n if (!initOptions.postProcess.includes('contentstorage')) {\n initOptions.postProcess.push('contentstorage');\n }\n }\n\n /**\n * Read translations for a given language and namespace\n * This is the main method called by i18next to load translations\n */\n read(\n language: string,\n namespace: string,\n callback: ReadCallback\n ): void {\n if (this.options.debug) {\n console.log(`[ContentStorage] Loading translations: ${language}/${namespace}`);\n }\n\n this.loadTranslations(language, namespace)\n .then((translations) => {\n // Track translations if in live mode\n if (this.isLiveMode && this.shouldTrackNamespace(namespace)) {\n this.trackTranslations(translations, namespace, language);\n\n // Cleanup if needed\n if (this.options.maxMemoryMapSize) {\n cleanupMemoryMap(this.options.maxMemoryMapSize);\n }\n }\n\n callback(null, translations);\n })\n .catch((error) => {\n if (this.options.debug) {\n console.error('[ContentStorage] Failed to load translations:', error);\n }\n callback(error, false);\n });\n }\n\n /**\n * Load translations from CDN or custom source\n */\n private async loadTranslations(\n language: string,\n namespace: string\n ): Promise<TranslationData> {\n const url = this.getLoadPath(language, namespace);\n\n if (this.options.debug) {\n console.log(`[ContentStorage] Fetching from: ${url}`);\n }\n\n try {\n const fetchFn = this.options.request || this.defaultFetch.bind(this);\n return await fetchFn(url, {\n method: 'GET',\n headers: {\n 'Accept': 'application/json',\n },\n });\n } catch (error) {\n if (this.options.debug) {\n console.error('[ContentStorage] Fetch error:', error);\n }\n throw error;\n }\n }\n\n /**\n * Default fetch implementation\n */\n private async defaultFetch(url: string, options: RequestInit): Promise<any> {\n const response = await fetch(url, options);\n\n if (!response.ok) {\n throw new Error(\n `Failed to load translations: ${response.status} ${response.statusText}`\n );\n }\n\n return response.json();\n }\n\n /**\n * Get the URL to load translations from\n */\n private getLoadPath(language: string, namespace: string): string {\n const { loadPath, contentKey } = this.options;\n\n // Custom load path function\n if (typeof loadPath === 'function') {\n return loadPath(language, namespace);\n }\n\n // Custom load path string with interpolation\n if (typeof loadPath === 'string') {\n return loadPath\n .replace('{{lng}}', language)\n .replace('{{ns}}', namespace);\n }\n\n // Default CDN path\n if (!contentKey) {\n throw new Error(\n '[ContentStorage] contentKey is required when using default CDN path'\n );\n }\n\n // Default: Always use uppercase language code\n const lng = language.toUpperCase();\n\n // Default: https://cdn.contentstorage.app/{contentKey}/content/{LNG}.json\n return `https://cdn.contentstorage.app/${contentKey}/content/${lng}.json`;\n }\n\n /**\n * Check if a namespace should be tracked\n */\n private shouldTrackNamespace(namespace: string): boolean {\n const { trackNamespaces } = this.options;\n\n // If no filter specified, track all namespaces\n if (!trackNamespaces || trackNamespaces.length === 0) {\n return true;\n }\n\n return trackNamespaces.includes(namespace);\n }\n\n /**\n * Track all translations in the loaded data\n */\n private trackTranslations(\n translations: TranslationData,\n namespace: string,\n language: string\n ): void {\n if (!isBrowser()) return;\n\n const flatTranslations = flattenTranslations(translations);\n\n for (const [key, value] of flatTranslations) {\n // Skip empty values\n if (!value) continue;\n\n // Don't pass namespace - let keys be tracked without prefix by default\n // Only keys with explicit colon notation (e.g., \"common:welcome\") will have namespace\n trackTranslation(\n value,\n key,\n undefined, // namespace not passed by default\n language,\n this.options.debug\n );\n }\n\n if (this.options.debug) {\n console.log(\n `[ContentStorage] Tracked ${flatTranslations.length} translations for ${namespace}`\n );\n }\n }\n}\n\n/**\n * Create a new instance of the Contentstorage backend\n */\nexport function createContentstorageBackend(\n options?: ContentstoragePluginOptions\n): ContentstorageBackend {\n return new ContentstorageBackend(undefined, options);\n}\n\n// Default export\nexport default ContentstorageBackend;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/utils.ts","../src/post-processor.ts","../src/plugin.ts"],"sourcesContent":["import type { ContentstorageWindow, MemoryMap, MemoryMapEntry } from './types';\n\n/**\n * Checks if the code is running in a browser environment\n */\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\n/**\n * Gets the Contentstorage window object with type safety\n */\nexport function getContentstorageWindow(): ContentstorageWindow | null {\n if (!isBrowser()) return null;\n return window as ContentstorageWindow;\n}\n\n/**\n * Detects if the application is running in ContentStorage live editor mode\n *\n * @param liveEditorParam - Query parameter name to check\n * @param forceLiveMode - Force live mode regardless of environment\n * @returns true if in live editor mode\n */\nexport function detectLiveEditorMode(\n liveEditorParam: string = 'contentstorage_live_editor',\n forceLiveMode: boolean = false\n): boolean {\n if (forceLiveMode) return true;\n if (!isBrowser()) return false;\n\n try {\n const win = getContentstorageWindow();\n if (!win) return false;\n\n // Check 1: Running in an iframe\n const inIframe = win.self !== win.top;\n\n // Check 2: URL has the live editor marker\n const urlParams = new URLSearchParams(win.location.search);\n const hasMarker = urlParams.has(liveEditorParam);\n\n return !!(inIframe && hasMarker);\n } catch (e) {\n // Cross-origin restrictions might block window.top access\n // This is expected when not in live editor mode\n return false;\n }\n}\n\n/**\n * Initializes the global memory map if it doesn't exist\n */\nexport function initializeMemoryMap(): MemoryMap | null {\n const win = getContentstorageWindow();\n if (!win) return null;\n\n if (!win.memoryMap) {\n win.memoryMap = new Map<string, MemoryMapEntry>();\n }\n\n return win.memoryMap;\n}\n\n/**\n * Load the ContentStorage live editor script\n * This script enables the click-to-edit functionality in the live editor\n */\nlet liveEditorReadyPromise: Promise<boolean> | null = null;\n\nexport function loadLiveEditorScript(\n retries: number = 2,\n delay: number = 3000,\n debug: boolean = false,\n customScriptUrl?: string\n): Promise<boolean> {\n // Return existing promise if already loading\n if (liveEditorReadyPromise) {\n return liveEditorReadyPromise;\n }\n\n liveEditorReadyPromise = new Promise<boolean>((resolve) => {\n const win = getContentstorageWindow();\n if (!win) {\n resolve(false);\n return;\n }\n\n const cdnScriptUrl = customScriptUrl || 'https://cdn.contentstorage.app/live-editor.js?contentstorage-live-editor=true';\n\n const loadScript = (attempt: number = 1) => {\n if (debug) {\n console.log(`[ContentStorage] Attempting to load live editor script (attempt ${attempt}/${retries})`);\n }\n\n const scriptElement = win.document.createElement('script');\n scriptElement.type = 'text/javascript';\n scriptElement.src = cdnScriptUrl;\n\n scriptElement.onload = () => {\n if (debug) {\n console.log(`[ContentStorage] Live editor script loaded successfully`);\n }\n resolve(true);\n };\n\n scriptElement.onerror = (error) => {\n // Clean up the failed script element\n scriptElement.remove();\n\n if (debug) {\n console.error(`[ContentStorage] Failed to load live editor script (attempt ${attempt}/${retries})`, error);\n }\n\n if (attempt < retries) {\n setTimeout(() => loadScript(attempt + 1), delay);\n } else {\n console.error(`[ContentStorage] All ${retries} attempts to load live editor script failed`);\n resolve(false);\n }\n };\n\n win.document.head.appendChild(scriptElement);\n };\n\n loadScript();\n });\n\n return liveEditorReadyPromise;\n}\n\n/**\n * Gets the global memory map\n */\nexport function getMemoryMap(): MemoryMap | null {\n const win = getContentstorageWindow();\n return win?.memoryMap || null;\n}\n\n/**\n * Sets the current language code on the window object\n * This is used by the live editor to know which language is currently active\n *\n * @param languageCode - The language code to set (e.g., 'en', 'es', 'fr')\n */\nexport function setCurrentLanguageCode(languageCode: string): void {\n const win = getContentstorageWindow();\n if (win) {\n win.currentLanguageCode = languageCode;\n }\n}\n\n/**\n * Gets the current language code from the window object\n *\n * @returns The current language code, or null if not set\n */\nexport function getCurrentLanguageCode(): string | null {\n const win = getContentstorageWindow();\n return win?.currentLanguageCode || null;\n}\n\n/**\n * Normalizes i18next key format to consistent dot notation\n * Converts namespace:key format to namespace.key\n * Only adds namespace prefix if explicitly present in the key (colon notation)\n *\n * @param key - The translation key\n * @param namespace - Optional namespace (only used if not already in key)\n * @returns Normalized key in dot notation\n */\nexport function normalizeKey(key: string, namespace?: string): string {\n // namespace parameter kept for backward compatibility but not used\n void namespace;\n\n let normalizedKey = key;\n\n // Convert colon notation to dot notation (e.g., \"common:welcome\" -> \"common.welcome\")\n if (normalizedKey.includes(':')) {\n normalizedKey = normalizedKey.replace(':', '.');\n }\n\n // Don't automatically prepend namespace - only if key already had it via colon notation\n // This ensures keys match ContentStorage content IDs by default\n\n return normalizedKey;\n}\n\n/**\n * Extracts the base translation key without interpolation context\n * Handles plural forms, contexts, and other i18next features\n *\n * Examples:\n * - 'welcome' -> 'welcome'\n * - 'items_plural' -> 'items'\n * - 'friend_male' -> 'friend'\n *\n * @param key - The translation key\n * @returns Base key without suffixes\n */\nexport function extractBaseKey(key: string): string {\n // Remove plural suffixes (_zero, _one, _two, _few, _many, _other, _plural)\n let baseKey = key.replace(/_(zero|one|two|few|many|other|plural)$/, '');\n\n // Remove context suffixes (anything after last underscore that's not a nested key)\n // Be careful not to remove underscores that are part of the actual key\n // This is a heuristic - contexts usually come at the end\n const lastUnderscore = baseKey.lastIndexOf('_');\n if (lastUnderscore > 0) {\n // Only remove if it looks like a context (short suffix, typically lowercase)\n const suffix = baseKey.substring(lastUnderscore + 1);\n if (suffix.length < 10 && suffix.toLowerCase() === suffix) {\n // This might be a context, but we'll keep it for now to avoid false positives\n // Real context handling should be done at a higher level\n }\n }\n\n return baseKey;\n}\n\n/**\n * Removes interpolation variables from a translated string\n *\n * Examples:\n * - 'Hello {{name}}!' -> 'Hello !'\n * - 'You have {{count}} items' -> 'You have items'\n *\n * @param value - The translated string\n * @returns String with interpolations removed\n */\nexport function removeInterpolation(value: string): string {\n // Remove i18next interpolation syntax: {{variable}}\n return value.replace(/\\{\\{[^}]+\\}\\}/g, '').trim();\n}\n\n/**\n * i18next internal option keys that should not be treated as user variables\n * Note: 'count' and 'context' are included as they are often used in interpolation\n */\nconst I18NEXT_INTERNAL_KEYS = new Set([\n 'defaultValue',\n 'replace',\n 'lng',\n 'lngs',\n 'fallbackLng',\n 'ns',\n 'keySeparator',\n 'nsSeparator',\n 'returnObjects',\n 'returnDetails',\n 'returnedObjectHandler',\n 'joinArrays',\n 'postProcess',\n 'interpolation',\n 'skipInterpolation',\n 'appendNamespaceToMissingKey',\n 'missingKeyHandler',\n 'parseMissingKeyHandler',\n 'overloadTranslationOptionHandler',\n 'saveMissing',\n 'saveMissingTo',\n 'missingKeyNoValueFallbackToKey',\n 'missingInterpolationHandler',\n 'formatSeparator',\n 'ignoreJSONStructure',\n]);\n\n/**\n * Extracts user-provided variables from i18next options\n * Filters out i18next internal options to return only interpolation variables\n *\n * @param options - i18next options object\n * @returns Object containing only user variables, or undefined if none\n */\nexport function extractUserVariables(options?: any): Record<string, any> | undefined {\n if (!options || typeof options !== 'object') {\n return undefined;\n }\n\n const variables: Record<string, any> = {};\n let hasVariables = false;\n\n for (const key in options) {\n if (!Object.prototype.hasOwnProperty.call(options, key)) continue;\n\n // Skip i18next internal keys\n if (I18NEXT_INTERNAL_KEYS.has(key)) continue;\n\n // Skip keys starting with underscore (private i18next properties)\n if (key.startsWith('_')) continue;\n\n // Skip undefined values\n if (options[key] === undefined) continue;\n\n // This is a user variable\n variables[key] = options[key];\n hasVariables = true;\n }\n\n return hasVariables ? variables : undefined;\n}\n\n// Schedule clear for next frame (memory map cleanup)\nlet clearScheduled = false;\n\n/**\n * Tracks a translation in the memory map\n *\n * @param translationValue - The actual translated text\n * @param translationKey - The content ID (i18next key)\n * @param namespace - Optional namespace\n * @param language - Optional language code\n * @param debug - Enable debug logging\n * @param variables - Optional interpolation variables used in the translation\n */\nexport function trackTranslation(\n translationValue: string,\n translationKey: string,\n namespace?: string,\n language?: string,\n debug: boolean = false,\n variables?: Record<string, any>\n): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap) return;\n\n // Schedule clear for next frame (only once per frame)\n // This ensures only currently rendered translations remain in the map\n if (!clearScheduled && isBrowser()) {\n clearScheduled = true;\n requestAnimationFrame(() => {\n memoryMap.clear();\n clearScheduled = false;\n\n if (debug) {\n console.log('[ContentStorage] Memory map cleared for new frame');\n }\n });\n }\n\n // Normalize the key\n const normalizedKey = normalizeKey(translationKey, namespace);\n\n // Get or create entry\n const existingEntry = memoryMap.get(translationValue);\n const idSet = existingEntry ? existingEntry.ids : new Set<string>();\n idSet.add(normalizedKey);\n\n // Merge variables: prefer new variables if provided, otherwise keep existing\n // This ensures variables are preserved when backend tracks without them\n const mergedVariables = variables && Object.keys(variables).length > 0\n ? variables\n : existingEntry?.variables;\n\n const entry: MemoryMapEntry = {\n ids: idSet,\n type: 'text',\n ...(mergedVariables && Object.keys(mergedVariables).length > 0 && { variables: mergedVariables }),\n metadata: {\n namespace,\n language,\n trackedAt: Date.now(),\n },\n };\n\n memoryMap.set(translationValue, entry);\n\n if (debug) {\n console.log('[ContentStorage] Tracked translation:', {\n value: translationValue,\n key: normalizedKey,\n namespace,\n language,\n variables,\n });\n }\n}\n\n/**\n * Cleans up old entries from memory map when size exceeds limit\n * Removes oldest entries first (based on trackedAt timestamp)\n *\n * @param maxSize - Maximum number of entries to keep\n */\nexport function cleanupMemoryMap(maxSize: number): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap || memoryMap.size <= maxSize) return;\n\n // Convert to array with timestamps\n const entries = Array.from(memoryMap.entries()).map(([key, value]) => ({\n key,\n value,\n timestamp: value.metadata?.trackedAt || 0,\n }));\n\n // Sort by timestamp (oldest first)\n entries.sort((a, b) => a.timestamp - b.timestamp);\n\n // Calculate how many to remove\n const toRemove = memoryMap.size - maxSize;\n\n // Remove oldest entries\n for (let i = 0; i < toRemove; i++) {\n memoryMap.delete(entries[i].key);\n }\n}\n\n/**\n * Deeply traverses a translation object and extracts all string values with their keys\n *\n * @param obj - Translation object to traverse\n * @param prefix - Current key prefix (for nested objects)\n * @returns Array of [key, value] pairs\n */\nexport function flattenTranslations(\n obj: any,\n prefix: string = ''\n): Array<[string, string]> {\n const results: Array<[string, string]> = [];\n\n for (const key in obj) {\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n\n const value = obj[key];\n const fullKey = prefix ? `${prefix}.${key}` : key;\n\n if (typeof value === 'string') {\n results.push([fullKey, value]);\n } else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n // Recurse into nested objects\n results.push(...flattenTranslations(value, fullKey));\n }\n }\n\n return results;\n}\n\n/**\n * Debug helper to log memory map contents\n */\nexport function debugMemoryMap(): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap) {\n console.log('[ContentStorage] Memory map not initialized');\n return;\n }\n\n console.log('[ContentStorage] Memory map contents:');\n console.log(`Total entries: ${memoryMap.size}`);\n\n const entries = Array.from(memoryMap.entries()).slice(0, 10);\n console.table(\n entries.map(([value, entry]) => ({\n value: value.substring(0, 50),\n keys: Array.from(entry.ids).join(', '),\n namespace: entry.metadata?.namespace || 'N/A',\n }))\n );\n\n if (memoryMap.size > 10) {\n console.log(`... and ${memoryMap.size - 10} more entries`);\n }\n}\n","import type { PostProcessorModule } from 'i18next';\nimport type { ContentstoragePluginOptions } from './types';\nimport { trackTranslation, detectLiveEditorMode, initializeMemoryMap, loadLiveEditorScript, extractUserVariables, setCurrentLanguageCode } from './utils';\n\n/**\n * Contentstorage Live Editor Post-Processor\n *\n * This post-processor enables live editor functionality by tracking translations\n * at the point of resolution, capturing the actual values returned by i18next\n * including interpolations and plural forms.\n *\n * Use this to enable click-to-edit functionality in the Contentstorage live editor.\n * It works in addition to or instead of the backend plugin for more comprehensive\n * tracking, especially for dynamic translations.\n *\n * @example\n * ```typescript\n * import i18next from 'i18next';\n * import { ContentstorageLiveEditorPostProcessor } from '@contentstorage/i18next-plugin';\n *\n * i18next\n * .use(new ContentstorageLiveEditorPostProcessor({ debug: true }))\n * .init({\n * postProcess: ['contentstorage']\n * });\n * ```\n */\nexport class ContentstorageLiveEditorPostProcessor implements PostProcessorModule {\n static type: 'postProcessor' = 'postProcessor';\n type: 'postProcessor' = 'postProcessor';\n name: string = 'contentstorage';\n\n private options: ContentstoragePluginOptions;\n private isLiveMode: boolean = false;\n\n constructor(options: ContentstoragePluginOptions = {}) {\n this.options = {\n debug: false,\n liveEditorParam: 'contentstorage_live_editor',\n forceLiveMode: false,\n ...options,\n };\n\n // Detect live editor mode\n this.isLiveMode = detectLiveEditorMode(\n this.options.liveEditorParam,\n this.options.forceLiveMode\n );\n\n if (this.isLiveMode) {\n initializeMemoryMap();\n\n // Initialize current language code with browser language or fallback\n // This ensures window.currentLanguageCode is never undefined\n const browserLanguage = typeof navigator !== 'undefined' && navigator.language\n ? navigator.language.split('-')[0]\n : 'en';\n setCurrentLanguageCode(browserLanguage);\n\n // Load the live editor script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);\n\n if (this.options.debug) {\n console.log('[ContentStorage] Post-processor initialized in live mode');\n console.log(`[ContentStorage] Initial language code set to: ${browserLanguage}`);\n }\n }\n }\n\n /**\n * Process the translated value\n * Called by i18next after translation resolution\n */\n process(\n value: string,\n key: string | string[],\n options: any,\n translator: any\n ): string {\n // Only track in live mode\n if (!this.isLiveMode) {\n return value;\n }\n\n // Handle array of keys (fallback keys)\n const translationKey = Array.isArray(key) ? key[0] : key;\n\n // Only extract namespace if key explicitly uses colon notation\n // Don't pass namespace from options - let keys be clean by default\n let namespace: string | undefined;\n if (translationKey.includes(':')) {\n [namespace] = translationKey.split(':');\n }\n console.log('[Contentstorage plugin] ', {\n options,\n translator\n })\n // Extract language\n const language = options?.lng || translator?.language;\n\n // Set current language code for live editor\n if (language) {\n setCurrentLanguageCode(language);\n }\n\n // Extract user variables from options\n const variables = extractUserVariables(options);\n\n // Try to get the template (non-interpolated value) from the translator\n // This allows us to track the template with {{placeholders}} instead of resolved values\n let template = value;\n try {\n if (translator?.resourceStore) {\n const ns = namespace || options?.ns || translator.options?.defaultNS || 'translation';\n const lng = language || translator.language;\n\n // Try to get the raw translation template from the resource store\n const rawTranslation = translator.resourceStore.getResource(lng, ns, translationKey);\n if (rawTranslation && typeof rawTranslation === 'string') {\n template = rawTranslation;\n }\n }\n } catch (e) {\n // If we can't get the template, fall back to using the resolved value\n if (this.options.debug) {\n console.warn('[Contentstorage plugin] Could not retrieve template for:', translationKey, e);\n }\n }\n\n // Track the translation with the template\n trackTranslation(\n template,\n translationKey,\n namespace,\n language,\n this.options.debug,\n variables\n );\n\n return value;\n }\n}\n\n/**\n * Create a new instance of the Contentstorage Live Editor post-processor\n */\nexport function createContentstorageLiveEditorPostProcessor(\n options?: ContentstoragePluginOptions\n): ContentstorageLiveEditorPostProcessor {\n return new ContentstorageLiveEditorPostProcessor(options);\n}\n","import type {\n BackendModule,\n ReadCallback,\n Services,\n InitOptions,\n} from 'i18next';\nimport type {\n ContentstoragePluginOptions,\n TranslationData,\n} from './types';\nimport {\n detectLiveEditorMode,\n initializeMemoryMap,\n trackTranslation,\n cleanupMemoryMap,\n flattenTranslations,\n isBrowser,\n loadLiveEditorScript,\n} from './utils';\nimport { ContentstorageLiveEditorPostProcessor } from './post-processor';\n\n/**\n * Contentstorage i18next Backend Plugin\n *\n * This plugin enables translation tracking for the Contentstorage live editor\n * by maintaining a memory map of translations and their keys.\n *\n * Features:\n * - Automatic live editor mode detection\n * - Translation tracking with memory map\n * - Support for nested translations\n * - Memory management with size limits\n * - Custom CDN or load path support\n *\n * @example\n * ```typescript\n * import i18next from 'i18next';\n * import ContentstorageBackend from '@contentstorage/i18next-plugin';\n *\n * i18next\n * .use(ContentstorageBackend)\n * .init({\n * backend: {\n * contentKey: 'your-content-key',\n * debug: true\n * }\n * });\n * ```\n */\nexport class ContentstorageBackend implements BackendModule<ContentstoragePluginOptions> {\n static type: 'backend' = 'backend';\n type: 'backend' = 'backend';\n\n private options: ContentstoragePluginOptions;\n private isLiveMode: boolean = false;\n private postProcessor?: ContentstorageLiveEditorPostProcessor;\n\n constructor(_services?: Services, options?: ContentstoragePluginOptions, _i18nextOptions?: InitOptions) {\n this.options = options || {};\n\n // Initialize if services and i18nextOptions are provided\n // This allows i18next to initialize the plugin automatically\n if (_services && _i18nextOptions) {\n this.init(_services, options, _i18nextOptions);\n }\n }\n\n /**\n * Initialize the plugin\n * Called by i18next during initialization\n */\n init(\n services: Services,\n backendOptions: ContentstoragePluginOptions = {},\n i18nextOptions: InitOptions = {}\n ): void {\n\n this.options = {\n debug: false,\n maxMemoryMapSize: 10000,\n liveEditorParam: 'contentstorage_live_editor',\n forceLiveMode: false,\n ...backendOptions,\n };\n\n // Detect live editor mode\n this.isLiveMode = detectLiveEditorMode(\n this.options.liveEditorParam,\n this.options.forceLiveMode\n );\n\n if (this.isLiveMode) {\n // Initialize memory map\n initializeMemoryMap();\n\n // Load the live editor script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl).then((loaded) => {\n if (loaded) {\n if (this.options.debug) {\n console.log('[ContentStorage] Live editor ready');\n }\n } else {\n console.warn('[ContentStorage] Failed to load live editor script');\n }\n });\n\n // Auto-register the post-processor for live editor tracking\n this.registerPostProcessor(services, i18nextOptions);\n\n if (this.options.debug) {\n console.log('[ContentStorage] Live editor mode enabled');\n console.log('[ContentStorage] Post-processor auto-registered');\n console.log('[ContentStorage] Plugin initialized with options:', this.options);\n }\n } else if (this.options.debug) {\n console.log('[ContentStorage] Running in normal mode (not live editor)');\n }\n }\n\n /**\n * Auto-register the live editor post-processor\n * This allows dynamic translation tracking without requiring explicit postProcess config\n */\n private registerPostProcessor(services: Services, i18nextOptions: InitOptions): void {\n // Create post-processor instance\n this.postProcessor = new ContentstorageLiveEditorPostProcessor(this.options);\n\n // Register with i18next\n services.languageUtils?.addPostProcessor(this.postProcessor);\n\n // Add to postProcess array if it exists, otherwise create it\n const initOptions = i18nextOptions as any;\n if (!initOptions.postProcess) {\n initOptions.postProcess = [];\n }\n\n // Ensure postProcess is an array\n if (!Array.isArray(initOptions.postProcess)) {\n initOptions.postProcess = [initOptions.postProcess];\n }\n\n // Add our post-processor if not already present\n if (!initOptions.postProcess.includes('contentstorage')) {\n initOptions.postProcess.push('contentstorage');\n }\n }\n\n /**\n * Read translations for a given language and namespace\n * This is the main method called by i18next to load translations\n */\n read(\n language: string,\n namespace: string,\n callback: ReadCallback\n ): void {\n if (this.options.debug) {\n console.log(`[ContentStorage] Loading translations: ${language}/${namespace}`);\n }\n\n this.loadTranslations(language, namespace)\n .then((translations) => {\n // Track translations if in live mode\n if (this.isLiveMode && this.shouldTrackNamespace(namespace)) {\n this.trackTranslations(translations, namespace, language);\n\n // Cleanup if needed\n if (this.options.maxMemoryMapSize) {\n cleanupMemoryMap(this.options.maxMemoryMapSize);\n }\n }\n\n callback(null, translations);\n })\n .catch((error) => {\n if (this.options.debug) {\n console.error('[ContentStorage] Failed to load translations:', error);\n }\n callback(error, false);\n });\n }\n\n /**\n * Load translations from CDN or custom source\n */\n private async loadTranslations(\n language: string,\n namespace: string\n ): Promise<TranslationData> {\n const url = this.getLoadPath(language, namespace);\n\n if (this.options.debug) {\n console.log(`[ContentStorage] Fetching from: ${url}`);\n }\n\n try {\n const fetchFn = this.options.request || this.defaultFetch.bind(this);\n return await fetchFn(url, {\n method: 'GET',\n headers: {\n 'Accept': 'application/json',\n },\n });\n } catch (error) {\n if (this.options.debug) {\n console.error('[ContentStorage] Fetch error:', error);\n }\n throw error;\n }\n }\n\n /**\n * Default fetch implementation\n */\n private async defaultFetch(url: string, options: RequestInit): Promise<any> {\n const response = await fetch(url, options);\n\n if (!response.ok) {\n throw new Error(\n `Failed to load translations: ${response.status} ${response.statusText}`\n );\n }\n\n return response.json();\n }\n\n /**\n * Get the URL to load translations from\n */\n private getLoadPath(language: string, namespace: string): string {\n const { loadPath, contentKey } = this.options;\n\n // Custom load path function\n if (typeof loadPath === 'function') {\n return loadPath(language, namespace);\n }\n\n // Custom load path string with interpolation\n if (typeof loadPath === 'string') {\n return loadPath\n .replace('{{lng}}', language)\n .replace('{{ns}}', namespace);\n }\n\n // Default CDN path\n if (!contentKey) {\n throw new Error(\n '[ContentStorage] contentKey is required when using default CDN path'\n );\n }\n\n // Default: Always use uppercase language code\n const lng = language.toUpperCase();\n\n // Default: https://cdn.contentstorage.app/{contentKey}/content/{LNG}.json\n return `https://cdn.contentstorage.app/${contentKey}/content/${lng}.json`;\n }\n\n /**\n * Check if a namespace should be tracked\n */\n private shouldTrackNamespace(namespace: string): boolean {\n const { trackNamespaces } = this.options;\n\n // If no filter specified, track all namespaces\n if (!trackNamespaces || trackNamespaces.length === 0) {\n return true;\n }\n\n return trackNamespaces.includes(namespace);\n }\n\n /**\n * Track all translations in the loaded data\n */\n private trackTranslations(\n translations: TranslationData,\n namespace: string,\n language: string\n ): void {\n if (!isBrowser()) return;\n\n const flatTranslations = flattenTranslations(translations);\n\n for (const [key, value] of flatTranslations) {\n // Skip empty values\n if (!value) continue;\n\n // Don't pass namespace - let keys be tracked without prefix by default\n // Only keys with explicit colon notation (e.g., \"common:welcome\") will have namespace\n trackTranslation(\n value,\n key,\n undefined, // namespace not passed by default\n language,\n this.options.debug\n );\n }\n\n if (this.options.debug) {\n console.log(\n `[ContentStorage] Tracked ${flatTranslations.length} translations for ${namespace}`\n );\n }\n }\n}\n\n/**\n * Create a new instance of the Contentstorage backend\n */\nexport function createContentstorageBackend(\n options?: ContentstoragePluginOptions\n): ContentstorageBackend {\n return new ContentstorageBackend(undefined, options);\n}\n\n// Default export\nexport default ContentstorageBackend;\n"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -216,6 +216,8 @@ function extractUserVariables(options) {
216
216
  }
217
217
  return hasVariables ? variables : undefined;
218
218
  }
219
+ // Schedule clear for next frame (memory map cleanup)
220
+ let clearScheduled = false;
219
221
  /**
220
222
  * Tracks a translation in the memory map
221
223
  *
@@ -230,6 +232,18 @@ function trackTranslation(translationValue, translationKey, namespace, language,
230
232
  const memoryMap = getMemoryMap();
231
233
  if (!memoryMap)
232
234
  return;
235
+ // Schedule clear for next frame (only once per frame)
236
+ // This ensures only currently rendered translations remain in the map
237
+ if (!clearScheduled && isBrowser()) {
238
+ clearScheduled = true;
239
+ requestAnimationFrame(() => {
240
+ memoryMap.clear();
241
+ clearScheduled = false;
242
+ if (debug) {
243
+ console.log('[ContentStorage] Memory map cleared for new frame');
244
+ }
245
+ });
246
+ }
233
247
  // Normalize the key
234
248
  const normalizedKey = normalizeKey(translationKey);
235
249
  // Get or create entry
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/utils.ts","../src/post-processor.ts","../src/plugin.ts"],"sourcesContent":["import type { ContentstorageWindow, MemoryMap, MemoryMapEntry } from './types';\n\n/**\n * Checks if the code is running in a browser environment\n */\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\n/**\n * Gets the Contentstorage window object with type safety\n */\nexport function getContentstorageWindow(): ContentstorageWindow | null {\n if (!isBrowser()) return null;\n return window as ContentstorageWindow;\n}\n\n/**\n * Detects if the application is running in ContentStorage live editor mode\n *\n * @param liveEditorParam - Query parameter name to check\n * @param forceLiveMode - Force live mode regardless of environment\n * @returns true if in live editor mode\n */\nexport function detectLiveEditorMode(\n liveEditorParam: string = 'contentstorage_live_editor',\n forceLiveMode: boolean = false\n): boolean {\n if (forceLiveMode) return true;\n if (!isBrowser()) return false;\n\n try {\n const win = getContentstorageWindow();\n if (!win) return false;\n\n // Check 1: Running in an iframe\n const inIframe = win.self !== win.top;\n\n // Check 2: URL has the live editor marker\n const urlParams = new URLSearchParams(win.location.search);\n const hasMarker = urlParams.has(liveEditorParam);\n\n return !!(inIframe && hasMarker);\n } catch (e) {\n // Cross-origin restrictions might block window.top access\n // This is expected when not in live editor mode\n return false;\n }\n}\n\n/**\n * Initializes the global memory map if it doesn't exist\n */\nexport function initializeMemoryMap(): MemoryMap | null {\n const win = getContentstorageWindow();\n if (!win) return null;\n\n if (!win.memoryMap) {\n win.memoryMap = new Map<string, MemoryMapEntry>();\n }\n\n return win.memoryMap;\n}\n\n/**\n * Load the ContentStorage live editor script\n * This script enables the click-to-edit functionality in the live editor\n */\nlet liveEditorReadyPromise: Promise<boolean> | null = null;\n\nexport function loadLiveEditorScript(\n retries: number = 2,\n delay: number = 3000,\n debug: boolean = false,\n customScriptUrl?: string\n): Promise<boolean> {\n // Return existing promise if already loading\n if (liveEditorReadyPromise) {\n return liveEditorReadyPromise;\n }\n\n liveEditorReadyPromise = new Promise<boolean>((resolve) => {\n const win = getContentstorageWindow();\n if (!win) {\n resolve(false);\n return;\n }\n\n const cdnScriptUrl = customScriptUrl || 'https://cdn.contentstorage.app/live-editor.js?contentstorage-live-editor=true';\n\n const loadScript = (attempt: number = 1) => {\n if (debug) {\n console.log(`[ContentStorage] Attempting to load live editor script (attempt ${attempt}/${retries})`);\n }\n\n const scriptElement = win.document.createElement('script');\n scriptElement.type = 'text/javascript';\n scriptElement.src = cdnScriptUrl;\n\n scriptElement.onload = () => {\n if (debug) {\n console.log(`[ContentStorage] Live editor script loaded successfully`);\n }\n resolve(true);\n };\n\n scriptElement.onerror = (error) => {\n // Clean up the failed script element\n scriptElement.remove();\n\n if (debug) {\n console.error(`[ContentStorage] Failed to load live editor script (attempt ${attempt}/${retries})`, error);\n }\n\n if (attempt < retries) {\n setTimeout(() => loadScript(attempt + 1), delay);\n } else {\n console.error(`[ContentStorage] All ${retries} attempts to load live editor script failed`);\n resolve(false);\n }\n };\n\n win.document.head.appendChild(scriptElement);\n };\n\n loadScript();\n });\n\n return liveEditorReadyPromise;\n}\n\n/**\n * Gets the global memory map\n */\nexport function getMemoryMap(): MemoryMap | null {\n const win = getContentstorageWindow();\n return win?.memoryMap || null;\n}\n\n/**\n * Sets the current language code on the window object\n * This is used by the live editor to know which language is currently active\n *\n * @param languageCode - The language code to set (e.g., 'en', 'es', 'fr')\n */\nexport function setCurrentLanguageCode(languageCode: string): void {\n const win = getContentstorageWindow();\n if (win) {\n win.currentLanguageCode = languageCode;\n }\n}\n\n/**\n * Gets the current language code from the window object\n *\n * @returns The current language code, or null if not set\n */\nexport function getCurrentLanguageCode(): string | null {\n const win = getContentstorageWindow();\n return win?.currentLanguageCode || null;\n}\n\n/**\n * Normalizes i18next key format to consistent dot notation\n * Converts namespace:key format to namespace.key\n * Only adds namespace prefix if explicitly present in the key (colon notation)\n *\n * @param key - The translation key\n * @param namespace - Optional namespace (only used if not already in key)\n * @returns Normalized key in dot notation\n */\nexport function normalizeKey(key: string, namespace?: string): string {\n // namespace parameter kept for backward compatibility but not used\n void namespace;\n\n let normalizedKey = key;\n\n // Convert colon notation to dot notation (e.g., \"common:welcome\" -> \"common.welcome\")\n if (normalizedKey.includes(':')) {\n normalizedKey = normalizedKey.replace(':', '.');\n }\n\n // Don't automatically prepend namespace - only if key already had it via colon notation\n // This ensures keys match ContentStorage content IDs by default\n\n return normalizedKey;\n}\n\n/**\n * Extracts the base translation key without interpolation context\n * Handles plural forms, contexts, and other i18next features\n *\n * Examples:\n * - 'welcome' -> 'welcome'\n * - 'items_plural' -> 'items'\n * - 'friend_male' -> 'friend'\n *\n * @param key - The translation key\n * @returns Base key without suffixes\n */\nexport function extractBaseKey(key: string): string {\n // Remove plural suffixes (_zero, _one, _two, _few, _many, _other, _plural)\n let baseKey = key.replace(/_(zero|one|two|few|many|other|plural)$/, '');\n\n // Remove context suffixes (anything after last underscore that's not a nested key)\n // Be careful not to remove underscores that are part of the actual key\n // This is a heuristic - contexts usually come at the end\n const lastUnderscore = baseKey.lastIndexOf('_');\n if (lastUnderscore > 0) {\n // Only remove if it looks like a context (short suffix, typically lowercase)\n const suffix = baseKey.substring(lastUnderscore + 1);\n if (suffix.length < 10 && suffix.toLowerCase() === suffix) {\n // This might be a context, but we'll keep it for now to avoid false positives\n // Real context handling should be done at a higher level\n }\n }\n\n return baseKey;\n}\n\n/**\n * Removes interpolation variables from a translated string\n *\n * Examples:\n * - 'Hello {{name}}!' -> 'Hello !'\n * - 'You have {{count}} items' -> 'You have items'\n *\n * @param value - The translated string\n * @returns String with interpolations removed\n */\nexport function removeInterpolation(value: string): string {\n // Remove i18next interpolation syntax: {{variable}}\n return value.replace(/\\{\\{[^}]+\\}\\}/g, '').trim();\n}\n\n/**\n * i18next internal option keys that should not be treated as user variables\n * Note: 'count' and 'context' are included as they are often used in interpolation\n */\nconst I18NEXT_INTERNAL_KEYS = new Set([\n 'defaultValue',\n 'replace',\n 'lng',\n 'lngs',\n 'fallbackLng',\n 'ns',\n 'keySeparator',\n 'nsSeparator',\n 'returnObjects',\n 'returnDetails',\n 'returnedObjectHandler',\n 'joinArrays',\n 'postProcess',\n 'interpolation',\n 'skipInterpolation',\n 'appendNamespaceToMissingKey',\n 'missingKeyHandler',\n 'parseMissingKeyHandler',\n 'overloadTranslationOptionHandler',\n 'saveMissing',\n 'saveMissingTo',\n 'missingKeyNoValueFallbackToKey',\n 'missingInterpolationHandler',\n 'formatSeparator',\n 'ignoreJSONStructure',\n]);\n\n/**\n * Extracts user-provided variables from i18next options\n * Filters out i18next internal options to return only interpolation variables\n *\n * @param options - i18next options object\n * @returns Object containing only user variables, or undefined if none\n */\nexport function extractUserVariables(options?: any): Record<string, any> | undefined {\n if (!options || typeof options !== 'object') {\n return undefined;\n }\n\n const variables: Record<string, any> = {};\n let hasVariables = false;\n\n for (const key in options) {\n if (!Object.prototype.hasOwnProperty.call(options, key)) continue;\n\n // Skip i18next internal keys\n if (I18NEXT_INTERNAL_KEYS.has(key)) continue;\n\n // Skip keys starting with underscore (private i18next properties)\n if (key.startsWith('_')) continue;\n\n // Skip undefined values\n if (options[key] === undefined) continue;\n\n // This is a user variable\n variables[key] = options[key];\n hasVariables = true;\n }\n\n return hasVariables ? variables : undefined;\n}\n\n/**\n * Tracks a translation in the memory map\n *\n * @param translationValue - The actual translated text\n * @param translationKey - The content ID (i18next key)\n * @param namespace - Optional namespace\n * @param language - Optional language code\n * @param debug - Enable debug logging\n * @param variables - Optional interpolation variables used in the translation\n */\nexport function trackTranslation(\n translationValue: string,\n translationKey: string,\n namespace?: string,\n language?: string,\n debug: boolean = false,\n variables?: Record<string, any>\n): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap) return;\n\n // Normalize the key\n const normalizedKey = normalizeKey(translationKey, namespace);\n\n // Get or create entry\n const existingEntry = memoryMap.get(translationValue);\n const idSet = existingEntry ? existingEntry.ids : new Set<string>();\n idSet.add(normalizedKey);\n\n // Merge variables: prefer new variables if provided, otherwise keep existing\n // This ensures variables are preserved when backend tracks without them\n const mergedVariables = variables && Object.keys(variables).length > 0\n ? variables\n : existingEntry?.variables;\n\n const entry: MemoryMapEntry = {\n ids: idSet,\n type: 'text',\n ...(mergedVariables && Object.keys(mergedVariables).length > 0 && { variables: mergedVariables }),\n metadata: {\n namespace,\n language,\n trackedAt: Date.now(),\n },\n };\n\n memoryMap.set(translationValue, entry);\n\n if (debug) {\n console.log('[ContentStorage] Tracked translation:', {\n value: translationValue,\n key: normalizedKey,\n namespace,\n language,\n variables,\n });\n }\n}\n\n/**\n * Cleans up old entries from memory map when size exceeds limit\n * Removes oldest entries first (based on trackedAt timestamp)\n *\n * @param maxSize - Maximum number of entries to keep\n */\nexport function cleanupMemoryMap(maxSize: number): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap || memoryMap.size <= maxSize) return;\n\n // Convert to array with timestamps\n const entries = Array.from(memoryMap.entries()).map(([key, value]) => ({\n key,\n value,\n timestamp: value.metadata?.trackedAt || 0,\n }));\n\n // Sort by timestamp (oldest first)\n entries.sort((a, b) => a.timestamp - b.timestamp);\n\n // Calculate how many to remove\n const toRemove = memoryMap.size - maxSize;\n\n // Remove oldest entries\n for (let i = 0; i < toRemove; i++) {\n memoryMap.delete(entries[i].key);\n }\n}\n\n/**\n * Deeply traverses a translation object and extracts all string values with their keys\n *\n * @param obj - Translation object to traverse\n * @param prefix - Current key prefix (for nested objects)\n * @returns Array of [key, value] pairs\n */\nexport function flattenTranslations(\n obj: any,\n prefix: string = ''\n): Array<[string, string]> {\n const results: Array<[string, string]> = [];\n\n for (const key in obj) {\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n\n const value = obj[key];\n const fullKey = prefix ? `${prefix}.${key}` : key;\n\n if (typeof value === 'string') {\n results.push([fullKey, value]);\n } else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n // Recurse into nested objects\n results.push(...flattenTranslations(value, fullKey));\n }\n }\n\n return results;\n}\n\n/**\n * Debug helper to log memory map contents\n */\nexport function debugMemoryMap(): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap) {\n console.log('[ContentStorage] Memory map not initialized');\n return;\n }\n\n console.log('[ContentStorage] Memory map contents:');\n console.log(`Total entries: ${memoryMap.size}`);\n\n const entries = Array.from(memoryMap.entries()).slice(0, 10);\n console.table(\n entries.map(([value, entry]) => ({\n value: value.substring(0, 50),\n keys: Array.from(entry.ids).join(', '),\n namespace: entry.metadata?.namespace || 'N/A',\n }))\n );\n\n if (memoryMap.size > 10) {\n console.log(`... and ${memoryMap.size - 10} more entries`);\n }\n}\n","import type { PostProcessorModule } from 'i18next';\nimport type { ContentstoragePluginOptions } from './types';\nimport { trackTranslation, detectLiveEditorMode, initializeMemoryMap, loadLiveEditorScript, extractUserVariables, setCurrentLanguageCode } from './utils';\n\n/**\n * Contentstorage Live Editor Post-Processor\n *\n * This post-processor enables live editor functionality by tracking translations\n * at the point of resolution, capturing the actual values returned by i18next\n * including interpolations and plural forms.\n *\n * Use this to enable click-to-edit functionality in the Contentstorage live editor.\n * It works in addition to or instead of the backend plugin for more comprehensive\n * tracking, especially for dynamic translations.\n *\n * @example\n * ```typescript\n * import i18next from 'i18next';\n * import { ContentstorageLiveEditorPostProcessor } from '@contentstorage/i18next-plugin';\n *\n * i18next\n * .use(new ContentstorageLiveEditorPostProcessor({ debug: true }))\n * .init({\n * postProcess: ['contentstorage']\n * });\n * ```\n */\nexport class ContentstorageLiveEditorPostProcessor implements PostProcessorModule {\n static type: 'postProcessor' = 'postProcessor';\n type: 'postProcessor' = 'postProcessor';\n name: string = 'contentstorage';\n\n private options: ContentstoragePluginOptions;\n private isLiveMode: boolean = false;\n\n constructor(options: ContentstoragePluginOptions = {}) {\n this.options = {\n debug: false,\n liveEditorParam: 'contentstorage_live_editor',\n forceLiveMode: false,\n ...options,\n };\n\n // Detect live editor mode\n this.isLiveMode = detectLiveEditorMode(\n this.options.liveEditorParam,\n this.options.forceLiveMode\n );\n\n if (this.isLiveMode) {\n initializeMemoryMap();\n\n // Initialize current language code with browser language or fallback\n // This ensures window.currentLanguageCode is never undefined\n const browserLanguage = typeof navigator !== 'undefined' && navigator.language\n ? navigator.language.split('-')[0]\n : 'en';\n setCurrentLanguageCode(browserLanguage);\n\n // Load the live editor script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);\n\n if (this.options.debug) {\n console.log('[ContentStorage] Post-processor initialized in live mode');\n console.log(`[ContentStorage] Initial language code set to: ${browserLanguage}`);\n }\n }\n }\n\n /**\n * Process the translated value\n * Called by i18next after translation resolution\n */\n process(\n value: string,\n key: string | string[],\n options: any,\n translator: any\n ): string {\n // Only track in live mode\n if (!this.isLiveMode) {\n return value;\n }\n\n // Handle array of keys (fallback keys)\n const translationKey = Array.isArray(key) ? key[0] : key;\n\n // Only extract namespace if key explicitly uses colon notation\n // Don't pass namespace from options - let keys be clean by default\n let namespace: string | undefined;\n if (translationKey.includes(':')) {\n [namespace] = translationKey.split(':');\n }\n console.log('[Contentstorage plugin] ', {\n options,\n translator\n })\n // Extract language\n const language = options?.lng || translator?.language;\n\n // Set current language code for live editor\n if (language) {\n setCurrentLanguageCode(language);\n }\n\n // Extract user variables from options\n const variables = extractUserVariables(options);\n\n // Try to get the template (non-interpolated value) from the translator\n // This allows us to track the template with {{placeholders}} instead of resolved values\n let template = value;\n try {\n if (translator?.resourceStore) {\n const ns = namespace || options?.ns || translator.options?.defaultNS || 'translation';\n const lng = language || translator.language;\n\n // Try to get the raw translation template from the resource store\n const rawTranslation = translator.resourceStore.getResource(lng, ns, translationKey);\n if (rawTranslation && typeof rawTranslation === 'string') {\n template = rawTranslation;\n }\n }\n } catch (e) {\n // If we can't get the template, fall back to using the resolved value\n if (this.options.debug) {\n console.warn('[Contentstorage plugin] Could not retrieve template for:', translationKey, e);\n }\n }\n\n // Track the translation with the template\n trackTranslation(\n template,\n translationKey,\n namespace,\n language,\n this.options.debug,\n variables\n );\n\n return value;\n }\n}\n\n/**\n * Create a new instance of the Contentstorage Live Editor post-processor\n */\nexport function createContentstorageLiveEditorPostProcessor(\n options?: ContentstoragePluginOptions\n): ContentstorageLiveEditorPostProcessor {\n return new ContentstorageLiveEditorPostProcessor(options);\n}\n","import type {\n BackendModule,\n ReadCallback,\n Services,\n InitOptions,\n} from 'i18next';\nimport type {\n ContentstoragePluginOptions,\n TranslationData,\n} from './types';\nimport {\n detectLiveEditorMode,\n initializeMemoryMap,\n trackTranslation,\n cleanupMemoryMap,\n flattenTranslations,\n isBrowser,\n loadLiveEditorScript,\n} from './utils';\nimport { ContentstorageLiveEditorPostProcessor } from './post-processor';\n\n/**\n * Contentstorage i18next Backend Plugin\n *\n * This plugin enables translation tracking for the Contentstorage live editor\n * by maintaining a memory map of translations and their keys.\n *\n * Features:\n * - Automatic live editor mode detection\n * - Translation tracking with memory map\n * - Support for nested translations\n * - Memory management with size limits\n * - Custom CDN or load path support\n *\n * @example\n * ```typescript\n * import i18next from 'i18next';\n * import ContentstorageBackend from '@contentstorage/i18next-plugin';\n *\n * i18next\n * .use(ContentstorageBackend)\n * .init({\n * backend: {\n * contentKey: 'your-content-key',\n * debug: true\n * }\n * });\n * ```\n */\nexport class ContentstorageBackend implements BackendModule<ContentstoragePluginOptions> {\n static type: 'backend' = 'backend';\n type: 'backend' = 'backend';\n\n private options: ContentstoragePluginOptions;\n private isLiveMode: boolean = false;\n private postProcessor?: ContentstorageLiveEditorPostProcessor;\n\n constructor(_services?: Services, options?: ContentstoragePluginOptions, _i18nextOptions?: InitOptions) {\n this.options = options || {};\n\n // Initialize if services and i18nextOptions are provided\n // This allows i18next to initialize the plugin automatically\n if (_services && _i18nextOptions) {\n this.init(_services, options, _i18nextOptions);\n }\n }\n\n /**\n * Initialize the plugin\n * Called by i18next during initialization\n */\n init(\n services: Services,\n backendOptions: ContentstoragePluginOptions = {},\n i18nextOptions: InitOptions = {}\n ): void {\n\n this.options = {\n debug: false,\n maxMemoryMapSize: 10000,\n liveEditorParam: 'contentstorage_live_editor',\n forceLiveMode: false,\n ...backendOptions,\n };\n\n // Detect live editor mode\n this.isLiveMode = detectLiveEditorMode(\n this.options.liveEditorParam,\n this.options.forceLiveMode\n );\n\n if (this.isLiveMode) {\n // Initialize memory map\n initializeMemoryMap();\n\n // Load the live editor script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl).then((loaded) => {\n if (loaded) {\n if (this.options.debug) {\n console.log('[ContentStorage] Live editor ready');\n }\n } else {\n console.warn('[ContentStorage] Failed to load live editor script');\n }\n });\n\n // Auto-register the post-processor for live editor tracking\n this.registerPostProcessor(services, i18nextOptions);\n\n if (this.options.debug) {\n console.log('[ContentStorage] Live editor mode enabled');\n console.log('[ContentStorage] Post-processor auto-registered');\n console.log('[ContentStorage] Plugin initialized with options:', this.options);\n }\n } else if (this.options.debug) {\n console.log('[ContentStorage] Running in normal mode (not live editor)');\n }\n }\n\n /**\n * Auto-register the live editor post-processor\n * This allows dynamic translation tracking without requiring explicit postProcess config\n */\n private registerPostProcessor(services: Services, i18nextOptions: InitOptions): void {\n // Create post-processor instance\n this.postProcessor = new ContentstorageLiveEditorPostProcessor(this.options);\n\n // Register with i18next\n services.languageUtils?.addPostProcessor(this.postProcessor);\n\n // Add to postProcess array if it exists, otherwise create it\n const initOptions = i18nextOptions as any;\n if (!initOptions.postProcess) {\n initOptions.postProcess = [];\n }\n\n // Ensure postProcess is an array\n if (!Array.isArray(initOptions.postProcess)) {\n initOptions.postProcess = [initOptions.postProcess];\n }\n\n // Add our post-processor if not already present\n if (!initOptions.postProcess.includes('contentstorage')) {\n initOptions.postProcess.push('contentstorage');\n }\n }\n\n /**\n * Read translations for a given language and namespace\n * This is the main method called by i18next to load translations\n */\n read(\n language: string,\n namespace: string,\n callback: ReadCallback\n ): void {\n if (this.options.debug) {\n console.log(`[ContentStorage] Loading translations: ${language}/${namespace}`);\n }\n\n this.loadTranslations(language, namespace)\n .then((translations) => {\n // Track translations if in live mode\n if (this.isLiveMode && this.shouldTrackNamespace(namespace)) {\n this.trackTranslations(translations, namespace, language);\n\n // Cleanup if needed\n if (this.options.maxMemoryMapSize) {\n cleanupMemoryMap(this.options.maxMemoryMapSize);\n }\n }\n\n callback(null, translations);\n })\n .catch((error) => {\n if (this.options.debug) {\n console.error('[ContentStorage] Failed to load translations:', error);\n }\n callback(error, false);\n });\n }\n\n /**\n * Load translations from CDN or custom source\n */\n private async loadTranslations(\n language: string,\n namespace: string\n ): Promise<TranslationData> {\n const url = this.getLoadPath(language, namespace);\n\n if (this.options.debug) {\n console.log(`[ContentStorage] Fetching from: ${url}`);\n }\n\n try {\n const fetchFn = this.options.request || this.defaultFetch.bind(this);\n return await fetchFn(url, {\n method: 'GET',\n headers: {\n 'Accept': 'application/json',\n },\n });\n } catch (error) {\n if (this.options.debug) {\n console.error('[ContentStorage] Fetch error:', error);\n }\n throw error;\n }\n }\n\n /**\n * Default fetch implementation\n */\n private async defaultFetch(url: string, options: RequestInit): Promise<any> {\n const response = await fetch(url, options);\n\n if (!response.ok) {\n throw new Error(\n `Failed to load translations: ${response.status} ${response.statusText}`\n );\n }\n\n return response.json();\n }\n\n /**\n * Get the URL to load translations from\n */\n private getLoadPath(language: string, namespace: string): string {\n const { loadPath, contentKey } = this.options;\n\n // Custom load path function\n if (typeof loadPath === 'function') {\n return loadPath(language, namespace);\n }\n\n // Custom load path string with interpolation\n if (typeof loadPath === 'string') {\n return loadPath\n .replace('{{lng}}', language)\n .replace('{{ns}}', namespace);\n }\n\n // Default CDN path\n if (!contentKey) {\n throw new Error(\n '[ContentStorage] contentKey is required when using default CDN path'\n );\n }\n\n // Default: Always use uppercase language code\n const lng = language.toUpperCase();\n\n // Default: https://cdn.contentstorage.app/{contentKey}/content/{LNG}.json\n return `https://cdn.contentstorage.app/${contentKey}/content/${lng}.json`;\n }\n\n /**\n * Check if a namespace should be tracked\n */\n private shouldTrackNamespace(namespace: string): boolean {\n const { trackNamespaces } = this.options;\n\n // If no filter specified, track all namespaces\n if (!trackNamespaces || trackNamespaces.length === 0) {\n return true;\n }\n\n return trackNamespaces.includes(namespace);\n }\n\n /**\n * Track all translations in the loaded data\n */\n private trackTranslations(\n translations: TranslationData,\n namespace: string,\n language: string\n ): void {\n if (!isBrowser()) return;\n\n const flatTranslations = flattenTranslations(translations);\n\n for (const [key, value] of flatTranslations) {\n // Skip empty values\n if (!value) continue;\n\n // Don't pass namespace - let keys be tracked without prefix by default\n // Only keys with explicit colon notation (e.g., \"common:welcome\") will have namespace\n trackTranslation(\n value,\n key,\n undefined, // namespace not passed by default\n language,\n this.options.debug\n );\n }\n\n if (this.options.debug) {\n console.log(\n `[ContentStorage] Tracked ${flatTranslations.length} translations for ${namespace}`\n );\n }\n }\n}\n\n/**\n * Create a new instance of the Contentstorage backend\n */\nexport function createContentstorageBackend(\n options?: ContentstoragePluginOptions\n): ContentstorageBackend {\n return new ContentstorageBackend(undefined, options);\n}\n\n// Default export\nexport default ContentstorageBackend;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/utils.ts","../src/post-processor.ts","../src/plugin.ts"],"sourcesContent":["import type { ContentstorageWindow, MemoryMap, MemoryMapEntry } from './types';\n\n/**\n * Checks if the code is running in a browser environment\n */\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\n/**\n * Gets the Contentstorage window object with type safety\n */\nexport function getContentstorageWindow(): ContentstorageWindow | null {\n if (!isBrowser()) return null;\n return window as ContentstorageWindow;\n}\n\n/**\n * Detects if the application is running in ContentStorage live editor mode\n *\n * @param liveEditorParam - Query parameter name to check\n * @param forceLiveMode - Force live mode regardless of environment\n * @returns true if in live editor mode\n */\nexport function detectLiveEditorMode(\n liveEditorParam: string = 'contentstorage_live_editor',\n forceLiveMode: boolean = false\n): boolean {\n if (forceLiveMode) return true;\n if (!isBrowser()) return false;\n\n try {\n const win = getContentstorageWindow();\n if (!win) return false;\n\n // Check 1: Running in an iframe\n const inIframe = win.self !== win.top;\n\n // Check 2: URL has the live editor marker\n const urlParams = new URLSearchParams(win.location.search);\n const hasMarker = urlParams.has(liveEditorParam);\n\n return !!(inIframe && hasMarker);\n } catch (e) {\n // Cross-origin restrictions might block window.top access\n // This is expected when not in live editor mode\n return false;\n }\n}\n\n/**\n * Initializes the global memory map if it doesn't exist\n */\nexport function initializeMemoryMap(): MemoryMap | null {\n const win = getContentstorageWindow();\n if (!win) return null;\n\n if (!win.memoryMap) {\n win.memoryMap = new Map<string, MemoryMapEntry>();\n }\n\n return win.memoryMap;\n}\n\n/**\n * Load the ContentStorage live editor script\n * This script enables the click-to-edit functionality in the live editor\n */\nlet liveEditorReadyPromise: Promise<boolean> | null = null;\n\nexport function loadLiveEditorScript(\n retries: number = 2,\n delay: number = 3000,\n debug: boolean = false,\n customScriptUrl?: string\n): Promise<boolean> {\n // Return existing promise if already loading\n if (liveEditorReadyPromise) {\n return liveEditorReadyPromise;\n }\n\n liveEditorReadyPromise = new Promise<boolean>((resolve) => {\n const win = getContentstorageWindow();\n if (!win) {\n resolve(false);\n return;\n }\n\n const cdnScriptUrl = customScriptUrl || 'https://cdn.contentstorage.app/live-editor.js?contentstorage-live-editor=true';\n\n const loadScript = (attempt: number = 1) => {\n if (debug) {\n console.log(`[ContentStorage] Attempting to load live editor script (attempt ${attempt}/${retries})`);\n }\n\n const scriptElement = win.document.createElement('script');\n scriptElement.type = 'text/javascript';\n scriptElement.src = cdnScriptUrl;\n\n scriptElement.onload = () => {\n if (debug) {\n console.log(`[ContentStorage] Live editor script loaded successfully`);\n }\n resolve(true);\n };\n\n scriptElement.onerror = (error) => {\n // Clean up the failed script element\n scriptElement.remove();\n\n if (debug) {\n console.error(`[ContentStorage] Failed to load live editor script (attempt ${attempt}/${retries})`, error);\n }\n\n if (attempt < retries) {\n setTimeout(() => loadScript(attempt + 1), delay);\n } else {\n console.error(`[ContentStorage] All ${retries} attempts to load live editor script failed`);\n resolve(false);\n }\n };\n\n win.document.head.appendChild(scriptElement);\n };\n\n loadScript();\n });\n\n return liveEditorReadyPromise;\n}\n\n/**\n * Gets the global memory map\n */\nexport function getMemoryMap(): MemoryMap | null {\n const win = getContentstorageWindow();\n return win?.memoryMap || null;\n}\n\n/**\n * Sets the current language code on the window object\n * This is used by the live editor to know which language is currently active\n *\n * @param languageCode - The language code to set (e.g., 'en', 'es', 'fr')\n */\nexport function setCurrentLanguageCode(languageCode: string): void {\n const win = getContentstorageWindow();\n if (win) {\n win.currentLanguageCode = languageCode;\n }\n}\n\n/**\n * Gets the current language code from the window object\n *\n * @returns The current language code, or null if not set\n */\nexport function getCurrentLanguageCode(): string | null {\n const win = getContentstorageWindow();\n return win?.currentLanguageCode || null;\n}\n\n/**\n * Normalizes i18next key format to consistent dot notation\n * Converts namespace:key format to namespace.key\n * Only adds namespace prefix if explicitly present in the key (colon notation)\n *\n * @param key - The translation key\n * @param namespace - Optional namespace (only used if not already in key)\n * @returns Normalized key in dot notation\n */\nexport function normalizeKey(key: string, namespace?: string): string {\n // namespace parameter kept for backward compatibility but not used\n void namespace;\n\n let normalizedKey = key;\n\n // Convert colon notation to dot notation (e.g., \"common:welcome\" -> \"common.welcome\")\n if (normalizedKey.includes(':')) {\n normalizedKey = normalizedKey.replace(':', '.');\n }\n\n // Don't automatically prepend namespace - only if key already had it via colon notation\n // This ensures keys match ContentStorage content IDs by default\n\n return normalizedKey;\n}\n\n/**\n * Extracts the base translation key without interpolation context\n * Handles plural forms, contexts, and other i18next features\n *\n * Examples:\n * - 'welcome' -> 'welcome'\n * - 'items_plural' -> 'items'\n * - 'friend_male' -> 'friend'\n *\n * @param key - The translation key\n * @returns Base key without suffixes\n */\nexport function extractBaseKey(key: string): string {\n // Remove plural suffixes (_zero, _one, _two, _few, _many, _other, _plural)\n let baseKey = key.replace(/_(zero|one|two|few|many|other|plural)$/, '');\n\n // Remove context suffixes (anything after last underscore that's not a nested key)\n // Be careful not to remove underscores that are part of the actual key\n // This is a heuristic - contexts usually come at the end\n const lastUnderscore = baseKey.lastIndexOf('_');\n if (lastUnderscore > 0) {\n // Only remove if it looks like a context (short suffix, typically lowercase)\n const suffix = baseKey.substring(lastUnderscore + 1);\n if (suffix.length < 10 && suffix.toLowerCase() === suffix) {\n // This might be a context, but we'll keep it for now to avoid false positives\n // Real context handling should be done at a higher level\n }\n }\n\n return baseKey;\n}\n\n/**\n * Removes interpolation variables from a translated string\n *\n * Examples:\n * - 'Hello {{name}}!' -> 'Hello !'\n * - 'You have {{count}} items' -> 'You have items'\n *\n * @param value - The translated string\n * @returns String with interpolations removed\n */\nexport function removeInterpolation(value: string): string {\n // Remove i18next interpolation syntax: {{variable}}\n return value.replace(/\\{\\{[^}]+\\}\\}/g, '').trim();\n}\n\n/**\n * i18next internal option keys that should not be treated as user variables\n * Note: 'count' and 'context' are included as they are often used in interpolation\n */\nconst I18NEXT_INTERNAL_KEYS = new Set([\n 'defaultValue',\n 'replace',\n 'lng',\n 'lngs',\n 'fallbackLng',\n 'ns',\n 'keySeparator',\n 'nsSeparator',\n 'returnObjects',\n 'returnDetails',\n 'returnedObjectHandler',\n 'joinArrays',\n 'postProcess',\n 'interpolation',\n 'skipInterpolation',\n 'appendNamespaceToMissingKey',\n 'missingKeyHandler',\n 'parseMissingKeyHandler',\n 'overloadTranslationOptionHandler',\n 'saveMissing',\n 'saveMissingTo',\n 'missingKeyNoValueFallbackToKey',\n 'missingInterpolationHandler',\n 'formatSeparator',\n 'ignoreJSONStructure',\n]);\n\n/**\n * Extracts user-provided variables from i18next options\n * Filters out i18next internal options to return only interpolation variables\n *\n * @param options - i18next options object\n * @returns Object containing only user variables, or undefined if none\n */\nexport function extractUserVariables(options?: any): Record<string, any> | undefined {\n if (!options || typeof options !== 'object') {\n return undefined;\n }\n\n const variables: Record<string, any> = {};\n let hasVariables = false;\n\n for (const key in options) {\n if (!Object.prototype.hasOwnProperty.call(options, key)) continue;\n\n // Skip i18next internal keys\n if (I18NEXT_INTERNAL_KEYS.has(key)) continue;\n\n // Skip keys starting with underscore (private i18next properties)\n if (key.startsWith('_')) continue;\n\n // Skip undefined values\n if (options[key] === undefined) continue;\n\n // This is a user variable\n variables[key] = options[key];\n hasVariables = true;\n }\n\n return hasVariables ? variables : undefined;\n}\n\n// Schedule clear for next frame (memory map cleanup)\nlet clearScheduled = false;\n\n/**\n * Tracks a translation in the memory map\n *\n * @param translationValue - The actual translated text\n * @param translationKey - The content ID (i18next key)\n * @param namespace - Optional namespace\n * @param language - Optional language code\n * @param debug - Enable debug logging\n * @param variables - Optional interpolation variables used in the translation\n */\nexport function trackTranslation(\n translationValue: string,\n translationKey: string,\n namespace?: string,\n language?: string,\n debug: boolean = false,\n variables?: Record<string, any>\n): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap) return;\n\n // Schedule clear for next frame (only once per frame)\n // This ensures only currently rendered translations remain in the map\n if (!clearScheduled && isBrowser()) {\n clearScheduled = true;\n requestAnimationFrame(() => {\n memoryMap.clear();\n clearScheduled = false;\n\n if (debug) {\n console.log('[ContentStorage] Memory map cleared for new frame');\n }\n });\n }\n\n // Normalize the key\n const normalizedKey = normalizeKey(translationKey, namespace);\n\n // Get or create entry\n const existingEntry = memoryMap.get(translationValue);\n const idSet = existingEntry ? existingEntry.ids : new Set<string>();\n idSet.add(normalizedKey);\n\n // Merge variables: prefer new variables if provided, otherwise keep existing\n // This ensures variables are preserved when backend tracks without them\n const mergedVariables = variables && Object.keys(variables).length > 0\n ? variables\n : existingEntry?.variables;\n\n const entry: MemoryMapEntry = {\n ids: idSet,\n type: 'text',\n ...(mergedVariables && Object.keys(mergedVariables).length > 0 && { variables: mergedVariables }),\n metadata: {\n namespace,\n language,\n trackedAt: Date.now(),\n },\n };\n\n memoryMap.set(translationValue, entry);\n\n if (debug) {\n console.log('[ContentStorage] Tracked translation:', {\n value: translationValue,\n key: normalizedKey,\n namespace,\n language,\n variables,\n });\n }\n}\n\n/**\n * Cleans up old entries from memory map when size exceeds limit\n * Removes oldest entries first (based on trackedAt timestamp)\n *\n * @param maxSize - Maximum number of entries to keep\n */\nexport function cleanupMemoryMap(maxSize: number): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap || memoryMap.size <= maxSize) return;\n\n // Convert to array with timestamps\n const entries = Array.from(memoryMap.entries()).map(([key, value]) => ({\n key,\n value,\n timestamp: value.metadata?.trackedAt || 0,\n }));\n\n // Sort by timestamp (oldest first)\n entries.sort((a, b) => a.timestamp - b.timestamp);\n\n // Calculate how many to remove\n const toRemove = memoryMap.size - maxSize;\n\n // Remove oldest entries\n for (let i = 0; i < toRemove; i++) {\n memoryMap.delete(entries[i].key);\n }\n}\n\n/**\n * Deeply traverses a translation object and extracts all string values with their keys\n *\n * @param obj - Translation object to traverse\n * @param prefix - Current key prefix (for nested objects)\n * @returns Array of [key, value] pairs\n */\nexport function flattenTranslations(\n obj: any,\n prefix: string = ''\n): Array<[string, string]> {\n const results: Array<[string, string]> = [];\n\n for (const key in obj) {\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n\n const value = obj[key];\n const fullKey = prefix ? `${prefix}.${key}` : key;\n\n if (typeof value === 'string') {\n results.push([fullKey, value]);\n } else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n // Recurse into nested objects\n results.push(...flattenTranslations(value, fullKey));\n }\n }\n\n return results;\n}\n\n/**\n * Debug helper to log memory map contents\n */\nexport function debugMemoryMap(): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap) {\n console.log('[ContentStorage] Memory map not initialized');\n return;\n }\n\n console.log('[ContentStorage] Memory map contents:');\n console.log(`Total entries: ${memoryMap.size}`);\n\n const entries = Array.from(memoryMap.entries()).slice(0, 10);\n console.table(\n entries.map(([value, entry]) => ({\n value: value.substring(0, 50),\n keys: Array.from(entry.ids).join(', '),\n namespace: entry.metadata?.namespace || 'N/A',\n }))\n );\n\n if (memoryMap.size > 10) {\n console.log(`... and ${memoryMap.size - 10} more entries`);\n }\n}\n","import type { PostProcessorModule } from 'i18next';\nimport type { ContentstoragePluginOptions } from './types';\nimport { trackTranslation, detectLiveEditorMode, initializeMemoryMap, loadLiveEditorScript, extractUserVariables, setCurrentLanguageCode } from './utils';\n\n/**\n * Contentstorage Live Editor Post-Processor\n *\n * This post-processor enables live editor functionality by tracking translations\n * at the point of resolution, capturing the actual values returned by i18next\n * including interpolations and plural forms.\n *\n * Use this to enable click-to-edit functionality in the Contentstorage live editor.\n * It works in addition to or instead of the backend plugin for more comprehensive\n * tracking, especially for dynamic translations.\n *\n * @example\n * ```typescript\n * import i18next from 'i18next';\n * import { ContentstorageLiveEditorPostProcessor } from '@contentstorage/i18next-plugin';\n *\n * i18next\n * .use(new ContentstorageLiveEditorPostProcessor({ debug: true }))\n * .init({\n * postProcess: ['contentstorage']\n * });\n * ```\n */\nexport class ContentstorageLiveEditorPostProcessor implements PostProcessorModule {\n static type: 'postProcessor' = 'postProcessor';\n type: 'postProcessor' = 'postProcessor';\n name: string = 'contentstorage';\n\n private options: ContentstoragePluginOptions;\n private isLiveMode: boolean = false;\n\n constructor(options: ContentstoragePluginOptions = {}) {\n this.options = {\n debug: false,\n liveEditorParam: 'contentstorage_live_editor',\n forceLiveMode: false,\n ...options,\n };\n\n // Detect live editor mode\n this.isLiveMode = detectLiveEditorMode(\n this.options.liveEditorParam,\n this.options.forceLiveMode\n );\n\n if (this.isLiveMode) {\n initializeMemoryMap();\n\n // Initialize current language code with browser language or fallback\n // This ensures window.currentLanguageCode is never undefined\n const browserLanguage = typeof navigator !== 'undefined' && navigator.language\n ? navigator.language.split('-')[0]\n : 'en';\n setCurrentLanguageCode(browserLanguage);\n\n // Load the live editor script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);\n\n if (this.options.debug) {\n console.log('[ContentStorage] Post-processor initialized in live mode');\n console.log(`[ContentStorage] Initial language code set to: ${browserLanguage}`);\n }\n }\n }\n\n /**\n * Process the translated value\n * Called by i18next after translation resolution\n */\n process(\n value: string,\n key: string | string[],\n options: any,\n translator: any\n ): string {\n // Only track in live mode\n if (!this.isLiveMode) {\n return value;\n }\n\n // Handle array of keys (fallback keys)\n const translationKey = Array.isArray(key) ? key[0] : key;\n\n // Only extract namespace if key explicitly uses colon notation\n // Don't pass namespace from options - let keys be clean by default\n let namespace: string | undefined;\n if (translationKey.includes(':')) {\n [namespace] = translationKey.split(':');\n }\n console.log('[Contentstorage plugin] ', {\n options,\n translator\n })\n // Extract language\n const language = options?.lng || translator?.language;\n\n // Set current language code for live editor\n if (language) {\n setCurrentLanguageCode(language);\n }\n\n // Extract user variables from options\n const variables = extractUserVariables(options);\n\n // Try to get the template (non-interpolated value) from the translator\n // This allows us to track the template with {{placeholders}} instead of resolved values\n let template = value;\n try {\n if (translator?.resourceStore) {\n const ns = namespace || options?.ns || translator.options?.defaultNS || 'translation';\n const lng = language || translator.language;\n\n // Try to get the raw translation template from the resource store\n const rawTranslation = translator.resourceStore.getResource(lng, ns, translationKey);\n if (rawTranslation && typeof rawTranslation === 'string') {\n template = rawTranslation;\n }\n }\n } catch (e) {\n // If we can't get the template, fall back to using the resolved value\n if (this.options.debug) {\n console.warn('[Contentstorage plugin] Could not retrieve template for:', translationKey, e);\n }\n }\n\n // Track the translation with the template\n trackTranslation(\n template,\n translationKey,\n namespace,\n language,\n this.options.debug,\n variables\n );\n\n return value;\n }\n}\n\n/**\n * Create a new instance of the Contentstorage Live Editor post-processor\n */\nexport function createContentstorageLiveEditorPostProcessor(\n options?: ContentstoragePluginOptions\n): ContentstorageLiveEditorPostProcessor {\n return new ContentstorageLiveEditorPostProcessor(options);\n}\n","import type {\n BackendModule,\n ReadCallback,\n Services,\n InitOptions,\n} from 'i18next';\nimport type {\n ContentstoragePluginOptions,\n TranslationData,\n} from './types';\nimport {\n detectLiveEditorMode,\n initializeMemoryMap,\n trackTranslation,\n cleanupMemoryMap,\n flattenTranslations,\n isBrowser,\n loadLiveEditorScript,\n} from './utils';\nimport { ContentstorageLiveEditorPostProcessor } from './post-processor';\n\n/**\n * Contentstorage i18next Backend Plugin\n *\n * This plugin enables translation tracking for the Contentstorage live editor\n * by maintaining a memory map of translations and their keys.\n *\n * Features:\n * - Automatic live editor mode detection\n * - Translation tracking with memory map\n * - Support for nested translations\n * - Memory management with size limits\n * - Custom CDN or load path support\n *\n * @example\n * ```typescript\n * import i18next from 'i18next';\n * import ContentstorageBackend from '@contentstorage/i18next-plugin';\n *\n * i18next\n * .use(ContentstorageBackend)\n * .init({\n * backend: {\n * contentKey: 'your-content-key',\n * debug: true\n * }\n * });\n * ```\n */\nexport class ContentstorageBackend implements BackendModule<ContentstoragePluginOptions> {\n static type: 'backend' = 'backend';\n type: 'backend' = 'backend';\n\n private options: ContentstoragePluginOptions;\n private isLiveMode: boolean = false;\n private postProcessor?: ContentstorageLiveEditorPostProcessor;\n\n constructor(_services?: Services, options?: ContentstoragePluginOptions, _i18nextOptions?: InitOptions) {\n this.options = options || {};\n\n // Initialize if services and i18nextOptions are provided\n // This allows i18next to initialize the plugin automatically\n if (_services && _i18nextOptions) {\n this.init(_services, options, _i18nextOptions);\n }\n }\n\n /**\n * Initialize the plugin\n * Called by i18next during initialization\n */\n init(\n services: Services,\n backendOptions: ContentstoragePluginOptions = {},\n i18nextOptions: InitOptions = {}\n ): void {\n\n this.options = {\n debug: false,\n maxMemoryMapSize: 10000,\n liveEditorParam: 'contentstorage_live_editor',\n forceLiveMode: false,\n ...backendOptions,\n };\n\n // Detect live editor mode\n this.isLiveMode = detectLiveEditorMode(\n this.options.liveEditorParam,\n this.options.forceLiveMode\n );\n\n if (this.isLiveMode) {\n // Initialize memory map\n initializeMemoryMap();\n\n // Load the live editor script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl).then((loaded) => {\n if (loaded) {\n if (this.options.debug) {\n console.log('[ContentStorage] Live editor ready');\n }\n } else {\n console.warn('[ContentStorage] Failed to load live editor script');\n }\n });\n\n // Auto-register the post-processor for live editor tracking\n this.registerPostProcessor(services, i18nextOptions);\n\n if (this.options.debug) {\n console.log('[ContentStorage] Live editor mode enabled');\n console.log('[ContentStorage] Post-processor auto-registered');\n console.log('[ContentStorage] Plugin initialized with options:', this.options);\n }\n } else if (this.options.debug) {\n console.log('[ContentStorage] Running in normal mode (not live editor)');\n }\n }\n\n /**\n * Auto-register the live editor post-processor\n * This allows dynamic translation tracking without requiring explicit postProcess config\n */\n private registerPostProcessor(services: Services, i18nextOptions: InitOptions): void {\n // Create post-processor instance\n this.postProcessor = new ContentstorageLiveEditorPostProcessor(this.options);\n\n // Register with i18next\n services.languageUtils?.addPostProcessor(this.postProcessor);\n\n // Add to postProcess array if it exists, otherwise create it\n const initOptions = i18nextOptions as any;\n if (!initOptions.postProcess) {\n initOptions.postProcess = [];\n }\n\n // Ensure postProcess is an array\n if (!Array.isArray(initOptions.postProcess)) {\n initOptions.postProcess = [initOptions.postProcess];\n }\n\n // Add our post-processor if not already present\n if (!initOptions.postProcess.includes('contentstorage')) {\n initOptions.postProcess.push('contentstorage');\n }\n }\n\n /**\n * Read translations for a given language and namespace\n * This is the main method called by i18next to load translations\n */\n read(\n language: string,\n namespace: string,\n callback: ReadCallback\n ): void {\n if (this.options.debug) {\n console.log(`[ContentStorage] Loading translations: ${language}/${namespace}`);\n }\n\n this.loadTranslations(language, namespace)\n .then((translations) => {\n // Track translations if in live mode\n if (this.isLiveMode && this.shouldTrackNamespace(namespace)) {\n this.trackTranslations(translations, namespace, language);\n\n // Cleanup if needed\n if (this.options.maxMemoryMapSize) {\n cleanupMemoryMap(this.options.maxMemoryMapSize);\n }\n }\n\n callback(null, translations);\n })\n .catch((error) => {\n if (this.options.debug) {\n console.error('[ContentStorage] Failed to load translations:', error);\n }\n callback(error, false);\n });\n }\n\n /**\n * Load translations from CDN or custom source\n */\n private async loadTranslations(\n language: string,\n namespace: string\n ): Promise<TranslationData> {\n const url = this.getLoadPath(language, namespace);\n\n if (this.options.debug) {\n console.log(`[ContentStorage] Fetching from: ${url}`);\n }\n\n try {\n const fetchFn = this.options.request || this.defaultFetch.bind(this);\n return await fetchFn(url, {\n method: 'GET',\n headers: {\n 'Accept': 'application/json',\n },\n });\n } catch (error) {\n if (this.options.debug) {\n console.error('[ContentStorage] Fetch error:', error);\n }\n throw error;\n }\n }\n\n /**\n * Default fetch implementation\n */\n private async defaultFetch(url: string, options: RequestInit): Promise<any> {\n const response = await fetch(url, options);\n\n if (!response.ok) {\n throw new Error(\n `Failed to load translations: ${response.status} ${response.statusText}`\n );\n }\n\n return response.json();\n }\n\n /**\n * Get the URL to load translations from\n */\n private getLoadPath(language: string, namespace: string): string {\n const { loadPath, contentKey } = this.options;\n\n // Custom load path function\n if (typeof loadPath === 'function') {\n return loadPath(language, namespace);\n }\n\n // Custom load path string with interpolation\n if (typeof loadPath === 'string') {\n return loadPath\n .replace('{{lng}}', language)\n .replace('{{ns}}', namespace);\n }\n\n // Default CDN path\n if (!contentKey) {\n throw new Error(\n '[ContentStorage] contentKey is required when using default CDN path'\n );\n }\n\n // Default: Always use uppercase language code\n const lng = language.toUpperCase();\n\n // Default: https://cdn.contentstorage.app/{contentKey}/content/{LNG}.json\n return `https://cdn.contentstorage.app/${contentKey}/content/${lng}.json`;\n }\n\n /**\n * Check if a namespace should be tracked\n */\n private shouldTrackNamespace(namespace: string): boolean {\n const { trackNamespaces } = this.options;\n\n // If no filter specified, track all namespaces\n if (!trackNamespaces || trackNamespaces.length === 0) {\n return true;\n }\n\n return trackNamespaces.includes(namespace);\n }\n\n /**\n * Track all translations in the loaded data\n */\n private trackTranslations(\n translations: TranslationData,\n namespace: string,\n language: string\n ): void {\n if (!isBrowser()) return;\n\n const flatTranslations = flattenTranslations(translations);\n\n for (const [key, value] of flatTranslations) {\n // Skip empty values\n if (!value) continue;\n\n // Don't pass namespace - let keys be tracked without prefix by default\n // Only keys with explicit colon notation (e.g., \"common:welcome\") will have namespace\n trackTranslation(\n value,\n key,\n undefined, // namespace not passed by default\n language,\n this.options.debug\n );\n }\n\n if (this.options.debug) {\n console.log(\n `[ContentStorage] Tracked ${flatTranslations.length} translations for ${namespace}`\n );\n }\n }\n}\n\n/**\n * Create a new instance of the Contentstorage backend\n */\nexport function createContentstorageBackend(\n options?: ContentstoragePluginOptions\n): ContentstorageBackend {\n return new ContentstorageBackend(undefined, options);\n}\n\n// Default export\nexport default ContentstorageBackend;\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAkB,MAAM,SAAS,CAAC;AAE/E;;GAEG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,oBAAoB,GAAG,IAAI,CAGrE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,eAAe,GAAE,MAAqC,EACtD,aAAa,GAAE,OAAe,GAC7B,OAAO,CAqBT;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,SAAS,GAAG,IAAI,CAStD;AAQD,wBAAgB,oBAAoB,CAClC,OAAO,GAAE,MAAU,EACnB,KAAK,GAAE,MAAa,EACpB,KAAK,GAAE,OAAe,EACtB,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,OAAO,CAAC,CAsDlB;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,SAAS,GAAG,IAAI,CAG/C;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAKjE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,GAAG,IAAI,CAGtD;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAepE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAkBlD;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGzD;AAkCD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CA0BnF;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,gBAAgB,EAAE,MAAM,EACxB,cAAc,EAAE,MAAM,EACtB,SAAS,CAAC,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,EACjB,KAAK,GAAE,OAAe,EACtB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC9B,IAAI,CAwCN;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAqBtD;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,GAAG,EACR,MAAM,GAAE,MAAW,GAClB,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAkBzB;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAsBrC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAkB,MAAM,SAAS,CAAC;AAE/E;;GAEG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,oBAAoB,GAAG,IAAI,CAGrE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,eAAe,GAAE,MAAqC,EACtD,aAAa,GAAE,OAAe,GAC7B,OAAO,CAqBT;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,SAAS,GAAG,IAAI,CAStD;AAQD,wBAAgB,oBAAoB,CAClC,OAAO,GAAE,MAAU,EACnB,KAAK,GAAE,MAAa,EACpB,KAAK,GAAE,OAAe,EACtB,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,OAAO,CAAC,CAsDlB;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,SAAS,GAAG,IAAI,CAG/C;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAKjE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,GAAG,IAAI,CAGtD;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAepE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAkBlD;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGzD;AAkCD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CA0BnF;AAKD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,gBAAgB,EAAE,MAAM,EACxB,cAAc,EAAE,MAAM,EACtB,SAAS,CAAC,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,EACjB,KAAK,GAAE,OAAe,EACtB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC9B,IAAI,CAsDN;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAqBtD;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,GAAG,EACR,MAAM,GAAE,MAAW,GAClB,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAkBzB;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAsBrC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentstorage/i18next-plugin",
3
- "version": "2.0.14",
3
+ "version": "2.1.0-2",
4
4
  "description": "i18next plugin for Contentstorage live editor translation tracking",
5
5
  "author": "Kaido Hussar <kaido@contentstorage.app>",
6
6
  "main": "dist/index.js",