Skip to content

Commit cf018d3

Browse files
committed
up
1 parent 76884c6 commit cf018d3

File tree

2 files changed

+30
-51
lines changed

2 files changed

+30
-51
lines changed

src/runtime/reactivity.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { OwlError } from "../common/owl_error";
22
import { Atom } from "../common/types";
3-
import { makeAtom, onReadAtom, onWriteAtom } from "./signals";
3+
import { onReadAtom, onWriteAtom } from "./signals";
44

55
// Special key to subscribe to, to be notified of key creation/deletion
66
const KEYCHANGES = Symbol("Key changes");
@@ -87,7 +87,10 @@ function getTargetKeyAtom(target: Target, key: PropertyKey): Atom {
8787
}
8888
let atom = keyToAtomItem.get(key)!;
8989
if (!atom) {
90-
atom = makeAtom();
90+
atom = {
91+
value: undefined,
92+
observers: new Set(),
93+
};
9194
keyToAtomItem.set(key, atom);
9295
}
9396
return atom;

src/runtime/signals.ts

Lines changed: 25 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ export function effect<T>(fn: () => T) {
99
state: ComputationState.STALE,
1010
value: undefined,
1111
compute() {
12+
// In case the cleanup read an atom.
13+
// todo: test it
1214
CurrentComputation = undefined!;
1315
// `removeSources` is made by `runComputation`.
1416
unsubscribeEffect(effectComputation);
@@ -23,11 +25,12 @@ export function effect<T>(fn: () => T) {
2325

2426
// Remove sources and unsubscribe
2527
return () => {
26-
removeSources(effectComputation);
27-
const currentComputation = CurrentComputation;
28+
// In case the cleanup read an atom.
29+
// todo: test it
30+
const previousComputation = CurrentComputation;
2831
CurrentComputation = undefined!;
2932
unsubscribeEffect(effectComputation);
30-
CurrentComputation = currentComputation!;
33+
CurrentComputation = previousComputation!;
3134
};
3235
}
3336
export function derived<T>(fn: () => T): () => T {
@@ -67,34 +70,27 @@ export function onWriteAtom(atom: Atom) {
6770
});
6871
batchProcessEffects();
6972
}
70-
export function makeAtom(): Atom {
71-
const atom: Atom = {
72-
value: undefined,
73-
observers: new Set(),
74-
};
75-
return atom;
76-
}
7773

74+
export function withoutReactivity<T extends (...args: any[]) => any>(fn: T): ReturnType<T> {
75+
return runWithComputation(undefined!, fn);
76+
}
7877
export function getCurrentComputation() {
7978
return CurrentComputation;
8079
}
8180
export function setComputation(computation: Computation) {
8281
CurrentComputation = computation;
8382
}
8483
export function runWithComputation<T>(computation: Computation, fn: () => T): T {
85-
const currentComputation = CurrentComputation;
84+
const previousComputation = CurrentComputation;
8685
CurrentComputation = computation;
8786
let result: T;
8887
try {
8988
result = fn();
9089
} finally {
91-
CurrentComputation = currentComputation!;
90+
CurrentComputation = previousComputation!;
9291
}
9392
return result;
9493
}
95-
export function withoutReactivity<T extends (...args: any[]) => any>(fn: T): ReturnType<T> {
96-
return runWithComputation(undefined!, fn);
97-
}
9894

9995
function updateComputation(computation: Computation) {
10096
const state = computation.state;
@@ -106,11 +102,11 @@ function updateComputation(computation: Computation) {
106102
// todo: test performance. We might want to avoid removing the atoms to
107103
// directly re-add them at compute. Especially as we are making them stale.
108104
removeSources(computation);
109-
const executionContext = CurrentComputation;
105+
const previousComputation = CurrentComputation;
110106
CurrentComputation = computation;
111107
computation.value = computation.compute?.();
112108
computation.state = ComputationState.EXECUTED;
113-
CurrentComputation = executionContext;
109+
CurrentComputation = previousComputation;
114110
}
115111

116112
function removeSources(computation: Computation) {
@@ -149,24 +145,16 @@ function processEffects() {
149145
}
150146

151147
function unsubscribeEffect(effectComputation: Computation) {
148+
removeSources(effectComputation);
152149
cleanupEffect(effectComputation);
153-
unsubscribeChildEffect(effectComputation);
154-
}
155-
/**
156-
* Unsubscribe an execution context and all its children from all atoms
157-
* they are subscribed to.
158-
*
159-
* @param parentEffect the context to unsubscribe
160-
*/
161-
function unsubscribeChildEffect(parentEffect: Computation) {
162-
for (const children of parentEffect.childrenEffect!) {
163-
cleanupEffect(children);
164-
removeSources(children);
150+
for (const children of effectComputation.childrenEffect!) {
165151
// Consider it executed to avoid it's re-execution
152+
// todo: make a test for it
166153
children.state = ComputationState.EXECUTED;
167-
unsubscribeChildEffect(children);
154+
removeSources(children);
155+
unsubscribeEffect(children);
168156
}
169-
parentEffect.childrenEffect!.length = 0;
157+
effectComputation.childrenEffect!.length = 0;
170158
}
171159
function cleanupEffect(computation: Computation) {
172160
// the computation.value of an effect is a cleanup function
@@ -177,24 +165,6 @@ function cleanupEffect(computation: Computation) {
177165
}
178166
}
179167

180-
function computeSources(derived: Derived<any, any>) {
181-
for (const source of derived.sources) {
182-
if ("sources" in source) continue;
183-
computeDerived(source as Derived<any, any>);
184-
}
185-
}
186-
187-
function computeDerived(derived: Derived<any, any>) {
188-
if (derived.state === ComputationState.EXECUTED) {
189-
onReadAtom(derived);
190-
return derived.value;
191-
} else if (derived.state === ComputationState.PENDING) {
192-
computeSources(derived);
193-
}
194-
onReadAtom(derived);
195-
return derived.value;
196-
}
197-
198168
function markDownstream<A, B>(derived: Derived<A, B>) {
199169
for (const observer of derived.observers) {
200170
// if the state has already been marked, skip it
@@ -204,6 +174,12 @@ function markDownstream<A, B>(derived: Derived<A, B>) {
204174
else Effects.push(observer);
205175
}
206176
}
177+
function computeSources(derived: Derived<any, any>) {
178+
for (const source of derived.sources) {
179+
if ("sources" in source) continue;
180+
updateComputation(source as Derived<any, any>);
181+
}
182+
}
207183

208184
// For tests
209185

0 commit comments

Comments
 (0)