vivth 0.11.2 → 1.0.1

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.
Files changed (106) hide show
  1. package/README.md +2157 -69
  2. package/README.src.md +35 -0
  3. package/bun.lock +57 -3
  4. package/dev/index.mjs +24 -25
  5. package/index.mjs +51 -29
  6. package/package.json +11 -7
  7. package/src/bundler/CompileMJS.mjs +110 -0
  8. package/src/bundler/EsBundler.mjs +79 -0
  9. package/src/class/Console.mjs +62 -0
  10. package/src/class/Derived.mjs +36 -25
  11. package/src/class/Effect.mjs +106 -0
  12. package/src/class/EnvSignal.mjs +88 -0
  13. package/src/class/EventSignal.mjs +200 -0
  14. package/src/class/ListDerived.mjs +39 -0
  15. package/src/class/ListSignal.mjs +256 -0
  16. package/src/class/Paths.mjs +70 -0
  17. package/src/class/QChannel.mjs +184 -0
  18. package/src/class/SafeExit.mjs +131 -0
  19. package/src/class/Setup.mjs +73 -0
  20. package/src/class/Signal.mjs +152 -54
  21. package/src/class/WorkerMainThread.mjs +328 -0
  22. package/src/class/WorkerResult.mjs +30 -0
  23. package/src/class/WorkerThread.mjs +151 -0
  24. package/src/common/Base64URL.mjs +26 -0
  25. package/src/common/EventNameSpace.mjs +8 -0
  26. package/src/common/eventObjects.mjs +5 -0
  27. package/src/common/lazie.mjs +3 -0
  28. package/src/doc/JSautoDOC.mjs +386 -0
  29. package/src/doc/parsedFile.mjs +537 -0
  30. package/src/function/CreateImmutable.mjs +64 -0
  31. package/src/function/EventCheck.mjs +27 -0
  32. package/src/function/EventObject.mjs +21 -0
  33. package/src/function/IsAsync.mjs +23 -0
  34. package/src/function/LazyFactory.mjs +71 -0
  35. package/src/function/Timeout.mjs +23 -0
  36. package/src/function/Try.mjs +64 -0
  37. package/src/function/TryAsync.mjs +15 -4
  38. package/src/function/TrySync.mjs +9 -4
  39. package/src/function/TsToMjs.mjs +67 -0
  40. package/src/function/WriteFileSafe.mjs +37 -0
  41. package/src/types/{AnyButUndefined.type.mjs → AnyButUndefined.mjs} +1 -0
  42. package/src/types/ExtnameType.mjs +6 -0
  43. package/src/types/IsListSignal.mjs +6 -0
  44. package/src/types/ListArg.mjs +6 -0
  45. package/src/types/MutationType.mjs +8 -0
  46. package/src/types/QCBFIFOReturn.mjs +6 -0
  47. package/src/types/QCBReturn.mjs +6 -0
  48. package/tsconfig.json +3 -3
  49. package/types/dev/index.d.mts +1 -0
  50. package/types/index.d.mts +34 -8
  51. package/types/src/bundler/A.d.mts +1 -0
  52. package/types/src/bundler/CompileMJS.d.mts +8 -0
  53. package/types/src/bundler/EsBundler.d.mts +7 -0
  54. package/types/src/class/Console.d.mts +40 -0
  55. package/types/src/class/Derived.d.mts +21 -9
  56. package/types/src/class/Effect.d.mts +77 -0
  57. package/types/src/class/EnvSignal.d.mts +47 -0
  58. package/types/src/class/EventSignal.d.mts +145 -0
  59. package/types/src/class/ListDerived.d.mts +35 -0
  60. package/types/src/class/ListSignal.d.mts +150 -0
  61. package/types/src/class/Paths.d.mts +50 -0
  62. package/types/src/class/QChannel.d.mts +115 -0
  63. package/types/src/class/SafeExit.d.mts +76 -0
  64. package/types/src/class/Setup.d.mts +76 -0
  65. package/types/src/class/Signal.d.mts +105 -26
  66. package/types/src/class/WorkerMainThread.d.mts +149 -0
  67. package/types/src/class/WorkerResult.d.mts +25 -0
  68. package/types/src/class/WorkerThread.d.mts +70 -0
  69. package/types/src/common/Base64URL.d.mts +1 -0
  70. package/types/src/common/EventNameSpace.d.mts +6 -0
  71. package/types/src/common/eventObjects.d.mts +3 -0
  72. package/types/src/common/lazie.d.mts +1 -0
  73. package/types/src/doc/JSautoDOC.d.mts +76 -0
  74. package/types/src/doc/parsedFile.d.mts +154 -0
  75. package/types/src/function/CreateImmutable.d.mts +3 -0
  76. package/types/src/function/EventCheck.d.mts +2 -0
  77. package/types/src/function/EventObject.d.mts +4 -0
  78. package/types/src/function/IsAsync.d.mts +1 -0
  79. package/types/src/function/LazyFactory.d.mts +4 -0
  80. package/types/src/function/Timeout.d.mts +1 -0
  81. package/types/src/function/Try.d.mts +1 -0
  82. package/types/src/function/TsToMjs.d.mts +4 -0
  83. package/types/src/function/WriteFileSafe.d.mts +2 -0
  84. package/types/src/types/{AnyButUndefined.type.d.mts → AnyButUndefined.d.mts} +3 -0
  85. package/types/src/types/ExtnameType.d.mts +4 -0
  86. package/types/src/types/IsListSignal.d.mts +4 -0
  87. package/types/src/types/ListArg.d.mts +4 -0
  88. package/types/src/types/MutationType.d.mts +5 -0
  89. package/types/src/types/QCBFIFOReturn.d.mts +4 -0
  90. package/types/src/types/QCBReturn.d.mts +7 -0
  91. package/src/class/$.mjs +0 -68
  92. package/src/class/PingFIFO.mjs +0 -78
  93. package/src/class/PingUnique.mjs +0 -84
  94. package/src/class/Q.mjs +0 -98
  95. package/src/class/QFIFO.mjs +0 -66
  96. package/src/class/QUnique.mjs +0 -75
  97. package/src/common.mjs +0 -16
  98. package/src/function/NewQBlock.mjs +0 -39
  99. package/types/src/class/$.d.mts +0 -40
  100. package/types/src/class/PingFIFO.d.mts +0 -57
  101. package/types/src/class/PingUnique.d.mts +0 -48
  102. package/types/src/class/Q.d.mts +0 -63
  103. package/types/src/class/QFIFO.d.mts +0 -47
  104. package/types/src/class/QUnique.d.mts +0 -46
  105. package/types/src/common.d.mts +0 -2
  106. package/types/src/function/NewQBlock.d.mts +0 -1
@@ -0,0 +1,328 @@
1
+ // @ts-check
2
+
3
+ import { Base64URL } from '../common/Base64URL.mjs';
4
+ import { closeWorkerThreadEventObject } from '../common/eventObjects.mjs';
5
+ import { Try } from '../function/Try.mjs';
6
+ import { TryAsync } from '../function/TryAsync.mjs';
7
+ import { Console } from './Console.mjs';
8
+ import { Derived } from './Derived.mjs';
9
+ import { Effect } from './Effect.mjs';
10
+ import { Paths } from './Paths.mjs';
11
+ import { SafeExit } from './SafeExit.mjs';
12
+ import { Signal } from './Signal.mjs';
13
+
14
+ /**
15
+ * @template A
16
+ * @typedef {import('./WorkerResult.mjs').WorkerResult<A>} WorkerResult
17
+ */
18
+ /**
19
+ * @typedef {import('./WorkerThread.mjs').WorkerThread} WorkerThread
20
+ */
21
+
22
+ /**
23
+ * @description
24
+ * - class helper to create `Worker` instance;
25
+ * @template {WorkerThread} WT
26
+ */
27
+ export class WorkerMainThread {
28
+ static #isRegistered = false;
29
+ /**
30
+ * @description
31
+ * - need to be called first, before any `WorkerMainThread` instantiation:
32
+ * @param {Object} param0
33
+ * @param {typeof WorkerMainThread["workerClass"]} param0.workerClass
34
+ * @param {typeof WorkerMainThread["pathValidator"]} param0.pathValidator
35
+ * ```js
36
+ * async(relativePath) => {
37
+ * // verify whether relativePath exist, then return the full path
38
+ * // use fetch | fs, chained with Paths.instance.root + WorkerMainThread.basePath;
39
+ * }
40
+ * ```
41
+ * @param {typeof WorkerMainThread["basePath"]} [param0.basePath]
42
+ * - additonal realtivePath from rootPath;
43
+ * - default: '';
44
+ * @example
45
+ * import { WorkerMainThread } from 'vivth';
46
+ *
47
+ * WorkerMainThread.setup({
48
+ * workerClass: async () => await (import('worker_threads')).Worker,
49
+ * basePath: 'public/assets/js/workers',
50
+ * pathValidator: async (workerPath, root, base) => {
51
+ * const res = await fetch(`${root}/${base}/${workerPath}`);
52
+ * // might also check wheter it need base or not
53
+ * return await res.ok;
54
+ * },
55
+ * });
56
+ */
57
+ static setup = ({ workerClass, pathValidator, basePath = '' }) => {
58
+ if (!Paths.root) {
59
+ return;
60
+ }
61
+ if (WorkerMainThread.#isRegistered) {
62
+ Console.warn({ message: 'WorkerMainThread.setup, can only be called once' });
63
+ return;
64
+ }
65
+ WorkerMainThread.#isRegistered = true;
66
+ WorkerMainThread.workerClass = workerClass;
67
+ WorkerMainThread.pathValidator = pathValidator;
68
+ WorkerMainThread.basePath = basePath;
69
+ };
70
+ /**
71
+ * @description
72
+ * - reference for `Worker` class;
73
+ * - edit via `setup`;
74
+ * @type {()=>Promise<typeof Worker|typeof import('worker_threads').Worker>}
75
+ */
76
+ static workerClass;
77
+ /**
78
+ * @description
79
+ * - reference for worker file `basePath`;
80
+ * - edit via `setup`;
81
+ * @type {string}
82
+ */
83
+ static basePath;
84
+ /**
85
+ * @description
86
+ * - reference for validating path;
87
+ * - edit via `setup`;
88
+ * @type {(paths:{worker: string, root:string, base: string})=>Promise<string>}
89
+ */
90
+ static pathValidator;
91
+ static #options = /** @type {import('worker_threads').WorkerOptions & { type?: 'module' }} */ ({
92
+ type: 'module',
93
+ });
94
+ /**
95
+ * @description
96
+ * - create Worker_instance;
97
+ * @param {string} handler
98
+ * - if `isInline` === `false`, `handler` should be:
99
+ * >- pointing to worker thread file; WHICH
100
+ * >- the path must be relative to `projectRoot`;
101
+ * - if `isInline` === `true`, `handler` should be
102
+ * >- string literal of prebundled worker thread script; OR
103
+ * >- manually made string literal of worker thread script;
104
+ * @param {Omit<WorkerOptions|import('worker_threads').WorkerOptions, 'eval'|'type'>} [options]
105
+ * @param {boolean} [isInline]
106
+ * @example
107
+ * import { WorkerMainThread } from 'vivth';
108
+ *
109
+ * export const myDoubleWorker = new WorkerMainThread('./doubleWorkerThread.mjs');
110
+ */
111
+ constructor(handler, options = {}, isInline = false) {
112
+ /**
113
+ * @param {WT["Receive"]} ev
114
+ * @returns {void}
115
+ */
116
+ const listener = (ev) => {
117
+ this.#proxyReceiver.value = ev;
118
+ };
119
+ WorkerMainThread.#workerFilehandler(handler, options, this, listener, isInline);
120
+ }
121
+ /**
122
+ * @type {import('./Signal.mjs').Signal<import('./WorkerResult.mjs').WorkerResult<WT["Post"]>|MessageEvent<import('./WorkerResult.mjs').WorkerResult<WT["Post"]>>>}
123
+ */
124
+ #proxyReceiver = new Signal(undefined);
125
+ /**
126
+ * @param {string} handler
127
+ * @param { WorkerOptions
128
+ * | import('worker_threads').WorkerOptions} options
129
+ * @param {WorkerMainThread} worker
130
+ * @param {(any:any)=>void} listener
131
+ * @param {boolean} isInline
132
+ * @returns {Promise<void>}
133
+ */
134
+ static #workerFilehandler = async (handler, options, worker, listener, isInline) => {
135
+ let resolvedPath;
136
+ if (!isInline) {
137
+ const pathValidator = WorkerMainThread.pathValidator;
138
+ const [resolvedPath_, error] = await TryAsync(async () => {
139
+ return await pathValidator({
140
+ worker: handler,
141
+ root: Paths.root,
142
+ base: WorkerMainThread.basePath,
143
+ });
144
+ });
145
+ if (error) {
146
+ Console.error({
147
+ error,
148
+ pathValidator,
149
+ message: 'invalid pathValidator inputed to `WorkerMainThread`;',
150
+ });
151
+ return;
152
+ }
153
+ resolvedPath = resolvedPath_;
154
+ } else {
155
+ WorkerMainThread.#options.eval = true;
156
+ resolvedPath = handler;
157
+ }
158
+ const [_1, error1] = await Try({
159
+ universal: async () => {
160
+ const WorkerClass = await WorkerMainThread.workerClass();
161
+ if (!WorkerClass) {
162
+ throw new Error('invalid `Worker` inputed to `WorkerMainThread`;');
163
+ }
164
+ const [_2, error2] = await Try({
165
+ browser: async () => {
166
+ if (!WorkerMainThread.isBrowser) {
167
+ throw new Error('not a browser');
168
+ }
169
+ let worker_;
170
+ if (!isInline) {
171
+ worker_ = worker.#worker.value = new WorkerClass(resolvedPath, {
172
+ ...options,
173
+ ...WorkerMainThread.#options,
174
+ });
175
+ } else {
176
+ const inlineURL = Base64URL(handler, 'application/javascript', btoa);
177
+ worker_ = worker.#worker.value = new WorkerClass(inlineURL, {
178
+ ...options,
179
+ ...WorkerMainThread.#options,
180
+ });
181
+ }
182
+ if (!('onmessage' in worker_)) {
183
+ throw new Error();
184
+ }
185
+ worker_.onmessage = listener;
186
+ if (SafeExit.instance) {
187
+ SafeExit.instance.addCallback(async () => {
188
+ worker_.onmessage = null;
189
+ });
190
+ }
191
+ },
192
+ nonBrowser: async () => {
193
+ const worker_ = (worker.#worker.value = new WorkerClass(resolvedPath, {
194
+ ...options,
195
+ ...WorkerMainThread.#options,
196
+ }));
197
+ if (!('addEventListener' in worker_)) {
198
+ throw new Error();
199
+ }
200
+ worker_.addEventListener('message', listener);
201
+ if (SafeExit.instance) {
202
+ SafeExit.instance.addCallback(async () => {
203
+ worker_.removeEventListener('message', listener);
204
+ });
205
+ }
206
+ },
207
+ });
208
+ if (error2) {
209
+ throw new Error();
210
+ }
211
+ if (SafeExit.instance) {
212
+ SafeExit.instance.addCallback(async () => {
213
+ worker.#worker.value.postMessage(closeWorkerThreadEventObject);
214
+ worker.terminate();
215
+ });
216
+ }
217
+ },
218
+ nodeOrBun: async () => {
219
+ if (!worker.#worker.value) {
220
+ const { Worker } = await import('node:worker_threads');
221
+ worker.#worker.value = new Worker(resolvedPath, {
222
+ ...options,
223
+ ...WorkerMainThread.#options,
224
+ });
225
+ }
226
+ const worker_ = worker.#worker.value;
227
+ // @ts-expect-error
228
+ worker_.addListener('message', listener);
229
+ if (SafeExit.instance) {
230
+ SafeExit.instance.addCallback(async () => {
231
+ // @ts-expect-error
232
+ worker_.removeListener('message', listener);
233
+ worker_.postMessage(closeWorkerThreadEventObject);
234
+ worker.terminate();
235
+ });
236
+ }
237
+ },
238
+ });
239
+ if (error1) {
240
+ Console.error(error1);
241
+ return;
242
+ }
243
+ };
244
+ /**
245
+ * @type {boolean}
246
+ */
247
+ static #isBrowser = undefined;
248
+ /**
249
+ * @description
250
+ * - check whether js run in browser
251
+ * @type {boolean}
252
+ */
253
+ static get isBrowser() {
254
+ if (WorkerMainThread.#isBrowser === undefined) {
255
+ WorkerMainThread.#isBrowser =
256
+ typeof window !== 'undefined' &&
257
+ typeof location === 'object' &&
258
+ typeof location.origin === 'string';
259
+ }
260
+ return WorkerMainThread.#isBrowser;
261
+ }
262
+ /**
263
+ * lazyly generated because node version need to await
264
+ * @type {Signal<Worker | import('worker_threads').Worker>}
265
+ */
266
+ #worker = new Signal(undefined);
267
+ /**
268
+ * @type {Signal<WT["Receive"]>}
269
+ */
270
+ #proxyPost = new Signal(undefined);
271
+ #handler = new Effect(async ({ subscribe }) => {
272
+ const postData = subscribe(this.#proxyPost).value;
273
+ const worker = subscribe(this.#worker).value;
274
+ if (!worker || postData === undefined) {
275
+ return;
276
+ }
277
+ worker.postMessage(postData);
278
+ });
279
+ /**
280
+ * @description
281
+ * - terminate all signals that are used on this instance;
282
+ * @type {()=>void}
283
+ */
284
+ terminate = () => {
285
+ /**
286
+ * this is more for browser, as most of this are automatically cleaned with `SafeExit`;
287
+ */
288
+ this.#worker.value?.terminate();
289
+ this.#worker.remove.ref();
290
+ this.#handler.options.removeEffect();
291
+ this.#proxyPost.remove.ref();
292
+ this.#proxyReceiver.remove.ref();
293
+ this.receiverSignal.remove.ref();
294
+ };
295
+ /**
296
+ * @description
297
+ * - result signal of the processed message;
298
+ * @type {Derived<WorkerResult<WT["Post"]>>}
299
+ * @example
300
+ * import { Effect } from 'vivth';
301
+ * import { myDoubleWorker } from './myDoubleWorker.mjs';
302
+ *
303
+ * const doubleReceiverSignal = myDoubleWorker.receiverSignal;
304
+ * new Effect(async({ subscribe }) => {
305
+ * const value = subscribe(doubleReceiverSignal).value;
306
+ * // code
307
+ * })
308
+ */
309
+ receiverSignal = new Derived(async ({ subscribe }) => {
310
+ const val = subscribe(this.#proxyReceiver).value;
311
+ if (val instanceof MessageEvent) {
312
+ return val.data;
313
+ }
314
+ return val;
315
+ });
316
+ /**
317
+ * @description
318
+ * - callback to send message to the worker thread;
319
+ * @type {(event: WT["Receive"])=>void}
320
+ * @example
321
+ * import { myDoubleWorker } from './myDoubleWorker.mjs';
322
+ *
323
+ * myDoubleWorker.postMessage(90);
324
+ */
325
+ postMessage = (data) => {
326
+ this.#proxyPost.value = data;
327
+ };
328
+ }
@@ -0,0 +1,30 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * @description
5
+ * - typeHelper for `Worker` message passing;
6
+ * - uses error as value instead;
7
+ * @template POST
8
+ */
9
+ export class WorkerResult {
10
+ /**
11
+ * @param {POST} data
12
+ * @param {Error|string|undefined} error
13
+ */
14
+ constructor(data, error) {
15
+ this.data = data;
16
+ this.error = error;
17
+ }
18
+ /**
19
+ * @description
20
+ * - result value;
21
+ * @type {POST}
22
+ */
23
+ data;
24
+ /**
25
+ * @description
26
+ * - error value;
27
+ * @type {Error|string|undefined}
28
+ */
29
+ error;
30
+ }
@@ -0,0 +1,151 @@
1
+ // @ts-check
2
+
3
+ import { closeWorkerThreadEventObject } from '../common/eventObjects.mjs';
4
+ import { EventCheck } from '../function/EventCheck.mjs';
5
+ import { LazyFactory } from '../function/LazyFactory.mjs';
6
+ import { Try } from '../function/Try.mjs';
7
+ import { TryAsync } from '../function/TryAsync.mjs';
8
+ import { Console } from './Console.mjs';
9
+ import { QChannel } from './QChannel.mjs';
10
+ import { WorkerResult } from './WorkerResult.mjs';
11
+
12
+ /**
13
+ * @description
14
+ * - class helper for `WorkerThread` creation;
15
+ * @template Receive
16
+ * @template Post
17
+ */
18
+ export class WorkerThread {
19
+ /**
20
+ * @type {{parentPort:()=>Promise<any>}}
21
+ */
22
+ static #parentPortRef = LazyFactory(() => {
23
+ return { parentPort: async () => (await import('node:worker_threads')).parentPort };
24
+ });
25
+ /**
26
+ * @description
27
+ * - need to be called and exported as new `WorkerThread` class reference;
28
+ * @template Receive_
29
+ * @template Post_
30
+ * @param {{parentPort:()=>Promise<any>}} parentPortRef
31
+ * - correct parentPort reference;
32
+ * @returns {typeof WorkerThread<Receive_, Post_>}
33
+ * @example
34
+ * import { WorkerThread } from 'vivth';
35
+ *
36
+ * WorkerThread.setup({ parentPort: async () => await import('node:worker_threads') });
37
+ * // that is the default value, if your parentPort/equivalent API is not that;
38
+ * // you need to call this method;
39
+ */
40
+ static setup = (parentPortRef) => {
41
+ this.#parentPortRef = parentPortRef;
42
+ return WorkerThread;
43
+ };
44
+ /**
45
+ * @returns {QChannel<WorkerThread>}
46
+ */
47
+ #qChannel = new QChannel();
48
+ /**
49
+ * @param {any} ev
50
+ */
51
+ static #isCloseWorkerEvent = (ev) => {
52
+ return EventCheck(ev, closeWorkerThreadEventObject);
53
+ };
54
+ /**
55
+ * @description
56
+ * - instantiate via created class from `setup` static method;
57
+ * @param {WorkerThread["handler"]} handler
58
+ * @example
59
+ * import { MyWorkerThread } from './MyWorkerThread.mjs';
60
+ *
61
+ * const doubleWorker = new MyWorkerThread((ev, isLastOnQ) => {
62
+ * // if(!isLastOnQ) {
63
+ * // return null; // can be used for imperative debouncing;
64
+ * // }
65
+ * return ev = ev \* 2;
66
+ * });
67
+ */
68
+ constructor(handler) {
69
+ this.handler = handler;
70
+ const this_ = this;
71
+ Try({
72
+ post: async () => {
73
+ /**
74
+ * @param {MessageEvent<Receive>|Receive} ev
75
+ * @returns {Promise<void>}
76
+ */
77
+ self.onmessage = async function (ev) {
78
+ const [_, error] = await TryAsync(async () => {
79
+ ev = ev instanceof MessageEvent ? ev.data : ev;
80
+ if (WorkerThread.#isCloseWorkerEvent(ev)) {
81
+ self.onmessage = null;
82
+ return;
83
+ }
84
+ const [data, error] = await this_.#qChannel.callback(this, async ({ isLastOnQ }) => {
85
+ return await handler(ev, isLastOnQ);
86
+ });
87
+ if (error) {
88
+ throw error;
89
+ }
90
+ self.postMessage(new WorkerResult(data, undefined));
91
+ });
92
+ if (!error) {
93
+ return;
94
+ }
95
+ self.postMessage(new WorkerResult(undefined, error?.message ?? 'Unknown error'));
96
+ };
97
+ },
98
+ parentPost: async () => {
99
+ const parentPort = await WorkerThread.#parentPortRef.parentPort();
100
+ /**
101
+ * @param {MessageEvent<Receive>|Receive} ev
102
+ * @returns {Promise<void>}
103
+ */
104
+ const listener = async function (ev) {
105
+ const [_, error] = await TryAsync(async () => {
106
+ ev = ev instanceof MessageEvent ? ev.data : ev;
107
+ if (WorkerThread.#isCloseWorkerEvent(ev)) {
108
+ parentPort.off('message', listener);
109
+ return;
110
+ }
111
+ const [data, error] = await this_.#qChannel.callback(this, async ({ isLastOnQ }) => {
112
+ return await handler(ev, isLastOnQ);
113
+ });
114
+ if (error) {
115
+ throw error;
116
+ }
117
+ parentPort.postMessage(new WorkerResult(data, undefined));
118
+ });
119
+ if (!error) {
120
+ return;
121
+ }
122
+ parentPort.postMessage(new WorkerResult(undefined, error?.message ?? 'Unknown error'));
123
+ };
124
+ parentPort.on('message', listener);
125
+ },
126
+ }).then(([_, error]) => {
127
+ if (!error) {
128
+ return;
129
+ }
130
+ Console.error(error);
131
+ });
132
+ }
133
+ /**
134
+ * @description
135
+ * - type helper;
136
+ * @type {(ev: Receive, isLastOnQ:boolean) => Post}
137
+ */
138
+ handler;
139
+ /**
140
+ * @description
141
+ * - helper type, hold no actual value;
142
+ * @type {Receive}
143
+ */
144
+ Receive;
145
+ /**
146
+ * @description
147
+ * - helper type, hold no actual value;
148
+ * @type {Post}
149
+ */
150
+ Post;
151
+ }
@@ -0,0 +1,26 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * @description
5
+ * - create inline base64 url;
6
+ * - usage:
7
+ * >- can be extremely usefull to display file on desktop app webview, without exposing http server;
8
+ * @param {string} fileString
9
+ * @param {string} mimeType
10
+ * @param {(string:string)=>string} btoaFunction
11
+ * - check your js runtime `btoa`;
12
+ * @returns {string}
13
+ * @example
14
+ * import { Base64URL } from 'vivth'
15
+ * import { fileString } from './fileString.mjs';
16
+ *
17
+ * Base64URL(fileString, 'application/javascript', btoa);
18
+ */
19
+ export const Base64URL = (fileString, mimeType, btoaFunction) => {
20
+ const utf8 = new TextEncoder().encode(fileString);
21
+ let binary = '';
22
+ for (let byte of utf8) {
23
+ binary += String.fromCharCode(byte);
24
+ }
25
+ return `data:${mimeType};base64,${btoaFunction(binary)}`;
26
+ };
@@ -0,0 +1,8 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * @description
5
+ * - namespacing for event, string as ID, related API;
6
+ * @type {'vivthEvent'}
7
+ */
8
+ export const EventNameSpace = 'vivthEvent';
@@ -0,0 +1,5 @@
1
+ // @ts-check
2
+
3
+ import { EventObject } from '../function/EventObject.mjs';
4
+
5
+ export const closeWorkerThreadEventObject = EventObject('worker:terminate');
@@ -0,0 +1,3 @@
1
+ // @ts-check
2
+
3
+ export const unwrapLazy = 'vivth:unwrapLazy;';