@qwik.dev/core 2.0.0-beta.21 → 2.0.0-beta.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/backpatch/package.json +1 -1
- package/dist/build/package.json +1 -1
- package/dist/cli.mjs +7742 -422
- package/dist/core-internal.d.ts +270 -164
- package/dist/core.min.mjs +1 -2
- package/dist/core.mjs +938 -932
- package/dist/core.mjs.map +1 -1
- package/dist/core.prod.mjs +562 -504
- package/dist/loader/package.json +1 -1
- package/dist/optimizer.mjs +440 -441
- package/dist/server.mjs +20 -5
- package/dist/testing/index.d.ts +68 -34
- package/dist/testing/index.mjs +958 -881
- package/dist/testing/package.json +1 -1
- package/handlers.mjs +1 -1
- package/package.json +2 -2
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.23-dev+03de42d
|
|
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
|
|
@@ -14,7 +14,7 @@ import { p } from '@qwik.dev/core/preloader';
|
|
|
14
14
|
*
|
|
15
15
|
* @public
|
|
16
16
|
*/
|
|
17
|
-
const version = "2.0.0-beta.
|
|
17
|
+
const version = "2.0.0-beta.23-dev+03de42d";
|
|
18
18
|
|
|
19
19
|
// same as isDev but separate so we can test
|
|
20
20
|
const qDev = globalThis.qDev !== false;
|
|
@@ -230,7 +230,6 @@ const MATH_NS = 'http://www.w3.org/1998/Math/MathML';
|
|
|
230
230
|
// Attributes namespaces
|
|
231
231
|
const XLINK_NS = 'http://www.w3.org/1999/xlink';
|
|
232
232
|
const XML_NS = 'http://www.w3.org/XML/1998/namespace';
|
|
233
|
-
const ResourceEvent = 'qResource';
|
|
234
233
|
const RenderEvent = 'qRender';
|
|
235
234
|
const TaskEvent = 'qTask';
|
|
236
235
|
/** `<q:slot name="...">` */
|
|
@@ -396,11 +395,6 @@ const maybeThen = (valueOrPromise, thenFn) => {
|
|
|
396
395
|
? valueOrPromise.then(thenFn)
|
|
397
396
|
: thenFn(valueOrPromise);
|
|
398
397
|
};
|
|
399
|
-
const delay = (timeout) => {
|
|
400
|
-
return new Promise((resolve) => {
|
|
401
|
-
setTimeout(resolve, timeout);
|
|
402
|
-
});
|
|
403
|
-
};
|
|
404
398
|
const checkError = (e) => {
|
|
405
399
|
if (isServer && e instanceof ReferenceError && e.message.includes('window')) {
|
|
406
400
|
e.message = 'It seems like you forgot to add "if (isBrowser) {...}" here:' + e.message;
|
|
@@ -577,40 +571,6 @@ const vnode_getElementNamespaceFlags = (element) => {
|
|
|
577
571
|
return 0 /* VNodeFlags.NS_html */;
|
|
578
572
|
}
|
|
579
573
|
};
|
|
580
|
-
function vnode_getDomChildrenWithCorrectNamespacesToInsert(journal, domParentVNode, newChild) {
|
|
581
|
-
const { elementNamespace, elementNamespaceFlag } = getNewElementNamespaceData(domParentVNode, newChild);
|
|
582
|
-
let domChildren = [];
|
|
583
|
-
if (elementNamespace === HTML_NS) {
|
|
584
|
-
// parent is in the default namespace, so just get the dom children. This is the fast path.
|
|
585
|
-
domChildren = vnode_getDOMChildNodes(journal, newChild, true);
|
|
586
|
-
}
|
|
587
|
-
else {
|
|
588
|
-
// parent is in a different namespace, so we need to clone the children with the correct namespace.
|
|
589
|
-
// The namespace cannot be changed on nodes, so we need to clone these nodes
|
|
590
|
-
const children = vnode_getDOMChildNodes(journal, newChild, true);
|
|
591
|
-
for (let i = 0; i < children.length; i++) {
|
|
592
|
-
const childVNode = children[i];
|
|
593
|
-
if (vnode_isTextVNode(childVNode)) {
|
|
594
|
-
// text nodes are always in the default namespace
|
|
595
|
-
domChildren.push(childVNode);
|
|
596
|
-
continue;
|
|
597
|
-
}
|
|
598
|
-
if ((childVNode.flags & 1536 /* VNodeFlags.NAMESPACE_MASK */) ===
|
|
599
|
-
(domParentVNode.flags & 1536 /* VNodeFlags.NAMESPACE_MASK */)) {
|
|
600
|
-
// if the child and parent have the same namespace, we don't need to clone the element
|
|
601
|
-
domChildren.push(childVNode);
|
|
602
|
-
continue;
|
|
603
|
-
}
|
|
604
|
-
// clone the element with the correct namespace
|
|
605
|
-
const newChildElement = vnode_cloneElementWithNamespace(childVNode, domParentVNode, elementNamespace, elementNamespaceFlag);
|
|
606
|
-
if (newChildElement) {
|
|
607
|
-
childVNode.node = newChildElement;
|
|
608
|
-
domChildren.push(childVNode);
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
return domChildren;
|
|
613
|
-
}
|
|
614
574
|
/** This function clones an element with a different namespace, including the children */
|
|
615
575
|
function cloneDomTreeWithNamespace(element, elementName, namespace, deep = false) {
|
|
616
576
|
const newElement = element.ownerDocument.createElementNS(namespace, elementName);
|
|
@@ -963,8 +923,7 @@ class TextVNode extends VNode {
|
|
|
963
923
|
const globalCursorQueue = [];
|
|
964
924
|
const pausedCursorQueue = [];
|
|
965
925
|
/**
|
|
966
|
-
* Adds a cursor to the global queue.
|
|
967
|
-
* maintain correct priority order.
|
|
926
|
+
* Adds a cursor to the global queue.
|
|
968
927
|
*
|
|
969
928
|
* @param cursor - The cursor to add
|
|
970
929
|
*/
|
|
@@ -979,7 +938,7 @@ function addCursorToQueue(container, cursor) {
|
|
|
979
938
|
}
|
|
980
939
|
}
|
|
981
940
|
globalCursorQueue.splice(insertIndex, 0, cursor);
|
|
982
|
-
container.$
|
|
941
|
+
container.$pendingCount$++;
|
|
983
942
|
container.$renderPromise$ ||= new Promise((r) => (container.$resolveRenderPromise$ = r));
|
|
984
943
|
}
|
|
985
944
|
/**
|
|
@@ -1007,7 +966,7 @@ function getHighestPriorityCursor() {
|
|
|
1007
966
|
function pauseCursor(cursor, container) {
|
|
1008
967
|
pausedCursorQueue.push(cursor);
|
|
1009
968
|
removeCursorFromQueue(cursor, container, true);
|
|
1010
|
-
container.$
|
|
969
|
+
container.$pendingCount$++;
|
|
1011
970
|
}
|
|
1012
971
|
function resumeCursor(cursor, container) {
|
|
1013
972
|
const index = pausedCursorQueue.indexOf(cursor);
|
|
@@ -1017,7 +976,7 @@ function resumeCursor(cursor, container) {
|
|
|
1017
976
|
pausedCursorQueue[index] = pausedCursorQueue[lastIndex];
|
|
1018
977
|
}
|
|
1019
978
|
pausedCursorQueue.pop();
|
|
1020
|
-
container.$
|
|
979
|
+
container.$pendingCount$--;
|
|
1021
980
|
}
|
|
1022
981
|
addCursorToQueue(container, cursor);
|
|
1023
982
|
}
|
|
@@ -1040,7 +999,7 @@ function removeCursorFromQueue(cursor, container, keepCursorFlag) {
|
|
|
1040
999
|
// }
|
|
1041
1000
|
// globalCursorQueue.pop();
|
|
1042
1001
|
globalCursorQueue.splice(index, 1);
|
|
1043
|
-
container.$
|
|
1002
|
+
container.$pendingCount$--;
|
|
1044
1003
|
}
|
|
1045
1004
|
}
|
|
1046
1005
|
|
|
@@ -1129,7 +1088,7 @@ class SignalImpl {
|
|
|
1129
1088
|
$container$ = null;
|
|
1130
1089
|
$wrappedSignal$ = null;
|
|
1131
1090
|
constructor(container, value) {
|
|
1132
|
-
this.$container$ = container;
|
|
1091
|
+
this.$container$ = container || tryGetInvokeContext()?.$container$ || null;
|
|
1133
1092
|
this.$untrackedValue$ = value;
|
|
1134
1093
|
}
|
|
1135
1094
|
/**
|
|
@@ -1147,14 +1106,13 @@ class SignalImpl {
|
|
|
1147
1106
|
this.$untrackedValue$ = value;
|
|
1148
1107
|
}
|
|
1149
1108
|
get value() {
|
|
1109
|
+
// Important: first read, then subscribe. Otherwise, initial compute invalidation will cause the reading subscriber to be marked invalid.
|
|
1110
|
+
const val = this.untrackedValue;
|
|
1150
1111
|
const ctx = tryGetInvokeContext();
|
|
1151
1112
|
if (!ctx) {
|
|
1152
|
-
return
|
|
1113
|
+
return val;
|
|
1153
1114
|
}
|
|
1154
1115
|
if (this.$container$ === null) {
|
|
1155
|
-
if (!ctx.$container$) {
|
|
1156
|
-
return this.untrackedValue;
|
|
1157
|
-
}
|
|
1158
1116
|
// Grab the container now we have access to it
|
|
1159
1117
|
this.$container$ = ctx.$container$;
|
|
1160
1118
|
}
|
|
@@ -1175,7 +1133,7 @@ class SignalImpl {
|
|
|
1175
1133
|
(import.meta.env.TEST ? !isDomContainer(this.$container$) : isServer) &&
|
|
1176
1134
|
addQrlToSerializationCtx(effectSubscriber, this.$container$);
|
|
1177
1135
|
}
|
|
1178
|
-
return
|
|
1136
|
+
return val;
|
|
1179
1137
|
}
|
|
1180
1138
|
set value(value) {
|
|
1181
1139
|
if (value !== this.$untrackedValue$) {
|
|
@@ -1191,10 +1149,15 @@ class SignalImpl {
|
|
|
1191
1149
|
}
|
|
1192
1150
|
toString() {
|
|
1193
1151
|
if (isDev) {
|
|
1194
|
-
|
|
1195
|
-
(
|
|
1196
|
-
.
|
|
1197
|
-
|
|
1152
|
+
try {
|
|
1153
|
+
return (`[${this.constructor.name}${this.$flags$ & 1 /* SignalFlags.INVALID */ ? ' INVALID' : ''} ${this.$untrackedValue$}]` +
|
|
1154
|
+
(Array.from(this.$effects$ || [])
|
|
1155
|
+
.map((e) => '\n -> ' + pad(qwikDebugToString(e.consumer), ' '))
|
|
1156
|
+
.join('\n') || ''));
|
|
1157
|
+
}
|
|
1158
|
+
catch (e) {
|
|
1159
|
+
return `[${this.constructor.name} <cannot stringify>]`;
|
|
1160
|
+
}
|
|
1198
1161
|
}
|
|
1199
1162
|
else {
|
|
1200
1163
|
return this.constructor.name;
|
|
@@ -1204,35 +1167,27 @@ class SignalImpl {
|
|
|
1204
1167
|
return { value: this.$untrackedValue$ };
|
|
1205
1168
|
}
|
|
1206
1169
|
}
|
|
1207
|
-
const setupSignalValueAccess = (target,
|
|
1170
|
+
const setupSignalValueAccess = (target, effectsProp, valueProp) => {
|
|
1208
1171
|
const ctx = tryGetInvokeContext();
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
if (target.$container$ === null) {
|
|
1213
|
-
if (!ctx.$container$) {
|
|
1214
|
-
return returnValueFn();
|
|
1215
|
-
}
|
|
1216
|
-
// Grab the container now we have access to it
|
|
1217
|
-
target.$container$ = ctx.$container$;
|
|
1218
|
-
}
|
|
1219
|
-
else {
|
|
1172
|
+
// We need a container for this
|
|
1173
|
+
// Grab the container if we have access to it
|
|
1174
|
+
if (ctx && (target.$container$ ||= ctx.$container$ || null)) {
|
|
1220
1175
|
isDev &&
|
|
1221
1176
|
assertTrue(!ctx.$container$ || ctx.$container$ === target.$container$, 'Do not use signals across containers');
|
|
1177
|
+
const effectSubscriber = ctx.$effectSubscriber$;
|
|
1178
|
+
if (effectSubscriber) {
|
|
1179
|
+
// Let's make sure that we have a reference to this effect.
|
|
1180
|
+
// Adding reference is essentially adding a subscription, so if the signal
|
|
1181
|
+
// changes we know who to notify.
|
|
1182
|
+
ensureContainsSubscription((target[effectsProp] ||= new Set()), effectSubscriber);
|
|
1183
|
+
// But when effect is scheduled in needs to be able to know which signals
|
|
1184
|
+
// to unsubscribe from. So we need to store the reference from the effect back
|
|
1185
|
+
// to this signal.
|
|
1186
|
+
ensureContainsBackRef(effectSubscriber, target);
|
|
1187
|
+
addQrlToSerializationCtx(effectSubscriber, target.$container$);
|
|
1188
|
+
}
|
|
1222
1189
|
}
|
|
1223
|
-
|
|
1224
|
-
if (effectSubscriber) {
|
|
1225
|
-
// Let's make sure that we have a reference to this effect.
|
|
1226
|
-
// Adding reference is essentially adding a subscription, so if the signal
|
|
1227
|
-
// changes we know who to notify.
|
|
1228
|
-
ensureContainsSubscription(effectsFn(), effectSubscriber);
|
|
1229
|
-
// But when effect is scheduled in needs to be able to know which signals
|
|
1230
|
-
// to unsubscribe from. So we need to store the reference from the effect back
|
|
1231
|
-
// to this signal.
|
|
1232
|
-
ensureContainsBackRef(effectSubscriber, target);
|
|
1233
|
-
addQrlToSerializationCtx(effectSubscriber, target.$container$);
|
|
1234
|
-
}
|
|
1235
|
-
return returnValueFn();
|
|
1190
|
+
return target[valueProp];
|
|
1236
1191
|
};
|
|
1237
1192
|
|
|
1238
1193
|
/** @internal */
|
|
@@ -1461,19 +1416,6 @@ const isPropsProxy = (obj) => {
|
|
|
1461
1416
|
return obj && _VAR_PROPS in obj;
|
|
1462
1417
|
};
|
|
1463
1418
|
|
|
1464
|
-
const cleanupDestroyable = (destroyable) => {
|
|
1465
|
-
const destroy = destroyable.$destroy$;
|
|
1466
|
-
if (destroy) {
|
|
1467
|
-
destroyable.$destroy$ = null;
|
|
1468
|
-
try {
|
|
1469
|
-
destroy();
|
|
1470
|
-
}
|
|
1471
|
-
catch (err) {
|
|
1472
|
-
logError(err);
|
|
1473
|
-
}
|
|
1474
|
-
}
|
|
1475
|
-
};
|
|
1476
|
-
|
|
1477
1419
|
/**
|
|
1478
1420
|
* # ================================
|
|
1479
1421
|
*
|
|
@@ -1594,14 +1536,19 @@ const trackFn = (target, container) => (obj, prop) => {
|
|
|
1594
1536
|
}
|
|
1595
1537
|
});
|
|
1596
1538
|
};
|
|
1539
|
+
/**
|
|
1540
|
+
* This adds $destroy$ to the target if a cleanup function is registered. It must be called before
|
|
1541
|
+
* running any computations again.
|
|
1542
|
+
*/
|
|
1597
1543
|
const cleanupFn = (target, handleError) => {
|
|
1598
1544
|
let cleanupFns = null;
|
|
1599
1545
|
const cleanup = (fn) => {
|
|
1600
1546
|
if (typeof fn == 'function') {
|
|
1601
1547
|
if (!cleanupFns) {
|
|
1602
1548
|
cleanupFns = [];
|
|
1603
|
-
target.$destroy$ =
|
|
1549
|
+
target.$destroy$ = () => {
|
|
1604
1550
|
target.$destroy$ = null;
|
|
1551
|
+
// TODO handle promises
|
|
1605
1552
|
for (const fn of cleanupFns) {
|
|
1606
1553
|
try {
|
|
1607
1554
|
fn();
|
|
@@ -1610,7 +1557,7 @@ const cleanupFn = (target, handleError) => {
|
|
|
1610
1557
|
handleError(err);
|
|
1611
1558
|
}
|
|
1612
1559
|
}
|
|
1613
|
-
}
|
|
1560
|
+
};
|
|
1614
1561
|
}
|
|
1615
1562
|
cleanupFns.push(fn);
|
|
1616
1563
|
}
|
|
@@ -1618,9 +1565,9 @@ const cleanupFn = (target, handleError) => {
|
|
|
1618
1565
|
return [cleanup, cleanupFns ?? []];
|
|
1619
1566
|
};
|
|
1620
1567
|
|
|
1621
|
-
const DEBUG = false;
|
|
1568
|
+
const DEBUG$1 = false;
|
|
1622
1569
|
// eslint-disable-next-line no-console
|
|
1623
|
-
const log = (...args) => console.log('COMPUTED SIGNAL', ...args.map(qwikDebugToString));
|
|
1570
|
+
const log$1 = (...args) => console.log('COMPUTED SIGNAL', ...args.map(qwikDebugToString));
|
|
1624
1571
|
/**
|
|
1625
1572
|
* A signal which is computed from other signals.
|
|
1626
1573
|
*
|
|
@@ -1643,7 +1590,7 @@ class ComputedSignalImpl extends SignalImpl {
|
|
|
1643
1590
|
16 /* SerializationSignalFlags.SERIALIZATION_STRATEGY_ALWAYS */) {
|
|
1644
1591
|
// The value is used for comparison when signals trigger, which can only happen
|
|
1645
1592
|
// when it was calculated before. Therefore we can pass whatever we like.
|
|
1646
|
-
super(container
|
|
1593
|
+
super(container || fn.$container$, NEEDS_COMPUTATION);
|
|
1647
1594
|
this.$computeQrl$ = fn;
|
|
1648
1595
|
this.$flags$ = flags;
|
|
1649
1596
|
}
|
|
@@ -1651,20 +1598,18 @@ class ComputedSignalImpl extends SignalImpl {
|
|
|
1651
1598
|
this.$flags$ |= 1 /* SignalFlags.INVALID */;
|
|
1652
1599
|
const ctx = newInvokeContext();
|
|
1653
1600
|
ctx.$container$ = this.$container$ || undefined;
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
this.$flags$ |= 2 /* SignalFlags.RUN_EFFECTS */;
|
|
1667
|
-
super.force();
|
|
1601
|
+
// @ts-expect-error it's confused about args any[] vs []
|
|
1602
|
+
const running = retryOnPromise(invokeApply.bind(this, ctx, this.$computeIfNeeded$));
|
|
1603
|
+
if (running) {
|
|
1604
|
+
running.catch((err) => {
|
|
1605
|
+
if (this.$container$) {
|
|
1606
|
+
this.$container$.handleError(err, null);
|
|
1607
|
+
}
|
|
1608
|
+
else {
|
|
1609
|
+
console.error('Error during computation', err);
|
|
1610
|
+
}
|
|
1611
|
+
});
|
|
1612
|
+
}
|
|
1668
1613
|
}
|
|
1669
1614
|
get untrackedValue() {
|
|
1670
1615
|
this.$computeIfNeeded$();
|
|
@@ -1692,16 +1637,9 @@ class ComputedSignalImpl extends SignalImpl {
|
|
|
1692
1637
|
computeQrl.$hash$,
|
|
1693
1638
|
]);
|
|
1694
1639
|
}
|
|
1695
|
-
DEBUG && log('Signal.$compute$', untrackedValue);
|
|
1640
|
+
DEBUG$1 && log$1('Signal.$compute$', untrackedValue);
|
|
1696
1641
|
this.$flags$ &= ~1 /* SignalFlags.INVALID */;
|
|
1697
|
-
|
|
1698
|
-
if (didChange) {
|
|
1699
|
-
// skip first computation when value is not changed
|
|
1700
|
-
if (this.$untrackedValue$ !== NEEDS_COMPUTATION) {
|
|
1701
|
-
this.$flags$ |= 2 /* SignalFlags.RUN_EFFECTS */;
|
|
1702
|
-
}
|
|
1703
|
-
this.$untrackedValue$ = untrackedValue;
|
|
1704
|
-
}
|
|
1642
|
+
super.value = untrackedValue;
|
|
1705
1643
|
}
|
|
1706
1644
|
finally {
|
|
1707
1645
|
if (ctx) {
|
|
@@ -1711,6 +1649,51 @@ class ComputedSignalImpl extends SignalImpl {
|
|
|
1711
1649
|
}
|
|
1712
1650
|
}
|
|
1713
1651
|
|
|
1652
|
+
/**
|
|
1653
|
+
* Planned features:
|
|
1654
|
+
*
|
|
1655
|
+
* - `eagerCleanup`: boolean - whether to run cleanups eagerly when there are no more subscribers, or
|
|
1656
|
+
* to wait until the next computation/destroy.
|
|
1657
|
+
*/
|
|
1658
|
+
const DEBUG = false;
|
|
1659
|
+
const log = (...args) =>
|
|
1660
|
+
// eslint-disable-next-line no-console
|
|
1661
|
+
console.log('ASYNC COMPUTED SIGNAL', ...args.map(qwikDebugToString));
|
|
1662
|
+
/** Retains job metadata and also serves as the argument for the compute function */
|
|
1663
|
+
class AsyncJob {
|
|
1664
|
+
$signal$;
|
|
1665
|
+
/** First holds the compute promise and then the cleanup promise */
|
|
1666
|
+
$promise$ = null;
|
|
1667
|
+
$cleanupRequested$ = false;
|
|
1668
|
+
$canWrite$ = true;
|
|
1669
|
+
$track$;
|
|
1670
|
+
$cleanups$;
|
|
1671
|
+
$abortController$;
|
|
1672
|
+
constructor($signal$) {
|
|
1673
|
+
this.$signal$ = $signal$;
|
|
1674
|
+
}
|
|
1675
|
+
get track() {
|
|
1676
|
+
return (this.$track$ ||= trackFn(this.$signal$, this.$signal$.$container$));
|
|
1677
|
+
}
|
|
1678
|
+
get abortSignal() {
|
|
1679
|
+
return (this.$abortController$ ||= new AbortController()).signal;
|
|
1680
|
+
}
|
|
1681
|
+
/** Backward compatible cache method for resource */
|
|
1682
|
+
cache() {
|
|
1683
|
+
console.error('useResource cache() method does not do anything. Use `useAsync$` instead of `useResource$`, use the `interval` option for polling behavior.');
|
|
1684
|
+
}
|
|
1685
|
+
get previous() {
|
|
1686
|
+
const val = this.$signal$.$untrackedValue$;
|
|
1687
|
+
if (val !== NEEDS_COMPUTATION) {
|
|
1688
|
+
return val;
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1691
|
+
cleanup(callback) {
|
|
1692
|
+
if (typeof callback === 'function') {
|
|
1693
|
+
(this.$cleanups$ ||= []).push(callback);
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1714
1697
|
/**
|
|
1715
1698
|
* # ================================
|
|
1716
1699
|
*
|
|
@@ -1723,19 +1706,45 @@ class AsyncSignalImpl extends ComputedSignalImpl {
|
|
|
1723
1706
|
$untrackedError$ = undefined;
|
|
1724
1707
|
$loadingEffects$ = undefined;
|
|
1725
1708
|
$errorEffects$ = undefined;
|
|
1726
|
-
$
|
|
1727
|
-
|
|
1728
|
-
$
|
|
1709
|
+
$current$ = null;
|
|
1710
|
+
// TODO only create the array if concurrency > 1
|
|
1711
|
+
$jobs$ = [];
|
|
1712
|
+
$concurrency$ = 1;
|
|
1713
|
+
$interval$ = 0;
|
|
1714
|
+
$pollTimeoutId$ = undefined;
|
|
1715
|
+
$timeoutMs$;
|
|
1716
|
+
$computationTimeoutId$;
|
|
1729
1717
|
[_EFFECT_BACK_REF] = undefined;
|
|
1730
|
-
constructor(container, fn, flags = 1 /* SignalFlags.INVALID */
|
|
1718
|
+
constructor(container, fn, flags = 1 /* SignalFlags.INVALID */ |
|
|
1719
|
+
16 /* SerializationSignalFlags.SERIALIZATION_STRATEGY_ALWAYS */, options) {
|
|
1731
1720
|
super(container, fn, flags);
|
|
1721
|
+
const interval = options?.interval || 0;
|
|
1722
|
+
const concurrency = options?.concurrency ?? 1;
|
|
1723
|
+
const initial = options?.initial;
|
|
1724
|
+
const timeout = options?.timeout;
|
|
1725
|
+
const eagerCleanup = options?.eagerCleanup;
|
|
1726
|
+
// Handle initial value - eagerly evaluate if function, set $untrackedValue$ and $promiseValue$
|
|
1727
|
+
// Do NOT call setValue() which would clear the INVALID flag and prevent async computation
|
|
1728
|
+
if (initial !== undefined) {
|
|
1729
|
+
const initialValue = typeof initial === 'function' ? initial() : initial;
|
|
1730
|
+
this.$untrackedValue$ = initialValue;
|
|
1731
|
+
}
|
|
1732
|
+
this.$concurrency$ = concurrency;
|
|
1733
|
+
this.$timeoutMs$ = timeout;
|
|
1734
|
+
if (eagerCleanup) {
|
|
1735
|
+
this.$flags$ |= 32 /* AsyncSignalFlags.EAGER_CLEANUP */;
|
|
1736
|
+
}
|
|
1737
|
+
this.interval = interval;
|
|
1732
1738
|
}
|
|
1733
1739
|
/**
|
|
1734
1740
|
* Loading is true if the signal is still waiting for the promise to resolve, false if the promise
|
|
1735
1741
|
* has resolved or rejected.
|
|
1742
|
+
*
|
|
1743
|
+
* Accessing .loading will trigger computation if needed, since it's often used like
|
|
1744
|
+
* `signal.loading ? <Loading /> : signal.value`.
|
|
1736
1745
|
*/
|
|
1737
1746
|
get loading() {
|
|
1738
|
-
return setupSignalValueAccess(this,
|
|
1747
|
+
return setupSignalValueAccess(this, '$loadingEffects$', 'untrackedLoading');
|
|
1739
1748
|
}
|
|
1740
1749
|
set untrackedLoading(value) {
|
|
1741
1750
|
if (value !== this.$untrackedLoading$) {
|
|
@@ -1744,11 +1753,17 @@ class AsyncSignalImpl extends ComputedSignalImpl {
|
|
|
1744
1753
|
}
|
|
1745
1754
|
}
|
|
1746
1755
|
get untrackedLoading() {
|
|
1756
|
+
// reading `.loading` means someone is interested in the result, so we should trigger the computation. The alternative is eager computation or imperative calls to invalidate; this seems nicer.
|
|
1757
|
+
this.$computeIfNeeded$();
|
|
1758
|
+
// During SSR there's no such thing as loading state, we must render complete results
|
|
1759
|
+
if ((import.meta.env.TEST ? isServerPlatform() : isServer) && this.$current$?.$promise$) {
|
|
1760
|
+
throw this.$current$?.$promise$;
|
|
1761
|
+
}
|
|
1747
1762
|
return this.$untrackedLoading$;
|
|
1748
1763
|
}
|
|
1749
1764
|
/** The error that occurred when the signal was resolved. */
|
|
1750
1765
|
get error() {
|
|
1751
|
-
return setupSignalValueAccess(this,
|
|
1766
|
+
return setupSignalValueAccess(this, '$errorEffects$', 'untrackedError');
|
|
1752
1767
|
}
|
|
1753
1768
|
set untrackedError(value) {
|
|
1754
1769
|
if (value !== this.$untrackedError$) {
|
|
@@ -1759,123 +1774,205 @@ class AsyncSignalImpl extends ComputedSignalImpl {
|
|
|
1759
1774
|
get untrackedError() {
|
|
1760
1775
|
return this.$untrackedError$;
|
|
1761
1776
|
}
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1777
|
+
get interval() {
|
|
1778
|
+
return this.$interval$;
|
|
1779
|
+
}
|
|
1780
|
+
set interval(value) {
|
|
1781
|
+
this.$clearNextPoll$();
|
|
1782
|
+
this.$interval$ = value;
|
|
1783
|
+
if (this.$interval$ > 0 && this.$effects$?.size) {
|
|
1784
|
+
this.$scheduleNextPoll$();
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
/** Invalidates the signal, causing it to re-compute its value. */
|
|
1788
|
+
async invalidate() {
|
|
1789
|
+
this.$flags$ |= 1 /* SignalFlags.INVALID */;
|
|
1790
|
+
this.$clearNextPoll$();
|
|
1791
|
+
if (this.$effects$?.size || this.$loadingEffects$?.size || this.$errorEffects$?.size) {
|
|
1792
|
+
// compute in next microtask
|
|
1793
|
+
await true;
|
|
1794
|
+
this.$computeIfNeeded$();
|
|
1795
|
+
}
|
|
1766
1796
|
}
|
|
1797
|
+
/** Abort the current computation and run cleanups if needed. */
|
|
1798
|
+
abort(reason) {
|
|
1799
|
+
if (this.$current$) {
|
|
1800
|
+
this.$requestCleanups$(this.$current$, reason);
|
|
1801
|
+
}
|
|
1802
|
+
}
|
|
1803
|
+
/** Schedule eager cleanup on next macro task if no subscribers remain. */
|
|
1804
|
+
$scheduleEagerCleanup$() {
|
|
1805
|
+
if (!(this.$flags$ & 32 /* AsyncSignalFlags.EAGER_CLEANUP */) || this.$hasSubscribers$()) {
|
|
1806
|
+
return;
|
|
1807
|
+
}
|
|
1808
|
+
if (!(import.meta.env.TEST ? !isServerPlatform() : isBrowser)) {
|
|
1809
|
+
return;
|
|
1810
|
+
}
|
|
1811
|
+
setTimeout(() => {
|
|
1812
|
+
if (!this.$hasSubscribers$()) {
|
|
1813
|
+
this.abort();
|
|
1814
|
+
}
|
|
1815
|
+
});
|
|
1816
|
+
}
|
|
1817
|
+
/** Returns a promise resolves when the signal finished computing. */
|
|
1767
1818
|
async promise() {
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1819
|
+
this.$computeIfNeeded$();
|
|
1820
|
+
// Wait for the current computation to finish, but if we became invalid while running, we need to wait for the new computation instead. So we loop until we are no longer invalid
|
|
1821
|
+
while (this.$current$?.$promise$) {
|
|
1822
|
+
await this.$current$?.$promise$;
|
|
1823
|
+
}
|
|
1772
1824
|
}
|
|
1825
|
+
/** Run the computation if needed */
|
|
1773
1826
|
$computeIfNeeded$() {
|
|
1774
1827
|
if (!(this.$flags$ & 1 /* SignalFlags.INVALID */)) {
|
|
1775
1828
|
return;
|
|
1776
1829
|
}
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1830
|
+
this.$clearNextPoll$();
|
|
1831
|
+
if (this.$current$) {
|
|
1832
|
+
this.$requestCleanups$(this.$current$);
|
|
1833
|
+
}
|
|
1834
|
+
const limit = this.$concurrency$ === 0 ? Number.POSITIVE_INFINITY : this.$concurrency$;
|
|
1835
|
+
if (this.$jobs$.length >= limit) {
|
|
1836
|
+
// We requested cleanups for all the previous jobs, once one finishes it will be removed from the jobs array and trigger computeIfNeeded
|
|
1837
|
+
return;
|
|
1838
|
+
}
|
|
1839
|
+
this.$flags$ &= -2 /* SignalFlags.INVALID */;
|
|
1840
|
+
// We put the actual computation in a separate method so we can easily retain the promise
|
|
1841
|
+
const running = new AsyncJob(this);
|
|
1842
|
+
this.$current$ = running;
|
|
1843
|
+
this.$jobs$.push(running);
|
|
1844
|
+
running.$promise$ = this.$runComputation$(running);
|
|
1845
|
+
}
|
|
1846
|
+
async $runComputation$(running) {
|
|
1847
|
+
const isCurrent = () => running === this.$current$;
|
|
1848
|
+
this.untrackedLoading = true;
|
|
1849
|
+
const fn = this.$computeQrl$.resolved || (await this.$computeQrl$.resolve());
|
|
1850
|
+
try {
|
|
1851
|
+
if (this.$timeoutMs$) {
|
|
1852
|
+
this.$computationTimeoutId$ = setTimeout(() => {
|
|
1853
|
+
running.$abortController$?.abort();
|
|
1854
|
+
const error = new Error(`timeout`);
|
|
1855
|
+
if (isCurrent()) {
|
|
1856
|
+
this.untrackedError = error;
|
|
1857
|
+
running.$canWrite$ = false;
|
|
1858
|
+
}
|
|
1859
|
+
}, this.$timeoutMs$);
|
|
1860
|
+
}
|
|
1861
|
+
const value = await retryOnPromise(fn.bind(null, running));
|
|
1862
|
+
running.$promise$ = null;
|
|
1863
|
+
if (running.$canWrite$) {
|
|
1864
|
+
const index = this.$jobs$.indexOf(running);
|
|
1865
|
+
if (index !== -1) {
|
|
1866
|
+
for (let i = 0; i < index; i++) {
|
|
1867
|
+
this.$jobs$[i].$canWrite$ = false;
|
|
1868
|
+
}
|
|
1806
1869
|
}
|
|
1807
|
-
|
|
1808
|
-
|
|
1870
|
+
DEBUG && log('Promise resolved', value);
|
|
1871
|
+
// we leave error as-is until result
|
|
1872
|
+
// Note that these assignments run setters
|
|
1873
|
+
this.untrackedError = undefined;
|
|
1874
|
+
this.value = value;
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
catch (err) {
|
|
1878
|
+
running.$promise$ = null;
|
|
1879
|
+
if (isCurrent()) {
|
|
1809
1880
|
this.untrackedError = err;
|
|
1810
|
-
}
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
if (isCurrent()) {
|
|
1884
|
+
clearTimeout(this.$computationTimeoutId$);
|
|
1885
|
+
if (this.$flags$ & 1 /* SignalFlags.INVALID */) {
|
|
1886
|
+
// we became invalid again while running, so we need to re-run the computation to get the new promise
|
|
1887
|
+
this.$computeIfNeeded$();
|
|
1815
1888
|
}
|
|
1816
1889
|
else {
|
|
1817
|
-
|
|
1818
|
-
|
|
1890
|
+
this.untrackedLoading = false;
|
|
1891
|
+
this.$scheduleNextPoll$();
|
|
1819
1892
|
}
|
|
1820
1893
|
}
|
|
1821
|
-
|
|
1822
|
-
|
|
1894
|
+
}
|
|
1895
|
+
/** Called after SSR/unmount */
|
|
1896
|
+
async $destroy$() {
|
|
1897
|
+
this.$clearNextPoll$();
|
|
1898
|
+
clearTimeout(this.$computationTimeoutId$);
|
|
1899
|
+
if (this.$current$) {
|
|
1900
|
+
await this.$requestCleanups$(this.$current$);
|
|
1823
1901
|
}
|
|
1902
|
+
await Promise.all(this.$jobs$.map((job) => job.$promise$));
|
|
1824
1903
|
}
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
this.$
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
}
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
this
|
|
1904
|
+
get untrackedValue() {
|
|
1905
|
+
this.$computeIfNeeded$();
|
|
1906
|
+
if (this.$current$?.$promise$) {
|
|
1907
|
+
if (this.$untrackedValue$ === NEEDS_COMPUTATION ||
|
|
1908
|
+
(import.meta.env.TEST ? isServerPlatform() : isServer)) {
|
|
1909
|
+
throw this.$current$?.$promise$;
|
|
1910
|
+
}
|
|
1911
|
+
return this.$untrackedValue$;
|
|
1912
|
+
}
|
|
1913
|
+
if (this.$untrackedError$) {
|
|
1914
|
+
throw this.$untrackedError$;
|
|
1915
|
+
}
|
|
1916
|
+
return this.$untrackedValue$;
|
|
1917
|
+
}
|
|
1918
|
+
$clearNextPoll$() {
|
|
1919
|
+
if (this.$pollTimeoutId$ !== undefined) {
|
|
1920
|
+
clearTimeout(this.$pollTimeoutId$);
|
|
1921
|
+
this.$pollTimeoutId$ = undefined;
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
$scheduleNextPoll$() {
|
|
1925
|
+
if ((import.meta.env.TEST ? !isServerPlatform() : isBrowser) && this.$interval$ > 0) {
|
|
1926
|
+
this.$clearNextPoll$();
|
|
1927
|
+
this.$pollTimeoutId$ = setTimeout(this.invalidate.bind(this), this.$interval$);
|
|
1928
|
+
this.$pollTimeoutId$?.unref?.();
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
$hasSubscribers$() {
|
|
1932
|
+
return !!(this.$effects$?.size || this.$loadingEffects$?.size || this.$errorEffects$?.size);
|
|
1933
|
+
}
|
|
1934
|
+
async $requestCleanups$(job, reason) {
|
|
1935
|
+
if (job.$cleanupRequested$) {
|
|
1936
|
+
return job.$promise$;
|
|
1937
|
+
}
|
|
1938
|
+
job.$cleanupRequested$ = true;
|
|
1939
|
+
job.$abortController$?.abort(reason);
|
|
1940
|
+
job.$promise$ = Promise.resolve(job.$promise$).then(() => (job.$promise$ = this.$runCleanups$(job)));
|
|
1941
|
+
}
|
|
1942
|
+
/** Clean up and trigger signal compute once complete */
|
|
1943
|
+
async $runCleanups$(job) {
|
|
1944
|
+
const cleanups = job.$cleanups$;
|
|
1945
|
+
if (cleanups?.length) {
|
|
1946
|
+
const onError = (err) => {
|
|
1947
|
+
const handleError = this.$container$?.handleError;
|
|
1948
|
+
if (handleError) {
|
|
1949
|
+
handleError(err, null);
|
|
1950
|
+
}
|
|
1951
|
+
else {
|
|
1952
|
+
console.error('Error in async signal cleanup', err);
|
|
1953
|
+
}
|
|
1954
|
+
};
|
|
1955
|
+
// Keep this sync-ish so sync functions run immediately.
|
|
1956
|
+
await Promise.all(cleanups.map((fn) => {
|
|
1957
|
+
try {
|
|
1958
|
+
const result = fn();
|
|
1959
|
+
if (isPromise(result)) {
|
|
1960
|
+
return result.catch(onError);
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
catch (err) {
|
|
1964
|
+
onError(err);
|
|
1965
|
+
}
|
|
1966
|
+
}));
|
|
1967
|
+
cleanups.length = 0;
|
|
1968
|
+
}
|
|
1969
|
+
// Now trigger compute
|
|
1970
|
+
const jobs = this.$jobs$;
|
|
1971
|
+
const idx = jobs.indexOf(job);
|
|
1972
|
+
if (idx !== -1) {
|
|
1973
|
+
jobs.splice(idx, 1);
|
|
1877
1974
|
}
|
|
1878
|
-
|
|
1975
|
+
this.$computeIfNeeded$();
|
|
1879
1976
|
}
|
|
1880
1977
|
}
|
|
1881
1978
|
|
|
@@ -1941,6 +2038,7 @@ class SerializerSignalImpl extends ComputedSignalImpl {
|
|
|
1941
2038
|
return;
|
|
1942
2039
|
}
|
|
1943
2040
|
throwIfQRLNotResolved(this.$computeQrl$);
|
|
2041
|
+
this.$flags$ &= -2 /* SignalFlags.INVALID */;
|
|
1944
2042
|
let arg = this.$computeQrl$.resolved;
|
|
1945
2043
|
if (typeof arg === 'function') {
|
|
1946
2044
|
arg = arg();
|
|
@@ -1951,13 +2049,13 @@ class SerializerSignalImpl extends ComputedSignalImpl {
|
|
|
1951
2049
|
const untrackedValue = trackSignal(() => this.$didInitialize$
|
|
1952
2050
|
? update?.(currentValue) || currentValue
|
|
1953
2051
|
: deserialize(currentValue), this, "." /* EffectProperty.VNODE */, this.$container$);
|
|
2052
|
+
this.$didInitialize$ = true;
|
|
2053
|
+
// We allow forcing the update of the signal without changing the value, for example when the deserialized value is the same reference as the old value but its internals have changed. In that case we want to trigger effects that depend on this signal, even though the value is the same.
|
|
1954
2054
|
const didChange = (this.$didInitialize$ && untrackedValue !== 'undefined') ||
|
|
1955
2055
|
untrackedValue !== this.$untrackedValue$;
|
|
1956
|
-
this.$flags$ &= -2 /* SignalFlags.INVALID */;
|
|
1957
|
-
this.$didInitialize$ = true;
|
|
1958
2056
|
if (didChange) {
|
|
1959
|
-
this.$flags$ |= 2 /* SignalFlags.RUN_EFFECTS */;
|
|
1960
2057
|
this.$untrackedValue$ = untrackedValue;
|
|
2058
|
+
scheduleEffects(this.$container$, this, this.$effects$);
|
|
1961
2059
|
}
|
|
1962
2060
|
}
|
|
1963
2061
|
}
|
|
@@ -1972,7 +2070,7 @@ const createComputedSignal = (qrl, options) => {
|
|
|
1972
2070
|
};
|
|
1973
2071
|
/** @internal */
|
|
1974
2072
|
const createAsyncSignal = (qrl, options) => {
|
|
1975
|
-
return new AsyncSignalImpl(options?.container || null, qrl, getComputedSignalFlags(options?.serializationStrategy || '
|
|
2073
|
+
return new AsyncSignalImpl(options?.container || null, qrl, getComputedSignalFlags(options?.serializationStrategy || 'always'), options);
|
|
1976
2074
|
};
|
|
1977
2075
|
/** @internal */
|
|
1978
2076
|
const createSerializerSignal = (arg) => {
|
|
@@ -1994,23 +2092,18 @@ const createSignal = createSignal$1;
|
|
|
1994
2092
|
* The QRL must be a function which returns the value of the signal. The function must not have side
|
|
1995
2093
|
* effects, and it must be synchronous.
|
|
1996
2094
|
*
|
|
1997
|
-
* If you need the function to be async, use `
|
|
2095
|
+
* If you need the function to be async, use `createAsync$` instead (don't forget to use `track()`).
|
|
1998
2096
|
*
|
|
1999
2097
|
* @public
|
|
2000
2098
|
*/
|
|
2001
2099
|
const createComputed$ = /*#__PURE__*/ implicit$FirstArg(createComputedSignal);
|
|
2002
2100
|
/**
|
|
2003
|
-
* Create
|
|
2004
|
-
*
|
|
2005
|
-
* computed signal is recalculated.
|
|
2006
|
-
*
|
|
2007
|
-
* The QRL must be a function which returns the value of the signal. The function must not have side
|
|
2008
|
-
* effects, and it can be async.
|
|
2101
|
+
* Create a signal holding a `.value` which is calculated from the given async function (QRL). The
|
|
2102
|
+
* standalone version of `useAsync$`.
|
|
2009
2103
|
*
|
|
2010
2104
|
* @public
|
|
2011
2105
|
*/
|
|
2012
|
-
const createAsync$ =
|
|
2013
|
-
/*#__PURE__*/ implicit$FirstArg(createAsyncSignal);
|
|
2106
|
+
const createAsync$ = /*#__PURE__*/ implicit$FirstArg(createAsyncSignal);
|
|
2014
2107
|
/**
|
|
2015
2108
|
* Create a signal that holds a custom serializable value. See {@link useSerializer$} for more
|
|
2016
2109
|
* details.
|
|
@@ -2135,17 +2228,6 @@ class WrappedSignalImpl extends SignalImpl {
|
|
|
2135
2228
|
scheduleEffects(this.$container$, this, this.$effects$);
|
|
2136
2229
|
}
|
|
2137
2230
|
}
|
|
2138
|
-
/**
|
|
2139
|
-
* Use this to force running subscribers, for example when the calculated value has mutated but
|
|
2140
|
-
* remained the same object.
|
|
2141
|
-
*/
|
|
2142
|
-
force() {
|
|
2143
|
-
this.$flags$ |= 2 /* SignalFlags.RUN_EFFECTS */;
|
|
2144
|
-
if (this.$container$ && this.$hostElement$) {
|
|
2145
|
-
this.$container$.setHostProp(this.$hostElement$, HOST_SIGNAL, this);
|
|
2146
|
-
markVNodeDirty(this.$container$, this.$hostElement$, 16 /* ChoreBits.COMPUTE */);
|
|
2147
|
-
}
|
|
2148
|
-
}
|
|
2149
2231
|
get untrackedValue() {
|
|
2150
2232
|
this.$computeIfNeeded$();
|
|
2151
2233
|
isDev && assertFalse(this.$untrackedValue$ === NEEDS_COMPUTATION, 'Invalid state');
|
|
@@ -2243,6 +2325,11 @@ function clearAsyncSignal(producer, effect) {
|
|
|
2243
2325
|
if (pendingEffects && pendingEffects.has(effect)) {
|
|
2244
2326
|
pendingEffects.delete(effect);
|
|
2245
2327
|
}
|
|
2328
|
+
const errorEffects = producer.$errorEffects$;
|
|
2329
|
+
if (errorEffects && errorEffects.has(effect)) {
|
|
2330
|
+
errorEffects.delete(effect);
|
|
2331
|
+
}
|
|
2332
|
+
producer.$scheduleEagerCleanup$();
|
|
2246
2333
|
}
|
|
2247
2334
|
function clearStoreOrProps(producer, effect) {
|
|
2248
2335
|
const effects = producer?.$effects$;
|
|
@@ -2298,6 +2385,25 @@ function _chk(_, element) {
|
|
|
2298
2385
|
const signal = _captures[0];
|
|
2299
2386
|
signal.value = element.checked;
|
|
2300
2387
|
}
|
|
2388
|
+
/**
|
|
2389
|
+
* Resumes selected state (e.g. polling AsyncSignals) by deserializing captures. Used for
|
|
2390
|
+
* document:onQIdle to resume async signals with active polling.
|
|
2391
|
+
*
|
|
2392
|
+
* @internal
|
|
2393
|
+
*/
|
|
2394
|
+
function _res(_, element) {
|
|
2395
|
+
maybeScopeFromQL(this, element);
|
|
2396
|
+
// Captures are deserialized, signals are now resumed
|
|
2397
|
+
}
|
|
2398
|
+
|
|
2399
|
+
const isObjectEmpty = (obj) => {
|
|
2400
|
+
for (const key in obj) {
|
|
2401
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
2402
|
+
return false;
|
|
2403
|
+
}
|
|
2404
|
+
}
|
|
2405
|
+
return true;
|
|
2406
|
+
};
|
|
2301
2407
|
|
|
2302
2408
|
const _hasOwnProperty$2 = Object.prototype.hasOwnProperty;
|
|
2303
2409
|
// TODO store props as the arrays the vnodes also use?
|
|
@@ -2315,8 +2421,8 @@ class JSXNodeImpl {
|
|
|
2315
2421
|
this.children = children;
|
|
2316
2422
|
this.toSort = !!toSort;
|
|
2317
2423
|
this.key = key === null || key === undefined ? null : typeof key === 'string' ? key : '' + key;
|
|
2318
|
-
this.varProps = !varProps ||
|
|
2319
|
-
this.constProps = !constProps ||
|
|
2424
|
+
this.varProps = !varProps || isObjectEmpty(varProps) ? EMPTY_OBJ : varProps;
|
|
2425
|
+
this.constProps = !constProps || isObjectEmpty(constProps) ? null : constProps;
|
|
2320
2426
|
if (qDev && dev) {
|
|
2321
2427
|
this.dev = {
|
|
2322
2428
|
...dev,
|
|
@@ -2365,9 +2471,6 @@ const isJSXNode = (n) => {
|
|
|
2365
2471
|
return n instanceof JSXNodeImpl;
|
|
2366
2472
|
}
|
|
2367
2473
|
};
|
|
2368
|
-
const isEmpty = (obj) => {
|
|
2369
|
-
return Object.keys(obj).length === 0;
|
|
2370
|
-
};
|
|
2371
2474
|
|
|
2372
2475
|
const BIND_VALUE = 'bind:value';
|
|
2373
2476
|
const BIND_CHECKED = 'bind:checked';
|
|
@@ -2811,7 +2914,7 @@ function addUseOnEvent(jsxElement, key, value) {
|
|
|
2811
2914
|
props[key] = undefined;
|
|
2812
2915
|
}
|
|
2813
2916
|
}
|
|
2814
|
-
const getValue
|
|
2917
|
+
const getValue = (o) => o.value;
|
|
2815
2918
|
/**
|
|
2816
2919
|
* Finds the first element node in the JSX output.
|
|
2817
2920
|
*
|
|
@@ -2835,7 +2938,7 @@ function findFirstElementNode(jsx) {
|
|
|
2835
2938
|
return maybeThen(jsx, (jsx) => findFirstElementNode(jsx));
|
|
2836
2939
|
}
|
|
2837
2940
|
else if (isSignal(jsx)) {
|
|
2838
|
-
return findFirstElementNode(untrack(getValue
|
|
2941
|
+
return findFirstElementNode(untrack(getValue, jsx));
|
|
2839
2942
|
}
|
|
2840
2943
|
}
|
|
2841
2944
|
return null;
|
|
@@ -3263,6 +3366,18 @@ const createSetTextOperation = (target, text) => new SetTextOperation(target, te
|
|
|
3263
3366
|
const createInsertOrMoveOperation = (target, parent, beforeTarget) => new InsertOrMoveOperation(target, parent, beforeTarget);
|
|
3264
3367
|
const createSetAttributeOperation = (target, attrName, attrValue, scopedStyleIdPrefix = null, isSvg = false) => new SetAttributeOperation(target, attrName, attrValue, scopedStyleIdPrefix, isSvg);
|
|
3265
3368
|
|
|
3369
|
+
const cleanupDestroyable = (destroyable) => {
|
|
3370
|
+
if (destroyable.$destroy$) {
|
|
3371
|
+
try {
|
|
3372
|
+
destroyable.$destroy$();
|
|
3373
|
+
}
|
|
3374
|
+
catch (err) {
|
|
3375
|
+
logError(err);
|
|
3376
|
+
}
|
|
3377
|
+
destroyable.$destroy$ = null;
|
|
3378
|
+
}
|
|
3379
|
+
};
|
|
3380
|
+
|
|
3266
3381
|
/**
|
|
3267
3382
|
* This safely calls an event handler, handling errors and retrying on thrown Promises, and
|
|
3268
3383
|
* providing extra parameters defined on the elements as arguments (used for loop optimization)
|
|
@@ -3747,25 +3862,24 @@ function expectSlot(diffContext) {
|
|
|
3747
3862
|
)
|
|
3748
3863
|
: null;
|
|
3749
3864
|
if (vProjectedNode == null) {
|
|
3750
|
-
|
|
3751
|
-
vnode_insertBefore(diffContext.journal, diffContext.vParent, (diffContext.vNewNode = vnode_newVirtual()), diffContext.vCurrent && getInsertBefore(diffContext));
|
|
3865
|
+
diffContext.vNewNode = vnode_newVirtual();
|
|
3752
3866
|
vnode_setProp(diffContext.vNewNode, QSlot, slotNameKey);
|
|
3753
3867
|
vHost && vnode_setProp(vHost, slotNameKey, diffContext.vNewNode);
|
|
3754
3868
|
isDev &&
|
|
3755
|
-
vnode_setProp(diffContext.vNewNode, DEBUG_TYPE, "P" /* VirtualType.Projection */);
|
|
3756
|
-
|
|
3869
|
+
vnode_setProp(diffContext.vNewNode, DEBUG_TYPE, "P" /* VirtualType.Projection */); // Nothing to project, so render content of the slot.
|
|
3870
|
+
vnode_insertBefore(diffContext.journal, diffContext.vParent, diffContext.vNewNode, diffContext.vCurrent && getInsertBefore(diffContext));
|
|
3757
3871
|
return false;
|
|
3758
3872
|
}
|
|
3759
3873
|
else if (vProjectedNode === diffContext.vCurrent) ;
|
|
3760
3874
|
else {
|
|
3761
3875
|
// move from q:template to the target node
|
|
3762
3876
|
const oldParent = vProjectedNode.parent;
|
|
3763
|
-
|
|
3877
|
+
diffContext.vNewNode = vProjectedNode;
|
|
3764
3878
|
vnode_setProp(diffContext.vNewNode, QSlot, slotNameKey);
|
|
3765
3879
|
vHost && vnode_setProp(vHost, slotNameKey, diffContext.vNewNode);
|
|
3766
3880
|
isDev &&
|
|
3767
3881
|
vnode_setProp(diffContext.vNewNode, DEBUG_TYPE, "P" /* VirtualType.Projection */);
|
|
3768
|
-
|
|
3882
|
+
vnode_insertBefore(diffContext.journal, diffContext.vParent, diffContext.vNewNode, diffContext.vCurrent && getInsertBefore(diffContext));
|
|
3769
3883
|
// If we moved from a q:template and it's now empty, remove it
|
|
3770
3884
|
if (oldParent &&
|
|
3771
3885
|
vnode_isElementVNode(oldParent) &&
|
|
@@ -3942,20 +4056,34 @@ function createNewElement(diffContext, jsx, elementName, currentFile) {
|
|
|
3942
4056
|
element.setAttribute('class', diffContext.scopedStyleIdPrefix);
|
|
3943
4057
|
}
|
|
3944
4058
|
}
|
|
3945
|
-
|
|
4059
|
+
vnode_insertElementBefore(diffContext.journal, diffContext.vParent, diffContext.vNewNode, diffContext.vCurrent);
|
|
3946
4060
|
}
|
|
3947
4061
|
function registerEventHandlers(key, value, element, vnode, diffContext) {
|
|
3948
4062
|
const scopedKebabName = key.slice(2);
|
|
3949
|
-
if (
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
4063
|
+
if (Array.isArray(value)) {
|
|
4064
|
+
const arr = value;
|
|
4065
|
+
const handlers = [];
|
|
4066
|
+
for (let i = 0; i < arr.length; i++) {
|
|
4067
|
+
const item = arr[i];
|
|
4068
|
+
if (Array.isArray(item)) {
|
|
4069
|
+
for (let j = 0; j < item.length; j++) {
|
|
4070
|
+
const handler = item[j];
|
|
4071
|
+
if (handler) {
|
|
4072
|
+
handlers.push(runEventHandlerQRL.bind(null, handler));
|
|
4073
|
+
}
|
|
4074
|
+
}
|
|
4075
|
+
}
|
|
4076
|
+
else if (item) {
|
|
4077
|
+
handlers.push(runEventHandlerQRL.bind(null, item));
|
|
4078
|
+
}
|
|
3956
4079
|
}
|
|
4080
|
+
(element._qDispatch ||= {})[scopedKebabName] = handlers;
|
|
4081
|
+
}
|
|
4082
|
+
else if (value) {
|
|
4083
|
+
(element._qDispatch ||= {})[scopedKebabName] = [
|
|
4084
|
+
runEventHandlerQRL.bind(null, value),
|
|
4085
|
+
];
|
|
3957
4086
|
}
|
|
3958
|
-
(element._qDispatch ||= {})[scopedKebabName] = handlers;
|
|
3959
4087
|
// window and document events need attrs so qwik loader can find them
|
|
3960
4088
|
// TODO only do these when not already present
|
|
3961
4089
|
if (key.charAt(2) !== 'e') {
|
|
@@ -4274,13 +4402,13 @@ function expectVirtual(diffContext, type, jsxKey) {
|
|
|
4274
4402
|
}
|
|
4275
4403
|
// For fragments without a key, always create a new virtual node (ensures rerender semantics)
|
|
4276
4404
|
if (jsxKey === null || diffContext.isCreationMode) {
|
|
4277
|
-
|
|
4405
|
+
vnode_insertVirtualBefore(diffContext.journal, diffContext.vParent, (diffContext.vNewNode = vnode_newVirtual()), diffContext.vCurrent && getInsertBefore(diffContext));
|
|
4278
4406
|
diffContext.vNewNode.key = jsxKey;
|
|
4279
4407
|
isDev && vnode_setProp(diffContext.vNewNode, DEBUG_TYPE, type);
|
|
4280
4408
|
return;
|
|
4281
4409
|
}
|
|
4282
4410
|
if (moveOrCreateKeyedNode(diffContext, null, jsxKey, getSideBufferKey(null, jsxKey), diffContext.vParent, true)) {
|
|
4283
|
-
|
|
4411
|
+
vnode_insertVirtualBefore(diffContext.journal, diffContext.vParent, (diffContext.vNewNode = vnode_newVirtual()), diffContext.vCurrent && getInsertBefore(diffContext));
|
|
4284
4412
|
diffContext.vNewNode.key = jsxKey;
|
|
4285
4413
|
isDev && vnode_setProp(diffContext.vNewNode, DEBUG_TYPE, type);
|
|
4286
4414
|
}
|
|
@@ -4374,7 +4502,7 @@ function insertNewComponent(diffContext, host, componentQRL, jsxProps) {
|
|
|
4374
4502
|
if (host) {
|
|
4375
4503
|
clearAllEffects(diffContext.container, host);
|
|
4376
4504
|
}
|
|
4377
|
-
|
|
4505
|
+
vnode_insertVirtualBefore(diffContext.journal, diffContext.vParent, (diffContext.vNewNode = vnode_newVirtual()), diffContext.vCurrent && getInsertBefore(diffContext));
|
|
4378
4506
|
const jsxNode = diffContext.jsxValue;
|
|
4379
4507
|
isDev && vnode_setProp(diffContext.vNewNode, DEBUG_TYPE, "C" /* VirtualType.Component */);
|
|
4380
4508
|
vnode_setProp(diffContext.vNewNode, OnRenderProp, componentQRL);
|
|
@@ -4382,7 +4510,7 @@ function insertNewComponent(diffContext, host, componentQRL, jsxProps) {
|
|
|
4382
4510
|
diffContext.vNewNode.key = jsxNode.key;
|
|
4383
4511
|
}
|
|
4384
4512
|
function insertNewInlineComponent(diffContext) {
|
|
4385
|
-
|
|
4513
|
+
vnode_insertVirtualBefore(diffContext.journal, diffContext.vParent, (diffContext.vNewNode = vnode_newVirtual()), diffContext.vCurrent && getInsertBefore(diffContext));
|
|
4386
4514
|
const jsxNode = diffContext.jsxValue;
|
|
4387
4515
|
isDev &&
|
|
4388
4516
|
vnode_setProp(diffContext.vNewNode, DEBUG_TYPE, "I" /* VirtualType.InlineComponent */);
|
|
@@ -4402,7 +4530,7 @@ function expectText(diffContext, text) {
|
|
|
4402
4530
|
return;
|
|
4403
4531
|
}
|
|
4404
4532
|
}
|
|
4405
|
-
|
|
4533
|
+
vnode_insertElementBefore(diffContext.journal, diffContext.vParent, (diffContext.vNewNode = vnode_newText((import.meta.env.TEST ? diffContext.container.document : document).createTextNode(text), text)), diffContext.vCurrent);
|
|
4406
4534
|
}
|
|
4407
4535
|
/**
|
|
4408
4536
|
* Retrieve the key from the VNode.
|
|
@@ -4531,7 +4659,7 @@ function isPropsEmpty(props) {
|
|
|
4531
4659
|
if (!props) {
|
|
4532
4660
|
return true;
|
|
4533
4661
|
}
|
|
4534
|
-
return
|
|
4662
|
+
return isObjectEmpty(props);
|
|
4535
4663
|
}
|
|
4536
4664
|
/**
|
|
4537
4665
|
* If vnode is removed, it is necessary to release all subscriptions associated with it.
|
|
@@ -4570,7 +4698,7 @@ function cleanup(container, journal, vNode, cursorRoot = null) {
|
|
|
4570
4698
|
if (isObject(obj)) {
|
|
4571
4699
|
const objIsTask = isTask(obj);
|
|
4572
4700
|
if (objIsTask && obj.$flags$ & 1 /* TaskFlags.VISIBLE_TASK */) {
|
|
4573
|
-
obj.$flags$ |=
|
|
4701
|
+
obj.$flags$ |= 16 /* TaskFlags.NEEDS_CLEANUP */;
|
|
4574
4702
|
markVNodeDirty(container, vCursor, 64 /* ChoreBits.CLEANUP */, cursorRoot);
|
|
4575
4703
|
// don't call cleanupDestroyable yet, do it by the scheduler
|
|
4576
4704
|
continue;
|
|
@@ -4724,281 +4852,6 @@ function containsWrappedSignal(data, signal) {
|
|
|
4724
4852
|
}
|
|
4725
4853
|
return false;
|
|
4726
4854
|
}
|
|
4727
|
-
let count = 0;
|
|
4728
|
-
|
|
4729
|
-
/**
|
|
4730
|
-
* @internal
|
|
4731
|
-
* The storage provider for hooks. Each invocation increases index i. Data is stored in an array.
|
|
4732
|
-
*/
|
|
4733
|
-
const useSequentialScope = () => {
|
|
4734
|
-
const iCtx = useInvokeContext();
|
|
4735
|
-
const hostElement = iCtx.$hostElement$;
|
|
4736
|
-
const host = hostElement;
|
|
4737
|
-
let seq = iCtx.$container$.getHostProp(host, ELEMENT_SEQ);
|
|
4738
|
-
if (seq === null) {
|
|
4739
|
-
seq = [];
|
|
4740
|
-
iCtx.$container$.setHostProp(host, ELEMENT_SEQ, seq);
|
|
4741
|
-
}
|
|
4742
|
-
let seqIdx = iCtx.$container$.getHostProp(host, ELEMENT_SEQ_IDX);
|
|
4743
|
-
if (seqIdx === null) {
|
|
4744
|
-
seqIdx = 0;
|
|
4745
|
-
}
|
|
4746
|
-
iCtx.$container$.setHostProp(host, ELEMENT_SEQ_IDX, seqIdx + 1);
|
|
4747
|
-
while (seq.length <= seqIdx) {
|
|
4748
|
-
seq.push(undefined);
|
|
4749
|
-
}
|
|
4750
|
-
const set = (value) => {
|
|
4751
|
-
if (qDev && qSerialize) {
|
|
4752
|
-
verifySerializable(value);
|
|
4753
|
-
}
|
|
4754
|
-
return (seq[seqIdx] = value);
|
|
4755
|
-
};
|
|
4756
|
-
return {
|
|
4757
|
-
val: seq[seqIdx],
|
|
4758
|
-
set,
|
|
4759
|
-
i: seqIdx,
|
|
4760
|
-
iCtx,
|
|
4761
|
-
};
|
|
4762
|
-
};
|
|
4763
|
-
|
|
4764
|
-
/** @internal */
|
|
4765
|
-
const useResourceQrl = (qrl, opts) => {
|
|
4766
|
-
const { val, set, i, iCtx } = useSequentialScope();
|
|
4767
|
-
if (val != null) {
|
|
4768
|
-
return val.$state$;
|
|
4769
|
-
}
|
|
4770
|
-
assertQrl(qrl);
|
|
4771
|
-
const container = iCtx.$container$;
|
|
4772
|
-
const resource = createResourceReturn(container, opts);
|
|
4773
|
-
const el = iCtx.$hostElement$;
|
|
4774
|
-
const task = new Task(8 /* TaskFlags.DIRTY */ | 4 /* TaskFlags.RESOURCE */, i, el, qrl, resource, null);
|
|
4775
|
-
set(task);
|
|
4776
|
-
runResource(task, container, el);
|
|
4777
|
-
return resource;
|
|
4778
|
-
};
|
|
4779
|
-
// <docs markdown="../readme.md#useResource">
|
|
4780
|
-
// !!DO NOT EDIT THIS COMMENT DIRECTLY!!!
|
|
4781
|
-
// (edit ../readme.md#useResource instead and run `pnpm docs.sync`)
|
|
4782
|
-
/**
|
|
4783
|
-
* This method works like an async memoized function that runs whenever some tracked value changes
|
|
4784
|
-
* and returns some data.
|
|
4785
|
-
*
|
|
4786
|
-
* `useResource` however returns immediate a `ResourceReturn` object that contains the data and a
|
|
4787
|
-
* state that indicates if the data is available or not.
|
|
4788
|
-
*
|
|
4789
|
-
* The status can be one of the following:
|
|
4790
|
-
*
|
|
4791
|
-
* - `pending` - the data is not yet available.
|
|
4792
|
-
* - `resolved` - the data is available.
|
|
4793
|
-
* - `rejected` - the data is not available due to an error or timeout.
|
|
4794
|
-
*
|
|
4795
|
-
* Be careful when using a `try/catch` statement in `useResource$`. If you catch the error and don't
|
|
4796
|
-
* re-throw it (or a new Error), the resource status will never be `rejected`.
|
|
4797
|
-
*
|
|
4798
|
-
* ### Example
|
|
4799
|
-
*
|
|
4800
|
-
* Example showing how `useResource` to perform a fetch to request the weather, whenever the input
|
|
4801
|
-
* city name changes.
|
|
4802
|
-
*
|
|
4803
|
-
* ```tsx
|
|
4804
|
-
* const Cmp = component$(() => {
|
|
4805
|
-
* const cityS = useSignal('');
|
|
4806
|
-
*
|
|
4807
|
-
* const weatherResource = useResource$(async ({ track, cleanup }) => {
|
|
4808
|
-
* const cityName = track(cityS);
|
|
4809
|
-
* const abortController = new AbortController();
|
|
4810
|
-
* cleanup(() => abortController.abort('cleanup'));
|
|
4811
|
-
* const res = await fetch(`http://weatherdata.com?city=${cityName}`, {
|
|
4812
|
-
* signal: abortController.signal,
|
|
4813
|
-
* });
|
|
4814
|
-
* const data = await res.json();
|
|
4815
|
-
* return data as { temp: number };
|
|
4816
|
-
* });
|
|
4817
|
-
*
|
|
4818
|
-
* return (
|
|
4819
|
-
* <div>
|
|
4820
|
-
* <input name="city" bind:value={cityS} />
|
|
4821
|
-
* <Resource
|
|
4822
|
-
* value={weatherResource}
|
|
4823
|
-
* onResolved={(weather) => {
|
|
4824
|
-
* return <div>Temperature: {weather.temp}</div>;
|
|
4825
|
-
* }}
|
|
4826
|
-
* />
|
|
4827
|
-
* </div>
|
|
4828
|
-
* );
|
|
4829
|
-
* });
|
|
4830
|
-
* ```
|
|
4831
|
-
*
|
|
4832
|
-
* @public
|
|
4833
|
-
* @see Resource
|
|
4834
|
-
* @see ResourceReturn
|
|
4835
|
-
*/
|
|
4836
|
-
// </docs>
|
|
4837
|
-
const Resource = (props) => {
|
|
4838
|
-
// Resource path
|
|
4839
|
-
return _jsxSorted(Fragment, null, null, getResourceValueAsPromise(props), 0, null);
|
|
4840
|
-
};
|
|
4841
|
-
const getResolved = (resource) => resource._resolved;
|
|
4842
|
-
const getValue = (resource) => resource.value;
|
|
4843
|
-
const getLoading = (resource) => resource.loading;
|
|
4844
|
-
function getResourceValueAsPromise(props) {
|
|
4845
|
-
const resource = props.value;
|
|
4846
|
-
if (isResourceReturn(resource)) {
|
|
4847
|
-
// create a subscription for the resource._state changes
|
|
4848
|
-
const state = resource._state;
|
|
4849
|
-
const isBrowser = !isServerPlatform();
|
|
4850
|
-
if (isBrowser) {
|
|
4851
|
-
if (state === 'pending' && props.onPending) {
|
|
4852
|
-
resource.value.catch(() => { });
|
|
4853
|
-
return Promise.resolve().then(useBindInvokeContext(props.onPending));
|
|
4854
|
-
}
|
|
4855
|
-
else if (state === 'rejected' && props.onRejected) {
|
|
4856
|
-
return Promise.resolve(resource._error).then(useBindInvokeContext(props.onRejected));
|
|
4857
|
-
}
|
|
4858
|
-
else {
|
|
4859
|
-
const resolvedValue = untrack(getResolved, resource);
|
|
4860
|
-
if (resolvedValue !== undefined) {
|
|
4861
|
-
// resolved, pending without onPending prop or rejected without onRejected prop
|
|
4862
|
-
return Promise.resolve(resolvedValue).then(useBindInvokeContext(props.onResolved));
|
|
4863
|
-
}
|
|
4864
|
-
}
|
|
4865
|
-
}
|
|
4866
|
-
return untrack(getValue, resource).then(useBindInvokeContext(props.onResolved), useBindInvokeContext(props.onRejected));
|
|
4867
|
-
}
|
|
4868
|
-
else if (isPromise(resource)) {
|
|
4869
|
-
return resource.then(useBindInvokeContext(props.onResolved), useBindInvokeContext(props.onRejected));
|
|
4870
|
-
}
|
|
4871
|
-
else if (isSignal(resource)) {
|
|
4872
|
-
const value = retryOnPromise(() => resource.value);
|
|
4873
|
-
const promise = isPromise(value) ? value : Promise.resolve(value);
|
|
4874
|
-
return promise.then(useBindInvokeContext(props.onResolved));
|
|
4875
|
-
}
|
|
4876
|
-
else {
|
|
4877
|
-
return Promise.resolve(resource).then(useBindInvokeContext(props.onResolved));
|
|
4878
|
-
}
|
|
4879
|
-
}
|
|
4880
|
-
const _createResourceReturn = (opts) => {
|
|
4881
|
-
const resource = {
|
|
4882
|
-
__brand: 'resource',
|
|
4883
|
-
value: undefined,
|
|
4884
|
-
loading: !isServerPlatform(),
|
|
4885
|
-
_resolved: undefined,
|
|
4886
|
-
_error: undefined,
|
|
4887
|
-
_state: 'pending',
|
|
4888
|
-
_timeout: opts?.timeout ?? -1,
|
|
4889
|
-
_cache: 0,
|
|
4890
|
-
_generation: 0,
|
|
4891
|
-
};
|
|
4892
|
-
return resource;
|
|
4893
|
-
};
|
|
4894
|
-
const createResourceReturn = (container, opts, initialPromise) => {
|
|
4895
|
-
const result = _createResourceReturn(opts);
|
|
4896
|
-
result.value = initialPromise;
|
|
4897
|
-
return createStore(container, result, 1 /* StoreFlags.RECURSIVE */);
|
|
4898
|
-
};
|
|
4899
|
-
const isResourceReturn = (obj) => {
|
|
4900
|
-
return isObject(obj) && (getStoreTarget(obj) || obj).__brand === 'resource';
|
|
4901
|
-
};
|
|
4902
|
-
const runResource = (task, container, host) => {
|
|
4903
|
-
task.$flags$ &= -9 /* TaskFlags.DIRTY */;
|
|
4904
|
-
cleanupDestroyable(task);
|
|
4905
|
-
const iCtx = newInvokeContext(container.$locale$, host, ResourceEvent);
|
|
4906
|
-
iCtx.$container$ = container;
|
|
4907
|
-
const taskFn = task.$qrl$.getFn(iCtx, () => clearAllEffects(container, task));
|
|
4908
|
-
const resource = task.$state$;
|
|
4909
|
-
isDev &&
|
|
4910
|
-
assertDefined(resource, 'useResource: when running a resource, "task.resource" must be a defined.', task);
|
|
4911
|
-
const track = trackFn(task, container);
|
|
4912
|
-
const [cleanup, cleanups] = cleanupFn(task, (reason) => container.handleError(reason, host));
|
|
4913
|
-
const resourceTarget = unwrapStore(resource);
|
|
4914
|
-
const opts = {
|
|
4915
|
-
track,
|
|
4916
|
-
cleanup,
|
|
4917
|
-
cache(policy) {
|
|
4918
|
-
let milliseconds = 0;
|
|
4919
|
-
if (policy === 'immutable') {
|
|
4920
|
-
milliseconds = Infinity;
|
|
4921
|
-
}
|
|
4922
|
-
else {
|
|
4923
|
-
milliseconds = policy;
|
|
4924
|
-
}
|
|
4925
|
-
resource._cache = milliseconds;
|
|
4926
|
-
},
|
|
4927
|
-
previous: resourceTarget._resolved,
|
|
4928
|
-
};
|
|
4929
|
-
let resolve;
|
|
4930
|
-
let reject;
|
|
4931
|
-
let done = false;
|
|
4932
|
-
// Increment generation to track this execution
|
|
4933
|
-
const currentGeneration = ++resourceTarget._generation;
|
|
4934
|
-
const setState = (resolved, value) => {
|
|
4935
|
-
// Ignore results from outdated executions
|
|
4936
|
-
if (done || resourceTarget._generation !== currentGeneration) {
|
|
4937
|
-
return false;
|
|
4938
|
-
}
|
|
4939
|
-
done = true;
|
|
4940
|
-
if (resolved) {
|
|
4941
|
-
resourceTarget.loading = false;
|
|
4942
|
-
resourceTarget._state = 'resolved';
|
|
4943
|
-
resourceTarget._resolved = value;
|
|
4944
|
-
resourceTarget._error = undefined;
|
|
4945
|
-
resolve(value);
|
|
4946
|
-
}
|
|
4947
|
-
else {
|
|
4948
|
-
resourceTarget.loading = false;
|
|
4949
|
-
resourceTarget._state = 'rejected';
|
|
4950
|
-
resourceTarget._error = value;
|
|
4951
|
-
reject(value);
|
|
4952
|
-
}
|
|
4953
|
-
if (!isServerPlatform()) {
|
|
4954
|
-
forceStoreEffects(resource, '_state');
|
|
4955
|
-
}
|
|
4956
|
-
return true;
|
|
4957
|
-
};
|
|
4958
|
-
/**
|
|
4959
|
-
* Add cleanup to resolve the resource if we are trying to run the same resource again while the
|
|
4960
|
-
* previous one is not resolved yet. The next `runResource` run will call this cleanup
|
|
4961
|
-
*/
|
|
4962
|
-
cleanups.push(() => {
|
|
4963
|
-
if (untrack(getLoading, resource) === true) {
|
|
4964
|
-
const value = untrack(getResolved, resource);
|
|
4965
|
-
setState(true, value);
|
|
4966
|
-
}
|
|
4967
|
-
});
|
|
4968
|
-
// Execute mutation inside empty invocation
|
|
4969
|
-
// TODO: is it right? why we need to invoke inside context and trigger effects?
|
|
4970
|
-
invoke(iCtx, () => {
|
|
4971
|
-
// console.log('RESOURCE.pending: ');
|
|
4972
|
-
resource._state = 'pending';
|
|
4973
|
-
resource.loading = !isServerPlatform();
|
|
4974
|
-
resource.value = new Promise((r, re) => {
|
|
4975
|
-
resolve = r;
|
|
4976
|
-
reject = re;
|
|
4977
|
-
});
|
|
4978
|
-
});
|
|
4979
|
-
const promise = safeCall(() => taskFn(opts), (value) => {
|
|
4980
|
-
setState(true, value);
|
|
4981
|
-
}, (err) => {
|
|
4982
|
-
if (isPromise(err)) {
|
|
4983
|
-
return err.then(() => runResource(task, container, host));
|
|
4984
|
-
}
|
|
4985
|
-
else {
|
|
4986
|
-
setState(false, err);
|
|
4987
|
-
}
|
|
4988
|
-
});
|
|
4989
|
-
const timeout = resourceTarget._timeout;
|
|
4990
|
-
if (timeout > 0) {
|
|
4991
|
-
return Promise.race([
|
|
4992
|
-
promise,
|
|
4993
|
-
delay(timeout).then(() => {
|
|
4994
|
-
if (setState(false, new Error('timeout'))) {
|
|
4995
|
-
cleanupDestroyable(task);
|
|
4996
|
-
}
|
|
4997
|
-
}),
|
|
4998
|
-
]);
|
|
4999
|
-
}
|
|
5000
|
-
return promise;
|
|
5001
|
-
};
|
|
5002
4855
|
|
|
5003
4856
|
/**
|
|
5004
4857
|
* Executes tasks for a vNode if the TASKS dirty bit is set. Tasks are stored in the ELEMENT_SEQ
|
|
@@ -5030,21 +4883,16 @@ function executeTasks(vNode, container, cursorData) {
|
|
|
5030
4883
|
if (item instanceof Task) {
|
|
5031
4884
|
const task = item;
|
|
5032
4885
|
// Skip if task is not dirty
|
|
5033
|
-
if (!(task.$flags$ &
|
|
4886
|
+
if (!(task.$flags$ & 4 /* TaskFlags.DIRTY */)) {
|
|
5034
4887
|
continue;
|
|
5035
4888
|
}
|
|
5036
|
-
|
|
5037
|
-
if (task.$flags$ & 4 /* TaskFlags.RESOURCE */) {
|
|
5038
|
-
// Resources: just run, don't save promise anywhere
|
|
5039
|
-
runResource(task, container, vNode);
|
|
5040
|
-
}
|
|
5041
|
-
else if (task.$flags$ & 1 /* TaskFlags.VISIBLE_TASK */) {
|
|
4889
|
+
if (task.$flags$ & 1 /* TaskFlags.VISIBLE_TASK */) {
|
|
5042
4890
|
// VisibleTasks: store for execution after flush (don't execute now)
|
|
5043
4891
|
(cursorData.afterFlushTasks ||= []).push(task);
|
|
5044
4892
|
}
|
|
5045
4893
|
else {
|
|
5046
4894
|
// Regular tasks: chain promises only between each other
|
|
5047
|
-
const isRenderBlocking = !!(task.$flags$ &
|
|
4895
|
+
const isRenderBlocking = !!(task.$flags$ & 8 /* TaskFlags.RENDER_BLOCKING */);
|
|
5048
4896
|
const result = runTask(task, container, vNode);
|
|
5049
4897
|
if (isPromise(result)) {
|
|
5050
4898
|
if (isRenderBlocking) {
|
|
@@ -5204,8 +5052,8 @@ function executeCleanup(vNode, container) {
|
|
|
5204
5052
|
}
|
|
5205
5053
|
for (const item of elementSeq) {
|
|
5206
5054
|
if (item instanceof Task) {
|
|
5207
|
-
if (item.$flags$ &
|
|
5208
|
-
item.$flags$ &= -
|
|
5055
|
+
if (item.$flags$ & 16 /* TaskFlags.NEEDS_CLEANUP */) {
|
|
5056
|
+
item.$flags$ &= -17 /* TaskFlags.NEEDS_CLEANUP */;
|
|
5209
5057
|
const task = item;
|
|
5210
5058
|
cleanupDestroyable(task);
|
|
5211
5059
|
}
|
|
@@ -5273,8 +5121,8 @@ function _flushJournal(journal) {
|
|
|
5273
5121
|
else {
|
|
5274
5122
|
const doc = batchParent.ownerDocument || batchParent;
|
|
5275
5123
|
const fragment = doc.createDocumentFragment();
|
|
5276
|
-
for (
|
|
5277
|
-
fragment.appendChild(
|
|
5124
|
+
for (let i = 0; i < batchNodes.length; i++) {
|
|
5125
|
+
fragment.appendChild(batchNodes[i]);
|
|
5278
5126
|
}
|
|
5279
5127
|
fastInsertBefore(batchParent, fragment, batchBefore);
|
|
5280
5128
|
}
|
|
@@ -5284,7 +5132,8 @@ function _flushJournal(journal) {
|
|
|
5284
5132
|
batchSet.clear();
|
|
5285
5133
|
}
|
|
5286
5134
|
};
|
|
5287
|
-
for (
|
|
5135
|
+
for (let i = 0; i < journal.length; i++) {
|
|
5136
|
+
const operation = journal[i];
|
|
5288
5137
|
if (operation instanceof InsertOrMoveOperation) {
|
|
5289
5138
|
if (batchParent === operation.parent && batchBefore === operation.beforeTarget) {
|
|
5290
5139
|
if (!batchNodes) {
|
|
@@ -5642,12 +5491,7 @@ function finishWalk(container, cursor, cursorData, isServer) {
|
|
|
5642
5491
|
}
|
|
5643
5492
|
}
|
|
5644
5493
|
function resolveCursor(container) {
|
|
5645
|
-
|
|
5646
|
-
// or just ignore and resolve manually
|
|
5647
|
-
if (container.$cursorCount$ === 0 && container.$pausedCursorCount$ === 0) {
|
|
5648
|
-
container.$resolveRenderPromise$();
|
|
5649
|
-
container.$renderPromise$ = null;
|
|
5650
|
-
}
|
|
5494
|
+
container.$checkPendingCount$();
|
|
5651
5495
|
}
|
|
5652
5496
|
/**
|
|
5653
5497
|
* Partitions dirtyChildren array so non-projections come first, projections last. Uses in-place
|
|
@@ -5820,17 +5664,10 @@ function executeTasksChore(container, ssrNode) {
|
|
|
5820
5664
|
if (item instanceof Task) {
|
|
5821
5665
|
const task = item;
|
|
5822
5666
|
// Skip if task is not dirty
|
|
5823
|
-
if (!(task.$flags$ &
|
|
5667
|
+
if (!(task.$flags$ & 4 /* TaskFlags.DIRTY */)) {
|
|
5824
5668
|
continue;
|
|
5825
5669
|
}
|
|
5826
|
-
|
|
5827
|
-
// Check if it's a resource
|
|
5828
|
-
if (task.$flags$ & 4 /* TaskFlags.RESOURCE */) {
|
|
5829
|
-
result = runResource(task, container, ssrNode);
|
|
5830
|
-
}
|
|
5831
|
-
else {
|
|
5832
|
-
result = runTask(task, container, ssrNode);
|
|
5833
|
-
}
|
|
5670
|
+
const result = runTask(task, container, ssrNode);
|
|
5834
5671
|
promise = promise ? promise.then(() => result) : result;
|
|
5835
5672
|
}
|
|
5836
5673
|
}
|
|
@@ -6334,6 +6171,24 @@ function registerQrlHandlers(attr, key, container, element) {
|
|
|
6334
6171
|
});
|
|
6335
6172
|
(element._qDispatch ||= {})[scopedKebabName] = handlers;
|
|
6336
6173
|
}
|
|
6174
|
+
/** Walks the direct children of a parent node and calls the callback for each child. */
|
|
6175
|
+
function vnode_walkDirectChildren(journal, vParent, callback) {
|
|
6176
|
+
let vNode = vnode_getFirstChild(vParent);
|
|
6177
|
+
while (vNode) {
|
|
6178
|
+
if (vnode_isTextVNode(vNode)) {
|
|
6179
|
+
vnode_ensureTextInflated(journal, vNode);
|
|
6180
|
+
callback(vNode, vParent);
|
|
6181
|
+
}
|
|
6182
|
+
else if (vnode_isElementVNode(vNode)) {
|
|
6183
|
+
callback(vNode, vParent);
|
|
6184
|
+
}
|
|
6185
|
+
else {
|
|
6186
|
+
// for virtual nodes, we need to walk their children
|
|
6187
|
+
vnode_walkDirectChildren(journal, vNode, callback);
|
|
6188
|
+
}
|
|
6189
|
+
vNode = vNode.nextSibling;
|
|
6190
|
+
}
|
|
6191
|
+
}
|
|
6337
6192
|
/** Walks the VNode tree and materialize it using `vnode_getFirstChild`. */
|
|
6338
6193
|
function vnode_walkVNode(vNode, callback) {
|
|
6339
6194
|
let vCursor = vNode;
|
|
@@ -6383,52 +6238,15 @@ function vnode_walkVNode(vNode, callback) {
|
|
|
6383
6238
|
}
|
|
6384
6239
|
} while (true);
|
|
6385
6240
|
}
|
|
6386
|
-
function vnode_getDOMChildNodes(journal, root, isVNode = false, childNodes = []) {
|
|
6387
|
-
if (vnode_isElementOrTextVNode(root)) {
|
|
6388
|
-
if (vnode_isTextVNode(root)) {
|
|
6389
|
-
/**
|
|
6390
|
-
* If we are collecting text nodes, we need to ensure that they are inflated. If not inflated
|
|
6391
|
-
* we would return a single text node which represents many actual text nodes, or removing a
|
|
6392
|
-
* single text node would remove many text nodes.
|
|
6393
|
-
*/
|
|
6394
|
-
vnode_ensureTextInflated(journal, root);
|
|
6395
|
-
}
|
|
6396
|
-
childNodes.push(isVNode ? root : vnode_getNode(root));
|
|
6397
|
-
return childNodes;
|
|
6398
|
-
}
|
|
6399
|
-
let vNode = vnode_getFirstChild(root);
|
|
6400
|
-
while (vNode) {
|
|
6401
|
-
if (vnode_isElementVNode(vNode)) {
|
|
6402
|
-
childNodes.push(isVNode ? vNode : vnode_getNode(vNode));
|
|
6403
|
-
}
|
|
6404
|
-
else if (vnode_isTextVNode(vNode)) {
|
|
6405
|
-
/**
|
|
6406
|
-
* If we are collecting text nodes, we need to ensure that they are inflated. If not inflated
|
|
6407
|
-
* we would return a single text node which represents many actual text nodes, or removing a
|
|
6408
|
-
* single text node would remove many text nodes.
|
|
6409
|
-
*/
|
|
6410
|
-
vnode_ensureTextInflated(journal, vNode);
|
|
6411
|
-
childNodes.push(isVNode ? vNode : vnode_getNode(vNode));
|
|
6412
|
-
}
|
|
6413
|
-
else {
|
|
6414
|
-
isVNode
|
|
6415
|
-
? vnode_getDOMChildNodes(journal, vNode, true, childNodes)
|
|
6416
|
-
: vnode_getDOMChildNodes(journal, vNode, false, childNodes);
|
|
6417
|
-
}
|
|
6418
|
-
vNode = vNode.nextSibling;
|
|
6419
|
-
}
|
|
6420
|
-
return childNodes;
|
|
6421
|
-
}
|
|
6422
6241
|
function vnode_getDOMContainer(vNode) {
|
|
6423
6242
|
let cursor = vNode;
|
|
6424
6243
|
while (cursor) {
|
|
6425
6244
|
if (vnode_isElementVNode(cursor)) {
|
|
6426
|
-
|
|
6427
|
-
|
|
6428
|
-
}
|
|
6429
|
-
catch {
|
|
6245
|
+
const qContainerElement = _getQContainerElement(cursor.node);
|
|
6246
|
+
if (!qContainerElement) {
|
|
6430
6247
|
return null;
|
|
6431
6248
|
}
|
|
6249
|
+
return getDomContainerFromQContainerElement(qContainerElement);
|
|
6432
6250
|
}
|
|
6433
6251
|
cursor = cursor.parent;
|
|
6434
6252
|
}
|
|
@@ -6696,27 +6514,71 @@ const indexOfAlphanumeric = (id, length) => {
|
|
|
6696
6514
|
idx++;
|
|
6697
6515
|
}
|
|
6698
6516
|
else {
|
|
6699
|
-
return idx;
|
|
6517
|
+
return idx;
|
|
6518
|
+
}
|
|
6519
|
+
}
|
|
6520
|
+
return length;
|
|
6521
|
+
};
|
|
6522
|
+
const vnode_createErrorDiv = (journal, document, host, err) => {
|
|
6523
|
+
const errorDiv = document.createElement('errored-host');
|
|
6524
|
+
if (err && err instanceof Error) {
|
|
6525
|
+
errorDiv.props = { error: err };
|
|
6526
|
+
}
|
|
6527
|
+
errorDiv.setAttribute('q:key', '_error_');
|
|
6528
|
+
const vErrorDiv = vnode_newElement(errorDiv, 'errored-host');
|
|
6529
|
+
if (vnode_isElementOrTextVNode(host)) {
|
|
6530
|
+
vnode_insertBefore(journal, vErrorDiv, host, null);
|
|
6531
|
+
}
|
|
6532
|
+
else {
|
|
6533
|
+
// first collect all the children, we can't move them while walking the children
|
|
6534
|
+
const children = [];
|
|
6535
|
+
vnode_walkDirectChildren(journal, host, (vNode) => {
|
|
6536
|
+
children.push(vNode);
|
|
6537
|
+
});
|
|
6538
|
+
for (let i = 0; i < children.length; i++) {
|
|
6539
|
+
vnode_insertBefore(journal, vErrorDiv, children[i], null);
|
|
6540
|
+
}
|
|
6541
|
+
}
|
|
6542
|
+
return vErrorDiv;
|
|
6543
|
+
};
|
|
6544
|
+
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
6545
|
+
const vnode_insertElementBefore = (journal, parent, newChild, insertBefore) => {
|
|
6546
|
+
ensureElementOrVirtualVNode(parent);
|
|
6547
|
+
const parentIsElement = vnode_isElementVNode(parent);
|
|
6548
|
+
if (parentIsElement) {
|
|
6549
|
+
ensureMaterialized(parent);
|
|
6550
|
+
}
|
|
6551
|
+
const newChildCurrentParent = newChild.parent;
|
|
6552
|
+
if (newChild === insertBefore) {
|
|
6553
|
+
// invalid insertBefore. We can't insert before self reference
|
|
6554
|
+
// prevent infinity loop and putting self reference to next sibling
|
|
6555
|
+
if (newChildCurrentParent) {
|
|
6556
|
+
// early return, as the newChild is already in the tree and we are already in the correct position
|
|
6557
|
+
return;
|
|
6558
|
+
}
|
|
6559
|
+
else {
|
|
6560
|
+
// if the newChild is not in the tree, than we insert it at the end of the list
|
|
6561
|
+
insertBefore = null;
|
|
6700
6562
|
}
|
|
6701
6563
|
}
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
const
|
|
6705
|
-
const
|
|
6706
|
-
if (
|
|
6707
|
-
|
|
6564
|
+
vnode_unlinkFromOldParent(journal, newChildCurrentParent, parent, newChild);
|
|
6565
|
+
const childNode = newChild.node;
|
|
6566
|
+
const parentIsDeleted = parent.flags & 32 /* VNodeFlags.Deleted */;
|
|
6567
|
+
const parentNode = parentIsElement ? parent.node : vnode_getDomParent(parent, false);
|
|
6568
|
+
if (parentNode && !parentIsDeleted) {
|
|
6569
|
+
addVNodeOperation(journal, createInsertOrMoveOperation(childNode, parentNode, vnode_findInsertBefore(journal, parent, insertBefore)?.node ?? null));
|
|
6570
|
+
}
|
|
6571
|
+
// link newChild into the previous/next list
|
|
6572
|
+
vnode_connectSiblings(parent, newChild, insertBefore);
|
|
6573
|
+
if (parentIsDeleted) {
|
|
6574
|
+
// if the parent is deleted, then the new child is also deleted
|
|
6575
|
+
newChild.flags |= 32 /* VNodeFlags.Deleted */;
|
|
6708
6576
|
}
|
|
6709
|
-
errorDiv.setAttribute('q:key', '_error_');
|
|
6710
|
-
const vErrorDiv = vnode_newElement(errorDiv, 'errored-host');
|
|
6711
|
-
vnode_getDOMChildNodes(journal, host, true).forEach((child) => {
|
|
6712
|
-
vnode_insertBefore(journal, vErrorDiv, child, null);
|
|
6713
|
-
});
|
|
6714
|
-
return vErrorDiv;
|
|
6715
6577
|
};
|
|
6716
|
-
|
|
6717
|
-
const vnode_insertBefore = (journal, parent, newChild, insertBefore) => {
|
|
6578
|
+
const vnode_insertVirtualBefore = (journal, parent, newChild, insertBefore) => {
|
|
6718
6579
|
ensureElementOrVirtualVNode(parent);
|
|
6719
|
-
|
|
6580
|
+
const parentIsElement = vnode_isElementVNode(parent);
|
|
6581
|
+
if (parentIsElement) {
|
|
6720
6582
|
ensureMaterialized(parent);
|
|
6721
6583
|
}
|
|
6722
6584
|
const newChildCurrentParent = newChild.parent;
|
|
@@ -6732,32 +6594,106 @@ const vnode_insertBefore = (journal, parent, newChild, insertBefore) => {
|
|
|
6732
6594
|
insertBefore = null;
|
|
6733
6595
|
}
|
|
6734
6596
|
}
|
|
6735
|
-
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
|
|
6740
|
-
|
|
6741
|
-
|
|
6742
|
-
|
|
6743
|
-
|
|
6744
|
-
|
|
6745
|
-
|
|
6746
|
-
|
|
6747
|
-
|
|
6748
|
-
|
|
6749
|
-
|
|
6750
|
-
|
|
6751
|
-
|
|
6752
|
-
|
|
6753
|
-
|
|
6754
|
-
|
|
6755
|
-
|
|
6756
|
-
|
|
6757
|
-
|
|
6758
|
-
|
|
6759
|
-
|
|
6597
|
+
vnode_unlinkFromOldParent(journal, newChildCurrentParent, parent, newChild);
|
|
6598
|
+
const parentIsDeleted = parent.flags & 32 /* VNodeFlags.Deleted */;
|
|
6599
|
+
const domParentVNode = parentIsElement ? parent : vnode_getDomParentVNode(parent, false);
|
|
6600
|
+
const parentNode = domParentVNode?.node;
|
|
6601
|
+
const adjustedInsertBefore = vnode_findInsertBefore(journal, parent, insertBefore);
|
|
6602
|
+
const adjustedInsertBeforeNode = adjustedInsertBefore?.node ?? null;
|
|
6603
|
+
const isProjection = vnode_isProjection(newChild);
|
|
6604
|
+
if (isProjection && domParentVNode && (domParentVNode.flags & 1536 /* VNodeFlags.NAMESPACE_MASK */) !== 0) {
|
|
6605
|
+
const domParentVNode = vnode_getDomParentVNode(parent, false);
|
|
6606
|
+
const adjustedInsertBeforeNode = vnode_findInsertBefore(journal, parent, insertBefore)?.node ?? null;
|
|
6607
|
+
/**
|
|
6608
|
+
* Find the parent node and the dom children with the correct namespaces before we unlink the
|
|
6609
|
+
* previous node. If we don't do this, we will end up with situations where we inflate text
|
|
6610
|
+
* nodes from shared text node not correctly.
|
|
6611
|
+
*
|
|
6612
|
+
* Example:
|
|
6613
|
+
*
|
|
6614
|
+
* ```
|
|
6615
|
+
* <Component>
|
|
6616
|
+
* <Projection>a</Projection>
|
|
6617
|
+
* <Projection>b</Projection>
|
|
6618
|
+
* </Component>
|
|
6619
|
+
* ```
|
|
6620
|
+
*
|
|
6621
|
+
* Projection nodes are virtual nodes, so they don't have a dom parent. They will be written to
|
|
6622
|
+
* the q:template element if not visible at the start. Inside the q:template element, the
|
|
6623
|
+
* projection nodes will be streamed as single text node "ab". We need to split it, but if we
|
|
6624
|
+
* unlink the previous or next sibling, we don't know that after "a" node is "b". So we need to
|
|
6625
|
+
* find children first (and inflate them).
|
|
6626
|
+
*/
|
|
6627
|
+
const { elementNamespace, elementNamespaceFlag } = getNewElementNamespaceData(domParentVNode, newChild);
|
|
6628
|
+
vnode_walkDirectChildren(journal, newChild, (vNode) => {
|
|
6629
|
+
if (vnode_isTextVNode(vNode)) {
|
|
6630
|
+
addVNodeOperation(journal, createInsertOrMoveOperation(vNode.node, parentNode, adjustedInsertBeforeNode));
|
|
6631
|
+
}
|
|
6632
|
+
else {
|
|
6633
|
+
if ((vNode.flags & 1536 /* VNodeFlags.NAMESPACE_MASK */) !== elementNamespaceFlag) {
|
|
6634
|
+
const newChildElement = vnode_cloneElementWithNamespace(vNode, domParentVNode, elementNamespace, elementNamespaceFlag);
|
|
6635
|
+
if (newChildElement) {
|
|
6636
|
+
vNode.node = newChildElement;
|
|
6637
|
+
}
|
|
6638
|
+
}
|
|
6639
|
+
addVNodeOperation(journal, createInsertOrMoveOperation(vNode.node, parentNode, adjustedInsertBeforeNode));
|
|
6640
|
+
}
|
|
6641
|
+
});
|
|
6642
|
+
}
|
|
6643
|
+
else if (
|
|
6644
|
+
// for projection there can be no parent node
|
|
6645
|
+
parentNode &&
|
|
6646
|
+
!parentIsDeleted) {
|
|
6647
|
+
vnode_walkDirectChildren(journal, newChild, (vNode) => {
|
|
6648
|
+
addVNodeOperation(journal, createInsertOrMoveOperation(vNode.node, parentNode, adjustedInsertBeforeNode));
|
|
6649
|
+
});
|
|
6650
|
+
}
|
|
6651
|
+
vnode_connectSiblings(parent, newChild, insertBefore);
|
|
6652
|
+
if (parentIsDeleted) {
|
|
6653
|
+
// if the parent is deleted, then the new child is also deleted
|
|
6654
|
+
newChild.flags |= 32 /* VNodeFlags.Deleted */;
|
|
6655
|
+
}
|
|
6656
|
+
};
|
|
6657
|
+
const vnode_findInsertBefore = (journal, parent, insertBefore) => {
|
|
6658
|
+
let adjustedInsertBefore = null;
|
|
6659
|
+
if (insertBefore == null) {
|
|
6660
|
+
if (vnode_isVirtualVNode(parent)) {
|
|
6661
|
+
// If `insertBefore` is null, than we need to insert at the end of the list.
|
|
6662
|
+
// Well, not quite. If the parent is a virtual node, our "last node" is not the same
|
|
6663
|
+
// as the DOM "last node". So in that case we need to look for the "next node" from
|
|
6664
|
+
// our parent.
|
|
6665
|
+
adjustedInsertBefore = vnode_getDomSibling(parent, true, false);
|
|
6666
|
+
}
|
|
6667
|
+
}
|
|
6668
|
+
else if (vnode_isVirtualVNode(insertBefore)) {
|
|
6669
|
+
// If the `insertBefore` is virtual, than we need to descend into the virtual and find e actual
|
|
6670
|
+
adjustedInsertBefore = vnode_getDomSibling(insertBefore, true, true);
|
|
6671
|
+
}
|
|
6672
|
+
else {
|
|
6673
|
+
adjustedInsertBefore = insertBefore;
|
|
6674
|
+
}
|
|
6675
|
+
adjustedInsertBefore && vnode_ensureInflatedIfText(journal, adjustedInsertBefore);
|
|
6676
|
+
return adjustedInsertBefore;
|
|
6677
|
+
};
|
|
6678
|
+
const vnode_connectSiblings = (parent, vNode, vNext) => {
|
|
6679
|
+
const vPrevious = vNext ? vNext.previousSibling : parent.lastChild;
|
|
6680
|
+
if (vNext) {
|
|
6681
|
+
vNext.previousSibling = vNode;
|
|
6682
|
+
}
|
|
6683
|
+
else {
|
|
6684
|
+
parent.lastChild = vNode;
|
|
6685
|
+
}
|
|
6686
|
+
if (vPrevious) {
|
|
6687
|
+
vPrevious.nextSibling = vNode;
|
|
6688
|
+
}
|
|
6689
|
+
else {
|
|
6690
|
+
parent.firstChild = vNode;
|
|
6760
6691
|
}
|
|
6692
|
+
vNode.previousSibling = vPrevious;
|
|
6693
|
+
vNode.nextSibling = vNext;
|
|
6694
|
+
vNode.parent = parent;
|
|
6695
|
+
};
|
|
6696
|
+
const vnode_unlinkFromOldParent = (journal, currentParent, newParent, newChild) => {
|
|
6761
6697
|
/**
|
|
6762
6698
|
* Ensure that the previous node is unlinked.
|
|
6763
6699
|
*
|
|
@@ -6795,58 +6731,17 @@ const vnode_insertBefore = (journal, parent, newChild, insertBefore) => {
|
|
|
6795
6731
|
* <p>Test content</p> // <-- to remove
|
|
6796
6732
|
* ```
|
|
6797
6733
|
*/
|
|
6798
|
-
if (
|
|
6799
|
-
(newChild.previousSibling || newChild.nextSibling ||
|
|
6800
|
-
vnode_remove(journal,
|
|
6801
|
-
}
|
|
6802
|
-
const parentIsDeleted = parent.flags & 32 /* VNodeFlags.Deleted */;
|
|
6803
|
-
let adjustedInsertBefore = null;
|
|
6804
|
-
// if the parent is deleted, then we don't need to insert the new child
|
|
6805
|
-
if (!parentIsDeleted) {
|
|
6806
|
-
if (insertBefore == null) {
|
|
6807
|
-
if (vnode_isVirtualVNode(parent)) {
|
|
6808
|
-
// If `insertBefore` is null, than we need to insert at the end of the list.
|
|
6809
|
-
// Well, not quite. If the parent is a virtual node, our "last node" is not the same
|
|
6810
|
-
// as the DOM "last node". So in that case we need to look for the "next node" from
|
|
6811
|
-
// our parent.
|
|
6812
|
-
adjustedInsertBefore = vnode_getDomSibling(parent, true, false);
|
|
6813
|
-
}
|
|
6814
|
-
}
|
|
6815
|
-
else if (vnode_isVirtualVNode(insertBefore)) {
|
|
6816
|
-
// If the `insertBefore` is virtual, than we need to descend into the virtual and find e actual
|
|
6817
|
-
adjustedInsertBefore = vnode_getDomSibling(insertBefore, true, true);
|
|
6818
|
-
}
|
|
6819
|
-
else {
|
|
6820
|
-
adjustedInsertBefore = insertBefore;
|
|
6821
|
-
}
|
|
6822
|
-
adjustedInsertBefore && vnode_ensureInflatedIfText(journal, adjustedInsertBefore);
|
|
6823
|
-
if (domChildren && domChildren.length) {
|
|
6824
|
-
for (const child of domChildren) {
|
|
6825
|
-
addVNodeOperation(journal, createInsertOrMoveOperation(child.node, parentNode, vnode_getNode(adjustedInsertBefore)));
|
|
6826
|
-
}
|
|
6827
|
-
}
|
|
6828
|
-
}
|
|
6829
|
-
// link newChild into the previous/next list
|
|
6830
|
-
const vNext = insertBefore;
|
|
6831
|
-
const vPrevious = vNext ? vNext.previousSibling : parent.lastChild;
|
|
6832
|
-
if (vNext) {
|
|
6833
|
-
vNext.previousSibling = newChild;
|
|
6734
|
+
if (currentParent &&
|
|
6735
|
+
(newChild.previousSibling || newChild.nextSibling || currentParent !== newParent)) {
|
|
6736
|
+
vnode_remove(journal, currentParent, newChild, false);
|
|
6834
6737
|
}
|
|
6835
|
-
|
|
6836
|
-
|
|
6837
|
-
|
|
6838
|
-
|
|
6839
|
-
vPrevious.nextSibling = newChild;
|
|
6738
|
+
};
|
|
6739
|
+
const vnode_insertBefore = (journal, parent, newChild, insertBefore) => {
|
|
6740
|
+
if (vnode_isElementOrTextVNode(newChild)) {
|
|
6741
|
+
vnode_insertElementBefore(journal, parent, newChild, insertBefore);
|
|
6840
6742
|
}
|
|
6841
6743
|
else {
|
|
6842
|
-
parent
|
|
6843
|
-
}
|
|
6844
|
-
newChild.previousSibling = vPrevious;
|
|
6845
|
-
newChild.nextSibling = vNext;
|
|
6846
|
-
newChild.parent = parent;
|
|
6847
|
-
if (parentIsDeleted) {
|
|
6848
|
-
// if the parent is deleted, then the new child is also deleted
|
|
6849
|
-
newChild.flags |= 32 /* VNodeFlags.Deleted */;
|
|
6744
|
+
vnode_insertVirtualBefore(journal, parent, newChild, insertBefore);
|
|
6850
6745
|
}
|
|
6851
6746
|
};
|
|
6852
6747
|
const vnode_getDomParent = (vnode, includeProjection) => {
|
|
@@ -6865,18 +6760,18 @@ const vnode_remove = (journal, vParent, vToRemove, removeDOM) => {
|
|
|
6865
6760
|
vnode_ensureTextInflated(journal, vToRemove);
|
|
6866
6761
|
}
|
|
6867
6762
|
if (removeDOM) {
|
|
6868
|
-
const domParent = vnode_getDomParent(vParent, false);
|
|
6869
6763
|
const isInnerHTMLParent = vnode_getProp(vParent, dangerouslySetInnerHTML, null) !== null;
|
|
6870
6764
|
if (isInnerHTMLParent) {
|
|
6871
6765
|
// ignore children, as they are inserted via innerHTML
|
|
6872
6766
|
return;
|
|
6873
6767
|
}
|
|
6874
|
-
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
6768
|
+
if (vnode_isElementOrTextVNode(vToRemove)) {
|
|
6769
|
+
addVNodeOperation(journal, createDeleteOperation(vToRemove.node));
|
|
6770
|
+
}
|
|
6771
|
+
else {
|
|
6772
|
+
vnode_walkDirectChildren(journal, vToRemove, (vNode) => {
|
|
6773
|
+
addVNodeOperation(journal, createDeleteOperation(vNode.node));
|
|
6774
|
+
});
|
|
6880
6775
|
}
|
|
6881
6776
|
}
|
|
6882
6777
|
const vPrevious = vToRemove.previousSibling;
|
|
@@ -6900,16 +6795,13 @@ const vnode_truncate = (journal, vParent, vDelete, removeDOM = true) => {
|
|
|
6900
6795
|
isDev && assertDefined(vDelete, 'Missing vDelete.');
|
|
6901
6796
|
const parent = vnode_getDomParent(vParent, true);
|
|
6902
6797
|
if (parent && removeDOM) {
|
|
6903
|
-
if (
|
|
6798
|
+
if (vnode_isElementOrTextVNode(vParent)) {
|
|
6904
6799
|
addVNodeOperation(journal, createRemoveAllChildrenOperation(vParent.node));
|
|
6905
6800
|
}
|
|
6906
6801
|
else {
|
|
6907
|
-
|
|
6908
|
-
|
|
6909
|
-
|
|
6910
|
-
addVNodeOperation(journal, createDeleteOperation(child.node));
|
|
6911
|
-
}
|
|
6912
|
-
}
|
|
6802
|
+
vnode_walkDirectChildren(journal, vParent, (vNode) => {
|
|
6803
|
+
addVNodeOperation(journal, createDeleteOperation(vNode.node));
|
|
6804
|
+
});
|
|
6913
6805
|
}
|
|
6914
6806
|
}
|
|
6915
6807
|
const vPrevious = vDelete.previousSibling;
|
|
@@ -7284,7 +7176,7 @@ const vnode_getAttrKeys = (container, vnode) => {
|
|
|
7284
7176
|
const keys = [];
|
|
7285
7177
|
const props = vnode.props;
|
|
7286
7178
|
if (props) {
|
|
7287
|
-
for (const key
|
|
7179
|
+
for (const key in props) {
|
|
7288
7180
|
if (!key.startsWith(Q_PROPS_SEPARATOR)) {
|
|
7289
7181
|
keys.push(key);
|
|
7290
7182
|
}
|
|
@@ -7314,7 +7206,15 @@ const vnode_getNode = (vnode) => {
|
|
|
7314
7206
|
return vnode.node;
|
|
7315
7207
|
};
|
|
7316
7208
|
/** @internal */
|
|
7317
|
-
function vnode_toString(depth = 20, offset = '', materialize = false, siblings = false, colorize = true, container =
|
|
7209
|
+
function vnode_toString(depth = 20, offset = '', materialize = false, siblings = false, colorize = true, container = null) {
|
|
7210
|
+
if (this && !container) {
|
|
7211
|
+
try {
|
|
7212
|
+
container = vnode_getDOMContainer(this);
|
|
7213
|
+
}
|
|
7214
|
+
catch {
|
|
7215
|
+
// ignore, as this is only for debugging
|
|
7216
|
+
}
|
|
7217
|
+
}
|
|
7318
7218
|
let vnode = this;
|
|
7319
7219
|
if (depth === 0) {
|
|
7320
7220
|
return '...';
|
|
@@ -7338,12 +7238,14 @@ function vnode_toString(depth = 20, offset = '', materialize = false, siblings =
|
|
|
7338
7238
|
if (vnode.dirty) {
|
|
7339
7239
|
attrs.push(` dirty:${vnode.dirty}`);
|
|
7340
7240
|
}
|
|
7341
|
-
|
|
7342
|
-
|
|
7343
|
-
|
|
7344
|
-
|
|
7345
|
-
|
|
7346
|
-
|
|
7241
|
+
if (container) {
|
|
7242
|
+
vnode_getAttrKeys(container, vnode).forEach((key) => {
|
|
7243
|
+
if (key !== DEBUG_TYPE && key !== debugStyleScopeIdPrefixAttr) {
|
|
7244
|
+
const value = vnode_getProp(vnode, key, null);
|
|
7245
|
+
attrs.push(' ' + key + '=' + qwikDebugToString(value));
|
|
7246
|
+
}
|
|
7247
|
+
});
|
|
7248
|
+
}
|
|
7347
7249
|
const name = (colorize ? NAME_COL_PREFIX : '') +
|
|
7348
7250
|
(VirtualTypeName[vnode_getProp(vnode, DEBUG_TYPE, null) || "V" /* VirtualType.Virtual */] ||
|
|
7349
7251
|
VirtualTypeName["V" /* VirtualType.Virtual */]) +
|
|
@@ -7366,7 +7268,7 @@ function vnode_toString(depth = 20, offset = '', materialize = false, siblings =
|
|
|
7366
7268
|
if (vnode.dirtyChildren) {
|
|
7367
7269
|
attrs.push(` dirtyChildren[${vnode.dirtyChildren.length}]`);
|
|
7368
7270
|
}
|
|
7369
|
-
const keys = vnode_getAttrKeys(container, vnode);
|
|
7271
|
+
const keys = container ? vnode_getAttrKeys(container, vnode) : [];
|
|
7370
7272
|
for (const key of keys) {
|
|
7371
7273
|
const value = vnode_getProp(vnode, key, null);
|
|
7372
7274
|
attrs.push(' ' + key + '=' + qwikDebugToString(value));
|
|
@@ -7566,8 +7468,8 @@ function materializeFromVNodeData(vParent, vData, element, child) {
|
|
|
7566
7468
|
if (!container) {
|
|
7567
7469
|
container = getDomContainer(element);
|
|
7568
7470
|
}
|
|
7569
|
-
for (
|
|
7570
|
-
container.ensureProjectionResolved(
|
|
7471
|
+
for (let i = 0; i < components.length; i++) {
|
|
7472
|
+
container.ensureProjectionResolved(components[i]);
|
|
7571
7473
|
}
|
|
7572
7474
|
components = null;
|
|
7573
7475
|
}
|
|
@@ -7723,15 +7625,6 @@ const useInvokeContext = () => {
|
|
|
7723
7625
|
isDev && assertDefined(ctx.$effectSubscriber$, `invoke: $effectSubscriber$ must be defined`, ctx);
|
|
7724
7626
|
return ctx;
|
|
7725
7627
|
};
|
|
7726
|
-
function useBindInvokeContext(fn) {
|
|
7727
|
-
if (fn == null) {
|
|
7728
|
-
return fn;
|
|
7729
|
-
}
|
|
7730
|
-
const ctx = getInvokeContext();
|
|
7731
|
-
return function (...args) {
|
|
7732
|
-
return (invokeApply).call(this, ctx, fn, args);
|
|
7733
|
-
};
|
|
7734
|
-
}
|
|
7735
7628
|
/** Call a function with the given InvokeContext and given arguments. */
|
|
7736
7629
|
function invoke(context, fn, ...args) {
|
|
7737
7630
|
return invokeApply.call(this, context, fn, args);
|
|
@@ -7831,7 +7724,7 @@ const trackSignal = (fn, subscriber, property, container, data) => {
|
|
|
7831
7724
|
try {
|
|
7832
7725
|
trackInvocation.$effectSubscriber$ = getSubscriber(subscriber, property, data);
|
|
7833
7726
|
trackInvocation.$container$ = container;
|
|
7834
|
-
return
|
|
7727
|
+
return invokeApply(trackInvocation, fn);
|
|
7835
7728
|
}
|
|
7836
7729
|
finally {
|
|
7837
7730
|
trackInvocation.$effectSubscriber$ = previousSubscriber;
|
|
@@ -7875,6 +7768,41 @@ const _waitUntilRendered = (container) => {
|
|
|
7875
7768
|
return container.$renderPromise$ || Promise.resolve();
|
|
7876
7769
|
};
|
|
7877
7770
|
|
|
7771
|
+
/**
|
|
7772
|
+
* @internal
|
|
7773
|
+
* The storage provider for hooks. Each invocation increases index i. Data is stored in an array.
|
|
7774
|
+
*/
|
|
7775
|
+
const useSequentialScope = () => {
|
|
7776
|
+
const iCtx = useInvokeContext();
|
|
7777
|
+
const hostElement = iCtx.$hostElement$;
|
|
7778
|
+
const host = hostElement;
|
|
7779
|
+
let seq = iCtx.$container$.getHostProp(host, ELEMENT_SEQ);
|
|
7780
|
+
if (seq === null) {
|
|
7781
|
+
seq = [];
|
|
7782
|
+
iCtx.$container$.setHostProp(host, ELEMENT_SEQ, seq);
|
|
7783
|
+
}
|
|
7784
|
+
let seqIdx = iCtx.$container$.getHostProp(host, ELEMENT_SEQ_IDX);
|
|
7785
|
+
if (seqIdx === null) {
|
|
7786
|
+
seqIdx = 0;
|
|
7787
|
+
}
|
|
7788
|
+
iCtx.$container$.setHostProp(host, ELEMENT_SEQ_IDX, seqIdx + 1);
|
|
7789
|
+
while (seq.length <= seqIdx) {
|
|
7790
|
+
seq.push(undefined);
|
|
7791
|
+
}
|
|
7792
|
+
const set = (value) => {
|
|
7793
|
+
if (qDev && qSerialize) {
|
|
7794
|
+
verifySerializable(value);
|
|
7795
|
+
}
|
|
7796
|
+
return (seq[seqIdx] = value);
|
|
7797
|
+
};
|
|
7798
|
+
return {
|
|
7799
|
+
val: seq[seqIdx],
|
|
7800
|
+
set,
|
|
7801
|
+
i: seqIdx,
|
|
7802
|
+
iCtx,
|
|
7803
|
+
};
|
|
7804
|
+
};
|
|
7805
|
+
|
|
7878
7806
|
// <docs markdown="../readme.md#createContextId">
|
|
7879
7807
|
// !!DO NOT EDIT THIS COMMENT DIRECTLY!!!
|
|
7880
7808
|
// (edit ../readme.md#createContextId instead and run `pnpm docs.sync`)
|
|
@@ -8165,7 +8093,6 @@ const _typeIdNames = [
|
|
|
8165
8093
|
'Map',
|
|
8166
8094
|
'Uint8Array',
|
|
8167
8095
|
'Task',
|
|
8168
|
-
'Resource',
|
|
8169
8096
|
'Component',
|
|
8170
8097
|
'Signal',
|
|
8171
8098
|
'WrappedSignal',
|
|
@@ -8300,13 +8227,6 @@ const allocate = (container, typeId, value) => {
|
|
|
8300
8227
|
}
|
|
8301
8228
|
case 20 /* TypeIds.Task */:
|
|
8302
8229
|
return new Task(-1, -1, null, null, null, null);
|
|
8303
|
-
case 21 /* TypeIds.Resource */: {
|
|
8304
|
-
const res = createResourceReturn(container,
|
|
8305
|
-
// we don't care about the timeout value
|
|
8306
|
-
undefined, undefined);
|
|
8307
|
-
res.loading = false;
|
|
8308
|
-
return res;
|
|
8309
|
-
}
|
|
8310
8230
|
case 6 /* TypeIds.URL */:
|
|
8311
8231
|
return new URL(value);
|
|
8312
8232
|
case 7 /* TypeIds.Date */:
|
|
@@ -8316,19 +8236,19 @@ const allocate = (container, typeId, value) => {
|
|
|
8316
8236
|
return new RegExp(value.slice(1, idx), value.slice(idx + 1));
|
|
8317
8237
|
case 15 /* TypeIds.Error */:
|
|
8318
8238
|
return new Error();
|
|
8319
|
-
case
|
|
8239
|
+
case 21 /* TypeIds.Component */:
|
|
8320
8240
|
return componentQrl(null);
|
|
8321
|
-
case
|
|
8241
|
+
case 22 /* TypeIds.Signal */:
|
|
8322
8242
|
return new SignalImpl(container, 0);
|
|
8323
|
-
case
|
|
8243
|
+
case 23 /* TypeIds.WrappedSignal */:
|
|
8324
8244
|
return new WrappedSignalImpl(container, null, null, null);
|
|
8325
|
-
case
|
|
8245
|
+
case 24 /* TypeIds.ComputedSignal */:
|
|
8326
8246
|
return new ComputedSignalImpl(container, null);
|
|
8327
|
-
case
|
|
8328
|
-
return new AsyncSignalImpl(container, null);
|
|
8329
|
-
case
|
|
8247
|
+
case 25 /* TypeIds.AsyncSignal */:
|
|
8248
|
+
return new AsyncSignalImpl(container, null, undefined, { interval: 0 });
|
|
8249
|
+
case 26 /* TypeIds.SerializerSignal */:
|
|
8330
8250
|
return new SerializerSignalImpl(container, null);
|
|
8331
|
-
case
|
|
8251
|
+
case 27 /* TypeIds.Store */: {
|
|
8332
8252
|
const data = value;
|
|
8333
8253
|
// We need to allocate the store first, before we inflate its data, because the data can
|
|
8334
8254
|
// reference the store itself (circular)
|
|
@@ -8347,9 +8267,9 @@ const allocate = (container, typeId, value) => {
|
|
|
8347
8267
|
}
|
|
8348
8268
|
case 13 /* TypeIds.URLSearchParams */:
|
|
8349
8269
|
return new URLSearchParams(value);
|
|
8350
|
-
case
|
|
8270
|
+
case 28 /* TypeIds.FormData */:
|
|
8351
8271
|
return new FormData();
|
|
8352
|
-
case
|
|
8272
|
+
case 29 /* TypeIds.JSXNode */:
|
|
8353
8273
|
return new JSXNodeImpl(null, null, null, null, null);
|
|
8354
8274
|
case 12 /* TypeIds.BigInt */:
|
|
8355
8275
|
return BigInt(value);
|
|
@@ -8374,7 +8294,7 @@ const allocate = (container, typeId, value) => {
|
|
|
8374
8294
|
const rest = encodedLength & 3;
|
|
8375
8295
|
const decodedLength = blocks * 3 + (rest ? rest - 1 : 0);
|
|
8376
8296
|
return new Uint8Array(decodedLength);
|
|
8377
|
-
case
|
|
8297
|
+
case 30 /* TypeIds.PropsProxy */:
|
|
8378
8298
|
return createPropsProxy(null);
|
|
8379
8299
|
case 10 /* TypeIds.VNode */:
|
|
8380
8300
|
return retrieveVNodeOrDocument(container, value);
|
|
@@ -8412,9 +8332,9 @@ const allocate = (container, typeId, value) => {
|
|
|
8412
8332
|
else {
|
|
8413
8333
|
throw qError(17 /* QError.serializeErrorExpectedVNode */, [typeof vNode]);
|
|
8414
8334
|
}
|
|
8415
|
-
case
|
|
8335
|
+
case 31 /* TypeIds.SubscriptionData */:
|
|
8416
8336
|
return new SubscriptionData({});
|
|
8417
|
-
case
|
|
8337
|
+
case 32 /* TypeIds.EffectSubscription */:
|
|
8418
8338
|
return new EffectSubscription(null, null, null, null);
|
|
8419
8339
|
default:
|
|
8420
8340
|
throw qError(18 /* QError.serializeErrorCannotAllocate */, [typeId]);
|
|
@@ -8759,7 +8679,7 @@ async function serialize(serializationContext) {
|
|
|
8759
8679
|
else if (isQwikComponent(value)) {
|
|
8760
8680
|
const [qrl] = value[SERIALIZABLE_STATE];
|
|
8761
8681
|
serializationContext.$renderSymbols$.add(qrl.$symbol$);
|
|
8762
|
-
output(
|
|
8682
|
+
output(21 /* TypeIds.Component */, [qrl]);
|
|
8763
8683
|
}
|
|
8764
8684
|
else {
|
|
8765
8685
|
throw qError(34 /* QError.serializeErrorCannotSerializeFunction */, [value.toString()]);
|
|
@@ -8797,7 +8717,7 @@ async function serialize(serializationContext) {
|
|
|
8797
8717
|
const writeObjectValue = (value) => {
|
|
8798
8718
|
if (isPropsProxy(value)) {
|
|
8799
8719
|
const owner = value[_OWNER];
|
|
8800
|
-
output(
|
|
8720
|
+
output(30 /* TypeIds.PropsProxy */, [
|
|
8801
8721
|
_serializationWeakRef(owner),
|
|
8802
8722
|
owner.varProps,
|
|
8803
8723
|
owner.constProps,
|
|
@@ -8805,10 +8725,10 @@ async function serialize(serializationContext) {
|
|
|
8805
8725
|
]);
|
|
8806
8726
|
}
|
|
8807
8727
|
else if (value instanceof SubscriptionData) {
|
|
8808
|
-
output(
|
|
8728
|
+
output(31 /* TypeIds.SubscriptionData */, [value.data.$scopedStyleIdPrefix$, value.data.$isConst$]);
|
|
8809
8729
|
}
|
|
8810
8730
|
else if (value instanceof EffectSubscription) {
|
|
8811
|
-
output(
|
|
8731
|
+
output(32 /* TypeIds.EffectSubscription */, [
|
|
8812
8732
|
value.consumer,
|
|
8813
8733
|
value.property,
|
|
8814
8734
|
value.backRef,
|
|
@@ -8816,41 +8736,30 @@ async function serialize(serializationContext) {
|
|
|
8816
8736
|
]);
|
|
8817
8737
|
}
|
|
8818
8738
|
else if (isStore(value)) {
|
|
8819
|
-
|
|
8820
|
-
|
|
8821
|
-
|
|
8822
|
-
|
|
8823
|
-
|
|
8824
|
-
|
|
8825
|
-
|
|
8826
|
-
|
|
8827
|
-
|
|
8828
|
-
|
|
8829
|
-
|
|
8830
|
-
|
|
8831
|
-
|
|
8832
|
-
|
|
8833
|
-
|
|
8834
|
-
|
|
8835
|
-
for (const prop in storeTarget) {
|
|
8836
|
-
const propValue = storeTarget[prop];
|
|
8837
|
-
const innerStore = $storeProxyMap$.get(propValue);
|
|
8838
|
-
if (innerStore) {
|
|
8839
|
-
innerStores.push(innerStore);
|
|
8840
|
-
}
|
|
8841
|
-
}
|
|
8842
|
-
const out = [storeTarget, flags, effects, ...innerStores];
|
|
8843
|
-
while (out[out.length - 1] === undefined) {
|
|
8844
|
-
out.pop();
|
|
8845
|
-
}
|
|
8846
|
-
output(28 /* TypeIds.Store */, out);
|
|
8739
|
+
const storeHandler = getStoreHandler(value);
|
|
8740
|
+
const storeTarget = getStoreTarget(value);
|
|
8741
|
+
const flags = storeHandler.$flags$;
|
|
8742
|
+
const effects = storeHandler.$effects$;
|
|
8743
|
+
// We need to retain the nested stores too, they won't be found from the target
|
|
8744
|
+
const innerStores = [];
|
|
8745
|
+
for (const prop in storeTarget) {
|
|
8746
|
+
const propValue = storeTarget[prop];
|
|
8747
|
+
const innerStore = $storeProxyMap$.get(propValue);
|
|
8748
|
+
if (innerStore) {
|
|
8749
|
+
innerStores.push(innerStore);
|
|
8750
|
+
}
|
|
8751
|
+
}
|
|
8752
|
+
const out = [storeTarget, flags, effects, ...innerStores];
|
|
8753
|
+
while (out[out.length - 1] === undefined) {
|
|
8754
|
+
out.pop();
|
|
8847
8755
|
}
|
|
8756
|
+
output(27 /* TypeIds.Store */, out);
|
|
8848
8757
|
}
|
|
8849
8758
|
else if (isSerializerObj(value)) {
|
|
8850
8759
|
const result = value[SerializerSymbol](value);
|
|
8851
8760
|
if (isPromise(result)) {
|
|
8852
8761
|
const forwardRef = resolvePromise(result, $addRoot$, (resolved, resolvedValue) => {
|
|
8853
|
-
return new PromiseResult(
|
|
8762
|
+
return new PromiseResult(26 /* TypeIds.SerializerSignal */, resolved, resolvedValue, undefined, undefined);
|
|
8854
8763
|
});
|
|
8855
8764
|
output(2 /* TypeIds.ForwardRef */, forwardRef);
|
|
8856
8765
|
}
|
|
@@ -8887,12 +8796,12 @@ async function serialize(serializationContext) {
|
|
|
8887
8796
|
const maybeValue = getCustomSerializerPromise(value, value.$untrackedValue$);
|
|
8888
8797
|
if (isPromise(maybeValue)) {
|
|
8889
8798
|
const forwardRefId = resolvePromise(maybeValue, $addRoot$, (resolved, resolvedValue) => {
|
|
8890
|
-
return new PromiseResult(
|
|
8799
|
+
return new PromiseResult(26 /* TypeIds.SerializerSignal */, resolved, resolvedValue, value.$effects$, value.$computeQrl$);
|
|
8891
8800
|
});
|
|
8892
8801
|
output(2 /* TypeIds.ForwardRef */, forwardRefId);
|
|
8893
8802
|
}
|
|
8894
8803
|
else {
|
|
8895
|
-
output(
|
|
8804
|
+
output(26 /* TypeIds.SerializerSignal */, [
|
|
8896
8805
|
value.$computeQrl$,
|
|
8897
8806
|
filterEffectBackRefs(value[_EFFECT_BACK_REF]),
|
|
8898
8807
|
value.$effects$,
|
|
@@ -8902,7 +8811,7 @@ async function serialize(serializationContext) {
|
|
|
8902
8811
|
return;
|
|
8903
8812
|
}
|
|
8904
8813
|
if (value instanceof WrappedSignalImpl) {
|
|
8905
|
-
output(
|
|
8814
|
+
output(23 /* TypeIds.WrappedSignal */, [
|
|
8906
8815
|
...serializeWrappingFn(serializationContext, value),
|
|
8907
8816
|
filterEffectBackRefs(value[_EFFECT_BACK_REF]),
|
|
8908
8817
|
value.$flags$,
|
|
@@ -8916,28 +8825,36 @@ async function serialize(serializationContext) {
|
|
|
8916
8825
|
const shouldNeverSerialize = value.$flags$ & 8 /* SerializationSignalFlags.SERIALIZATION_STRATEGY_NEVER */;
|
|
8917
8826
|
const isInvalid = value.$flags$ & 1 /* SignalFlags.INVALID */;
|
|
8918
8827
|
const isSkippable = fastSkipSerialize(value.$untrackedValue$);
|
|
8919
|
-
|
|
8828
|
+
const isAsync = value instanceof AsyncSignalImpl;
|
|
8829
|
+
const interval = isAsync && value.$interval$ > 0 ? value.$interval$ : undefined;
|
|
8830
|
+
const concurrency = isAsync && value.$concurrency$ !== 1 ? value.$concurrency$ : undefined;
|
|
8831
|
+
const timeout = isAsync && value.$timeoutMs$ !== 0 ? value.$timeoutMs$ : undefined;
|
|
8832
|
+
const eagerCleanup = isAsync && value.$flags$ & 32 /* AsyncSignalFlags.EAGER_CLEANUP */ ? true : undefined;
|
|
8833
|
+
if (isInvalid || isSkippable) {
|
|
8834
|
+
v = NEEDS_COMPUTATION;
|
|
8835
|
+
}
|
|
8836
|
+
else if (shouldAlwaysSerialize) {
|
|
8920
8837
|
v = value.$untrackedValue$;
|
|
8921
8838
|
}
|
|
8922
8839
|
else if (shouldNeverSerialize) {
|
|
8923
8840
|
v = NEEDS_COMPUTATION;
|
|
8924
8841
|
}
|
|
8925
|
-
else if (isInvalid || isSkippable) {
|
|
8926
|
-
v = NEEDS_COMPUTATION;
|
|
8927
|
-
}
|
|
8928
8842
|
const out = [
|
|
8929
8843
|
value.$computeQrl$,
|
|
8930
8844
|
filterEffectBackRefs(value[_EFFECT_BACK_REF]),
|
|
8931
8845
|
value.$effects$,
|
|
8932
8846
|
];
|
|
8933
|
-
const isAsync = value instanceof AsyncSignalImpl;
|
|
8934
8847
|
if (isAsync) {
|
|
8935
|
-
|
|
8848
|
+
// After SSR, the signal is never loading, so no need to send it
|
|
8849
|
+
out.push(value.$loadingEffects$, value.$errorEffects$, value.$untrackedError$);
|
|
8936
8850
|
}
|
|
8937
8851
|
let keepUndefined = false;
|
|
8938
|
-
if (v !== NEEDS_COMPUTATION
|
|
8852
|
+
if (v !== NEEDS_COMPUTATION ||
|
|
8853
|
+
interval !== undefined ||
|
|
8854
|
+
concurrency !== undefined ||
|
|
8855
|
+
timeout !== undefined) {
|
|
8939
8856
|
out.push(v);
|
|
8940
|
-
if (
|
|
8857
|
+
if (v === undefined) {
|
|
8941
8858
|
/**
|
|
8942
8859
|
* If value is undefined, we need to keep it in the output. If we don't do that, later
|
|
8943
8860
|
* during resuming, the value will be set to symbol(invalid) with flag invalid, and
|
|
@@ -8946,7 +8863,13 @@ async function serialize(serializationContext) {
|
|
|
8946
8863
|
keepUndefined = true;
|
|
8947
8864
|
}
|
|
8948
8865
|
}
|
|
8949
|
-
|
|
8866
|
+
if (isAsync) {
|
|
8867
|
+
out.push(interval);
|
|
8868
|
+
out.push(concurrency);
|
|
8869
|
+
out.push(timeout);
|
|
8870
|
+
out.push(eagerCleanup);
|
|
8871
|
+
}
|
|
8872
|
+
output(isAsync ? 25 /* TypeIds.AsyncSignal */ : 24 /* TypeIds.ComputedSignal */, out, keepUndefined);
|
|
8950
8873
|
}
|
|
8951
8874
|
else {
|
|
8952
8875
|
const v = value.$untrackedValue$;
|
|
@@ -8955,7 +8878,7 @@ async function serialize(serializationContext) {
|
|
|
8955
8878
|
if (value.$effects$) {
|
|
8956
8879
|
out.push(...value.$effects$);
|
|
8957
8880
|
}
|
|
8958
|
-
output(
|
|
8881
|
+
output(22 /* TypeIds.Signal */, out, keepUndefined);
|
|
8959
8882
|
}
|
|
8960
8883
|
}
|
|
8961
8884
|
else if (value instanceof URL) {
|
|
@@ -9017,7 +8940,7 @@ async function serialize(serializationContext) {
|
|
|
9017
8940
|
array.push(key, value.name);
|
|
9018
8941
|
}
|
|
9019
8942
|
});
|
|
9020
|
-
output(
|
|
8943
|
+
output(28 /* TypeIds.FormData */, array);
|
|
9021
8944
|
}
|
|
9022
8945
|
else if (value instanceof URLSearchParams) {
|
|
9023
8946
|
output(13 /* TypeIds.URLSearchParams */, value.toString());
|
|
@@ -9044,7 +8967,7 @@ async function serialize(serializationContext) {
|
|
|
9044
8967
|
while (out[out.length - 1] === undefined) {
|
|
9045
8968
|
out.pop();
|
|
9046
8969
|
}
|
|
9047
|
-
output(
|
|
8970
|
+
output(29 /* TypeIds.JSXNode */, out);
|
|
9048
8971
|
}
|
|
9049
8972
|
else if (value instanceof Task) {
|
|
9050
8973
|
const out = [
|
|
@@ -9067,12 +8990,9 @@ async function serialize(serializationContext) {
|
|
|
9067
8990
|
output(2 /* TypeIds.ForwardRef */, forwardRefId);
|
|
9068
8991
|
}
|
|
9069
8992
|
else if (value instanceof PromiseResult) {
|
|
9070
|
-
if (value.$type$ ===
|
|
9071
|
-
output(21 /* TypeIds.Resource */, [value.$resolved$, value.$value$, value.$effects$]);
|
|
9072
|
-
}
|
|
9073
|
-
else if (value.$type$ === 27 /* TypeIds.SerializerSignal */) {
|
|
8993
|
+
if (value.$type$ === 26 /* TypeIds.SerializerSignal */) {
|
|
9074
8994
|
if (value.$qrl$) {
|
|
9075
|
-
output(
|
|
8995
|
+
output(26 /* TypeIds.SerializerSignal */, [value.$qrl$, value.$effects$, value.$value$]);
|
|
9076
8996
|
}
|
|
9077
8997
|
else if (value.$resolved$) {
|
|
9078
8998
|
// We replace ourselves with this value
|
|
@@ -9247,9 +9167,6 @@ function isObjectLiteral(obj) {
|
|
|
9247
9167
|
const prototype = Object.getPrototypeOf(obj);
|
|
9248
9168
|
return prototype == null || prototype === Object.prototype || prototype === Array.prototype;
|
|
9249
9169
|
}
|
|
9250
|
-
function isResource(value) {
|
|
9251
|
-
return '__brand' in value && value.__brand === 'resource';
|
|
9252
|
-
}
|
|
9253
9170
|
function serializeWrappingFn(serializationContext, value) {
|
|
9254
9171
|
// if value is an object then we need to wrap this in ()
|
|
9255
9172
|
if (value.$funcStr$ && value.$funcStr$[0] === '{') {
|
|
@@ -9313,6 +9230,7 @@ DomRefConstructor, symbolToChunkResolver, getProp, setProp, storeProxyMap, write
|
|
|
9313
9230
|
const syncFnMap = new Map();
|
|
9314
9231
|
const syncFns = [];
|
|
9315
9232
|
const roots = [];
|
|
9233
|
+
const eagerResume = new Set();
|
|
9316
9234
|
const getSeenRef = (obj) => seenObjsMap.get(obj);
|
|
9317
9235
|
const $markSeen$ = (obj, parent, index) => {
|
|
9318
9236
|
const ref = { $index$: index, $parent$: parent };
|
|
@@ -9408,9 +9326,10 @@ DomRefConstructor, symbolToChunkResolver, getProp, setProp, storeProxyMap, write
|
|
|
9408
9326
|
$writer$: writer,
|
|
9409
9327
|
$eventQrls$: new Set(),
|
|
9410
9328
|
$eventNames$: new Set(),
|
|
9411
|
-
$resources$: new Set(),
|
|
9412
9329
|
$renderSymbols$: new Set(),
|
|
9413
9330
|
$storeProxyMap$: storeProxyMap,
|
|
9331
|
+
$eagerResume$: eagerResume,
|
|
9332
|
+
$resources$: new Set(),
|
|
9414
9333
|
$getProp$: getProp,
|
|
9415
9334
|
$setProp$: setProp,
|
|
9416
9335
|
};
|
|
@@ -9430,8 +9349,7 @@ class _SharedContainer {
|
|
|
9430
9349
|
$buildBase$ = null;
|
|
9431
9350
|
$renderPromise$ = null;
|
|
9432
9351
|
$resolveRenderPromise$ = null;
|
|
9433
|
-
$
|
|
9434
|
-
$pausedCursorCount$ = 0;
|
|
9352
|
+
$pendingCount$ = 0;
|
|
9435
9353
|
constructor(serverData, locale) {
|
|
9436
9354
|
this.$serverData$ = serverData;
|
|
9437
9355
|
this.$locale$ = locale;
|
|
@@ -9447,6 +9365,12 @@ class _SharedContainer {
|
|
|
9447
9365
|
serializationCtxFactory(NodeConstructor, DomRefConstructor, symbolToChunkResolver, writer) {
|
|
9448
9366
|
return createSerializationContext(NodeConstructor, DomRefConstructor, symbolToChunkResolver, this.getHostProp.bind(this), this.setHostProp.bind(this), this.$storeProxyMap$, writer);
|
|
9449
9367
|
}
|
|
9368
|
+
$checkPendingCount$() {
|
|
9369
|
+
if (this.$pendingCount$ === 0) {
|
|
9370
|
+
this.$resolveRenderPromise$?.();
|
|
9371
|
+
this.$renderPromise$ = null;
|
|
9372
|
+
}
|
|
9373
|
+
}
|
|
9450
9374
|
}
|
|
9451
9375
|
|
|
9452
9376
|
function isAsyncGenerator(value) {
|
|
@@ -9540,6 +9464,7 @@ function processJSXNode(ssr, enqueue, value, options) {
|
|
|
9540
9464
|
}
|
|
9541
9465
|
}
|
|
9542
9466
|
else if (isSignal(value)) {
|
|
9467
|
+
maybeAddPollingAsyncSignalToEagerResume(ssr.serializationCtx, value);
|
|
9543
9468
|
ssr.openFragment(isDev ? [DEBUG_TYPE, "S" /* VirtualType.WrappedSignal */] : EMPTY_ARRAY);
|
|
9544
9469
|
const signalNode = ssr.getOrCreateLastNode();
|
|
9545
9470
|
const unwrappedSignal = value instanceof WrappedSignalImpl ? value.$unwrapIfSignal$() : value;
|
|
@@ -9728,6 +9653,7 @@ function toSsrAttrs(record, options) {
|
|
|
9728
9653
|
return;
|
|
9729
9654
|
}
|
|
9730
9655
|
if (isSignal(value)) {
|
|
9656
|
+
maybeAddPollingAsyncSignalToEagerResume(options.serializationCtx, value);
|
|
9731
9657
|
// write signal as is. We will track this signal inside `writeAttrs`
|
|
9732
9658
|
if (isClassAttr(key)) {
|
|
9733
9659
|
// additionally append styleScopedId for class attr
|
|
@@ -9816,6 +9742,19 @@ function addPreventDefaultEventToSerializationContext(serializationCtx, key) {
|
|
|
9816
9742
|
serializationCtx.$eventNames$.add(eventName);
|
|
9817
9743
|
}
|
|
9818
9744
|
}
|
|
9745
|
+
function maybeAddPollingAsyncSignalToEagerResume(serializationCtx, signal) {
|
|
9746
|
+
// Unwrap if it's a WrappedSignalImpl
|
|
9747
|
+
const unwrappedSignal = signal instanceof WrappedSignalImpl ? signal.$unwrapIfSignal$() : signal;
|
|
9748
|
+
if (unwrappedSignal instanceof AsyncSignalImpl) {
|
|
9749
|
+
const interval = unwrappedSignal.$interval$;
|
|
9750
|
+
// Don't check for $effects$ here - effects are added later during tracking.
|
|
9751
|
+
// The AsyncSignal's polling mechanism will check for effects before scheduling.
|
|
9752
|
+
if (interval > 0) {
|
|
9753
|
+
serializationCtx.$addRoot$(unwrappedSignal);
|
|
9754
|
+
serializationCtx.$eagerResume$.add(unwrappedSignal);
|
|
9755
|
+
}
|
|
9756
|
+
}
|
|
9757
|
+
}
|
|
9819
9758
|
function getSlotName(host, jsx, ssr) {
|
|
9820
9759
|
const constProps = jsx.constProps;
|
|
9821
9760
|
if (constProps && typeof constProps == 'object' && 'name' in constProps) {
|
|
@@ -9853,7 +9792,7 @@ function appendClassIfScopedStyleExists(jsx, styleScoped) {
|
|
|
9853
9792
|
* NOTE: `useLexicalScope` method can only be used in the synchronous portion of the callback
|
|
9854
9793
|
* (before any `await` statements.)
|
|
9855
9794
|
*
|
|
9856
|
-
* @deprecated
|
|
9795
|
+
* @deprecated Use `_captures` instead.
|
|
9857
9796
|
* @internal
|
|
9858
9797
|
*/
|
|
9859
9798
|
// </docs>
|
|
@@ -9862,6 +9801,117 @@ const useLexicalScope = () => {
|
|
|
9862
9801
|
return _captures;
|
|
9863
9802
|
};
|
|
9864
9803
|
|
|
9804
|
+
/**
|
|
9805
|
+
* The resource function wrapper
|
|
9806
|
+
*
|
|
9807
|
+
* @internal
|
|
9808
|
+
*/
|
|
9809
|
+
const _rsc = async (arg) => {
|
|
9810
|
+
const [fn, ref] = _captures;
|
|
9811
|
+
const result = await fn(arg);
|
|
9812
|
+
if (result && typeof result === 'object') {
|
|
9813
|
+
if (ref.r) {
|
|
9814
|
+
Object.assign(ref.r, result);
|
|
9815
|
+
}
|
|
9816
|
+
else {
|
|
9817
|
+
// We need lazy creation because we don't know if it will be an array or an object, and we want to preserve the original reference for reactivity to work
|
|
9818
|
+
ref.r = createStore(fn.$container$, result, 1 /* StoreFlags.RECURSIVE */);
|
|
9819
|
+
}
|
|
9820
|
+
}
|
|
9821
|
+
else {
|
|
9822
|
+
ref.r = result;
|
|
9823
|
+
}
|
|
9824
|
+
return { r: ref.r };
|
|
9825
|
+
};
|
|
9826
|
+
/** @internal */
|
|
9827
|
+
const useResourceQrl = (qrl, opts) => {
|
|
9828
|
+
assertQrl(qrl);
|
|
9829
|
+
const { val, set, iCtx } = useSequentialScope();
|
|
9830
|
+
if (val) {
|
|
9831
|
+
return val;
|
|
9832
|
+
}
|
|
9833
|
+
const ref = {};
|
|
9834
|
+
// Wrap the function so we can maintain a stable reference to the store
|
|
9835
|
+
const wrapped = createQRL(null, '_rsc', _rsc, null, [qrl, ref]);
|
|
9836
|
+
qrl.$container$ = iCtx.$container$;
|
|
9837
|
+
const asyncSignal = createAsyncSignal(wrapped, {
|
|
9838
|
+
timeout: opts?.timeout,
|
|
9839
|
+
container: iCtx.$container$,
|
|
9840
|
+
concurrency: 0,
|
|
9841
|
+
});
|
|
9842
|
+
// Resource is eager
|
|
9843
|
+
asyncSignal.$computeIfNeeded$();
|
|
9844
|
+
// Create a wrapper that presents the Promise-based ResourceReturn API
|
|
9845
|
+
const resource = {
|
|
9846
|
+
__brand: 'resource',
|
|
9847
|
+
signal: asyncSignal,
|
|
9848
|
+
get value() {
|
|
9849
|
+
return asyncSignal
|
|
9850
|
+
.promise()
|
|
9851
|
+
.then(() => (asyncSignal.error ? Promise.reject(asyncSignal.error) : asyncSignal.value.r));
|
|
9852
|
+
},
|
|
9853
|
+
get loading() {
|
|
9854
|
+
return asyncSignal.loading;
|
|
9855
|
+
},
|
|
9856
|
+
};
|
|
9857
|
+
set(resource);
|
|
9858
|
+
return resource;
|
|
9859
|
+
};
|
|
9860
|
+
/**
|
|
9861
|
+
* ```tsx
|
|
9862
|
+
* const Cmp = component$(() => {
|
|
9863
|
+
* const city = useSignal('');
|
|
9864
|
+
*
|
|
9865
|
+
* const weather = useAsync$(async ({ track, cleanup, abortSignal }) => {
|
|
9866
|
+
* const cityName = track(city);
|
|
9867
|
+
* const res = await fetch(`http://weatherdata.com?city=${cityName}`, {
|
|
9868
|
+
* signal: abortSignal,
|
|
9869
|
+
* });
|
|
9870
|
+
* const temp = (await res.json()) as { temp: number };
|
|
9871
|
+
* return temp;
|
|
9872
|
+
* });
|
|
9873
|
+
*
|
|
9874
|
+
* return (
|
|
9875
|
+
* <div>
|
|
9876
|
+
* <input name="city" bind:value={city} />
|
|
9877
|
+
* <div>
|
|
9878
|
+
* Temperature:{' '}
|
|
9879
|
+
* {weather.loading
|
|
9880
|
+
* ? 'Loading...'
|
|
9881
|
+
* : weather.error
|
|
9882
|
+
* ? `Error: ${weather.error.message}`
|
|
9883
|
+
* : weather.value.temp}
|
|
9884
|
+
* </div>
|
|
9885
|
+
* </div>
|
|
9886
|
+
* );
|
|
9887
|
+
* });
|
|
9888
|
+
* ```
|
|
9889
|
+
*
|
|
9890
|
+
* @deprecated Use `useAsync$` instead, which is more efficient, and has a more flexible API. Just
|
|
9891
|
+
* read the `loading` and `error` properties from the returned signal to determine the status.
|
|
9892
|
+
* @public
|
|
9893
|
+
*/
|
|
9894
|
+
const Resource = ({ value, onResolved, onPending, onRejected, }) => {
|
|
9895
|
+
if (isPromise(value)) {
|
|
9896
|
+
return value.then(onResolved, onRejected);
|
|
9897
|
+
}
|
|
9898
|
+
const isRes = isResourceReturn(value);
|
|
9899
|
+
const signal = isRes ? value.signal : value;
|
|
9900
|
+
if (onPending && signal.loading) {
|
|
9901
|
+
return onPending();
|
|
9902
|
+
}
|
|
9903
|
+
if (onRejected && signal.error) {
|
|
9904
|
+
return onRejected(signal.error);
|
|
9905
|
+
}
|
|
9906
|
+
const val = isRes ? signal.value?.r : signal.value;
|
|
9907
|
+
return (isPromise(val)
|
|
9908
|
+
? val.then(onResolved, onRejected)
|
|
9909
|
+
: onResolved(val));
|
|
9910
|
+
};
|
|
9911
|
+
const isResourceReturn = (obj) => {
|
|
9912
|
+
return obj && obj.__brand === 'resource';
|
|
9913
|
+
};
|
|
9914
|
+
|
|
9865
9915
|
let loading = Promise.resolve();
|
|
9866
9916
|
const inflate = (container, target, typeId, data) => {
|
|
9867
9917
|
if (typeId === 0 /* TypeIds.Plain */) {
|
|
@@ -9898,25 +9948,10 @@ const inflate = (container, target, typeId, data) => {
|
|
|
9898
9948
|
task[_EFFECT_BACK_REF] = v[4];
|
|
9899
9949
|
task.$state$ = v[5];
|
|
9900
9950
|
break;
|
|
9901
|
-
case 21 /* TypeIds.
|
|
9902
|
-
const [resolved, result, effects] = data;
|
|
9903
|
-
const resource = target;
|
|
9904
|
-
if (resolved) {
|
|
9905
|
-
resource.value = Promise.resolve(result);
|
|
9906
|
-
resource._resolved = result;
|
|
9907
|
-
resource._state = 'resolved';
|
|
9908
|
-
}
|
|
9909
|
-
else {
|
|
9910
|
-
resource.value = Promise.reject(result);
|
|
9911
|
-
resource._error = result;
|
|
9912
|
-
resource._state = 'rejected';
|
|
9913
|
-
}
|
|
9914
|
-
getStoreHandler(target).$effects$ = effects;
|
|
9915
|
-
break;
|
|
9916
|
-
case 22 /* TypeIds.Component */:
|
|
9951
|
+
case 21 /* TypeIds.Component */:
|
|
9917
9952
|
target[SERIALIZABLE_STATE][0] = data[0];
|
|
9918
9953
|
break;
|
|
9919
|
-
case
|
|
9954
|
+
case 27 /* TypeIds.Store */: {
|
|
9920
9955
|
// Inflate the store target
|
|
9921
9956
|
const store = unwrapStore(target);
|
|
9922
9957
|
const storeTarget = pendingStoreTargets.get(store);
|
|
@@ -9934,14 +9969,14 @@ const inflate = (container, target, typeId, data) => {
|
|
|
9934
9969
|
storeHandler.$effects$ = effects;
|
|
9935
9970
|
break;
|
|
9936
9971
|
}
|
|
9937
|
-
case
|
|
9972
|
+
case 22 /* TypeIds.Signal */: {
|
|
9938
9973
|
const signal = target;
|
|
9939
9974
|
const d = data;
|
|
9940
9975
|
signal.$untrackedValue$ = d[0];
|
|
9941
9976
|
signal.$effects$ = new Set(d.slice(1));
|
|
9942
9977
|
break;
|
|
9943
9978
|
}
|
|
9944
|
-
case
|
|
9979
|
+
case 23 /* TypeIds.WrappedSignal */: {
|
|
9945
9980
|
const signal = target;
|
|
9946
9981
|
const d = data;
|
|
9947
9982
|
signal.$func$ = container.getSyncFn(d[0]);
|
|
@@ -9955,7 +9990,7 @@ const inflate = (container, target, typeId, data) => {
|
|
|
9955
9990
|
inflateWrappedSignalValue(signal);
|
|
9956
9991
|
break;
|
|
9957
9992
|
}
|
|
9958
|
-
case
|
|
9993
|
+
case 25 /* TypeIds.AsyncSignal */: {
|
|
9959
9994
|
const asyncSignal = target;
|
|
9960
9995
|
const d = data;
|
|
9961
9996
|
asyncSignal.$computeQrl$ = d[0];
|
|
@@ -9963,19 +9998,27 @@ const inflate = (container, target, typeId, data) => {
|
|
|
9963
9998
|
asyncSignal.$effects$ = new Set(d[2]);
|
|
9964
9999
|
asyncSignal.$loadingEffects$ = new Set(d[3]);
|
|
9965
10000
|
asyncSignal.$errorEffects$ = new Set(d[4]);
|
|
9966
|
-
asyncSignal.$
|
|
9967
|
-
|
|
9968
|
-
const hasValue = d.length > 7;
|
|
10001
|
+
asyncSignal.$untrackedError$ = d[5];
|
|
10002
|
+
const hasValue = d.length > 6;
|
|
9969
10003
|
if (hasValue) {
|
|
9970
|
-
asyncSignal.$untrackedValue$ = d[
|
|
9971
|
-
|
|
10004
|
+
asyncSignal.$untrackedValue$ = d[6];
|
|
10005
|
+
}
|
|
10006
|
+
if (asyncSignal.$untrackedValue$ !== NEEDS_COMPUTATION) {
|
|
10007
|
+
// If we have a value after SSR, it will always be mean the signal was not invalid
|
|
10008
|
+
asyncSignal.$flags$ &= -2 /* SignalFlags.INVALID */;
|
|
10009
|
+
}
|
|
10010
|
+
// Note, we use the setter so that it schedules polling if needed
|
|
10011
|
+
asyncSignal.interval = d[7] ?? 0;
|
|
10012
|
+
asyncSignal.$concurrency$ = d[8] ?? 1;
|
|
10013
|
+
asyncSignal.$timeoutMs$ = d[9] ?? 0;
|
|
10014
|
+
if (d[10]) {
|
|
10015
|
+
asyncSignal.$flags$ |= 32 /* AsyncSignalFlags.EAGER_CLEANUP */;
|
|
9972
10016
|
}
|
|
9973
|
-
asyncSignal.$flags$ |= 1 /* SignalFlags.INVALID */;
|
|
9974
10017
|
break;
|
|
9975
10018
|
}
|
|
9976
10019
|
// Inflating a SerializerSignal is the same as inflating a ComputedSignal
|
|
9977
|
-
case
|
|
9978
|
-
case
|
|
10020
|
+
case 26 /* TypeIds.SerializerSignal */:
|
|
10021
|
+
case 24 /* TypeIds.ComputedSignal */: {
|
|
9979
10022
|
const computed = target;
|
|
9980
10023
|
const d = data;
|
|
9981
10024
|
computed.$computeQrl$ = d[0];
|
|
@@ -9995,13 +10038,11 @@ const inflate = (container, target, typeId, data) => {
|
|
|
9995
10038
|
const hasValue = d.length > 3;
|
|
9996
10039
|
if (hasValue) {
|
|
9997
10040
|
computed.$untrackedValue$ = d[3];
|
|
9998
|
-
// The serialized signal is always invalid so it can recreate the custom object
|
|
9999
|
-
if (typeId === 27 /* TypeIds.SerializerSignal */) {
|
|
10000
|
-
computed.$flags$ |= 1 /* SignalFlags.INVALID */;
|
|
10001
|
-
}
|
|
10002
10041
|
}
|
|
10003
|
-
|
|
10004
|
-
|
|
10042
|
+
if (typeId !== 26 /* TypeIds.SerializerSignal */ && computed.$untrackedValue$ !== NEEDS_COMPUTATION) {
|
|
10043
|
+
// If we have a value after SSR, it will always be mean the signal was not invalid
|
|
10044
|
+
// The serialized signal is always left invalid so it can recreate the custom object
|
|
10045
|
+
computed.$flags$ &= -2 /* SignalFlags.INVALID */;
|
|
10005
10046
|
}
|
|
10006
10047
|
break;
|
|
10007
10048
|
}
|
|
@@ -10013,7 +10054,7 @@ const inflate = (container, target, typeId, data) => {
|
|
|
10013
10054
|
}
|
|
10014
10055
|
break;
|
|
10015
10056
|
}
|
|
10016
|
-
case
|
|
10057
|
+
case 28 /* TypeIds.FormData */: {
|
|
10017
10058
|
const formData = target;
|
|
10018
10059
|
const d = data;
|
|
10019
10060
|
for (let i = 0; i < d.length; i++) {
|
|
@@ -10021,7 +10062,7 @@ const inflate = (container, target, typeId, data) => {
|
|
|
10021
10062
|
}
|
|
10022
10063
|
break;
|
|
10023
10064
|
}
|
|
10024
|
-
case
|
|
10065
|
+
case 29 /* TypeIds.JSXNode */: {
|
|
10025
10066
|
const jsx = target;
|
|
10026
10067
|
const [type, key, varProps, constProps, children, toSort] = data;
|
|
10027
10068
|
jsx.type = type;
|
|
@@ -10068,7 +10109,7 @@ const inflate = (container, target, typeId, data) => {
|
|
|
10068
10109
|
bytes[i++] = s.charCodeAt(0);
|
|
10069
10110
|
}
|
|
10070
10111
|
break;
|
|
10071
|
-
case
|
|
10112
|
+
case 30 /* TypeIds.PropsProxy */:
|
|
10072
10113
|
const propsProxy = target;
|
|
10073
10114
|
const d = data;
|
|
10074
10115
|
let owner = d[0];
|
|
@@ -10079,13 +10120,13 @@ const inflate = (container, target, typeId, data) => {
|
|
|
10079
10120
|
propsProxy[_OWNER] = owner;
|
|
10080
10121
|
propsProxy[_PROPS_HANDLER].$effects$ = d[3];
|
|
10081
10122
|
break;
|
|
10082
|
-
case
|
|
10123
|
+
case 31 /* TypeIds.SubscriptionData */: {
|
|
10083
10124
|
const effectData = target;
|
|
10084
10125
|
effectData.data.$scopedStyleIdPrefix$ = data[0];
|
|
10085
10126
|
effectData.data.$isConst$ = data[1];
|
|
10086
10127
|
break;
|
|
10087
10128
|
}
|
|
10088
|
-
case
|
|
10129
|
+
case 32 /* TypeIds.EffectSubscription */: {
|
|
10089
10130
|
const effectSub = target;
|
|
10090
10131
|
const d = data;
|
|
10091
10132
|
effectSub.consumer = d[0];
|
|
@@ -10658,7 +10699,7 @@ class DomContainer extends _SharedContainer {
|
|
|
10658
10699
|
const insertHost = vnode_isElementVNode(vHost) ? vHostParent || vHost : vHost;
|
|
10659
10700
|
// If the host is different then we need to insert errored-host in the same position as the host.
|
|
10660
10701
|
const insertBefore = insertHost === vHost ? null : vHostNextSibling;
|
|
10661
|
-
|
|
10702
|
+
vnode_insertElementBefore(journal, insertHost, vErrorDiv, insertBefore);
|
|
10662
10703
|
};
|
|
10663
10704
|
this.$renderPromise$ ? this.$renderPromise$.then(createErrorWrapper) : createErrorWrapper();
|
|
10664
10705
|
}
|
|
@@ -10808,8 +10849,8 @@ const useTaskQrl = (qrl, opts) => {
|
|
|
10808
10849
|
set(1);
|
|
10809
10850
|
const taskFlags =
|
|
10810
10851
|
// enabled by default
|
|
10811
|
-
opts?.deferUpdates === false ? 0 :
|
|
10812
|
-
const task = new Task(
|
|
10852
|
+
opts?.deferUpdates === false ? 0 : 8 /* TaskFlags.RENDER_BLOCKING */;
|
|
10853
|
+
const task = new Task(4 /* TaskFlags.DIRTY */ | 2 /* TaskFlags.TASK */ | taskFlags, i, iCtx.$hostElement$, qrl, undefined, null);
|
|
10813
10854
|
// In V2 we add the task to the sequential scope. We need to do this
|
|
10814
10855
|
// in order to be able to retrieve it later when the parent element is
|
|
10815
10856
|
// deleted and we need to be able to release the task subscriptions.
|
|
@@ -10822,7 +10863,7 @@ const useTaskQrl = (qrl, opts) => {
|
|
|
10822
10863
|
}
|
|
10823
10864
|
};
|
|
10824
10865
|
const runTask = (task, container, host) => {
|
|
10825
|
-
task.$flags$ &= -
|
|
10866
|
+
task.$flags$ &= -5 /* TaskFlags.DIRTY */;
|
|
10826
10867
|
cleanupDestroyable(task);
|
|
10827
10868
|
const iCtx = newInvokeContext(container.$locale$, host, TaskEvent);
|
|
10828
10869
|
iCtx.$container$ = container;
|
|
@@ -10873,7 +10914,7 @@ function scheduleTask(_event, element) {
|
|
|
10873
10914
|
setCaptures(deserializeCaptures(container, this));
|
|
10874
10915
|
}
|
|
10875
10916
|
const task = _captures[0];
|
|
10876
|
-
task.$flags$ |=
|
|
10917
|
+
task.$flags$ |= 4 /* TaskFlags.DIRTY */;
|
|
10877
10918
|
markVNodeDirty(container, task.$el$, 1 /* ChoreBits.TASKS */);
|
|
10878
10919
|
}
|
|
10879
10920
|
|
|
@@ -10900,7 +10941,7 @@ const ensureContainsBackRef = (array, value) => {
|
|
|
10900
10941
|
(array.backRef ||= new Set()).add(value);
|
|
10901
10942
|
};
|
|
10902
10943
|
const addQrlToSerializationCtx = (effectSubscriber, container) => {
|
|
10903
|
-
if (container) {
|
|
10944
|
+
if (container?.serializationCtx) {
|
|
10904
10945
|
const effect = effectSubscriber.consumer;
|
|
10905
10946
|
const property = effectSubscriber.property;
|
|
10906
10947
|
let qrl = null;
|
|
@@ -10926,7 +10967,7 @@ const scheduleEffects = (container, signal, effects) => {
|
|
|
10926
10967
|
const property = effectSubscription.property;
|
|
10927
10968
|
isDev && assertDefined(container, 'Container must be defined.');
|
|
10928
10969
|
if (isTask(consumer)) {
|
|
10929
|
-
consumer.$flags$ |=
|
|
10970
|
+
consumer.$flags$ |= 4 /* TaskFlags.DIRTY */;
|
|
10930
10971
|
markVNodeDirty(container, consumer.$el$, 1 /* ChoreBits.TASKS */);
|
|
10931
10972
|
}
|
|
10932
10973
|
else if (consumer instanceof SignalImpl) {
|
|
@@ -11605,14 +11646,11 @@ function preprocessState(data, container) {
|
|
|
11605
11646
|
/**
|
|
11606
11647
|
* Serialize data to string using SerializationContext.
|
|
11607
11648
|
*
|
|
11608
|
-
* @param data - Data to serialize
|
|
11609
11649
|
* @internal
|
|
11610
11650
|
*/
|
|
11611
11651
|
async function _serialize(data) {
|
|
11612
11652
|
const serializationContext = createSerializationContext(null, null, () => '', () => '', () => { }, new WeakMap());
|
|
11613
|
-
|
|
11614
|
-
serializationContext.$addRoot$(root);
|
|
11615
|
-
}
|
|
11653
|
+
serializationContext.$addRoot$(data);
|
|
11616
11654
|
await serializationContext.$serialize$();
|
|
11617
11655
|
return serializationContext.$writer$.toString();
|
|
11618
11656
|
}
|
|
@@ -11624,18 +11662,14 @@ async function _serialize(data) {
|
|
|
11624
11662
|
*/
|
|
11625
11663
|
function _deserialize(rawStateData) {
|
|
11626
11664
|
if (rawStateData == null) {
|
|
11627
|
-
|
|
11665
|
+
throw new Error('No state data to deserialize');
|
|
11628
11666
|
}
|
|
11629
11667
|
const stateData = JSON.parse(rawStateData);
|
|
11630
|
-
if (!Array.isArray(stateData)) {
|
|
11631
|
-
|
|
11668
|
+
if (!Array.isArray(stateData) || stateData.length < 2 || typeof stateData[0] !== 'number') {
|
|
11669
|
+
throw new Error('Invalid state data');
|
|
11632
11670
|
}
|
|
11633
11671
|
const container = _createDeserializeContainer(stateData);
|
|
11634
|
-
|
|
11635
|
-
for (let i = 0; i < stateData.length; i += 2) {
|
|
11636
|
-
output[i / 2] = deserializeData(container, stateData[i], stateData[i + 1]);
|
|
11637
|
-
}
|
|
11638
|
-
return output;
|
|
11672
|
+
return deserializeData(container, stateData[0], stateData[1]);
|
|
11639
11673
|
}
|
|
11640
11674
|
function getObjectById(id, stateData) {
|
|
11641
11675
|
if (typeof id === 'string') {
|
|
@@ -11709,6 +11743,10 @@ const _verifySerializable = (value, seen, ctx, preMessage) => {
|
|
|
11709
11743
|
});
|
|
11710
11744
|
return value;
|
|
11711
11745
|
}
|
|
11746
|
+
// We don't want to walk internal objects, assume we already checked the contents
|
|
11747
|
+
if (unwrapped.__brand) {
|
|
11748
|
+
return value;
|
|
11749
|
+
}
|
|
11712
11750
|
if (isSerializableObject(unwrapped)) {
|
|
11713
11751
|
for (const [key, item] of Object.entries(unwrapped)) {
|
|
11714
11752
|
_verifySerializable(item, seen, ctx + '.' + key);
|
|
@@ -13166,8 +13204,8 @@ const useVisibleTaskQrl = (qrl, opts) => {
|
|
|
13166
13204
|
const { val, set, i, iCtx } = useSequentialScope();
|
|
13167
13205
|
const eagerness = opts?.strategy ?? 'intersection-observer';
|
|
13168
13206
|
if (val) {
|
|
13169
|
-
if (!(val.$flags$ &
|
|
13170
|
-
val.$flags$ |=
|
|
13207
|
+
if (!(val.$flags$ & 32 /* TaskFlags.EVENTS_REGISTERED */) && !isServerPlatform()) {
|
|
13208
|
+
val.$flags$ |= 32 /* TaskFlags.EVENTS_REGISTERED */;
|
|
13171
13209
|
useRegisterTaskEvents(val, eagerness);
|
|
13172
13210
|
}
|
|
13173
13211
|
return;
|
|
@@ -13176,7 +13214,7 @@ const useVisibleTaskQrl = (qrl, opts) => {
|
|
|
13176
13214
|
let flags;
|
|
13177
13215
|
if (!isServerPlatform()) {
|
|
13178
13216
|
// In DOM we immediately execute
|
|
13179
|
-
flags = 1 /* TaskFlags.VISIBLE_TASK */ |
|
|
13217
|
+
flags = 1 /* TaskFlags.VISIBLE_TASK */ | 4 /* TaskFlags.DIRTY */;
|
|
13180
13218
|
qrl.resolve();
|
|
13181
13219
|
markVNodeDirty(iCtx.$container$, iCtx.$hostElement$, 1 /* ChoreBits.TASKS */);
|
|
13182
13220
|
}
|
|
@@ -13222,48 +13260,16 @@ const getTaskHandlerQrl = (task) => {
|
|
|
13222
13260
|
* Be careful when using a `try/catch` statement in `useResource$`. If you catch the error and don't
|
|
13223
13261
|
* re-throw it (or a new Error), the resource status will never be `rejected`.
|
|
13224
13262
|
*
|
|
13225
|
-
*
|
|
13226
|
-
*
|
|
13227
|
-
*
|
|
13228
|
-
* city name changes.
|
|
13229
|
-
*
|
|
13230
|
-
* ```tsx
|
|
13231
|
-
* const Cmp = component$(() => {
|
|
13232
|
-
* const cityS = useSignal('');
|
|
13233
|
-
*
|
|
13234
|
-
* const weatherResource = useResource$(async ({ track, cleanup }) => {
|
|
13235
|
-
* const cityName = track(cityS);
|
|
13236
|
-
* const abortController = new AbortController();
|
|
13237
|
-
* cleanup(() => abortController.abort('cleanup'));
|
|
13238
|
-
* const res = await fetch(`http://weatherdata.com?city=${cityName}`, {
|
|
13239
|
-
* signal: abortController.signal,
|
|
13240
|
-
* });
|
|
13241
|
-
* const data = await res.json();
|
|
13242
|
-
* return data as { temp: number };
|
|
13243
|
-
* });
|
|
13244
|
-
*
|
|
13245
|
-
* return (
|
|
13246
|
-
* <div>
|
|
13247
|
-
* <input name="city" bind:value={cityS} />
|
|
13248
|
-
* <Resource
|
|
13249
|
-
* value={weatherResource}
|
|
13250
|
-
* onResolved={(weather) => {
|
|
13251
|
-
* return <div>Temperature: {weather.temp}</div>;
|
|
13252
|
-
* }}
|
|
13253
|
-
* />
|
|
13254
|
-
* </div>
|
|
13255
|
-
* );
|
|
13256
|
-
* });
|
|
13257
|
-
* ```
|
|
13258
|
-
*
|
|
13263
|
+
* @deprecated Use `useAsync$` instead, which is more powerful and flexible. `useResource$` is still
|
|
13264
|
+
* available for backward compatibility but it is recommended to migrate to `useAsync$` for new
|
|
13265
|
+
* code and when updating existing code.
|
|
13259
13266
|
* @public
|
|
13267
|
+
* @see useAsync$
|
|
13260
13268
|
* @see Resource
|
|
13261
13269
|
* @see ResourceReturn
|
|
13262
13270
|
*/
|
|
13263
13271
|
// </docs>
|
|
13264
|
-
const useResource$ = (
|
|
13265
|
-
return useResourceQrl(dollar(generatorFn), opts);
|
|
13266
|
-
};
|
|
13272
|
+
const useResource$ = implicit$FirstArg(useResourceQrl);
|
|
13267
13273
|
|
|
13268
13274
|
// <docs markdown="../readme.md#useTask">
|
|
13269
13275
|
// !!DO NOT EDIT THIS COMMENT DIRECTLY!!!
|
|
@@ -13495,5 +13501,5 @@ if (import.meta.hot) {
|
|
|
13495
13501
|
});
|
|
13496
13502
|
}
|
|
13497
13503
|
|
|
13498
|
-
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, _IMMUTABLE, _SharedContainer, SubscriptionData as _SubscriptionData, _UNINITIALIZED, _VAR_PROPS, _captures, _chk, _deserialize, _dumpState, _executeSsrChores, _fnSignal, _getConstProps, _getContextContainer, _getContextEvent, _getContextHostElement, getDomContainer as _getDomContainer, _getQContainerElement, _getVarProps, _hasStoreEffects, 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, _regSymbol, _resolveContextWithoutSequentialScope, _restProps, _run, _serialize, scheduleTask as _task, _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 };
|
|
13504
|
+
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, _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, 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, scheduleTask as _task, _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 };
|
|
13499
13505
|
//# sourceMappingURL=core.mjs.map
|