@jbpark/live-editor 6.0.0 → 6.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ko.md +8 -0
- package/README.md +8 -0
- package/dist/{boundary-CySnDUs2.js → boundary-CLMNMZFa.js} +4 -4
- package/dist/boundary-CLMNMZFa.js.map +1 -0
- package/dist/{cn-CAnad2vL.js → compile-BWZ5U59y.js} +135 -2
- package/dist/compile-BWZ5U59y.js.map +1 -0
- package/dist/{context-Bjq0CvBE.js → context-DJxX9epB.js} +2 -3
- package/dist/context-DJxX9epB.js.map +1 -0
- package/dist/{core-BNVuH8-l.js → core-BfJwD8Jx.js} +3 -6
- package/dist/core-BfJwD8Jx.js.map +1 -0
- package/dist/dnd/index.js +2 -2
- package/dist/{dnd-BvjEDo-x.js → dnd-DAGjlJ0_.js} +241 -170
- package/dist/dnd-DAGjlJ0_.js.map +1 -0
- package/dist/{document-uHqw0mvr.js → document-MkQGxfry.js} +1182 -636
- package/dist/document-MkQGxfry.js.map +1 -0
- package/dist/editor/index.js +2 -2
- package/dist/{editor-CvnzrM9J.js → editor-B_VOz3Q0.js} +2 -2
- package/dist/{editor-CvnzrM9J.js.map → editor-B_VOz3Q0.js.map} +1 -1
- package/dist/editor-caches-DXYXgWeD.js +63 -0
- package/dist/editor-caches-DXYXgWeD.js.map +1 -0
- package/dist/error/index.d.ts +1 -1
- package/dist/error/index.js +2 -2
- package/dist/{error-CFzvnLCf.js → error-E3T5CS3m.js} +13 -12
- package/dist/error-E3T5CS3m.js.map +1 -0
- package/dist/{index-DfIvkht8.d.ts → index-BC9hY7dI.d.ts} +5 -5
- package/dist/{index-CqsS207F.d.ts → index-D-Dfv65w.d.ts} +3 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.js +5 -5
- package/dist/preview/index.d.ts +1 -1
- package/dist/preview/index.js +1 -1
- package/dist/{preview-B05MkVIQ.js → preview-DFb1pOqJ.js} +30 -11
- package/dist/preview-DFb1pOqJ.js.map +1 -0
- package/dist/provider/index.js +1 -1
- package/dist/{sections-DhH_aVf5.js → sections-CnG7OLr8.js} +3 -3
- package/dist/{sections-DhH_aVf5.js.map → sections-CnG7OLr8.js.map} +1 -1
- package/dist/states-Ci1AvoQ9.js.map +1 -1
- package/dist/style.css +74 -74
- package/dist/ui-kit/index.js +2 -2
- package/dist/ui-kit/style.css +22 -6
- package/dist/{update-BuYQJqjq.js → update-DnX2ibYn.js} +162 -43
- package/dist/update-DnX2ibYn.js.map +1 -0
- package/dist/{use-dynamic-tailwind-B3l1qZRW.js → use-dynamic-tailwind-CjXeHjsr.js} +115 -40
- package/dist/use-dynamic-tailwind-CjXeHjsr.js.map +1 -0
- package/dist/{use-field-state-iQGW0vc6.js → use-field-state-B1VLhWfr.js} +2 -2
- package/dist/{use-field-state-iQGW0vc6.js.map → use-field-state-B1VLhWfr.js.map} +1 -1
- package/dist/utils/ast/index.js +1 -86
- package/dist/utils/index.js +3 -4
- package/package.json +3 -4
- package/dist/boundary-CySnDUs2.js.map +0 -1
- package/dist/cn-CAnad2vL.js.map +0 -1
- package/dist/compile-my0AjsCw.js +0 -136
- package/dist/compile-my0AjsCw.js.map +0 -1
- package/dist/constants-st9gnJ5g.js +0 -55
- package/dist/constants-st9gnJ5g.js.map +0 -1
- package/dist/context-Bjq0CvBE.js.map +0 -1
- package/dist/core-BNVuH8-l.js.map +0 -1
- package/dist/detect-typescript-CMF0FVKD.js +0 -10
- package/dist/detect-typescript-CMF0FVKD.js.map +0 -1
- package/dist/dnd-BvjEDo-x.js.map +0 -1
- package/dist/document-uHqw0mvr.js.map +0 -1
- package/dist/editor-caches-ClMvdcQF.js +0 -23
- package/dist/editor-caches-ClMvdcQF.js.map +0 -1
- package/dist/error-CFzvnLCf.js.map +0 -1
- package/dist/preview-B05MkVIQ.js.map +0 -1
- package/dist/update-BuYQJqjq.js.map +0 -1
- package/dist/use-dynamic-tailwind-B3l1qZRW.js.map +0 -1
- package/dist/utils/ast/index.js.map +0 -1
package/dist/editor/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { t as Core } from "../core-
|
|
2
|
-
import { t as Editor } from "../editor-
|
|
1
|
+
import { t as Core } from "../core-BfJwD8Jx.js";
|
|
2
|
+
import { t as Editor } from "../editor-B_VOz3Q0.js";
|
|
3
3
|
export { Core, Editor as default };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as usePreview, r as useError } from "./states-Ci1AvoQ9.js";
|
|
2
|
-
import { n as useFormatCode, t as Core } from "./core-
|
|
2
|
+
import { n as useFormatCode, t as Core } from "./core-BfJwD8Jx.js";
|
|
3
3
|
import { useCallback, useState } from "react";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
import { useDebouncedCallback } from "@jbpark/use-hooks";
|
|
@@ -63,4 +63,4 @@ Editor.Core = Core;
|
|
|
63
63
|
//#endregion
|
|
64
64
|
export { Editor as t };
|
|
65
65
|
|
|
66
|
-
//# sourceMappingURL=editor-
|
|
66
|
+
//# sourceMappingURL=editor-B_VOz3Q0.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor-
|
|
1
|
+
{"version":3,"file":"editor-B_VOz3Q0.js","names":["Editor","EditorImpl"],"sources":["../src/components/editor/editor.tsx","../src/components/editor/index.ts"],"sourcesContent":["import { useCallback, useState } from 'react';\n\nimport { useDebouncedCallback } from '@jbpark/use-hooks';\n\nimport { useError, usePreview } from '~/components/context/states';\n\nimport Core, { type Props as CoreProps } from './core';\nimport { useFormatCode } from './use-format-code';\n\nexport interface EditorRenderData {\n value: string;\n onChange: (value: string) => void;\n // The same Prettier formatting the built-in editor uses on Cmd+S, for a\n // custom editor's own format-on-save.\n formatCode: (code: string) => Promise<string>;\n}\n\nexport interface Props extends Omit<CoreProps, 'value' | 'onSave' | 'onError'> {\n value?: string;\n defaultValue?: string;\n debounce?: number;\n // Replaces the built-in CodeMirror editor. `Live.Editor` still sends the\n // value to the provider, debounced; only the editing surface changes.\n renderEditor?: (data: EditorRenderData) => React.ReactNode;\n}\n\nconst Editor = ({\n defaultValue,\n value: _value,\n debounce = 1000,\n onChange: _onChange,\n renderEditor,\n fragment,\n prettierOptions,\n ...props\n}: Props) => {\n const { code, setCode } = usePreview();\n const { setError } = useError();\n\n // Controlled, the host owns the document; uncontrolled, the provider does\n // (#341). `draft` shows each keystroke at once, while the provider hears\n // about it after `debounce`.\n const controlled = _value !== undefined;\n const [draft, setDraft] = useState(() => defaultValue ?? code);\n\n // The last code this editor pushed, and the provider code it has already\n // seen. A provider change that isn't this editor's own push came from\n // somewhere else sharing the provider — an uncontrolled DnD, say — and the\n // draft follows it. Adjusted during render so no frame shows the old one.\n const [pushed, setPushed] = useState<string | null>(null);\n const [seenCode, setSeenCode] = useState(code);\n\n if (code !== seenCode) {\n setSeenCode(code);\n\n if (!controlled && code !== pushed) {\n setDraft(code);\n }\n }\n\n const value = controlled ? _value : draft;\n\n const pushCode = useCallback(\n (next: string) => {\n setPushed(next);\n setCode(next);\n },\n [setCode],\n );\n\n const onChange = useCallback(\n (next: string) => {\n if (!controlled) {\n setDraft(next);\n }\n\n _onChange?.(next);\n },\n [_onChange, controlled],\n );\n\n // Formatting on save reaches the provider at once, ahead of the debounce.\n const onSave = useCallback(\n (formattedCode: string) => {\n pushCode(formattedCode);\n },\n [pushCode],\n );\n\n const onError = useCallback(\n (error: string | null) => {\n setError(error);\n },\n [setError],\n );\n\n const formatCode = useFormatCode({ fragment, prettierOptions });\n\n // Pushes `value` to the provider `debounce` ms after it stops changing,\n // and at once on mount. A pending push is never dropped: it runs when the\n // editor unmounts, and when focus leaves it — so clicking into another\n // surface right after typing edits a document that includes the typing.\n const push = useDebouncedCallback(\n () => pushCode(value),\n { delay: debounce, flushOnUnmount: true },\n [value],\n );\n\n // `display: contents` so the wrapper adds a blur listener without adding a\n // box: the editor lays out against this element's parent, as before.\n return (\n <div style={{ display: 'contents' }} onBlur={push.flush}>\n {renderEditor ? (\n renderEditor({ value, onChange, formatCode })\n ) : (\n <Core\n value={value}\n onChange={onChange}\n onSave={onSave}\n onError={onError}\n fragment={fragment}\n prettierOptions={prettierOptions}\n {...props}\n />\n )}\n </div>\n );\n};\n\nexport default Editor;\n","import Core, { type Props as CoreProps } from './core';\nimport EditorImpl, { type EditorRenderData, type Props } from './editor';\n\ntype EditorComponent = typeof EditorImpl & { Core: typeof Core };\n\nconst Editor = EditorImpl as EditorComponent;\n\nEditor.Core = Core;\n\nexport { Core };\nexport type { Props, CoreProps, EditorRenderData };\nexport default Editor;\n"],"mappings":";;;;;;AA0BA,MAAMA,YAAU,EACd,cACA,OAAO,QACP,WAAW,KACX,UAAU,WACV,cACA,UACA,iBACA,GAAG,YACQ;CACX,MAAM,EAAE,MAAM,YAAY,WAAW;CACrC,MAAM,EAAE,aAAa,SAAS;CAK9B,MAAM,aAAa,WAAW,KAAA;CAC9B,MAAM,CAAC,OAAO,YAAY,eAAe,gBAAgB,IAAI;CAM7D,MAAM,CAAC,QAAQ,aAAa,SAAwB,IAAI;CACxD,MAAM,CAAC,UAAU,eAAe,SAAS,IAAI;CAE7C,IAAI,SAAS,UAAU;EACrB,YAAY,IAAI;EAEhB,IAAI,CAAC,cAAc,SAAS,QAC1B,SAAS,IAAI;CAEjB;CAEA,MAAM,QAAQ,aAAa,SAAS;CAEpC,MAAM,WAAW,aACd,SAAiB;EAChB,UAAU,IAAI;EACd,QAAQ,IAAI;CACd,GACA,CAAC,OAAO,CACV;CAEA,MAAM,WAAW,aACd,SAAiB;EAChB,IAAI,CAAC,YACH,SAAS,IAAI;EAGf,YAAY,IAAI;CAClB,GACA,CAAC,WAAW,UAAU,CACxB;CAGA,MAAM,SAAS,aACZ,kBAA0B;EACzB,SAAS,aAAa;CACxB,GACA,CAAC,QAAQ,CACX;CAEA,MAAM,UAAU,aACb,UAAyB;EACxB,SAAS,KAAK;CAChB,GACA,CAAC,QAAQ,CACX;CAEA,MAAM,aAAa,cAAc;EAAE;EAAU;CAAgB,CAAC;CAM9D,MAAM,OAAO,2BACL,SAAS,KAAK,GACpB;EAAE,OAAO;EAAU,gBAAgB;CAAK,GACxC,CAAC,KAAK,CACR;CAIA,OACE,oBAAC,OAAD;EAAK,OAAO,EAAE,SAAS,WAAW;EAAG,QAAQ,KAAK;EAC/C,UAAA,eACC,aAAa;GAAE;GAAO;GAAU;EAAW,CAAC,IAE5C,oBAAC,MAAD;GACS;GACG;GACF;GACC;GACC;GACO;GACjB,GAAI;EACL,CAAA;CAEA,CAAA;AAET;;;AC1HA,MAAM,SAASC;AAEf,OAAO,OAAO"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
//#region src/constants/index.ts
|
|
2
|
+
const CONFIG = {
|
|
3
|
+
CACHE_LIMIT: 50,
|
|
4
|
+
DOCUMENT_CACHE_LIMIT: 4,
|
|
5
|
+
SCRIPT_CACHE_LIMIT: 10
|
|
6
|
+
};
|
|
7
|
+
const DATA_ATTR = {
|
|
8
|
+
ID: "data-id",
|
|
9
|
+
BINDING: "data-binding",
|
|
10
|
+
BINDING_KEY: "data-binding-key",
|
|
11
|
+
ITEM: "data-item"
|
|
12
|
+
};
|
|
13
|
+
const RESERVED_BINDING_PROPERTIES = [
|
|
14
|
+
DATA_ATTR.ID,
|
|
15
|
+
"data-name",
|
|
16
|
+
DATA_ATTR.BINDING,
|
|
17
|
+
DATA_ATTR.BINDING_KEY
|
|
18
|
+
];
|
|
19
|
+
const REGEX = {
|
|
20
|
+
NUMBER: /^-?\d+(\.\d+)?$/,
|
|
21
|
+
BOOLEAN_OR_NULL: /^(true|false|null|undefined)$/
|
|
22
|
+
};
|
|
23
|
+
const BINDING_PROP = {
|
|
24
|
+
CHILDREN: "children",
|
|
25
|
+
INNER_TEXT: "innerText",
|
|
26
|
+
INNER_HTML: "innerHTML",
|
|
27
|
+
ITEMS: "items"
|
|
28
|
+
};
|
|
29
|
+
const DEFAULT_CONTAINER_ID = "app-container";
|
|
30
|
+
const documentTemplate = (containerId) => `
|
|
31
|
+
const App = () => {
|
|
32
|
+
return (
|
|
33
|
+
<main id="${containerId}"></main>
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default App;
|
|
38
|
+
`;
|
|
39
|
+
const DEFAULT_TEMPLATE = documentTemplate(DEFAULT_CONTAINER_ID);
|
|
40
|
+
//#endregion
|
|
41
|
+
//#region src/utils/editor-caches.ts
|
|
42
|
+
const editorCaches = /* @__PURE__ */ new Set();
|
|
43
|
+
const registerEditorCache = (clear) => {
|
|
44
|
+
editorCaches.add(clear);
|
|
45
|
+
};
|
|
46
|
+
const clearEditorCaches = () => {
|
|
47
|
+
editorCaches.forEach((clear) => clear());
|
|
48
|
+
};
|
|
49
|
+
let activeEditorSessions = 0;
|
|
50
|
+
const registerEditorSession = () => {
|
|
51
|
+
activeEditorSessions += 1;
|
|
52
|
+
let released = false;
|
|
53
|
+
return () => {
|
|
54
|
+
if (released) return;
|
|
55
|
+
released = true;
|
|
56
|
+
activeEditorSessions -= 1;
|
|
57
|
+
if (activeEditorSessions === 0) clearEditorCaches();
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
//#endregion
|
|
61
|
+
export { CONFIG as a, DEFAULT_TEMPLATE as c, documentTemplate as d, BINDING_PROP as i, REGEX as l, registerEditorCache as n, DATA_ATTR as o, registerEditorSession as r, DEFAULT_CONTAINER_ID as s, clearEditorCaches as t, RESERVED_BINDING_PROPERTIES as u };
|
|
62
|
+
|
|
63
|
+
//# sourceMappingURL=editor-caches-DXYXgWeD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editor-caches-DXYXgWeD.js","names":[],"sources":["../src/constants/index.ts","../src/utils/editor-caches.ts"],"sourcesContent":["export const STORAGE_KEY = 'live-editor-code';\n\nexport const CONFIG = {\n CACHE_LIMIT: 50,\n // The document parse cache. Its entries are whole Babel ASTs (about\n // 0.66 MB per document), and only the current and previous version get hits,\n // so it keeps few (#106).\n DOCUMENT_CACHE_LIMIT: 4,\n // The script cache (`utils/scripts.ts`). Its entries are live blob URLs,\n // revoked on eviction, and a preview loads only a few scripts (#104).\n SCRIPT_CACHE_LIMIT: 10,\n} as const;\n\nexport const DATA_ATTR = {\n ID: 'data-id',\n BINDING: 'data-binding',\n // Names an entry of `Live.Dnd`'s `bindingKeys` instead of declaring the\n // bindings inline (#513).\n BINDING_KEY: 'data-binding-key',\n ITEM: 'data-item',\n} as const;\n\n// Attributes the editor owns. `data-id` links the canvas to the source,\n// `data-name` is a section's name, and `data-binding` and `data-binding-key`\n// declare what each edit is checked against. A binding can't target them,\n// since rewriting one would break that link (#429).\nexport const RESERVED_BINDING_PROPERTIES: readonly string[] = [\n DATA_ATTR.ID,\n 'data-name',\n DATA_ATTR.BINDING,\n DATA_ATTR.BINDING_KEY,\n];\n\nexport const REGEX = {\n NUMBER: /^-?\\d+(\\.\\d+)?$/,\n BOOLEAN_OR_NULL: /^(true|false|null|undefined)$/,\n} as const;\n\nexport const BINDING_PROP = {\n CHILDREN: 'children',\n INNER_TEXT: 'innerText',\n INNER_HTML: 'innerHTML',\n ITEMS: 'items',\n} as const;\n\n// The element whose `<section>` children are a document's sections, unless\n// `Live.Dnd`'s `containerId` says otherwise (#449).\nexport const DEFAULT_CONTAINER_ID = 'app-container';\n\n// A new, empty document built around `containerId`. `createDocument()` in\n// `@jbpark/live-editor/utils` is the public way in; this is the template\n// behind it and behind `DEFAULT_TEMPLATE`.\nexport const documentTemplate = (containerId: string) => `\nconst App = () => {\n return (\n <main id=\"${containerId}\"></main>\n )\n}\n\nexport default App;\n`;\n\nexport const DEFAULT_TEMPLATE = documentTemplate(DEFAULT_CONTAINER_ID);\n\nexport { PALETTE_SECTIONS } from './palette-sections';\n","// The page-wide caches the editor owns: compiled modules, script blobs and\n// the AST parse caches. Each registers its own `clear` here when its module\n// loads, so this module imports none of them, and the provider doesn't pull\n// Babel into every bundle that mounts `Live` (#407). A section preview cache\n// belongs to its component and isn't listed here.\nconst editorCaches = new Set<() => void>();\n\nexport const registerEditorCache = (clear: () => void) => {\n editorCaches.add(clear);\n};\n\nexport const clearEditorCaches = () => {\n editorCaches.forEach(clear => clear());\n};\n\n// Shared by every editor on the page, so they're cleared only when the last\n// one unmounts. Clearing earlier could revoke a blob URL another editor is\n// about to load.\nlet activeEditorSessions = 0;\n\n// Returns the release function, so a caller can only release what it\n// acquired. Calling it twice is harmless, as React may in development.\nexport const registerEditorSession = (): (() => void) => {\n activeEditorSessions += 1;\n\n let released = false;\n\n return () => {\n if (released) {\n return;\n }\n\n released = true;\n activeEditorSessions -= 1;\n\n if (activeEditorSessions === 0) {\n clearEditorCaches();\n }\n };\n};\n"],"mappings":";AAEA,MAAa,SAAS;CACpB,aAAa;CAIb,sBAAsB;CAGtB,oBAAoB;AACtB;AAEA,MAAa,YAAY;CACvB,IAAI;CACJ,SAAS;CAGT,aAAa;CACb,MAAM;AACR;AAMA,MAAa,8BAAiD;CAC5D,UAAU;CACV;CACA,UAAU;CACV,UAAU;AACZ;AAEA,MAAa,QAAQ;CACnB,QAAQ;CACR,iBAAiB;AACnB;AAEA,MAAa,eAAe;CAC1B,UAAU;CACV,YAAY;CACZ,YAAY;CACZ,OAAO;AACT;AAIA,MAAa,uBAAuB;AAKpC,MAAa,oBAAoB,gBAAwB;;;gBAGzC,YAAY;;;;;;AAO5B,MAAa,mBAAmB,iBAAiB,oBAAoB;;;ACzDrE,MAAM,+BAAe,IAAI,IAAgB;AAEzC,MAAa,uBAAuB,UAAsB;CACxD,aAAa,IAAI,KAAK;AACxB;AAEA,MAAa,0BAA0B;CACrC,aAAa,SAAQ,UAAS,MAAM,CAAC;AACvC;AAKA,IAAI,uBAAuB;AAI3B,MAAa,8BAA4C;CACvD,wBAAwB;CAExB,IAAI,WAAW;CAEf,aAAa;EACX,IAAI,UACF;EAGF,WAAW;EACX,wBAAwB;EAExB,IAAI,yBAAyB,GAC3B,kBAAkB;CAEtB;AACF"}
|
package/dist/error/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as Guard, o as Props, r as Runtime, s as ErrorBoundary, t as Error } from "../index-
|
|
1
|
+
import { i as Guard, o as Props, r as Runtime, s as ErrorBoundary, t as Error } from "../index-BC9hY7dI.js";
|
|
2
2
|
export { ErrorBoundary, Guard as ErrorGuard, Runtime as ErrorRuntime, type Props, Error as default };
|
package/dist/error/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { t as ErrorBoundary } from "../boundary-
|
|
2
|
-
import { n as Runtime, r as Guard, t as Error } from "../error-
|
|
1
|
+
import { t as ErrorBoundary } from "../boundary-CLMNMZFa.js";
|
|
2
|
+
import { n as Runtime, r as Guard, t as Error } from "../error-E3T5CS3m.js";
|
|
3
3
|
export { ErrorBoundary, Guard as ErrorGuard, Runtime as ErrorRuntime, Error as default };
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { i as useLiveMessages } from "./messages-DrINcRdG.js";
|
|
2
2
|
import { r as useError } from "./states-Ci1AvoQ9.js";
|
|
3
|
-
import { n as Error$1, t as ErrorBoundary } from "./boundary-
|
|
3
|
+
import { n as Error$1, t as ErrorBoundary } from "./boundary-CLMNMZFa.js";
|
|
4
4
|
import { useEffect, useRef, useState } from "react";
|
|
5
|
-
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import { useEventListener, useLatest } from "@jbpark/use-hooks";
|
|
7
|
+
//#region src/components/error/ignored-page-error.ts
|
|
8
|
+
const IGNORED_PAGE_ERROR = /ResizeObserver loop (completed with undelivered notifications|limit exceeded)/;
|
|
9
|
+
const isIgnoredPageError = (message) => IGNORED_PAGE_ERROR.test(message ?? "");
|
|
10
|
+
//#endregion
|
|
7
11
|
//#region src/components/error/guard.tsx
|
|
8
12
|
const Guard = ({ children, onError }) => {
|
|
9
13
|
const [error, setError] = useState(null);
|
|
@@ -11,11 +15,9 @@ const Guard = ({ children, onError }) => {
|
|
|
11
15
|
const errorHandled = useRef(false);
|
|
12
16
|
const messagesRef = useLatest(messages);
|
|
13
17
|
useEventListener("error", (event) => {
|
|
14
|
-
if (errorHandled.current) return;
|
|
18
|
+
if (errorHandled.current || isIgnoredPageError(event.message)) return;
|
|
15
19
|
errorHandled.current = true;
|
|
16
20
|
const errorMessage = event.error?.message || event.message || messagesRef.current.errors.unknown;
|
|
17
|
-
console.error("⚡ [Guard] Event handler error:", errorMessage);
|
|
18
|
-
event.preventDefault();
|
|
19
21
|
setError(errorMessage);
|
|
20
22
|
onError?.(event.error || new window.Error(errorMessage));
|
|
21
23
|
setTimeout(() => {
|
|
@@ -26,14 +28,13 @@ const Guard = ({ children, onError }) => {
|
|
|
26
28
|
if (errorHandled.current) return;
|
|
27
29
|
errorHandled.current = true;
|
|
28
30
|
const errorMessage = event.reason?.message || messagesRef.current.errors.unhandledRejection;
|
|
29
|
-
event.preventDefault();
|
|
30
31
|
setError(errorMessage);
|
|
31
32
|
onError?.(event.reason || new window.Error(errorMessage));
|
|
32
33
|
setTimeout(() => {
|
|
33
34
|
errorHandled.current = false;
|
|
34
35
|
}, 100);
|
|
35
36
|
}, { capture: true });
|
|
36
|
-
|
|
37
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [error && /* @__PURE__ */ jsx(Error$1, {
|
|
37
38
|
title: messages.errors.runtime,
|
|
38
39
|
message: error,
|
|
39
40
|
style: { margin: 16 },
|
|
@@ -41,23 +42,23 @@ const Guard = ({ children, onError }) => {
|
|
|
41
42
|
setError(null);
|
|
42
43
|
errorHandled.current = false;
|
|
43
44
|
}
|
|
44
|
-
});
|
|
45
|
-
return /* @__PURE__ */ jsx("div", { children });
|
|
45
|
+
}), /* @__PURE__ */ jsx("div", { children })] });
|
|
46
46
|
};
|
|
47
47
|
//#endregion
|
|
48
48
|
//#region src/components/error/runtime.tsx
|
|
49
|
-
const Runtime = ({ open = true, reset }) => {
|
|
49
|
+
const Runtime = ({ open = true, reset, ...divProps }) => {
|
|
50
50
|
const { error: message, setError } = useError();
|
|
51
51
|
const messages = useLiveMessages();
|
|
52
52
|
useEventListener("error", (e) => {
|
|
53
|
+
if (isIgnoredPageError(e.message)) return;
|
|
53
54
|
setError(e.message);
|
|
54
|
-
e.preventDefault();
|
|
55
55
|
});
|
|
56
56
|
useEffect(() => {
|
|
57
57
|
return () => setError(null);
|
|
58
58
|
}, [setError]);
|
|
59
59
|
if (!open) return null;
|
|
60
60
|
return /* @__PURE__ */ jsx(Error$1, {
|
|
61
|
+
...divProps,
|
|
61
62
|
message,
|
|
62
63
|
onReset: reset,
|
|
63
64
|
title: messages.errors.runtime
|
|
@@ -72,4 +73,4 @@ Error.Guard = Guard;
|
|
|
72
73
|
//#endregion
|
|
73
74
|
export { Runtime as n, Guard as r, Error as t };
|
|
74
75
|
|
|
75
|
-
//# sourceMappingURL=error-
|
|
76
|
+
//# sourceMappingURL=error-E3T5CS3m.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-E3T5CS3m.js","names":["ErrorComponent","Error","ErrorImpl","ErrorRuntime","ErrorGuard"],"sources":["../src/components/error/ignored-page-error.ts","../src/components/error/guard.tsx","../src/components/error/runtime.tsx","../src/components/error/index.ts"],"sourcesContent":["// Benign browser notices that arrive as `error` events on `window`. They\n// don't come from the preview and mean nothing went wrong (#714).\nconst IGNORED_PAGE_ERROR =\n /ResizeObserver loop (completed with undelivered notifications|limit exceeded)/;\n\nexport const isIgnoredPageError = (message: string | undefined) =>\n IGNORED_PAGE_ERROR.test(message ?? '');\n","import { useRef, useState } from 'react';\n\nimport { useEventListener, useLatest } from '@jbpark/use-hooks';\n\nimport { useLiveMessages } from '~/components/context/messages';\n\nimport ErrorComponent from './error';\nimport { isIgnoredPageError } from './ignored-page-error';\n\n// Exported although no file imports it: the declaration of `App` in\n// `src/index.tsx` names it, and TypeScript can't name a type from another\n// module unless it is exported (TS4023).\nexport interface Props {\n children: React.ReactNode;\n onError?: (error: Error) => void;\n}\n\nconst Guard = ({ children, onError }: Props) => {\n const [error, setError] = useState<string | null>(null);\n const messages = useLiveMessages();\n\n const errorHandled = useRef(false);\n // Read by the listeners, so new messages don't subscribe them again.\n const messagesRef = useLatest(messages);\n\n useEventListener(\n 'error',\n event => {\n // Checked before `errorHandled` is set, so an ignored notice doesn't\n // drop the real error that follows it.\n if (errorHandled.current || isIgnoredPageError(event.message)) {\n return;\n }\n\n errorHandled.current = true;\n\n const errorMessage =\n event.error?.message ||\n event.message ||\n messagesRef.current.errors.unknown;\n\n // Not `preventDefault()`: the browser still reports the error in the\n // console, with its stack (#714).\n setError(errorMessage);\n onError?.(event.error || new window.Error(errorMessage));\n\n setTimeout(() => {\n errorHandled.current = false;\n }, 100);\n },\n { capture: true },\n );\n\n useEventListener(\n 'unhandledrejection',\n event => {\n if (errorHandled.current) {\n return;\n }\n\n errorHandled.current = true;\n\n const errorMessage =\n event.reason?.message || messagesRef.current.errors.unhandledRejection;\n\n setError(errorMessage);\n onError?.(event.reason || new window.Error(errorMessage));\n\n setTimeout(() => {\n errorHandled.current = false;\n }, 100);\n },\n { capture: true },\n );\n\n // The box goes next to the children, not in place of them: the listener\n // can't tell where an error came from, so an error from the host page must\n // not unmount the preview and lose its state (#714). `children` stay the\n // second child, so React keeps them mounted when the box appears.\n return (\n <>\n {error && (\n <ErrorComponent\n title={messages.errors.runtime}\n message={error}\n style={{ margin: 16 }}\n onReset={() => {\n setError(null);\n errorHandled.current = false;\n }}\n />\n )}\n <div>{children}</div>\n </>\n );\n};\n\nexport default Guard;\n","import { useEffect } from 'react';\n\nimport { useEventListener } from '@jbpark/use-hooks';\n\nimport { useLiveMessages } from '~/components/context/messages';\nimport { useError } from '~/components/context/states';\n\nimport Error from './error';\nimport { isIgnoredPageError } from './ignored-page-error';\n\n// Exported although no file imports it: the declaration of `App` in\n// `src/index.tsx` names it, and TypeScript can't name a type from another\n// module unless it is exported (TS4023).\nexport interface Props extends Omit<\n React.ComponentPropsWithRef<'div'>,\n // The component renders its own content.\n 'children' | 'dangerouslySetInnerHTML'\n> {\n open?: boolean;\n reset?: () => void;\n}\n\nconst Runtime = ({ open = true, reset, ...divProps }: Props) => {\n const { error: message, setError } = useError();\n const messages = useLiveMessages();\n\n // Not `preventDefault()`, so the browser still reports the error (#714).\n useEventListener('error', e => {\n if (isIgnoredPageError(e.message)) {\n return;\n }\n\n setError(e.message);\n });\n\n useEffect(() => {\n return () => setError(null);\n }, [setError]);\n\n if (!open) {\n return null;\n }\n\n return (\n <Error\n {...divProps}\n message={message}\n onReset={reset}\n title={messages.errors.runtime}\n />\n );\n};\n\nexport default Runtime;\n","import ErrorBoundary from './boundary';\nimport ErrorImpl, { type Props } from './error';\nimport ErrorGuard from './guard';\nimport ErrorRuntime from './runtime';\n\ntype ErrorComponent = typeof ErrorImpl & {\n Boundary: typeof ErrorBoundary;\n Runtime: typeof ErrorRuntime;\n Guard: typeof ErrorGuard;\n};\n\nconst Error = ErrorImpl as ErrorComponent;\n\nError.Boundary = ErrorBoundary;\nError.Runtime = ErrorRuntime;\nError.Guard = ErrorGuard;\n\nexport { ErrorBoundary, ErrorRuntime, ErrorGuard };\nexport type { Props };\nexport default Error;\n"],"mappings":";;;;;;;AAEA,MAAM,qBACJ;AAEF,MAAa,sBAAsB,YACjC,mBAAmB,KAAK,WAAW,EAAE;;;ACWvC,MAAM,SAAS,EAAE,UAAU,cAAqB;CAC9C,MAAM,CAAC,OAAO,YAAY,SAAwB,IAAI;CACtD,MAAM,WAAW,gBAAgB;CAEjC,MAAM,eAAe,OAAO,KAAK;CAEjC,MAAM,cAAc,UAAU,QAAQ;CAEtC,iBACE,UACA,UAAS;EAGP,IAAI,aAAa,WAAW,mBAAmB,MAAM,OAAO,GAC1D;EAGF,aAAa,UAAU;EAEvB,MAAM,eACJ,MAAM,OAAO,WACb,MAAM,WACN,YAAY,QAAQ,OAAO;EAI7B,SAAS,YAAY;EACrB,UAAU,MAAM,SAAS,IAAI,OAAO,MAAM,YAAY,CAAC;EAEvD,iBAAiB;GACf,aAAa,UAAU;EACzB,GAAG,GAAG;CACR,GACA,EAAE,SAAS,KAAK,CAClB;CAEA,iBACE,uBACA,UAAS;EACP,IAAI,aAAa,SACf;EAGF,aAAa,UAAU;EAEvB,MAAM,eACJ,MAAM,QAAQ,WAAW,YAAY,QAAQ,OAAO;EAEtD,SAAS,YAAY;EACrB,UAAU,MAAM,UAAU,IAAI,OAAO,MAAM,YAAY,CAAC;EAExD,iBAAiB;GACf,aAAa,UAAU;EACzB,GAAG,GAAG;CACR,GACA,EAAE,SAAS,KAAK,CAClB;CAMA,OACE,qBAAA,UAAA,EAAA,UAAA,CACG,SACC,oBAACA,SAAD;EACE,OAAO,SAAS,OAAO;EACvB,SAAS;EACT,OAAO,EAAE,QAAQ,GAAG;EACpB,eAAe;GACb,SAAS,IAAI;GACb,aAAa,UAAU;EACzB;CACD,CAAA,GAEH,oBAAC,OAAD,EAAM,SAAc,CAAA,CACpB,EAAA,CAAA;AAEN;;;ACzEA,MAAM,WAAW,EAAE,OAAO,MAAM,OAAO,GAAG,eAAsB;CAC9D,MAAM,EAAE,OAAO,SAAS,aAAa,SAAS;CAC9C,MAAM,WAAW,gBAAgB;CAGjC,iBAAiB,UAAS,MAAK;EAC7B,IAAI,mBAAmB,EAAE,OAAO,GAC9B;EAGF,SAAS,EAAE,OAAO;CACpB,CAAC;CAED,gBAAgB;EACd,aAAa,SAAS,IAAI;CAC5B,GAAG,CAAC,QAAQ,CAAC;CAEb,IAAI,CAAC,MACH,OAAO;CAGT,OACE,oBAACC,SAAD;EACE,GAAI;EACK;EACT,SAAS;EACT,OAAO,SAAS,OAAO;CACxB,CAAA;AAEL;;;ACxCA,MAAM,QAAQC;AAEd,MAAM,WAAW;AACjB,MAAM,UAAUC;AAChB,MAAM,QAAQC"}
|
|
@@ -24,12 +24,12 @@ declare class ErrorBoundary extends React$1.Component<Props$3, State> {
|
|
|
24
24
|
}
|
|
25
25
|
//#endregion
|
|
26
26
|
//#region src/components/error/error.d.ts
|
|
27
|
-
interface Props$2 extends React.ComponentPropsWithRef<'div'> {
|
|
27
|
+
interface Props$2 extends Omit<React.ComponentPropsWithRef<'div'>, 'children' | 'dangerouslySetInnerHTML'> {
|
|
28
28
|
message?: string | null;
|
|
29
29
|
title?: string;
|
|
30
30
|
onReset?: () => void;
|
|
31
31
|
}
|
|
32
|
-
declare const Error$2: ({ message, title, className, style, onReset }: Props$2) => import("react").JSX.Element | null;
|
|
32
|
+
declare const Error$2: ({ message, title, className, style, onReset, ...divProps }: Props$2) => import("react").JSX.Element | null;
|
|
33
33
|
//#endregion
|
|
34
34
|
//#region src/components/error/guard.d.ts
|
|
35
35
|
interface Props$1 {
|
|
@@ -39,11 +39,11 @@ interface Props$1 {
|
|
|
39
39
|
declare const Guard: ({ children, onError }: Props$1) => import("react").JSX.Element;
|
|
40
40
|
//#endregion
|
|
41
41
|
//#region src/components/error/runtime.d.ts
|
|
42
|
-
interface Props extends React.ComponentPropsWithRef<'div'> {
|
|
42
|
+
interface Props extends Omit<React.ComponentPropsWithRef<'div'>, 'children' | 'dangerouslySetInnerHTML'> {
|
|
43
43
|
open?: boolean;
|
|
44
44
|
reset?: () => void;
|
|
45
45
|
}
|
|
46
|
-
declare const Runtime: ({ open, reset }: Props) => import("react").JSX.Element | null;
|
|
46
|
+
declare const Runtime: ({ open, reset, ...divProps }: Props) => import("react").JSX.Element | null;
|
|
47
47
|
//#endregion
|
|
48
48
|
//#region src/components/error/index.d.ts
|
|
49
49
|
type ErrorComponent = typeof Error$2 & {
|
|
@@ -54,4 +54,4 @@ type ErrorComponent = typeof Error$2 & {
|
|
|
54
54
|
declare const Error$1: ErrorComponent;
|
|
55
55
|
//#endregion
|
|
56
56
|
export { Props$1 as a, Guard as i, Props as n, Props$2 as o, Runtime as r, ErrorBoundary as s, Error$1 as t };
|
|
57
|
-
//# sourceMappingURL=index-
|
|
57
|
+
//# sourceMappingURL=index-BC9hY7dI.d.ts.map
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { t as FrameProps } from "./index-92L7F440.js";
|
|
2
2
|
import React from "react";
|
|
3
3
|
//#region src/components/preview/types.d.ts
|
|
4
|
-
interface Props extends React.ComponentPropsWithRef<'div'> {
|
|
4
|
+
interface Props extends Omit<React.ComponentPropsWithRef<'div'>, 'children' | 'dangerouslySetInnerHTML'> {
|
|
5
5
|
code?: string;
|
|
6
6
|
showError?: boolean;
|
|
7
7
|
props?: Record<string, unknown>;
|
|
8
|
+
/** @deprecated Has no effect. Will be removed in the next major version. */
|
|
8
9
|
container?: HTMLElement | null;
|
|
9
10
|
frame?: boolean | FrameProps;
|
|
10
11
|
modules?: Record<string, unknown>;
|
|
@@ -16,4 +17,4 @@ interface Props extends React.ComponentPropsWithRef<'div'> {
|
|
|
16
17
|
declare const Preview: ({ code, props, modules, dynamicTailwind, provider, ...restProps }: Props) => import("react").JSX.Element;
|
|
17
18
|
//#endregion
|
|
18
19
|
export { Props as n, Preview as t };
|
|
19
|
-
//# sourceMappingURL=index-
|
|
20
|
+
//# sourceMappingURL=index-D-Dfv65w.d.ts.map
|
package/dist/index.d.ts
CHANGED
|
@@ -6,16 +6,16 @@ import { A as Panel, F as DndNodePick, L as DndRenderSectionFallback, M as DndPa
|
|
|
6
6
|
import { t as FrameProps } from "./index-92L7F440.js";
|
|
7
7
|
import { c as PanelNodeChange, i as PanelBinding, l as PanelNodesChange, n as DndRenderField, r as FieldProps, t as DndEditError } from "./edit-options-C_r9aCz4.js";
|
|
8
8
|
import { a as Props$3, n as EditorRenderData, r as Props$2, t as Editor } from "./index-C93npmTU.js";
|
|
9
|
-
import { a as Props$6, n as Props$5, o as Props$4, s as ErrorBoundary, t as Error } from "./index-
|
|
10
|
-
import { n as Props$7, t as Preview } from "./index-
|
|
9
|
+
import { a as Props$6, n as Props$5, o as Props$4, s as ErrorBoundary, t as Error } from "./index-BC9hY7dI.js";
|
|
10
|
+
import { n as Props$7, t as Preview } from "./index-D-Dfv65w.js";
|
|
11
11
|
//#region src/index.d.ts
|
|
12
12
|
declare const App: {
|
|
13
13
|
({ children, messages }: Props): import("react").JSX.Element;
|
|
14
14
|
Preview: ({ code, props, modules, dynamicTailwind, provider, ...restProps }: Props$7) => import("react").JSX.Element;
|
|
15
15
|
Renderer: ({ code, props, modules, dynamicTailwind, provider, ...restProps }: Props$7) => import("react").JSX.Element;
|
|
16
|
-
Error: (({ message, title, className, style, onReset }: Props$4) => import("react").JSX.Element | null) & {
|
|
16
|
+
Error: (({ message, title, className, style, onReset, ...divProps }: Props$4) => import("react").JSX.Element | null) & {
|
|
17
17
|
Boundary: typeof ErrorBoundary;
|
|
18
|
-
Runtime: ({ open, reset }: Props$5) => import("react").JSX.Element | null;
|
|
18
|
+
Runtime: ({ open, reset, ...divProps }: Props$5) => import("react").JSX.Element | null;
|
|
19
19
|
Guard: ({ children, onError }: Props$6) => import("react").JSX.Element;
|
|
20
20
|
};
|
|
21
21
|
Editor: (({ defaultValue, value: _value, debounce, onChange: _onChange, renderEditor, fragment, prettierOptions, ...props }: Props$2) => import("react").JSX.Element) & {
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { t as Dnd } from "./dnd-
|
|
1
|
+
import { t as Dnd } from "./dnd-DAGjlJ0_.js";
|
|
2
2
|
import { i as useLiveMessages, n as defaultMessages } from "./messages-DrINcRdG.js";
|
|
3
|
-
import { t as ContextProvider } from "./context-
|
|
4
|
-
import { t as Editor } from "./editor-
|
|
5
|
-
import { t as Error } from "./error-
|
|
6
|
-
import { t as Preview } from "./preview-
|
|
3
|
+
import { t as ContextProvider } from "./context-DJxX9epB.js";
|
|
4
|
+
import { t as Editor } from "./editor-B_VOz3Q0.js";
|
|
5
|
+
import { t as Error } from "./error-E3T5CS3m.js";
|
|
6
|
+
import { t as Preview } from "./preview-DFb1pOqJ.js";
|
|
7
7
|
import { jsx } from "react/jsx-runtime";
|
|
8
8
|
//#region src/index.tsx
|
|
9
9
|
const App = ({ children, messages }) => {
|
package/dist/preview/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as Props, t as Preview } from "../index-
|
|
1
|
+
import { n as Props, t as Preview } from "../index-D-Dfv65w.js";
|
|
2
2
|
export { type Props, Preview as default };
|
package/dist/preview/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as Preview } from "../preview-
|
|
1
|
+
import { t as Preview } from "../preview-DFb1pOqJ.js";
|
|
2
2
|
export { Preview as default };
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { i as useLiveMessages } from "./messages-DrINcRdG.js";
|
|
2
2
|
import { i as usePreview, r as useError } from "./states-Ci1AvoQ9.js";
|
|
3
|
-
import {
|
|
4
|
-
import { a as renderStableComponent, i as NO_PROPS, n as useCompiledModule, o as Frame, r as NO_MODULES, t as useDynamicTailwind } from "./use-dynamic-tailwind-
|
|
5
|
-
import { t as Error } from "./error-
|
|
6
|
-
import { useMemo } from "react";
|
|
3
|
+
import { a as cn } from "./compile-BWZ5U59y.js";
|
|
4
|
+
import { a as renderStableComponent, i as NO_PROPS, n as useCompiledModule, o as Frame, r as NO_MODULES, s as useIsClient, t as useDynamicTailwind } from "./use-dynamic-tailwind-CjXeHjsr.js";
|
|
5
|
+
import { t as Error } from "./error-E3T5CS3m.js";
|
|
6
|
+
import { useLayoutEffect, useMemo } from "react";
|
|
7
7
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import { useMergedRef } from "@jbpark/use-hooks";
|
|
8
9
|
//#region src/components/preview/preview.module.css
|
|
9
10
|
var preview_module_default = {
|
|
10
11
|
"fill": "U36FtW_fill",
|
|
@@ -13,30 +14,43 @@ var preview_module_default = {
|
|
|
13
14
|
};
|
|
14
15
|
//#endregion
|
|
15
16
|
//#region src/components/preview/client.tsx
|
|
16
|
-
const Client = ({ code: _code, className, showError, props = NO_PROPS, modules = NO_MODULES, frame, dynamicTailwind = false, provider }) => {
|
|
17
|
+
const Client = ({ code: _code, className, showError, props = NO_PROPS, modules = NO_MODULES, frame, dynamicTailwind = false, provider, container: _container, style, ref, ...divProps }) => {
|
|
17
18
|
const { code } = usePreview();
|
|
18
19
|
const { error, setError } = useError();
|
|
19
20
|
const messages = useLiveMessages();
|
|
20
21
|
const isError = !!showError && !!error;
|
|
21
22
|
const classNames = cn(isError && preview_module_default.hidden, className);
|
|
22
23
|
const effectiveCode = _code === void 0 ? code : _code;
|
|
23
|
-
const
|
|
24
|
+
const isClient = useIsClient();
|
|
25
|
+
const module = useCompiledModule(frame && !isClient ? "" : effectiveCode, modules);
|
|
26
|
+
useLayoutEffect(() => () => setError(null), [effectiveCode, setError]);
|
|
24
27
|
const { ref: contentRef, css: dynamicCSS } = useDynamicTailwind(effectiveCode, dynamicTailwind);
|
|
28
|
+
const mergedRef = useMergedRef(contentRef, ref);
|
|
25
29
|
const componentProps = useMemo(() => ({ ...props }), [props]);
|
|
30
|
+
const clearError = () => setError(null);
|
|
26
31
|
const renderProvider = (component) => {
|
|
27
32
|
return provider ? provider(component) : component;
|
|
28
33
|
};
|
|
29
34
|
if (module && module.error) return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
|
|
35
|
+
...divProps,
|
|
36
|
+
ref,
|
|
30
37
|
className: cn(preview_module_default.fill, classNames),
|
|
38
|
+
style,
|
|
31
39
|
children: /* @__PURE__ */ jsx(Error, {
|
|
32
40
|
message: module.error,
|
|
33
41
|
title: messages.errors.compile
|
|
34
42
|
})
|
|
35
|
-
}), /* @__PURE__ */ jsx(Error.Runtime, {
|
|
43
|
+
}), /* @__PURE__ */ jsx(Error.Runtime, {
|
|
44
|
+
open: isError,
|
|
45
|
+
reset: clearError
|
|
46
|
+
})] });
|
|
36
47
|
const Component = module?.exports?.default;
|
|
37
48
|
if (!Component) return null;
|
|
38
49
|
return /* @__PURE__ */ jsxs(Fragment, { children: [frame ? /* @__PURE__ */ jsx("div", {
|
|
50
|
+
...divProps,
|
|
51
|
+
ref,
|
|
39
52
|
className: cn(preview_module_default.fill, classNames),
|
|
53
|
+
style,
|
|
40
54
|
children: /* @__PURE__ */ jsx(Frame, {
|
|
41
55
|
...frame,
|
|
42
56
|
children: (container) => /* @__PURE__ */ jsx("div", {
|
|
@@ -56,12 +70,14 @@ const Client = ({ code: _code, className, showError, props = NO_PROPS, modules =
|
|
|
56
70
|
})
|
|
57
71
|
})
|
|
58
72
|
}) : /* @__PURE__ */ jsx("div", {
|
|
59
|
-
|
|
73
|
+
...divProps,
|
|
74
|
+
ref: mergedRef,
|
|
60
75
|
className: cn(preview_module_default.fill, preview_module_default.scroll, classNames),
|
|
61
76
|
style: {
|
|
62
77
|
isolation: "isolate",
|
|
63
78
|
transform: "translateZ(0)",
|
|
64
|
-
containerType: "inline-size"
|
|
79
|
+
containerType: "inline-size",
|
|
80
|
+
...style
|
|
65
81
|
},
|
|
66
82
|
children: /* @__PURE__ */ jsx(Error.Boundary, {
|
|
67
83
|
resetKeys: [effectiveCode],
|
|
@@ -71,7 +87,10 @@ const Client = ({ code: _code, className, showError, props = NO_PROPS, modules =
|
|
|
71
87
|
children: [renderStableComponent(Component, effectiveCode, componentProps), dynamicTailwind && dynamicCSS && /* @__PURE__ */ jsx("style", { children: dynamicCSS })]
|
|
72
88
|
}))
|
|
73
89
|
})
|
|
74
|
-
}), /* @__PURE__ */ jsx(Error.Runtime, {
|
|
90
|
+
}), /* @__PURE__ */ jsx(Error.Runtime, {
|
|
91
|
+
open: isError,
|
|
92
|
+
reset: clearError
|
|
93
|
+
})] });
|
|
75
94
|
};
|
|
76
95
|
//#endregion
|
|
77
96
|
//#region src/components/preview/preview.tsx
|
|
@@ -88,4 +107,4 @@ const Preview = ({ code, props = NO_PROPS, modules = NO_MODULES, dynamicTailwind
|
|
|
88
107
|
//#endregion
|
|
89
108
|
export { Preview as t };
|
|
90
109
|
|
|
91
|
-
//# sourceMappingURL=preview-
|
|
110
|
+
//# sourceMappingURL=preview-DFb1pOqJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview-DFb1pOqJ.js","names":["styles","LiveError"],"sources":["../src/components/preview/preview.module.css","../src/components/preview/client.tsx","../src/components/preview/preview.tsx"],"sourcesContent":["@layer components {\n .fill {\n position: relative;\n width: 100%;\n height: 100%;\n }\n\n .scroll {\n overflow-x: hidden;\n overflow-y: auto;\n }\n\n /* Hides the preview while the runtime error overlay covers it. */\n .hidden {\n display: none;\n }\n}\n","import { useLayoutEffect, useMemo } from 'react';\n\nimport { useMergedRef } from '@jbpark/use-hooks';\n\nimport { useLiveMessages } from '~/components/context/messages';\nimport { useError, usePreview } from '~/components/context/states';\nimport LiveError from '~/components/error';\nimport Frame, { type FrameProps } from '~/components/frame';\nimport { useIsClient } from '~/components/frame/use-is-client';\nimport { cn } from '~/utils/cn';\n\nimport styles from './preview.module.css';\n\nimport { NO_MODULES, NO_PROPS } from './defaults';\nimport { renderStableComponent } from './stable-component';\nimport type { Props } from './types';\nimport { useCompiledModule } from './use-compiled-module';\nimport { useDynamicTailwind } from './use-dynamic-tailwind';\n\nconst Client = ({\n code: _code,\n className,\n showError,\n props = NO_PROPS,\n modules = NO_MODULES,\n frame,\n dynamicTailwind = false,\n provider,\n // Kept out of the DOM; it has no effect.\n container: _container,\n style,\n ref,\n // The remaining div props, for the outer wrapper in every branch (#721).\n ...divProps\n}: Props) => {\n const { code } = usePreview();\n const { error, setError } = useError();\n const messages = useLiveMessages();\n const isError = !!showError && !!error;\n\n const classNames = cn(isError && styles.hidden, className);\n\n const effectiveCode = _code === undefined ? code : _code;\n\n const isClient = useIsClient();\n\n // A frame renders nothing on the server, so the code isn't compiled or run\n // there. Without one the server renders the preview, as before (#716).\n const module = useCompiledModule(\n frame && !isClient ? '' : effectiveCode,\n modules,\n );\n\n // Clears the error when the code changes, as the provider's `setCode`\n // does, which a `code` prop never calls (#714). In the cleanup, which runs\n // before the new code's own render error is reported, so that one stays.\n useLayoutEffect(() => () => setError(null), [effectiveCode, setError]);\n\n // Attached to the wrapper below; scans the rendered DOM so classes coming\n // from an imported component are picked up too. See the hook for details.\n const { ref: contentRef, css: dynamicCSS } = useDynamicTailwind(\n effectiveCode,\n dynamicTailwind,\n );\n\n const mergedRef = useMergedRef(contentRef, ref);\n\n const componentProps = useMemo(\n () => ({\n ...props,\n }),\n [props],\n );\n\n const clearError = () => setError(null);\n\n const renderProvider = (component: React.ReactNode) => {\n return provider ? provider(component) : component;\n };\n\n if (module && module.error) {\n return (\n <>\n <div\n {...divProps}\n ref={ref}\n className={cn(styles.fill, classNames)}\n style={style}\n >\n <LiveError message={module.error} title={messages.errors.compile} />\n </div>\n <LiveError.Runtime open={isError} reset={clearError} />\n </>\n );\n }\n\n const Component = module?.exports?.default;\n\n if (!Component) {\n return null;\n }\n\n return (\n <>\n {frame ? (\n <div\n {...divProps}\n ref={ref}\n className={cn(styles.fill, classNames)}\n style={style}\n >\n <Frame {...(frame as FrameProps)}>\n {container => (\n <div ref={contentRef} style={{ display: 'contents' }}>\n <LiveError.Boundary\n resetKeys={[effectiveCode]}\n onError={(e: Error) => setError(e.message)}\n >\n {renderProvider(\n <LiveError.Guard onError={e => setError(e.message)}>\n {/* Keeps the DOM when an edit leaves the hooks alone. */}\n {renderStableComponent(Component, effectiveCode, {\n ...componentProps,\n container,\n })}\n {dynamicTailwind && dynamicCSS && (\n <style>{dynamicCSS}</style>\n )}\n </LiveError.Guard>,\n )}\n </LiveError.Boundary>\n </div>\n )}\n </Frame>\n </div>\n ) : (\n <div\n {...divProps}\n ref={mergedRef}\n className={cn(styles.fill, styles.scroll, classNames)}\n // The host's style last, so it can override these, as in\n // `Live.Error`.\n style={{\n isolation: 'isolate',\n transform: 'translateZ(0)',\n containerType: 'inline-size',\n ...style,\n }}\n >\n <LiveError.Boundary\n resetKeys={[effectiveCode]}\n onError={e => setError(e.message)}\n >\n {renderProvider(\n <LiveError.Guard onError={e => setError(e.message)}>\n {renderStableComponent(\n Component,\n effectiveCode,\n componentProps,\n )}\n {dynamicTailwind && dynamicCSS && <style>{dynamicCSS}</style>}\n </LiveError.Guard>,\n )}\n </LiveError.Boundary>\n </div>\n )}\n <LiveError.Runtime open={isError} reset={clearError} />\n </>\n );\n};\n\nexport default Client;\n","import Client from './client';\nimport { NO_MODULES, NO_PROPS } from './defaults';\nimport type { Props } from './types';\n\n// `Live.Preview`: a thin wrapper around `Client`, which compiles, handles\n// errors and wraps the frame. One render path for both `code` and the\n// provider's code (#187).\nconst Preview = ({\n code,\n props = NO_PROPS,\n modules = NO_MODULES,\n dynamicTailwind = false,\n provider,\n ...restProps\n}: Props) => {\n return (\n <Client\n code={code}\n props={props}\n modules={modules}\n dynamicTailwind={dynamicTailwind}\n provider={provider}\n {...restProps}\n />\n );\n};\n\nexport default Preview;\n"],"mappings":"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"}
|
package/dist/provider/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { i as useLiveMessages, n as defaultMessages } from "../messages-DrINcRdG.js";
|
|
2
|
-
import { t as ContextProvider } from "../context-
|
|
2
|
+
import { t as ContextProvider } from "../context-DJxX9epB.js";
|
|
3
3
|
export { ContextProvider as default, defaultMessages, useLiveMessages };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as inspectDocument, i as getSections, o as parseDocument, r as generateSectionPreview, s as replaceDocumentSections } from "./document-
|
|
2
|
-
import {
|
|
1
|
+
import { a as inspectDocument, i as getSections, o as parseDocument, r as generateSectionPreview, s as replaceDocumentSections } from "./document-MkQGxfry.js";
|
|
2
|
+
import { d as documentTemplate, s as DEFAULT_CONTAINER_ID } from "./editor-caches-DXYXgWeD.js";
|
|
3
3
|
//#region src/utils/sections.ts
|
|
4
4
|
const extractSections = (code, options) => {
|
|
5
5
|
const doc = parseDocument(code, options);
|
|
@@ -23,4 +23,4 @@ const checkDocument = (code, options) => {
|
|
|
23
23
|
//#endregion
|
|
24
24
|
export { replaceSections as a, generateSection as i, createDocument as n, extractSections as r, checkDocument as t };
|
|
25
25
|
|
|
26
|
-
//# sourceMappingURL=sections-
|
|
26
|
+
//# sourceMappingURL=sections-CnG7OLr8.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sections-
|
|
1
|
+
{"version":3,"file":"sections-CnG7OLr8.js","names":[],"sources":["../src/utils/sections.ts"],"sourcesContent":["import { DEFAULT_CONTAINER_ID, documentTemplate } from '~/constants';\nimport type { Section } from '~/types';\n\nimport {\n type DocumentOptions,\n type DocumentProblem,\n type SectionOptions,\n createSectionPreviewCache,\n generateSectionPreview,\n getSections,\n inspectDocument,\n parseDocument,\n replaceDocumentSections,\n} from './ast/document';\n\nexport const extractSections = (\n code: string,\n options?: SectionOptions,\n): Section[] => {\n const doc = parseDocument(code, options);\n\n return doc ? getSections(doc, options) : [];\n};\n\nexport const replaceSections = (\n code: string,\n sections: string[],\n options?: DocumentOptions,\n): string => {\n return replaceDocumentSections(code, sections, options);\n};\n\nexport const generateSection = (\n code: string,\n fullCode: string,\n options?: DocumentOptions,\n) => {\n return generateSectionPreview(fullCode, code, options);\n};\n\n// A new, empty document `Live.Dnd` can add sections to: an `App` component\n// rendering the container element and nothing else. Start a controlled\n// `Live.Dnd` from this rather than an empty string, which has no container,\n// so nothing dropped on the canvas would land anywhere (#449). Pass the same\n// `containerId` you give `Live.Dnd`.\nexport const createDocument = ({\n containerId = DEFAULT_CONTAINER_ID,\n}: DocumentOptions = {}): string => {\n // The id is written into a JSX attribute as-is, so anything that could end\n // the attribute or the tag is refused rather than producing broken source.\n if (!/^[^\\s\"'<>{}]+$/.test(containerId)) {\n throw new Error(\n `createDocument: containerId must be a plain element id, got ${JSON.stringify(containerId)}`,\n );\n }\n\n return documentTemplate(containerId);\n};\n\n// Whether `Live.Dnd` can edit a document: it parses, and it has the\n// container. A host can check one before saving or loading it, and gets the\n// same reasons `Live.Dnd` reports through `onEditError` (#522).\nexport type DocumentCheck = { ok: true } | ({ ok: false } & DocumentProblem);\n\nexport const checkDocument = (\n code: string,\n options?: DocumentOptions,\n): DocumentCheck => {\n const inspection = inspectDocument(code, options);\n\n if (inspection.ok) {\n return { ok: true };\n }\n\n // A copy: the inspection is cached and shared with `Live.Dnd`.\n return { ...inspection };\n};\n\n// Generates every section's preview from one parse and reuses an unchanged\n// preview between calls (#131). Keep one instance per editor, as `Live.Dnd`\n// does.\nexport { createSectionPreviewCache };\nexport type {\n DocumentOptions,\n DocumentProblem,\n SectionOptions,\n} from './ast/document';\n"],"mappings":";;;AAeA,MAAa,mBACX,MACA,YACc;CACd,MAAM,MAAM,cAAc,MAAM,OAAO;CAEvC,OAAO,MAAM,YAAY,KAAK,OAAO,IAAI,CAAC;AAC5C;AAEA,MAAa,mBACX,MACA,UACA,YACW;CACX,OAAO,wBAAwB,MAAM,UAAU,OAAO;AACxD;AAEA,MAAa,mBACX,MACA,UACA,YACG;CACH,OAAO,uBAAuB,UAAU,MAAM,OAAO;AACvD;AAOA,MAAa,kBAAkB,EAC7B,cAAc,yBACK,CAAC,MAAc;CAGlC,IAAI,CAAC,iBAAiB,KAAK,WAAW,GACpC,MAAM,IAAI,MACR,+DAA+D,KAAK,UAAU,WAAW,GAC3F;CAGF,OAAO,iBAAiB,WAAW;AACrC;AAOA,MAAa,iBACX,MACA,YACkB;CAClB,MAAM,aAAa,gBAAgB,MAAM,OAAO;CAEhD,IAAI,WAAW,IACb,OAAO,EAAE,IAAI,KAAK;CAIpB,OAAO,EAAE,GAAG,WAAW;AACzB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"states-Ci1AvoQ9.js","names":[],"sources":["../src/components/context/states.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"states-Ci1AvoQ9.js","names":[],"sources":["../src/components/context/states.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\nimport type { Dispatch, SetStateAction } from 'react';\n\nexport interface PreviewContextType {\n code: string;\n setCode: Dispatch<SetStateAction<string>>;\n}\n\nexport interface ErrorContextType {\n error: string | null;\n setError: Dispatch<SetStateAction<string | null>>;\n}\n\n// `undefined` outside a provider, so `usePreview` and `useError` can throw\n// there instead of silently doing nothing.\nexport const PreviewContext = createContext<PreviewContextType | undefined>(\n undefined,\n);\n\nexport const ErrorContext = createContext<ErrorContextType | undefined>(\n undefined,\n);\n\nexport const usePreview = () => {\n const context = useContext(PreviewContext);\n\n if (context === undefined) {\n throw new Error('usePreview must be used within <Live> (ContextProvider)');\n }\n\n return context;\n};\n\nexport const useError = () => {\n const context = useContext(ErrorContext);\n\n if (context === undefined) {\n throw new Error('useError must be used within <Live> (ContextProvider)');\n }\n\n return context;\n};\n"],"mappings":";;AAeA,MAAa,iBAAiB,cAC5B,KAAA,CACF;AAEA,MAAa,eAAe,cAC1B,KAAA,CACF;AAEA,MAAa,mBAAmB;CAC9B,MAAM,UAAU,WAAW,cAAc;CAEzC,IAAI,YAAY,KAAA,GACd,MAAM,IAAI,MAAM,yDAAyD;CAG3E,OAAO;AACT;AAEA,MAAa,iBAAiB;CAC5B,MAAM,UAAU,WAAW,YAAY;CAEvC,IAAI,YAAY,KAAA,GACd,MAAM,IAAI,MAAM,uDAAuD;CAGzE,OAAO;AACT"}
|