diff --git a/packages/core/package.json b/packages/core/package.json index b07d87df..e920ae3d 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -25,7 +25,7 @@ "prepublishOnly": "yarn build ", "prepack": "cp ../../README.md ./", "postpack": "rm ./README.md", - "serve": "webpack serve", + "serve": "webpack serve --config-name configMain", "test": "cross-env NODE_ENV=test jest", "test:integration": "cross-env NODE_ENV=test jest -c jest.config.integration.js", "test:ci": "cross-env NODE_ENV=test jest --maxWorkers=2 --coverage", diff --git a/packages/core/src/components/entry-editor/Editor.tsx b/packages/core/src/components/entry-editor/Editor.tsx index 5f92f525..92c439aa 100644 --- a/packages/core/src/components/entry-editor/Editor.tsx +++ b/packages/core/src/components/entry-editor/Editor.tsx @@ -212,7 +212,6 @@ const Editor: FC> = ({ }, [collection, createBackup, entryDraft.entry, hasChanged]); useEntryCallback({ - hasChanged, collection, slug, callback: () => { diff --git a/packages/core/src/components/entry-editor/editor-preview-pane/EditorPreviewPane.tsx b/packages/core/src/components/entry-editor/editor-preview-pane/EditorPreviewPane.tsx index 88e1b155..e6ad7ffa 100644 --- a/packages/core/src/components/entry-editor/editor-preview-pane/EditorPreviewPane.tsx +++ b/packages/core/src/components/entry-editor/editor-preview-pane/EditorPreviewPane.tsx @@ -186,7 +186,10 @@ const EditorPreviewPane = (props: TranslatedProps) => { const livePreviewIframe = useRef(null); const passEventToIframe = useCallback((event: DataUpdateEvent) => { if (livePreviewIframe.current) { - livePreviewIframe.current.contentWindow?.postMessage(event); + livePreviewIframe.current.contentWindow?.postMessage({ + message: 'data:update', + value: { fieldPath: event.detail.fieldPath, value: event.detail.value }, + }); } }, []); diff --git a/packages/core/src/components/index.tsx b/packages/core/src/components/index.tsx deleted file mode 100644 index 1cbb6130..00000000 --- a/packages/core/src/components/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './live'; diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index e5bbb31f..121a2749 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -16,7 +16,6 @@ import Registry from './lib/registry'; export * from './backends'; export * from './interface'; -export * from './components'; export * from './lib'; export { default as locales } from './locales'; export * from './widgets'; diff --git a/packages/core/src/lib/hooks/useData.tsx b/packages/core/src/lib/hooks/useData.tsx index bf1d163b..3b6e256a 100644 --- a/packages/core/src/lib/hooks/useData.tsx +++ b/packages/core/src/lib/hooks/useData.tsx @@ -1,23 +1,29 @@ -import { useCallback, useEffect, useState } from 'react'; -import { useSearchParams } from 'react-router-dom'; +import { useCallback, useEffect, useMemo, useState } from 'react'; import type { ValueOrNestedValue } from '@staticcms/core/interface'; -import type DataUpdateEvent from '../util/events/DataEvent'; export default function useData(value: ValueOrNestedValue, path: string) { const [data, setData] = useState(value); - const [searchParams] = useSearchParams(); - const isCms = searchParams.get('useCmsData') === 'true'; + const isCms = useMemo(() => { + if (!window) { + return false; + } + + const searchParams = new URLSearchParams(window.location.search); + return searchParams.get('useCmsData') === 'true'; + }, []); const onDataChange = useCallback( - (event: DataUpdateEvent) => { - if (!isCms) { + (event: MessageEvent) => { + if (!isCms || event.data.message !== 'data:update') { return; } - if (event.detail.fieldPath === path) { - setData(event.detail.value); + const { fieldPath, value } = event.data.value; + + if (fieldPath === path) { + setData(value); } }, [isCms, path], @@ -28,10 +34,10 @@ export default function useData(value: ValueOrNestedValue, path: string) { return; } - window.addEventListener('data:update', onDataChange); + window?.addEventListener('message', onDataChange); return () => { - window.removeEventListener('data:update', onDataChange); + window?.removeEventListener('message', onDataChange); }; }, [isCms, onDataChange]); diff --git a/packages/core/src/lib/hooks/useEntryCallback.ts b/packages/core/src/lib/hooks/useEntryCallback.ts index 97ae4feb..f65621ea 100644 --- a/packages/core/src/lib/hooks/useEntryCallback.ts +++ b/packages/core/src/lib/hooks/useEntryCallback.ts @@ -63,18 +63,12 @@ async function handleChange( } interface EntryCallbackProps { - hasChanged: boolean; collection: Collection; slug: string | undefined; callback: () => void; } -export default function useEntryCallback({ - hasChanged, - slug, - collection, - callback, -}: EntryCallbackProps) { +export default function useEntryCallback({ slug, collection, callback }: EntryCallbackProps) { const dispatch = useAppDispatch(); const entry = useAppSelector(selectEditingDraft); @@ -85,7 +79,7 @@ export default function useEntryCallback({ return; } - if (hasChanged && entry) { + if (entry) { const file = fileForEntry(collection, slug); let updatedEntryData = entry.data; @@ -121,9 +115,9 @@ export default function useEntryCallback({ setLastEntryData(entry?.data); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [entry, hasChanged]); + }, [entry]); - const debouncedRunUpdateCheck = useDebouncedCallback(runUpdateCheck, 500); + const debouncedRunUpdateCheck = useDebouncedCallback(runUpdateCheck, 200); useEffect(() => { debouncedRunUpdateCheck(); diff --git a/packages/core/src/components/live/Data.tsx b/packages/core/src/live/Data.tsx similarity index 85% rename from packages/core/src/components/live/Data.tsx rename to packages/core/src/live/Data.tsx index 9cdb9eee..5626e7f0 100644 --- a/packages/core/src/components/live/Data.tsx +++ b/packages/core/src/live/Data.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { useData } from '@staticcms/core/lib'; +import useData from '@staticcms/core/lib/hooks/useData'; import type { ValueOrNestedValue } from '@staticcms/core/interface'; import type { FC } from 'react'; @@ -12,7 +12,6 @@ export interface DataProps { const Data: FC = ({ path, value }) => { const data = useData(value, path); - return <>{data}; }; diff --git a/packages/core/src/components/live/index.tsx b/packages/core/src/live/index.ts similarity index 100% rename from packages/core/src/components/live/index.tsx rename to packages/core/src/live/index.ts diff --git a/packages/core/webpack.config.js b/packages/core/webpack.config.js index 11d20da6..22e682de 100644 --- a/packages/core/webpack.config.js +++ b/packages/core/webpack.config.js @@ -12,8 +12,7 @@ function moduleNameToPath(libName) { return path.resolve(__dirname, '..', '..', 'node_modules', libName); } -module.exports = { - entry: './src/index.ts', +const config = { mode: isProduction ? 'production' : 'development', devtool: 'source-map', externals: isProduction @@ -107,15 +106,6 @@ module.exports = { STATIC_CMS_CORE_VERSION: JSON.stringify(`${pkg.version}${isProduction ? '' : '-dev'}`), }), ].filter(Boolean), - output: { - publicPath: '', - path: path.resolve(__dirname, 'dist'), - filename: 'static-cms-core.js', - library: { - name: 'StaticCmsCore', - type: 'umd', - }, - }, devServer: { static: { directory: './dev-test', @@ -126,3 +116,33 @@ module.exports = { hot: true, }, }; + +const configLive = Object.assign({}, config, { + name: "configLive", + entry: './src/live/index.ts', + output: { + publicPath: '', + path: path.resolve(__dirname, 'dist'), + filename: 'live.js', + library: { + name: 'StaticCmsCoreLive', + type: 'umd', + }, + } +}); + +const configMain = Object.assign({}, config, { + name: "configMain", + entry: './src/index.ts', + output: { + publicPath: '', + path: path.resolve(__dirname, 'dist'), + filename: 'static-cms-core.js', + library: { + name: 'StaticCmsCore', + type: 'umd', + }, + } +}); + +module.exports = [configMain, configLive]