Skip to content

Commit f0d9a98

Browse files
committed
up
1 parent cf018d3 commit f0d9a98

File tree

1 file changed

+31
-30
lines changed

1 file changed

+31
-30
lines changed

src/runtime/signals.ts

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -58,18 +58,37 @@ export function onReadAtom(atom: Atom) {
5858
CurrentComputation.sources!.add(atom);
5959
atom.observers.add(CurrentComputation);
6060
}
61+
6162
export function onWriteAtom(atom: Atom) {
62-
stackEffects(() => {
63+
collectEffects(() => {
6364
for (const ctx of atom.observers) {
6465
if (ctx.state === ComputationState.EXECUTED) {
65-
ctx.state = ComputationState.STALE;
6666
if (ctx.isDerived) markDownstream(ctx as Derived<any, any>);
6767
else Effects.push(ctx);
6868
}
69+
ctx.state = ComputationState.STALE;
6970
}
7071
});
7172
batchProcessEffects();
7273
}
74+
function collectEffects(fn: Function) {
75+
if (Effects) return fn();
76+
Effects = [];
77+
try {
78+
return fn();
79+
} finally {
80+
// processEffects();
81+
true;
82+
}
83+
}
84+
const batchProcessEffects = batched(processEffects);
85+
function processEffects() {
86+
if (!Effects) return;
87+
for (const computation of Effects) {
88+
updateComputation(computation);
89+
}
90+
Effects = undefined!;
91+
}
7392

7493
export function withoutReactivity<T extends (...args: any[]) => any>(fn: T): ReturnType<T> {
7594
return runWithComputation(undefined!, fn);
@@ -98,6 +117,13 @@ function updateComputation(computation: Computation) {
98117
if (state === ComputationState.EXECUTED) return;
99118
if (state === ComputationState.PENDING) {
100119
computeSources(computation as Derived<any, any>);
120+
// If the state is still not stale after processing the sources, it means
121+
// none of the dependencies have changed.
122+
// todo: test it
123+
if (computation.state !== ComputationState.STALE) {
124+
computation.state = ComputationState.EXECUTED;
125+
return;
126+
}
101127
}
102128
// todo: test performance. We might want to avoid removing the atoms to
103129
// directly re-add them at compute. Especially as we are making them stale.
@@ -108,42 +134,17 @@ function updateComputation(computation: Computation) {
108134
computation.state = ComputationState.EXECUTED;
109135
CurrentComputation = previousComputation;
110136
}
111-
112137
function removeSources(computation: Computation) {
113138
const sources = computation.sources;
114139
for (const source of sources) {
115140
const observers = source.observers;
116141
observers.delete(computation);
117-
// if source has no observer anymore, remove its sources too
118-
if (observers.size === 0 && "sources" in source) {
119-
removeSources(source as Derived<any, any>);
120-
if (source.state !== ComputationState.STALE) {
121-
source.state = ComputationState.PENDING;
122-
}
123-
}
142+
// todo: if source has no effect observer anymore, remove its sources too
143+
// todo: test it
124144
}
125145
sources.clear();
126146
}
127147

128-
function stackEffects(fn: Function) {
129-
if (Effects) return fn();
130-
Effects = [];
131-
try {
132-
return fn();
133-
} finally {
134-
// processEffects();
135-
true;
136-
}
137-
}
138-
const batchProcessEffects = batched(processEffects);
139-
function processEffects() {
140-
if (!Effects) return;
141-
for (const computation of Effects) {
142-
updateComputation(computation);
143-
}
144-
Effects = undefined!;
145-
}
146-
147148
function unsubscribeEffect(effectComputation: Computation) {
148149
removeSources(effectComputation);
149150
cleanupEffect(effectComputation);
@@ -176,7 +177,7 @@ function markDownstream<A, B>(derived: Derived<A, B>) {
176177
}
177178
function computeSources(derived: Derived<any, any>) {
178179
for (const source of derived.sources) {
179-
if ("sources" in source) continue;
180+
if (!("compute" in source)) continue;
180181
updateComputation(source as Derived<any, any>);
181182
}
182183
}

0 commit comments

Comments
 (0)