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
package/README.src.md CHANGED
@@ -31,8 +31,12 @@ npm i vivth
31
31
 
32
32
  ## versions:
33
33
 
34
- - `1.0.0+:b`:
34
+ - `1.0.0+:beta`:
35
+
35
36
  > - beta release;
36
37
  > - checking edge cases;
37
38
  > - stable API, the exposed API access are highly unlikely to changes, only the underlying code
38
39
  > might changes for improving performance;
40
+
41
+ - `1.3.x:beta`:
42
+ > - type should now fully fixed, even with strict ts check;
package/bun.lock CHANGED
@@ -4,8 +4,10 @@
4
4
  "": {
5
5
  "name": "vivth",
6
6
  "dependencies": {
7
+ "@types/mime-types": "^3.0.1",
7
8
  "chokidar": "^4.0.3",
8
9
  "esbuild": "^0.25.9",
10
+ "i": "^0.3.7",
9
11
  "mime-types": "^3.0.1",
10
12
  "pkg": "^5.8.1",
11
13
  },
@@ -95,6 +97,8 @@
95
97
 
96
98
  "@types/bun": ["@types/bun@1.2.21", "", { "dependencies": { "bun-types": "1.2.21" } }, "sha512-NiDnvEqmbfQ6dmZ3EeUO577s4P5bf4HCTXtI6trMc6f6RzirY5IrF3aIookuSpyslFzrnvv2lmEWv5HyC1X79A=="],
97
99
 
100
+ "@types/mime-types": ["@types/mime-types@3.0.1", "", {}, "sha512-xRMsfuQbnRq1Ef+C+RKaENOxXX87Ygl38W1vDfPHRku02TgQr+Qd8iivLtAMcR0KF5/29xlnFihkTlbqFrGOVQ=="],
101
+
98
102
  "@types/node": ["@types/node@22.13.5", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg=="],
99
103
 
100
104
  "@types/react": ["@types/react@19.1.12", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w=="],
@@ -189,6 +193,8 @@
189
193
 
190
194
  "https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="],
191
195
 
196
+ "i": ["i@0.3.7", "", {}, "sha512-FYz4wlXgkQwIPqhzC5TdNMLSE5+GS1IIDJZY/1ZiEPCT2S3COUVZeT5OW4BmW4r5LHLQuOosSwsvnroG9GR59Q=="],
197
+
192
198
  "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
193
199
 
194
200
  "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
package/index.mjs CHANGED
@@ -6,11 +6,12 @@
6
6
  * this library is made and distributed under MIT license;
7
7
  */
8
8
 
9
+ export { CompileJS } from './src/bundler/CompileJS.mjs';
9
10
  export { CreateESPlugin } from './src/bundler/CreateESPlugin.mjs';
10
11
  export { EsBundler } from './src/bundler/EsBundler.mjs';
11
12
  export { FSInline } from './src/bundler/FSInline.mjs';
12
13
  export { FSInlineAnalyzer } from './src/bundler/FSInlineAnalyzer.mjs';
13
- export { CompileJS } from './src/bundler/CompileJS.mjs';
14
+ export { Console } from './src/class/Console.mjs';
14
15
  export { Derived } from './src/class/Derived.mjs';
15
16
  export { Effect } from './src/class/Effect.mjs';
16
17
  export { EnvSignal } from './src/class/EnvSignal.mjs';
@@ -18,29 +19,28 @@ export { EventSignal } from './src/class/EventSignal.mjs';
18
19
  export { FileSafe } from './src/class/FileSafe.mjs';
19
20
  export { ListDerived } from './src/class/ListDerived.mjs';
20
21
  export { ListSignal } from './src/class/ListSignal.mjs';
22
+ export { LitExp } from './src/class/LitExp.mjs';
21
23
  export { Paths } from './src/class/Paths.mjs';
22
24
  export { QChannel } from './src/class/QChannel.mjs';
23
25
  export { SafeExit } from './src/class/SafeExit.mjs';
24
26
  export { Setup } from './src/class/Setup.mjs';
25
27
  export { Signal } from './src/class/Signal.mjs';
26
28
  export { WorkerMainThread } from './src/class/WorkerMainThread.mjs';
27
- export { Console } from './src/class/Console.mjs';
29
+ export { Base64URL } from './src/common/Base64URL.mjs';
28
30
  export { Base64URLFromFile } from './src/common/Base64URLFromFile.mjs';
29
31
  export { EventNameSpace } from './src/common/EventNameSpace.mjs';
30
32
  export { JSautoDOC } from './src/doc/JSautoDOC.mjs';
31
- export { LitExp } from './src/class/LitExp.mjs';
33
+ export { CreateImmutable } from './src/function/CreateImmutable.mjs';
32
34
  export { EventCheck } from './src/function/EventCheck.mjs';
33
35
  export { EventObject } from './src/function/EventObject.mjs';
34
- export { IsAsync } from './src/function/IsAsync.mjs';
35
36
  export { GetRuntime } from './src/function/GetRuntime.mjs';
37
+ export { IsAsync } from './src/function/IsAsync.mjs';
36
38
  export { LazyFactory } from './src/function/LazyFactory.mjs';
37
39
  export { Timeout } from './src/function/Timeout.mjs';
38
40
  export { Try } from './src/function/Try.mjs';
39
41
  export { TryAsync } from './src/function/TryAsync.mjs';
40
42
  export { TrySync } from './src/function/TrySync.mjs';
41
43
  export { TsToMjs } from './src/function/TsToMjs.mjs';
42
- export { Base64URL } from './src/common/Base64URL.mjs';
43
- export { CreateImmutable } from './src/function/CreateImmutable.mjs';
44
44
  export { WorkerResult } from './src/class/WorkerResult.mjs';
45
45
  export { WorkerThread } from './src/class/WorkerThread.mjs';
46
46
  export { ToBundledJSPlugin } from './src/bundler/adds/ToBundledJSPlugin.mjs';
@@ -59,6 +59,10 @@ export { ToBundledJSPlugin } from './src/bundler/adds/ToBundledJSPlugin.mjs';
59
59
  /**
60
60
  * @typedef {import('./src/types/LitExpKeyType.mjs').LitExpKeyType} LitExpKeyType
61
61
  */
62
+ /**
63
+ * @template {import('./src/types/LitExpKeyType.mjs').LitExpKeyType} KEYS
64
+ * @typedef {import('./src/types/LitExpResultType.mjs').LitExpResultType<KEYS>} LitExpResultType
65
+ */
62
66
  /**
63
67
  * @typedef {import('./src/types/MutationType.mjs').MutationType} MutationType
64
68
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vivth",
3
- "version": "1.2.3",
3
+ "version": "1.3.0",
4
4
  "description": "library primitives",
5
5
  "main": "index.mjs",
6
6
  "types": "./types/index.d.mts",
@@ -10,8 +10,10 @@
10
10
  "typescript": "^5.9.2"
11
11
  },
12
12
  "dependencies": {
13
+ "@types/mime-types": "^3.0.1",
13
14
  "chokidar": "^4.0.3",
14
15
  "esbuild": "^0.25.9",
16
+ "i": "^0.3.7",
15
17
  "mime-types": "^3.0.1",
16
18
  "pkg": "^5.8.1"
17
19
  },
@@ -16,7 +16,10 @@ import { FSInlineAnalyzer } from './FSInlineAnalyzer.mjs';
16
16
  * @typedef {import('./CreateESPlugin.mjs')["CreateESPlugin"]} CreateESPlugin
17
17
  */
18
18
 
19
- let binaryExtension = undefined;
19
+ /**
20
+ * @type {string|undefined}
21
+ */
22
+ let binaryExtension;
20
23
 
21
24
  /**
22
25
  * @param {Record<string, string[]|string>} compilerOptions
@@ -27,7 +30,7 @@ const generateFlagsValue = (compilerOptions) => {
27
30
  for (const flag in compilerOptions) {
28
31
  const value = compilerOptions[flag];
29
32
  options.push(`--${flag}`);
30
- if (!Array.isArray(value)) {
33
+ if (Array.isArray(value) === false) {
31
34
  if (value) {
32
35
  options.push(value);
33
36
  }
@@ -43,7 +46,7 @@ const generateFlagsValue = (compilerOptions) => {
43
46
  * @returns {string} extension including dot (e.g. '.exe', '')
44
47
  */
45
48
  const getBinaryExtension = () => {
46
- if (!binaryExtension) {
49
+ if (binaryExtension === undefined) {
47
50
  switch (platform()) {
48
51
  case 'win32':
49
52
  binaryExtension = '.exe';
@@ -100,10 +103,10 @@ const getBinaryExtension = () => {
100
103
  * - no need to add the output/outdir, as it use the `options.outDir`;
101
104
  * @param {ReturnType<CreateESPlugin>[]} [options.esBundlerPlugins]
102
105
  * - plugins for `EsBundler`;
103
- * @return {ReturnType<TryAsync<{compileResult:Promise<any>,
104
- * commandCalled: string;
105
- * compiledBinFile: string;
106
- * bundledJSFile:string
106
+ * @return {ReturnType<typeof TryAsync<{compileResult:Promise<any>|undefined,
107
+ * commandCalled: string|undefined;
108
+ * compiledBinFile: string|undefined;
109
+ * bundledJSFile:string|undefined
107
110
  * }>>}
108
111
  * @example
109
112
  * import { join } from 'node:path';
@@ -139,7 +142,7 @@ export async function CompileJS({
139
142
  encoding = 'utf-8',
140
143
  outDir,
141
144
  compiler = undefined,
142
- compilerArguments = undefined,
145
+ compilerArguments = {},
143
146
  esBundlerPlugins = [],
144
147
  }) {
145
148
  return await TryAsync(async () => {
@@ -41,7 +41,9 @@ export async function EsBundler(
41
41
  esbuildOptions = {}
42
42
  ) {
43
43
  return await TryAsync(async () => {
44
- /** @type {Parameters<build>[0]['stdin']['loader']} */
44
+ /**
45
+ * @type {import('esbuild').StdinOptions["loader"]}
46
+ */
45
47
  let loader;
46
48
  switch (extension) {
47
49
  case '.mts':
@@ -84,7 +86,7 @@ export async function EsBundler(
84
86
  Console.warn(result.warnings.map((w) => w.text).join('\n'));
85
87
  }
86
88
  const resString = result.outputFiles?.[0]?.text;
87
- if (!resString) {
89
+ if (resString === undefined) {
88
90
  return '';
89
91
  }
90
92
  return resString;
@@ -26,6 +26,9 @@ export class FSInline {
26
26
  */
27
27
  static vivthFSInlineFile = async (filePathFromProject) => {
28
28
  filePathFromProject = Paths.normalizesForRoot(filePathFromProject);
29
+ if (Paths.root === undefined) {
30
+ return Buffer.from([]);
31
+ }
29
32
  const fullAbsolutePath = join(Paths.root, filePathFromProject);
30
33
  return Buffer.from(await readFile(fullAbsolutePath));
31
34
  };
@@ -15,9 +15,10 @@ import { EsBundler } from './EsBundler.mjs';
15
15
  */
16
16
  const hydrateRegex = (str) => {
17
17
  const match = str.match(/^\/(.*)\/([a-z]*)$/);
18
- if (!match) throw new Error('Invalid regex string format');
19
-
20
- const [, pattern, flags] = match;
18
+ if (match === null) {
19
+ throw new Error('Invalid regex string format');
20
+ }
21
+ const [, pattern = '', flags] = match;
21
22
  return new RegExp(pattern, flags);
22
23
  };
23
24
 
@@ -70,6 +71,7 @@ export class FSInlineAnalyzer {
70
71
  const templateFile = literalFile`${'FSInline'}${'method'}${'path'}${'closing'}`;
71
72
  const templateWorker = literalWorker`${'ref'}${'method'}${'path'}${'closing'}`;
72
73
  const templateDir = literalDir`${'FSInline'}${'method'}${'path'}${'methodClosing'}${'rule'}${'functionClosing'}`;
74
+
73
75
  const [resultMatchingFile, errorMatchingFile] = templateFile.evaluate.matchedAllAndGrouped(
74
76
  content,
75
77
  {
@@ -95,15 +97,26 @@ export class FSInlineAnalyzer {
95
97
  const {
96
98
  result: { named: namedFile },
97
99
  } = resultMatchingFile;
100
+ if (Paths.root === undefined) {
101
+ throw new Error('Path.root undefined');
102
+ }
98
103
  for (let i = 0; i < namedFile.length; i++) {
99
- const { path } = namedFile[i];
104
+ const res = namedFile[i];
105
+ if (res === undefined) {
106
+ continue;
107
+ }
108
+ const { path } = res;
100
109
  FSInline.vivthFSInlinelists[path] = Buffer.from(await readFile(join(Paths.root, path)));
101
110
  }
102
111
  const {
103
112
  result: { named: namedWorker },
104
113
  } = resultMatchingWorker;
105
114
  for (let i = 0; i < namedWorker.length; i++) {
106
- const { path } = namedWorker[i];
115
+ const res = namedWorker[i];
116
+ if (res === undefined) {
117
+ continue;
118
+ }
119
+ const { path } = res;
107
120
  const fullPath = join(Paths.root, path);
108
121
  const content = await readFile(fullPath, { encoding: 'utf-8' });
109
122
  const [contentBundled, errorBundled] = await EsBundler(
@@ -134,11 +147,19 @@ export class FSInlineAnalyzer {
134
147
  result: { named: namedDir },
135
148
  } = resultMatchingDir;
136
149
  for (let i = 0; i < namedDir.length; i++) {
137
- let { path, rule } = namedDir[i];
150
+ const res = namedDir[i];
151
+ if (res === undefined) {
152
+ continue;
153
+ }
154
+ let { path, rule } = res;
138
155
  rule = rule.trim();
139
156
  const results = await FSInlineAnalyzer.#dir(join(Paths.root, path), hydrateRegex(rule));
140
157
  for (let j = 0; j < results.length; j++) {
141
- const { path, buffer } = results[j];
158
+ const res = results[j];
159
+ if (res === undefined) {
160
+ continue;
161
+ }
162
+ const { path, buffer } = res;
142
163
  if (path in FSInline.vivthFSInlinelists) {
143
164
  continue;
144
165
  }
@@ -169,6 +190,9 @@ export class FSInlineAnalyzer {
169
190
  * @returns {Promise<void>}
170
191
  */
171
192
  const walk = async (current) => {
193
+ if (Paths.root === undefined) {
194
+ return;
195
+ }
172
196
  const entries = await readdir(current, {
173
197
  recursive: false,
174
198
  withFileTypes: true,
@@ -12,7 +12,11 @@ export class FSInline {
12
12
  */
13
13
  static vivthFSInlineFile = async (filePathFromProject) => {
14
14
  filePathFromProject = Paths.normalizesForRoot(filePathFromProject);
15
- return Buffer.from(FSInline.vivthFSInlinelists[filePathFromProject]);
15
+ const bufferStored = FSInline.vivthFSInlinelists[filePathFromProject];
16
+ if (bufferStored === undefined) {
17
+ return Buffer.from([]);
18
+ }
19
+ return Buffer.from(bufferStored);
16
20
  };
17
21
  /**
18
22
  * @param {string} dirPathFromProject
@@ -25,7 +25,7 @@ export function ToBundledJSPlugin(includedInPath) {
25
25
  const filePath = args.path;
26
26
  const fileExt = extname(filePath);
27
27
  /**
28
- * @type {'js'|'ts'}
28
+ * @type {'js'|'ts'|undefined}
29
29
  */
30
30
  let loader;
31
31
  switch (fileExt) {
@@ -36,12 +36,11 @@ export function ToBundledJSPlugin(includedInPath) {
36
36
  case '.mjs':
37
37
  case '.cjs':
38
38
  case '.js':
39
- default:
40
39
  loader = 'js';
41
40
  break;
42
41
  }
43
42
  const originalContent = (await readFile(filePath)).toString('utf-8');
44
- if (!loader) {
43
+ if (loader === undefined) {
45
44
  return {
46
45
  contents: originalContent,
47
46
  loader,
@@ -61,7 +60,7 @@ export function ToBundledJSPlugin(includedInPath) {
61
60
  `${realRef}${fileExt}`
62
61
  );
63
62
  const isExist = await exists(runtimeFile);
64
- if (!isExist) {
63
+ if (isExist === false) {
65
64
  return {
66
65
  contents: originalContent,
67
66
  loader,
@@ -43,7 +43,9 @@ export class Console {
43
43
  * hello: 'world!!',
44
44
  * });
45
45
  */
46
- static log = (data) => Console.#call('🟢', 'log', data);
46
+ static log = (data) => {
47
+ return Console.#call('🟢', 'log', data);
48
+ };
47
49
  /**
48
50
  * @description
49
51
  * @param {any} data
@@ -55,7 +57,9 @@ export class Console {
55
57
  * hello: 'world!!',
56
58
  * });
57
59
  */
58
- static info = (data) => Console.#call('🔵', 'info', data);
60
+ static info = (data) => {
61
+ return Console.#call('🔵', 'info', data);
62
+ };
59
63
  /**
60
64
  * @description
61
65
  * @param {any} data
@@ -67,7 +71,9 @@ export class Console {
67
71
  * hello: 'world!!',
68
72
  * });
69
73
  */
70
- static warn = (data) => Console.#call('🟠', 'warn', data);
74
+ static warn = (data) => {
75
+ return Console.#call('🟠', 'warn', data);
76
+ };
71
77
  /**
72
78
  * @description
73
79
  * @param {any} data
@@ -79,5 +85,7 @@ export class Console {
79
85
  * hello: 'world!!',
80
86
  * });
81
87
  */
82
- static error = (data) => Console.#call('🔴', 'error', data);
88
+ static error = (data) => {
89
+ return Console.#call('🔴', 'error', data);
90
+ };
83
91
  }
@@ -17,7 +17,7 @@ export class Derived extends Signal {
17
17
  * @description
18
18
  * - Derived used [Signal](#signal) and [Effect](#effect) under the hood;
19
19
  * @param {(effectInstanceOptions:Omit<Effect["options"] &
20
- * Derived["options"], unwrapLazy>) =>
20
+ * Derived<VALUE>["options"], unwrapLazy>) =>
21
21
  * Promise<VALUE>} derivedFunction
22
22
  * @example
23
23
  * import { Signal, Derived } from 'vivth';
@@ -36,6 +36,7 @@ export class Derived extends Signal {
36
36
  * count.value++;
37
37
  */
38
38
  constructor(derivedFunction) {
39
+ // @ts-expect-error
39
40
  super(undefined);
40
41
  const derived_instanceOptions = this.options;
41
42
  new Effect(async (options) => {
@@ -89,7 +90,9 @@ export class Derived extends Signal {
89
90
  * @description
90
91
  * - the most recent value of the instance
91
92
  * - can be turn into reactive with Effect or Derived instantiation;
93
+ * - initial value are always `undefined`, make sure to put a check before consuming(inside an `Effect`);
92
94
  * @returns {VALUE}
95
+ * @override
93
96
  */
94
97
  get value() {
95
98
  return super.value;
@@ -100,6 +103,7 @@ export class Derived extends Signal {
100
103
  * - it's value should always be determined by it's own `derivedFunction`;
101
104
  * @private
102
105
  * @type {VALUE}
106
+ * @override
103
107
  */
104
108
  set value(newValue) {
105
109
  Console.warn({
@@ -69,9 +69,9 @@ export class Effect {
69
69
  * @instance options
70
70
  * @description
71
71
  * - normally it's passed as argument to constructor, however it is also accessible from `options` property;
72
- * @template {Signal} SIGNAL
73
- * @param {SIGNAL} signal
74
- * @returns {SIGNAL}
72
+ * @template V
73
+ * @param {Signal<V>} signal
74
+ * @returns {Signal<V>}
75
75
  * @example
76
76
  * import { Effect } from 'vivth';
77
77
  *
@@ -81,7 +81,7 @@ export class Effect {
81
81
  * effect.options.subscribe(signalInstance);
82
82
  */
83
83
  subscribe: (signal) => {
84
- if (!(signal instanceof Signal)) {
84
+ if (signal instanceof Signal === false) {
85
85
  // @ts-expect-error
86
86
  signal = signal[unwrapLazy]();
87
87
  }
@@ -136,7 +136,7 @@ export class Effect {
136
136
  /**
137
137
  * @type {Object}
138
138
  */
139
- #current;
139
+ #current = {};
140
140
  /**
141
141
  * @param {Omit<Effect["options"], typeof unwrapLazy>} effectInstance
142
142
  * @returns {Promise<void>}
@@ -158,7 +158,7 @@ export class Effect {
158
158
  TryAsync(async () => {
159
159
  await this.#effect(this.options[unwrapLazy]());
160
160
  }).then(([, error]) => {
161
- if (!error) {
161
+ if (error === undefined) {
162
162
  return;
163
163
  }
164
164
  Console.error(error);
@@ -7,7 +7,6 @@ import { Signal } from './Signal.mjs';
7
7
 
8
8
  /**
9
9
  * @description
10
- * - non browser API;
11
10
  * - uses [Signal](#signal) and [Derived](#derived) under the hood;
12
11
  * @template VALUE
13
12
  */
@@ -19,16 +18,10 @@ export class EnvSignal {
19
18
  */
20
19
  constructor(initialValue) {
21
20
  this.#proxyConst = LazyFactory(() => new Signal(initialValue));
22
- let isRun = false;
23
21
  this.env = LazyFactory(
24
22
  () =>
25
23
  new Derived(async ({ subscribe }) => {
26
- const derived = subscribe(this.#proxyConst).value;
27
- if (!isRun) {
28
- isRun = true;
29
- return initialValue;
30
- }
31
- return derived;
24
+ return subscribe(this.#proxyConst).value;
32
25
  })
33
26
  );
34
27
  }
@@ -21,7 +21,7 @@ export class EventSignal {
21
21
  /**
22
22
  * @description
23
23
  * - `Map` of `EventSignal`, using the `stringName` of the `EventSignal_instance` as `key`;
24
- * @type {Map<string, EventSignal>}
24
+ * @type {Map<string, EventSignal<any>>}
25
25
  */
26
26
  static map = new Map();
27
27
  /**
@@ -35,22 +35,23 @@ export class EventSignal {
35
35
  * >- the `Promise` nature is to prevent race condition on creating the instance;
36
36
  * @param {string} stringName
37
37
  * @param {IsListSignal} [isList_]
38
- * @returns {Promise<EventSignal>}
38
+ * @returns {Promise<EventSignal<any>>}
39
39
  * @example
40
40
  * import { EventSignal } from 'vivth';
41
41
  *
42
42
  * const myEventSignal = await EventSignal.get('dataEvent');
43
43
  */
44
- static async get(stringName, isList_ = false) {
44
+ static get = async (stringName, isList_ = false) => {
45
45
  const { resume } = await EventSignal.#qChannelEventSignal.key(stringName);
46
46
  const mapped = EventSignal.map;
47
- if (!mapped.has(stringName)) {
47
+ if (mapped.has(stringName) === false) {
48
48
  let instance = new EventSignal(stringName, isList_);
49
49
  mapped.set(stringName, instance);
50
50
  }
51
51
  resume();
52
+ // @ts-expect-error
52
53
  return mapped.get(stringName);
53
- }
54
+ };
54
55
  /**
55
56
  * @private
56
57
  * @param {string} name
@@ -74,7 +75,7 @@ export class EventSignal {
74
75
  * - is [Signal](#signal) or [ListSignal](#listsignal) instance, depending on the `isList` argument;
75
76
  * - if needed to pass along the messages, it can be used as `dispatcher` and `listener` at the same time;
76
77
  * - is `lazily` created;
77
- * @type {Signal|ListSignal}
78
+ * @type {Signal<any>|ListSignal<any>}
78
79
  * @example
79
80
  * import { EventSignal, Effect, Console } from 'vivth';
80
81
  *
@@ -98,7 +99,7 @@ export class EventSignal {
98
99
  * - is [Derived](#derived) or [ListDerived](#listderived) instance, depending on the `isList` argument;
99
100
  * - can be used as listener when passed down value shouldn't be modified manually;
100
101
  * - is `lazily` created along with `dispatch`, if `listen` is accessed first, then `dispatch` will also be created automatically;
101
- * @type {Derived|ListDerived}
102
+ * @type {Derived<any>|ListDerived<any>}
102
103
  * @example
103
104
  * import { EventSignal, Effect, Console } from 'vivth';
104
105
  *
@@ -109,7 +109,7 @@ export class FileSafe {
109
109
  * - also returning promise of result & error as value;
110
110
  * @param {Parameters<mkdir>[0]} outDir
111
111
  * - absolute path
112
- * @returns {ReturnType<typeof TryAsync<string>>}
112
+ * @returns {ReturnType<typeof TryAsync<string|undefined>>}
113
113
  * @example
114
114
  * import { join } from 'node:path';
115
115
  * import { FileSafe, Paths } from 'vivth';
@@ -22,8 +22,10 @@ export class ListSignal extends Signal {
22
22
  * @param {unknown} value - The value to validate.
23
23
  * @returns {value is Array<Record<string, string>>} True if the first item is a valid string record or array is empty.
24
24
  */
25
- static isValid = (value) => {
26
- if (!Array.isArray(value)) return false;
25
+ static isValid(value) {
26
+ if (Array.isArray(value) === false) {
27
+ return false;
28
+ }
27
29
  const first = value[0];
28
30
  if (first === undefined) {
29
31
  // allow empty array
@@ -37,7 +39,7 @@ export class ListSignal extends Signal {
37
39
  ([key, val]) => typeof key === 'string' && typeof val === 'string'
38
40
  )
39
41
  );
40
- };
42
+ }
41
43
  /**
42
44
  * @description
43
45
  * - usefull for `loops`;
@@ -57,6 +59,7 @@ export class ListSignal extends Signal {
57
59
  * @description
58
60
  * - reference to original inputed `value`;
59
61
  * @returns {LISTARG[]}
62
+ * @override
60
63
  */
61
64
  get value() {
62
65
  return super.value;
@@ -66,6 +69,7 @@ export class ListSignal extends Signal {
66
69
  * - you cannot mannually set`value` `ListSignal_instance`;
67
70
  * @private
68
71
  * @type {LISTARG[]}
72
+ * @override
69
73
  */
70
74
  set value(_) {
71
75
  Console.error('`List.value` `setter` are not available outside the class or instance');
@@ -158,7 +162,7 @@ export class ListSignal extends Signal {
158
162
  */
159
163
  splice: (start, deleteCount, ...listArg) => {
160
164
  const end = start + deleteCount - 1;
161
- if (!this.#checkLength('splice', end)) {
165
+ if (this.#checkLength('splice', end) === false) {
162
166
  return;
163
167
  }
164
168
  super.value.splice(start, deleteCount, ...listArg);
@@ -173,9 +177,13 @@ export class ListSignal extends Signal {
173
177
  * @returns {void}
174
178
  */
175
179
  swap: (indexA, indexB) => {
176
- if (!this.#checkLength('swap', indexA) || !this.#checkLength('swap', indexB)) {
180
+ if (
181
+ this.#checkLength('swap', indexA) === false ||
182
+ this.#checkLength('swap', indexB) === false
183
+ ) {
177
184
  return;
178
185
  }
186
+ // @ts-expect-error
179
187
  [super.value[indexA], super.value[indexB]] = [super.value[indexB], super.value[indexA]];
180
188
  this.subscribers.notify();
181
189
  },
@@ -188,15 +196,15 @@ export class ListSignal extends Signal {
188
196
  * @returns {void}
189
197
  */
190
198
  modify: (index, listArg) => {
191
- if (!this.#checkLength('modify', index)) {
199
+ if (this.#checkLength('modify', index) === false) {
192
200
  return;
193
201
  }
194
202
  for (const key in listArg) {
195
203
  const listArgKey = listArg[key];
196
- if (!listArgKey) {
197
- continue;
204
+ if (listArgKey) {
205
+ // @ts-expect-error
206
+ super.value[index][key] = listArgKey;
198
207
  }
199
- super.value[index][key] = listArgKey;
200
208
  }
201
209
  this.subscribers.notify();
202
210
  },
@@ -208,7 +216,7 @@ export class ListSignal extends Signal {
208
216
  * @returns {void}
209
217
  */
210
218
  remove: (index) => {
211
- if (!this.#checkLength('remove', index)) {
219
+ if (this.#checkLength('remove', index) === false) {
212
220
  return;
213
221
  }
214
222
  this.arrayMethods.splice(index, 1);