11/* eslint-disable */
2- // Ported from https://github.com/stackblitz/alien-signals/blob/v1.0.6 /src/system.ts
2+ // Ported from https://github.com/stackblitz/alien-signals/blob/v1.0.7 /src/system.ts
33import type { ComputedRefImpl as Computed } from './computed.js'
44import type { ReactiveEffect as Effect } from './effect.js'
55
@@ -32,14 +32,14 @@ export const enum SubscriberFlags {
3232 Propagated = Dirty | PendingComputed ,
3333}
3434
35- interface QueuedLink {
36- effect : Effect
37- next : QueuedLink | undefined
35+ interface OneWayLink < T > {
36+ target : T
37+ linked : OneWayLink < T > | undefined
3838}
3939
4040let batchDepth = 0
41- let queuedEffects : QueuedLink | undefined
42- let queuedEffectsTail : QueuedLink | undefined
41+ let queuedEffects : OneWayLink < Effect > | undefined
42+ let queuedEffectsTail : OneWayLink < Effect > | undefined
4343
4444export function startBatch ( ) : void {
4545 ++ batchDepth
@@ -72,13 +72,14 @@ export function link(dep: Dependency, sub: Subscriber): Link | undefined {
7272 return linkNewDep ( dep , sub , nextDep , currentDep )
7373}
7474
75- export function propagate ( link : Link ) : void {
75+ export function propagate ( current : Link ) : void {
76+ let next = current . nextSub
77+ let branchs : OneWayLink < Link | undefined > | undefined
78+ let branchDepth = 0
7679 let targetFlag = SubscriberFlags . Dirty
77- let subs = link
78- let stack = 0
7980
8081 top: do {
81- const sub = link . sub
82+ const sub = current . sub
8283 const subFlags = sub . flags
8384
8485 if (
@@ -94,33 +95,31 @@ export function propagate(link: Link): void {
9495 ( ( sub . flags = ( subFlags & ~ SubscriberFlags . Recursed ) | targetFlag ) ,
9596 true ) ) ||
9697 ( ! ( subFlags & SubscriberFlags . Propagated ) &&
97- isValidLink ( link , sub ) &&
98+ isValidLink ( current , sub ) &&
9899 ( ( sub . flags = subFlags | SubscriberFlags . Recursed | targetFlag ) ,
99100 ( sub as Dependency ) . subs !== undefined ) )
100101 ) {
101102 const subSubs = ( sub as Dependency ) . subs
102103 if ( subSubs !== undefined ) {
104+ current = subSubs
103105 if ( subSubs . nextSub !== undefined ) {
104- subSubs . prevSub = subs
105- link = subs = subSubs
106- targetFlag = SubscriberFlags . PendingComputed
107- ++ stack
108- } else {
109- link = subSubs
110- targetFlag = SubscriberFlags . PendingComputed
106+ branchs = { target : next , linked : branchs }
107+ ++ branchDepth
108+ next = current . nextSub
111109 }
110+ targetFlag = SubscriberFlags . PendingComputed
112111 continue
113112 }
114113 if ( subFlags & SubscriberFlags . Effect ) {
115114 if ( queuedEffectsTail !== undefined ) {
116- queuedEffectsTail = queuedEffectsTail . next = {
117- effect : sub as Effect ,
118- next : undefined ,
115+ queuedEffectsTail = queuedEffectsTail . linked = {
116+ target : sub as Effect ,
117+ linked : undefined ,
119118 }
120119 } else {
121120 queuedEffectsTail = queuedEffects = {
122- effect : sub as Effect ,
123- next : undefined ,
121+ target : sub as Effect ,
122+ linked : undefined ,
124123 }
125124 }
126125 }
@@ -129,28 +128,25 @@ export function propagate(link: Link): void {
129128 } else if (
130129 ! ( subFlags & targetFlag ) &&
131130 subFlags & SubscriberFlags . Propagated &&
132- isValidLink ( link , sub )
131+ isValidLink ( current , sub )
133132 ) {
134133 sub . flags = subFlags | targetFlag
135134 }
136135
137- if ( ( link = subs . nextSub ! ) !== undefined ) {
138- subs = link
139- targetFlag = stack
136+ if ( ( current = next ! ) !== undefined ) {
137+ next = current . nextSub
138+ targetFlag = branchDepth
140139 ? SubscriberFlags . PendingComputed
141140 : SubscriberFlags . Dirty
142141 continue
143142 }
144143
145- while ( stack ) {
146- -- stack
147- const dep = subs . dep
148- const depSubs = dep . subs !
149- subs = depSubs . prevSub !
150- depSubs . prevSub = undefined
151- if ( ( link = subs . nextSub ! ) !== undefined ) {
152- subs = link
153- targetFlag = stack
144+ while ( branchDepth -- ) {
145+ current = branchs ! . target !
146+ branchs = branchs ! . linked
147+ if ( current !== undefined ) {
148+ next = current . nextSub
149+ targetFlag = branchDepth
154150 ? SubscriberFlags . PendingComputed
155151 : SubscriberFlags . Dirty
156152 continue top
@@ -221,8 +217,8 @@ export function processComputedUpdate(
221217
222218export function processEffectNotifications ( ) : void {
223219 while ( queuedEffects !== undefined ) {
224- const effect = queuedEffects . effect
225- queuedEffects = queuedEffects . next
220+ const effect = queuedEffects . target
221+ queuedEffects = queuedEffects . linked
226222 if ( queuedEffects === undefined ) {
227223 queuedEffectsTail = undefined
228224 }
@@ -264,87 +260,68 @@ function linkNewDep(
264260 return newLink
265261}
266262
267- function checkDirty ( link : Link ) : boolean {
268- let stack = 0
269- let dirty : boolean
263+ function checkDirty ( current : Link ) : boolean {
264+ let prevLinks : OneWayLink < Link > | undefined
265+ let checkDepth = 0
270266
271267 top: do {
272- dirty = false
273- const dep = link . dep
268+ const dep = current . dep
274269
275270 if ( 'flags' in dep ) {
276271 const depFlags = dep . flags
277272 if (
278273 ( depFlags & ( SubscriberFlags . Computed | SubscriberFlags . Dirty ) ) ===
279274 ( SubscriberFlags . Computed | SubscriberFlags . Dirty )
280275 ) {
281- if ( ( dep as Computed ) . update ( ) ) {
282- const subs = dep . subs !
283- if ( subs . nextSub !== undefined ) {
284- shallowPropagate ( subs )
276+ if ( dep . update ( ) ) {
277+ if ( current . nextSub !== undefined || current . prevSub !== undefined ) {
278+ shallowPropagate ( dep . subs ! )
285279 }
286- dirty = true
280+ while ( checkDepth -- ) {
281+ const computed = current . sub as Computed
282+ const firstSub = computed . subs !
283+
284+ if ( computed . update ( ) ) {
285+ if ( firstSub . nextSub !== undefined ) {
286+ shallowPropagate ( firstSub )
287+ current = prevLinks ! . target
288+ prevLinks = prevLinks ! . linked
289+ } else {
290+ current = firstSub
291+ }
292+ continue
293+ }
294+
295+ if ( firstSub . nextSub !== undefined ) {
296+ if ( ( current = prevLinks ! . target . nextDep ! ) === undefined ) {
297+ return false
298+ }
299+ prevLinks = prevLinks ! . linked
300+ continue top
301+ }
302+
303+ return false
304+ }
305+ return true
287306 }
288307 } else if (
289308 ( depFlags &
290309 ( SubscriberFlags . Computed | SubscriberFlags . PendingComputed ) ) ===
291310 ( SubscriberFlags . Computed | SubscriberFlags . PendingComputed )
292311 ) {
293- const depSubs = dep . subs !
294- if ( depSubs . nextSub !== undefined ) {
295- depSubs . prevSub = link
312+ dep . flags = depFlags & ~ SubscriberFlags . PendingComputed
313+ if ( current . nextSub !== undefined || current . prevSub !== undefined ) {
314+ prevLinks = { target : current , linked : prevLinks }
296315 }
297- link = dep . deps !
298- ++ stack
316+ ++ checkDepth
317+ current = dep . deps !
299318 continue
300319 }
301320 }
302321
303- if ( ! dirty && link . nextDep !== undefined ) {
304- link = link . nextDep
305- continue
306- }
307-
308- if ( stack ) {
309- let sub = link . sub as Computed
310- do {
311- -- stack
312- const subSubs = sub . subs !
313-
314- if ( dirty ) {
315- if ( sub . update ( ) ) {
316- if ( ( link = subSubs . prevSub ! ) !== undefined ) {
317- subSubs . prevSub = undefined
318- shallowPropagate ( subSubs )
319- sub = link . sub as Computed
320- } else {
321- sub = subSubs . sub as Computed
322- }
323- continue
324- }
325- } else {
326- sub . flags &= ~ SubscriberFlags . PendingComputed
327- }
328-
329- if ( ( link = subSubs . prevSub ! ) !== undefined ) {
330- subSubs . prevSub = undefined
331- if ( link . nextDep !== undefined ) {
332- link = link . nextDep
333- continue top
334- }
335- sub = link . sub as Computed
336- } else {
337- if ( ( link = subSubs . nextDep ! ) !== undefined ) {
338- continue top
339- }
340- sub = subSubs . sub as Computed
341- }
342-
343- dirty = false
344- } while ( stack )
322+ if ( ( current = current . nextDep ! ) === undefined ) {
323+ return false
345324 }
346-
347- return dirty
348325 } while ( true )
349326}
350327
0 commit comments