} as HMRRuntime
}
-interface HMRRecord {
- comp: ComponentOptions
- instances: Set<ComponentInternalInstance>
-}
+type HMRRecord = Set<ComponentInternalInstance>
const map: Map<string, HMRRecord> = new Map()
createRecord(id, instance.type as ComponentOptions)
record = map.get(id)!
}
- record.instances.add(instance)
+ record.add(instance)
}
export function unregisterHMR(instance: ComponentInternalInstance) {
- map.get(instance.type.__hmrId!)!.instances.delete(instance)
+ map.get(instance.type.__hmrId!)!.delete(instance)
}
function createRecord(id: string, comp: ComponentOptions): boolean {
if (map.has(id)) {
return false
}
- map.set(id, {
- comp,
- instances: new Set()
- })
+ map.set(id, new Set())
return true
}
if (!record) return
// Array.from creates a snapshot which avoids the set being mutated during
// updates
- Array.from(record.instances).forEach(instance => {
+ Array.from(record).forEach(instance => {
if (newRender) {
instance.render = newRender as InternalRenderFunction
}
function reload(id: string, newComp: ComponentOptions) {
const record = map.get(id)
if (!record) return
- // 1. Update existing comp definition to match new one
- const comp = record.comp
- Object.assign(comp, newComp)
- for (const key in comp) {
- if (!(key in newComp)) {
- delete (comp as any)[key]
- }
- }
- // 2. Mark component dirty. This forces the renderer to replace the component
- // on patch.
- comp.__hmrUpdated = true
// Array.from creates a snapshot which avoids the set being mutated during
// updates
- Array.from(record.instances).forEach(instance => {
+ Array.from(record).forEach(instance => {
+ const comp = instance.type
+ if (!comp.__hmrUpdated) {
+ // 1. Update existing comp definition to match new one
+ Object.assign(comp, newComp)
+ for (const key in comp) {
+ if (!(key in newComp)) {
+ delete (comp as any)[key]
+ }
+ }
+ // 2. Mark component dirty. This forces the renderer to replace the component
+ // on patch.
+ comp.__hmrUpdated = true
+ // 3. Make sure to unmark the component after the reload.
+ queuePostFlushCb(() => {
+ comp.__hmrUpdated = false
+ })
+ }
+
if (instance.parent) {
- // 3. Force the parent instance to re-render. This will cause all updated
+ // 4. Force the parent instance to re-render. This will cause all updated
// components to be unmounted and re-mounted. Queue the update so that we
// don't end up forcing the same parent to re-render multiple times.
queueJob(instance.parent.update)
)
}
})
- // 4. Make sure to unmark the component after the reload.
- queuePostFlushCb(() => {
- comp.__hmrUpdated = false
- })
}
function tryWrap(fn: (id: string, arg: any) => any): Function {