@esportsplus/reactivity 0.20.0 → 0.20.2

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,7 +1,7 @@
1
- const COMPUTED = Symbol('computed');
2
- const REACTIVE_ARRAY = Symbol('reactive.array');
3
- const REACTIVE_OBJECT = Symbol('reactive.object');
4
- const SIGNAL = Symbol('signal');
1
+ const COMPUTED = Symbol('reactivity.computed');
2
+ const REACTIVE_ARRAY = Symbol('reactivity.reactive.array');
3
+ const REACTIVE_OBJECT = Symbol('reactivity.reactive.object');
4
+ const SIGNAL = Symbol('reactivity.signal');
5
5
  const STABILIZER_IDLE = 0;
6
6
  const STABILIZER_RESCHEDULE = 1;
7
7
  const STABILIZER_RUNNING = 2;
@@ -1,4 +1,3 @@
1
- import { REACTIVE_ARRAY } from '../constants.js';
2
1
  type Events<T> = {
3
2
  clear: undefined;
4
3
  concat: {
@@ -34,7 +33,6 @@ type Listener<V> = {
34
33
  };
35
34
  type Listeners = Record<string, (Listener<any> | null)[]>;
36
35
  declare class ReactiveArray<T> extends Array<T> {
37
- [REACTIVE_ARRAY]: boolean;
38
36
  listeners: Listeners;
39
37
  constructor(...items: T[]);
40
38
  clear(): void;
@@ -48,7 +46,7 @@ declare class ReactiveArray<T> extends Array<T> {
48
46
  push(...items: T[]): number;
49
47
  reverse(): this;
50
48
  shift(): T | undefined;
51
- sort(fn: (a: T, b: T) => number): this;
49
+ sort(fn?: (a: T, b: T) => number): this;
52
50
  splice(start: number, deleteCount?: number, ...items: T[]): T[];
53
51
  unshift(...items: T[]): number;
54
52
  }
@@ -2,7 +2,6 @@ import { isArray } from '@esportsplus/utilities';
2
2
  import { REACTIVE_ARRAY } from '../constants.js';
3
3
  import { isReactiveObject } from './object.js';
4
4
  class ReactiveArray extends Array {
5
- [REACTIVE_ARRAY] = true;
6
5
  listeners = {};
7
6
  constructor(...items) {
8
7
  super(...items);
@@ -18,14 +17,15 @@ class ReactiveArray extends Array {
18
17
  if (isArray(item)) {
19
18
  for (let j = 0, o = item.length; j < o; j++) {
20
19
  added.push(item[j]);
20
+ super.push(item[j]);
21
21
  }
22
22
  }
23
23
  else {
24
24
  added.push(item);
25
+ super.push(item);
25
26
  }
26
27
  }
27
28
  if (added.length) {
28
- super.push(...added);
29
29
  this.dispatch('concat', { items: added });
30
30
  }
31
31
  return this;
@@ -50,10 +50,14 @@ class ReactiveArray extends Array {
50
50
  listeners[i] = null;
51
51
  }
52
52
  }
53
+ while (listeners.length && listeners[listeners.length - 1] === null) {
54
+ listeners.pop();
55
+ }
53
56
  }
54
57
  dispose() {
55
58
  let item;
56
- while (item = super.pop()) {
59
+ while (this.length) {
60
+ item = super.pop();
57
61
  if (isReactiveObject(item)) {
58
62
  item.dispose();
59
63
  }
@@ -76,6 +80,9 @@ class ReactiveArray extends Array {
76
80
  }
77
81
  }
78
82
  listeners[hole] = listener;
83
+ while (listeners.length && listeners[listeners.length - 1] === null) {
84
+ listeners.pop();
85
+ }
79
86
  }
80
87
  }
81
88
  once(event, listener) {
@@ -136,4 +143,5 @@ class ReactiveArray extends Array {
136
143
  return length;
137
144
  }
138
145
  }
146
+ Object.defineProperty(ReactiveArray.prototype, REACTIVE_ARRAY, { value: true });
139
147
  export { ReactiveArray };
@@ -1,6 +1,4 @@
1
- import { REACTIVE_OBJECT } from '../constants.js';
2
1
  declare class ReactiveObject<T extends Record<PropertyKey, unknown>> {
3
- [REACTIVE_OBJECT]: boolean;
4
2
  private disposers;
5
3
  constructor(data: T);
6
4
  dispose(): void;
@@ -3,12 +3,11 @@ import { computed, dispose, effect, read, root, set, signal } from '../system.js
3
3
  import { REACTIVE_OBJECT } from '../constants.js';
4
4
  import { ReactiveArray } from './array.js';
5
5
  class ReactiveObject {
6
- [REACTIVE_OBJECT] = true;
7
6
  disposers = null;
8
7
  constructor(data) {
9
- let keys = Object.keys(data), key;
10
- while (key = keys.pop()) {
11
- let value = data[key], type = typeof value;
8
+ let keys = Object.keys(data);
9
+ for (let i = 0, n = keys.length; i < n; ++i) {
10
+ let key = keys[i], value = data[key], type = typeof value;
12
11
  if (type === 'function') {
13
12
  let node;
14
13
  defineProperty(this, key, {
@@ -73,7 +72,8 @@ class ReactiveObject {
73
72
  }
74
73
  }
75
74
  }
75
+ Object.defineProperty(ReactiveObject.prototype, REACTIVE_OBJECT, { value: true });
76
76
  const isReactiveObject = (value) => {
77
- return typeof value === 'object' && value !== null && REACTIVE_OBJECT in value;
77
+ return typeof value === 'object' && value !== null && value[REACTIVE_OBJECT] === true;
78
78
  };
79
79
  export { isReactiveObject, ReactiveObject };
package/build/system.js CHANGED
@@ -219,7 +219,7 @@ function unlink(link) {
219
219
  if (prevSub) {
220
220
  prevSub.nextSub = nextSub;
221
221
  }
222
- else if ((dep.subs = nextSub) === null && 'fn' in dep) {
222
+ else if ((dep.subs = nextSub) === null && dep.type === COMPUTED) {
223
223
  dispose(dep);
224
224
  }
225
225
  if (linkPool.length < linkPoolMax) {
@@ -233,7 +233,7 @@ function update(computed) {
233
233
  if (computed.state & STATE_CHECK) {
234
234
  for (let link = computed.deps; link; link = link.nextDep) {
235
235
  let dep = link.dep;
236
- if ('fn' in dep) {
236
+ if (dep.type === COMPUTED) {
237
237
  update(dep);
238
238
  if (computed.state & STATE_DIRTY) {
239
239
  break;
@@ -248,7 +248,6 @@ function update(computed) {
248
248
  }
249
249
  const computed = (fn) => {
250
250
  let self = {
251
- [COMPUTED]: true,
252
251
  cleanup: null,
253
252
  deps: null,
254
253
  depsTail: null,
@@ -259,6 +258,7 @@ const computed = (fn) => {
259
258
  state: STATE_NONE,
260
259
  subs: null,
261
260
  subsTail: null,
261
+ type: COMPUTED,
262
262
  value: undefined,
263
263
  };
264
264
  self.prevHeap = self;
@@ -302,10 +302,10 @@ const effect = (fn) => {
302
302
  };
303
303
  };
304
304
  const isComputed = (value) => {
305
- return isObject(value) && COMPUTED in value;
305
+ return isObject(value) && value.type === COMPUTED;
306
306
  };
307
307
  const isSignal = (value) => {
308
- return isObject(value) && SIGNAL in value;
308
+ return isObject(value) && value.type === SIGNAL;
309
309
  };
310
310
  const onCleanup = (fn) => {
311
311
  let parent = observer || scope;
@@ -327,7 +327,7 @@ const onCleanup = (fn) => {
327
327
  const read = (node) => {
328
328
  if (observer) {
329
329
  link(node, observer);
330
- if ('fn' in node) {
330
+ if (node.type === COMPUTED) {
331
331
  let height = node.height;
332
332
  if (height >= observer.height) {
333
333
  observer.height = height + 1;
@@ -384,9 +384,9 @@ const set = (signal, value) => {
384
384
  };
385
385
  const signal = (value) => {
386
386
  return {
387
- [SIGNAL]: true,
388
387
  subs: null,
389
388
  subsTail: null,
389
+ type: SIGNAL,
390
390
  value,
391
391
  };
392
392
  };
package/build/types.d.ts CHANGED
@@ -2,7 +2,6 @@ import { COMPUTED, SIGNAL, STATE_CHECK, STATE_DIRTY, STATE_IN_HEAP, STATE_NONE,
2
2
  import { ReactiveArray } from './reactive/array.js';
3
3
  import { ReactiveObject } from './reactive/object.js';
4
4
  interface Computed<T> {
5
- [COMPUTED]: true;
6
5
  cleanup: VoidFunction | VoidFunction[] | null;
7
6
  deps: Link | null;
8
7
  depsTail: Link | null;
@@ -13,6 +12,7 @@ interface Computed<T> {
13
12
  state: typeof STATE_CHECK | typeof STATE_DIRTY | typeof STATE_IN_HEAP | typeof STATE_NONE | typeof STATE_RECOMPUTING;
14
13
  subs: Link | null;
15
14
  subsTail: Link | null;
15
+ type: typeof COMPUTED;
16
16
  value: T;
17
17
  }
18
18
  interface Link {
@@ -24,9 +24,9 @@ interface Link {
24
24
  version: number;
25
25
  }
26
26
  type Signal<T> = {
27
- [SIGNAL]: true;
28
27
  subs: Link | null;
29
28
  subsTail: Link | null;
29
+ type: typeof SIGNAL;
30
30
  value: T;
31
31
  };
32
32
  export type { Computed, Link, Signal, ReactiveArray, ReactiveObject };
package/build/types.js CHANGED
@@ -1 +1 @@
1
- import { COMPUTED, SIGNAL } from './constants.js';
1
+ export {};
package/package.json CHANGED
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "type": "module",
18
18
  "types": "build/index.d.ts",
19
- "version": "0.20.0",
19
+ "version": "0.20.2",
20
20
  "scripts": {
21
21
  "build": "tsc && tsc-alias",
22
22
  "-": "-"
package/src/constants.ts CHANGED
@@ -1,10 +1,10 @@
1
- const COMPUTED = Symbol('computed');
1
+ const COMPUTED = Symbol('reactivity.computed');
2
2
 
3
- const REACTIVE_ARRAY = Symbol('reactive.array');
3
+ const REACTIVE_ARRAY = Symbol('reactivity.reactive.array');
4
4
 
5
- const REACTIVE_OBJECT = Symbol('reactive.object');
5
+ const REACTIVE_OBJECT = Symbol('reactivity.reactive.object');
6
6
 
7
- const SIGNAL = Symbol('signal');
7
+ const SIGNAL = Symbol('reactivity.signal');
8
8
 
9
9
 
10
10
  const STABILIZER_IDLE = 0;
@@ -42,7 +42,6 @@ type Listeners = Record<string, (Listener<any> | null)[]>;
42
42
 
43
43
 
44
44
  class ReactiveArray<T> extends Array<T> {
45
- [REACTIVE_ARRAY] = true;
46
45
  listeners: Listeners = {};
47
46
 
48
47
 
@@ -67,15 +66,16 @@ class ReactiveArray<T> extends Array<T> {
67
66
  if (isArray(item)) {
68
67
  for (let j = 0, o = item.length; j < o; j++) {
69
68
  added.push(item[j]);
69
+ super.push(item[j]);
70
70
  }
71
71
  }
72
72
  else {
73
73
  added.push(item as T);
74
+ super.push(item as T);
74
75
  }
75
76
  }
76
77
 
77
78
  if (added.length) {
78
- super.push(...added);
79
79
  this.dispatch('concat', { items: added });
80
80
  }
81
81
 
@@ -107,12 +107,18 @@ class ReactiveArray<T> extends Array<T> {
107
107
  listeners[i] = null;
108
108
  }
109
109
  }
110
+
111
+ while (listeners.length && listeners[listeners.length - 1] === null) {
112
+ listeners.pop();
113
+ }
110
114
  }
111
115
 
112
116
  dispose() {
113
117
  let item;
114
118
 
115
- while (item = super.pop()) {
119
+ while (this.length) {
120
+ item = super.pop();
121
+
116
122
  if (isReactiveObject(item)) {
117
123
  item.dispose();
118
124
  }
@@ -140,6 +146,10 @@ class ReactiveArray<T> extends Array<T> {
140
146
  }
141
147
 
142
148
  listeners[hole] = listener;
149
+
150
+ while (listeners.length && listeners[listeners.length - 1] === null) {
151
+ listeners.pop();
152
+ }
143
153
  }
144
154
  }
145
155
 
@@ -189,7 +199,7 @@ class ReactiveArray<T> extends Array<T> {
189
199
  return item;
190
200
  }
191
201
 
192
- sort(fn: (a: T, b: T) => number) {
202
+ sort(fn?: (a: T, b: T) => number) {
193
203
  super.sort(fn);
194
204
  this.dispatch('sort');
195
205
 
@@ -223,5 +233,7 @@ class ReactiveArray<T> extends Array<T> {
223
233
  }
224
234
  }
225
235
 
236
+ Object.defineProperty(ReactiveArray.prototype, REACTIVE_ARRAY, { value: true });
237
+
226
238
 
227
239
  export { ReactiveArray };
@@ -6,18 +6,15 @@ import { ReactiveArray } from './array';
6
6
 
7
7
 
8
8
  class ReactiveObject<T extends Record<PropertyKey, unknown>> {
9
- [REACTIVE_OBJECT] = true;
10
-
11
-
12
9
  private disposers: VoidFunction[] | null = null;
13
10
 
14
11
 
15
12
  constructor(data: T) {
16
- let keys = Object.keys(data),
17
- key: keyof T | undefined;
13
+ let keys = Object.keys(data);
18
14
 
19
- while (key = keys.pop()) {
20
- let value = data[key],
15
+ for (let i = 0, n = keys.length; i < n; ++i) {
16
+ let key: keyof T | undefined = keys[i],
17
+ value = data[key],
21
18
  type = typeof value;
22
19
 
23
20
  if (type === 'function') {
@@ -108,9 +105,11 @@ class ReactiveObject<T extends Record<PropertyKey, unknown>> {
108
105
  }
109
106
  }
110
107
 
108
+ Object.defineProperty(ReactiveObject.prototype, REACTIVE_OBJECT, { value: true });
109
+
111
110
 
112
111
  const isReactiveObject = (value: any): value is ReactiveObject<any> => {
113
- return typeof value === 'object' && value !== null && REACTIVE_OBJECT in value;
112
+ return typeof value === 'object' && value !== null && value[REACTIVE_OBJECT] === true;
114
113
  };
115
114
 
116
115
 
package/src/system.ts CHANGED
@@ -321,7 +321,7 @@ function unlink(link: Link): Link | null {
321
321
  if (prevSub) {
322
322
  prevSub.nextSub = nextSub;
323
323
  }
324
- else if ((dep.subs = nextSub) === null && 'fn' in dep) {
324
+ else if ((dep.subs = nextSub) === null && dep.type === COMPUTED) {
325
325
  dispose(dep);
326
326
  }
327
327
 
@@ -340,7 +340,7 @@ function update<T>(computed: Computed<T>): void {
340
340
  for (let link = computed.deps; link; link = link.nextDep) {
341
341
  let dep = link.dep;
342
342
 
343
- if ('fn' in dep) {
343
+ if (dep.type === COMPUTED) {
344
344
  update(dep);
345
345
 
346
346
  if (computed.state & STATE_DIRTY) {
@@ -360,7 +360,6 @@ function update<T>(computed: Computed<T>): void {
360
360
 
361
361
  const computed = <T>(fn: Computed<T>['fn']): Computed<T> => {
362
362
  let self: Computed<T> = {
363
- [COMPUTED]: true,
364
363
  cleanup: null,
365
364
  deps: null,
366
365
  depsTail: null,
@@ -371,6 +370,7 @@ const computed = <T>(fn: Computed<T>['fn']): Computed<T> => {
371
370
  state: STATE_NONE,
372
371
  subs: null,
373
372
  subsTail: null,
373
+ type: COMPUTED,
374
374
  value: undefined as T,
375
375
  };
376
376
 
@@ -427,11 +427,11 @@ const effect = <T>(fn: Computed<T>['fn']) => {
427
427
  };
428
428
 
429
429
  const isComputed = (value: unknown): value is Computed<unknown> => {
430
- return isObject(value) && COMPUTED in value;
430
+ return isObject(value) && value.type === COMPUTED;
431
431
  };
432
432
 
433
433
  const isSignal = (value: unknown): value is Signal<unknown> => {
434
- return isObject(value) && SIGNAL in value;
434
+ return isObject(value) && value.type === SIGNAL;
435
435
  };
436
436
 
437
437
  const onCleanup = (fn: VoidFunction): typeof fn => {
@@ -460,7 +460,7 @@ const read = <T>(node: Signal<T> | Computed<T>): T => {
460
460
  if (observer) {
461
461
  link(node, observer);
462
462
 
463
- if ('fn' in node) {
463
+ if (node.type === COMPUTED) {
464
464
  let height = node.height;
465
465
 
466
466
  if (height >= observer.height) {
@@ -541,9 +541,9 @@ const set = <T>(signal: Signal<T>, value: T) => {
541
541
 
542
542
  const signal = <T>(value: T): Signal<T> => {
543
543
  return {
544
- [SIGNAL]: true,
545
544
  subs: null,
546
545
  subsTail: null,
546
+ type: SIGNAL,
547
547
  value,
548
548
  };
549
549
  };
package/src/types.ts CHANGED
@@ -4,7 +4,6 @@ import { ReactiveObject } from './reactive/object';
4
4
 
5
5
 
6
6
  interface Computed<T> {
7
- [COMPUTED]: true;
8
7
  cleanup: VoidFunction | VoidFunction[] | null;
9
8
  deps: Link | null;
10
9
  depsTail: Link | null;
@@ -20,6 +19,7 @@ interface Computed<T> {
20
19
  typeof STATE_RECOMPUTING;
21
20
  subs: Link | null;
22
21
  subsTail: Link | null;
22
+ type: typeof COMPUTED;
23
23
  value: T;
24
24
  }
25
25
 
@@ -33,9 +33,9 @@ interface Link {
33
33
  }
34
34
 
35
35
  type Signal<T> = {
36
- [SIGNAL]: true;
37
36
  subs: Link | null;
38
37
  subsTail: Link | null;
38
+ type: typeof SIGNAL;
39
39
  value: T;
40
40
  };
41
41