@matterbridge/thread 3.10.13-dev-20261007-320f739 → 3.10.13-dev-20261008-55d98fb
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/dist/threadsManager.d.ts +3 -1
- package/dist/threadsManager.js +108 -47
- package/dist/{workerWrapper.d.ts → threadsWrapper.d.ts} +8 -3
- package/dist/{workerWrapper.js → threadsWrapper.js} +15 -10
- package/dist/workerArchiveCommand.d.ts +2 -2
- package/dist/workerArchiveCommand.js +2 -2
- package/dist/workerCheckUpdates.d.ts +2 -2
- package/dist/workerCheckUpdates.js +2 -2
- package/dist/workerDockerVersion.d.ts +2 -2
- package/dist/workerDockerVersion.js +2 -2
- package/dist/workerGlobalPrefix.d.ts +2 -2
- package/dist/workerGlobalPrefix.js +2 -2
- package/dist/workerSpawnCommand.d.ts +2 -2
- package/dist/workerSpawnCommand.js +2 -2
- package/dist/workerSystemCheck.d.ts +2 -2
- package/dist/workerSystemCheck.js +2 -2
- package/dist/zipjs.js +2 -1
- package/package.json +8 -10
- package/dist/backend.d.ts +0 -42
- package/dist/backend.js +0 -369
- package/dist/backendExpress.d.ts +0 -21
- package/dist/backendExpress.js +0 -455
- package/dist/backendWsServer.d.ts +0 -39
- package/dist/backendWsServer.js +0 -393
- package/dist/threadBackend.d.ts +0 -3
- package/dist/threadBackend.js +0 -24
package/dist/threadsManager.d.ts
CHANGED
|
@@ -11,11 +11,13 @@ export declare class ThreadsManager {
|
|
|
11
11
|
private readonly boundMsgHandler;
|
|
12
12
|
private interval;
|
|
13
13
|
private intervalMs;
|
|
14
|
+
private readonly coreDirectory;
|
|
14
15
|
private threads;
|
|
15
16
|
private terminateWorkers;
|
|
16
|
-
constructor(intervalMs?: number);
|
|
17
|
+
constructor(coreDirectory: string, intervalMs?: number);
|
|
17
18
|
destroy(): void;
|
|
18
19
|
private msgHandler;
|
|
20
|
+
private sendShutdown;
|
|
19
21
|
private terminateExitedWorkers;
|
|
20
22
|
private intervalHandler;
|
|
21
23
|
runThread(name: string, workerData?: WorkerData, argv?: string[], env?: NodeJS.ProcessEnv, execArgv?: string[], pipedOutput?: boolean): Worker;
|
package/dist/threadsManager.js
CHANGED
|
@@ -19,6 +19,7 @@ export class ThreadsManager {
|
|
|
19
19
|
boundMsgHandler = this.msgHandler.bind(this);
|
|
20
20
|
interval;
|
|
21
21
|
intervalMs;
|
|
22
|
+
coreDirectory;
|
|
22
23
|
threads = [
|
|
23
24
|
{ name: 'CheckUpdates', path: 'workerCheckUpdates.js', type: 'worker' },
|
|
24
25
|
{ name: 'SystemCheck', path: 'workerSystemCheck.js', type: 'worker' },
|
|
@@ -27,9 +28,11 @@ export class ThreadsManager {
|
|
|
27
28
|
{ name: 'ArchiveCommand', path: 'workerArchiveCommand.js', type: 'worker' },
|
|
28
29
|
{ name: 'DockerVersion', path: 'workerDockerVersion.js', type: 'worker' },
|
|
29
30
|
{ name: 'Backend', path: 'threadBackend.js', type: 'thread' },
|
|
31
|
+
{ name: 'RootNode', path: 'threadRootNode.js', type: 'thread', multiple: true },
|
|
32
|
+
{ name: 'Tracker', path: 'threadTracker.js', type: 'thread', multiple: true, startup: true, shutdown: true },
|
|
30
33
|
];
|
|
31
34
|
terminateWorkers = new Set();
|
|
32
|
-
constructor(intervalMs = 60_000) {
|
|
35
|
+
constructor(coreDirectory, intervalMs = 60_000) {
|
|
33
36
|
this.debug = hasAnyParameter('debug', 'verbose', 'debug-threads', 'verbose-threads');
|
|
34
37
|
this.verbose = hasAnyParameter('verbose', 'verbose-threads');
|
|
35
38
|
this.tracker = hasAnyParameter('tracker', 'tracker-threads');
|
|
@@ -44,6 +47,7 @@ export class ThreadsManager {
|
|
|
44
47
|
this.server = new BroadcastServer('manager', this.log);
|
|
45
48
|
this.server.on('broadcast_message', this.boundMsgHandler);
|
|
46
49
|
this.intervalMs = intervalMs;
|
|
50
|
+
this.coreDirectory = coreDirectory;
|
|
47
51
|
this.interval = setInterval(this.intervalHandler.bind(this), this.intervalMs);
|
|
48
52
|
if (this.verbose)
|
|
49
53
|
this.log.notice(`ThreadsManager initialized. Listening for broadcast messages...`);
|
|
@@ -51,6 +55,7 @@ export class ThreadsManager {
|
|
|
51
55
|
destroy() {
|
|
52
56
|
clearInterval(this.interval);
|
|
53
57
|
this.terminateExitedWorkers();
|
|
58
|
+
this.sendShutdown(this.threads.filter((t) => t.shutdown));
|
|
54
59
|
this.server.off('broadcast_message', this.boundMsgHandler);
|
|
55
60
|
this.server.close();
|
|
56
61
|
if (this.verbose)
|
|
@@ -81,12 +86,31 @@ export class ThreadsManager {
|
|
|
81
86
|
this.server.respond({ ...msg, result: { success: false } });
|
|
82
87
|
}
|
|
83
88
|
break;
|
|
89
|
+
case 'manager_shutdown': {
|
|
90
|
+
const threads = msg.params.thread === undefined ? this.threads : this.threads.filter((t) => t.name === msg.params.thread);
|
|
91
|
+
if (threads.length === 0)
|
|
92
|
+
this.log.warn(`Failed to shut down thread ${CYAN}${msg.params.thread}${wr}: thread not found`);
|
|
93
|
+
this.sendShutdown(threads);
|
|
94
|
+
this.server.respond({ ...msg, result: { success: threads.length > 0 } });
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
84
97
|
default:
|
|
85
98
|
if (this.verbose)
|
|
86
99
|
this.log.debug(`Unknown broadcast request ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}`);
|
|
87
100
|
}
|
|
88
101
|
}
|
|
89
102
|
}
|
|
103
|
+
sendShutdown(threads) {
|
|
104
|
+
for (const thread of threads) {
|
|
105
|
+
for (const info of [thread, ...(thread.instances ?? [])]) {
|
|
106
|
+
if (!info.worker)
|
|
107
|
+
continue;
|
|
108
|
+
const shutdownMessage = { type: 'shutdown', threadName: thread.name, threadId: info.worker.threadId };
|
|
109
|
+
info.worker.postMessage(shutdownMessage);
|
|
110
|
+
this.log.debug(`Thread ${thread.name} sent shutdown message to thread id ${info.worker.threadId}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
90
114
|
terminateExitedWorkers() {
|
|
91
115
|
if (this.terminateWorkers.size > 0) {
|
|
92
116
|
this.log.debug(`Terminating ${this.terminateWorkers.size} workers that have exited...`);
|
|
@@ -104,16 +128,26 @@ export class ThreadsManager {
|
|
|
104
128
|
}
|
|
105
129
|
intervalHandler() {
|
|
106
130
|
for (const thread of this.threads) {
|
|
107
|
-
|
|
131
|
+
if (!thread.multiple) {
|
|
132
|
+
this.log.debug(`Thread ${thread.name} running: ${thread.worker ? 'yes' : 'no'}, threadId: ${thread.worker?.threadId ?? 'none'}, lastSeen: ${thread.lastSeen ? new Date(thread.lastSeen).toISOString() : 'never'}, runs: ${thread.runCount ?? 0}, errors: ${thread.errorCount ?? 0}`);
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
const instances = thread.instances ?? [];
|
|
136
|
+
this.log.debug(`Thread ${thread.name} instances: ${instances.length}, running: ${instances.filter((instance) => instance.worker).length}, runs: ${thread.runCount ?? 0}, errors: ${thread.errorCount ?? 0}`);
|
|
137
|
+
instances.forEach((instance, index) => {
|
|
138
|
+
this.log.debug(`- instance ${index} running: ${instance.worker ? 'yes' : 'no'}, threadId: ${instance.worker?.threadId ?? 'none'}, lastSeen: ${instance.lastSeen ? new Date(instance.lastSeen).toISOString() : 'never'}, lastStarted: ${instance.lastStarted ? new Date(instance.lastStarted).toISOString() : 'never'}, lastStopped: ${instance.lastStopped ? new Date(instance.lastStopped).toISOString() : 'never'}, lastDuration: ${instance.lastDuration ?? 'none'} ms`);
|
|
139
|
+
});
|
|
108
140
|
}
|
|
109
141
|
this.terminateExitedWorkers();
|
|
110
142
|
for (const thread of this.threads) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
143
|
+
for (const info of [thread, ...(thread.instances ?? [])]) {
|
|
144
|
+
if (info.worker && Date.now() - (info.lastSeen ?? 0) > this.intervalMs) {
|
|
145
|
+
const msg = { type: 'ping', threadId: info.worker.threadId, threadName: thread.name };
|
|
146
|
+
info.worker.postMessage(msg);
|
|
147
|
+
}
|
|
148
|
+
if (info.worker && Date.now() - (info.lastSeen ?? 0) > this.intervalMs * 2) {
|
|
149
|
+
this.log.warn(`Thread ${CYAN}${thread.name}${db} has not been seen for more than ${this.intervalMs * 2} ms. It may be unresponsive.`);
|
|
150
|
+
}
|
|
117
151
|
}
|
|
118
152
|
}
|
|
119
153
|
}
|
|
@@ -122,76 +156,100 @@ export class ThreadsManager {
|
|
|
122
156
|
if (!threadInfo) {
|
|
123
157
|
throw new Error(`Thread ${name} not found`);
|
|
124
158
|
}
|
|
125
|
-
if (threadInfo.worker) {
|
|
159
|
+
if (threadInfo.worker && !threadInfo.multiple) {
|
|
126
160
|
throw new Error(`Thread ${name} is already running with thread ID ${threadInfo.worker.threadId}`);
|
|
127
161
|
}
|
|
128
162
|
const path = this.resolvePath(threadInfo.path);
|
|
129
163
|
if (!fs.existsSync(path)) {
|
|
130
164
|
throw new Error(`Thread ${name} file not found at path ${path}`);
|
|
131
165
|
}
|
|
132
|
-
this.log.debug(`Starting thread ${threadInfo.name} from path ${path} type ${threadInfo.type}...`);
|
|
166
|
+
this.log.debug(`Starting thread ${threadInfo.name} from path ${path} type ${threadInfo.type}${threadInfo.multiple ? ` instances: ${threadInfo.instances?.length}` : ''}...`);
|
|
133
167
|
threadInfo.lastStarted = undefined;
|
|
134
168
|
threadInfo.lastStopped = undefined;
|
|
135
169
|
threadInfo.lastDuration = undefined;
|
|
136
|
-
|
|
137
|
-
|
|
170
|
+
const worker = this.createESMWorker(threadInfo.name, path, { ...workerData, type: threadInfo.type, debug: this.debug, verbose: this.verbose, tracker: this.tracker, logLevel: this.log.logLevel }, argv, env, execArgv, pipedOutput);
|
|
171
|
+
if (threadInfo.multiple) {
|
|
172
|
+
threadInfo.instances ??= [];
|
|
173
|
+
threadInfo.instances.push({ worker });
|
|
174
|
+
}
|
|
175
|
+
else
|
|
176
|
+
threadInfo.worker = worker;
|
|
138
177
|
worker.once('online', () => {
|
|
139
178
|
const now = Date.now();
|
|
179
|
+
const info = [threadInfo, ...(threadInfo.instances ?? [])].find((info) => info.worker === worker);
|
|
180
|
+
if (info) {
|
|
181
|
+
info.lastSeen = now;
|
|
182
|
+
info.lastStarted = now;
|
|
183
|
+
}
|
|
140
184
|
this.log.debug(`Thread ${threadInfo.name} is online at ${new Date(now).toISOString()}`);
|
|
141
185
|
});
|
|
142
186
|
worker.once('exit', () => {
|
|
143
187
|
const now = Date.now();
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
188
|
+
const info = [threadInfo, ...(threadInfo.instances ?? [])].find((info) => info.worker === worker);
|
|
189
|
+
if (info) {
|
|
190
|
+
info.lastSeen = now;
|
|
191
|
+
info.lastStopped = now;
|
|
192
|
+
info.lastDuration = Math.max(0, now - (info.lastStarted ?? now));
|
|
193
|
+
info.worker = undefined;
|
|
149
194
|
}
|
|
150
|
-
this.log.debug(`Thread ${threadInfo.name} has exited at ${new Date(now).toISOString()}`);
|
|
195
|
+
this.log.debug(`Thread ${threadInfo.name} has exited at ${new Date(now).toISOString()} after ${info?.lastDuration ?? 0} ms`);
|
|
151
196
|
this.terminateWorkers.delete(worker);
|
|
152
197
|
});
|
|
153
198
|
worker.on('message', (message) => {
|
|
154
199
|
const now = Date.now();
|
|
155
|
-
threadInfo.
|
|
200
|
+
const info = [threadInfo, ...(threadInfo.instances ?? [])].find((info) => info.worker === worker);
|
|
201
|
+
if (info) {
|
|
202
|
+
info.lastSeen = now;
|
|
203
|
+
}
|
|
156
204
|
if (this.verbose)
|
|
157
205
|
this.log.debug(`Thread ${threadInfo.name} sent a message at ${new Date(now).toISOString()}: ${debugStringify(message)}`);
|
|
158
|
-
if (message.type === '
|
|
159
|
-
AnsiLogger.create({ logName: threadInfo.name, logNameColor: MAGENTA, logTimestampFormat: 4, logLevel: this.log.logLevel }).log(message.logLevel, message.message);
|
|
160
|
-
}
|
|
161
|
-
else if (message.type === 'init') {
|
|
162
|
-
threadInfo.lastStarted = now;
|
|
206
|
+
if (message.type === 'init') {
|
|
163
207
|
threadInfo.runCount = (threadInfo.runCount ?? 0) + 1;
|
|
164
208
|
this.log.debug(`Thread ${threadInfo.name} is online started at ${new Date(now).toISOString()} with thread id ${worker.threadId}`);
|
|
209
|
+
if (threadInfo.startup) {
|
|
210
|
+
const startupMessage = { type: 'startup', threadName: threadInfo.name, threadId: worker.threadId };
|
|
211
|
+
worker.postMessage(startupMessage);
|
|
212
|
+
this.log.debug(`Thread ${threadInfo.name} sent startup message to thread id ${worker.threadId}`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
else if (message.type === 'pong') {
|
|
216
|
+
this.log.debug(`Thread ${threadInfo.name} received a pong at ${new Date(now).toISOString()}`);
|
|
217
|
+
}
|
|
218
|
+
else if (message.type === 'log') {
|
|
219
|
+
AnsiLogger.create({ logName: threadInfo.name, logNameColor: MAGENTA, logTimestampFormat: 4, logLevel: this.log.logLevel }).log(message.logLevel, message.message);
|
|
165
220
|
}
|
|
166
221
|
else if (message.type === 'exit') {
|
|
167
|
-
threadInfo.lastStopped = now;
|
|
168
|
-
threadInfo.lastDuration = Math.max(0, now - (threadInfo.lastStarted ?? now));
|
|
169
222
|
if (!message.success) {
|
|
170
223
|
threadInfo.errorCount = (threadInfo.errorCount ?? 0) + 1;
|
|
171
224
|
}
|
|
172
225
|
this.terminateWorkers.add(worker);
|
|
173
|
-
threadInfo.
|
|
174
|
-
this.log.debug(`Thread ${threadInfo.name} has exited at ${new Date(now).toISOString()} with thread id ${worker.threadId} after running for ${threadInfo.lastDuration} ms`);
|
|
226
|
+
this.log.debug(`Thread ${threadInfo.name} has exited at ${new Date(now).toISOString()} with thread id ${worker.threadId}`);
|
|
175
227
|
}
|
|
176
228
|
});
|
|
177
229
|
worker.on('messageerror', () => {
|
|
178
230
|
const now = Date.now();
|
|
179
|
-
threadInfo.
|
|
180
|
-
|
|
231
|
+
const info = [threadInfo, ...(threadInfo.instances ?? [])].find((info) => info.worker === worker);
|
|
232
|
+
if (info) {
|
|
233
|
+
info.lastSeen = now;
|
|
234
|
+
threadInfo.errorCount = (threadInfo.errorCount ?? 0) + 1;
|
|
235
|
+
}
|
|
181
236
|
this.log.error(`Thread ${threadInfo.name} encountered a message error at ${new Date(now).toISOString()}`);
|
|
182
237
|
});
|
|
183
238
|
worker.once('error', (error) => {
|
|
184
239
|
const now = Date.now();
|
|
185
|
-
threadInfo.
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
240
|
+
const info = [threadInfo, ...(threadInfo.instances ?? [])].find((info) => info.worker === worker);
|
|
241
|
+
if (info) {
|
|
242
|
+
info.lastSeen = now;
|
|
243
|
+
info.lastStopped = now;
|
|
244
|
+
info.lastDuration = Math.max(0, now - (info.lastStarted ?? now));
|
|
245
|
+
threadInfo.errorCount = (threadInfo.errorCount ?? 0) + 1;
|
|
246
|
+
info.worker = undefined;
|
|
247
|
+
}
|
|
190
248
|
this.terminateWorkers.add(worker);
|
|
191
|
-
this.log.error(`Thread ${threadInfo.name} encountered an error at ${new Date(now).toISOString()} after running for ${
|
|
249
|
+
this.log.error(`Thread ${threadInfo.name} encountered an error at ${new Date(now).toISOString()} after running for ${info?.lastDuration} ms: ${getErrorMessage(error)}`);
|
|
192
250
|
});
|
|
193
251
|
this.log.debug(`Started thread ${threadInfo.name} from path ${path} type ${threadInfo.type} with thread id ${worker.threadId}`);
|
|
194
|
-
return
|
|
252
|
+
return worker;
|
|
195
253
|
}
|
|
196
254
|
async runInMainThread(name, workerData = null) {
|
|
197
255
|
const threadInfo = this.threads.find((t) => t.name === name);
|
|
@@ -200,27 +258,30 @@ export class ThreadsManager {
|
|
|
200
258
|
}
|
|
201
259
|
this.log.debug(`Running thread ${threadInfo.name} in the main thread...`);
|
|
202
260
|
let success = false;
|
|
203
|
-
const
|
|
204
|
-
if (
|
|
205
|
-
|
|
261
|
+
const threadsWrapper = (await import(this.resolvePath(threadInfo.path))).default;
|
|
262
|
+
if (threadsWrapper && typeof threadsWrapper === 'object' && threadsWrapper.name === name && threadsWrapper.entrypoint && typeof threadsWrapper.entrypoint === 'function') {
|
|
263
|
+
threadsWrapper.workerData = workerData ? { ...workerData, type: threadInfo.type } : null;
|
|
206
264
|
try {
|
|
207
|
-
success = await
|
|
265
|
+
success = await threadsWrapper.entrypoint(threadsWrapper);
|
|
208
266
|
}
|
|
209
267
|
finally {
|
|
210
268
|
if (!success || threadInfo.type !== 'thread')
|
|
211
|
-
|
|
269
|
+
threadsWrapper.destroy(success);
|
|
212
270
|
}
|
|
213
271
|
}
|
|
214
272
|
this.log.debug(`Finished running thread ${threadInfo.name} in the main thread.`);
|
|
215
273
|
return success;
|
|
216
274
|
}
|
|
217
275
|
resolvePath(fileName) {
|
|
218
|
-
const
|
|
276
|
+
const threadDirectory = path.dirname(fileURLToPath(import.meta.url));
|
|
219
277
|
const candidates = [
|
|
220
|
-
path.join(
|
|
221
|
-
path.join(
|
|
222
|
-
path.join(
|
|
223
|
-
path.join(
|
|
278
|
+
path.join(threadDirectory, fileName),
|
|
279
|
+
path.join(threadDirectory, '..', 'dist', fileName),
|
|
280
|
+
path.join(threadDirectory, '..', 'src', fileName.replace(/\.js$/, '.ts')),
|
|
281
|
+
path.join(threadDirectory, 'workers', fileName),
|
|
282
|
+
path.join(this.coreDirectory, 'runners', fileName),
|
|
283
|
+
path.join(this.coreDirectory, '..', 'dist', 'runners', fileName),
|
|
284
|
+
path.join(this.coreDirectory, '..', 'src', 'runners', fileName.replace(/\.js$/, '.ts')),
|
|
224
285
|
];
|
|
225
286
|
for (const candidate of candidates) {
|
|
226
287
|
if (fs.existsSync(candidate))
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
1
2
|
import type { ParentPortMessage, ThreadNames, WorkerData } from '@matterbridge/types';
|
|
2
3
|
import type { Tracker } from '@matterbridge/utils/tracker';
|
|
3
4
|
import { AnsiLogger, LogLevel } from 'node-ansi-logger';
|
|
4
5
|
import { BroadcastServer } from './broadcastServer.js';
|
|
5
|
-
export
|
|
6
|
+
export interface ThreadsWrapperEvents {
|
|
7
|
+
startup: [];
|
|
8
|
+
shutdown: [];
|
|
9
|
+
}
|
|
10
|
+
export declare class ThreadsWrapper extends EventEmitter<ThreadsWrapperEvents> {
|
|
6
11
|
name: ThreadNames;
|
|
7
|
-
|
|
12
|
+
entrypoint: (worker: ThreadsWrapper) => Promise<boolean>;
|
|
8
13
|
debug: boolean;
|
|
9
14
|
verbose: boolean;
|
|
10
15
|
useTracker: boolean;
|
|
@@ -15,7 +20,7 @@ export declare class WorkerWrapper {
|
|
|
15
20
|
private destroyed;
|
|
16
21
|
private readonly boundUnhandledRejectionHandler;
|
|
17
22
|
private readonly boundUncaughtExceptionHandler;
|
|
18
|
-
constructor(name: ThreadNames,
|
|
23
|
+
constructor(name: ThreadNames, entrypoint: (worker: ThreadsWrapper) => Promise<boolean>);
|
|
19
24
|
destroy(success: boolean): void;
|
|
20
25
|
private handleUnhandledRejection;
|
|
21
26
|
private handleUncaughtException;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
1
2
|
import { isMainThread, parentPort, threadId, workerData } from 'node:worker_threads';
|
|
2
3
|
import { getErrorMessage, inspectError } from '@matterbridge/utils';
|
|
3
4
|
import { hasAnyParameter } from '@matterbridge/utils/cli';
|
|
@@ -6,10 +7,10 @@ import { logModuleLoaded } from '@matterbridge/utils/loader';
|
|
|
6
7
|
import { AnsiLogger, debugStringify, MAGENTA } from 'node-ansi-logger';
|
|
7
8
|
import { BroadcastServer } from './broadcastServer.js';
|
|
8
9
|
import { ThreadsManager } from './threadsManager.js';
|
|
9
|
-
logModuleLoaded('
|
|
10
|
-
export class
|
|
10
|
+
logModuleLoaded('ThreadsWrapper');
|
|
11
|
+
export class ThreadsWrapper extends EventEmitter {
|
|
11
12
|
name;
|
|
12
|
-
|
|
13
|
+
entrypoint;
|
|
13
14
|
debug = hasAnyParameter('debug', 'verbose', 'debug-threads', 'verbose-threads');
|
|
14
15
|
verbose = hasAnyParameter('verbose', 'verbose-threads');
|
|
15
16
|
useTracker = hasAnyParameter('tracker', 'tracker-threads');
|
|
@@ -24,9 +25,10 @@ export class WorkerWrapper {
|
|
|
24
25
|
boundUncaughtExceptionHandler = (error) => {
|
|
25
26
|
this.handleUncaughtException(error);
|
|
26
27
|
};
|
|
27
|
-
constructor(name,
|
|
28
|
+
constructor(name, entrypoint) {
|
|
29
|
+
super();
|
|
28
30
|
this.name = name;
|
|
29
|
-
this.
|
|
31
|
+
this.entrypoint = entrypoint;
|
|
30
32
|
if (this.workerData) {
|
|
31
33
|
this.debug = this.workerData.debug ?? this.debug;
|
|
32
34
|
this.verbose = this.workerData.verbose ?? this.verbose;
|
|
@@ -46,7 +48,7 @@ export class WorkerWrapper {
|
|
|
46
48
|
return;
|
|
47
49
|
})
|
|
48
50
|
.catch((err) => {
|
|
49
|
-
this.safeParentLog("error", `
|
|
51
|
+
this.safeParentLog("error", `ThreadsWrapper ${this.name}: failed to load Tracker ${getErrorMessage(err)}`);
|
|
50
52
|
return;
|
|
51
53
|
});
|
|
52
54
|
}
|
|
@@ -65,8 +67,11 @@ export class WorkerWrapper {
|
|
|
65
67
|
this.parentPost({ type: 'pong', threadId, threadName: this.name });
|
|
66
68
|
this.parentLog(this.name, "debug", `Worker ${this.name}:${threadId} sent pong message type to parent: ${debugStringify(message)}`);
|
|
67
69
|
break;
|
|
68
|
-
case '
|
|
69
|
-
|
|
70
|
+
case 'startup':
|
|
71
|
+
setImmediate(() => this.emit('startup'));
|
|
72
|
+
break;
|
|
73
|
+
case 'shutdown':
|
|
74
|
+
setImmediate(() => this.emit('shutdown'));
|
|
70
75
|
break;
|
|
71
76
|
default:
|
|
72
77
|
this.parentLog(this.name, "warn", `Worker ${this.name}:${threadId} received unknown message type from parent: ${debugStringify(message)}`);
|
|
@@ -89,10 +94,10 @@ export class WorkerWrapper {
|
|
|
89
94
|
void (async () => {
|
|
90
95
|
let success = false;
|
|
91
96
|
try {
|
|
92
|
-
success = await
|
|
97
|
+
success = await entrypoint(this);
|
|
93
98
|
}
|
|
94
99
|
catch (err) {
|
|
95
|
-
inspectError(this.log, `Worker ${this.name}
|
|
100
|
+
inspectError(this.log, `Worker ${this.name} entrypoint failed`, err);
|
|
96
101
|
}
|
|
97
102
|
finally {
|
|
98
103
|
if (!success || this.workerData?.type !== 'thread')
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
declare const _default:
|
|
1
|
+
import { ThreadsWrapper } from './threadsWrapper.js';
|
|
2
|
+
declare const _default: ThreadsWrapper;
|
|
3
3
|
export default _default;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { isArchiveWorkerData } from '@matterbridge/types';
|
|
2
2
|
import { logModuleLoaded } from '@matterbridge/utils/loader';
|
|
3
|
-
import {
|
|
3
|
+
import { ThreadsWrapper } from './threadsWrapper.js';
|
|
4
4
|
import { createZip, readZip, unZip } from './zipjs.js';
|
|
5
5
|
logModuleLoaded('ArchiveCommand', '\u001B[35m');
|
|
6
|
-
export default new
|
|
6
|
+
export default new ThreadsWrapper('ArchiveCommand', async (worker) => {
|
|
7
7
|
if (!isArchiveWorkerData(worker.workerData)) {
|
|
8
8
|
worker.logger("error", `ArchiveCommand invalid parameters`);
|
|
9
9
|
return false;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
declare const _default:
|
|
1
|
+
import { ThreadsWrapper } from './threadsWrapper.js';
|
|
2
|
+
declare const _default: ThreadsWrapper;
|
|
3
3
|
export default _default;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { inspectError } from '@matterbridge/utils/error';
|
|
2
2
|
import { logModuleLoaded } from '@matterbridge/utils/loader';
|
|
3
3
|
import { checkUpdates } from './checkUpdates.js';
|
|
4
|
-
import {
|
|
4
|
+
import { ThreadsWrapper } from './threadsWrapper.js';
|
|
5
5
|
logModuleLoaded('CheckUpdates', '\u001B[35m');
|
|
6
|
-
export default new
|
|
6
|
+
export default new ThreadsWrapper('CheckUpdates', async (worker) => {
|
|
7
7
|
worker.logger("info", `Starting check updates...`);
|
|
8
8
|
let success = false;
|
|
9
9
|
try {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
declare const _default:
|
|
1
|
+
import { ThreadsWrapper } from './threadsWrapper.js';
|
|
2
|
+
declare const _default: ThreadsWrapper;
|
|
3
3
|
export default _default;
|
|
@@ -3,9 +3,9 @@ import { inspectError } from '@matterbridge/utils/error';
|
|
|
3
3
|
import { logModuleLoaded } from '@matterbridge/utils/loader';
|
|
4
4
|
import { debugStringify } from 'node-ansi-logger';
|
|
5
5
|
import { getDockerVersion, takeDockerVersionWarning } from './dockerVersion.js';
|
|
6
|
-
import {
|
|
6
|
+
import { ThreadsWrapper } from './threadsWrapper.js';
|
|
7
7
|
logModuleLoaded('DockerVersion', '\u001B[35m');
|
|
8
|
-
export default new
|
|
8
|
+
export default new ThreadsWrapper('DockerVersion', async (worker) => {
|
|
9
9
|
worker.logger("info", `Starting docker version check...`);
|
|
10
10
|
let success = false;
|
|
11
11
|
let dockerBuildConfig;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
declare const _default:
|
|
1
|
+
import { ThreadsWrapper } from './threadsWrapper.js';
|
|
2
|
+
declare const _default: ThreadsWrapper;
|
|
3
3
|
export default _default;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { inspectError } from '@matterbridge/utils/error';
|
|
2
2
|
import { logModuleLoaded } from '@matterbridge/utils/loader';
|
|
3
3
|
import { getGlobalNodeModules } from '@matterbridge/utils/npm-prefix';
|
|
4
|
-
import {
|
|
4
|
+
import { ThreadsWrapper } from './threadsWrapper.js';
|
|
5
5
|
logModuleLoaded('GlobalPrefix', '\u001B[35m');
|
|
6
|
-
export default new
|
|
6
|
+
export default new ThreadsWrapper('GlobalPrefix', async (worker) => {
|
|
7
7
|
let prefix;
|
|
8
8
|
worker.logger("info", `Starting global prefix check...`);
|
|
9
9
|
let success = false;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
declare const _default:
|
|
1
|
+
import { ThreadsWrapper } from './threadsWrapper.js';
|
|
2
|
+
declare const _default: ThreadsWrapper;
|
|
3
3
|
export default _default;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { isSpawnWorkerData } from '@matterbridge/types';
|
|
2
2
|
import { logModuleLoaded } from '@matterbridge/utils/loader';
|
|
3
3
|
import { spawnCommand } from './spawnCommand.js';
|
|
4
|
-
import {
|
|
4
|
+
import { ThreadsWrapper } from './threadsWrapper.js';
|
|
5
5
|
logModuleLoaded('SpawnCommand', '\u001B[35m');
|
|
6
|
-
export default new
|
|
6
|
+
export default new ThreadsWrapper('SpawnCommand', async (worker) => {
|
|
7
7
|
if (!isSpawnWorkerData(worker.workerData)) {
|
|
8
8
|
worker.logger("error", `SpawnCommand invalid parameters`);
|
|
9
9
|
return false;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
declare const _default:
|
|
1
|
+
import { ThreadsWrapper } from './threadsWrapper.js';
|
|
2
|
+
declare const _default: ThreadsWrapper;
|
|
3
3
|
export default _default;
|
|
@@ -3,9 +3,9 @@ import { getBunLatestVersion, getBunVersion, isBun } from '@matterbridge/utils/b
|
|
|
3
3
|
import { inspectError } from '@matterbridge/utils/error';
|
|
4
4
|
import { logModuleLoaded } from '@matterbridge/utils/loader';
|
|
5
5
|
import { excludedInterfaceNamePattern } from '@matterbridge/utils/network';
|
|
6
|
-
import {
|
|
6
|
+
import { ThreadsWrapper } from './threadsWrapper.js';
|
|
7
7
|
logModuleLoaded('SystemCheck', '\u001B[35m');
|
|
8
|
-
export default new
|
|
8
|
+
export default new ThreadsWrapper('SystemCheck', async (worker) => {
|
|
9
9
|
worker.logger("info", `Starting system check...`);
|
|
10
10
|
let success = false;
|
|
11
11
|
try {
|
package/dist/zipjs.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { mkdir, readdir, readFile, stat, writeFile } from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { Uint8ArrayReader, Uint8ArrayWriter, ZipReader, ZipWriter } from '@zip.js/zip.js';
|
|
3
|
+
import { configure, Uint8ArrayReader, Uint8ArrayWriter, ZipReader, ZipWriter } from '@zip.js/zip.js';
|
|
4
4
|
import { AnsiLogger } from 'node-ansi-logger';
|
|
5
|
+
configure({ useWebWorkers: false });
|
|
5
6
|
export async function createZip(zipPath, sourcePaths) {
|
|
6
7
|
if (sourcePaths.length === 0)
|
|
7
8
|
throw new Error('No files or directories provided to createZip.');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matterbridge/thread",
|
|
3
|
-
"version": "3.10.13-dev-
|
|
3
|
+
"version": "3.10.13-dev-20261008-55d98fb",
|
|
4
4
|
"description": "Matterbridge thread library",
|
|
5
5
|
"author": "https://github.com/Luligu",
|
|
6
6
|
"homepage": "https://matterbridge.io/",
|
|
@@ -57,6 +57,10 @@
|
|
|
57
57
|
"./manager": {
|
|
58
58
|
"types": "./dist/threadsManager.d.ts",
|
|
59
59
|
"import": "./dist/threadsManager.js"
|
|
60
|
+
},
|
|
61
|
+
"./wrapper": {
|
|
62
|
+
"types": "./dist/threadsWrapper.d.ts",
|
|
63
|
+
"import": "./dist/threadsWrapper.js"
|
|
60
64
|
}
|
|
61
65
|
},
|
|
62
66
|
"engines": {
|
|
@@ -76,15 +80,9 @@
|
|
|
76
80
|
},
|
|
77
81
|
"dependencies": {
|
|
78
82
|
"@matter/main": "0.17.9",
|
|
79
|
-
"@matterbridge/types": "3.10.13-dev-
|
|
80
|
-
"@matterbridge/utils": "3.10.13-dev-
|
|
83
|
+
"@matterbridge/types": "3.10.13-dev-20261008-55d98fb",
|
|
84
|
+
"@matterbridge/utils": "3.10.13-dev-20261008-55d98fb",
|
|
81
85
|
"@zip.js/zip.js": "2.22.0",
|
|
82
|
-
"
|
|
83
|
-
"express": "5.2.1",
|
|
84
|
-
"express-rate-limit": "8.7.0",
|
|
85
|
-
"multer": "2.4.0",
|
|
86
|
-
"node-ansi-logger": "3.3.1",
|
|
87
|
-
"node-persist-manager": "2.1.1",
|
|
88
|
-
"ws": "8.22.0"
|
|
86
|
+
"node-ansi-logger": "3.3.1"
|
|
89
87
|
}
|
|
90
88
|
}
|
package/dist/backend.d.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import EventEmitter from 'node:events';
|
|
2
|
-
import { type ApiClusters, type ApiDevice, type ApiPlugin, type ApiSettings, type SharedMatterbridge, type ApiMatter } from '@matterbridge/types';
|
|
3
|
-
import type { BackendExpress } from './backendExpress.js';
|
|
4
|
-
import type { BackendWsServer } from './backendWsServer.js';
|
|
5
|
-
interface BackendEvents {
|
|
6
|
-
server_listening: [protocol: string, port: number, address?: string];
|
|
7
|
-
server_error: [error: unknown];
|
|
8
|
-
server_stopped: [];
|
|
9
|
-
websocket_server_listening: [protocol: string];
|
|
10
|
-
websocket_server_stopped: [];
|
|
11
|
-
}
|
|
12
|
-
export declare class Backend extends EventEmitter<BackendEvents> {
|
|
13
|
-
private debug;
|
|
14
|
-
private verbose;
|
|
15
|
-
private diagnostic;
|
|
16
|
-
private log;
|
|
17
|
-
private matterbridge;
|
|
18
|
-
private readonly server;
|
|
19
|
-
private port;
|
|
20
|
-
private listening;
|
|
21
|
-
private httpServer;
|
|
22
|
-
private httpsServer;
|
|
23
|
-
readonly secure: boolean;
|
|
24
|
-
readonly requestCert: boolean;
|
|
25
|
-
backendExpress: BackendExpress | undefined;
|
|
26
|
-
backendWsServer: BackendWsServer | undefined;
|
|
27
|
-
storedPassword: string | undefined;
|
|
28
|
-
authClients: Set<string>;
|
|
29
|
-
authClientsTimeout: NodeJS.Timeout | undefined;
|
|
30
|
-
constructor(matterbridge: SharedMatterbridge);
|
|
31
|
-
destroy(): void;
|
|
32
|
-
private broadcastMsgHandler;
|
|
33
|
-
start(port?: number): Promise<void>;
|
|
34
|
-
stop(): Promise<void>;
|
|
35
|
-
getApiSettings(): Promise<ApiSettings>;
|
|
36
|
-
getApiPlugins(): Promise<ApiPlugin[]>;
|
|
37
|
-
getApiDevices(pluginName?: string): Promise<ApiDevice[]>;
|
|
38
|
-
getApiCluster(pluginName: string, endpointNumber: number, serialNumber?: string, uniqueId?: string): Promise<ApiClusters | undefined>;
|
|
39
|
-
generateDiagnostic(): Promise<void>;
|
|
40
|
-
getApiMatter(id: string): Promise<ApiMatter | undefined>;
|
|
41
|
-
}
|
|
42
|
-
export {};
|