vivth 1.1.1 → 1.2.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.
Files changed (108) hide show
  1. package/.vivth-temp/README.src.md +35 -0
  2. package/README.md +1243 -441
  3. package/README.src.md +5 -2
  4. package/bun.lock +228 -0
  5. package/index.mjs +22 -9
  6. package/package.json +6 -3
  7. package/src/bundler/CompileJS.mjs +258 -0
  8. package/src/bundler/CreateESPlugin.mjs +24 -0
  9. package/src/bundler/EsBundler.mjs +27 -13
  10. package/src/bundler/FSInline.mjs +57 -0
  11. package/src/bundler/FSInlineAnalyzer.mjs +197 -0
  12. package/src/bundler/FSInlineBundled.mjs +34 -0
  13. package/src/bundler/adds/ToBundledJSPlugin.mjs +77 -0
  14. package/src/bundler/adds/externals.mjs +8 -0
  15. package/src/bundler/adds/pluginVivthBundle.mjs +5 -0
  16. package/src/class/Console.mjs +48 -27
  17. package/src/class/Derived.mjs +55 -7
  18. package/src/class/Effect.mjs +100 -39
  19. package/src/class/EnvSignal.mjs +5 -5
  20. package/src/class/EventSignal.mjs +55 -5
  21. package/src/class/FileSafe.mjs +124 -0
  22. package/src/class/ListDerived.mjs +6 -3
  23. package/src/class/ListSignal.mjs +11 -11
  24. package/src/class/LitExp.mjs +405 -0
  25. package/src/class/Paths.mjs +39 -4
  26. package/src/class/QChannel.mjs +79 -28
  27. package/src/class/SafeExit.mjs +31 -11
  28. package/src/class/Setup.mjs +12 -7
  29. package/src/class/Signal.mjs +26 -24
  30. package/src/class/WorkerMainThread.mjs +108 -135
  31. package/src/class/WorkerMainThreadBundled.mjs +216 -0
  32. package/src/class/WorkerThread.mjs +40 -31
  33. package/src/common/Base64URL.mjs +10 -5
  34. package/src/common/Base64URLFromFile.mjs +24 -0
  35. package/src/common/keys.mjs +3 -0
  36. package/src/doc/JSautoDOC.mjs +32 -56
  37. package/src/doc/parsedFile.mjs +37 -36
  38. package/src/function/CreateImmutable.mjs +9 -9
  39. package/src/function/EventCheck.mjs +2 -2
  40. package/src/function/EventObject.mjs +5 -5
  41. package/src/function/GetRuntime.mjs +38 -0
  42. package/src/function/IsAsync.mjs +2 -2
  43. package/src/function/LazyFactory.mjs +13 -13
  44. package/src/function/Timeout.mjs +2 -2
  45. package/src/function/Try.mjs +17 -12
  46. package/src/function/TryAsync.mjs +5 -5
  47. package/src/function/TrySync.mjs +5 -5
  48. package/src/function/TsToMjs.mjs +5 -4
  49. package/src/types/LitExpKeyType.mjs +5 -0
  50. package/src/types/QCBReturn.mjs +1 -1
  51. package/src/types/Runtime.mjs +7 -0
  52. package/types/dev/fsInline.d.mts +1 -0
  53. package/types/dev/test.d.mts +1 -0
  54. package/types/dev/testWorker.d.mts +7 -0
  55. package/types/dev/testbundle.d.mts +1 -0
  56. package/types/dev/workerThreadClass.d.mts +13 -0
  57. package/types/index.d.mts +18 -9
  58. package/types/src/bundler/CompileJS.d.mts +78 -0
  59. package/types/src/bundler/CreateESPlugin.d.mts +17 -0
  60. package/types/src/bundler/EsBundler.d.mts +33 -4
  61. package/types/src/bundler/FSInline.d.mts +43 -0
  62. package/types/src/bundler/FSInlineAnalyzer.d.mts +36 -0
  63. package/types/src/bundler/FSInlineBundled.d.mts +22 -0
  64. package/types/src/bundler/adds/ToBundledJSPlugin.d.mts +16 -0
  65. package/types/src/bundler/adds/externals.d.mts +1 -0
  66. package/types/src/bundler/adds/pluginVivthBundle.d.mts +1 -0
  67. package/types/src/class/Console.d.mts +36 -5
  68. package/types/src/class/Derived.d.mts +132 -5
  69. package/types/src/class/Effect.d.mts +106 -7
  70. package/types/src/class/EnvSignal.d.mts +8 -8
  71. package/types/src/class/EventSignal.d.mts +151 -7
  72. package/types/src/class/FileSafe.d.mts +90 -0
  73. package/types/src/class/ListDerived.d.mts +8 -5
  74. package/types/src/class/ListSignal.d.mts +123 -18
  75. package/types/src/class/LitExp.d.mts +361 -0
  76. package/types/src/class/Paths.d.mts +30 -4
  77. package/types/src/class/QChannel.d.mts +69 -22
  78. package/types/src/class/SafeExit.d.mts +24 -9
  79. package/types/src/class/Setup.d.mts +13 -10
  80. package/types/src/class/Signal.d.mts +73 -17
  81. package/types/src/class/WorkerMainThread.d.mts +47 -39
  82. package/types/src/class/WorkerMainThreadBundled.d.mts +85 -0
  83. package/types/src/class/WorkerThread.d.mts +34 -26
  84. package/types/src/common/Base64URL.d.mts +22 -1
  85. package/types/src/common/Base64URLFromFile.d.mts +16 -0
  86. package/types/src/common/keys.d.mts +1 -0
  87. package/types/src/doc/JSautoDOC.d.mts +3 -19
  88. package/types/src/doc/parsedFile.d.mts +72 -13
  89. package/types/src/function/CreateImmutable.d.mts +27 -2
  90. package/types/src/function/EventCheck.d.mts +15 -0
  91. package/types/src/function/EventObject.d.mts +17 -2
  92. package/types/src/function/GetRuntime.d.mts +2 -0
  93. package/types/src/function/IsAsync.d.mts +18 -0
  94. package/types/src/function/LazyFactory.d.mts +35 -2
  95. package/types/src/function/Timeout.d.mts +16 -0
  96. package/types/src/function/Try.d.mts +52 -1
  97. package/types/src/function/TryAsync.d.mts +22 -1
  98. package/types/src/function/TrySync.d.mts +16 -1
  99. package/types/src/function/TsToMjs.d.mts +19 -0
  100. package/types/src/types/LitExpKeyType.d.mts +1 -0
  101. package/types/src/types/QCBReturn.d.mts +1 -1
  102. package/types/src/types/Runtime.d.mts +1 -0
  103. package/dev/index.mjs +0 -28
  104. package/src/bundler/CompileMJS.mjs +0 -110
  105. package/src/function/WriteFileSafe.mjs +0 -37
  106. package/types/src/bundler/A.d.mts +0 -1
  107. package/types/src/bundler/CompileMJS.d.mts +0 -8
  108. package/types/src/function/WriteFileSafe.d.mts +0 -2
@@ -2,7 +2,6 @@
2
2
 
3
3
  import { closeWorkerThreadEventObject } from '../common/eventObjects.mjs';
4
4
  import { EventCheck } from '../function/EventCheck.mjs';
5
- import { LazyFactory } from '../function/LazyFactory.mjs';
6
5
  import { Try } from '../function/Try.mjs';
7
6
  import { TryAsync } from '../function/TryAsync.mjs';
8
7
  import { Console } from './Console.mjs';
@@ -12,39 +11,43 @@ import { WorkerResult } from './WorkerResult.mjs';
12
11
  /**
13
12
  * @description
14
13
  * - class helper for `WorkerThread` creation;
15
- * @template Receive
16
- * @template Post
14
+ * - before any `Worker` functionaily to be used, you need to setup it with `WorkerThread.setup` and `WorkerMainThread.setup` before runing anytyhing;
15
+ * @template RECEIVE
16
+ * @template POST
17
17
  */
18
18
  export class WorkerThread {
19
19
  /**
20
- * @type {{parentPort:()=>Promise<any>}}
20
+ * @typedef {import('../types/QCBReturn.mjs').QCBReturn} QCBReturn
21
21
  */
22
- static #parentPortRef = LazyFactory(() => {
23
- return { parentPort: async () => (await import('node:worker_threads')).parentPort };
24
- });
22
+ /**
23
+ * @type {Parameters<typeof WorkerThread["setup"]>[0]}
24
+ */
25
+ static #refs = undefined;
25
26
  /**
26
27
  * @description
27
28
  * - 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_>}
29
+ * @template RECEIVE
30
+ * @template POST
31
+ * @param {{parentPort:import('worker_threads')["parentPort"]}} refs
32
+ * -example:
33
+ * ```js
34
+ * import { parentPort } from 'node:worker_threads';
35
+ * ```
36
+ * @returns {typeof WorkerThread<RECEIVE, POST>}
33
37
  * @example
34
38
  * import { WorkerThread } from 'vivth';
39
+ * import { parentPort } from 'node:worker_threads';
35
40
  *
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;
41
+ * export const MyWorkerThreadRef = WorkerThread.setup({ parentPort });
39
42
  */
40
- static setup = (parentPortRef) => {
41
- this.#parentPortRef = parentPortRef;
43
+ static setup(refs) {
44
+ WorkerThread.#refs = refs;
42
45
  return WorkerThread;
43
- };
46
+ }
44
47
  /**
45
48
  * @returns {QChannel<WorkerThread>}
46
49
  */
47
- #qChannel = new QChannel();
50
+ #qChannel = new QChannel('`WorkerThread` individuals');
48
51
  /**
49
52
  * @param {any} ev
50
53
  */
@@ -59,9 +62,13 @@ export class WorkerThread {
59
62
  * import { MyWorkerThread } from './MyWorkerThread.mjs';
60
63
  *
61
64
  * const doubleWorker = new MyWorkerThread((ev, isLastOnQ) => {
62
- * // if(!isLastOnQ) {
65
+ * // if(!isLastOnQ()) {
63
66
  * // return null; // can be used for imperative debouncing;
64
67
  * // }
68
+ * // await fetch('some/path')
69
+ * // if(!isLastOnQ()) {
70
+ * // return;
71
+ * // }
65
72
  * return ev = ev \* 2;
66
73
  * });
67
74
  */
@@ -71,13 +78,14 @@ export class WorkerThread {
71
78
  Try({
72
79
  post: async () => {
73
80
  /**
74
- * @param {MessageEvent<Receive>|Receive} ev
81
+ * @param {MessageEvent<RECEIVE>|RECEIVE} ev
75
82
  * @returns {Promise<void>}
76
83
  */
77
84
  self.onmessage = async function (ev) {
78
- const [_, error] = await TryAsync(async () => {
85
+ const [, error] = await TryAsync(async () => {
79
86
  ev = ev instanceof MessageEvent ? ev.data : ev;
80
87
  if (WorkerThread.#isCloseWorkerEvent(ev)) {
88
+ this_.#qChannel.close();
81
89
  self.onmessage = null;
82
90
  return;
83
91
  }
@@ -96,15 +104,16 @@ export class WorkerThread {
96
104
  };
97
105
  },
98
106
  parentPost: async () => {
99
- const parentPort = await WorkerThread.#parentPortRef.parentPort();
107
+ const { parentPort } = WorkerThread.#refs;
100
108
  /**
101
- * @param {MessageEvent<Receive>|Receive} ev
109
+ * @param {MessageEvent<RECEIVE>|RECEIVE} ev
102
110
  * @returns {Promise<void>}
103
111
  */
104
112
  const listener = async function (ev) {
105
- const [_, error] = await TryAsync(async () => {
113
+ const [, error] = await TryAsync(async () => {
106
114
  ev = ev instanceof MessageEvent ? ev.data : ev;
107
115
  if (WorkerThread.#isCloseWorkerEvent(ev)) {
116
+ this_.#qChannel.close();
108
117
  parentPort.off('message', listener);
109
118
  return;
110
119
  }
@@ -123,7 +132,7 @@ export class WorkerThread {
123
132
  };
124
133
  parentPort.on('message', listener);
125
134
  },
126
- }).then(([_, error]) => {
135
+ }).then(([, error]) => {
127
136
  if (!error) {
128
137
  return;
129
138
  }
@@ -133,19 +142,19 @@ export class WorkerThread {
133
142
  /**
134
143
  * @description
135
144
  * - type helper;
136
- * @type {(ev: Receive, isLastOnQ:boolean) => Post}
145
+ * @type {(ev: RECEIVE, isLastOnQ:QCBReturn["isLastOnQ"]) => POST}
137
146
  */
138
147
  handler;
139
148
  /**
140
149
  * @description
141
150
  * - helper type, hold no actual value;
142
- * @type {Receive}
151
+ * @type {RECEIVE}
143
152
  */
144
- Receive;
153
+ RECEIVE;
145
154
  /**
146
155
  * @description
147
156
  * - helper type, hold no actual value;
148
- * @type {Post}
157
+ * @type {POST}
149
158
  */
150
- Post;
159
+ POST;
151
160
  }
@@ -9,18 +9,23 @@
9
9
  * @param {string} mimeType
10
10
  * @param {(string:string)=>string} btoaFunction
11
11
  * - check your js runtime `btoa`;
12
- * @returns {string}
12
+ * - node compatible:
13
+ * ```js
14
+ * (str, prevBufferEncoding) =>
15
+ * Buffer.from(str, prevBufferEncoding).toString('base64')
16
+ * ```
17
+ * @returns {Base64URLString}
13
18
  * @example
14
19
  * import { Base64URL } from 'vivth'
15
- * import { fileString } from './fileString.mjs';
20
+ * import fileString from './fileString.mjs';
16
21
  *
17
22
  * Base64URL(fileString, 'application/javascript', btoa);
18
23
  */
19
- export const Base64URL = (fileString, mimeType, btoaFunction) => {
24
+ export function Base64URL(fileString, mimeType, btoaFunction) {
20
25
  const utf8 = new TextEncoder().encode(fileString);
21
26
  let binary = '';
22
27
  for (let byte of utf8) {
23
28
  binary += String.fromCharCode(byte);
24
29
  }
25
- return `data:${mimeType};base64,${btoaFunction(binary)}`;
26
- };
30
+ return `data:${mimeType.toString()};base64,${btoaFunction(binary)}`;
31
+ }
@@ -0,0 +1,24 @@
1
+ // @ts-check
2
+
3
+ import { readFile } from 'node:fs/promises';
4
+
5
+ import { lookup } from 'mime-types';
6
+
7
+ /**
8
+ * @description
9
+ * - create inline base64 url;
10
+ * - usage:
11
+ * >- can be extremely usefull to display file on desktop app webview, without exposing http server;
12
+ * >- when using `FSInline`, use [Base64URL](#base64url) instead;
13
+ * @param {string} filePath
14
+ * @returns {Promise<Base64URLString>}
15
+ * @example
16
+ * import { join } from 'node:path'
17
+ *
18
+ * import { Base64URLFromFile, Paths } from 'vivth'
19
+ *
20
+ * await Base64URLFromFile(join(Paths.root, '/path/to/file'));
21
+ */
22
+ export async function Base64URLFromFile(filePath) {
23
+ return `data:${lookup(filePath)};base64,${await readFile(filePath, { encoding: 'base64' })}`;
24
+ }
@@ -0,0 +1,3 @@
1
+ // @ts-check
2
+
3
+ export const keys_vivthGenereteDir = '.vivth';
@@ -5,7 +5,6 @@ import { readFile, stat } from 'node:fs/promises';
5
5
 
6
6
  import chokidar from 'chokidar';
7
7
  import { EventSignal } from '../class/EventSignal.mjs';
8
- import { QChannel } from '../class/QChannel.mjs';
9
8
  import { parsedFile } from './parsedFile.mjs';
10
9
  import { SafeExit } from '../class/SafeExit.mjs';
11
10
  import { Effect } from '../class/Effect.mjs';
@@ -13,10 +12,9 @@ import { Paths } from '../class/Paths.mjs';
13
12
  import { Signal } from '../class/Signal.mjs';
14
13
  import { LazyFactory } from '../function/LazyFactory.mjs';
15
14
  import { TryAsync } from '../function/TryAsync.mjs';
16
- import { Timeout } from '../function/Timeout.mjs';
17
15
  import { Console } from '../class/Console.mjs';
18
16
  import { TsToMjs } from '../function/TsToMjs.mjs';
19
- import { WriteFileSafe } from '../function/WriteFileSafe.mjs';
17
+ import { FileSafe } from '../class/FileSafe.mjs';
20
18
 
21
19
  /**
22
20
  * @typedef {import('fs').Stats} Stats
@@ -47,7 +45,7 @@ const acceptableExt = new Set(['.mjs', '.mts', '.ts']);
47
45
  * >>- `"at"description` are treated as plain `markdown`;
48
46
  * >>- first `"at"${string}` after `"at"description` until `"at"example` will be treated as `javascript` comment block on the `markdown`;
49
47
  * >>- `"at"example` are treated as `javascript` block on the `markdown` file, and should be placed last on the same comment block;
50
- * >>- you can always look at `vivth/src` files to check how the source, and the `README.md` and `index.mjs` is documentation/generation results;
48
+ * >>- you can always look at `vivth/src` files to check how the source, and the `README.md` and `index.mjs` documentation/generation results;
51
49
  */
52
50
  export class JSautoDOC {
53
51
  /**
@@ -69,25 +67,9 @@ export class JSautoDOC {
69
67
  * @param {import('chokidar').ChokidarOptions} [options.option]
70
68
  * - ChokidarOptions;
71
69
  * @example
72
- * import { Console, Setup, JSautoDOC } from 'vivth';
70
+ * import { JSautoDOC } from 'vivth';
73
71
  *
74
- * const { paths, safeExit } = Setup;
75
- *
76
- * new paths({
77
- * root: process?.env?.INIT_CWD ?? process?.cwd(),
78
- * });
79
- *
80
- * new safeExit({
81
- * exitEventNames: ['SIGINT', 'SIGTERM', 'exit'],
82
- * exitCallbackListeners: (eventName) => {
83
- * process.once(eventName, function () {
84
- * safeExit.instance.exiting.correction(true);
85
- * Console.log(`safe exit via "${eventName}"`);
86
- * });
87
- * },
88
- * });
89
- *
90
- * new JSautoDOC({
72
+ * new JSautoDOC({
91
73
  * paths: { dir: 'src', file: 'index.mjs', readMe: 'README.md' },
92
74
  * copyright: 'this library is made and distributed under MIT license;',
93
75
  * tableOfContentTitle: 'list of exported API and typehelpers',
@@ -189,39 +171,32 @@ export class JSautoDOC {
189
171
  * @type {Signal<string>}
190
172
  */
191
173
  #readMESRCContent = LazyFactory(() => new Signal(undefined));
192
- /**
193
- * @type {QChannel<JSautoDOC>}
194
- */
195
- #modQ = new QChannel();
196
- #generatedREADME_md = new Effect(async ({ subscribe }) => {
197
- this.#modQ.callback(this, async ({ isLastOnQ }) => {
198
- if (!isLastOnQ) {
199
- return;
200
- }
201
- await Timeout(1000);
202
- const contentSRC = subscribe(this.#readMESRCContent).value;
203
- const filepaths = subscribe(this.#filePaths).value;
204
- if (!contentSRC || !filepaths) {
205
- return;
206
- }
207
- const { readme, mjsFile } = await this.#generateFromSRC(contentSRC, filepaths);
208
- const readmePath = join(Paths.root, this.#paths.readMe);
209
- const mjsFilePath = join(Paths.root, this.#paths.file);
210
- const [[, errorWriteReadme], [, errorWriteMjsFile]] = await Promise.all([
211
- WriteFileSafe(readmePath, readme, { encoding }),
212
- WriteFileSafe(join(Paths.root, this.#paths.file), mjsFile, { encoding }),
213
- ]);
214
- if (!errorWriteMjsFile) {
215
- Console.info({ message: `successfully generate: '${mjsFilePath}'` });
216
- } else {
217
- Console.error({ message: `unable to generate: '${mjsFilePath}';`, errorWriteMjsFile });
218
- }
219
- if (!errorWriteReadme) {
220
- Console.info({ message: `successfully generate: '${readmePath}'` });
221
- } else {
222
- Console.error({ message: `unable to generate: '${readmePath}';`, errorWriteReadme });
223
- }
224
- });
174
+ #generatedREADME_md = new Effect(async ({ subscribe, isLastCalled }) => {
175
+ const contentSRC = subscribe(this.#readMESRCContent).value;
176
+ const filepaths = subscribe(this.#filePaths).value;
177
+ if (!(await isLastCalled(100)) || !contentSRC || !filepaths) {
178
+ return;
179
+ }
180
+ const { readme, mjsFile } = await this.#generateFromSRC(contentSRC, filepaths);
181
+ if (!(await isLastCalled())) {
182
+ return;
183
+ }
184
+ const readmePath = join(Paths.root, this.#paths.readMe);
185
+ const mjsFilePath = join(Paths.root, this.#paths.file);
186
+ const [[, errorWriteReadme], [, errorWriteMjsFile]] = await Promise.all([
187
+ FileSafe.write(readmePath, readme, { encoding }),
188
+ FileSafe.write(mjsFilePath, mjsFile, { encoding }),
189
+ ]);
190
+ if (!errorWriteReadme) {
191
+ Console.info({ message: `successfully generate: '${readmePath}'` });
192
+ } else {
193
+ Console.error({ message: `unable to generate: '${readmePath}';`, errorWriteReadme });
194
+ }
195
+ if (!errorWriteMjsFile) {
196
+ Console.info({ message: `successfully generate: '${mjsFilePath}'` });
197
+ } else {
198
+ Console.error({ message: `unable to generate: '${mjsFilePath}';`, errorWriteMjsFile });
199
+ }
225
200
  });
226
201
  /**
227
202
  * @param {string} string
@@ -355,12 +330,13 @@ export class JSautoDOC {
355
330
  return;
356
331
  }
357
332
  dispatch.value = new parsedFile(path__, encoding);
333
+ await dispatch.value.parse();
358
334
  dispatch.subscribers.notify();
359
335
  this.#filePaths.subscribers.notify(async ({ signalInstance }) => {
360
336
  Console.info({ [eventName]: path__ });
361
337
  signalInstance.value.add(path__);
362
338
  });
363
- }).then(([_, error]) => {
339
+ }).then(([, error]) => {
364
340
  if (!error) {
365
341
  return;
366
342
  }
@@ -35,34 +35,35 @@ export class parsedFile {
35
35
  }
36
36
  this.#relativePath = Paths.normalize(relative(root, this.#fullPath));
37
37
  this.#encoding = encoding;
38
- this.content.parsed().then(({ details, error, exportName }) => {
39
- if (error) {
40
- return;
41
- }
42
- for (let i = 0; i < details.length; i++) {
43
- const [
44
- _,
45
- __,
46
- instanceOrStaticDef,
47
- fullDescription,
48
- isExport,
49
- typeOfVar,
50
- getterOrSetter,
51
- namedVar,
52
- ] = details[i];
53
- const interpreted = this.#interpreteArrayDesc(
54
- exportName,
55
- instanceOrStaticDef,
56
- fullDescription,
57
- isExport,
58
- typeOfVar,
59
- getterOrSetter,
60
- namedVar
61
- );
62
- this.documented.readme.add(interpreted);
63
- }
64
- });
65
38
  }
39
+ parse = async () => {
40
+ const { details, error, exportName } = await this.content.parsed();
41
+ if (error) {
42
+ return;
43
+ }
44
+ for (let i = 0; i < details.length; i++) {
45
+ const [
46
+ _,
47
+ __,
48
+ instanceOrStaticDef,
49
+ fullDescription,
50
+ isExport,
51
+ typeOfVar,
52
+ getterOrSetter,
53
+ namedVar,
54
+ ] = details[i];
55
+ const interpreted = this.#interpreteArrayDesc(
56
+ exportName,
57
+ instanceOrStaticDef,
58
+ fullDescription,
59
+ isExport,
60
+ typeOfVar,
61
+ getterOrSetter,
62
+ namedVar
63
+ );
64
+ this.documented.readme.add(interpreted);
65
+ }
66
+ };
66
67
  documented = LazyFactory(() => {
67
68
  return {
68
69
  typedef: async () => {
@@ -373,13 +374,13 @@ export class parsedFile {
373
374
  const this_ = this;
374
375
  return {
375
376
  /**
376
- * @type {string}
377
+ * @returns {string}
377
378
  */
378
379
  get withExt() {
379
380
  return basename(this_.#fullPath);
380
381
  },
381
382
  /**
382
- * @type {string}
383
+ * @returns {string}
383
384
  */
384
385
  get noExt() {
385
386
  return basename(this_.#fullPath, extname(this_.#fullPath));
@@ -390,13 +391,13 @@ export class parsedFile {
390
391
  const this_ = this;
391
392
  return {
392
393
  /**
393
- * @type {string}
394
+ * @returns {string}
394
395
  */
395
396
  get relative() {
396
397
  return this_.#relativePath;
397
398
  },
398
399
  /**
399
- * @type {string}
400
+ * @returns {string}
400
401
  */
401
402
  get full() {
402
403
  return this_.#fullPath;
@@ -407,13 +408,13 @@ export class parsedFile {
407
408
  const this_ = this;
408
409
  return {
409
410
  /**
410
- * @type {string}
411
+ * @returns {string}
411
412
  */
412
413
  get relative() {
413
414
  return dirname(this_.#relativePath);
414
415
  },
415
416
  /**
416
- * @type {string}
417
+ * @returns {string}
417
418
  */
418
419
  get full() {
419
420
  return dirname(this_.#fullPath);
@@ -424,7 +425,7 @@ export class parsedFile {
424
425
  const this_ = this;
425
426
  return {
426
427
  /**
427
- * @type {string|undefined}
428
+ * @returns {string|undefined}
428
429
  */
429
430
  get withDot() {
430
431
  if (this_.isDirectory && !this_.isFile) {
@@ -433,7 +434,7 @@ export class parsedFile {
433
434
  return extname(this_.#fullPath);
434
435
  },
435
436
  /**
436
- * @type {string|undefined}
437
+ * @returns {string|undefined}
437
438
  */
438
439
  get noDot() {
439
440
  if (this_.isDirectory && !this_.isFile) {
@@ -515,7 +516,7 @@ export class parsedFile {
515
516
  };
516
517
  });
517
518
  /**
518
- * @type {[Promise<any>, undefined]|[undefined, Error]}
519
+ * @returns {[Promise<any>, undefined]|[undefined, Error]}
519
520
  */
520
521
  get importAsModuleJS() {
521
522
  const realTimePath = `${this.#fullPath}?${Date.now()}`;
@@ -9,14 +9,14 @@ import { TrySync } from './TrySync.mjs';
9
9
  * - function for create immutable object;
10
10
  * - usefull for binding immutable object to global for shared object:
11
11
  * >- e.g. to window object in browser;
12
- * @template {Object} P
13
- * @template {Object} O
12
+ * @template {Object} PARENT
13
+ * @template {Object} OBJECT
14
14
  * @param {string} keyName
15
- * @param {P} parent
16
- * @param {(this:P)=>O} object
15
+ * @param {PARENT} parent
16
+ * @param {(this:PARENT)=>OBJECT} object
17
17
  * @param {Object} [options]
18
18
  * @param {boolean} [options.lazy]
19
- * @return {O}
19
+ * @return {OBJECT}
20
20
  * @example
21
21
  * import { CreateImmutable } from 'vivth';
22
22
  *
@@ -29,7 +29,7 @@ import { TrySync } from './TrySync.mjs';
29
29
  * getMap(name_) => mappedObject.get(name_),
30
30
  * })
31
31
  */
32
- export const CreateImmutable = (parent, keyName, object, { lazy = true } = {}) => {
32
+ export function CreateImmutable(parent, keyName, object, { lazy = true } = {}) {
33
33
  if (!parent || typeof parent !== 'object') {
34
34
  Console.error({
35
35
  object,
@@ -39,7 +39,7 @@ export const CreateImmutable = (parent, keyName, object, { lazy = true } = {}) =
39
39
  });
40
40
  return;
41
41
  }
42
- let [_, error] = TrySync(() => {
42
+ let [, error] = TrySync(() => {
43
43
  Object.defineProperty(parent, keyName, {
44
44
  value: lazy ? LazyFactory(() => object.call(parent)) : object.call(parent),
45
45
  writable: false,
@@ -48,7 +48,7 @@ export const CreateImmutable = (parent, keyName, object, { lazy = true } = {}) =
48
48
  });
49
49
  });
50
50
  if (error) {
51
- [_, error] = TrySync(() => {
51
+ [, error] = TrySync(() => {
52
52
  parent[keyName] = lazy ? LazyFactory(() => object.call(parent)) : object.call(parent);
53
53
  });
54
54
  }
@@ -61,4 +61,4 @@ export const CreateImmutable = (parent, keyName, object, { lazy = true } = {}) =
61
61
  return;
62
62
  }
63
63
  return parent[keyName];
64
- };
64
+ }
@@ -17,11 +17,11 @@ import { EventNameSpace } from '../common/EventNameSpace.mjs';
17
17
  * // or manually {[EventNameSpace]:'worker:exit'};
18
18
  * // which either will result true;
19
19
  */
20
- export const EventCheck = (object, eventObject) => {
20
+ export function EventCheck(object, eventObject) {
21
21
  return (
22
22
  object &&
23
23
  typeof object === 'object' &&
24
24
  EventNameSpace in object &&
25
25
  object[EventNameSpace] === eventObject[EventNameSpace]
26
26
  );
27
- };
27
+ }
@@ -4,9 +4,9 @@ import { EventNameSpace } from '../common/EventNameSpace.mjs';
4
4
  /**
5
5
  * @description
6
6
  * - simple object generation function helper for [EventCheck](#eventcheck), for multiple context, eg: `mainThread` <-> `workerThread`;
7
- * @template {string} N
8
- * @param {N} name
9
- * @returns {{[EventNameSpace]: N}}
7
+ * @template {string} NAME
8
+ * @param {NAME} name
9
+ * @returns {{[EventNameSpace]: NAME}}
10
10
  * @example
11
11
  * import { EventCheck } from 'vivth';
12
12
  * import { incomingMessage } from './some/where.mjs';
@@ -16,6 +16,6 @@ import { EventNameSpace } from '../common/EventNameSpace.mjs';
16
16
  * // or manually {[EventNameSpace]:'worker:exit'};
17
17
  * // which either will result true;
18
18
  */
19
- export const EventObject = (name) => {
19
+ export function EventObject(name) {
20
20
  return { [EventNameSpace]: name };
21
- };
21
+ }
@@ -0,0 +1,38 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * @typedef {import("../types/Runtime.mjs").Runtime} Runtime
5
+ */
6
+
7
+ /**
8
+ * @type {Runtime|undefined}
9
+ */
10
+ let runtime = undefined;
11
+
12
+ /**
13
+ * @description
14
+ * - detects the current JavaScript runtime;
15
+ * @type {()=>Runtime}
16
+ * @example
17
+ * import { GetRuntime } form 'vivth';
18
+ *
19
+ * const runtime = GetRuntime();
20
+ */
21
+ export function GetRuntime() {
22
+ if (!runtime) {
23
+ if (typeof Bun !== 'undefined') {
24
+ runtime = 'bun';
25
+ }
26
+ // @ts-expect-error
27
+ else if (typeof Deno !== 'undefined') {
28
+ runtime = 'deno';
29
+ } else if (typeof process !== 'undefined' && process.versions?.node) {
30
+ runtime = 'node';
31
+ } else if (typeof window !== 'undefined' && typeof document !== 'undefined') {
32
+ runtime = 'browser';
33
+ } else {
34
+ runtime = 'unknown';
35
+ }
36
+ }
37
+ return runtime;
38
+ }
@@ -18,6 +18,6 @@
18
18
  * IsAsync(a); // false
19
19
  * IsAsync(b); // true
20
20
  */
21
- export const IsAsync = (functionReference) => {
21
+ export function IsAsync(functionReference) {
22
22
  return functionReference.constructor.name === 'AsyncFunction';
23
- };
23
+ }