@@ -14,8 +14,11 @@ import { isArr, createText, Suspense, ErrorBoundary } from './h'
1414import { commit , removeElement } from './commit'
1515
1616let currentFiber : Fiber = null
17+ let currentDom : Node | null = null
18+
1719export const render = ( vnode : Fiber , node : Node ) => {
18- if ( node . firstChild ) node . removeChild ( node . firstChild ) // no hydrating
20+ currentDom = node . firstChild
21+
1922 let rootFiber = {
2023 node,
2124 props : { children : vnode } ,
@@ -70,15 +73,8 @@ const capture = (fiber: Fiber) => {
7073 fiber . memo = false
7174 return sibling ( fiber )
7275 }
73- try {
74- updateHook ( fiber )
75- } catch ( e ) {
76- if ( e instanceof Promise ) {
77- return suspenseRender ( fiber , e ) . child
78- } else {
79- return errorBoundaryRender ( fiber , e ) . child
80- }
81- }
76+ updateHook ( fiber )
77+
8278 } else {
8379 updateHost ( fiber as FiberHost )
8480 }
@@ -141,16 +137,37 @@ const updateHook = (fiber: Fiber) => {
141137 resetCursor ( )
142138 resetFiber ( fiber )
143139 fiber . node = fiber . node || fragment ( fiber )
144- let children = ( fiber . type as FC ) ( fiber . props )
145- reconcileChildren ( fiber , simpleVnode ( children ) )
140+ try {
141+ let children = ( fiber . type as FC ) ( fiber . props )
142+ reconcileChildren ( fiber , simpleVnode ( children ) )
143+ } catch ( e ) {
144+ if ( e instanceof Promise ) {
145+ return suspenseRender ( fiber , e ) . child
146+ } else {
147+ return errorBoundaryRender ( fiber , e ) . child
148+ }
149+ }
146150}
147151
148152const updateHost = ( fiber : FiberHost ) => {
153+ if ( fiber . type ) {
154+ const ssrDom = currentDom
155+ if ( ssrDom ) {
156+ if ( fiber . type !== ssrDom . nodeName . toLowerCase ( ) ) {
157+ removeElement ( { node : ssrDom } as FiberFinish )
158+ fiber . kids = [ ] // all kids should INSERT
159+ } else {
160+ fiber . action . op = TAG . UPDATE
161+ }
162+ }
163+ currentDom = ssrDom ? nextDom ( ssrDom ) : null
164+ }
149165
150166 if ( ! fiber . node ) {
151167 if ( fiber . type === 'svg' ) fiber . lane |= TAG . SVG
152168 fiber . node = createElement ( fiber )
153169 }
170+
154171 reconcileChildren ( fiber , fiber . props . children )
155172}
156173
@@ -205,7 +222,6 @@ const diff = (aCh: Fiber[], bCh: Fiber[]) => {
205222 aTail = aCh . length - 1 ,
206223 bTail = bCh . length - 1 ,
207224 bMap = { } ,
208- same = ( a : Fiber , b : Fiber ) => ( a . type === b . type && a . key === b . key ) ,
209225 temp = [ ] ,
210226 actions = [ ]
211227
@@ -270,6 +286,24 @@ const diff = (aCh: Fiber[], bCh: Fiber[]) => {
270286 return actions
271287}
272288
289+ function nextDom ( currentNode : Node | null ) : Node | null {
290+ if ( ! currentNode ) return null
291+ if ( currentNode . firstChild ) {
292+ return currentNode . firstChild
293+ }
294+ let node = currentNode
295+ while ( node ) {
296+ if ( node . nextSibling ) {
297+ return node . nextSibling
298+ }
299+ node = node . parentNode
300+ }
301+
302+ return null
303+ }
304+
305+ const same = ( a : Fiber , b : Fiber ) => a && b && ( a . type === b . type && a . key === b . key )
306+
273307export const useFiber = ( ) => currentFiber || null
274308export const resetFiber = ( fiber : Fiber ) => currentFiber = fiber
275309export const isFn = ( x : unknown ) : x is Function => typeof x === 'function'
0 commit comments