vivth 0.9.3 → 0.10.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/README.md +15 -9
- package/index.mjs +2 -0
- package/package.json +1 -1
- package/src/class/$.mjs +15 -19
- package/src/class/Q.mjs +21 -11
- package/src/class/QFIFO.mjs +66 -0
- package/src/class/QUnique.mjs +75 -0
- package/src/class/Signal.mjs +23 -20
- package/src/function/NewPingFIFO.mjs +2 -69
- package/src/function/NewPingUnique.mjs +3 -66
- package/tsconfig.json +1 -1
- package/types/index.d.mts +2 -0
- package/types/src/class/$.d.mts +4 -8
- package/types/src/class/Q.d.mts +10 -3
- package/types/src/class/QFIFO.d.mts +47 -0
- package/types/src/class/QUnique.d.mts +46 -0
- package/types/src/class/Signal.d.mts +4 -10
- package/types/src/function/NewPingUnique.d.mts +1 -1
package/README.md
CHANGED
|
@@ -18,6 +18,8 @@ bun i vivth
|
|
|
18
18
|
- [$](#$)
|
|
19
19
|
- [Derived](#derived)
|
|
20
20
|
- [Q](#q)
|
|
21
|
+
- [QFIFO](#qfifo)
|
|
22
|
+
- [QUnique](#qunique)
|
|
21
23
|
- [Signal](#signal)
|
|
22
24
|
- [New$](#new$)
|
|
23
25
|
- [NewDerived](#newderived)
|
|
@@ -40,7 +42,19 @@ bun i vivth
|
|
|
40
42
|
|
|
41
43
|
<h2 id="q">Q</h2>
|
|
42
44
|
|
|
43
|
-
- class that containts static methods to generate Promise based `awaiter` inside async function, to prevent race condition, including but not limited to:
|
|
44
|
-
behaviour:
|
|
45
|
+
- class that containts static methods to generate Promise based `awaiter` inside async function, to prevent race condition, including but not limited to:
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
|
|
47
|
+
*) <sub>[go to exported list](#exported-api-and-type-list)</sub>
|
|
48
|
+
|
|
49
|
+
<h2 id="qfifo">QFIFO</h2>
|
|
50
|
+
|
|
51
|
+
```js
|
|
47
52
|
* @typedef {[callback:()=>(any|Promise<any>),debounce?:(number)]} queueFIFODetails
|
|
48
53
|
*/
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
54
|
+
|
|
55
|
+
*) <sub>[go to exported list](#exported-api-and-type-list)</sub>
|
|
56
|
+
|
|
57
|
+
<h2 id="qunique">QUnique</h2>
|
|
58
|
+
|
|
59
|
+
- a class for Queue;
|
|
52
|
-
for minimal total bundle size use `function` [NewPingUnique](#newpingunique) instead;
|
|
53
|
-
this class provides `QUnique.makeQClass`;
|
|
54
60
|
|
|
55
61
|
*) <sub>[go to exported list](#exported-api-and-type-list)</sub>
|
|
56
62
|
|
package/index.mjs
CHANGED
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
export { $ } from './src/class/$.mjs';
|
|
26
26
|
export { Derived } from './src/class/Derived.mjs';
|
|
27
27
|
export { Q } from './src/class/Q.mjs';
|
|
28
|
+
export { QFIFO } from './src/class/QFIFO.mjs';
|
|
29
|
+
export { QUnique } from './src/class/QUnique.mjs';
|
|
28
30
|
export { Signal } from './src/class/Signal.mjs';
|
|
29
31
|
export { New$ } from './src/function/New$.mjs';
|
|
30
32
|
export { NewDerived } from './src/function/NewDerived.mjs';
|
package/package.json
CHANGED
package/src/class/$.mjs
CHANGED
|
@@ -13,33 +13,29 @@ export class $ {
|
|
|
13
13
|
* @typedef {import('../class/Signal.mjs').Signal} Signal
|
|
14
14
|
*/
|
|
15
15
|
/**
|
|
16
|
-
* effects
|
|
17
16
|
* @type {Map<$, Set<Signal>>}
|
|
18
17
|
*/
|
|
19
|
-
static
|
|
18
|
+
static effects = new Map();
|
|
20
19
|
/**
|
|
21
|
-
* signalInstance
|
|
22
20
|
* @type {Map<Signal, Set<$>>}
|
|
23
21
|
*/
|
|
24
|
-
static
|
|
22
|
+
static mappedSignals = new Map();
|
|
25
23
|
/**
|
|
26
|
-
* activeSignalUponRegistering
|
|
27
24
|
* @type {Set<Signal>}
|
|
28
25
|
*/
|
|
29
|
-
static
|
|
26
|
+
static activeSignal = new Set();
|
|
30
27
|
/**
|
|
31
|
-
* isRegistering
|
|
32
28
|
* @type {boolean}
|
|
33
29
|
*/
|
|
34
|
-
static
|
|
30
|
+
static isRegistering = false;
|
|
35
31
|
/**
|
|
36
32
|
* @returns {void}
|
|
37
33
|
*/
|
|
38
34
|
remove$ = () => {
|
|
39
|
-
$.
|
|
40
|
-
$.
|
|
35
|
+
$.effects.get(this)?.forEach((signalInstance) => {
|
|
36
|
+
$.mappedSignals.get(signalInstance).delete(this);
|
|
41
37
|
});
|
|
42
|
-
$.
|
|
38
|
+
$.effects.set(this, new Set());
|
|
43
39
|
};
|
|
44
40
|
/**
|
|
45
41
|
* @type {()=>void}
|
|
@@ -51,22 +47,22 @@ export class $ {
|
|
|
51
47
|
constructor(effect) {
|
|
52
48
|
this.effect = effect;
|
|
53
49
|
NewPingFIFO(async () => {
|
|
54
|
-
$.
|
|
50
|
+
$.isRegistering = true;
|
|
55
51
|
if (isAsync(effect)) {
|
|
56
52
|
await effect();
|
|
57
53
|
} else {
|
|
58
54
|
effect();
|
|
59
55
|
}
|
|
60
|
-
$.
|
|
61
|
-
const signalInstances = $.
|
|
62
|
-
$.
|
|
56
|
+
$.isRegistering = false;
|
|
57
|
+
const signalInstances = $.activeSignal;
|
|
58
|
+
$.effects.set(this, $.activeSignal);
|
|
63
59
|
signalInstances.forEach((signal) => {
|
|
64
|
-
if (!$.
|
|
65
|
-
$.
|
|
60
|
+
if (!$.mappedSignals.has(signal)) {
|
|
61
|
+
$.mappedSignals.set(signal, new Set());
|
|
66
62
|
}
|
|
67
|
-
$.
|
|
63
|
+
$.mappedSignals.get(signal).add(this);
|
|
68
64
|
});
|
|
69
|
-
$.
|
|
65
|
+
$.activeSignal = new Set();
|
|
70
66
|
});
|
|
71
67
|
}
|
|
72
68
|
}
|
package/src/class/Q.mjs
CHANGED
|
@@ -25,16 +25,26 @@
|
|
|
25
25
|
* - behaviour:
|
|
26
26
|
* > - `fifo`: call all queued callback `first in first out` style;
|
|
27
27
|
* > - `unique`: call all queued callback with the same `uniqueID` `first in first out` style, if the `uniqueID` is different it will be called in parallel;
|
|
28
|
+
* - this class provides `Q.makeQClass`;
|
|
29
|
+
* >- this method will setup `Q` to use the inputed `uniqueMap`(as arg0) as centralized lookup for queue managed by `Q`;
|
|
30
|
+
* >- usefull to modify this class for browser runtime, since `vivth` cannot just refer to window, you can just add `window["someobject"]`: `Array<Map<any, Promise<any>>>` as lookups;
|
|
28
31
|
*/
|
|
29
32
|
export class Q {
|
|
33
|
+
/**
|
|
34
|
+
* @param {Map<any, Promise<any>>} uniqueMap
|
|
35
|
+
* @returns {typeof Q}
|
|
36
|
+
*/
|
|
37
|
+
static makeQClass = (uniqueMap) => {
|
|
38
|
+
Q.#unique = uniqueMap;
|
|
39
|
+
return Q;
|
|
40
|
+
};
|
|
30
41
|
/**
|
|
31
42
|
* @typedef {import('../types/anyButUndefined.type.mjs').anyButUndefined} anyButUndefined
|
|
32
43
|
*/
|
|
33
44
|
/**
|
|
34
|
-
* @private
|
|
35
45
|
* @type {Promise<void>}
|
|
36
46
|
*/
|
|
37
|
-
static
|
|
47
|
+
static #fifo = Promise.resolve();
|
|
38
48
|
/**
|
|
39
49
|
* Blocks execution for subsequent calls until the current one finishes.
|
|
40
50
|
* @returns {Promise<{resume:()=>void}>} Resolves when it's safe to proceed, returning a cleanup function
|
|
@@ -44,8 +54,8 @@ export class Q {
|
|
|
44
54
|
const next = new Promise((resolve) => {
|
|
45
55
|
resolveFn = resolve;
|
|
46
56
|
});
|
|
47
|
-
const prev = Q
|
|
48
|
-
Q
|
|
57
|
+
const prev = Q.#fifo;
|
|
58
|
+
Q.#fifo = next;
|
|
49
59
|
await prev;
|
|
50
60
|
return {
|
|
51
61
|
resume: () => {
|
|
@@ -56,7 +66,7 @@ export class Q {
|
|
|
56
66
|
/**
|
|
57
67
|
* @type {Map<any, Promise<any>>}
|
|
58
68
|
*/
|
|
59
|
-
static
|
|
69
|
+
static #unique = new Map();
|
|
60
70
|
/**
|
|
61
71
|
* Ensures that each id has only one task running at a time.
|
|
62
72
|
* Calls with the same id will wait for the previous call to finish.
|
|
@@ -64,23 +74,23 @@ export class Q {
|
|
|
64
74
|
* @returns {Promise<{resume:()=>void}>} Resolves when it's safe to proceed for the given id, returning a cleanup function
|
|
65
75
|
*/
|
|
66
76
|
static unique = async (id) => {
|
|
67
|
-
if (!Q.
|
|
68
|
-
Q.
|
|
77
|
+
if (!Q.#unique.has(id)) {
|
|
78
|
+
Q.#unique.set(id, Promise.resolve());
|
|
69
79
|
let resolveFn;
|
|
70
80
|
const next = new Promise((resolve) => {
|
|
71
81
|
resolveFn = resolve;
|
|
72
82
|
});
|
|
73
|
-
const prev = Q.
|
|
74
|
-
Q.
|
|
83
|
+
const prev = Q.#unique.get(id);
|
|
84
|
+
Q.#unique.set(id, next);
|
|
75
85
|
await prev;
|
|
76
86
|
return {
|
|
77
87
|
resume: () => {
|
|
78
88
|
resolveFn();
|
|
79
|
-
Q.
|
|
89
|
+
Q.#unique.delete(id);
|
|
80
90
|
},
|
|
81
91
|
};
|
|
82
92
|
} else {
|
|
83
|
-
const prev = Q.
|
|
93
|
+
const prev = Q.#unique.get(id);
|
|
84
94
|
await prev;
|
|
85
95
|
return await Q.unique(id);
|
|
86
96
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import { timeout } from '../common.mjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @description
|
|
7
|
+
* ```js
|
|
8
|
+
* /**
|
|
9
|
+
* * @typedef {[callback:()=>(any|Promise<any>),debounce?:(number)]} queueFIFODetails
|
|
10
|
+
* *[blank]/
|
|
11
|
+
* ```
|
|
12
|
+
* - a class for Queue;
|
|
13
|
+
* - for minimal total bundle size use `function` [NewPingFIFO](#newpingfifo) instead;
|
|
14
|
+
* - this class provides `QFIFO.makeQClass`;
|
|
15
|
+
* >- this method will setup `QFIFO` to use the inputed `queueArray`(as arg0) as centralized lookup for queue managed by `QFIFO`;
|
|
16
|
+
* >- usefull to modify this class for browser runtime, since `vivth` cannot just refer to window, you can just add `window["someobject"]`: `Array<queueFIFODetails>` as lookups;
|
|
17
|
+
*/
|
|
18
|
+
export class QFIFO {
|
|
19
|
+
/**
|
|
20
|
+
* @param {queueFIFODetails[]} queueArray
|
|
21
|
+
* @returns {typeof QFIFO}
|
|
22
|
+
*/
|
|
23
|
+
static makeQClass = (queueArray) => {
|
|
24
|
+
QFIFO.#queue = queueArray;
|
|
25
|
+
return QFIFO;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* @type {queueFIFODetails[]}
|
|
29
|
+
*/
|
|
30
|
+
static #queue = [];
|
|
31
|
+
/**
|
|
32
|
+
* @type {boolean}
|
|
33
|
+
*/
|
|
34
|
+
static #isRunning = false;
|
|
35
|
+
/**
|
|
36
|
+
* @type {(...queueFIFODetails:queueFIFODetails)=>void}
|
|
37
|
+
*/
|
|
38
|
+
static assign = (..._queue) => {
|
|
39
|
+
QFIFO.#push(_queue);
|
|
40
|
+
if (!QFIFO.#isRunning) {
|
|
41
|
+
QFIFO.#run();
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* @param {queueFIFODetails} _queue
|
|
46
|
+
*/
|
|
47
|
+
static #push = (_queue) => {
|
|
48
|
+
QFIFO.#queue.push(_queue);
|
|
49
|
+
};
|
|
50
|
+
static #run = async () => {
|
|
51
|
+
QFIFO.#isRunning = true;
|
|
52
|
+
while (QFIFO.#queue.length !== 0) {
|
|
53
|
+
const [callback, debounceMs = 0] = QFIFO.#queue[0];
|
|
54
|
+
QFIFO.#queue.shift();
|
|
55
|
+
await callback();
|
|
56
|
+
/**
|
|
57
|
+
* conditional debounce;
|
|
58
|
+
* queue FIFO messing up when have debouncer while `debounceMS` are set to 0;
|
|
59
|
+
*/
|
|
60
|
+
// if (debounceMs) {
|
|
61
|
+
await timeout(debounceMs);
|
|
62
|
+
// }
|
|
63
|
+
}
|
|
64
|
+
QFIFO.#isRunning = false;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import { timeout } from '../common.mjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @description
|
|
7
|
+
* - a class for Queue;
|
|
8
|
+
* - for minimal total bundle size use `function` [NewPingUnique](#newpingunique) instead;
|
|
9
|
+
* - this class provides `QUnique.makeQClass`;
|
|
10
|
+
* >- this method will setup `QUnique` to use the inputed `queueMap`(as arg0) as centralized lookup for queue managed by `QUnique`;
|
|
11
|
+
* >- usefull to modify this class for browser runtime, since `vivth` cannot just refer to window, you can just add `window["someobject"]`: `Map<any, [()=>Promise<any>,number]>` as lookups;
|
|
12
|
+
*/
|
|
13
|
+
export class QUnique {
|
|
14
|
+
/**
|
|
15
|
+
* @param {Map<any, [()=>Promise<any>,number]>} queueMap
|
|
16
|
+
* @returns {typeof QUnique}
|
|
17
|
+
*/
|
|
18
|
+
static makeQClass = (queueMap) => {
|
|
19
|
+
QUnique.#queue = queueMap;
|
|
20
|
+
return QUnique;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* @typedef {Object} queueUniqueObject
|
|
24
|
+
* @property {any} i
|
|
25
|
+
* @property {()=>(any|Promise<any>)} c
|
|
26
|
+
* @property {number} [d]
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* @type {Map<any, [()=>Promise<any>,number]>}
|
|
30
|
+
*/
|
|
31
|
+
static #queue = new Map();
|
|
32
|
+
/**
|
|
33
|
+
* @type {boolean}
|
|
34
|
+
*/
|
|
35
|
+
static #isRunning = false;
|
|
36
|
+
/**
|
|
37
|
+
* @type {(queueUniqueObject:queueUniqueObject)=>void}
|
|
38
|
+
*/
|
|
39
|
+
static assign = (_queue) => {
|
|
40
|
+
QUnique.#push(_queue);
|
|
41
|
+
if (!QUnique.#isRunning) {
|
|
42
|
+
QUnique.#run();
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* @param {queueUniqueObject} _queue
|
|
47
|
+
*/
|
|
48
|
+
static #push = (_queue) => {
|
|
49
|
+
const { i, c, d } = _queue;
|
|
50
|
+
QUnique.#queue.set(i, [c, d ? d : 0]);
|
|
51
|
+
};
|
|
52
|
+
static #run = async () => {
|
|
53
|
+
QUnique.#isRunning = true;
|
|
54
|
+
const keysIterator = QUnique.#queue.keys();
|
|
55
|
+
let keys = keysIterator.next();
|
|
56
|
+
while (!keys.done) {
|
|
57
|
+
const key = keys.value;
|
|
58
|
+
const q = QUnique.#queue.get(key);
|
|
59
|
+
if (!q) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const [callback, debounce] = q;
|
|
63
|
+
QUnique.#queue.delete(key);
|
|
64
|
+
/**
|
|
65
|
+
* debounce anyway;
|
|
66
|
+
* queue with unique id have characteristic of messing up when have no debouncer;
|
|
67
|
+
* especially when request comes too fast;
|
|
68
|
+
*/
|
|
69
|
+
await timeout(debounce);
|
|
70
|
+
await callback();
|
|
71
|
+
keys = keysIterator.next();
|
|
72
|
+
}
|
|
73
|
+
QUnique.#isRunning = false;
|
|
74
|
+
};
|
|
75
|
+
}
|
package/src/class/Signal.mjs
CHANGED
|
@@ -13,25 +13,24 @@ import { $ } from './$.mjs';
|
|
|
13
13
|
*/
|
|
14
14
|
export class Signal {
|
|
15
15
|
/**
|
|
16
|
-
* subscribed
|
|
17
16
|
* @protected
|
|
18
17
|
*/
|
|
19
|
-
get
|
|
20
|
-
return $.
|
|
18
|
+
get subscribed() {
|
|
19
|
+
return $.mappedSignals.get(this);
|
|
21
20
|
}
|
|
22
21
|
/**
|
|
23
22
|
* destroy all props
|
|
24
23
|
*/
|
|
25
24
|
unRef = () => {
|
|
26
25
|
this.removeAll$();
|
|
27
|
-
this
|
|
26
|
+
this.#Value = null;
|
|
28
27
|
};
|
|
29
28
|
/**
|
|
30
29
|
* remove all effects
|
|
31
30
|
* @return {void}
|
|
32
31
|
*/
|
|
33
32
|
removeAll$ = () => {
|
|
34
|
-
this.
|
|
33
|
+
this.subscribed?.forEach(($_) => {
|
|
35
34
|
$_.remove$();
|
|
36
35
|
});
|
|
37
36
|
};
|
|
@@ -41,7 +40,7 @@ export class Signal {
|
|
|
41
40
|
* @return {void}
|
|
42
41
|
*/
|
|
43
42
|
remove$ = ($_) => {
|
|
44
|
-
if ($.
|
|
43
|
+
if ($.effects.get($_)?.has(this)) {
|
|
45
44
|
$_.remove$();
|
|
46
45
|
}
|
|
47
46
|
};
|
|
@@ -49,48 +48,52 @@ export class Signal {
|
|
|
49
48
|
* @param {Value} value
|
|
50
49
|
*/
|
|
51
50
|
constructor(value) {
|
|
52
|
-
this
|
|
51
|
+
this.#Value = value;
|
|
53
52
|
}
|
|
54
53
|
/**
|
|
55
|
-
* @private
|
|
56
54
|
* @type {Value}
|
|
57
55
|
*/
|
|
58
|
-
|
|
56
|
+
#prev = undefined;
|
|
59
57
|
get prev() {
|
|
60
|
-
return this
|
|
58
|
+
return this.#prev;
|
|
61
59
|
}
|
|
62
60
|
/**
|
|
63
|
-
* @private
|
|
64
61
|
* @type {Value}
|
|
65
62
|
*/
|
|
66
|
-
|
|
63
|
+
#Value;
|
|
64
|
+
/**
|
|
65
|
+
* @type {Value}
|
|
66
|
+
*/
|
|
67
|
+
get nonReactiveValue() {
|
|
68
|
+
return this.#Value;
|
|
69
|
+
}
|
|
67
70
|
/**
|
|
68
71
|
* @type {Value}
|
|
69
72
|
*/
|
|
70
73
|
get value() {
|
|
71
|
-
if ($.
|
|
72
|
-
$.
|
|
74
|
+
if ($.isRegistering) {
|
|
75
|
+
$.activeSignal.add(this);
|
|
73
76
|
}
|
|
74
|
-
return this
|
|
77
|
+
return this.#Value;
|
|
75
78
|
}
|
|
76
79
|
/**
|
|
77
80
|
* @type {Value}
|
|
78
81
|
*/
|
|
79
82
|
set value(newValue) {
|
|
80
|
-
if (this
|
|
83
|
+
if (this.#Value === newValue) {
|
|
81
84
|
return;
|
|
82
85
|
}
|
|
83
|
-
this
|
|
84
|
-
this
|
|
86
|
+
this.#prev = this.#Value;
|
|
87
|
+
this.#Value = newValue;
|
|
85
88
|
this.call$();
|
|
86
89
|
}
|
|
87
90
|
/**
|
|
88
91
|
* @returns {void}
|
|
89
92
|
*/
|
|
90
93
|
call$ = () => {
|
|
91
|
-
if (!this.
|
|
94
|
+
if (!this.subscribed) {
|
|
92
95
|
return;
|
|
93
96
|
}
|
|
94
|
-
this.
|
|
97
|
+
this.subscribed.forEach(($_) => $_.effect());
|
|
95
98
|
};
|
|
96
99
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { QFIFO } from '../class/QFIFO.mjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @description
|
|
@@ -16,76 +16,9 @@ import { timeout } from '../common.mjs';
|
|
|
16
16
|
* }
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
|
-
class qFIFO {
|
|
20
|
-
static {
|
|
21
|
-
new qFIFO();
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* @typedef {[callback:()=>(any|Promise<any>),debounce?:(number)]} queueFIFODetails
|
|
25
|
-
*/
|
|
26
|
-
/**
|
|
27
|
-
* @private
|
|
28
|
-
*/
|
|
29
|
-
constructor() {}
|
|
30
|
-
/**
|
|
31
|
-
* queue
|
|
32
|
-
* @private
|
|
33
|
-
* @type {queueFIFODetails[]}
|
|
34
|
-
*/
|
|
35
|
-
static q = [];
|
|
36
|
-
/**
|
|
37
|
-
* isRunning
|
|
38
|
-
* @private
|
|
39
|
-
* @type {boolean}
|
|
40
|
-
*/
|
|
41
|
-
static R = false;
|
|
42
|
-
/**
|
|
43
|
-
* auto initiator
|
|
44
|
-
* @private
|
|
45
|
-
*/
|
|
46
|
-
/**
|
|
47
|
-
* assign
|
|
48
|
-
* @type {(...queueFIFODetails:queueFIFODetails)=>void}
|
|
49
|
-
*/
|
|
50
|
-
static a = (..._queue) => {
|
|
51
|
-
qFIFO.p(_queue);
|
|
52
|
-
if (!qFIFO.R) {
|
|
53
|
-
qFIFO.r();
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
/**
|
|
57
|
-
* push
|
|
58
|
-
* @private
|
|
59
|
-
* @param {queueFIFODetails} _queue
|
|
60
|
-
*/
|
|
61
|
-
static p = (_queue) => {
|
|
62
|
-
qFIFO.q.push(_queue);
|
|
63
|
-
};
|
|
64
|
-
/**
|
|
65
|
-
* run
|
|
66
|
-
* @private
|
|
67
|
-
*/
|
|
68
|
-
static r = async () => {
|
|
69
|
-
qFIFO.R = true;
|
|
70
|
-
while (qFIFO.q.length !== 0) {
|
|
71
|
-
const [callback, debounceMs = 0] = qFIFO.q[0];
|
|
72
|
-
qFIFO.q.shift();
|
|
73
|
-
await callback();
|
|
74
|
-
/**
|
|
75
|
-
* conditional debounce;
|
|
76
|
-
* queue FIFO messing up when have debouncer while `debounceMS` are set to 0;
|
|
77
|
-
*/
|
|
78
|
-
// if (debounceMs) {
|
|
79
|
-
await timeout(debounceMs);
|
|
80
|
-
// }
|
|
81
|
-
}
|
|
82
|
-
qFIFO.R = false;
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
|
|
86
19
|
/**
|
|
87
20
|
* @param {()=>(any|Promise<any>)} callback
|
|
88
21
|
* @param {number} debounce
|
|
89
22
|
* @returns
|
|
90
23
|
*/
|
|
91
|
-
export const NewPingFIFO = (callback, debounce = 0) =>
|
|
24
|
+
export const NewPingFIFO = (callback, debounce = 0) => QFIFO.assign(callback, debounce);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { QUnique } from '../../index.mjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @description
|
|
@@ -19,74 +19,11 @@ import { timeout } from '../common.mjs';
|
|
|
19
19
|
* }
|
|
20
20
|
* ```
|
|
21
21
|
*/
|
|
22
|
-
class qUnique {
|
|
23
|
-
/**
|
|
24
|
-
* @typedef {import('../types/anyButUndefined.type.mjs').anyButUndefined} anyButUndefined
|
|
25
|
-
* @typedef {Object} queueUniqueObject
|
|
26
|
-
* @property {any} i
|
|
27
|
-
* @property {()=>(any|Promise<any>)} c
|
|
28
|
-
* @property {number} [d]
|
|
29
|
-
*/
|
|
30
|
-
/**
|
|
31
|
-
* @private
|
|
32
|
-
* @type {Map<any, [()=>Promise<any>,number]>}
|
|
33
|
-
*/
|
|
34
|
-
static queue = new Map();
|
|
35
|
-
/**
|
|
36
|
-
* isRunning
|
|
37
|
-
* @private
|
|
38
|
-
* @type {boolean}
|
|
39
|
-
*/
|
|
40
|
-
static r = false;
|
|
41
|
-
/**
|
|
42
|
-
* assign
|
|
43
|
-
* @type {(queueUniqueObject:queueUniqueObject)=>void}
|
|
44
|
-
*/
|
|
45
|
-
static A = (_queue) => {
|
|
46
|
-
qUnique.p(_queue);
|
|
47
|
-
if (!qUnique.r) {
|
|
48
|
-
qUnique.R();
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
/**
|
|
52
|
-
* push
|
|
53
|
-
* @private
|
|
54
|
-
* @param {queueUniqueObject} _queue
|
|
55
|
-
*/
|
|
56
|
-
static p = (_queue) => {
|
|
57
|
-
const { i, c, d } = _queue;
|
|
58
|
-
qUnique.queue.set(i, [c, d ? d : 0]);
|
|
59
|
-
};
|
|
60
|
-
/**
|
|
61
|
-
* run
|
|
62
|
-
* @private
|
|
63
|
-
*/
|
|
64
|
-
static R = async () => {
|
|
65
|
-
qUnique.r = true;
|
|
66
|
-
const keysIterator = qUnique.queue.keys();
|
|
67
|
-
let keys = keysIterator.next();
|
|
68
|
-
while (!keys.done) {
|
|
69
|
-
const key = keys.value;
|
|
70
|
-
const [callback, debounce] = qUnique.queue.get(key);
|
|
71
|
-
qUnique.queue.delete(key);
|
|
72
|
-
/**
|
|
73
|
-
* debounce anyway;
|
|
74
|
-
* queue with unique id have characteristic of messing up when have no debouncer;
|
|
75
|
-
* especially when request comes too fast;
|
|
76
|
-
*/
|
|
77
|
-
await timeout(debounce);
|
|
78
|
-
await callback();
|
|
79
|
-
keys = keysIterator.next();
|
|
80
|
-
}
|
|
81
|
-
qUnique.r = false;
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
|
|
85
22
|
/**
|
|
86
|
-
* @param {anyButUndefined} uniqueID
|
|
23
|
+
* @param {import('../../index.mjs').anyButUndefined} uniqueID
|
|
87
24
|
* @param {()=>(any|Promise<any>)} callback
|
|
88
25
|
* @param {number} debounce
|
|
89
26
|
* @returns
|
|
90
27
|
*/
|
|
91
28
|
export const NewPingUnique = (uniqueID, callback, debounce = 0) =>
|
|
92
|
-
|
|
29
|
+
QUnique.assign({ i: uniqueID, c: callback, d: debounce });
|
package/tsconfig.json
CHANGED
package/types/index.d.mts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { $ } from "./src/class/$.mjs";
|
|
2
2
|
export { Derived } from "./src/class/Derived.mjs";
|
|
3
3
|
export { Q } from "./src/class/Q.mjs";
|
|
4
|
+
export { QFIFO } from "./src/class/QFIFO.mjs";
|
|
5
|
+
export { QUnique } from "./src/class/QUnique.mjs";
|
|
4
6
|
export { Signal } from "./src/class/Signal.mjs";
|
|
5
7
|
export { New$ } from "./src/function/New$.mjs";
|
|
6
8
|
export { NewDerived } from "./src/function/NewDerived.mjs";
|
package/types/src/class/$.d.mts
CHANGED
|
@@ -8,25 +8,21 @@ export class $ {
|
|
|
8
8
|
* @typedef {import('../class/Signal.mjs').Signal} Signal
|
|
9
9
|
*/
|
|
10
10
|
/**
|
|
11
|
-
* effects
|
|
12
11
|
* @type {Map<$, Set<Signal>>}
|
|
13
12
|
*/
|
|
14
|
-
static
|
|
13
|
+
static effects: Map<$, Set<import("../class/Signal.mjs").Signal<any>>>;
|
|
15
14
|
/**
|
|
16
|
-
* signalInstance
|
|
17
15
|
* @type {Map<Signal, Set<$>>}
|
|
18
16
|
*/
|
|
19
|
-
static
|
|
17
|
+
static mappedSignals: Map<import("../class/Signal.mjs").Signal<any>, Set<$>>;
|
|
20
18
|
/**
|
|
21
|
-
* activeSignalUponRegistering
|
|
22
19
|
* @type {Set<Signal>}
|
|
23
20
|
*/
|
|
24
|
-
static
|
|
21
|
+
static activeSignal: Set<import("../class/Signal.mjs").Signal<any>>;
|
|
25
22
|
/**
|
|
26
|
-
* isRegistering
|
|
27
23
|
* @type {boolean}
|
|
28
24
|
*/
|
|
29
|
-
static
|
|
25
|
+
static isRegistering: boolean;
|
|
30
26
|
/**
|
|
31
27
|
* @param {$["effect"]} effect
|
|
32
28
|
*/
|
package/types/src/class/Q.d.mts
CHANGED
|
@@ -23,16 +23,23 @@
|
|
|
23
23
|
* - behaviour:
|
|
24
24
|
* > - `fifo`: call all queued callback `first in first out` style;
|
|
25
25
|
* > - `unique`: call all queued callback with the same `uniqueID` `first in first out` style, if the `uniqueID` is different it will be called in parallel;
|
|
26
|
+
* - this class provides `Q.makeQClass`;
|
|
27
|
+
* >- this method will setup `Q` to use the inputed `uniqueMap`(as arg0) as centralized lookup for queue managed by `Q`;
|
|
28
|
+
* >- usefull to modify this class for browser runtime, since `vivth` cannot just refer to window, you can just add `window["someobject"]`: `Array<Map<any, Promise<any>>>` as lookups;
|
|
26
29
|
*/
|
|
27
30
|
export class Q {
|
|
31
|
+
/**
|
|
32
|
+
* @param {Map<any, Promise<any>>} uniqueMap
|
|
33
|
+
* @returns {typeof Q}
|
|
34
|
+
*/
|
|
35
|
+
static makeQClass: (uniqueMap: Map<any, Promise<any>>) => typeof Q;
|
|
28
36
|
/**
|
|
29
37
|
* @typedef {import('../types/anyButUndefined.type.mjs').anyButUndefined} anyButUndefined
|
|
30
38
|
*/
|
|
31
39
|
/**
|
|
32
|
-
* @private
|
|
33
40
|
* @type {Promise<void>}
|
|
34
41
|
*/
|
|
35
|
-
|
|
42
|
+
static "__#3@#fifo": Promise<void>;
|
|
36
43
|
/**
|
|
37
44
|
* Blocks execution for subsequent calls until the current one finishes.
|
|
38
45
|
* @returns {Promise<{resume:()=>void}>} Resolves when it's safe to proceed, returning a cleanup function
|
|
@@ -43,7 +50,7 @@ export class Q {
|
|
|
43
50
|
/**
|
|
44
51
|
* @type {Map<any, Promise<any>>}
|
|
45
52
|
*/
|
|
46
|
-
static
|
|
53
|
+
static "__#3@#unique": Map<any, Promise<any>>;
|
|
47
54
|
/**
|
|
48
55
|
* Ensures that each id has only one task running at a time.
|
|
49
56
|
* Calls with the same id will wait for the previous call to finish.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description
|
|
3
|
+
* ```js
|
|
4
|
+
* /**
|
|
5
|
+
* * @typedef {[callback:()=>(any|Promise<any>),debounce?:(number)]} queueFIFODetails
|
|
6
|
+
* *[blank]/
|
|
7
|
+
* ```
|
|
8
|
+
* - a class for Queue;
|
|
9
|
+
* - for minimal total bundle size use `function` [NewPingFIFO](#newpingfifo) instead;
|
|
10
|
+
* - this class provides `QFIFO.makeQClass`;
|
|
11
|
+
* >- this method will setup `QFIFO` to use the inputed `queueArray`(as arg0) as centralized lookup for queue managed by `QFIFO`;
|
|
12
|
+
* >- usefull to modify this class for browser runtime, since `vivth` cannot just refer to window, you can just add `window["someobject"]`: `Array<queueFIFODetails>` as lookups;
|
|
13
|
+
*/
|
|
14
|
+
export class QFIFO {
|
|
15
|
+
/**
|
|
16
|
+
* @param {queueFIFODetails[]} queueArray
|
|
17
|
+
* @returns {typeof QFIFO}
|
|
18
|
+
*/
|
|
19
|
+
static makeQClass: (queueArray: queueFIFODetails[]) => typeof QFIFO;
|
|
20
|
+
/**
|
|
21
|
+
* @type {queueFIFODetails[]}
|
|
22
|
+
*/
|
|
23
|
+
static "__#1@#queue": queueFIFODetails[];
|
|
24
|
+
/**
|
|
25
|
+
* @type {boolean}
|
|
26
|
+
*/
|
|
27
|
+
static "__#1@#isRunning": boolean;
|
|
28
|
+
/**
|
|
29
|
+
* @type {(...queueFIFODetails:queueFIFODetails)=>void}
|
|
30
|
+
*/
|
|
31
|
+
static assign: (...queueFIFODetails: queueFIFODetails) => void;
|
|
32
|
+
/**
|
|
33
|
+
* @param {queueFIFODetails} _queue
|
|
34
|
+
*/
|
|
35
|
+
static "__#1@#push": (_queue: queueFIFODetails) => void;
|
|
36
|
+
static "__#1@#run": () => Promise<void>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* *[blank]/
|
|
40
|
+
* ```
|
|
41
|
+
* - a class for Queue;
|
|
42
|
+
* - for minimal total bundle size use `function` [NewPingFIFO](#newpingfifo) instead;
|
|
43
|
+
* - this class provides `QFIFO.makeQClass`;
|
|
44
|
+
* >- this method will setup `QFIFO` to use the inputed `queueArray`(as arg0) as centralized lookup for queue managed by `QFIFO`;
|
|
45
|
+
* >- usefull to modify this class for browser runtime, since `vivth` cannot just refer to window, you can just add `window["someobject"]`: `Array<queueFIFODetails>` as lookups;
|
|
46
|
+
*/
|
|
47
|
+
export type queueFIFODetails = [callback: () => (any | Promise<any>), debounce?: (number)];
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description
|
|
3
|
+
* - a class for Queue;
|
|
4
|
+
* - for minimal total bundle size use `function` [NewPingUnique](#newpingunique) instead;
|
|
5
|
+
* - this class provides `QUnique.makeQClass`;
|
|
6
|
+
* >- this method will setup `QUnique` to use the inputed `queueMap`(as arg0) as centralized lookup for queue managed by `QUnique`;
|
|
7
|
+
* >- usefull to modify this class for browser runtime, since `vivth` cannot just refer to window, you can just add `window["someobject"]`: `Map<any, [()=>Promise<any>,number]>` as lookups;
|
|
8
|
+
*/
|
|
9
|
+
export class QUnique {
|
|
10
|
+
/**
|
|
11
|
+
* @param {Map<any, [()=>Promise<any>,number]>} queueMap
|
|
12
|
+
* @returns {typeof QUnique}
|
|
13
|
+
*/
|
|
14
|
+
static makeQClass: (queueMap: Map<any, [() => Promise<any>, number]>) => typeof QUnique;
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {Object} queueUniqueObject
|
|
17
|
+
* @property {any} i
|
|
18
|
+
* @property {()=>(any|Promise<any>)} c
|
|
19
|
+
* @property {number} [d]
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* @type {Map<any, [()=>Promise<any>,number]>}
|
|
23
|
+
*/
|
|
24
|
+
static "__#4@#queue": Map<any, [() => Promise<any>, number]>;
|
|
25
|
+
/**
|
|
26
|
+
* @type {boolean}
|
|
27
|
+
*/
|
|
28
|
+
static "__#4@#isRunning": boolean;
|
|
29
|
+
/**
|
|
30
|
+
* @type {(queueUniqueObject:queueUniqueObject)=>void}
|
|
31
|
+
*/
|
|
32
|
+
static assign: (queueUniqueObject: {
|
|
33
|
+
i: any;
|
|
34
|
+
c: () => (any | Promise<any>);
|
|
35
|
+
d?: number;
|
|
36
|
+
}) => void;
|
|
37
|
+
/**
|
|
38
|
+
* @param {queueUniqueObject} _queue
|
|
39
|
+
*/
|
|
40
|
+
static "__#4@#push": (_queue: {
|
|
41
|
+
i: any;
|
|
42
|
+
c: () => (any | Promise<any>);
|
|
43
|
+
d?: number;
|
|
44
|
+
}) => void;
|
|
45
|
+
static "__#4@#run": () => Promise<void>;
|
|
46
|
+
}
|
|
@@ -13,19 +13,13 @@ export class Signal<Value> {
|
|
|
13
13
|
*/
|
|
14
14
|
constructor(value: Value);
|
|
15
15
|
/**
|
|
16
|
-
* subscribed
|
|
17
16
|
* @protected
|
|
18
17
|
*/
|
|
19
|
-
protected get
|
|
18
|
+
protected get subscribed(): Set<$>;
|
|
20
19
|
/**
|
|
21
20
|
* destroy all props
|
|
22
21
|
*/
|
|
23
22
|
unRef: () => void;
|
|
24
|
-
/**
|
|
25
|
-
* @private
|
|
26
|
-
* @type {Value}
|
|
27
|
-
*/
|
|
28
|
-
private V;
|
|
29
23
|
/**
|
|
30
24
|
* remove all effects
|
|
31
25
|
* @return {void}
|
|
@@ -37,12 +31,11 @@ export class Signal<Value> {
|
|
|
37
31
|
* @return {void}
|
|
38
32
|
*/
|
|
39
33
|
remove$: ($_: $) => void;
|
|
34
|
+
get prev(): Value;
|
|
40
35
|
/**
|
|
41
|
-
* @private
|
|
42
36
|
* @type {Value}
|
|
43
37
|
*/
|
|
44
|
-
|
|
45
|
-
get prev(): Value;
|
|
38
|
+
get nonReactiveValue(): Value;
|
|
46
39
|
/**
|
|
47
40
|
* @type {Value}
|
|
48
41
|
*/
|
|
@@ -55,5 +48,6 @@ export class Signal<Value> {
|
|
|
55
48
|
* @returns {void}
|
|
56
49
|
*/
|
|
57
50
|
call$: () => void;
|
|
51
|
+
#private;
|
|
58
52
|
}
|
|
59
53
|
import { $ } from './$.mjs';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export function NewPingUnique(uniqueID: import("
|
|
1
|
+
export function NewPingUnique(uniqueID: import("../../index.mjs").anyButUndefined, callback: () => (any | Promise<any>), debounce?: number): void;
|