@e-mc/watch 0.6.0 → 0.7.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/LICENSE +10 -10
- package/filegroup/index.d.ts +5 -5
- package/index.d.ts +4 -4
- package/index.js +29 -32
- package/package.json +6 -6
package/LICENSE
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
Copyright 2023 An Pham
|
|
2
|
-
|
|
3
|
-
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
4
|
-
|
|
5
|
-
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
6
|
-
|
|
7
|
-
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
8
|
-
|
|
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
|
-
|
|
1
|
+
Copyright 2023 An Pham
|
|
2
|
+
|
|
3
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
4
|
+
|
|
5
|
+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
6
|
+
|
|
7
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
8
|
+
|
|
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
|
+
|
|
11
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/filegroup/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { FileGroupConstructor } from '../../types/lib/watch';
|
|
2
|
-
import type { ExternalAsset } from '../../types/lib/asset';
|
|
3
|
-
|
|
4
|
-
declare const FileGroup: FileGroupConstructor<ExternalAsset>;
|
|
5
|
-
|
|
1
|
+
import type { FileGroupConstructor } from '../../types/lib/watch';
|
|
2
|
+
import type { ExternalAsset } from '../../types/lib/asset';
|
|
3
|
+
|
|
4
|
+
declare const FileGroup: FileGroupConstructor<ExternalAsset>;
|
|
5
|
+
|
|
6
6
|
export = FileGroup;
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { IFileManager, WatchConstructor } from '../types/lib';
|
|
2
|
-
|
|
3
|
-
declare const Watch: WatchConstructor<IFileManager>;
|
|
4
|
-
|
|
1
|
+
import type { IFileManager, WatchConstructor } from '../types/lib';
|
|
2
|
+
|
|
3
|
+
declare const Watch: WatchConstructor<IFileManager>;
|
|
4
|
+
|
|
5
5
|
export = Watch;
|
package/index.js
CHANGED
|
@@ -21,11 +21,11 @@ const kTlsVersion = Symbol('tlsVersion');
|
|
|
21
21
|
const kTlsPassphrase = Symbol('tlsPassphrase');
|
|
22
22
|
const kTlsConfig = Symbol('tlsConfig');
|
|
23
23
|
const PLATFORM_WIN32 = process.platform === 'win32';
|
|
24
|
+
const HTTP_MAP = new Map();
|
|
25
|
+
const DISK_MAP = new Map();
|
|
26
|
+
const PORT_MAP = new Map();
|
|
27
|
+
const SECURE_MAP = new Map();
|
|
24
28
|
let STATE_MAP = new WeakSet();
|
|
25
|
-
let HTTP_MAP = {};
|
|
26
|
-
let DISK_MAP = {};
|
|
27
|
-
let PORT_MAP = {};
|
|
28
|
-
let SECURE_MAP = {};
|
|
29
29
|
function isConnectionTimeout(err) {
|
|
30
30
|
switch (err instanceof Error && err.code) {
|
|
31
31
|
case 'ETIMEDOUT':
|
|
@@ -56,16 +56,19 @@ function getInterval({ watch }) {
|
|
|
56
56
|
return 0;
|
|
57
57
|
}
|
|
58
58
|
function closeFileGroup(map) {
|
|
59
|
-
for (const
|
|
60
|
-
for (const group of
|
|
59
|
+
for (const item of map.values()) {
|
|
60
|
+
for (const group of item.values()) {
|
|
61
61
|
abortTimeout(group);
|
|
62
62
|
}
|
|
63
|
+
item.clear();
|
|
63
64
|
}
|
|
65
|
+
map.clear();
|
|
64
66
|
}
|
|
65
67
|
function closeServer(map) {
|
|
66
|
-
for (const port
|
|
67
|
-
|
|
68
|
+
for (const [port, value] of map) {
|
|
69
|
+
value.close(err => err && Watch.writeFail([`Unable to shutdown ${map === PORT_MAP ? 'WS' : 'WSS'} server`, 'port: ' + port], err));
|
|
68
70
|
}
|
|
71
|
+
map.clear();
|
|
69
72
|
}
|
|
70
73
|
const formatDate = (value) => new Date(value).toLocaleString().replace(/\/20\d+, /, '@').replace(/:\d+ (AM|PM)$/, (...match) => match[1]);
|
|
71
74
|
class Watch extends core_1.Client {
|
|
@@ -77,7 +80,7 @@ class Watch extends core_1.Client {
|
|
|
77
80
|
let wss;
|
|
78
81
|
try {
|
|
79
82
|
if ((0, types_1.isPlainObject)(secure)) {
|
|
80
|
-
if (wss = SECURE_MAP
|
|
83
|
+
if (wss = SECURE_MAP.get(port.toString())) {
|
|
81
84
|
return wss;
|
|
82
85
|
}
|
|
83
86
|
const { ca, passphrase, version, config } = secure;
|
|
@@ -92,7 +95,7 @@ class Watch extends core_1.Client {
|
|
|
92
95
|
});
|
|
93
96
|
server.listen(port);
|
|
94
97
|
wss = new ws.Server({ server });
|
|
95
|
-
SECURE_MAP
|
|
98
|
+
SECURE_MAP.set(port.toString(), wss);
|
|
96
99
|
if (active) {
|
|
97
100
|
STATE_MAP.add(wss);
|
|
98
101
|
}
|
|
@@ -101,12 +104,12 @@ class Watch extends core_1.Client {
|
|
|
101
104
|
this.writeFail('TLS/SSL key and cert not found', (0, types_1.errorMessage)('ws', 'Missing TLS/SSL credentials'));
|
|
102
105
|
}
|
|
103
106
|
}
|
|
104
|
-
else if (wss = PORT_MAP
|
|
107
|
+
else if (wss = PORT_MAP.get(port.toString())) {
|
|
105
108
|
return wss;
|
|
106
109
|
}
|
|
107
110
|
else {
|
|
108
111
|
wss = new ws.Server({ port });
|
|
109
|
-
PORT_MAP
|
|
112
|
+
PORT_MAP.set(port.toString(), wss);
|
|
110
113
|
if (active) {
|
|
111
114
|
STATE_MAP.add(wss);
|
|
112
115
|
}
|
|
@@ -142,10 +145,6 @@ class Watch extends core_1.Client {
|
|
|
142
145
|
closeServer(PORT_MAP);
|
|
143
146
|
closeServer(SECURE_MAP);
|
|
144
147
|
filegroup_1.default.CLIENT_SESSION.clear();
|
|
145
|
-
HTTP_MAP = {};
|
|
146
|
-
DISK_MAP = {};
|
|
147
|
-
PORT_MAP = {};
|
|
148
|
-
SECURE_MAP = {};
|
|
149
148
|
STATE_MAP = new WeakSet();
|
|
150
149
|
}
|
|
151
150
|
static checkTimeout(client) {
|
|
@@ -257,15 +256,15 @@ class Watch extends core_1.Client {
|
|
|
257
256
|
}
|
|
258
257
|
const fatalError = (map, target, err) => {
|
|
259
258
|
const uri = target.value.uri;
|
|
260
|
-
delete
|
|
259
|
+
map.delete(uri);
|
|
261
260
|
abortTimeout(target);
|
|
262
261
|
this.writeFail(["Unable to watch file" /* ERR_MESSAGE.WATCH_FILE */, uri], err, 16 /* LOG_TYPE.WATCH */);
|
|
263
262
|
};
|
|
264
263
|
const watchExpired = (map, target, message = 'Expired') => {
|
|
265
264
|
this.formatMessage(16 /* LOG_TYPE.WATCH */, 'WATCH', [message, target.startTime ? 'since ' + formatDate(target.startTime) : ''], target.uri, { titleColor: 'grey' });
|
|
266
|
-
const data = map
|
|
267
|
-
if (!data
|
|
268
|
-
delete
|
|
265
|
+
const data = map.get(target.uri);
|
|
266
|
+
if (!data?.size) {
|
|
267
|
+
map.delete(target.uri);
|
|
269
268
|
return true;
|
|
270
269
|
}
|
|
271
270
|
return false;
|
|
@@ -369,7 +368,7 @@ class Watch extends core_1.Client {
|
|
|
369
368
|
const isMap = (value) => value ? value.size > 0 : false;
|
|
370
369
|
const checkAborted = (result, current) => result?.aborted && current.abortable && current.abort();
|
|
371
370
|
const checkPreceding = (map) => {
|
|
372
|
-
const data = map
|
|
371
|
+
const data = map.get(uri);
|
|
373
372
|
if (!data) {
|
|
374
373
|
return;
|
|
375
374
|
}
|
|
@@ -403,10 +402,10 @@ class Watch extends core_1.Client {
|
|
|
403
402
|
else if (server !== wss) {
|
|
404
403
|
if (wss.clients.size === 0 && !STATE_MAP.has(wss)) {
|
|
405
404
|
if (secure) {
|
|
406
|
-
delete
|
|
405
|
+
SECURE_MAP.delete(port.toString());
|
|
407
406
|
}
|
|
408
407
|
else {
|
|
409
|
-
delete
|
|
408
|
+
PORT_MAP.delete(port.toString());
|
|
410
409
|
}
|
|
411
410
|
wss.close();
|
|
412
411
|
}
|
|
@@ -455,7 +454,7 @@ class Watch extends core_1.Client {
|
|
|
455
454
|
}
|
|
456
455
|
const statusCode = res.statusCode;
|
|
457
456
|
const valid = statusCode >= 200 /* HTTP_STATUS.OK */ && statusCode < 300 /* HTTP_STATUS.MULTIPLE_CHOICES */;
|
|
458
|
-
const map = HTTP_MAP
|
|
457
|
+
const map = HTTP_MAP.get(uri);
|
|
459
458
|
const etag = res.headers.etag;
|
|
460
459
|
const lastModified = res.headers['last-modified'];
|
|
461
460
|
if (valid && map?.size && (etag || lastModified)) {
|
|
@@ -526,7 +525,7 @@ class Watch extends core_1.Client {
|
|
|
526
525
|
})
|
|
527
526
|
.then(() => {
|
|
528
527
|
if (!timeout.aborted) {
|
|
529
|
-
const map = HTTP_MAP
|
|
528
|
+
const map = HTTP_MAP.get(uri);
|
|
530
529
|
if (isMap(map)) {
|
|
531
530
|
let ms = Watch.MAX_TIMEOUT;
|
|
532
531
|
for (const session of map.values()) {
|
|
@@ -535,18 +534,16 @@ class Watch extends core_1.Client {
|
|
|
535
534
|
setTimeout(recurse.bind(this), timeout.interval = ms);
|
|
536
535
|
}
|
|
537
536
|
else {
|
|
538
|
-
delete
|
|
537
|
+
HTTP_MAP.delete(uri);
|
|
539
538
|
}
|
|
540
539
|
}
|
|
541
540
|
})
|
|
542
541
|
.catch(err => {
|
|
543
542
|
fatalError(HTTP_MAP, target, err);
|
|
544
|
-
|
|
545
|
-
client.destroy();
|
|
546
|
-
}
|
|
543
|
+
client?.destroy();
|
|
547
544
|
});
|
|
548
545
|
}).call(this);
|
|
549
|
-
HTTP_MAP
|
|
546
|
+
HTTP_MAP.set(uri, new Map([[dest, target]]));
|
|
550
547
|
}
|
|
551
548
|
else if (esm || path.isAbsolute(uri = core_1.Client.resolveFile(uri)) && this.canRead(uri, { hostPermissionOnly: !!this.host })) {
|
|
552
549
|
if ((status = checkPreceding(DISK_MAP)) !== undefined) {
|
|
@@ -558,7 +555,7 @@ class Watch extends core_1.Client {
|
|
|
558
555
|
fatalError(DISK_MAP, target, (0, types_1.createAbortError)());
|
|
559
556
|
return;
|
|
560
557
|
}
|
|
561
|
-
const map = DISK_MAP
|
|
558
|
+
const map = DISK_MAP.get(uri);
|
|
562
559
|
switch (event) {
|
|
563
560
|
case 'change': {
|
|
564
561
|
if (isMap(map)) {
|
|
@@ -601,7 +598,7 @@ class Watch extends core_1.Client {
|
|
|
601
598
|
break;
|
|
602
599
|
}
|
|
603
600
|
});
|
|
604
|
-
DISK_MAP
|
|
601
|
+
DISK_MAP.set(uri, new Map([[dest, target]]));
|
|
605
602
|
}
|
|
606
603
|
else {
|
|
607
604
|
return 2 /* ERR.LOCAL_ACCESS */;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@e-mc/watch",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "Watch constructor for E-mc.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -20,10 +20,10 @@
|
|
|
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.
|
|
26
|
-
"picomatch": "^
|
|
27
|
-
"ws": "^8.
|
|
23
|
+
"@e-mc/core": "0.7.1",
|
|
24
|
+
"@e-mc/request": "0.7.1",
|
|
25
|
+
"@e-mc/types": "0.7.1",
|
|
26
|
+
"picomatch": "^3.0.1",
|
|
27
|
+
"ws": "^8.14.2"
|
|
28
28
|
}
|
|
29
29
|
}
|