@@ -172,61 +172,84 @@ const side = (effects?: HookEffect[]) => {
172172 effects . length = 0
173173}
174174
175- const diff = function ( a : Fiber [ ] , b : Fiber [ ] ) {
176- var actions : Action [ ] = [ ] ,
177- aMap : Record < string , number | undefined > = { } ,
178- bMap : Record < string , number | undefined > = { } ,
179- key = ( v : Fiber ) => v . key ,
180- i : number ,
181- j : number
182- for ( i = 0 ; i < a . length ; i ++ ) {
183- aMap [ key ( a [ i ] ) ] = i
175+ const diff = ( aCh , bCh ) => {
176+ let aHead = 0 ,
177+ bHead = 0 ,
178+ aTail = aCh . length - 1 ,
179+ bTail = bCh . length - 1 ,
180+ aMap = null ,
181+ bMap = null ,
182+ key = ( v ) => v . key ,
183+ temp = [ ] ,
184+ actions = [ ]
185+
186+ while ( aHead <= aTail && bHead <= bTail ) {
187+ if ( key ( aCh [ aTail ] ) !== key ( bCh [ bTail ] ) ) break
188+ clone ( aCh [ aTail ] , bCh [ bTail ] )
189+ temp . push ( { op : TAG . UPDATE } )
190+ aTail --
191+ bTail --
184192 }
185- for ( i = 0 ; i < b . length ; i ++ ) {
186- bMap [ key ( b [ i ] ) ] = i
193+
194+ while ( aHead <= aTail && bHead <= bTail ) {
195+ if ( key ( aCh [ aHead ] ) !== key ( bCh [ bHead ] ) ) break
196+ clone ( aCh [ aHead ] , bCh [ bHead ] )
197+ actions . push ( { op : TAG . UPDATE } )
198+ aHead ++
199+ bHead ++
187200 }
188- for ( i = j = 0 ; i !== a . length || j !== b . length ; ) {
189- var aElm = a [ i ] ,
190- bElm = b [ j ]
201+ if ( ! aMap ) {
202+ aMap = { }
203+ for ( let i = aHead ; i <= aTail ; i ++ ) {
204+ aMap [ key ( aCh [ i ] ) ] = i
205+ }
206+ }
207+ if ( ! bMap ) {
208+ bMap = { }
209+ for ( let i = bHead ; i <= bTail ; i ++ ) {
210+ bMap [ key ( bCh [ i ] ) ] = i
211+ }
212+ }
213+ while ( aHead !== aTail + 1 || bHead !== bTail + 1 ) {
214+ var aElm = aCh [ aHead ] ,
215+ bElm = bCh [ bHead ]
191216 if ( aElm === null ) {
192- i ++
193- } else if ( b . length <= j ) {
217+ aHead ++
218+ } else if ( bTail + 1 <= bHead ) {
194219 removeElement ( aElm )
195- i ++
196- } else if ( a . length <= i ) {
220+ aHead ++
221+ } else if ( aTail + 1 <= aHead ) {
197222 actions . push ( { op : TAG . INSERT , cur : bElm , ref : aElm } )
198- j ++
223+ bHead ++
199224 } else if ( key ( aElm ) === key ( bElm ) ) {
200-
201225 if ( aElm . type === bElm . type ) {
202226 clone ( aElm , bElm )
203227 actions . push ( { op : TAG . UPDATE } )
204228 } else { // replace
205229 actions . push ( { op : TAG . REPLACE , cur : bElm , ref : aElm } )
206230 }
207-
208- i ++
209- j ++
231+ aHead ++
232+ bHead ++
210233 } else {
211234 var foundB = bMap [ key ( aElm ) ]
212235 var foundA = aMap [ key ( bElm ) ]
213236 if ( foundB === undefined ) {
214- removeElement ( a [ i ] )
215- i ++
237+ removeElement ( aElm )
238+ aHead ++
216239 } else if ( foundA === undefined ) {
217240 actions . push ( { op : TAG . INSERT , cur : bElm , ref : aElm } )
218- j ++
241+ bHead ++
219242 } else {
220- clone ( a [ foundA ] , bElm )
221- actions . push ( { op : TAG . MOVE , cur : a [ foundA ] , ref : aElm } )
222- a [ foundA ] = null
223- j ++
243+ clone ( aCh [ foundA ] , bElm )
244+ actions . push ( { op : TAG . MOVE , cur : aCh [ foundA ] , ref : aElm } )
245+ aCh [ foundA ] = null
246+ bHead ++
224247 }
225248 }
226249 }
250+ actions . concat ( temp )
227251 return actions
228252}
229-
230253export const getCurrentFiber = ( ) => currentFiber || null
231254export const isFn = ( x : unknown ) : x is Function => typeof x === 'function'
232255export const isStr = ( s : unknown ) : s is number | string =>
0 commit comments