@esportsplus/reactivity 0.12.0 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/reactive/array.d.ts +1 -0
- package/build/reactive/array.js +26 -29
- package/build/reactive/index.js +17 -7
- package/build/reactive/object.js +2 -4
- package/build/system.d.ts +4 -1
- package/build/system.js +38 -34
- package/package.json +1 -1
- package/src/reactive/array.ts +30 -35
- package/src/reactive/index.ts +21 -8
- package/src/reactive/object.ts +3 -6
- package/src/system.ts +41 -37
|
@@ -35,6 +35,7 @@ type Listener<V> = {
|
|
|
35
35
|
type Value<T> = T extends Record<PropertyKey, unknown> ? ReactiveObject<T> : T extends Array<infer U> ? API<U> : T;
|
|
36
36
|
declare class ReactiveArray<T> {
|
|
37
37
|
[REACTIVE_ARRAY]: boolean;
|
|
38
|
+
disposables: number;
|
|
38
39
|
private data;
|
|
39
40
|
private listeners;
|
|
40
41
|
private proxy;
|
package/build/reactive/array.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { isFunction, isNumber, isObject } from '@esportsplus/utilities';
|
|
2
2
|
import { REACTIVE_ARRAY } from '../constants.js';
|
|
3
|
-
import { computed, dispose, isComputed,
|
|
3
|
+
import { computed, dispose, isComputed, read } from '../system.js';
|
|
4
4
|
import object, { isReactiveObject } from './object.js';
|
|
5
5
|
class ReactiveArray {
|
|
6
6
|
[REACTIVE_ARRAY] = true;
|
|
7
|
+
disposables = 0;
|
|
7
8
|
data;
|
|
8
9
|
listeners = null;
|
|
9
10
|
proxy;
|
|
@@ -171,36 +172,32 @@ const isReactiveArray = (value) => {
|
|
|
171
172
|
return isObject(value) && REACTIVE_ARRAY in value;
|
|
172
173
|
};
|
|
173
174
|
export default function array(input) {
|
|
174
|
-
let
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
return read(value);
|
|
181
|
-
}
|
|
182
|
-
return value;
|
|
175
|
+
let proxy = new Proxy({}, {
|
|
176
|
+
get(_, key) {
|
|
177
|
+
if (isNumber(key)) {
|
|
178
|
+
let value = wrapped[key];
|
|
179
|
+
if (isComputed(value)) {
|
|
180
|
+
return read(value);
|
|
183
181
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
return
|
|
188
|
-
},
|
|
189
|
-
set(_, key, value) {
|
|
190
|
-
if (isNumber(key)) {
|
|
191
|
-
array.splice(key, 1, value);
|
|
192
|
-
return true;
|
|
193
|
-
}
|
|
194
|
-
else if (key === 'length') {
|
|
195
|
-
return array.length = value;
|
|
196
|
-
}
|
|
197
|
-
return false;
|
|
182
|
+
return value;
|
|
183
|
+
}
|
|
184
|
+
else if (key in array) {
|
|
185
|
+
return array[key];
|
|
198
186
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
187
|
+
return wrapped[key];
|
|
188
|
+
},
|
|
189
|
+
set(_, key, value) {
|
|
190
|
+
if (isNumber(key)) {
|
|
191
|
+
array.splice(key, 1, value);
|
|
192
|
+
return true;
|
|
193
|
+
}
|
|
194
|
+
else if (key === 'length') {
|
|
195
|
+
return array.length = value;
|
|
196
|
+
}
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
}), wrapped = factory(input);
|
|
200
|
+
let array = new ReactiveArray(wrapped, proxy);
|
|
204
201
|
return proxy;
|
|
205
202
|
}
|
|
206
203
|
;
|
package/build/reactive/index.js
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
import { isArray, isObject } from '@esportsplus/utilities';
|
|
2
|
+
import { onCleanup, root } from '../system.js';
|
|
2
3
|
import array from './array.js';
|
|
3
4
|
import object from './object.js';
|
|
4
5
|
export default (input) => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
let value;
|
|
7
|
+
return root(() => {
|
|
8
|
+
if (isArray(input)) {
|
|
9
|
+
value = array(input);
|
|
10
|
+
}
|
|
11
|
+
else if (isObject(input)) {
|
|
12
|
+
value = object(input);
|
|
13
|
+
}
|
|
14
|
+
if (value) {
|
|
15
|
+
if (root.disposables) {
|
|
16
|
+
onCleanup(() => value.dispose());
|
|
17
|
+
}
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
throw new Error(`@esportsplus/reactivity: 'reactive' received invalid input - ${JSON.stringify(input)}`);
|
|
21
|
+
});
|
|
12
22
|
};
|
package/build/reactive/object.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineProperty, isArray, isFunction, isObject, isPromise } from '@esportsplus/utilities';
|
|
2
|
-
import { computed, dispose, effect, isComputed,
|
|
2
|
+
import { computed, dispose, effect, isComputed, read, root, set, signal } from '../system.js';
|
|
3
3
|
import { REACTIVE_OBJECT } from '../constants.js';
|
|
4
4
|
import array, { isReactiveArray } from './array.js';
|
|
5
5
|
class ReactiveObject {
|
|
@@ -74,9 +74,7 @@ const isReactiveObject = (value) => {
|
|
|
74
74
|
return isObject(value) && REACTIVE_OBJECT in value;
|
|
75
75
|
};
|
|
76
76
|
export default function object(input) {
|
|
77
|
-
|
|
78
|
-
onCleanup(() => object.dispose());
|
|
79
|
-
return object;
|
|
77
|
+
return new ReactiveObject(input);
|
|
80
78
|
}
|
|
81
79
|
;
|
|
82
80
|
export { isReactiveObject };
|
package/build/system.d.ts
CHANGED
|
@@ -6,7 +6,10 @@ declare const isComputed: (value: unknown) => value is Computed<unknown>;
|
|
|
6
6
|
declare const isSignal: (value: unknown) => value is Signal<unknown>;
|
|
7
7
|
declare const onCleanup: (fn: VoidFunction) => typeof fn;
|
|
8
8
|
declare const read: <T>(node: Signal<T> | Computed<T>) => T;
|
|
9
|
-
declare const root:
|
|
9
|
+
declare const root: {
|
|
10
|
+
<T>(fn: () => T): T;
|
|
11
|
+
disposables: number;
|
|
12
|
+
};
|
|
10
13
|
declare const set: <T>(signal: Signal<T>, value: T) => void;
|
|
11
14
|
declare const signal: <T>(value: T) => Signal<T>;
|
|
12
15
|
export { computed, dispose, effect, isComputed, isSignal, onCleanup, read, root, set, signal };
|
package/build/system.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { isArray, isObject
|
|
1
|
+
import { isArray, isObject } from '@esportsplus/utilities';
|
|
2
2
|
import { COMPUTED, SIGNAL, STABILIZER_IDLE, STABILIZER_RESCHEDULE, STABILIZER_RUNNING, STABILIZER_SCHEDULED, STATE_CHECK, STATE_DIRTY, STATE_IN_HEAP, STATE_NONE, STATE_RECOMPUTING } from './constants.js';
|
|
3
3
|
let depth = 0, heap = new Array(2048), index = 0, length = 0, microtask = queueMicrotask, notified = false, observer = null, stabilizer = STABILIZER_IDLE, version = 0;
|
|
4
|
-
function cleanup(
|
|
5
|
-
if (!
|
|
4
|
+
function cleanup(computed) {
|
|
5
|
+
if (!computed.cleanup) {
|
|
6
6
|
return;
|
|
7
7
|
}
|
|
8
|
-
let
|
|
9
|
-
if (isArray(
|
|
10
|
-
for (let i = 0, n =
|
|
11
|
-
|
|
8
|
+
let value = computed.cleanup;
|
|
9
|
+
if (isArray(value)) {
|
|
10
|
+
for (let i = 0, n = value.length; i < n; i++) {
|
|
11
|
+
value[i]();
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
else {
|
|
15
|
-
|
|
15
|
+
value();
|
|
16
16
|
}
|
|
17
|
-
|
|
17
|
+
computed.cleanup = null;
|
|
18
18
|
}
|
|
19
19
|
function deleteFromHeap(computed) {
|
|
20
20
|
let state = computed.state;
|
|
@@ -138,11 +138,11 @@ function recompute(computed, del) {
|
|
|
138
138
|
depth--;
|
|
139
139
|
observer = o;
|
|
140
140
|
computed.state = STATE_NONE;
|
|
141
|
-
let depsTail = computed.depsTail,
|
|
142
|
-
if (
|
|
141
|
+
let depsTail = computed.depsTail, remove = depsTail !== null ? depsTail.nextDep : computed.deps;
|
|
142
|
+
if (remove !== null) {
|
|
143
143
|
do {
|
|
144
|
-
|
|
145
|
-
} while (
|
|
144
|
+
remove = unlink(remove);
|
|
145
|
+
} while (remove !== null);
|
|
146
146
|
if (depsTail !== null) {
|
|
147
147
|
depsTail.nextDep = null;
|
|
148
148
|
}
|
|
@@ -153,11 +153,11 @@ function recompute(computed, del) {
|
|
|
153
153
|
if (ok && value !== computed.value) {
|
|
154
154
|
computed.value = value;
|
|
155
155
|
for (let c = computed.subs; c !== null; c = c.nextSub) {
|
|
156
|
-
let
|
|
156
|
+
let s = c.sub, state = s.state;
|
|
157
157
|
if (state & STATE_CHECK) {
|
|
158
|
-
|
|
158
|
+
s.state = state | STATE_DIRTY;
|
|
159
159
|
}
|
|
160
|
-
insertIntoHeap(
|
|
160
|
+
insertIntoHeap(s);
|
|
161
161
|
}
|
|
162
162
|
schedule();
|
|
163
163
|
}
|
|
@@ -172,24 +172,24 @@ function schedule() {
|
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
174
|
function stabilize() {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
175
|
+
root(() => {
|
|
176
|
+
stabilizer = STABILIZER_RUNNING;
|
|
177
|
+
for (index = 0; index <= length; index++) {
|
|
178
|
+
let computed = heap[index];
|
|
179
|
+
heap[index] = undefined;
|
|
180
|
+
while (computed !== undefined) {
|
|
181
|
+
let next = computed.nextHeap;
|
|
182
|
+
recompute(computed, false);
|
|
183
|
+
computed = next;
|
|
184
|
+
}
|
|
184
185
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
}
|
|
186
|
+
if (stabilizer === STABILIZER_RESCHEDULE) {
|
|
187
|
+
microtask(stabilize);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
stabilizer = STABILIZER_IDLE;
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
193
|
}
|
|
194
194
|
function unlink(link) {
|
|
195
195
|
let { dep, nextDep, nextSub, prevSub } = link;
|
|
@@ -255,6 +255,7 @@ const computed = (fn) => {
|
|
|
255
255
|
}
|
|
256
256
|
else {
|
|
257
257
|
recompute(self, false);
|
|
258
|
+
root.disposables++;
|
|
258
259
|
}
|
|
259
260
|
return self;
|
|
260
261
|
};
|
|
@@ -319,12 +320,15 @@ const read = (node) => {
|
|
|
319
320
|
return node.value;
|
|
320
321
|
};
|
|
321
322
|
const root = (fn) => {
|
|
322
|
-
let o = observer;
|
|
323
|
+
let d = root.disposables, o = observer;
|
|
323
324
|
observer = null;
|
|
325
|
+
root.disposables = 0;
|
|
324
326
|
let value = fn();
|
|
325
327
|
observer = o;
|
|
328
|
+
root.disposables = d;
|
|
326
329
|
return value;
|
|
327
330
|
};
|
|
331
|
+
root.disposables = 0;
|
|
328
332
|
const set = (signal, value) => {
|
|
329
333
|
if (signal.value === value) {
|
|
330
334
|
return;
|
package/package.json
CHANGED
package/src/reactive/array.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isFunction, isNumber, isObject } from '@esportsplus/utilities';
|
|
2
2
|
import { REACTIVE_ARRAY } from '~/constants';
|
|
3
|
-
import { computed, dispose, isComputed,
|
|
3
|
+
import { computed, dispose, isComputed, read } from '~/system';
|
|
4
4
|
import { Computed, Infer } from '~/types';
|
|
5
5
|
import object, { isReactiveObject, ReactiveObject } from './object';
|
|
6
6
|
|
|
@@ -50,6 +50,7 @@ type Value<T> =
|
|
|
50
50
|
|
|
51
51
|
class ReactiveArray<T> {
|
|
52
52
|
[REACTIVE_ARRAY] = true;
|
|
53
|
+
disposables: number = 0;
|
|
53
54
|
|
|
54
55
|
private data: Item<T>[];
|
|
55
56
|
private listeners: Record<string, (Listener<any> | null)[]> | null = null;
|
|
@@ -294,44 +295,38 @@ const isReactiveArray = (value: any): value is ReactiveArray<any> => {
|
|
|
294
295
|
|
|
295
296
|
|
|
296
297
|
export default function array<T>(input: T[]) {
|
|
297
|
-
let
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
return read(value);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
return value;
|
|
308
|
-
}
|
|
309
|
-
else if (key in array) {
|
|
310
|
-
return array[key as keyof typeof array];
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
return wrapped[key];
|
|
314
|
-
},
|
|
315
|
-
set(_: any, key: any, value: any) {
|
|
316
|
-
if (isNumber(key)) {
|
|
317
|
-
array.splice(key, 1, value);
|
|
318
|
-
return true;
|
|
319
|
-
}
|
|
320
|
-
else if (key === 'length') {
|
|
321
|
-
return array.length = value;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
return false;
|
|
298
|
+
let proxy = new Proxy({}, {
|
|
299
|
+
get(_: any, key: any) {
|
|
300
|
+
if (isNumber(key)) {
|
|
301
|
+
let value = wrapped[key];
|
|
302
|
+
|
|
303
|
+
if (isComputed(value)) {
|
|
304
|
+
return read(value);
|
|
325
305
|
}
|
|
326
|
-
}) as API<T>,
|
|
327
|
-
wrapped = factory(input);
|
|
328
306
|
|
|
329
|
-
|
|
307
|
+
return value;
|
|
308
|
+
}
|
|
309
|
+
else if (key in array) {
|
|
310
|
+
return array[key as keyof typeof array];
|
|
311
|
+
}
|
|
330
312
|
|
|
331
|
-
|
|
332
|
-
|
|
313
|
+
return wrapped[key];
|
|
314
|
+
},
|
|
315
|
+
set(_: any, key: any, value: any) {
|
|
316
|
+
if (isNumber(key)) {
|
|
317
|
+
array.splice(key, 1, value);
|
|
318
|
+
return true;
|
|
319
|
+
}
|
|
320
|
+
else if (key === 'length') {
|
|
321
|
+
return array.length = value;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
return false;
|
|
325
|
+
}
|
|
326
|
+
}) as API<T>,
|
|
327
|
+
wrapped = factory(input);
|
|
333
328
|
|
|
334
|
-
|
|
329
|
+
let array = new ReactiveArray(wrapped, proxy);
|
|
335
330
|
|
|
336
331
|
return proxy;
|
|
337
332
|
};
|
package/src/reactive/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isArray, isObject } from '@esportsplus/utilities';
|
|
2
|
+
import { onCleanup, root } from '~/system';
|
|
2
3
|
import array from './array';
|
|
3
4
|
import object from './object';
|
|
4
5
|
|
|
@@ -21,13 +22,25 @@ type Input<T> =
|
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
export default <T extends Record<PropertyKey, unknown> | unknown[]>(input: Input<T>): API<T> => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
let value: API<T> | undefined;
|
|
26
|
+
|
|
27
|
+
return root(() => {
|
|
28
|
+
if (isArray(input)) {
|
|
29
|
+
value = array(input) as API<T>;
|
|
30
|
+
}
|
|
31
|
+
else if (isObject(input)) {
|
|
32
|
+
value = object(input) as API<T>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (value) {
|
|
36
|
+
if (root.disposables) {
|
|
37
|
+
onCleanup(() => value!.dispose());
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
throw new Error(`@esportsplus/reactivity: 'reactive' received invalid input - ${JSON.stringify(input)}`);
|
|
44
|
+
});
|
|
32
45
|
};
|
|
33
46
|
export type { Input };
|
package/src/reactive/object.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineProperty, isArray, isFunction, isObject, isPromise, Prettify } from '@esportsplus/utilities';
|
|
2
|
-
import { computed, dispose, effect, isComputed,
|
|
2
|
+
import { computed, dispose, effect, isComputed, read, root, set, signal } from '~/system';
|
|
3
3
|
import { Computed, Infer, Signal } from '~/types';
|
|
4
4
|
import { REACTIVE_OBJECT } from '~/constants';
|
|
5
5
|
import array, { isReactiveArray } from './array';
|
|
@@ -11,6 +11,7 @@ type API<T extends Record<PropertyKey, unknown>> = Prettify<{ [K in keyof T]: In
|
|
|
11
11
|
class ReactiveObject<T extends Record<PropertyKey, unknown>> {
|
|
12
12
|
[REACTIVE_OBJECT] = true;
|
|
13
13
|
|
|
14
|
+
|
|
14
15
|
constructor(data: T) {
|
|
15
16
|
for (let key in data) {
|
|
16
17
|
let value = data[key];
|
|
@@ -100,11 +101,7 @@ const isReactiveObject = (value: any): value is ReactiveObject<any> => {
|
|
|
100
101
|
|
|
101
102
|
|
|
102
103
|
export default function object<T extends Record<PropertyKey, unknown>>(input: T) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
onCleanup(() => object.dispose());
|
|
106
|
-
|
|
107
|
-
return object;
|
|
104
|
+
return new ReactiveObject<T>(input);
|
|
108
105
|
};
|
|
109
106
|
export { isReactiveObject };
|
|
110
107
|
export type { API as ReactiveObject };
|
package/src/system.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isArray, isObject
|
|
1
|
+
import { isArray, isObject } from '@esportsplus/utilities';
|
|
2
2
|
import {
|
|
3
3
|
COMPUTED, SIGNAL,
|
|
4
4
|
STABILIZER_IDLE, STABILIZER_RESCHEDULE, STABILIZER_RUNNING, STABILIZER_SCHEDULED,
|
|
@@ -18,23 +18,23 @@ let depth = 0,
|
|
|
18
18
|
version = 0;
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
function cleanup<T>(
|
|
22
|
-
if (!
|
|
21
|
+
function cleanup<T>(computed: Computed<T>): void {
|
|
22
|
+
if (!computed.cleanup) {
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
let
|
|
26
|
+
let value = computed.cleanup;
|
|
27
27
|
|
|
28
|
-
if (isArray(
|
|
29
|
-
for (let i = 0, n =
|
|
30
|
-
|
|
28
|
+
if (isArray(value)) {
|
|
29
|
+
for (let i = 0, n = value.length; i < n; i++) {
|
|
30
|
+
value[i]();
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
else {
|
|
34
|
-
|
|
34
|
+
value();
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
computed.cleanup = null;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
function deleteFromHeap<T>(computed: Computed<T>) {
|
|
@@ -208,13 +208,13 @@ function recompute<T>(computed: Computed<T>, del: boolean) {
|
|
|
208
208
|
computed.state = STATE_NONE;
|
|
209
209
|
|
|
210
210
|
let depsTail = computed.depsTail as Link | null,
|
|
211
|
-
|
|
211
|
+
remove = depsTail !== null ? depsTail.nextDep : computed.deps;
|
|
212
212
|
|
|
213
|
-
if (
|
|
213
|
+
if (remove !== null) {
|
|
214
214
|
do {
|
|
215
|
-
|
|
215
|
+
remove = unlink(remove);
|
|
216
216
|
}
|
|
217
|
-
while (
|
|
217
|
+
while (remove !== null);
|
|
218
218
|
|
|
219
219
|
if (depsTail !== null) {
|
|
220
220
|
depsTail.nextDep = null;
|
|
@@ -228,14 +228,14 @@ function recompute<T>(computed: Computed<T>, del: boolean) {
|
|
|
228
228
|
computed.value = value as T;
|
|
229
229
|
|
|
230
230
|
for (let c = computed.subs; c !== null; c = c.nextSub) {
|
|
231
|
-
let
|
|
232
|
-
state =
|
|
231
|
+
let s = c.sub,
|
|
232
|
+
state = s.state;
|
|
233
233
|
|
|
234
234
|
if (state & STATE_CHECK) {
|
|
235
|
-
|
|
235
|
+
s.state = state | STATE_DIRTY;
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
-
insertIntoHeap(
|
|
238
|
+
insertIntoHeap(s);
|
|
239
239
|
}
|
|
240
240
|
|
|
241
241
|
schedule();
|
|
@@ -253,32 +253,30 @@ function schedule() {
|
|
|
253
253
|
}
|
|
254
254
|
|
|
255
255
|
function stabilize() {
|
|
256
|
-
|
|
256
|
+
root(() => {
|
|
257
|
+
stabilizer = STABILIZER_RUNNING;
|
|
257
258
|
|
|
258
|
-
|
|
259
|
+
for (index = 0; index <= length; index++) {
|
|
260
|
+
let computed = heap[index];
|
|
259
261
|
|
|
260
|
-
|
|
261
|
-
let computed = heap[index];
|
|
262
|
+
heap[index] = undefined;
|
|
262
263
|
|
|
263
|
-
|
|
264
|
+
while (computed !== undefined) {
|
|
265
|
+
let next = computed.nextHeap;
|
|
264
266
|
|
|
265
|
-
|
|
266
|
-
let next = computed.nextHeap;
|
|
267
|
+
recompute(computed, false);
|
|
267
268
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
computed = next;
|
|
269
|
+
computed = next;
|
|
270
|
+
}
|
|
271
271
|
}
|
|
272
|
-
}
|
|
273
272
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}
|
|
273
|
+
if (stabilizer === STABILIZER_RESCHEDULE) {
|
|
274
|
+
microtask(stabilize);
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
stabilizer = STABILIZER_IDLE;
|
|
278
|
+
}
|
|
279
|
+
});
|
|
282
280
|
}
|
|
283
281
|
|
|
284
282
|
// https://github.com/stackblitz/alien-signals/blob/v2.0.3/src/system.ts#L100
|
|
@@ -359,6 +357,7 @@ const computed = <T>(fn: Computed<T>['fn']): Computed<T> => {
|
|
|
359
357
|
}
|
|
360
358
|
else {
|
|
361
359
|
recompute(self, false);
|
|
360
|
+
root.disposables++;
|
|
362
361
|
}
|
|
363
362
|
|
|
364
363
|
return self;
|
|
@@ -446,17 +445,22 @@ const read = <T>(node: Signal<T> | Computed<T>): T => {
|
|
|
446
445
|
};
|
|
447
446
|
|
|
448
447
|
const root = <T>(fn: () => T) => {
|
|
449
|
-
let
|
|
448
|
+
let d = root.disposables,
|
|
449
|
+
o = observer;
|
|
450
450
|
|
|
451
451
|
observer = null;
|
|
452
|
+
root.disposables = 0;
|
|
452
453
|
|
|
453
454
|
let value = fn();
|
|
454
455
|
|
|
455
456
|
observer = o;
|
|
457
|
+
root.disposables = d;
|
|
456
458
|
|
|
457
459
|
return value;
|
|
458
460
|
};
|
|
459
461
|
|
|
462
|
+
root.disposables = 0;
|
|
463
|
+
|
|
460
464
|
const set = <T>(signal: Signal<T>, value: T) => {
|
|
461
465
|
if (signal.value === value) {
|
|
462
466
|
return;
|