@immediately-run/sdk 0.58.0 → 0.59.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/dist/agentLoop.cjs +16 -23
- package/dist/agentLoop.cjs.map +1 -1
- package/dist/agentLoop.js +16 -23
- package/dist/agentLoop.js.map +1 -1
- package/dist/components/Link.cjs +14 -8
- package/dist/components/Link.cjs.map +1 -1
- package/dist/components/Link.d.cts +1 -1
- package/dist/components/Link.d.ts +1 -1
- package/dist/components/Link.js +14 -8
- package/dist/components/Link.js.map +1 -1
- package/dist/components/MDXComponents.cjs.map +1 -1
- package/dist/components/MDXComponents.js.map +1 -1
- package/dist/components/ScrollAfterNavigation.cjs.map +1 -1
- package/dist/components/ScrollAfterNavigation.js.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/markers.cjs.map +1 -1
- package/dist/markers.js.map +1 -1
- package/dist/moduleCache.cjs.map +1 -1
- package/dist/moduleCache.js.map +1 -1
- package/dist/mounts.cjs.map +1 -1
- package/dist/mounts.d.cts +6 -0
- package/dist/mounts.d.ts +6 -0
- package/dist/mounts.js.map +1 -1
- package/dist/ready.cjs.map +1 -1
- package/dist/ready.js.map +1 -1
- package/dist/theme.cjs +93 -9
- package/dist/theme.cjs.map +1 -1
- package/dist/theme.d.cts +133 -16
- package/dist/theme.d.ts +133 -16
- package/dist/theme.js +84 -9
- package/dist/theme.js.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.d.cts +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +2 -2
package/dist/components/Link.cjs
CHANGED
|
@@ -29,22 +29,29 @@ var import_routing = require("../routing");
|
|
|
29
29
|
var import_scrollToId = require("../scrollToId");
|
|
30
30
|
var import_TinkerableContext = require("../TinkerableContext");
|
|
31
31
|
var import_urlUtils = require("../urlUtils");
|
|
32
|
+
const useComposedAnchorClick = (onClick, intercept, interceptDeps) => (0, import_react.useCallback)(
|
|
33
|
+
(e) => {
|
|
34
|
+
onClick?.(e);
|
|
35
|
+
if (e.defaultPrevented) return;
|
|
36
|
+
intercept(e);
|
|
37
|
+
},
|
|
38
|
+
[onClick, ...interceptDeps]
|
|
39
|
+
);
|
|
32
40
|
const FragmentLink = ({
|
|
33
41
|
href,
|
|
34
42
|
children,
|
|
35
43
|
onClick,
|
|
36
44
|
...props
|
|
37
45
|
}) => {
|
|
38
|
-
const clickHandler = (
|
|
46
|
+
const clickHandler = useComposedAnchorClick(
|
|
47
|
+
onClick,
|
|
39
48
|
(e) => {
|
|
40
|
-
onClick?.(e);
|
|
41
|
-
if (e.defaultPrevented) return;
|
|
42
49
|
if (href && href.startsWith("#")) {
|
|
43
50
|
e.preventDefault();
|
|
44
51
|
(0, import_scrollToId.scrollToId)(href.slice(1));
|
|
45
52
|
}
|
|
46
53
|
},
|
|
47
|
-
[href
|
|
54
|
+
[href]
|
|
48
55
|
);
|
|
49
56
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href, onClick: clickHandler, ...props, children });
|
|
50
57
|
};
|
|
@@ -55,17 +62,16 @@ const InternalLink = ({
|
|
|
55
62
|
target,
|
|
56
63
|
...props
|
|
57
64
|
}) => {
|
|
58
|
-
const clickHandler = (
|
|
65
|
+
const clickHandler = useComposedAnchorClick(
|
|
66
|
+
onClick,
|
|
59
67
|
(e) => {
|
|
60
|
-
onClick?.(e);
|
|
61
|
-
if (e.defaultPrevented) return;
|
|
62
68
|
if (!href) return;
|
|
63
69
|
if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || e.button !== 0) return;
|
|
64
70
|
if (target && target !== "_self") return;
|
|
65
71
|
e.preventDefault();
|
|
66
72
|
(0, import_routing.navigate)(href);
|
|
67
73
|
},
|
|
68
|
-
[href,
|
|
74
|
+
[href, target]
|
|
69
75
|
);
|
|
70
76
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { ...props, href, target, onClick: clickHandler, children });
|
|
71
77
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/Link.tsx"],"sourcesContent":["import { ReactNode, use, useCallback } from 'react';\nimport { navigate } from '../routing';\nimport { scrollToId } from '../scrollToId';\nimport { TinkerableContext } from '../TinkerableContext';\nimport { constructOuterUrl, isInternalHref } from '../urlUtils';\n\n/** A same-page anchor (`#frag`): scrolls the addressed section into view on click\n * **without a route change** (MARKDOWN_SYNTAX_SPEC §13.5). The default behavior of a\n * bare `#`-href is intercepted so the sandbox URL the host owns is never mutated\n * out from under it; a fragment that names nothing leaves the scroll position\n * untouched (a soft failure). */\nexport const FragmentLink = ({\n href,\n children,\n onClick,\n ...props\n}: React.DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>): ReactNode => {\n const clickHandler =
|
|
1
|
+
{"version":3,"sources":["../../src/components/Link.tsx"],"sourcesContent":["import { ReactNode, use, useCallback } from 'react';\nimport { navigate } from '../routing';\nimport { scrollToId } from '../scrollToId';\nimport { TinkerableContext } from '../TinkerableContext';\nimport { constructOuterUrl, isInternalHref } from '../urlUtils';\n\n/** The click contract shared by this module's link primitives: a consumer-supplied\n * `onClick` is COMPOSED with the interception, never substituted for it. The\n * consumer handler runs FIRST and calling `preventDefault()` in it opts the click\n * out of the interception entirely; otherwise `intercept` runs. Both primitives\n * spelled this out inline until they were one named contract, which is how they\n * drifted apart once already (see {@link InternalLink}).\n *\n * `intercept` is re-created on every render, so it is deliberately NOT a\n * dependency: `interceptDeps` names the values it closes over, and the memo is\n * invalidated exactly when those change — the dependency set each call site had\n * when it wrote the handler out by hand. */\nconst useComposedAnchorClick = (\n onClick: React.MouseEventHandler<HTMLAnchorElement> | undefined,\n intercept: (e: React.MouseEvent<HTMLAnchorElement>) => void,\n interceptDeps: React.DependencyList,\n): React.MouseEventHandler<HTMLAnchorElement> =>\n useCallback(\n (e: React.MouseEvent<HTMLAnchorElement>) => {\n onClick?.(e);\n if (e.defaultPrevented) return;\n intercept(e);\n },\n [onClick, ...interceptDeps],\n );\n\n/** A same-page anchor (`#frag`): scrolls the addressed section into view on click\n * **without a route change** (MARKDOWN_SYNTAX_SPEC §13.5). The default behavior of a\n * bare `#`-href is intercepted so the sandbox URL the host owns is never mutated\n * out from under it; a fragment that names nothing leaves the scroll position\n * untouched (a soft failure). */\nexport const FragmentLink = ({\n href,\n children,\n onClick,\n ...props\n}: React.DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>): ReactNode => {\n const clickHandler = useComposedAnchorClick(\n onClick,\n (e) => {\n if (href && href.startsWith('#')) {\n e.preventDefault();\n scrollToId(href.slice(1));\n }\n },\n [href],\n );\n return (\n <a href={href} onClick={clickHandler} {...props}>\n {children}\n </a>\n );\n};\n\n/** An `<a>` that performs in-sandbox navigation on click (prevents the default\n * full-page load and routes via {@link navigate}).\n *\n * A consumer-supplied `onClick` is COMPOSED with the router interception, never\n * substituted for it (`useComposedAnchorClick` above): it runs first, and\n * calling `preventDefault()` opts out of routing. Regression guard: `...props`\n * used to spread AFTER `onClick={clickHandler}`, so a consumer `onClick` (e.g. a\n * drawer's close-on-navigate) silently REPLACED the interception — the default\n * anchor action then navigated the sandboxed iframe itself to the host URL,\n * reloading the whole app (and framing the host inside its own sandbox).\n *\n * Modifier/middle clicks and explicit non-self `target`s keep the browser\n * default: the rendered href is a real host URL, so open-in-new-tab works. */\nexport const InternalLink = ({\n href,\n children,\n onClick,\n target,\n ...props\n}: React.DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>): ReactNode => {\n const clickHandler = useComposedAnchorClick(\n onClick,\n (e) => {\n if (!href) return;\n // Open-in-new-tab gestures (and an explicit target) are the browser's.\n if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || e.button !== 0) return;\n if (target && target !== '_self') return;\n e.preventDefault();\n navigate(href);\n },\n [href, target],\n );\n // Spread FIRST so no forwarded prop can clobber the interception or the href.\n return (\n <a {...props} href={href} target={target} onClick={clickHandler}>\n {children}\n </a>\n );\n};\n\n/** A link that routes same-app hrefs through the sandbox router (as an\n * {@link InternalLink}) and renders external hrefs as a plain `<a>`. */\nexport const Link = ({\n href,\n children,\n ...properties\n}: React.DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>): ReactNode => {\n const { outerHref, navigationState } = use(TinkerableContext);\n // A pure same-page fragment (`#sec-8-9`) scrolls in place — no route change (§13.5).\n if (href && href.startsWith('#')) {\n return (\n <FragmentLink href={href} {...properties}>\n {children}\n </FragmentLink>\n );\n }\n if (href && isInternalHref(outerHref, href, navigationState)) {\n const targetHref = constructOuterUrl(outerHref, href, navigationState);\n return (\n <InternalLink href={targetHref} {...properties}>\n {children}\n </InternalLink>\n );\n } else {\n // create a regular link to external resource\n return <a {...{ href, ...properties }}>{children}</a>;\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqDI;AArDJ,mBAA4C;AAC5C,qBAAyB;AACzB,wBAA2B;AAC3B,+BAAkC;AAClC,sBAAkD;AAalD,MAAM,yBAAyB,CAC7B,SACA,WACA,sBAEA;AAAA,EACE,CAAC,MAA2C;AAC1C,cAAU,CAAC;AACX,QAAI,EAAE,iBAAkB;AACxB,cAAU,CAAC;AAAA,EACb;AAAA,EACA,CAAC,SAAS,GAAG,aAAa;AAC5B;AAOK,MAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAA4G;AAC1G,QAAM,eAAe;AAAA,IACnB;AAAA,IACA,CAAC,MAAM;AACL,UAAI,QAAQ,KAAK,WAAW,GAAG,GAAG;AAChC,UAAE,eAAe;AACjB,0CAAW,KAAK,MAAM,CAAC,CAAC;AAAA,MAC1B;AAAA,IACF;AAAA,IACA,CAAC,IAAI;AAAA,EACP;AACA,SACE,4CAAC,OAAE,MAAY,SAAS,cAAe,GAAG,OACvC,UACH;AAEJ;AAeO,MAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAA4G;AAC1G,QAAM,eAAe;AAAA,IACnB;AAAA,IACA,CAAC,MAAM;AACL,UAAI,CAAC,KAAM;AAEX,UAAI,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAG;AACxE,UAAI,UAAU,WAAW,QAAS;AAClC,QAAE,eAAe;AACjB,mCAAS,IAAI;AAAA,IACf;AAAA,IACA,CAAC,MAAM,MAAM;AAAA,EACf;AAEA,SACE,4CAAC,OAAG,GAAG,OAAO,MAAY,QAAgB,SAAS,cAChD,UACH;AAEJ;AAIO,MAAM,OAAO,CAAC;AAAA,EACnB;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAA4G;AAC1G,QAAM,EAAE,WAAW,gBAAgB,QAAI,kBAAI,0CAAiB;AAE5D,MAAI,QAAQ,KAAK,WAAW,GAAG,GAAG;AAChC,WACE,4CAAC,gBAAa,MAAa,GAAG,YAC3B,UACH;AAAA,EAEJ;AACA,MAAI,YAAQ,gCAAe,WAAW,MAAM,eAAe,GAAG;AAC5D,UAAM,iBAAa,mCAAkB,WAAW,MAAM,eAAe;AACrE,WACE,4CAAC,gBAAa,MAAM,YAAa,GAAG,YACjC,UACH;AAAA,EAEJ,OAAO;AAEL,WAAO,4CAAC,OAAG,GAAG,EAAE,MAAM,GAAG,WAAW,GAAI,UAAS;AAAA,EACnD;AACF;","names":[]}
|
|
@@ -10,7 +10,7 @@ declare const FragmentLink: ({ href, children, onClick, ...props }: React.Detail
|
|
|
10
10
|
* full-page load and routes via {@link navigate}).
|
|
11
11
|
*
|
|
12
12
|
* A consumer-supplied `onClick` is COMPOSED with the router interception, never
|
|
13
|
-
* substituted for it (
|
|
13
|
+
* substituted for it (`useComposedAnchorClick` above): it runs first, and
|
|
14
14
|
* calling `preventDefault()` opts out of routing. Regression guard: `...props`
|
|
15
15
|
* used to spread AFTER `onClick={clickHandler}`, so a consumer `onClick` (e.g. a
|
|
16
16
|
* drawer's close-on-navigate) silently REPLACED the interception — the default
|
|
@@ -10,7 +10,7 @@ declare const FragmentLink: ({ href, children, onClick, ...props }: React.Detail
|
|
|
10
10
|
* full-page load and routes via {@link navigate}).
|
|
11
11
|
*
|
|
12
12
|
* A consumer-supplied `onClick` is COMPOSED with the router interception, never
|
|
13
|
-
* substituted for it (
|
|
13
|
+
* substituted for it (`useComposedAnchorClick` above): it runs first, and
|
|
14
14
|
* calling `preventDefault()` opts out of routing. Regression guard: `...props`
|
|
15
15
|
* used to spread AFTER `onClick={clickHandler}`, so a consumer `onClick` (e.g. a
|
|
16
16
|
* drawer's close-on-navigate) silently REPLACED the interception — the default
|
package/dist/components/Link.js
CHANGED
|
@@ -5,22 +5,29 @@ import { navigate } from "../routing";
|
|
|
5
5
|
import { scrollToId } from "../scrollToId";
|
|
6
6
|
import { TinkerableContext } from "../TinkerableContext";
|
|
7
7
|
import { constructOuterUrl, isInternalHref } from "../urlUtils";
|
|
8
|
+
const useComposedAnchorClick = (onClick, intercept, interceptDeps) => useCallback(
|
|
9
|
+
(e) => {
|
|
10
|
+
onClick?.(e);
|
|
11
|
+
if (e.defaultPrevented) return;
|
|
12
|
+
intercept(e);
|
|
13
|
+
},
|
|
14
|
+
[onClick, ...interceptDeps]
|
|
15
|
+
);
|
|
8
16
|
const FragmentLink = ({
|
|
9
17
|
href,
|
|
10
18
|
children,
|
|
11
19
|
onClick,
|
|
12
20
|
...props
|
|
13
21
|
}) => {
|
|
14
|
-
const clickHandler =
|
|
22
|
+
const clickHandler = useComposedAnchorClick(
|
|
23
|
+
onClick,
|
|
15
24
|
(e) => {
|
|
16
|
-
onClick?.(e);
|
|
17
|
-
if (e.defaultPrevented) return;
|
|
18
25
|
if (href && href.startsWith("#")) {
|
|
19
26
|
e.preventDefault();
|
|
20
27
|
scrollToId(href.slice(1));
|
|
21
28
|
}
|
|
22
29
|
},
|
|
23
|
-
[href
|
|
30
|
+
[href]
|
|
24
31
|
);
|
|
25
32
|
return /* @__PURE__ */ jsx("a", { href, onClick: clickHandler, ...props, children });
|
|
26
33
|
};
|
|
@@ -31,17 +38,16 @@ const InternalLink = ({
|
|
|
31
38
|
target,
|
|
32
39
|
...props
|
|
33
40
|
}) => {
|
|
34
|
-
const clickHandler =
|
|
41
|
+
const clickHandler = useComposedAnchorClick(
|
|
42
|
+
onClick,
|
|
35
43
|
(e) => {
|
|
36
|
-
onClick?.(e);
|
|
37
|
-
if (e.defaultPrevented) return;
|
|
38
44
|
if (!href) return;
|
|
39
45
|
if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || e.button !== 0) return;
|
|
40
46
|
if (target && target !== "_self") return;
|
|
41
47
|
e.preventDefault();
|
|
42
48
|
navigate(href);
|
|
43
49
|
},
|
|
44
|
-
[href,
|
|
50
|
+
[href, target]
|
|
45
51
|
);
|
|
46
52
|
return /* @__PURE__ */ jsx("a", { ...props, href, target, onClick: clickHandler, children });
|
|
47
53
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/Link.tsx"],"sourcesContent":["import { ReactNode, use, useCallback } from 'react';\nimport { navigate } from '../routing';\nimport { scrollToId } from '../scrollToId';\nimport { TinkerableContext } from '../TinkerableContext';\nimport { constructOuterUrl, isInternalHref } from '../urlUtils';\n\n/** A same-page anchor (`#frag`): scrolls the addressed section into view on click\n * **without a route change** (MARKDOWN_SYNTAX_SPEC §13.5). The default behavior of a\n * bare `#`-href is intercepted so the sandbox URL the host owns is never mutated\n * out from under it; a fragment that names nothing leaves the scroll position\n * untouched (a soft failure). */\nexport const FragmentLink = ({\n href,\n children,\n onClick,\n ...props\n}: React.DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>): ReactNode => {\n const clickHandler =
|
|
1
|
+
{"version":3,"sources":["../../src/components/Link.tsx"],"sourcesContent":["import { ReactNode, use, useCallback } from 'react';\nimport { navigate } from '../routing';\nimport { scrollToId } from '../scrollToId';\nimport { TinkerableContext } from '../TinkerableContext';\nimport { constructOuterUrl, isInternalHref } from '../urlUtils';\n\n/** The click contract shared by this module's link primitives: a consumer-supplied\n * `onClick` is COMPOSED with the interception, never substituted for it. The\n * consumer handler runs FIRST and calling `preventDefault()` in it opts the click\n * out of the interception entirely; otherwise `intercept` runs. Both primitives\n * spelled this out inline until they were one named contract, which is how they\n * drifted apart once already (see {@link InternalLink}).\n *\n * `intercept` is re-created on every render, so it is deliberately NOT a\n * dependency: `interceptDeps` names the values it closes over, and the memo is\n * invalidated exactly when those change — the dependency set each call site had\n * when it wrote the handler out by hand. */\nconst useComposedAnchorClick = (\n onClick: React.MouseEventHandler<HTMLAnchorElement> | undefined,\n intercept: (e: React.MouseEvent<HTMLAnchorElement>) => void,\n interceptDeps: React.DependencyList,\n): React.MouseEventHandler<HTMLAnchorElement> =>\n useCallback(\n (e: React.MouseEvent<HTMLAnchorElement>) => {\n onClick?.(e);\n if (e.defaultPrevented) return;\n intercept(e);\n },\n [onClick, ...interceptDeps],\n );\n\n/** A same-page anchor (`#frag`): scrolls the addressed section into view on click\n * **without a route change** (MARKDOWN_SYNTAX_SPEC §13.5). The default behavior of a\n * bare `#`-href is intercepted so the sandbox URL the host owns is never mutated\n * out from under it; a fragment that names nothing leaves the scroll position\n * untouched (a soft failure). */\nexport const FragmentLink = ({\n href,\n children,\n onClick,\n ...props\n}: React.DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>): ReactNode => {\n const clickHandler = useComposedAnchorClick(\n onClick,\n (e) => {\n if (href && href.startsWith('#')) {\n e.preventDefault();\n scrollToId(href.slice(1));\n }\n },\n [href],\n );\n return (\n <a href={href} onClick={clickHandler} {...props}>\n {children}\n </a>\n );\n};\n\n/** An `<a>` that performs in-sandbox navigation on click (prevents the default\n * full-page load and routes via {@link navigate}).\n *\n * A consumer-supplied `onClick` is COMPOSED with the router interception, never\n * substituted for it (`useComposedAnchorClick` above): it runs first, and\n * calling `preventDefault()` opts out of routing. Regression guard: `...props`\n * used to spread AFTER `onClick={clickHandler}`, so a consumer `onClick` (e.g. a\n * drawer's close-on-navigate) silently REPLACED the interception — the default\n * anchor action then navigated the sandboxed iframe itself to the host URL,\n * reloading the whole app (and framing the host inside its own sandbox).\n *\n * Modifier/middle clicks and explicit non-self `target`s keep the browser\n * default: the rendered href is a real host URL, so open-in-new-tab works. */\nexport const InternalLink = ({\n href,\n children,\n onClick,\n target,\n ...props\n}: React.DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>): ReactNode => {\n const clickHandler = useComposedAnchorClick(\n onClick,\n (e) => {\n if (!href) return;\n // Open-in-new-tab gestures (and an explicit target) are the browser's.\n if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || e.button !== 0) return;\n if (target && target !== '_self') return;\n e.preventDefault();\n navigate(href);\n },\n [href, target],\n );\n // Spread FIRST so no forwarded prop can clobber the interception or the href.\n return (\n <a {...props} href={href} target={target} onClick={clickHandler}>\n {children}\n </a>\n );\n};\n\n/** A link that routes same-app hrefs through the sandbox router (as an\n * {@link InternalLink}) and renders external hrefs as a plain `<a>`. */\nexport const Link = ({\n href,\n children,\n ...properties\n}: React.DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>): ReactNode => {\n const { outerHref, navigationState } = use(TinkerableContext);\n // A pure same-page fragment (`#sec-8-9`) scrolls in place — no route change (§13.5).\n if (href && href.startsWith('#')) {\n return (\n <FragmentLink href={href} {...properties}>\n {children}\n </FragmentLink>\n );\n }\n if (href && isInternalHref(outerHref, href, navigationState)) {\n const targetHref = constructOuterUrl(outerHref, href, navigationState);\n return (\n <InternalLink href={targetHref} {...properties}>\n {children}\n </InternalLink>\n );\n } else {\n // create a regular link to external resource\n return <a {...{ href, ...properties }}>{children}</a>;\n }\n};\n"],"mappings":";AAqDI;AArDJ,SAAoB,KAAK,mBAAmB;AAC5C,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAC3B,SAAS,yBAAyB;AAClC,SAAS,mBAAmB,sBAAsB;AAalD,MAAM,yBAAyB,CAC7B,SACA,WACA,kBAEA;AAAA,EACE,CAAC,MAA2C;AAC1C,cAAU,CAAC;AACX,QAAI,EAAE,iBAAkB;AACxB,cAAU,CAAC;AAAA,EACb;AAAA,EACA,CAAC,SAAS,GAAG,aAAa;AAC5B;AAOK,MAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAA4G;AAC1G,QAAM,eAAe;AAAA,IACnB;AAAA,IACA,CAAC,MAAM;AACL,UAAI,QAAQ,KAAK,WAAW,GAAG,GAAG;AAChC,UAAE,eAAe;AACjB,mBAAW,KAAK,MAAM,CAAC,CAAC;AAAA,MAC1B;AAAA,IACF;AAAA,IACA,CAAC,IAAI;AAAA,EACP;AACA,SACE,oBAAC,OAAE,MAAY,SAAS,cAAe,GAAG,OACvC,UACH;AAEJ;AAeO,MAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAA4G;AAC1G,QAAM,eAAe;AAAA,IACnB;AAAA,IACA,CAAC,MAAM;AACL,UAAI,CAAC,KAAM;AAEX,UAAI,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAG;AACxE,UAAI,UAAU,WAAW,QAAS;AAClC,QAAE,eAAe;AACjB,eAAS,IAAI;AAAA,IACf;AAAA,IACA,CAAC,MAAM,MAAM;AAAA,EACf;AAEA,SACE,oBAAC,OAAG,GAAG,OAAO,MAAY,QAAgB,SAAS,cAChD,UACH;AAEJ;AAIO,MAAM,OAAO,CAAC;AAAA,EACnB;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAA4G;AAC1G,QAAM,EAAE,WAAW,gBAAgB,IAAI,IAAI,iBAAiB;AAE5D,MAAI,QAAQ,KAAK,WAAW,GAAG,GAAG;AAChC,WACE,oBAAC,gBAAa,MAAa,GAAG,YAC3B,UACH;AAAA,EAEJ;AACA,MAAI,QAAQ,eAAe,WAAW,MAAM,eAAe,GAAG;AAC5D,UAAM,aAAa,kBAAkB,WAAW,MAAM,eAAe;AACrE,WACE,oBAAC,gBAAa,MAAM,YAAa,GAAG,YACjC,UACH;AAAA,EAEJ,OAAO;AAEL,WAAO,oBAAC,OAAG,GAAG,EAAE,MAAM,GAAG,WAAW,GAAI,UAAS;AAAA,EACnD;AACF;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/MDXComponents.tsx"],"sourcesContent":["import { ReactNode, use } from 'react';\nimport { Admonition } from './Admonition';\nimport { FS_PREFIX, LinkSpaceContext,
|
|
1
|
+
{"version":3,"sources":["../../src/components/MDXComponents.tsx"],"sourcesContent":["import { ReactNode, use } from 'react';\nimport { Admonition } from './Admonition';\nimport { FS_PREFIX, LinkSpaceContext, resolveLinkTarget } from '../linkSpace';\nimport { splitHash } from '../urlUtils';\nimport { HeadingAnchor } from './HeadingAnchor';\nimport { Link } from './Link';\nimport { WikiLink } from './WikiLink';\n\n// The link primitives moved to ./Link so WikiLink can reuse Link without a\n// MDXComponents ↔ WikiLink import cycle (check:circular). Re-exported here so the\n// public `Link` / `InternalLink` entry points are unchanged.\nexport { InternalLink, Link } from './Link';\nexport { Admonition } from './Admonition';\nexport type { AdmonitionType } from './Admonition';\nexport { HeadingAnchor } from './HeadingAnchor';\nexport { WikiLink } from './WikiLink';\n\n/** Default MDX component overrides passed to {@link MDXProvider} by `boot`. These\n * are the platform's *phantom defaults* (MARKDOWN_SYNTAX_SPEC §11.2): they are\n * always present in the provider — even for a plain-markdown repo that never\n * calls `boot({ mdxComponents })` — so the platform-emitted `Admonition` (§12)\n * and `WikiLink` (§13) components resolve without the MDX missing-reference guard\n * firing, and Markdown links route in-app via {@link Link}. An app overrides any\n * of them by name via `boot({ mdxComponents })`, which *merges* over these\n * defaults (§11.3) — overriding `WikiLink` alone still keeps `a` and `Admonition`. */\nexport const DEFAULT_MDX_COMPONENTS = {\n a({\n href,\n children,\n ...properties\n }: React.DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>) {\n // R3-273 link spaces, same shared resolver as WikiLink: an `$fs:` href is\n // translated to its mount-absolute path; an ABSOLUTE href is corpus-rooted\n // when an enclosing LinkSpaceContext declares a corpusRoot (a non-corpus app\n // declares none and is untouched). Relative and external hrefs pass through —\n // <Link> already routes same-app hrefs and renders the rest as plain anchors.\n const { corpusRoot } = use(LinkSpaceContext);\n let mapped = href;\n if (href && (href.startsWith(FS_PREFIX) || (corpusRoot !== null && href.startsWith('/')))) {\n const [pathPart, frag] = splitHash(href);\n const resolution = resolveLinkTarget(pathPart, { corpusRoot });\n if (resolution.state !== 'resolved') {\n // Malformed `$fs:` (incl. scheme smuggling) — broken text, never an anchor.\n return (\n <span className=\"ir-link-broken\" data-state=\"broken\" title={`Invalid ${FS_PREFIX} link: ${href}`}>\n {children}\n </span>\n );\n }\n mapped = `${resolution.path}${frag ? `#${frag}` : ''}`;\n }\n return (\n <Link href={mapped} {...properties}>\n {children}\n </Link>\n );\n },\n Admonition,\n HeadingAnchor,\n WikiLink,\n} as Record<string, (props: any) => ReactNode>;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4CU;AA5CV,mBAA+B;AAC/B,wBAA2B;AAC3B,uBAA+D;AAC/D,sBAA0B;AAC1B,2BAA8B;AAC9B,kBAAqB;AACrB,sBAAyB;AAKzB,IAAAA,eAAmC;AACnC,IAAAC,qBAA2B;AAE3B,IAAAC,wBAA8B;AAC9B,IAAAC,mBAAyB;AAUlB,MAAM,yBAAyB;AAAA,EACpC,EAAE;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GAA8F;AAM5F,UAAM,EAAE,WAAW,QAAI,kBAAI,iCAAgB;AAC3C,QAAI,SAAS;AACb,QAAI,SAAS,KAAK,WAAW,0BAAS,KAAM,eAAe,QAAQ,KAAK,WAAW,GAAG,IAAK;AACzF,YAAM,CAAC,UAAU,IAAI,QAAI,2BAAU,IAAI;AACvC,YAAM,iBAAa,oCAAkB,UAAU,EAAE,WAAW,CAAC;AAC7D,UAAI,WAAW,UAAU,YAAY;AAEnC,eACE,4CAAC,UAAK,WAAU,kBAAiB,cAAW,UAAS,OAAO,WAAW,0BAAS,UAAU,IAAI,IAC3F,UACH;AAAA,MAEJ;AACA,eAAS,GAAG,WAAW,IAAI,GAAG,OAAO,IAAI,IAAI,KAAK,EAAE;AAAA,IACtD;AACA,WACE,4CAAC,oBAAK,MAAM,QAAS,GAAG,YACrB,UACH;AAAA,EAEJ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":["import_Link","import_Admonition","import_HeadingAnchor","import_WikiLink"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/MDXComponents.tsx"],"sourcesContent":["import { ReactNode, use } from 'react';\nimport { Admonition } from './Admonition';\nimport { FS_PREFIX, LinkSpaceContext,
|
|
1
|
+
{"version":3,"sources":["../../src/components/MDXComponents.tsx"],"sourcesContent":["import { ReactNode, use } from 'react';\nimport { Admonition } from './Admonition';\nimport { FS_PREFIX, LinkSpaceContext, resolveLinkTarget } from '../linkSpace';\nimport { splitHash } from '../urlUtils';\nimport { HeadingAnchor } from './HeadingAnchor';\nimport { Link } from './Link';\nimport { WikiLink } from './WikiLink';\n\n// The link primitives moved to ./Link so WikiLink can reuse Link without a\n// MDXComponents ↔ WikiLink import cycle (check:circular). Re-exported here so the\n// public `Link` / `InternalLink` entry points are unchanged.\nexport { InternalLink, Link } from './Link';\nexport { Admonition } from './Admonition';\nexport type { AdmonitionType } from './Admonition';\nexport { HeadingAnchor } from './HeadingAnchor';\nexport { WikiLink } from './WikiLink';\n\n/** Default MDX component overrides passed to {@link MDXProvider} by `boot`. These\n * are the platform's *phantom defaults* (MARKDOWN_SYNTAX_SPEC §11.2): they are\n * always present in the provider — even for a plain-markdown repo that never\n * calls `boot({ mdxComponents })` — so the platform-emitted `Admonition` (§12)\n * and `WikiLink` (§13) components resolve without the MDX missing-reference guard\n * firing, and Markdown links route in-app via {@link Link}. An app overrides any\n * of them by name via `boot({ mdxComponents })`, which *merges* over these\n * defaults (§11.3) — overriding `WikiLink` alone still keeps `a` and `Admonition`. */\nexport const DEFAULT_MDX_COMPONENTS = {\n a({\n href,\n children,\n ...properties\n }: React.DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>) {\n // R3-273 link spaces, same shared resolver as WikiLink: an `$fs:` href is\n // translated to its mount-absolute path; an ABSOLUTE href is corpus-rooted\n // when an enclosing LinkSpaceContext declares a corpusRoot (a non-corpus app\n // declares none and is untouched). Relative and external hrefs pass through —\n // <Link> already routes same-app hrefs and renders the rest as plain anchors.\n const { corpusRoot } = use(LinkSpaceContext);\n let mapped = href;\n if (href && (href.startsWith(FS_PREFIX) || (corpusRoot !== null && href.startsWith('/')))) {\n const [pathPart, frag] = splitHash(href);\n const resolution = resolveLinkTarget(pathPart, { corpusRoot });\n if (resolution.state !== 'resolved') {\n // Malformed `$fs:` (incl. scheme smuggling) — broken text, never an anchor.\n return (\n <span className=\"ir-link-broken\" data-state=\"broken\" title={`Invalid ${FS_PREFIX} link: ${href}`}>\n {children}\n </span>\n );\n }\n mapped = `${resolution.path}${frag ? `#${frag}` : ''}`;\n }\n return (\n <Link href={mapped} {...properties}>\n {children}\n </Link>\n );\n },\n Admonition,\n HeadingAnchor,\n WikiLink,\n} as Record<string, (props: any) => ReactNode>;\n"],"mappings":";AA4CU;AA5CV,SAAoB,WAAW;AAC/B,SAAS,kBAAkB;AAC3B,SAAS,WAAW,kBAAkB,yBAAyB;AAC/D,SAAS,iBAAiB;AAC1B,SAAS,qBAAqB;AAC9B,SAAS,YAAY;AACrB,SAAS,gBAAgB;AAKzB,SAAS,cAAc,QAAAA,aAAY;AACnC,SAAS,cAAAC,mBAAkB;AAE3B,SAAS,iBAAAC,sBAAqB;AAC9B,SAAS,YAAAC,iBAAgB;AAUlB,MAAM,yBAAyB;AAAA,EACpC,EAAE;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GAA8F;AAM5F,UAAM,EAAE,WAAW,IAAI,IAAI,gBAAgB;AAC3C,QAAI,SAAS;AACb,QAAI,SAAS,KAAK,WAAW,SAAS,KAAM,eAAe,QAAQ,KAAK,WAAW,GAAG,IAAK;AACzF,YAAM,CAAC,UAAU,IAAI,IAAI,UAAU,IAAI;AACvC,YAAM,aAAa,kBAAkB,UAAU,EAAE,WAAW,CAAC;AAC7D,UAAI,WAAW,UAAU,YAAY;AAEnC,eACE,oBAAC,UAAK,WAAU,kBAAiB,cAAW,UAAS,OAAO,WAAW,SAAS,UAAU,IAAI,IAC3F,UACH;AAAA,MAEJ;AACA,eAAS,GAAG,WAAW,IAAI,GAAG,OAAO,IAAI,IAAI,KAAK,EAAE;AAAA,IACtD;AACA,WACE,oBAAC,QAAK,MAAM,QAAS,GAAG,YACrB,UACH;AAAA,EAEJ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":["Link","Admonition","HeadingAnchor","WikiLink"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/ScrollAfterNavigation.tsx"],"sourcesContent":["import { use, useEffect } from 'react';\n\nimport { TinkerableContext } from '../TinkerableContext';\nimport { scrollToId } from '../scrollToId';\n\n/**\n * Deep-linking Capability C (MARKDOWN_SYNTAX_SPEC §13.5): after an in-app navigation\n * whose URL carries a `#fragment`, scroll the target section into view.\n *\n * In-app navigation swaps the rendered file **asynchronously** — the destination\n * file's tree mounts *after* the route change — so the element the fragment\n * addresses does not exist at click time. This effect records the pending fragment\n * and retries until the target appears: an immediate attempt, a `MutationObserver`\n * over late-mounting subtrees, and a few timed retries (the `[120, 300, 600]ms`\n * cadence `grove/src/components/Toc.tsx` proves for late-mounting prose). If the\n * target never appears within the window it degrades to top-of-page — a missing\n * fragment is never a hard failure.\n *\n * It re-runs when the destination page **or** the fragment changes, so a fresh click\n * on the same target re-scrolls. Mounted once inside the navigation provider (see\n * `boot`'s `TinkerableApp`) so it is uniform for **every** MDX app — the SDK router\n * owns cross-page anchor navigation, not any one consumer (Grove).\n */\nexport const useScrollAfterNavigation = (): void => {\n const { navigationState } = use(TinkerableContext);\n const frag = navigationState.hash;\n // Re-run when the destination page OR the fragment changes.\n const navKey = `${navigationState.sandboxPath}
|
|
1
|
+
{"version":3,"sources":["../../src/components/ScrollAfterNavigation.tsx"],"sourcesContent":["import { use, useEffect } from 'react';\n\nimport { TinkerableContext } from '../TinkerableContext';\nimport { scrollToId } from '../scrollToId';\n\n/**\n * Deep-linking Capability C (MARKDOWN_SYNTAX_SPEC §13.5): after an in-app navigation\n * whose URL carries a `#fragment`, scroll the target section into view.\n *\n * In-app navigation swaps the rendered file **asynchronously** — the destination\n * file's tree mounts *after* the route change — so the element the fragment\n * addresses does not exist at click time. This effect records the pending fragment\n * and retries until the target appears: an immediate attempt, a `MutationObserver`\n * over late-mounting subtrees, and a few timed retries (the `[120, 300, 600]ms`\n * cadence `grove/src/components/Toc.tsx` proves for late-mounting prose). If the\n * target never appears within the window it degrades to top-of-page — a missing\n * fragment is never a hard failure.\n *\n * It re-runs when the destination page **or** the fragment changes, so a fresh click\n * on the same target re-scrolls. Mounted once inside the navigation provider (see\n * `boot`'s `TinkerableApp`) so it is uniform for **every** MDX app — the SDK router\n * owns cross-page anchor navigation, not any one consumer (Grove).\n */\nexport const useScrollAfterNavigation = (): void => {\n const { navigationState } = use(TinkerableContext);\n const frag = navigationState.hash;\n // Re-run when the destination page OR the fragment changes. The two are joined\n // with a NUL — a byte neither a sandbox path nor a fragment can contain — so no\n // pair of (path, fragment) values can collide into the same key. It is written as\n // the \\u0000 ESCAPE, never as a raw byte: a literal NUL in the source makes the\n // file binary to grep, diff and review tooling.\n const navKey = `${navigationState.sandboxPath}\\u0000${frag}`;\n\n useEffect(() => {\n if (!frag || typeof document === 'undefined') return;\n // Fast path: the target is already in the DOM (same page, or the tree mounted\n // synchronously) — scroll now, no observer/timer churn.\n if (scrollToId(frag)) return;\n\n let done = false;\n const finish = () => {\n done = true;\n observer.disconnect();\n timers.forEach(clearTimeout);\n clearTimeout(finalTimer);\n };\n const tryScroll = () => {\n if (!done && scrollToId(frag)) finish();\n };\n\n const observer = new MutationObserver(tryScroll);\n const timers = [120, 300, 600].map((ms) => setTimeout(tryScroll, ms));\n // Final fallback once the retry window closes: if the fragment never resolved,\n // scroll to the top rather than strand the reader at the previous page's offset.\n const finalTimer = setTimeout(() => {\n if (!done) {\n finish();\n window.scrollTo?.(0, 0);\n }\n }, 900);\n\n observer.observe(document.body, { childList: true, subtree: true });\n return finish;\n }, [navKey, frag]);\n};\n\n/** Null-rendering mount point for {@link useScrollAfterNavigation} inside the\n * navigation provider. */\nexport const ScrollAfterNavigation = (): null => {\n useScrollAfterNavigation();\n return null;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA+B;AAE/B,+BAAkC;AAClC,wBAA2B;AAoBpB,MAAM,2BAA2B,MAAY;AAClD,QAAM,EAAE,gBAAgB,QAAI,kBAAI,0CAAiB;AACjD,QAAM,OAAO,gBAAgB;AAM7B,QAAM,SAAS,GAAG,gBAAgB,WAAW,KAAS,IAAI;AAE1D,8BAAU,MAAM;AACd,QAAI,CAAC,QAAQ,OAAO,aAAa,YAAa;AAG9C,YAAI,8BAAW,IAAI,EAAG;AAEtB,QAAI,OAAO;AACX,UAAM,SAAS,MAAM;AACnB,aAAO;AACP,eAAS,WAAW;AACpB,aAAO,QAAQ,YAAY;AAC3B,mBAAa,UAAU;AAAA,IACzB;AACA,UAAM,YAAY,MAAM;AACtB,UAAI,CAAC,YAAQ,8BAAW,IAAI,EAAG,QAAO;AAAA,IACxC;AAEA,UAAM,WAAW,IAAI,iBAAiB,SAAS;AAC/C,UAAM,SAAS,CAAC,KAAK,KAAK,GAAG,EAAE,IAAI,CAAC,OAAO,WAAW,WAAW,EAAE,CAAC;AAGpE,UAAM,aAAa,WAAW,MAAM;AAClC,UAAI,CAAC,MAAM;AACT,eAAO;AACP,eAAO,WAAW,GAAG,CAAC;AAAA,MACxB;AAAA,IACF,GAAG,GAAG;AAEN,aAAS,QAAQ,SAAS,MAAM,EAAE,WAAW,MAAM,SAAS,KAAK,CAAC;AAClE,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,IAAI,CAAC;AACnB;AAIO,MAAM,wBAAwB,MAAY;AAC/C,2BAAyB;AACzB,SAAO;AACT;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/ScrollAfterNavigation.tsx"],"sourcesContent":["import { use, useEffect } from 'react';\n\nimport { TinkerableContext } from '../TinkerableContext';\nimport { scrollToId } from '../scrollToId';\n\n/**\n * Deep-linking Capability C (MARKDOWN_SYNTAX_SPEC §13.5): after an in-app navigation\n * whose URL carries a `#fragment`, scroll the target section into view.\n *\n * In-app navigation swaps the rendered file **asynchronously** — the destination\n * file's tree mounts *after* the route change — so the element the fragment\n * addresses does not exist at click time. This effect records the pending fragment\n * and retries until the target appears: an immediate attempt, a `MutationObserver`\n * over late-mounting subtrees, and a few timed retries (the `[120, 300, 600]ms`\n * cadence `grove/src/components/Toc.tsx` proves for late-mounting prose). If the\n * target never appears within the window it degrades to top-of-page — a missing\n * fragment is never a hard failure.\n *\n * It re-runs when the destination page **or** the fragment changes, so a fresh click\n * on the same target re-scrolls. Mounted once inside the navigation provider (see\n * `boot`'s `TinkerableApp`) so it is uniform for **every** MDX app — the SDK router\n * owns cross-page anchor navigation, not any one consumer (Grove).\n */\nexport const useScrollAfterNavigation = (): void => {\n const { navigationState } = use(TinkerableContext);\n const frag = navigationState.hash;\n // Re-run when the destination page OR the fragment changes.\n const navKey = `${navigationState.sandboxPath}
|
|
1
|
+
{"version":3,"sources":["../../src/components/ScrollAfterNavigation.tsx"],"sourcesContent":["import { use, useEffect } from 'react';\n\nimport { TinkerableContext } from '../TinkerableContext';\nimport { scrollToId } from '../scrollToId';\n\n/**\n * Deep-linking Capability C (MARKDOWN_SYNTAX_SPEC §13.5): after an in-app navigation\n * whose URL carries a `#fragment`, scroll the target section into view.\n *\n * In-app navigation swaps the rendered file **asynchronously** — the destination\n * file's tree mounts *after* the route change — so the element the fragment\n * addresses does not exist at click time. This effect records the pending fragment\n * and retries until the target appears: an immediate attempt, a `MutationObserver`\n * over late-mounting subtrees, and a few timed retries (the `[120, 300, 600]ms`\n * cadence `grove/src/components/Toc.tsx` proves for late-mounting prose). If the\n * target never appears within the window it degrades to top-of-page — a missing\n * fragment is never a hard failure.\n *\n * It re-runs when the destination page **or** the fragment changes, so a fresh click\n * on the same target re-scrolls. Mounted once inside the navigation provider (see\n * `boot`'s `TinkerableApp`) so it is uniform for **every** MDX app — the SDK router\n * owns cross-page anchor navigation, not any one consumer (Grove).\n */\nexport const useScrollAfterNavigation = (): void => {\n const { navigationState } = use(TinkerableContext);\n const frag = navigationState.hash;\n // Re-run when the destination page OR the fragment changes. The two are joined\n // with a NUL — a byte neither a sandbox path nor a fragment can contain — so no\n // pair of (path, fragment) values can collide into the same key. It is written as\n // the \\u0000 ESCAPE, never as a raw byte: a literal NUL in the source makes the\n // file binary to grep, diff and review tooling.\n const navKey = `${navigationState.sandboxPath}\\u0000${frag}`;\n\n useEffect(() => {\n if (!frag || typeof document === 'undefined') return;\n // Fast path: the target is already in the DOM (same page, or the tree mounted\n // synchronously) — scroll now, no observer/timer churn.\n if (scrollToId(frag)) return;\n\n let done = false;\n const finish = () => {\n done = true;\n observer.disconnect();\n timers.forEach(clearTimeout);\n clearTimeout(finalTimer);\n };\n const tryScroll = () => {\n if (!done && scrollToId(frag)) finish();\n };\n\n const observer = new MutationObserver(tryScroll);\n const timers = [120, 300, 600].map((ms) => setTimeout(tryScroll, ms));\n // Final fallback once the retry window closes: if the fragment never resolved,\n // scroll to the top rather than strand the reader at the previous page's offset.\n const finalTimer = setTimeout(() => {\n if (!done) {\n finish();\n window.scrollTo?.(0, 0);\n }\n }, 900);\n\n observer.observe(document.body, { childList: true, subtree: true });\n return finish;\n }, [navKey, frag]);\n};\n\n/** Null-rendering mount point for {@link useScrollAfterNavigation} inside the\n * navigation provider. */\nexport const ScrollAfterNavigation = (): null => {\n useScrollAfterNavigation();\n return null;\n};\n"],"mappings":";AAAA,SAAS,KAAK,iBAAiB;AAE/B,SAAS,yBAAyB;AAClC,SAAS,kBAAkB;AAoBpB,MAAM,2BAA2B,MAAY;AAClD,QAAM,EAAE,gBAAgB,IAAI,IAAI,iBAAiB;AACjD,QAAM,OAAO,gBAAgB;AAM7B,QAAM,SAAS,GAAG,gBAAgB,WAAW,KAAS,IAAI;AAE1D,YAAU,MAAM;AACd,QAAI,CAAC,QAAQ,OAAO,aAAa,YAAa;AAG9C,QAAI,WAAW,IAAI,EAAG;AAEtB,QAAI,OAAO;AACX,UAAM,SAAS,MAAM;AACnB,aAAO;AACP,eAAS,WAAW;AACpB,aAAO,QAAQ,YAAY;AAC3B,mBAAa,UAAU;AAAA,IACzB;AACA,UAAM,YAAY,MAAM;AACtB,UAAI,CAAC,QAAQ,WAAW,IAAI,EAAG,QAAO;AAAA,IACxC;AAEA,UAAM,WAAW,IAAI,iBAAiB,SAAS;AAC/C,UAAM,SAAS,CAAC,KAAK,KAAK,GAAG,EAAE,IAAI,CAAC,OAAO,WAAW,WAAW,EAAE,CAAC;AAGpE,UAAM,aAAa,WAAW,MAAM;AAClC,UAAI,CAAC,MAAM;AACT,eAAO;AACP,eAAO,WAAW,GAAG,CAAC;AAAA,MACxB;AAAA,IACF,GAAG,GAAG;AAEN,aAAS,QAAQ,SAAS,MAAM,EAAE,WAAW,MAAM,SAAS,KAAK,CAAC;AAClE,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,IAAI,CAAC;AACnB;AAIO,MAAM,wBAAwB,MAAY;AAC/C,2BAAyB;AACzB,SAAO;AACT;","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -13,7 +13,7 @@ export { ObjectUrlState, useAllMetadata, useFileMetadata, useMetadataQuery, useO
|
|
|
13
13
|
export { MetadataSource, MetadataSourceMode, MetadataSourceProps, useMetadataStore } from './metadataSource.cjs';
|
|
14
14
|
export { getInjectedMetadataEmitter, getInjectedMetadataSnapshot } from './injectedBundler.cjs';
|
|
15
15
|
export { AuthState, AuthStatus, SandboxUser, getAuthState, onAuthChange, useAuth } from './auth.cjs';
|
|
16
|
-
export { HostTheme, getHostTheme, onHostThemeChange, setHostTheme, useHostTheme } from './theme.cjs';
|
|
16
|
+
export { HostTheme, HostThemeSelection, SetHostThemeSelectionParams, ThemeBundleLocation, ThemeCatalog, ThemeCatalogEntry, addThemeSource, getHostTheme, getHostThemeSelection, getThemeCatalog, onHostThemeChange, onHostThemeSelectionChange, onThemeCatalogChange, removeThemeSource, setHostTheme, setHostThemeSelection, useHostTheme, useHostThemeSelection, useThemeCatalog } from './theme.cjs';
|
|
17
17
|
export { EditorContext, getEditorContext, onEditorContextChange, useEditorContext } from './editorContext.cjs';
|
|
18
18
|
export { EditTarget, EditorOpenError, EditorOpenOptions, EditorSelection, EditorSessionError, EditorWriteError, RequestEditError, closeFile, createFile, createFolder, deleteEntry, openInEditor, renameEntry, requestEdit, setActiveFile, uploadFile } from './editor.cjs';
|
|
19
19
|
export { FormFactor, FormFactorClass, Orientation, getFormFactor, onFormFactorChange, useFormFactor } from './formFactor.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export { ObjectUrlState, useAllMetadata, useFileMetadata, useMetadataQuery, useO
|
|
|
13
13
|
export { MetadataSource, MetadataSourceMode, MetadataSourceProps, useMetadataStore } from './metadataSource.js';
|
|
14
14
|
export { getInjectedMetadataEmitter, getInjectedMetadataSnapshot } from './injectedBundler.js';
|
|
15
15
|
export { AuthState, AuthStatus, SandboxUser, getAuthState, onAuthChange, useAuth } from './auth.js';
|
|
16
|
-
export { HostTheme, getHostTheme, onHostThemeChange, setHostTheme, useHostTheme } from './theme.js';
|
|
16
|
+
export { HostTheme, HostThemeSelection, SetHostThemeSelectionParams, ThemeBundleLocation, ThemeCatalog, ThemeCatalogEntry, addThemeSource, getHostTheme, getHostThemeSelection, getThemeCatalog, onHostThemeChange, onHostThemeSelectionChange, onThemeCatalogChange, removeThemeSource, setHostTheme, setHostThemeSelection, useHostTheme, useHostThemeSelection, useThemeCatalog } from './theme.js';
|
|
17
17
|
export { EditorContext, getEditorContext, onEditorContextChange, useEditorContext } from './editorContext.js';
|
|
18
18
|
export { EditTarget, EditorOpenError, EditorOpenOptions, EditorSelection, EditorSessionError, EditorWriteError, RequestEditError, closeFile, createFile, createFolder, deleteEntry, openInEditor, renameEntry, requestEdit, setActiveFile, uploadFile } from './editor.js';
|
|
19
19
|
export { FormFactor, FormFactorClass, Orientation, getFormFactor, onFormFactorChange, useFormFactor } from './formFactor.js';
|
package/dist/markers.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/markers.ts"],"sourcesContent":["// Runtime emission of the boot `ir.*` markers (LOAD_PROFILING_SPEC §3/§3.2, R3-46).\n//\n// The host already MERGED the receive end: it validates a forwarded\n// `{ type:'ir-marker', name, at, attrs? }` against the LP-5 allowlist\n// (`irMarkers.ts`) and brackets request→interactive, treating an accepted\n// `ir.interactive` as the root-render-commit signal (site-main\n// `routePerfMessage`/`perfTimeline`). This module is the SANDBOX-side emitter for\n// the boot marks the SDK owns — `ir.fmp` (first meaningful paint) and\n// `ir.interactive` (root render commit) — forwarded over the same transport as\n// `reportReady()` (`ready.ts`). The per-marker timestamp is the sandbox-relative\n// `performance.now()` at emission (§3.2).\n//\n// Mirrors `ready.ts`'s dependency seam so the emission is unit-testable without a\n// host transport, and is idempotent per name so React StrictMode's double-invoke\n// (or any re-commit) can't mint a boot mark twice.\nimport { sendMessage as defaultSend } from './sandboxUtils';\nimport { isIrMarkerName, type IrMarkerName } from './irMarkers';\n\ninterface MarkerDeps {\n send: (type: string, data?: Record<string, unknown>) => void;\n now: () => number;\n}\n\nconst realNow = (): number =>\n typeof performance !== 'undefined' && typeof performance.now === 'function' ? performance.now() : Date.now();\n\nconst defaultDeps: MarkerDeps = { send: defaultSend, now: realNow };\n\nlet deps: MarkerDeps = defaultDeps;\nconst emitted = new Set<string>();\n\n/**\n * Forward one `ir.*` marker to the host (`ir-marker`). The host re-validates against\n * the allowlist, so a bad name/attr is dropped there; we only emit names the SDK\n * itself owns. A transport that isn't ready yet is swallowed — a missing boot mark\n * must never break the app's boot.\n */\nexport function emitMarker(name: IrMarkerName, attrs?: Record<string, unknown>): void {\n if (!isIrMarkerName(name)) return;\n try {\n deps.send('ir-marker', { name, at: deps.now(), ...(attrs !== undefined ? { attrs } : {}) });\n } catch {\n /* transport not ready — boot continues; the host simply lacks this mark */\n }\n}\n\n/** Emit a boot one-shot at most once per name (idempotent across StrictMode/re-commit). */\nexport function emitMarkerOnce(name: IrMarkerName, attrs?: Record<string, unknown>): void {\n if (emitted.has(name)) return;\n emitted.add(name);\n emitMarker(name, attrs);\n}\n\n/** Test seam: override the transport/clock. */\nexport function __setMarkerDeps(d: Partial<MarkerDeps>): void {\n deps = { ...defaultDeps, ...d };\n}\n\n/** Test seam: reset module state (the once-guard + deps) between cases. */\nexport function __resetMarkers(): void {\n deps = defaultDeps;\n emitted.clear();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
1
|
+
{"version":3,"sources":["../src/markers.ts"],"sourcesContent":["// Runtime emission of the boot `ir.*` markers (LOAD_PROFILING_SPEC §3/§3.2, R3-46).\n//\n// The host already MERGED the receive end: it validates a forwarded\n// `{ type:'ir-marker', name, at, attrs? }` against the LP-5 allowlist\n// (`irMarkers.ts`) and brackets request→interactive, treating an accepted\n// `ir.interactive` as the root-render-commit signal (site-main\n// `routePerfMessage`/`perfTimeline`). This module is the SANDBOX-side emitter for\n// the boot marks the SDK owns — `ir.fmp` (first meaningful paint) and\n// `ir.interactive` (root render commit) — forwarded over the same transport as\n// `reportReady()` (`ready.ts`). The per-marker timestamp is the sandbox-relative\n// `performance.now()` at emission (§3.2).\n//\n// Mirrors `ready.ts`'s dependency seam so the emission is unit-testable without a\n// host transport, and is idempotent per name so React StrictMode's double-invoke\n// (or any re-commit) can't mint a boot mark twice. The seam and the `realNow`\n// fallback are a deliberate second copy, not an oversight: sharing them would mean\n// a new module-level export, and this package's surface is additive-only, so every\n// export is a public subpath API a pinned app can import forever.\nimport { sendMessage as defaultSend } from './sandboxUtils';\nimport { isIrMarkerName, type IrMarkerName } from './irMarkers';\n\ninterface MarkerDeps {\n send: (type: string, data?: Record<string, unknown>) => void;\n now: () => number;\n}\n\nconst realNow = (): number =>\n typeof performance !== 'undefined' && typeof performance.now === 'function' ? performance.now() : Date.now();\n\nconst defaultDeps: MarkerDeps = { send: defaultSend, now: realNow };\n\nlet deps: MarkerDeps = defaultDeps;\nconst emitted = new Set<string>();\n\n/**\n * Forward one `ir.*` marker to the host (`ir-marker`). The host re-validates against\n * the allowlist, so a bad name/attr is dropped there; we only emit names the SDK\n * itself owns. A transport that isn't ready yet is swallowed — a missing boot mark\n * must never break the app's boot.\n */\nexport function emitMarker(name: IrMarkerName, attrs?: Record<string, unknown>): void {\n if (!isIrMarkerName(name)) return;\n try {\n deps.send('ir-marker', { name, at: deps.now(), ...(attrs !== undefined ? { attrs } : {}) });\n } catch {\n /* transport not ready — boot continues; the host simply lacks this mark */\n }\n}\n\n/** Emit a boot one-shot at most once per name (idempotent across StrictMode/re-commit). */\nexport function emitMarkerOnce(name: IrMarkerName, attrs?: Record<string, unknown>): void {\n if (emitted.has(name)) return;\n emitted.add(name);\n emitMarker(name, attrs);\n}\n\n/** Test seam: override the transport/clock. */\nexport function __setMarkerDeps(d: Partial<MarkerDeps>): void {\n deps = { ...defaultDeps, ...d };\n}\n\n/** Test seam: reset module state (the once-guard + deps) between cases. */\nexport function __resetMarkers(): void {\n deps = defaultDeps;\n emitted.clear();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBA,0BAA2C;AAC3C,uBAAkD;AAOlD,MAAM,UAAU,MACd,OAAO,gBAAgB,eAAe,OAAO,YAAY,QAAQ,aAAa,YAAY,IAAI,IAAI,KAAK,IAAI;AAE7G,MAAM,cAA0B,EAAE,MAAM,oBAAAA,aAAa,KAAK,QAAQ;AAElE,IAAI,OAAmB;AACvB,MAAM,UAAU,oBAAI,IAAY;AAQzB,SAAS,WAAW,MAAoB,OAAuC;AACpF,MAAI,KAAC,iCAAe,IAAI,EAAG;AAC3B,MAAI;AACF,SAAK,KAAK,aAAa,EAAE,MAAM,IAAI,KAAK,IAAI,GAAG,GAAI,UAAU,SAAY,EAAE,MAAM,IAAI,CAAC,EAAG,CAAC;AAAA,EAC5F,QAAQ;AAAA,EAER;AACF;AAGO,SAAS,eAAe,MAAoB,OAAuC;AACxF,MAAI,QAAQ,IAAI,IAAI,EAAG;AACvB,UAAQ,IAAI,IAAI;AAChB,aAAW,MAAM,KAAK;AACxB;AAGO,SAAS,gBAAgB,GAA8B;AAC5D,SAAO,EAAE,GAAG,aAAa,GAAG,EAAE;AAChC;AAGO,SAAS,iBAAuB;AACrC,SAAO;AACP,UAAQ,MAAM;AAChB;","names":["defaultSend"]}
|
package/dist/markers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/markers.ts"],"sourcesContent":["// Runtime emission of the boot `ir.*` markers (LOAD_PROFILING_SPEC §3/§3.2, R3-46).\n//\n// The host already MERGED the receive end: it validates a forwarded\n// `{ type:'ir-marker', name, at, attrs? }` against the LP-5 allowlist\n// (`irMarkers.ts`) and brackets request→interactive, treating an accepted\n// `ir.interactive` as the root-render-commit signal (site-main\n// `routePerfMessage`/`perfTimeline`). This module is the SANDBOX-side emitter for\n// the boot marks the SDK owns — `ir.fmp` (first meaningful paint) and\n// `ir.interactive` (root render commit) — forwarded over the same transport as\n// `reportReady()` (`ready.ts`). The per-marker timestamp is the sandbox-relative\n// `performance.now()` at emission (§3.2).\n//\n// Mirrors `ready.ts`'s dependency seam so the emission is unit-testable without a\n// host transport, and is idempotent per name so React StrictMode's double-invoke\n// (or any re-commit) can't mint a boot mark twice.\nimport { sendMessage as defaultSend } from './sandboxUtils';\nimport { isIrMarkerName, type IrMarkerName } from './irMarkers';\n\ninterface MarkerDeps {\n send: (type: string, data?: Record<string, unknown>) => void;\n now: () => number;\n}\n\nconst realNow = (): number =>\n typeof performance !== 'undefined' && typeof performance.now === 'function' ? performance.now() : Date.now();\n\nconst defaultDeps: MarkerDeps = { send: defaultSend, now: realNow };\n\nlet deps: MarkerDeps = defaultDeps;\nconst emitted = new Set<string>();\n\n/**\n * Forward one `ir.*` marker to the host (`ir-marker`). The host re-validates against\n * the allowlist, so a bad name/attr is dropped there; we only emit names the SDK\n * itself owns. A transport that isn't ready yet is swallowed — a missing boot mark\n * must never break the app's boot.\n */\nexport function emitMarker(name: IrMarkerName, attrs?: Record<string, unknown>): void {\n if (!isIrMarkerName(name)) return;\n try {\n deps.send('ir-marker', { name, at: deps.now(), ...(attrs !== undefined ? { attrs } : {}) });\n } catch {\n /* transport not ready — boot continues; the host simply lacks this mark */\n }\n}\n\n/** Emit a boot one-shot at most once per name (idempotent across StrictMode/re-commit). */\nexport function emitMarkerOnce(name: IrMarkerName, attrs?: Record<string, unknown>): void {\n if (emitted.has(name)) return;\n emitted.add(name);\n emitMarker(name, attrs);\n}\n\n/** Test seam: override the transport/clock. */\nexport function __setMarkerDeps(d: Partial<MarkerDeps>): void {\n deps = { ...defaultDeps, ...d };\n}\n\n/** Test seam: reset module state (the once-guard + deps) between cases. */\nexport function __resetMarkers(): void {\n deps = defaultDeps;\n emitted.clear();\n}\n"],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../src/markers.ts"],"sourcesContent":["// Runtime emission of the boot `ir.*` markers (LOAD_PROFILING_SPEC §3/§3.2, R3-46).\n//\n// The host already MERGED the receive end: it validates a forwarded\n// `{ type:'ir-marker', name, at, attrs? }` against the LP-5 allowlist\n// (`irMarkers.ts`) and brackets request→interactive, treating an accepted\n// `ir.interactive` as the root-render-commit signal (site-main\n// `routePerfMessage`/`perfTimeline`). This module is the SANDBOX-side emitter for\n// the boot marks the SDK owns — `ir.fmp` (first meaningful paint) and\n// `ir.interactive` (root render commit) — forwarded over the same transport as\n// `reportReady()` (`ready.ts`). The per-marker timestamp is the sandbox-relative\n// `performance.now()` at emission (§3.2).\n//\n// Mirrors `ready.ts`'s dependency seam so the emission is unit-testable without a\n// host transport, and is idempotent per name so React StrictMode's double-invoke\n// (or any re-commit) can't mint a boot mark twice. The seam and the `realNow`\n// fallback are a deliberate second copy, not an oversight: sharing them would mean\n// a new module-level export, and this package's surface is additive-only, so every\n// export is a public subpath API a pinned app can import forever.\nimport { sendMessage as defaultSend } from './sandboxUtils';\nimport { isIrMarkerName, type IrMarkerName } from './irMarkers';\n\ninterface MarkerDeps {\n send: (type: string, data?: Record<string, unknown>) => void;\n now: () => number;\n}\n\nconst realNow = (): number =>\n typeof performance !== 'undefined' && typeof performance.now === 'function' ? performance.now() : Date.now();\n\nconst defaultDeps: MarkerDeps = { send: defaultSend, now: realNow };\n\nlet deps: MarkerDeps = defaultDeps;\nconst emitted = new Set<string>();\n\n/**\n * Forward one `ir.*` marker to the host (`ir-marker`). The host re-validates against\n * the allowlist, so a bad name/attr is dropped there; we only emit names the SDK\n * itself owns. A transport that isn't ready yet is swallowed — a missing boot mark\n * must never break the app's boot.\n */\nexport function emitMarker(name: IrMarkerName, attrs?: Record<string, unknown>): void {\n if (!isIrMarkerName(name)) return;\n try {\n deps.send('ir-marker', { name, at: deps.now(), ...(attrs !== undefined ? { attrs } : {}) });\n } catch {\n /* transport not ready — boot continues; the host simply lacks this mark */\n }\n}\n\n/** Emit a boot one-shot at most once per name (idempotent across StrictMode/re-commit). */\nexport function emitMarkerOnce(name: IrMarkerName, attrs?: Record<string, unknown>): void {\n if (emitted.has(name)) return;\n emitted.add(name);\n emitMarker(name, attrs);\n}\n\n/** Test seam: override the transport/clock. */\nexport function __setMarkerDeps(d: Partial<MarkerDeps>): void {\n deps = { ...defaultDeps, ...d };\n}\n\n/** Test seam: reset module state (the once-guard + deps) between cases. */\nexport function __resetMarkers(): void {\n deps = defaultDeps;\n emitted.clear();\n}\n"],"mappings":";AAkBA,SAAS,eAAe,mBAAmB;AAC3C,SAAS,sBAAyC;AAOlD,MAAM,UAAU,MACd,OAAO,gBAAgB,eAAe,OAAO,YAAY,QAAQ,aAAa,YAAY,IAAI,IAAI,KAAK,IAAI;AAE7G,MAAM,cAA0B,EAAE,MAAM,aAAa,KAAK,QAAQ;AAElE,IAAI,OAAmB;AACvB,MAAM,UAAU,oBAAI,IAAY;AAQzB,SAAS,WAAW,MAAoB,OAAuC;AACpF,MAAI,CAAC,eAAe,IAAI,EAAG;AAC3B,MAAI;AACF,SAAK,KAAK,aAAa,EAAE,MAAM,IAAI,KAAK,IAAI,GAAG,GAAI,UAAU,SAAY,EAAE,MAAM,IAAI,CAAC,EAAG,CAAC;AAAA,EAC5F,QAAQ;AAAA,EAER;AACF;AAGO,SAAS,eAAe,MAAoB,OAAuC;AACxF,MAAI,QAAQ,IAAI,IAAI,EAAG;AACvB,UAAQ,IAAI,IAAI;AAChB,aAAW,MAAM,KAAK;AACxB;AAGO,SAAS,gBAAgB,GAA8B;AAC5D,SAAO,EAAE,GAAG,aAAa,GAAG,EAAE;AAChC;AAGO,SAAS,iBAAuB;AACrC,SAAO;AACP,UAAQ,MAAM;AAChB;","names":[]}
|
package/dist/moduleCache.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/moduleCache.tsx"],"sourcesContent":["// based on: https://www.bbss.dev/posts/react-learn-suspense/#fetchcache-provider\n\nimport { createContext, ReactNode
|
|
1
|
+
{"version":3,"sources":["../src/moduleCache.tsx"],"sourcesContent":["// based on: https://www.bbss.dev/posts/react-learn-suspense/#fetchcache-provider\n\nimport { createContext, ReactNode } from 'react';\nimport { EvaluationContext } from './sandboxTypes';\nimport { addListener } from './sandboxUtils';\nimport { COMPILE } from './generated/protocol';\n\nexport class ModuleCache {\n nameResolutionPromises: Record<string, Promise<string>> = {};\n evaluationContextPromises: Record<string, Promise<EvaluationContext>> = {};\n\n constructor() {\n // A compile-time cache reset, deliberately NOT performed. Resetting here\n // replaced every <Include>'s module-evaluation-context promise with a new\n // promise for the same value on EVERY compilation, including compilations that\n // do not affect that module, so the component lost its state for nothing. The\n // listener stays registered (and the reset stays here, disabled) because the\n // fix is to scope the reset to the modules a compile actually changed, not to\n // drop the seam.\n addListener(COMPILE, () => {\n // this.nameResolutionPromises = {};\n // this.evaluationContextPromises = {};\n });\n }\n\n private getCacheKey(mod: EvaluationContext, moduleName: string): string {\n return `${mod.evaluation.module.filepath}|${moduleName}`;\n }\n\n resolveModuleName(moduleName: string, baseModule?: EvaluationContext): Promise<string> {\n // note: uses current module as base module if none specified by caller\n // @ts-ignore\n const mod = baseModule ?? (module as EvaluationContext);\n const cacheKey = this.getCacheKey(mod, moduleName);\n if (!(cacheKey in this.nameResolutionPromises)) {\n this.nameResolutionPromises[cacheKey] = mod.resolve(moduleName);\n }\n return this.nameResolutionPromises[cacheKey];\n }\n\n getEvaluationContext(moduleName: string, baseModule?: EvaluationContext): Promise<EvaluationContext> {\n // note: uses current module as base module if none specified by caller\n // @ts-ignore\n const mod = baseModule ?? (module as EvaluationContext);\n const cacheKey = this.getCacheKey(mod, moduleName);\n if (!(cacheKey in this.evaluationContextPromises)) {\n this.evaluationContextPromises[cacheKey] = mod.getModuleEvaluationContext(moduleName);\n }\n return this.evaluationContextPromises[cacheKey];\n }\n}\n\nexport const ModuleCacheContext = createContext<null | ModuleCache>(null);\n\nexport const ModuleCacheContextProvider = ({\n children,\n moduleCache,\n}: {\n children: ReactNode;\n moduleCache: ModuleCache;\n}) => {\n return <ModuleCacheContext.Provider value={moduleCache}>{children}</ModuleCacheContext.Provider>;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA6DS;AA3DT,mBAAyC;AAEzC,0BAA4B;AAC5B,sBAAwB;AAEjB,MAAM,YAAY;AAAA,EAIvB,cAAc;AAHd,kCAA0D,CAAC;AAC3D,qCAAwE,CAAC;AAUvE,yCAAY,yBAAS,MAAM;AAAA,IAG3B,CAAC;AAAA,EACH;AAAA,EAEQ,YAAY,KAAwB,YAA4B;AACtE,WAAO,GAAG,IAAI,WAAW,OAAO,QAAQ,IAAI,UAAU;AAAA,EACxD;AAAA,EAEA,kBAAkB,YAAoB,YAAiD;AAGrF,UAAM,MAAM,cAAe;AAC3B,UAAM,WAAW,KAAK,YAAY,KAAK,UAAU;AACjD,QAAI,EAAE,YAAY,KAAK,yBAAyB;AAC9C,WAAK,uBAAuB,QAAQ,IAAI,IAAI,QAAQ,UAAU;AAAA,IAChE;AACA,WAAO,KAAK,uBAAuB,QAAQ;AAAA,EAC7C;AAAA,EAEA,qBAAqB,YAAoB,YAA4D;AAGnG,UAAM,MAAM,cAAe;AAC3B,UAAM,WAAW,KAAK,YAAY,KAAK,UAAU;AACjD,QAAI,EAAE,YAAY,KAAK,4BAA4B;AACjD,WAAK,0BAA0B,QAAQ,IAAI,IAAI,2BAA2B,UAAU;AAAA,IACtF;AACA,WAAO,KAAK,0BAA0B,QAAQ;AAAA,EAChD;AACF;AAEO,MAAM,yBAAqB,4BAAkC,IAAI;AAEjE,MAAM,6BAA6B,CAAC;AAAA,EACzC;AAAA,EACA;AACF,MAGM;AACJ,SAAO,4CAAC,mBAAmB,UAAnB,EAA4B,OAAO,aAAc,UAAS;AACpE;","names":[]}
|
package/dist/moduleCache.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/moduleCache.tsx"],"sourcesContent":["// based on: https://www.bbss.dev/posts/react-learn-suspense/#fetchcache-provider\n\nimport { createContext, ReactNode
|
|
1
|
+
{"version":3,"sources":["../src/moduleCache.tsx"],"sourcesContent":["// based on: https://www.bbss.dev/posts/react-learn-suspense/#fetchcache-provider\n\nimport { createContext, ReactNode } from 'react';\nimport { EvaluationContext } from './sandboxTypes';\nimport { addListener } from './sandboxUtils';\nimport { COMPILE } from './generated/protocol';\n\nexport class ModuleCache {\n nameResolutionPromises: Record<string, Promise<string>> = {};\n evaluationContextPromises: Record<string, Promise<EvaluationContext>> = {};\n\n constructor() {\n // A compile-time cache reset, deliberately NOT performed. Resetting here\n // replaced every <Include>'s module-evaluation-context promise with a new\n // promise for the same value on EVERY compilation, including compilations that\n // do not affect that module, so the component lost its state for nothing. The\n // listener stays registered (and the reset stays here, disabled) because the\n // fix is to scope the reset to the modules a compile actually changed, not to\n // drop the seam.\n addListener(COMPILE, () => {\n // this.nameResolutionPromises = {};\n // this.evaluationContextPromises = {};\n });\n }\n\n private getCacheKey(mod: EvaluationContext, moduleName: string): string {\n return `${mod.evaluation.module.filepath}|${moduleName}`;\n }\n\n resolveModuleName(moduleName: string, baseModule?: EvaluationContext): Promise<string> {\n // note: uses current module as base module if none specified by caller\n // @ts-ignore\n const mod = baseModule ?? (module as EvaluationContext);\n const cacheKey = this.getCacheKey(mod, moduleName);\n if (!(cacheKey in this.nameResolutionPromises)) {\n this.nameResolutionPromises[cacheKey] = mod.resolve(moduleName);\n }\n return this.nameResolutionPromises[cacheKey];\n }\n\n getEvaluationContext(moduleName: string, baseModule?: EvaluationContext): Promise<EvaluationContext> {\n // note: uses current module as base module if none specified by caller\n // @ts-ignore\n const mod = baseModule ?? (module as EvaluationContext);\n const cacheKey = this.getCacheKey(mod, moduleName);\n if (!(cacheKey in this.evaluationContextPromises)) {\n this.evaluationContextPromises[cacheKey] = mod.getModuleEvaluationContext(moduleName);\n }\n return this.evaluationContextPromises[cacheKey];\n }\n}\n\nexport const ModuleCacheContext = createContext<null | ModuleCache>(null);\n\nexport const ModuleCacheContextProvider = ({\n children,\n moduleCache,\n}: {\n children: ReactNode;\n moduleCache: ModuleCache;\n}) => {\n return <ModuleCacheContext.Provider value={moduleCache}>{children}</ModuleCacheContext.Provider>;\n};\n"],"mappings":";AA6DS;AA3DT,SAAS,qBAAgC;AAEzC,SAAS,mBAAmB;AAC5B,SAAS,eAAe;AAEjB,MAAM,YAAY;AAAA,EAIvB,cAAc;AAHd,kCAA0D,CAAC;AAC3D,qCAAwE,CAAC;AAUvE,gBAAY,SAAS,MAAM;AAAA,IAG3B,CAAC;AAAA,EACH;AAAA,EAEQ,YAAY,KAAwB,YAA4B;AACtE,WAAO,GAAG,IAAI,WAAW,OAAO,QAAQ,IAAI,UAAU;AAAA,EACxD;AAAA,EAEA,kBAAkB,YAAoB,YAAiD;AAGrF,UAAM,MAAM,cAAe;AAC3B,UAAM,WAAW,KAAK,YAAY,KAAK,UAAU;AACjD,QAAI,EAAE,YAAY,KAAK,yBAAyB;AAC9C,WAAK,uBAAuB,QAAQ,IAAI,IAAI,QAAQ,UAAU;AAAA,IAChE;AACA,WAAO,KAAK,uBAAuB,QAAQ;AAAA,EAC7C;AAAA,EAEA,qBAAqB,YAAoB,YAA4D;AAGnG,UAAM,MAAM,cAAe;AAC3B,UAAM,WAAW,KAAK,YAAY,KAAK,UAAU;AACjD,QAAI,EAAE,YAAY,KAAK,4BAA4B;AACjD,WAAK,0BAA0B,QAAQ,IAAI,IAAI,2BAA2B,UAAU;AAAA,IACtF;AACA,WAAO,KAAK,0BAA0B,QAAQ;AAAA,EAChD;AACF;AAEO,MAAM,qBAAqB,cAAkC,IAAI;AAEjE,MAAM,6BAA6B,CAAC;AAAA,EACzC;AAAA,EACA;AACF,MAGM;AACJ,SAAO,oBAAC,mBAAmB,UAAnB,EAA4B,OAAO,aAAc,UAAS;AACpE;","names":[]}
|