@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.
@@ -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;
@@ -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
- 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}`);
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
- if (thread.worker && Date.now() - (thread.lastSeen ?? 0) > this.intervalMs) {
112
- const msg = { type: 'ping', threadId: thread.worker.threadId, threadName: thread.name };
113
- thread.worker.postMessage(msg);
114
- }
115
- if (thread.worker && Date.now() - (thread.lastSeen ?? 0) > this.intervalMs * 2) {
116
- this.log.warn(`Thread ${CYAN}${thread.name}${db} has not been seen for more than ${this.intervalMs * 2} ms. It may be unresponsive.`);
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
- threadInfo.worker = this.createESMWorker(threadInfo.name, path, { ...workerData, type: threadInfo.type, debug: this.debug, verbose: this.verbose, logLevel: this.log.logLevel }, argv, env, execArgv, pipedOutput);
137
- const worker = threadInfo.worker;
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
- if (threadInfo.worker === worker) {
145
- threadInfo.lastSeen = now;
146
- threadInfo.lastStopped = now;
147
- threadInfo.lastDuration = Math.max(0, now - (threadInfo.lastStarted ?? now));
148
- threadInfo.worker = undefined;
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.lastSeen = now;
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 === 'log') {
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.worker = undefined;
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.lastSeen = now;
180
- threadInfo.errorCount = (threadInfo.errorCount ?? 0) + 1;
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.lastSeen = now;
186
- threadInfo.lastStopped = now;
187
- threadInfo.lastDuration = Math.max(0, now - (threadInfo.lastStarted ?? now));
188
- threadInfo.errorCount = (threadInfo.errorCount ?? 0) + 1;
189
- threadInfo.worker = undefined;
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 ${threadInfo.lastDuration} ms: ${getErrorMessage(error)}`);
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 threadInfo.worker;
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 workerWrapper = (await import(this.resolvePath(threadInfo.path))).default;
204
- if (workerWrapper && typeof workerWrapper === 'object' && workerWrapper.name === name && workerWrapper.callback && typeof workerWrapper.callback === 'function') {
205
- workerWrapper.workerData = workerData ? { ...workerData, type: threadInfo.type } : null;
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 workerWrapper.callback(workerWrapper);
265
+ success = await threadsWrapper.entrypoint(threadsWrapper);
208
266
  }
209
267
  finally {
210
268
  if (!success || threadInfo.type !== 'thread')
211
- workerWrapper.destroy(success);
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 currentModuleDirectory = path.dirname(fileURLToPath(import.meta.url));
276
+ const threadDirectory = path.dirname(fileURLToPath(import.meta.url));
219
277
  const candidates = [
220
- path.join(currentModuleDirectory, fileName),
221
- path.join(currentModuleDirectory, '..', 'dist', fileName),
222
- path.join(currentModuleDirectory, '..', 'src', fileName.replace(/\.js$/, '.ts')),
223
- path.join(currentModuleDirectory, 'workers', fileName),
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 declare class WorkerWrapper {
6
+ export interface ThreadsWrapperEvents {
7
+ startup: [];
8
+ shutdown: [];
9
+ }
10
+ export declare class ThreadsWrapper extends EventEmitter<ThreadsWrapperEvents> {
6
11
  name: ThreadNames;
7
- callback: (worker: WorkerWrapper) => Promise<boolean>;
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, callback: (worker: WorkerWrapper) => Promise<boolean>);
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('WorkerWrapper');
10
- export class WorkerWrapper {
10
+ logModuleLoaded('ThreadsWrapper');
11
+ export class ThreadsWrapper extends EventEmitter {
11
12
  name;
12
- callback;
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, callback) {
28
+ constructor(name, entrypoint) {
29
+ super();
28
30
  this.name = name;
29
- this.callback = callback;
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", `WorkerWrapper ${this.name}: failed to load Tracker ${getErrorMessage(err)}`);
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 'pong':
69
- this.parentLog(this.name, "debug", `Worker ${this.name}:${threadId} received pong message type from parent: ${debugStringify(message)}`);
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 callback(this);
97
+ success = await entrypoint(this);
93
98
  }
94
99
  catch (err) {
95
- inspectError(this.log, `Worker ${this.name} callback failed`, err);
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 { WorkerWrapper } from './workerWrapper.js';
2
- declare const _default: WorkerWrapper;
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 { WorkerWrapper } from './workerWrapper.js';
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 WorkerWrapper('ArchiveCommand', async (worker) => {
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 { WorkerWrapper } from './workerWrapper.js';
2
- declare const _default: WorkerWrapper;
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 { WorkerWrapper } from './workerWrapper.js';
4
+ import { ThreadsWrapper } from './threadsWrapper.js';
5
5
  logModuleLoaded('CheckUpdates', '\u001B[35m');
6
- export default new WorkerWrapper('CheckUpdates', async (worker) => {
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 { WorkerWrapper } from './workerWrapper.js';
2
- declare const _default: WorkerWrapper;
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 { WorkerWrapper } from './workerWrapper.js';
6
+ import { ThreadsWrapper } from './threadsWrapper.js';
7
7
  logModuleLoaded('DockerVersion', '\u001B[35m');
8
- export default new WorkerWrapper('DockerVersion', async (worker) => {
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 { WorkerWrapper } from './workerWrapper.js';
2
- declare const _default: WorkerWrapper;
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 { WorkerWrapper } from './workerWrapper.js';
4
+ import { ThreadsWrapper } from './threadsWrapper.js';
5
5
  logModuleLoaded('GlobalPrefix', '\u001B[35m');
6
- export default new WorkerWrapper('GlobalPrefix', async (worker) => {
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 { WorkerWrapper } from './workerWrapper.js';
2
- declare const _default: WorkerWrapper;
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 { WorkerWrapper } from './workerWrapper.js';
4
+ import { ThreadsWrapper } from './threadsWrapper.js';
5
5
  logModuleLoaded('SpawnCommand', '\u001B[35m');
6
- export default new WorkerWrapper('SpawnCommand', async (worker) => {
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 { WorkerWrapper } from './workerWrapper.js';
2
- declare const _default: WorkerWrapper;
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 { WorkerWrapper } from './workerWrapper.js';
6
+ import { ThreadsWrapper } from './threadsWrapper.js';
7
7
  logModuleLoaded('SystemCheck', '\u001B[35m');
8
- export default new WorkerWrapper('SystemCheck', async (worker) => {
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-20261007-320f739",
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-20261007-320f739",
80
- "@matterbridge/utils": "3.10.13-dev-20261007-320f739",
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
- "escape-html": "1.0.3",
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 {};