vivth 1.2.3 → 1.3.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 (71) hide show
  1. package/README.md +608 -586
  2. package/README.src.md +5 -1
  3. package/bun.lock +6 -0
  4. package/index.mjs +10 -6
  5. package/package.json +3 -1
  6. package/src/bundler/CompileJS.mjs +11 -8
  7. package/src/bundler/EsBundler.mjs +4 -2
  8. package/src/bundler/FSInline.mjs +3 -0
  9. package/src/bundler/FSInlineAnalyzer.mjs +31 -7
  10. package/src/bundler/FSInlineBundled.mjs +5 -1
  11. package/src/bundler/adds/ToBundledJSPlugin.mjs +3 -4
  12. package/src/class/Console.mjs +12 -4
  13. package/src/class/Derived.mjs +5 -1
  14. package/src/class/Effect.mjs +6 -6
  15. package/src/class/EnvSignal.mjs +1 -8
  16. package/src/class/EventSignal.mjs +8 -7
  17. package/src/class/FileSafe.mjs +1 -1
  18. package/src/class/ListSignal.mjs +18 -10
  19. package/src/class/LitExp.mjs +241 -204
  20. package/src/class/Paths.mjs +10 -8
  21. package/src/class/QChannel.mjs +14 -7
  22. package/src/class/SafeExit.mjs +16 -7
  23. package/src/class/Signal.mjs +8 -7
  24. package/src/class/WorkerMainThread.mjs +45 -24
  25. package/src/class/WorkerMainThreadBundled.mjs +42 -24
  26. package/src/class/WorkerThread.mjs +21 -7
  27. package/src/common/Base64URL.mjs +2 -2
  28. package/src/common/Base64URLFromFile.mjs +1 -1
  29. package/src/doc/JSautoDOC.mjs +99 -62
  30. package/src/doc/correctBeforeParse.mjs +139 -0
  31. package/src/doc/parsedFile.mjs +127 -76
  32. package/src/function/CreateImmutable.mjs +12 -7
  33. package/src/function/GetRuntime.mjs +8 -3
  34. package/src/function/LazyFactory.mjs +10 -4
  35. package/src/function/Try.mjs +4 -1
  36. package/src/function/TryAsync.mjs +2 -1
  37. package/src/function/TrySync.mjs +3 -1
  38. package/src/function/TsToMjs.mjs +7 -4
  39. package/src/types/AnyButUndefined.mjs +1 -0
  40. package/src/types/LitExpResultType.mjs +7 -0
  41. package/src/types/Runtime.mjs +1 -1
  42. package/tsconfig.json +27 -5
  43. package/types/dev/workerThreadClass.d.mts +1 -1
  44. package/types/index.d.mts +7 -6
  45. package/types/src/bundler/CompileJS.d.mts +14 -9
  46. package/types/src/bundler/EsBundler.d.mts +1 -1
  47. package/types/src/class/Derived.d.mts +4 -64
  48. package/types/src/class/Effect.d.mts +8 -8
  49. package/types/src/class/EnvSignal.d.mts +0 -1
  50. package/types/src/class/EventSignal.d.mts +5 -5
  51. package/types/src/class/FileSafe.d.mts +2 -2
  52. package/types/src/class/ListSignal.d.mts +1 -1
  53. package/types/src/class/LitExp.d.mts +49 -53
  54. package/types/src/class/Paths.d.mts +4 -4
  55. package/types/src/class/QChannel.d.mts +1 -1
  56. package/types/src/class/SafeExit.d.mts +3 -3
  57. package/types/src/class/Signal.d.mts +3 -3
  58. package/types/src/class/WorkerMainThread.d.mts +13 -8
  59. package/types/src/class/WorkerMainThreadBundled.d.mts +13 -8
  60. package/types/src/class/WorkerThread.d.mts +4 -4
  61. package/types/src/common/Base64URL.d.mts +2 -2
  62. package/types/src/common/Base64URLFromFile.d.mts +2 -2
  63. package/types/src/doc/JSautoDOC.d.mts +33 -12
  64. package/types/src/doc/correctBeforeParse.d.mts +2 -0
  65. package/types/src/doc/parsedFile.d.mts +7 -10
  66. package/types/src/function/CreateImmutable.d.mts +2 -2
  67. package/types/src/function/Try.d.mts +2 -2
  68. package/types/src/function/TryAsync.d.mts +2 -2
  69. package/types/src/function/TrySync.d.mts +3 -2
  70. package/types/src/function/TsToMjs.d.mts +2 -2
  71. package/types/src/types/LitExpResultType.d.mts +7 -0
@@ -18,6 +18,22 @@ export class LitExp {
18
18
  /**
19
19
  * @typedef {import("../types/LitExpKeyType.mjs").LitExpKeyType} LitExpKeyType
20
20
  */
21
+
22
+ /**
23
+ * @description
24
+ * - to escape special chars from string literal;
25
+ * - returned value can be used to create instance of RegExp;
26
+ * @param {string} string
27
+ * @returns {string}
28
+ * @example
29
+ * import { LitExp } from 'vivt';
30
+ *
31
+ * const escapedLiteral = LitExp.escape(`something[][;alerk325]`);
32
+ * new RegExp(escapedLiteral, 'g');
33
+ */
34
+ static escape = (string) => {
35
+ return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
36
+ };
21
37
  /**
22
38
  * @description
23
39
  * - constructor helper;
@@ -57,7 +73,7 @@ export class LitExp {
57
73
  * // recommended to end the template literal with any string but `key`;
58
74
  * })()
59
75
  */
60
- static prepare = (keysAndDefaultValuePair) => {
76
+ static prepare(keysAndDefaultValuePair) {
61
77
  return TrySync(() => {
62
78
  for (const key in keysAndDefaultValuePair) {
63
79
  const regex = keysAndDefaultValuePair[key];
@@ -69,7 +85,7 @@ export class LitExp {
69
85
  return (templateStringArray, ...values) =>
70
86
  new LitExp(keysAndDefaultValuePair, templateStringArray, ...values);
71
87
  });
72
- };
88
+ }
73
89
  /**
74
90
  * @private
75
91
  * @param {KEYS} keys
@@ -101,22 +117,31 @@ export class LitExp {
101
117
  * @param {TemplateStringsArray} strings
102
118
  * @returns {ReturnType<typeof TrySync<string[]>>}
103
119
  */
104
- static #processTemplate = (instance_rules, intance_values, valueHandler, strings) => {
120
+ static #processTemplate(instance_rules, intance_values, valueHandler, strings) {
105
121
  return TrySync(() => {
122
+ /**
123
+ * @type {string[]}
124
+ */
106
125
  const result = [];
107
126
  const values = intance_values;
108
127
  const stringsLength = strings.length;
109
128
  for (let i = 0; i < stringsLength; i++) {
110
129
  const string = strings[i];
130
+ if (string === undefined) {
131
+ throw new Error('string undefined');
132
+ }
111
133
  if (i + 1 == stringsLength && string === '') {
112
- result.push('(?:\\s*?|$)');
134
+ result.push('(?:\\s+?|$)');
113
135
  } else {
114
- result.push(string);
136
+ result.push(LitExp.escape(string));
115
137
  }
116
138
  if (i < values.length) {
117
139
  const value = values[i];
140
+ if (value === undefined || instance_rules[value] === undefined) {
141
+ continue;
142
+ }
118
143
  const [valueHandled, errorValue] = valueHandler(value, instance_rules[value]);
119
- if (errorValue || !valueHandled) {
144
+ if (errorValue || valueHandled === '') {
120
145
  throw errorValue;
121
146
  }
122
147
  result.push(valueHandled);
@@ -124,7 +149,7 @@ export class LitExp {
124
149
  }
125
150
  return result;
126
151
  });
127
- };
152
+ }
128
153
  /**
129
154
  * @param {Parameters<LitExp<KEYS>["evaluate"]["execGroups"]>[1] &
130
155
  * { absoluteLeadAndFollowing: boolean }} options
@@ -133,7 +158,7 @@ export class LitExp {
133
158
  #regExp = ({ flags, whiteSpaceSensitive, absoluteLeadAndFollowing }) => {
134
159
  return TrySync(() => {
135
160
  let regExpStringCache;
136
- if (!this.#regExpStringCache) {
161
+ if (this.#regExpStringCache === undefined) {
137
162
  const [regExpStringCache, error] = LitExp.#processTemplate(
138
163
  this.#keyRules,
139
164
  this.#values,
@@ -145,10 +170,10 @@ export class LitExp {
145
170
  }
146
171
  this.#regExpStringCache = regExpStringCache.join('');
147
172
  }
148
- if (!whiteSpaceSensitive) {
149
- regExpStringCache = this.#regExpStringCache.replace(/\s+/g, `\\s+`);
150
- } else {
173
+ if (whiteSpaceSensitive) {
151
174
  regExpStringCache = this.#regExpStringCache;
175
+ } else {
176
+ regExpStringCache = this.#regExpStringCache.replace(/\s+/g, `\\s+`);
152
177
  }
153
178
  return new RegExp(
154
179
  absoluteLeadAndFollowing ? `\^${regExpStringCache}\$` : regExpStringCache,
@@ -163,75 +188,83 @@ export class LitExp {
163
188
  #regexToMatchAll = ({ flags, whiteSpaceSensitive }) => {
164
189
  return TrySync(() => {
165
190
  let regExpToMatchStringCache;
166
- if (!this.#regExpToMatchStringCache) {
191
+ if (this.#regExpToMatchStringCache === undefined) {
167
192
  const [regExpToMatchStringCache, error] = LitExp.#processTemplate(
168
193
  this.#keyRules,
169
194
  this.#values,
170
195
  LitExp.#namedChapture,
171
196
  this.#templateStringArray
172
197
  );
173
- if (error) {
198
+ if (error || regExpToMatchStringCache === undefined) {
174
199
  throw error;
175
200
  }
176
201
  this.#regExpToMatchStringCache = regExpToMatchStringCache.join('');
177
202
  }
178
- if (!whiteSpaceSensitive) {
179
- regExpToMatchStringCache = this.#regExpToMatchStringCache.replace(/\s+/g, `\\s+`);
180
- } else {
203
+ if (whiteSpaceSensitive) {
181
204
  regExpToMatchStringCache = this.#regExpToMatchStringCache;
205
+ } else {
206
+ regExpToMatchStringCache = this.#regExpToMatchStringCache.replace(/\s+/g, `\\s+`);
182
207
  }
183
208
  return new RegExp(`\(${regExpToMatchStringCache}\)`, flags);
184
209
  });
185
210
  };
186
-
211
+ /**
212
+ * @typedef {ReturnType<LitExp<KEYS>["evaluate"]["execGroups"]>} ExecGroups
213
+ * @typedef {ExecGroups extends [infer First, ...any] ? First : undefined} FirstGroup
214
+ * @typedef {FirstGroup extends { result: any } ? Partial<FirstGroup["result"]> : undefined} Overrides
215
+ */
187
216
  /**
188
217
  * @description
189
218
  * - instance methods for generating things;
190
219
  */
191
- make = LazyFactory(() => ({
192
- /**
193
- * @instance make
194
- * @description
195
- * - to make string based on the template literal;
196
- * @param {Partial<ReturnType<LitExp<KEYS>["evaluate"]["execGroups"]>>[0]["result"]} overrides
197
- * @returns {string}
198
- * @example
199
- * import { LitExp } from 'vivth';
200
- *
201
- * const [literal, errorPreparing] = LitExp.prepare({
202
- * myKey: false,
203
- * ...keyCaptureLogicPair
204
- * })
205
- *
206
- * // asuming no error
207
- * litExp_instance = `templateLiteral:${'myKey'};`;
208
- * const [result, error] = litExp_instance.make.string({
209
- * myKey: 'actualvalue',
210
- * });
211
- *
212
- * console.log(result); // "templateLiteral:actualvalue;"
213
- */
214
- string: (overrides) => {
215
- return TrySync(() => {
216
- const [res, error] = LitExp.#processTemplate(
217
- this.#keyRules,
218
- this.#values,
219
- (key) => {
220
- return TrySync(() => {
221
- return overrides[key.toString()] ?? '';
222
- });
223
- },
224
- this.#templateStringArray
225
- );
226
- if (error || !res) {
227
- throw error;
228
- }
229
- return res.join('');
230
- })[0];
231
- },
232
- }));
220
+ make = LazyFactory(() => {
221
+ const this_ = this;
222
+ return {
223
+ /**
224
+ * @instance make
225
+ * @description
226
+ * - to make string based on the template literal;
227
+ * @param {Partial<{ [K in keyof KEYS]?: string }>} overrides
228
+ * @returns {string|undefined}
229
+ * @example
230
+ * import { LitExp } from 'vivth';
231
+ *
232
+ * const [literal, errorPreparing] = LitExp.prepare({
233
+ * myKey: false,
234
+ * ...keyCaptureLogicPair
235
+ * })
236
+ *
237
+ * // asuming no error
238
+ * litExp_instance = `templateLiteral:${'myKey'};`;
239
+ * const [result, error] = litExp_instance.make.string({
240
+ * myKey: 'actualvalue',
241
+ * });
242
+ *
243
+ * console.log(result); // "templateLiteral:actualvalue;"
244
+ */
245
+ string: (overrides) => {
246
+ return TrySync(() => {
247
+ const [res, error] = LitExp.#processTemplate(
248
+ this_.#keyRules,
249
+ this_.#values,
250
+ // @ts-expect-error
251
+ (key) => {
252
+ return TrySync(() => {
253
+ return overrides[key];
254
+ });
255
+ },
256
+ this_.#templateStringArray
257
+ );
258
+ if (error) {
259
+ throw error;
260
+ }
261
+ return res.join('');
262
+ })[0];
263
+ },
264
+ };
265
+ });
233
266
  /**
234
- * @type {string}
267
+ * @type {string|undefined}
235
268
  */
236
269
  #regExpStringCache;
237
270
  /**
@@ -240,152 +273,81 @@ export class LitExp {
240
273
  * @param {keyof KEYS} value
241
274
  * @returns {ReturnType<typeof TrySync<string>>}
242
275
  */
243
- static #namedChapture = (value, regex) => {
276
+ static #namedChapture(value, regex) {
244
277
  return TrySync(() => {
245
- const capture = !regex ? `[\\s\\S]*?` : regex.source;
278
+ const capture = regex === false ? `[\\s\\S]*?` : regex.source;
246
279
  return `(?<${value.toString()}>${capture})`;
247
280
  });
248
- };
281
+ }
249
282
  /**
250
- * @type {string}
283
+ * @type {string|undefined}
251
284
  */
252
285
  #regExpToMatchStringCache;
253
286
  /**
254
287
  * @description
255
288
  * - methods collections to evaluate string with `Literal Expression`;
256
289
  */
257
- evaluate = LazyFactory(() => ({
258
- /**
259
- * @instance evaluate
260
- * @description
261
- * - to exec and grouped based on `key`;
262
- * @param {string} string
263
- * @param {Object} options
264
- * @param {ConstructorParameters<typeof RegExp>[1]} options.flags
265
- * @param {boolean} options.whiteSpaceSensitive
266
- * - true: leave any whitespace as is to be used as regex detection;
267
- * - false: convert all whitespace to `\s+`;
268
- * @param {boolean} options.absoluteLeadAndFollowing
269
- * - false: standard capture;
270
- * - true: add `^` and `$` to capture definition:
271
- * >- meaning string will have to match starting and end of line from capture definition;
272
- * @returns {ReturnType<typeof TrySync<{
273
- * result:{ whole:string, named: Record<keyof KEYS, string>},
274
- * regexp:RegExp}>>
275
- * }
276
- * @example
277
- * import { LitExp } from 'vivth';
278
- *
279
- * const [literal, errorPreparing] = LitExp.prepare({
280
- * myKey: false,
281
- * ...keyCaptureLogicPair
282
- * })
283
- *
284
- * // asuming no eror
285
- * const litExp_instance = literal`templateLiteral:${'myKey'};`
286
- *
287
- * const [{
288
- * result:{ // asuming there's no error
289
- * named: { myKey },
290
- * whole,
291
- * },
292
- * regex, // for reference
293
- * }, error] = litExp_instance.evaluate.execGroups(
294
- * `templateLiteral:Something;`,
295
- * { ...options }
296
- * )
297
- *
298
- * console.log(whole); // "templateLiteral:Something;"
299
- * console.log(myKey); // "Something"
300
- */
301
- execGroups: (string, options) => {
302
- // @ts-expect-error
303
- return TrySync(() => {
304
- const [regexp, error] = this.#regExp(options);
305
- if (error || !regexp) {
306
- throw error;
307
- }
308
- const execResult = regexp.exec(string);
309
- const whole = execResult[1];
310
- const named = execResult?.groups;
311
- const result = { named, whole };
312
- if (!named) {
313
- throw new Error(
314
- JSON.stringify({
315
- regexpSource: regexp.source,
316
- message: 'no match is found',
317
- sugestion: 'make sure all `keys` values will capture any scenario',
318
- })
319
- );
320
- }
321
- return { result, regexp };
322
- });
323
- },
324
- /**
325
- * @instance evaluate
326
- * @description
327
- * - to match all and grouped based on `key`;
328
- * @param {Parameters<LitExp<KEYS>["evaluate"]["execGroups"]>[0]} string
329
- * @param {Omit<Parameters<LitExp<KEYS>["evaluate"]["execGroups"]>[1], 'absoluteLeadAndFollowing'>} options
330
- * @returns {ReturnType<typeof TrySync<{result:{whole:string[], named:Array<Record<keyof KEYS, string>>},
331
- * regexp: RegExp}>>
332
- * }
333
- * @example
334
- * import { LitExp, Console } from 'vivth';
335
- *
336
- * const [literal, errorPreparing] = LitExp.prepare({
337
- * myKey: false,
338
- * ...keyCaptureLogicPair
339
- * })
340
- *
341
- * // asuming no error;
342
- * litExp_instance = literal`templateLiteral:${'myKey'};`
343
- *
344
- * const [resultOfMatchedAllAndGrouped, error] = litExp_instance.evaluate.matchedAllAndGrouped(
345
- * `templateLiteral:Something;
346
- * templateLiteral:SomethingElse;`,
347
- * { ...options }
348
- * )
349
- * (()=>{
350
- * if (error) {
351
- * Console.error(error);
352
- * return;
353
- * }
354
- * const {
355
- * result: {
356
- * whole: [whole0, whole1],
357
- * named: [
358
- * { myKey: myKeyExec0, },
359
- * { myKey: myKeyExec1, },
360
- * ],
361
- * },
362
- * regexp
363
- * } = resultOfMatchedAllAndGrouped;
364
- *
365
- * console.log(whole0); // "templateLiteral:Something;"
366
- * console.log(whole1); // "templateLiteral:SomethingElse;"
367
- * console.log(myKeyExec0); // "Something"
368
- * console.log(myKeyExec1); // "SomethingElse"
369
- * })()
370
- */
371
- matchedAllAndGrouped: (string, options) => {
372
- return TrySync(() => {
373
- const [regexp, error] = this.#regexToMatchAll(options);
374
- if (error || !regexp) {
375
- throw error;
376
- }
377
- /**
378
- * @type {Array<Record<keyof KEYS, string>>}
379
- */
380
- const named = [];
381
- const whole = [];
382
- /**
383
- * @type {{whole:string[], named:Array<Record<keyof KEYS, string>>}}
384
- */
385
- const result = { named, whole };
386
- const matchedAll = string.matchAll(regexp);
387
- for (const match of matchedAll) {
388
- if (!match.groups) {
290
+ evaluate = LazyFactory(() => {
291
+ const this_ = this;
292
+ return {
293
+ /**
294
+ * @instance evaluate
295
+ * @description
296
+ * - to exec and grouped based on `key`;
297
+ * @param {string} string
298
+ * @param {Object} options
299
+ * @param {ConstructorParameters<typeof RegExp>[1]} options.flags
300
+ * @param {boolean} options.whiteSpaceSensitive
301
+ * - true: leave any whitespace as is to be used as regex detection;
302
+ * - false: convert all whitespace to `\s+`;
303
+ * @param {boolean} options.absoluteLeadAndFollowing
304
+ * - false: standard capture;
305
+ * - true: add `^` and `$` to capture definition:
306
+ * >- meaning string will have to match starting and end of line from capture definition;
307
+ * @returns {ReturnType<typeof TrySync<{
308
+ * result:{ whole:string, named: Record<keyof KEYS, string>},
309
+ * regexp:RegExp}>>
310
+ * }
311
+ * @example
312
+ * import { LitExp } from 'vivth';
313
+ *
314
+ * const [literal, errorPreparing] = LitExp.prepare({
315
+ * myKey: false,
316
+ * ...keyCaptureLogicPair
317
+ * })
318
+ *
319
+ * // asuming no eror
320
+ * const litExp_instance = literal`templateLiteral:${'myKey'};`
321
+ *
322
+ * const [{
323
+ * result:{ // asuming there's no error
324
+ * named: { myKey },
325
+ * whole,
326
+ * },
327
+ * regex, // for reference
328
+ * }, error] = litExp_instance.evaluate.execGroups(
329
+ * `templateLiteral:Something;`,
330
+ * { ...options }
331
+ * )
332
+ *
333
+ * console.log(whole); // "templateLiteral:Something;"
334
+ * console.log(myKey); // "Something"
335
+ */
336
+ execGroups(string, options) {
337
+ // @ts-expect-error
338
+ return TrySync(() => {
339
+ const [regexp, error] = this_.#regExp(options);
340
+ if (error) {
341
+ throw error;
342
+ }
343
+ const execResult = regexp.exec(string);
344
+ if (execResult === null) {
345
+ return undefined;
346
+ }
347
+ const whole = execResult[1];
348
+ const named = execResult?.groups;
349
+ const result = { named, whole };
350
+ if (named === undefined) {
389
351
  throw new Error(
390
352
  JSON.stringify({
391
353
  regexpSource: regexp.source,
@@ -394,12 +356,87 @@ export class LitExp {
394
356
  })
395
357
  );
396
358
  }
397
- whole.push(match[1]);
398
- // @ts-expect-error
399
- named.push(match.groups);
400
- }
401
- return { result, regexp };
402
- });
403
- },
404
- }));
359
+ return { result, regexp };
360
+ });
361
+ },
362
+ /**
363
+ * @instance evaluate
364
+ * @description
365
+ * - to match all and grouped based on `key`;
366
+ * @param {Parameters<LitExp<KEYS>["evaluate"]["execGroups"]>[0]} string
367
+ * @param {Omit<Parameters<LitExp<KEYS>["evaluate"]["execGroups"]>[1], 'absoluteLeadAndFollowing'>} options
368
+ * @returns {ReturnType<typeof TrySync<import('../types/LitExpResultType.mjs').LitExpResultType<KEYS>>>
369
+ * }
370
+ * @example
371
+ * import { LitExp, Console } from 'vivth';
372
+ *
373
+ * const [literal, errorPreparing] = LitExp.prepare({
374
+ * myKey: false,
375
+ * ...keyCaptureLogicPair
376
+ * })
377
+ *
378
+ * // asuming no error;
379
+ * litExp_instance = literal`templateLiteral:${'myKey'};`
380
+ *
381
+ * const [resultOfMatchedAllAndGrouped, error] = litExp_instance.evaluate.matchedAllAndGrouped(
382
+ * `templateLiteral:Something;
383
+ * templateLiteral:SomethingElse;`,
384
+ * { ...options }
385
+ * )
386
+ * (()=>{
387
+ * if (error) {
388
+ * Console.error(error);
389
+ * return;
390
+ * }
391
+ * const {
392
+ * result: { whole, named },
393
+ * regexp
394
+ * } = resultOfMatchedAllAndGrouped;
395
+ *
396
+ * named.foreach(({myKey})=>{
397
+ * // code
398
+ * })
399
+ * whole.foreach((capturedString)=>{
400
+ * // code
401
+ * })
402
+ * })()
403
+ */
404
+ matchedAllAndGrouped: (string, options) => {
405
+ return TrySync(() => {
406
+ const [regexp, error] = this.#regexToMatchAll(options);
407
+ if (error) {
408
+ throw error;
409
+ }
410
+ /**
411
+ * @type {Array<Record<keyof KEYS, string>>}
412
+ */
413
+ const named = [];
414
+ /**
415
+ * @type {Array<string>}
416
+ */
417
+ const whole = [];
418
+ /**
419
+ * @type {{whole:string[], named:Array<Record<keyof KEYS, string>>}}
420
+ */
421
+ const result = { named, whole };
422
+ const matchedAll = string.matchAll(regexp);
423
+ for (const match of matchedAll) {
424
+ if (match.groups === undefined) {
425
+ throw new Error(
426
+ JSON.stringify({
427
+ regexpSource: regexp.source,
428
+ message: 'no match is found',
429
+ sugestion: 'make sure all `keys` values will capture any scenario',
430
+ })
431
+ );
432
+ }
433
+ whole.push(match[1] ?? '');
434
+ // @ts-expect-error
435
+ named.push(match.groups);
436
+ }
437
+ return { result, regexp };
438
+ });
439
+ },
440
+ };
441
+ });
405
442
  }
@@ -12,9 +12,9 @@ import { Console } from './Console.mjs';
12
12
  */
13
13
  export class Paths {
14
14
  /**
15
- * @type {Paths}
15
+ * @type {Paths|undefined}
16
16
  */
17
- static #instance = undefined;
17
+ static #instance;
18
18
  /**
19
19
  * @description
20
20
  * @param {Object} options
@@ -51,19 +51,19 @@ export class Paths {
51
51
  this.#root = root;
52
52
  }
53
53
  /**
54
- * @type {string}
54
+ * @type {string|undefined}
55
55
  */
56
- #root = undefined;
56
+ #root;
57
57
  /**
58
58
  * @description
59
59
  * - reference for rootPath
60
60
  * - `Paths` needed to be instantiated via:
61
61
  * >- `Paths` constructor;
62
62
  * >- `Setup.paths` constructor;
63
- * @type {string}
63
+ * @type {string|undefined}
64
64
  */
65
65
  static get root() {
66
- if (!Paths.#instance.#root) {
66
+ if (Paths.#instance === undefined) {
67
67
  Console.error({
68
68
  error: 'Paths.instance.#root is undefined',
69
69
  solutions: 'instantiate `Paths` or instantiate `Setup`',
@@ -82,7 +82,9 @@ export class Paths {
82
82
  *
83
83
  * Paths.normalize('file:\\D:\\myFile.mjs'); // "file://D://myFile.mjs"
84
84
  */
85
- static normalize = (path_) => path_.replace(/\\/g, '/');
85
+ static normalize = (path_) => {
86
+ return path_.replace(/\\/g, '/');
87
+ };
86
88
  /**
87
89
  * @description
88
90
  * - normalize path separator to forward slash `/`;
@@ -96,7 +98,7 @@ export class Paths {
96
98
  */
97
99
  static normalizesForRoot = (path_) => {
98
100
  let normalized = Paths.normalize(path_);
99
- if (!normalized.startsWith('/')) {
101
+ if (normalized.startsWith('/') === false) {
100
102
  normalized = `/${normalized}`;
101
103
  }
102
104
  // @ts-expect-error
@@ -48,17 +48,18 @@ export class QChannel {
48
48
  * - ensures that each id has only one task running at a time.
49
49
  * - calls with the same id will wait for the previous call to finish.
50
50
  * @param {AnyButUndefined} id
51
- * @param {QChannel} instance
51
+ * @param {QChannel<any>} instance
52
52
  * @returns {Promise<QCBReturn>} Resolves when it's safe to proceed for the given id, returning a cleanup function
53
53
  */
54
54
  static #uniqueCB = async (id, instance) => {
55
55
  const existing = QChannel.#uniquePromiser.get(id);
56
+ // @ts-expect-error
56
57
  let resolveFn;
57
58
  const nextPromise = new Promise((resolve) => {
58
59
  resolveFn = resolve;
59
60
  });
60
61
  const context = {};
61
- if (!existing) {
62
+ if (existing === undefined) {
62
63
  QChannel.#uniquePromiser.set(id, [nextPromise, context]);
63
64
  await Promise.resolve();
64
65
  } else {
@@ -67,15 +68,17 @@ export class QChannel {
67
68
  QChannel.#uniquePromiser.set(id, [nextPromise, context]);
68
69
  }
69
70
  const resume = () => {
71
+ // @ts-expect-error
70
72
  resolveFn();
71
73
  QChannel.#uniquePromiser.delete(id);
72
74
  };
73
75
  return {
74
76
  resume,
75
77
  isLastOnQ: () => {
76
- if (!QChannel.#uniquePromiser.has(id)) {
78
+ if (QChannel.#uniquePromiser.has(id) === false) {
77
79
  return false;
78
80
  }
81
+ // @ts-expect-error
79
82
  const [, lastContext] = QChannel.#uniquePromiser.get(id);
80
83
  return instance.#shouldRun && lastContext === context;
81
84
  },
@@ -140,13 +143,13 @@ export class QChannel {
140
143
  /**
141
144
  * @type {boolean}
142
145
  */
143
- #shouldRun_;
146
+ #shouldRun_ = true;
144
147
  /**
145
148
  * @returns {boolean}
146
149
  */
147
150
  get #shouldRun() {
148
151
  const shoulRun = this.#shouldRun_;
149
- if (!shoulRun) {
152
+ if (shoulRun === false) {
150
153
  Console.warn({ qChannel_name: this.name, message: 'is closed' });
151
154
  }
152
155
  return shoulRun;
@@ -197,11 +200,15 @@ export class QChannel {
197
200
  key = async (keyID) => {
198
201
  const { resume } = await QChannel.#uniqueCB(this, this);
199
202
  const mapped = this.#mapped;
200
- if (!mapped.has(keyID)) {
203
+ if (mapped.has(keyID) === false) {
201
204
  mapped.set(keyID, {});
202
205
  }
203
206
  resume();
204
- return await QChannel.#uniqueCB(mapped.get(keyID), this);
207
+ return await QChannel.#uniqueCB(
208
+ // @ts-expect-error
209
+ mapped.get(keyID),
210
+ this
211
+ );
205
212
  };
206
213
  /**
207
214
  * @description