|
|
@@ -62,10 +62,24 @@ import {
|
|
|
import { ErrorCodes, callWithErrorHandling } from './errorHandling'
|
|
|
import { KeepAliveSink, isKeepAlive } from './components/KeepAlive'
|
|
|
import { registerHMR, unregisterHMR } from './hmr'
|
|
|
-import { createHydrationFunctions } from './hydration'
|
|
|
+import { createHydrationFunctions, RootHydrateFunction } from './hydration'
|
|
|
|
|
|
const __HMR__ = __BUNDLER__ && __DEV__
|
|
|
|
|
|
+export interface Renderer<HostNode = any, HostElement = any> {
|
|
|
+ render: RootRenderFunction<HostNode, HostElement>
|
|
|
+ createApp: CreateAppFunction<HostElement>
|
|
|
+}
|
|
|
+
|
|
|
+export interface HydrationRenderer extends Renderer<Node, Element> {
|
|
|
+ hydrate: RootHydrateFunction
|
|
|
+}
|
|
|
+
|
|
|
+export type RootRenderFunction<HostNode, HostElement> = (
|
|
|
+ vnode: VNode<HostNode, HostElement> | null,
|
|
|
+ container: HostElement
|
|
|
+) => void
|
|
|
+
|
|
|
export interface RendererOptions<HostNode = any, HostElement = any> {
|
|
|
patchProp(
|
|
|
el: HostElement,
|
|
|
@@ -102,41 +116,6 @@ export interface RendererOptions<HostNode = any, HostElement = any> {
|
|
|
): HostElement
|
|
|
}
|
|
|
|
|
|
-export type RootRenderFunction<HostNode, HostElement> = (
|
|
|
- vnode: VNode<HostNode, HostElement> | null,
|
|
|
- dom: HostElement
|
|
|
-) => void
|
|
|
-
|
|
|
-// An object exposing the internals of a renderer, passed to tree-shakeable
|
|
|
-// features so that they can be decoupled from this file.
|
|
|
-export interface RendererInternals<HostNode = any, HostElement = any> {
|
|
|
- patch: (
|
|
|
- n1: VNode<HostNode, HostElement> | null, // null means this is a mount
|
|
|
- n2: VNode<HostNode, HostElement>,
|
|
|
- container: HostElement,
|
|
|
- anchor?: HostNode | null,
|
|
|
- parentComponent?: ComponentInternalInstance | null,
|
|
|
- parentSuspense?: SuspenseBoundary<HostNode, HostElement> | null,
|
|
|
- isSVG?: boolean,
|
|
|
- optimized?: boolean
|
|
|
- ) => void
|
|
|
- unmount: (
|
|
|
- vnode: VNode<HostNode, HostElement>,
|
|
|
- parentComponent: ComponentInternalInstance | null,
|
|
|
- parentSuspense: SuspenseBoundary<HostNode, HostElement> | null,
|
|
|
- doRemove?: boolean
|
|
|
- ) => void
|
|
|
- move: (
|
|
|
- vnode: VNode<HostNode, HostElement>,
|
|
|
- container: HostElement,
|
|
|
- anchor: HostNode | null,
|
|
|
- type: MoveType,
|
|
|
- parentSuspense?: SuspenseBoundary<HostNode, HostElement> | null
|
|
|
- ) => void
|
|
|
- next: (vnode: VNode<HostNode, HostElement>) => HostNode | null
|
|
|
- options: RendererOptions<HostNode, HostElement>
|
|
|
-}
|
|
|
-
|
|
|
export const enum MoveType {
|
|
|
ENTER,
|
|
|
LEAVE,
|
|
|
@@ -186,25 +165,36 @@ export function createRenderer<
|
|
|
HostNode extends object = any,
|
|
|
HostElement extends HostNode = any
|
|
|
>(options: RendererOptions<HostNode, HostElement>) {
|
|
|
- const res = baseCreateRenderer(options)
|
|
|
- return res as typeof res & {
|
|
|
- hydrate: undefined
|
|
|
- }
|
|
|
+ return baseCreateRenderer<HostNode, HostElement>(options)
|
|
|
}
|
|
|
|
|
|
// Separate API for creating hydration-enabled renderer.
|
|
|
// Hydration logic is only used when calling this function, making it
|
|
|
// tree-shakable.
|
|
|
-export function createHydrationRenderer<
|
|
|
+export function createHydrationRenderer(
|
|
|
+ options: RendererOptions<Node, Element>
|
|
|
+) {
|
|
|
+ return baseCreateRenderer<Node, Element>(options, createHydrationFunctions)
|
|
|
+}
|
|
|
+
|
|
|
+// overload 1: no hydration
|
|
|
+function baseCreateRenderer<
|
|
|
HostNode extends object = any,
|
|
|
HostElement extends HostNode = any
|
|
|
->(options: RendererOptions<HostNode, HostElement>) {
|
|
|
- const res = baseCreateRenderer(options, createHydrationFunctions)
|
|
|
- return res as typeof res & {
|
|
|
- hydrate: ReturnType<typeof createHydrationFunctions>[0]
|
|
|
- }
|
|
|
-}
|
|
|
+>(
|
|
|
+ options: RendererOptions<HostNode, HostElement>
|
|
|
+): Renderer<HostNode, HostElement>
|
|
|
+
|
|
|
+// overload 2: with hydration
|
|
|
+function baseCreateRenderer<
|
|
|
+ HostNode extends object = any,
|
|
|
+ HostElement extends HostNode = any
|
|
|
+>(
|
|
|
+ options: RendererOptions<HostNode, HostElement>,
|
|
|
+ createHydrationFns: typeof createHydrationFunctions
|
|
|
+): HydrationRenderer
|
|
|
|
|
|
+// implementation
|
|
|
function baseCreateRenderer<
|
|
|
HostNode extends object = any,
|
|
|
HostElement extends HostNode = any
|
|
|
@@ -1862,6 +1852,36 @@ function baseCreateRenderer<
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// An object exposing the internals of a renderer, passed to tree-shakeable
|
|
|
+// features so that they can be decoupled from this file.
|
|
|
+export interface RendererInternals<HostNode = any, HostElement = any> {
|
|
|
+ patch: (
|
|
|
+ n1: VNode<HostNode, HostElement> | null, // null means this is a mount
|
|
|
+ n2: VNode<HostNode, HostElement>,
|
|
|
+ container: HostElement,
|
|
|
+ anchor?: HostNode | null,
|
|
|
+ parentComponent?: ComponentInternalInstance | null,
|
|
|
+ parentSuspense?: SuspenseBoundary<HostNode, HostElement> | null,
|
|
|
+ isSVG?: boolean,
|
|
|
+ optimized?: boolean
|
|
|
+ ) => void
|
|
|
+ unmount: (
|
|
|
+ vnode: VNode<HostNode, HostElement>,
|
|
|
+ parentComponent: ComponentInternalInstance | null,
|
|
|
+ parentSuspense: SuspenseBoundary<HostNode, HostElement> | null,
|
|
|
+ doRemove?: boolean
|
|
|
+ ) => void
|
|
|
+ move: (
|
|
|
+ vnode: VNode<HostNode, HostElement>,
|
|
|
+ container: HostElement,
|
|
|
+ anchor: HostNode | null,
|
|
|
+ type: MoveType,
|
|
|
+ parentSuspense?: SuspenseBoundary<HostNode, HostElement> | null
|
|
|
+ ) => void
|
|
|
+ next: (vnode: VNode<HostNode, HostElement>) => HostNode | null
|
|
|
+ options: RendererOptions<HostNode, HostElement>
|
|
|
+}
|
|
|
+
|
|
|
// https://en.wikipedia.org/wiki/Longest_increasing_subsequence
|
|
|
function getSequence(arr: number[]): number[] {
|
|
|
const p = arr.slice()
|