@oscarpalmer/atoms 0.29.0 → 0.31.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/js/index.js +32 -143
- package/dist/js/index.mjs +0 -1
- package/dist/js/proxy.js +12 -5
- package/dist/js/queue.js +12 -5
- package/dist/js/queue.mjs +12 -5
- package/dist/js/signal.js +44 -15
- package/dist/js/timer.js +20 -5
- package/dist/js/timer.mjs +20 -5
- package/package.json +4 -7
- package/src/js/index.ts +0 -1
- package/src/js/queue.ts +17 -5
- package/src/js/timer.ts +29 -5
- package/types/index.d.ts +0 -1
- package/types/queue.d.ts +3 -0
- package/src/js/signal.ts +0 -259
- package/types/signal.d.ts +0 -130
package/dist/js/index.js
CHANGED
|
@@ -286,18 +286,25 @@ function isPlainObject(value) {
|
|
|
286
286
|
|
|
287
287
|
// src/js/queue.ts
|
|
288
288
|
function queue(callback) {
|
|
289
|
-
|
|
290
|
-
if (
|
|
289
|
+
_atomic_queued.add(callback);
|
|
290
|
+
if (_atomic_queued.size > 0) {
|
|
291
291
|
queueMicrotask(() => {
|
|
292
|
-
const callbacks = Array.from(
|
|
293
|
-
|
|
292
|
+
const callbacks = Array.from(_atomic_queued);
|
|
293
|
+
_atomic_queued.clear();
|
|
294
294
|
for (const callback2 of callbacks) {
|
|
295
295
|
callback2();
|
|
296
296
|
}
|
|
297
297
|
});
|
|
298
298
|
}
|
|
299
299
|
}
|
|
300
|
-
|
|
300
|
+
if (globalThis._atomic_queued === undefined) {
|
|
301
|
+
const queued = new Set;
|
|
302
|
+
Object.defineProperty(globalThis, "_atomic_queued", {
|
|
303
|
+
get() {
|
|
304
|
+
return queued;
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
}
|
|
301
308
|
|
|
302
309
|
// src/js/value.ts
|
|
303
310
|
var _cloneNested = function(value) {
|
|
@@ -610,132 +617,6 @@ class Manager {
|
|
|
610
617
|
}
|
|
611
618
|
}
|
|
612
619
|
var cloned = new Map;
|
|
613
|
-
// src/js/signal.ts
|
|
614
|
-
function computed(callback) {
|
|
615
|
-
return new Computed(callback);
|
|
616
|
-
}
|
|
617
|
-
function effect(callback) {
|
|
618
|
-
return new Effect(callback);
|
|
619
|
-
}
|
|
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);
|
|
625
|
-
}
|
|
626
|
-
return reactive._value;
|
|
627
|
-
};
|
|
628
|
-
function isComputed(value2) {
|
|
629
|
-
return value2 instanceof Computed;
|
|
630
|
-
}
|
|
631
|
-
function isEffect(value2) {
|
|
632
|
-
return value2 instanceof Effect;
|
|
633
|
-
}
|
|
634
|
-
function isReactive(value2) {
|
|
635
|
-
return value2 instanceof Computed || value2 instanceof Signal;
|
|
636
|
-
}
|
|
637
|
-
function isSignal(value2) {
|
|
638
|
-
return value2 instanceof Signal;
|
|
639
|
-
}
|
|
640
|
-
var setValue = function(reactive, value2, run) {
|
|
641
|
-
if (!run && Object.is(value2, reactive._value)) {
|
|
642
|
-
return;
|
|
643
|
-
}
|
|
644
|
-
reactive._value = value2;
|
|
645
|
-
if (reactive._active) {
|
|
646
|
-
for (const effect2 of reactive._effects) {
|
|
647
|
-
queue(effect2._callback);
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
};
|
|
651
|
-
function signal(value2) {
|
|
652
|
-
return new Signal(value2);
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
class Reactive {
|
|
656
|
-
_active = true;
|
|
657
|
-
_effects = new Set;
|
|
658
|
-
peek() {
|
|
659
|
-
return this._value;
|
|
660
|
-
}
|
|
661
|
-
toJSON() {
|
|
662
|
-
return this.value;
|
|
663
|
-
}
|
|
664
|
-
toString() {
|
|
665
|
-
return String(this.value);
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
class Computed extends Reactive {
|
|
670
|
-
_effect;
|
|
671
|
-
get value() {
|
|
672
|
-
return getValue(this);
|
|
673
|
-
}
|
|
674
|
-
constructor(callback) {
|
|
675
|
-
super();
|
|
676
|
-
this._effect = effect(() => setValue(this, callback(), false));
|
|
677
|
-
}
|
|
678
|
-
run() {
|
|
679
|
-
this._effect.run();
|
|
680
|
-
}
|
|
681
|
-
stop() {
|
|
682
|
-
this._effect.stop();
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
class Effect {
|
|
687
|
-
_callback;
|
|
688
|
-
_active = false;
|
|
689
|
-
_reactives = new Set;
|
|
690
|
-
constructor(_callback) {
|
|
691
|
-
this._callback = _callback;
|
|
692
|
-
this.run();
|
|
693
|
-
}
|
|
694
|
-
run() {
|
|
695
|
-
if (this._active) {
|
|
696
|
-
return;
|
|
697
|
-
}
|
|
698
|
-
this._active = true;
|
|
699
|
-
const index = effects.push(this) - 1;
|
|
700
|
-
this._callback();
|
|
701
|
-
effects.splice(index, 1);
|
|
702
|
-
}
|
|
703
|
-
stop() {
|
|
704
|
-
if (!this._active) {
|
|
705
|
-
return;
|
|
706
|
-
}
|
|
707
|
-
this._active = false;
|
|
708
|
-
for (const value2 of this._reactives) {
|
|
709
|
-
value2._effects.delete(this);
|
|
710
|
-
}
|
|
711
|
-
this._reactives.clear();
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
class Signal extends Reactive {
|
|
716
|
-
_value;
|
|
717
|
-
get value() {
|
|
718
|
-
return getValue(this);
|
|
719
|
-
}
|
|
720
|
-
set value(value2) {
|
|
721
|
-
setValue(this, value2, false);
|
|
722
|
-
}
|
|
723
|
-
constructor(_value) {
|
|
724
|
-
super();
|
|
725
|
-
this._value = _value;
|
|
726
|
-
}
|
|
727
|
-
run() {
|
|
728
|
-
if (this._active) {
|
|
729
|
-
return;
|
|
730
|
-
}
|
|
731
|
-
this._active = true;
|
|
732
|
-
setValue(this, this._value, true);
|
|
733
|
-
}
|
|
734
|
-
stop() {
|
|
735
|
-
this._active = false;
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
var effects = [];
|
|
739
620
|
// src/js/timer.ts
|
|
740
621
|
function repeat(callback, options) {
|
|
741
622
|
const count = typeof options?.count === "number" ? options.count : Number.POSITIVE_INFINITY;
|
|
@@ -763,8 +644,11 @@ var work = function(type, timer, state, options) {
|
|
|
763
644
|
}
|
|
764
645
|
state.active = true;
|
|
765
646
|
const isRepeated = count > 0;
|
|
766
|
-
const milliseconds = 16.666666666666668;
|
|
767
647
|
let index = 0;
|
|
648
|
+
let total = count * interval;
|
|
649
|
+
if (total < milliseconds) {
|
|
650
|
+
total = milliseconds;
|
|
651
|
+
}
|
|
768
652
|
let start;
|
|
769
653
|
function step(timestamp) {
|
|
770
654
|
if (!state.active) {
|
|
@@ -772,14 +656,13 @@ var work = function(type, timer, state, options) {
|
|
|
772
656
|
}
|
|
773
657
|
start ??= timestamp;
|
|
774
658
|
const elapsed = timestamp - start;
|
|
775
|
-
const
|
|
776
|
-
|
|
777
|
-
if (minimum < interval && interval < maximum) {
|
|
659
|
+
const finished = elapsed >= total;
|
|
660
|
+
if (finished || elapsed - 2 < interval && interval < elapsed + 2) {
|
|
778
661
|
if (state.active) {
|
|
779
662
|
callback(isRepeated ? index : undefined);
|
|
780
663
|
}
|
|
781
664
|
index += 1;
|
|
782
|
-
if (index < count) {
|
|
665
|
+
if (!finished && index < count) {
|
|
783
666
|
start = undefined;
|
|
784
667
|
} else {
|
|
785
668
|
state.active = false;
|
|
@@ -793,6 +676,7 @@ var work = function(type, timer, state, options) {
|
|
|
793
676
|
state.frame = requestAnimationFrame(step);
|
|
794
677
|
return timer;
|
|
795
678
|
};
|
|
679
|
+
var milliseconds = 0;
|
|
796
680
|
|
|
797
681
|
class Timer {
|
|
798
682
|
get active() {
|
|
@@ -819,23 +703,30 @@ class Timer {
|
|
|
819
703
|
return work("stop", this, this.state, this.options);
|
|
820
704
|
}
|
|
821
705
|
}
|
|
706
|
+
(() => {
|
|
707
|
+
let start;
|
|
708
|
+
function fn(time) {
|
|
709
|
+
if (start === undefined) {
|
|
710
|
+
start = time;
|
|
711
|
+
requestAnimationFrame(fn);
|
|
712
|
+
} else {
|
|
713
|
+
milliseconds = time - start;
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
requestAnimationFrame(fn);
|
|
717
|
+
})();
|
|
822
718
|
export {
|
|
823
719
|
wait,
|
|
824
720
|
unsubscribe,
|
|
825
721
|
unique,
|
|
826
722
|
subscribe,
|
|
827
723
|
splice,
|
|
828
|
-
signal,
|
|
829
724
|
set,
|
|
830
725
|
repeat,
|
|
831
726
|
queue,
|
|
832
727
|
push,
|
|
833
728
|
proxy,
|
|
834
729
|
merge,
|
|
835
|
-
isSignal,
|
|
836
|
-
isReactive,
|
|
837
|
-
isEffect,
|
|
838
|
-
isComputed,
|
|
839
730
|
insert,
|
|
840
731
|
indexOf,
|
|
841
732
|
groupBy,
|
|
@@ -851,10 +742,8 @@ export {
|
|
|
851
742
|
find,
|
|
852
743
|
filter,
|
|
853
744
|
exists,
|
|
854
|
-
effect,
|
|
855
745
|
diff,
|
|
856
746
|
createUuid,
|
|
857
|
-
computed,
|
|
858
747
|
cloneProxy,
|
|
859
748
|
clone,
|
|
860
749
|
clamp,
|
package/dist/js/index.mjs
CHANGED
package/dist/js/proxy.js
CHANGED
|
@@ -21,18 +21,25 @@ function isPlainObject(value) {
|
|
|
21
21
|
|
|
22
22
|
// src/js/queue.ts
|
|
23
23
|
function queue(callback) {
|
|
24
|
-
|
|
25
|
-
if (
|
|
24
|
+
_atomic_queued.add(callback);
|
|
25
|
+
if (_atomic_queued.size > 0) {
|
|
26
26
|
queueMicrotask(() => {
|
|
27
|
-
const callbacks = Array.from(
|
|
28
|
-
|
|
27
|
+
const callbacks = Array.from(_atomic_queued);
|
|
28
|
+
_atomic_queued.clear();
|
|
29
29
|
for (const callback2 of callbacks) {
|
|
30
30
|
callback2();
|
|
31
31
|
}
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
-
|
|
35
|
+
if (globalThis._atomic_queued === undefined) {
|
|
36
|
+
const queued = new Set;
|
|
37
|
+
Object.defineProperty(globalThis, "_atomic_queued", {
|
|
38
|
+
get() {
|
|
39
|
+
return queued;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
36
43
|
|
|
37
44
|
// src/js/value.ts
|
|
38
45
|
var _cloneNested = function(value) {
|
package/dist/js/queue.js
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
// src/js/queue.ts
|
|
2
2
|
function queue(callback) {
|
|
3
|
-
|
|
4
|
-
if (
|
|
3
|
+
_atomic_queued.add(callback);
|
|
4
|
+
if (_atomic_queued.size > 0) {
|
|
5
5
|
queueMicrotask(() => {
|
|
6
|
-
const callbacks = Array.from(
|
|
7
|
-
|
|
6
|
+
const callbacks = Array.from(_atomic_queued);
|
|
7
|
+
_atomic_queued.clear();
|
|
8
8
|
for (const callback2 of callbacks) {
|
|
9
9
|
callback2();
|
|
10
10
|
}
|
|
11
11
|
});
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
|
-
|
|
14
|
+
if (globalThis._atomic_queued === undefined) {
|
|
15
|
+
const queued = new Set;
|
|
16
|
+
Object.defineProperty(globalThis, "_atomic_queued", {
|
|
17
|
+
get() {
|
|
18
|
+
return queued;
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
15
22
|
export {
|
|
16
23
|
queue
|
|
17
24
|
};
|
package/dist/js/queue.mjs
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
// src/js/queue.ts
|
|
2
2
|
function queue(callback) {
|
|
3
|
-
|
|
4
|
-
if (
|
|
3
|
+
_atomic_queued.add(callback);
|
|
4
|
+
if (_atomic_queued.size > 0) {
|
|
5
5
|
queueMicrotask(() => {
|
|
6
|
-
const callbacks = Array.from(
|
|
7
|
-
|
|
6
|
+
const callbacks = Array.from(_atomic_queued);
|
|
7
|
+
_atomic_queued.clear();
|
|
8
8
|
for (const callback2 of callbacks) {
|
|
9
9
|
callback2();
|
|
10
10
|
}
|
|
11
11
|
});
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
|
-
|
|
14
|
+
if (globalThis._atomic_queued === undefined) {
|
|
15
|
+
const queued = new Set;
|
|
16
|
+
Object.defineProperty(globalThis, "_atomic_queued", {
|
|
17
|
+
get() {
|
|
18
|
+
return queued;
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
15
22
|
export {
|
|
16
23
|
queue
|
|
17
24
|
};
|
package/dist/js/signal.js
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
// src/js/queue.ts
|
|
2
2
|
function queue(callback) {
|
|
3
|
-
|
|
4
|
-
if (
|
|
3
|
+
_atomic_queued.add(callback);
|
|
4
|
+
if (_atomic_queued.size > 0) {
|
|
5
5
|
queueMicrotask(() => {
|
|
6
|
-
const callbacks = Array.from(
|
|
7
|
-
|
|
6
|
+
const callbacks = Array.from(_atomic_queued);
|
|
7
|
+
_atomic_queued.clear();
|
|
8
8
|
for (const callback2 of callbacks) {
|
|
9
9
|
callback2();
|
|
10
10
|
}
|
|
11
11
|
});
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
|
-
|
|
14
|
+
if (globalThis._atomic_effects === undefined) {
|
|
15
|
+
const queued = new Set;
|
|
16
|
+
Object.defineProperty(globalThis, "_atomic_queued", {
|
|
17
|
+
get() {
|
|
18
|
+
return queued;
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
15
22
|
|
|
16
23
|
// src/js/signal.ts
|
|
17
24
|
function computed(callback) {
|
|
@@ -21,7 +28,7 @@ function effect(callback) {
|
|
|
21
28
|
return new Effect(callback);
|
|
22
29
|
}
|
|
23
30
|
var getValue = function(reactive) {
|
|
24
|
-
const effect2 =
|
|
31
|
+
const effect2 = _atomic_effects[_atomic_effects.length - 1];
|
|
25
32
|
if (effect2 !== undefined) {
|
|
26
33
|
reactive._effects.add(effect2);
|
|
27
34
|
effect2._reactives.add(reactive);
|
|
@@ -29,16 +36,19 @@ var getValue = function(reactive) {
|
|
|
29
36
|
return reactive._value;
|
|
30
37
|
};
|
|
31
38
|
function isComputed(value) {
|
|
32
|
-
return value
|
|
39
|
+
return isInstance(/^computed$/i, value);
|
|
33
40
|
}
|
|
34
41
|
function isEffect(value) {
|
|
35
|
-
return value
|
|
42
|
+
return isInstance(/^effect$/i, value);
|
|
36
43
|
}
|
|
44
|
+
var isInstance = function(expression, value) {
|
|
45
|
+
return expression.test(value?.constructor?.name ?? "") && value.atomic === true;
|
|
46
|
+
};
|
|
37
47
|
function isReactive(value) {
|
|
38
|
-
return value
|
|
48
|
+
return isComputed(value) || isSignal(value);
|
|
39
49
|
}
|
|
40
50
|
function isSignal(value) {
|
|
41
|
-
return value
|
|
51
|
+
return isInstance(/^signal$/i, value);
|
|
42
52
|
}
|
|
43
53
|
var setValue = function(reactive, value, run) {
|
|
44
54
|
if (!run && Object.is(value, reactive._value)) {
|
|
@@ -54,8 +64,27 @@ var setValue = function(reactive, value, run) {
|
|
|
54
64
|
function signal(value) {
|
|
55
65
|
return new Signal(value);
|
|
56
66
|
}
|
|
67
|
+
if (globalThis._atomic_effects === undefined) {
|
|
68
|
+
const effects = [];
|
|
69
|
+
Object.defineProperty(globalThis, "_atomic_effects", {
|
|
70
|
+
get() {
|
|
71
|
+
return effects;
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
57
75
|
|
|
58
|
-
class
|
|
76
|
+
class Atomic {
|
|
77
|
+
constructor() {
|
|
78
|
+
Object.defineProperty(this, "atomic", {
|
|
79
|
+
value: true
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
class Reactive extends Atomic {
|
|
85
|
+
constructor() {
|
|
86
|
+
super(...arguments);
|
|
87
|
+
}
|
|
59
88
|
_active = true;
|
|
60
89
|
_effects = new Set;
|
|
61
90
|
peek() {
|
|
@@ -86,11 +115,12 @@ class Computed extends Reactive {
|
|
|
86
115
|
}
|
|
87
116
|
}
|
|
88
117
|
|
|
89
|
-
class Effect {
|
|
118
|
+
class Effect extends Atomic {
|
|
90
119
|
_callback;
|
|
91
120
|
_active = false;
|
|
92
121
|
_reactives = new Set;
|
|
93
122
|
constructor(_callback) {
|
|
123
|
+
super();
|
|
94
124
|
this._callback = _callback;
|
|
95
125
|
this.run();
|
|
96
126
|
}
|
|
@@ -99,9 +129,9 @@ class Effect {
|
|
|
99
129
|
return;
|
|
100
130
|
}
|
|
101
131
|
this._active = true;
|
|
102
|
-
const index =
|
|
132
|
+
const index = _atomic_effects.push(this) - 1;
|
|
103
133
|
this._callback();
|
|
104
|
-
|
|
134
|
+
_atomic_effects.splice(index, 1);
|
|
105
135
|
}
|
|
106
136
|
stop() {
|
|
107
137
|
if (!this._active) {
|
|
@@ -138,7 +168,6 @@ class Signal extends Reactive {
|
|
|
138
168
|
this._active = false;
|
|
139
169
|
}
|
|
140
170
|
}
|
|
141
|
-
var effects = [];
|
|
142
171
|
export {
|
|
143
172
|
signal,
|
|
144
173
|
isSignal,
|
package/dist/js/timer.js
CHANGED
|
@@ -25,8 +25,11 @@ var work = function(type, timer, state, options) {
|
|
|
25
25
|
}
|
|
26
26
|
state.active = true;
|
|
27
27
|
const isRepeated = count > 0;
|
|
28
|
-
const milliseconds = 16.666666666666668;
|
|
29
28
|
let index = 0;
|
|
29
|
+
let total = count * interval;
|
|
30
|
+
if (total < milliseconds) {
|
|
31
|
+
total = milliseconds;
|
|
32
|
+
}
|
|
30
33
|
let start;
|
|
31
34
|
function step(timestamp) {
|
|
32
35
|
if (!state.active) {
|
|
@@ -34,14 +37,13 @@ var work = function(type, timer, state, options) {
|
|
|
34
37
|
}
|
|
35
38
|
start ??= timestamp;
|
|
36
39
|
const elapsed = timestamp - start;
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
if (minimum < interval && interval < maximum) {
|
|
40
|
+
const finished = elapsed >= total;
|
|
41
|
+
if (finished || elapsed - 2 < interval && interval < elapsed + 2) {
|
|
40
42
|
if (state.active) {
|
|
41
43
|
callback(isRepeated ? index : undefined);
|
|
42
44
|
}
|
|
43
45
|
index += 1;
|
|
44
|
-
if (index < count) {
|
|
46
|
+
if (!finished && index < count) {
|
|
45
47
|
start = undefined;
|
|
46
48
|
} else {
|
|
47
49
|
state.active = false;
|
|
@@ -55,6 +57,7 @@ var work = function(type, timer, state, options) {
|
|
|
55
57
|
state.frame = requestAnimationFrame(step);
|
|
56
58
|
return timer;
|
|
57
59
|
};
|
|
60
|
+
var milliseconds = 0;
|
|
58
61
|
|
|
59
62
|
class Timer {
|
|
60
63
|
get active() {
|
|
@@ -81,6 +84,18 @@ class Timer {
|
|
|
81
84
|
return work("stop", this, this.state, this.options);
|
|
82
85
|
}
|
|
83
86
|
}
|
|
87
|
+
(() => {
|
|
88
|
+
let start;
|
|
89
|
+
function fn(time) {
|
|
90
|
+
if (start === undefined) {
|
|
91
|
+
start = time;
|
|
92
|
+
requestAnimationFrame(fn);
|
|
93
|
+
} else {
|
|
94
|
+
milliseconds = time - start;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
requestAnimationFrame(fn);
|
|
98
|
+
})();
|
|
84
99
|
export {
|
|
85
100
|
wait,
|
|
86
101
|
repeat,
|
package/dist/js/timer.mjs
CHANGED
|
@@ -25,8 +25,11 @@ var work = function(type, timer, state, options) {
|
|
|
25
25
|
}
|
|
26
26
|
state.active = true;
|
|
27
27
|
const isRepeated = count > 0;
|
|
28
|
-
const milliseconds = 16.666666666666668;
|
|
29
28
|
let index = 0;
|
|
29
|
+
let total = count * interval;
|
|
30
|
+
if (total < milliseconds) {
|
|
31
|
+
total = milliseconds;
|
|
32
|
+
}
|
|
30
33
|
let start;
|
|
31
34
|
function step(timestamp) {
|
|
32
35
|
if (!state.active) {
|
|
@@ -34,14 +37,13 @@ var work = function(type, timer, state, options) {
|
|
|
34
37
|
}
|
|
35
38
|
start ??= timestamp;
|
|
36
39
|
const elapsed = timestamp - start;
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
if (minimum < interval && interval < maximum) {
|
|
40
|
+
const finished = elapsed >= total;
|
|
41
|
+
if (finished || elapsed - 2 < interval && interval < elapsed + 2) {
|
|
40
42
|
if (state.active) {
|
|
41
43
|
callback(isRepeated ? index : undefined);
|
|
42
44
|
}
|
|
43
45
|
index += 1;
|
|
44
|
-
if (index < count) {
|
|
46
|
+
if (!finished && index < count) {
|
|
45
47
|
start = undefined;
|
|
46
48
|
} else {
|
|
47
49
|
state.active = false;
|
|
@@ -55,6 +57,7 @@ var work = function(type, timer, state, options) {
|
|
|
55
57
|
state.frame = requestAnimationFrame(step);
|
|
56
58
|
return timer;
|
|
57
59
|
};
|
|
60
|
+
var milliseconds = 0;
|
|
58
61
|
|
|
59
62
|
class Timer {
|
|
60
63
|
get active() {
|
|
@@ -81,6 +84,18 @@ class Timer {
|
|
|
81
84
|
return work("stop", this, this.state, this.options);
|
|
82
85
|
}
|
|
83
86
|
}
|
|
87
|
+
(() => {
|
|
88
|
+
let start;
|
|
89
|
+
function fn(time) {
|
|
90
|
+
if (start === undefined) {
|
|
91
|
+
start = time;
|
|
92
|
+
requestAnimationFrame(fn);
|
|
93
|
+
} else {
|
|
94
|
+
milliseconds = time - start;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
requestAnimationFrame(fn);
|
|
98
|
+
})();
|
|
84
99
|
export {
|
|
85
100
|
wait,
|
|
86
101
|
repeat,
|
package/package.json
CHANGED
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
"typescript": "^5.4"
|
|
13
13
|
},
|
|
14
14
|
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./types/index.d.ts"
|
|
17
|
+
},
|
|
15
18
|
"./array": {
|
|
16
19
|
"bun": "./src/js/array.ts",
|
|
17
20
|
"import": "./dist/js/array.mjs",
|
|
@@ -60,12 +63,6 @@
|
|
|
60
63
|
"require": "./dist/js/queue.js",
|
|
61
64
|
"types": "./types/queue.d.ts"
|
|
62
65
|
},
|
|
63
|
-
"./signal": {
|
|
64
|
-
"bun": "./src/js/signal.ts",
|
|
65
|
-
"import": "./dist/js/signal.mjs",
|
|
66
|
-
"require": "./dist/js/signal.js",
|
|
67
|
-
"types": "./types/signal.d.ts"
|
|
68
|
-
},
|
|
69
66
|
"./string": {
|
|
70
67
|
"bun": "./src/js/string.ts",
|
|
71
68
|
"import": "./dist/js/string.mjs",
|
|
@@ -117,5 +114,5 @@
|
|
|
117
114
|
},
|
|
118
115
|
"type": "module",
|
|
119
116
|
"types": "./types/index.d.ts",
|
|
120
|
-
"version": "0.
|
|
117
|
+
"version": "0.31.0"
|
|
121
118
|
}
|
package/src/js/index.ts
CHANGED
package/src/js/queue.ts
CHANGED
|
@@ -1,16 +1,28 @@
|
|
|
1
|
-
|
|
1
|
+
declare global {
|
|
2
|
+
var _atomic_queued: Set<() => void>;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
if (globalThis._atomic_queued === undefined) {
|
|
6
|
+
const queued = new Set<() => void>();
|
|
7
|
+
|
|
8
|
+
Object.defineProperty(globalThis, '_atomic_queued', {
|
|
9
|
+
get() {
|
|
10
|
+
return queued;
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
}
|
|
2
14
|
|
|
3
15
|
/**
|
|
4
16
|
* Queues a callback to be executed at the next best time
|
|
5
17
|
*/
|
|
6
18
|
export function queue(callback: () => void): void {
|
|
7
|
-
|
|
19
|
+
_atomic_queued.add(callback);
|
|
8
20
|
|
|
9
|
-
if (
|
|
21
|
+
if (_atomic_queued.size > 0) {
|
|
10
22
|
queueMicrotask(() => {
|
|
11
|
-
const callbacks = Array.from(
|
|
23
|
+
const callbacks = Array.from(_atomic_queued);
|
|
12
24
|
|
|
13
|
-
|
|
25
|
+
_atomic_queued.clear();
|
|
14
26
|
|
|
15
27
|
for (const callback of callbacks) {
|
|
16
28
|
callback();
|
package/src/js/timer.ts
CHANGED
|
@@ -39,6 +39,8 @@ type TimerState = {
|
|
|
39
39
|
|
|
40
40
|
type WorkType = 'restart' | 'start' | 'stop';
|
|
41
41
|
|
|
42
|
+
let milliseconds = 0;
|
|
43
|
+
|
|
42
44
|
/**
|
|
43
45
|
* A timer that can be started, stopped, and restarted as neeeded
|
|
44
46
|
*/
|
|
@@ -154,9 +156,13 @@ function work(
|
|
|
154
156
|
state.active = true;
|
|
155
157
|
|
|
156
158
|
const isRepeated = count > 0;
|
|
157
|
-
const milliseconds = 1000 / 60;
|
|
158
159
|
|
|
159
160
|
let index = 0;
|
|
161
|
+
let total = count * interval;
|
|
162
|
+
|
|
163
|
+
if (total < milliseconds) {
|
|
164
|
+
total = milliseconds;
|
|
165
|
+
}
|
|
160
166
|
|
|
161
167
|
let start: DOMHighResTimeStamp | undefined;
|
|
162
168
|
|
|
@@ -168,17 +174,16 @@ function work(
|
|
|
168
174
|
start ??= timestamp;
|
|
169
175
|
|
|
170
176
|
const elapsed = timestamp - start;
|
|
171
|
-
const
|
|
172
|
-
const minimum = elapsed - milliseconds;
|
|
177
|
+
const finished = elapsed >= total;
|
|
173
178
|
|
|
174
|
-
if (
|
|
179
|
+
if (finished || (elapsed - 2 < interval && interval < elapsed + 2)) {
|
|
175
180
|
if (state.active) {
|
|
176
181
|
callback((isRepeated ? index : undefined) as never);
|
|
177
182
|
}
|
|
178
183
|
|
|
179
184
|
index += 1;
|
|
180
185
|
|
|
181
|
-
if (index < count) {
|
|
186
|
+
if (!finished && index < count) {
|
|
182
187
|
start = undefined;
|
|
183
188
|
} else {
|
|
184
189
|
state.active = false;
|
|
@@ -197,3 +202,22 @@ function work(
|
|
|
197
202
|
|
|
198
203
|
return timer;
|
|
199
204
|
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Called immediately to calculate an approximate refresh rate in milliseconds
|
|
208
|
+
*/
|
|
209
|
+
(() => {
|
|
210
|
+
let start: number;
|
|
211
|
+
|
|
212
|
+
function fn(time: number) {
|
|
213
|
+
if (start === undefined) {
|
|
214
|
+
start = time;
|
|
215
|
+
|
|
216
|
+
requestAnimationFrame(fn);
|
|
217
|
+
} else {
|
|
218
|
+
milliseconds = time - start;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
requestAnimationFrame(fn);
|
|
223
|
+
})();
|
package/types/index.d.ts
CHANGED
package/types/queue.d.ts
CHANGED
package/src/js/signal.ts
DELETED
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
import {queue} from './queue';
|
|
2
|
-
|
|
3
|
-
type InternalEffect = {
|
|
4
|
-
_active: boolean;
|
|
5
|
-
_callback: () => void;
|
|
6
|
-
_reactives: Set<InternalReactive>;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
type InternalReactive = {
|
|
10
|
-
_active: boolean;
|
|
11
|
-
_effects: Set<InternalEffect>;
|
|
12
|
-
_value: unknown;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* The base class for reactive values
|
|
17
|
-
*/
|
|
18
|
-
abstract class Reactive<T = unknown> {
|
|
19
|
-
protected _active = true;
|
|
20
|
-
protected _effects = new Set<InternalEffect>();
|
|
21
|
-
protected declare _value: T;
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* The current value
|
|
25
|
-
*/
|
|
26
|
-
abstract get value(): T;
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* The current value, returned without triggering computations or effects
|
|
30
|
-
*/
|
|
31
|
-
peek(): T {
|
|
32
|
-
return this._value;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Allows reactivity for value, if it was stopped
|
|
37
|
-
*/
|
|
38
|
-
abstract run(): void;
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Stops reactivity for value, if it's running
|
|
42
|
-
*/
|
|
43
|
-
abstract stop(): void;
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Returns the JSON representation of the value
|
|
47
|
-
*/
|
|
48
|
-
toJSON(): T {
|
|
49
|
-
return this.value;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Returns the string representation of the value
|
|
54
|
-
*/
|
|
55
|
-
toString(): string {
|
|
56
|
-
return String(this.value);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* A computed, reactive value
|
|
62
|
-
*/
|
|
63
|
-
class Computed<T> extends Reactive<T> {
|
|
64
|
-
private readonly _effect: Effect;
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* @inheritdoc
|
|
68
|
-
*/
|
|
69
|
-
get value(): T {
|
|
70
|
-
return getValue(this as never) as T;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
constructor(callback: () => T) {
|
|
74
|
-
super();
|
|
75
|
-
|
|
76
|
-
this._effect = effect(() => setValue(this as never, callback(), false));
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* @inheritdoc
|
|
81
|
-
*/
|
|
82
|
-
run(): void {
|
|
83
|
-
this._effect.run();
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* @inheritdoc
|
|
88
|
-
*/
|
|
89
|
-
stop(): void {
|
|
90
|
-
this._effect.stop();
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* A reactive effect
|
|
96
|
-
*/
|
|
97
|
-
class Effect {
|
|
98
|
-
private _active = false;
|
|
99
|
-
private readonly _reactives = new Set<InternalReactive>();
|
|
100
|
-
|
|
101
|
-
constructor(private readonly _callback: () => void) {
|
|
102
|
-
this.run();
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Starts and runs the effect, if it was stopped
|
|
107
|
-
*/
|
|
108
|
-
run(): void {
|
|
109
|
-
if (this._active) {
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
this._active = true;
|
|
114
|
-
|
|
115
|
-
const index = effects.push(this as never) - 1;
|
|
116
|
-
|
|
117
|
-
this._callback();
|
|
118
|
-
|
|
119
|
-
effects.splice(index, 1);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Stops the effect, if it's running
|
|
124
|
-
*/
|
|
125
|
-
stop(): void {
|
|
126
|
-
if (!this._active) {
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
this._active = false;
|
|
131
|
-
|
|
132
|
-
for (const value of this._reactives) {
|
|
133
|
-
value._effects.delete(this as never);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
this._reactives.clear();
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* A reactive value
|
|
142
|
-
*/
|
|
143
|
-
class Signal<T> extends Reactive<T> {
|
|
144
|
-
/**
|
|
145
|
-
* @inheritdoc
|
|
146
|
-
*/
|
|
147
|
-
get value(): T {
|
|
148
|
-
return getValue(this as never) as T;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Sets the value
|
|
153
|
-
*/
|
|
154
|
-
set value(value: T) {
|
|
155
|
-
setValue(this as never, value, false);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
constructor(protected readonly _value: T) {
|
|
159
|
-
super();
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* @inheritdoc
|
|
164
|
-
*/
|
|
165
|
-
run(): void {
|
|
166
|
-
if (this._active) {
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
this._active = true;
|
|
171
|
-
|
|
172
|
-
setValue(this as never, this._value, true);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* @inheritdoc
|
|
177
|
-
*/
|
|
178
|
-
stop(): void {
|
|
179
|
-
this._active = false;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const effects: InternalEffect[] = [];
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* Creates a computed, reactive value
|
|
187
|
-
*/
|
|
188
|
-
export function computed<T>(callback: () => T): Computed<T> {
|
|
189
|
-
return new Computed(callback);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Creates a reactive effect
|
|
194
|
-
*/
|
|
195
|
-
export function effect(callback: () => void): Effect {
|
|
196
|
-
return new Effect(callback);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
function getValue(reactive: InternalReactive): unknown {
|
|
200
|
-
const effect = effects[effects.length - 1];
|
|
201
|
-
|
|
202
|
-
if (effect !== undefined) {
|
|
203
|
-
reactive._effects.add(effect);
|
|
204
|
-
effect._reactives.add(reactive);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
return reactive._value;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* Is the value a computed, reactive value?
|
|
212
|
-
*/
|
|
213
|
-
export function isComputed(value: unknown): value is Computed<unknown> {
|
|
214
|
-
return value instanceof Computed;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Is the value a reactive effect?
|
|
219
|
-
*/
|
|
220
|
-
export function isEffect(value: unknown): value is Effect {
|
|
221
|
-
return value instanceof Effect;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* Is the value a reactive value?
|
|
226
|
-
*/
|
|
227
|
-
export function isReactive(value: unknown): value is Reactive<unknown> {
|
|
228
|
-
return value instanceof Computed || value instanceof Signal;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Is the value a reactive value?
|
|
233
|
-
*/
|
|
234
|
-
export function isSignal(value: unknown): value is Signal<unknown> {
|
|
235
|
-
return value instanceof Signal;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
function setValue<T>(reactive: InternalReactive, value: T, run: boolean): void {
|
|
239
|
-
if (!run && Object.is(value, reactive._value)) {
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
reactive._value = value;
|
|
244
|
-
|
|
245
|
-
if (reactive._active) {
|
|
246
|
-
for (const effect of reactive._effects) {
|
|
247
|
-
queue(effect._callback);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* Creates a reactive value
|
|
254
|
-
*/
|
|
255
|
-
export function signal<T>(value: T): Signal<T> {
|
|
256
|
-
return new Signal(value);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
export type {Computed, Effect, Reactive, Signal};
|
package/types/signal.d.ts
DELETED
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
type InternalEffect = {
|
|
2
|
-
_active: boolean;
|
|
3
|
-
_callback: () => void;
|
|
4
|
-
_reactives: Set<InternalReactive>;
|
|
5
|
-
};
|
|
6
|
-
type InternalReactive = {
|
|
7
|
-
_active: boolean;
|
|
8
|
-
_effects: Set<InternalEffect>;
|
|
9
|
-
_value: unknown;
|
|
10
|
-
};
|
|
11
|
-
/**
|
|
12
|
-
* The base class for reactive values
|
|
13
|
-
*/
|
|
14
|
-
declare abstract class Reactive<T = unknown> {
|
|
15
|
-
protected _active: boolean;
|
|
16
|
-
protected _effects: Set<InternalEffect>;
|
|
17
|
-
protected _value: T;
|
|
18
|
-
/**
|
|
19
|
-
* The current value
|
|
20
|
-
*/
|
|
21
|
-
abstract get value(): T;
|
|
22
|
-
/**
|
|
23
|
-
* The current value, returned without triggering computations or effects
|
|
24
|
-
*/
|
|
25
|
-
peek(): T;
|
|
26
|
-
/**
|
|
27
|
-
* Allows reactivity for value, if it was stopped
|
|
28
|
-
*/
|
|
29
|
-
abstract run(): void;
|
|
30
|
-
/**
|
|
31
|
-
* Stops reactivity for value, if it's running
|
|
32
|
-
*/
|
|
33
|
-
abstract stop(): void;
|
|
34
|
-
/**
|
|
35
|
-
* Returns the JSON representation of the value
|
|
36
|
-
*/
|
|
37
|
-
toJSON(): T;
|
|
38
|
-
/**
|
|
39
|
-
* Returns the string representation of the value
|
|
40
|
-
*/
|
|
41
|
-
toString(): string;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* A computed, reactive value
|
|
45
|
-
*/
|
|
46
|
-
declare class Computed<T> extends Reactive<T> {
|
|
47
|
-
private readonly _effect;
|
|
48
|
-
/**
|
|
49
|
-
* @inheritdoc
|
|
50
|
-
*/
|
|
51
|
-
get value(): T;
|
|
52
|
-
constructor(callback: () => T);
|
|
53
|
-
/**
|
|
54
|
-
* @inheritdoc
|
|
55
|
-
*/
|
|
56
|
-
run(): void;
|
|
57
|
-
/**
|
|
58
|
-
* @inheritdoc
|
|
59
|
-
*/
|
|
60
|
-
stop(): void;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* A reactive effect
|
|
64
|
-
*/
|
|
65
|
-
declare class Effect {
|
|
66
|
-
private readonly _callback;
|
|
67
|
-
private _active;
|
|
68
|
-
private readonly _reactives;
|
|
69
|
-
constructor(_callback: () => void);
|
|
70
|
-
/**
|
|
71
|
-
* Starts and runs the effect, if it was stopped
|
|
72
|
-
*/
|
|
73
|
-
run(): void;
|
|
74
|
-
/**
|
|
75
|
-
* Stops the effect, if it's running
|
|
76
|
-
*/
|
|
77
|
-
stop(): void;
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* A reactive value
|
|
81
|
-
*/
|
|
82
|
-
declare class Signal<T> extends Reactive<T> {
|
|
83
|
-
protected readonly _value: T;
|
|
84
|
-
/**
|
|
85
|
-
* @inheritdoc
|
|
86
|
-
*/
|
|
87
|
-
get value(): T;
|
|
88
|
-
/**
|
|
89
|
-
* Sets the value
|
|
90
|
-
*/
|
|
91
|
-
set value(value: T);
|
|
92
|
-
constructor(_value: T);
|
|
93
|
-
/**
|
|
94
|
-
* @inheritdoc
|
|
95
|
-
*/
|
|
96
|
-
run(): void;
|
|
97
|
-
/**
|
|
98
|
-
* @inheritdoc
|
|
99
|
-
*/
|
|
100
|
-
stop(): void;
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Creates a computed, reactive value
|
|
104
|
-
*/
|
|
105
|
-
export declare function computed<T>(callback: () => T): Computed<T>;
|
|
106
|
-
/**
|
|
107
|
-
* Creates a reactive effect
|
|
108
|
-
*/
|
|
109
|
-
export declare function effect(callback: () => void): Effect;
|
|
110
|
-
/**
|
|
111
|
-
* Is the value a computed, reactive value?
|
|
112
|
-
*/
|
|
113
|
-
export declare function isComputed(value: unknown): value is Computed<unknown>;
|
|
114
|
-
/**
|
|
115
|
-
* Is the value a reactive effect?
|
|
116
|
-
*/
|
|
117
|
-
export declare function isEffect(value: unknown): value is Effect;
|
|
118
|
-
/**
|
|
119
|
-
* Is the value a reactive value?
|
|
120
|
-
*/
|
|
121
|
-
export declare function isReactive(value: unknown): value is Reactive<unknown>;
|
|
122
|
-
/**
|
|
123
|
-
* Is the value a reactive value?
|
|
124
|
-
*/
|
|
125
|
-
export declare function isSignal(value: unknown): value is Signal<unknown>;
|
|
126
|
-
/**
|
|
127
|
-
* Creates a reactive value
|
|
128
|
-
*/
|
|
129
|
-
export declare function signal<T>(value: T): Signal<T>;
|
|
130
|
-
export type { Computed, Effect, Reactive, Signal };
|