@qwik.dev/core 2.0.0-alpha.4 → 2.0.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bindings/qwik.darwin-arm64.node +0 -0
- package/bindings/qwik.darwin-x64.node +0 -0
- package/bindings/qwik.linux-x64-gnu.node +0 -0
- package/bindings/qwik.win32-x64-msvc.node +0 -0
- package/bindings/qwik_wasm_bg.wasm +0 -0
- package/dist/build/package.json +1 -1
- package/dist/cli.cjs +2 -23
- package/dist/core-internal.d.ts +3 -3
- package/dist/core.cjs +446 -278
- package/dist/core.cjs.map +1 -1
- package/dist/core.min.mjs +1 -1
- package/dist/core.mjs +446 -278
- package/dist/core.mjs.map +1 -1
- package/dist/core.prod.cjs +406 -308
- package/dist/core.prod.mjs +493 -386
- package/dist/insights/index.qwik.cjs +8 -8
- package/dist/insights/index.qwik.mjs +8 -8
- package/dist/loader/package.json +1 -1
- package/dist/optimizer.cjs +306 -189
- package/dist/optimizer.mjs +362 -239
- package/dist/prefetch/package.json +1 -1
- package/dist/server.cjs +396 -254
- package/dist/server.mjs +395 -253
- package/dist/starters/features/turso/src/utils/turso.ts +1 -1
- package/dist/testing/index.cjs +394 -252
- package/dist/testing/index.mjs +393 -251
- package/dist/testing/package.json +1 -1
- package/package.json +3 -3
package/dist/core.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* @qwik.dev/core 2.0.0-alpha.
|
|
3
|
+
* @qwik.dev/core 2.0.0-alpha.6-dev+d848ba5
|
|
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
|
|
@@ -152,7 +152,7 @@
|
|
|
152
152
|
'SsrError(tag): {{0}}', // 29
|
|
153
153
|
'QRLs can not be resolved because it does not have an attached container. This means that the QRL does not know where it belongs inside the DOM, so it cant dynamically import() from a relative path.', // 30
|
|
154
154
|
'QRLs can not be dynamically resolved, because it does not have a chunk path', // 31
|
|
155
|
-
'
|
|
155
|
+
'{{0}}\nThe JSX ref attribute must be a Signal', // 32
|
|
156
156
|
'Serialization Error: Deserialization of data type {{0}} is not implemented', // 33
|
|
157
157
|
'Serialization Error: Expected vnode for ref prop, but got {{0}}', // 34
|
|
158
158
|
'Serialization Error: Cannot allocate data type {{0}}', // 35
|
|
@@ -160,12 +160,11 @@
|
|
|
160
160
|
'Serialization Error: Serialization of data type {{0}} is not implemented', // 37
|
|
161
161
|
'Serialization Error: Unvisited {{0}}', // 38
|
|
162
162
|
'Serialization Error: Missing QRL chunk for {{0}}', // 39
|
|
163
|
-
'
|
|
163
|
+
'{{0}}\nThe value of the textarea must be a string found {{1}}', // 40
|
|
164
164
|
'Unable to find q:container', // 41
|
|
165
165
|
"Element must have 'q:container' attribute.", // 42
|
|
166
166
|
'Unknown vnode type {{0}}.', // 43
|
|
167
167
|
'Materialize error: missing element: {{0}} {{1}} {{2}}', // 44
|
|
168
|
-
'SsrError: {{0}}', // 45
|
|
169
168
|
'Cannot coerce a Signal, use `.value` instead', // 46
|
|
170
169
|
'useComputedSignal$ QRL {{0}} {{1}} returned a Promise', // 47
|
|
171
170
|
'ComputedSignal is read-only', // 48
|
|
@@ -237,19 +236,130 @@
|
|
|
237
236
|
QError[QError["elementWithoutContainer"] = 42] = "elementWithoutContainer";
|
|
238
237
|
QError[QError["invalidVNodeType"] = 43] = "invalidVNodeType";
|
|
239
238
|
QError[QError["materializeVNodeDataError"] = 44] = "materializeVNodeDataError";
|
|
240
|
-
QError[QError["
|
|
241
|
-
QError[QError["
|
|
242
|
-
QError[QError["
|
|
243
|
-
QError[QError["
|
|
244
|
-
QError[QError["
|
|
245
|
-
QError[QError["
|
|
246
|
-
QError[QError["unsafeAttr"] = 51] = "unsafeAttr";
|
|
239
|
+
QError[QError["cannotCoerceSignal"] = 45] = "cannotCoerceSignal";
|
|
240
|
+
QError[QError["computedNotSync"] = 46] = "computedNotSync";
|
|
241
|
+
QError[QError["computedReadOnly"] = 47] = "computedReadOnly";
|
|
242
|
+
QError[QError["wrappedReadOnly"] = 48] = "wrappedReadOnly";
|
|
243
|
+
QError[QError["promisesNotExpected"] = 49] = "promisesNotExpected";
|
|
244
|
+
QError[QError["unsafeAttr"] = 50] = "unsafeAttr";
|
|
247
245
|
})(QError || (QError = {}));
|
|
248
246
|
const qError = (code, errorMessageArgs = []) => {
|
|
249
247
|
const text = codeToText(code, ...errorMessageArgs);
|
|
250
248
|
return logErrorAndStop(text, ...errorMessageArgs);
|
|
251
249
|
};
|
|
252
250
|
|
|
251
|
+
/**
|
|
252
|
+
* A friendly name tag for a VirtualVNode.
|
|
253
|
+
*
|
|
254
|
+
* Theses are used to give a name to a VirtualVNode. This is useful for debugging and testing.
|
|
255
|
+
*
|
|
256
|
+
* The name is only added in development mode and is not included in production builds.
|
|
257
|
+
*/
|
|
258
|
+
const DEBUG_TYPE = 'q:type';
|
|
259
|
+
var VirtualType;
|
|
260
|
+
(function (VirtualType) {
|
|
261
|
+
VirtualType["Virtual"] = "V";
|
|
262
|
+
VirtualType["Fragment"] = "F";
|
|
263
|
+
VirtualType["WrappedSignal"] = "S";
|
|
264
|
+
VirtualType["Awaited"] = "A";
|
|
265
|
+
VirtualType["Component"] = "C";
|
|
266
|
+
VirtualType["InlineComponent"] = "I";
|
|
267
|
+
VirtualType["Projection"] = "P";
|
|
268
|
+
})(VirtualType || (VirtualType = {}));
|
|
269
|
+
const START = '\x1b[34m';
|
|
270
|
+
const END = '\x1b[0m';
|
|
271
|
+
const VirtualTypeName = {
|
|
272
|
+
[VirtualType.Virtual]: /* ********* */ START + 'Virtual' + END, //
|
|
273
|
+
[VirtualType.Fragment]: /* ******** */ START + 'Fragment' + END, //
|
|
274
|
+
[VirtualType.WrappedSignal]: /* *** */ START + 'Signal' + END, //
|
|
275
|
+
[VirtualType.Awaited]: /* ********* */ START + 'Awaited' + END, //
|
|
276
|
+
[VirtualType.Component]: /* ******* */ START + 'Component' + END, //
|
|
277
|
+
[VirtualType.InlineComponent]: /* * */ START + 'InlineComponent' + END, //
|
|
278
|
+
[VirtualType.Projection]: /* ****** */ START + 'Projection' + END, //
|
|
279
|
+
};
|
|
280
|
+
var QContainerValue;
|
|
281
|
+
(function (QContainerValue) {
|
|
282
|
+
QContainerValue["PAUSED"] = "paused";
|
|
283
|
+
QContainerValue["RESUMED"] = "resumed";
|
|
284
|
+
// these values below are used in the qwik loader as a plain text for the q:container selector
|
|
285
|
+
// standard dangerouslySetInnerHTML
|
|
286
|
+
QContainerValue["HTML"] = "html";
|
|
287
|
+
// textarea
|
|
288
|
+
QContainerValue["TEXT"] = "text";
|
|
289
|
+
})(QContainerValue || (QContainerValue = {}));
|
|
290
|
+
|
|
291
|
+
/** State factory of the component. */
|
|
292
|
+
const OnRenderProp = 'q:renderFn';
|
|
293
|
+
/** Component style content prefix */
|
|
294
|
+
const ComponentStylesPrefixContent = '⭐️';
|
|
295
|
+
/** `<some-element q:slot="...">` */
|
|
296
|
+
const QSlot = 'q:slot';
|
|
297
|
+
const QSlotParent = ':';
|
|
298
|
+
const QSlotRef = 'q:sref';
|
|
299
|
+
const QSlotS = 'q:s';
|
|
300
|
+
const QStyle = 'q:style';
|
|
301
|
+
const QStyleSelector = 'style[q\\:style]';
|
|
302
|
+
const QStyleSSelector = 'style[q\\:sstyle]';
|
|
303
|
+
const QStylesAllSelector = QStyleSelector + ',' + QStyleSSelector;
|
|
304
|
+
const QScopedStyle = 'q:sstyle';
|
|
305
|
+
const QCtxAttr = 'q:ctx';
|
|
306
|
+
const QSubscribers = 'q:subs';
|
|
307
|
+
const QFuncsPrefix = 'qFuncs_';
|
|
308
|
+
const getQFuncs = (document, hash) => {
|
|
309
|
+
return document[QFuncsPrefix + hash] || [];
|
|
310
|
+
};
|
|
311
|
+
const QBaseAttr = 'q:base';
|
|
312
|
+
const QLocaleAttr = 'q:locale';
|
|
313
|
+
const QManifestHashAttr = 'q:manifest-hash';
|
|
314
|
+
const QInstanceAttr = 'q:instance';
|
|
315
|
+
const QContainerIsland = 'q:container-island';
|
|
316
|
+
const QContainerIslandEnd = '/' + QContainerIsland;
|
|
317
|
+
const QIgnore = 'q:ignore';
|
|
318
|
+
const QIgnoreEnd = '/' + QIgnore;
|
|
319
|
+
const QContainerAttr = 'q:container';
|
|
320
|
+
const QContainerAttrEnd = '/' + QContainerAttr;
|
|
321
|
+
const QTemplate = 'q:template';
|
|
322
|
+
// the same selector should be inside the qwik loader
|
|
323
|
+
// and the same selector should be inside the qwik router spa-shim and spa-init
|
|
324
|
+
const QContainerSelector = '[q\\:container]:not([q\\:container=' +
|
|
325
|
+
QContainerValue.HTML +
|
|
326
|
+
']):not([q\\:container=' +
|
|
327
|
+
QContainerValue.TEXT +
|
|
328
|
+
'])';
|
|
329
|
+
const HTML_NS = 'http://www.w3.org/1999/xhtml';
|
|
330
|
+
const SVG_NS = 'http://www.w3.org/2000/svg';
|
|
331
|
+
const MATH_NS = 'http://www.w3.org/1998/Math/MathML';
|
|
332
|
+
const ResourceEvent = 'qResource';
|
|
333
|
+
const RenderEvent = 'qRender';
|
|
334
|
+
const TaskEvent = 'qTask';
|
|
335
|
+
const QDefaultSlot = '';
|
|
336
|
+
/**
|
|
337
|
+
* Attribute to mark that this VNode has a pointer to itself from the `qwik/json` state.
|
|
338
|
+
*
|
|
339
|
+
* As the VNode get materialized the vnode now becomes eligible for mutation. Once the vnode mutates
|
|
340
|
+
* the `VNode` references from the `qwik/json` may become invalid. For this reason, these references
|
|
341
|
+
* need to be eagerly resolved. `VNODE_REF` stores a pointer to "this" vnode. This allows the system
|
|
342
|
+
* to eagerly resolve these pointes as the vnodes are materialized.
|
|
343
|
+
*/
|
|
344
|
+
const ELEMENT_ID = 'q:id';
|
|
345
|
+
const ELEMENT_KEY = 'q:key';
|
|
346
|
+
const ELEMENT_PROPS = 'q:props';
|
|
347
|
+
const ELEMENT_SEQ = 'q:seq';
|
|
348
|
+
const ELEMENT_SEQ_IDX = 'q:seqIdx';
|
|
349
|
+
const Q_PREFIX = 'q:';
|
|
350
|
+
/** Non serializable markers - always begins with `:` character */
|
|
351
|
+
const NON_SERIALIZABLE_MARKER_PREFIX = ':';
|
|
352
|
+
const USE_ON_LOCAL = NON_SERIALIZABLE_MARKER_PREFIX + 'on';
|
|
353
|
+
const USE_ON_LOCAL_SEQ_IDX = NON_SERIALIZABLE_MARKER_PREFIX + 'onIdx';
|
|
354
|
+
const USE_ON_LOCAL_FLAGS = NON_SERIALIZABLE_MARKER_PREFIX + 'onFlags';
|
|
355
|
+
// comment nodes
|
|
356
|
+
const FLUSH_COMMENT = 'qkssr-f';
|
|
357
|
+
const STREAM_BLOCK_START_COMMENT = 'qkssr-pu';
|
|
358
|
+
const STREAM_BLOCK_END_COMMENT = 'qkssr-po';
|
|
359
|
+
const Q_PROPS_SEPARATOR = ':';
|
|
360
|
+
const dangerouslySetInnerHTML = 'dangerouslySetInnerHTML';
|
|
361
|
+
const qwikInspectorAttr = 'data-qwik-inspector';
|
|
362
|
+
|
|
253
363
|
// keep this import from core/build so the cjs build works
|
|
254
364
|
const createPlatform = () => {
|
|
255
365
|
return {
|
|
@@ -310,7 +420,7 @@
|
|
|
310
420
|
*/
|
|
311
421
|
const toUrl = (doc, containerEl, url) => {
|
|
312
422
|
const baseURI = doc.baseURI;
|
|
313
|
-
const base = new URL(containerEl.getAttribute(
|
|
423
|
+
const base = new URL(containerEl.getAttribute(QBaseAttr) ?? baseURI, baseURI);
|
|
314
424
|
return new URL(url, base);
|
|
315
425
|
};
|
|
316
426
|
let _platform = /*#__PURE__ */ createPlatform();
|
|
@@ -402,15 +512,24 @@
|
|
|
402
512
|
setTimeout(resolve, timeout);
|
|
403
513
|
});
|
|
404
514
|
};
|
|
515
|
+
// Retries a function that throws a promise.
|
|
405
516
|
function retryOnPromise(fn, retryCount = 0) {
|
|
406
|
-
|
|
407
|
-
return fn();
|
|
408
|
-
}
|
|
409
|
-
catch (e) {
|
|
517
|
+
const retryOrThrow = (e) => {
|
|
410
518
|
if (isPromise(e) && retryCount < MAX_RETRY_ON_PROMISE_COUNT) {
|
|
411
519
|
return e.then(retryOnPromise.bind(null, fn, retryCount++));
|
|
412
520
|
}
|
|
413
521
|
throw e;
|
|
522
|
+
};
|
|
523
|
+
try {
|
|
524
|
+
const result = fn();
|
|
525
|
+
if (isPromise(result)) {
|
|
526
|
+
// not awaited promise is not caught by try/catch block
|
|
527
|
+
return result.catch((e) => retryOrThrow(e));
|
|
528
|
+
}
|
|
529
|
+
return result;
|
|
530
|
+
}
|
|
531
|
+
catch (e) {
|
|
532
|
+
return retryOrThrow(e);
|
|
414
533
|
}
|
|
415
534
|
}
|
|
416
535
|
|
|
@@ -453,118 +572,6 @@
|
|
|
453
572
|
VNodeDataFlag[VNodeDataFlag["SERIALIZE"] = 16] = "SERIALIZE";
|
|
454
573
|
})(VNodeDataFlag || (VNodeDataFlag = {}));
|
|
455
574
|
|
|
456
|
-
/**
|
|
457
|
-
* A friendly name tag for a VirtualVNode.
|
|
458
|
-
*
|
|
459
|
-
* Theses are used to give a name to a VirtualVNode. This is useful for debugging and testing.
|
|
460
|
-
*
|
|
461
|
-
* The name is only added in development mode and is not included in production builds.
|
|
462
|
-
*/
|
|
463
|
-
const DEBUG_TYPE = 'q:type';
|
|
464
|
-
var VirtualType;
|
|
465
|
-
(function (VirtualType) {
|
|
466
|
-
VirtualType["Virtual"] = "V";
|
|
467
|
-
VirtualType["Fragment"] = "F";
|
|
468
|
-
VirtualType["WrappedSignal"] = "S";
|
|
469
|
-
VirtualType["Awaited"] = "A";
|
|
470
|
-
VirtualType["Component"] = "C";
|
|
471
|
-
VirtualType["InlineComponent"] = "I";
|
|
472
|
-
VirtualType["Projection"] = "P";
|
|
473
|
-
})(VirtualType || (VirtualType = {}));
|
|
474
|
-
const START = '\x1b[34m';
|
|
475
|
-
const END = '\x1b[0m';
|
|
476
|
-
const VirtualTypeName = {
|
|
477
|
-
[VirtualType.Virtual]: /* ********* */ START + 'Virtual' + END, //
|
|
478
|
-
[VirtualType.Fragment]: /* ******** */ START + 'Fragment' + END, //
|
|
479
|
-
[VirtualType.WrappedSignal]: /* *** */ START + 'Signal' + END, //
|
|
480
|
-
[VirtualType.Awaited]: /* ********* */ START + 'Awaited' + END, //
|
|
481
|
-
[VirtualType.Component]: /* ******* */ START + 'Component' + END, //
|
|
482
|
-
[VirtualType.InlineComponent]: /* * */ START + 'InlineComponent' + END, //
|
|
483
|
-
[VirtualType.Projection]: /* ****** */ START + 'Projection' + END, //
|
|
484
|
-
};
|
|
485
|
-
var QContainerValue;
|
|
486
|
-
(function (QContainerValue) {
|
|
487
|
-
QContainerValue["PAUSED"] = "paused";
|
|
488
|
-
QContainerValue["RESUMED"] = "resumed";
|
|
489
|
-
// these values below are used in the qwik loader as a plain text for the q:container selector
|
|
490
|
-
// standard dangerouslySetInnerHTML
|
|
491
|
-
QContainerValue["HTML"] = "html";
|
|
492
|
-
// textarea
|
|
493
|
-
QContainerValue["TEXT"] = "text";
|
|
494
|
-
})(QContainerValue || (QContainerValue = {}));
|
|
495
|
-
|
|
496
|
-
/** State factory of the component. */
|
|
497
|
-
const OnRenderProp = 'q:renderFn';
|
|
498
|
-
/** Component style content prefix */
|
|
499
|
-
const ComponentStylesPrefixContent = '⭐️';
|
|
500
|
-
/** `<some-element q:slot="...">` */
|
|
501
|
-
const QSlot = 'q:slot';
|
|
502
|
-
const QSlotParent = ':';
|
|
503
|
-
const QSlotRef = 'q:sref';
|
|
504
|
-
const QSlotS = 'q:s';
|
|
505
|
-
const QStyle = 'q:style';
|
|
506
|
-
const QStyleSelector = 'style[q\\:style]';
|
|
507
|
-
const QStyleSSelector = 'style[q\\:sstyle]';
|
|
508
|
-
const QStylesAllSelector = QStyleSelector + ',' + QStyleSSelector;
|
|
509
|
-
const QScopedStyle = 'q:sstyle';
|
|
510
|
-
const QCtxAttr = 'q:ctx';
|
|
511
|
-
const QSubscribers = 'q:subs';
|
|
512
|
-
const QFuncsPrefix = 'qFuncs_';
|
|
513
|
-
const getQFuncs = (document, hash) => {
|
|
514
|
-
return document[QFuncsPrefix + hash] || [];
|
|
515
|
-
};
|
|
516
|
-
const QBaseAttr = 'q:base';
|
|
517
|
-
const QLocaleAttr = 'q:locale';
|
|
518
|
-
const QManifestHashAttr = 'q:manifest-hash';
|
|
519
|
-
const QInstanceAttr = 'q:instance';
|
|
520
|
-
const QContainerIsland = 'q:container-island';
|
|
521
|
-
const QContainerIslandEnd = '/' + QContainerIsland;
|
|
522
|
-
const QIgnore = 'q:ignore';
|
|
523
|
-
const QIgnoreEnd = '/' + QIgnore;
|
|
524
|
-
const QContainerAttr = 'q:container';
|
|
525
|
-
const QContainerAttrEnd = '/' + QContainerAttr;
|
|
526
|
-
const QTemplate = 'q:template';
|
|
527
|
-
// the same selector should be inside the qwik loader
|
|
528
|
-
// and the same selector should be inside the qwik router spa-shim and spa-init
|
|
529
|
-
const QContainerSelector = '[q\\:container]:not([q\\:container=' +
|
|
530
|
-
QContainerValue.HTML +
|
|
531
|
-
']):not([q\\:container=' +
|
|
532
|
-
QContainerValue.TEXT +
|
|
533
|
-
'])';
|
|
534
|
-
const HTML_NS = 'http://www.w3.org/1999/xhtml';
|
|
535
|
-
const SVG_NS = 'http://www.w3.org/2000/svg';
|
|
536
|
-
const MATH_NS = 'http://www.w3.org/1998/Math/MathML';
|
|
537
|
-
const ResourceEvent = 'qResource';
|
|
538
|
-
const RenderEvent = 'qRender';
|
|
539
|
-
const TaskEvent = 'qTask';
|
|
540
|
-
const QDefaultSlot = '';
|
|
541
|
-
/**
|
|
542
|
-
* Attribute to mark that this VNode has a pointer to itself from the `qwik/json` state.
|
|
543
|
-
*
|
|
544
|
-
* As the VNode get materialized the vnode now becomes eligible for mutation. Once the vnode mutates
|
|
545
|
-
* the `VNode` references from the `qwik/json` may become invalid. For this reason, these references
|
|
546
|
-
* need to be eagerly resolved. `VNODE_REF` stores a pointer to "this" vnode. This allows the system
|
|
547
|
-
* to eagerly resolve these pointes as the vnodes are materialized.
|
|
548
|
-
*/
|
|
549
|
-
const ELEMENT_ID = 'q:id';
|
|
550
|
-
const ELEMENT_KEY = 'q:key';
|
|
551
|
-
const ELEMENT_PROPS = 'q:props';
|
|
552
|
-
const ELEMENT_SEQ = 'q:seq';
|
|
553
|
-
const ELEMENT_SEQ_IDX = 'q:seqIdx';
|
|
554
|
-
const Q_PREFIX = 'q:';
|
|
555
|
-
/** Non serializable markers - always begins with `:` character */
|
|
556
|
-
const NON_SERIALIZABLE_MARKER_PREFIX = ':';
|
|
557
|
-
const USE_ON_LOCAL = NON_SERIALIZABLE_MARKER_PREFIX + 'on';
|
|
558
|
-
const USE_ON_LOCAL_SEQ_IDX = NON_SERIALIZABLE_MARKER_PREFIX + 'onIdx';
|
|
559
|
-
const USE_ON_LOCAL_FLAGS = NON_SERIALIZABLE_MARKER_PREFIX + 'onFlags';
|
|
560
|
-
// comment nodes
|
|
561
|
-
const FLUSH_COMMENT = 'qkssr-f';
|
|
562
|
-
const STREAM_BLOCK_START_COMMENT = 'qkssr-pu';
|
|
563
|
-
const STREAM_BLOCK_END_COMMENT = 'qkssr-po';
|
|
564
|
-
const Q_PROPS_SEPARATOR = ':';
|
|
565
|
-
const dangerouslySetInnerHTML = 'dangerouslySetInnerHTML';
|
|
566
|
-
const qwikInspectorAttr = 'data-qwik-inspector';
|
|
567
|
-
|
|
568
575
|
let _locale = undefined;
|
|
569
576
|
/**
|
|
570
577
|
* Retrieve the current locale.
|
|
@@ -1138,7 +1145,6 @@
|
|
|
1138
1145
|
}
|
|
1139
1146
|
/** In the case of oldValue and value are the same, the effects are not triggered. */
|
|
1140
1147
|
set(target, prop, value) {
|
|
1141
|
-
target = unwrapDeserializerProxy(target);
|
|
1142
1148
|
if (typeof prop === 'symbol') {
|
|
1143
1149
|
target[prop] = value;
|
|
1144
1150
|
return true;
|
|
@@ -1207,6 +1213,8 @@
|
|
|
1207
1213
|
// to unsubscribe from. So we need to store the reference from the effect back
|
|
1208
1214
|
// to this signal.
|
|
1209
1215
|
ensureContains(effectSubscriber, target);
|
|
1216
|
+
// We need to add the subscriber to the effect so that we can clean it up later
|
|
1217
|
+
ensureEffectContainsSubscriber(effectSubscriber[EffectSubscriptionsProp.EFFECT], target, store.$container$);
|
|
1210
1218
|
}
|
|
1211
1219
|
function setNewValueAndTriggerEffects(prop, value, target, currentStore) {
|
|
1212
1220
|
target[prop] = value;
|
|
@@ -1277,32 +1285,40 @@
|
|
|
1277
1285
|
}
|
|
1278
1286
|
for (let i = effects.length - 1; i >= 0; i--) {
|
|
1279
1287
|
const subscriber = effects[i];
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1288
|
+
clearEffects(subscriber, value, effects, i, container);
|
|
1289
|
+
}
|
|
1290
|
+
if (effects.length === 0) {
|
|
1291
|
+
vnode_setProp(value, QSubscribers, null);
|
|
1284
1292
|
}
|
|
1285
1293
|
}
|
|
1286
|
-
function clearSubscriberEffectDependencies(value) {
|
|
1294
|
+
function clearSubscriberEffectDependencies(container, value) {
|
|
1287
1295
|
if (value.$effectDependencies$) {
|
|
1288
1296
|
for (let i = value.$effectDependencies$.length - 1; i >= 0; i--) {
|
|
1289
1297
|
const subscriber = value.$effectDependencies$[i];
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1298
|
+
clearEffects(subscriber, value, value.$effectDependencies$, i, container);
|
|
1299
|
+
}
|
|
1300
|
+
if (value.$effectDependencies$.length === 0) {
|
|
1301
|
+
value.$effectDependencies$ = null;
|
|
1294
1302
|
}
|
|
1295
1303
|
}
|
|
1296
1304
|
}
|
|
1297
|
-
function clearEffects(subscriber, value) {
|
|
1298
|
-
|
|
1299
|
-
|
|
1305
|
+
function clearEffects(subscriber, value, effectArray, indexToRemove, container) {
|
|
1306
|
+
let subscriptionRemoved = false;
|
|
1307
|
+
const seenSet = new Set();
|
|
1308
|
+
if (subscriber instanceof WrappedSignal) {
|
|
1309
|
+
subscriptionRemoved = clearSignalEffects(subscriber, value, seenSet);
|
|
1300
1310
|
}
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1311
|
+
else if (container.$storeProxyMap$.has(subscriber)) {
|
|
1312
|
+
const store = container.$storeProxyMap$.get(subscriber);
|
|
1313
|
+
const handler = getStoreHandler(store);
|
|
1314
|
+
subscriptionRemoved = clearStoreEffects(handler, value);
|
|
1305
1315
|
}
|
|
1316
|
+
if (subscriptionRemoved) {
|
|
1317
|
+
effectArray.splice(indexToRemove, 1);
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
function clearSignalEffects(subscriber, value, seenSet) {
|
|
1321
|
+
const effectSubscriptions = subscriber.$effects$;
|
|
1306
1322
|
let subscriptionRemoved = false;
|
|
1307
1323
|
if (effectSubscriptions) {
|
|
1308
1324
|
for (let i = effectSubscriptions.length - 1; i >= 0; i--) {
|
|
@@ -1313,15 +1329,84 @@
|
|
|
1313
1329
|
}
|
|
1314
1330
|
}
|
|
1315
1331
|
}
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1332
|
+
if (subscriber instanceof WrappedSignal) {
|
|
1333
|
+
const hostElement = subscriber.$hostElement$;
|
|
1334
|
+
if (hostElement && hostElement === value) {
|
|
1335
|
+
subscriber.$hostElement$ = null;
|
|
1336
|
+
}
|
|
1337
|
+
// clear the effects of the arguments
|
|
1338
|
+
const args = subscriber.$args$;
|
|
1339
|
+
if (args) {
|
|
1340
|
+
clearArgsEffects(args, subscriber, seenSet);
|
|
1321
1341
|
}
|
|
1322
1342
|
}
|
|
1323
1343
|
return subscriptionRemoved;
|
|
1324
1344
|
}
|
|
1345
|
+
function clearStoreEffects(storeHandler, value) {
|
|
1346
|
+
const effectSubscriptions = storeHandler.$effects$;
|
|
1347
|
+
if (!effectSubscriptions) {
|
|
1348
|
+
return false;
|
|
1349
|
+
}
|
|
1350
|
+
let subscriptionRemoved = false;
|
|
1351
|
+
for (const key in effectSubscriptions) {
|
|
1352
|
+
const effects = effectSubscriptions[key];
|
|
1353
|
+
for (let i = effects.length - 1; i >= 0; i--) {
|
|
1354
|
+
const effect = effects[i];
|
|
1355
|
+
if (effect[EffectSubscriptionsProp.EFFECT] === value) {
|
|
1356
|
+
effects.splice(i, 1);
|
|
1357
|
+
subscriptionRemoved = true;
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
if (effects.length === 0) {
|
|
1361
|
+
delete effectSubscriptions[key];
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
return subscriptionRemoved;
|
|
1365
|
+
}
|
|
1366
|
+
function clearArgsEffects(args, subscriber, seenSet) {
|
|
1367
|
+
for (let i = args.length - 1; i >= 0; i--) {
|
|
1368
|
+
const arg = args[i];
|
|
1369
|
+
clearArgEffect(arg, subscriber, seenSet);
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
function clearArgEffect(arg, subscriber, seenSet) {
|
|
1373
|
+
if (seenSet.has(arg)) {
|
|
1374
|
+
return;
|
|
1375
|
+
}
|
|
1376
|
+
seenSet.add(arg);
|
|
1377
|
+
if (isSignal(arg)) {
|
|
1378
|
+
clearSignalEffects(arg, subscriber, seenSet);
|
|
1379
|
+
}
|
|
1380
|
+
else if (typeof arg === 'object' && arg !== null) {
|
|
1381
|
+
if (isStore(arg)) {
|
|
1382
|
+
clearStoreEffects(getStoreHandler(arg), subscriber);
|
|
1383
|
+
}
|
|
1384
|
+
else if (isPropsProxy(arg)) {
|
|
1385
|
+
// Separate check for props proxy, because props proxy getter could call signal getter.
|
|
1386
|
+
// To avoid that we need to get the constProps and varProps directly
|
|
1387
|
+
// from the props proxy object and loop over them.
|
|
1388
|
+
const constProps = arg[_CONST_PROPS];
|
|
1389
|
+
const varProps = arg[_VAR_PROPS];
|
|
1390
|
+
if (constProps) {
|
|
1391
|
+
for (const key in constProps) {
|
|
1392
|
+
clearArgEffect(constProps[key], subscriber, seenSet);
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
for (const key in varProps) {
|
|
1396
|
+
clearArgEffect(varProps[key], subscriber, seenSet);
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
else {
|
|
1400
|
+
for (const key in arg) {
|
|
1401
|
+
clearArgEffect(arg[key], subscriber, seenSet);
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
else if (Array.isArray(arg)) {
|
|
1406
|
+
clearArgsEffects(arg, subscriber, seenSet);
|
|
1407
|
+
}
|
|
1408
|
+
else ;
|
|
1409
|
+
}
|
|
1325
1410
|
|
|
1326
1411
|
/** @internal */
|
|
1327
1412
|
const useResourceQrl = (qrl, opts) => {
|
|
@@ -1408,14 +1493,17 @@
|
|
|
1408
1493
|
// create a subscription for the resource._state changes
|
|
1409
1494
|
const state = resource._state;
|
|
1410
1495
|
if (state === 'pending' && props.onPending) {
|
|
1411
|
-
return Promise.resolve(props.onPending
|
|
1496
|
+
return Promise.resolve().then(useBindInvokeContext(props.onPending));
|
|
1412
1497
|
}
|
|
1413
1498
|
else if (state === 'rejected' && props.onRejected) {
|
|
1414
|
-
return Promise.resolve(resource._error).then(props.onRejected);
|
|
1499
|
+
return Promise.resolve(resource._error).then(useBindInvokeContext(props.onRejected));
|
|
1415
1500
|
}
|
|
1416
1501
|
else {
|
|
1417
|
-
|
|
1418
|
-
|
|
1502
|
+
const resolvedValue = untrack(() => resource._resolved);
|
|
1503
|
+
if (resolvedValue !== undefined) {
|
|
1504
|
+
// resolved, pending without onPending prop or rejected without onRejected prop
|
|
1505
|
+
return Promise.resolve(resolvedValue).then(useBindInvokeContext(props.onResolved));
|
|
1506
|
+
}
|
|
1419
1507
|
}
|
|
1420
1508
|
}
|
|
1421
1509
|
return resource.value.then(useBindInvokeContext(props.onResolved), useBindInvokeContext(props.onRejected));
|
|
@@ -1456,7 +1544,7 @@
|
|
|
1456
1544
|
cleanupTask(task);
|
|
1457
1545
|
const iCtx = newInvokeContext(container.$locale$, host, undefined, ResourceEvent);
|
|
1458
1546
|
iCtx.$container$ = container;
|
|
1459
|
-
const taskFn = task.$qrl$.getFn(iCtx, () => clearSubscriberEffectDependencies(task));
|
|
1547
|
+
const taskFn = task.$qrl$.getFn(iCtx, () => clearSubscriberEffectDependencies(container, task));
|
|
1460
1548
|
const resource = task.$state$;
|
|
1461
1549
|
assertDefined(resource, 'useResource: when running a resource, "task.resource" must be a defined.', task);
|
|
1462
1550
|
const track = (obj, prop) => {
|
|
@@ -2257,6 +2345,17 @@
|
|
|
2257
2345
|
}
|
|
2258
2346
|
}
|
|
2259
2347
|
|
|
2348
|
+
function getFileLocationFromJsx(jsxDev) {
|
|
2349
|
+
if (!jsxDev) {
|
|
2350
|
+
return null;
|
|
2351
|
+
}
|
|
2352
|
+
const sanitizedFileName = jsxDev.fileName?.replace(/\\/g, '/');
|
|
2353
|
+
if (sanitizedFileName) {
|
|
2354
|
+
return `${sanitizedFileName}:${jsxDev.lineNumber}:${jsxDev.columnNumber}`;
|
|
2355
|
+
}
|
|
2356
|
+
return null;
|
|
2357
|
+
}
|
|
2358
|
+
|
|
2260
2359
|
const vnode_diff = (container, jsxNode, vStartNode, scopedStyleIdPrefix) => {
|
|
2261
2360
|
let journal = container.$journal$;
|
|
2262
2361
|
/**
|
|
@@ -2700,7 +2799,7 @@
|
|
|
2700
2799
|
*
|
|
2701
2800
|
* @returns {boolean}
|
|
2702
2801
|
*/
|
|
2703
|
-
function createNewElement(jsx, elementName) {
|
|
2802
|
+
function createNewElement(jsx, elementName, currentFile) {
|
|
2704
2803
|
const element = createElementWithNamespace(elementName);
|
|
2705
2804
|
const { constProps } = jsx;
|
|
2706
2805
|
let needsQDispatchEventPatch = false;
|
|
@@ -2731,6 +2830,9 @@
|
|
|
2731
2830
|
value(element);
|
|
2732
2831
|
continue;
|
|
2733
2832
|
}
|
|
2833
|
+
else {
|
|
2834
|
+
throw qError(QError.invalidRefValue, [currentFile]);
|
|
2835
|
+
}
|
|
2734
2836
|
}
|
|
2735
2837
|
if (isSignal(value)) {
|
|
2736
2838
|
const signalData = new EffectPropData({
|
|
@@ -2745,13 +2847,13 @@
|
|
|
2745
2847
|
continue;
|
|
2746
2848
|
}
|
|
2747
2849
|
if (elementName === 'textarea' && key === 'value') {
|
|
2748
|
-
if (typeof value !== 'string') {
|
|
2850
|
+
if (value && typeof value !== 'string') {
|
|
2749
2851
|
if (build.isDev) {
|
|
2750
|
-
throw qError(QError.wrongTextareaValue);
|
|
2852
|
+
throw qError(QError.wrongTextareaValue, [currentFile, value]);
|
|
2751
2853
|
}
|
|
2752
2854
|
continue;
|
|
2753
2855
|
}
|
|
2754
|
-
element.value = escapeHTML(value);
|
|
2856
|
+
element.value = escapeHTML(value || '');
|
|
2755
2857
|
continue;
|
|
2756
2858
|
}
|
|
2757
2859
|
value = serializeAttribute(key, value, scopedStyleIdPrefix);
|
|
@@ -2785,6 +2887,7 @@
|
|
|
2785
2887
|
const isSameElementName = vCurrent && vnode_isElementVNode(vCurrent) && elementName === vnode_getElementName(vCurrent);
|
|
2786
2888
|
const jsxKey = jsx.key;
|
|
2787
2889
|
let needsQDispatchEventPatch = false;
|
|
2890
|
+
const currentFile = getFileLocationFromJsx(jsx.dev);
|
|
2788
2891
|
if (!isSameElementName || jsxKey !== getKey(vCurrent)) {
|
|
2789
2892
|
// So we have a key and it does not match the current node.
|
|
2790
2893
|
// We need to do a forward search to find it.
|
|
@@ -2797,14 +2900,21 @@
|
|
|
2797
2900
|
else {
|
|
2798
2901
|
// Existing keyed node
|
|
2799
2902
|
vnode_insertBefore(journal, vParent, vNewNode, vCurrent);
|
|
2903
|
+
// We are here, so jsx is different from the vCurrent, so now we want to point to the moved node.
|
|
2904
|
+
vCurrent = vNewNode;
|
|
2905
|
+
// We need to clean up the vNewNode, because we don't want to skip advance to next sibling (see `advance` function).
|
|
2906
|
+
vNewNode = null;
|
|
2907
|
+
// We need also to go back to the previous sibling, because we assigned previous sibling to the vCurrent.
|
|
2908
|
+
if (vSiblings !== null) {
|
|
2909
|
+
vSiblingsIdx -= SiblingsArray.Size;
|
|
2910
|
+
}
|
|
2800
2911
|
}
|
|
2801
2912
|
}
|
|
2802
2913
|
// reconcile attributes
|
|
2803
2914
|
const jsxAttrs = [];
|
|
2804
2915
|
const props = jsx.varProps;
|
|
2805
2916
|
for (const key in props) {
|
|
2806
|
-
|
|
2807
|
-
value = serializeAttribute(key, value, scopedStyleIdPrefix);
|
|
2917
|
+
const value = props[key];
|
|
2808
2918
|
if (value != null) {
|
|
2809
2919
|
mapArray_set(jsxAttrs, key, value, 0);
|
|
2810
2920
|
}
|
|
@@ -2813,7 +2923,8 @@
|
|
|
2813
2923
|
mapArray_set(jsxAttrs, ELEMENT_KEY, jsxKey, 0);
|
|
2814
2924
|
}
|
|
2815
2925
|
const vNode = (vNewNode || vCurrent);
|
|
2816
|
-
needsQDispatchEventPatch =
|
|
2926
|
+
needsQDispatchEventPatch =
|
|
2927
|
+
setBulkProps(vNode, jsxAttrs, currentFile) || needsQDispatchEventPatch;
|
|
2817
2928
|
if (needsQDispatchEventPatch) {
|
|
2818
2929
|
// Event handler needs to be patched onto the element.
|
|
2819
2930
|
const element = vnode_getNode(vNode);
|
|
@@ -2838,7 +2949,7 @@
|
|
|
2838
2949
|
}
|
|
2839
2950
|
}
|
|
2840
2951
|
/** @param tag Returns true if `qDispatchEvent` needs patching */
|
|
2841
|
-
function setBulkProps(vnode, srcAttrs) {
|
|
2952
|
+
function setBulkProps(vnode, srcAttrs, currentFile) {
|
|
2842
2953
|
vnode_ensureElementInflated(vnode);
|
|
2843
2954
|
const dstAttrs = vnode;
|
|
2844
2955
|
let srcIdx = 0;
|
|
@@ -2863,11 +2974,18 @@
|
|
|
2863
2974
|
value(element);
|
|
2864
2975
|
return;
|
|
2865
2976
|
}
|
|
2977
|
+
else {
|
|
2978
|
+
throw qError(QError.invalidRefValue, [currentFile]);
|
|
2979
|
+
}
|
|
2866
2980
|
}
|
|
2867
2981
|
if (isSignal(value)) {
|
|
2868
|
-
|
|
2982
|
+
const signalData = new EffectPropData({
|
|
2983
|
+
$scopedStyleIdPrefix$: scopedStyleIdPrefix,
|
|
2984
|
+
$isConst$: false,
|
|
2985
|
+
});
|
|
2986
|
+
value = trackSignalAndAssignHost(value, vnode, key, container, signalData);
|
|
2869
2987
|
}
|
|
2870
|
-
vnode_setAttr(journal, vnode, key, value);
|
|
2988
|
+
vnode_setAttr(journal, vnode, key, serializeAttribute(key, value, scopedStyleIdPrefix));
|
|
2871
2989
|
if (value === null) {
|
|
2872
2990
|
// if we set `null` than attribute was removed and we need to shorten the dstLength
|
|
2873
2991
|
dstLength = dstAttrs.length;
|
|
@@ -2923,6 +3041,10 @@
|
|
|
2923
3041
|
}
|
|
2924
3042
|
srcIdx++;
|
|
2925
3043
|
srcKey = srcIdx < srcLength ? srcAttrs[srcIdx++] : null;
|
|
3044
|
+
// we need to increment dstIdx too, because we added destination key and value to the VNode
|
|
3045
|
+
// and dstAttrs is a reference to the VNode
|
|
3046
|
+
dstIdx++;
|
|
3047
|
+
dstKey = dstIdx < dstLength ? dstAttrs[dstIdx++] : null;
|
|
2926
3048
|
}
|
|
2927
3049
|
else if (srcKey == dstKey) {
|
|
2928
3050
|
const srcValue = srcAttrs[srcIdx++];
|
|
@@ -3040,7 +3162,7 @@
|
|
|
3040
3162
|
vNewNode = retrieveChildWithKey(null, jsxKey);
|
|
3041
3163
|
if (vNewNode != null) {
|
|
3042
3164
|
// We found it, move it up.
|
|
3043
|
-
vnode_insertBefore(journal, vParent,
|
|
3165
|
+
vnode_insertBefore(journal, vParent, vNewNode, vCurrent && getInsertBefore());
|
|
3044
3166
|
return;
|
|
3045
3167
|
}
|
|
3046
3168
|
}
|
|
@@ -3282,7 +3404,7 @@
|
|
|
3282
3404
|
const obj = seq[i];
|
|
3283
3405
|
if (isTask(obj)) {
|
|
3284
3406
|
const task = obj;
|
|
3285
|
-
clearSubscriberEffectDependencies(task);
|
|
3407
|
+
clearSubscriberEffectDependencies(container, task);
|
|
3286
3408
|
if (task.$flags$ & TaskFlags.VISIBLE_TASK) {
|
|
3287
3409
|
container.$scheduler$(ChoreType.CLEANUP_VISIBLE, task);
|
|
3288
3410
|
}
|
|
@@ -3483,6 +3605,108 @@
|
|
|
3483
3605
|
*/
|
|
3484
3606
|
const createComputed$ = /*#__PURE__*/ implicit$FirstArg(createComputedQrl);
|
|
3485
3607
|
|
|
3608
|
+
/// These global variables are used to avoid creating new arrays for each call to `vnode_documentPosition`.
|
|
3609
|
+
const aVNodePath = [];
|
|
3610
|
+
const bVNodePath = [];
|
|
3611
|
+
/**
|
|
3612
|
+
* Compare two VNodes and determine their document position relative to each other.
|
|
3613
|
+
*
|
|
3614
|
+
* @param a VNode to compare
|
|
3615
|
+
* @param b VNode to compare
|
|
3616
|
+
* @param rootVNode - Root VNode of a container
|
|
3617
|
+
* @returns -1 if `a` is before `b`, 0 if `a` is the same as `b`, 1 if `a` is after `b`.
|
|
3618
|
+
*/
|
|
3619
|
+
const vnode_documentPosition = (a, b, rootVNode) => {
|
|
3620
|
+
if (a === b) {
|
|
3621
|
+
return 0;
|
|
3622
|
+
}
|
|
3623
|
+
let aDepth = -1;
|
|
3624
|
+
let bDepth = -1;
|
|
3625
|
+
while (a) {
|
|
3626
|
+
const vNode = (aVNodePath[++aDepth] = a);
|
|
3627
|
+
a = (vNode[VNodeProps.parent] ||
|
|
3628
|
+
(rootVNode && vnode_getProp(a, QSlotParent, (id) => vnode_locate(rootVNode, id))));
|
|
3629
|
+
}
|
|
3630
|
+
while (b) {
|
|
3631
|
+
const vNode = (bVNodePath[++bDepth] = b);
|
|
3632
|
+
b = (vNode[VNodeProps.parent] ||
|
|
3633
|
+
(rootVNode && vnode_getProp(b, QSlotParent, (id) => vnode_locate(rootVNode, id))));
|
|
3634
|
+
}
|
|
3635
|
+
while (aDepth >= 0 && bDepth >= 0) {
|
|
3636
|
+
a = aVNodePath[aDepth];
|
|
3637
|
+
b = bVNodePath[bDepth];
|
|
3638
|
+
if (a === b) {
|
|
3639
|
+
// if the nodes are the same, we need to check the next level.
|
|
3640
|
+
aDepth--;
|
|
3641
|
+
bDepth--;
|
|
3642
|
+
}
|
|
3643
|
+
else {
|
|
3644
|
+
// We found a difference so we need to scan nodes at this level.
|
|
3645
|
+
let cursor = b;
|
|
3646
|
+
do {
|
|
3647
|
+
cursor = vnode_getNextSibling(cursor);
|
|
3648
|
+
if (cursor === a) {
|
|
3649
|
+
return 1;
|
|
3650
|
+
}
|
|
3651
|
+
} while (cursor);
|
|
3652
|
+
cursor = b;
|
|
3653
|
+
do {
|
|
3654
|
+
cursor = vnode_getPreviousSibling(cursor);
|
|
3655
|
+
if (cursor === a) {
|
|
3656
|
+
return -1;
|
|
3657
|
+
}
|
|
3658
|
+
} while (cursor);
|
|
3659
|
+
if (rootVNode && vnode_getProp(b, QSlotParent, (id) => vnode_locate(rootVNode, id))) {
|
|
3660
|
+
// The "b" node is a projection, so we need to set it after "a" node,
|
|
3661
|
+
// because the "a" node could be a context provider.
|
|
3662
|
+
return -1;
|
|
3663
|
+
}
|
|
3664
|
+
// The node is not in the list of siblings, that means it must be disconnected.
|
|
3665
|
+
return 1;
|
|
3666
|
+
}
|
|
3667
|
+
}
|
|
3668
|
+
return aDepth < bDepth ? -1 : 1;
|
|
3669
|
+
};
|
|
3670
|
+
/// These global variables are used to avoid creating new arrays for each call to `ssrNodeDocumentPosition`.
|
|
3671
|
+
const aSsrNodePath = [];
|
|
3672
|
+
const bSsrNodePath = [];
|
|
3673
|
+
/**
|
|
3674
|
+
* Compare two SSR nodes and determine their document position relative to each other. Compares only
|
|
3675
|
+
* position between parent and child.
|
|
3676
|
+
*
|
|
3677
|
+
* @param a SSR node to compare
|
|
3678
|
+
* @param b SSR node to compare
|
|
3679
|
+
* @returns -1 if `a` is before `b`, 0 if `a` is the same as `b`, 1 if `a` is after `b`.
|
|
3680
|
+
*/
|
|
3681
|
+
const ssrNodeDocumentPosition = (a, b) => {
|
|
3682
|
+
if (a === b) {
|
|
3683
|
+
return 0;
|
|
3684
|
+
}
|
|
3685
|
+
let aDepth = -1;
|
|
3686
|
+
let bDepth = -1;
|
|
3687
|
+
while (a) {
|
|
3688
|
+
const ssrNode = (aSsrNodePath[++aDepth] = a);
|
|
3689
|
+
a = ssrNode.currentComponentNode;
|
|
3690
|
+
}
|
|
3691
|
+
while (b) {
|
|
3692
|
+
const ssrNode = (bSsrNodePath[++bDepth] = b);
|
|
3693
|
+
b = ssrNode.currentComponentNode;
|
|
3694
|
+
}
|
|
3695
|
+
while (aDepth >= 0 && bDepth >= 0) {
|
|
3696
|
+
a = aSsrNodePath[aDepth];
|
|
3697
|
+
b = bSsrNodePath[bDepth];
|
|
3698
|
+
if (a === b) {
|
|
3699
|
+
// if the nodes are the same, we need to check the next level.
|
|
3700
|
+
aDepth--;
|
|
3701
|
+
bDepth--;
|
|
3702
|
+
}
|
|
3703
|
+
else {
|
|
3704
|
+
return 1;
|
|
3705
|
+
}
|
|
3706
|
+
}
|
|
3707
|
+
return aDepth < bDepth ? -1 : 1;
|
|
3708
|
+
};
|
|
3709
|
+
|
|
3486
3710
|
/**
|
|
3487
3711
|
* Scheduler is responsible for running application code in predictable order.
|
|
3488
3712
|
*
|
|
@@ -3615,7 +3839,7 @@
|
|
|
3615
3839
|
$executed$: false,
|
|
3616
3840
|
};
|
|
3617
3841
|
chore.$promise$ = new Promise((resolve) => (chore.$resolve$ = resolve));
|
|
3618
|
-
chore = sortedInsert(choreQueue, chore);
|
|
3842
|
+
chore = sortedInsert(choreQueue, chore, container.rootVNode || null);
|
|
3619
3843
|
if (!journalFlushScheduled && runLater) {
|
|
3620
3844
|
// If we are not currently draining, we need to schedule a drain.
|
|
3621
3845
|
journalFlushScheduled = true;
|
|
@@ -3626,7 +3850,7 @@
|
|
|
3626
3850
|
return chore.$promise$;
|
|
3627
3851
|
}
|
|
3628
3852
|
else {
|
|
3629
|
-
return drainUpTo(chore);
|
|
3853
|
+
return drainUpTo(chore, container.rootVNode || null);
|
|
3630
3854
|
}
|
|
3631
3855
|
}
|
|
3632
3856
|
/**
|
|
@@ -3634,7 +3858,7 @@
|
|
|
3634
3858
|
*
|
|
3635
3859
|
* @param runUptoChore
|
|
3636
3860
|
*/
|
|
3637
|
-
function drainUpTo(runUptoChore) {
|
|
3861
|
+
function drainUpTo(runUptoChore, rootVNode) {
|
|
3638
3862
|
// If it already ran, it's not in the queue
|
|
3639
3863
|
if (runUptoChore.$executed$) {
|
|
3640
3864
|
return runUptoChore.$returnValue$;
|
|
@@ -3645,7 +3869,7 @@
|
|
|
3645
3869
|
}
|
|
3646
3870
|
while (choreQueue.length) {
|
|
3647
3871
|
const nextChore = choreQueue.shift();
|
|
3648
|
-
const order = choreComparator(nextChore, runUptoChore,
|
|
3872
|
+
const order = choreComparator(nextChore, runUptoChore, rootVNode);
|
|
3649
3873
|
if (order === null) {
|
|
3650
3874
|
continue;
|
|
3651
3875
|
}
|
|
@@ -3661,7 +3885,7 @@
|
|
|
3661
3885
|
}
|
|
3662
3886
|
const returnValue = executeChore(nextChore);
|
|
3663
3887
|
if (isPromise(returnValue)) {
|
|
3664
|
-
const promise = returnValue.then(() => drainUpTo(runUptoChore));
|
|
3888
|
+
const promise = returnValue.then(() => drainUpTo(runUptoChore, rootVNode));
|
|
3665
3889
|
return promise;
|
|
3666
3890
|
}
|
|
3667
3891
|
}
|
|
@@ -3682,7 +3906,7 @@
|
|
|
3682
3906
|
returnValue = safeCall(() => executeComponent(container, host, host, chore.$target$, chore.$payload$), (jsx) => {
|
|
3683
3907
|
if (chore.$type$ === ChoreType.COMPONENT) {
|
|
3684
3908
|
const styleScopedId = container.getHostProp(host, QScopedStyle);
|
|
3685
|
-
return vnode_diff(container, jsx, host, addComponentStylePrefix(styleScopedId));
|
|
3909
|
+
return retryOnPromise(() => vnode_diff(container, jsx, host, addComponentStylePrefix(styleScopedId)));
|
|
3686
3910
|
}
|
|
3687
3911
|
else {
|
|
3688
3912
|
return jsx;
|
|
@@ -3713,7 +3937,7 @@
|
|
|
3713
3937
|
if (isSignal(jsx)) {
|
|
3714
3938
|
jsx = jsx.value;
|
|
3715
3939
|
}
|
|
3716
|
-
returnValue = vnode_diff(container, jsx, parentVirtualNode, null);
|
|
3940
|
+
returnValue = retryOnPromise(() => vnode_diff(container, jsx, parentVirtualNode, null));
|
|
3717
3941
|
break;
|
|
3718
3942
|
case ChoreType.NODE_PROP:
|
|
3719
3943
|
const virtualNode = chore.$host$;
|
|
@@ -3782,7 +4006,15 @@
|
|
|
3782
4006
|
vnode_isVNode(chore.$host$) &&
|
|
3783
4007
|
chore.$host$[VNodeProps.flags] & VNodeFlags.Deleted);
|
|
3784
4008
|
}
|
|
3785
|
-
|
|
4009
|
+
/**
|
|
4010
|
+
* Compares two chores to determine their execution order in the scheduler's queue.
|
|
4011
|
+
*
|
|
4012
|
+
* @param a - The first chore to compare
|
|
4013
|
+
* @param b - The second chore to compare
|
|
4014
|
+
* @returns A number indicating the relative order of the chores. A negative number means `a` runs
|
|
4015
|
+
* before `b`.
|
|
4016
|
+
*/
|
|
4017
|
+
function choreComparator(a, b, rootVNode) {
|
|
3786
4018
|
const macroTypeDiff = (a.$type$ & ChoreType.MACRO) - (b.$type$ & ChoreType.MACRO);
|
|
3787
4019
|
if (macroTypeDiff !== 0) {
|
|
3788
4020
|
return macroTypeDiff;
|
|
@@ -3795,7 +4027,7 @@
|
|
|
3795
4027
|
if (aHost !== bHost && aHost !== null && bHost !== null) {
|
|
3796
4028
|
if (vnode_isVNode(aHost) && vnode_isVNode(bHost)) {
|
|
3797
4029
|
// we are running on the client.
|
|
3798
|
-
const hostDiff = vnode_documentPosition(aHost, bHost);
|
|
4030
|
+
const hostDiff = vnode_documentPosition(aHost, bHost, rootVNode);
|
|
3799
4031
|
if (hostDiff !== 0) {
|
|
3800
4032
|
return hostDiff;
|
|
3801
4033
|
}
|
|
@@ -3809,11 +4041,11 @@
|
|
|
3809
4041
|
You are attempting to change a state that has already been streamed to the client.
|
|
3810
4042
|
This can lead to inconsistencies between Server-Side Rendering (SSR) and Client-Side Rendering (CSR).
|
|
3811
4043
|
Problematic Node: ${aHost.toString()}`;
|
|
3812
|
-
if (shouldThrowOnHostMismatch) {
|
|
3813
|
-
throw qError(QError.serverHostMismatch, [errorMessage]);
|
|
3814
|
-
}
|
|
3815
4044
|
logWarn(errorMessage);
|
|
3816
|
-
|
|
4045
|
+
const hostDiff = ssrNodeDocumentPosition(aHost, bHost);
|
|
4046
|
+
if (hostDiff !== 0) {
|
|
4047
|
+
return hostDiff;
|
|
4048
|
+
}
|
|
3817
4049
|
}
|
|
3818
4050
|
}
|
|
3819
4051
|
const microTypeDiff = (a.$type$ & ChoreType.MICRO) - (b.$type$ & ChoreType.MICRO);
|
|
@@ -3836,7 +4068,7 @@
|
|
|
3836
4068
|
}
|
|
3837
4069
|
return 0;
|
|
3838
4070
|
}
|
|
3839
|
-
function sortedFindIndex(sortedArray, value) {
|
|
4071
|
+
function sortedFindIndex(sortedArray, value, rootVNode) {
|
|
3840
4072
|
/// We need to ensure that the `queue` is sorted by priority.
|
|
3841
4073
|
/// 1. Find a place where to insert into.
|
|
3842
4074
|
let bottom = 0;
|
|
@@ -3844,7 +4076,7 @@
|
|
|
3844
4076
|
while (bottom < top) {
|
|
3845
4077
|
const middle = bottom + ((top - bottom) >> 1);
|
|
3846
4078
|
const midChore = sortedArray[middle];
|
|
3847
|
-
const comp = choreComparator(value, midChore,
|
|
4079
|
+
const comp = choreComparator(value, midChore, rootVNode);
|
|
3848
4080
|
if (comp < 0) {
|
|
3849
4081
|
top = middle;
|
|
3850
4082
|
}
|
|
@@ -3858,10 +4090,10 @@
|
|
|
3858
4090
|
}
|
|
3859
4091
|
return ~bottom;
|
|
3860
4092
|
}
|
|
3861
|
-
function sortedInsert(sortedArray, value) {
|
|
4093
|
+
function sortedInsert(sortedArray, value, rootVNode) {
|
|
3862
4094
|
/// We need to ensure that the `queue` is sorted by priority.
|
|
3863
4095
|
/// 1. Find a place where to insert into.
|
|
3864
|
-
const idx = sortedFindIndex(sortedArray, value);
|
|
4096
|
+
const idx = sortedFindIndex(sortedArray, value, rootVNode);
|
|
3865
4097
|
if (idx < 0) {
|
|
3866
4098
|
/// 2. Insert the chore into the queue.
|
|
3867
4099
|
sortedArray.splice(~idx, 0, value);
|
|
@@ -3939,7 +4171,7 @@
|
|
|
3939
4171
|
cleanupTask(task);
|
|
3940
4172
|
const iCtx = newInvokeContext(container.$locale$, host, undefined, TaskEvent);
|
|
3941
4173
|
iCtx.$container$ = container;
|
|
3942
|
-
const taskFn = task.$qrl$.getFn(iCtx, () => clearSubscriberEffectDependencies(task));
|
|
4174
|
+
const taskFn = task.$qrl$.getFn(iCtx, () => clearSubscriberEffectDependencies(container, task));
|
|
3943
4175
|
const track = (obj, prop) => {
|
|
3944
4176
|
const ctx = newInvokeContext();
|
|
3945
4177
|
ctx.$effectSubscriber$ = [task, EffectProperty.COMPONENT];
|
|
@@ -4571,7 +4803,7 @@
|
|
|
4571
4803
|
appendClassIfScopedStyleExists(jsx, options.styleScoped);
|
|
4572
4804
|
let qwikInspectorAttrValue = null;
|
|
4573
4805
|
if (build.isDev && jsx.dev && jsx.type !== 'head') {
|
|
4574
|
-
qwikInspectorAttrValue =
|
|
4806
|
+
qwikInspectorAttrValue = getFileLocationFromJsx(jsx.dev);
|
|
4575
4807
|
if (qInspector) {
|
|
4576
4808
|
appendQwikInspectorAttribute(jsx, qwikInspectorAttrValue);
|
|
4577
4809
|
}
|
|
@@ -4845,13 +5077,6 @@
|
|
|
4845
5077
|
}
|
|
4846
5078
|
return directGetPropsProxyProp(jsx, 'name') || QDefaultSlot;
|
|
4847
5079
|
}
|
|
4848
|
-
function getQwikInspectorAttributeValue(jsxDev) {
|
|
4849
|
-
const sanitizedFileName = jsxDev.fileName?.replace(/\\/g, '/');
|
|
4850
|
-
if (sanitizedFileName) {
|
|
4851
|
-
return `${sanitizedFileName}:${jsxDev.lineNumber}:${jsxDev.columnNumber}`;
|
|
4852
|
-
}
|
|
4853
|
-
return null;
|
|
4854
|
-
}
|
|
4855
5080
|
function appendQwikInspectorAttribute(jsx, qwikInspectorAttrValue) {
|
|
4856
5081
|
if (qwikInspectorAttrValue && (!jsx.constProps || !(qwikInspectorAttr in jsx.constProps))) {
|
|
4857
5082
|
(jsx.constProps ||= {})[qwikInspectorAttr] = qwikInspectorAttrValue;
|
|
@@ -4873,7 +5098,7 @@
|
|
|
4873
5098
|
*
|
|
4874
5099
|
* @public
|
|
4875
5100
|
*/
|
|
4876
|
-
const version = "2.0.0-alpha.
|
|
5101
|
+
const version = "2.0.0-alpha.6-dev+d848ba5";
|
|
4877
5102
|
|
|
4878
5103
|
/** @internal */
|
|
4879
5104
|
class _SharedContainer {
|
|
@@ -6764,7 +6989,7 @@
|
|
|
6764
6989
|
assertTrue(vnode_isTextVNode(vnode), 'Expecting Text Node.');
|
|
6765
6990
|
return vnode[TextVNodeProps.node];
|
|
6766
6991
|
};
|
|
6767
|
-
function vnode_toString(depth =
|
|
6992
|
+
function vnode_toString(depth = 20, offset = '', materialize = false, siblings = false) {
|
|
6768
6993
|
let vnode = this;
|
|
6769
6994
|
if (depth === 0) {
|
|
6770
6995
|
return '...';
|
|
@@ -6981,51 +7206,6 @@
|
|
|
6981
7206
|
throw qError(QError.invalidVNodeType, [type]);
|
|
6982
7207
|
};
|
|
6983
7208
|
const isElement = (node) => node && typeof node == 'object' && fastNodeType(node) === /** Node.ELEMENT_NODE* */ 1;
|
|
6984
|
-
/// These global variables are used to avoid creating new arrays for each call to `vnode_getPathToClosestDomNode`.
|
|
6985
|
-
const aPath = [];
|
|
6986
|
-
const bPath = [];
|
|
6987
|
-
const vnode_documentPosition = (a, b) => {
|
|
6988
|
-
if (a === b) {
|
|
6989
|
-
return 0;
|
|
6990
|
-
}
|
|
6991
|
-
let aDepth = -1;
|
|
6992
|
-
let bDepth = -1;
|
|
6993
|
-
while (a) {
|
|
6994
|
-
a = (aPath[++aDepth] = a)[VNodeProps.parent];
|
|
6995
|
-
}
|
|
6996
|
-
while (b) {
|
|
6997
|
-
b = (bPath[++bDepth] = b)[VNodeProps.parent];
|
|
6998
|
-
}
|
|
6999
|
-
while (aDepth >= 0 && bDepth >= 0) {
|
|
7000
|
-
a = aPath[aDepth];
|
|
7001
|
-
b = bPath[bDepth];
|
|
7002
|
-
if (a === b) {
|
|
7003
|
-
// if the nodes are the same, we need to check the next level.
|
|
7004
|
-
aDepth--;
|
|
7005
|
-
bDepth--;
|
|
7006
|
-
}
|
|
7007
|
-
else {
|
|
7008
|
-
// We found a difference so we need to scan nodes at this level.
|
|
7009
|
-
let cursor = b;
|
|
7010
|
-
do {
|
|
7011
|
-
cursor = vnode_getNextSibling(cursor);
|
|
7012
|
-
if (cursor === a) {
|
|
7013
|
-
return 1;
|
|
7014
|
-
}
|
|
7015
|
-
} while (cursor);
|
|
7016
|
-
cursor = b;
|
|
7017
|
-
do {
|
|
7018
|
-
cursor = vnode_getPreviousSibling(cursor);
|
|
7019
|
-
if (cursor === a) {
|
|
7020
|
-
return -1;
|
|
7021
|
-
}
|
|
7022
|
-
} while (cursor);
|
|
7023
|
-
// The node is not in the list of siblings, that means it must be disconnected.
|
|
7024
|
-
return 1;
|
|
7025
|
-
}
|
|
7026
|
-
}
|
|
7027
|
-
return aDepth < bDepth ? -1 : 1;
|
|
7028
|
-
};
|
|
7029
7209
|
/**
|
|
7030
7210
|
* Use this method to find the parent component for projection.
|
|
7031
7211
|
*
|
|
@@ -7052,11 +7232,7 @@
|
|
|
7052
7232
|
while (projectionDepth--) {
|
|
7053
7233
|
while (vHost &&
|
|
7054
7234
|
(vnode_isVirtualVNode(vHost) ? vnode_getProp(vHost, OnRenderProp, null) === null : true)) {
|
|
7055
|
-
const
|
|
7056
|
-
const qSlotParent = qSlotParentProp &&
|
|
7057
|
-
(typeof qSlotParentProp === 'string'
|
|
7058
|
-
? vnode_locate(rootVNode, qSlotParentProp)
|
|
7059
|
-
: qSlotParentProp);
|
|
7235
|
+
const qSlotParent = vnode_getProp(vHost, QSlotParent, (id) => vnode_locate(rootVNode, id));
|
|
7060
7236
|
const vProjectionParent = vnode_isVirtualVNode(vHost) && qSlotParent;
|
|
7061
7237
|
if (vProjectionParent) {
|
|
7062
7238
|
// We found a projection, so we need to go up one more level.
|
|
@@ -7965,14 +8141,14 @@
|
|
|
7965
8141
|
if (vnode_getProp(vNode, OnRenderProp, null) !== null) {
|
|
7966
8142
|
return vNode;
|
|
7967
8143
|
}
|
|
7968
|
-
|
|
7969
|
-
|
|
7970
|
-
|
|
7971
|
-
|
|
7972
|
-
|
|
7973
|
-
|
|
8144
|
+
vNode =
|
|
8145
|
+
vnode_getParent(vNode) ||
|
|
8146
|
+
// If virtual node, than it could be a slot so we need to read its parent.
|
|
8147
|
+
vnode_getProp(vNode, QSlotParent, this.$vnodeLocate$);
|
|
8148
|
+
}
|
|
8149
|
+
else {
|
|
8150
|
+
vNode = vnode_getParent(vNode);
|
|
7974
8151
|
}
|
|
7975
|
-
vNode = vnode_getParent(vNode);
|
|
7976
8152
|
}
|
|
7977
8153
|
return null;
|
|
7978
8154
|
}
|
|
@@ -8072,12 +8248,6 @@
|
|
|
8072
8248
|
|
|
8073
8249
|
/** There's [documentation](./serialization.md) */
|
|
8074
8250
|
const deserializedProxyMap = new WeakMap();
|
|
8075
|
-
const unwrapDeserializerProxy = (value) => {
|
|
8076
|
-
const unwrapped = typeof value === 'object' &&
|
|
8077
|
-
value !== null &&
|
|
8078
|
-
value[SERIALIZER_PROXY_UNWRAP];
|
|
8079
|
-
return unwrapped ? unwrapped : value;
|
|
8080
|
-
};
|
|
8081
8251
|
const isDeserializerProxy = (value) => {
|
|
8082
8252
|
return typeof value === 'object' && value !== null && SERIALIZER_PROXY_UNWRAP in value;
|
|
8083
8253
|
};
|
|
@@ -8130,14 +8300,14 @@
|
|
|
8130
8300
|
return value;
|
|
8131
8301
|
}
|
|
8132
8302
|
const container = this.$container$;
|
|
8133
|
-
|
|
8134
|
-
Reflect.set(target, property, propValue);
|
|
8135
|
-
this.$data$[idx] = undefined;
|
|
8136
|
-
this.$data$[idx + 1] = propValue;
|
|
8303
|
+
let propValue = allocate(container, typeId, value);
|
|
8137
8304
|
/** We stored the reference, so now we can inflate, allowing cycles. */
|
|
8138
8305
|
if (typeId >= TypeIds.Error) {
|
|
8139
|
-
inflate(container, propValue, typeId, value);
|
|
8306
|
+
propValue = inflate(container, propValue, typeId, value);
|
|
8140
8307
|
}
|
|
8308
|
+
Reflect.set(target, property, propValue);
|
|
8309
|
+
this.$data$[idx] = undefined;
|
|
8310
|
+
this.$data$[idx + 1] = propValue;
|
|
8141
8311
|
return propValue;
|
|
8142
8312
|
}
|
|
8143
8313
|
has(target, property) {
|
|
@@ -8176,7 +8346,7 @@
|
|
|
8176
8346
|
const inflate = (container, target, typeId, data) => {
|
|
8177
8347
|
if (typeId === undefined) {
|
|
8178
8348
|
// Already processed
|
|
8179
|
-
return;
|
|
8349
|
+
return target;
|
|
8180
8350
|
}
|
|
8181
8351
|
// restore the complex data, except for plain objects
|
|
8182
8352
|
if (typeId !== TypeIds.Object && Array.isArray(data)) {
|
|
@@ -8248,16 +8418,13 @@
|
|
|
8248
8418
|
case TypeIds.Store:
|
|
8249
8419
|
case TypeIds.StoreArray: {
|
|
8250
8420
|
const [value, flags, effects, storeEffect] = data;
|
|
8251
|
-
const
|
|
8252
|
-
|
|
8253
|
-
// First assign so it sets up the deep stores
|
|
8254
|
-
Object.assign(getStoreTarget(target), value);
|
|
8255
|
-
// Afterwards restore the effects so they don't get triggered
|
|
8421
|
+
const store = getOrCreateStore(value, flags, container);
|
|
8422
|
+
const storeHandler = getStoreHandler(store);
|
|
8256
8423
|
if (storeEffect) {
|
|
8257
8424
|
effects[STORE_ARRAY_PROP] = storeEffect;
|
|
8258
8425
|
}
|
|
8259
|
-
|
|
8260
|
-
|
|
8426
|
+
storeHandler.$effects$ = effects;
|
|
8427
|
+
target = store;
|
|
8261
8428
|
break;
|
|
8262
8429
|
}
|
|
8263
8430
|
case TypeIds.Signal: {
|
|
@@ -8384,6 +8551,7 @@
|
|
|
8384
8551
|
default:
|
|
8385
8552
|
throw qError(QError.serializeErrorNotImplemented, [typeId]);
|
|
8386
8553
|
}
|
|
8554
|
+
return target;
|
|
8387
8555
|
};
|
|
8388
8556
|
const _constants = [
|
|
8389
8557
|
undefined,
|
|
@@ -8449,9 +8617,9 @@
|
|
|
8449
8617
|
case TypeIds.ComputedSignal:
|
|
8450
8618
|
return new ComputedSignal(container, null);
|
|
8451
8619
|
case TypeIds.Store:
|
|
8452
|
-
return createStore(container, {}, 0);
|
|
8453
8620
|
case TypeIds.StoreArray:
|
|
8454
|
-
|
|
8621
|
+
// ignore allocate, we need to assign target while creating store
|
|
8622
|
+
return null;
|
|
8455
8623
|
case TypeIds.URLSearchParams:
|
|
8456
8624
|
return new URLSearchParams(value);
|
|
8457
8625
|
case TypeIds.FormData:
|
|
@@ -9313,15 +9481,15 @@
|
|
|
9313
9481
|
}
|
|
9314
9482
|
return output;
|
|
9315
9483
|
}
|
|
9316
|
-
function deserializeData(container, typeId,
|
|
9484
|
+
function deserializeData(container, typeId, value) {
|
|
9317
9485
|
if (typeId === undefined) {
|
|
9318
|
-
return
|
|
9486
|
+
return value;
|
|
9319
9487
|
}
|
|
9320
|
-
|
|
9488
|
+
let propValue = allocate(container, typeId, value);
|
|
9321
9489
|
if (typeId >= TypeIds.Error) {
|
|
9322
|
-
inflate(container,
|
|
9490
|
+
propValue = inflate(container, propValue, typeId, value);
|
|
9323
9491
|
}
|
|
9324
|
-
return
|
|
9492
|
+
return propValue;
|
|
9325
9493
|
}
|
|
9326
9494
|
function getObjectById(id, stateData) {
|
|
9327
9495
|
if (typeof id === 'string') {
|