@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
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/scope.ts"],"sourcesContent":["import { isReactive, type MaybeReactive } from './binding'\nimport { createEffect } from './effect'\nimport { createRoot, onCleanup, registerRootCleanup } from './lifecycle'\n\nexport { effectScope } from './signal'\n\nexport interface ReactiveScope {\n run<T>(fn: () => T): T\n stop(): void\n}\n\n/**\n * Create an explicit reactive scope that can contain effects/memos and be stopped manually.\n * The scope registers with the current root for cleanup.\n */\nexport function createScope(): ReactiveScope {\n let dispose: (() => void) | null = null\n\n const stop = () => {\n if (dispose) {\n dispose()\n dispose = null\n }\n }\n\n const run = <T>(fn: () => T): T => {\n stop()\n const { dispose: rootDispose, value } = createRoot(fn, { inherit: true })\n dispose = rootDispose\n return value\n }\n\n registerRootCleanup(stop)\n return { run, stop }\n}\n\n/**\n * Run a block of reactive code inside a managed scope that follows a boolean flag.\n * When the flag turns false, the scope is disposed and all contained effects/memos are cleaned up.\n */\nexport function runInScope(flag: MaybeReactive<boolean>, fn: () => void): void {\n const scope = createScope()\n const evaluate = () => (isReactive(flag) ? (flag as () => boolean)() : !!flag)\n\n createEffect(() => {\n const enabled = evaluate()\n if (enabled) {\n scope.run(fn)\n } else {\n scope.stop()\n }\n })\n\n onCleanup(scope.stop)\n}\n"],"mappings":";;;;;;;;;AAeO,SAAS,cAA6B;AAC3C,MAAI,UAA+B;AAEnC,QAAM,OAAO,MAAM;AACjB,QAAI,SAAS;AACX,cAAQ;AACR,gBAAU;AAAA,IACZ;AAAA,EACF;AAEA,QAAM,MAAM,CAAI,OAAmB;AACjC,SAAK;AACL,UAAM,EAAE,SAAS,aAAa,MAAM,IAAI,WAAW,IAAI,EAAE,SAAS,KAAK,CAAC;AACxE,cAAU;AACV,WAAO;AAAA,EACT;AAEA,sBAAoB,IAAI;AACxB,SAAO,EAAE,KAAK,KAAK;AACrB;AAMO,SAAS,WAAW,MAA8B,IAAsB;AAC7E,QAAM,QAAQ,YAAY;AAC1B,QAAM,WAAW,MAAO,WAAW,IAAI,IAAK,KAAuB,IAAI,CAAC,CAAC;AAEzE,eAAa,MAAM;AACjB,UAAM,UAAU,SAAS;AACzB,QAAI,SAAS;AACX,YAAM,IAAI,EAAE;AAAA,IACd,OAAO;AACL,YAAM,KAAK;AAAA,IACb;AAAA,EACF,CAAC;AAED,YAAU,MAAM,IAAI;AACtB;","names":[]}
@@ -1,4 +1,4 @@
1
- import { B as BaseProps, F as FictNode } from './effect-Auji1rz9.js';
1
+ import { B as BaseProps, F as FictNode } from './effect-ClARNUCc.js';
2
2
 
3
3
  /**
4
4
  * @fileoverview Context API for Fict
@@ -1,4 +1,4 @@
1
- import { B as BaseProps, F as FictNode } from './effect-Auji1rz9.cjs';
1
+ import { B as BaseProps, F as FictNode } from './effect-ClARNUCc.cjs';
2
2
 
3
3
  /**
4
4
  * @fileoverview Context API for Fict
@@ -88,8 +88,29 @@ interface BindingHandle {
88
88
  }
89
89
  /** Managed child node with its dispose function */
90
90
  /**
91
- * Check if a value is reactive (a getter function)
92
- * Note: Event handlers (functions that take arguments) are NOT reactive values
91
+ * Check if a value is reactive (a getter function that returns a value).
92
+ *
93
+ * A value is considered reactive if:
94
+ * 1. It's a signal or computed value created by the runtime (marked with Symbol)
95
+ * 2. It's a zero-argument function (getter pattern used by the compiler)
96
+ *
97
+ * NOT considered reactive:
98
+ * - Event handlers (functions that take arguments)
99
+ * - Effect disposers (zero-arg but for cleanup, not value access)
100
+ * - Effect scopes (zero-arg but for scope management)
101
+ *
102
+ * @param value - The value to check
103
+ * @returns true if the value is a reactive getter
104
+ *
105
+ * @example
106
+ * ```ts
107
+ * const [count, setCount] = createSignal(0)
108
+ * isReactive(count) // true - signal accessor
109
+ * isReactive(() => 42) // true - getter pattern
110
+ * isReactive((x) => x) // false - takes argument
111
+ * isReactive('hello') // false - not a function
112
+ * isReactive(effectDisposer) // false - effect cleanup function
113
+ * ```
93
114
  */
94
115
  declare function isReactive(value: unknown): value is () => unknown;
95
116
  /**
@@ -88,8 +88,29 @@ interface BindingHandle {
88
88
  }
89
89
  /** Managed child node with its dispose function */
90
90
  /**
91
- * Check if a value is reactive (a getter function)
92
- * Note: Event handlers (functions that take arguments) are NOT reactive values
91
+ * Check if a value is reactive (a getter function that returns a value).
92
+ *
93
+ * A value is considered reactive if:
94
+ * 1. It's a signal or computed value created by the runtime (marked with Symbol)
95
+ * 2. It's a zero-argument function (getter pattern used by the compiler)
96
+ *
97
+ * NOT considered reactive:
98
+ * - Event handlers (functions that take arguments)
99
+ * - Effect disposers (zero-arg but for cleanup, not value access)
100
+ * - Effect scopes (zero-arg but for scope management)
101
+ *
102
+ * @param value - The value to check
103
+ * @returns true if the value is a reactive getter
104
+ *
105
+ * @example
106
+ * ```ts
107
+ * const [count, setCount] = createSignal(0)
108
+ * isReactive(count) // true - signal accessor
109
+ * isReactive(() => 42) // true - getter pattern
110
+ * isReactive((x) => x) // false - takes argument
111
+ * isReactive('hello') // false - not a function
112
+ * isReactive(effectDisposer) // false - effect cleanup function
113
+ * ```
93
114
  */
94
115
  declare function isReactive(value: unknown): value is () => unknown;
95
116
  /**
package/dist/index.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
 
4
4
 
5
- var _chunkGJTYOFMOcjs = require('./chunk-GJTYOFMO.cjs');
5
+ var _chunk527QSKFMcjs = require('./chunk-527QSKFM.cjs');
6
6
 
7
7
 
8
8
 
@@ -34,7 +34,7 @@ var _chunkGJTYOFMOcjs = require('./chunk-GJTYOFMO.cjs');
34
34
 
35
35
 
36
36
 
37
- var _chunkPMF6MWEVcjs = require('./chunk-PMF6MWEV.cjs');
37
+ var _chunkJ74L7UYPcjs = require('./chunk-J74L7UYP.cjs');
38
38
 
39
39
  // src/ref.ts
40
40
  function createRef() {
@@ -46,8 +46,8 @@ function ErrorBoundary(props) {
46
46
  const fragment = document.createDocumentFragment();
47
47
  const marker = document.createComment("fict:error-boundary");
48
48
  fragment.appendChild(marker);
49
- const currentView = _chunkPMF6MWEVcjs.signal.call(void 0, _nullishCoalesce(props.children, () => ( null)));
50
- const hostRoot = _chunkPMF6MWEVcjs.getCurrentRoot.call(void 0, );
49
+ const currentView = _chunkJ74L7UYPcjs.signal.call(void 0, _nullishCoalesce(props.children, () => ( null)));
50
+ const hostRoot = _chunkJ74L7UYPcjs.getCurrentRoot.call(void 0, );
51
51
  let cleanup;
52
52
  let activeNodes = [];
53
53
  let renderingFallback = false;
@@ -63,26 +63,26 @@ function ErrorBoundary(props) {
63
63
  cleanup = void 0;
64
64
  }
65
65
  if (activeNodes.length) {
66
- _chunkPMF6MWEVcjs.removeNodes.call(void 0, activeNodes);
66
+ _chunkJ74L7UYPcjs.removeNodes.call(void 0, activeNodes);
67
67
  activeNodes = [];
68
68
  }
69
69
  if (value == null || value === false) {
70
70
  return;
71
71
  }
72
- const root = _chunkPMF6MWEVcjs.createRootContext.call(void 0, hostRoot);
73
- const prev = _chunkPMF6MWEVcjs.pushRoot.call(void 0, root);
72
+ const root = _chunkJ74L7UYPcjs.createRootContext.call(void 0, hostRoot);
73
+ const prev = _chunkJ74L7UYPcjs.pushRoot.call(void 0, root);
74
74
  let nodes = [];
75
75
  try {
76
- const output = _chunkPMF6MWEVcjs.createElement.call(void 0, value);
77
- nodes = _chunkPMF6MWEVcjs.toNodeArray.call(void 0, output);
76
+ const output = _chunkJ74L7UYPcjs.createElement.call(void 0, value);
77
+ nodes = _chunkJ74L7UYPcjs.toNodeArray.call(void 0, output);
78
78
  const parentNode = marker.parentNode;
79
79
  if (parentNode) {
80
- _chunkPMF6MWEVcjs.insertNodesBefore.call(void 0, parentNode, nodes, marker);
80
+ _chunkJ74L7UYPcjs.insertNodesBefore.call(void 0, parentNode, nodes, marker);
81
81
  }
82
82
  } catch (err) {
83
- _chunkPMF6MWEVcjs.popRoot.call(void 0, prev);
84
- _chunkPMF6MWEVcjs.flushOnMount.call(void 0, root);
85
- _chunkPMF6MWEVcjs.destroyRoot.call(void 0, root);
83
+ _chunkJ74L7UYPcjs.popRoot.call(void 0, prev);
84
+ _chunkJ74L7UYPcjs.flushOnMount.call(void 0, root);
85
+ _chunkJ74L7UYPcjs.destroyRoot.call(void 0, root);
86
86
  if (renderingFallback) {
87
87
  throw err;
88
88
  }
@@ -97,19 +97,19 @@ function ErrorBoundary(props) {
97
97
  }
98
98
  return;
99
99
  }
100
- _chunkPMF6MWEVcjs.popRoot.call(void 0, prev);
101
- _chunkPMF6MWEVcjs.flushOnMount.call(void 0, root);
100
+ _chunkJ74L7UYPcjs.popRoot.call(void 0, prev);
101
+ _chunkJ74L7UYPcjs.flushOnMount.call(void 0, root);
102
102
  cleanup = () => {
103
- _chunkPMF6MWEVcjs.destroyRoot.call(void 0, root);
104
- _chunkPMF6MWEVcjs.removeNodes.call(void 0, nodes);
103
+ _chunkJ74L7UYPcjs.destroyRoot.call(void 0, root);
104
+ _chunkJ74L7UYPcjs.removeNodes.call(void 0, nodes);
105
105
  };
106
106
  activeNodes = nodes;
107
107
  };
108
- _chunkPMF6MWEVcjs.createEffect.call(void 0, () => {
108
+ _chunkJ74L7UYPcjs.createEffect.call(void 0, () => {
109
109
  const value = currentView();
110
110
  renderValue(value);
111
111
  });
112
- _chunkPMF6MWEVcjs.registerErrorHandler.call(void 0, (err) => {
112
+ _chunkJ74L7UYPcjs.registerErrorHandler.call(void 0, (err) => {
113
113
  renderValue(toView(err));
114
114
  _optionalChain([props, 'access', _5 => _5.onError, 'optionalCall', _6 => _6(err)]);
115
115
  return true;
@@ -118,7 +118,7 @@ function ErrorBoundary(props) {
118
118
  const isGetter = typeof props.resetKeys === "function" && props.resetKeys.length === 0;
119
119
  const getter = isGetter ? props.resetKeys : void 0;
120
120
  let prev = isGetter ? getter() : props.resetKeys;
121
- _chunkPMF6MWEVcjs.createEffect.call(void 0, () => {
121
+ _chunkJ74L7UYPcjs.createEffect.call(void 0, () => {
122
122
  const next = getter ? getter() : props.resetKeys;
123
123
  if (prev !== next) {
124
124
  prev = next;
@@ -147,58 +147,54 @@ function createSuspenseToken() {
147
147
  }
148
148
  var isThenable = (value) => typeof value === "object" && value !== null && typeof value.then === "function";
149
149
  function Suspense(props) {
150
- const currentView = _chunkPMF6MWEVcjs.signal.call(void 0, _nullishCoalesce(props.children, () => ( null)));
151
- const pending = _chunkPMF6MWEVcjs.signal.call(void 0, 0);
150
+ const currentView = _chunkJ74L7UYPcjs.signal.call(void 0, _nullishCoalesce(props.children, () => ( null)));
151
+ const pending = _chunkJ74L7UYPcjs.signal.call(void 0, 0);
152
152
  let resolvedOnce = false;
153
153
  let epoch = 0;
154
- const hostRoot = _chunkPMF6MWEVcjs.getCurrentRoot.call(void 0, );
154
+ const hostRoot = _chunkJ74L7UYPcjs.getCurrentRoot.call(void 0, );
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();
163
159
  cleanup = void 0;
164
160
  }
165
161
  if (activeNodes.length) {
166
- _chunkPMF6MWEVcjs.removeNodes.call(void 0, activeNodes);
162
+ _chunkJ74L7UYPcjs.removeNodes.call(void 0, activeNodes);
167
163
  activeNodes = [];
168
164
  }
169
165
  if (view == null || view === false) {
170
166
  return;
171
167
  }
172
- const root = _chunkPMF6MWEVcjs.createRootContext.call(void 0, hostRoot);
173
- const prev = _chunkPMF6MWEVcjs.pushRoot.call(void 0, root);
168
+ const root = _chunkJ74L7UYPcjs.createRootContext.call(void 0, hostRoot);
169
+ const prev = _chunkJ74L7UYPcjs.pushRoot.call(void 0, root);
174
170
  let nodes = [];
175
171
  try {
176
- const output = _chunkPMF6MWEVcjs.createElement.call(void 0, view);
177
- nodes = _chunkPMF6MWEVcjs.toNodeArray.call(void 0, output);
178
- const suspendedAttempt = nodes.length > 0 && nodes.every((node) => node instanceof Comment && node.data === "fict:suspend");
172
+ const output = _chunkJ74L7UYPcjs.createElement.call(void 0, view);
173
+ nodes = _chunkJ74L7UYPcjs.toNodeArray.call(void 0, output);
174
+ const suspendedAttempt = root.suspended || nodes.length > 0 && nodes.every((node) => node instanceof Comment && node.data === "fict:suspend");
179
175
  if (suspendedAttempt) {
180
- _chunkPMF6MWEVcjs.popRoot.call(void 0, prev);
181
- _chunkPMF6MWEVcjs.destroyRoot.call(void 0, root);
176
+ _chunkJ74L7UYPcjs.popRoot.call(void 0, prev);
177
+ _chunkJ74L7UYPcjs.destroyRoot.call(void 0, root);
182
178
  return;
183
179
  }
184
180
  const parentNode = marker.parentNode;
185
181
  if (parentNode) {
186
- _chunkPMF6MWEVcjs.insertNodesBefore.call(void 0, parentNode, nodes, marker);
182
+ _chunkJ74L7UYPcjs.insertNodesBefore.call(void 0, parentNode, nodes, marker);
187
183
  }
188
184
  } catch (err) {
189
- _chunkPMF6MWEVcjs.popRoot.call(void 0, prev);
190
- _chunkPMF6MWEVcjs.flushOnMount.call(void 0, root);
191
- _chunkPMF6MWEVcjs.destroyRoot.call(void 0, root);
192
- if (!_chunkPMF6MWEVcjs.handleError.call(void 0, err, { source: "render" }, hostRoot)) {
185
+ _chunkJ74L7UYPcjs.popRoot.call(void 0, prev);
186
+ _chunkJ74L7UYPcjs.flushOnMount.call(void 0, root);
187
+ _chunkJ74L7UYPcjs.destroyRoot.call(void 0, root);
188
+ if (!_chunkJ74L7UYPcjs.handleError.call(void 0, err, { source: "render" }, hostRoot)) {
193
189
  throw err;
194
190
  }
195
191
  return;
196
192
  }
197
- _chunkPMF6MWEVcjs.popRoot.call(void 0, prev);
198
- _chunkPMF6MWEVcjs.flushOnMount.call(void 0, root);
193
+ _chunkJ74L7UYPcjs.popRoot.call(void 0, prev);
194
+ _chunkJ74L7UYPcjs.flushOnMount.call(void 0, root);
199
195
  cleanup = () => {
200
- _chunkPMF6MWEVcjs.destroyRoot.call(void 0, root);
201
- _chunkPMF6MWEVcjs.removeNodes.call(void 0, nodes);
196
+ _chunkJ74L7UYPcjs.destroyRoot.call(void 0, root);
197
+ _chunkJ74L7UYPcjs.removeNodes.call(void 0, nodes);
202
198
  };
203
199
  activeNodes = nodes;
204
200
  };
@@ -213,10 +209,11 @@ function Suspense(props) {
213
209
  _optionalChain([props, 'access', _7 => _7.onResolve, 'optionalCall', _8 => _8()]);
214
210
  }
215
211
  };
216
- _chunkPMF6MWEVcjs.registerSuspenseHandler.call(void 0, (token) => {
212
+ _chunkJ74L7UYPcjs.registerSuspenseHandler.call(void 0, (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(_nullishCoalesce(props.children, () => ( null)));
227
+ currentView(_nullishCoalesce(props.children, () => ( null)));
228
+ renderView(_nullishCoalesce(props.children, () => ( null)));
231
229
  onResolveMaybe();
232
230
  }
233
231
  },
@@ -238,7 +236,7 @@ function Suspense(props) {
238
236
  const newPending = Math.max(0, pending() - 1);
239
237
  pending(newPending);
240
238
  _optionalChain([props, 'access', _9 => _9.onReject, 'optionalCall', _10 => _10(err)]);
241
- if (!_chunkPMF6MWEVcjs.handleError.call(void 0, err, { source: "render" }, hostRoot)) {
239
+ if (!_chunkJ74L7UYPcjs.handleError.call(void 0, err, { source: "render" }, hostRoot)) {
242
240
  throw err;
243
241
  }
244
242
  }
@@ -247,20 +245,19 @@ function Suspense(props) {
247
245
  }
248
246
  return false;
249
247
  });
250
- _chunkPMF6MWEVcjs.createEffect.call(void 0, () => {
251
- renderView(currentView());
252
- });
248
+ renderView(_nullishCoalesce(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;
256
252
  let prev = isGetter ? getter() : props.resetKeys;
257
- _chunkPMF6MWEVcjs.createEffect.call(void 0, () => {
253
+ _chunkJ74L7UYPcjs.createEffect.call(void 0, () => {
258
254
  const next = getter ? getter() : props.resetKeys;
259
255
  if (prev !== next) {
260
256
  prev = next;
261
257
  epoch++;
262
258
  pending(0);
263
- switchView(_nullishCoalesce(props.children, () => ( null)));
259
+ currentView(_nullishCoalesce(props.children, () => ( null)));
260
+ renderView(_nullishCoalesce(props.children, () => ( null)));
264
261
  }
265
262
  });
266
263
  }
@@ -291,5 +288,5 @@ function Suspense(props) {
291
288
 
292
289
 
293
290
 
294
- exports.ErrorBoundary = ErrorBoundary; exports.Fragment = _chunkPMF6MWEVcjs.Fragment; exports.Suspense = Suspense; exports.batch = _chunkPMF6MWEVcjs.batch2; exports.createContext = _chunkGJTYOFMOcjs.createContext; exports.createEffect = _chunkPMF6MWEVcjs.createEffect; exports.createElement = _chunkPMF6MWEVcjs.createElement; exports.createMemo = _chunkPMF6MWEVcjs.createMemo; exports.createPortal = _chunkPMF6MWEVcjs.createPortal; exports.createRef = createRef; exports.createRoot = _chunkPMF6MWEVcjs.createRoot; exports.createSuspenseToken = createSuspenseToken; exports.hasContext = _chunkGJTYOFMOcjs.hasContext; exports.mergeProps = _chunkPMF6MWEVcjs.mergeProps; exports.onCleanup = _chunkPMF6MWEVcjs.onCleanup; exports.onDestroy = _chunkPMF6MWEVcjs.onDestroy; exports.onMount = _chunkPMF6MWEVcjs.onMount; exports.prop = _chunkPMF6MWEVcjs.prop; exports.render = _chunkPMF6MWEVcjs.render; exports.startTransition = _chunkPMF6MWEVcjs.startTransition; exports.untrack = _chunkPMF6MWEVcjs.untrack2; exports.useContext = _chunkGJTYOFMOcjs.useContext; exports.useDeferredValue = _chunkPMF6MWEVcjs.useDeferredValue; exports.useTransition = _chunkPMF6MWEVcjs.useTransition;
291
+ exports.ErrorBoundary = ErrorBoundary; exports.Fragment = _chunkJ74L7UYPcjs.Fragment; exports.Suspense = Suspense; exports.batch = _chunkJ74L7UYPcjs.batch2; exports.createContext = _chunk527QSKFMcjs.createContext; exports.createEffect = _chunkJ74L7UYPcjs.createEffect; exports.createElement = _chunkJ74L7UYPcjs.createElement; exports.createMemo = _chunkJ74L7UYPcjs.createMemo; exports.createPortal = _chunkJ74L7UYPcjs.createPortal; exports.createRef = createRef; exports.createRoot = _chunkJ74L7UYPcjs.createRoot; exports.createSuspenseToken = createSuspenseToken; exports.hasContext = _chunk527QSKFMcjs.hasContext; exports.mergeProps = _chunkJ74L7UYPcjs.mergeProps; exports.onCleanup = _chunkJ74L7UYPcjs.onCleanup; exports.onDestroy = _chunkJ74L7UYPcjs.onDestroy; exports.onMount = _chunkJ74L7UYPcjs.onMount; exports.prop = _chunkJ74L7UYPcjs.prop; exports.render = _chunkJ74L7UYPcjs.render; exports.startTransition = _chunkJ74L7UYPcjs.startTransition; exports.untrack = _chunkJ74L7UYPcjs.untrack2; exports.useContext = _chunk527QSKFMcjs.useContext; exports.useDeferredValue = _chunkJ74L7UYPcjs.useDeferredValue; exports.useTransition = _chunkJ74L7UYPcjs.useTransition;
295
292
  //# 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":"AAAA;AACE;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACA;AChBO,SAAS,SAAA,CAAA,EAA2D;AACzE,EAAA,OAAO,EAAE,OAAA,EAAS,KAAK,CAAA;AACzB;ADkBA;AACA;AEtBO,SAAS,aAAA,CAAc,KAAA,EAAqC;AACjE,EAAA,MAAM,SAAA,EAAW,QAAA,CAAS,sBAAA,CAAuB,CAAA;AACjD,EAAA,MAAM,OAAA,EAAS,QAAA,CAAS,aAAA,CAAc,qBAAqB,CAAA;AAC3D,EAAA,QAAA,CAAS,WAAA,CAAY,MAAM,CAAA;AAE3B,EAAA,MAAM,YAAA,EAAc,sCAAA,iBAA8B,KAAA,CAAM,QAAA,UAAY,MAAI,CAAA;AACxE,EAAA,MAAM,SAAA,EAAW,8CAAA,CAAe;AAEhC,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI,YAAA,EAAsB,CAAC,CAAA;AAC3B,EAAA,IAAI,kBAAA,EAAoB,KAAA;AAExB,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,CAAsC,GAAG,EAAA,EAChD,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,MAAkB,CAAA;AAC1B,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,4CAAA,IAAiB,CAAA;AACjB,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,mBAAM,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,4CAAA,CAAa,EAAA,GAAM;AACjB,IAAA,MAAM,MAAA,EAAQ,WAAA,CAAY,CAAA;AAC1B,IAAA,WAAA,CAAY,KAAK,CAAA;AAAA,EACnB,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;AFEA;AACA;AGtGO,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,sCAAA,iBAA8B,KAAA,CAAM,QAAA,UAAY,MAAI,CAAA;AACxE,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;AAEhC,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,WAAA,CAAY,IAAI,CAAA;AAChB,IAAA,UAAA,CAAW,IAAI,CAAA;AAAA,EACjB,CAAA;AAEA,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;AACF,MAAA,MAAM,OAAA,EAAS,6CAAA,IAAkB,CAAA;AACjC,MAAA,MAAA,EAAQ,2CAAA,MAAkB,CAAA;AAG1B,MAAA,MAAM,iBAAA,EACJ,KAAA,CAAM,OAAA,EAAS,EAAA,GACf,KAAA,CAAM,KAAA,CAAM,CAAA,IAAA,EAAA,GAAQ,KAAA,WAAgB,QAAA,GAAY,IAAA,CAAiB,KAAA,IAAS,cAAc,CAAA;AAC1F,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,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,4CAAA,IAAiB,CAAA;AACjB,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;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,QAAA,CAAS,sBAAA,CAAuB,CAAA;AACjD,EAAA,MAAM,OAAA,EAAS,QAAA,CAAS,aAAA,CAAc,eAAe,CAAA;AACrD,EAAA,QAAA,CAAS,WAAA,CAAY,MAAM,CAAA;AAC3B,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI,YAAA,EAAsB,CAAC,CAAA;AAE3B,EAAA,MAAM,eAAA,EAAiB,CAAA,EAAA,GAAM;AAC3B,IAAA,GAAA,CAAI,CAAC,YAAA,EAAc;AACjB,MAAA,aAAA,EAAe,IAAA;AACf,sBAAA,KAAA,qBAAM,SAAA,0BAAA,CAAY,GAAA;AAAA,IACpB;AAAA,EACF,CAAA;AAEA,EAAA,uDAAA,CAAwB,KAAA,EAAA,GAAS;AAC/B,IAAA,MAAM,WAAA,EAAa,KAAA;AACnB,IAAA,OAAA,CAAQ,OAAA,CAAQ,EAAA,EAAI,CAAC,CAAA;AACrB,IAAA,UAAA,CAAW,UAAA,CAAW,CAAC,CAAA;AAEvB,IAAA,MAAM,SAAA,EAAY,KAAA,CAAwB,KAAA,EACrC,MAAA,EACD,UAAA,CAAW,KAAK,EAAA,EACd,MAAA,EACA,IAAA;AAEN,IAAA,GAAA,CAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,IAAA;AAAA,QACP,CAAA,EAAA,GAAM;AAGJ,UAAA,GAAA,CAAI,MAAA,IAAU,UAAA,EAAY;AAExB,YAAA,MAAA;AAAA,UACF;AAIA,UAAA,MAAM,WAAA,EAAa,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,OAAA,CAAQ,EAAA,EAAI,CAAC,CAAA;AAC5C,UAAA,OAAA,CAAQ,UAAU,CAAA;AAClB,UAAA,GAAA,CAAI,WAAA,IAAe,CAAA,EAAG;AACpB,YAAA,UAAA,kBAAW,KAAA,CAAM,QAAA,UAAY,MAAI,CAAA;AACjC,YAAA,cAAA,CAAe,CAAA;AAAA,UACjB;AAAA,QACF,CAAA;AAAA,QACA,CAAA,GAAA,EAAA,GAAO;AAEL,UAAA,GAAA,CAAI,MAAA,IAAU,UAAA,EAAY;AACxB,YAAA,MAAA;AAAA,UACF;AACA,UAAA,MAAM,WAAA,EAAa,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,OAAA,CAAQ,EAAA,EAAI,CAAC,CAAA;AAC5C,UAAA,OAAA,CAAQ,UAAU,CAAA;AAClB,0BAAA,KAAA,qBAAM,QAAA,4BAAA,CAAW,GAAG,GAAA;AACpB,UAAA,GAAA,CAAI,CAAC,2CAAA,GAAY,EAAK,EAAE,MAAA,EAAQ,SAAS,CAAA,EAAG,QAAQ,CAAA,EAAG;AACrD,YAAA,MAAM,GAAA;AAAA,UACR;AAAA,QACF;AAAA,MACF,CAAA;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,OAAO,KAAA;AAAA,EACT,CAAC,CAAA;AAED,EAAA,4CAAA,CAAa,EAAA,GAAM;AACjB,IAAA,UAAA,CAAW,WAAA,CAAY,CAAC,CAAA;AAAA,EAC1B,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,KAAA,EAAA;AACA,QAAA,OAAA,CAAQ,CAAC,CAAA;AACT,QAAA,UAAA,kBAAW,KAAA,CAAM,QAAA,UAAY,MAAI,CAAA;AAAA,MACnC;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,QAAA;AACT;AHiEA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,ipCAAC","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 { 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"]}
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 { 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"]}
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
- export { F as Fragment, J as JSX, M as Memo, e as createElement, c as createMemo, d as createRoot, m as mergeProps, b as onCleanup, a as onDestroy, o as onMount, p as prop, r as render } from './props-CrOMYbLv.cjs';
2
- import { R as RefObject, B as BaseProps, F as FictNode, S as SuspenseToken } from './effect-Auji1rz9.cjs';
3
- export { p as ClassProp, C as Cleanup, l as Component, D as DOMElement, E as Effect, r as ErrorInfo, q as EventHandler, k as FictVNode, P as PropsWithChildren, m as Ref, n as RefCallback, o as StyleProp, h as createEffect, j as createPortal } from './effect-Auji1rz9.cjs';
4
- export { C as Context, P as ProviderProps, c as createContext, h as hasContext, u as useContext } from './context-UXySaqI_.cjs';
1
+ export { F as Fragment, J as JSX, M as Memo, e as createElement, c as createMemo, d as createRoot, m as mergeProps, b as onCleanup, a as onDestroy, o as onMount, p as prop, r as render } from './props-CBwuh35e.cjs';
2
+ import { R as RefObject, B as BaseProps, F as FictNode, S as SuspenseToken } from './effect-ClARNUCc.cjs';
3
+ export { p as ClassProp, C as Cleanup, l as Component, D as DOMElement, E as Effect, r as ErrorInfo, q as EventHandler, k as FictVNode, P as PropsWithChildren, m as Ref, n as RefCallback, o as StyleProp, h as createEffect, j as createPortal } from './effect-ClARNUCc.cjs';
4
+ export { C as Context, P as ProviderProps, c as createContext, h as hasContext, u as useContext } from './context-9gFXOdJl.cjs';
5
5
 
6
6
  /**
7
7
  * Create a ref object for DOM element references.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- export { F as Fragment, J as JSX, M as Memo, e as createElement, c as createMemo, d as createRoot, m as mergeProps, b as onCleanup, a as onDestroy, o as onMount, p as prop, r as render } from './props-ES0Ag_Wd.js';
2
- import { R as RefObject, B as BaseProps, F as FictNode, S as SuspenseToken } from './effect-Auji1rz9.js';
3
- export { p as ClassProp, C as Cleanup, l as Component, D as DOMElement, E as Effect, r as ErrorInfo, q as EventHandler, k as FictVNode, P as PropsWithChildren, m as Ref, n as RefCallback, o as StyleProp, h as createEffect, j as createPortal } from './effect-Auji1rz9.js';
4
- export { C as Context, P as ProviderProps, c as createContext, h as hasContext, u as useContext } from './context-B7UYnfzM.js';
1
+ export { F as Fragment, J as JSX, M as Memo, e as createElement, c as createMemo, d as createRoot, m as mergeProps, b as onCleanup, a as onDestroy, o as onMount, p as prop, r as render } from './props-DAyeRPwH.js';
2
+ import { R as RefObject, B as BaseProps, F as FictNode, S as SuspenseToken } from './effect-ClARNUCc.js';
3
+ export { p as ClassProp, C as Cleanup, l as Component, D as DOMElement, E as Effect, r as ErrorInfo, q as EventHandler, k as FictVNode, P as PropsWithChildren, m as Ref, n as RefCallback, o as StyleProp, h as createEffect, j as createPortal } from './effect-ClARNUCc.js';
4
+ export { C as Context, P as ProviderProps, c as createContext, h as hasContext, u as useContext } from './context-4woHo7-L.js';
5
5
 
6
6
  /**
7
7
  * Create a ref object for DOM element references.