77 getStatefulHooks ,
88 getStatefulHookValue ,
99 getComponent ,
10+ isRoot ,
11+ getActualChildren ,
1012} from "./bindings" ;
1113import {
1214 addDebugValue ,
@@ -42,6 +44,7 @@ function trackPrevState(Ctor: ComponentConstructor) {
4244export function setupOptionsV10 (
4345 options : Options ,
4446 renderer : Renderer ,
47+ roots : Map < VNode , Node > ,
4548 config : RendererConfig ,
4649) {
4750 // Track component state. Only supported in Preact > 10.4.0
@@ -58,6 +61,7 @@ export function setupOptionsV10(
5861 // Store (possible) previous hooks so that we don't overwrite them
5962 const prevVNodeHook = options . vnode ;
6063 const prevCommitRoot = o . _commit || o . __c ;
64+ const prevRoot = o . _root || o . __ ;
6165 const prevBeforeUnmount = options . unmount ;
6266 const prevBeforeDiff = o . _diff || o . __b ;
6367 const prevRender = o . _render || o . __r ;
@@ -164,18 +168,44 @@ export function setupOptionsV10(
164168 if ( prevAfterDiff ) prevAfterDiff ( vnode ) ;
165169 } ;
166170
171+ const userRootToContainer = new Map < VNode , Node > ( ) ;
167172 o . _commit = o . __c = ( vnode : VNode | null , queue : any [ ] ) => {
168173 if ( prevCommitRoot ) prevCommitRoot ( vnode , queue ) ;
169174
170175 // These cases are already handled by `unmount`
171176 if ( vnode == null ) return ;
177+ if ( isRoot ( vnode , config ) ) {
178+ const children = getActualChildren ( vnode ) ;
179+ if ( children . length > 0 ) {
180+ const dom = userRootToContainer . get ( children [ 0 ] as any ) ;
181+ if ( dom ) {
182+ roots . set ( vnode , dom ) ;
183+ }
184+ }
185+ }
172186
173187 const tmpTimings = timings ;
174188 ownerStack = [ ] ;
175189 timings = createVNodeTimings ( ) ;
176190 renderer . onCommit ( vnode , owners , tmpTimings , null ) ;
177191 } ;
178192
193+ o . _root = o . __ = ( vnode : VNode , parent : Node | null ) => {
194+ if ( parent === null ) {
195+ userRootToContainer . delete ( vnode ) ;
196+ } else {
197+ // Some islands based frameworks use a virtual container node
198+ // instead of an actual DOM node.
199+ const treeParent =
200+ "Node" in globalThis && parent instanceof Node
201+ ? parent
202+ : ( parent as any ) . parentNode ;
203+ userRootToContainer . set ( vnode , treeParent ) ;
204+ }
205+
206+ if ( prevRoot ) prevRoot ( vnode , parent ) ;
207+ } ;
208+
179209 options . unmount = vnode => {
180210 if ( prevBeforeUnmount ) prevBeforeUnmount ( vnode ) ;
181211 if ( vnode . type !== null ) {
0 commit comments