1- //@ts -check
1+ //@ts -nocheck
22
33import DEBUG from '../debug.js' ;
44import errors from '../errors.js' ;
@@ -19,6 +19,15 @@ import { Signal, _get as getSignal, _set as setSignal } from './signals.js';
1919 */
2020export const dom = hole => diffFragment ( hole . n ? hole . update ( hole ) : hole . valueOf ( false ) , 1 ) ;
2121
22+ const holed = ( prev , current ) => {
23+ const changes = [ ] , h = prev . length , l = current . length ;
24+ for ( let c , p , j = 0 , i = 0 ; i < l ; i ++ ) {
25+ c = current [ i ] ;
26+ changes [ i ] = j < h && ( p = prev [ j ++ ] ) . t === c . t ? ( current [ i ] = p ) . update ( c ) : c . valueOf ( false ) ;
27+ }
28+ return changes ;
29+ } ;
30+
2231/**
2332 * @param {Hole } hole
2433 * @param {unknown } value
@@ -57,13 +66,48 @@ const getHole = (hole, value) => {
5766 hole . update ( value ) ;
5867 }
5968 else {
60- //@ts -ignore
6169 hole . n . replaceWith ( dom ( value ) ) ;
6270 hole = value ;
6371 }
6472 return hole ;
6573} ;
6674
75+ const createEffect = ( node , value , obj ) => {
76+ let signals = [ ] , entry = [ COMPONENT , null , obj ] , bootstrap = true , hole ;
77+ effect ( ( ) => {
78+ if ( bootstrap ) {
79+ bootstrap = false ;
80+ hole = component ( value , obj , signals ) ;
81+ if ( ! signals . length ) signals = children ;
82+ if ( hole ) {
83+ node . replaceWith ( dom ( hole ) ) ;
84+ entry [ 1 ] = hole ;
85+ }
86+ else node . remove ( ) ;
87+ }
88+ else {
89+ const result = component ( value , obj , signals ) ;
90+ if ( hole ) {
91+ if ( DEBUG && ! ( result instanceof Hole ) ) throw errors . invalid_component ( value ) ;
92+ if ( getHole ( hole , /** @type {Hole } */ ( result ) ) === result ) entry [ 2 ] = ( hole = result ) ;
93+ }
94+ }
95+ } ) ;
96+ return entry ;
97+ } ;
98+
99+ const updateRefs = refs => {
100+ for ( const node of refs ) {
101+ const value = node [ ref ] ;
102+ if ( typeof value === 'function' )
103+ value ( node ) ;
104+ else if ( value instanceof Signal )
105+ value . value = node ;
106+ else if ( value )
107+ value . current = node ;
108+ }
109+ } ;
110+
67111const props = Symbol ( ) ;
68112const global = { } ;
69113
@@ -75,10 +119,7 @@ export class Hole {
75119 constructor ( template , values ) {
76120 this . t = template ;
77121 this . v = values ;
78- this . c = children ;
79- /** @type {Node? } */
80122 this . n = null ;
81- /** @type {number } */
82123 this . k = - 1 ;
83124 }
84125
@@ -93,67 +134,37 @@ export class Hole {
93134 let length = values . length ;
94135 let changes = children ;
95136 let node , prev , refs ;
96- //@ts -ignore
97137 if ( DEBUG && length !== updates . length ) throw errors . invalid_interpolation ( this . t [ 3 ] , values ) ;
98138 if ( 0 < length ) {
99139 changes = updates . slice ( 0 ) ;
100140 while ( length -- ) {
101- //@ts -ignore
102141 const [ path , update , type ] = updates [ length ] ;
103142 const value = values [ length ] ;
104143 if ( prev !== path ) {
105144 node = resolve ( root , path ) ;
106145 prev = path ;
107- //@ts -ignore
108146 if ( DEBUG && ! node ) throw errors . invalid_path ( this . t [ 3 ] , path ) ;
109147 }
110148 if ( type & COMPONENT ) {
111149 const obj = node [ props ] || ( node [ props ] = { } ) ;
112150 if ( type === COMPONENT ) {
113151 for ( const { name, value } of node . attributes ) obj [ name ] ??= value ;
114152 obj . children ??= [ ...node . content . childNodes ] ;
115- //@ts -ignore
116- let signals = [ ] , bootstrap = true , entry , hole ;
117- effect ( ( ) => {
118- if ( bootstrap ) {
119- bootstrap = false ;
120- //@ts -ignore
121- hole = component ( value , obj , signals ) ;
122- //@ts -ignore
123- if ( ! signals . length ) signals = children ;
124- if ( hole ) node . replaceWith ( dom ( hole ) ) ;
125- else node . remove ( ) ;
126- //@ts -ignore
127- changes [ length ] = ( entry = [ type , hole , obj ] ) ;
128- }
129- else {
130- //@ts -ignore
131- const result = component ( value , obj , signals ) ;
132- if ( hole ) {
133- if ( DEBUG && ! ( result instanceof Hole ) ) throw errors . invalid_component ( value ) ;
134- if ( getHole ( hole , /** @type {Hole } */ ( result ) ) === result ) entry [ 2 ] = ( hole = result ) ;
135- }
136- }
137- } ) ;
153+ changes [ length ] = createEffect ( node , value , obj ) ;
138154 }
139155 else {
140156 update ( obj , value ) ;
141- //@ts -ignore
142157 changes [ length ] = [ type , update , obj ] ;
143158 }
144159 }
145160 else {
146161 let commit = true ;
147- //@ts -ignore
148162 if ( DEBUG && ( type & ARRAY ) && ! isArray ( value ) ) throw errors . invalid_interpolation ( this . t [ 3 ] , value ) ;
149163 if ( ! direct && ( type & COMMENT ) && ! ( type & SIGNAL ) ) {
150164 if ( type & ARRAY ) {
151165 commit = false ;
152- //@ts -ignore
153- if ( value . length ) {
154- //@ts -ignore
155- node . before ( ...( node [ nodes ] = value [ 0 ] instanceof Hole ? value . map ( dom ) : value ) ) ;
156- }
166+ if ( value . length )
167+ update ( node , value [ 0 ] instanceof Hole ? holed ( children , value ) : value ) ;
157168 }
158169 else if ( value instanceof Hole ) {
159170 commit = false ;
@@ -170,37 +181,19 @@ export class Hole {
170181 update ( node , value ) ;
171182 }
172183 }
173- //@ts -ignore
174184 changes [ length ] = [ type , update , value , node ] ;
175185 if ( direct && ( type & COMMENT ) ) node . remove ( ) ;
176186 }
177187 }
178- if ( refs ) {
179- for ( const node of refs ) {
180- const value = node [ ref ] ;
181- if ( typeof value === 'function' )
182- value ( node ) ;
183- else if ( value instanceof Signal )
184- value . value = node ;
185- else if ( value )
186- value . current = node ;
187- }
188- }
188+ if ( refs ) updateRefs ( refs ) ;
189189 }
190190
191191 const { childNodes } = root ;
192192 const size = childNodes . length ;
193193 const n = size === 1 ? childNodes [ 0 ] : ( size ? PersistentFragment ( root ) : root ) ;
194- if ( ! direct ) {
195- //@ts -ignore
196- this . v = children ;
197- this . c = changes ;
198- this . n = n ;
199- if ( - 1 < this . k ) {
200- //@ts -ignore
201- keys . set ( changes [ this . k ] [ 2 ] , n , this ) ;
202- }
203- }
194+ this . v = changes ;
195+ this . n = n ;
196+ if ( - 1 < this . k ) keys . set ( changes [ this . k ] [ 2 ] , n , this ) ;
204197 return n ;
205198 }
206199
@@ -210,7 +203,7 @@ export class Hole {
210203 */
211204 update ( hole ) {
212205 const key = this . k ;
213- const changes = this . c ;
206+ const changes = this . v ;
214207 const values = hole . v ;
215208
216209 if ( - 1 < key && changes [ key ] [ 2 ] !== values [ key ] )
@@ -225,7 +218,6 @@ export class Hole {
225218 if ( type & COMPONENT ) {
226219 if ( type === COMPONENT ) {
227220 if ( DEBUG && typeof value !== 'function' ) throw errors . invalid_component ( value ) ;
228- //@ts -ignore
229221 const result = value ( prev , global ) ;
230222 if ( update ) {
231223 if ( DEBUG && ! ( result instanceof Hole ) ) throw errors . invalid_component ( value ) ;
@@ -239,25 +231,14 @@ export class Hole {
239231 if ( type & ARRAY ) {
240232 if ( DEBUG && ! isArray ( value ) ) throw errors . invalid_interpolation ( [ ] , value ) ;
241233 if ( type & COMMENT ) {
242- //@ts -ignore
243- const l = value . length ;
244- const h = prev . length ;
245234 // TODO: a smarter differ that does not require 2 loops
246- //@ts -ignore
247- if ( l && ( value [ 0 ] instanceof Hole ) ) {
248- //@ts -ignore
249- if ( DEBUG && h && ! ( prev [ 0 ] instanceof Hole ) ) throw errors . invalid_interpolation ( [ ] , value [ 0 ] ) ;
250- change = [ ] ;
251- //@ts -ignore
252- for ( let c , p , j = 0 , i = 0 ; i < l ; i ++ ) {
253- //@ts -ignore
254- c = value [ i ] ;
255- //@ts -ignore
256- change [ i ] = j < h && ( p = prev [ j ++ ] ) . t === c . t ? ( value [ i ] = p ) . update ( c ) : dom ( c ) ;
235+ if ( value . length ) {
236+ if ( value [ 0 ] instanceof Hole ) {
237+ if ( DEBUG && prev . length && ! ( prev [ 0 ] instanceof Hole ) ) throw errors . invalid_interpolation ( [ ] , value [ 0 ] ) ;
238+ change = holed ( prev , value ) ;
257239 }
258240 }
259241 }
260- //@ts -ignore
261242 else if ( ( type & EVENT ) && ( value [ 0 ] === prev [ 0 ] ) ) continue ;
262243 }
263244 else if ( type & COMMENT ) {
@@ -270,7 +251,6 @@ export class Hole {
270251 else if ( prev instanceof Hole ) {
271252 if ( DEBUG && ! ( value instanceof Hole ) ) throw errors . invalid_interpolation ( [ ] , value ) ;
272253 value = getHole ( prev , /** @type {Hole } */ ( value ) ) ;
273- //@ts -ignore
274254 change = value . n ;
275255 }
276256 }
0 commit comments