@intlayer/editor-react 8.1.2 → 8.1.3-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 (57) hide show
  1. package/dist/cjs/CommunicatorContext.cjs +1 -42
  2. package/dist/cjs/CommunicatorContext.cjs.map +1 -1
  3. package/dist/cjs/ConfigurationContext.cjs +1 -25
  4. package/dist/cjs/ConfigurationContext.cjs.map +1 -1
  5. package/dist/cjs/DictionariesRecordContext.cjs +1 -48
  6. package/dist/cjs/DictionariesRecordContext.cjs.map +1 -1
  7. package/dist/cjs/EditedContentContext.cjs +1 -169
  8. package/dist/cjs/EditedContentContext.cjs.map +1 -1
  9. package/dist/cjs/EditorEnabledContext.cjs +1 -33
  10. package/dist/cjs/EditorEnabledContext.cjs.map +1 -1
  11. package/dist/cjs/EditorProvider.cjs +1 -67
  12. package/dist/cjs/EditorProvider.cjs.map +1 -1
  13. package/dist/cjs/FocusDictionaryContext.cjs +1 -55
  14. package/dist/cjs/FocusDictionaryContext.cjs.map +1 -1
  15. package/dist/cjs/_virtual/_rolldown/runtime.cjs +1 -29
  16. package/dist/cjs/index.cjs +1 -53
  17. package/dist/cjs/useCrossFrameMessageListener.cjs +1 -78
  18. package/dist/cjs/useCrossFrameMessageListener.cjs.map +1 -1
  19. package/dist/cjs/useCrossFrameState.cjs +1 -108
  20. package/dist/cjs/useCrossFrameState.cjs.map +1 -1
  21. package/dist/cjs/useCrossURLPathState.cjs +1 -67
  22. package/dist/cjs/useCrossURLPathState.cjs.map +1 -1
  23. package/dist/cjs/useEditorLocale.cjs +1 -23
  24. package/dist/cjs/useEditorLocale.cjs.map +1 -1
  25. package/dist/cjs/useFocusUnmergedDictionary.cjs +1 -51
  26. package/dist/cjs/useFocusUnmergedDictionary.cjs.map +1 -1
  27. package/dist/cjs/useIframeClickInterceptor.cjs +1 -24
  28. package/dist/cjs/useIframeClickInterceptor.cjs.map +1 -1
  29. package/dist/esm/CommunicatorContext.mjs +1 -38
  30. package/dist/esm/CommunicatorContext.mjs.map +1 -1
  31. package/dist/esm/ConfigurationContext.mjs +1 -21
  32. package/dist/esm/ConfigurationContext.mjs.map +1 -1
  33. package/dist/esm/DictionariesRecordContext.mjs +1 -44
  34. package/dist/esm/DictionariesRecordContext.mjs.map +1 -1
  35. package/dist/esm/EditedContentContext.mjs +1 -163
  36. package/dist/esm/EditedContentContext.mjs.map +1 -1
  37. package/dist/esm/EditorEnabledContext.mjs +1 -27
  38. package/dist/esm/EditorEnabledContext.mjs.map +1 -1
  39. package/dist/esm/EditorProvider.mjs +1 -65
  40. package/dist/esm/EditorProvider.mjs.map +1 -1
  41. package/dist/esm/FocusDictionaryContext.mjs +1 -51
  42. package/dist/esm/FocusDictionaryContext.mjs.map +1 -1
  43. package/dist/esm/index.mjs +1 -17
  44. package/dist/esm/useCrossFrameMessageListener.mjs +1 -76
  45. package/dist/esm/useCrossFrameMessageListener.mjs.map +1 -1
  46. package/dist/esm/useCrossFrameState.mjs +1 -106
  47. package/dist/esm/useCrossFrameState.mjs.map +1 -1
  48. package/dist/esm/useCrossURLPathState.mjs +1 -64
  49. package/dist/esm/useCrossURLPathState.mjs.map +1 -1
  50. package/dist/esm/useEditorLocale.mjs +1 -20
  51. package/dist/esm/useEditorLocale.mjs.map +1 -1
  52. package/dist/esm/useFocusUnmergedDictionary.mjs +1 -49
  53. package/dist/esm/useFocusUnmergedDictionary.mjs.map +1 -1
  54. package/dist/esm/useIframeClickInterceptor.mjs +1 -21
  55. package/dist/esm/useIframeClickInterceptor.mjs.map +1 -1
  56. package/dist/types/EditedContentContext.d.ts.map +1 -1
  57. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"FocusDictionaryContext.cjs","names":["useCrossFrameState","MessageKey","NodeType"],"sources":["../../src/FocusDictionaryContext.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey } from '@intlayer/editor';\nimport {\n type KeyPath,\n type LocalDictionaryId,\n NodeType,\n} from '@intlayer/types';\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":";;;;;;;;;;;AAiCA,MAAM,uDAEJ,OAAU;AACZ,MAAM,yDAEJ,OAAU;AAEZ,MAAa,2BAAkD,EAC7D,eACI;CACJ,MAAM,CAAC,gBAAgB,qBACrBA,8CACEC,4BAAW,kCACX,KACD;CAEH,MAAM,4BAA4B,YAAuB;AACvD,qBAAmB,SAAS;AAC1B,OAAI,CAAC,KACH,QAAO;GAIT,MAAM,kBAAkB,QAAQ,QAC7B,QAAQ,IAAI,SAASC,yBAAS,YAChC;AAED,UAAO;IACL,GAAG;IACH,SAAS;IACV;IACD;;AAGJ,QACE,2CAAC,4BAA4B;EAAS,OAAO,EAAE,gBAAgB;YAC7D,2CAAC,8BAA8B;GAC7B,OAAO;IAAE;IAAmB;IAA0B;GAErD;IACsC;GACJ;;AAI3C,MAAa,kCAAkC;CAC7C,MAAM,gCAAqB,8BAA8B;AACzD,KAAI,YAAY,OACd,OAAM,IAAI,MACR,0EACD;AAEH,QAAO;;AAGT,MAAa,2BAA2B;CACtC,MAAM,gBAAgB,2BAA2B;CACjD,MAAM,qCAA0B,4BAA4B;AAE5D,KAAI,iBAAiB,OACnB,OAAM,IAAI,MACR,wEACD;AAGH,QAAO;EAAE,GAAG;EAAc,GAAG;EAAe"}
1
+ {"version":3,"file":"FocusDictionaryContext.cjs","names":["useCrossFrameState","MessageKey","NodeType"],"sources":["../../src/FocusDictionaryContext.tsx"],"sourcesContent":["'use client';\n\nimport { MessageKey } from '@intlayer/editor';\nimport {\n type KeyPath,\n type LocalDictionaryId,\n NodeType,\n} from '@intlayer/types';\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":"yRAiCA,MAAM,GAAA,EAAA,EAAA,eAEJ,IAAA,GAAU,CACN,GAAA,EAAA,EAAA,eAEJ,IAAA,GAAU,CAEC,GAAkD,CAC7D,cACI,CACJ,GAAM,CAAC,EAAgB,GACrBA,EAAAA,mBACEC,EAAAA,WAAW,iCACX,KACD,CAoBH,OACE,EAAA,EAAA,KAAC,EAA4B,SAAA,CAAS,MAAO,CAAE,iBAAgB,WAC7D,EAAA,EAAA,KAAC,EAA8B,SAAA,CAC7B,MAAO,CAAE,oBAAmB,yBArBA,GAAuB,CACvD,EAAmB,GAAS,CAC1B,GAAI,CAAC,EACH,OAAO,EAIT,IAAM,EAAkB,EAAQ,OAC7B,GAAQ,EAAI,OAASC,EAAAA,SAAS,YAChC,CAED,MAAO,CACL,GAAG,EACH,QAAS,EACV,EACD,EAMwD,CAErD,YACsC,EACJ,EAI9B,MAAkC,CAC7C,IAAM,GAAA,EAAA,EAAA,YAAqB,EAA8B,CACzD,GAAI,IAAY,IAAA,GACd,MAAU,MACR,0EACD,CAEH,OAAO,GAGI,MAA2B,CACtC,IAAM,EAAgB,GAA2B,CAC3C,GAAA,EAAA,EAAA,YAA0B,EAA4B,CAE5D,GAAI,IAAiB,IAAA,GACnB,MAAU,MACR,wEACD,CAGH,MAAO,CAAE,GAAG,EAAc,GAAG,EAAe"}
@@ -1,29 +1 @@
1
- //#region \0rolldown/runtime.js
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __copyProps = (to, from, except, desc) => {
9
- if (from && typeof from === "object" || typeof from === "function") {
10
- for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
- key = keys[i];
12
- if (!__hasOwnProp.call(to, key) && key !== except) {
13
- __defProp(to, key, {
14
- get: ((k) => from[k]).bind(null, key),
15
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
- });
17
- }
18
- }
19
- }
20
- return to;
21
- };
22
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
- value: mod,
24
- enumerable: true
25
- }) : target, mod));
26
-
27
- //#endregion
28
-
29
- exports.__toESM = __toESM;
1
+ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));exports.__toESM=s;
@@ -1,53 +1 @@
1
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_CommunicatorContext = require('./CommunicatorContext.cjs');
3
- const require_useCrossFrameMessageListener = require('./useCrossFrameMessageListener.cjs');
4
- const require_useCrossFrameState = require('./useCrossFrameState.cjs');
5
- const require_ConfigurationContext = require('./ConfigurationContext.cjs');
6
- const require_DictionariesRecordContext = require('./DictionariesRecordContext.cjs');
7
- const require_useEditorLocale = require('./useEditorLocale.cjs');
8
- const require_EditedContentContext = require('./EditedContentContext.cjs');
9
- const require_EditorEnabledContext = require('./EditorEnabledContext.cjs');
10
- const require_FocusDictionaryContext = require('./FocusDictionaryContext.cjs');
11
- const require_EditorProvider = require('./EditorProvider.cjs');
12
- const require_useCrossURLPathState = require('./useCrossURLPathState.cjs');
13
- const require_useFocusUnmergedDictionary = require('./useFocusUnmergedDictionary.cjs');
14
- const require_useIframeClickInterceptor = require('./useIframeClickInterceptor.cjs');
15
-
16
- exports.CommunicatorProvider = require_CommunicatorContext.CommunicatorProvider;
17
- exports.ConfigurationProvider = require_ConfigurationContext.ConfigurationProvider;
18
- exports.DictionariesRecordProvider = require_DictionariesRecordContext.DictionariesRecordProvider;
19
- exports.EditedContentProvider = require_EditedContentContext.EditedContentProvider;
20
- exports.EditorEnabledProvider = require_EditorEnabledContext.EditorEnabledProvider;
21
- exports.EditorProvider = require_EditorProvider.EditorProvider;
22
- exports.FocusDictionaryProvider = require_FocusDictionaryContext.FocusDictionaryProvider;
23
- exports.useCommunicator = require_CommunicatorContext.useCommunicator;
24
- exports.useConfiguration = require_ConfigurationContext.useConfiguration;
25
- exports.useConfigurationState = require_ConfigurationContext.useConfigurationState;
26
- exports.useCrossFrameMessageListener = require_useCrossFrameMessageListener.useCrossFrameMessageListener;
27
- exports.useCrossFrameState = require_useCrossFrameState.useCrossFrameState;
28
- exports.useCrossURLPathSetter = require_useCrossURLPathState.useCrossURLPathSetter;
29
- exports.useCrossURLPathState = require_useCrossURLPathState.useCrossURLPathState;
30
- exports.useDictionariesRecord = require_DictionariesRecordContext.useDictionariesRecord;
31
- exports.useDictionariesRecordActions = require_DictionariesRecordContext.useDictionariesRecordActions;
32
- exports.useEditedContent = require_EditedContentContext.useEditedContent;
33
- exports.useEditedContentActions = require_EditedContentContext.useEditedContentActions;
34
- exports.useEditorEnabled = require_EditorEnabledContext.useEditorEnabled;
35
- exports.useEditorEnabledState = require_EditorEnabledContext.useEditorEnabledState;
36
- exports.useEditorLocale = require_useEditorLocale.useEditorLocale;
37
- exports.useFocusDictionary = require_FocusDictionaryContext.useFocusDictionary;
38
- exports.useFocusDictionaryActions = require_FocusDictionaryContext.useFocusDictionaryActions;
39
- exports.useFocusUnmergedDictionary = require_useFocusUnmergedDictionary.useFocusUnmergedDictionary;
40
- exports.useGetEditedContentState = require_EditedContentContext.useGetEditedContentState;
41
- exports.useGetEditorEnabledState = require_EditorEnabledContext.useGetEditorEnabledState;
42
- exports.useIframeClickInterceptor = require_useIframeClickInterceptor.useIframeClickInterceptor;
43
- exports.useIframeClickMerger = require_useIframeClickInterceptor.useIframeClickMerger;
44
- exports.usePostEditedContentState = require_EditedContentContext.usePostEditedContentState;
45
- exports.usePostEditorEnabledState = require_EditorEnabledContext.usePostEditorEnabledState;
46
- exports.useSetEditorLocale = require_useEditorLocale.useSetEditorLocale;
47
- var _intlayer_editor = require("@intlayer/editor");
48
- Object.keys(_intlayer_editor).forEach(function (k) {
49
- if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
50
- enumerable: true,
51
- get: function () { return _intlayer_editor[k]; }
52
- });
53
- });
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./CommunicatorContext.cjs`),t=require(`./useCrossFrameMessageListener.cjs`),n=require(`./useCrossFrameState.cjs`),r=require(`./ConfigurationContext.cjs`),i=require(`./DictionariesRecordContext.cjs`),a=require(`./useEditorLocale.cjs`),o=require(`./EditedContentContext.cjs`),s=require(`./EditorEnabledContext.cjs`),c=require(`./FocusDictionaryContext.cjs`),l=require(`./EditorProvider.cjs`),u=require(`./useCrossURLPathState.cjs`),d=require(`./useFocusUnmergedDictionary.cjs`),f=require(`./useIframeClickInterceptor.cjs`);exports.CommunicatorProvider=e.CommunicatorProvider,exports.ConfigurationProvider=r.ConfigurationProvider,exports.DictionariesRecordProvider=i.DictionariesRecordProvider,exports.EditedContentProvider=o.EditedContentProvider,exports.EditorEnabledProvider=s.EditorEnabledProvider,exports.EditorProvider=l.EditorProvider,exports.FocusDictionaryProvider=c.FocusDictionaryProvider,exports.useCommunicator=e.useCommunicator,exports.useConfiguration=r.useConfiguration,exports.useConfigurationState=r.useConfigurationState,exports.useCrossFrameMessageListener=t.useCrossFrameMessageListener,exports.useCrossFrameState=n.useCrossFrameState,exports.useCrossURLPathSetter=u.useCrossURLPathSetter,exports.useCrossURLPathState=u.useCrossURLPathState,exports.useDictionariesRecord=i.useDictionariesRecord,exports.useDictionariesRecordActions=i.useDictionariesRecordActions,exports.useEditedContent=o.useEditedContent,exports.useEditedContentActions=o.useEditedContentActions,exports.useEditorEnabled=s.useEditorEnabled,exports.useEditorEnabledState=s.useEditorEnabledState,exports.useEditorLocale=a.useEditorLocale,exports.useFocusDictionary=c.useFocusDictionary,exports.useFocusDictionaryActions=c.useFocusDictionaryActions,exports.useFocusUnmergedDictionary=d.useFocusUnmergedDictionary,exports.useGetEditedContentState=o.useGetEditedContentState,exports.useGetEditorEnabledState=s.useGetEditorEnabledState,exports.useIframeClickInterceptor=f.useIframeClickInterceptor,exports.useIframeClickMerger=f.useIframeClickMerger,exports.usePostEditedContentState=o.usePostEditedContentState,exports.usePostEditorEnabledState=s.usePostEditorEnabledState,exports.useSetEditorLocale=a.useSetEditorLocale;var p=require(`@intlayer/editor`);Object.keys(p).forEach(function(e){e!==`default`&&!Object.prototype.hasOwnProperty.call(exports,e)&&Object.defineProperty(exports,e,{enumerable:!0,get:function(){return p[e]}})});
@@ -1,79 +1,2 @@
1
- 'use client';
2
-
3
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
- const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
5
- const require_CommunicatorContext = require('./CommunicatorContext.cjs');
6
- let react = require("react");
7
- let _intlayer_editor = require("@intlayer/editor");
8
-
9
- //#region src/useCrossFrameMessageListener.tsx
10
- /**
11
- * useCrossFrameMessageListener
12
- *
13
- * This React hook listens for messages sent via the `postMessage` API and triggers a callback
14
- * whenever a message of the specified type (`key`) is received. It is useful for synchronizing
15
- * state or events across different windows, iframes, or contexts.
16
- *
17
- * @template S - The type of the data payload in the message.
18
- * @param key - A unique identifier for the message type to listen for.
19
- * @param [onEventTriggered] - A callback function triggered when a message
20
- * @param [revalidator] - A function that re-suscribes the listener. Could be usefull if onEventTriggered depend of some state
21
- * with the specified key is received. The callback receives the message data as its argument.
22
- *
23
- * @returns {{ postMessage: (data: S) => void }} An object containing a `postMessage` function
24
- * that allows broadcasting messages with the specified key and data.
25
- */
26
- const useCrossFrameMessageListener = (key, onEventTriggered, revalidator) => {
27
- const { allowedOrigins, postMessage, senderId } = require_CommunicatorContext.useCommunicator();
28
- (0, react.useEffect)(() => {
29
- if (onEventTriggered) {
30
- /**
31
- * Message handler to process incoming messages.
32
- *
33
- * - **Message Filtering:** Ensures only messages with the specified `key` are processed.
34
- * - **Origin Validation:** Checks that the origin of the message is within the allowed origins.
35
- *
36
- * @param {MessageEvent<{ type: string; data: S }>} event - The incoming message event object.
37
- */
38
- const handleMessage = (event) => {
39
- const { type, data, senderId: msgSenderId } = event.data;
40
- if (type !== key) return;
41
- if (msgSenderId === senderId) return;
42
- if (typeof allowedOrigins === "undefined" || allowedOrigins?.filter((url) => ![
43
- null,
44
- void 0,
45
- "",
46
- "*"
47
- ].includes(url)).some((url) => (0, _intlayer_editor.compareUrls)(url, event.origin)) || allowedOrigins?.includes("*")) onEventTriggered(data);
48
- };
49
- window.addEventListener("message", handleMessage);
50
- return () => window.removeEventListener("message", handleMessage);
51
- }
52
- }, [
53
- allowedOrigins,
54
- postMessage,
55
- senderId,
56
- revalidator
57
- ]);
58
- /**
59
- * A wrapper function around the `postMessage` function to broadcast messages efficiently.
60
- *
61
- * - **Encapsulation:** Ensures the `postMessage` function is scoped to the provided key.
62
- * - **Ease of Use:** Simplifies broadcasting messages with consistent type and format.
63
- *
64
- * @param {S} data - The data payload to include in the message.
65
- * @returns {void}
66
- */
67
- const postMessageWrapper = (data) => {
68
- postMessage({
69
- type: key,
70
- data,
71
- senderId
72
- });
73
- };
74
- return postMessageWrapper;
75
- };
76
-
77
- //#endregion
78
- exports.useCrossFrameMessageListener = useCrossFrameMessageListener;
1
+ "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);const e=require(`./CommunicatorContext.cjs`);let t=require(`react`),n=require(`@intlayer/editor`);const r=(r,i,a)=>{let{allowedOrigins:o,postMessage:s,senderId:c}=e.useCommunicator();return(0,t.useEffect)(()=>{if(i){let e=e=>{let{type:t,data:a,senderId:s}=e.data;t===r&&s!==c&&(o===void 0||o?.filter(e=>![null,void 0,``,`*`].includes(e)).some(t=>(0,n.compareUrls)(t,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})}};exports.useCrossFrameMessageListener=r;
79
2
  //# sourceMappingURL=useCrossFrameMessageListener.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"useCrossFrameMessageListener.cjs","names":["useCommunicator"],"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":";;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,MAAa,gCACX,KACA,kBACA,gBACG;CACH,MAAM,EAAE,gBAAgB,aAAa,aAAaA,6CAAiB;AAEnE,4BAAgB;AACd,MAAI,kBAAkB;;;;;;;;;GASpB,MAAM,iBACJ,UACG;IACH,MAAM,EAAE,MAAM,MAAM,UAAU,gBAAgB,MAAM;AAGpD,QAAI,SAAS,IAAK;AAGlB,QAAI,gBAAgB,SAAU;AAG9B,QACE,OAAO,mBAAmB,eAC1B,gBACI,QAAQ,QAAQ,CAAC;KAAC;KAAM;KAAW;KAAI;KAAI,CAAC,SAAS,IAAI,CAAC,CAC3D,MAAM,0CAAoB,KAAK,MAAM,OAAO,CAAC,IAChD,gBAAgB,SAAS,IAAI,CAG7B,kBAAiB,KAAK;;AAI1B,UAAO,iBAAiB,WAAW,cAAc;AAGjD,gBAAa,OAAO,oBAAoB,WAAW,cAAc;;IAElE;EAAC;EAAgB;EAAa;EAAU;EAAY,CAAC;;;;;;;;;;CAWxD,MAAM,sBAA0C,SAAS;AACvD,cAAY;GAAE,MAAM;GAAK;GAAM;GAAU,CAAC;;AAG5C,QAAO"}
1
+ {"version":3,"file":"useCrossFrameMessageListener.cjs","names":["useCommunicator"],"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":"8NAsBA,MAAa,GACX,EACA,EACA,IACG,CACH,GAAM,CAAE,iBAAgB,cAAa,YAAaA,EAAAA,iBAAiB,CAwDnE,OAtDA,EAAA,EAAA,eAAgB,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,IAAA,EAAA,EAAA,aAAoB,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,109 +1,2 @@
1
- 'use client';
2
-
3
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
- const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
5
- const require_CommunicatorContext = require('./CommunicatorContext.cjs');
6
- const require_useCrossFrameMessageListener = require('./useCrossFrameMessageListener.cjs');
7
- let react = require("react");
8
-
9
- //#region src/useCrossFrameState.tsx
10
- const resolveState = (state, prevState) => typeof state === "function" ? state(prevState) : state;
11
- /**
12
- * Configuration options for `useCrossFrameState`.
13
- * @typedef {Object} CrossFrameStateOptions
14
- * @property {boolean} [emit=true] - Whether to broadcast state changes to other instances.
15
- * @property {boolean} [receive=true] - Whether to listen for state updates from other instances.
16
- */
17
- /**
18
- * useCrossFrameState
19
- *
20
- * This React hook synchronizes state across multiple instances (e.g., different iframes or windows).
21
- * It uses the `postMessage` API to communicate state changes and updates between instances.
22
- *
23
- * @template S - The type of the state.
24
- * @param key - A unique identifier for the state to synchronize.
25
- * @param initialState - The initial state value or a function to compute it lazily.
26
- * @param options - Configuration options to control emitting and receiving messages.
27
- * - `emit` (default: true): Whether to broadcast state changes to other instances.
28
- * - `receive` (default: true): Whether to listen for state updates from other instances.
29
- *
30
- * @returns {[S, Dispatch<SetStateAction<S>>]} An array containing the current state and a setter function.
31
- */
32
- const useCrossFrameState = (key, initialState, options) => {
33
- const { postMessage, senderId } = require_CommunicatorContext.useCommunicator();
34
- const { emit, receive } = options ?? {
35
- emit: true,
36
- receive: true
37
- };
38
- const handleStateChange = (state, prevState) => {
39
- const resolvedState = resolveState(state, prevState);
40
- if (emit && typeof postMessage === "function" && typeof resolvedState !== "undefined") postMessage({
41
- type: `${key}/post`,
42
- data: resolvedState,
43
- senderId
44
- });
45
- return resolvedState;
46
- };
47
- const postState = () => {
48
- if (typeof postMessage !== "function") return;
49
- postMessage({
50
- type: `${key}/post`,
51
- data: state,
52
- senderId
53
- });
54
- };
55
- const [state, setState] = (0, react.useState)(() => handleStateChange(initialState));
56
- /**
57
- * A wrapper function around the `setState` function to handle messaging efficiently.
58
- *
59
- * This approach has several advantages over using an additional `useEffect`:
60
- * - **Avoid Redundant Re-renders:** By emitting the message directly within the `setState` logic,
61
- * it prevents the extra render cycle that would be triggered when using `useEffect`.
62
- * - **Consistency:** Ensures the message is emitted immediately when the state is updated,
63
- * avoiding potential delays caused by the asynchronous nature of `useEffect`.
64
- *
65
- * This function keeps the same API as `setState` and is memoized using `useCallback`
66
- * to prevent unnecessary re-renders of dependent components.
67
- *
68
- * @template S - The type of the state.
69
- * @param {SetStateAction<S>} valueOrUpdater - The new state or a function to produce it.
70
- * @returns {void}
71
- */
72
- const setStateWrapper = (valueOrUpdater) => setState((prevState) => handleStateChange(valueOrUpdater, prevState));
73
- /**
74
- * Listen for messages with the specified key and update the state accordingly.
75
- */
76
- require_useCrossFrameMessageListener.useCrossFrameMessageListener(`${key}/post`, receive ? (data) => {
77
- setState(data);
78
- } : void 0);
79
- const onGetMessage = (_, originSenderId) => {
80
- if (!emit) return;
81
- if (typeof postMessage !== "function") return;
82
- if (originSenderId === senderId) return;
83
- if (typeof state === "undefined") return;
84
- postMessage({
85
- type: `${key}/post`,
86
- data: state,
87
- senderId
88
- });
89
- };
90
- /**
91
- * Listen for messages request to get the state content and send it back.
92
- */
93
- require_useCrossFrameMessageListener.useCrossFrameMessageListener(`${key}/get`, emit ? onGetMessage : void 0, state);
94
- (0, react.useEffect)(() => {
95
- if (receive && typeof postMessage === "function" && typeof state === "undefined") postMessage({
96
- type: `${key}/get`,
97
- senderId
98
- });
99
- }, []);
100
- return [
101
- state,
102
- setStateWrapper,
103
- postState
104
- ];
105
- };
106
-
107
- //#endregion
108
- exports.useCrossFrameState = useCrossFrameState;
1
+ "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);const e=require(`./CommunicatorContext.cjs`),t=require(`./useCrossFrameMessageListener.cjs`);let n=require(`react`);const r=(e,t)=>typeof e==`function`?e(t):e,i=(i,a,o)=>{let{postMessage:s,senderId:c}=e.useCommunicator(),{emit:l,receive:u}=o??{emit:!0,receive:!0},d=(e,t)=>{let n=r(e,t);return l&&typeof s==`function`&&n!==void 0&&s({type:`${i}/post`,data:n,senderId:c}),n},f=()=>{typeof s==`function`&&s({type:`${i}/post`,data:p,senderId:c})},[p,m]=(0,n.useState)(()=>d(a));return t.useCrossFrameMessageListener(`${i}/post`,u?e=>{m(e)}:void 0),t.useCrossFrameMessageListener(`${i}/get`,l?(e,t)=>{l&&typeof s==`function`&&t!==c&&p!==void 0&&s({type:`${i}/post`,data:p,senderId:c})}:void 0,p),(0,n.useEffect)(()=>{u&&typeof s==`function`&&p===void 0&&s({type:`${i}/get`,senderId:c})},[]),[p,e=>m(t=>d(e,t)),f]};exports.useCrossFrameState=i;
109
2
  //# sourceMappingURL=useCrossFrameState.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"useCrossFrameState.cjs","names":["useCommunicator"],"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":";;;;;;;;;AAYA,MAAM,gBAAoB,OAA2B,cACnD,OAAO,UAAU,aACZ,MAA+B,UAAU,GACzC;;;;;;;;;;;;;;;;;;;;;;AAwBP,MAAa,sBACX,KACA,cACA,YACuD;CACvD,MAAM,EAAE,aAAa,aAAaA,6CAAiB;CAEnD,MAAM,EAAE,MAAM,YAAY,WAAW;EAAE,MAAM;EAAM,SAAS;EAAM;CAElE,MAAM,qBAAqB,OAA2B,cAAkB;EAEtE,MAAM,gBAAmB,aAAa,OAAO,UAAU;AAGvD,MACE,QACA,OAAO,gBAAgB,cACvB,OAAO,kBAAkB,YAEzB,aAAY;GAAE,MAAM,GAAG,IAAI;GAAQ,MAAM;GAAe;GAAU,CAAC;AAGrE,SAAO;;CAGT,MAAM,kBAAkB;AACtB,MAAI,OAAO,gBAAgB,WAAY;AACvC,cAAY;GAAE,MAAM,GAAG,IAAI;GAAQ,MAAM;GAAO;GAAU,CAAC;;CAG7D,MAAM,CAAC,OAAO,sCAA8B,kBAAkB,aAAa,CAAC;;;;;;;;;;;;;;;;;CAkB5E,MAAM,mBAAgD,mBACpD,UAAU,cAAc,kBAAkB,gBAAgB,UAAU,CAAC;;;;AAKvE,mEACE,GAAG,IAAI,QAEP,WACK,SAAS;AACR,WAAS,KAAK;KAEhB,OACL;CAED,MAAM,gBAAgB,GAAY,mBAA4B;AAC5D,MAAI,CAAC,KAAM;AACX,MAAI,OAAO,gBAAgB,WAAY;AACvC,MAAI,mBAAmB,SAAU;AACjC,MAAI,OAAO,UAAU,YAAa;AAElC,cAAY;GAAE,MAAM,GAAG,IAAI;GAAQ,MAAM;GAAO;GAAU,CAAC;;;;;AAM7D,mEACE,GAAG,IAAI,OAEP,OAAO,eAAe,QACtB,MACD;AAED,4BAAgB;AAGd,MACE,WACA,OAAO,gBAAgB,cACvB,OAAO,UAAU,YAEjB,aAAY;GAAE,MAAM,GAAG,IAAI;GAAO;GAAU,CAAC;IAE9C,EAAE,CAAC;AAGN,QAAO;EAAC;EAAO;EAAiB;EAAU"}
1
+ {"version":3,"file":"useCrossFrameState.cjs","names":["useCommunicator"],"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":"gPAYA,MAAM,GAAoB,EAA2B,IACnD,OAAO,GAAU,WACZ,EAA+B,EAAU,CACzC,EAwBM,GACX,EACA,EACA,IACuD,CACvD,GAAM,CAAE,cAAa,YAAaA,EAAAA,iBAAiB,CAE7C,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,IAAA,EAAA,EAAA,cAA8B,EAAkB,EAAa,CAAC,CAkE5E,OA1CA,EAAA,6BACE,GAAG,EAAI,OAEP,EACK,GAAS,CACR,EAAS,EAAK,EAEhB,IAAA,GACL,CAcD,EAAA,6BACE,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,EAED,EAAA,EAAA,eAAgB,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,68 +1,2 @@
1
- 'use client';
2
-
3
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
- const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
5
- const require_useCrossFrameState = require('./useCrossFrameState.cjs');
6
- let react = require("react");
7
- let _intlayer_editor = require("@intlayer/editor");
8
-
9
- //#region src/useCrossURLPathState.tsx
10
- const useCrossURLPathState = (initialState, options) => require_useCrossFrameState.useCrossFrameState(_intlayer_editor.MessageKey.INTLAYER_URL_CHANGE, initialState, options);
11
- const useCrossURLPathSetter = (initialState) => {
12
- const states = useCrossURLPathState(initialState, {
13
- emit: true,
14
- receive: false
15
- });
16
- const [_state, setState] = states;
17
- (0, react.useEffect)(() => {
18
- /**
19
- * 1) Monkey patch history methods (pushState, replaceState)
20
- * to dispatch a custom event whenever they are called.
21
- */
22
- const originalPushState = history.pushState;
23
- const originalReplaceState = history.replaceState;
24
- const injectLocationChangeEvent = (method) => function(...args) {
25
- method.apply(this, args);
26
- window.dispatchEvent(new Event("locationchange"));
27
- };
28
- history.pushState = injectLocationChangeEvent(originalPushState);
29
- history.replaceState = injectLocationChangeEvent(originalReplaceState);
30
- /**
31
- * 2) The callback to update our state whenever the URL changes.
32
- */
33
- const updateURLState = () => {
34
- setState(window.location.pathname);
35
- };
36
- /**
37
- * 3) Attach event listeners for locationchange, popstate, hashchange.
38
- * - 'locationchange' is our custom event triggered by push/replaceState overrides.
39
- * - 'popstate' is fired on back/forward navigation.
40
- * - 'hashchange' is for URL hash (#) changes.
41
- * - 'load' is when new page is loaded
42
- */
43
- window.addEventListener("locationchange", updateURLState);
44
- window.addEventListener("popstate", updateURLState);
45
- window.addEventListener("hashchange", updateURLState);
46
- window.addEventListener("load", updateURLState);
47
- updateURLState();
48
- /**
49
- * 4) Cleanup when the component unmounts:
50
- * - Remove event listeners.
51
- * - Restore original pushState & replaceState to avoid side effects.
52
- */
53
- return () => {
54
- window.removeEventListener("locationchange", updateURLState);
55
- window.removeEventListener("popstate", updateURLState);
56
- window.removeEventListener("hashchange", updateURLState);
57
- window.removeEventListener("load", updateURLState);
58
- history.pushState = originalPushState;
59
- history.replaceState = originalReplaceState;
60
- };
61
- }, []);
62
- return states;
63
- };
64
-
65
- //#endregion
66
- exports.useCrossURLPathSetter = useCrossURLPathSetter;
67
- exports.useCrossURLPathState = useCrossURLPathState;
1
+ "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);const e=require(`./useCrossFrameState.cjs`);let t=require(`react`),n=require(`@intlayer/editor`);const r=(t,r)=>e.useCrossFrameState(n.MessageKey.INTLAYER_URL_CHANGE,t,r),i=e=>{let n=r(e,{emit:!0,receive:!1}),[i,a]=n;return(0,t.useEffect)(()=>{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}},[]),n};exports.useCrossURLPathSetter=i,exports.useCrossURLPathState=r;
68
2
  //# sourceMappingURL=useCrossURLPathState.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"useCrossURLPathState.cjs","names":["useCrossFrameState","MessageKey"],"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":";;;;;;;;;AASA,MAAa,wBACX,cACA,YACGA,8CAAmBC,4BAAW,qBAAqB,cAAc,QAAQ;AAE9E,MAAa,yBAAyB,iBAA0B;CAC9D,MAAM,SAAS,qBAAqB,cAAc;EAChD,MAAM;EACN,SAAS;EACV,CAAC;CACF,MAAM,CAAC,QAAQ,YAAY;AAE3B,4BAAgB;;;;;EAKd,MAAM,oBAAoB,QAAQ;EAClC,MAAM,uBAAuB,QAAQ;EAErC,MAAM,6BAA6B,WACjC,SAAgC,GAAG,MAA8B;AAC/D,UAAO,MAAM,MAAM,KAAK;AACxB,UAAO,cAAc,IAAI,MAAM,iBAAiB,CAAC;;AAGrD,UAAQ,YAAY,0BAA0B,kBAAkB;AAChE,UAAQ,eAAe,0BAA0B,qBAAqB;;;;EAKtE,MAAM,uBAAuB;AAC3B,YAAS,OAAO,SAAS,SAAS;;;;;;;;;AAUpC,SAAO,iBAAiB,kBAAkB,eAAe;AACzD,SAAO,iBAAiB,YAAY,eAAe;AACnD,SAAO,iBAAiB,cAAc,eAAe;AACrD,SAAO,iBAAiB,QAAQ,eAAe;AAG/C,kBAAgB;;;;;;AAOhB,eAAa;AACX,UAAO,oBAAoB,kBAAkB,eAAe;AAC5D,UAAO,oBAAoB,YAAY,eAAe;AACtD,UAAO,oBAAoB,cAAc,eAAe;AACxD,UAAO,oBAAoB,QAAQ,eAAe;AAClD,WAAQ,YAAY;AACpB,WAAQ,eAAe;;IAExB,EAAE,CAAC;AAEN,QAAO"}
1
+ {"version":3,"file":"useCrossURLPathState.cjs","names":["useCrossFrameState","MessageKey"],"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":"6NASA,MAAa,GACX,EACA,IACGA,EAAAA,mBAAmBC,EAAAA,WAAW,oBAAqB,EAAc,EAAQ,CAEjE,EAAyB,GAA0B,CAC9D,IAAM,EAAS,EAAqB,EAAc,CAChD,KAAM,GACN,QAAS,GACV,CAAC,CACI,CAAC,EAAQ,GAAY,EAwD3B,OAtDA,EAAA,EAAA,eAAgB,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,24 +1,2 @@
1
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
3
- const require_useCrossFrameState = require('./useCrossFrameState.cjs');
4
- let _intlayer_editor = require("@intlayer/editor");
5
-
6
- //#region src/useEditorLocale.tsx
7
- const useEditorLocale = () => {
8
- const [currentLocale] = require_useCrossFrameState.useCrossFrameState(_intlayer_editor.MessageKey.INTLAYER_CURRENT_LOCALE, void 0, {
9
- receive: true,
10
- emit: false
11
- });
12
- return currentLocale;
13
- };
14
- const useSetEditorLocale = () => {
15
- return require_useCrossFrameState.useCrossFrameState(_intlayer_editor.MessageKey.INTLAYER_CURRENT_LOCALE, void 0, {
16
- receive: true,
17
- emit: false
18
- });
19
- };
20
-
21
- //#endregion
22
- exports.useEditorLocale = useEditorLocale;
23
- exports.useSetEditorLocale = useSetEditorLocale;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);const e=require(`./useCrossFrameState.cjs`);let t=require(`@intlayer/editor`);const n=()=>{let[n]=e.useCrossFrameState(t.MessageKey.INTLAYER_CURRENT_LOCALE,void 0,{receive:!0,emit:!1});return n},r=()=>e.useCrossFrameState(t.MessageKey.INTLAYER_CURRENT_LOCALE,void 0,{receive:!0,emit:!1});exports.useEditorLocale=n,exports.useSetEditorLocale=r;
24
2
  //# sourceMappingURL=useEditorLocale.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"useEditorLocale.cjs","names":["useCrossFrameState","MessageKey"],"sources":["../../src/useEditorLocale.tsx"],"sourcesContent":["import { MessageKey } from '@intlayer/editor';\nimport type { Locale } from '@intlayer/types';\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":";;;;;;AAIA,MAAa,wBAAwB;CACnC,MAAM,CAAC,iBAAiBA,8CACtBC,4BAAW,yBACX,QACA;EACE,SAAS;EACT,MAAM;EACP,CACF;AAED,QAAO;;AAGT,MAAa,2BAA2B;AAUtC,QATyBD,8CACvBC,4BAAW,yBACX,QACA;EACE,SAAS;EACT,MAAM;EACP,CACF"}
1
+ {"version":3,"file":"useEditorLocale.cjs","names":["useCrossFrameState","MessageKey"],"sources":["../../src/useEditorLocale.tsx"],"sourcesContent":["import { MessageKey } from '@intlayer/editor';\nimport type { Locale } from '@intlayer/types';\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":"6LAIA,MAAa,MAAwB,CACnC,GAAM,CAAC,GAAiBA,EAAAA,mBACtBC,EAAAA,WAAW,wBACX,IAAA,GACA,CACE,QAAS,GACT,KAAM,GACP,CACF,CAED,OAAO,GAGI,MACcD,EAAAA,mBACvBC,EAAAA,WAAW,wBACX,IAAA,GACA,CACE,QAAS,GACT,KAAM,GACP,CACF"}
@@ -1,52 +1,2 @@
1
- 'use client';
2
-
3
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
- const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
5
- const require_DictionariesRecordContext = require('./DictionariesRecordContext.cjs');
6
- const require_useEditorLocale = require('./useEditorLocale.cjs');
7
- const require_FocusDictionaryContext = require('./FocusDictionaryContext.cjs');
8
- let react = require("react");
9
- let _intlayer_core = require("@intlayer/core");
10
-
11
- //#region src/useFocusUnmergedDictionary.tsx
12
- /**
13
- * Converts merged keypath format to unmerged format.
14
- * Merged: [{type: "translation", key: "fr"}, {type: "object", key: "title"}]
15
- * Unmerged: [{type: "object", key: "title"}, {type: "translation", key: "fr"}]
16
- */
17
- const mergedKeyPathToUnmergedKeyPath = (keyPath, dictionaries, locale) => {
18
- for (const dictionary of dictionaries) try {
19
- if ((0, _intlayer_core.getContentNodeByKeyPath)(dictionary.content, keyPath ?? [], locale)) return {
20
- keyPath,
21
- dictionaryLocalId: dictionary.localId
22
- };
23
- } catch {}
24
- };
25
- const useFocusUnmergedDictionary = () => {
26
- const { localeDictionaries } = require_DictionariesRecordContext.useDictionariesRecord();
27
- const currentLocale = require_useEditorLocale.useEditorLocale();
28
- const { setFocusedContent, setFocusedContentKeyPath, focusedContent: mergedFocusedContent } = require_FocusDictionaryContext.useFocusDictionary();
29
- return {
30
- focusedContent: (0, react.useMemo)(() => {
31
- if (!mergedFocusedContent) return mergedFocusedContent;
32
- if (!localeDictionaries) return mergedFocusedContent;
33
- if (mergedFocusedContent.dictionaryLocalId) return mergedFocusedContent;
34
- const dictionaries = Object.values(localeDictionaries).filter((dictionary) => dictionary.key === mergedFocusedContent.dictionaryKey);
35
- const unmergedKeyPath = mergedKeyPathToUnmergedKeyPath(mergedFocusedContent.keyPath ?? [], dictionaries, currentLocale);
36
- return {
37
- ...mergedFocusedContent,
38
- ...unmergedKeyPath
39
- };
40
- }, [
41
- mergedFocusedContent,
42
- localeDictionaries,
43
- currentLocale
44
- ]),
45
- setFocusedContent,
46
- setFocusedContentKeyPath
47
- };
48
- };
49
-
50
- //#endregion
51
- exports.useFocusUnmergedDictionary = useFocusUnmergedDictionary;
1
+ "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);const e=require(`./DictionariesRecordContext.cjs`),t=require(`./useEditorLocale.cjs`),n=require(`./FocusDictionaryContext.cjs`);let r=require(`react`),i=require(`@intlayer/core/dictionaryManipulator`);const a=(e,t,n)=>{for(let r of t)try{if((0,i.getContentNodeByKeyPath)(r.content,e??[],n))return{keyPath:e,dictionaryLocalId:r.localId}}catch{}},o=()=>{let{localeDictionaries:i}=e.useDictionariesRecord(),o=t.useEditorLocale(),{setFocusedContent:s,setFocusedContentKeyPath:c,focusedContent:l}=n.useFocusDictionary();return{focusedContent:(0,r.useMemo)(()=>{if(!l||!i||l.dictionaryLocalId)return l;let e=Object.values(i).filter(e=>e.key===l.dictionaryKey),t=a(l.keyPath??[],e,o);return{...l,...t}},[l,i,o]),setFocusedContent:s,setFocusedContentKeyPath:c}};exports.useFocusUnmergedDictionary=o;
52
2
  //# sourceMappingURL=useFocusUnmergedDictionary.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"useFocusUnmergedDictionary.cjs","names":["useDictionariesRecord","useEditorLocale","useFocusDictionary"],"sources":["../../src/useFocusUnmergedDictionary.tsx"],"sourcesContent":["'use client';\n\nimport { getContentNodeByKeyPath } from '@intlayer/core';\nimport type {\n Dictionary,\n KeyPath,\n LocalDictionaryId,\n Locale,\n} from '@intlayer/types';\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":";;;;;;;;;;;;;;;;AAwBA,MAAM,kCACJ,SACA,cACA,WACgC;AAIhC,MAAK,MAAM,cAAc,aACvB,KAAI;AAOF,kDALE,WAAW,SACX,WAAW,EAAE,EACb,OACD,CAGC,QAAO;GAAE;GAAS,mBAAmB,WAAW;GAAS;SAErD;;AAMZ,MAAa,mCAAmC;CAC9C,MAAM,EAAE,uBAAuBA,yDAAuB;CACtD,MAAM,gBAAgBC,yCAAiB;CACvC,MAAM,EACJ,mBACA,0BACA,gBAAgB,yBACdC,mDAAoB;AAuBxB,QAAO;EACL,yCAtBuD;AACvD,OAAI,CAAC,qBAAsB,QAAO;AAClC,OAAI,CAAC,mBAAoB,QAAO;AAChC,OAAI,qBAAqB,kBAAmB,QAAO;GAEnD,MAAM,eAAe,OAAO,OAAO,mBAAmB,CAAC,QACpD,eAAe,WAAW,QAAQ,qBAAqB,cACzD;GAED,MAAM,kBAAkB,+BACtB,qBAAqB,WAAW,EAAE,EAClC,cACA,cACD;AAED,UAAO;IACL,GAAG;IACH,GAAG;IACJ;KACA;GAAC;GAAsB;GAAoB;GAAc,CAAC;EAI3D;EACA;EACD"}
1
+ {"version":3,"file":"useFocusUnmergedDictionary.cjs","names":["useDictionariesRecord","useEditorLocale","useFocusDictionary"],"sources":["../../src/useFocusUnmergedDictionary.tsx"],"sourcesContent":["'use client';\n\nimport { getContentNodeByKeyPath } from '@intlayer/core/dictionaryManipulator';\nimport type {\n Dictionary,\n KeyPath,\n LocalDictionaryId,\n Locale,\n} from '@intlayer/types';\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":"qUAwBA,MAAM,GACJ,EACA,EACA,IACgC,CAIhC,IAAK,IAAM,KAAc,EACvB,GAAI,CAOF,IAAA,EAAA,EAAA,yBALE,EAAW,QACX,GAAW,EAAE,CACb,EACD,CAGC,MAAO,CAAE,UAAS,kBAAmB,EAAW,QAAS,MAErD,IAMC,MAAmC,CAC9C,GAAM,CAAE,sBAAuBA,EAAAA,uBAAuB,CAChD,EAAgBC,EAAAA,iBAAiB,CACjC,CACJ,oBACA,2BACA,eAAgB,GACdC,EAAAA,oBAAoB,CAuBxB,MAAO,CACL,gBAAA,EAAA,EAAA,aAtBuD,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,25 +1,2 @@
1
- 'use client';
2
-
3
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
- const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
5
- const require_useCrossFrameMessageListener = require('./useCrossFrameMessageListener.cjs');
6
- let react = require("react");
7
- let _intlayer_editor = require("@intlayer/editor");
8
-
9
- //#region src/useIframeClickInterceptor.tsx
10
- const useIframeClickInterceptor = () => {
11
- const postMessage = require_useCrossFrameMessageListener.useCrossFrameMessageListener(_intlayer_editor.MessageKey.INTLAYER_IFRAME_CLICKED);
12
- const handlePostMessageEvent = () => {
13
- postMessage();
14
- };
15
- (0, react.useEffect)(() => {
16
- window.addEventListener("mousedown", handlePostMessageEvent);
17
- return () => window.removeEventListener("mousedown", handlePostMessageEvent);
18
- }, [postMessage]);
19
- };
20
- const useIframeClickMerger = () => require_useCrossFrameMessageListener.useCrossFrameMessageListener(_intlayer_editor.MessageKey.INTLAYER_IFRAME_CLICKED, _intlayer_editor.mergeIframeClick);
21
-
22
- //#endregion
23
- exports.useIframeClickInterceptor = useIframeClickInterceptor;
24
- exports.useIframeClickMerger = useIframeClickMerger;
1
+ "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);const e=require(`./useCrossFrameMessageListener.cjs`);let t=require(`react`),n=require(`@intlayer/editor`);const r=()=>{let r=e.useCrossFrameMessageListener(n.MessageKey.INTLAYER_IFRAME_CLICKED),i=()=>{r()};(0,t.useEffect)(()=>(window.addEventListener(`mousedown`,i),()=>window.removeEventListener(`mousedown`,i)),[r])},i=()=>e.useCrossFrameMessageListener(n.MessageKey.INTLAYER_IFRAME_CLICKED,n.mergeIframeClick);exports.useIframeClickInterceptor=r,exports.useIframeClickMerger=i;
25
2
  //# sourceMappingURL=useIframeClickInterceptor.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"useIframeClickInterceptor.cjs","names":["useCrossFrameMessageListener","MessageKey","mergeIframeClick"],"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":";;;;;;;;;AAMA,MAAa,kCAAkC;CAC7C,MAAM,cAAcA,kEAClBC,4BAAW,wBACZ;CACD,MAAM,+BAA8C;AAClD,eAAa;;AAGf,4BAAgB;AACd,SAAO,iBAAiB,aAAa,uBAAuB;AAE5D,eACE,OAAO,oBAAoB,aAAa,uBAAuB;IAChE,CAAC,YAAY,CAAC;;AAGnB,MAAa,6BACXD,kEACEC,4BAAW,yBACXC,kCACD"}
1
+ {"version":3,"file":"useIframeClickInterceptor.cjs","names":["useCrossFrameMessageListener","MessageKey","mergeIframeClick"],"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":"uOAMA,MAAa,MAAkC,CAC7C,IAAM,EAAcA,EAAAA,6BAClBC,EAAAA,WAAW,wBACZ,CACK,MAA8C,CAClD,GAAa,GAGf,EAAA,EAAA,gBACE,OAAO,iBAAiB,YAAa,EAAuB,KAG1D,OAAO,oBAAoB,YAAa,EAAuB,EAChE,CAAC,EAAY,CAAC,EAGN,MACXD,EAAAA,6BACEC,EAAAA,WAAW,wBACXC,EAAAA,iBACD"}