@esportsplus/reactivity 0.6.1 → 0.7.0

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/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { default as reactive } from './reactive/index.js';
2
2
  export { computed, dispose, oncleanup, root, signal, stabilize } from './signal.js';
3
+ export { default as scheduler } from './scheduler.js';
3
4
  export * from './types.js';
package/build/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export { default as reactive } from './reactive/index.js';
2
2
  export { computed, dispose, oncleanup, root, signal, stabilize } from './signal.js';
3
+ export { default as scheduler } from './scheduler.js';
3
4
  export * from './types.js';
@@ -27,12 +27,12 @@ type Events<T> = {
27
27
  items: Item<T>[];
28
28
  };
29
29
  };
30
- type Item<T> = Computed<T> | ReactiveArray<T> | ReactiveObject<T extends Record<PropertyKey, unknown> ? T : never> | T;
30
+ type Item<T> = Computed<T> | API<T> | ReactiveObject<T extends Record<PropertyKey, unknown> ? T : never> | T;
31
31
  type Listener<V> = {
32
32
  once?: boolean;
33
33
  (value: V): void;
34
34
  };
35
- type Value<T> = T extends Record<PropertyKey, unknown> ? ReactiveObject<T> : T extends Array<infer U> ? ReactiveArray<U> : T;
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> extends Disposable {
37
37
  private data;
38
38
  private listeners;
@@ -40,12 +40,12 @@ declare class ReactiveArray<T> extends Disposable {
40
40
  constructor(data: Item<T>[], proxy: API<T>);
41
41
  get length(): number;
42
42
  set length(n: number);
43
- at(i: number): ReactiveArray<T> | T | ReactiveObject<T extends Record<PropertyKey, unknown> ? T : never>;
44
- dispatch<D>(event: keyof Events<T>, value?: D): void;
43
+ at(i: number): T | API<T> | ReactiveObject<T extends Record<PropertyKey, unknown> ? T : never>;
44
+ dispatch<K extends keyof Events<T>, V>(event: K, value?: V): void;
45
45
  dispose(): void;
46
46
  map<R>(fn: (this: API<T>, value: Value<T>, i: number) => R, i?: number, n?: number): R[];
47
- on<T>(event: keyof Events<T>, listener: Listener<T>): void;
48
- once<T>(event: keyof Events<T>, listener: Listener<T>): void;
47
+ on<K extends keyof Events<T>>(event: K, listener: Listener<Events<T>[K]>): void;
48
+ once<K extends keyof Events<T>>(event: K, listener: Listener<Events<T>[K]>): void;
49
49
  pop(): Item<T> | undefined;
50
50
  push(...input: T[]): number;
51
51
  reverse(): this;
@@ -55,4 +55,4 @@ declare class ReactiveArray<T> extends Disposable {
55
55
  unshift(...input: T[]): number;
56
56
  }
57
57
  export default function array<T>(input: T[]): API<T>;
58
- export { ReactiveArray };
58
+ export type { API as ReactiveArray };
@@ -213,4 +213,3 @@ export default function array(input) {
213
213
  return proxy;
214
214
  }
215
215
  ;
216
- export { ReactiveArray };
@@ -10,4 +10,4 @@ declare class ReactiveObject<T extends Record<PropertyKey, unknown>> extends Dis
10
10
  dispose(): void;
11
11
  }
12
12
  export default function object<T extends Record<PropertyKey, unknown>>(input: T): API<T>;
13
- export { ReactiveObject };
13
+ export type { API as ReactiveObject };
@@ -91,4 +91,3 @@ export default function object(input) {
91
91
  return new ReactiveObject(input);
92
92
  }
93
93
  ;
94
- export { ReactiveObject };
@@ -0,0 +1,4 @@
1
+ declare const scheduler: (schedule: (task: VoidFunction) => void) => void;
2
+ declare const state: import("./types.js").Signal<number>;
3
+ export default scheduler;
4
+ export { state };
@@ -0,0 +1,17 @@
1
+ import { STATE_DIRTY, STATE_NONE } from './constants.js';
2
+ import { computed, dispose, read, signal, stabilize } from './signal.js';
3
+ let c = null;
4
+ const scheduler = (schedule) => {
5
+ if (c) {
6
+ dispose(c);
7
+ }
8
+ c = computed(() => {
9
+ if (read(state) !== STATE_DIRTY) {
10
+ return;
11
+ }
12
+ schedule(stabilize);
13
+ });
14
+ };
15
+ const state = signal(STATE_NONE);
16
+ export default scheduler;
17
+ export { state };
package/build/signal.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { isArray, isObject } from '@esportsplus/utilities';
2
2
  import { REACTIVE, STATE_CHECK, STATE_DIRTY, STATE_IN_HEAP, STATE_NONE, STATE_RECOMPUTING } from './constants.js';
3
+ import { state } from './scheduler.js';
3
4
  let dirtyHeap = new Array(2000), maxDirty = 0, markedHeap = false, minDirty = 0, observer = null;
4
5
  function cleanup(node) {
5
6
  if (!node.cleanup) {
@@ -159,6 +160,9 @@ function recompute(el, del) {
159
160
  insertIntoHeap(o);
160
161
  }
161
162
  }
163
+ if (state.value === STATE_NONE) {
164
+ root(() => signal.set(state, STATE_DIRTY));
165
+ }
162
166
  }
163
167
  function unlink(link) {
164
168
  let dep = link.dep, nextDep = link.nextDep, nextSub = link.nextSub, prevSub = link.prevSub;
@@ -305,14 +309,17 @@ signal.set = (el, v) => {
305
309
  }
306
310
  };
307
311
  const stabilize = () => {
308
- for (minDirty = 0; minDirty <= maxDirty; minDirty++) {
309
- let el = dirtyHeap[minDirty];
310
- dirtyHeap[minDirty] = undefined;
311
- while (el !== undefined) {
312
- let next = el.nextHeap;
313
- recompute(el, false);
314
- el = next;
312
+ root(() => {
313
+ for (minDirty = 0; minDirty <= maxDirty; minDirty++) {
314
+ let el = dirtyHeap[minDirty];
315
+ dirtyHeap[minDirty] = undefined;
316
+ while (el !== undefined) {
317
+ let next = el.nextHeap;
318
+ recompute(el, false);
319
+ el = next;
320
+ }
315
321
  }
316
- }
322
+ signal.set(state, STATE_NONE);
323
+ });
317
324
  };
318
325
  export { computed, dispose, isComputed, isReactive, isSignal, oncleanup, read, root, signal, stabilize };
package/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "private": false,
13
13
  "type": "module",
14
14
  "types": "build/index.d.ts",
15
- "version": "0.6.1",
15
+ "version": "0.7.0",
16
16
  "scripts": {
17
17
  "build": "tsc && tsc-alias",
18
18
  "-": "-"
package/src/constants.ts CHANGED
@@ -11,4 +11,11 @@ const STATE_RECOMPUTING = 1 << 2;
11
11
  const STATE_IN_HEAP = 1 << 3;
12
12
 
13
13
 
14
- export { REACTIVE, STATE_CHECK, STATE_DIRTY, STATE_IN_HEAP, STATE_NONE, STATE_RECOMPUTING };
14
+ export {
15
+ REACTIVE,
16
+ STATE_CHECK,
17
+ STATE_DIRTY,
18
+ STATE_IN_HEAP,
19
+ STATE_NONE,
20
+ STATE_RECOMPUTING
21
+ };
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { default as reactive } from './reactive';
2
2
  export { computed, dispose, oncleanup, root, signal, stabilize } from './signal';
3
+ export { default as scheduler } from './scheduler';
3
4
  export * from './types';
@@ -33,7 +33,7 @@ type Events<T> = {
33
33
  };
34
34
  };
35
35
 
36
- type Item<T> = Computed<T> | ReactiveArray<T> | ReactiveObject<T extends Record<PropertyKey, unknown> ? T : never> | T;
36
+ type Item<T> = Computed<T> | API<T> | ReactiveObject<T extends Record<PropertyKey, unknown> ? T : never> | T;
37
37
 
38
38
  type Listener<V> = {
39
39
  once?: boolean;
@@ -44,7 +44,7 @@ type Value<T> =
44
44
  T extends Record<PropertyKey, unknown>
45
45
  ? ReactiveObject<T>
46
46
  : T extends Array<infer U>
47
- ? ReactiveArray<U>
47
+ ? API<U>
48
48
  : T;
49
49
 
50
50
 
@@ -85,7 +85,7 @@ class ReactiveArray<T> extends Disposable {
85
85
  return value;
86
86
  }
87
87
 
88
- dispatch<D>(event: keyof Events<T>, value?: D) {
88
+ dispatch<K extends keyof Events<T>, V>(event: K, value?: V) {
89
89
  if (this.listeners === null || this.listeners[event] === undefined) {
90
90
  return;
91
91
  }
@@ -162,7 +162,7 @@ class ReactiveArray<T> extends Disposable {
162
162
  return values;
163
163
  }
164
164
 
165
- on<T>(event: keyof Events<T>, listener: Listener<T>) {
165
+ on<K extends keyof Events<T>>(event: K, listener: Listener<Events<T>[K]>) {
166
166
  if (this.listeners === null) {
167
167
  this.listeners = { [event]: [listener] };
168
168
  }
@@ -185,7 +185,7 @@ class ReactiveArray<T> extends Disposable {
185
185
  }
186
186
  }
187
187
 
188
- once<T>(event: keyof Events<T>, listener: Listener<T>) {
188
+ once<K extends keyof Events<T>>(event: K, listener: Listener<Events<T>[K]>) {
189
189
  listener.once = true;
190
190
  this.on(event, listener);
191
191
  }
@@ -291,7 +291,7 @@ function factory<T>(input: T[]) {
291
291
  items[i] = computed(value as Computed<T>['fn']);
292
292
  }
293
293
  else if (isObject(value)) {
294
- items[i] = object(value);
294
+ items[i] = object(value) as Item<T>;
295
295
  }
296
296
  else {
297
297
  items[i] = value;
@@ -346,4 +346,4 @@ export default function array<T>(input: T[]) {
346
346
 
347
347
  return proxy;
348
348
  };
349
- export { ReactiveArray };
349
+ export type { API as ReactiveArray };
@@ -121,4 +121,4 @@ class ReactiveObject<T extends Record<PropertyKey, unknown>> extends Disposable
121
121
  export default function object<T extends Record<PropertyKey, unknown>>(input: T) {
122
122
  return new ReactiveObject(input) as API<T>;
123
123
  };
124
- export { ReactiveObject };
124
+ export type { API as ReactiveObject };
@@ -0,0 +1,27 @@
1
+ import { STATE_DIRTY, STATE_NONE } from './constants';
2
+ import { computed, dispose, read, signal, stabilize } from './signal';
3
+ import { Computed } from './types';
4
+
5
+
6
+ let c: Computed<void> | null = null;
7
+
8
+
9
+ const scheduler = (schedule: (task: VoidFunction) => void) => {
10
+ if (c) {
11
+ dispose(c);
12
+ }
13
+
14
+ c = computed(() => {
15
+ if (read(state) !== STATE_DIRTY) {
16
+ return;
17
+ }
18
+
19
+ schedule(stabilize);
20
+ });
21
+ };
22
+
23
+ const state = signal(STATE_NONE);
24
+
25
+
26
+ export default scheduler;
27
+ export { state };
package/src/signal.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { isArray, isObject } from '@esportsplus/utilities';
2
2
  import { REACTIVE, STATE_CHECK, STATE_DIRTY, STATE_IN_HEAP, STATE_NONE, STATE_RECOMPUTING } from './constants';
3
3
  import { Computed, Link, Signal, } from './types';
4
+ import { state } from './scheduler';
4
5
 
5
6
 
6
7
  let dirtyHeap: (Computed<unknown> | undefined)[] = new Array(2000),
@@ -226,6 +227,10 @@ function recompute<T>(el: Computed<T>, del: boolean) {
226
227
  insertIntoHeap(o);
227
228
  }
228
229
  }
230
+
231
+ if (state.value === STATE_NONE) {
232
+ root(() => signal.set(state, STATE_DIRTY));
233
+ }
229
234
  }
230
235
 
231
236
  // https://github.com/stackblitz/alien-signals/blob/v2.0.3/src/system.ts#L100
@@ -421,19 +426,23 @@ signal.set = <T>(el: Signal<T>, v: T) => {
421
426
  };
422
427
 
423
428
  const stabilize = () => {
424
- for (minDirty = 0; minDirty <= maxDirty; minDirty++) {
425
- let el = dirtyHeap[minDirty];
429
+ root(() => {
430
+ for (minDirty = 0; minDirty <= maxDirty; minDirty++) {
431
+ let el = dirtyHeap[minDirty];
426
432
 
427
- dirtyHeap[minDirty] = undefined;
433
+ dirtyHeap[minDirty] = undefined;
428
434
 
429
- while (el !== undefined) {
430
- let next = el.nextHeap;
435
+ while (el !== undefined) {
436
+ let next = el.nextHeap;
431
437
 
432
- recompute(el, false);
438
+ recompute(el, false);
433
439
 
434
- el = next;
440
+ el = next;
441
+ }
435
442
  }
436
- }
443
+
444
+ signal.set(state, STATE_NONE);
445
+ });
437
446
  };
438
447
 
439
448