wip: prepare hmr for vapor

This commit is contained in:
Evan You 2024-12-08 16:32:29 +08:00
parent 6f5493c677
commit e8067f1cd9
No known key found for this signature in database
GPG Key ID: 00E9AB7A6704CE0A
2 changed files with 70 additions and 59 deletions

View File

@ -348,6 +348,10 @@ export interface GenericComponentInstance {
* @internal
*/
scope: EffectScope
/**
* render function will have different types between vdom and vapor
*/
render?: Function | null
/**
* SSR render function
* (they are the same between vdom and vapor components.)

View File

@ -4,7 +4,7 @@ import {
type ComponentInternalInstance,
type ComponentOptions,
type ConcreteComponent,
type InternalRenderFunction,
type GenericComponentInstance,
isClassComponent,
} from './component'
import { queueJob, queuePostFlushCb } from './scheduler'
@ -16,8 +16,8 @@ export let isHmrUpdating = false
export const hmrDirtyComponents: Map<
ConcreteComponent,
Set<ComponentInternalInstance>
> = new Map<ConcreteComponent, Set<ComponentInternalInstance>>()
Set<GenericComponentInstance>
> = new Map<ConcreteComponent, Set<GenericComponentInstance>>()
export interface HMRRuntime {
createRecord: typeof createRecord
@ -45,11 +45,11 @@ const map: Map<
// to apply hot updates to the component even when there are no actively
// rendered instance.
initialDef: ComponentOptions
instances: Set<ComponentInternalInstance>
instances: Set<GenericComponentInstance>
}
> = new Map()
export function registerHMR(instance: ComponentInternalInstance): void {
export function registerHMR(instance: GenericComponentInstance): void {
const id = instance.type.__hmrId!
let record = map.get(id)
if (!record) {
@ -59,7 +59,7 @@ export function registerHMR(instance: ComponentInternalInstance): void {
record.instances.add(instance)
}
export function unregisterHMR(instance: ComponentInternalInstance): void {
export function unregisterHMR(instance: GenericComponentInstance): void {
map.get(instance.type.__hmrId!)!.instances.delete(instance)
}
@ -90,13 +90,18 @@ function rerender(id: string, newRender?: Function): void {
// Create a snapshot which avoids the set being mutated during updates
;[...record.instances].forEach(instance => {
if (newRender) {
instance.render = newRender as InternalRenderFunction
instance.render = newRender
normalizeClassComponent(instance.type as HMRComponent).render = newRender
}
instance.renderCache = []
// this flag forces child components with slot content to update
isHmrUpdating = true
instance.update()
if (instance.vapor) {
// TODO
} else {
const i = instance as ComponentInternalInstance
i.renderCache = []
i.update()
}
isHmrUpdating = false
})
}
@ -112,8 +117,10 @@ function reload(id: string, newComp: HMRComponent): void {
// create a snapshot which avoids the set being mutated during updates
const instances = [...record.instances]
for (let i = 0; i < instances.length; i++) {
const instance = instances[i]
if (newComp.vapor) {
// TODO
} else {
for (const instance of instances as ComponentInternalInstance[]) {
const oldComp = normalizeClassComponent(instance.type as HMRComponent)
let dirtyInstances = hmrDirtyComponents.get(oldComp)
@ -167,7 +174,7 @@ function reload(id: string, newComp: HMRComponent): void {
instance.root.ce._removeChildStyle(oldComp)
}
}
}
// 5. make sure to cleanup dirty hmr components after update
queuePostFlushCb(() => {
hmrDirtyComponents.clear()