@e-mc/watch 0.10.5 → 0.11.0
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/LICENSE +1 -1
- package/README.md +12 -9
- package/filegroup/index.js +1 -1
- package/index.js +57 -62
- package/package.json +4 -4
package/LICENSE
CHANGED
|
@@ -8,4 +8,4 @@ Redistribution and use in source and binary forms, with or without modification,
|
|
|
8
8
|
|
|
9
9
|
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
10
10
|
|
|
11
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
11
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @e-mc/watch
|
|
2
2
|
|
|
3
|
-
* NodeJS 16
|
|
4
|
-
*
|
|
3
|
+
* NodeJS 16 LTS
|
|
4
|
+
* ES2021
|
|
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.
|
|
12
|
+
* [View Source](https://www.unpkg.com/@e-mc/types@0.11.0/lib/index.d.ts)
|
|
13
13
|
|
|
14
14
|
```typescript
|
|
15
15
|
import type { IFileManager, ModuleConstructor } from "./index";
|
|
@@ -41,6 +41,8 @@ interface IWatch extends IClient<IFileManager, WatchModule, ModifiedPostFinalize
|
|
|
41
41
|
get port(): number;
|
|
42
42
|
set securePort(value);
|
|
43
43
|
get securePort(): number;
|
|
44
|
+
set host(value);
|
|
45
|
+
get host(): IFileManager | null;
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
interface WatchConstructor extends ModuleConstructor {
|
|
@@ -49,6 +51,7 @@ interface WatchConstructor extends ModuleConstructor {
|
|
|
49
51
|
shutdown(): void;
|
|
50
52
|
setTimeout(value: number | string): void;
|
|
51
53
|
checkTimeout(client: ws): boolean;
|
|
54
|
+
isConnectionError(err: unknown): boolean;
|
|
52
55
|
readonly prototype: IWatch;
|
|
53
56
|
new(module?: WatchModule): IWatch;
|
|
54
57
|
}
|
|
@@ -106,14 +109,14 @@ instance.start(assets, { disk_read: ["/path/workspace/output/**"] });
|
|
|
106
109
|
|
|
107
110
|
## References
|
|
108
111
|
|
|
109
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
110
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
111
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
112
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
113
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
112
|
+
- https://www.unpkg.com/@e-mc/types@0.11.0/lib/asset.d.ts
|
|
113
|
+
- https://www.unpkg.com/@e-mc/types@0.11.0/lib/core.d.ts
|
|
114
|
+
- https://www.unpkg.com/@e-mc/types@0.11.0/lib/filemanager.d.ts
|
|
115
|
+
- https://www.unpkg.com/@e-mc/types@0.11.0/lib/settings.d.ts
|
|
116
|
+
- https://www.unpkg.com/@e-mc/types@0.11.0/lib/watch.d.ts
|
|
114
117
|
|
|
115
118
|
* https://www.npmjs.com/package/@types/ws
|
|
116
119
|
|
|
117
120
|
## LICENSE
|
|
118
121
|
|
|
119
|
-
BSD 3-Clause
|
|
122
|
+
BSD 3-Clause
|
package/filegroup/index.js
CHANGED
package/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
3
|
-
const path = require("path");
|
|
4
|
-
const fs = require("fs");
|
|
5
|
-
const https = require("https");
|
|
3
|
+
const path = require("node:path");
|
|
4
|
+
const fs = require("node:fs");
|
|
5
|
+
const https = require("node:https");
|
|
6
6
|
const ws = require("ws");
|
|
7
7
|
const pm = require("picomatch");
|
|
8
8
|
const types_1 = require("@e-mc/types");
|
|
@@ -25,15 +25,6 @@ const DISK_MAP = new Map();
|
|
|
25
25
|
const PORT_MAP = new Map();
|
|
26
26
|
const SECURE_MAP = new Map();
|
|
27
27
|
let STATE_MAP = new WeakSet();
|
|
28
|
-
function isConnectionTimeout(err) {
|
|
29
|
-
switch (err instanceof Error && err.code) {
|
|
30
|
-
case 'ETIMEDOUT':
|
|
31
|
-
case 'ECONNRESET':
|
|
32
|
-
return true;
|
|
33
|
-
default:
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
28
|
function abortTimeout(group) {
|
|
38
29
|
group.timeout.aborted = true;
|
|
39
30
|
const watcher = group.watcher;
|
|
@@ -84,11 +75,11 @@ function fatalError(instance, map, target, err) {
|
|
|
84
75
|
abortTimeout(target);
|
|
85
76
|
instance.writeFail(["Unable to watch file", uri], err, 16);
|
|
86
77
|
}
|
|
87
|
-
function getErrorMessage(item, status
|
|
78
|
+
function getErrorMessage(item, status) {
|
|
88
79
|
switch (status) {
|
|
89
80
|
case 1:
|
|
90
|
-
if ((0, types_1.existsFlag)(item
|
|
91
|
-
return
|
|
81
|
+
if ((0, types_1.existsFlag)(item)) {
|
|
82
|
+
return;
|
|
92
83
|
}
|
|
93
84
|
return "ETag not supported";
|
|
94
85
|
case 2:
|
|
@@ -212,6 +203,9 @@ class Watch extends core_1.Client {
|
|
|
212
203
|
filegroup_1.CONNECTION_TIMEOUT = Math.min(value, core_1.Client.MAX_TIMEOUT);
|
|
213
204
|
}
|
|
214
205
|
}
|
|
206
|
+
static isConnectionError(err) {
|
|
207
|
+
return (0, util_1.checkRetryable)(err);
|
|
208
|
+
}
|
|
215
209
|
init(config) {
|
|
216
210
|
const { interval, port, secure } = this.module;
|
|
217
211
|
if (secure) {
|
|
@@ -234,7 +228,7 @@ class Watch extends core_1.Client {
|
|
|
234
228
|
const settings = this.getUserSettings();
|
|
235
229
|
const destMap = Object.create(null);
|
|
236
230
|
for (const item of assets) {
|
|
237
|
-
if (!(0, types_1.ignoreFlag)(item
|
|
231
|
+
if (!(0, types_1.ignoreFlag)(item)) {
|
|
238
232
|
const { bundleId, uri, localUri } = item;
|
|
239
233
|
if (!(0, types_1.isEmpty)(bundleId)) {
|
|
240
234
|
(destMap[':' + bundleId] ||= []).push(item);
|
|
@@ -264,20 +258,19 @@ class Watch extends core_1.Client {
|
|
|
264
258
|
const watch = items[i].watch;
|
|
265
259
|
if ((0, types_1.isObject)(watch)) {
|
|
266
260
|
watch.assets?.forEach(other => {
|
|
267
|
-
if (items.includes(other)) {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
other.
|
|
261
|
+
if (!items.includes(other)) {
|
|
262
|
+
if ((0, types_1.watchFlag)(other)) {
|
|
263
|
+
if (!other.watch) {
|
|
264
|
+
other = filegroup_1.cloneAsset(other);
|
|
265
|
+
other.watch = { ...watch };
|
|
266
|
+
}
|
|
267
|
+
other.flags &= ~1;
|
|
268
|
+
other.invalid = undefined;
|
|
269
|
+
items.push(other);
|
|
270
|
+
}
|
|
271
|
+
else if (!related.includes(other)) {
|
|
272
|
+
related.push(other);
|
|
274
273
|
}
|
|
275
|
-
other.flags &= ~1;
|
|
276
|
-
other.invalid = undefined;
|
|
277
|
-
items.push(other);
|
|
278
|
-
}
|
|
279
|
-
else if (!related.includes(other)) {
|
|
280
|
-
related.push(other);
|
|
281
274
|
}
|
|
282
275
|
});
|
|
283
276
|
}
|
|
@@ -390,10 +383,10 @@ class Watch extends core_1.Client {
|
|
|
390
383
|
}
|
|
391
384
|
const current = data.get(dest)?.value;
|
|
392
385
|
if (current && !current.expired) {
|
|
393
|
-
let reset;
|
|
386
|
+
let reset = false;
|
|
394
387
|
if (id) {
|
|
395
388
|
const sockets = current.sockets;
|
|
396
|
-
for (let i = 0, active; i < sockets.length; ++i) {
|
|
389
|
+
for (let i = 0, active = false; i < sockets.length; ++i) {
|
|
397
390
|
const socket = sockets[i];
|
|
398
391
|
if (socket.id === id) {
|
|
399
392
|
if (active) {
|
|
@@ -449,8 +442,9 @@ class Watch extends core_1.Client {
|
|
|
449
442
|
if (!group.etag && !group.lastModified) {
|
|
450
443
|
return 1;
|
|
451
444
|
}
|
|
452
|
-
|
|
453
|
-
|
|
445
|
+
const pre = checkPreceding(HTTP_MAP);
|
|
446
|
+
if (pre !== undefined) {
|
|
447
|
+
return pre;
|
|
454
448
|
}
|
|
455
449
|
const url = group.url ||= new URL(uri);
|
|
456
450
|
const request = this.host?.Request || new request_1();
|
|
@@ -485,20 +479,8 @@ class Watch extends core_1.Client {
|
|
|
485
479
|
aborted = true;
|
|
486
480
|
}
|
|
487
481
|
else if (value.etag) {
|
|
488
|
-
if (etag) {
|
|
489
|
-
|
|
490
|
-
value.etag = etag;
|
|
491
|
-
if (value.started) {
|
|
492
|
-
void this.modified(value).then(result => {
|
|
493
|
-
wasAborted(result, value);
|
|
494
|
-
});
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
else if (value.lastModified && lastModified) {
|
|
500
|
-
if (lastModified !== value.lastModified) {
|
|
501
|
-
value.lastModified = lastModified;
|
|
482
|
+
if (etag && etag !== value.etag) {
|
|
483
|
+
value.etag = etag;
|
|
502
484
|
if (value.started) {
|
|
503
485
|
void this.modified(value).then(result => {
|
|
504
486
|
wasAborted(result, value);
|
|
@@ -506,6 +488,14 @@ class Watch extends core_1.Client {
|
|
|
506
488
|
}
|
|
507
489
|
}
|
|
508
490
|
}
|
|
491
|
+
else if (lastModified && value.lastModified && lastModified !== value.lastModified) {
|
|
492
|
+
value.lastModified = lastModified;
|
|
493
|
+
if (value.started) {
|
|
494
|
+
void this.modified(value).then(result => {
|
|
495
|
+
wasAborted(result, value);
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
}
|
|
509
499
|
}
|
|
510
500
|
if (aborted) {
|
|
511
501
|
map.delete(destUrl);
|
|
@@ -527,18 +517,20 @@ class Watch extends core_1.Client {
|
|
|
527
517
|
resolve();
|
|
528
518
|
})
|
|
529
519
|
.on('error', err => {
|
|
530
|
-
if (!timeout.aborted && !(
|
|
520
|
+
if (!timeout.aborted && !(Watch.isConnectionError(err) && ++timeout.retries <= 10)) {
|
|
531
521
|
reject(err);
|
|
532
|
-
return;
|
|
533
522
|
}
|
|
534
|
-
|
|
523
|
+
else {
|
|
524
|
+
resolve();
|
|
525
|
+
}
|
|
535
526
|
})
|
|
536
527
|
.on('timeout', () => {
|
|
537
528
|
if (!timeout.aborted && ++timeout.retries > 10) {
|
|
538
529
|
reject((0, types_1.errorMessage)(408, "HTTP request timeout"));
|
|
539
|
-
return;
|
|
540
530
|
}
|
|
541
|
-
|
|
531
|
+
else {
|
|
532
|
+
resolve();
|
|
533
|
+
}
|
|
542
534
|
});
|
|
543
535
|
})
|
|
544
536
|
.then(() => {
|
|
@@ -564,8 +556,9 @@ class Watch extends core_1.Client {
|
|
|
564
556
|
HTTP_MAP.set(uri, new Map([[dest, target]]));
|
|
565
557
|
}
|
|
566
558
|
else if (esm || path.isAbsolute(uri = core_1.Client.resolveFile(uri)) && this.canRead(uri, { hostPermissionOnly: !!this.host })) {
|
|
567
|
-
|
|
568
|
-
|
|
559
|
+
const pre = checkPreceding(DISK_MAP);
|
|
560
|
+
if (pre !== undefined) {
|
|
561
|
+
return pre;
|
|
569
562
|
}
|
|
570
563
|
let ptime = 0;
|
|
571
564
|
target.watcher = fs.watch(uri, (event, filename) => {
|
|
@@ -622,7 +615,7 @@ class Watch extends core_1.Client {
|
|
|
622
615
|
}
|
|
623
616
|
return 0;
|
|
624
617
|
};
|
|
625
|
-
if ((0, types_1.isArray)(sourceFiles) && sourceFiles.
|
|
618
|
+
if ((0, types_1.isArray)(sourceFiles) && (sourceFiles = sourceFiles.filter(file => this.canRead(file, { hostPermissionOnly: !!this.host }))).length > 0) {
|
|
626
619
|
let index = 0;
|
|
627
620
|
for (const file of new Set(sourceFiles)) {
|
|
628
621
|
if (index++ > 0) {
|
|
@@ -639,11 +632,13 @@ class Watch extends core_1.Client {
|
|
|
639
632
|
else {
|
|
640
633
|
continue;
|
|
641
634
|
}
|
|
642
|
-
if (status
|
|
643
|
-
|
|
635
|
+
if (status > 0) {
|
|
636
|
+
if (message ||= getErrorMessage(item, status)) {
|
|
637
|
+
this.formatFail((16 | (status === 2 ? 8192 : 0)), 'WATCH', ["Unable to watch file", watched && path.basename(watched)], (0, types_1.errorValue)(message, watched), { fatal: false });
|
|
638
|
+
}
|
|
644
639
|
}
|
|
645
|
-
else
|
|
646
|
-
this.
|
|
640
|
+
else {
|
|
641
|
+
this.formatMessage(16, 'WATCH', ['Start', interval + 'ms ' + (expires ? formatDate(expires) : 'never')], watched, { titleColor: 'blue' });
|
|
647
642
|
}
|
|
648
643
|
}
|
|
649
644
|
}
|
|
@@ -822,7 +817,7 @@ class Watch extends core_1.Client {
|
|
|
822
817
|
return this._assets;
|
|
823
818
|
}
|
|
824
819
|
set interval(value) {
|
|
825
|
-
if (
|
|
820
|
+
if (value > 0) {
|
|
826
821
|
this[kInterval] = value;
|
|
827
822
|
}
|
|
828
823
|
}
|
|
@@ -830,7 +825,7 @@ class Watch extends core_1.Client {
|
|
|
830
825
|
return this[kInterval];
|
|
831
826
|
}
|
|
832
827
|
set port(value) {
|
|
833
|
-
if (
|
|
828
|
+
if (value > 0) {
|
|
834
829
|
this[kPort] = value;
|
|
835
830
|
}
|
|
836
831
|
}
|
|
@@ -838,7 +833,7 @@ class Watch extends core_1.Client {
|
|
|
838
833
|
return this[kPort];
|
|
839
834
|
}
|
|
840
835
|
set securePort(value) {
|
|
841
|
-
if (
|
|
836
|
+
if (value > 0) {
|
|
842
837
|
this[kSecurePort] = value;
|
|
843
838
|
}
|
|
844
839
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@e-mc/watch",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
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.
|
|
24
|
-
"@e-mc/request": "0.
|
|
25
|
-
"@e-mc/types": "0.
|
|
23
|
+
"@e-mc/core": "0.11.0",
|
|
24
|
+
"@e-mc/request": "0.11.0",
|
|
25
|
+
"@e-mc/types": "0.11.0",
|
|
26
26
|
"picomatch": "^4.0.2",
|
|
27
27
|
"ws": "^8.18.0"
|
|
28
28
|
}
|