@@ -148,7 +148,7 @@ export class Signal<T = any> implements ISignal<T> {
148148 $untrackedValue$ : T ;
149149
150150 /** Store a list of effects which are dependent on this signal. */
151- $effects$ : null | EffectSubscriptions [ ] = null ;
151+ $effects$ : null | Set < EffectSubscriptions > = null ;
152152
153153 $container$ : Container | null = null ;
154154
@@ -184,7 +184,7 @@ export class Signal<T = any> implements ISignal<T> {
184184 }
185185 const effectSubscriber = ctx . $effectSubscriber$ ;
186186 if ( effectSubscriber ) {
187- const effects = ( this . $effects$ ||= [ ] ) ;
187+ const effects = ( this . $effects$ ||= new Set ( ) ) ;
188188 // Let's make sure that we have a reference to this effect.
189189 // Adding reference is essentially adding a subscription, so if the signal
190190 // changes we know who to notify.
@@ -227,7 +227,9 @@ export class Signal<T = any> implements ISignal<T> {
227227 toString ( ) {
228228 return (
229229 `[${ this . constructor . name } ${ ( this as any ) . $invalid$ ? ' INVALID' : '' } ${ String ( this . $untrackedValue$ ) } ]` +
230- ( this . $effects$ ?. map ( ( e ) => '\n -> ' + pad ( qwikDebugToString ( e [ 0 ] ) , ' ' ) ) . join ( '\n' ) || '' )
230+ ( Array . from ( this . $effects$ || [ ] )
231+ . map ( ( e ) => '\n -> ' + pad ( qwikDebugToString ( e [ 0 ] ) , ' ' ) )
232+ . join ( '\n' ) || '' )
231233 ) ;
232234 }
233235 toJSON ( ) {
@@ -245,19 +247,13 @@ export const ensureContains = (array: any[], value: any): boolean => {
245247} ;
246248
247249export const ensureContainsEffect = (
248- array : EffectSubscriptions [ ] ,
250+ array : Set < EffectSubscriptions > ,
249251 effectSubscriptions : EffectSubscriptions
250252) => {
251- for ( let i = 0 ; i < array . length ; i ++ ) {
252- const existingEffect = array [ i ] ;
253- if (
254- existingEffect [ 0 ] === effectSubscriptions [ 0 ] &&
255- existingEffect [ 1 ] === effectSubscriptions [ 1 ]
256- ) {
257- return ;
258- }
253+ if ( array . has ( effectSubscriptions ) ) {
254+ return ;
259255 }
260- array . push ( effectSubscriptions ) ;
256+ array . add ( effectSubscriptions ) ;
261257} ;
262258
263259export const ensureEffectContainsSubscriber = (
@@ -266,36 +262,35 @@ export const ensureEffectContainsSubscriber = (
266262 container : Container | null
267263) => {
268264 if ( isSubscriber ( effect ) ) {
269- effect . $effectDependencies$ ||= [ ] ;
270-
271- if ( subscriberExistInSubscribers ( effect . $effectDependencies$ , subscriber ) ) {
265+ effect . $effectDependencies$ ||= new Set ( ) ;
266+ if ( effect . $effectDependencies$ . has ( subscriber ) ) {
272267 return ;
273268 }
274269
275- effect . $effectDependencies$ . push ( subscriber ) ;
270+ effect . $effectDependencies$ . add ( subscriber ) ;
276271 } else if ( vnode_isVNode ( effect ) && ! vnode_isTextVNode ( effect ) ) {
277- let subscribers = vnode_getProp < ( Subscriber | TargetType ) [ ] > (
272+ let subscribers = vnode_getProp < Set < Subscriber | TargetType > > (
278273 effect ,
279274 QSubscribers ,
280275 container ? container . $getObjectById$ : null
281276 ) ;
282- subscribers ||= [ ] ;
277+ subscribers ||= new Set ( ) ;
283278
284- if ( subscriberExistInSubscribers ( subscribers , subscriber ) ) {
279+ if ( subscribers . has ( subscriber ) ) {
285280 return ;
286281 }
287282
288- subscribers . push ( subscriber ) ;
283+ subscribers . add ( subscriber ) ;
289284 vnode_setProp ( effect , QSubscribers , subscribers ) ;
290285 } else if ( isSSRNode ( effect ) ) {
291- let subscribers = effect . getProp ( QSubscribers ) as ( Subscriber | TargetType ) [ ] ;
292- subscribers ||= [ ] ;
286+ let subscribers = effect . getProp ( QSubscribers ) as Set < Subscriber | TargetType > ;
287+ subscribers ||= new Set ( ) ;
293288
294- if ( subscriberExistInSubscribers ( subscribers , subscriber ) ) {
289+ if ( subscribers . has ( subscriber ) ) {
295290 return ;
296291 }
297292
298- subscribers . push ( subscriber ) ;
293+ subscribers . add ( subscriber ) ;
299294 effect . setProp ( QSubscribers , subscribers ) ;
300295 }
301296} ;
@@ -304,18 +299,6 @@ const isSSRNode = (effect: Effect): effect is ISsrNode => {
304299 return 'setProp' in effect && 'getProp' in effect && 'removeProp' in effect && 'id' in effect ;
305300} ;
306301
307- const subscriberExistInSubscribers = (
308- subscribers : ( Subscriber | TargetType ) [ ] ,
309- subscriber : Subscriber | TargetType
310- ) => {
311- for ( let i = 0 ; i < subscribers . length ; i ++ ) {
312- if ( subscribers [ i ] === subscriber ) {
313- return true ;
314- }
315- }
316- return false ;
317- } ;
318-
319302export const addQrlToSerializationCtx = (
320303 effectSubscriber : EffectSubscriptions ,
321304 isMissing : boolean ,
@@ -341,7 +324,7 @@ export const addQrlToSerializationCtx = (
341324export const triggerEffects = (
342325 container : Container | null ,
343326 signal : Signal | TargetType ,
344- effects : EffectSubscriptions [ ] | null
327+ effects : Set < EffectSubscriptions > | null
345328) => {
346329 const isBrowser = isDomContainer ( container ) ;
347330 if ( effects ) {
@@ -503,7 +486,7 @@ export class WrappedSignal<T> extends Signal<T> implements Subscriber {
503486 // We need a separate flag to know when the computation needs running because
504487 // we need the old value to know if effects need running after computation
505488 $invalid$ : boolean = true ;
506- $effectDependencies$ : Subscriber [ ] | null = null ;
489+ $effectDependencies$ : Set < Subscriber > | null = null ;
507490 $hostElement$ : HostElement | null = null ;
508491 $forceRunEffects$ : boolean = false ;
509492
0 commit comments