1
1
/* 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
3
3
import type { ComputedRefImpl as Computed } from './computed.js'
4
4
import type { ReactiveEffect as Effect } from './effect.js'
5
5
@@ -32,14 +32,14 @@ export const enum SubscriberFlags {
32
32
Propagated = Dirty | PendingComputed ,
33
33
}
34
34
35
- interface QueuedLink {
36
- effect : Effect
37
- next : QueuedLink | undefined
35
+ interface OneWayLink < T > {
36
+ target : T
37
+ linked : OneWayLink < T > | undefined
38
38
}
39
39
40
40
let batchDepth = 0
41
- let queuedEffects : QueuedLink | undefined
42
- let queuedEffectsTail : QueuedLink | undefined
41
+ let queuedEffects : OneWayLink < Effect > | undefined
42
+ let queuedEffectsTail : OneWayLink < Effect > | undefined
43
43
44
44
export function startBatch ( ) : void {
45
45
++ batchDepth
@@ -72,13 +72,14 @@ export function link(dep: Dependency, sub: Subscriber): Link | undefined {
72
72
return linkNewDep ( dep , sub , nextDep , currentDep )
73
73
}
74
74
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
76
79
let targetFlag = SubscriberFlags . Dirty
77
- let subs = link
78
- let stack = 0
79
80
80
81
top: do {
81
- const sub = link . sub
82
+ const sub = current . sub
82
83
const subFlags = sub . flags
83
84
84
85
if (
@@ -94,33 +95,31 @@ export function propagate(link: Link): void {
94
95
( ( sub . flags = ( subFlags & ~ SubscriberFlags . Recursed ) | targetFlag ) ,
95
96
true ) ) ||
96
97
( ! ( subFlags & SubscriberFlags . Propagated ) &&
97
- isValidLink ( link , sub ) &&
98
+ isValidLink ( current , sub ) &&
98
99
( ( sub . flags = subFlags | SubscriberFlags . Recursed | targetFlag ) ,
99
100
( sub as Dependency ) . subs !== undefined ) )
100
101
) {
101
102
const subSubs = ( sub as Dependency ) . subs
102
103
if ( subSubs !== undefined ) {
104
+ current = subSubs
103
105
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
111
109
}
110
+ targetFlag = SubscriberFlags . PendingComputed
112
111
continue
113
112
}
114
113
if ( subFlags & SubscriberFlags . Effect ) {
115
114
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 ,
119
118
}
120
119
} else {
121
120
queuedEffectsTail = queuedEffects = {
122
- effect : sub as Effect ,
123
- next : undefined ,
121
+ target : sub as Effect ,
122
+ linked : undefined ,
124
123
}
125
124
}
126
125
}
@@ -129,28 +128,25 @@ export function propagate(link: Link): void {
129
128
} else if (
130
129
! ( subFlags & targetFlag ) &&
131
130
subFlags & SubscriberFlags . Propagated &&
132
- isValidLink ( link , sub )
131
+ isValidLink ( current , sub )
133
132
) {
134
133
sub . flags = subFlags | targetFlag
135
134
}
136
135
137
- if ( ( link = subs . nextSub ! ) !== undefined ) {
138
- subs = link
139
- targetFlag = stack
136
+ if ( ( current = next ! ) !== undefined ) {
137
+ next = current . nextSub
138
+ targetFlag = branchDepth
140
139
? SubscriberFlags . PendingComputed
141
140
: SubscriberFlags . Dirty
142
141
continue
143
142
}
144
143
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
154
150
? SubscriberFlags . PendingComputed
155
151
: SubscriberFlags . Dirty
156
152
continue top
@@ -221,8 +217,8 @@ export function processComputedUpdate(
221
217
222
218
export function processEffectNotifications ( ) : void {
223
219
while ( queuedEffects !== undefined ) {
224
- const effect = queuedEffects . effect
225
- queuedEffects = queuedEffects . next
220
+ const effect = queuedEffects . target
221
+ queuedEffects = queuedEffects . linked
226
222
if ( queuedEffects === undefined ) {
227
223
queuedEffectsTail = undefined
228
224
}
@@ -264,87 +260,68 @@ function linkNewDep(
264
260
return newLink
265
261
}
266
262
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
270
266
271
267
top: do {
272
- dirty = false
273
- const dep = link . dep
268
+ const dep = current . dep
274
269
275
270
if ( 'flags' in dep ) {
276
271
const depFlags = dep . flags
277
272
if (
278
273
( depFlags & ( SubscriberFlags . Computed | SubscriberFlags . Dirty ) ) ===
279
274
( SubscriberFlags . Computed | SubscriberFlags . Dirty )
280
275
) {
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 ! )
285
279
}
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
287
306
}
288
307
} else if (
289
308
( depFlags &
290
309
( SubscriberFlags . Computed | SubscriberFlags . PendingComputed ) ) ===
291
310
( SubscriberFlags . Computed | SubscriberFlags . PendingComputed )
292
311
) {
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 }
296
315
}
297
- link = dep . deps !
298
- ++ stack
316
+ ++ checkDepth
317
+ current = dep . deps !
299
318
continue
300
319
}
301
320
}
302
321
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
345
324
}
346
-
347
- return dirty
348
325
} while ( true )
349
326
}
350
327
0 commit comments