@simplysm/core-node 13.0.2 → 13.0.7

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.
@@ -49,6 +49,7 @@ export declare class FsWatcher {
49
49
  private readonly _watcher;
50
50
  private readonly _ignoreInitial;
51
51
  private readonly _debounceQueues;
52
+ private readonly _globMatchers;
52
53
  private readonly _logger;
53
54
  private constructor();
54
55
  /**
@@ -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,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
+ {"version":3,"file":"fs-watcher.d.ts","sourceRoot":"","sources":["../../src/features/fs-watcher.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,QAAQ,MAAM,UAAU,CAAC;AAKrC,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,eAAe,CAAC;AAyBxD;;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;IACvD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAmB;IAEjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoC;IAE5D,OAAO;IA6BP;;;;;;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;IAwEzG;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAO7B"}
@@ -1,7 +1,19 @@
1
1
  import { DebounceQueue } from "@simplysm/core-common";
2
2
  import * as chokidar from "chokidar";
3
3
  import consola from "consola";
4
+ import { Minimatch } from "minimatch";
5
+ import path from "path";
4
6
  import { pathNorm } from "../utils/path.js";
7
+ const GLOB_CHARS_RE = /[*?{[\]]/;
8
+ function extractGlobBase(globPath) {
9
+ const segments = globPath.split(/[/\\]/);
10
+ const baseSegments = [];
11
+ for (const seg of segments) {
12
+ if (GLOB_CHARS_RE.test(seg)) break;
13
+ baseSegments.push(seg);
14
+ }
15
+ return baseSegments.join(path.sep) || path.sep;
16
+ }
5
17
  const FS_WATCHER_EVENTS = ["add", "addDir", "change", "unlink", "unlinkDir"];
6
18
  class FsWatcher {
7
19
  /**
@@ -23,9 +35,21 @@ class FsWatcher {
23
35
  _watcher;
24
36
  _ignoreInitial = true;
25
37
  _debounceQueues = [];
38
+ _globMatchers = [];
26
39
  _logger = consola.withTag("sd-fs-watcher");
27
40
  constructor(paths, options) {
28
- this._watcher = chokidar.watch(paths, {
41
+ const watchPaths = [];
42
+ for (const p of paths) {
43
+ const posixPath = p.replace(/\\/g, "/");
44
+ if (GLOB_CHARS_RE.test(posixPath)) {
45
+ this._globMatchers.push(new Minimatch(posixPath, { dot: true }));
46
+ watchPaths.push(extractGlobBase(p));
47
+ } else {
48
+ watchPaths.push(p);
49
+ }
50
+ }
51
+ const uniquePaths = [...new Set(watchPaths)];
52
+ this._watcher = chokidar.watch(uniquePaths, {
29
53
  persistent: true,
30
54
  ...options,
31
55
  ignoreInitial: true
@@ -53,6 +77,10 @@ class FsWatcher {
53
77
  }
54
78
  this._watcher.on("all", (event, filePath) => {
55
79
  if (!FS_WATCHER_EVENTS.includes(event)) return;
80
+ if (this._globMatchers.length > 0) {
81
+ const posixFilePath = filePath.replace(/\\/g, "/");
82
+ if (!this._globMatchers.some((m) => m.match(posixFilePath))) return;
83
+ }
56
84
  if (!changeInfoMap.has(filePath)) {
57
85
  changeInfoMap.set(filePath, event);
58
86
  }
@@ -73,8 +101,8 @@ class FsWatcher {
73
101
  const currChangeInfoMap = changeInfoMap;
74
102
  changeInfoMap = /* @__PURE__ */ new Map();
75
103
  const changeInfos = Array.from(currChangeInfoMap.entries()).map(
76
- ([path, evt]) => ({
77
- path: pathNorm(path),
104
+ ([changedPath, evt]) => ({
105
+ path: pathNorm(changedPath),
78
106
  event: evt
79
107
  })
80
108
  );
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/features/fs-watcher.ts"],
4
- "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;",
4
+ "mappings": "AAAA,SAAS,qBAAqB;AAC9B,YAAY,cAAc;AAC1B,OAAO,aAAa;AAEpB,SAAS,iBAAiB;AAC1B,OAAO,UAAU;AACjB,SAAwB,gBAAgB;AAKxC,MAAM,gBAAgB;AAMtB,SAAS,gBAAgB,UAA0B;AACjD,QAAM,WAAW,SAAS,MAAM,OAAO;AACvC,QAAM,eAAyB,CAAC;AAChC,aAAW,OAAO,UAAU;AAC1B,QAAI,cAAc,KAAK,GAAG,EAAG;AAC7B,iBAAa,KAAK,GAAG;AAAA,EACvB;AACA,SAAO,aAAa,KAAK,KAAK,GAAG,KAAK,KAAK;AAC7C;AASA,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,EACpC,gBAA6B,CAAC;AAAA,EAE9B,UAAU,QAAQ,QAAQ,eAAe;AAAA,EAElD,YAAY,OAAiB,SAAoC;AACvE,UAAM,aAAuB,CAAC;AAE9B,eAAW,KAAK,OAAO;AACrB,YAAM,YAAY,EAAE,QAAQ,OAAO,GAAG;AACtC,UAAI,cAAc,KAAK,SAAS,GAAG;AACjC,aAAK,cAAc,KAAK,IAAI,UAAU,WAAW,EAAE,KAAK,KAAK,CAAC,CAAC;AAC/D,mBAAW,KAAK,gBAAgB,CAAC,CAAC;AAAA,MACpC,OAAO;AACL,mBAAW,KAAK,CAAC;AAAA,MACnB;AAAA,IACF;AAGA,UAAM,cAAc,CAAC,GAAG,IAAI,IAAI,UAAU,CAAC;AAE3C,SAAK,WAAW,SAAS,MAAM,aAAa;AAAA,MAC1C,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;AAG1D,UAAI,KAAK,cAAc,SAAS,GAAG;AACjC,cAAM,gBAAgB,SAAS,QAAQ,OAAO,GAAG;AACjD,YAAI,CAAC,KAAK,cAAc,KAAK,CAAC,MAAM,EAAE,MAAM,aAAa,CAAC,EAAG;AAAA,MAC/D;AAUA,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,aAAa,GAAG,OAA4B;AAAA,YAC5C,MAAM,SAAS,WAAW;AAAA,YAC1B,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;",
5
5
  "names": []
6
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/core-node",
3
- "version": "13.0.2",
3
+ "version": "13.0.7",
4
4
  "description": "심플리즘 패키지 - 코어 모듈 (node)",
5
5
  "author": "김석래",
6
6
  "repository": {
@@ -20,8 +20,9 @@
20
20
  "dependencies": {
21
21
  "chokidar": "^5.0.0",
22
22
  "consola": "^3.4.2",
23
- "glob": "^13.0.2",
23
+ "glob": "^13.0.3",
24
+ "minimatch": "^10.2.0",
24
25
  "tsx": "^4.21.0",
25
- "@simplysm/core-common": "13.0.2"
26
+ "@simplysm/core-common": "13.0.7"
26
27
  }
27
28
  }
@@ -2,8 +2,31 @@ import { DebounceQueue } from "@simplysm/core-common";
2
2
  import * as chokidar from "chokidar";
3
3
  import consola from "consola";
4
4
  import type { EventName } from "chokidar/handler.js";
5
+ import { Minimatch } from "minimatch";
6
+ import path from "path";
5
7
  import { type NormPath, pathNorm } from "../utils/path";
6
8
 
9
+ //#region Helpers
10
+
11
+ /** glob 메타문자 패턴 */
12
+ const GLOB_CHARS_RE = /[*?{[\]]/;
13
+
14
+ /**
15
+ * glob 패턴에서 base 디렉토리 추출.
16
+ * @example extractGlobBase("/home/user/src/**\/*.ts") → "/home/user/src"
17
+ */
18
+ function extractGlobBase(globPath: string): string {
19
+ const segments = globPath.split(/[/\\]/);
20
+ const baseSegments: string[] = [];
21
+ for (const seg of segments) {
22
+ if (GLOB_CHARS_RE.test(seg)) break;
23
+ baseSegments.push(seg);
24
+ }
25
+ return baseSegments.join(path.sep) || path.sep;
26
+ }
27
+
28
+ //#endregion
29
+
7
30
  //#region Types
8
31
 
9
32
  /**
@@ -71,11 +94,27 @@ export class FsWatcher {
71
94
  private readonly _watcher: chokidar.FSWatcher;
72
95
  private readonly _ignoreInitial: boolean = true;
73
96
  private readonly _debounceQueues: DebounceQueue[] = [];
97
+ private readonly _globMatchers: Minimatch[] = [];
74
98
 
75
99
  private readonly _logger = consola.withTag("sd-fs-watcher");
76
100
 
77
101
  private constructor(paths: string[], options?: chokidar.ChokidarOptions) {
78
- this._watcher = chokidar.watch(paths, {
102
+ const watchPaths: string[] = [];
103
+
104
+ for (const p of paths) {
105
+ const posixPath = p.replace(/\\/g, "/");
106
+ if (GLOB_CHARS_RE.test(posixPath)) {
107
+ this._globMatchers.push(new Minimatch(posixPath, { dot: true }));
108
+ watchPaths.push(extractGlobBase(p));
109
+ } else {
110
+ watchPaths.push(p);
111
+ }
112
+ }
113
+
114
+ // 중복 경로 제거
115
+ const uniquePaths = [...new Set(watchPaths)];
116
+
117
+ this._watcher = chokidar.watch(uniquePaths, {
79
118
  persistent: true,
80
119
  ...options,
81
120
  ignoreInitial: true,
@@ -112,6 +151,12 @@ export class FsWatcher {
112
151
  // 지원하는 이벤트만 처리
113
152
  if (!FS_WATCHER_EVENTS.includes(event as FsWatcherEvent)) return;
114
153
 
154
+ // glob 매처가 있으면 패턴 필터링 적용
155
+ if (this._globMatchers.length > 0) {
156
+ const posixFilePath = filePath.replace(/\\/g, "/");
157
+ if (!this._globMatchers.some((m) => m.match(posixFilePath))) return;
158
+ }
159
+
115
160
  /*
116
161
  * 이벤트 병합 전략:
117
162
  * 짧은 시간 내 같은 파일에 대해 여러 이벤트가 발생하면 최종 상태만 전달한다.
@@ -148,8 +193,8 @@ export class FsWatcher {
148
193
  changeInfoMap = new Map<string, EventName>();
149
194
 
150
195
  const changeInfos = Array.from(currChangeInfoMap.entries()).map(
151
- ([path, evt]): FsWatcherChangeInfo => ({
152
- path: pathNorm(path),
196
+ ([changedPath, evt]): FsWatcherChangeInfo => ({
197
+ path: pathNorm(changedPath),
153
198
  event: evt as FsWatcherEvent,
154
199
  }),
155
200
  );