@qwik.dev/core 2.0.0-beta.38 → 2.0.0-beta.39
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 +14 -5
- package/dist/core-internal.d.ts +19 -76
- package/dist/core.min.mjs +9 -9
- package/dist/core.mjs +177 -266
- package/dist/core.mjs.map +1 -1
- package/dist/core.prod.mjs +2647 -2716
- package/dist/loader/index.mjs +2 -2
- package/dist/loader/package.json +1 -1
- package/dist/optimizer.mjs +1681 -1754
- package/dist/qwikloader.debug.js +1 -1
- package/dist/qwikloader.js +1 -1
- package/dist/server.mjs +28 -28
- package/dist/server.prod.mjs +282 -283
- package/dist/starters/adapters/fastify/package.json +2 -2
- package/dist/starters/features/csr/package.json +1 -1
- package/dist/starters/features/drizzle/package.json +1 -1
- package/dist/starters/features/vitest/package.json +1 -1
- package/dist/testing/index.d.ts +4 -2
- package/dist/testing/index.mjs +188 -257
- package/dist/testing/package.json +1 -1
- package/dist/worker/package.json +1 -1
- package/package.json +6 -6
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.39-dev+6fb620f
|
|
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
|
|
@@ -321,6 +321,7 @@ const VNodeDataChar = {
|
|
|
321
321
|
CLOSE: /* ************* */ 125, // `}` is the end of the VNodeData for a virtual element.
|
|
322
322
|
SCOPED_STYLE: /* ******* */ 59, // `;` - `q:sstyle` - Style attribute.
|
|
323
323
|
RENDER_FN: /* ********** */ 60, // `<` - `q:renderFn' - Component QRL render function (body)
|
|
324
|
+
RENDER_HASH_PREFIX: /* **/ 95, // `_` after `<` identifies a component hash.
|
|
324
325
|
ID: /* ***************** */ 61, // `=` - `q:id` - ID of the element.
|
|
325
326
|
PROPS: /* ************** */ 62, // `>` - `q:props' - Component Props
|
|
326
327
|
SLOT_PARENT: /* ******** */ 63, // `?` - `q:sparent` - Slot parent.
|
|
@@ -405,6 +406,7 @@ function decodeVNodeDataString(str) {
|
|
|
405
406
|
|
|
406
407
|
/** State factory of the component. */
|
|
407
408
|
const OnRenderProp = 'q:renderFn';
|
|
409
|
+
const QComponentHash = 'q:componentHash';
|
|
408
410
|
/** Target DOM element for external projection rendering. */
|
|
409
411
|
const QTargetElement = 'q:targetEl';
|
|
410
412
|
/** Component style content prefix */
|
|
@@ -438,7 +440,6 @@ const QIgnore = 'q:ignore';
|
|
|
438
440
|
const QIgnoreEnd = '/' + QIgnore;
|
|
439
441
|
const QContainerAttr = 'q:container';
|
|
440
442
|
const QContainerAttrEnd = '/' + QContainerAttr;
|
|
441
|
-
const QCursorBoundary = 'q:cursorBoundary';
|
|
442
443
|
const QTemplate = 'q:template';
|
|
443
444
|
// the same selector should be inside the qwik loader
|
|
444
445
|
// and the same selector should be inside the qwik router spa-shim and spa-init
|
|
@@ -479,6 +480,7 @@ const NON_SERIALIZABLE_MARKER_PREFIX = ':';
|
|
|
479
480
|
const USE_ON_LOCAL = NON_SERIALIZABLE_MARKER_PREFIX + 'on';
|
|
480
481
|
const USE_ON_LOCAL_SEQ_IDX = NON_SERIALIZABLE_MARKER_PREFIX + 'onIdx';
|
|
481
482
|
const USE_ON_LOCAL_FLAGS = NON_SERIALIZABLE_MARKER_PREFIX + 'onFlags';
|
|
483
|
+
const QCursorBoundary = NON_SERIALIZABLE_MARKER_PREFIX + 'cursorBoundary';
|
|
482
484
|
const NEAREST_CURSOR_BOUNDARY = NON_SERIALIZABLE_MARKER_PREFIX + 'nearestCursorBoundary';
|
|
483
485
|
const Q_PROPS_SEPARATOR = ':';
|
|
484
486
|
const dangerouslySetInnerHTML = 'dangerouslySetInnerHTML';
|
|
@@ -1264,7 +1266,7 @@ const COMMA = ',';
|
|
|
1264
1266
|
*
|
|
1265
1267
|
* @public
|
|
1266
1268
|
*/
|
|
1267
|
-
const version = "2.0.0-beta.
|
|
1269
|
+
const version = "2.0.0-beta.39-dev+6fb620f";
|
|
1268
1270
|
|
|
1269
1271
|
const isNode = (value) => {
|
|
1270
1272
|
return value && typeof value.nodeType === 'number';
|
|
@@ -2314,7 +2316,7 @@ class Job {
|
|
|
2314
2316
|
/** Backward compatible cache method for resource */
|
|
2315
2317
|
cache() {
|
|
2316
2318
|
isDev &&
|
|
2317
|
-
console.error('useResource cache() method does not do anything. Use `useComputed$` instead of `useResource
|
|
2319
|
+
console.error('useResource cache() method does not do anything. Use `useComputed$` instead of `useResource$`; for polling use the `usePoll` hook from `@qwik.dev/utils`.');
|
|
2318
2320
|
}
|
|
2319
2321
|
get previous() {
|
|
2320
2322
|
const val = this.$signal$.$untrackedValue$;
|
|
@@ -2333,7 +2335,7 @@ class Job {
|
|
|
2333
2335
|
*
|
|
2334
2336
|
* Sync compute functions resolve synchronously and every read they perform is auto-tracked. When
|
|
2335
2337
|
* the compute function turns out to be async (it returned a promise), the signal lazily switches on
|
|
2336
|
-
* the async engine — jobs, `loading`, `error
|
|
2338
|
+
* the async engine — jobs, `loading`, `error` — giving it the same API as an AsyncSignal.
|
|
2337
2339
|
* Auto-tracking only covers reads before the first await point (the invoke context is lost after
|
|
2338
2340
|
* it); later reads must use the ComputeCtx `track()`.
|
|
2339
2341
|
*/
|
|
@@ -2381,20 +2383,11 @@ class ComputedSignalImpl extends SignalImpl {
|
|
|
2381
2383
|
// clientOnly can never resolve during SSR, so it must be async from the start
|
|
2382
2384
|
this.$flags$ |= 64 /* AsyncSignalFlags.CLIENT_ONLY */ | 512 /* AsyncSignalFlags.ASYNC_MODE */;
|
|
2383
2385
|
}
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
this.$flags$ |= 128 /* AsyncSignalFlags.CLEAR_ON_INVALIDATE */;
|
|
2390
|
-
}
|
|
2391
|
-
const expires = options.expires ?? (options.interval ? Math.abs(options.interval) : undefined);
|
|
2392
|
-
if (expires) {
|
|
2393
|
-
this.expires = expires;
|
|
2394
|
-
}
|
|
2395
|
-
if (options.poll === false || (options.interval !== undefined && options.interval < 0)) {
|
|
2396
|
-
this.$flags$ |= 256 /* AsyncSignalFlags.NO_POLL */;
|
|
2397
|
-
}
|
|
2386
|
+
}
|
|
2387
|
+
/** Clear the value so readers see the loading state, then recompute. */
|
|
2388
|
+
clear() {
|
|
2389
|
+
this.$untrackedValue$ = NEEDS_COMPUTATION;
|
|
2390
|
+
this.invalidate();
|
|
2398
2391
|
}
|
|
2399
2392
|
invalidate(info) {
|
|
2400
2393
|
if (arguments.length > 0) {
|
|
@@ -2402,7 +2395,7 @@ class ComputedSignalImpl extends SignalImpl {
|
|
|
2402
2395
|
this.$infoVersion$ = this.$infoVersion$ === undefined ? 1 : this.$infoVersion$ + 1;
|
|
2403
2396
|
}
|
|
2404
2397
|
if (this.$flags$ & 512 /* AsyncSignalFlags.ASYNC_MODE */) {
|
|
2405
|
-
this.$setInvalid$(true
|
|
2398
|
+
this.$setInvalid$(true);
|
|
2406
2399
|
return;
|
|
2407
2400
|
}
|
|
2408
2401
|
this.$flags$ |= 1 /* ComputedSignalFlags.INVALID */;
|
|
@@ -2450,9 +2443,7 @@ class ComputedSignalImpl extends SignalImpl {
|
|
|
2450
2443
|
else if (this.$current$) {
|
|
2451
2444
|
this.$current$.$canWrite$ = false;
|
|
2452
2445
|
}
|
|
2453
|
-
this.$clearNextPoll$();
|
|
2454
2446
|
super.value = value;
|
|
2455
|
-
this.$scheduleNextPoll$();
|
|
2456
2447
|
return;
|
|
2457
2448
|
}
|
|
2458
2449
|
super.value = value;
|
|
@@ -2572,52 +2563,8 @@ class ComputedSignalImpl extends SignalImpl {
|
|
|
2572
2563
|
}
|
|
2573
2564
|
return this.$untrackedError$;
|
|
2574
2565
|
}
|
|
2575
|
-
|
|
2576
|
-
return this.$expires$ || 0;
|
|
2577
|
-
}
|
|
2578
|
-
set expires(value) {
|
|
2579
|
-
this.$clearNextPoll$();
|
|
2580
|
-
this.$expires$ = value;
|
|
2581
|
-
if (this.$expires$ && this.$hasSubscribers$()) {
|
|
2582
|
-
this.$scheduleNextPoll$();
|
|
2583
|
-
}
|
|
2584
|
-
}
|
|
2585
|
-
get poll() {
|
|
2586
|
-
return !(this.$flags$ & 256 /* AsyncSignalFlags.NO_POLL */);
|
|
2587
|
-
}
|
|
2588
|
-
set poll(value) {
|
|
2589
|
-
if (value) {
|
|
2590
|
-
this.$flags$ &= -257 /* AsyncSignalFlags.NO_POLL */;
|
|
2591
|
-
}
|
|
2592
|
-
else {
|
|
2593
|
-
this.$flags$ |= 256 /* AsyncSignalFlags.NO_POLL */;
|
|
2594
|
-
}
|
|
2595
|
-
// Reschedule since poll behavior changed
|
|
2596
|
-
if (this.$expires$ && this.$hasSubscribers$()) {
|
|
2597
|
-
this.$clearNextPoll$();
|
|
2598
|
-
this.$scheduleNextPoll$();
|
|
2599
|
-
}
|
|
2600
|
-
}
|
|
2601
|
-
/** @deprecated Use `expires` and `poll` instead. */
|
|
2602
|
-
get interval() {
|
|
2603
|
-
const expires = this.$expires$ || 0;
|
|
2604
|
-
return this.$flags$ & 256 /* AsyncSignalFlags.NO_POLL */ ? -expires : expires;
|
|
2605
|
-
}
|
|
2606
|
-
set interval(value) {
|
|
2607
|
-
if (value < 0) {
|
|
2608
|
-
this.$flags$ |= 256 /* AsyncSignalFlags.NO_POLL */;
|
|
2609
|
-
}
|
|
2610
|
-
else {
|
|
2611
|
-
this.$flags$ &= -257 /* AsyncSignalFlags.NO_POLL */;
|
|
2612
|
-
}
|
|
2613
|
-
this.expires = Math.abs(value);
|
|
2614
|
-
}
|
|
2615
|
-
$setInvalid$(allowRecalc, mustClear) {
|
|
2566
|
+
$setInvalid$(allowRecalc) {
|
|
2616
2567
|
this.$flags$ |= 1 /* ComputedSignalFlags.INVALID */;
|
|
2617
|
-
this.$clearNextPoll$();
|
|
2618
|
-
if (mustClear) {
|
|
2619
|
-
this.$untrackedValue$ = NEEDS_COMPUTATION;
|
|
2620
|
-
}
|
|
2621
2568
|
if (allowRecalc &&
|
|
2622
2569
|
(this.$effects$?.size || this.$loadingEffects$?.size || this.$errorEffects$?.size)) {
|
|
2623
2570
|
// compute in next microtask
|
|
@@ -2742,7 +2689,6 @@ class ComputedSignalImpl extends SignalImpl {
|
|
|
2742
2689
|
this.$container$?.serializationCtx.$eagerResume$.add(this);
|
|
2743
2690
|
return;
|
|
2744
2691
|
}
|
|
2745
|
-
this.$clearNextPoll$();
|
|
2746
2692
|
// Clear flag here to make sure the cleanups don't start another compute
|
|
2747
2693
|
this.$flags$ &= -2 /* ComputedSignalFlags.INVALID */;
|
|
2748
2694
|
const current = this.$current$;
|
|
@@ -2845,7 +2791,6 @@ class ComputedSignalImpl extends SignalImpl {
|
|
|
2845
2791
|
}
|
|
2846
2792
|
else {
|
|
2847
2793
|
this.untrackedPending = false;
|
|
2848
|
-
this.$scheduleNextPoll$();
|
|
2849
2794
|
}
|
|
2850
2795
|
}
|
|
2851
2796
|
}
|
|
@@ -2868,7 +2813,6 @@ class ComputedSignalImpl extends SignalImpl {
|
|
|
2868
2813
|
}
|
|
2869
2814
|
/** Called after SSR/unmount */
|
|
2870
2815
|
async $destroy$() {
|
|
2871
|
-
this.$clearNextPoll$();
|
|
2872
2816
|
clearTimeout(this.$computationTimeoutId$);
|
|
2873
2817
|
const current = this.$current$;
|
|
2874
2818
|
if (current) {
|
|
@@ -2881,24 +2825,6 @@ class ComputedSignalImpl extends SignalImpl {
|
|
|
2881
2825
|
await current?.$promise$;
|
|
2882
2826
|
}
|
|
2883
2827
|
}
|
|
2884
|
-
$clearNextPoll$() {
|
|
2885
|
-
if (this.$pollTimeoutId$ !== undefined) {
|
|
2886
|
-
clearTimeout(this.$pollTimeoutId$);
|
|
2887
|
-
this.$pollTimeoutId$ = undefined;
|
|
2888
|
-
}
|
|
2889
|
-
}
|
|
2890
|
-
$scheduleNextPoll$() {
|
|
2891
|
-
if ((qTest ? isServerPlatform() : isServer) || !this.$expires$) {
|
|
2892
|
-
return;
|
|
2893
|
-
}
|
|
2894
|
-
this.$clearNextPoll$();
|
|
2895
|
-
const allowRecalc = !(this.$flags$ & 256 /* AsyncSignalFlags.NO_POLL */);
|
|
2896
|
-
// Even when clear on invalidate, we don't clear if we're merely re-running due to polling
|
|
2897
|
-
// We expect to get the new value soon, so we can avoid showing a loading state
|
|
2898
|
-
const mustClear = this.$flags$ & 128 /* AsyncSignalFlags.CLEAR_ON_INVALIDATE */ && !allowRecalc;
|
|
2899
|
-
this.$pollTimeoutId$ = setTimeout(() => this.$setInvalid$(allowRecalc, mustClear), this.$expires$);
|
|
2900
|
-
this.$pollTimeoutId$?.unref?.();
|
|
2901
|
-
}
|
|
2902
2828
|
$hasSubscribers$() {
|
|
2903
2829
|
return !!(this.$effects$?.size || this.$loadingEffects$?.size || this.$errorEffects$?.size);
|
|
2904
2830
|
}
|
|
@@ -3053,9 +2979,9 @@ class SerializerSignalImpl extends ComputedSignalImpl {
|
|
|
3053
2979
|
*
|
|
3054
2980
|
* # ================================
|
|
3055
2981
|
*
|
|
3056
|
-
* The async engine (jobs, loading, error
|
|
3057
|
-
*
|
|
3058
|
-
*
|
|
2982
|
+
* The async engine (jobs, loading, error) lives in ComputedSignalImpl; this subclass configures it
|
|
2983
|
+
* from options and switches the compute invocation to CTX_ARG mode: the compute fn receives the
|
|
2984
|
+
* ComputeCtx argument and tracks only via its explicit `track()` (no auto-tracking).
|
|
3059
2985
|
*
|
|
3060
2986
|
* @internal
|
|
3061
2987
|
*/
|
|
@@ -4066,31 +3992,25 @@ const useConstant = (value, ...args) => {
|
|
|
4066
3992
|
return set(value);
|
|
4067
3993
|
};
|
|
4068
3994
|
|
|
4069
|
-
const createCursorBoundary = () => {
|
|
4070
|
-
return {
|
|
4071
|
-
pending: createSignal(0),
|
|
4072
|
-
version: createSignal(0),
|
|
4073
|
-
};
|
|
4074
|
-
};
|
|
4075
3995
|
/** @internal */
|
|
4076
3996
|
const useCursorBoundary = () => {
|
|
4077
3997
|
if (!__EXPERIMENTAL__.suspense) {
|
|
4078
3998
|
throw new Error('useCursorBoundary is experimental and must be enabled with `experimental: ["suspense"]` in the `qwikVite` plugin.');
|
|
4079
3999
|
}
|
|
4080
|
-
return
|
|
4000
|
+
return useSignal(0);
|
|
4081
4001
|
};
|
|
4082
4002
|
function addCursorBoundary(cursorData, vNode) {
|
|
4083
4003
|
if (!__EXPERIMENTAL__.suspense) {
|
|
4084
4004
|
return;
|
|
4085
4005
|
}
|
|
4086
|
-
const boundary = getNearestCursorBoundary(
|
|
4006
|
+
const boundary = getNearestCursorBoundary(vNode);
|
|
4087
4007
|
if (!boundary) {
|
|
4088
4008
|
return;
|
|
4089
4009
|
}
|
|
4090
4010
|
const boundaries = (cursorData.boundaries ||= []);
|
|
4091
4011
|
if (!boundaries.includes(boundary)) {
|
|
4092
4012
|
boundaries.push(boundary);
|
|
4093
|
-
boundary.
|
|
4013
|
+
boundary.value++;
|
|
4094
4014
|
}
|
|
4095
4015
|
}
|
|
4096
4016
|
function resolveCursorBoundaries(cursorData) {
|
|
@@ -4104,40 +4024,35 @@ function resolveCursorBoundaries(cursorData) {
|
|
|
4104
4024
|
cursorData.boundaries = null;
|
|
4105
4025
|
for (let i = 0; i < boundaries.length; i++) {
|
|
4106
4026
|
const boundary = boundaries[i];
|
|
4107
|
-
boundary.
|
|
4108
|
-
boundary.version.value++;
|
|
4027
|
+
boundary.value = Math.max(0, boundary.value - 1);
|
|
4109
4028
|
}
|
|
4110
4029
|
}
|
|
4111
|
-
function getOwnCursorBoundary(
|
|
4030
|
+
function getOwnCursorBoundary(vNode) {
|
|
4112
4031
|
if (!__EXPERIMENTAL__.suspense) {
|
|
4113
4032
|
return null;
|
|
4114
4033
|
}
|
|
4115
|
-
return
|
|
4116
|
-
}
|
|
4117
|
-
function getNearestCursorBoundaryProp(vNode) {
|
|
4118
|
-
if (!__EXPERIMENTAL__.suspense) {
|
|
4119
|
-
return null;
|
|
4120
|
-
}
|
|
4121
|
-
return (vnode_getProp(vNode, NEAREST_CURSOR_BOUNDARY, null) ||
|
|
4122
|
-
null);
|
|
4034
|
+
return vnode_getProp(vNode, QCursorBoundary, null) || null;
|
|
4123
4035
|
}
|
|
4124
4036
|
function clearNearestCursorBoundary(vNode) {
|
|
4125
|
-
|
|
4126
|
-
return;
|
|
4127
|
-
}
|
|
4128
|
-
vnode_setProp(vNode, NEAREST_CURSOR_BOUNDARY, null);
|
|
4037
|
+
setNearestCursorBoundary(vNode, null);
|
|
4129
4038
|
}
|
|
4130
|
-
function getNearestCursorBoundary(
|
|
4039
|
+
function getNearestCursorBoundary(vNode) {
|
|
4131
4040
|
if (!__EXPERIMENTAL__.suspense) {
|
|
4132
4041
|
return null;
|
|
4133
4042
|
}
|
|
4134
|
-
return
|
|
4043
|
+
return (vnode_getProp(vNode, NEAREST_CURSOR_BOUNDARY, null) ||
|
|
4044
|
+
getOwnCursorBoundary(vNode));
|
|
4135
4045
|
}
|
|
4136
4046
|
function setNearestCursorBoundary(vNode, boundary) {
|
|
4137
4047
|
__EXPERIMENTAL__.suspense && vnode_setProp(vNode, NEAREST_CURSOR_BOUNDARY, boundary);
|
|
4138
4048
|
}
|
|
4049
|
+
function clearCursorBoundary(vNode) {
|
|
4050
|
+
if (__EXPERIMENTAL__.suspense && vNode.props && QCursorBoundary in vNode.props) {
|
|
4051
|
+
vnode_setProp(vNode, QCursorBoundary, null);
|
|
4052
|
+
}
|
|
4053
|
+
}
|
|
4139
4054
|
/** Updates the nearest cursor boundary cache on a vnode and any already-dirty descendants. */
|
|
4140
|
-
function updateDirtySubtreeCursorBoundary(
|
|
4055
|
+
function updateDirtySubtreeCursorBoundary(vNode, boundary) {
|
|
4141
4056
|
if (!__EXPERIMENTAL__.suspense) {
|
|
4142
4057
|
return;
|
|
4143
4058
|
}
|
|
@@ -4148,7 +4063,7 @@ function updateDirtySubtreeCursorBoundary(container, vNode, boundary) {
|
|
|
4148
4063
|
}
|
|
4149
4064
|
for (let i = 0; i < dirtyChildren.length; i++) {
|
|
4150
4065
|
const child = dirtyChildren[i];
|
|
4151
|
-
updateDirtySubtreeCursorBoundary(
|
|
4066
|
+
updateDirtySubtreeCursorBoundary(child, getOwnCursorBoundary(child) || boundary);
|
|
4152
4067
|
}
|
|
4153
4068
|
}
|
|
4154
4069
|
|
|
@@ -4698,7 +4613,7 @@ function expectSlot(diffContext) {
|
|
|
4698
4613
|
diffContext.$vNewNode$ = vnode_newVirtual();
|
|
4699
4614
|
vnode_setProp(diffContext.$vNewNode$, QSlot, slotNameKey);
|
|
4700
4615
|
vnode_setProp(diffContext.$vNewNode$, QCursorBoundary, cursorBoundary);
|
|
4701
|
-
updateDirtySubtreeCursorBoundary(diffContext.$
|
|
4616
|
+
updateDirtySubtreeCursorBoundary(diffContext.$vNewNode$, cursorBoundary);
|
|
4702
4617
|
vHost && vnode_setProp(vHost, slotNameKey, diffContext.$vNewNode$);
|
|
4703
4618
|
isDev &&
|
|
4704
4619
|
vnode_setProp(diffContext.$vNewNode$, DEBUG_TYPE, "P" /* VirtualType.Projection */); // Nothing to project, so render content of the slot.
|
|
@@ -4712,7 +4627,7 @@ function expectSlot(diffContext) {
|
|
|
4712
4627
|
diffContext.$vNewNode$ = vProjectedNode;
|
|
4713
4628
|
vnode_setProp(diffContext.$vNewNode$, QSlot, slotNameKey);
|
|
4714
4629
|
vnode_setProp(diffContext.$vNewNode$, QCursorBoundary, cursorBoundary);
|
|
4715
|
-
updateDirtySubtreeCursorBoundary(diffContext.$
|
|
4630
|
+
updateDirtySubtreeCursorBoundary(diffContext.$vNewNode$, cursorBoundary);
|
|
4716
4631
|
vHost && vnode_setProp(vHost, slotNameKey, diffContext.$vNewNode$);
|
|
4717
4632
|
isDev &&
|
|
4718
4633
|
vnode_setProp(diffContext.$vNewNode$, DEBUG_TYPE, "P" /* VirtualType.Projection */);
|
|
@@ -5404,7 +5319,9 @@ function getComponentHash(vNode, getObject) {
|
|
|
5404
5319
|
return null;
|
|
5405
5320
|
}
|
|
5406
5321
|
const qrl = vnode_getProp(vNode, OnRenderProp, getObject);
|
|
5407
|
-
return qrl
|
|
5322
|
+
return qrl
|
|
5323
|
+
? qrl.$hash$
|
|
5324
|
+
: vnode_getProp(vNode, QComponentHash, null);
|
|
5408
5325
|
}
|
|
5409
5326
|
/**
|
|
5410
5327
|
* Marker class for JSX projection.
|
|
@@ -6029,8 +5946,8 @@ function findFirstElementNode(jsx) {
|
|
|
6029
5946
|
function injectPlaceholderElement(jsx, placeholder) {
|
|
6030
5947
|
// For regular JSX nodes, we can append the placeholder to its children.
|
|
6031
5948
|
if (isJSXNode(jsx)) {
|
|
6032
|
-
// Inline components
|
|
6033
|
-
if (jsx.type !== Fragment
|
|
5949
|
+
// Inline components may ignore children, while component$ children become projections.
|
|
5950
|
+
if (jsx.type !== Fragment) {
|
|
6034
5951
|
return _jsxSorted(Fragment, null, null, [jsx, placeholder], 0, null);
|
|
6035
5952
|
}
|
|
6036
5953
|
if (jsx.children == null) {
|
|
@@ -6994,6 +6911,7 @@ function finishWalk(container, cursor, cursorData, isServer) {
|
|
|
6994
6911
|
executeFlushPhase(cursor, container);
|
|
6995
6912
|
}
|
|
6996
6913
|
resolveCursorBoundaries(cursorData);
|
|
6914
|
+
clearCursorBoundary(cursor);
|
|
6997
6915
|
if (cursorData.extraPromises) {
|
|
6998
6916
|
Promise.all(cursorData.extraPromises).then(() => {
|
|
6999
6917
|
resolveCursor(container);
|
|
@@ -7094,12 +7012,7 @@ function getNextVNode(vNode, cursor, container) {
|
|
|
7094
7012
|
return getNextVNode(parent, cursor, container);
|
|
7095
7013
|
}
|
|
7096
7014
|
function splitCursorBoundary(container, vNode) {
|
|
7097
|
-
if (!
|
|
7098
|
-
return false;
|
|
7099
|
-
}
|
|
7100
|
-
if (!vNode.props ||
|
|
7101
|
-
!(QCursorBoundary in vNode.props) ||
|
|
7102
|
-
!container.getHostProp(vNode, QCursorBoundary)) {
|
|
7015
|
+
if (!getOwnCursorBoundary(vNode)) {
|
|
7103
7016
|
return false;
|
|
7104
7017
|
}
|
|
7105
7018
|
if (!isCursor(vNode)) {
|
|
@@ -7300,17 +7213,16 @@ function propagatePath(target) {
|
|
|
7300
7213
|
* Propagates dirty bits from vNode up to the specified cursorRoot. Used during diff when we know
|
|
7301
7214
|
* the cursor root to merge with. Also updates cursor position if we pass through any cursors.
|
|
7302
7215
|
*/
|
|
7303
|
-
function propagateToCursorRoot(
|
|
7216
|
+
function propagateToCursorRoot(vNode, cursorRoot) {
|
|
7304
7217
|
reusablePath.push(vNode);
|
|
7305
|
-
let cursorBoundary = getOwnCursorBoundary(
|
|
7218
|
+
let cursorBoundary = getOwnCursorBoundary(vNode);
|
|
7306
7219
|
let current = vNode.slotParent || vNode.parent;
|
|
7307
7220
|
while (current) {
|
|
7308
7221
|
const isDirty = current.dirty & 1023 /* ChoreBits.DIRTY_MASK */;
|
|
7309
7222
|
const currentIsCursor = isCursor(current);
|
|
7310
7223
|
if (__EXPERIMENTAL__.suspense) {
|
|
7311
7224
|
cursorBoundary ||=
|
|
7312
|
-
getOwnCursorBoundary(
|
|
7313
|
-
(isDirty ? getNearestCursorBoundary(container, current) : null);
|
|
7225
|
+
getOwnCursorBoundary(current) || (isDirty ? getNearestCursorBoundary(current) : null);
|
|
7314
7226
|
}
|
|
7315
7227
|
// Stop when we reach the cursor root or a dirty ancestor
|
|
7316
7228
|
if (current === cursorRoot || isDirty) {
|
|
@@ -7345,18 +7257,16 @@ function propagateToCursorRoot(container, vNode, cursorRoot) {
|
|
|
7345
7257
|
* Finds a blocking cursor or dirty ancestor and propagates dirty bits to it. Returns true if found
|
|
7346
7258
|
* and attached, false if a new cursor should be created.
|
|
7347
7259
|
*/
|
|
7348
|
-
function findAndPropagateToBlockingCursor(
|
|
7260
|
+
function findAndPropagateToBlockingCursor(vNode) {
|
|
7349
7261
|
reusablePath.push(vNode);
|
|
7350
|
-
let cursorBoundary =
|
|
7351
|
-
? getOwnCursorBoundary(container, vNode)
|
|
7352
|
-
: null;
|
|
7262
|
+
let cursorBoundary = getOwnCursorBoundary(vNode);
|
|
7353
7263
|
let current = vNode.slotParent || vNode.parent;
|
|
7354
7264
|
while (current) {
|
|
7355
7265
|
const currentIsCursor = isCursor(current);
|
|
7356
7266
|
if (__EXPERIMENTAL__.suspense) {
|
|
7357
7267
|
cursorBoundary ||=
|
|
7358
|
-
getOwnCursorBoundary(
|
|
7359
|
-
(currentIsCursor ? getNearestCursorBoundary(
|
|
7268
|
+
getOwnCursorBoundary(current) ||
|
|
7269
|
+
(currentIsCursor ? getNearestCursorBoundary(current) : null);
|
|
7360
7270
|
}
|
|
7361
7271
|
if (currentIsCursor) {
|
|
7362
7272
|
// Existing cursor case: attach this dirty vnode to the blocking cursor found above it and
|
|
@@ -7397,7 +7307,7 @@ function markVNodeDirty(container, vNode, bits, cursorRoot = null) {
|
|
|
7397
7307
|
? container.$renderPromise$.then(() => result)
|
|
7398
7308
|
: result;
|
|
7399
7309
|
}
|
|
7400
|
-
return;
|
|
7310
|
+
return result;
|
|
7401
7311
|
}
|
|
7402
7312
|
const isRealDirty = bits & 1023 /* ChoreBits.DIRTY_MASK */;
|
|
7403
7313
|
// If already dirty, no need to propagate again
|
|
@@ -7407,14 +7317,14 @@ function markVNodeDirty(container, vNode, bits, cursorRoot = null) {
|
|
|
7407
7317
|
const parent = vNode.slotParent || vNode.parent;
|
|
7408
7318
|
// If cursorRoot is provided, propagate up to it
|
|
7409
7319
|
if (cursorRoot && isRealDirty && parent && !parent.dirty) {
|
|
7410
|
-
propagateToCursorRoot(
|
|
7320
|
+
propagateToCursorRoot(vNode, cursorRoot);
|
|
7411
7321
|
return;
|
|
7412
7322
|
}
|
|
7413
7323
|
// We must attach to a cursor subtree if it exists
|
|
7414
7324
|
if (parent && parent.dirty & 1023 /* ChoreBits.DIRTY_MASK */) {
|
|
7415
7325
|
// Dirty parent case: this vnode joins an already scheduled subtree, so inherit the parent's
|
|
7416
7326
|
// nearest boundary unless this vnode owns a boundary itself.
|
|
7417
|
-
setNearestCursorBoundary(vNode, getOwnCursorBoundary(
|
|
7327
|
+
setNearestCursorBoundary(vNode, getOwnCursorBoundary(vNode) || getNearestCursorBoundary(parent));
|
|
7418
7328
|
if (isRealDirty) {
|
|
7419
7329
|
parent.dirty |= 64 /* ChoreBits.CHILDREN */;
|
|
7420
7330
|
}
|
|
@@ -7446,7 +7356,7 @@ function markVNodeDirty(container, vNode, bits, cursorRoot = null) {
|
|
|
7446
7356
|
else if (!isCursor(vNode)) {
|
|
7447
7357
|
// Check if there's an existing cursor that is blocking (executing a render-blocking task)
|
|
7448
7358
|
// If so, merge with it instead of creating a new cursor (single-pass find + propagate)
|
|
7449
|
-
if (!findAndPropagateToBlockingCursor(
|
|
7359
|
+
if (!findAndPropagateToBlockingCursor(vNode)) {
|
|
7450
7360
|
// No blocking cursor found, create a new one
|
|
7451
7361
|
addCursor(container, vNode, 0);
|
|
7452
7362
|
}
|
|
@@ -7454,7 +7364,7 @@ function markVNodeDirty(container, vNode, bits, cursorRoot = null) {
|
|
|
7454
7364
|
else {
|
|
7455
7365
|
// Existing cursor-root case: the vnode is already the scheduled cursor, so only its own
|
|
7456
7366
|
// boundary can be authoritative here.
|
|
7457
|
-
setNearestCursorBoundary(vNode, getOwnCursorBoundary(
|
|
7367
|
+
setNearestCursorBoundary(vNode, getOwnCursorBoundary(vNode));
|
|
7458
7368
|
}
|
|
7459
7369
|
}
|
|
7460
7370
|
function addVNodeOperation(journal, operation) {
|
|
@@ -9132,8 +9042,14 @@ function materializeFromVNodeData(vParent, vData, element, child, segmentId) {
|
|
|
9132
9042
|
vnode_setProp(vParent, QScopedStyle, consumeValue());
|
|
9133
9043
|
}
|
|
9134
9044
|
else if (peek() === VNodeDataChar.RENDER_FN) {
|
|
9135
|
-
|
|
9136
|
-
|
|
9045
|
+
const renderRef = consumeValue();
|
|
9046
|
+
if (renderRef.charCodeAt(0) === VNodeDataChar.RENDER_HASH_PREFIX) {
|
|
9047
|
+
vnode_setProp(vParent, QComponentHash, decodeURIComponent(decodeVNodeDataString(renderRef.slice(1))));
|
|
9048
|
+
}
|
|
9049
|
+
else {
|
|
9050
|
+
(components ||= []).push(vParent);
|
|
9051
|
+
vnode_setProp(vParent, OnRenderProp, renderRef);
|
|
9052
|
+
}
|
|
9137
9053
|
}
|
|
9138
9054
|
else if (peek() === VNodeDataChar.ID) {
|
|
9139
9055
|
if (!container) {
|
|
@@ -9181,7 +9097,7 @@ function materializeFromVNodeData(vParent, vData, element, child, segmentId) {
|
|
|
9181
9097
|
else if (peek() === VNodeDataChar.SEPARATOR) {
|
|
9182
9098
|
// Custom attribute: |key|value
|
|
9183
9099
|
const keyValue = consumeValue();
|
|
9184
|
-
const key = decodeVNodeDataString(keyValue);
|
|
9100
|
+
const key = decodeURIComponent(decodeVNodeDataString(keyValue));
|
|
9185
9101
|
const valueSeparatorIdx = dataIdx + keyValue.length + 1;
|
|
9186
9102
|
const isEscapedValue = getChar(valueSeparatorIdx + 1) === VNodeDataChar.SEPARATOR;
|
|
9187
9103
|
let value;
|
|
@@ -10776,7 +10692,6 @@ class Serializer {
|
|
|
10776
10692
|
// async-mode computeds carry the same engine state and must round-trip like AsyncSignals
|
|
10777
10693
|
const isAsync = !!(value.$flags$ & 512 /* AsyncSignalFlags.ASYNC_MODE */);
|
|
10778
10694
|
const isErrored = isAsync && !!value.$untrackedError$;
|
|
10779
|
-
const expires = isAsync && value.$expires$ !== 0 ? value.$expires$ : undefined;
|
|
10780
10695
|
const concurrency = isAsync && value.$concurrency$ !== 1 ? value.$concurrency$ : undefined;
|
|
10781
10696
|
const timeout = isAsync && value.$timeoutMs$ !== 0 ? value.$timeoutMs$ : undefined;
|
|
10782
10697
|
// Send the flags but remove the serialization bits and default to 0 when undefined
|
|
@@ -10797,10 +10712,7 @@ class Serializer {
|
|
|
10797
10712
|
out.push(value.$loadingEffects$, value.$errorEffects$, value.$untrackedError$);
|
|
10798
10713
|
out.push(asyncFlags || undefined);
|
|
10799
10714
|
}
|
|
10800
|
-
if (v !== NEEDS_COMPUTATION ||
|
|
10801
|
-
expires !== undefined ||
|
|
10802
|
-
concurrency !== undefined ||
|
|
10803
|
-
timeout !== undefined) {
|
|
10715
|
+
if (v !== NEEDS_COMPUTATION || concurrency !== undefined || timeout !== undefined) {
|
|
10804
10716
|
/**
|
|
10805
10717
|
* If value is undefined, we need to keep it in the output. If we don't do that, later
|
|
10806
10718
|
* during resuming, the value will be set to symbol(invalid) with flag invalid, and thats
|
|
@@ -10809,7 +10721,6 @@ class Serializer {
|
|
|
10809
10721
|
out.push(v === undefined ? explicitUndefined : v);
|
|
10810
10722
|
}
|
|
10811
10723
|
if (isAsync) {
|
|
10812
|
-
out.push(expires);
|
|
10813
10724
|
out.push(concurrency);
|
|
10814
10725
|
out.push(timeout);
|
|
10815
10726
|
}
|
|
@@ -12137,6 +12048,16 @@ const applyQwikComponentBody = (ssr, jsx, component) => {
|
|
|
12137
12048
|
|
|
12138
12049
|
class MaybeAsyncSignal {
|
|
12139
12050
|
}
|
|
12051
|
+
const markPromiseHandled = (ssr, promise, host = null) => {
|
|
12052
|
+
promise.catch((reason) => {
|
|
12053
|
+
try {
|
|
12054
|
+
ssr.handleError(reason, host);
|
|
12055
|
+
}
|
|
12056
|
+
catch {
|
|
12057
|
+
// Original promise remains awaited later.
|
|
12058
|
+
}
|
|
12059
|
+
});
|
|
12060
|
+
};
|
|
12140
12061
|
function setParentOptions(mutable, styleScoped, parentComponentFrame) {
|
|
12141
12062
|
return () => {
|
|
12142
12063
|
mutable.currentStyleScoped = styleScoped;
|
|
@@ -12147,6 +12068,11 @@ function setParentOptions(mutable, styleScoped, parentComponentFrame) {
|
|
|
12147
12068
|
async function _walkJSX(ssr, value, options) {
|
|
12148
12069
|
const stack = [value];
|
|
12149
12070
|
const enqueue = (value) => stack.push(value);
|
|
12071
|
+
const enqueuePromise = (promise) => {
|
|
12072
|
+
markPromiseHandled(ssr, promise);
|
|
12073
|
+
stack.push(promise);
|
|
12074
|
+
stack.push(Promise);
|
|
12075
|
+
};
|
|
12150
12076
|
const drain = async () => {
|
|
12151
12077
|
while (stack.length) {
|
|
12152
12078
|
try {
|
|
@@ -12169,7 +12095,7 @@ async function _walkJSX(ssr, value, options) {
|
|
|
12169
12095
|
}
|
|
12170
12096
|
continue;
|
|
12171
12097
|
}
|
|
12172
|
-
processJSXNode(ssr, enqueue, value, options);
|
|
12098
|
+
processJSXNode(ssr, enqueue, enqueuePromise, value, options);
|
|
12173
12099
|
}
|
|
12174
12100
|
finally {
|
|
12175
12101
|
const pendingFlush = ssr.streamHandler.waitForPendingFlush();
|
|
@@ -12181,7 +12107,7 @@ async function _walkJSX(ssr, value, options) {
|
|
|
12181
12107
|
};
|
|
12182
12108
|
await drain();
|
|
12183
12109
|
}
|
|
12184
|
-
function processJSXNode(ssr, enqueue, value, options) {
|
|
12110
|
+
function processJSXNode(ssr, enqueue, enqueuePromise, value, options) {
|
|
12185
12111
|
// console.log('processJSXNode', value);
|
|
12186
12112
|
if (value == null) {
|
|
12187
12113
|
ssr.textNode('');
|
|
@@ -12202,7 +12128,6 @@ function processJSXNode(ssr, enqueue, value, options) {
|
|
|
12202
12128
|
}
|
|
12203
12129
|
}
|
|
12204
12130
|
else if (isSignal(value)) {
|
|
12205
|
-
maybeAddPollingAsyncSignalToEagerResume(ssr.serializationCtx, value);
|
|
12206
12131
|
ssr.openFragment(isDev ? { [DEBUG_TYPE]: "S" /* VirtualType.WrappedSignal */ } : EMPTY_OBJ);
|
|
12207
12132
|
const signalNode = ssr.getOrCreateLastNode();
|
|
12208
12133
|
const unwrappedSignal = value instanceof WrappedSignalImpl ? value.$unwrapIfSignal$() : value;
|
|
@@ -12213,8 +12138,7 @@ function processJSXNode(ssr, enqueue, value, options) {
|
|
|
12213
12138
|
else if (isPromise(value)) {
|
|
12214
12139
|
ssr.openFragment(isDev ? { [DEBUG_TYPE]: "A" /* VirtualType.Awaited */ } : EMPTY_OBJ);
|
|
12215
12140
|
enqueue(ssr.closeFragment);
|
|
12216
|
-
|
|
12217
|
-
enqueue(Promise);
|
|
12141
|
+
enqueuePromise(value);
|
|
12218
12142
|
enqueue(() => ssr.streamHandler.flush());
|
|
12219
12143
|
}
|
|
12220
12144
|
else if (isAsyncGenerator(value)) {
|
|
@@ -12285,11 +12209,9 @@ function processJSXNode(ssr, enqueue, value, options) {
|
|
|
12285
12209
|
const componentFrame = options.parentComponentFrame;
|
|
12286
12210
|
if (componentFrame) {
|
|
12287
12211
|
const compId = componentFrame.componentNode.id || '';
|
|
12288
|
-
const projectionAttrs = isDev
|
|
12289
|
-
|
|
12290
|
-
|
|
12291
|
-
projectionAttrs[QCursorBoundary] = cursorBoundary;
|
|
12292
|
-
}
|
|
12212
|
+
const projectionAttrs = isDev
|
|
12213
|
+
? { [DEBUG_TYPE]: "P" /* VirtualType.Projection */ }
|
|
12214
|
+
: {};
|
|
12293
12215
|
projectionAttrs[QSlotParent] = compId;
|
|
12294
12216
|
ssr.openProjection(projectionAttrs);
|
|
12295
12217
|
const host = componentFrame.componentNode;
|
|
@@ -12337,8 +12259,12 @@ function processJSXNode(ssr, enqueue, value, options) {
|
|
|
12337
12259
|
else {
|
|
12338
12260
|
value = generator;
|
|
12339
12261
|
}
|
|
12340
|
-
|
|
12341
|
-
|
|
12262
|
+
if (isPromise(value)) {
|
|
12263
|
+
enqueuePromise(value);
|
|
12264
|
+
}
|
|
12265
|
+
else {
|
|
12266
|
+
enqueue(value);
|
|
12267
|
+
}
|
|
12342
12268
|
}
|
|
12343
12269
|
else if (type === SSRRaw) {
|
|
12344
12270
|
ssr.htmlNode(directGetPropsProxyProp(jsx, 'data'));
|
|
@@ -12362,6 +12288,7 @@ function processJSXNode(ssr, enqueue, value, options) {
|
|
|
12362
12288
|
enqueue(setParentOptions(options, options.currentStyleScoped, options.parentComponentFrame));
|
|
12363
12289
|
enqueue(() => ssr.closeComponent());
|
|
12364
12290
|
if (isPromise(jsxOutput)) {
|
|
12291
|
+
markPromiseHandled(ssr, jsxOutput, host);
|
|
12365
12292
|
// Defer reading QScopedStyle until after the promise resolves
|
|
12366
12293
|
enqueue(async () => {
|
|
12367
12294
|
await ssr.streamHandler.flush();
|
|
@@ -12386,27 +12313,17 @@ function processJSXNode(ssr, enqueue, value, options) {
|
|
|
12386
12313
|
enqueue(ssr.closeFragment);
|
|
12387
12314
|
const component = ssr.getParentComponentFrame();
|
|
12388
12315
|
const jsxOutput = applyInlineComponent(ssr, component && component.componentNode, type, jsx);
|
|
12389
|
-
|
|
12390
|
-
|
|
12316
|
+
if (isPromise(jsxOutput)) {
|
|
12317
|
+
enqueuePromise(jsxOutput);
|
|
12318
|
+
}
|
|
12319
|
+
else {
|
|
12320
|
+
enqueue(jsxOutput);
|
|
12321
|
+
}
|
|
12391
12322
|
}
|
|
12392
12323
|
}
|
|
12393
12324
|
}
|
|
12394
12325
|
}
|
|
12395
12326
|
}
|
|
12396
|
-
function maybeAddPollingAsyncSignalToEagerResume(serializationCtx, signal) {
|
|
12397
|
-
// Unwrap if it's a WrappedSignalImpl
|
|
12398
|
-
const unwrappedSignal = signal instanceof WrappedSignalImpl ? signal.$unwrapIfSignal$() : signal;
|
|
12399
|
-
if (unwrappedSignal instanceof ComputedSignalImpl) {
|
|
12400
|
-
const expires = unwrappedSignal.$expires$;
|
|
12401
|
-
// Don't check for $effects$ here - effects are added later during tracking.
|
|
12402
|
-
// The AsyncSignal's polling mechanism will check for effects before scheduling.
|
|
12403
|
-
// Only eager-resume for polling signals, not stale-only ones.
|
|
12404
|
-
if (expires && !(unwrappedSignal.$flags$ & 256 /* AsyncSignalFlags.NO_POLL */)) {
|
|
12405
|
-
serializationCtx.$addRoot$(unwrappedSignal);
|
|
12406
|
-
serializationCtx.$eagerResume$.add(unwrappedSignal);
|
|
12407
|
-
}
|
|
12408
|
-
}
|
|
12409
|
-
}
|
|
12410
12327
|
function appendQwikInspectorAttribute(jsx, qwikInspectorAttrValue) {
|
|
12411
12328
|
if (qwikInspectorAttrValue && (!jsx.constProps || !(qwikInspectorAttr in jsx.constProps))) {
|
|
12412
12329
|
(jsx.constProps ||= {})[qwikInspectorAttr] = qwikInspectorAttrValue;
|
|
@@ -12579,7 +12496,8 @@ function setEvent(serializationCtx, key, rawValue, hasMovedCaptures) {
|
|
|
12579
12496
|
*
|
|
12580
12497
|
* For internal qrls (starting with `_`) we assume that they do the right thing.
|
|
12581
12498
|
*/
|
|
12582
|
-
if (!qrl.$symbol$.startsWith('_') &&
|
|
12499
|
+
if (!qrl.$symbol$.startsWith('_') &&
|
|
12500
|
+
(Array.isArray(qrl.$captures$) || (hasMovedCaptures && qrl.$hasMovedCaptures$))) {
|
|
12583
12501
|
qrl = createQRL(null, '_run', _run, null, [qrl]);
|
|
12584
12502
|
}
|
|
12585
12503
|
return qrlToChunks(serializationCtx, qrl);
|
|
@@ -13123,17 +13041,11 @@ function* inflateIterator(container, target, typeId, data) {
|
|
|
13123
13041
|
if (asyncSignal.$untrackedValue$ === NEEDS_COMPUTATION) {
|
|
13124
13042
|
asyncSignal.$flags$ |= 1 /* ComputedSignalFlags.INVALID */;
|
|
13125
13043
|
}
|
|
13126
|
-
|
|
13127
|
-
|
|
13128
|
-
asyncSignal.expires = Math.abs(rawExpires);
|
|
13129
|
-
if (rawExpires < 0) {
|
|
13130
|
-
asyncSignal.$flags$ |= 256 /* AsyncSignalFlags.NO_POLL */;
|
|
13131
|
-
}
|
|
13132
|
-
if (d[8] !== undefined && d[8] !== 1) {
|
|
13133
|
-
asyncSignal.$concurrency$ = (d[8] ?? 1);
|
|
13044
|
+
if (d[7] !== undefined && d[7] !== 1) {
|
|
13045
|
+
asyncSignal.$concurrency$ = (d[7] ?? 1);
|
|
13134
13046
|
asyncSignal.$jobs$ = [];
|
|
13135
13047
|
}
|
|
13136
|
-
asyncSignal.$timeoutMs$ = (d[
|
|
13048
|
+
asyncSignal.$timeoutMs$ = (d[8] ?? 0);
|
|
13137
13049
|
restoreEffectBackRefForEffects(asyncSignal.$effects$, asyncSignal);
|
|
13138
13050
|
restoreEffectBackRefForEffects(asyncSignal.$loadingEffects$, asyncSignal);
|
|
13139
13051
|
restoreEffectBackRefForEffects(asyncSignal.$errorEffects$, asyncSignal);
|
|
@@ -13915,7 +13827,7 @@ const isRecoverable = (err) => {
|
|
|
13915
13827
|
};
|
|
13916
13828
|
|
|
13917
13829
|
/** @internal */
|
|
13918
|
-
const canRevealRegistration = (registration, isPending = (item) => item.boundary.
|
|
13830
|
+
const canRevealRegistration = (registration, isPending = (item) => item.boundary.untrackedValue > 0) => {
|
|
13919
13831
|
if (registration === null) {
|
|
13920
13832
|
return true;
|
|
13921
13833
|
}
|
|
@@ -13992,15 +13904,9 @@ class OutOfOrderRevealCoordinator {
|
|
|
13992
13904
|
}
|
|
13993
13905
|
/** @internal */
|
|
13994
13906
|
const createOutOfOrderRevealCoordinator = (order, collapsed) => {
|
|
13995
|
-
|
|
13996
|
-
|
|
13997
|
-
|
|
13998
|
-
const container = tryGetInvokeContext()?.$container$;
|
|
13999
|
-
let id = 0;
|
|
14000
|
-
if (container) {
|
|
14001
|
-
id = (outOfOrderRevealIds.get(container) || 0) + 1;
|
|
14002
|
-
outOfOrderRevealIds.set(container, id);
|
|
14003
|
-
}
|
|
13907
|
+
const container = tryGetInvokeContext().$container$;
|
|
13908
|
+
const id = (outOfOrderRevealIds.get(container) || 0) + 1;
|
|
13909
|
+
outOfOrderRevealIds.set(container, id);
|
|
14004
13910
|
return new OutOfOrderRevealCoordinator(id, order, collapsed);
|
|
14005
13911
|
};
|
|
14006
13912
|
const getOutOfOrderRevealOrderCode = (order) => {
|
|
@@ -14024,16 +13930,7 @@ const isOutOfOrderStreaming = () => {
|
|
|
14024
13930
|
return container?.outOfOrderStreaming === true && !isOutOfOrderSegmentContainer(container);
|
|
14025
13931
|
};
|
|
14026
13932
|
/** @internal */
|
|
14027
|
-
const nextOutOfOrderSuspenseId = () =>
|
|
14028
|
-
if (!__EXPERIMENTAL__.suspense) {
|
|
14029
|
-
return 0;
|
|
14030
|
-
}
|
|
14031
|
-
const container = tryGetInvokeContext()?.$container$;
|
|
14032
|
-
if (container?.outOfOrderStreaming !== true) {
|
|
14033
|
-
return 0;
|
|
14034
|
-
}
|
|
14035
|
-
return container?.nextOutOfOrderId?.() ?? 0;
|
|
14036
|
-
};
|
|
13933
|
+
const nextOutOfOrderSuspenseId = () => tryGetInvokeContext().$container$.nextOutOfOrderId();
|
|
14037
13934
|
/** @internal */
|
|
14038
13935
|
const applySubscriptionPatches = (container, patches) => {
|
|
14039
13936
|
if (!__EXPERIMENTAL__.suspense || !patches) {
|
|
@@ -14972,7 +14869,6 @@ class DomContainer extends _SharedContainer {
|
|
|
14972
14869
|
case OnRenderProp:
|
|
14973
14870
|
case QCtxAttr:
|
|
14974
14871
|
case QBackRefs:
|
|
14975
|
-
case QCursorBoundary:
|
|
14976
14872
|
getObjectById = this.$getObjectById$;
|
|
14977
14873
|
break;
|
|
14978
14874
|
case ELEMENT_SEQ_IDX:
|
|
@@ -15398,6 +15294,7 @@ const setupHmr = (LazyRefClass, setGetLazyRef) => {
|
|
|
15398
15294
|
};
|
|
15399
15295
|
|
|
15400
15296
|
// keep these imports above the rest to prevent circular dep issues
|
|
15297
|
+
let reportedChunkFailures;
|
|
15401
15298
|
let getLazyRef = (chunk, symbol, symbolFn, ref, container) => {
|
|
15402
15299
|
return new LazyRef(chunk, symbol, symbolFn, ref, container);
|
|
15403
15300
|
};
|
|
@@ -15438,7 +15335,25 @@ class LazyRef {
|
|
|
15438
15335
|
this.$ref$ = ref;
|
|
15439
15336
|
if (isPromise(ref)) {
|
|
15440
15337
|
ref.then((r) => (this.$ref$ = r), (err) => {
|
|
15441
|
-
|
|
15338
|
+
const errorMessage = `qrl ${this.$symbol$} failed to load`;
|
|
15339
|
+
if (qTest ? isServerPlatform() : isServer) {
|
|
15340
|
+
console.error(errorMessage, err);
|
|
15341
|
+
}
|
|
15342
|
+
else if (qTest ? !isServerPlatform() : isBrowser$1) {
|
|
15343
|
+
const failureKey = this.$chunk$ === null ? `symbol:${this.$symbol$}` : `chunk:${this.$chunk$}`;
|
|
15344
|
+
const container = this.$container$;
|
|
15345
|
+
let containerFailures = container && reportedChunkFailures?.get(container);
|
|
15346
|
+
if (!containerFailures?.has(failureKey)) {
|
|
15347
|
+
if (container) {
|
|
15348
|
+
if (!containerFailures) {
|
|
15349
|
+
containerFailures = new Set();
|
|
15350
|
+
(reportedChunkFailures ||= new WeakMap()).set(container, containerFailures);
|
|
15351
|
+
}
|
|
15352
|
+
containerFailures.add(failureKey);
|
|
15353
|
+
}
|
|
15354
|
+
console.error(errorMessage, err);
|
|
15355
|
+
}
|
|
15356
|
+
}
|
|
15442
15357
|
// We shouldn't cache rejections, we can try again later
|
|
15443
15358
|
this.$ref$ = null;
|
|
15444
15359
|
});
|
|
@@ -15531,6 +15446,10 @@ const qrlWithCaptures = function (captures) {
|
|
|
15531
15446
|
const newQrl = new QRLClass(qrl.$lazy$, captures, qrl.$captures$ ? qrl.$container$ : undefined);
|
|
15532
15447
|
return makeQrlFn(newQrl);
|
|
15533
15448
|
};
|
|
15449
|
+
const qrlWithMovedCaptures = function () {
|
|
15450
|
+
this[QRL_STATE].$lazy$.$hasMovedCaptures$ = true;
|
|
15451
|
+
return this;
|
|
15452
|
+
};
|
|
15534
15453
|
const qrlSetRef = function (ref) {
|
|
15535
15454
|
const qrl = getInstance(this);
|
|
15536
15455
|
qrl.$lazy$.$setRef$(ref);
|
|
@@ -15586,6 +15505,11 @@ const QRL_FUNCTION_PROTO = Object.create(Function.prototype, {
|
|
|
15586
15505
|
this[QRL_STATE].$captures$ = value;
|
|
15587
15506
|
},
|
|
15588
15507
|
},
|
|
15508
|
+
$hasMovedCaptures$: {
|
|
15509
|
+
get() {
|
|
15510
|
+
return this[QRL_STATE].$lazy$.$hasMovedCaptures$;
|
|
15511
|
+
},
|
|
15512
|
+
},
|
|
15589
15513
|
$container$: {
|
|
15590
15514
|
get() {
|
|
15591
15515
|
return this[QRL_STATE].$container$;
|
|
@@ -15634,6 +15558,9 @@ const QRL_FUNCTION_PROTO = Object.create(Function.prototype, {
|
|
|
15634
15558
|
w: {
|
|
15635
15559
|
value: qrlWithCaptures,
|
|
15636
15560
|
},
|
|
15561
|
+
m: {
|
|
15562
|
+
value: qrlWithMovedCaptures,
|
|
15563
|
+
},
|
|
15637
15564
|
s: {
|
|
15638
15565
|
value: qrlSetRef,
|
|
15639
15566
|
},
|
|
@@ -16971,10 +16898,10 @@ const eachCmpTask = async ({ track }) => {
|
|
|
16971
16898
|
const context = tryGetInvokeContext();
|
|
16972
16899
|
const host = context.$hostElement$;
|
|
16973
16900
|
const container = context.$container$;
|
|
16974
|
-
markVNodeDirty(container, host, 256 /* ChoreBits.RECONCILE */);
|
|
16901
|
+
const renderPromise = markVNodeDirty(container, host, 256 /* ChoreBits.RECONCILE */);
|
|
16975
16902
|
const isSsr = qTest ? isServerPlatform() : isServer;
|
|
16976
16903
|
if (isSsr) {
|
|
16977
|
-
await
|
|
16904
|
+
await renderPromise;
|
|
16978
16905
|
}
|
|
16979
16906
|
};
|
|
16980
16907
|
/** @internal */
|
|
@@ -17133,19 +17060,19 @@ const _hf0 = (p0, p1, p2, p3) => ({
|
|
|
17133
17060
|
display: p1.value === 'fallback' &&
|
|
17134
17061
|
p0.fallback != null &&
|
|
17135
17062
|
p0.fallback !== false &&
|
|
17136
|
-
(p2
|
|
17063
|
+
(p2.value || !p3.reveal.collapsed)
|
|
17137
17064
|
? 'contents'
|
|
17138
17065
|
: 'none',
|
|
17139
17066
|
});
|
|
17140
|
-
const _hf0_str = '{display:p1.value==="fallback"&&p0.fallback!=null&&p0.fallback!==false&&(p2
|
|
17141
|
-
const _hf1 = (p0, p1
|
|
17142
|
-
display:
|
|
17067
|
+
const _hf0_str = '{display:p1.value==="fallback"&&p0.fallback!=null&&p0.fallback!==false&&(p2.value||!p3.reveal.collapsed)?"contents":"none"}';
|
|
17068
|
+
const _hf1 = (p0, p1) => ({
|
|
17069
|
+
display: p0.value === 'content' && p1.value ? 'contents' : 'none',
|
|
17143
17070
|
});
|
|
17144
|
-
const _hf1_str = '{display:
|
|
17071
|
+
const _hf1_str = '{display:p0.value==="content"&&p1.value?"contents":"none"}';
|
|
17145
17072
|
/** @internal */
|
|
17146
17073
|
const suspenseTask = ({ track, cleanup }) => {
|
|
17147
17074
|
const cursorBoundary = _captures[0], props = _captures[1], state = _captures[2], revealRegistration = _captures[3];
|
|
17148
|
-
const pendingCount = track(cursorBoundary
|
|
17075
|
+
const pendingCount = track(cursorBoundary);
|
|
17149
17076
|
const isBrowserEnv = qTest ? !isServerPlatform() : isBrowser$1;
|
|
17150
17077
|
if (revealRegistration !== null && isBrowserEnv) {
|
|
17151
17078
|
revealRegistration.reveal.version.value++;
|
|
@@ -17155,7 +17082,7 @@ const suspenseTask = ({ track, cleanup }) => {
|
|
|
17155
17082
|
return;
|
|
17156
17083
|
}
|
|
17157
17084
|
const delayTimer = setTimeout(() => {
|
|
17158
|
-
if (cursorBoundary.
|
|
17085
|
+
if (cursorBoundary.value > 0) {
|
|
17159
17086
|
state.value = 'fallback';
|
|
17160
17087
|
}
|
|
17161
17088
|
}, props.delay ?? 0);
|
|
@@ -17184,19 +17111,17 @@ const suspenseCmp = (props) => {
|
|
|
17184
17111
|
const outOfOrderRevealBoundary = isServerOutOfOrder
|
|
17185
17112
|
? (revealRegistration?.reveal.ooos?.register(revealRegistration) ?? null)
|
|
17186
17113
|
: null;
|
|
17187
|
-
const showOutOfOrderFallback = isServerOutOfOrder &&
|
|
17114
|
+
const showOutOfOrderFallback = isServerOutOfOrder &&
|
|
17115
|
+
untrack(() => props.fallback != null && props.fallback !== false) &&
|
|
17116
|
+
(outOfOrderRevealBoundary === null || outOfOrderRevealBoundary.showFallback);
|
|
17188
17117
|
const outOfOrderBoundaryState = showOutOfOrderFallback && isPositiveDelay(props.delay)
|
|
17189
|
-
? { contentResolved: false, delayTimer: null }
|
|
17118
|
+
? { contentResolved: false, delay: props.delay, delayTimer: null }
|
|
17190
17119
|
: null;
|
|
17191
|
-
const
|
|
17192
|
-
? /*#__PURE__*/ _fnSignal(_hf0, [props, state, canReveal, revealRegistration], _hf0_str)
|
|
17193
|
-
: null;
|
|
17194
|
-
const contentStyle = /*#__PURE__*/ _fnSignal(_hf1, [props, state, canReveal], _hf1_str);
|
|
17120
|
+
const contentStyle = /*#__PURE__*/ _fnSignal(_hf1, [state, canReveal], _hf1_str);
|
|
17195
17121
|
const fallbackHost = (isServerOutOfOrder
|
|
17196
17122
|
? /*#__PURE__*/ _jsxSorted(SSRFallback, {
|
|
17197
17123
|
boundary: outOfOrderBoundaryState,
|
|
17198
|
-
|
|
17199
|
-
fallbackStyle: outOfOrderFallbackStyle,
|
|
17124
|
+
fallbackStyle: _fnSignal(_hf0, [props, state, canReveal, revealRegistration], _hf0_str),
|
|
17200
17125
|
showFallback: showOutOfOrderFallback,
|
|
17201
17126
|
state,
|
|
17202
17127
|
}, null, _wrapProp(props, 'fallback'), 1, null)
|
|
@@ -17232,15 +17157,16 @@ const Suspense = /*#__PURE__*/ componentQrl(
|
|
|
17232
17157
|
const SSRFallback = __EXPERIMENTAL__.suspense
|
|
17233
17158
|
? /*#__PURE__*/ createInternalServerComponent((ssr, jsx, _options, enqueue) => {
|
|
17234
17159
|
const boundaryState = jsx.varProps.boundary;
|
|
17235
|
-
const delay = jsx.varProps.delay;
|
|
17236
17160
|
const fallbackStyle = jsx.varProps.fallbackStyle;
|
|
17237
17161
|
const showFallback = jsx.varProps.showFallback === true;
|
|
17238
17162
|
const state = jsx.varProps.state;
|
|
17239
|
-
if (showFallback
|
|
17240
|
-
|
|
17241
|
-
|
|
17242
|
-
|
|
17243
|
-
|
|
17163
|
+
if (showFallback) {
|
|
17164
|
+
if (boundaryState) {
|
|
17165
|
+
enqueue(() => scheduleOutOfOrderFallbackDelay(ssr, boundaryState, state));
|
|
17166
|
+
}
|
|
17167
|
+
else {
|
|
17168
|
+
state.value = 'fallback';
|
|
17169
|
+
}
|
|
17244
17170
|
}
|
|
17245
17171
|
enqueue(
|
|
17246
17172
|
/*#__PURE__*/ _jsxSorted('div', {
|
|
@@ -17250,13 +17176,13 @@ const SSRFallback = __EXPERIMENTAL__.suspense
|
|
|
17250
17176
|
: null;
|
|
17251
17177
|
const SSRDeferredSlot = __EXPERIMENTAL__.suspense
|
|
17252
17178
|
? /*#__PURE__*/ createInternalServerComponent(async (ssr, jsx, options) => {
|
|
17253
|
-
const boundaryId = jsx.varProps.boundaryId
|
|
17179
|
+
const boundaryId = jsx.varProps.boundaryId;
|
|
17254
17180
|
const contentSegment = `${boundaryId}`;
|
|
17255
17181
|
const boundaryState = jsx.varProps.boundary;
|
|
17256
17182
|
const contentStyle = jsx.varProps.contentStyle;
|
|
17257
17183
|
const revealBoundary = jsx.varProps.reveal;
|
|
17258
17184
|
const content = ssr.segment(contentSegment, createClaimedDeferredSlot(ssr, jsx, options), options);
|
|
17259
|
-
|
|
17185
|
+
ssr.write(`<template ${QSuspenseResolved}="${boundaryId}"></template>`);
|
|
17260
17186
|
ssr.emitOutOfOrderExecutorIfNeeded();
|
|
17261
17187
|
ssr.queueOutOfOrderSegment(content.then((rendered) => emitRenderedOutOfOrderSegment(ssr, boundaryId, contentSegment, rendered, contentStyle, revealBoundary, boundaryState)));
|
|
17262
17188
|
})
|
|
@@ -17275,29 +17201,27 @@ function createClaimedDeferredSlot(ssr, jsx, options) {
|
|
|
17275
17201
|
return /*#__PURE__*/ _jsxSorted(Slot, jsx.varProps, jsx.constProps, slotChildren, jsx.flags, jsx.key);
|
|
17276
17202
|
}
|
|
17277
17203
|
async function emitRenderedOutOfOrderSegment(ssr, boundaryId, segmentId, rendered, contentStyle, revealBoundary, boundaryState) {
|
|
17278
|
-
|
|
17204
|
+
if (boundaryState) {
|
|
17205
|
+
boundaryState.contentResolved = true;
|
|
17206
|
+
if (boundaryState.delayTimer) {
|
|
17207
|
+
clearTimeout(boundaryState.delayTimer);
|
|
17208
|
+
boundaryState.delayTimer = null;
|
|
17209
|
+
}
|
|
17210
|
+
}
|
|
17279
17211
|
revealBoundary?.resolve();
|
|
17280
17212
|
await ssr.$runQueuedRender$(async () => {
|
|
17281
17213
|
ssr.addRoot(contentStyle);
|
|
17282
17214
|
const result = await rendered.container.$finalizeOutOfOrderSegment$(segmentId, rendered);
|
|
17283
|
-
|
|
17215
|
+
ssr.write(`<template ${QSuspenseResolved}="${boundaryId}"${revealBoundary?.attrs ?? ''}>`);
|
|
17216
|
+
ssr.write(result.html);
|
|
17217
|
+
ssr.write('</template>');
|
|
17284
17218
|
ssr.emitOutOfOrderSegmentScripts(result.scripts);
|
|
17285
17219
|
ssr.emitInlineScript(`qO(${boundaryId})`);
|
|
17286
17220
|
// qO() is the browser-visible handoff for this segment, so flush it immediately.
|
|
17287
17221
|
await ssr.streamHandler.flush();
|
|
17288
17222
|
});
|
|
17289
17223
|
}
|
|
17290
|
-
function
|
|
17291
|
-
if (!boundaryState) {
|
|
17292
|
-
return;
|
|
17293
|
-
}
|
|
17294
|
-
boundaryState.contentResolved = true;
|
|
17295
|
-
if (boundaryState.delayTimer) {
|
|
17296
|
-
clearTimeout(boundaryState.delayTimer);
|
|
17297
|
-
boundaryState.delayTimer = null;
|
|
17298
|
-
}
|
|
17299
|
-
}
|
|
17300
|
-
function scheduleOutOfOrderFallbackDelay(ssr, boundaryState, state, delay) {
|
|
17224
|
+
function scheduleOutOfOrderFallbackDelay(ssr, boundaryState, state) {
|
|
17301
17225
|
boundaryState.delayTimer = setTimeout(() => {
|
|
17302
17226
|
boundaryState.delayTimer = null;
|
|
17303
17227
|
void ssr.$runQueuedRender$(async () => {
|
|
@@ -17308,24 +17232,11 @@ function scheduleOutOfOrderFallbackDelay(ssr, boundaryState, state, delay) {
|
|
|
17308
17232
|
ssr.emitBackpatchDataAndExecutorIfNeeded();
|
|
17309
17233
|
await ssr.streamHandler.flush();
|
|
17310
17234
|
});
|
|
17311
|
-
}, delay);
|
|
17235
|
+
}, boundaryState.delay);
|
|
17312
17236
|
}
|
|
17313
17237
|
function isPositiveDelay(delay) {
|
|
17314
17238
|
return typeof delay === 'number' && Number.isFinite(delay) && delay > 0;
|
|
17315
17239
|
}
|
|
17316
|
-
function shouldRenderFallback(fallback, revealBoundary) {
|
|
17317
|
-
return (fallback != null &&
|
|
17318
|
-
fallback !== false &&
|
|
17319
|
-
(revealBoundary === null || revealBoundary.showFallback));
|
|
17320
|
-
}
|
|
17321
|
-
function writeOutOfOrderPlaceholder(ssr, boundaryId) {
|
|
17322
|
-
ssr.write(`<template ${QSuspenseResolved}="${boundaryId}"></template>`);
|
|
17323
|
-
}
|
|
17324
|
-
function writeOutOfOrderResolvedTemplate(ssr, boundaryId, html, revealBoundary) {
|
|
17325
|
-
ssr.write(`<template ${QSuspenseResolved}="${boundaryId}"${revealBoundary?.attrs ?? ''}>`);
|
|
17326
|
-
ssr.write(html);
|
|
17327
|
-
ssr.write('</template>');
|
|
17328
|
-
}
|
|
17329
17240
|
|
|
17330
17241
|
// keep this import from core/build so the cjs build works
|
|
17331
17242
|
/**
|