UNPKG

@collight/dns-sd

Version:

A DNS Service Discovery implementation in modern TypeScript

3 lines (2 loc) 2.64 kB
import{EventEmitter as l}from"events";import{debug as a}from"../utils/debug.js";import{nameEquals as h}from"../utils/dns-utils.js";import"fast-deep-equal";import"multicast-dns";import{ServiceType as u}from"../utils/ServiceType.js";import{DiscoveredService as d}from"./DiscoveredService.js";const r=class r extends l{constructor(t,e){super(),this.services=[],this.mdns=t,this.filter=e?.filter}get queryNames(){if(!this.filter)return[r.WILDCARD];const{protocol:t,type:e,name:i,subtypes:s}=this.filter;return(s&&s.length>0?s.map(o=>new u(e,t,o).toString()):[new u(e,t).toString()]).map(o=>typeof i=="string"?`${i}.${o}${r.TLD}`:`${o}${r.TLD}`)}start(){this.onresponse||(this.onresponse=(t,e)=>{a("mdns on response packet:",t);for(const s of[...t.answers,...t.additionals])s.type==="PTR"&&s.ttl===0&&this.removeService(s.data);const i=d.fromResponse(t,e);if(i.length===0){if(!this.filter)for(const s of t.answers)s.type!=="PTR"||s.name!==r.WILDCARD||(a("mdns wildcard query with:",s.data),this.mdns.query(s.data,"PTR"));return}for(const s of i)this.services.some(n=>h(n.fqdn,s.fqdn))?this.updateService(s):this.addService(s)},this.mdns.on("response",this.onresponse),this.update())}stop(){if(this.onresponse){this.mdns.removeListener("response",this.onresponse),this.onresponse=void 0;for(const t of this.services)clearTimeout(t.ttlTimer);this.services=[]}}update(){a("mdns query with:",this.queryNames);for(const t of this.queryNames)this.mdns.query(t,"PTR")}match(t){if(!this.filter)return!0;const{protocol:e,type:i,subtypes:s,name:n,txt:o}=this.filter;if(e!==t.protocol||i!==t.type||(s?.some(f=>!t.subtypes.includes(f))??!1)||n!==void 0&&(typeof n=="string"&&!h(n,t.name)||n instanceof RegExp&&!n.test(t.name)))return!1;if(o){for(const[f,m]of Object.entries(o))if(t.txt?.[f]===void 0||typeof m=="string"&&m!==t.txt[f]||m instanceof RegExp&&!m.test(t.txt[f]))return!1}return!0}setupTTLTimer(t){t.ttl!==void 0&&(t.ttlTimer=setTimeout(()=>{t.expired&&this.removeService(t.fqdn)},t.ttl*1e3))}addService(t){this.match(t)&&(this.services.push(t),this.setupTTLTimer(t),this.emit("up",t))}updateService(t){if(!this.match(t)){this.removeService(t.fqdn);return}for(let e=0;e<this.services.length;++e){const i=this.services[e];if(h(i.fqdn,t.fqdn)){clearTimeout(i.ttlTimer),this.services[e]=t,this.setupTTLTimer(t),this.emit("update",t,i);break}}}removeService(t){for(let e=0;e<this.services.length;++e){const i=this.services[e];if(i&&h(i.fqdn,t)){this.services.splice(e,1),clearTimeout(i.ttlTimer),this.emit("down",i);return}}}};r.TLD=".local",r.WILDCARD="_services._dns-sd._udp"+r.TLD;let p=r;export{p as Browser}; //# sourceMappingURL=Browser.js.map