@fictjs/runtime 0.2.0 → 0.2.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/advanced.cjs +8 -8
- package/dist/advanced.js +3 -3
- package/dist/{chunk-BSUMPMKX.cjs → chunk-7EAEROZ5.cjs} +7 -7
- package/dist/{chunk-BSUMPMKX.cjs.map → chunk-7EAEROZ5.cjs.map} +1 -1
- package/dist/{chunk-QV5GOCR5.js → chunk-7TPCESQS.js} +2 -2
- package/dist/{chunk-5KXEEQUO.js → chunk-FOLRR3NZ.js} +1 -1
- package/dist/chunk-FOLRR3NZ.js.map +1 -0
- package/dist/{chunk-J74L7UYP.cjs → chunk-MWI3USXB.cjs} +1 -1
- package/dist/chunk-MWI3USXB.cjs.map +1 -0
- package/dist/{chunk-FG3M7EBL.js → chunk-VVNMIER7.js} +2 -2
- package/dist/{chunk-FG3M7EBL.js.map → chunk-VVNMIER7.js.map} +1 -1
- package/dist/{chunk-527QSKFM.cjs → chunk-Z5WRKD7Y.cjs} +16 -16
- package/dist/{chunk-527QSKFM.cjs.map → chunk-Z5WRKD7Y.cjs.map} +1 -1
- package/dist/index.cjs +46 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.dev.js +8 -12
- package/dist/index.dev.js.map +1 -1
- package/dist/index.js +10 -14
- package/dist/index.js.map +1 -1
- package/dist/internal.cjs +64 -42
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.js +32 -10
- package/dist/internal.js.map +1 -1
- package/package.json +1 -1
- package/src/context.ts +1 -1
- package/src/error-boundary.ts +9 -9
- package/src/signal.ts +2 -1
- package/src/store.ts +42 -20
- package/src/suspense.ts +0 -5
- package/dist/chunk-5KXEEQUO.js.map +0 -1
- package/dist/chunk-J74L7UYP.cjs.map +0 -1
- package/dist/jsx-runtime.d.cts +0 -671
- package/dist/jsx-runtime.d.ts +0 -671
- /package/dist/{chunk-QV5GOCR5.js.map → chunk-7TPCESQS.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
createContext,
|
|
3
3
|
hasContext,
|
|
4
4
|
useContext
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-VVNMIER7.js";
|
|
6
6
|
import {
|
|
7
7
|
Fragment,
|
|
8
8
|
batch2 as batch,
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
untrack2 as untrack,
|
|
35
35
|
useDeferredValue,
|
|
36
36
|
useTransition
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-FOLRR3NZ.js";
|
|
38
38
|
|
|
39
39
|
// src/ref.ts
|
|
40
40
|
function createRef() {
|
|
@@ -46,14 +46,15 @@ function ErrorBoundary(props) {
|
|
|
46
46
|
const fragment = document.createDocumentFragment();
|
|
47
47
|
const marker = document.createComment("fict:error-boundary");
|
|
48
48
|
fragment.appendChild(marker);
|
|
49
|
-
const currentView = signal(props.children ?? null);
|
|
50
49
|
const hostRoot = getCurrentRoot();
|
|
51
50
|
let cleanup;
|
|
52
51
|
let activeNodes = [];
|
|
53
52
|
let renderingFallback = false;
|
|
53
|
+
let reset = () => {
|
|
54
|
+
};
|
|
54
55
|
const toView = (err) => {
|
|
55
56
|
if (err != null) {
|
|
56
|
-
return typeof props.fallback === "function" ? props.fallback(err) : props.fallback;
|
|
57
|
+
return typeof props.fallback === "function" ? props.fallback(err, reset) : props.fallback;
|
|
57
58
|
}
|
|
58
59
|
return props.children ?? null;
|
|
59
60
|
};
|
|
@@ -81,7 +82,6 @@ function ErrorBoundary(props) {
|
|
|
81
82
|
}
|
|
82
83
|
} catch (err) {
|
|
83
84
|
popRoot(prev);
|
|
84
|
-
flushOnMount(root);
|
|
85
85
|
destroyRoot(root);
|
|
86
86
|
if (renderingFallback) {
|
|
87
87
|
throw err;
|
|
@@ -105,10 +105,11 @@ function ErrorBoundary(props) {
|
|
|
105
105
|
};
|
|
106
106
|
activeNodes = nodes;
|
|
107
107
|
};
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
renderValue(
|
|
111
|
-
}
|
|
108
|
+
reset = () => {
|
|
109
|
+
renderingFallback = false;
|
|
110
|
+
renderValue(toView(null));
|
|
111
|
+
};
|
|
112
|
+
renderValue(props.children ?? null);
|
|
112
113
|
registerErrorHandler((err) => {
|
|
113
114
|
renderValue(toView(err));
|
|
114
115
|
props.onError?.(err);
|
|
@@ -147,7 +148,6 @@ function createSuspenseToken() {
|
|
|
147
148
|
}
|
|
148
149
|
var isThenable = (value) => typeof value === "object" && value !== null && typeof value.then === "function";
|
|
149
150
|
function Suspense(props) {
|
|
150
|
-
const currentView = signal(props.children ?? null);
|
|
151
151
|
const pending = signal(0);
|
|
152
152
|
let resolvedOnce = false;
|
|
153
153
|
let epoch = 0;
|
|
@@ -183,7 +183,6 @@ function Suspense(props) {
|
|
|
183
183
|
}
|
|
184
184
|
} catch (err) {
|
|
185
185
|
popRoot(prev);
|
|
186
|
-
flushOnMount(root);
|
|
187
186
|
destroyRoot(root);
|
|
188
187
|
if (!handleError(err, { source: "render" }, hostRoot)) {
|
|
189
188
|
throw err;
|
|
@@ -212,7 +211,6 @@ function Suspense(props) {
|
|
|
212
211
|
registerSuspenseHandler((token) => {
|
|
213
212
|
const tokenEpoch = epoch;
|
|
214
213
|
pending(pending() + 1);
|
|
215
|
-
currentView(toFallback());
|
|
216
214
|
renderView(toFallback());
|
|
217
215
|
const thenable = token.then ? token : isThenable(token) ? token : null;
|
|
218
216
|
if (thenable) {
|
|
@@ -224,7 +222,6 @@ function Suspense(props) {
|
|
|
224
222
|
const newPending = Math.max(0, pending() - 1);
|
|
225
223
|
pending(newPending);
|
|
226
224
|
if (newPending === 0) {
|
|
227
|
-
currentView(props.children ?? null);
|
|
228
225
|
renderView(props.children ?? null);
|
|
229
226
|
onResolveMaybe();
|
|
230
227
|
}
|
|
@@ -256,7 +253,6 @@ function Suspense(props) {
|
|
|
256
253
|
prev = next;
|
|
257
254
|
epoch++;
|
|
258
255
|
pending(0);
|
|
259
|
-
currentView(props.children ?? null);
|
|
260
256
|
renderView(props.children ?? null);
|
|
261
257
|
}
|
|
262
258
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ref.ts","../src/error-boundary.ts","../src/suspense.ts"],"sourcesContent":["import type { RefObject } from './types'\n\n/**\n * Create a ref object for DOM element references.\n *\n * @returns A ref object with a `current` property initialized to `null`\n *\n * @example\n * ```tsx\n * import { createRef } from 'fict'\n *\n * function Component() {\n * const inputRef = createRef<HTMLInputElement>()\n *\n * $effect(() => {\n * inputRef.current?.focus()\n * })\n *\n * return <input ref={inputRef} />\n * }\n * ```\n */\nexport function createRef<T extends Element = HTMLElement>(): RefObject<T> {\n return { current: null }\n}\n","import { createElement } from './dom'\nimport { createEffect } from './effect'\nimport {\n createRootContext,\n destroyRoot,\n flushOnMount,\n getCurrentRoot,\n pushRoot,\n popRoot,\n registerErrorHandler,\n} from './lifecycle'\nimport { insertNodesBefore, removeNodes, toNodeArray } from './node-ops'\nimport { createSignal } from './signal'\nimport type { BaseProps, FictNode } from './types'\n\ninterface ErrorBoundaryProps extends BaseProps {\n fallback: FictNode | ((err: unknown) => FictNode)\n onError?: (err: unknown) => void\n resetKeys?: unknown | (() => unknown)\n}\n\nexport function ErrorBoundary(props: ErrorBoundaryProps): FictNode {\n const fragment = document.createDocumentFragment()\n const marker = document.createComment('fict:error-boundary')\n fragment.appendChild(marker)\n\n const currentView = createSignal<FictNode | null>(props.children ?? null)\n const hostRoot = getCurrentRoot()\n\n let cleanup: (() => void) | undefined\n let activeNodes: Node[] = []\n let renderingFallback = false\n\n const toView = (err: unknown | null): FictNode | null => {\n if (err != null) {\n return typeof props.fallback === 'function'\n ? (props.fallback as (e: unknown) => FictNode)(err)\n : props.fallback\n }\n return props.children ?? null\n }\n\n const renderValue = (value: FictNode | null) => {\n if (cleanup) {\n cleanup()\n cleanup = undefined\n }\n if (activeNodes.length) {\n removeNodes(activeNodes)\n activeNodes = []\n }\n\n if (value == null || value === false) {\n return\n }\n\n const root = createRootContext(hostRoot)\n const prev = pushRoot(root)\n let nodes: Node[] = []\n try {\n const output = createElement(value)\n nodes = toNodeArray(output)\n const parentNode = marker.parentNode as (ParentNode & Node) | null\n if (parentNode) {\n insertNodesBefore(parentNode, nodes, marker)\n }\n } catch (err) {\n popRoot(prev)\n flushOnMount(root)\n destroyRoot(root)\n // Fall back immediately on render errors, avoid infinite recursion\n if (renderingFallback) {\n throw err\n }\n // nested errors. If fallback rendering also throws, we should NOT reset\n // the flag until we're sure no more recursion is happening.\n renderingFallback = true\n try {\n renderValue(toView(err))\n // Only reset if successful - if renderValue threw, we want to keep\n // renderingFallback = true to prevent infinite recursion\n renderingFallback = false\n props.onError?.(err)\n } catch (fallbackErr) {\n // Fallback rendering failed - keep renderingFallback = true\n // to prevent further attempts, then rethrow\n // If fallback fails, report both errors\n props.onError?.(err)\n throw fallbackErr\n }\n return\n }\n popRoot(prev)\n flushOnMount(root)\n\n cleanup = () => {\n destroyRoot(root)\n removeNodes(nodes)\n }\n activeNodes = nodes\n }\n\n createEffect(() => {\n const value = currentView()\n renderValue(value)\n })\n\n registerErrorHandler(err => {\n renderValue(toView(err))\n props.onError?.(err)\n return true\n })\n\n if (props.resetKeys !== undefined) {\n const isGetter =\n typeof props.resetKeys === 'function' && (props.resetKeys as () => unknown).length === 0\n const getter = isGetter ? (props.resetKeys as () => unknown) : undefined\n let prev = isGetter ? getter!() : props.resetKeys\n createEffect(() => {\n const next = getter ? getter() : props.resetKeys\n if (prev !== next) {\n prev = next\n renderValue(toView(null))\n }\n })\n }\n\n return fragment\n}\n","import { createElement } from './dom'\nimport { createEffect } from './effect'\nimport {\n createRootContext,\n destroyRoot,\n flushOnMount,\n getCurrentRoot,\n handleError,\n pushRoot,\n popRoot,\n registerSuspenseHandler,\n} from './lifecycle'\nimport { insertNodesBefore, removeNodes, toNodeArray } from './node-ops'\nimport { createSignal } from './signal'\nimport type { BaseProps, FictNode, SuspenseToken } from './types'\n\nexport interface SuspenseProps extends BaseProps {\n fallback: FictNode | ((err?: unknown) => FictNode)\n onResolve?: () => void\n onReject?: (err: unknown) => void\n resetKeys?: unknown | (() => unknown)\n}\n\nexport interface SuspenseHandle {\n token: SuspenseToken\n resolve: () => void\n reject: (err: unknown) => void\n}\n\nexport function createSuspenseToken(): SuspenseHandle {\n let resolve!: () => void\n let reject!: (err: unknown) => void\n const promise = new Promise<void>((res, rej) => {\n resolve = res\n reject = rej\n })\n return {\n token: {\n then: promise.then.bind(promise),\n },\n resolve,\n reject,\n }\n}\n\nconst isThenable = (value: unknown): value is PromiseLike<unknown> =>\n typeof value === 'object' &&\n value !== null &&\n typeof (value as PromiseLike<unknown>).then === 'function'\n\nexport function Suspense(props: SuspenseProps): FictNode {\n const currentView = createSignal<FictNode | null>(props.children ?? null)\n const pending = createSignal(0)\n let resolvedOnce = false\n let epoch = 0\n const hostRoot = getCurrentRoot()\n\n const toFallback = (err?: unknown) =>\n typeof props.fallback === 'function'\n ? (props.fallback as (e?: unknown) => FictNode)(err)\n : props.fallback\n\n const renderView = (view: FictNode | null) => {\n if (cleanup) {\n cleanup()\n cleanup = undefined\n }\n if (activeNodes.length) {\n removeNodes(activeNodes)\n activeNodes = []\n }\n\n if (view == null || view === false) {\n return\n }\n\n const root = createRootContext(hostRoot)\n const prev = pushRoot(root)\n let nodes: Node[] = []\n try {\n const output = createElement(view)\n nodes = toNodeArray(output)\n // Suspended view: child threw a suspense token and was handled upstream.\n // Avoid replacing existing fallback content; tear down this attempt.\n const suspendedAttempt =\n root.suspended ||\n (nodes.length > 0 &&\n nodes.every(node => node instanceof Comment && (node as Comment).data === 'fict:suspend'))\n if (suspendedAttempt) {\n popRoot(prev)\n destroyRoot(root)\n return\n }\n const parentNode = marker.parentNode as (ParentNode & Node) | null\n if (parentNode) {\n insertNodesBefore(parentNode, nodes, marker)\n }\n } catch (err) {\n popRoot(prev)\n flushOnMount(root)\n destroyRoot(root)\n if (!handleError(err, { source: 'render' }, hostRoot)) {\n throw err\n }\n return\n }\n popRoot(prev)\n flushOnMount(root)\n\n cleanup = () => {\n destroyRoot(root)\n removeNodes(nodes)\n }\n activeNodes = nodes\n }\n\n const fragment = document.createDocumentFragment()\n const marker = document.createComment('fict:suspense')\n fragment.appendChild(marker)\n let cleanup: (() => void) | undefined\n let activeNodes: Node[] = []\n\n const onResolveMaybe = () => {\n if (!resolvedOnce) {\n resolvedOnce = true\n props.onResolve?.()\n }\n }\n\n registerSuspenseHandler(token => {\n const tokenEpoch = epoch\n pending(pending() + 1)\n // Directly render fallback instead of using switchView to avoid\n // triggering the effect which would cause duplicate renders\n currentView(toFallback())\n renderView(toFallback())\n\n const thenable = (token as SuspenseToken).then\n ? (token as SuspenseToken)\n : isThenable(token)\n ? token\n : null\n\n if (thenable) {\n thenable.then(\n () => {\n // This prevents stale token resolutions from affecting state after\n // a reset. The order is important: check epoch first, then update state.\n if (epoch !== tokenEpoch) {\n // Token is stale (from before a reset), ignore it completely\n return\n }\n // Use Math.max as a defensive measure - pending should never go below 0,\n // but this protects against edge cases where a token might resolve twice\n // or after the component has been reset.\n const newPending = Math.max(0, pending() - 1)\n pending(newPending)\n if (newPending === 0) {\n // Directly render children instead of using switchView\n currentView(props.children ?? null)\n renderView(props.children ?? null)\n onResolveMaybe()\n }\n },\n err => {\n // Same epoch check - ignore stale tokens\n if (epoch !== tokenEpoch) {\n return\n }\n const newPending = Math.max(0, pending() - 1)\n pending(newPending)\n props.onReject?.(err)\n if (!handleError(err, { source: 'render' }, hostRoot)) {\n throw err\n }\n },\n )\n return true\n }\n\n return false\n })\n\n // Initial render - render children directly\n // Note: This will be called synchronously during component creation.\n // If children suspend, the handler above will be called and switch to fallback.\n renderView(props.children ?? null)\n\n if (props.resetKeys !== undefined) {\n const isGetter =\n typeof props.resetKeys === 'function' && (props.resetKeys as () => unknown).length === 0\n const getter = isGetter ? (props.resetKeys as () => unknown) : undefined\n let prev = isGetter ? getter!() : props.resetKeys\n createEffect(() => {\n const next = getter ? getter() : props.resetKeys\n if (prev !== next) {\n prev = next\n epoch++\n pending(0)\n // Directly render children instead of using switchView\n currentView(props.children ?? null)\n renderView(props.children ?? null)\n }\n })\n }\n\n return fragment\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/ref.ts","../src/error-boundary.ts","../src/suspense.ts"],"sourcesContent":["import type { RefObject } from './types'\n\n/**\n * Create a ref object for DOM element references.\n *\n * @returns A ref object with a `current` property initialized to `null`\n *\n * @example\n * ```tsx\n * import { createRef } from 'fict'\n *\n * function Component() {\n * const inputRef = createRef<HTMLInputElement>()\n *\n * $effect(() => {\n * inputRef.current?.focus()\n * })\n *\n * return <input ref={inputRef} />\n * }\n * ```\n */\nexport function createRef<T extends Element = HTMLElement>(): RefObject<T> {\n return { current: null }\n}\n","import { createElement } from './dom'\nimport { createEffect } from './effect'\nimport {\n createRootContext,\n destroyRoot,\n flushOnMount,\n getCurrentRoot,\n pushRoot,\n popRoot,\n registerErrorHandler,\n} from './lifecycle'\nimport { insertNodesBefore, removeNodes, toNodeArray } from './node-ops'\nimport type { BaseProps, FictNode } from './types'\n\ninterface ErrorBoundaryProps extends BaseProps {\n fallback: FictNode | ((err: unknown, reset?: () => void) => FictNode)\n onError?: (err: unknown) => void\n resetKeys?: unknown | (() => unknown)\n}\n\nexport function ErrorBoundary(props: ErrorBoundaryProps): FictNode {\n const fragment = document.createDocumentFragment()\n const marker = document.createComment('fict:error-boundary')\n fragment.appendChild(marker)\n\n const hostRoot = getCurrentRoot()\n\n let cleanup: (() => void) | undefined\n let activeNodes: Node[] = []\n let renderingFallback = false\n\n let reset = () => {}\n const toView = (err: unknown | null): FictNode | null => {\n if (err != null) {\n return typeof props.fallback === 'function'\n ? (props.fallback as (e: unknown, reset?: () => void) => FictNode)(err, reset)\n : props.fallback\n }\n return props.children ?? null\n }\n\n const renderValue = (value: FictNode | null) => {\n if (cleanup) {\n cleanup()\n cleanup = undefined\n }\n if (activeNodes.length) {\n removeNodes(activeNodes)\n activeNodes = []\n }\n\n if (value == null || value === false) {\n return\n }\n\n const root = createRootContext(hostRoot)\n const prev = pushRoot(root)\n let nodes: Node[] = []\n try {\n const output = createElement(value)\n nodes = toNodeArray(output)\n const parentNode = marker.parentNode as (ParentNode & Node) | null\n if (parentNode) {\n insertNodesBefore(parentNode, nodes, marker)\n }\n } catch (err) {\n popRoot(prev)\n destroyRoot(root)\n // Fall back immediately on render errors, avoid infinite recursion\n if (renderingFallback) {\n throw err\n }\n // nested errors. If fallback rendering also throws, we should NOT reset\n // the flag until we're sure no more recursion is happening.\n renderingFallback = true\n try {\n renderValue(toView(err))\n // Only reset if successful - if renderValue threw, we want to keep\n // renderingFallback = true to prevent infinite recursion\n renderingFallback = false\n props.onError?.(err)\n } catch (fallbackErr) {\n // Fallback rendering failed - keep renderingFallback = true\n // to prevent further attempts, then rethrow\n // If fallback fails, report both errors\n props.onError?.(err)\n throw fallbackErr\n }\n return\n }\n popRoot(prev)\n flushOnMount(root)\n\n cleanup = () => {\n destroyRoot(root)\n removeNodes(nodes)\n }\n activeNodes = nodes\n }\n\n reset = () => {\n renderingFallback = false\n renderValue(toView(null))\n }\n\n renderValue(props.children ?? null)\n\n registerErrorHandler(err => {\n renderValue(toView(err))\n props.onError?.(err)\n return true\n })\n\n if (props.resetKeys !== undefined) {\n const isGetter =\n typeof props.resetKeys === 'function' && (props.resetKeys as () => unknown).length === 0\n const getter = isGetter ? (props.resetKeys as () => unknown) : undefined\n let prev = isGetter ? getter!() : props.resetKeys\n createEffect(() => {\n const next = getter ? getter() : props.resetKeys\n if (prev !== next) {\n prev = next\n renderValue(toView(null))\n }\n })\n }\n\n return fragment\n}\n","import { createElement } from './dom'\nimport { createEffect } from './effect'\nimport {\n createRootContext,\n destroyRoot,\n flushOnMount,\n getCurrentRoot,\n handleError,\n pushRoot,\n popRoot,\n registerSuspenseHandler,\n} from './lifecycle'\nimport { insertNodesBefore, removeNodes, toNodeArray } from './node-ops'\nimport { createSignal } from './signal'\nimport type { BaseProps, FictNode, SuspenseToken } from './types'\n\nexport interface SuspenseProps extends BaseProps {\n fallback: FictNode | ((err?: unknown) => FictNode)\n onResolve?: () => void\n onReject?: (err: unknown) => void\n resetKeys?: unknown | (() => unknown)\n}\n\nexport interface SuspenseHandle {\n token: SuspenseToken\n resolve: () => void\n reject: (err: unknown) => void\n}\n\nexport function createSuspenseToken(): SuspenseHandle {\n let resolve!: () => void\n let reject!: (err: unknown) => void\n const promise = new Promise<void>((res, rej) => {\n resolve = res\n reject = rej\n })\n return {\n token: {\n then: promise.then.bind(promise),\n },\n resolve,\n reject,\n }\n}\n\nconst isThenable = (value: unknown): value is PromiseLike<unknown> =>\n typeof value === 'object' &&\n value !== null &&\n typeof (value as PromiseLike<unknown>).then === 'function'\n\nexport function Suspense(props: SuspenseProps): FictNode {\n const pending = createSignal(0)\n let resolvedOnce = false\n let epoch = 0\n const hostRoot = getCurrentRoot()\n\n const toFallback = (err?: unknown) =>\n typeof props.fallback === 'function'\n ? (props.fallback as (e?: unknown) => FictNode)(err)\n : props.fallback\n\n const renderView = (view: FictNode | null) => {\n if (cleanup) {\n cleanup()\n cleanup = undefined\n }\n if (activeNodes.length) {\n removeNodes(activeNodes)\n activeNodes = []\n }\n\n if (view == null || view === false) {\n return\n }\n\n const root = createRootContext(hostRoot)\n const prev = pushRoot(root)\n let nodes: Node[] = []\n try {\n const output = createElement(view)\n nodes = toNodeArray(output)\n // Suspended view: child threw a suspense token and was handled upstream.\n // Avoid replacing existing fallback content; tear down this attempt.\n const suspendedAttempt =\n root.suspended ||\n (nodes.length > 0 &&\n nodes.every(node => node instanceof Comment && (node as Comment).data === 'fict:suspend'))\n if (suspendedAttempt) {\n popRoot(prev)\n destroyRoot(root)\n return\n }\n const parentNode = marker.parentNode as (ParentNode & Node) | null\n if (parentNode) {\n insertNodesBefore(parentNode, nodes, marker)\n }\n } catch (err) {\n popRoot(prev)\n destroyRoot(root)\n if (!handleError(err, { source: 'render' }, hostRoot)) {\n throw err\n }\n return\n }\n popRoot(prev)\n flushOnMount(root)\n\n cleanup = () => {\n destroyRoot(root)\n removeNodes(nodes)\n }\n activeNodes = nodes\n }\n\n const fragment = document.createDocumentFragment()\n const marker = document.createComment('fict:suspense')\n fragment.appendChild(marker)\n let cleanup: (() => void) | undefined\n let activeNodes: Node[] = []\n\n const onResolveMaybe = () => {\n if (!resolvedOnce) {\n resolvedOnce = true\n props.onResolve?.()\n }\n }\n\n registerSuspenseHandler(token => {\n const tokenEpoch = epoch\n pending(pending() + 1)\n // Directly render fallback instead of using switchView to avoid\n // triggering the effect which would cause duplicate renders\n renderView(toFallback())\n\n const thenable = (token as SuspenseToken).then\n ? (token as SuspenseToken)\n : isThenable(token)\n ? token\n : null\n\n if (thenable) {\n thenable.then(\n () => {\n // This prevents stale token resolutions from affecting state after\n // a reset. The order is important: check epoch first, then update state.\n if (epoch !== tokenEpoch) {\n // Token is stale (from before a reset), ignore it completely\n return\n }\n // Use Math.max as a defensive measure - pending should never go below 0,\n // but this protects against edge cases where a token might resolve twice\n // or after the component has been reset.\n const newPending = Math.max(0, pending() - 1)\n pending(newPending)\n if (newPending === 0) {\n // Directly render children instead of using switchView\n renderView(props.children ?? null)\n onResolveMaybe()\n }\n },\n err => {\n // Same epoch check - ignore stale tokens\n if (epoch !== tokenEpoch) {\n return\n }\n const newPending = Math.max(0, pending() - 1)\n pending(newPending)\n props.onReject?.(err)\n if (!handleError(err, { source: 'render' }, hostRoot)) {\n throw err\n }\n },\n )\n return true\n }\n\n return false\n })\n\n // Initial render - render children directly\n // Note: This will be called synchronously during component creation.\n // If children suspend, the handler above will be called and switch to fallback.\n renderView(props.children ?? null)\n\n if (props.resetKeys !== undefined) {\n const isGetter =\n typeof props.resetKeys === 'function' && (props.resetKeys as () => unknown).length === 0\n const getter = isGetter ? (props.resetKeys as () => unknown) : undefined\n let prev = isGetter ? getter!() : props.resetKeys\n createEffect(() => {\n const next = getter ? getter() : props.resetKeys\n if (prev !== next) {\n prev = next\n epoch++\n pending(0)\n // Directly render children instead of using switchView\n renderView(props.children ?? null)\n }\n })\n }\n\n return fragment\n}\n"],"mappings":"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","names":[]}
|
package/dist/internal.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunk7EAEROZ5cjs = require('./chunk-7EAEROZ5.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
@@ -66,7 +66,7 @@ var _chunkBSUMPMKXcjs = require('./chunk-BSUMPMKX.cjs');
|
|
|
66
66
|
|
|
67
67
|
|
|
68
68
|
|
|
69
|
-
var
|
|
69
|
+
var _chunkMWI3USXBcjs = require('./chunk-MWI3USXB.cjs');
|
|
70
70
|
|
|
71
71
|
// src/store.ts
|
|
72
72
|
var PROXY = Symbol("fict:store-proxy");
|
|
@@ -76,7 +76,7 @@ function createStore(initialValue) {
|
|
|
76
76
|
const unwrapped = unwrap2(initialValue);
|
|
77
77
|
const wrapped = wrap(unwrapped);
|
|
78
78
|
function setStore(fn) {
|
|
79
|
-
|
|
79
|
+
_chunkMWI3USXBcjs.batch.call(void 0, () => {
|
|
80
80
|
const result = fn(wrapped);
|
|
81
81
|
if (result !== void 0) {
|
|
82
82
|
reconcile(wrapped, result);
|
|
@@ -89,7 +89,7 @@ var proxyCache = /* @__PURE__ */ new WeakMap();
|
|
|
89
89
|
var signalCache = /* @__PURE__ */ new WeakMap();
|
|
90
90
|
function wrap(value) {
|
|
91
91
|
if (value === null || typeof value !== "object") return value;
|
|
92
|
-
if (value
|
|
92
|
+
if (Reflect.get(value, PROXY)) return value;
|
|
93
93
|
if (proxyCache.has(value)) return proxyCache.get(value);
|
|
94
94
|
const handler = {
|
|
95
95
|
get(target, prop2, receiver) {
|
|
@@ -114,6 +114,8 @@ function wrap(value) {
|
|
|
114
114
|
},
|
|
115
115
|
set(target, prop2, value2, receiver) {
|
|
116
116
|
if (prop2 === PROXY || prop2 === TARGET) return false;
|
|
117
|
+
const isArrayLength = Array.isArray(target) && prop2 === "length";
|
|
118
|
+
const oldLength = isArrayLength ? target.length : void 0;
|
|
117
119
|
const hadKey = Object.prototype.hasOwnProperty.call(target, prop2);
|
|
118
120
|
const oldValue = Reflect.get(target, prop2, receiver);
|
|
119
121
|
if (oldValue === value2) return true;
|
|
@@ -123,6 +125,23 @@ function wrap(value) {
|
|
|
123
125
|
if (!hadKey) {
|
|
124
126
|
trigger(target, ITERATE_KEY);
|
|
125
127
|
}
|
|
128
|
+
if (isArrayLength) {
|
|
129
|
+
const nextLength = target.length;
|
|
130
|
+
if (typeof oldLength === "number" && nextLength < oldLength) {
|
|
131
|
+
const signals = signalCache.get(target);
|
|
132
|
+
if (signals) {
|
|
133
|
+
for (const key of signals.keys()) {
|
|
134
|
+
if (typeof key !== "string") continue;
|
|
135
|
+
const index = Number(key);
|
|
136
|
+
if (!Number.isInteger(index) || String(index) !== key) continue;
|
|
137
|
+
if (index >= nextLength && index < oldLength) {
|
|
138
|
+
trigger(target, key);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
trigger(target, ITERATE_KEY);
|
|
144
|
+
}
|
|
126
145
|
}
|
|
127
146
|
return result;
|
|
128
147
|
},
|
|
@@ -143,8 +162,8 @@ function wrap(value) {
|
|
|
143
162
|
return proxy;
|
|
144
163
|
}
|
|
145
164
|
function unwrap2(value) {
|
|
146
|
-
if (value && typeof value === "object" && value
|
|
147
|
-
return value
|
|
165
|
+
if (value && typeof value === "object" && Reflect.get(value, PROXY)) {
|
|
166
|
+
return Reflect.get(value, TARGET);
|
|
148
167
|
}
|
|
149
168
|
return value;
|
|
150
169
|
}
|
|
@@ -157,7 +176,7 @@ function track(target, prop2) {
|
|
|
157
176
|
let s = signals.get(prop2);
|
|
158
177
|
if (!s) {
|
|
159
178
|
const initial = prop2 === ITERATE_KEY ? Reflect.ownKeys(target).length : getLastValue(target, prop2);
|
|
160
|
-
s =
|
|
179
|
+
s = _chunkMWI3USXBcjs.signal.call(void 0, initial);
|
|
161
180
|
signals.set(prop2, s);
|
|
162
181
|
}
|
|
163
182
|
s();
|
|
@@ -176,7 +195,7 @@ function trigger(target, prop2) {
|
|
|
176
195
|
}
|
|
177
196
|
}
|
|
178
197
|
function getLastValue(target, prop2) {
|
|
179
|
-
return target
|
|
198
|
+
return Reflect.get(target, prop2);
|
|
180
199
|
}
|
|
181
200
|
function reconcile(target, value) {
|
|
182
201
|
if (target === value) return;
|
|
@@ -191,13 +210,16 @@ function reconcile(target, value) {
|
|
|
191
210
|
const realValue = unwrap2(value);
|
|
192
211
|
const keys = /* @__PURE__ */ new Set([...Object.keys(realTarget), ...Object.keys(realValue)]);
|
|
193
212
|
for (const key of keys) {
|
|
194
|
-
|
|
213
|
+
const rTarget = realTarget;
|
|
214
|
+
const rValue = realValue;
|
|
215
|
+
if (rValue[key] === void 0 && rTarget[key] !== void 0) {
|
|
195
216
|
delete target[key];
|
|
196
|
-
} else if (
|
|
197
|
-
|
|
217
|
+
} else if (rTarget[key] !== rValue[key]) {
|
|
218
|
+
;
|
|
219
|
+
target[key] = rValue[key];
|
|
198
220
|
}
|
|
199
221
|
}
|
|
200
|
-
if (Array.isArray(target) && target.length !== realValue.length) {
|
|
222
|
+
if (Array.isArray(target) && Array.isArray(realValue) && target.length !== realValue.length) {
|
|
201
223
|
target.length = realValue.length;
|
|
202
224
|
}
|
|
203
225
|
}
|
|
@@ -329,7 +351,7 @@ var MAX_SAFE_VERSION = 9007199254740991;
|
|
|
329
351
|
function createVersionedSignalAccessor(initialValue) {
|
|
330
352
|
let current = initialValue;
|
|
331
353
|
let version = 0;
|
|
332
|
-
const track2 =
|
|
354
|
+
const track2 = _chunkMWI3USXBcjs.signal.call(void 0, version);
|
|
333
355
|
function accessor(value) {
|
|
334
356
|
if (arguments.length === 0) {
|
|
335
357
|
track2();
|
|
@@ -346,7 +368,7 @@ function createKeyedListContainer() {
|
|
|
346
368
|
const endMarker = document.createComment("fict:list:end");
|
|
347
369
|
const dispose = () => {
|
|
348
370
|
for (const block of container.blocks.values()) {
|
|
349
|
-
|
|
371
|
+
_chunkMWI3USXBcjs.destroyRoot.call(void 0, block.root);
|
|
350
372
|
}
|
|
351
373
|
container.blocks.clear();
|
|
352
374
|
container.nextBlocks.clear();
|
|
@@ -385,32 +407,32 @@ function createKeyedListContainer() {
|
|
|
385
407
|
}
|
|
386
408
|
function createKeyedBlock(key, item, index, render, needsIndex = true, hostRoot) {
|
|
387
409
|
const itemSig = createVersionedSignalAccessor(item);
|
|
388
|
-
const indexSig = needsIndex ?
|
|
410
|
+
const indexSig = needsIndex ? _chunkMWI3USXBcjs.signal.call(void 0, index) : ((next) => {
|
|
389
411
|
if (arguments.length === 0) return index;
|
|
390
412
|
index = next;
|
|
391
413
|
return index;
|
|
392
414
|
});
|
|
393
|
-
const root =
|
|
394
|
-
const prevRoot =
|
|
415
|
+
const root = _chunkMWI3USXBcjs.createRootContext.call(void 0, hostRoot);
|
|
416
|
+
const prevRoot = _chunkMWI3USXBcjs.pushRoot.call(void 0, root);
|
|
395
417
|
let nodes = [];
|
|
396
418
|
let scopeDispose;
|
|
397
|
-
const prevSub =
|
|
419
|
+
const prevSub = _chunkMWI3USXBcjs.setActiveSub.call(void 0, void 0);
|
|
398
420
|
try {
|
|
399
|
-
scopeDispose =
|
|
421
|
+
scopeDispose = _chunkMWI3USXBcjs.effectScope.call(void 0, () => {
|
|
400
422
|
const rendered = render(itemSig, indexSig, key);
|
|
401
423
|
if (rendered instanceof Node || Array.isArray(rendered) && rendered.every((n) => n instanceof Node)) {
|
|
402
|
-
nodes =
|
|
424
|
+
nodes = _chunkMWI3USXBcjs.toNodeArray.call(void 0, rendered);
|
|
403
425
|
} else {
|
|
404
|
-
const element =
|
|
405
|
-
nodes =
|
|
426
|
+
const element = _chunkMWI3USXBcjs.createElement.call(void 0, rendered);
|
|
427
|
+
nodes = _chunkMWI3USXBcjs.toNodeArray.call(void 0, element);
|
|
406
428
|
}
|
|
407
429
|
});
|
|
408
430
|
if (scopeDispose) {
|
|
409
431
|
root.cleanups.push(scopeDispose);
|
|
410
432
|
}
|
|
411
433
|
} finally {
|
|
412
|
-
|
|
413
|
-
|
|
434
|
+
_chunkMWI3USXBcjs.setActiveSub.call(void 0, prevSub);
|
|
435
|
+
_chunkMWI3USXBcjs.popRoot.call(void 0, prevRoot);
|
|
414
436
|
}
|
|
415
437
|
return {
|
|
416
438
|
key,
|
|
@@ -516,7 +538,7 @@ function createKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
516
538
|
}
|
|
517
539
|
function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
518
540
|
const container = createKeyedListContainer();
|
|
519
|
-
const hostRoot =
|
|
541
|
+
const hostRoot = _chunkMWI3USXBcjs.getCurrentRoot.call(void 0, );
|
|
520
542
|
const fragment = document.createDocumentFragment();
|
|
521
543
|
fragment.append(container.startMarker, container.endMarker);
|
|
522
544
|
let disposed = false;
|
|
@@ -538,7 +560,7 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
538
560
|
if (disposed) return;
|
|
539
561
|
const parent = getConnectedParent();
|
|
540
562
|
if (!parent) return;
|
|
541
|
-
|
|
563
|
+
_chunkMWI3USXBcjs.batch2.call(void 0, () => {
|
|
542
564
|
const oldBlocks = container.blocks;
|
|
543
565
|
const newBlocks = container.nextBlocks;
|
|
544
566
|
const prevOrderedBlocks = container.orderedBlocks;
|
|
@@ -548,7 +570,7 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
548
570
|
if (newItems.length === 0) {
|
|
549
571
|
if (oldBlocks.size > 0) {
|
|
550
572
|
for (const block of oldBlocks.values()) {
|
|
551
|
-
|
|
573
|
+
_chunkMWI3USXBcjs.destroyRoot.call(void 0, block.root);
|
|
552
574
|
}
|
|
553
575
|
const range = document.createRange();
|
|
554
576
|
range.setStartAfter(container.startMarker);
|
|
@@ -629,8 +651,8 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
629
651
|
`[fict] Duplicate key "${String(key)}" detected in list rendering. Each item should have a unique key. The previous item with this key will be replaced.`
|
|
630
652
|
);
|
|
631
653
|
}
|
|
632
|
-
|
|
633
|
-
|
|
654
|
+
_chunkMWI3USXBcjs.destroyRoot.call(void 0, existingBlock.root);
|
|
655
|
+
_chunkMWI3USXBcjs.removeNodes.call(void 0, existingBlock.nodes);
|
|
634
656
|
}
|
|
635
657
|
block = createKeyedBlock(key, item, index, renderItem, needsIndex, hostRoot);
|
|
636
658
|
createdBlocks.push(block);
|
|
@@ -643,8 +665,8 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
643
665
|
hasDuplicateKey = true;
|
|
644
666
|
const prior = nextOrderedBlocks[position];
|
|
645
667
|
if (prior && prior !== resolvedBlock) {
|
|
646
|
-
|
|
647
|
-
|
|
668
|
+
_chunkMWI3USXBcjs.destroyRoot.call(void 0, prior.root);
|
|
669
|
+
_chunkMWI3USXBcjs.removeNodes.call(void 0, prior.nodes);
|
|
648
670
|
}
|
|
649
671
|
nextOrderedBlocks[position] = resolvedBlock;
|
|
650
672
|
} else {
|
|
@@ -682,7 +704,7 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
682
704
|
}
|
|
683
705
|
}
|
|
684
706
|
if (appendedNodes.length > 0) {
|
|
685
|
-
|
|
707
|
+
_chunkMWI3USXBcjs.insertNodesBefore.call(void 0, parent, appendedNodes, container.endMarker);
|
|
686
708
|
const currentNodes = container.currentNodes;
|
|
687
709
|
currentNodes.pop();
|
|
688
710
|
for (let i = 0; i < appendedNodes.length; i++) {
|
|
@@ -696,15 +718,15 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
696
718
|
container.nextOrderedBlocks = prevOrderedBlocks;
|
|
697
719
|
for (const block of createdBlocks) {
|
|
698
720
|
if (newBlocks.get(block.key) === block) {
|
|
699
|
-
|
|
721
|
+
_chunkMWI3USXBcjs.flushOnMount.call(void 0, block.root);
|
|
700
722
|
}
|
|
701
723
|
}
|
|
702
724
|
return;
|
|
703
725
|
}
|
|
704
726
|
if (oldBlocks.size > 0) {
|
|
705
727
|
for (const block of oldBlocks.values()) {
|
|
706
|
-
|
|
707
|
-
|
|
728
|
+
_chunkMWI3USXBcjs.destroyRoot.call(void 0, block.root);
|
|
729
|
+
_chunkMWI3USXBcjs.removeNodes.call(void 0, block.nodes);
|
|
708
730
|
}
|
|
709
731
|
oldBlocks.clear();
|
|
710
732
|
}
|
|
@@ -763,7 +785,7 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
763
785
|
container.nextOrderedBlocks = prevOrderedBlocks;
|
|
764
786
|
for (const block of createdBlocks) {
|
|
765
787
|
if (newBlocks.get(block.key) === block) {
|
|
766
|
-
|
|
788
|
+
_chunkMWI3USXBcjs.flushOnMount.call(void 0, block.root);
|
|
767
789
|
}
|
|
768
790
|
}
|
|
769
791
|
});
|
|
@@ -777,15 +799,15 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
777
799
|
const parent = getConnectedParent();
|
|
778
800
|
if (!parent) return false;
|
|
779
801
|
const start = () => {
|
|
780
|
-
effectDispose =
|
|
802
|
+
effectDispose = _chunkMWI3USXBcjs.createRenderEffect.call(void 0, performDiff);
|
|
781
803
|
effectStarted = true;
|
|
782
804
|
};
|
|
783
805
|
if (hostRoot) {
|
|
784
|
-
const prev =
|
|
806
|
+
const prev = _chunkMWI3USXBcjs.pushRoot.call(void 0, hostRoot);
|
|
785
807
|
try {
|
|
786
808
|
start();
|
|
787
809
|
} finally {
|
|
788
|
-
|
|
810
|
+
_chunkMWI3USXBcjs.popRoot.call(void 0, prev);
|
|
789
811
|
}
|
|
790
812
|
} else {
|
|
791
813
|
start();
|
|
@@ -799,7 +821,7 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
799
821
|
if (getConnectedParent()) {
|
|
800
822
|
disconnectObserver();
|
|
801
823
|
if (ensureEffectStarted()) {
|
|
802
|
-
|
|
824
|
+
_chunkMWI3USXBcjs.flush.call(void 0, );
|
|
803
825
|
}
|
|
804
826
|
}
|
|
805
827
|
});
|
|
@@ -833,7 +855,7 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
833
855
|
if (disposed) return;
|
|
834
856
|
scheduleStart();
|
|
835
857
|
if (ensureEffectStarted()) {
|
|
836
|
-
|
|
858
|
+
_chunkMWI3USXBcjs.flush.call(void 0, );
|
|
837
859
|
} else {
|
|
838
860
|
waitForConnection();
|
|
839
861
|
}
|
|
@@ -906,5 +928,5 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
906
928
|
|
|
907
929
|
|
|
908
930
|
|
|
909
|
-
exports.Aliases =
|
|
931
|
+
exports.Aliases = _chunkMWI3USXBcjs.Aliases; exports.BooleanAttributes = _chunkMWI3USXBcjs.BooleanAttributes; exports.ChildProperties = _chunkMWI3USXBcjs.ChildProperties; exports.DelegatedEvents = _chunkMWI3USXBcjs.DelegatedEvents; exports.Fragment = _chunkMWI3USXBcjs.Fragment; exports.Properties = _chunkMWI3USXBcjs.Properties; exports.SVGElements = _chunkMWI3USXBcjs.SVGElements; exports.SVGNamespace = _chunkMWI3USXBcjs.SVGNamespace; exports.UnitlessStyles = _chunkMWI3USXBcjs.UnitlessStyles; exports.__fictPopContext = _chunkMWI3USXBcjs.__fictPopContext; exports.__fictProp = _chunkMWI3USXBcjs.__fictProp; exports.__fictPropsRest = _chunkMWI3USXBcjs.__fictPropsRest; exports.__fictPushContext = _chunkMWI3USXBcjs.__fictPushContext; exports.__fictRender = _chunkMWI3USXBcjs.__fictRender; exports.__fictResetContext = _chunkMWI3USXBcjs.__fictResetContext; exports.__fictUseContext = _chunkMWI3USXBcjs.__fictUseContext; exports.__fictUseEffect = _chunkMWI3USXBcjs.__fictUseEffect; exports.__fictUseMemo = _chunkMWI3USXBcjs.__fictUseMemo; exports.__fictUseSignal = _chunkMWI3USXBcjs.__fictUseSignal; exports.addEventListener = _chunkMWI3USXBcjs.addEventListener; exports.assign = _chunkMWI3USXBcjs.assign; exports.bindAttribute = _chunkMWI3USXBcjs.bindAttribute; exports.bindClass = _chunkMWI3USXBcjs.bindClass; exports.bindEvent = _chunkMWI3USXBcjs.bindEvent; exports.bindProperty = _chunkMWI3USXBcjs.bindProperty; exports.bindRef = _chunkMWI3USXBcjs.bindRef; exports.bindStyle = _chunkMWI3USXBcjs.bindStyle; exports.bindText = _chunkMWI3USXBcjs.bindText; exports.callEventHandler = _chunkMWI3USXBcjs.callEventHandler; exports.classList = _chunkMWI3USXBcjs.classList; exports.clearDelegatedEvents = _chunkMWI3USXBcjs.clearDelegatedEvents; exports.createConditional = _chunkMWI3USXBcjs.createConditional; exports.createEffect = _chunkMWI3USXBcjs.createEffect; exports.createElement = _chunkMWI3USXBcjs.createElement; exports.createKeyedList = createKeyedList; exports.createMemo = _chunkMWI3USXBcjs.createMemo; exports.createPortal = _chunkMWI3USXBcjs.createPortal; exports.createPropsProxy = _chunkMWI3USXBcjs.createPropsProxy; exports.createRenderEffect = _chunkMWI3USXBcjs.createRenderEffect; exports.createSelector = _chunkMWI3USXBcjs.createSelector; exports.createSignal = _chunkMWI3USXBcjs.signal; exports.createStore = createStore; exports.delegateEvents = _chunkMWI3USXBcjs.delegateEvents; exports.getPropAlias = _chunkMWI3USXBcjs.getPropAlias; exports.insert = _chunkMWI3USXBcjs.insert; exports.insertNodesBefore = _chunkMWI3USXBcjs.insertNodesBefore; exports.isNodeBetweenMarkers = isNodeBetweenMarkers; exports.isReactive = _chunkMWI3USXBcjs.isReactive; exports.mergeProps = _chunkMWI3USXBcjs.mergeProps; exports.moveNodesBefore = moveNodesBefore; exports.onDestroy = _chunkMWI3USXBcjs.onDestroy; exports.prop = _chunkMWI3USXBcjs.prop; exports.reconcileArrays = reconcileArrays; exports.removeNodes = _chunkMWI3USXBcjs.removeNodes; exports.runInScope = _chunk7EAEROZ5cjs.runInScope; exports.spread = _chunkMWI3USXBcjs.spread; exports.template = _chunkMWI3USXBcjs.template; exports.toNodeArray = _chunkMWI3USXBcjs.toNodeArray; exports.unwrap = _chunkMWI3USXBcjs.unwrap;
|
|
910
932
|
//# sourceMappingURL=internal.cjs.map
|