@esportsplus/reactivity 0.11.5 → 0.11.7

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.
@@ -1,15 +1,12 @@
1
- import { NeverAsync } from '@esportsplus/utilities';
2
1
  import array from './array.js';
3
2
  import object from './object.js';
4
3
  type API<T> = T extends Record<PropertyKey, unknown> ? ReturnType<typeof object<T>> : T extends unknown[] ? ReturnType<typeof array<T>> : never;
5
- type Input<T> = T extends unknown[] ? T : T extends {
4
+ type Input<T> = T extends {
6
5
  dispose: any;
7
6
  } | {
8
7
  signals: any;
9
8
  } ? {
10
9
  never: '[ dispose, signals ] are reserved keys';
11
- } : T extends Record<PropertyKey, unknown> ? {
12
- [K in keyof T]: T[K] extends (...args: unknown[]) => ((...args: unknown[]) => Promise<unknown>) ? T[K] : T[K] extends (...args: unknown[]) => unknown ? NeverAsync<T[K]> : T[K];
13
- } : never;
10
+ } : T extends Record<PropertyKey, unknown> | unknown[] ? T : never;
14
11
  declare const _default: <T>(input: Input<T>) => API<T>;
15
12
  export default _default;
@@ -1,6 +1,6 @@
1
- import { defineProperty, isArray, isAsyncFunction, isFunction, isInstanceOf } from '@esportsplus/utilities';
1
+ import { defineProperty, isArray, isFunction, isInstanceOf, isPromise } from '@esportsplus/utilities';
2
2
  import array from './array.js';
3
- import { computed, dispose, effect, read, signal } from '../system.js';
3
+ import { computed, dispose, effect, read, root, signal } from '../system.js';
4
4
  import { Disposable } from './disposable.js';
5
5
  let { set } = signal;
6
6
  class ReactiveObject extends Disposable {
@@ -30,20 +30,22 @@ class ReactiveObject extends Disposable {
30
30
  enumerable: true,
31
31
  get() {
32
32
  if (c === undefined) {
33
- c = disposable[key] = computed(value);
34
- if (isAsyncFunction(c.value)) {
35
- let factory = c, version = 0;
36
- c = signal(null);
37
- effect(() => {
38
- let id = version++;
39
- read(factory)().then((value) => {
40
- if (id !== version) {
41
- return;
42
- }
43
- set(c, value);
33
+ root(() => {
34
+ c = disposable[key] = computed(value);
35
+ if (isPromise(c.value)) {
36
+ let factory = c, version = 0;
37
+ c = signal(undefined);
38
+ effect(() => {
39
+ let id = ++version;
40
+ read(factory).then((value) => {
41
+ if (id !== version) {
42
+ return;
43
+ }
44
+ set(c, value);
45
+ });
44
46
  });
45
- });
46
- }
47
+ }
48
+ });
47
49
  }
48
50
  return read(c);
49
51
  }
package/build/system.js CHANGED
@@ -58,12 +58,9 @@ function insertIntoHeap(computed) {
58
58
  if (height > length) {
59
59
  length = height;
60
60
  if (height >= heap.length) {
61
- heap.length += 250;
61
+ heap.length *= 1.5;
62
62
  }
63
63
  }
64
- if (stabilizer === STABILIZER_RUNNING && index > height) {
65
- stabilizer = STABILIZER_RESCHEDULE;
66
- }
67
64
  }
68
65
  function link(dep, sub) {
69
66
  let prevDep = sub.depsTail;
@@ -138,6 +135,7 @@ function recompute(computed, del) {
138
135
  catch (e) {
139
136
  ok = false;
140
137
  }
138
+ depth--;
141
139
  observer = o;
142
140
  computed.state = STATE_NONE;
143
141
  let depsTail = computed.depsTail, toRemove = depsTail !== null ? depsTail.nextDep : computed.deps;
@@ -161,11 +159,17 @@ function recompute(computed, del) {
161
159
  }
162
160
  insertIntoHeap(o);
163
161
  }
162
+ schedule();
164
163
  }
165
- if (!--depth && stabilizer === STABILIZER_IDLE) {
164
+ }
165
+ function schedule() {
166
+ if (stabilizer === STABILIZER_IDLE && !depth) {
166
167
  stabilizer = STABILIZER_SCHEDULED;
167
168
  scheduler(stabilize);
168
169
  }
170
+ else if (stabilizer === STABILIZER_RUNNING) {
171
+ stabilizer = STABILIZER_RESCHEDULE;
172
+ }
169
173
  }
170
174
  function stabilize() {
171
175
  root(() => {
@@ -247,6 +251,7 @@ const computed = (fn) => {
247
251
  else {
248
252
  self.height = observer.height + 1;
249
253
  insertIntoHeap(self);
254
+ schedule();
250
255
  }
251
256
  link(self, observer);
252
257
  }
@@ -337,8 +342,12 @@ signal.set = (signal, value) => {
337
342
  }
338
343
  notified = false;
339
344
  signal.value = value;
345
+ if (signal.subs === null) {
346
+ return;
347
+ }
340
348
  for (let link = signal.subs; link !== null; link = link.nextSub) {
341
349
  insertIntoHeap(link.sub);
342
350
  }
351
+ schedule();
343
352
  };
344
353
  export { computed, dispose, effect, isComputed, isSignal, onCleanup, read, root, signal };
package/build/types.d.ts CHANGED
@@ -13,7 +13,7 @@ interface Computed<T> extends Signal<T> {
13
13
  prevHeap: Computed<unknown>;
14
14
  state: typeof STATE_CHECK | typeof STATE_DIRTY | typeof STATE_IN_HEAP | typeof STATE_NONE | typeof STATE_RECOMPUTING;
15
15
  }
16
- type Infer<T> = T extends (...args: unknown[]) => ((...args: unknown[]) => Promise<infer R>) ? R : T extends (...args: any[]) => infer R ? R | null : T extends (infer U)[] ? ReactiveArray<U> : T extends ReactiveObject<any> ? T : T extends Record<PropertyKey, unknown> ? {
16
+ type Infer<T> = T extends (...args: unknown[]) => Promise<infer R> ? R | undefined : T extends (...args: any[]) => infer R ? R : T extends (infer U)[] ? ReactiveArray<U> : T extends ReactiveObject<any> ? T : T extends Record<PropertyKey, unknown> ? {
17
17
  [K in keyof T]: T[K];
18
18
  } : T;
19
19
  interface Link {
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.11.5",
15
+ "version": "0.11.7",
16
16
  "scripts": {
17
17
  "build": "tsc && tsc-alias",
18
18
  "-": "-"
@@ -1,4 +1,4 @@
1
- import { isArray, isObject, NeverAsync } from '@esportsplus/utilities';
1
+ import { isArray, isObject } from '@esportsplus/utilities';
2
2
  import array from './array';
3
3
  import object from './object';
4
4
 
@@ -11,20 +11,11 @@ type API<T> =
11
11
  : never;
12
12
 
13
13
  type Input<T> =
14
- T extends unknown[]
15
- ? T
16
- : T extends { dispose: any } | { signals: any }
17
- ? { never: '[ dispose, signals ] are reserved keys' }
18
- : T extends Record<PropertyKey, unknown>
19
- ? {
20
- [K in keyof T]:
21
- T[K] extends (...args: unknown[]) => ((...args: unknown[]) => Promise<unknown>)
22
- ? T[K]
23
- : T[K] extends (...args: unknown[]) => unknown
24
- ? NeverAsync<T[K]>
25
- : T[K]
26
- }
27
- : never;
14
+ T extends { dispose: any } | { signals: any }
15
+ ? { never: '[ dispose, signals ] are reserved keys' }
16
+ : T extends Record<PropertyKey, unknown> | unknown[]
17
+ ? T
18
+ : never;
28
19
 
29
20
 
30
21
  export default <T>(input: Input<T>): API<T> => {
@@ -1,6 +1,6 @@
1
- import { defineProperty, isArray, isAsyncFunction, isFunction, isInstanceOf, Prettify } from '@esportsplus/utilities';
1
+ import { defineProperty, isArray, isFunction, isInstanceOf, isPromise, Prettify } from '@esportsplus/utilities';
2
2
  import array, { ReactiveArray } from './array';
3
- import { computed, dispose, effect, read, signal } from '~/system';
3
+ import { computed, dispose, effect, read, root, signal } from '~/system';
4
4
  import { Computed, Infer, Signal } from '~/types';
5
5
  import { Disposable } from './disposable';
6
6
 
@@ -44,35 +44,37 @@ class ReactiveObject<T extends Record<PropertyKey, unknown>> extends Disposable
44
44
  });
45
45
  }
46
46
  else if (isFunction(value)) {
47
- let c: Computed<T[typeof key]> | Signal<T[typeof key] | null> | undefined;
47
+ let c: Computed<T[typeof key]> | Signal<T[typeof key] | undefined> | undefined;
48
48
 
49
49
  defineProperty(this, key, {
50
50
  enumerable: true,
51
51
  get() {
52
52
  if (c === undefined) {
53
- c = disposable[key] = computed(value as Computed<T[typeof key]>['fn']);
53
+ root(() => {
54
+ c = disposable[key] = computed(value as Computed<T[typeof key]>['fn']);
54
55
 
55
- if (isAsyncFunction(c.value)) {
56
- let factory = c,
57
- version = 0;
56
+ if (isPromise(c.value)) {
57
+ let factory = c,
58
+ version = 0;
58
59
 
59
- c = signal(null);
60
+ c = signal(undefined);
60
61
 
61
- effect(() => {
62
- let id = version++;
62
+ effect(() => {
63
+ let id = ++version;
63
64
 
64
- (read(factory) as any as () => Promise<T[typeof key]>)().then((value) => {
65
- if (id !== version) {
66
- return;
67
- }
65
+ (read(factory) as Promise<T[typeof key]>).then((value) => {
66
+ if (id !== version) {
67
+ return;
68
+ }
68
69
 
69
- set(c!, value);
70
+ set(c!, value);
71
+ });
70
72
  });
71
- });
72
- }
73
+ }
74
+ });
73
75
  }
74
76
 
75
- return read(c);
77
+ return read(c!);
76
78
  }
77
79
  });
78
80
  }
package/src/system.ts CHANGED
@@ -98,13 +98,9 @@ function insertIntoHeap<T>(computed: Computed<T>) {
98
98
 
99
99
  // Simple auto adjust to avoid manual management within apps.
100
100
  if (height >= heap.length) {
101
- heap.length += 250;
101
+ heap.length *= 1.5;
102
102
  }
103
103
  }
104
-
105
- if (stabilizer === STABILIZER_RUNNING && index > height) {
106
- stabilizer = STABILIZER_RESCHEDULE;
107
- }
108
104
  }
109
105
 
110
106
  // https://github.com/stackblitz/alien-signals/blob/v2.0.3/src/system.ts#L52
@@ -207,6 +203,7 @@ function recompute<T>(computed: Computed<T>, del: boolean) {
207
203
  ok = false;
208
204
  }
209
205
 
206
+ depth--;
210
207
  observer = o;
211
208
  computed.state = STATE_NONE;
212
209
 
@@ -240,12 +237,19 @@ function recompute<T>(computed: Computed<T>, del: boolean) {
240
237
 
241
238
  insertIntoHeap(o);
242
239
  }
240
+
241
+ schedule();
243
242
  }
243
+ }
244
244
 
245
- if (!--depth && stabilizer === STABILIZER_IDLE) {
245
+ function schedule() {
246
+ if (stabilizer === STABILIZER_IDLE && !depth) {
246
247
  stabilizer = STABILIZER_SCHEDULED;
247
248
  scheduler(stabilize);
248
249
  }
250
+ else if (stabilizer === STABILIZER_RUNNING) {
251
+ stabilizer = STABILIZER_RESCHEDULE;
252
+ }
249
253
  }
250
254
 
251
255
  function stabilize() {
@@ -349,6 +353,7 @@ const computed = <T>(fn: Computed<T>['fn']): Computed<T> => {
349
353
  else {
350
354
  self.height = observer.height + 1;
351
355
  insertIntoHeap(self);
356
+ schedule();
352
357
  }
353
358
 
354
359
  link(self, observer);
@@ -472,9 +477,15 @@ signal.set = <T>(signal: Signal<T>, value: T) => {
472
477
  notified = false;
473
478
  signal.value = value;
474
479
 
475
- for (let link = signal.subs; link !== null; link = link.nextSub) {
480
+ if (signal.subs === null) {
481
+ return;
482
+ }
483
+
484
+ for (let link: Link | null = signal.subs; link !== null; link = link.nextSub) {
476
485
  insertIntoHeap(link.sub);
477
486
  }
487
+
488
+ schedule();
478
489
  };
479
490
 
480
491
 
package/src/types.ts CHANGED
@@ -22,10 +22,10 @@ interface Computed<T> extends Signal<T> {
22
22
  }
23
23
 
24
24
  type Infer<T> =
25
- T extends (...args: unknown[]) => ((...args: unknown[]) => Promise<infer R>)
26
- ? R
25
+ T extends (...args: unknown[]) => Promise<infer R>
26
+ ? R | undefined
27
27
  : T extends (...args: any[]) => infer R
28
- ? R | null
28
+ ? R
29
29
  : T extends (infer U)[]
30
30
  ? ReactiveArray<U>
31
31
  : T extends ReactiveObject<any>