@qwik.dev/core 2.0.0-beta.28 → 2.0.0-beta.29
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.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/backpatch/package.json +1 -1
- package/dist/build/package.json +1 -1
- package/dist/cli.mjs +2 -2
- package/dist/core-internal.d.ts +81 -10
- package/dist/core.min.mjs +1 -1
- package/dist/core.mjs +431 -201
- package/dist/core.mjs.map +1 -1
- package/dist/core.prod.mjs +2440 -2309
- package/dist/loader/package.json +1 -1
- package/dist/optimizer.mjs +2 -2
- package/dist/server.mjs +2 -2
- package/dist/server.prod.mjs +254 -254
- package/dist/testing/index.d.ts +42 -8
- package/dist/testing/index.mjs +407 -291
- package/dist/testing/package.json +1 -1
- package/package.json +2 -2
- package/public.d.ts +1 -0
package/dist/core.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* @qwik.dev/core 2.0.0-beta.
|
|
3
|
+
* @qwik.dev/core 2.0.0-beta.29-dev+bc61b71
|
|
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
|
|
@@ -270,11 +270,8 @@ function assertQrl(qrl) {
|
|
|
270
270
|
}
|
|
271
271
|
}
|
|
272
272
|
const getSymbolHash = (symbolName) => {
|
|
273
|
-
const index = symbolName.lastIndexOf('_');
|
|
274
|
-
|
|
275
|
-
return symbolName.slice(index + 1);
|
|
276
|
-
}
|
|
277
|
-
return symbolName;
|
|
273
|
+
const index = symbolName.lastIndexOf('_') + 1;
|
|
274
|
+
return symbolName.slice(index);
|
|
278
275
|
};
|
|
279
276
|
|
|
280
277
|
/**
|
|
@@ -385,6 +382,8 @@ function decodeVNodeDataString(str) {
|
|
|
385
382
|
|
|
386
383
|
/** State factory of the component. */
|
|
387
384
|
const OnRenderProp = 'q:renderFn';
|
|
385
|
+
/** Target DOM element for external projection rendering. */
|
|
386
|
+
const QTargetElement = 'q:targetEl';
|
|
388
387
|
/** Component style content prefix */
|
|
389
388
|
const ComponentStylesPrefixContent = '⚡️';
|
|
390
389
|
/** `<some-element q:slot="...">` */
|
|
@@ -1008,7 +1007,7 @@ const COMMA = ',';
|
|
|
1008
1007
|
*
|
|
1009
1008
|
* @public
|
|
1010
1009
|
*/
|
|
1011
|
-
const version = "2.0.0-beta.
|
|
1010
|
+
const version = "2.0.0-beta.29-dev+bc61b71";
|
|
1012
1011
|
|
|
1013
1012
|
// keep this import from core/build so the cjs build works
|
|
1014
1013
|
const createPlatform = () => {
|
|
@@ -2073,7 +2072,7 @@ class ComputedSignalImpl extends SignalImpl {
|
|
|
2073
2072
|
16 /* SerializationSignalFlags.SERIALIZATION_STRATEGY_ALWAYS */) {
|
|
2074
2073
|
// The value is used for comparison when signals trigger, which can only happen
|
|
2075
2074
|
// when it was calculated before. Therefore we can pass whatever we like.
|
|
2076
|
-
super(container ||
|
|
2075
|
+
super(container || tryGetInvokeContext()?.$container$, NEEDS_COMPUTATION);
|
|
2077
2076
|
this.$computeQrl$ = fn;
|
|
2078
2077
|
this.$flags$ = flags;
|
|
2079
2078
|
}
|
|
@@ -6324,14 +6323,14 @@ const createFastGetter = (propName) => {
|
|
|
6324
6323
|
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
6325
6324
|
const vnode_newElement = (element, elementName, key = null) => {
|
|
6326
6325
|
isDev && assertEqual(fastNodeType(element), 1 /* ELEMENT_NODE */, 'Expecting element node.');
|
|
6327
|
-
const vnode = new ElementVNode(key, 1 /* VNodeFlags.Element */ | 8 /* VNodeFlags.Inflated */ | (-1 <<
|
|
6326
|
+
const vnode = new ElementVNode(key, 1 /* VNodeFlags.Element */ | 8 /* VNodeFlags.Inflated */ | (-1 << 12 /* VNodeFlagsIndex.shift */), // Flag
|
|
6328
6327
|
null, null, null, null, null, null, element, elementName);
|
|
6329
6328
|
element.vNode = vnode;
|
|
6330
6329
|
return vnode;
|
|
6331
6330
|
};
|
|
6332
6331
|
const vnode_newUnMaterializedElement = (element) => {
|
|
6333
6332
|
isDev && assertEqual(fastNodeType(element), 1 /* ELEMENT_NODE */, 'Expecting element node.');
|
|
6334
|
-
const vnode = new ElementVNode(null, 1 /* VNodeFlags.Element */ | (-1 <<
|
|
6333
|
+
const vnode = new ElementVNode(null, 1 /* VNodeFlags.Element */ | (-1 << 12 /* VNodeFlagsIndex.shift */), // Flag
|
|
6335
6334
|
null, null, null, null, undefined, undefined, element, undefined);
|
|
6336
6335
|
element.vNode = vnode;
|
|
6337
6336
|
return vnode;
|
|
@@ -6340,7 +6339,7 @@ const vnode_newSharedText = (previousTextNode, sharedTextNode, textContent) => {
|
|
|
6340
6339
|
isDev &&
|
|
6341
6340
|
sharedTextNode &&
|
|
6342
6341
|
assertEqual(fastNodeType(sharedTextNode), 3 /* TEXT_NODE */, 'Expecting text node.');
|
|
6343
|
-
const vnode = new TextVNode(4 /* VNodeFlags.Text */ | (-1 <<
|
|
6342
|
+
const vnode = new TextVNode(4 /* VNodeFlags.Text */ | (-1 << 12 /* VNodeFlagsIndex.shift */), // Flag
|
|
6344
6343
|
null, // Parent
|
|
6345
6344
|
previousTextNode, // Previous TextNode (usually first child)
|
|
6346
6345
|
null, // Next sibling
|
|
@@ -6348,7 +6347,7 @@ const vnode_newSharedText = (previousTextNode, sharedTextNode, textContent) => {
|
|
|
6348
6347
|
return vnode;
|
|
6349
6348
|
};
|
|
6350
6349
|
const vnode_newText = (textNode, textContent) => {
|
|
6351
|
-
const vnode = new TextVNode(4 /* VNodeFlags.Text */ | 8 /* VNodeFlags.Inflated */ | (-1 <<
|
|
6350
|
+
const vnode = new TextVNode(4 /* VNodeFlags.Text */ | 8 /* VNodeFlags.Inflated */ | (-1 << 12 /* VNodeFlagsIndex.shift */), // Flags
|
|
6352
6351
|
null, // Parent
|
|
6353
6352
|
null, // No previous sibling
|
|
6354
6353
|
null, // We may have a next sibling.
|
|
@@ -6362,7 +6361,7 @@ const vnode_newText = (textNode, textContent) => {
|
|
|
6362
6361
|
return vnode;
|
|
6363
6362
|
};
|
|
6364
6363
|
const vnode_newVirtual = () => {
|
|
6365
|
-
const vnode = new VirtualVNode(null, 2 /* VNodeFlags.Virtual */ | (-1 <<
|
|
6364
|
+
const vnode = new VirtualVNode(null, 2 /* VNodeFlags.Virtual */ | (-1 << 12 /* VNodeFlagsIndex.shift */), // Flags
|
|
6366
6365
|
null, null, null, null, null, null);
|
|
6367
6366
|
isDev && assertFalse(vnode_isElementVNode(vnode), 'Incorrect format of TextVNode.');
|
|
6368
6367
|
isDev && assertFalse(vnode_isTextVNode(vnode), 'Incorrect format of TextVNode.');
|
|
@@ -6522,8 +6521,7 @@ function registerQrlHandlers(attr, key, container, element) {
|
|
|
6522
6521
|
const scopedKebabName = key.slice(2);
|
|
6523
6522
|
const qrls = value.split('|');
|
|
6524
6523
|
const handlers = qrls.map((qrl) => {
|
|
6525
|
-
const handler = parseQRL(qrl);
|
|
6526
|
-
handler.$container$ = container;
|
|
6524
|
+
const handler = parseQRL(qrl, container);
|
|
6527
6525
|
// These QRLs are mostly _run and _task and don't need wrapping with retryOnPromise
|
|
6528
6526
|
return handler;
|
|
6529
6527
|
});
|
|
@@ -6818,7 +6816,7 @@ const vnode_locate = (rootVNode, id) => {
|
|
|
6818
6816
|
const vnode_getChildWithIdx = (vNode, childIdx) => {
|
|
6819
6817
|
let child = vnode_getFirstChild(vNode);
|
|
6820
6818
|
isDev && assertDefined(child, 'Missing child.');
|
|
6821
|
-
while (child.flags >>>
|
|
6819
|
+
while (child.flags >>> 12 /* VNodeFlagsIndex.shift */ !== childIdx) {
|
|
6822
6820
|
child = child.nextSibling;
|
|
6823
6821
|
isDev && assertDefined(child, 'Missing child.');
|
|
6824
6822
|
}
|
|
@@ -6894,6 +6892,7 @@ const vnode_createErrorDiv = (journal, document, host, err) => {
|
|
|
6894
6892
|
}
|
|
6895
6893
|
return vErrorDiv;
|
|
6896
6894
|
};
|
|
6895
|
+
const vnode_applyJournal = _flushJournal;
|
|
6897
6896
|
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
6898
6897
|
const vnode_insertElementBefore = (journal, parent, newChild, insertBefore) => {
|
|
6899
6898
|
ensureElementOrVirtualVNode(parent);
|
|
@@ -6949,8 +6948,15 @@ const vnode_insertVirtualBefore = (journal, parent, newChild, insertBefore) => {
|
|
|
6949
6948
|
}
|
|
6950
6949
|
vnode_unlinkFromOldParent(journal, newChildCurrentParent, parent, newChild);
|
|
6951
6950
|
const parentIsDeleted = parent.flags & 32 /* VNodeFlags.Deleted */;
|
|
6952
|
-
const
|
|
6953
|
-
|
|
6951
|
+
const targetEl = !parentIsElement && parent.flags & 2048 /* VNodeFlags.HasTargetElement */
|
|
6952
|
+
? parent.props?.[QTargetElement]
|
|
6953
|
+
: null;
|
|
6954
|
+
const domParentVNode = targetEl
|
|
6955
|
+
? null
|
|
6956
|
+
: parentIsElement
|
|
6957
|
+
? parent
|
|
6958
|
+
: vnode_getDomParentVNode(parent, false);
|
|
6959
|
+
const parentNode = targetEl || domParentVNode?.node;
|
|
6954
6960
|
const adjustedInsertBefore = vnode_findInsertBefore(journal, parent, insertBefore);
|
|
6955
6961
|
const adjustedInsertBeforeNode = adjustedInsertBefore?.node ?? null;
|
|
6956
6962
|
const isProjection = vnode_isProjection(newChild);
|
|
@@ -7139,8 +7145,13 @@ const vnode_insertBefore = (journal, parent, newChild, insertBefore) => {
|
|
|
7139
7145
|
}
|
|
7140
7146
|
};
|
|
7141
7147
|
const vnode_getDomParent = (vnode, includeProjection) => {
|
|
7142
|
-
vnode
|
|
7143
|
-
|
|
7148
|
+
while (vnode && !vnode_isElementVNode(vnode)) {
|
|
7149
|
+
if (vnode.flags & 2048 /* VNodeFlags.HasTargetElement */) {
|
|
7150
|
+
return vnode.props?.[QTargetElement];
|
|
7151
|
+
}
|
|
7152
|
+
vnode = (vnode.parent || (includeProjection ? vnode.slotParent : null));
|
|
7153
|
+
}
|
|
7154
|
+
return vnode ? vnode.node : null;
|
|
7144
7155
|
};
|
|
7145
7156
|
const vnode_getDomParentVNode = (vnode, includeProjection) => {
|
|
7146
7157
|
while (vnode && !vnode_isElementVNode(vnode)) {
|
|
@@ -7346,7 +7357,9 @@ const fastNextSibling = (node) => {
|
|
|
7346
7357
|
return getNodeAfterCommentNode(node, QContainerIsland, _fastNextSibling, _fastFirstChild);
|
|
7347
7358
|
}
|
|
7348
7359
|
else if (node.nodeValue?.startsWith(QContainerIslandEnd)) {
|
|
7349
|
-
|
|
7360
|
+
// Search for either the next container-island or the end of the q:ignore block,
|
|
7361
|
+
// whichever comes first. This handles multiple islands within a single q:ignore.
|
|
7362
|
+
return getNodeAfterCommentNode(node, [QContainerIsland, QIgnoreEnd], _fastNextSibling, _fastFirstChild);
|
|
7350
7363
|
}
|
|
7351
7364
|
else if (nodeValue?.startsWith(QContainerAttr)) {
|
|
7352
7365
|
while (node && (node = _fastNextSibling.call(node))) {
|
|
@@ -7362,8 +7375,23 @@ const fastNextSibling = (node) => {
|
|
|
7362
7375
|
return node;
|
|
7363
7376
|
};
|
|
7364
7377
|
function getNodeAfterCommentNode(node, commentValue, nextSibling, firstChild) {
|
|
7378
|
+
const isSingleValue = typeof commentValue === 'string';
|
|
7379
|
+
const length = commentValue.length;
|
|
7365
7380
|
while (node) {
|
|
7366
|
-
|
|
7381
|
+
const nodeValue = node.nodeValue;
|
|
7382
|
+
let isMatch;
|
|
7383
|
+
if (isSingleValue) {
|
|
7384
|
+
isMatch = nodeValue?.startsWith(commentValue);
|
|
7385
|
+
}
|
|
7386
|
+
else {
|
|
7387
|
+
for (let i = 0; i < length; i++) {
|
|
7388
|
+
if (nodeValue?.startsWith(commentValue[i])) {
|
|
7389
|
+
isMatch = true;
|
|
7390
|
+
break;
|
|
7391
|
+
}
|
|
7392
|
+
}
|
|
7393
|
+
}
|
|
7394
|
+
if (isMatch) {
|
|
7367
7395
|
node = nextSibling.call(node) || null;
|
|
7368
7396
|
return node;
|
|
7369
7397
|
}
|
|
@@ -7371,11 +7399,14 @@ function getNodeAfterCommentNode(node, commentValue, nextSibling, firstChild) {
|
|
|
7371
7399
|
if (!nextNode) {
|
|
7372
7400
|
nextNode = nextSibling.call(node);
|
|
7373
7401
|
}
|
|
7374
|
-
|
|
7402
|
+
// Go up through parents until we find one with a next sibling
|
|
7403
|
+
while (!nextNode) {
|
|
7375
7404
|
nextNode = fastParentNode(node);
|
|
7376
|
-
if (nextNode) {
|
|
7377
|
-
|
|
7405
|
+
if (!nextNode) {
|
|
7406
|
+
break;
|
|
7378
7407
|
}
|
|
7408
|
+
node = nextNode;
|
|
7409
|
+
nextNode = nextSibling.call(nextNode);
|
|
7379
7410
|
}
|
|
7380
7411
|
node = nextNode;
|
|
7381
7412
|
}
|
|
@@ -7388,6 +7419,16 @@ const fastFirstChild = (node) => {
|
|
|
7388
7419
|
_fastFirstChild = fastGetter(node, 'firstChild');
|
|
7389
7420
|
}
|
|
7390
7421
|
node = node && _fastFirstChild.call(node);
|
|
7422
|
+
// Handle q:ignore as first child (e.g. qwikify$ Host with reactify$ projections).
|
|
7423
|
+
// Navigate depth-first to the first q:container-island and return its first element.
|
|
7424
|
+
if (node &&
|
|
7425
|
+
fastNodeType(node) === /* Node.COMMENT_NODE */ 8 &&
|
|
7426
|
+
node.nodeValue?.startsWith(QIgnore)) {
|
|
7427
|
+
if (!_fastNextSibling) {
|
|
7428
|
+
_fastNextSibling = fastGetter(node, 'nextSibling');
|
|
7429
|
+
}
|
|
7430
|
+
return getNodeAfterCommentNode(node, QContainerIsland, _fastNextSibling, _fastFirstChild);
|
|
7431
|
+
}
|
|
7391
7432
|
while (node && !fastIsTextOrElement(node)) {
|
|
7392
7433
|
node = fastNextSibling(node);
|
|
7393
7434
|
}
|
|
@@ -7590,7 +7631,7 @@ function vnode_toString(depth = 20, offset = '', materialize = false, siblings =
|
|
|
7590
7631
|
strings.push(qwikDebugToString(vnode_getText(vnode)));
|
|
7591
7632
|
}
|
|
7592
7633
|
else if (vnode_isVirtualVNode(vnode)) {
|
|
7593
|
-
const idx = vnode.flags >>>
|
|
7634
|
+
const idx = vnode.flags >>> 12 /* VNodeFlagsIndex.shift */;
|
|
7594
7635
|
const attrs = ['[' + String(idx) + ']'];
|
|
7595
7636
|
if (vnode.dirty) {
|
|
7596
7637
|
attrs.push(` dirty:${vnode.dirty}`);
|
|
@@ -7678,7 +7719,7 @@ function materializeFromVNodeData(vParent, vData, element, child) {
|
|
|
7678
7719
|
let vLast = null;
|
|
7679
7720
|
let previousTextNode = null;
|
|
7680
7721
|
const addVNode = (node) => {
|
|
7681
|
-
node.flags = (node.flags &
|
|
7722
|
+
node.flags = (node.flags & 4095 /* VNodeFlagsIndex.mask */) | (idx << 12 /* VNodeFlagsIndex.shift */);
|
|
7682
7723
|
idx++;
|
|
7683
7724
|
vLast && (vLast.nextSibling = node);
|
|
7684
7725
|
node.previousSibling = vLast;
|
|
@@ -8498,7 +8539,8 @@ function qrlToString(serializationContext, qrl, raw) {
|
|
|
8498
8539
|
const backChannel = (globalThis.__qrl_back_channel__ ||=
|
|
8499
8540
|
new Map());
|
|
8500
8541
|
// During tests the resolved value is always available
|
|
8501
|
-
|
|
8542
|
+
const lazy = qrl.$lazy$;
|
|
8543
|
+
backChannel.set(lazy.$symbol$, lazy.$ref$);
|
|
8502
8544
|
if (!chunk) {
|
|
8503
8545
|
chunk = QRL_RUNTIME_CHUNK;
|
|
8504
8546
|
}
|
|
@@ -8531,7 +8573,7 @@ function qrlToString(serializationContext, qrl, raw) {
|
|
|
8531
8573
|
}
|
|
8532
8574
|
return qrlStringInline;
|
|
8533
8575
|
}
|
|
8534
|
-
function createQRLWithBackChannel(chunk, symbol, captures) {
|
|
8576
|
+
function createQRLWithBackChannel(chunk, symbol, captures, container) {
|
|
8535
8577
|
let qrlImporter = null;
|
|
8536
8578
|
if (isDev && chunk === QRL_RUNTIME_CHUNK) {
|
|
8537
8579
|
const backChannel = globalThis.__qrl_back_channel__;
|
|
@@ -8541,12 +8583,12 @@ function createQRLWithBackChannel(chunk, symbol, captures) {
|
|
|
8541
8583
|
qrlImporter = () => Promise.resolve({ [symbol]: fn });
|
|
8542
8584
|
}
|
|
8543
8585
|
}
|
|
8544
|
-
return createQRL(chunk, symbol, null, qrlImporter, captures);
|
|
8586
|
+
return createQRL(chunk, symbol, null, qrlImporter, captures, container);
|
|
8545
8587
|
}
|
|
8546
8588
|
/** Parses "chunk#hash#...rootRef" */
|
|
8547
|
-
function parseQRL(qrl) {
|
|
8589
|
+
function parseQRL(qrl, container) {
|
|
8548
8590
|
const [chunk, symbol, captures] = qrl.split('#');
|
|
8549
|
-
return createQRLWithBackChannel(chunk, symbol, captures || null);
|
|
8591
|
+
return createQRLWithBackChannel(chunk, symbol, captures || null, container);
|
|
8550
8592
|
}
|
|
8551
8593
|
const QRL_RUNTIME_CHUNK = 'mock-chunk';
|
|
8552
8594
|
|
|
@@ -8583,13 +8625,12 @@ const allocate = (container, typeId, value) => {
|
|
|
8583
8625
|
const [chunkId, symbolId, captureIds] = value.split('#');
|
|
8584
8626
|
const chunk = container.$getObjectById$(chunkId);
|
|
8585
8627
|
const symbol = container.$getObjectById$(symbolId);
|
|
8586
|
-
qrl = createQRLWithBackChannel(chunk, symbol, captureIds || null);
|
|
8628
|
+
qrl = createQRLWithBackChannel(chunk, symbol, captureIds || null, container);
|
|
8587
8629
|
}
|
|
8588
8630
|
else {
|
|
8589
8631
|
// Sync qrl
|
|
8590
|
-
qrl = createQRLWithBackChannel('', String(value), null);
|
|
8632
|
+
qrl = createQRLWithBackChannel('', String(value), null, container);
|
|
8591
8633
|
}
|
|
8592
|
-
qrl.$container$ = container;
|
|
8593
8634
|
return qrl;
|
|
8594
8635
|
}
|
|
8595
8636
|
case 20 /* TypeIds.Task */:
|
|
@@ -8796,19 +8837,19 @@ const _noopQrl = (symbolName, lexicalScopeCapture) => {
|
|
|
8796
8837
|
/** @internal */
|
|
8797
8838
|
const _noopQrlDEV = (symbolName, opts, lexicalScopeCapture) => {
|
|
8798
8839
|
const newQrl = _noopQrl(symbolName, lexicalScopeCapture);
|
|
8799
|
-
newQrl
|
|
8840
|
+
newQrl.$lazy$.dev = opts;
|
|
8800
8841
|
return newQrl;
|
|
8801
8842
|
};
|
|
8802
8843
|
/** @internal */
|
|
8803
8844
|
const qrlDEV = (chunkOrFn, symbol, opts, lexicalScopeCapture) => {
|
|
8804
8845
|
const newQrl = qrl(chunkOrFn, symbol, lexicalScopeCapture, 1);
|
|
8805
|
-
newQrl
|
|
8846
|
+
newQrl.$lazy$.dev = opts;
|
|
8806
8847
|
return newQrl;
|
|
8807
8848
|
};
|
|
8808
8849
|
/** @internal */
|
|
8809
8850
|
const inlinedQrlDEV = (symbol, symbolName, opts, lexicalScopeCapture) => {
|
|
8810
8851
|
const qrl = inlinedQrl(symbol, symbolName, lexicalScopeCapture);
|
|
8811
|
-
qrl
|
|
8852
|
+
qrl.$lazy$.dev = opts;
|
|
8812
8853
|
return qrl;
|
|
8813
8854
|
};
|
|
8814
8855
|
/**
|
|
@@ -10104,8 +10145,7 @@ const useResourceQrl = (qrl, opts) => {
|
|
|
10104
10145
|
}
|
|
10105
10146
|
const ref = {};
|
|
10106
10147
|
// Wrap the function so we can maintain a stable reference to the store
|
|
10107
|
-
const wrapped = createQRL(null, '_rsc', _rsc, null, [qrl, ref]);
|
|
10108
|
-
qrl.$container$ = iCtx.$container$;
|
|
10148
|
+
const wrapped = createQRL(null, '_rsc', _rsc, null, [qrl, ref], iCtx.$container$);
|
|
10109
10149
|
const asyncSignal = createAsyncSignal(wrapped, {
|
|
10110
10150
|
timeout: opts?.timeout,
|
|
10111
10151
|
container: iCtx.$container$,
|
|
@@ -10407,18 +10447,26 @@ const _hmr = (event, element) => {
|
|
|
10407
10447
|
host = parent;
|
|
10408
10448
|
}
|
|
10409
10449
|
// Replace the component QRL with a fresh one to bypass caching
|
|
10410
|
-
//
|
|
10411
|
-
const
|
|
10412
|
-
if (
|
|
10413
|
-
|
|
10414
|
-
const
|
|
10415
|
-
const
|
|
10416
|
-
const
|
|
10417
|
-
|
|
10418
|
-
|
|
10419
|
-
|
|
10420
|
-
|
|
10421
|
-
|
|
10450
|
+
// Maybe we should use a qrl registry to invalidate all QRLs from a parent?
|
|
10451
|
+
const qrl = container.getHostProp(host, OnRenderProp);
|
|
10452
|
+
if (qrl) {
|
|
10453
|
+
// This code is highly coupled to the internal implementation of QRL
|
|
10454
|
+
const instance = qrl.__proto__;
|
|
10455
|
+
const lazy = instance.$lazy$;
|
|
10456
|
+
const chunk = lazy.$chunk$;
|
|
10457
|
+
if (chunk) {
|
|
10458
|
+
/**
|
|
10459
|
+
* Bust the cache by appending a timestamp to the chunk URL. There's some chance that we
|
|
10460
|
+
* import the same chunk multiple times, but that's not really a problem for segments.
|
|
10461
|
+
*/
|
|
10462
|
+
const bustUrl = chunk.split('?')[0] + '?t=' + Date.now();
|
|
10463
|
+
lazy.$chunk$ = bustUrl;
|
|
10464
|
+
lazy.$ref$ = undefined;
|
|
10465
|
+
instance.resolved = undefined;
|
|
10466
|
+
// Force rerender
|
|
10467
|
+
markVNodeDirty(container, host, 4 /* ChoreBits.COMPONENT */);
|
|
10468
|
+
}
|
|
10469
|
+
}
|
|
10422
10470
|
};
|
|
10423
10471
|
/** Sanitize path to a valid CSS-safe event name (no colons, dots, slashes). */
|
|
10424
10472
|
const toEventName = (devPath) => 'qHmr' + devPath.replace(/[^a-zA-Z0-9_]/g, '_');
|
|
@@ -10440,7 +10488,86 @@ function _useHmr(devPath) {
|
|
|
10440
10488
|
useOnDocument(toEventName(devPath), hmrQrl);
|
|
10441
10489
|
}
|
|
10442
10490
|
|
|
10491
|
+
/**
|
|
10492
|
+
* Register an external projection on a parent component VNode.
|
|
10493
|
+
*
|
|
10494
|
+
* Creates a new VirtualVNode that will render the given component QRL with the given props. The
|
|
10495
|
+
* VNode is stored as a projection on the parent, and a low-priority cursor is added so the cursor
|
|
10496
|
+
* walker will process it.
|
|
10497
|
+
*
|
|
10498
|
+
* Use `_setProjectionTarget` to set the DOM target element before the cursor fires.
|
|
10499
|
+
*
|
|
10500
|
+
* @internal
|
|
10501
|
+
*/
|
|
10502
|
+
function _addProjection(container, parentVNode, componentQRL, props, slotName) {
|
|
10503
|
+
const vnode = vnode_newVirtual();
|
|
10504
|
+
vnode_setProp(vnode, QSlot, slotName);
|
|
10505
|
+
vnode.parent = parentVNode;
|
|
10506
|
+
vnode_setProp(parentVNode, slotName, vnode);
|
|
10507
|
+
vnode_setProp(vnode, OnRenderProp, componentQRL);
|
|
10508
|
+
vnode_setProp(vnode, ELEMENT_PROPS, props);
|
|
10509
|
+
vnode.dirty = 4 /* ChoreBits.COMPONENT */;
|
|
10510
|
+
addCursor(container, vnode, 1); // low priority
|
|
10511
|
+
return vnode;
|
|
10512
|
+
}
|
|
10513
|
+
/**
|
|
10514
|
+
* Set the DOM target element for an external projection VNode.
|
|
10515
|
+
*
|
|
10516
|
+
* When the cursor walker processes this VNode, DOM operations will target this element instead of
|
|
10517
|
+
* walking the parent chain.
|
|
10518
|
+
*
|
|
10519
|
+
* @internal
|
|
10520
|
+
*/
|
|
10521
|
+
function _setProjectionTarget(vnode, targetElement) {
|
|
10522
|
+
vnode_setProp(vnode, QTargetElement, targetElement);
|
|
10523
|
+
vnode.flags |= 2048 /* VNodeFlags.HasTargetElement */;
|
|
10524
|
+
}
|
|
10525
|
+
/**
|
|
10526
|
+
* Update the props on an external projection VNode and trigger re-rendering.
|
|
10527
|
+
*
|
|
10528
|
+
* @internal
|
|
10529
|
+
*/
|
|
10530
|
+
function _updateProjectionProps(container, vnode, newProps) {
|
|
10531
|
+
vnode_setProp(vnode, ELEMENT_PROPS, newProps);
|
|
10532
|
+
markVNodeDirty(container, vnode, 4 /* ChoreBits.COMPONENT */);
|
|
10533
|
+
}
|
|
10534
|
+
/**
|
|
10535
|
+
* Remove an external projection from its parent and clean up.
|
|
10536
|
+
*
|
|
10537
|
+
* @internal
|
|
10538
|
+
*/
|
|
10539
|
+
function _removeProjection(container, parentVNode, vnode, slotName) {
|
|
10540
|
+
// Remove from parent's projections
|
|
10541
|
+
vnode_setProp(parentVNode, slotName, null);
|
|
10542
|
+
// Clean up effects, subscriptions, and child vnodes
|
|
10543
|
+
const journal = [];
|
|
10544
|
+
cleanup(container, journal, vnode);
|
|
10545
|
+
vnode_applyJournal(journal);
|
|
10546
|
+
// Clean up DOM
|
|
10547
|
+
if (vnode.flags & 2048 /* VNodeFlags.HasTargetElement */) {
|
|
10548
|
+
const targetEl = vnode_getProp(vnode, QTargetElement, null);
|
|
10549
|
+
if (targetEl) {
|
|
10550
|
+
targetEl.replaceChildren();
|
|
10551
|
+
}
|
|
10552
|
+
vnode_setProp(vnode, QTargetElement, null);
|
|
10553
|
+
vnode.flags &= -2049 /* VNodeFlags.HasTargetElement */;
|
|
10554
|
+
}
|
|
10555
|
+
}
|
|
10556
|
+
|
|
10443
10557
|
let loading = Promise.resolve();
|
|
10558
|
+
const dangerousObjectKeys = new Set([
|
|
10559
|
+
'constructor',
|
|
10560
|
+
'prototype',
|
|
10561
|
+
'toString',
|
|
10562
|
+
'valueOf',
|
|
10563
|
+
'toJSON',
|
|
10564
|
+
'then',
|
|
10565
|
+
]);
|
|
10566
|
+
const isSafeObjectKV = (key, value) => {
|
|
10567
|
+
return (typeof key === 'string' &&
|
|
10568
|
+
key !== '__proto__' &&
|
|
10569
|
+
(typeof value !== 'function' || !dangerousObjectKeys.has(key)));
|
|
10570
|
+
};
|
|
10444
10571
|
const inflate = (container, target, typeId, data) => {
|
|
10445
10572
|
if (typeId === 0 /* TypeIds.Plain */) {
|
|
10446
10573
|
// Already processed
|
|
@@ -10463,6 +10590,9 @@ const inflate = (container, target, typeId, data) => {
|
|
|
10463
10590
|
for (let i = 0; i < data.length; i += 2) {
|
|
10464
10591
|
const key = data[i];
|
|
10465
10592
|
const value = data[i + 1];
|
|
10593
|
+
if (!isSafeObjectKV(key, value)) {
|
|
10594
|
+
continue;
|
|
10595
|
+
}
|
|
10466
10596
|
target[key] = value;
|
|
10467
10597
|
}
|
|
10468
10598
|
break;
|
|
@@ -11036,13 +11166,18 @@ function processVNodeData(document) {
|
|
|
11036
11166
|
nextNode = null;
|
|
11037
11167
|
}
|
|
11038
11168
|
else if (nodeType === 64 /* NodeType.COMMENT_ISLAND_END */) {
|
|
11169
|
+
// Walk forward to find either the next container-island or the end of the q:ignore block.
|
|
11170
|
+
// This handles multiple islands within a single q:ignore block.
|
|
11039
11171
|
nextNode = node;
|
|
11172
|
+
let nextNodeType;
|
|
11040
11173
|
do {
|
|
11041
11174
|
nextNode = walker.nextNode();
|
|
11042
11175
|
if (!nextNode) {
|
|
11043
11176
|
throw new Error(`Ignore block not closed!`);
|
|
11044
11177
|
}
|
|
11045
|
-
|
|
11178
|
+
nextNodeType = getFastNodeType(nextNode);
|
|
11179
|
+
} while (nextNodeType !== 32 /* NodeType.COMMENT_IGNORE_END */ &&
|
|
11180
|
+
nextNodeType !== 65 /* NodeType.COMMENT_ISLAND_START */);
|
|
11046
11181
|
nextNode = null;
|
|
11047
11182
|
}
|
|
11048
11183
|
else if (nodeType === 9 /* NodeType.COMMENT_SKIP_START */) {
|
|
@@ -11247,8 +11382,7 @@ class DomContainer extends _SharedContainer {
|
|
|
11247
11382
|
this.$stateData$[id] = vParent;
|
|
11248
11383
|
}
|
|
11249
11384
|
parseQRL(qrlStr) {
|
|
11250
|
-
const qrl = parseQRL(qrlStr);
|
|
11251
|
-
qrl.$container$ = this;
|
|
11385
|
+
const qrl = parseQRL(qrlStr, this);
|
|
11252
11386
|
return qrl;
|
|
11253
11387
|
}
|
|
11254
11388
|
handleError(err, host) {
|
|
@@ -12406,6 +12540,198 @@ const NoSerializeSymbol = Symbol('noSerialize');
|
|
|
12406
12540
|
const SerializerSymbol = Symbol('serialize');
|
|
12407
12541
|
|
|
12408
12542
|
// keep these imports above the rest to prevent circular dep issues
|
|
12543
|
+
/**
|
|
12544
|
+
* Shared lazy-loading reference that holds module loading metadata. Multiple QRLs pointing to the
|
|
12545
|
+
* same chunk+symbol can share a single LazyRef, differing only in their captured scope.
|
|
12546
|
+
*/
|
|
12547
|
+
class LazyRef {
|
|
12548
|
+
$chunk$;
|
|
12549
|
+
$symbol$;
|
|
12550
|
+
$symbolFn$;
|
|
12551
|
+
$ref$;
|
|
12552
|
+
$container$;
|
|
12553
|
+
// Don't allocate dev property immediately so that in prod we don't have this property
|
|
12554
|
+
dev;
|
|
12555
|
+
constructor($chunk$, $symbol$, $symbolFn$, $ref$, container) {
|
|
12556
|
+
this.$chunk$ = $chunk$;
|
|
12557
|
+
this.$symbol$ = $symbol$;
|
|
12558
|
+
this.$symbolFn$ = $symbolFn$;
|
|
12559
|
+
this.$ref$ = $ref$;
|
|
12560
|
+
if ($ref$) {
|
|
12561
|
+
this.$setRef$($ref$);
|
|
12562
|
+
}
|
|
12563
|
+
if (container && !$ref$ && typeof $chunk$ === 'string' && !$symbolFn$) {
|
|
12564
|
+
// We only store the container if we're going to import the chunk
|
|
12565
|
+
// Note that this container is not necessarily the same one as from the captures
|
|
12566
|
+
this.$container$ = container;
|
|
12567
|
+
}
|
|
12568
|
+
if (qDev) {
|
|
12569
|
+
// this will be filled in later
|
|
12570
|
+
this.dev = null;
|
|
12571
|
+
}
|
|
12572
|
+
/** Preload the chunk with somewhat lower probability when we create the QRL. */
|
|
12573
|
+
if (isBrowser && $chunk$) {
|
|
12574
|
+
p($chunk$, 0.8);
|
|
12575
|
+
}
|
|
12576
|
+
}
|
|
12577
|
+
/** We don't read hash very often so let's not allocate a string for every QRL */
|
|
12578
|
+
get $hash$() {
|
|
12579
|
+
return getSymbolHash(this.$symbol$);
|
|
12580
|
+
}
|
|
12581
|
+
$setRef$(ref) {
|
|
12582
|
+
this.$ref$ = ref;
|
|
12583
|
+
if (isPromise(ref)) {
|
|
12584
|
+
ref.then((r) => (this.$ref$ = r), (err) => {
|
|
12585
|
+
console.error(`qrl ${this.$symbol$} failed to load`, err);
|
|
12586
|
+
// We shouldn't cache rejections, we can try again later
|
|
12587
|
+
this.$ref$ = null;
|
|
12588
|
+
});
|
|
12589
|
+
}
|
|
12590
|
+
}
|
|
12591
|
+
/** Load the raw module export without capture binding. */
|
|
12592
|
+
$load$() {
|
|
12593
|
+
if (this.$ref$ != null) {
|
|
12594
|
+
return this.$ref$;
|
|
12595
|
+
}
|
|
12596
|
+
if (this.$chunk$ === '') {
|
|
12597
|
+
// Sync QRL
|
|
12598
|
+
isDev && assertDefined(this.$container$, 'Sync QRL must have container element');
|
|
12599
|
+
const hash = this.$container$.$instanceHash$;
|
|
12600
|
+
const doc = this.$container$.element?.ownerDocument || document;
|
|
12601
|
+
const qFuncs = getQFuncs(doc, hash);
|
|
12602
|
+
return (this.$ref$ = qFuncs[Number(this.$symbol$)]);
|
|
12603
|
+
}
|
|
12604
|
+
if (isBrowser && this.$chunk$) {
|
|
12605
|
+
/** We will run the QRL, so now the probability of the chunk is 100% */
|
|
12606
|
+
p(this.$chunk$, 1);
|
|
12607
|
+
}
|
|
12608
|
+
const symbol = this.$symbol$;
|
|
12609
|
+
const importP = this.$symbolFn$
|
|
12610
|
+
? this.$symbolFn$().then((module) => module[symbol])
|
|
12611
|
+
: getPlatform().importSymbol(this.$container$?.element, this.$chunk$, symbol);
|
|
12612
|
+
this.$setRef$(importP);
|
|
12613
|
+
return this.$ref$;
|
|
12614
|
+
}
|
|
12615
|
+
}
|
|
12616
|
+
/**
|
|
12617
|
+
* When a method is called on the qrlFn wrapper function, `this` is the function, not the QRLClass
|
|
12618
|
+
* instance that holds the data. This helper returns the actual instance by checking whether `this`
|
|
12619
|
+
* owns `resolved` (always set on the instance).
|
|
12620
|
+
*/
|
|
12621
|
+
const getInstance = (instance) => {
|
|
12622
|
+
return Object.prototype.hasOwnProperty.call(instance, 'resolved')
|
|
12623
|
+
? instance
|
|
12624
|
+
: Object.getPrototypeOf(instance);
|
|
12625
|
+
};
|
|
12626
|
+
/**
|
|
12627
|
+
* We use a class here to avoid copying all the methods for every QRL instance. The QRL itself is a
|
|
12628
|
+
* function that calls the internal $callFn$ method, and we set the prototype to the class instance
|
|
12629
|
+
* so it has access to all the properties and methods. That's why we need to extend Function, so
|
|
12630
|
+
* that `.apply()` etc work.
|
|
12631
|
+
*
|
|
12632
|
+
* So a QRL is a function that has a prototype of a QRLClass instance. This is unconventional, but
|
|
12633
|
+
* it allows us to have a callable QRL that is also a class.
|
|
12634
|
+
*
|
|
12635
|
+
* Note the use of getInstance everywhere when writing to `this`. If you write to `this` directly,
|
|
12636
|
+
* it will be stored on the function itself, and we don't want that because the QRLClass instance
|
|
12637
|
+
* doesn't have access to it, and it uses more memory.
|
|
12638
|
+
*/
|
|
12639
|
+
class QRLClass extends Function {
|
|
12640
|
+
$lazy$;
|
|
12641
|
+
resolved = undefined;
|
|
12642
|
+
// This is defined or undefined for the lifetime of the QRL, so we set it lazily
|
|
12643
|
+
$captures$;
|
|
12644
|
+
$container$;
|
|
12645
|
+
constructor($lazy$, $captures$, container) {
|
|
12646
|
+
super();
|
|
12647
|
+
this.$lazy$ = $lazy$;
|
|
12648
|
+
if ($captures$) {
|
|
12649
|
+
this.$captures$ = $captures$;
|
|
12650
|
+
if (typeof $captures$ === 'string') {
|
|
12651
|
+
// We cannot rely on the container of the lazy ref, it may be missing or different
|
|
12652
|
+
this.$container$ = container;
|
|
12653
|
+
}
|
|
12654
|
+
if (qDev) {
|
|
12655
|
+
if ($captures$ && typeof $captures$ === 'object') {
|
|
12656
|
+
for (const item of $captures$) {
|
|
12657
|
+
verifySerializable(item, 'Captured variable in the closure can not be serialized');
|
|
12658
|
+
}
|
|
12659
|
+
}
|
|
12660
|
+
}
|
|
12661
|
+
}
|
|
12662
|
+
// If it is plain value with deserialized or missing captures, resolve it immediately
|
|
12663
|
+
// Otherwise we keep using the async path so we can wait for qrls to load
|
|
12664
|
+
if ($lazy$.$ref$ != null && typeof this.$captures$ !== 'string' && !isPromise($lazy$.$ref$)) {
|
|
12665
|
+
// we can pass this instead of using getInstance because we know we are not the qrlFn
|
|
12666
|
+
this.resolved = bindCaptures(this, $lazy$.$ref$);
|
|
12667
|
+
}
|
|
12668
|
+
}
|
|
12669
|
+
w(captures) {
|
|
12670
|
+
const newQrl = new QRLClass(this.$lazy$, captures, this.$captures$ ? this.$container$ : undefined);
|
|
12671
|
+
return makeQrlFn(newQrl);
|
|
12672
|
+
}
|
|
12673
|
+
s(ref) {
|
|
12674
|
+
const qrl = getInstance(this);
|
|
12675
|
+
qrl.$lazy$.$setRef$(ref);
|
|
12676
|
+
qrl.resolved = bindCaptures(qrl, ref);
|
|
12677
|
+
}
|
|
12678
|
+
// --- Getter proxies for backward compat ---
|
|
12679
|
+
get $chunk$() {
|
|
12680
|
+
return this.$lazy$.$chunk$;
|
|
12681
|
+
}
|
|
12682
|
+
get $symbol$() {
|
|
12683
|
+
return this.$lazy$.$symbol$;
|
|
12684
|
+
}
|
|
12685
|
+
get $hash$() {
|
|
12686
|
+
return this.$lazy$.$hash$;
|
|
12687
|
+
}
|
|
12688
|
+
get dev() {
|
|
12689
|
+
return this.$lazy$.dev;
|
|
12690
|
+
}
|
|
12691
|
+
$callFn$(withThis, ...args) {
|
|
12692
|
+
if (this.resolved) {
|
|
12693
|
+
return this.resolved.apply(withThis, args);
|
|
12694
|
+
}
|
|
12695
|
+
// Not resolved yet: we'll return a promise
|
|
12696
|
+
// grab the context while we are sync
|
|
12697
|
+
const ctx = tryGetInvokeContext();
|
|
12698
|
+
return this.resolve(ctx?.$container$).then(() => invokeApply.call(withThis, ctx, this.resolved, args));
|
|
12699
|
+
}
|
|
12700
|
+
async resolve(container) {
|
|
12701
|
+
// We need to write to the QRLClass instance, not the function
|
|
12702
|
+
const qrl = getInstance(this);
|
|
12703
|
+
return maybeThen($resolve$(qrl, container), () => qrl.resolved);
|
|
12704
|
+
}
|
|
12705
|
+
getSymbol() {
|
|
12706
|
+
return this.$symbol$;
|
|
12707
|
+
}
|
|
12708
|
+
getHash() {
|
|
12709
|
+
return this.$hash$;
|
|
12710
|
+
}
|
|
12711
|
+
getCaptured() {
|
|
12712
|
+
const qrl = getInstance(this);
|
|
12713
|
+
ensureQrlCaptures(qrl);
|
|
12714
|
+
return qrl.$captures$;
|
|
12715
|
+
}
|
|
12716
|
+
getFn(currentCtx, beforeFn) {
|
|
12717
|
+
const qrl = getInstance(this);
|
|
12718
|
+
const bound = (...args) => {
|
|
12719
|
+
if (!qrl.resolved) {
|
|
12720
|
+
return qrl.resolve().then((fn) => {
|
|
12721
|
+
if (qDev && !isFunction(fn)) {
|
|
12722
|
+
throw qError(5 /* QError.qrlIsNotFunction */);
|
|
12723
|
+
}
|
|
12724
|
+
return bound(...args);
|
|
12725
|
+
});
|
|
12726
|
+
}
|
|
12727
|
+
if (beforeFn && beforeFn() === false) {
|
|
12728
|
+
return undefined;
|
|
12729
|
+
}
|
|
12730
|
+
return invokeApply(currentCtx, qrl.resolved, args);
|
|
12731
|
+
};
|
|
12732
|
+
return bound;
|
|
12733
|
+
}
|
|
12734
|
+
}
|
|
12409
12735
|
/**
|
|
12410
12736
|
* The current captured scope during QRL invocation. This is used to provide the lexical scope for
|
|
12411
12737
|
* QRL functions. It is used one time per invocation, synchronously, so it is safe to store it in
|
|
@@ -12428,114 +12754,62 @@ const deserializeCaptures = (container, captures) => {
|
|
|
12428
12754
|
const ensureQrlCaptures = (qrl) => {
|
|
12429
12755
|
// We read the captures once, synchronously, so no need to keep previous
|
|
12430
12756
|
_captures = qrl.$captures$;
|
|
12757
|
+
const container = qrl.$container$;
|
|
12431
12758
|
if (typeof _captures === 'string') {
|
|
12432
|
-
if (!
|
|
12759
|
+
if (!container) {
|
|
12433
12760
|
throw qError(13 /* QError.qrlMissingContainer */);
|
|
12434
12761
|
}
|
|
12435
12762
|
const prevLoading = loading;
|
|
12436
|
-
_captures = qrl.$captures$ = deserializeCaptures(
|
|
12763
|
+
_captures = qrl.$captures$ = deserializeCaptures(container, _captures);
|
|
12437
12764
|
if (loading !== prevLoading) {
|
|
12438
12765
|
// return the loading promise so callers can await it
|
|
12439
12766
|
return loading;
|
|
12440
12767
|
}
|
|
12441
12768
|
}
|
|
12442
12769
|
};
|
|
12443
|
-
function bindFnToContext(qrl, currentCtx, beforeFn) {
|
|
12444
|
-
// Note that we bind the current `this`
|
|
12445
|
-
const bound = (...args) => {
|
|
12446
|
-
if (!qrl.resolved) {
|
|
12447
|
-
return qrl.resolve().then((fn) => {
|
|
12448
|
-
if (!isFunction(fn)) {
|
|
12449
|
-
throw qError(5 /* QError.qrlIsNotFunction */);
|
|
12450
|
-
}
|
|
12451
|
-
return bound(...args);
|
|
12452
|
-
});
|
|
12453
|
-
}
|
|
12454
|
-
if (beforeFn && beforeFn() === false) {
|
|
12455
|
-
return;
|
|
12456
|
-
}
|
|
12457
|
-
return invokeApply.call(this, currentCtx, qrl.resolved, args);
|
|
12458
|
-
};
|
|
12459
|
-
return bound;
|
|
12460
|
-
}
|
|
12461
12770
|
// Wrap functions to provide their lexical scope
|
|
12462
|
-
const bindCaptures = (qrl,
|
|
12463
|
-
if (typeof
|
|
12464
|
-
return
|
|
12771
|
+
const bindCaptures = (qrl, ref) => {
|
|
12772
|
+
if (typeof ref !== 'function' || !qrl.$captures$) {
|
|
12773
|
+
return ref;
|
|
12465
12774
|
}
|
|
12466
|
-
return function
|
|
12775
|
+
return function boundCaptures(...args) {
|
|
12467
12776
|
ensureQrlCaptures(qrl);
|
|
12468
|
-
return
|
|
12777
|
+
return ref.apply(this, args);
|
|
12469
12778
|
};
|
|
12470
12779
|
};
|
|
12471
|
-
const
|
|
12472
|
-
|
|
12473
|
-
|
|
12474
|
-
|
|
12475
|
-
if (symbolRef != null) {
|
|
12476
|
-
// Resolving (Promise) or already resolved (value)
|
|
12477
|
-
return symbolRef;
|
|
12478
|
-
}
|
|
12780
|
+
const $resolve$ = (qrl, container) => {
|
|
12781
|
+
const lazy = qrl.$lazy$;
|
|
12782
|
+
const shouldDeserialize = typeof qrl.$captures$ === 'string';
|
|
12783
|
+
if (shouldDeserialize && !qrl.$container$) {
|
|
12479
12784
|
if (container) {
|
|
12480
12785
|
qrl.$container$ = container;
|
|
12481
12786
|
}
|
|
12482
|
-
else
|
|
12483
|
-
|
|
12484
|
-
if (ctx?.$container$) {
|
|
12485
|
-
qrl.$container$ = ctx.$container$;
|
|
12486
|
-
}
|
|
12487
|
-
}
|
|
12488
|
-
if (qrl.$chunk$ === '') {
|
|
12489
|
-
// Sync QRL
|
|
12490
|
-
isDev && assertDefined(qrl.$container$, 'Sync QRL must have container element');
|
|
12491
|
-
const hash = qrl.$container$.$instanceHash$;
|
|
12492
|
-
const doc = qrl.$container$.element?.ownerDocument || document;
|
|
12493
|
-
const qFuncs = getQFuncs(doc, hash);
|
|
12494
|
-
// No need to wrap, syncQRLs can't have captured scope
|
|
12495
|
-
return (qrl.resolved = symbolRef = qFuncs[Number(qrl.$symbol$)]);
|
|
12496
|
-
}
|
|
12497
|
-
if (isBrowser && qrl.$chunk$) {
|
|
12498
|
-
/** We run the QRL, so now the probability of the chunk is 100% */
|
|
12499
|
-
p(qrl.$chunk$, 1);
|
|
12500
|
-
}
|
|
12501
|
-
const start = now();
|
|
12502
|
-
const symbol = qrl.$symbol$;
|
|
12503
|
-
const importP = symbolFn
|
|
12504
|
-
? symbolFn().then((module) => module[symbol])
|
|
12505
|
-
: getPlatform().importSymbol(qrl.$container$?.element, qrl.$chunk$, symbol);
|
|
12506
|
-
symbolRef = maybeThen(importP, (resolved) => {
|
|
12507
|
-
// We memoize the result on the symbolFn
|
|
12508
|
-
// Make sure not to memoize the wrapped function!
|
|
12509
|
-
if (!isDev && symbolFn) {
|
|
12510
|
-
symbolFn[symbol] = resolved;
|
|
12511
|
-
}
|
|
12512
|
-
return (symbolRef = qrl.resolved = bindCaptures(qrl, resolved));
|
|
12513
|
-
});
|
|
12514
|
-
if (isPromise(symbolRef)) {
|
|
12515
|
-
const ctx = tryGetInvokeContext();
|
|
12516
|
-
symbolRef.then(() => emitUsedSymbol(symbol, ctx?.$hostElement$ instanceof ElementVNode ? ctx?.$hostElement$.node : undefined, start), (err) => {
|
|
12517
|
-
console.error(`qrl ${symbol} failed to load`, err);
|
|
12518
|
-
// We shouldn't cache rejections, we can try again later
|
|
12519
|
-
symbolRef = null;
|
|
12520
|
-
});
|
|
12521
|
-
}
|
|
12522
|
-
// Try to deserialize captures if any
|
|
12523
|
-
if (qrl.$container$) {
|
|
12524
|
-
await ensureQrlCaptures(qrl);
|
|
12787
|
+
else {
|
|
12788
|
+
qrl.$container$ = tryGetInvokeContext()?.$container$;
|
|
12525
12789
|
}
|
|
12526
|
-
|
|
12527
|
-
|
|
12790
|
+
}
|
|
12791
|
+
if (qrl.resolved) {
|
|
12792
|
+
return;
|
|
12793
|
+
}
|
|
12794
|
+
// Capture context while still sync
|
|
12795
|
+
const start = now();
|
|
12796
|
+
const ctx = tryGetInvokeContext();
|
|
12797
|
+
// Load raw value via LazyRef - may be sync (e.g. sync QRLs) or async
|
|
12798
|
+
const rawOrPromise = lazy.$load$();
|
|
12799
|
+
const maybePromise = maybeThen(rawOrPromise, (raw) => {
|
|
12800
|
+
qrl.resolved = bindCaptures(qrl, raw);
|
|
12801
|
+
});
|
|
12802
|
+
if (maybePromise) {
|
|
12803
|
+
// We're importing; emit symbol usage event
|
|
12804
|
+
const symbol = lazy.$symbol$;
|
|
12805
|
+
emitUsedSymbol(symbol, ctx?.$hostElement$ instanceof ElementVNode ? ctx?.$hostElement$.node : undefined, start);
|
|
12806
|
+
}
|
|
12807
|
+
const capturedPromise = shouldDeserialize && qrl.$container$ && ensureQrlCaptures(qrl);
|
|
12808
|
+
if (capturedPromise) {
|
|
12809
|
+
return capturedPromise.then(() => maybePromise);
|
|
12810
|
+
}
|
|
12811
|
+
return maybePromise;
|
|
12528
12812
|
};
|
|
12529
|
-
function getSymbol() {
|
|
12530
|
-
return this.$symbol$;
|
|
12531
|
-
}
|
|
12532
|
-
function getHash() {
|
|
12533
|
-
return this.$hash$;
|
|
12534
|
-
}
|
|
12535
|
-
function getCaptured() {
|
|
12536
|
-
ensureQrlCaptures(this);
|
|
12537
|
-
return this.$captures$;
|
|
12538
|
-
}
|
|
12539
12813
|
/**
|
|
12540
12814
|
* Creates a QRL instance to represent a lazily loaded value. Normally this is a function, but it
|
|
12541
12815
|
* can be any value.
|
|
@@ -12549,64 +12823,19 @@ function getCaptured() {
|
|
|
12549
12823
|
*
|
|
12550
12824
|
* @internal
|
|
12551
12825
|
*/
|
|
12552
|
-
const createQRL = (chunk, symbol, symbolRef, symbolFn, captures) => {
|
|
12553
|
-
|
|
12554
|
-
const
|
|
12555
|
-
|
|
12556
|
-
|
|
12557
|
-
|
|
12558
|
-
|
|
12559
|
-
|
|
12560
|
-
|
|
12561
|
-
}
|
|
12562
|
-
const qrl = async function qrlFn(...args) {
|
|
12563
|
-
if (qrl.resolved) {
|
|
12564
|
-
return qrl.resolved.apply(this, args);
|
|
12565
|
-
}
|
|
12566
|
-
// grab the context while we are sync
|
|
12567
|
-
const ctx = tryGetInvokeContext();
|
|
12568
|
-
await qrl.resolve(ctx?.$container$);
|
|
12569
|
-
return invokeApply.call(this, ctx, qrl.resolved, args);
|
|
12826
|
+
const createQRL = (chunk, symbol, symbolRef, symbolFn, captures, container) => {
|
|
12827
|
+
const lazy = new LazyRef(chunk, symbol, symbolFn, symbolRef, container);
|
|
12828
|
+
const qrl = new QRLClass(lazy, captures, container);
|
|
12829
|
+
return makeQrlFn(qrl);
|
|
12830
|
+
};
|
|
12831
|
+
const makeQrlFn = (qrl) => {
|
|
12832
|
+
// The QRL has to be callable, so we create a function that calls the internal $callFn$
|
|
12833
|
+
const qrlFn = async function (...args) {
|
|
12834
|
+
return qrl.$callFn$(this, ...args);
|
|
12570
12835
|
};
|
|
12571
|
-
//
|
|
12572
|
-
|
|
12573
|
-
|
|
12574
|
-
}
|
|
12575
|
-
const resolve = symbolRef != null ? async () => symbolRef : makeResolveFunction(qrl, symbolFn);
|
|
12576
|
-
const hash = getSymbolHash(symbol);
|
|
12577
|
-
Object.assign(qrl, {
|
|
12578
|
-
getSymbol,
|
|
12579
|
-
getHash,
|
|
12580
|
-
getCaptured,
|
|
12581
|
-
// This can be called with other `this`
|
|
12582
|
-
getFn: function (currentCtx, beforeFn) {
|
|
12583
|
-
return bindFnToContext.call(this, qrl, currentCtx, beforeFn);
|
|
12584
|
-
},
|
|
12585
|
-
resolve,
|
|
12586
|
-
resolved: undefined,
|
|
12587
|
-
$chunk$: chunk,
|
|
12588
|
-
$symbol$: symbol,
|
|
12589
|
-
$hash$: hash,
|
|
12590
|
-
$captures$: captures,
|
|
12591
|
-
$container$: null,
|
|
12592
|
-
});
|
|
12593
|
-
if (qDev) {
|
|
12594
|
-
qrl.dev = null;
|
|
12595
|
-
qrl.$symbolRef$ = origSymbolRef;
|
|
12596
|
-
seal(qrl);
|
|
12597
|
-
}
|
|
12598
|
-
// Now that the qrl is fully constructed, we can resolve/wrap the symbolRef if we received it. If it is a plain value without computed captures, the qrl will be resolved immediately.
|
|
12599
|
-
if (symbolRef != null) {
|
|
12600
|
-
symbolRef = maybeThen(ensureQrlCaptures(qrl), () => maybeThen(symbolRef, (resolved) => {
|
|
12601
|
-
symbolRef = qrl.resolved = bindCaptures(qrl, resolved);
|
|
12602
|
-
return symbolRef;
|
|
12603
|
-
}));
|
|
12604
|
-
}
|
|
12605
|
-
if (isBrowser && chunk) {
|
|
12606
|
-
/** Preloading the chunk when we create the QRL. */
|
|
12607
|
-
p(chunk, 0.8);
|
|
12608
|
-
}
|
|
12609
|
-
return qrl;
|
|
12836
|
+
// ...and set the prototype to the QRL instance so it has all the properties and methods without copying them
|
|
12837
|
+
Object.setPrototypeOf(qrlFn, qrl);
|
|
12838
|
+
return qrlFn;
|
|
12610
12839
|
};
|
|
12611
12840
|
const EMITTED = /*#__PURE__*/ new Set();
|
|
12612
12841
|
const emitUsedSymbol = (symbol, element, reqTime) => {
|
|
@@ -12781,6 +13010,7 @@ const componentQrl = (componentQrl) => {
|
|
|
12781
13010
|
QwikComponent[SERIALIZABLE_STATE] = [componentQrl];
|
|
12782
13011
|
return QwikComponent;
|
|
12783
13012
|
};
|
|
13013
|
+
/** @internal */
|
|
12784
13014
|
const SERIALIZABLE_STATE = Symbol('serializable-data');
|
|
12785
13015
|
const isQwikComponent = (component) => {
|
|
12786
13016
|
return typeof component == 'function' && component[SERIALIZABLE_STATE] !== undefined;
|
|
@@ -13910,5 +14140,5 @@ if (import.meta.hot) {
|
|
|
13910
14140
|
});
|
|
13911
14141
|
}
|
|
13912
14142
|
|
|
13913
|
-
export { $, Fragment, NoSerializeSymbol, PrefetchGraph, PrefetchServiceWorker, RenderOnce, Resource, SSRComment, SSRRaw, SSRStream, SSRStreamBlock, SerializerSymbol, SkipRender, Slot, _CONST_PROPS, DomContainer as _DomContainer, _EFFECT_BACK_REF, EMPTY_ARRAY as _EMPTY_ARRAY, EMPTY_OBJ as _EMPTY_OBJ, _IMMUTABLE, _SharedContainer, SubscriptionData as _SubscriptionData, _UNINITIALIZED, _VAR_PROPS, _captures, _chk, createQRL as _createQRL, _deserialize, _dumpState, _executeSsrChores, _fnSignal, _getConstProps, _getContextContainer, _getContextEvent, _getContextHostElement, getDomContainer as _getDomContainer, _getQContainerElement, _getVarProps, _hasStoreEffects, _hmr, isJSXNode as _isJSXNode, isStore as _isStore, isStringifiable as _isStringifiable, isTask as _isTask, _jsxBranch, _jsxC, _jsxQ, _jsxS, _jsxSorted, _jsxSplit, mapApp_findIndx as _mapApp_findIndx, mapArray_get as _mapArray_get, mapArray_set as _mapArray_set, _noopQrl, _noopQrlDEV, preprocessState as _preprocessState, _qrlSync, qrlToString as _qrlToString, _regSymbol, _res, _resolveContextWithoutSequentialScope, _restProps, _rsc, _run, _serialize, setEvent as _setEvent, scheduleTask as _task, _useHmr, _val, verifySerializable as _verifySerializable, vnode_ensureElementInflated as _vnode_ensureElementInflated, vnode_getAttrKeys as _vnode_getAttrKeys, vnode_getFirstChild as _vnode_getFirstChild, vnode_isMaterialized as _vnode_isMaterialized, vnode_isTextVNode as _vnode_isTextVNode, vnode_isVirtualVNode as _vnode_isVirtualVNode, vnode_toString as _vnode_toString, _waitUntilRendered, _walkJSX, _wrapProp, _wrapSignal, component$, componentQrl, createAsync$, createAsyncSignal as createAsyncQrl, createComputed$, createComputedSignal as createComputedQrl, createContextId, h as createElement, createSerializer$, createSerializerSignal as createSerializerQrl, createSignal, event$, eventQrl, forceStoreEffects, getDomContainer, getLocale, getPlatform, h, implicit$FirstArg, inlinedQrl, inlinedQrlDEV, isSignal, jsx, jsxDEV, jsxs, noSerialize, qrl, qrlDEV, render, setPlatform, sync$, untrack, unwrapStore, useAsync$, useAsyncQrl, useComputed$, useComputedQrl, useConstant, useContext, useContextProvider, useErrorBoundary, useId, useLexicalScope, useOn, useOnDocument, useOnWindow, useResource$, useResourceQrl, useSerializer$, useSerializerQrl, useServerData, useSignal, useStore, useStyles$, useStylesQrl, useStylesScoped$, useStylesScopedQrl, useTask$, useTaskQrl, useVisibleTask$, useVisibleTaskQrl, version, withLocale };
|
|
14143
|
+
export { $, Fragment, NoSerializeSymbol, PrefetchGraph, PrefetchServiceWorker, RenderOnce, Resource, SSRComment, SSRRaw, SSRStream, SSRStreamBlock, SerializerSymbol, SkipRender, Slot, _CONST_PROPS, DomContainer as _DomContainer, _EFFECT_BACK_REF, EMPTY_ARRAY as _EMPTY_ARRAY, EMPTY_OBJ as _EMPTY_OBJ, _IMMUTABLE, _SharedContainer, SubscriptionData as _SubscriptionData, _UNINITIALIZED, _VAR_PROPS, _addProjection, _captures, _chk, createQRL as _createQRL, _deserialize, _dumpState, _executeSsrChores, _fnSignal, _getConstProps, _getContextContainer, _getContextEvent, _getContextHostElement, getDomContainer as _getDomContainer, _getQContainerElement, _getVarProps, _hasStoreEffects, _hmr, isJSXNode as _isJSXNode, isStore as _isStore, isStringifiable as _isStringifiable, isTask as _isTask, _jsxBranch, _jsxC, _jsxQ, _jsxS, _jsxSorted, _jsxSplit, mapApp_findIndx as _mapApp_findIndx, mapArray_get as _mapArray_get, mapArray_set as _mapArray_set, _noopQrl, _noopQrlDEV, preprocessState as _preprocessState, _qrlSync, qrlToString as _qrlToString, _regSymbol, _removeProjection, _res, _resolveContextWithoutSequentialScope, _restProps, _rsc, _run, _serialize, setEvent as _setEvent, _setProjectionTarget, scheduleTask as _task, _updateProjectionProps, _useHmr, _val, verifySerializable as _verifySerializable, vnode_ensureElementInflated as _vnode_ensureElementInflated, vnode_getAttrKeys as _vnode_getAttrKeys, vnode_getFirstChild as _vnode_getFirstChild, vnode_isMaterialized as _vnode_isMaterialized, vnode_isTextVNode as _vnode_isTextVNode, vnode_isVirtualVNode as _vnode_isVirtualVNode, vnode_toString as _vnode_toString, _waitUntilRendered, _walkJSX, _wrapProp, _wrapSignal, component$, componentQrl, createAsync$, createAsyncSignal as createAsyncQrl, createComputed$, createComputedSignal as createComputedQrl, createContextId, h as createElement, createSerializer$, createSerializerSignal as createSerializerQrl, createSignal, event$, eventQrl, forceStoreEffects, getDomContainer, getLocale, getPlatform, h, implicit$FirstArg, inlinedQrl, inlinedQrlDEV, isSignal, jsx, jsxDEV, jsxs, noSerialize, qrl, qrlDEV, render, setPlatform, sync$, untrack, unwrapStore, useAsync$, useAsyncQrl, useComputed$, useComputedQrl, useConstant, useContext, useContextProvider, useErrorBoundary, useId, useLexicalScope, useOn, useOnDocument, useOnWindow, useResource$, useResourceQrl, useSerializer$, useSerializerQrl, useServerData, useSignal, useStore, useStyles$, useStylesQrl, useStylesScoped$, useStylesScopedQrl, useTask$, useTaskQrl, useVisibleTask$, useVisibleTaskQrl, version, withLocale };
|
|
13914
14144
|
//# sourceMappingURL=core.mjs.map
|