signalium 0.2.2 → 0.2.4
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/CHANGELOG.md +12 -0
- package/dist/config.d.ts +6 -2
- package/dist/config.js +11 -14
- package/dist/scheduling.d.ts +3 -1
- package/dist/scheduling.js +36 -26
- package/dist/signals.d.ts +8 -12
- package/dist/signals.js +103 -265
- package/dist/weakref.d.ts +2 -0
- package/dist/weakref.js +10 -0
- package/package.json +1 -1
- package/src/__tests__/async.test.ts +141 -11
- package/src/__tests__/subscription.test.ts +3 -3
- package/src/__tests__/utils/instrumented.ts +3 -3
- package/src/config.ts +14 -14
- package/src/scheduling.ts +42 -34
- package/src/signals.ts +113 -326
- package/src/weakref.ts +9 -0
package/CHANGELOG.md
CHANGED
package/dist/config.d.ts
CHANGED
@@ -1,3 +1,7 @@
|
|
1
1
|
export type FlushCallback = () => Promise<void>;
|
2
|
-
export
|
3
|
-
export declare let
|
2
|
+
export type FlushFn = (fn: () => Promise<void>) => void;
|
3
|
+
export declare let scheduleFlush: FlushFn;
|
4
|
+
export declare const setScheduleFlush: (flushFn: FlushFn) => void;
|
5
|
+
export type BatchFn = (fn: () => void) => void;
|
6
|
+
export declare let runBatch: BatchFn;
|
7
|
+
export declare const setRunBatch: (batchFn: BatchFn) => void;
|
package/dist/config.js
CHANGED
@@ -1,19 +1,16 @@
|
|
1
|
-
let
|
2
|
-
let
|
3
|
-
|
4
|
-
export let scheduleWatchers = flushWatchers => {
|
5
|
-
if (currentWatcherFlush !== null)
|
1
|
+
let currentFlush = null;
|
2
|
+
export let scheduleFlush = flushWatchers => {
|
3
|
+
if (currentFlush !== null)
|
6
4
|
return;
|
7
|
-
|
8
|
-
|
5
|
+
currentFlush = setTimeout(() => {
|
6
|
+
currentFlush = null;
|
9
7
|
flushWatchers();
|
10
8
|
}, 0);
|
11
9
|
};
|
12
|
-
export
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
});
|
10
|
+
export const setScheduleFlush = (flushFn) => {
|
11
|
+
scheduleFlush = flushFn;
|
12
|
+
};
|
13
|
+
export let runBatch = fn => fn();
|
14
|
+
export const setRunBatch = (batchFn) => {
|
15
|
+
runBatch = batchFn;
|
19
16
|
};
|
package/dist/scheduling.d.ts
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
-
import
|
1
|
+
import { ComputedSignal } from './signals.js';
|
2
2
|
export declare const scheduleWatcher: (watcher: ComputedSignal<any>) => void;
|
3
|
+
export declare const scheduleDirty: (signal: ComputedSignal<any>) => void;
|
4
|
+
export declare const schedulePull: (signal: ComputedSignal<any>) => void;
|
3
5
|
export declare const scheduleDisconnect: (disconnect: ComputedSignal<any>) => void;
|
package/dist/scheduling.js
CHANGED
@@ -1,36 +1,46 @@
|
|
1
|
-
import {
|
2
|
-
let
|
3
|
-
|
4
|
-
|
1
|
+
import { scheduleFlush, runBatch } from './config.js';
|
2
|
+
let PENDING_DIRTIES = [];
|
3
|
+
let PENDING_PULLS = [];
|
4
|
+
let PENDING_WATCHERS = [];
|
5
|
+
let PENDING_DISCONNECTS = new Map();
|
6
|
+
const microtask = () => Promise.resolve();
|
5
7
|
export const scheduleWatcher = (watcher) => {
|
6
8
|
PENDING_WATCHERS.push(watcher);
|
7
|
-
|
8
|
-
let resolve;
|
9
|
-
const promise = new Promise(r => {
|
10
|
-
resolve = r;
|
11
|
-
});
|
12
|
-
PENDING_FLUSH_WATCHERS = { promise, resolve: resolve };
|
13
|
-
}
|
14
|
-
scheduleWatchers(flushWatchers);
|
9
|
+
scheduleFlush(flushWatchers);
|
15
10
|
};
|
16
|
-
const
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
PENDING_WATCHERS.length = 0;
|
11
|
+
export const scheduleDirty = (signal) => {
|
12
|
+
PENDING_DIRTIES.push(signal);
|
13
|
+
scheduleFlush(flushWatchers);
|
14
|
+
};
|
15
|
+
export const schedulePull = (signal) => {
|
16
|
+
PENDING_PULLS.push(signal);
|
17
|
+
scheduleFlush(flushWatchers);
|
24
18
|
};
|
25
19
|
export const scheduleDisconnect = (disconnect) => {
|
26
20
|
const current = PENDING_DISCONNECTS.get(disconnect) ?? 0;
|
27
21
|
PENDING_DISCONNECTS.set(disconnect, current + 1);
|
28
|
-
|
22
|
+
scheduleFlush(flushWatchers);
|
29
23
|
};
|
30
|
-
const
|
31
|
-
|
32
|
-
|
33
|
-
|
24
|
+
const flushWatchers = async () => {
|
25
|
+
while (PENDING_DIRTIES.length > 0 || PENDING_PULLS.length > 0) {
|
26
|
+
for (const dirty of PENDING_DIRTIES) {
|
27
|
+
dirty._dirtyConsumers();
|
28
|
+
}
|
29
|
+
for (const pull of PENDING_PULLS) {
|
30
|
+
pull._check();
|
31
|
+
}
|
32
|
+
PENDING_DIRTIES = [];
|
33
|
+
PENDING_PULLS = [];
|
34
|
+
await microtask();
|
34
35
|
}
|
35
|
-
|
36
|
+
runBatch(() => {
|
37
|
+
for (const watcher of PENDING_WATCHERS) {
|
38
|
+
watcher._check();
|
39
|
+
}
|
40
|
+
for (const [signal, count] of PENDING_DISCONNECTS) {
|
41
|
+
signal._disconnect(count);
|
42
|
+
}
|
43
|
+
PENDING_WATCHERS = [];
|
44
|
+
PENDING_DISCONNECTS.clear();
|
45
|
+
});
|
36
46
|
};
|
package/dist/signals.d.ts
CHANGED
@@ -32,26 +32,22 @@ declare const enum SignalState {
|
|
32
32
|
Dirty = 2
|
33
33
|
}
|
34
34
|
interface Link {
|
35
|
-
id: number;
|
36
|
-
sub: WeakRef<ComputedSignal<any>>;
|
37
35
|
dep: ComputedSignal<any>;
|
36
|
+
sub: WeakRef<ComputedSignal<any>>;
|
38
37
|
ord: number;
|
39
38
|
version: number;
|
40
|
-
|
41
|
-
nextSub: Link | undefined;
|
42
|
-
prevSub: Link | undefined;
|
39
|
+
consumedAt: number;
|
43
40
|
nextDirty: Link | undefined;
|
44
41
|
}
|
45
|
-
export declare function endTrack(sub: ComputedSignal<any>, shouldDisconnect: boolean): void;
|
46
42
|
export declare class ComputedSignal<T> {
|
47
|
-
|
43
|
+
_id: number;
|
48
44
|
_type: SignalType;
|
49
|
-
|
50
|
-
_subsTail: Link | undefined;
|
51
|
-
_deps: Link | undefined;
|
45
|
+
_deps: Map<ComputedSignal<any>, Link>;
|
52
46
|
_dirtyDep: Link | undefined;
|
47
|
+
_subs: Set<Link>;
|
53
48
|
_state: SignalState;
|
54
49
|
_version: number;
|
50
|
+
_computedCount: number;
|
55
51
|
_connectedCount: number;
|
56
52
|
_currentValue: T | AsyncResult<T> | undefined;
|
57
53
|
_compute: SignalCompute<T> | SignalAsyncCompute<T> | SignalSubscribe<T> | undefined;
|
@@ -60,7 +56,7 @@ export declare class ComputedSignal<T> {
|
|
60
56
|
constructor(type: SignalType, compute: SignalCompute<T> | SignalAsyncCompute<T> | SignalSubscribe<T> | undefined, equals?: SignalEquals<T>, initValue?: T);
|
61
57
|
get(): T | AsyncResult<T>;
|
62
58
|
_check(shouldWatch?: boolean): number;
|
63
|
-
_run(wasConnected: boolean,
|
59
|
+
_run(wasConnected: boolean, shouldConnect: boolean): void;
|
64
60
|
_resetDirty(): void;
|
65
61
|
_dirty(): void;
|
66
62
|
_dirtyConsumers(): void;
|
@@ -92,7 +88,7 @@ export type AsyncResult<T> = AsyncPending<T> | AsyncReady<T>;
|
|
92
88
|
declare class StateSignal<T> implements StateSignal<T> {
|
93
89
|
private _value;
|
94
90
|
private _equals;
|
95
|
-
private
|
91
|
+
private _subs;
|
96
92
|
constructor(_value: T, _equals?: SignalEquals<T>);
|
97
93
|
get(): T;
|
98
94
|
set(value: T): void;
|