@esportsplus/reactivity 0.11.2 → 0.11.3

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.
@@ -2,12 +2,14 @@ import { NeverAsync } from '@esportsplus/utilities';
2
2
  import array from './array.js';
3
3
  import object from './object.js';
4
4
  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 (...args: unknown[]) => unknown ? NeverAsync<T> : T extends {
5
+ type Input<T> = T extends unknown[] ? T : T extends {
6
6
  dispose: any;
7
7
  } | {
8
8
  signals: any;
9
9
  } ? {
10
10
  never: '[ dispose, signals ] are reserved keys';
11
- } : T extends Record<PropertyKey, unknown> | unknown[] ? T : never;
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;
12
14
  declare const _default: <T>(input: Input<T>) => API<T>;
13
15
  export default _default;
@@ -1,6 +1,6 @@
1
- import { defineProperty, isArray, isFunction, isInstanceOf } from '@esportsplus/utilities';
1
+ import { defineProperty, isArray, isAsyncFunction, isFunction, isInstanceOf } from '@esportsplus/utilities';
2
2
  import array from './array.js';
3
- import { computed, dispose, read, signal } from '../system.js';
3
+ import { computed, dispose, effect, read, signal } from '../system.js';
4
4
  import { Disposable } from './disposable.js';
5
5
  let { set } = signal;
6
6
  class ReactiveObject extends Disposable {
@@ -31,6 +31,19 @@ class ReactiveObject extends Disposable {
31
31
  get() {
32
32
  if (c === undefined) {
33
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);
44
+ });
45
+ });
46
+ }
34
47
  }
35
48
  return read(c);
36
49
  }
package/build/system.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { isArray, isObject } from '@esportsplus/utilities';
2
- import { REACTIVE, STABILIZER_IDLE, STABILIZER_RUNNING, STABILIZER_SCHEDULED, STATE_CHECK, STATE_DIRTY, STATE_IN_HEAP, STATE_NONE, STATE_RECOMPUTING } from './constants.js';
2
+ import { REACTIVE, 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(2000), index = 0, length = 0, notified = false, observer = null, scheduler = queueMicrotask, stabilizer = STABILIZER_IDLE, version = 0;
4
4
  function cleanup(node) {
5
5
  if (!node.cleanup) {
@@ -62,7 +62,7 @@ function insertIntoHeap(computed) {
62
62
  }
63
63
  }
64
64
  if (stabilizer === STABILIZER_RUNNING && index > height) {
65
- stabilizer = STABILIZER_SCHEDULED;
65
+ stabilizer = STABILIZER_RESCHEDULE;
66
66
  }
67
67
  }
68
68
  function link(dep, sub) {
@@ -179,7 +179,7 @@ function stabilize() {
179
179
  computed = next;
180
180
  }
181
181
  }
182
- if (stabilizer === STABILIZER_SCHEDULED) {
182
+ if (stabilizer === STABILIZER_RESCHEDULE) {
183
183
  scheduler(stabilize);
184
184
  }
185
185
  else {
package/build/types.d.ts CHANGED
@@ -2,19 +2,18 @@ import { REACTIVE, STATE_CHECK, STATE_DIRTY, STATE_IN_HEAP, STATE_NONE, STATE_RE
2
2
  import { onCleanup } from './system.js';
3
3
  import { ReactiveArray } from './reactive/array.js';
4
4
  import { ReactiveObject } from './reactive/object.js';
5
- import { NeverAsync } from '@esportsplus/utilities';
6
5
  interface Computed<T> extends Signal<T> {
7
6
  [REACTIVE]: true;
8
7
  cleanup: VoidFunction | VoidFunction[] | null;
9
8
  deps: Link | null;
10
9
  depsTail: Link | null;
11
- fn: NeverAsync<(oc?: typeof onCleanup) => T>;
10
+ fn: (oc?: typeof onCleanup) => T;
12
11
  height: number;
13
12
  nextHeap: Computed<unknown> | undefined;
14
13
  prevHeap: Computed<unknown>;
15
14
  state: typeof STATE_CHECK | typeof STATE_DIRTY | typeof STATE_IN_HEAP | typeof STATE_NONE | typeof STATE_RECOMPUTING;
16
15
  }
17
- type Infer<T> = T extends (...args: unknown[]) => unknown ? ReturnType<T> : T extends (infer U)[] ? ReactiveArray<U> : T extends ReactiveObject<any> ? T : T extends Record<PropertyKey, unknown> ? {
16
+ type Infer<T> = T extends (...args: unknown[]) => ((...args: unknown[]) => Promise<infer R>) ? R : T extends (...args: any[]) => infer R ? R : T extends (infer U)[] ? ReactiveArray<U> : T extends ReactiveObject<any> ? T : T extends Record<PropertyKey, unknown> ? {
18
17
  [K in keyof T]: T[K];
19
18
  } : T;
20
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.2",
15
+ "version": "0.11.3",
16
16
  "scripts": {
17
17
  "build": "tsc && tsc-alias",
18
18
  "-": "-"
@@ -11,13 +11,20 @@ type API<T> =
11
11
  : never;
12
12
 
13
13
  type Input<T> =
14
- T extends (...args: unknown[]) => unknown
15
- ? NeverAsync<T>
14
+ T extends unknown[]
15
+ ? T
16
16
  : T extends { dispose: any } | { signals: any }
17
17
  ? { never: '[ dispose, signals ] are reserved keys' }
18
- : T extends Record<PropertyKey, unknown> | unknown[]
19
- ? T
20
- : never;
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;
21
28
 
22
29
 
23
30
  export default <T>(input: Input<T>): API<T> => {
@@ -1,6 +1,6 @@
1
- import { defineProperty, isArray, isFunction, isInstanceOf, Prettify } from '@esportsplus/utilities';
1
+ import { defineProperty, isArray, isAsyncFunction, isFunction, isInstanceOf, Prettify } from '@esportsplus/utilities';
2
2
  import array, { ReactiveArray } from './array';
3
- import { computed, dispose, read, signal } from '~/system';
3
+ import { computed, dispose, effect, read, signal } from '~/system';
4
4
  import { Computed, Infer, Signal } from '~/types';
5
5
  import { Disposable } from './disposable';
6
6
 
@@ -44,13 +44,32 @@ class ReactiveObject<T extends Record<PropertyKey, unknown>> extends Disposable
44
44
  });
45
45
  }
46
46
  else if (isFunction(value)) {
47
- let c: Computed<T> | undefined;
47
+ let c: Computed<T[typeof key]> | Signal<T[typeof key] | null> | 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>['fn']);
53
+ c = disposable[key] = computed(value as Computed<T[typeof key]>['fn']);
54
+
55
+ if (isAsyncFunction(c.value)) {
56
+ let factory = c,
57
+ version = 0;
58
+
59
+ c = signal(null);
60
+
61
+ effect(() => {
62
+ let id = version++;
63
+
64
+ (read(factory) as any as () => Promise<T[typeof key]>)().then((value) => {
65
+ if (id !== version) {
66
+ return;
67
+ }
68
+
69
+ set(c!, value);
70
+ });
71
+ });
72
+ }
54
73
  }
55
74
 
56
75
  return read(c);
@@ -63,7 +82,7 @@ class ReactiveObject<T extends Record<PropertyKey, unknown>> extends Disposable
63
82
  defineProperty(this, key, {
64
83
  enumerable: true,
65
84
  get() {
66
- return read(s as Signal<typeof value>);
85
+ return read(s);
67
86
  },
68
87
  set(v: typeof value) {
69
88
  set(s, v);
package/src/system.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { isArray, isObject } from '@esportsplus/utilities';
2
2
  import {
3
3
  REACTIVE,
4
- STABILIZER_IDLE, STABILIZER_RUNNING, STABILIZER_SCHEDULED,
4
+ STABILIZER_IDLE, STABILIZER_RESCHEDULE, STABILIZER_RUNNING, STABILIZER_SCHEDULED,
5
5
  STATE_CHECK, STATE_DIRTY, STATE_IN_HEAP, STATE_NONE, STATE_RECOMPUTING
6
6
  } from './constants';
7
7
  import { Computed, Link, Signal, } from './types';
@@ -103,7 +103,7 @@ function insertIntoHeap<T>(computed: Computed<T>) {
103
103
  }
104
104
 
105
105
  if (stabilizer === STABILIZER_RUNNING && index > height) {
106
- stabilizer = STABILIZER_SCHEDULED;
106
+ stabilizer = STABILIZER_RESCHEDULE;
107
107
  }
108
108
  }
109
109
 
@@ -266,7 +266,7 @@ function stabilize() {
266
266
  }
267
267
  }
268
268
 
269
- if (stabilizer === STABILIZER_SCHEDULED) {
269
+ if (stabilizer === STABILIZER_RESCHEDULE) {
270
270
  scheduler(stabilize);
271
271
  }
272
272
  else {
package/src/types.ts CHANGED
@@ -2,7 +2,6 @@ import { REACTIVE, STATE_CHECK, STATE_DIRTY, STATE_IN_HEAP, STATE_NONE, STATE_RE
2
2
  import { onCleanup } from './system';
3
3
  import { ReactiveArray } from './reactive/array';
4
4
  import { ReactiveObject } from './reactive/object';
5
- import { NeverAsync } from '@esportsplus/utilities';
6
5
 
7
6
 
8
7
  interface Computed<T> extends Signal<T> {
@@ -10,7 +9,7 @@ interface Computed<T> extends Signal<T> {
10
9
  cleanup: VoidFunction | VoidFunction[] | null;
11
10
  deps: Link | null;
12
11
  depsTail: Link | null;
13
- fn: NeverAsync<(oc?: typeof onCleanup) => T>;
12
+ fn: (oc?: typeof onCleanup) => T;
14
13
  height: number;
15
14
  nextHeap: Computed<unknown> | undefined;
16
15
  prevHeap: Computed<unknown>;
@@ -23,15 +22,17 @@ interface Computed<T> extends Signal<T> {
23
22
  }
24
23
 
25
24
  type Infer<T> =
26
- T extends (...args: unknown[]) => unknown
27
- ? ReturnType<T>
28
- : T extends (infer U)[]
29
- ? ReactiveArray<U>
30
- : T extends ReactiveObject<any>
31
- ? T
32
- : T extends Record<PropertyKey, unknown>
33
- ? { [K in keyof T]: T[K] }
34
- : T;
25
+ T extends (...args: unknown[]) => ((...args: unknown[]) => Promise<infer R>)
26
+ ? R
27
+ : T extends (...args: any[]) => infer R
28
+ ? R
29
+ : T extends (infer U)[]
30
+ ? ReactiveArray<U>
31
+ : T extends ReactiveObject<any>
32
+ ? T
33
+ : T extends Record<PropertyKey, unknown>
34
+ ? { [K in keyof T]: T[K] }
35
+ : T;
35
36
 
36
37
  interface Link {
37
38
  dep: Signal<unknown> | Computed<unknown>;