vivth 0.11.1 → 1.0.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/.vivth/dist/init.mjs +24 -0
- package/README.md +2157 -69
- package/README.src.md +35 -0
- package/bun.lock +57 -3
- package/dev/index.mjs +24 -25
- package/index.mjs +51 -29
- package/package.json +11 -7
- package/src/bundler/CompileMJS.mjs +110 -0
- package/src/bundler/EsBundler.mjs +79 -0
- package/src/class/Console.mjs +62 -0
- package/src/class/Derived.mjs +37 -21
- package/src/class/Effect.mjs +106 -0
- package/src/class/EnvSignal.mjs +88 -0
- package/src/class/EventSignal.mjs +200 -0
- package/src/class/ListDerived.mjs +39 -0
- package/src/class/ListSignal.mjs +256 -0
- package/src/class/Paths.mjs +70 -0
- package/src/class/QChannel.mjs +184 -0
- package/src/class/SafeExit.mjs +131 -0
- package/src/class/Setup.mjs +73 -0
- package/src/class/Signal.mjs +152 -54
- package/src/class/WorkerMainThread.mjs +328 -0
- package/src/class/WorkerResult.mjs +30 -0
- package/src/class/WorkerThread.mjs +151 -0
- package/src/common/Base64URL.mjs +26 -0
- package/src/common/EventNameSpace.mjs +8 -0
- package/src/common/eventObjects.mjs +5 -0
- package/src/common/lazie.mjs +3 -0
- package/src/doc/JSautoDOC.mjs +386 -0
- package/src/doc/parsedFile.mjs +537 -0
- package/src/function/CreateImmutable.mjs +64 -0
- package/src/function/EventCheck.mjs +27 -0
- package/src/function/EventObject.mjs +21 -0
- package/src/function/IsAsync.mjs +23 -0
- package/src/function/LazyFactory.mjs +71 -0
- package/src/function/Timeout.mjs +23 -0
- package/src/function/Try.mjs +64 -0
- package/src/function/TryAsync.mjs +15 -4
- package/src/function/TrySync.mjs +9 -4
- package/src/function/TsToMjs.mjs +67 -0
- package/src/function/WriteFileSafe.mjs +37 -0
- package/src/types/{AnyButUndefined.type.mjs → AnyButUndefined.mjs} +1 -0
- package/src/types/ExtnameType.mjs +6 -0
- package/src/types/IsListSignal.mjs +6 -0
- package/src/types/ListArg.mjs +6 -0
- package/src/types/MutationType.mjs +8 -0
- package/src/types/QCBFIFOReturn.mjs +6 -0
- package/src/types/QCBReturn.mjs +6 -0
- package/tsconfig.json +3 -3
- package/types/dev/index.d.mts +1 -0
- package/types/index.d.mts +34 -8
- package/types/src/bundler/A.d.mts +1 -0
- package/types/src/bundler/CompileMJS.d.mts +8 -0
- package/types/src/bundler/EsBundler.d.mts +7 -0
- package/types/src/class/Console.d.mts +40 -0
- package/types/src/class/Derived.d.mts +21 -7
- package/types/src/class/Effect.d.mts +77 -0
- package/types/src/class/EnvSignal.d.mts +47 -0
- package/types/src/class/EventSignal.d.mts +145 -0
- package/types/src/class/ListDerived.d.mts +35 -0
- package/types/src/class/ListSignal.d.mts +150 -0
- package/types/src/class/Paths.d.mts +50 -0
- package/types/src/class/QChannel.d.mts +115 -0
- package/types/src/class/SafeExit.d.mts +76 -0
- package/types/src/class/Setup.d.mts +76 -0
- package/types/src/class/Signal.d.mts +105 -26
- package/types/src/class/WorkerMainThread.d.mts +149 -0
- package/types/src/class/WorkerResult.d.mts +25 -0
- package/types/src/class/WorkerThread.d.mts +70 -0
- package/types/src/common/Base64URL.d.mts +1 -0
- package/types/src/common/EventNameSpace.d.mts +6 -0
- package/types/src/common/eventObjects.d.mts +3 -0
- package/types/src/common/lazie.d.mts +1 -0
- package/types/src/doc/JSautoDOC.d.mts +76 -0
- package/types/src/doc/parsedFile.d.mts +154 -0
- package/types/src/function/CreateImmutable.d.mts +3 -0
- package/types/src/function/EventCheck.d.mts +2 -0
- package/types/src/function/EventObject.d.mts +4 -0
- package/types/src/function/IsAsync.d.mts +1 -0
- package/types/src/function/LazyFactory.d.mts +4 -0
- package/types/src/function/Timeout.d.mts +1 -0
- package/types/src/function/Try.d.mts +1 -0
- package/types/src/function/TsToMjs.d.mts +4 -0
- package/types/src/function/WriteFileSafe.d.mts +2 -0
- package/types/src/types/{AnyButUndefined.type.d.mts → AnyButUndefined.d.mts} +3 -0
- package/types/src/types/ExtnameType.d.mts +4 -0
- package/types/src/types/IsListSignal.d.mts +4 -0
- package/types/src/types/ListArg.d.mts +4 -0
- package/types/src/types/MutationType.d.mts +5 -0
- package/types/src/types/QCBFIFOReturn.d.mts +4 -0
- package/types/src/types/QCBReturn.d.mts +7 -0
- package/src/class/$.mjs +0 -68
- package/src/class/PingFIFO.mjs +0 -78
- package/src/class/PingUnique.mjs +0 -84
- package/src/class/Q.mjs +0 -98
- package/src/class/QFIFO.mjs +0 -66
- package/src/class/QUnique.mjs +0 -75
- package/src/common.mjs +0 -16
- package/src/function/NewQBlock.mjs +0 -39
- package/types/src/class/$.d.mts +0 -38
- package/types/src/class/PingFIFO.d.mts +0 -57
- package/types/src/class/PingUnique.d.mts +0 -48
- package/types/src/class/Q.d.mts +0 -63
- package/types/src/class/QFIFO.d.mts +0 -47
- package/types/src/class/QUnique.d.mts +0 -46
- package/types/src/common.d.mts +0 -2
- package/types/src/function/NewQBlock.d.mts +0 -1
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description
|
|
3
|
+
* - Signal implementation for `CustomEvent`, to dispatch and listen;
|
|
4
|
+
* @template {IsListSignal} isList
|
|
5
|
+
* - boolean;
|
|
6
|
+
*/
|
|
7
|
+
export class EventSignal<isList extends boolean> {
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {import('../types/IsListSignal.mjs').IsListSignal} IsListSignal
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* @description
|
|
13
|
+
* - `Map` of `EventSignal`, using the `stringName` of the `EventSignal_instance` as `key`;
|
|
14
|
+
* @type {Map<string, EventSignal>}
|
|
15
|
+
*/
|
|
16
|
+
static map: Map<string, EventSignal<any>>;
|
|
17
|
+
/**
|
|
18
|
+
* @type {QChannel<string>}
|
|
19
|
+
*/
|
|
20
|
+
static "__#12261@#qChannelEventSignal": QChannel<string>;
|
|
21
|
+
/**
|
|
22
|
+
* @description
|
|
23
|
+
* - the constructor it self is set to `private`;
|
|
24
|
+
* - it's globally queued:
|
|
25
|
+
* >- the `Promise` nature is to prevent race condition on creating the instance;
|
|
26
|
+
* @param {string} stringName
|
|
27
|
+
* @param {IsListSignal} [isList_]
|
|
28
|
+
* @returns {Promise<EventSignal>}
|
|
29
|
+
* @example
|
|
30
|
+
* import { EventSignal } from 'vivth';
|
|
31
|
+
*
|
|
32
|
+
* const myEventSignal = await EventSignal.get('dataEvent');
|
|
33
|
+
*/
|
|
34
|
+
static get(stringName: string, isList_?: boolean): Promise<EventSignal<any>>;
|
|
35
|
+
/**
|
|
36
|
+
* @description
|
|
37
|
+
* - methods of this static property is lazily created;
|
|
38
|
+
* - remove signal and effect subscription of the named `EventSignal_instance`;
|
|
39
|
+
*/
|
|
40
|
+
static remove: {
|
|
41
|
+
/**
|
|
42
|
+
* @static remove
|
|
43
|
+
* @description
|
|
44
|
+
* - remove subscriber from the named `EventSignal_instance`;
|
|
45
|
+
* @param {string} name
|
|
46
|
+
* @param {import('./Effect.mjs').Effect} effect
|
|
47
|
+
* @returns {void}
|
|
48
|
+
* @example
|
|
49
|
+
* import { EventSignal } from 'vivth';
|
|
50
|
+
*
|
|
51
|
+
* EventSignal.remove.subscriber('yourEventSignalName', yourEffectInstance);
|
|
52
|
+
*/
|
|
53
|
+
subscriber: (name: string, effect: import("./Effect.mjs").Effect) => void;
|
|
54
|
+
/**
|
|
55
|
+
* @static remove
|
|
56
|
+
* @description
|
|
57
|
+
* - remove all subscribers from the named `EventSignal_instance`;
|
|
58
|
+
* @param {string} name
|
|
59
|
+
* @returns {void}
|
|
60
|
+
* @example
|
|
61
|
+
* import { EventSignal } from 'vivth';
|
|
62
|
+
*
|
|
63
|
+
* EventSignal.remove.allSubscribers('yourEventSignalName');
|
|
64
|
+
*/
|
|
65
|
+
allSubscribers: (name: string) => void;
|
|
66
|
+
/**
|
|
67
|
+
* @static remove
|
|
68
|
+
* @description
|
|
69
|
+
* - remove reference of the `proxySignals` of the named `EventSignal_instance`;
|
|
70
|
+
* @param {string} name
|
|
71
|
+
* @returns {void}
|
|
72
|
+
* @example
|
|
73
|
+
* import { EventSignal } from 'vivth';
|
|
74
|
+
*
|
|
75
|
+
* EventSignal.remove.refs('yourEventSignalName');
|
|
76
|
+
*/
|
|
77
|
+
refs: (name: string) => void;
|
|
78
|
+
} & {
|
|
79
|
+
"vivth:unwrapLazy;": string;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* @private
|
|
83
|
+
* @param {string} name
|
|
84
|
+
* @param {isList} [isList]
|
|
85
|
+
*/
|
|
86
|
+
private constructor();
|
|
87
|
+
/**
|
|
88
|
+
* @type {string}
|
|
89
|
+
*/
|
|
90
|
+
name: string;
|
|
91
|
+
/**
|
|
92
|
+
* @description
|
|
93
|
+
* - is [Signal](#signal) or [ListSignal](#listsignal) instance, depending on the `isList` argument;
|
|
94
|
+
* - if needed to pass along the messages, it can be used as `dispatcher` and `listener` at the same time;
|
|
95
|
+
* - is `lazily` created;
|
|
96
|
+
* @type {Signal|ListSignal}
|
|
97
|
+
*/
|
|
98
|
+
dispatch: Signal<any> | ListSignal<any>;
|
|
99
|
+
/**
|
|
100
|
+
* @description
|
|
101
|
+
* - is [Derived](#derived) or [ListDerived](#listderived) instance, depending on the `isList` argument;
|
|
102
|
+
* - can be used as listener when passed down value shouldn't be modified manually;
|
|
103
|
+
* - is `lazily` created along with `dispatch`, if `listen` is accessed first, then `dispatch` will also be created automatically;
|
|
104
|
+
* @type {Derived|ListDerived}
|
|
105
|
+
*/
|
|
106
|
+
listen: Derived<any> | ListDerived<any>;
|
|
107
|
+
remove: {
|
|
108
|
+
/**
|
|
109
|
+
* @instance remove
|
|
110
|
+
* @description
|
|
111
|
+
* - remove subscriber from the `EventSignal_instance`;
|
|
112
|
+
* @param {import('./Effect.mjs').Effect} effect
|
|
113
|
+
* @returns {void}
|
|
114
|
+
* @example
|
|
115
|
+
* eventSignal_instance.remove.subscriber(yourEffectInstance);
|
|
116
|
+
*/
|
|
117
|
+
subscriber: (effect: import("./Effect.mjs").Effect) => void;
|
|
118
|
+
/**
|
|
119
|
+
* @instance remove
|
|
120
|
+
* @description
|
|
121
|
+
* - remove allSubscribers from the `EventSignal_instance`;
|
|
122
|
+
* @type {()=>void}
|
|
123
|
+
* @example
|
|
124
|
+
* eventSignal_instance.remove.allSubscribers();
|
|
125
|
+
*/
|
|
126
|
+
allSubscribers: () => void;
|
|
127
|
+
/**
|
|
128
|
+
* @instance remove
|
|
129
|
+
* @description
|
|
130
|
+
* - remove reference of the `proxySignals` of the `EventSignal_instance`;
|
|
131
|
+
* @type {()=>void}
|
|
132
|
+
* @example
|
|
133
|
+
* eventSignal_instance.remove.ref();
|
|
134
|
+
*/
|
|
135
|
+
ref: () => void;
|
|
136
|
+
} & {
|
|
137
|
+
"vivth:unwrapLazy;": string;
|
|
138
|
+
};
|
|
139
|
+
#private;
|
|
140
|
+
}
|
|
141
|
+
import { Signal } from './Signal.mjs';
|
|
142
|
+
import { ListSignal } from './ListSignal.mjs';
|
|
143
|
+
import { Derived } from './Derived.mjs';
|
|
144
|
+
import { ListDerived } from './ListDerived.mjs';
|
|
145
|
+
import { QChannel } from './QChannel.mjs';
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description
|
|
3
|
+
* - class to create `dervivedList` that satisfy `Array<Record<string, string>>`;
|
|
4
|
+
* - usefull for `derivedLoops`, e.g. temporary search values;
|
|
5
|
+
* - is a `Derived` instance;
|
|
6
|
+
* @template {ListArg} LA
|
|
7
|
+
* @extends {Derived<LA[]>}
|
|
8
|
+
*/
|
|
9
|
+
export class ListDerived<LA extends import("../types/ListArg.mjs").ListArg> extends Derived<LA[]> {
|
|
10
|
+
/**
|
|
11
|
+
* @typedef {import('../types/ListArg.mjs').ListArg} ListArg
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* @description
|
|
15
|
+
* @param {(effectInstanceOptions:Effect["options"])=>Promise<LA[]>} derivedFunction
|
|
16
|
+
* @example
|
|
17
|
+
* import { ListSignal, ListDerived } from 'vivth';
|
|
18
|
+
*
|
|
19
|
+
* const listExample = new ListSignal([
|
|
20
|
+
* {key1: "test1"},
|
|
21
|
+
* {key1: "test2"},
|
|
22
|
+
* ]);
|
|
23
|
+
*
|
|
24
|
+
* export const listDerivedExample = new ListDerived(async({ subscribe }) => {
|
|
25
|
+
* // becarefull to not mutate the reference value
|
|
26
|
+
* return subscribe(listExample).value.filter((val) => {
|
|
27
|
+
* // subscribe(listExample).structuredClone can be used as alternative
|
|
28
|
+
* // filter logic
|
|
29
|
+
* })
|
|
30
|
+
* });
|
|
31
|
+
*/
|
|
32
|
+
constructor(derivedFunction: (effectInstanceOptions: Effect["options"]) => Promise<LA[]>);
|
|
33
|
+
}
|
|
34
|
+
import { Derived } from './Derived.mjs';
|
|
35
|
+
import { Effect } from './Effect.mjs';
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('../types/ListArg.mjs').ListArg} ListArg
|
|
3
|
+
* @typedef {import('../types/MutationType.mjs').MutationType} MutationType
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @description
|
|
7
|
+
* - class to create list that satisfy `Array<Record<string, string>>`.
|
|
8
|
+
* @template {import('../types/ListArg.mjs').ListArg} LA
|
|
9
|
+
* @extends {Signal<LA[]>}
|
|
10
|
+
*/
|
|
11
|
+
export class ListSignal<LA extends import("../types/ListArg.mjs").ListArg> extends Signal<LA[]> {
|
|
12
|
+
/**
|
|
13
|
+
* @description
|
|
14
|
+
* - Checks if the input is an array whose first item (if present) is a plain object
|
|
15
|
+
* - with string keys and string values. Allows empty arrays.
|
|
16
|
+
* @param {unknown} value - The value to validate.
|
|
17
|
+
* @returns {value is Array<Record<string, string>>} True if the first item is a valid string record or array is empty.
|
|
18
|
+
*/
|
|
19
|
+
static isValid: (value: unknown) => value is Array<Record<string, string>>;
|
|
20
|
+
/**
|
|
21
|
+
* @description
|
|
22
|
+
* - usefull for `loops`;
|
|
23
|
+
* @param {LA[]} [value]
|
|
24
|
+
* @example
|
|
25
|
+
* import { ListSignal } from 'vivth';
|
|
26
|
+
*
|
|
27
|
+
* const listExample = new ListSignal([
|
|
28
|
+
* {key1: "test1",},
|
|
29
|
+
* {key1: "test2",},
|
|
30
|
+
* ]);
|
|
31
|
+
*/
|
|
32
|
+
constructor(value?: LA[]);
|
|
33
|
+
/**
|
|
34
|
+
* @description
|
|
35
|
+
* - methods collection that mimics `Array` API;
|
|
36
|
+
* - calling this methods will notify subscribers for changes, except for some;
|
|
37
|
+
*/
|
|
38
|
+
arrayMethods: {
|
|
39
|
+
/**
|
|
40
|
+
* @instance arrayMethods
|
|
41
|
+
* @description
|
|
42
|
+
* - reference to structuredClone elements of `value`;
|
|
43
|
+
* - calling doesn't notify
|
|
44
|
+
* @type {Array<LA>}
|
|
45
|
+
*/
|
|
46
|
+
readonly structuredClone: Array<LA>;
|
|
47
|
+
/**
|
|
48
|
+
* @instance arrayMethods
|
|
49
|
+
* @description
|
|
50
|
+
* - appends new elements to the end;
|
|
51
|
+
* @param {...LA} listArg
|
|
52
|
+
* @returns {void}
|
|
53
|
+
*/
|
|
54
|
+
push: (...listArg: LA[]) => void;
|
|
55
|
+
/**
|
|
56
|
+
* @instance arrayMethods
|
|
57
|
+
* @description
|
|
58
|
+
* - removes the first element;
|
|
59
|
+
* @type {()=>void}
|
|
60
|
+
*/
|
|
61
|
+
shift: () => void;
|
|
62
|
+
/**
|
|
63
|
+
* @instance arrayMethods
|
|
64
|
+
* @description
|
|
65
|
+
* - inserts new element at the start;
|
|
66
|
+
* @param {...LA} listArg
|
|
67
|
+
* @returns {void}
|
|
68
|
+
*/
|
|
69
|
+
unshift: (...listArg: LA[]) => void;
|
|
70
|
+
/**
|
|
71
|
+
* @instance arrayMethods
|
|
72
|
+
* @description
|
|
73
|
+
* - for both start and end, a negative index can be used to indicate an offset from the end of the data. For example, -2 refers to the second to last element of the data;
|
|
74
|
+
* @param {number} [start]
|
|
75
|
+
* - the beginning index of the specified portion of the data. If start is undefined, then the slice begins at index 0.
|
|
76
|
+
* @param {number} [end]
|
|
77
|
+
* - the end index of the specified portion of the data. This is exclusive of the element at the index 'end'. If end is undefined, then the slice extends to the end of the data.
|
|
78
|
+
* @returns {void}
|
|
79
|
+
*/
|
|
80
|
+
slice: (start?: number, end?: number) => void;
|
|
81
|
+
/**
|
|
82
|
+
* @instance arrayMethods
|
|
83
|
+
* @description
|
|
84
|
+
* - replace whole `List` data with new array.
|
|
85
|
+
* @param {LA[]} listArgs
|
|
86
|
+
* - new array in place of the deleted array.
|
|
87
|
+
* @returns {void}
|
|
88
|
+
*/
|
|
89
|
+
replace: (listArgs: LA[]) => void;
|
|
90
|
+
/**
|
|
91
|
+
* @instance arrayMethods
|
|
92
|
+
* @description
|
|
93
|
+
* - removes elements from an data and, if necessary, inserts new elements in their place;
|
|
94
|
+
* @param {number} start
|
|
95
|
+
* - The zero-based location in the data from which to start removing elements.
|
|
96
|
+
* @param {number} deleteCount
|
|
97
|
+
* -The number of elements to remove.
|
|
98
|
+
* @param {...LA} listArg
|
|
99
|
+
* - new data in place of the deleted data.
|
|
100
|
+
* @returns {void}
|
|
101
|
+
*/
|
|
102
|
+
splice: (start: number, deleteCount: number, ...listArg: LA[]) => void;
|
|
103
|
+
/**
|
|
104
|
+
* @instance arrayMethods
|
|
105
|
+
* @description
|
|
106
|
+
* - swap `List` data between two indexes;
|
|
107
|
+
* @param {number} indexA
|
|
108
|
+
* @param {number} indexB
|
|
109
|
+
* @returns {void}
|
|
110
|
+
*/
|
|
111
|
+
swap: (indexA: number, indexB: number) => void;
|
|
112
|
+
/**
|
|
113
|
+
* @instance arrayMethods
|
|
114
|
+
* @description
|
|
115
|
+
* - modify `List` element at specific index;
|
|
116
|
+
* @param {number} index
|
|
117
|
+
* @param {Partial<LA>} listArg
|
|
118
|
+
* @returns {void}
|
|
119
|
+
*/
|
|
120
|
+
modify: (index: number, listArg: Partial<LA>) => void;
|
|
121
|
+
/**
|
|
122
|
+
* @instance arrayMethods
|
|
123
|
+
* @description
|
|
124
|
+
* - remove `List` element at specific index;
|
|
125
|
+
* @param {number} index
|
|
126
|
+
* @returns {void}
|
|
127
|
+
*/
|
|
128
|
+
remove: (index: number) => void;
|
|
129
|
+
/**
|
|
130
|
+
* @instance arrayMethods
|
|
131
|
+
* @description
|
|
132
|
+
* - reverses the elements in an `List` in place.
|
|
133
|
+
* @returns {void}
|
|
134
|
+
*/
|
|
135
|
+
reverse: () => void;
|
|
136
|
+
/**
|
|
137
|
+
* @instance arrayMethods
|
|
138
|
+
* @description
|
|
139
|
+
* - removes the last element;
|
|
140
|
+
* @returns {void}
|
|
141
|
+
*/
|
|
142
|
+
pop: () => void;
|
|
143
|
+
} & {
|
|
144
|
+
"vivth:unwrapLazy;": string;
|
|
145
|
+
};
|
|
146
|
+
#private;
|
|
147
|
+
}
|
|
148
|
+
export type ListArg = import("../types/ListArg.mjs").ListArg;
|
|
149
|
+
export type MutationType = import("../types/MutationType.mjs").MutationType;
|
|
150
|
+
import { Signal } from './Signal.mjs';
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description
|
|
3
|
+
* - class helpers to define pathReference;
|
|
4
|
+
* - is a singleton;
|
|
5
|
+
*/
|
|
6
|
+
export class Paths {
|
|
7
|
+
/**
|
|
8
|
+
* @type {Paths}
|
|
9
|
+
*/
|
|
10
|
+
static "__#13337@#instance": Paths;
|
|
11
|
+
/**
|
|
12
|
+
* @description
|
|
13
|
+
* - reference for rootPath
|
|
14
|
+
* - `Paths` needed to be instantiated via:
|
|
15
|
+
* >- `Paths` constructor;
|
|
16
|
+
* >- `Setup.paths` constructor;
|
|
17
|
+
* @type {string}
|
|
18
|
+
*/
|
|
19
|
+
static get root(): string;
|
|
20
|
+
/**
|
|
21
|
+
* @description
|
|
22
|
+
* - normalize path separator to forward slash `/`;
|
|
23
|
+
* @param {string} path_
|
|
24
|
+
* @returns {string}
|
|
25
|
+
* @example
|
|
26
|
+
* import { Paths } from 'vivth';
|
|
27
|
+
*
|
|
28
|
+
* Paths.normalize('file:\\D:\\myFile.mjs'); // return 'file://D://myFile.mjs'
|
|
29
|
+
*/
|
|
30
|
+
static normalize: (path_: string) => string;
|
|
31
|
+
/**
|
|
32
|
+
* @description
|
|
33
|
+
* @param {Object} options
|
|
34
|
+
* @param {string} options.root
|
|
35
|
+
* - browser: location.origin
|
|
36
|
+
* - node/bun compatible: process?.env?.INIT_CWD ?? process?.cwd();
|
|
37
|
+
* - deno: Deno.env.get("INIT_CWD") ?? Deno.cwd(); need for `deno run --allow-env --allow-read your_script.ts`
|
|
38
|
+
* - other: you need to check your JSRuntime for the rootPath reference;
|
|
39
|
+
* @example
|
|
40
|
+
* import { Paths } from 'vivth';
|
|
41
|
+
*
|
|
42
|
+
* new Paths({
|
|
43
|
+
* root: location.origin,
|
|
44
|
+
* })
|
|
45
|
+
*/
|
|
46
|
+
constructor({ root }: {
|
|
47
|
+
root: string;
|
|
48
|
+
});
|
|
49
|
+
#private;
|
|
50
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description
|
|
3
|
+
* - class for `Queue` handling;
|
|
4
|
+
* @template {AnyButUndefinedType} T
|
|
5
|
+
*/
|
|
6
|
+
export class QChannel<T extends import("../types/AnyButUndefined.mjs").AnyButUndefined> {
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {import('../types/AnyButUndefined.mjs').AnyButUndefined} AnyButUndefinedType
|
|
9
|
+
* @typedef {import('../types/QCBReturn.mjs').QCBReturn} QCBReturn
|
|
10
|
+
* @typedef {import('../types/QCBFIFOReturn.mjs').QCBFIFOReturn} QCBFIFOReturn
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* @description
|
|
14
|
+
* - to modify `MapReference`
|
|
15
|
+
* @param {Map<AnyButUndefinedType, [Promise<any>, {}]>} uniqueMap
|
|
16
|
+
* @returns {typeof QChannel}
|
|
17
|
+
* - usefull for Queue primitive on multiple library but single reference, like the Web by making the `Map` on `window` object;
|
|
18
|
+
*/
|
|
19
|
+
static makeQClass: (uniqueMap: Map<import("../types/AnyButUndefined.mjs").AnyButUndefined, [Promise<any>, {}]>) => typeof QChannel;
|
|
20
|
+
/**
|
|
21
|
+
* @type {Map<AnyButUndefinedType, [Promise<any>, {}]>}
|
|
22
|
+
*/
|
|
23
|
+
static "__#7@#uniquePromiser": Map<import("../types/AnyButUndefined.mjs").AnyButUndefined, [Promise<any>, {}]>;
|
|
24
|
+
/**
|
|
25
|
+
* - ensures that each id has only one task running at a time.
|
|
26
|
+
* - calls with the same id will wait for the previous call to finish.
|
|
27
|
+
* @param {AnyButUndefinedType} id
|
|
28
|
+
* @returns {Promise<QCBReturn>} Resolves when it's safe to proceed for the given id, returning a cleanup function
|
|
29
|
+
*/
|
|
30
|
+
static "__#7@#uniqueCB": (id: import("../types/AnyButUndefined.mjs").AnyButUndefined) => Promise<import("../types/QCBReturn.mjs").QCBReturn>;
|
|
31
|
+
/**
|
|
32
|
+
* @description
|
|
33
|
+
* - first in first out handler
|
|
34
|
+
*/
|
|
35
|
+
static fifo: {
|
|
36
|
+
/**
|
|
37
|
+
* @static fifo
|
|
38
|
+
* @description
|
|
39
|
+
* - blocks execution for subsequent calls until the current one finishes.
|
|
40
|
+
* @returns {Promise<QCBFIFOReturn>} Resolves when it's safe to proceed, returning a cleanup function
|
|
41
|
+
* @example
|
|
42
|
+
* const { resume } = await QChannel.fifo.key();
|
|
43
|
+
* // blocks all `FIFO` called using this method and QChannel.fifoCallback;
|
|
44
|
+
* resume();
|
|
45
|
+
*/
|
|
46
|
+
key: () => Promise<import("../types/QCBFIFOReturn.mjs").QCBFIFOReturn>;
|
|
47
|
+
/**
|
|
48
|
+
* @static fifo
|
|
49
|
+
* @description
|
|
50
|
+
* - blocks execution for subsequent calls until the current one finishes.
|
|
51
|
+
* @template ResultType
|
|
52
|
+
* @param {()=>Promise<ResultType>} asyncCallback
|
|
53
|
+
* @returns {Promise<[ResultType|undefined, Error|undefined]>}
|
|
54
|
+
* @example
|
|
55
|
+
* const [result, error] = await QChannel.fifo.callback(async () = > {
|
|
56
|
+
* // code
|
|
57
|
+
* })
|
|
58
|
+
*/
|
|
59
|
+
callback: <ResultType>(asyncCallback: () => Promise<ResultType>) => Promise<[ResultType | undefined, Error | undefined]>;
|
|
60
|
+
} & {
|
|
61
|
+
"vivth:unwrapLazy;": string;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* @description
|
|
65
|
+
* - clear up all queued on the instance;
|
|
66
|
+
* - only clear up the reference, the already called will not be stoped;
|
|
67
|
+
* @returns {void}
|
|
68
|
+
*/
|
|
69
|
+
clear: () => void;
|
|
70
|
+
/**
|
|
71
|
+
* @description
|
|
72
|
+
* - each `QChannelInstance` are managing it's own `queue`, and will not `await` for other `QChannelInstance`;
|
|
73
|
+
* - caveat:
|
|
74
|
+
* >- need to manually call resume();
|
|
75
|
+
* >- slightly more performant than `callback`;
|
|
76
|
+
* @param {T} keyID
|
|
77
|
+
* @returns {Promise<QCBReturn>}
|
|
78
|
+
* @example
|
|
79
|
+
* const q = new QChannel();
|
|
80
|
+
* const handler = async () => {
|
|
81
|
+
* const { resume, isLastOnQ } = await q.key(keyID);
|
|
82
|
+
* // if (!isLastOnQ) { // imperative debounce if needed
|
|
83
|
+
* // resume();
|
|
84
|
+
* // return;
|
|
85
|
+
* // }
|
|
86
|
+
* // don't forget to call resume before any returns;
|
|
87
|
+
* // blocks only if keyID is the same, until resume is called;
|
|
88
|
+
* resume(); // don't forget to call resume before any returns;
|
|
89
|
+
* return 'something';
|
|
90
|
+
* }
|
|
91
|
+
* handler();
|
|
92
|
+
*/
|
|
93
|
+
key: (keyID: T) => Promise<import("../types/QCBReturn.mjs").QCBReturn>;
|
|
94
|
+
/**
|
|
95
|
+
* @description
|
|
96
|
+
* - `callbackBlock` with error as value:
|
|
97
|
+
* - caveat:
|
|
98
|
+
* >- no need to manually call resume();
|
|
99
|
+
* >- slightly less performant than `callback`;
|
|
100
|
+
* @template ResultType
|
|
101
|
+
* @param {T} keyID
|
|
102
|
+
* @param {(options:Omit<QCBReturn, "resume">)=>Promise<ResultType>} asyncCallback
|
|
103
|
+
* @returns {Promise<[ResultType|undefined, Error|undefined]>}
|
|
104
|
+
* @example
|
|
105
|
+
* const q = new QChannel();
|
|
106
|
+
* const [result, error] = await q.callback(keyID, async ({ isLastOnQ }) = > {
|
|
107
|
+
* // if (!isLastOnQ) { // imperative debounce if needed
|
|
108
|
+
* // return;
|
|
109
|
+
* // }
|
|
110
|
+
* // code
|
|
111
|
+
* })
|
|
112
|
+
*/
|
|
113
|
+
callback: (keyID: T, asyncCallback: (options: Omit<import("../types/QCBReturn.mjs").QCBReturn, "resume">) => Promise<ResultType>) => Promise<[ResultType | undefined, Error | undefined]>;
|
|
114
|
+
#private;
|
|
115
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @type {Set<()=>Promise<void>>}
|
|
3
|
+
*/
|
|
4
|
+
export const safeCleanUpCBs: Set<() => Promise<void>>;
|
|
5
|
+
/**
|
|
6
|
+
* @description
|
|
7
|
+
* - class helper for describing how to Safely Response on exit events
|
|
8
|
+
* - singleton;
|
|
9
|
+
* @template {[string, ...string[]]} ExitEventNames
|
|
10
|
+
*/
|
|
11
|
+
export class SafeExit<ExitEventNames extends [string, ...string[]]> {
|
|
12
|
+
/**
|
|
13
|
+
* @description
|
|
14
|
+
* - only accessible after instantiation;
|
|
15
|
+
* @type {SafeExit}
|
|
16
|
+
*/
|
|
17
|
+
static instance: SafeExit<any>;
|
|
18
|
+
/**
|
|
19
|
+
* @description
|
|
20
|
+
* @param {Object} options
|
|
21
|
+
* @param {ExitEventNames} options.exitEventNames
|
|
22
|
+
* @param {(eventName:string)=>void} [options.exitCallbackListeners]
|
|
23
|
+
* - default value
|
|
24
|
+
* ```js
|
|
25
|
+
* (eventName) => {
|
|
26
|
+
* process.once(eventName, function () {
|
|
27
|
+
* SafeExit.instance.exiting.correction(true);
|
|
28
|
+
* Console.log(`safe exit via "${eventName}"`);
|
|
29
|
+
* });
|
|
30
|
+
* };
|
|
31
|
+
* ```
|
|
32
|
+
* - if your exit callback doesn't uses `process` global object you need to input on the SafeExit instantiation
|
|
33
|
+
* @example
|
|
34
|
+
* import { SafeExit, Console } from 'vivth';
|
|
35
|
+
*
|
|
36
|
+
* new SafeExit({
|
|
37
|
+
* // exitEventNames are blank by default, you need to manually name them all;
|
|
38
|
+
* exitEventNames: ['SIGINT', 'SIGTERM', ...otherExitEventNames],
|
|
39
|
+
* // optional deno example
|
|
40
|
+
* exitCallbackListeners = (eventName) => {
|
|
41
|
+
* const sig = Deno.signal(eventName);
|
|
42
|
+
* for await (const _ of sig) {
|
|
43
|
+
* exiting.correction(true);
|
|
44
|
+
* sig.dispose();
|
|
45
|
+
* Console.log(`safe exit via "${eventName}"`);
|
|
46
|
+
* }
|
|
47
|
+
* }
|
|
48
|
+
* });
|
|
49
|
+
*/
|
|
50
|
+
constructor({ exitEventNames, exitCallbackListeners }: {
|
|
51
|
+
exitEventNames: ExitEventNames;
|
|
52
|
+
exitCallbackListeners?: (eventName: string) => void;
|
|
53
|
+
});
|
|
54
|
+
/**
|
|
55
|
+
* @description
|
|
56
|
+
* - optional exit event registration, by listening to it inside an `Effect`;
|
|
57
|
+
* - when the value is `true`, meaning program is exitting;
|
|
58
|
+
* @type {EnvSignal<boolean>}
|
|
59
|
+
*/
|
|
60
|
+
exiting: EnvSignal<boolean>;
|
|
61
|
+
/**
|
|
62
|
+
* @description
|
|
63
|
+
* - optional exit event registration;
|
|
64
|
+
* - the callbacks will be called when exiting;
|
|
65
|
+
* @param {()=>(Promise<void>)} cb
|
|
66
|
+
* @example
|
|
67
|
+
* import { SafeExit } from 'vivth';
|
|
68
|
+
*
|
|
69
|
+
* SafeExit.instance.addCallback(()=>{
|
|
70
|
+
* // code
|
|
71
|
+
* })
|
|
72
|
+
*/
|
|
73
|
+
addCallback: (cb: () => (Promise<void>)) => void;
|
|
74
|
+
#private;
|
|
75
|
+
}
|
|
76
|
+
import { EnvSignal } from './EnvSignal.mjs';
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description
|
|
3
|
+
* - class with collections of methods/constructors for setting up necessary variables for vivth internal functionalities;
|
|
4
|
+
*/
|
|
5
|
+
export class Setup {
|
|
6
|
+
/**
|
|
7
|
+
* @description
|
|
8
|
+
* - proxy `SafeExit_instance` for Setup
|
|
9
|
+
* @example
|
|
10
|
+
* import { Setup, Console } from 'vivth';
|
|
11
|
+
*
|
|
12
|
+
* new Setup.safeExit({
|
|
13
|
+
* // exitEventNames are blank by default, you need to manually name them all;
|
|
14
|
+
* exitEventNames: ['SIGINT', 'SIGTERM', ...otherExitEventNames],
|
|
15
|
+
* // optional deno example
|
|
16
|
+
* exitCallbackListeners = (eventName) => {
|
|
17
|
+
* const sig = Deno.signal(eventName);
|
|
18
|
+
* for await (const _ of sig) {
|
|
19
|
+
* SafeExit.instance.exiting.correction(true);
|
|
20
|
+
* sig.dispose();
|
|
21
|
+
* Console.info(`safe exit via "${eventName}"`);
|
|
22
|
+
* }
|
|
23
|
+
* }
|
|
24
|
+
* });
|
|
25
|
+
*/
|
|
26
|
+
static safeExit: typeof SafeExit;
|
|
27
|
+
/**
|
|
28
|
+
* @description
|
|
29
|
+
* - proxy `Paths_instance` for Setup;
|
|
30
|
+
* @example
|
|
31
|
+
* import { Setup } from 'vivth';
|
|
32
|
+
*
|
|
33
|
+
* new Setup.paths({
|
|
34
|
+
* root: location.origin, // browser example
|
|
35
|
+
* })
|
|
36
|
+
*/
|
|
37
|
+
static paths: typeof Paths;
|
|
38
|
+
/**
|
|
39
|
+
* @description
|
|
40
|
+
* - proxy `WorkerMainThread_instance` for Setup;
|
|
41
|
+
* @example
|
|
42
|
+
* import { Setup } from 'vivth';
|
|
43
|
+
*
|
|
44
|
+
* Setup.workerMain({
|
|
45
|
+
* workerClass: async () => await (import('worker_threads')).Worker,
|
|
46
|
+
* basePath: 'public/assets/js/workers',
|
|
47
|
+
* pathValidator: async (workerPath, root, base) => {
|
|
48
|
+
* const res = await fetch(`${root}/${base}/${workerPath}`);
|
|
49
|
+
* // might also check wheter it need base or not
|
|
50
|
+
* return await res.ok;
|
|
51
|
+
* },
|
|
52
|
+
* });
|
|
53
|
+
*/
|
|
54
|
+
static workerMain: ({ workerClass, pathValidator, basePath }: {
|
|
55
|
+
workerClass: (typeof WorkerMainThread)["workerClass"];
|
|
56
|
+
pathValidator: (typeof WorkerMainThread)["pathValidator"];
|
|
57
|
+
basePath?: (typeof WorkerMainThread)["basePath"];
|
|
58
|
+
}) => void;
|
|
59
|
+
/**
|
|
60
|
+
* @description
|
|
61
|
+
* - correct `parentPort` reference when needed;
|
|
62
|
+
* @example
|
|
63
|
+
* import { Setup } from 'vivth';
|
|
64
|
+
*
|
|
65
|
+
* Setup.workerThread({ parentPort: async () => await import('node:worker_threads') });
|
|
66
|
+
* // that is the default value, if your parentPort/equivalent API is not that;
|
|
67
|
+
* // you need to call this method;
|
|
68
|
+
*/
|
|
69
|
+
static workerThread: <Receive_, Post_>(parentPortRef: {
|
|
70
|
+
parentPort: () => Promise<any>;
|
|
71
|
+
}) => typeof WorkerThread<Receive_, Post_>;
|
|
72
|
+
}
|
|
73
|
+
import { SafeExit } from './SafeExit.mjs';
|
|
74
|
+
import { Paths } from './Paths.mjs';
|
|
75
|
+
import { WorkerMainThread } from './WorkerMainThread.mjs';
|
|
76
|
+
import { WorkerThread } from './WorkerThread.mjs';
|