@fictjs/runtime 0.17.0 → 0.17.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.
Files changed (64) hide show
  1. package/dist/advanced.cjs +9 -9
  2. package/dist/advanced.d.cts +3 -3
  3. package/dist/advanced.d.ts +3 -3
  4. package/dist/advanced.js +4 -4
  5. package/dist/{binding-CQUGLLBI.d.ts → binding-BfzY9rae.d.ts} +2 -2
  6. package/dist/{binding-BlABuUiG.d.cts → binding-CDR2ERoq.d.cts} +2 -2
  7. package/dist/{chunk-5FVWBK4M.cjs → chunk-2J4INHDT.cjs} +40 -40
  8. package/dist/{chunk-5FVWBK4M.cjs.map → chunk-2J4INHDT.cjs.map} +1 -1
  9. package/dist/{chunk-6DNYVH5U.cjs → chunk-CKKZDUHM.cjs} +21 -18
  10. package/dist/chunk-CKKZDUHM.cjs.map +1 -0
  11. package/dist/{chunk-UQTWIV3S.js → chunk-DHRRJJ6W.js} +8 -5
  12. package/dist/chunk-DHRRJJ6W.js.map +1 -0
  13. package/dist/{chunk-IIWHTV23.js → chunk-LFLFSJFU.js} +3 -3
  14. package/dist/{chunk-ECKYFH5Q.cjs → chunk-NBDEMBBX.cjs} +43 -81
  15. package/dist/chunk-NBDEMBBX.cjs.map +1 -0
  16. package/dist/{chunk-CFAWL76V.js → chunk-OKPQWORE.js} +43 -81
  17. package/dist/chunk-OKPQWORE.js.map +1 -0
  18. package/dist/{chunk-M42N54LG.js → chunk-OLHZBAIF.js} +3 -3
  19. package/dist/{chunk-F5SDRX4J.js → chunk-R2HYEOP7.js} +470 -172
  20. package/dist/chunk-R2HYEOP7.js.map +1 -0
  21. package/dist/{chunk-INYTG4NG.cjs → chunk-UG2IFQOY.cjs} +650 -352
  22. package/dist/chunk-UG2IFQOY.cjs.map +1 -0
  23. package/dist/{chunk-WY4LI5PB.cjs → chunk-VP2WC7X3.cjs} +8 -8
  24. package/dist/{chunk-WY4LI5PB.cjs.map → chunk-VP2WC7X3.cjs.map} +1 -1
  25. package/dist/{devtools-DWIZRe7L.d.cts → devtools-BwkkQ6DN.d.cts} +1 -1
  26. package/dist/{devtools-DNnnDGu1.d.ts → devtools-CK3SVU_w.d.ts} +1 -1
  27. package/dist/index.cjs +55 -42
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.cts +4 -4
  30. package/dist/index.d.ts +4 -4
  31. package/dist/index.dev.js +260 -156
  32. package/dist/index.dev.js.map +1 -1
  33. package/dist/index.js +16 -3
  34. package/dist/index.js.map +1 -1
  35. package/dist/internal-list.cjs +4 -4
  36. package/dist/internal-list.js +3 -3
  37. package/dist/internal.cjs +5 -5
  38. package/dist/internal.d.cts +3 -3
  39. package/dist/internal.d.ts +3 -3
  40. package/dist/internal.js +4 -4
  41. package/dist/loader.cjs +18 -18
  42. package/dist/loader.js +1 -1
  43. package/dist/{props-C04ScJgm.d.ts → props-CFoQ471Y.d.ts} +1 -1
  44. package/dist/{props-CdmuXCiu.d.cts → props-D4tK8Gn0.d.cts} +1 -1
  45. package/dist/{scope-gpOMWTlf.d.ts → scope-BFzD_7hx.d.ts} +1 -1
  46. package/dist/{scope-GwC4DJ50.d.cts → scope-Ck3mTQVS.d.cts} +1 -1
  47. package/package.json +1 -1
  48. package/src/binding.ts +561 -166
  49. package/src/context.ts +8 -1
  50. package/src/dom.ts +26 -44
  51. package/src/effect.ts +9 -12
  52. package/src/error-boundary.ts +8 -0
  53. package/src/hydration.ts +25 -6
  54. package/src/lifecycle.ts +31 -79
  55. package/src/signal.ts +4 -1
  56. package/src/suspense.ts +8 -0
  57. package/dist/chunk-6DNYVH5U.cjs.map +0 -1
  58. package/dist/chunk-CFAWL76V.js.map +0 -1
  59. package/dist/chunk-ECKYFH5Q.cjs.map +0 -1
  60. package/dist/chunk-F5SDRX4J.js.map +0 -1
  61. package/dist/chunk-INYTG4NG.cjs.map +0 -1
  62. package/dist/chunk-UQTWIV3S.js.map +0 -1
  63. /package/dist/{chunk-IIWHTV23.js.map → chunk-LFLFSJFU.js.map} +0 -0
  64. /package/dist/{chunk-M42N54LG.js.map → chunk-OLHZBAIF.js.map} +0 -0
@@ -1,4 +1,4 @@
1
- import { B as BaseProps, F as FictNode } from './binding-CQUGLLBI.js';
1
+ import { B as BaseProps, F as FictNode } from './binding-BfzY9rae.js';
2
2
 
3
3
  /**
4
4
  * @fileoverview Context API for Fict
package/dist/index.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
 
4
4
 
5
- var _chunk6DNYVH5Ucjs = require('./chunk-6DNYVH5U.cjs');
5
+ var _chunkCKKZDUHMcjs = require('./chunk-CKKZDUHM.cjs');
6
6
 
7
7
 
8
8
 
@@ -19,7 +19,7 @@ var _chunk6DNYVH5Ucjs = require('./chunk-6DNYVH5U.cjs');
19
19
 
20
20
 
21
21
 
22
- var _chunkINYTG4NGcjs = require('./chunk-INYTG4NG.cjs');
22
+ var _chunkUG2IFQOYcjs = require('./chunk-UG2IFQOY.cjs');
23
23
 
24
24
 
25
25
 
@@ -40,7 +40,8 @@ var _chunkINYTG4NGcjs = require('./chunk-INYTG4NG.cjs');
40
40
 
41
41
 
42
42
 
43
- var _chunkECKYFH5Qcjs = require('./chunk-ECKYFH5Q.cjs');
43
+
44
+ var _chunkNBDEMBBXcjs = require('./chunk-NBDEMBBX.cjs');
44
45
 
45
46
  // src/ref.ts
46
47
  function createRef() {
@@ -49,7 +50,7 @@ function createRef() {
49
50
 
50
51
  // src/error-boundary.ts
51
52
  function ErrorBoundary(props) {
52
- const hostRoot = _chunkECKYFH5Qcjs.getCurrentRoot.call(void 0, );
53
+ const hostRoot = _chunkNBDEMBBXcjs.getCurrentRoot.call(void 0, );
53
54
  const markerOwnerDocument = _nullishCoalesce(_optionalChain([hostRoot, 'optionalAccess', _ => _.ownerDocument]), () => ( document));
54
55
  const fragment = markerOwnerDocument.createDocumentFragment();
55
56
  const marker = markerOwnerDocument.createComment("fict:error-boundary");
@@ -71,25 +72,25 @@ function ErrorBoundary(props) {
71
72
  cleanup = void 0;
72
73
  }
73
74
  if (activeNodes.length) {
74
- _chunkINYTG4NGcjs.removeNodes.call(void 0, activeNodes);
75
+ _chunkUG2IFQOYcjs.removeNodes.call(void 0, activeNodes);
75
76
  activeNodes = [];
76
77
  }
77
78
  if (value == null || value === false) {
78
79
  return;
79
80
  }
80
- const root = _chunkECKYFH5Qcjs.createRootContext.call(void 0, hostRoot);
81
- const prev = _chunkECKYFH5Qcjs.pushRoot.call(void 0, root);
81
+ const root = _chunkNBDEMBBXcjs.createRootContext.call(void 0, hostRoot);
82
+ const prev = _chunkNBDEMBBXcjs.pushRoot.call(void 0, root);
82
83
  let nodes = [];
83
84
  try {
84
- const output = _chunkINYTG4NGcjs.createElement.call(void 0, value);
85
- nodes = _chunkINYTG4NGcjs.toNodeArray.call(void 0, output, markerOwnerDocument);
85
+ const output = _chunkUG2IFQOYcjs.createElement.call(void 0, value);
86
+ nodes = _chunkUG2IFQOYcjs.toNodeArray.call(void 0, output, markerOwnerDocument);
86
87
  const parentNode = marker.parentNode;
87
88
  if (parentNode) {
88
- _chunkINYTG4NGcjs.insertNodesBefore.call(void 0, parentNode, nodes, marker);
89
+ _chunkUG2IFQOYcjs.insertNodesBefore.call(void 0, parentNode, nodes, marker);
89
90
  }
90
91
  } catch (err) {
91
- _chunkECKYFH5Qcjs.popRoot.call(void 0, prev);
92
- _chunkECKYFH5Qcjs.destroyRoot.call(void 0, root);
92
+ _chunkNBDEMBBXcjs.popRoot.call(void 0, prev);
93
+ _chunkNBDEMBBXcjs.destroyRoot.call(void 0, root);
93
94
  if (renderingFallback) {
94
95
  throw err;
95
96
  }
@@ -104,11 +105,11 @@ function ErrorBoundary(props) {
104
105
  }
105
106
  return;
106
107
  }
107
- _chunkECKYFH5Qcjs.popRoot.call(void 0, prev);
108
- _chunkECKYFH5Qcjs.flushOnMount.call(void 0, root);
108
+ _chunkNBDEMBBXcjs.popRoot.call(void 0, prev);
109
+ _chunkNBDEMBBXcjs.flushOnMount.call(void 0, root);
109
110
  cleanup = () => {
110
- _chunkECKYFH5Qcjs.destroyRoot.call(void 0, root);
111
- _chunkINYTG4NGcjs.removeNodes.call(void 0, nodes);
111
+ _chunkNBDEMBBXcjs.destroyRoot.call(void 0, root);
112
+ _chunkUG2IFQOYcjs.removeNodes.call(void 0, nodes);
112
113
  };
113
114
  activeNodes = nodes;
114
115
  };
@@ -117,7 +118,13 @@ function ErrorBoundary(props) {
117
118
  renderValue(toView(null));
118
119
  };
119
120
  renderValue(_nullishCoalesce(props.children, () => ( null)));
120
- _chunkECKYFH5Qcjs.registerErrorHandler.call(void 0, (err) => {
121
+ _chunkNBDEMBBXcjs.registerRootCleanup.call(void 0, () => {
122
+ if (cleanup) {
123
+ cleanup();
124
+ cleanup = void 0;
125
+ }
126
+ });
127
+ _chunkNBDEMBBXcjs.registerErrorHandler.call(void 0, (err) => {
121
128
  renderValue(toView(err));
122
129
  _optionalChain([props, 'access', _6 => _6.onError, 'optionalCall', _7 => _7(err)]);
123
130
  return true;
@@ -126,7 +133,7 @@ function ErrorBoundary(props) {
126
133
  const isGetter = typeof props.resetKeys === "function" && props.resetKeys.length === 0;
127
134
  const getter = isGetter ? props.resetKeys : void 0;
128
135
  let prev = isGetter ? getter() : props.resetKeys;
129
- _chunkECKYFH5Qcjs.createEffect.call(void 0, () => {
136
+ _chunkNBDEMBBXcjs.createEffect.call(void 0, () => {
130
137
  const next = getter ? getter() : props.resetKeys;
131
138
  if (prev !== next) {
132
139
  prev = next;
@@ -155,11 +162,11 @@ function createSuspenseToken() {
155
162
  }
156
163
  var isThenable = (value) => typeof value === "object" && value !== null && typeof value.then === "function";
157
164
  function Suspense(props) {
158
- const streamHooks = _chunkECKYFH5Qcjs.__fictGetSSRStreamHooks.call(void 0, );
159
- const pending = _chunkECKYFH5Qcjs.signal.call(void 0, 0);
165
+ const streamHooks = _chunkNBDEMBBXcjs.__fictGetSSRStreamHooks.call(void 0, );
166
+ const pending = _chunkNBDEMBBXcjs.signal.call(void 0, 0);
160
167
  let resolvedOnce = false;
161
168
  let epoch = 0;
162
- const hostRoot = _chunkECKYFH5Qcjs.getCurrentRoot.call(void 0, );
169
+ const hostRoot = _chunkNBDEMBBXcjs.getCurrentRoot.call(void 0, );
163
170
  const markerOwnerDocument = _nullishCoalesce(_optionalChain([hostRoot, 'optionalAccess', _8 => _8.ownerDocument]), () => ( document));
164
171
  const toFallback = (err) => typeof props.fallback === "function" ? props.fallback(err) : props.fallback;
165
172
  const renderView = (view) => {
@@ -168,50 +175,50 @@ function Suspense(props) {
168
175
  cleanup = void 0;
169
176
  }
170
177
  if (activeNodes.length) {
171
- _chunkINYTG4NGcjs.removeNodes.call(void 0, activeNodes);
178
+ _chunkUG2IFQOYcjs.removeNodes.call(void 0, activeNodes);
172
179
  activeNodes = [];
173
180
  }
174
181
  if (view == null || view === false) {
175
182
  return;
176
183
  }
177
- const root = _chunkECKYFH5Qcjs.createRootContext.call(void 0, hostRoot);
178
- const prev = _chunkECKYFH5Qcjs.pushRoot.call(void 0, root);
184
+ const root = _chunkNBDEMBBXcjs.createRootContext.call(void 0, hostRoot);
185
+ const prev = _chunkNBDEMBBXcjs.pushRoot.call(void 0, root);
179
186
  let nodes = [];
180
187
  let boundaryPushed = false;
181
188
  try {
182
189
  if (streamBoundaryId) {
183
- _chunkECKYFH5Qcjs.__fictPushSSRBoundary.call(void 0, streamBoundaryId);
190
+ _chunkNBDEMBBXcjs.__fictPushSSRBoundary.call(void 0, streamBoundaryId);
184
191
  boundaryPushed = true;
185
192
  }
186
- const output = _chunkINYTG4NGcjs.createElement.call(void 0, view);
187
- nodes = _chunkINYTG4NGcjs.toNodeArray.call(void 0, output, markerOwnerDocument);
193
+ const output = _chunkUG2IFQOYcjs.createElement.call(void 0, view);
194
+ nodes = _chunkUG2IFQOYcjs.toNodeArray.call(void 0, output, markerOwnerDocument);
188
195
  const suspendedAttempt = root.suspended || nodes.length > 0 && nodes.every((node) => node instanceof Comment && node.data === "fict:suspend");
189
196
  if (suspendedAttempt) {
190
- _chunkECKYFH5Qcjs.popRoot.call(void 0, prev);
191
- _chunkECKYFH5Qcjs.destroyRoot.call(void 0, root);
197
+ _chunkNBDEMBBXcjs.popRoot.call(void 0, prev);
198
+ _chunkNBDEMBBXcjs.destroyRoot.call(void 0, root);
192
199
  return;
193
200
  }
194
201
  const parentNode = endMarker.parentNode;
195
202
  if (parentNode) {
196
- _chunkINYTG4NGcjs.insertNodesBefore.call(void 0, parentNode, nodes, endMarker);
203
+ _chunkUG2IFQOYcjs.insertNodesBefore.call(void 0, parentNode, nodes, endMarker);
197
204
  }
198
205
  } catch (err) {
199
- _chunkECKYFH5Qcjs.popRoot.call(void 0, prev);
200
- _chunkECKYFH5Qcjs.destroyRoot.call(void 0, root);
201
- if (!_chunkECKYFH5Qcjs.handleError.call(void 0, err, { source: "render" }, hostRoot)) {
206
+ _chunkNBDEMBBXcjs.popRoot.call(void 0, prev);
207
+ _chunkNBDEMBBXcjs.destroyRoot.call(void 0, root);
208
+ if (!_chunkNBDEMBBXcjs.handleError.call(void 0, err, { source: "render" }, hostRoot)) {
202
209
  throw err;
203
210
  }
204
211
  return;
205
212
  } finally {
206
213
  if (boundaryPushed) {
207
- _chunkECKYFH5Qcjs.__fictPopSSRBoundary.call(void 0, _nullishCoalesce(streamBoundaryId, () => ( void 0)));
214
+ _chunkNBDEMBBXcjs.__fictPopSSRBoundary.call(void 0, _nullishCoalesce(streamBoundaryId, () => ( void 0)));
208
215
  }
209
216
  }
210
- _chunkECKYFH5Qcjs.popRoot.call(void 0, prev);
211
- _chunkECKYFH5Qcjs.flushOnMount.call(void 0, root);
217
+ _chunkNBDEMBBXcjs.popRoot.call(void 0, prev);
218
+ _chunkNBDEMBBXcjs.flushOnMount.call(void 0, root);
212
219
  cleanup = () => {
213
- _chunkECKYFH5Qcjs.destroyRoot.call(void 0, root);
214
- _chunkINYTG4NGcjs.removeNodes.call(void 0, nodes);
220
+ _chunkNBDEMBBXcjs.destroyRoot.call(void 0, root);
221
+ _chunkUG2IFQOYcjs.removeNodes.call(void 0, nodes);
215
222
  };
216
223
  activeNodes = nodes;
217
224
  };
@@ -237,7 +244,7 @@ function Suspense(props) {
237
244
  _optionalChain([props, 'access', _10 => _10.onResolve, 'optionalCall', _11 => _11()]);
238
245
  }
239
246
  };
240
- _chunkECKYFH5Qcjs.registerSuspenseHandler.call(void 0, (token) => {
247
+ _chunkNBDEMBBXcjs.registerSuspenseHandler.call(void 0, (token) => {
241
248
  const tokenEpoch = epoch;
242
249
  if (!streamPending && streamBoundaryId && _optionalChain([streamHooks, 'optionalAccess', _12 => _12.boundaryPending])) {
243
250
  streamPending = true;
@@ -275,7 +282,7 @@ function Suspense(props) {
275
282
  } catch (callbackError) {
276
283
  rejectionError = callbackError;
277
284
  }
278
- const handled = _chunkECKYFH5Qcjs.handleError.call(void 0, rejectionError, { source: "render" }, hostRoot);
285
+ const handled = _chunkNBDEMBBXcjs.handleError.call(void 0, rejectionError, { source: "render" }, hostRoot);
279
286
  if (!handled) {
280
287
  if (_optionalChain([streamHooks, 'optionalAccess', _16 => _16.onError])) {
281
288
  streamHooks.onError(rejectionError, _nullishCoalesce(streamBoundaryId, () => ( void 0)));
@@ -294,11 +301,17 @@ function Suspense(props) {
294
301
  return false;
295
302
  });
296
303
  renderView(_nullishCoalesce(props.children, () => ( null)));
304
+ _chunkNBDEMBBXcjs.registerRootCleanup.call(void 0, () => {
305
+ if (cleanup) {
306
+ cleanup();
307
+ cleanup = void 0;
308
+ }
309
+ });
297
310
  if (props.resetKeys !== void 0) {
298
311
  const isGetter = typeof props.resetKeys === "function" && props.resetKeys.length === 0;
299
312
  const getter = isGetter ? props.resetKeys : void 0;
300
313
  let prev = isGetter ? getter() : props.resetKeys;
301
- _chunkECKYFH5Qcjs.createEffect.call(void 0, () => {
314
+ _chunkNBDEMBBXcjs.createEffect.call(void 0, () => {
302
315
  const next = getter ? getter() : props.resetKeys;
303
316
  if (prev !== next) {
304
317
  prev = next;
@@ -340,5 +353,5 @@ function Suspense(props) {
340
353
 
341
354
 
342
355
 
343
- exports.ErrorBoundary = ErrorBoundary; exports.Fragment = _chunkINYTG4NGcjs.Fragment; exports.Suspense = Suspense; exports.batch = _chunkINYTG4NGcjs.batch; exports.createContext = _chunk6DNYVH5Ucjs.createContext; exports.createEffect = _chunkECKYFH5Qcjs.createEffect; exports.createElement = _chunkINYTG4NGcjs.createElement; exports.createMemo = _chunkECKYFH5Qcjs.createMemo; exports.createPortal = _chunkINYTG4NGcjs.createPortal; exports.createRef = createRef; exports.createRoot = _chunkECKYFH5Qcjs.createRoot; exports.createSuspenseToken = createSuspenseToken; exports.hasContext = _chunk6DNYVH5Ucjs.hasContext; exports.keyed = _chunkINYTG4NGcjs.keyed; exports.mergeProps = _chunkINYTG4NGcjs.mergeProps; exports.onCleanup = _chunkECKYFH5Qcjs.onCleanup; exports.onDestroy = _chunkECKYFH5Qcjs.onDestroy; exports.onMount = _chunkECKYFH5Qcjs.onMount; exports.prop = _chunkINYTG4NGcjs.prop; exports.render = _chunkINYTG4NGcjs.render; exports.startTransition = _chunkINYTG4NGcjs.startTransition; exports.untrack = _chunkINYTG4NGcjs.untrack; exports.useContext = _chunk6DNYVH5Ucjs.useContext; exports.useDeferredValue = _chunkINYTG4NGcjs.useDeferredValue; exports.useTransition = _chunkINYTG4NGcjs.useTransition;
356
+ exports.ErrorBoundary = ErrorBoundary; exports.Fragment = _chunkUG2IFQOYcjs.Fragment; exports.Suspense = Suspense; exports.batch = _chunkUG2IFQOYcjs.batch; exports.createContext = _chunkCKKZDUHMcjs.createContext; exports.createEffect = _chunkNBDEMBBXcjs.createEffect; exports.createElement = _chunkUG2IFQOYcjs.createElement; exports.createMemo = _chunkNBDEMBBXcjs.createMemo; exports.createPortal = _chunkUG2IFQOYcjs.createPortal; exports.createRef = createRef; exports.createRoot = _chunkNBDEMBBXcjs.createRoot; exports.createSuspenseToken = createSuspenseToken; exports.hasContext = _chunkCKKZDUHMcjs.hasContext; exports.keyed = _chunkUG2IFQOYcjs.keyed; exports.mergeProps = _chunkUG2IFQOYcjs.mergeProps; exports.onCleanup = _chunkNBDEMBBXcjs.onCleanup; exports.onDestroy = _chunkNBDEMBBXcjs.onDestroy; exports.onMount = _chunkNBDEMBBXcjs.onMount; exports.prop = _chunkUG2IFQOYcjs.prop; exports.render = _chunkUG2IFQOYcjs.render; exports.startTransition = _chunkUG2IFQOYcjs.startTransition; exports.untrack = _chunkUG2IFQOYcjs.untrack; exports.useContext = _chunkCKKZDUHMcjs.useContext; exports.useDeferredValue = _chunkUG2IFQOYcjs.useDeferredValue; exports.useTransition = _chunkUG2IFQOYcjs.useTransition;
344
357
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/fict/fict/packages/runtime/dist/index.cjs","../src/ref.ts","../src/error-boundary.ts","../src/suspense.ts"],"names":[],"mappings":"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","file":"/home/runner/work/fict/fict/packages/runtime/dist/index.cjs","sourcesContent":[null,"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 hostRoot = getCurrentRoot()\n const markerOwnerDocument = hostRoot?.ownerDocument ?? document\n const fragment = markerOwnerDocument.createDocumentFragment()\n const marker = markerOwnerDocument.createComment('fict:error-boundary')\n fragment.appendChild(marker)\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, markerOwnerDocument)\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 { __fictGetSSRStreamHooks, __fictPopSSRBoundary, __fictPushSSRBoundary } from './ssr-stream'\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 streamHooks = __fictGetSSRStreamHooks()\n const pending = createSignal(0)\n let resolvedOnce = false\n let epoch = 0\n const hostRoot = getCurrentRoot()\n const markerOwnerDocument = hostRoot?.ownerDocument ?? document\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 let boundaryPushed = false\n try {\n if (streamBoundaryId) {\n __fictPushSSRBoundary(streamBoundaryId)\n boundaryPushed = true\n }\n const output = createElement(view)\n nodes = toNodeArray(output, markerOwnerDocument)\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 = endMarker.parentNode as (ParentNode & Node) | null\n if (parentNode) {\n insertNodesBefore(parentNode, nodes, endMarker)\n }\n } catch (err) {\n popRoot(prev)\n destroyRoot(root)\n if (!handleError(err, { source: 'render' }, hostRoot)) {\n throw err\n }\n return\n } finally {\n if (boundaryPushed) {\n __fictPopSSRBoundary(streamBoundaryId ?? undefined)\n }\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 = markerOwnerDocument.createDocumentFragment()\n const startMarker = markerOwnerDocument.createComment('fict:suspense-start')\n const endMarker = markerOwnerDocument.createComment('fict:suspense-end')\n fragment.appendChild(startMarker)\n fragment.appendChild(endMarker)\n let cleanup: (() => void) | undefined\n let activeNodes: Node[] = []\n let streamBoundaryId: string | null = null\n let streamPending = false\n\n if (streamHooks?.registerBoundary) {\n streamBoundaryId = streamHooks.registerBoundary(startMarker, endMarker) ?? null\n if (streamBoundaryId) {\n startMarker.data = `fict:suspense-start:${streamBoundaryId}`\n endMarker.data = `fict:suspense-end:${streamBoundaryId}`\n }\n }\n\n const onResolveMaybe = () => {\n if (!resolvedOnce) {\n resolvedOnce = true\n props.onResolve?.()\n }\n }\n\n registerSuspenseHandler(token => {\n const tokenEpoch = epoch\n if (!streamPending && streamBoundaryId && streamHooks?.boundaryPending) {\n streamPending = true\n streamHooks.boundaryPending(streamBoundaryId)\n }\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 if (streamPending && streamBoundaryId && streamHooks?.boundaryResolved) {\n streamPending = false\n streamHooks.boundaryResolved(streamBoundaryId)\n }\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 let rejectionError = err\n try {\n props.onReject?.(err)\n } catch (callbackError) {\n rejectionError = callbackError\n }\n\n const handled = handleError(rejectionError, { source: 'render' }, hostRoot)\n if (!handled) {\n if (streamHooks?.onError) {\n streamHooks.onError(rejectionError, streamBoundaryId ?? undefined)\n return\n }\n throw rejectionError\n }\n if (\n newPending === 0 &&\n streamPending &&\n streamBoundaryId &&\n streamHooks?.boundaryResolved\n ) {\n streamPending = false\n streamHooks.boundaryResolved(streamBoundaryId)\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 if (streamPending && streamBoundaryId && streamHooks?.boundaryResolved) {\n streamPending = false\n streamHooks.boundaryResolved(streamBoundaryId)\n }\n }\n })\n }\n\n return fragment\n}\n"]}
1
+ {"version":3,"sources":["/home/runner/work/fict/fict/packages/runtime/dist/index.cjs","../src/ref.ts","../src/error-boundary.ts","../src/suspense.ts"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACA;ACvBO,SAAS,SAAA,CAAA,EAA2D;AACzE,EAAA,OAAO,EAAE,OAAA,EAAS,KAAK,CAAA;AACzB;ADyBA;AACA;AE7BO,SAAS,aAAA,CAAc,KAAA,EAAqC;AACjE,EAAA,MAAM,SAAA,EAAW,8CAAA,CAAe;AAChC,EAAA,MAAM,oBAAA,mCAAsB,QAAA,2BAAU,eAAA,UAAiB,UAAA;AACvD,EAAA,MAAM,SAAA,EAAW,mBAAA,CAAoB,sBAAA,CAAuB,CAAA;AAC5D,EAAA,MAAM,OAAA,EAAS,mBAAA,CAAoB,aAAA,CAAc,qBAAqB,CAAA;AACtE,EAAA,QAAA,CAAS,WAAA,CAAY,MAAM,CAAA;AAE3B,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI,YAAA,EAAsB,CAAC,CAAA;AAC3B,EAAA,IAAI,kBAAA,EAAoB,KAAA;AAExB,EAAA,IAAI,MAAA,EAAQ,CAAA,EAAA,GAAM;AAAA,EAAC,CAAA;AACnB,EAAA,MAAM,OAAA,EAAS,CAAC,GAAA,EAAA,GAAyC;AACvD,IAAA,GAAA,CAAI,IAAA,GAAO,IAAA,EAAM;AACf,MAAA,OAAO,OAAO,KAAA,CAAM,SAAA,IAAa,WAAA,EAC5B,KAAA,CAAM,QAAA,CAA0D,GAAA,EAAK,KAAK,EAAA,EAC3E,KAAA,CAAM,QAAA;AAAA,IACZ;AACA,IAAA,wBAAO,KAAA,CAAM,QAAA,UAAY,MAAA;AAAA,EAC3B,CAAA;AAEA,EAAA,MAAM,YAAA,EAAc,CAAC,KAAA,EAAA,GAA2B;AAC9C,IAAA,GAAA,CAAI,OAAA,EAAS;AACX,MAAA,OAAA,CAAQ,CAAA;AACR,MAAA,QAAA,EAAU,KAAA,CAAA;AAAA,IACZ;AACA,IAAA,GAAA,CAAI,WAAA,CAAY,MAAA,EAAQ;AACtB,MAAA,2CAAA,WAAuB,CAAA;AACvB,MAAA,YAAA,EAAc,CAAC,CAAA;AAAA,IACjB;AAEA,IAAA,GAAA,CAAI,MAAA,GAAS,KAAA,GAAQ,MAAA,IAAU,KAAA,EAAO;AACpC,MAAA,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,KAAA,EAAO,iDAAA,QAA0B,CAAA;AACvC,IAAA,MAAM,KAAA,EAAO,wCAAA,IAAa,CAAA;AAC1B,IAAA,IAAI,MAAA,EAAgB,CAAC,CAAA;AACrB,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,EAAS,6CAAA,KAAmB,CAAA;AAClC,MAAA,MAAA,EAAQ,2CAAA,MAAY,EAAQ,mBAAmB,CAAA;AAC/C,MAAA,MAAM,WAAA,EAAa,MAAA,CAAO,UAAA;AAC1B,MAAA,GAAA,CAAI,UAAA,EAAY;AACd,QAAA,iDAAA,UAAkB,EAAY,KAAA,EAAO,MAAM,CAAA;AAAA,MAC7C;AAAA,IACF,EAAA,MAAA,CAAS,GAAA,EAAK;AACZ,MAAA,uCAAA,IAAY,CAAA;AACZ,MAAA,2CAAA,IAAgB,CAAA;AAEhB,MAAA,GAAA,CAAI,iBAAA,EAAmB;AACrB,QAAA,MAAM,GAAA;AAAA,MACR;AAGA,MAAA,kBAAA,EAAoB,IAAA;AACpB,MAAA,IAAI;AACF,QAAA,WAAA,CAAY,MAAA,CAAO,GAAG,CAAC,CAAA;AAGvB,QAAA,kBAAA,EAAoB,KAAA;AACpB,wBAAA,KAAA,qBAAM,OAAA,0BAAA,CAAU,GAAG,GAAA;AAAA,MACrB,EAAA,MAAA,CAAS,WAAA,EAAa;AAIpB,wBAAA,KAAA,qBAAM,OAAA,0BAAA,CAAU,GAAG,GAAA;AACnB,QAAA,MAAM,WAAA;AAAA,MACR;AACA,MAAA,MAAA;AAAA,IACF;AACA,IAAA,uCAAA,IAAY,CAAA;AACZ,IAAA,4CAAA,IAAiB,CAAA;AAEjB,IAAA,QAAA,EAAU,CAAA,EAAA,GAAM;AACd,MAAA,2CAAA,IAAgB,CAAA;AAChB,MAAA,2CAAA,KAAiB,CAAA;AAAA,IACnB,CAAA;AACA,IAAA,YAAA,EAAc,KAAA;AAAA,EAChB,CAAA;AAEA,EAAA,MAAA,EAAQ,CAAA,EAAA,GAAM;AACZ,IAAA,kBAAA,EAAoB,KAAA;AACpB,IAAA,WAAA,CAAY,MAAA,CAAO,IAAI,CAAC,CAAA;AAAA,EAC1B,CAAA;AAEA,EAAA,WAAA,kBAAY,KAAA,CAAM,QAAA,UAAY,MAAI,CAAA;AAElC,EAAA,mDAAA,CAAoB,EAAA,GAAM;AACxB,IAAA,GAAA,CAAI,OAAA,EAAS;AACX,MAAA,OAAA,CAAQ,CAAA;AACR,MAAA,QAAA,EAAU,KAAA,CAAA;AAAA,IACZ;AAAA,EACF,CAAC,CAAA;AAED,EAAA,oDAAA,CAAqB,GAAA,EAAA,GAAO;AAC1B,IAAA,WAAA,CAAY,MAAA,CAAO,GAAG,CAAC,CAAA;AACvB,oBAAA,KAAA,qBAAM,OAAA,0BAAA,CAAU,GAAG,GAAA;AACnB,IAAA,OAAO,IAAA;AAAA,EACT,CAAC,CAAA;AAED,EAAA,GAAA,CAAI,KAAA,CAAM,UAAA,IAAc,KAAA,CAAA,EAAW;AACjC,IAAA,MAAM,SAAA,EACJ,OAAO,KAAA,CAAM,UAAA,IAAc,WAAA,GAAe,KAAA,CAAM,SAAA,CAA4B,OAAA,IAAW,CAAA;AACzF,IAAA,MAAM,OAAA,EAAS,SAAA,EAAY,KAAA,CAAM,UAAA,EAA8B,KAAA,CAAA;AAC/D,IAAA,IAAI,KAAA,EAAO,SAAA,EAAW,MAAA,CAAQ,EAAA,EAAI,KAAA,CAAM,SAAA;AACxC,IAAA,4CAAA,CAAa,EAAA,GAAM;AACjB,MAAA,MAAM,KAAA,EAAO,OAAA,EAAS,MAAA,CAAO,EAAA,EAAI,KAAA,CAAM,SAAA;AACvC,MAAA,GAAA,CAAI,KAAA,IAAS,IAAA,EAAM;AACjB,QAAA,KAAA,EAAO,IAAA;AACP,QAAA,WAAA,CAAY,MAAA,CAAO,IAAI,CAAC,CAAA;AAAA,MAC1B;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,QAAA;AACT;AFSA;AACA;AGnHO,SAAS,mBAAA,CAAA,EAAsC;AACpD,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI,MAAA;AACJ,EAAA,MAAM,QAAA,EAAU,IAAI,OAAA,CAAc,CAAC,GAAA,EAAK,GAAA,EAAA,GAAQ;AAC9C,IAAA,QAAA,EAAU,GAAA;AACV,IAAA,OAAA,EAAS,GAAA;AAAA,EACX,CAAC,CAAA;AACD,EAAA,OAAO;AAAA,IACL,KAAA,EAAO;AAAA,MACL,IAAA,EAAM,OAAA,CAAQ,IAAA,CAAK,IAAA,CAAK,OAAO;AAAA,IACjC,CAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,EACF,CAAA;AACF;AAEA,IAAM,WAAA,EAAa,CAAC,KAAA,EAAA,GAClB,OAAO,MAAA,IAAU,SAAA,GACjB,MAAA,IAAU,KAAA,GACV,OAAQ,KAAA,CAA+B,KAAA,IAAS,UAAA;AAE3C,SAAS,QAAA,CAAS,KAAA,EAAgC;AACvD,EAAA,MAAM,YAAA,EAAc,uDAAA,CAAwB;AAC5C,EAAA,MAAM,QAAA,EAAU,sCAAA,CAAc,CAAA;AAC9B,EAAA,IAAI,aAAA,EAAe,KAAA;AACnB,EAAA,IAAI,MAAA,EAAQ,CAAA;AACZ,EAAA,MAAM,SAAA,EAAW,8CAAA,CAAe;AAChC,EAAA,MAAM,oBAAA,mCAAsB,QAAA,6BAAU,eAAA,UAAiB,UAAA;AAEvD,EAAA,MAAM,WAAA,EAAa,CAAC,GAAA,EAAA,GAClB,OAAO,KAAA,CAAM,SAAA,IAAa,WAAA,EACrB,KAAA,CAAM,QAAA,CAAuC,GAAG,EAAA,EACjD,KAAA,CAAM,QAAA;AAEZ,EAAA,MAAM,WAAA,EAAa,CAAC,IAAA,EAAA,GAA0B;AAC5C,IAAA,GAAA,CAAI,OAAA,EAAS;AACX,MAAA,OAAA,CAAQ,CAAA;AACR,MAAA,QAAA,EAAU,KAAA,CAAA;AAAA,IACZ;AACA,IAAA,GAAA,CAAI,WAAA,CAAY,MAAA,EAAQ;AACtB,MAAA,2CAAA,WAAuB,CAAA;AACvB,MAAA,YAAA,EAAc,CAAC,CAAA;AAAA,IACjB;AAEA,IAAA,GAAA,CAAI,KAAA,GAAQ,KAAA,GAAQ,KAAA,IAAS,KAAA,EAAO;AAClC,MAAA,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,KAAA,EAAO,iDAAA,QAA0B,CAAA;AACvC,IAAA,MAAM,KAAA,EAAO,wCAAA,IAAa,CAAA;AAC1B,IAAA,IAAI,MAAA,EAAgB,CAAC,CAAA;AACrB,IAAA,IAAI,eAAA,EAAiB,KAAA;AACrB,IAAA,IAAI;AACF,MAAA,GAAA,CAAI,gBAAA,EAAkB;AACpB,QAAA,qDAAA,gBAAsC,CAAA;AACtC,QAAA,eAAA,EAAiB,IAAA;AAAA,MACnB;AACA,MAAA,MAAM,OAAA,EAAS,6CAAA,IAAkB,CAAA;AACjC,MAAA,MAAA,EAAQ,2CAAA,MAAY,EAAQ,mBAAmB,CAAA;AAG/C,MAAA,MAAM,iBAAA,EACJ,IAAA,CAAK,UAAA,GACJ,KAAA,CAAM,OAAA,EAAS,EAAA,GACd,KAAA,CAAM,KAAA,CAAM,CAAA,IAAA,EAAA,GAAQ,KAAA,WAAgB,QAAA,GAAY,IAAA,CAAiB,KAAA,IAAS,cAAc,CAAA;AAC5F,MAAA,GAAA,CAAI,gBAAA,EAAkB;AACpB,QAAA,uCAAA,IAAY,CAAA;AACZ,QAAA,2CAAA,IAAgB,CAAA;AAChB,QAAA,MAAA;AAAA,MACF;AACA,MAAA,MAAM,WAAA,EAAa,SAAA,CAAU,UAAA;AAC7B,MAAA,GAAA,CAAI,UAAA,EAAY;AACd,QAAA,iDAAA,UAAkB,EAAY,KAAA,EAAO,SAAS,CAAA;AAAA,MAChD;AAAA,IACF,EAAA,MAAA,CAAS,GAAA,EAAK;AACZ,MAAA,uCAAA,IAAY,CAAA;AACZ,MAAA,2CAAA,IAAgB,CAAA;AAChB,MAAA,GAAA,CAAI,CAAC,2CAAA,GAAY,EAAK,EAAE,MAAA,EAAQ,SAAS,CAAA,EAAG,QAAQ,CAAA,EAAG;AACrD,QAAA,MAAM,GAAA;AAAA,MACR;AACA,MAAA,MAAA;AAAA,IACF,EAAA,QAAE;AACA,MAAA,GAAA,CAAI,cAAA,EAAgB;AAClB,QAAA,oDAAA,iBAAqB,gBAAA,UAAoB,KAAA,GAAS,CAAA;AAAA,MACpD;AAAA,IACF;AACA,IAAA,uCAAA,IAAY,CAAA;AACZ,IAAA,4CAAA,IAAiB,CAAA;AAEjB,IAAA,QAAA,EAAU,CAAA,EAAA,GAAM;AACd,MAAA,2CAAA,IAAgB,CAAA;AAChB,MAAA,2CAAA,KAAiB,CAAA;AAAA,IACnB,CAAA;AACA,IAAA,YAAA,EAAc,KAAA;AAAA,EAChB,CAAA;AAEA,EAAA,MAAM,SAAA,EAAW,mBAAA,CAAoB,sBAAA,CAAuB,CAAA;AAC5D,EAAA,MAAM,YAAA,EAAc,mBAAA,CAAoB,aAAA,CAAc,qBAAqB,CAAA;AAC3E,EAAA,MAAM,UAAA,EAAY,mBAAA,CAAoB,aAAA,CAAc,mBAAmB,CAAA;AACvE,EAAA,QAAA,CAAS,WAAA,CAAY,WAAW,CAAA;AAChC,EAAA,QAAA,CAAS,WAAA,CAAY,SAAS,CAAA;AAC9B,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI,YAAA,EAAsB,CAAC,CAAA;AAC3B,EAAA,IAAI,iBAAA,EAAkC,IAAA;AACtC,EAAA,IAAI,cAAA,EAAgB,KAAA;AAEpB,EAAA,GAAA,iBAAI,WAAA,6BAAa,kBAAA,EAAkB;AACjC,IAAA,iBAAA,mBAAmB,WAAA,CAAY,gBAAA,CAAiB,WAAA,EAAa,SAAS,CAAA,UAAK,MAAA;AAC3E,IAAA,GAAA,CAAI,gBAAA,EAAkB;AACpB,MAAA,WAAA,CAAY,KAAA,EAAO,CAAA,oBAAA,EAAuB,gBAAgB,CAAA,CAAA;AACJ,MAAA;AACxD,IAAA;AACF,EAAA;AAE6B,EAAA;AACR,IAAA;AACF,MAAA;AACG,sBAAA;AACpB,IAAA;AACF,EAAA;AAEiC,EAAA;AACZ,IAAA;AACoC,IAAA;AACrC,MAAA;AAC4B,MAAA;AAC9C,IAAA;AACqB,IAAA;AAGE,IAAA;AAKjB,IAAA;AAGQ,IAAA;AACH,MAAA;AACD,QAAA;AAGsB,UAAA;AAExB,YAAA;AACF,UAAA;AAI4C,UAAA;AAC1B,UAAA;AACI,UAAA;AAEa,YAAA;AACQ,YAAA;AACvB,cAAA;AAC6B,cAAA;AAC/C,YAAA;AACe,YAAA;AACjB,UAAA;AACF,QAAA;AACO,QAAA;AAEqB,UAAA;AACxB,YAAA;AACF,UAAA;AAC4C,UAAA;AAC1B,UAAA;AACG,UAAA;AACjB,UAAA;AACkB,4BAAA;AACE,UAAA;AACL,YAAA;AACnB,UAAA;AAEsD,UAAA;AACxC,UAAA;AACc,YAAA;AACY,cAAA;AACpC,cAAA;AACF,YAAA;AACM,YAAA;AACR,UAAA;AAIE,UAAA;AAGgB,YAAA;AAC6B,YAAA;AAC/C,UAAA;AACF,QAAA;AACF,MAAA;AACO,MAAA;AACT,IAAA;AAEO,IAAA;AACR,EAAA;AAKgC,EAAA;AAEP,EAAA;AACX,IAAA;AACH,MAAA;AACE,MAAA;AACZ,IAAA;AACD,EAAA;AAEkC,EAAA;AAEW,IAAA;AACmB,IAAA;AACvB,IAAA;AACrB,IAAA;AACsB,MAAA;AACpB,MAAA;AACV,QAAA;AACP,QAAA;AACS,QAAA;AAEwB,QAAA;AACqB,QAAA;AACpC,UAAA;AAC6B,UAAA;AAC/C,QAAA;AACF,MAAA;AACD,IAAA;AACH,EAAA;AAEO,EAAA;AACT;AH+DiE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/work/fict/fict/packages/runtime/dist/index.cjs","sourcesContent":[null,"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 registerRootCleanup,\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 hostRoot = getCurrentRoot()\n const markerOwnerDocument = hostRoot?.ownerDocument ?? document\n const fragment = markerOwnerDocument.createDocumentFragment()\n const marker = markerOwnerDocument.createComment('fict:error-boundary')\n fragment.appendChild(marker)\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, markerOwnerDocument)\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 registerRootCleanup(() => {\n if (cleanup) {\n cleanup()\n cleanup = undefined\n }\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 registerRootCleanup,\n registerSuspenseHandler,\n} from './lifecycle'\nimport { insertNodesBefore, removeNodes, toNodeArray } from './node-ops'\nimport { createSignal } from './signal'\nimport { __fictGetSSRStreamHooks, __fictPopSSRBoundary, __fictPushSSRBoundary } from './ssr-stream'\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 streamHooks = __fictGetSSRStreamHooks()\n const pending = createSignal(0)\n let resolvedOnce = false\n let epoch = 0\n const hostRoot = getCurrentRoot()\n const markerOwnerDocument = hostRoot?.ownerDocument ?? document\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 let boundaryPushed = false\n try {\n if (streamBoundaryId) {\n __fictPushSSRBoundary(streamBoundaryId)\n boundaryPushed = true\n }\n const output = createElement(view)\n nodes = toNodeArray(output, markerOwnerDocument)\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 = endMarker.parentNode as (ParentNode & Node) | null\n if (parentNode) {\n insertNodesBefore(parentNode, nodes, endMarker)\n }\n } catch (err) {\n popRoot(prev)\n destroyRoot(root)\n if (!handleError(err, { source: 'render' }, hostRoot)) {\n throw err\n }\n return\n } finally {\n if (boundaryPushed) {\n __fictPopSSRBoundary(streamBoundaryId ?? undefined)\n }\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 = markerOwnerDocument.createDocumentFragment()\n const startMarker = markerOwnerDocument.createComment('fict:suspense-start')\n const endMarker = markerOwnerDocument.createComment('fict:suspense-end')\n fragment.appendChild(startMarker)\n fragment.appendChild(endMarker)\n let cleanup: (() => void) | undefined\n let activeNodes: Node[] = []\n let streamBoundaryId: string | null = null\n let streamPending = false\n\n if (streamHooks?.registerBoundary) {\n streamBoundaryId = streamHooks.registerBoundary(startMarker, endMarker) ?? null\n if (streamBoundaryId) {\n startMarker.data = `fict:suspense-start:${streamBoundaryId}`\n endMarker.data = `fict:suspense-end:${streamBoundaryId}`\n }\n }\n\n const onResolveMaybe = () => {\n if (!resolvedOnce) {\n resolvedOnce = true\n props.onResolve?.()\n }\n }\n\n registerSuspenseHandler(token => {\n const tokenEpoch = epoch\n if (!streamPending && streamBoundaryId && streamHooks?.boundaryPending) {\n streamPending = true\n streamHooks.boundaryPending(streamBoundaryId)\n }\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 if (streamPending && streamBoundaryId && streamHooks?.boundaryResolved) {\n streamPending = false\n streamHooks.boundaryResolved(streamBoundaryId)\n }\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 let rejectionError = err\n try {\n props.onReject?.(err)\n } catch (callbackError) {\n rejectionError = callbackError\n }\n\n const handled = handleError(rejectionError, { source: 'render' }, hostRoot)\n if (!handled) {\n if (streamHooks?.onError) {\n streamHooks.onError(rejectionError, streamBoundaryId ?? undefined)\n return\n }\n throw rejectionError\n }\n if (\n newPending === 0 &&\n streamPending &&\n streamBoundaryId &&\n streamHooks?.boundaryResolved\n ) {\n streamPending = false\n streamHooks.boundaryResolved(streamBoundaryId)\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 registerRootCleanup(() => {\n if (cleanup) {\n cleanup()\n cleanup = undefined\n }\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 // Directly render children instead of using switchView\n renderView(props.children ?? null)\n if (streamPending && streamBoundaryId && streamHooks?.boundaryResolved) {\n streamPending = false\n streamHooks.boundaryResolved(streamBoundaryId)\n }\n }\n })\n }\n\n return fragment\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
- export { F as Fragment, J as JSX, M as Memo, d as createElement, c as createMemo, k as keyed, m as mergeProps, p as prop, r as render } from './props-CdmuXCiu.cjs';
2
- import { S as RefObject, B as BaseProps, F as FictNode, T as SuspenseToken } from './binding-BlABuUiG.cjs';
3
- export { a3 as ClassProp, Z as Cleanup, _ as Component, R as DOMElement, U as Effect, a5 as ErrorInfo, a4 as EventHandler, Y as FictVNode, $ as PropsWithChildren, a0 as Ref, a1 as RefCallback, a2 as StyleProp, j as createEffect, E as createPortal, X as createRoot, W as onCleanup, N as onDestroy, V as onMount } from './binding-BlABuUiG.cjs';
4
- export { C as Context, F as FictDevtoolsHook, P as ProviderProps, c as createContext, h as hasContext, u as useContext } from './devtools-DWIZRe7L.cjs';
1
+ export { F as Fragment, J as JSX, M as Memo, d as createElement, c as createMemo, k as keyed, m as mergeProps, p as prop, r as render } from './props-D4tK8Gn0.cjs';
2
+ import { S as RefObject, B as BaseProps, F as FictNode, T as SuspenseToken } from './binding-CDR2ERoq.cjs';
3
+ export { a3 as ClassProp, Z as Cleanup, _ as Component, R as DOMElement, U as Effect, a5 as ErrorInfo, a4 as EventHandler, Y as FictVNode, $ as PropsWithChildren, a0 as Ref, a1 as RefCallback, a2 as StyleProp, j as createEffect, E as createPortal, X as createRoot, W as onCleanup, N as onDestroy, V as onMount } from './binding-CDR2ERoq.cjs';
4
+ export { C as Context, F as FictDevtoolsHook, P as ProviderProps, c as createContext, h as hasContext, u as useContext } from './devtools-BwkkQ6DN.cjs';
5
5
  import './signal-Z4KkDk9h.cjs';
6
6
 
7
7
  /**
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- export { F as Fragment, J as JSX, M as Memo, d as createElement, c as createMemo, k as keyed, m as mergeProps, p as prop, r as render } from './props-C04ScJgm.js';
2
- import { S as RefObject, B as BaseProps, F as FictNode, T as SuspenseToken } from './binding-CQUGLLBI.js';
3
- export { a3 as ClassProp, Z as Cleanup, _ as Component, R as DOMElement, U as Effect, a5 as ErrorInfo, a4 as EventHandler, Y as FictVNode, $ as PropsWithChildren, a0 as Ref, a1 as RefCallback, a2 as StyleProp, j as createEffect, E as createPortal, X as createRoot, W as onCleanup, N as onDestroy, V as onMount } from './binding-CQUGLLBI.js';
4
- export { C as Context, F as FictDevtoolsHook, P as ProviderProps, c as createContext, h as hasContext, u as useContext } from './devtools-DNnnDGu1.js';
1
+ export { F as Fragment, J as JSX, M as Memo, d as createElement, c as createMemo, k as keyed, m as mergeProps, p as prop, r as render } from './props-CFoQ471Y.js';
2
+ import { S as RefObject, B as BaseProps, F as FictNode, T as SuspenseToken } from './binding-BfzY9rae.js';
3
+ export { a3 as ClassProp, Z as Cleanup, _ as Component, R as DOMElement, U as Effect, a5 as ErrorInfo, a4 as EventHandler, Y as FictVNode, $ as PropsWithChildren, a0 as Ref, a1 as RefCallback, a2 as StyleProp, j as createEffect, E as createPortal, X as createRoot, W as onCleanup, N as onDestroy, V as onMount } from './binding-BfzY9rae.js';
4
+ export { C as Context, F as FictDevtoolsHook, P as ProviderProps, c as createContext, h as hasContext, u as useContext } from './devtools-CK3SVU_w.js';
5
5
  import './signal-Z4KkDk9h.js';
6
6
 
7
7
  /**