@simplysm/core-node 13.0.97 → 13.0.99

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.
package/README.md ADDED
@@ -0,0 +1,112 @@
1
+ # @simplysm/core-node
2
+
3
+ Simplysm package - Core module (node). Node.js utilities for file system operations, path manipulation, file watching, and type-safe worker threads.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @simplysm/core-node
9
+ ```
10
+
11
+ ## API Overview
12
+
13
+ ### File System Utils (`fsx` namespace)
14
+
15
+ | API | Type | Description |
16
+ |-----|------|-------------|
17
+ | `existsSync` | function | Check if a file or directory exists (sync) |
18
+ | `exists` | function | Check if a file or directory exists (async) |
19
+ | `mkdirSync` | function | Create a directory recursively (sync) |
20
+ | `mkdir` | function | Create a directory recursively (async) |
21
+ | `rmSync` | function | Delete a file or directory (sync) |
22
+ | `rm` | function | Delete a file or directory with retries (async) |
23
+ | `copySync` | function | Copy a file or directory with optional filter (sync) |
24
+ | `copy` | function | Copy a file or directory with optional filter (async) |
25
+ | `readSync` | function | Read a file as UTF-8 string (sync) |
26
+ | `read` | function | Read a file as UTF-8 string (async) |
27
+ | `readBufferSync` | function | Read a file as Buffer (sync) |
28
+ | `readBuffer` | function | Read a file as Buffer (async) |
29
+ | `readJsonSync` | function | Read a JSON file using JsonConvert (sync) |
30
+ | `readJson` | function | Read a JSON file using JsonConvert (async) |
31
+ | `writeSync` | function | Write data to a file, auto-creates parent dirs (sync) |
32
+ | `write` | function | Write data to a file, auto-creates parent dirs (async) |
33
+ | `writeJsonSync` | function | Write data to a JSON file (sync) |
34
+ | `writeJson` | function | Write data to a JSON file (async) |
35
+ | `readdirSync` | function | Read directory contents (sync) |
36
+ | `readdir` | function | Read directory contents (async) |
37
+ | `statSync` | function | Get file info, follows symlinks (sync) |
38
+ | `stat` | function | Get file info, follows symlinks (async) |
39
+ | `lstatSync` | function | Get file info, no symlink follow (sync) |
40
+ | `lstat` | function | Get file info, no symlink follow (async) |
41
+ | `globSync` | function | Search files by glob pattern (sync) |
42
+ | `glob` | function | Search files by glob pattern (async) |
43
+ | `clearEmptyDirectory` | function | Recursively delete empty directories |
44
+ | `findAllParentChildPathsSync` | function | Search for glob matches traversing parent dirs (sync) |
45
+ | `findAllParentChildPaths` | function | Search for glob matches traversing parent dirs (async) |
46
+
47
+ -> See [docs/fs.md](./docs/fs.md) for details.
48
+
49
+ ### Path Utils (`pathx` namespace)
50
+
51
+ | API | Type | Description |
52
+ |-----|------|-------------|
53
+ | `NormPath` | type | Brand type for normalized path |
54
+ | `posix` | function | Convert to POSIX-style path (backslash to forward slash) |
55
+ | `changeFileDirectory` | function | Change the directory of a file path |
56
+ | `basenameWithoutExt` | function | Get filename without extension |
57
+ | `isChildPath` | function | Check if a path is a child of another path |
58
+ | `norm` | function | Normalize path to absolute NormPath |
59
+ | `filterByTargets` | function | Filter files by target path list |
60
+
61
+ -> See [docs/path.md](./docs/path.md) for details.
62
+
63
+ ### Features
64
+
65
+ | API | Type | Description |
66
+ |-----|------|-------------|
67
+ | `FsWatcherEvent` | type | File change event type (`add`, `addDir`, `change`, `unlink`, `unlinkDir`) |
68
+ | `FsWatcherChangeInfo` | interface | File change information (`event`, `path`) |
69
+ | `FsWatcher` | class | Chokidar-based file watcher with event merging |
70
+
71
+ -> See [docs/features.md](./docs/features.md) for details.
72
+
73
+ ### Worker System
74
+
75
+ | API | Type | Description |
76
+ |-----|------|-------------|
77
+ | `WorkerModule` | interface | Worker module type structure for type inference |
78
+ | `PromisifyMethods` | type | Maps method return values to Promise |
79
+ | `WorkerProxy` | type | Proxy type with promisified methods + on/off/terminate |
80
+ | `WorkerRequest` | interface | Internal worker request message |
81
+ | `WorkerResponse` | type | Internal worker response message |
82
+ | `Worker` | object | Type-safe Worker wrapper with `create()` factory |
83
+ | `createWorker` | function | Worker factory for use in worker threads |
84
+
85
+ -> See [docs/worker.md](./docs/worker.md) for details.
86
+
87
+ ## Usage Examples
88
+
89
+ ```typescript
90
+ import { fsx, pathx, FsWatcher, Worker, createWorker } from "@simplysm/core-node";
91
+
92
+ // File system
93
+ const content = await fsx.read("/path/to/file.txt");
94
+ await fsx.write("/path/to/output.txt", content);
95
+
96
+ // Path utilities
97
+ const normalized = pathx.norm("/some/path");
98
+ const posixPath = pathx.posix("C:\\Users\\test");
99
+
100
+ // File watching
101
+ const watcher = await FsWatcher.watch(["src/**/*.ts"]);
102
+ watcher.onChange({ delay: 300 }, (changes) => {
103
+ for (const { path, event } of changes) {
104
+ // handle changes
105
+ }
106
+ });
107
+
108
+ // Workers
109
+ const worker = Worker.create<typeof import("./worker")>("./worker.ts");
110
+ const result = await worker.add(10, 20);
111
+ await worker.terminate();
112
+ ```
@@ -0,0 +1,91 @@
1
+ # Features
2
+
3
+ ## FsWatcher
4
+
5
+ Chokidar-based file system watcher wrapper. Merges events that occur within a short time and calls the callback once.
6
+
7
+ ```typescript
8
+ import { FsWatcher } from "@simplysm/core-node";
9
+ ```
10
+
11
+ ### Types
12
+
13
+ #### `FsWatcherEvent`
14
+
15
+ File change event type.
16
+
17
+ ```typescript
18
+ type FsWatcherEvent = "add" | "addDir" | "change" | "unlink" | "unlinkDir";
19
+ ```
20
+
21
+ #### `FsWatcherChangeInfo`
22
+
23
+ File change information.
24
+
25
+ ```typescript
26
+ interface FsWatcherChangeInfo {
27
+ /** Change event type */
28
+ event: FsWatcherEvent;
29
+ /** Changed file/directory path (normalized) */
30
+ path: NormPath;
31
+ }
32
+ ```
33
+
34
+ ### Class: `FsWatcher`
35
+
36
+ The `ignoreInitial` option of chokidar is internally always set to `true`. If you pass `options.ignoreInitial: false`, the callback will be called with an empty array on the first `onChange` call, but the actual initial file list is not included. This is intentional behavior to prevent conflicts with the event merging logic.
37
+
38
+ #### `FsWatcher.watch`
39
+
40
+ Starts watching files (asynchronous). Waits until the ready event is emitted.
41
+
42
+ ```typescript
43
+ static async watch(paths: string[], options?: chokidar.ChokidarOptions): Promise<FsWatcher>;
44
+ ```
45
+
46
+ **Parameters:**
47
+ - `paths` -- Array of file/directory paths or glob patterns to watch
48
+ - `options` -- chokidar options
49
+
50
+ #### `onChange`
51
+
52
+ Registers a file change event handler. Collects events for the specified delay time and calls the callback once.
53
+
54
+ ```typescript
55
+ onChange(
56
+ opt: { delay?: number },
57
+ cb: (changeInfos: FsWatcherChangeInfo[]) => void | Promise<void>,
58
+ ): this;
59
+ ```
60
+
61
+ **Parameters:**
62
+ - `opt.delay` -- Event merge wait time (ms)
63
+ - `cb` -- Change event callback
64
+
65
+ Event merging strategy:
66
+ - `add` + `change` -> `add` (modification immediately after creation is considered as creation)
67
+ - `add` + `unlink` -> no change (immediate deletion after creation is considered as no change)
68
+ - `unlink` + `add` -> `add` (recreation after deletion is considered as creation)
69
+ - Otherwise -> overwrite with latest event
70
+
71
+ #### `close`
72
+
73
+ Closes the file watcher.
74
+
75
+ ```typescript
76
+ async close(): Promise<void>;
77
+ ```
78
+
79
+ ### Example
80
+
81
+ ```typescript
82
+ const watcher = await FsWatcher.watch(["src/**/*.ts"]);
83
+ watcher.onChange({ delay: 300 }, (changes) => {
84
+ for (const { path, event } of changes) {
85
+ console.log(`${event}: ${path}`);
86
+ }
87
+ });
88
+
89
+ // Close
90
+ await watcher.close();
91
+ ```
package/docs/fs.md ADDED
@@ -0,0 +1,309 @@
1
+ # File System Utilities
2
+
3
+ File system utilities exported as the `fsx` namespace.
4
+
5
+ ```typescript
6
+ import { fsx } from "@simplysm/core-node";
7
+ ```
8
+
9
+ ## Existence Check
10
+
11
+ ### `existsSync`
12
+
13
+ Checks if a file or directory exists (synchronous).
14
+
15
+ ```typescript
16
+ function existsSync(targetPath: string): boolean;
17
+ ```
18
+
19
+ ### `exists`
20
+
21
+ Checks if a file or directory exists (asynchronous).
22
+
23
+ ```typescript
24
+ function exists(targetPath: string): Promise<boolean>;
25
+ ```
26
+
27
+ ## Create Directory
28
+
29
+ ### `mkdirSync`
30
+
31
+ Creates a directory (recursive).
32
+
33
+ ```typescript
34
+ function mkdirSync(targetPath: string): void;
35
+ ```
36
+
37
+ ### `mkdir`
38
+
39
+ Creates a directory (recursive, asynchronous).
40
+
41
+ ```typescript
42
+ function mkdir(targetPath: string): Promise<void>;
43
+ ```
44
+
45
+ ## Delete
46
+
47
+ ### `rmSync`
48
+
49
+ Deletes a file or directory.
50
+
51
+ The synchronous version fails immediately without retries. Use `rm` for cases with potential transient errors like file locks.
52
+
53
+ ```typescript
54
+ function rmSync(targetPath: string): void;
55
+ ```
56
+
57
+ ### `rm`
58
+
59
+ Deletes a file or directory (asynchronous).
60
+
61
+ The asynchronous version retries up to 6 times (500ms interval) for transient errors like file locks.
62
+
63
+ ```typescript
64
+ function rm(targetPath: string): Promise<void>;
65
+ ```
66
+
67
+ ## Copy
68
+
69
+ ### `copySync`
70
+
71
+ Copies a file or directory.
72
+
73
+ If `sourcePath` does not exist, no action is performed and the function returns.
74
+
75
+ ```typescript
76
+ function copySync(
77
+ sourcePath: string,
78
+ targetPath: string,
79
+ filter?: (absolutePath: string) => boolean,
80
+ ): void;
81
+ ```
82
+
83
+ **Parameters:**
84
+ - `sourcePath` -- Path of the source to copy
85
+ - `targetPath` -- Destination path for the copy
86
+ - `filter` -- A filter function that determines whether to copy. The **absolute path** of each file/directory is passed. Returns `true` to copy, `false` to exclude. The top-level `sourcePath` is not subject to filtering; the filter function is applied recursively to all children. Returning `false` for a directory skips that directory and all its contents.
87
+
88
+ ### `copy`
89
+
90
+ Copies a file or directory (asynchronous). Same behavior as `copySync`.
91
+
92
+ ```typescript
93
+ function copy(
94
+ sourcePath: string,
95
+ targetPath: string,
96
+ filter?: (absolutePath: string) => boolean,
97
+ ): Promise<void>;
98
+ ```
99
+
100
+ ## Read File
101
+
102
+ ### `readSync`
103
+
104
+ Reads a file as a UTF-8 string.
105
+
106
+ ```typescript
107
+ function readSync(targetPath: string): string;
108
+ ```
109
+
110
+ ### `read`
111
+
112
+ Reads a file as a UTF-8 string (asynchronous).
113
+
114
+ ```typescript
115
+ function read(targetPath: string): Promise<string>;
116
+ ```
117
+
118
+ ### `readBufferSync`
119
+
120
+ Reads a file as a Buffer.
121
+
122
+ ```typescript
123
+ function readBufferSync(targetPath: string): Buffer;
124
+ ```
125
+
126
+ ### `readBuffer`
127
+
128
+ Reads a file as a Buffer (asynchronous).
129
+
130
+ ```typescript
131
+ function readBuffer(targetPath: string): Promise<Buffer>;
132
+ ```
133
+
134
+ ### `readJsonSync`
135
+
136
+ Reads a JSON file (using JsonConvert).
137
+
138
+ ```typescript
139
+ function readJsonSync<TData = unknown>(targetPath: string): TData;
140
+ ```
141
+
142
+ ### `readJson`
143
+
144
+ Reads a JSON file (using JsonConvert, asynchronous).
145
+
146
+ ```typescript
147
+ function readJson<TData = unknown>(targetPath: string): Promise<TData>;
148
+ ```
149
+
150
+ ## Write File
151
+
152
+ ### `writeSync`
153
+
154
+ Writes data to a file (auto-creates parent directories).
155
+
156
+ ```typescript
157
+ function writeSync(targetPath: string, data: string | Uint8Array): void;
158
+ ```
159
+
160
+ ### `write`
161
+
162
+ Writes data to a file (auto-creates parent directories, asynchronous).
163
+
164
+ ```typescript
165
+ function write(targetPath: string, data: string | Uint8Array): Promise<void>;
166
+ ```
167
+
168
+ ### `writeJsonSync`
169
+
170
+ Writes data to a JSON file (using JsonConvert).
171
+
172
+ ```typescript
173
+ function writeJsonSync(
174
+ targetPath: string,
175
+ data: unknown,
176
+ options?: {
177
+ replacer?: (this: unknown, key: string | undefined, value: unknown) => unknown;
178
+ space?: string | number;
179
+ },
180
+ ): void;
181
+ ```
182
+
183
+ ### `writeJson`
184
+
185
+ Writes data to a JSON file (using JsonConvert, asynchronous).
186
+
187
+ ```typescript
188
+ function writeJson(
189
+ targetPath: string,
190
+ data: unknown,
191
+ options?: {
192
+ replacer?: (this: unknown, key: string | undefined, value: unknown) => unknown;
193
+ space?: string | number;
194
+ },
195
+ ): Promise<void>;
196
+ ```
197
+
198
+ ## Read Directory
199
+
200
+ ### `readdirSync`
201
+
202
+ Reads the contents of a directory.
203
+
204
+ ```typescript
205
+ function readdirSync(targetPath: string): string[];
206
+ ```
207
+
208
+ ### `readdir`
209
+
210
+ Reads the contents of a directory (asynchronous).
211
+
212
+ ```typescript
213
+ function readdir(targetPath: string): Promise<string[]>;
214
+ ```
215
+
216
+ ## File Information
217
+
218
+ ### `statSync`
219
+
220
+ Gets file/directory information (follows symbolic links).
221
+
222
+ ```typescript
223
+ function statSync(targetPath: string): fs.Stats;
224
+ ```
225
+
226
+ ### `stat`
227
+
228
+ Gets file/directory information (follows symbolic links, asynchronous).
229
+
230
+ ```typescript
231
+ function stat(targetPath: string): Promise<fs.Stats>;
232
+ ```
233
+
234
+ ### `lstatSync`
235
+
236
+ Gets file/directory information (does not follow symbolic links).
237
+
238
+ ```typescript
239
+ function lstatSync(targetPath: string): fs.Stats;
240
+ ```
241
+
242
+ ### `lstat`
243
+
244
+ Gets file/directory information (does not follow symbolic links, asynchronous).
245
+
246
+ ```typescript
247
+ function lstat(targetPath: string): Promise<fs.Stats>;
248
+ ```
249
+
250
+ ## Glob
251
+
252
+ ### `globSync`
253
+
254
+ Searches for files using a glob pattern.
255
+
256
+ ```typescript
257
+ function globSync(pattern: string, options?: GlobOptions): string[];
258
+ ```
259
+
260
+ Returns an array of absolute paths for matched files.
261
+
262
+ ### `glob`
263
+
264
+ Searches for files using a glob pattern (asynchronous).
265
+
266
+ ```typescript
267
+ function glob(pattern: string, options?: GlobOptions): Promise<string[]>;
268
+ ```
269
+
270
+ Returns an array of absolute paths for matched files.
271
+
272
+ ## Utilities
273
+
274
+ ### `clearEmptyDirectory`
275
+
276
+ Recursively searches and deletes empty directories under a specified directory. If all child directories are deleted and a parent becomes empty, it will also be deleted.
277
+
278
+ ```typescript
279
+ function clearEmptyDirectory(dirPath: string): Promise<void>;
280
+ ```
281
+
282
+ ### `findAllParentChildPathsSync`
283
+
284
+ Searches for files matching a glob pattern by traversing parent directories from a start path towards the root. Collects all file paths matching the `childGlob` pattern in each directory.
285
+
286
+ ```typescript
287
+ function findAllParentChildPathsSync(
288
+ childGlob: string,
289
+ fromPath: string,
290
+ rootPath?: string,
291
+ ): string[];
292
+ ```
293
+
294
+ **Parameters:**
295
+ - `childGlob` -- Glob pattern to search for in each directory
296
+ - `fromPath` -- Path to start searching from
297
+ - `rootPath` -- Path to stop searching at (if not specified, searches to filesystem root). `fromPath` must be a child path of `rootPath`. Otherwise, searches to the filesystem root.
298
+
299
+ ### `findAllParentChildPaths`
300
+
301
+ Asynchronous version of `findAllParentChildPathsSync`.
302
+
303
+ ```typescript
304
+ function findAllParentChildPaths(
305
+ childGlob: string,
306
+ fromPath: string,
307
+ rootPath?: string,
308
+ ): Promise<string[]>;
309
+ ```
package/docs/path.md ADDED
@@ -0,0 +1,120 @@
1
+ # Path Utilities
2
+
3
+ Path utilities exported as the `pathx` namespace.
4
+
5
+ ```typescript
6
+ import { pathx } from "@simplysm/core-node";
7
+ ```
8
+
9
+ ## Types
10
+
11
+ ### `NormPath`
12
+
13
+ Brand type representing a normalized path. Can only be created through `norm()`.
14
+
15
+ ```typescript
16
+ type NormPath = string & { [NORM]: never };
17
+ ```
18
+
19
+ ## Functions
20
+
21
+ ### `posix`
22
+
23
+ Converts to POSIX-style path (backslash to forward slash).
24
+
25
+ ```typescript
26
+ function posix(...args: string[]): string;
27
+ ```
28
+
29
+ **Examples:**
30
+ ```typescript
31
+ posix("C:\\Users\\test"); // "C:/Users/test"
32
+ posix("src", "index.ts"); // "src/index.ts"
33
+ ```
34
+
35
+ ### `changeFileDirectory`
36
+
37
+ Changes the directory of a file path.
38
+
39
+ ```typescript
40
+ function changeFileDirectory(
41
+ filePath: string,
42
+ fromDirectory: string,
43
+ toDirectory: string,
44
+ ): string;
45
+ ```
46
+
47
+ Throws an error if the file is not inside `fromDirectory`.
48
+
49
+ **Example:**
50
+ ```typescript
51
+ changeFileDirectory("/a/b/c.txt", "/a", "/x");
52
+ // "/x/b/c.txt"
53
+ ```
54
+
55
+ ### `basenameWithoutExt`
56
+
57
+ Returns the filename (basename) without extension.
58
+
59
+ ```typescript
60
+ function basenameWithoutExt(filePath: string): string;
61
+ ```
62
+
63
+ **Examples:**
64
+ ```typescript
65
+ basenameWithoutExt("file.txt"); // "file"
66
+ basenameWithoutExt("/path/to/file.spec.ts"); // "file.spec"
67
+ ```
68
+
69
+ ### `isChildPath`
70
+
71
+ Checks if `childPath` is a child path of `parentPath`. Returns `false` if the paths are the same.
72
+
73
+ Paths are internally normalized using `norm()` and compared using platform-specific path separators.
74
+
75
+ ```typescript
76
+ function isChildPath(childPath: string, parentPath: string): boolean;
77
+ ```
78
+
79
+ **Examples:**
80
+ ```typescript
81
+ isChildPath("/a/b/c", "/a/b"); // true
82
+ isChildPath("/a/b", "/a/b/c"); // false
83
+ isChildPath("/a/b", "/a/b"); // false (same path)
84
+ ```
85
+
86
+ ### `norm`
87
+
88
+ Normalizes the path and returns it as `NormPath`. Converts to absolute path and normalizes using platform-specific separators.
89
+
90
+ ```typescript
91
+ function norm(...paths: string[]): NormPath;
92
+ ```
93
+
94
+ **Examples:**
95
+ ```typescript
96
+ norm("/some/path"); // NormPath
97
+ norm("relative", "path"); // NormPath (converted to absolute path)
98
+ ```
99
+
100
+ ### `filterByTargets`
101
+
102
+ Filters files based on a list of target paths. Includes files that match or are children of a target path.
103
+
104
+ ```typescript
105
+ function filterByTargets(files: string[], targets: string[], cwd: string): string[];
106
+ ```
107
+
108
+ **Parameters:**
109
+ - `files` -- File paths to filter. Must be absolute paths under `cwd`.
110
+ - `targets` -- Target paths (relative to `cwd`, POSIX style recommended)
111
+ - `cwd` -- Current working directory (absolute path)
112
+
113
+ If `targets` is empty, returns `files` as-is; otherwise returns only files under target paths.
114
+
115
+ **Example:**
116
+ ```typescript
117
+ const files = ["/proj/src/a.ts", "/proj/src/b.ts", "/proj/tests/c.ts"];
118
+ filterByTargets(files, ["src"], "/proj");
119
+ // ["/proj/src/a.ts", "/proj/src/b.ts"]
120
+ ```
package/docs/worker.md ADDED
@@ -0,0 +1,168 @@
1
+ # Worker
2
+
3
+ Type-safe `worker_threads` wrapper providing a proxy-based RPC interface for worker threads.
4
+
5
+ ```typescript
6
+ import { Worker, createWorker } from "@simplysm/core-node";
7
+ ```
8
+
9
+ ## Types
10
+
11
+ ### `WorkerModule`
12
+
13
+ Type structure of the worker module returned by `createWorker()`. Used for type inference in `Worker.create<typeof import("./worker")>()`.
14
+
15
+ ```typescript
16
+ interface WorkerModule {
17
+ default: {
18
+ __methods: Record<string, (...args: any[]) => unknown>;
19
+ __events: Record<string, unknown>;
20
+ };
21
+ }
22
+ ```
23
+
24
+ ### `PromisifyMethods<TMethods>`
25
+
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>>`.
27
+
28
+ ```typescript
29
+ type PromisifyMethods<TMethods> = {
30
+ [K in keyof TMethods]: TMethods[K] extends (...args: infer P) => infer R
31
+ ? (...args: P) => Promise<Awaited<R>>
32
+ : never;
33
+ };
34
+ ```
35
+
36
+ ### `WorkerProxy<TModule>`
37
+
38
+ Proxy type returned by `Worker.create()`. Provides promisified methods + `on()` + `off()` + `terminate()`.
39
+
40
+ ```typescript
41
+ type WorkerProxy<TModule extends WorkerModule> = PromisifyMethods<
42
+ TModule["default"]["__methods"]
43
+ > & {
44
+ /** Registers a worker event listener. */
45
+ on<TEventName extends keyof TModule["default"]["__events"] & string>(
46
+ event: TEventName,
47
+ listener: (data: TModule["default"]["__events"][TEventName]) => void,
48
+ ): void;
49
+
50
+ /** Unregisters a worker event listener. */
51
+ off<TEventName extends keyof TModule["default"]["__events"] & string>(
52
+ event: TEventName,
53
+ listener: (data: TModule["default"]["__events"][TEventName]) => void,
54
+ ): void;
55
+
56
+ /** Terminates the worker. */
57
+ terminate(): Promise<void>;
58
+ };
59
+ ```
60
+
61
+ ### `WorkerRequest`
62
+
63
+ Internal worker request message.
64
+
65
+ ```typescript
66
+ interface WorkerRequest {
67
+ id: string;
68
+ method: string;
69
+ params: unknown[];
70
+ }
71
+ ```
72
+
73
+ ### `WorkerResponse`
74
+
75
+ Internal worker response message.
76
+
77
+ ```typescript
78
+ type WorkerResponse =
79
+ | { request: WorkerRequest; type: "return"; body?: unknown }
80
+ | { request: WorkerRequest; type: "error"; body: Error }
81
+ | { type: "event"; event: string; body?: unknown }
82
+ | { type: "log"; body: string };
83
+ ```
84
+
85
+ ## `Worker.create`
86
+
87
+ Creates a type-safe Worker Proxy.
88
+
89
+ ```typescript
90
+ const Worker = {
91
+ create<TModule extends WorkerModule>(
92
+ filePath: string,
93
+ opt?: Omit<WorkerOptions, "stdout" | "stderr">,
94
+ ): WorkerProxy<TModule>;
95
+ };
96
+ ```
97
+
98
+ **Parameters:**
99
+ - `filePath` -- Worker file path (file:// URL or absolute path)
100
+ - `opt` -- Worker options
101
+
102
+ **Returns:** Proxy object (supports direct method calls, `on()`, `off()`, and `terminate()`)
103
+
104
+ In development (`.ts` files), TypeScript worker files are executed via tsx. In production (`.js` files), Worker is created directly.
105
+
106
+ ## `createWorker`
107
+
108
+ Worker factory for use in worker threads. This is the function called inside the worker file.
109
+
110
+ ```typescript
111
+ function createWorker<
112
+ TMethods extends Record<string, (...args: any[]) => unknown>,
113
+ TEvents extends Record<string, unknown> = Record<string, never>,
114
+ >(
115
+ methods: TMethods,
116
+ ): {
117
+ send<TEventName extends keyof TEvents & string>(event: TEventName, data?: TEvents[TEventName]): void;
118
+ __methods: TMethods;
119
+ __events: TEvents;
120
+ };
121
+ ```
122
+
123
+ ## Example
124
+
125
+ ```typescript
126
+ // worker.ts
127
+ import { createWorker } from "@simplysm/core-node";
128
+
129
+ export default createWorker({
130
+ add: (a: number, b: number) => a + b,
131
+ });
132
+
133
+ // main.ts
134
+ import { Worker } from "@simplysm/core-node";
135
+
136
+ const worker = Worker.create<typeof import("./worker")>("./worker.ts");
137
+ const result = await worker.add(10, 20); // 30
138
+ await worker.terminate();
139
+ ```
140
+
141
+ ### Worker with Events
142
+
143
+ ```typescript
144
+ // worker.ts
145
+ import { createWorker } from "@simplysm/core-node";
146
+
147
+ interface MyEvents {
148
+ progress: number;
149
+ }
150
+
151
+ const methods = {
152
+ calc: (x: number) => {
153
+ sender.send("progress", 50);
154
+ return x * 2;
155
+ },
156
+ };
157
+
158
+ const sender = createWorker<typeof methods, MyEvents>(methods);
159
+ export default sender;
160
+
161
+ // 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
167
+ await worker.terminate();
168
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/core-node",
3
- "version": "13.0.97",
3
+ "version": "13.0.99",
4
4
  "description": "Simplysm package - Core module (node)",
5
5
  "author": "simplysm",
6
6
  "license": "Apache-2.0",
@@ -25,6 +25,6 @@
25
25
  "glob": "^13.0.6",
26
26
  "minimatch": "^10.2.4",
27
27
  "tsx": "^4.21.0",
28
- "@simplysm/core-common": "13.0.97"
28
+ "@simplysm/core-common": "13.0.99"
29
29
  }
30
30
  }