@simplysm/core-node 13.0.69 → 13.0.71

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.
@@ -43,18 +43,18 @@ class WorkerInternal extends EventEmitter {
43
43
  this._worker.stderr.pipe(process.stderr);
44
44
  this._worker.on("exit", (code) => {
45
45
  if (!this._isTerminated && code !== 0) {
46
- logger.error(`\uC6CC\uCEE4\uAC00 \uC624\uB958\uC640 \uD568\uAED8 \uB2EB\uD798 (code: ${code})`);
47
- this._rejectAllPending(new Error(`\uC6CC\uCEE4\uAC00 \uBE44\uC815\uC0C1 \uC885\uB8CC\uB428 (code: ${code})`));
46
+ logger.error(`Worker crashed (code: ${code})`);
47
+ this._rejectAllPending(new Error(`Worker crashed (code: ${code})`));
48
48
  }
49
49
  });
50
50
  this._worker.on("error", (err) => {
51
- logger.error("\uC6CC\uCEE4 \uC624\uB958:", err);
51
+ logger.error("Worker error:", err);
52
52
  this._rejectAllPending(err);
53
53
  });
54
54
  this._worker.on("message", (serializedResponse) => {
55
55
  const decoded = transferableDecode(serializedResponse);
56
56
  if (decoded == null || typeof decoded !== "object" || !("type" in decoded)) {
57
- logger.warn("\uC6CC\uCEE4\uC5D0\uC11C \uC798\uBABB\uB41C \uD615\uC2DD\uC758 \uC751\uB2F5:", decoded);
57
+ logger.warn("Invalid response format from worker:", decoded);
58
58
  return;
59
59
  }
60
60
  const response = decoded;
@@ -78,7 +78,7 @@ class WorkerInternal extends EventEmitter {
78
78
  });
79
79
  }
80
80
  /**
81
- * 대기 중인 모든 요청을 reject합니다.
81
+ * Rejects all pending requests.
82
82
  */
83
83
  _rejectAllPending(err) {
84
84
  for (const [_id, { method, reject }] of this._pendingRequests) {
@@ -87,7 +87,7 @@ class WorkerInternal extends EventEmitter {
87
87
  this._pendingRequests.clear();
88
88
  }
89
89
  /**
90
- * 워커 메서드 호출.
90
+ * Calls a worker method.
91
91
  */
92
92
  call(method, params) {
93
93
  return new Promise((resolve, reject) => {
@@ -102,21 +102,21 @@ class WorkerInternal extends EventEmitter {
102
102
  });
103
103
  }
104
104
  /**
105
- * 워커 종료.
105
+ * Terminates the worker.
106
106
  */
107
107
  async terminate() {
108
108
  this._isTerminated = true;
109
- this._rejectAllPending(new Error("\uC6CC\uCEE4\uAC00 \uC885\uB8CC\uB428"));
109
+ this._rejectAllPending(new Error("Worker terminated"));
110
110
  await this._worker.terminate();
111
111
  }
112
112
  }
113
113
  const Worker = {
114
114
  /**
115
- * 타입 안전한 Worker Proxy 생성.
115
+ * Creates a type-safe Worker Proxy.
116
116
  *
117
- * @param filePath - 워커 파일 경로 (file:// URL 또는 절대 경로)
118
- * @param opt - Worker 옵션
119
- * @returns Proxy 객체 (메서드 직접 호출, on(), terminate() 지원)
117
+ * @param filePath - Worker file path (file:// URL or absolute path)
118
+ * @param opt - Worker options
119
+ * @returns Proxy object (supports direct method calls, on(), and terminate())
120
120
  */
121
121
  create(filePath, opt) {
122
122
  const internal = new WorkerInternal(filePath, opt);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/worker/worker.ts"],
4
- "mappings": "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",
4
+ "mappings": "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",
5
5
  "names": []
6
6
  }
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@simplysm/core-node",
3
- "version": "13.0.69",
4
- "description": "심플리즘 패키지 - 코어 모듈 (node)",
5
- "author": "김석래",
3
+ "version": "13.0.71",
4
+ "description": "Simplysm package - Core module (node)",
5
+ "author": "simplysm",
6
6
  "license": "Apache-2.0",
7
7
  "repository": {
8
8
  "type": "git",
@@ -14,7 +14,8 @@
14
14
  "types": "./dist/index.d.ts",
15
15
  "files": [
16
16
  "dist",
17
- "src"
17
+ "src",
18
+ "tests"
18
19
  ],
19
20
  "sideEffects": false,
20
21
  "dependencies": {
@@ -23,6 +24,6 @@
23
24
  "glob": "^13.0.6",
24
25
  "minimatch": "^10.2.2",
25
26
  "tsx": "^4.21.0",
26
- "@simplysm/core-common": "13.0.69"
27
+ "@simplysm/core-common": "13.0.71"
27
28
  }
28
29
  }
@@ -8,11 +8,11 @@ import { type NormPath, pathNorm } from "../utils/path";
8
8
 
9
9
  //#region Helpers
10
10
 
11
- /** glob 메타문자 패턴 */
11
+ /** Glob metacharacter pattern */
12
12
  const GLOB_CHARS_RE = /[*?{[\]]/;
13
13
 
14
14
  /**
15
- * glob 패턴에서 base 디렉토리 추출.
15
+ * Extracts the base directory from a glob pattern.
16
16
  * @example extractGlobBase("/home/user/src/**\/*.ts") → "/home/user/src"
17
17
  */
18
18
  function extractGlobBase(globPath: string): string {
@@ -30,22 +30,22 @@ function extractGlobBase(globPath: string): string {
30
30
  //#region Types
31
31
 
32
32
  /**
33
- * 지원하는 파일 변경 이벤트 타입 목록.
33
+ * List of supported file change event types.
34
34
  */
35
35
  const FS_WATCHER_EVENTS = ["add", "addDir", "change", "unlink", "unlinkDir"] as const;
36
36
 
37
37
  /**
38
- * 파일 변경 이벤트 타입.
38
+ * File change event type.
39
39
  */
40
40
  export type FsWatcherEvent = (typeof FS_WATCHER_EVENTS)[number];
41
41
 
42
42
  /**
43
- * 파일 변경 정보.
43
+ * File change information.
44
44
  */
45
45
  export interface FsWatcherChangeInfo {
46
- /** 변경 이벤트 타입 */
46
+ /** Change event type */
47
47
  event: FsWatcherEvent;
48
- /** 변경된 파일/디렉토리 경로 (정규화됨) */
48
+ /** Changed file/directory path (normalized) */
49
49
  path: NormPath;
50
50
  }
51
51
 
@@ -54,13 +54,13 @@ export interface FsWatcherChangeInfo {
54
54
  //#region FsWatcher
55
55
 
56
56
  /**
57
- * chokidar 기반 파일 시스템 감시 래퍼.
58
- * 짧은 시간 발생한 이벤트를 병합하여 콜백 호출.
57
+ * Chokidar-based file system watcher wrapper.
58
+ * Merges events that occur within a short time and calls the callback once.
59
59
  *
60
- * **주의**: chokidar의 `ignoreInitial` 옵션은 내부적으로 항상 `true`로 설정된다.
61
- * `options.ignoreInitial: false`를 전달하면 `onChange` 호출 배열로
62
- * 콜백이 호출되지만, 실제 초기 파일 목록은 포함되지 않는다.
63
- * 이는 이벤트 병합 로직과의 충돌을 방지하기 위한 의도된 동작이다.
60
+ * **Note**: The `ignoreInitial` option of chokidar is internally always set to `true`.
61
+ * If you pass `options.ignoreInitial: false`, the callback will be called with an empty array on the first `onChange` call,
62
+ * but the actual initial file list is not included.
63
+ * This is intentional behavior to prevent conflicts with the event merging logic.
64
64
  *
65
65
  * @example
66
66
  * const watcher = await FsWatcher.watch(["src/**\/*.ts"]);
@@ -70,16 +70,16 @@ export interface FsWatcherChangeInfo {
70
70
  * }
71
71
  * });
72
72
  *
73
- * // 종료
73
+ * // Close
74
74
  * await watcher.close();
75
75
  */
76
76
  export class FsWatcher {
77
77
  /**
78
- * 파일 감시 시작 (비동기).
79
- * ready 이벤트가 발생할 때까지 대기.
78
+ * Starts watching files (asynchronous).
79
+ * Waits until the ready event is emitted.
80
80
  *
81
- * @param paths - 감시할 파일/디렉토리 경로 또는 glob 패턴 배열
82
- * @param options - chokidar 옵션
81
+ * @param paths - Array of file/directory paths or glob patterns to watch
82
+ * @param options - chokidar options
83
83
  */
84
84
  static async watch(paths: string[], options?: chokidar.ChokidarOptions): Promise<FsWatcher> {
85
85
  return new Promise<FsWatcher>((resolve, reject) => {
@@ -111,7 +111,7 @@ export class FsWatcher {
111
111
  }
112
112
  }
113
113
 
114
- // 중복 경로 제거
114
+ // Remove duplicate paths
115
115
  const uniquePaths = [...new Set(watchPaths)];
116
116
 
117
117
  this._watcher = chokidar.watch(uniquePaths, {
@@ -121,18 +121,18 @@ export class FsWatcher {
121
121
  });
122
122
  this._ignoreInitial = options?.ignoreInitial ?? this._ignoreInitial;
123
123
 
124
- // 감시 발생하는 에러 로깅
124
+ // Log errors that occur during watching
125
125
  this._watcher.on("error", (err) => {
126
126
  this._logger.error("FsWatcher error:", err);
127
127
  });
128
128
  }
129
129
 
130
130
  /**
131
- * 파일 변경 이벤트 핸들러 등록.
132
- * 지정된 delay 시간 동안 이벤트를 모아서 번에 콜백 호출.
131
+ * Registers a file change event handler.
132
+ * Collects events for the specified delay time and calls the callback once.
133
133
  *
134
- * @param opt.delay - 이벤트 병합 대기 시간 (ms)
135
- * @param cb - 변경 이벤트 콜백
134
+ * @param opt.delay - Event merge wait time (ms)
135
+ * @param cb - Change event callback
136
136
  */
137
137
  onChange(
138
138
  opt: { delay?: number },
@@ -143,7 +143,7 @@ export class FsWatcher {
143
143
 
144
144
  let changeInfoMap = new Map<string, EventName>();
145
145
 
146
- // ignoreInitial false 초기에 배열로 콜백 호출
146
+ // If ignoreInitial is false, call callback with empty array initially
147
147
  if (!this._ignoreInitial) {
148
148
  fnQ.run(async () => {
149
149
  await cb([]);
@@ -151,22 +151,22 @@ export class FsWatcher {
151
151
  }
152
152
 
153
153
  this._watcher.on("all", (event, filePath) => {
154
- // 지원하는 이벤트만 처리
154
+ // Only process supported events
155
155
  if (!FS_WATCHER_EVENTS.includes(event as FsWatcherEvent)) return;
156
156
 
157
- // glob 매처가 있으면 패턴 필터링 적용
157
+ // If glob matchers exist, apply pattern filtering
158
158
  if (this._globMatchers.length > 0) {
159
159
  const posixFilePath = filePath.replace(/\\/g, "/");
160
160
  if (!this._globMatchers.some((m) => m.match(posixFilePath))) return;
161
161
  }
162
162
 
163
163
  /*
164
- * 이벤트 병합 전략:
165
- * 짧은 시간 같은 파일에 대해 여러 이벤트가 발생하면 최종 상태만 전달한다.
166
- * - add + change → add (생성 직후 수정은 생성으로 간주)
167
- * - add + unlink → 삭제 (생성 즉시 삭제는 변경 없음)
168
- * - unlink + add → add (삭제 재생성은 생성으로 간주)
169
- * - 최신 이벤트로 덮어씀
164
+ * Event merging strategy:
165
+ * If multiple events occur for the same file within a short time, only the final state is passed.
166
+ * - add + change → add (modification immediately after creation is considered as creation)
167
+ * - add + unlink → no change (immediate deletion after creation is considered as no change)
168
+ * - unlink + add → add (recreation after deletion is considered as creation)
169
+ * - otherwiseoverwrite with latest event
170
170
  */
171
171
  if (!changeInfoMap.has(filePath)) {
172
172
  changeInfoMap.set(filePath, event);
@@ -174,19 +174,19 @@ export class FsWatcher {
174
174
  const prevEvent = changeInfoMap.get(filePath)!;
175
175
 
176
176
  if (prevEvent === "add" && event === "change") {
177
- // add change → add 유지
177
+ // add followed by change → keep add
178
178
  changeInfoMap.set(filePath, "add");
179
179
  } else if (
180
180
  (prevEvent === "add" && event === "unlink") ||
181
181
  (prevEvent === "addDir" && event === "unlinkDir")
182
182
  ) {
183
- // add unlink → 변경 없음 (삭제)
183
+ // add followed by unlink → no change (deletion)
184
184
  changeInfoMap.delete(filePath);
185
185
  } else if (prevEvent === "unlink" && (event === "add" || event === "change")) {
186
- // unlink add/change → add (파일 재생성)
186
+ // unlink followed by add/change → add (file recreation)
187
187
  changeInfoMap.set(filePath, "add");
188
188
  } else if (prevEvent === "unlinkDir" && event === "addDir") {
189
- // unlinkDir addDir → addDir (디렉토리 재생성)
189
+ // unlinkDir followed by addDir → addDir (directory recreation)
190
190
  changeInfoMap.set(filePath, "addDir");
191
191
  } else {
192
192
  changeInfoMap.set(filePath, event);
@@ -213,7 +213,7 @@ export class FsWatcher {
213
213
  }
214
214
 
215
215
  /**
216
- * 파일 감시 종료.
216
+ * Closes the file watcher.
217
217
  */
218
218
  async close(): Promise<void> {
219
219
  for (const q of this._debounceQueues) {