@collight/dns-sd
Version:
A DNS Service Discovery implementation in modern TypeScript
1 lines • 5.57 kB
Source Map (JSON)
{"version":3,"file":"DNSSD.cjs","sources":["../../src/DNSSD.ts"],"sourcesContent":["import mDNS from 'multicast-dns';\n\nimport { Browser, BrowserOptions, DiscoveredService } from './browser';\nimport { Registry, Service, ServiceOptions } from './registry';\nimport { MDNSServer } from './utils';\n\n// MARK: DNSSD\n/**\n * High-level API for Multicast DNS Service Discovery and Advertisement.\n *\n * The `DNSSD` class provides convenient methods for:\n * - Publishing services to the local network\n * - Browsing and discovering services\n * - Unpublishing and cleaning up all registered services\n * - Managing underlying mDNS server lifecycle\n *\n * It wraps a lower-level `MDNSServer` and coordinates interactions with\n * the service `Registry` and service `Browser`.\n *\n * @example\n * const dnssd = new DNSSD()\n *\n * // Advertise a new service\n * dnssd.publish({ name: 'My Printer', type: 'printer', port: 9100 })\n *\n * // Discover services\n * dnssd.startBrowser({ type: 'printer' }, service => {\n * console.log('Found service:', service)\n * })\n */\nexport class DNSSD {\n readonly server: MDNSServer;\n readonly registry: Registry;\n\n constructor(options: mDNS.Options = {}) {\n this.server = new MDNSServer(options);\n this.registry = new Registry(this.server);\n }\n\n // MARK: service\n /**\n * Creates a new service instance without publishing it to the network.\n *\n * @param options - Configuration options for the service.\n * @returns A new `Service` instance linked to this registry.\n */\n makeService(options: ServiceOptions): Service {\n return this.registry.makeService(options);\n }\n\n /**\n * Publishes a service to the network using the given options.\n *\n * @param options - Configuration options for the service.\n * @returns A promise that resolves with the published service.\n */\n async publish(options: ServiceOptions): Promise<Service> {\n return this.registry.publish(options);\n }\n\n /**\n * Unpublishes all services that were previously published.\n *\n * Sends goodbye messages and clears internal state.\n */\n async unpublishAll(): Promise<void> {\n await this.registry.unpublishAll();\n }\n\n // MARK: browser\n /**\n * Creates a new mDNS browser for discovering services on the network.\n *\n * @param options - Optional configuration for the browser.\n * @returns A new `Browser` instance.\n */\n makeBrowser(options?: BrowserOptions): Browser {\n return new Browser(this.server.mdns, options);\n }\n\n /**\n * Creates and starts a browser for discovering services, with an optional handler for discovered services.\n *\n * @param options - Optional configuration for the browser.\n * @param onServiceUp - Optional callback invoked when a service is discovered.\n * @returns A started `Browser` instance.\n */\n startBrowser(options?: BrowserOptions, onServiceUp?: (service: DiscoveredService) => void): Browser {\n const browser = this.makeBrowser(options);\n if (onServiceUp) {\n browser.on('up', onServiceUp);\n }\n browser.start();\n return browser;\n }\n\n /**\n * Discovers a single service matching the provided criteria, with a timeout.\n *\n * Stops discovery after the first match or when the timeout is reached.\n *\n * @param options - Optional browser options to filter services.\n * @param timeoutMs - Maximum time in milliseconds to wait for a match.\n * @returns A promise that resolves with the discovered service or `null` if none found.\n */\n async findOne(options?: BrowserOptions, timeoutMs = 10000): Promise<DiscoveredService | null> {\n return new Promise(resolve => {\n const browser = new Browser(this.server.mdns, options);\n browser.start();\n\n let timer: NodeJS.Timeout | undefined = setTimeout(() => {\n browser.stop();\n resolve(null);\n }, timeoutMs);\n\n browser.once('up', service => {\n if (timer !== undefined) {\n clearTimeout(timer);\n timer = undefined;\n }\n browser.stop();\n resolve(service);\n });\n });\n }\n\n // MARK: destroy\n /**\n * Destroys the DNSSD instance, stopping all services and shutting down the server.\n *\n * No further operations should be performed after destruction.\n */\n async destroy(): Promise<void> {\n return new Promise(resolve => {\n this.registry.destroy();\n this.server.mdns.destroy(resolve);\n });\n }\n}\n"],"names":["DNSSD","options","MDNSServer","Registry","Browser","onServiceUp","browser","timeoutMs","resolve","timer","service"],"mappings":"iQA8BO,MAAMA,CAAM,CAIjB,YAAYC,EAAwB,GAAI,CACtC,KAAK,OAAS,IAAIC,EAAAA,WAAWD,CAAO,EACpC,KAAK,SAAW,IAAIE,WAAS,KAAK,MAAM,CAC1C,CASA,YAAYF,EAAkC,CAC5C,OAAO,KAAK,SAAS,YAAYA,CAAO,CAC1C,CAQA,MAAM,QAAQA,EAA2C,CACvD,OAAO,KAAK,SAAS,QAAQA,CAAO,CACtC,CAOA,MAAM,cAA8B,CAClC,MAAM,KAAK,SAAS,aAAA,CACtB,CASA,YAAYA,EAAmC,CAC7C,OAAO,IAAIG,EAAAA,QAAQ,KAAK,OAAO,KAAMH,CAAO,CAC9C,CASA,aAAaA,EAA0BI,EAA6D,CAClG,MAAMC,EAAU,KAAK,YAAYL,CAAO,EACxC,OAAII,GACFC,EAAQ,GAAG,KAAMD,CAAW,EAE9BC,EAAQ,MAAA,EACDA,CACT,CAWA,MAAM,QAAQL,EAA0BM,EAAY,IAA0C,CAC5F,OAAO,IAAI,QAAQC,GAAW,CAC5B,MAAMF,EAAU,IAAIF,EAAAA,QAAQ,KAAK,OAAO,KAAMH,CAAO,EACrDK,EAAQ,MAAA,EAER,IAAIG,EAAoC,WAAW,IAAM,CACvDH,EAAQ,KAAA,EACRE,EAAQ,IAAI,CACd,EAAGD,CAAS,EAEZD,EAAQ,KAAK,KAAMI,GAAW,CACxBD,IAAU,SACZ,aAAaA,CAAK,EAClBA,EAAQ,QAEVH,EAAQ,KAAA,EACRE,EAAQE,CAAO,CACjB,CAAC,CACH,CAAC,CACH,CAQA,MAAM,SAAyB,CAC7B,OAAO,IAAI,QAAQF,GAAW,CAC5B,KAAK,SAAS,QAAA,EACd,KAAK,OAAO,KAAK,QAAQA,CAAO,CAClC,CAAC,CACH,CACF"}