@qwik.dev/core 2.0.0-beta.41 → 2.0.0-beta.43
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/backpatch/package.json +1 -1
- package/dist/build/package.json +1 -1
- package/dist/cli.mjs +2 -2
- package/dist/core-internal.d.ts +85 -16
- package/dist/core.min.mjs +11 -9
- package/dist/core.mjs +709 -128
- package/dist/core.mjs.map +1 -1
- package/dist/core.prod.mjs +3866 -3322
- package/dist/error-swap-executor.debug.js +37 -0
- package/dist/error-swap-executor.js +1 -0
- package/dist/loader/index.mjs +2 -2
- package/dist/loader/package.json +1 -1
- package/dist/optimizer.d.ts +2 -0
- package/dist/optimizer.mjs +15 -10
- package/dist/out-of-order-executor.debug.js +12 -12
- package/dist/qwikloader.debug.js +1 -1
- package/dist/qwikloader.js +1 -1
- package/dist/server.d.ts +27 -0
- package/dist/server.mjs +100 -40
- package/dist/server.prod.mjs +849 -781
- package/dist/testing/index.d.ts +11 -2
- package/dist/testing/index.mjs +6560 -6308
- package/dist/testing/package.json +1 -1
- package/dist/worker/package.json +1 -1
- package/handlers.mjs +3 -0
- package/package.json +3 -3
- package/public.d.ts +3 -1
package/dist/core.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* @qwik.dev/core 2.0.0-beta.
|
|
3
|
+
* @qwik.dev/core 2.0.0-beta.43-dev+e478dfb
|
|
4
4
|
* Copyright QwikDev. All Rights Reserved.
|
|
5
5
|
* Use of this source code is governed by an MIT-style license that can be
|
|
6
6
|
* found in the LICENSE file at https://github.com/QwikDev/qwik/blob/main/LICENSE
|
|
@@ -29,6 +29,9 @@ const STYLE = qDev
|
|
|
29
29
|
const logError = (message, ...optionalParams) => {
|
|
30
30
|
return createAndLogError(false, message, ...optionalParams);
|
|
31
31
|
};
|
|
32
|
+
const logErrorAndThrowAsync = (message, ...optionalParams) => {
|
|
33
|
+
return createAndLogError(true, message, ...optionalParams);
|
|
34
|
+
};
|
|
32
35
|
const throwErrorAndStop = (message, ...optionalParams) => {
|
|
33
36
|
const error = createAndLogError(false, message, ...optionalParams);
|
|
34
37
|
// eslint-disable-next-line no-debugger
|
|
@@ -186,9 +189,6 @@ const isString = (v) => {
|
|
|
186
189
|
const isFunction = (v) => {
|
|
187
190
|
return typeof v === 'function';
|
|
188
191
|
};
|
|
189
|
-
const isPrimitiveOrNullUndefined = (v) => {
|
|
190
|
-
return (typeof v !== 'object' && typeof v !== 'function') || v === null || v === undefined;
|
|
191
|
-
};
|
|
192
192
|
|
|
193
193
|
const baseUrl = 'https://qwikdev-build-v2.qwik-8nx.pages.dev/docs/errors/#q';
|
|
194
194
|
const codeToText = (code, ...parts) => {
|
|
@@ -418,6 +418,8 @@ const QSlotS = 'q:s';
|
|
|
418
418
|
const QStatePatchAttrSelector = '[q\\:patch]';
|
|
419
419
|
const QSuspenseResolved = 'q:r';
|
|
420
420
|
const QSuspenseResultParent = 'q:rp';
|
|
421
|
+
const QErrorContentHost = 'q:ebc';
|
|
422
|
+
const QErrorFallbackHost = 'q:ebf';
|
|
421
423
|
const QStyle = 'q:style';
|
|
422
424
|
const QStyleSelector = 'style[q\\:style]';
|
|
423
425
|
const QStyleSSelector = 'style[q\\:sstyle]';
|
|
@@ -470,6 +472,7 @@ const QDefaultSlot = '';
|
|
|
470
472
|
const ELEMENT_ID = 'q:id';
|
|
471
473
|
const ELEMENT_KEY = 'q:key';
|
|
472
474
|
const ELEMENT_PROPS = 'q:props';
|
|
475
|
+
const USE_ON_PLACEHOLDER_KEY = ':useOn';
|
|
473
476
|
/** @internal */
|
|
474
477
|
const ELEMENT_SEQ = 'q:seq';
|
|
475
478
|
const ELEMENT_SEQ_IDX = 'q:seqIdx';
|
|
@@ -489,8 +492,13 @@ const debugStyleScopeIdPrefixAttr = '__scopedStyleIdPrefix__';
|
|
|
489
492
|
|
|
490
493
|
const MAX_RETRY_ON_PROMISE_COUNT = 100;
|
|
491
494
|
const isPromise = (value) => {
|
|
492
|
-
|
|
493
|
-
|
|
495
|
+
try {
|
|
496
|
+
// not using "value instanceof Promise" to have zone.js support
|
|
497
|
+
return !!value && typeof value == 'object' && typeof value.then === 'function';
|
|
498
|
+
}
|
|
499
|
+
catch {
|
|
500
|
+
return false;
|
|
501
|
+
}
|
|
494
502
|
};
|
|
495
503
|
const safeCall = (call, thenFn, rejectFn) => {
|
|
496
504
|
try {
|
|
@@ -518,8 +526,13 @@ const delay = (timeout) => {
|
|
|
518
526
|
});
|
|
519
527
|
};
|
|
520
528
|
const checkError = (e) => {
|
|
521
|
-
|
|
522
|
-
|
|
529
|
+
try {
|
|
530
|
+
if (isServer && e instanceof ReferenceError && e.message.includes('window')) {
|
|
531
|
+
e.message = 'It seems like you forgot to add "if (isBrowser) {...}" here:' + e.message;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
catch {
|
|
535
|
+
// ignore
|
|
523
536
|
}
|
|
524
537
|
};
|
|
525
538
|
const justThrow = (e) => {
|
|
@@ -1266,7 +1279,7 @@ const COMMA = ',';
|
|
|
1266
1279
|
*
|
|
1267
1280
|
* @public
|
|
1268
1281
|
*/
|
|
1269
|
-
const version = "2.0.0-beta.
|
|
1282
|
+
const version = "2.0.0-beta.43-dev+e478dfb";
|
|
1270
1283
|
|
|
1271
1284
|
const isNode = (value) => {
|
|
1272
1285
|
return value && typeof value.nodeType === 'number';
|
|
@@ -3780,6 +3793,16 @@ const _propertyIsEnumerable = Object.prototype.propertyIsEnumerable;
|
|
|
3780
3793
|
function isSlotProp(prop) {
|
|
3781
3794
|
return !prop.startsWith('q:') && !prop.startsWith(NON_SERIALIZABLE_MARKER_PREFIX);
|
|
3782
3795
|
}
|
|
3796
|
+
function hasSlotProps(props) {
|
|
3797
|
+
if (props) {
|
|
3798
|
+
for (const prop in props) {
|
|
3799
|
+
if (isSlotProp(prop)) {
|
|
3800
|
+
return true;
|
|
3801
|
+
}
|
|
3802
|
+
}
|
|
3803
|
+
}
|
|
3804
|
+
return false;
|
|
3805
|
+
}
|
|
3783
3806
|
/** @internal */
|
|
3784
3807
|
const _restProps = (props, omit = [], target = {}) => {
|
|
3785
3808
|
// The optimizer can apply this transform to plain, non-component objects and
|
|
@@ -4022,7 +4045,12 @@ function addCursorBoundary(cursorData, vNode) {
|
|
|
4022
4045
|
if (!__EXPERIMENTAL__.suspense) {
|
|
4023
4046
|
return;
|
|
4024
4047
|
}
|
|
4025
|
-
|
|
4048
|
+
let boundary = null;
|
|
4049
|
+
let current = vNode;
|
|
4050
|
+
while (current && !boundary) {
|
|
4051
|
+
boundary = getNearestCursorBoundary(current);
|
|
4052
|
+
current = current.slotParent || current.parent;
|
|
4053
|
+
}
|
|
4026
4054
|
if (!boundary) {
|
|
4027
4055
|
return;
|
|
4028
4056
|
}
|
|
@@ -4169,7 +4197,7 @@ function runEventHandlerQRL(handler, event, element, ctx) {
|
|
|
4169
4197
|
if (!(hostElement.flags & 32 /* VNodeFlags.Deleted */)) {
|
|
4170
4198
|
return invokeApply(ctx, realHandler, [event, element]);
|
|
4171
4199
|
}
|
|
4172
|
-
}, (err) => container.handleError(err, hostElement));
|
|
4200
|
+
}, (err) => container.handleError(err, hostElement, "event" /* ErrorBoundaryPhase.Event */));
|
|
4173
4201
|
}
|
|
4174
4202
|
/**
|
|
4175
4203
|
* This is called by qwik-loader to run a QRL. It has to be synchronous when possible.
|
|
@@ -5498,11 +5526,14 @@ function cleanup(container, journal, vNode, cursorRoot = null) {
|
|
|
5498
5526
|
const obj = seq[i];
|
|
5499
5527
|
if (isObject(obj)) {
|
|
5500
5528
|
const objIsTask = isTask(obj);
|
|
5501
|
-
if (objIsTask
|
|
5502
|
-
obj
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
|
|
5529
|
+
if (objIsTask) {
|
|
5530
|
+
clearAllEffects(container, obj);
|
|
5531
|
+
if (obj.$flags$ & 1 /* TaskFlags.VISIBLE_TASK */) {
|
|
5532
|
+
obj.$flags$ |= 16 /* TaskFlags.NEEDS_CLEANUP */;
|
|
5533
|
+
markVNodeDirty(container, vCursor, 128 /* ChoreBits.CLEANUP */, cursorRoot);
|
|
5534
|
+
// don't call cleanupDestroyable yet, do it by the scheduler
|
|
5535
|
+
continue;
|
|
5536
|
+
}
|
|
5506
5537
|
}
|
|
5507
5538
|
// Stores and plain signals are only producers; their subscriptions are removed
|
|
5508
5539
|
// when cleaning the consumers that read them. They don't own reactive backrefs.
|
|
@@ -5958,43 +5989,16 @@ function findFirstElementNode(jsx) {
|
|
|
5958
5989
|
* This is necessary for headless components (components that don't render a real DOM element) to
|
|
5959
5990
|
* have an anchor point for `useOn` event listeners that target the document or window.
|
|
5960
5991
|
*
|
|
5961
|
-
* @param jsx The JSX output
|
|
5992
|
+
* @param jsx The JSX output of the component.
|
|
5962
5993
|
* @param placeholder The placeholder element to inject.
|
|
5963
|
-
* @returns The
|
|
5994
|
+
* @returns The JSX output with the placeholder as its last sibling.
|
|
5964
5995
|
*/
|
|
5965
5996
|
function injectPlaceholderElement(jsx, placeholder) {
|
|
5966
|
-
|
|
5967
|
-
if (isJSXNode(jsx)) {
|
|
5968
|
-
// Inline components may ignore children, while component$ children become projections.
|
|
5969
|
-
if (jsx.type !== Fragment) {
|
|
5970
|
-
return _jsxSorted(Fragment, null, null, [jsx, placeholder], 0, null);
|
|
5971
|
-
}
|
|
5972
|
-
if (jsx.children == null) {
|
|
5973
|
-
jsx.children = placeholder;
|
|
5974
|
-
}
|
|
5975
|
-
else if (isArray(jsx.children)) {
|
|
5976
|
-
jsx.children.push(placeholder);
|
|
5977
|
-
}
|
|
5978
|
-
else {
|
|
5979
|
-
jsx.children = [jsx.children, placeholder];
|
|
5980
|
-
}
|
|
5981
|
-
return jsx;
|
|
5982
|
-
}
|
|
5983
|
-
// For primitives, we can't add children, so we wrap them in a fragment.
|
|
5984
|
-
if (isPrimitiveOrNullUndefined(jsx)) {
|
|
5985
|
-
return _jsxSorted(Fragment, null, null, [jsx, placeholder], 0, null);
|
|
5986
|
-
}
|
|
5987
|
-
// For an array of nodes, we inject the placeholder into the first element.
|
|
5988
|
-
if (isArray(jsx) && jsx.length > 0) {
|
|
5989
|
-
injectPlaceholderElement(jsx[0], placeholder);
|
|
5990
|
-
return jsx;
|
|
5991
|
-
}
|
|
5992
|
-
// For anything else we do nothing.
|
|
5993
|
-
return jsx;
|
|
5997
|
+
return isArray(jsx) ? [...jsx, placeholder] : [jsx, placeholder];
|
|
5994
5998
|
}
|
|
5995
5999
|
/** @returns An empty <script> element for adding qwik metadata attributes to */
|
|
5996
6000
|
function createPlaceholderScriptNode() {
|
|
5997
|
-
return new JSXNodeImpl('script', null, { hidden: '' }, null, 0,
|
|
6001
|
+
return new JSXNodeImpl('script', null, { hidden: '' }, null, 0, USE_ON_PLACEHOLDER_KEY);
|
|
5998
6002
|
}
|
|
5999
6003
|
|
|
6000
6004
|
function collectChildren(first, last = null) {
|
|
@@ -9335,7 +9339,10 @@ const runTask = (task, container, host) => {
|
|
|
9335
9339
|
return pendingTask;
|
|
9336
9340
|
}
|
|
9337
9341
|
task.$flags$ &= -5 /* TaskFlags.DIRTY */;
|
|
9338
|
-
const handleError = (reason) =>
|
|
9342
|
+
const handleError = (reason) => {
|
|
9343
|
+
tagErrorPhase(reason, "hook" /* ErrorBoundaryPhase.Hook */);
|
|
9344
|
+
container.handleError(reason, host, "hook" /* ErrorBoundaryPhase.Hook */);
|
|
9345
|
+
};
|
|
9339
9346
|
let taskPromise = null;
|
|
9340
9347
|
const result = maybeThen(cleanupAsyncDestroyable(task, handleError), () => {
|
|
9341
9348
|
const iCtx = newInvokeContext(container.$locale$, host, TaskEvent);
|
|
@@ -9405,6 +9412,10 @@ function scheduleTask(_event, element) {
|
|
|
9405
9412
|
setCaptures(deserializeCaptureDeltas(container, this));
|
|
9406
9413
|
}
|
|
9407
9414
|
const task = _captures[0];
|
|
9415
|
+
if (!task.$el$) {
|
|
9416
|
+
// An ErrorBoundary tore the host down; the task has nothing left to run against.
|
|
9417
|
+
return;
|
|
9418
|
+
}
|
|
9408
9419
|
task.$flags$ |= 4 /* TaskFlags.DIRTY */;
|
|
9409
9420
|
markVNodeDirty(container, task.$el$, 1 /* ChoreBits.TASKS */);
|
|
9410
9421
|
});
|
|
@@ -9669,7 +9680,12 @@ const getStoreHandler = (value) => {
|
|
|
9669
9680
|
return value[STORE_HANDLER];
|
|
9670
9681
|
};
|
|
9671
9682
|
const getStoreTarget = (value) => {
|
|
9672
|
-
|
|
9683
|
+
try {
|
|
9684
|
+
return value?.[STORE_TARGET] || null;
|
|
9685
|
+
}
|
|
9686
|
+
catch {
|
|
9687
|
+
return null;
|
|
9688
|
+
}
|
|
9673
9689
|
};
|
|
9674
9690
|
/**
|
|
9675
9691
|
* Force a store to recompute and schedule effects.
|
|
@@ -9770,11 +9786,17 @@ class StoreHandler {
|
|
|
9770
9786
|
return this.toString;
|
|
9771
9787
|
}
|
|
9772
9788
|
const flags = this.$flags$;
|
|
9773
|
-
|
|
9774
|
-
|
|
9775
|
-
|
|
9776
|
-
|
|
9777
|
-
|
|
9789
|
+
let shouldWrapRecursively = false;
|
|
9790
|
+
if (flags & 1 /* StoreFlags.RECURSIVE */ && isObject(value)) {
|
|
9791
|
+
try {
|
|
9792
|
+
shouldWrapRecursively =
|
|
9793
|
+
!Object.isFrozen(value) && !isStore(value) && !Object.isFrozen(target);
|
|
9794
|
+
}
|
|
9795
|
+
catch {
|
|
9796
|
+
// ignore
|
|
9797
|
+
}
|
|
9798
|
+
}
|
|
9799
|
+
if (shouldWrapRecursively) {
|
|
9778
9800
|
return getOrCreateStore(value, this.$flags$, this.$container$);
|
|
9779
9801
|
}
|
|
9780
9802
|
return value;
|
|
@@ -10727,8 +10749,9 @@ class Serializer {
|
|
|
10727
10749
|
}
|
|
10728
10750
|
const out = [value.$computeQrl$, value.$effects$];
|
|
10729
10751
|
if (isAsync) {
|
|
10752
|
+
const untrackedError = value.$untrackedError$;
|
|
10730
10753
|
// After SSR, the signal is never loading, so no need to send it
|
|
10731
|
-
out.push(value.$loadingEffects$, value.$errorEffects$,
|
|
10754
|
+
out.push(value.$loadingEffects$, value.$errorEffects$, untrackedError === undefined || isDev ? untrackedError : redactToGeneric(untrackedError));
|
|
10732
10755
|
out.push(asyncFlags || undefined);
|
|
10733
10756
|
}
|
|
10734
10757
|
if (v !== NEEDS_COMPUTATION || concurrency !== undefined || timeout !== undefined) {
|
|
@@ -10765,8 +10788,9 @@ class Serializer {
|
|
|
10765
10788
|
}
|
|
10766
10789
|
else if (value instanceof Error) {
|
|
10767
10790
|
const out = [value.message];
|
|
10768
|
-
|
|
10769
|
-
|
|
10791
|
+
for (const entry of Object.entries(value)) {
|
|
10792
|
+
out.push(entry[0], entry[1]);
|
|
10793
|
+
}
|
|
10770
10794
|
/// In production we don't want to leak the stack trace.
|
|
10771
10795
|
if (isDev) {
|
|
10772
10796
|
out.push('stack', value.stack);
|
|
@@ -10774,15 +10798,20 @@ class Serializer {
|
|
|
10774
10798
|
this.output(23 /* TypeIds.Error */, out);
|
|
10775
10799
|
}
|
|
10776
10800
|
else if (this.$serializationContext$.$isSsrNode$(value)) {
|
|
10801
|
+
// Paired with ssr-container's vnode-data INERT skip: drop the state root AND the path together.
|
|
10802
|
+
if (value.vnodeData &&
|
|
10803
|
+
value.vnodeData[0] & 32 /* VNodeDataFlag.INERT */ &&
|
|
10804
|
+
/[A-Za-z]/.test(value.id)) {
|
|
10805
|
+
this.output(3 /* TypeIds.Constant */, 0 /* Constants.Undefined */);
|
|
10806
|
+
return;
|
|
10807
|
+
}
|
|
10777
10808
|
const rootIndex = this.$serializationContext$.$addRoot$(value);
|
|
10778
10809
|
this.$serializationContext$.$setProp$(value, ELEMENT_ID, rootIndex);
|
|
10779
10810
|
// we need to output before the vnode overwrites its values
|
|
10780
10811
|
this.output(10 /* TypeIds.VNode */, value.id);
|
|
10781
10812
|
const vNodeData = value.vnodeData;
|
|
10782
10813
|
if (vNodeData) {
|
|
10783
|
-
discoverValuesForVNodeData(vNodeData,
|
|
10784
|
-
this.$serializationContext$.$addRoot$(vNodeDataValue);
|
|
10785
|
-
});
|
|
10814
|
+
discoverValuesForVNodeData(vNodeData, this.$serializationContext$);
|
|
10786
10815
|
this.$serializationContext$.$markSsrNodeForSerialization$(value, 16 /* VNodeDataFlag.SERIALIZE */);
|
|
10787
10816
|
}
|
|
10788
10817
|
if (value.children) {
|
|
@@ -11066,9 +11095,9 @@ function getCustomSerializerPromise(signal, value) {
|
|
|
11066
11095
|
return data;
|
|
11067
11096
|
});
|
|
11068
11097
|
}
|
|
11069
|
-
const discoverValuesForVNodeData = (vnodeData,
|
|
11098
|
+
const discoverValuesForVNodeData = (vnodeData, serializationContext) => {
|
|
11070
11099
|
const length = vnodeData.length;
|
|
11071
|
-
for (let i =
|
|
11100
|
+
for (let i = 1; i < length; i++) {
|
|
11072
11101
|
const value = vnodeData[i];
|
|
11073
11102
|
if (isSsrAttrs(value)) {
|
|
11074
11103
|
for (const key in value) {
|
|
@@ -11081,7 +11110,7 @@ const discoverValuesForVNodeData = (vnodeData, callback) => {
|
|
|
11081
11110
|
shouldSkipComponentProps(value, attrValue)))) {
|
|
11082
11111
|
continue;
|
|
11083
11112
|
}
|
|
11084
|
-
|
|
11113
|
+
serializationContext.$addRoot$(attrValue);
|
|
11085
11114
|
}
|
|
11086
11115
|
}
|
|
11087
11116
|
}
|
|
@@ -12067,15 +12096,23 @@ const applyQwikComponentBody = (ssr, jsx, component) => {
|
|
|
12067
12096
|
|
|
12068
12097
|
class MaybeAsyncSignal {
|
|
12069
12098
|
}
|
|
12070
|
-
|
|
12071
|
-
|
|
12072
|
-
|
|
12073
|
-
|
|
12074
|
-
|
|
12075
|
-
|
|
12076
|
-
|
|
12077
|
-
|
|
12078
|
-
|
|
12099
|
+
// we need to differentiate between JSX functions and ssr container functions for error boundary
|
|
12100
|
+
// JSX functions need to be skipped after error boundary catch an error
|
|
12101
|
+
class InvokeJSXFunction {
|
|
12102
|
+
}
|
|
12103
|
+
const openBoundaryContentScope = (ssr, contentHost) => {
|
|
12104
|
+
const enclosing = ssr.$errorContentHost$;
|
|
12105
|
+
ssr.$errorContentHost$ = contentHost;
|
|
12106
|
+
return () => {
|
|
12107
|
+
ssr.$errorContentHost$ = enclosing;
|
|
12108
|
+
};
|
|
12109
|
+
};
|
|
12110
|
+
const isInsideFailedBoundaryContent = (ssr) => {
|
|
12111
|
+
const contentHost = ssr.$errorContentHost$;
|
|
12112
|
+
return !!contentHost && (contentHost.vnodeData[0] & 32 /* VNodeDataFlag.INERT */) !== 0;
|
|
12113
|
+
};
|
|
12114
|
+
const markPromiseHandled = (promise) => {
|
|
12115
|
+
promise.catch(() => { });
|
|
12079
12116
|
};
|
|
12080
12117
|
function setParentOptions(mutable, styleScoped, parentComponentFrame) {
|
|
12081
12118
|
return () => {
|
|
@@ -12088,23 +12125,43 @@ async function _walkJSX(ssr, value, options) {
|
|
|
12088
12125
|
const stack = [value];
|
|
12089
12126
|
const enqueue = (value) => stack.push(value);
|
|
12090
12127
|
const enqueuePromise = (promise) => {
|
|
12091
|
-
markPromiseHandled(
|
|
12128
|
+
markPromiseHandled(promise);
|
|
12092
12129
|
stack.push(promise);
|
|
12093
12130
|
stack.push(Promise);
|
|
12094
12131
|
};
|
|
12095
12132
|
const drain = async () => {
|
|
12096
12133
|
while (stack.length) {
|
|
12134
|
+
let phase = "render" /* ErrorBoundaryPhase.Render */;
|
|
12097
12135
|
try {
|
|
12098
12136
|
const value = stack.pop();
|
|
12099
12137
|
// Reference equality first (no prototype walk), then typeof
|
|
12100
12138
|
if (value === MaybeAsyncSignal) {
|
|
12101
12139
|
const trackFn = stack.pop();
|
|
12140
|
+
if (__EXPERIMENTAL__.errorBoundary && isInsideFailedBoundaryContent(ssr)) {
|
|
12141
|
+
continue;
|
|
12142
|
+
}
|
|
12143
|
+
phase = "hook" /* ErrorBoundaryPhase.Hook */;
|
|
12102
12144
|
await retryOnPromise(() => stack.push(trackFn()));
|
|
12103
12145
|
continue;
|
|
12104
12146
|
}
|
|
12147
|
+
if (__EXPERIMENTAL__.errorBoundary && value === InvokeJSXFunction) {
|
|
12148
|
+
const fnChild = stack.pop();
|
|
12149
|
+
if (isInsideFailedBoundaryContent(ssr)) {
|
|
12150
|
+
continue;
|
|
12151
|
+
}
|
|
12152
|
+
const result = fnChild.apply(ssr);
|
|
12153
|
+
if (isPromise(result)) {
|
|
12154
|
+
await result;
|
|
12155
|
+
}
|
|
12156
|
+
continue;
|
|
12157
|
+
}
|
|
12105
12158
|
if (typeof value === 'function') {
|
|
12106
12159
|
if (value === Promise) {
|
|
12107
|
-
|
|
12160
|
+
const pending = stack.pop();
|
|
12161
|
+
if (__EXPERIMENTAL__.errorBoundary && isInsideFailedBoundaryContent(ssr)) {
|
|
12162
|
+
continue;
|
|
12163
|
+
}
|
|
12164
|
+
stack.push(await pending);
|
|
12108
12165
|
}
|
|
12109
12166
|
else {
|
|
12110
12167
|
const result = value.apply(ssr);
|
|
@@ -12114,8 +12171,17 @@ async function _walkJSX(ssr, value, options) {
|
|
|
12114
12171
|
}
|
|
12115
12172
|
continue;
|
|
12116
12173
|
}
|
|
12174
|
+
if (__EXPERIMENTAL__.errorBoundary && isInsideFailedBoundaryContent(ssr)) {
|
|
12175
|
+
if (isPromise(value)) {
|
|
12176
|
+
value.catch(() => { });
|
|
12177
|
+
}
|
|
12178
|
+
continue;
|
|
12179
|
+
}
|
|
12117
12180
|
processJSXNode(ssr, enqueue, enqueuePromise, value, options);
|
|
12118
12181
|
}
|
|
12182
|
+
catch (err) {
|
|
12183
|
+
ssr.handleError(err, ssr.getOrCreateLastNode(), phase);
|
|
12184
|
+
}
|
|
12119
12185
|
finally {
|
|
12120
12186
|
const pendingFlush = ssr.streamHandler.waitForPendingFlush();
|
|
12121
12187
|
if (isPromise(pendingFlush)) {
|
|
@@ -12126,6 +12192,12 @@ async function _walkJSX(ssr, value, options) {
|
|
|
12126
12192
|
};
|
|
12127
12193
|
await drain();
|
|
12128
12194
|
}
|
|
12195
|
+
function enqueueJSX(enqueue, value) {
|
|
12196
|
+
enqueue(value);
|
|
12197
|
+
if (__EXPERIMENTAL__.errorBoundary && typeof value === 'function') {
|
|
12198
|
+
enqueue(InvokeJSXFunction);
|
|
12199
|
+
}
|
|
12200
|
+
}
|
|
12129
12201
|
function processJSXNode(ssr, enqueue, enqueuePromise, value, options) {
|
|
12130
12202
|
// console.log('processJSXNode', value);
|
|
12131
12203
|
if (value == null) {
|
|
@@ -12143,7 +12215,7 @@ function processJSXNode(ssr, enqueue, enqueuePromise, value, options) {
|
|
|
12143
12215
|
else if (typeof value === 'object') {
|
|
12144
12216
|
if (Array.isArray(value)) {
|
|
12145
12217
|
for (let i = value.length - 1; i >= 0; i--) {
|
|
12146
|
-
enqueue
|
|
12218
|
+
enqueueJSX(enqueue, value[i]);
|
|
12147
12219
|
}
|
|
12148
12220
|
}
|
|
12149
12221
|
else if (isSignal(value)) {
|
|
@@ -12162,19 +12234,28 @@ function processJSXNode(ssr, enqueue, enqueuePromise, value, options) {
|
|
|
12162
12234
|
}
|
|
12163
12235
|
else if (isAsyncGenerator(value)) {
|
|
12164
12236
|
enqueue(async () => {
|
|
12165
|
-
|
|
12166
|
-
|
|
12167
|
-
|
|
12168
|
-
|
|
12169
|
-
|
|
12170
|
-
|
|
12237
|
+
if (__EXPERIMENTAL__.errorBoundary && isInsideFailedBoundaryContent(ssr)) {
|
|
12238
|
+
return;
|
|
12239
|
+
}
|
|
12240
|
+
const freshWalkOptions = () => ({
|
|
12241
|
+
currentStyleScoped: options.currentStyleScoped,
|
|
12242
|
+
parentComponentFrame: options.parentComponentFrame,
|
|
12243
|
+
});
|
|
12244
|
+
try {
|
|
12245
|
+
for await (const chunk of value) {
|
|
12246
|
+
await _walkJSX(ssr, chunk, freshWalkOptions());
|
|
12247
|
+
await ssr.streamHandler.flush();
|
|
12248
|
+
}
|
|
12249
|
+
}
|
|
12250
|
+
catch (err) {
|
|
12251
|
+
ssr.handleError(err, ssr.getOrCreateLastNode(), "render" /* ErrorBoundaryPhase.Render */);
|
|
12252
|
+
await _walkJSX(ssr, null, freshWalkOptions());
|
|
12171
12253
|
}
|
|
12172
12254
|
});
|
|
12173
12255
|
}
|
|
12174
12256
|
else {
|
|
12175
12257
|
const jsx = value;
|
|
12176
12258
|
const type = jsx.type;
|
|
12177
|
-
// Below, JSXChildren allows functions and regexes, but we assume the dev only uses those as appropriate.
|
|
12178
12259
|
if (typeof type === 'string') {
|
|
12179
12260
|
appendClassIfScopedStyleExists(jsx, options.currentStyleScoped);
|
|
12180
12261
|
let qwikInspectorAttrValue = null;
|
|
@@ -12188,6 +12269,9 @@ function processJSXNode(ssr, enqueue, enqueuePromise, value, options) {
|
|
|
12188
12269
|
if (innerHTML) {
|
|
12189
12270
|
ssr.htmlNode(innerHTML);
|
|
12190
12271
|
}
|
|
12272
|
+
if (__EXPERIMENTAL__.errorBoundary && directGetPropsProxyProp(jsx, QErrorContentHost)) {
|
|
12273
|
+
enqueue(openBoundaryContentScope(ssr, ssr.getOrCreateLastNode()));
|
|
12274
|
+
}
|
|
12191
12275
|
enqueue(ssr.closeElement);
|
|
12192
12276
|
if (type === 'head') {
|
|
12193
12277
|
ssr.emitQwikLoaderAtTopIfNeeded();
|
|
@@ -12206,10 +12290,11 @@ function processJSXNode(ssr, enqueue, enqueuePromise, value, options) {
|
|
|
12206
12290
|
}
|
|
12207
12291
|
}
|
|
12208
12292
|
const children = jsx.children;
|
|
12209
|
-
children != null && enqueue
|
|
12293
|
+
children != null && enqueueJSX(enqueue, children);
|
|
12210
12294
|
}
|
|
12211
12295
|
else if (isFunction(type)) {
|
|
12212
|
-
if (__EXPERIMENTAL__.suspense
|
|
12296
|
+
if ((__EXPERIMENTAL__.suspense || __EXPERIMENTAL__.errorBoundary) &&
|
|
12297
|
+
isInternalServerComponent(type)) {
|
|
12213
12298
|
enqueue(() => getInternalServerComponentHandler(type)(ssr, jsx, options, enqueue));
|
|
12214
12299
|
return;
|
|
12215
12300
|
}
|
|
@@ -12220,9 +12305,8 @@ function processJSXNode(ssr, enqueue, enqueuePromise, value, options) {
|
|
|
12220
12305
|
}
|
|
12221
12306
|
ssr.openFragment(attrs);
|
|
12222
12307
|
enqueue(ssr.closeFragment);
|
|
12223
|
-
// In theory we could get functions or regexes, but we assume all is well
|
|
12224
12308
|
const children = jsx.children;
|
|
12225
|
-
children != null && enqueue
|
|
12309
|
+
children != null && enqueueJSX(enqueue, children);
|
|
12226
12310
|
}
|
|
12227
12311
|
else if (type === Slot) {
|
|
12228
12312
|
const componentFrame = options.parentComponentFrame;
|
|
@@ -12244,7 +12328,7 @@ function processJSXNode(ssr, enqueue, enqueuePromise, value, options) {
|
|
|
12244
12328
|
if (slotDefaultChildren && slotChildren !== slotDefaultChildren) {
|
|
12245
12329
|
ssr.addUnclaimedProjection(componentFrame, QDefaultSlot, slotDefaultChildren);
|
|
12246
12330
|
}
|
|
12247
|
-
enqueue
|
|
12331
|
+
enqueueJSX(enqueue, slotChildren);
|
|
12248
12332
|
enqueue(setParentOptions(options, componentFrame.projectionScopedStyle, componentFrame.projectionComponentFrame));
|
|
12249
12333
|
}
|
|
12250
12334
|
else {
|
|
@@ -12291,7 +12375,7 @@ function processJSXNode(ssr, enqueue, enqueuePromise, value, options) {
|
|
|
12291
12375
|
else if (type === SSRStreamBlock) {
|
|
12292
12376
|
ssr.streamHandler.streamBlockStart();
|
|
12293
12377
|
enqueue(() => ssr.streamHandler.streamBlockEnd());
|
|
12294
|
-
enqueue
|
|
12378
|
+
enqueueJSX(enqueue, jsx.children);
|
|
12295
12379
|
}
|
|
12296
12380
|
else if (isQwikComponent(type)) {
|
|
12297
12381
|
// prod: use new instance of an object for props, we always modify props for a component
|
|
@@ -12301,13 +12385,13 @@ function processJSXNode(ssr, enqueue, enqueuePromise, value, options) {
|
|
|
12301
12385
|
}
|
|
12302
12386
|
ssr.openComponent(componentAttrs);
|
|
12303
12387
|
const host = ssr.getOrCreateLastNode();
|
|
12388
|
+
enqueue(setParentOptions(options, options.currentStyleScoped, options.parentComponentFrame));
|
|
12389
|
+
enqueue(() => ssr.closeComponent());
|
|
12304
12390
|
const componentFrame = ssr.getParentComponentFrame();
|
|
12305
12391
|
componentFrame.distributeChildrenIntoSlots(jsx.children, options.currentStyleScoped, options.parentComponentFrame);
|
|
12306
12392
|
const jsxOutput = applyQwikComponentBody(ssr, jsx, type);
|
|
12307
|
-
enqueue(setParentOptions(options, options.currentStyleScoped, options.parentComponentFrame));
|
|
12308
|
-
enqueue(() => ssr.closeComponent());
|
|
12309
12393
|
if (isPromise(jsxOutput)) {
|
|
12310
|
-
markPromiseHandled(
|
|
12394
|
+
markPromiseHandled(jsxOutput);
|
|
12311
12395
|
// Defer reading QScopedStyle until after the promise resolves
|
|
12312
12396
|
enqueue(async () => {
|
|
12313
12397
|
await ssr.streamHandler.flush();
|
|
@@ -12359,6 +12443,99 @@ function appendClassIfScopedStyleExists(jsx, styleScoped) {
|
|
|
12359
12443
|
}
|
|
12360
12444
|
}
|
|
12361
12445
|
|
|
12446
|
+
/** @internal */
|
|
12447
|
+
function handleSSRError(container, err, host, phase) {
|
|
12448
|
+
if (!__EXPERIMENTAL__.errorBoundary || (qDev && !isRecoverable(err))) {
|
|
12449
|
+
throw err;
|
|
12450
|
+
}
|
|
12451
|
+
for (let boundaryNode = host; boundaryNode; boundaryNode = boundaryNode.parentComponent) {
|
|
12452
|
+
const errorStore = getOwnSSRErrorBoundaryStore(boundaryNode);
|
|
12453
|
+
if (!errorStore || !errorStore.$fallback$) {
|
|
12454
|
+
continue;
|
|
12455
|
+
}
|
|
12456
|
+
if (container.$isOutOfOrderSegment$ && errorStore.$emitFallback$) {
|
|
12457
|
+
throw err;
|
|
12458
|
+
}
|
|
12459
|
+
markBoundaryErrored(errorStore, err, phase);
|
|
12460
|
+
getRootContainer(container).$hasBoundaryError$ = true;
|
|
12461
|
+
if (container.$isOutOfOrderSegment$) {
|
|
12462
|
+
markErrorFromDeferredSegment(errorStore);
|
|
12463
|
+
}
|
|
12464
|
+
markErrorBoundaryContentInert(container, boundaryNode, errorStore);
|
|
12465
|
+
return;
|
|
12466
|
+
}
|
|
12467
|
+
throw err;
|
|
12468
|
+
}
|
|
12469
|
+
function markErrorBoundaryContentInert(container, boundaryNode, errorStore) {
|
|
12470
|
+
const ancestorOwners = new Map();
|
|
12471
|
+
let boundaryContentOwner = null;
|
|
12472
|
+
let depth = 0;
|
|
12473
|
+
for (let node = boundaryNode; node; node = node.parentComponent) {
|
|
12474
|
+
if (node.id) {
|
|
12475
|
+
ancestorOwners.set(node.id, { node, depth: depth++ });
|
|
12476
|
+
}
|
|
12477
|
+
if (node !== boundaryNode && !boundaryContentOwner) {
|
|
12478
|
+
const store = getOwnSSRErrorBoundaryStore(node);
|
|
12479
|
+
if (store?.error !== undefined || !hasSlotProps(node.getProp(ELEMENT_PROPS))) {
|
|
12480
|
+
boundaryContentOwner = node;
|
|
12481
|
+
}
|
|
12482
|
+
}
|
|
12483
|
+
}
|
|
12484
|
+
const topmostSevered = { node: null, depth: -1 };
|
|
12485
|
+
const children = boundaryNode.children;
|
|
12486
|
+
if (children) {
|
|
12487
|
+
for (let i = 0; i < children.length; i++) {
|
|
12488
|
+
markErrorSubtreeInert(container, children[i], ancestorOwners, topmostSevered);
|
|
12489
|
+
}
|
|
12490
|
+
}
|
|
12491
|
+
if (topmostSevered.node) {
|
|
12492
|
+
const immediateContentOwner = topmostSevered.node.parentComponent;
|
|
12493
|
+
if (topmostSevered.node === boundaryNode) {
|
|
12494
|
+
container.$retainForResume$(boundaryContentOwner);
|
|
12495
|
+
}
|
|
12496
|
+
else if (immediateContentOwner?.id) {
|
|
12497
|
+
container.$retainForResume$(immediateContentOwner);
|
|
12498
|
+
errorStore.projectedContentOwner = immediateContentOwner;
|
|
12499
|
+
}
|
|
12500
|
+
}
|
|
12501
|
+
}
|
|
12502
|
+
function getOwnSSRErrorBoundaryStore(node) {
|
|
12503
|
+
const ctx = node.getProp(QCtxAttr);
|
|
12504
|
+
return ctx ? mapArray_get(ctx, ERROR_CONTEXT.id, 0) : null;
|
|
12505
|
+
}
|
|
12506
|
+
function markErrorSubtreeInert(container, node, ancestorOwners, topmostSevered) {
|
|
12507
|
+
node.vnodeData[0] |= 32 /* VNodeDataFlag.INERT */;
|
|
12508
|
+
const ownerId = node.getProp(QSlotParent);
|
|
12509
|
+
if (ownerId) {
|
|
12510
|
+
const owner = ancestorOwners.get(ownerId);
|
|
12511
|
+
if (owner) {
|
|
12512
|
+
owner.node.removeProp(node.getProp(QSlot) ?? QDefaultSlot);
|
|
12513
|
+
if (owner.depth > topmostSevered.depth) {
|
|
12514
|
+
topmostSevered.node = owner.node;
|
|
12515
|
+
topmostSevered.depth = owner.depth;
|
|
12516
|
+
}
|
|
12517
|
+
}
|
|
12518
|
+
}
|
|
12519
|
+
// Element consumers keep materializing when inert, so their bindings would keep patching hidden
|
|
12520
|
+
// DOM; virtual ones can't materialize and would leave producers pointing at a dead node.
|
|
12521
|
+
clearAllEffects(container, node);
|
|
12522
|
+
const seq = node.getProp(ELEMENT_SEQ);
|
|
12523
|
+
if (seq) {
|
|
12524
|
+
for (let i = 0; i < seq.length; i++) {
|
|
12525
|
+
const item = seq[i];
|
|
12526
|
+
if (isTask(item)) {
|
|
12527
|
+
clearAllEffects(container, item);
|
|
12528
|
+
}
|
|
12529
|
+
}
|
|
12530
|
+
}
|
|
12531
|
+
const children = node.children;
|
|
12532
|
+
if (children) {
|
|
12533
|
+
for (let i = 0; i < children.length; i++) {
|
|
12534
|
+
markErrorSubtreeInert(container, children[i], ancestorOwners, topmostSevered);
|
|
12535
|
+
}
|
|
12536
|
+
}
|
|
12537
|
+
}
|
|
12538
|
+
|
|
12362
12539
|
// <docs markdown="../readme.md#useLexicalScope">
|
|
12363
12540
|
// !!DO NOT EDIT THIS COMMENT DIRECTLY!!!
|
|
12364
12541
|
// (edit ../readme.md#useLexicalScope instead and run `pnpm docs.sync`)
|
|
@@ -13836,14 +14013,179 @@ const _resolveContextWithoutSequentialScope = (context) => {
|
|
|
13836
14013
|
};
|
|
13837
14014
|
|
|
13838
14015
|
const ERROR_CONTEXT = /*#__PURE__*/ createContextId('qk-error');
|
|
13839
|
-
const
|
|
13840
|
-
|
|
13841
|
-
|
|
13842
|
-
|
|
14016
|
+
const ERROR_BOUNDARY_QRL_SYMBOL = '_ebC';
|
|
14017
|
+
const safeRead = (read, fallback) => {
|
|
14018
|
+
try {
|
|
14019
|
+
return read();
|
|
14020
|
+
}
|
|
14021
|
+
catch {
|
|
14022
|
+
return fallback;
|
|
14023
|
+
}
|
|
14024
|
+
};
|
|
14025
|
+
const isRecoverable = (err) => safeRead(() => !(err instanceof Error && 'plugin' in err), true);
|
|
14026
|
+
const GENERIC_BOUNDARY_ERROR_MESSAGE = 'An error occurred';
|
|
14027
|
+
const errorBoundaryDigest = (err) => hashCode(safeRead(() => err instanceof Error ? `${err.name}: ${err.message}\n${err.stack ?? ''}` : String(err), 'unknown'));
|
|
14028
|
+
const REDACTED = /*#__PURE__*/ Symbol();
|
|
14029
|
+
const redactToGeneric = (err) => {
|
|
14030
|
+
const redacted = new Error(GENERIC_BOUNDARY_ERROR_MESSAGE);
|
|
14031
|
+
redacted.digest = errorBoundaryDigest(err);
|
|
14032
|
+
Object.defineProperty(redacted, REDACTED, { value: true });
|
|
14033
|
+
return redacted;
|
|
14034
|
+
};
|
|
14035
|
+
const toBoundaryError = (raw) => {
|
|
14036
|
+
if (raw instanceof Error) {
|
|
14037
|
+
return raw;
|
|
14038
|
+
}
|
|
14039
|
+
let message;
|
|
14040
|
+
try {
|
|
14041
|
+
message = String(raw);
|
|
14042
|
+
}
|
|
14043
|
+
catch {
|
|
14044
|
+
try {
|
|
14045
|
+
message = Object.prototype.toString.call(raw);
|
|
14046
|
+
}
|
|
14047
|
+
catch {
|
|
14048
|
+
message = GENERIC_BOUNDARY_ERROR_MESSAGE;
|
|
13843
14049
|
}
|
|
13844
14050
|
}
|
|
14051
|
+
const wrapped = new Error(message);
|
|
14052
|
+
wrapped.cause = raw;
|
|
14053
|
+
return wrapped;
|
|
14054
|
+
};
|
|
14055
|
+
const isReadableProjection = (projected) => safeRead(() => {
|
|
14056
|
+
void projected.message;
|
|
14057
|
+
void projected.name;
|
|
14058
|
+
for (const key in projected) {
|
|
14059
|
+
void projected[key];
|
|
14060
|
+
}
|
|
13845
14061
|
return true;
|
|
14062
|
+
}, false);
|
|
14063
|
+
const redactBoundaryErrorForDisplay = (error, showRaw, transformError) => {
|
|
14064
|
+
try {
|
|
14065
|
+
if (transformError) {
|
|
14066
|
+
const projected = transformError(error);
|
|
14067
|
+
if (projected instanceof Error) {
|
|
14068
|
+
return isReadableProjection(projected) ? projected : redactToGeneric(error);
|
|
14069
|
+
}
|
|
14070
|
+
if (projected != null) {
|
|
14071
|
+
if (showRaw && isPromise(projected)) {
|
|
14072
|
+
logWarn('transformError must return synchronously; an async one redacts every error.');
|
|
14073
|
+
}
|
|
14074
|
+
return redactToGeneric(error);
|
|
14075
|
+
}
|
|
14076
|
+
}
|
|
14077
|
+
if (safeRead(() => error instanceof Error && REDACTED in error, false)) {
|
|
14078
|
+
return error;
|
|
14079
|
+
}
|
|
14080
|
+
if (!showRaw) {
|
|
14081
|
+
return redactToGeneric(error);
|
|
14082
|
+
}
|
|
14083
|
+
if (error instanceof Error) {
|
|
14084
|
+
return error;
|
|
14085
|
+
}
|
|
14086
|
+
const rawMessage = error?.message;
|
|
14087
|
+
if (typeof rawMessage === 'string') {
|
|
14088
|
+
const wrapped = new Error(rawMessage);
|
|
14089
|
+
wrapped.cause = error;
|
|
14090
|
+
return wrapped;
|
|
14091
|
+
}
|
|
14092
|
+
return toBoundaryError(error);
|
|
14093
|
+
}
|
|
14094
|
+
catch {
|
|
14095
|
+
return redactToGeneric(error);
|
|
14096
|
+
}
|
|
14097
|
+
};
|
|
14098
|
+
const fireOnError = (onError, error, phase, boundaryId) => {
|
|
14099
|
+
if (!onError) {
|
|
14100
|
+
return;
|
|
14101
|
+
}
|
|
14102
|
+
try {
|
|
14103
|
+
const digest = errorBoundaryDigest(error);
|
|
14104
|
+
void Promise.resolve(onError(toBoundaryError(error), { phase, boundaryId, digest })).catch(logError);
|
|
14105
|
+
}
|
|
14106
|
+
catch (e) {
|
|
14107
|
+
logError(e);
|
|
14108
|
+
}
|
|
14109
|
+
};
|
|
14110
|
+
const boundariesWithDeferredError = /*#__PURE__*/ new WeakSet();
|
|
14111
|
+
const markErrorFromDeferredSegment = (store) => {
|
|
14112
|
+
boundariesWithDeferredError.add(store);
|
|
14113
|
+
};
|
|
14114
|
+
const isErrorFromDeferredSegment = (store) => boundariesWithDeferredError.has(store);
|
|
14115
|
+
const ERROR_PHASE = /*#__PURE__*/ Symbol('qErrorPhase');
|
|
14116
|
+
const tagErrorPhase = (err, phase) => {
|
|
14117
|
+
try {
|
|
14118
|
+
Object.defineProperty(err, ERROR_PHASE, { value: phase, configurable: true });
|
|
14119
|
+
}
|
|
14120
|
+
catch {
|
|
14121
|
+
// ignore
|
|
14122
|
+
}
|
|
14123
|
+
};
|
|
14124
|
+
const getTaggedErrorPhase = (err) => safeRead(() => err?.[ERROR_PHASE], undefined);
|
|
14125
|
+
const markBoundaryErrored = (store, error, phase = "render" /* ErrorBoundaryPhase.Render */) => {
|
|
14126
|
+
// `null` would collide with the capture-only sentinel, so wrap every nullish throw.
|
|
14127
|
+
store.error = error == null ? toBoundaryError(error) : error;
|
|
14128
|
+
const onError = store.$onError$;
|
|
14129
|
+
if (onError) {
|
|
14130
|
+
fireOnError(onError, error, getTaggedErrorPhase(error) ?? phase, store.boundaryId ?? '');
|
|
14131
|
+
}
|
|
14132
|
+
};
|
|
14133
|
+
const handleQError = (e) => {
|
|
14134
|
+
const detail = e
|
|
14135
|
+
.detail;
|
|
14136
|
+
if (detail?.importError) {
|
|
14137
|
+
return;
|
|
14138
|
+
}
|
|
14139
|
+
const source = detail.element;
|
|
14140
|
+
// The listener is document-wide, so only this document's elements may route through it.
|
|
14141
|
+
if (!source || source.ownerDocument !== e.currentTarget) {
|
|
14142
|
+
return;
|
|
14143
|
+
}
|
|
14144
|
+
// A destroyed container clears this back-pointer, so a stale target resolves to nothing.
|
|
14145
|
+
const container = source.closest(QContainerSelector)?.qContainer;
|
|
14146
|
+
const host = container?.vNodeLocate(source);
|
|
14147
|
+
if (!container || !host) {
|
|
14148
|
+
return;
|
|
14149
|
+
}
|
|
14150
|
+
try {
|
|
14151
|
+
container.handleError(detail.error, host, "event" /* ErrorBoundaryPhase.Event */);
|
|
14152
|
+
}
|
|
14153
|
+
catch (handlerError) {
|
|
14154
|
+
logError(handlerError);
|
|
14155
|
+
}
|
|
13846
14156
|
};
|
|
14157
|
+
/**
|
|
14158
|
+
* One listener per document, routed by target, so no container is retained by the document. The
|
|
14159
|
+
* marker lives on the document so a second bundle on the page reuses it instead of
|
|
14160
|
+
* double-handling.
|
|
14161
|
+
*/
|
|
14162
|
+
function installQErrorListener(doc) {
|
|
14163
|
+
if (!doc.qErrorHandler) {
|
|
14164
|
+
doc.qErrorHandler = handleQError;
|
|
14165
|
+
doc.addEventListener?.('qerror', handleQError);
|
|
14166
|
+
}
|
|
14167
|
+
}
|
|
14168
|
+
function handleDevError(container, err, host) {
|
|
14169
|
+
if (typeof document !== 'undefined') {
|
|
14170
|
+
setErrorPayload(host, err);
|
|
14171
|
+
markVNodeDirty(container, host, 512 /* ChoreBits.ERROR_WRAP */);
|
|
14172
|
+
}
|
|
14173
|
+
try {
|
|
14174
|
+
if (err instanceof Error && !('hostElement' in err)) {
|
|
14175
|
+
err['hostElement'] = String(host);
|
|
14176
|
+
}
|
|
14177
|
+
}
|
|
14178
|
+
catch {
|
|
14179
|
+
// ignore
|
|
14180
|
+
}
|
|
14181
|
+
if (!isRecoverable(err)) {
|
|
14182
|
+
throw err;
|
|
14183
|
+
}
|
|
14184
|
+
}
|
|
14185
|
+
function getOwnErrorBoundaryStore(container, host) {
|
|
14186
|
+
const ctx = container.getHostProp(host, QCtxAttr);
|
|
14187
|
+
return ctx ? mapArray_get(ctx, ERROR_CONTEXT.id, 0) : null;
|
|
14188
|
+
}
|
|
13847
14189
|
|
|
13848
14190
|
/** @internal */
|
|
13849
14191
|
const canRevealRegistration = (registration, isPending = (item) => item.boundary.untrackedValue > 0) => {
|
|
@@ -14721,6 +15063,9 @@ class DomContainer extends _SharedContainer {
|
|
|
14721
15063
|
this.$setServerData$();
|
|
14722
15064
|
element.qContainer = this;
|
|
14723
15065
|
element.qDestroy = () => this.$destroy$();
|
|
15066
|
+
if (__EXPERIMENTAL__.errorBoundary) {
|
|
15067
|
+
installQErrorListener(this.document);
|
|
15068
|
+
}
|
|
14724
15069
|
this.$containerDataProcessState$ = 1 /* ContainerDataProcessState.ProcessingVNode */;
|
|
14725
15070
|
processVNodeData(document, element);
|
|
14726
15071
|
onVNodeDataReady(document, () => {
|
|
@@ -14816,29 +15161,49 @@ class DomContainer extends _SharedContainer {
|
|
|
14816
15161
|
this.$stateData$[id] = vParent;
|
|
14817
15162
|
}
|
|
14818
15163
|
parseQRL(qrlStr) {
|
|
14819
|
-
|
|
14820
|
-
return qrl;
|
|
15164
|
+
return parseQRL(qrlStr, this);
|
|
14821
15165
|
}
|
|
14822
|
-
handleError(err, host) {
|
|
15166
|
+
handleError(err, host, phase = "render" /* ErrorBoundaryPhase.Render */) {
|
|
14823
15167
|
if (qDev && host) {
|
|
14824
|
-
|
|
14825
|
-
|
|
14826
|
-
|
|
15168
|
+
handleDevError(this, err, host);
|
|
15169
|
+
}
|
|
15170
|
+
if (!__EXPERIMENTAL__.errorBoundary) {
|
|
15171
|
+
const errorStore = host && this.resolveContext(host, ERROR_CONTEXT);
|
|
15172
|
+
if (!errorStore) {
|
|
15173
|
+
logErrorAndThrowAsync(err);
|
|
15174
|
+
return;
|
|
14827
15175
|
}
|
|
14828
|
-
|
|
14829
|
-
|
|
14830
|
-
|
|
14831
|
-
|
|
15176
|
+
errorStore.error = err;
|
|
15177
|
+
return;
|
|
15178
|
+
}
|
|
15179
|
+
// `null` would collide with the capture-only sentinel, so wrap every nullish throw.
|
|
15180
|
+
const storedError = err == null ? toBoundaryError(err) : err;
|
|
15181
|
+
let current = host;
|
|
15182
|
+
while (current) {
|
|
15183
|
+
const boundaryHost = this.resolveContextHost(current, ERROR_CONTEXT);
|
|
15184
|
+
if (!boundaryHost) {
|
|
15185
|
+
break;
|
|
14832
15186
|
}
|
|
14833
|
-
|
|
14834
|
-
|
|
15187
|
+
const store = getOwnErrorBoundaryStore(this, boundaryHost);
|
|
15188
|
+
if (store && store.error === undefined) {
|
|
15189
|
+
store.error = storedError;
|
|
15190
|
+
const boundaryProps = this.getHostProp(boundaryHost, ELEMENT_PROPS);
|
|
15191
|
+
fireOnError(boundaryProps?.onError$, err, phase, store.boundaryId ?? '');
|
|
15192
|
+
markVNodeDirty(this, boundaryHost, 4 /* ChoreBits.COMPONENT */);
|
|
15193
|
+
return;
|
|
14835
15194
|
}
|
|
15195
|
+
// Capture-only sentinel for the ErrorProvider test spy; folds away in prod builds.
|
|
15196
|
+
if (qTest && store && store.error === null) {
|
|
15197
|
+
store.error = storedError;
|
|
15198
|
+
return;
|
|
15199
|
+
}
|
|
15200
|
+
if (boundaryHost.dirty & 4 /* ChoreBits.COMPONENT */) {
|
|
15201
|
+
logError(err);
|
|
15202
|
+
return;
|
|
15203
|
+
}
|
|
15204
|
+
current = this.getParentHost(boundaryHost);
|
|
14836
15205
|
}
|
|
14837
|
-
|
|
14838
|
-
if (!errorStore) {
|
|
14839
|
-
throw err;
|
|
14840
|
-
}
|
|
14841
|
-
errorStore.error = err;
|
|
15206
|
+
logErrorAndThrowAsync(err);
|
|
14842
15207
|
}
|
|
14843
15208
|
setContext(host, context, value) {
|
|
14844
15209
|
let ctx = this.getHostProp(host, QCtxAttr);
|
|
@@ -14848,14 +15213,20 @@ class DomContainer extends _SharedContainer {
|
|
|
14848
15213
|
mapArray_set(ctx, context.id, value, 0, true);
|
|
14849
15214
|
}
|
|
14850
15215
|
resolveContext(host, contextId) {
|
|
15216
|
+
const found = this.resolveContextHost(host, contextId);
|
|
15217
|
+
return found
|
|
15218
|
+
? mapArray_get(this.getHostProp(found, QCtxAttr), contextId.id, 0)
|
|
15219
|
+
: undefined;
|
|
15220
|
+
}
|
|
15221
|
+
resolveContextHost(host, contextId) {
|
|
14851
15222
|
while (host) {
|
|
14852
15223
|
const ctx = this.getHostProp(host, QCtxAttr);
|
|
14853
15224
|
if (ctx != null && mapArray_has(ctx, contextId.id, 0)) {
|
|
14854
|
-
return
|
|
15225
|
+
return host;
|
|
14855
15226
|
}
|
|
14856
15227
|
host = this.getParentHost(host);
|
|
14857
15228
|
}
|
|
14858
|
-
return
|
|
15229
|
+
return null;
|
|
14859
15230
|
}
|
|
14860
15231
|
getParentHost(host) {
|
|
14861
15232
|
let vNode = host.parent;
|
|
@@ -16867,13 +17238,217 @@ const useTask$ = /*#__PURE__*/ implicit$FirstArg(useTaskQrl);
|
|
|
16867
17238
|
// We need to cast to help out the api extractor
|
|
16868
17239
|
const useVisibleTask$ = /*#__PURE__*/ implicit$FirstArg(useVisibleTaskQrl);
|
|
16869
17240
|
|
|
16870
|
-
|
|
16871
|
-
|
|
16872
|
-
|
|
17241
|
+
const createErrorBoundaryStore = () => Object.defineProperty({ error: undefined }, 'error', { enumerable: false });
|
|
17242
|
+
/** @internal */
|
|
17243
|
+
const useErrorBoundaryStore = () => {
|
|
17244
|
+
const error = useStore(createErrorBoundaryStore);
|
|
16873
17245
|
useContextProvider(ERROR_CONTEXT, error);
|
|
16874
17246
|
return error;
|
|
16875
17247
|
};
|
|
16876
17248
|
|
|
17249
|
+
/** Finalizes a deferred segment and emits its swap scripts; shared by Suspense and ErrorBoundary. */
|
|
17250
|
+
async function finalizeAndSwapOutOfOrderSegment(ssr, boundaryId, rendered, revealBoundary) {
|
|
17251
|
+
const segmentId = String(boundaryId);
|
|
17252
|
+
const result = await rendered.container.$finalizeOutOfOrderSegment$(segmentId, rendered);
|
|
17253
|
+
ssr.write(`<template ${QSuspenseResolved}="${boundaryId}"${revealBoundary?.attrs ?? ''}>`);
|
|
17254
|
+
ssr.write(result.html);
|
|
17255
|
+
ssr.write('</template>');
|
|
17256
|
+
ssr.emitOutOfOrderSegmentScripts(result.scripts);
|
|
17257
|
+
ssr.emitOutOfOrderExecutorIfNeeded();
|
|
17258
|
+
ssr.emitInlineScript(`qO(${boundaryId})`);
|
|
17259
|
+
const errorSwapIds = rendered.container.$errorSwapIds$;
|
|
17260
|
+
if (__EXPERIMENTAL__.errorBoundary && errorSwapIds?.length) {
|
|
17261
|
+
ssr.emitErrorSwapExecutorIfNeeded();
|
|
17262
|
+
for (let i = 0; i < errorSwapIds.length; i++) {
|
|
17263
|
+
ssr.emitInlineScript(`qErr(${errorSwapIds[i]})`);
|
|
17264
|
+
}
|
|
17265
|
+
}
|
|
17266
|
+
// qO() is the browser-visible handoff for this segment, so flush it immediately.
|
|
17267
|
+
await ssr.streamHandler.flush();
|
|
17268
|
+
}
|
|
17269
|
+
|
|
17270
|
+
/** @internal */
|
|
17271
|
+
const errorBoundaryReset = () => {
|
|
17272
|
+
const [host] = _captures;
|
|
17273
|
+
// this is executed only on client
|
|
17274
|
+
const container = tryGetInvokeContext()?.$container$;
|
|
17275
|
+
const isBrowserEnv = qTest ? !isServerPlatform() : isBrowser$1;
|
|
17276
|
+
if (isBrowserEnv && host && container) {
|
|
17277
|
+
resetErrorBoundary(container, host);
|
|
17278
|
+
}
|
|
17279
|
+
};
|
|
17280
|
+
const RESET_KEY_SUFFIX = '\0';
|
|
17281
|
+
/** @internal */
|
|
17282
|
+
function resetErrorBoundary(container, host) {
|
|
17283
|
+
const boundaryHost = container.resolveContextHost(host, ERROR_CONTEXT);
|
|
17284
|
+
if (!boundaryHost) {
|
|
17285
|
+
return;
|
|
17286
|
+
}
|
|
17287
|
+
const store = getOwnErrorBoundaryStore(container, boundaryHost);
|
|
17288
|
+
if (!store) {
|
|
17289
|
+
return;
|
|
17290
|
+
}
|
|
17291
|
+
scheduleBoundaryContentReset(container, boundaryHost, store.projectedContentOwner ?? null);
|
|
17292
|
+
store.error = undefined;
|
|
17293
|
+
}
|
|
17294
|
+
function scheduleBoundaryContentReset(container, boundaryHost, recordedContentOwner) {
|
|
17295
|
+
let resetHost = boundaryHost;
|
|
17296
|
+
let contentOwner = null;
|
|
17297
|
+
let vNode = vnode_getProjectionParentOrParent(boundaryHost);
|
|
17298
|
+
let crossedProjection = false;
|
|
17299
|
+
while (vNode) {
|
|
17300
|
+
if (vnode_isVirtualVNode(vNode)) {
|
|
17301
|
+
if (vnode_getProp(vNode, QSlot, null) !== null) {
|
|
17302
|
+
crossedProjection = true;
|
|
17303
|
+
}
|
|
17304
|
+
else if (vnode_getProp(vNode, OnRenderProp, null) !== null) {
|
|
17305
|
+
if (!crossedProjection) {
|
|
17306
|
+
const ownerBoundary = getOwnErrorBoundaryStore(container, vNode);
|
|
17307
|
+
if (!ownerBoundary || ownerBoundary.error !== undefined) {
|
|
17308
|
+
if (contentOwner) {
|
|
17309
|
+
resetHost = contentOwner;
|
|
17310
|
+
}
|
|
17311
|
+
contentOwner = vNode;
|
|
17312
|
+
if (ownerBoundary?.error !== undefined || !hasSlotProps(vNode.props)) {
|
|
17313
|
+
break;
|
|
17314
|
+
}
|
|
17315
|
+
}
|
|
17316
|
+
}
|
|
17317
|
+
crossedProjection = false;
|
|
17318
|
+
}
|
|
17319
|
+
}
|
|
17320
|
+
vNode = vnode_getProjectionParentOrParent(vNode);
|
|
17321
|
+
}
|
|
17322
|
+
if (recordedContentOwner && recordedContentOwner !== contentOwner) {
|
|
17323
|
+
resetHost = contentOwner ?? resetHost;
|
|
17324
|
+
contentOwner = recordedContentOwner;
|
|
17325
|
+
}
|
|
17326
|
+
if (contentOwner) {
|
|
17327
|
+
// Force keyed diff to recreate emptied projected content.
|
|
17328
|
+
resetHost.key = `${resetHost.key ?? ''}${RESET_KEY_SUFFIX}`;
|
|
17329
|
+
markVNodeDirty(container, contentOwner, 4 /* ChoreBits.COMPONENT */);
|
|
17330
|
+
}
|
|
17331
|
+
else {
|
|
17332
|
+
markVNodeDirty(container, boundaryHost, 4 /* ChoreBits.COMPONENT */);
|
|
17333
|
+
}
|
|
17334
|
+
}
|
|
17335
|
+
const renderFallbackOrLastResort = (fallbackQrl, error, reset) => {
|
|
17336
|
+
return fallbackQrl(error, reset).catch((err) => {
|
|
17337
|
+
if (fallbackQrl.resolved !== undefined) {
|
|
17338
|
+
throw err;
|
|
17339
|
+
}
|
|
17340
|
+
return /*#__PURE__*/ _jsxSorted('div', { role: 'alert' }, null, 'Something went wrong.', 0, null);
|
|
17341
|
+
});
|
|
17342
|
+
};
|
|
17343
|
+
const buildSSRErrorBoundaryHosts = (store, container) => {
|
|
17344
|
+
const boundaryId = container?.nextOutOfOrderId(false) ?? 0;
|
|
17345
|
+
return [
|
|
17346
|
+
/*#__PURE__*/ _jsxSorted('div', {
|
|
17347
|
+
[QErrorContentHost]: String(boundaryId),
|
|
17348
|
+
style: 'display:contents',
|
|
17349
|
+
}, null,
|
|
17350
|
+
/*#__PURE__*/ _jsxSorted(Slot, null, null, null, 0, null), 1, null),
|
|
17351
|
+
/*#__PURE__*/ _jsxSorted(SSRErrorFallbackHost, {
|
|
17352
|
+
boundaryId,
|
|
17353
|
+
store,
|
|
17354
|
+
}, null, null, 1, null),
|
|
17355
|
+
];
|
|
17356
|
+
};
|
|
17357
|
+
/** @internal */
|
|
17358
|
+
const errorBoundaryCmp = (props) => {
|
|
17359
|
+
if (!__EXPERIMENTAL__.errorBoundary) {
|
|
17360
|
+
throw new Error('<ErrorBoundary> requires the `errorBoundary` experimental feature. Enable it in your Qwik Vite config: qwikVite({ experimental: ["errorBoundary"] }).');
|
|
17361
|
+
}
|
|
17362
|
+
const store = useErrorBoundaryStore();
|
|
17363
|
+
const invokeCtx = tryGetInvokeContext();
|
|
17364
|
+
const container = invokeCtx?.$container$;
|
|
17365
|
+
if (container && (getStoreTarget(store) ?? store).boundaryId === undefined) {
|
|
17366
|
+
store.boundaryId = getNextUniqueIndex(container);
|
|
17367
|
+
}
|
|
17368
|
+
const isServerEnv = qTest ? isServerPlatform() : !isBrowser$1;
|
|
17369
|
+
if (!isServerEnv && store.error === undefined) {
|
|
17370
|
+
return /*#__PURE__*/ _jsxSorted(Slot, null, null, null, 0, null);
|
|
17371
|
+
}
|
|
17372
|
+
const reset = /*#__PURE__*/ inlinedQrl(errorBoundaryReset, '_ebR', [invokeCtx?.$hostElement$]);
|
|
17373
|
+
if (isServerEnv) {
|
|
17374
|
+
const fallbackQrl = props.fallback$;
|
|
17375
|
+
store.$fallback$ = noSerialize((error) => fallbackQrl(error, reset));
|
|
17376
|
+
const onErrorQrl = props.onError$;
|
|
17377
|
+
if (onErrorQrl) {
|
|
17378
|
+
store.$onError$ = noSerialize((error, info) => onErrorQrl(error, info));
|
|
17379
|
+
}
|
|
17380
|
+
return buildSSRErrorBoundaryHosts(store, container);
|
|
17381
|
+
}
|
|
17382
|
+
const displayError = redactBoundaryErrorForDisplay(store.error, true);
|
|
17383
|
+
return /*#__PURE__*/ _jsxSorted(Fragment, null, null, renderFallbackOrLastResort(props.fallback$, displayError, reset), 0, null);
|
|
17384
|
+
};
|
|
17385
|
+
/** Renders `fallback$` instead of its children when a descendant throws. @public @experimental */
|
|
17386
|
+
const ErrorBoundary =
|
|
17387
|
+
/*#__PURE__*/ componentQrl(
|
|
17388
|
+
/*#__PURE__*/ inlinedQrl(errorBoundaryCmp, ERROR_BOUNDARY_QRL_SYMBOL));
|
|
17389
|
+
const consumeSSRErrorFallback = (ssr, store) => {
|
|
17390
|
+
const fallback = store.$fallback$;
|
|
17391
|
+
delete store.$fallback$;
|
|
17392
|
+
const projected = redactBoundaryErrorForDisplay(store.error, isDev, ssr.$transformError$);
|
|
17393
|
+
return fallback(projected);
|
|
17394
|
+
};
|
|
17395
|
+
const SSRErrorFallbackRenderer = __EXPERIMENTAL__.errorBoundary
|
|
17396
|
+
? /*#__PURE__*/ createInternalServerComponent((ssr, jsx, options, enqueue) => {
|
|
17397
|
+
const boundaryId = jsx.varProps.boundaryId;
|
|
17398
|
+
const store = jsx.varProps.store;
|
|
17399
|
+
if (jsx.varProps.deliverLate) {
|
|
17400
|
+
const streamFallback = async (error) => {
|
|
17401
|
+
if (!store.$fallback$) {
|
|
17402
|
+
return;
|
|
17403
|
+
}
|
|
17404
|
+
// The catch site already recorded it; marking again refires onError$.
|
|
17405
|
+
if (store.error !== error) {
|
|
17406
|
+
markBoundaryErrored(store, error, "render" /* ErrorBoundaryPhase.Render */);
|
|
17407
|
+
}
|
|
17408
|
+
const segment = await ssr.segment(`${boundaryId}`, consumeSSRErrorFallback(ssr, store), options);
|
|
17409
|
+
// qErr hides the errored content host and strips its broadcast handlers.
|
|
17410
|
+
segment.container.$registerErrorSwap$(boundaryId);
|
|
17411
|
+
await ssr.$runQueuedRender$(() => finalizeAndSwapOutOfOrderSegment(ssr, boundaryId, segment, null));
|
|
17412
|
+
};
|
|
17413
|
+
store.$emitFallback$ = noSerialize(streamFallback);
|
|
17414
|
+
ssr.write(`<template ${QSuspenseResolved}="${boundaryId}"></template>`);
|
|
17415
|
+
if (store.error !== undefined) {
|
|
17416
|
+
return streamFallback(store.error);
|
|
17417
|
+
}
|
|
17418
|
+
return;
|
|
17419
|
+
}
|
|
17420
|
+
if (store.error === undefined || !store.$fallback$) {
|
|
17421
|
+
return;
|
|
17422
|
+
}
|
|
17423
|
+
if (isOutOfOrderSegmentContainer(ssr)) {
|
|
17424
|
+
ssr.$registerErrorSwap$(boundaryId);
|
|
17425
|
+
}
|
|
17426
|
+
else {
|
|
17427
|
+
enqueue(() => {
|
|
17428
|
+
ssr.emitErrorSwapExecutorIfNeeded();
|
|
17429
|
+
ssr.emitInlineScript(`qErr(${boundaryId})`);
|
|
17430
|
+
});
|
|
17431
|
+
}
|
|
17432
|
+
enqueue(consumeSSRErrorFallback(ssr, store));
|
|
17433
|
+
})
|
|
17434
|
+
: null;
|
|
17435
|
+
const SSRErrorFallbackHost = __EXPERIMENTAL__.errorBoundary
|
|
17436
|
+
? /*#__PURE__*/ createInternalServerComponent((ssr, jsx, _options, enqueue) => {
|
|
17437
|
+
const boundaryId = jsx.varProps.boundaryId;
|
|
17438
|
+
const store = jsx.varProps.store;
|
|
17439
|
+
const deliverLate = __EXPERIMENTAL__.suspense &&
|
|
17440
|
+
ssr.outOfOrderStreaming &&
|
|
17441
|
+
!isOutOfOrderSegmentContainer(ssr) &&
|
|
17442
|
+
(store.error === undefined || isErrorFromDeferredSegment(store));
|
|
17443
|
+
enqueue(
|
|
17444
|
+
/*#__PURE__*/ _jsxSorted('div', {
|
|
17445
|
+
[deliverLate ? QSuspenseResultParent : QErrorFallbackHost]: String(boundaryId),
|
|
17446
|
+
style: 'display:none',
|
|
17447
|
+
}, null,
|
|
17448
|
+
/*#__PURE__*/ _jsxSorted(SSRErrorFallbackRenderer, { boundaryId, store, deliverLate }, null, null, 1, null), 1, null));
|
|
17449
|
+
})
|
|
17450
|
+
: null;
|
|
17451
|
+
|
|
16877
17452
|
/** @internal */
|
|
16878
17453
|
const eachCmpTask = async ({ track }) => {
|
|
16879
17454
|
const props = _captures[0];
|
|
@@ -17164,10 +17739,23 @@ const SSRDeferredSlot = __EXPERIMENTAL__.suspense
|
|
|
17164
17739
|
const boundaryState = jsx.varProps.boundary;
|
|
17165
17740
|
const contentStyle = jsx.varProps.contentStyle;
|
|
17166
17741
|
const revealBoundary = jsx.varProps.reveal;
|
|
17742
|
+
const errorBoundaryStore = __EXPERIMENTAL__.errorBoundary && options.parentComponentFrame
|
|
17743
|
+
? ssr.resolveContext(options.parentComponentFrame.componentNode, ERROR_CONTEXT)
|
|
17744
|
+
: undefined;
|
|
17167
17745
|
const content = ssr.segment(contentSegment, createClaimedDeferredSlot(ssr, jsx, options), options);
|
|
17168
17746
|
ssr.write(`<template ${QSuspenseResolved}="${boundaryId}"></template>`);
|
|
17169
17747
|
ssr.emitOutOfOrderExecutorIfNeeded();
|
|
17170
|
-
ssr.queueOutOfOrderSegment(content
|
|
17748
|
+
ssr.queueOutOfOrderSegment(content
|
|
17749
|
+
.then((rendered) => emitRenderedOutOfOrderSegment(ssr, boundaryId, rendered, contentStyle, revealBoundary, boundaryState))
|
|
17750
|
+
.catch((error) => {
|
|
17751
|
+
if (errorBoundaryStore?.$emitFallback$) {
|
|
17752
|
+
return errorBoundaryStore.$emitFallback$(error);
|
|
17753
|
+
}
|
|
17754
|
+
if (errorBoundaryStore?.error !== undefined) {
|
|
17755
|
+
return;
|
|
17756
|
+
}
|
|
17757
|
+
throw error;
|
|
17758
|
+
}));
|
|
17171
17759
|
})
|
|
17172
17760
|
: null;
|
|
17173
17761
|
function createClaimedDeferredSlot(ssr, jsx, options) {
|
|
@@ -17183,7 +17771,7 @@ function createClaimedDeferredSlot(ssr, jsx, options) {
|
|
|
17183
17771
|
}
|
|
17184
17772
|
return /*#__PURE__*/ _jsxSorted(Slot, jsx.varProps, jsx.constProps, slotChildren, jsx.flags, jsx.key);
|
|
17185
17773
|
}
|
|
17186
|
-
async function emitRenderedOutOfOrderSegment(ssr, boundaryId,
|
|
17774
|
+
async function emitRenderedOutOfOrderSegment(ssr, boundaryId, rendered, contentStyle, revealBoundary, boundaryState) {
|
|
17187
17775
|
if (boundaryState) {
|
|
17188
17776
|
boundaryState.contentResolved = true;
|
|
17189
17777
|
if (boundaryState.delayTimer) {
|
|
@@ -17194,14 +17782,7 @@ async function emitRenderedOutOfOrderSegment(ssr, boundaryId, segmentId, rendere
|
|
|
17194
17782
|
revealBoundary?.resolve();
|
|
17195
17783
|
await ssr.$runQueuedRender$(async () => {
|
|
17196
17784
|
ssr.addRoot(contentStyle);
|
|
17197
|
-
|
|
17198
|
-
ssr.write(`<template ${QSuspenseResolved}="${boundaryId}"${revealBoundary?.attrs ?? ''}>`);
|
|
17199
|
-
ssr.write(result.html);
|
|
17200
|
-
ssr.write('</template>');
|
|
17201
|
-
ssr.emitOutOfOrderSegmentScripts(result.scripts);
|
|
17202
|
-
ssr.emitInlineScript(`qO(${boundaryId})`);
|
|
17203
|
-
// qO() is the browser-visible handoff for this segment, so flush it immediately.
|
|
17204
|
-
await ssr.streamHandler.flush();
|
|
17785
|
+
await finalizeAndSwapOutOfOrderSegment(ssr, boundaryId, rendered, revealBoundary);
|
|
17205
17786
|
});
|
|
17206
17787
|
}
|
|
17207
17788
|
function scheduleOutOfOrderFallbackDelay(ssr, boundaryState, state) {
|
|
@@ -17316,5 +17897,5 @@ if (import.meta.hot) {
|
|
|
17316
17897
|
});
|
|
17317
17898
|
}
|
|
17318
17899
|
|
|
17319
|
-
export { $, Each, Fragment, NoSerializeSymbol, PrefetchGraph, PrefetchServiceWorker, RenderOnce, Resource, Reveal, SSRComment, SSRRaw, SSRStream, SSRStreamBlock, SerializerSymbol, Show, SkipRender, Slot, Suspense, _CONST_PROPS, DomContainer as _DomContainer, _EFFECT_BACK_REF, ELEMENT_SEQ as _ELEMENT_SEQ, EMPTY_ARRAY as _EMPTY_ARRAY, EMPTY_OBJ as _EMPTY_OBJ, _IMMUTABLE, _SharedContainer, SubscriptionData as _SubscriptionData, SubscriptionPatch as _SubscriptionPatch, Task as _Task, _UNINITIALIZED, _VAR_PROPS, _addProjection, _captures, _chk, _createDeserializeContainer, createQRL as _createQRL, createStore as _createStore, delay as _delay, _deserialize, _dumpState, eachCmp as _eaC, eachCmpTask as _eaT, _executeSsrChores, _fnSignal, getAsyncLocalStorage as _getAsyncLocalStorage, _getConstProps, _getContextContainer, _getContextEvent, _getContextHostElement, getDomContainer as _getDomContainer, _getQContainerElement, getSubscriber as _getSubscriber, _getVarProps, _hasStoreEffects, _hmr, _injectAsyncSignalValue, invoke as _invoke, isJSXNode as _isJSXNode, isStore as _isStore, isStringifiable as _isStringifiable, isTask as _isTask, _jsxBranch, _jsxC, _jsxQ, _jsxS, _jsxSorted, _jsxSplit, mapApp_findIndx as _mapApp_findIndx, mapArray_get as _mapArray_get, mapArray_set as _mapArray_set, _markSignalAsExternallyOwned, newInvokeContext as _newInvokeContext, _noopQrl, _noopQrlDEV, preprocessState as _preprocessState, _qrlSync, qrlToString as _qrlToString, _qrlWithChunk, _qrlWithChunkDEV, revealCmp as _reC, revealCanReveal as _reR, revealCleanupTask as _reT, _regSymbol, _removeProjection, _res, _resolveContextWithoutSequentialScope, _restProps, retryOnPromise as _retryOnPromise, _rsc, _run, _serialize, setEvent as _setEvent, _setProjectionTarget, showCmp as _shC, showCmpTask as _shT, suspenseCmp as _suC, suspenseTask as _suT, scheduleTask as _task, _updateProjectionProps, _useHmr, _val, verifySerializable as _verifySerializable, vnode_ensureElementInflated as _vnode_ensureElementInflated, vnode_getAttrKeys as _vnode_getAttrKeys, vnode_getElementName as _vnode_getElementName, vnode_getFirstChild as _vnode_getFirstChild, vnode_getProp as _vnode_getProp, vnode_getVNodeForChildNode as _vnode_getVNodeForChildNode, vnode_insertBefore as _vnode_insertBefore, vnode_isElementVNode as _vnode_isElementVNode, vnode_isMaterialized as _vnode_isMaterialized, vnode_isTextVNode as _vnode_isTextVNode, vnode_isVirtualVNode as _vnode_isVirtualVNode, vnode_newVirtual as _vnode_newVirtual, vnode_remove as _vnode_remove, vnode_setProp as _vnode_setProp, vnode_toString as _vnode_toString, _waitUntilRendered, _walkJSX, _wrapProp, _wrapSignal, component$, componentQrl, createAsyncSignal as createAsyncQrl, createComputed$, createComputedSignal as createComputedQrl, createContextId, h as createElement, createSerializer$, createSerializerSignal as createSerializerQrl, createSignal, event$, eventQrl, forceStoreEffects, getClientManifest, getDomContainer, getLocale, getPlatform, h, implicit$FirstArg, inlinedQrl, inlinedQrlDEV, isSignal, jsx, jsxDEV, jsxs, noSerialize, qrl, qrlDEV, render, setPlatform, sync$, untrack, unwrapStore, useComputed$, useComputedQrl, useConstant, useContext, useContextProvider,
|
|
17900
|
+
export { $, Each, ErrorBoundary, Fragment, NoSerializeSymbol, PrefetchGraph, PrefetchServiceWorker, RenderOnce, Resource, Reveal, SSRComment, SSRRaw, SSRStream, SSRStreamBlock, SerializerSymbol, Show, SkipRender, Slot, Suspense, _CONST_PROPS, DomContainer as _DomContainer, _EFFECT_BACK_REF, ELEMENT_SEQ as _ELEMENT_SEQ, EMPTY_ARRAY as _EMPTY_ARRAY, EMPTY_OBJ as _EMPTY_OBJ, _IMMUTABLE, _SharedContainer, SubscriptionData as _SubscriptionData, SubscriptionPatch as _SubscriptionPatch, Task as _Task, _UNINITIALIZED, _VAR_PROPS, _addProjection, _captures, _chk, _createDeserializeContainer, createQRL as _createQRL, createStore as _createStore, delay as _delay, _deserialize, _dumpState, eachCmp as _eaC, eachCmpTask as _eaT, errorBoundaryCmp as _ebC, errorBoundaryReset as _ebR, _executeSsrChores, _fnSignal, getAsyncLocalStorage as _getAsyncLocalStorage, _getConstProps, _getContextContainer, _getContextEvent, _getContextHostElement, getDomContainer as _getDomContainer, _getQContainerElement, getSubscriber as _getSubscriber, _getVarProps, handleSSRError as _handleSSRError, _hasStoreEffects, _hmr, _injectAsyncSignalValue, invoke as _invoke, isJSXNode as _isJSXNode, isStore as _isStore, isStringifiable as _isStringifiable, isTask as _isTask, _jsxBranch, _jsxC, _jsxQ, _jsxS, _jsxSorted, _jsxSplit, mapApp_findIndx as _mapApp_findIndx, mapArray_get as _mapArray_get, mapArray_set as _mapArray_set, _markSignalAsExternallyOwned, newInvokeContext as _newInvokeContext, _noopQrl, _noopQrlDEV, preprocessState as _preprocessState, _qrlSync, qrlToString as _qrlToString, _qrlWithChunk, _qrlWithChunkDEV, revealCmp as _reC, revealCanReveal as _reR, revealCleanupTask as _reT, _regSymbol, _removeProjection, _res, _resolveContextWithoutSequentialScope, _restProps, retryOnPromise as _retryOnPromise, _rsc, _run, _serialize, setEvent as _setEvent, _setProjectionTarget, showCmp as _shC, showCmpTask as _shT, suspenseCmp as _suC, suspenseTask as _suT, scheduleTask as _task, _updateProjectionProps, _useHmr, _val, verifySerializable as _verifySerializable, vnode_ensureElementInflated as _vnode_ensureElementInflated, vnode_getAttrKeys as _vnode_getAttrKeys, vnode_getElementName as _vnode_getElementName, vnode_getFirstChild as _vnode_getFirstChild, vnode_getProp as _vnode_getProp, vnode_getVNodeForChildNode as _vnode_getVNodeForChildNode, vnode_insertBefore as _vnode_insertBefore, vnode_isElementVNode as _vnode_isElementVNode, vnode_isMaterialized as _vnode_isMaterialized, vnode_isTextVNode as _vnode_isTextVNode, vnode_isVirtualVNode as _vnode_isVirtualVNode, vnode_newVirtual as _vnode_newVirtual, vnode_remove as _vnode_remove, vnode_setProp as _vnode_setProp, vnode_toString as _vnode_toString, _waitUntilRendered, _walkJSX, _wrapProp, _wrapSignal, component$, componentQrl, createAsyncSignal as createAsyncQrl, createComputed$, createComputedSignal as createComputedQrl, createContextId, h as createElement, createSerializer$, createSerializerSignal as createSerializerQrl, createSignal, event$, eventQrl, forceStoreEffects, getClientManifest, getDomContainer, getLocale, getPlatform, h, implicit$FirstArg, inlinedQrl, inlinedQrlDEV, isSignal, jsx, jsxDEV, jsxs, noSerialize, qrl, qrlDEV, render, setPlatform, sync$, untrack, unwrapStore, useComputed$, useComputedQrl, useConstant, useContext, useContextProvider, useId, useLexicalScope, useOn, useOnDocument, useOnWindow, useResource$, useResourceQrl, useSerializer$, useSerializerQrl, useServerData, useSignal, useStore, useStyles$, useStylesQrl, useStylesScoped$, useStylesScopedQrl, useTask$, useTaskQrl, useVisibleTask$, useVisibleTaskQrl, version, withLocale };
|
|
17320
17901
|
//# sourceMappingURL=core.mjs.map
|