11import { createReactiveSystem , type ReactiveFlags , type ReactiveNode } from './system.js' ;
22
3- interface EffectScope extends ReactiveNode { }
4-
53interface Effect extends ReactiveNode {
64 fn ( ) : void ;
75}
@@ -16,7 +14,13 @@ interface Signal<T = any> extends ReactiveNode {
1614 pendingValue : T ;
1715}
1816
19- const queuedEffects : ( Effect | EffectScope | undefined ) [ ] = [ ] ;
17+ let cycle = 0 ;
18+ let batchDepth = 0 ;
19+ let notifyIndex = 0 ;
20+ let queuedLength = 0 ;
21+ let activeSub : ReactiveNode | undefined ;
22+
23+ const queued : ( Effect | undefined ) [ ] = [ ] ;
2024const {
2125 link,
2226 unlink,
@@ -31,8 +35,29 @@ const {
3135 return updateSignal ( node as Signal ) ;
3236 }
3337 } ,
34- notify,
35- unwatched ( node : Signal | Computed | Effect | EffectScope ) {
38+ notify ( effect : Effect ) {
39+ let flags = effect . flags ;
40+ let insertIndex = queuedLength ;
41+ let firstInsertedIndex = insertIndex ;
42+
43+ do {
44+ effect . flags = flags & ~ ( 2 satisfies ReactiveFlags . Watching ) ;
45+ queued [ insertIndex ++ ] = effect ;
46+ effect = effect . subs ?. sub as Effect ;
47+ if ( effect === undefined || ! ( ( flags = effect . flags ) & 2 satisfies ReactiveFlags . Watching ) ) {
48+ break ;
49+ }
50+ } while ( true ) ;
51+
52+ queuedLength = insertIndex ;
53+
54+ while ( firstInsertedIndex < insertIndex -- ) {
55+ const left = queued [ firstInsertedIndex ] ;
56+ queued [ firstInsertedIndex ++ ] = queued [ insertIndex ] ;
57+ queued [ insertIndex ] = left ;
58+ }
59+ } ,
60+ unwatched ( node ) {
3661 if ( ! ( node . flags & 1 satisfies ReactiveFlags . Mutable ) ) {
3762 effectScopeOper . call ( node ) ;
3863 } else if ( node . depsTail !== undefined ) {
@@ -43,12 +68,6 @@ const {
4368 } ,
4469} ) ;
4570
46- let cycle = 0 ;
47- let batchDepth = 0 ;
48- let notifyIndex = 0 ;
49- let queuedEffectsLength = 0 ;
50- let activeSub : ReactiveNode | undefined ;
51-
5271export function getActiveSub ( ) : ReactiveNode | undefined {
5372 return activeSub ;
5473}
@@ -144,7 +163,7 @@ export function effect(fn: () => void): () => void {
144163}
145164
146165export function effectScope ( fn : ( ) => void ) : ( ) => void {
147- const e : EffectScope = {
166+ const e : ReactiveNode = {
148167 deps : undefined ,
149168 depsTail : undefined ,
150169 subs : undefined ,
@@ -183,28 +202,13 @@ function updateSignal(s: Signal): boolean {
183202 return s . currentValue !== ( s . currentValue = s . pendingValue ) ;
184203}
185204
186- function notify ( e : Effect | EffectScope ) {
205+ function run ( e : Effect ) : void {
187206 const flags = e . flags ;
188- if ( ! ( flags & 64 /* Queued */ ) ) {
189- e . flags = flags | 64 /* Queued */ ;
190- const subs = e . subs ;
191- if ( subs !== undefined ) {
192- notify ( subs . sub as Effect | EffectScope ) ;
193- } else {
194- queuedEffects [ queuedEffectsLength ++ ] = e ;
195- }
196- }
197- }
198-
199- function run ( e : Effect | EffectScope , flags : ReactiveFlags ) : void {
200207 if (
201208 flags & 16 satisfies ReactiveFlags . Dirty
202209 || (
203210 flags & 32 satisfies ReactiveFlags . Pending
204- && (
205- checkDirty ( e . deps ! , e )
206- || ( e . flags = flags & ~ ( 32 satisfies ReactiveFlags . Pending ) , false )
207- )
211+ && checkDirty ( e . deps ! , e )
208212 )
209213 ) {
210214 ++ cycle ;
@@ -219,26 +223,18 @@ function run(e: Effect | EffectScope, flags: ReactiveFlags): void {
219223 purgeDeps ( e ) ;
220224 }
221225 } else {
222- let link = e . deps ;
223- while ( link !== undefined ) {
224- const dep = link . dep ;
225- const depFlags = dep . flags ;
226- if ( depFlags & 64 /* Queued */ ) {
227- run ( dep , dep . flags = depFlags & ~ ( 64 /* Queued */ ) ) ;
228- }
229- link = link . nextDep ;
230- }
226+ e . flags = 2 satisfies ReactiveFlags . Watching ;
231227 }
232228}
233229
234230function flush ( ) : void {
235- while ( notifyIndex < queuedEffectsLength ) {
236- const effect = queuedEffects [ notifyIndex ] ! ;
237- queuedEffects [ notifyIndex ++ ] = undefined ;
238- run ( effect , effect . flags &= ~ ( 64 /* Queued */ ) ) ;
231+ while ( notifyIndex < queuedLength ) {
232+ const effect = queued [ notifyIndex ] ! ;
233+ queued [ notifyIndex ++ ] = undefined ;
234+ run ( effect ) ;
239235 }
240236 notifyIndex = 0 ;
241- queuedEffectsLength = 0 ;
237+ queuedLength = 0 ;
242238}
243239
244240function computedOper < T > ( this : Computed < T > ) : T {
@@ -312,7 +308,7 @@ function effectOper(this: Effect): void {
312308 effectScopeOper . call ( this ) ;
313309}
314310
315- function effectScopeOper ( this : EffectScope ) : void {
311+ function effectScopeOper ( this : ReactiveNode ) : void {
316312 this . depsTail = undefined ;
317313 this . flags = 0 satisfies ReactiveFlags . None ;
318314 purgeDeps ( this ) ;
0 commit comments