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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # signalium
2
2
 
3
+ ## 0.2.4
4
+
5
+ ### Patch Changes
6
+
7
+ - c2af4d0: Refactor scheduling, add batching for React Native
8
+
9
+ ## 0.2.3
10
+
11
+ ### Patch Changes
12
+
13
+ - 0ba50a0: Remove linked-lists for deps and subs
14
+
3
15
  ## 0.2.2
4
16
 
5
17
  ### Patch Changes
package/dist/config.d.ts CHANGED
@@ -1,3 +1,7 @@
1
1
  export type FlushCallback = () => Promise<void>;
2
- export declare let scheduleWatchers: (flushWatchers: FlushCallback) => void;
3
- export declare let scheduleDisconnects: (flushDisconnects: FlushCallback) => void;
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 currentWatcherFlush = null;
2
- let currentDisconnectFlush = null;
3
- const idleCallback = typeof requestIdleCallback === 'function' ? requestIdleCallback : (cb) => setTimeout(cb, 0);
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
- currentWatcherFlush = setTimeout(() => {
8
- currentWatcherFlush = null;
5
+ currentFlush = setTimeout(() => {
6
+ currentFlush = null;
9
7
  flushWatchers();
10
8
  }, 0);
11
9
  };
12
- export let scheduleDisconnects = flushDisconnects => {
13
- if (currentDisconnectFlush !== null)
14
- return;
15
- currentDisconnectFlush = idleCallback(() => {
16
- currentDisconnectFlush = null;
17
- flushDisconnects();
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
  };
@@ -1,3 +1,5 @@
1
- import type { ComputedSignal } from './signals.js';
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;
@@ -1,36 +1,46 @@
1
- import { scheduleWatchers, scheduleDisconnects } from './config.js';
2
- let PENDING_FLUSH_WATCHERS = null;
3
- const PENDING_WATCHERS = [];
4
- const PENDING_DISCONNECTS = new Map();
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
- if (PENDING_FLUSH_WATCHERS === null) {
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 flushWatchers = async () => {
17
- PENDING_FLUSH_WATCHERS.resolve();
18
- PENDING_FLUSH_WATCHERS = null;
19
- let watcher;
20
- while ((watcher = PENDING_WATCHERS.shift())) {
21
- watcher._check();
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
- scheduleDisconnects(flushDisconnects);
22
+ scheduleFlush(flushWatchers);
29
23
  };
30
- const flushDisconnects = async () => {
31
- await PENDING_FLUSH_WATCHERS?.promise;
32
- for (const [signal, count] of PENDING_DISCONNECTS) {
33
- signal._disconnect(count);
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
- PENDING_DISCONNECTS.clear();
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
- nextDep: Link | undefined;
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
- id: number;
43
+ _id: number;
48
44
  _type: SignalType;
49
- _subs: Link | undefined;
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, isConnected: boolean, shouldConnect: boolean): void;
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 _consumers;
91
+ private _subs;
96
92
  constructor(_value: T, _equals?: SignalEquals<T>);
97
93
  get(): T;
98
94
  set(value: T): void;