// exposed properties via expose()
exposed: Record<string, any> | null
+ /**
+ * setup related
+ * @internal
+ */
+ setupState?: Data
+ /**
+ * devtools access to additional info
+ * @internal
+ */
+ devtoolsRawSetupState?: any
+
// lifecycle
isMounted: boolean
isUnmounted: boolean
* @internal
*/
[LifecycleHooks.SERVER_PREFETCH]?: LifecycleHook<() => Promise<unknown>>
+ /**
+ * @internal vapor only
+ */
+ hmrRerender?: () => void
}
/**
* @internal
*/
setupState: Data
- /**
- * devtools access to additional info
- * @internal
- */
- devtoolsRawSetupState?: any
// main proxy that serves as the public instance (`this`)
proxy: ComponentPublicInstance | null
// this flag forces child components with slot content to update
isHmrUpdating = true
if (instance.vapor) {
- // TODO
+ // @ts-expect-error TODO
+ instance.hmrRerender()
} else {
const i = instance as ComponentInternalInstance
i.renderCache = []
type AppUnmountFn,
} from './apiCreateApp'
export { currentInstance, setCurrentInstance } from './componentCurrentInstance'
+export { registerHMR, unregisterHMR } from './hmr'
if (this.scope) {
this.scope.off()
parent && remove(this.nodes, parent)
+ // TODO lifecycle unmount
}
if (render) {
nextUid,
popWarningContext,
pushWarningContext,
+ registerHMR,
setCurrentInstance,
warn,
} from '@vue/runtime-dom'
getSlot,
} from './componentSlots'
import { insert } from './dom/node'
+import { hmrRerender } from './hmr'
export { currentInstance } from '@vue/runtime-dom'
)
instance.block = []
} else {
- instance.setupState = setupResult
- instance.block = component.render.call(
- null,
- proxyRefs(setupResult),
- instance.props,
- instance.emit,
- instance.attrs,
- instance.slots,
- )
+ instance.devtoolsRawSetupState = setupResult
+ instance.setupState = proxyRefs(setupResult)
+ devRender(instance)
+
+ // HMR
+ registerHMR(instance)
+ instance.hmrRerender = hmrRerender.bind(null, instance)
}
} else {
// in prod result can only be block
return instance
}
+/**
+ * dev only
+ */
+export function devRender(instance: VaporComponentInstance): void {
+ instance.block = instance.type.render!.call(
+ null,
+ instance.setupState,
+ instance.props,
+ instance.emit,
+ instance.attrs,
+ instance.slots,
+ )
+}
+
const emptyContext: GenericAppContext = {
app: null as any,
config: {},
// dev only
setupState?: Record<string, any>
+ devtoolsRawSetupState?: any
+ hmrRerender?: () => void
propsOptions?: NormalizedPropsOptions
emitsOptions?: ObjectEmitsOptions | null
--- /dev/null
+import {
+ popWarningContext,
+ pushWarningContext,
+ setCurrentInstance,
+} from '@vue/runtime-core'
+import { normalizeBlock } from './block'
+import { type VaporComponentInstance, devRender } from './component'
+import { insert, remove } from './dom/node'
+
+export function hmrRerender(instance: VaporComponentInstance): void {
+ const normalized = normalizeBlock(instance.block)
+ const parent = normalized[0].parentNode!
+ const anchor = normalized[normalized.length - 1].nextSibling
+ remove(instance.block, parent)
+ const reset = setCurrentInstance(instance)
+ pushWarningContext(instance)
+ devRender(instance)
+ reset()
+ popWarningContext()
+ insert(instance.block, parent, anchor)
+}