diff --git a/packages/runtime-vapor/__tests__/dom/template.spec.ts b/packages/runtime-vapor/__tests__/dom/template.spec.ts index 85de30987..792c55242 100644 --- a/packages/runtime-vapor/__tests__/dom/template.spec.ts +++ b/packages/runtime-vapor/__tests__/dom/template.spec.ts @@ -20,8 +20,8 @@ describe('api: template', () => { test('nthChild', () => { const t = template('
nested

') - const root = t() - const span = nthChild(root, 0) + const root = t() as ParentNode + const span = nthChild(root, 0) as ParentNode const b = nthChild(span, 0) const p = nthChild(root, 1) expect(span).toBe(root.firstChild) @@ -31,7 +31,7 @@ describe('api: template', () => { test('next', () => { const t = template('

') - const root = t() + const root = t() as ParentNode const span = child(root as ParentNode) const b = next(span) diff --git a/packages/runtime-vapor/src/dom/hydration.ts b/packages/runtime-vapor/src/dom/hydration.ts index aab0e76e6..1b27a2e5f 100644 --- a/packages/runtime-vapor/src/dom/hydration.ts +++ b/packages/runtime-vapor/src/dom/hydration.ts @@ -30,6 +30,7 @@ function performHydration( // optimize anchor cache lookup ;(Comment.prototype as any).$fe = undefined ;(Node.prototype as any).$idx = undefined + ;(Node.prototype as any).$children = undefined isOptimized = true } enableHydrationNodeLookup() diff --git a/packages/runtime-vapor/src/dom/node.ts b/packages/runtime-vapor/src/dom/node.ts index 6a99e95ba..a43e8315c 100644 --- a/packages/runtime-vapor/src/dom/node.ts +++ b/packages/runtime-vapor/src/dom/node.ts @@ -2,8 +2,8 @@ import { type ChildItem, + type InsertionParent, getHydrationState, - getTemplateChildren, } from '../insertionState' export function createElement(tagName: string): HTMLElement { @@ -46,23 +46,23 @@ const __txt: typeof __child = (node: ParentNode): Node => { } /* @__NO_SIDE_EFFECTS__ */ -export function _child(node: ParentNode): Node { - const templateChildren = getTemplateChildren(node) - return templateChildren ? templateChildren[0] : node.firstChild! +export function _child(node: InsertionParent): Node { + const children = node.$children + return children ? children[0] : node.firstChild! } /** * Hydration-specific version of `child`. */ /* @__NO_SIDE_EFFECTS__ */ -export function __child(node: ParentNode & { $lpn?: Node }): Node { +export function __child(node: ParentNode): Node { return __nthChild(node, 0)! } /* @__NO_SIDE_EFFECTS__ */ -export function _nthChild(node: Node, i: number): Node { - const templateChildren = getTemplateChildren(node as ParentNode) - return templateChildren ? templateChildren[i] : node.childNodes[i] +export function _nthChild(node: InsertionParent, i: number): Node { + const children = node.$children + return children ? children[i] : node.childNodes[i] } /** @@ -92,10 +92,8 @@ export function __nthChild(node: Node, i: number): Node { /* @__NO_SIDE_EFFECTS__ */ export function _next(node: Node): Node { - const templateChildren = getTemplateChildren(node.parentNode!) - return templateChildren - ? templateChildren[(node as ChildItem).$idx + 1] - : node.nextSibling! + const children = (node.parentNode! as InsertionParent).$children + return children ? children[(node as ChildItem).$idx + 1] : node.nextSibling! } /** diff --git a/packages/runtime-vapor/src/insertionState.ts b/packages/runtime-vapor/src/insertionState.ts index bcfd900a6..3cd21600e 100644 --- a/packages/runtime-vapor/src/insertionState.ts +++ b/packages/runtime-vapor/src/insertionState.ts @@ -1,18 +1,16 @@ import { isHydrating } from './dom/hydration' -export interface ChildItem extends ChildNode { - $idx: number -} +export type ChildItem = ChildNode & { $idx: number } +export type InsertionParent = ParentNode & { $children?: ChildItem[] } + type HydrationState = { logicalChildren: ChildItem[] prevDynamicCount: number insertionAnchors: Map | null appendAnchor: Node | null } -export let insertionParent: ParentNode | undefined +export let insertionParent: InsertionParent | undefined export let insertionAnchor: Node | 0 | undefined | null -const templateChildrenCache = new WeakMap() - const hydrationStateCache = new WeakMap() /** @@ -87,22 +85,22 @@ function initializeHydrationState( function cacheTemplateChildren( anchor: number | Node | null | undefined, - parent: ParentNode, + parent: InsertionParent, ) { // special handling append anchor value to null insertionAnchor = typeof anchor === 'number' && anchor > 0 ? null : (anchor as Node) - if (!templateChildrenCache.has(parent)) { + if (!parent.$children) { const nodes = parent.childNodes const len = nodes.length - const children = new Array(len) + const children = new Array(len) as ChildItem[] for (let i = 0; i < len; i++) { const node = nodes[i] as ChildItem node.$idx = i children[i] = node } - templateChildrenCache.set(parent, children) + parent.$children = children } } @@ -110,12 +108,6 @@ export function resetInsertionState(): void { insertionParent = insertionAnchor = undefined } -export function getTemplateChildren( - parent: ParentNode, -): ChildItem[] | undefined { - return templateChildrenCache.get(parent) -} - export function getHydrationState( parent: ParentNode, ): HydrationState | undefined {