@fictjs/runtime 0.0.15 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/advanced.cjs +8 -8
  2. package/dist/advanced.d.cts +3 -3
  3. package/dist/advanced.d.ts +3 -3
  4. package/dist/advanced.js +3 -3
  5. package/dist/{chunk-GJTYOFMO.cjs → chunk-527QSKFM.cjs} +16 -16
  6. package/dist/{chunk-GJTYOFMO.cjs.map → chunk-527QSKFM.cjs.map} +1 -1
  7. package/dist/{chunk-RY4WDS6R.js → chunk-5KXEEQUO.js} +115 -20
  8. package/dist/chunk-5KXEEQUO.js.map +1 -0
  9. package/dist/{chunk-624QY53A.cjs → chunk-BSUMPMKX.cjs} +7 -7
  10. package/dist/chunk-BSUMPMKX.cjs.map +1 -0
  11. package/dist/{chunk-IUZXKAAY.js → chunk-FG3M7EBL.js} +2 -2
  12. package/dist/{chunk-PMF6MWEV.cjs → chunk-J74L7UYP.cjs} +128 -33
  13. package/dist/chunk-J74L7UYP.cjs.map +1 -0
  14. package/dist/{chunk-F3AIYQB7.js → chunk-QV5GOCR5.js} +3 -3
  15. package/dist/chunk-QV5GOCR5.js.map +1 -0
  16. package/dist/{context-B7UYnfzM.d.ts → context-4woHo7-L.d.ts} +1 -1
  17. package/dist/{context-UXySaqI_.d.cts → context-9gFXOdJl.d.cts} +1 -1
  18. package/dist/{effect-Auji1rz9.d.cts → effect-ClARNUCc.d.cts} +23 -2
  19. package/dist/{effect-Auji1rz9.d.ts → effect-ClARNUCc.d.ts} +23 -2
  20. package/dist/index.cjs +51 -54
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +4 -4
  23. package/dist/index.d.ts +4 -4
  24. package/dist/index.dev.js +96 -28
  25. package/dist/index.dev.js.map +1 -1
  26. package/dist/index.js +10 -13
  27. package/dist/index.js.map +1 -1
  28. package/dist/internal.cjs +44 -35
  29. package/dist/internal.cjs.map +1 -1
  30. package/dist/internal.d.cts +9 -4
  31. package/dist/internal.d.ts +9 -4
  32. package/dist/internal.js +12 -3
  33. package/dist/internal.js.map +1 -1
  34. package/dist/jsx-runtime.d.cts +671 -0
  35. package/dist/jsx-runtime.d.ts +671 -0
  36. package/dist/{props-ES0Ag_Wd.d.ts → props-CBwuh35e.d.cts} +13 -6
  37. package/dist/{props-CrOMYbLv.d.cts → props-DAyeRPwH.d.ts} +13 -6
  38. package/dist/{scope-S6eAzBJZ.d.ts → scope-DvgMquEy.d.ts} +1 -1
  39. package/dist/{scope-DKYzWfTn.d.cts → scope-xmdo6lVU.d.cts} +1 -1
  40. package/package.json +1 -1
  41. package/src/binding.ts +62 -8
  42. package/src/constants.ts +2 -3
  43. package/src/dev-entry.ts +22 -0
  44. package/src/effect.ts +9 -2
  45. package/src/lifecycle.ts +24 -6
  46. package/src/list-helpers.ts +14 -3
  47. package/src/props.ts +29 -3
  48. package/src/scope.ts +1 -1
  49. package/src/signal.ts +43 -4
  50. package/src/suspense.ts +17 -13
  51. package/dist/chunk-624QY53A.cjs.map +0 -1
  52. package/dist/chunk-F3AIYQB7.js.map +0 -1
  53. package/dist/chunk-PMF6MWEV.cjs.map +0 -1
  54. package/dist/chunk-RY4WDS6R.js.map +0 -1
  55. /package/dist/{chunk-IUZXKAAY.js.map → chunk-FG3M7EBL.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-IUZXKAAY.js";
5
+ } from "./chunk-FG3M7EBL.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-RY4WDS6R.js";
37
+ } from "./chunk-5KXEEQUO.js";
38
38
 
39
39
  // src/ref.ts
40
40
  function createRef() {
@@ -153,10 +153,6 @@ function Suspense(props) {
153
153
  let epoch = 0;
154
154
  const hostRoot = getCurrentRoot();
155
155
  const toFallback = (err) => typeof props.fallback === "function" ? props.fallback(err) : props.fallback;
156
- const switchView = (view) => {
157
- currentView(view);
158
- renderView(view);
159
- };
160
156
  const renderView = (view) => {
161
157
  if (cleanup) {
162
158
  cleanup();
@@ -175,7 +171,7 @@ function Suspense(props) {
175
171
  try {
176
172
  const output = createElement(view);
177
173
  nodes = toNodeArray(output);
178
- const suspendedAttempt = nodes.length > 0 && nodes.every((node) => node instanceof Comment && node.data === "fict:suspend");
174
+ const suspendedAttempt = root.suspended || nodes.length > 0 && nodes.every((node) => node instanceof Comment && node.data === "fict:suspend");
179
175
  if (suspendedAttempt) {
180
176
  popRoot(prev);
181
177
  destroyRoot(root);
@@ -216,7 +212,8 @@ function Suspense(props) {
216
212
  registerSuspenseHandler((token) => {
217
213
  const tokenEpoch = epoch;
218
214
  pending(pending() + 1);
219
- switchView(toFallback());
215
+ currentView(toFallback());
216
+ renderView(toFallback());
220
217
  const thenable = token.then ? token : isThenable(token) ? token : null;
221
218
  if (thenable) {
222
219
  thenable.then(
@@ -227,7 +224,8 @@ function Suspense(props) {
227
224
  const newPending = Math.max(0, pending() - 1);
228
225
  pending(newPending);
229
226
  if (newPending === 0) {
230
- switchView(props.children ?? null);
227
+ currentView(props.children ?? null);
228
+ renderView(props.children ?? null);
231
229
  onResolveMaybe();
232
230
  }
233
231
  },
@@ -247,9 +245,7 @@ function Suspense(props) {
247
245
  }
248
246
  return false;
249
247
  });
250
- createEffect(() => {
251
- renderView(currentView());
252
- });
248
+ renderView(props.children ?? null);
253
249
  if (props.resetKeys !== void 0) {
254
250
  const isGetter = typeof props.resetKeys === "function" && props.resetKeys.length === 0;
255
251
  const getter = isGetter ? props.resetKeys : void 0;
@@ -260,7 +256,8 @@ function Suspense(props) {
260
256
  prev = next;
261
257
  epoch++;
262
258
  pending(0);
263
- switchView(props.children ?? null);
259
+ currentView(props.children ?? null);
260
+ renderView(props.children ?? null);
264
261
  }
265
262
  });
266
263
  }
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 switchView = (view: FictNode | null) => {\n currentView(view)\n renderView(view)\n }\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 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 switchView(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 switchView(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 createEffect(() => {\n renderView(currentView())\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 epoch++\n pending(0)\n switchView(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 { 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":[]}
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 _chunk624QY53Acjs = require('./chunk-624QY53A.cjs');
3
+ var _chunkBSUMPMKXcjs = require('./chunk-BSUMPMKX.cjs');
4
4
 
5
5
 
6
6
 
@@ -66,7 +66,7 @@ var _chunk624QY53Acjs = require('./chunk-624QY53A.cjs');
66
66
 
67
67
 
68
68
 
69
- var _chunkPMF6MWEVcjs = require('./chunk-PMF6MWEV.cjs');
69
+ var _chunkJ74L7UYPcjs = require('./chunk-J74L7UYP.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
- _chunkPMF6MWEVcjs.batch.call(void 0, () => {
79
+ _chunkJ74L7UYPcjs.batch.call(void 0, () => {
80
80
  const result = fn(wrapped);
81
81
  if (result !== void 0) {
82
82
  reconcile(wrapped, result);
@@ -157,7 +157,7 @@ function track(target, prop2) {
157
157
  let s = signals.get(prop2);
158
158
  if (!s) {
159
159
  const initial = prop2 === ITERATE_KEY ? Reflect.ownKeys(target).length : getLastValue(target, prop2);
160
- s = _chunkPMF6MWEVcjs.signal.call(void 0, initial);
160
+ s = _chunkJ74L7UYPcjs.signal.call(void 0, initial);
161
161
  signals.set(prop2, s);
162
162
  }
163
163
  s();
@@ -308,6 +308,13 @@ function moveNodesBefore(parent, nodes, anchor) {
308
308
  try {
309
309
  const clone = parent.ownerDocument.importNode(node, true);
310
310
  parent.insertBefore(clone, anchor);
311
+ nodes[i] = clone;
312
+ if (isDev) {
313
+ console.warn(
314
+ `[fict] Node cloning fallback triggered during list reordering. This may indicate cross-document node insertion. The node reference has been updated to the clone.`
315
+ );
316
+ }
317
+ anchor = clone;
311
318
  continue;
312
319
  } catch (e2) {
313
320
  }
@@ -322,7 +329,7 @@ var MAX_SAFE_VERSION = 9007199254740991;
322
329
  function createVersionedSignalAccessor(initialValue) {
323
330
  let current = initialValue;
324
331
  let version = 0;
325
- const track2 = _chunkPMF6MWEVcjs.signal.call(void 0, version);
332
+ const track2 = _chunkJ74L7UYPcjs.signal.call(void 0, version);
326
333
  function accessor(value) {
327
334
  if (arguments.length === 0) {
328
335
  track2();
@@ -339,7 +346,7 @@ function createKeyedListContainer() {
339
346
  const endMarker = document.createComment("fict:list:end");
340
347
  const dispose = () => {
341
348
  for (const block of container.blocks.values()) {
342
- _chunkPMF6MWEVcjs.destroyRoot.call(void 0, block.root);
349
+ _chunkJ74L7UYPcjs.destroyRoot.call(void 0, block.root);
343
350
  }
344
351
  container.blocks.clear();
345
352
  container.nextBlocks.clear();
@@ -378,32 +385,32 @@ function createKeyedListContainer() {
378
385
  }
379
386
  function createKeyedBlock(key, item, index, render, needsIndex = true, hostRoot) {
380
387
  const itemSig = createVersionedSignalAccessor(item);
381
- const indexSig = needsIndex ? _chunkPMF6MWEVcjs.signal.call(void 0, index) : ((next) => {
388
+ const indexSig = needsIndex ? _chunkJ74L7UYPcjs.signal.call(void 0, index) : ((next) => {
382
389
  if (arguments.length === 0) return index;
383
390
  index = next;
384
391
  return index;
385
392
  });
386
- const root = _chunkPMF6MWEVcjs.createRootContext.call(void 0, hostRoot);
387
- const prevRoot = _chunkPMF6MWEVcjs.pushRoot.call(void 0, root);
393
+ const root = _chunkJ74L7UYPcjs.createRootContext.call(void 0, hostRoot);
394
+ const prevRoot = _chunkJ74L7UYPcjs.pushRoot.call(void 0, root);
388
395
  let nodes = [];
389
396
  let scopeDispose;
390
- const prevSub = _chunkPMF6MWEVcjs.setActiveSub.call(void 0, void 0);
397
+ const prevSub = _chunkJ74L7UYPcjs.setActiveSub.call(void 0, void 0);
391
398
  try {
392
- scopeDispose = _chunkPMF6MWEVcjs.effectScope.call(void 0, () => {
399
+ scopeDispose = _chunkJ74L7UYPcjs.effectScope.call(void 0, () => {
393
400
  const rendered = render(itemSig, indexSig, key);
394
401
  if (rendered instanceof Node || Array.isArray(rendered) && rendered.every((n) => n instanceof Node)) {
395
- nodes = _chunkPMF6MWEVcjs.toNodeArray.call(void 0, rendered);
402
+ nodes = _chunkJ74L7UYPcjs.toNodeArray.call(void 0, rendered);
396
403
  } else {
397
- const element = _chunkPMF6MWEVcjs.createElement.call(void 0, rendered);
398
- nodes = _chunkPMF6MWEVcjs.toNodeArray.call(void 0, element);
404
+ const element = _chunkJ74L7UYPcjs.createElement.call(void 0, rendered);
405
+ nodes = _chunkJ74L7UYPcjs.toNodeArray.call(void 0, element);
399
406
  }
400
407
  });
401
408
  if (scopeDispose) {
402
409
  root.cleanups.push(scopeDispose);
403
410
  }
404
411
  } finally {
405
- _chunkPMF6MWEVcjs.setActiveSub.call(void 0, prevSub);
406
- _chunkPMF6MWEVcjs.popRoot.call(void 0, prevRoot);
412
+ _chunkJ74L7UYPcjs.setActiveSub.call(void 0, prevSub);
413
+ _chunkJ74L7UYPcjs.popRoot.call(void 0, prevRoot);
407
414
  }
408
415
  return {
409
416
  key,
@@ -509,7 +516,7 @@ function createKeyedList(getItems, keyFn, renderItem, needsIndex) {
509
516
  }
510
517
  function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
511
518
  const container = createKeyedListContainer();
512
- const hostRoot = _chunkPMF6MWEVcjs.getCurrentRoot.call(void 0, );
519
+ const hostRoot = _chunkJ74L7UYPcjs.getCurrentRoot.call(void 0, );
513
520
  const fragment = document.createDocumentFragment();
514
521
  fragment.append(container.startMarker, container.endMarker);
515
522
  let disposed = false;
@@ -521,7 +528,9 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
521
528
  const endParent = container.endMarker.parentNode;
522
529
  const startParent = container.startMarker.parentNode;
523
530
  if (endParent && startParent && endParent === startParent && endParent.nodeType !== 11) {
524
- return endParent;
531
+ const parentNode = endParent;
532
+ if ("isConnected" in parentNode && !parentNode.isConnected) return null;
533
+ return parentNode;
525
534
  }
526
535
  return null;
527
536
  };
@@ -529,7 +538,7 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
529
538
  if (disposed) return;
530
539
  const parent = getConnectedParent();
531
540
  if (!parent) return;
532
- _chunkPMF6MWEVcjs.batch2.call(void 0, () => {
541
+ _chunkJ74L7UYPcjs.batch2.call(void 0, () => {
533
542
  const oldBlocks = container.blocks;
534
543
  const newBlocks = container.nextBlocks;
535
544
  const prevOrderedBlocks = container.orderedBlocks;
@@ -539,7 +548,7 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
539
548
  if (newItems.length === 0) {
540
549
  if (oldBlocks.size > 0) {
541
550
  for (const block of oldBlocks.values()) {
542
- _chunkPMF6MWEVcjs.destroyRoot.call(void 0, block.root);
551
+ _chunkJ74L7UYPcjs.destroyRoot.call(void 0, block.root);
543
552
  }
544
553
  const range = document.createRange();
545
554
  range.setStartAfter(container.startMarker);
@@ -620,8 +629,8 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
620
629
  `[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.`
621
630
  );
622
631
  }
623
- _chunkPMF6MWEVcjs.destroyRoot.call(void 0, existingBlock.root);
624
- _chunkPMF6MWEVcjs.removeNodes.call(void 0, existingBlock.nodes);
632
+ _chunkJ74L7UYPcjs.destroyRoot.call(void 0, existingBlock.root);
633
+ _chunkJ74L7UYPcjs.removeNodes.call(void 0, existingBlock.nodes);
625
634
  }
626
635
  block = createKeyedBlock(key, item, index, renderItem, needsIndex, hostRoot);
627
636
  createdBlocks.push(block);
@@ -634,8 +643,8 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
634
643
  hasDuplicateKey = true;
635
644
  const prior = nextOrderedBlocks[position];
636
645
  if (prior && prior !== resolvedBlock) {
637
- _chunkPMF6MWEVcjs.destroyRoot.call(void 0, prior.root);
638
- _chunkPMF6MWEVcjs.removeNodes.call(void 0, prior.nodes);
646
+ _chunkJ74L7UYPcjs.destroyRoot.call(void 0, prior.root);
647
+ _chunkJ74L7UYPcjs.removeNodes.call(void 0, prior.nodes);
639
648
  }
640
649
  nextOrderedBlocks[position] = resolvedBlock;
641
650
  } else {
@@ -673,7 +682,7 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
673
682
  }
674
683
  }
675
684
  if (appendedNodes.length > 0) {
676
- _chunkPMF6MWEVcjs.insertNodesBefore.call(void 0, parent, appendedNodes, container.endMarker);
685
+ _chunkJ74L7UYPcjs.insertNodesBefore.call(void 0, parent, appendedNodes, container.endMarker);
677
686
  const currentNodes = container.currentNodes;
678
687
  currentNodes.pop();
679
688
  for (let i = 0; i < appendedNodes.length; i++) {
@@ -687,15 +696,15 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
687
696
  container.nextOrderedBlocks = prevOrderedBlocks;
688
697
  for (const block of createdBlocks) {
689
698
  if (newBlocks.get(block.key) === block) {
690
- _chunkPMF6MWEVcjs.flushOnMount.call(void 0, block.root);
699
+ _chunkJ74L7UYPcjs.flushOnMount.call(void 0, block.root);
691
700
  }
692
701
  }
693
702
  return;
694
703
  }
695
704
  if (oldBlocks.size > 0) {
696
705
  for (const block of oldBlocks.values()) {
697
- _chunkPMF6MWEVcjs.destroyRoot.call(void 0, block.root);
698
- _chunkPMF6MWEVcjs.removeNodes.call(void 0, block.nodes);
706
+ _chunkJ74L7UYPcjs.destroyRoot.call(void 0, block.root);
707
+ _chunkJ74L7UYPcjs.removeNodes.call(void 0, block.nodes);
699
708
  }
700
709
  oldBlocks.clear();
701
710
  }
@@ -754,7 +763,7 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
754
763
  container.nextOrderedBlocks = prevOrderedBlocks;
755
764
  for (const block of createdBlocks) {
756
765
  if (newBlocks.get(block.key) === block) {
757
- _chunkPMF6MWEVcjs.flushOnMount.call(void 0, block.root);
766
+ _chunkJ74L7UYPcjs.flushOnMount.call(void 0, block.root);
758
767
  }
759
768
  }
760
769
  });
@@ -768,15 +777,15 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
768
777
  const parent = getConnectedParent();
769
778
  if (!parent) return false;
770
779
  const start = () => {
771
- effectDispose = _chunkPMF6MWEVcjs.createRenderEffect.call(void 0, performDiff);
780
+ effectDispose = _chunkJ74L7UYPcjs.createRenderEffect.call(void 0, performDiff);
772
781
  effectStarted = true;
773
782
  };
774
783
  if (hostRoot) {
775
- const prev = _chunkPMF6MWEVcjs.pushRoot.call(void 0, hostRoot);
784
+ const prev = _chunkJ74L7UYPcjs.pushRoot.call(void 0, hostRoot);
776
785
  try {
777
786
  start();
778
787
  } finally {
779
- _chunkPMF6MWEVcjs.popRoot.call(void 0, prev);
788
+ _chunkJ74L7UYPcjs.popRoot.call(void 0, prev);
780
789
  }
781
790
  } else {
782
791
  start();
@@ -790,7 +799,7 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
790
799
  if (getConnectedParent()) {
791
800
  disconnectObserver();
792
801
  if (ensureEffectStarted()) {
793
- _chunkPMF6MWEVcjs.flush.call(void 0, );
802
+ _chunkJ74L7UYPcjs.flush.call(void 0, );
794
803
  }
795
804
  }
796
805
  });
@@ -824,7 +833,7 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
824
833
  if (disposed) return;
825
834
  scheduleStart();
826
835
  if (ensureEffectStarted()) {
827
- _chunkPMF6MWEVcjs.flush.call(void 0, );
836
+ _chunkJ74L7UYPcjs.flush.call(void 0, );
828
837
  } else {
829
838
  waitForConnection();
830
839
  }
@@ -897,5 +906,5 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
897
906
 
898
907
 
899
908
 
900
- exports.Aliases = _chunkPMF6MWEVcjs.Aliases; exports.BooleanAttributes = _chunkPMF6MWEVcjs.BooleanAttributes; exports.ChildProperties = _chunkPMF6MWEVcjs.ChildProperties; exports.DelegatedEvents = _chunkPMF6MWEVcjs.DelegatedEvents; exports.Fragment = _chunkPMF6MWEVcjs.Fragment; exports.Properties = _chunkPMF6MWEVcjs.Properties; exports.SVGElements = _chunkPMF6MWEVcjs.SVGElements; exports.SVGNamespace = _chunkPMF6MWEVcjs.SVGNamespace; exports.UnitlessStyles = _chunkPMF6MWEVcjs.UnitlessStyles; exports.__fictPopContext = _chunkPMF6MWEVcjs.__fictPopContext; exports.__fictProp = _chunkPMF6MWEVcjs.__fictProp; exports.__fictPropsRest = _chunkPMF6MWEVcjs.__fictPropsRest; exports.__fictPushContext = _chunkPMF6MWEVcjs.__fictPushContext; exports.__fictRender = _chunkPMF6MWEVcjs.__fictRender; exports.__fictResetContext = _chunkPMF6MWEVcjs.__fictResetContext; exports.__fictUseContext = _chunkPMF6MWEVcjs.__fictUseContext; exports.__fictUseEffect = _chunkPMF6MWEVcjs.__fictUseEffect; exports.__fictUseMemo = _chunkPMF6MWEVcjs.__fictUseMemo; exports.__fictUseSignal = _chunkPMF6MWEVcjs.__fictUseSignal; exports.addEventListener = _chunkPMF6MWEVcjs.addEventListener; exports.assign = _chunkPMF6MWEVcjs.assign; exports.bindAttribute = _chunkPMF6MWEVcjs.bindAttribute; exports.bindClass = _chunkPMF6MWEVcjs.bindClass; exports.bindEvent = _chunkPMF6MWEVcjs.bindEvent; exports.bindProperty = _chunkPMF6MWEVcjs.bindProperty; exports.bindRef = _chunkPMF6MWEVcjs.bindRef; exports.bindStyle = _chunkPMF6MWEVcjs.bindStyle; exports.bindText = _chunkPMF6MWEVcjs.bindText; exports.callEventHandler = _chunkPMF6MWEVcjs.callEventHandler; exports.classList = _chunkPMF6MWEVcjs.classList; exports.clearDelegatedEvents = _chunkPMF6MWEVcjs.clearDelegatedEvents; exports.createConditional = _chunkPMF6MWEVcjs.createConditional; exports.createEffect = _chunkPMF6MWEVcjs.createEffect; exports.createElement = _chunkPMF6MWEVcjs.createElement; exports.createKeyedList = createKeyedList; exports.createMemo = _chunkPMF6MWEVcjs.createMemo; exports.createPortal = _chunkPMF6MWEVcjs.createPortal; exports.createPropsProxy = _chunkPMF6MWEVcjs.createPropsProxy; exports.createRenderEffect = _chunkPMF6MWEVcjs.createRenderEffect; exports.createSelector = _chunkPMF6MWEVcjs.createSelector; exports.createSignal = _chunkPMF6MWEVcjs.signal; exports.createStore = createStore; exports.delegateEvents = _chunkPMF6MWEVcjs.delegateEvents; exports.getPropAlias = _chunkPMF6MWEVcjs.getPropAlias; exports.insert = _chunkPMF6MWEVcjs.insert; exports.insertNodesBefore = _chunkPMF6MWEVcjs.insertNodesBefore; exports.isNodeBetweenMarkers = isNodeBetweenMarkers; exports.isReactive = _chunkPMF6MWEVcjs.isReactive; exports.mergeProps = _chunkPMF6MWEVcjs.mergeProps; exports.moveNodesBefore = moveNodesBefore; exports.onDestroy = _chunkPMF6MWEVcjs.onDestroy; exports.prop = _chunkPMF6MWEVcjs.prop; exports.reconcileArrays = reconcileArrays; exports.removeNodes = _chunkPMF6MWEVcjs.removeNodes; exports.runInScope = _chunk624QY53Acjs.runInScope; exports.spread = _chunkPMF6MWEVcjs.spread; exports.template = _chunkPMF6MWEVcjs.template; exports.toNodeArray = _chunkPMF6MWEVcjs.toNodeArray; exports.unwrap = _chunkPMF6MWEVcjs.unwrap;
909
+ exports.Aliases = _chunkJ74L7UYPcjs.Aliases; exports.BooleanAttributes = _chunkJ74L7UYPcjs.BooleanAttributes; exports.ChildProperties = _chunkJ74L7UYPcjs.ChildProperties; exports.DelegatedEvents = _chunkJ74L7UYPcjs.DelegatedEvents; exports.Fragment = _chunkJ74L7UYPcjs.Fragment; exports.Properties = _chunkJ74L7UYPcjs.Properties; exports.SVGElements = _chunkJ74L7UYPcjs.SVGElements; exports.SVGNamespace = _chunkJ74L7UYPcjs.SVGNamespace; exports.UnitlessStyles = _chunkJ74L7UYPcjs.UnitlessStyles; exports.__fictPopContext = _chunkJ74L7UYPcjs.__fictPopContext; exports.__fictProp = _chunkJ74L7UYPcjs.__fictProp; exports.__fictPropsRest = _chunkJ74L7UYPcjs.__fictPropsRest; exports.__fictPushContext = _chunkJ74L7UYPcjs.__fictPushContext; exports.__fictRender = _chunkJ74L7UYPcjs.__fictRender; exports.__fictResetContext = _chunkJ74L7UYPcjs.__fictResetContext; exports.__fictUseContext = _chunkJ74L7UYPcjs.__fictUseContext; exports.__fictUseEffect = _chunkJ74L7UYPcjs.__fictUseEffect; exports.__fictUseMemo = _chunkJ74L7UYPcjs.__fictUseMemo; exports.__fictUseSignal = _chunkJ74L7UYPcjs.__fictUseSignal; exports.addEventListener = _chunkJ74L7UYPcjs.addEventListener; exports.assign = _chunkJ74L7UYPcjs.assign; exports.bindAttribute = _chunkJ74L7UYPcjs.bindAttribute; exports.bindClass = _chunkJ74L7UYPcjs.bindClass; exports.bindEvent = _chunkJ74L7UYPcjs.bindEvent; exports.bindProperty = _chunkJ74L7UYPcjs.bindProperty; exports.bindRef = _chunkJ74L7UYPcjs.bindRef; exports.bindStyle = _chunkJ74L7UYPcjs.bindStyle; exports.bindText = _chunkJ74L7UYPcjs.bindText; exports.callEventHandler = _chunkJ74L7UYPcjs.callEventHandler; exports.classList = _chunkJ74L7UYPcjs.classList; exports.clearDelegatedEvents = _chunkJ74L7UYPcjs.clearDelegatedEvents; exports.createConditional = _chunkJ74L7UYPcjs.createConditional; exports.createEffect = _chunkJ74L7UYPcjs.createEffect; exports.createElement = _chunkJ74L7UYPcjs.createElement; exports.createKeyedList = createKeyedList; exports.createMemo = _chunkJ74L7UYPcjs.createMemo; exports.createPortal = _chunkJ74L7UYPcjs.createPortal; exports.createPropsProxy = _chunkJ74L7UYPcjs.createPropsProxy; exports.createRenderEffect = _chunkJ74L7UYPcjs.createRenderEffect; exports.createSelector = _chunkJ74L7UYPcjs.createSelector; exports.createSignal = _chunkJ74L7UYPcjs.signal; exports.createStore = createStore; exports.delegateEvents = _chunkJ74L7UYPcjs.delegateEvents; exports.getPropAlias = _chunkJ74L7UYPcjs.getPropAlias; exports.insert = _chunkJ74L7UYPcjs.insert; exports.insertNodesBefore = _chunkJ74L7UYPcjs.insertNodesBefore; exports.isNodeBetweenMarkers = isNodeBetweenMarkers; exports.isReactive = _chunkJ74L7UYPcjs.isReactive; exports.mergeProps = _chunkJ74L7UYPcjs.mergeProps; exports.moveNodesBefore = moveNodesBefore; exports.onDestroy = _chunkJ74L7UYPcjs.onDestroy; exports.prop = _chunkJ74L7UYPcjs.prop; exports.reconcileArrays = reconcileArrays; exports.removeNodes = _chunkJ74L7UYPcjs.removeNodes; exports.runInScope = _chunkBSUMPMKXcjs.runInScope; exports.spread = _chunkJ74L7UYPcjs.spread; exports.template = _chunkJ74L7UYPcjs.template; exports.toNodeArray = _chunkJ74L7UYPcjs.toNodeArray; exports.unwrap = _chunkJ74L7UYPcjs.unwrap;
901
910
  //# sourceMappingURL=internal.cjs.map