@devioarts/capacitor-mdns 0.0.3 → 0.1.0
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 +54 -67
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/devioarts/capacitor/mdns/mDNS.kt +134 -37
- package/android/src/main/java/com/devioarts/capacitor/mdns/mDNSPlugin.kt +18 -5
- package/dist/docs.json +65 -3
- package/dist/esm/definitions.d.ts +27 -1
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/web.d.ts +3 -1
- package/dist/esm/web.js +12 -3
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +13 -3
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +13 -3
- package/dist/plugin.js.map +1 -1
- package/docs/electron.md +65 -0
- package/docs/platform-setup.md +52 -0
- package/docs/playground.md +19 -0
- package/docs/runtime-behavior.md +14 -0
- package/electron/dist/plugin-settings.js +15 -0
- package/electron/dist/plugin-settings.js.map +1 -0
- package/electron/dist/plugin.cjs.js +344 -0
- package/electron/dist/plugin.cjs.js.map +1 -0
- package/electron/global.d.ts +2 -0
- package/electron/mdns-bridge.cjs +8 -2
- package/electron/mdns.ts +151 -63
- package/electron/rollup.config.mjs +22 -0
- package/electron/src/index.ts +1 -0
- package/electron/src/plugin-settings.ts +12 -0
- package/electron/tsconfig.json +21 -0
- package/electron/types-public/index.d.ts +25 -0
- package/ios/Sources/mDNSPlugin/mDNS.swift +95 -28
- package/ios/Sources/mDNSPlugin/mDNSPlugin.swift +12 -3
- package/ios/Tests/mDNSPluginTests/mDNSPluginTests.swift +3 -9
- package/package.json +46 -18
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var Bonjour = require('bonjour-service');
|
|
4
|
+
var electron = require('electron');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Electron main-process implementation of the mDNS/Bonjour functionality.
|
|
8
|
+
*
|
|
9
|
+
* Uses the `bonjour-service` package to:
|
|
10
|
+
* - publish (advertise) a single service;
|
|
11
|
+
* - discover services of a given type and normalize results to the shared schema;
|
|
12
|
+
* - wire the API over Electron's ipcMain (see registerIpc/attachOnReady).
|
|
13
|
+
*
|
|
14
|
+
* Notes:
|
|
15
|
+
* - Instance name matching is normalized and prefix-safe, mirroring iOS/Android behavior.
|
|
16
|
+
* - TXT records are forwarded as strings when present.
|
|
17
|
+
*/
|
|
18
|
+
class mDNS {
|
|
19
|
+
constructor() {
|
|
20
|
+
this.publishTimeoutMs = 5000;
|
|
21
|
+
this.stopTimeoutMs = 3000;
|
|
22
|
+
this.broadcastQueue = Promise.resolve();
|
|
23
|
+
this.destroyed = false;
|
|
24
|
+
//<editor-fold desc="Init/Destroy">
|
|
25
|
+
this.ipcRegistered = false;
|
|
26
|
+
//</editor-fold>
|
|
27
|
+
this.bonjour = new Bonjour();
|
|
28
|
+
}
|
|
29
|
+
registerIpc() {
|
|
30
|
+
if (this.ipcRegistered)
|
|
31
|
+
return;
|
|
32
|
+
try {
|
|
33
|
+
electron.ipcMain.removeHandler('mdns:startBroadcast');
|
|
34
|
+
electron.ipcMain.removeHandler('mdns:stopBroadcast');
|
|
35
|
+
electron.ipcMain.removeHandler('mdns:discover');
|
|
36
|
+
electron.ipcMain.removeHandler('mdns:getPluginPlatform');
|
|
37
|
+
}
|
|
38
|
+
catch (_a) {
|
|
39
|
+
/* ignore */
|
|
40
|
+
}
|
|
41
|
+
electron.ipcMain.handle('mdns:startBroadcast', (_evt, o) => this.startBroadcast(o));
|
|
42
|
+
electron.ipcMain.handle('mdns:stopBroadcast', () => this.stopBroadcast());
|
|
43
|
+
electron.ipcMain.handle('mdns:discover', (_evt, o) => this.discover(o));
|
|
44
|
+
electron.ipcMain.handle('mdns:getPluginPlatform', () => this.getPluginPlatform());
|
|
45
|
+
this.ipcRegistered = true;
|
|
46
|
+
}
|
|
47
|
+
unregisterIpc() {
|
|
48
|
+
if (!this.ipcRegistered)
|
|
49
|
+
return;
|
|
50
|
+
try {
|
|
51
|
+
electron.ipcMain.removeHandler('mdns:startBroadcast');
|
|
52
|
+
electron.ipcMain.removeHandler('mdns:stopBroadcast');
|
|
53
|
+
electron.ipcMain.removeHandler('mdns:discover');
|
|
54
|
+
electron.ipcMain.removeHandler('mdns:getPluginPlatform');
|
|
55
|
+
}
|
|
56
|
+
catch (_a) {
|
|
57
|
+
/* ignore */
|
|
58
|
+
}
|
|
59
|
+
this.ipcRegistered = false;
|
|
60
|
+
}
|
|
61
|
+
/** Manual IPC registration (if you set autoRegisterIpc: false). Idempotent. */
|
|
62
|
+
init() {
|
|
63
|
+
this.registerIpc();
|
|
64
|
+
}
|
|
65
|
+
async destroy() {
|
|
66
|
+
this.destroyed = true;
|
|
67
|
+
this.unregisterIpc();
|
|
68
|
+
await this.withBroadcastLock(async () => {
|
|
69
|
+
await this.stopBroadcastUnlocked();
|
|
70
|
+
try {
|
|
71
|
+
this.bonjour.destroy();
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
console.warn('[mDNS] bonjour.destroy error:', err);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
// ----------------------------- utils -----------------------------
|
|
79
|
+
toErr(err) {
|
|
80
|
+
return err instanceof Error ? err.message : String(err);
|
|
81
|
+
}
|
|
82
|
+
validatePort(port) {
|
|
83
|
+
return Number.isInteger(port) && typeof port === 'number' && port > 0 && port <= 65535
|
|
84
|
+
? null
|
|
85
|
+
: 'Missing/invalid port';
|
|
86
|
+
}
|
|
87
|
+
isRecord(value) {
|
|
88
|
+
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
89
|
+
}
|
|
90
|
+
withBroadcastLock(work) {
|
|
91
|
+
// Publish and stop share one Bonjour service; serializing them prevents orphaned advertisers.
|
|
92
|
+
const run = this.broadcastQueue.catch(() => undefined).then(work);
|
|
93
|
+
this.broadcastQueue = run.catch(() => undefined);
|
|
94
|
+
return run;
|
|
95
|
+
}
|
|
96
|
+
normalize(name) {
|
|
97
|
+
return name.replace(/ \(\d+\)$/, '');
|
|
98
|
+
}
|
|
99
|
+
matchesTarget(candidate, target) {
|
|
100
|
+
if (!target)
|
|
101
|
+
return true;
|
|
102
|
+
const c = this.normalize(candidate), t = this.normalize(target);
|
|
103
|
+
return c === t || c.startsWith(t);
|
|
104
|
+
}
|
|
105
|
+
parseType(typeWithDot) {
|
|
106
|
+
const raw = typeof typeWithDot === 'string' && typeWithDot.trim() ? typeWithDot.trim() : '_http._tcp.';
|
|
107
|
+
const s = raw.replace(/\.$/, '');
|
|
108
|
+
const m = /^_([^.]+)\._(tcp|udp)$/.exec(s);
|
|
109
|
+
if (!m)
|
|
110
|
+
return { type: 'http', protocol: 'tcp' };
|
|
111
|
+
return { type: m[1], protocol: m[2] };
|
|
112
|
+
}
|
|
113
|
+
toFullType(type, protocol) {
|
|
114
|
+
return `_${type}._${protocol}.`;
|
|
115
|
+
}
|
|
116
|
+
hasCbStop(x) {
|
|
117
|
+
return !!x && typeof x.stop === 'function';
|
|
118
|
+
}
|
|
119
|
+
async safeStopService(svc) {
|
|
120
|
+
if (!svc || !this.hasCbStop(svc))
|
|
121
|
+
return;
|
|
122
|
+
try {
|
|
123
|
+
await new Promise((res) => {
|
|
124
|
+
let settled = false;
|
|
125
|
+
const done = () => {
|
|
126
|
+
if (settled)
|
|
127
|
+
return;
|
|
128
|
+
settled = true;
|
|
129
|
+
if (timeout)
|
|
130
|
+
clearTimeout(timeout);
|
|
131
|
+
res();
|
|
132
|
+
};
|
|
133
|
+
const timeout = setTimeout(done, this.stopTimeoutMs);
|
|
134
|
+
try {
|
|
135
|
+
svc.stop(done);
|
|
136
|
+
}
|
|
137
|
+
catch (e) {
|
|
138
|
+
console.warn('[mDNS] service.stop threw:', e);
|
|
139
|
+
done();
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
console.warn('[mDNS] service.stop error:', err);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
safeStopBrowser(b) {
|
|
148
|
+
if (!b)
|
|
149
|
+
return;
|
|
150
|
+
try {
|
|
151
|
+
b.stop();
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
console.warn('[mDNS] browser.stop error:', err);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// ----------------------------- API -----------------------------
|
|
158
|
+
/**
|
|
159
|
+
* Return the Electron main-process implementation marker.
|
|
160
|
+
*/
|
|
161
|
+
async getPluginPlatform() {
|
|
162
|
+
return { platform: 'electron' };
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Publish (advertise) a single Bonjour/mDNS service via bonjour-service.
|
|
166
|
+
* @param options See MdnsBroadcastOptions for type/name/port/txt.
|
|
167
|
+
* @returns Result indicating whether publishing is active and the final name.
|
|
168
|
+
*/
|
|
169
|
+
async startBroadcast(options) {
|
|
170
|
+
return this.withBroadcastLock(async () => {
|
|
171
|
+
const safeOptions = (options !== null && options !== void 0 ? options : {});
|
|
172
|
+
const portError = this.validatePort(safeOptions.port);
|
|
173
|
+
if (portError)
|
|
174
|
+
return { publishing: false, name: '', error: true, errorMessage: portError };
|
|
175
|
+
if (this.destroyed)
|
|
176
|
+
return { publishing: false, name: '', error: true, errorMessage: 'mDNS instance is destroyed' };
|
|
177
|
+
await this.stopBroadcastUnlocked();
|
|
178
|
+
const { type, protocol } = this.parseType(safeOptions.type);
|
|
179
|
+
return new Promise((resolve) => {
|
|
180
|
+
let settled = false;
|
|
181
|
+
let timeout = null;
|
|
182
|
+
const safeResolve = (r) => {
|
|
183
|
+
if (!settled) {
|
|
184
|
+
settled = true;
|
|
185
|
+
if (timeout) {
|
|
186
|
+
clearTimeout(timeout);
|
|
187
|
+
timeout = null;
|
|
188
|
+
}
|
|
189
|
+
resolve(r);
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
try {
|
|
193
|
+
const svc = this.bonjour.publish({
|
|
194
|
+
name: typeof safeOptions.name === 'string' && safeOptions.name.trim()
|
|
195
|
+
? safeOptions.name.trim()
|
|
196
|
+
: 'DevIOArtsMDNS',
|
|
197
|
+
type,
|
|
198
|
+
protocol,
|
|
199
|
+
port: safeOptions.port,
|
|
200
|
+
txt: this.isRecord(safeOptions.txt) ? this.normalizeTxt(safeOptions.txt) : undefined,
|
|
201
|
+
});
|
|
202
|
+
const cleanupListeners = () => {
|
|
203
|
+
try {
|
|
204
|
+
svc.removeListener('up', onUp);
|
|
205
|
+
svc.removeListener('error', onError);
|
|
206
|
+
}
|
|
207
|
+
catch (_a) {
|
|
208
|
+
/* ignore */
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
const onUp = () => {
|
|
212
|
+
cleanupListeners();
|
|
213
|
+
safeResolve({ publishing: true, name: svc.name || '', error: false, errorMessage: null });
|
|
214
|
+
};
|
|
215
|
+
const onError = (err) => {
|
|
216
|
+
cleanupListeners();
|
|
217
|
+
void this.safeStopService(svc);
|
|
218
|
+
if (this.advertiser === svc)
|
|
219
|
+
this.advertiser = undefined;
|
|
220
|
+
safeResolve({ publishing: false, name: '', error: true, errorMessage: this.toErr(err) });
|
|
221
|
+
};
|
|
222
|
+
const onTimeout = () => {
|
|
223
|
+
cleanupListeners();
|
|
224
|
+
void this.safeStopService(svc);
|
|
225
|
+
if (this.advertiser === svc)
|
|
226
|
+
this.advertiser = undefined;
|
|
227
|
+
safeResolve({
|
|
228
|
+
publishing: false,
|
|
229
|
+
name: '',
|
|
230
|
+
error: true,
|
|
231
|
+
errorMessage: `Timed out waiting for service publish after ${this.publishTimeoutMs}ms`,
|
|
232
|
+
});
|
|
233
|
+
};
|
|
234
|
+
svc.once('up', onUp);
|
|
235
|
+
svc.once('error', onError);
|
|
236
|
+
timeout = setTimeout(onTimeout, this.publishTimeoutMs);
|
|
237
|
+
this.advertiser = svc;
|
|
238
|
+
}
|
|
239
|
+
catch (e) {
|
|
240
|
+
safeResolve({ publishing: false, name: '', error: true, errorMessage: this.toErr(e) });
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Stop advertising the current service if any and clear internal state.
|
|
247
|
+
* @returns Result indicating whether the advertiser is active and error info.
|
|
248
|
+
*/
|
|
249
|
+
async stopBroadcast() {
|
|
250
|
+
return this.withBroadcastLock(() => this.stopBroadcastUnlocked());
|
|
251
|
+
}
|
|
252
|
+
async stopBroadcastUnlocked() {
|
|
253
|
+
try {
|
|
254
|
+
if (this.advertiser) {
|
|
255
|
+
await this.safeStopService(this.advertiser);
|
|
256
|
+
this.advertiser = undefined;
|
|
257
|
+
}
|
|
258
|
+
return { publishing: false, error: false, errorMessage: null };
|
|
259
|
+
}
|
|
260
|
+
catch (e) {
|
|
261
|
+
return { publishing: false, error: true, errorMessage: this.toErr(e) };
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Discover services of the given type and optionally filter by instance name.
|
|
266
|
+
* Deduplicates by (name:port), collects IPv4/IPv6 addresses and TXT, and
|
|
267
|
+
* resolves with either an early-exit match or after a timeout.
|
|
268
|
+
* @param options See MdnsDiscoverOptions for type/name/timeout.
|
|
269
|
+
*/
|
|
270
|
+
async discover(options = {}) {
|
|
271
|
+
const safeOptions = (options !== null && options !== void 0 ? options : {});
|
|
272
|
+
if (this.destroyed) {
|
|
273
|
+
return { error: true, errorMessage: 'mDNS instance is destroyed', servicesFound: 0, services: [] };
|
|
274
|
+
}
|
|
275
|
+
const { type, protocol } = this.parseType(safeOptions.type);
|
|
276
|
+
const targetId = typeof safeOptions.name === 'string' && safeOptions.name ? safeOptions.name : null;
|
|
277
|
+
const timeoutMs = typeof safeOptions.timeout === 'number' ? safeOptions.timeout : 3000;
|
|
278
|
+
let browser = null;
|
|
279
|
+
const services = [];
|
|
280
|
+
let hadError = false;
|
|
281
|
+
let errMsg = null;
|
|
282
|
+
return new Promise((resolve) => {
|
|
283
|
+
let timer = null;
|
|
284
|
+
let settled = false;
|
|
285
|
+
const finish = () => {
|
|
286
|
+
if (settled)
|
|
287
|
+
return;
|
|
288
|
+
settled = true;
|
|
289
|
+
if (browser) {
|
|
290
|
+
this.safeStopBrowser(browser);
|
|
291
|
+
browser = null;
|
|
292
|
+
}
|
|
293
|
+
if (timer) {
|
|
294
|
+
clearTimeout(timer);
|
|
295
|
+
timer = null;
|
|
296
|
+
}
|
|
297
|
+
resolve({
|
|
298
|
+
error: hadError,
|
|
299
|
+
errorMessage: errMsg,
|
|
300
|
+
services,
|
|
301
|
+
servicesFound: services.length,
|
|
302
|
+
});
|
|
303
|
+
};
|
|
304
|
+
try {
|
|
305
|
+
browser = this.bonjour.find({ type, protocol }, (s) => {
|
|
306
|
+
var _a;
|
|
307
|
+
if (!this.matchesTarget(s.name || '', targetId))
|
|
308
|
+
return;
|
|
309
|
+
const item = {
|
|
310
|
+
name: s.name || '',
|
|
311
|
+
type: this.toFullType(type, protocol),
|
|
312
|
+
domain: 'local.',
|
|
313
|
+
port: (_a = s.port) !== null && _a !== void 0 ? _a : 0,
|
|
314
|
+
hosts: Array.isArray(s.addresses) ? s.addresses.slice() : [],
|
|
315
|
+
txt: s.txt && Object.keys(s.txt).length ? this.normalizeTxt(s.txt) : undefined,
|
|
316
|
+
};
|
|
317
|
+
const key = `${item.name}:${item.port}`;
|
|
318
|
+
if (!services.some((x) => `${x.name}:${x.port}` === key))
|
|
319
|
+
services.push(item);
|
|
320
|
+
if (targetId && this.matchesTarget(item.name, targetId))
|
|
321
|
+
finish();
|
|
322
|
+
});
|
|
323
|
+
// Record error and let the timeout conclude; results will still be returned.
|
|
324
|
+
const onBrowserError = (err) => {
|
|
325
|
+
hadError = true;
|
|
326
|
+
errMsg = this.toErr(err);
|
|
327
|
+
};
|
|
328
|
+
browser.on('error', onBrowserError);
|
|
329
|
+
timer = setTimeout(finish, Math.max(0, timeoutMs));
|
|
330
|
+
}
|
|
331
|
+
catch (err) {
|
|
332
|
+
hadError = true;
|
|
333
|
+
errMsg = this.toErr(err);
|
|
334
|
+
finish();
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
normalizeTxt(txt) {
|
|
339
|
+
return Object.fromEntries(Object.entries(txt).map(([key, value]) => [key, Buffer.isBuffer(value) ? value.toString('utf8') : String(value)]));
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
exports.mDNS = mDNS;
|
|
344
|
+
//# sourceMappingURL=plugin.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.cjs.js","sources":["../build/electron/mdns.js"],"sourcesContent":["import Bonjour from 'bonjour-service';\nimport { ipcMain } from 'electron';\n/**\n * Electron main-process implementation of the mDNS/Bonjour functionality.\n *\n * Uses the `bonjour-service` package to:\n * - publish (advertise) a single service;\n * - discover services of a given type and normalize results to the shared schema;\n * - wire the API over Electron's ipcMain (see registerIpc/attachOnReady).\n *\n * Notes:\n * - Instance name matching is normalized and prefix-safe, mirroring iOS/Android behavior.\n * - TXT records are forwarded as strings when present.\n */\nexport class mDNS {\n constructor() {\n this.publishTimeoutMs = 5000;\n this.stopTimeoutMs = 3000;\n this.broadcastQueue = Promise.resolve();\n this.destroyed = false;\n //<editor-fold desc=\"Init/Destroy\">\n this.ipcRegistered = false;\n //</editor-fold>\n this.bonjour = new Bonjour();\n }\n registerIpc() {\n if (this.ipcRegistered)\n return;\n try {\n ipcMain.removeHandler('mdns:startBroadcast');\n ipcMain.removeHandler('mdns:stopBroadcast');\n ipcMain.removeHandler('mdns:discover');\n ipcMain.removeHandler('mdns:getPluginPlatform');\n }\n catch (_a) {\n /* ignore */\n }\n ipcMain.handle('mdns:startBroadcast', (_evt, o) => this.startBroadcast(o));\n ipcMain.handle('mdns:stopBroadcast', () => this.stopBroadcast());\n ipcMain.handle('mdns:discover', (_evt, o) => this.discover(o));\n ipcMain.handle('mdns:getPluginPlatform', () => this.getPluginPlatform());\n this.ipcRegistered = true;\n }\n unregisterIpc() {\n if (!this.ipcRegistered)\n return;\n try {\n ipcMain.removeHandler('mdns:startBroadcast');\n ipcMain.removeHandler('mdns:stopBroadcast');\n ipcMain.removeHandler('mdns:discover');\n ipcMain.removeHandler('mdns:getPluginPlatform');\n }\n catch (_a) {\n /* ignore */\n }\n this.ipcRegistered = false;\n }\n /** Manual IPC registration (if you set autoRegisterIpc: false). Idempotent. */\n init() {\n this.registerIpc();\n }\n async destroy() {\n this.destroyed = true;\n this.unregisterIpc();\n await this.withBroadcastLock(async () => {\n await this.stopBroadcastUnlocked();\n try {\n this.bonjour.destroy();\n }\n catch (err) {\n console.warn('[mDNS] bonjour.destroy error:', err);\n }\n });\n }\n // ----------------------------- utils -----------------------------\n toErr(err) {\n return err instanceof Error ? err.message : String(err);\n }\n validatePort(port) {\n return Number.isInteger(port) && typeof port === 'number' && port > 0 && port <= 65535\n ? null\n : 'Missing/invalid port';\n }\n isRecord(value) {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n }\n withBroadcastLock(work) {\n // Publish and stop share one Bonjour service; serializing them prevents orphaned advertisers.\n const run = this.broadcastQueue.catch(() => undefined).then(work);\n this.broadcastQueue = run.catch(() => undefined);\n return run;\n }\n normalize(name) {\n return name.replace(/ \\(\\d+\\)$/, '');\n }\n matchesTarget(candidate, target) {\n if (!target)\n return true;\n const c = this.normalize(candidate), t = this.normalize(target);\n return c === t || c.startsWith(t);\n }\n parseType(typeWithDot) {\n const raw = typeof typeWithDot === 'string' && typeWithDot.trim() ? typeWithDot.trim() : '_http._tcp.';\n const s = raw.replace(/\\.$/, '');\n const m = /^_([^.]+)\\._(tcp|udp)$/.exec(s);\n if (!m)\n return { type: 'http', protocol: 'tcp' };\n return { type: m[1], protocol: m[2] };\n }\n toFullType(type, protocol) {\n return `_${type}._${protocol}.`;\n }\n hasCbStop(x) {\n return !!x && typeof x.stop === 'function';\n }\n async safeStopService(svc) {\n if (!svc || !this.hasCbStop(svc))\n return;\n try {\n await new Promise((res) => {\n let settled = false;\n const done = () => {\n if (settled)\n return;\n settled = true;\n if (timeout)\n clearTimeout(timeout);\n res();\n };\n const timeout = setTimeout(done, this.stopTimeoutMs);\n try {\n svc.stop(done);\n }\n catch (e) {\n console.warn('[mDNS] service.stop threw:', e);\n done();\n }\n });\n }\n catch (err) {\n console.warn('[mDNS] service.stop error:', err);\n }\n }\n safeStopBrowser(b) {\n if (!b)\n return;\n try {\n b.stop();\n }\n catch (err) {\n console.warn('[mDNS] browser.stop error:', err);\n }\n }\n // ----------------------------- API -----------------------------\n /**\n * Return the Electron main-process implementation marker.\n */\n async getPluginPlatform() {\n return { platform: 'electron' };\n }\n /**\n * Publish (advertise) a single Bonjour/mDNS service via bonjour-service.\n * @param options See MdnsBroadcastOptions for type/name/port/txt.\n * @returns Result indicating whether publishing is active and the final name.\n */\n async startBroadcast(options) {\n return this.withBroadcastLock(async () => {\n const safeOptions = (options !== null && options !== void 0 ? options : {});\n const portError = this.validatePort(safeOptions.port);\n if (portError)\n return { publishing: false, name: '', error: true, errorMessage: portError };\n if (this.destroyed)\n return { publishing: false, name: '', error: true, errorMessage: 'mDNS instance is destroyed' };\n await this.stopBroadcastUnlocked();\n const { type, protocol } = this.parseType(safeOptions.type);\n return new Promise((resolve) => {\n let settled = false;\n let timeout = null;\n const safeResolve = (r) => {\n if (!settled) {\n settled = true;\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n }\n resolve(r);\n }\n };\n try {\n const svc = this.bonjour.publish({\n name: typeof safeOptions.name === 'string' && safeOptions.name.trim()\n ? safeOptions.name.trim()\n : 'DevIOArtsMDNS',\n type,\n protocol,\n port: safeOptions.port,\n txt: this.isRecord(safeOptions.txt) ? this.normalizeTxt(safeOptions.txt) : undefined,\n });\n const cleanupListeners = () => {\n try {\n svc.removeListener('up', onUp);\n svc.removeListener('error', onError);\n }\n catch (_a) {\n /* ignore */\n }\n };\n const onUp = () => {\n cleanupListeners();\n safeResolve({ publishing: true, name: svc.name || '', error: false, errorMessage: null });\n };\n const onError = (err) => {\n cleanupListeners();\n void this.safeStopService(svc);\n if (this.advertiser === svc)\n this.advertiser = undefined;\n safeResolve({ publishing: false, name: '', error: true, errorMessage: this.toErr(err) });\n };\n const onTimeout = () => {\n cleanupListeners();\n void this.safeStopService(svc);\n if (this.advertiser === svc)\n this.advertiser = undefined;\n safeResolve({\n publishing: false,\n name: '',\n error: true,\n errorMessage: `Timed out waiting for service publish after ${this.publishTimeoutMs}ms`,\n });\n };\n svc.once('up', onUp);\n svc.once('error', onError);\n timeout = setTimeout(onTimeout, this.publishTimeoutMs);\n this.advertiser = svc;\n }\n catch (e) {\n safeResolve({ publishing: false, name: '', error: true, errorMessage: this.toErr(e) });\n }\n });\n });\n }\n /**\n * Stop advertising the current service if any and clear internal state.\n * @returns Result indicating whether the advertiser is active and error info.\n */\n async stopBroadcast() {\n return this.withBroadcastLock(() => this.stopBroadcastUnlocked());\n }\n async stopBroadcastUnlocked() {\n try {\n if (this.advertiser) {\n await this.safeStopService(this.advertiser);\n this.advertiser = undefined;\n }\n return { publishing: false, error: false, errorMessage: null };\n }\n catch (e) {\n return { publishing: false, error: true, errorMessage: this.toErr(e) };\n }\n }\n /**\n * Discover services of the given type and optionally filter by instance name.\n * Deduplicates by (name:port), collects IPv4/IPv6 addresses and TXT, and\n * resolves with either an early-exit match or after a timeout.\n * @param options See MdnsDiscoverOptions for type/name/timeout.\n */\n async discover(options = {}) {\n const safeOptions = (options !== null && options !== void 0 ? options : {});\n if (this.destroyed) {\n return { error: true, errorMessage: 'mDNS instance is destroyed', servicesFound: 0, services: [] };\n }\n const { type, protocol } = this.parseType(safeOptions.type);\n const targetId = typeof safeOptions.name === 'string' && safeOptions.name ? safeOptions.name : null;\n const timeoutMs = typeof safeOptions.timeout === 'number' ? safeOptions.timeout : 3000;\n let browser = null;\n const services = [];\n let hadError = false;\n let errMsg = null;\n return new Promise((resolve) => {\n let timer = null;\n let settled = false;\n const finish = () => {\n if (settled)\n return;\n settled = true;\n if (browser) {\n this.safeStopBrowser(browser);\n browser = null;\n }\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n resolve({\n error: hadError,\n errorMessage: errMsg,\n services,\n servicesFound: services.length,\n });\n };\n try {\n browser = this.bonjour.find({ type, protocol }, (s) => {\n var _a;\n if (!this.matchesTarget(s.name || '', targetId))\n return;\n const item = {\n name: s.name || '',\n type: this.toFullType(type, protocol),\n domain: 'local.',\n port: (_a = s.port) !== null && _a !== void 0 ? _a : 0,\n hosts: Array.isArray(s.addresses) ? s.addresses.slice() : [],\n txt: s.txt && Object.keys(s.txt).length ? this.normalizeTxt(s.txt) : undefined,\n };\n const key = `${item.name}:${item.port}`;\n if (!services.some((x) => `${x.name}:${x.port}` === key))\n services.push(item);\n if (targetId && this.matchesTarget(item.name, targetId))\n finish();\n });\n // Record error and let the timeout conclude; results will still be returned.\n const onBrowserError = (err) => {\n hadError = true;\n errMsg = this.toErr(err);\n };\n browser.on('error', onBrowserError);\n timer = setTimeout(finish, Math.max(0, timeoutMs));\n }\n catch (err) {\n hadError = true;\n errMsg = this.toErr(err);\n finish();\n }\n });\n }\n normalizeTxt(txt) {\n return Object.fromEntries(Object.entries(txt).map(([key, value]) => [key, Buffer.isBuffer(value) ? value.toString('utf8') : String(value)]));\n }\n}\n//# sourceMappingURL=mdns.js.map"],"names":["ipcMain"],"mappings":"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"}
|
package/electron/global.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type {
|
|
|
4
4
|
MdnsBroadcastResult,
|
|
5
5
|
MdnsDiscoverOptions,
|
|
6
6
|
MdnsDiscoverResult,
|
|
7
|
+
MdnsPluginPlatformResult,
|
|
7
8
|
MdnsStopResult,
|
|
8
9
|
} from '../src/definitions'; // Types only; no runtime import
|
|
9
10
|
|
|
@@ -14,6 +15,7 @@ declare global {
|
|
|
14
15
|
* Primary name with the same casing as iOS jsName.
|
|
15
16
|
*/
|
|
16
17
|
mDNS: {
|
|
18
|
+
getPluginPlatform(): Promise<MdnsPluginPlatformResult>;
|
|
17
19
|
startBroadcast(options: MdnsBroadcastOptions): Promise<MdnsBroadcastResult>;
|
|
18
20
|
stopBroadcast(): Promise<MdnsStopResult>;
|
|
19
21
|
discover(options?: MdnsDiscoverOptions): Promise<MdnsDiscoverResult>;
|
package/electron/mdns-bridge.cjs
CHANGED
|
@@ -5,6 +5,12 @@
|
|
|
5
5
|
// contextBridge.exposeInMainWorld('mdns', createMDNSAPI({ ipcRenderer })) // alias
|
|
6
6
|
module.exports.createMDNSAPI = ({ ipcRenderer }) => {
|
|
7
7
|
return {
|
|
8
|
+
/**
|
|
9
|
+
* Return the platform implementation that handled this call.
|
|
10
|
+
* @returns {Promise<{platform: 'electron'}>}
|
|
11
|
+
*/
|
|
12
|
+
getPluginPlatform: () => ipcRenderer.invoke('mdns:getPluginPlatform'),
|
|
13
|
+
|
|
8
14
|
/**
|
|
9
15
|
* Start advertising a Bonjour/mDNS service.
|
|
10
16
|
* @param {{type?: string, name: string, port: number, txt?: Record<string,string>}} options
|
|
@@ -20,8 +26,8 @@ module.exports.createMDNSAPI = ({ ipcRenderer }) => {
|
|
|
20
26
|
|
|
21
27
|
/**
|
|
22
28
|
* Discover services of a given type, optional normalized exact/prefix name filter.
|
|
23
|
-
* @param {{type?: string,
|
|
24
|
-
* @returns {Promise<{services: Array<{name:string,type:string,domain:string,port:number,hosts
|
|
29
|
+
* @param {{type?: string, name?: string, timeout?: number}} [options]
|
|
30
|
+
* @returns {Promise<{error:boolean,errorMessage:string|null,servicesFound:number,services: Array<{name:string,type:string,domain:string,port:number,hosts:string[],txt?:Record<string,string>}>}>}
|
|
25
31
|
*/
|
|
26
32
|
discover: (options) => ipcRenderer.invoke('mdns:discover', options),
|
|
27
33
|
}
|