@oscarpalmer/atoms 0.27.0 → 0.28.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/dist/css/a11y.css CHANGED
@@ -1,3 +1,6 @@
1
+ .visually-hidden {
2
+ position: absolute !important;
3
+ }
1
4
  .visually-hidden:not(:active):not(:focus):not(:focus-within) {
2
5
  width: 1px !important;
3
6
  height: 1px !important;
package/dist/js/index.js CHANGED
@@ -284,6 +284,21 @@ function isPlainObject(value) {
284
284
  return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value) && !(Symbol.iterator in value);
285
285
  }
286
286
 
287
+ // src/js/queue.ts
288
+ function queue(callback) {
289
+ queued.add(callback);
290
+ if (queued.size > 0) {
291
+ queueMicrotask(() => {
292
+ const callbacks = Array.from(queued);
293
+ queued.clear();
294
+ for (const callback2 of callbacks) {
295
+ callback2();
296
+ }
297
+ });
298
+ }
299
+ }
300
+ var queued = new Set;
301
+
287
302
  // src/js/value.ts
288
303
  var _cloneNested = function(value) {
289
304
  const cloned = Array.isArray(value) ? [] : {};
@@ -535,13 +550,10 @@ var _isProxy = function(value2) {
535
550
  return value2?.$ instanceof Manager;
536
551
  };
537
552
  var _onChange = function(manager, value2) {
538
- cancelAnimationFrame(frames.get(manager));
539
553
  if (!cloned.has(manager)) {
540
554
  cloned.set(manager, value2);
541
555
  }
542
- frames.set(manager, requestAnimationFrame(() => {
543
- _emit(manager);
544
- }));
556
+ queue(manager.emitter);
545
557
  };
546
558
  function cloneProxy(proxy) {
547
559
  if (!_isProxy(proxy)) {
@@ -575,6 +587,9 @@ class Manager {
575
587
  }
576
588
  constructor(owner) {
577
589
  this.owner = owner;
590
+ this.emitter = function() {
591
+ _emit(this);
592
+ }.bind(this);
578
593
  }
579
594
  clone() {
580
595
  return _createProxy(undefined, clone(merge(this.owner)));
@@ -595,7 +610,6 @@ class Manager {
595
610
  }
596
611
  }
597
612
  var cloned = new Map;
598
- var frames = new Map;
599
613
  // src/js/signal.ts
600
614
  function computed(callback) {
601
615
  return new Computed(callback);
@@ -603,13 +617,13 @@ function computed(callback) {
603
617
  function effect(callback) {
604
618
  return new Effect(callback);
605
619
  }
606
- var getValue = function(instance) {
607
- const last = effects[effects.length - 1];
608
- if (last !== undefined) {
609
- instance._effects.add(last);
610
- last._values.add(instance);
620
+ var getValue = function(reactive) {
621
+ const effect2 = effects[effects.length - 1];
622
+ if (effect2 !== undefined) {
623
+ reactive._effects.add(effect2);
624
+ effect2._reactives.add(reactive);
611
625
  }
612
- return instance._value;
626
+ return reactive._value;
613
627
  };
614
628
  function isComputed(value2) {
615
629
  return value2 instanceof Computed;
@@ -623,21 +637,16 @@ function isReactive(value2) {
623
637
  function isSignal(value2) {
624
638
  return value2 instanceof Signal;
625
639
  }
626
- var setValue = function(instance, value2, run) {
627
- if (!run && Object.is(value2, instance._value)) {
640
+ var setValue = function(reactive, value2, run) {
641
+ if (!run && Object.is(value2, reactive._value)) {
628
642
  return;
629
643
  }
630
- instance._value = value2;
631
- cancelAnimationFrame(instance._frame);
632
- if (!instance._active) {
633
- return;
634
- }
635
- instance._frame = requestAnimationFrame(() => {
636
- for (const effect2 of instance._effects) {
637
- effect2._callback();
644
+ reactive._value = value2;
645
+ if (reactive._active) {
646
+ for (const effect2 of reactive._effects) {
647
+ queue(effect2._callback);
638
648
  }
639
- instance._frame = undefined;
640
- });
649
+ }
641
650
  };
642
651
  function signal(value2) {
643
652
  return new Signal(value2);
@@ -646,7 +655,6 @@ function signal(value2) {
646
655
  class Reactive {
647
656
  _active = true;
648
657
  _effects = new Set;
649
- _frame;
650
658
  peek() {
651
659
  return this._value;
652
660
  }
@@ -678,7 +686,7 @@ class Computed extends Reactive {
678
686
  class Effect {
679
687
  _callback;
680
688
  _active = false;
681
- _values = new Set;
689
+ _reactives = new Set;
682
690
  constructor(_callback) {
683
691
  this._callback = _callback;
684
692
  this.run();
@@ -697,10 +705,10 @@ class Effect {
697
705
  return;
698
706
  }
699
707
  this._active = false;
700
- for (const value2 of this._values) {
708
+ for (const value2 of this._reactives) {
701
709
  value2._effects.delete(this);
702
710
  }
703
- this._values.clear();
711
+ this._reactives.clear();
704
712
  }
705
713
  }
706
714
 
@@ -730,7 +738,7 @@ class Signal extends Reactive {
730
738
  var effects = [];
731
739
  // src/js/timer.ts
732
740
  function repeat(callback, options) {
733
- const count = typeof options?.count === "number" ? options.count : Infinity;
741
+ const count = typeof options?.count === "number" ? options.count : Number.POSITIVE_INFINITY;
734
742
  return new Timer(callback, { ...options ?? {}, ...{ count } }).start();
735
743
  }
736
744
  function wait(callback, time) {
@@ -820,6 +828,7 @@ export {
820
828
  signal,
821
829
  set,
822
830
  repeat,
831
+ queue,
823
832
  push,
824
833
  proxy,
825
834
  merge,
package/dist/js/index.mjs CHANGED
@@ -4,6 +4,7 @@ export * from "./element";
4
4
  export * from "./event";
5
5
  export * from "./number";
6
6
  export * from "./proxy";
7
+ export * from "./queue";
7
8
  export * from "./signal";
8
9
  export * from "./string";
9
10
  export * from "./timer";
package/dist/js/proxy.js CHANGED
@@ -19,6 +19,21 @@ function isPlainObject(value) {
19
19
  return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value) && !(Symbol.iterator in value);
20
20
  }
21
21
 
22
+ // src/js/queue.ts
23
+ function queue(callback) {
24
+ queued.add(callback);
25
+ if (queued.size > 0) {
26
+ queueMicrotask(() => {
27
+ const callbacks = Array.from(queued);
28
+ queued.clear();
29
+ for (const callback2 of callbacks) {
30
+ callback2();
31
+ }
32
+ });
33
+ }
34
+ }
35
+ var queued = new Set;
36
+
22
37
  // src/js/value.ts
23
38
  var _cloneNested = function(value) {
24
39
  const cloned = Array.isArray(value) ? [] : {};
@@ -239,13 +254,10 @@ var _isProxy = function(value2) {
239
254
  return value2?.$ instanceof Manager;
240
255
  };
241
256
  var _onChange = function(manager, value2) {
242
- cancelAnimationFrame(frames.get(manager));
243
257
  if (!cloned.has(manager)) {
244
258
  cloned.set(manager, value2);
245
259
  }
246
- frames.set(manager, requestAnimationFrame(() => {
247
- _emit(manager);
248
- }));
260
+ queue(manager.emitter);
249
261
  };
250
262
  function cloneProxy(proxy) {
251
263
  if (!_isProxy(proxy)) {
@@ -279,6 +291,9 @@ class Manager {
279
291
  }
280
292
  constructor(owner) {
281
293
  this.owner = owner;
294
+ this.emitter = function() {
295
+ _emit(this);
296
+ }.bind(this);
282
297
  }
283
298
  clone() {
284
299
  return _createProxy(undefined, clone(merge(this.owner)));
@@ -299,7 +314,6 @@ class Manager {
299
314
  }
300
315
  }
301
316
  var cloned = new Map;
302
- var frames = new Map;
303
317
  export {
304
318
  unsubscribe,
305
319
  subscribe,
package/dist/js/proxy.mjs CHANGED
@@ -1,5 +1,8 @@
1
1
  // src/js/proxy.ts
2
- import {isArrayOrPlainObject} from "./is";
2
+ import {
3
+ isArrayOrPlainObject
4
+ } from "./is";
5
+ import {queue as queue2} from "./queue";
3
6
  import {clone, diff, get, merge} from "./value";
4
7
  var _createProxy = function(existing, value2) {
5
8
  if (!isArrayOrPlainObject(value2) || _isProxy(value2) && value2.$ === existing) {
@@ -60,13 +63,10 @@ var _isProxy = function(value2) {
60
63
  return value2?.$ instanceof Manager;
61
64
  };
62
65
  var _onChange = function(manager, value2) {
63
- cancelAnimationFrame(frames.get(manager));
64
66
  if (!cloned.has(manager)) {
65
67
  cloned.set(manager, value2);
66
68
  }
67
- frames.set(manager, requestAnimationFrame(() => {
68
- _emit(manager);
69
- }));
69
+ queue2(manager.emitter);
70
70
  };
71
71
  function cloneProxy(proxy) {
72
72
  if (!_isProxy(proxy)) {
@@ -100,6 +100,9 @@ class Manager {
100
100
  }
101
101
  constructor(owner) {
102
102
  this.owner = owner;
103
+ this.emitter = function() {
104
+ _emit(this);
105
+ }.bind(this);
103
106
  }
104
107
  clone() {
105
108
  return _createProxy(undefined, clone(merge(this.owner)));
@@ -120,7 +123,6 @@ class Manager {
120
123
  }
121
124
  }
122
125
  var cloned = new Map;
123
- var frames = new Map;
124
126
  export {
125
127
  unsubscribe,
126
128
  subscribe,
@@ -0,0 +1,17 @@
1
+ // src/js/queue.ts
2
+ function queue(callback) {
3
+ queued.add(callback);
4
+ if (queued.size > 0) {
5
+ queueMicrotask(() => {
6
+ const callbacks = Array.from(queued);
7
+ queued.clear();
8
+ for (const callback2 of callbacks) {
9
+ callback2();
10
+ }
11
+ });
12
+ }
13
+ }
14
+ var queued = new Set;
15
+ export {
16
+ queue
17
+ };
@@ -0,0 +1,17 @@
1
+ // src/js/queue.ts
2
+ function queue(callback) {
3
+ queued.add(callback);
4
+ if (queued.size > 0) {
5
+ queueMicrotask(() => {
6
+ const callbacks = Array.from(queued);
7
+ queued.clear();
8
+ for (const callback2 of callbacks) {
9
+ callback2();
10
+ }
11
+ });
12
+ }
13
+ }
14
+ var queued = new Set;
15
+ export {
16
+ queue
17
+ };
package/dist/js/signal.js CHANGED
@@ -1,3 +1,18 @@
1
+ // src/js/queue.ts
2
+ function queue(callback) {
3
+ queued.add(callback);
4
+ if (queued.size > 0) {
5
+ queueMicrotask(() => {
6
+ const callbacks = Array.from(queued);
7
+ queued.clear();
8
+ for (const callback2 of callbacks) {
9
+ callback2();
10
+ }
11
+ });
12
+ }
13
+ }
14
+ var queued = new Set;
15
+
1
16
  // src/js/signal.ts
2
17
  function computed(callback) {
3
18
  return new Computed(callback);
@@ -5,13 +20,13 @@ function computed(callback) {
5
20
  function effect(callback) {
6
21
  return new Effect(callback);
7
22
  }
8
- var getValue = function(instance) {
9
- const last = effects[effects.length - 1];
10
- if (last !== undefined) {
11
- instance._effects.add(last);
12
- last._values.add(instance);
23
+ var getValue = function(reactive) {
24
+ const effect2 = effects[effects.length - 1];
25
+ if (effect2 !== undefined) {
26
+ reactive._effects.add(effect2);
27
+ effect2._reactives.add(reactive);
13
28
  }
14
- return instance._value;
29
+ return reactive._value;
15
30
  };
16
31
  function isComputed(value) {
17
32
  return value instanceof Computed;
@@ -25,21 +40,16 @@ function isReactive(value) {
25
40
  function isSignal(value) {
26
41
  return value instanceof Signal;
27
42
  }
28
- var setValue = function(instance, value, run) {
29
- if (!run && Object.is(value, instance._value)) {
43
+ var setValue = function(reactive, value, run) {
44
+ if (!run && Object.is(value, reactive._value)) {
30
45
  return;
31
46
  }
32
- instance._value = value;
33
- cancelAnimationFrame(instance._frame);
34
- if (!instance._active) {
35
- return;
36
- }
37
- instance._frame = requestAnimationFrame(() => {
38
- for (const effect2 of instance._effects) {
39
- effect2._callback();
47
+ reactive._value = value;
48
+ if (reactive._active) {
49
+ for (const effect2 of reactive._effects) {
50
+ queue(effect2._callback);
40
51
  }
41
- instance._frame = undefined;
42
- });
52
+ }
43
53
  };
44
54
  function signal(value) {
45
55
  return new Signal(value);
@@ -48,7 +58,6 @@ function signal(value) {
48
58
  class Reactive {
49
59
  _active = true;
50
60
  _effects = new Set;
51
- _frame;
52
61
  peek() {
53
62
  return this._value;
54
63
  }
@@ -80,7 +89,7 @@ class Computed extends Reactive {
80
89
  class Effect {
81
90
  _callback;
82
91
  _active = false;
83
- _values = new Set;
92
+ _reactives = new Set;
84
93
  constructor(_callback) {
85
94
  this._callback = _callback;
86
95
  this.run();
@@ -99,10 +108,10 @@ class Effect {
99
108
  return;
100
109
  }
101
110
  this._active = false;
102
- for (const value of this._values) {
111
+ for (const value of this._reactives) {
103
112
  value._effects.delete(this);
104
113
  }
105
- this._values.clear();
114
+ this._reactives.clear();
106
115
  }
107
116
  }
108
117
 
@@ -1,17 +1,18 @@
1
1
  // src/js/signal.ts
2
+ import {queue as queue2} from "./queue";
2
3
  function computed(callback) {
3
4
  return new Computed(callback);
4
5
  }
5
6
  function effect(callback) {
6
7
  return new Effect(callback);
7
8
  }
8
- var getValue = function(instance) {
9
- const last = effects[effects.length - 1];
10
- if (last !== undefined) {
11
- instance._effects.add(last);
12
- last._values.add(instance);
9
+ var getValue = function(reactive) {
10
+ const effect2 = effects[effects.length - 1];
11
+ if (effect2 !== undefined) {
12
+ reactive._effects.add(effect2);
13
+ effect2._reactives.add(reactive);
13
14
  }
14
- return instance._value;
15
+ return reactive._value;
15
16
  };
16
17
  function isComputed(value) {
17
18
  return value instanceof Computed;
@@ -25,21 +26,16 @@ function isReactive(value) {
25
26
  function isSignal(value) {
26
27
  return value instanceof Signal;
27
28
  }
28
- var setValue = function(instance, value, run) {
29
- if (!run && Object.is(value, instance._value)) {
29
+ var setValue = function(reactive, value, run) {
30
+ if (!run && Object.is(value, reactive._value)) {
30
31
  return;
31
32
  }
32
- instance._value = value;
33
- cancelAnimationFrame(instance._frame);
34
- if (!instance._active) {
35
- return;
36
- }
37
- instance._frame = requestAnimationFrame(() => {
38
- for (const effect2 of instance._effects) {
39
- effect2._callback();
33
+ reactive._value = value;
34
+ if (reactive._active) {
35
+ for (const effect2 of reactive._effects) {
36
+ queue2(effect2._callback);
40
37
  }
41
- instance._frame = undefined;
42
- });
38
+ }
43
39
  };
44
40
  function signal(value) {
45
41
  return new Signal(value);
@@ -48,7 +44,6 @@ function signal(value) {
48
44
  class Reactive {
49
45
  _active = true;
50
46
  _effects = new Set;
51
- _frame;
52
47
  peek() {
53
48
  return this._value;
54
49
  }
@@ -80,7 +75,7 @@ class Computed extends Reactive {
80
75
  class Effect {
81
76
  _callback;
82
77
  _active = false;
83
- _values = new Set;
78
+ _reactives = new Set;
84
79
  constructor(_callback) {
85
80
  this._callback = _callback;
86
81
  this.run();
@@ -99,10 +94,10 @@ class Effect {
99
94
  return;
100
95
  }
101
96
  this._active = false;
102
- for (const value of this._values) {
97
+ for (const value of this._reactives) {
103
98
  value._effects.delete(this);
104
99
  }
105
- this._values.clear();
100
+ this._reactives.clear();
106
101
  }
107
102
  }
108
103
 
package/dist/js/timer.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/js/timer.ts
2
2
  function repeat(callback, options) {
3
- const count = typeof options?.count === "number" ? options.count : Infinity;
3
+ const count = typeof options?.count === "number" ? options.count : Number.POSITIVE_INFINITY;
4
4
  return new Timer(callback, { ...options ?? {}, ...{ count } }).start();
5
5
  }
6
6
  function wait(callback, time) {
package/dist/js/timer.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/js/timer.ts
2
2
  function repeat(callback, options) {
3
- const count = typeof options?.count === "number" ? options.count : Infinity;
3
+ const count = typeof options?.count === "number" ? options.count : Number.POSITIVE_INFINITY;
4
4
  return new Timer(callback, { ...options ?? {}, ...{ count } }).start();
5
5
  }
6
6
  function wait(callback, time) {
package/dist/js/value.mjs CHANGED
@@ -1,5 +1,7 @@
1
1
  // src/js/value.ts
2
- import {isArrayOrPlainObject} from "./is";
2
+ import {
3
+ isArrayOrPlainObject
4
+ } from "./is";
3
5
  import {getString} from "./string";
4
6
  var _cloneNested = function(value) {
5
7
  const cloned = Array.isArray(value) ? [] : {};
package/package.json CHANGED
@@ -54,6 +54,12 @@
54
54
  "require": "./dist/js/proxy.js",
55
55
  "types": "./types/proxy.d.ts"
56
56
  },
57
+ "./queue": {
58
+ "bun": "./src/js/queue.ts",
59
+ "import": "./dist/js/queue.mjs",
60
+ "require": "./dist/js/queue.js",
61
+ "types": "./types/queue.d.ts"
62
+ },
57
63
  "./signal": {
58
64
  "bun": "./src/js/signal.ts",
59
65
  "import": "./dist/js/signal.mjs",
@@ -111,5 +117,5 @@
111
117
  },
112
118
  "type": "module",
113
119
  "types": "./types/index.d.ts",
114
- "version": "0.27.0"
120
+ "version": "0.28.0"
115
121
  }
package/src/css/a11y.scss CHANGED
@@ -1,8 +1,12 @@
1
- .visually-hidden:not(:active):not(:focus):not(:focus-within) {
2
- width: 1px !important;
3
- height: 1px !important;
4
- clip: rect(1px, 1px 1px, 1px) !important;
5
- clip-path: inset(50%) !important;
6
- overflow: hidden !important;
7
- white-space: nowrap !important;
8
- }
1
+ .visually-hidden {
2
+ position: absolute !important;
3
+
4
+ &:not(:active):not(:focus):not(:focus-within) {
5
+ width: 1px !important;
6
+ height: 1px !important;
7
+ clip: rect(1px, 1px 1px, 1px) !important;
8
+ clip-path: inset(50%) !important;
9
+ overflow: hidden !important;
10
+ white-space: nowrap !important;
11
+ }
12
+ }
package/src/js/array.ts CHANGED
@@ -1,5 +1,5 @@
1
- import {PlainObject} from './is';
2
- import {Key} from './value';
1
+ import type {PlainObject} from './is';
2
+ import type {Key} from './value';
3
3
 
4
4
  type BooleanCallback<T> = (item: T, index: number, array: T[]) => boolean;
5
5
 
package/src/js/index.ts CHANGED
@@ -3,6 +3,7 @@ export * from './element';
3
3
  export * from './event';
4
4
  export * from './number';
5
5
  export * from './proxy';
6
+ export * from './queue';
6
7
  export * from './signal';
7
8
  export * from './string';
8
9
  export * from './timer';
package/src/js/proxy.ts CHANGED
@@ -1,16 +1,26 @@
1
- import {ArrayOrPlainObject, PlainObject, isArrayOrPlainObject} from './is';
1
+ import {
2
+ type ArrayOrPlainObject,
3
+ type PlainObject,
4
+ isArrayOrPlainObject,
5
+ } from './is';
6
+ import {queue} from './queue';
2
7
  import {clone, diff, get, merge} from './value';
3
8
 
4
9
  class Manager<T extends ArrayOrPlainObject = PlainObject> {
5
10
  private count = 0;
6
11
 
12
+ declare readonly emitter: () => void;
7
13
  readonly subscribers = new Map<string, Set<Subscriber>>();
8
14
 
9
15
  get subscribed(): boolean {
10
16
  return this.count > 0;
11
17
  }
12
18
 
13
- constructor(readonly owner: Proxied<T>) {}
19
+ constructor(readonly owner: Proxied<T>) {
20
+ this.emitter = function (this: Manager<T>) {
21
+ _emit(this as never);
22
+ }.bind(this);
23
+ }
14
24
 
15
25
  clone(): T {
16
26
  return _createProxy(undefined, clone(merge(this.owner))) as T;
@@ -47,7 +57,6 @@ type Proxied<T extends ArrayOrPlainObject = PlainObject> = {
47
57
  export type Subscriber<T1 = unknown, T2 = T1> = (to: T1, from: T2) => void;
48
58
 
49
59
  const cloned = new Map<Manager, unknown>();
50
- const frames = new Map<Manager, number>();
51
60
 
52
61
  function _createProxy<T extends ArrayOrPlainObject>(
53
62
  existing: Manager | undefined,
@@ -144,18 +153,11 @@ function _isProxy(value: unknown): value is Proxied {
144
153
  }
145
154
 
146
155
  function _onChange(manager: Manager, value: unknown): void {
147
- cancelAnimationFrame(frames.get(manager) as number);
148
-
149
156
  if (!cloned.has(manager)) {
150
157
  cloned.set(manager, value);
151
158
  }
152
159
 
153
- frames.set(
154
- manager,
155
- requestAnimationFrame(() => {
156
- _emit(manager);
157
- }),
158
- );
160
+ queue(manager.emitter);
159
161
  }
160
162
 
161
163
  /**
@@ -0,0 +1,20 @@
1
+ const queued = new Set<() => void>();
2
+
3
+ /**
4
+ * Queues a callback to be executed at the next best time
5
+ */
6
+ export function queue(callback: () => void): void {
7
+ queued.add(callback);
8
+
9
+ if (queued.size > 0) {
10
+ queueMicrotask(() => {
11
+ const callbacks = Array.from(queued);
12
+
13
+ queued.clear();
14
+
15
+ for (const callback of callbacks) {
16
+ callback();
17
+ }
18
+ });
19
+ }
20
+ }
package/src/js/signal.ts CHANGED
@@ -1,12 +1,14 @@
1
+ import {queue} from './queue';
2
+
1
3
  type InternalEffect = {
4
+ _active: boolean;
2
5
  _callback: () => void;
3
- _values: Set<InternalReactive>;
6
+ _reactives: Set<InternalReactive>;
4
7
  };
5
8
 
6
9
  type InternalReactive = {
7
10
  _active: boolean;
8
11
  _effects: Set<InternalEffect>;
9
- _frame: number | undefined;
10
12
  _value: unknown;
11
13
  };
12
14
 
@@ -16,7 +18,6 @@ type InternalReactive = {
16
18
  abstract class Reactive<T = unknown> {
17
19
  protected _active = true;
18
20
  protected _effects = new Set<InternalEffect>();
19
- protected _frame: number | undefined;
20
21
  protected declare _value: T;
21
22
 
22
23
  /**
@@ -95,7 +96,7 @@ class Computed<T> extends Reactive<T> {
95
96
  */
96
97
  class Effect {
97
98
  private _active = false;
98
- private readonly _values = new Set<InternalReactive>();
99
+ private readonly _reactives = new Set<InternalReactive>();
99
100
 
100
101
  constructor(private readonly _callback: () => void) {
101
102
  this.run();
@@ -128,11 +129,11 @@ class Effect {
128
129
 
129
130
  this._active = false;
130
131
 
131
- for (const value of this._values) {
132
+ for (const value of this._reactives) {
132
133
  value._effects.delete(this as never);
133
134
  }
134
135
 
135
- this._values.clear();
136
+ this._reactives.clear();
136
137
  }
137
138
  }
138
139
 
@@ -195,15 +196,15 @@ export function effect(callback: () => void): Effect {
195
196
  return new Effect(callback);
196
197
  }
197
198
 
198
- function getValue(instance: InternalReactive): unknown {
199
- const last = effects[effects.length - 1];
199
+ function getValue(reactive: InternalReactive): unknown {
200
+ const effect = effects[effects.length - 1];
200
201
 
201
- if (last !== undefined) {
202
- instance._effects.add(last);
203
- last._values.add(instance);
202
+ if (effect !== undefined) {
203
+ reactive._effects.add(effect);
204
+ effect._reactives.add(reactive);
204
205
  }
205
206
 
206
- return instance._value;
207
+ return reactive._value;
207
208
  }
208
209
 
209
210
  /**
@@ -220,6 +221,9 @@ export function isEffect(value: unknown): value is Effect {
220
221
  return value instanceof Effect;
221
222
  }
222
223
 
224
+ /**
225
+ * Is the value a reactive value?
226
+ */
223
227
  export function isReactive(value: unknown): value is Reactive<unknown> {
224
228
  return value instanceof Reactive;
225
229
  }
@@ -231,26 +235,18 @@ export function isSignal(value: unknown): value is Signal<unknown> {
231
235
  return value instanceof Signal;
232
236
  }
233
237
 
234
- function setValue<T>(instance: InternalReactive, value: T, run: boolean): void {
235
- if (!run && Object.is(value, instance._value)) {
238
+ function setValue<T>(reactive: InternalReactive, value: T, run: boolean): void {
239
+ if (!run && Object.is(value, reactive._value)) {
236
240
  return;
237
241
  }
238
242
 
239
- instance._value = value;
240
-
241
- cancelAnimationFrame(instance._frame as never);
243
+ reactive._value = value;
242
244
 
243
- if (!instance._active) {
244
- return;
245
- }
246
-
247
- instance._frame = requestAnimationFrame(() => {
248
- for (const effect of instance._effects) {
249
- effect._callback();
245
+ if (reactive._active) {
246
+ for (const effect of reactive._effects) {
247
+ queue(effect._callback);
250
248
  }
251
-
252
- instance._frame = undefined;
253
- });
249
+ }
254
250
  }
255
251
 
256
252
  /**
package/src/js/timer.ts CHANGED
@@ -104,7 +104,10 @@ export function repeat(
104
104
  callback: (index: number) => void,
105
105
  options?: Options,
106
106
  ): Timer {
107
- const count = typeof options?.count === 'number' ? options.count : Infinity;
107
+ const count =
108
+ typeof options?.count === 'number'
109
+ ? options.count
110
+ : Number.POSITIVE_INFINITY;
108
111
 
109
112
  return new Timer(callback, {...(options ?? {}), ...{count}}).start();
110
113
  }
package/src/js/value.ts CHANGED
@@ -1,5 +1,8 @@
1
- import {chunk} from './array';
2
- import {ArrayOrPlainObject, PlainObject, isArrayOrPlainObject} from './is';
1
+ import {
2
+ type ArrayOrPlainObject,
3
+ type PlainObject,
4
+ isArrayOrPlainObject,
5
+ } from './is';
3
6
  import {getString} from './string';
4
7
 
5
8
  export type DiffType = 'full' | 'none' | 'partial';
package/types/array.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Key } from './value';
1
+ import type { Key } from './value';
2
2
  type BooleanCallback<T> = (item: T, index: number, array: T[]) => boolean;
3
3
  type KeyCallback<T> = (item: T) => Key;
4
4
  /**
package/types/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export * from './element';
3
3
  export * from './event';
4
4
  export * from './number';
5
5
  export * from './proxy';
6
+ export * from './queue';
6
7
  export * from './signal';
7
8
  export * from './string';
8
9
  export * from './timer';
package/types/proxy.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ArrayOrPlainObject, PlainObject } from './is';
1
+ import { type ArrayOrPlainObject, type PlainObject } from './is';
2
2
  export type Subscriber<T1 = unknown, T2 = T1> = (to: T1, from: T2) => void;
3
3
  /**
4
4
  * Clones and creates a new proxy
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Queues a callback to be executed at the next best time
3
+ */
4
+ export declare function queue(callback: () => void): void;
package/types/signal.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  type InternalEffect = {
2
+ _active: boolean;
2
3
  _callback: () => void;
3
- _values: Set<InternalReactive>;
4
+ _reactives: Set<InternalReactive>;
4
5
  };
5
6
  type InternalReactive = {
6
7
  _active: boolean;
7
8
  _effects: Set<InternalEffect>;
8
- _frame: number | undefined;
9
9
  _value: unknown;
10
10
  };
11
11
  /**
@@ -14,7 +14,6 @@ type InternalReactive = {
14
14
  declare abstract class Reactive<T = unknown> {
15
15
  protected _active: boolean;
16
16
  protected _effects: Set<InternalEffect>;
17
- protected _frame: number | undefined;
18
17
  protected _value: T;
19
18
  /**
20
19
  * The current value
@@ -66,7 +65,7 @@ declare class Computed<T> extends Reactive<T> {
66
65
  declare class Effect {
67
66
  private readonly _callback;
68
67
  private _active;
69
- private readonly _values;
68
+ private readonly _reactives;
70
69
  constructor(_callback: () => void);
71
70
  /**
72
71
  * Starts and runs the effect, if it was stopped
@@ -116,6 +115,9 @@ export declare function isComputed(value: unknown): value is Computed<unknown>;
116
115
  * Is the value a reactive effect?
117
116
  */
118
117
  export declare function isEffect(value: unknown): value is Effect;
118
+ /**
119
+ * Is the value a reactive value?
120
+ */
119
121
  export declare function isReactive(value: unknown): value is Reactive<unknown>;
120
122
  /**
121
123
  * Is the value a reactive value?
package/types/value.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ArrayOrPlainObject } from './is';
1
+ import { type ArrayOrPlainObject } from './is';
2
2
  export type DiffType = 'full' | 'none' | 'partial';
3
3
  export type DiffResult<T1 = unknown, T2 = T1> = {
4
4
  original: DiffValue<T1, T2>;