@matterbridge/thread 3.5.3 → 3.5.4-dev-20260211-520e349

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/README.md CHANGED
@@ -19,4 +19,4 @@
19
19
 
20
20
  ---
21
21
 
22
- Matterbridge internal package (not intended for direct use).
22
+ [Matterbridge](https://matterbridge.io) internal package (not intended for direct use).
@@ -0,0 +1,29 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { AnsiLogger } from 'node-ansi-logger';
3
+ import type { WorkerMessage, WorkerMessageRequest, WorkerMessageRequestAny, WorkerMessageResponse, WorkerMessageResponseSuccess, WorkerMessageTypes, WorkerSrcType } from '@matterbridge/types';
4
+ interface BroadcastServerEvents {
5
+ broadcast_message: [msg: WorkerMessage];
6
+ }
7
+ export declare class BroadcastServer extends EventEmitter<BroadcastServerEvents> {
8
+ readonly name: WorkerSrcType;
9
+ private readonly log;
10
+ private readonly channel;
11
+ private readonly broadcastChannel;
12
+ private closed;
13
+ private readonly debug;
14
+ private readonly verbose;
15
+ constructor(name: WorkerSrcType, log: AnsiLogger, channel?: string);
16
+ close(): void;
17
+ private broadcastMessageHandler;
18
+ private broadcastMessageErrorHandler;
19
+ getUniqueId(): number;
20
+ isWorkerRequest(value: unknown): value is WorkerMessageRequest;
21
+ isWorkerRequestOfType<K extends keyof WorkerMessageTypes>(value: unknown, type: K): value is WorkerMessageRequest<K>;
22
+ isWorkerResponse(value: unknown): value is WorkerMessageResponse;
23
+ isWorkerResponseOfType<K extends keyof WorkerMessageTypes>(value: unknown, type: K): value is WorkerMessageResponse<K>;
24
+ broadcast(message: WorkerMessage): void;
25
+ request<K extends keyof WorkerMessageTypes>(message: WorkerMessageRequest<K>): void;
26
+ respond<K extends keyof WorkerMessageTypes>(message: WorkerMessageResponse<K>): void;
27
+ fetch<T extends WorkerMessageRequestAny, K extends Extract<keyof WorkerMessageTypes, T['type']>>(message: T, timeout?: number): Promise<WorkerMessageResponseSuccess<K>>;
28
+ }
29
+ export {};
@@ -0,0 +1,198 @@
1
+ if (process.argv.includes('--loader') || process.argv.includes('-loader'))
2
+ console.log('\u001B[32mBroadcastServer loaded.\u001B[40;0m');
3
+ import { EventEmitter } from 'node:events';
4
+ import { BroadcastChannel } from 'node:worker_threads';
5
+ import { CYAN, db, debugStringify, er } from 'node-ansi-logger';
6
+ import { hasParameter, logError } from '@matterbridge/utils';
7
+ export class BroadcastServer extends EventEmitter {
8
+ name;
9
+ log;
10
+ channel;
11
+ broadcastChannel;
12
+ closed = false;
13
+ debug = hasParameter('debug') || hasParameter('verbose');
14
+ verbose = hasParameter('verbose');
15
+ constructor(name, log, channel = 'broadcast-channel') {
16
+ super();
17
+ this.name = name;
18
+ this.log = log;
19
+ this.channel = channel;
20
+ this.broadcastChannel = new BroadcastChannel(this.channel);
21
+ this.broadcastChannel.onmessage = this.broadcastMessageHandler.bind(this);
22
+ this.broadcastChannel.onmessageerror = this.broadcastMessageErrorHandler.bind(this);
23
+ }
24
+ close() {
25
+ this.broadcastChannel.onmessage = null;
26
+ this.broadcastChannel.onmessageerror = null;
27
+ this.broadcastChannel.close();
28
+ this.closed = true;
29
+ }
30
+ broadcastMessageHandler(event) {
31
+ const msg = event.data;
32
+ if (msg.dst === this.name || msg.dst === 'all') {
33
+ if (this.verbose)
34
+ this.log.debug(`Server ${CYAN}${this.name}${db} received broadcast message: ${debugStringify(msg)}`);
35
+ this.emit('broadcast_message', msg);
36
+ }
37
+ else {
38
+ if (this.verbose)
39
+ this.log.debug(`Server ${CYAN}${this.name}${db} received unrelated broadcast message: ${debugStringify(msg)}`);
40
+ }
41
+ }
42
+ broadcastMessageErrorHandler(event) {
43
+ const msg = event.data;
44
+ this.log.error(`Server ${CYAN}${this.name}${db} received message error: ${debugStringify(msg)}`);
45
+ }
46
+ getUniqueId() {
47
+ return Math.floor(Math.random() * 900000000) + 100000000;
48
+ }
49
+ isWorkerRequest(value) {
50
+ if (typeof value !== 'object' || value === null) {
51
+ return false;
52
+ }
53
+ const message = value;
54
+ if (typeof message.type !== 'string' ||
55
+ typeof message.src !== 'string' ||
56
+ typeof message.dst !== 'string' ||
57
+ typeof message.id !== 'number' ||
58
+ typeof message.timestamp !== 'number') {
59
+ return false;
60
+ }
61
+ return message.result === undefined && message.error === undefined;
62
+ }
63
+ isWorkerRequestOfType(value, type) {
64
+ return this.isWorkerRequest(value) && value.type === type;
65
+ }
66
+ isWorkerResponse(value) {
67
+ if (typeof value !== 'object' || value === null) {
68
+ return false;
69
+ }
70
+ const message = value;
71
+ if (typeof message.type !== 'string' ||
72
+ typeof message.src !== 'string' ||
73
+ typeof message.dst !== 'string' ||
74
+ typeof message.id !== 'number' ||
75
+ typeof message.timestamp !== 'number') {
76
+ return false;
77
+ }
78
+ const hasError = typeof message.error === 'string';
79
+ const hasResult = message.result !== undefined;
80
+ return hasError !== hasResult;
81
+ }
82
+ isWorkerResponseOfType(value, type) {
83
+ return this.isWorkerResponse(value) && value.type === type;
84
+ }
85
+ broadcast(message) {
86
+ if (this.closed) {
87
+ this.log.error('Broadcast channel is closed');
88
+ return;
89
+ }
90
+ if (message.id === undefined) {
91
+ message.id = this.getUniqueId();
92
+ }
93
+ if (message.timestamp === undefined) {
94
+ message.timestamp = Date.now();
95
+ }
96
+ message.src = this.name;
97
+ if (this.verbose)
98
+ this.log.debug(`Broadcasting message: ${debugStringify(message)}`);
99
+ try {
100
+ this.broadcastChannel.postMessage(message);
101
+ }
102
+ catch (error) {
103
+ logError(this.log, `Failed to broadcast message ${debugStringify(message)}${er}`, error);
104
+ }
105
+ }
106
+ request(message) {
107
+ if (this.closed) {
108
+ this.log.error('Broadcast channel is closed');
109
+ return;
110
+ }
111
+ if (message.id === undefined) {
112
+ message.id = this.getUniqueId();
113
+ }
114
+ if (message.timestamp === undefined) {
115
+ message.timestamp = Date.now();
116
+ }
117
+ message.src = this.name;
118
+ if (!this.isWorkerRequest(message)) {
119
+ this.log.error(`Invalid request message format: ${debugStringify(message)}`);
120
+ return;
121
+ }
122
+ if (this.verbose)
123
+ this.log.debug(`Broadcasting request message: ${debugStringify(message)}`);
124
+ try {
125
+ this.broadcastChannel.postMessage(message);
126
+ }
127
+ catch (error) {
128
+ logError(this.log, `Failed to broadcast request message ${debugStringify(message)}${er}`, error);
129
+ }
130
+ }
131
+ respond(message) {
132
+ if (this.closed) {
133
+ this.log.error('Broadcast channel is closed');
134
+ return;
135
+ }
136
+ if (typeof message.timestamp === 'number') {
137
+ message.elapsed = Date.now() - message.timestamp;
138
+ }
139
+ if (message.timestamp === undefined) {
140
+ message.timestamp = Date.now();
141
+ }
142
+ if (message.dst === this.name || message.dst === 'all') {
143
+ message.dst = message.src;
144
+ }
145
+ message.src = this.name;
146
+ if (!this.isWorkerResponse(message)) {
147
+ this.log.error(`Invalid response message format: ${debugStringify(message)}`);
148
+ return;
149
+ }
150
+ if (this.verbose)
151
+ this.log.debug(`Broadcasting response message: ${debugStringify(message)}`);
152
+ try {
153
+ this.broadcastChannel.postMessage(message);
154
+ }
155
+ catch (error) {
156
+ logError(this.log, `Failed to broadcast response message ${debugStringify(message)}${er}`, error);
157
+ }
158
+ }
159
+ async fetch(message, timeout = 250) {
160
+ if (this.closed) {
161
+ return Promise.reject(new Error('Broadcast channel is closed'));
162
+ }
163
+ if (message.id === undefined) {
164
+ message.id = this.getUniqueId();
165
+ }
166
+ if (message.timestamp === undefined) {
167
+ message.timestamp = Date.now();
168
+ }
169
+ if (this.verbose)
170
+ this.log.debug(`Fetching message: ${debugStringify(message)}`);
171
+ return new Promise((resolve, reject) => {
172
+ const responseHandler = (msg) => {
173
+ if (this.isWorkerResponseOfType(msg, message.type) && msg.id === message.id) {
174
+ clearTimeout(timeoutId);
175
+ this.off('broadcast_message', responseHandler);
176
+ if (this.verbose)
177
+ this.log.debug(`Fetch response: ${debugStringify(msg)}`);
178
+ if ('error' in msg && typeof msg.error === 'string') {
179
+ reject(new Error(`Fetch received error response ${msg.error} to message type ${message.type} id ${message.id} from ${message.src} to ${message.dst}`));
180
+ }
181
+ else if ('result' in msg) {
182
+ resolve(msg);
183
+ }
184
+ else {
185
+ reject(new Error(`Fetch received malformed response for message type ${message.type} id ${message.id} from ${message.src} to ${message.dst}`));
186
+ }
187
+ return;
188
+ }
189
+ };
190
+ this.on('broadcast_message', responseHandler);
191
+ this.request(message);
192
+ const timeoutId = setTimeout(() => {
193
+ this.off('broadcast_message', responseHandler);
194
+ reject(new Error(`Fetch timeout after ${timeout}ms for message type ${message.type} id ${message.id} from ${message.src} to ${message.dst}`));
195
+ }, timeout);
196
+ });
197
+ }
198
+ }
@@ -0,0 +1,9 @@
1
+ import { AnsiLogger } from 'node-ansi-logger';
2
+ import type { ApiPlugin, SharedMatterbridge } from '@matterbridge/types';
3
+ import { BroadcastServer } from './broadcastServer.js';
4
+ export declare function checkUpdates(matterbridge: SharedMatterbridge): Promise<void>;
5
+ export declare function checkUpdatesAndLog(matterbridge: SharedMatterbridge, log: AnsiLogger, server: BroadcastServer): Promise<void>;
6
+ export declare function getMatterbridgeLatestVersion(matterbridge: SharedMatterbridge, log: AnsiLogger, server: BroadcastServer): Promise<string | undefined>;
7
+ export declare function getMatterbridgeDevVersion(matterbridge: SharedMatterbridge, log: AnsiLogger, server: BroadcastServer): Promise<string | undefined>;
8
+ export declare function getPluginLatestVersion(log: AnsiLogger, server: BroadcastServer, plugin: ApiPlugin): Promise<string | undefined>;
9
+ export declare function getPluginDevVersion(log: AnsiLogger, server: BroadcastServer, plugin: ApiPlugin): Promise<string | undefined>;
@@ -0,0 +1,139 @@
1
+ import { AnsiLogger, db, debugStringify, nt, wr } from 'node-ansi-logger';
2
+ import { isValidString } from '@matterbridge/utils';
3
+ import { plg } from '@matterbridge/types';
4
+ import { BroadcastServer } from './broadcastServer.js';
5
+ export async function checkUpdates(matterbridge) {
6
+ const log = new AnsiLogger({ logName: 'MatterbridgeUpdates', logTimestampFormat: 4, logLevel: matterbridge.logLevel });
7
+ const server = new BroadcastServer('updates', log);
8
+ const checkUpdatePromise = checkUpdatesAndLog(matterbridge, log, server);
9
+ const latestVersionPromise = getMatterbridgeLatestVersion(matterbridge, log, server);
10
+ const devVersionPromise = getMatterbridgeDevVersion(matterbridge, log, server);
11
+ const pluginsVersionPromises = [];
12
+ const pluginsDevVersionPromises = [];
13
+ try {
14
+ const plugins = (await server.fetch({ type: 'plugins_apipluginarray', src: server.name, dst: 'plugins' }, 1000)).result.plugins;
15
+ for (const plugin of plugins) {
16
+ pluginsVersionPromises.push(getPluginLatestVersion(log, server, plugin));
17
+ pluginsDevVersionPromises.push(getPluginDevVersion(log, server, plugin));
18
+ }
19
+ }
20
+ catch (error) {
21
+ log.debug(`Error fetching plugins for update check: ${error instanceof Error ? error.message : error}`);
22
+ }
23
+ await Promise.all([checkUpdatePromise, latestVersionPromise, devVersionPromise, ...pluginsVersionPromises, ...pluginsDevVersionPromises]);
24
+ server.close();
25
+ }
26
+ export async function checkUpdatesAndLog(matterbridge, log, server) {
27
+ const { getGitHubUpdate } = await import('@matterbridge/utils');
28
+ const branch = matterbridge.matterbridgeVersion.includes('-dev-') ? 'dev' : 'main';
29
+ try {
30
+ const updateJson = await getGitHubUpdate(branch, 'update.json', 5_000);
31
+ log.debug(`GitHub ${branch} update status: ${debugStringify(updateJson)}.`);
32
+ if (isValidString(branch === 'main' ? updateJson.latestMessage : updateJson.devMessage, 1) &&
33
+ isValidString(branch === 'main' ? updateJson.latestMessageSeverity : updateJson.devMessageSeverity, 4) &&
34
+ ['info', 'warning', 'error', 'success'].includes(branch === 'main' ? updateJson.latestMessageSeverity : updateJson.devMessageSeverity)) {
35
+ log.notice(`GitHub ${branch} update message: ${branch === 'main' ? updateJson.latestMessage : updateJson.devMessage}`);
36
+ server.request({
37
+ type: 'frontend_snackbarmessage',
38
+ src: server.name,
39
+ dst: 'frontend',
40
+ params: {
41
+ message: branch === 'main' ? updateJson.latestMessage : updateJson.devMessage,
42
+ timeout: 0,
43
+ severity: branch === 'main' ? updateJson.latestMessageSeverity : updateJson.devMessageSeverity,
44
+ },
45
+ });
46
+ }
47
+ }
48
+ catch (error) {
49
+ log.debug(`Error checking GitHub ${branch} updates: ${error instanceof Error ? error.message : error}`);
50
+ }
51
+ }
52
+ export async function getMatterbridgeLatestVersion(matterbridge, log, server) {
53
+ const { getNpmPackageVersion } = await import('@matterbridge/utils');
54
+ try {
55
+ const version = await getNpmPackageVersion('matterbridge');
56
+ server.request({ type: 'matterbridge_latest_version', src: server.name, dst: 'matterbridge', params: { version } });
57
+ if (matterbridge.matterbridgeVersion !== version) {
58
+ log.notice(`Matterbridge is out of date. Current version: ${matterbridge.matterbridgeVersion}. Latest version: ${version}.`);
59
+ server.request({
60
+ type: 'frontend_snackbarmessage',
61
+ src: server.name,
62
+ dst: 'frontend',
63
+ params: { message: 'Matterbridge latest update available', timeout: 0, severity: 'info' },
64
+ });
65
+ server.request({ type: 'frontend_updaterequired', src: server.name, dst: 'frontend', params: { devVersion: false } });
66
+ server.request({ type: 'frontend_refreshrequired', src: server.name, dst: 'frontend', params: { changed: 'settings' } });
67
+ }
68
+ else {
69
+ log.debug(`Matterbridge is up to date. Current version: ${matterbridge.matterbridgeVersion}. Latest version: ${version}.`);
70
+ }
71
+ return version;
72
+ }
73
+ catch (error) {
74
+ log.warn(`Error getting Matterbridge latest version: ${error instanceof Error ? error.message : error}`);
75
+ }
76
+ }
77
+ export async function getMatterbridgeDevVersion(matterbridge, log, server) {
78
+ const { getNpmPackageVersion } = await import('@matterbridge/utils');
79
+ try {
80
+ const version = await getNpmPackageVersion('matterbridge', 'dev');
81
+ server.request({ type: 'matterbridge_dev_version', src: server.name, dst: 'matterbridge', params: { version } });
82
+ if ((matterbridge.matterbridgeVersion.includes('-dev-') || matterbridge.matterbridgeVersion.includes('-git-')) && matterbridge.matterbridgeVersion !== version) {
83
+ log.notice(`Matterbridge@dev is out of date. Current version: ${matterbridge.matterbridgeVersion}. Latest dev version: ${version}.`);
84
+ server.request({
85
+ type: 'frontend_snackbarmessage',
86
+ src: server.name,
87
+ dst: 'frontend',
88
+ params: { message: 'Matterbridge dev update available', timeout: 0, severity: 'info' },
89
+ });
90
+ server.request({ type: 'frontend_updaterequired', src: server.name, dst: 'frontend', params: { devVersion: true } });
91
+ server.request({ type: 'frontend_refreshrequired', src: server.name, dst: 'frontend', params: { changed: 'settings' } });
92
+ }
93
+ else if ((matterbridge.matterbridgeVersion.includes('-dev-') || matterbridge.matterbridgeVersion.includes('-git-')) && matterbridge.matterbridgeVersion === version) {
94
+ log.debug(`Matterbridge@dev is up to date. Current version: ${matterbridge.matterbridgeVersion}. Latest dev version: ${version}.`);
95
+ }
96
+ return version;
97
+ }
98
+ catch (error) {
99
+ log.warn(`Error getting Matterbridge latest dev version: ${error instanceof Error ? error.message : error}`);
100
+ }
101
+ }
102
+ export async function getPluginLatestVersion(log, server, plugin) {
103
+ const { getNpmPackageVersion } = await import('@matterbridge/utils');
104
+ try {
105
+ const version = await getNpmPackageVersion(plugin.name);
106
+ plugin.latestVersion = version;
107
+ server.request({ type: 'plugins_set_latest_version', src: server.name, dst: 'plugins', params: { plugin, version } });
108
+ if (plugin.version !== plugin.latestVersion) {
109
+ log.notice(`The plugin ${plg}${plugin.name}${nt} is out of date. Current version: ${plugin.version}. Latest version: ${plugin.latestVersion}.`);
110
+ server.request({ type: 'frontend_refreshrequired', src: server.name, dst: 'frontend', params: { changed: 'plugins' } });
111
+ }
112
+ else {
113
+ log.debug(`The plugin ${plg}${plugin.name}${db} is up to date. Current version: ${plugin.version}. Latest version: ${plugin.latestVersion}.`);
114
+ }
115
+ return version;
116
+ }
117
+ catch (error) {
118
+ log.warn(`Error getting plugin ${plg}${plugin.name}${wr} latest version: ${error instanceof Error ? error.message : error}`);
119
+ }
120
+ }
121
+ export async function getPluginDevVersion(log, server, plugin) {
122
+ const { getNpmPackageVersion } = await import('@matterbridge/utils');
123
+ try {
124
+ const version = await getNpmPackageVersion(plugin.name, 'dev');
125
+ plugin.devVersion = version;
126
+ server.request({ type: 'plugins_set_dev_version', src: server.name, dst: 'plugins', params: { plugin, version } });
127
+ if ((plugin.version.includes('-dev-') || plugin.version.includes('-git-')) && plugin.version !== plugin.devVersion) {
128
+ log.notice(`The plugin ${plg}${plugin.name}${nt} is out of date. Current version: ${plugin.version}. Latest dev version: ${plugin.devVersion}.`);
129
+ server.request({ type: 'frontend_refreshrequired', src: server.name, dst: 'frontend', params: { changed: 'plugins' } });
130
+ }
131
+ else if (plugin.version.includes('-dev-') && plugin.version === plugin.devVersion) {
132
+ log.debug(`The plugin ${plg}${plugin.name}${db} is up to date. Current version: ${plugin.version}. Latest dev version: ${plugin.devVersion}.`);
133
+ }
134
+ return version;
135
+ }
136
+ catch (error) {
137
+ log.debug(`Error getting plugin ${plg}${plugin.name}${db} latest dev version: ${error instanceof Error ? error.message : error}`);
138
+ }
139
+ }
package/dist/export.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export * from './worker.js';
2
- export * from './workerTypes.js';
2
+ export * from './broadcastServer.js';
package/dist/export.js CHANGED
@@ -1,2 +1,2 @@
1
1
  export * from './worker.js';
2
- export * from './workerTypes.js';
2
+ export * from './broadcastServer.js';
package/dist/worker.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Worker } from 'node:worker_threads';
2
2
  import { AnsiLogger, LogLevel } from 'node-ansi-logger';
3
- import type { ParentPortMessage } from './workerTypes.js';
3
+ import type { ParentPortMessage } from '@matterbridge/types';
4
4
  export declare function parentPost(message: ParentPortMessage): void;
5
5
  export declare function parentLog(logName: string | undefined, logLevel: LogLevel, message: string): void;
6
6
  export declare function createESMWorker(name: string, relativePath: string, workerData?: Record<string, boolean | number | string | object>, argv?: string[], env?: NodeJS.ProcessEnv, execArgv?: string[]): Worker;
package/dist/worker.js CHANGED
@@ -2,11 +2,11 @@ import { isMainThread, parentPort, threadId, Worker, workerData } from 'node:wor
2
2
  import { pathToFileURL } from 'node:url';
3
3
  import { resolve } from 'node:path';
4
4
  import { inspect } from 'node:util';
5
- import { AnsiLogger, debugStringify } from 'node-ansi-logger';
5
+ import { AnsiLogger, debugStringify, MAGENTA } from 'node-ansi-logger';
6
6
  import { hasParameter } from '@matterbridge/utils';
7
- const debug = hasParameter('debug') || hasParameter('verbose') || hasParameter('debug_worker') || hasParameter('verbose_worker');
8
- const verbose = hasParameter('verbose') || hasParameter('verbose_worker');
9
- const log = new AnsiLogger({ logName: 'Worker', logTimestampFormat: 4, logLevel: debug ? "debug" : "info" });
7
+ const debug = hasParameter('debug') || hasParameter('verbose') || hasParameter('debug-worker') || hasParameter('verbose-worker');
8
+ const verbose = hasParameter('verbose') || hasParameter('verbose-worker');
9
+ const log = new AnsiLogger({ logName: 'Worker', logNameColor: MAGENTA, logTimestampFormat: 4, logLevel: debug ? "debug" : "info" });
10
10
  export function parentPost(message) {
11
11
  if (!parentPort)
12
12
  throw new Error(`WorkerServer ${workerData.threadName}: parentPort is not available.`);
@@ -0,0 +1,42 @@
1
+ import { threadId, isMainThread, parentPort, workerData } from 'node:worker_threads';
2
+ import { AnsiLogger, MAGENTA } from 'node-ansi-logger';
3
+ import { hasParameter, inspectError } from '@matterbridge/utils';
4
+ import { checkUpdates } from './checkUpdates.js';
5
+ import { logWorkerInfo, parentLog, parentPost } from './worker.js';
6
+ import { BroadcastServer } from './broadcastServer.js';
7
+ const debug = hasParameter('debug') || hasParameter('verbose') || hasParameter('debug-worker') || hasParameter('verbose-worker');
8
+ const verbose = hasParameter('verbose') || hasParameter('verbose-worker');
9
+ if (!isMainThread && parentPort) {
10
+ parentPost({ type: 'init', threadId, threadName: workerData.threadName, success: true });
11
+ if (debug)
12
+ parentLog('MatterbridgeCheckUpdates', "info", `Worker ${workerData.threadName}:${threadId} initialized.`);
13
+ }
14
+ const log = new AnsiLogger({
15
+ logName: 'MatterbridgeCheckUpdates',
16
+ logNameColor: MAGENTA,
17
+ logTimestampFormat: 4,
18
+ logLevel: debug ? "debug" : "info",
19
+ });
20
+ const server = new BroadcastServer('matterbridge', log);
21
+ if (verbose)
22
+ logWorkerInfo(log, verbose);
23
+ let success = false;
24
+ try {
25
+ const shared = (await server.fetch({ type: 'matterbridge_shared', src: `matterbridge`, dst: 'matterbridge' })).result.data;
26
+ await checkUpdates(shared);
27
+ success = true;
28
+ log.debug(`Check updates succeeded`);
29
+ if (!isMainThread && parentPort)
30
+ parentLog('MatterbridgeCheckUpdates', "debug", `Check updates succeeded`);
31
+ }
32
+ catch (error) {
33
+ const errorMessage = inspectError(log, `Failed to check updates`, error);
34
+ if (!isMainThread && parentPort)
35
+ parentLog('MatterbridgeCheckUpdates', "error", errorMessage);
36
+ }
37
+ server.close();
38
+ if (!isMainThread && parentPort) {
39
+ parentPost({ type: 'exit', threadId, threadName: workerData.threadName, success });
40
+ if (debug)
41
+ parentLog('MatterbridgeCheckUpdates', "info", `Worker ${workerData.threadName}:${threadId} exiting with success: ${success}.`);
42
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,42 @@
1
+ import { threadId, isMainThread, parentPort, workerData } from 'node:worker_threads';
2
+ import { AnsiLogger, MAGENTA } from 'node-ansi-logger';
3
+ import { getGlobalNodeModules, hasParameter, inspectError } from '@matterbridge/utils';
4
+ import { logWorkerInfo, parentLog, parentPost } from './worker.js';
5
+ import { BroadcastServer } from './broadcastServer.js';
6
+ const debug = hasParameter('debug') || hasParameter('verbose') || hasParameter('debug-worker') || hasParameter('verbose-worker');
7
+ const verbose = hasParameter('verbose') || hasParameter('verbose-worker');
8
+ if (!isMainThread && parentPort) {
9
+ parentPost({ type: 'init', threadId, threadName: workerData.threadName, success: true });
10
+ if (debug)
11
+ parentLog('MatterbridgePrefix', "info", `Worker ${workerData.threadName}:${threadId} initialized.`);
12
+ }
13
+ const log = new AnsiLogger({
14
+ logName: 'MatterbridgePrefix',
15
+ logNameColor: MAGENTA,
16
+ logTimestampFormat: 4,
17
+ logLevel: debug ? "debug" : "info",
18
+ });
19
+ const server = new BroadcastServer('matterbridge', log);
20
+ if (verbose)
21
+ logWorkerInfo(log, verbose);
22
+ let prefix;
23
+ let success = false;
24
+ try {
25
+ prefix = await getGlobalNodeModules();
26
+ log.debug(`Global node_modules Directory: ${prefix}`);
27
+ server.request({ type: 'matterbridge_global_prefix', src: `matterbridge`, dst: 'matterbridge', params: { prefix } });
28
+ success = true;
29
+ if (!isMainThread && parentPort)
30
+ parentLog('MatterbridgePrefix', "debug", `Global node_modules Directory: ${prefix}`);
31
+ }
32
+ catch (error) {
33
+ const errorMessage = inspectError(log, `Failed to get global node modules`, error);
34
+ if (!isMainThread && parentPort)
35
+ parentLog('MatterbridgePrefix', "error", errorMessage);
36
+ }
37
+ server.close();
38
+ if (!isMainThread && parentPort) {
39
+ parentPost({ type: 'exit', threadId, threadName: workerData.threadName, success });
40
+ if (debug)
41
+ parentLog('MatterbridgePrefix', "info", `Worker ${workerData.threadName}:${threadId} exiting with success: ${success}.`);
42
+ }
package/package.json CHANGED
@@ -1,17 +1,42 @@
1
1
  {
2
2
  "name": "@matterbridge/thread",
3
- "version": "3.5.3",
3
+ "version": "3.5.4-dev-20260211-520e349",
4
4
  "description": "Matterbridge thread library",
5
5
  "author": "https://github.com/Luligu",
6
+ "homepage": "https://matterbridge.io/",
6
7
  "repository": {
7
8
  "type": "git",
8
9
  "url": "git+https://github.com/Luligu/matterbridge.git",
9
10
  "directory": "packages/thread"
10
11
  },
12
+ "bugs": {
13
+ "url": "https://github.com/Luligu/matterbridge/issues"
14
+ },
11
15
  "publishConfig": {
12
16
  "access": "public"
13
17
  },
14
- "keywords": [],
18
+ "keywords": [
19
+ "matterbridge",
20
+ "homebridge",
21
+ "bridge",
22
+ "plugin",
23
+ "frontend",
24
+ "matter.js",
25
+ "matter-node.js",
26
+ "matter",
27
+ "matterprotocol",
28
+ "iot",
29
+ "smarthome",
30
+ "connectedthings",
31
+ "hap",
32
+ "homekit",
33
+ "siri",
34
+ "google-home",
35
+ "alexa",
36
+ "homeassistant",
37
+ "smartthings",
38
+ "ewelink"
39
+ ],
15
40
  "license": "Apache-2.0",
16
41
  "funding": {
17
42
  "type": "buymeacoffee",
@@ -35,7 +60,13 @@
35
60
  "npm-shrinkwrap.json",
36
61
  "CHANGELOG.md"
37
62
  ],
63
+ "overrides": {
64
+ "eslint": "9.39.2",
65
+ "@eslint/js": "9.39.2"
66
+ },
38
67
  "dependencies": {
39
- "node-ansi-logger": "3.2.0"
68
+ "node-ansi-logger": "3.2.0",
69
+ "@matterbridge/utils": "3.5.4-dev-20260211-520e349",
70
+ "@matterbridge/types": "3.5.4-dev-20260211-520e349"
40
71
  }
41
72
  }
@@ -1,27 +0,0 @@
1
- import type { LogLevel } from 'node-ansi-logger';
2
- export type ParentPortMessage = {
3
- type: 'init';
4
- threadName: string | null;
5
- threadId: number;
6
- success: boolean;
7
- } | {
8
- type: 'ping';
9
- threadName: string | null;
10
- threadId: number;
11
- } | {
12
- type: 'pong';
13
- threadName: string | null;
14
- threadId: number;
15
- } | {
16
- type: 'log';
17
- threadName: string | null;
18
- threadId: number;
19
- logName: string | undefined;
20
- logLevel: LogLevel;
21
- message: string;
22
- } | {
23
- type: 'exit';
24
- threadName: string | null;
25
- threadId: number;
26
- success: boolean;
27
- };