@qwik.dev/core 2.0.0-alpha.6 → 2.0.0-alpha.7
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/bindings/qwik.darwin-arm64.node +0 -0
- package/bindings/qwik.darwin-x64.node +0 -0
- package/bindings/qwik.linux-x64-gnu.node +0 -0
- package/bindings/qwik.win32-x64-msvc.node +0 -0
- package/bindings/qwik_wasm_bg.wasm +0 -0
- package/dist/build/package.json +1 -1
- package/dist/cli.cjs +65 -42
- package/dist/core-internal.d.ts +77 -76
- package/dist/core.cjs +1498 -1323
- package/dist/core.cjs.map +1 -1
- package/dist/core.min.mjs +1 -1
- package/dist/core.mjs +1496 -1323
- package/dist/core.mjs.map +1 -1
- package/dist/core.prod.cjs +884 -782
- package/dist/core.prod.mjs +1006 -867
- package/dist/insights/index.qwik.cjs +3652 -154
- package/dist/insights/index.qwik.mjs +3652 -154
- package/dist/loader/index.cjs +2 -2
- package/dist/loader/index.mjs +2 -2
- package/dist/loader/package.json +1 -1
- package/dist/optimizer.cjs +210 -5714
- package/dist/optimizer.mjs +191 -6037
- package/dist/prefetch/package.json +1 -1
- package/dist/qwikloader.debug.js +12 -15
- package/dist/qwikloader.js +2 -2
- package/dist/server.cjs +762 -7127
- package/dist/server.mjs +778 -7121
- package/dist/starters/adapters/fastify/src/plugins/fastify-qwik.ts +2 -0
- package/dist/starters/features/cypress/package.json +1 -1
- package/dist/starters/features/drizzle/drizzle/schema.ts +6 -18
- package/dist/starters/features/drizzle/drizzle.config.ts +5 -4
- package/dist/starters/features/drizzle/package.json +14 -11
- package/dist/starters/features/pandacss/package.json +1 -1
- package/dist/starters/features/partytown/package.json +1 -1
- package/dist/starters/features/postcss/package.json +1 -1
- package/dist/starters/features/prisma/package.json +1 -1
- package/dist/starters/features/react/package.json +1 -1
- package/dist/starters/features/storybook/package.json +1 -1
- package/dist/starters/features/styled-vanilla-extract/package.json +2 -1
- package/dist/starters/features/tailwind/package.json +15 -9
- package/dist/starters/features/tailwind/src/global.css +1 -7
- package/dist/starters/features/turso/package.json +1 -1
- package/dist/starters/features/vitest/package.json +1 -1
- package/dist/testing/index.cjs +1265 -1124
- package/dist/testing/index.mjs +1271 -1124
- package/dist/testing/package.json +1 -1
- package/handlers.mjs +9 -0
- package/package.json +6 -4
- package/public.d.ts +2 -0
- package/dist/starters/features/tailwind/.vscode/settings.json +0 -3
- package/dist/starters/features/tailwind/postcss.config.cjs +0 -6
- package/dist/starters/features/tailwind/tailwind.config.js +0 -8
package/dist/core.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* @qwik.dev/core 2.0.0-alpha.
|
|
3
|
+
* @qwik.dev/core 2.0.0-alpha.7-dev+a26598a
|
|
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
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
8
|
+
import { isDev, isServer } from '@qwik.dev/core/build';
|
|
9
9
|
export { isBrowser, isDev, isServer } from '@qwik.dev/core/build';
|
|
10
10
|
|
|
11
11
|
// same as isDev but separate so we can test
|
|
@@ -118,8 +118,8 @@ const codeToText = (code, ...parts) => {
|
|
|
118
118
|
// Keep one error, one line to make it easier to search for the error message.
|
|
119
119
|
const MAP = [
|
|
120
120
|
'Error while serializing class or style attributes', // 0
|
|
121
|
-
'', // 1
|
|
122
|
-
'', // 2
|
|
121
|
+
'Scheduler not found', // 1
|
|
122
|
+
'track() received object, without prop to track', // 2
|
|
123
123
|
'Only primitive and object literals can be serialized. {{0}}', // 3
|
|
124
124
|
'', // 4 unused
|
|
125
125
|
'You can render over a existing q:container. Skipping render().', // 5
|
|
@@ -162,12 +162,11 @@ const codeToText = (code, ...parts) => {
|
|
|
162
162
|
"Element must have 'q:container' attribute.", // 42
|
|
163
163
|
'Unknown vnode type {{0}}.', // 43
|
|
164
164
|
'Materialize error: missing element: {{0}} {{1}} {{2}}', // 44
|
|
165
|
-
'Cannot coerce a Signal, use `.value` instead', //
|
|
166
|
-
'useComputedSignal$ QRL {{0}} {{1}} returned a Promise', //
|
|
167
|
-
'ComputedSignal is read-only', //
|
|
168
|
-
'WrappedSignal is read-only', //
|
|
169
|
-
'
|
|
170
|
-
'Attribute value is unsafe for SSR', // 51
|
|
165
|
+
'Cannot coerce a Signal, use `.value` instead', // 45
|
|
166
|
+
'useComputedSignal$ QRL {{0}} {{1}} returned a Promise', // 46
|
|
167
|
+
'ComputedSignal is read-only', // 47
|
|
168
|
+
'WrappedSignal is read-only', // 48
|
|
169
|
+
'Attribute value is unsafe for SSR', // 49
|
|
171
170
|
];
|
|
172
171
|
let text = MAP[code] ?? '';
|
|
173
172
|
if (parts.length) {
|
|
@@ -189,8 +188,8 @@ const codeToText = (code, ...parts) => {
|
|
|
189
188
|
var QError;
|
|
190
189
|
(function (QError) {
|
|
191
190
|
QError[QError["stringifyClassOrStyle"] = 0] = "stringifyClassOrStyle";
|
|
192
|
-
QError[QError["
|
|
193
|
-
QError[QError["
|
|
191
|
+
QError[QError["schedulerNotFound"] = 1] = "schedulerNotFound";
|
|
192
|
+
QError[QError["trackObjectWithoutProp"] = 2] = "trackObjectWithoutProp";
|
|
194
193
|
QError[QError["verifySerializable"] = 3] = "verifySerializable";
|
|
195
194
|
QError[QError["UNUSED_4"] = 4] = "UNUSED_4";
|
|
196
195
|
QError[QError["cannotRenderOverExistingContainer"] = 5] = "cannotRenderOverExistingContainer";
|
|
@@ -237,14 +236,37 @@ var QError;
|
|
|
237
236
|
QError[QError["computedNotSync"] = 46] = "computedNotSync";
|
|
238
237
|
QError[QError["computedReadOnly"] = 47] = "computedReadOnly";
|
|
239
238
|
QError[QError["wrappedReadOnly"] = 48] = "wrappedReadOnly";
|
|
240
|
-
QError[QError["
|
|
241
|
-
QError[QError["unsafeAttr"] = 50] = "unsafeAttr";
|
|
239
|
+
QError[QError["unsafeAttr"] = 49] = "unsafeAttr";
|
|
242
240
|
})(QError || (QError = {}));
|
|
243
241
|
const qError = (code, errorMessageArgs = []) => {
|
|
244
242
|
const text = codeToText(code, ...errorMessageArgs);
|
|
245
243
|
return logErrorAndStop(text, ...errorMessageArgs);
|
|
246
244
|
};
|
|
247
245
|
|
|
246
|
+
/** QRL related utilities that you can import without importing all of Qwik. */
|
|
247
|
+
const SYNC_QRL = '<sync>';
|
|
248
|
+
/** Sync QRL is a function which is serialized into `<script q:func="qwik/json">` tag. */
|
|
249
|
+
const isSyncQrl = (value) => {
|
|
250
|
+
return isQrl$1(value) && value.$symbol$ == SYNC_QRL;
|
|
251
|
+
};
|
|
252
|
+
const isQrl$1 = (value) => {
|
|
253
|
+
return typeof value === 'function' && typeof value.getSymbol === 'function';
|
|
254
|
+
};
|
|
255
|
+
function assertQrl(qrl) {
|
|
256
|
+
if (isDev) {
|
|
257
|
+
if (!isQrl$1(qrl)) {
|
|
258
|
+
throw new Error('Not a QRL');
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
const getSymbolHash = (symbolName) => {
|
|
263
|
+
const index = symbolName.lastIndexOf('_');
|
|
264
|
+
if (index > -1) {
|
|
265
|
+
return symbolName.slice(index + 1);
|
|
266
|
+
}
|
|
267
|
+
return symbolName;
|
|
268
|
+
};
|
|
269
|
+
|
|
248
270
|
/**
|
|
249
271
|
* A friendly name tag for a VirtualVNode.
|
|
250
272
|
*
|
|
@@ -288,7 +310,7 @@ var QContainerValue;
|
|
|
288
310
|
/** State factory of the component. */
|
|
289
311
|
const OnRenderProp = 'q:renderFn';
|
|
290
312
|
/** Component style content prefix */
|
|
291
|
-
const ComponentStylesPrefixContent = '
|
|
313
|
+
const ComponentStylesPrefixContent = '⚡️';
|
|
292
314
|
/** `<some-element q:slot="...">` */
|
|
293
315
|
const QSlot = 'q:slot';
|
|
294
316
|
const QSlotParent = ':';
|
|
@@ -300,7 +322,7 @@ const QStyleSSelector = 'style[q\\:sstyle]';
|
|
|
300
322
|
const QStylesAllSelector = QStyleSelector + ',' + QStyleSSelector;
|
|
301
323
|
const QScopedStyle = 'q:sstyle';
|
|
302
324
|
const QCtxAttr = 'q:ctx';
|
|
303
|
-
const
|
|
325
|
+
const QBackRefs = 'q:brefs';
|
|
304
326
|
const QFuncsPrefix = 'qFuncs_';
|
|
305
327
|
const getQFuncs = (document, hash) => {
|
|
306
328
|
return document[QFuncsPrefix + hash] || [];
|
|
@@ -496,11 +518,6 @@ const maybeThen = (valueOrPromise, thenFn) => {
|
|
|
496
518
|
? valueOrPromise.then(thenFn, shouldNotError)
|
|
497
519
|
: thenFn(valueOrPromise);
|
|
498
520
|
};
|
|
499
|
-
const maybeThenPassError = (valueOrPromise, thenFn) => {
|
|
500
|
-
return isPromise(valueOrPromise)
|
|
501
|
-
? valueOrPromise.then(thenFn)
|
|
502
|
-
: thenFn(valueOrPromise);
|
|
503
|
-
};
|
|
504
521
|
const shouldNotError = (reason) => {
|
|
505
522
|
throwErrorAndStop(reason);
|
|
506
523
|
};
|
|
@@ -618,7 +635,7 @@ function setLocale(locale) {
|
|
|
618
635
|
_locale = locale;
|
|
619
636
|
}
|
|
620
637
|
|
|
621
|
-
const isQrl
|
|
638
|
+
const isQrl = (value) => {
|
|
622
639
|
return typeof value === 'function' && typeof value.getSymbol === 'function';
|
|
623
640
|
};
|
|
624
641
|
|
|
@@ -690,21 +707,21 @@ const qrl = (chunkOrFn, symbol, lexicalScopeCapture = EMPTY_ARRAY, stackOffset =
|
|
|
690
707
|
// Emit event
|
|
691
708
|
announcedQRL.add(symbol);
|
|
692
709
|
emitEvent('qprefetch', {
|
|
693
|
-
symbols: [
|
|
710
|
+
symbols: [symbol],
|
|
694
711
|
bundles: chunk && [chunk],
|
|
695
712
|
});
|
|
696
713
|
}
|
|
697
714
|
// Unwrap subscribers
|
|
698
|
-
return createQRL(chunk, symbol, null, symbolFn, null, lexicalScopeCapture
|
|
715
|
+
return createQRL(chunk, symbol, null, symbolFn, null, lexicalScopeCapture);
|
|
699
716
|
};
|
|
700
717
|
/** @internal */
|
|
701
718
|
const inlinedQrl = (symbol, symbolName, lexicalScopeCapture = EMPTY_ARRAY) => {
|
|
702
719
|
// Unwrap subscribers
|
|
703
|
-
return createQRL(null, symbolName, symbol, null, null, lexicalScopeCapture
|
|
720
|
+
return createQRL(null, symbolName, symbol, null, null, lexicalScopeCapture);
|
|
704
721
|
};
|
|
705
722
|
/** @internal */
|
|
706
723
|
const _noopQrl = (symbolName, lexicalScopeCapture = EMPTY_ARRAY) => {
|
|
707
|
-
return createQRL(null, symbolName, null, null, null, lexicalScopeCapture
|
|
724
|
+
return createQRL(null, symbolName, null, null, null, lexicalScopeCapture);
|
|
708
725
|
};
|
|
709
726
|
/** @internal */
|
|
710
727
|
const _noopQrlDEV = (symbolName, opts, lexicalScopeCapture = EMPTY_ARRAY) => {
|
|
@@ -733,6 +750,80 @@ const _regSymbol = (symbol, hash) => {
|
|
|
733
750
|
return symbol;
|
|
734
751
|
};
|
|
735
752
|
|
|
753
|
+
var ChoreType;
|
|
754
|
+
(function (ChoreType) {
|
|
755
|
+
/// MASKS defining three levels of sorting
|
|
756
|
+
ChoreType[ChoreType["MACRO"] = 240] = "MACRO";
|
|
757
|
+
/* order of elements (not encoded here) */
|
|
758
|
+
ChoreType[ChoreType["MICRO"] = 15] = "MICRO";
|
|
759
|
+
/** Ensure that the QRL promise is resolved before processing next chores in the queue */
|
|
760
|
+
ChoreType[ChoreType["QRL_RESOLVE"] = 1] = "QRL_RESOLVE";
|
|
761
|
+
ChoreType[ChoreType["RUN_QRL"] = 2] = "RUN_QRL";
|
|
762
|
+
ChoreType[ChoreType["TASK"] = 3] = "TASK";
|
|
763
|
+
ChoreType[ChoreType["NODE_DIFF"] = 4] = "NODE_DIFF";
|
|
764
|
+
ChoreType[ChoreType["NODE_PROP"] = 5] = "NODE_PROP";
|
|
765
|
+
ChoreType[ChoreType["COMPONENT"] = 6] = "COMPONENT";
|
|
766
|
+
ChoreType[ChoreType["RECOMPUTE_AND_SCHEDULE_EFFECTS"] = 7] = "RECOMPUTE_AND_SCHEDULE_EFFECTS";
|
|
767
|
+
// Next macro level
|
|
768
|
+
ChoreType[ChoreType["JOURNAL_FLUSH"] = 16] = "JOURNAL_FLUSH";
|
|
769
|
+
// Next macro level
|
|
770
|
+
ChoreType[ChoreType["VISIBLE"] = 32] = "VISIBLE";
|
|
771
|
+
// Next macro level
|
|
772
|
+
ChoreType[ChoreType["CLEANUP_VISIBLE"] = 48] = "CLEANUP_VISIBLE";
|
|
773
|
+
// Next macro level
|
|
774
|
+
ChoreType[ChoreType["WAIT_FOR_ALL"] = 255] = "WAIT_FOR_ALL";
|
|
775
|
+
})(ChoreType || (ChoreType = {}));
|
|
776
|
+
|
|
777
|
+
// <docs markdown="../readme.md#useLexicalScope">
|
|
778
|
+
// !!DO NOT EDIT THIS COMMENT DIRECTLY!!!
|
|
779
|
+
// (edit ../readme.md#useLexicalScope instead and run `pnpm docs.sync`)
|
|
780
|
+
/**
|
|
781
|
+
* Used by the Qwik Optimizer to restore the lexically scoped variables.
|
|
782
|
+
*
|
|
783
|
+
* This method should not be present in the application source code.
|
|
784
|
+
*
|
|
785
|
+
* NOTE: `useLexicalScope` method can only be used in the synchronous portion of the callback
|
|
786
|
+
* (before any `await` statements.)
|
|
787
|
+
*
|
|
788
|
+
* @internal
|
|
789
|
+
*/
|
|
790
|
+
// </docs>
|
|
791
|
+
const useLexicalScope = () => {
|
|
792
|
+
const context = getInvokeContext();
|
|
793
|
+
let qrl = context.$qrl$;
|
|
794
|
+
if (!qrl) {
|
|
795
|
+
const el = context.$element$;
|
|
796
|
+
assertDefined(el, 'invoke: element must be defined inside useLexicalScope()', context);
|
|
797
|
+
const containerElement = _getQContainerElement(el);
|
|
798
|
+
assertDefined(containerElement, `invoke: cant find parent q:container of`, el);
|
|
799
|
+
const container = getDomContainer(containerElement);
|
|
800
|
+
qrl = container.parseQRL(decodeURIComponent(String(context.$url$)));
|
|
801
|
+
}
|
|
802
|
+
else {
|
|
803
|
+
assertQrl(qrl);
|
|
804
|
+
assertDefined(qrl.$captureRef$, 'invoke: qrl $captureRef$ must be defined inside useLexicalScope()', qrl);
|
|
805
|
+
}
|
|
806
|
+
return qrl.$captureRef$;
|
|
807
|
+
};
|
|
808
|
+
|
|
809
|
+
/**
|
|
810
|
+
* This is called by qwik-loader to schedule a QRL. It has to be synchronous.
|
|
811
|
+
*
|
|
812
|
+
* @internal
|
|
813
|
+
*/
|
|
814
|
+
const queueQRL = (...args) => {
|
|
815
|
+
// This will already check container
|
|
816
|
+
const [runQrl] = useLexicalScope();
|
|
817
|
+
const context = getInvokeContext();
|
|
818
|
+
const hostElement = context.$hostElement$;
|
|
819
|
+
const container = getDomContainer(hostElement);
|
|
820
|
+
const scheduler = container.$scheduler$;
|
|
821
|
+
if (!scheduler) {
|
|
822
|
+
throw qError(QError.schedulerNotFound);
|
|
823
|
+
}
|
|
824
|
+
return scheduler(ChoreType.RUN_QRL, hostElement, runQrl, args);
|
|
825
|
+
};
|
|
826
|
+
|
|
736
827
|
/**
|
|
737
828
|
* Allows to project the children of the current component. <Slot/> can only be used within the
|
|
738
829
|
* context of a component defined with `component$`.
|
|
@@ -857,6 +948,47 @@ function isPreventDefault(key) {
|
|
|
857
948
|
return key.startsWith('preventdefault:');
|
|
858
949
|
}
|
|
859
950
|
|
|
951
|
+
function getFileLocationFromJsx(jsxDev) {
|
|
952
|
+
if (!jsxDev) {
|
|
953
|
+
return null;
|
|
954
|
+
}
|
|
955
|
+
const sanitizedFileName = jsxDev.fileName?.replace(/\\/g, '/');
|
|
956
|
+
if (sanitizedFileName) {
|
|
957
|
+
return `${sanitizedFileName}:${jsxDev.lineNumber}:${jsxDev.columnNumber}`;
|
|
958
|
+
}
|
|
959
|
+
return null;
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
const styleContent = (styleId) => {
|
|
963
|
+
return ComponentStylesPrefixContent + styleId;
|
|
964
|
+
};
|
|
965
|
+
function hasClassAttr(props) {
|
|
966
|
+
for (const key in props) {
|
|
967
|
+
if (Object.prototype.hasOwnProperty.call(props, key) && isClassAttr(key)) {
|
|
968
|
+
return true;
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
return false;
|
|
972
|
+
}
|
|
973
|
+
function isClassAttr(key) {
|
|
974
|
+
return key === 'class' || key === 'className';
|
|
975
|
+
}
|
|
976
|
+
function convertScopedStyleIdsToArray(scopedStyleIds) {
|
|
977
|
+
return scopedStyleIds?.split(' ') ?? null;
|
|
978
|
+
}
|
|
979
|
+
function convertStyleIdsToString(scopedStyleIds) {
|
|
980
|
+
return Array.from(scopedStyleIds).join(' ');
|
|
981
|
+
}
|
|
982
|
+
const addComponentStylePrefix = (styleId) => {
|
|
983
|
+
if (styleId) {
|
|
984
|
+
let idx = 0;
|
|
985
|
+
do {
|
|
986
|
+
styleId = styleId.substring(0, idx) + styleContent(styleId.substring(idx));
|
|
987
|
+
} while ((idx = styleId.indexOf(' ', idx) + 1) !== 0);
|
|
988
|
+
}
|
|
989
|
+
return styleId || null;
|
|
990
|
+
};
|
|
991
|
+
|
|
860
992
|
/** CSS properties which accept numbers but are not in units of "px". */
|
|
861
993
|
const unitlessNumbers = new Set([
|
|
862
994
|
'animationIterationCount',
|
|
@@ -1015,36 +1147,6 @@ const styleKey = (qStyles, index) => {
|
|
|
1015
1147
|
assertQrl(qStyles);
|
|
1016
1148
|
return `${hashCode(qStyles.$hash$)}-${index}`;
|
|
1017
1149
|
};
|
|
1018
|
-
const styleContent = (styleId) => {
|
|
1019
|
-
return ComponentStylesPrefixContent + styleId;
|
|
1020
|
-
};
|
|
1021
|
-
|
|
1022
|
-
function hasClassAttr(props) {
|
|
1023
|
-
for (const key in props) {
|
|
1024
|
-
if (Object.prototype.hasOwnProperty.call(props, key) && isClassAttr(key)) {
|
|
1025
|
-
return true;
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1028
|
-
return false;
|
|
1029
|
-
}
|
|
1030
|
-
function isClassAttr(key) {
|
|
1031
|
-
return key === 'class' || key === 'className';
|
|
1032
|
-
}
|
|
1033
|
-
function convertScopedStyleIdsToArray(scopedStyleIds) {
|
|
1034
|
-
return scopedStyleIds?.split(' ') ?? null;
|
|
1035
|
-
}
|
|
1036
|
-
function convertStyleIdsToString(scopedStyleIds) {
|
|
1037
|
-
return Array.from(scopedStyleIds).join(' ');
|
|
1038
|
-
}
|
|
1039
|
-
const addComponentStylePrefix = (styleId) => {
|
|
1040
|
-
if (styleId) {
|
|
1041
|
-
let idx = 0;
|
|
1042
|
-
do {
|
|
1043
|
-
styleId = styleId.substring(0, idx) + styleContent(styleId.substring(idx));
|
|
1044
|
-
} while ((idx = styleId.indexOf(' ', idx) + 1) !== 0);
|
|
1045
|
-
}
|
|
1046
|
-
return styleId || null;
|
|
1047
|
-
};
|
|
1048
1150
|
|
|
1049
1151
|
const STORE_TARGET = Symbol('store.target');
|
|
1050
1152
|
const STORE_HANDLER = Symbol('store.handler');
|
|
@@ -1189,8 +1291,12 @@ class StoreHandler {
|
|
|
1189
1291
|
return Reflect.ownKeys(target);
|
|
1190
1292
|
}
|
|
1191
1293
|
getOwnPropertyDescriptor(target, prop) {
|
|
1294
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(target, prop);
|
|
1192
1295
|
if (Array.isArray(target) || typeof prop === 'symbol') {
|
|
1193
|
-
return
|
|
1296
|
+
return descriptor;
|
|
1297
|
+
}
|
|
1298
|
+
if (descriptor && !descriptor.configurable) {
|
|
1299
|
+
return descriptor;
|
|
1194
1300
|
}
|
|
1195
1301
|
return {
|
|
1196
1302
|
enumerable: true,
|
|
@@ -1198,355 +1304,280 @@ class StoreHandler {
|
|
|
1198
1304
|
};
|
|
1199
1305
|
}
|
|
1200
1306
|
}
|
|
1201
|
-
function addEffect(target, prop, store,
|
|
1202
|
-
const effectsMap = (store.$effects$ ||=
|
|
1203
|
-
|
|
1204
|
-
|
|
1307
|
+
function addEffect(target, prop, store, effectSubscription) {
|
|
1308
|
+
const effectsMap = (store.$effects$ ||= new Map());
|
|
1309
|
+
let effects = effectsMap.get(prop);
|
|
1310
|
+
if (!effects) {
|
|
1311
|
+
effects = new Set();
|
|
1312
|
+
effectsMap.set(prop, effects);
|
|
1313
|
+
}
|
|
1205
1314
|
// Let's make sure that we have a reference to this effect.
|
|
1206
1315
|
// Adding reference is essentially adding a subscription, so if the signal
|
|
1207
1316
|
// changes we know who to notify.
|
|
1208
|
-
|
|
1317
|
+
ensureContainsSubscription(effects, effectSubscription);
|
|
1209
1318
|
// But when effect is scheduled in needs to be able to know which signals
|
|
1210
1319
|
// to unsubscribe from. So we need to store the reference from the effect back
|
|
1211
1320
|
// to this signal.
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
ensureEffectContainsSubscriber(effectSubscriber[EffectSubscriptionsProp.EFFECT], target, store.$container$);
|
|
1321
|
+
ensureContainsBackRef(effectSubscription, target);
|
|
1322
|
+
addQrlToSerializationCtx(effectSubscription, store.$container$);
|
|
1215
1323
|
}
|
|
1216
1324
|
function setNewValueAndTriggerEffects(prop, value, target, currentStore) {
|
|
1217
1325
|
target[prop] = value;
|
|
1218
1326
|
triggerEffects(currentStore.$container$, currentStore, getEffects(target, prop, currentStore.$effects$));
|
|
1219
1327
|
}
|
|
1220
1328
|
function getEffects(target, prop, storeEffects) {
|
|
1221
|
-
let effectsToTrigger
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1329
|
+
let effectsToTrigger;
|
|
1330
|
+
if (storeEffects) {
|
|
1331
|
+
if (Array.isArray(target)) {
|
|
1332
|
+
for (const effects of storeEffects.values()) {
|
|
1333
|
+
effectsToTrigger ||= new Set();
|
|
1334
|
+
for (const effect of effects) {
|
|
1335
|
+
effectsToTrigger.add(effect);
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
else {
|
|
1340
|
+
effectsToTrigger = storeEffects.get(prop);
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
const storeArrayValue = storeEffects?.get(STORE_ARRAY_PROP);
|
|
1227
1344
|
if (storeArrayValue) {
|
|
1228
|
-
effectsToTrigger ||=
|
|
1229
|
-
|
|
1345
|
+
effectsToTrigger ||= new Set();
|
|
1346
|
+
for (const effect of storeArrayValue) {
|
|
1347
|
+
effectsToTrigger.add(effect);
|
|
1348
|
+
}
|
|
1230
1349
|
}
|
|
1231
|
-
return effectsToTrigger;
|
|
1350
|
+
return effectsToTrigger || null;
|
|
1232
1351
|
}
|
|
1233
1352
|
|
|
1234
1353
|
/**
|
|
1235
|
-
*
|
|
1236
|
-
*
|
|
1354
|
+
* Special value used to mark that a given signal needs to be computed. This is essentially a
|
|
1355
|
+
* "marked as dirty" flag.
|
|
1237
1356
|
*/
|
|
1238
|
-
const
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
const host = hostElement;
|
|
1242
|
-
let seq = iCtx.$container$.getHostProp(host, ELEMENT_SEQ);
|
|
1243
|
-
if (seq === null) {
|
|
1244
|
-
seq = [];
|
|
1245
|
-
iCtx.$container$.setHostProp(host, ELEMENT_SEQ, seq);
|
|
1246
|
-
}
|
|
1247
|
-
let seqIdx = iCtx.$container$.getHostProp(host, ELEMENT_SEQ_IDX);
|
|
1248
|
-
if (seqIdx === null) {
|
|
1249
|
-
seqIdx = 0;
|
|
1250
|
-
}
|
|
1251
|
-
iCtx.$container$.setHostProp(host, ELEMENT_SEQ_IDX, seqIdx + 1);
|
|
1252
|
-
while (seq.length <= seqIdx) {
|
|
1253
|
-
seq.push(undefined);
|
|
1254
|
-
}
|
|
1255
|
-
const set = (value) => {
|
|
1256
|
-
if (qDev && qSerialize) {
|
|
1257
|
-
verifySerializable(value);
|
|
1258
|
-
}
|
|
1259
|
-
return (seq[seqIdx] = value);
|
|
1260
|
-
};
|
|
1261
|
-
return {
|
|
1262
|
-
val: seq[seqIdx],
|
|
1263
|
-
set,
|
|
1264
|
-
i: seqIdx,
|
|
1265
|
-
iCtx,
|
|
1266
|
-
};
|
|
1267
|
-
};
|
|
1357
|
+
const NEEDS_COMPUTATION = Symbol('invalid');
|
|
1358
|
+
/** @internal */
|
|
1359
|
+
const _EFFECT_BACK_REF = Symbol('backRef');
|
|
1268
1360
|
|
|
1269
|
-
|
|
1270
|
-
|
|
1361
|
+
/** Class for back reference to the EffectSubscription */
|
|
1362
|
+
class BackRef {
|
|
1363
|
+
[_EFFECT_BACK_REF] = null;
|
|
1271
1364
|
}
|
|
1272
|
-
function
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
function clearVNodeEffectDependencies(container, value) {
|
|
1276
|
-
if (vnode_isElementVNode(value)) {
|
|
1277
|
-
ensureMaterialized(value);
|
|
1365
|
+
function clearAllEffects(container, consumer) {
|
|
1366
|
+
if (vnode_isVNode(consumer) && vnode_isElementVNode(consumer)) {
|
|
1367
|
+
ensureMaterialized(consumer);
|
|
1278
1368
|
}
|
|
1279
|
-
const effects =
|
|
1369
|
+
const effects = consumer[_EFFECT_BACK_REF];
|
|
1280
1370
|
if (!effects) {
|
|
1281
1371
|
return;
|
|
1282
1372
|
}
|
|
1283
|
-
for (
|
|
1284
|
-
const
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
if (effects.length === 0) {
|
|
1288
|
-
vnode_setProp(value, QSubscribers, null);
|
|
1289
|
-
}
|
|
1290
|
-
}
|
|
1291
|
-
function clearSubscriberEffectDependencies(container, value) {
|
|
1292
|
-
if (value.$effectDependencies$) {
|
|
1293
|
-
for (let i = value.$effectDependencies$.length - 1; i >= 0; i--) {
|
|
1294
|
-
const subscriber = value.$effectDependencies$[i];
|
|
1295
|
-
clearEffects(subscriber, value, value.$effectDependencies$, i, container);
|
|
1296
|
-
}
|
|
1297
|
-
if (value.$effectDependencies$.length === 0) {
|
|
1298
|
-
value.$effectDependencies$ = null;
|
|
1373
|
+
for (const [, effect] of effects) {
|
|
1374
|
+
const backRefs = effect[EffectSubscriptionProp.BACK_REF];
|
|
1375
|
+
if (!backRefs) {
|
|
1376
|
+
return;
|
|
1299
1377
|
}
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
let subscriptionRemoved = false;
|
|
1304
|
-
const seenSet = new Set();
|
|
1305
|
-
if (subscriber instanceof WrappedSignal) {
|
|
1306
|
-
subscriptionRemoved = clearSignalEffects(subscriber, value, seenSet);
|
|
1307
|
-
}
|
|
1308
|
-
else if (container.$storeProxyMap$.has(subscriber)) {
|
|
1309
|
-
const store = container.$storeProxyMap$.get(subscriber);
|
|
1310
|
-
const handler = getStoreHandler(store);
|
|
1311
|
-
subscriptionRemoved = clearStoreEffects(handler, value);
|
|
1312
|
-
}
|
|
1313
|
-
if (subscriptionRemoved) {
|
|
1314
|
-
effectArray.splice(indexToRemove, 1);
|
|
1315
|
-
}
|
|
1316
|
-
}
|
|
1317
|
-
function clearSignalEffects(subscriber, value, seenSet) {
|
|
1318
|
-
const effectSubscriptions = subscriber.$effects$;
|
|
1319
|
-
let subscriptionRemoved = false;
|
|
1320
|
-
if (effectSubscriptions) {
|
|
1321
|
-
for (let i = effectSubscriptions.length - 1; i >= 0; i--) {
|
|
1322
|
-
const effect = effectSubscriptions[i];
|
|
1323
|
-
if (effect[EffectSubscriptionsProp.EFFECT] === value) {
|
|
1324
|
-
effectSubscriptions.splice(i, 1);
|
|
1325
|
-
subscriptionRemoved = true;
|
|
1378
|
+
for (const producer of backRefs) {
|
|
1379
|
+
if (producer instanceof Signal) {
|
|
1380
|
+
clearSignal(container, producer, effect);
|
|
1326
1381
|
}
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
if (hostElement && hostElement === value) {
|
|
1332
|
-
subscriber.$hostElement$ = null;
|
|
1333
|
-
}
|
|
1334
|
-
// clear the effects of the arguments
|
|
1335
|
-
const args = subscriber.$args$;
|
|
1336
|
-
if (args) {
|
|
1337
|
-
clearArgsEffects(args, subscriber, seenSet);
|
|
1338
|
-
}
|
|
1339
|
-
}
|
|
1340
|
-
return subscriptionRemoved;
|
|
1341
|
-
}
|
|
1342
|
-
function clearStoreEffects(storeHandler, value) {
|
|
1343
|
-
const effectSubscriptions = storeHandler.$effects$;
|
|
1344
|
-
if (!effectSubscriptions) {
|
|
1345
|
-
return false;
|
|
1346
|
-
}
|
|
1347
|
-
let subscriptionRemoved = false;
|
|
1348
|
-
for (const key in effectSubscriptions) {
|
|
1349
|
-
const effects = effectSubscriptions[key];
|
|
1350
|
-
for (let i = effects.length - 1; i >= 0; i--) {
|
|
1351
|
-
const effect = effects[i];
|
|
1352
|
-
if (effect[EffectSubscriptionsProp.EFFECT] === value) {
|
|
1353
|
-
effects.splice(i, 1);
|
|
1354
|
-
subscriptionRemoved = true;
|
|
1382
|
+
else if (container.$storeProxyMap$.has(producer)) {
|
|
1383
|
+
const target = container.$storeProxyMap$.get(producer);
|
|
1384
|
+
const storeHandler = getStoreHandler(target);
|
|
1385
|
+
clearStore(storeHandler, effect);
|
|
1355
1386
|
}
|
|
1356
1387
|
}
|
|
1357
|
-
if (effects.length === 0) {
|
|
1358
|
-
delete effectSubscriptions[key];
|
|
1359
|
-
}
|
|
1360
|
-
}
|
|
1361
|
-
return subscriptionRemoved;
|
|
1362
|
-
}
|
|
1363
|
-
function clearArgsEffects(args, subscriber, seenSet) {
|
|
1364
|
-
for (let i = args.length - 1; i >= 0; i--) {
|
|
1365
|
-
const arg = args[i];
|
|
1366
|
-
clearArgEffect(arg, subscriber, seenSet);
|
|
1367
1388
|
}
|
|
1368
1389
|
}
|
|
1369
|
-
function
|
|
1370
|
-
|
|
1371
|
-
|
|
1390
|
+
function clearSignal(container, producer, effect) {
|
|
1391
|
+
const effects = producer.$effects$;
|
|
1392
|
+
if (effects) {
|
|
1393
|
+
effects.delete(effect);
|
|
1372
1394
|
}
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1395
|
+
if (producer instanceof WrappedSignal) {
|
|
1396
|
+
producer.$hostElement$ = null;
|
|
1397
|
+
clearAllEffects(container, producer);
|
|
1376
1398
|
}
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
// To avoid that we need to get the constProps and varProps directly
|
|
1384
|
-
// from the props proxy object and loop over them.
|
|
1385
|
-
const constProps = arg[_CONST_PROPS];
|
|
1386
|
-
const varProps = arg[_VAR_PROPS];
|
|
1387
|
-
if (constProps) {
|
|
1388
|
-
for (const key in constProps) {
|
|
1389
|
-
clearArgEffect(constProps[key], subscriber, seenSet);
|
|
1390
|
-
}
|
|
1391
|
-
}
|
|
1392
|
-
for (const key in varProps) {
|
|
1393
|
-
clearArgEffect(varProps[key], subscriber, seenSet);
|
|
1394
|
-
}
|
|
1395
|
-
}
|
|
1396
|
-
else {
|
|
1397
|
-
for (const key in arg) {
|
|
1398
|
-
clearArgEffect(arg[key], subscriber, seenSet);
|
|
1399
|
-
}
|
|
1399
|
+
}
|
|
1400
|
+
function clearStore(producer, effect) {
|
|
1401
|
+
const effects = producer?.$effects$;
|
|
1402
|
+
if (effects) {
|
|
1403
|
+
for (const propEffects of effects.values()) {
|
|
1404
|
+
propEffects.delete(effect);
|
|
1400
1405
|
}
|
|
1401
1406
|
}
|
|
1402
|
-
else if (Array.isArray(arg)) {
|
|
1403
|
-
clearArgsEffects(arg, subscriber, seenSet);
|
|
1404
|
-
}
|
|
1405
|
-
else ;
|
|
1406
1407
|
}
|
|
1407
1408
|
|
|
1408
|
-
|
|
1409
|
-
const useResourceQrl = (qrl, opts) => {
|
|
1410
|
-
const { val, set, i, iCtx } = useSequentialScope();
|
|
1411
|
-
if (val != null) {
|
|
1412
|
-
return val;
|
|
1413
|
-
}
|
|
1414
|
-
assertQrl(qrl);
|
|
1415
|
-
const container = iCtx.$container$;
|
|
1416
|
-
const resource = createResourceReturn(container, opts);
|
|
1417
|
-
const el = iCtx.$hostElement$;
|
|
1418
|
-
const task = new Task(TaskFlags.DIRTY | TaskFlags.RESOURCE, i, el, qrl, resource, null);
|
|
1419
|
-
runResource(task, container, iCtx.$hostElement$);
|
|
1420
|
-
set(resource);
|
|
1421
|
-
return resource;
|
|
1422
|
-
};
|
|
1423
|
-
// <docs markdown="../readme.md#useResource">
|
|
1409
|
+
// <docs markdown="../../readme.md#implicit$FirstArg">
|
|
1424
1410
|
// !!DO NOT EDIT THIS COMMENT DIRECTLY!!!
|
|
1425
|
-
// (edit
|
|
1411
|
+
// (edit ../../readme.md#implicit$FirstArg instead and run `pnpm docs.sync`)
|
|
1426
1412
|
/**
|
|
1427
|
-
*
|
|
1428
|
-
* and returns some data.
|
|
1413
|
+
* Create a `____$(...)` convenience method from `___(...)`.
|
|
1429
1414
|
*
|
|
1430
|
-
*
|
|
1431
|
-
*
|
|
1415
|
+
* It is very common for functions to take a lazy-loadable resource as a first argument. For this
|
|
1416
|
+
* reason, the Qwik Optimizer automatically extracts the first argument from any function which ends
|
|
1417
|
+
* in `$`.
|
|
1432
1418
|
*
|
|
1433
|
-
*
|
|
1419
|
+
* This means that `foo$(arg0)` and `foo($(arg0))` are equivalent with respect to Qwik Optimizer.
|
|
1420
|
+
* The former is just a shorthand for the latter.
|
|
1434
1421
|
*
|
|
1435
|
-
*
|
|
1436
|
-
* - `resolved` - the data is available.
|
|
1437
|
-
* - `rejected` - the data is not available due to an error or timeout.
|
|
1422
|
+
* For example, these function calls are equivalent:
|
|
1438
1423
|
*
|
|
1439
|
-
*
|
|
1440
|
-
* re-throw it (or a new Error), the resource status will never be `rejected`.
|
|
1424
|
+
* - `component$(() => {...})` is same as `component($(() => {...}))`
|
|
1441
1425
|
*
|
|
1442
|
-
*
|
|
1426
|
+
* ```tsx
|
|
1427
|
+
* export function myApi(callback: QRL<() => void>): void {
|
|
1428
|
+
* // ...
|
|
1429
|
+
* }
|
|
1443
1430
|
*
|
|
1444
|
-
*
|
|
1445
|
-
*
|
|
1431
|
+
* export const myApi$ = implicit$FirstArg(myApi);
|
|
1432
|
+
* // type of myApi$: (callback: () => void): void
|
|
1446
1433
|
*
|
|
1447
|
-
*
|
|
1448
|
-
*
|
|
1449
|
-
* const cityS = useSignal('');
|
|
1434
|
+
* // can be used as:
|
|
1435
|
+
* myApi$(() => console.log('callback'));
|
|
1450
1436
|
*
|
|
1451
|
-
*
|
|
1452
|
-
*
|
|
1453
|
-
*
|
|
1454
|
-
* cleanup(() => abortController.abort('cleanup'));
|
|
1455
|
-
* const res = await fetch(`http://weatherdata.com?city=${cityName}`, {
|
|
1456
|
-
* signal: abortController.signal,
|
|
1457
|
-
* });
|
|
1458
|
-
* const data = await res.json();
|
|
1459
|
-
* return data as { temp: number };
|
|
1460
|
-
* });
|
|
1437
|
+
* // will be transpiled to:
|
|
1438
|
+
* // FILE: <current file>
|
|
1439
|
+
* myApi(qrl('./chunk-abc.js', 'callback'));
|
|
1461
1440
|
*
|
|
1462
|
-
*
|
|
1463
|
-
*
|
|
1464
|
-
* <input name="city" bind:value={cityS} />
|
|
1465
|
-
* <Resource
|
|
1466
|
-
* value={weatherResource}
|
|
1467
|
-
* onResolved={(weather) => {
|
|
1468
|
-
* return <div>Temperature: {weather.temp}</div>;
|
|
1469
|
-
* }}
|
|
1470
|
-
* />
|
|
1471
|
-
* </div>
|
|
1472
|
-
* );
|
|
1473
|
-
* });
|
|
1441
|
+
* // FILE: chunk-abc.js
|
|
1442
|
+
* export const callback = () => console.log('callback');
|
|
1474
1443
|
* ```
|
|
1475
1444
|
*
|
|
1445
|
+
* @param fn - A function that should have its first argument automatically `$`.
|
|
1476
1446
|
* @public
|
|
1477
|
-
* @see Resource
|
|
1478
|
-
* @see ResourceReturn
|
|
1479
1447
|
*/
|
|
1480
1448
|
// </docs>
|
|
1481
|
-
const
|
|
1482
|
-
|
|
1483
|
-
|
|
1449
|
+
const implicit$FirstArg = (fn) => {
|
|
1450
|
+
return function (first, ...rest) {
|
|
1451
|
+
return fn.call(null, dollar(first), ...rest);
|
|
1452
|
+
};
|
|
1484
1453
|
};
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1454
|
+
|
|
1455
|
+
const createSignal$1 = (value) => {
|
|
1456
|
+
return new Signal(null, value);
|
|
1457
|
+
};
|
|
1458
|
+
const createComputedSignal = (qrl) => {
|
|
1459
|
+
throwIfQRLNotResolved(qrl);
|
|
1460
|
+
return new ComputedSignal(null, qrl);
|
|
1461
|
+
};
|
|
1462
|
+
|
|
1463
|
+
/**
|
|
1464
|
+
* Creates a Signal with the given value. If no value is given, the signal is created with
|
|
1465
|
+
* `undefined`.
|
|
1466
|
+
*
|
|
1467
|
+
* @public
|
|
1468
|
+
*/
|
|
1469
|
+
const createSignal = createSignal$1;
|
|
1470
|
+
/** @internal */
|
|
1471
|
+
const createComputedQrl = createComputedSignal;
|
|
1472
|
+
/**
|
|
1473
|
+
* Create a computed signal which is calculated from the given QRL. A computed signal is a signal
|
|
1474
|
+
* which is calculated from other signals. When the signals change, the computed signal is
|
|
1475
|
+
* recalculated.
|
|
1476
|
+
*
|
|
1477
|
+
* The QRL must be a function which returns the value of the signal. The function must not have side
|
|
1478
|
+
* effects, and it mus be synchronous.
|
|
1479
|
+
*
|
|
1480
|
+
* If you need the function to be async, use `useSignal` and `useTask$` instead.
|
|
1481
|
+
*
|
|
1482
|
+
* @public
|
|
1483
|
+
*/
|
|
1484
|
+
const createComputed$ = /*#__PURE__*/ implicit$FirstArg(createComputedQrl);
|
|
1485
|
+
|
|
1486
|
+
/**
|
|
1487
|
+
* @internal
|
|
1488
|
+
* The storage provider for hooks. Each invocation increases index i. Data is stored in an array.
|
|
1489
|
+
*/
|
|
1490
|
+
const useSequentialScope = () => {
|
|
1491
|
+
const iCtx = useInvokeContext();
|
|
1492
|
+
const hostElement = iCtx.$hostElement$;
|
|
1493
|
+
const host = hostElement;
|
|
1494
|
+
let seq = iCtx.$container$.getHostProp(host, ELEMENT_SEQ);
|
|
1495
|
+
if (seq === null) {
|
|
1496
|
+
seq = [];
|
|
1497
|
+
iCtx.$container$.setHostProp(host, ELEMENT_SEQ, seq);
|
|
1510
1498
|
}
|
|
1511
|
-
|
|
1512
|
-
|
|
1499
|
+
let seqIdx = iCtx.$container$.getHostProp(host, ELEMENT_SEQ_IDX);
|
|
1500
|
+
if (seqIdx === null) {
|
|
1501
|
+
seqIdx = 0;
|
|
1513
1502
|
}
|
|
1514
|
-
|
|
1515
|
-
|
|
1503
|
+
iCtx.$container$.setHostProp(host, ELEMENT_SEQ_IDX, seqIdx + 1);
|
|
1504
|
+
while (seq.length <= seqIdx) {
|
|
1505
|
+
seq.push(undefined);
|
|
1516
1506
|
}
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
value
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1507
|
+
const set = (value) => {
|
|
1508
|
+
if (qDev && qSerialize) {
|
|
1509
|
+
verifySerializable(value);
|
|
1510
|
+
}
|
|
1511
|
+
return (seq[seqIdx] = value);
|
|
1512
|
+
};
|
|
1513
|
+
return {
|
|
1514
|
+
val: seq[seqIdx],
|
|
1515
|
+
set,
|
|
1516
|
+
i: seqIdx,
|
|
1517
|
+
iCtx,
|
|
1528
1518
|
};
|
|
1529
|
-
return resource;
|
|
1530
|
-
};
|
|
1531
|
-
const createResourceReturn = (container, opts, initialPromise) => {
|
|
1532
|
-
const result = _createResourceReturn(opts);
|
|
1533
|
-
result.value = initialPromise;
|
|
1534
|
-
return createStore(container, result, StoreFlags.RECURSIVE);
|
|
1535
1519
|
};
|
|
1536
|
-
|
|
1537
|
-
|
|
1520
|
+
|
|
1521
|
+
function getSubscriber(effect, prop, data) {
|
|
1522
|
+
if (!effect[_EFFECT_BACK_REF]) {
|
|
1523
|
+
if (isServer && isSsrNode(effect)) {
|
|
1524
|
+
effect.setProp(QBackRefs, new Map());
|
|
1525
|
+
}
|
|
1526
|
+
else {
|
|
1527
|
+
effect[_EFFECT_BACK_REF] = new Map();
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
const subMap = effect[_EFFECT_BACK_REF];
|
|
1531
|
+
let sub = subMap.get(prop);
|
|
1532
|
+
if (!sub) {
|
|
1533
|
+
sub = [effect, prop];
|
|
1534
|
+
subMap.set(prop, sub);
|
|
1535
|
+
}
|
|
1536
|
+
if (data) {
|
|
1537
|
+
sub[EffectSubscriptionProp.DATA] = data;
|
|
1538
|
+
}
|
|
1539
|
+
return sub;
|
|
1540
|
+
}
|
|
1541
|
+
function isSsrNode(value) {
|
|
1542
|
+
return '__brand__' in value && 'currentComponentNode' in value;
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
var TaskFlags;
|
|
1546
|
+
(function (TaskFlags) {
|
|
1547
|
+
TaskFlags[TaskFlags["VISIBLE_TASK"] = 1] = "VISIBLE_TASK";
|
|
1548
|
+
TaskFlags[TaskFlags["TASK"] = 2] = "TASK";
|
|
1549
|
+
TaskFlags[TaskFlags["RESOURCE"] = 4] = "RESOURCE";
|
|
1550
|
+
TaskFlags[TaskFlags["DIRTY"] = 8] = "DIRTY";
|
|
1551
|
+
})(TaskFlags || (TaskFlags = {}));
|
|
1552
|
+
/** @internal */
|
|
1553
|
+
const useTaskQrl = (qrl) => {
|
|
1554
|
+
const { val, set, iCtx, i } = useSequentialScope();
|
|
1555
|
+
if (val) {
|
|
1556
|
+
return;
|
|
1557
|
+
}
|
|
1558
|
+
assertQrl(qrl);
|
|
1559
|
+
set(1);
|
|
1560
|
+
const task = new Task(TaskFlags.DIRTY | TaskFlags.TASK, i, iCtx.$hostElement$, qrl, undefined, null);
|
|
1561
|
+
// In V2 we add the task to the sequential scope. We need to do this
|
|
1562
|
+
// in order to be able to retrieve it later when the parent element is
|
|
1563
|
+
// deleted and we need to be able to release the task subscriptions.
|
|
1564
|
+
set(task);
|
|
1565
|
+
const container = iCtx.$container$;
|
|
1566
|
+
const promise = container.$scheduler$(ChoreType.TASK, task);
|
|
1567
|
+
if (isPromise(promise)) {
|
|
1568
|
+
// TODO: should we handle this differently?
|
|
1569
|
+
promise.catch(() => { });
|
|
1570
|
+
}
|
|
1538
1571
|
};
|
|
1539
|
-
const
|
|
1572
|
+
const runTask = (task, container, host) => {
|
|
1540
1573
|
task.$flags$ &= ~TaskFlags.DIRTY;
|
|
1541
1574
|
cleanupTask(task);
|
|
1542
|
-
const iCtx = newInvokeContext(container.$locale$, host, undefined,
|
|
1575
|
+
const iCtx = newInvokeContext(container.$locale$, host, undefined, TaskEvent);
|
|
1543
1576
|
iCtx.$container$ = container;
|
|
1544
|
-
const taskFn = task.$qrl$.getFn(iCtx, () =>
|
|
1545
|
-
const resource = task.$state$;
|
|
1546
|
-
assertDefined(resource, 'useResource: when running a resource, "task.resource" must be a defined.', task);
|
|
1577
|
+
const taskFn = task.$qrl$.getFn(iCtx, () => clearAllEffects(container, task));
|
|
1547
1578
|
const track = (obj, prop) => {
|
|
1548
1579
|
const ctx = newInvokeContext();
|
|
1549
|
-
ctx.$effectSubscriber$ =
|
|
1580
|
+
ctx.$effectSubscriber$ = getSubscriber(task, EffectProperty.COMPONENT);
|
|
1550
1581
|
ctx.$container$ = container;
|
|
1551
1582
|
return invoke(ctx, () => {
|
|
1552
1583
|
if (isFunction(obj)) {
|
|
@@ -1559,115 +1590,85 @@ const runResource = (task, container, host) => {
|
|
|
1559
1590
|
return obj.value;
|
|
1560
1591
|
}
|
|
1561
1592
|
else {
|
|
1562
|
-
|
|
1593
|
+
throw qError(QError.trackObjectWithoutProp);
|
|
1563
1594
|
}
|
|
1564
1595
|
});
|
|
1565
1596
|
};
|
|
1566
1597
|
const handleError = (reason) => container.handleError(reason, host);
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1598
|
+
let cleanupFns = null;
|
|
1599
|
+
const cleanup = (fn) => {
|
|
1600
|
+
if (typeof fn == 'function') {
|
|
1601
|
+
if (!cleanupFns) {
|
|
1602
|
+
cleanupFns = [];
|
|
1603
|
+
task.$destroy$ = noSerialize(() => {
|
|
1604
|
+
task.$destroy$ = null;
|
|
1605
|
+
cleanupFns.forEach((fn) => {
|
|
1606
|
+
try {
|
|
1607
|
+
fn();
|
|
1608
|
+
}
|
|
1609
|
+
catch (err) {
|
|
1610
|
+
handleError(err);
|
|
1611
|
+
}
|
|
1612
|
+
});
|
|
1613
|
+
});
|
|
1575
1614
|
}
|
|
1576
|
-
|
|
1577
|
-
|
|
1615
|
+
cleanupFns.push(fn);
|
|
1616
|
+
}
|
|
1617
|
+
};
|
|
1618
|
+
const taskApi = { track, cleanup };
|
|
1619
|
+
const result = safeCall(() => taskFn(taskApi), cleanup, (err) => {
|
|
1620
|
+
// If a Promise is thrown, that means we need to re-run the task.
|
|
1621
|
+
if (isPromise(err)) {
|
|
1622
|
+
return err.then(() => runTask(task, container, host));
|
|
1623
|
+
}
|
|
1624
|
+
else {
|
|
1625
|
+
throw err;
|
|
1626
|
+
}
|
|
1578
1627
|
});
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
cache(policy) {
|
|
1588
|
-
let milliseconds = 0;
|
|
1589
|
-
if (policy === 'immutable') {
|
|
1590
|
-
milliseconds = Infinity;
|
|
1591
|
-
}
|
|
1592
|
-
else {
|
|
1593
|
-
milliseconds = policy;
|
|
1594
|
-
}
|
|
1595
|
-
resource._cache = milliseconds;
|
|
1596
|
-
},
|
|
1597
|
-
previous: resourceTarget._resolved,
|
|
1598
|
-
};
|
|
1599
|
-
let resolve;
|
|
1600
|
-
let reject;
|
|
1601
|
-
let done = false;
|
|
1602
|
-
const setState = (resolved, value) => {
|
|
1603
|
-
if (!done) {
|
|
1604
|
-
done = true;
|
|
1605
|
-
if (resolved) {
|
|
1606
|
-
done = true;
|
|
1607
|
-
resource.loading = false;
|
|
1608
|
-
resource._state = 'resolved';
|
|
1609
|
-
resource._resolved = value;
|
|
1610
|
-
resource._error = undefined;
|
|
1611
|
-
resolve(value);
|
|
1612
|
-
}
|
|
1613
|
-
else {
|
|
1614
|
-
done = true;
|
|
1615
|
-
resource.loading = false;
|
|
1616
|
-
resource._state = 'rejected';
|
|
1617
|
-
resource._error = value;
|
|
1618
|
-
reject(value);
|
|
1619
|
-
}
|
|
1620
|
-
return true;
|
|
1621
|
-
}
|
|
1622
|
-
return false;
|
|
1623
|
-
};
|
|
1624
|
-
/**
|
|
1625
|
-
* Add cleanup to resolve the resource if we are trying to run the same resource again while the
|
|
1626
|
-
* previous one is not resolved yet. The next `runResource` run will call this cleanup
|
|
1627
|
-
*/
|
|
1628
|
-
cleanups.push(() => {
|
|
1629
|
-
if (untrack(() => resource.loading) === true) {
|
|
1630
|
-
const value = untrack(() => resource._resolved);
|
|
1631
|
-
setState(true, value);
|
|
1632
|
-
}
|
|
1633
|
-
});
|
|
1634
|
-
// Execute mutation inside empty invocation
|
|
1635
|
-
invoke(iCtx, () => {
|
|
1636
|
-
// console.log('RESOURCE.pending: ');
|
|
1637
|
-
resource._state = 'pending';
|
|
1638
|
-
resource.loading = !isServerPlatform();
|
|
1639
|
-
const promise = (resource.value = new Promise((r, re) => {
|
|
1640
|
-
resolve = r;
|
|
1641
|
-
reject = re;
|
|
1642
|
-
}));
|
|
1643
|
-
promise.catch(ignoreErrorToPreventNodeFromCrashing);
|
|
1644
|
-
});
|
|
1645
|
-
const promise = safeCall(() => Promise.resolve(taskFn(opts)), (value) => {
|
|
1646
|
-
setState(true, value);
|
|
1647
|
-
}, (err) => {
|
|
1648
|
-
if (isPromise(err)) {
|
|
1649
|
-
return err.then(() => runResource(task, container, host));
|
|
1628
|
+
return result;
|
|
1629
|
+
};
|
|
1630
|
+
const cleanupTask = (task) => {
|
|
1631
|
+
const destroy = task.$destroy$;
|
|
1632
|
+
if (destroy) {
|
|
1633
|
+
task.$destroy$ = null;
|
|
1634
|
+
try {
|
|
1635
|
+
destroy();
|
|
1650
1636
|
}
|
|
1651
|
-
|
|
1652
|
-
|
|
1637
|
+
catch (err) {
|
|
1638
|
+
logError(err);
|
|
1653
1639
|
}
|
|
1654
|
-
});
|
|
1655
|
-
const timeout = resourceTarget._timeout;
|
|
1656
|
-
if (timeout > 0) {
|
|
1657
|
-
return Promise.race([
|
|
1658
|
-
promise,
|
|
1659
|
-
delay(timeout).then(() => {
|
|
1660
|
-
if (setState(false, new Error('timeout'))) {
|
|
1661
|
-
cleanupTask(task);
|
|
1662
|
-
}
|
|
1663
|
-
}),
|
|
1664
|
-
]);
|
|
1665
1640
|
}
|
|
1666
|
-
return promise;
|
|
1667
1641
|
};
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1642
|
+
class Task extends BackRef {
|
|
1643
|
+
$flags$;
|
|
1644
|
+
$index$;
|
|
1645
|
+
$el$;
|
|
1646
|
+
$qrl$;
|
|
1647
|
+
$state$;
|
|
1648
|
+
$destroy$;
|
|
1649
|
+
constructor($flags$, $index$, $el$, $qrl$, $state$, $destroy$) {
|
|
1650
|
+
super();
|
|
1651
|
+
this.$flags$ = $flags$;
|
|
1652
|
+
this.$index$ = $index$;
|
|
1653
|
+
this.$el$ = $el$;
|
|
1654
|
+
this.$qrl$ = $qrl$;
|
|
1655
|
+
this.$state$ = $state$;
|
|
1656
|
+
this.$destroy$ = $destroy$;
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
const isTask = (value) => {
|
|
1660
|
+
return value instanceof Task;
|
|
1661
|
+
};
|
|
1662
|
+
/**
|
|
1663
|
+
* Used internally as a qrl event handler to schedule a task.
|
|
1664
|
+
*
|
|
1665
|
+
* @internal
|
|
1666
|
+
*/
|
|
1667
|
+
const scheduleTask = (_event, element) => {
|
|
1668
|
+
const [task] = useLexicalScope();
|
|
1669
|
+
const type = task.$flags$ & TaskFlags.VISIBLE_TASK ? ChoreType.VISIBLE : ChoreType.TASK;
|
|
1670
|
+
const container = getDomContainer(element);
|
|
1671
|
+
container.$scheduler$(type, task);
|
|
1671
1672
|
};
|
|
1672
1673
|
|
|
1673
1674
|
/** @file Public types for the client deserialization */
|
|
@@ -1745,22 +1746,67 @@ var VirtualVNodeProps;
|
|
|
1745
1746
|
VirtualVNodeProps[VirtualVNodeProps["PROPS_OFFSET"] = 6] = "PROPS_OFFSET";
|
|
1746
1747
|
})(VirtualVNodeProps || (VirtualVNodeProps = {}));
|
|
1747
1748
|
|
|
1748
|
-
const
|
|
1749
|
+
const mapApp_findIndx = (elementVNode, key, start) => {
|
|
1750
|
+
assertTrue(start % 2 === 0, 'Expecting even number.');
|
|
1751
|
+
let bottom = start >> 1;
|
|
1752
|
+
let top = (elementVNode.length - 2) >> 1;
|
|
1753
|
+
while (bottom <= top) {
|
|
1754
|
+
const mid = bottom + ((top - bottom) >> 1);
|
|
1755
|
+
const midKey = elementVNode[mid << 1];
|
|
1756
|
+
if (midKey === key) {
|
|
1757
|
+
return mid << 1;
|
|
1758
|
+
}
|
|
1759
|
+
if (midKey < key) {
|
|
1760
|
+
bottom = mid + 1;
|
|
1761
|
+
}
|
|
1762
|
+
else {
|
|
1763
|
+
top = mid - 1;
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1766
|
+
return (bottom << 1) ^ -1;
|
|
1767
|
+
};
|
|
1768
|
+
const mapArray_set = (elementVNode, key, value, start) => {
|
|
1769
|
+
const indx = mapApp_findIndx(elementVNode, key, start);
|
|
1770
|
+
if (indx >= 0) {
|
|
1771
|
+
if (value == null) {
|
|
1772
|
+
elementVNode.splice(indx, 2);
|
|
1773
|
+
}
|
|
1774
|
+
else {
|
|
1775
|
+
elementVNode[indx + 1] = value;
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
else if (value != null) {
|
|
1779
|
+
elementVNode.splice(indx ^ -1, 0, key, value);
|
|
1780
|
+
}
|
|
1781
|
+
};
|
|
1782
|
+
const mapArray_get = (elementVNode, key, start) => {
|
|
1783
|
+
const indx = mapApp_findIndx(elementVNode, key, start);
|
|
1784
|
+
if (indx >= 0) {
|
|
1785
|
+
return elementVNode[indx + 1];
|
|
1786
|
+
}
|
|
1787
|
+
else {
|
|
1788
|
+
return null;
|
|
1789
|
+
}
|
|
1790
|
+
};
|
|
1791
|
+
|
|
1792
|
+
const isForeignObjectElement = (elementName) => {
|
|
1793
|
+
return isDev ? elementName.toLowerCase() === 'foreignobject' : elementName === 'foreignObject';
|
|
1794
|
+
};
|
|
1749
1795
|
const isSvgElement = (elementName) => elementName === 'svg' || isForeignObjectElement(elementName);
|
|
1750
1796
|
const isMathElement = (elementName) => elementName === 'math';
|
|
1751
1797
|
const vnode_isDefaultNamespace = (vnode) => {
|
|
1752
1798
|
const flags = vnode[VNodeProps.flags];
|
|
1753
1799
|
return (flags & VNodeFlags.NAMESPACE_MASK) === 0;
|
|
1754
1800
|
};
|
|
1755
|
-
const vnode_getElementNamespaceFlags = (
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1801
|
+
const vnode_getElementNamespaceFlags = (element) => {
|
|
1802
|
+
const namespace = fastNamespaceURI(element);
|
|
1803
|
+
switch (namespace) {
|
|
1804
|
+
case SVG_NS:
|
|
1805
|
+
return VNodeFlags.NS_svg;
|
|
1806
|
+
case MATH_NS:
|
|
1807
|
+
return VNodeFlags.NS_math;
|
|
1808
|
+
default:
|
|
1809
|
+
return VNodeFlags.NS_html;
|
|
1764
1810
|
}
|
|
1765
1811
|
};
|
|
1766
1812
|
function vnode_getDomChildrenWithCorrectNamespacesToInsert(journal, domParentVNode, newChild) {
|
|
@@ -2114,19 +2160,21 @@ const useOnEventsSequentialScope = () => {
|
|
|
2114
2160
|
* @returns
|
|
2115
2161
|
*/
|
|
2116
2162
|
const executeComponent = (container, renderHost, subscriptionHost, componentQRL, props) => {
|
|
2117
|
-
const iCtx = newInvokeContext(container.$locale$, subscriptionHost, undefined, RenderEvent);
|
|
2118
|
-
|
|
2119
|
-
|
|
2163
|
+
const iCtx = newInvokeContext(container.$locale$, subscriptionHost || undefined, undefined, RenderEvent);
|
|
2164
|
+
if (subscriptionHost) {
|
|
2165
|
+
iCtx.$effectSubscriber$ = getSubscriber(subscriptionHost, EffectProperty.COMPONENT);
|
|
2166
|
+
iCtx.$container$ = container;
|
|
2167
|
+
}
|
|
2120
2168
|
let componentFn;
|
|
2121
2169
|
container.ensureProjectionResolved(renderHost);
|
|
2122
2170
|
let isInlineComponent = false;
|
|
2123
2171
|
if (componentQRL === null) {
|
|
2124
|
-
componentQRL =
|
|
2172
|
+
componentQRL = container.getHostProp(renderHost, OnRenderProp);
|
|
2125
2173
|
assertDefined(componentQRL, 'No Component found at this location');
|
|
2126
2174
|
}
|
|
2127
|
-
if (isQrl(componentQRL)) {
|
|
2175
|
+
if (isQrl$1(componentQRL)) {
|
|
2128
2176
|
props = props || container.getHostProp(renderHost, ELEMENT_PROPS) || EMPTY_OBJ;
|
|
2129
|
-
if (props
|
|
2177
|
+
if (props.children) {
|
|
2130
2178
|
delete props.children;
|
|
2131
2179
|
}
|
|
2132
2180
|
componentFn = componentQRL.getFn(iCtx);
|
|
@@ -2144,18 +2192,16 @@ const executeComponent = (container, renderHost, subscriptionHost, componentQRL,
|
|
|
2144
2192
|
if (!isInlineComponent) {
|
|
2145
2193
|
container.setHostProp(renderHost, ELEMENT_SEQ_IDX, null);
|
|
2146
2194
|
container.setHostProp(renderHost, USE_ON_LOCAL_SEQ_IDX, null);
|
|
2147
|
-
|
|
2148
|
-
container.setHostProp(renderHost, ELEMENT_PROPS, props);
|
|
2149
|
-
}
|
|
2195
|
+
container.setHostProp(renderHost, ELEMENT_PROPS, props);
|
|
2150
2196
|
}
|
|
2151
2197
|
if (vnode_isVNode(renderHost)) {
|
|
2152
|
-
|
|
2198
|
+
clearAllEffects(container, renderHost);
|
|
2153
2199
|
}
|
|
2154
2200
|
return componentFn(props);
|
|
2155
2201
|
}, (jsx) => {
|
|
2156
2202
|
const useOnEvents = container.getHostProp(renderHost, USE_ON_LOCAL);
|
|
2157
2203
|
if (useOnEvents) {
|
|
2158
|
-
return
|
|
2204
|
+
return addUseOnEvents(jsx, useOnEvents);
|
|
2159
2205
|
}
|
|
2160
2206
|
return jsx;
|
|
2161
2207
|
}, (err) => {
|
|
@@ -2181,6 +2227,7 @@ const executeComponent = (container, renderHost, subscriptionHost, componentQRL,
|
|
|
2181
2227
|
*/
|
|
2182
2228
|
function addUseOnEvents(jsx, useOnEvents) {
|
|
2183
2229
|
const jsxElement = findFirstStringJSX(jsx);
|
|
2230
|
+
let jsxResult = jsx;
|
|
2184
2231
|
return maybeThen(jsxElement, (jsxElement) => {
|
|
2185
2232
|
let isInvisibleComponent = false;
|
|
2186
2233
|
if (!jsxElement) {
|
|
@@ -2199,13 +2246,15 @@ function addUseOnEvents(jsx, useOnEvents) {
|
|
|
2199
2246
|
if (Object.prototype.hasOwnProperty.call(useOnEvents, key)) {
|
|
2200
2247
|
if (isInvisibleComponent) {
|
|
2201
2248
|
if (key === 'onQvisible$') {
|
|
2202
|
-
jsxElement = addScriptNodeForInvisibleComponents(
|
|
2249
|
+
const [jsxElement, jsx] = addScriptNodeForInvisibleComponents(jsxResult);
|
|
2250
|
+
jsxResult = jsx;
|
|
2203
2251
|
if (jsxElement) {
|
|
2204
2252
|
addUseOnEvent(jsxElement, 'document:onQinit$', useOnEvents[key]);
|
|
2205
2253
|
}
|
|
2206
2254
|
}
|
|
2207
2255
|
else if (key.startsWith('document:') || key.startsWith('window:')) {
|
|
2208
|
-
jsxElement = addScriptNodeForInvisibleComponents(
|
|
2256
|
+
const [jsxElement, jsx] = addScriptNodeForInvisibleComponents(jsxResult);
|
|
2257
|
+
jsxResult = jsx;
|
|
2209
2258
|
if (jsxElement) {
|
|
2210
2259
|
addUseOnEvent(jsxElement, key, useOnEvents[key]);
|
|
2211
2260
|
}
|
|
@@ -2223,7 +2272,7 @@ function addUseOnEvents(jsx, useOnEvents) {
|
|
|
2223
2272
|
}
|
|
2224
2273
|
}
|
|
2225
2274
|
}
|
|
2226
|
-
return
|
|
2275
|
+
return jsxResult;
|
|
2227
2276
|
});
|
|
2228
2277
|
}
|
|
2229
2278
|
function addUseOnEvent(jsxElement, key, value) {
|
|
@@ -2269,6 +2318,9 @@ function addScriptNodeForInvisibleComponents(jsx) {
|
|
|
2269
2318
|
type: 'placeholder',
|
|
2270
2319
|
hidden: '',
|
|
2271
2320
|
}, null, 3);
|
|
2321
|
+
if (jsx.type === Slot) {
|
|
2322
|
+
return [jsxElement, _jsxSorted(Fragment, null, null, [jsx, jsxElement], 0, null)];
|
|
2323
|
+
}
|
|
2272
2324
|
if (jsx.children == null) {
|
|
2273
2325
|
jsx.children = jsxElement;
|
|
2274
2326
|
}
|
|
@@ -2278,15 +2330,23 @@ function addScriptNodeForInvisibleComponents(jsx) {
|
|
|
2278
2330
|
else {
|
|
2279
2331
|
jsx.children = [jsx.children, jsxElement];
|
|
2280
2332
|
}
|
|
2281
|
-
return jsxElement;
|
|
2333
|
+
return [jsxElement, jsx];
|
|
2282
2334
|
}
|
|
2283
2335
|
else if (Array.isArray(jsx) && jsx.length) {
|
|
2284
2336
|
// get first element
|
|
2285
|
-
|
|
2337
|
+
const [jsxElement, _] = addScriptNodeForInvisibleComponents(jsx[0]);
|
|
2338
|
+
return [jsxElement, jsx];
|
|
2286
2339
|
}
|
|
2287
|
-
return null;
|
|
2340
|
+
return [null, null];
|
|
2288
2341
|
}
|
|
2289
2342
|
|
|
2343
|
+
/** @internal */
|
|
2344
|
+
const _CONST_PROPS = Symbol('CONST');
|
|
2345
|
+
/** @internal */
|
|
2346
|
+
const _VAR_PROPS = Symbol('VAR');
|
|
2347
|
+
/** @internal @deprecated v1 compat */
|
|
2348
|
+
const _IMMUTABLE = Symbol('IMMUTABLE');
|
|
2349
|
+
|
|
2290
2350
|
function isSlotProp(prop) {
|
|
2291
2351
|
return !prop.startsWith('q:') && !prop.startsWith(NON_SERIALIZABLE_MARKER_PREFIX);
|
|
2292
2352
|
}
|
|
@@ -2295,12 +2355,24 @@ function isParentSlotProp(prop) {
|
|
|
2295
2355
|
}
|
|
2296
2356
|
/** @internal */
|
|
2297
2357
|
const _restProps = (props, omit, target = {}) => {
|
|
2298
|
-
|
|
2358
|
+
let constPropsTarget = null;
|
|
2359
|
+
const constProps = props[_CONST_PROPS];
|
|
2360
|
+
if (constProps) {
|
|
2361
|
+
for (const key in constProps) {
|
|
2362
|
+
if (!omit.includes(key)) {
|
|
2363
|
+
constPropsTarget ||= {};
|
|
2364
|
+
constPropsTarget[key] = constProps[key];
|
|
2365
|
+
}
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2368
|
+
const varPropsTarget = target;
|
|
2369
|
+
const varProps = props[_VAR_PROPS];
|
|
2370
|
+
for (const key in varProps) {
|
|
2299
2371
|
if (!omit.includes(key)) {
|
|
2300
|
-
|
|
2372
|
+
varPropsTarget[key] = varProps[key];
|
|
2301
2373
|
}
|
|
2302
2374
|
}
|
|
2303
|
-
return
|
|
2375
|
+
return createPropsProxy(varPropsTarget, constPropsTarget);
|
|
2304
2376
|
};
|
|
2305
2377
|
|
|
2306
2378
|
function escapeHTML(html) {
|
|
@@ -2342,17 +2414,6 @@ function escapeHTML(html) {
|
|
|
2342
2414
|
}
|
|
2343
2415
|
}
|
|
2344
2416
|
|
|
2345
|
-
function getFileLocationFromJsx(jsxDev) {
|
|
2346
|
-
if (!jsxDev) {
|
|
2347
|
-
return null;
|
|
2348
|
-
}
|
|
2349
|
-
const sanitizedFileName = jsxDev.fileName?.replace(/\\/g, '/');
|
|
2350
|
-
if (sanitizedFileName) {
|
|
2351
|
-
return `${sanitizedFileName}:${jsxDev.lineNumber}:${jsxDev.columnNumber}`;
|
|
2352
|
-
}
|
|
2353
|
-
return null;
|
|
2354
|
-
}
|
|
2355
|
-
|
|
2356
2417
|
const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
|
|
2357
2418
|
let journal = container.$journal$;
|
|
2358
2419
|
/**
|
|
@@ -2371,9 +2432,9 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
|
|
|
2371
2432
|
/// (Node can be null, if we are at the end of the list.)
|
|
2372
2433
|
let vCurrent = null;
|
|
2373
2434
|
/// When we insert new node we start it here so that we can descend into it.
|
|
2374
|
-
/// NOTE: it can't be stored in `vCurrent` because `
|
|
2435
|
+
/// NOTE: it can't be stored in `vCurrent` because `vNewNode` is in journal
|
|
2375
2436
|
/// and is not connected to the tree.
|
|
2376
|
-
let vNewNode = null;
|
|
2437
|
+
let vNewNode = null;
|
|
2377
2438
|
/// When elements have keys they can be consumed out of order and therefore we can't use nextSibling.
|
|
2378
2439
|
/// In such a case this array will contain the elements after the current location.
|
|
2379
2440
|
/// The array even indices will contains keys and odd indices the vNode.
|
|
@@ -2426,7 +2487,7 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
|
|
|
2426
2487
|
}
|
|
2427
2488
|
else if (isSignal(jsxValue)) {
|
|
2428
2489
|
if (vCurrent) {
|
|
2429
|
-
|
|
2490
|
+
clearAllEffects(container, vCurrent);
|
|
2430
2491
|
}
|
|
2431
2492
|
expectVirtual(VirtualType.WrappedSignal, null);
|
|
2432
2493
|
descend(trackSignalAndAssignHost(jsxValue, (vNewNode || vCurrent), EffectProperty.VNODE, container), true);
|
|
@@ -2641,9 +2702,10 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
|
|
|
2641
2702
|
};
|
|
2642
2703
|
const projections = [];
|
|
2643
2704
|
if (host) {
|
|
2705
|
+
const props = vnode_getProps(host);
|
|
2644
2706
|
// we need to create empty projections for all the slots to remove unused slots content
|
|
2645
|
-
for (let i =
|
|
2646
|
-
const prop =
|
|
2707
|
+
for (let i = 0; i < props.length; i = i + 2) {
|
|
2708
|
+
const prop = props[i];
|
|
2647
2709
|
if (isSlotProp(prop)) {
|
|
2648
2710
|
const slotName = prop;
|
|
2649
2711
|
projections.push(slotName);
|
|
@@ -2811,10 +2873,19 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
|
|
|
2811
2873
|
// But we need to mark them so that they don't get pulled into the diff.
|
|
2812
2874
|
const eventName = getEventNameFromJsxProp(key);
|
|
2813
2875
|
const scope = getEventNameScopeFromJsxProp(key);
|
|
2814
|
-
vnode_setProp(vNewNode, HANDLER_PREFIX + ':' + scope + ':' + eventName, value);
|
|
2815
2876
|
if (eventName) {
|
|
2877
|
+
vnode_setProp(vNewNode, HANDLER_PREFIX + ':' + scope + ':' + eventName, value);
|
|
2816
2878
|
registerQwikLoaderEvent(eventName);
|
|
2817
2879
|
}
|
|
2880
|
+
if (scope) {
|
|
2881
|
+
// add an event attr with empty value for qwikloader element selector.
|
|
2882
|
+
// We don't need value here. For ssr this value is a QRL,
|
|
2883
|
+
// but for CSR value should be just empty
|
|
2884
|
+
const htmlEvent = convertEventNameFromJsxPropToHtmlAttr(key);
|
|
2885
|
+
if (htmlEvent) {
|
|
2886
|
+
vnode_setAttr(journal, vNewNode, htmlEvent, '');
|
|
2887
|
+
}
|
|
2888
|
+
}
|
|
2818
2889
|
needsQDispatchEventPatch = true;
|
|
2819
2890
|
continue;
|
|
2820
2891
|
}
|
|
@@ -2827,12 +2898,15 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
|
|
|
2827
2898
|
value(element);
|
|
2828
2899
|
continue;
|
|
2829
2900
|
}
|
|
2901
|
+
else if (value == null) {
|
|
2902
|
+
continue;
|
|
2903
|
+
}
|
|
2830
2904
|
else {
|
|
2831
2905
|
throw qError(QError.invalidRefValue, [currentFile]);
|
|
2832
2906
|
}
|
|
2833
2907
|
}
|
|
2834
2908
|
if (isSignal(value)) {
|
|
2835
|
-
const signalData = new
|
|
2909
|
+
const signalData = new SubscriptionData({
|
|
2836
2910
|
$scopedStyleIdPrefix$: scopedStyleIdPrefix,
|
|
2837
2911
|
$isConst$: true,
|
|
2838
2912
|
});
|
|
@@ -2936,7 +3010,7 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
|
|
|
2936
3010
|
let returnValue = false;
|
|
2937
3011
|
qrls.flat(2).forEach((qrl) => {
|
|
2938
3012
|
if (qrl) {
|
|
2939
|
-
const value = qrl
|
|
3013
|
+
const value = container.$scheduler$(ChoreType.RUN_QRL, vNode, qrl, [event, element]);
|
|
2940
3014
|
returnValue = returnValue || value === true;
|
|
2941
3015
|
}
|
|
2942
3016
|
});
|
|
@@ -2948,10 +3022,10 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
|
|
|
2948
3022
|
/** @param tag Returns true if `qDispatchEvent` needs patching */
|
|
2949
3023
|
function setBulkProps(vnode, srcAttrs, currentFile) {
|
|
2950
3024
|
vnode_ensureElementInflated(vnode);
|
|
2951
|
-
const dstAttrs = vnode;
|
|
3025
|
+
const dstAttrs = vnode_getProps(vnode);
|
|
2952
3026
|
let srcIdx = 0;
|
|
2953
3027
|
const srcLength = srcAttrs.length;
|
|
2954
|
-
let dstIdx =
|
|
3028
|
+
let dstIdx = 0;
|
|
2955
3029
|
let dstLength = dstAttrs.length;
|
|
2956
3030
|
let srcKey = srcIdx < srcLength ? srcAttrs[srcIdx++] : null;
|
|
2957
3031
|
let dstKey = dstIdx < dstLength ? dstAttrs[dstIdx++] : null;
|
|
@@ -2971,12 +3045,15 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
|
|
|
2971
3045
|
value(element);
|
|
2972
3046
|
return;
|
|
2973
3047
|
}
|
|
3048
|
+
else if (value == null) {
|
|
3049
|
+
return;
|
|
3050
|
+
}
|
|
2974
3051
|
else {
|
|
2975
3052
|
throw qError(QError.invalidRefValue, [currentFile]);
|
|
2976
3053
|
}
|
|
2977
3054
|
}
|
|
2978
3055
|
if (isSignal(value)) {
|
|
2979
|
-
const signalData = new
|
|
3056
|
+
const signalData = new SubscriptionData({
|
|
2980
3057
|
$scopedStyleIdPrefix$: scopedStyleIdPrefix,
|
|
2981
3058
|
$isConst$: false,
|
|
2982
3059
|
});
|
|
@@ -2990,21 +3067,21 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
|
|
|
2990
3067
|
};
|
|
2991
3068
|
const recordJsxEvent = (key, value) => {
|
|
2992
3069
|
const eventName = getEventNameFromJsxProp(key);
|
|
3070
|
+
const scope = getEventNameScopeFromJsxProp(key);
|
|
2993
3071
|
if (eventName) {
|
|
2994
|
-
const scope = getEventNameScopeFromJsxProp(key);
|
|
2995
3072
|
record(':' + scope + ':' + eventName, value);
|
|
2996
|
-
|
|
2997
|
-
// add an event attr with empty value for qwikloader element selector.
|
|
2998
|
-
// We don't need value here. For ssr this value is a QRL,
|
|
2999
|
-
// but for CSR value should be just empty
|
|
3000
|
-
const htmlEvent = convertEventNameFromJsxPropToHtmlAttr(key);
|
|
3001
|
-
if (htmlEvent) {
|
|
3002
|
-
record(htmlEvent, '');
|
|
3003
|
-
}
|
|
3004
|
-
// register an event for qwik loader
|
|
3005
|
-
if (eventName) {
|
|
3073
|
+
// register an event for qwik loader
|
|
3006
3074
|
registerQwikLoaderEvent(eventName);
|
|
3007
3075
|
}
|
|
3076
|
+
if (scope) {
|
|
3077
|
+
// add an event attr with empty value for qwikloader element selector.
|
|
3078
|
+
// We don't need value here. For ssr this value is a QRL,
|
|
3079
|
+
// but for CSR value should be just empty
|
|
3080
|
+
const htmlEvent = convertEventNameFromJsxPropToHtmlAttr(key);
|
|
3081
|
+
if (htmlEvent) {
|
|
3082
|
+
record(htmlEvent, '');
|
|
3083
|
+
}
|
|
3084
|
+
}
|
|
3008
3085
|
};
|
|
3009
3086
|
while (srcKey !== null || dstKey !== null) {
|
|
3010
3087
|
if (dstKey?.startsWith(HANDLER_PREFIX) || dstKey?.startsWith(Q_PREFIX)) {
|
|
@@ -3200,10 +3277,6 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
|
|
|
3200
3277
|
else if (!hashesAreEqual) {
|
|
3201
3278
|
insertNewComponent(host, componentQRL, jsxProps);
|
|
3202
3279
|
if (vNewNode) {
|
|
3203
|
-
if (host) {
|
|
3204
|
-
// TODO(varixo): not sure why we need to copy flags here.
|
|
3205
|
-
vNewNode[VNodeProps.flags] = host[VNodeProps.flags];
|
|
3206
|
-
}
|
|
3207
3280
|
host = vNewNode;
|
|
3208
3281
|
shouldRender = true;
|
|
3209
3282
|
}
|
|
@@ -3256,7 +3329,7 @@ const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
|
|
|
3256
3329
|
}
|
|
3257
3330
|
function insertNewComponent(host, componentQRL, jsxProps) {
|
|
3258
3331
|
if (host) {
|
|
3259
|
-
|
|
3332
|
+
clearAllEffects(container, host);
|
|
3260
3333
|
}
|
|
3261
3334
|
vnode_insertBefore(journal, vParent, (vNewNode = vnode_newVirtual()), vCurrent && getInsertBefore());
|
|
3262
3335
|
const jsxNode = jsxValue;
|
|
@@ -3344,8 +3417,8 @@ function propsDiffer(src, dst) {
|
|
|
3344
3417
|
if (!src || !dst) {
|
|
3345
3418
|
return true;
|
|
3346
3419
|
}
|
|
3347
|
-
let srcKeys = removePropsKeys(Object.keys(src), ['children',
|
|
3348
|
-
let dstKeys = removePropsKeys(Object.keys(dst), ['children',
|
|
3420
|
+
let srcKeys = removePropsKeys(Object.keys(src), ['children', QBackRefs]);
|
|
3421
|
+
let dstKeys = removePropsKeys(Object.keys(dst), ['children', QBackRefs]);
|
|
3349
3422
|
if (srcKeys.length !== dstKeys.length) {
|
|
3350
3423
|
return true;
|
|
3351
3424
|
}
|
|
@@ -3391,7 +3464,7 @@ function cleanup(container, vNode) {
|
|
|
3391
3464
|
do {
|
|
3392
3465
|
const type = vCursor[VNodeProps.flags];
|
|
3393
3466
|
if (type & VNodeFlags.ELEMENT_OR_VIRTUAL_MASK) {
|
|
3394
|
-
|
|
3467
|
+
clearAllEffects(container, vCursor);
|
|
3395
3468
|
markVNodeAsDeleted(vCursor);
|
|
3396
3469
|
// Only elements and virtual nodes need to be traversed for children
|
|
3397
3470
|
if (type & VNodeFlags.Virtual) {
|
|
@@ -3401,7 +3474,7 @@ function cleanup(container, vNode) {
|
|
|
3401
3474
|
const obj = seq[i];
|
|
3402
3475
|
if (isTask(obj)) {
|
|
3403
3476
|
const task = obj;
|
|
3404
|
-
|
|
3477
|
+
clearAllEffects(container, task);
|
|
3405
3478
|
if (task.$flags$ & TaskFlags.VISIBLE_TASK) {
|
|
3406
3479
|
container.$scheduler$(ChoreType.CLEANUP_VISIBLE, task);
|
|
3407
3480
|
}
|
|
@@ -3416,8 +3489,8 @@ function cleanup(container, vNode) {
|
|
|
3416
3489
|
vnode_getProp(vCursor, OnRenderProp, null) !== null;
|
|
3417
3490
|
if (isComponent) {
|
|
3418
3491
|
// SPECIAL CASE: If we are a component, we need to descend into the projected content and release the content.
|
|
3419
|
-
const attrs = vCursor;
|
|
3420
|
-
for (let i =
|
|
3492
|
+
const attrs = vnode_getProps(vCursor);
|
|
3493
|
+
for (let i = 0; i < attrs.length; i = i + 2) {
|
|
3421
3494
|
const key = attrs[i];
|
|
3422
3495
|
if (!isParentSlotProp(key) && isSlotProp(key)) {
|
|
3423
3496
|
const value = attrs[i + 1];
|
|
@@ -3525,82 +3598,270 @@ var SiblingsArray;
|
|
|
3525
3598
|
SiblingsArray[SiblingsArray["NextVNode"] = 5] = "NextVNode";
|
|
3526
3599
|
})(SiblingsArray || (SiblingsArray = {}));
|
|
3527
3600
|
|
|
3528
|
-
|
|
3601
|
+
/** @internal */
|
|
3602
|
+
const useResourceQrl = (qrl, opts) => {
|
|
3603
|
+
const { val, set, i, iCtx } = useSequentialScope();
|
|
3604
|
+
if (val != null) {
|
|
3605
|
+
return val;
|
|
3606
|
+
}
|
|
3607
|
+
assertQrl(qrl);
|
|
3608
|
+
const container = iCtx.$container$;
|
|
3609
|
+
const resource = createResourceReturn(container, opts);
|
|
3610
|
+
const el = iCtx.$hostElement$;
|
|
3611
|
+
const task = new Task(TaskFlags.DIRTY | TaskFlags.RESOURCE, i, el, qrl, resource, null);
|
|
3612
|
+
container.$scheduler$(ChoreType.TASK, task);
|
|
3613
|
+
set(resource);
|
|
3614
|
+
return resource;
|
|
3615
|
+
};
|
|
3616
|
+
// <docs markdown="../readme.md#useResource">
|
|
3529
3617
|
// !!DO NOT EDIT THIS COMMENT DIRECTLY!!!
|
|
3530
|
-
// (edit
|
|
3618
|
+
// (edit ../readme.md#useResource instead and run `pnpm docs.sync`)
|
|
3531
3619
|
/**
|
|
3532
|
-
*
|
|
3620
|
+
* This method works like an async memoized function that runs whenever some tracked value changes
|
|
3621
|
+
* and returns some data.
|
|
3533
3622
|
*
|
|
3534
|
-
*
|
|
3535
|
-
*
|
|
3536
|
-
* in `$`.
|
|
3623
|
+
* `useResource` however returns immediate a `ResourceReturn` object that contains the data and a
|
|
3624
|
+
* state that indicates if the data is available or not.
|
|
3537
3625
|
*
|
|
3538
|
-
*
|
|
3539
|
-
* The former is just a shorthand for the latter.
|
|
3626
|
+
* The status can be one of the following:
|
|
3540
3627
|
*
|
|
3541
|
-
*
|
|
3628
|
+
* - `pending` - the data is not yet available.
|
|
3629
|
+
* - `resolved` - the data is available.
|
|
3630
|
+
* - `rejected` - the data is not available due to an error or timeout.
|
|
3542
3631
|
*
|
|
3543
|
-
*
|
|
3632
|
+
* Be careful when using a `try/catch` statement in `useResource$`. If you catch the error and don't
|
|
3633
|
+
* re-throw it (or a new Error), the resource status will never be `rejected`.
|
|
3544
3634
|
*
|
|
3545
|
-
*
|
|
3546
|
-
* export function myApi(callback: QRL<() => void>): void {
|
|
3547
|
-
* // ...
|
|
3548
|
-
* }
|
|
3635
|
+
* ### Example
|
|
3549
3636
|
*
|
|
3550
|
-
*
|
|
3551
|
-
*
|
|
3637
|
+
* Example showing how `useResource` to perform a fetch to request the weather, whenever the input
|
|
3638
|
+
* city name changes.
|
|
3552
3639
|
*
|
|
3553
|
-
*
|
|
3554
|
-
*
|
|
3640
|
+
* ```tsx
|
|
3641
|
+
* const Cmp = component$(() => {
|
|
3642
|
+
* const cityS = useSignal('');
|
|
3555
3643
|
*
|
|
3556
|
-
*
|
|
3557
|
-
*
|
|
3558
|
-
*
|
|
3644
|
+
* const weatherResource = useResource$(async ({ track, cleanup }) => {
|
|
3645
|
+
* const cityName = track(cityS);
|
|
3646
|
+
* const abortController = new AbortController();
|
|
3647
|
+
* cleanup(() => abortController.abort('cleanup'));
|
|
3648
|
+
* const res = await fetch(`http://weatherdata.com?city=${cityName}`, {
|
|
3649
|
+
* signal: abortController.signal,
|
|
3650
|
+
* });
|
|
3651
|
+
* const data = await res.json();
|
|
3652
|
+
* return data as { temp: number };
|
|
3653
|
+
* });
|
|
3559
3654
|
*
|
|
3560
|
-
*
|
|
3561
|
-
*
|
|
3655
|
+
* return (
|
|
3656
|
+
* <div>
|
|
3657
|
+
* <input name="city" bind:value={cityS} />
|
|
3658
|
+
* <Resource
|
|
3659
|
+
* value={weatherResource}
|
|
3660
|
+
* onResolved={(weather) => {
|
|
3661
|
+
* return <div>Temperature: {weather.temp}</div>;
|
|
3662
|
+
* }}
|
|
3663
|
+
* />
|
|
3664
|
+
* </div>
|
|
3665
|
+
* );
|
|
3666
|
+
* });
|
|
3562
3667
|
* ```
|
|
3563
3668
|
*
|
|
3564
|
-
* @param fn - A function that should have its first argument automatically `$`.
|
|
3565
3669
|
* @public
|
|
3670
|
+
* @see Resource
|
|
3671
|
+
* @see ResourceReturn
|
|
3566
3672
|
*/
|
|
3567
3673
|
// </docs>
|
|
3568
|
-
const
|
|
3569
|
-
|
|
3570
|
-
|
|
3674
|
+
const Resource = (props) => {
|
|
3675
|
+
// Resource path
|
|
3676
|
+
return _jsxSorted(Fragment, null, null, getResourceValueAsPromise(props), 0, null);
|
|
3677
|
+
};
|
|
3678
|
+
function getResourceValueAsPromise(props) {
|
|
3679
|
+
const resource = props.value;
|
|
3680
|
+
if (isResourceReturn(resource) && resource.value) {
|
|
3681
|
+
const isBrowser = !isServerPlatform();
|
|
3682
|
+
if (isBrowser) {
|
|
3683
|
+
// create a subscription for the resource._state changes
|
|
3684
|
+
const state = resource._state;
|
|
3685
|
+
if (state === 'pending' && props.onPending) {
|
|
3686
|
+
return Promise.resolve().then(useBindInvokeContext(props.onPending));
|
|
3687
|
+
}
|
|
3688
|
+
else if (state === 'rejected' && props.onRejected) {
|
|
3689
|
+
return Promise.resolve(resource._error).then(useBindInvokeContext(props.onRejected));
|
|
3690
|
+
}
|
|
3691
|
+
else {
|
|
3692
|
+
const resolvedValue = untrack(() => resource._resolved);
|
|
3693
|
+
if (resolvedValue !== undefined) {
|
|
3694
|
+
// resolved, pending without onPending prop or rejected without onRejected prop
|
|
3695
|
+
return Promise.resolve(resolvedValue).then(useBindInvokeContext(props.onResolved));
|
|
3696
|
+
}
|
|
3697
|
+
}
|
|
3698
|
+
}
|
|
3699
|
+
return resource.value.then(useBindInvokeContext(props.onResolved), useBindInvokeContext(props.onRejected));
|
|
3700
|
+
}
|
|
3701
|
+
else if (isPromise(resource)) {
|
|
3702
|
+
return resource.then(useBindInvokeContext(props.onResolved), useBindInvokeContext(props.onRejected));
|
|
3703
|
+
}
|
|
3704
|
+
else if (isSignal(resource)) {
|
|
3705
|
+
return Promise.resolve(resource.value).then(useBindInvokeContext(props.onResolved), useBindInvokeContext(props.onRejected));
|
|
3706
|
+
}
|
|
3707
|
+
else {
|
|
3708
|
+
return Promise.resolve(resource).then(useBindInvokeContext(props.onResolved), useBindInvokeContext(props.onRejected));
|
|
3709
|
+
}
|
|
3710
|
+
}
|
|
3711
|
+
const _createResourceReturn = (opts) => {
|
|
3712
|
+
const resource = {
|
|
3713
|
+
__brand: 'resource',
|
|
3714
|
+
value: undefined,
|
|
3715
|
+
loading: isServerPlatform() ? false : true,
|
|
3716
|
+
_resolved: undefined,
|
|
3717
|
+
_error: undefined,
|
|
3718
|
+
_state: 'pending',
|
|
3719
|
+
_timeout: opts?.timeout ?? -1,
|
|
3720
|
+
_cache: 0,
|
|
3571
3721
|
};
|
|
3722
|
+
return resource;
|
|
3572
3723
|
};
|
|
3573
|
-
|
|
3574
|
-
const
|
|
3575
|
-
|
|
3724
|
+
const createResourceReturn = (container, opts, initialPromise) => {
|
|
3725
|
+
const result = _createResourceReturn(opts);
|
|
3726
|
+
result.value = initialPromise;
|
|
3727
|
+
return createStore(container, result, StoreFlags.RECURSIVE);
|
|
3576
3728
|
};
|
|
3577
|
-
const
|
|
3578
|
-
|
|
3579
|
-
|
|
3729
|
+
const isResourceReturn = (obj) => {
|
|
3730
|
+
return isObject(obj) && (getStoreTarget(obj) || obj).__brand === 'resource';
|
|
3731
|
+
};
|
|
3732
|
+
const runResource = (task, container, host) => {
|
|
3733
|
+
task.$flags$ &= ~TaskFlags.DIRTY;
|
|
3734
|
+
cleanupTask(task);
|
|
3735
|
+
const iCtx = newInvokeContext(container.$locale$, host, undefined, ResourceEvent);
|
|
3736
|
+
iCtx.$container$ = container;
|
|
3737
|
+
const taskFn = task.$qrl$.getFn(iCtx, () => clearAllEffects(container, task));
|
|
3738
|
+
const resource = task.$state$;
|
|
3739
|
+
assertDefined(resource, 'useResource: when running a resource, "task.resource" must be a defined.', task);
|
|
3740
|
+
const track = (obj, prop) => {
|
|
3741
|
+
const ctx = newInvokeContext();
|
|
3742
|
+
ctx.$effectSubscriber$ = getSubscriber(task, EffectProperty.COMPONENT);
|
|
3743
|
+
ctx.$container$ = container;
|
|
3744
|
+
return invoke(ctx, () => {
|
|
3745
|
+
if (isFunction(obj)) {
|
|
3746
|
+
return obj();
|
|
3747
|
+
}
|
|
3748
|
+
if (prop) {
|
|
3749
|
+
return obj[prop];
|
|
3750
|
+
}
|
|
3751
|
+
else if (isSignal(obj)) {
|
|
3752
|
+
return obj.value;
|
|
3753
|
+
}
|
|
3754
|
+
else {
|
|
3755
|
+
return obj;
|
|
3756
|
+
}
|
|
3757
|
+
});
|
|
3758
|
+
};
|
|
3759
|
+
const handleError = (reason) => container.handleError(reason, host);
|
|
3760
|
+
const cleanups = [];
|
|
3761
|
+
task.$destroy$ = noSerialize(() => {
|
|
3762
|
+
cleanups.forEach((fn) => {
|
|
3763
|
+
try {
|
|
3764
|
+
fn();
|
|
3765
|
+
}
|
|
3766
|
+
catch (err) {
|
|
3767
|
+
handleError(err);
|
|
3768
|
+
}
|
|
3769
|
+
});
|
|
3770
|
+
done = true;
|
|
3771
|
+
});
|
|
3772
|
+
const resourceTarget = unwrapStore(resource);
|
|
3773
|
+
const opts = {
|
|
3774
|
+
track,
|
|
3775
|
+
cleanup(fn) {
|
|
3776
|
+
if (typeof fn === 'function') {
|
|
3777
|
+
cleanups.push(fn);
|
|
3778
|
+
}
|
|
3779
|
+
},
|
|
3780
|
+
cache(policy) {
|
|
3781
|
+
let milliseconds = 0;
|
|
3782
|
+
if (policy === 'immutable') {
|
|
3783
|
+
milliseconds = Infinity;
|
|
3784
|
+
}
|
|
3785
|
+
else {
|
|
3786
|
+
milliseconds = policy;
|
|
3787
|
+
}
|
|
3788
|
+
resource._cache = milliseconds;
|
|
3789
|
+
},
|
|
3790
|
+
previous: resourceTarget._resolved,
|
|
3791
|
+
};
|
|
3792
|
+
let resolve;
|
|
3793
|
+
let reject;
|
|
3794
|
+
let done = false;
|
|
3795
|
+
const setState = (resolved, value) => {
|
|
3796
|
+
if (!done) {
|
|
3797
|
+
done = true;
|
|
3798
|
+
if (resolved) {
|
|
3799
|
+
done = true;
|
|
3800
|
+
resource.loading = false;
|
|
3801
|
+
resource._state = 'resolved';
|
|
3802
|
+
resource._resolved = value;
|
|
3803
|
+
resource._error = undefined;
|
|
3804
|
+
resolve(value);
|
|
3805
|
+
}
|
|
3806
|
+
else {
|
|
3807
|
+
done = true;
|
|
3808
|
+
resource.loading = false;
|
|
3809
|
+
resource._state = 'rejected';
|
|
3810
|
+
resource._error = value;
|
|
3811
|
+
reject(value);
|
|
3812
|
+
}
|
|
3813
|
+
return true;
|
|
3814
|
+
}
|
|
3815
|
+
return false;
|
|
3816
|
+
};
|
|
3817
|
+
/**
|
|
3818
|
+
* Add cleanup to resolve the resource if we are trying to run the same resource again while the
|
|
3819
|
+
* previous one is not resolved yet. The next `runResource` run will call this cleanup
|
|
3820
|
+
*/
|
|
3821
|
+
cleanups.push(() => {
|
|
3822
|
+
if (untrack(() => resource.loading) === true) {
|
|
3823
|
+
const value = untrack(() => resource._resolved);
|
|
3824
|
+
setState(true, value);
|
|
3825
|
+
}
|
|
3826
|
+
});
|
|
3827
|
+
// Execute mutation inside empty invocation
|
|
3828
|
+
invoke(iCtx, () => {
|
|
3829
|
+
// console.log('RESOURCE.pending: ');
|
|
3830
|
+
resource._state = 'pending';
|
|
3831
|
+
resource.loading = !isServerPlatform();
|
|
3832
|
+
const promise = (resource.value = new Promise((r, re) => {
|
|
3833
|
+
resolve = r;
|
|
3834
|
+
reject = re;
|
|
3835
|
+
}));
|
|
3836
|
+
promise.catch(ignoreErrorToPreventNodeFromCrashing);
|
|
3837
|
+
});
|
|
3838
|
+
const promise = safeCall(() => Promise.resolve(taskFn(opts)), (value) => {
|
|
3839
|
+
setState(true, value);
|
|
3840
|
+
}, (err) => {
|
|
3841
|
+
if (isPromise(err)) {
|
|
3842
|
+
return err.then(() => runResource(task, container, host));
|
|
3843
|
+
}
|
|
3844
|
+
else {
|
|
3845
|
+
setState(false, err);
|
|
3846
|
+
}
|
|
3847
|
+
});
|
|
3848
|
+
const timeout = resourceTarget._timeout;
|
|
3849
|
+
if (timeout > 0) {
|
|
3850
|
+
return Promise.race([
|
|
3851
|
+
promise,
|
|
3852
|
+
delay(timeout).then(() => {
|
|
3853
|
+
if (setState(false, new Error('timeout'))) {
|
|
3854
|
+
cleanupTask(task);
|
|
3855
|
+
}
|
|
3856
|
+
}),
|
|
3857
|
+
]);
|
|
3858
|
+
}
|
|
3859
|
+
return promise;
|
|
3860
|
+
};
|
|
3861
|
+
const ignoreErrorToPreventNodeFromCrashing = (err) => {
|
|
3862
|
+
// ignore error to prevent node from crashing
|
|
3863
|
+
// node will crash in promise is rejected and no one is listening to the rejection.
|
|
3580
3864
|
};
|
|
3581
|
-
|
|
3582
|
-
/**
|
|
3583
|
-
* Creates a Signal with the given value. If no value is given, the signal is created with
|
|
3584
|
-
* `undefined`.
|
|
3585
|
-
*
|
|
3586
|
-
* @public
|
|
3587
|
-
*/
|
|
3588
|
-
const createSignal = createSignal$1;
|
|
3589
|
-
/** @internal */
|
|
3590
|
-
const createComputedQrl = createComputedSignal;
|
|
3591
|
-
/**
|
|
3592
|
-
* Create a computed signal which is calculated from the given QRL. A computed signal is a signal
|
|
3593
|
-
* which is calculated from other signals. When the signals change, the computed signal is
|
|
3594
|
-
* recalculated.
|
|
3595
|
-
*
|
|
3596
|
-
* The QRL must be a function which returns the value of the signal. The function must not have side
|
|
3597
|
-
* effects, and it mus be synchronous.
|
|
3598
|
-
*
|
|
3599
|
-
* If you need the function to be async, use `useSignal` and `useTask$` instead.
|
|
3600
|
-
*
|
|
3601
|
-
* @public
|
|
3602
|
-
*/
|
|
3603
|
-
const createComputed$ = /*#__PURE__*/ implicit$FirstArg(createComputedQrl);
|
|
3604
3865
|
|
|
3605
3866
|
/// These global variables are used to avoid creating new arrays for each call to `vnode_documentPosition`.
|
|
3606
3867
|
const aVNodePath = [];
|
|
@@ -3785,38 +4046,29 @@ const ssrNodeDocumentPosition = (a, b) => {
|
|
|
3785
4046
|
* - Visible Tasks are sorted afterJournalFlush, than depth first on component and finally in
|
|
3786
4047
|
* declaration order within component.
|
|
3787
4048
|
*/
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
ChoreType[ChoreType["MICRO"] = 15] = "MICRO";
|
|
3794
|
-
/** Ensure tha the QRL promise is resolved before processing next chores in the queue */
|
|
3795
|
-
ChoreType[ChoreType["QRL_RESOLVE"] = 1] = "QRL_RESOLVE";
|
|
3796
|
-
ChoreType[ChoreType["RESOURCE"] = 2] = "RESOURCE";
|
|
3797
|
-
ChoreType[ChoreType["TASK"] = 3] = "TASK";
|
|
3798
|
-
ChoreType[ChoreType["NODE_DIFF"] = 4] = "NODE_DIFF";
|
|
3799
|
-
ChoreType[ChoreType["NODE_PROP"] = 5] = "NODE_PROP";
|
|
3800
|
-
ChoreType[ChoreType["COMPONENT_SSR"] = 6] = "COMPONENT_SSR";
|
|
3801
|
-
ChoreType[ChoreType["COMPONENT"] = 7] = "COMPONENT";
|
|
3802
|
-
ChoreType[ChoreType["RECOMPUTE_AND_SCHEDULE_EFFECTS"] = 8] = "RECOMPUTE_AND_SCHEDULE_EFFECTS";
|
|
3803
|
-
ChoreType[ChoreType["JOURNAL_FLUSH"] = 16] = "JOURNAL_FLUSH";
|
|
3804
|
-
ChoreType[ChoreType["VISIBLE"] = 32] = "VISIBLE";
|
|
3805
|
-
ChoreType[ChoreType["CLEANUP_VISIBLE"] = 48] = "CLEANUP_VISIBLE";
|
|
3806
|
-
ChoreType[ChoreType["WAIT_FOR_ALL"] = 255] = "WAIT_FOR_ALL";
|
|
3807
|
-
})(ChoreType || (ChoreType = {}));
|
|
4049
|
+
// Turn this on to get debug output of what the scheduler is doing.
|
|
4050
|
+
const DEBUG$1 = false;
|
|
4051
|
+
const getPromise = (chore) => (chore.$promise$ ||= new Promise((resolve) => {
|
|
4052
|
+
chore.$resolve$ = resolve;
|
|
4053
|
+
}));
|
|
3808
4054
|
const createScheduler = (container, scheduleDrain, journalFlush) => {
|
|
3809
4055
|
const choreQueue = [];
|
|
4056
|
+
const qrlRuns = [];
|
|
3810
4057
|
let currentChore = null;
|
|
3811
|
-
let
|
|
4058
|
+
let drainScheduled = false;
|
|
3812
4059
|
return schedule;
|
|
3813
4060
|
///// IMPLEMENTATION /////
|
|
3814
4061
|
function schedule(type, hostOrTask = null, targetOrQrl = null, payload = null) {
|
|
3815
|
-
const
|
|
3816
|
-
const
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
4062
|
+
const isServer = !isDomContainer(container);
|
|
4063
|
+
const isComponentSsr = isServer && type === ChoreType.COMPONENT;
|
|
4064
|
+
const runLater = type !== ChoreType.WAIT_FOR_ALL && !isComponentSsr && type !== ChoreType.RUN_QRL;
|
|
4065
|
+
const isTask = type === ChoreType.TASK || type === ChoreType.VISIBLE || type === ChoreType.CLEANUP_VISIBLE;
|
|
4066
|
+
const isClientOnly = type === ChoreType.JOURNAL_FLUSH ||
|
|
4067
|
+
type === ChoreType.NODE_DIFF ||
|
|
4068
|
+
type === ChoreType.NODE_PROP;
|
|
4069
|
+
if (isServer && isClientOnly) {
|
|
4070
|
+
return;
|
|
4071
|
+
}
|
|
3820
4072
|
if (isTask) {
|
|
3821
4073
|
hostOrTask.$flags$ |= TaskFlags.DIRTY;
|
|
3822
4074
|
}
|
|
@@ -3835,192 +4087,234 @@ const createScheduler = (container, scheduleDrain, journalFlush) => {
|
|
|
3835
4087
|
$returnValue$: null,
|
|
3836
4088
|
$executed$: false,
|
|
3837
4089
|
};
|
|
3838
|
-
chore.$promise$ = new Promise((resolve) => (chore.$resolve$ = resolve));
|
|
3839
4090
|
chore = sortedInsert(choreQueue, chore, container.rootVNode || null);
|
|
3840
|
-
if (!
|
|
4091
|
+
if (!drainScheduled && runLater) {
|
|
3841
4092
|
// If we are not currently draining, we need to schedule a drain.
|
|
3842
|
-
|
|
4093
|
+
drainScheduled = true;
|
|
3843
4094
|
schedule(ChoreType.JOURNAL_FLUSH);
|
|
3844
|
-
|
|
4095
|
+
// Catch here to avoid unhandled promise rejection
|
|
4096
|
+
scheduleDrain()?.catch?.(() => { });
|
|
3845
4097
|
}
|
|
4098
|
+
// TODO figure out what to do with chore errors
|
|
3846
4099
|
if (runLater) {
|
|
3847
|
-
return chore
|
|
4100
|
+
return getPromise(chore);
|
|
3848
4101
|
}
|
|
3849
4102
|
else {
|
|
3850
|
-
return drainUpTo(chore,
|
|
4103
|
+
return drainUpTo(chore, isServer);
|
|
3851
4104
|
}
|
|
3852
4105
|
}
|
|
3853
|
-
/**
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
* @param runUptoChore
|
|
3857
|
-
*/
|
|
3858
|
-
function drainUpTo(runUptoChore, rootVNode) {
|
|
3859
|
-
// If it already ran, it's not in the queue
|
|
3860
|
-
if (runUptoChore.$executed$) {
|
|
3861
|
-
return runUptoChore.$returnValue$;
|
|
3862
|
-
}
|
|
3863
|
-
if (currentChore) {
|
|
3864
|
-
// Already running chore, which means we're waiting for async completion
|
|
3865
|
-
return runUptoChore.$promise$;
|
|
3866
|
-
}
|
|
4106
|
+
/** Execute all of the chores up to and including the given chore. */
|
|
4107
|
+
function drainUpTo(runUptoChore, isServer) {
|
|
4108
|
+
let maxRetries = 5000;
|
|
3867
4109
|
while (choreQueue.length) {
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
if (order === null) {
|
|
3871
|
-
continue;
|
|
4110
|
+
if (maxRetries-- < 0) {
|
|
4111
|
+
throw new Error('drainUpTo: max retries reached');
|
|
3872
4112
|
}
|
|
3873
|
-
if (
|
|
3874
|
-
//
|
|
3875
|
-
|
|
4113
|
+
if (currentChore) {
|
|
4114
|
+
// Already running chore, which means we're waiting for async completion
|
|
4115
|
+
return getPromise(currentChore)
|
|
4116
|
+
.then(() => drainUpTo(runUptoChore, isServer))
|
|
4117
|
+
.catch((e) => {
|
|
4118
|
+
container.handleError(e, currentChore?.$host$);
|
|
4119
|
+
});
|
|
4120
|
+
}
|
|
4121
|
+
const nextChore = choreQueue[0];
|
|
4122
|
+
if (nextChore.$executed$) {
|
|
4123
|
+
choreQueue.shift();
|
|
4124
|
+
if (nextChore === runUptoChore) {
|
|
4125
|
+
break;
|
|
4126
|
+
}
|
|
4127
|
+
continue;
|
|
3876
4128
|
}
|
|
3877
|
-
|
|
3878
|
-
if (isDeletedVNode &&
|
|
4129
|
+
if (vNodeAlreadyDeleted(nextChore) &&
|
|
3879
4130
|
// we need to process cleanup tasks for deleted nodes
|
|
3880
4131
|
nextChore.$type$ !== ChoreType.CLEANUP_VISIBLE) {
|
|
4132
|
+
choreQueue.shift();
|
|
3881
4133
|
continue;
|
|
3882
4134
|
}
|
|
3883
|
-
|
|
3884
|
-
if (isPromise(returnValue)) {
|
|
3885
|
-
const promise = returnValue.then(() => drainUpTo(runUptoChore, rootVNode));
|
|
3886
|
-
return promise;
|
|
3887
|
-
}
|
|
4135
|
+
executeChore(nextChore, isServer);
|
|
3888
4136
|
}
|
|
3889
4137
|
return runUptoChore.$returnValue$;
|
|
3890
4138
|
}
|
|
3891
|
-
function executeChore(chore) {
|
|
4139
|
+
function executeChore(chore, isServer) {
|
|
3892
4140
|
const host = chore.$host$;
|
|
3893
4141
|
assertEqual(currentChore, null, 'Chore already running.');
|
|
3894
4142
|
currentChore = chore;
|
|
3895
4143
|
let returnValue = null;
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
returnValue = safeCall(() => executeComponent(container, host, host, chore.$target$, chore.$payload$), (jsx) => {
|
|
3904
|
-
if (chore.$type$ === ChoreType.COMPONENT) {
|
|
3905
|
-
const styleScopedId = container.getHostProp(host, QScopedStyle);
|
|
3906
|
-
return retryOnPromise(() => vnode_diff(container, jsx, host, addComponentStylePrefix(styleScopedId)));
|
|
4144
|
+
try {
|
|
4145
|
+
switch (chore.$type$) {
|
|
4146
|
+
case ChoreType.WAIT_FOR_ALL:
|
|
4147
|
+
{
|
|
4148
|
+
if (isServer) {
|
|
4149
|
+
drainScheduled = false;
|
|
4150
|
+
}
|
|
3907
4151
|
}
|
|
3908
|
-
|
|
3909
|
-
|
|
4152
|
+
break;
|
|
4153
|
+
case ChoreType.JOURNAL_FLUSH:
|
|
4154
|
+
{
|
|
4155
|
+
returnValue = journalFlush();
|
|
4156
|
+
drainScheduled = false;
|
|
4157
|
+
}
|
|
4158
|
+
break;
|
|
4159
|
+
case ChoreType.COMPONENT:
|
|
4160
|
+
{
|
|
4161
|
+
returnValue = safeCall(() => executeComponent(container, host, host, chore.$target$, chore.$payload$), (jsx) => {
|
|
4162
|
+
if (isServer) {
|
|
4163
|
+
return jsx;
|
|
4164
|
+
}
|
|
4165
|
+
else {
|
|
4166
|
+
const styleScopedId = container.getHostProp(host, QScopedStyle);
|
|
4167
|
+
return retryOnPromise(() => vnode_diff(container, jsx, host, addComponentStylePrefix(styleScopedId)));
|
|
4168
|
+
}
|
|
4169
|
+
}, (err) => container.handleError(err, host));
|
|
4170
|
+
}
|
|
4171
|
+
break;
|
|
4172
|
+
case ChoreType.RUN_QRL:
|
|
4173
|
+
{
|
|
4174
|
+
const fn = chore.$target$.getFn();
|
|
4175
|
+
const result = retryOnPromise(() => fn(...chore.$payload$));
|
|
4176
|
+
if (isPromise(result)) {
|
|
4177
|
+
const handled = result
|
|
4178
|
+
.finally(() => {
|
|
4179
|
+
qrlRuns.splice(qrlRuns.indexOf(handled), 1);
|
|
4180
|
+
})
|
|
4181
|
+
.catch((error) => {
|
|
4182
|
+
container.handleError(error, chore.$host$);
|
|
4183
|
+
});
|
|
4184
|
+
// Don't wait for the promise to resolve
|
|
4185
|
+
// TODO come up with a better solution, we also want concurrent signal handling with tasks but serial tasks
|
|
4186
|
+
qrlRuns.push(handled);
|
|
4187
|
+
DEBUG$1 &&
|
|
4188
|
+
debugTrace('execute.DONE (but still running)', chore, currentChore, choreQueue);
|
|
4189
|
+
chore.$returnValue$ = handled;
|
|
4190
|
+
chore.$resolve$?.(handled);
|
|
4191
|
+
currentChore = null;
|
|
4192
|
+
chore.$executed$ = true;
|
|
4193
|
+
// early out so we don't call after()
|
|
4194
|
+
return;
|
|
4195
|
+
}
|
|
4196
|
+
returnValue = null;
|
|
4197
|
+
}
|
|
4198
|
+
break;
|
|
4199
|
+
case ChoreType.TASK:
|
|
4200
|
+
case ChoreType.VISIBLE:
|
|
4201
|
+
{
|
|
4202
|
+
const payload = chore.$payload$;
|
|
4203
|
+
if (payload.$flags$ & TaskFlags.RESOURCE) {
|
|
4204
|
+
const result = runResource(payload, container, host);
|
|
4205
|
+
// Don't await the return value of the resource, because async resources should not be awaited.
|
|
4206
|
+
// The reason for this is that we should be able to update for example a node with loading
|
|
4207
|
+
// text. If we await the resource, the loading text will not be displayed until the resource
|
|
4208
|
+
// is loaded.
|
|
4209
|
+
// Awaiting on the client also causes a deadlock.
|
|
4210
|
+
// In any case, the resource will never throw.
|
|
4211
|
+
returnValue = isServer ? result : null;
|
|
4212
|
+
}
|
|
4213
|
+
else {
|
|
4214
|
+
returnValue = runTask(payload, container, host);
|
|
4215
|
+
}
|
|
4216
|
+
}
|
|
4217
|
+
break;
|
|
4218
|
+
case ChoreType.CLEANUP_VISIBLE:
|
|
4219
|
+
{
|
|
4220
|
+
const task = chore.$payload$;
|
|
4221
|
+
cleanupTask(task);
|
|
4222
|
+
}
|
|
4223
|
+
break;
|
|
4224
|
+
case ChoreType.NODE_DIFF:
|
|
4225
|
+
{
|
|
4226
|
+
const parentVirtualNode = chore.$target$;
|
|
4227
|
+
let jsx = chore.$payload$;
|
|
4228
|
+
if (isSignal(jsx)) {
|
|
4229
|
+
jsx = jsx.value;
|
|
4230
|
+
}
|
|
4231
|
+
returnValue = retryOnPromise(() => vnode_diff(container, jsx, parentVirtualNode, null));
|
|
4232
|
+
}
|
|
4233
|
+
break;
|
|
4234
|
+
case ChoreType.NODE_PROP:
|
|
4235
|
+
{
|
|
4236
|
+
const virtualNode = chore.$host$;
|
|
4237
|
+
const payload = chore.$payload$;
|
|
4238
|
+
let value = payload.$value$;
|
|
4239
|
+
if (isSignal(value)) {
|
|
4240
|
+
value = value.value;
|
|
4241
|
+
}
|
|
4242
|
+
const isConst = payload.$isConst$;
|
|
4243
|
+
const journal = container.$journal$;
|
|
4244
|
+
const property = chore.$idx$;
|
|
4245
|
+
const serializedValue = serializeAttribute(property, value, payload.$scopedStyleIdPrefix$);
|
|
4246
|
+
if (isConst) {
|
|
4247
|
+
const element = virtualNode[ElementVNodeProps.element];
|
|
4248
|
+
journal.push(VNodeJournalOpCode.SetAttribute, element, property, serializedValue);
|
|
4249
|
+
}
|
|
4250
|
+
else {
|
|
4251
|
+
vnode_setAttr(journal, virtualNode, property, serializedValue);
|
|
4252
|
+
}
|
|
4253
|
+
}
|
|
4254
|
+
break;
|
|
4255
|
+
case ChoreType.QRL_RESOLVE: {
|
|
4256
|
+
{
|
|
4257
|
+
const target = chore.$target$;
|
|
4258
|
+
returnValue = !target.resolved ? target.resolve() : null;
|
|
3910
4259
|
}
|
|
3911
|
-
}, (err) => container.handleError(err, host));
|
|
3912
|
-
break;
|
|
3913
|
-
case ChoreType.RESOURCE:
|
|
3914
|
-
// Don't await the return value of the resource, because async resources should not be awaited.
|
|
3915
|
-
// The reason for this is that we should be able to update for example a node with loading
|
|
3916
|
-
// text. If we await the resource, the loading text will not be displayed until the resource
|
|
3917
|
-
// is loaded.
|
|
3918
|
-
const result = runResource(chore.$payload$, container, host);
|
|
3919
|
-
returnValue = isDomContainer(container) ? null : result;
|
|
3920
|
-
break;
|
|
3921
|
-
case ChoreType.TASK:
|
|
3922
|
-
returnValue = runTask(chore.$payload$, container, host);
|
|
3923
|
-
break;
|
|
3924
|
-
case ChoreType.VISIBLE:
|
|
3925
|
-
returnValue = runTask(chore.$payload$, container, host);
|
|
3926
|
-
break;
|
|
3927
|
-
case ChoreType.CLEANUP_VISIBLE:
|
|
3928
|
-
const task = chore.$payload$;
|
|
3929
|
-
cleanupTask(task);
|
|
3930
|
-
break;
|
|
3931
|
-
case ChoreType.NODE_DIFF:
|
|
3932
|
-
const parentVirtualNode = chore.$target$;
|
|
3933
|
-
let jsx = chore.$payload$;
|
|
3934
|
-
if (isSignal(jsx)) {
|
|
3935
|
-
jsx = jsx.value;
|
|
3936
|
-
}
|
|
3937
|
-
returnValue = retryOnPromise(() => vnode_diff(container, jsx, parentVirtualNode, null));
|
|
3938
|
-
break;
|
|
3939
|
-
case ChoreType.NODE_PROP:
|
|
3940
|
-
const virtualNode = chore.$host$;
|
|
3941
|
-
const payload = chore.$payload$;
|
|
3942
|
-
let value = payload.$value$;
|
|
3943
|
-
if (isSignal(value)) {
|
|
3944
|
-
value = value.value;
|
|
3945
|
-
}
|
|
3946
|
-
const isConst = payload.$isConst$;
|
|
3947
|
-
const journal = container.$journal$;
|
|
3948
|
-
const property = chore.$idx$;
|
|
3949
|
-
const serializedValue = serializeAttribute(property, value, payload.$scopedStyleIdPrefix$);
|
|
3950
|
-
if (isConst) {
|
|
3951
|
-
const element = virtualNode[ElementVNodeProps.element];
|
|
3952
|
-
journal.push(VNodeJournalOpCode.SetAttribute, element, property, serializedValue);
|
|
3953
|
-
}
|
|
3954
|
-
else {
|
|
3955
|
-
vnode_setAttr(journal, virtualNode, property, serializedValue);
|
|
3956
|
-
}
|
|
3957
|
-
break;
|
|
3958
|
-
case ChoreType.QRL_RESOLVE: {
|
|
3959
|
-
const target = chore.$target$;
|
|
3960
|
-
returnValue = !target.resolved ? target.resolve() : null;
|
|
3961
|
-
break;
|
|
3962
|
-
}
|
|
3963
|
-
case ChoreType.RECOMPUTE_AND_SCHEDULE_EFFECTS: {
|
|
3964
|
-
const target = chore.$target$;
|
|
3965
|
-
const forceRunEffects = target.$forceRunEffects$;
|
|
3966
|
-
target.$forceRunEffects$ = false;
|
|
3967
|
-
if (!target.$effects$?.length) {
|
|
3968
4260
|
break;
|
|
3969
4261
|
}
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
4262
|
+
case ChoreType.RECOMPUTE_AND_SCHEDULE_EFFECTS: {
|
|
4263
|
+
{
|
|
4264
|
+
const target = chore.$target$;
|
|
4265
|
+
const forceRunEffects = target.$forceRunEffects$;
|
|
4266
|
+
target.$forceRunEffects$ = false;
|
|
4267
|
+
if (!target.$effects$?.size) {
|
|
4268
|
+
break;
|
|
4269
|
+
}
|
|
4270
|
+
returnValue = retryOnPromise(() => {
|
|
4271
|
+
if (target.$computeIfNeeded$() || forceRunEffects) {
|
|
4272
|
+
triggerEffects(container, target, target.$effects$);
|
|
4273
|
+
}
|
|
4274
|
+
});
|
|
3973
4275
|
}
|
|
3974
|
-
|
|
3975
|
-
|
|
4276
|
+
break;
|
|
4277
|
+
}
|
|
3976
4278
|
}
|
|
3977
4279
|
}
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
}
|
|
4280
|
+
catch (e) {
|
|
4281
|
+
returnValue = Promise.reject(e);
|
|
4282
|
+
}
|
|
4283
|
+
const after = (value, error) => {
|
|
3983
4284
|
currentChore = null;
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
}
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
}
|
|
4001
|
-
function vNodeAlreadyDeleted(chore) {
|
|
4002
|
-
return !!(chore.$host$ &&
|
|
4003
|
-
vnode_isVNode(chore.$host$) &&
|
|
4004
|
-
chore.$host$[VNodeProps.flags] & VNodeFlags.Deleted);
|
|
4005
|
-
}
|
|
4006
|
-
/**
|
|
4007
|
-
* Compares two chores to determine their execution order in the scheduler's queue.
|
|
4008
|
-
*
|
|
4009
|
-
* @param a - The first chore to compare
|
|
4010
|
-
* @param b - The second chore to compare
|
|
4011
|
-
* @returns A number indicating the relative order of the chores. A negative number means `a` runs
|
|
4012
|
-
* before `b`.
|
|
4013
|
-
*/
|
|
4014
|
-
function choreComparator(a, b, rootVNode) {
|
|
4015
|
-
const macroTypeDiff = (a.$type$ & ChoreType.MACRO) - (b.$type$ & ChoreType.MACRO);
|
|
4016
|
-
if (macroTypeDiff !== 0) {
|
|
4017
|
-
return macroTypeDiff;
|
|
4285
|
+
chore.$executed$ = true;
|
|
4286
|
+
if (error) {
|
|
4287
|
+
container.handleError(error, host);
|
|
4288
|
+
}
|
|
4289
|
+
else {
|
|
4290
|
+
chore.$returnValue$ = value;
|
|
4291
|
+
chore.$resolve$?.(value);
|
|
4292
|
+
}
|
|
4293
|
+
};
|
|
4294
|
+
if (isPromise(returnValue)) {
|
|
4295
|
+
chore.$promise$ = returnValue.then(after, (error) => after(undefined, error));
|
|
4296
|
+
chore.$resolve$?.(chore.$promise$);
|
|
4297
|
+
chore.$resolve$ = undefined;
|
|
4298
|
+
}
|
|
4299
|
+
else {
|
|
4300
|
+
after(returnValue);
|
|
4301
|
+
}
|
|
4018
4302
|
}
|
|
4019
|
-
|
|
4020
|
-
|
|
4303
|
+
/**
|
|
4304
|
+
* Compares two chores to determine their execution order in the scheduler's queue.
|
|
4305
|
+
*
|
|
4306
|
+
* @param a - The first chore to compare
|
|
4307
|
+
* @param b - The second chore to compare
|
|
4308
|
+
* @returns A number indicating the relative order of the chores. A negative number means `a` runs
|
|
4309
|
+
* before `b`.
|
|
4310
|
+
*/
|
|
4311
|
+
function choreComparator(a, b, rootVNode) {
|
|
4312
|
+
const macroTypeDiff = (a.$type$ & ChoreType.MACRO) - (b.$type$ & ChoreType.MACRO);
|
|
4313
|
+
if (macroTypeDiff !== 0) {
|
|
4314
|
+
return macroTypeDiff;
|
|
4315
|
+
}
|
|
4021
4316
|
const aHost = a.$host$;
|
|
4022
4317
|
const bHost = b.$host$;
|
|
4023
|
-
// QRL_RESOLVE does not have a host.
|
|
4024
4318
|
if (aHost !== bHost && aHost !== null && bHost !== null) {
|
|
4025
4319
|
if (vnode_isVNode(aHost) && vnode_isVNode(bHost)) {
|
|
4026
4320
|
// we are running on the client.
|
|
@@ -4030,6 +4324,8 @@ function choreComparator(a, b, rootVNode) {
|
|
|
4030
4324
|
}
|
|
4031
4325
|
}
|
|
4032
4326
|
else {
|
|
4327
|
+
assertFalse(vnode_isVNode(aHost), 'expected aHost to be SSRNode but it is a VNode');
|
|
4328
|
+
assertFalse(vnode_isVNode(bHost), 'expected bHost to be SSRNode but it is a VNode');
|
|
4033
4329
|
// we are running on the server.
|
|
4034
4330
|
// On server we can't schedule task for a different host!
|
|
4035
4331
|
// Server is SSR, and therefore scheduling for anything but the current host
|
|
@@ -4049,247 +4345,114 @@ function choreComparator(a, b, rootVNode) {
|
|
|
4049
4345
|
if (microTypeDiff !== 0) {
|
|
4050
4346
|
return microTypeDiff;
|
|
4051
4347
|
}
|
|
4348
|
+
// types are the same
|
|
4052
4349
|
const idxDiff = toNumber(a.$idx$) - toNumber(b.$idx$);
|
|
4053
|
-
if (idxDiff !== 0) {
|
|
4054
|
-
return idxDiff;
|
|
4055
|
-
}
|
|
4056
|
-
// If the host is the same, we need to compare the target.
|
|
4057
|
-
if (a.$target$ !== b.$target$ &&
|
|
4058
|
-
((a.$type$ === ChoreType.QRL_RESOLVE && b.$type$ === ChoreType.QRL_RESOLVE) ||
|
|
4059
|
-
(a.$type$ === ChoreType.NODE_PROP && b.$type$ === ChoreType.NODE_PROP) ||
|
|
4060
|
-
(a.$type$ === ChoreType.RECOMPUTE_AND_SCHEDULE_EFFECTS &&
|
|
4061
|
-
b.$type$ === ChoreType.RECOMPUTE_AND_SCHEDULE_EFFECTS))) {
|
|
4062
|
-
// 1 means that we are going to process chores as FIFO
|
|
4063
|
-
return 1;
|
|
4064
|
-
}
|
|
4065
|
-
}
|
|
4066
|
-
return 0;
|
|
4067
|
-
}
|
|
4068
|
-
function sortedFindIndex(sortedArray, value, rootVNode) {
|
|
4069
|
-
/// We need to ensure that the `queue` is sorted by priority.
|
|
4070
|
-
/// 1. Find a place where to insert into.
|
|
4071
|
-
let bottom = 0;
|
|
4072
|
-
let top = sortedArray.length;
|
|
4073
|
-
while (bottom < top) {
|
|
4074
|
-
const middle = bottom + ((top - bottom) >> 1);
|
|
4075
|
-
const midChore = sortedArray[middle];
|
|
4076
|
-
const comp = choreComparator(value, midChore, rootVNode);
|
|
4077
|
-
if (comp < 0) {
|
|
4078
|
-
top = middle;
|
|
4079
|
-
}
|
|
4080
|
-
else if (comp > 0) {
|
|
4081
|
-
bottom = middle + 1;
|
|
4082
|
-
}
|
|
4083
|
-
else {
|
|
4084
|
-
// We already have the host in the queue.
|
|
4085
|
-
return middle;
|
|
4086
|
-
}
|
|
4087
|
-
}
|
|
4088
|
-
return ~bottom;
|
|
4089
|
-
}
|
|
4090
|
-
function sortedInsert(sortedArray, value, rootVNode) {
|
|
4091
|
-
/// We need to ensure that the `queue` is sorted by priority.
|
|
4092
|
-
/// 1. Find a place where to insert into.
|
|
4093
|
-
const idx = sortedFindIndex(sortedArray, value, rootVNode);
|
|
4094
|
-
if (idx < 0) {
|
|
4095
|
-
/// 2. Insert the chore into the queue.
|
|
4096
|
-
sortedArray.splice(~idx, 0, value);
|
|
4097
|
-
return value;
|
|
4098
|
-
}
|
|
4099
|
-
const existing = sortedArray[idx];
|
|
4100
|
-
choreUpdate(existing, value);
|
|
4101
|
-
return existing;
|
|
4102
|
-
}
|
|
4103
|
-
|
|
4104
|
-
// <docs markdown="../readme.md#useLexicalScope">
|
|
4105
|
-
// !!DO NOT EDIT THIS COMMENT DIRECTLY!!!
|
|
4106
|
-
// (edit ../readme.md#useLexicalScope instead and run `pnpm docs.sync`)
|
|
4107
|
-
/**
|
|
4108
|
-
* Used by the Qwik Optimizer to restore the lexically scoped variables.
|
|
4109
|
-
*
|
|
4110
|
-
* This method should not be present in the application source code.
|
|
4111
|
-
*
|
|
4112
|
-
* NOTE: `useLexicalScope` method can only be used in the synchronous portion of the callback
|
|
4113
|
-
* (before any `await` statements.)
|
|
4114
|
-
*
|
|
4115
|
-
* @internal
|
|
4116
|
-
*/
|
|
4117
|
-
// </docs>
|
|
4118
|
-
const useLexicalScope = () => {
|
|
4119
|
-
const context = getInvokeContext();
|
|
4120
|
-
let qrl = context.$qrl$;
|
|
4121
|
-
if (!qrl) {
|
|
4122
|
-
const el = context.$element$;
|
|
4123
|
-
assertDefined(el, 'invoke: element must be defined inside useLexicalScope()', context);
|
|
4124
|
-
const containerElement = _getQContainerElement(el);
|
|
4125
|
-
assertDefined(containerElement, `invoke: cant find parent q:container of`, el);
|
|
4126
|
-
const container = getDomContainer(containerElement);
|
|
4127
|
-
qrl = container.parseQRL(decodeURIComponent(String(context.$url$)));
|
|
4128
|
-
}
|
|
4129
|
-
else {
|
|
4130
|
-
assertQrl(qrl);
|
|
4131
|
-
assertDefined(qrl.$captureRef$, 'invoke: qrl $captureRef$ must be defined inside useLexicalScope()', qrl);
|
|
4132
|
-
}
|
|
4133
|
-
return qrl.$captureRef$;
|
|
4134
|
-
};
|
|
4135
|
-
|
|
4136
|
-
var TaskFlags;
|
|
4137
|
-
(function (TaskFlags) {
|
|
4138
|
-
TaskFlags[TaskFlags["VISIBLE_TASK"] = 1] = "VISIBLE_TASK";
|
|
4139
|
-
TaskFlags[TaskFlags["TASK"] = 2] = "TASK";
|
|
4140
|
-
TaskFlags[TaskFlags["RESOURCE"] = 4] = "RESOURCE";
|
|
4141
|
-
TaskFlags[TaskFlags["DIRTY"] = 8] = "DIRTY";
|
|
4142
|
-
})(TaskFlags || (TaskFlags = {}));
|
|
4143
|
-
/** @internal */
|
|
4144
|
-
const useTaskQrl = (qrl, opts) => {
|
|
4145
|
-
const { val, set, iCtx, i } = useSequentialScope();
|
|
4146
|
-
if (val) {
|
|
4147
|
-
return;
|
|
4148
|
-
}
|
|
4149
|
-
assertQrl(qrl);
|
|
4150
|
-
set(1);
|
|
4151
|
-
const host = iCtx.$hostElement$;
|
|
4152
|
-
const task = new Task(TaskFlags.DIRTY | TaskFlags.TASK, i, iCtx.$hostElement$, qrl, undefined, null);
|
|
4153
|
-
// In V2 we add the task to the sequential scope. We need to do this
|
|
4154
|
-
// in order to be able to retrieve it later when the parent element is
|
|
4155
|
-
// deleted and we need to be able to release the task subscriptions.
|
|
4156
|
-
set(task);
|
|
4157
|
-
const result = runTask(task, iCtx.$container$, host);
|
|
4158
|
-
if (isPromise(result)) {
|
|
4159
|
-
throw result;
|
|
4160
|
-
}
|
|
4161
|
-
qrl.$resolveLazy$(iCtx.$element$);
|
|
4162
|
-
if (isServerPlatform()) {
|
|
4163
|
-
useRunTask(task, opts?.eagerness);
|
|
4164
|
-
}
|
|
4165
|
-
};
|
|
4166
|
-
const runTask = (task, container, host) => {
|
|
4167
|
-
task.$flags$ &= ~TaskFlags.DIRTY;
|
|
4168
|
-
cleanupTask(task);
|
|
4169
|
-
const iCtx = newInvokeContext(container.$locale$, host, undefined, TaskEvent);
|
|
4170
|
-
iCtx.$container$ = container;
|
|
4171
|
-
const taskFn = task.$qrl$.getFn(iCtx, () => clearSubscriberEffectDependencies(container, task));
|
|
4172
|
-
const track = (obj, prop) => {
|
|
4173
|
-
const ctx = newInvokeContext();
|
|
4174
|
-
ctx.$effectSubscriber$ = [task, EffectProperty.COMPONENT];
|
|
4175
|
-
ctx.$container$ = container;
|
|
4176
|
-
return invoke(ctx, () => {
|
|
4177
|
-
if (isFunction(obj)) {
|
|
4178
|
-
return obj();
|
|
4179
|
-
}
|
|
4180
|
-
if (prop) {
|
|
4181
|
-
return obj[prop];
|
|
4182
|
-
}
|
|
4183
|
-
else if (isSignal(obj)) {
|
|
4184
|
-
return obj.value;
|
|
4185
|
-
}
|
|
4186
|
-
else {
|
|
4187
|
-
return obj;
|
|
4188
|
-
}
|
|
4189
|
-
});
|
|
4190
|
-
};
|
|
4191
|
-
const handleError = (reason) => container.handleError(reason, host);
|
|
4192
|
-
let cleanupFns = null;
|
|
4193
|
-
const cleanup = (fn) => {
|
|
4194
|
-
if (typeof fn == 'function') {
|
|
4195
|
-
if (!cleanupFns) {
|
|
4196
|
-
cleanupFns = [];
|
|
4197
|
-
task.$destroy$ = noSerialize(() => {
|
|
4198
|
-
task.$destroy$ = null;
|
|
4199
|
-
cleanupFns.forEach((fn) => {
|
|
4200
|
-
try {
|
|
4201
|
-
fn();
|
|
4202
|
-
}
|
|
4203
|
-
catch (err) {
|
|
4204
|
-
handleError(err);
|
|
4205
|
-
}
|
|
4206
|
-
});
|
|
4207
|
-
});
|
|
4208
|
-
}
|
|
4209
|
-
cleanupFns.push(fn);
|
|
4210
|
-
}
|
|
4211
|
-
};
|
|
4212
|
-
const taskApi = { track, cleanup };
|
|
4213
|
-
const result = safeCall(() => taskFn(taskApi), cleanup, (err) => {
|
|
4214
|
-
if (isPromise(err)) {
|
|
4215
|
-
return err.then(() => runTask(task, container, host));
|
|
4216
|
-
}
|
|
4217
|
-
else {
|
|
4218
|
-
return handleError(err);
|
|
4350
|
+
if (idxDiff !== 0) {
|
|
4351
|
+
return idxDiff;
|
|
4219
4352
|
}
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
const destroy = task.$destroy$;
|
|
4225
|
-
if (destroy) {
|
|
4226
|
-
task.$destroy$ = null;
|
|
4227
|
-
try {
|
|
4228
|
-
destroy();
|
|
4353
|
+
// If the host is the same (or missing), and the type is the same, we need to compare the target.
|
|
4354
|
+
if (a.$target$ !== b.$target$ || a.$payload$ !== b.$payload$) {
|
|
4355
|
+
// 1 means that we are going to process chores as FIFO
|
|
4356
|
+
return 1;
|
|
4229
4357
|
}
|
|
4230
|
-
|
|
4231
|
-
|
|
4358
|
+
// If the chore is the same as the current chore, we will run it again
|
|
4359
|
+
if (b === currentChore) {
|
|
4360
|
+
return 1;
|
|
4232
4361
|
}
|
|
4362
|
+
// The chores are the same and will run only once
|
|
4363
|
+
return 0;
|
|
4233
4364
|
}
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4365
|
+
function sortedFindIndex(sortedArray, value, rootVNode) {
|
|
4366
|
+
/// We need to ensure that the `queue` is sorted by priority.
|
|
4367
|
+
/// 1. Find a place where to insert into.
|
|
4368
|
+
let bottom = 0;
|
|
4369
|
+
let top = sortedArray.length;
|
|
4370
|
+
while (bottom < top) {
|
|
4371
|
+
const middle = bottom + ((top - bottom) >> 1);
|
|
4372
|
+
const midChore = sortedArray[middle];
|
|
4373
|
+
const comp = choreComparator(value, midChore, rootVNode);
|
|
4374
|
+
if (comp < 0) {
|
|
4375
|
+
top = middle;
|
|
4376
|
+
}
|
|
4377
|
+
else if (comp > 0) {
|
|
4378
|
+
bottom = middle + 1;
|
|
4379
|
+
}
|
|
4380
|
+
else {
|
|
4381
|
+
// We already have the host in the queue.
|
|
4382
|
+
return middle;
|
|
4383
|
+
}
|
|
4384
|
+
}
|
|
4385
|
+
return ~bottom;
|
|
4241
4386
|
}
|
|
4242
|
-
|
|
4243
|
-
|
|
4387
|
+
function sortedInsert(sortedArray, value, rootVNode) {
|
|
4388
|
+
/// We need to ensure that the `queue` is sorted by priority.
|
|
4389
|
+
/// 1. Find a place where to insert into.
|
|
4390
|
+
const idx = sortedFindIndex(sortedArray, value, rootVNode);
|
|
4391
|
+
if (idx < 0) {
|
|
4392
|
+
/// 2. Insert the chore into the queue.
|
|
4393
|
+
sortedArray.splice(~idx, 0, value);
|
|
4394
|
+
return value;
|
|
4395
|
+
}
|
|
4396
|
+
const existing = sortedArray[idx];
|
|
4397
|
+
/**
|
|
4398
|
+
* When a derived signal is updated we need to run vnode_diff. However the signal can update
|
|
4399
|
+
* multiple times during component execution. For this reason it is necessary for us to update
|
|
4400
|
+
* the chore with the latest result of the signal.
|
|
4401
|
+
*/
|
|
4402
|
+
if (existing.$type$ === ChoreType.NODE_DIFF) {
|
|
4403
|
+
existing.$payload$ = value.$payload$;
|
|
4404
|
+
}
|
|
4405
|
+
if (existing.$executed$) {
|
|
4406
|
+
existing.$executed$ = false;
|
|
4407
|
+
}
|
|
4408
|
+
return existing;
|
|
4244
4409
|
}
|
|
4245
4410
|
};
|
|
4246
|
-
const
|
|
4247
|
-
|
|
4248
|
-
const taskHandler = createQRL(taskQrl.$chunk$, '_hW', _hW, null, null, [task], taskQrl.$symbol$);
|
|
4249
|
-
// Needed for chunk lookup in dev mode
|
|
4250
|
-
if (taskQrl.dev) {
|
|
4251
|
-
taskHandler.dev = taskQrl.dev;
|
|
4252
|
-
}
|
|
4253
|
-
return taskHandler;
|
|
4411
|
+
const toNumber = (value) => {
|
|
4412
|
+
return typeof value === 'number' ? value : -1;
|
|
4254
4413
|
};
|
|
4255
|
-
|
|
4256
|
-
$
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4414
|
+
function vNodeAlreadyDeleted(chore) {
|
|
4415
|
+
return !!(chore.$host$ &&
|
|
4416
|
+
vnode_isVNode(chore.$host$) &&
|
|
4417
|
+
chore.$host$[VNodeProps.flags] & VNodeFlags.Deleted);
|
|
4418
|
+
}
|
|
4419
|
+
function debugChoreTypeToString(type) {
|
|
4420
|
+
return ({
|
|
4421
|
+
[ChoreType.QRL_RESOLVE]: 'QRL_RESOLVE',
|
|
4422
|
+
[ChoreType.RUN_QRL]: 'RUN_QRL',
|
|
4423
|
+
[ChoreType.TASK]: 'TASK',
|
|
4424
|
+
[ChoreType.NODE_DIFF]: 'NODE_DIFF',
|
|
4425
|
+
[ChoreType.NODE_PROP]: 'NODE_PROP',
|
|
4426
|
+
[ChoreType.COMPONENT]: 'COMPONENT',
|
|
4427
|
+
[ChoreType.RECOMPUTE_AND_SCHEDULE_EFFECTS]: 'RECOMPUTE_SIGNAL',
|
|
4428
|
+
[ChoreType.JOURNAL_FLUSH]: 'JOURNAL_FLUSH',
|
|
4429
|
+
[ChoreType.VISIBLE]: 'VISIBLE',
|
|
4430
|
+
[ChoreType.CLEANUP_VISIBLE]: 'CLEANUP_VISIBLE',
|
|
4431
|
+
[ChoreType.WAIT_FOR_ALL]: 'WAIT_FOR_ALL',
|
|
4432
|
+
}[type] || 'UNKNOWN: ' + type);
|
|
4433
|
+
}
|
|
4434
|
+
function debugChoreToString(chore) {
|
|
4435
|
+
const type = debugChoreTypeToString(chore.$type$);
|
|
4436
|
+
const host = String(chore.$host$).replaceAll(/\n.*/gim, '');
|
|
4437
|
+
const qrlTarget = chore.$target$?.$symbol$;
|
|
4438
|
+
return `Chore(${type} ${chore.$type$ === ChoreType.QRL_RESOLVE || chore.$type$ === ChoreType.RUN_QRL ? qrlTarget : host} ${chore.$idx$})`;
|
|
4439
|
+
}
|
|
4440
|
+
function debugTrace(action, arg, currentChore, queue) {
|
|
4441
|
+
const lines = ['===========================\nScheduler: ' + action];
|
|
4442
|
+
if (arg && !('$type$' in arg)) {
|
|
4443
|
+
lines.push(' arg: ' + String(arg).replaceAll(/\n.*/gim, ''));
|
|
4444
|
+
}
|
|
4445
|
+
if (queue) {
|
|
4446
|
+
queue.forEach((chore) => {
|
|
4447
|
+
const active = chore === arg ? '>>>' : ' ';
|
|
4448
|
+
lines.push(` ${active} > ` +
|
|
4449
|
+
(chore === currentChore ? '[running] ' : '') +
|
|
4450
|
+
debugChoreToString(chore));
|
|
4451
|
+
});
|
|
4270
4452
|
}
|
|
4453
|
+
// eslint-disable-next-line no-console
|
|
4454
|
+
console.log(lines.join('\n') + '\n');
|
|
4271
4455
|
}
|
|
4272
|
-
const isTask = (value) => {
|
|
4273
|
-
return value instanceof Task;
|
|
4274
|
-
};
|
|
4275
|
-
/**
|
|
4276
|
-
* Low-level API used by the Optimizer to process `useTask$()` API. This method is not intended to
|
|
4277
|
-
* be used by developers.
|
|
4278
|
-
*
|
|
4279
|
-
* @internal
|
|
4280
|
-
*/
|
|
4281
|
-
const _hW = () => {
|
|
4282
|
-
const [task] = useLexicalScope();
|
|
4283
|
-
const container = getDomContainer(task.$el$);
|
|
4284
|
-
const type = task.$flags$ & TaskFlags.VISIBLE_TASK ? ChoreType.VISIBLE : ChoreType.TASK;
|
|
4285
|
-
container.$scheduler$(type, task);
|
|
4286
|
-
};
|
|
4287
|
-
|
|
4288
|
-
/**
|
|
4289
|
-
* Special value used to mark that a given signal needs to be computed. This is essentially a
|
|
4290
|
-
* "marked as dirty" flag.
|
|
4291
|
-
*/
|
|
4292
|
-
const NEEDS_COMPUTATION = Symbol('invalid');
|
|
4293
4456
|
|
|
4294
4457
|
/**
|
|
4295
4458
|
* @file
|
|
@@ -4323,18 +4486,19 @@ const isSignal = (value) => {
|
|
|
4323
4486
|
return value instanceof Signal;
|
|
4324
4487
|
};
|
|
4325
4488
|
/** @internal */
|
|
4326
|
-
class
|
|
4489
|
+
class SubscriptionData {
|
|
4327
4490
|
data;
|
|
4328
4491
|
constructor(data) {
|
|
4329
4492
|
this.data = data;
|
|
4330
4493
|
}
|
|
4331
4494
|
}
|
|
4332
|
-
var
|
|
4333
|
-
(function (
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4495
|
+
var EffectSubscriptionProp;
|
|
4496
|
+
(function (EffectSubscriptionProp) {
|
|
4497
|
+
EffectSubscriptionProp[EffectSubscriptionProp["CONSUMER"] = 0] = "CONSUMER";
|
|
4498
|
+
EffectSubscriptionProp[EffectSubscriptionProp["PROPERTY"] = 1] = "PROPERTY";
|
|
4499
|
+
EffectSubscriptionProp[EffectSubscriptionProp["BACK_REF"] = 2] = "BACK_REF";
|
|
4500
|
+
EffectSubscriptionProp[EffectSubscriptionProp["DATA"] = 3] = "DATA";
|
|
4501
|
+
})(EffectSubscriptionProp || (EffectSubscriptionProp = {}));
|
|
4338
4502
|
var EffectProperty;
|
|
4339
4503
|
(function (EffectProperty) {
|
|
4340
4504
|
EffectProperty["COMPONENT"] = ":";
|
|
@@ -4371,19 +4535,16 @@ class Signal {
|
|
|
4371
4535
|
}
|
|
4372
4536
|
const effectSubscriber = ctx.$effectSubscriber$;
|
|
4373
4537
|
if (effectSubscriber) {
|
|
4374
|
-
const effects = (this.$effects$ ||=
|
|
4538
|
+
const effects = (this.$effects$ ||= new Set());
|
|
4375
4539
|
// Let's make sure that we have a reference to this effect.
|
|
4376
4540
|
// Adding reference is essentially adding a subscription, so if the signal
|
|
4377
4541
|
// changes we know who to notify.
|
|
4378
|
-
|
|
4542
|
+
ensureContainsSubscription(effects, effectSubscriber);
|
|
4379
4543
|
// But when effect is scheduled in needs to be able to know which signals
|
|
4380
4544
|
// to unsubscribe from. So we need to store the reference from the effect back
|
|
4381
4545
|
// to this signal.
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
// We need to add the subscriber to the effect so that we can clean it up later
|
|
4385
|
-
ensureEffectContainsSubscriber(effectSubscriber[EffectSubscriptionsProp.EFFECT], this, this.$container$);
|
|
4386
|
-
}
|
|
4546
|
+
ensureContainsBackRef(effectSubscriber, this);
|
|
4547
|
+
addQrlToSerializationCtx(effectSubscriber, this.$container$);
|
|
4387
4548
|
}
|
|
4388
4549
|
}
|
|
4389
4550
|
return this.untrackedValue;
|
|
@@ -4402,122 +4563,97 @@ class Signal {
|
|
|
4402
4563
|
}
|
|
4403
4564
|
toString() {
|
|
4404
4565
|
return (`[${this.constructor.name}${this.$invalid$ ? ' INVALID' : ''} ${String(this.$untrackedValue$)}]` +
|
|
4405
|
-
(this.$effects
|
|
4566
|
+
(Array.from(this.$effects$ || [])
|
|
4567
|
+
.map((e) => '\n -> ' + pad(qwikDebugToString(e[0]), ' '))
|
|
4568
|
+
.join('\n') || ''));
|
|
4406
4569
|
}
|
|
4407
4570
|
toJSON() {
|
|
4408
4571
|
return { value: this.$untrackedValue$ };
|
|
4409
4572
|
}
|
|
4410
4573
|
}
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
const isMissing = array.indexOf(value) === -1;
|
|
4414
|
-
if (isMissing) {
|
|
4415
|
-
array.push(value);
|
|
4416
|
-
}
|
|
4417
|
-
};
|
|
4418
|
-
const ensureContainsEffect = (array, effectSubscriptions) => {
|
|
4419
|
-
for (let i = 0; i < array.length; i++) {
|
|
4420
|
-
const existingEffect = array[i];
|
|
4421
|
-
if (existingEffect[0] === effectSubscriptions[0] &&
|
|
4422
|
-
existingEffect[1] === effectSubscriptions[1]) {
|
|
4423
|
-
return;
|
|
4424
|
-
}
|
|
4425
|
-
}
|
|
4426
|
-
array.push(effectSubscriptions);
|
|
4574
|
+
const ensureContainsSubscription = (array, effectSubscription) => {
|
|
4575
|
+
array.add(effectSubscription);
|
|
4427
4576
|
};
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
|
|
4577
|
+
/** Ensure the item is in back refs set */
|
|
4578
|
+
const ensureContainsBackRef = (array, value) => {
|
|
4579
|
+
array[EffectSubscriptionProp.BACK_REF] ||= new Set();
|
|
4580
|
+
array[EffectSubscriptionProp.BACK_REF].add(value);
|
|
4581
|
+
};
|
|
4582
|
+
const addQrlToSerializationCtx = (effectSubscriber, container) => {
|
|
4583
|
+
if (!!container && !isDomContainer(container)) {
|
|
4584
|
+
const effect = effectSubscriber[EffectSubscriptionProp.CONSUMER];
|
|
4585
|
+
const property = effectSubscriber[EffectSubscriptionProp.PROPERTY];
|
|
4586
|
+
let qrl = null;
|
|
4587
|
+
if (isTask(effect)) {
|
|
4588
|
+
qrl = effect.$qrl$;
|
|
4433
4589
|
}
|
|
4434
|
-
effect
|
|
4435
|
-
|
|
4436
|
-
else if (vnode_isVNode(effect) && !vnode_isTextVNode(effect)) {
|
|
4437
|
-
let subscribers = vnode_getProp(effect, QSubscribers, container ? container.$getObjectById$ : null);
|
|
4438
|
-
subscribers ||= [];
|
|
4439
|
-
if (subscriberExistInSubscribers(subscribers, subscriber)) {
|
|
4440
|
-
return;
|
|
4590
|
+
else if (effect instanceof ComputedSignal) {
|
|
4591
|
+
qrl = effect.$computeQrl$;
|
|
4441
4592
|
}
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
}
|
|
4445
|
-
else if (isSSRNode(effect)) {
|
|
4446
|
-
let subscribers = effect.getProp(QSubscribers);
|
|
4447
|
-
subscribers ||= [];
|
|
4448
|
-
if (subscriberExistInSubscribers(subscribers, subscriber)) {
|
|
4449
|
-
return;
|
|
4593
|
+
else if (property === EffectProperty.COMPONENT) {
|
|
4594
|
+
qrl = container.getHostProp(effect, OnRenderProp);
|
|
4450
4595
|
}
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
}
|
|
4454
|
-
};
|
|
4455
|
-
const isSSRNode = (effect) => {
|
|
4456
|
-
return 'setProp' in effect && 'getProp' in effect && 'removeProp' in effect && 'id' in effect;
|
|
4457
|
-
};
|
|
4458
|
-
const subscriberExistInSubscribers = (subscribers, subscriber) => {
|
|
4459
|
-
for (let i = 0; i < subscribers.length; i++) {
|
|
4460
|
-
if (subscribers[i] === subscriber) {
|
|
4461
|
-
return true;
|
|
4596
|
+
if (qrl) {
|
|
4597
|
+
container.serializationCtx.$eventQrls$.add(qrl);
|
|
4462
4598
|
}
|
|
4463
4599
|
}
|
|
4464
|
-
return false;
|
|
4465
4600
|
};
|
|
4466
4601
|
const triggerEffects = (container, signal, effects) => {
|
|
4602
|
+
const isBrowser = isDomContainer(container);
|
|
4467
4603
|
if (effects) {
|
|
4468
|
-
const scheduleEffect = (
|
|
4469
|
-
const
|
|
4470
|
-
const property =
|
|
4604
|
+
const scheduleEffect = (effectSubscription) => {
|
|
4605
|
+
const consumer = effectSubscription[EffectSubscriptionProp.CONSUMER];
|
|
4606
|
+
const property = effectSubscription[EffectSubscriptionProp.PROPERTY];
|
|
4471
4607
|
assertDefined(container, 'Container must be defined.');
|
|
4472
|
-
if (isTask(
|
|
4473
|
-
|
|
4608
|
+
if (isTask(consumer)) {
|
|
4609
|
+
consumer.$flags$ |= TaskFlags.DIRTY;
|
|
4474
4610
|
let choreType = ChoreType.TASK;
|
|
4475
|
-
if (
|
|
4611
|
+
if (consumer.$flags$ & TaskFlags.VISIBLE_TASK) {
|
|
4476
4612
|
choreType = ChoreType.VISIBLE;
|
|
4477
4613
|
}
|
|
4478
|
-
|
|
4479
|
-
choreType = ChoreType.RESOURCE;
|
|
4480
|
-
}
|
|
4481
|
-
container.$scheduler$(choreType, effect);
|
|
4614
|
+
container.$scheduler$(choreType, consumer);
|
|
4482
4615
|
}
|
|
4483
|
-
else if (
|
|
4616
|
+
else if (consumer instanceof Signal) {
|
|
4484
4617
|
// we don't schedule ComputedSignal/DerivedSignal directly, instead we invalidate it and
|
|
4485
4618
|
// and schedule the signals effects (recursively)
|
|
4486
|
-
if (
|
|
4619
|
+
if (consumer instanceof ComputedSignal) {
|
|
4487
4620
|
// Ensure that the computed signal's QRL is resolved.
|
|
4488
4621
|
// If not resolved schedule it to be resolved.
|
|
4489
|
-
if (!
|
|
4490
|
-
container.$scheduler$(ChoreType.QRL_RESOLVE, null,
|
|
4622
|
+
if (!consumer.$computeQrl$.resolved) {
|
|
4623
|
+
container.$scheduler$(ChoreType.QRL_RESOLVE, null, consumer.$computeQrl$);
|
|
4491
4624
|
}
|
|
4492
4625
|
}
|
|
4493
|
-
|
|
4626
|
+
consumer.$invalidate$();
|
|
4494
4627
|
}
|
|
4495
4628
|
else if (property === EffectProperty.COMPONENT) {
|
|
4496
|
-
const host =
|
|
4629
|
+
const host = consumer;
|
|
4497
4630
|
const qrl = container.getHostProp(host, OnRenderProp);
|
|
4498
4631
|
assertDefined(qrl, 'Component must have QRL');
|
|
4499
4632
|
const props = container.getHostProp(host, ELEMENT_PROPS);
|
|
4500
4633
|
container.$scheduler$(ChoreType.COMPONENT, host, qrl, props);
|
|
4501
4634
|
}
|
|
4502
|
-
else if (
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
4635
|
+
else if (isBrowser) {
|
|
4636
|
+
if (property === EffectProperty.VNODE) {
|
|
4637
|
+
const host = consumer;
|
|
4638
|
+
container.$scheduler$(ChoreType.NODE_DIFF, host, host, signal);
|
|
4639
|
+
}
|
|
4640
|
+
else {
|
|
4641
|
+
const host = consumer;
|
|
4642
|
+
const effectData = effectSubscription[EffectSubscriptionProp.DATA];
|
|
4643
|
+
if (effectData instanceof SubscriptionData) {
|
|
4644
|
+
const data = effectData.data;
|
|
4645
|
+
const payload = {
|
|
4646
|
+
...data,
|
|
4647
|
+
$value$: signal,
|
|
4648
|
+
};
|
|
4649
|
+
container.$scheduler$(ChoreType.NODE_PROP, host, property, payload);
|
|
4650
|
+
}
|
|
4517
4651
|
}
|
|
4518
4652
|
}
|
|
4519
4653
|
};
|
|
4520
|
-
effects
|
|
4654
|
+
for (const effect of effects) {
|
|
4655
|
+
scheduleEffect(effect);
|
|
4656
|
+
}
|
|
4521
4657
|
}
|
|
4522
4658
|
};
|
|
4523
4659
|
/**
|
|
@@ -4575,7 +4711,7 @@ class ComputedSignal extends Signal {
|
|
|
4575
4711
|
throwIfQRLNotResolved(computeQrl);
|
|
4576
4712
|
const ctx = tryGetInvokeContext();
|
|
4577
4713
|
const previousEffectSubscription = ctx?.$effectSubscriber$;
|
|
4578
|
-
ctx && (ctx.$effectSubscriber$ =
|
|
4714
|
+
ctx && (ctx.$effectSubscriber$ = getSubscriber(this, EffectProperty.VNODE));
|
|
4579
4715
|
try {
|
|
4580
4716
|
const untrackedValue = computeQrl.getFn(ctx)();
|
|
4581
4717
|
if (isPromise(untrackedValue)) {
|
|
@@ -4613,9 +4749,9 @@ class WrappedSignal extends Signal {
|
|
|
4613
4749
|
// We need a separate flag to know when the computation needs running because
|
|
4614
4750
|
// we need the old value to know if effects need running after computation
|
|
4615
4751
|
$invalid$ = true;
|
|
4616
|
-
$effectDependencies$ = null;
|
|
4617
4752
|
$hostElement$ = null;
|
|
4618
4753
|
$forceRunEffects$ = false;
|
|
4754
|
+
[_EFFECT_BACK_REF] = null;
|
|
4619
4755
|
constructor(container, fn, args, fnStr) {
|
|
4620
4756
|
super(container, NEEDS_COMPUTATION);
|
|
4621
4757
|
this.$args$ = args;
|
|
@@ -4683,7 +4819,7 @@ const applyQwikComponentBody = (ssr, jsx, component) => {
|
|
|
4683
4819
|
if (jsx.key !== null) {
|
|
4684
4820
|
host.setProp(ELEMENT_KEY, jsx.key);
|
|
4685
4821
|
}
|
|
4686
|
-
return scheduler(ChoreType.
|
|
4822
|
+
return scheduler(ChoreType.COMPONENT, host, componentQrl, srcProps);
|
|
4687
4823
|
};
|
|
4688
4824
|
|
|
4689
4825
|
class ParentComponentData {
|
|
@@ -4695,21 +4831,10 @@ class ParentComponentData {
|
|
|
4695
4831
|
}
|
|
4696
4832
|
}
|
|
4697
4833
|
/** @internal */
|
|
4698
|
-
function _walkJSX(ssr, value, options) {
|
|
4834
|
+
async function _walkJSX(ssr, value, options) {
|
|
4699
4835
|
const stack = [value];
|
|
4700
|
-
let resolveDrain;
|
|
4701
|
-
let rejectDrain;
|
|
4702
|
-
const drained = options.allowPromises &&
|
|
4703
|
-
new Promise((res, rej) => {
|
|
4704
|
-
resolveDrain = res;
|
|
4705
|
-
rejectDrain = rej;
|
|
4706
|
-
});
|
|
4707
4836
|
const enqueue = (value) => stack.push(value);
|
|
4708
|
-
const
|
|
4709
|
-
stack.push(value);
|
|
4710
|
-
drain();
|
|
4711
|
-
};
|
|
4712
|
-
const drain = () => {
|
|
4837
|
+
const drain = async () => {
|
|
4713
4838
|
while (stack.length) {
|
|
4714
4839
|
const value = stack.pop();
|
|
4715
4840
|
if (value instanceof ParentComponentData) {
|
|
@@ -4719,20 +4844,10 @@ function _walkJSX(ssr, value, options) {
|
|
|
4719
4844
|
}
|
|
4720
4845
|
else if (typeof value === 'function') {
|
|
4721
4846
|
if (value === Promise) {
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
}
|
|
4725
|
-
stack.pop().then(resolveValue, rejectDrain);
|
|
4726
|
-
return;
|
|
4727
|
-
}
|
|
4728
|
-
const waitOn = value.apply(ssr);
|
|
4729
|
-
if (waitOn) {
|
|
4730
|
-
if (!options.allowPromises) {
|
|
4731
|
-
throw qError(QError.promisesNotExpected);
|
|
4732
|
-
}
|
|
4733
|
-
waitOn.then(drain, rejectDrain);
|
|
4734
|
-
return;
|
|
4847
|
+
stack.push(await stack.pop());
|
|
4848
|
+
continue;
|
|
4735
4849
|
}
|
|
4850
|
+
await value.apply(ssr);
|
|
4736
4851
|
continue;
|
|
4737
4852
|
}
|
|
4738
4853
|
processJSXNode(ssr, enqueue, value, {
|
|
@@ -4740,12 +4855,8 @@ function _walkJSX(ssr, value, options) {
|
|
|
4740
4855
|
parentComponentFrame: options.parentComponentFrame,
|
|
4741
4856
|
});
|
|
4742
4857
|
}
|
|
4743
|
-
if (stack.length === 0 && options.allowPromises) {
|
|
4744
|
-
resolveDrain();
|
|
4745
|
-
}
|
|
4746
4858
|
};
|
|
4747
|
-
drain();
|
|
4748
|
-
return drained;
|
|
4859
|
+
await drain();
|
|
4749
4860
|
}
|
|
4750
4861
|
function processJSXNode(ssr, enqueue, value, options) {
|
|
4751
4862
|
// console.log('processJSXNode', value);
|
|
@@ -4784,7 +4895,6 @@ function processJSXNode(ssr, enqueue, value, options) {
|
|
|
4784
4895
|
enqueue(async () => {
|
|
4785
4896
|
for await (const chunk of value) {
|
|
4786
4897
|
await _walkJSX(ssr, chunk, {
|
|
4787
|
-
allowPromises: true,
|
|
4788
4898
|
currentStyleScoped: options.styleScoped,
|
|
4789
4899
|
parentComponentFrame: options.parentComponentFrame,
|
|
4790
4900
|
});
|
|
@@ -4871,7 +4981,6 @@ function processJSXNode(ssr, enqueue, value, options) {
|
|
|
4871
4981
|
value = generator({
|
|
4872
4982
|
async write(chunk) {
|
|
4873
4983
|
await _walkJSX(ssr, chunk, {
|
|
4874
|
-
allowPromises: true,
|
|
4875
4984
|
currentStyleScoped: options.styleScoped,
|
|
4876
4985
|
parentComponentFrame: options.parentComponentFrame,
|
|
4877
4986
|
});
|
|
@@ -5028,11 +5137,23 @@ function setEvent(serializationCtx, key, rawValue) {
|
|
|
5028
5137
|
const appendToValue = (valueToAppend) => {
|
|
5029
5138
|
value = (value == null ? '' : value + '\n') + valueToAppend;
|
|
5030
5139
|
};
|
|
5140
|
+
const getQrlString = (qrl) => {
|
|
5141
|
+
/**
|
|
5142
|
+
* If there are captures we need to schedule so everything is executed in the right order + qrls
|
|
5143
|
+
* are resolved.
|
|
5144
|
+
*
|
|
5145
|
+
* For internal qrls (starting with `_`) we assume that they do the right thing.
|
|
5146
|
+
*/
|
|
5147
|
+
if (!qrl.$symbol$.startsWith('_') && (qrl.$captureRef$ || qrl.$capture$)) {
|
|
5148
|
+
qrl = createQRL(null, '_run', queueQRL, null, null, [qrl]);
|
|
5149
|
+
}
|
|
5150
|
+
return qrlToString(serializationCtx, qrl);
|
|
5151
|
+
};
|
|
5031
5152
|
if (Array.isArray(qrls)) {
|
|
5032
5153
|
for (let i = 0; i <= qrls.length; i++) {
|
|
5033
5154
|
const qrl = qrls[i];
|
|
5034
|
-
if (isQrl(qrl)) {
|
|
5035
|
-
appendToValue(
|
|
5155
|
+
if (isQrl$1(qrl)) {
|
|
5156
|
+
appendToValue(getQrlString(qrl));
|
|
5036
5157
|
addQwikEventToSerializationContext(serializationCtx, key, qrl);
|
|
5037
5158
|
}
|
|
5038
5159
|
else if (qrl != null) {
|
|
@@ -5044,8 +5165,8 @@ function setEvent(serializationCtx, key, rawValue) {
|
|
|
5044
5165
|
}
|
|
5045
5166
|
}
|
|
5046
5167
|
}
|
|
5047
|
-
else if (isQrl(qrls)) {
|
|
5048
|
-
value =
|
|
5168
|
+
else if (isQrl$1(qrls)) {
|
|
5169
|
+
value = getQrlString(qrls);
|
|
5049
5170
|
addQwikEventToSerializationContext(serializationCtx, key, qrls);
|
|
5050
5171
|
}
|
|
5051
5172
|
return value;
|
|
@@ -5095,7 +5216,7 @@ function appendClassIfScopedStyleExists(jsx, styleScoped) {
|
|
|
5095
5216
|
*
|
|
5096
5217
|
* @public
|
|
5097
5218
|
*/
|
|
5098
|
-
const version = "2.0.0-alpha.
|
|
5219
|
+
const version = "2.0.0-alpha.7-dev+a26598a";
|
|
5099
5220
|
|
|
5100
5221
|
/** @internal */
|
|
5101
5222
|
class _SharedContainer {
|
|
@@ -5127,13 +5248,6 @@ class _SharedContainer {
|
|
|
5127
5248
|
}
|
|
5128
5249
|
}
|
|
5129
5250
|
|
|
5130
|
-
/** @internal */
|
|
5131
|
-
const _CONST_PROPS = Symbol('CONST');
|
|
5132
|
-
/** @internal */
|
|
5133
|
-
const _VAR_PROPS = Symbol('VAR');
|
|
5134
|
-
/** @internal @deprecated v1 compat */
|
|
5135
|
-
const _IMMUTABLE = Symbol('IMMUTABLE');
|
|
5136
|
-
|
|
5137
5251
|
// Keep these properties named like this so they're the same as from wrapSignal
|
|
5138
5252
|
const getValueProp = (p0) => p0.value;
|
|
5139
5253
|
const getProp = (p0, p1) => p0[p1];
|
|
@@ -5545,7 +5659,7 @@ function qwikDebugToString(value) {
|
|
|
5545
5659
|
else if (isTask(value)) {
|
|
5546
5660
|
return `Task(${qwikDebugToString(value.$qrl$)})`;
|
|
5547
5661
|
}
|
|
5548
|
-
else if (isQrl
|
|
5662
|
+
else if (isQrl(value)) {
|
|
5549
5663
|
return `Qrl(${value.$symbol$})`;
|
|
5550
5664
|
}
|
|
5551
5665
|
else if (typeof value === 'object' || typeof value === 'function') {
|
|
@@ -5699,14 +5813,21 @@ const VNodeDataChar = {
|
|
|
5699
5813
|
CONTEXT_CHAR: /* **** */ ']',
|
|
5700
5814
|
SEQ_IDX: /* ************ */ 94, // `^` - `q:seqIdx' - Sequential scope id
|
|
5701
5815
|
SEQ_IDX_CHAR: /* **** */ '^',
|
|
5702
|
-
|
|
5703
|
-
|
|
5816
|
+
BACK_REFS: /* ********** */ 96, // '`' - `q:brefs' - Effect dependencies/subscriptions
|
|
5817
|
+
BACK_REFS_CHAR: /* ** */ '`',
|
|
5704
5818
|
SEPARATOR: /* ********* */ 124, // `|` - Separator char to encode any key/value pairs.
|
|
5705
5819
|
SEPARATOR_CHAR: /* ** */ '|',
|
|
5706
5820
|
SLOT: /* ************** */ 126, // `~` - `q:slot' - Slot name
|
|
5707
5821
|
SLOT_CHAR: /* ******* */ '~',
|
|
5708
5822
|
};
|
|
5709
5823
|
|
|
5824
|
+
const mergeMaps = (map1, map2) => {
|
|
5825
|
+
for (const [k, v] of map2) {
|
|
5826
|
+
map1.set(k, v);
|
|
5827
|
+
}
|
|
5828
|
+
return map1;
|
|
5829
|
+
};
|
|
5830
|
+
|
|
5710
5831
|
/**
|
|
5711
5832
|
* @file
|
|
5712
5833
|
*
|
|
@@ -5962,6 +6083,7 @@ const vnode_ensureElementInflated = (vnode) => {
|
|
|
5962
6083
|
elementVNode[VNodeProps.flags] ^= VNodeFlags.Inflated;
|
|
5963
6084
|
const element = elementVNode[ElementVNodeProps.element];
|
|
5964
6085
|
const attributes = element.attributes;
|
|
6086
|
+
const props = vnode_getProps(elementVNode);
|
|
5965
6087
|
for (let idx = 0; idx < attributes.length; idx++) {
|
|
5966
6088
|
const attr = attributes[idx];
|
|
5967
6089
|
const key = attr.name;
|
|
@@ -5972,15 +6094,15 @@ const vnode_ensureElementInflated = (vnode) => {
|
|
|
5972
6094
|
}
|
|
5973
6095
|
else if (key.startsWith(QContainerAttr)) {
|
|
5974
6096
|
if (attr.value === QContainerValue.HTML) {
|
|
5975
|
-
mapArray_set(
|
|
6097
|
+
mapArray_set(props, dangerouslySetInnerHTML, element.innerHTML, 0);
|
|
5976
6098
|
}
|
|
5977
6099
|
else if (attr.value === QContainerValue.TEXT && 'value' in element) {
|
|
5978
|
-
mapArray_set(
|
|
6100
|
+
mapArray_set(props, 'value', element.value, 0);
|
|
5979
6101
|
}
|
|
5980
6102
|
}
|
|
5981
6103
|
else if (!key.startsWith('on:')) {
|
|
5982
6104
|
const value = attr.value;
|
|
5983
|
-
mapArray_set(
|
|
6105
|
+
mapArray_set(props, key, value, 0);
|
|
5984
6106
|
}
|
|
5985
6107
|
}
|
|
5986
6108
|
}
|
|
@@ -6416,54 +6538,16 @@ const vnode_applyJournal = (journal) => {
|
|
|
6416
6538
|
journal.length = 0;
|
|
6417
6539
|
};
|
|
6418
6540
|
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
6419
|
-
const mapApp_findIndx = (elementVNode, key, start) => {
|
|
6420
|
-
assertTrue(start % 2 === 0, 'Expecting even number.');
|
|
6421
|
-
let bottom = start >> 1;
|
|
6422
|
-
let top = (elementVNode.length - 2) >> 1;
|
|
6423
|
-
while (bottom <= top) {
|
|
6424
|
-
const mid = bottom + ((top - bottom) >> 1);
|
|
6425
|
-
const midKey = elementVNode[mid << 1];
|
|
6426
|
-
if (midKey === key) {
|
|
6427
|
-
return mid << 1;
|
|
6428
|
-
}
|
|
6429
|
-
if (midKey < key) {
|
|
6430
|
-
bottom = mid + 1;
|
|
6431
|
-
}
|
|
6432
|
-
else {
|
|
6433
|
-
top = mid - 1;
|
|
6434
|
-
}
|
|
6435
|
-
}
|
|
6436
|
-
return (bottom << 1) ^ -1;
|
|
6437
|
-
};
|
|
6438
|
-
const mapArray_set = (elementVNode, key, value, start) => {
|
|
6439
|
-
const indx = mapApp_findIndx(elementVNode, key, start);
|
|
6440
|
-
if (indx >= 0) {
|
|
6441
|
-
if (value == null) {
|
|
6442
|
-
elementVNode.splice(indx, 2);
|
|
6443
|
-
}
|
|
6444
|
-
else {
|
|
6445
|
-
elementVNode[indx + 1] = value;
|
|
6446
|
-
}
|
|
6447
|
-
}
|
|
6448
|
-
else if (value != null) {
|
|
6449
|
-
elementVNode.splice(indx ^ -1, 0, key, value);
|
|
6450
|
-
}
|
|
6451
|
-
};
|
|
6452
|
-
const mapArray_get = (elementVNode, key, start) => {
|
|
6453
|
-
const indx = mapApp_findIndx(elementVNode, key, start);
|
|
6454
|
-
if (indx >= 0) {
|
|
6455
|
-
return elementVNode[indx + 1];
|
|
6456
|
-
}
|
|
6457
|
-
else {
|
|
6458
|
-
return null;
|
|
6459
|
-
}
|
|
6460
|
-
};
|
|
6461
|
-
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
6462
6541
|
const vnode_insertBefore = (journal, parent, newChild, insertBefore) => {
|
|
6463
6542
|
ensureElementOrVirtualVNode(parent);
|
|
6464
6543
|
if (vnode_isElementVNode(parent)) {
|
|
6465
6544
|
ensureMaterialized(parent);
|
|
6466
6545
|
}
|
|
6546
|
+
if (newChild === insertBefore) {
|
|
6547
|
+
// invalid insertBefore. We can't insert before self reference
|
|
6548
|
+
// prevent infinity loop and putting self reference to next sibling
|
|
6549
|
+
insertBefore = null;
|
|
6550
|
+
}
|
|
6467
6551
|
let adjustedInsertBefore = null;
|
|
6468
6552
|
if (insertBefore == null) {
|
|
6469
6553
|
if (vnode_isVirtualVNode(parent)) {
|
|
@@ -6587,9 +6671,10 @@ const vnode_getElementName = (vnode) => {
|
|
|
6587
6671
|
const elementVNode = ensureElementVNode(vnode);
|
|
6588
6672
|
let elementName = elementVNode[ElementVNodeProps.elementName];
|
|
6589
6673
|
if (elementName === undefined) {
|
|
6590
|
-
|
|
6591
|
-
|
|
6592
|
-
elementVNode[
|
|
6674
|
+
const element = elementVNode[ElementVNodeProps.element];
|
|
6675
|
+
const nodeName = isDev ? fastNodeName(element).toLowerCase() : fastNodeName(element);
|
|
6676
|
+
elementName = elementVNode[ElementVNodeProps.elementName] = nodeName;
|
|
6677
|
+
elementVNode[VNodeProps.flags] |= vnode_getElementNamespaceFlags(element);
|
|
6593
6678
|
}
|
|
6594
6679
|
return elementName;
|
|
6595
6680
|
};
|
|
@@ -6771,6 +6856,20 @@ const fastFirstChild = (node) => {
|
|
|
6771
6856
|
}
|
|
6772
6857
|
return node;
|
|
6773
6858
|
};
|
|
6859
|
+
let _fastNamespaceURI = null;
|
|
6860
|
+
const fastNamespaceURI = (element) => {
|
|
6861
|
+
if (!_fastNamespaceURI) {
|
|
6862
|
+
_fastNamespaceURI = fastGetter(element, 'namespaceURI');
|
|
6863
|
+
}
|
|
6864
|
+
return _fastNamespaceURI.call(element);
|
|
6865
|
+
};
|
|
6866
|
+
let _fastNodeName = null;
|
|
6867
|
+
const fastNodeName = (element) => {
|
|
6868
|
+
if (!_fastNodeName) {
|
|
6869
|
+
_fastNodeName = fastGetter(element, 'nodeName');
|
|
6870
|
+
}
|
|
6871
|
+
return _fastNodeName.call(element);
|
|
6872
|
+
};
|
|
6774
6873
|
const fastGetter = (prototype, name) => {
|
|
6775
6874
|
let getter;
|
|
6776
6875
|
while (prototype && !(getter = Object.getOwnPropertyDescriptor(prototype, name)?.get)) {
|
|
@@ -6837,8 +6936,11 @@ const materializeFromDOM = (vParent, firstChild, vData) => {
|
|
|
6837
6936
|
container.$setRawState$(parseInt(id), vParent);
|
|
6838
6937
|
isDev && vnode_setAttr(null, vParent, ELEMENT_ID, id);
|
|
6839
6938
|
}
|
|
6840
|
-
else if (peek() === VNodeDataChar.
|
|
6841
|
-
|
|
6939
|
+
else if (peek() === VNodeDataChar.BACK_REFS) {
|
|
6940
|
+
if (!container) {
|
|
6941
|
+
container = getDomContainer(vParent[ElementVNodeProps.element]);
|
|
6942
|
+
}
|
|
6943
|
+
setEffectBackRefFromVNodeData(vParent, consumeValue(), container);
|
|
6842
6944
|
}
|
|
6843
6945
|
else {
|
|
6844
6946
|
// prevent infinity loop if there are some characters outside the range
|
|
@@ -6848,6 +6950,18 @@ const materializeFromDOM = (vParent, firstChild, vData) => {
|
|
|
6848
6950
|
}
|
|
6849
6951
|
return vFirstChild;
|
|
6850
6952
|
};
|
|
6953
|
+
function setEffectBackRefFromVNodeData(vParent, value, container) {
|
|
6954
|
+
const deserializedSubMap = container.$getObjectById$(value);
|
|
6955
|
+
if (!vParent[_EFFECT_BACK_REF]) {
|
|
6956
|
+
Object.defineProperty(vParent, _EFFECT_BACK_REF, {
|
|
6957
|
+
value: deserializedSubMap,
|
|
6958
|
+
});
|
|
6959
|
+
}
|
|
6960
|
+
else {
|
|
6961
|
+
const subMap = vParent[_EFFECT_BACK_REF];
|
|
6962
|
+
mergeMaps(subMap, deserializedSubMap);
|
|
6963
|
+
}
|
|
6964
|
+
}
|
|
6851
6965
|
const processVNodeData$1 = (vData, callback) => {
|
|
6852
6966
|
let nextToConsumeIdx = 0;
|
|
6853
6967
|
let ch = 0;
|
|
@@ -6892,8 +7006,9 @@ const vnode_getAttrKeys = (vnode) => {
|
|
|
6892
7006
|
if ((type & VNodeFlags.ELEMENT_OR_VIRTUAL_MASK) !== 0) {
|
|
6893
7007
|
vnode_ensureElementInflated(vnode);
|
|
6894
7008
|
const keys = [];
|
|
6895
|
-
|
|
6896
|
-
|
|
7009
|
+
const props = vnode_getProps(vnode);
|
|
7010
|
+
for (let i = 0; i < props.length; i = i + 2) {
|
|
7011
|
+
const key = props[i];
|
|
6897
7012
|
if (!key.startsWith(Q_PROPS_SEPARATOR)) {
|
|
6898
7013
|
keys.push(key);
|
|
6899
7014
|
}
|
|
@@ -6906,22 +7021,23 @@ const vnode_setAttr = (journal, vnode, key, value) => {
|
|
|
6906
7021
|
const type = vnode[VNodeProps.flags];
|
|
6907
7022
|
if ((type & VNodeFlags.ELEMENT_OR_VIRTUAL_MASK) !== 0) {
|
|
6908
7023
|
vnode_ensureElementInflated(vnode);
|
|
6909
|
-
const
|
|
7024
|
+
const props = vnode_getProps(vnode);
|
|
7025
|
+
const idx = mapApp_findIndx(props, key, 0);
|
|
6910
7026
|
if (idx >= 0) {
|
|
6911
|
-
if (
|
|
7027
|
+
if (props[idx + 1] != value && (type & VNodeFlags.Element) !== 0) {
|
|
6912
7028
|
// Values are different, update DOM
|
|
6913
7029
|
const element = vnode[ElementVNodeProps.element];
|
|
6914
7030
|
journal && journal.push(VNodeJournalOpCode.SetAttribute, element, key, value);
|
|
6915
7031
|
}
|
|
6916
7032
|
if (value == null) {
|
|
6917
|
-
|
|
7033
|
+
props.splice(idx, 2);
|
|
6918
7034
|
}
|
|
6919
7035
|
else {
|
|
6920
|
-
|
|
7036
|
+
props[idx + 1] = value;
|
|
6921
7037
|
}
|
|
6922
7038
|
}
|
|
6923
7039
|
else if (value != null) {
|
|
6924
|
-
|
|
7040
|
+
props.splice(idx ^ -1, 0, key, value);
|
|
6925
7041
|
if ((type & VNodeFlags.Element) !== 0) {
|
|
6926
7042
|
// New value, update DOM
|
|
6927
7043
|
const element = vnode[ElementVNodeProps.element];
|
|
@@ -6934,7 +7050,8 @@ const vnode_getAttr = (vnode, key) => {
|
|
|
6934
7050
|
const type = vnode[VNodeProps.flags];
|
|
6935
7051
|
if ((type & VNodeFlags.ELEMENT_OR_VIRTUAL_MASK) !== 0) {
|
|
6936
7052
|
vnode_ensureElementInflated(vnode);
|
|
6937
|
-
|
|
7053
|
+
const props = vnode_getProps(vnode);
|
|
7054
|
+
return mapArray_get(props, key, 0);
|
|
6938
7055
|
}
|
|
6939
7056
|
return null;
|
|
6940
7057
|
};
|
|
@@ -6942,11 +7059,12 @@ const vnode_getProp = (vnode, key, getObject) => {
|
|
|
6942
7059
|
const type = vnode[VNodeProps.flags];
|
|
6943
7060
|
if ((type & VNodeFlags.ELEMENT_OR_VIRTUAL_MASK) !== 0) {
|
|
6944
7061
|
type & VNodeFlags.Element && vnode_ensureElementInflated(vnode);
|
|
6945
|
-
const
|
|
7062
|
+
const props = vnode_getProps(vnode);
|
|
7063
|
+
const idx = mapApp_findIndx(props, key, 0);
|
|
6946
7064
|
if (idx >= 0) {
|
|
6947
|
-
let value =
|
|
7065
|
+
let value = props[idx + 1];
|
|
6948
7066
|
if (typeof value === 'string' && getObject) {
|
|
6949
|
-
|
|
7067
|
+
props[idx + 1] = value = getObject(value);
|
|
6950
7068
|
}
|
|
6951
7069
|
return value;
|
|
6952
7070
|
}
|
|
@@ -6955,12 +7073,13 @@ const vnode_getProp = (vnode, key, getObject) => {
|
|
|
6955
7073
|
};
|
|
6956
7074
|
const vnode_setProp = (vnode, key, value) => {
|
|
6957
7075
|
ensureElementOrVirtualVNode(vnode);
|
|
6958
|
-
const
|
|
7076
|
+
const props = vnode_getProps(vnode);
|
|
7077
|
+
const idx = mapApp_findIndx(props, key, 0);
|
|
6959
7078
|
if (idx >= 0) {
|
|
6960
|
-
|
|
7079
|
+
props[idx + 1] = value;
|
|
6961
7080
|
}
|
|
6962
7081
|
else if (value != null) {
|
|
6963
|
-
|
|
7082
|
+
props.splice(idx ^ -1, 0, key, value);
|
|
6964
7083
|
}
|
|
6965
7084
|
};
|
|
6966
7085
|
const vnode_getPropStartIndex = (vnode) => {
|
|
@@ -6973,6 +7092,9 @@ const vnode_getPropStartIndex = (vnode) => {
|
|
|
6973
7092
|
}
|
|
6974
7093
|
throw qError(QError.invalidVNodeType, [type]);
|
|
6975
7094
|
};
|
|
7095
|
+
const vnode_getProps = (vnode) => {
|
|
7096
|
+
return vnode[vnode_getPropStartIndex(vnode)];
|
|
7097
|
+
};
|
|
6976
7098
|
const vnode_getParent = (vnode) => {
|
|
6977
7099
|
return vnode[VNodeProps.parent] || null;
|
|
6978
7100
|
};
|
|
@@ -7136,8 +7258,11 @@ function materializeFromVNodeData(vParent, vData, element, child) {
|
|
|
7136
7258
|
else if (peek() === VNodeDataChar.SEQ_IDX) {
|
|
7137
7259
|
vnode_setAttr(null, vParent, ELEMENT_SEQ_IDX, consumeValue());
|
|
7138
7260
|
}
|
|
7139
|
-
else if (peek() === VNodeDataChar.
|
|
7140
|
-
|
|
7261
|
+
else if (peek() === VNodeDataChar.BACK_REFS) {
|
|
7262
|
+
if (!container) {
|
|
7263
|
+
container = getDomContainer(element);
|
|
7264
|
+
}
|
|
7265
|
+
setEffectBackRefFromVNodeData(vParent, consumeValue(), container);
|
|
7141
7266
|
}
|
|
7142
7267
|
else if (peek() === VNodeDataChar.CONTEXT) {
|
|
7143
7268
|
vnode_setAttr(null, vParent, QCtxAttr, consumeValue());
|
|
@@ -7245,23 +7370,20 @@ const vnode_getProjectionParentComponent = (vHost, rootVNode) => {
|
|
|
7245
7370
|
};
|
|
7246
7371
|
const VNodeArray = class VNode extends Array {
|
|
7247
7372
|
static createElement(flags, parent, previousSibling, nextSibling, firstChild, lastChild, element, elementName) {
|
|
7248
|
-
const vnode = new VNode(flags, parent, previousSibling, nextSibling);
|
|
7249
|
-
vnode.push(firstChild, lastChild, element, elementName);
|
|
7373
|
+
const vnode = new VNode(flags, parent, previousSibling, nextSibling, firstChild, lastChild, element, elementName, []);
|
|
7250
7374
|
return vnode;
|
|
7251
7375
|
}
|
|
7252
7376
|
static createText(flags, parent, previousSibling, nextSibling, textNode, text) {
|
|
7253
|
-
const vnode = new VNode(flags, parent, previousSibling, nextSibling);
|
|
7254
|
-
vnode.push(textNode, text);
|
|
7377
|
+
const vnode = new VNode(flags, parent, previousSibling, nextSibling, textNode, text);
|
|
7255
7378
|
return vnode;
|
|
7256
7379
|
}
|
|
7257
7380
|
static createVirtual(flags, parent, previousSibling, nextSibling, firstChild, lastChild) {
|
|
7258
|
-
const vnode = new VNode(flags, parent, previousSibling, nextSibling);
|
|
7259
|
-
vnode.push(firstChild, lastChild);
|
|
7381
|
+
const vnode = new VNode(flags, parent, previousSibling, nextSibling, firstChild, lastChild, []);
|
|
7260
7382
|
return vnode;
|
|
7261
7383
|
}
|
|
7262
|
-
constructor(flags, parent, previousSibling, nextSibling) {
|
|
7263
|
-
|
|
7264
|
-
|
|
7384
|
+
constructor(flags, parent, previousSibling, nextSibling, ...rest) {
|
|
7385
|
+
// @ts-expect-error
|
|
7386
|
+
super(flags, parent, previousSibling, nextSibling, ...rest);
|
|
7265
7387
|
if (isDev) {
|
|
7266
7388
|
this.toString = vnode_toString;
|
|
7267
7389
|
}
|
|
@@ -7326,10 +7448,12 @@ function invokeApply(context, fn, args) {
|
|
|
7326
7448
|
return returnValue;
|
|
7327
7449
|
}
|
|
7328
7450
|
const newInvokeContextFromTuple = ([element, event, url]) => {
|
|
7329
|
-
const
|
|
7451
|
+
const domContainer = getDomContainer(element);
|
|
7452
|
+
const container = domContainer.element;
|
|
7453
|
+
const vNode = container ? vnode_locate(domContainer.rootVNode, element) : undefined;
|
|
7330
7454
|
const locale = container?.getAttribute(QLocaleAttr) || undefined;
|
|
7331
7455
|
locale && setLocale(locale);
|
|
7332
|
-
return newInvokeContext(locale,
|
|
7456
|
+
return newInvokeContext(locale, vNode, element, event, url);
|
|
7333
7457
|
};
|
|
7334
7458
|
// TODO how about putting url and locale (and event/custom?) in to a "static" object
|
|
7335
7459
|
const newInvokeContext = (locale, hostElement, element, event, url) => {
|
|
@@ -7364,16 +7488,14 @@ const trackInvocation = /*#__PURE__*/ newInvokeContext(undefined, undefined, und
|
|
|
7364
7488
|
* @param property `true` - subscriber is component `false` - subscriber is VNode `string` -
|
|
7365
7489
|
* subscriber is property
|
|
7366
7490
|
* @param container
|
|
7491
|
+
* @param data - Additional subscription data
|
|
7367
7492
|
* @returns
|
|
7368
7493
|
*/
|
|
7369
7494
|
const trackSignal = (fn, subscriber, property, container, data) => {
|
|
7370
7495
|
const previousSubscriber = trackInvocation.$effectSubscriber$;
|
|
7371
7496
|
const previousContainer = trackInvocation.$container$;
|
|
7372
7497
|
try {
|
|
7373
|
-
trackInvocation.$effectSubscriber$ =
|
|
7374
|
-
if (data) {
|
|
7375
|
-
trackInvocation.$effectSubscriber$.push(data);
|
|
7376
|
-
}
|
|
7498
|
+
trackInvocation.$effectSubscriber$ = getSubscriber(subscriber, property, data);
|
|
7377
7499
|
trackInvocation.$container$ = container;
|
|
7378
7500
|
return invoke(trackInvocation, fn);
|
|
7379
7501
|
}
|
|
@@ -7394,8 +7516,16 @@ const _getContextElement = () => {
|
|
|
7394
7516
|
if (iCtx) {
|
|
7395
7517
|
const hostElement = iCtx.$hostElement$;
|
|
7396
7518
|
let element = null;
|
|
7397
|
-
if (
|
|
7398
|
-
|
|
7519
|
+
if (hostElement != null) {
|
|
7520
|
+
if (vnode_isVNode(hostElement)) {
|
|
7521
|
+
if (vnode_isElementVNode(hostElement)) {
|
|
7522
|
+
element = vnode_getNode(hostElement);
|
|
7523
|
+
}
|
|
7524
|
+
}
|
|
7525
|
+
else {
|
|
7526
|
+
// isSSRnode
|
|
7527
|
+
element = hostElement;
|
|
7528
|
+
}
|
|
7399
7529
|
}
|
|
7400
7530
|
return element ?? iCtx.$qrl$?.$setContainer$(undefined);
|
|
7401
7531
|
}
|
|
@@ -8031,9 +8161,9 @@ class DomContainer extends _SharedContainer {
|
|
|
8031
8161
|
$storeProxyMap$ = new WeakMap();
|
|
8032
8162
|
$qFuncs$;
|
|
8033
8163
|
$instanceHash$;
|
|
8034
|
-
|
|
8164
|
+
vNodeLocate = (id) => vnode_locate(this.rootVNode, id);
|
|
8165
|
+
$stateData$;
|
|
8035
8166
|
$styleIds$ = null;
|
|
8036
|
-
$vnodeLocate$ = (id) => vnode_locate(this.rootVNode, id);
|
|
8037
8167
|
$renderCount$ = 0;
|
|
8038
8168
|
constructor(element) {
|
|
8039
8169
|
super(() => this.scheduleRender(), () => vnode_applyJournal(this.$journal$), {}, element.getAttribute('q:locale'));
|
|
@@ -8059,29 +8189,29 @@ class DomContainer extends _SharedContainer {
|
|
|
8059
8189
|
this.rootVNode = vnode_newUnMaterializedElement(this.element);
|
|
8060
8190
|
// These are here to initialize all properties at once for single class transition
|
|
8061
8191
|
this.$rawStateData$ = null;
|
|
8062
|
-
this
|
|
8192
|
+
this.$stateData$ = null;
|
|
8063
8193
|
const document = this.element.ownerDocument;
|
|
8064
8194
|
if (!document.qVNodeData) {
|
|
8065
8195
|
processVNodeData(document);
|
|
8066
8196
|
}
|
|
8067
8197
|
this.$rawStateData$ = [];
|
|
8068
|
-
this
|
|
8198
|
+
this.$stateData$ = [];
|
|
8069
8199
|
const qwikStates = element.querySelectorAll('script[type="qwik/state"]');
|
|
8070
8200
|
if (qwikStates.length !== 0) {
|
|
8071
8201
|
const lastState = qwikStates[qwikStates.length - 1];
|
|
8072
8202
|
this.$rawStateData$ = JSON.parse(lastState.textContent);
|
|
8073
|
-
this
|
|
8203
|
+
this.$stateData$ = wrapDeserializerProxy(this, this.$rawStateData$);
|
|
8074
8204
|
}
|
|
8075
8205
|
this.$qFuncs$ = getQFuncs(document, this.$instanceHash$) || EMPTY_ARRAY;
|
|
8076
8206
|
}
|
|
8077
8207
|
$setRawState$(id, vParent) {
|
|
8078
|
-
this
|
|
8208
|
+
this.$stateData$[id] = vParent;
|
|
8079
8209
|
}
|
|
8080
8210
|
parseQRL(qrl) {
|
|
8081
8211
|
return inflateQRL(this, parseQRL(qrl));
|
|
8082
8212
|
}
|
|
8083
8213
|
handleError(err, host) {
|
|
8084
|
-
if (qDev) {
|
|
8214
|
+
if (qDev && host) {
|
|
8085
8215
|
// Clean vdom
|
|
8086
8216
|
if (typeof document !== 'undefined') {
|
|
8087
8217
|
const vHost = host;
|
|
@@ -8105,7 +8235,7 @@ class DomContainer extends _SharedContainer {
|
|
|
8105
8235
|
throw err;
|
|
8106
8236
|
}
|
|
8107
8237
|
}
|
|
8108
|
-
const errorStore = this.resolveContext(host, ERROR_CONTEXT);
|
|
8238
|
+
const errorStore = host && this.resolveContext(host, ERROR_CONTEXT);
|
|
8109
8239
|
if (!errorStore) {
|
|
8110
8240
|
throw err;
|
|
8111
8241
|
}
|
|
@@ -8141,7 +8271,7 @@ class DomContainer extends _SharedContainer {
|
|
|
8141
8271
|
vNode =
|
|
8142
8272
|
vnode_getParent(vNode) ||
|
|
8143
8273
|
// If virtual node, than it could be a slot so we need to read its parent.
|
|
8144
|
-
vnode_getProp(vNode, QSlotParent, this
|
|
8274
|
+
vnode_getProp(vNode, QSlotParent, this.vNodeLocate);
|
|
8145
8275
|
}
|
|
8146
8276
|
else {
|
|
8147
8277
|
vNode = vnode_getParent(vNode);
|
|
@@ -8161,7 +8291,7 @@ class DomContainer extends _SharedContainer {
|
|
|
8161
8291
|
case ELEMENT_PROPS:
|
|
8162
8292
|
case OnRenderProp:
|
|
8163
8293
|
case QCtxAttr:
|
|
8164
|
-
case
|
|
8294
|
+
case QBackRefs:
|
|
8165
8295
|
getObjectById = this.$getObjectById$;
|
|
8166
8296
|
break;
|
|
8167
8297
|
case ELEMENT_SEQ_IDX:
|
|
@@ -8174,7 +8304,7 @@ class DomContainer extends _SharedContainer {
|
|
|
8174
8304
|
scheduleRender() {
|
|
8175
8305
|
this.$renderCount$++;
|
|
8176
8306
|
this.renderDone ||= getPlatform().nextTick(() => this.processChores());
|
|
8177
|
-
return this.renderDone;
|
|
8307
|
+
return this.renderDone.finally(() => emitEvent('qrender', { instanceHash: this.$instanceHash$, renderCount: this.$renderCount$ }));
|
|
8178
8308
|
}
|
|
8179
8309
|
processChores() {
|
|
8180
8310
|
let renderCount = this.$renderCount$;
|
|
@@ -8197,12 +8327,13 @@ class DomContainer extends _SharedContainer {
|
|
|
8197
8327
|
ensureProjectionResolved(vNode) {
|
|
8198
8328
|
if ((vNode[VNodeProps.flags] & VNodeFlags.Resolved) === 0) {
|
|
8199
8329
|
vNode[VNodeProps.flags] |= VNodeFlags.Resolved;
|
|
8200
|
-
|
|
8201
|
-
|
|
8330
|
+
const props = vnode_getProps(vNode);
|
|
8331
|
+
for (let i = 0; i < props.length; i = i + 2) {
|
|
8332
|
+
const prop = props[i];
|
|
8202
8333
|
if (isSlotProp(prop)) {
|
|
8203
|
-
const value =
|
|
8334
|
+
const value = props[i + 1];
|
|
8204
8335
|
if (typeof value == 'string') {
|
|
8205
|
-
|
|
8336
|
+
props[i + 1] = this.vNodeLocate(value);
|
|
8206
8337
|
}
|
|
8207
8338
|
}
|
|
8208
8339
|
}
|
|
@@ -8213,7 +8344,7 @@ class DomContainer extends _SharedContainer {
|
|
|
8213
8344
|
id = parseFloat(id);
|
|
8214
8345
|
}
|
|
8215
8346
|
assertTrue(id < this.$rawStateData$.length / 2, `Invalid reference: ${id} >= ${this.$rawStateData$.length / 2}`);
|
|
8216
|
-
return this
|
|
8347
|
+
return this.$stateData$[id];
|
|
8217
8348
|
};
|
|
8218
8349
|
getSyncFn(id) {
|
|
8219
8350
|
const fn = this.$qFuncs$[id];
|
|
@@ -8285,8 +8416,7 @@ class DeserializationHandler {
|
|
|
8285
8416
|
? parseInt(property, 10)
|
|
8286
8417
|
: NaN;
|
|
8287
8418
|
if (Number.isNaN(i) || i < 0 || i >= this.$length$) {
|
|
8288
|
-
|
|
8289
|
-
return out;
|
|
8419
|
+
return Reflect.get(target, property, receiver);
|
|
8290
8420
|
}
|
|
8291
8421
|
// The serialized data is an array with 2 values for each item
|
|
8292
8422
|
const idx = i * 2;
|
|
@@ -8352,6 +8482,7 @@ const inflate = (container, target, typeId, data) => {
|
|
|
8352
8482
|
switch (typeId) {
|
|
8353
8483
|
case TypeIds.Object:
|
|
8354
8484
|
// We use getters for making complex values lazy
|
|
8485
|
+
// TODO scan the data for computeQRLs and schedule resolve chores
|
|
8355
8486
|
for (let i = 0; i < data.length; i += 4) {
|
|
8356
8487
|
const key = deserializeData(container, data[i], data[i + 1]);
|
|
8357
8488
|
const valType = data[i + 2];
|
|
@@ -8391,7 +8522,7 @@ const inflate = (container, target, typeId, data) => {
|
|
|
8391
8522
|
task.$flags$ = v[1];
|
|
8392
8523
|
task.$index$ = v[2];
|
|
8393
8524
|
task.$el$ = v[3];
|
|
8394
|
-
task
|
|
8525
|
+
task[_EFFECT_BACK_REF] = v[4];
|
|
8395
8526
|
task.$state$ = v[5];
|
|
8396
8527
|
break;
|
|
8397
8528
|
case TypeIds.Resource:
|
|
@@ -8414,12 +8545,9 @@ const inflate = (container, target, typeId, data) => {
|
|
|
8414
8545
|
break;
|
|
8415
8546
|
case TypeIds.Store:
|
|
8416
8547
|
case TypeIds.StoreArray: {
|
|
8417
|
-
const [value, flags, effects
|
|
8548
|
+
const [value, flags, effects] = data;
|
|
8418
8549
|
const store = getOrCreateStore(value, flags, container);
|
|
8419
8550
|
const storeHandler = getStoreHandler(store);
|
|
8420
|
-
if (storeEffect) {
|
|
8421
|
-
effects[STORE_ARRAY_PROP] = storeEffect;
|
|
8422
|
-
}
|
|
8423
8551
|
storeHandler.$effects$ = effects;
|
|
8424
8552
|
target = store;
|
|
8425
8553
|
break;
|
|
@@ -8428,7 +8556,7 @@ const inflate = (container, target, typeId, data) => {
|
|
|
8428
8556
|
const signal = target;
|
|
8429
8557
|
const d = data;
|
|
8430
8558
|
signal.$untrackedValue$ = d[0];
|
|
8431
|
-
signal.$effects$ = d.slice(1);
|
|
8559
|
+
signal.$effects$ = new Set(d.slice(1));
|
|
8432
8560
|
break;
|
|
8433
8561
|
}
|
|
8434
8562
|
case TypeIds.WrappedSignal: {
|
|
@@ -8436,10 +8564,10 @@ const inflate = (container, target, typeId, data) => {
|
|
|
8436
8564
|
const d = data;
|
|
8437
8565
|
signal.$func$ = container.getSyncFn(d[0]);
|
|
8438
8566
|
signal.$args$ = d[1];
|
|
8439
|
-
signal
|
|
8567
|
+
signal[_EFFECT_BACK_REF] = d[2];
|
|
8440
8568
|
signal.$untrackedValue$ = d[3];
|
|
8441
8569
|
signal.$hostElement$ = d[4];
|
|
8442
|
-
signal.$effects$ = d.slice(5);
|
|
8570
|
+
signal.$effects$ = new Set(d.slice(5));
|
|
8443
8571
|
break;
|
|
8444
8572
|
}
|
|
8445
8573
|
case TypeIds.ComputedSignal: {
|
|
@@ -8559,6 +8687,7 @@ const _constants = [
|
|
|
8559
8687
|
EMPTY_ARRAY,
|
|
8560
8688
|
EMPTY_OBJ,
|
|
8561
8689
|
NEEDS_COMPUTATION,
|
|
8690
|
+
STORE_ARRAY_PROP,
|
|
8562
8691
|
Slot,
|
|
8563
8692
|
Fragment,
|
|
8564
8693
|
NaN,
|
|
@@ -8639,6 +8768,8 @@ const allocate = (container, typeId, value) => {
|
|
|
8639
8768
|
reject = rej;
|
|
8640
8769
|
});
|
|
8641
8770
|
resolvers.set(promise, [resolve, reject]);
|
|
8771
|
+
// Don't leave unhandled promise rejections
|
|
8772
|
+
promise.catch(() => { });
|
|
8642
8773
|
return promise;
|
|
8643
8774
|
case TypeIds.Uint8Array:
|
|
8644
8775
|
const encodedLength = value.length;
|
|
@@ -8648,12 +8779,9 @@ const allocate = (container, typeId, value) => {
|
|
|
8648
8779
|
return new Uint8Array(decodedLength);
|
|
8649
8780
|
case TypeIds.PropsProxy:
|
|
8650
8781
|
return createPropsProxy(null, null);
|
|
8651
|
-
case TypeIds.RefVNode:
|
|
8652
8782
|
case TypeIds.VNode:
|
|
8653
|
-
|
|
8654
|
-
|
|
8655
|
-
return vnodeOrDocument;
|
|
8656
|
-
}
|
|
8783
|
+
return retrieveVNodeOrDocument(container, value);
|
|
8784
|
+
case TypeIds.RefVNode:
|
|
8657
8785
|
const vNode = retrieveVNodeOrDocument(container, value);
|
|
8658
8786
|
if (vnode_isVNode(vNode)) {
|
|
8659
8787
|
return vnode_getNode(vNode);
|
|
@@ -8662,7 +8790,7 @@ const allocate = (container, typeId, value) => {
|
|
|
8662
8790
|
throw qError(QError.serializeErrorExpectedVNode, [typeof vNode]);
|
|
8663
8791
|
}
|
|
8664
8792
|
case TypeIds.EffectData:
|
|
8665
|
-
return new
|
|
8793
|
+
return new SubscriptionData({});
|
|
8666
8794
|
default:
|
|
8667
8795
|
throw qError(QError.serializeErrorCannotAllocate, [typeId]);
|
|
8668
8796
|
}
|
|
@@ -8694,7 +8822,7 @@ function parseQRL(qrl) {
|
|
|
8694
8822
|
assertDefined(backChannel, 'Missing QRL_RUNTIME_CHUNK');
|
|
8695
8823
|
qrlRef = backChannel.get(symbol);
|
|
8696
8824
|
}
|
|
8697
|
-
return createQRL(chunk, symbol, qrlRef, null, captureIds, null
|
|
8825
|
+
return createQRL(chunk, symbol, qrlRef, null, captureIds, null);
|
|
8698
8826
|
}
|
|
8699
8827
|
function inflateQRL(container, qrl) {
|
|
8700
8828
|
const captureIds = qrl.$capture$;
|
|
@@ -8812,7 +8940,7 @@ prepVNodeData) => {
|
|
|
8812
8940
|
/** Visit an object, adding anything that will be serialized as to scan */
|
|
8813
8941
|
const visit = (obj) => {
|
|
8814
8942
|
if (typeof obj === 'function') {
|
|
8815
|
-
if (isQrl(obj)) {
|
|
8943
|
+
if (isQrl$1(obj)) {
|
|
8816
8944
|
if (obj.$captureRef$) {
|
|
8817
8945
|
discoveredValues.push(...obj.$captureRef$);
|
|
8818
8946
|
}
|
|
@@ -8831,6 +8959,7 @@ prepVNodeData) => {
|
|
|
8831
8959
|
obj instanceof RegExp ||
|
|
8832
8960
|
obj instanceof Uint8Array ||
|
|
8833
8961
|
obj instanceof URLSearchParams ||
|
|
8962
|
+
vnode_isVNode(obj) ||
|
|
8834
8963
|
(typeof FormData !== 'undefined' && obj instanceof FormData) ||
|
|
8835
8964
|
// Ignore the no serialize objects
|
|
8836
8965
|
fastSkipSerialize(obj)) ;
|
|
@@ -8840,8 +8969,7 @@ prepVNodeData) => {
|
|
|
8840
8969
|
else if (isStore(obj)) {
|
|
8841
8970
|
const target = getStoreTarget(obj);
|
|
8842
8971
|
const effects = getStoreHandler(obj).$effects$;
|
|
8843
|
-
|
|
8844
|
-
discoveredValues.push(target, effects, storeEffect);
|
|
8972
|
+
discoveredValues.push(target, effects);
|
|
8845
8973
|
for (const prop in target) {
|
|
8846
8974
|
const propValue = target[prop];
|
|
8847
8975
|
if (storeProxyMap.has(propValue)) {
|
|
@@ -8875,9 +9003,7 @@ prepVNodeData) => {
|
|
|
8875
9003
|
}
|
|
8876
9004
|
// WrappedSignal uses syncQrl which has no captured refs
|
|
8877
9005
|
if (obj instanceof WrappedSignal) {
|
|
8878
|
-
|
|
8879
|
-
discoveredValues.push(...obj.$effectDependencies$);
|
|
8880
|
-
}
|
|
9006
|
+
discoverEffectBackRefs(obj[_EFFECT_BACK_REF], discoveredValues);
|
|
8881
9007
|
if (obj.$args$) {
|
|
8882
9008
|
discoveredValues.push(...obj.$args$);
|
|
8883
9009
|
}
|
|
@@ -8890,7 +9016,8 @@ prepVNodeData) => {
|
|
|
8890
9016
|
}
|
|
8891
9017
|
}
|
|
8892
9018
|
else if (obj instanceof Task) {
|
|
8893
|
-
discoveredValues.push(obj.$el$, obj.$qrl$, obj.$state
|
|
9019
|
+
discoveredValues.push(obj.$el$, obj.$qrl$, obj.$state$);
|
|
9020
|
+
discoverEffectBackRefs(obj[_EFFECT_BACK_REF], discoveredValues);
|
|
8894
9021
|
}
|
|
8895
9022
|
else if (isSsrNode(obj)) {
|
|
8896
9023
|
discoverValuesForVNodeData(obj.vnodeData, discoveredValues);
|
|
@@ -8909,7 +9036,7 @@ prepVNodeData) => {
|
|
|
8909
9036
|
else if (Array.isArray(obj)) {
|
|
8910
9037
|
discoveredValues.push(...obj);
|
|
8911
9038
|
}
|
|
8912
|
-
else if (isQrl(obj)) {
|
|
9039
|
+
else if (isQrl$1(obj)) {
|
|
8913
9040
|
obj.$captureRef$ && obj.$captureRef$.length && discoveredValues.push(...obj.$captureRef$);
|
|
8914
9041
|
}
|
|
8915
9042
|
else if (isPropsProxy(obj)) {
|
|
@@ -8925,7 +9052,7 @@ prepVNodeData) => {
|
|
|
8925
9052
|
});
|
|
8926
9053
|
promises.push(obj);
|
|
8927
9054
|
}
|
|
8928
|
-
else if (obj instanceof
|
|
9055
|
+
else if (obj instanceof SubscriptionData) {
|
|
8929
9056
|
discoveredValues.push(obj.data);
|
|
8930
9057
|
}
|
|
8931
9058
|
else if (isObjectLiteral(obj)) {
|
|
@@ -8970,15 +9097,31 @@ const discoverValuesForVNodeData = (vnodeData, discoveredValues) => {
|
|
|
8970
9097
|
for (const value of vnodeData) {
|
|
8971
9098
|
if (isSsrAttrs(value)) {
|
|
8972
9099
|
for (let i = 1; i < value.length; i += 2) {
|
|
8973
|
-
|
|
9100
|
+
const attrValue = value[i];
|
|
9101
|
+
if (typeof attrValue === 'string') {
|
|
8974
9102
|
continue;
|
|
8975
9103
|
}
|
|
8976
|
-
const attrValue = value[i];
|
|
8977
9104
|
discoveredValues.push(attrValue);
|
|
8978
9105
|
}
|
|
8979
9106
|
}
|
|
8980
9107
|
}
|
|
8981
9108
|
};
|
|
9109
|
+
const discoverEffectBackRefs = (effectsBackRefs, discoveredValues) => {
|
|
9110
|
+
if (effectsBackRefs) {
|
|
9111
|
+
// We need serialize effect subscriptions with back refs
|
|
9112
|
+
let hasBackRefs = false;
|
|
9113
|
+
for (const [, effect] of effectsBackRefs) {
|
|
9114
|
+
const backRefs = effect[EffectSubscriptionProp.BACK_REF];
|
|
9115
|
+
if (backRefs) {
|
|
9116
|
+
hasBackRefs = true;
|
|
9117
|
+
break;
|
|
9118
|
+
}
|
|
9119
|
+
}
|
|
9120
|
+
if (hasBackRefs) {
|
|
9121
|
+
discoveredValues.push(effectsBackRefs);
|
|
9122
|
+
}
|
|
9123
|
+
}
|
|
9124
|
+
};
|
|
8982
9125
|
const promiseResults = new WeakMap();
|
|
8983
9126
|
/**
|
|
8984
9127
|
* Format:
|
|
@@ -9050,7 +9193,7 @@ function serialize(serializationContext) {
|
|
|
9050
9193
|
else if (value === Fragment) {
|
|
9051
9194
|
output(TypeIds.Constant, Constants.Fragment);
|
|
9052
9195
|
}
|
|
9053
|
-
else if (isQrl(value)) {
|
|
9196
|
+
else if (isQrl$1(value)) {
|
|
9054
9197
|
const qrl = qrlToString(serializationContext, value);
|
|
9055
9198
|
const id = serializationContext.$addRoot$(qrl);
|
|
9056
9199
|
output(TypeIds.QRL, id);
|
|
@@ -9125,6 +9268,9 @@ function serialize(serializationContext) {
|
|
|
9125
9268
|
else if (value === NEEDS_COMPUTATION) {
|
|
9126
9269
|
output(TypeIds.Constant, Constants.NEEDS_COMPUTATION);
|
|
9127
9270
|
}
|
|
9271
|
+
else if (value === STORE_ARRAY_PROP) {
|
|
9272
|
+
output(TypeIds.Constant, Constants.STORE_ARRAY_PROP);
|
|
9273
|
+
}
|
|
9128
9274
|
else {
|
|
9129
9275
|
throw qError(QError.serializeErrorUnknownType, [typeof value]);
|
|
9130
9276
|
}
|
|
@@ -9161,7 +9307,7 @@ function serialize(serializationContext) {
|
|
|
9161
9307
|
: 0;
|
|
9162
9308
|
output(TypeIds.PropsProxy, out);
|
|
9163
9309
|
}
|
|
9164
|
-
else if (value instanceof
|
|
9310
|
+
else if (value instanceof SubscriptionData) {
|
|
9165
9311
|
output(TypeIds.EffectData, [value.data.$scopedStyleIdPrefix$, value.data.$isConst$]);
|
|
9166
9312
|
}
|
|
9167
9313
|
else if (isStore(value)) {
|
|
@@ -9172,6 +9318,7 @@ function serialize(serializationContext) {
|
|
|
9172
9318
|
if (!res) {
|
|
9173
9319
|
throw qError(QError.serializeErrorUnvisited, ['resource']);
|
|
9174
9320
|
}
|
|
9321
|
+
// TODO the effects include the resourcereturn which has duplicate data
|
|
9175
9322
|
output(TypeIds.Resource, [...res, getStoreHandler(value).$effects$]);
|
|
9176
9323
|
}
|
|
9177
9324
|
else {
|
|
@@ -9179,7 +9326,6 @@ function serialize(serializationContext) {
|
|
|
9179
9326
|
const storeTarget = getStoreTarget(value);
|
|
9180
9327
|
const flags = storeHandler.$flags$;
|
|
9181
9328
|
const effects = storeHandler.$effects$;
|
|
9182
|
-
const storeEffect = effects?.[STORE_ARRAY_PROP] ?? null;
|
|
9183
9329
|
const innerStores = [];
|
|
9184
9330
|
for (const prop in storeTarget) {
|
|
9185
9331
|
const propValue = storeTarget[prop];
|
|
@@ -9189,7 +9335,7 @@ function serialize(serializationContext) {
|
|
|
9189
9335
|
serializationContext.$addRoot$(innerStore);
|
|
9190
9336
|
}
|
|
9191
9337
|
}
|
|
9192
|
-
const out = [storeTarget, flags, effects,
|
|
9338
|
+
const out = [storeTarget, flags, effects, ...innerStores];
|
|
9193
9339
|
while (out[out.length - 1] == null) {
|
|
9194
9340
|
out.pop();
|
|
9195
9341
|
}
|
|
@@ -9228,7 +9374,7 @@ function serialize(serializationContext) {
|
|
|
9228
9374
|
if (value instanceof WrappedSignal) {
|
|
9229
9375
|
output(TypeIds.WrappedSignal, [
|
|
9230
9376
|
...serializeWrappingFn(serializationContext, value),
|
|
9231
|
-
value
|
|
9377
|
+
filterEffectBackRefs(value[_EFFECT_BACK_REF]),
|
|
9232
9378
|
v,
|
|
9233
9379
|
value.$hostElement$,
|
|
9234
9380
|
...(value.$effects$ || []),
|
|
@@ -9335,7 +9481,7 @@ function serialize(serializationContext) {
|
|
|
9335
9481
|
value.$flags$,
|
|
9336
9482
|
value.$index$,
|
|
9337
9483
|
value.$el$,
|
|
9338
|
-
value
|
|
9484
|
+
value[_EFFECT_BACK_REF],
|
|
9339
9485
|
value.$state$,
|
|
9340
9486
|
];
|
|
9341
9487
|
while (out[out.length - 1] == null) {
|
|
@@ -9358,12 +9504,27 @@ function serialize(serializationContext) {
|
|
|
9358
9504
|
const out = btoa(buf).replace(/=+$/, '');
|
|
9359
9505
|
output(TypeIds.Uint8Array, out);
|
|
9360
9506
|
}
|
|
9507
|
+
else if (vnode_isVNode(value)) {
|
|
9508
|
+
output(TypeIds.Constant, Constants.Undefined);
|
|
9509
|
+
}
|
|
9361
9510
|
else {
|
|
9362
9511
|
throw qError(QError.serializeErrorUnknownType, [typeof value]);
|
|
9363
9512
|
}
|
|
9364
9513
|
};
|
|
9365
9514
|
writeValue(serializationContext.$roots$, -1);
|
|
9366
9515
|
}
|
|
9516
|
+
function filterEffectBackRefs(effectBackRef) {
|
|
9517
|
+
let effectBackRefToSerialize = null;
|
|
9518
|
+
if (effectBackRef) {
|
|
9519
|
+
for (const [effectProp, effect] of effectBackRef) {
|
|
9520
|
+
if (effect[EffectSubscriptionProp.BACK_REF]) {
|
|
9521
|
+
effectBackRefToSerialize ||= new Map();
|
|
9522
|
+
effectBackRefToSerialize.set(effectProp, effect);
|
|
9523
|
+
}
|
|
9524
|
+
}
|
|
9525
|
+
}
|
|
9526
|
+
return effectBackRefToSerialize;
|
|
9527
|
+
}
|
|
9367
9528
|
function serializeWrappingFn(serializationContext, value) {
|
|
9368
9529
|
// if value is an object then we need to wrap this in ()
|
|
9369
9530
|
if (value.$funcStr$ && value.$funcStr$[0] === '{') {
|
|
@@ -9376,15 +9537,12 @@ function serializeWrappingFn(serializationContext, value) {
|
|
|
9376
9537
|
function qrlToString(serializationContext, value) {
|
|
9377
9538
|
let symbol = value.$symbol$;
|
|
9378
9539
|
let chunk = value.$chunk$;
|
|
9379
|
-
const refSymbol = value.$refSymbol$ ?? symbol;
|
|
9380
9540
|
const platform = getPlatform();
|
|
9381
9541
|
if (platform) {
|
|
9382
|
-
const result = platform.chunkForSymbol(
|
|
9542
|
+
const result = platform.chunkForSymbol(symbol, chunk, value.dev?.file);
|
|
9383
9543
|
if (result) {
|
|
9384
9544
|
chunk = result[1];
|
|
9385
|
-
|
|
9386
|
-
symbol = result[0];
|
|
9387
|
-
}
|
|
9545
|
+
symbol = result[0];
|
|
9388
9546
|
}
|
|
9389
9547
|
}
|
|
9390
9548
|
const isSync = isSyncQrl(value);
|
|
@@ -9561,9 +9719,9 @@ const frameworkType = (obj) => {
|
|
|
9561
9719
|
return ((typeof obj === 'object' &&
|
|
9562
9720
|
obj !== null &&
|
|
9563
9721
|
(obj instanceof Signal || obj instanceof Task || isJSXNode(obj))) ||
|
|
9564
|
-
isQrl(obj));
|
|
9722
|
+
isQrl$1(obj));
|
|
9565
9723
|
};
|
|
9566
|
-
const canSerialize = (value) => {
|
|
9724
|
+
const canSerialize = (value, seen = new WeakSet()) => {
|
|
9567
9725
|
if (value == null ||
|
|
9568
9726
|
typeof value === 'string' ||
|
|
9569
9727
|
typeof value === 'number' ||
|
|
@@ -9572,6 +9730,10 @@ const canSerialize = (value) => {
|
|
|
9572
9730
|
return true;
|
|
9573
9731
|
}
|
|
9574
9732
|
else if (typeof value === 'object') {
|
|
9733
|
+
if (seen.has(value)) {
|
|
9734
|
+
return true;
|
|
9735
|
+
}
|
|
9736
|
+
seen.add(value);
|
|
9575
9737
|
const proto = Object.getPrototypeOf(value);
|
|
9576
9738
|
if (isStore(value)) {
|
|
9577
9739
|
value = getStoreTarget(value);
|
|
@@ -9580,7 +9742,7 @@ const canSerialize = (value) => {
|
|
|
9580
9742
|
for (const key in value) {
|
|
9581
9743
|
// if the value is a props proxy, then sometimes we could create a component-level subscription,
|
|
9582
9744
|
// so we should call untrack here to avoid tracking the value
|
|
9583
|
-
if (!canSerialize(untrack(() => value[key]))) {
|
|
9745
|
+
if (!canSerialize(untrack(() => value[key]), seen)) {
|
|
9584
9746
|
return false;
|
|
9585
9747
|
}
|
|
9586
9748
|
}
|
|
@@ -9588,7 +9750,7 @@ const canSerialize = (value) => {
|
|
|
9588
9750
|
}
|
|
9589
9751
|
else if (proto == Array.prototype) {
|
|
9590
9752
|
for (let i = 0; i < value.length; i++) {
|
|
9591
|
-
if (!canSerialize(value[i])) {
|
|
9753
|
+
if (!canSerialize(value[i], seen)) {
|
|
9592
9754
|
return false;
|
|
9593
9755
|
}
|
|
9594
9756
|
}
|
|
@@ -9638,7 +9800,7 @@ const canSerialize = (value) => {
|
|
|
9638
9800
|
}
|
|
9639
9801
|
}
|
|
9640
9802
|
else if (typeof value === 'function') {
|
|
9641
|
-
if (isQrl(value) || isQwikComponent(value)) {
|
|
9803
|
+
if (isQrl$1(value) || isQwikComponent(value)) {
|
|
9642
9804
|
return true;
|
|
9643
9805
|
}
|
|
9644
9806
|
}
|
|
@@ -9691,20 +9853,21 @@ var Constants;
|
|
|
9691
9853
|
Constants[Constants["EMPTY_ARRAY"] = 5] = "EMPTY_ARRAY";
|
|
9692
9854
|
Constants[Constants["EMPTY_OBJ"] = 6] = "EMPTY_OBJ";
|
|
9693
9855
|
Constants[Constants["NEEDS_COMPUTATION"] = 7] = "NEEDS_COMPUTATION";
|
|
9694
|
-
Constants[Constants["
|
|
9695
|
-
Constants[Constants["
|
|
9696
|
-
Constants[Constants["
|
|
9697
|
-
Constants[Constants["
|
|
9698
|
-
Constants[Constants["
|
|
9699
|
-
Constants[Constants["
|
|
9856
|
+
Constants[Constants["STORE_ARRAY_PROP"] = 8] = "STORE_ARRAY_PROP";
|
|
9857
|
+
Constants[Constants["Slot"] = 9] = "Slot";
|
|
9858
|
+
Constants[Constants["Fragment"] = 10] = "Fragment";
|
|
9859
|
+
Constants[Constants["NaN"] = 11] = "NaN";
|
|
9860
|
+
Constants[Constants["PositiveInfinity"] = 12] = "PositiveInfinity";
|
|
9861
|
+
Constants[Constants["NegativeInfinity"] = 13] = "NegativeInfinity";
|
|
9862
|
+
Constants[Constants["MaxSafeInt"] = 14] = "MaxSafeInt";
|
|
9700
9863
|
// used for close fragment
|
|
9701
|
-
Constants[Constants["AlmostMaxSafeInt"] =
|
|
9702
|
-
Constants[Constants["MinSafeInt"] =
|
|
9864
|
+
Constants[Constants["AlmostMaxSafeInt"] = 15] = "AlmostMaxSafeInt";
|
|
9865
|
+
Constants[Constants["MinSafeInt"] = 16] = "MinSafeInt";
|
|
9703
9866
|
})(Constants || (Constants = {}));
|
|
9704
9867
|
|
|
9705
9868
|
/** @internal */
|
|
9706
9869
|
const verifySerializable = (value, preMessage) => {
|
|
9707
|
-
const seen = new
|
|
9870
|
+
const seen = new WeakSet();
|
|
9708
9871
|
return _verifySerializable(value, seen, '_', preMessage);
|
|
9709
9872
|
};
|
|
9710
9873
|
const _verifySerializable = (value, seen, ctx, preMessage) => {
|
|
@@ -9713,10 +9876,12 @@ const _verifySerializable = (value, seen, ctx, preMessage) => {
|
|
|
9713
9876
|
return value;
|
|
9714
9877
|
}
|
|
9715
9878
|
if (shouldSerialize(unwrapped)) {
|
|
9716
|
-
if (
|
|
9717
|
-
|
|
9879
|
+
if (typeof unwrapped === 'object') {
|
|
9880
|
+
if (seen.has(unwrapped)) {
|
|
9881
|
+
return value;
|
|
9882
|
+
}
|
|
9883
|
+
seen.add(unwrapped);
|
|
9718
9884
|
}
|
|
9719
|
-
seen.add(unwrapped);
|
|
9720
9885
|
if (isSignal(unwrapped)) {
|
|
9721
9886
|
return value;
|
|
9722
9887
|
}
|
|
@@ -9820,16 +9985,7 @@ const _weakSerialize = (input) => {
|
|
|
9820
9985
|
return input;
|
|
9821
9986
|
};
|
|
9822
9987
|
|
|
9823
|
-
const
|
|
9824
|
-
return typeof value === 'function' && typeof value.getSymbol === 'function';
|
|
9825
|
-
};
|
|
9826
|
-
// Make sure this value is same as value in `platform.ts`
|
|
9827
|
-
const SYNC_QRL = '<sync>';
|
|
9828
|
-
/** Sync QRL is a function which is serialized into `<script q:func="qwik/json">` tag. */
|
|
9829
|
-
const isSyncQrl = (value) => {
|
|
9830
|
-
return isQrl(value) && value.$symbol$ == SYNC_QRL;
|
|
9831
|
-
};
|
|
9832
|
-
const createQRL = (chunk, symbol, symbolRef, symbolFn, capture, captureRef, refSymbol) => {
|
|
9988
|
+
const createQRL = (chunk, symbol, symbolRef, symbolFn, capture, captureRef) => {
|
|
9833
9989
|
if (qDev && qSerialize) {
|
|
9834
9990
|
if (captureRef) {
|
|
9835
9991
|
for (const item of captureRef) {
|
|
@@ -9851,9 +10007,14 @@ const createQRL = (chunk, symbol, symbolRef, symbolFn, capture, captureRef, refS
|
|
|
9851
10007
|
};
|
|
9852
10008
|
function bindFnToContext(currentCtx, beforeFn) {
|
|
9853
10009
|
// Note that we bind the current `this`
|
|
9854
|
-
|
|
9855
|
-
if (!
|
|
9856
|
-
|
|
10010
|
+
const bound = (...args) => {
|
|
10011
|
+
if (!qrl.resolved) {
|
|
10012
|
+
return qrl.resolve().then((fn) => {
|
|
10013
|
+
if (!isFunction(fn)) {
|
|
10014
|
+
throw qError(QError.qrlIsNotFunction);
|
|
10015
|
+
}
|
|
10016
|
+
return bound(...args);
|
|
10017
|
+
});
|
|
9857
10018
|
}
|
|
9858
10019
|
if (beforeFn && beforeFn() === false) {
|
|
9859
10020
|
return;
|
|
@@ -9866,13 +10027,14 @@ const createQRL = (chunk, symbol, symbolRef, symbolFn, capture, captureRef, refS
|
|
|
9866
10027
|
context.$qrl$ = qrl;
|
|
9867
10028
|
context.$event$ ||= this;
|
|
9868
10029
|
try {
|
|
9869
|
-
return invoke.call(this, context,
|
|
10030
|
+
return invoke.call(this, context, symbolRef, ...args);
|
|
9870
10031
|
}
|
|
9871
10032
|
finally {
|
|
9872
10033
|
context.$qrl$ = prevQrl;
|
|
9873
10034
|
context.$event$ = prevEvent;
|
|
9874
10035
|
}
|
|
9875
|
-
}
|
|
10036
|
+
};
|
|
10037
|
+
return bound;
|
|
9876
10038
|
}
|
|
9877
10039
|
const resolveLazy = (containerEl) => {
|
|
9878
10040
|
return symbolRef !== null ? symbolRef : resolve(containerEl);
|
|
@@ -9884,8 +10046,20 @@ const createQRL = (chunk, symbol, symbolRef, symbolFn, capture, captureRef, refS
|
|
|
9884
10046
|
}
|
|
9885
10047
|
return function (...args) {
|
|
9886
10048
|
let context = tryGetInvokeContext();
|
|
10049
|
+
// use the given qrl if it is the right one
|
|
9887
10050
|
if (context) {
|
|
9888
|
-
|
|
10051
|
+
// TODO check if this is necessary in production
|
|
10052
|
+
if (context.$qrl$?.$symbol$ === qrl.$symbol$) {
|
|
10053
|
+
return fn.apply(this, args);
|
|
10054
|
+
}
|
|
10055
|
+
const prevQrl = context.$qrl$;
|
|
10056
|
+
context.$qrl$ = qrl;
|
|
10057
|
+
try {
|
|
10058
|
+
return fn.apply(this, args);
|
|
10059
|
+
}
|
|
10060
|
+
finally {
|
|
10061
|
+
context.$qrl$ = prevQrl;
|
|
10062
|
+
}
|
|
9889
10063
|
}
|
|
9890
10064
|
context = newInvokeContext();
|
|
9891
10065
|
context.$qrl$ = qrl;
|
|
@@ -9913,11 +10087,11 @@ const createQRL = (chunk, symbol, symbolRef, symbolFn, capture, captureRef, refS
|
|
|
9913
10087
|
const start = now();
|
|
9914
10088
|
const ctx = tryGetInvokeContext();
|
|
9915
10089
|
if (symbolFn !== null) {
|
|
9916
|
-
symbolRef = symbolFn().then((module) => (qrl.resolved = symbolRef =
|
|
10090
|
+
symbolRef = symbolFn().then((module) => (qrl.resolved = wrapFn((symbolRef = module[symbol]))));
|
|
9917
10091
|
}
|
|
9918
10092
|
else {
|
|
9919
10093
|
const imported = getPlatform().importSymbol(_containerEl, chunk, symbol);
|
|
9920
|
-
symbolRef = maybeThen(imported, (ref) => (qrl.resolved = symbolRef =
|
|
10094
|
+
symbolRef = maybeThen(imported, (ref) => (qrl.resolved = wrapFn((symbolRef = ref))));
|
|
9921
10095
|
}
|
|
9922
10096
|
if (typeof symbolRef === 'object' && isPromise(symbolRef)) {
|
|
9923
10097
|
symbolRef.then(() => emitUsedSymbol(symbol, ctx?.$element$, start), (err) => {
|
|
@@ -9940,10 +10114,9 @@ const createQRL = (chunk, symbol, symbolRef, symbolFn, capture, captureRef, refS
|
|
|
9940
10114
|
return invoke;
|
|
9941
10115
|
}
|
|
9942
10116
|
};
|
|
9943
|
-
const
|
|
9944
|
-
const hash = getSymbolHash(resolvedSymbol);
|
|
10117
|
+
const hash = getSymbolHash(symbol);
|
|
9945
10118
|
Object.assign(qrl, {
|
|
9946
|
-
getSymbol: () =>
|
|
10119
|
+
getSymbol: () => symbol,
|
|
9947
10120
|
getHash: () => hash,
|
|
9948
10121
|
getCaptured: () => captureRef,
|
|
9949
10122
|
resolve,
|
|
@@ -9951,7 +10124,6 @@ const createQRL = (chunk, symbol, symbolRef, symbolFn, capture, captureRef, refS
|
|
|
9951
10124
|
$setContainer$: setContainer,
|
|
9952
10125
|
$chunk$: chunk,
|
|
9953
10126
|
$symbol$: symbol,
|
|
9954
|
-
$refSymbol$: refSymbol,
|
|
9955
10127
|
$hash$: hash,
|
|
9956
10128
|
getFn: bindFnToContext,
|
|
9957
10129
|
$capture$: capture,
|
|
@@ -9960,8 +10132,8 @@ const createQRL = (chunk, symbol, symbolRef, symbolFn, capture, captureRef, refS
|
|
|
9960
10132
|
resolved: undefined,
|
|
9961
10133
|
});
|
|
9962
10134
|
if (symbolRef) {
|
|
9963
|
-
//
|
|
9964
|
-
symbolRef = maybeThen(symbolRef, (resolved) => (qrl.resolved = symbolRef =
|
|
10135
|
+
// Unwrap any promises
|
|
10136
|
+
symbolRef = maybeThen(symbolRef, (resolved) => (qrl.resolved = wrapFn((symbolRef = resolved))));
|
|
9965
10137
|
}
|
|
9966
10138
|
if (isDev) {
|
|
9967
10139
|
Object.defineProperty(qrl, '_devOnlySymbolRef', {
|
|
@@ -9975,20 +10147,6 @@ const createQRL = (chunk, symbol, symbolRef, symbolFn, capture, captureRef, refS
|
|
|
9975
10147
|
}
|
|
9976
10148
|
return qrl;
|
|
9977
10149
|
};
|
|
9978
|
-
const getSymbolHash = (symbolName) => {
|
|
9979
|
-
const index = symbolName.lastIndexOf('_');
|
|
9980
|
-
if (index > -1) {
|
|
9981
|
-
return symbolName.slice(index + 1);
|
|
9982
|
-
}
|
|
9983
|
-
return symbolName;
|
|
9984
|
-
};
|
|
9985
|
-
function assertQrl(qrl) {
|
|
9986
|
-
if (qDev) {
|
|
9987
|
-
if (!isQrl(qrl)) {
|
|
9988
|
-
throw new Error('Not a QRL');
|
|
9989
|
-
}
|
|
9990
|
-
}
|
|
9991
|
-
}
|
|
9992
10150
|
const EMITTED = /*#__PURE__*/ new Set();
|
|
9993
10151
|
const emitUsedSymbol = (symbol, element, reqTime) => {
|
|
9994
10152
|
if (!EMITTED.has(symbol)) {
|
|
@@ -10101,7 +10259,7 @@ const $ = (expression) => {
|
|
|
10101
10259
|
if (!qRuntimeQrl && qDev) {
|
|
10102
10260
|
throw new Error('Optimizer should replace all usages of $() with some special syntax. If you need to create a QRL manually, use inlinedQrl() instead.');
|
|
10103
10261
|
}
|
|
10104
|
-
return createQRL(null, 's' + runtimeSymbolId++, expression, null, null, null
|
|
10262
|
+
return createQRL(null, 's' + runtimeSymbolId++, expression, null, null, null);
|
|
10105
10263
|
};
|
|
10106
10264
|
/** @private Use To avoid optimizer replacement */
|
|
10107
10265
|
const dollar = $;
|
|
@@ -10127,7 +10285,7 @@ const sync$ = (fn) => {
|
|
|
10127
10285
|
// eslint-disable-next-line no-new-func
|
|
10128
10286
|
fn = new Function('return ' + fn.toString())();
|
|
10129
10287
|
}
|
|
10130
|
-
return createQRL('', SYNC_QRL, fn, null, null, null
|
|
10288
|
+
return createQRL('', SYNC_QRL, fn, null, null, null);
|
|
10131
10289
|
};
|
|
10132
10290
|
/**
|
|
10133
10291
|
* Extract function into a synchronously loadable QRL.
|
|
@@ -10144,7 +10302,7 @@ const _qrlSync = function (fn, serializedFn) {
|
|
|
10144
10302
|
serializedFn = fn.toString();
|
|
10145
10303
|
}
|
|
10146
10304
|
fn.serialized = serializedFn;
|
|
10147
|
-
return createQRL('', SYNC_QRL, fn, null, null, null
|
|
10305
|
+
return createQRL('', SYNC_QRL, fn, null, null, null);
|
|
10148
10306
|
};
|
|
10149
10307
|
|
|
10150
10308
|
/** @internal */
|
|
@@ -10863,6 +11021,21 @@ const useVisibleTaskQrl = (qrl, opts) => {
|
|
|
10863
11021
|
iCtx.$container$.$scheduler$(ChoreType.VISIBLE, task);
|
|
10864
11022
|
}
|
|
10865
11023
|
};
|
|
11024
|
+
const useRunTask = (task, eagerness) => {
|
|
11025
|
+
if (eagerness === 'intersection-observer') {
|
|
11026
|
+
useOn('qvisible', getTaskHandlerQrl(task));
|
|
11027
|
+
}
|
|
11028
|
+
else if (eagerness === 'document-ready') {
|
|
11029
|
+
useOnDocument('qinit', getTaskHandlerQrl(task));
|
|
11030
|
+
}
|
|
11031
|
+
else if (eagerness === 'document-idle') {
|
|
11032
|
+
useOnDocument('qidle', getTaskHandlerQrl(task));
|
|
11033
|
+
}
|
|
11034
|
+
};
|
|
11035
|
+
const getTaskHandlerQrl = (task) => {
|
|
11036
|
+
const taskHandler = createQRL(null, '_task', scheduleTask, null, null, [task]);
|
|
11037
|
+
return taskHandler;
|
|
11038
|
+
};
|
|
10866
11039
|
|
|
10867
11040
|
// <docs markdown="../readme.md#useResource">
|
|
10868
11041
|
// !!DO NOT EDIT THIS COMMENT DIRECTLY!!!
|
|
@@ -11173,5 +11346,5 @@ const PrefetchGraph = (opts = {}) => {
|
|
|
11173
11346
|
return _jsxSorted('script', null, props, null, 0, 'prefetch-graph');
|
|
11174
11347
|
};
|
|
11175
11348
|
|
|
11176
|
-
export { $, Fragment, PrefetchGraph, PrefetchServiceWorker, RenderOnce, Resource, SSRComment, SSRRaw, SSRStream, SSRStreamBlock, SkipRender, Slot, _CONST_PROPS, DomContainer as _DomContainer, EMPTY_ARRAY as _EMPTY_ARRAY,
|
|
11349
|
+
export { $, Fragment, PrefetchGraph, PrefetchServiceWorker, RenderOnce, Resource, SSRComment, SSRRaw, SSRStream, SSRStreamBlock, SkipRender, Slot, _CONST_PROPS, DomContainer as _DomContainer, _EFFECT_BACK_REF, EMPTY_ARRAY as _EMPTY_ARRAY, SubscriptionData as _EffectData, _IMMUTABLE, _SharedContainer, _VAR_PROPS, _deserialize, _fnSignal, _getContextElement, _getContextEvent, getDomContainer as _getDomContainer, _getQContainerElement, isJSXNode as _isJSXNode, isStringifiable as _isStringifiable, _jsxBranch, _jsxC, _jsxQ, _jsxS, _jsxSorted, _jsxSplit, _noopQrl, _noopQrlDEV, _qrlSync, _regSymbol, _restProps, queueQRL as _run, _serialize, scheduleTask as _task, verifySerializable as _verifySerializable, _waitUntilRendered, _walkJSX, _weakSerialize, _wrapProp, _wrapSignal, component$, componentQrl, createComputed$, createComputedQrl, createContextId, h as createElement, createSignal, event$, eventQrl, getDomContainer, getLocale, getPlatform, h, implicit$FirstArg, inlinedQrl, inlinedQrlDEV, isSignal, jsx, jsxDEV, jsx as jsxs, noSerialize, qrl, qrlDEV, render, setPlatform, sync$, untrack, unwrapStore, useComputed$, useComputedQrl, useConstant, useContext, useContextProvider, useErrorBoundary, useId, useLexicalScope, useOn, useOnDocument, useOnWindow, useResource$, useResourceQrl, useServerData, useSignal, useStore, useStyles$, useStylesQrl, useStylesScoped$, useStylesScopedQrl, useTask$, useTaskQrl, useVisibleTask$, useVisibleTaskQrl, version, withLocale };
|
|
11177
11350
|
//# sourceMappingURL=core.mjs.map
|