@qwik.dev/core 2.0.0-beta.29 → 2.0.0-beta.30
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 +2 -2
- package/dist/core-internal.d.ts +32 -184
- package/dist/core.min.mjs +2 -1
- package/dist/core.mjs +810 -340
- package/dist/core.mjs.map +1 -1
- package/dist/core.prod.mjs +3692 -3249
- package/dist/loader/index.mjs +2 -2
- package/dist/loader/package.json +1 -1
- package/dist/optimizer.d.ts +8 -224
- package/dist/optimizer.mjs +1382 -1702
- package/dist/qwikloader.debug.js +10 -3
- package/dist/qwikloader.js +1 -1
- package/dist/server.d.ts +2 -181
- package/dist/server.mjs +23 -21
- package/dist/server.prod.mjs +337 -336
- package/dist/starters/adapters/netlify-edge/package.json +2 -2
- package/dist/testing/index.d.ts +4 -1
- package/dist/testing/index.mjs +1241 -696
- package/dist/testing/package.json +1 -1
- package/handlers.mjs +1 -1
- package/package.json +5 -6
- package/public.d.ts +1 -0
- package/bindings/qwik.darwin-arm64.node +0 -0
- package/bindings/qwik.linux-x64-gnu.node +0 -0
- package/bindings/qwik.wasm.mjs +0 -464
- package/bindings/qwik.win32-x64-msvc.node +0 -0
- package/bindings/qwik_wasm_bg.wasm +0 -0
- package/dist/starters/features/playwright/playwright-report/index.html +0 -22047
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.30-dev+5421ed4
|
|
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
|
|
@@ -13,7 +13,6 @@ import { p } from '@qwik.dev/core/preloader';
|
|
|
13
13
|
const g = globalThis;
|
|
14
14
|
const qDev = g.qDev !== false;
|
|
15
15
|
const qInspector = g.qInspector === true;
|
|
16
|
-
const qSerialize = g.qSerialize !== false;
|
|
17
16
|
const qDynamicPlatform = g.qDynamicPlatform !== false;
|
|
18
17
|
const qTest = g.qTest === true;
|
|
19
18
|
const qRuntimeQrl = g.qRuntimeQrl === true;
|
|
@@ -1007,7 +1006,7 @@ const COMMA = ',';
|
|
|
1007
1006
|
*
|
|
1008
1007
|
* @public
|
|
1009
1008
|
*/
|
|
1010
|
-
const version = "2.0.0-beta.
|
|
1009
|
+
const version = "2.0.0-beta.30-dev+5421ed4";
|
|
1011
1010
|
|
|
1012
1011
|
// keep this import from core/build so the cjs build works
|
|
1013
1012
|
const createPlatform = () => {
|
|
@@ -1876,6 +1875,9 @@ function getEffects$1(effects, prop) {
|
|
|
1876
1875
|
const directGetPropsProxyProp = (jsx, prop) => {
|
|
1877
1876
|
return (jsx.constProps && prop in jsx.constProps ? jsx.constProps[prop] : jsx.varProps[prop]);
|
|
1878
1877
|
};
|
|
1878
|
+
const _getProps = (props, prop) => {
|
|
1879
|
+
return _getVarProps(props)?.[prop] || _getConstProps(props)?.[prop] || null;
|
|
1880
|
+
};
|
|
1879
1881
|
/** Used by the optimizer for spread props operations @internal */
|
|
1880
1882
|
const _getVarProps = (props) => {
|
|
1881
1883
|
if (!props) {
|
|
@@ -2030,15 +2032,22 @@ const cleanupFn = (target, handleError) => {
|
|
|
2030
2032
|
cleanupFns = [];
|
|
2031
2033
|
target.$destroy$ = () => {
|
|
2032
2034
|
target.$destroy$ = null;
|
|
2033
|
-
|
|
2035
|
+
let cleanupPromises = null;
|
|
2034
2036
|
for (const fn of cleanupFns) {
|
|
2035
2037
|
try {
|
|
2036
|
-
fn();
|
|
2038
|
+
const result = fn();
|
|
2039
|
+
if (isPromise(result)) {
|
|
2040
|
+
(cleanupPromises ||= []).push(result.catch(handleError));
|
|
2041
|
+
}
|
|
2037
2042
|
}
|
|
2038
2043
|
catch (err) {
|
|
2039
2044
|
handleError(err);
|
|
2040
2045
|
}
|
|
2041
2046
|
}
|
|
2047
|
+
cleanupFns = null;
|
|
2048
|
+
if (cleanupPromises?.length) {
|
|
2049
|
+
return Promise.all(cleanupPromises).then(() => undefined);
|
|
2050
|
+
}
|
|
2042
2051
|
};
|
|
2043
2052
|
}
|
|
2044
2053
|
cleanupFns.push(fn);
|
|
@@ -2574,11 +2583,7 @@ class SerializerSignalImpl extends ComputedSignalImpl {
|
|
|
2574
2583
|
return;
|
|
2575
2584
|
}
|
|
2576
2585
|
throwIfQRLNotResolved(this.$computeQrl$);
|
|
2577
|
-
|
|
2578
|
-
let arg = this.$computeQrl$.resolved;
|
|
2579
|
-
if (typeof arg === 'function') {
|
|
2580
|
-
arg = arg();
|
|
2581
|
-
}
|
|
2586
|
+
const arg = untrack(this.$computeQrl$.resolved);
|
|
2582
2587
|
const { deserialize, initial } = arg;
|
|
2583
2588
|
const update = arg.update;
|
|
2584
2589
|
const currentValue = this.$untrackedValue$ === NEEDS_COMPUTATION ? initial : this.$untrackedValue$;
|
|
@@ -2586,6 +2591,8 @@ class SerializerSignalImpl extends ComputedSignalImpl {
|
|
|
2586
2591
|
? update?.(currentValue) || currentValue
|
|
2587
2592
|
: deserialize(currentValue), this, "." /* EffectProperty.VNODE */, this.$container$);
|
|
2588
2593
|
this.$didInitialize$ = true;
|
|
2594
|
+
// Needs to invalidate only after all possible Promise throws happened
|
|
2595
|
+
this.$flags$ &= -2 /* SignalFlags.INVALID */;
|
|
2589
2596
|
// 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.
|
|
2590
2597
|
const didChange = (this.$didInitialize$ && untrackedValue !== 'undefined') ||
|
|
2591
2598
|
untrackedValue !== this.$untrackedValue$;
|
|
@@ -3709,6 +3716,37 @@ const cleanupDestroyable = (destroyable) => {
|
|
|
3709
3716
|
destroyable.$destroy$ = null;
|
|
3710
3717
|
}
|
|
3711
3718
|
};
|
|
3719
|
+
const cleanupAsyncDestroyable = (destroyable, handleError) => {
|
|
3720
|
+
const pendingCleanup = destroyable.$destroyPromise$;
|
|
3721
|
+
if (pendingCleanup) {
|
|
3722
|
+
return pendingCleanup;
|
|
3723
|
+
}
|
|
3724
|
+
const cleanup = destroyable.$destroy$;
|
|
3725
|
+
if (!cleanup) {
|
|
3726
|
+
return;
|
|
3727
|
+
}
|
|
3728
|
+
destroyable.$destroy$ = null;
|
|
3729
|
+
try {
|
|
3730
|
+
const result = cleanup();
|
|
3731
|
+
if (isPromise(result)) {
|
|
3732
|
+
const cleanupPromise = Promise.resolve(result)
|
|
3733
|
+
.then(() => undefined, (err) => {
|
|
3734
|
+
handleError(err);
|
|
3735
|
+
})
|
|
3736
|
+
.finally(() => {
|
|
3737
|
+
if (destroyable.$destroyPromise$ === cleanupPromise) {
|
|
3738
|
+
destroyable.$destroyPromise$ = undefined;
|
|
3739
|
+
}
|
|
3740
|
+
});
|
|
3741
|
+
destroyable.$destroyPromise$ = cleanupPromise;
|
|
3742
|
+
return cleanupPromise;
|
|
3743
|
+
}
|
|
3744
|
+
}
|
|
3745
|
+
catch (err) {
|
|
3746
|
+
handleError(err);
|
|
3747
|
+
}
|
|
3748
|
+
return;
|
|
3749
|
+
};
|
|
3712
3750
|
|
|
3713
3751
|
/**
|
|
3714
3752
|
* This safely calls an event handler, handling errors and retrying on thrown Promises, and
|
|
@@ -3770,13 +3808,20 @@ function _run(event, element) {
|
|
|
3770
3808
|
return runEventHandlerQRL(qrlToRun, event, element, ctx);
|
|
3771
3809
|
}
|
|
3772
3810
|
|
|
3773
|
-
/**
|
|
3774
|
-
* Helper to get the next sibling of a VNode. Extracted to module scope to help V8 inline it
|
|
3775
|
-
* reliably.
|
|
3776
|
-
*/
|
|
3777
3811
|
function peekNextSibling(vCurrent) {
|
|
3778
3812
|
return vCurrent ? vCurrent.nextSibling : null;
|
|
3779
3813
|
}
|
|
3814
|
+
function getLevelBoundary(diffContext) {
|
|
3815
|
+
return diffContext.$vParent$ === diffContext.$vEndParent$ ? diffContext.$vEnd$ : null;
|
|
3816
|
+
}
|
|
3817
|
+
function getCurrentInsertBefore(diffContext) {
|
|
3818
|
+
return diffContext.$vCurrent$ || getLevelBoundary(diffContext);
|
|
3819
|
+
}
|
|
3820
|
+
function peekNextSiblingWithinBoundary(diffContext, vCurrent) {
|
|
3821
|
+
const nextSibling = peekNextSibling(vCurrent);
|
|
3822
|
+
const boundary = getLevelBoundary(diffContext);
|
|
3823
|
+
return nextSibling === boundary ? null : nextSibling;
|
|
3824
|
+
}
|
|
3780
3825
|
const _hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
3781
3826
|
/** Helper to set an attribute on a vnode. Extracted to module scope to avoid closure allocation. */
|
|
3782
3827
|
function setAttribute(journal, vnode, key, value, scopedStyleIdPrefix, originalValue) {
|
|
@@ -3798,6 +3843,8 @@ function createDiffContext(container, journal, cursor, scopedStyleIdPrefix) {
|
|
|
3798
3843
|
$vParent$: null,
|
|
3799
3844
|
$vCurrent$: null,
|
|
3800
3845
|
$vNewNode$: null,
|
|
3846
|
+
$vEnd$: null,
|
|
3847
|
+
$vEndParent$: null,
|
|
3801
3848
|
$vSiblings$: null,
|
|
3802
3849
|
$vSiblingsArray$: null,
|
|
3803
3850
|
$vSideBuffer$: null,
|
|
@@ -3819,10 +3866,34 @@ function createDiffContext(container, journal, cursor, scopedStyleIdPrefix) {
|
|
|
3819
3866
|
},
|
|
3820
3867
|
};
|
|
3821
3868
|
}
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3869
|
+
function prepareDiffContext(diffContext, container, journal, cursor, scopedStyleIdPrefix) {
|
|
3870
|
+
diffContext.$container$ = container;
|
|
3871
|
+
diffContext.$journal$ = journal;
|
|
3872
|
+
diffContext.$cursor$ = cursor;
|
|
3873
|
+
diffContext.$scopedStyleIdPrefix$ = scopedStyleIdPrefix;
|
|
3874
|
+
diffContext.$subscriptionData$.$const$.data.$scopedStyleIdPrefix$ = scopedStyleIdPrefix;
|
|
3875
|
+
diffContext.$subscriptionData$.$var$.data.$scopedStyleIdPrefix$ = scopedStyleIdPrefix;
|
|
3876
|
+
diffContext.$asyncQueue$.length = 0;
|
|
3877
|
+
diffContext.$asyncAttributePromises$.length = 0;
|
|
3878
|
+
}
|
|
3879
|
+
function getPreparedDiffContext(diffContext, container, journal, cursor, scopedStyleIdPrefix) {
|
|
3880
|
+
const reusableDiffContext = diffContext ?? createDiffContext(container, journal, cursor, scopedStyleIdPrefix);
|
|
3881
|
+
prepareDiffContext(reusableDiffContext, container, journal, cursor, scopedStyleIdPrefix);
|
|
3882
|
+
return reusableDiffContext;
|
|
3883
|
+
}
|
|
3884
|
+
const vnode_diff = (container, journal, jsxNode, vStartNode, cursor, scopedStyleIdPrefix, diffContext) => {
|
|
3885
|
+
return runDiff(getPreparedDiffContext(diffContext, container, journal, cursor, scopedStyleIdPrefix), jsxNode, vStartNode);
|
|
3886
|
+
};
|
|
3887
|
+
const vnode_diff_range = (container, journal, jsxNode, vParent, vCurrent, vEnd, cursor, scopedStyleIdPrefix,
|
|
3888
|
+
// Allows callers diffing into an empty known-new range to skip keyed-sibling materialization.
|
|
3889
|
+
forceCreationMode = false, diffContext) => {
|
|
3890
|
+
return runDiff(getPreparedDiffContext(diffContext, container, journal, cursor, scopedStyleIdPrefix), jsxNode, vParent, vCurrent, vEnd, forceCreationMode);
|
|
3891
|
+
};
|
|
3892
|
+
//////////////////////////////////////////////
|
|
3893
|
+
//////////////////////////////////////////////
|
|
3894
|
+
//////////////////////////////////////////////
|
|
3895
|
+
function runDiff(diffContext, jsxNode, vStartNode, vCurrent = vnode_getFirstChild(vStartNode), vEnd = null, forceCreationMode = false) {
|
|
3896
|
+
diff(diffContext, jsxNode, vStartNode, vCurrent, vEnd, forceCreationMode);
|
|
3826
3897
|
const result = drainAsyncQueue(diffContext);
|
|
3827
3898
|
// Cleanup diffContext after completion
|
|
3828
3899
|
if (isPromise(result)) {
|
|
@@ -3833,112 +3904,123 @@ const vnode_diff = (container, journal, jsxNode, vStartNode, cursor, scopedStyle
|
|
|
3833
3904
|
else {
|
|
3834
3905
|
cleanupDiffContext(diffContext);
|
|
3835
3906
|
}
|
|
3836
|
-
}
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
//////////////////////////////////////////////
|
|
3840
|
-
function diff(diffContext, jsxNode, vStartNode) {
|
|
3907
|
+
}
|
|
3908
|
+
function diff(diffContext, jsxNode, vStartNode, vCurrent = vnode_getFirstChild(vStartNode), vEnd = null, forceCreationMode = false) {
|
|
3909
|
+
const previousCreationMode = diffContext.$isCreationMode$;
|
|
3841
3910
|
isDev && assertFalse(vnode_isVNode(jsxNode), 'JSXNode should not be a VNode');
|
|
3842
3911
|
isDev && assertTrue(vnode_isVNode(vStartNode), 'vStartNode should be a VNode');
|
|
3912
|
+
diffContext.$isCreationMode$ = forceCreationMode || previousCreationMode;
|
|
3843
3913
|
diffContext.$vParent$ = vStartNode;
|
|
3844
3914
|
diffContext.$vNewNode$ = null;
|
|
3845
|
-
diffContext.$vCurrent$ =
|
|
3915
|
+
diffContext.$vCurrent$ = vCurrent;
|
|
3916
|
+
diffContext.$vEnd$ = vEnd;
|
|
3917
|
+
diffContext.$vEndParent$ = vStartNode;
|
|
3846
3918
|
stackPush(diffContext, jsxNode, true);
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
while (diffContext.$
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
if (
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
expectElement(diffContext, diffContext.$jsxValue$, type);
|
|
3867
|
-
const hasDangerousInnerHTML = (diffContext.$jsxValue$.constProps &&
|
|
3868
|
-
_hasOwnProperty.call(diffContext.$jsxValue$.constProps, dangerouslySetInnerHTML)) ||
|
|
3869
|
-
_hasOwnProperty.call(diffContext.$jsxValue$.varProps, dangerouslySetInnerHTML);
|
|
3870
|
-
if (hasDangerousInnerHTML) {
|
|
3871
|
-
expectNoChildren(diffContext, false);
|
|
3872
|
-
}
|
|
3873
|
-
else {
|
|
3874
|
-
descend(diffContext, diffContext.$jsxValue$.children, true);
|
|
3875
|
-
}
|
|
3876
|
-
}
|
|
3877
|
-
else if (typeof type === 'function') {
|
|
3878
|
-
if (type === Fragment) {
|
|
3879
|
-
expectNoTextNode(diffContext);
|
|
3880
|
-
expectVirtual(diffContext, "F" /* VirtualType.Fragment */, diffContext.$jsxValue$.key);
|
|
3881
|
-
descend(diffContext, diffContext.$jsxValue$.children, true);
|
|
3882
|
-
}
|
|
3883
|
-
else if (type === Slot) {
|
|
3919
|
+
try {
|
|
3920
|
+
if (diffContext.$vParent$.flags & 32 /* VNodeFlags.Deleted */) {
|
|
3921
|
+
// Ignore diff if the parent is deleted.
|
|
3922
|
+
return;
|
|
3923
|
+
}
|
|
3924
|
+
while (diffContext.$stack$.length) {
|
|
3925
|
+
while (diffContext.$jsxIdx$ < diffContext.$jsxCount$) {
|
|
3926
|
+
isDev &&
|
|
3927
|
+
assertFalse(diffContext.$vParent$ === diffContext.$vCurrent$, "Parent and current can't be the same");
|
|
3928
|
+
if (typeof diffContext.$jsxValue$ === 'string') {
|
|
3929
|
+
expectText(diffContext, diffContext.$jsxValue$);
|
|
3930
|
+
}
|
|
3931
|
+
else if (typeof diffContext.$jsxValue$ === 'number') {
|
|
3932
|
+
expectText(diffContext, String(diffContext.$jsxValue$));
|
|
3933
|
+
}
|
|
3934
|
+
else if (diffContext.$jsxValue$ && typeof diffContext.$jsxValue$ === 'object') {
|
|
3935
|
+
if (isJSXNode(diffContext.$jsxValue$)) {
|
|
3936
|
+
const type = diffContext.$jsxValue$.type;
|
|
3937
|
+
if (typeof type === 'string') {
|
|
3884
3938
|
expectNoTextNode(diffContext);
|
|
3885
|
-
|
|
3886
|
-
|
|
3939
|
+
expectElement(diffContext, diffContext.$jsxValue$, type);
|
|
3940
|
+
const hasDangerousInnerHTML = (diffContext.$jsxValue$.constProps &&
|
|
3941
|
+
_hasOwnProperty.call(diffContext.$jsxValue$.constProps, dangerouslySetInnerHTML)) ||
|
|
3942
|
+
_hasOwnProperty.call(diffContext.$jsxValue$.varProps, dangerouslySetInnerHTML);
|
|
3943
|
+
if (hasDangerousInnerHTML) {
|
|
3944
|
+
// Only clean up children for existing nodes; new nodes have no children yet
|
|
3945
|
+
if (!diffContext.$vNewNode$) {
|
|
3946
|
+
expectNoChildren(diffContext, false);
|
|
3947
|
+
}
|
|
3948
|
+
}
|
|
3949
|
+
else {
|
|
3887
3950
|
descend(diffContext, diffContext.$jsxValue$.children, true);
|
|
3888
3951
|
}
|
|
3889
3952
|
}
|
|
3890
|
-
else if (type ===
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3953
|
+
else if (typeof type === 'function') {
|
|
3954
|
+
if (type === Fragment) {
|
|
3955
|
+
expectNoTextNode(diffContext);
|
|
3956
|
+
expectVirtual(diffContext, "F" /* VirtualType.Fragment */, diffContext.$jsxValue$.key);
|
|
3957
|
+
descend(diffContext, diffContext.$jsxValue$.children, true);
|
|
3958
|
+
}
|
|
3959
|
+
else if (type === Slot) {
|
|
3960
|
+
expectNoTextNode(diffContext);
|
|
3961
|
+
if (!expectSlot(diffContext)) {
|
|
3962
|
+
// nothing to project, so try to render the Slot default content.
|
|
3963
|
+
descend(diffContext, diffContext.$jsxValue$.children, true);
|
|
3964
|
+
}
|
|
3965
|
+
}
|
|
3966
|
+
else if (type === Projection) {
|
|
3967
|
+
expectProjection(diffContext);
|
|
3968
|
+
descend(diffContext, diffContext.$jsxValue$.children, true,
|
|
3969
|
+
// special case for projection, we don't want to expect no children
|
|
3970
|
+
// because the projection's children are not removed
|
|
3971
|
+
false);
|
|
3972
|
+
}
|
|
3973
|
+
else if (type === SSRComment) {
|
|
3974
|
+
expectNoMore(diffContext);
|
|
3975
|
+
}
|
|
3976
|
+
else if (type === SSRRaw) {
|
|
3977
|
+
expectNoMore(diffContext);
|
|
3978
|
+
}
|
|
3979
|
+
else {
|
|
3980
|
+
// Must be a component
|
|
3981
|
+
expectNoTextNode(diffContext);
|
|
3982
|
+
expectComponent(diffContext, type);
|
|
3983
|
+
}
|
|
3899
3984
|
}
|
|
3900
|
-
|
|
3901
|
-
|
|
3985
|
+
}
|
|
3986
|
+
else if (Array.isArray(diffContext.$jsxValue$)) {
|
|
3987
|
+
descend(diffContext, diffContext.$jsxValue$, false);
|
|
3988
|
+
}
|
|
3989
|
+
else if (isSignal(diffContext.$jsxValue$)) {
|
|
3990
|
+
expectVirtual(diffContext, "S" /* VirtualType.WrappedSignal */, null);
|
|
3991
|
+
const unwrappedSignal = diffContext.$jsxValue$ instanceof WrappedSignalImpl
|
|
3992
|
+
? diffContext.$jsxValue$.$unwrapIfSignal$()
|
|
3993
|
+
: diffContext.$jsxValue$;
|
|
3994
|
+
const signals = diffContext.$vCurrent$?.[_EFFECT_BACK_REF]?.get("." /* EffectProperty.VNODE */)?.backRef;
|
|
3995
|
+
let hasUnwrappedSignal = signals?.has(unwrappedSignal);
|
|
3996
|
+
if (signals && unwrappedSignal instanceof WrappedSignalImpl) {
|
|
3997
|
+
hasUnwrappedSignal = containsWrappedSignal(signals, unwrappedSignal);
|
|
3902
3998
|
}
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
expectComponent(diffContext, type);
|
|
3999
|
+
if (!hasUnwrappedSignal) {
|
|
4000
|
+
const vHost = (diffContext.$vNewNode$ || diffContext.$vCurrent$);
|
|
4001
|
+
descend(diffContext, resolveSignalAndDescend(diffContext, () => trackSignalAndAssignHost(unwrappedSignal, vHost, "." /* EffectProperty.VNODE */, diffContext.$container$)), true);
|
|
3907
4002
|
}
|
|
3908
4003
|
}
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
}
|
|
3913
|
-
else if (isSignal(diffContext.$jsxValue$)) {
|
|
3914
|
-
expectVirtual(diffContext, "S" /* VirtualType.WrappedSignal */, null);
|
|
3915
|
-
const unwrappedSignal = diffContext.$jsxValue$ instanceof WrappedSignalImpl
|
|
3916
|
-
? diffContext.$jsxValue$.$unwrapIfSignal$()
|
|
3917
|
-
: diffContext.$jsxValue$;
|
|
3918
|
-
const signals = diffContext.$vCurrent$?.[_EFFECT_BACK_REF]?.get("." /* EffectProperty.VNODE */)?.backRef;
|
|
3919
|
-
let hasUnwrappedSignal = signals?.has(unwrappedSignal);
|
|
3920
|
-
if (signals && unwrappedSignal instanceof WrappedSignalImpl) {
|
|
3921
|
-
hasUnwrappedSignal = containsWrappedSignal(signals, unwrappedSignal);
|
|
3922
|
-
}
|
|
3923
|
-
if (!hasUnwrappedSignal) {
|
|
3924
|
-
const vHost = (diffContext.$vNewNode$ || diffContext.$vCurrent$);
|
|
3925
|
-
descend(diffContext, resolveSignalAndDescend(diffContext, () => trackSignalAndAssignHost(unwrappedSignal, vHost, "." /* EffectProperty.VNODE */, diffContext.$container$)), true);
|
|
4004
|
+
else if (isPromise(diffContext.$jsxValue$)) {
|
|
4005
|
+
expectVirtual(diffContext, "A" /* VirtualType.Awaited */, null);
|
|
4006
|
+
diffContext.$asyncQueue$.push(diffContext.$jsxValue$, diffContext.$vNewNode$ || diffContext.$vCurrent$);
|
|
3926
4007
|
}
|
|
3927
4008
|
}
|
|
3928
|
-
else if (
|
|
3929
|
-
|
|
3930
|
-
diffContext.$asyncQueue$.push(diffContext.$jsxValue$, diffContext.$vNewNode$ || diffContext.$vCurrent$);
|
|
4009
|
+
else if (diffContext.$jsxValue$ === SkipRender) {
|
|
4010
|
+
// do nothing, we are skipping this node
|
|
3931
4011
|
}
|
|
4012
|
+
else {
|
|
4013
|
+
expectText(diffContext, '');
|
|
4014
|
+
}
|
|
4015
|
+
advance(diffContext);
|
|
3932
4016
|
}
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
}
|
|
3937
|
-
advance(diffContext);
|
|
4017
|
+
expectNoMore(diffContext);
|
|
4018
|
+
cleanupSideBuffer(diffContext);
|
|
4019
|
+
ascend(diffContext);
|
|
3938
4020
|
}
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
4021
|
+
}
|
|
4022
|
+
finally {
|
|
4023
|
+
diffContext.$isCreationMode$ = previousCreationMode;
|
|
3942
4024
|
}
|
|
3943
4025
|
}
|
|
3944
4026
|
function resolveSignalAndDescend(diffContext, fn) {
|
|
@@ -3978,7 +4060,7 @@ function advance(diffContext) {
|
|
|
3978
4060
|
diffContext.$vNewNode$ = null;
|
|
3979
4061
|
}
|
|
3980
4062
|
else {
|
|
3981
|
-
diffContext.$vCurrent$ =
|
|
4063
|
+
diffContext.$vCurrent$ = peekNextSiblingWithinBoundary(diffContext, diffContext.$vCurrent$);
|
|
3982
4064
|
}
|
|
3983
4065
|
}
|
|
3984
4066
|
/**
|
|
@@ -4068,11 +4150,10 @@ function stackPush(diffContext, children, descendVNode) {
|
|
|
4068
4150
|
}
|
|
4069
4151
|
function getInsertBefore(diffContext) {
|
|
4070
4152
|
if (diffContext.$vNewNode$) {
|
|
4071
|
-
return diffContext
|
|
4072
|
-
}
|
|
4073
|
-
else {
|
|
4074
|
-
return peekNextSibling(diffContext.$vCurrent$);
|
|
4153
|
+
return getCurrentInsertBefore(diffContext);
|
|
4075
4154
|
}
|
|
4155
|
+
return (peekNextSiblingWithinBoundary(diffContext, diffContext.$vCurrent$) ||
|
|
4156
|
+
getLevelBoundary(diffContext));
|
|
4076
4157
|
}
|
|
4077
4158
|
/////////////////////////////////////////////////////////////////////////////
|
|
4078
4159
|
/////////////////////////////////////////////////////////////////////////////
|
|
@@ -4163,7 +4244,7 @@ function expectSlot(diffContext) {
|
|
|
4163
4244
|
vHost && vnode_setProp(vHost, slotNameKey, diffContext.$vNewNode$);
|
|
4164
4245
|
isDev &&
|
|
4165
4246
|
vnode_setProp(diffContext.$vNewNode$, DEBUG_TYPE, "P" /* VirtualType.Projection */); // Nothing to project, so render content of the slot.
|
|
4166
|
-
vnode_insertBefore(diffContext.$journal$, diffContext.$vParent$, diffContext.$vNewNode$,
|
|
4247
|
+
vnode_insertBefore(diffContext.$journal$, diffContext.$vParent$, diffContext.$vNewNode$, getInsertBefore(diffContext));
|
|
4167
4248
|
return false;
|
|
4168
4249
|
}
|
|
4169
4250
|
else if (vProjectedNode === diffContext.$vCurrent$) ;
|
|
@@ -4176,7 +4257,7 @@ function expectSlot(diffContext) {
|
|
|
4176
4257
|
isDev &&
|
|
4177
4258
|
vnode_setProp(diffContext.$vNewNode$, DEBUG_TYPE, "P" /* VirtualType.Projection */);
|
|
4178
4259
|
vnode_inflateProjectionTrailingText(diffContext.$journal$, diffContext.$vNewNode$);
|
|
4179
|
-
vnode_insertBefore(diffContext.$journal$, diffContext.$vParent$, diffContext.$vNewNode$,
|
|
4260
|
+
vnode_insertBefore(diffContext.$journal$, diffContext.$vParent$, diffContext.$vNewNode$, getInsertBefore(diffContext));
|
|
4180
4261
|
// If we moved from a q:template and it's now empty, remove it
|
|
4181
4262
|
if (oldParent &&
|
|
4182
4263
|
vnode_isElementVNode(oldParent) &&
|
|
@@ -4258,12 +4339,13 @@ function expectNoChildren(diffContext, removeDOM = true) {
|
|
|
4258
4339
|
}
|
|
4259
4340
|
/** Expect no more nodes - Any nodes which are still at cursor, need to be removed. */
|
|
4260
4341
|
function expectNoMore(diffContext) {
|
|
4342
|
+
const boundary = getLevelBoundary(diffContext);
|
|
4261
4343
|
isDev &&
|
|
4262
4344
|
assertFalse(diffContext.$vParent$ === diffContext.$vCurrent$, "Parent and current can't be the same");
|
|
4263
|
-
if (diffContext.$vCurrent$ !== null) {
|
|
4264
|
-
while (diffContext.$vCurrent$) {
|
|
4345
|
+
if (diffContext.$vCurrent$ !== null && diffContext.$vCurrent$ !== boundary) {
|
|
4346
|
+
while (diffContext.$vCurrent$ && diffContext.$vCurrent$ !== boundary) {
|
|
4265
4347
|
const toRemove = diffContext.$vCurrent$;
|
|
4266
|
-
diffContext.$vCurrent$ =
|
|
4348
|
+
diffContext.$vCurrent$ = peekNextSiblingWithinBoundary(diffContext, diffContext.$vCurrent$);
|
|
4267
4349
|
if (diffContext.$vParent$ === toRemove.parent) {
|
|
4268
4350
|
cleanup(diffContext.$container$, diffContext.$journal$, toRemove, diffContext.$cursor$);
|
|
4269
4351
|
// If we are diffing projection than the parent is not the parent of the node.
|
|
@@ -4276,12 +4358,52 @@ function expectNoMore(diffContext) {
|
|
|
4276
4358
|
function expectNoTextNode(diffContext) {
|
|
4277
4359
|
if (diffContext.$vCurrent$ !== null && vnode_isTextVNode(diffContext.$vCurrent$)) {
|
|
4278
4360
|
const toRemove = diffContext.$vCurrent$;
|
|
4279
|
-
diffContext.$vCurrent$ =
|
|
4361
|
+
diffContext.$vCurrent$ = peekNextSiblingWithinBoundary(diffContext, diffContext.$vCurrent$);
|
|
4280
4362
|
vnode_remove(diffContext.$journal$, diffContext.$vParent$, toRemove, true);
|
|
4281
4363
|
}
|
|
4282
4364
|
}
|
|
4365
|
+
function applyRef(value, element, currentFile) {
|
|
4366
|
+
if (isSignal(value)) {
|
|
4367
|
+
value.value = element;
|
|
4368
|
+
return true;
|
|
4369
|
+
}
|
|
4370
|
+
if (typeof value === 'function') {
|
|
4371
|
+
value(element);
|
|
4372
|
+
return true;
|
|
4373
|
+
}
|
|
4374
|
+
if (value == null) {
|
|
4375
|
+
return true;
|
|
4376
|
+
}
|
|
4377
|
+
throw qError(15 /* QError.invalidRefValue */, [currentFile]);
|
|
4378
|
+
}
|
|
4379
|
+
function resolveSignalValue(container, vHost, key, signal, subscriptionData) {
|
|
4380
|
+
return retryOnPromise(() => trackSignalAndAssignHost(signal, vHost, key, container, subscriptionData));
|
|
4381
|
+
}
|
|
4382
|
+
function queueConstAttributePromise(diffContext, element, key, value, isSvg) {
|
|
4383
|
+
const scopedStyleIdPrefix = diffContext.$scopedStyleIdPrefix$;
|
|
4384
|
+
const attributePromise = value.then((resolvedValue) => directSetAttribute(element, key, serializeAttribute(key, resolvedValue, scopedStyleIdPrefix), isSvg));
|
|
4385
|
+
diffContext.$asyncAttributePromises$.push(attributePromise);
|
|
4386
|
+
}
|
|
4387
|
+
function applyConstInnerHtml(element, value) {
|
|
4388
|
+
if (value) {
|
|
4389
|
+
element.innerHTML = String(value);
|
|
4390
|
+
element.setAttribute(QContainerAttr, "html" /* QContainerValue.HTML */);
|
|
4391
|
+
}
|
|
4392
|
+
}
|
|
4393
|
+
function applyConstTextareaValue(element, value, currentFile) {
|
|
4394
|
+
if (value && typeof value !== 'string') {
|
|
4395
|
+
if (isDev) {
|
|
4396
|
+
throw qError(23 /* QError.wrongTextareaValue */, [currentFile, value]);
|
|
4397
|
+
}
|
|
4398
|
+
return true;
|
|
4399
|
+
}
|
|
4400
|
+
element.value = escapeHTML(value || '');
|
|
4401
|
+
return true;
|
|
4402
|
+
}
|
|
4283
4403
|
function createNewElement(diffContext, jsx, elementName, currentFile) {
|
|
4284
4404
|
const element = createElementWithNamespace(diffContext, elementName);
|
|
4405
|
+
const vHost = diffContext.$vNewNode$;
|
|
4406
|
+
const isSvg = (vHost.flags & 512 /* VNodeFlags.NS_svg */) !== 0;
|
|
4285
4407
|
const { constProps } = jsx;
|
|
4286
4408
|
if (constProps) {
|
|
4287
4409
|
// Const props are, well, constant, they will never change!
|
|
@@ -4290,54 +4412,29 @@ function createNewElement(diffContext, jsx, elementName, currentFile) {
|
|
|
4290
4412
|
for (const key in constProps) {
|
|
4291
4413
|
let value = constProps[key];
|
|
4292
4414
|
if (isHtmlAttributeAnEventName(key)) {
|
|
4293
|
-
registerEventHandlers(key, value, element,
|
|
4415
|
+
registerEventHandlers(key, value, element, vHost, diffContext);
|
|
4294
4416
|
continue;
|
|
4295
4417
|
}
|
|
4296
|
-
if (key === 'ref') {
|
|
4297
|
-
|
|
4298
|
-
value.value = element;
|
|
4299
|
-
continue;
|
|
4300
|
-
}
|
|
4301
|
-
else if (typeof value === 'function') {
|
|
4302
|
-
value(element);
|
|
4303
|
-
continue;
|
|
4304
|
-
}
|
|
4305
|
-
else if (value == null) {
|
|
4306
|
-
continue;
|
|
4307
|
-
}
|
|
4308
|
-
else {
|
|
4309
|
-
throw qError(15 /* QError.invalidRefValue */, [currentFile]);
|
|
4310
|
-
}
|
|
4418
|
+
if (key === 'ref' && applyRef(value, element, currentFile)) {
|
|
4419
|
+
continue;
|
|
4311
4420
|
}
|
|
4312
4421
|
if (isSignal(value)) {
|
|
4313
|
-
|
|
4314
|
-
const signal = value;
|
|
4315
|
-
value = retryOnPromise(() => trackSignalAndAssignHost(signal, vHost, key, diffContext.$container$, diffContext.$subscriptionData$.$const$));
|
|
4422
|
+
value = resolveSignalValue(diffContext.$container$, diffContext.$vNewNode$, key, value, diffContext.$subscriptionData$.$const$);
|
|
4316
4423
|
}
|
|
4317
4424
|
if (isPromise(value)) {
|
|
4318
|
-
|
|
4319
|
-
const attributePromise = value.then((resolvedValue) => directSetAttribute(element, key, serializeAttribute(key, resolvedValue, diffContext.$scopedStyleIdPrefix$), (vHost.flags & 512 /* VNodeFlags.NS_svg */) !== 0));
|
|
4320
|
-
diffContext.$asyncAttributePromises$.push(attributePromise);
|
|
4425
|
+
queueConstAttributePromise(diffContext, element, key, value, isSvg);
|
|
4321
4426
|
continue;
|
|
4322
4427
|
}
|
|
4323
4428
|
if (key === dangerouslySetInnerHTML) {
|
|
4324
|
-
|
|
4325
|
-
element.innerHTML = String(value);
|
|
4326
|
-
element.setAttribute(QContainerAttr, "html" /* QContainerValue.HTML */);
|
|
4327
|
-
}
|
|
4429
|
+
applyConstInnerHtml(element, value);
|
|
4328
4430
|
continue;
|
|
4329
4431
|
}
|
|
4330
|
-
if (elementName === 'textarea' &&
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
throw qError(23 /* QError.wrongTextareaValue */, [currentFile, value]);
|
|
4334
|
-
}
|
|
4335
|
-
continue;
|
|
4336
|
-
}
|
|
4337
|
-
element.value = escapeHTML(value || '');
|
|
4432
|
+
if (elementName === 'textarea' &&
|
|
4433
|
+
key === 'value' &&
|
|
4434
|
+
applyConstTextareaValue(element, value, currentFile)) {
|
|
4338
4435
|
continue;
|
|
4339
4436
|
}
|
|
4340
|
-
directSetAttribute(element, key, serializeAttribute(key, value, diffContext.$scopedStyleIdPrefix$),
|
|
4437
|
+
directSetAttribute(element, key, serializeAttribute(key, value, diffContext.$scopedStyleIdPrefix$), isSvg);
|
|
4341
4438
|
}
|
|
4342
4439
|
}
|
|
4343
4440
|
const key = jsx.key;
|
|
@@ -4352,7 +4449,7 @@ function createNewElement(diffContext, jsx, elementName, currentFile) {
|
|
|
4352
4449
|
element.setAttribute('class', diffContext.$scopedStyleIdPrefix$);
|
|
4353
4450
|
}
|
|
4354
4451
|
}
|
|
4355
|
-
vnode_insertElementBefore(diffContext.$journal$, diffContext.$vParent$, diffContext.$vNewNode$, diffContext
|
|
4452
|
+
vnode_insertElementBefore(diffContext.$journal$, diffContext.$vParent$, diffContext.$vNewNode$, getCurrentInsertBefore(diffContext));
|
|
4356
4453
|
}
|
|
4357
4454
|
function registerEventHandlers(key, value, element, vnode, diffContext) {
|
|
4358
4455
|
const scopedKebabName = key.slice(2);
|
|
@@ -4374,13 +4471,11 @@ function registerEventHandlers(key, value, element, vnode, diffContext) {
|
|
|
4374
4471
|
}
|
|
4375
4472
|
}
|
|
4376
4473
|
if (handlers.length > 0) {
|
|
4377
|
-
(element._qDispatch ||= {})[scopedKebabName] = handlers;
|
|
4474
|
+
(element._qDispatch ||= {})[scopedKebabName] = handlers.length === 1 ? handlers[0] : handlers;
|
|
4378
4475
|
}
|
|
4379
4476
|
}
|
|
4380
4477
|
else if (value) {
|
|
4381
|
-
(element._qDispatch ||= {})[scopedKebabName] =
|
|
4382
|
-
runEventHandlerQRL.bind(null, value),
|
|
4383
|
-
];
|
|
4478
|
+
(element._qDispatch ||= {})[scopedKebabName] = runEventHandlerQRL.bind(null, value);
|
|
4384
4479
|
}
|
|
4385
4480
|
// window and document events need attrs so qwik loader can find them
|
|
4386
4481
|
// TODO only do these when not already present
|
|
@@ -4485,17 +4580,9 @@ const patchProperty = (diffContext, vnode, key, value, currentFile) => {
|
|
|
4485
4580
|
const originalValue = value;
|
|
4486
4581
|
if (key === 'ref') {
|
|
4487
4582
|
const element = vnode.node;
|
|
4488
|
-
if (
|
|
4489
|
-
value.value = element;
|
|
4583
|
+
if (applyRef(value, element, currentFile)) {
|
|
4490
4584
|
return;
|
|
4491
4585
|
}
|
|
4492
|
-
else if (typeof value === 'function') {
|
|
4493
|
-
value(element);
|
|
4494
|
-
return;
|
|
4495
|
-
}
|
|
4496
|
-
else {
|
|
4497
|
-
throw qError(15 /* QError.invalidRefValue */, [currentFile]);
|
|
4498
|
-
}
|
|
4499
4586
|
}
|
|
4500
4587
|
const currentEffect = vnode[_EFFECT_BACK_REF]?.get(key);
|
|
4501
4588
|
if (isSignal(value)) {
|
|
@@ -4507,7 +4594,7 @@ const patchProperty = (diffContext, vnode, key, value, currentFile) => {
|
|
|
4507
4594
|
clearEffectSubscription(diffContext.$container$, currentEffect);
|
|
4508
4595
|
}
|
|
4509
4596
|
const vHost = vnode;
|
|
4510
|
-
value =
|
|
4597
|
+
value = resolveSignalValue(diffContext.$container$, vHost, key, unwrappedSignal, diffContext.$subscriptionData$.$var$);
|
|
4511
4598
|
}
|
|
4512
4599
|
else {
|
|
4513
4600
|
if (currentEffect) {
|
|
@@ -4548,8 +4635,9 @@ function retrieveChildWithKey(diffContext, nodeName, key) {
|
|
|
4548
4635
|
// it is not materialized; so materialize it.
|
|
4549
4636
|
diffContext.$vSiblings$ = new Map();
|
|
4550
4637
|
diffContext.$vSiblingsArray$ = [];
|
|
4638
|
+
const boundary = getLevelBoundary(diffContext);
|
|
4551
4639
|
let vNode = diffContext.$vCurrent$;
|
|
4552
|
-
while (vNode) {
|
|
4640
|
+
while (vNode && vNode !== boundary) {
|
|
4553
4641
|
const name = vnode_isElementVNode(vNode) ? vnode_getElementName(vNode) : null;
|
|
4554
4642
|
const vKey = getKey(vNode) ||
|
|
4555
4643
|
getComponentHash(vNode, diffContext.$container$.$getObjectById$);
|
|
@@ -4608,8 +4696,9 @@ function collectSideBufferSiblings(diffContext, targetNode) {
|
|
|
4608
4696
|
return;
|
|
4609
4697
|
}
|
|
4610
4698
|
// Walk from vCurrent up to the target node and collect all keyed siblings
|
|
4699
|
+
const boundary = getLevelBoundary(diffContext);
|
|
4611
4700
|
let vNode = diffContext.$vCurrent$;
|
|
4612
|
-
while (vNode && vNode !== targetNode) {
|
|
4701
|
+
while (vNode && vNode !== targetNode && vNode !== boundary) {
|
|
4613
4702
|
const name = vnode_isElementVNode(vNode) ? vnode_getElementName(vNode) : null;
|
|
4614
4703
|
const vKey = getKey(vNode) ||
|
|
4615
4704
|
getComponentHash(vNode, diffContext.$container$.$getObjectById$);
|
|
@@ -4652,7 +4741,7 @@ function moveOrCreateKeyedNode(diffContext, nodeName, lookupKey, sideBufferKey,
|
|
|
4652
4741
|
diffContext.$vNewNode$ = retrieveChildWithKey(diffContext, nodeName, lookupKey);
|
|
4653
4742
|
if (diffContext.$vNewNode$) {
|
|
4654
4743
|
if (!sideBufferKey) {
|
|
4655
|
-
vnode_insertBefore(diffContext.$journal$, parentForInsert, diffContext.$vNewNode$, diffContext
|
|
4744
|
+
vnode_insertBefore(diffContext.$journal$, parentForInsert, diffContext.$vNewNode$, getCurrentInsertBefore(diffContext));
|
|
4656
4745
|
}
|
|
4657
4746
|
diffContext.$vCurrent$ = diffContext.$vNewNode$;
|
|
4658
4747
|
diffContext.$vNewNode$ = null;
|
|
@@ -4679,7 +4768,7 @@ function moveOrCreateKeyedNode(diffContext, nodeName, lookupKey, sideBufferKey,
|
|
|
4679
4768
|
}
|
|
4680
4769
|
// Only move if the node is not already in the correct position
|
|
4681
4770
|
if (buffered !== diffContext.$vCurrent$) {
|
|
4682
|
-
vnode_insertBefore(diffContext.$journal$, parentForInsert, buffered, diffContext
|
|
4771
|
+
vnode_insertBefore(diffContext.$journal$, parentForInsert, buffered, getCurrentInsertBefore(diffContext));
|
|
4683
4772
|
}
|
|
4684
4773
|
diffContext.$vCurrent$ = buffered;
|
|
4685
4774
|
diffContext.$vNewNode$ = null;
|
|
@@ -4701,13 +4790,13 @@ function expectVirtual(diffContext, type, jsxKey) {
|
|
|
4701
4790
|
}
|
|
4702
4791
|
// For fragments without a key, always create a new virtual node (ensures rerender semantics)
|
|
4703
4792
|
if (jsxKey === null || diffContext.$isCreationMode$) {
|
|
4704
|
-
vnode_insertVirtualBefore(diffContext.$journal$, diffContext.$vParent$, (diffContext.$vNewNode$ = vnode_newVirtual()),
|
|
4793
|
+
vnode_insertVirtualBefore(diffContext.$journal$, diffContext.$vParent$, (diffContext.$vNewNode$ = vnode_newVirtual()), getInsertBefore(diffContext));
|
|
4705
4794
|
diffContext.$vNewNode$.key = jsxKey;
|
|
4706
4795
|
isDev && vnode_setProp(diffContext.$vNewNode$, DEBUG_TYPE, type);
|
|
4707
4796
|
return;
|
|
4708
4797
|
}
|
|
4709
4798
|
if (moveOrCreateKeyedNode(diffContext, null, jsxKey, getSideBufferKey(null, jsxKey), diffContext.$vParent$, true)) {
|
|
4710
|
-
vnode_insertVirtualBefore(diffContext.$journal$, diffContext.$vParent$, (diffContext.$vNewNode$ = vnode_newVirtual()),
|
|
4799
|
+
vnode_insertVirtualBefore(diffContext.$journal$, diffContext.$vParent$, (diffContext.$vNewNode$ = vnode_newVirtual()), getInsertBefore(diffContext));
|
|
4711
4800
|
diffContext.$vNewNode$.key = jsxKey;
|
|
4712
4801
|
isDev && vnode_setProp(diffContext.$vNewNode$, DEBUG_TYPE, type);
|
|
4713
4802
|
}
|
|
@@ -4809,7 +4898,7 @@ function insertNewComponent(diffContext, host, componentQRL, jsxProps) {
|
|
|
4809
4898
|
if (host) {
|
|
4810
4899
|
clearAllEffects(diffContext.$container$, host);
|
|
4811
4900
|
}
|
|
4812
|
-
vnode_insertVirtualBefore(diffContext.$journal$, diffContext.$vParent$, (diffContext.$vNewNode$ = vnode_newVirtual()),
|
|
4901
|
+
vnode_insertVirtualBefore(diffContext.$journal$, diffContext.$vParent$, (diffContext.$vNewNode$ = vnode_newVirtual()), getInsertBefore(diffContext));
|
|
4813
4902
|
const jsxNode = diffContext.$jsxValue$;
|
|
4814
4903
|
isDev && vnode_setProp(diffContext.$vNewNode$, DEBUG_TYPE, "C" /* VirtualType.Component */);
|
|
4815
4904
|
vnode_setProp(diffContext.$vNewNode$, OnRenderProp, componentQRL);
|
|
@@ -4817,7 +4906,7 @@ function insertNewComponent(diffContext, host, componentQRL, jsxProps) {
|
|
|
4817
4906
|
diffContext.$vNewNode$.key = jsxNode.key;
|
|
4818
4907
|
}
|
|
4819
4908
|
function insertNewInlineComponent(diffContext) {
|
|
4820
|
-
vnode_insertVirtualBefore(diffContext.$journal$, diffContext.$vParent$, (diffContext.$vNewNode$ = vnode_newVirtual()),
|
|
4909
|
+
vnode_insertVirtualBefore(diffContext.$journal$, diffContext.$vParent$, (diffContext.$vNewNode$ = vnode_newVirtual()), getInsertBefore(diffContext));
|
|
4821
4910
|
const jsxNode = diffContext.$jsxValue$;
|
|
4822
4911
|
isDev &&
|
|
4823
4912
|
vnode_setProp(diffContext.$vNewNode$, DEBUG_TYPE, "I" /* VirtualType.InlineComponent */);
|
|
@@ -4837,7 +4926,7 @@ function expectText(diffContext, text) {
|
|
|
4837
4926
|
return;
|
|
4838
4927
|
}
|
|
4839
4928
|
}
|
|
4840
|
-
vnode_insertElementBefore(diffContext.$journal$, diffContext.$vParent$, (diffContext.$vNewNode$ = vnode_newText((import.meta.env.TEST ? diffContext.$container$.document : document).createTextNode(text), text)), diffContext
|
|
4929
|
+
vnode_insertElementBefore(diffContext.$journal$, diffContext.$vParent$, (diffContext.$vNewNode$ = vnode_newText((import.meta.env.TEST ? diffContext.$container$.document : document).createTextNode(text), text)), getCurrentInsertBefore(diffContext));
|
|
4841
4930
|
}
|
|
4842
4931
|
/**
|
|
4843
4932
|
* Retrieve the key from the VNode.
|
|
@@ -5160,6 +5249,221 @@ function containsWrappedSignal(data, signal) {
|
|
|
5160
5249
|
return false;
|
|
5161
5250
|
}
|
|
5162
5251
|
|
|
5252
|
+
function collectChildren(first, last = null) {
|
|
5253
|
+
const children = [];
|
|
5254
|
+
let child = first;
|
|
5255
|
+
while (child) {
|
|
5256
|
+
children.push(child);
|
|
5257
|
+
if (child === last) {
|
|
5258
|
+
break;
|
|
5259
|
+
}
|
|
5260
|
+
child = child.nextSibling;
|
|
5261
|
+
}
|
|
5262
|
+
return children;
|
|
5263
|
+
}
|
|
5264
|
+
function renderKeyedRow(item, index, key, renderItem) {
|
|
5265
|
+
const jsx = renderItem(item, index);
|
|
5266
|
+
if (isDev && !isJSXNode(jsx)) {
|
|
5267
|
+
throw new Error('Each item$ must return a single JSX node');
|
|
5268
|
+
}
|
|
5269
|
+
jsx.key = key;
|
|
5270
|
+
return jsx;
|
|
5271
|
+
}
|
|
5272
|
+
function buildJsxRange(items, nextKeys, keyOf, renderItem, start, end) {
|
|
5273
|
+
const jsxItems = new Array(end - start + 1);
|
|
5274
|
+
for (let i = start; i <= end; i++) {
|
|
5275
|
+
const key = nextKeys[i] ?? (nextKeys[i] = keyOf(items[i], i));
|
|
5276
|
+
jsxItems[i - start] = renderKeyedRow(items[i], i, key, renderItem);
|
|
5277
|
+
}
|
|
5278
|
+
return jsxItems;
|
|
5279
|
+
}
|
|
5280
|
+
function firstInsertedBeforeAnchor(parent, anchor, count) {
|
|
5281
|
+
let inserted = (anchor ? anchor.previousSibling : parent.lastChild);
|
|
5282
|
+
for (let i = 1; i < count && inserted; i++) {
|
|
5283
|
+
inserted = inserted.previousSibling;
|
|
5284
|
+
}
|
|
5285
|
+
return inserted;
|
|
5286
|
+
}
|
|
5287
|
+
function longestIncreasingSubsequencePositions(arr) {
|
|
5288
|
+
const n = arr.length;
|
|
5289
|
+
if (n === 0) {
|
|
5290
|
+
return [];
|
|
5291
|
+
}
|
|
5292
|
+
const tails = [];
|
|
5293
|
+
const prev = new Array(n).fill(-1);
|
|
5294
|
+
for (let i = 0; i < n; i++) {
|
|
5295
|
+
const x = arr[i];
|
|
5296
|
+
let low = 0;
|
|
5297
|
+
let high = tails.length;
|
|
5298
|
+
while (low < high) {
|
|
5299
|
+
const mid = (low + high) >> 1;
|
|
5300
|
+
if (arr[tails[mid]] < x) {
|
|
5301
|
+
low = mid + 1;
|
|
5302
|
+
}
|
|
5303
|
+
else {
|
|
5304
|
+
high = mid;
|
|
5305
|
+
}
|
|
5306
|
+
}
|
|
5307
|
+
if (low > 0) {
|
|
5308
|
+
prev[i] = tails[low - 1];
|
|
5309
|
+
}
|
|
5310
|
+
if (low === tails.length) {
|
|
5311
|
+
tails.push(i);
|
|
5312
|
+
}
|
|
5313
|
+
else {
|
|
5314
|
+
tails[low] = i;
|
|
5315
|
+
}
|
|
5316
|
+
}
|
|
5317
|
+
const lis = [];
|
|
5318
|
+
let current = tails[tails.length - 1];
|
|
5319
|
+
while (current !== -1) {
|
|
5320
|
+
lis.push(current);
|
|
5321
|
+
current = prev[current];
|
|
5322
|
+
}
|
|
5323
|
+
lis.reverse();
|
|
5324
|
+
return lis;
|
|
5325
|
+
}
|
|
5326
|
+
function reconcileKeyedLoopToParent(container, journal, parent, cursor, items, keyOf, renderItem) {
|
|
5327
|
+
const clientContainer = container;
|
|
5328
|
+
const nextLength = items.length;
|
|
5329
|
+
const firstLoopChild = vnode_getFirstChild(parent);
|
|
5330
|
+
const diffContext = createDiffContext(clientContainer, journal, cursor, null);
|
|
5331
|
+
const nextKeys = new Array(nextLength);
|
|
5332
|
+
if (firstLoopChild === null) {
|
|
5333
|
+
if (nextLength > 0) {
|
|
5334
|
+
return vnode_diff_range(clientContainer, journal, buildJsxRange(items, nextKeys, keyOf, renderItem, 0, nextLength - 1), parent, null, null, cursor, null, true, diffContext);
|
|
5335
|
+
}
|
|
5336
|
+
return;
|
|
5337
|
+
}
|
|
5338
|
+
if (nextLength === 0) {
|
|
5339
|
+
vnode_truncate(journal, parent, firstLoopChild, true);
|
|
5340
|
+
return;
|
|
5341
|
+
}
|
|
5342
|
+
let start = 0;
|
|
5343
|
+
let nextEnd = nextLength - 1;
|
|
5344
|
+
let oldStart = firstLoopChild;
|
|
5345
|
+
while (oldStart &&
|
|
5346
|
+
start <= nextEnd &&
|
|
5347
|
+
oldStart.key === (nextKeys[start] ??= keyOf(items[start], start))) {
|
|
5348
|
+
oldStart = oldStart.nextSibling;
|
|
5349
|
+
start++;
|
|
5350
|
+
}
|
|
5351
|
+
if (oldStart === null) {
|
|
5352
|
+
if (start > nextEnd) {
|
|
5353
|
+
return;
|
|
5354
|
+
}
|
|
5355
|
+
return vnode_diff_range(clientContainer, journal, buildJsxRange(items, nextKeys, keyOf, renderItem, start, nextEnd), parent, null, null, cursor, null, true, diffContext);
|
|
5356
|
+
}
|
|
5357
|
+
if (start > nextEnd) {
|
|
5358
|
+
vnode_truncate(journal, parent, oldStart, true);
|
|
5359
|
+
return;
|
|
5360
|
+
}
|
|
5361
|
+
const oldStartBoundary = oldStart.previousSibling;
|
|
5362
|
+
let oldEnd = parent.lastChild;
|
|
5363
|
+
while (oldEnd !== oldStartBoundary &&
|
|
5364
|
+
nextEnd >= start &&
|
|
5365
|
+
oldEnd.key === (nextKeys[nextEnd] ??= keyOf(items[nextEnd], nextEnd))) {
|
|
5366
|
+
oldEnd = oldEnd.previousSibling;
|
|
5367
|
+
nextEnd--;
|
|
5368
|
+
}
|
|
5369
|
+
const suffixAnchor = oldEnd ? oldEnd.nextSibling : oldStart;
|
|
5370
|
+
if (start > nextEnd) {
|
|
5371
|
+
let child = oldStart;
|
|
5372
|
+
while (child && child !== suffixAnchor) {
|
|
5373
|
+
const nextChild = child.nextSibling;
|
|
5374
|
+
vnode_remove(journal, parent, child, true);
|
|
5375
|
+
child = nextChild;
|
|
5376
|
+
}
|
|
5377
|
+
return;
|
|
5378
|
+
}
|
|
5379
|
+
if (oldEnd === oldStartBoundary) {
|
|
5380
|
+
const anchor = suffixAnchor;
|
|
5381
|
+
return vnode_diff_range(clientContainer, journal, buildJsxRange(items, nextKeys, keyOf, renderItem, start, nextEnd), parent, anchor, anchor, cursor, null, true, diffContext);
|
|
5382
|
+
}
|
|
5383
|
+
for (let i = start; i <= nextEnd; i++) {
|
|
5384
|
+
nextKeys[i] ??= keyOf(items[i], i);
|
|
5385
|
+
}
|
|
5386
|
+
const middleLength = nextEnd - start + 1;
|
|
5387
|
+
const nextIndexByKey = new Map();
|
|
5388
|
+
for (let i = start; i <= nextEnd; i++) {
|
|
5389
|
+
nextIndexByKey.set(nextKeys[i], i - start);
|
|
5390
|
+
}
|
|
5391
|
+
const prev = collectChildren(oldStart, oldEnd);
|
|
5392
|
+
const survivors = [];
|
|
5393
|
+
const prevRelIndexByKey = new Map();
|
|
5394
|
+
for (let i = 0; i < prev.length; i++) {
|
|
5395
|
+
const prevNode = prev[i];
|
|
5396
|
+
const prevKey = prevNode.key;
|
|
5397
|
+
if (nextIndexByKey.has(prevKey)) {
|
|
5398
|
+
prevRelIndexByKey.set(prevKey, survivors.length);
|
|
5399
|
+
survivors.push(prevNode);
|
|
5400
|
+
}
|
|
5401
|
+
else {
|
|
5402
|
+
vnode_remove(journal, parent, prevNode, true);
|
|
5403
|
+
}
|
|
5404
|
+
}
|
|
5405
|
+
const nextRefs = new Int32Array(middleLength);
|
|
5406
|
+
nextRefs.fill(-1);
|
|
5407
|
+
const seq = [];
|
|
5408
|
+
const seqOffsets = [];
|
|
5409
|
+
for (let offset = 0; offset < middleLength; offset++) {
|
|
5410
|
+
const relIndex = prevRelIndexByKey.get(nextKeys[start + offset]);
|
|
5411
|
+
if (relIndex !== undefined) {
|
|
5412
|
+
nextRefs[offset] = relIndex;
|
|
5413
|
+
seqOffsets.push(offset);
|
|
5414
|
+
seq.push(relIndex);
|
|
5415
|
+
}
|
|
5416
|
+
}
|
|
5417
|
+
const keepMask = new Uint8Array(middleLength);
|
|
5418
|
+
const lisPositions = longestIncreasingSubsequencePositions(seq);
|
|
5419
|
+
for (let i = 0; i < lisPositions.length; i++) {
|
|
5420
|
+
keepMask[seqOffsets[lisPositions[i]]] = 1;
|
|
5421
|
+
}
|
|
5422
|
+
let index = nextEnd;
|
|
5423
|
+
let anchor = suffixAnchor;
|
|
5424
|
+
const resume = () => {
|
|
5425
|
+
while (index >= start) {
|
|
5426
|
+
const offset = index - start;
|
|
5427
|
+
if (keepMask[offset] === 1) {
|
|
5428
|
+
anchor = survivors[nextRefs[offset]];
|
|
5429
|
+
index--;
|
|
5430
|
+
continue;
|
|
5431
|
+
}
|
|
5432
|
+
const existingRelIndex = nextRefs[offset];
|
|
5433
|
+
if (existingRelIndex !== -1) {
|
|
5434
|
+
const node = survivors[existingRelIndex];
|
|
5435
|
+
const alreadyPlaced = anchor === null ? parent.lastChild === node : node.nextSibling === anchor;
|
|
5436
|
+
if (!alreadyPlaced) {
|
|
5437
|
+
vnode_insertBefore(journal, parent, node, anchor);
|
|
5438
|
+
}
|
|
5439
|
+
anchor = node;
|
|
5440
|
+
index--;
|
|
5441
|
+
continue;
|
|
5442
|
+
}
|
|
5443
|
+
let blockStart = index;
|
|
5444
|
+
while (blockStart > start) {
|
|
5445
|
+
const prevOffset = blockStart - 1 - start;
|
|
5446
|
+
if (keepMask[prevOffset] === 1 || nextRefs[prevOffset] !== -1) {
|
|
5447
|
+
break;
|
|
5448
|
+
}
|
|
5449
|
+
blockStart--;
|
|
5450
|
+
}
|
|
5451
|
+
const blockLength = index - blockStart + 1;
|
|
5452
|
+
const result = vnode_diff_range(clientContainer, journal, buildJsxRange(items, nextKeys, null, renderItem, blockStart, index), parent, anchor, anchor, cursor, null, true, diffContext);
|
|
5453
|
+
return maybeThen(result, () => {
|
|
5454
|
+
const firstInserted = firstInsertedBeforeAnchor(parent, anchor, blockLength);
|
|
5455
|
+
if (isDev && !firstInserted) {
|
|
5456
|
+
throw new Error('Failed to insert keyed loop block');
|
|
5457
|
+
}
|
|
5458
|
+
anchor = firstInserted;
|
|
5459
|
+
index = blockStart - 1;
|
|
5460
|
+
return resume();
|
|
5461
|
+
});
|
|
5462
|
+
}
|
|
5463
|
+
};
|
|
5464
|
+
return resume();
|
|
5465
|
+
}
|
|
5466
|
+
|
|
5163
5467
|
/**
|
|
5164
5468
|
* Executes tasks for a vNode if the TASKS dirty bit is set. Tasks are stored in the ELEMENT_SEQ
|
|
5165
5469
|
* property and executed in order.
|
|
@@ -5232,6 +5536,8 @@ function executeNodeDiff(vNode, container, journal, cursor) {
|
|
|
5232
5536
|
if (!jsx) {
|
|
5233
5537
|
return;
|
|
5234
5538
|
}
|
|
5539
|
+
// cleanup payload
|
|
5540
|
+
setNodeDiffPayload(vNode, null);
|
|
5235
5541
|
if (isSignal(jsx)) {
|
|
5236
5542
|
jsx = jsx.value;
|
|
5237
5543
|
}
|
|
@@ -5392,6 +5698,35 @@ function executeCompute(vNode, container) {
|
|
|
5392
5698
|
}
|
|
5393
5699
|
});
|
|
5394
5700
|
}
|
|
5701
|
+
/**
|
|
5702
|
+
* Executes a reconcile chore for a vNode if the RECONCILE dirty bit is set. This handles the
|
|
5703
|
+
* reconciliation of a keyed loop.
|
|
5704
|
+
*
|
|
5705
|
+
* @param container - The container
|
|
5706
|
+
* @param journal - The journal
|
|
5707
|
+
* @param vNode - The vNode
|
|
5708
|
+
* @returns Promise if reconcile is async, void otherwise
|
|
5709
|
+
*/
|
|
5710
|
+
function executeReconcile(vNode, container, journal, cursor) {
|
|
5711
|
+
vNode.dirty &= -129 /* ChoreBits.RECONCILE */;
|
|
5712
|
+
const host = vNode;
|
|
5713
|
+
const props = container.getHostProp(host, ELEMENT_PROPS) || null;
|
|
5714
|
+
if (!props) {
|
|
5715
|
+
return;
|
|
5716
|
+
}
|
|
5717
|
+
let items = _getProps(props, 'items');
|
|
5718
|
+
if (isSignal(items)) {
|
|
5719
|
+
items = untrack(items);
|
|
5720
|
+
}
|
|
5721
|
+
const keyQrl = _getProps(props, 'key$');
|
|
5722
|
+
const itemQrl = _getProps(props, 'item$');
|
|
5723
|
+
const keyOf = keyQrl.resolved;
|
|
5724
|
+
const itemFn = itemQrl.resolved;
|
|
5725
|
+
if (keyOf !== undefined && itemFn !== undefined) {
|
|
5726
|
+
return reconcileKeyedLoopToParent(container, journal, host, cursor, items, keyOf, itemFn);
|
|
5727
|
+
}
|
|
5728
|
+
return maybeThen(keyQrl.resolve(), (resolvedKeyOf) => maybeThen(itemQrl.resolve(), (resolvedItemFn) => reconcileKeyedLoopToParent(container, journal, host, cursor, items, resolvedKeyOf, resolvedItemFn)));
|
|
5729
|
+
}
|
|
5395
5730
|
|
|
5396
5731
|
/**
|
|
5397
5732
|
* Executes the flush phase for a cursor.
|
|
@@ -5698,7 +6033,7 @@ function walkCursor(cursor, options) {
|
|
|
5698
6033
|
return;
|
|
5699
6034
|
}
|
|
5700
6035
|
// Skip if the vNode is not dirty
|
|
5701
|
-
if (!(currentVNode.dirty &
|
|
6036
|
+
if (!(currentVNode.dirty & 255 /* ChoreBits.DIRTY_MASK */)) {
|
|
5702
6037
|
// Move to next node
|
|
5703
6038
|
setCursorPosition(container, cursorData, getNextVNode(currentVNode, cursor));
|
|
5704
6039
|
continue;
|
|
@@ -5717,7 +6052,7 @@ function walkCursor(cursor, options) {
|
|
|
5717
6052
|
}
|
|
5718
6053
|
}
|
|
5719
6054
|
// Clear dirty bits and move to next node
|
|
5720
|
-
currentVNode.dirty &= -
|
|
6055
|
+
currentVNode.dirty &= -256 /* ChoreBits.DIRTY_MASK */;
|
|
5721
6056
|
setCursorPosition(container, cursorData, getNextVNode(currentVNode, cursor));
|
|
5722
6057
|
continue;
|
|
5723
6058
|
}
|
|
@@ -5733,6 +6068,9 @@ function walkCursor(cursor, options) {
|
|
|
5733
6068
|
else if (currentVNode.dirty & 4 /* ChoreBits.COMPONENT */) {
|
|
5734
6069
|
result = executeComponentChore(currentVNode, container, journal, cursor);
|
|
5735
6070
|
}
|
|
6071
|
+
else if (currentVNode.dirty & 128 /* ChoreBits.RECONCILE */) {
|
|
6072
|
+
result = executeReconcile(currentVNode, container, journal, cursor);
|
|
6073
|
+
}
|
|
5736
6074
|
else if (currentVNode.dirty & 8 /* ChoreBits.NODE_PROPS */) {
|
|
5737
6075
|
executeNodeProps(currentVNode, journal);
|
|
5738
6076
|
}
|
|
@@ -5778,11 +6116,11 @@ function walkCursor(cursor, options) {
|
|
|
5778
6116
|
}
|
|
5779
6117
|
}
|
|
5780
6118
|
isDev &&
|
|
5781
|
-
assertFalse(!!(cursor.dirty &
|
|
6119
|
+
assertFalse(!!(cursor.dirty & 255 /* ChoreBits.DIRTY_MASK */ && !cursorData.position), 'Cursor is still dirty and position is not set after walking');
|
|
5782
6120
|
finishWalk(container, cursor, cursorData, isRunningOnServer);
|
|
5783
6121
|
}
|
|
5784
6122
|
function finishWalk(container, cursor, cursorData, isServer) {
|
|
5785
|
-
if (!(cursor.dirty &
|
|
6123
|
+
if (!(cursor.dirty & 255 /* ChoreBits.DIRTY_MASK */)) {
|
|
5786
6124
|
removeCursorFromQueue(cursor, container);
|
|
5787
6125
|
if (!isServer) {
|
|
5788
6126
|
executeFlushPhase(cursor, container);
|
|
@@ -5854,7 +6192,7 @@ function partitionDirtyChildren(dirtyChildren, parent) {
|
|
|
5854
6192
|
/** @returns Next vNode to process, or null if traversal is complete */
|
|
5855
6193
|
function getNextVNode(vNode, cursor) {
|
|
5856
6194
|
if (vNode === cursor) {
|
|
5857
|
-
if (cursor.dirty &
|
|
6195
|
+
if (cursor.dirty & 255 /* ChoreBits.DIRTY_MASK */) {
|
|
5858
6196
|
return cursor;
|
|
5859
6197
|
}
|
|
5860
6198
|
return null;
|
|
@@ -5868,7 +6206,7 @@ function getNextVNode(vNode, cursor) {
|
|
|
5868
6206
|
parent = vNode.parent;
|
|
5869
6207
|
}
|
|
5870
6208
|
if (!parent) {
|
|
5871
|
-
if (cursor.dirty &
|
|
6209
|
+
if (cursor.dirty & 255 /* ChoreBits.DIRTY_MASK */) {
|
|
5872
6210
|
return cursor;
|
|
5873
6211
|
}
|
|
5874
6212
|
return null;
|
|
@@ -5879,7 +6217,7 @@ function getNextVNode(vNode, cursor) {
|
|
|
5879
6217
|
let count = len;
|
|
5880
6218
|
while (count-- > 0) {
|
|
5881
6219
|
const nextVNode = dirtyChildren[index];
|
|
5882
|
-
if (nextVNode.dirty &
|
|
6220
|
+
if (nextVNode.dirty & 255 /* ChoreBits.DIRTY_MASK */) {
|
|
5883
6221
|
parent.nextDirtyChildIndex = (index + 1) % len;
|
|
5884
6222
|
return nextVNode;
|
|
5885
6223
|
}
|
|
@@ -5955,7 +6293,7 @@ function _executeSsrChores(container, ssrNode) {
|
|
|
5955
6293
|
if (ssrNode.dirty & 16 /* ChoreBits.COMPUTE */) {
|
|
5956
6294
|
executeCompute(ssrNode, container);
|
|
5957
6295
|
}
|
|
5958
|
-
if (ssrNode.dirty &
|
|
6296
|
+
if (ssrNode.dirty & 255 /* ChoreBits.DIRTY_MASK */) {
|
|
5959
6297
|
// We are running on the server.
|
|
5960
6298
|
// On server we can't schedule task for a different host!
|
|
5961
6299
|
// Server is SSR, and therefore scheduling for anything but the current host
|
|
@@ -5970,7 +6308,7 @@ function _executeSsrChores(container, ssrNode) {
|
|
|
5970
6308
|
This is often caused by modifying a signal in an already rendered component during SSR.`;
|
|
5971
6309
|
logWarn(warningMessage);
|
|
5972
6310
|
}
|
|
5973
|
-
ssrNode.dirty &= -
|
|
6311
|
+
ssrNode.dirty &= -256 /* ChoreBits.DIRTY_MASK */;
|
|
5974
6312
|
return;
|
|
5975
6313
|
}
|
|
5976
6314
|
let promise = null;
|
|
@@ -5980,13 +6318,17 @@ function _executeSsrChores(container, ssrNode) {
|
|
|
5980
6318
|
promise = result;
|
|
5981
6319
|
}
|
|
5982
6320
|
}
|
|
6321
|
+
if (ssrNode.dirty & 128 /* ChoreBits.RECONCILE */) {
|
|
6322
|
+
const result = executeReconcileChore(container, ssrNode);
|
|
6323
|
+
promise = promise ? promise.then(() => result) : result;
|
|
6324
|
+
}
|
|
5983
6325
|
// In SSR, we don't handle the COMPONENT bit here.
|
|
5984
6326
|
// During initial render, if a task completes and marks the component dirty,
|
|
5985
6327
|
// we want to leave the COMPONENT bit set so that executeComponent can detect
|
|
5986
6328
|
// it after $waitOn$ completes and re-execute the component function.
|
|
5987
6329
|
// executeComponent will clear the bit after re-executing.
|
|
5988
6330
|
// Clear all dirty bits EXCEPT COMPONENT
|
|
5989
|
-
ssrNode.dirty &= -
|
|
6331
|
+
ssrNode.dirty &= -252;
|
|
5990
6332
|
if (promise) {
|
|
5991
6333
|
return promise;
|
|
5992
6334
|
}
|
|
@@ -6028,6 +6370,32 @@ function executeNodePropChore(container, ssrNode) {
|
|
|
6028
6370
|
container.addBackpatchEntry(ssrNode.id, property, serializedValue);
|
|
6029
6371
|
}
|
|
6030
6372
|
}
|
|
6373
|
+
async function executeReconcileChore(container, ssrNode) {
|
|
6374
|
+
ssrNode.dirty &= -129 /* ChoreBits.RECONCILE */;
|
|
6375
|
+
const host = ssrNode;
|
|
6376
|
+
const props = container.getHostProp(host, ELEMENT_PROPS) || null;
|
|
6377
|
+
if (!props) {
|
|
6378
|
+
return;
|
|
6379
|
+
}
|
|
6380
|
+
let items = _getProps(props, 'items');
|
|
6381
|
+
if (isSignal(items)) {
|
|
6382
|
+
items = untrack(items);
|
|
6383
|
+
}
|
|
6384
|
+
const keyOf = (await _getProps(props, 'key$').resolve());
|
|
6385
|
+
const itemFn = (await _getProps(props, 'item$').resolve());
|
|
6386
|
+
const children = [];
|
|
6387
|
+
for (let i = 0; i < items.length; i++) {
|
|
6388
|
+
const item = items[i];
|
|
6389
|
+
const jsx = itemFn(item, i);
|
|
6390
|
+
const key = keyOf(item, i);
|
|
6391
|
+
jsx.key = key;
|
|
6392
|
+
children.push(jsx);
|
|
6393
|
+
}
|
|
6394
|
+
await container.renderJSX(children, {
|
|
6395
|
+
currentStyleScoped: null,
|
|
6396
|
+
parentComponentFrame: container.getComponentFrame(0),
|
|
6397
|
+
});
|
|
6398
|
+
}
|
|
6031
6399
|
|
|
6032
6400
|
/** Reusable path array to avoid allocations */
|
|
6033
6401
|
const reusablePath = [];
|
|
@@ -6051,7 +6419,7 @@ function propagateToCursorRoot(vNode, cursorRoot) {
|
|
|
6051
6419
|
reusablePath.push(vNode);
|
|
6052
6420
|
let current = vNode.slotParent || vNode.parent;
|
|
6053
6421
|
while (current) {
|
|
6054
|
-
const isDirty = current.dirty &
|
|
6422
|
+
const isDirty = current.dirty & 255 /* ChoreBits.DIRTY_MASK */;
|
|
6055
6423
|
const currentIsCursor = isCursor(current);
|
|
6056
6424
|
// Stop when we reach the cursor root or a dirty ancestor
|
|
6057
6425
|
if (current === cursorRoot || isDirty) {
|
|
@@ -6123,9 +6491,9 @@ function markVNodeDirty(container, vNode, bits, cursorRoot = null) {
|
|
|
6123
6491
|
}
|
|
6124
6492
|
return;
|
|
6125
6493
|
}
|
|
6126
|
-
const isRealDirty = bits &
|
|
6494
|
+
const isRealDirty = bits & 255 /* ChoreBits.DIRTY_MASK */;
|
|
6127
6495
|
// If already dirty, no need to propagate again
|
|
6128
|
-
if ((isRealDirty ? prevDirty &
|
|
6496
|
+
if ((isRealDirty ? prevDirty & 255 /* ChoreBits.DIRTY_MASK */ : prevDirty) || vNode === cursorRoot) {
|
|
6129
6497
|
return;
|
|
6130
6498
|
}
|
|
6131
6499
|
const parent = vNode.slotParent || vNode.parent;
|
|
@@ -6135,7 +6503,7 @@ function markVNodeDirty(container, vNode, bits, cursorRoot = null) {
|
|
|
6135
6503
|
return;
|
|
6136
6504
|
}
|
|
6137
6505
|
// We must attach to a cursor subtree if it exists
|
|
6138
|
-
if (parent && parent.dirty &
|
|
6506
|
+
if (parent && parent.dirty & 255 /* ChoreBits.DIRTY_MASK */) {
|
|
6139
6507
|
if (isRealDirty) {
|
|
6140
6508
|
parent.dirty |= 32 /* ChoreBits.CHILDREN */;
|
|
6141
6509
|
}
|
|
@@ -6516,16 +6884,26 @@ const vnode_ensureElementInflated = (container, vnode) => {
|
|
|
6516
6884
|
}
|
|
6517
6885
|
}
|
|
6518
6886
|
};
|
|
6887
|
+
const unwrapEventHandlerQrl = (handler) => {
|
|
6888
|
+
if (handler.$symbol$ === '_run') {
|
|
6889
|
+
const innerHandler = handler.getCaptured()?.[0];
|
|
6890
|
+
if (isQrl(innerHandler)) {
|
|
6891
|
+
return innerHandler;
|
|
6892
|
+
}
|
|
6893
|
+
}
|
|
6894
|
+
return handler;
|
|
6895
|
+
};
|
|
6519
6896
|
function registerQrlHandlers(attr, key, container, element) {
|
|
6520
6897
|
const value = attr.value;
|
|
6521
6898
|
const scopedKebabName = key.slice(2);
|
|
6522
6899
|
const qrls = value.split('|');
|
|
6523
|
-
const handlers =
|
|
6524
|
-
|
|
6900
|
+
const handlers = [];
|
|
6901
|
+
for (let i = 0; i < qrls.length; i++) {
|
|
6902
|
+
const handler = unwrapEventHandlerQrl(parseQRL(qrls[i], container));
|
|
6525
6903
|
// These QRLs are mostly _run and _task and don't need wrapping with retryOnPromise
|
|
6526
|
-
|
|
6527
|
-
}
|
|
6528
|
-
(element._qDispatch ||= {})[scopedKebabName] = handlers;
|
|
6904
|
+
handlers.push(runEventHandlerQRL.bind(null, handler));
|
|
6905
|
+
}
|
|
6906
|
+
(element._qDispatch ||= {})[scopedKebabName] = handlers.length === 1 ? handlers[0] : handlers;
|
|
6529
6907
|
}
|
|
6530
6908
|
/** Walks the direct children of a parent node and calls the callback for each child. */
|
|
6531
6909
|
function vnode_walkDirectChildren(journal, vParent, callback) {
|
|
@@ -7204,9 +7582,17 @@ const vnode_truncate = (journal, vParent, vDelete, removeDOM = true) => {
|
|
|
7204
7582
|
addVNodeOperation(journal, createRemoveAllChildrenOperation(vParent.node));
|
|
7205
7583
|
}
|
|
7206
7584
|
else {
|
|
7207
|
-
|
|
7208
|
-
|
|
7209
|
-
|
|
7585
|
+
const domParentVNode = vnode_getDomParentVNode(vParent, false);
|
|
7586
|
+
if (domParentVNode &&
|
|
7587
|
+
domParentVNode.firstChild === vParent &&
|
|
7588
|
+
domParentVNode.lastChild === vParent) {
|
|
7589
|
+
addVNodeOperation(journal, createRemoveAllChildrenOperation(parent));
|
|
7590
|
+
}
|
|
7591
|
+
else {
|
|
7592
|
+
vnode_walkDirectChildren(journal, vParent, (vNode) => {
|
|
7593
|
+
addVNodeOperation(journal, createDeleteOperation(vNode.node));
|
|
7594
|
+
});
|
|
7595
|
+
}
|
|
7210
7596
|
}
|
|
7211
7597
|
}
|
|
7212
7598
|
const vPrevious = vDelete.previousSibling;
|
|
@@ -8198,7 +8584,7 @@ const useSequentialScope = () => {
|
|
|
8198
8584
|
seq.push(undefined);
|
|
8199
8585
|
}
|
|
8200
8586
|
const set = (value) => {
|
|
8201
|
-
if (qDev
|
|
8587
|
+
if (qDev) {
|
|
8202
8588
|
verifySerializable(value);
|
|
8203
8589
|
}
|
|
8204
8590
|
return (seq[seqIdx] = value);
|
|
@@ -8335,7 +8721,7 @@ const useContextProvider = (context, newValue) => {
|
|
|
8335
8721
|
if (qDev) {
|
|
8336
8722
|
validateContext(context);
|
|
8337
8723
|
}
|
|
8338
|
-
if (qDev
|
|
8724
|
+
if (qDev) {
|
|
8339
8725
|
verifySerializable(newValue);
|
|
8340
8726
|
}
|
|
8341
8727
|
iCtx.$container$.setContext(iCtx.$hostElement$, context, newValue);
|
|
@@ -8756,13 +9142,6 @@ function retrieveVNodeOrDocument(container, value) {
|
|
|
8756
9142
|
: container.element?.ownerDocument;
|
|
8757
9143
|
}
|
|
8758
9144
|
|
|
8759
|
-
// https://regexr.com/68v72
|
|
8760
|
-
// @ts-expect-error this is a valid regex
|
|
8761
|
-
const EXTRACT_IMPORT_PATH = /\(\s*(['"])([^\1]+)\1\s*\)/;
|
|
8762
|
-
// https://regexr.com/690ds
|
|
8763
|
-
const EXTRACT_SELF_IMPORT = /Promise\s*\.\s*resolve/;
|
|
8764
|
-
// https://regexr.com/6a83h
|
|
8765
|
-
const EXTRACT_FILE_NAME = /[\\/(]([\w\d.\-_]+\.(js|ts)x?):/;
|
|
8766
9145
|
// <docs markdown="../../readme.md#qrl">
|
|
8767
9146
|
// !!DO NOT EDIT THIS COMMENT DIRECTLY!!!
|
|
8768
9147
|
// (edit ../../readme.md#qrl instead and run `pnpm docs.sync`)
|
|
@@ -8784,29 +9163,6 @@ const qrl = (chunkOrFn, symbol, lexicalScopeCapture, stackOffset = 0) => {
|
|
|
8784
9163
|
let symbolFn = null;
|
|
8785
9164
|
if (isFunction(chunkOrFn)) {
|
|
8786
9165
|
symbolFn = chunkOrFn;
|
|
8787
|
-
if (qSerialize) {
|
|
8788
|
-
let match;
|
|
8789
|
-
const srcCode = String(chunkOrFn);
|
|
8790
|
-
if ((match = srcCode.match(EXTRACT_IMPORT_PATH)) && match[2]) {
|
|
8791
|
-
chunk = match[2];
|
|
8792
|
-
}
|
|
8793
|
-
else if ((match = srcCode.match(EXTRACT_SELF_IMPORT))) {
|
|
8794
|
-
const ref = 'QWIK-SELF';
|
|
8795
|
-
const frames = new Error(ref).stack.split('\n');
|
|
8796
|
-
const start = frames.findIndex((f) => f.includes(ref));
|
|
8797
|
-
const frame = frames[start + 2 + stackOffset];
|
|
8798
|
-
match = frame.match(EXTRACT_FILE_NAME);
|
|
8799
|
-
if (!match) {
|
|
8800
|
-
chunk = 'main';
|
|
8801
|
-
}
|
|
8802
|
-
else {
|
|
8803
|
-
chunk = match[1];
|
|
8804
|
-
}
|
|
8805
|
-
}
|
|
8806
|
-
else {
|
|
8807
|
-
throw qError(6 /* QError.dynamicImportFailed */, [srcCode]);
|
|
8808
|
-
}
|
|
8809
|
-
}
|
|
8810
9166
|
}
|
|
8811
9167
|
else if (isString(chunkOrFn)) {
|
|
8812
9168
|
chunk = chunkOrFn;
|
|
@@ -10450,9 +10806,7 @@ const _hmr = (event, element) => {
|
|
|
10450
10806
|
// Maybe we should use a qrl registry to invalidate all QRLs from a parent?
|
|
10451
10807
|
const qrl = container.getHostProp(host, OnRenderProp);
|
|
10452
10808
|
if (qrl) {
|
|
10453
|
-
|
|
10454
|
-
const instance = qrl.__proto__;
|
|
10455
|
-
const lazy = instance.$lazy$;
|
|
10809
|
+
const lazy = qrl.$lazy$;
|
|
10456
10810
|
const chunk = lazy.$chunk$;
|
|
10457
10811
|
if (chunk) {
|
|
10458
10812
|
/**
|
|
@@ -10462,7 +10816,7 @@ const _hmr = (event, element) => {
|
|
|
10462
10816
|
const bustUrl = chunk.split('?')[0] + '?t=' + Date.now();
|
|
10463
10817
|
lazy.$chunk$ = bustUrl;
|
|
10464
10818
|
lazy.$ref$ = undefined;
|
|
10465
|
-
|
|
10819
|
+
qrl.resolved = undefined;
|
|
10466
10820
|
// Force rerender
|
|
10467
10821
|
markVNodeDirty(container, host, 4 /* ChoreBits.COMPONENT */);
|
|
10468
10822
|
}
|
|
@@ -11345,6 +11699,7 @@ class DomContainer extends _SharedContainer {
|
|
|
11345
11699
|
this.$setServerData$();
|
|
11346
11700
|
element.setAttribute(QContainerAttr, "resumed" /* QContainerValue.RESUMED */);
|
|
11347
11701
|
element.qContainer = this;
|
|
11702
|
+
element.qDestroy = () => this.$destroy$();
|
|
11348
11703
|
const qwikStates = element.querySelectorAll('script[type="qwik/state"]');
|
|
11349
11704
|
if (qwikStates.length !== 0) {
|
|
11350
11705
|
const lastState = qwikStates[qwikStates.length - 1];
|
|
@@ -11357,6 +11712,19 @@ class DomContainer extends _SharedContainer {
|
|
|
11357
11712
|
element.dispatchEvent(new CustomEvent('qresume', { bubbles: true }));
|
|
11358
11713
|
}
|
|
11359
11714
|
}
|
|
11715
|
+
/** Tear down this container so stale references fail gracefully. */
|
|
11716
|
+
$destroy$() {
|
|
11717
|
+
this.vNodeLocate = () => null;
|
|
11718
|
+
this.$rawStateData$.length = 0;
|
|
11719
|
+
this.$stateData$.length = 0;
|
|
11720
|
+
this.$getObjectById$ = () => undefined;
|
|
11721
|
+
const el = this.element;
|
|
11722
|
+
el.qContainer = undefined;
|
|
11723
|
+
el.qVnodeData = undefined;
|
|
11724
|
+
el.qVNodeRefs = undefined;
|
|
11725
|
+
el.removeAttribute(QContainerAttr);
|
|
11726
|
+
el.ownerDocument.qVNodeData = undefined;
|
|
11727
|
+
}
|
|
11360
11728
|
/**
|
|
11361
11729
|
* The first time we render we need to hoist the styles. (Meaning we need to move all styles from
|
|
11362
11730
|
* component inline to <head>)
|
|
@@ -11562,23 +11930,45 @@ const useTaskQrl = (qrl, opts) => {
|
|
|
11562
11930
|
}
|
|
11563
11931
|
};
|
|
11564
11932
|
const runTask = (task, container, host) => {
|
|
11933
|
+
const pendingTask = task.$taskPromise$;
|
|
11934
|
+
if (pendingTask) {
|
|
11935
|
+
return pendingTask;
|
|
11936
|
+
}
|
|
11565
11937
|
task.$flags$ &= -5 /* TaskFlags.DIRTY */;
|
|
11566
|
-
|
|
11567
|
-
|
|
11568
|
-
|
|
11569
|
-
|
|
11570
|
-
|
|
11571
|
-
|
|
11572
|
-
|
|
11573
|
-
|
|
11574
|
-
|
|
11575
|
-
|
|
11576
|
-
|
|
11577
|
-
|
|
11578
|
-
|
|
11579
|
-
|
|
11580
|
-
|
|
11938
|
+
const handleError = (reason) => container.handleError(reason, host);
|
|
11939
|
+
let taskPromise = null;
|
|
11940
|
+
const result = maybeThen(cleanupAsyncDestroyable(task, handleError), () => {
|
|
11941
|
+
const iCtx = newInvokeContext(container.$locale$, host, TaskEvent);
|
|
11942
|
+
iCtx.$container$ = container;
|
|
11943
|
+
const taskFn = task.$qrl$.getFn(iCtx, () => clearAllEffects(container, task));
|
|
11944
|
+
const track = trackFn(task, container);
|
|
11945
|
+
const [cleanup] = cleanupFn(task, handleError);
|
|
11946
|
+
const taskApi = { track, cleanup };
|
|
11947
|
+
return safeCall(() => taskFn(taskApi), cleanup, (err) => {
|
|
11948
|
+
// If a Promise is thrown, that means we need to re-run the task.
|
|
11949
|
+
if (isPromise(err)) {
|
|
11950
|
+
return err.then(() => {
|
|
11951
|
+
if (task.$taskPromise$ === taskPromise) {
|
|
11952
|
+
task.$taskPromise$ = null;
|
|
11953
|
+
}
|
|
11954
|
+
return runTask(task, container, host);
|
|
11955
|
+
});
|
|
11956
|
+
}
|
|
11957
|
+
else {
|
|
11958
|
+
handleError(err);
|
|
11959
|
+
}
|
|
11960
|
+
});
|
|
11581
11961
|
});
|
|
11962
|
+
if (isPromise(result)) {
|
|
11963
|
+
taskPromise = result.finally(() => {
|
|
11964
|
+
if (task.$taskPromise$ === taskPromise) {
|
|
11965
|
+
task.$taskPromise$ = null;
|
|
11966
|
+
}
|
|
11967
|
+
});
|
|
11968
|
+
task.$taskPromise$ = taskPromise;
|
|
11969
|
+
return taskPromise;
|
|
11970
|
+
}
|
|
11971
|
+
return result;
|
|
11582
11972
|
};
|
|
11583
11973
|
class Task extends BackRef {
|
|
11584
11974
|
$flags$;
|
|
@@ -11587,6 +11977,8 @@ class Task extends BackRef {
|
|
|
11587
11977
|
$qrl$;
|
|
11588
11978
|
$state$;
|
|
11589
11979
|
$destroy$;
|
|
11980
|
+
$destroyPromise$;
|
|
11981
|
+
$taskPromise$ = null;
|
|
11590
11982
|
constructor($flags$, $index$, $el$, $qrl$, $state$, $destroy$) {
|
|
11591
11983
|
super();
|
|
11592
11984
|
this.$flags$ = $flags$;
|
|
@@ -11707,8 +12099,8 @@ const scheduleEffects = (container, signal, effects) => {
|
|
|
11707
12099
|
}
|
|
11708
12100
|
};
|
|
11709
12101
|
const effectsSnapshot = Array.from(effects);
|
|
11710
|
-
for (
|
|
11711
|
-
scheduleEffect(
|
|
12102
|
+
for (let i = 0; i < effectsSnapshot.length; i++) {
|
|
12103
|
+
scheduleEffect(effectsSnapshot[i]);
|
|
11712
12104
|
}
|
|
11713
12105
|
}
|
|
11714
12106
|
};
|
|
@@ -12613,37 +13005,26 @@ class LazyRef {
|
|
|
12613
13005
|
return this.$ref$;
|
|
12614
13006
|
}
|
|
12615
13007
|
}
|
|
13008
|
+
const QRL_STATE = Symbol('qrl-state');
|
|
12616
13009
|
/**
|
|
12617
|
-
*
|
|
12618
|
-
*
|
|
12619
|
-
* owns `resolved` (always set on the instance).
|
|
13010
|
+
* QRL methods may run with `this` set either to the callable wrapper or directly to the backing
|
|
13011
|
+
* state object. This helper normalizes both cases to the shared backing state.
|
|
12620
13012
|
*/
|
|
12621
13013
|
const getInstance = (instance) => {
|
|
12622
|
-
return
|
|
12623
|
-
? instance
|
|
12624
|
-
: Object.getPrototypeOf(instance);
|
|
13014
|
+
return instance?.[QRL_STATE] ?? instance;
|
|
12625
13015
|
};
|
|
12626
13016
|
/**
|
|
12627
|
-
*
|
|
12628
|
-
*
|
|
12629
|
-
*
|
|
12630
|
-
* that `.apply()` etc work.
|
|
12631
|
-
*
|
|
12632
|
-
* So a QRL is a function that has a prototype of a QRLClass instance. This is unconventional, but
|
|
12633
|
-
* it allows us to have a callable QRL that is also a class.
|
|
12634
|
-
*
|
|
12635
|
-
* Note the use of getInstance everywhere when writing to `this`. If you write to `this` directly,
|
|
12636
|
-
* it will be stored on the function itself, and we don't want that because the QRLClass instance
|
|
12637
|
-
* doesn't have access to it, and it uses more memory.
|
|
13017
|
+
* QRL state lives in a plain object. The callable wrapper stores that state under a symbol and uses
|
|
13018
|
+
* a shared prototype derived from Function.prototype for methods/getters. This keeps QRLs callable
|
|
13019
|
+
* without using a unique state object as each function's prototype.
|
|
12638
13020
|
*/
|
|
12639
|
-
class QRLClass
|
|
13021
|
+
class QRLClass {
|
|
12640
13022
|
$lazy$;
|
|
12641
13023
|
resolved = undefined;
|
|
12642
13024
|
// This is defined or undefined for the lifetime of the QRL, so we set it lazily
|
|
12643
13025
|
$captures$;
|
|
12644
13026
|
$container$;
|
|
12645
13027
|
constructor($lazy$, $captures$, container) {
|
|
12646
|
-
super();
|
|
12647
13028
|
this.$lazy$ = $lazy$;
|
|
12648
13029
|
if ($captures$) {
|
|
12649
13030
|
this.$captures$ = $captures$;
|
|
@@ -12662,76 +13043,140 @@ class QRLClass extends Function {
|
|
|
12662
13043
|
// If it is plain value with deserialized or missing captures, resolve it immediately
|
|
12663
13044
|
// Otherwise we keep using the async path so we can wait for qrls to load
|
|
12664
13045
|
if ($lazy$.$ref$ != null && typeof this.$captures$ !== 'string' && !isPromise($lazy$.$ref$)) {
|
|
12665
|
-
// we can pass this instead of using getInstance because we know we are not the qrlFn
|
|
12666
13046
|
this.resolved = bindCaptures(this, $lazy$.$ref$);
|
|
12667
13047
|
}
|
|
12668
13048
|
}
|
|
12669
|
-
|
|
12670
|
-
|
|
12671
|
-
|
|
12672
|
-
|
|
12673
|
-
|
|
12674
|
-
const qrl = getInstance(this);
|
|
12675
|
-
qrl.$lazy$.$setRef$(ref);
|
|
12676
|
-
qrl.resolved = bindCaptures(qrl, ref);
|
|
12677
|
-
}
|
|
12678
|
-
// --- Getter proxies for backward compat ---
|
|
12679
|
-
get $chunk$() {
|
|
12680
|
-
return this.$lazy$.$chunk$;
|
|
12681
|
-
}
|
|
12682
|
-
get $symbol$() {
|
|
12683
|
-
return this.$lazy$.$symbol$;
|
|
12684
|
-
}
|
|
12685
|
-
get $hash$() {
|
|
12686
|
-
return this.$lazy$.$hash$;
|
|
12687
|
-
}
|
|
12688
|
-
get dev() {
|
|
12689
|
-
return this.$lazy$.dev;
|
|
13049
|
+
}
|
|
13050
|
+
const qrlCallFn = function (withThis, ...args) {
|
|
13051
|
+
const qrl = getInstance(this);
|
|
13052
|
+
if (qrl.resolved) {
|
|
13053
|
+
return qrl.resolved.apply(withThis, args);
|
|
12690
13054
|
}
|
|
12691
|
-
|
|
12692
|
-
|
|
12693
|
-
|
|
13055
|
+
// Not resolved yet: we'll return a promise
|
|
13056
|
+
// grab the context while we are sync
|
|
13057
|
+
const ctx = tryGetInvokeContext();
|
|
13058
|
+
return qrlResolve
|
|
13059
|
+
.call(qrl, ctx?.$container$)
|
|
13060
|
+
.then(() => invokeApply.call(withThis, ctx, qrl.resolved, args));
|
|
13061
|
+
};
|
|
13062
|
+
const qrlWithCaptures = function (captures) {
|
|
13063
|
+
const qrl = getInstance(this);
|
|
13064
|
+
const newQrl = new QRLClass(qrl.$lazy$, captures, qrl.$captures$ ? qrl.$container$ : undefined);
|
|
13065
|
+
return makeQrlFn(newQrl);
|
|
13066
|
+
};
|
|
13067
|
+
const qrlSetRef = function (ref) {
|
|
13068
|
+
const qrl = getInstance(this);
|
|
13069
|
+
qrl.$lazy$.$setRef$(ref);
|
|
13070
|
+
qrl.resolved = bindCaptures(qrl, ref);
|
|
13071
|
+
};
|
|
13072
|
+
const qrlResolve = async function (container) {
|
|
13073
|
+
const qrl = getInstance(this);
|
|
13074
|
+
return maybeThen($resolve$(qrl, container), () => qrl.resolved);
|
|
13075
|
+
};
|
|
13076
|
+
const qrlGetSymbol = function () {
|
|
13077
|
+
return getInstance(this).$lazy$.$symbol$;
|
|
13078
|
+
};
|
|
13079
|
+
const qrlGetHash = function () {
|
|
13080
|
+
return getInstance(this).$lazy$.$hash$;
|
|
13081
|
+
};
|
|
13082
|
+
const qrlGetCaptured = function () {
|
|
13083
|
+
const qrl = getInstance(this);
|
|
13084
|
+
ensureQrlCaptures(qrl);
|
|
13085
|
+
return qrl.$captures$;
|
|
13086
|
+
};
|
|
13087
|
+
const qrlGetFn = function (currentCtx, beforeFn) {
|
|
13088
|
+
const qrl = getInstance(this);
|
|
13089
|
+
const bound = (...args) => {
|
|
13090
|
+
if (!qrl.resolved) {
|
|
13091
|
+
return qrlResolve.call(qrl).then((fn) => {
|
|
13092
|
+
if (qDev && !isFunction(fn)) {
|
|
13093
|
+
throw qError(5 /* QError.qrlIsNotFunction */);
|
|
13094
|
+
}
|
|
13095
|
+
return bound(...args);
|
|
13096
|
+
});
|
|
12694
13097
|
}
|
|
12695
|
-
|
|
12696
|
-
|
|
12697
|
-
|
|
12698
|
-
return
|
|
12699
|
-
}
|
|
12700
|
-
|
|
12701
|
-
|
|
12702
|
-
|
|
12703
|
-
|
|
12704
|
-
|
|
12705
|
-
|
|
12706
|
-
|
|
12707
|
-
|
|
12708
|
-
|
|
12709
|
-
|
|
12710
|
-
}
|
|
12711
|
-
|
|
12712
|
-
|
|
12713
|
-
|
|
12714
|
-
|
|
12715
|
-
|
|
12716
|
-
|
|
12717
|
-
|
|
12718
|
-
|
|
12719
|
-
|
|
12720
|
-
|
|
12721
|
-
|
|
12722
|
-
|
|
12723
|
-
|
|
12724
|
-
|
|
12725
|
-
|
|
12726
|
-
|
|
12727
|
-
|
|
12728
|
-
|
|
12729
|
-
|
|
12730
|
-
|
|
12731
|
-
|
|
12732
|
-
|
|
12733
|
-
|
|
12734
|
-
|
|
13098
|
+
if (beforeFn && beforeFn() === false) {
|
|
13099
|
+
return undefined;
|
|
13100
|
+
}
|
|
13101
|
+
return invokeApply(currentCtx, qrl.resolved, args);
|
|
13102
|
+
};
|
|
13103
|
+
return bound;
|
|
13104
|
+
};
|
|
13105
|
+
const QRL_FUNCTION_PROTO = Object.create(Function.prototype, {
|
|
13106
|
+
resolved: {
|
|
13107
|
+
get() {
|
|
13108
|
+
return this[QRL_STATE].resolved;
|
|
13109
|
+
},
|
|
13110
|
+
set(value) {
|
|
13111
|
+
this[QRL_STATE].resolved = value;
|
|
13112
|
+
},
|
|
13113
|
+
},
|
|
13114
|
+
$captures$: {
|
|
13115
|
+
get() {
|
|
13116
|
+
return this[QRL_STATE].$captures$;
|
|
13117
|
+
},
|
|
13118
|
+
set(value) {
|
|
13119
|
+
this[QRL_STATE].$captures$ = value;
|
|
13120
|
+
},
|
|
13121
|
+
},
|
|
13122
|
+
$container$: {
|
|
13123
|
+
get() {
|
|
13124
|
+
return this[QRL_STATE].$container$;
|
|
13125
|
+
},
|
|
13126
|
+
set(value) {
|
|
13127
|
+
this[QRL_STATE].$container$ = value;
|
|
13128
|
+
},
|
|
13129
|
+
},
|
|
13130
|
+
$lazy$: {
|
|
13131
|
+
get() {
|
|
13132
|
+
return this[QRL_STATE].$lazy$;
|
|
13133
|
+
},
|
|
13134
|
+
},
|
|
13135
|
+
$chunk$: {
|
|
13136
|
+
get() {
|
|
13137
|
+
return this[QRL_STATE].$lazy$.$chunk$;
|
|
13138
|
+
},
|
|
13139
|
+
},
|
|
13140
|
+
$symbol$: {
|
|
13141
|
+
get() {
|
|
13142
|
+
return this[QRL_STATE].$lazy$.$symbol$;
|
|
13143
|
+
},
|
|
13144
|
+
},
|
|
13145
|
+
$hash$: {
|
|
13146
|
+
get() {
|
|
13147
|
+
return this[QRL_STATE].$lazy$.$hash$;
|
|
13148
|
+
},
|
|
13149
|
+
},
|
|
13150
|
+
dev: {
|
|
13151
|
+
get() {
|
|
13152
|
+
return this[QRL_STATE].$lazy$.dev;
|
|
13153
|
+
},
|
|
13154
|
+
},
|
|
13155
|
+
$callFn$: {
|
|
13156
|
+
value: qrlCallFn,
|
|
13157
|
+
},
|
|
13158
|
+
w: {
|
|
13159
|
+
value: qrlWithCaptures,
|
|
13160
|
+
},
|
|
13161
|
+
s: {
|
|
13162
|
+
value: qrlSetRef,
|
|
13163
|
+
},
|
|
13164
|
+
resolve: {
|
|
13165
|
+
value: qrlResolve,
|
|
13166
|
+
},
|
|
13167
|
+
getSymbol: {
|
|
13168
|
+
value: qrlGetSymbol,
|
|
13169
|
+
},
|
|
13170
|
+
getHash: {
|
|
13171
|
+
value: qrlGetHash,
|
|
13172
|
+
},
|
|
13173
|
+
getCaptured: {
|
|
13174
|
+
value: qrlGetCaptured,
|
|
13175
|
+
},
|
|
13176
|
+
getFn: {
|
|
13177
|
+
value: qrlGetFn,
|
|
13178
|
+
},
|
|
13179
|
+
});
|
|
12735
13180
|
/**
|
|
12736
13181
|
* The current captured scope during QRL invocation. This is used to provide the lexical scope for
|
|
12737
13182
|
* QRL functions. It is used one time per invocation, synchronously, so it is safe to store it in
|
|
@@ -12829,12 +13274,12 @@ const createQRL = (chunk, symbol, symbolRef, symbolFn, captures, container) => {
|
|
|
12829
13274
|
return makeQrlFn(qrl);
|
|
12830
13275
|
};
|
|
12831
13276
|
const makeQrlFn = (qrl) => {
|
|
12832
|
-
// The QRL has to be callable, so we create a function
|
|
13277
|
+
// The QRL has to be callable, so we create a function and attach the per-instance state to it.
|
|
12833
13278
|
const qrlFn = async function (...args) {
|
|
12834
|
-
return
|
|
13279
|
+
return qrlCallFn.call(qrlFn, this, ...args);
|
|
12835
13280
|
};
|
|
12836
|
-
|
|
12837
|
-
Object.setPrototypeOf(qrlFn,
|
|
13281
|
+
qrlFn[QRL_STATE] = qrl;
|
|
13282
|
+
Object.setPrototypeOf(qrlFn, QRL_FUNCTION_PROTO);
|
|
12838
13283
|
return qrlFn;
|
|
12839
13284
|
};
|
|
12840
13285
|
const EMITTED = /*#__PURE__*/ new Set();
|
|
@@ -14046,6 +14491,31 @@ const useErrorBoundary = () => {
|
|
|
14046
14491
|
return error;
|
|
14047
14492
|
};
|
|
14048
14493
|
|
|
14494
|
+
/** @internal */
|
|
14495
|
+
const eachCmpTask = async ({ track }) => {
|
|
14496
|
+
const props = _captures[0];
|
|
14497
|
+
track(() => props.items);
|
|
14498
|
+
const context = tryGetInvokeContext();
|
|
14499
|
+
const host = context.$hostElement$;
|
|
14500
|
+
const container = context.$container$;
|
|
14501
|
+
markVNodeDirty(container, host, 128 /* ChoreBits.RECONCILE */);
|
|
14502
|
+
const isSsr = import.meta.env.TEST ? isServerPlatform() : isServer;
|
|
14503
|
+
if (isSsr) {
|
|
14504
|
+
await container.$renderPromise$;
|
|
14505
|
+
}
|
|
14506
|
+
};
|
|
14507
|
+
/** @internal */
|
|
14508
|
+
const eachCmp = (props) => {
|
|
14509
|
+
if (!__EXPERIMENTAL__.each) {
|
|
14510
|
+
throw new Error('Each is experimental and must be enabled with `experimental: ["each"]` in the `qwikVite` plugin.');
|
|
14511
|
+
}
|
|
14512
|
+
useTaskQrl(/*#__PURE__*/ inlinedQrl(eachCmpTask, '_eaT', [props]));
|
|
14513
|
+
return SkipRender;
|
|
14514
|
+
};
|
|
14515
|
+
/** @public @experimental */
|
|
14516
|
+
const Each = /*#__PURE__*/ componentQrl(
|
|
14517
|
+
/*#__PURE__*/ inlinedQrl(eachCmp, '_eaC'));
|
|
14518
|
+
|
|
14049
14519
|
// keep this import from core/build so the cjs build works
|
|
14050
14520
|
/**
|
|
14051
14521
|
* @deprecated This is no longer needed as the preloading happens automatically in qrl-class.ts.
|
|
@@ -14140,5 +14610,5 @@ if (import.meta.hot) {
|
|
|
14140
14610
|
});
|
|
14141
14611
|
}
|
|
14142
14612
|
|
|
14143
|
-
export { $, Fragment, NoSerializeSymbol, PrefetchGraph, PrefetchServiceWorker, RenderOnce, Resource, SSRComment, SSRRaw, SSRStream, SSRStreamBlock, SerializerSymbol, SkipRender, Slot, _CONST_PROPS, DomContainer as _DomContainer, _EFFECT_BACK_REF, EMPTY_ARRAY as _EMPTY_ARRAY, EMPTY_OBJ as _EMPTY_OBJ, _IMMUTABLE, _SharedContainer, SubscriptionData as _SubscriptionData, _UNINITIALIZED, _VAR_PROPS, _addProjection, _captures, _chk, createQRL as _createQRL, _deserialize, _dumpState, _executeSsrChores, _fnSignal, _getConstProps, _getContextContainer, _getContextEvent, _getContextHostElement, getDomContainer as _getDomContainer, _getQContainerElement, _getVarProps, _hasStoreEffects, _hmr, isJSXNode as _isJSXNode, isStore as _isStore, isStringifiable as _isStringifiable, isTask as _isTask, _jsxBranch, _jsxC, _jsxQ, _jsxS, _jsxSorted, _jsxSplit, mapApp_findIndx as _mapApp_findIndx, mapArray_get as _mapArray_get, mapArray_set as _mapArray_set, _noopQrl, _noopQrlDEV, preprocessState as _preprocessState, _qrlSync, qrlToString as _qrlToString, _regSymbol, _removeProjection, _res, _resolveContextWithoutSequentialScope, _restProps, _rsc, _run, _serialize, setEvent as _setEvent, _setProjectionTarget, scheduleTask as _task, _updateProjectionProps, _useHmr, _val, verifySerializable as _verifySerializable, vnode_ensureElementInflated as _vnode_ensureElementInflated, vnode_getAttrKeys as _vnode_getAttrKeys, vnode_getFirstChild as _vnode_getFirstChild, vnode_isMaterialized as _vnode_isMaterialized, vnode_isTextVNode as _vnode_isTextVNode, vnode_isVirtualVNode as _vnode_isVirtualVNode, vnode_toString as _vnode_toString, _waitUntilRendered, _walkJSX, _wrapProp, _wrapSignal, component$, componentQrl, createAsync$, createAsyncSignal as createAsyncQrl, createComputed$, createComputedSignal as createComputedQrl, createContextId, h as createElement, createSerializer$, createSerializerSignal as createSerializerQrl, createSignal, event$, eventQrl, forceStoreEffects, getDomContainer, getLocale, getPlatform, h, implicit$FirstArg, inlinedQrl, inlinedQrlDEV, isSignal, jsx, jsxDEV, jsxs, noSerialize, qrl, qrlDEV, render, setPlatform, sync$, untrack, unwrapStore, useAsync$, useAsyncQrl, useComputed$, useComputedQrl, useConstant, useContext, useContextProvider, useErrorBoundary, useId, useLexicalScope, useOn, useOnDocument, useOnWindow, useResource$, useResourceQrl, useSerializer$, useSerializerQrl, useServerData, useSignal, useStore, useStyles$, useStylesQrl, useStylesScoped$, useStylesScopedQrl, useTask$, useTaskQrl, useVisibleTask$, useVisibleTaskQrl, version, withLocale };
|
|
14613
|
+
export { $, Each, Fragment, NoSerializeSymbol, PrefetchGraph, PrefetchServiceWorker, RenderOnce, Resource, SSRComment, SSRRaw, SSRStream, SSRStreamBlock, SerializerSymbol, SkipRender, Slot, _CONST_PROPS, DomContainer as _DomContainer, _EFFECT_BACK_REF, EMPTY_ARRAY as _EMPTY_ARRAY, EMPTY_OBJ as _EMPTY_OBJ, _IMMUTABLE, _SharedContainer, SubscriptionData as _SubscriptionData, _UNINITIALIZED, _VAR_PROPS, _addProjection, _captures, _chk, createQRL as _createQRL, _deserialize, _dumpState, eachCmp as _eaC, eachCmpTask as _eaT, _executeSsrChores, _fnSignal, _getConstProps, _getContextContainer, _getContextEvent, _getContextHostElement, getDomContainer as _getDomContainer, _getQContainerElement, _getVarProps, _hasStoreEffects, _hmr, isJSXNode as _isJSXNode, isStore as _isStore, isStringifiable as _isStringifiable, isTask as _isTask, _jsxBranch, _jsxC, _jsxQ, _jsxS, _jsxSorted, _jsxSplit, mapApp_findIndx as _mapApp_findIndx, mapArray_get as _mapArray_get, mapArray_set as _mapArray_set, _noopQrl, _noopQrlDEV, preprocessState as _preprocessState, _qrlSync, qrlToString as _qrlToString, _regSymbol, _removeProjection, _res, _resolveContextWithoutSequentialScope, _restProps, _rsc, _run, _serialize, setEvent as _setEvent, _setProjectionTarget, scheduleTask as _task, _updateProjectionProps, _useHmr, _val, verifySerializable as _verifySerializable, vnode_ensureElementInflated as _vnode_ensureElementInflated, vnode_getAttrKeys as _vnode_getAttrKeys, vnode_getFirstChild as _vnode_getFirstChild, vnode_isMaterialized as _vnode_isMaterialized, vnode_isTextVNode as _vnode_isTextVNode, vnode_isVirtualVNode as _vnode_isVirtualVNode, vnode_toString as _vnode_toString, _waitUntilRendered, _walkJSX, _wrapProp, _wrapSignal, component$, componentQrl, createAsync$, createAsyncSignal as createAsyncQrl, createComputed$, createComputedSignal as createComputedQrl, createContextId, h as createElement, createSerializer$, createSerializerSignal as createSerializerQrl, createSignal, event$, eventQrl, forceStoreEffects, getDomContainer, getLocale, getPlatform, h, implicit$FirstArg, inlinedQrl, inlinedQrlDEV, isSignal, jsx, jsxDEV, jsxs, noSerialize, qrl, qrlDEV, render, setPlatform, sync$, untrack, unwrapStore, useAsync$, useAsyncQrl, useComputed$, useComputedQrl, useConstant, useContext, useContextProvider, useErrorBoundary, useId, useLexicalScope, useOn, useOnDocument, useOnWindow, useResource$, useResourceQrl, useSerializer$, useSerializerQrl, useServerData, useSignal, useStore, useStyles$, useStylesQrl, useStylesScoped$, useStylesScopedQrl, useTask$, useTaskQrl, useVisibleTask$, useVisibleTaskQrl, version, withLocale };
|
|
14144
14614
|
//# sourceMappingURL=core.mjs.map
|