1- import { RendererConfig10 } from "./renderer" ;
2- import { HookType } from "../../constants" ;
3-
1+ import { HookType } from "../shared/hooks" ;
42import type { Component , VNode } from "preact" ;
53import type {
64 Component as IComponent ,
75 VNode as IVNode ,
86} from "preact/src/internal" ;
9-
10- // These hook types are declared in "preact/hooks/src/internal" but not very
11- // complete, so for now loosely declare locally.
12- type ComponentHooks = Record < string , any > ;
13- type HookState = Record < string , any > ;
7+ import { ComponentHooks , HookState , PreactBindings } from "../shared/bindings" ;
8+ import { RendererConfig } from "../shared/renderer" ;
9+ import { getRenderReasonPost } from "./renderReason" ;
1410
1511// Mangle accessors
1612
@@ -30,7 +26,7 @@ export function getVNodeParent(vnode: VNode): VNode | null {
3026/**
3127 * Check if a `vnode` is the root of a tree
3228 */
33- export function isRoot ( vnode : VNode , config : RendererConfig10 ) : boolean {
29+ export function isRoot ( vnode : VNode , config : RendererConfig ) : boolean {
3430 return getVNodeParent ( vnode ) == null && vnode . type === config . Fragment ;
3531}
3632
@@ -64,12 +60,14 @@ export function isSuspenseVNode(vnode: VNode): boolean {
6460/**
6561 * Get the internal hooks state of a component
6662 */
67- export function getComponentHooks ( c : Component ) : ComponentHooks | null {
63+ export function getComponentHooks ( vnode : VNode ) : ComponentHooks | null {
64+ const c = getComponent ( vnode ) ;
65+ if ( ! c ) return null ;
6866 return ( c as any ) . __hooks || ( c as any ) . __H || null ;
6967}
7068
71- export function getStatefulHooks ( c : Component ) : HookState [ ] | null {
72- const hooks = getComponentHooks ( c ) ;
69+ export function getStatefulHooks ( vnode : VNode ) : HookState [ ] | null {
70+ const hooks = getComponentHooks ( vnode ) ;
7371 return hooks !== null
7472 ? hooks . _list ||
7573 hooks . __ ||
@@ -94,11 +92,14 @@ export function getStatefulHookValue(hookState: HookState): unknown {
9492}
9593
9694export function getHookState (
97- c : Component ,
95+ vnode : VNode ,
9896 index : number ,
9997 type ?: HookType ,
10098) : unknown {
101- const list = getStatefulHooks ( c ) ;
99+ const c = getComponent ( vnode ) ;
100+ if ( c === null ) return null ;
101+
102+ const list = getStatefulHooks ( vnode ) ;
102103 if ( list && list [ index ] ) {
103104 // useContext
104105 if ( type === HookType . useContext ) {
@@ -136,7 +137,7 @@ export function getActualChildren(
136137/**
137138 * Get the root of a `vnode`
138139 */
139- export function findRoot ( vnode : VNode , config : RendererConfig10 ) : VNode {
140+ export function findRoot ( vnode : VNode , config : RendererConfig ) : VNode {
140141 let next : VNode | null = vnode ;
141142 while ( ( next = getVNodeParent ( next ) ) != null ) {
142143 if ( isRoot ( next , config ) ) {
@@ -162,7 +163,7 @@ export function getAncestor(vnode: VNode): VNode | null {
162163/**
163164 * Get human readable name of the component/dom element
164165 */
165- export function getDisplayName ( vnode : VNode , config : RendererConfig10 ) : string {
166+ export function getDisplayName ( vnode : VNode , config : RendererConfig ) : string {
166167 const { type } = vnode ;
167168 if ( type === config . Fragment ) return "Fragment" ;
168169 else if ( typeof type === "function" ) {
@@ -218,7 +219,7 @@ export function setNextState<S>(c: Component, value: S): S {
218219 return ( ( c as IComponent ) . _nextState = ( c as any ) . __s = value ) ;
219220}
220221
221- export function getSuspenseStateKey ( c : Component < any , any > ) {
222+ function getSuspenseStateKey ( c : Component < any , any > ) {
222223 if ( "_suspended" in c . state ) {
223224 return "_suspended" ;
224225 } else if ( "__e" in c . state ) {
@@ -235,6 +236,22 @@ export function getSuspenseStateKey(c: Component<any, any>) {
235236 return null ;
236237}
237238
239+ export function getSuspendedState ( vnode : VNode ) {
240+ const c = getComponent ( vnode ) ;
241+ if ( c ) {
242+ const key = getSuspenseStateKey ( c ) ;
243+ if ( key ) {
244+ return ! ! ( c as any ) . _nextState [ key ] ;
245+ }
246+ }
247+
248+ return null ;
249+ }
250+
251+ export function isTextVNode ( vnode : VNode ) {
252+ return vnode !== null && vnode . type === null ;
253+ }
254+
238255export function createSuspenseState ( vnode : VNode , suspended : boolean ) {
239256 const c = getComponent ( vnode ) as Component < any , any > ;
240257 const key = getSuspenseStateKey ( c ) ;
@@ -244,3 +261,58 @@ export function createSuspenseState(vnode: VNode, suspended: boolean) {
244261
245262 return { } ;
246263}
264+
265+ export function getInstance ( vnode : VNode ) : any {
266+ // For components we use the instance to check refs, otherwise
267+ // we'll use a dom node
268+ if ( typeof vnode . type === "function" ) {
269+ return getComponent ( vnode ) ;
270+ }
271+
272+ return getDom ( vnode ) ;
273+ }
274+
275+ export function isComponent ( vnode : VNode ) {
276+ return vnode !== null && typeof vnode . type === "function" ;
277+ }
278+
279+ export function isVNode ( x : any ) : x is VNode {
280+ return x != null && x . type !== undefined && hasDom ( x ) ;
281+ }
282+
283+ export function isElement ( vnode : VNode ) : boolean {
284+ return typeof vnode . type === "string" ;
285+ }
286+
287+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
288+ export function isPortal ( vnode : VNode ) {
289+ // TODO: Find a way to detect portals
290+ return false ;
291+ }
292+
293+ export const bindingsV10 : PreactBindings < VNode > = {
294+ isRoot,
295+ getDisplayName,
296+ getPropsVNodeDisplayName : getDisplayName ,
297+ getActualChildren,
298+ getAncestor,
299+ getDom,
300+ isTextVNode,
301+ getInstance,
302+ createSuspenseState,
303+ getComponent,
304+ getComponentHooks,
305+ getHookState,
306+ getVNodeParent,
307+ isComponent,
308+ isElement,
309+ isSuspenseVNode,
310+ getSuspendedState,
311+ isVNode,
312+ setNextState,
313+ isPortal,
314+ getStatefulHookValue,
315+ getStatefulHooks,
316+ isUseReducerOrState,
317+ getRenderReasonPost,
318+ } ;
0 commit comments