@qwik.dev/core 2.0.0-beta.31 → 2.0.0-beta.34
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/index.mjs +2 -2
- package/dist/backpatch/package.json +1 -1
- package/dist/backpatch-executor.debug.js +12 -6
- package/dist/backpatch-executor.js +1 -1
- package/dist/build/package.json +1 -1
- package/dist/cli.mjs +2 -2
- package/dist/core-internal.d.ts +182 -38
- package/dist/core.min.mjs +2 -2
- package/dist/core.mjs +790 -438
- package/dist/core.mjs.map +1 -1
- package/dist/core.prod.mjs +3405 -3161
- package/dist/loader/index.mjs +2 -2
- package/dist/loader/package.json +1 -1
- package/dist/optimizer.mjs +727 -722
- package/dist/preloader.mjs +64 -89
- package/dist/qwikloader.debug.js +237 -90
- package/dist/qwikloader.js +1 -1
- package/dist/server.d.ts +0 -54
- package/dist/server.mjs +119 -491
- package/dist/server.prod.mjs +625 -1033
- package/dist/starters/adapters/bun/src/entry.bun.ts +2 -8
- package/dist/starters/adapters/cloud-run/src/entry.cloud-run.tsx +2 -4
- package/dist/starters/adapters/deno/src/entry.deno.ts +2 -8
- package/dist/starters/adapters/express/src/entry.express.tsx +1 -4
- package/dist/starters/adapters/fastify/src/plugins/fastify-qwik.ts +1 -2
- package/dist/starters/adapters/node-server/src/entry.node-server.tsx +2 -4
- package/dist/testing/index.d.ts +7 -4
- package/dist/testing/index.mjs +1452 -3772
- package/dist/testing/package.json +1 -1
- package/package.json +3 -3
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.34-dev+8b055bb
|
|
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
|
|
@@ -189,9 +189,11 @@ const isPrimitiveOrNullUndefined = (v) => {
|
|
|
189
189
|
return (typeof v !== 'object' && typeof v !== 'function') || v === null || v === undefined;
|
|
190
190
|
};
|
|
191
191
|
|
|
192
|
+
const baseUrl = 'https://qwikdev-build-v2.qwik-8nx.pages.dev/docs/errors/#q';
|
|
192
193
|
const codeToText = (code, ...parts) => {
|
|
193
194
|
if (qDev) {
|
|
194
195
|
// Keep one error, one line to make it easier to search for the error message.
|
|
196
|
+
// Keep in sync with packages/docs/src/routes/docs/errors/index.mdx
|
|
195
197
|
const MAP = [
|
|
196
198
|
'Error while serializing class or style attributes', // 0
|
|
197
199
|
'Scheduler not found', // 1
|
|
@@ -228,6 +230,7 @@ const codeToText = (code, ...parts) => {
|
|
|
228
230
|
'Attribute value is unsafe for SSR {{0}}', // 32
|
|
229
231
|
'SerializerSymbol function returned rejected promise', // 33
|
|
230
232
|
'Serialization Error: Cannot serialize function: {{0}}', // 34
|
|
233
|
+
'Cannot read .value of a clientOnly async signal during SSR. Use .loading to check state, or provide an initial value.', // 35
|
|
231
234
|
];
|
|
232
235
|
let text = MAP[code] ?? '';
|
|
233
236
|
if (parts.length) {
|
|
@@ -242,9 +245,7 @@ const codeToText = (code, ...parts) => {
|
|
|
242
245
|
return `Code(Q${code}): ${text}`;
|
|
243
246
|
}
|
|
244
247
|
else {
|
|
245
|
-
|
|
246
|
-
// TODO change the URL after merging into main
|
|
247
|
-
return `Code(Q${code}) https://github.com/QwikDev/qwik/blob/build/v2/packages/qwik/src/core/shared/error/error.ts#${parts.join()}L${9 + code}`;
|
|
248
|
+
return `Code(Q${code}) ${baseUrl}${code}`;
|
|
248
249
|
}
|
|
249
250
|
};
|
|
250
251
|
const qError = (code, errorMessageArgs = []) => {
|
|
@@ -571,49 +572,52 @@ const addComponentStylePrefix = (styleId) => {
|
|
|
571
572
|
* - A `-` (not at the beginning) makes next character uppercase: `dbl-click` => `dblClick`
|
|
572
573
|
*/
|
|
573
574
|
const EVENT_SUFFIX = '$';
|
|
575
|
+
const DOM_CONTENT_LOADED_EVENT = 'DOMContentLoaded';
|
|
574
576
|
const isHtmlAttributeAnEventName = (name) => {
|
|
575
577
|
return (name.charCodeAt(0) === 113 /* q */ &&
|
|
576
578
|
name.charCodeAt(1) === 45 /* - */ &&
|
|
577
|
-
name.charCodeAt(3) === 58 /* : */
|
|
579
|
+
(name.charCodeAt(3) === 58 /* : */ ||
|
|
580
|
+
(name.charCodeAt(3) === 112 /* p */ && name.charCodeAt(4) === 58)) /* : */);
|
|
578
581
|
};
|
|
579
|
-
function jsxEventToHtmlAttribute(jsxEvent) {
|
|
582
|
+
function jsxEventToHtmlAttribute(jsxEvent, isPassive = false) {
|
|
580
583
|
if (jsxEvent.endsWith(EVENT_SUFFIX)) {
|
|
581
|
-
const [prefix, idx] = getEventScopeDataFromJsxEvent(jsxEvent);
|
|
584
|
+
const [prefix, idx] = getEventScopeDataFromJsxEvent(jsxEvent, isPassive);
|
|
582
585
|
if (idx !== -1) {
|
|
583
|
-
|
|
584
|
-
return name === 'DOMContentLoaded'
|
|
585
|
-
? // The only DOM event that is not all lowercase
|
|
586
|
-
prefix + '-d-o-m-content-loaded'
|
|
587
|
-
: createEventName(name.charAt(0) === '-'
|
|
588
|
-
? // marker for case sensitive event name
|
|
589
|
-
name.slice(1)
|
|
590
|
-
: name.toLowerCase(), prefix);
|
|
586
|
+
return prefix + normalizeJsxEventName(jsxEvent.slice(idx, -1));
|
|
591
587
|
}
|
|
592
588
|
}
|
|
593
589
|
return null; // Return null if not matching expected format
|
|
594
590
|
}
|
|
595
|
-
function createEventName(event, prefix) {
|
|
591
|
+
function createEventName(event, prefix = '') {
|
|
596
592
|
const eventName = fromCamelToKebabCase(event);
|
|
597
593
|
return prefix + eventName;
|
|
598
594
|
}
|
|
599
|
-
function getEventScopeDataFromJsxEvent(eventName) {
|
|
595
|
+
function getEventScopeDataFromJsxEvent(eventName, isPassive = false) {
|
|
600
596
|
let prefix;
|
|
601
597
|
let idx = -1;
|
|
602
598
|
// set prefix and idx based on the scope
|
|
603
599
|
if (eventName.startsWith("on" /* EventNameJSXScope.on */)) {
|
|
604
|
-
prefix = "q-e:" /* EventNameHtmlScope.on */;
|
|
600
|
+
prefix = isPassive ? "q-ep:" /* EventNameHtmlScope.onPassive */ : "q-e:" /* EventNameHtmlScope.on */;
|
|
605
601
|
idx = 2;
|
|
606
602
|
}
|
|
607
603
|
else if (eventName.startsWith("window:on" /* EventNameJSXScope.window */)) {
|
|
608
|
-
prefix = "q-w:" /* EventNameHtmlScope.window */;
|
|
604
|
+
prefix = isPassive ? "q-wp:" /* EventNameHtmlScope.windowPassive */ : "q-w:" /* EventNameHtmlScope.window */;
|
|
609
605
|
idx = 9;
|
|
610
606
|
}
|
|
611
607
|
else if (eventName.startsWith("document:on" /* EventNameJSXScope.document */)) {
|
|
612
|
-
prefix = "q-d:" /* EventNameHtmlScope.document */;
|
|
608
|
+
prefix = isPassive ? "q-dp:" /* EventNameHtmlScope.documentPassive */ : "q-d:" /* EventNameHtmlScope.document */;
|
|
613
609
|
idx = 11;
|
|
614
610
|
}
|
|
615
611
|
return [prefix, idx];
|
|
616
612
|
}
|
|
613
|
+
const normalizeJsxEventName = (name) => {
|
|
614
|
+
return name === DOM_CONTENT_LOADED_EVENT
|
|
615
|
+
? '-d-o-m-content-loaded'
|
|
616
|
+
: createEventName(name.charAt(0) === '-'
|
|
617
|
+
? // marker for case sensitive event name
|
|
618
|
+
name.slice(1)
|
|
619
|
+
: name.toLowerCase());
|
|
620
|
+
};
|
|
617
621
|
function isPreventDefault(key) {
|
|
618
622
|
return key.startsWith('preventdefault:');
|
|
619
623
|
}
|
|
@@ -621,11 +625,11 @@ function isPreventDefault(key) {
|
|
|
621
625
|
const fromCamelToKebabCase = (text) => {
|
|
622
626
|
return text.replace(/([A-Z-])/g, (a) => '-' + a.toLowerCase());
|
|
623
627
|
};
|
|
624
|
-
/** E.g. `"q-e:click"` => `['e', 'click']` */
|
|
625
|
-
const getEventDataFromHtmlAttribute = (htmlKey) =>
|
|
626
|
-
htmlKey.
|
|
627
|
-
htmlKey.
|
|
628
|
-
|
|
628
|
+
/** E.g. `"q-e:click"` => `['e', 'click']`, `"q-ep:click"` => `['ep', 'click']` */
|
|
629
|
+
const getEventDataFromHtmlAttribute = (htmlKey) => {
|
|
630
|
+
const separatorIndex = htmlKey.indexOf(':');
|
|
631
|
+
return [htmlKey.slice(2, separatorIndex), htmlKey.slice(separatorIndex + 1)];
|
|
632
|
+
};
|
|
629
633
|
/** E.g. `"e:click"`, `"w:load"` */
|
|
630
634
|
const getScopedEventName = (scope, eventName) => scope + ':' + eventName;
|
|
631
635
|
|
|
@@ -916,6 +920,9 @@ const createMacroTask = (fn) => {
|
|
|
916
920
|
const isBrowser = import.meta.env.TEST ? !isServerPlatform() : !isServer;
|
|
917
921
|
// Browser-specific setup
|
|
918
922
|
const doc = isBrowser ? document : undefined;
|
|
923
|
+
const config = {
|
|
924
|
+
$maxIdlePreloads$: 25,
|
|
925
|
+
};
|
|
919
926
|
// Determine which rel attribute to use based on browser support
|
|
920
927
|
const rel = isBrowser && doc.createElement('link').relList?.supports?.('modulepreload')
|
|
921
928
|
? 'modulePreload'
|
|
@@ -983,10 +990,8 @@ function trigger() {
|
|
|
983
990
|
const bundle = queue[0];
|
|
984
991
|
const inverseProbability = bundle.$inverseProbability$;
|
|
985
992
|
const probability = 1 - inverseProbability;
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
// When we're 99% sure, everything needs to be queued
|
|
989
|
-
if (probability >= 0.99 || preloadCount < allowedPreloads) {
|
|
993
|
+
// We want to preload all the transitive static (1) and dynamic (0.99) dependencies, throttled by the user defined maxIdlePreloads.
|
|
994
|
+
if (probability >= 0.99 || preloadCount < config.$maxIdlePreloads$) {
|
|
990
995
|
queue.shift();
|
|
991
996
|
preloadOne(bundle);
|
|
992
997
|
if (performance.now() >= deadline) {
|
|
@@ -1003,13 +1008,12 @@ function trigger() {
|
|
|
1003
1008
|
nextTriggerMacroTask();
|
|
1004
1009
|
}
|
|
1005
1010
|
}
|
|
1006
|
-
const enqueueAdjustment = (bundle, inverseProbability,
|
|
1011
|
+
const enqueueAdjustment = (bundle, inverseProbability, seen) => {
|
|
1007
1012
|
// Keep existing work on the stack hot and append new roots behind it.
|
|
1008
1013
|
adjustmentStack.unshift({
|
|
1009
1014
|
$bundle$: bundle,
|
|
1010
1015
|
$inverseProbability$: inverseProbability,
|
|
1011
1016
|
$seen$: seen,
|
|
1012
|
-
$context$: context,
|
|
1013
1017
|
});
|
|
1014
1018
|
};
|
|
1015
1019
|
const processAdjustmentFrame = () => {
|
|
@@ -1029,9 +1033,8 @@ const processAdjustmentFrame = () => {
|
|
|
1029
1033
|
}
|
|
1030
1034
|
const probability = 1 - bundle.$inverseProbability$;
|
|
1031
1035
|
let newInverseProbability;
|
|
1032
|
-
if (probability === 1 ||
|
|
1033
|
-
|
|
1034
|
-
// we're loaded at max probability, so elevate dynamic imports to 99% sure
|
|
1036
|
+
if (probability === 1 || probability >= 0.99) {
|
|
1037
|
+
// bundle is requested at max probability, so elevate all its transitive static and dynamic deps to 99% sure
|
|
1035
1038
|
newInverseProbability = Math.min(0.01, 1 - dep.$importProbability$);
|
|
1036
1039
|
}
|
|
1037
1040
|
else {
|
|
@@ -1047,7 +1050,6 @@ const processAdjustmentFrame = () => {
|
|
|
1047
1050
|
$bundle$: depBundle,
|
|
1048
1051
|
$inverseProbability$: newInverseProbability,
|
|
1049
1052
|
$seen$: frame.$seen$,
|
|
1050
|
-
$context$: frame.$context$,
|
|
1051
1053
|
});
|
|
1052
1054
|
return true;
|
|
1053
1055
|
}
|
|
@@ -1124,55 +1126,26 @@ const preloadOne = (bundle) => {
|
|
|
1124
1126
|
};
|
|
1125
1127
|
doc.head.appendChild(link);
|
|
1126
1128
|
};
|
|
1127
|
-
|
|
1128
|
-
* Adjust the probability of a bundle based on the probability of its dependent bundles, and queue
|
|
1129
|
-
* it if it's likely enough to be preloaded.
|
|
1130
|
-
*
|
|
1131
|
-
* Note that if the probability is 100%, we treat the dynamic imports as 99% sure, and both will be
|
|
1132
|
-
* preloaded without limit.
|
|
1133
|
-
*
|
|
1134
|
-
* We also limit "organic" probability to 98% so they don't get unlimited preloads.
|
|
1135
|
-
*/
|
|
1136
|
-
const adjustProbabilities = (bundle, newInverseProbability, seen) => {
|
|
1137
|
-
enqueueAdjustment(bundle, newInverseProbability, { $depsCount$: 0 }, seen);
|
|
1138
|
-
if (shouldYieldInBrowser) {
|
|
1139
|
-
nextAdjustmentMacroTask();
|
|
1140
|
-
}
|
|
1141
|
-
else {
|
|
1142
|
-
processPendingAdjustments();
|
|
1143
|
-
}
|
|
1144
|
-
};
|
|
1145
|
-
const handleBundle = (name, inverseProbability, context) => {
|
|
1129
|
+
const handleBundle = (name, inverseProbability) => {
|
|
1146
1130
|
const bundle = getBundle(name);
|
|
1147
|
-
if (bundle
|
|
1148
|
-
|
|
1149
|
-
enqueueAdjustment(bundle, inverseProbability, context);
|
|
1150
|
-
}
|
|
1151
|
-
else {
|
|
1152
|
-
adjustProbabilities(bundle, inverseProbability);
|
|
1153
|
-
}
|
|
1131
|
+
if (bundle) {
|
|
1132
|
+
enqueueAdjustment(bundle, inverseProbability);
|
|
1154
1133
|
}
|
|
1155
1134
|
};
|
|
1156
|
-
const preload = (
|
|
1157
|
-
if (!
|
|
1135
|
+
const preload = (item, probability) => {
|
|
1136
|
+
if (!item?.length) {
|
|
1158
1137
|
return;
|
|
1159
1138
|
}
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
if (Array.isArray(name)) {
|
|
1139
|
+
const inverseProbability = 1 - probability ;
|
|
1140
|
+
if (Array.isArray(item)) {
|
|
1163
1141
|
// We must process in reverse order to ensure first bundles are handled first
|
|
1164
|
-
for (let i =
|
|
1165
|
-
const
|
|
1166
|
-
|
|
1167
|
-
inverseProbability = 1 - item / 10;
|
|
1168
|
-
}
|
|
1169
|
-
else {
|
|
1170
|
-
handleBundle(item, inverseProbability, context);
|
|
1171
|
-
}
|
|
1142
|
+
for (let i = item.length - 1; i >= 0; i--) {
|
|
1143
|
+
const bundle = item[i];
|
|
1144
|
+
handleBundle(bundle, inverseProbability);
|
|
1172
1145
|
}
|
|
1173
1146
|
}
|
|
1174
1147
|
else {
|
|
1175
|
-
handleBundle(
|
|
1148
|
+
handleBundle(item, inverseProbability);
|
|
1176
1149
|
}
|
|
1177
1150
|
if (shouldYieldInBrowser) {
|
|
1178
1151
|
nextAdjustmentMacroTask();
|
|
@@ -1215,7 +1188,7 @@ const COMMA = ',';
|
|
|
1215
1188
|
*
|
|
1216
1189
|
* @public
|
|
1217
1190
|
*/
|
|
1218
|
-
const version = "2.0.0-beta.
|
|
1191
|
+
const version = "2.0.0-beta.34-dev+8b055bb";
|
|
1219
1192
|
|
|
1220
1193
|
const isNode = (value) => {
|
|
1221
1194
|
return value && typeof value.nodeType === 'number';
|
|
@@ -2033,19 +2006,16 @@ console.log('ASYNC COMPUTED SIGNAL', ...args.map(qwikDebugToString));
|
|
|
2033
2006
|
/** Retains job metadata and also serves as the argument for the compute function */
|
|
2034
2007
|
class AsyncJob {
|
|
2035
2008
|
$signal$;
|
|
2036
|
-
info;
|
|
2037
|
-
$infoVersion$;
|
|
2038
2009
|
/** First holds the compute promise and then the cleanup promise */
|
|
2039
2010
|
$promise$ = null;
|
|
2040
2011
|
$cleanupRequested$ = false;
|
|
2041
2012
|
$canWrite$ = true;
|
|
2042
|
-
$track$;
|
|
2043
|
-
$cleanups$;
|
|
2044
|
-
$abortController$;
|
|
2045
2013
|
constructor($signal$, info, $infoVersion$) {
|
|
2046
2014
|
this.$signal$ = $signal$;
|
|
2047
|
-
|
|
2048
|
-
|
|
2015
|
+
if (info !== undefined) {
|
|
2016
|
+
this.info = info;
|
|
2017
|
+
this.$infoVersion$ = $infoVersion$;
|
|
2018
|
+
}
|
|
2049
2019
|
}
|
|
2050
2020
|
get track() {
|
|
2051
2021
|
return (this.$track$ ||= trackFn(this.$signal$, this.$signal$.$container$));
|
|
@@ -2056,7 +2026,7 @@ class AsyncJob {
|
|
|
2056
2026
|
/** Backward compatible cache method for resource */
|
|
2057
2027
|
cache() {
|
|
2058
2028
|
isDev &&
|
|
2059
|
-
console.error('useResource cache() method does not do anything. Use `useAsync$` instead of `useResource$`, use the `
|
|
2029
|
+
console.error('useResource cache() method does not do anything. Use `useAsync$` instead of `useResource$`, use the `expires` option for polling behavior.');
|
|
2060
2030
|
}
|
|
2061
2031
|
get previous() {
|
|
2062
2032
|
const val = this.$signal$.$untrackedValue$;
|
|
@@ -2076,48 +2046,55 @@ class AsyncJob {
|
|
|
2076
2046
|
* AsyncSignalImpl
|
|
2077
2047
|
*
|
|
2078
2048
|
* # ================================
|
|
2049
|
+
*
|
|
2050
|
+
* @internal
|
|
2079
2051
|
*/
|
|
2080
2052
|
class AsyncSignalImpl extends ComputedSignalImpl {
|
|
2081
2053
|
$untrackedLoading$ = false;
|
|
2082
2054
|
$untrackedError$ = undefined;
|
|
2083
|
-
$loadingEffects$ = undefined;
|
|
2084
|
-
$errorEffects$ = undefined;
|
|
2085
2055
|
$current$ = null;
|
|
2086
|
-
// TODO only create the array if concurrency > 1
|
|
2087
|
-
$jobs$ = [];
|
|
2088
|
-
$concurrency$ = 1;
|
|
2089
|
-
$interval$ = 0;
|
|
2090
|
-
$timeoutMs$;
|
|
2091
|
-
$info$ = undefined;
|
|
2092
|
-
$infoVersion$ = 0;
|
|
2093
2056
|
[_EFFECT_BACK_REF] = undefined;
|
|
2094
2057
|
constructor(container, fn, flags = 1 /* SignalFlags.INVALID */ |
|
|
2095
2058
|
16 /* SerializationSignalFlags.SERIALIZATION_STRATEGY_ALWAYS */, options) {
|
|
2096
2059
|
super(container, fn, flags);
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
const timeout = options?.timeout;
|
|
2101
|
-
const eagerCleanup = options?.eagerCleanup;
|
|
2102
|
-
const clientOnly = options?.clientOnly;
|
|
2060
|
+
if (!options) {
|
|
2061
|
+
return;
|
|
2062
|
+
}
|
|
2103
2063
|
// Handle initial value - eagerly evaluate if function, set $untrackedValue$ and $promiseValue$
|
|
2104
2064
|
// Do NOT call setValue() which would clear the INVALID flag and prevent async computation
|
|
2065
|
+
const initial = options.initial;
|
|
2105
2066
|
if (initial !== undefined) {
|
|
2106
2067
|
const initialValue = typeof initial === 'function' ? initial() : initial;
|
|
2107
2068
|
this.$untrackedValue$ = initialValue;
|
|
2108
2069
|
}
|
|
2109
|
-
|
|
2070
|
+
const concurrency = options.concurrency;
|
|
2071
|
+
if (concurrency !== undefined && concurrency >= 0 && concurrency !== 1) {
|
|
2072
|
+
this.$concurrency$ = concurrency;
|
|
2073
|
+
this.$jobs$ = [];
|
|
2074
|
+
}
|
|
2075
|
+
const timeout = options.timeout;
|
|
2110
2076
|
if (timeout) {
|
|
2111
2077
|
this.$timeoutMs$ = timeout;
|
|
2112
2078
|
}
|
|
2113
|
-
if (eagerCleanup) {
|
|
2079
|
+
if (options.eagerCleanup) {
|
|
2114
2080
|
this.$flags$ |= 32 /* AsyncSignalFlags.EAGER_CLEANUP */;
|
|
2115
2081
|
}
|
|
2116
|
-
if (clientOnly) {
|
|
2082
|
+
if (options.clientOnly) {
|
|
2117
2083
|
this.$flags$ |= 64 /* AsyncSignalFlags.CLIENT_ONLY */;
|
|
2118
2084
|
}
|
|
2119
|
-
if (
|
|
2120
|
-
|
|
2085
|
+
if (options.allowStale === false) {
|
|
2086
|
+
if (isDev && initial !== undefined) {
|
|
2087
|
+
throw new Error('allowStale: false and initial cannot be used together. ' +
|
|
2088
|
+
'allowStale: false clears the value on invalidation, which conflicts with providing an initial value.');
|
|
2089
|
+
}
|
|
2090
|
+
this.$flags$ |= 128 /* AsyncSignalFlags.CLEAR_ON_INVALIDATE */;
|
|
2091
|
+
}
|
|
2092
|
+
const expires = options.expires ?? (options.interval ? Math.abs(options.interval) : undefined);
|
|
2093
|
+
if (expires) {
|
|
2094
|
+
this.expires = expires;
|
|
2095
|
+
}
|
|
2096
|
+
if (options.poll === false || (options.interval !== undefined && options.interval < 0)) {
|
|
2097
|
+
this.$flags$ |= 256 /* AsyncSignalFlags.NO_POLL */;
|
|
2121
2098
|
}
|
|
2122
2099
|
}
|
|
2123
2100
|
get untrackedValue() {
|
|
@@ -2137,9 +2114,7 @@ class AsyncSignalImpl extends ComputedSignalImpl {
|
|
|
2137
2114
|
if ((import.meta.env.TEST ? isServerPlatform() : isServer) &&
|
|
2138
2115
|
this.$flags$ & 64 /* AsyncSignalFlags.CLIENT_ONLY */ &&
|
|
2139
2116
|
this.$untrackedValue$ === NEEDS_COMPUTATION) {
|
|
2140
|
-
throw
|
|
2141
|
-
? 'During SSR, cannot read .value from clientOnly async signal without an initial value. Use .loading or provide an initial value.'
|
|
2142
|
-
: 'Cannot read .value from clientOnly');
|
|
2117
|
+
throw qError(35 /* QError.asyncClientOnlyValueDuringSSR */);
|
|
2143
2118
|
}
|
|
2144
2119
|
return this.$untrackedValue$;
|
|
2145
2120
|
}
|
|
@@ -2166,8 +2141,13 @@ class AsyncSignalImpl extends ComputedSignalImpl {
|
|
|
2166
2141
|
this.untrackedError = undefined;
|
|
2167
2142
|
this.$info$ = undefined;
|
|
2168
2143
|
// Prevent pending computations from overwriting this value
|
|
2169
|
-
|
|
2170
|
-
this.$jobs
|
|
2144
|
+
if (this.$jobs$) {
|
|
2145
|
+
for (let i = 0; i < this.$jobs$.length; i++) {
|
|
2146
|
+
this.$jobs$[i].$canWrite$ = false;
|
|
2147
|
+
}
|
|
2148
|
+
}
|
|
2149
|
+
else if (this.$current$) {
|
|
2150
|
+
this.$current$.$canWrite$ = false;
|
|
2171
2151
|
}
|
|
2172
2152
|
this.$clearNextPoll$();
|
|
2173
2153
|
super.value = value;
|
|
@@ -2235,28 +2215,64 @@ class AsyncSignalImpl extends ComputedSignalImpl {
|
|
|
2235
2215
|
get untrackedError() {
|
|
2236
2216
|
return this.$untrackedError$;
|
|
2237
2217
|
}
|
|
2238
|
-
get
|
|
2239
|
-
return this.$
|
|
2218
|
+
get expires() {
|
|
2219
|
+
return this.$expires$ || 0;
|
|
2240
2220
|
}
|
|
2241
|
-
set
|
|
2221
|
+
set expires(value) {
|
|
2242
2222
|
this.$clearNextPoll$();
|
|
2243
|
-
this.$
|
|
2244
|
-
if (this.$
|
|
2223
|
+
this.$expires$ = value;
|
|
2224
|
+
if (this.$expires$ && this.$hasSubscribers$()) {
|
|
2245
2225
|
this.$scheduleNextPoll$();
|
|
2246
2226
|
}
|
|
2247
2227
|
}
|
|
2228
|
+
get poll() {
|
|
2229
|
+
return !(this.$flags$ & 256 /* AsyncSignalFlags.NO_POLL */);
|
|
2230
|
+
}
|
|
2231
|
+
set poll(value) {
|
|
2232
|
+
if (value) {
|
|
2233
|
+
this.$flags$ &= -257 /* AsyncSignalFlags.NO_POLL */;
|
|
2234
|
+
}
|
|
2235
|
+
else {
|
|
2236
|
+
this.$flags$ |= 256 /* AsyncSignalFlags.NO_POLL */;
|
|
2237
|
+
}
|
|
2238
|
+
// Reschedule since poll behavior changed
|
|
2239
|
+
if (this.$expires$ && this.$hasSubscribers$()) {
|
|
2240
|
+
this.$clearNextPoll$();
|
|
2241
|
+
this.$scheduleNextPoll$();
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
/** @deprecated Use `expires` and `poll` instead. */
|
|
2245
|
+
get interval() {
|
|
2246
|
+
const expires = this.$expires$ || 0;
|
|
2247
|
+
return this.$flags$ & 256 /* AsyncSignalFlags.NO_POLL */ ? -expires : expires;
|
|
2248
|
+
}
|
|
2249
|
+
set interval(value) {
|
|
2250
|
+
if (value < 0) {
|
|
2251
|
+
this.$flags$ |= 256 /* AsyncSignalFlags.NO_POLL */;
|
|
2252
|
+
}
|
|
2253
|
+
else {
|
|
2254
|
+
this.$flags$ &= -257 /* AsyncSignalFlags.NO_POLL */;
|
|
2255
|
+
}
|
|
2256
|
+
this.expires = Math.abs(value);
|
|
2257
|
+
}
|
|
2248
2258
|
/** Invalidates the signal, causing it to re-compute its value. */
|
|
2249
2259
|
async invalidate(info) {
|
|
2250
|
-
this.$flags$ |= 1 /* SignalFlags.INVALID */;
|
|
2251
|
-
this.$clearNextPoll$();
|
|
2252
2260
|
if (arguments.length > 0) {
|
|
2253
2261
|
this.$info$ = info;
|
|
2254
|
-
this.$infoVersion
|
|
2262
|
+
this.$infoVersion$ = this.$infoVersion$ === undefined ? 1 : this.$infoVersion$ + 1;
|
|
2255
2263
|
}
|
|
2256
|
-
|
|
2264
|
+
this.$setInvalid$(true, this.$flags$ & 128 /* AsyncSignalFlags.CLEAR_ON_INVALIDATE */);
|
|
2265
|
+
}
|
|
2266
|
+
$setInvalid$(allowRecalc, mustClear) {
|
|
2267
|
+
this.$flags$ |= 1 /* SignalFlags.INVALID */;
|
|
2268
|
+
this.$clearNextPoll$();
|
|
2269
|
+
if (mustClear) {
|
|
2270
|
+
this.$untrackedValue$ = NEEDS_COMPUTATION;
|
|
2271
|
+
}
|
|
2272
|
+
if (allowRecalc &&
|
|
2273
|
+
(this.$effects$?.size || this.$loadingEffects$?.size || this.$errorEffects$?.size)) {
|
|
2257
2274
|
// compute in next microtask
|
|
2258
|
-
|
|
2259
|
-
this.$computeIfNeeded$();
|
|
2275
|
+
Promise.resolve().then(() => this.$computeIfNeeded$());
|
|
2260
2276
|
}
|
|
2261
2277
|
}
|
|
2262
2278
|
/** Abort the current computation and run cleanups if needed. */
|
|
@@ -2301,63 +2317,92 @@ class AsyncSignalImpl extends ComputedSignalImpl {
|
|
|
2301
2317
|
return;
|
|
2302
2318
|
}
|
|
2303
2319
|
this.$clearNextPoll$();
|
|
2304
|
-
|
|
2305
|
-
|
|
2320
|
+
// Clear flag here to make sure the cleanups don't start another compute
|
|
2321
|
+
this.$flags$ &= -2 /* SignalFlags.INVALID */;
|
|
2322
|
+
const current = this.$current$;
|
|
2323
|
+
if (current) {
|
|
2324
|
+
this.$requestCleanups$(current);
|
|
2306
2325
|
}
|
|
2307
|
-
const limit = this.$concurrency$ === 0 ? Number.POSITIVE_INFINITY : this.$concurrency
|
|
2308
|
-
|
|
2326
|
+
const limit = this.$concurrency$ === 0 ? Number.POSITIVE_INFINITY : (this.$concurrency$ ?? 1);
|
|
2327
|
+
// We only have $jobs$[] when concurrency != 1
|
|
2328
|
+
if (this.$jobs$ ? this.$jobs$.length >= limit : current?.$promise$) {
|
|
2309
2329
|
// We requested cleanups for all the previous jobs, once one finishes it will be removed from the jobs array and trigger computeIfNeeded
|
|
2330
|
+
// Restore invalid state
|
|
2331
|
+
this.$flags$ |= 1 /* SignalFlags.INVALID */;
|
|
2310
2332
|
return;
|
|
2311
2333
|
}
|
|
2312
|
-
this.$flags$ &= -2 /* SignalFlags.INVALID */;
|
|
2313
2334
|
// We put the actual computation in a separate method so we can easily retain the promise
|
|
2314
2335
|
const infoVersion = this.$infoVersion$;
|
|
2315
2336
|
const running = new AsyncJob(this, this.$info$, infoVersion);
|
|
2316
2337
|
this.$current$ = running;
|
|
2317
|
-
this.$jobs
|
|
2338
|
+
if (this.$jobs$) {
|
|
2339
|
+
this.$jobs$.push(running);
|
|
2340
|
+
}
|
|
2318
2341
|
running.$promise$ = this.$runComputation$(running);
|
|
2319
2342
|
}
|
|
2320
2343
|
async $runComputation$(running) {
|
|
2321
2344
|
const isCurrent = () => running === this.$current$;
|
|
2322
|
-
|
|
2323
|
-
|
|
2345
|
+
let fn = this.$computeQrl$.resolved;
|
|
2346
|
+
if (!fn) {
|
|
2347
|
+
// QRL resolution is async — we have to publish loading=true before awaiting so
|
|
2348
|
+
// subscribers know the value isn't ready yet.
|
|
2349
|
+
this.untrackedLoading = true;
|
|
2350
|
+
fn = await this.$computeQrl$.resolve();
|
|
2351
|
+
if (running.$abortController$?.signal.aborted) {
|
|
2352
|
+
running.$promise$ = null;
|
|
2353
|
+
return;
|
|
2354
|
+
}
|
|
2355
|
+
}
|
|
2324
2356
|
try {
|
|
2325
2357
|
if (this.$timeoutMs$) {
|
|
2326
2358
|
this.$computationTimeoutId$ = setTimeout(() => {
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
this.untrackedError = error;
|
|
2331
|
-
running.$canWrite$ = false;
|
|
2332
|
-
}
|
|
2359
|
+
const error = new Error(`timeout ${this.$timeoutMs$}ms`);
|
|
2360
|
+
this.$setError$(running, error);
|
|
2361
|
+
running.$abortController$?.abort(error);
|
|
2333
2362
|
}, this.$timeoutMs$);
|
|
2334
2363
|
}
|
|
2335
|
-
// Try to stay sync if possible
|
|
2364
|
+
// Try to stay sync if possible. Only publish loading=true to subscribers when
|
|
2365
|
+
// the compute is actually asynchronous — a synchronous resolve (e.g. pre-loaded
|
|
2366
|
+
// values injected via _injectAsyncSignalValue) should never transition through a
|
|
2367
|
+
// visible loading state, which on SSR would fire the loading-effect subscribers
|
|
2368
|
+
// (tasks) while the value is still "loading" from their perspective.
|
|
2336
2369
|
const valuePromise = retryOnPromise(fn.bind(null, running));
|
|
2337
|
-
|
|
2370
|
+
let value;
|
|
2371
|
+
if (isPromise(valuePromise)) {
|
|
2372
|
+
this.untrackedLoading = true;
|
|
2373
|
+
value = await valuePromise;
|
|
2374
|
+
}
|
|
2375
|
+
else {
|
|
2376
|
+
value = valuePromise;
|
|
2377
|
+
}
|
|
2338
2378
|
running.$promise$ = null;
|
|
2339
2379
|
if (running.$canWrite$) {
|
|
2340
|
-
const
|
|
2341
|
-
if (
|
|
2342
|
-
|
|
2343
|
-
|
|
2380
|
+
const jobs = this.$jobs$;
|
|
2381
|
+
if (jobs) {
|
|
2382
|
+
let doDisable = false;
|
|
2383
|
+
for (let i = jobs.length - 1; i >= 0; i--) {
|
|
2384
|
+
if (jobs[i] === running) {
|
|
2385
|
+
doDisable = true;
|
|
2386
|
+
}
|
|
2387
|
+
else if (doDisable) {
|
|
2388
|
+
jobs[i].$canWrite$ = false;
|
|
2389
|
+
}
|
|
2344
2390
|
}
|
|
2345
2391
|
}
|
|
2346
2392
|
DEBUG && log('Promise resolved', value);
|
|
2347
2393
|
// we leave error as-is until result
|
|
2348
2394
|
// Note that these assignments run setters
|
|
2349
2395
|
this.untrackedError = undefined;
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2396
|
+
/**
|
|
2397
|
+
* Use super.value instead of this.value to persist invalid state, so that invalidation
|
|
2398
|
+
* during computation recomputes
|
|
2399
|
+
*/
|
|
2353
2400
|
super.value = value;
|
|
2354
2401
|
}
|
|
2355
2402
|
}
|
|
2356
2403
|
catch (err) {
|
|
2357
2404
|
running.$promise$ = null;
|
|
2358
|
-
|
|
2359
|
-
this.untrackedError = err;
|
|
2360
|
-
}
|
|
2405
|
+
this.$setError$(running, err);
|
|
2361
2406
|
}
|
|
2362
2407
|
if (isCurrent()) {
|
|
2363
2408
|
clearTimeout(this.$computationTimeoutId$);
|
|
@@ -2374,14 +2419,37 @@ class AsyncSignalImpl extends ComputedSignalImpl {
|
|
|
2374
2419
|
}
|
|
2375
2420
|
}
|
|
2376
2421
|
}
|
|
2422
|
+
/**
|
|
2423
|
+
* Sets the error from the given job. We only accept errors from the current job and we ignore
|
|
2424
|
+
* AbortErrors.
|
|
2425
|
+
*/
|
|
2426
|
+
$setError$(job, error) {
|
|
2427
|
+
if (job !== this.$current$ || !job.$canWrite$) {
|
|
2428
|
+
return;
|
|
2429
|
+
}
|
|
2430
|
+
job.$canWrite$ = false;
|
|
2431
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
2432
|
+
// AbortError from AbortSignal is a cancellation, not an actual error
|
|
2433
|
+
return;
|
|
2434
|
+
}
|
|
2435
|
+
this.untrackedError = error;
|
|
2436
|
+
// Job failures should be rare and require retrying
|
|
2437
|
+
this.untrackedValue = NEEDS_COMPUTATION;
|
|
2438
|
+
}
|
|
2377
2439
|
/** Called after SSR/unmount */
|
|
2378
2440
|
async $destroy$() {
|
|
2379
2441
|
this.$clearNextPoll$();
|
|
2380
2442
|
clearTimeout(this.$computationTimeoutId$);
|
|
2381
|
-
|
|
2382
|
-
|
|
2443
|
+
const current = this.$current$;
|
|
2444
|
+
if (current) {
|
|
2445
|
+
this.$requestCleanups$(current);
|
|
2446
|
+
}
|
|
2447
|
+
if (this.$jobs$) {
|
|
2448
|
+
await Promise.all(this.$jobs$.map((job) => job.$promise$));
|
|
2449
|
+
}
|
|
2450
|
+
else {
|
|
2451
|
+
await current?.$promise$;
|
|
2383
2452
|
}
|
|
2384
|
-
await Promise.all(this.$jobs$.map((job) => job.$promise$));
|
|
2385
2453
|
}
|
|
2386
2454
|
$clearNextPoll$() {
|
|
2387
2455
|
if (this.$pollTimeoutId$ !== undefined) {
|
|
@@ -2390,66 +2458,76 @@ class AsyncSignalImpl extends ComputedSignalImpl {
|
|
|
2390
2458
|
}
|
|
2391
2459
|
}
|
|
2392
2460
|
$scheduleNextPoll$() {
|
|
2393
|
-
if (
|
|
2461
|
+
if ((import.meta.env.TEST ? isServerPlatform() : isServer) || !this.$expires$) {
|
|
2394
2462
|
return;
|
|
2395
2463
|
}
|
|
2396
2464
|
this.$clearNextPoll$();
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
}
|
|
2403
|
-
else {
|
|
2404
|
-
this.$pollTimeoutId$ = setTimeout(this.invalidate.bind(this), this.$interval$);
|
|
2405
|
-
}
|
|
2465
|
+
const allowRecalc = !(this.$flags$ & 256 /* AsyncSignalFlags.NO_POLL */);
|
|
2466
|
+
// Even when clear on invalidate, we don't clear if we're merely re-running due to polling
|
|
2467
|
+
// We expect to get the new value soon, so we can avoid showing a loading state
|
|
2468
|
+
const mustClear = this.$flags$ & 128 /* AsyncSignalFlags.CLEAR_ON_INVALIDATE */ && !allowRecalc;
|
|
2469
|
+
this.$pollTimeoutId$ = setTimeout(() => this.$setInvalid$(allowRecalc, mustClear), this.$expires$);
|
|
2406
2470
|
this.$pollTimeoutId$?.unref?.();
|
|
2407
2471
|
}
|
|
2408
2472
|
$hasSubscribers$() {
|
|
2409
2473
|
return !!(this.$effects$?.size || this.$loadingEffects$?.size || this.$errorEffects$?.size);
|
|
2410
2474
|
}
|
|
2411
|
-
|
|
2475
|
+
$requestCleanups$(job, reason) {
|
|
2412
2476
|
if (job.$cleanupRequested$) {
|
|
2413
|
-
return
|
|
2477
|
+
return;
|
|
2414
2478
|
}
|
|
2415
2479
|
job.$cleanupRequested$ = true;
|
|
2416
2480
|
job.$abortController$?.abort(reason);
|
|
2417
|
-
job.$promise$ =
|
|
2481
|
+
job.$promise$ = maybeThen(job.$promise$, () => this.$runCleanups$(job));
|
|
2418
2482
|
}
|
|
2419
2483
|
/** Clean up and trigger signal compute once complete */
|
|
2420
|
-
|
|
2484
|
+
$runCleanups$(job) {
|
|
2421
2485
|
const cleanups = job.$cleanups$;
|
|
2422
|
-
|
|
2423
|
-
const
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2486
|
+
const onError = (err) => {
|
|
2487
|
+
const handleError = this.$container$?.handleError;
|
|
2488
|
+
if (handleError) {
|
|
2489
|
+
handleError(err, null);
|
|
2490
|
+
}
|
|
2491
|
+
else {
|
|
2492
|
+
console.error('Error in async signal cleanup', err);
|
|
2493
|
+
}
|
|
2494
|
+
};
|
|
2495
|
+
const onDone = () => {
|
|
2496
|
+
job.$promise$ = null;
|
|
2497
|
+
if (cleanups) {
|
|
2498
|
+
cleanups.length = 0;
|
|
2499
|
+
}
|
|
2500
|
+
// Now trigger compute
|
|
2501
|
+
const jobs = this.$jobs$;
|
|
2502
|
+
if (jobs) {
|
|
2503
|
+
const idx = jobs.indexOf(job);
|
|
2504
|
+
if (idx !== -1) {
|
|
2505
|
+
jobs.splice(idx, 1);
|
|
2430
2506
|
}
|
|
2431
|
-
}
|
|
2507
|
+
}
|
|
2508
|
+
this.$computeIfNeeded$();
|
|
2509
|
+
};
|
|
2510
|
+
let promiseChain = undefined;
|
|
2511
|
+
if (cleanups) {
|
|
2432
2512
|
// Keep this sync-ish so sync functions run immediately.
|
|
2433
|
-
|
|
2513
|
+
for (let i = 0; i < cleanups.length; i++) {
|
|
2434
2514
|
try {
|
|
2435
|
-
const result =
|
|
2515
|
+
const result = cleanups[i]();
|
|
2436
2516
|
if (isPromise(result)) {
|
|
2437
|
-
|
|
2517
|
+
promiseChain = (promiseChain ? promiseChain.then(() => result) : result).catch(onError);
|
|
2438
2518
|
}
|
|
2439
2519
|
}
|
|
2440
2520
|
catch (err) {
|
|
2441
2521
|
onError(err);
|
|
2442
2522
|
}
|
|
2443
|
-
}
|
|
2444
|
-
cleanups.length = 0;
|
|
2523
|
+
}
|
|
2445
2524
|
}
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2525
|
+
if (promiseChain) {
|
|
2526
|
+
return promiseChain.then(onDone);
|
|
2527
|
+
}
|
|
2528
|
+
else {
|
|
2529
|
+
onDone();
|
|
2451
2530
|
}
|
|
2452
|
-
this.$computeIfNeeded$();
|
|
2453
2531
|
}
|
|
2454
2532
|
}
|
|
2455
2533
|
|
|
@@ -3108,7 +3186,69 @@ const isJSXNode = (n) => {
|
|
|
3108
3186
|
|
|
3109
3187
|
const BIND_VALUE = 'bind:value';
|
|
3110
3188
|
const BIND_CHECKED = 'bind:checked';
|
|
3189
|
+
const PASSIVE = 'passive:';
|
|
3190
|
+
const PREVENT_DEFAULT = 'preventdefault:';
|
|
3111
3191
|
const _hasOwnProperty$1 = Object.prototype.hasOwnProperty;
|
|
3192
|
+
const removePassiveMarkers = (props, passiveKeys, preventDefaultKeys, passiveEvents, canMutate = false) => {
|
|
3193
|
+
let mutableProps = props;
|
|
3194
|
+
let copied = canMutate;
|
|
3195
|
+
if (passiveKeys.length > 0) {
|
|
3196
|
+
if (!copied) {
|
|
3197
|
+
mutableProps = { ...mutableProps };
|
|
3198
|
+
copied = true;
|
|
3199
|
+
}
|
|
3200
|
+
for (let i = 0; i < passiveKeys.length; i++) {
|
|
3201
|
+
const k = passiveKeys[i];
|
|
3202
|
+
delete mutableProps[k];
|
|
3203
|
+
}
|
|
3204
|
+
}
|
|
3205
|
+
if (preventDefaultKeys.length > 0) {
|
|
3206
|
+
for (let i = 0; i < preventDefaultKeys.length; i++) {
|
|
3207
|
+
const k = preventDefaultKeys[i];
|
|
3208
|
+
if (passiveEvents.has(normalizeJsxEventName(k.slice(PREVENT_DEFAULT.length)))) {
|
|
3209
|
+
if (!copied) {
|
|
3210
|
+
mutableProps = { ...mutableProps };
|
|
3211
|
+
copied = true;
|
|
3212
|
+
}
|
|
3213
|
+
delete mutableProps[k];
|
|
3214
|
+
}
|
|
3215
|
+
}
|
|
3216
|
+
}
|
|
3217
|
+
return mutableProps;
|
|
3218
|
+
};
|
|
3219
|
+
const getPassiveEventKey = (key) => {
|
|
3220
|
+
if (key.startsWith('on') && key.endsWith('$')) {
|
|
3221
|
+
return normalizeJsxEventName(key.slice(2, -1));
|
|
3222
|
+
}
|
|
3223
|
+
if (key.startsWith('window:on') && key.endsWith('$')) {
|
|
3224
|
+
return normalizeJsxEventName(key.slice(9, -1));
|
|
3225
|
+
}
|
|
3226
|
+
if (key.startsWith('document:on') && key.endsWith('$')) {
|
|
3227
|
+
return normalizeJsxEventName(key.slice(11, -1));
|
|
3228
|
+
}
|
|
3229
|
+
return null;
|
|
3230
|
+
};
|
|
3231
|
+
const convertJsxEventProps = (props, eventKeys, keyOrder, passiveEvents, canMutate = false) => {
|
|
3232
|
+
let mutableProps = props;
|
|
3233
|
+
let copied = canMutate;
|
|
3234
|
+
for (let i = 0; i < eventKeys.length; i++) {
|
|
3235
|
+
const k = eventKeys[i];
|
|
3236
|
+
const passiveEventKey = getPassiveEventKey(k);
|
|
3237
|
+
const attr = jsxEventToHtmlAttribute(k, passiveEvents.has(passiveEventKey));
|
|
3238
|
+
if (attr) {
|
|
3239
|
+
if (!copied) {
|
|
3240
|
+
mutableProps = { ...mutableProps };
|
|
3241
|
+
copied = true;
|
|
3242
|
+
}
|
|
3243
|
+
const attrIndex = keyOrder.get(attr);
|
|
3244
|
+
if (attrIndex === undefined || attrIndex < keyOrder.get(k)) {
|
|
3245
|
+
mutableProps[attr] = mutableProps[k];
|
|
3246
|
+
}
|
|
3247
|
+
delete mutableProps[k];
|
|
3248
|
+
}
|
|
3249
|
+
}
|
|
3250
|
+
return mutableProps;
|
|
3251
|
+
};
|
|
3112
3252
|
/**
|
|
3113
3253
|
* Create a JSXNode with the properties fully split into variable and constant parts, and children
|
|
3114
3254
|
* separated out. Furthermore, the varProps must be a sorted object, that is, the keys must be
|
|
@@ -3154,20 +3294,28 @@ const _jsxSplit = (type, varProps, constProps, children, flags, key, dev) => {
|
|
|
3154
3294
|
let bindCheckedSignal = null;
|
|
3155
3295
|
// Apply transformations for native HTML elements only
|
|
3156
3296
|
if (typeof type === 'string') {
|
|
3157
|
-
|
|
3297
|
+
const passiveEvents = new Set();
|
|
3298
|
+
const constEventKeys = [];
|
|
3299
|
+
const varEventKeys = [];
|
|
3300
|
+
const constPassiveKeys = [];
|
|
3301
|
+
const varPassiveKeys = [];
|
|
3302
|
+
const constPreventDefaultKeys = [];
|
|
3303
|
+
const varPreventDefaultKeys = [];
|
|
3304
|
+
const constKeyOrder = new Map();
|
|
3305
|
+
const varKeyOrder = new Map();
|
|
3158
3306
|
if (constProps) {
|
|
3159
|
-
|
|
3307
|
+
let index = 0;
|
|
3160
3308
|
for (const k in constProps) {
|
|
3161
|
-
|
|
3162
|
-
if (
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3309
|
+
constKeyOrder.set(k, index++);
|
|
3310
|
+
if (k.startsWith(PASSIVE)) {
|
|
3311
|
+
constPassiveKeys.push(k);
|
|
3312
|
+
passiveEvents.add(normalizeJsxEventName(k.slice(PASSIVE.length)));
|
|
3313
|
+
}
|
|
3314
|
+
else if (k.startsWith(PREVENT_DEFAULT)) {
|
|
3315
|
+
constPreventDefaultKeys.push(k);
|
|
3316
|
+
}
|
|
3317
|
+
else if (getPassiveEventKey(k) !== null) {
|
|
3318
|
+
constEventKeys.push(k);
|
|
3171
3319
|
}
|
|
3172
3320
|
else if (k === BIND_CHECKED) {
|
|
3173
3321
|
// Set flag, will process after walk
|
|
@@ -3177,24 +3325,21 @@ const _jsxSplit = (type, varProps, constProps, children, flags, key, dev) => {
|
|
|
3177
3325
|
// Set flag, will process after walk
|
|
3178
3326
|
bindValueSignal = constProps[k];
|
|
3179
3327
|
}
|
|
3180
|
-
processedKeys.add(k);
|
|
3181
3328
|
}
|
|
3182
3329
|
}
|
|
3183
3330
|
if (varProps) {
|
|
3184
|
-
|
|
3331
|
+
let index = 0;
|
|
3185
3332
|
for (const k in varProps) {
|
|
3186
|
-
|
|
3187
|
-
if (
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
delete varProps[k];
|
|
3197
|
-
toSort = true;
|
|
3333
|
+
varKeyOrder.set(k, index++);
|
|
3334
|
+
if (k.startsWith(PASSIVE)) {
|
|
3335
|
+
varPassiveKeys.push(k);
|
|
3336
|
+
passiveEvents.add(normalizeJsxEventName(k.slice(PASSIVE.length)));
|
|
3337
|
+
}
|
|
3338
|
+
else if (k.startsWith(PREVENT_DEFAULT)) {
|
|
3339
|
+
varPreventDefaultKeys.push(k);
|
|
3340
|
+
}
|
|
3341
|
+
else if (getPassiveEventKey(k) !== null) {
|
|
3342
|
+
varEventKeys.push(k);
|
|
3198
3343
|
}
|
|
3199
3344
|
else if (k === BIND_CHECKED) {
|
|
3200
3345
|
// Set flag, will process after walk
|
|
@@ -3204,9 +3349,23 @@ const _jsxSplit = (type, varProps, constProps, children, flags, key, dev) => {
|
|
|
3204
3349
|
// Set flag, will process after walk
|
|
3205
3350
|
bindValueSignal = varProps[k];
|
|
3206
3351
|
}
|
|
3207
|
-
processedKeys.add(k);
|
|
3208
3352
|
}
|
|
3209
3353
|
}
|
|
3354
|
+
if (constProps) {
|
|
3355
|
+
const originalConstProps = constProps;
|
|
3356
|
+
constProps = removePassiveMarkers(constProps, constPassiveKeys, constPreventDefaultKeys, passiveEvents, constPropsCopied);
|
|
3357
|
+
constPropsCopied = constPropsCopied || constProps !== originalConstProps;
|
|
3358
|
+
constProps = convertJsxEventProps(constProps, constEventKeys, constKeyOrder, passiveEvents, constPropsCopied);
|
|
3359
|
+
constPropsCopied = constPropsCopied || constProps !== originalConstProps;
|
|
3360
|
+
}
|
|
3361
|
+
if (varProps) {
|
|
3362
|
+
const originalVarProps = varProps;
|
|
3363
|
+
varProps = removePassiveMarkers(varProps, varPassiveKeys, varPreventDefaultKeys, passiveEvents, varPropsCopied);
|
|
3364
|
+
varPropsCopied = varPropsCopied || varProps !== originalVarProps;
|
|
3365
|
+
varProps = convertJsxEventProps(varProps, varEventKeys, varKeyOrder, passiveEvents, varPropsCopied);
|
|
3366
|
+
varPropsCopied = varPropsCopied || varProps !== originalVarProps;
|
|
3367
|
+
toSort = toSort || varEventKeys.length > 0;
|
|
3368
|
+
}
|
|
3210
3369
|
// Handle bind:* - only in varProps, bind:* should be moved to varProps
|
|
3211
3370
|
if (bindCheckedSignal || bindValueSignal) {
|
|
3212
3371
|
if (!varPropsCopied) {
|
|
@@ -3518,11 +3677,13 @@ function addUseOnEvents(jsx, useOnEvents) {
|
|
|
3518
3677
|
}
|
|
3519
3678
|
else {
|
|
3520
3679
|
if (isDev) {
|
|
3680
|
+
const sourceLocation = getUseOnSourceLocation(useOnEvents[key].qrls);
|
|
3521
3681
|
logWarn('You are trying to add an event "' +
|
|
3522
3682
|
key +
|
|
3523
3683
|
'" using `useOn` hook, ' +
|
|
3524
3684
|
'but a node to which you can add an event is not found. ' +
|
|
3525
|
-
'Please make sure that the component
|
|
3685
|
+
'Please make sure that the component outputs a DOM element.' +
|
|
3686
|
+
(sourceLocation ? ` Offending \`useOn\`: ${sourceLocation}.` : ''));
|
|
3526
3687
|
}
|
|
3527
3688
|
continue;
|
|
3528
3689
|
}
|
|
@@ -3531,11 +3692,12 @@ function addUseOnEvents(jsx, useOnEvents) {
|
|
|
3531
3692
|
if (targetElement.type === 'script' && key === qVisibleEvent) {
|
|
3532
3693
|
eventKey = 'q-d:qinit';
|
|
3533
3694
|
if (isDev) {
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
'
|
|
3537
|
-
'but
|
|
3538
|
-
'
|
|
3695
|
+
const sourceLocation = getUseOnSourceLocation(useOnEvents[key].qrls);
|
|
3696
|
+
logWarn(`You are trying to add the event "${key}" ` +
|
|
3697
|
+
'using the `useVisibleTask$` hook with the "intersection-observer" strategy, ' +
|
|
3698
|
+
'but this only works when the component outputs a DOM element. Falling back to ' +
|
|
3699
|
+
'"document-ready" instead.' +
|
|
3700
|
+
(sourceLocation ? ` Offending \`useVisibleTask$\`: ${sourceLocation}.` : ''));
|
|
3539
3701
|
}
|
|
3540
3702
|
}
|
|
3541
3703
|
addUseOnEvent(targetElement, eventKey, useOnEvents[key]);
|
|
@@ -3545,6 +3707,21 @@ function addUseOnEvents(jsx, useOnEvents) {
|
|
|
3545
3707
|
return jsxResult;
|
|
3546
3708
|
});
|
|
3547
3709
|
}
|
|
3710
|
+
function getUseOnSourceLocation(eventQrls) {
|
|
3711
|
+
for (let i = 0; i < eventQrls.length; i++) {
|
|
3712
|
+
const eventQrl = eventQrls[i];
|
|
3713
|
+
const task = eventQrl?.getCaptured()?.[0];
|
|
3714
|
+
if (isTask(task)) {
|
|
3715
|
+
const dev = task.$qrl$.dev;
|
|
3716
|
+
if (dev?.file) {
|
|
3717
|
+
return typeof dev.lo === 'number' && typeof dev.hi === 'number'
|
|
3718
|
+
? `${dev.file}:${dev.lo}-${dev.hi}`
|
|
3719
|
+
: dev.file;
|
|
3720
|
+
}
|
|
3721
|
+
}
|
|
3722
|
+
}
|
|
3723
|
+
return null;
|
|
3724
|
+
}
|
|
3548
3725
|
/**
|
|
3549
3726
|
* Adds an event to the JSX element.
|
|
3550
3727
|
*
|
|
@@ -3556,14 +3733,15 @@ function addUseOnEvent(jsxElement, key, value) {
|
|
|
3556
3733
|
// These handlers are always there, so they go in constProps
|
|
3557
3734
|
const props = (jsxElement.constProps ||= {});
|
|
3558
3735
|
const propValue = props[key];
|
|
3736
|
+
const qrls = value.qrls;
|
|
3559
3737
|
if (propValue == null) {
|
|
3560
|
-
props[key] =
|
|
3738
|
+
props[key] = qrls;
|
|
3561
3739
|
}
|
|
3562
3740
|
else if (Array.isArray(propValue)) {
|
|
3563
|
-
propValue.push(...
|
|
3741
|
+
propValue.push(...qrls);
|
|
3564
3742
|
}
|
|
3565
3743
|
else {
|
|
3566
|
-
props[key] = [propValue, ...
|
|
3744
|
+
props[key] = [propValue, ...qrls];
|
|
3567
3745
|
}
|
|
3568
3746
|
const varProp = jsxElement.varProps[key];
|
|
3569
3747
|
if (varProp) {
|
|
@@ -3572,10 +3750,28 @@ function addUseOnEvent(jsxElement, key, value) {
|
|
|
3572
3750
|
propValue.push(...props[key]);
|
|
3573
3751
|
}
|
|
3574
3752
|
else {
|
|
3575
|
-
jsxElement.varProps[key] = [propValue, ...
|
|
3753
|
+
jsxElement.varProps[key] = [propValue, ...qrls];
|
|
3576
3754
|
}
|
|
3577
3755
|
props[key] = undefined;
|
|
3578
3756
|
}
|
|
3757
|
+
const capture = value.capture;
|
|
3758
|
+
const preventdefault = value.preventdefault;
|
|
3759
|
+
const stoppropagation = value.stoppropagation;
|
|
3760
|
+
if (!capture && !preventdefault && !stoppropagation) {
|
|
3761
|
+
return;
|
|
3762
|
+
}
|
|
3763
|
+
const [, eventName] = getEventDataFromHtmlAttribute(key);
|
|
3764
|
+
capture && addUseOnModifier(jsxElement, eventName, 'capture');
|
|
3765
|
+
preventdefault && addUseOnModifier(jsxElement, eventName, 'preventdefault');
|
|
3766
|
+
stoppropagation && addUseOnModifier(jsxElement, eventName, 'stoppropagation');
|
|
3767
|
+
}
|
|
3768
|
+
function addUseOnModifier(jsxElement, eventName, modifier) {
|
|
3769
|
+
const key = `${modifier}:${eventName}`;
|
|
3770
|
+
const varProps = jsxElement.varProps;
|
|
3771
|
+
if (varProps === EMPTY_OBJ) {
|
|
3772
|
+
jsxElement.varProps = {};
|
|
3773
|
+
}
|
|
3774
|
+
jsxElement.varProps[key] = true;
|
|
3579
3775
|
}
|
|
3580
3776
|
/**
|
|
3581
3777
|
* Finds the first element node in the JSX output.
|
|
@@ -6080,13 +6276,18 @@ function scheduleYield() {
|
|
|
6080
6276
|
*
|
|
6081
6277
|
* @param options - Walk options (time budget, etc.)
|
|
6082
6278
|
*/
|
|
6083
|
-
function processCursorQueue(
|
|
6084
|
-
timeBudget: 1000 / 60, // 60fps
|
|
6085
|
-
}) {
|
|
6279
|
+
function processCursorQueue() {
|
|
6086
6280
|
isNextTickScheduled = false;
|
|
6281
|
+
const startTime = performance.now();
|
|
6282
|
+
const yieldTime = startTime + 15; // 16 ms = 60 FPS, use 15 to yield slightly before next frame
|
|
6087
6283
|
let cursor = null;
|
|
6088
6284
|
while ((cursor = getHighestPriorityCursor())) {
|
|
6089
|
-
walkCursor(cursor,
|
|
6285
|
+
if (walkCursor(cursor, yieldTime)) {
|
|
6286
|
+
// Cursor overran time budget, yield to browser
|
|
6287
|
+
// Note that each tick we process at least one thing
|
|
6288
|
+
scheduleYield();
|
|
6289
|
+
return;
|
|
6290
|
+
}
|
|
6090
6291
|
}
|
|
6091
6292
|
}
|
|
6092
6293
|
/**
|
|
@@ -6105,13 +6306,12 @@ function processCursorQueue(options = {
|
|
|
6105
6306
|
* Note that there is only one walker for all containers in the app with the same Qwik version.
|
|
6106
6307
|
*
|
|
6107
6308
|
* @param cursor - The cursor to walk
|
|
6108
|
-
* @param
|
|
6109
|
-
* @returns
|
|
6309
|
+
* @param until - Time budget (timestamp to yield by)
|
|
6310
|
+
* @returns `true` if the walk was paused due to time budget (do not process more cursors in this
|
|
6311
|
+
* tick)
|
|
6110
6312
|
*/
|
|
6111
|
-
function walkCursor(cursor,
|
|
6112
|
-
const { timeBudget } = options;
|
|
6313
|
+
function walkCursor(cursor, until) {
|
|
6113
6314
|
const isRunningOnServer = import.meta.env.TEST ? isServerPlatform() : isServer;
|
|
6114
|
-
const startTime = performance.now();
|
|
6115
6315
|
const cursorData = getCursorData(cursor);
|
|
6116
6316
|
// Check if cursor is blocked by a promise
|
|
6117
6317
|
const blockingPromise = cursorData.promise;
|
|
@@ -6212,13 +6412,8 @@ function walkCursor(cursor, options) {
|
|
|
6212
6412
|
return;
|
|
6213
6413
|
}
|
|
6214
6414
|
// Check time budget (only for DOM, not SSR)
|
|
6215
|
-
if (
|
|
6216
|
-
|
|
6217
|
-
if (elapsed >= timeBudget) {
|
|
6218
|
-
// Schedule continuation as macrotask to actually yield to browser
|
|
6219
|
-
scheduleYield();
|
|
6220
|
-
return;
|
|
6221
|
-
}
|
|
6415
|
+
if (performance.now() >= until) {
|
|
6416
|
+
return true;
|
|
6222
6417
|
}
|
|
6223
6418
|
}
|
|
6224
6419
|
isDev &&
|
|
@@ -6835,6 +7030,7 @@ const vnode_newText = (textNode, textContent) => {
|
|
|
6835
7030
|
isDev && assertFalse(vnode_isVirtualVNode(vnode), 'Incorrect format of TextVNode.');
|
|
6836
7031
|
return vnode;
|
|
6837
7032
|
};
|
|
7033
|
+
/** @internal */
|
|
6838
7034
|
const vnode_newVirtual = () => {
|
|
6839
7035
|
const vnode = new VirtualVNode(null, 2 /* VNodeFlags.Virtual */ | (-1 << 12 /* VNodeFlagsIndex.shift */), // Flags
|
|
6840
7036
|
null, null, null, null, null, null);
|
|
@@ -6847,6 +7043,7 @@ const vnode_newVirtual = () => {
|
|
|
6847
7043
|
const vnode_isVNode = (vNode) => {
|
|
6848
7044
|
return vNode instanceof VNode;
|
|
6849
7045
|
};
|
|
7046
|
+
/** @internal */
|
|
6850
7047
|
const vnode_isElementVNode = (vNode) => {
|
|
6851
7048
|
return (vNode.flags & 1 /* VNodeFlags.Element */) === 1 /* VNodeFlags.Element */;
|
|
6852
7049
|
};
|
|
@@ -6905,6 +7102,7 @@ const vnode_getNodeTypeName = (vNode) => {
|
|
|
6905
7102
|
}
|
|
6906
7103
|
return '<unknown>';
|
|
6907
7104
|
};
|
|
7105
|
+
/** @internal */
|
|
6908
7106
|
const vnode_getProp = (vNode, key, getObject) => {
|
|
6909
7107
|
if (vnode_isElementVNode(vNode) || vnode_isVirtualVNode(vNode)) {
|
|
6910
7108
|
const value = vNode.props?.[key] ?? null;
|
|
@@ -6917,6 +7115,7 @@ const vnode_getProp = (vNode, key, getObject) => {
|
|
|
6917
7115
|
}
|
|
6918
7116
|
return null;
|
|
6919
7117
|
};
|
|
7118
|
+
/** @internal */
|
|
6920
7119
|
const vnode_setProp = (vNode, key, value) => {
|
|
6921
7120
|
if (value == null && vNode.props) {
|
|
6922
7121
|
delete vNode.props[key];
|
|
@@ -7308,6 +7507,7 @@ const vnode_getChildWithIdx = (vNode, childIdx) => {
|
|
|
7308
7507
|
return child;
|
|
7309
7508
|
};
|
|
7310
7509
|
const vNodeStack = [];
|
|
7510
|
+
/** @internal */
|
|
7311
7511
|
const vnode_getVNodeForChildNode = (vNode, childElement) => {
|
|
7312
7512
|
ensureElementVNode(vNode);
|
|
7313
7513
|
let child = vnode_getFirstChild(vNode);
|
|
@@ -7621,6 +7821,7 @@ const vnode_inflateProjectionTrailingText = (journal, projection) => {
|
|
|
7621
7821
|
vnode_ensureTextInflated(journal, last);
|
|
7622
7822
|
}
|
|
7623
7823
|
};
|
|
7824
|
+
/** @internal */
|
|
7624
7825
|
const vnode_insertBefore = (journal, parent, newChild, insertBefore) => {
|
|
7625
7826
|
if (vnode_isElementOrTextVNode(newChild)) {
|
|
7626
7827
|
vnode_insertElementBefore(journal, parent, newChild, insertBefore);
|
|
@@ -7644,6 +7845,7 @@ const vnode_getDomParentVNode = (vnode, includeProjection) => {
|
|
|
7644
7845
|
}
|
|
7645
7846
|
return vnode;
|
|
7646
7847
|
};
|
|
7848
|
+
/** @internal */
|
|
7647
7849
|
const vnode_remove = (journal, vParent, vToRemove, removeDOM) => {
|
|
7648
7850
|
isDev && assertEqual(vParent, vToRemove.parent, 'Parent mismatch.');
|
|
7649
7851
|
if (vnode_isTextVNode(vToRemove)) {
|
|
@@ -7712,6 +7914,7 @@ const vnode_truncate = (journal, vParent, vDelete, removeDOM = true) => {
|
|
|
7712
7914
|
vParent.lastChild = vPrevious;
|
|
7713
7915
|
};
|
|
7714
7916
|
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
7917
|
+
/** @internal */
|
|
7715
7918
|
const vnode_getElementName = (vnode) => {
|
|
7716
7919
|
const elementVNode = ensureElementVNode(vnode);
|
|
7717
7920
|
let elementName = elementVNode.elementName;
|
|
@@ -9115,6 +9318,95 @@ function getEffects(target, prop, storeEffects) {
|
|
|
9115
9318
|
return effectsToTrigger;
|
|
9116
9319
|
}
|
|
9117
9320
|
|
|
9321
|
+
/** Used to represent an undefined value that must be serialized */
|
|
9322
|
+
const explicitUndefined = Symbol('undefined');
|
|
9323
|
+
// Used for allocate, make sure they are in sync with Constants
|
|
9324
|
+
const _constants = [
|
|
9325
|
+
undefined,
|
|
9326
|
+
null,
|
|
9327
|
+
true,
|
|
9328
|
+
false,
|
|
9329
|
+
'',
|
|
9330
|
+
EMPTY_ARRAY,
|
|
9331
|
+
EMPTY_OBJ,
|
|
9332
|
+
NEEDS_COMPUTATION,
|
|
9333
|
+
STORE_ALL_PROPS,
|
|
9334
|
+
_UNINITIALIZED,
|
|
9335
|
+
Slot,
|
|
9336
|
+
Fragment,
|
|
9337
|
+
NaN,
|
|
9338
|
+
Infinity,
|
|
9339
|
+
-Infinity,
|
|
9340
|
+
Number.MAX_SAFE_INTEGER,
|
|
9341
|
+
Number.MAX_SAFE_INTEGER - 1,
|
|
9342
|
+
Number.MIN_SAFE_INTEGER,
|
|
9343
|
+
];
|
|
9344
|
+
// Used for dumpState, make sure they are in sync with Constants
|
|
9345
|
+
const _constantNames = [
|
|
9346
|
+
'undefined',
|
|
9347
|
+
'null',
|
|
9348
|
+
'true',
|
|
9349
|
+
'false',
|
|
9350
|
+
"''",
|
|
9351
|
+
'EMPTY_ARRAY',
|
|
9352
|
+
'EMPTY_OBJ',
|
|
9353
|
+
'NEEDS_COMPUTATION',
|
|
9354
|
+
'STORE_ALL_PROPS',
|
|
9355
|
+
'_UNINITIALIZED',
|
|
9356
|
+
'Slot',
|
|
9357
|
+
'Fragment',
|
|
9358
|
+
'NaN',
|
|
9359
|
+
'Infinity',
|
|
9360
|
+
'-Infinity',
|
|
9361
|
+
'MAX_SAFE_INTEGER',
|
|
9362
|
+
'MAX_SAFE_INTEGER-1',
|
|
9363
|
+
'MIN_SAFE_INTEGER',
|
|
9364
|
+
];
|
|
9365
|
+
// Used for dumpState, make sure they are in sync with TypeIds
|
|
9366
|
+
const _typeIdNames = [
|
|
9367
|
+
'Plain',
|
|
9368
|
+
'RootRef',
|
|
9369
|
+
'ForwardRef',
|
|
9370
|
+
'Constant',
|
|
9371
|
+
'Array',
|
|
9372
|
+
'Object',
|
|
9373
|
+
'URL',
|
|
9374
|
+
'Date',
|
|
9375
|
+
'Regex',
|
|
9376
|
+
'QRL',
|
|
9377
|
+
'VNode',
|
|
9378
|
+
'RefVNode',
|
|
9379
|
+
'BigInt',
|
|
9380
|
+
'URLSearchParams',
|
|
9381
|
+
'ForwardRefs',
|
|
9382
|
+
'TemporalDuration',
|
|
9383
|
+
'TemporalInstant',
|
|
9384
|
+
'TemporalPlainDate',
|
|
9385
|
+
'TemporalPlainDateTime',
|
|
9386
|
+
'TemporalPlainMonthDay',
|
|
9387
|
+
'TemporalPlainTime',
|
|
9388
|
+
'TemporalPlainYearMonth',
|
|
9389
|
+
'TemporalZonedDateTime',
|
|
9390
|
+
'Error',
|
|
9391
|
+
'Promise',
|
|
9392
|
+
'Set',
|
|
9393
|
+
'Map',
|
|
9394
|
+
'Uint8Array',
|
|
9395
|
+
'Task',
|
|
9396
|
+
'Component',
|
|
9397
|
+
'Signal',
|
|
9398
|
+
'WrappedSignal',
|
|
9399
|
+
'ComputedSignal',
|
|
9400
|
+
'AsyncSignal',
|
|
9401
|
+
'SerializerSignal',
|
|
9402
|
+
'Store',
|
|
9403
|
+
'FormData',
|
|
9404
|
+
'JSXNode',
|
|
9405
|
+
'PropsProxy',
|
|
9406
|
+
'SubscriptionData',
|
|
9407
|
+
'EffectSubscription',
|
|
9408
|
+
];
|
|
9409
|
+
|
|
9118
9410
|
function qrlToString(serializationContext, qrl, raw) {
|
|
9119
9411
|
let symbol = qrl.$symbol$;
|
|
9120
9412
|
let chunk = qrl.$chunk$;
|
|
@@ -9211,6 +9503,8 @@ class Serializer {
|
|
|
9211
9503
|
$parent$;
|
|
9212
9504
|
$qrlMap$ = new Map();
|
|
9213
9505
|
$writer$;
|
|
9506
|
+
/** We need to determine this at runtime because polyfills may not be loaded a module load time */
|
|
9507
|
+
$hasTemporal$ = typeof Temporal !== 'undefined';
|
|
9214
9508
|
constructor($serializationContext$) {
|
|
9215
9509
|
this.$serializationContext$ = $serializationContext$;
|
|
9216
9510
|
this.$writer$ = $serializationContext$.$writer$;
|
|
@@ -9254,6 +9548,29 @@ class Serializer {
|
|
|
9254
9548
|
}
|
|
9255
9549
|
return false;
|
|
9256
9550
|
}
|
|
9551
|
+
maybeNumericObjectKey$(key) {
|
|
9552
|
+
if (key.length === 0 || key.length >= 8) {
|
|
9553
|
+
return key;
|
|
9554
|
+
}
|
|
9555
|
+
let i = 0;
|
|
9556
|
+
if (key.charCodeAt(0) === 45) {
|
|
9557
|
+
if (key.length === 1) {
|
|
9558
|
+
return key;
|
|
9559
|
+
}
|
|
9560
|
+
i = 1;
|
|
9561
|
+
}
|
|
9562
|
+
const first = key.charCodeAt(i);
|
|
9563
|
+
if (first < 49 || first > 57) {
|
|
9564
|
+
return key;
|
|
9565
|
+
}
|
|
9566
|
+
for (i++; i < key.length; i++) {
|
|
9567
|
+
const c = key.charCodeAt(i);
|
|
9568
|
+
if (c < 48 || c > 57) {
|
|
9569
|
+
return key;
|
|
9570
|
+
}
|
|
9571
|
+
}
|
|
9572
|
+
return Number(key);
|
|
9573
|
+
}
|
|
9257
9574
|
/** Output a type,value pair. If the value is an array, it calls writeValue on each item. */
|
|
9258
9575
|
output(type, value, keepUndefined) {
|
|
9259
9576
|
if (typeof value === 'number') {
|
|
@@ -9381,6 +9698,9 @@ class Serializer {
|
|
|
9381
9698
|
else if (value === _UNINITIALIZED) {
|
|
9382
9699
|
this.output(3 /* TypeIds.Constant */, 9 /* Constants.UNINITIALIZED */);
|
|
9383
9700
|
}
|
|
9701
|
+
else if (value === explicitUndefined) {
|
|
9702
|
+
this.output(3 /* TypeIds.Constant */, 0 /* Constants.Undefined */);
|
|
9703
|
+
}
|
|
9384
9704
|
break;
|
|
9385
9705
|
case 'function':
|
|
9386
9706
|
if (value === Slot) {
|
|
@@ -9418,7 +9738,7 @@ class Serializer {
|
|
|
9418
9738
|
else if (isQwikComponent(value)) {
|
|
9419
9739
|
const [qrl] = value[SERIALIZABLE_STATE];
|
|
9420
9740
|
this.$serializationContext$.$renderSymbols$.add(qrl.$symbol$);
|
|
9421
|
-
this.output(
|
|
9741
|
+
this.output(29 /* TypeIds.Component */, [qrl]);
|
|
9422
9742
|
}
|
|
9423
9743
|
else {
|
|
9424
9744
|
throw qError(34 /* QError.serializeErrorCannotSerializeFunction */, [value.toString()]);
|
|
@@ -9456,7 +9776,7 @@ class Serializer {
|
|
|
9456
9776
|
writeObjectValue(value) {
|
|
9457
9777
|
if (isPropsProxy(value)) {
|
|
9458
9778
|
const owner = value[_OWNER];
|
|
9459
|
-
this.output(
|
|
9779
|
+
this.output(38 /* TypeIds.PropsProxy */, [
|
|
9460
9780
|
_serializationWeakRef(owner),
|
|
9461
9781
|
owner.varProps,
|
|
9462
9782
|
owner.constProps,
|
|
@@ -9464,13 +9784,15 @@ class Serializer {
|
|
|
9464
9784
|
]);
|
|
9465
9785
|
}
|
|
9466
9786
|
else if (value instanceof SubscriptionData) {
|
|
9467
|
-
|
|
9787
|
+
// TODO make everything optional or use two types
|
|
9788
|
+
this.output(39 /* TypeIds.SubscriptionData */, [
|
|
9468
9789
|
value.data.$scopedStyleIdPrefix$,
|
|
9469
9790
|
value.data.$isConst$,
|
|
9470
9791
|
]);
|
|
9471
9792
|
}
|
|
9472
9793
|
else if (value instanceof EffectSubscription) {
|
|
9473
|
-
|
|
9794
|
+
// TODO no data if [null, true]
|
|
9795
|
+
this.output(40 /* TypeIds.EffectSubscription */, [value.consumer, value.property, value.data]);
|
|
9474
9796
|
}
|
|
9475
9797
|
else if (isStore(value)) {
|
|
9476
9798
|
const storeHandler = getStoreHandler(value);
|
|
@@ -9490,13 +9812,13 @@ class Serializer {
|
|
|
9490
9812
|
while (out[out.length - 1] === undefined) {
|
|
9491
9813
|
out.pop();
|
|
9492
9814
|
}
|
|
9493
|
-
this.output(
|
|
9815
|
+
this.output(35 /* TypeIds.Store */, out);
|
|
9494
9816
|
}
|
|
9495
9817
|
else if (isSerializerObj(value)) {
|
|
9496
9818
|
const result = value[SerializerSymbol](value);
|
|
9497
9819
|
if (isPromise(result)) {
|
|
9498
9820
|
const forwardRef = this.resolvePromise(result, (resolved, resolvedValue) => {
|
|
9499
|
-
return new PromiseResult(
|
|
9821
|
+
return new PromiseResult(34 /* TypeIds.SerializerSignal */, resolved, resolvedValue, undefined, undefined);
|
|
9500
9822
|
});
|
|
9501
9823
|
this.output(2 /* TypeIds.ForwardRef */, forwardRef);
|
|
9502
9824
|
}
|
|
@@ -9517,7 +9839,7 @@ class Serializer {
|
|
|
9517
9839
|
if (Object.prototype.hasOwnProperty.call(value, key)) {
|
|
9518
9840
|
const subVal = value[key];
|
|
9519
9841
|
if (!fastSkipSerialize(subVal)) {
|
|
9520
|
-
out.push(key, subVal);
|
|
9842
|
+
out.push(this.maybeNumericObjectKey$(key), subVal);
|
|
9521
9843
|
}
|
|
9522
9844
|
}
|
|
9523
9845
|
}
|
|
@@ -9533,17 +9855,17 @@ class Serializer {
|
|
|
9533
9855
|
const maybeValue = getCustomSerializerPromise(value, value.$untrackedValue$);
|
|
9534
9856
|
if (isPromise(maybeValue)) {
|
|
9535
9857
|
const forwardRefId = this.resolvePromise(maybeValue, (resolved, resolvedValue) => {
|
|
9536
|
-
return new PromiseResult(
|
|
9858
|
+
return new PromiseResult(34 /* TypeIds.SerializerSignal */, resolved, resolvedValue, value.$effects$, value.$computeQrl$);
|
|
9537
9859
|
});
|
|
9538
9860
|
this.output(2 /* TypeIds.ForwardRef */, forwardRefId);
|
|
9539
9861
|
}
|
|
9540
9862
|
else {
|
|
9541
|
-
this.output(
|
|
9863
|
+
this.output(34 /* TypeIds.SerializerSignal */, [value.$computeQrl$, value.$effects$, maybeValue]);
|
|
9542
9864
|
}
|
|
9543
9865
|
return;
|
|
9544
9866
|
}
|
|
9545
9867
|
if (value instanceof WrappedSignalImpl) {
|
|
9546
|
-
this.output(
|
|
9868
|
+
this.output(31 /* TypeIds.WrappedSignal */, [
|
|
9547
9869
|
...serializeWrappingFn(this.$serializationContext$, value),
|
|
9548
9870
|
value.$flags$,
|
|
9549
9871
|
value.$hostElement$,
|
|
@@ -9557,7 +9879,7 @@ class Serializer {
|
|
|
9557
9879
|
const isInvalid = value.$flags$ & 1 /* SignalFlags.INVALID */;
|
|
9558
9880
|
const isSkippable = fastSkipSerialize(value.$untrackedValue$);
|
|
9559
9881
|
const isAsync = value instanceof AsyncSignalImpl;
|
|
9560
|
-
const
|
|
9882
|
+
const expires = isAsync && value.$expires$ !== 0 ? value.$expires$ : undefined;
|
|
9561
9883
|
const concurrency = isAsync && value.$concurrency$ !== 1 ? value.$concurrency$ : undefined;
|
|
9562
9884
|
const timeout = isAsync && value.$timeoutMs$ !== 0 ? value.$timeoutMs$ : undefined;
|
|
9563
9885
|
// Send the flags but remove the serialization bits and default to 0 when undefined
|
|
@@ -9578,36 +9900,31 @@ class Serializer {
|
|
|
9578
9900
|
out.push(value.$loadingEffects$, value.$errorEffects$, value.$untrackedError$);
|
|
9579
9901
|
out.push(asyncFlags || undefined);
|
|
9580
9902
|
}
|
|
9581
|
-
let keepUndefined = false;
|
|
9582
9903
|
if (v !== NEEDS_COMPUTATION ||
|
|
9583
|
-
|
|
9904
|
+
expires !== undefined ||
|
|
9584
9905
|
concurrency !== undefined ||
|
|
9585
9906
|
timeout !== undefined) {
|
|
9586
|
-
|
|
9587
|
-
|
|
9588
|
-
|
|
9589
|
-
|
|
9590
|
-
|
|
9591
|
-
|
|
9592
|
-
*/
|
|
9593
|
-
keepUndefined = true;
|
|
9594
|
-
}
|
|
9907
|
+
/**
|
|
9908
|
+
* If value is undefined, we need to keep it in the output. If we don't do that, later
|
|
9909
|
+
* during resuming, the value will be set to symbol(invalid) with flag invalid, and thats
|
|
9910
|
+
* is incorrect.
|
|
9911
|
+
*/
|
|
9912
|
+
out.push(v === undefined ? explicitUndefined : v);
|
|
9595
9913
|
}
|
|
9596
9914
|
if (isAsync) {
|
|
9597
|
-
out.push(
|
|
9915
|
+
out.push(expires);
|
|
9598
9916
|
out.push(concurrency);
|
|
9599
9917
|
out.push(timeout);
|
|
9600
9918
|
}
|
|
9601
|
-
this.output(isAsync ?
|
|
9919
|
+
this.output(isAsync ? 33 /* TypeIds.AsyncSignal */ : 32 /* TypeIds.ComputedSignal */, out);
|
|
9602
9920
|
}
|
|
9603
9921
|
else {
|
|
9604
9922
|
const v = value.$untrackedValue$;
|
|
9605
|
-
const
|
|
9606
|
-
const out = [v];
|
|
9923
|
+
const out = [v === undefined ? explicitUndefined : v];
|
|
9607
9924
|
if (value.$effects$) {
|
|
9608
9925
|
out.push(...value.$effects$);
|
|
9609
9926
|
}
|
|
9610
|
-
this.output(
|
|
9927
|
+
this.output(30 /* TypeIds.Signal */, out);
|
|
9611
9928
|
}
|
|
9612
9929
|
}
|
|
9613
9930
|
else if (value instanceof URL) {
|
|
@@ -9616,6 +9933,30 @@ class Serializer {
|
|
|
9616
9933
|
else if (value instanceof Date) {
|
|
9617
9934
|
this.output(7 /* TypeIds.Date */, Number.isNaN(value.valueOf()) ? '' : value.valueOf());
|
|
9618
9935
|
}
|
|
9936
|
+
else if (this.$hasTemporal$ && value instanceof Temporal.Duration) {
|
|
9937
|
+
this.output(15 /* TypeIds.TemporalDuration */, value.toJSON());
|
|
9938
|
+
}
|
|
9939
|
+
else if (this.$hasTemporal$ && value instanceof Temporal.Instant) {
|
|
9940
|
+
this.output(16 /* TypeIds.TemporalInstant */, value.toJSON());
|
|
9941
|
+
}
|
|
9942
|
+
else if (this.$hasTemporal$ && value instanceof Temporal.PlainDate) {
|
|
9943
|
+
this.output(17 /* TypeIds.TemporalPlainDate */, value.toJSON());
|
|
9944
|
+
}
|
|
9945
|
+
else if (this.$hasTemporal$ && value instanceof Temporal.PlainDateTime) {
|
|
9946
|
+
this.output(18 /* TypeIds.TemporalPlainDateTime */, value.toJSON());
|
|
9947
|
+
}
|
|
9948
|
+
else if (this.$hasTemporal$ && value instanceof Temporal.PlainMonthDay) {
|
|
9949
|
+
this.output(19 /* TypeIds.TemporalPlainMonthDay */, value.toJSON());
|
|
9950
|
+
}
|
|
9951
|
+
else if (this.$hasTemporal$ && value instanceof Temporal.PlainTime) {
|
|
9952
|
+
this.output(20 /* TypeIds.TemporalPlainTime */, value.toJSON());
|
|
9953
|
+
}
|
|
9954
|
+
else if (this.$hasTemporal$ && value instanceof Temporal.PlainYearMonth) {
|
|
9955
|
+
this.output(21 /* TypeIds.TemporalPlainYearMonth */, value.toJSON());
|
|
9956
|
+
}
|
|
9957
|
+
else if (this.$hasTemporal$ && value instanceof Temporal.ZonedDateTime) {
|
|
9958
|
+
this.output(22 /* TypeIds.TemporalZonedDateTime */, value.toJSON());
|
|
9959
|
+
}
|
|
9619
9960
|
else if (value instanceof RegExp) {
|
|
9620
9961
|
this.output(8 /* TypeIds.Regex */, value.toString());
|
|
9621
9962
|
}
|
|
@@ -9627,7 +9968,7 @@ class Serializer {
|
|
|
9627
9968
|
if (isDev) {
|
|
9628
9969
|
out.push('stack', value.stack);
|
|
9629
9970
|
}
|
|
9630
|
-
this.output(
|
|
9971
|
+
this.output(23 /* TypeIds.Error */, out);
|
|
9631
9972
|
}
|
|
9632
9973
|
else if (this.$serializationContext$.$isSsrNode$(value)) {
|
|
9633
9974
|
const rootIndex = this.$serializationContext$.$addRoot$(value);
|
|
@@ -9659,20 +10000,20 @@ class Serializer {
|
|
|
9659
10000
|
array.push(k, v);
|
|
9660
10001
|
}
|
|
9661
10002
|
}
|
|
9662
|
-
this.output(
|
|
10003
|
+
this.output(36 /* TypeIds.FormData */, array);
|
|
9663
10004
|
}
|
|
9664
10005
|
else if (value instanceof URLSearchParams) {
|
|
9665
10006
|
this.output(13 /* TypeIds.URLSearchParams */, value.toString());
|
|
9666
10007
|
}
|
|
9667
10008
|
else if (value instanceof Set) {
|
|
9668
|
-
this.output(
|
|
10009
|
+
this.output(25 /* TypeIds.Set */, [...value.values()]);
|
|
9669
10010
|
}
|
|
9670
10011
|
else if (value instanceof Map) {
|
|
9671
10012
|
const combined = [];
|
|
9672
10013
|
for (const [k, v] of value.entries()) {
|
|
9673
10014
|
combined.push(k, v);
|
|
9674
10015
|
}
|
|
9675
|
-
this.output(
|
|
10016
|
+
this.output(26 /* TypeIds.Map */, combined);
|
|
9676
10017
|
}
|
|
9677
10018
|
else if (isJSXNode(value)) {
|
|
9678
10019
|
const out = [
|
|
@@ -9686,25 +10027,25 @@ class Serializer {
|
|
|
9686
10027
|
while (out[out.length - 1] === undefined) {
|
|
9687
10028
|
out.pop();
|
|
9688
10029
|
}
|
|
9689
|
-
this.output(
|
|
10030
|
+
this.output(37 /* TypeIds.JSXNode */, out);
|
|
9690
10031
|
}
|
|
9691
10032
|
else if (value instanceof Task) {
|
|
9692
10033
|
const out = [value.$qrl$, value.$flags$, value.$index$, value.$el$, value.$state$];
|
|
9693
10034
|
while (out[out.length - 1] === undefined) {
|
|
9694
10035
|
out.pop();
|
|
9695
10036
|
}
|
|
9696
|
-
this.output(
|
|
10037
|
+
this.output(28 /* TypeIds.Task */, out);
|
|
9697
10038
|
}
|
|
9698
10039
|
else if (isPromise(value)) {
|
|
9699
10040
|
const forwardRefId = this.resolvePromise(value, (resolved, resolvedValue) => {
|
|
9700
|
-
return new PromiseResult(
|
|
10041
|
+
return new PromiseResult(24 /* TypeIds.Promise */, resolved, resolvedValue);
|
|
9701
10042
|
});
|
|
9702
10043
|
this.output(2 /* TypeIds.ForwardRef */, forwardRefId);
|
|
9703
10044
|
}
|
|
9704
10045
|
else if (value instanceof PromiseResult) {
|
|
9705
|
-
if (value.$type$ ===
|
|
10046
|
+
if (value.$type$ === 34 /* TypeIds.SerializerSignal */) {
|
|
9706
10047
|
if (value.$qrl$) {
|
|
9707
|
-
this.output(
|
|
10048
|
+
this.output(34 /* TypeIds.SerializerSignal */, [value.$qrl$, value.$effects$, value.$value$]);
|
|
9708
10049
|
}
|
|
9709
10050
|
else if (value.$resolved$) {
|
|
9710
10051
|
// We replace ourselves with this value
|
|
@@ -9718,7 +10059,7 @@ class Serializer {
|
|
|
9718
10059
|
}
|
|
9719
10060
|
}
|
|
9720
10061
|
else {
|
|
9721
|
-
this.output(
|
|
10062
|
+
this.output(24 /* TypeIds.Promise */, [value.$resolved$, value.$value$]);
|
|
9722
10063
|
}
|
|
9723
10064
|
}
|
|
9724
10065
|
else if (value instanceof Uint8Array) {
|
|
@@ -9728,7 +10069,7 @@ class Serializer {
|
|
|
9728
10069
|
buf += String.fromCharCode(value[i]);
|
|
9729
10070
|
}
|
|
9730
10071
|
const out = btoa(buf).replace(/=+$/, '');
|
|
9731
|
-
this.output(
|
|
10072
|
+
this.output(27 /* TypeIds.Uint8Array */, out);
|
|
9732
10073
|
}
|
|
9733
10074
|
else if (value instanceof SerializationWeakRef) {
|
|
9734
10075
|
const obj = value.$obj$;
|
|
@@ -10046,7 +10387,9 @@ DomRefConstructor, symbolToChunkResolver, setProp, storeProxyMap, writer) => {
|
|
|
10046
10387
|
if (!writer) {
|
|
10047
10388
|
const buffer = [];
|
|
10048
10389
|
writer = {
|
|
10049
|
-
write: (text) =>
|
|
10390
|
+
write: (text) => {
|
|
10391
|
+
buffer.push(text);
|
|
10392
|
+
},
|
|
10050
10393
|
toString: () => buffer.join(''),
|
|
10051
10394
|
};
|
|
10052
10395
|
}
|
|
@@ -10056,6 +10399,7 @@ DomRefConstructor, symbolToChunkResolver, setProp, storeProxyMap, writer) => {
|
|
|
10056
10399
|
|
|
10057
10400
|
const getKeyVal = (value, key) => value[key];
|
|
10058
10401
|
const canSerialize = (value, seen = new WeakSet()) => {
|
|
10402
|
+
const hasTemporal = typeof Temporal !== 'undefined';
|
|
10059
10403
|
if (value == null ||
|
|
10060
10404
|
typeof value === 'string' ||
|
|
10061
10405
|
typeof value === 'number' ||
|
|
@@ -10118,6 +10462,30 @@ const canSerialize = (value, seen = new WeakSet()) => {
|
|
|
10118
10462
|
else if (value instanceof Date) {
|
|
10119
10463
|
return true;
|
|
10120
10464
|
}
|
|
10465
|
+
else if (hasTemporal && value instanceof Temporal.Duration) {
|
|
10466
|
+
return true;
|
|
10467
|
+
}
|
|
10468
|
+
else if (hasTemporal && value instanceof Temporal.Instant) {
|
|
10469
|
+
return true;
|
|
10470
|
+
}
|
|
10471
|
+
else if (hasTemporal && value instanceof Temporal.PlainDate) {
|
|
10472
|
+
return true;
|
|
10473
|
+
}
|
|
10474
|
+
else if (hasTemporal && value instanceof Temporal.PlainDateTime) {
|
|
10475
|
+
return true;
|
|
10476
|
+
}
|
|
10477
|
+
else if (hasTemporal && value instanceof Temporal.PlainMonthDay) {
|
|
10478
|
+
return true;
|
|
10479
|
+
}
|
|
10480
|
+
else if (hasTemporal && value instanceof Temporal.PlainTime) {
|
|
10481
|
+
return true;
|
|
10482
|
+
}
|
|
10483
|
+
else if (hasTemporal && value instanceof Temporal.PlainYearMonth) {
|
|
10484
|
+
return true;
|
|
10485
|
+
}
|
|
10486
|
+
else if (hasTemporal && value instanceof Temporal.ZonedDateTime) {
|
|
10487
|
+
return true;
|
|
10488
|
+
}
|
|
10121
10489
|
else if (value instanceof RegExp) {
|
|
10122
10490
|
return true;
|
|
10123
10491
|
}
|
|
@@ -10154,85 +10522,6 @@ const canSerialize = (value, seen = new WeakSet()) => {
|
|
|
10154
10522
|
return false;
|
|
10155
10523
|
};
|
|
10156
10524
|
|
|
10157
|
-
// Used for allocate, make sure they are in sync with Constants
|
|
10158
|
-
const _constants = [
|
|
10159
|
-
undefined,
|
|
10160
|
-
null,
|
|
10161
|
-
true,
|
|
10162
|
-
false,
|
|
10163
|
-
'',
|
|
10164
|
-
EMPTY_ARRAY,
|
|
10165
|
-
EMPTY_OBJ,
|
|
10166
|
-
NEEDS_COMPUTATION,
|
|
10167
|
-
STORE_ALL_PROPS,
|
|
10168
|
-
_UNINITIALIZED,
|
|
10169
|
-
Slot,
|
|
10170
|
-
Fragment,
|
|
10171
|
-
NaN,
|
|
10172
|
-
Infinity,
|
|
10173
|
-
-Infinity,
|
|
10174
|
-
Number.MAX_SAFE_INTEGER,
|
|
10175
|
-
Number.MAX_SAFE_INTEGER - 1,
|
|
10176
|
-
Number.MIN_SAFE_INTEGER,
|
|
10177
|
-
];
|
|
10178
|
-
// Used for dumpState, make sure they are in sync with Constants
|
|
10179
|
-
const _constantNames = [
|
|
10180
|
-
'undefined',
|
|
10181
|
-
'null',
|
|
10182
|
-
'true',
|
|
10183
|
-
'false',
|
|
10184
|
-
"''",
|
|
10185
|
-
'EMPTY_ARRAY',
|
|
10186
|
-
'EMPTY_OBJ',
|
|
10187
|
-
'NEEDS_COMPUTATION',
|
|
10188
|
-
'STORE_ALL_PROPS',
|
|
10189
|
-
'_UNINITIALIZED',
|
|
10190
|
-
'Slot',
|
|
10191
|
-
'Fragment',
|
|
10192
|
-
'NaN',
|
|
10193
|
-
'Infinity',
|
|
10194
|
-
'-Infinity',
|
|
10195
|
-
'MAX_SAFE_INTEGER',
|
|
10196
|
-
'MAX_SAFE_INTEGER-1',
|
|
10197
|
-
'MIN_SAFE_INTEGER',
|
|
10198
|
-
];
|
|
10199
|
-
// Used for dumpState, make sure they are in sync with TypeIds
|
|
10200
|
-
const _typeIdNames = [
|
|
10201
|
-
'Plain',
|
|
10202
|
-
'RootRef',
|
|
10203
|
-
'ForwardRef',
|
|
10204
|
-
'Constant',
|
|
10205
|
-
'Array',
|
|
10206
|
-
'Object',
|
|
10207
|
-
'URL',
|
|
10208
|
-
'Date',
|
|
10209
|
-
'Regex',
|
|
10210
|
-
'QRL',
|
|
10211
|
-
'VNode',
|
|
10212
|
-
'RefVNode',
|
|
10213
|
-
'BigInt',
|
|
10214
|
-
'URLSearchParams',
|
|
10215
|
-
'ForwardRefs',
|
|
10216
|
-
'Error',
|
|
10217
|
-
'Promise',
|
|
10218
|
-
'Set',
|
|
10219
|
-
'Map',
|
|
10220
|
-
'Uint8Array',
|
|
10221
|
-
'Task',
|
|
10222
|
-
'Component',
|
|
10223
|
-
'Signal',
|
|
10224
|
-
'WrappedSignal',
|
|
10225
|
-
'ComputedSignal',
|
|
10226
|
-
'AsyncSignal',
|
|
10227
|
-
'SerializerSignal',
|
|
10228
|
-
'Store',
|
|
10229
|
-
'FormData',
|
|
10230
|
-
'JSXNode',
|
|
10231
|
-
'PropsProxy',
|
|
10232
|
-
'SubscriptionData',
|
|
10233
|
-
'EffectSubscription',
|
|
10234
|
-
];
|
|
10235
|
-
|
|
10236
10525
|
const circularProofJson = (obj, indent) => {
|
|
10237
10526
|
const seen = new WeakSet();
|
|
10238
10527
|
return JSON.stringify(obj, (_, value) => {
|
|
@@ -10445,30 +10734,46 @@ const allocate = (container, typeId, value) => {
|
|
|
10445
10734
|
}
|
|
10446
10735
|
return qrl;
|
|
10447
10736
|
}
|
|
10448
|
-
case
|
|
10737
|
+
case 28 /* TypeIds.Task */:
|
|
10449
10738
|
return new Task(-1, -1, null, null, null, null);
|
|
10450
10739
|
case 6 /* TypeIds.URL */:
|
|
10451
10740
|
return new URL(value);
|
|
10452
10741
|
case 7 /* TypeIds.Date */:
|
|
10453
10742
|
return new Date(value);
|
|
10743
|
+
case 15 /* TypeIds.TemporalDuration */:
|
|
10744
|
+
return Temporal.Duration.from(value);
|
|
10745
|
+
case 16 /* TypeIds.TemporalInstant */:
|
|
10746
|
+
return Temporal.Instant.from(value);
|
|
10747
|
+
case 17 /* TypeIds.TemporalPlainDate */:
|
|
10748
|
+
return Temporal.PlainDate.from(value);
|
|
10749
|
+
case 18 /* TypeIds.TemporalPlainDateTime */:
|
|
10750
|
+
return Temporal.PlainDateTime.from(value);
|
|
10751
|
+
case 19 /* TypeIds.TemporalPlainMonthDay */:
|
|
10752
|
+
return Temporal.PlainMonthDay.from(value);
|
|
10753
|
+
case 20 /* TypeIds.TemporalPlainTime */:
|
|
10754
|
+
return Temporal.PlainTime.from(value);
|
|
10755
|
+
case 21 /* TypeIds.TemporalPlainYearMonth */:
|
|
10756
|
+
return Temporal.PlainYearMonth.from(value);
|
|
10757
|
+
case 22 /* TypeIds.TemporalZonedDateTime */:
|
|
10758
|
+
return Temporal.ZonedDateTime.from(value);
|
|
10454
10759
|
case 8 /* TypeIds.Regex */:
|
|
10455
10760
|
const idx = value.lastIndexOf('/');
|
|
10456
10761
|
return new RegExp(value.slice(1, idx), value.slice(idx + 1));
|
|
10457
|
-
case
|
|
10762
|
+
case 23 /* TypeIds.Error */:
|
|
10458
10763
|
return new Error();
|
|
10459
|
-
case
|
|
10764
|
+
case 29 /* TypeIds.Component */:
|
|
10460
10765
|
return componentQrl(null);
|
|
10461
|
-
case
|
|
10766
|
+
case 30 /* TypeIds.Signal */:
|
|
10462
10767
|
return new SignalImpl(container, 0);
|
|
10463
|
-
case
|
|
10768
|
+
case 31 /* TypeIds.WrappedSignal */:
|
|
10464
10769
|
return new WrappedSignalImpl(container, null, null, null);
|
|
10465
|
-
case
|
|
10770
|
+
case 32 /* TypeIds.ComputedSignal */:
|
|
10466
10771
|
return new ComputedSignalImpl(container, null);
|
|
10467
|
-
case
|
|
10468
|
-
return new AsyncSignalImpl(container, null, undefined, {
|
|
10469
|
-
case
|
|
10772
|
+
case 33 /* TypeIds.AsyncSignal */:
|
|
10773
|
+
return new AsyncSignalImpl(container, null, undefined, {});
|
|
10774
|
+
case 34 /* TypeIds.SerializerSignal */:
|
|
10470
10775
|
return new SerializerSignalImpl(container, null);
|
|
10471
|
-
case
|
|
10776
|
+
case 35 /* TypeIds.Store */: {
|
|
10472
10777
|
const data = value;
|
|
10473
10778
|
// We need to allocate the store first, before we inflate its data, because the data can
|
|
10474
10779
|
// reference the store itself (circular)
|
|
@@ -10487,17 +10792,17 @@ const allocate = (container, typeId, value) => {
|
|
|
10487
10792
|
}
|
|
10488
10793
|
case 13 /* TypeIds.URLSearchParams */:
|
|
10489
10794
|
return new URLSearchParams(value);
|
|
10490
|
-
case
|
|
10795
|
+
case 36 /* TypeIds.FormData */:
|
|
10491
10796
|
return new FormData();
|
|
10492
|
-
case
|
|
10797
|
+
case 37 /* TypeIds.JSXNode */:
|
|
10493
10798
|
return new JSXNodeImpl(null, null, null, null, 0, null);
|
|
10494
10799
|
case 12 /* TypeIds.BigInt */:
|
|
10495
10800
|
return BigInt(value);
|
|
10496
|
-
case
|
|
10801
|
+
case 25 /* TypeIds.Set */:
|
|
10497
10802
|
return new Set();
|
|
10498
|
-
case
|
|
10803
|
+
case 26 /* TypeIds.Map */:
|
|
10499
10804
|
return new Map();
|
|
10500
|
-
case
|
|
10805
|
+
case 24 /* TypeIds.Promise */:
|
|
10501
10806
|
let resolve;
|
|
10502
10807
|
let reject;
|
|
10503
10808
|
const promise = new Promise((res, rej) => {
|
|
@@ -10508,13 +10813,13 @@ const allocate = (container, typeId, value) => {
|
|
|
10508
10813
|
// Don't leave unhandled promise rejections
|
|
10509
10814
|
promise.catch(() => { });
|
|
10510
10815
|
return promise;
|
|
10511
|
-
case
|
|
10816
|
+
case 27 /* TypeIds.Uint8Array */:
|
|
10512
10817
|
const encodedLength = value.length;
|
|
10513
10818
|
const blocks = encodedLength >>> 2;
|
|
10514
10819
|
const rest = encodedLength & 3;
|
|
10515
10820
|
const decodedLength = blocks * 3 + (rest ? rest - 1 : 0);
|
|
10516
10821
|
return new Uint8Array(decodedLength);
|
|
10517
|
-
case
|
|
10822
|
+
case 38 /* TypeIds.PropsProxy */:
|
|
10518
10823
|
return createPropsProxy(null);
|
|
10519
10824
|
case 10 /* TypeIds.VNode */:
|
|
10520
10825
|
return retrieveVNodeOrDocument(container, value);
|
|
@@ -10552,9 +10857,9 @@ const allocate = (container, typeId, value) => {
|
|
|
10552
10857
|
else {
|
|
10553
10858
|
throw qError(17 /* QError.serializeErrorExpectedVNode */, [typeof vNode]);
|
|
10554
10859
|
}
|
|
10555
|
-
case
|
|
10860
|
+
case 39 /* TypeIds.SubscriptionData */:
|
|
10556
10861
|
return new SubscriptionData({});
|
|
10557
|
-
case
|
|
10862
|
+
case 40 /* TypeIds.EffectSubscription */:
|
|
10558
10863
|
return new EffectSubscription(null, null, null, null);
|
|
10559
10864
|
default:
|
|
10560
10865
|
throw qError(18 /* QError.serializeErrorCannotAllocate */, [typeId]);
|
|
@@ -10737,23 +11042,31 @@ async function _walkJSX(ssr, value, options) {
|
|
|
10737
11042
|
const enqueue = (value) => stack.push(value);
|
|
10738
11043
|
const drain = async () => {
|
|
10739
11044
|
while (stack.length) {
|
|
10740
|
-
|
|
10741
|
-
|
|
10742
|
-
|
|
10743
|
-
|
|
10744
|
-
|
|
10745
|
-
|
|
10746
|
-
|
|
10747
|
-
if (typeof value === 'function') {
|
|
10748
|
-
if (value === Promise) {
|
|
10749
|
-
stack.push(await stack.pop());
|
|
11045
|
+
try {
|
|
11046
|
+
const value = stack.pop();
|
|
11047
|
+
// Reference equality first (no prototype walk), then typeof
|
|
11048
|
+
if (value === MaybeAsyncSignal) {
|
|
11049
|
+
const trackFn = stack.pop();
|
|
11050
|
+
await retryOnPromise(() => stack.push(trackFn()));
|
|
11051
|
+
continue;
|
|
10750
11052
|
}
|
|
10751
|
-
|
|
10752
|
-
|
|
11053
|
+
if (typeof value === 'function') {
|
|
11054
|
+
if (value === Promise) {
|
|
11055
|
+
stack.push(await stack.pop());
|
|
11056
|
+
}
|
|
11057
|
+
else {
|
|
11058
|
+
await value.apply(ssr);
|
|
11059
|
+
}
|
|
11060
|
+
continue;
|
|
11061
|
+
}
|
|
11062
|
+
processJSXNode(ssr, enqueue, value, options);
|
|
11063
|
+
}
|
|
11064
|
+
finally {
|
|
11065
|
+
const pendingFlush = ssr.streamHandler.waitForPendingFlush();
|
|
11066
|
+
if (isPromise(pendingFlush)) {
|
|
11067
|
+
await pendingFlush;
|
|
10753
11068
|
}
|
|
10754
|
-
continue;
|
|
10755
11069
|
}
|
|
10756
|
-
processJSXNode(ssr, enqueue, value, options);
|
|
10757
11070
|
}
|
|
10758
11071
|
};
|
|
10759
11072
|
await drain();
|
|
@@ -10801,7 +11114,7 @@ function processJSXNode(ssr, enqueue, value, options) {
|
|
|
10801
11114
|
currentStyleScoped: options.currentStyleScoped,
|
|
10802
11115
|
parentComponentFrame: options.parentComponentFrame,
|
|
10803
11116
|
});
|
|
10804
|
-
ssr.streamHandler.flush();
|
|
11117
|
+
await ssr.streamHandler.flush();
|
|
10805
11118
|
}
|
|
10806
11119
|
});
|
|
10807
11120
|
}
|
|
@@ -10898,7 +11211,7 @@ function processJSXNode(ssr, enqueue, value, options) {
|
|
|
10898
11211
|
currentStyleScoped: options.currentStyleScoped,
|
|
10899
11212
|
parentComponentFrame: options.parentComponentFrame,
|
|
10900
11213
|
});
|
|
10901
|
-
ssr.streamHandler.flush();
|
|
11214
|
+
await ssr.streamHandler.flush();
|
|
10902
11215
|
},
|
|
10903
11216
|
});
|
|
10904
11217
|
}
|
|
@@ -10964,10 +11277,11 @@ function maybeAddPollingAsyncSignalToEagerResume(serializationCtx, signal) {
|
|
|
10964
11277
|
// Unwrap if it's a WrappedSignalImpl
|
|
10965
11278
|
const unwrappedSignal = signal instanceof WrappedSignalImpl ? signal.$unwrapIfSignal$() : signal;
|
|
10966
11279
|
if (unwrappedSignal instanceof AsyncSignalImpl) {
|
|
10967
|
-
const
|
|
11280
|
+
const expires = unwrappedSignal.$expires$;
|
|
10968
11281
|
// Don't check for $effects$ here - effects are added later during tracking.
|
|
10969
11282
|
// The AsyncSignal's polling mechanism will check for effects before scheduling.
|
|
10970
|
-
|
|
11283
|
+
// Only eager-resume for polling signals, not stale-only ones.
|
|
11284
|
+
if (expires && !(unwrappedSignal.$flags$ & 256 /* AsyncSignalFlags.NO_POLL */)) {
|
|
10971
11285
|
serializationCtx.$addRoot$(unwrappedSignal);
|
|
10972
11286
|
serializationCtx.$eagerResume$.add(unwrappedSignal);
|
|
10973
11287
|
}
|
|
@@ -11195,8 +11509,8 @@ function addQwikEventToSerializationContext(serializationCtx, key, qrl) {
|
|
|
11195
11509
|
* @see `useOn`, `useOnWindow`, `useOnDocument`.
|
|
11196
11510
|
*/
|
|
11197
11511
|
// </docs>
|
|
11198
|
-
const useOn = (event, eventQrl) => {
|
|
11199
|
-
_useOn("q-e:" /* EventNameHtmlScope.on */, event, eventQrl);
|
|
11512
|
+
const useOn = (event, eventQrl, options) => {
|
|
11513
|
+
_useOn(options?.passive ? "q-ep:" /* EventNameHtmlScope.onPassive */ : "q-e:" /* EventNameHtmlScope.on */, event, eventQrl, options);
|
|
11200
11514
|
};
|
|
11201
11515
|
// <docs markdown="../readme.md#useOnDocument">
|
|
11202
11516
|
// !!DO NOT EDIT THIS COMMENT DIRECTLY!!!
|
|
@@ -11229,8 +11543,8 @@ const useOn = (event, eventQrl) => {
|
|
|
11229
11543
|
* ```
|
|
11230
11544
|
*/
|
|
11231
11545
|
// </docs>
|
|
11232
|
-
const useOnDocument = (event, eventQrl) => {
|
|
11233
|
-
_useOn("q-d:" /* EventNameHtmlScope.document */, event, eventQrl);
|
|
11546
|
+
const useOnDocument = (event, eventQrl, options) => {
|
|
11547
|
+
_useOn(options?.passive ? "q-dp:" /* EventNameHtmlScope.documentPassive */ : "q-d:" /* EventNameHtmlScope.document */, event, eventQrl, options);
|
|
11234
11548
|
};
|
|
11235
11549
|
// <docs markdown="../readme.md#useOnWindow">
|
|
11236
11550
|
// !!DO NOT EDIT THIS COMMENT DIRECTLY!!!
|
|
@@ -11264,10 +11578,10 @@ const useOnDocument = (event, eventQrl) => {
|
|
|
11264
11578
|
* ```
|
|
11265
11579
|
*/
|
|
11266
11580
|
// </docs>
|
|
11267
|
-
const useOnWindow = (event, eventQrl) => {
|
|
11268
|
-
_useOn("q-w:" /* EventNameHtmlScope.window */, event, eventQrl);
|
|
11581
|
+
const useOnWindow = (event, eventQrl, options) => {
|
|
11582
|
+
_useOn(options?.passive ? "q-wp:" /* EventNameHtmlScope.windowPassive */ : "q-w:" /* EventNameHtmlScope.window */, event, eventQrl, options);
|
|
11269
11583
|
};
|
|
11270
|
-
const _useOn = (prefix, eventName, eventQrl) => {
|
|
11584
|
+
const _useOn = (prefix, eventName, eventQrl, options) => {
|
|
11271
11585
|
const { isAdded, addEvent } = useOnEventsSequentialScope();
|
|
11272
11586
|
if (isAdded) {
|
|
11273
11587
|
return;
|
|
@@ -11276,11 +11590,11 @@ const _useOn = (prefix, eventName, eventQrl) => {
|
|
|
11276
11590
|
if (Array.isArray(eventName)) {
|
|
11277
11591
|
for (let i = 0; i < eventName.length; i++) {
|
|
11278
11592
|
const event = eventName[i];
|
|
11279
|
-
addEvent(prefix + fromCamelToKebabCase(event), eventQrl);
|
|
11593
|
+
addEvent(prefix + fromCamelToKebabCase(event), eventQrl, options);
|
|
11280
11594
|
}
|
|
11281
11595
|
}
|
|
11282
11596
|
else {
|
|
11283
|
-
addEvent(prefix + fromCamelToKebabCase(eventName), eventQrl);
|
|
11597
|
+
addEvent(prefix + fromCamelToKebabCase(eventName), eventQrl, options);
|
|
11284
11598
|
}
|
|
11285
11599
|
}
|
|
11286
11600
|
};
|
|
@@ -11317,13 +11631,27 @@ const useOnEventsSequentialScope = () => {
|
|
|
11317
11631
|
while (addedFlags.length <= seqIdx) {
|
|
11318
11632
|
addedFlags.push(false);
|
|
11319
11633
|
}
|
|
11320
|
-
const addEvent = (eventName, eventQrl) => {
|
|
11634
|
+
const addEvent = (eventName, eventQrl, options) => {
|
|
11321
11635
|
addedFlags[seqIdx] = true;
|
|
11322
|
-
let
|
|
11323
|
-
if (!
|
|
11324
|
-
onMap[eventName] =
|
|
11636
|
+
let event = onMap[eventName];
|
|
11637
|
+
if (!event) {
|
|
11638
|
+
onMap[eventName] = event = {
|
|
11639
|
+
qrls: [],
|
|
11640
|
+
capture: false,
|
|
11641
|
+
preventdefault: false,
|
|
11642
|
+
stoppropagation: false,
|
|
11643
|
+
};
|
|
11644
|
+
}
|
|
11645
|
+
event.qrls.push(eventQrl);
|
|
11646
|
+
if (options?.capture) {
|
|
11647
|
+
event.capture = true;
|
|
11648
|
+
}
|
|
11649
|
+
if (options?.preventdefault) {
|
|
11650
|
+
event.preventdefault = true;
|
|
11651
|
+
}
|
|
11652
|
+
if (options?.stoppropagation) {
|
|
11653
|
+
event.stoppropagation = true;
|
|
11325
11654
|
}
|
|
11326
|
-
events.push(eventQrl);
|
|
11327
11655
|
};
|
|
11328
11656
|
return {
|
|
11329
11657
|
isAdded: addedFlags[seqIdx],
|
|
@@ -11451,6 +11779,9 @@ const dangerousObjectKeys = new Set([
|
|
|
11451
11779
|
'then',
|
|
11452
11780
|
]);
|
|
11453
11781
|
const isSafeObjectKV = (key, value) => {
|
|
11782
|
+
if (typeof key === 'number') {
|
|
11783
|
+
return true;
|
|
11784
|
+
}
|
|
11454
11785
|
return (typeof key === 'string' &&
|
|
11455
11786
|
key !== '__proto__' &&
|
|
11456
11787
|
(typeof value !== 'function' || !dangerousObjectKeys.has(key)));
|
|
@@ -11483,7 +11814,7 @@ const inflate = (container, target, typeId, data) => {
|
|
|
11483
11814
|
target[key] = value;
|
|
11484
11815
|
}
|
|
11485
11816
|
break;
|
|
11486
|
-
case
|
|
11817
|
+
case 28 /* TypeIds.Task */:
|
|
11487
11818
|
const task = target;
|
|
11488
11819
|
const v = data;
|
|
11489
11820
|
task.$qrl$ = v[0];
|
|
@@ -11492,10 +11823,10 @@ const inflate = (container, target, typeId, data) => {
|
|
|
11492
11823
|
task.$el$ = v[3];
|
|
11493
11824
|
task.$state$ = v[4];
|
|
11494
11825
|
break;
|
|
11495
|
-
case
|
|
11826
|
+
case 29 /* TypeIds.Component */:
|
|
11496
11827
|
target[SERIALIZABLE_STATE][0] = data[0];
|
|
11497
11828
|
break;
|
|
11498
|
-
case
|
|
11829
|
+
case 35 /* TypeIds.Store */: {
|
|
11499
11830
|
// Inflate the store target
|
|
11500
11831
|
const store = unwrapStore(target);
|
|
11501
11832
|
const storeTarget = pendingStoreTargets.get(store);
|
|
@@ -11514,7 +11845,7 @@ const inflate = (container, target, typeId, data) => {
|
|
|
11514
11845
|
restoreEffectBackRefForEffectsMap(storeHandler.$effects$, store);
|
|
11515
11846
|
break;
|
|
11516
11847
|
}
|
|
11517
|
-
case
|
|
11848
|
+
case 30 /* TypeIds.Signal */: {
|
|
11518
11849
|
const signal = target;
|
|
11519
11850
|
const d = data;
|
|
11520
11851
|
signal.$untrackedValue$ = d[0];
|
|
@@ -11522,7 +11853,7 @@ const inflate = (container, target, typeId, data) => {
|
|
|
11522
11853
|
restoreEffectBackRefForEffects(signal.$effects$, signal);
|
|
11523
11854
|
break;
|
|
11524
11855
|
}
|
|
11525
|
-
case
|
|
11856
|
+
case 31 /* TypeIds.WrappedSignal */: {
|
|
11526
11857
|
const signal = target;
|
|
11527
11858
|
const d = data;
|
|
11528
11859
|
signal.$func$ = container.getSyncFn(d[0]);
|
|
@@ -11536,14 +11867,22 @@ const inflate = (container, target, typeId, data) => {
|
|
|
11536
11867
|
restoreEffectBackRefForEffects(signal.$effects$, signal);
|
|
11537
11868
|
break;
|
|
11538
11869
|
}
|
|
11539
|
-
case
|
|
11870
|
+
case 33 /* TypeIds.AsyncSignal */: {
|
|
11540
11871
|
const asyncSignal = target;
|
|
11541
11872
|
const d = data;
|
|
11542
11873
|
asyncSignal.$computeQrl$ = d[0];
|
|
11543
|
-
|
|
11544
|
-
|
|
11545
|
-
|
|
11546
|
-
|
|
11874
|
+
if (d[1]) {
|
|
11875
|
+
asyncSignal.$effects$ = new Set(d[1]);
|
|
11876
|
+
}
|
|
11877
|
+
if (d[2]) {
|
|
11878
|
+
asyncSignal.$loadingEffects$ = new Set(d[2]);
|
|
11879
|
+
}
|
|
11880
|
+
if (d[3]) {
|
|
11881
|
+
asyncSignal.$errorEffects$ = new Set(d[3]);
|
|
11882
|
+
}
|
|
11883
|
+
if (d[4]) {
|
|
11884
|
+
asyncSignal.$untrackedError$ = d[4];
|
|
11885
|
+
}
|
|
11547
11886
|
asyncSignal.$flags$ = d[5] ?? 0;
|
|
11548
11887
|
if (asyncSignal.$flags$ & 64 /* AsyncSignalFlags.CLIENT_ONLY */) {
|
|
11549
11888
|
// If it's client only, it was serialized because it pretended to be loading
|
|
@@ -11557,9 +11896,16 @@ const inflate = (container, target, typeId, data) => {
|
|
|
11557
11896
|
if (asyncSignal.$untrackedValue$ === NEEDS_COMPUTATION) {
|
|
11558
11897
|
asyncSignal.$flags$ |= 1 /* SignalFlags.INVALID */;
|
|
11559
11898
|
}
|
|
11560
|
-
//
|
|
11561
|
-
|
|
11562
|
-
asyncSignal
|
|
11899
|
+
// Handle old format (negative = no poll) and new format (always positive, flag in d[5])
|
|
11900
|
+
const rawExpires = (d[7] ?? 0);
|
|
11901
|
+
asyncSignal.expires = Math.abs(rawExpires);
|
|
11902
|
+
if (rawExpires < 0) {
|
|
11903
|
+
asyncSignal.$flags$ |= 256 /* AsyncSignalFlags.NO_POLL */;
|
|
11904
|
+
}
|
|
11905
|
+
if (d[8] !== undefined && d[8] !== 1) {
|
|
11906
|
+
asyncSignal.$concurrency$ = (d[8] ?? 1);
|
|
11907
|
+
asyncSignal.$jobs$ = [];
|
|
11908
|
+
}
|
|
11563
11909
|
asyncSignal.$timeoutMs$ = (d[9] ?? 0);
|
|
11564
11910
|
restoreEffectBackRefForEffects(asyncSignal.$effects$, asyncSignal);
|
|
11565
11911
|
restoreEffectBackRefForEffects(asyncSignal.$loadingEffects$, asyncSignal);
|
|
@@ -11567,8 +11913,8 @@ const inflate = (container, target, typeId, data) => {
|
|
|
11567
11913
|
break;
|
|
11568
11914
|
}
|
|
11569
11915
|
// Inflating a SerializerSignal is the same as inflating a ComputedSignal
|
|
11570
|
-
case
|
|
11571
|
-
case
|
|
11916
|
+
case 34 /* TypeIds.SerializerSignal */:
|
|
11917
|
+
case 32 /* TypeIds.ComputedSignal */: {
|
|
11572
11918
|
const computed = target;
|
|
11573
11919
|
const d = data;
|
|
11574
11920
|
computed.$computeQrl$ = d[0];
|
|
@@ -11588,7 +11934,7 @@ const inflate = (container, target, typeId, data) => {
|
|
|
11588
11934
|
if (hasValue) {
|
|
11589
11935
|
computed.$untrackedValue$ = d[2];
|
|
11590
11936
|
}
|
|
11591
|
-
if (typeId !==
|
|
11937
|
+
if (typeId !== 34 /* TypeIds.SerializerSignal */ && computed.$untrackedValue$ !== NEEDS_COMPUTATION) {
|
|
11592
11938
|
// If we have a value after SSR, it will always be mean the signal was not invalid
|
|
11593
11939
|
// The serialized signal is always left invalid so it can recreate the custom object
|
|
11594
11940
|
computed.$flags$ &= -2 /* SignalFlags.INVALID */;
|
|
@@ -11596,7 +11942,7 @@ const inflate = (container, target, typeId, data) => {
|
|
|
11596
11942
|
restoreEffectBackRefForEffects(computed.$effects$, computed);
|
|
11597
11943
|
break;
|
|
11598
11944
|
}
|
|
11599
|
-
case
|
|
11945
|
+
case 23 /* TypeIds.Error */: {
|
|
11600
11946
|
const d = data;
|
|
11601
11947
|
target.message = d[0];
|
|
11602
11948
|
for (let i = 1; i < d.length; i += 2) {
|
|
@@ -11604,7 +11950,7 @@ const inflate = (container, target, typeId, data) => {
|
|
|
11604
11950
|
}
|
|
11605
11951
|
break;
|
|
11606
11952
|
}
|
|
11607
|
-
case
|
|
11953
|
+
case 36 /* TypeIds.FormData */: {
|
|
11608
11954
|
const formData = target;
|
|
11609
11955
|
const d = data;
|
|
11610
11956
|
for (let i = 0; i < d.length; i++) {
|
|
@@ -11612,7 +11958,7 @@ const inflate = (container, target, typeId, data) => {
|
|
|
11612
11958
|
}
|
|
11613
11959
|
break;
|
|
11614
11960
|
}
|
|
11615
|
-
case
|
|
11961
|
+
case 37 /* TypeIds.JSXNode */: {
|
|
11616
11962
|
const jsx = target;
|
|
11617
11963
|
const [type, key, varProps, constProps, children, toSort] = data;
|
|
11618
11964
|
jsx.type = type;
|
|
@@ -11623,7 +11969,7 @@ const inflate = (container, target, typeId, data) => {
|
|
|
11623
11969
|
jsx.toSort = !!toSort;
|
|
11624
11970
|
break;
|
|
11625
11971
|
}
|
|
11626
|
-
case
|
|
11972
|
+
case 25 /* TypeIds.Set */: {
|
|
11627
11973
|
const set = target;
|
|
11628
11974
|
const d = data;
|
|
11629
11975
|
for (let i = 0; i < d.length; i++) {
|
|
@@ -11631,7 +11977,7 @@ const inflate = (container, target, typeId, data) => {
|
|
|
11631
11977
|
}
|
|
11632
11978
|
break;
|
|
11633
11979
|
}
|
|
11634
|
-
case
|
|
11980
|
+
case 26 /* TypeIds.Map */: {
|
|
11635
11981
|
const map = target;
|
|
11636
11982
|
const d = data;
|
|
11637
11983
|
for (let i = 0; i < d.length; i++) {
|
|
@@ -11639,7 +11985,7 @@ const inflate = (container, target, typeId, data) => {
|
|
|
11639
11985
|
}
|
|
11640
11986
|
break;
|
|
11641
11987
|
}
|
|
11642
|
-
case
|
|
11988
|
+
case 24 /* TypeIds.Promise */: {
|
|
11643
11989
|
const promise = target;
|
|
11644
11990
|
const [resolved, result] = data;
|
|
11645
11991
|
const [resolve, reject] = resolvers.get(promise);
|
|
@@ -11651,7 +11997,7 @@ const inflate = (container, target, typeId, data) => {
|
|
|
11651
11997
|
}
|
|
11652
11998
|
break;
|
|
11653
11999
|
}
|
|
11654
|
-
case
|
|
12000
|
+
case 27 /* TypeIds.Uint8Array */:
|
|
11655
12001
|
const bytes = target;
|
|
11656
12002
|
const buf = atob(data);
|
|
11657
12003
|
let i = 0;
|
|
@@ -11660,7 +12006,7 @@ const inflate = (container, target, typeId, data) => {
|
|
|
11660
12006
|
bytes[i++] = s.charCodeAt(0);
|
|
11661
12007
|
}
|
|
11662
12008
|
break;
|
|
11663
|
-
case
|
|
12009
|
+
case 38 /* TypeIds.PropsProxy */:
|
|
11664
12010
|
const propsProxy = target;
|
|
11665
12011
|
const d = data;
|
|
11666
12012
|
let owner = d[0];
|
|
@@ -11673,13 +12019,13 @@ const inflate = (container, target, typeId, data) => {
|
|
|
11673
12019
|
propsHandler.$effects$ = d[3];
|
|
11674
12020
|
restoreEffectBackRefForEffectsMap(propsHandler.$effects$, propsProxy);
|
|
11675
12021
|
break;
|
|
11676
|
-
case
|
|
12022
|
+
case 39 /* TypeIds.SubscriptionData */: {
|
|
11677
12023
|
const effectData = target;
|
|
11678
12024
|
effectData.data.$scopedStyleIdPrefix$ = data[0];
|
|
11679
12025
|
effectData.data.$isConst$ = data[1];
|
|
11680
12026
|
break;
|
|
11681
12027
|
}
|
|
11682
|
-
case
|
|
12028
|
+
case 40 /* TypeIds.EffectSubscription */: {
|
|
11683
12029
|
const effectSub = target;
|
|
11684
12030
|
const d = data;
|
|
11685
12031
|
effectSub.consumer = d[0];
|
|
@@ -11770,7 +12116,7 @@ function restoreEffectBackRefForEffectsMap(effectsMap, consumer) {
|
|
|
11770
12116
|
}
|
|
11771
12117
|
|
|
11772
12118
|
/** Arrays/Objects are special-cased so their identifiers is a single digit. */
|
|
11773
|
-
const needsInflation = (typeId) => typeId >=
|
|
12119
|
+
const needsInflation = (typeId) => typeId >= 23 /* TypeIds.Error */ || typeId === 4 /* TypeIds.Array */ || typeId === 5 /* TypeIds.Object */;
|
|
11774
12120
|
const deserializedProxyMap = new WeakMap();
|
|
11775
12121
|
const isDeserializerProxy = (value) => {
|
|
11776
12122
|
return isObject(value) && SERIALIZER_PROXY_UNWRAP in value;
|
|
@@ -11934,6 +12280,14 @@ const _verifySerializable = (value, seen, ctx, preMessage) => {
|
|
|
11934
12280
|
if (canSerialize(unwrapped)) {
|
|
11935
12281
|
return value;
|
|
11936
12282
|
}
|
|
12283
|
+
// Framework-internal branded values (e.g. route loaders/actions, validators)
|
|
12284
|
+
// are callables or objects that stamp __brand / __brand__ to opt out of the
|
|
12285
|
+
// serializer walking their internals. Honor that for both objects and
|
|
12286
|
+
// functions — loader/action refs are functions with __brand = 'server_loader'
|
|
12287
|
+
// / 'server_action' and should not be rejected as unserializable.
|
|
12288
|
+
if (unwrapped.__brand || unwrapped.__brand__) {
|
|
12289
|
+
return value;
|
|
12290
|
+
}
|
|
11937
12291
|
const typeObj = typeof unwrapped;
|
|
11938
12292
|
switch (typeObj) {
|
|
11939
12293
|
case 'object':
|
|
@@ -11963,10 +12317,6 @@ const _verifySerializable = (value, seen, ctx, preMessage) => {
|
|
|
11963
12317
|
if (unwrapped instanceof VNode) {
|
|
11964
12318
|
return value;
|
|
11965
12319
|
}
|
|
11966
|
-
// We have .__brand and .__brand__
|
|
11967
|
-
if (unwrapped.__brand || unwrapped.__brand__) {
|
|
11968
|
-
return value;
|
|
11969
|
-
}
|
|
11970
12320
|
if (isSerializableObject(unwrapped)) {
|
|
11971
12321
|
for (const [key, item] of Object.entries(unwrapped)) {
|
|
11972
12322
|
_verifySerializable(item, seen, ctx + '.' + key);
|
|
@@ -13308,13 +13658,15 @@ class QRLClass {
|
|
|
13308
13658
|
$container$;
|
|
13309
13659
|
constructor($lazy$, $captures$, container) {
|
|
13310
13660
|
this.$lazy$ = $lazy$;
|
|
13661
|
+
if (qDev) {
|
|
13662
|
+
initQrlClassDev($lazy$, $captures$, this);
|
|
13663
|
+
}
|
|
13311
13664
|
if ($captures$) {
|
|
13312
13665
|
this.$captures$ = $captures$;
|
|
13313
13666
|
if (typeof $captures$ === 'string') {
|
|
13314
13667
|
// We cannot rely on the container of the lazy ref, it may be missing or different
|
|
13315
13668
|
this.$container$ = container;
|
|
13316
13669
|
}
|
|
13317
|
-
qDev && initQrlClassDev($lazy$, $captures$, this);
|
|
13318
13670
|
}
|
|
13319
13671
|
// If it is plain value with deserialized or missing captures, resolve it immediately
|
|
13320
13672
|
// Otherwise we keep using the async path so we can wait for qrls to load
|
|
@@ -14930,5 +15282,5 @@ if (import.meta.hot) {
|
|
|
14930
15282
|
});
|
|
14931
15283
|
}
|
|
14932
15284
|
|
|
14933
|
-
export { $, Each, Fragment, NoSerializeSymbol, PrefetchGraph, PrefetchServiceWorker, RenderOnce, Resource, SSRComment, SSRRaw, SSRStream, SSRStreamBlock, SerializerSymbol, SkipRender, Slot, _CONST_PROPS, DomContainer as _DomContainer, _EFFECT_BACK_REF, EMPTY_ARRAY as _EMPTY_ARRAY, EMPTY_OBJ as _EMPTY_OBJ, _IMMUTABLE, _SharedContainer, SubscriptionData as _SubscriptionData, _UNINITIALIZED, _VAR_PROPS, _addProjection, _captures, _chk, createQRL as _createQRL, _deserialize, _dumpState, eachCmp as _eaC, eachCmpTask as _eaT, _executeSsrChores, _fnSignal, _getConstProps, _getContextContainer, _getContextEvent, _getContextHostElement, getDomContainer as _getDomContainer, _getQContainerElement, _getVarProps, _hasStoreEffects, _hmr, 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, _noopQrl, _noopQrlDEV, preprocessState as _preprocessState, _qrlSync, qrlToString as _qrlToString, _regSymbol, _removeProjection, _res, _resolveContextWithoutSequentialScope, _restProps, _rsc, _run, _serialize, setEvent as _setEvent, _setProjectionTarget, scheduleTask as _task, _updateProjectionProps, _useHmr, _val, verifySerializable as _verifySerializable, vnode_ensureElementInflated as _vnode_ensureElementInflated, vnode_getAttrKeys as _vnode_getAttrKeys, vnode_getFirstChild as _vnode_getFirstChild, vnode_isMaterialized as _vnode_isMaterialized, vnode_isTextVNode as _vnode_isTextVNode, vnode_isVirtualVNode as _vnode_isVirtualVNode, vnode_toString as _vnode_toString, _waitUntilRendered, _walkJSX, _wrapProp, _wrapSignal, component$, componentQrl, createAsync$, createAsyncSignal as createAsyncQrl, createComputed$, createComputedSignal as createComputedQrl, createContextId, h as createElement, createSerializer$, createSerializerSignal as createSerializerQrl, createSignal, event$, eventQrl, forceStoreEffects, getDomContainer, getLocale, getPlatform, h, implicit$FirstArg, inlinedQrl, inlinedQrlDEV, isSignal, jsx, jsxDEV, jsxs, noSerialize, qrl, qrlDEV, render, setPlatform, sync$, untrack, unwrapStore, useAsync$, useAsyncQrl, useComputed$, useComputedQrl, useConstant, useContext, useContextProvider, useErrorBoundary, useId, useLexicalScope, useOn, useOnDocument, useOnWindow, useResource$, useResourceQrl, useSerializer$, useSerializerQrl, useServerData, useSignal, useStore, useStyles$, useStylesQrl, useStylesScoped$, useStylesScopedQrl, useTask$, useTaskQrl, useVisibleTask$, useVisibleTaskQrl, version, withLocale };
|
|
15285
|
+
export { $, Each, Fragment, NoSerializeSymbol, PrefetchGraph, PrefetchServiceWorker, RenderOnce, Resource, SSRComment, SSRRaw, SSRStream, SSRStreamBlock, SerializerSymbol, SkipRender, Slot, _CONST_PROPS, DomContainer as _DomContainer, _EFFECT_BACK_REF, EMPTY_ARRAY as _EMPTY_ARRAY, EMPTY_OBJ as _EMPTY_OBJ, _IMMUTABLE, _SharedContainer, SubscriptionData as _SubscriptionData, _UNINITIALIZED, _VAR_PROPS, _addProjection, _captures, _chk, createQRL as _createQRL, _deserialize, _dumpState, eachCmp as _eaC, eachCmpTask as _eaT, _executeSsrChores, _fnSignal, _getConstProps, _getContextContainer, _getContextEvent, _getContextHostElement, getDomContainer as _getDomContainer, _getQContainerElement, _getVarProps, _hasStoreEffects, _hmr, 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, _noopQrl, _noopQrlDEV, preprocessState as _preprocessState, _qrlSync, qrlToString as _qrlToString, _regSymbol, _removeProjection, _res, _resolveContextWithoutSequentialScope, _restProps, _rsc, _run, _serialize, setEvent as _setEvent, _setProjectionTarget, 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, createAsync$, createAsyncSignal as createAsyncQrl, createComputed$, createComputedSignal as createComputedQrl, createContextId, h as createElement, createSerializer$, createSerializerSignal as createSerializerQrl, createSignal, event$, eventQrl, forceStoreEffects, getDomContainer, getLocale, getPlatform, h, implicit$FirstArg, inlinedQrl, inlinedQrlDEV, isSignal, jsx, jsxDEV, jsxs, noSerialize, qrl, qrlDEV, render, setPlatform, sync$, untrack, unwrapStore, useAsync$, useAsyncQrl, useComputed$, useComputedQrl, useConstant, useContext, useContextProvider, useErrorBoundary, useId, useLexicalScope, useOn, useOnDocument, useOnWindow, useResource$, useResourceQrl, useSerializer$, useSerializerQrl, useServerData, useSignal, useStore, useStyles$, useStylesQrl, useStylesScoped$, useStylesScopedQrl, useTask$, useTaskQrl, useVisibleTask$, useVisibleTaskQrl, version, withLocale };
|
|
14934
15286
|
//# sourceMappingURL=core.mjs.map
|