wip(vapor): more hydration

This commit is contained in:
Evan You 2025-03-07 19:45:46 +08:00
parent 64270ae1b4
commit e9d912a188
No known key found for this signature in database
GPG Key ID: 00E9AB7A6704CE0A
5 changed files with 2333 additions and 7 deletions

File diff suppressed because it is too large Load Diff

View File

@ -21,7 +21,7 @@ import {
import type { RawProps } from './componentProps'
import { getGlobalThis } from '@vue/shared'
import { optimizePropertyLookup } from './dom/prop'
import { withHydration } from './dom/hydrate'
import { withHydration } from './dom/hydration'
let _createApp: CreateAppFunction<ParentNode, VaporComponent>

View File

@ -7,7 +7,7 @@ import {
} from './component'
import { createComment, createTextNode } from './dom/node'
import { EffectScope, pauseTracking, resetTracking } from '@vue/reactivity'
import { isHydrating } from './dom/hydrate'
import { isHydrating } from './dom/hydration'
export type Block =
| Node

View File

@ -7,8 +7,16 @@ export function setCurrentHydrationNode(node: Node | null): void {
currentHydrationNode = node
}
let isOptimized = false
export function withHydration(container: ParentNode, fn: () => void): void {
adoptHydrationNode = adoptHydrationNodeImpl
if (!isOptimized) {
// optimize anchor cache lookup
const proto = Comment.prototype as any
proto.$p = proto.$e = undefined
isOptimized = true
}
isHydrating = true
currentHydrationNode = child(container)
const res = fn()
@ -48,7 +56,9 @@ function adoptHydrationNodeImpl(
let end: Node | undefined | null
if (template) {
while (node.nodeType === 8) node = next(node)
if (template[0] !== '<' && template[1] !== '!') {
while (node.nodeType === 8) node = next(node)
}
adopted = end = node
} else if (isComment(node, '[')) {
// fragment
@ -96,14 +106,16 @@ function adoptHydrationNodeImpl(
if (__DEV__ && template) {
const type = adopted.nodeType
if (
type === 8 ||
(type === 8 && !template.startsWith('<!')) ||
(type === 1 &&
!template.startsWith(
`<` + (adopted as Element).tagName.toLowerCase(),
)) ||
(type === 3 && !template.startsWith((adopted as Text).data))
(type === 3 &&
template.trim() &&
!template.startsWith((adopted as Text).data))
) {
// TODO recover
// TODO recover and provide more info
throw new Error('hydration mismatch!')
}
}

View File

@ -2,7 +2,7 @@ import {
adoptHydrationNode,
currentHydrationNode,
isHydrating,
} from './hydrate'
} from './hydration'
import { child } from './node'
let t: HTMLTemplateElement