From 7d01bc8e6e205b66e4432dc72a4f4cbfbbc840eb Mon Sep 17 00:00:00 2001 From: Varixo Date: Mon, 24 Jun 2024 18:45:22 +0200 Subject: [PATCH 1/3] fix(v2): fix vnode separators --- packages/qwik/src/core/v2/client/process-vnode-data.ts | 1 - packages/qwik/src/core/v2/shared/vnode-data-types.ts | 10 +++++----- packages/qwik/src/server/v2-ssr-container.ts | 4 ++-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/packages/qwik/src/core/v2/client/process-vnode-data.ts b/packages/qwik/src/core/v2/client/process-vnode-data.ts index c48541254d6..87edb31de55 100644 --- a/packages/qwik/src/core/v2/client/process-vnode-data.ts +++ b/packages/qwik/src/core/v2/client/process-vnode-data.ts @@ -245,7 +245,6 @@ export function processVNodeData(document: Document) { ch = VNodeDataSeparator.ADVANCE_1; } } - vData_end = vData_start; vData_end = findVDataSectionEnd(vData, vData_start, vData_length); } else { vNodeElementIndex = Number.MAX_SAFE_INTEGER; diff --git a/packages/qwik/src/core/v2/shared/vnode-data-types.ts b/packages/qwik/src/core/v2/shared/vnode-data-types.ts index 40938e04781..535986c6e6f 100644 --- a/packages/qwik/src/core/v2/shared/vnode-data-types.ts +++ b/packages/qwik/src/core/v2/shared/vnode-data-types.ts @@ -24,8 +24,8 @@ export const VNodeDataSeparator = { ADVANCE_16: /* ******** */ 37, // `%` is vNodeData separator skipping 8. ADVANCE_32_CH: /* **** */ `&`, // `&` is vNodeData separator skipping 16. ADVANCE_32: /* ******** */ 38, // `&` is vNodeData separator skipping 16. - ADVANCE_64_CH: /* **** */ '`', // '`'` is vNodeData separator skipping 32. - ADVANCE_64: /* ******** */ 39, // '`'` is vNodeData separator skipping 32. + ADVANCE_64_CH: /* **** */ `'`, // `'` is vNodeData separator skipping 32. + ADVANCE_64: /* ******** */ 39, // `'` is vNodeData separator skipping 32. ADVANCE_128_CH: /* *** */ `(`, // `(` is vNodeData separator skipping 64. ADVANCE_128: /* ******* */ 40, // `(` is vNodeData separator skipping 64. ADVANCE_256_CH: /* *** */ `)`, // `)` is vNodeData separator skipping 128. @@ -34,12 +34,12 @@ export const VNodeDataSeparator = { ADVANCE_512: /* ******* */ 42, // `*` is vNodeData separator skipping 256. ADVANCE_1024_CH: /* ** */ `+`, // `+` is vNodeData separator skipping 512. ADVANCE_1024: /* ****** */ 43, // `+` is vNodeData separator skipping 512. - ADVANCE_2048_CH: /* * */ '`', // '`'` is vNodeData separator skipping 1024. - ADVANCE_2048: /* ****** */ 44, // '`'` is vNodeData separator skipping 1024. + ADVANCE_2048_CH: /* * */ ',', // ',' is vNodeData separator skipping 1024. + ADVANCE_2048: /* ****** */ 44, // ',' is vNodeData separator skipping 1024. ADVANCE_4096_CH: /* * */ `.`, // `.` is vNodeData separator skipping 2048. ADVANCE_4096: /* ****** */ 46, // `.` is vNodeData separator skipping 2048. ADVANCE_8192_CH: /* * */ `/`, // `/` is vNodeData separator skipping 4096. - ADVANCE_9102: /* ****** */ 47, // `/` is vNodeData separator skipping 4096. + ADVANCE_8192: /* ****** */ 47, // `/` is vNodeData separator skipping 4096. }; /** VNodeDataChar contains information about the VNodeData used for encoding props */ diff --git a/packages/qwik/src/server/v2-ssr-container.ts b/packages/qwik/src/server/v2-ssr-container.ts index 4495753cf4f..6d756bfd99b 100644 --- a/packages/qwik/src/server/v2-ssr-container.ts +++ b/packages/qwik/src/server/v2-ssr-container.ts @@ -621,7 +621,7 @@ class SSRContainer extends _SharedContainer implements ISSRContainer { if (flag !== VNodeDataFlag.NONE) { lastSerializedIdx = this.emitVNodeSeparators(lastSerializedIdx, elementIdx); if (flag & VNodeDataFlag.REFERENCE) { - this.write('~'); + this.write(VNodeDataSeparator.REFERENCE_CH); } if (flag & (VNodeDataFlag.TEXT_DATA | VNodeDataFlag.VIRTUAL_NODE)) { let fragmentAttrs: SsrAttrs | null = null; @@ -956,7 +956,7 @@ class SSRContainer extends _SharedContainer implements ISSRContainer { let skipCount = elementIdx - lastSerializedIdx; // console.log('emitVNodeSeparators', lastSerializedIdx, elementIdx, skipCount); while (skipCount != 0) { - if (skipCount >= 4096) { + if (skipCount > 4096) { this.write(VNodeDataSeparator.ADVANCE_8192_CH); skipCount -= 8192; } else { From d8a1a58b619df778e184171801b873f0afd3ca88 Mon Sep 17 00:00:00 2001 From: Varixo Date: Mon, 24 Jun 2024 22:15:48 +0200 Subject: [PATCH 2/3] add vnode encoding for ELEMENT_SEQ_IDX --- packages/qwik/src/core/use/use-sequential-scope.ts | 8 +++----- packages/qwik/src/core/util/markers.ts | 1 + packages/qwik/src/core/v2/client/dom-container.ts | 4 ++-- packages/qwik/src/core/v2/client/vnode.ts | 3 +++ packages/qwik/src/core/v2/shared/component-execution.ts | 5 ++--- packages/qwik/src/core/v2/shared/vnode-data-types.ts | 2 ++ packages/qwik/src/server/qwik-copy.ts | 1 + packages/qwik/src/server/v2-ssr-container.ts | 4 ++++ 8 files changed, 18 insertions(+), 10 deletions(-) diff --git a/packages/qwik/src/core/use/use-sequential-scope.ts b/packages/qwik/src/core/use/use-sequential-scope.ts index 05ca6e6c5ec..83b6e4aee97 100644 --- a/packages/qwik/src/core/use/use-sequential-scope.ts +++ b/packages/qwik/src/core/use/use-sequential-scope.ts @@ -1,6 +1,6 @@ import { verifySerializable } from '../state/common'; import { getContext, type QContext } from '../state/context'; -import { ELEMENT_SEQ } from '../util/markers'; +import { ELEMENT_SEQ, ELEMENT_SEQ_IDX } from '../util/markers'; import { qDev, qSerialize } from '../util/qdev'; import type { fixMeAny, HostElement } from '../v2/shared/types'; import { useInvokeContext, type RenderInvokeContext } from './use-core'; @@ -31,11 +31,11 @@ export const useSequentialScope = (): SequentialScope => { seq = []; iCtx.$container2$.setHostProp(host, ELEMENT_SEQ, seq); } - let seqIdx = iCtx.$container2$.getHostProp(host, SEQ_IDX_LOCAL); + let seqIdx = iCtx.$container2$.getHostProp(host, ELEMENT_SEQ_IDX); if (seqIdx === null) { seqIdx = 0; } - iCtx.$container2$.setHostProp(host, SEQ_IDX_LOCAL, seqIdx + 1); + iCtx.$container2$.setHostProp(host, ELEMENT_SEQ_IDX, seqIdx + 1); while (seq.length <= seqIdx) { seq.push(undefined); } @@ -73,5 +73,3 @@ export const useSequentialScope = (): SequentialScope => { }; } }; - -export const SEQ_IDX_LOCAL = 'q:seqIdx'; diff --git a/packages/qwik/src/core/util/markers.ts b/packages/qwik/src/core/util/markers.ts index 6da54af44e8..84ef22318a4 100644 --- a/packages/qwik/src/core/util/markers.ts +++ b/packages/qwik/src/core/util/markers.ts @@ -71,6 +71,7 @@ export const ELEMENT_ID = 'q:id'; export const ELEMENT_KEY = 'q:key'; export const ELEMENT_PROPS = 'q:props'; export const ELEMENT_SEQ = 'q:seq'; +export const ELEMENT_SEQ_IDX = 'q:seqIdx'; export const ELEMENT_SELF_ID = -1; export const ELEMENT_ID_SELECTOR = '[q\\:id]'; export const ELEMENT_ID_PREFIX = '#'; diff --git a/packages/qwik/src/core/v2/client/dom-container.ts b/packages/qwik/src/core/v2/client/dom-container.ts index 252a6b18c23..624744f5eca 100644 --- a/packages/qwik/src/core/v2/client/dom-container.ts +++ b/packages/qwik/src/core/v2/client/dom-container.ts @@ -8,12 +8,12 @@ import { ERROR_CONTEXT, isRecoverable } from '../../render/error-handling'; import type { JSXOutput } from '../../render/jsx/types/jsx-node'; import type { StoreTracker } from '../../state/store'; import type { ContextId } from '../../use/use-context'; -import { SEQ_IDX_LOCAL } from '../../use/use-sequential-scope'; import { EMPTY_ARRAY } from '../../util/flyweight'; import { throwErrorAndStop } from '../../util/log'; import { ELEMENT_PROPS, ELEMENT_SEQ, + ELEMENT_SEQ_IDX, OnRenderProp, QContainerAttr, QContainerSelector, @@ -263,7 +263,7 @@ export class DomContainer extends _SharedContainer implements IClientContainer, case QCtxAttr: getObjectById = this.$getObjectById$; break; - case SEQ_IDX_LOCAL: + case ELEMENT_SEQ_IDX: getObjectById = parseInt; break; } diff --git a/packages/qwik/src/core/v2/client/vnode.ts b/packages/qwik/src/core/v2/client/vnode.ts index b8f51df580a..ea34fdf6210 100644 --- a/packages/qwik/src/core/v2/client/vnode.ts +++ b/packages/qwik/src/core/v2/client/vnode.ts @@ -128,6 +128,7 @@ import { ELEMENT_KEY, ELEMENT_PROPS, ELEMENT_SEQ, + ELEMENT_SEQ_IDX, OnRenderProp, QContainerAttr, QContainerAttrEnd, @@ -1688,6 +1689,8 @@ function materializeFromVNodeData( vnode_setAttr(null, vParent, ELEMENT_KEY, consumeValue()); } else if (peek() === VNodeDataChar.SEQ) { vnode_setAttr(null, vParent, ELEMENT_SEQ, consumeValue()); + } else if (peek() === VNodeDataChar.SEQ_IDX) { + vnode_setAttr(null, vParent, ELEMENT_SEQ_IDX, consumeValue()); } else if (peek() === VNodeDataChar.CONTEXT) { vnode_setAttr(null, vParent, QCtxAttr, consumeValue()); } else if (peek() === VNodeDataChar.OPEN) { diff --git a/packages/qwik/src/core/v2/shared/component-execution.ts b/packages/qwik/src/core/v2/shared/component-execution.ts index 9e0d44edbfb..531276448ff 100644 --- a/packages/qwik/src/core/v2/shared/component-execution.ts +++ b/packages/qwik/src/core/v2/shared/component-execution.ts @@ -6,9 +6,8 @@ import type { JSXNode, JSXOutput } from '../../render/jsx/types/jsx-node'; import { SubscriptionType } from '../../state/common'; import { invokeApply, newInvokeContext } from '../../use/use-core'; import { USE_ON_LOCAL, type UseOnMap } from '../../use/use-on'; -import { SEQ_IDX_LOCAL } from '../../use/use-sequential-scope'; import { EMPTY_OBJ } from '../../util/flyweight'; -import { ELEMENT_PROPS, OnRenderProp, RenderEvent } from '../../util/markers'; +import { ELEMENT_PROPS, ELEMENT_SEQ_IDX, OnRenderProp, RenderEvent } from '../../util/markers'; import { isPromise, safeCall } from '../../util/promises'; import type { ValueOrPromise } from '../../util/types'; import type { Container2, HostElement, fixMeAny } from './types'; @@ -73,7 +72,7 @@ export const executeComponent2 = ( const executeComponentWithPromiseExceptionRetry = (): ValueOrPromise => safeCall( () => { - container.setHostProp(renderHost, SEQ_IDX_LOCAL, null); + container.setHostProp(renderHost, ELEMENT_SEQ_IDX, null); container.setHostProp(renderHost, ELEMENT_PROPS, props); return componentFn(props); }, diff --git a/packages/qwik/src/core/v2/shared/vnode-data-types.ts b/packages/qwik/src/core/v2/shared/vnode-data-types.ts index 535986c6e6f..7c755ba3c54 100644 --- a/packages/qwik/src/core/v2/shared/vnode-data-types.ts +++ b/packages/qwik/src/core/v2/shared/vnode-data-types.ts @@ -67,6 +67,8 @@ export const VNodeDataChar = { DON_T_USE_CHAR: '\\', CONTEXT: /* ************ */ 93, // `]` - `q:ctx' - Component context/props CONTEXT_CHAR: /* **** */ ']', + SEQ_IDX: /* ************ */ 94, // `[` - `q:seqIdx' - Sequential scope id + SEQ_IDX_CHAR: /* **** */ '^', SEPARATOR: /* ********* */ 124, // `|` - Separator char to encode any key/value pairs. SEPARATOR_CHAR: /* ** */ '|', SLOT: /* ************** */ 126, // `~` - `q:slot' - Slot name diff --git a/packages/qwik/src/server/qwik-copy.ts b/packages/qwik/src/server/qwik-copy.ts index f039eb812cd..9d52768bb26 100644 --- a/packages/qwik/src/server/qwik-copy.ts +++ b/packages/qwik/src/server/qwik-copy.ts @@ -20,6 +20,7 @@ export { ELEMENT_KEY, ELEMENT_PROPS, ELEMENT_SEQ, + ELEMENT_SEQ_IDX, OnRenderProp, QContainerAttr, QCtxAttr, diff --git a/packages/qwik/src/server/v2-ssr-container.ts b/packages/qwik/src/server/v2-ssr-container.ts index 6d756bfd99b..976c8ab0742 100644 --- a/packages/qwik/src/server/v2-ssr-container.ts +++ b/packages/qwik/src/server/v2-ssr-container.ts @@ -19,6 +19,7 @@ import { ELEMENT_KEY, ELEMENT_PROPS, ELEMENT_SEQ, + ELEMENT_SEQ_IDX, OnRenderProp, QCtxAttr, QScopedStyle, @@ -701,6 +702,9 @@ class SSRContainer extends _SharedContainer implements ISSRContainer { case ELEMENT_SEQ: write(VNodeDataChar.SEQ_CHAR); break; + case ELEMENT_SEQ_IDX: + write(VNodeDataChar.SEQ_IDX_CHAR); + break; // Skipping `\` character for now because it is used for escaping. case QCtxAttr: write(VNodeDataChar.CONTEXT_CHAR); From 592316ed46c494a9c6bc991d3fe94b4687fbe5f4 Mon Sep 17 00:00:00 2001 From: Varixo Date: Tue, 25 Jun 2024 16:21:57 +0200 Subject: [PATCH 3/3] fix vnode separators --- packages/qwik/src/core/v2/client/process-vnode-data.ts | 3 ++- packages/qwik/src/core/v2/shared/vnode-data-types.ts | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/qwik/src/core/v2/client/process-vnode-data.ts b/packages/qwik/src/core/v2/client/process-vnode-data.ts index 87edb31de55..f3b3d27973e 100644 --- a/packages/qwik/src/core/v2/client/process-vnode-data.ts +++ b/packages/qwik/src/core/v2/client/process-vnode-data.ts @@ -110,7 +110,8 @@ export function processVNodeData(document: Document) { return NodeType.OTHER; }; - const isSeparator = (ch: number) => /* `!` */ 33 <= ch && ch <= 47; /* `/` */ + const isSeparator = (ch: number) => + /* `!` */ VNodeDataSeparator.ADVANCE_1 <= ch && ch <= VNodeDataSeparator.ADVANCE_8192; /* `.` */ /** * Given the `vData` string, `start` index, and `end` index, find the end of the VNodeData * section. diff --git a/packages/qwik/src/core/v2/shared/vnode-data-types.ts b/packages/qwik/src/core/v2/shared/vnode-data-types.ts index 7c755ba3c54..c4d4ed49f8e 100644 --- a/packages/qwik/src/core/v2/shared/vnode-data-types.ts +++ b/packages/qwik/src/core/v2/shared/vnode-data-types.ts @@ -36,10 +36,10 @@ export const VNodeDataSeparator = { ADVANCE_1024: /* ****** */ 43, // `+` is vNodeData separator skipping 512. ADVANCE_2048_CH: /* * */ ',', // ',' is vNodeData separator skipping 1024. ADVANCE_2048: /* ****** */ 44, // ',' is vNodeData separator skipping 1024. - ADVANCE_4096_CH: /* * */ `.`, // `.` is vNodeData separator skipping 2048. - ADVANCE_4096: /* ****** */ 46, // `.` is vNodeData separator skipping 2048. - ADVANCE_8192_CH: /* * */ `/`, // `/` is vNodeData separator skipping 4096. - ADVANCE_8192: /* ****** */ 47, // `/` is vNodeData separator skipping 4096. + ADVANCE_4096_CH: /* * */ `-`, // `.` is vNodeData separator skipping 2048. + ADVANCE_4096: /* ****** */ 45, // `.` is vNodeData separator skipping 2048. + ADVANCE_8192_CH: /* * */ `.`, // `/` is vNodeData separator skipping 4096. + ADVANCE_8192: /* ****** */ 46, // `/` is vNodeData separator skipping 4096. }; /** VNodeDataChar contains information about the VNodeData used for encoding props */ @@ -67,7 +67,7 @@ export const VNodeDataChar = { DON_T_USE_CHAR: '\\', CONTEXT: /* ************ */ 93, // `]` - `q:ctx' - Component context/props CONTEXT_CHAR: /* **** */ ']', - SEQ_IDX: /* ************ */ 94, // `[` - `q:seqIdx' - Sequential scope id + SEQ_IDX: /* ************ */ 94, // `^` - `q:seqIdx' - Sequential scope id SEQ_IDX_CHAR: /* **** */ '^', SEPARATOR: /* ********* */ 124, // `|` - Separator char to encode any key/value pairs. SEPARATOR_CHAR: /* ** */ '|',