@fictjs/runtime 0.10.0 → 0.12.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 +9 -9
- package/dist/advanced.d.cts +3 -3
- package/dist/advanced.d.ts +3 -3
- package/dist/advanced.js +4 -4
- package/dist/{binding-DqxS9ZQf.d.ts → binding-DcnhUSQK.d.ts} +1 -1
- package/dist/{binding-DUEukRxl.d.cts → binding-FRyTeLDn.d.cts} +1 -1
- package/dist/{chunk-DKA2I6ET.js → chunk-2UR2UWE2.js} +3 -3
- package/dist/{chunk-SZLJCQFZ.cjs → chunk-44EQF3AR.cjs} +63 -52
- package/dist/chunk-44EQF3AR.cjs.map +1 -0
- package/dist/{chunk-I4GKKAAY.cjs → chunk-4QGEN5SJ.cjs} +295 -262
- package/dist/chunk-4QGEN5SJ.cjs.map +1 -0
- package/dist/{chunk-V7BC64W2.cjs → chunk-C5IE4WUG.cjs} +8 -8
- package/dist/{chunk-V7BC64W2.cjs.map → chunk-C5IE4WUG.cjs.map} +1 -1
- package/dist/{chunk-F4RVNXOL.js → chunk-DIK33H5U.js} +8 -2
- package/dist/chunk-DIK33H5U.js.map +1 -0
- package/dist/{chunk-2JRPPCG7.js → chunk-FESAXMHT.js} +7 -6
- package/dist/{chunk-2JRPPCG7.js.map → chunk-FESAXMHT.js.map} +1 -1
- package/dist/chunk-FHQZCAAK.cjs +112 -0
- package/dist/chunk-FHQZCAAK.cjs.map +1 -0
- package/dist/{chunk-EQ5E4WOV.cjs → chunk-QNMYVXRL.cjs} +44 -38
- package/dist/chunk-QNMYVXRL.cjs.map +1 -0
- package/dist/{chunk-P4TZLFV6.js → chunk-S63VBIWN.js} +27 -16
- package/dist/chunk-S63VBIWN.js.map +1 -0
- package/dist/{chunk-R6FINS25.js → chunk-WIHNVN6L.js} +106 -73
- package/dist/chunk-WIHNVN6L.js.map +1 -0
- package/dist/{devtools-CMxlJUTx.d.cts → devtools-BtIkN77t.d.cts} +1 -1
- package/dist/{devtools-C4Hgfa-S.d.ts → devtools-D2z4llpA.d.ts} +1 -1
- package/dist/index.cjs +60 -58
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.dev.js +72 -51
- package/dist/index.dev.js.map +1 -1
- package/dist/index.js +13 -11
- package/dist/index.js.map +1 -1
- package/dist/internal-list.cjs +4 -4
- package/dist/internal-list.d.cts +1 -1
- package/dist/internal-list.d.ts +1 -1
- package/dist/internal-list.js +3 -3
- package/dist/internal.cjs +5 -5
- package/dist/internal.d.cts +4 -4
- package/dist/internal.d.ts +4 -4
- package/dist/internal.js +4 -4
- package/dist/{list-BBzsJhrm.d.ts → list-BKM6YOPq.d.ts} +1 -1
- package/dist/{list-_NJCcjl1.d.cts → list-Bi8dDF8Q.d.cts} +1 -1
- package/dist/loader.cjs +28 -26
- package/dist/loader.cjs.map +1 -1
- package/dist/loader.js +11 -9
- package/dist/loader.js.map +1 -1
- package/dist/{props--zJ4ebbT.d.cts → props-9chMyBGb.d.cts} +1 -1
- package/dist/{props-BAGR7j-j.d.ts → props-D1nj2p_3.d.ts} +1 -1
- package/dist/{scope-CuImnvh1.d.ts → scope-BSkhJr0a.d.ts} +1 -1
- package/dist/{scope-Dq5hOu7c.d.cts → scope-Bn3sxem5.d.cts} +1 -1
- package/package.json +1 -1
- package/src/binding.ts +59 -29
- package/src/context.ts +4 -3
- package/src/dom.ts +65 -39
- package/src/error-boundary.ts +5 -5
- package/src/lifecycle.ts +8 -1
- package/src/list-helpers.ts +30 -13
- package/src/loader.ts +10 -8
- package/src/node-ops.ts +8 -5
- package/src/suspense.ts +5 -4
- package/dist/chunk-EQ5E4WOV.cjs.map +0 -1
- package/dist/chunk-F4RVNXOL.js.map +0 -1
- package/dist/chunk-I4GKKAAY.cjs.map +0 -1
- package/dist/chunk-K3DH5SD5.cjs +0 -111
- package/dist/chunk-K3DH5SD5.cjs.map +0 -1
- package/dist/chunk-P4TZLFV6.js.map +0 -1
- package/dist/chunk-R6FINS25.js.map +0 -1
- package/dist/chunk-SZLJCQFZ.cjs.map +0 -1
- /package/dist/{chunk-DKA2I6ET.js.map → chunk-2UR2UWE2.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var _chunkFHQZCAAKcjs = require('./chunk-FHQZCAAK.cjs');
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
@@ -19,7 +19,7 @@ var _chunkK3DH5SD5cjs = require('./chunk-K3DH5SD5.cjs');
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
var
|
|
22
|
+
var _chunk4QGEN5SJcjs = require('./chunk-4QGEN5SJ.cjs');
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
|
|
@@ -40,7 +40,7 @@ var _chunkI4GKKAAYcjs = require('./chunk-I4GKKAAY.cjs');
|
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
|
|
43
|
-
var
|
|
43
|
+
var _chunkQNMYVXRLcjs = require('./chunk-QNMYVXRL.cjs');
|
|
44
44
|
|
|
45
45
|
// src/ref.ts
|
|
46
46
|
function createRef() {
|
|
@@ -49,10 +49,11 @@ function createRef() {
|
|
|
49
49
|
|
|
50
50
|
// src/error-boundary.ts
|
|
51
51
|
function ErrorBoundary(props) {
|
|
52
|
-
const
|
|
53
|
-
const
|
|
52
|
+
const hostRoot = _chunkQNMYVXRLcjs.getCurrentRoot.call(void 0, );
|
|
53
|
+
const markerOwnerDocument = _nullishCoalesce(_optionalChain([hostRoot, 'optionalAccess', _ => _.ownerDocument]), () => ( document));
|
|
54
|
+
const fragment = markerOwnerDocument.createDocumentFragment();
|
|
55
|
+
const marker = markerOwnerDocument.createComment("fict:error-boundary");
|
|
54
56
|
fragment.appendChild(marker);
|
|
55
|
-
const hostRoot = _chunkEQ5E4WOVcjs.getCurrentRoot.call(void 0, );
|
|
56
57
|
let cleanup;
|
|
57
58
|
let activeNodes = [];
|
|
58
59
|
let renderingFallback = false;
|
|
@@ -70,25 +71,25 @@ function ErrorBoundary(props) {
|
|
|
70
71
|
cleanup = void 0;
|
|
71
72
|
}
|
|
72
73
|
if (activeNodes.length) {
|
|
73
|
-
|
|
74
|
+
_chunk4QGEN5SJcjs.removeNodes.call(void 0, activeNodes);
|
|
74
75
|
activeNodes = [];
|
|
75
76
|
}
|
|
76
77
|
if (value == null || value === false) {
|
|
77
78
|
return;
|
|
78
79
|
}
|
|
79
|
-
const root =
|
|
80
|
-
const prev =
|
|
80
|
+
const root = _chunkQNMYVXRLcjs.createRootContext.call(void 0, hostRoot);
|
|
81
|
+
const prev = _chunkQNMYVXRLcjs.pushRoot.call(void 0, root);
|
|
81
82
|
let nodes = [];
|
|
82
83
|
try {
|
|
83
|
-
const output =
|
|
84
|
-
nodes =
|
|
84
|
+
const output = _chunk4QGEN5SJcjs.createElement.call(void 0, value);
|
|
85
|
+
nodes = _chunk4QGEN5SJcjs.toNodeArray.call(void 0, output, markerOwnerDocument);
|
|
85
86
|
const parentNode = marker.parentNode;
|
|
86
87
|
if (parentNode) {
|
|
87
|
-
|
|
88
|
+
_chunk4QGEN5SJcjs.insertNodesBefore.call(void 0, parentNode, nodes, marker);
|
|
88
89
|
}
|
|
89
90
|
} catch (err) {
|
|
90
|
-
|
|
91
|
-
|
|
91
|
+
_chunkQNMYVXRLcjs.popRoot.call(void 0, prev);
|
|
92
|
+
_chunkQNMYVXRLcjs.destroyRoot.call(void 0, root);
|
|
92
93
|
if (renderingFallback) {
|
|
93
94
|
throw err;
|
|
94
95
|
}
|
|
@@ -96,18 +97,18 @@ function ErrorBoundary(props) {
|
|
|
96
97
|
try {
|
|
97
98
|
renderValue(toView(err));
|
|
98
99
|
renderingFallback = false;
|
|
99
|
-
_optionalChain([props, 'access',
|
|
100
|
+
_optionalChain([props, 'access', _2 => _2.onError, 'optionalCall', _3 => _3(err)]);
|
|
100
101
|
} catch (fallbackErr) {
|
|
101
|
-
_optionalChain([props, 'access',
|
|
102
|
+
_optionalChain([props, 'access', _4 => _4.onError, 'optionalCall', _5 => _5(err)]);
|
|
102
103
|
throw fallbackErr;
|
|
103
104
|
}
|
|
104
105
|
return;
|
|
105
106
|
}
|
|
106
|
-
|
|
107
|
-
|
|
107
|
+
_chunkQNMYVXRLcjs.popRoot.call(void 0, prev);
|
|
108
|
+
_chunkQNMYVXRLcjs.flushOnMount.call(void 0, root);
|
|
108
109
|
cleanup = () => {
|
|
109
|
-
|
|
110
|
-
|
|
110
|
+
_chunkQNMYVXRLcjs.destroyRoot.call(void 0, root);
|
|
111
|
+
_chunk4QGEN5SJcjs.removeNodes.call(void 0, nodes);
|
|
111
112
|
};
|
|
112
113
|
activeNodes = nodes;
|
|
113
114
|
};
|
|
@@ -116,16 +117,16 @@ function ErrorBoundary(props) {
|
|
|
116
117
|
renderValue(toView(null));
|
|
117
118
|
};
|
|
118
119
|
renderValue(_nullishCoalesce(props.children, () => ( null)));
|
|
119
|
-
|
|
120
|
+
_chunkQNMYVXRLcjs.registerErrorHandler.call(void 0, (err) => {
|
|
120
121
|
renderValue(toView(err));
|
|
121
|
-
_optionalChain([props, 'access',
|
|
122
|
+
_optionalChain([props, 'access', _6 => _6.onError, 'optionalCall', _7 => _7(err)]);
|
|
122
123
|
return true;
|
|
123
124
|
});
|
|
124
125
|
if (props.resetKeys !== void 0) {
|
|
125
126
|
const isGetter = typeof props.resetKeys === "function" && props.resetKeys.length === 0;
|
|
126
127
|
const getter = isGetter ? props.resetKeys : void 0;
|
|
127
128
|
let prev = isGetter ? getter() : props.resetKeys;
|
|
128
|
-
|
|
129
|
+
_chunkQNMYVXRLcjs.createEffect.call(void 0, () => {
|
|
129
130
|
const next = getter ? getter() : props.resetKeys;
|
|
130
131
|
if (prev !== next) {
|
|
131
132
|
prev = next;
|
|
@@ -154,11 +155,12 @@ function createSuspenseToken() {
|
|
|
154
155
|
}
|
|
155
156
|
var isThenable = (value) => typeof value === "object" && value !== null && typeof value.then === "function";
|
|
156
157
|
function Suspense(props) {
|
|
157
|
-
const streamHooks =
|
|
158
|
-
const pending =
|
|
158
|
+
const streamHooks = _chunkQNMYVXRLcjs.__fictGetSSRStreamHooks.call(void 0, );
|
|
159
|
+
const pending = _chunkQNMYVXRLcjs.signal.call(void 0, 0);
|
|
159
160
|
let resolvedOnce = false;
|
|
160
161
|
let epoch = 0;
|
|
161
|
-
const hostRoot =
|
|
162
|
+
const hostRoot = _chunkQNMYVXRLcjs.getCurrentRoot.call(void 0, );
|
|
163
|
+
const markerOwnerDocument = _nullishCoalesce(_optionalChain([hostRoot, 'optionalAccess', _8 => _8.ownerDocument]), () => ( document));
|
|
162
164
|
const toFallback = (err) => typeof props.fallback === "function" ? props.fallback(err) : props.fallback;
|
|
163
165
|
const renderView = (view) => {
|
|
164
166
|
if (cleanup) {
|
|
@@ -166,63 +168,63 @@ function Suspense(props) {
|
|
|
166
168
|
cleanup = void 0;
|
|
167
169
|
}
|
|
168
170
|
if (activeNodes.length) {
|
|
169
|
-
|
|
171
|
+
_chunk4QGEN5SJcjs.removeNodes.call(void 0, activeNodes);
|
|
170
172
|
activeNodes = [];
|
|
171
173
|
}
|
|
172
174
|
if (view == null || view === false) {
|
|
173
175
|
return;
|
|
174
176
|
}
|
|
175
|
-
const root =
|
|
176
|
-
const prev =
|
|
177
|
+
const root = _chunkQNMYVXRLcjs.createRootContext.call(void 0, hostRoot);
|
|
178
|
+
const prev = _chunkQNMYVXRLcjs.pushRoot.call(void 0, root);
|
|
177
179
|
let nodes = [];
|
|
178
180
|
let boundaryPushed = false;
|
|
179
181
|
try {
|
|
180
182
|
if (streamBoundaryId) {
|
|
181
|
-
|
|
183
|
+
_chunkQNMYVXRLcjs.__fictPushSSRBoundary.call(void 0, streamBoundaryId);
|
|
182
184
|
boundaryPushed = true;
|
|
183
185
|
}
|
|
184
|
-
const output =
|
|
185
|
-
nodes =
|
|
186
|
+
const output = _chunk4QGEN5SJcjs.createElement.call(void 0, view);
|
|
187
|
+
nodes = _chunk4QGEN5SJcjs.toNodeArray.call(void 0, output, markerOwnerDocument);
|
|
186
188
|
const suspendedAttempt = root.suspended || nodes.length > 0 && nodes.every((node) => node instanceof Comment && node.data === "fict:suspend");
|
|
187
189
|
if (suspendedAttempt) {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
+
_chunkQNMYVXRLcjs.popRoot.call(void 0, prev);
|
|
191
|
+
_chunkQNMYVXRLcjs.destroyRoot.call(void 0, root);
|
|
190
192
|
return;
|
|
191
193
|
}
|
|
192
194
|
const parentNode = endMarker.parentNode;
|
|
193
195
|
if (parentNode) {
|
|
194
|
-
|
|
196
|
+
_chunk4QGEN5SJcjs.insertNodesBefore.call(void 0, parentNode, nodes, endMarker);
|
|
195
197
|
}
|
|
196
198
|
} catch (err) {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
if (!
|
|
199
|
+
_chunkQNMYVXRLcjs.popRoot.call(void 0, prev);
|
|
200
|
+
_chunkQNMYVXRLcjs.destroyRoot.call(void 0, root);
|
|
201
|
+
if (!_chunkQNMYVXRLcjs.handleError.call(void 0, err, { source: "render" }, hostRoot)) {
|
|
200
202
|
throw err;
|
|
201
203
|
}
|
|
202
204
|
return;
|
|
203
205
|
} finally {
|
|
204
206
|
if (boundaryPushed) {
|
|
205
|
-
|
|
207
|
+
_chunkQNMYVXRLcjs.__fictPopSSRBoundary.call(void 0, _nullishCoalesce(streamBoundaryId, () => ( void 0)));
|
|
206
208
|
}
|
|
207
209
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
+
_chunkQNMYVXRLcjs.popRoot.call(void 0, prev);
|
|
211
|
+
_chunkQNMYVXRLcjs.flushOnMount.call(void 0, root);
|
|
210
212
|
cleanup = () => {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
+
_chunkQNMYVXRLcjs.destroyRoot.call(void 0, root);
|
|
214
|
+
_chunk4QGEN5SJcjs.removeNodes.call(void 0, nodes);
|
|
213
215
|
};
|
|
214
216
|
activeNodes = nodes;
|
|
215
217
|
};
|
|
216
|
-
const fragment =
|
|
217
|
-
const startMarker =
|
|
218
|
-
const endMarker =
|
|
218
|
+
const fragment = markerOwnerDocument.createDocumentFragment();
|
|
219
|
+
const startMarker = markerOwnerDocument.createComment("fict:suspense-start");
|
|
220
|
+
const endMarker = markerOwnerDocument.createComment("fict:suspense-end");
|
|
219
221
|
fragment.appendChild(startMarker);
|
|
220
222
|
fragment.appendChild(endMarker);
|
|
221
223
|
let cleanup;
|
|
222
224
|
let activeNodes = [];
|
|
223
225
|
let streamBoundaryId = null;
|
|
224
226
|
let streamPending = false;
|
|
225
|
-
if (_optionalChain([streamHooks, 'optionalAccess',
|
|
227
|
+
if (_optionalChain([streamHooks, 'optionalAccess', _9 => _9.registerBoundary])) {
|
|
226
228
|
streamBoundaryId = _nullishCoalesce(streamHooks.registerBoundary(startMarker, endMarker), () => ( null));
|
|
227
229
|
if (streamBoundaryId) {
|
|
228
230
|
startMarker.data = `fict:suspense-start:${streamBoundaryId}`;
|
|
@@ -232,12 +234,12 @@ function Suspense(props) {
|
|
|
232
234
|
const onResolveMaybe = () => {
|
|
233
235
|
if (!resolvedOnce) {
|
|
234
236
|
resolvedOnce = true;
|
|
235
|
-
_optionalChain([props, 'access',
|
|
237
|
+
_optionalChain([props, 'access', _10 => _10.onResolve, 'optionalCall', _11 => _11()]);
|
|
236
238
|
}
|
|
237
239
|
};
|
|
238
|
-
|
|
240
|
+
_chunkQNMYVXRLcjs.registerSuspenseHandler.call(void 0, (token) => {
|
|
239
241
|
const tokenEpoch = epoch;
|
|
240
|
-
if (!streamPending && streamBoundaryId && _optionalChain([streamHooks, 'optionalAccess',
|
|
242
|
+
if (!streamPending && streamBoundaryId && _optionalChain([streamHooks, 'optionalAccess', _12 => _12.boundaryPending])) {
|
|
241
243
|
streamPending = true;
|
|
242
244
|
streamHooks.boundaryPending(streamBoundaryId);
|
|
243
245
|
}
|
|
@@ -254,7 +256,7 @@ function Suspense(props) {
|
|
|
254
256
|
pending(newPending);
|
|
255
257
|
if (newPending === 0) {
|
|
256
258
|
renderView(_nullishCoalesce(props.children, () => ( null)));
|
|
257
|
-
if (streamPending && streamBoundaryId && _optionalChain([streamHooks, 'optionalAccess',
|
|
259
|
+
if (streamPending && streamBoundaryId && _optionalChain([streamHooks, 'optionalAccess', _13 => _13.boundaryResolved])) {
|
|
258
260
|
streamPending = false;
|
|
259
261
|
streamHooks.boundaryResolved(streamBoundaryId);
|
|
260
262
|
}
|
|
@@ -269,19 +271,19 @@ function Suspense(props) {
|
|
|
269
271
|
pending(newPending);
|
|
270
272
|
let rejectionError = err;
|
|
271
273
|
try {
|
|
272
|
-
_optionalChain([props, 'access',
|
|
274
|
+
_optionalChain([props, 'access', _14 => _14.onReject, 'optionalCall', _15 => _15(err)]);
|
|
273
275
|
} catch (callbackError) {
|
|
274
276
|
rejectionError = callbackError;
|
|
275
277
|
}
|
|
276
|
-
const handled =
|
|
278
|
+
const handled = _chunkQNMYVXRLcjs.handleError.call(void 0, rejectionError, { source: "render" }, hostRoot);
|
|
277
279
|
if (!handled) {
|
|
278
|
-
if (_optionalChain([streamHooks, 'optionalAccess',
|
|
280
|
+
if (_optionalChain([streamHooks, 'optionalAccess', _16 => _16.onError])) {
|
|
279
281
|
streamHooks.onError(rejectionError, _nullishCoalesce(streamBoundaryId, () => ( void 0)));
|
|
280
282
|
return;
|
|
281
283
|
}
|
|
282
284
|
throw rejectionError;
|
|
283
285
|
}
|
|
284
|
-
if (newPending === 0 && streamPending && streamBoundaryId && _optionalChain([streamHooks, 'optionalAccess',
|
|
286
|
+
if (newPending === 0 && streamPending && streamBoundaryId && _optionalChain([streamHooks, 'optionalAccess', _17 => _17.boundaryResolved])) {
|
|
285
287
|
streamPending = false;
|
|
286
288
|
streamHooks.boundaryResolved(streamBoundaryId);
|
|
287
289
|
}
|
|
@@ -296,14 +298,14 @@ function Suspense(props) {
|
|
|
296
298
|
const isGetter = typeof props.resetKeys === "function" && props.resetKeys.length === 0;
|
|
297
299
|
const getter = isGetter ? props.resetKeys : void 0;
|
|
298
300
|
let prev = isGetter ? getter() : props.resetKeys;
|
|
299
|
-
|
|
301
|
+
_chunkQNMYVXRLcjs.createEffect.call(void 0, () => {
|
|
300
302
|
const next = getter ? getter() : props.resetKeys;
|
|
301
303
|
if (prev !== next) {
|
|
302
304
|
prev = next;
|
|
303
305
|
epoch++;
|
|
304
306
|
pending(0);
|
|
305
307
|
renderView(_nullishCoalesce(props.children, () => ( null)));
|
|
306
|
-
if (streamPending && streamBoundaryId && _optionalChain([streamHooks, 'optionalAccess',
|
|
308
|
+
if (streamPending && streamBoundaryId && _optionalChain([streamHooks, 'optionalAccess', _18 => _18.boundaryResolved])) {
|
|
307
309
|
streamPending = false;
|
|
308
310
|
streamHooks.boundaryResolved(streamBoundaryId);
|
|
309
311
|
}
|
|
@@ -338,5 +340,5 @@ function Suspense(props) {
|
|
|
338
340
|
|
|
339
341
|
|
|
340
342
|
|
|
341
|
-
exports.ErrorBoundary = ErrorBoundary; exports.Fragment =
|
|
343
|
+
exports.ErrorBoundary = ErrorBoundary; exports.Fragment = _chunk4QGEN5SJcjs.Fragment; exports.Suspense = Suspense; exports.batch = _chunk4QGEN5SJcjs.batch; exports.createContext = _chunkFHQZCAAKcjs.createContext; exports.createEffect = _chunkQNMYVXRLcjs.createEffect; exports.createElement = _chunk4QGEN5SJcjs.createElement; exports.createMemo = _chunkQNMYVXRLcjs.createMemo; exports.createPortal = _chunk4QGEN5SJcjs.createPortal; exports.createRef = createRef; exports.createRoot = _chunkQNMYVXRLcjs.createRoot; exports.createSuspenseToken = createSuspenseToken; exports.hasContext = _chunkFHQZCAAKcjs.hasContext; exports.keyed = _chunk4QGEN5SJcjs.keyed; exports.mergeProps = _chunk4QGEN5SJcjs.mergeProps; exports.onCleanup = _chunkQNMYVXRLcjs.onCleanup; exports.onDestroy = _chunkQNMYVXRLcjs.onDestroy; exports.onMount = _chunkQNMYVXRLcjs.onMount; exports.prop = _chunk4QGEN5SJcjs.prop; exports.render = _chunk4QGEN5SJcjs.render; exports.startTransition = _chunk4QGEN5SJcjs.startTransition; exports.untrack = _chunk4QGEN5SJcjs.untrack; exports.useContext = _chunkFHQZCAAKcjs.useContext; exports.useDeferredValue = _chunk4QGEN5SJcjs.useDeferredValue; exports.useTransition = _chunk4QGEN5SJcjs.useTransition;
|
|
342
344
|
//# 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":"AAAA;AACE;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACA;ACtBO,SAAS,SAAA,CAAA,EAA2D;AACzE,EAAA,OAAO,EAAE,OAAA,EAAS,KAAK,CAAA;AACzB;ADwBA;AACA;AE7BO,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,SAAA,EAAW,8CAAA,CAAe;AAEhC,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI,YAAA,EAAsB,CAAC,CAAA;AAC3B,EAAA,IAAI,kBAAA,EAAoB,KAAA;AAExB,EAAA,IAAI,MAAA,EAAQ,CAAA,EAAA,GAAM;AAAA,EAAC,CAAA;AACnB,EAAA,MAAM,OAAA,EAAS,CAAC,GAAA,EAAA,GAAyC;AACvD,IAAA,GAAA,CAAI,IAAA,GAAO,IAAA,EAAM;AACf,MAAA,OAAO,OAAO,KAAA,CAAM,SAAA,IAAa,WAAA,EAC5B,KAAA,CAAM,QAAA,CAA0D,GAAA,EAAK,KAAK,EAAA,EAC3E,KAAA,CAAM,QAAA;AAAA,IACZ;AACA,IAAA,wBAAO,KAAA,CAAM,QAAA,UAAY,MAAA;AAAA,EAC3B,CAAA;AAEA,EAAA,MAAM,YAAA,EAAc,CAAC,KAAA,EAAA,GAA2B;AAC9C,IAAA,GAAA,CAAI,OAAA,EAAS;AACX,MAAA,OAAA,CAAQ,CAAA;AACR,MAAA,QAAA,EAAU,KAAA,CAAA;AAAA,IACZ;AACA,IAAA,GAAA,CAAI,WAAA,CAAY,MAAA,EAAQ;AACtB,MAAA,2CAAA,WAAuB,CAAA;AACvB,MAAA,YAAA,EAAc,CAAC,CAAA;AAAA,IACjB;AAEA,IAAA,GAAA,CAAI,MAAA,GAAS,KAAA,GAAQ,MAAA,IAAU,KAAA,EAAO;AACpC,MAAA,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,KAAA,EAAO,iDAAA,QAA0B,CAAA;AACvC,IAAA,MAAM,KAAA,EAAO,wCAAA,IAAa,CAAA;AAC1B,IAAA,IAAI,MAAA,EAAgB,CAAC,CAAA;AACrB,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,EAAS,6CAAA,KAAmB,CAAA;AAClC,MAAA,MAAA,EAAQ,2CAAA,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,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,MAAA,EAAQ,CAAA,EAAA,GAAM;AACZ,IAAA,kBAAA,EAAoB,KAAA;AACpB,IAAA,WAAA,CAAY,MAAA,CAAO,IAAI,CAAC,CAAA;AAAA,EAC1B,CAAA;AAEA,EAAA,WAAA,kBAAY,KAAA,CAAM,QAAA,UAAY,MAAI,CAAA;AAElC,EAAA,oDAAA,CAAqB,GAAA,EAAA,GAAO;AAC1B,IAAA,WAAA,CAAY,MAAA,CAAO,GAAG,CAAC,CAAA;AACvB,oBAAA,KAAA,qBAAM,OAAA,0BAAA,CAAU,GAAG,GAAA;AACnB,IAAA,OAAO,IAAA;AAAA,EACT,CAAC,CAAA;AAED,EAAA,GAAA,CAAI,KAAA,CAAM,UAAA,IAAc,KAAA,CAAA,EAAW;AACjC,IAAA,MAAM,SAAA,EACJ,OAAO,KAAA,CAAM,UAAA,IAAc,WAAA,GAAe,KAAA,CAAM,SAAA,CAA4B,OAAA,IAAW,CAAA;AACzF,IAAA,MAAM,OAAA,EAAS,SAAA,EAAY,KAAA,CAAM,UAAA,EAA8B,KAAA,CAAA;AAC/D,IAAA,IAAI,KAAA,EAAO,SAAA,EAAW,MAAA,CAAQ,EAAA,EAAI,KAAA,CAAM,SAAA;AACxC,IAAA,4CAAA,CAAa,EAAA,GAAM;AACjB,MAAA,MAAM,KAAA,EAAO,OAAA,EAAS,MAAA,CAAO,EAAA,EAAI,KAAA,CAAM,SAAA;AACvC,MAAA,GAAA,CAAI,KAAA,IAAS,IAAA,EAAM;AACjB,QAAA,KAAA,EAAO,IAAA;AACP,QAAA,WAAA,CAAY,MAAA,CAAO,IAAI,CAAC,CAAA;AAAA,MAC1B;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,QAAA;AACT;AFSA;AACA;AG5GO,SAAS,mBAAA,CAAA,EAAsC;AACpD,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI,MAAA;AACJ,EAAA,MAAM,QAAA,EAAU,IAAI,OAAA,CAAc,CAAC,GAAA,EAAK,GAAA,EAAA,GAAQ;AAC9C,IAAA,QAAA,EAAU,GAAA;AACV,IAAA,OAAA,EAAS,GAAA;AAAA,EACX,CAAC,CAAA;AACD,EAAA,OAAO;AAAA,IACL,KAAA,EAAO;AAAA,MACL,IAAA,EAAM,OAAA,CAAQ,IAAA,CAAK,IAAA,CAAK,OAAO;AAAA,IACjC,CAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,EACF,CAAA;AACF;AAEA,IAAM,WAAA,EAAa,CAAC,KAAA,EAAA,GAClB,OAAO,MAAA,IAAU,SAAA,GACjB,MAAA,IAAU,KAAA,GACV,OAAQ,KAAA,CAA+B,KAAA,IAAS,UAAA;AAE3C,SAAS,QAAA,CAAS,KAAA,EAAgC;AACvD,EAAA,MAAM,YAAA,EAAc,uDAAA,CAAwB;AAC5C,EAAA,MAAM,QAAA,EAAU,sCAAA,CAAc,CAAA;AAC9B,EAAA,IAAI,aAAA,EAAe,KAAA;AACnB,EAAA,IAAI,MAAA,EAAQ,CAAA;AACZ,EAAA,MAAM,SAAA,EAAW,8CAAA,CAAe;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,GAAA,CAAI,OAAA,EAAS;AACX,MAAA,OAAA,CAAQ,CAAA;AACR,MAAA,QAAA,EAAU,KAAA,CAAA;AAAA,IACZ;AACA,IAAA,GAAA,CAAI,WAAA,CAAY,MAAA,EAAQ;AACtB,MAAA,2CAAA,WAAuB,CAAA;AACvB,MAAA,YAAA,EAAc,CAAC,CAAA;AAAA,IACjB;AAEA,IAAA,GAAA,CAAI,KAAA,GAAQ,KAAA,GAAQ,KAAA,IAAS,KAAA,EAAO;AAClC,MAAA,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,KAAA,EAAO,iDAAA,QAA0B,CAAA;AACvC,IAAA,MAAM,KAAA,EAAO,wCAAA,IAAa,CAAA;AAC1B,IAAA,IAAI,MAAA,EAAgB,CAAC,CAAA;AACrB,IAAA,IAAI,eAAA,EAAiB,KAAA;AACrB,IAAA,IAAI;AACF,MAAA,GAAA,CAAI,gBAAA,EAAkB;AACpB,QAAA,qDAAA,gBAAsC,CAAA;AACtC,QAAA,eAAA,EAAiB,IAAA;AAAA,MACnB;AACA,MAAA,MAAM,OAAA,EAAS,6CAAA,IAAkB,CAAA;AACjC,MAAA,MAAA,EAAQ,2CAAA,MAAkB,CAAA;AAG1B,MAAA,MAAM,iBAAA,EACJ,IAAA,CAAK,UAAA,GACJ,KAAA,CAAM,OAAA,EAAS,EAAA,GACd,KAAA,CAAM,KAAA,CAAM,CAAA,IAAA,EAAA,GAAQ,KAAA,WAAgB,QAAA,GAAY,IAAA,CAAiB,KAAA,IAAS,cAAc,CAAA;AAC5F,MAAA,GAAA,CAAI,gBAAA,EAAkB;AACpB,QAAA,uCAAA,IAAY,CAAA;AACZ,QAAA,2CAAA,IAAgB,CAAA;AAChB,QAAA,MAAA;AAAA,MACF;AACA,MAAA,MAAM,WAAA,EAAa,SAAA,CAAU,UAAA;AAC7B,MAAA,GAAA,CAAI,UAAA,EAAY;AACd,QAAA,iDAAA,UAAkB,EAAY,KAAA,EAAO,SAAS,CAAA;AAAA,MAChD;AAAA,IACF,EAAA,MAAA,CAAS,GAAA,EAAK;AACZ,MAAA,uCAAA,IAAY,CAAA;AACZ,MAAA,2CAAA,IAAgB,CAAA;AAChB,MAAA,GAAA,CAAI,CAAC,2CAAA,GAAY,EAAK,EAAE,MAAA,EAAQ,SAAS,CAAA,EAAG,QAAQ,CAAA,EAAG;AACrD,QAAA,MAAM,GAAA;AAAA,MACR;AACA,MAAA,MAAA;AAAA,IACF,EAAA,QAAE;AACA,MAAA,GAAA,CAAI,cAAA,EAAgB;AAClB,QAAA,oDAAA,iBAAqB,gBAAA,UAAoB,KAAA,GAAS,CAAA;AAAA,MACpD;AAAA,IACF;AACA,IAAA,uCAAA,IAAY,CAAA;AACZ,IAAA,4CAAA,IAAiB,CAAA;AAEjB,IAAA,QAAA,EAAU,CAAA,EAAA,GAAM;AACd,MAAA,2CAAA,IAAgB,CAAA;AAChB,MAAA,2CAAA,KAAiB,CAAA;AAAA,IACnB,CAAA;AACA,IAAA,YAAA,EAAc,KAAA;AAAA,EAChB,CAAA;AAEA,EAAA,MAAM,SAAA,EAAW,QAAA,CAAS,sBAAA,CAAuB,CAAA;AACjD,EAAA,MAAM,YAAA,EAAc,QAAA,CAAS,aAAA,CAAc,qBAAqB,CAAA;AAChE,EAAA,MAAM,UAAA,EAAY,QAAA,CAAS,aAAA,CAAc,mBAAmB,CAAA;AAC5D,EAAA,QAAA,CAAS,WAAA,CAAY,WAAW,CAAA;AAChC,EAAA,QAAA,CAAS,WAAA,CAAY,SAAS,CAAA;AAC9B,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI,YAAA,EAAsB,CAAC,CAAA;AAC3B,EAAA,IAAI,iBAAA,EAAkC,IAAA;AACtC,EAAA,IAAI,cAAA,EAAgB,KAAA;AAEpB,EAAA,GAAA,iBAAI,WAAA,6BAAa,kBAAA,EAAkB;AACjC,IAAA,iBAAA,mBAAmB,WAAA,CAAY,gBAAA,CAAiB,WAAA,EAAa,SAAS,CAAA,UAAK,MAAA;AAC3E,IAAA,GAAA,CAAI,gBAAA,EAAkB;AACpB,MAAA,WAAA,CAAY,KAAA,EAAO,CAAA,oBAAA,EAAuB,gBAAgB,CAAA,CAAA;AACJ,MAAA;AACxD,IAAA;AACF,EAAA;AAE6B,EAAA;AACR,IAAA;AACF,MAAA;AACG,sBAAA;AACpB,IAAA;AACF,EAAA;AAEiC,EAAA;AACZ,IAAA;AACoC,IAAA;AACrC,MAAA;AAC4B,MAAA;AAC9C,IAAA;AACqB,IAAA;AAGE,IAAA;AAKjB,IAAA;AAGQ,IAAA;AACH,MAAA;AACD,QAAA;AAGsB,UAAA;AAExB,YAAA;AACF,UAAA;AAI4C,UAAA;AAC1B,UAAA;AACI,UAAA;AAEa,YAAA;AACQ,YAAA;AACvB,cAAA;AAC6B,cAAA;AAC/C,YAAA;AACe,YAAA;AACjB,UAAA;AACF,QAAA;AACO,QAAA;AAEqB,UAAA;AACxB,YAAA;AACF,UAAA;AAC4C,UAAA;AAC1B,UAAA;AACG,UAAA;AACjB,UAAA;AACkB,4BAAA;AACE,UAAA;AACL,YAAA;AACnB,UAAA;AAEsD,UAAA;AACxC,UAAA;AACc,YAAA;AACY,cAAA;AACpC,cAAA;AACF,YAAA;AACM,YAAA;AACR,UAAA;AAIE,UAAA;AAGgB,YAAA;AAC6B,YAAA;AAC/C,UAAA;AACF,QAAA;AACF,MAAA;AACO,MAAA;AACT,IAAA;AAEO,IAAA;AACR,EAAA;AAKgC,EAAA;AAEE,EAAA;AAEW,IAAA;AACmB,IAAA;AACvB,IAAA;AACrB,IAAA;AACsB,MAAA;AACpB,MAAA;AACV,QAAA;AACP,QAAA;AACS,QAAA;AAEwB,QAAA;AACqB,QAAA;AACpC,UAAA;AAC6B,UAAA;AAC/C,QAAA;AACF,MAAA;AACD,IAAA;AACH,EAAA;AAEO,EAAA;AACT;AHyDiE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/work/fict/fict/packages/runtime/dist/index.cjs","sourcesContent":[null,"import type { RefObject } from './types'\n\n/**\n * Create a ref object for DOM element references.\n *\n * @returns A ref object with a `current` property initialized to `null`\n *\n * @example\n * ```tsx\n * import { createRef } from 'fict'\n *\n * function Component() {\n * const inputRef = createRef<HTMLInputElement>()\n *\n * $effect(() => {\n * inputRef.current?.focus()\n * })\n *\n * return <input ref={inputRef} />\n * }\n * ```\n */\nexport function createRef<T extends Element = HTMLElement>(): RefObject<T> {\n return { current: null }\n}\n","import { createElement } from './dom'\nimport { createEffect } from './effect'\nimport {\n createRootContext,\n destroyRoot,\n flushOnMount,\n getCurrentRoot,\n pushRoot,\n popRoot,\n registerErrorHandler,\n} 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 { __fictGetSSRStreamHooks, __fictPopSSRBoundary, __fictPushSSRBoundary } from './ssr-stream'\nimport type { BaseProps, FictNode, SuspenseToken } from './types'\n\nexport interface SuspenseProps extends BaseProps {\n fallback: FictNode | ((err?: unknown) => FictNode)\n onResolve?: () => void\n onReject?: (err: unknown) => void\n resetKeys?: unknown | (() => unknown)\n}\n\nexport interface SuspenseHandle {\n token: SuspenseToken\n resolve: () => void\n reject: (err: unknown) => void\n}\n\nexport function createSuspenseToken(): SuspenseHandle {\n let resolve!: () => void\n let reject!: (err: unknown) => void\n const promise = new Promise<void>((res, rej) => {\n resolve = res\n reject = rej\n })\n return {\n token: {\n then: promise.then.bind(promise),\n },\n resolve,\n reject,\n }\n}\n\nconst isThenable = (value: unknown): value is PromiseLike<unknown> =>\n typeof value === 'object' &&\n value !== null &&\n typeof (value as PromiseLike<unknown>).then === 'function'\n\nexport function Suspense(props: SuspenseProps): FictNode {\n const streamHooks = __fictGetSSRStreamHooks()\n const pending = createSignal(0)\n let resolvedOnce = false\n let epoch = 0\n const hostRoot = getCurrentRoot()\n\n const toFallback = (err?: unknown) =>\n typeof props.fallback === 'function'\n ? (props.fallback as (e?: unknown) => FictNode)(err)\n : props.fallback\n\n const renderView = (view: FictNode | null) => {\n if (cleanup) {\n cleanup()\n cleanup = undefined\n }\n if (activeNodes.length) {\n removeNodes(activeNodes)\n activeNodes = []\n }\n\n if (view == null || view === false) {\n return\n }\n\n const root = createRootContext(hostRoot)\n const prev = pushRoot(root)\n let nodes: Node[] = []\n let boundaryPushed = false\n try {\n if (streamBoundaryId) {\n __fictPushSSRBoundary(streamBoundaryId)\n boundaryPushed = true\n }\n const output = createElement(view)\n nodes = toNodeArray(output)\n // Suspended view: child threw a suspense token and was handled upstream.\n // Avoid replacing existing fallback content; tear down this attempt.\n const suspendedAttempt =\n root.suspended ||\n (nodes.length > 0 &&\n nodes.every(node => node instanceof Comment && (node as Comment).data === 'fict:suspend'))\n if (suspendedAttempt) {\n popRoot(prev)\n destroyRoot(root)\n return\n }\n const parentNode = endMarker.parentNode as (ParentNode & Node) | null\n if (parentNode) {\n insertNodesBefore(parentNode, nodes, endMarker)\n }\n } catch (err) {\n popRoot(prev)\n destroyRoot(root)\n if (!handleError(err, { source: 'render' }, hostRoot)) {\n throw err\n }\n return\n } finally {\n if (boundaryPushed) {\n __fictPopSSRBoundary(streamBoundaryId ?? undefined)\n }\n }\n popRoot(prev)\n flushOnMount(root)\n\n cleanup = () => {\n destroyRoot(root)\n removeNodes(nodes)\n }\n activeNodes = nodes\n }\n\n const fragment = document.createDocumentFragment()\n const startMarker = document.createComment('fict:suspense-start')\n const endMarker = document.createComment('fict:suspense-end')\n fragment.appendChild(startMarker)\n fragment.appendChild(endMarker)\n let cleanup: (() => void) | undefined\n let activeNodes: Node[] = []\n let streamBoundaryId: string | null = null\n let streamPending = false\n\n if (streamHooks?.registerBoundary) {\n streamBoundaryId = streamHooks.registerBoundary(startMarker, endMarker) ?? null\n if (streamBoundaryId) {\n startMarker.data = `fict:suspense-start:${streamBoundaryId}`\n endMarker.data = `fict:suspense-end:${streamBoundaryId}`\n }\n }\n\n const onResolveMaybe = () => {\n if (!resolvedOnce) {\n resolvedOnce = true\n props.onResolve?.()\n }\n }\n\n registerSuspenseHandler(token => {\n const tokenEpoch = epoch\n if (!streamPending && streamBoundaryId && streamHooks?.boundaryPending) {\n streamPending = true\n streamHooks.boundaryPending(streamBoundaryId)\n }\n pending(pending() + 1)\n // Directly render fallback instead of using switchView to avoid\n // triggering the effect which would cause duplicate renders\n renderView(toFallback())\n\n const thenable = (token as SuspenseToken).then\n ? (token as SuspenseToken)\n : isThenable(token)\n ? token\n : null\n\n if (thenable) {\n thenable.then(\n () => {\n // This prevents stale token resolutions from affecting state after\n // a reset. The order is important: check epoch first, then update state.\n if (epoch !== tokenEpoch) {\n // Token is stale (from before a reset), ignore it completely\n return\n }\n // Use Math.max as a defensive measure - pending should never go below 0,\n // but this protects against edge cases where a token might resolve twice\n // or after the component has been reset.\n const newPending = Math.max(0, pending() - 1)\n pending(newPending)\n if (newPending === 0) {\n // Directly render children instead of using switchView\n renderView(props.children ?? null)\n if (streamPending && streamBoundaryId && streamHooks?.boundaryResolved) {\n streamPending = false\n streamHooks.boundaryResolved(streamBoundaryId)\n }\n onResolveMaybe()\n }\n },\n err => {\n // Same epoch check - ignore stale tokens\n if (epoch !== tokenEpoch) {\n return\n }\n const newPending = Math.max(0, pending() - 1)\n pending(newPending)\n let rejectionError = err\n try {\n props.onReject?.(err)\n } catch (callbackError) {\n rejectionError = callbackError\n }\n\n const handled = handleError(rejectionError, { source: 'render' }, hostRoot)\n if (!handled) {\n if (streamHooks?.onError) {\n streamHooks.onError(rejectionError, streamBoundaryId ?? undefined)\n return\n }\n throw rejectionError\n }\n if (\n newPending === 0 &&\n streamPending &&\n streamBoundaryId &&\n streamHooks?.boundaryResolved\n ) {\n streamPending = false\n streamHooks.boundaryResolved(streamBoundaryId)\n }\n },\n )\n return true\n }\n\n return false\n })\n\n // Initial render - render children directly\n // Note: This will be called synchronously during component creation.\n // If children suspend, the handler above will be called and switch to fallback.\n renderView(props.children ?? null)\n\n if (props.resetKeys !== undefined) {\n const isGetter =\n typeof props.resetKeys === 'function' && (props.resetKeys as () => unknown).length === 0\n const getter = isGetter ? (props.resetKeys as () => unknown) : undefined\n let prev = isGetter ? getter!() : props.resetKeys\n createEffect(() => {\n const next = getter ? getter() : props.resetKeys\n if (prev !== next) {\n prev = next\n epoch++\n pending(0)\n // Directly render children instead of using switchView\n renderView(props.children ?? null)\n if (streamPending && streamBoundaryId && streamHooks?.boundaryResolved) {\n streamPending = false\n streamHooks.boundaryResolved(streamBoundaryId)\n }\n }\n })\n }\n\n return fragment\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/fict/fict/packages/runtime/dist/index.cjs","../src/ref.ts","../src/error-boundary.ts","../src/suspense.ts"],"names":[],"mappings":"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","file":"/home/runner/work/fict/fict/packages/runtime/dist/index.cjs","sourcesContent":[null,"import type { RefObject } from './types'\n\n/**\n * Create a ref object for DOM element references.\n *\n * @returns A ref object with a `current` property initialized to `null`\n *\n * @example\n * ```tsx\n * import { createRef } from 'fict'\n *\n * function Component() {\n * const inputRef = createRef<HTMLInputElement>()\n *\n * $effect(() => {\n * inputRef.current?.focus()\n * })\n *\n * return <input ref={inputRef} />\n * }\n * ```\n */\nexport function createRef<T extends Element = HTMLElement>(): RefObject<T> {\n return { current: null }\n}\n","import { createElement } from './dom'\nimport { createEffect } from './effect'\nimport {\n createRootContext,\n destroyRoot,\n flushOnMount,\n getCurrentRoot,\n pushRoot,\n popRoot,\n registerErrorHandler,\n} from './lifecycle'\nimport { insertNodesBefore, removeNodes, toNodeArray } from './node-ops'\nimport type { BaseProps, FictNode } from './types'\n\ninterface ErrorBoundaryProps extends BaseProps {\n fallback: FictNode | ((err: unknown, reset?: () => void) => FictNode)\n onError?: (err: unknown) => void\n resetKeys?: unknown | (() => unknown)\n}\n\nexport function ErrorBoundary(props: ErrorBoundaryProps): FictNode {\n const hostRoot = getCurrentRoot()\n const markerOwnerDocument = hostRoot?.ownerDocument ?? document\n const fragment = markerOwnerDocument.createDocumentFragment()\n const marker = markerOwnerDocument.createComment('fict:error-boundary')\n fragment.appendChild(marker)\n\n let cleanup: (() => void) | undefined\n let activeNodes: Node[] = []\n let renderingFallback = false\n\n let reset = () => {}\n const toView = (err: unknown | null): FictNode | null => {\n if (err != null) {\n return typeof props.fallback === 'function'\n ? (props.fallback as (e: unknown, reset?: () => void) => FictNode)(err, reset)\n : props.fallback\n }\n return props.children ?? null\n }\n\n const renderValue = (value: FictNode | null) => {\n if (cleanup) {\n cleanup()\n cleanup = undefined\n }\n if (activeNodes.length) {\n removeNodes(activeNodes)\n activeNodes = []\n }\n\n if (value == null || value === false) {\n return\n }\n\n const root = createRootContext(hostRoot)\n const prev = pushRoot(root)\n let nodes: Node[] = []\n try {\n const output = createElement(value)\n nodes = toNodeArray(output, markerOwnerDocument)\n const parentNode = marker.parentNode as (ParentNode & Node) | null\n if (parentNode) {\n insertNodesBefore(parentNode, nodes, marker)\n }\n } catch (err) {\n popRoot(prev)\n destroyRoot(root)\n // Fall back immediately on render errors, avoid infinite recursion\n if (renderingFallback) {\n throw err\n }\n // nested errors. If fallback rendering also throws, we should NOT reset\n // the flag until we're sure no more recursion is happening.\n renderingFallback = true\n try {\n renderValue(toView(err))\n // Only reset if successful - if renderValue threw, we want to keep\n // renderingFallback = true to prevent infinite recursion\n renderingFallback = false\n props.onError?.(err)\n } catch (fallbackErr) {\n // Fallback rendering failed - keep renderingFallback = true\n // to prevent further attempts, then rethrow\n // If fallback fails, report both errors\n props.onError?.(err)\n throw fallbackErr\n }\n return\n }\n popRoot(prev)\n flushOnMount(root)\n\n cleanup = () => {\n destroyRoot(root)\n removeNodes(nodes)\n }\n activeNodes = nodes\n }\n\n reset = () => {\n renderingFallback = false\n renderValue(toView(null))\n }\n\n renderValue(props.children ?? null)\n\n registerErrorHandler(err => {\n renderValue(toView(err))\n props.onError?.(err)\n return true\n })\n\n if (props.resetKeys !== undefined) {\n const isGetter =\n typeof props.resetKeys === 'function' && (props.resetKeys as () => unknown).length === 0\n const getter = isGetter ? (props.resetKeys as () => unknown) : undefined\n let prev = isGetter ? getter!() : props.resetKeys\n createEffect(() => {\n const next = getter ? getter() : props.resetKeys\n if (prev !== next) {\n prev = next\n renderValue(toView(null))\n }\n })\n }\n\n return fragment\n}\n","import { createElement } from './dom'\nimport { createEffect } from './effect'\nimport {\n createRootContext,\n destroyRoot,\n flushOnMount,\n getCurrentRoot,\n handleError,\n pushRoot,\n popRoot,\n registerSuspenseHandler,\n} from './lifecycle'\nimport { insertNodesBefore, removeNodes, toNodeArray } from './node-ops'\nimport { createSignal } from './signal'\nimport { __fictGetSSRStreamHooks, __fictPopSSRBoundary, __fictPushSSRBoundary } from './ssr-stream'\nimport type { BaseProps, FictNode, SuspenseToken } from './types'\n\nexport interface SuspenseProps extends BaseProps {\n fallback: FictNode | ((err?: unknown) => FictNode)\n onResolve?: () => void\n onReject?: (err: unknown) => void\n resetKeys?: unknown | (() => unknown)\n}\n\nexport interface SuspenseHandle {\n token: SuspenseToken\n resolve: () => void\n reject: (err: unknown) => void\n}\n\nexport function createSuspenseToken(): SuspenseHandle {\n let resolve!: () => void\n let reject!: (err: unknown) => void\n const promise = new Promise<void>((res, rej) => {\n resolve = res\n reject = rej\n })\n return {\n token: {\n then: promise.then.bind(promise),\n },\n resolve,\n reject,\n }\n}\n\nconst isThenable = (value: unknown): value is PromiseLike<unknown> =>\n typeof value === 'object' &&\n value !== null &&\n typeof (value as PromiseLike<unknown>).then === 'function'\n\nexport function Suspense(props: SuspenseProps): FictNode {\n const streamHooks = __fictGetSSRStreamHooks()\n const pending = createSignal(0)\n let resolvedOnce = false\n let epoch = 0\n const hostRoot = getCurrentRoot()\n const markerOwnerDocument = hostRoot?.ownerDocument ?? document\n\n const toFallback = (err?: unknown) =>\n typeof props.fallback === 'function'\n ? (props.fallback as (e?: unknown) => FictNode)(err)\n : props.fallback\n\n const renderView = (view: FictNode | null) => {\n if (cleanup) {\n cleanup()\n cleanup = undefined\n }\n if (activeNodes.length) {\n removeNodes(activeNodes)\n activeNodes = []\n }\n\n if (view == null || view === false) {\n return\n }\n\n const root = createRootContext(hostRoot)\n const prev = pushRoot(root)\n let nodes: Node[] = []\n let boundaryPushed = false\n try {\n if (streamBoundaryId) {\n __fictPushSSRBoundary(streamBoundaryId)\n boundaryPushed = true\n }\n const output = createElement(view)\n nodes = toNodeArray(output, markerOwnerDocument)\n // Suspended view: child threw a suspense token and was handled upstream.\n // Avoid replacing existing fallback content; tear down this attempt.\n const suspendedAttempt =\n root.suspended ||\n (nodes.length > 0 &&\n nodes.every(node => node instanceof Comment && (node as Comment).data === 'fict:suspend'))\n if (suspendedAttempt) {\n popRoot(prev)\n destroyRoot(root)\n return\n }\n const parentNode = endMarker.parentNode as (ParentNode & Node) | null\n if (parentNode) {\n insertNodesBefore(parentNode, nodes, endMarker)\n }\n } catch (err) {\n popRoot(prev)\n destroyRoot(root)\n if (!handleError(err, { source: 'render' }, hostRoot)) {\n throw err\n }\n return\n } finally {\n if (boundaryPushed) {\n __fictPopSSRBoundary(streamBoundaryId ?? undefined)\n }\n }\n popRoot(prev)\n flushOnMount(root)\n\n cleanup = () => {\n destroyRoot(root)\n removeNodes(nodes)\n }\n activeNodes = nodes\n }\n\n const fragment = markerOwnerDocument.createDocumentFragment()\n const startMarker = markerOwnerDocument.createComment('fict:suspense-start')\n const endMarker = markerOwnerDocument.createComment('fict:suspense-end')\n fragment.appendChild(startMarker)\n fragment.appendChild(endMarker)\n let cleanup: (() => void) | undefined\n let activeNodes: Node[] = []\n let streamBoundaryId: string | null = null\n let streamPending = false\n\n if (streamHooks?.registerBoundary) {\n streamBoundaryId = streamHooks.registerBoundary(startMarker, endMarker) ?? null\n if (streamBoundaryId) {\n startMarker.data = `fict:suspense-start:${streamBoundaryId}`\n endMarker.data = `fict:suspense-end:${streamBoundaryId}`\n }\n }\n\n const onResolveMaybe = () => {\n if (!resolvedOnce) {\n resolvedOnce = true\n props.onResolve?.()\n }\n }\n\n registerSuspenseHandler(token => {\n const tokenEpoch = epoch\n if (!streamPending && streamBoundaryId && streamHooks?.boundaryPending) {\n streamPending = true\n streamHooks.boundaryPending(streamBoundaryId)\n }\n pending(pending() + 1)\n // Directly render fallback instead of using switchView to avoid\n // triggering the effect which would cause duplicate renders\n renderView(toFallback())\n\n const thenable = (token as SuspenseToken).then\n ? (token as SuspenseToken)\n : isThenable(token)\n ? token\n : null\n\n if (thenable) {\n thenable.then(\n () => {\n // This prevents stale token resolutions from affecting state after\n // a reset. The order is important: check epoch first, then update state.\n if (epoch !== tokenEpoch) {\n // Token is stale (from before a reset), ignore it completely\n return\n }\n // Use Math.max as a defensive measure - pending should never go below 0,\n // but this protects against edge cases where a token might resolve twice\n // or after the component has been reset.\n const newPending = Math.max(0, pending() - 1)\n pending(newPending)\n if (newPending === 0) {\n // Directly render children instead of using switchView\n renderView(props.children ?? null)\n if (streamPending && streamBoundaryId && streamHooks?.boundaryResolved) {\n streamPending = false\n streamHooks.boundaryResolved(streamBoundaryId)\n }\n onResolveMaybe()\n }\n },\n err => {\n // Same epoch check - ignore stale tokens\n if (epoch !== tokenEpoch) {\n return\n }\n const newPending = Math.max(0, pending() - 1)\n pending(newPending)\n let rejectionError = err\n try {\n props.onReject?.(err)\n } catch (callbackError) {\n rejectionError = callbackError\n }\n\n const handled = handleError(rejectionError, { source: 'render' }, hostRoot)\n if (!handled) {\n if (streamHooks?.onError) {\n streamHooks.onError(rejectionError, streamBoundaryId ?? undefined)\n return\n }\n throw rejectionError\n }\n if (\n newPending === 0 &&\n streamPending &&\n streamBoundaryId &&\n streamHooks?.boundaryResolved\n ) {\n streamPending = false\n streamHooks.boundaryResolved(streamBoundaryId)\n }\n },\n )\n return true\n }\n\n return false\n })\n\n // Initial render - render children directly\n // Note: This will be called synchronously during component creation.\n // If children suspend, the handler above will be called and switch to fallback.\n renderView(props.children ?? null)\n\n if (props.resetKeys !== undefined) {\n const isGetter =\n typeof props.resetKeys === 'function' && (props.resetKeys as () => unknown).length === 0\n const getter = isGetter ? (props.resetKeys as () => unknown) : undefined\n let prev = isGetter ? getter!() : props.resetKeys\n createEffect(() => {\n const next = getter ? getter() : props.resetKeys\n if (prev !== next) {\n prev = next\n epoch++\n pending(0)\n // Directly render children instead of using switchView\n renderView(props.children ?? null)\n if (streamPending && streamBoundaryId && streamHooks?.boundaryResolved) {\n streamPending = false\n streamHooks.boundaryResolved(streamBoundaryId)\n }\n }\n })\n }\n\n return fragment\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { F as Fragment, J as JSX, M as Memo, d as createElement, c as createMemo, k as keyed, m as mergeProps, p as prop, r as render } from './props
|
|
2
|
-
import { S as RefObject, B as BaseProps, F as FictNode, T as SuspenseToken } from './binding-
|
|
3
|
-
export { a3 as ClassProp, Z as Cleanup, _ as Component, R as DOMElement, U as Effect, a5 as ErrorInfo, a4 as EventHandler, Y as FictVNode, $ as PropsWithChildren, a0 as Ref, a1 as RefCallback, a2 as StyleProp, j as createEffect, E as createPortal, X as createRoot, W as onCleanup, N as onDestroy, V as onMount } from './binding-
|
|
4
|
-
export { C as Context, F as FictDevtoolsHook, P as ProviderProps, c as createContext, h as hasContext, u as useContext } from './devtools-
|
|
1
|
+
export { F as Fragment, J as JSX, M as Memo, d as createElement, c as createMemo, k as keyed, m as mergeProps, p as prop, r as render } from './props-9chMyBGb.cjs';
|
|
2
|
+
import { S as RefObject, B as BaseProps, F as FictNode, T as SuspenseToken } from './binding-FRyTeLDn.cjs';
|
|
3
|
+
export { a3 as ClassProp, Z as Cleanup, _ as Component, R as DOMElement, U as Effect, a5 as ErrorInfo, a4 as EventHandler, Y as FictVNode, $ as PropsWithChildren, a0 as Ref, a1 as RefCallback, a2 as StyleProp, j as createEffect, E as createPortal, X as createRoot, W as onCleanup, N as onDestroy, V as onMount } from './binding-FRyTeLDn.cjs';
|
|
4
|
+
export { C as Context, F as FictDevtoolsHook, P as ProviderProps, c as createContext, h as hasContext, u as useContext } from './devtools-BtIkN77t.cjs';
|
|
5
5
|
import './signal-Z4KkDk9h.cjs';
|
|
6
6
|
|
|
7
7
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { F as Fragment, J as JSX, M as Memo, d as createElement, c as createMemo, k as keyed, m as mergeProps, p as prop, r as render } from './props-
|
|
2
|
-
import { S as RefObject, B as BaseProps, F as FictNode, T as SuspenseToken } from './binding-
|
|
3
|
-
export { a3 as ClassProp, Z as Cleanup, _ as Component, R as DOMElement, U as Effect, a5 as ErrorInfo, a4 as EventHandler, Y as FictVNode, $ as PropsWithChildren, a0 as Ref, a1 as RefCallback, a2 as StyleProp, j as createEffect, E as createPortal, X as createRoot, W as onCleanup, N as onDestroy, V as onMount } from './binding-
|
|
4
|
-
export { C as Context, F as FictDevtoolsHook, P as ProviderProps, c as createContext, h as hasContext, u as useContext } from './devtools-
|
|
1
|
+
export { F as Fragment, J as JSX, M as Memo, d as createElement, c as createMemo, k as keyed, m as mergeProps, p as prop, r as render } from './props-D1nj2p_3.js';
|
|
2
|
+
import { S as RefObject, B as BaseProps, F as FictNode, T as SuspenseToken } from './binding-DcnhUSQK.js';
|
|
3
|
+
export { a3 as ClassProp, Z as Cleanup, _ as Component, R as DOMElement, U as Effect, a5 as ErrorInfo, a4 as EventHandler, Y as FictVNode, $ as PropsWithChildren, a0 as Ref, a1 as RefCallback, a2 as StyleProp, j as createEffect, E as createPortal, X as createRoot, W as onCleanup, N as onDestroy, V as onMount } from './binding-DcnhUSQK.js';
|
|
4
|
+
export { C as Context, F as FictDevtoolsHook, P as ProviderProps, c as createContext, h as hasContext, u as useContext } from './devtools-D2z4llpA.js';
|
|
5
5
|
import './signal-Z4KkDk9h.js';
|
|
6
6
|
|
|
7
7
|
/**
|