@simplysm/core-node 13.0.0-beta.38 → 13.0.0-beta.41

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.
@@ -1 +1 @@
1
- {"version":3,"file":"fs-watcher.d.ts","sourceRoot":"","sources":["../../src/features/fs-watcher.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,QAAQ,MAAM,UAAU,CAAC;AAGrC,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,eAAe,CAAC;AAIxD;;GAEG;AACH,QAAA,MAAM,iBAAiB,6DAA8D,CAAC;AAEtF;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,gBAAgB;IAChB,KAAK,EAAE,cAAc,CAAC;IACtB,4BAA4B;IAC5B,IAAI,EAAE,QAAQ,CAAC;CAChB;AAMD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,SAAS;IACpB;;;;;;OAMG;WACU,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC;IAU3F,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAuB;IAEvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4C;IAEpE,OAAO;IAcP;;;;;;OAMG;IACH,QAAQ,CAAC,GAAG,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,EAAE,EAAE,CAAC,WAAW,EAAE,mBAAmB,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAkEzG;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAO7B"}
1
+ {"version":3,"file":"fs-watcher.d.ts","sourceRoot":"","sources":["../../src/features/fs-watcher.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,QAAQ,MAAM,UAAU,CAAC;AAGrC,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,eAAe,CAAC;AAIxD;;GAEG;AACH,QAAA,MAAM,iBAAiB,6DAA8D,CAAC;AAEtF;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,gBAAgB;IAChB,KAAK,EAAE,cAAc,CAAC;IACtB,4BAA4B;IAC5B,IAAI,EAAE,QAAQ,CAAC;CAChB;AAMD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,SAAS;IACpB;;;;;;OAMG;WACU,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC;IAU3F,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAuB;IAEvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoC;IAE5D,OAAO;IAcP;;;;;;OAMG;IACH,QAAQ,CAAC,GAAG,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,EAAE,EAAE,CAAC,WAAW,EAAE,mBAAmB,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAkEzG;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAO7B"}
@@ -1,6 +1,6 @@
1
1
  import { DebounceQueue } from "@simplysm/core-common";
2
2
  import * as chokidar from "chokidar";
3
- import { createConsola } from "consola";
3
+ import consola from "consola";
4
4
  import { pathNorm } from "../utils/path.js";
5
5
  const FS_WATCHER_EVENTS = ["add", "addDir", "change", "unlink", "unlinkDir"];
6
6
  class FsWatcher {
@@ -23,7 +23,7 @@ class FsWatcher {
23
23
  _watcher;
24
24
  _ignoreInitial = true;
25
25
  _debounceQueues = [];
26
- _logger = createConsola().withTag("sd-fs-watcher");
26
+ _logger = consola.withTag("sd-fs-watcher");
27
27
  constructor(paths, options) {
28
28
  this._watcher = chokidar.watch(paths, {
29
29
  persistent: true,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/features/fs-watcher.ts"],
4
- "sourcesContent": ["import { DebounceQueue } from \"@simplysm/core-common\";\nimport * as chokidar from \"chokidar\";\nimport { createConsola } from \"consola\";\nimport type { EventName } from \"chokidar/handler.js\";\nimport { type NormPath, pathNorm } from \"../utils/path\";\n\n//#region Types\n\n/**\n * \uC9C0\uC6D0\uD558\uB294 \uD30C\uC77C \uBCC0\uACBD \uC774\uBCA4\uD2B8 \uD0C0\uC785 \uBAA9\uB85D.\n */\nconst FS_WATCHER_EVENTS = [\"add\", \"addDir\", \"change\", \"unlink\", \"unlinkDir\"] as const;\n\n/**\n * \uD30C\uC77C \uBCC0\uACBD \uC774\uBCA4\uD2B8 \uD0C0\uC785.\n */\nexport type FsWatcherEvent = (typeof FS_WATCHER_EVENTS)[number];\n\n/**\n * \uD30C\uC77C \uBCC0\uACBD \uC815\uBCF4.\n */\nexport interface FsWatcherChangeInfo {\n /** \uBCC0\uACBD \uC774\uBCA4\uD2B8 \uD0C0\uC785 */\n event: FsWatcherEvent;\n /** \uBCC0\uACBD\uB41C \uD30C\uC77C/\uB514\uB809\uD1A0\uB9AC \uACBD\uB85C (\uC815\uADDC\uD654\uB428) */\n path: NormPath;\n}\n\n//#endregion\n\n//#region FsWatcher\n\n/**\n * chokidar \uAE30\uBC18 \uD30C\uC77C \uC2DC\uC2A4\uD15C \uAC10\uC2DC \uB798\uD37C.\n * \uC9E7\uC740 \uC2DC\uAC04 \uB0B4 \uBC1C\uC0DD\uD55C \uC774\uBCA4\uD2B8\uB97C \uBCD1\uD569\uD558\uC5EC \uCF5C\uBC31 \uD638\uCD9C.\n *\n * **\uC8FC\uC758**: chokidar\uC758 `ignoreInitial` \uC635\uC158\uC740 \uB0B4\uBD80\uC801\uC73C\uB85C \uD56D\uC0C1 `true`\uB85C \uC124\uC815\uB41C\uB2E4.\n * `options.ignoreInitial: false`\uB97C \uC804\uB2EC\uD558\uBA74 `onChange` \uCCAB \uD638\uCD9C \uC2DC \uBE48 \uBC30\uC5F4\uB85C\n * \uCF5C\uBC31\uC774 \uD638\uCD9C\uB418\uC9C0\uB9CC, \uC2E4\uC81C \uCD08\uAE30 \uD30C\uC77C \uBAA9\uB85D\uC740 \uD3EC\uD568\uB418\uC9C0 \uC54A\uB294\uB2E4.\n * \uC774\uB294 \uC774\uBCA4\uD2B8 \uBCD1\uD569 \uB85C\uC9C1\uACFC\uC758 \uCDA9\uB3CC\uC744 \uBC29\uC9C0\uD558\uAE30 \uC704\uD55C \uC758\uB3C4\uB41C \uB3D9\uC791\uC774\uB2E4.\n *\n * @example\n * const watcher = await FsWatcher.watch([\"src/**\\/*.ts\"]);\n * watcher.onChange({ delay: 300 }, (changes) => {\n * for (const { path, event } of changes) {\n * console.log(`${event}: ${path}`);\n * }\n * });\n *\n * // \uC885\uB8CC\n * await watcher.close();\n */\nexport class FsWatcher {\n /**\n * \uD30C\uC77C \uAC10\uC2DC \uC2DC\uC791 (\uBE44\uB3D9\uAE30).\n * ready \uC774\uBCA4\uD2B8\uAC00 \uBC1C\uC0DD\uD560 \uB54C\uAE4C\uC9C0 \uB300\uAE30.\n *\n * @param paths - \uAC10\uC2DC\uD560 \uD30C\uC77C/\uB514\uB809\uD1A0\uB9AC \uACBD\uB85C \uB610\uB294 glob \uD328\uD134 \uBC30\uC5F4\n * @param options - chokidar \uC635\uC158\n */\n static async watch(paths: string[], options?: chokidar.ChokidarOptions): Promise<FsWatcher> {\n return new Promise<FsWatcher>((resolve, reject) => {\n const watcher = new FsWatcher(paths, options);\n watcher._watcher.on(\"ready\", () => {\n resolve(watcher);\n });\n watcher._watcher.on(\"error\", reject);\n });\n }\n\n private readonly _watcher: chokidar.FSWatcher;\n private readonly _ignoreInitial: boolean = true;\n private readonly _debounceQueues: DebounceQueue[] = [];\n\n private readonly _logger = createConsola().withTag(\"sd-fs-watcher\");\n\n private constructor(paths: string[], options?: chokidar.ChokidarOptions) {\n this._watcher = chokidar.watch(paths, {\n persistent: true,\n ...options,\n ignoreInitial: true,\n });\n this._ignoreInitial = options?.ignoreInitial ?? this._ignoreInitial;\n\n // \uAC10\uC2DC \uC911 \uBC1C\uC0DD\uD558\uB294 \uC5D0\uB7EC \uB85C\uAE45\n this._watcher.on(\"error\", (err) => {\n this._logger.error(\"FsWatcher error:\", err);\n });\n }\n\n /**\n * \uD30C\uC77C \uBCC0\uACBD \uC774\uBCA4\uD2B8 \uD578\uB4E4\uB7EC \uB4F1\uB85D.\n * \uC9C0\uC815\uB41C delay \uC2DC\uAC04 \uB3D9\uC548 \uC774\uBCA4\uD2B8\uB97C \uBAA8\uC544\uC11C \uD55C \uBC88\uC5D0 \uCF5C\uBC31 \uD638\uCD9C.\n *\n * @param opt.delay - \uC774\uBCA4\uD2B8 \uBCD1\uD569 \uB300\uAE30 \uC2DC\uAC04 (ms)\n * @param cb - \uBCC0\uACBD \uC774\uBCA4\uD2B8 \uCF5C\uBC31\n */\n onChange(opt: { delay?: number }, cb: (changeInfos: FsWatcherChangeInfo[]) => void | Promise<void>): this {\n const fnQ = new DebounceQueue(opt.delay);\n this._debounceQueues.push(fnQ);\n\n let changeInfoMap = new Map<string, EventName>();\n\n // ignoreInitial\uC774 false\uBA74 \uCD08\uAE30\uC5D0 \uBE48 \uBC30\uC5F4\uB85C \uCF5C\uBC31 \uD638\uCD9C\n if (!this._ignoreInitial) {\n fnQ.run(async () => {\n await cb([]);\n });\n }\n\n this._watcher.on(\"all\", (event, filePath) => {\n // \uC9C0\uC6D0\uD558\uB294 \uC774\uBCA4\uD2B8\uB9CC \uCC98\uB9AC\n if (!FS_WATCHER_EVENTS.includes(event as FsWatcherEvent)) return;\n\n /*\n * \uC774\uBCA4\uD2B8 \uBCD1\uD569 \uC804\uB7B5:\n * \uC9E7\uC740 \uC2DC\uAC04 \uB0B4 \uAC19\uC740 \uD30C\uC77C\uC5D0 \uB300\uD574 \uC5EC\uB7EC \uC774\uBCA4\uD2B8\uAC00 \uBC1C\uC0DD\uD558\uBA74 \uCD5C\uC885 \uC0C1\uD0DC\uB9CC \uC804\uB2EC\uD55C\uB2E4.\n * - add + change \u2192 add (\uC0DD\uC131 \uC9C1\uD6C4 \uC218\uC815\uC740 \uC0DD\uC131\uC73C\uB85C \uAC04\uC8FC)\n * - add + unlink \u2192 \uC0AD\uC81C (\uC0DD\uC131 \uD6C4 \uC989\uC2DC \uC0AD\uC81C\uB294 \uBCC0\uACBD \uC5C6\uC74C)\n * - unlink + add \u2192 add (\uC0AD\uC81C \uD6C4 \uC7AC\uC0DD\uC131\uC740 \uC0DD\uC131\uC73C\uB85C \uAC04\uC8FC)\n * - \uADF8 \uC678 \u2192 \uCD5C\uC2E0 \uC774\uBCA4\uD2B8\uB85C \uB36E\uC5B4\uC500\n */\n if (!changeInfoMap.has(filePath)) {\n changeInfoMap.set(filePath, event);\n }\n const prevEvent = changeInfoMap.get(filePath)!;\n\n if (prevEvent === \"add\" && event === \"change\") {\n // add \uD6C4 change \u2192 add \uC720\uC9C0\n changeInfoMap.set(filePath, \"add\");\n } else if ((prevEvent === \"add\" && event === \"unlink\") || (prevEvent === \"addDir\" && event === \"unlinkDir\")) {\n // add \uD6C4 unlink \u2192 \uBCC0\uACBD \uC5C6\uC74C (\uC0AD\uC81C)\n changeInfoMap.delete(filePath);\n } else if (prevEvent === \"unlink\" && (event === \"add\" || event === \"change\")) {\n // unlink \uD6C4 add/change \u2192 add (\uD30C\uC77C \uC7AC\uC0DD\uC131)\n changeInfoMap.set(filePath, \"add\");\n } else if (prevEvent === \"unlinkDir\" && event === \"addDir\") {\n // unlinkDir \uD6C4 addDir \u2192 addDir (\uB514\uB809\uD1A0\uB9AC \uC7AC\uC0DD\uC131)\n changeInfoMap.set(filePath, \"addDir\");\n } else {\n changeInfoMap.set(filePath, event);\n }\n\n fnQ.run(async () => {\n if (changeInfoMap.size === 0) return;\n\n const currChangeInfoMap = changeInfoMap;\n changeInfoMap = new Map<string, EventName>();\n\n const changeInfos = Array.from(currChangeInfoMap.entries()).map(\n ([path, evt]): FsWatcherChangeInfo => ({\n path: pathNorm(path),\n event: evt as FsWatcherEvent,\n }),\n );\n\n await cb(changeInfos);\n });\n });\n\n return this;\n }\n\n /**\n * \uD30C\uC77C \uAC10\uC2DC \uC885\uB8CC.\n */\n async close(): Promise<void> {\n for (const q of this._debounceQueues) {\n q.dispose();\n }\n this._debounceQueues.length = 0;\n await this._watcher.close();\n }\n}\n\n//#endregion\n"],
5
- "mappings": "AAAA,SAAS,qBAAqB;AAC9B,YAAY,cAAc;AAC1B,SAAS,qBAAqB;AAE9B,SAAwB,gBAAgB;AAOxC,MAAM,oBAAoB,CAAC,OAAO,UAAU,UAAU,UAAU,WAAW;AAyCpE,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQrB,aAAa,MAAM,OAAiB,SAAwD;AAC1F,WAAO,IAAI,QAAmB,CAAC,SAAS,WAAW;AACjD,YAAM,UAAU,IAAI,UAAU,OAAO,OAAO;AAC5C,cAAQ,SAAS,GAAG,SAAS,MAAM;AACjC,gBAAQ,OAAO;AAAA,MACjB,CAAC;AACD,cAAQ,SAAS,GAAG,SAAS,MAAM;AAAA,IACrC,CAAC;AAAA,EACH;AAAA,EAEiB;AAAA,EACA,iBAA0B;AAAA,EAC1B,kBAAmC,CAAC;AAAA,EAEpC,UAAU,cAAc,EAAE,QAAQ,eAAe;AAAA,EAE1D,YAAY,OAAiB,SAAoC;AACvE,SAAK,WAAW,SAAS,MAAM,OAAO;AAAA,MACpC,YAAY;AAAA,MACZ,GAAG;AAAA,MACH,eAAe;AAAA,IACjB,CAAC;AACD,SAAK,iBAAiB,SAAS,iBAAiB,KAAK;AAGrD,SAAK,SAAS,GAAG,SAAS,CAAC,QAAQ;AACjC,WAAK,QAAQ,MAAM,oBAAoB,GAAG;AAAA,IAC5C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,SAAS,KAAyB,IAAwE;AACxG,UAAM,MAAM,IAAI,cAAc,IAAI,KAAK;AACvC,SAAK,gBAAgB,KAAK,GAAG;AAE7B,QAAI,gBAAgB,oBAAI,IAAuB;AAG/C,QAAI,CAAC,KAAK,gBAAgB;AACxB,UAAI,IAAI,YAAY;AAClB,cAAM,GAAG,CAAC,CAAC;AAAA,MACb,CAAC;AAAA,IACH;AAEA,SAAK,SAAS,GAAG,OAAO,CAAC,OAAO,aAAa;AAE3C,UAAI,CAAC,kBAAkB,SAAS,KAAuB,EAAG;AAU1D,UAAI,CAAC,cAAc,IAAI,QAAQ,GAAG;AAChC,sBAAc,IAAI,UAAU,KAAK;AAAA,MACnC;AACA,YAAM,YAAY,cAAc,IAAI,QAAQ;AAE5C,UAAI,cAAc,SAAS,UAAU,UAAU;AAE7C,sBAAc,IAAI,UAAU,KAAK;AAAA,MACnC,WAAY,cAAc,SAAS,UAAU,YAAc,cAAc,YAAY,UAAU,aAAc;AAE3G,sBAAc,OAAO,QAAQ;AAAA,MAC/B,WAAW,cAAc,aAAa,UAAU,SAAS,UAAU,WAAW;AAE5E,sBAAc,IAAI,UAAU,KAAK;AAAA,MACnC,WAAW,cAAc,eAAe,UAAU,UAAU;AAE1D,sBAAc,IAAI,UAAU,QAAQ;AAAA,MACtC,OAAO;AACL,sBAAc,IAAI,UAAU,KAAK;AAAA,MACnC;AAEA,UAAI,IAAI,YAAY;AAClB,YAAI,cAAc,SAAS,EAAG;AAE9B,cAAM,oBAAoB;AAC1B,wBAAgB,oBAAI,IAAuB;AAE3C,cAAM,cAAc,MAAM,KAAK,kBAAkB,QAAQ,CAAC,EAAE;AAAA,UAC1D,CAAC,CAAC,MAAM,GAAG,OAA4B;AAAA,YACrC,MAAM,SAAS,IAAI;AAAA,YACnB,OAAO;AAAA,UACT;AAAA,QACF;AAEA,cAAM,GAAG,WAAW;AAAA,MACtB,CAAC;AAAA,IACH,CAAC;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAuB;AAC3B,eAAW,KAAK,KAAK,iBAAiB;AACpC,QAAE,QAAQ;AAAA,IACZ;AACA,SAAK,gBAAgB,SAAS;AAC9B,UAAM,KAAK,SAAS,MAAM;AAAA,EAC5B;AACF;",
4
+ "sourcesContent": ["import { DebounceQueue } from \"@simplysm/core-common\";\nimport * as chokidar from \"chokidar\";\nimport consola from \"consola\";\nimport type { EventName } from \"chokidar/handler.js\";\nimport { type NormPath, pathNorm } from \"../utils/path\";\n\n//#region Types\n\n/**\n * \uC9C0\uC6D0\uD558\uB294 \uD30C\uC77C \uBCC0\uACBD \uC774\uBCA4\uD2B8 \uD0C0\uC785 \uBAA9\uB85D.\n */\nconst FS_WATCHER_EVENTS = [\"add\", \"addDir\", \"change\", \"unlink\", \"unlinkDir\"] as const;\n\n/**\n * \uD30C\uC77C \uBCC0\uACBD \uC774\uBCA4\uD2B8 \uD0C0\uC785.\n */\nexport type FsWatcherEvent = (typeof FS_WATCHER_EVENTS)[number];\n\n/**\n * \uD30C\uC77C \uBCC0\uACBD \uC815\uBCF4.\n */\nexport interface FsWatcherChangeInfo {\n /** \uBCC0\uACBD \uC774\uBCA4\uD2B8 \uD0C0\uC785 */\n event: FsWatcherEvent;\n /** \uBCC0\uACBD\uB41C \uD30C\uC77C/\uB514\uB809\uD1A0\uB9AC \uACBD\uB85C (\uC815\uADDC\uD654\uB428) */\n path: NormPath;\n}\n\n//#endregion\n\n//#region FsWatcher\n\n/**\n * chokidar \uAE30\uBC18 \uD30C\uC77C \uC2DC\uC2A4\uD15C \uAC10\uC2DC \uB798\uD37C.\n * \uC9E7\uC740 \uC2DC\uAC04 \uB0B4 \uBC1C\uC0DD\uD55C \uC774\uBCA4\uD2B8\uB97C \uBCD1\uD569\uD558\uC5EC \uCF5C\uBC31 \uD638\uCD9C.\n *\n * **\uC8FC\uC758**: chokidar\uC758 `ignoreInitial` \uC635\uC158\uC740 \uB0B4\uBD80\uC801\uC73C\uB85C \uD56D\uC0C1 `true`\uB85C \uC124\uC815\uB41C\uB2E4.\n * `options.ignoreInitial: false`\uB97C \uC804\uB2EC\uD558\uBA74 `onChange` \uCCAB \uD638\uCD9C \uC2DC \uBE48 \uBC30\uC5F4\uB85C\n * \uCF5C\uBC31\uC774 \uD638\uCD9C\uB418\uC9C0\uB9CC, \uC2E4\uC81C \uCD08\uAE30 \uD30C\uC77C \uBAA9\uB85D\uC740 \uD3EC\uD568\uB418\uC9C0 \uC54A\uB294\uB2E4.\n * \uC774\uB294 \uC774\uBCA4\uD2B8 \uBCD1\uD569 \uB85C\uC9C1\uACFC\uC758 \uCDA9\uB3CC\uC744 \uBC29\uC9C0\uD558\uAE30 \uC704\uD55C \uC758\uB3C4\uB41C \uB3D9\uC791\uC774\uB2E4.\n *\n * @example\n * const watcher = await FsWatcher.watch([\"src/**\\/*.ts\"]);\n * watcher.onChange({ delay: 300 }, (changes) => {\n * for (const { path, event } of changes) {\n * console.log(`${event}: ${path}`);\n * }\n * });\n *\n * // \uC885\uB8CC\n * await watcher.close();\n */\nexport class FsWatcher {\n /**\n * \uD30C\uC77C \uAC10\uC2DC \uC2DC\uC791 (\uBE44\uB3D9\uAE30).\n * ready \uC774\uBCA4\uD2B8\uAC00 \uBC1C\uC0DD\uD560 \uB54C\uAE4C\uC9C0 \uB300\uAE30.\n *\n * @param paths - \uAC10\uC2DC\uD560 \uD30C\uC77C/\uB514\uB809\uD1A0\uB9AC \uACBD\uB85C \uB610\uB294 glob \uD328\uD134 \uBC30\uC5F4\n * @param options - chokidar \uC635\uC158\n */\n static async watch(paths: string[], options?: chokidar.ChokidarOptions): Promise<FsWatcher> {\n return new Promise<FsWatcher>((resolve, reject) => {\n const watcher = new FsWatcher(paths, options);\n watcher._watcher.on(\"ready\", () => {\n resolve(watcher);\n });\n watcher._watcher.on(\"error\", reject);\n });\n }\n\n private readonly _watcher: chokidar.FSWatcher;\n private readonly _ignoreInitial: boolean = true;\n private readonly _debounceQueues: DebounceQueue[] = [];\n\n private readonly _logger = consola.withTag(\"sd-fs-watcher\");\n\n private constructor(paths: string[], options?: chokidar.ChokidarOptions) {\n this._watcher = chokidar.watch(paths, {\n persistent: true,\n ...options,\n ignoreInitial: true,\n });\n this._ignoreInitial = options?.ignoreInitial ?? this._ignoreInitial;\n\n // \uAC10\uC2DC \uC911 \uBC1C\uC0DD\uD558\uB294 \uC5D0\uB7EC \uB85C\uAE45\n this._watcher.on(\"error\", (err) => {\n this._logger.error(\"FsWatcher error:\", err);\n });\n }\n\n /**\n * \uD30C\uC77C \uBCC0\uACBD \uC774\uBCA4\uD2B8 \uD578\uB4E4\uB7EC \uB4F1\uB85D.\n * \uC9C0\uC815\uB41C delay \uC2DC\uAC04 \uB3D9\uC548 \uC774\uBCA4\uD2B8\uB97C \uBAA8\uC544\uC11C \uD55C \uBC88\uC5D0 \uCF5C\uBC31 \uD638\uCD9C.\n *\n * @param opt.delay - \uC774\uBCA4\uD2B8 \uBCD1\uD569 \uB300\uAE30 \uC2DC\uAC04 (ms)\n * @param cb - \uBCC0\uACBD \uC774\uBCA4\uD2B8 \uCF5C\uBC31\n */\n onChange(opt: { delay?: number }, cb: (changeInfos: FsWatcherChangeInfo[]) => void | Promise<void>): this {\n const fnQ = new DebounceQueue(opt.delay);\n this._debounceQueues.push(fnQ);\n\n let changeInfoMap = new Map<string, EventName>();\n\n // ignoreInitial\uC774 false\uBA74 \uCD08\uAE30\uC5D0 \uBE48 \uBC30\uC5F4\uB85C \uCF5C\uBC31 \uD638\uCD9C\n if (!this._ignoreInitial) {\n fnQ.run(async () => {\n await cb([]);\n });\n }\n\n this._watcher.on(\"all\", (event, filePath) => {\n // \uC9C0\uC6D0\uD558\uB294 \uC774\uBCA4\uD2B8\uB9CC \uCC98\uB9AC\n if (!FS_WATCHER_EVENTS.includes(event as FsWatcherEvent)) return;\n\n /*\n * \uC774\uBCA4\uD2B8 \uBCD1\uD569 \uC804\uB7B5:\n * \uC9E7\uC740 \uC2DC\uAC04 \uB0B4 \uAC19\uC740 \uD30C\uC77C\uC5D0 \uB300\uD574 \uC5EC\uB7EC \uC774\uBCA4\uD2B8\uAC00 \uBC1C\uC0DD\uD558\uBA74 \uCD5C\uC885 \uC0C1\uD0DC\uB9CC \uC804\uB2EC\uD55C\uB2E4.\n * - add + change \u2192 add (\uC0DD\uC131 \uC9C1\uD6C4 \uC218\uC815\uC740 \uC0DD\uC131\uC73C\uB85C \uAC04\uC8FC)\n * - add + unlink \u2192 \uC0AD\uC81C (\uC0DD\uC131 \uD6C4 \uC989\uC2DC \uC0AD\uC81C\uB294 \uBCC0\uACBD \uC5C6\uC74C)\n * - unlink + add \u2192 add (\uC0AD\uC81C \uD6C4 \uC7AC\uC0DD\uC131\uC740 \uC0DD\uC131\uC73C\uB85C \uAC04\uC8FC)\n * - \uADF8 \uC678 \u2192 \uCD5C\uC2E0 \uC774\uBCA4\uD2B8\uB85C \uB36E\uC5B4\uC500\n */\n if (!changeInfoMap.has(filePath)) {\n changeInfoMap.set(filePath, event);\n }\n const prevEvent = changeInfoMap.get(filePath)!;\n\n if (prevEvent === \"add\" && event === \"change\") {\n // add \uD6C4 change \u2192 add \uC720\uC9C0\n changeInfoMap.set(filePath, \"add\");\n } else if ((prevEvent === \"add\" && event === \"unlink\") || (prevEvent === \"addDir\" && event === \"unlinkDir\")) {\n // add \uD6C4 unlink \u2192 \uBCC0\uACBD \uC5C6\uC74C (\uC0AD\uC81C)\n changeInfoMap.delete(filePath);\n } else if (prevEvent === \"unlink\" && (event === \"add\" || event === \"change\")) {\n // unlink \uD6C4 add/change \u2192 add (\uD30C\uC77C \uC7AC\uC0DD\uC131)\n changeInfoMap.set(filePath, \"add\");\n } else if (prevEvent === \"unlinkDir\" && event === \"addDir\") {\n // unlinkDir \uD6C4 addDir \u2192 addDir (\uB514\uB809\uD1A0\uB9AC \uC7AC\uC0DD\uC131)\n changeInfoMap.set(filePath, \"addDir\");\n } else {\n changeInfoMap.set(filePath, event);\n }\n\n fnQ.run(async () => {\n if (changeInfoMap.size === 0) return;\n\n const currChangeInfoMap = changeInfoMap;\n changeInfoMap = new Map<string, EventName>();\n\n const changeInfos = Array.from(currChangeInfoMap.entries()).map(\n ([path, evt]): FsWatcherChangeInfo => ({\n path: pathNorm(path),\n event: evt as FsWatcherEvent,\n }),\n );\n\n await cb(changeInfos);\n });\n });\n\n return this;\n }\n\n /**\n * \uD30C\uC77C \uAC10\uC2DC \uC885\uB8CC.\n */\n async close(): Promise<void> {\n for (const q of this._debounceQueues) {\n q.dispose();\n }\n this._debounceQueues.length = 0;\n await this._watcher.close();\n }\n}\n\n//#endregion\n"],
5
+ "mappings": "AAAA,SAAS,qBAAqB;AAC9B,YAAY,cAAc;AAC1B,OAAO,aAAa;AAEpB,SAAwB,gBAAgB;AAOxC,MAAM,oBAAoB,CAAC,OAAO,UAAU,UAAU,UAAU,WAAW;AAyCpE,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQrB,aAAa,MAAM,OAAiB,SAAwD;AAC1F,WAAO,IAAI,QAAmB,CAAC,SAAS,WAAW;AACjD,YAAM,UAAU,IAAI,UAAU,OAAO,OAAO;AAC5C,cAAQ,SAAS,GAAG,SAAS,MAAM;AACjC,gBAAQ,OAAO;AAAA,MACjB,CAAC;AACD,cAAQ,SAAS,GAAG,SAAS,MAAM;AAAA,IACrC,CAAC;AAAA,EACH;AAAA,EAEiB;AAAA,EACA,iBAA0B;AAAA,EAC1B,kBAAmC,CAAC;AAAA,EAEpC,UAAU,QAAQ,QAAQ,eAAe;AAAA,EAElD,YAAY,OAAiB,SAAoC;AACvE,SAAK,WAAW,SAAS,MAAM,OAAO;AAAA,MACpC,YAAY;AAAA,MACZ,GAAG;AAAA,MACH,eAAe;AAAA,IACjB,CAAC;AACD,SAAK,iBAAiB,SAAS,iBAAiB,KAAK;AAGrD,SAAK,SAAS,GAAG,SAAS,CAAC,QAAQ;AACjC,WAAK,QAAQ,MAAM,oBAAoB,GAAG;AAAA,IAC5C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,SAAS,KAAyB,IAAwE;AACxG,UAAM,MAAM,IAAI,cAAc,IAAI,KAAK;AACvC,SAAK,gBAAgB,KAAK,GAAG;AAE7B,QAAI,gBAAgB,oBAAI,IAAuB;AAG/C,QAAI,CAAC,KAAK,gBAAgB;AACxB,UAAI,IAAI,YAAY;AAClB,cAAM,GAAG,CAAC,CAAC;AAAA,MACb,CAAC;AAAA,IACH;AAEA,SAAK,SAAS,GAAG,OAAO,CAAC,OAAO,aAAa;AAE3C,UAAI,CAAC,kBAAkB,SAAS,KAAuB,EAAG;AAU1D,UAAI,CAAC,cAAc,IAAI,QAAQ,GAAG;AAChC,sBAAc,IAAI,UAAU,KAAK;AAAA,MACnC;AACA,YAAM,YAAY,cAAc,IAAI,QAAQ;AAE5C,UAAI,cAAc,SAAS,UAAU,UAAU;AAE7C,sBAAc,IAAI,UAAU,KAAK;AAAA,MACnC,WAAY,cAAc,SAAS,UAAU,YAAc,cAAc,YAAY,UAAU,aAAc;AAE3G,sBAAc,OAAO,QAAQ;AAAA,MAC/B,WAAW,cAAc,aAAa,UAAU,SAAS,UAAU,WAAW;AAE5E,sBAAc,IAAI,UAAU,KAAK;AAAA,MACnC,WAAW,cAAc,eAAe,UAAU,UAAU;AAE1D,sBAAc,IAAI,UAAU,QAAQ;AAAA,MACtC,OAAO;AACL,sBAAc,IAAI,UAAU,KAAK;AAAA,MACnC;AAEA,UAAI,IAAI,YAAY;AAClB,YAAI,cAAc,SAAS,EAAG;AAE9B,cAAM,oBAAoB;AAC1B,wBAAgB,oBAAI,IAAuB;AAE3C,cAAM,cAAc,MAAM,KAAK,kBAAkB,QAAQ,CAAC,EAAE;AAAA,UAC1D,CAAC,CAAC,MAAM,GAAG,OAA4B;AAAA,YACrC,MAAM,SAAS,IAAI;AAAA,YACnB,OAAO;AAAA,UACT;AAAA,QACF;AAEA,cAAM,GAAG,WAAW;AAAA,MACtB,CAAC;AAAA,IACH,CAAC;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAuB;AAC3B,eAAW,KAAK,KAAK,iBAAiB;AACpC,QAAE,QAAQ;AAAA,IACZ;AACA,SAAK,gBAAgB,SAAS;AAC9B,UAAM,KAAK,SAAS,MAAM;AAAA,EAC5B;AACF;",
6
6
  "names": []
7
7
  }
@@ -1,9 +1,9 @@
1
1
  import { EventEmitter, transferableDecode, transferableEncode, Uuid } from "@simplysm/core-common";
2
- import { createConsola } from "consola";
2
+ import consola from "consola";
3
3
  import path from "path";
4
4
  import { fileURLToPath } from "url";
5
5
  import { Worker as WorkerRaw } from "worker_threads";
6
- const logger = createConsola().withTag("sd-worker");
6
+ const logger = consola.withTag("sd-worker");
7
7
  class WorkerInternal extends EventEmitter {
8
8
  _worker;
9
9
  _isTerminated = false;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/worker/worker.ts"],
4
- "sourcesContent": ["import { EventEmitter, transferableDecode, transferableEncode, Uuid } from \"@simplysm/core-common\";\nimport { createConsola } from \"consola\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport type { WorkerOptions as WorkerRawOptions } from \"worker_threads\";\nimport { Worker as WorkerRaw } from \"worker_threads\";\nimport type { WorkerModule, WorkerProxy, WorkerRequest, WorkerResponse } from \"./types\";\n\nconst logger = createConsola().withTag(\"sd-worker\");\n\n//#region WorkerInternal\n\n/**\n * Worker \uB0B4\uBD80 \uAD6C\uD604 \uD074\uB798\uC2A4.\n * Proxy\uB97C \uD1B5\uD574 \uC678\uBD80\uC5D0 \uB178\uCD9C\uB428.\n *\n * \uAC1C\uBC1C \uD658\uACBD(.ts)\uC5D0\uC11C\uB294 tsx\uB97C \uD1B5\uD574 TypeScript \uC6CC\uCEE4 \uD30C\uC77C\uC744 \uC2E4\uD589\uD558\uACE0,\n * \uD504\uB85C\uB355\uC158 \uD658\uACBD(.js)\uC5D0\uC11C\uB294 \uC9C1\uC811 Worker\uB97C \uC0DD\uC131\uD55C\uB2E4.\n */\nclass WorkerInternal extends EventEmitter<Record<string, unknown>> {\n private readonly _worker: WorkerRaw;\n private _isTerminated = false;\n private readonly _pendingRequests = new Map<\n string,\n { method: string; resolve: (value: unknown) => void; reject: (err: Error) => void }\n >();\n\n constructor(filePath: string, opt?: Omit<WorkerRawOptions, \"stdout\" | \"stderr\">) {\n super();\n\n const ext = path.extname(import.meta.filename);\n\n // \uD0C0\uC785 \uAC00\uB4DC\uB97C \uD1B5\uD55C env \uAC1D\uCCB4 \uCD94\uCD9C\n const envObj = opt?.env != null && typeof opt.env === \"object\" ? opt.env : {};\n\n // \uAC1C\uBC1C \uD658\uACBD (.ts \uD30C\uC77C)\uC778 \uACBD\uC6B0 tsx\uB97C \uD1B5\uD574 \uC2E4\uD589\n // worker-dev-proxy.js: tsx\uB85C TypeScript \uC6CC\uCEE4 \uD30C\uC77C\uC744 \uB3D9\uC801\uC73C\uB85C \uB85C\uB4DC\uD558\uB294 \uD504\uB85D\uC2DC\n if (ext === \".ts\") {\n // file:// URL\uC778 \uACBD\uC6B0 \uC808\uB300 \uACBD\uB85C\uB85C \uBCC0\uD658 (worker-dev-proxy.js\uC5D0\uC11C \uB2E4\uC2DC pathToFileURL \uC801\uC6A9)\n const workerPath = filePath.startsWith(\"file://\") ? fileURLToPath(filePath) : filePath;\n this._worker = new WorkerRaw(path.resolve(import.meta.dirname, \"../../lib/worker-dev-proxy.js\"), {\n stdout: true,\n stderr: true,\n ...opt,\n env: {\n ...process.env,\n ...envObj,\n },\n argv: [workerPath, ...(opt?.argv ?? [])],\n });\n } else {\n // \uD504\uB85C\uB355\uC158 \uD658\uACBD (.js \uD30C\uC77C)\n // file:// URL\uC778 \uACBD\uC6B0 \uBCC0\uD658, \uC774\uBBF8 \uC808\uB300 \uACBD\uB85C\uC778 \uACBD\uC6B0 \uADF8\uB300\uB85C \uC0AC\uC6A9\n const workerPath = filePath.startsWith(\"file://\") ? fileURLToPath(filePath) : filePath;\n this._worker = new WorkerRaw(workerPath, {\n stdout: true,\n stderr: true,\n ...opt,\n env: {\n ...process.env,\n ...envObj,\n },\n });\n }\n\n // \uC6CC\uCEE4\uC758 stdout/stderr\uB97C \uBA54\uC778\uC5D0 \uCD9C\uB825\n this._worker.stdout.pipe(process.stdout);\n this._worker.stderr.pipe(process.stderr);\n\n this._worker.on(\"exit\", (code) => {\n if (!this._isTerminated && code !== 0) {\n logger.error(`\uC6CC\uCEE4\uAC00 \uC624\uB958\uC640 \uD568\uAED8 \uB2EB\uD798 (code: ${code})`);\n // \uBE44\uC815\uC0C1 \uC885\uB8CC \uC2DC \uB300\uAE30 \uC911\uC778 \uBAA8\uB4E0 \uC694\uCCAD reject\n this._rejectAllPending(new Error(`\uC6CC\uCEE4\uAC00 \uBE44\uC815\uC0C1 \uC885\uB8CC\uB428 (code: ${code})`));\n }\n });\n\n this._worker.on(\"error\", (err) => {\n logger.error(\"\uC6CC\uCEE4 \uC624\uB958:\", err);\n // \uC6CC\uCEE4 \uC5D0\uB7EC \uC2DC \uB300\uAE30 \uC911\uC778 \uBAA8\uB4E0 \uC694\uCCAD reject\n this._rejectAllPending(err);\n });\n\n this._worker.on(\"message\", (serializedResponse: unknown) => {\n const decoded = transferableDecode(serializedResponse);\n\n // \uC751\uB2F5 \uAD6C\uC870 \uAC80\uC99D\n if (decoded == null || typeof decoded !== \"object\" || !(\"type\" in decoded)) {\n logger.warn(\"\uC6CC\uCEE4\uC5D0\uC11C \uC798\uBABB\uB41C \uD615\uC2DD\uC758 \uC751\uB2F5:\", decoded);\n return;\n }\n const response = decoded as WorkerResponse;\n\n if (response.type === \"event\") {\n this.emit(response.event, response.body);\n } else if (response.type === \"log\") {\n process.stdout.write(response.body);\n } else if (response.type === \"return\") {\n const pending = this._pendingRequests.get(response.request.id);\n if (pending) {\n this._pendingRequests.delete(response.request.id);\n pending.resolve(response.body);\n }\n } else {\n // response.type === \"error\"\n const pending = this._pendingRequests.get(response.request.id);\n if (pending) {\n this._pendingRequests.delete(response.request.id);\n pending.reject(response.body);\n }\n }\n });\n }\n\n /**\n * \uB300\uAE30 \uC911\uC778 \uBAA8\uB4E0 \uC694\uCCAD\uC744 reject\uD569\uB2C8\uB2E4.\n */\n private _rejectAllPending(err: Error): void {\n for (const [_id, { method, reject }] of this._pendingRequests) {\n reject(new Error(`${err.message} (method: ${method})`));\n }\n this._pendingRequests.clear();\n }\n\n /**\n * \uC6CC\uCEE4 \uBA54\uC11C\uB4DC \uD638\uCD9C.\n */\n call(method: string, params: unknown[]): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const request: WorkerRequest = {\n id: Uuid.new().toString(),\n method,\n params,\n };\n\n this._pendingRequests.set(request.id, { method, resolve, reject });\n\n const serialized = transferableEncode(request);\n this._worker.postMessage(serialized.result, serialized.transferList);\n });\n }\n\n /**\n * \uC6CC\uCEE4 \uC885\uB8CC.\n */\n async terminate(): Promise<void> {\n this._isTerminated = true;\n this._rejectAllPending(new Error(\"\uC6CC\uCEE4\uAC00 \uC885\uB8CC\uB428\"));\n await this._worker.terminate();\n }\n}\n\n//#endregion\n\n//#region Worker\n\n/**\n * \uD0C0\uC785 \uC548\uC804\uD55C Worker \uB798\uD37C.\n *\n * @example\n * // worker.ts\n * export default createWorker({\n * add: (a: number, b: number) => a + b,\n * });\n *\n * // main.ts\n * const worker = Worker.create<typeof import(\"./worker\")>(\"./worker.ts\");\n * const result = await worker.add(10, 20); // 30\n * await worker.terminate();\n */\nexport const Worker = {\n /**\n * \uD0C0\uC785 \uC548\uC804\uD55C Worker Proxy \uC0DD\uC131.\n *\n * @param filePath - \uC6CC\uCEE4 \uD30C\uC77C \uACBD\uB85C (file:// URL \uB610\uB294 \uC808\uB300 \uACBD\uB85C)\n * @param opt - Worker \uC635\uC158\n * @returns Proxy \uAC1D\uCCB4 (\uBA54\uC11C\uB4DC \uC9C1\uC811 \uD638\uCD9C, on(), terminate() \uC9C0\uC6D0)\n */\n create<TModule extends WorkerModule>(\n filePath: string,\n opt?: Omit<WorkerRawOptions, \"stdout\" | \"stderr\">,\n ): WorkerProxy<TModule> {\n const internal = new WorkerInternal(filePath, opt);\n\n return new Proxy({} as WorkerProxy<TModule>, {\n get(_target, prop: string) {\n // \uC608\uC57D\uB41C \uBA54\uC11C\uB4DC: on, off, terminate\n if (prop === \"on\") {\n return (event: string, listener: (data: unknown) => void) => {\n internal.on(event, listener);\n };\n }\n if (prop === \"off\") {\n return (event: string, listener: (data: unknown) => void) => {\n internal.off(event, listener);\n };\n }\n if (prop === \"terminate\") {\n return () => internal.terminate();\n }\n\n // \uADF8 \uC678\uB294 \uC6CC\uCEE4 \uBA54\uC11C\uB4DC\uB85C \uCC98\uB9AC\n return (...args: unknown[]) => internal.call(prop, args);\n },\n });\n },\n};\n\n//#endregion\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { EventEmitter, transferableDecode, transferableEncode, Uuid } from \"@simplysm/core-common\";\nimport consola from \"consola\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport type { WorkerOptions as WorkerRawOptions } from \"worker_threads\";\nimport { Worker as WorkerRaw } from \"worker_threads\";\nimport type { WorkerModule, WorkerProxy, WorkerRequest, WorkerResponse } from \"./types\";\n\nconst logger = consola.withTag(\"sd-worker\");\n\n//#region WorkerInternal\n\n/**\n * Worker \uB0B4\uBD80 \uAD6C\uD604 \uD074\uB798\uC2A4.\n * Proxy\uB97C \uD1B5\uD574 \uC678\uBD80\uC5D0 \uB178\uCD9C\uB428.\n *\n * \uAC1C\uBC1C \uD658\uACBD(.ts)\uC5D0\uC11C\uB294 tsx\uB97C \uD1B5\uD574 TypeScript \uC6CC\uCEE4 \uD30C\uC77C\uC744 \uC2E4\uD589\uD558\uACE0,\n * \uD504\uB85C\uB355\uC158 \uD658\uACBD(.js)\uC5D0\uC11C\uB294 \uC9C1\uC811 Worker\uB97C \uC0DD\uC131\uD55C\uB2E4.\n */\nclass WorkerInternal extends EventEmitter<Record<string, unknown>> {\n private readonly _worker: WorkerRaw;\n private _isTerminated = false;\n private readonly _pendingRequests = new Map<\n string,\n { method: string; resolve: (value: unknown) => void; reject: (err: Error) => void }\n >();\n\n constructor(filePath: string, opt?: Omit<WorkerRawOptions, \"stdout\" | \"stderr\">) {\n super();\n\n const ext = path.extname(import.meta.filename);\n\n // \uD0C0\uC785 \uAC00\uB4DC\uB97C \uD1B5\uD55C env \uAC1D\uCCB4 \uCD94\uCD9C\n const envObj = opt?.env != null && typeof opt.env === \"object\" ? opt.env : {};\n\n // \uAC1C\uBC1C \uD658\uACBD (.ts \uD30C\uC77C)\uC778 \uACBD\uC6B0 tsx\uB97C \uD1B5\uD574 \uC2E4\uD589\n // worker-dev-proxy.js: tsx\uB85C TypeScript \uC6CC\uCEE4 \uD30C\uC77C\uC744 \uB3D9\uC801\uC73C\uB85C \uB85C\uB4DC\uD558\uB294 \uD504\uB85D\uC2DC\n if (ext === \".ts\") {\n // file:// URL\uC778 \uACBD\uC6B0 \uC808\uB300 \uACBD\uB85C\uB85C \uBCC0\uD658 (worker-dev-proxy.js\uC5D0\uC11C \uB2E4\uC2DC pathToFileURL \uC801\uC6A9)\n const workerPath = filePath.startsWith(\"file://\") ? fileURLToPath(filePath) : filePath;\n this._worker = new WorkerRaw(path.resolve(import.meta.dirname, \"../../lib/worker-dev-proxy.js\"), {\n stdout: true,\n stderr: true,\n ...opt,\n env: {\n ...process.env,\n ...envObj,\n },\n argv: [workerPath, ...(opt?.argv ?? [])],\n });\n } else {\n // \uD504\uB85C\uB355\uC158 \uD658\uACBD (.js \uD30C\uC77C)\n // file:// URL\uC778 \uACBD\uC6B0 \uBCC0\uD658, \uC774\uBBF8 \uC808\uB300 \uACBD\uB85C\uC778 \uACBD\uC6B0 \uADF8\uB300\uB85C \uC0AC\uC6A9\n const workerPath = filePath.startsWith(\"file://\") ? fileURLToPath(filePath) : filePath;\n this._worker = new WorkerRaw(workerPath, {\n stdout: true,\n stderr: true,\n ...opt,\n env: {\n ...process.env,\n ...envObj,\n },\n });\n }\n\n // \uC6CC\uCEE4\uC758 stdout/stderr\uB97C \uBA54\uC778\uC5D0 \uCD9C\uB825\n this._worker.stdout.pipe(process.stdout);\n this._worker.stderr.pipe(process.stderr);\n\n this._worker.on(\"exit\", (code) => {\n if (!this._isTerminated && code !== 0) {\n logger.error(`\uC6CC\uCEE4\uAC00 \uC624\uB958\uC640 \uD568\uAED8 \uB2EB\uD798 (code: ${code})`);\n // \uBE44\uC815\uC0C1 \uC885\uB8CC \uC2DC \uB300\uAE30 \uC911\uC778 \uBAA8\uB4E0 \uC694\uCCAD reject\n this._rejectAllPending(new Error(`\uC6CC\uCEE4\uAC00 \uBE44\uC815\uC0C1 \uC885\uB8CC\uB428 (code: ${code})`));\n }\n });\n\n this._worker.on(\"error\", (err) => {\n logger.error(\"\uC6CC\uCEE4 \uC624\uB958:\", err);\n // \uC6CC\uCEE4 \uC5D0\uB7EC \uC2DC \uB300\uAE30 \uC911\uC778 \uBAA8\uB4E0 \uC694\uCCAD reject\n this._rejectAllPending(err);\n });\n\n this._worker.on(\"message\", (serializedResponse: unknown) => {\n const decoded = transferableDecode(serializedResponse);\n\n // \uC751\uB2F5 \uAD6C\uC870 \uAC80\uC99D\n if (decoded == null || typeof decoded !== \"object\" || !(\"type\" in decoded)) {\n logger.warn(\"\uC6CC\uCEE4\uC5D0\uC11C \uC798\uBABB\uB41C \uD615\uC2DD\uC758 \uC751\uB2F5:\", decoded);\n return;\n }\n const response = decoded as WorkerResponse;\n\n if (response.type === \"event\") {\n this.emit(response.event, response.body);\n } else if (response.type === \"log\") {\n process.stdout.write(response.body);\n } else if (response.type === \"return\") {\n const pending = this._pendingRequests.get(response.request.id);\n if (pending) {\n this._pendingRequests.delete(response.request.id);\n pending.resolve(response.body);\n }\n } else {\n // response.type === \"error\"\n const pending = this._pendingRequests.get(response.request.id);\n if (pending) {\n this._pendingRequests.delete(response.request.id);\n pending.reject(response.body);\n }\n }\n });\n }\n\n /**\n * \uB300\uAE30 \uC911\uC778 \uBAA8\uB4E0 \uC694\uCCAD\uC744 reject\uD569\uB2C8\uB2E4.\n */\n private _rejectAllPending(err: Error): void {\n for (const [_id, { method, reject }] of this._pendingRequests) {\n reject(new Error(`${err.message} (method: ${method})`));\n }\n this._pendingRequests.clear();\n }\n\n /**\n * \uC6CC\uCEE4 \uBA54\uC11C\uB4DC \uD638\uCD9C.\n */\n call(method: string, params: unknown[]): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const request: WorkerRequest = {\n id: Uuid.new().toString(),\n method,\n params,\n };\n\n this._pendingRequests.set(request.id, { method, resolve, reject });\n\n const serialized = transferableEncode(request);\n this._worker.postMessage(serialized.result, serialized.transferList);\n });\n }\n\n /**\n * \uC6CC\uCEE4 \uC885\uB8CC.\n */\n async terminate(): Promise<void> {\n this._isTerminated = true;\n this._rejectAllPending(new Error(\"\uC6CC\uCEE4\uAC00 \uC885\uB8CC\uB428\"));\n await this._worker.terminate();\n }\n}\n\n//#endregion\n\n//#region Worker\n\n/**\n * \uD0C0\uC785 \uC548\uC804\uD55C Worker \uB798\uD37C.\n *\n * @example\n * // worker.ts\n * export default createWorker({\n * add: (a: number, b: number) => a + b,\n * });\n *\n * // main.ts\n * const worker = Worker.create<typeof import(\"./worker\")>(\"./worker.ts\");\n * const result = await worker.add(10, 20); // 30\n * await worker.terminate();\n */\nexport const Worker = {\n /**\n * \uD0C0\uC785 \uC548\uC804\uD55C Worker Proxy \uC0DD\uC131.\n *\n * @param filePath - \uC6CC\uCEE4 \uD30C\uC77C \uACBD\uB85C (file:// URL \uB610\uB294 \uC808\uB300 \uACBD\uB85C)\n * @param opt - Worker \uC635\uC158\n * @returns Proxy \uAC1D\uCCB4 (\uBA54\uC11C\uB4DC \uC9C1\uC811 \uD638\uCD9C, on(), terminate() \uC9C0\uC6D0)\n */\n create<TModule extends WorkerModule>(\n filePath: string,\n opt?: Omit<WorkerRawOptions, \"stdout\" | \"stderr\">,\n ): WorkerProxy<TModule> {\n const internal = new WorkerInternal(filePath, opt);\n\n return new Proxy({} as WorkerProxy<TModule>, {\n get(_target, prop: string) {\n // \uC608\uC57D\uB41C \uBA54\uC11C\uB4DC: on, off, terminate\n if (prop === \"on\") {\n return (event: string, listener: (data: unknown) => void) => {\n internal.on(event, listener);\n };\n }\n if (prop === \"off\") {\n return (event: string, listener: (data: unknown) => void) => {\n internal.off(event, listener);\n };\n }\n if (prop === \"terminate\") {\n return () => internal.terminate();\n }\n\n // \uADF8 \uC678\uB294 \uC6CC\uCEE4 \uBA54\uC11C\uB4DC\uB85C \uCC98\uB9AC\n return (...args: unknown[]) => internal.call(prop, args);\n },\n });\n },\n};\n\n//#endregion\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/core-node",
3
- "version": "13.0.0-beta.38",
3
+ "version": "13.0.0-beta.41",
4
4
  "description": "심플리즘 패키지 - 코어 모듈 (node)",
5
5
  "author": "김석래",
6
6
  "repository": {
@@ -21,6 +21,6 @@
21
21
  "consola": "^3.4.2",
22
22
  "glob": "^13.0.2",
23
23
  "tsx": "^4.21.0",
24
- "@simplysm/core-common": "13.0.0-beta.38"
24
+ "@simplysm/core-common": "13.0.0-beta.41"
25
25
  }
26
26
  }