@simplysm/core-node 13.0.100 → 14.0.1

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 (41) hide show
  1. package/dist/features/fs-watcher.d.ts +21 -21
  2. package/dist/features/fs-watcher.d.ts.map +1 -1
  3. package/dist/features/fs-watcher.js +176 -114
  4. package/dist/features/fs-watcher.js.map +1 -6
  5. package/dist/index.js +6 -7
  6. package/dist/index.js.map +1 -6
  7. package/dist/utils/fs.d.ts +96 -96
  8. package/dist/utils/fs.d.ts.map +1 -1
  9. package/dist/utils/fs.js +437 -272
  10. package/dist/utils/fs.js.map +1 -6
  11. package/dist/utils/path.d.ts +22 -22
  12. package/dist/utils/path.js +103 -45
  13. package/dist/utils/path.js.map +1 -6
  14. package/dist/worker/create-worker.d.ts +3 -3
  15. package/dist/worker/create-worker.js +106 -81
  16. package/dist/worker/create-worker.js.map +1 -6
  17. package/dist/worker/types.d.ts +14 -14
  18. package/dist/worker/types.js +4 -1
  19. package/dist/worker/types.js.map +1 -6
  20. package/dist/worker/worker.d.ts +5 -5
  21. package/dist/worker/worker.js +168 -132
  22. package/dist/worker/worker.js.map +1 -6
  23. package/lib/worker-dev-proxy.js +15 -0
  24. package/package.json +8 -6
  25. package/src/features/fs-watcher.ts +53 -42
  26. package/src/index.ts +3 -3
  27. package/src/utils/fs.ts +111 -120
  28. package/src/utils/path.ts +26 -26
  29. package/src/worker/create-worker.ts +10 -10
  30. package/src/worker/types.ts +14 -14
  31. package/src/worker/worker.ts +29 -29
  32. package/README.md +0 -112
  33. package/docs/features.md +0 -91
  34. package/docs/fs.md +0 -309
  35. package/docs/path.md +0 -120
  36. package/docs/worker.md +0 -168
  37. package/tests/utils/fs-watcher.spec.ts +0 -286
  38. package/tests/utils/fs.spec.ts +0 -705
  39. package/tests/utils/path.spec.ts +0 -179
  40. package/tests/worker/fixtures/test-worker.ts +0 -35
  41. package/tests/worker/sd-worker.spec.ts +0 -174
@@ -5,15 +5,15 @@ import type { WorkerRequest, WorkerResponse } from "./types";
5
5
  //#region createWorker
6
6
 
7
7
  /**
8
- * Worker factory for use in worker threads.
8
+ * Worker thread에서 사용하기 위한 워커 팩토리.
9
9
  *
10
10
  * @example
11
- * // Worker without events
11
+ * // 이벤트 없는 워커
12
12
  * export default createWorker({
13
13
  * add: (a: number, b: number) => a + b,
14
14
  * });
15
15
  *
16
- * // Worker with events
16
+ * // 이벤트가 있는 워커
17
17
  * interface MyEvents { progress: number; }
18
18
  * const methods = {
19
19
  * calc: (x: number) => { sender.send("progress", 50); return x * 2; },
@@ -32,13 +32,13 @@ export function createWorker<
32
32
  __events: TEvents;
33
33
  } {
34
34
  if (parentPort === null) {
35
- throw new SdError("This script must be executed in a worker thread (parentPort required).");
35
+ throw new SdError(" 스크립트는 worker thread에서 실행되어야 합니다 (parentPort 필요).");
36
36
  }
37
37
 
38
38
  const port = parentPort;
39
39
 
40
- // Worker thread's stdout is not automatically forwarded to the main thread
41
- // Intercept stdout.write and forward it to the main thread via message protocol
40
+ // Worker thread stdout 메인 스레드로 자동 전달되지 않음
41
+ // stdout.write 가로채서 메시지 프로토콜을 통해 메인 스레드로 전달
42
42
  process.stdout.write = (
43
43
  chunk: string | Uint8Array,
44
44
  encodingOrCallback?: BufferEncoding | ((err?: Error) => void),
@@ -50,7 +50,7 @@ export function createWorker<
50
50
  port.postMessage(serialized.result, serialized.transferList);
51
51
 
52
52
  const cb = typeof encodingOrCallback === "function" ? encodingOrCallback : callback;
53
- if (cb) {
53
+ if (cb != null) {
54
54
  queueMicrotask(() => cb());
55
55
  }
56
56
 
@@ -60,7 +60,7 @@ export function createWorker<
60
60
  port.on("message", async (serializedRequest: unknown) => {
61
61
  const decoded = transfer.decode(serializedRequest);
62
62
 
63
- // Validate request structure
63
+ // 요청 구조 검증
64
64
  if (
65
65
  decoded == null ||
66
66
  typeof decoded !== "object" ||
@@ -77,7 +77,7 @@ export function createWorker<
77
77
  const errorResponse: WorkerResponse = {
78
78
  type: "error",
79
79
  request: { id: "unknown", method: "unknown", params: [] },
80
- body: new SdError(`Invalid worker request format: ${decodedStr}`),
80
+ body: new SdError(`잘못된 워커 요청 형식: ${decodedStr}`),
81
81
  };
82
82
  const serialized = transfer.encode(errorResponse);
83
83
  port.postMessage(serialized.result, serialized.transferList);
@@ -91,7 +91,7 @@ export function createWorker<
91
91
  const response: WorkerResponse = {
92
92
  request,
93
93
  type: "error",
94
- body: new SdError(`Unknown method: ${request.method}`),
94
+ body: new SdError(`알 없는 메서드: ${request.method}`),
95
95
  };
96
96
 
97
97
  const serialized = transfer.encode(response);
@@ -1,11 +1,11 @@
1
1
  //#region Types
2
2
 
3
3
  /**
4
- * Type structure of the worker module returned by `createWorker()`.
5
- * Used for type inference in `Worker.create<typeof import("./worker")>()`.
4
+ * `createWorker()`가 반환하는 워커 모듈의 타입 구조.
5
+ * `Worker.create<typeof import("./worker")>()`에서 타입 추론에 사용된다.
6
6
  *
7
- * @see createWorker - Create worker module
8
- * @see Worker.create - Create worker proxy
7
+ * @see createWorker - 워커 모듈 생성
8
+ * @see Worker.create - 워커 프록시 생성
9
9
  */
10
10
  export interface WorkerModule {
11
11
  default: {
@@ -15,9 +15,9 @@ export interface WorkerModule {
15
15
  }
16
16
 
17
17
  /**
18
- * Mapping type that wraps method return values in Promise.
19
- * Worker methods operate based on postMessage and are always asynchronous,
20
- * so synchronous method types are also converted to `Promise<Awaited<R>>`.
18
+ * 메서드 반환값을 Promise로 감싸는 매핑 타입.
19
+ * 워커 메서드는 postMessage 기반으로 동작하여 항상 비동기이므로,
20
+ * 동기 메서드 타입도 `Promise<Awaited<R>>`로 변환된다.
21
21
  */
22
22
  export type PromisifyMethods<TMethods> = {
23
23
  [K in keyof TMethods]: TMethods[K] extends (...args: infer P) => infer R
@@ -26,14 +26,14 @@ export type PromisifyMethods<TMethods> = {
26
26
  };
27
27
 
28
28
  /**
29
- * Proxy type returned by Worker.create().
30
- * Provides promisified methods + on() + terminate().
29
+ * Worker.create()가 반환하는 프록시 타입.
30
+ * Promise화된 메서드 + on() + terminate()을 제공한다.
31
31
  */
32
32
  export type WorkerProxy<TModule extends WorkerModule> = PromisifyMethods<
33
33
  TModule["default"]["__methods"]
34
34
  > & {
35
35
  /**
36
- * Registers a worker event listener.
36
+ * 워커 이벤트 리스너를 등록한다.
37
37
  */
38
38
  on<TEventName extends keyof TModule["default"]["__events"] & string>(
39
39
  event: TEventName,
@@ -41,7 +41,7 @@ export type WorkerProxy<TModule extends WorkerModule> = PromisifyMethods<
41
41
  ): void;
42
42
 
43
43
  /**
44
- * Unregisters a worker event listener.
44
+ * 워커 이벤트 리스너를 해제한다.
45
45
  */
46
46
  off<TEventName extends keyof TModule["default"]["__events"] & string>(
47
47
  event: TEventName,
@@ -49,13 +49,13 @@ export type WorkerProxy<TModule extends WorkerModule> = PromisifyMethods<
49
49
  ): void;
50
50
 
51
51
  /**
52
- * Terminates the worker.
52
+ * 워커를 종료한다.
53
53
  */
54
54
  terminate(): Promise<void>;
55
55
  };
56
56
 
57
57
  /**
58
- * Internal worker request message.
58
+ * 내부 워커 요청 메시지.
59
59
  */
60
60
  export interface WorkerRequest {
61
61
  id: string;
@@ -64,7 +64,7 @@ export interface WorkerRequest {
64
64
  }
65
65
 
66
66
  /**
67
- * Internal worker response message.
67
+ * 내부 워커 응답 메시지.
68
68
  */
69
69
  export type WorkerResponse =
70
70
  | {
@@ -11,11 +11,11 @@ const logger = consola.withTag("sd-worker");
11
11
  //#region WorkerInternal
12
12
 
13
13
  /**
14
- * Internal implementation class for Worker.
15
- * Exposed to the outside through a Proxy.
14
+ * Worker의 내부 구현 클래스.
15
+ * Proxy를 통해 외부에 노출된다.
16
16
  *
17
- * In development (.ts files), TypeScript worker files are executed via tsx.
18
- * In production (.js files), Worker is created directly.
17
+ * 개발 환경(.ts 파일)에서는 TypeScript 워커 파일을 tsx를 통해 실행한다.
18
+ * 프로덕션 환경(.js 파일)에서는 Worker 직접 생성한다.
19
19
  */
20
20
  class WorkerInternal extends EventEmitter<Record<string, unknown>> {
21
21
  private readonly _worker: WorkerRaw;
@@ -30,13 +30,13 @@ class WorkerInternal extends EventEmitter<Record<string, unknown>> {
30
30
 
31
31
  const ext = path.extname(import.meta.filename);
32
32
 
33
- // Extract env object through type guard
33
+ // 타입 가드를 통해 env 객체 추출
34
34
  const envObj = opt?.env != null && typeof opt.env === "object" ? opt.env : {};
35
35
 
36
- // In development (.ts files), execute via tsx
37
- // worker-dev-proxy.js: Proxy to dynamically load TypeScript worker files via tsx
36
+ // 개발 환경(.ts 파일)에서는 tsx를 통해 실행
37
+ // worker-dev-proxy.js: tsx를 통해 TypeScript 워커 파일을 동적으로 로드하는 프록시
38
38
  if (ext === ".ts") {
39
- // If file:// URL, convert to absolute path (worker-dev-proxy.js applies pathToFileURL again)
39
+ // file:// URL이면 절대 경로로 변환 (worker-dev-proxy.js 다시 pathToFileURL 적용)
40
40
  const workerPath = filePath.startsWith("file://") ? fileURLToPath(filePath) : filePath;
41
41
  this._worker = new WorkerRaw(
42
42
  path.resolve(import.meta.dirname, "../../lib/worker-dev-proxy.js"),
@@ -52,8 +52,8 @@ class WorkerInternal extends EventEmitter<Record<string, unknown>> {
52
52
  },
53
53
  );
54
54
  } else {
55
- // Production environment (.js files)
56
- // If file:// URL, convert it; otherwise use absolute path as-is
55
+ // 프로덕션 환경 (.js 파일)
56
+ // file:// URL이면 변환; 그렇지 않으면 절대 경로를 그대로 사용
57
57
  const workerPath = filePath.startsWith("file://") ? fileURLToPath(filePath) : filePath;
58
58
  this._worker = new WorkerRaw(workerPath, {
59
59
  stdout: true,
@@ -66,30 +66,30 @@ class WorkerInternal extends EventEmitter<Record<string, unknown>> {
66
66
  });
67
67
  }
68
68
 
69
- // Pipe worker's stdout/stderr to main process
69
+ // 워커의 stdout/stderr 메인 프로세스로 파이프
70
70
  this._worker.stdout.pipe(process.stdout);
71
71
  this._worker.stderr.pipe(process.stderr);
72
72
 
73
73
  this._worker.on("exit", (code) => {
74
74
  if (!this._isTerminated && code !== 0) {
75
- logger.error(`Worker crashed (code: ${code})`);
76
- // Reject all pending requests on abnormal exit
77
- this._rejectAllPending(new Error(`Worker crashed (code: ${code})`));
75
+ logger.error(`워커가 비정상 종료되었습니다 (코드: ${code})`);
76
+ // 비정상 종료 대기 중인 모든 요청을 거부
77
+ this._rejectAllPending(new Error(`워커가 비정상 종료되었습니다 (코드: ${code})`));
78
78
  }
79
79
  });
80
80
 
81
81
  this._worker.on("error", (err) => {
82
- logger.error("Worker error:", err);
83
- // Reject all pending requests on worker error
82
+ logger.error("워커 오류:", err);
83
+ // 워커 오류 대기 중인 모든 요청을 거부
84
84
  this._rejectAllPending(err);
85
85
  });
86
86
 
87
87
  this._worker.on("message", (serializedResponse: unknown) => {
88
88
  const decoded = transfer.decode(serializedResponse);
89
89
 
90
- // Validate response structure
90
+ // 응답 구조 검증
91
91
  if (decoded == null || typeof decoded !== "object" || !("type" in decoded)) {
92
- logger.warn("Invalid response format from worker:", decoded);
92
+ logger.warn("워커로부터 잘못된 응답 형식:", decoded);
93
93
  return;
94
94
  }
95
95
  const response = decoded as WorkerResponse;
@@ -116,7 +116,7 @@ class WorkerInternal extends EventEmitter<Record<string, unknown>> {
116
116
  }
117
117
 
118
118
  /**
119
- * Rejects all pending requests.
119
+ * 대기 중인 모든 요청을 거부한다.
120
120
  */
121
121
  private _rejectAllPending(err: Error): void {
122
122
  for (const [_id, { method, reject }] of this._pendingRequests) {
@@ -126,7 +126,7 @@ class WorkerInternal extends EventEmitter<Record<string, unknown>> {
126
126
  }
127
127
 
128
128
  /**
129
- * Calls a worker method.
129
+ * 워커 메서드를 호출한다.
130
130
  */
131
131
  call(method: string, params: unknown[]): Promise<unknown> {
132
132
  return new Promise((resolve, reject) => {
@@ -144,11 +144,11 @@ class WorkerInternal extends EventEmitter<Record<string, unknown>> {
144
144
  }
145
145
 
146
146
  /**
147
- * Terminates the worker.
147
+ * 워커를 종료한다.
148
148
  */
149
149
  async terminate(): Promise<void> {
150
150
  this._isTerminated = true;
151
- this._rejectAllPending(new Error("Worker terminated"));
151
+ this._rejectAllPending(new Error("워커가 종료되었습니다"));
152
152
  await this._worker.terminate();
153
153
  }
154
154
  }
@@ -158,7 +158,7 @@ class WorkerInternal extends EventEmitter<Record<string, unknown>> {
158
158
  //#region Worker
159
159
 
160
160
  /**
161
- * Type-safe Worker wrapper.
161
+ * 타입 안전한 Worker 래퍼.
162
162
  *
163
163
  * @example
164
164
  * // worker.ts
@@ -173,11 +173,11 @@ class WorkerInternal extends EventEmitter<Record<string, unknown>> {
173
173
  */
174
174
  export const Worker = {
175
175
  /**
176
- * Creates a type-safe Worker Proxy.
176
+ * 타입 안전한 Worker Proxy를 생성한다.
177
177
  *
178
- * @param filePath - Worker file path (file:// URL or absolute path)
179
- * @param opt - Worker options
180
- * @returns Proxy object (supports direct method calls, on(), and terminate())
178
+ * @param filePath - 워커 파일 경로 (file:// URL 또는 절대 경로)
179
+ * @param opt - 워커 옵션
180
+ * @returns Proxy 객체 (메서드 직접 호출, on(), terminate() 지원)
181
181
  */
182
182
  create<TModule extends WorkerModule>(
183
183
  filePath: string,
@@ -187,7 +187,7 @@ export const Worker = {
187
187
 
188
188
  return new Proxy({} as WorkerProxy<TModule>, {
189
189
  get(_target, prop: string) {
190
- // Reserved methods: on, off, terminate
190
+ // 예약된 메서드: on, off, terminate
191
191
  if (prop === "on") {
192
192
  return (event: string, listener: (data: unknown) => void) => {
193
193
  internal.on(event, listener);
@@ -202,7 +202,7 @@ export const Worker = {
202
202
  return () => internal.terminate();
203
203
  }
204
204
 
205
- // Otherwise, treat as worker method
205
+ // 외의 경우 워커 메서드로 처리
206
206
  return (...args: unknown[]) => internal.call(prop, args);
207
207
  },
208
208
  });
package/README.md DELETED
@@ -1,112 +0,0 @@
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
- ```
package/docs/features.md DELETED
@@ -1,91 +0,0 @@
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
- ```