@intlayer/editor-react 8.3.3 → 8.4.0-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/dist/cjs/CommunicatorContext.cjs +1 -1
  2. package/dist/cjs/CommunicatorContext.cjs.map +1 -1
  3. package/dist/cjs/ConfigurationContext.cjs +1 -1
  4. package/dist/cjs/ConfigurationContext.cjs.map +1 -1
  5. package/dist/cjs/DictionariesRecordContext.cjs +1 -1
  6. package/dist/cjs/DictionariesRecordContext.cjs.map +1 -1
  7. package/dist/cjs/EditedContentContext.cjs +1 -1
  8. package/dist/cjs/EditedContentContext.cjs.map +1 -1
  9. package/dist/cjs/EditorEnabledContext.cjs +1 -1
  10. package/dist/cjs/EditorEnabledContext.cjs.map +1 -1
  11. package/dist/cjs/EditorProvider.cjs +1 -1
  12. package/dist/cjs/EditorProvider.cjs.map +1 -1
  13. package/dist/cjs/EditorStateContext.cjs +2 -0
  14. package/dist/cjs/EditorStateContext.cjs.map +1 -0
  15. package/dist/cjs/FocusDictionaryContext.cjs +1 -1
  16. package/dist/cjs/FocusDictionaryContext.cjs.map +1 -1
  17. package/dist/cjs/index.cjs +1 -1
  18. package/dist/cjs/useCrossFrameMessageListener.cjs +1 -1
  19. package/dist/cjs/useCrossFrameMessageListener.cjs.map +1 -1
  20. package/dist/cjs/useCrossFrameState.cjs +1 -1
  21. package/dist/cjs/useCrossFrameState.cjs.map +1 -1
  22. package/dist/cjs/useCrossURLPathState.cjs +1 -1
  23. package/dist/cjs/useCrossURLPathState.cjs.map +1 -1
  24. package/dist/cjs/useEditorLocale.cjs +1 -1
  25. package/dist/cjs/useEditorLocale.cjs.map +1 -1
  26. package/dist/cjs/useFocusUnmergedDictionary.cjs +1 -1
  27. package/dist/cjs/useFocusUnmergedDictionary.cjs.map +1 -1
  28. package/dist/cjs/useIframeClickInterceptor.cjs +1 -1
  29. package/dist/cjs/useIframeClickInterceptor.cjs.map +1 -1
  30. package/dist/esm/CommunicatorContext.mjs +1 -1
  31. package/dist/esm/CommunicatorContext.mjs.map +1 -1
  32. package/dist/esm/ConfigurationContext.mjs +1 -1
  33. package/dist/esm/ConfigurationContext.mjs.map +1 -1
  34. package/dist/esm/DictionariesRecordContext.mjs +1 -1
  35. package/dist/esm/DictionariesRecordContext.mjs.map +1 -1
  36. package/dist/esm/EditedContentContext.mjs +1 -1
  37. package/dist/esm/EditedContentContext.mjs.map +1 -1
  38. package/dist/esm/EditorEnabledContext.mjs +1 -1
  39. package/dist/esm/EditorEnabledContext.mjs.map +1 -1
  40. package/dist/esm/EditorProvider.mjs +1 -1
  41. package/dist/esm/EditorProvider.mjs.map +1 -1
  42. package/dist/esm/EditorStateContext.mjs +2 -0
  43. package/dist/esm/EditorStateContext.mjs.map +1 -0
  44. package/dist/esm/FocusDictionaryContext.mjs +1 -1
  45. package/dist/esm/FocusDictionaryContext.mjs.map +1 -1
  46. package/dist/esm/index.mjs +1 -1
  47. package/dist/esm/useCrossFrameMessageListener.mjs +1 -1
  48. package/dist/esm/useCrossFrameMessageListener.mjs.map +1 -1
  49. package/dist/esm/useCrossFrameState.mjs +1 -1
  50. package/dist/esm/useCrossFrameState.mjs.map +1 -1
  51. package/dist/esm/useCrossURLPathState.mjs +1 -1
  52. package/dist/esm/useCrossURLPathState.mjs.map +1 -1
  53. package/dist/esm/useEditorLocale.mjs +1 -1
  54. package/dist/esm/useEditorLocale.mjs.map +1 -1
  55. package/dist/esm/useFocusUnmergedDictionary.mjs.map +1 -1
  56. package/dist/esm/useIframeClickInterceptor.mjs +1 -1
  57. package/dist/esm/useIframeClickInterceptor.mjs.map +1 -1
  58. package/dist/types/CommunicatorContext.d.ts +6 -5
  59. package/dist/types/CommunicatorContext.d.ts.map +1 -1
  60. package/dist/types/ConfigurationContext.d.ts +5 -5
  61. package/dist/types/ConfigurationContext.d.ts.map +1 -1
  62. package/dist/types/DictionariesRecordContext.d.ts +8 -11
  63. package/dist/types/DictionariesRecordContext.d.ts.map +1 -1
  64. package/dist/types/EditedContentContext.d.ts +9 -11
  65. package/dist/types/EditedContentContext.d.ts.map +1 -1
  66. package/dist/types/EditorEnabledContext.d.ts +21 -9
  67. package/dist/types/EditorEnabledContext.d.ts.map +1 -1
  68. package/dist/types/EditorProvider.d.ts +9 -4
  69. package/dist/types/EditorProvider.d.ts.map +1 -1
  70. package/dist/types/EditorStateContext.d.ts +11 -0
  71. package/dist/types/EditorStateContext.d.ts.map +1 -0
  72. package/dist/types/FocusDictionaryContext.d.ts +8 -16
  73. package/dist/types/FocusDictionaryContext.d.ts.map +1 -1
  74. package/dist/types/index.d.ts +9 -8
  75. package/dist/types/useCrossFrameMessageListener.d.ts +3 -13
  76. package/dist/types/useCrossFrameMessageListener.d.ts.map +1 -1
  77. package/dist/types/useCrossFrameState.d.ts +2 -20
  78. package/dist/types/useCrossFrameState.d.ts.map +1 -1
  79. package/dist/types/useCrossURLPathState.d.ts.map +1 -1
  80. package/dist/types/useEditorLocale.d.ts +2 -3
  81. package/dist/types/useEditorLocale.d.ts.map +1 -1
  82. package/dist/types/useFocusUnmergedDictionary.d.ts +1 -2
  83. package/dist/types/useFocusUnmergedDictionary.d.ts.map +1 -1
  84. package/dist/types/useIframeClickInterceptor.d.ts +11 -1
  85. package/dist/types/useIframeClickInterceptor.d.ts.map +1 -1
  86. package/package.json +7 -7
  87. package/dist/cjs/_virtual/_rolldown/runtime.cjs +0 -1
@@ -1,2 +1,2 @@
1
- "use client";import{useCrossFrameMessageListener as e}from"./useCrossFrameMessageListener.mjs";import{useCrossFrameState as t}from"./useCrossFrameState.mjs";import{useDictionariesRecord as n}from"./DictionariesRecordContext.mjs";import{useEditorLocale as r}from"./useEditorLocale.mjs";import{MessageKey as i}from"@intlayer/editor";import{jsx as a}from"react/jsx-runtime";import{NodeType as o}from"@intlayer/types/nodeType";import{createContext as s,useContext as c}from"react";import{editDictionaryByKeyPath as l,getContentNodeByKeyPath as u,renameContentNodeByKeyPath as d}from"@intlayer/core/dictionaryManipulator";const f=s(void 0),p=t=>e(`${i.INTLAYER_EDITED_CONTENT_CHANGED}/post`,t),m=t=>e(`${i.INTLAYER_EDITED_CONTENT_CHANGED}/get`,t),h=s(void 0),g=(e,t)=>typeof e==`function`?e(t):e,_=({children:e})=>{let{localeDictionaries:s}=n(),c=r(),[p,m]=t(i.INTLAYER_EDITED_CONTENT_CHANGED);return a(f.Provider,{value:{editedContent:p},children:a(h.Provider,{value:{setEditedContentState:m,setEditedDictionary:e=>{let t=g(e);return m(n=>t.localId?(t=g(e,n?.[t.localId]),{...n,[t.localId]:t}):(console.error(`no localId`,t),n)),t},setEditedContent:(e,t)=>{m(n=>({...n,[e]:{...n?.[e],content:t}}))},addEditedContent:(e,t,n=[],r=!0)=>{m(i=>{let a=s[e]?.content,o=structuredClone(i?.[e]?.content??a),c=n;if(!r){let e=0,t=n.slice(0,-1),r=n[n.length-1],i=r.key;for(;u(o,c)!==void 0;)e++,i=e===0?r.key:`${r.key} (${e})`,c=[...t,{...r,key:i}]}let d=l(o,c,t);return{...i,[e]:{...i?.[e],content:d}}})},renameEditedContent:(e,t,n=[])=>{m(r=>{let i=s[e]?.content,a=d(structuredClone(r?.[e]?.content??i),t,n);return{...r,[e]:{...r?.[e],content:a}}})},removeEditedContent:(e,t)=>{m(n=>{let r=s[e]?.content,i=l(structuredClone(n?.[e]?.content??r),t,u(r,t));return{...n,[e]:{...n?.[e],content:i}}})},restoreEditedContent:e=>{m(t=>{let n={...t};return delete n[e],n})},clearEditedDictionaryContent:e=>{m(t=>{let n={...t};return delete n[e],n})},clearEditedContent:()=>{m({})},getEditedContentValue:(e,t)=>{if(!p)return;let n=t.filter(e=>e.type!==o.Translation);if(e.includes(`:local:`)||e.includes(`:remote:`))return u(p?.[e]?.content??{},n,c);let r=Object.keys(p).filter(t=>t.startsWith(`${e}:`));for(let e of r){let t=u(p?.[e]?.content??{},n,c);if(t)return t}}},children:e})})},v=()=>c(h),y=()=>{let e=c(f),t=v();return{...e,...t}};export{_ as EditedContentProvider,y as useEditedContent,v as useEditedContentActions,m as useGetEditedContentState,p as usePostEditedContentState};
1
+ "use client";import{useEditorStateManager as e}from"./EditorStateContext.mjs";import{useEffect as t,useState as n}from"react";const r=()=>{let t=e();return{setEditedContentState:e=>t?.editedContent.set(e),setEditedDictionary:e=>t?.setEditedDictionary(e),setEditedContent:(e,n)=>t?.setEditedContent(e,n),addEditedContent:(e,n,r,i)=>t?.addContent(e,n,r,i),renameEditedContent:(e,n,r)=>t?.renameContent(e,n,r),removeEditedContent:(e,n)=>t?.removeContent(e,n),restoreEditedContent:e=>t?.restoreContent(e),clearEditedDictionaryContent:e=>t?.clearContent(e),clearEditedContent:()=>t?.clearAllContent(),getEditedContentValue:(e,n)=>t?.getContentValue(e,n)}},i=()=>{let i=e(),[a,o]=n(i?.editedContent.value);return t(()=>{if(!i)return;let e=e=>o(e.detail);return i.editedContent.addEventListener(`change`,e),()=>i.editedContent.removeEventListener(`change`,e)},[i]),{editedContent:a,...r()}},a=n=>{let r=e();t(()=>{if(!(!n||!r))return r.messenger.subscribe(`INTLAYER_EDITED_CONTENT_CHANGED/post`,n)},[r,n])},o=()=>{let t=e();return()=>{t?.messenger.send(`INTLAYER_EDITED_CONTENT_CHANGED/get`)}};export{i as useEditedContent,r as useEditedContentActions,o as useGetEditedContentState,a as usePostEditedContentState};
2
2
  //# sourceMappingURL=EditedContentContext.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"EditedContentContext.mjs","names":[],"sources":["../../src/EditedContentContext.tsx"],"sourcesContent":["'use client';\n\nimport {\n editDictionaryByKeyPath,\n getContentNodeByKeyPath,\n renameContentNodeByKeyPath,\n} from '@intlayer/core/dictionaryManipulator';\nimport { MessageKey } from '@intlayer/editor';\nimport type { ContentNode, Dictionary, LocalDictionaryId } from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';;\nimport { NodeType } from '@intlayer/types/nodeType';\nimport {\n createContext,\n type Dispatch,\n type FC,\n type PropsWithChildren,\n type SetStateAction,\n useContext,\n} from 'react';\nimport {\n type DictionaryContent,\n useDictionariesRecord,\n} from './DictionariesRecordContext';\nimport { useCrossFrameMessageListener } from './useCrossFrameMessageListener';\nimport { useCrossFrameState } from './useCrossFrameState';\nimport { useEditorLocale } from './useEditorLocale';\n\ntype EditedContentStateContextType = {\n editedContent: Record<LocalDictionaryId, Dictionary> | undefined;\n};\n\nconst EditedContentStateContext = createContext<\n EditedContentStateContextType | undefined\n>(undefined);\n\nexport const usePostEditedContentState = <S,>(\n onEventTriggered?: (data: S) => void\n) =>\n useCrossFrameMessageListener(\n `${MessageKey.INTLAYER_EDITED_CONTENT_CHANGED}/post`,\n onEventTriggered\n );\n\nexport const useGetEditedContentState = <S,>(\n onEventTriggered?: (data: S) => void\n) =>\n useCrossFrameMessageListener(\n `${MessageKey.INTLAYER_EDITED_CONTENT_CHANGED}/get`,\n onEventTriggered\n );\n\ntype EditedContentActionsContextType = {\n setEditedContentState: (editedContent: DictionaryContent) => void;\n setEditedDictionary: Dispatch<SetStateAction<Dictionary>>;\n setEditedContent: (\n localDictionaryId: LocalDictionaryId,\n newValue: Dictionary['content']\n ) => void;\n addEditedContent: (\n localDictionaryId: LocalDictionaryId,\n newValue: ContentNode<any>,\n keyPath?: KeyPath[],\n overwrite?: boolean\n ) => void;\n renameEditedContent: (\n localDictionaryId: LocalDictionaryId,\n newKey: KeyPath['key'],\n keyPath?: KeyPath[]\n ) => void;\n removeEditedContent: (\n localDictionaryId: LocalDictionaryId,\n keyPath: KeyPath[]\n ) => void;\n restoreEditedContent: (localDictionaryId: LocalDictionaryId) => void;\n clearEditedDictionaryContent: (localDictionaryId: LocalDictionaryId) => void;\n clearEditedContent: () => void;\n getEditedContentValue: (\n localDictionaryIdOrKey: LocalDictionaryId | Dictionary['key'] | string,\n keyPath: KeyPath[]\n ) => ContentNode | undefined;\n};\n\nconst EditedContentActionsContext = createContext<\n EditedContentActionsContextType | undefined\n>(undefined);\n\nconst resolveState = <S,>(state?: SetStateAction<S>, prevState?: S): S =>\n typeof state === 'function'\n ? (state as (prevState?: S) => S)(prevState)\n : (state as S);\n\nexport const EditedContentProvider: FC<PropsWithChildren> = ({ children }) => {\n const { localeDictionaries } = useDictionariesRecord();\n const currentLocale = useEditorLocale();\n\n const [editedContent, setEditedContentState] =\n useCrossFrameState<DictionaryContent>(\n MessageKey.INTLAYER_EDITED_CONTENT_CHANGED\n );\n\n const setEditedDictionary: Dispatch<SetStateAction<Dictionary>> = (\n newValue\n ) => {\n let updatedDictionaries: Dictionary = resolveState(newValue);\n\n setEditedContentState((prev) => {\n if (!updatedDictionaries.localId) {\n console.error('no localId', updatedDictionaries);\n\n return prev;\n }\n\n updatedDictionaries = resolveState(\n newValue,\n prev?.[updatedDictionaries.localId]\n );\n\n return {\n ...prev,\n [updatedDictionaries.localId as LocalDictionaryId]: updatedDictionaries,\n };\n });\n\n return updatedDictionaries;\n };\n\n const setEditedContent = (\n localDictionaryId: LocalDictionaryId,\n newValue: Dictionary['content']\n ) => {\n setEditedContentState((prev) => ({\n ...prev,\n [localDictionaryId]: {\n ...prev?.[localDictionaryId],\n content: newValue,\n },\n }));\n };\n\n const addEditedContent = (\n localDictionaryId: LocalDictionaryId,\n newValue: ContentNode,\n keyPath: KeyPath[] = [],\n overwrite: boolean = true\n ) => {\n setEditedContentState((prev) => {\n // Get the starting content: edited version if available, otherwise a deep copy of the original\n const originalContent = localeDictionaries[localDictionaryId]?.content;\n const currentContent = structuredClone(\n prev?.[localDictionaryId]?.content ?? originalContent\n );\n\n let newKeyPath = keyPath;\n if (!overwrite) {\n // Find a unique key based on the keyPath provided\n let index = 0;\n\n const otherKeyPath = keyPath.slice(0, -1);\n const lastKeyPath: KeyPath = keyPath[keyPath.length - 1];\n\n let finalKey = lastKeyPath.key;\n\n // Loop until we find a key that does not exist\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\n return {\n ...prev,\n [localDictionaryId]: {\n ...prev?.[localDictionaryId],\n content: updatedContent as Dictionary['content'],\n },\n };\n });\n };\n\n const renameEditedContent = (\n localDictionaryId: LocalDictionaryId,\n newKey: KeyPath['key'],\n keyPath: KeyPath[] = []\n ) => {\n setEditedContentState((prev) => {\n // Retrieve the base content: use edited version if available, otherwise deep copy of original\n const originalContent = localeDictionaries[localDictionaryId]?.content;\n const currentContent = structuredClone(\n prev?.[localDictionaryId]?.content ?? originalContent\n );\n\n const contentWithNewField = renameContentNodeByKeyPath(\n currentContent,\n newKey,\n keyPath\n );\n\n return {\n ...prev,\n [localDictionaryId]: {\n ...prev?.[localDictionaryId],\n content: contentWithNewField as Dictionary['content'],\n },\n };\n });\n };\n\n const removeEditedContent = (\n localDictionaryId: LocalDictionaryId,\n keyPath: KeyPath[]\n ) => {\n setEditedContentState((prev) => {\n // Retrieve the original content as reference\n const originalContent = localeDictionaries[localDictionaryId]?.content;\n const currentContent = structuredClone(\n prev?.[localDictionaryId]?.content ?? originalContent\n );\n\n // Get the initial value from the original dictionary content\n const initialContent = getContentNodeByKeyPath(originalContent, keyPath);\n\n // Restore the value at the given keyPath\n const restoredContent = editDictionaryByKeyPath(\n currentContent,\n keyPath,\n initialContent\n );\n\n return {\n ...prev,\n [localDictionaryId]: {\n ...prev?.[localDictionaryId],\n content: restoredContent as Dictionary['content'],\n },\n };\n });\n };\n\n const restoreEditedContent = (localDictionaryId: LocalDictionaryId) => {\n setEditedContentState((prev) => {\n const updated = { ...prev };\n delete updated[localDictionaryId];\n return updated;\n });\n };\n\n const clearEditedDictionaryContent = (\n localDictionaryId: LocalDictionaryId\n ) => {\n setEditedContentState((prev) => {\n const filtered = { ...prev };\n delete filtered[localDictionaryId];\n return filtered;\n });\n };\n\n const clearEditedContent = () => {\n setEditedContentState({});\n };\n\n const getEditedContentValue = (\n localDictionaryIdOrKey: LocalDictionaryId | Dictionary['key'] | string,\n keyPath: KeyPath[]\n ): ContentNode | undefined => {\n if (!editedContent) 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 currentContent =\n editedContent?.[localDictionaryIdOrKey as LocalDictionaryId]?.content ??\n {};\n\n const contentNode = getContentNodeByKeyPath(\n currentContent,\n filteredKeyPath,\n currentLocale\n );\n\n return contentNode;\n }\n\n const filteredDictionariesLocalId = Object.keys(editedContent).filter(\n (key) => key.startsWith(`${localDictionaryIdOrKey}:`)\n );\n\n for (const localDictionaryId of filteredDictionariesLocalId) {\n const currentContent =\n editedContent?.[localDictionaryId as LocalDictionaryId]?.content ?? {};\n const contentNode = getContentNodeByKeyPath(\n currentContent,\n filteredKeyPath,\n currentLocale\n );\n\n if (contentNode) return contentNode;\n }\n\n return undefined;\n };\n\n return (\n <EditedContentStateContext.Provider\n value={{\n editedContent,\n }}\n >\n <EditedContentActionsContext.Provider\n value={{\n setEditedContentState,\n setEditedDictionary,\n setEditedContent,\n addEditedContent,\n renameEditedContent,\n removeEditedContent,\n restoreEditedContent,\n clearEditedDictionaryContent,\n clearEditedContent,\n getEditedContentValue,\n }}\n >\n {children}\n </EditedContentActionsContext.Provider>\n </EditedContentStateContext.Provider>\n );\n};\n\nexport const useEditedContentActions = () =>\n useContext(EditedContentActionsContext);\n\nexport const useEditedContent = () => {\n const stateContext = useContext(EditedContentStateContext);\n const actionContext = useEditedContentActions();\n\n return { ...stateContext, ...actionContext };\n};\n"],"mappings":"ymBA+BA,MAAM,EAA4B,EAEhC,IAAA,GAAU,CAEC,EACX,GAEA,EACE,GAAG,EAAW,gCAAgC,OAC9C,EACD,CAEU,EACX,GAEA,EACE,GAAG,EAAW,gCAAgC,MAC9C,EACD,CAiCG,EAA8B,EAElC,IAAA,GAAU,CAEN,GAAoB,EAA2B,IACnD,OAAO,GAAU,WACZ,EAA+B,EAAU,CACzC,EAEM,GAAgD,CAAE,cAAe,CAC5E,GAAM,CAAE,sBAAuB,GAAuB,CAChD,EAAgB,GAAiB,CAEjC,CAAC,EAAe,GACpB,EACE,EAAW,gCACZ,CA+NH,OACE,EAAC,EAA0B,SAA3B,CACE,MAAO,CACL,gBACD,UAED,EAAC,EAA4B,SAA7B,CACE,MAAO,CACL,wBACA,oBArON,GACG,CACH,IAAI,EAAkC,EAAa,EAAS,CAoB5D,OAlBA,EAAuB,GAChB,EAAoB,SAMzB,EAAsB,EACpB,EACA,IAAO,EAAoB,SAC5B,CAEM,CACL,GAAG,GACF,EAAoB,SAA+B,EACrD,GAbC,QAAQ,MAAM,aAAc,EAAoB,CAEzC,GAYT,CAEK,GAgND,kBA5MN,EACA,IACG,CACH,EAAuB,IAAU,CAC/B,GAAG,GACF,GAAoB,CACnB,GAAG,IAAO,GACV,QAAS,EACV,CACF,EAAE,EAoMG,kBAhMN,EACA,EACA,EAAqB,EAAE,CACvB,EAAqB,KAClB,CACH,EAAuB,GAAS,CAE9B,IAAM,EAAkB,EAAmB,IAAoB,QACzD,EAAiB,gBACrB,IAAO,IAAoB,SAAW,EACvC,CAEG,EAAa,EACjB,GAAI,CAAC,EAAW,CAEd,IAAI,EAAQ,EAEN,EAAe,EAAQ,MAAM,EAAG,GAAG,CACnC,EAAuB,EAAQ,EAAQ,OAAS,GAElD,EAAW,EAAY,IAG3B,KACS,EAAwB,EAAgB,EAAW,GAC1D,QAEA,IACA,EACE,IAAU,EAAI,EAAY,IAAM,GAAG,EAAY,IAAI,IAAI,EAAM,GAC/D,EAAa,CACX,GAAG,EACH,CAAE,GAAG,EAAa,IAAK,EAAU,CAClC,CAIL,IAAM,EAAiB,EACrB,EACA,EACA,EACD,CAED,MAAO,CACL,GAAG,GACF,GAAoB,CACnB,GAAG,IAAO,GACV,QAAS,EACV,CACF,EACD,EA+II,qBA3IN,EACA,EACA,EAAqB,EAAE,GACpB,CACH,EAAuB,GAAS,CAE9B,IAAM,EAAkB,EAAmB,IAAoB,QAKzD,EAAsB,EAJL,gBACrB,IAAO,IAAoB,SAAW,EACvC,CAIC,EACA,EACD,CAED,MAAO,CACL,GAAG,GACF,GAAoB,CACnB,GAAG,IAAO,GACV,QAAS,EACV,CACF,EACD,EAoHI,qBAhHN,EACA,IACG,CACH,EAAuB,GAAS,CAE9B,IAAM,EAAkB,EAAmB,IAAoB,QASzD,EAAkB,EARD,gBACrB,IAAO,IAAoB,SAAW,EACvC,CAQC,EALqB,EAAwB,EAAiB,EAAQ,CAOvE,CAED,MAAO,CACL,GAAG,GACF,GAAoB,CACnB,GAAG,IAAO,GACV,QAAS,EACV,CACF,EACD,EAsFI,qBAnFsB,GAAyC,CACrE,EAAuB,GAAS,CAC9B,IAAM,EAAU,CAAE,GAAG,EAAM,CAE3B,OADA,OAAO,EAAQ,GACR,GACP,EA+EI,6BA3EN,GACG,CACH,EAAuB,GAAS,CAC9B,IAAM,EAAW,CAAE,GAAG,EAAM,CAE5B,OADA,OAAO,EAAS,GACT,GACP,EAsEI,uBAnEyB,CAC/B,EAAsB,EAAE,CAAC,EAmEnB,uBA/DN,EACA,IAC4B,CAC5B,GAAI,CAAC,EAAe,OAEpB,IAAM,EAAkB,EAAQ,OAC7B,GAAQ,EAAI,OAAS,EAAS,YAChC,CAMD,GAHE,EAAuB,SAAS,UAAU,EAC1C,EAAuB,SAAS,WAAW,CAa3C,OANoB,EAHlB,IAAgB,IAA8C,SAC9D,EAAE,CAIF,EACA,EACD,CAKH,IAAM,EAA8B,OAAO,KAAK,EAAc,CAAC,OAC5D,GAAQ,EAAI,WAAW,GAAG,EAAuB,GAAG,CACtD,CAED,IAAK,IAAM,KAAqB,EAA6B,CAG3D,IAAM,EAAc,EADlB,IAAgB,IAAyC,SAAW,EAAE,CAGtE,EACA,EACD,CAED,GAAI,EAAa,OAAO,IAwBrB,CAEA,WACoC,CAAA,CACJ,CAAA,EAI5B,MACX,EAAW,EAA4B,CAE5B,MAAyB,CACpC,IAAM,EAAe,EAAW,EAA0B,CACpD,EAAgB,GAAyB,CAE/C,MAAO,CAAE,GAAG,EAAc,GAAG,EAAe"}
1
+ {"version":3,"file":"EditedContentContext.mjs","names":[],"sources":["../../src/EditedContentContext.tsx"],"sourcesContent":["'use client';\n\nimport type { DictionaryContent } from '@intlayer/editor';\nimport type {\n ContentNode,\n Dictionary,\n LocalDictionaryId,\n} from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport { useEffect, useState } from 'react';\nimport { useEditorStateManager } from './EditorStateContext';\n\nexport type { DictionaryContent } from '@intlayer/editor';\n\ntype EditedContentActionsContextType = {\n setEditedContentState: (editedContent: DictionaryContent) => void;\n setEditedDictionary: (dict: Dictionary) => void;\n setEditedContent: (\n localDictionaryId: LocalDictionaryId,\n newValue: Dictionary['content']\n ) => void;\n addEditedContent: (\n localDictionaryId: LocalDictionaryId,\n newValue: ContentNode<any>,\n keyPath?: KeyPath[],\n overwrite?: boolean\n ) => void;\n renameEditedContent: (\n localDictionaryId: LocalDictionaryId,\n newKey: KeyPath['key'],\n keyPath?: KeyPath[]\n ) => void;\n removeEditedContent: (\n localDictionaryId: LocalDictionaryId,\n keyPath: KeyPath[]\n ) => void;\n restoreEditedContent: (localDictionaryId: LocalDictionaryId) => void;\n clearEditedDictionaryContent: (localDictionaryId: LocalDictionaryId) => void;\n clearEditedContent: () => void;\n getEditedContentValue: (\n localDictionaryIdOrKey: LocalDictionaryId | Dictionary['key'] | string,\n keyPath: KeyPath[]\n ) => ContentNode | undefined;\n};\n\nexport const useEditedContentActions = (): EditedContentActionsContextType => {\n const manager = useEditorStateManager();\n\n return {\n setEditedContentState: (value: DictionaryContent) =>\n manager?.editedContent.set(value),\n setEditedDictionary: (dict: Dictionary) =>\n manager?.setEditedDictionary(dict),\n setEditedContent: (\n localId: LocalDictionaryId,\n value: Dictionary['content']\n ) => manager?.setEditedContent(localId, value),\n addEditedContent: (localId, value, keyPath, overwrite) =>\n manager?.addContent(localId, value, keyPath, overwrite),\n renameEditedContent: (localId, newKey, keyPath) =>\n manager?.renameContent(localId, newKey, keyPath),\n removeEditedContent: (localId, keyPath) =>\n manager?.removeContent(localId, keyPath),\n restoreEditedContent: (localId) => manager?.restoreContent(localId),\n clearEditedDictionaryContent: (localId) => manager?.clearContent(localId),\n clearEditedContent: () => manager?.clearAllContent(),\n getEditedContentValue: (localIdOrKey, keyPath) =>\n manager?.getContentValue(localIdOrKey, keyPath),\n };\n};\n\nexport const useEditedContent = () => {\n const manager = useEditorStateManager();\n const [editedContent, setEditedContentState] = useState<\n DictionaryContent | undefined\n >(manager?.editedContent.value);\n\n useEffect(() => {\n if (!manager) return;\n const handler = (e: Event) =>\n setEditedContentState((e as CustomEvent<DictionaryContent>).detail);\n manager.editedContent.addEventListener('change', handler);\n return () => manager.editedContent.removeEventListener('change', handler);\n }, [manager]);\n\n const actions = useEditedContentActions();\n return { editedContent, ...actions };\n};\n\nexport const usePostEditedContentState = <S,>(\n onEventTriggered?: (data: S) => void\n) => {\n const manager = useEditorStateManager();\n useEffect(() => {\n if (!onEventTriggered || !manager) return;\n return manager.messenger.subscribe(\n `INTLAYER_EDITED_CONTENT_CHANGED/post`,\n onEventTriggered as (data: unknown) => void\n );\n }, [manager, onEventTriggered]);\n};\n\nexport const useGetEditedContentState = () => {\n const manager = useEditorStateManager();\n return () => {\n manager?.messenger.send('INTLAYER_EDITED_CONTENT_CHANGED/get');\n };\n};\n"],"mappings":"8HA6CA,MAAa,MAAiE,CAC5E,IAAM,EAAU,GAAuB,CAEvC,MAAO,CACL,sBAAwB,GACtB,GAAS,cAAc,IAAI,EAAM,CACnC,oBAAsB,GACpB,GAAS,oBAAoB,EAAK,CACpC,kBACE,EACA,IACG,GAAS,iBAAiB,EAAS,EAAM,CAC9C,kBAAmB,EAAS,EAAO,EAAS,IAC1C,GAAS,WAAW,EAAS,EAAO,EAAS,EAAU,CACzD,qBAAsB,EAAS,EAAQ,IACrC,GAAS,cAAc,EAAS,EAAQ,EAAQ,CAClD,qBAAsB,EAAS,IAC7B,GAAS,cAAc,EAAS,EAAQ,CAC1C,qBAAuB,GAAY,GAAS,eAAe,EAAQ,CACnE,6BAA+B,GAAY,GAAS,aAAa,EAAQ,CACzE,uBAA0B,GAAS,iBAAiB,CACpD,uBAAwB,EAAc,IACpC,GAAS,gBAAgB,EAAc,EAAQ,CAClD,EAGU,MAAyB,CACpC,IAAM,EAAU,GAAuB,CACjC,CAAC,EAAe,GAAyB,EAE7C,GAAS,cAAc,MAAM,CAW/B,OATA,MAAgB,CACd,GAAI,CAAC,EAAS,OACd,IAAM,EAAW,GACf,EAAuB,EAAqC,OAAO,CAErE,OADA,EAAQ,cAAc,iBAAiB,SAAU,EAAQ,KAC5C,EAAQ,cAAc,oBAAoB,SAAU,EAAQ,EACxE,CAAC,EAAQ,CAAC,CAGN,CAAE,gBAAe,GADR,GAAyB,CACL,EAGzB,EACX,GACG,CACH,IAAM,EAAU,GAAuB,CACvC,MAAgB,CACV,MAAC,GAAoB,CAAC,GAC1B,OAAO,EAAQ,UAAU,UACvB,uCACA,EACD,EACA,CAAC,EAAS,EAAiB,CAAC,EAGpB,MAAiC,CAC5C,IAAM,EAAU,GAAuB,CACvC,UAAa,CACX,GAAS,UAAU,KAAK,sCAAsC"}
@@ -1,2 +1,2 @@
1
- "use client";import{useCrossFrameMessageListener as e}from"./useCrossFrameMessageListener.mjs";import{useCrossFrameState as t}from"./useCrossFrameState.mjs";import{MessageKey as n}from"@intlayer/editor";import{jsx as r}from"react/jsx-runtime";import{createContext as i,useContext as a}from"react";const o=i({enabled:!1}),s=e=>t(n.INTLAYER_EDITOR_ENABLED,!1,e),c=t=>e(`${n.INTLAYER_EDITOR_ENABLED}/post`,t),l=t=>e(`${n.INTLAYER_EDITOR_ENABLED}/get`,t),u=({children:e})=>{let[t]=s({emit:!1,receive:!0});return r(o.Provider,{value:{enabled:t},children:e})},d=()=>a(o);export{u as EditorEnabledProvider,d as useEditorEnabled,s as useEditorEnabledState,l as useGetEditorEnabledState,c as usePostEditorEnabledState};
1
+ "use client";import{useEditorStateManager as e}from"./EditorStateContext.mjs";import{useEffect as t,useState as n}from"react";import{MessageKey as r}from"@intlayer/editor";const i=()=>{let r=e(),[i,a]=n(r?.editorEnabled.value??!1);return t(()=>{if(!r)return;let e=e=>a(e.detail);return r.editorEnabled.addEventListener(`change`,e),()=>r.editorEnabled.removeEventListener(`change`,e)},[r]),{enabled:i}},a=n=>{let i=e();t(()=>{if(n)return i?.messenger.subscribe(`${r.INTLAYER_EDITOR_ENABLED}/get`,n)},[i,n])},o=()=>{let t=e();return e=>{t?.editorEnabled.set(e),t?.editorEnabled.postCurrentValue()}},s=()=>{let{enabled:t}=i(),n=e();return[t,e=>n?.editorEnabled.set(e)]},c=()=>{let t=e();return()=>t?.pingClient()};export{i as useEditorEnabled,s as useEditorEnabledState,c as useEditorPingClient,a as useGetEditorEnabledState,o as usePostEditorEnabledState};
2
2
  //# sourceMappingURL=EditorEnabledContext.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"EditorEnabledContext.mjs","names":[],"sources":["../../src/EditorEnabledContext.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey } from '@intlayer/editor';\nimport {\n createContext,\n type FC,\n type PropsWithChildren,\n useContext,\n} from 'react';\nimport { useCrossFrameMessageListener } from './useCrossFrameMessageListener';\nimport {\n type CrossFrameStateOptions,\n useCrossFrameState,\n} from './useCrossFrameState';\n\nexport type EditorEnabledStateProps = {\n enabled: boolean;\n};\n\nconst EditorEnabledContext = createContext<EditorEnabledStateProps>({\n enabled: false,\n});\n\nexport const useEditorEnabledState = (options?: CrossFrameStateOptions) =>\n useCrossFrameState(MessageKey.INTLAYER_EDITOR_ENABLED, false, options);\n\nexport const usePostEditorEnabledState = <S,>(\n onEventTriggered?: (data: S) => void\n) =>\n useCrossFrameMessageListener(\n `${MessageKey.INTLAYER_EDITOR_ENABLED}/post`,\n onEventTriggered\n );\n\nexport const useGetEditorEnabledState = <S,>(\n onEventTriggered?: (data: S) => void\n) =>\n useCrossFrameMessageListener(\n `${MessageKey.INTLAYER_EDITOR_ENABLED}/get`,\n onEventTriggered\n );\n\nexport const EditorEnabledProvider: FC<PropsWithChildren> = ({ children }) => {\n const [isEnabled] = useEditorEnabledState({\n emit: false,\n receive: true,\n });\n\n return (\n <EditorEnabledContext.Provider value={{ enabled: isEnabled }}>\n {children}\n </EditorEnabledContext.Provider>\n );\n};\n\nexport const useEditorEnabled = () => useContext(EditorEnabledContext);\n"],"mappings":"ySAmBA,MAAM,EAAuB,EAAuC,CAClE,QAAS,GACV,CAAC,CAEW,EAAyB,GACpC,EAAmB,EAAW,wBAAyB,GAAO,EAAQ,CAE3D,EACX,GAEA,EACE,GAAG,EAAW,wBAAwB,OACtC,EACD,CAEU,EACX,GAEA,EACE,GAAG,EAAW,wBAAwB,MACtC,EACD,CAEU,GAAgD,CAAE,cAAe,CAC5E,GAAM,CAAC,GAAa,EAAsB,CACxC,KAAM,GACN,QAAS,GACV,CAAC,CAEF,OACE,EAAC,EAAqB,SAAtB,CAA+B,MAAO,CAAE,QAAS,EAAW,CACzD,WAC6B,CAAA,EAIvB,MAAyB,EAAW,EAAqB"}
1
+ {"version":3,"file":"EditorEnabledContext.mjs","names":[],"sources":["../../src/EditorEnabledContext.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey } from '@intlayer/editor';\nimport { useEffect, useState } from 'react';\nimport { useEditorStateManager } from './EditorStateContext';\n\nexport type EditorEnabledStateProps = {\n enabled: boolean;\n};\n\n/**\n * Returns the current editor-enabled state, kept in sync with the shared\n * EditorStateManager. Replaces the old EditorEnabledContext + EditorEnabledProvider.\n */\nexport const useEditorEnabled = (): EditorEnabledStateProps => {\n const manager = useEditorStateManager();\n const [enabled, setEnabled] = useState<boolean>(\n manager?.editorEnabled.value ?? false\n );\n\n useEffect(() => {\n if (!manager) return;\n\n const handler = (e: Event) =>\n setEnabled((e as CustomEvent<boolean>).detail);\n manager.editorEnabled.addEventListener('change', handler);\n return () => manager.editorEnabled.removeEventListener('change', handler);\n }, [manager]);\n\n return { enabled };\n};\n\n/**\n * Subscribes to incoming \"get\" requests for editor-enabled state and calls\n * the provided callback so the caller can respond.\n * Used by the editor side to respond when the client asks for the current state.\n */\nexport const useGetEditorEnabledState = (onRequest?: () => void) => {\n const manager = useEditorStateManager();\n\n useEffect(() => {\n if (!onRequest) return;\n\n return manager?.messenger.subscribe(\n `${MessageKey.INTLAYER_EDITOR_ENABLED}/get`,\n onRequest\n );\n }, [manager, onRequest]);\n};\n\n/**\n * Returns a function that sets the editor-enabled state and broadcasts it.\n */\nexport const usePostEditorEnabledState = () => {\n const manager = useEditorStateManager();\n\n return (value: boolean) => {\n manager?.editorEnabled.set(value);\n manager?.editorEnabled.postCurrentValue();\n };\n};\n\nexport const useEditorEnabledState = () => {\n const { enabled } = useEditorEnabled();\n const manager = useEditorStateManager();\n const setter = (value: boolean) => manager?.editorEnabled.set(value);\n\n return [enabled, setter] as const;\n};\n\n/**\n * Returns a function that re-pings the client via ARE_YOU_THERE.\n * Use this as the onClick for an \"Enable Editor\" / reconnect button.\n */\nexport const useEditorPingClient = (): (() => void) => {\n const manager = useEditorStateManager();\n\n return () => manager?.pingClient();\n};\n"],"mappings":"4KAcA,MAAa,MAAkD,CAC7D,IAAM,EAAU,GAAuB,CACjC,CAAC,EAAS,GAAc,EAC5B,GAAS,cAAc,OAAS,GACjC,CAWD,OATA,MAAgB,CACd,GAAI,CAAC,EAAS,OAEd,IAAM,EAAW,GACf,EAAY,EAA2B,OAAO,CAEhD,OADA,EAAQ,cAAc,iBAAiB,SAAU,EAAQ,KAC5C,EAAQ,cAAc,oBAAoB,SAAU,EAAQ,EACxE,CAAC,EAAQ,CAAC,CAEN,CAAE,UAAS,EAQP,EAA4B,GAA2B,CAClE,IAAM,EAAU,GAAuB,CAEvC,MAAgB,CACT,KAEL,OAAO,GAAS,UAAU,UACxB,GAAG,EAAW,wBAAwB,MACtC,EACD,EACA,CAAC,EAAS,EAAU,CAAC,EAMb,MAAkC,CAC7C,IAAM,EAAU,GAAuB,CAEvC,MAAQ,IAAmB,CACzB,GAAS,cAAc,IAAI,EAAM,CACjC,GAAS,cAAc,kBAAkB,GAIhC,MAA8B,CACzC,GAAM,CAAE,WAAY,GAAkB,CAChC,EAAU,GAAuB,CAGvC,MAAO,CAAC,EAFQ,GAAmB,GAAS,cAAc,IAAI,EAAM,CAE5C,EAOb,MAA0C,CACrD,IAAM,EAAU,GAAuB,CAEvC,UAAa,GAAS,YAAY"}
@@ -1,2 +1,2 @@
1
- "use client";import{CommunicatorProvider as e}from"./CommunicatorContext.mjs";import{FocusDictionaryProvider as t}from"./FocusDictionaryContext.mjs";import{DictionariesRecordProvider as n}from"./DictionariesRecordContext.mjs";import{ConfigurationProvider as r}from"./ConfigurationContext.mjs";import{EditedContentProvider as i,useGetEditedContentState as a}from"./EditedContentContext.mjs";import{EditorEnabledProvider as o,useEditorEnabled as s,useGetEditorEnabledState as c}from"./EditorEnabledContext.mjs";import{jsx as l}from"react/jsx-runtime";import{useEffect as u,useState as d}from"react";const f=({children:e})=>{let r=a();return u(()=>{r()},[]),l(n,{children:l(i,{children:l(t,{children:e})})})},p=({children:e,fallback:t})=>{let n=c(),{enabled:r}=s();return u(()=>{r||n()},[r]),r?e:t},m=({children:e,fallback:t})=>{let[n,r]=d(!1);return u(()=>{r(window.self!==window.top)},[]),n?e:t},h=({children:e,fallback:t})=>l(o,{children:l(m,{fallback:t,children:l(p,{fallback:t,children:l(f,{children:e})})})}),g=({children:t,configuration:n,postMessage:i,allowedOrigins:a,mode:o})=>l(r,{configuration:n,children:l(e,{postMessage:i,allowedOrigins:a,children:o===`editor`?l(f,{children:t}):l(h,{fallback:t,children:t})})});export{g as EditorProvider};
1
+ "use client";import{EditorStateProvider as e}from"./EditorStateContext.mjs";import{useEffect as t,useRef as n}from"react";import{jsx as r}from"react/jsx-runtime";import{EditorStateManager as i,defineIntlayerElements as a,setGlobalEditorManager as o}from"@intlayer/editor";const s=({children:s,configuration:c,postMessage:l,allowedOrigins:u})=>{let d=n(null);d.current||=new i({mode:`editor`,messenger:{allowedOrigins:u,postMessageFn:l},configuration:c});let f=d.current;return t(()=>(a(),o(f),f.start(),()=>{f.stop(),o(null)}),[f]),r(e,{manager:f,children:s})};export{s as EditorProvider};
2
2
  //# sourceMappingURL=EditorProvider.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"EditorProvider.mjs","names":[],"sources":["../../src/EditorProvider.tsx"],"sourcesContent":["'use client';\n\nimport {\n type FC,\n type PropsWithChildren,\n type ReactNode,\n useEffect,\n useState,\n} from 'react';\nimport {\n CommunicatorProvider,\n type CommunicatorProviderProps,\n} from './CommunicatorContext';\nimport {\n ConfigurationProvider,\n type ConfigurationProviderProps,\n} from './ConfigurationContext';\nimport { DictionariesRecordProvider } from './DictionariesRecordContext';\nimport {\n EditedContentProvider,\n useGetEditedContentState,\n} from './EditedContentContext';\nimport {\n EditorEnabledProvider,\n useEditorEnabled,\n useGetEditorEnabledState,\n} from './EditorEnabledContext';\nimport { FocusDictionaryProvider } from './FocusDictionaryContext';\n\n/**\n * This component add all the providers needed by the editor.\n * It is used to wrap the application, or the editor to work together.\n */\nconst EditorProvidersWrapper: FC<PropsWithChildren> = ({ children }) => {\n const getEditedContentState = useGetEditedContentState();\n\n useEffect(() => {\n getEditedContentState();\n }, []);\n\n return (\n <DictionariesRecordProvider>\n <EditedContentProvider>\n <FocusDictionaryProvider>{children}</FocusDictionaryProvider>\n </EditedContentProvider>\n </DictionariesRecordProvider>\n );\n};\n\ntype FallbackProps = {\n fallback: ReactNode;\n};\n\n/**\n * This component check if the editor is enabled to render the editor providers.\n */\nconst EditorEnabledCheckRenderer: FC<PropsWithChildren<FallbackProps>> = ({\n children,\n fallback,\n}) => {\n const getEditorEnabled = useGetEditorEnabledState();\n\n const { enabled } = useEditorEnabled();\n\n useEffect(() => {\n if (enabled) return;\n\n // Check if the editor is wrapping the application\n getEditorEnabled();\n }, [enabled]);\n\n return enabled ? children : fallback;\n};\n\n/**\n * This component is used to check if the editor is wrapping the application.\n * It avoid to send window.postMessage to the application if the editor is not wrapping the application.\n */\nconst IframeCheckRenderer: FC<PropsWithChildren<FallbackProps>> = ({\n children,\n fallback,\n}) => {\n const [isInIframe, setIsInIframe] = useState(false);\n\n useEffect(() => {\n setIsInIframe(window.self !== window.top);\n }, []);\n\n return isInIframe ? children : fallback;\n};\n\nexport type EditorProviderProps = CommunicatorProviderProps &\n ConfigurationProviderProps & {\n mode: 'editor' | 'client';\n };\n\n/**\n * Inner component for client mode with communicator context available\n */\nconst ClientModeContent: FC<PropsWithChildren<FallbackProps>> = ({\n children,\n fallback,\n}) => (\n <EditorEnabledProvider>\n <IframeCheckRenderer fallback={fallback}>\n <EditorEnabledCheckRenderer fallback={fallback}>\n <EditorProvidersWrapper>{children}</EditorProvidersWrapper>\n </EditorEnabledCheckRenderer>\n </IframeCheckRenderer>\n </EditorEnabledProvider>\n);\n\nexport const EditorProvider: FC<PropsWithChildren<EditorProviderProps>> = ({\n children,\n configuration,\n postMessage,\n allowedOrigins,\n mode,\n}) => (\n <ConfigurationProvider configuration={configuration}>\n <CommunicatorProvider postMessage={postMessage} allowedOrigins={allowedOrigins}>\n {mode === 'editor' ? (\n <EditorProvidersWrapper>{children}</EditorProvidersWrapper>\n ) : (\n <ClientModeContent fallback={children}>\n {children}\n </ClientModeContent>\n )}\n </CommunicatorProvider>\n </ConfigurationProvider>\n);\n"],"mappings":"qlBAiCA,MAAM,GAAiD,CAAE,cAAe,CACtE,IAAM,EAAwB,GAA0B,CAMxD,OAJA,MAAgB,CACd,GAAuB,EACtB,EAAE,CAAC,CAGJ,EAAC,EAAD,CAAA,SACE,EAAC,EAAD,CAAA,SACE,EAAC,EAAD,CAA0B,WAAmC,CAAA,CACvC,CAAA,CACG,CAAA,EAW3B,GAAoE,CACxE,WACA,cACI,CACJ,IAAM,EAAmB,GAA0B,CAE7C,CAAE,WAAY,GAAkB,CAStC,OAPA,MAAgB,CACV,GAGJ,GAAkB,EACjB,CAAC,EAAQ,CAAC,CAEN,EAAU,EAAW,GAOxB,GAA6D,CACjE,WACA,cACI,CACJ,GAAM,CAAC,EAAY,GAAiB,EAAS,GAAM,CAMnD,OAJA,MAAgB,CACd,EAAc,OAAO,OAAS,OAAO,IAAI,EACxC,EAAE,CAAC,CAEC,EAAa,EAAW,GAW3B,GAA2D,CAC/D,WACA,cAEA,EAAC,EAAD,CAAA,SACE,EAAC,EAAD,CAA+B,oBAC7B,EAAC,EAAD,CAAsC,oBACpC,EAAC,EAAD,CAAyB,WAAkC,CAAA,CAChC,CAAA,CACT,CAAA,CACA,CAAA,CAGb,GAA8D,CACzE,WACA,gBACA,cACA,iBACA,UAEA,EAAC,EAAD,CAAsC,yBACpC,EAAC,EAAD,CAAmC,cAA6B,0BAC7D,IAAS,SACR,EAAC,EAAD,CAAyB,WAAkC,CAAA,CAE3D,EAAC,EAAD,CAAmB,SAAU,EAC1B,WACiB,CAAA,CAED,CAAA,CACD,CAAA"}
1
+ {"version":3,"file":"EditorProvider.mjs","names":[],"sources":["../../src/EditorProvider.tsx"],"sourcesContent":["'use client';\n\nimport {\n defineIntlayerElements,\n EditorStateManager,\n type MessengerConfig,\n setGlobalEditorManager,\n} from '@intlayer/editor';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { type FC, type PropsWithChildren, useEffect, useRef } from 'react';\nimport { EditorStateProvider } from './EditorStateContext';\n\nexport type EditorProviderProps = {\n configuration: IntlayerConfig;\n postMessage: (data: any) => void;\n allowedOrigins: string[];\n};\n\n/**\n * EditorProvider creates and manages the lifecycle of an EditorStateManager,\n * provides it to all descendants, and registers the Lit web components.\n */\nexport const EditorProvider: FC<PropsWithChildren<EditorProviderProps>> = ({\n children,\n configuration,\n postMessage,\n allowedOrigins,\n}) => {\n const managerRef = useRef<EditorStateManager | null>(null);\n\n if (!managerRef.current) {\n const messengerConfig: MessengerConfig = {\n allowedOrigins,\n postMessageFn: postMessage,\n };\n\n managerRef.current = new EditorStateManager({\n mode: 'editor',\n messenger: messengerConfig,\n configuration,\n });\n }\n const manager = managerRef.current;\n\n useEffect(() => {\n defineIntlayerElements();\n setGlobalEditorManager(manager);\n\n manager.start();\n return () => {\n manager.stop();\n setGlobalEditorManager(null);\n };\n }, [manager]);\n\n return (\n <EditorStateProvider manager={manager}>{children}</EditorStateProvider>\n );\n};\n"],"mappings":"gRAsBA,MAAa,GAA8D,CACzE,WACA,gBACA,cACA,oBACI,CACJ,IAAM,EAAa,EAAkC,KAAK,CAE1D,AAME,EAAW,UAAU,IAAI,EAAmB,CAC1C,KAAM,SACN,UAPuC,CACvC,iBACA,cAAe,EAChB,CAKC,gBACD,CAAC,CAEJ,IAAM,EAAU,EAAW,QAa3B,OAXA,OACE,GAAwB,CACxB,EAAuB,EAAQ,CAE/B,EAAQ,OAAO,KACF,CACX,EAAQ,MAAM,CACd,EAAuB,KAAK,GAE7B,CAAC,EAAQ,CAAC,CAGX,EAAC,EAAD,CAA8B,UAAU,WAA+B,CAAA"}
@@ -0,0 +1,2 @@
1
+ "use client";import{createContext as e,useContext as t}from"react";import{jsx as n}from"react/jsx-runtime";const r=e(null),i=({children:e,manager:t})=>n(r.Provider,{value:t,children:e}),a=()=>t(r);export{i as EditorStateProvider,a as useEditorStateManager};
2
+ //# sourceMappingURL=EditorStateContext.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EditorStateContext.mjs","names":[],"sources":["../../src/EditorStateContext.tsx"],"sourcesContent":["'use client';\n\nimport type { EditorStateManager } from '@intlayer/editor';\nimport {\n createContext,\n type FC,\n type PropsWithChildren,\n useContext,\n} from 'react';\n\nconst EditorStateContext = createContext<EditorStateManager | null>(null);\n\nexport const EditorStateProvider: FC<\n PropsWithChildren<{ manager: EditorStateManager }>\n> = ({ children, manager }) => (\n <EditorStateContext.Provider value={manager}>\n {children}\n </EditorStateContext.Provider>\n);\n\nexport const useEditorStateManager = (): EditorStateManager | null =>\n useContext(EditorStateContext);\n"],"mappings":"2GAUA,MAAM,EAAqB,EAAyC,KAAK,CAE5D,GAER,CAAE,WAAU,aACf,EAAC,EAAmB,SAApB,CAA6B,MAAO,EACjC,WAC2B,CAAA,CAGnB,MACX,EAAW,EAAmB"}
@@ -1,2 +1,2 @@
1
- "use client";import{useCrossFrameState as e}from"./useCrossFrameState.mjs";import{MessageKey as t}from"@intlayer/editor";import{jsx as n}from"react/jsx-runtime";import{NodeType as r}from"@intlayer/types/nodeType";import{createContext as i,useContext as a}from"react";const o=i(void 0),s=i(void 0),c=({children:i})=>{let[a,c]=e(t.INTLAYER_FOCUSED_CONTENT_CHANGED,null);return n(o.Provider,{value:{focusedContent:a},children:n(s.Provider,{value:{setFocusedContent:c,setFocusedContentKeyPath:e=>{c(t=>{if(!t)return t;let n=e.filter(e=>e.type!==r.Translation);return{...t,keyPath:n}})}},children:i})})},l=()=>{let e=a(s);if(e===void 0)throw Error(`useFocusDictionaryActions must be used within a FocusDictionaryProvider`);return e},u=()=>{let e=l(),t=a(o);if(t===void 0)throw Error(`useFocusDictionaryState must be used within a FocusDictionaryProvider`);return{...t,...e}};export{c as FocusDictionaryProvider,u as useFocusDictionary,l as useFocusDictionaryActions};
1
+ "use client";import{useEditorStateManager as e}from"./EditorStateContext.mjs";import{useEffect as t,useState as n}from"react";const r=()=>{let r=e(),[i,a]=n(r?.focusedContent.value??null);return t(()=>{if(!r)return;let e=e=>a(e.detail);return r.focusedContent.addEventListener(`change`,e),()=>r.focusedContent.removeEventListener(`change`,e)},[r]),{focusedContent:i,setFocusedContent:e=>r?.focusedContent.set(e),setFocusedContentKeyPath:e=>r?.setFocusedContentKeyPath(e)}},i=()=>{let{setFocusedContent:e,setFocusedContentKeyPath:t}=r();return{setFocusedContent:e,setFocusedContentKeyPath:t}};export{r as useFocusDictionary,i as useFocusDictionaryActions};
2
2
  //# sourceMappingURL=FocusDictionaryContext.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"FocusDictionaryContext.mjs","names":[],"sources":["../../src/FocusDictionaryContext.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey } from '@intlayer/editor';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport type { LocalDictionaryId } from '@intlayer/types/dictionary';;\nimport { NodeType } from '@intlayer/types/nodeType';\nimport {\n createContext,\n type Dispatch,\n type FC,\n type PropsWithChildren,\n type SetStateAction,\n useContext,\n} from 'react';\nimport { useCrossFrameState } from './useCrossFrameState';\n\nexport type FileContent = {\n dictionaryKey: string;\n dictionaryLocalId?: LocalDictionaryId;\n keyPath?: KeyPath[];\n};\n\nexport type FocusDictionaryState = {\n focusedContent: FileContent | null;\n};\n\nexport type FocusDictionaryActions = {\n setFocusedContent: Dispatch<SetStateAction<FileContent | null>>;\n setFocusedContentKeyPath: (keyPath: KeyPath[]) => void;\n};\n\nconst FocusDictionaryStateContext = createContext<\n FocusDictionaryState | undefined\n>(undefined);\nconst FocusDictionaryActionsContext = createContext<\n FocusDictionaryActions | undefined\n>(undefined);\n\nexport const FocusDictionaryProvider: FC<PropsWithChildren> = ({\n children,\n}) => {\n const [focusedContent, setFocusedContent] =\n useCrossFrameState<FileContent | null>(\n MessageKey.INTLAYER_FOCUSED_CONTENT_CHANGED,\n null\n );\n\n const setFocusedContentKeyPath = (keyPath: KeyPath[]) => {\n setFocusedContent((prev) => {\n if (!prev) {\n return prev; // nothing to update if there's no focused content\n }\n\n // Remove translation key path if it exists to make it more flexible with optimization client / editor\n const filteredKeyPath = keyPath.filter(\n (key) => key.type !== NodeType.Translation\n );\n\n return {\n ...prev,\n keyPath: filteredKeyPath,\n };\n });\n };\n\n return (\n <FocusDictionaryStateContext.Provider value={{ focusedContent }}>\n <FocusDictionaryActionsContext.Provider\n value={{ setFocusedContent, setFocusedContentKeyPath }}\n >\n {children}\n </FocusDictionaryActionsContext.Provider>\n </FocusDictionaryStateContext.Provider>\n );\n};\n\nexport const useFocusDictionaryActions = () => {\n const context = useContext(FocusDictionaryActionsContext);\n if (context === undefined) {\n throw new Error(\n 'useFocusDictionaryActions must be used within a FocusDictionaryProvider'\n );\n }\n return context;\n};\n\nexport const useFocusDictionary = () => {\n const actionContext = useFocusDictionaryActions();\n const stateContext = useContext(FocusDictionaryStateContext);\n\n if (stateContext === undefined) {\n throw new Error(\n 'useFocusDictionaryState must be used within a FocusDictionaryProvider'\n );\n }\n\n return { ...stateContext, ...actionContext };\n};\n"],"mappings":"2QA+BA,MAAM,EAA8B,EAElC,IAAA,GAAU,CACN,EAAgC,EAEpC,IAAA,GAAU,CAEC,GAAkD,CAC7D,cACI,CACJ,GAAM,CAAC,EAAgB,GACrB,EACE,EAAW,iCACX,KACD,CAoBH,OACE,EAAC,EAA4B,SAA7B,CAAsC,MAAO,CAAE,iBAAgB,UAC7D,EAAC,EAA8B,SAA/B,CACE,MAAO,CAAE,oBAAmB,yBArBA,GAAuB,CACvD,EAAmB,GAAS,CAC1B,GAAI,CAAC,EACH,OAAO,EAIT,IAAM,EAAkB,EAAQ,OAC7B,GAAQ,EAAI,OAAS,EAAS,YAChC,CAED,MAAO,CACL,GAAG,EACH,QAAS,EACV,EACD,EAMwD,CAErD,WACsC,CAAA,CACJ,CAAA,EAI9B,MAAkC,CAC7C,IAAM,EAAU,EAAW,EAA8B,CACzD,GAAI,IAAY,IAAA,GACd,MAAU,MACR,0EACD,CAEH,OAAO,GAGI,MAA2B,CACtC,IAAM,EAAgB,GAA2B,CAC3C,EAAe,EAAW,EAA4B,CAE5D,GAAI,IAAiB,IAAA,GACnB,MAAU,MACR,wEACD,CAGH,MAAO,CAAE,GAAG,EAAc,GAAG,EAAe"}
1
+ {"version":3,"file":"FocusDictionaryContext.mjs","names":[],"sources":["../../src/FocusDictionaryContext.tsx"],"sourcesContent":["'use client';\n\nimport type { FileContent } from '@intlayer/editor';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport { useEffect, useState } from 'react';\nimport { useEditorStateManager } from './EditorStateContext';\n\nexport type { FileContent } from '@intlayer/editor';\n\nexport type FocusDictionaryState = {\n focusedContent: FileContent | null;\n};\n\nexport type FocusDictionaryActions = {\n setFocusedContent: (value: FileContent | null) => void;\n setFocusedContentKeyPath: (keyPath: KeyPath[]) => void;\n};\n\n/**\n * Returns the focused-content state and setters, backed by EditorStateManager.\n */\nexport const useFocusDictionary = (): FocusDictionaryState &\n FocusDictionaryActions => {\n const manager = useEditorStateManager();\n const [focusedContent, setFocusedContentState] = useState<FileContent | null>(\n manager?.focusedContent.value ?? null\n );\n\n useEffect(() => {\n if (!manager) return;\n const handler = (e: Event) =>\n setFocusedContentState((e as CustomEvent<FileContent | null>).detail);\n manager.focusedContent.addEventListener('change', handler);\n return () => manager.focusedContent.removeEventListener('change', handler);\n }, [manager]);\n\n return {\n focusedContent,\n setFocusedContent: (value: FileContent | null) =>\n manager?.focusedContent.set(value),\n setFocusedContentKeyPath: (keyPath: KeyPath[]) =>\n manager?.setFocusedContentKeyPath(keyPath),\n };\n};\n\nexport const useFocusDictionaryActions = (): FocusDictionaryActions => {\n const { setFocusedContent, setFocusedContentKeyPath } = useFocusDictionary();\n return { setFocusedContent, setFocusedContentKeyPath };\n};\n"],"mappings":"8HAqBA,MAAa,MACe,CAC1B,IAAM,EAAU,GAAuB,CACjC,CAAC,EAAgB,GAA0B,EAC/C,GAAS,eAAe,OAAS,KAClC,CAUD,OARA,MAAgB,CACd,GAAI,CAAC,EAAS,OACd,IAAM,EAAW,GACf,EAAwB,EAAsC,OAAO,CAEvE,OADA,EAAQ,eAAe,iBAAiB,SAAU,EAAQ,KAC7C,EAAQ,eAAe,oBAAoB,SAAU,EAAQ,EACzE,CAAC,EAAQ,CAAC,CAEN,CACL,iBACA,kBAAoB,GAClB,GAAS,eAAe,IAAI,EAAM,CACpC,yBAA2B,GACzB,GAAS,yBAAyB,EAAQ,CAC7C,EAGU,MAA0D,CACrE,GAAM,CAAE,oBAAmB,4BAA6B,GAAoB,CAC5E,MAAO,CAAE,oBAAmB,2BAA0B"}
@@ -1 +1 @@
1
- import{CommunicatorProvider as e,useCommunicator as t}from"./CommunicatorContext.mjs";import{useCrossFrameMessageListener as n}from"./useCrossFrameMessageListener.mjs";import{useCrossFrameState as r}from"./useCrossFrameState.mjs";import{FocusDictionaryProvider as i,useFocusDictionary as a,useFocusDictionaryActions as o}from"./FocusDictionaryContext.mjs";import{useCrossURLPathSetter as s,useCrossURLPathState as c}from"./useCrossURLPathState.mjs";import{DictionariesRecordProvider as l,useDictionariesRecord as u,useDictionariesRecordActions as d}from"./DictionariesRecordContext.mjs";import{useEditorLocale as f,useSetEditorLocale as p}from"./useEditorLocale.mjs";import{useFocusUnmergedDictionary as m}from"./useFocusUnmergedDictionary.mjs";import{ConfigurationProvider as h,useConfiguration as g,useConfigurationState as _}from"./ConfigurationContext.mjs";import{EditedContentProvider as v,useEditedContent as y,useEditedContentActions as b,useGetEditedContentState as x,usePostEditedContentState as S}from"./EditedContentContext.mjs";import{EditorEnabledProvider as C,useEditorEnabled as w,useEditorEnabledState as T,useGetEditorEnabledState as E,usePostEditorEnabledState as D}from"./EditorEnabledContext.mjs";import{EditorProvider as O}from"./EditorProvider.mjs";import{useIframeClickInterceptor as k,useIframeClickMerger as A}from"./useIframeClickInterceptor.mjs";export*from"@intlayer/editor";export{e as CommunicatorProvider,h as ConfigurationProvider,l as DictionariesRecordProvider,v as EditedContentProvider,C as EditorEnabledProvider,O as EditorProvider,i as FocusDictionaryProvider,t as useCommunicator,g as useConfiguration,_ as useConfigurationState,n as useCrossFrameMessageListener,r as useCrossFrameState,s as useCrossURLPathSetter,c as useCrossURLPathState,u as useDictionariesRecord,d as useDictionariesRecordActions,y as useEditedContent,b as useEditedContentActions,w as useEditorEnabled,T as useEditorEnabledState,f as useEditorLocale,a as useFocusDictionary,o as useFocusDictionaryActions,m as useFocusUnmergedDictionary,x as useGetEditedContentState,E as useGetEditorEnabledState,k as useIframeClickInterceptor,A as useIframeClickMerger,S as usePostEditedContentState,D as usePostEditorEnabledState,p as useSetEditorLocale};
1
+ import{EditorStateProvider as e,useEditorStateManager as t}from"./EditorStateContext.mjs";import{useFocusDictionary as n,useFocusDictionaryActions as r}from"./FocusDictionaryContext.mjs";import{useCrossFrameState as i}from"./useCrossFrameState.mjs";import{useCrossURLPathSetter as a,useCrossURLPathState as o}from"./useCrossURLPathState.mjs";import{useDictionariesRecord as s,useDictionariesRecordActions as c}from"./DictionariesRecordContext.mjs";import{useEditorLocale as l,useSetEditorLocale as u}from"./useEditorLocale.mjs";import{useFocusUnmergedDictionary as d}from"./useFocusUnmergedDictionary.mjs";import{EditorProvider as f}from"./EditorProvider.mjs";import{useCommunicator as p}from"./CommunicatorContext.mjs";import{ConfigurationProvider as m,useConfiguration as h,useConfigurationState as g}from"./ConfigurationContext.mjs";import{useEditedContent as _,useEditedContentActions as v,useGetEditedContentState as y,usePostEditedContentState as b}from"./EditedContentContext.mjs";import{useEditorEnabled as x,useEditorEnabledState as S,useEditorPingClient as C,useGetEditorEnabledState as w,usePostEditorEnabledState as T}from"./EditorEnabledContext.mjs";import{useCrossFrameMessageListener as E}from"./useCrossFrameMessageListener.mjs";import{useIframeClickInterceptor as D,useIframeClickMerger as O}from"./useIframeClickInterceptor.mjs";import{MessageKey as k}from"@intlayer/editor";export{m as ConfigurationProvider,f as EditorProvider,e as EditorStateProvider,k as MessageKey,p as useCommunicator,h as useConfiguration,g as useConfigurationState,E as useCrossFrameMessageListener,i as useCrossFrameState,a as useCrossURLPathSetter,o as useCrossURLPathState,s as useDictionariesRecord,c as useDictionariesRecordActions,_ as useEditedContent,v as useEditedContentActions,x as useEditorEnabled,S as useEditorEnabledState,l as useEditorLocale,C as useEditorPingClient,t as useEditorStateManager,n as useFocusDictionary,r as useFocusDictionaryActions,d as useFocusUnmergedDictionary,y as useGetEditedContentState,w as useGetEditorEnabledState,D as useIframeClickInterceptor,O as useIframeClickMerger,b as usePostEditedContentState,T as usePostEditorEnabledState,u as useSetEditorLocale};
@@ -1,2 +1,2 @@
1
- "use client";import{useCommunicator as e}from"./CommunicatorContext.mjs";import{compareUrls as t}from"@intlayer/editor";import{useEffect as n}from"react";const r=(r,i,a)=>{let{allowedOrigins:o,postMessage:s,senderId:c}=e();return n(()=>{if(i){let e=e=>{let{type:n,data:a,senderId:s}=e.data;n===r&&s!==c&&(o===void 0||o?.filter(e=>![null,void 0,``,`*`].includes(e)).some(n=>t(n,e.origin))||o?.includes(`*`))&&i(a)};return window.addEventListener(`message`,e),()=>window.removeEventListener(`message`,e)}},[o,s,c,a]),e=>{s({type:r,data:e,senderId:c})}};export{r as useCrossFrameMessageListener};
1
+ "use client";import{useEditorStateManager as e}from"./EditorStateContext.mjs";import{useEffect as t}from"react";const n=(n,r,i)=>{let a=e();return t(()=>{if(r)return a?.messenger.subscribe(n,r)},[a,n,i]),e=>{a?.messenger.send(n,e)}};export{n as useCrossFrameMessageListener};
2
2
  //# sourceMappingURL=useCrossFrameMessageListener.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"useCrossFrameMessageListener.mjs","names":[],"sources":["../../src/useCrossFrameMessageListener.tsx"],"sourcesContent":["'use client';\n\nimport { compareUrls, type MessageKey } from '@intlayer/editor';\nimport { useEffect } from 'react';\nimport { useCommunicator } from './CommunicatorContext';\n\n/**\n * useCrossFrameMessageListener\n *\n * This React hook listens for messages sent via the `postMessage` API and triggers a callback\n * whenever a message of the specified type (`key`) is received. It is useful for synchronizing\n * state or events across different windows, iframes, or contexts.\n *\n * @template S - The type of the data payload in the message.\n * @param key - A unique identifier for the message type to listen for.\n * @param [onEventTriggered] - A callback function triggered when a message\n * @param [revalidator] - A function that re-suscribes the listener. Could be usefull if onEventTriggered depend of some state\n * with the specified key is received. The callback receives the message data as its argument.\n *\n * @returns {{ postMessage: (data: S) => void }} An object containing a `postMessage` function\n * that allows broadcasting messages with the specified key and data.\n */\nexport const useCrossFrameMessageListener = <S,>(\n key: `${MessageKey}` | `${MessageKey}/post` | `${MessageKey}/get`,\n onEventTriggered?: (data: S) => void,\n revalidator?: any\n) => {\n const { allowedOrigins, postMessage, senderId } = useCommunicator();\n\n useEffect(() => {\n if (onEventTriggered) {\n /**\n * Message handler to process incoming messages.\n *\n * - **Message Filtering:** Ensures only messages with the specified `key` are processed.\n * - **Origin Validation:** Checks that the origin of the message is within the allowed origins.\n *\n * @param {MessageEvent<{ type: string; data: S }>} event - The incoming message event object.\n */\n const handleMessage = (\n event: MessageEvent<{ type: string; data: S; senderId: string }>\n ) => {\n const { type, data, senderId: msgSenderId } = event.data;\n\n // Ignore messages that do not match the current key\n if (type !== key) return;\n\n // Ignore messages from myself\n if (msgSenderId === senderId) return;\n\n // Check if the message origin is allowed\n if (\n typeof allowedOrigins === 'undefined' ||\n allowedOrigins\n ?.filter((url) => ![null, undefined, '', '*'].includes(url))\n .some((url) => compareUrls(url, event.origin)) ||\n allowedOrigins?.includes('*')\n ) {\n // Update the local state with the received data\n onEventTriggered(data);\n }\n };\n\n window.addEventListener('message', handleMessage);\n\n // Clean up the event listener on unmount\n return () => window.removeEventListener('message', handleMessage);\n }\n }, [allowedOrigins, postMessage, senderId, revalidator]);\n\n /**\n * A wrapper function around the `postMessage` function to broadcast messages efficiently.\n *\n * - **Encapsulation:** Ensures the `postMessage` function is scoped to the provided key.\n * - **Ease of Use:** Simplifies broadcasting messages with consistent type and format.\n *\n * @param {S} data - The data payload to include in the message.\n * @returns {void}\n */\n const postMessageWrapper: (data?: S) => void = (data) => {\n postMessage({ type: key, data, senderId });\n };\n\n return postMessageWrapper;\n};\n"],"mappings":"0JAsBA,MAAa,GACX,EACA,EACA,IACG,CACH,GAAM,CAAE,iBAAgB,cAAa,YAAa,GAAiB,CAwDnE,OAtDA,MAAgB,CACd,GAAI,EAAkB,CASpB,IAAM,EACJ,GACG,CACH,GAAM,CAAE,OAAM,OAAM,SAAU,GAAgB,EAAM,KAGhD,IAAS,GAGT,IAAgB,IAIX,IAAmB,QAC1B,GACI,OAAQ,GAAQ,CAAC,CAAC,KAAM,IAAA,GAAW,GAAI,IAAI,CAAC,SAAS,EAAI,CAAC,CAC3D,KAAM,GAAQ,EAAY,EAAK,EAAM,OAAO,CAAC,EAChD,GAAgB,SAAS,IAAI,GAG7B,EAAiB,EAAK,EAO1B,OAHA,OAAO,iBAAiB,UAAW,EAAc,KAGpC,OAAO,oBAAoB,UAAW,EAAc,GAElE,CAAC,EAAgB,EAAa,EAAU,EAAY,CAAC,CAWR,GAAS,CACvD,EAAY,CAAE,KAAM,EAAK,OAAM,WAAU,CAAC"}
1
+ {"version":3,"file":"useCrossFrameMessageListener.mjs","names":[],"sources":["../../src/useCrossFrameMessageListener.tsx"],"sourcesContent":["'use client';\n\nimport type { MessageKey } from '@intlayer/editor';\nimport { useEffect } from 'react';\nimport { useEditorStateManager } from './EditorStateContext';\n\n/**\n * Listens for cross-frame messages of the specified type and calls the callback.\n * Returns a function to manually send a message of the same type.\n *\n * Backed by CrossFrameMessenger from EditorStateManager.\n */\nexport const useCrossFrameMessageListener = <S,>(\n key: `${MessageKey}` | `${MessageKey}/post` | `${MessageKey}/get`,\n onEventTriggered?: (data: S) => void,\n revalidator?: any\n) => {\n const manager = useEditorStateManager();\n\n useEffect(() => {\n if (!onEventTriggered) return;\n return manager?.messenger.subscribe<S>(key, onEventTriggered);\n }, [manager, key, revalidator]);\n\n return (data?: S) => {\n manager?.messenger.send(key, data);\n };\n};\n"],"mappings":"gHAYA,MAAa,GACX,EACA,EACA,IACG,CACH,IAAM,EAAU,GAAuB,CAOvC,OALA,MAAgB,CACT,KACL,OAAO,GAAS,UAAU,UAAa,EAAK,EAAiB,EAC5D,CAAC,EAAS,EAAK,EAAY,CAAC,CAEvB,GAAa,CACnB,GAAS,UAAU,KAAK,EAAK,EAAK"}
@@ -1,2 +1,2 @@
1
- "use client";import{useCommunicator as e}from"./CommunicatorContext.mjs";import{useCrossFrameMessageListener as t}from"./useCrossFrameMessageListener.mjs";import{useEffect as n,useState as r}from"react";const i=(e,t)=>typeof e==`function`?e(t):e,a=(a,o,s)=>{let{postMessage:c,senderId:l}=e()??{},{emit:u,receive:d}=s??{emit:!0,receive:!0},f=(e,t)=>{let n=i(e,t);return u&&typeof c==`function`&&n!==void 0&&c({type:`${a}/post`,data:n,senderId:l}),n},p=()=>{typeof c==`function`&&c({type:`${a}/post`,data:m,senderId:l})},[m,h]=r(()=>f(o));return t(`${a}/post`,d?e=>{h(e)}:void 0),t(`${a}/get`,u?(e,t)=>{u&&typeof c==`function`&&t!==l&&m!==void 0&&c({type:`${a}/post`,data:m,senderId:l})}:void 0,m),n(()=>{d&&typeof c==`function`&&m===void 0&&c({type:`${a}/get`,senderId:l})},[]),[m,e=>h(t=>f(e,t)),p]};export{a as useCrossFrameState};
1
+ "use client";import{useEditorStateManager as e}from"./EditorStateContext.mjs";import{useEffect as t,useRef as n,useState as r}from"react";import{CrossFrameStateManager as i}from"@intlayer/editor";const a=(a,o,s)=>{let c=e(),l=typeof o==`function`?o():o,[u,d]=r(l),f=n(l),p=n(null);return t(()=>{let{emit:e=!0,receive:t=!0}=s??{},n=new i(a,c?.messenger,{emit:e,receive:t,initialValue:l});p.current=n;let r=e=>{let t=e.detail;f.current=t,d(t)};return n.addEventListener(`change`,r),n.start(),()=>{n.removeEventListener(`change`,r),n.stop(),p.current=null}},[a,c?.messenger,s?.emit,s?.receive]),[u,e=>{d(t=>{let n=typeof e==`function`?e(t):e;return f.current=n,p.current?.set(n),n})},()=>{p.current?.postCurrentValue()}]};export{a as useCrossFrameState};
2
2
  //# sourceMappingURL=useCrossFrameState.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"useCrossFrameState.mjs","names":[],"sources":["../../src/useCrossFrameState.tsx"],"sourcesContent":["'use client';\n\nimport type { MessageKey } from '@intlayer/editor';\nimport { type Dispatch, type SetStateAction, useEffect, useState } from 'react';\nimport { useCommunicator } from './CommunicatorContext';\nimport { useCrossFrameMessageListener } from './useCrossFrameMessageListener';\n\nexport type CrossFrameStateOptions = {\n emit?: boolean;\n receive?: boolean;\n};\n\nconst resolveState = <S,>(state?: SetStateAction<S>, prevState?: S): S =>\n typeof state === 'function'\n ? (state as (prevState?: S) => S)(prevState)\n : (state as S);\n\n/**\n * Configuration options for `useCrossFrameState`.\n * @typedef {Object} CrossFrameStateOptions\n * @property {boolean} [emit=true] - Whether to broadcast state changes to other instances.\n * @property {boolean} [receive=true] - Whether to listen for state updates from other instances.\n */\n\n/**\n * useCrossFrameState\n *\n * This React hook synchronizes state across multiple instances (e.g., different iframes or windows).\n * It uses the `postMessage` API to communicate state changes and updates between instances.\n *\n * @template S - The type of the state.\n * @param key - A unique identifier for the state to synchronize.\n * @param initialState - The initial state value or a function to compute it lazily.\n * @param options - Configuration options to control emitting and receiving messages.\n * - `emit` (default: true): Whether to broadcast state changes to other instances.\n * - `receive` (default: true): Whether to listen for state updates from other instances.\n *\n * @returns {[S, Dispatch<SetStateAction<S>>]} An array containing the current state and a setter function.\n */\nexport const useCrossFrameState = <S,>(\n key: `${MessageKey}`,\n initialState?: S | (() => S),\n options?: CrossFrameStateOptions\n): [S, Dispatch<SetStateAction<S>>, typeof postState] => {\n const { postMessage, senderId } = useCommunicator() ?? {};\n\n const { emit, receive } = options ?? { emit: true, receive: true };\n\n const handleStateChange = (state?: SetStateAction<S>, prevState?: S) => {\n // Initialize state from the provided initial value, if defined\n const resolvedState: S = resolveState(state, prevState);\n\n // Emit the initial state if `emit` is enabled and initial state is defined\n if (\n emit &&\n typeof postMessage === 'function' &&\n typeof resolvedState !== 'undefined'\n ) {\n postMessage({ type: `${key}/post`, data: resolvedState, senderId });\n }\n\n return resolvedState;\n };\n\n const postState = () => {\n if (typeof postMessage !== 'function') return;\n postMessage({ type: `${key}/post`, data: state, senderId });\n };\n\n const [state, setState] = useState<S>(() => handleStateChange(initialState));\n\n /**\n * A wrapper function around the `setState` function to handle messaging efficiently.\n *\n * This approach has several advantages over using an additional `useEffect`:\n * - **Avoid Redundant Re-renders:** By emitting the message directly within the `setState` logic,\n * it prevents the extra render cycle that would be triggered when using `useEffect`.\n * - **Consistency:** Ensures the message is emitted immediately when the state is updated,\n * avoiding potential delays caused by the asynchronous nature of `useEffect`.\n *\n * This function keeps the same API as `setState` and is memoized using `useCallback`\n * to prevent unnecessary re-renders of dependent components.\n *\n * @template S - The type of the state.\n * @param {SetStateAction<S>} valueOrUpdater - The new state or a function to produce it.\n * @returns {void}\n */\n const setStateWrapper: Dispatch<SetStateAction<S>> = (valueOrUpdater) =>\n setState((prevState) => handleStateChange(valueOrUpdater, prevState));\n\n /**\n * Listen for messages with the specified key and update the state accordingly.\n */\n useCrossFrameMessageListener<S>(\n `${key}/post`,\n // Only activate the state listener if the `receive` option is true\n receive\n ? (data) => {\n setState(data);\n }\n : undefined\n );\n\n const onGetMessage = (_: unknown, originSenderId?: string) => {\n if (!emit) return;\n if (typeof postMessage !== 'function') return;\n if (originSenderId === senderId) return;\n if (typeof state === 'undefined') return;\n\n postMessage({ type: `${key}/post`, data: state, senderId });\n };\n\n /**\n * Listen for messages request to get the state content and send it back.\n */\n useCrossFrameMessageListener<S>(\n `${key}/get`,\n // Only activate the state listener if the `emit` option is true\n emit ? onGetMessage : undefined,\n state // Revalidate the listener if the state changes\n );\n\n useEffect(() => {\n // If the component is mounted and the hook in receive mode,\n // Request the state from the other instance\n if (\n receive &&\n typeof postMessage === 'function' &&\n typeof state === 'undefined'\n ) {\n postMessage({ type: `${key}/get`, senderId });\n }\n }, []);\n\n // Return the useState state and setter\n return [state, setStateWrapper, postState];\n};\n"],"mappings":"2MAYA,MAAM,GAAoB,EAA2B,IACnD,OAAO,GAAU,WACZ,EAA+B,EAAU,CACzC,EAwBM,GACX,EACA,EACA,IACuD,CACvD,GAAM,CAAE,cAAa,YAAa,GAAiB,EAAI,EAAE,CAEnD,CAAE,OAAM,WAAY,GAAW,CAAE,KAAM,GAAM,QAAS,GAAM,CAE5D,GAAqB,EAA2B,IAAkB,CAEtE,IAAM,EAAmB,EAAa,EAAO,EAAU,CAWvD,OAPE,GACA,OAAO,GAAgB,YAChB,IAAkB,QAEzB,EAAY,CAAE,KAAM,GAAG,EAAI,OAAQ,KAAM,EAAe,WAAU,CAAC,CAG9D,GAGH,MAAkB,CAClB,OAAO,GAAgB,YAC3B,EAAY,CAAE,KAAM,GAAG,EAAI,OAAQ,KAAM,EAAO,WAAU,CAAC,EAGvD,CAAC,EAAO,GAAY,MAAkB,EAAkB,EAAa,CAAC,CAkE5E,OA1CA,EACE,GAAG,EAAI,OAEP,EACK,GAAS,CACR,EAAS,EAAK,EAEhB,IAAA,GACL,CAcD,EACE,GAAG,EAAI,MAEP,GAfoB,EAAY,IAA4B,CACvD,GACD,OAAO,GAAgB,YACvB,IAAmB,GACZ,IAAU,QAErB,EAAY,CAAE,KAAM,GAAG,EAAI,OAAQ,KAAM,EAAO,WAAU,CAAC,EASrC,IAAA,GACtB,EACD,CAED,MAAgB,CAIZ,GACA,OAAO,GAAgB,YAChB,IAAU,QAEjB,EAAY,CAAE,KAAM,GAAG,EAAI,MAAO,WAAU,CAAC,EAE9C,EAAE,CAAC,CAGC,CAAC,EAhD8C,GACpD,EAAU,GAAc,EAAkB,EAAgB,EAAU,CAAC,CA+CvC,EAAU"}
1
+ {"version":3,"file":"useCrossFrameState.mjs","names":[],"sources":["../../src/useCrossFrameState.tsx"],"sourcesContent":["'use client';\n\nimport type { MessageKey } from '@intlayer/editor';\nimport { CrossFrameStateManager } from '@intlayer/editor';\nimport {\n type Dispatch,\n type SetStateAction,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { useEditorStateManager } from './EditorStateContext';\n\nexport type CrossFrameStateOptions = {\n emit?: boolean;\n receive?: boolean;\n};\n\n/**\n * Synchronizes a React state value across frames using CrossFrameStateManager.\n */\nexport const useCrossFrameState = <S,>(\n key: `${MessageKey}`,\n initialState?: S | (() => S),\n options?: CrossFrameStateOptions\n): [S, Dispatch<SetStateAction<S>>, () => void] => {\n const manager = useEditorStateManager();\n\n const resolvedInitial =\n typeof initialState === 'function'\n ? (initialState as () => S)()\n : initialState;\n\n const [value, setValueState] = useState<S>(resolvedInitial as S);\n const valueRef = useRef<S>(resolvedInitial as S);\n\n const stateManagerRef = useRef<CrossFrameStateManager<S> | null>(null);\n\n useEffect(() => {\n const { emit = true, receive = true } = options ?? {};\n const stateManager = new CrossFrameStateManager<S>(\n key,\n manager?.messenger,\n {\n emit,\n receive,\n initialValue: resolvedInitial,\n }\n );\n stateManagerRef.current = stateManager;\n\n const handler = (e: Event) => {\n const newValue = (e as CustomEvent<S>).detail;\n valueRef.current = newValue;\n setValueState(newValue);\n };\n stateManager.addEventListener('change', handler);\n stateManager.start();\n\n return () => {\n stateManager.removeEventListener('change', handler);\n stateManager.stop();\n stateManagerRef.current = null;\n };\n }, [key, manager?.messenger, options?.emit, options?.receive]);\n\n const setValue: Dispatch<SetStateAction<S>> = (valueOrUpdater) => {\n setValueState((prev) => {\n const newValue =\n typeof valueOrUpdater === 'function'\n ? (valueOrUpdater as (prev: S) => S)(prev)\n : valueOrUpdater;\n valueRef.current = newValue;\n stateManagerRef.current?.set(newValue);\n return newValue;\n });\n };\n\n const postState = () => {\n stateManagerRef.current?.postCurrentValue();\n };\n\n return [value, setValue, postState];\n};\n"],"mappings":"oMAqBA,MAAa,GACX,EACA,EACA,IACiD,CACjD,IAAM,EAAU,GAAuB,CAEjC,EACJ,OAAO,GAAiB,WACnB,GAA0B,CAC3B,EAEA,CAAC,EAAO,GAAiB,EAAY,EAAqB,CAC1D,EAAW,EAAU,EAAqB,CAE1C,EAAkB,EAAyC,KAAK,CA8CtE,OA5CA,MAAgB,CACd,GAAM,CAAE,OAAO,GAAM,UAAU,IAAS,GAAW,EAAE,CAC/C,EAAe,IAAI,EACvB,EACA,GAAS,UACT,CACE,OACA,UACA,aAAc,EACf,CACF,CACD,EAAgB,QAAU,EAE1B,IAAM,EAAW,GAAa,CAC5B,IAAM,EAAY,EAAqB,OACvC,EAAS,QAAU,EACnB,EAAc,EAAS,EAKzB,OAHA,EAAa,iBAAiB,SAAU,EAAQ,CAChD,EAAa,OAAO,KAEP,CACX,EAAa,oBAAoB,SAAU,EAAQ,CACnD,EAAa,MAAM,CACnB,EAAgB,QAAU,OAE3B,CAAC,EAAK,GAAS,UAAW,GAAS,KAAM,GAAS,QAAQ,CAAC,CAkBvD,CAAC,EAhBuC,GAAmB,CAChE,EAAe,GAAS,CACtB,IAAM,EACJ,OAAO,GAAmB,WACrB,EAAkC,EAAK,CACxC,EAGN,MAFA,GAAS,QAAU,EACnB,EAAgB,SAAS,IAAI,EAAS,CAC/B,GACP,MAGoB,CACtB,EAAgB,SAAS,kBAAkB,EAGV"}
@@ -1,2 +1,2 @@
1
- "use client";import{useCrossFrameState as e}from"./useCrossFrameState.mjs";import{MessageKey as t}from"@intlayer/editor";import{useEffect as n}from"react";const r=(n,r)=>e(t.INTLAYER_URL_CHANGE,n,r),i=e=>{let t=r(e,{emit:!0,receive:!1}),[i,a]=t;return n(()=>{let e=history.pushState,t=history.replaceState,n=e=>function(...t){e.apply(this,t),window.dispatchEvent(new Event(`locationchange`))};history.pushState=n(e),history.replaceState=n(t);let r=()=>{a(window.location.pathname)};return window.addEventListener(`locationchange`,r),window.addEventListener(`popstate`,r),window.addEventListener(`hashchange`,r),window.addEventListener(`load`,r),r(),()=>{window.removeEventListener(`locationchange`,r),window.removeEventListener(`popstate`,r),window.removeEventListener(`hashchange`,r),window.removeEventListener(`load`,r),history.pushState=e,history.replaceState=t}},[]),t};export{i as useCrossURLPathSetter,r as useCrossURLPathState};
1
+ "use client";import{useCrossFrameState as e}from"./useCrossFrameState.mjs";import{MessageKey as t}from"@intlayer/editor";const n=(n,r)=>e(t.INTLAYER_URL_CHANGE,n,r),r=e=>n(e,{emit:!0,receive:!1});export{r as useCrossURLPathSetter,n as useCrossURLPathState};
2
2
  //# sourceMappingURL=useCrossURLPathState.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"useCrossURLPathState.mjs","names":[],"sources":["../../src/useCrossURLPathState.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey } from '@intlayer/editor';\nimport { useEffect } from 'react';\nimport {\n type CrossFrameStateOptions,\n useCrossFrameState,\n} from './useCrossFrameState';\n\nexport const useCrossURLPathState = (\n initialState?: string,\n options?: CrossFrameStateOptions\n) => useCrossFrameState(MessageKey.INTLAYER_URL_CHANGE, initialState, options);\n\nexport const useCrossURLPathSetter = (initialState?: string) => {\n const states = useCrossURLPathState(initialState, {\n emit: true,\n receive: false,\n });\n const [_state, setState] = states;\n\n useEffect(() => {\n /**\n * 1) Monkey patch history methods (pushState, replaceState)\n * to dispatch a custom event whenever they are called.\n */\n const originalPushState = history.pushState;\n const originalReplaceState = history.replaceState;\n\n const injectLocationChangeEvent = (method: (...args: any[]) => void) =>\n function (this: typeof history, ...args: [any, string, string?]) {\n method.apply(this, args);\n window.dispatchEvent(new Event('locationchange'));\n };\n\n history.pushState = injectLocationChangeEvent(originalPushState);\n history.replaceState = injectLocationChangeEvent(originalReplaceState);\n\n /**\n * 2) The callback to update our state whenever the URL changes.\n */\n const updateURLState = () => {\n setState(window.location.pathname);\n };\n\n /**\n * 3) Attach event listeners for locationchange, popstate, hashchange.\n * - 'locationchange' is our custom event triggered by push/replaceState overrides.\n * - 'popstate' is fired on back/forward navigation.\n * - 'hashchange' is for URL hash (#) changes.\n * - 'load' is when new page is loaded\n */\n window.addEventListener('locationchange', updateURLState);\n window.addEventListener('popstate', updateURLState);\n window.addEventListener('hashchange', updateURLState);\n window.addEventListener('load', updateURLState);\n\n // Initialize our state immediately on mount\n updateURLState();\n\n /**\n * 4) Cleanup when the component unmounts:\n * - Remove event listeners.\n * - Restore original pushState & replaceState to avoid side effects.\n */\n return () => {\n window.removeEventListener('locationchange', updateURLState);\n window.removeEventListener('popstate', updateURLState);\n window.removeEventListener('hashchange', updateURLState);\n window.removeEventListener('load', updateURLState);\n history.pushState = originalPushState;\n history.replaceState = originalReplaceState;\n };\n }, []);\n\n return states;\n};\n"],"mappings":"2JASA,MAAa,GACX,EACA,IACG,EAAmB,EAAW,oBAAqB,EAAc,EAAQ,CAEjE,EAAyB,GAA0B,CAC9D,IAAM,EAAS,EAAqB,EAAc,CAChD,KAAM,GACN,QAAS,GACV,CAAC,CACI,CAAC,EAAQ,GAAY,EAwD3B,OAtDA,MAAgB,CAKd,IAAM,EAAoB,QAAQ,UAC5B,EAAuB,QAAQ,aAE/B,EAA6B,GACjC,SAAgC,GAAG,EAA8B,CAC/D,EAAO,MAAM,KAAM,EAAK,CACxB,OAAO,cAAc,IAAI,MAAM,iBAAiB,CAAC,EAGrD,QAAQ,UAAY,EAA0B,EAAkB,CAChE,QAAQ,aAAe,EAA0B,EAAqB,CAKtE,IAAM,MAAuB,CAC3B,EAAS,OAAO,SAAS,SAAS,EAuBpC,OAbA,OAAO,iBAAiB,iBAAkB,EAAe,CACzD,OAAO,iBAAiB,WAAY,EAAe,CACnD,OAAO,iBAAiB,aAAc,EAAe,CACrD,OAAO,iBAAiB,OAAQ,EAAe,CAG/C,GAAgB,KAOH,CACX,OAAO,oBAAoB,iBAAkB,EAAe,CAC5D,OAAO,oBAAoB,WAAY,EAAe,CACtD,OAAO,oBAAoB,aAAc,EAAe,CACxD,OAAO,oBAAoB,OAAQ,EAAe,CAClD,QAAQ,UAAY,EACpB,QAAQ,aAAe,IAExB,EAAE,CAAC,CAEC"}
1
+ {"version":3,"file":"useCrossURLPathState.mjs","names":[],"sources":["../../src/useCrossURLPathState.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey } from '@intlayer/editor';\nimport {\n type CrossFrameStateOptions,\n useCrossFrameState,\n} from './useCrossFrameState';\n\nexport const useCrossURLPathState = (\n initialState?: string,\n options?: CrossFrameStateOptions\n) => useCrossFrameState(MessageKey.INTLAYER_URL_CHANGE, initialState, options);\n\nexport const useCrossURLPathSetter = (initialState?: string) => {\n // The EditorStateManager already handles URL tracking in client mode via\n // UrlStateManager.start(). This hook remains for explicit use cases.\n return useCrossURLPathState(initialState, { emit: true, receive: false });\n};\n"],"mappings":"yHAQA,MAAa,GACX,EACA,IACG,EAAmB,EAAW,oBAAqB,EAAc,EAAQ,CAEjE,EAAyB,GAG7B,EAAqB,EAAc,CAAE,KAAM,GAAM,QAAS,GAAO,CAAC"}
@@ -1,2 +1,2 @@
1
- import{useCrossFrameState as e}from"./useCrossFrameState.mjs";import{MessageKey as t}from"@intlayer/editor";const n=()=>{let[n]=e(t.INTLAYER_CURRENT_LOCALE,void 0,{receive:!0,emit:!1});return n},r=()=>e(t.INTLAYER_CURRENT_LOCALE,void 0,{receive:!0,emit:!1});export{n as useEditorLocale,r as useSetEditorLocale};
1
+ "use client";import{useEditorStateManager as e}from"./EditorStateContext.mjs";import{useEffect as t,useState as n}from"react";const r=()=>{let r=e(),[i,a]=n(r?.currentLocale.value);return t(()=>{if(!r)return;let e=e=>a(e.detail);return r.currentLocale.addEventListener(`change`,e),()=>r.currentLocale.removeEventListener(`change`,e)},[r]),i},i=()=>{let t=e();return e=>t?.currentLocale.set(e)};export{r as useEditorLocale,i as useSetEditorLocale};
2
2
  //# sourceMappingURL=useEditorLocale.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"useEditorLocale.mjs","names":[],"sources":["../../src/useEditorLocale.tsx"],"sourcesContent":["import { MessageKey } from '@intlayer/editor';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport { useCrossFrameState } from './useCrossFrameState';\n\nexport const useEditorLocale = () => {\n const [currentLocale] = useCrossFrameState<Locale>(\n MessageKey.INTLAYER_CURRENT_LOCALE,\n undefined,\n {\n receive: true,\n emit: false,\n }\n );\n\n return currentLocale;\n};\n\nexport const useSetEditorLocale = () => {\n const setCurrentLocale = useCrossFrameState<Locale>(\n MessageKey.INTLAYER_CURRENT_LOCALE,\n undefined,\n {\n receive: true,\n emit: false,\n }\n );\n\n return setCurrentLocale;\n};\n"],"mappings":"4GAIA,MAAa,MAAwB,CACnC,GAAM,CAAC,GAAiB,EACtB,EAAW,wBACX,IAAA,GACA,CACE,QAAS,GACT,KAAM,GACP,CACF,CAED,OAAO,GAGI,MACc,EACvB,EAAW,wBACX,IAAA,GACA,CACE,QAAS,GACT,KAAM,GACP,CACF"}
1
+ {"version":3,"file":"useEditorLocale.mjs","names":[],"sources":["../../src/useEditorLocale.tsx"],"sourcesContent":["'use client';\n\nimport type { Locale } from '@intlayer/types/allLocales';\nimport { useEffect, useState } from 'react';\nimport { useEditorStateManager } from './EditorStateContext';\n\nexport const useEditorLocale = (): Locale | undefined => {\n const manager = useEditorStateManager();\n const [locale, setLocale] = useState<Locale | undefined>(\n manager?.currentLocale.value\n );\n\n useEffect(() => {\n if (!manager) return;\n\n const handler = (e: Event) => setLocale((e as CustomEvent<Locale>).detail);\n manager.currentLocale.addEventListener('change', handler);\n\n return () => manager.currentLocale.removeEventListener('change', handler);\n }, [manager]);\n\n return locale;\n};\n\nexport const useSetEditorLocale = () => {\n const manager = useEditorStateManager();\n return (locale: Locale) => manager?.currentLocale.set(locale);\n};\n"],"mappings":"8HAMA,MAAa,MAA4C,CACvD,IAAM,EAAU,GAAuB,CACjC,CAAC,EAAQ,GAAa,EAC1B,GAAS,cAAc,MACxB,CAWD,OATA,MAAgB,CACd,GAAI,CAAC,EAAS,OAEd,IAAM,EAAW,GAAa,EAAW,EAA0B,OAAO,CAG1E,OAFA,EAAQ,cAAc,iBAAiB,SAAU,EAAQ,KAE5C,EAAQ,cAAc,oBAAoB,SAAU,EAAQ,EACxE,CAAC,EAAQ,CAAC,CAEN,GAGI,MAA2B,CACtC,IAAM,EAAU,GAAuB,CACvC,MAAQ,IAAmB,GAAS,cAAc,IAAI,EAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"useFocusUnmergedDictionary.mjs","names":[],"sources":["../../src/useFocusUnmergedDictionary.tsx"],"sourcesContent":["'use client';\n\nimport { getContentNodeByKeyPath } from '@intlayer/core/dictionaryManipulator';\nimport type { Dictionary, LocalDictionaryId } from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport { useMemo } from 'react';\nimport { useDictionariesRecord } from './DictionariesRecordContext';\nimport { type FileContent, useFocusDictionary } from './FocusDictionaryContext';\nimport { useEditorLocale } from './useEditorLocale';\n\ntype UnmergedKeyPath = {\n keyPath: KeyPath[];\n dictionaryLocalId?: LocalDictionaryId;\n};\n\n/**\n * Converts merged keypath format to unmerged format.\n * Merged: [{type: \"translation\", key: \"fr\"}, {type: \"object\", key: \"title\"}]\n * Unmerged: [{type: \"object\", key: \"title\"}, {type: \"translation\", key: \"fr\"}]\n */\nconst mergedKeyPathToUnmergedKeyPath = (\n keyPath: KeyPath[],\n dictionaries: Dictionary[],\n locale: Locale\n): UnmergedKeyPath | undefined => {\n // If we have a dictionary, verify the path exists\n // Try to find the correct position for the translation key\n // by checking which path actually exists in the dictionary\n for (const dictionary of dictionaries) {\n try {\n const result = getContentNodeByKeyPath(\n dictionary.content,\n keyPath ?? [],\n locale\n );\n\n if (result) {\n return { keyPath, dictionaryLocalId: dictionary.localId };\n }\n } catch {\n // Continue to next candidate\n }\n }\n};\n\nexport const useFocusUnmergedDictionary = () => {\n const { localeDictionaries } = useDictionariesRecord();\n const currentLocale = useEditorLocale();\n const {\n setFocusedContent,\n setFocusedContentKeyPath,\n focusedContent: mergedFocusedContent,\n } = useFocusDictionary();\n\n const focusedContent = useMemo<FileContent | null>(() => {\n if (!mergedFocusedContent) return mergedFocusedContent;\n if (!localeDictionaries) return mergedFocusedContent;\n if (mergedFocusedContent.dictionaryLocalId) return mergedFocusedContent;\n\n const dictionaries = Object.values(localeDictionaries).filter(\n (dictionary) => dictionary.key === mergedFocusedContent.dictionaryKey\n );\n\n const unmergedKeyPath = mergedKeyPathToUnmergedKeyPath(\n mergedFocusedContent.keyPath ?? [],\n dictionaries,\n currentLocale\n );\n\n return {\n ...mergedFocusedContent,\n ...unmergedKeyPath,\n };\n }, [mergedFocusedContent, localeDictionaries, currentLocale]);\n\n return {\n focusedContent,\n setFocusedContent,\n setFocusedContentKeyPath,\n };\n};\n"],"mappings":"8TAqBA,MAAM,GACJ,EACA,EACA,IACgC,CAIhC,IAAK,IAAM,KAAc,EACvB,GAAI,CAOF,GANe,EACb,EAAW,QACX,GAAW,EAAE,CACb,EACD,CAGC,MAAO,CAAE,UAAS,kBAAmB,EAAW,QAAS,MAErD,IAMC,MAAmC,CAC9C,GAAM,CAAE,sBAAuB,GAAuB,CAChD,EAAgB,GAAiB,CACjC,CACJ,oBACA,2BACA,eAAgB,GACd,GAAoB,CAuBxB,MAAO,CACL,eAtBqB,MAAkC,CAGvD,GAFI,CAAC,GACD,CAAC,GACD,EAAqB,kBAAmB,OAAO,EAEnD,IAAM,EAAe,OAAO,OAAO,EAAmB,CAAC,OACpD,GAAe,EAAW,MAAQ,EAAqB,cACzD,CAEK,EAAkB,EACtB,EAAqB,SAAW,EAAE,CAClC,EACA,EACD,CAED,MAAO,CACL,GAAG,EACH,GAAG,EACJ,EACA,CAAC,EAAsB,EAAoB,EAAc,CAAC,CAI3D,oBACA,2BACD"}
1
+ {"version":3,"file":"useFocusUnmergedDictionary.mjs","names":[],"sources":["../../src/useFocusUnmergedDictionary.tsx"],"sourcesContent":["'use client';\n\nimport { getContentNodeByKeyPath } from '@intlayer/core/dictionaryManipulator';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { Dictionary, LocalDictionaryId } from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport { useMemo } from 'react';\nimport { useDictionariesRecord } from './DictionariesRecordContext';\nimport { type FileContent, useFocusDictionary } from './FocusDictionaryContext';\nimport { useEditorLocale } from './useEditorLocale';\n\ntype UnmergedKeyPath = {\n keyPath: KeyPath[];\n dictionaryLocalId?: LocalDictionaryId;\n};\n\n/**\n * Converts merged keypath format to unmerged format.\n * Merged: [{type: \"translation\", key: \"fr\"}, {type: \"object\", key: \"title\"}]\n * Unmerged: [{type: \"object\", key: \"title\"}, {type: \"translation\", key: \"fr\"}]\n */\nconst mergedKeyPathToUnmergedKeyPath = (\n keyPath: KeyPath[],\n dictionaries: Dictionary[],\n locale?: Locale\n): UnmergedKeyPath | undefined => {\n // If we have a dictionary, verify the path exists\n // Try to find the correct position for the translation key\n // by checking which path actually exists in the dictionary\n for (const dictionary of dictionaries) {\n try {\n const result = getContentNodeByKeyPath(\n dictionary.content,\n keyPath ?? [],\n locale\n );\n\n if (result) {\n return { keyPath, dictionaryLocalId: dictionary.localId };\n }\n } catch {\n // Continue to next candidate\n }\n }\n};\n\nexport const useFocusUnmergedDictionary = () => {\n const { localeDictionaries } = useDictionariesRecord();\n const currentLocale = useEditorLocale();\n const {\n setFocusedContent,\n setFocusedContentKeyPath,\n focusedContent: mergedFocusedContent,\n } = useFocusDictionary();\n\n const focusedContent = useMemo<FileContent | null>(() => {\n if (!mergedFocusedContent) return mergedFocusedContent;\n if (!localeDictionaries) return mergedFocusedContent;\n if (mergedFocusedContent.dictionaryLocalId) return mergedFocusedContent;\n\n const dictionaries = Object.values(localeDictionaries).filter(\n (dictionary) => dictionary.key === mergedFocusedContent.dictionaryKey\n );\n\n const unmergedKeyPath = mergedKeyPathToUnmergedKeyPath(\n mergedFocusedContent.keyPath ?? [],\n dictionaries,\n currentLocale\n );\n\n return {\n ...mergedFocusedContent,\n ...unmergedKeyPath,\n };\n }, [mergedFocusedContent, localeDictionaries, currentLocale]);\n\n return {\n focusedContent,\n setFocusedContent,\n setFocusedContentKeyPath,\n };\n};\n"],"mappings":"8TAqBA,MAAM,GACJ,EACA,EACA,IACgC,CAIhC,IAAK,IAAM,KAAc,EACvB,GAAI,CAOF,GANe,EACb,EAAW,QACX,GAAW,EAAE,CACb,EACD,CAGC,MAAO,CAAE,UAAS,kBAAmB,EAAW,QAAS,MAErD,IAMC,MAAmC,CAC9C,GAAM,CAAE,sBAAuB,GAAuB,CAChD,EAAgB,GAAiB,CACjC,CACJ,oBACA,2BACA,eAAgB,GACd,GAAoB,CAuBxB,MAAO,CACL,eAtBqB,MAAkC,CAGvD,GAFI,CAAC,GACD,CAAC,GACD,EAAqB,kBAAmB,OAAO,EAEnD,IAAM,EAAe,OAAO,OAAO,EAAmB,CAAC,OACpD,GAAe,EAAW,MAAQ,EAAqB,cACzD,CAEK,EAAkB,EACtB,EAAqB,SAAW,EAAE,CAClC,EACA,EACD,CAED,MAAO,CACL,GAAG,EACH,GAAG,EACJ,EACA,CAAC,EAAsB,EAAoB,EAAc,CAAC,CAI3D,oBACA,2BACD"}
@@ -1,2 +1,2 @@
1
- "use client";import{useCrossFrameMessageListener as e}from"./useCrossFrameMessageListener.mjs";import{MessageKey as t,mergeIframeClick as n}from"@intlayer/editor";import{useEffect as r}from"react";const i=()=>{let n=e(t.INTLAYER_IFRAME_CLICKED),i=()=>{n()};r(()=>(window.addEventListener(`mousedown`,i),()=>window.removeEventListener(`mousedown`,i)),[n])},a=()=>e(t.INTLAYER_IFRAME_CLICKED,n);export{i as useIframeClickInterceptor,a as useIframeClickMerger};
1
+ "use client";import{useCrossFrameMessageListener as e}from"./useCrossFrameMessageListener.mjs";import{MessageKey as t,mergeIframeClick as n}from"@intlayer/editor";const r=()=>{e(t.INTLAYER_IFRAME_CLICKED)},i=()=>{e(t.INTLAYER_IFRAME_CLICKED,n)};export{r as useIframeClickInterceptor,i as useIframeClickMerger};
2
2
  //# sourceMappingURL=useIframeClickInterceptor.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"useIframeClickInterceptor.mjs","names":[],"sources":["../../src/useIframeClickInterceptor.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey, mergeIframeClick } from '@intlayer/editor';\nimport { useEffect } from 'react';\nimport { useCrossFrameMessageListener } from './useCrossFrameMessageListener';\n\nexport const useIframeClickInterceptor = () => {\n const postMessage = useCrossFrameMessageListener<undefined>(\n MessageKey.INTLAYER_IFRAME_CLICKED\n );\n const handlePostMessageEvent: EventListener = () => {\n postMessage();\n };\n\n useEffect(() => {\n window.addEventListener('mousedown', handlePostMessageEvent);\n\n return () =>\n window.removeEventListener('mousedown', handlePostMessageEvent);\n }, [postMessage]);\n};\n\nexport const useIframeClickMerger = () =>\n useCrossFrameMessageListener<MessageEvent>(\n MessageKey.INTLAYER_IFRAME_CLICKED,\n mergeIframeClick\n );\n"],"mappings":"qMAMA,MAAa,MAAkC,CAC7C,IAAM,EAAc,EAClB,EAAW,wBACZ,CACK,MAA8C,CAClD,GAAa,EAGf,OACE,OAAO,iBAAiB,YAAa,EAAuB,KAG1D,OAAO,oBAAoB,YAAa,EAAuB,EAChE,CAAC,EAAY,CAAC,EAGN,MACX,EACE,EAAW,wBACX,EACD"}
1
+ {"version":3,"file":"useIframeClickInterceptor.mjs","names":[],"sources":["../../src/useIframeClickInterceptor.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey, mergeIframeClick } from '@intlayer/editor';\nimport { useCrossFrameMessageListener } from './useCrossFrameMessageListener';\n\n/**\n * Broadcasts mousedown events from within an iframe to the parent frame.\n * Called in the client application (inside the iframe).\n * Note: EditorStateManager.start() already sets this up in client mode.\n * This hook exists for explicit / standalone use cases.\n */\nexport const useIframeClickInterceptor = () => {\n useCrossFrameMessageListener<undefined>(MessageKey.INTLAYER_IFRAME_CLICKED);\n};\n\n/**\n * Merges received iframe click events into the parent's DOM event stream.\n * Called in the editor (parent frame).\n */\nexport const useIframeClickMerger = () => {\n useCrossFrameMessageListener<MessageEvent>(\n MessageKey.INTLAYER_IFRAME_CLICKED,\n mergeIframeClick\n );\n};\n"],"mappings":"mKAWA,MAAa,MAAkC,CAC7C,EAAwC,EAAW,wBAAwB,EAOhE,MAA6B,CACxC,EACE,EAAW,wBACX,EACD"}
@@ -1,14 +1,15 @@
1
- import { FC, PropsWithChildren } from "react";
1
+ import { MessagePayload, MessengerConfig } from "@intlayer/editor";
2
2
 
3
3
  //#region src/CommunicatorContext.d.ts
4
4
  type UseCrossPlatformStateProps = {
5
- postMessage: typeof window.postMessage;
5
+ postMessage: (payload: MessagePayload) => void;
6
6
  allowedOrigins?: string[];
7
7
  senderId: string;
8
8
  };
9
- type CommunicatorProviderProps = PropsWithChildren<Omit<UseCrossPlatformStateProps, 'senderId'>>;
10
- declare const CommunicatorProvider: FC<CommunicatorProviderProps>;
9
+ /**
10
+ * Returns the communicator API backed by the shared EditorStateManager messenger.
11
+ */
11
12
  declare const useCommunicator: () => UseCrossPlatformStateProps;
12
13
  //#endregion
13
- export { CommunicatorProvider, CommunicatorProviderProps, UseCrossPlatformStateProps, useCommunicator };
14
+ export { type MessengerConfig, UseCrossPlatformStateProps, useCommunicator };
14
15
  //# sourceMappingURL=CommunicatorContext.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CommunicatorContext.d.ts","names":[],"sources":["../../src/CommunicatorContext.tsx"],"mappings":";;;KAcY,0BAAA;EACV,WAAA,SAAoB,MAAA,CAAO,WAAA;EAC3B,cAAA;EACA,QAAA;AAAA;AAAA,KAeU,yBAAA,GAA4B,iBAAA,CACtC,IAAA,CAAK,0BAAA;AAAA,cAGM,oBAAA,EAAsB,EAAA,CAAG,yBAAA;AAAA,cAoBzB,eAAA,QAAe,0BAAA"}
1
+ {"version":3,"file":"CommunicatorContext.d.ts","names":[],"sources":["../../src/CommunicatorContext.tsx"],"mappings":";;;KAKY,0BAAA;EACV,WAAA,GAAc,OAAA,EAAS,cAAA;EACvB,cAAA;EACA,QAAA;AAAA;;;;cAMW,eAAA,QAAsB,0BAAA"}
@@ -3,12 +3,12 @@ import { FC, PropsWithChildren } from "react";
3
3
  import { IntlayerConfig } from "@intlayer/types/config";
4
4
 
5
5
  //#region src/ConfigurationContext.d.ts
6
- declare const useConfigurationState: () => [IntlayerConfig, react.Dispatch<react.SetStateAction<IntlayerConfig>>, () => void];
7
- type ConfigurationProviderProps = {
6
+ type ConfigurationProviderProps = PropsWithChildren<{
8
7
  configuration?: IntlayerConfig;
9
- };
10
- declare const ConfigurationProvider: FC<PropsWithChildren<ConfigurationProviderProps>>;
11
- declare const useConfiguration: () => IntlayerConfig;
8
+ }>;
9
+ declare const ConfigurationProvider: FC<ConfigurationProviderProps>;
10
+ declare const useConfiguration: () => IntlayerConfig | undefined;
11
+ declare const useConfigurationState: () => readonly [IntlayerConfig, react.Dispatch<react.SetStateAction<IntlayerConfig>>, () => void];
12
12
  //#endregion
13
13
  export { ConfigurationProvider, ConfigurationProviderProps, useConfiguration, useConfigurationState };
14
14
  //# sourceMappingURL=ConfigurationContext.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ConfigurationContext.d.ts","names":[],"sources":["../../src/ConfigurationContext.tsx"],"mappings":";;;;;cAgBa,qBAAA,SAAqB,cAAA,EAAA,KAAA,CAAA,QAAA,CAAA,KAAA,CAAA,cAAA,CAAA,cAAA;AAAA,KAUtB,0BAAA;EACV,aAAA,GAAgB,cAAA;AAAA;AAAA,cAGL,qBAAA,EAAuB,EAAA,CAClC,iBAAA,CAAkB,0BAAA;AAAA,cAOP,gBAAA,QAAgB,cAAA"}
1
+ {"version":3,"file":"ConfigurationContext.d.ts","names":[],"sources":["../../src/ConfigurationContext.tsx"],"mappings":";;;;;KAMY,0BAAA,GAA6B,iBAAA;EACvC,aAAA,GAAgB,cAAA;AAAA;AAAA,cAGL,qBAAA,EAAuB,EAAA,CAAG,0BAAA;AAAA,cAe1B,gBAAA,QAAuB,cAAA;AAAA,cAkBvB,qBAAA,kBAAqB,cAAA,EAAA,KAAA,CAAA,QAAA,CAAA,KAAA,CAAA,cAAA,CAAA,cAAA"}
@@ -1,19 +1,16 @@
1
- import { Dispatch, FC, PropsWithChildren, SetStateAction } from "react";
2
- import { Dictionary, LocalDictionaryId } from "@intlayer/types/dictionary";
1
+ import { DictionaryContent, DictionaryContent as DictionaryContent$1 } from "@intlayer/editor";
2
+ import { Dictionary } from "@intlayer/types/dictionary";
3
3
 
4
4
  //#region src/DictionariesRecordContext.d.ts
5
- type DictionaryContent = Record<LocalDictionaryId, Dictionary>;
5
+ type DictionariesRecordStatesContextType = {
6
+ localeDictionaries: DictionaryContent$1;
7
+ };
6
8
  type DictionariesRecordActionsContextType = {
7
- setLocaleDictionaries: Dispatch<SetStateAction<DictionaryContent>>;
9
+ setLocaleDictionaries: (value: DictionaryContent$1) => void;
8
10
  setLocaleDictionary: (dictionary: Dictionary) => void;
9
11
  };
10
- declare const DictionariesRecordProvider: FC<PropsWithChildren>;
12
+ declare const useDictionariesRecord: () => DictionariesRecordStatesContextType & DictionariesRecordActionsContextType;
11
13
  declare const useDictionariesRecordActions: () => DictionariesRecordActionsContextType;
12
- declare const useDictionariesRecord: () => {
13
- setLocaleDictionaries: Dispatch<SetStateAction<DictionaryContent>>;
14
- setLocaleDictionary: (dictionary: Dictionary) => void;
15
- localeDictionaries: DictionaryContent;
16
- };
17
14
  //#endregion
18
- export { DictionariesRecordProvider, DictionaryContent, useDictionariesRecord, useDictionariesRecordActions };
15
+ export { type DictionaryContent, useDictionariesRecord, useDictionariesRecordActions };
19
16
  //# sourceMappingURL=DictionariesRecordContext.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DictionariesRecordContext.d.ts","names":[],"sources":["../../src/DictionariesRecordContext.tsx"],"mappings":";;;;KAeY,iBAAA,GAAoB,MAAA,CAAO,iBAAA,EAAmB,UAAA;AAAA,KAKrD,oCAAA;EACH,qBAAA,EAAuB,QAAA,CAAS,cAAA,CAAe,iBAAA;EAC/C,mBAAA,GAAsB,UAAA,EAAY,UAAA;AAAA;AAAA,cAUvB,0BAAA,EAA4B,EAAA,CAAG,iBAAA;AAAA,cAwC/B,4BAAA,QAA4B,oCAAA;AAAA,cAG5B,qBAAA;yBAtDY,QAAA,CAAS,cAAA,CAAe,iBAAA;wBACzB,UAAA,EAAY,UAAA;sBAJd,iBAAA;AAAA"}
1
+ {"version":3,"file":"DictionariesRecordContext.d.ts","names":[],"sources":["../../src/DictionariesRecordContext.tsx"],"mappings":";;;;KASK,mCAAA;EACH,kBAAA,EAAoB,mBAAA;AAAA;AAAA,KAEjB,oCAAA;EACH,qBAAA,GAAwB,KAAA,EAAO,mBAAA;EAC/B,mBAAA,GAAsB,UAAA,EAAY,UAAA;AAAA;AAAA,cAGvB,qBAAA,QAA4B,mCAAA,GACvC,oCAAA;AAAA,cAgCW,4BAAA,QACP,oCAAA"}
@@ -1,14 +1,11 @@
1
- import { DictionaryContent } from "./DictionariesRecordContext.js";
2
- import { Dispatch, FC, PropsWithChildren, SetStateAction } from "react";
1
+ import { DictionaryContent, DictionaryContent as DictionaryContent$1 } from "@intlayer/editor";
3
2
  import { ContentNode, Dictionary, LocalDictionaryId } from "@intlayer/types/dictionary";
4
3
  import { KeyPath } from "@intlayer/types/keyPath";
5
4
 
6
5
  //#region src/EditedContentContext.d.ts
7
- declare const usePostEditedContentState: <S>(onEventTriggered?: (data: S) => void) => (data?: S) => void;
8
- declare const useGetEditedContentState: <S>(onEventTriggered?: (data: S) => void) => (data?: S) => void;
9
6
  type EditedContentActionsContextType = {
10
- setEditedContentState: (editedContent: DictionaryContent) => void;
11
- setEditedDictionary: Dispatch<SetStateAction<Dictionary>>;
7
+ setEditedContentState: (editedContent: DictionaryContent$1) => void;
8
+ setEditedDictionary: (dict: Dictionary) => void;
12
9
  setEditedContent: (localDictionaryId: LocalDictionaryId, newValue: Dictionary['content']) => void;
13
10
  addEditedContent: (localDictionaryId: LocalDictionaryId, newValue: ContentNode<any>, keyPath?: KeyPath[], overwrite?: boolean) => void;
14
11
  renameEditedContent: (localDictionaryId: LocalDictionaryId, newKey: KeyPath['key'], keyPath?: KeyPath[]) => void;
@@ -18,11 +15,10 @@ type EditedContentActionsContextType = {
18
15
  clearEditedContent: () => void;
19
16
  getEditedContentValue: (localDictionaryIdOrKey: LocalDictionaryId | Dictionary['key'] | string, keyPath: KeyPath[]) => ContentNode | undefined;
20
17
  };
21
- declare const EditedContentProvider: FC<PropsWithChildren>;
22
18
  declare const useEditedContentActions: () => EditedContentActionsContextType;
23
19
  declare const useEditedContent: () => {
24
- setEditedContentState: (editedContent: DictionaryContent) => void;
25
- setEditedDictionary: Dispatch<SetStateAction<Dictionary>>;
20
+ setEditedContentState: (editedContent: DictionaryContent$1) => void;
21
+ setEditedDictionary: (dict: Dictionary) => void;
26
22
  setEditedContent: (localDictionaryId: LocalDictionaryId, newValue: Dictionary["content"]) => void;
27
23
  addEditedContent: (localDictionaryId: LocalDictionaryId, newValue: ContentNode<any>, keyPath?: KeyPath[], overwrite?: boolean) => void;
28
24
  renameEditedContent: (localDictionaryId: LocalDictionaryId, newKey: KeyPath["key"], keyPath?: KeyPath[]) => void;
@@ -31,8 +27,10 @@ declare const useEditedContent: () => {
31
27
  clearEditedDictionaryContent: (localDictionaryId: LocalDictionaryId) => void;
32
28
  clearEditedContent: () => void;
33
29
  getEditedContentValue: (localDictionaryIdOrKey: LocalDictionaryId | Dictionary["key"] | string, keyPath: KeyPath[]) => ContentNode | undefined;
34
- editedContent: Record<LocalDictionaryId, Dictionary> | undefined;
30
+ editedContent: DictionaryContent$1;
35
31
  };
32
+ declare const usePostEditedContentState: <S>(onEventTriggered?: (data: S) => void) => void;
33
+ declare const useGetEditedContentState: () => () => void;
36
34
  //#endregion
37
- export { EditedContentProvider, useEditedContent, useEditedContentActions, useGetEditedContentState, usePostEditedContentState };
35
+ export { type DictionaryContent, useEditedContent, useEditedContentActions, useGetEditedContentState, usePostEditedContentState };
38
36
  //# sourceMappingURL=EditedContentContext.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EditedContentContext.d.ts","names":[],"sources":["../../src/EditedContentContext.tsx"],"mappings":";;;;;;cAmCa,yBAAA,MACX,gBAAA,IAAoB,IAAA,EAAM,CAAA,eAAU,IAAA,GAAA,CAAA;AAAA,cAOzB,wBAAA,MACX,gBAAA,IAAoB,IAAA,EAAM,CAAA,eAAU,IAAA,GAAA,CAAA;AAAA,KAOjC,+BAAA;EACH,qBAAA,GAAwB,aAAA,EAAe,iBAAA;EACvC,mBAAA,EAAqB,QAAA,CAAS,cAAA,CAAe,UAAA;EAC7C,gBAAA,GACE,iBAAA,EAAmB,iBAAA,EACnB,QAAA,EAAU,UAAA;EAEZ,gBAAA,GACE,iBAAA,EAAmB,iBAAA,EACnB,QAAA,EAAU,WAAA,OACV,OAAA,GAAU,OAAA,IACV,SAAA;EAEF,mBAAA,GACE,iBAAA,EAAmB,iBAAA,EACnB,MAAA,EAAQ,OAAA,SACR,OAAA,GAAU,OAAA;EAEZ,mBAAA,GACE,iBAAA,EAAmB,iBAAA,EACnB,OAAA,EAAS,OAAA;EAEX,oBAAA,GAAuB,iBAAA,EAAmB,iBAAA;EAC1C,4BAAA,GAA+B,iBAAA,EAAmB,iBAAA;EAClD,kBAAA;EACA,qBAAA,GACE,sBAAA,EAAwB,iBAAA,GAAoB,UAAA,kBAC5C,OAAA,EAAS,OAAA,OACN,WAAA;AAAA;AAAA,cAYM,qBAAA,EAAuB,EAAA,CAAG,iBAAA;AAAA,cAgQ1B,uBAAA,QAAuB,+BAAA;AAAA,cAGvB,gBAAA;0BA1Sa,aAAA,EAAe,iBAAA;uBAClB,QAAA,CAAS,cAAA,CAAe,UAAA;qBAE3C,iBAAA,EAAmB,iBAAA,EACnB,QAAA,EAAU,UAAA;qBAGV,iBAAA,EAAmB,iBAAA,EACnB,QAAA,EAAU,WAAA,OACV,OAAA,GAAU,OAAA,IACV,SAAA;wBAGA,iBAAA,EAAmB,iBAAA,EACnB,MAAA,EAAQ,OAAA,SACR,OAAA,GAAU,OAAA;wBAGV,iBAAA,EAAmB,iBAAA,EACnB,OAAA,EAAS,OAAA;yBAEY,iBAAA,EAAmB,iBAAA;iCACX,iBAAA,EAAmB,iBAAA;;0BAGhD,sBAAA,EAAwB,iBAAA,GAAoB,UAAA,kBAC5C,OAAA,EAAS,OAAA,OACN,WAAA;iBAnDU,MAAA,CAAO,iBAAA,EAAmB,UAAA;AAAA"}
1
+ {"version":3,"file":"EditedContentContext.d.ts","names":[],"sources":["../../src/EditedContentContext.tsx"],"mappings":";;;;;KAcK,+BAAA;EACH,qBAAA,GAAwB,aAAA,EAAe,mBAAA;EACvC,mBAAA,GAAsB,IAAA,EAAM,UAAA;EAC5B,gBAAA,GACE,iBAAA,EAAmB,iBAAA,EACnB,QAAA,EAAU,UAAA;EAEZ,gBAAA,GACE,iBAAA,EAAmB,iBAAA,EACnB,QAAA,EAAU,WAAA,OACV,OAAA,GAAU,OAAA,IACV,SAAA;EAEF,mBAAA,GACE,iBAAA,EAAmB,iBAAA,EACnB,MAAA,EAAQ,OAAA,SACR,OAAA,GAAU,OAAA;EAEZ,mBAAA,GACE,iBAAA,EAAmB,iBAAA,EACnB,OAAA,EAAS,OAAA;EAEX,oBAAA,GAAuB,iBAAA,EAAmB,iBAAA;EAC1C,4BAAA,GAA+B,iBAAA,EAAmB,iBAAA;EAClD,kBAAA;EACA,qBAAA,GACE,sBAAA,EAAwB,iBAAA,GAAoB,UAAA,kBAC5C,OAAA,EAAS,OAAA,OACN,WAAA;AAAA;AAAA,cAGM,uBAAA,QAA8B,+BAAA;AAAA,cA0B9B,gBAAA;0BAxDa,aAAA,EAAe,mBAAA;wBACjB,IAAA,EAAM,UAAA;qBAE1B,iBAAA,EAAmB,iBAAA,EACnB,QAAA,EAAU,UAAA;qBAGV,iBAAA,EAAmB,iBAAA,EACnB,QAAA,EAAU,WAAA,OACV,OAAA,GAAU,OAAA,IACV,SAAA;wBAGA,iBAAA,EAAmB,iBAAA,EACnB,MAAA,EAAQ,OAAA,SACR,OAAA,GAAU,OAAA;wBAGV,iBAAA,EAAmB,iBAAA,EACnB,OAAA,EAAS,OAAA;yBAEY,iBAAA,EAAmB,iBAAA;iCACX,iBAAA,EAAmB,iBAAA;;0BAGhD,sBAAA,EAAwB,iBAAA,GAAoB,UAAA,kBAC5C,OAAA,EAAS,OAAA,OACN,WAAA;;;cA+CM,yBAAA,MACX,gBAAA,IAAoB,IAAA,EAAM,CAAA;AAAA,cAYf,wBAAA"}
@@ -1,16 +1,28 @@
1
- import { CrossFrameStateOptions } from "./useCrossFrameState.js";
2
- import * as react from "react";
3
- import { FC, PropsWithChildren } from "react";
4
-
5
1
  //#region src/EditorEnabledContext.d.ts
6
2
  type EditorEnabledStateProps = {
7
3
  enabled: boolean;
8
4
  };
9
- declare const useEditorEnabledState: (options?: CrossFrameStateOptions) => [boolean, react.Dispatch<react.SetStateAction<boolean>>, () => void];
10
- declare const usePostEditorEnabledState: <S>(onEventTriggered?: (data: S) => void) => (data?: S) => void;
11
- declare const useGetEditorEnabledState: <S>(onEventTriggered?: (data: S) => void) => (data?: S) => void;
12
- declare const EditorEnabledProvider: FC<PropsWithChildren>;
5
+ /**
6
+ * Returns the current editor-enabled state, kept in sync with the shared
7
+ * EditorStateManager. Replaces the old EditorEnabledContext + EditorEnabledProvider.
8
+ */
13
9
  declare const useEditorEnabled: () => EditorEnabledStateProps;
10
+ /**
11
+ * Subscribes to incoming "get" requests for editor-enabled state and calls
12
+ * the provided callback so the caller can respond.
13
+ * Used by the editor side to respond when the client asks for the current state.
14
+ */
15
+ declare const useGetEditorEnabledState: (onRequest?: () => void) => void;
16
+ /**
17
+ * Returns a function that sets the editor-enabled state and broadcasts it.
18
+ */
19
+ declare const usePostEditorEnabledState: () => (value: boolean) => void;
20
+ declare const useEditorEnabledState: () => readonly [boolean, (value: boolean) => void];
21
+ /**
22
+ * Returns a function that re-pings the client via ARE_YOU_THERE.
23
+ * Use this as the onClick for an "Enable Editor" / reconnect button.
24
+ */
25
+ declare const useEditorPingClient: () => (() => void);
14
26
  //#endregion
15
- export { EditorEnabledProvider, EditorEnabledStateProps, useEditorEnabled, useEditorEnabledState, useGetEditorEnabledState, usePostEditorEnabledState };
27
+ export { EditorEnabledStateProps, useEditorEnabled, useEditorEnabledState, useEditorPingClient, useGetEditorEnabledState, usePostEditorEnabledState };
16
28
  //# sourceMappingURL=EditorEnabledContext.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EditorEnabledContext.d.ts","names":[],"sources":["../../src/EditorEnabledContext.tsx"],"mappings":";;;;;KAeY,uBAAA;EACV,OAAA;AAAA;AAAA,cAOW,qBAAA,GAAyB,OAAA,GAAU,sBAAA,eAAsB,KAAA,CAAA,QAAA,CAAA,KAAA,CAAA,cAAA;AAAA,cAGzD,yBAAA,MACX,gBAAA,IAAoB,IAAA,EAAM,CAAA,eAAU,IAAA,GAAA,CAAA;AAAA,cAOzB,wBAAA,MACX,gBAAA,IAAoB,IAAA,EAAM,CAAA,eAAU,IAAA,GAAA,CAAA;AAAA,cAOzB,qBAAA,EAAuB,EAAA,CAAG,iBAAA;AAAA,cAa1B,gBAAA,QAAgB,uBAAA"}
1
+ {"version":3,"file":"EditorEnabledContext.d.ts","names":[],"sources":["../../src/EditorEnabledContext.tsx"],"mappings":";KAMY,uBAAA;EACV,OAAA;AAAA;;;;AAOF;cAAa,gBAAA,QAAuB,uBAAA;;;;AAuBpC;;cAAa,wBAAA,GAA4B,SAAA;;;AAgBzC;cAAa,yBAAA,SAGH,KAAA;AAAA,cAMG,qBAAA,4BAAqB,KAAA;;;AAAlC;;cAYa,mBAAA"}
@@ -1,11 +1,16 @@
1
- import { CommunicatorProviderProps } from "./CommunicatorContext.js";
2
- import { ConfigurationProviderProps } from "./ConfigurationContext.js";
3
1
  import { FC, PropsWithChildren } from "react";
2
+ import { IntlayerConfig } from "@intlayer/types/config";
4
3
 
5
4
  //#region src/EditorProvider.d.ts
6
- type EditorProviderProps = CommunicatorProviderProps & ConfigurationProviderProps & {
7
- mode: 'editor' | 'client';
5
+ type EditorProviderProps = {
6
+ configuration: IntlayerConfig;
7
+ postMessage: (data: any) => void;
8
+ allowedOrigins: string[];
8
9
  };
10
+ /**
11
+ * EditorProvider creates and manages the lifecycle of an EditorStateManager,
12
+ * provides it to all descendants, and registers the Lit web components.
13
+ */
9
14
  declare const EditorProvider: FC<PropsWithChildren<EditorProviderProps>>;
10
15
  //#endregion
11
16
  export { EditorProvider, EditorProviderProps };