@esportsplus/reactivity 0.16.7 → 0.17.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.
@@ -1,24 +1,8 @@
1
- import { defineProperty, isArray, isFunction, isObject, isPromise, Prettify } from '@esportsplus/utilities';
1
+ import { defineProperty, isArray, isObject, isPromise } from '@esportsplus/utilities';
2
2
  import { computed, dispose, effect, read, root, set, signal } from '~/system';
3
3
  import { Computed, Signal } from '~/types';
4
4
  import { REACTIVE_OBJECT } from '~/constants';
5
- import array, { ReactiveArray } from './array';
6
-
7
-
8
- type API<T> = Prettify<{ [K in keyof T]: Infer<T[K]> } & { dispose: VoidFunction } >;
9
-
10
- type Infer<T> =
11
- T extends (...args: unknown[]) => Promise<infer R>
12
- ? R | undefined
13
- : T extends (...args: any[]) => infer R
14
- ? R
15
- : T extends (infer U)[]
16
- ? ReactiveArray<U>
17
- : T extends ReactiveObject<any>
18
- ? T
19
- : T extends Record<PropertyKey, unknown>
20
- ? { [K in keyof T]: T[K] }
21
- : T;
5
+ import { ReactiveArray } from './array';
22
6
 
23
7
 
24
8
  class ReactiveObject<T extends Record<PropertyKey, unknown>> {
@@ -35,17 +19,9 @@ class ReactiveObject<T extends Record<PropertyKey, unknown>> {
35
19
  let key = keys[i],
36
20
  value = data[key];
37
21
 
38
- if (isArray(value)) {
39
- let node = array(value);
40
-
41
- (this.disposers ??= []).push( () => node.dispose() );
22
+ let type = typeof value;
42
23
 
43
- defineProperty(this, key, {
44
- enumerable: true,
45
- value: node
46
- });
47
- }
48
- else if (isFunction(value)) {
24
+ if (type === 'function') {
49
25
  let node: Computed<T[typeof key]> | Signal<T[typeof key] | undefined> | undefined;
50
26
 
51
27
  defineProperty(this, key, {
@@ -84,20 +60,37 @@ class ReactiveObject<T extends Record<PropertyKey, unknown>> {
84
60
  return read(node!);
85
61
  }
86
62
  });
63
+
64
+ continue;
65
+ }
66
+
67
+ if (value == null || type !== 'object') {
68
+ // Avoid isArray when possible
87
69
  }
88
- else {
89
- let node = signal(value);
70
+ else if (isArray(value)) {
71
+ let node = new ReactiveArray(value);
72
+
73
+ (this.disposers ??= []).push( () => node.dispose() );
90
74
 
91
75
  defineProperty(this, key, {
92
76
  enumerable: true,
93
- get() {
94
- return read(node);
95
- },
96
- set(v: typeof value) {
97
- set(node, v);
98
- }
77
+ value: node
99
78
  });
79
+
80
+ continue;
100
81
  }
82
+
83
+ let node = signal(value);
84
+
85
+ defineProperty(this, key, {
86
+ enumerable: true,
87
+ get() {
88
+ return read(node);
89
+ },
90
+ set(v: typeof value) {
91
+ set(node, v);
92
+ }
93
+ });
101
94
  }
102
95
  }
103
96
 
@@ -122,8 +115,4 @@ const isReactiveObject = (value: any): value is ReactiveObject<any> => {
122
115
  };
123
116
 
124
117
 
125
- export default <T extends Record<PropertyKey, unknown>>(input: T) => {
126
- return new ReactiveObject<T>(input) as API<T>;
127
- };
128
- export { isReactiveObject };
129
- export type { API as ReactiveObject };
118
+ export { isReactiveObject, ReactiveObject };
package/src/system.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { isArray, isObject } from '@esportsplus/utilities';
1
+ import { isObject } from '@esportsplus/utilities';
2
2
  import {
3
3
  COMPUTED, SIGNAL,
4
4
  STABILIZER_IDLE, STABILIZER_RESCHEDULE, STABILIZER_RUNNING, STABILIZER_SCHEDULED,
@@ -26,14 +26,14 @@ function cleanup<T>(computed: Computed<T>): void {
26
26
 
27
27
  let value = computed.cleanup;
28
28
 
29
- if (isArray(value)) {
29
+ if (typeof value === 'function') {
30
+ value();
31
+ }
32
+ else {
30
33
  for (let i = 0, n = value.length; i < n; i++) {
31
34
  value[i]();
32
35
  }
33
36
  }
34
- else {
35
- value();
36
- }
37
37
 
38
38
  computed.cleanup = null;
39
39
  }
@@ -108,16 +108,16 @@ function insertIntoHeap<T>(computed: Computed<T>) {
108
108
  function link<T>(dep: Signal<T> | Computed<T>, sub: Computed<T>) {
109
109
  let prevDep = sub.depsTail;
110
110
 
111
- if (prevDep !== null && prevDep.dep === dep) {
111
+ if (prevDep && prevDep.dep === dep) {
112
112
  return;
113
113
  }
114
114
 
115
115
  let nextDep: Link | null = null;
116
116
 
117
117
  if (sub.state & STATE_RECOMPUTING) {
118
- nextDep = prevDep !== null ? prevDep.nextDep : sub.deps;
118
+ nextDep = prevDep ? prevDep.nextDep : sub.deps;
119
119
 
120
- if (nextDep !== null && nextDep.dep === dep) {
120
+ if (nextDep && nextDep.dep === dep) {
121
121
  nextDep.version = version;
122
122
  sub.depsTail = nextDep;
123
123
  return;
@@ -128,7 +128,7 @@ function link<T>(dep: Signal<T> | Computed<T>, sub: Computed<T>) {
128
128
 
129
129
  // https://github.com/stackblitz/alien-signals/commit/54fe1b3947fac5c0aecb73b0b0eaff000806c454
130
130
  if (
131
- prevSub !== null &&
131
+ prevSub &&
132
132
  prevSub.version === version &&
133
133
  prevSub.sub === sub
134
134
  ) {
@@ -146,14 +146,14 @@ function link<T>(dep: Signal<T> | Computed<T>, sub: Computed<T>) {
146
146
  version
147
147
  };
148
148
 
149
- if (prevDep !== null) {
149
+ if (prevDep) {
150
150
  prevDep.nextDep = newLink;
151
151
  }
152
152
  else {
153
153
  sub.deps = newLink;
154
154
  }
155
155
 
156
- if (prevSub !== null) {
156
+ if (prevSub) {
157
157
  prevSub.nextSub = newLink;
158
158
  }
159
159
  else {
@@ -170,7 +170,7 @@ function notify<T>(computed: Computed<T>, newState = STATE_DIRTY) {
170
170
 
171
171
  computed.state = state | newState;
172
172
 
173
- for (let link = computed.subs; link !== null; link = link.nextSub) {
173
+ for (let link = computed.subs; link; link = link.nextSub) {
174
174
  notify(link.sub, STATE_CHECK);
175
175
  }
176
176
  }
@@ -211,15 +211,15 @@ function recompute<T>(computed: Computed<T>, del: boolean) {
211
211
  computed.state = STATE_NONE;
212
212
 
213
213
  let depsTail = computed.depsTail as Link | null,
214
- remove = depsTail !== null ? depsTail.nextDep : computed.deps;
214
+ remove = depsTail ? depsTail.nextDep : computed.deps;
215
215
 
216
- if (remove !== null) {
216
+ if (remove) {
217
217
  do {
218
218
  remove = unlink(remove);
219
219
  }
220
- while (remove !== null);
220
+ while (remove);
221
221
 
222
- if (depsTail !== null) {
222
+ if (depsTail) {
223
223
  depsTail.nextDep = null;
224
224
  }
225
225
  else {
@@ -230,7 +230,7 @@ function recompute<T>(computed: Computed<T>, del: boolean) {
230
230
  if (ok && value !== computed.value) {
231
231
  computed.value = value as T;
232
232
 
233
- for (let c = computed.subs; c !== null; c = c.nextSub) {
233
+ for (let c = computed.subs; c; c = c.nextSub) {
234
234
  let s = c.sub,
235
235
  state = s.state;
236
236
 
@@ -246,6 +246,10 @@ function recompute<T>(computed: Computed<T>, del: boolean) {
246
246
  }
247
247
 
248
248
  function schedule() {
249
+ if (stabilizer === STABILIZER_SCHEDULED) {
250
+ return;
251
+ }
252
+
249
253
  if (stabilizer === STABILIZER_IDLE && !depth) {
250
254
  stabilizer = STABILIZER_SCHEDULED;
251
255
  microtask(stabilize);
@@ -296,14 +300,14 @@ function unlink(link: Link): Link | null {
296
300
  nextSub = link.nextSub,
297
301
  prevSub = link.prevSub;
298
302
 
299
- if (nextSub !== null) {
303
+ if (nextSub) {
300
304
  nextSub.prevSub = prevSub;
301
305
  }
302
306
  else {
303
307
  dep.subsTail = prevSub;
304
308
  }
305
309
 
306
- if (prevSub !== null) {
310
+ if (prevSub) {
307
311
  prevSub.nextSub = nextSub;
308
312
  }
309
313
  else if ((dep.subs = nextSub) === null && 'fn' in dep) {
@@ -385,7 +389,7 @@ const dispose = <T>(computed: Computed<T>) => {
385
389
 
386
390
  let dep = computed.deps;
387
391
 
388
- while (dep !== null) {
392
+ while (dep) {
389
393
  dep = unlink(dep);
390
394
  }
391
395
 
@@ -424,11 +428,11 @@ const onCleanup = (fn: VoidFunction): typeof fn => {
424
428
  if (!cleanup) {
425
429
  parent.cleanup = fn;
426
430
  }
427
- else if (isArray(cleanup)) {
428
- cleanup.push(fn);
431
+ else if (typeof cleanup === 'function') {
432
+ parent.cleanup = [cleanup, fn];
429
433
  }
430
434
  else {
431
- parent.cleanup = [cleanup, fn];
435
+ cleanup.push(fn);
432
436
  }
433
437
 
434
438
  return fn;
@@ -510,7 +514,7 @@ const set = <T>(signal: Signal<T>, value: T) => {
510
514
  return;
511
515
  }
512
516
 
513
- for (let link: Link | null = signal.subs; link !== null; link = link.nextSub) {
517
+ for (let link: Link | null = signal.subs; link; link = link.nextSub) {
514
518
  insertIntoHeap(link.sub);
515
519
  }
516
520