@fictjs/runtime 0.3.0 → 0.5.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.
- package/dist/advanced.cjs +10 -8
- package/dist/advanced.cjs.map +1 -1
- package/dist/advanced.d.cts +4 -3
- package/dist/advanced.d.ts +4 -3
- package/dist/advanced.js +10 -8
- package/dist/advanced.js.map +1 -1
- package/dist/{chunk-TWELIZRY.js → chunk-5AA7HP4S.js} +5 -3
- package/dist/{chunk-TWELIZRY.js.map → chunk-5AA7HP4S.js.map} +1 -1
- package/dist/chunk-6SOPF5LZ.cjs +2363 -0
- package/dist/chunk-6SOPF5LZ.cjs.map +1 -0
- package/dist/{chunk-SO6X7G5S.js → chunk-BQG7VEBY.js} +501 -1880
- package/dist/chunk-BQG7VEBY.js.map +1 -0
- package/dist/chunk-FKDMDAUR.js +2363 -0
- package/dist/chunk-FKDMDAUR.js.map +1 -0
- package/dist/{chunk-L4DIV3RC.cjs → chunk-GHUV2FLD.cjs} +9 -7
- package/dist/chunk-GHUV2FLD.cjs.map +1 -0
- package/dist/{chunk-XLIZJMMJ.js → chunk-KKKYW54Z.js} +8 -6
- package/dist/{chunk-XLIZJMMJ.js.map → chunk-KKKYW54Z.js.map} +1 -1
- package/dist/{chunk-M2TSXZ4C.cjs → chunk-KYLNC4CD.cjs} +18 -16
- package/dist/chunk-KYLNC4CD.cjs.map +1 -0
- package/dist/chunk-TKWN42TA.cjs +2259 -0
- package/dist/chunk-TKWN42TA.cjs.map +1 -0
- package/dist/{context-B25xyQrJ.d.cts → context-CTBE00S_.d.cts} +1 -1
- package/dist/{context-CGdP7_Jb.d.ts → context-lkLhbkFJ.d.ts} +1 -1
- package/dist/{effect-D6kaLM2-.d.cts → effect-BpSNEJJz.d.cts} +7 -67
- package/dist/{effect-D6kaLM2-.d.ts → effect-BpSNEJJz.d.ts} +7 -67
- package/dist/index.cjs +40 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -4
- package/dist/index.d.ts +5 -4
- package/dist/index.dev.js +92 -4
- package/dist/index.dev.js.map +1 -1
- package/dist/index.js +19 -17
- package/dist/index.js.map +1 -1
- package/dist/internal.cjs +189 -202
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +13 -23
- package/dist/internal.d.ts +13 -23
- package/dist/internal.js +195 -208
- package/dist/internal.js.map +1 -1
- package/dist/loader.cjs +280 -0
- package/dist/loader.cjs.map +1 -0
- package/dist/loader.d.cts +57 -0
- package/dist/loader.d.ts +57 -0
- package/dist/loader.js +280 -0
- package/dist/loader.js.map +1 -0
- package/dist/{props-BIfromL0.d.cts → props-XTHYD19o.d.cts} +13 -2
- package/dist/{props-BEgIVMRx.d.ts → props-x-HbI-jX.d.ts} +13 -2
- package/dist/resume-BrAkmSTY.d.cts +79 -0
- package/dist/resume-Dx8_l72o.d.ts +79 -0
- package/dist/{scope-CzNkn587.d.ts → scope-CdbGmsFf.d.ts} +1 -1
- package/dist/{scope-Cx_3CjIZ.d.cts → scope-DfcP9I-A.d.cts} +1 -1
- package/dist/signal-C4ISF17w.d.cts +66 -0
- package/dist/signal-C4ISF17w.d.ts +66 -0
- package/package.json +8 -3
- package/src/binding.ts +254 -5
- package/src/dom.ts +103 -5
- package/src/hooks.ts +15 -2
- package/src/hydration.ts +75 -0
- package/src/internal.ts +34 -2
- package/src/list-helpers.ts +113 -12
- package/src/loader.ts +437 -0
- package/src/node-ops.ts +65 -0
- package/src/resume.ts +517 -0
- package/src/store.ts +8 -0
- package/dist/chunk-ID3WBWNO.cjs +0 -3638
- package/dist/chunk-ID3WBWNO.cjs.map +0 -1
- package/dist/chunk-L4DIV3RC.cjs.map +0 -1
- package/dist/chunk-M2TSXZ4C.cjs.map +0 -1
- package/dist/chunk-SO6X7G5S.js.map +0 -1
|
@@ -194,6 +194,11 @@ declare function classList(node: Element, value: Record<string, boolean> | null
|
|
|
194
194
|
* @param createElementFn - Optional function to create DOM elements (when marker is provided)
|
|
195
195
|
*/
|
|
196
196
|
declare function insert(parent: ParentNode & Node, getValue: () => FictNode, markerOrCreateElement?: Node | CreateElementFn, createElementFn?: CreateElementFn): Cleanup;
|
|
197
|
+
/**
|
|
198
|
+
* Insert reactive content between two marker comments.
|
|
199
|
+
* Supports hydration by claiming existing nodes between markers.
|
|
200
|
+
*/
|
|
201
|
+
declare function insertBetween(start: Comment, end: Comment, getValue: () => FictNode, createElementFn?: CreateElementFn): Cleanup;
|
|
197
202
|
/**
|
|
198
203
|
* Create a reactive child binding that updates when the child value changes.
|
|
199
204
|
* This is used for dynamic expressions like `{show && <Modal />}` or `{items.map(...)}`.
|
|
@@ -333,7 +338,7 @@ declare function assign(node: Element, props: Record<string, unknown>, isSVG?: b
|
|
|
333
338
|
* )
|
|
334
339
|
* ```
|
|
335
340
|
*/
|
|
336
|
-
declare function createConditional(condition: () => boolean, renderTrue: () => FictNode, createElementFn: CreateElementFn, renderFalse?: () => FictNode): BindingHandle;
|
|
341
|
+
declare function createConditional(condition: () => boolean, renderTrue: () => FictNode, createElementFn: CreateElementFn, renderFalse?: () => FictNode, startOverride?: Comment, endOverride?: Comment): BindingHandle;
|
|
337
342
|
/**
|
|
338
343
|
* Create a show/hide binding that uses CSS display instead of DOM manipulation.
|
|
339
344
|
* More efficient than conditional when the content is expensive to create.
|
|
@@ -374,71 +379,6 @@ declare function createRoot<T>(fn: () => T, options?: CreateRootOptions): {
|
|
|
374
379
|
};
|
|
375
380
|
declare function registerErrorHandler(fn: ErrorHandler): void;
|
|
376
381
|
|
|
377
|
-
/**
|
|
378
|
-
* Options for creating a signal
|
|
379
|
-
*/
|
|
380
|
-
interface SignalOptions<T> {
|
|
381
|
-
/** Custom equality check */
|
|
382
|
-
equals?: false | ((prev: T, next: T) => boolean);
|
|
383
|
-
/** Debug name */
|
|
384
|
-
name?: string;
|
|
385
|
-
/** Source location */
|
|
386
|
-
devToolsSource?: string;
|
|
387
|
-
}
|
|
388
|
-
/**
|
|
389
|
-
* Options for creating a memo
|
|
390
|
-
*/
|
|
391
|
-
interface MemoOptions<T> {
|
|
392
|
-
/** Custom equality check */
|
|
393
|
-
equals?: false | ((prev: T, next: T) => boolean);
|
|
394
|
-
/** Debug name */
|
|
395
|
-
name?: string;
|
|
396
|
-
/** Source location */
|
|
397
|
-
devToolsSource?: string;
|
|
398
|
-
}
|
|
399
|
-
/**
|
|
400
|
-
* Signal accessor - function to get/set signal value
|
|
401
|
-
*/
|
|
402
|
-
interface SignalAccessor<T> {
|
|
403
|
-
(): T;
|
|
404
|
-
(value: T): void;
|
|
405
|
-
}
|
|
406
|
-
/**
|
|
407
|
-
* Computed accessor - function to get computed value
|
|
408
|
-
*/
|
|
409
|
-
type ComputedAccessor<T> = () => T;
|
|
410
|
-
/**
|
|
411
|
-
* Effect scope disposer - function to dispose an effect scope
|
|
412
|
-
*/
|
|
413
|
-
type EffectScopeDisposer = () => void;
|
|
414
|
-
/**
|
|
415
|
-
* Create a reactive signal
|
|
416
|
-
* @param initialValue - The initial value
|
|
417
|
-
* @returns A signal accessor function
|
|
418
|
-
*/
|
|
419
|
-
declare function signal<T>(initialValue: T, options?: SignalOptions<T>): SignalAccessor<T>;
|
|
420
|
-
/**
|
|
421
|
-
* Create a reactive effect scope
|
|
422
|
-
* @param fn - The scope function
|
|
423
|
-
* @returns An effect scope disposer function
|
|
424
|
-
*/
|
|
425
|
-
declare function effectScope(fn: () => void): EffectScopeDisposer;
|
|
426
|
-
/**
|
|
427
|
-
* Reset all global reactive state for test isolation.
|
|
428
|
-
* ONLY use this in test setup/teardown - never in production code.
|
|
429
|
-
* This clears effect queues, resets batch depth, and clears pending flushes.
|
|
430
|
-
*/
|
|
431
|
-
declare function __resetReactiveState(): void;
|
|
432
|
-
/**
|
|
433
|
-
* Create a selector signal that efficiently updates only when the selected key matches.
|
|
434
|
-
* Useful for large lists where only one item is selected.
|
|
435
|
-
*
|
|
436
|
-
* @param source - The source signal returning the current key
|
|
437
|
-
* @param equalityFn - Optional equality function
|
|
438
|
-
* @returns A selector function that takes a key and returns a boolean signal accessor
|
|
439
|
-
*/
|
|
440
|
-
declare function createSelector<T>(source: () => T, equalityFn?: (a: T, b: T) => boolean): (key: T) => boolean;
|
|
441
|
-
|
|
442
382
|
/**
|
|
443
383
|
* Effect callback run synchronously; async callbacks are not tracked after the first await.
|
|
444
384
|
* TypeScript will reject `async () => {}` here—split async work or read signals before awaiting.
|
|
@@ -447,4 +387,4 @@ type Effect = () => void | Cleanup;
|
|
|
447
387
|
declare function createEffect(fn: Effect): () => void;
|
|
448
388
|
declare function createRenderEffect(fn: Effect): () => void;
|
|
449
389
|
|
|
450
|
-
export {
|
|
390
|
+
export { bindStyle as A, type BaseProps as B, type Cleanup as C, type DOMElement as D, type Effect as E, type FictNode as F, bindClass as G, bindEvent as H, callEventHandler as I, bindProperty as J, bindRef as K, insert as L, insertBetween as M, createConditional as N, spread as O, type PropsWithChildren as P, assign as Q, type RefObject as R, type SuspenseToken as S, classList as T, delegateEvents as U, clearDelegatedEvents as V, addEventListener as W, type MaybeReactive as X, type BindingHandle as Y, type CreateElementFn as Z, type AttributeSetter as _, createChildBinding as a, createAttributeBinding as b, createTextBinding as c, createStyleBinding as d, createClassBinding as e, createShow as f, createRenderEffect as g, createEffect as h, isReactive as i, onDestroy as j, onCleanup as k, createRoot as l, createPortal as m, type FictVNode as n, onMount as o, type Component as p, type Ref as q, registerErrorHandler as r, type RefCallback as s, type StyleProp as t, unwrap as u, type ClassProp as v, type EventHandler as w, type ErrorInfo as x, bindText as y, bindAttribute as z };
|
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var _chunkKYLNC4CDcjs = require('./chunk-KYLNC4CD.cjs');
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
@@ -19,6 +19,7 @@ var _chunkM2TSXZ4Ccjs = require('./chunk-M2TSXZ4C.cjs');
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
|
|
22
|
+
var _chunkTKWN42TAcjs = require('./chunk-TKWN42TA.cjs');
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
|
|
@@ -35,7 +36,8 @@ var _chunkM2TSXZ4Ccjs = require('./chunk-M2TSXZ4C.cjs');
|
|
|
35
36
|
|
|
36
37
|
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
|
|
40
|
+
var _chunk6SOPF5LZcjs = require('./chunk-6SOPF5LZ.cjs');
|
|
39
41
|
|
|
40
42
|
// src/ref.ts
|
|
41
43
|
function createRef() {
|
|
@@ -47,7 +49,7 @@ function ErrorBoundary(props) {
|
|
|
47
49
|
const fragment = document.createDocumentFragment();
|
|
48
50
|
const marker = document.createComment("fict:error-boundary");
|
|
49
51
|
fragment.appendChild(marker);
|
|
50
|
-
const hostRoot =
|
|
52
|
+
const hostRoot = _chunk6SOPF5LZcjs.getCurrentRoot.call(void 0, );
|
|
51
53
|
let cleanup;
|
|
52
54
|
let activeNodes = [];
|
|
53
55
|
let renderingFallback = false;
|
|
@@ -65,25 +67,25 @@ function ErrorBoundary(props) {
|
|
|
65
67
|
cleanup = void 0;
|
|
66
68
|
}
|
|
67
69
|
if (activeNodes.length) {
|
|
68
|
-
|
|
70
|
+
_chunkTKWN42TAcjs.removeNodes.call(void 0, activeNodes);
|
|
69
71
|
activeNodes = [];
|
|
70
72
|
}
|
|
71
73
|
if (value == null || value === false) {
|
|
72
74
|
return;
|
|
73
75
|
}
|
|
74
|
-
const root =
|
|
75
|
-
const prev =
|
|
76
|
+
const root = _chunk6SOPF5LZcjs.createRootContext.call(void 0, hostRoot);
|
|
77
|
+
const prev = _chunk6SOPF5LZcjs.pushRoot.call(void 0, root);
|
|
76
78
|
let nodes = [];
|
|
77
79
|
try {
|
|
78
|
-
const output =
|
|
79
|
-
nodes =
|
|
80
|
+
const output = _chunkTKWN42TAcjs.createElement.call(void 0, value);
|
|
81
|
+
nodes = _chunkTKWN42TAcjs.toNodeArray.call(void 0, output);
|
|
80
82
|
const parentNode = marker.parentNode;
|
|
81
83
|
if (parentNode) {
|
|
82
|
-
|
|
84
|
+
_chunkTKWN42TAcjs.insertNodesBefore.call(void 0, parentNode, nodes, marker);
|
|
83
85
|
}
|
|
84
86
|
} catch (err) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
+
_chunk6SOPF5LZcjs.popRoot.call(void 0, prev);
|
|
88
|
+
_chunk6SOPF5LZcjs.destroyRoot.call(void 0, root);
|
|
87
89
|
if (renderingFallback) {
|
|
88
90
|
throw err;
|
|
89
91
|
}
|
|
@@ -98,11 +100,11 @@ function ErrorBoundary(props) {
|
|
|
98
100
|
}
|
|
99
101
|
return;
|
|
100
102
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
+
_chunk6SOPF5LZcjs.popRoot.call(void 0, prev);
|
|
104
|
+
_chunk6SOPF5LZcjs.flushOnMount.call(void 0, root);
|
|
103
105
|
cleanup = () => {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
+
_chunk6SOPF5LZcjs.destroyRoot.call(void 0, root);
|
|
107
|
+
_chunkTKWN42TAcjs.removeNodes.call(void 0, nodes);
|
|
106
108
|
};
|
|
107
109
|
activeNodes = nodes;
|
|
108
110
|
};
|
|
@@ -111,7 +113,7 @@ function ErrorBoundary(props) {
|
|
|
111
113
|
renderValue(toView(null));
|
|
112
114
|
};
|
|
113
115
|
renderValue(_nullishCoalesce(props.children, () => ( null)));
|
|
114
|
-
|
|
116
|
+
_chunk6SOPF5LZcjs.registerErrorHandler.call(void 0, (err) => {
|
|
115
117
|
renderValue(toView(err));
|
|
116
118
|
_optionalChain([props, 'access', _5 => _5.onError, 'optionalCall', _6 => _6(err)]);
|
|
117
119
|
return true;
|
|
@@ -120,7 +122,7 @@ function ErrorBoundary(props) {
|
|
|
120
122
|
const isGetter = typeof props.resetKeys === "function" && props.resetKeys.length === 0;
|
|
121
123
|
const getter = isGetter ? props.resetKeys : void 0;
|
|
122
124
|
let prev = isGetter ? getter() : props.resetKeys;
|
|
123
|
-
|
|
125
|
+
_chunk6SOPF5LZcjs.createEffect.call(void 0, () => {
|
|
124
126
|
const next = getter ? getter() : props.resetKeys;
|
|
125
127
|
if (prev !== next) {
|
|
126
128
|
prev = next;
|
|
@@ -149,10 +151,10 @@ function createSuspenseToken() {
|
|
|
149
151
|
}
|
|
150
152
|
var isThenable = (value) => typeof value === "object" && value !== null && typeof value.then === "function";
|
|
151
153
|
function Suspense(props) {
|
|
152
|
-
const pending =
|
|
154
|
+
const pending = _chunk6SOPF5LZcjs.signal.call(void 0, 0);
|
|
153
155
|
let resolvedOnce = false;
|
|
154
156
|
let epoch = 0;
|
|
155
|
-
const hostRoot =
|
|
157
|
+
const hostRoot = _chunk6SOPF5LZcjs.getCurrentRoot.call(void 0, );
|
|
156
158
|
const toFallback = (err) => typeof props.fallback === "function" ? props.fallback(err) : props.fallback;
|
|
157
159
|
const renderView = (view) => {
|
|
158
160
|
if (cleanup) {
|
|
@@ -160,41 +162,41 @@ function Suspense(props) {
|
|
|
160
162
|
cleanup = void 0;
|
|
161
163
|
}
|
|
162
164
|
if (activeNodes.length) {
|
|
163
|
-
|
|
165
|
+
_chunkTKWN42TAcjs.removeNodes.call(void 0, activeNodes);
|
|
164
166
|
activeNodes = [];
|
|
165
167
|
}
|
|
166
168
|
if (view == null || view === false) {
|
|
167
169
|
return;
|
|
168
170
|
}
|
|
169
|
-
const root =
|
|
170
|
-
const prev =
|
|
171
|
+
const root = _chunk6SOPF5LZcjs.createRootContext.call(void 0, hostRoot);
|
|
172
|
+
const prev = _chunk6SOPF5LZcjs.pushRoot.call(void 0, root);
|
|
171
173
|
let nodes = [];
|
|
172
174
|
try {
|
|
173
|
-
const output =
|
|
174
|
-
nodes =
|
|
175
|
+
const output = _chunkTKWN42TAcjs.createElement.call(void 0, view);
|
|
176
|
+
nodes = _chunkTKWN42TAcjs.toNodeArray.call(void 0, output);
|
|
175
177
|
const suspendedAttempt = root.suspended || nodes.length > 0 && nodes.every((node) => node instanceof Comment && node.data === "fict:suspend");
|
|
176
178
|
if (suspendedAttempt) {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
+
_chunk6SOPF5LZcjs.popRoot.call(void 0, prev);
|
|
180
|
+
_chunk6SOPF5LZcjs.destroyRoot.call(void 0, root);
|
|
179
181
|
return;
|
|
180
182
|
}
|
|
181
183
|
const parentNode = marker.parentNode;
|
|
182
184
|
if (parentNode) {
|
|
183
|
-
|
|
185
|
+
_chunkTKWN42TAcjs.insertNodesBefore.call(void 0, parentNode, nodes, marker);
|
|
184
186
|
}
|
|
185
187
|
} catch (err) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if (!
|
|
188
|
+
_chunk6SOPF5LZcjs.popRoot.call(void 0, prev);
|
|
189
|
+
_chunk6SOPF5LZcjs.destroyRoot.call(void 0, root);
|
|
190
|
+
if (!_chunk6SOPF5LZcjs.handleError.call(void 0, err, { source: "render" }, hostRoot)) {
|
|
189
191
|
throw err;
|
|
190
192
|
}
|
|
191
193
|
return;
|
|
192
194
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
+
_chunk6SOPF5LZcjs.popRoot.call(void 0, prev);
|
|
196
|
+
_chunk6SOPF5LZcjs.flushOnMount.call(void 0, root);
|
|
195
197
|
cleanup = () => {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
+
_chunk6SOPF5LZcjs.destroyRoot.call(void 0, root);
|
|
199
|
+
_chunkTKWN42TAcjs.removeNodes.call(void 0, nodes);
|
|
198
200
|
};
|
|
199
201
|
activeNodes = nodes;
|
|
200
202
|
};
|
|
@@ -209,7 +211,7 @@ function Suspense(props) {
|
|
|
209
211
|
_optionalChain([props, 'access', _7 => _7.onResolve, 'optionalCall', _8 => _8()]);
|
|
210
212
|
}
|
|
211
213
|
};
|
|
212
|
-
|
|
214
|
+
_chunk6SOPF5LZcjs.registerSuspenseHandler.call(void 0, (token) => {
|
|
213
215
|
const tokenEpoch = epoch;
|
|
214
216
|
pending(pending() + 1);
|
|
215
217
|
renderView(toFallback());
|
|
@@ -234,7 +236,7 @@ function Suspense(props) {
|
|
|
234
236
|
const newPending = Math.max(0, pending() - 1);
|
|
235
237
|
pending(newPending);
|
|
236
238
|
_optionalChain([props, 'access', _9 => _9.onReject, 'optionalCall', _10 => _10(err)]);
|
|
237
|
-
if (!
|
|
239
|
+
if (!_chunk6SOPF5LZcjs.handleError.call(void 0, err, { source: "render" }, hostRoot)) {
|
|
238
240
|
throw err;
|
|
239
241
|
}
|
|
240
242
|
}
|
|
@@ -248,7 +250,7 @@ function Suspense(props) {
|
|
|
248
250
|
const isGetter = typeof props.resetKeys === "function" && props.resetKeys.length === 0;
|
|
249
251
|
const getter = isGetter ? props.resetKeys : void 0;
|
|
250
252
|
let prev = isGetter ? getter() : props.resetKeys;
|
|
251
|
-
|
|
253
|
+
_chunk6SOPF5LZcjs.createEffect.call(void 0, () => {
|
|
252
254
|
const next = getter ? getter() : props.resetKeys;
|
|
253
255
|
if (prev !== next) {
|
|
254
256
|
prev = next;
|
|
@@ -286,5 +288,5 @@ function Suspense(props) {
|
|
|
286
288
|
|
|
287
289
|
|
|
288
290
|
|
|
289
|
-
exports.ErrorBoundary = ErrorBoundary; exports.Fragment =
|
|
291
|
+
exports.ErrorBoundary = ErrorBoundary; exports.Fragment = _chunkTKWN42TAcjs.Fragment; exports.Suspense = Suspense; exports.batch = _chunkTKWN42TAcjs.batch; exports.createContext = _chunkKYLNC4CDcjs.createContext; exports.createEffect = _chunk6SOPF5LZcjs.createEffect; exports.createElement = _chunkTKWN42TAcjs.createElement; exports.createMemo = _chunk6SOPF5LZcjs.createMemo; exports.createPortal = _chunkTKWN42TAcjs.createPortal; exports.createRef = createRef; exports.createRoot = _chunk6SOPF5LZcjs.createRoot; exports.createSuspenseToken = createSuspenseToken; exports.hasContext = _chunkKYLNC4CDcjs.hasContext; exports.keyed = _chunkTKWN42TAcjs.keyed; exports.mergeProps = _chunkTKWN42TAcjs.mergeProps; exports.onCleanup = _chunk6SOPF5LZcjs.onCleanup; exports.onDestroy = _chunk6SOPF5LZcjs.onDestroy; exports.onMount = _chunk6SOPF5LZcjs.onMount; exports.prop = _chunkTKWN42TAcjs.prop; exports.render = _chunkTKWN42TAcjs.render; exports.startTransition = _chunkTKWN42TAcjs.startTransition; exports.untrack = _chunkTKWN42TAcjs.untrack; exports.useContext = _chunkKYLNC4CDcjs.useContext; exports.useDeferredValue = _chunkTKWN42TAcjs.useDeferredValue; exports.useTransition = _chunkTKWN42TAcjs.useTransition;
|
|
290
292
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -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 fragment = document.createDocumentFragment()\n const marker = document.createComment('fict:error-boundary')\n fragment.appendChild(marker)\n\n const hostRoot = getCurrentRoot()\n\n let cleanup: (() => void) | undefined\n let activeNodes: Node[] = []\n let renderingFallback = false\n\n let reset = () => {}\n const toView = (err: unknown | null): FictNode | null => {\n if (err != null) {\n return typeof props.fallback === 'function'\n ? (props.fallback as (e: unknown, reset?: () => void) => FictNode)(err, reset)\n : props.fallback\n }\n return props.children ?? null\n }\n\n const renderValue = (value: FictNode | null) => {\n if (cleanup) {\n cleanup()\n cleanup = undefined\n }\n if (activeNodes.length) {\n removeNodes(activeNodes)\n activeNodes = []\n }\n\n if (value == null || value === false) {\n return\n }\n\n const root = createRootContext(hostRoot)\n const prev = pushRoot(root)\n let nodes: Node[] = []\n try {\n const output = createElement(value)\n nodes = toNodeArray(output)\n const parentNode = marker.parentNode as (ParentNode & Node) | null\n if (parentNode) {\n insertNodesBefore(parentNode, nodes, marker)\n }\n } catch (err) {\n popRoot(prev)\n destroyRoot(root)\n // Fall back immediately on render errors, avoid infinite recursion\n if (renderingFallback) {\n throw err\n }\n // nested errors. If fallback rendering also throws, we should NOT reset\n // the flag until we're sure no more recursion is happening.\n renderingFallback = true\n try {\n renderValue(toView(err))\n // Only reset if successful - if renderValue threw, we want to keep\n // renderingFallback = true to prevent infinite recursion\n renderingFallback = false\n props.onError?.(err)\n } catch (fallbackErr) {\n // Fallback rendering failed - keep renderingFallback = true\n // to prevent further attempts, then rethrow\n // If fallback fails, report both errors\n props.onError?.(err)\n throw fallbackErr\n }\n return\n }\n popRoot(prev)\n flushOnMount(root)\n\n cleanup = () => {\n destroyRoot(root)\n removeNodes(nodes)\n }\n activeNodes = nodes\n }\n\n reset = () => {\n renderingFallback = false\n renderValue(toView(null))\n }\n\n renderValue(props.children ?? null)\n\n registerErrorHandler(err => {\n renderValue(toView(err))\n props.onError?.(err)\n return true\n })\n\n if (props.resetKeys !== undefined) {\n const isGetter =\n typeof props.resetKeys === 'function' && (props.resetKeys as () => unknown).length === 0\n const getter = isGetter ? (props.resetKeys as () => unknown) : undefined\n let prev = isGetter ? getter!() : props.resetKeys\n createEffect(() => {\n const next = getter ? getter() : props.resetKeys\n if (prev !== next) {\n prev = next\n renderValue(toView(null))\n }\n })\n }\n\n return fragment\n}\n","import { createElement } from './dom'\nimport { createEffect } from './effect'\nimport {\n createRootContext,\n destroyRoot,\n flushOnMount,\n getCurrentRoot,\n handleError,\n pushRoot,\n popRoot,\n registerSuspenseHandler,\n} from './lifecycle'\nimport { insertNodesBefore, removeNodes, toNodeArray } from './node-ops'\nimport { createSignal } from './signal'\nimport type { BaseProps, FictNode, SuspenseToken } from './types'\n\nexport interface SuspenseProps extends BaseProps {\n fallback: FictNode | ((err?: unknown) => FictNode)\n onResolve?: () => void\n onReject?: (err: unknown) => void\n resetKeys?: unknown | (() => unknown)\n}\n\nexport interface SuspenseHandle {\n token: SuspenseToken\n resolve: () => void\n reject: (err: unknown) => void\n}\n\nexport function createSuspenseToken(): SuspenseHandle {\n let resolve!: () => void\n let reject!: (err: unknown) => void\n const promise = new Promise<void>((res, rej) => {\n resolve = res\n reject = rej\n })\n return {\n token: {\n then: promise.then.bind(promise),\n },\n resolve,\n reject,\n }\n}\n\nconst isThenable = (value: unknown): value is PromiseLike<unknown> =>\n typeof value === 'object' &&\n value !== null &&\n typeof (value as PromiseLike<unknown>).then === 'function'\n\nexport function Suspense(props: SuspenseProps): FictNode {\n const pending = createSignal(0)\n let resolvedOnce = false\n let epoch = 0\n const hostRoot = getCurrentRoot()\n\n const toFallback = (err?: unknown) =>\n typeof props.fallback === 'function'\n ? (props.fallback as (e?: unknown) => FictNode)(err)\n : props.fallback\n\n const renderView = (view: FictNode | null) => {\n if (cleanup) {\n cleanup()\n cleanup = undefined\n }\n if (activeNodes.length) {\n removeNodes(activeNodes)\n activeNodes = []\n }\n\n if (view == null || view === false) {\n return\n }\n\n const root = createRootContext(hostRoot)\n const prev = pushRoot(root)\n let nodes: Node[] = []\n try {\n const output = createElement(view)\n nodes = toNodeArray(output)\n // Suspended view: child threw a suspense token and was handled upstream.\n // Avoid replacing existing fallback content; tear down this attempt.\n const suspendedAttempt =\n root.suspended ||\n (nodes.length > 0 &&\n nodes.every(node => node instanceof Comment && (node as Comment).data === 'fict:suspend'))\n if (suspendedAttempt) {\n popRoot(prev)\n destroyRoot(root)\n return\n }\n const parentNode = marker.parentNode as (ParentNode & Node) | null\n if (parentNode) {\n insertNodesBefore(parentNode, nodes, marker)\n }\n } catch (err) {\n popRoot(prev)\n destroyRoot(root)\n if (!handleError(err, { source: 'render' }, hostRoot)) {\n throw err\n }\n return\n }\n popRoot(prev)\n flushOnMount(root)\n\n cleanup = () => {\n destroyRoot(root)\n removeNodes(nodes)\n }\n activeNodes = nodes\n }\n\n const fragment = document.createDocumentFragment()\n const marker = document.createComment('fict:suspense')\n fragment.appendChild(marker)\n let cleanup: (() => void) | undefined\n let activeNodes: Node[] = []\n\n const onResolveMaybe = () => {\n if (!resolvedOnce) {\n resolvedOnce = true\n props.onResolve?.()\n }\n }\n\n registerSuspenseHandler(token => {\n const tokenEpoch = epoch\n pending(pending() + 1)\n // Directly render fallback instead of using switchView to avoid\n // triggering the effect which would cause duplicate renders\n renderView(toFallback())\n\n const thenable = (token as SuspenseToken).then\n ? (token as SuspenseToken)\n : isThenable(token)\n ? token\n : null\n\n if (thenable) {\n thenable.then(\n () => {\n // This prevents stale token resolutions from affecting state after\n // a reset. The order is important: check epoch first, then update state.\n if (epoch !== tokenEpoch) {\n // Token is stale (from before a reset), ignore it completely\n return\n }\n // Use Math.max as a defensive measure - pending should never go below 0,\n // but this protects against edge cases where a token might resolve twice\n // or after the component has been reset.\n const newPending = Math.max(0, pending() - 1)\n pending(newPending)\n if (newPending === 0) {\n // Directly render children instead of using switchView\n renderView(props.children ?? null)\n onResolveMaybe()\n }\n },\n err => {\n // Same epoch check - ignore stale tokens\n if (epoch !== tokenEpoch) {\n return\n }\n const newPending = Math.max(0, pending() - 1)\n pending(newPending)\n props.onReject?.(err)\n if (!handleError(err, { source: 'render' }, hostRoot)) {\n throw err\n }\n },\n )\n return true\n }\n\n return false\n })\n\n // Initial render - render children directly\n // Note: This will be called synchronously during component creation.\n // If children suspend, the handler above will be called and switch to fallback.\n renderView(props.children ?? null)\n\n if (props.resetKeys !== undefined) {\n const isGetter =\n typeof props.resetKeys === 'function' && (props.resetKeys as () => unknown).length === 0\n const getter = isGetter ? (props.resetKeys as () => unknown) : undefined\n let prev = isGetter ? getter!() : props.resetKeys\n createEffect(() => {\n const next = getter ? getter() : props.resetKeys\n if (prev !== next) {\n prev = next\n epoch++\n pending(0)\n // Directly render children instead of using switchView\n renderView(props.children ?? null)\n }\n })\n }\n\n return fragment\n}\n"]}
|
|
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 fragment = document.createDocumentFragment()\n const marker = document.createComment('fict:error-boundary')\n fragment.appendChild(marker)\n\n const hostRoot = getCurrentRoot()\n\n let cleanup: (() => void) | undefined\n let activeNodes: Node[] = []\n let renderingFallback = false\n\n let reset = () => {}\n const toView = (err: unknown | null): FictNode | null => {\n if (err != null) {\n return typeof props.fallback === 'function'\n ? (props.fallback as (e: unknown, reset?: () => void) => FictNode)(err, reset)\n : props.fallback\n }\n return props.children ?? null\n }\n\n const renderValue = (value: FictNode | null) => {\n if (cleanup) {\n cleanup()\n cleanup = undefined\n }\n if (activeNodes.length) {\n removeNodes(activeNodes)\n activeNodes = []\n }\n\n if (value == null || value === false) {\n return\n }\n\n const root = createRootContext(hostRoot)\n const prev = pushRoot(root)\n let nodes: Node[] = []\n try {\n const output = createElement(value)\n nodes = toNodeArray(output)\n const parentNode = marker.parentNode as (ParentNode & Node) | null\n if (parentNode) {\n insertNodesBefore(parentNode, nodes, marker)\n }\n } catch (err) {\n popRoot(prev)\n destroyRoot(root)\n // Fall back immediately on render errors, avoid infinite recursion\n if (renderingFallback) {\n throw err\n }\n // nested errors. If fallback rendering also throws, we should NOT reset\n // the flag until we're sure no more recursion is happening.\n renderingFallback = true\n try {\n renderValue(toView(err))\n // Only reset if successful - if renderValue threw, we want to keep\n // renderingFallback = true to prevent infinite recursion\n renderingFallback = false\n props.onError?.(err)\n } catch (fallbackErr) {\n // Fallback rendering failed - keep renderingFallback = true\n // to prevent further attempts, then rethrow\n // If fallback fails, report both errors\n props.onError?.(err)\n throw fallbackErr\n }\n return\n }\n popRoot(prev)\n flushOnMount(root)\n\n cleanup = () => {\n destroyRoot(root)\n removeNodes(nodes)\n }\n activeNodes = nodes\n }\n\n reset = () => {\n renderingFallback = false\n renderValue(toView(null))\n }\n\n renderValue(props.children ?? null)\n\n registerErrorHandler(err => {\n renderValue(toView(err))\n props.onError?.(err)\n return true\n })\n\n if (props.resetKeys !== undefined) {\n const isGetter =\n typeof props.resetKeys === 'function' && (props.resetKeys as () => unknown).length === 0\n const getter = isGetter ? (props.resetKeys as () => unknown) : undefined\n let prev = isGetter ? getter!() : props.resetKeys\n createEffect(() => {\n const next = getter ? getter() : props.resetKeys\n if (prev !== next) {\n prev = next\n renderValue(toView(null))\n }\n })\n }\n\n return fragment\n}\n","import { createElement } from './dom'\nimport { createEffect } from './effect'\nimport {\n createRootContext,\n destroyRoot,\n flushOnMount,\n getCurrentRoot,\n handleError,\n pushRoot,\n popRoot,\n registerSuspenseHandler,\n} from './lifecycle'\nimport { insertNodesBefore, removeNodes, toNodeArray } from './node-ops'\nimport { createSignal } from './signal'\nimport type { BaseProps, FictNode, SuspenseToken } from './types'\n\nexport interface SuspenseProps extends BaseProps {\n fallback: FictNode | ((err?: unknown) => FictNode)\n onResolve?: () => void\n onReject?: (err: unknown) => void\n resetKeys?: unknown | (() => unknown)\n}\n\nexport interface SuspenseHandle {\n token: SuspenseToken\n resolve: () => void\n reject: (err: unknown) => void\n}\n\nexport function createSuspenseToken(): SuspenseHandle {\n let resolve!: () => void\n let reject!: (err: unknown) => void\n const promise = new Promise<void>((res, rej) => {\n resolve = res\n reject = rej\n })\n return {\n token: {\n then: promise.then.bind(promise),\n },\n resolve,\n reject,\n }\n}\n\nconst isThenable = (value: unknown): value is PromiseLike<unknown> =>\n typeof value === 'object' &&\n value !== null &&\n typeof (value as PromiseLike<unknown>).then === 'function'\n\nexport function Suspense(props: SuspenseProps): FictNode {\n const pending = createSignal(0)\n let resolvedOnce = false\n let epoch = 0\n const hostRoot = getCurrentRoot()\n\n const toFallback = (err?: unknown) =>\n typeof props.fallback === 'function'\n ? (props.fallback as (e?: unknown) => FictNode)(err)\n : props.fallback\n\n const renderView = (view: FictNode | null) => {\n if (cleanup) {\n cleanup()\n cleanup = undefined\n }\n if (activeNodes.length) {\n removeNodes(activeNodes)\n activeNodes = []\n }\n\n if (view == null || view === false) {\n return\n }\n\n const root = createRootContext(hostRoot)\n const prev = pushRoot(root)\n let nodes: Node[] = []\n try {\n const output = createElement(view)\n nodes = toNodeArray(output)\n // Suspended view: child threw a suspense token and was handled upstream.\n // Avoid replacing existing fallback content; tear down this attempt.\n const suspendedAttempt =\n root.suspended ||\n (nodes.length > 0 &&\n nodes.every(node => node instanceof Comment && (node as Comment).data === 'fict:suspend'))\n if (suspendedAttempt) {\n popRoot(prev)\n destroyRoot(root)\n return\n }\n const parentNode = marker.parentNode as (ParentNode & Node) | null\n if (parentNode) {\n insertNodesBefore(parentNode, nodes, marker)\n }\n } catch (err) {\n popRoot(prev)\n destroyRoot(root)\n if (!handleError(err, { source: 'render' }, hostRoot)) {\n throw err\n }\n return\n }\n popRoot(prev)\n flushOnMount(root)\n\n cleanup = () => {\n destroyRoot(root)\n removeNodes(nodes)\n }\n activeNodes = nodes\n }\n\n const fragment = document.createDocumentFragment()\n const marker = document.createComment('fict:suspense')\n fragment.appendChild(marker)\n let cleanup: (() => void) | undefined\n let activeNodes: Node[] = []\n\n const onResolveMaybe = () => {\n if (!resolvedOnce) {\n resolvedOnce = true\n props.onResolve?.()\n }\n }\n\n registerSuspenseHandler(token => {\n const tokenEpoch = epoch\n pending(pending() + 1)\n // Directly render fallback instead of using switchView to avoid\n // triggering the effect which would cause duplicate renders\n renderView(toFallback())\n\n const thenable = (token as SuspenseToken).then\n ? (token as SuspenseToken)\n : isThenable(token)\n ? token\n : null\n\n if (thenable) {\n thenable.then(\n () => {\n // This prevents stale token resolutions from affecting state after\n // a reset. The order is important: check epoch first, then update state.\n if (epoch !== tokenEpoch) {\n // Token is stale (from before a reset), ignore it completely\n return\n }\n // Use Math.max as a defensive measure - pending should never go below 0,\n // but this protects against edge cases where a token might resolve twice\n // or after the component has been reset.\n const newPending = Math.max(0, pending() - 1)\n pending(newPending)\n if (newPending === 0) {\n // Directly render children instead of using switchView\n renderView(props.children ?? null)\n onResolveMaybe()\n }\n },\n err => {\n // Same epoch check - ignore stale tokens\n if (epoch !== tokenEpoch) {\n return\n }\n const newPending = Math.max(0, pending() - 1)\n pending(newPending)\n props.onReject?.(err)\n if (!handleError(err, { source: 'render' }, hostRoot)) {\n throw err\n }\n },\n )\n return true\n }\n\n return false\n })\n\n // Initial render - render children directly\n // Note: This will be called synchronously during component creation.\n // If children suspend, the handler above will be called and switch to fallback.\n renderView(props.children ?? null)\n\n if (props.resetKeys !== undefined) {\n const isGetter =\n typeof props.resetKeys === 'function' && (props.resetKeys as () => unknown).length === 0\n const getter = isGetter ? (props.resetKeys as () => unknown) : undefined\n let prev = isGetter ? getter!() : props.resetKeys\n createEffect(() => {\n const next = getter ? getter() : props.resetKeys\n if (prev !== next) {\n prev = next\n epoch++\n pending(0)\n // Directly render children instead of using switchView\n renderView(props.children ?? null)\n }\n })\n }\n\n return fragment\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export { F as Fragment, J as JSX, M as Memo, a as createElement, c as createMemo, k as keyed, m as mergeProps, p as prop, r as render } from './props-
|
|
2
|
-
import { R as RefObject, B as BaseProps, F as FictNode,
|
|
3
|
-
export {
|
|
4
|
-
export { C as Context, F as FictDevtoolsHook, P as ProviderProps, c as createContext, h as hasContext, u as useContext } from './context-
|
|
1
|
+
export { F as Fragment, J as JSX, M as Memo, a as createElement, c as createMemo, k as keyed, m as mergeProps, p as prop, r as render } from './props-XTHYD19o.cjs';
|
|
2
|
+
import { R as RefObject, B as BaseProps, F as FictNode, S as SuspenseToken } from './effect-BpSNEJJz.cjs';
|
|
3
|
+
export { v as ClassProp, C as Cleanup, p as Component, D as DOMElement, E as Effect, x as ErrorInfo, w as EventHandler, n as FictVNode, P as PropsWithChildren, q as Ref, s as RefCallback, t as StyleProp, h as createEffect, m as createPortal, l as createRoot, k as onCleanup, j as onDestroy, o as onMount } from './effect-BpSNEJJz.cjs';
|
|
4
|
+
export { C as Context, F as FictDevtoolsHook, P as ProviderProps, c as createContext, h as hasContext, u as useContext } from './context-CTBE00S_.cjs';
|
|
5
|
+
import './signal-C4ISF17w.cjs';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Create a ref object for DOM element references.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export { F as Fragment, J as JSX, M as Memo, a as createElement, c as createMemo, k as keyed, m as mergeProps, p as prop, r as render } from './props-
|
|
2
|
-
import { R as RefObject, B as BaseProps, F as FictNode,
|
|
3
|
-
export {
|
|
4
|
-
export { C as Context, F as FictDevtoolsHook, P as ProviderProps, c as createContext, h as hasContext, u as useContext } from './context-
|
|
1
|
+
export { F as Fragment, J as JSX, M as Memo, a as createElement, c as createMemo, k as keyed, m as mergeProps, p as prop, r as render } from './props-x-HbI-jX.js';
|
|
2
|
+
import { R as RefObject, B as BaseProps, F as FictNode, S as SuspenseToken } from './effect-BpSNEJJz.js';
|
|
3
|
+
export { v as ClassProp, C as Cleanup, p as Component, D as DOMElement, E as Effect, x as ErrorInfo, w as EventHandler, n as FictVNode, P as PropsWithChildren, q as Ref, s as RefCallback, t as StyleProp, h as createEffect, m as createPortal, l as createRoot, k as onCleanup, j as onDestroy, o as onMount } from './effect-BpSNEJJz.js';
|
|
4
|
+
export { C as Context, F as FictDevtoolsHook, P as ProviderProps, c as createContext, h as hasContext, u as useContext } from './context-lkLhbkFJ.js';
|
|
5
|
+
import './signal-C4ISF17w.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Create a ref object for DOM element references.
|
package/dist/index.dev.js
CHANGED
|
@@ -495,8 +495,10 @@ function createRenderEffect(fn) {
|
|
|
495
495
|
// src/hooks.ts
|
|
496
496
|
var isDev3 = true ? true : typeof process === "undefined" || process.env?.NODE_ENV !== "production";
|
|
497
497
|
var ctxStack = [];
|
|
498
|
+
var preparedContext = null;
|
|
498
499
|
function __fictPushContext() {
|
|
499
|
-
const ctx = { slots: [], cursor: 0 };
|
|
500
|
+
const ctx = preparedContext ?? { slots: [], cursor: 0 };
|
|
501
|
+
preparedContext = null;
|
|
500
502
|
ctxStack.push(ctx);
|
|
501
503
|
return ctx;
|
|
502
504
|
}
|
|
@@ -1673,6 +1675,22 @@ var unitlessList = isDev5 ? [
|
|
|
1673
1675
|
] : ["opacity", "zIndex"];
|
|
1674
1676
|
var UnitlessStyles = new Set(unitlessList);
|
|
1675
1677
|
|
|
1678
|
+
// src/hydration.ts
|
|
1679
|
+
var hydrationStack = [];
|
|
1680
|
+
function withHydration(root, fn) {
|
|
1681
|
+
const owner = root.ownerDocument ?? document;
|
|
1682
|
+
hydrationStack.push({
|
|
1683
|
+
cursor: root.firstChild,
|
|
1684
|
+
boundary: null,
|
|
1685
|
+
owner
|
|
1686
|
+
});
|
|
1687
|
+
try {
|
|
1688
|
+
fn();
|
|
1689
|
+
} finally {
|
|
1690
|
+
hydrationStack.pop();
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
|
|
1676
1694
|
// src/node-ops.ts
|
|
1677
1695
|
function toNodeArray(node) {
|
|
1678
1696
|
try {
|
|
@@ -1816,6 +1834,40 @@ function removeNodes(nodes) {
|
|
|
1816
1834
|
}
|
|
1817
1835
|
}
|
|
1818
1836
|
|
|
1837
|
+
// src/resume.ts
|
|
1838
|
+
var ssrEnabled = false;
|
|
1839
|
+
var resumableEnabled = false;
|
|
1840
|
+
var hydrating = false;
|
|
1841
|
+
var scopeCounter = 0;
|
|
1842
|
+
var scopeRegistry = /* @__PURE__ */ new Map();
|
|
1843
|
+
function __fictIsResumable() {
|
|
1844
|
+
return ssrEnabled || resumableEnabled;
|
|
1845
|
+
}
|
|
1846
|
+
function __fictIsHydrating() {
|
|
1847
|
+
return hydrating;
|
|
1848
|
+
}
|
|
1849
|
+
function __fictRegisterScope(ctx, host, type, props) {
|
|
1850
|
+
if (!__fictIsResumable()) return "";
|
|
1851
|
+
const id = `s${++scopeCounter}`;
|
|
1852
|
+
ctx.scopeId = id;
|
|
1853
|
+
if (type !== void 0) {
|
|
1854
|
+
ctx.scopeType = type;
|
|
1855
|
+
}
|
|
1856
|
+
host.setAttribute("data-fict-s", id);
|
|
1857
|
+
if (type) {
|
|
1858
|
+
host.setAttribute("data-fict-t", type);
|
|
1859
|
+
}
|
|
1860
|
+
const record = { id, ctx, host };
|
|
1861
|
+
if (type !== void 0) {
|
|
1862
|
+
record.type = type;
|
|
1863
|
+
}
|
|
1864
|
+
if (props !== void 0) {
|
|
1865
|
+
record.props = props;
|
|
1866
|
+
}
|
|
1867
|
+
scopeRegistry.set(id, record);
|
|
1868
|
+
return id;
|
|
1869
|
+
}
|
|
1870
|
+
|
|
1819
1871
|
// src/binding.ts
|
|
1820
1872
|
var isDev6 = true ? true : typeof process === "undefined" || process.env?.NODE_ENV !== "production";
|
|
1821
1873
|
function isReactive(value) {
|
|
@@ -2400,14 +2452,22 @@ var nextComponentId = 1;
|
|
|
2400
2452
|
function render(view, container) {
|
|
2401
2453
|
const root = createRootContext();
|
|
2402
2454
|
const prev = pushRoot(root);
|
|
2403
|
-
let dom;
|
|
2455
|
+
let dom = void 0;
|
|
2404
2456
|
try {
|
|
2405
2457
|
const output = view();
|
|
2406
|
-
|
|
2458
|
+
if (__fictIsHydrating()) {
|
|
2459
|
+
withHydration(container, () => {
|
|
2460
|
+
dom = createElement(output);
|
|
2461
|
+
});
|
|
2462
|
+
} else {
|
|
2463
|
+
dom = createElement(output);
|
|
2464
|
+
}
|
|
2407
2465
|
} finally {
|
|
2408
2466
|
popRoot(prev);
|
|
2409
2467
|
}
|
|
2410
|
-
|
|
2468
|
+
if (!__fictIsHydrating()) {
|
|
2469
|
+
container.replaceChildren(dom);
|
|
2470
|
+
}
|
|
2411
2471
|
container.setAttribute("data-fict-fine-grained", "1");
|
|
2412
2472
|
flushOnMount(root);
|
|
2413
2473
|
const teardown = () => {
|
|
@@ -2434,6 +2494,13 @@ function createElementWithContext(node, namespace) {
|
|
|
2434
2494
|
if (node === null || node === void 0 || node === false) {
|
|
2435
2495
|
return document.createTextNode("");
|
|
2436
2496
|
}
|
|
2497
|
+
if (isReactive(node)) {
|
|
2498
|
+
const resolved = node();
|
|
2499
|
+
if (resolved === node) {
|
|
2500
|
+
return document.createTextNode("");
|
|
2501
|
+
}
|
|
2502
|
+
return createElementWithContext(resolved, namespace);
|
|
2503
|
+
}
|
|
2437
2504
|
if (typeof node === "object" && node !== null && !(node instanceof Node)) {
|
|
2438
2505
|
if ("marker" in node) {
|
|
2439
2506
|
const handle = node;
|
|
@@ -2510,6 +2577,27 @@ function createElementWithContext(node, namespace) {
|
|
|
2510
2577
|
});
|
|
2511
2578
|
onCleanup(() => hook.componentUnmount?.(componentId));
|
|
2512
2579
|
}
|
|
2580
|
+
if (__fictIsResumable() && !__fictIsHydrating()) {
|
|
2581
|
+
const content = createElementWithContext(rendered, namespace);
|
|
2582
|
+
const host = namespace === "svg" ? document.createElementNS(SVG_NS, "fict-host") : namespace === "mathml" ? document.createElementNS(MATHML_NS, "fict-host") : document.createElement("fict-host");
|
|
2583
|
+
host.setAttribute("data-fict-host", "");
|
|
2584
|
+
if (namespace === null && host.style) {
|
|
2585
|
+
;
|
|
2586
|
+
host.style.display = "contents";
|
|
2587
|
+
}
|
|
2588
|
+
const meta = vnode.type.__fictMeta;
|
|
2589
|
+
const typeKey = (meta?.id ?? vnode.type.name) || "Anonymous";
|
|
2590
|
+
__fictRegisterScope(ctx, host, typeKey, rawProps);
|
|
2591
|
+
if (meta?.resume) {
|
|
2592
|
+
host.setAttribute("data-fict-h", meta.resume);
|
|
2593
|
+
}
|
|
2594
|
+
if (content instanceof DocumentFragment) {
|
|
2595
|
+
host.append(...Array.from(content.childNodes));
|
|
2596
|
+
} else {
|
|
2597
|
+
host.appendChild(content);
|
|
2598
|
+
}
|
|
2599
|
+
return host;
|
|
2600
|
+
}
|
|
2513
2601
|
return createElementWithContext(rendered, namespace);
|
|
2514
2602
|
} catch (err) {
|
|
2515
2603
|
if (handleSuspend(err)) {
|