@byokit/discover

中文文档
0.8.7发布于 2026/10/25Apache-2.0TypeScriptES Module构建来源已验证近 30 天下载 3814

TypeScript套件让人们通过他们已经支付的人工智能计划,在网络,电话和桌面上登录到你的应用程序.

中文使用文档
文档目录16 节
  1. 安装
  2. iOS 设置( Expo)
  3. 快速启动
  4. API 一览
  5. 路线
  6. 建议
  7. 多个直接听众
  8. 电话路由证据( 反应本地和节点)
  9. 可达到性和防火墙
  10. 分级规则
  11. mDNS 数据
  12. 广告(节点)
  13. 浏览( 本地反应)
  14. 测试
  15. 链接
  16. 许可证

@byokit/发现

npm CI Apache 2.0 Node | React Native

电话地址可以拨家庭电脑.
对于 @byokit/pair是因为 offer({ urls }): 私人隧道服务到一个人的尾网,直接 加密链接,另一个私人覆盖网络或局域网. 在节点上还可以通过mDNS对计算机进行广告宣传; 在电话(React Industrial)中,它浏览周围的mDNS服务.

原为 @byokit/reach,它继续作为已贬值的shim通过0.7.x再将这个软件包输出出去 并在0.8.0中删除.

安装

npm install @byokit/discover

npm • 妇女 最近发布 • 妇女 所有释放

iOS 设置( Expo)

iOS 只返回本地网络 mDNS 的结果, 当应用程序声明它浏览的 Bonjour 服务类型和 a 使用说明。 添加配置插件并列出您通过的类型 browse()数字 :

{
  "expo": {
    "plugins": [["@byokit/discover", { "services": ["_byokit._tcp"] }]]
  }
}

services 需要且必须是非空; 空列表未按名称预建而非写入 空的 Bonjour 列表 . localNetwork 覆盖 iOS 提示中显示的使用字符串( 合理的默认) 用于省略时。 预建写入 NSBonjourServices 财务报告和审定财务报表 NSLocalNetworkUsageDescription 输入 Info.plist; 在添加插件后重建本地二进制 。 Android 不需要插件 : react-native-zeroconf自己的清单已经合并 CHANGE_WIFI_MULTICAST_STATE。 。 。 .

快速启动

npm install @byokit/discover

确定8792端口服务器的地址, 聆听联系人说的地方, 把地址放入对齐 提供。 持久性 ingress 并传回作为 previous {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}下次再说.

import { createServer } from 'node:http';
import { reach } from '@byokit/discover';

const { urls, bind, ingress, pendingCleanup } = await reach({ port: 8792, previous: saved.ingress });
// One listener per address reach names, never a wildcard: loopback behind Serve, the selected tailnet IP for
// direct Tailscale, the classified LAN (or overlay) addresses for those routes.
const servers = bind.map((address) => createServer(handler).listen(8792, address));
saved.ingress = ingress;
if (pendingCleanup) saved.pendingCleanup = pendingCleanup; // retry unserve() later
const { text } = host.offer({ role: 'control', urls });     // show `text` as a QR

带有由编造而成的界面列表的局域网路由,因此它从不触及Tailscale或网络. 多克的桥是 跳过; NetBird 风格 wt0 地址为 private 路线,而不是局域网 :

import type { NetworkInterfaceInfo } from 'node:os';
import { reach, routes } from '@byokit/discover';

const nic = (address: string): NetworkInterfaceInfo =>
  ({ address, netmask: '255.255.255.0', family: 'IPv4', mac: '02:00:00:00:00:01', internal: false, cidr: `${address}/24` });
const interfaces = { en0: [nic('192.168.1.20')], docker0: [nic('172.17.0.1')], wt0: [nic('100.90.1.2')] };

console.log(routes(interfaces));
console.log(await reach({ port: 8792, via: 'lan', interfaces }));
{
  lan: [ '192.168.1.20' ],
  private: [ { address: '100.90.1.2', interface: 'wt0' } ],
  tailscale: []
}
{ urls: [ 'ws://192.168.1.20:8792' ], bind: [ '192.168.1.20' ] }

API 一览

导出它会做什么
reach({ port, via?, previous?, tailscale?, interfaces?, address? })拨号 urls,则 bind 收听的地址(每个听众一个,从来不是通配符) ingress 持续(加) pendingCleanup 当删除失败时)
directRoutes({ port, listen?, interfaces?, tailnetIPs?, hosts?, path? })多个直接收听器 hosts 和配对 urls,带有明确的回放/尾网/局域网范围
phoneNetwork({ nativeModule? })电话Wi-Fi/手机运输和VPN状态(yes, (中文(简体) ), no, (中文(简体) ), unknown(中文(简体) )
nativeAddresses({ nativeModule? })IPv4接口证据,包括实际前缀长度; 4. 节点默认读取其界面
routeOf(url)地址提示 : home, (中文(简体) ), tailscale, (中文(简体) ), relay, (中文(简体) ), loopback 或者说 unknown
observe({ urls, priorEvidence?, nativeModule?, addresses?, probe? })当前前缀证据和有界限的探测器,保留宿主先前的证据
probe(url, { timeout?, fetch? })类型 answers, (中文(简体) ), refused, (中文(简体) ), timeout 或者说 unknown 观察
routes(interfaces?, tailnetIPs?)这台计算机的IPv4路线: lan 地址:, private 覆盖地址和 tailscale 地址
recommend({ port?, interfaces?, tailscale?, state?, serve?, lan?, private?, current? })每一条日常语言的路线,首先推荐: { via, recommended, sentence, needs, disabledReason? } 每条路线
advertise({ type, port, name?, txt?, addresses? })出版物 _<type>._tcp 超过 mDNS(节点),仅使用所选地址;返回 { stop }
tailscaleState({ bin?, timeoutMs? })非投掷安装、后端、登录、密钥过期、对等和地址诊断
firewall({ port, platform?, run?, timeoutMs? })本地防火墙是否在端口上被挡入 : { blocked, how, nextStep },在不访问管理员的情况下读取
needsSignin(status), (中文(简体) ), isPeer(status, ip)原始纯帮助 tailscale status --json: 明确的登录状态和同行IP成员
tailscaleStatus, (中文(简体) ), tailscaleName, (中文(简体) ), magicDnsName读取本地 Tailscale 状态和此机器的 MagicDNS 名称
inspectServe, (中文(简体) ), serveRootProxy检查谁持有服务根 : free, (中文(简体) ), ours, (中文(简体) ), occupied, (中文(简体) ), funnel, (中文(简体) ), disabled 或者说 inconclusive
serve, (中文(简体) ), unserve制作或删除应用程序的“ 服务” 映射, 并进行所有权检查
SERVE_OWNED_ERROR, (中文(简体) ), FUNNEL_ERROR带漏斗的根和根的错误消息
browse({ type }), (中文(简体) ), scan({ type, ms })只反应本地条目: 发现 mDNS 服务, 流式或时间框
类型Via, (中文(简体) ), Reach, (中文(简体) ), RecommendVia, (中文(简体) ), RecommendEntry, (中文(简体) ), RecommendOptions, (中文(简体) ), PrivateRoute, (中文(简体) ), ServeIngress, (中文(简体) ), ServeRoot, (中文(简体) ), TailscaleOptions, (中文(简体) ), TailscaleState, (中文(简体) ), TailscalePeer, (中文(简体) ), Bonjour, (中文(简体) ), BonjourRecord; 在本地反应 BrowseService, (中文(简体) ), BrowseHandle, (中文(简体) ), BrowseOptions, (中文(简体) ), BrowseEvents, (中文(简体) ), BrowseEventName, (中文(简体) ), ZeroconfLike

路线

via 选择路径 :

via地址服务器绑定
auto (默认)如果安装了Tailscale, 则使用局域网现下表
tailscalewss://<MagicDNS name> 通过尾图服务127.0.0.1
tailscale-directws://<tailnet IP>:<port>选中的尾网 IP
private另一个覆盖网络(NetBird, WireGuard, ZeroTier,.)每个覆盖地址
lan物理外观界面上的私人IPv4地址(未知多克,VM或VPN桥接)每个局域网地址

bind 是一个列表:每个听众一个地址,所以手机到达了它提供的地址上的服务器. 局域网 或上线路由绑定每个机密地址的名称, 绝不使用通配符—— 通配符打开端口 这台电脑的每一个接口, 包括那部电话从未提供的接口.

直接 Tailscale 绑定第一个 CGNAT IPv4 地址 Self.TailscaleIPs关闭局域网. 过 address 与 via: 'tailscale-direct' 从同一列表中选择另一个 IPv4 地址; 在删除已有的Service映射之前,拒绝使用外国地址和通配符.

routes(interfaces, tailnetIPs) 包括名为 Tailscale 的界面 tailscale; 通过 即兴表演 ips 以识别 MacOS 上的分级地址 utun 接口。 其他叠加, 包括没有tailscale 证据的 CGNAT 地址,请在 private。该函数不运行 CLI.

只IPv6网络:尚未.

分级只能是运输 Link的握手仍然检查每个设备密钥.

建议

recommend() 每个混凝土路线列出一个条目(tailscale, (中文(简体) ), tailscale-direct, (中文(简体) ), private, (中文(简体) ), lan与 因此推荐令和每日副本在一个地方直播. sentence 财务报告和审定财务报表 needs 来自 @byokit/ui是因为 routeChoices();这里只添加可用性. auto 这不是一条路线:它选择 建议条目。 过 state, (中文(简体) ), serve, (中文(简体) ), lan 财务报告和审定财务报表 private 假的,在不触摸尾盘的情况下决定 网络;没有选项,它将探测此计算机(tailscaleState, (中文(简体) ), inspectServe 打开 port, (中文(简体) ), routes) (中文(简体) ).

import { recommend } from '@byokit/discover';

const entries = await recommend({
  state: { installed: true, backendState: 'Running', needsSignin: false, dnsName: 'dev.tailnet.ts.net', ips: ['100.64.0.1'] },
  serve: { status: 'free' },
  lan: ['192.168.1.20'],
  private: [],
});
console.log(entries.map((e) => `${e.recommended ? '●' : '○'} ${e.via}: ${e.sentence}`));
● tailscale: Your phone reaches this computer from anywhere.
○ tailscale-direct: Same as above without Tailscale Serve. Pick this if Serve is already used on this computer for something else.
○ private: Pick this if this computer and phone are already on one.
○ lan: Easiest. Works while your phone is on the same Wi-Fi as this computer. Nothing else to install.

顺序是目前的健康路线(通过该路线为 current)),后为"服务"作"服务"作"服务"作"服务"作"服务"作"服务"作"服务"作"服务"作"服务"作"服务"作"服务"作"服务"作"服务"作"服务"作"服务"作"服务"作"服务"作"服务"作"服务"作"服务"作"服务"作"服务"作"服务"作"服务"作服务" root被取出,被禁用,被放出,或者无名——然后是私人的覆盖,然后是Same Wi-Fi. 轨距已安装但 签名退出后仍可选择, 登录在 needs,而建议使用相同的Wi-Fi。 没有准备就等于没有进入 建议,每个条目都带有 disabledReason。 。 。 .

多个直接听众

directRoutes 是同步的,没有运行 CLI,服务或收听器。 默认情况下它会选择回转加 机密的尾网地址 提供 listen 只允许其真正的范围。 局域网约束个人 局域网地址,因此启用局域网不会隐含地打开无关的上盖或被禁用的范围. reach() 遵循同一规则: bind 列表名称,每个收听者一个地址,以及局域网或覆盖 路径从不要求通配符. 过 tailscaleState().ips 作为 tailnetIPs 用于未命名接口。 地址必须在界面中存在 shapt; CLI 仅凭证据不能创建收听器. 刷新快照并调和听众 当网络或对接窗口政策发生变化时.

import type { NetworkInterfaceInfo } from 'node:os';
import { directRoutes } from '@byokit/discover';

const nic = (address: string): NetworkInterfaceInfo => ({ address, netmask: '255.255.255.0',
  family: 'IPv4', mac: '02:00:00:00:00:01', internal: false, cidr: `${address}/24` });
const umer = directRoutes({
  port: 8792, path: '/link',
  interfaces: { en0: [nic('192.168.1.20')], utun3: [nic('100.101.2.3')] },
  tailnetIPs: ['100.101.2.3'],
  listen: { loopback: true, tailnet: true, lan: true },
});
console.log(umer.hosts); // ['127.0.0.1', '100.101.2.3', '192.168.1.20']
console.log(umer.urls);  // ['ws://192.168.1.20:8792/link', 'ws://100.101.2.3:8792/link']
// Create a server for each host; give urls to link's offer only after those servers listen.

hosts 用明确的被绑定的收听器覆盖范围选择(通过数组而不是逗号分隔) 字符串). 明确钉住 0.0.0.0 故意打开每个 IPv4 接口;其拨号 URL 仅扩展 至分类局域网/尾网地址。 一个空的 hosts 数组返回没有听众或 URL 。 拨号 URL 设置局域网 在尾网之前,删除重复,并仅在没有远程候选时包含回放.

电话路由证据( 反应本地和节点)

使用 @byokit/discover/react-native 明确或根 react-native 出口条件。 都暴露出来了 nativeAddresses, (中文(简体) ), routeOf, (中文(简体) ), observe, (中文(简体) ), probe 财务报告和审定财务报表 phoneNetwork 与节点相同的类型。 这些函数导入 no 节点模块. Expo 应用程序使用捆绑 ByokitReach 默认情况下在Android/iOS上的本地模块. 重建当地人 安装 @ byokit/ 发现后二进制 。 Android 读取界面前缀和网络能力; iOS 读取 接口 netmask 和 NWPath 传输。 赤裸回放本地应用程序可以提供本地地址模块 结束 nativeModule 每个电话。 这支持没有全局单子的现有模块和假相. 阅读器 addresses(): Promise<NativeAddress[]>返回时 { address, prefixLength?, interface? } 每个IPv4接口。 获取 prefixLength 从平台上 界面前缀/网格,从不猜测 24。 仅保留字符串的阅读器需要适配器,不能 提供前缀证据,直到其本土实施暴露.

此示例运行时没有本地网络( 使用节点根导入以在节点下运行 ) :

import { nativeAddresses, routeOf, observe, probe } from '@byokit/discover/react-native';
import type { NativeAddressesModule } from '@byokit/discover/react-native';

const umer: NativeAddressesModule = {
  addresses: async () => [{ address: '192.168.1.2', prefixLength: 23, interface: 'wlan0' }],
};
const fakeFetch: typeof fetch = async () => new Response('', { status: 503 });
console.log(await nativeAddresses({ nativeModule: umer }));
console.log(routeOf('ws://100.64.0.3:8792/link')); // 'tailscale'
console.log(await probe('ws://192.168.0.20:8792/link', { timeout: 4000, fetch: fakeFetch }));
const facts = await observe({
  urls: ['ws://192.168.0.20:8792/link', 'ws://100.64.0.3:8792/link'],
  nativeModule: umer,
  priorEvidence: { anywhere: 'anywhere', peer: true, reached: { tailscale: 123 } },
  probe: { timeout: 4000, fetch: fakeFetch },
});
console.log(facts.home, facts.target, facts.knock?.state); // true, LAN URL, 'answers'

对于VPN/错误网络旗帜, phoneNetwork() 返回新的活动网络快照 :

import { phoneNetwork } from '@byokit/discover/react-native';

// Expo: const network = await phoneNetwork();
// Runnable fake for Umer's phone (Node can use the root import):
const network = await phoneNetwork({ nativeModule: {
  phoneNetwork: async () => ({ onWifi: true, cellular: false, vpnActive: 'yes' }),
} });
console.log(network); // { onWifi: true, cellular: false, vpnActive: 'yes' }

Android 使用活动网络的 TRANSPORT_WIFI, (中文(简体) ), TRANSPORT_CELLULAR 财务报告和审定财务报表 TRANSPORT_VPN 能力; 多个运输旗可以是真实的. iOS 将 NWPath 用于 Wi-Fi/ cellular 并总是返回 vpnActive: 'unknown'。 。 。 . 没有本地读取器, 读取失败或没有路径输出 { onWifi: false, cellular: false, vpnActive: 'unknown' }· ; 背面的假运输旗并不能证明网络不存在。 节点返回后退, 除非 读者被注射。 此快照从未确定可以达到特定的对等点 。 包裹 安卓正常的原生货品 ACCESS_NETWORK_STATE 权限; 没有运行时间权限对话框 这是需要的。 曝光自动链接发现捆绑模块; 安装 expo-modules-core 如果在本地应用程序中 尚未存在。 仅限JS的环境可以注入读取器;所有本土加载被推迟使用.

observe 比较主机的家用IPv4地址与电话的实际接口前缀. 它更喜欢一个 匹配家用 URL, 否则当快照包含一个 CGNAT 地址时, 尾网 URL . home 不详 (单位:千美元)undefined(a) 没有可用的前缀证据; vpn 未知,没有地址. tailnet 表示一个 候选 URL 存在; vpn 表示当地CGNAT地址存在. 导航卫星系统 .ts.net 分类是路由 提示,不是 Tailscale 、 共享对等方、 Wi- Fi 关联或可达性的证据 . routeOf 识别中继器 網址由 /link/v1/ 返回时 unknown 用于不正确/不支持或其他公共URL。 IPv6 证据是 尚未支持 . priorEvidence 保留先前已认证的主机, 它不会被刷新 根据本意见. addresses 可直接提供快照;节点默认为自己的IPv4接口. 不可用/ 失效的本地模块给出空快照, 并且从未发明网络证据 .

probe 将 WebSocket URL 映射到 HTTP( S)并保存其路径。 每个 HTTP 状态都意味着 answers没有 被认证的链接。 明确 ECONNREFUSED 表示 refused; 通用本地获取错误(包括 dNS/TLS 可能的失败)指 unknown。 。 。 . timeout 即使获取也忽略了中止. 默认约束为4000ms. 探测器只是对呼叫者所通过 URL (或候选人) 的主动请求 observe 选择);它从不运行 Tailscale CLI,在中或更改服务。 弹出 fetch 用于离线测试. Apps决定自己的下线措辞,仍然通过链接认证.

可达到性和防火墙

两次检查在设置其勾选符前进行,顺序如下:

  1. 电话能接通这些地址吗? 这是 @byokit/pair是因为 check(urls):它以 LINK_PROBE 不花一次性的票, 所以检查的报价 仍然对以后。 设置 自动检查自己公布的URL;电话在征得同意前重新检查扫描报价。 这个包 不再出口——从 @byokit/pair回答探测器的宿主.
  2. 这是电脑的防火墙封锁了港口吗? 这是这个包裹的 firewall({ port }) (只有节点). 它只读普通用户可能读到的.. ufw status,则 nft list ruleset,则 iptables -S linux; macOS上的应用程序防火墙状态; netsh advfirewall ——和 从未要求管理员访问 。 任何无法读取的东西 'unknown'这是一个诚实的答案: 把它当作"检查另一种方式", 从来没有像封锁或清晰.
import { firewall } from '@byokit/discover';

const verdict = await firewall({ port: 8792 });
console.log(verdict.blocked, verdict.how);  // true | false | 'unknown', plus the firewall that said so
if (verdict.blocked !== false) console.log(verdict.nextStep);  // plain words, never a sudo command

blocked: true 列出拒绝规则; false 表示防火墙已关闭或让端口通过. 'unknown' 覆盖一个活动防火墙,没有规则命名端口(包括macOS,它决定每 app 而不是每个端口),需要管理员访问读取的状态,并设置此帮助工具 不检查。 过 platform 财务报告和审定财务报表 run 仅在测试中,用于重放被扭曲的命令输出 .

分级规则

这些是Muxr第0004号决定的规则.

  • 永远不要漏斗. 设置用途 tailscale serve --yes --bg --https=443 http://127.0.0.1:<port>,哪个 只在尾网内可见。 拒绝已启用的漏斗根, 包括其代理匹配时 ; 在更改路线或 DNS 名称之前关闭漏斗.
  • 服务器保持回转 服务( A)bind: ['127.0.0.1']) (中文(简体) ).
  • 这台机器是自己的 Self.DNSName 已使用. 缺少或无效的MagicDNS名称是一个错误. 登录退出或 已损坏的尾图也是个错误 。 无人不问就回到局域网.
  • 未记录的根处理器被拒绝 . 若为 / 打开 <name>:443 已经有任何处理器, reach 抛出,除非 previous 记录匹配的应用创建的映射。 选择 tailscale-direct 或删除不相关的绘图.
  • 所有权指纹. 坚持返回 ingress (单位:千美元){ kind, port, dnsName, proxy }并传为 previous。 。 。 . unserve 财务报告和审定财务报表 reach({ previous }) 只删除 / 同时它仍然指向这个代理; 兄弟姐妹路径仍然存在. 在 DNS 重命名时, 尝试在启用新名称之前删除已记录的旧根; 清理失败 返回其指纹 pendingCleanup,除了旧根上的漏斗停止了过渡。 设置后 或去除后,再次检查根;在设置后报告被占用的根,没有作进一步修改,同时 路由切换器保存失败清理 pendingCleanup。 。 。 . 分级CLI没有比较和设置:检查和写之间的变化仍然可以被覆盖. 校验后写会检测到一个相冲突的最终状态,但不能消除这一种族.
  • 直倒倒倒倒倒倒倒倒. 如果服务在尾网被禁用( 错误包括管理员链接) , 时间 退出,或被带走,使用 via: 'tailscale-direct'与 previous,也可以删除此软件包的映射. 如果无法校验清理, 请求的路由仍然以 pendingCleanup: previous;坚持 指纹和重试 unserve(pendingCleanup) 等会. auto 也保留 previous 当纹章消失时 它会回到局域网。 在删除工作服务映射前对地址进行明确的路由切换检查. 成功的清理省略 pendingCleanup。 。 。 . 如果一个 Service 写入成功但状态无法校验, 抛出的错误也带有 error.pendingCleanup;在报告错误之前坚持它,然后检查或稍后重试清理.

CLI是: 校对: tailscale 打开 PATH然后是macOS应用程序。 过 tailscale: { bin, timeoutMs } 来选择另一个。 这个 下级步骤也导出 : tailscaleStatus, (中文(简体) ), tailscaleName, (中文(简体) ), inspectServe, (中文(简体) ), serve, (中文(简体) ), unserve,以及 routes 用于界面列表.

对于一个接线员, await tailscaleState() 返回时 { installed, backendState, needsSignin, reason, dnsName, ips, keyExpiry?, Peer? } 没有扔. backendState, (中文(简体) ), reason 和已实现的 dnsName 当未知时可以缺席. 缺失的CLI,超时,变形的JSON和守护进程故障都是诊断结果;他们从不设置Service或签名. needsSignin 只对 NeedsLogin· ; NeedsMachineAuth 相反,要求行政部门批准 Stopped 这并不意味着 登录。 现有 tailscaleStatus() 仍然有CLI失败.

keyExpiry 保存一个有效的 Self.KeyExpiry 日期字符串; 主机选择如何标签已过期的密钥 . Peer 是经过验证的 { TailscaleIPs, DNSName?, Online? }时缺席 当 CLI 报告空地图时为空 。 额外的字段和错误的条目被丢弃 .

纯洁的帮手 原始状态 JSON· ; isPeer 也接受快照键入 Peer 地图. isPeer(status, ip) 检查 Peer[*].TailscaleIPs,接受一个 IPv4-映射的套接字地址(::ffff:100.64.0.2),并排除 Self。 。 。 . 离线同伴仍然算作同伴. 同伴会籍是一个发现提示:链接的握手必须认证设备.

mDNS 数据

广告(节点)

advertise({ type, port, name?, txt?, addresses? }) 发表 _<type>._tcp 与 bonjour服务 返回时 { stop }拨号 URL txt。 。 。 . 该工具包过滤 bonjour-service的 A/AAA记录到 addresses,默认为 routes().lan,所以多克,VPN和 尾网地址默认除外. 明确的列表可以选择包括 IPv6 在内的接口地址; 只有 地址 bonjour- service 生成可以发布. 一个空列表不发布 A/AAAA 记录. 所选列表 当广告开始时被快照,同样的过滤器适用于停站时的告别记录. 发现元数据 (PTR,SRV和TXT)被保留. 找到错误的计算机的设备会失败链接的握手,因为主机密钥被固定.

import { advertise } from '@byokit/discover';

const ad = await advertise({ type: 'muxr', port: 8792, txt: { url: 'ws://192.168.1.20:8792' } });
// later
await ad.stop();

浏览( 本地反应)

在本地反应( 软件包) 下 react-native 出口条件, @byokit/discover 也浏览局域网这样一个应用程序 可以在不输入地址的情况下找到服务 :

import { browse, scan } from '@byokit/discover';

// Stream discovery: start, then stop when done.
const found = browse({ type: 'muxr' });                  // protocol 'tcp', domain 'local.' by default
found.on('found', (s) => console.log(s.name, s.addresses, s.port, s.txt));   // first resolve of a name
found.on('updated', (s) => console.log('refreshed', s.name));                // a known name resolved again
found.on('lost', (name) => console.log(name, 'left'));
found.on('error', (error) => console.log(error.message));
found.on('stopped', ({ reason }) => console.log(reason)); // 'preempted' if another browse starts
found.stop();                                            // idempotent

// Time-boxed: collect for N ms, then stop. Later resolves replace the earlier entry, first-seen order.
const hosts = await scan({ type: 'ssh', ms: 8000 });     // rejects on error or preemption

A 类 BrowseService 携带 name, (中文(简体) ), host, (中文(简体) ), addresses, (中文(简体) ), port (单位:千美元)0 当时,天台没有赏赐任何人 txt (弦声) (仅限数值)。 被钉住 react-native-zeroconf 抚养(0.17.4由@byokit/discover提供,而不是应用.

  • 一一一一一一浏览. 一个本地浏览器一次运行一个浏览. 开始另一个 browse 或者说 scan 预置当前控件, 包括当两者请求相同类型时: 它收到一个 stopped 事件为 { reason: 'preempted' },失去已知的服务,而不恢复。 一个先发制人 scan 拒绝; 呼叫者 需要不断发现时,必须在完成其他扫描后开始新的浏览.
  • 活动匹配. 已解决的事件必须在 fullName; 清除仅适用于 浏览找到的名字 。 原生错误在先发后被忽略一秒钟. 本地模块 提供不扫描 ID: 用于新浏览重用名称的未打入后删除, 或第二秒后出现错误, 仍然可以归结为新扫描;静态第二时发生的一个真实错误也被忽略.
  • 入会. 默认节点条目不导入本地模块; 使用 react-native 出口条件 眉来眉去. 博览会的应用程序在添加了@byokit/discover后必须重建其本土二进制.
  • 机器人模拟器. mDNS多播对仿真器不起作用;在真设备上测试发现.

测试

test/journey-reach.test.ts 驱动构建的软件包, 如主机应用程序 : reach, (中文(简体) ), serve编号 :unserve, (中文(简体) ), recommend, (中文(简体) ), advertise, (中文(简体) ), routes编号 :directRoutes 财务报告和审定财务报表 tailscaleState 对付假人 tailscale 记录每个电话的CLI 真实的 二进制从不运行,也没有包出: mDNS 广告使用假的发布器, React Industrial 浏览 API (单位:千美元)test/browse.test.ts)使用假零conf模块.

许可证

阿帕奇2.0 (英语). 见 自由主义 财务报告和审定财务报表 通知。 。 。 .

版本与发布记录

@byokit/discover 共发布 11 个版本,首次发布于 2026/10/06;过去 12 个月发布了 11 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.8.7latest2026/10/2514 天前
0.8.62026/10/2316 天前
0.8.52026/10/2317 天前
0.8.42026/10/1822 天前
0.8.32026/10/1722 天前
0.8.22026/10/1623 天前

关于 @byokit/discover 的常见问题

@byokit/discover 是什么?

TypeScript套件让人们通过他们已经支付的人工智能计划,在网络,电话和桌面上登录到你的应用程序.

如何安装 @byokit/discover?

在项目目录运行 npm install @byokit/discover,或使用 pnpm add / yarn add / bun add。

@byokit/discover 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@byokit/discover 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@byokit/discover 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@byokit/discover 可以商用吗?

@byokit/discover 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@byokit/discover 的下载量有多少?

根据 npm 官方下载统计,@byokit/discover 在 2026/10/09 – 2026/11/07 这 30 天内被下载 3,814 次,日均约 127 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@byokit/discover 还在维护吗?

最新版本 0.8.7 发布于 2026/10/25(14 天前);至今共发布 11 个版本,其中过去 12 个月发布了 11 个;首次发布于 2026/10/06。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。