11/* eslint-disable */ 
2- // Ported from https://github.com/stackblitz/alien-signals/blob/v1.0.4 /src/system.ts 
2+ // Ported from https://github.com/stackblitz/alien-signals/blob/v1.0.13 /src/system.ts 
33import  type  {  ComputedRefImpl  as  Computed  }  from  './computed.js' 
44import  type  {  ReactiveEffect  as  Effect  }  from  './effect.js' 
55
@@ -32,9 +32,16 @@ export const enum SubscriberFlags {
3232  Propagated  =  Dirty  |  PendingComputed , 
3333} 
3434
35+ interface  OneWayLink < T >  { 
36+   target : T 
37+   linked : OneWayLink < T >  |  undefined 
38+ } 
39+ 
40+ const  notifyBuffer : ( Effect  |  undefined ) [ ]  =  [ ] 
41+ 
3542let  batchDepth  =  0 
36- let  queuedEffects :  Effect   |   undefined 
37- let  queuedEffectsTail :  Effect   |   undefined 
43+ let  notifyIndex   =   0 
44+ let  notifyBufferLength   =   0 
3845
3946export  function  startBatch ( ) : void   { 
4047  ++ batchDepth 
@@ -67,80 +74,81 @@ export function link(dep: Dependency, sub: Subscriber): Link | undefined {
6774  return  linkNewDep ( dep ,  sub ,  nextDep ,  currentDep ) 
6875} 
6976
70- export  function  propagate ( link : Link ) : void   { 
77+ export  function  propagate ( current : Link ) : void   { 
78+   let  next  =  current . nextSub 
79+   let  branchs : OneWayLink < Link  |  undefined >  |  undefined 
80+   let  branchDepth  =  0 
7181  let  targetFlag  =  SubscriberFlags . Dirty 
72-   let  subs  =  link 
73-   let  stack  =  0 
7482
7583  top: do  { 
76-     const  sub  =  link . sub 
84+     const  sub  =  current . sub 
7785    const  subFlags  =  sub . flags 
7886
87+     let  shouldNotify  =  false 
88+ 
7989    if  ( 
80-       ( ! ( 
90+       ! ( 
8191        subFlags  & 
8292        ( SubscriberFlags . Tracking  | 
8393          SubscriberFlags . Recursed  | 
8494          SubscriberFlags . Propagated ) 
85-       )  && 
86-         ( ( sub . flags  =  subFlags  |  targetFlag ) ,  true ) )  || 
87-       ( subFlags  &  SubscriberFlags . Recursed  && 
88-         ! ( subFlags  &  SubscriberFlags . Tracking )  && 
89-         ( ( sub . flags  =  ( subFlags  &  ~ SubscriberFlags . Recursed )  |  targetFlag ) , 
90-         true ) )  || 
91-       ( ! ( subFlags  &  SubscriberFlags . Propagated )  && 
92-         isValidLink ( link ,  sub )  && 
93-         ( ( sub . flags  =  subFlags  |  SubscriberFlags . Recursed  |  targetFlag ) , 
94-         ( sub  as  Dependency ) . subs  !==  undefined ) ) 
95+       ) 
96+     )  { 
97+       sub . flags  =  subFlags  |  targetFlag 
98+       shouldNotify  =  true 
99+     }  else  if  ( 
100+       subFlags  &  SubscriberFlags . Recursed  && 
101+       ! ( subFlags  &  SubscriberFlags . Tracking ) 
95102    )  { 
103+       sub . flags  =  ( subFlags  &  ~ SubscriberFlags . Recursed )  |  targetFlag 
104+       shouldNotify  =  true 
105+     }  else  if  ( 
106+       ! ( subFlags  &  SubscriberFlags . Propagated )  && 
107+       isValidLink ( current ,  sub ) 
108+     )  { 
109+       sub . flags  =  subFlags  |  SubscriberFlags . Recursed  |  targetFlag 
110+       shouldNotify  =  ( sub  as  Dependency ) . subs  !==  undefined 
111+     } 
112+ 
113+     if  ( shouldNotify )  { 
96114      const  subSubs  =  ( sub  as  Dependency ) . subs 
97115      if  ( subSubs  !==  undefined )  { 
116+         current  =  subSubs 
98117        if  ( subSubs . nextSub  !==  undefined )  { 
99-           subSubs . prevSub  =  subs 
100-           link  =  subs  =  subSubs 
101-           targetFlag  =  SubscriberFlags . PendingComputed 
102-           ++ stack 
103-         }  else  { 
104-           link  =  subSubs 
105-           targetFlag  =  SubscriberFlags . PendingComputed 
118+           branchs  =  {  target : next ,  linked : branchs  } 
119+           ++ branchDepth 
120+           next  =  current . nextSub 
106121        } 
122+         targetFlag  =  SubscriberFlags . PendingComputed 
107123        continue 
108124      } 
109125      if  ( subFlags  &  SubscriberFlags . Effect )  { 
110-         if  ( queuedEffectsTail  !==  undefined )  { 
111-           queuedEffectsTail . depsTail ! . nextDep  =  sub . deps 
112-         }  else  { 
113-           queuedEffects  =  sub  as  Effect 
114-         } 
115-         queuedEffectsTail  =  sub  as  Effect 
126+         notifyBuffer [ notifyBufferLength ++ ]  =  sub  as  Effect 
116127      } 
117128    }  else  if  ( ! ( subFlags  &  ( SubscriberFlags . Tracking  |  targetFlag ) ) )  { 
118129      sub . flags  =  subFlags  |  targetFlag 
119130    }  else  if  ( 
120131      ! ( subFlags  &  targetFlag )  && 
121132      subFlags  &  SubscriberFlags . Propagated  && 
122-       isValidLink ( link ,  sub ) 
133+       isValidLink ( current ,  sub ) 
123134    )  { 
124135      sub . flags  =  subFlags  |  targetFlag 
125136    } 
126137
127-     if  ( ( link  =  subs . nextSub ! )  !==  undefined )  { 
128-       subs  =  link 
129-       targetFlag  =  stack 
138+     if  ( ( current  =  next ! )  !==  undefined )  { 
139+       next  =  current . nextSub 
140+       targetFlag  =  branchDepth 
130141        ? SubscriberFlags . PendingComputed 
131142        : SubscriberFlags . Dirty 
132143      continue 
133144    } 
134145
135-     while  ( stack )  { 
136-       -- stack 
137-       const  dep  =  subs . dep 
138-       const  depSubs  =  dep . subs ! 
139-       subs  =  depSubs . prevSub ! 
140-       depSubs . prevSub  =  undefined 
141-       if  ( ( link  =  subs . nextSub ! )  !==  undefined )  { 
142-         subs  =  link 
143-         targetFlag  =  stack 
146+     while  ( branchDepth -- )  { 
147+       current  =  branchs ! . target ! 
148+       branchs  =  branchs ! . linked 
149+       if  ( current  !==  undefined )  { 
150+         next  =  current . nextSub 
151+         targetFlag  =  branchDepth 
144152          ? SubscriberFlags . PendingComputed 
145153          : SubscriberFlags . Dirty 
146154        continue  top
@@ -194,35 +202,26 @@ export function processComputedUpdate(
194202  computed : Computed , 
195203  flags : SubscriberFlags , 
196204) : void   { 
197-   if  ( 
198-     flags  &  SubscriberFlags . Dirty  || 
199-     ( checkDirty ( computed . deps ! ) 
200-       ? true 
201-       : ( ( computed . flags  =  flags  &  ~ SubscriberFlags . PendingComputed ) ,  false ) ) 
202-   )  { 
205+   if  ( flags  &  SubscriberFlags . Dirty  ||  checkDirty ( computed . deps ! ) )  { 
203206    if  ( computed . update ( ) )  { 
204207      const  subs  =  computed . subs 
205208      if  ( subs  !==  undefined )  { 
206209        shallowPropagate ( subs ) 
207210      } 
208211    } 
212+   }  else  { 
213+     computed . flags  =  flags  &  ~ SubscriberFlags . PendingComputed 
209214  } 
210215} 
211216
212217export  function  processEffectNotifications ( ) : void   { 
213-   while  ( queuedEffects  !==  undefined )  { 
214-     const  effect  =  queuedEffects 
215-     const  depsTail  =  effect . depsTail ! 
216-     const  queuedNext  =  depsTail . nextDep 
217-     if  ( queuedNext  !==  undefined )  { 
218-       depsTail . nextDep  =  undefined 
219-       queuedEffects  =  queuedNext . sub  as  Effect 
220-     }  else  { 
221-       queuedEffects  =  undefined 
222-       queuedEffectsTail  =  undefined 
223-     } 
218+   while  ( notifyIndex  <  notifyBufferLength )  { 
219+     const  effect  =  notifyBuffer [ notifyIndex ] ! 
220+     notifyBuffer [ notifyIndex ++ ]  =  undefined 
224221    effect . notify ( ) 
225222  } 
223+   notifyIndex  =  0 
224+   notifyBufferLength  =  0 
226225} 
227226
228227function  linkNewDep ( 
@@ -259,15 +258,18 @@ function linkNewDep(
259258  return  newLink 
260259} 
261260
262- function  checkDirty ( link : Link ) : boolean  { 
263-   let  stack  =  0 
261+ function  checkDirty ( current : Link ) : boolean  { 
262+   let  prevLinks : OneWayLink < Link >  |  undefined 
263+   let  checkDepth  =  0 
264264  let  dirty : boolean 
265265
266266  top: do  { 
267267    dirty  =  false 
268-     const  dep  =  link . dep 
268+     const  dep  =  current . dep 
269269
270-     if  ( 'flags'  in  dep )  { 
270+     if  ( current . sub . flags  &  SubscriberFlags . Dirty )  { 
271+       dirty  =  true 
272+     }  else  if  ( 'flags'  in  dep )  { 
271273      const  depFlags  =  dep . flags 
272274      if  ( 
273275        ( depFlags  &  ( SubscriberFlags . Computed  |  SubscriberFlags . Dirty ) )  === 
@@ -285,58 +287,49 @@ function checkDirty(link: Link): boolean {
285287          ( SubscriberFlags . Computed  |  SubscriberFlags . PendingComputed ) )  === 
286288        ( SubscriberFlags . Computed  |  SubscriberFlags . PendingComputed ) 
287289      )  { 
288-         const  depSubs  =  dep . subs ! 
289-         if  ( depSubs . nextSub  !==  undefined )  { 
290-           depSubs . prevSub  =  link 
290+         if  ( current . nextSub  !==  undefined  ||  current . prevSub  !==  undefined )  { 
291+           prevLinks  =  {  target : current ,  linked : prevLinks  } 
291292        } 
292-         link  =  dep . deps ! 
293-         ++ stack 
293+         current  =  dep . deps ! 
294+         ++ checkDepth 
294295        continue 
295296      } 
296297    } 
297298
298-     if  ( ! dirty  &&  link . nextDep  !==  undefined )  { 
299-       link  =  link . nextDep 
299+     if  ( ! dirty  &&  current . nextDep  !==  undefined )  { 
300+       current  =  current . nextDep 
300301      continue 
301302    } 
302303
303-     if  ( stack )  { 
304-       let  sub  =  link . sub  as  Computed 
305-       do  { 
306-         -- stack 
307-         const  subSubs  =  sub . subs ! 
308- 
309-         if  ( dirty )  { 
310-           if  ( sub . update ( ) )  { 
311-             if  ( ( link  =  subSubs . prevSub ! )  !==  undefined )  { 
312-               subSubs . prevSub  =  undefined 
313-               shallowPropagate ( subSubs ) 
314-               sub  =  link . sub  as  Computed 
315-             }  else  { 
316-               sub  =  subSubs . sub  as  Computed 
317-             } 
318-             continue 
319-           } 
320-         }  else  { 
321-           sub . flags  &=  ~ SubscriberFlags . PendingComputed 
322-         } 
323- 
324-         if  ( ( link  =  subSubs . prevSub ! )  !==  undefined )  { 
325-           subSubs . prevSub  =  undefined 
326-           if  ( link . nextDep  !==  undefined )  { 
327-             link  =  link . nextDep 
328-             continue  top
329-           } 
330-           sub  =  link . sub  as  Computed 
331-         }  else  { 
332-           if  ( ( link  =  subSubs . nextDep ! )  !==  undefined )  { 
333-             continue  top
304+     while  ( checkDepth )  { 
305+       -- checkDepth 
306+       const  sub  =  current . sub  as  Computed 
307+       const  firstSub  =  sub . subs ! 
308+       if  ( dirty )  { 
309+         if  ( sub . update ( ) )  { 
310+           if  ( firstSub . nextSub  !==  undefined )  { 
311+             current  =  prevLinks ! . target 
312+             prevLinks  =  prevLinks ! . linked 
313+             shallowPropagate ( firstSub ) 
314+           }  else  { 
315+             current  =  firstSub 
334316          } 
335-           sub   =   subSubs . sub   as   Computed 
317+           continue 
336318        } 
337- 
338-         dirty  =  false 
339-       }  while  ( stack ) 
319+       }  else  { 
320+         sub . flags  &=  ~ SubscriberFlags . PendingComputed 
321+       } 
322+       if  ( firstSub . nextSub  !==  undefined )  { 
323+         current  =  prevLinks ! . target 
324+         prevLinks  =  prevLinks ! . linked 
325+       }  else  { 
326+         current  =  firstSub 
327+       } 
328+       if  ( current . nextDep  !==  undefined )  { 
329+         current  =  current . nextDep 
330+         continue  top
331+       } 
332+       dirty  =  false 
340333    } 
341334
342335    return  dirty 
0 commit comments