@e-mc/watch 0.11.8 → 0.12.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.
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # @e-mc/watch
2
2
 
3
- * NodeJS 16 LTS
4
- * ES2021
3
+ * NodeJS 18
4
+ * ES2022
5
5
 
6
6
  ## General Usage
7
7
 
@@ -9,7 +9,7 @@
9
9
 
10
10
  ## Interface
11
11
 
12
- * [View Source](https://www.unpkg.com/@e-mc/types@0.11.8/lib/index.d.ts)
12
+ * [View Source](https://www.unpkg.com/@e-mc/types@0.12.1/lib/index.d.ts)
13
13
 
14
14
  ```typescript
15
15
  import type { IFileManager, ModuleConstructor } from "./index";
@@ -31,6 +31,7 @@ interface IWatch extends IClient<IFileManager, WatchModule, ModifiedPostFinalize
31
31
  setSSLKey(value: string): boolean;
32
32
  setSSLCert(value: string): boolean;
33
33
  hasSecureProtocol(): boolean;
34
+ getRecursiveFiles(watch: IFileGroup<ExternalAsset>): [string, string[]][];
34
35
  whenModified?(assets: ExternalAsset[], postFinalize: PostFinalizeCallback): IFileManager;
35
36
  whenModified?(assets: ExternalAsset[], sanitize?: boolean, postFinalize?: PostFinalizeCallback): IFileManager;
36
37
  set assets(value: ExternalAsset[]);
@@ -109,11 +110,11 @@ instance.start(assets, { disk_read: ["/path/workspace/output/**"] });
109
110
 
110
111
  ## References
111
112
 
112
- - https://www.unpkg.com/@e-mc/types@0.11.8/lib/asset.d.ts
113
- - https://www.unpkg.com/@e-mc/types@0.11.8/lib/core.d.ts
114
- - https://www.unpkg.com/@e-mc/types@0.11.8/lib/filemanager.d.ts
115
- - https://www.unpkg.com/@e-mc/types@0.11.8/lib/settings.d.ts
116
- - https://www.unpkg.com/@e-mc/types@0.11.8/lib/watch.d.ts
113
+ - https://www.unpkg.com/@e-mc/types@0.12.1/lib/asset.d.ts
114
+ - https://www.unpkg.com/@e-mc/types@0.12.1/lib/core.d.ts
115
+ - https://www.unpkg.com/@e-mc/types@0.12.1/lib/filemanager.d.ts
116
+ - https://www.unpkg.com/@e-mc/types@0.12.1/lib/settings.d.ts
117
+ - https://www.unpkg.com/@e-mc/types@0.12.1/lib/watch.d.ts
117
118
 
118
119
  * https://www.npmjs.com/package/@types/ws
119
120
 
@@ -1,19 +1,13 @@
1
1
  "use strict";
2
- var _a, _b, _c, _d, _e, _f;
3
2
  const util = require("node:util");
3
+ const pm = require("picomatch");
4
4
  const ws = require("ws");
5
5
  const types_1 = require("@e-mc/types");
6
6
  const core_1 = require("@e-mc/core");
7
- const kServer = Symbol('server');
8
- const kStarted = Symbol('started');
9
- const kPaused = Symbol('paused');
10
- const kAssets = Symbol('assets');
11
- const kSockets = Symbol('sockets');
12
- const kStartTime = Symbol('startTime');
13
- const kUri = Symbol('uri');
14
- const kEtag = Symbol('etag');
15
- const kLastModified = Symbol('lastModified');
16
7
  class SocketRequest {
8
+ expires;
9
+ socketId;
10
+ id;
17
11
  constructor(expires, socketId, id = '') {
18
12
  this.expires = expires;
19
13
  this.socketId = socketId;
@@ -25,6 +19,8 @@ class SocketRequest {
25
19
  }
26
20
  }
27
21
  class FileGroup extends core_1.AbortComponent {
22
+ static CONNECTION_TIMEOUT = 10 * 60000;
23
+ static CLIENT_SESSION = new Map();
28
24
  static checkTimeout(client) {
29
25
  if (client.readyState !== ws.OPEN) {
30
26
  return false;
@@ -44,34 +40,45 @@ class FileGroup extends core_1.AbortComponent {
44
40
  const watch = file.watch;
45
41
  return (0, types_1.cloneObject)(file, (0, types_1.isPlainObject)(watch) && (0, types_1.isArray)(watch.assets) ? new WeakSet([watch.assets]) : true);
46
42
  }
47
- constructor(uri, assets, startTime, abortable) {
43
+ captured = false;
44
+ port = NaN;
45
+ secure = false;
46
+ hot = false;
47
+ always = false;
48
+ url;
49
+ document;
50
+ main;
51
+ bundleMain;
52
+ sourceFiles;
53
+ _related = [];
54
+ _abortable;
55
+ #server = null;
56
+ #started = false;
57
+ #paused = false;
58
+ #etag = '';
59
+ #lastModified = '';
60
+ #startTime;
61
+ #sockets = [];
62
+ #uri;
63
+ #assets;
64
+ #recursive;
65
+ constructor(uri, assets, startTime, abortable, recursive) {
48
66
  super();
49
- this.captured = false;
50
- this.port = NaN;
51
- this.secure = false;
52
- this.hot = false;
53
- this.always = false;
54
- this._related = [];
55
- this._abortable = false;
56
- this[_a] = null;
57
- this[_b] = false;
58
- this[_c] = false;
59
- this[_d] = '';
60
- this[_e] = '';
61
- this[_f] = [];
62
- this[kUri] = uri;
63
- this[kAssets] = assets;
67
+ this.#uri = uri;
68
+ this.#assets = assets;
64
69
  if (typeof startTime === 'boolean') {
70
+ recursive = abortable;
65
71
  abortable = startTime;
66
72
  startTime = undefined;
67
73
  }
68
- if (typeof abortable === 'boolean') {
69
- this._abortable = abortable;
74
+ this._abortable = abortable === true;
75
+ this.#startTime = startTime || Date.now();
76
+ if (recursive && (0, types_1.supported)(19, 1)) {
77
+ this.#recursive = (Array.isArray(recursive) ? recursive : typeof recursive === 'string' ? [recursive] : []).map(value => core_1.Permission.toPosix(value));
70
78
  }
71
- this[kStartTime] = startTime || Date.now();
72
79
  }
73
80
  connection(server, port = 0, secure = false) {
74
- this[kServer] = server;
81
+ this.#server = server;
75
82
  if (port > 0) {
76
83
  this.port = port;
77
84
  }
@@ -120,32 +127,38 @@ class FileGroup extends core_1.AbortComponent {
120
127
  return result;
121
128
  }
122
129
  pause() {
123
- this[kPaused] = true;
130
+ this.#paused = true;
124
131
  }
125
132
  resume() {
126
- this[kPaused] = false;
133
+ this.#paused = false;
127
134
  }
128
135
  reset() {
129
136
  super.reset();
130
137
  this.captured = false;
131
138
  }
139
+ matchRecursive(value) {
140
+ if (!this.recursive) {
141
+ return false;
142
+ }
143
+ return this.#recursive?.length ? pm.isMatch(core_1.Permission.toPosix(value), this.#recursive, { nocase: process.platform === 'win32' }) : true;
144
+ }
132
145
  get server() {
133
- return this[kServer];
146
+ return this.#server;
134
147
  }
135
148
  get uri() {
136
- return this[kUri];
149
+ return this.#uri;
137
150
  }
138
151
  get sockets() {
139
- return this[kSockets];
152
+ return this.#sockets;
140
153
  }
141
154
  get startTime() {
142
- return this[kStartTime];
155
+ return this.#startTime;
143
156
  }
144
157
  get started() {
145
- return this[kStarted] ||= Date.now() >= this.startTime;
158
+ return this.#started ||= Date.now() >= this.startTime;
146
159
  }
147
160
  get assets() {
148
- return this[kAssets];
161
+ return this.#assets;
149
162
  }
150
163
  set related(value) {
151
164
  this._related = value.map(item => {
@@ -170,19 +183,19 @@ class FileGroup extends core_1.AbortComponent {
170
183
  }
171
184
  set etag(value) {
172
185
  if (typeof value === 'string') {
173
- this[kEtag] = value;
186
+ this.#etag = value;
174
187
  }
175
188
  }
176
189
  get etag() {
177
- return this[kEtag];
190
+ return this.#etag;
178
191
  }
179
192
  set lastModified(value) {
180
193
  if (typeof value === 'string') {
181
- this[kLastModified] = value;
194
+ this.#lastModified = value;
182
195
  }
183
196
  }
184
197
  get lastModified() {
185
- return this[kEtag] ? '' : this[kLastModified];
198
+ return this.#etag ? '' : this.#lastModified;
186
199
  }
187
200
  get expires() {
188
201
  let result = 0;
@@ -198,13 +211,15 @@ class FileGroup extends core_1.AbortComponent {
198
211
  return this.sockets.every(item => item.expired);
199
212
  }
200
213
  get paused() {
201
- return this[kPaused];
214
+ return this.#paused;
202
215
  }
203
216
  get abortable() {
204
217
  return this._abortable;
205
218
  }
219
+ get recursive() {
220
+ if (this.#recursive) {
221
+ return true;
222
+ }
223
+ }
206
224
  }
207
- _a = kServer, _b = kStarted, _c = kPaused, _d = kEtag, _e = kLastModified, _f = kSockets;
208
- FileGroup.CONNECTION_TIMEOUT = 10 * 60000;
209
- FileGroup.CLIENT_SESSION = new Map();
210
225
  module.exports = FileGroup;
package/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  "use strict";
2
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
3
2
  const path = require("node:path");
4
3
  const fs = require("node:fs");
5
4
  const https = require("node:https");
@@ -10,16 +9,7 @@ const core_1 = require("@e-mc/core");
10
9
  const util_1 = require("@e-mc/request/util");
11
10
  const request_1 = require("@e-mc/request");
12
11
  const filegroup_1 = require("@e-mc/watch/filegroup");
13
- const kInterval = Symbol('interval');
14
- const kPort = Symbol('port');
15
- const kSecurePort = Symbol('securePort');
16
- const kCa = Symbol('ca');
17
- const kTlsKey = Symbol('tlsKey');
18
- const kTlsCert = Symbol('tlsCert');
19
- const kTlsVersion = Symbol('tlsVersion');
20
- const kTlsPassphrase = Symbol('tlsPassphrase');
21
- const kTlsConfig = Symbol('tlsConfig');
22
- const kCiphers = Symbol('ciphers');
12
+ const kWatch = Symbol.for('watch:constructor');
23
13
  const HTTP_MAP = new Map();
24
14
  const DISK_MAP = new Map();
25
15
  const PORT_MAP = new Map();
@@ -69,12 +59,6 @@ function wasAborted(result, current) {
69
59
  current.abort();
70
60
  }
71
61
  }
72
- function fatalError(instance, map, target, err) {
73
- const uri = target.value.uri;
74
- map.delete(uri);
75
- abortTimeout(target);
76
- instance.writeFail(["Unable to watch file", uri], err, 16);
77
- }
78
62
  function getErrorMessage(item, status) {
79
63
  switch (status) {
80
64
  case 1:
@@ -93,24 +77,8 @@ function getErrorMessage(item, status) {
93
77
  const isMap = (value) => value ? value.size > 0 : false;
94
78
  const formatDate = (value) => new Date(value).toLocaleString().replace(/\/20\d+, /, '@').replace(/:\d+ (AM|PM)$/, (...match) => match[1]);
95
79
  class Watch extends core_1.Client {
96
- constructor() {
97
- super(...arguments);
98
- this.connectTimeout = Watch.PROCESS_TIMEOUT;
99
- this._moduleName = 'watch';
100
- this._assets = [];
101
- this._extensions = [];
102
- this._hostEvents = [];
103
- this[_a] = types_1.THRESHOLD.WATCH_INTERVAL;
104
- this[_b] = 80;
105
- this[_c] = 443;
106
- this[_d] = '';
107
- this[_e] = '';
108
- this[_f] = '';
109
- this[_g] = '';
110
- this[_h] = '';
111
- this[_j] = undefined;
112
- this[_k] = undefined;
113
- }
80
+ static [kWatch] = true;
81
+ static PROCESS_TIMEOUT = 5 * 1000;
114
82
  static createServer(port, secure, active) {
115
83
  if (typeof secure === 'boolean') {
116
84
  active = secure;
@@ -206,6 +174,24 @@ class Watch extends core_1.Client {
206
174
  static isConnectionError(err) {
207
175
  return (0, util_1.checkRetryable)(err);
208
176
  }
177
+ connectTimeout = Watch.PROCESS_TIMEOUT;
178
+ _moduleName = 'watch';
179
+ _assets = [];
180
+ _extensions = [];
181
+ _recursiveMap = Object.create(null);
182
+ _hostEvents = [];
183
+ #internal = types_1.THRESHOLD.WATCH_INTERVAL;
184
+ #port = 80;
185
+ #securePort = 443;
186
+ #ca = '';
187
+ #ciphers = '';
188
+ #tlsKey = '';
189
+ #tlsCert = '';
190
+ #tlsPassphrase = '';
191
+ #tlsVersion = undefined;
192
+ #tlsConfig = undefined;
193
+ #recursiveTime = new WeakMap();
194
+ whenModified;
209
195
  init(config) {
210
196
  const { interval, port, secure } = this.module;
211
197
  if (secure) {
@@ -280,7 +266,7 @@ class Watch extends core_1.Client {
280
266
  if (!watch) {
281
267
  continue;
282
268
  }
283
- let expires = 0, status = 0, wss = null, main, id, socketId, port, secure, hot, always, watched, message;
269
+ let expires = 0, status = 0, wss = null, main, id, socketId, port, secure, hot, always, recursive, watched, message;
284
270
  if (watch === true && settings) {
285
271
  const { uri, localUri, mimeType } = item;
286
272
  watch = false;
@@ -293,7 +279,7 @@ class Watch extends core_1.Client {
293
279
  }
294
280
  if (!watch && localUri && !(watch = settings[localUri])) {
295
281
  const pathname = core_1.Client.PLATFORM_WIN32 ? core_1.Client.toPosix(localUri) : localUri;
296
- const options = core_1.Client.PLATFORM_WIN32 ? { nocase: true, windows: true, posixSlashes: true } : {};
282
+ const options = core_1.Client.PLATFORM_WIN32 ? { nocase: true, matchBase: true, windows: true, posixSlashes: true } : { matchBase: true };
297
283
  for (const pattern in settings) {
298
284
  if ((0, types_1.hasGlob)(pattern) && pm.isMatch(pathname, pattern, options) && (watch = settings[pattern])) {
299
285
  break;
@@ -310,27 +296,30 @@ class Watch extends core_1.Client {
310
296
  }
311
297
  let startTime = Date.now();
312
298
  if ((0, types_1.isPlainObject)(watch)) {
313
- const { start, expires: expired, reload } = watch;
299
+ const reload = watch.reload;
314
300
  id = watch.id;
315
301
  if (watch.main) {
316
302
  main = item;
317
303
  }
318
- if (start) {
319
- const offset = (0, types_1.parseTime)(start);
304
+ if (watch.start) {
305
+ const offset = (0, types_1.parseTime)(watch.start);
320
306
  if (offset > 0) {
321
307
  startTime += offset;
322
308
  }
323
309
  }
324
- if (expired) {
325
- expires = (0, types_1.parseExpires)(expired, startTime);
310
+ if (watch.expires) {
311
+ expires = (0, types_1.parseExpires)(watch.expires, startTime);
312
+ }
313
+ if (watch.recursive) {
314
+ recursive = true;
326
315
  }
327
316
  if (reload && (socketId = reload.socketId)) {
328
317
  ({ port, module: hot, always } = reload);
329
318
  if (reload.secure) {
330
- const key = this[kTlsKey];
331
- const cert = this[kTlsCert];
319
+ const key = this.#tlsKey;
320
+ const cert = this.#tlsCert;
332
321
  if (key && cert) {
333
- wss = Watch.createServer(port ||= this.securePort, { ca: this[kCa], key, cert, passphrase: this[kTlsPassphrase], version: this[kTlsVersion], ciphers: this[kCiphers], config: this[kTlsConfig] });
322
+ wss = Watch.createServer(port ||= this.securePort, { ca: this.#ca, key, cert, passphrase: this.#tlsPassphrase, version: this.#tlsVersion, ciphers: this.#ciphers, config: this.#tlsConfig });
334
323
  }
335
324
  secure = true;
336
325
  }
@@ -350,7 +339,7 @@ class Watch extends core_1.Client {
350
339
  }
351
340
  const interval = getInterval(item) || watchInterval || this.interval;
352
341
  const watching = (uri, esm) => {
353
- const group = new filegroup_1(uri, main ? assets : items, startTime, this.willAbort("(watch)"));
342
+ const group = new filegroup_1(uri, main ? assets : items, startTime, this.willAbort("(watch)"), recursive);
354
343
  group.add(expires, socketId, id);
355
344
  if (main) {
356
345
  group.main = main;
@@ -551,7 +540,7 @@ class Watch extends core_1.Client {
551
540
  }
552
541
  })
553
542
  .catch((err) => {
554
- fatalError(this, HTTP_MAP, target, err);
543
+ this.#sendFatalError(err, HTTP_MAP, target);
555
544
  client?.destroy();
556
545
  });
557
546
  }).call(this);
@@ -559,13 +548,34 @@ class Watch extends core_1.Client {
559
548
  }
560
549
  else if (esm || path.isAbsolute(uri = core_1.Client.resolveFile(uri)) && this.canRead(uri, { hostPermissionOnly: !!this.host })) {
561
550
  const pre = checkPreceding(DISK_MAP);
551
+ const options = {};
552
+ let src = uri;
553
+ if (group.matchRecursive(uri)) {
554
+ src = path.dirname(uri);
555
+ for (const pathname in this._recursiveMap) {
556
+ if (src === pathname || src.startsWith(pathname + path.sep)) {
557
+ const parent = this._recursiveMap[pathname].get(group);
558
+ if (parent) {
559
+ parent.push(uri);
560
+ }
561
+ else {
562
+ (this._recursiveMap[pathname] = new Map()).set(group, [uri]);
563
+ }
564
+ return 4;
565
+ }
566
+ }
567
+ if (pre === undefined) {
568
+ (this._recursiveMap[src] = new Map()).set(group, [uri]);
569
+ options.recursive = true;
570
+ }
571
+ }
562
572
  if (pre !== undefined) {
563
573
  return pre;
564
574
  }
565
575
  let ptime = 0;
566
- target.watcher = fs.watch(uri, (event, filename) => {
576
+ target.watcher = fs.watch(src, options, (event, filename) => {
567
577
  if (this.aborted || group.aborted) {
568
- fatalError(this, DISK_MAP, target, (0, types_1.createAbortError)());
578
+ this.#sendFatalError((0, types_1.createAbortError)(), DISK_MAP, target);
569
579
  return;
570
580
  }
571
581
  const map = DISK_MAP.get(uri);
@@ -575,6 +585,11 @@ class Watch extends core_1.Client {
575
585
  try {
576
586
  const mtime = Math.floor(fs.statSync(uri).mtimeMs);
577
587
  if (mtime > ptime) {
588
+ ptime = mtime + types_1.THRESHOLD.WATCH_CHANGE;
589
+ if (filename && options.recursive && !group.matchRecursive(path.join(src, filename))) {
590
+ this.formatMessage(16, 'WATCH', ['File modification ignored', 'recursive'], path.join(src, filename), { titleColor: 'yellow' });
591
+ return;
592
+ }
578
593
  for (const [key, input] of map) {
579
594
  const value = input.value;
580
595
  if (value.expired) {
@@ -595,7 +610,6 @@ class Watch extends core_1.Client {
595
610
  });
596
611
  }
597
612
  }
598
- ptime = mtime + types_1.THRESHOLD.WATCH_CHANGE;
599
613
  }
600
614
  break;
601
615
  }
@@ -604,6 +618,9 @@ class Watch extends core_1.Client {
604
618
  }
605
619
  }
606
620
  case 'rename':
621
+ if (event === 'rename' && group.recursive) {
622
+ return;
623
+ }
607
624
  map?.clear();
608
625
  this.watchExpired(DISK_MAP, group, event === 'rename' ? 'File renamed: ' + filename : undefined);
609
626
  abortTimeout(target);
@@ -619,11 +636,11 @@ class Watch extends core_1.Client {
619
636
  };
620
637
  if ((0, types_1.isArray)(sourceFiles) && (sourceFiles = sourceFiles.filter(file => this.canRead(file, { hostPermissionOnly: !!this.host }))).length > 0) {
621
638
  let index = 0;
622
- for (const file of new Set(sourceFiles)) {
639
+ for (const file of Array.from(new Set(sourceFiles)).sort((a, b) => a.length - b.length)) {
623
640
  if (index++ > 0) {
624
641
  watching(file, true);
625
642
  }
626
- else if ((status = watching(watched = file, true)) > 0) {
643
+ else if ((status = watching(watched = file, true)) > 0 && status < 4) {
627
644
  break;
628
645
  }
629
646
  }
@@ -634,6 +651,9 @@ class Watch extends core_1.Client {
634
651
  else {
635
652
  continue;
636
653
  }
654
+ if (status === 4) {
655
+ continue;
656
+ }
637
657
  if (status > 0) {
638
658
  if (message ||= getErrorMessage(item, status)) {
639
659
  this.formatFail((16 | (status === 2 ? 8192 : 0)), 'WATCH', ["Unable to watch file", watched && path.basename(watched)], (0, types_1.errorValue)(message, watched), { fatal: false });
@@ -646,7 +666,18 @@ class Watch extends core_1.Client {
646
666
  }
647
667
  }
648
668
  async modified(watch) {
649
- this.formatMessage(16, 'WATCH', "File modified", watch.uri, { ...core_1.Client.LOG_STYLE_WARN });
669
+ const recursive = this.getRecursiveFiles(watch);
670
+ let message = "File modified", uri = watch.uri;
671
+ if (recursive.length > 0) {
672
+ const time = this.#recursiveTime.get(watch) || 0;
673
+ if (time + types_1.THRESHOLD.WATCH_RECURSIVE_CHANGE >= Date.now()) {
674
+ return;
675
+ }
676
+ message = "Directory was modified";
677
+ uri = path.dirname(watch.uri);
678
+ this.#recursiveTime.set(watch, Date.now());
679
+ }
680
+ this.formatMessage(16, 'WATCH', message, uri, { ...core_1.Client.LOG_STYLE_WARN });
650
681
  const { host, assets } = this;
651
682
  let items, sanitize = false;
652
683
  if (watch.main) {
@@ -698,31 +729,32 @@ class Watch extends core_1.Client {
698
729
  catch {
699
730
  }
700
731
  }
701
- if (manager) {
702
- if (host && watch.document) {
703
- for (const { instance } of host.Document) {
704
- if (host.hasDocument(instance, watch.document)) {
705
- const result = instance.watchInit?.(watch, items, sanitize);
706
- if (result) {
707
- if ((0, types_1.isArray)(result.using)) {
708
- manager.using(...result.using);
709
- }
710
- if (Array.isArray(result.dataSource)) {
711
- const document = manager.find(instance.moduleName);
712
- if (document) {
713
- document.dataSource = result.dataSource;
714
- }
715
- }
732
+ if (!manager) {
733
+ return;
734
+ }
735
+ if (host && watch.document) {
736
+ for (const { instance } of host.Document) {
737
+ if (host.hasDocument(instance, watch.document)) {
738
+ const result = instance.watchInit?.(watch, items, sanitize);
739
+ if (result) {
740
+ if ((0, types_1.isArray)(result.using)) {
741
+ manager.using(...result.using);
716
742
  }
717
- const listener = instance.watchModified?.(watch, items);
718
- if (typeof listener === 'function') {
719
- manager.on('end', listener);
743
+ if (Array.isArray(result.dataSource)) {
744
+ const document = manager.find(instance.moduleName);
745
+ if (document) {
746
+ document.dataSource = result.dataSource;
747
+ }
720
748
  }
721
749
  }
750
+ const listener = instance.watchModified?.(watch, items, recursive);
751
+ if (typeof listener === 'function') {
752
+ manager.on('end', listener);
753
+ }
722
754
  }
723
755
  }
724
- return await manager.start();
725
756
  }
757
+ return await manager.start();
726
758
  }
727
759
  catch (err) {
728
760
  this.writeFail(["Unknown", watch.url?.pathname || path.basename(watch.uri)], err);
@@ -736,16 +768,16 @@ class Watch extends core_1.Client {
736
768
  this.setCA(ca);
737
769
  }
738
770
  if (request_1.isCert(key) || core_1.Client.isPath(key = path.resolve(key)) && this.canRead(key, { ownPermissionOnly: true })) {
739
- this[kTlsKey] = key;
771
+ this.#tlsKey = key;
740
772
  }
741
773
  if (request_1.isCert(cert) || core_1.Client.isPath(cert = path.resolve(cert)) && this.canRead(cert, { ownPermissionOnly: true })) {
742
- this[kTlsCert] = cert;
774
+ this.#tlsCert = cert;
743
775
  }
744
776
  if ((0, types_1.isString)(passphrase)) {
745
- this[kTlsPassphrase] = passphrase;
777
+ this.#tlsPassphrase = passphrase;
746
778
  }
747
779
  if ((0, types_1.isString)(ciphers)) {
748
- this[kCiphers] = ciphers;
780
+ this.#ciphers = ciphers;
749
781
  }
750
782
  if (!(0, types_1.isPlainObject)(config)) {
751
783
  config = undefined;
@@ -764,33 +796,45 @@ class Watch extends core_1.Client {
764
796
  version = undefined;
765
797
  break;
766
798
  }
767
- this[kTlsConfig] = config;
768
- this[kTlsVersion] = version;
799
+ this.#tlsConfig = config;
800
+ this.#tlsVersion = version;
769
801
  return this.hasSecureProtocol();
770
802
  }
771
803
  setCA(value) {
772
804
  if ((0, types_1.isString)(value) && core_1.Client.isPath(value = path.resolve(value = value.trim())) && this.canRead(value, { ownPermissionOnly: true })) {
773
- this[kCa] = value;
805
+ this.#ca = value;
774
806
  return true;
775
807
  }
776
808
  return false;
777
809
  }
778
810
  setSSLKey(value) {
779
- this[kTlsConfig] = { secureProtocol: 'SSLv23_method' };
780
- this[kTlsVersion] = undefined;
781
- return !!(this[kTlsKey] = request_1.readTLSKey(value, true));
811
+ this.#tlsConfig = { secureProtocol: 'SSLv23_method' };
812
+ this.#tlsVersion = undefined;
813
+ return !!(this.#tlsKey = request_1.readTLSKey(value, true));
782
814
  }
783
815
  setSSLCert(value) {
784
- return !!(this[kTlsCert] = request_1.readTLSCert(value, true));
816
+ return !!(this.#tlsCert = request_1.readTLSCert(value, true));
785
817
  }
786
818
  hasSecureProtocol() {
787
- return !!this[kTlsKey] && !!this[kTlsCert];
819
+ return !!this.#tlsKey && !!this.#tlsCert;
788
820
  }
789
821
  willAbort(value) {
790
822
  return this.host ? this.host.willAbort(value) : value === "(watch)";
791
823
  }
824
+ getRecursiveFiles(watch) {
825
+ const result = [];
826
+ if (watch.recursive) {
827
+ for (const pathname in this._recursiveMap) {
828
+ const files = this._recursiveMap[pathname].get(watch);
829
+ if (files) {
830
+ result.push([pathname, files]);
831
+ }
832
+ }
833
+ }
834
+ return result;
835
+ }
792
836
  watchExpired(map, target, message = "Expired") {
793
- this.formatMessage(16, 'WATCH', [message, target.startTime ? 'since ' + formatDate(target.startTime) : ''], target.uri, { titleColor: 'grey' });
837
+ this.formatMessage(16, 'WATCH', [message, target.startTime ? 'since ' + formatDate(target.startTime) : ''], this.getRecursiveFiles(target).length > 0 ? path.dirname(target.uri) : target.uri, { titleColor: 'grey' });
794
838
  const data = map.get(target.uri);
795
839
  if (!data?.size) {
796
840
  map.delete(target.uri);
@@ -798,6 +842,12 @@ class Watch extends core_1.Client {
798
842
  }
799
843
  return false;
800
844
  }
845
+ #sendFatalError(err, map, target) {
846
+ const uri = target.value.uri;
847
+ map.delete(uri);
848
+ abortTimeout(target);
849
+ this.writeFail(["Unable to watch file", uri], err, 16);
850
+ }
801
851
  set host(value) {
802
852
  super.host = value;
803
853
  if ((0, types_1.isArray)(value?.assets)) {
@@ -820,29 +870,27 @@ class Watch extends core_1.Client {
820
870
  }
821
871
  set interval(value) {
822
872
  if (value > 0) {
823
- this[kInterval] = value;
873
+ this.#internal = value;
824
874
  }
825
875
  }
826
876
  get interval() {
827
- return this[kInterval];
877
+ return this.#internal;
828
878
  }
829
879
  set port(value) {
830
880
  if (value > 0) {
831
- this[kPort] = value;
881
+ this.#port = value;
832
882
  }
833
883
  }
834
884
  get port() {
835
- return this[kPort];
885
+ return this.#port;
836
886
  }
837
887
  set securePort(value) {
838
888
  if (value > 0) {
839
- this[kSecurePort] = value;
889
+ this.#securePort = value;
840
890
  }
841
891
  }
842
892
  get securePort() {
843
- return this[kSecurePort];
893
+ return this.#securePort;
844
894
  }
845
895
  }
846
- _a = kInterval, _b = kPort, _c = kSecurePort, _d = kCa, _e = kCiphers, _f = kTlsKey, _g = kTlsCert, _h = kTlsPassphrase, _j = kTlsVersion, _k = kTlsConfig;
847
- Watch.PROCESS_TIMEOUT = 5 * 1000;
848
896
  module.exports = Watch;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@e-mc/watch",
3
- "version": "0.11.8",
3
+ "version": "0.12.1",
4
4
  "description": "Watch constructor for E-mc.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -20,9 +20,9 @@
20
20
  "license": "BSD-3-Clause",
21
21
  "homepage": "https://github.com/anpham6/e-mc#readme",
22
22
  "dependencies": {
23
- "@e-mc/core": "0.11.8",
24
- "@e-mc/request": "0.11.8",
25
- "@e-mc/types": "0.11.8",
23
+ "@e-mc/core": "0.12.1",
24
+ "@e-mc/request": "0.12.1",
25
+ "@e-mc/types": "0.12.1",
26
26
  "picomatch": "^4.0.2",
27
27
  "ws": "^8.18.1"
28
28
  }