@e-mc/watch 0.8.10 → 0.9.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 +7 -3
- package/README.md +63 -13
- package/filegroup/index.js +2 -8
- package/index.js +96 -108
- package/package.json +6 -6
package/LICENSE
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
Copyright 2024 An Pham
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
6
6
|
|
|
7
|
-
|
|
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
|
+
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
|
|
4
|
-
*
|
|
3
|
+
* NodeJS 16
|
|
4
|
+
* ES2020
|
|
5
5
|
|
|
6
6
|
## General Usage
|
|
7
7
|
|
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
|
|
10
10
|
## Interface
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
* [View Source](https://www.unpkg.com/@e-mc/types@0.9.1/lib/index.d.ts)
|
|
13
13
|
|
|
14
14
|
```typescript
|
|
15
15
|
import type { IFileManager, ModuleConstructor } from "./index";
|
|
16
16
|
import type { ExternalAsset } from "./asset";
|
|
17
|
-
import type { IClient, IPermission } from "./core";
|
|
17
|
+
import type { HostInitConfig, IClient, IPermission } from "./core";
|
|
18
18
|
import type { FinalizeResult, PostFinalizeCallback } from "./filemanager";
|
|
19
19
|
import type { WatchModule } from "./settings";
|
|
20
20
|
import type { IFileGroup, ModifiedPostFinalizeListener, SecureOptions } from "./watch";
|
|
@@ -23,6 +23,7 @@ import type * as ws from "ws";
|
|
|
23
23
|
|
|
24
24
|
interface IWatch extends IClient<IFileManager, WatchModule, ModifiedPostFinalizeListener> {
|
|
25
25
|
connectTimeout: number;
|
|
26
|
+
init(config?: HostInitConfig): this;
|
|
26
27
|
start(assets: ExternalAsset[], permission?: IPermission | null): void;
|
|
27
28
|
modified(watch: IFileGroup<ExternalAsset>): Promise<FinalizeResult | void>;
|
|
28
29
|
configureServer(options: SecureOptions): boolean;
|
|
@@ -31,7 +32,7 @@ interface IWatch extends IClient<IFileManager, WatchModule, ModifiedPostFinalize
|
|
|
31
32
|
setSSLCert(value: string): boolean;
|
|
32
33
|
hasSecureProtocol(): boolean;
|
|
33
34
|
whenModified?(assets: ExternalAsset[], postFinalize: PostFinalizeCallback): IFileManager;
|
|
34
|
-
whenModified?(assets: ExternalAsset[], sanitize?: boolean
|
|
35
|
+
whenModified?(assets: ExternalAsset[], sanitize?: boolean, postFinalize?: PostFinalizeCallback): IFileManager;
|
|
35
36
|
set assets(value: ExternalAsset[]);
|
|
36
37
|
get assets(): ExternalAsset[];
|
|
37
38
|
set interval(value);
|
|
@@ -50,19 +51,68 @@ interface WatchConstructor extends ModuleConstructor {
|
|
|
50
51
|
checkTimeout(client: ws): boolean;
|
|
51
52
|
readonly prototype: IWatch;
|
|
52
53
|
new(module?: WatchModule): IWatch;
|
|
53
|
-
/* @deprecated */
|
|
54
|
-
new(interval?: number, port?: number, securePort?: number, extensions?: unknown[]): IWatch;
|
|
55
54
|
}
|
|
56
55
|
```
|
|
57
56
|
|
|
57
|
+
## Settings
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import type { PermittedDirectories } from "./core";
|
|
61
|
+
|
|
62
|
+
import type { SecureVersion } from "tls";
|
|
63
|
+
|
|
64
|
+
interface WatchModule {
|
|
65
|
+
// handler: "@e-mc/watch";
|
|
66
|
+
extensions?: string[];
|
|
67
|
+
timeout?: number | string;
|
|
68
|
+
interval?: number | string;
|
|
69
|
+
port?: number;
|
|
70
|
+
secure?: {
|
|
71
|
+
port?: number;
|
|
72
|
+
ca?: string;
|
|
73
|
+
key?: string;
|
|
74
|
+
cert?: string;
|
|
75
|
+
passphrase?: string;
|
|
76
|
+
version?: SecureVersion;
|
|
77
|
+
};
|
|
78
|
+
settings?: {
|
|
79
|
+
broadcast_id?: string | string[];
|
|
80
|
+
users?: Record<string, Record<string, unknown>>;
|
|
81
|
+
};
|
|
82
|
+
permission?: PermittedDirectories;
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Example usage
|
|
87
|
+
|
|
88
|
+
```javascript
|
|
89
|
+
const Watch = require("@e-mc/watch");
|
|
90
|
+
|
|
91
|
+
const instance = new Watch({ interval: 100, port: 8080 });
|
|
92
|
+
instance.init();
|
|
93
|
+
|
|
94
|
+
instance.whenModified = (assets) => {
|
|
95
|
+
assets.forEach(item => console.log(item.uri));
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const assets = [
|
|
99
|
+
{ localUri: "/path/workspace/output/image1.png", uri: "http://hostname/path/document1.png", watch: true },
|
|
100
|
+
{ localUri: "/path/workspace/output/image2.png", uri: "http://hostname/path/document2.png", watch: true }
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
instance.start(assets, { disk_read: ["/path/workspace/output/**"] });
|
|
104
|
+
```
|
|
105
|
+
|
|
58
106
|
## References
|
|
59
107
|
|
|
60
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
61
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
62
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
63
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
64
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
108
|
+
- https://www.unpkg.com/@e-mc/types@0.9.1/lib/asset.d.ts
|
|
109
|
+
- https://www.unpkg.com/@e-mc/types@0.9.1/lib/core.d.ts
|
|
110
|
+
- https://www.unpkg.com/@e-mc/types@0.9.1/lib/filemanager.d.ts
|
|
111
|
+
- https://www.unpkg.com/@e-mc/types@0.9.1/lib/settings.d.ts
|
|
112
|
+
- https://www.unpkg.com/@e-mc/types@0.9.1/lib/watch.d.ts
|
|
113
|
+
|
|
114
|
+
* https://www.npmjs.com/package/@types/ws
|
|
65
115
|
|
|
66
116
|
## LICENSE
|
|
67
117
|
|
|
68
|
-
|
|
118
|
+
BSD 3-Clause
|
package/filegroup/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var _a, _b, _c, _d, _e, _f;
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
3
|
const util = require("util");
|
|
5
4
|
const ws = require("ws");
|
|
6
5
|
const types_1 = require("@e-mc/types");
|
|
@@ -95,12 +94,11 @@ class FileGroup extends core_1.AbortComponent {
|
|
|
95
94
|
return this.sockets.find(item => item.socketId === socketId);
|
|
96
95
|
}
|
|
97
96
|
send(event, data) {
|
|
98
|
-
var _g;
|
|
99
97
|
const server = this.server;
|
|
100
98
|
let result = false;
|
|
101
99
|
if (server && (data.socketId = this.socketId)) {
|
|
102
100
|
data.event = event;
|
|
103
|
-
|
|
101
|
+
data.always ?? (data.always = this.always);
|
|
104
102
|
const value = data.value;
|
|
105
103
|
if (value && (util.types.isAnyArrayBuffer(value) || util.types.isArrayBufferView(value))) {
|
|
106
104
|
try {
|
|
@@ -209,9 +207,5 @@ class FileGroup extends core_1.AbortComponent {
|
|
|
209
207
|
_a = kServer, _b = kStarted, _c = kPaused, _d = kEtag, _e = kLastModified, _f = kSockets;
|
|
210
208
|
FileGroup.CONNECTION_TIMEOUT = 10 * 60000;
|
|
211
209
|
FileGroup.CLIENT_SESSION = new Map();
|
|
212
|
-
exports.default = FileGroup;
|
|
213
210
|
|
|
214
|
-
|
|
215
|
-
module.exports = exports.default;
|
|
216
|
-
module.exports.default = exports.default;
|
|
217
|
-
}
|
|
211
|
+
module.exports = FileGroup;
|
package/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
3
|
const path = require("path");
|
|
5
4
|
const fs = require("fs");
|
|
6
5
|
const https = require("https");
|
|
@@ -26,6 +25,15 @@ const DISK_MAP = new Map();
|
|
|
26
25
|
const PORT_MAP = new Map();
|
|
27
26
|
const SECURE_MAP = new Map();
|
|
28
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
|
+
}
|
|
29
37
|
function abortTimeout(group) {
|
|
30
38
|
group.timeout.aborted = true;
|
|
31
39
|
const watcher = group.watcher;
|
|
@@ -63,6 +71,23 @@ function closeServer(map) {
|
|
|
63
71
|
}
|
|
64
72
|
const formatDate = (value) => new Date(value).toLocaleString().replace(/\/20\d+, /, '@').replace(/:\d+ (AM|PM)$/, (...match) => match[1]);
|
|
65
73
|
class Watch extends core_1.Client {
|
|
74
|
+
constructor() {
|
|
75
|
+
super(...arguments);
|
|
76
|
+
this.connectTimeout = Watch.PROCESS_TIMEOUT;
|
|
77
|
+
this._moduleName = 'watch';
|
|
78
|
+
this._assets = [];
|
|
79
|
+
this._extensions = [];
|
|
80
|
+
this._hostEvents = [];
|
|
81
|
+
this[_a] = types_1.THRESHOLD.WATCH_INTERVAL;
|
|
82
|
+
this[_b] = 80;
|
|
83
|
+
this[_c] = 443;
|
|
84
|
+
this[_d] = '';
|
|
85
|
+
this[_e] = '';
|
|
86
|
+
this[_f] = '';
|
|
87
|
+
this[_g] = '';
|
|
88
|
+
this[_h] = undefined;
|
|
89
|
+
this[_j] = undefined;
|
|
90
|
+
}
|
|
66
91
|
static createServer(port, secure, active) {
|
|
67
92
|
if (typeof secure === 'boolean') {
|
|
68
93
|
active = secure;
|
|
@@ -76,13 +101,13 @@ class Watch extends core_1.Client {
|
|
|
76
101
|
}
|
|
77
102
|
const { ca, passphrase, version, config } = secure;
|
|
78
103
|
let { key, cert } = secure;
|
|
79
|
-
if (key && cert && (key = request_1.
|
|
104
|
+
if (key && cert && (key = request_1.readTLSKey(key, true)) && (cert = request_1.readTLSKey(cert, true))) {
|
|
80
105
|
const server = https.createServer({
|
|
81
106
|
...config,
|
|
82
|
-
ca: ca && request_1.
|
|
107
|
+
ca: ca && request_1.readCACert(ca, true) || undefined,
|
|
83
108
|
key: passphrase ? [{ pem: key, passphrase }] : key,
|
|
84
109
|
cert,
|
|
85
|
-
minVersion: version ||
|
|
110
|
+
minVersion: version || config?.minVersion
|
|
86
111
|
});
|
|
87
112
|
server.listen(port);
|
|
88
113
|
wss = new ws.Server({ server });
|
|
@@ -114,16 +139,16 @@ class Watch extends core_1.Client {
|
|
|
114
139
|
}
|
|
115
140
|
wss.on('connection', function (socket) {
|
|
116
141
|
socket.on('message', function () {
|
|
117
|
-
filegroup_1.
|
|
142
|
+
filegroup_1.CLIENT_SESSION.delete(this);
|
|
118
143
|
});
|
|
119
144
|
socket.on('close', function () {
|
|
120
|
-
filegroup_1.
|
|
145
|
+
filegroup_1.CLIENT_SESSION.delete(this);
|
|
121
146
|
});
|
|
122
|
-
this.clients.forEach(client => filegroup_1.
|
|
147
|
+
this.clients.forEach(client => filegroup_1.checkTimeout(client));
|
|
123
148
|
});
|
|
124
149
|
wss.on('error', function (err) {
|
|
125
150
|
const data = JSON.stringify({ event: types_1.WATCH_EVENT.ERROR, errors: [err.message] });
|
|
126
|
-
this.clients.forEach(client => filegroup_1.
|
|
151
|
+
this.clients.forEach(client => filegroup_1.checkTimeout(client) && client.send(data));
|
|
127
152
|
});
|
|
128
153
|
wss.on('close', function () {
|
|
129
154
|
this.clients.forEach(client => client.terminate());
|
|
@@ -135,54 +160,31 @@ class Watch extends core_1.Client {
|
|
|
135
160
|
closeFileGroup(DISK_MAP);
|
|
136
161
|
closeServer(PORT_MAP);
|
|
137
162
|
closeServer(SECURE_MAP);
|
|
138
|
-
filegroup_1.
|
|
163
|
+
filegroup_1.CLIENT_SESSION.clear();
|
|
139
164
|
STATE_MAP = new WeakSet();
|
|
140
165
|
}
|
|
141
166
|
static checkTimeout(client) {
|
|
142
|
-
return filegroup_1.
|
|
167
|
+
return filegroup_1.checkTimeout(client);
|
|
143
168
|
}
|
|
144
169
|
static setTimeout(value) {
|
|
145
170
|
if ((value = (0, types_1.parseTime)(value)) > 0) {
|
|
146
|
-
filegroup_1.
|
|
171
|
+
filegroup_1.CONNECTION_TIMEOUT = Math.min(value, core_1.Client.MAX_TIMEOUT);
|
|
147
172
|
}
|
|
148
173
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
this._hostEvents = [];
|
|
156
|
-
this[_a] = types_1.THRESHOLD.WATCH_INTERVAL;
|
|
157
|
-
this[_b] = 80;
|
|
158
|
-
this[_c] = 443;
|
|
159
|
-
this[_d] = '';
|
|
160
|
-
this[_e] = '';
|
|
161
|
-
this[_f] = '';
|
|
162
|
-
this[_g] = '';
|
|
163
|
-
this[_h] = undefined;
|
|
164
|
-
this[_j] = undefined;
|
|
165
|
-
let interval;
|
|
166
|
-
if ((0, types_1.isPlainObject)(data)) {
|
|
167
|
-
let secure;
|
|
168
|
-
({ interval, port, secure, extensions } = data);
|
|
169
|
-
if (secure) {
|
|
170
|
-
securePort = secure.port;
|
|
171
|
-
if (secure.cert && secure.key) {
|
|
172
|
-
this.configureServer(secure);
|
|
173
|
-
}
|
|
174
|
+
init(config) {
|
|
175
|
+
const { interval, port, secure } = this.module;
|
|
176
|
+
if (secure) {
|
|
177
|
+
this.securePort = (0, util_1.asInt)(secure.port);
|
|
178
|
+
if (secure.cert && secure.key) {
|
|
179
|
+
this.configureServer(secure);
|
|
174
180
|
}
|
|
175
181
|
}
|
|
176
182
|
this.interval = (0, util_1.asInt)(interval);
|
|
177
183
|
this.port = (0, util_1.asInt)(port);
|
|
178
|
-
|
|
179
|
-
if (Array.isArray(extensions)) {
|
|
180
|
-
this.module.extensions = extensions;
|
|
181
|
-
}
|
|
184
|
+
return super.init(config);
|
|
182
185
|
}
|
|
183
186
|
start(assets, permission) {
|
|
184
187
|
var _k;
|
|
185
|
-
var _l;
|
|
186
188
|
if (this.aborted) {
|
|
187
189
|
return;
|
|
188
190
|
}
|
|
@@ -192,15 +194,14 @@ class Watch extends core_1.Client {
|
|
|
192
194
|
const settings = this.getUserSettings();
|
|
193
195
|
const destMap = Object.create(null);
|
|
194
196
|
for (const item of assets) {
|
|
195
|
-
if ((0, types_1.ignoreFlag)(item.flags)) {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
(destMap[localUri] || (destMap[localUri] = [])).push(item);
|
|
197
|
+
if (!(0, types_1.ignoreFlag)(item.flags)) {
|
|
198
|
+
const { bundleId, uri, localUri } = item;
|
|
199
|
+
if (!(0, types_1.isEmpty)(bundleId)) {
|
|
200
|
+
(destMap[_k = ':' + bundleId] || (destMap[_k] = [])).push(item);
|
|
201
|
+
}
|
|
202
|
+
else if (uri && localUri) {
|
|
203
|
+
(destMap[localUri] || (destMap[localUri] = [])).push(item);
|
|
204
|
+
}
|
|
204
205
|
}
|
|
205
206
|
}
|
|
206
207
|
for (let dest in destMap) {
|
|
@@ -222,13 +223,13 @@ class Watch extends core_1.Client {
|
|
|
222
223
|
for (let i = 0, length = items.length; i < length; ++i) {
|
|
223
224
|
const watch = items[i].watch;
|
|
224
225
|
if ((0, types_1.isObject)(watch)) {
|
|
225
|
-
|
|
226
|
+
watch.assets?.forEach(other => {
|
|
226
227
|
if (items.includes(other)) {
|
|
227
228
|
return;
|
|
228
229
|
}
|
|
229
230
|
if ((0, types_1.watchFlag)(other.flags)) {
|
|
230
231
|
if (!other.watch) {
|
|
231
|
-
other = filegroup_1.
|
|
232
|
+
other = filegroup_1.cloneAsset(other);
|
|
232
233
|
other.watch = { ...watch };
|
|
233
234
|
}
|
|
234
235
|
other.flags &= ~1;
|
|
@@ -255,7 +256,7 @@ class Watch extends core_1.Client {
|
|
|
255
256
|
const watchExpired = (map, target, message = 'Expired') => {
|
|
256
257
|
this.formatMessage(16, 'WATCH', [message, target.startTime ? 'since ' + formatDate(target.startTime) : ''], target.uri, { titleColor: 'grey' });
|
|
257
258
|
const data = map.get(target.uri);
|
|
258
|
-
if (!
|
|
259
|
+
if (!data?.size) {
|
|
259
260
|
map.delete(target.uri);
|
|
260
261
|
return true;
|
|
261
262
|
}
|
|
@@ -329,8 +330,7 @@ class Watch extends core_1.Client {
|
|
|
329
330
|
}
|
|
330
331
|
const interval = getInterval(item) || watchInterval || this.interval;
|
|
331
332
|
const watching = (uri, esm) => {
|
|
332
|
-
|
|
333
|
-
const group = new filegroup_1.default(uri, main ? assets : items, startTime, this.willAbort("(watch)"));
|
|
333
|
+
const group = new filegroup_1(uri, main ? assets : items, startTime, this.willAbort("(watch)"));
|
|
334
334
|
group.add(expires, socketId, id);
|
|
335
335
|
if (main) {
|
|
336
336
|
group.main = main;
|
|
@@ -359,14 +359,13 @@ class Watch extends core_1.Client {
|
|
|
359
359
|
const timeout = { interval, retries: 0, aborted: false };
|
|
360
360
|
const target = { value: group, timeout, watcher: null };
|
|
361
361
|
const isMap = (value) => value ? value.size > 0 : false;
|
|
362
|
-
const wasAborted = (result, current) =>
|
|
362
|
+
const wasAborted = (result, current) => result?.aborted && current.abortable && current.abort();
|
|
363
363
|
const checkPreceding = (map) => {
|
|
364
|
-
var _k;
|
|
365
364
|
const data = map.get(uri);
|
|
366
365
|
if (!data) {
|
|
367
366
|
return;
|
|
368
367
|
}
|
|
369
|
-
const current =
|
|
368
|
+
const current = data.get(dest)?.value;
|
|
370
369
|
if (current && !current.expired) {
|
|
371
370
|
let reset;
|
|
372
371
|
if (id) {
|
|
@@ -431,7 +430,7 @@ class Watch extends core_1.Client {
|
|
|
431
430
|
return status;
|
|
432
431
|
}
|
|
433
432
|
const url = group.url || (group.url = new URL(uri));
|
|
434
|
-
const request =
|
|
433
|
+
const request = this.host?.Request || new request_1();
|
|
435
434
|
const agentTimeout = Math.max(timeout.interval * 10, this.connectTimeout);
|
|
436
435
|
const opts = request.opts(url, { method: 'HEAD', httpVersion: 1, timeout: agentTimeout, agentTimeout });
|
|
437
436
|
(function recurse() {
|
|
@@ -451,7 +450,7 @@ class Watch extends core_1.Client {
|
|
|
451
450
|
const map = HTTP_MAP.get(uri);
|
|
452
451
|
const etag = res.headers.etag;
|
|
453
452
|
const lastModified = res.headers['last-modified'];
|
|
454
|
-
if (valid &&
|
|
453
|
+
if (valid && map?.size && (etag || lastModified)) {
|
|
455
454
|
for (const [destUrl, input] of map) {
|
|
456
455
|
const value = input.value;
|
|
457
456
|
if (value.paused) {
|
|
@@ -491,19 +490,17 @@ class Watch extends core_1.Client {
|
|
|
491
490
|
}
|
|
492
491
|
else {
|
|
493
492
|
if (isMap(map)) {
|
|
494
|
-
reject(valid ? (0, types_1.errorValue)(
|
|
493
|
+
reject(valid ? (0, types_1.errorValue)("ETag not supported", uri) : (0, types_1.errorMessage)(statusCode, 'Invalid HTTP request', uri));
|
|
495
494
|
return;
|
|
496
495
|
}
|
|
497
496
|
watchExpired(HTTP_MAP, group);
|
|
498
497
|
abortTimeout(target);
|
|
499
498
|
}
|
|
500
|
-
|
|
501
|
-
client.destroy();
|
|
502
|
-
}
|
|
499
|
+
client?.destroy();
|
|
503
500
|
resolve();
|
|
504
501
|
})
|
|
505
502
|
.on('error', err => {
|
|
506
|
-
if (!timeout.aborted && !(
|
|
503
|
+
if (!timeout.aborted && !(isConnectionTimeout(err) && ++timeout.retries <= 10)) {
|
|
507
504
|
reject(err);
|
|
508
505
|
return;
|
|
509
506
|
}
|
|
@@ -532,9 +529,9 @@ class Watch extends core_1.Client {
|
|
|
532
529
|
}
|
|
533
530
|
}
|
|
534
531
|
})
|
|
535
|
-
.catch(err => {
|
|
532
|
+
.catch((err) => {
|
|
536
533
|
fatalError(HTTP_MAP, target, err);
|
|
537
|
-
client
|
|
534
|
+
client?.destroy();
|
|
538
535
|
});
|
|
539
536
|
}).call(this);
|
|
540
537
|
HTTP_MAP.set(uri, new Map([[dest, target]]));
|
|
@@ -551,7 +548,7 @@ class Watch extends core_1.Client {
|
|
|
551
548
|
}
|
|
552
549
|
const map = DISK_MAP.get(uri);
|
|
553
550
|
switch (event) {
|
|
554
|
-
case 'change':
|
|
551
|
+
case 'change':
|
|
555
552
|
if (isMap(map)) {
|
|
556
553
|
try {
|
|
557
554
|
const mtime = Math.floor(fs.statSync(uri).mtimeMs);
|
|
@@ -582,11 +579,8 @@ class Watch extends core_1.Client {
|
|
|
582
579
|
this.writeFail(["Unable to read file", path.basename(uri)], err, { type: 32, fatal: false });
|
|
583
580
|
}
|
|
584
581
|
}
|
|
585
|
-
}
|
|
586
582
|
case 'rename':
|
|
587
|
-
|
|
588
|
-
map.clear();
|
|
589
|
-
}
|
|
583
|
+
map?.clear();
|
|
590
584
|
watchExpired(DISK_MAP, group, event === 'rename' ? 'File renamed: ' + filename : undefined);
|
|
591
585
|
abortTimeout(target);
|
|
592
586
|
break;
|
|
@@ -645,13 +639,12 @@ class Watch extends core_1.Client {
|
|
|
645
639
|
}
|
|
646
640
|
}
|
|
647
641
|
async modified(watch) {
|
|
648
|
-
var _k, _l, _m, _o;
|
|
649
642
|
this.formatMessage(16, 'WATCH', 'File modified', watch.uri, { ...core_1.Client.LOG_STYLE_WARN });
|
|
650
643
|
const { host, assets } = this;
|
|
651
644
|
let items, sanitize = false;
|
|
652
645
|
if (watch.main) {
|
|
653
646
|
sanitize = watch.assets.length > assets.length;
|
|
654
|
-
items = sanitize ? watch.assets.map(item => filegroup_1.
|
|
647
|
+
items = sanitize ? watch.assets.map(item => filegroup_1.cloneAsset(item)) : assets.map(item => (0, types_1.cloneObject)(item, true));
|
|
655
648
|
}
|
|
656
649
|
else {
|
|
657
650
|
items = [];
|
|
@@ -669,9 +662,9 @@ class Watch extends core_1.Client {
|
|
|
669
662
|
sanitize = true;
|
|
670
663
|
}
|
|
671
664
|
if (sanitize) {
|
|
672
|
-
items = watch.assets.map(item => filegroup_1.
|
|
665
|
+
items = watch.assets.map(item => filegroup_1.cloneAsset(item));
|
|
673
666
|
}
|
|
674
|
-
if (watch.related
|
|
667
|
+
if ((0, types_1.isArray)(watch.related)) {
|
|
675
668
|
items.push(...watch.related);
|
|
676
669
|
}
|
|
677
670
|
}
|
|
@@ -680,7 +673,7 @@ class Watch extends core_1.Client {
|
|
|
680
673
|
}
|
|
681
674
|
watch.captured = false;
|
|
682
675
|
try {
|
|
683
|
-
const manager =
|
|
676
|
+
const manager = this.whenModified?.(items, sanitize);
|
|
684
677
|
for (const callback of this.extensions) {
|
|
685
678
|
try {
|
|
686
679
|
const listener = callback(watch, items);
|
|
@@ -696,35 +689,34 @@ class Watch extends core_1.Client {
|
|
|
696
689
|
catch {
|
|
697
690
|
}
|
|
698
691
|
}
|
|
699
|
-
if (
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
document.dataSource = result.dataSource;
|
|
692
|
+
if (manager) {
|
|
693
|
+
if (host && watch.document) {
|
|
694
|
+
for (const { instance } of host.Document) {
|
|
695
|
+
if (host.hasDocument(instance, watch.document)) {
|
|
696
|
+
const result = instance.watchInit?.(watch, items, sanitize);
|
|
697
|
+
if (result) {
|
|
698
|
+
if ((0, types_1.isArray)(result.using)) {
|
|
699
|
+
manager.using(...result.using);
|
|
700
|
+
}
|
|
701
|
+
if (Array.isArray(result.dataSource)) {
|
|
702
|
+
const document = manager.find(instance.moduleName);
|
|
703
|
+
if (document) {
|
|
704
|
+
document.dataSource = result.dataSource;
|
|
705
|
+
}
|
|
714
706
|
}
|
|
715
707
|
}
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
708
|
+
const listener = instance.watchModified?.(watch, items);
|
|
709
|
+
if (typeof listener === 'function') {
|
|
710
|
+
manager.on('end', listener);
|
|
711
|
+
}
|
|
720
712
|
}
|
|
721
713
|
}
|
|
722
714
|
}
|
|
715
|
+
return await manager.start();
|
|
723
716
|
}
|
|
724
|
-
return await manager.start();
|
|
725
717
|
}
|
|
726
718
|
catch (err) {
|
|
727
|
-
this.writeFail(["Unknown",
|
|
719
|
+
this.writeFail(["Unknown", watch.url?.pathname || path.basename(watch.uri)], err);
|
|
728
720
|
}
|
|
729
721
|
}
|
|
730
722
|
configureServer({ ca, key, cert, passphrase, version, config }) {
|
|
@@ -734,10 +726,10 @@ class Watch extends core_1.Client {
|
|
|
734
726
|
if (ca) {
|
|
735
727
|
this.setCA(ca);
|
|
736
728
|
}
|
|
737
|
-
if (request_1.
|
|
729
|
+
if (request_1.isCert(key) || core_1.Client.isPath(key = path.resolve(key = key.trim())) && this.canRead(key, { ownPermissionOnly: true })) {
|
|
738
730
|
this[kTlsKey] = key.trim();
|
|
739
731
|
}
|
|
740
|
-
if (request_1.
|
|
732
|
+
if (request_1.isCert(cert) || core_1.Client.isPath(cert = path.resolve(cert = cert.trim())) && this.canRead(cert, { ownPermissionOnly: true })) {
|
|
741
733
|
this[kTlsCert] = cert.trim();
|
|
742
734
|
}
|
|
743
735
|
if ((0, types_1.isString)(passphrase)) {
|
|
@@ -774,10 +766,10 @@ class Watch extends core_1.Client {
|
|
|
774
766
|
setSSLKey(value) {
|
|
775
767
|
this[kTlsConfig] = { secureProtocol: 'SSLv23_method' };
|
|
776
768
|
this[kTlsVersion] = undefined;
|
|
777
|
-
return !!(this[kTlsKey] = request_1.
|
|
769
|
+
return !!(this[kTlsKey] = request_1.readTLSKey(value, true));
|
|
778
770
|
}
|
|
779
771
|
setSSLCert(value) {
|
|
780
|
-
return !!(this[kTlsCert] = request_1.
|
|
772
|
+
return !!(this[kTlsCert] = request_1.readTLSCert(value, true));
|
|
781
773
|
}
|
|
782
774
|
hasSecureProtocol() {
|
|
783
775
|
return !!this[kTlsKey] && !!this[kTlsCert];
|
|
@@ -787,7 +779,7 @@ class Watch extends core_1.Client {
|
|
|
787
779
|
}
|
|
788
780
|
set host(value) {
|
|
789
781
|
super.host = value;
|
|
790
|
-
if (
|
|
782
|
+
if ((0, types_1.isArray)(value?.assets)) {
|
|
791
783
|
this.assets = value.assets;
|
|
792
784
|
}
|
|
793
785
|
}
|
|
@@ -832,9 +824,5 @@ class Watch extends core_1.Client {
|
|
|
832
824
|
}
|
|
833
825
|
_a = kInterval, _b = kPort, _c = kSecurePort, _d = kCa, _e = kTlsKey, _f = kTlsCert, _g = kTlsPassphrase, _h = kTlsVersion, _j = kTlsConfig;
|
|
834
826
|
Watch.PROCESS_TIMEOUT = 5 * 1000;
|
|
835
|
-
exports.default = Watch;
|
|
836
827
|
|
|
837
|
-
|
|
838
|
-
module.exports = exports.default;
|
|
839
|
-
module.exports.default = exports.default;
|
|
840
|
-
}
|
|
828
|
+
module.exports = Watch;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@e-mc/watch",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Watch constructor for E-mc.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -17,13 +17,13 @@
|
|
|
17
17
|
"squared-functions"
|
|
18
18
|
],
|
|
19
19
|
"author": "An Pham <anpham6@gmail.com>",
|
|
20
|
-
"license": "
|
|
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": "^
|
|
23
|
+
"@e-mc/core": "0.9.1",
|
|
24
|
+
"@e-mc/request": "0.9.1",
|
|
25
|
+
"@e-mc/types": "0.9.1",
|
|
26
|
+
"picomatch": "^4.0.2",
|
|
27
27
|
"ws": "^8.16.0"
|
|
28
28
|
}
|
|
29
29
|
}
|