@simplysm/core-node 13.0.100 → 14.0.4

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 (44) hide show
  1. package/README.md +93 -79
  2. package/dist/features/fs-watcher.d.ts +21 -21
  3. package/dist/features/fs-watcher.d.ts.map +1 -1
  4. package/dist/features/fs-watcher.js +176 -114
  5. package/dist/features/fs-watcher.js.map +1 -6
  6. package/dist/index.js +6 -7
  7. package/dist/index.js.map +1 -6
  8. package/dist/utils/fs.d.ts +96 -96
  9. package/dist/utils/fs.d.ts.map +1 -1
  10. package/dist/utils/fs.js +437 -272
  11. package/dist/utils/fs.js.map +1 -6
  12. package/dist/utils/path.d.ts +22 -22
  13. package/dist/utils/path.js +103 -45
  14. package/dist/utils/path.js.map +1 -6
  15. package/dist/worker/create-worker.d.ts +3 -3
  16. package/dist/worker/create-worker.js +106 -81
  17. package/dist/worker/create-worker.js.map +1 -6
  18. package/dist/worker/types.d.ts +14 -14
  19. package/dist/worker/types.js +4 -1
  20. package/dist/worker/types.js.map +1 -6
  21. package/dist/worker/worker.d.ts +5 -5
  22. package/dist/worker/worker.js +168 -132
  23. package/dist/worker/worker.js.map +1 -6
  24. package/docs/fs-watcher.md +107 -0
  25. package/docs/fsx.md +287 -0
  26. package/docs/pathx.md +115 -0
  27. package/docs/worker.md +117 -62
  28. package/lib/worker-dev-proxy.js +15 -0
  29. package/package.json +9 -6
  30. package/src/features/fs-watcher.ts +53 -42
  31. package/src/index.ts +3 -3
  32. package/src/utils/fs.ts +111 -120
  33. package/src/utils/path.ts +26 -26
  34. package/src/worker/create-worker.ts +10 -10
  35. package/src/worker/types.ts +14 -14
  36. package/src/worker/worker.ts +29 -29
  37. package/docs/features.md +0 -91
  38. package/docs/fs.md +0 -309
  39. package/docs/path.md +0 -120
  40. package/tests/utils/fs-watcher.spec.ts +0 -286
  41. package/tests/utils/fs.spec.ts +0 -705
  42. package/tests/utils/path.spec.ts +0 -179
  43. package/tests/worker/fixtures/test-worker.ts +0 -35
  44. package/tests/worker/sd-worker.spec.ts +0 -174
package/docs/fsx.md ADDED
@@ -0,0 +1,287 @@
1
+ # fsx -- File System Utilities
2
+
3
+ Namespace providing sync and async file system operations with automatic error wrapping, recursive directory creation, and glob support.
4
+
5
+ ```ts
6
+ import { fsx } from "@simplysm/core-node";
7
+ ```
8
+
9
+ ## Functions
10
+
11
+ ### existsSync
12
+
13
+ ```ts
14
+ function existsSync(targetPath: string): boolean
15
+ ```
16
+
17
+ Check if a file or directory exists (synchronous).
18
+
19
+ ### exists
20
+
21
+ ```ts
22
+ async function exists(targetPath: string): Promise<boolean>
23
+ ```
24
+
25
+ Check if a file or directory exists (asynchronous).
26
+
27
+ ### mkdirSync
28
+
29
+ ```ts
30
+ function mkdirSync(targetPath: string): void
31
+ ```
32
+
33
+ Create a directory recursively (synchronous). Equivalent to `mkdir -p`.
34
+
35
+ ### mkdir
36
+
37
+ ```ts
38
+ async function mkdir(targetPath: string): Promise<void>
39
+ ```
40
+
41
+ Create a directory recursively (asynchronous). Equivalent to `mkdir -p`.
42
+
43
+ ### rmSync
44
+
45
+ ```ts
46
+ function rmSync(targetPath: string): void
47
+ ```
48
+
49
+ Remove a file or directory recursively (synchronous). Does not retry on failure -- use `rm` if transient errors (e.g., file locks) are expected.
50
+
51
+ ### rm
52
+
53
+ ```ts
54
+ async function rm(targetPath: string): Promise<void>
55
+ ```
56
+
57
+ Remove a file or directory recursively (asynchronous). Retries up to 6 times with 500ms delay on transient errors.
58
+
59
+ ### copySync
60
+
61
+ ```ts
62
+ function copySync(
63
+ sourcePath: string,
64
+ targetPath: string,
65
+ filter?: (absolutePath: string) => boolean,
66
+ ): void
67
+ ```
68
+
69
+ Copy a file or directory recursively (synchronous).
70
+
71
+ - If `sourcePath` does not exist, returns silently.
72
+ - `filter` receives the absolute path of each child entry. Return `true` to include, `false` to exclude.
73
+ - The top-level `sourcePath` is not subject to filtering -- only its descendants are.
74
+ - Returning `false` for a directory skips it and all its contents.
75
+
76
+ ### copy
77
+
78
+ ```ts
79
+ async function copy(
80
+ sourcePath: string,
81
+ targetPath: string,
82
+ filter?: (absolutePath: string) => boolean,
83
+ ): Promise<void>
84
+ ```
85
+
86
+ Copy a file or directory recursively (asynchronous). Same semantics as `copySync`.
87
+
88
+ ### readSync
89
+
90
+ ```ts
91
+ function readSync(targetPath: string): string
92
+ ```
93
+
94
+ Read a file as a UTF-8 string (synchronous).
95
+
96
+ ### read
97
+
98
+ ```ts
99
+ async function read(targetPath: string): Promise<string>
100
+ ```
101
+
102
+ Read a file as a UTF-8 string (asynchronous).
103
+
104
+ ### readBufferSync
105
+
106
+ ```ts
107
+ function readBufferSync(targetPath: string): Buffer
108
+ ```
109
+
110
+ Read a file as a `Buffer` (synchronous).
111
+
112
+ ### readBuffer
113
+
114
+ ```ts
115
+ async function readBuffer(targetPath: string): Promise<Buffer>
116
+ ```
117
+
118
+ Read a file as a `Buffer` (asynchronous).
119
+
120
+ ### readJsonSync
121
+
122
+ ```ts
123
+ function readJsonSync<TData = unknown>(targetPath: string): TData
124
+ ```
125
+
126
+ Read and parse a JSON file using `json.parse` from `@simplysm/core-common` (synchronous). On parse failure, the error message includes a preview of the file contents.
127
+
128
+ ### readJson
129
+
130
+ ```ts
131
+ async function readJson<TData = unknown>(targetPath: string): Promise<TData>
132
+ ```
133
+
134
+ Read and parse a JSON file using `json.parse` from `@simplysm/core-common` (asynchronous). On parse failure, the error message includes a preview of the file contents.
135
+
136
+ ### writeSync
137
+
138
+ ```ts
139
+ function writeSync(targetPath: string, data: string | Uint8Array): void
140
+ ```
141
+
142
+ Write data to a file (synchronous). Parent directories are created automatically. The file is flushed to disk.
143
+
144
+ ### write
145
+
146
+ ```ts
147
+ async function write(targetPath: string, data: string | Uint8Array): Promise<void>
148
+ ```
149
+
150
+ Write data to a file (asynchronous). Parent directories are created automatically. The file is flushed to disk.
151
+
152
+ ### writeJsonSync
153
+
154
+ ```ts
155
+ function writeJsonSync(
156
+ targetPath: string,
157
+ data: unknown,
158
+ options?: {
159
+ replacer?: (this: unknown, key: string | undefined, value: unknown) => unknown;
160
+ space?: string | number;
161
+ },
162
+ ): void
163
+ ```
164
+
165
+ Serialize data to JSON and write to a file (synchronous). Uses `json.stringify` from `@simplysm/core-common`.
166
+
167
+ | Option | Type | Description |
168
+ |--------|------|-------------|
169
+ | `replacer` | `(this: unknown, key: string \| undefined, value: unknown) => unknown` | Custom replacer function |
170
+ | `space` | `string \| number` | Indentation (spaces or string) |
171
+
172
+ ### writeJson
173
+
174
+ ```ts
175
+ async function writeJson(
176
+ targetPath: string,
177
+ data: unknown,
178
+ options?: {
179
+ replacer?: (this: unknown, key: string | undefined, value: unknown) => unknown;
180
+ space?: string | number;
181
+ },
182
+ ): Promise<void>
183
+ ```
184
+
185
+ Serialize data to JSON and write to a file (asynchronous). Uses `json.stringify` from `@simplysm/core-common`. Same options as `writeJsonSync`.
186
+
187
+ ### readdirSync
188
+
189
+ ```ts
190
+ function readdirSync(targetPath: string): string[]
191
+ ```
192
+
193
+ Read directory contents (synchronous). Returns an array of entry names.
194
+
195
+ ### readdir
196
+
197
+ ```ts
198
+ async function readdir(targetPath: string): Promise<string[]>
199
+ ```
200
+
201
+ Read directory contents (asynchronous). Returns an array of entry names.
202
+
203
+ ### statSync
204
+
205
+ ```ts
206
+ function statSync(targetPath: string): fs.Stats
207
+ ```
208
+
209
+ Get file/directory info (synchronous). Follows symbolic links.
210
+
211
+ ### stat
212
+
213
+ ```ts
214
+ async function stat(targetPath: string): Promise<fs.Stats>
215
+ ```
216
+
217
+ Get file/directory info (asynchronous). Follows symbolic links.
218
+
219
+ ### lstatSync
220
+
221
+ ```ts
222
+ function lstatSync(targetPath: string): fs.Stats
223
+ ```
224
+
225
+ Get file/directory info (synchronous). Does **not** follow symbolic links.
226
+
227
+ ### lstat
228
+
229
+ ```ts
230
+ async function lstat(targetPath: string): Promise<fs.Stats>
231
+ ```
232
+
233
+ Get file/directory info (asynchronous). Does **not** follow symbolic links.
234
+
235
+ ### globSync
236
+
237
+ ```ts
238
+ function globSync(pattern: string, options?: GlobOptions): string[]
239
+ ```
240
+
241
+ Search for files matching a glob pattern (synchronous). Returns absolute paths. Backslashes in the pattern are converted to forward slashes.
242
+
243
+ ### glob
244
+
245
+ ```ts
246
+ async function glob(pattern: string, options?: GlobOptions): Promise<string[]>
247
+ ```
248
+
249
+ Search for files matching a glob pattern (asynchronous). Returns absolute paths. Backslashes in the pattern are converted to forward slashes.
250
+
251
+ ### clearEmptyDirectory
252
+
253
+ ```ts
254
+ async function clearEmptyDirectory(dirPath: string): Promise<void>
255
+ ```
256
+
257
+ Recursively find and remove empty directories under `dirPath`. If removing children causes a parent directory to become empty, it is also removed.
258
+
259
+ ### findAllParentChildPathsSync
260
+
261
+ ```ts
262
+ function findAllParentChildPathsSync(
263
+ childGlob: string,
264
+ fromPath: string,
265
+ rootPath?: string,
266
+ ): string[]
267
+ ```
268
+
269
+ Walk from `fromPath` toward the filesystem root, collecting all files matching `childGlob` in each directory (synchronous).
270
+
271
+ | Parameter | Type | Description |
272
+ |-----------|------|-------------|
273
+ | `childGlob` | `string` | Glob pattern to match in each directory |
274
+ | `fromPath` | `string` | Starting path for the upward walk |
275
+ | `rootPath` | `string?` | Stop path (defaults to filesystem root). `fromPath` must be a descendant of `rootPath`. |
276
+
277
+ ### findAllParentChildPaths
278
+
279
+ ```ts
280
+ async function findAllParentChildPaths(
281
+ childGlob: string,
282
+ fromPath: string,
283
+ rootPath?: string,
284
+ ): Promise<string[]>
285
+ ```
286
+
287
+ Walk from `fromPath` toward the filesystem root, collecting all files matching `childGlob` in each directory (asynchronous). Same parameters as `findAllParentChildPathsSync`.
package/docs/pathx.md ADDED
@@ -0,0 +1,115 @@
1
+ # pathx -- Path Utilities
2
+
3
+ Namespace providing path manipulation utilities with normalization, POSIX conversion, and filtering.
4
+
5
+ ```ts
6
+ import { pathx } from "@simplysm/core-node";
7
+ ```
8
+
9
+ ## Types
10
+
11
+ ### NormPath
12
+
13
+ ```ts
14
+ type NormPath = string & { [NORM]: never }
15
+ ```
16
+
17
+ Branded type representing a normalized absolute path. Can only be created via `norm()`. The brand prevents accidental use of raw strings where a normalized path is expected.
18
+
19
+ ## Functions
20
+
21
+ ### posix
22
+
23
+ ```ts
24
+ function posix(...args: string[]): string
25
+ ```
26
+
27
+ Convert a path to POSIX style by joining the arguments and replacing backslashes with forward slashes.
28
+
29
+ ```ts
30
+ pathx.posix("C:\\Users\\test"); // "C:/Users/test"
31
+ pathx.posix("src", "index.ts"); // "src/index.ts"
32
+ ```
33
+
34
+ ### changeFileDirectory
35
+
36
+ ```ts
37
+ function changeFileDirectory(
38
+ filePath: string,
39
+ fromDirectory: string,
40
+ toDirectory: string,
41
+ ): string
42
+ ```
43
+
44
+ Change the directory portion of a file path. The file must be inside `fromDirectory`; throws `ArgumentError` otherwise.
45
+
46
+ ```ts
47
+ pathx.changeFileDirectory("/a/b/c.txt", "/a", "/x");
48
+ // "/x/b/c.txt"
49
+ ```
50
+
51
+ ### basenameWithoutExt
52
+
53
+ ```ts
54
+ function basenameWithoutExt(filePath: string): string
55
+ ```
56
+
57
+ Return the filename without its extension.
58
+
59
+ ```ts
60
+ pathx.basenameWithoutExt("file.txt"); // "file"
61
+ pathx.basenameWithoutExt("/path/to/file.spec.ts"); // "file.spec"
62
+ ```
63
+
64
+ ### isChildPath
65
+
66
+ ```ts
67
+ function isChildPath(childPath: string, parentPath: string): boolean
68
+ ```
69
+
70
+ Check if `childPath` is a descendant of `parentPath`. Returns `false` for identical paths. Paths are normalized internally via `norm()`.
71
+
72
+ ```ts
73
+ pathx.isChildPath("/a/b/c", "/a/b"); // true
74
+ pathx.isChildPath("/a/b", "/a/b/c"); // false
75
+ pathx.isChildPath("/a/b", "/a/b"); // false (same path)
76
+ ```
77
+
78
+ ### norm
79
+
80
+ ```ts
81
+ function norm(...paths: string[]): NormPath
82
+ ```
83
+
84
+ Normalize and resolve path segments into an absolute `NormPath`. Uses the platform-specific path separator.
85
+
86
+ ```ts
87
+ pathx.norm("/some/path"); // NormPath
88
+ pathx.norm("relative", "path"); // NormPath (resolved to absolute)
89
+ ```
90
+
91
+ ### filterByTargets
92
+
93
+ ```ts
94
+ function filterByTargets(
95
+ files: string[],
96
+ targets: string[],
97
+ cwd: string,
98
+ ): string[]
99
+ ```
100
+
101
+ Filter file paths by target directory prefixes.
102
+
103
+ | Parameter | Type | Description |
104
+ |-----------|------|-------------|
105
+ | `files` | `string[]` | Absolute file paths to filter (must be under `cwd`) |
106
+ | `targets` | `string[]` | Target directory prefixes (relative to `cwd`, POSIX style recommended) |
107
+ | `cwd` | `string` | Current working directory (absolute path) |
108
+
109
+ Returns `files` unchanged if `targets` is empty. Otherwise returns only files whose relative path matches or is a child of a target.
110
+
111
+ ```ts
112
+ const files = ["/proj/src/a.ts", "/proj/src/b.ts", "/proj/tests/c.ts"];
113
+ pathx.filterByTargets(files, ["src"], "/proj");
114
+ // ["/proj/src/a.ts", "/proj/src/b.ts"]
115
+ ```
package/docs/worker.md CHANGED
@@ -1,18 +1,23 @@
1
- # Worker
1
+ # Worker -- Typed Worker Threads
2
2
 
3
- Type-safe `worker_threads` wrapper providing a proxy-based RPC interface for worker threads.
3
+ Type-safe worker thread wrapper providing Proxy-based RPC and event communication between the main thread and worker threads.
4
4
 
5
- ```typescript
5
+ ```ts
6
6
  import { Worker, createWorker } from "@simplysm/core-node";
7
+ import type {
8
+ WorkerModule,
9
+ PromisifyMethods,
10
+ WorkerProxy,
11
+ WorkerRequest,
12
+ WorkerResponse,
13
+ } from "@simplysm/core-node";
7
14
  ```
8
15
 
9
16
  ## Types
10
17
 
11
- ### `WorkerModule`
18
+ ### WorkerModule (interface)
12
19
 
13
- Type structure of the worker module returned by `createWorker()`. Used for type inference in `Worker.create<typeof import("./worker")>()`.
14
-
15
- ```typescript
20
+ ```ts
16
21
  interface WorkerModule {
17
22
  default: {
18
23
  __methods: Record<string, (...args: any[]) => unknown>;
@@ -21,48 +26,56 @@ interface WorkerModule {
21
26
  }
22
27
  ```
23
28
 
24
- ### `PromisifyMethods<TMethods>`
29
+ Type structure representing a worker module. Used with `Worker.create<typeof import("./worker")>()` for type inference.
30
+
31
+ | Field | Type | Description |
32
+ |-------|------|-------------|
33
+ | `default.__methods` | `Record<string, (...args: any[]) => unknown>` | Map of callable worker methods |
34
+ | `default.__events` | `Record<string, unknown>` | Map of event names to event data types |
25
35
 
26
- Mapping type that wraps method return values in `Promise`. Worker methods operate based on `postMessage` and are always asynchronous, so synchronous method types are also converted to `Promise<Awaited<R>>`.
36
+ ### PromisifyMethods
27
37
 
28
- ```typescript
38
+ ```ts
29
39
  type PromisifyMethods<TMethods> = {
30
40
  [K in keyof TMethods]: TMethods[K] extends (...args: infer P) => infer R
31
41
  ? (...args: P) => Promise<Awaited<R>>
32
42
  : never;
33
- };
43
+ }
34
44
  ```
35
45
 
36
- ### `WorkerProxy<TModule>`
46
+ Utility type that wraps all method return types in `Promise`. Worker methods communicate via `postMessage` and are inherently asynchronous, so even synchronous method signatures are converted to `Promise<Awaited<R>>`.
37
47
 
38
- Proxy type returned by `Worker.create()`. Provides promisified methods + `on()` + `off()` + `terminate()`.
48
+ ### WorkerProxy
39
49
 
40
- ```typescript
50
+ ```ts
41
51
  type WorkerProxy<TModule extends WorkerModule> = PromisifyMethods<
42
52
  TModule["default"]["__methods"]
43
53
  > & {
44
- /** Registers a worker event listener. */
45
54
  on<TEventName extends keyof TModule["default"]["__events"] & string>(
46
55
  event: TEventName,
47
56
  listener: (data: TModule["default"]["__events"][TEventName]) => void,
48
57
  ): void;
49
58
 
50
- /** Unregisters a worker event listener. */
51
59
  off<TEventName extends keyof TModule["default"]["__events"] & string>(
52
60
  event: TEventName,
53
61
  listener: (data: TModule["default"]["__events"][TEventName]) => void,
54
62
  ): void;
55
63
 
56
- /** Terminates the worker. */
57
64
  terminate(): Promise<void>;
58
- };
65
+ }
59
66
  ```
60
67
 
61
- ### `WorkerRequest`
68
+ The proxy type returned by `Worker.create()`. Combines promisified worker methods with event handling and termination.
69
+
70
+ | Method | Description |
71
+ |--------|-------------|
72
+ | `on(event, listener)` | Register an event listener |
73
+ | `off(event, listener)` | Remove an event listener |
74
+ | `terminate()` | Terminate the worker thread |
62
75
 
63
- Internal worker request message.
76
+ ### WorkerRequest (interface)
64
77
 
65
- ```typescript
78
+ ```ts
66
79
  interface WorkerRequest {
67
80
  id: string;
68
81
  method: string;
@@ -70,99 +83,141 @@ interface WorkerRequest {
70
83
  }
71
84
  ```
72
85
 
73
- ### `WorkerResponse`
86
+ Internal message format sent from the main thread to the worker.
74
87
 
75
- Internal worker response message.
88
+ | Field | Type | Description |
89
+ |-------|------|-------------|
90
+ | `id` | `string` | Unique request identifier (UUID) |
91
+ | `method` | `string` | Name of the method to invoke |
92
+ | `params` | `unknown[]` | Method arguments |
76
93
 
77
- ```typescript
94
+ ### WorkerResponse (type)
95
+
96
+ ```ts
78
97
  type WorkerResponse =
79
98
  | { request: WorkerRequest; type: "return"; body?: unknown }
80
99
  | { request: WorkerRequest; type: "error"; body: Error }
81
100
  | { type: "event"; event: string; body?: unknown }
82
- | { type: "log"; body: string };
101
+ | { type: "log"; body: string }
83
102
  ```
84
103
 
85
- ## `Worker.create`
104
+ Internal message format sent from the worker to the main thread. A discriminated union with four variants:
86
105
 
87
- Creates a type-safe Worker Proxy.
106
+ | Variant | Fields | Description |
107
+ |---------|--------|-------------|
108
+ | `return` | `request`, `body?` | Successful method return value |
109
+ | `error` | `request`, `body` | Method threw an error |
110
+ | `event` | `event`, `body?` | Worker-emitted event |
111
+ | `log` | `body` | Redirected stdout output |
88
112
 
89
- ```typescript
90
- const Worker = {
91
- create<TModule extends WorkerModule>(
92
- filePath: string,
93
- opt?: Omit<WorkerOptions, "stdout" | "stderr">,
94
- ): WorkerProxy<TModule>;
95
- };
113
+ ## Worker (const)
114
+
115
+ Factory object for creating type-safe worker proxies.
116
+
117
+ ### Worker.create
118
+
119
+ ```ts
120
+ Worker.create<TModule extends WorkerModule>(
121
+ filePath: string,
122
+ opt?: Omit<WorkerRawOptions, "stdout" | "stderr">,
123
+ ): WorkerProxy<TModule>
96
124
  ```
97
125
 
98
- **Parameters:**
99
- - `filePath` -- Worker file path (file:// URL or absolute path)
100
- - `opt` -- Worker options
126
+ Create a type-safe worker proxy.
101
127
 
102
- **Returns:** Proxy object (supports direct method calls, `on()`, `off()`, and `terminate()`)
128
+ | Parameter | Type | Description |
129
+ |-----------|------|-------------|
130
+ | `filePath` | `string` | Worker file path (`file://` URL or absolute path) |
131
+ | `opt` | `Omit<WorkerRawOptions, "stdout" \| "stderr">?` | Node.js `WorkerOptions` (excluding stdout/stderr which are managed internally) |
103
132
 
104
- In development (`.ts` files), TypeScript worker files are executed via tsx. In production (`.js` files), Worker is created directly.
133
+ In development (`.ts` files), the worker is loaded via `tsx`. In production (`.js` files), the worker is loaded directly.
105
134
 
106
- ## `createWorker`
135
+ Worker stdout/stderr is piped to the main process. On abnormal exit, all pending requests are rejected.
107
136
 
108
- Worker factory for use in worker threads. This is the function called inside the worker file.
137
+ ## createWorker (function)
109
138
 
110
- ```typescript
139
+ ```ts
111
140
  function createWorker<
112
141
  TMethods extends Record<string, (...args: any[]) => unknown>,
113
142
  TEvents extends Record<string, unknown> = Record<string, never>,
114
143
  >(
115
144
  methods: TMethods,
116
145
  ): {
117
- send<TEventName extends keyof TEvents & string>(event: TEventName, data?: TEvents[TEventName]): void;
146
+ send<TEventName extends keyof TEvents & string>(
147
+ event: TEventName,
148
+ data?: TEvents[TEventName],
149
+ ): void;
118
150
  __methods: TMethods;
119
151
  __events: TEvents;
120
- };
152
+ }
121
153
  ```
122
154
 
123
- ## Example
155
+ Define a worker module inside a worker thread file. Returns a sender object that can emit events to the main thread.
156
+
157
+ | Parameter | Type | Description |
158
+ |-----------|------|-------------|
159
+ | `methods` | `TMethods` | Object mapping method names to handler functions |
160
+
161
+ The returned object exposes:
162
+
163
+ | Property/Method | Description |
164
+ |-----------------|-------------|
165
+ | `send(event, data?)` | Emit a typed event to the main thread |
166
+ | `__methods` | Type-level reference to the methods map (used for type inference) |
167
+ | `__events` | Type-level reference to the events map (used for type inference) |
124
168
 
125
- ```typescript
126
- // worker.ts
169
+ Throws if not running in a worker thread (`parentPort` is null).
170
+
171
+ ## Usage
172
+
173
+ ### Basic worker (no events)
174
+
175
+ ```ts
176
+ // math-worker.ts
127
177
  import { createWorker } from "@simplysm/core-node";
128
178
 
129
179
  export default createWorker({
130
180
  add: (a: number, b: number) => a + b,
181
+ multiply: (a: number, b: number) => a * b,
131
182
  });
132
183
 
133
184
  // main.ts
134
185
  import { Worker } from "@simplysm/core-node";
135
186
 
136
- const worker = Worker.create<typeof import("./worker")>("./worker.ts");
137
- const result = await worker.add(10, 20); // 30
187
+ const worker = Worker.create<typeof import("./math-worker")>("./math-worker.ts");
188
+ const sum = await worker.add(10, 20); // 30
189
+ const product = await worker.multiply(3, 7); // 21
138
190
  await worker.terminate();
139
191
  ```
140
192
 
141
- ### Worker with Events
193
+ ### Worker with events
142
194
 
143
- ```typescript
144
- // worker.ts
195
+ ```ts
196
+ // process-worker.ts
145
197
  import { createWorker } from "@simplysm/core-node";
146
198
 
147
- interface MyEvents {
199
+ interface Events {
148
200
  progress: number;
149
201
  }
150
202
 
151
203
  const methods = {
152
- calc: (x: number) => {
153
- sender.send("progress", 50);
154
- return x * 2;
204
+ processData: (items: string[]) => {
205
+ for (let i = 0; i < items.length; i++) {
206
+ // ... process item ...
207
+ sender.send("progress", ((i + 1) / items.length) * 100);
208
+ }
209
+ return items.length;
155
210
  },
156
211
  };
157
212
 
158
- const sender = createWorker<typeof methods, MyEvents>(methods);
213
+ const sender = createWorker<typeof methods, Events>(methods);
159
214
  export default sender;
160
215
 
161
216
  // main.ts
162
- const worker = Worker.create<typeof import("./worker")>("./worker.ts");
163
- worker.on("progress", (value) => {
164
- console.log(`Progress: ${value}%`);
165
- });
166
- const result = await worker.calc(5); // 10
217
+ import { Worker } from "@simplysm/core-node";
218
+
219
+ const worker = Worker.create<typeof import("./process-worker")>("./process-worker.ts");
220
+ worker.on("progress", (pct) => console.log(`${pct}% done`));
221
+ const count = await worker.processData(["a", "b", "c"]);
167
222
  await worker.terminate();
168
223
  ```
@@ -0,0 +1,15 @@
1
+ import process from "node:process";
2
+ import { tsImport } from "tsx/esm/api";
3
+ import { pathToFileURL } from "node:url";
4
+
5
+ // Assume argv[2] contains the actual worker file path
6
+ const workerFile = process.argv[2];
7
+ if (!workerFile) {
8
+ throw new Error("Worker file path is required as argument!");
9
+ }
10
+
11
+ // If file:// URL is already passed, use it as-is; otherwise convert
12
+ const workerFileUrl = workerFile.startsWith("file://")
13
+ ? workerFile
14
+ : pathToFileURL(workerFile).href;
15
+ await tsImport(workerFileUrl, import.meta.url);