@intlayer/editor 8.3.2 → 8.3.4

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.
Files changed (54) hide show
  1. package/dist/cjs/ContentSelector-BXawqqyE.cjs +41 -0
  2. package/dist/cjs/ContentSelector-BXawqqyE.cjs.map +1 -0
  3. package/dist/cjs/components/ContentSelector.cjs +1 -0
  4. package/dist/cjs/components/index.cjs +1 -0
  5. package/dist/cjs/core/CrossFrameMessenger.cjs +2 -0
  6. package/dist/cjs/core/CrossFrameMessenger.cjs.map +1 -0
  7. package/dist/cjs/core/CrossFrameStateManager.cjs +2 -0
  8. package/dist/cjs/core/CrossFrameStateManager.cjs.map +1 -0
  9. package/dist/cjs/core/EditorStateManager.cjs +2 -0
  10. package/dist/cjs/core/EditorStateManager.cjs.map +1 -0
  11. package/dist/cjs/core/IframeClickInterceptor.cjs +2 -0
  12. package/dist/cjs/core/IframeClickInterceptor.cjs.map +1 -0
  13. package/dist/cjs/core/UrlStateManager.cjs +2 -0
  14. package/dist/cjs/core/UrlStateManager.cjs.map +1 -0
  15. package/dist/cjs/core/index.cjs +1 -0
  16. package/dist/cjs/index.cjs +1 -1
  17. package/dist/esm/ContentSelector-QN8BYkA9.mjs +41 -0
  18. package/dist/esm/ContentSelector-QN8BYkA9.mjs.map +1 -0
  19. package/dist/esm/components/ContentSelector.mjs +1 -0
  20. package/dist/esm/components/index.mjs +1 -0
  21. package/dist/esm/core/CrossFrameMessenger.mjs +2 -0
  22. package/dist/esm/core/CrossFrameMessenger.mjs.map +1 -0
  23. package/dist/esm/core/CrossFrameStateManager.mjs +2 -0
  24. package/dist/esm/core/CrossFrameStateManager.mjs.map +1 -0
  25. package/dist/esm/core/EditorStateManager.mjs +2 -0
  26. package/dist/esm/core/EditorStateManager.mjs.map +1 -0
  27. package/dist/esm/core/IframeClickInterceptor.mjs +2 -0
  28. package/dist/esm/core/IframeClickInterceptor.mjs.map +1 -0
  29. package/dist/esm/core/UrlStateManager.mjs +2 -0
  30. package/dist/esm/core/UrlStateManager.mjs.map +1 -0
  31. package/dist/esm/core/index.mjs +1 -0
  32. package/dist/esm/index.mjs +1 -1
  33. package/dist/types/ContentSelector-rBO8c1Kp.d.ts +49 -0
  34. package/dist/types/ContentSelector-rBO8c1Kp.d.ts.map +1 -0
  35. package/dist/types/CrossFrameMessenger-CAAHntwS.d.ts +48 -0
  36. package/dist/types/CrossFrameMessenger-CAAHntwS.d.ts.map +1 -0
  37. package/dist/types/CrossFrameStateManager-DxgxsAmo.d.ts +44 -0
  38. package/dist/types/CrossFrameStateManager-DxgxsAmo.d.ts.map +1 -0
  39. package/dist/types/EditorStateManager-Ym8YfMiG.d.ts +57 -0
  40. package/dist/types/EditorStateManager-Ym8YfMiG.d.ts.map +1 -0
  41. package/dist/types/IframeClickInterceptor-Dy1raFvk.d.ts +26 -0
  42. package/dist/types/IframeClickInterceptor-Dy1raFvk.d.ts.map +1 -0
  43. package/dist/types/UrlStateManager-Bq87v4hY.d.ts +21 -0
  44. package/dist/types/UrlStateManager-Bq87v4hY.d.ts.map +1 -0
  45. package/dist/types/components/ContentSelector.d.ts +2 -0
  46. package/dist/types/components/index.d.ts +2 -0
  47. package/dist/types/core/CrossFrameMessenger.d.ts +2 -0
  48. package/dist/types/core/CrossFrameStateManager.d.ts +2 -0
  49. package/dist/types/core/EditorStateManager.d.ts +2 -0
  50. package/dist/types/core/IframeClickInterceptor.d.ts +2 -0
  51. package/dist/types/core/UrlStateManager.d.ts +2 -0
  52. package/dist/types/core/index.d.ts +6 -0
  53. package/dist/types/index.d.ts +7 -1
  54. package/package.json +12 -3
@@ -0,0 +1,41 @@
1
+ let e=require(`lit`),t=require(`lit/decorators.js`);function n(e,t,n,r){var i=arguments.length,a=i<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,n):r,o;if(typeof Reflect==`object`&&typeof Reflect.decorate==`function`)a=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,n,a):o(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a}var r=class extends e.LitElement{constructor(...e){super(...e),this.isSelecting=!1,this.pressDuration=250,this._isHovered=!1,this._isSelectingState=!1,this._pressTimer=null,this._clickOutsideHandler=null}static{this.styles=e.css`
2
+ :host {
3
+ display: contents;
4
+ }
5
+
6
+ .wrapper {
7
+ display: inline-block;
8
+ cursor: pointer;
9
+ user-select: none;
10
+ border-radius: 0.375rem;
11
+ outline-width: 2px;
12
+ outline-offset: 4px;
13
+ outline-style: solid;
14
+ outline-color: transparent;
15
+ transition: all 100ms 50ms ease-in-out;
16
+ }
17
+
18
+ .wrapper[data-active] {
19
+ outline-color: inherit;
20
+ }
21
+ `}connectedCallback(){super.connectedCallback(),this._clickOutsideHandler=e=>{e.composedPath().includes(this)||(this._isSelectingState=!1,this._dispatch(`intlayer:click-outside`))},document.addEventListener(`mousedown`,this._clickOutsideHandler)}disconnectedCallback(){super.disconnectedCallback(),this._clickOutsideHandler&&=(document.removeEventListener(`mousedown`,this._clickOutsideHandler),null),this._clearPressTimer()}_clearPressTimer(){this._pressTimer!==null&&(clearTimeout(this._pressTimer),this._pressTimer=null)}_dispatch(e){this.dispatchEvent(new CustomEvent(e,{bubbles:!0,composed:!0}))}_handleMouseDown(){this._clearPressTimer(),this._pressTimer=setTimeout(()=>{this._isSelectingState=!0,this._dispatch(`intlayer:press`)},this.pressDuration)}_handleMouseEnter(){this._isHovered=!0,this._dispatch(`intlayer:hover`)}_handleMouseUpOrLeave(){this._isHovered&&(this._isHovered=!1,this._dispatch(`intlayer:unhover`)),this._clearPressTimer()}_handleClick(e){(this.isSelecting||this._isSelectingState)&&(e.preventDefault(),e.stopPropagation())}_handleBlur(){this._isSelectingState=!1}render(){return e.html`
22
+ <span
23
+ class="wrapper"
24
+ ?data-active=${this.isSelecting||this._isSelectingState||this._isHovered}
25
+ role="button"
26
+ tabindex="0"
27
+ @mousedown=${this._handleMouseDown}
28
+ @mouseup=${this._handleMouseUpOrLeave}
29
+ @mouseleave=${this._handleMouseUpOrLeave}
30
+ @mouseenter=${this._handleMouseEnter}
31
+ @click=${this._handleClick}
32
+ @touchstart=${this._handleMouseDown}
33
+ @touchend=${this._handleMouseUpOrLeave}
34
+ @touchcancel=${this._handleMouseUpOrLeave}
35
+ @blur=${this._handleBlur}
36
+ @keyup=${()=>{}}
37
+ >
38
+ <slot></slot>
39
+ </span>
40
+ `}};n([(0,t.property)({type:Boolean,attribute:`is-selecting`})],r.prototype,`isSelecting`,void 0),n([(0,t.property)({type:Number,attribute:`press-duration`})],r.prototype,`pressDuration`,void 0),n([(0,t.state)()],r.prototype,`_isHovered`,void 0),n([(0,t.state)()],r.prototype,`_isSelectingState`,void 0),n([(0,t.query)(`.wrapper`)],r.prototype,`_wrapper`,void 0);const i=()=>{typeof customElements>`u`||customElements.get(`intlayer-content-selector`)||customElements.define(`intlayer-content-selector`,r)};Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return r}});
41
+ //# sourceMappingURL=ContentSelector-BXawqqyE.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContentSelector-BXawqqyE.cjs","names":["LitElement"],"sources":["../../src/components/ContentSelector.ts"],"sourcesContent":["import { css, html, LitElement } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\n\nconst DEFAULT_PRESS_DURATION = 250;\n\n/**\n * <intlayer-content-selector>\n *\n * A framework-agnostic web component that wraps content with Intlayer editor\n * selection UI (hover outline, long-press to select, click-outside to deselect).\n *\n * Replaces the per-framework ContentSelector components (React, Svelte, Vue, Solid).\n *\n * @fires intlayer:press - Fired after a long press (pressDuration ms). Bubbles.\n * @fires intlayer:hover - Fired on mouseenter. Bubbles.\n * @fires intlayer:unhover - Fired on mouseleave / mouseup. Bubbles.\n * @fires intlayer:click-outside - Fired when a click occurs outside the element. Bubbles.\n *\n * @prop {boolean} isSelecting - Whether this element is currently selected (external state)\n * @prop {number} pressDuration - Long-press threshold in ms. Default: 250\n */\nexport class IntlayerContentSelectorElement extends LitElement {\n static styles = css`\n :host {\n display: contents;\n }\n\n .wrapper {\n display: inline-block;\n cursor: pointer;\n user-select: none;\n border-radius: 0.375rem;\n outline-width: 2px;\n outline-offset: 4px;\n outline-style: solid;\n outline-color: transparent;\n transition: all 100ms 50ms ease-in-out;\n }\n\n .wrapper[data-active] {\n outline-color: inherit;\n }\n `;\n\n @property({ type: Boolean, attribute: 'is-selecting' })\n isSelecting = false;\n\n @property({ type: Number, attribute: 'press-duration' })\n pressDuration = DEFAULT_PRESS_DURATION;\n\n @state() private _isHovered = false;\n @state() private _isSelectingState = false;\n\n @query('.wrapper') private _wrapper!: HTMLSpanElement;\n\n private _pressTimer: ReturnType<typeof setTimeout> | null = null;\n private _clickOutsideHandler: ((e: MouseEvent) => void) | null = null;\n\n connectedCallback(): void {\n super.connectedCallback();\n this._clickOutsideHandler = (e: MouseEvent) => {\n // composedPath() pierces shadow boundaries\n if (!e.composedPath().includes(this)) {\n this._isSelectingState = false;\n this._dispatch('intlayer:click-outside');\n }\n };\n document.addEventListener('mousedown', this._clickOutsideHandler);\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n if (this._clickOutsideHandler) {\n document.removeEventListener('mousedown', this._clickOutsideHandler);\n this._clickOutsideHandler = null;\n }\n this._clearPressTimer();\n }\n\n private _clearPressTimer(): void {\n if (this._pressTimer !== null) {\n clearTimeout(this._pressTimer);\n this._pressTimer = null;\n }\n }\n\n private _dispatch(eventName: string): void {\n this.dispatchEvent(\n new CustomEvent(eventName, { bubbles: true, composed: true })\n );\n }\n\n private _handleMouseDown(): void {\n this._clearPressTimer();\n this._pressTimer = setTimeout(() => {\n this._isSelectingState = true;\n this._dispatch('intlayer:press');\n }, this.pressDuration);\n }\n\n private _handleMouseEnter(): void {\n this._isHovered = true;\n this._dispatch('intlayer:hover');\n }\n\n private _handleMouseUpOrLeave(): void {\n if (this._isHovered) {\n this._isHovered = false;\n this._dispatch('intlayer:unhover');\n }\n this._clearPressTimer();\n }\n\n private _handleClick(e: MouseEvent): void {\n if (this.isSelecting || this._isSelectingState) {\n e.preventDefault();\n e.stopPropagation();\n }\n }\n\n private _handleBlur(): void {\n this._isSelectingState = false;\n }\n\n render() {\n const isActive =\n this.isSelecting || this._isSelectingState || this._isHovered;\n return html`\n <span\n class=\"wrapper\"\n ?data-active=${isActive}\n role=\"button\"\n tabindex=\"0\"\n @mousedown=${this._handleMouseDown}\n @mouseup=${this._handleMouseUpOrLeave}\n @mouseleave=${this._handleMouseUpOrLeave}\n @mouseenter=${this._handleMouseEnter}\n @click=${this._handleClick}\n @touchstart=${this._handleMouseDown}\n @touchend=${this._handleMouseUpOrLeave}\n @touchcancel=${this._handleMouseUpOrLeave}\n @blur=${this._handleBlur}\n @keyup=${() => {}}\n >\n <slot></slot>\n </span>\n `;\n }\n}\n\n/**\n * Register the <intlayer-content-selector> custom element.\n * Call this once at application startup (inside IntlayerEditorProvider or similar).\n * Safe to call multiple times — only registers if not already defined.\n */\nexport const defineIntlayerElements = (): void => {\n if (typeof customElements === 'undefined') return;\n if (!customElements.get('intlayer-content-selector')) {\n customElements.define(\n 'intlayer-content-selector',\n IntlayerContentSelectorElement\n );\n }\n};\n"],"mappings":"yXAqBA,IAAa,EAAb,cAAoDA,EAAAA,UAAW,gDAwB/C,sBAGE,oBAEc,0BACO,oBAIuB,+BACK,wBAlCjD,EAAA,GAAG;;;;;;;;;;;;;;;;;;;;IAoCnB,mBAA0B,CACxB,MAAM,mBAAmB,CACzB,KAAK,qBAAwB,GAAkB,CAExC,EAAE,cAAc,CAAC,SAAS,KAAK,GAClC,KAAK,kBAAoB,GACzB,KAAK,UAAU,yBAAyB,GAG5C,SAAS,iBAAiB,YAAa,KAAK,qBAAqB,CAGnE,sBAA6B,CAC3B,MAAM,sBAAsB,CAC5B,AAEE,KAAK,wBADL,SAAS,oBAAoB,YAAa,KAAK,qBAAqB,CACxC,MAE9B,KAAK,kBAAkB,CAGzB,kBAAiC,CAC3B,KAAK,cAAgB,OACvB,aAAa,KAAK,YAAY,CAC9B,KAAK,YAAc,MAIvB,UAAkB,EAAyB,CACzC,KAAK,cACH,IAAI,YAAY,EAAW,CAAE,QAAS,GAAM,SAAU,GAAM,CAAC,CAC9D,CAGH,kBAAiC,CAC/B,KAAK,kBAAkB,CACvB,KAAK,YAAc,eAAiB,CAClC,KAAK,kBAAoB,GACzB,KAAK,UAAU,iBAAiB,EAC/B,KAAK,cAAc,CAGxB,mBAAkC,CAChC,KAAK,WAAa,GAClB,KAAK,UAAU,iBAAiB,CAGlC,uBAAsC,CAChC,KAAK,aACP,KAAK,WAAa,GAClB,KAAK,UAAU,mBAAmB,EAEpC,KAAK,kBAAkB,CAGzB,aAAqB,EAAqB,EACpC,KAAK,aAAe,KAAK,qBAC3B,EAAE,gBAAgB,CAClB,EAAE,iBAAiB,EAIvB,aAA4B,CAC1B,KAAK,kBAAoB,GAG3B,QAAS,CAGP,MAAO,GAAA,IAAI;;;uBADT,KAAK,aAAe,KAAK,mBAAqB,KAAK,WAIzB;;;qBAGX,KAAK,iBAAiB;mBACxB,KAAK,sBAAsB;sBACxB,KAAK,sBAAsB;sBAC3B,KAAK,kBAAkB;iBAC5B,KAAK,aAAa;sBACb,KAAK,iBAAiB;oBACxB,KAAK,sBAAsB;uBACxB,KAAK,sBAAsB;gBAClC,KAAK,YAAY;qBACV,GAAG;;;;0BAlGd,CAAE,KAAM,QAAS,UAAW,eAAgB,CAAC,CAAA,CAAA,EAAA,UAAA,cAAA,IAAA,GAAA,mBAG7C,CAAE,KAAM,OAAQ,UAAW,iBAAkB,CAAC,CAAA,CAAA,EAAA,UAAA,gBAAA,IAAA,GAAA,iBAGhD,CAAA,CAAA,EAAA,UAAA,aAAA,IAAA,GAAA,iBACA,CAAA,CAAA,EAAA,UAAA,oBAAA,IAAA,GAAA,gBAED,WAAW,CAAA,CAAA,EAAA,UAAA,WAAA,IAAA,GAAA,CAsGpB,MAAa,MAAqC,CAC5C,OAAO,eAAmB,KACzB,eAAe,IAAI,4BAA4B,EAClD,eAAe,OACb,4BACA,EACD"}
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../ContentSelector-BXawqqyE.cjs`);exports.IntlayerContentSelectorElement=e.t,exports.defineIntlayerElements=e.n;
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../ContentSelector-BXawqqyE.cjs`);exports.IntlayerContentSelectorElement=e.t,exports.defineIntlayerElements=e.n;
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../compareUrls.cjs`),t=()=>Math.random().toString(36).slice(2);var n=class{constructor(e){this._subscribers=new Map,this._windowHandler=null,this._config=e,this.senderId=t()}start(){typeof window>`u`||this._windowHandler||(this._windowHandler=e=>{this._handleMessage(e)},window.addEventListener(`message`,this._windowHandler))}stop(){this._windowHandler&&=(window.removeEventListener(`message`,this._windowHandler),null)}send(e,t){let n={type:e,data:t,senderId:this.senderId};for(let e of this._config.allowedOrigins)e&&this._config.postMessageFn(n,e)}subscribe(e,t){return this._subscribers.has(e)||this._subscribers.set(e,new Set),this._subscribers.get(e).add(t),()=>{this._subscribers.get(e)?.delete(t)}}_handleMessage(t){let n=t.data;if(!n||typeof n!=`object`)return;let{type:r,data:i,senderId:a}=n;if(!r||typeof r!=`string`||a===this.senderId)return;let{allowedOrigins:o}=this._config;if(!(!o||o.length===0||o.includes(`*`)||o.filter(e=>!!e&&e!==``).some(n=>e.compareUrls(n,t.origin))))return;let s=this._subscribers.get(r);if(s)for(let e of s)e(i,a)}};exports.CrossFrameMessenger=n;
2
+ //# sourceMappingURL=CrossFrameMessenger.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CrossFrameMessenger.cjs","names":["compareUrls"],"sources":["../../../src/core/CrossFrameMessenger.ts"],"sourcesContent":["import { compareUrls } from '../compareUrls';\n\nconst randomUUID = (): string => Math.random().toString(36).slice(2);\n\nexport type MessagePayload = {\n type: string;\n data?: unknown;\n senderId?: string;\n};\n\nexport type MessengerConfig = {\n /**\n * Origins allowed to send messages to this instance.\n * Use '*' to allow all origins (not recommended for production).\n */\n allowedOrigins: string[];\n /**\n * Function used to send messages to other frames.\n * Injected so the messenger is agnostic to the frame topology.\n */\n postMessageFn: (payload: MessagePayload, origin: string) => void;\n};\n\ntype MessageHandler<T = unknown> = (data: T, senderId?: string) => void;\n\n/**\n * CrossFrameMessenger manages all cross-frame postMessage communication.\n * It owns a single window message listener and routes incoming messages to\n * type-specific subscribers.\n *\n * Replaces CommunicatorContext + useCrossFrameMessageListener across all frameworks.\n */\nexport class CrossFrameMessenger {\n readonly senderId: string;\n private readonly _config: MessengerConfig;\n private readonly _subscribers = new Map<string, Set<MessageHandler>>();\n private _windowHandler: ((event: MessageEvent) => void) | null = null;\n\n constructor(config: MessengerConfig) {\n this._config = config;\n this.senderId = randomUUID();\n }\n\n /** Start listening for incoming messages on window. */\n start(): void {\n if (typeof window === 'undefined') return;\n if (this._windowHandler) return;\n this._windowHandler = (event: MessageEvent<MessagePayload>) => {\n this._handleMessage(event);\n };\n window.addEventListener('message', this._windowHandler);\n }\n\n /** Stop listening and clean up. */\n stop(): void {\n if (this._windowHandler) {\n window.removeEventListener('message', this._windowHandler);\n this._windowHandler = null;\n }\n }\n\n /** Send a message payload to all configured target origins. */\n send(type: string, data?: unknown): void {\n const payload: MessagePayload = { type, data, senderId: this.senderId };\n for (const origin of this._config.allowedOrigins) {\n if (origin) {\n this._config.postMessageFn(payload, origin);\n }\n }\n }\n\n /**\n * Subscribe to messages of a given type.\n * Returns an unsubscribe function.\n */\n subscribe<T = unknown>(type: string, handler: MessageHandler<T>): () => void {\n if (!this._subscribers.has(type)) {\n this._subscribers.set(type, new Set());\n }\n this._subscribers.get(type)!.add(handler as MessageHandler);\n return () => {\n this._subscribers.get(type)?.delete(handler as MessageHandler);\n };\n }\n\n private _handleMessage(event: MessageEvent<MessagePayload>): void {\n const payload = event.data;\n if (!payload || typeof payload !== 'object') return;\n\n const { type, data, senderId: msgSenderId } = payload;\n if (!type || typeof type !== 'string') return;\n\n // Ignore messages originating from this instance\n if (msgSenderId === this.senderId) return;\n\n // Validate message origin\n const { allowedOrigins } = this._config;\n const isAllowed =\n !allowedOrigins ||\n allowedOrigins.length === 0 ||\n allowedOrigins.includes('*') ||\n allowedOrigins\n .filter((url) => Boolean(url) && url !== '')\n .some((url) => compareUrls(url, event.origin));\n\n if (!isAllowed) return;\n\n const handlers = this._subscribers.get(type);\n if (handlers) {\n for (const handler of handlers) {\n handler(data, msgSenderId);\n }\n }\n }\n}\n"],"mappings":"yGAEM,MAA2B,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAE,CA8BpE,IAAa,EAAb,KAAiC,CAM/B,YAAY,EAAyB,mBAHL,IAAI,wBAC6B,KAG/D,KAAK,QAAU,EACf,KAAK,SAAW,GAAY,CAI9B,OAAc,CACR,OAAO,OAAW,KAClB,KAAK,iBACT,KAAK,eAAkB,GAAwC,CAC7D,KAAK,eAAe,EAAM,EAE5B,OAAO,iBAAiB,UAAW,KAAK,eAAe,EAIzD,MAAa,CACX,AAEE,KAAK,kBADL,OAAO,oBAAoB,UAAW,KAAK,eAAe,CACpC,MAK1B,KAAK,EAAc,EAAsB,CACvC,IAAM,EAA0B,CAAE,OAAM,OAAM,SAAU,KAAK,SAAU,CACvE,IAAK,IAAM,KAAU,KAAK,QAAQ,eAC5B,GACF,KAAK,QAAQ,cAAc,EAAS,EAAO,CASjD,UAAuB,EAAc,EAAwC,CAK3E,OAJK,KAAK,aAAa,IAAI,EAAK,EAC9B,KAAK,aAAa,IAAI,EAAM,IAAI,IAAM,CAExC,KAAK,aAAa,IAAI,EAAK,CAAE,IAAI,EAA0B,KAC9C,CACX,KAAK,aAAa,IAAI,EAAK,EAAE,OAAO,EAA0B,EAIlE,eAAuB,EAA2C,CAChE,IAAM,EAAU,EAAM,KACtB,GAAI,CAAC,GAAW,OAAO,GAAY,SAAU,OAE7C,GAAM,CAAE,OAAM,OAAM,SAAU,GAAgB,EAI9C,GAHI,CAAC,GAAQ,OAAO,GAAS,UAGzB,IAAgB,KAAK,SAAU,OAGnC,GAAM,CAAE,kBAAmB,KAAK,QAShC,GAAI,EAPF,CAAC,GACD,EAAe,SAAW,GAC1B,EAAe,SAAS,IAAI,EAC5B,EACG,OAAQ,GAAQ,EAAQ,GAAQ,IAAQ,GAAG,CAC3C,KAAM,GAAQA,EAAAA,YAAY,EAAK,EAAM,OAAO,CAAC,EAElC,OAEhB,IAAM,EAAW,KAAK,aAAa,IAAI,EAAK,CAC5C,GAAI,EACF,IAAK,IAAM,KAAW,EACpB,EAAQ,EAAM,EAAY"}
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=class extends EventTarget{constructor(e,t,n={}){super(),this._unsubscribers=[],this._key=e,this._messenger=t,this._options={emit:n.emit??!0,receive:n.receive??!0},n.initialValue!==void 0&&(this._value=n.initialValue)}get value(){return this._value}set(e){this._value=e,this.dispatchEvent(new CustomEvent(`change`,{detail:e})),this._options.emit&&this._messenger.send(`${this._key}/post`,e)}start(){if(this._options.receive){let e=this._messenger.subscribe(`${this._key}/post`,e=>{this._value=e,this.dispatchEvent(new CustomEvent(`change`,{detail:e}))});this._unsubscribers.push(e)}if(this._options.emit){let e=this._messenger.subscribe(`${this._key}/get`,(e,t)=>{t!==this._messenger.senderId&&this._value!==void 0&&this._messenger.send(`${this._key}/post`,this._value)});this._unsubscribers.push(e)}this._options.receive&&this._value===void 0&&this._messenger.send(`${this._key}/get`)}stop(){for(let e of this._unsubscribers)e();this._unsubscribers.length=0}postCurrentValue(){this._value!==void 0&&this._messenger.send(`${this._key}/post`,this._value)}};exports.CrossFrameStateManager=e;
2
+ //# sourceMappingURL=CrossFrameStateManager.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CrossFrameStateManager.cjs","names":[],"sources":["../../../src/core/CrossFrameStateManager.ts"],"sourcesContent":["import type { CrossFrameMessenger } from './CrossFrameMessenger';\n\nexport type CrossFrameStateOptions = {\n /** Whether to broadcast state changes to other frames. Default: true */\n emit?: boolean;\n /** Whether to listen for state updates from other frames. Default: true */\n receive?: boolean;\n};\n\n/**\n * CrossFrameStateManager synchronizes a single named value across frames using\n * the postMessage API via CrossFrameMessenger.\n *\n * Protocol:\n * `{key}/post` — broadcast a new value\n * `{key}/get` — request the current value from other frames\n *\n * Replaces useCrossFrameState across all frameworks.\n *\n * @fires change — CustomEvent<T> dispatched whenever the value changes (local set or received)\n */\nexport class CrossFrameStateManager<T> extends EventTarget {\n private _value: T | undefined;\n private readonly _key: string;\n private readonly _messenger: CrossFrameMessenger;\n private readonly _options: Required<CrossFrameStateOptions>;\n private readonly _unsubscribers: Array<() => void> = [];\n\n constructor(\n key: string,\n messenger: CrossFrameMessenger,\n options: CrossFrameStateOptions & { initialValue?: T } = {}\n ) {\n super();\n this._key = key;\n this._messenger = messenger;\n this._options = {\n emit: options.emit ?? true,\n receive: options.receive ?? true,\n };\n if (options.initialValue !== undefined) {\n this._value = options.initialValue;\n }\n }\n\n get value(): T | undefined {\n return this._value;\n }\n\n /** Update the value locally and broadcast it to other frames if emit is enabled. */\n set(newValue: T): void {\n this._value = newValue;\n this.dispatchEvent(new CustomEvent<T>('change', { detail: newValue }));\n if (this._options.emit) {\n this._messenger.send(`${this._key}/post`, newValue);\n }\n }\n\n /**\n * Start listening for incoming state updates and responding to /get requests.\n * If receive=true and no initial value is set, sends a /get to request the current value.\n */\n start(): void {\n if (this._options.receive) {\n const unsub = this._messenger.subscribe<T>(\n `${this._key}/post`,\n (data) => {\n this._value = data;\n this.dispatchEvent(new CustomEvent<T>('change', { detail: data }));\n }\n );\n this._unsubscribers.push(unsub);\n }\n\n if (this._options.emit) {\n // Respond to /get requests by broadcasting current value\n const unsub = this._messenger.subscribe(\n `${this._key}/get`,\n (_, originSenderId) => {\n if (originSenderId === this._messenger.senderId) return;\n if (this._value === undefined) return;\n this._messenger.send(`${this._key}/post`, this._value);\n }\n );\n this._unsubscribers.push(unsub);\n }\n\n // If receiving and no initial value, request it from other frames\n if (this._options.receive && this._value === undefined) {\n this._messenger.send(`${this._key}/get`);\n }\n }\n\n /** Stop all listeners. */\n stop(): void {\n for (const unsub of this._unsubscribers) unsub();\n this._unsubscribers.length = 0;\n }\n\n /** Broadcast the current value to all frames (useful after reconnect). */\n postCurrentValue(): void {\n if (this._value !== undefined) {\n this._messenger.send(`${this._key}/post`, this._value);\n }\n }\n}\n"],"mappings":"mEAqBA,IAAa,EAAb,cAA+C,WAAY,CAOzD,YACE,EACA,EACA,EAAyD,EAAE,CAC3D,CACA,OAAO,qBAP4C,EAAE,CAQrD,KAAK,KAAO,EACZ,KAAK,WAAa,EAClB,KAAK,SAAW,CACd,KAAM,EAAQ,MAAQ,GACtB,QAAS,EAAQ,SAAW,GAC7B,CACG,EAAQ,eAAiB,IAAA,KAC3B,KAAK,OAAS,EAAQ,cAI1B,IAAI,OAAuB,CACzB,OAAO,KAAK,OAId,IAAI,EAAmB,CACrB,KAAK,OAAS,EACd,KAAK,cAAc,IAAI,YAAe,SAAU,CAAE,OAAQ,EAAU,CAAC,CAAC,CAClE,KAAK,SAAS,MAChB,KAAK,WAAW,KAAK,GAAG,KAAK,KAAK,OAAQ,EAAS,CAQvD,OAAc,CACZ,GAAI,KAAK,SAAS,QAAS,CACzB,IAAM,EAAQ,KAAK,WAAW,UAC5B,GAAG,KAAK,KAAK,OACZ,GAAS,CACR,KAAK,OAAS,EACd,KAAK,cAAc,IAAI,YAAe,SAAU,CAAE,OAAQ,EAAM,CAAC,CAAC,EAErE,CACD,KAAK,eAAe,KAAK,EAAM,CAGjC,GAAI,KAAK,SAAS,KAAM,CAEtB,IAAM,EAAQ,KAAK,WAAW,UAC5B,GAAG,KAAK,KAAK,OACZ,EAAG,IAAmB,CACjB,IAAmB,KAAK,WAAW,UACnC,KAAK,SAAW,IAAA,IACpB,KAAK,WAAW,KAAK,GAAG,KAAK,KAAK,OAAQ,KAAK,OAAO,EAEzD,CACD,KAAK,eAAe,KAAK,EAAM,CAI7B,KAAK,SAAS,SAAW,KAAK,SAAW,IAAA,IAC3C,KAAK,WAAW,KAAK,GAAG,KAAK,KAAK,MAAM,CAK5C,MAAa,CACX,IAAK,IAAM,KAAS,KAAK,eAAgB,GAAO,CAChD,KAAK,eAAe,OAAS,EAI/B,kBAAyB,CACnB,KAAK,SAAW,IAAA,IAClB,KAAK,WAAW,KAAK,GAAG,KAAK,KAAK,OAAQ,KAAK,OAAO"}
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./CrossFrameMessenger.cjs`),t=require(`./CrossFrameStateManager.cjs`),n=require(`../messagesKeys.cjs`),r=require(`./IframeClickInterceptor.cjs`),i=require(`./UrlStateManager.cjs`);let a=require(`@intlayer/core/dictionaryManipulator`),o=require(`@intlayer/types/nodeType`);var s=class{constructor(a){this._mode=a.mode,this.messenger=new e.CrossFrameMessenger(a.messenger),this.editorEnabled=new t.CrossFrameStateManager(n.MessageKey.INTLAYER_EDITOR_ENABLED,this.messenger,{emit:!1,receive:!0,initialValue:!1}),this.focusedContent=new t.CrossFrameStateManager(n.MessageKey.INTLAYER_FOCUSED_CONTENT_CHANGED,this.messenger,{emit:!0,receive:!0,initialValue:null}),this.localeDictionaries=new t.CrossFrameStateManager(n.MessageKey.INTLAYER_LOCALE_DICTIONARIES_CHANGED,this.messenger),this.editedContent=new t.CrossFrameStateManager(n.MessageKey.INTLAYER_EDITED_CONTENT_CHANGED,this.messenger),this.configuration=new t.CrossFrameStateManager(n.MessageKey.INTLAYER_CONFIGURATION,this.messenger,{emit:!0,receive:!1,...a.configuration?{initialValue:a.configuration}:{}}),this.currentLocale=new t.CrossFrameStateManager(n.MessageKey.INTLAYER_CURRENT_LOCALE,this.messenger,{emit:!1,receive:!0}),this._urlManager=new i.UrlStateManager(this.messenger),this._iframeInterceptor=new r.IframeClickInterceptor(this.messenger)}start(){this.messenger.start(),this.editorEnabled.start(),this.focusedContent.start(),this.localeDictionaries.start(),this.editedContent.start(),this.configuration.start(),this.currentLocale.start(),this._mode===`client`?(this._urlManager.start(),this._iframeInterceptor.startInterceptor(),this._loadDictionaries(),this.messenger.send(`${n.MessageKey.INTLAYER_EDITED_CONTENT_CHANGED}/get`)):this._iframeInterceptor.startMerger()}stop(){this.messenger.stop(),this.editorEnabled.stop(),this.focusedContent.stop(),this.localeDictionaries.stop(),this.editedContent.stop(),this.configuration.stop(),this.currentLocale.stop(),this._urlManager.stop(),this._iframeInterceptor.stopInterceptor(),this._iframeInterceptor.stopMerger()}setFocusedContentKeyPath(e){let t=e.filter(e=>e.type!==o.NodeType.Translation),n=this.focusedContent.value;n&&this.focusedContent.set({...n,keyPath:t})}setLocaleDictionary(e){if(!e.localId)return;let t=this.localeDictionaries.value??{};this.localeDictionaries.set({...t,[e.localId]:e})}setEditedDictionary(e){if(!e.localId){console.error(`setEditedDictionary: missing localId`,e);return}let t=this.editedContent.value??{};this.editedContent.set({...t,[e.localId]:e})}setEditedContent(e,t){let n=this.editedContent.value??{};this.editedContent.set({...n,[e]:{...n[e],content:t}})}addContent(e,t,n=[],r=!0){let i=this.editedContent.value??{},o=(this.localeDictionaries.value??{})[e]?.content,s=structuredClone(i[e]?.content??o),c=n;if(!r){let e=0,t=n.slice(0,-1),r=n[n.length-1],i=r.key;for(;(0,a.getContentNodeByKeyPath)(s,c)!==void 0;)e++,i=e===0?r.key:`${r.key} (${e})`,c=[...t,{...r,key:i}]}let l=(0,a.editDictionaryByKeyPath)(s,c,t);this.editedContent.set({...i,[e]:{...i[e],content:l}})}renameContent(e,t,n=[]){let r=this.editedContent.value??{},i=(this.localeDictionaries.value??{})[e]?.content,o=(0,a.renameContentNodeByKeyPath)(structuredClone(r[e]?.content??i),t,n);this.editedContent.set({...r,[e]:{...r[e],content:o}})}removeContent(e,t){let n=this.editedContent.value??{},r=(this.localeDictionaries.value??{})[e]?.content,i=(0,a.editDictionaryByKeyPath)(structuredClone(n[e]?.content??r),t,(0,a.getContentNodeByKeyPath)(r,t));this.editedContent.set({...n,[e]:{...n[e],content:i}})}restoreContent(e){let t={...this.editedContent.value??{}};delete t[e],this.editedContent.set(t)}clearContent(e){let t={...this.editedContent.value??{}};delete t[e],this.editedContent.set(t)}clearAllContent(){this.editedContent.set({})}getContentValue(e,t){let n=this.editedContent.value;if(!n)return;let r=t.filter(e=>e.type!==o.NodeType.Translation);if(e.includes(`:local:`)||e.includes(`:remote:`))return(0,a.getContentNodeByKeyPath)(n[e]?.content??{},r,this.currentLocale.value);let i=Object.keys(n).filter(t=>t.startsWith(`${e}:`));for(let e of i){let t=(0,a.getContentNodeByKeyPath)(n[e]?.content??{},r,this.currentLocale.value);if(t)return t}}async _loadDictionaries(){try{let e=(await import(`@intlayer/unmerged-dictionaries-entry`)).getUnmergedDictionaries(),t=Object.fromEntries(Object.values(e).flat().map(e=>[e.localId,e]));this.localeDictionaries.set(t)}catch{}}};exports.EditorStateManager=s;
2
+ //# sourceMappingURL=EditorStateManager.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EditorStateManager.cjs","names":["CrossFrameMessenger","CrossFrameStateManager","MessageKey","UrlStateManager","IframeClickInterceptor","NodeType"],"sources":["../../../src/core/EditorStateManager.ts"],"sourcesContent":["import {\n editDictionaryByKeyPath,\n getContentNodeByKeyPath,\n renameContentNodeByKeyPath,\n} from '@intlayer/core/dictionaryManipulator';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type {\n ContentNode,\n Dictionary,\n LocalDictionaryId,\n} from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport { NodeType } from '@intlayer/types/nodeType';\nimport { MessageKey } from '../messagesKeys';\nimport {\n CrossFrameMessenger,\n type MessengerConfig,\n} from './CrossFrameMessenger';\nimport { CrossFrameStateManager } from './CrossFrameStateManager';\nimport { IframeClickInterceptor } from './IframeClickInterceptor';\nimport { UrlStateManager } from './UrlStateManager';\n\nexport type DictionaryContent = Record<LocalDictionaryId, Dictionary>;\n\nexport type FileContent = {\n dictionaryKey: string;\n dictionaryLocalId?: LocalDictionaryId;\n keyPath?: KeyPath[];\n};\n\nexport type EditorStateManagerConfig = {\n /** 'client' = the app running inside the iframe; 'editor' = the editor wrapping the app */\n mode: 'editor' | 'client';\n /** Cross-frame messaging configuration */\n messenger: MessengerConfig;\n /** Optional initial Intlayer configuration to broadcast */\n configuration?: IntlayerConfig;\n};\n\n/**\n * EditorStateManager is the single entry point for all Intlayer editor state.\n * It is framework-agnostic: instantiate one instance at the root of the application\n * and subscribe to its EventTarget-based events from any framework adapter.\n *\n * Replaces all context providers, hooks and store files across React, Preact,\n * Solid, Svelte, and Vue integrations.\n */\nexport class EditorStateManager {\n readonly messenger: CrossFrameMessenger;\n readonly editorEnabled: CrossFrameStateManager<boolean>;\n readonly focusedContent: CrossFrameStateManager<FileContent | null>;\n readonly localeDictionaries: CrossFrameStateManager<DictionaryContent>;\n readonly editedContent: CrossFrameStateManager<DictionaryContent>;\n readonly configuration: CrossFrameStateManager<IntlayerConfig>;\n readonly currentLocale: CrossFrameStateManager<Locale>;\n\n private readonly _urlManager: UrlStateManager;\n private readonly _iframeInterceptor: IframeClickInterceptor;\n private readonly _mode: 'editor' | 'client';\n\n constructor(config: EditorStateManagerConfig) {\n this._mode = config.mode;\n\n this.messenger = new CrossFrameMessenger(config.messenger);\n\n this.editorEnabled = new CrossFrameStateManager<boolean>(\n MessageKey.INTLAYER_EDITOR_ENABLED,\n this.messenger,\n { emit: false, receive: true, initialValue: false }\n );\n\n this.focusedContent = new CrossFrameStateManager<FileContent | null>(\n MessageKey.INTLAYER_FOCUSED_CONTENT_CHANGED,\n this.messenger,\n { emit: true, receive: true, initialValue: null }\n );\n\n this.localeDictionaries = new CrossFrameStateManager<DictionaryContent>(\n MessageKey.INTLAYER_LOCALE_DICTIONARIES_CHANGED,\n this.messenger\n );\n\n this.editedContent = new CrossFrameStateManager<DictionaryContent>(\n MessageKey.INTLAYER_EDITED_CONTENT_CHANGED,\n this.messenger\n );\n\n this.configuration = new CrossFrameStateManager<IntlayerConfig>(\n MessageKey.INTLAYER_CONFIGURATION,\n this.messenger,\n {\n emit: true,\n receive: false,\n ...(config.configuration ? { initialValue: config.configuration } : {}),\n }\n );\n\n this.currentLocale = new CrossFrameStateManager<Locale>(\n MessageKey.INTLAYER_CURRENT_LOCALE,\n this.messenger,\n { emit: false, receive: true }\n );\n\n this._urlManager = new UrlStateManager(this.messenger);\n this._iframeInterceptor = new IframeClickInterceptor(this.messenger);\n }\n\n start(): void {\n this.messenger.start();\n this.editorEnabled.start();\n this.focusedContent.start();\n this.localeDictionaries.start();\n this.editedContent.start();\n this.configuration.start();\n this.currentLocale.start();\n\n if (this._mode === 'client') {\n this._urlManager.start();\n this._iframeInterceptor.startInterceptor();\n this._loadDictionaries();\n // Request current edited content from the editor\n this.messenger.send(`${MessageKey.INTLAYER_EDITED_CONTENT_CHANGED}/get`);\n } else {\n this._iframeInterceptor.startMerger();\n }\n }\n\n stop(): void {\n this.messenger.stop();\n this.editorEnabled.stop();\n this.focusedContent.stop();\n this.localeDictionaries.stop();\n this.editedContent.stop();\n this.configuration.stop();\n this.currentLocale.stop();\n this._urlManager.stop();\n this._iframeInterceptor.stopInterceptor();\n this._iframeInterceptor.stopMerger();\n }\n\n // ─── Focus helpers ──────────────────────────────────────────────────────────\n\n setFocusedContentKeyPath(keyPath: KeyPath[]): void {\n const filtered = keyPath.filter((key) => key.type !== NodeType.Translation);\n const prev = this.focusedContent.value;\n if (!prev) return;\n this.focusedContent.set({ ...prev, keyPath: filtered });\n }\n\n // ─── Dictionary record helpers ───────────────────────────────────────────\n\n setLocaleDictionary(dictionary: Dictionary): void {\n if (!dictionary.localId) return;\n const current = this.localeDictionaries.value ?? {};\n this.localeDictionaries.set({\n ...current,\n [dictionary.localId as LocalDictionaryId]: dictionary,\n });\n }\n\n // ─── Edited content helpers ───────────────────────────────────────────────\n\n setEditedDictionary(newDict: Dictionary): void {\n if (!newDict.localId) {\n console.error('setEditedDictionary: missing localId', newDict);\n return;\n }\n const current = this.editedContent.value ?? {};\n this.editedContent.set({\n ...current,\n [newDict.localId as LocalDictionaryId]: newDict,\n });\n }\n\n setEditedContent(\n localDictionaryId: LocalDictionaryId,\n newValue: Dictionary['content']\n ): void {\n const current = this.editedContent.value ?? {};\n this.editedContent.set({\n ...current,\n [localDictionaryId]: {\n ...current[localDictionaryId],\n content: newValue,\n },\n });\n }\n\n addContent(\n localDictionaryId: LocalDictionaryId,\n newValue: ContentNode,\n keyPath: KeyPath[] = [],\n overwrite = true\n ): void {\n const current = this.editedContent.value ?? {};\n const localeDicts = this.localeDictionaries.value ?? {};\n const originalContent = localeDicts[localDictionaryId]?.content;\n const currentContent = structuredClone(\n current[localDictionaryId]?.content ?? originalContent\n );\n\n let newKeyPath = keyPath;\n if (!overwrite) {\n let index = 0;\n const otherKeyPath = keyPath.slice(0, -1);\n const lastKeyPath = keyPath[keyPath.length - 1];\n let finalKey = lastKeyPath.key;\n while (\n typeof getContentNodeByKeyPath(currentContent, newKeyPath) !==\n 'undefined'\n ) {\n index++;\n finalKey =\n index === 0 ? lastKeyPath.key : `${lastKeyPath.key} (${index})`;\n newKeyPath = [\n ...otherKeyPath,\n { ...lastKeyPath, key: finalKey } as KeyPath,\n ];\n }\n }\n\n const updatedContent = editDictionaryByKeyPath(\n currentContent,\n newKeyPath,\n newValue\n );\n this.editedContent.set({\n ...current,\n [localDictionaryId]: {\n ...current[localDictionaryId],\n content: updatedContent as Dictionary['content'],\n },\n });\n }\n\n renameContent(\n localDictionaryId: LocalDictionaryId,\n newKey: KeyPath['key'],\n keyPath: KeyPath[] = []\n ): void {\n const current = this.editedContent.value ?? {};\n const localeDicts = this.localeDictionaries.value ?? {};\n const originalContent = localeDicts[localDictionaryId]?.content;\n const currentContent = structuredClone(\n current[localDictionaryId]?.content ?? originalContent\n );\n const updated = renameContentNodeByKeyPath(currentContent, newKey, keyPath);\n this.editedContent.set({\n ...current,\n [localDictionaryId]: {\n ...current[localDictionaryId],\n content: updated as Dictionary['content'],\n },\n });\n }\n\n removeContent(\n localDictionaryId: LocalDictionaryId,\n keyPath: KeyPath[]\n ): void {\n const current = this.editedContent.value ?? {};\n const localeDicts = this.localeDictionaries.value ?? {};\n const originalContent = localeDicts[localDictionaryId]?.content;\n const currentContent = structuredClone(\n current[localDictionaryId]?.content ?? originalContent\n );\n const initialContent = getContentNodeByKeyPath(originalContent, keyPath);\n const restored = editDictionaryByKeyPath(\n currentContent,\n keyPath,\n initialContent\n );\n this.editedContent.set({\n ...current,\n [localDictionaryId]: {\n ...current[localDictionaryId],\n content: restored as Dictionary['content'],\n },\n });\n }\n\n restoreContent(localDictionaryId: LocalDictionaryId): void {\n const current = this.editedContent.value ?? {};\n const updated = { ...current };\n delete updated[localDictionaryId];\n this.editedContent.set(updated);\n }\n\n clearContent(localDictionaryId: LocalDictionaryId): void {\n const current = this.editedContent.value ?? {};\n const filtered = { ...current };\n delete filtered[localDictionaryId];\n this.editedContent.set(filtered);\n }\n\n clearAllContent(): void {\n this.editedContent.set({});\n }\n\n getContentValue(\n localDictionaryIdOrKey: LocalDictionaryId | string,\n keyPath: KeyPath[]\n ): ContentNode | undefined {\n const edited = this.editedContent.value;\n if (!edited) return undefined;\n\n const filteredKeyPath = keyPath.filter(\n (key) => key.type !== NodeType.Translation\n );\n\n const isDictionaryId =\n localDictionaryIdOrKey.includes(':local:') ||\n localDictionaryIdOrKey.includes(':remote:');\n\n if (isDictionaryId) {\n const content =\n edited[localDictionaryIdOrKey as LocalDictionaryId]?.content ?? {};\n return getContentNodeByKeyPath(\n content,\n filteredKeyPath,\n this.currentLocale.value\n );\n }\n\n const matchingIds = Object.keys(edited).filter((key) =>\n key.startsWith(`${localDictionaryIdOrKey}:`)\n );\n for (const localId of matchingIds) {\n const content = edited[localId as LocalDictionaryId]?.content ?? {};\n const node = getContentNodeByKeyPath(\n content,\n filteredKeyPath,\n this.currentLocale.value\n );\n if (node) return node;\n }\n\n return undefined;\n }\n\n private async _loadDictionaries(): Promise<void> {\n try {\n const mod = await import('@intlayer/unmerged-dictionaries-entry');\n const unmergedDictionaries = mod.getUnmergedDictionaries();\n const dictionariesList = Object.fromEntries(\n Object.values(unmergedDictionaries)\n .flat()\n .map((dictionary) => [dictionary.localId, dictionary])\n ) as DictionaryContent;\n this.localeDictionaries.set(dictionariesList);\n } catch {\n // Dynamic entry not available (expected in editor mode or when not configured)\n }\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../mergeIframeClick.cjs`),t=require(`../messagesKeys.cjs`);var n=class{constructor(e){this._mousedownHandler=null,this._unsubscribeMerge=null,this._messenger=e}startInterceptor(){typeof window>`u`||(this._mousedownHandler=()=>{this._messenger.send(t.MessageKey.INTLAYER_IFRAME_CLICKED)},window.addEventListener(`mousedown`,this._mousedownHandler))}startMerger(){this._unsubscribeMerge=this._messenger.subscribe(t.MessageKey.INTLAYER_IFRAME_CLICKED,e.mergeIframeClick)}stopInterceptor(){this._mousedownHandler&&=(window.removeEventListener(`mousedown`,this._mousedownHandler),null)}stopMerger(){this._unsubscribeMerge?.(),this._unsubscribeMerge=null}};exports.IframeClickInterceptor=n;
2
+ //# sourceMappingURL=IframeClickInterceptor.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IframeClickInterceptor.cjs","names":["MessageKey","mergeIframeClick"],"sources":["../../../src/core/IframeClickInterceptor.ts"],"sourcesContent":["import { mergeIframeClick } from '../mergeIframeClick';\nimport { MessageKey } from '../messagesKeys';\nimport type { CrossFrameMessenger } from './CrossFrameMessenger';\n\n/**\n * IframeClickInterceptor handles click events across iframe boundaries.\n *\n * - startInterceptor(): called in the client (iframe) — broadcasts mousedown to parent\n * - startMerger(): called in the editor (parent) — merges received clicks into DOM events\n *\n * Replaces useIframeClickInterceptor / useIframeClickMerger across all frameworks.\n */\nexport class IframeClickInterceptor {\n private readonly _messenger: CrossFrameMessenger;\n private _mousedownHandler: EventListener | null = null;\n private _unsubscribeMerge: (() => void) | null = null;\n\n constructor(messenger: CrossFrameMessenger) {\n this._messenger = messenger;\n }\n\n /** Called on the client side (inside iframe). Broadcasts click events to parent. */\n startInterceptor(): void {\n if (typeof window === 'undefined') return;\n this._mousedownHandler = () => {\n this._messenger.send(MessageKey.INTLAYER_IFRAME_CLICKED);\n };\n window.addEventListener('mousedown', this._mousedownHandler);\n }\n\n /** Called on the editor side (parent frame). Merges incoming iframe clicks into DOM. */\n startMerger(): void {\n this._unsubscribeMerge = this._messenger.subscribe(\n MessageKey.INTLAYER_IFRAME_CLICKED,\n mergeIframeClick as (data: unknown) => void\n );\n }\n\n stopInterceptor(): void {\n if (this._mousedownHandler) {\n window.removeEventListener('mousedown', this._mousedownHandler);\n this._mousedownHandler = null;\n }\n }\n\n stopMerger(): void {\n this._unsubscribeMerge?.();\n this._unsubscribeMerge = null;\n }\n}\n"],"mappings":"+IAYA,IAAa,EAAb,KAAoC,CAKlC,YAAY,EAAgC,wBAHM,4BACD,KAG/C,KAAK,WAAa,EAIpB,kBAAyB,CACnB,OAAO,OAAW,MACtB,KAAK,sBAA0B,CAC7B,KAAK,WAAW,KAAKA,EAAAA,WAAW,wBAAwB,EAE1D,OAAO,iBAAiB,YAAa,KAAK,kBAAkB,EAI9D,aAAoB,CAClB,KAAK,kBAAoB,KAAK,WAAW,UACvCA,EAAAA,WAAW,wBACXC,EAAAA,iBACD,CAGH,iBAAwB,CACtB,AAEE,KAAK,qBADL,OAAO,oBAAoB,YAAa,KAAK,kBAAkB,CACtC,MAI7B,YAAmB,CACjB,KAAK,qBAAqB,CAC1B,KAAK,kBAAoB"}
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../messagesKeys.cjs`);var t=class{constructor(e){this._originalPushState=null,this._originalReplaceState=null,this._listeners=[],this._messenger=e}start(){if(typeof window>`u`)return;let t=()=>{this._messenger.send(`${e.MessageKey.INTLAYER_URL_CHANGE}/post`,window.location.pathname)};this._originalPushState=history.pushState,this._originalReplaceState=history.replaceState;let n=e=>function(...t){e.apply(this,t),window.dispatchEvent(new Event(`locationchange`))};history.pushState=n(this._originalPushState),history.replaceState=n(this._originalReplaceState);for(let e of[`locationchange`,`popstate`,`hashchange`,`load`]){let n=t;window.addEventListener(e,n),this._listeners.push([e,n])}t()}stop(){if(!(typeof window>`u`)){for(let[e,t]of this._listeners)window.removeEventListener(e,t);this._listeners=[],this._originalPushState&&=(history.pushState=this._originalPushState,null),this._originalReplaceState&&=(history.replaceState=this._originalReplaceState,null)}}};exports.UrlStateManager=t;
2
+ //# sourceMappingURL=UrlStateManager.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UrlStateManager.cjs","names":["MessageKey"],"sources":["../../../src/core/UrlStateManager.ts"],"sourcesContent":["import { MessageKey } from '../messagesKeys';\nimport type { CrossFrameMessenger } from './CrossFrameMessenger';\n\n/**\n * UrlStateManager patches window.history and broadcasts URL path changes\n * across frames via postMessage.\n *\n * Replaces useCrossURLPathSetter / useCrossURLPathState across all frameworks.\n */\nexport class UrlStateManager {\n private readonly _messenger: CrossFrameMessenger;\n private _originalPushState: typeof history.pushState | null = null;\n private _originalReplaceState: typeof history.replaceState | null = null;\n private _listeners: Array<[string, EventListener]> = [];\n\n constructor(messenger: CrossFrameMessenger) {\n this._messenger = messenger;\n }\n\n start(): void {\n if (typeof window === 'undefined') return;\n\n const updateURLState = () => {\n this._messenger.send(\n `${MessageKey.INTLAYER_URL_CHANGE}/post`,\n window.location.pathname\n );\n };\n\n this._originalPushState = history.pushState;\n this._originalReplaceState = history.replaceState;\n\n const injectLocationChange = (method: typeof history.pushState) =>\n function (\n this: typeof history,\n ...args: Parameters<typeof history.pushState>\n ) {\n method.apply(this, args);\n window.dispatchEvent(new Event('locationchange'));\n };\n\n history.pushState = injectLocationChange(\n this._originalPushState\n ) as typeof history.pushState;\n history.replaceState = injectLocationChange(\n this._originalReplaceState\n ) as typeof history.replaceState;\n\n for (const eventName of [\n 'locationchange',\n 'popstate',\n 'hashchange',\n 'load',\n ] as const) {\n const listener = updateURLState as EventListener;\n window.addEventListener(eventName, listener);\n this._listeners.push([eventName, listener]);\n }\n\n updateURLState();\n }\n\n stop(): void {\n if (typeof window === 'undefined') return;\n\n for (const [eventName, listener] of this._listeners) {\n window.removeEventListener(eventName, listener);\n }\n this._listeners = [];\n\n if (this._originalPushState) {\n history.pushState = this._originalPushState;\n this._originalPushState = null;\n }\n if (this._originalReplaceState) {\n history.replaceState = this._originalReplaceState;\n this._originalReplaceState = null;\n }\n }\n}\n"],"mappings":"0GASA,IAAa,EAAb,KAA6B,CAM3B,YAAY,EAAgC,yBAJkB,gCACM,qBACf,EAAE,CAGrD,KAAK,WAAa,EAGpB,OAAc,CACZ,GAAI,OAAO,OAAW,IAAa,OAEnC,IAAM,MAAuB,CAC3B,KAAK,WAAW,KACd,GAAGA,EAAAA,WAAW,oBAAoB,OAClC,OAAO,SAAS,SACjB,EAGH,KAAK,mBAAqB,QAAQ,UAClC,KAAK,sBAAwB,QAAQ,aAErC,IAAM,EAAwB,GAC5B,SAEE,GAAG,EACH,CACA,EAAO,MAAM,KAAM,EAAK,CACxB,OAAO,cAAc,IAAI,MAAM,iBAAiB,CAAC,EAGrD,QAAQ,UAAY,EAClB,KAAK,mBACN,CACD,QAAQ,aAAe,EACrB,KAAK,sBACN,CAED,IAAK,IAAM,IAAa,CACtB,iBACA,WACA,aACA,OACD,CAAW,CACV,IAAM,EAAW,EACjB,OAAO,iBAAiB,EAAW,EAAS,CAC5C,KAAK,WAAW,KAAK,CAAC,EAAW,EAAS,CAAC,CAG7C,GAAgB,CAGlB,MAAa,CACP,YAAO,OAAW,KAEtB,KAAK,GAAM,CAAC,EAAW,KAAa,KAAK,WACvC,OAAO,oBAAoB,EAAW,EAAS,CAEjD,KAAK,WAAa,EAAE,CAEpB,AAEE,KAAK,sBADL,QAAQ,UAAY,KAAK,mBACC,MAE5B,AAEE,KAAK,yBADL,QAAQ,aAAe,KAAK,sBACC"}
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./CrossFrameMessenger.cjs`),t=require(`./CrossFrameStateManager.cjs`),n=require(`./IframeClickInterceptor.cjs`),r=require(`./UrlStateManager.cjs`),i=require(`./EditorStateManager.cjs`);exports.CrossFrameMessenger=e.CrossFrameMessenger,exports.CrossFrameStateManager=t.CrossFrameStateManager,exports.EditorStateManager=i.EditorStateManager,exports.IframeClickInterceptor=n.IframeClickInterceptor,exports.UrlStateManager=r.UrlStateManager;
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./compareUrls.cjs`),t=require(`./mergeIframeClick.cjs`),n=require(`./messagesKeys.cjs`);exports.MessageKey=n.MessageKey,exports.compareUrls=e.compareUrls,exports.mergeIframeClick=t.mergeIframeClick;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./compareUrls.cjs`),t=require(`./mergeIframeClick.cjs`),n=require(`./ContentSelector-BXawqqyE.cjs`);require(`./components/index.cjs`);const r=require(`./core/CrossFrameMessenger.cjs`),i=require(`./core/CrossFrameStateManager.cjs`),a=require(`./messagesKeys.cjs`),o=require(`./core/IframeClickInterceptor.cjs`),s=require(`./core/UrlStateManager.cjs`),c=require(`./core/EditorStateManager.cjs`);require(`./core/index.cjs`),exports.CrossFrameMessenger=r.CrossFrameMessenger,exports.CrossFrameStateManager=i.CrossFrameStateManager,exports.EditorStateManager=c.EditorStateManager,exports.IframeClickInterceptor=o.IframeClickInterceptor,exports.IntlayerContentSelectorElement=n.t,exports.MessageKey=a.MessageKey,exports.UrlStateManager=s.UrlStateManager,exports.compareUrls=e.compareUrls,exports.defineIntlayerElements=n.n,exports.mergeIframeClick=t.mergeIframeClick;
@@ -0,0 +1,41 @@
1
+ import{LitElement as e,css as t,html as n}from"lit";import{property as r,query as i,state as a}from"lit/decorators.js";function o(e,t,n,r){var i=arguments.length,a=i<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,n):r,o;if(typeof Reflect==`object`&&typeof Reflect.decorate==`function`)a=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,n,a):o(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a}var s=class extends e{constructor(...e){super(...e),this.isSelecting=!1,this.pressDuration=250,this._isHovered=!1,this._isSelectingState=!1,this._pressTimer=null,this._clickOutsideHandler=null}static{this.styles=t`
2
+ :host {
3
+ display: contents;
4
+ }
5
+
6
+ .wrapper {
7
+ display: inline-block;
8
+ cursor: pointer;
9
+ user-select: none;
10
+ border-radius: 0.375rem;
11
+ outline-width: 2px;
12
+ outline-offset: 4px;
13
+ outline-style: solid;
14
+ outline-color: transparent;
15
+ transition: all 100ms 50ms ease-in-out;
16
+ }
17
+
18
+ .wrapper[data-active] {
19
+ outline-color: inherit;
20
+ }
21
+ `}connectedCallback(){super.connectedCallback(),this._clickOutsideHandler=e=>{e.composedPath().includes(this)||(this._isSelectingState=!1,this._dispatch(`intlayer:click-outside`))},document.addEventListener(`mousedown`,this._clickOutsideHandler)}disconnectedCallback(){super.disconnectedCallback(),this._clickOutsideHandler&&=(document.removeEventListener(`mousedown`,this._clickOutsideHandler),null),this._clearPressTimer()}_clearPressTimer(){this._pressTimer!==null&&(clearTimeout(this._pressTimer),this._pressTimer=null)}_dispatch(e){this.dispatchEvent(new CustomEvent(e,{bubbles:!0,composed:!0}))}_handleMouseDown(){this._clearPressTimer(),this._pressTimer=setTimeout(()=>{this._isSelectingState=!0,this._dispatch(`intlayer:press`)},this.pressDuration)}_handleMouseEnter(){this._isHovered=!0,this._dispatch(`intlayer:hover`)}_handleMouseUpOrLeave(){this._isHovered&&(this._isHovered=!1,this._dispatch(`intlayer:unhover`)),this._clearPressTimer()}_handleClick(e){(this.isSelecting||this._isSelectingState)&&(e.preventDefault(),e.stopPropagation())}_handleBlur(){this._isSelectingState=!1}render(){return n`
22
+ <span
23
+ class="wrapper"
24
+ ?data-active=${this.isSelecting||this._isSelectingState||this._isHovered}
25
+ role="button"
26
+ tabindex="0"
27
+ @mousedown=${this._handleMouseDown}
28
+ @mouseup=${this._handleMouseUpOrLeave}
29
+ @mouseleave=${this._handleMouseUpOrLeave}
30
+ @mouseenter=${this._handleMouseEnter}
31
+ @click=${this._handleClick}
32
+ @touchstart=${this._handleMouseDown}
33
+ @touchend=${this._handleMouseUpOrLeave}
34
+ @touchcancel=${this._handleMouseUpOrLeave}
35
+ @blur=${this._handleBlur}
36
+ @keyup=${()=>{}}
37
+ >
38
+ <slot></slot>
39
+ </span>
40
+ `}};o([r({type:Boolean,attribute:`is-selecting`})],s.prototype,`isSelecting`,void 0),o([r({type:Number,attribute:`press-duration`})],s.prototype,`pressDuration`,void 0),o([a()],s.prototype,`_isHovered`,void 0),o([a()],s.prototype,`_isSelectingState`,void 0),o([i(`.wrapper`)],s.prototype,`_wrapper`,void 0);const c=()=>{typeof customElements>`u`||customElements.get(`intlayer-content-selector`)||customElements.define(`intlayer-content-selector`,s)};export{c as n,s as t};
41
+ //# sourceMappingURL=ContentSelector-QN8BYkA9.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContentSelector-QN8BYkA9.mjs","names":[],"sources":["../../src/components/ContentSelector.ts"],"sourcesContent":["import { css, html, LitElement } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\n\nconst DEFAULT_PRESS_DURATION = 250;\n\n/**\n * <intlayer-content-selector>\n *\n * A framework-agnostic web component that wraps content with Intlayer editor\n * selection UI (hover outline, long-press to select, click-outside to deselect).\n *\n * Replaces the per-framework ContentSelector components (React, Svelte, Vue, Solid).\n *\n * @fires intlayer:press - Fired after a long press (pressDuration ms). Bubbles.\n * @fires intlayer:hover - Fired on mouseenter. Bubbles.\n * @fires intlayer:unhover - Fired on mouseleave / mouseup. Bubbles.\n * @fires intlayer:click-outside - Fired when a click occurs outside the element. Bubbles.\n *\n * @prop {boolean} isSelecting - Whether this element is currently selected (external state)\n * @prop {number} pressDuration - Long-press threshold in ms. Default: 250\n */\nexport class IntlayerContentSelectorElement extends LitElement {\n static styles = css`\n :host {\n display: contents;\n }\n\n .wrapper {\n display: inline-block;\n cursor: pointer;\n user-select: none;\n border-radius: 0.375rem;\n outline-width: 2px;\n outline-offset: 4px;\n outline-style: solid;\n outline-color: transparent;\n transition: all 100ms 50ms ease-in-out;\n }\n\n .wrapper[data-active] {\n outline-color: inherit;\n }\n `;\n\n @property({ type: Boolean, attribute: 'is-selecting' })\n isSelecting = false;\n\n @property({ type: Number, attribute: 'press-duration' })\n pressDuration = DEFAULT_PRESS_DURATION;\n\n @state() private _isHovered = false;\n @state() private _isSelectingState = false;\n\n @query('.wrapper') private _wrapper!: HTMLSpanElement;\n\n private _pressTimer: ReturnType<typeof setTimeout> | null = null;\n private _clickOutsideHandler: ((e: MouseEvent) => void) | null = null;\n\n connectedCallback(): void {\n super.connectedCallback();\n this._clickOutsideHandler = (e: MouseEvent) => {\n // composedPath() pierces shadow boundaries\n if (!e.composedPath().includes(this)) {\n this._isSelectingState = false;\n this._dispatch('intlayer:click-outside');\n }\n };\n document.addEventListener('mousedown', this._clickOutsideHandler);\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n if (this._clickOutsideHandler) {\n document.removeEventListener('mousedown', this._clickOutsideHandler);\n this._clickOutsideHandler = null;\n }\n this._clearPressTimer();\n }\n\n private _clearPressTimer(): void {\n if (this._pressTimer !== null) {\n clearTimeout(this._pressTimer);\n this._pressTimer = null;\n }\n }\n\n private _dispatch(eventName: string): void {\n this.dispatchEvent(\n new CustomEvent(eventName, { bubbles: true, composed: true })\n );\n }\n\n private _handleMouseDown(): void {\n this._clearPressTimer();\n this._pressTimer = setTimeout(() => {\n this._isSelectingState = true;\n this._dispatch('intlayer:press');\n }, this.pressDuration);\n }\n\n private _handleMouseEnter(): void {\n this._isHovered = true;\n this._dispatch('intlayer:hover');\n }\n\n private _handleMouseUpOrLeave(): void {\n if (this._isHovered) {\n this._isHovered = false;\n this._dispatch('intlayer:unhover');\n }\n this._clearPressTimer();\n }\n\n private _handleClick(e: MouseEvent): void {\n if (this.isSelecting || this._isSelectingState) {\n e.preventDefault();\n e.stopPropagation();\n }\n }\n\n private _handleBlur(): void {\n this._isSelectingState = false;\n }\n\n render() {\n const isActive =\n this.isSelecting || this._isSelectingState || this._isHovered;\n return html`\n <span\n class=\"wrapper\"\n ?data-active=${isActive}\n role=\"button\"\n tabindex=\"0\"\n @mousedown=${this._handleMouseDown}\n @mouseup=${this._handleMouseUpOrLeave}\n @mouseleave=${this._handleMouseUpOrLeave}\n @mouseenter=${this._handleMouseEnter}\n @click=${this._handleClick}\n @touchstart=${this._handleMouseDown}\n @touchend=${this._handleMouseUpOrLeave}\n @touchcancel=${this._handleMouseUpOrLeave}\n @blur=${this._handleBlur}\n @keyup=${() => {}}\n >\n <slot></slot>\n </span>\n `;\n }\n}\n\n/**\n * Register the <intlayer-content-selector> custom element.\n * Call this once at application startup (inside IntlayerEditorProvider or similar).\n * Safe to call multiple times — only registers if not already defined.\n */\nexport const defineIntlayerElements = (): void => {\n if (typeof customElements === 'undefined') return;\n if (!customElements.get('intlayer-content-selector')) {\n customElements.define(\n 'intlayer-content-selector',\n IntlayerContentSelectorElement\n );\n }\n};\n"],"mappings":"4bAqBA,IAAa,EAAb,cAAoD,CAAW,gDAwB/C,sBAGE,oBAEc,0BACO,oBAIuB,+BACK,wBAlCjD,CAAG;;;;;;;;;;;;;;;;;;;;IAoCnB,mBAA0B,CACxB,MAAM,mBAAmB,CACzB,KAAK,qBAAwB,GAAkB,CAExC,EAAE,cAAc,CAAC,SAAS,KAAK,GAClC,KAAK,kBAAoB,GACzB,KAAK,UAAU,yBAAyB,GAG5C,SAAS,iBAAiB,YAAa,KAAK,qBAAqB,CAGnE,sBAA6B,CAC3B,MAAM,sBAAsB,CAC5B,AAEE,KAAK,wBADL,SAAS,oBAAoB,YAAa,KAAK,qBAAqB,CACxC,MAE9B,KAAK,kBAAkB,CAGzB,kBAAiC,CAC3B,KAAK,cAAgB,OACvB,aAAa,KAAK,YAAY,CAC9B,KAAK,YAAc,MAIvB,UAAkB,EAAyB,CACzC,KAAK,cACH,IAAI,YAAY,EAAW,CAAE,QAAS,GAAM,SAAU,GAAM,CAAC,CAC9D,CAGH,kBAAiC,CAC/B,KAAK,kBAAkB,CACvB,KAAK,YAAc,eAAiB,CAClC,KAAK,kBAAoB,GACzB,KAAK,UAAU,iBAAiB,EAC/B,KAAK,cAAc,CAGxB,mBAAkC,CAChC,KAAK,WAAa,GAClB,KAAK,UAAU,iBAAiB,CAGlC,uBAAsC,CAChC,KAAK,aACP,KAAK,WAAa,GAClB,KAAK,UAAU,mBAAmB,EAEpC,KAAK,kBAAkB,CAGzB,aAAqB,EAAqB,EACpC,KAAK,aAAe,KAAK,qBAC3B,EAAE,gBAAgB,CAClB,EAAE,iBAAiB,EAIvB,aAA4B,CAC1B,KAAK,kBAAoB,GAG3B,QAAS,CAGP,MAAO,EAAI;;;uBADT,KAAK,aAAe,KAAK,mBAAqB,KAAK,WAIzB;;;qBAGX,KAAK,iBAAiB;mBACxB,KAAK,sBAAsB;sBACxB,KAAK,sBAAsB;sBAC3B,KAAK,kBAAkB;iBAC5B,KAAK,aAAa;sBACb,KAAK,iBAAiB;oBACxB,KAAK,sBAAsB;uBACxB,KAAK,sBAAsB;gBAClC,KAAK,YAAY;qBACV,GAAG;;;;WAlGvB,EAAS,CAAE,KAAM,QAAS,UAAW,eAAgB,CAAC,CAAA,CAAA,EAAA,UAAA,cAAA,IAAA,GAAA,IAGtD,EAAS,CAAE,KAAM,OAAQ,UAAW,iBAAkB,CAAC,CAAA,CAAA,EAAA,UAAA,gBAAA,IAAA,GAAA,IAGvD,GAAO,CAAA,CAAA,EAAA,UAAA,aAAA,IAAA,GAAA,IACP,GAAO,CAAA,CAAA,EAAA,UAAA,oBAAA,IAAA,GAAA,IAEP,EAAM,WAAW,CAAA,CAAA,EAAA,UAAA,WAAA,IAAA,GAAA,CAsGpB,MAAa,MAAqC,CAC5C,OAAO,eAAmB,KACzB,eAAe,IAAI,4BAA4B,EAClD,eAAe,OACb,4BACA,EACD"}
@@ -0,0 +1 @@
1
+ import{n as e,t}from"../ContentSelector-QN8BYkA9.mjs";export{t as IntlayerContentSelectorElement,e as defineIntlayerElements};
@@ -0,0 +1 @@
1
+ import{n as e,t}from"../ContentSelector-QN8BYkA9.mjs";export{t as IntlayerContentSelectorElement,e as defineIntlayerElements};
@@ -0,0 +1,2 @@
1
+ import{compareUrls as e}from"../compareUrls.mjs";const t=()=>Math.random().toString(36).slice(2);var n=class{constructor(e){this._subscribers=new Map,this._windowHandler=null,this._config=e,this.senderId=t()}start(){typeof window>`u`||this._windowHandler||(this._windowHandler=e=>{this._handleMessage(e)},window.addEventListener(`message`,this._windowHandler))}stop(){this._windowHandler&&=(window.removeEventListener(`message`,this._windowHandler),null)}send(e,t){let n={type:e,data:t,senderId:this.senderId};for(let e of this._config.allowedOrigins)e&&this._config.postMessageFn(n,e)}subscribe(e,t){return this._subscribers.has(e)||this._subscribers.set(e,new Set),this._subscribers.get(e).add(t),()=>{this._subscribers.get(e)?.delete(t)}}_handleMessage(t){let n=t.data;if(!n||typeof n!=`object`)return;let{type:r,data:i,senderId:a}=n;if(!r||typeof r!=`string`||a===this.senderId)return;let{allowedOrigins:o}=this._config;if(!(!o||o.length===0||o.includes(`*`)||o.filter(e=>!!e&&e!==``).some(n=>e(n,t.origin))))return;let s=this._subscribers.get(r);if(s)for(let e of s)e(i,a)}};export{n as CrossFrameMessenger};
2
+ //# sourceMappingURL=CrossFrameMessenger.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CrossFrameMessenger.mjs","names":[],"sources":["../../../src/core/CrossFrameMessenger.ts"],"sourcesContent":["import { compareUrls } from '../compareUrls';\n\nconst randomUUID = (): string => Math.random().toString(36).slice(2);\n\nexport type MessagePayload = {\n type: string;\n data?: unknown;\n senderId?: string;\n};\n\nexport type MessengerConfig = {\n /**\n * Origins allowed to send messages to this instance.\n * Use '*' to allow all origins (not recommended for production).\n */\n allowedOrigins: string[];\n /**\n * Function used to send messages to other frames.\n * Injected so the messenger is agnostic to the frame topology.\n */\n postMessageFn: (payload: MessagePayload, origin: string) => void;\n};\n\ntype MessageHandler<T = unknown> = (data: T, senderId?: string) => void;\n\n/**\n * CrossFrameMessenger manages all cross-frame postMessage communication.\n * It owns a single window message listener and routes incoming messages to\n * type-specific subscribers.\n *\n * Replaces CommunicatorContext + useCrossFrameMessageListener across all frameworks.\n */\nexport class CrossFrameMessenger {\n readonly senderId: string;\n private readonly _config: MessengerConfig;\n private readonly _subscribers = new Map<string, Set<MessageHandler>>();\n private _windowHandler: ((event: MessageEvent) => void) | null = null;\n\n constructor(config: MessengerConfig) {\n this._config = config;\n this.senderId = randomUUID();\n }\n\n /** Start listening for incoming messages on window. */\n start(): void {\n if (typeof window === 'undefined') return;\n if (this._windowHandler) return;\n this._windowHandler = (event: MessageEvent<MessagePayload>) => {\n this._handleMessage(event);\n };\n window.addEventListener('message', this._windowHandler);\n }\n\n /** Stop listening and clean up. */\n stop(): void {\n if (this._windowHandler) {\n window.removeEventListener('message', this._windowHandler);\n this._windowHandler = null;\n }\n }\n\n /** Send a message payload to all configured target origins. */\n send(type: string, data?: unknown): void {\n const payload: MessagePayload = { type, data, senderId: this.senderId };\n for (const origin of this._config.allowedOrigins) {\n if (origin) {\n this._config.postMessageFn(payload, origin);\n }\n }\n }\n\n /**\n * Subscribe to messages of a given type.\n * Returns an unsubscribe function.\n */\n subscribe<T = unknown>(type: string, handler: MessageHandler<T>): () => void {\n if (!this._subscribers.has(type)) {\n this._subscribers.set(type, new Set());\n }\n this._subscribers.get(type)!.add(handler as MessageHandler);\n return () => {\n this._subscribers.get(type)?.delete(handler as MessageHandler);\n };\n }\n\n private _handleMessage(event: MessageEvent<MessagePayload>): void {\n const payload = event.data;\n if (!payload || typeof payload !== 'object') return;\n\n const { type, data, senderId: msgSenderId } = payload;\n if (!type || typeof type !== 'string') return;\n\n // Ignore messages originating from this instance\n if (msgSenderId === this.senderId) return;\n\n // Validate message origin\n const { allowedOrigins } = this._config;\n const isAllowed =\n !allowedOrigins ||\n allowedOrigins.length === 0 ||\n allowedOrigins.includes('*') ||\n allowedOrigins\n .filter((url) => Boolean(url) && url !== '')\n .some((url) => compareUrls(url, event.origin));\n\n if (!isAllowed) return;\n\n const handlers = this._subscribers.get(type);\n if (handlers) {\n for (const handler of handlers) {\n handler(data, msgSenderId);\n }\n }\n }\n}\n"],"mappings":"iDAEA,MAAM,MAA2B,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAE,CA8BpE,IAAa,EAAb,KAAiC,CAM/B,YAAY,EAAyB,mBAHL,IAAI,wBAC6B,KAG/D,KAAK,QAAU,EACf,KAAK,SAAW,GAAY,CAI9B,OAAc,CACR,OAAO,OAAW,KAClB,KAAK,iBACT,KAAK,eAAkB,GAAwC,CAC7D,KAAK,eAAe,EAAM,EAE5B,OAAO,iBAAiB,UAAW,KAAK,eAAe,EAIzD,MAAa,CACX,AAEE,KAAK,kBADL,OAAO,oBAAoB,UAAW,KAAK,eAAe,CACpC,MAK1B,KAAK,EAAc,EAAsB,CACvC,IAAM,EAA0B,CAAE,OAAM,OAAM,SAAU,KAAK,SAAU,CACvE,IAAK,IAAM,KAAU,KAAK,QAAQ,eAC5B,GACF,KAAK,QAAQ,cAAc,EAAS,EAAO,CASjD,UAAuB,EAAc,EAAwC,CAK3E,OAJK,KAAK,aAAa,IAAI,EAAK,EAC9B,KAAK,aAAa,IAAI,EAAM,IAAI,IAAM,CAExC,KAAK,aAAa,IAAI,EAAK,CAAE,IAAI,EAA0B,KAC9C,CACX,KAAK,aAAa,IAAI,EAAK,EAAE,OAAO,EAA0B,EAIlE,eAAuB,EAA2C,CAChE,IAAM,EAAU,EAAM,KACtB,GAAI,CAAC,GAAW,OAAO,GAAY,SAAU,OAE7C,GAAM,CAAE,OAAM,OAAM,SAAU,GAAgB,EAI9C,GAHI,CAAC,GAAQ,OAAO,GAAS,UAGzB,IAAgB,KAAK,SAAU,OAGnC,GAAM,CAAE,kBAAmB,KAAK,QAShC,GAAI,EAPF,CAAC,GACD,EAAe,SAAW,GAC1B,EAAe,SAAS,IAAI,EAC5B,EACG,OAAQ,GAAQ,EAAQ,GAAQ,IAAQ,GAAG,CAC3C,KAAM,GAAQ,EAAY,EAAK,EAAM,OAAO,CAAC,EAElC,OAEhB,IAAM,EAAW,KAAK,aAAa,IAAI,EAAK,CAC5C,GAAI,EACF,IAAK,IAAM,KAAW,EACpB,EAAQ,EAAM,EAAY"}
@@ -0,0 +1,2 @@
1
+ var e=class extends EventTarget{constructor(e,t,n={}){super(),this._unsubscribers=[],this._key=e,this._messenger=t,this._options={emit:n.emit??!0,receive:n.receive??!0},n.initialValue!==void 0&&(this._value=n.initialValue)}get value(){return this._value}set(e){this._value=e,this.dispatchEvent(new CustomEvent(`change`,{detail:e})),this._options.emit&&this._messenger.send(`${this._key}/post`,e)}start(){if(this._options.receive){let e=this._messenger.subscribe(`${this._key}/post`,e=>{this._value=e,this.dispatchEvent(new CustomEvent(`change`,{detail:e}))});this._unsubscribers.push(e)}if(this._options.emit){let e=this._messenger.subscribe(`${this._key}/get`,(e,t)=>{t!==this._messenger.senderId&&this._value!==void 0&&this._messenger.send(`${this._key}/post`,this._value)});this._unsubscribers.push(e)}this._options.receive&&this._value===void 0&&this._messenger.send(`${this._key}/get`)}stop(){for(let e of this._unsubscribers)e();this._unsubscribers.length=0}postCurrentValue(){this._value!==void 0&&this._messenger.send(`${this._key}/post`,this._value)}};export{e as CrossFrameStateManager};
2
+ //# sourceMappingURL=CrossFrameStateManager.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CrossFrameStateManager.mjs","names":[],"sources":["../../../src/core/CrossFrameStateManager.ts"],"sourcesContent":["import type { CrossFrameMessenger } from './CrossFrameMessenger';\n\nexport type CrossFrameStateOptions = {\n /** Whether to broadcast state changes to other frames. Default: true */\n emit?: boolean;\n /** Whether to listen for state updates from other frames. Default: true */\n receive?: boolean;\n};\n\n/**\n * CrossFrameStateManager synchronizes a single named value across frames using\n * the postMessage API via CrossFrameMessenger.\n *\n * Protocol:\n * `{key}/post` — broadcast a new value\n * `{key}/get` — request the current value from other frames\n *\n * Replaces useCrossFrameState across all frameworks.\n *\n * @fires change — CustomEvent<T> dispatched whenever the value changes (local set or received)\n */\nexport class CrossFrameStateManager<T> extends EventTarget {\n private _value: T | undefined;\n private readonly _key: string;\n private readonly _messenger: CrossFrameMessenger;\n private readonly _options: Required<CrossFrameStateOptions>;\n private readonly _unsubscribers: Array<() => void> = [];\n\n constructor(\n key: string,\n messenger: CrossFrameMessenger,\n options: CrossFrameStateOptions & { initialValue?: T } = {}\n ) {\n super();\n this._key = key;\n this._messenger = messenger;\n this._options = {\n emit: options.emit ?? true,\n receive: options.receive ?? true,\n };\n if (options.initialValue !== undefined) {\n this._value = options.initialValue;\n }\n }\n\n get value(): T | undefined {\n return this._value;\n }\n\n /** Update the value locally and broadcast it to other frames if emit is enabled. */\n set(newValue: T): void {\n this._value = newValue;\n this.dispatchEvent(new CustomEvent<T>('change', { detail: newValue }));\n if (this._options.emit) {\n this._messenger.send(`${this._key}/post`, newValue);\n }\n }\n\n /**\n * Start listening for incoming state updates and responding to /get requests.\n * If receive=true and no initial value is set, sends a /get to request the current value.\n */\n start(): void {\n if (this._options.receive) {\n const unsub = this._messenger.subscribe<T>(\n `${this._key}/post`,\n (data) => {\n this._value = data;\n this.dispatchEvent(new CustomEvent<T>('change', { detail: data }));\n }\n );\n this._unsubscribers.push(unsub);\n }\n\n if (this._options.emit) {\n // Respond to /get requests by broadcasting current value\n const unsub = this._messenger.subscribe(\n `${this._key}/get`,\n (_, originSenderId) => {\n if (originSenderId === this._messenger.senderId) return;\n if (this._value === undefined) return;\n this._messenger.send(`${this._key}/post`, this._value);\n }\n );\n this._unsubscribers.push(unsub);\n }\n\n // If receiving and no initial value, request it from other frames\n if (this._options.receive && this._value === undefined) {\n this._messenger.send(`${this._key}/get`);\n }\n }\n\n /** Stop all listeners. */\n stop(): void {\n for (const unsub of this._unsubscribers) unsub();\n this._unsubscribers.length = 0;\n }\n\n /** Broadcast the current value to all frames (useful after reconnect). */\n postCurrentValue(): void {\n if (this._value !== undefined) {\n this._messenger.send(`${this._key}/post`, this._value);\n }\n }\n}\n"],"mappings":"AAqBA,IAAa,EAAb,cAA+C,WAAY,CAOzD,YACE,EACA,EACA,EAAyD,EAAE,CAC3D,CACA,OAAO,qBAP4C,EAAE,CAQrD,KAAK,KAAO,EACZ,KAAK,WAAa,EAClB,KAAK,SAAW,CACd,KAAM,EAAQ,MAAQ,GACtB,QAAS,EAAQ,SAAW,GAC7B,CACG,EAAQ,eAAiB,IAAA,KAC3B,KAAK,OAAS,EAAQ,cAI1B,IAAI,OAAuB,CACzB,OAAO,KAAK,OAId,IAAI,EAAmB,CACrB,KAAK,OAAS,EACd,KAAK,cAAc,IAAI,YAAe,SAAU,CAAE,OAAQ,EAAU,CAAC,CAAC,CAClE,KAAK,SAAS,MAChB,KAAK,WAAW,KAAK,GAAG,KAAK,KAAK,OAAQ,EAAS,CAQvD,OAAc,CACZ,GAAI,KAAK,SAAS,QAAS,CACzB,IAAM,EAAQ,KAAK,WAAW,UAC5B,GAAG,KAAK,KAAK,OACZ,GAAS,CACR,KAAK,OAAS,EACd,KAAK,cAAc,IAAI,YAAe,SAAU,CAAE,OAAQ,EAAM,CAAC,CAAC,EAErE,CACD,KAAK,eAAe,KAAK,EAAM,CAGjC,GAAI,KAAK,SAAS,KAAM,CAEtB,IAAM,EAAQ,KAAK,WAAW,UAC5B,GAAG,KAAK,KAAK,OACZ,EAAG,IAAmB,CACjB,IAAmB,KAAK,WAAW,UACnC,KAAK,SAAW,IAAA,IACpB,KAAK,WAAW,KAAK,GAAG,KAAK,KAAK,OAAQ,KAAK,OAAO,EAEzD,CACD,KAAK,eAAe,KAAK,EAAM,CAI7B,KAAK,SAAS,SAAW,KAAK,SAAW,IAAA,IAC3C,KAAK,WAAW,KAAK,GAAG,KAAK,KAAK,MAAM,CAK5C,MAAa,CACX,IAAK,IAAM,KAAS,KAAK,eAAgB,GAAO,CAChD,KAAK,eAAe,OAAS,EAI/B,kBAAyB,CACnB,KAAK,SAAW,IAAA,IAClB,KAAK,WAAW,KAAK,GAAG,KAAK,KAAK,OAAQ,KAAK,OAAO"}
@@ -0,0 +1,2 @@
1
+ import{CrossFrameMessenger as e}from"./CrossFrameMessenger.mjs";import{CrossFrameStateManager as t}from"./CrossFrameStateManager.mjs";import{MessageKey as n}from"../messagesKeys.mjs";import{IframeClickInterceptor as r}from"./IframeClickInterceptor.mjs";import{UrlStateManager as i}from"./UrlStateManager.mjs";import{editDictionaryByKeyPath as a,getContentNodeByKeyPath as o,renameContentNodeByKeyPath as s}from"@intlayer/core/dictionaryManipulator";import{NodeType as c}from"@intlayer/types/nodeType";var l=class{constructor(a){this._mode=a.mode,this.messenger=new e(a.messenger),this.editorEnabled=new t(n.INTLAYER_EDITOR_ENABLED,this.messenger,{emit:!1,receive:!0,initialValue:!1}),this.focusedContent=new t(n.INTLAYER_FOCUSED_CONTENT_CHANGED,this.messenger,{emit:!0,receive:!0,initialValue:null}),this.localeDictionaries=new t(n.INTLAYER_LOCALE_DICTIONARIES_CHANGED,this.messenger),this.editedContent=new t(n.INTLAYER_EDITED_CONTENT_CHANGED,this.messenger),this.configuration=new t(n.INTLAYER_CONFIGURATION,this.messenger,{emit:!0,receive:!1,...a.configuration?{initialValue:a.configuration}:{}}),this.currentLocale=new t(n.INTLAYER_CURRENT_LOCALE,this.messenger,{emit:!1,receive:!0}),this._urlManager=new i(this.messenger),this._iframeInterceptor=new r(this.messenger)}start(){this.messenger.start(),this.editorEnabled.start(),this.focusedContent.start(),this.localeDictionaries.start(),this.editedContent.start(),this.configuration.start(),this.currentLocale.start(),this._mode===`client`?(this._urlManager.start(),this._iframeInterceptor.startInterceptor(),this._loadDictionaries(),this.messenger.send(`${n.INTLAYER_EDITED_CONTENT_CHANGED}/get`)):this._iframeInterceptor.startMerger()}stop(){this.messenger.stop(),this.editorEnabled.stop(),this.focusedContent.stop(),this.localeDictionaries.stop(),this.editedContent.stop(),this.configuration.stop(),this.currentLocale.stop(),this._urlManager.stop(),this._iframeInterceptor.stopInterceptor(),this._iframeInterceptor.stopMerger()}setFocusedContentKeyPath(e){let t=e.filter(e=>e.type!==c.Translation),n=this.focusedContent.value;n&&this.focusedContent.set({...n,keyPath:t})}setLocaleDictionary(e){if(!e.localId)return;let t=this.localeDictionaries.value??{};this.localeDictionaries.set({...t,[e.localId]:e})}setEditedDictionary(e){if(!e.localId){console.error(`setEditedDictionary: missing localId`,e);return}let t=this.editedContent.value??{};this.editedContent.set({...t,[e.localId]:e})}setEditedContent(e,t){let n=this.editedContent.value??{};this.editedContent.set({...n,[e]:{...n[e],content:t}})}addContent(e,t,n=[],r=!0){let i=this.editedContent.value??{},s=(this.localeDictionaries.value??{})[e]?.content,c=structuredClone(i[e]?.content??s),l=n;if(!r){let e=0,t=n.slice(0,-1),r=n[n.length-1],i=r.key;for(;o(c,l)!==void 0;)e++,i=e===0?r.key:`${r.key} (${e})`,l=[...t,{...r,key:i}]}let u=a(c,l,t);this.editedContent.set({...i,[e]:{...i[e],content:u}})}renameContent(e,t,n=[]){let r=this.editedContent.value??{},i=(this.localeDictionaries.value??{})[e]?.content,a=s(structuredClone(r[e]?.content??i),t,n);this.editedContent.set({...r,[e]:{...r[e],content:a}})}removeContent(e,t){let n=this.editedContent.value??{},r=(this.localeDictionaries.value??{})[e]?.content,i=a(structuredClone(n[e]?.content??r),t,o(r,t));this.editedContent.set({...n,[e]:{...n[e],content:i}})}restoreContent(e){let t={...this.editedContent.value??{}};delete t[e],this.editedContent.set(t)}clearContent(e){let t={...this.editedContent.value??{}};delete t[e],this.editedContent.set(t)}clearAllContent(){this.editedContent.set({})}getContentValue(e,t){let n=this.editedContent.value;if(!n)return;let r=t.filter(e=>e.type!==c.Translation);if(e.includes(`:local:`)||e.includes(`:remote:`))return o(n[e]?.content??{},r,this.currentLocale.value);let i=Object.keys(n).filter(t=>t.startsWith(`${e}:`));for(let e of i){let t=o(n[e]?.content??{},r,this.currentLocale.value);if(t)return t}}async _loadDictionaries(){try{let e=(await import(`@intlayer/unmerged-dictionaries-entry`)).getUnmergedDictionaries(),t=Object.fromEntries(Object.values(e).flat().map(e=>[e.localId,e]));this.localeDictionaries.set(t)}catch{}}};export{l as EditorStateManager};
2
+ //# sourceMappingURL=EditorStateManager.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EditorStateManager.mjs","names":[],"sources":["../../../src/core/EditorStateManager.ts"],"sourcesContent":["import {\n editDictionaryByKeyPath,\n getContentNodeByKeyPath,\n renameContentNodeByKeyPath,\n} from '@intlayer/core/dictionaryManipulator';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type {\n ContentNode,\n Dictionary,\n LocalDictionaryId,\n} from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport { NodeType } from '@intlayer/types/nodeType';\nimport { MessageKey } from '../messagesKeys';\nimport {\n CrossFrameMessenger,\n type MessengerConfig,\n} from './CrossFrameMessenger';\nimport { CrossFrameStateManager } from './CrossFrameStateManager';\nimport { IframeClickInterceptor } from './IframeClickInterceptor';\nimport { UrlStateManager } from './UrlStateManager';\n\nexport type DictionaryContent = Record<LocalDictionaryId, Dictionary>;\n\nexport type FileContent = {\n dictionaryKey: string;\n dictionaryLocalId?: LocalDictionaryId;\n keyPath?: KeyPath[];\n};\n\nexport type EditorStateManagerConfig = {\n /** 'client' = the app running inside the iframe; 'editor' = the editor wrapping the app */\n mode: 'editor' | 'client';\n /** Cross-frame messaging configuration */\n messenger: MessengerConfig;\n /** Optional initial Intlayer configuration to broadcast */\n configuration?: IntlayerConfig;\n};\n\n/**\n * EditorStateManager is the single entry point for all Intlayer editor state.\n * It is framework-agnostic: instantiate one instance at the root of the application\n * and subscribe to its EventTarget-based events from any framework adapter.\n *\n * Replaces all context providers, hooks and store files across React, Preact,\n * Solid, Svelte, and Vue integrations.\n */\nexport class EditorStateManager {\n readonly messenger: CrossFrameMessenger;\n readonly editorEnabled: CrossFrameStateManager<boolean>;\n readonly focusedContent: CrossFrameStateManager<FileContent | null>;\n readonly localeDictionaries: CrossFrameStateManager<DictionaryContent>;\n readonly editedContent: CrossFrameStateManager<DictionaryContent>;\n readonly configuration: CrossFrameStateManager<IntlayerConfig>;\n readonly currentLocale: CrossFrameStateManager<Locale>;\n\n private readonly _urlManager: UrlStateManager;\n private readonly _iframeInterceptor: IframeClickInterceptor;\n private readonly _mode: 'editor' | 'client';\n\n constructor(config: EditorStateManagerConfig) {\n this._mode = config.mode;\n\n this.messenger = new CrossFrameMessenger(config.messenger);\n\n this.editorEnabled = new CrossFrameStateManager<boolean>(\n MessageKey.INTLAYER_EDITOR_ENABLED,\n this.messenger,\n { emit: false, receive: true, initialValue: false }\n );\n\n this.focusedContent = new CrossFrameStateManager<FileContent | null>(\n MessageKey.INTLAYER_FOCUSED_CONTENT_CHANGED,\n this.messenger,\n { emit: true, receive: true, initialValue: null }\n );\n\n this.localeDictionaries = new CrossFrameStateManager<DictionaryContent>(\n MessageKey.INTLAYER_LOCALE_DICTIONARIES_CHANGED,\n this.messenger\n );\n\n this.editedContent = new CrossFrameStateManager<DictionaryContent>(\n MessageKey.INTLAYER_EDITED_CONTENT_CHANGED,\n this.messenger\n );\n\n this.configuration = new CrossFrameStateManager<IntlayerConfig>(\n MessageKey.INTLAYER_CONFIGURATION,\n this.messenger,\n {\n emit: true,\n receive: false,\n ...(config.configuration ? { initialValue: config.configuration } : {}),\n }\n );\n\n this.currentLocale = new CrossFrameStateManager<Locale>(\n MessageKey.INTLAYER_CURRENT_LOCALE,\n this.messenger,\n { emit: false, receive: true }\n );\n\n this._urlManager = new UrlStateManager(this.messenger);\n this._iframeInterceptor = new IframeClickInterceptor(this.messenger);\n }\n\n start(): void {\n this.messenger.start();\n this.editorEnabled.start();\n this.focusedContent.start();\n this.localeDictionaries.start();\n this.editedContent.start();\n this.configuration.start();\n this.currentLocale.start();\n\n if (this._mode === 'client') {\n this._urlManager.start();\n this._iframeInterceptor.startInterceptor();\n this._loadDictionaries();\n // Request current edited content from the editor\n this.messenger.send(`${MessageKey.INTLAYER_EDITED_CONTENT_CHANGED}/get`);\n } else {\n this._iframeInterceptor.startMerger();\n }\n }\n\n stop(): void {\n this.messenger.stop();\n this.editorEnabled.stop();\n this.focusedContent.stop();\n this.localeDictionaries.stop();\n this.editedContent.stop();\n this.configuration.stop();\n this.currentLocale.stop();\n this._urlManager.stop();\n this._iframeInterceptor.stopInterceptor();\n this._iframeInterceptor.stopMerger();\n }\n\n // ─── Focus helpers ──────────────────────────────────────────────────────────\n\n setFocusedContentKeyPath(keyPath: KeyPath[]): void {\n const filtered = keyPath.filter((key) => key.type !== NodeType.Translation);\n const prev = this.focusedContent.value;\n if (!prev) return;\n this.focusedContent.set({ ...prev, keyPath: filtered });\n }\n\n // ─── Dictionary record helpers ───────────────────────────────────────────\n\n setLocaleDictionary(dictionary: Dictionary): void {\n if (!dictionary.localId) return;\n const current = this.localeDictionaries.value ?? {};\n this.localeDictionaries.set({\n ...current,\n [dictionary.localId as LocalDictionaryId]: dictionary,\n });\n }\n\n // ─── Edited content helpers ───────────────────────────────────────────────\n\n setEditedDictionary(newDict: Dictionary): void {\n if (!newDict.localId) {\n console.error('setEditedDictionary: missing localId', newDict);\n return;\n }\n const current = this.editedContent.value ?? {};\n this.editedContent.set({\n ...current,\n [newDict.localId as LocalDictionaryId]: newDict,\n });\n }\n\n setEditedContent(\n localDictionaryId: LocalDictionaryId,\n newValue: Dictionary['content']\n ): void {\n const current = this.editedContent.value ?? {};\n this.editedContent.set({\n ...current,\n [localDictionaryId]: {\n ...current[localDictionaryId],\n content: newValue,\n },\n });\n }\n\n addContent(\n localDictionaryId: LocalDictionaryId,\n newValue: ContentNode,\n keyPath: KeyPath[] = [],\n overwrite = true\n ): void {\n const current = this.editedContent.value ?? {};\n const localeDicts = this.localeDictionaries.value ?? {};\n const originalContent = localeDicts[localDictionaryId]?.content;\n const currentContent = structuredClone(\n current[localDictionaryId]?.content ?? originalContent\n );\n\n let newKeyPath = keyPath;\n if (!overwrite) {\n let index = 0;\n const otherKeyPath = keyPath.slice(0, -1);\n const lastKeyPath = keyPath[keyPath.length - 1];\n let finalKey = lastKeyPath.key;\n while (\n typeof getContentNodeByKeyPath(currentContent, newKeyPath) !==\n 'undefined'\n ) {\n index++;\n finalKey =\n index === 0 ? lastKeyPath.key : `${lastKeyPath.key} (${index})`;\n newKeyPath = [\n ...otherKeyPath,\n { ...lastKeyPath, key: finalKey } as KeyPath,\n ];\n }\n }\n\n const updatedContent = editDictionaryByKeyPath(\n currentContent,\n newKeyPath,\n newValue\n );\n this.editedContent.set({\n ...current,\n [localDictionaryId]: {\n ...current[localDictionaryId],\n content: updatedContent as Dictionary['content'],\n },\n });\n }\n\n renameContent(\n localDictionaryId: LocalDictionaryId,\n newKey: KeyPath['key'],\n keyPath: KeyPath[] = []\n ): void {\n const current = this.editedContent.value ?? {};\n const localeDicts = this.localeDictionaries.value ?? {};\n const originalContent = localeDicts[localDictionaryId]?.content;\n const currentContent = structuredClone(\n current[localDictionaryId]?.content ?? originalContent\n );\n const updated = renameContentNodeByKeyPath(currentContent, newKey, keyPath);\n this.editedContent.set({\n ...current,\n [localDictionaryId]: {\n ...current[localDictionaryId],\n content: updated as Dictionary['content'],\n },\n });\n }\n\n removeContent(\n localDictionaryId: LocalDictionaryId,\n keyPath: KeyPath[]\n ): void {\n const current = this.editedContent.value ?? {};\n const localeDicts = this.localeDictionaries.value ?? {};\n const originalContent = localeDicts[localDictionaryId]?.content;\n const currentContent = structuredClone(\n current[localDictionaryId]?.content ?? originalContent\n );\n const initialContent = getContentNodeByKeyPath(originalContent, keyPath);\n const restored = editDictionaryByKeyPath(\n currentContent,\n keyPath,\n initialContent\n );\n this.editedContent.set({\n ...current,\n [localDictionaryId]: {\n ...current[localDictionaryId],\n content: restored as Dictionary['content'],\n },\n });\n }\n\n restoreContent(localDictionaryId: LocalDictionaryId): void {\n const current = this.editedContent.value ?? {};\n const updated = { ...current };\n delete updated[localDictionaryId];\n this.editedContent.set(updated);\n }\n\n clearContent(localDictionaryId: LocalDictionaryId): void {\n const current = this.editedContent.value ?? {};\n const filtered = { ...current };\n delete filtered[localDictionaryId];\n this.editedContent.set(filtered);\n }\n\n clearAllContent(): void {\n this.editedContent.set({});\n }\n\n getContentValue(\n localDictionaryIdOrKey: LocalDictionaryId | string,\n keyPath: KeyPath[]\n ): ContentNode | undefined {\n const edited = this.editedContent.value;\n if (!edited) return undefined;\n\n const filteredKeyPath = keyPath.filter(\n (key) => key.type !== NodeType.Translation\n );\n\n const isDictionaryId =\n localDictionaryIdOrKey.includes(':local:') ||\n localDictionaryIdOrKey.includes(':remote:');\n\n if (isDictionaryId) {\n const content =\n edited[localDictionaryIdOrKey as LocalDictionaryId]?.content ?? {};\n return getContentNodeByKeyPath(\n content,\n filteredKeyPath,\n this.currentLocale.value\n );\n }\n\n const matchingIds = Object.keys(edited).filter((key) =>\n key.startsWith(`${localDictionaryIdOrKey}:`)\n );\n for (const localId of matchingIds) {\n const content = edited[localId as LocalDictionaryId]?.content ?? {};\n const node = getContentNodeByKeyPath(\n content,\n filteredKeyPath,\n this.currentLocale.value\n );\n if (node) return node;\n }\n\n return undefined;\n }\n\n private async _loadDictionaries(): Promise<void> {\n try {\n const mod = await import('@intlayer/unmerged-dictionaries-entry');\n const unmergedDictionaries = mod.getUnmergedDictionaries();\n const dictionariesList = Object.fromEntries(\n Object.values(unmergedDictionaries)\n .flat()\n .map((dictionary) => [dictionary.localId, dictionary])\n ) as DictionaryContent;\n this.localeDictionaries.set(dictionariesList);\n } catch {\n // Dynamic entry not available (expected in editor mode or when not configured)\n }\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{mergeIframeClick as e}from"../mergeIframeClick.mjs";import{MessageKey as t}from"../messagesKeys.mjs";var n=class{constructor(e){this._mousedownHandler=null,this._unsubscribeMerge=null,this._messenger=e}startInterceptor(){typeof window>`u`||(this._mousedownHandler=()=>{this._messenger.send(t.INTLAYER_IFRAME_CLICKED)},window.addEventListener(`mousedown`,this._mousedownHandler))}startMerger(){this._unsubscribeMerge=this._messenger.subscribe(t.INTLAYER_IFRAME_CLICKED,e)}stopInterceptor(){this._mousedownHandler&&=(window.removeEventListener(`mousedown`,this._mousedownHandler),null)}stopMerger(){this._unsubscribeMerge?.(),this._unsubscribeMerge=null}};export{n as IframeClickInterceptor};
2
+ //# sourceMappingURL=IframeClickInterceptor.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IframeClickInterceptor.mjs","names":[],"sources":["../../../src/core/IframeClickInterceptor.ts"],"sourcesContent":["import { mergeIframeClick } from '../mergeIframeClick';\nimport { MessageKey } from '../messagesKeys';\nimport type { CrossFrameMessenger } from './CrossFrameMessenger';\n\n/**\n * IframeClickInterceptor handles click events across iframe boundaries.\n *\n * - startInterceptor(): called in the client (iframe) — broadcasts mousedown to parent\n * - startMerger(): called in the editor (parent) — merges received clicks into DOM events\n *\n * Replaces useIframeClickInterceptor / useIframeClickMerger across all frameworks.\n */\nexport class IframeClickInterceptor {\n private readonly _messenger: CrossFrameMessenger;\n private _mousedownHandler: EventListener | null = null;\n private _unsubscribeMerge: (() => void) | null = null;\n\n constructor(messenger: CrossFrameMessenger) {\n this._messenger = messenger;\n }\n\n /** Called on the client side (inside iframe). Broadcasts click events to parent. */\n startInterceptor(): void {\n if (typeof window === 'undefined') return;\n this._mousedownHandler = () => {\n this._messenger.send(MessageKey.INTLAYER_IFRAME_CLICKED);\n };\n window.addEventListener('mousedown', this._mousedownHandler);\n }\n\n /** Called on the editor side (parent frame). Merges incoming iframe clicks into DOM. */\n startMerger(): void {\n this._unsubscribeMerge = this._messenger.subscribe(\n MessageKey.INTLAYER_IFRAME_CLICKED,\n mergeIframeClick as (data: unknown) => void\n );\n }\n\n stopInterceptor(): void {\n if (this._mousedownHandler) {\n window.removeEventListener('mousedown', this._mousedownHandler);\n this._mousedownHandler = null;\n }\n }\n\n stopMerger(): void {\n this._unsubscribeMerge?.();\n this._unsubscribeMerge = null;\n }\n}\n"],"mappings":"4GAYA,IAAa,EAAb,KAAoC,CAKlC,YAAY,EAAgC,wBAHM,4BACD,KAG/C,KAAK,WAAa,EAIpB,kBAAyB,CACnB,OAAO,OAAW,MACtB,KAAK,sBAA0B,CAC7B,KAAK,WAAW,KAAK,EAAW,wBAAwB,EAE1D,OAAO,iBAAiB,YAAa,KAAK,kBAAkB,EAI9D,aAAoB,CAClB,KAAK,kBAAoB,KAAK,WAAW,UACvC,EAAW,wBACX,EACD,CAGH,iBAAwB,CACtB,AAEE,KAAK,qBADL,OAAO,oBAAoB,YAAa,KAAK,kBAAkB,CACtC,MAI7B,YAAmB,CACjB,KAAK,qBAAqB,CAC1B,KAAK,kBAAoB"}
@@ -0,0 +1,2 @@
1
+ import{MessageKey as e}from"../messagesKeys.mjs";var t=class{constructor(e){this._originalPushState=null,this._originalReplaceState=null,this._listeners=[],this._messenger=e}start(){if(typeof window>`u`)return;let t=()=>{this._messenger.send(`${e.INTLAYER_URL_CHANGE}/post`,window.location.pathname)};this._originalPushState=history.pushState,this._originalReplaceState=history.replaceState;let n=e=>function(...t){e.apply(this,t),window.dispatchEvent(new Event(`locationchange`))};history.pushState=n(this._originalPushState),history.replaceState=n(this._originalReplaceState);for(let e of[`locationchange`,`popstate`,`hashchange`,`load`]){let n=t;window.addEventListener(e,n),this._listeners.push([e,n])}t()}stop(){if(!(typeof window>`u`)){for(let[e,t]of this._listeners)window.removeEventListener(e,t);this._listeners=[],this._originalPushState&&=(history.pushState=this._originalPushState,null),this._originalReplaceState&&=(history.replaceState=this._originalReplaceState,null)}}};export{t as UrlStateManager};
2
+ //# sourceMappingURL=UrlStateManager.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UrlStateManager.mjs","names":[],"sources":["../../../src/core/UrlStateManager.ts"],"sourcesContent":["import { MessageKey } from '../messagesKeys';\nimport type { CrossFrameMessenger } from './CrossFrameMessenger';\n\n/**\n * UrlStateManager patches window.history and broadcasts URL path changes\n * across frames via postMessage.\n *\n * Replaces useCrossURLPathSetter / useCrossURLPathState across all frameworks.\n */\nexport class UrlStateManager {\n private readonly _messenger: CrossFrameMessenger;\n private _originalPushState: typeof history.pushState | null = null;\n private _originalReplaceState: typeof history.replaceState | null = null;\n private _listeners: Array<[string, EventListener]> = [];\n\n constructor(messenger: CrossFrameMessenger) {\n this._messenger = messenger;\n }\n\n start(): void {\n if (typeof window === 'undefined') return;\n\n const updateURLState = () => {\n this._messenger.send(\n `${MessageKey.INTLAYER_URL_CHANGE}/post`,\n window.location.pathname\n );\n };\n\n this._originalPushState = history.pushState;\n this._originalReplaceState = history.replaceState;\n\n const injectLocationChange = (method: typeof history.pushState) =>\n function (\n this: typeof history,\n ...args: Parameters<typeof history.pushState>\n ) {\n method.apply(this, args);\n window.dispatchEvent(new Event('locationchange'));\n };\n\n history.pushState = injectLocationChange(\n this._originalPushState\n ) as typeof history.pushState;\n history.replaceState = injectLocationChange(\n this._originalReplaceState\n ) as typeof history.replaceState;\n\n for (const eventName of [\n 'locationchange',\n 'popstate',\n 'hashchange',\n 'load',\n ] as const) {\n const listener = updateURLState as EventListener;\n window.addEventListener(eventName, listener);\n this._listeners.push([eventName, listener]);\n }\n\n updateURLState();\n }\n\n stop(): void {\n if (typeof window === 'undefined') return;\n\n for (const [eventName, listener] of this._listeners) {\n window.removeEventListener(eventName, listener);\n }\n this._listeners = [];\n\n if (this._originalPushState) {\n history.pushState = this._originalPushState;\n this._originalPushState = null;\n }\n if (this._originalReplaceState) {\n history.replaceState = this._originalReplaceState;\n this._originalReplaceState = null;\n }\n }\n}\n"],"mappings":"iDASA,IAAa,EAAb,KAA6B,CAM3B,YAAY,EAAgC,yBAJkB,gCACM,qBACf,EAAE,CAGrD,KAAK,WAAa,EAGpB,OAAc,CACZ,GAAI,OAAO,OAAW,IAAa,OAEnC,IAAM,MAAuB,CAC3B,KAAK,WAAW,KACd,GAAG,EAAW,oBAAoB,OAClC,OAAO,SAAS,SACjB,EAGH,KAAK,mBAAqB,QAAQ,UAClC,KAAK,sBAAwB,QAAQ,aAErC,IAAM,EAAwB,GAC5B,SAEE,GAAG,EACH,CACA,EAAO,MAAM,KAAM,EAAK,CACxB,OAAO,cAAc,IAAI,MAAM,iBAAiB,CAAC,EAGrD,QAAQ,UAAY,EAClB,KAAK,mBACN,CACD,QAAQ,aAAe,EACrB,KAAK,sBACN,CAED,IAAK,IAAM,IAAa,CACtB,iBACA,WACA,aACA,OACD,CAAW,CACV,IAAM,EAAW,EACjB,OAAO,iBAAiB,EAAW,EAAS,CAC5C,KAAK,WAAW,KAAK,CAAC,EAAW,EAAS,CAAC,CAG7C,GAAgB,CAGlB,MAAa,CACP,YAAO,OAAW,KAEtB,KAAK,GAAM,CAAC,EAAW,KAAa,KAAK,WACvC,OAAO,oBAAoB,EAAW,EAAS,CAEjD,KAAK,WAAa,EAAE,CAEpB,AAEE,KAAK,sBADL,QAAQ,UAAY,KAAK,mBACC,MAE5B,AAEE,KAAK,yBADL,QAAQ,aAAe,KAAK,sBACC"}
@@ -0,0 +1 @@
1
+ import{CrossFrameMessenger as e}from"./CrossFrameMessenger.mjs";import{CrossFrameStateManager as t}from"./CrossFrameStateManager.mjs";import{IframeClickInterceptor as n}from"./IframeClickInterceptor.mjs";import{UrlStateManager as r}from"./UrlStateManager.mjs";import{EditorStateManager as i}from"./EditorStateManager.mjs";export{e as CrossFrameMessenger,t as CrossFrameStateManager,i as EditorStateManager,n as IframeClickInterceptor,r as UrlStateManager};
@@ -1 +1 @@
1
- import{compareUrls as e}from"./compareUrls.mjs";import{mergeIframeClick as t}from"./mergeIframeClick.mjs";import{MessageKey as n}from"./messagesKeys.mjs";export{n as MessageKey,e as compareUrls,t as mergeIframeClick};
1
+ import{compareUrls as e}from"./compareUrls.mjs";import{mergeIframeClick as t}from"./mergeIframeClick.mjs";import{n,t as r}from"./ContentSelector-QN8BYkA9.mjs";import"./components/index.mjs";import{CrossFrameMessenger as i}from"./core/CrossFrameMessenger.mjs";import{CrossFrameStateManager as a}from"./core/CrossFrameStateManager.mjs";import{MessageKey as o}from"./messagesKeys.mjs";import{IframeClickInterceptor as s}from"./core/IframeClickInterceptor.mjs";import{UrlStateManager as c}from"./core/UrlStateManager.mjs";import{EditorStateManager as l}from"./core/EditorStateManager.mjs";import"./core/index.mjs";export{i as CrossFrameMessenger,a as CrossFrameStateManager,l as EditorStateManager,s as IframeClickInterceptor,r as IntlayerContentSelectorElement,o as MessageKey,c as UrlStateManager,e as compareUrls,n as defineIntlayerElements,t as mergeIframeClick};
@@ -0,0 +1,49 @@
1
+ import * as lit from "lit";
2
+ import { LitElement } from "lit";
3
+
4
+ //#region src/components/ContentSelector.d.ts
5
+ /**
6
+ * <intlayer-content-selector>
7
+ *
8
+ * A framework-agnostic web component that wraps content with Intlayer editor
9
+ * selection UI (hover outline, long-press to select, click-outside to deselect).
10
+ *
11
+ * Replaces the per-framework ContentSelector components (React, Svelte, Vue, Solid).
12
+ *
13
+ * @fires intlayer:press - Fired after a long press (pressDuration ms). Bubbles.
14
+ * @fires intlayer:hover - Fired on mouseenter. Bubbles.
15
+ * @fires intlayer:unhover - Fired on mouseleave / mouseup. Bubbles.
16
+ * @fires intlayer:click-outside - Fired when a click occurs outside the element. Bubbles.
17
+ *
18
+ * @prop {boolean} isSelecting - Whether this element is currently selected (external state)
19
+ * @prop {number} pressDuration - Long-press threshold in ms. Default: 250
20
+ */
21
+ declare class IntlayerContentSelectorElement extends LitElement {
22
+ static styles: lit.CSSResult;
23
+ isSelecting: boolean;
24
+ pressDuration: number;
25
+ private _isHovered;
26
+ private _isSelectingState;
27
+ private _wrapper;
28
+ private _pressTimer;
29
+ private _clickOutsideHandler;
30
+ connectedCallback(): void;
31
+ disconnectedCallback(): void;
32
+ private _clearPressTimer;
33
+ private _dispatch;
34
+ private _handleMouseDown;
35
+ private _handleMouseEnter;
36
+ private _handleMouseUpOrLeave;
37
+ private _handleClick;
38
+ private _handleBlur;
39
+ render(): lit.TemplateResult<1>;
40
+ }
41
+ /**
42
+ * Register the <intlayer-content-selector> custom element.
43
+ * Call this once at application startup (inside IntlayerEditorProvider or similar).
44
+ * Safe to call multiple times — only registers if not already defined.
45
+ */
46
+ declare const defineIntlayerElements: () => void;
47
+ //#endregion
48
+ export { defineIntlayerElements as n, IntlayerContentSelectorElement as t };
49
+ //# sourceMappingURL=ContentSelector-rBO8c1Kp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContentSelector-rBO8c1Kp.d.ts","names":[],"sources":["../../src/components/ContentSelector.ts"],"mappings":";;;;;;;AAqBA;;;;;;;;;;;;;cAAa,8BAAA,SAAuC,UAAA;EAAA,OAC3C,MAAA,EADmC,GAAA,CAC7B,SAAA;EAuBb,WAAA;EAGA,aAAA;EAAA,QAEiB,UAAA;EAAA,QACA,iBAAA;EAAA,QAEU,QAAA;EAAA,QAEnB,WAAA;EAAA,QACA,oBAAA;EAER,iBAAA,CAAA;EAYA,oBAAA,CAAA;EAAA,QASQ,gBAAA;EAAA,QAOA,SAAA;EAAA,QAMA,gBAAA;EAAA,QAQA,iBAAA;EAAA,QAKA,qBAAA;EAAA,QAQA,YAAA;EAAA,QAOA,WAAA;EAIR,MAAA,CAAA,GAtGa,GAAA,CAsGP,cAAA;AAAA;;;;;;cA+BK,sBAAA"}
@@ -0,0 +1,48 @@
1
+ //#region src/core/CrossFrameMessenger.d.ts
2
+ type MessagePayload = {
3
+ type: string;
4
+ data?: unknown;
5
+ senderId?: string;
6
+ };
7
+ type MessengerConfig = {
8
+ /**
9
+ * Origins allowed to send messages to this instance.
10
+ * Use '*' to allow all origins (not recommended for production).
11
+ */
12
+ allowedOrigins: string[];
13
+ /**
14
+ * Function used to send messages to other frames.
15
+ * Injected so the messenger is agnostic to the frame topology.
16
+ */
17
+ postMessageFn: (payload: MessagePayload, origin: string) => void;
18
+ };
19
+ type MessageHandler<T = unknown> = (data: T, senderId?: string) => void;
20
+ /**
21
+ * CrossFrameMessenger manages all cross-frame postMessage communication.
22
+ * It owns a single window message listener and routes incoming messages to
23
+ * type-specific subscribers.
24
+ *
25
+ * Replaces CommunicatorContext + useCrossFrameMessageListener across all frameworks.
26
+ */
27
+ declare class CrossFrameMessenger {
28
+ readonly senderId: string;
29
+ private readonly _config;
30
+ private readonly _subscribers;
31
+ private _windowHandler;
32
+ constructor(config: MessengerConfig);
33
+ /** Start listening for incoming messages on window. */
34
+ start(): void;
35
+ /** Stop listening and clean up. */
36
+ stop(): void;
37
+ /** Send a message payload to all configured target origins. */
38
+ send(type: string, data?: unknown): void;
39
+ /**
40
+ * Subscribe to messages of a given type.
41
+ * Returns an unsubscribe function.
42
+ */
43
+ subscribe<T = unknown>(type: string, handler: MessageHandler<T>): () => void;
44
+ private _handleMessage;
45
+ }
46
+ //#endregion
47
+ export { MessagePayload as n, MessengerConfig as r, CrossFrameMessenger as t };
48
+ //# sourceMappingURL=CrossFrameMessenger-CAAHntwS.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CrossFrameMessenger-CAAHntwS.d.ts","names":[],"sources":["../../src/core/CrossFrameMessenger.ts"],"mappings":";KAIY,cAAA;EACV,IAAA;EACA,IAAA;EACA,QAAA;AAAA;AAAA,KAGU,eAAA;EAJV;;;;EASA,cAAA;EALyB;;;;EAUzB,aAAA,GAAgB,OAAA,EAAS,cAAA,EAAgB,MAAA;AAAA;AAAA,KAGtC,cAAA,iBAA+B,IAAA,EAAM,CAAA,EAAG,QAAA;;;;AAF3C;;;;cAWW,mBAAA;EAAA,SACF,QAAA;EAAA,iBACQ,OAAA;EAAA,iBACA,YAAA;EAAA,QACT,cAAA;cAEI,MAAA,EAAQ,eAAA;EANT;EAYX,KAAA,CAAA;EAZ8B;EAsB9B,IAAA,CAAA;EAqB6D;EAb7D,IAAA,CAAK,IAAA,UAAc,IAAA;EAayC;;;;EAA5D,SAAA,aAAA,CAAuB,IAAA,UAAc,OAAA,EAAS,cAAA,CAAe,CAAA;EAAA,QAUrD,cAAA;AAAA"}
@@ -0,0 +1,44 @@
1
+ import { t as CrossFrameMessenger } from "./CrossFrameMessenger-CAAHntwS.js";
2
+
3
+ //#region src/core/CrossFrameStateManager.d.ts
4
+ type CrossFrameStateOptions = {
5
+ /** Whether to broadcast state changes to other frames. Default: true */emit?: boolean; /** Whether to listen for state updates from other frames. Default: true */
6
+ receive?: boolean;
7
+ };
8
+ /**
9
+ * CrossFrameStateManager synchronizes a single named value across frames using
10
+ * the postMessage API via CrossFrameMessenger.
11
+ *
12
+ * Protocol:
13
+ * `{key}/post` — broadcast a new value
14
+ * `{key}/get` — request the current value from other frames
15
+ *
16
+ * Replaces useCrossFrameState across all frameworks.
17
+ *
18
+ * @fires change — CustomEvent<T> dispatched whenever the value changes (local set or received)
19
+ */
20
+ declare class CrossFrameStateManager<T> extends EventTarget {
21
+ private _value;
22
+ private readonly _key;
23
+ private readonly _messenger;
24
+ private readonly _options;
25
+ private readonly _unsubscribers;
26
+ constructor(key: string, messenger: CrossFrameMessenger, options?: CrossFrameStateOptions & {
27
+ initialValue?: T;
28
+ });
29
+ get value(): T | undefined;
30
+ /** Update the value locally and broadcast it to other frames if emit is enabled. */
31
+ set(newValue: T): void;
32
+ /**
33
+ * Start listening for incoming state updates and responding to /get requests.
34
+ * If receive=true and no initial value is set, sends a /get to request the current value.
35
+ */
36
+ start(): void;
37
+ /** Stop all listeners. */
38
+ stop(): void;
39
+ /** Broadcast the current value to all frames (useful after reconnect). */
40
+ postCurrentValue(): void;
41
+ }
42
+ //#endregion
43
+ export { CrossFrameStateOptions as n, CrossFrameStateManager as t };
44
+ //# sourceMappingURL=CrossFrameStateManager-DxgxsAmo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CrossFrameStateManager-DxgxsAmo.d.ts","names":[],"sources":["../../src/core/CrossFrameStateManager.ts"],"mappings":";;;KAEY,sBAAA;0EAEV,IAAA,YAFgC;EAIhC,OAAA;AAAA;;AAeF;;;;;;;;;;;cAAa,sBAAA,YAAkC,WAAA;EAAA,QACrC,MAAA;EAAA,iBACS,IAAA;EAAA,iBACA,UAAA;EAAA,iBACA,QAAA;EAAA,iBACA,cAAA;cAGf,GAAA,UACA,SAAA,EAAW,mBAAA,EACX,OAAA,GAAS,sBAAA;IAA2B,YAAA,GAAe,CAAA;EAAA;EAAA,IAcjD,KAAA,CAAA,GAAS,CAAA;EAfX;EAoBF,GAAA,CAAI,QAAA,EAAU,CAAA;EAnBwB;;;;EA+BtC,KAAA,CAAA;EAZA;EA4CA,IAAA,CAAA;EA5CI;EAkDJ,gBAAA,CAAA;AAAA"}
@@ -0,0 +1,57 @@
1
+ import { r as MessengerConfig, t as CrossFrameMessenger } from "./CrossFrameMessenger-CAAHntwS.js";
2
+ import { t as CrossFrameStateManager } from "./CrossFrameStateManager-DxgxsAmo.js";
3
+ import { Locale } from "@intlayer/types/allLocales";
4
+ import { IntlayerConfig } from "@intlayer/types/config";
5
+ import { ContentNode, Dictionary, LocalDictionaryId } from "@intlayer/types/dictionary";
6
+ import { KeyPath } from "@intlayer/types/keyPath";
7
+
8
+ //#region src/core/EditorStateManager.d.ts
9
+ type DictionaryContent = Record<LocalDictionaryId, Dictionary>;
10
+ type FileContent = {
11
+ dictionaryKey: string;
12
+ dictionaryLocalId?: LocalDictionaryId;
13
+ keyPath?: KeyPath[];
14
+ };
15
+ type EditorStateManagerConfig = {
16
+ /** 'client' = the app running inside the iframe; 'editor' = the editor wrapping the app */mode: 'editor' | 'client'; /** Cross-frame messaging configuration */
17
+ messenger: MessengerConfig; /** Optional initial Intlayer configuration to broadcast */
18
+ configuration?: IntlayerConfig;
19
+ };
20
+ /**
21
+ * EditorStateManager is the single entry point for all Intlayer editor state.
22
+ * It is framework-agnostic: instantiate one instance at the root of the application
23
+ * and subscribe to its EventTarget-based events from any framework adapter.
24
+ *
25
+ * Replaces all context providers, hooks and store files across React, Preact,
26
+ * Solid, Svelte, and Vue integrations.
27
+ */
28
+ declare class EditorStateManager {
29
+ readonly messenger: CrossFrameMessenger;
30
+ readonly editorEnabled: CrossFrameStateManager<boolean>;
31
+ readonly focusedContent: CrossFrameStateManager<FileContent | null>;
32
+ readonly localeDictionaries: CrossFrameStateManager<DictionaryContent>;
33
+ readonly editedContent: CrossFrameStateManager<DictionaryContent>;
34
+ readonly configuration: CrossFrameStateManager<IntlayerConfig>;
35
+ readonly currentLocale: CrossFrameStateManager<Locale>;
36
+ private readonly _urlManager;
37
+ private readonly _iframeInterceptor;
38
+ private readonly _mode;
39
+ constructor(config: EditorStateManagerConfig);
40
+ start(): void;
41
+ stop(): void;
42
+ setFocusedContentKeyPath(keyPath: KeyPath[]): void;
43
+ setLocaleDictionary(dictionary: Dictionary): void;
44
+ setEditedDictionary(newDict: Dictionary): void;
45
+ setEditedContent(localDictionaryId: LocalDictionaryId, newValue: Dictionary['content']): void;
46
+ addContent(localDictionaryId: LocalDictionaryId, newValue: ContentNode, keyPath?: KeyPath[], overwrite?: boolean): void;
47
+ renameContent(localDictionaryId: LocalDictionaryId, newKey: KeyPath['key'], keyPath?: KeyPath[]): void;
48
+ removeContent(localDictionaryId: LocalDictionaryId, keyPath: KeyPath[]): void;
49
+ restoreContent(localDictionaryId: LocalDictionaryId): void;
50
+ clearContent(localDictionaryId: LocalDictionaryId): void;
51
+ clearAllContent(): void;
52
+ getContentValue(localDictionaryIdOrKey: LocalDictionaryId | string, keyPath: KeyPath[]): ContentNode | undefined;
53
+ private _loadDictionaries;
54
+ }
55
+ //#endregion
56
+ export { FileContent as i, EditorStateManager as n, EditorStateManagerConfig as r, DictionaryContent as t };
57
+ //# sourceMappingURL=EditorStateManager-Ym8YfMiG.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EditorStateManager-Ym8YfMiG.d.ts","names":[],"sources":["../../src/core/EditorStateManager.ts"],"mappings":";;;;;;;;KAuBY,iBAAA,GAAoB,MAAA,CAAO,iBAAA,EAAmB,UAAA;AAAA,KAE9C,WAAA;EACV,aAAA;EACA,iBAAA,GAAoB,iBAAA;EACpB,OAAA,GAAU,OAAA;AAAA;AAAA,KAGA,wBAAA;EARoB,2FAU9B,IAAA,uBAVoC;EAYpC,SAAA,EAAW,eAAA,EAZ0B;EAcrC,aAAA,GAAgB,cAAA;AAAA;;AAZlB;;;;;;;cAuBa,kBAAA;EAAA,SACF,SAAA,EAAW,mBAAA;EAAA,SACX,aAAA,EAAe,sBAAA;EAAA,SACf,cAAA,EAAgB,sBAAA,CAAuB,WAAA;EAAA,SACvC,kBAAA,EAAoB,sBAAA,CAAuB,iBAAA;EAAA,SAC3C,aAAA,EAAe,sBAAA,CAAuB,iBAAA;EAAA,SACtC,aAAA,EAAe,sBAAA,CAAuB,cAAA;EAAA,SACtC,aAAA,EAAe,sBAAA,CAAuB,MAAA;EAAA,iBAE9B,WAAA;EAAA,iBACA,kBAAA;EAAA,iBACA,KAAA;cAEL,MAAA,EAAQ,wBAAA;EA+CpB,KAAA,CAAA;EAoBA,IAAA,CAAA;EAeA,wBAAA,CAAyB,OAAA,EAAS,OAAA;EASlC,mBAAA,CAAoB,UAAA,EAAY,UAAA;EAWhC,mBAAA,CAAoB,OAAA,EAAS,UAAA;EAY7B,gBAAA,CACE,iBAAA,EAAmB,iBAAA,EACnB,QAAA,EAAU,UAAA;EAYZ,UAAA,CACE,iBAAA,EAAmB,iBAAA,EACnB,QAAA,EAAU,WAAA,EACV,OAAA,GAAS,OAAA,IACT,SAAA;EA2CF,aAAA,CACE,iBAAA,EAAmB,iBAAA,EACnB,MAAA,EAAQ,OAAA,SACR,OAAA,GAAS,OAAA;EAkBX,aAAA,CACE,iBAAA,EAAmB,iBAAA,EACnB,OAAA,EAAS,OAAA;EAuBX,cAAA,CAAe,iBAAA,EAAmB,iBAAA;EAOlC,YAAA,CAAa,iBAAA,EAAmB,iBAAA;EAOhC,eAAA,CAAA;EAIA,eAAA,CACE,sBAAA,EAAwB,iBAAA,WACxB,OAAA,EAAS,OAAA,KACR,WAAA;EAAA,QAsCW,iBAAA;AAAA"}
@@ -0,0 +1,26 @@
1
+ import { t as CrossFrameMessenger } from "./CrossFrameMessenger-CAAHntwS.js";
2
+
3
+ //#region src/core/IframeClickInterceptor.d.ts
4
+ /**
5
+ * IframeClickInterceptor handles click events across iframe boundaries.
6
+ *
7
+ * - startInterceptor(): called in the client (iframe) — broadcasts mousedown to parent
8
+ * - startMerger(): called in the editor (parent) — merges received clicks into DOM events
9
+ *
10
+ * Replaces useIframeClickInterceptor / useIframeClickMerger across all frameworks.
11
+ */
12
+ declare class IframeClickInterceptor {
13
+ private readonly _messenger;
14
+ private _mousedownHandler;
15
+ private _unsubscribeMerge;
16
+ constructor(messenger: CrossFrameMessenger);
17
+ /** Called on the client side (inside iframe). Broadcasts click events to parent. */
18
+ startInterceptor(): void;
19
+ /** Called on the editor side (parent frame). Merges incoming iframe clicks into DOM. */
20
+ startMerger(): void;
21
+ stopInterceptor(): void;
22
+ stopMerger(): void;
23
+ }
24
+ //#endregion
25
+ export { IframeClickInterceptor as t };
26
+ //# sourceMappingURL=IframeClickInterceptor-Dy1raFvk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IframeClickInterceptor-Dy1raFvk.d.ts","names":[],"sources":["../../src/core/IframeClickInterceptor.ts"],"mappings":";;;;;AAYA;;;;;;cAAa,sBAAA;EAAA,iBACM,UAAA;EAAA,QACT,iBAAA;EAAA,QACA,iBAAA;cAEI,SAAA,EAAW,mBAAA;EAcvB;EATA,gBAAA,CAAA;EAuBA;EAdA,WAAA,CAAA;EAOA,eAAA,CAAA;EAOA,UAAA,CAAA;AAAA"}
@@ -0,0 +1,21 @@
1
+ import { t as CrossFrameMessenger } from "./CrossFrameMessenger-CAAHntwS.js";
2
+
3
+ //#region src/core/UrlStateManager.d.ts
4
+ /**
5
+ * UrlStateManager patches window.history and broadcasts URL path changes
6
+ * across frames via postMessage.
7
+ *
8
+ * Replaces useCrossURLPathSetter / useCrossURLPathState across all frameworks.
9
+ */
10
+ declare class UrlStateManager {
11
+ private readonly _messenger;
12
+ private _originalPushState;
13
+ private _originalReplaceState;
14
+ private _listeners;
15
+ constructor(messenger: CrossFrameMessenger);
16
+ start(): void;
17
+ stop(): void;
18
+ }
19
+ //#endregion
20
+ export { UrlStateManager as t };
21
+ //# sourceMappingURL=UrlStateManager-Bq87v4hY.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UrlStateManager-Bq87v4hY.d.ts","names":[],"sources":["../../src/core/UrlStateManager.ts"],"mappings":";;;;;AASA;;;;cAAa,eAAA;EAAA,iBACM,UAAA;EAAA,QACT,kBAAA;EAAA,QACA,qBAAA;EAAA,QACA,UAAA;cAEI,SAAA,EAAW,mBAAA;EAIvB,KAAA,CAAA;EA2CA,IAAA,CAAA;AAAA"}
@@ -0,0 +1,2 @@
1
+ import { n as defineIntlayerElements, t as IntlayerContentSelectorElement } from "../ContentSelector-rBO8c1Kp.js";
2
+ export { IntlayerContentSelectorElement, defineIntlayerElements };
@@ -0,0 +1,2 @@
1
+ import { n as defineIntlayerElements, t as IntlayerContentSelectorElement } from "../ContentSelector-rBO8c1Kp.js";
2
+ export { IntlayerContentSelectorElement, defineIntlayerElements };
@@ -0,0 +1,2 @@
1
+ import { n as MessagePayload, r as MessengerConfig, t as CrossFrameMessenger } from "../CrossFrameMessenger-CAAHntwS.js";
2
+ export { CrossFrameMessenger, MessagePayload, MessengerConfig };
@@ -0,0 +1,2 @@
1
+ import { n as CrossFrameStateOptions, t as CrossFrameStateManager } from "../CrossFrameStateManager-DxgxsAmo.js";
2
+ export { CrossFrameStateManager, CrossFrameStateOptions };
@@ -0,0 +1,2 @@
1
+ import { i as FileContent, n as EditorStateManager, r as EditorStateManagerConfig, t as DictionaryContent } from "../EditorStateManager-Ym8YfMiG.js";
2
+ export { DictionaryContent, EditorStateManager, EditorStateManagerConfig, FileContent };
@@ -0,0 +1,2 @@
1
+ import { t as IframeClickInterceptor } from "../IframeClickInterceptor-Dy1raFvk.js";
2
+ export { IframeClickInterceptor };
@@ -0,0 +1,2 @@
1
+ import { t as UrlStateManager } from "../UrlStateManager-Bq87v4hY.js";
2
+ export { UrlStateManager };
@@ -0,0 +1,6 @@
1
+ import { n as MessagePayload, r as MessengerConfig, t as CrossFrameMessenger } from "../CrossFrameMessenger-CAAHntwS.js";
2
+ import { n as CrossFrameStateOptions, t as CrossFrameStateManager } from "../CrossFrameStateManager-DxgxsAmo.js";
3
+ import { i as FileContent, n as EditorStateManager, r as EditorStateManagerConfig, t as DictionaryContent } from "../EditorStateManager-Ym8YfMiG.js";
4
+ import { t as IframeClickInterceptor } from "../IframeClickInterceptor-Dy1raFvk.js";
5
+ import { t as UrlStateManager } from "../UrlStateManager-Bq87v4hY.js";
6
+ export { CrossFrameMessenger, CrossFrameStateManager, CrossFrameStateOptions, DictionaryContent, EditorStateManager, EditorStateManagerConfig, FileContent, IframeClickInterceptor, MessagePayload, MessengerConfig, UrlStateManager };
@@ -1,4 +1,10 @@
1
1
  import { compareUrls } from "./compareUrls.js";
2
+ import { n as defineIntlayerElements, t as IntlayerContentSelectorElement } from "./ContentSelector-rBO8c1Kp.js";
3
+ import { n as MessagePayload, r as MessengerConfig, t as CrossFrameMessenger } from "./CrossFrameMessenger-CAAHntwS.js";
4
+ import { n as CrossFrameStateOptions, t as CrossFrameStateManager } from "./CrossFrameStateManager-DxgxsAmo.js";
5
+ import { i as FileContent, n as EditorStateManager, r as EditorStateManagerConfig, t as DictionaryContent } from "./EditorStateManager-Ym8YfMiG.js";
6
+ import { t as IframeClickInterceptor } from "./IframeClickInterceptor-Dy1raFvk.js";
7
+ import { t as UrlStateManager } from "./UrlStateManager-Bq87v4hY.js";
2
8
  import { mergeIframeClick } from "./mergeIframeClick.js";
3
9
  import { MessageKey } from "./messagesKeys.js";
4
- export { MessageKey, compareUrls, mergeIframeClick };
10
+ export { CrossFrameMessenger, CrossFrameStateManager, CrossFrameStateOptions, DictionaryContent, EditorStateManager, EditorStateManagerConfig, FileContent, IframeClickInterceptor, IntlayerContentSelectorElement, MessageKey, MessagePayload, MessengerConfig, UrlStateManager, compareUrls, defineIntlayerElements, mergeIframeClick };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intlayer/editor",
3
- "version": "8.3.2",
3
+ "version": "8.3.4",
4
4
  "private": false,
5
5
  "description": "Provides the utilities to interface the application with the Intlayer editor and manipulate dictionaries",
6
6
  "keywords": [
@@ -28,7 +28,10 @@
28
28
  "url": "https://github.com/aymericzip"
29
29
  }
30
30
  ],
31
- "sideEffects": false,
31
+ "sideEffects": [
32
+ "./dist/esm/components/*.mjs",
33
+ "./dist/cjs/components/*.cjs"
34
+ ],
32
35
  "exports": {
33
36
  ".": {
34
37
  "types": "./dist/types/index.d.ts",
@@ -69,13 +72,19 @@
69
72
  "test:watch": "bun --bun vitest",
70
73
  "typecheck": "tsc --noEmit --project tsconfig.types.json"
71
74
  },
75
+ "dependencies": {
76
+ "@intlayer/core": "8.3.4",
77
+ "@intlayer/types": "8.3.4",
78
+ "@intlayer/unmerged-dictionaries-entry": "8.3.4",
79
+ "lit": "^3.3.2"
80
+ },
72
81
  "devDependencies": {
73
82
  "@types/node": "25.5.0",
74
83
  "@utils/ts-config": "1.0.4",
75
84
  "@utils/ts-config-types": "1.0.4",
76
85
  "@utils/tsdown-config": "1.0.4",
77
86
  "rimraf": "6.1.3",
78
- "tsdown": "0.21.2",
87
+ "tsdown": "0.21.4",
79
88
  "typescript": "5.9.3",
80
89
  "vitest": "4.1.0"
81
90
  },