@finueva/pub-sub

中文文档
0.14.0发布于 2026/10/30MITTypeScriptES Module近 30 天下载 2420

Finueva Pub 子网络 SDK

中文使用文档
文档目录15 节
  1. 安装 SDK
  2. 不透明通道信号
  3. API 摘要
  4. 创建浏览器客户端
  5. 接收现场事件
  6. 每个浏览器共享一个连接
  7. 启用浏览器推
  8. 创建服务器客户端
  9. 开罚单
  10. 管理已注册的推力安装
  11. 发布事件
  12. 处理错误
  13. 学多点
  14. 许可证
  15. 私人手表(未公布候选人)

@finueva/pub-sub

使用 @finueva/pub-sub 接收现场活动,管理浏览器推,出票,发布活动.

已确认的Web 连接可选择使用 connect({ deliveryMode: "acknowledged", reauthorization: true, onEvent }) 在经纪人支持现场更新后。 SDK通过同样方式获得新票 getTicket 提供者,请求采取行动 reauthorize (签名像 connect,并重新授权现有订阅。 申请表必须重新验证每张票申请的会话权限。 成功更新不会释放新的打开状态; 实际失败会关闭套接字, 仍然需要应用程序重新连接/ 抓取 。 在启用此选项之前部署经纪人支助。 默认的边界替换行为和遗产v1不变.

Pub Sub是实验性的. 它试图立即交付。 它不保留、重放、顺序、重试、去重复或确认事件.

安装 SDK

pnpm add @finueva/pub-sub

Node.js工具和服务器应用程序需要Node.js 22或更晚.

不透明通道信号

下一个小SDK加 client.createSignalingClient(...) 到峡谷 createPubSubClient 结果。 它为Cloudflare使用相同的配置服务源和WebSocket厂或由明确组成的节点中继器. 信任的服务器客户端 issueChannelTicket({ userId, channel, publish, subscribe, expiresAt }) 申请授权后提供一次性使用补助金; expiresAt 这是一个绝对的毫秒期限,最多提前60秒.

const signaling = await client.createSignalingClient({
  userId: authorizedOwner,
  channel: authorizedChannel,
  getTicket: (signal) => requestApplicationChannelTicket(signal),
  onPeers: (self, peers) => peerProvider.updatePeers(self, peers),
  onEvent: ({ peerId, payload }) => peerProvider.receive(peerId, payload),
});
signaling.publish(opaquePayload, optionalRecipientPeerId);
await signaling.closed;

userId 是房间的主人名空间 而不是连接参与者的个人身份 获准使用同一所有者/渠道的参与者获得明确签名 peerId 连接身份。 其他拥有相同频道名的所有人被隔离. 目前所有者房容量为4个接通. 数据和同行存在在能力到期时终止;应用程序必须重新授权并重新连接。 Pub Sub不解释有效载荷或执行WebRTC或资源政策.

connectChannel 也可从下列网址获得: @finueva/pub-sub/channels。对于服务器宣布的替代节点路线,请通过所公布的绝对 websocketUrl;它必须共享配置的服务源,并且不包含查询、片段或证书。 服务器验证了票签的准确路径. 两种运行时间都使用通道/ticket子protocols,从未使用过售票查询参数. 见仓库的 频道架构 用于节点供应商合同和路由构成。 假设服务推出后发布的微量发布;来源可用性并不意味着这些方法存在于安装在更早的SDK中.

API 摘要

浏览器客户端 :

方法说明
connect()打开现场事件连接 .
enablePush()启用当前浏览器安装的推动 .
disablePush()禁用当前浏览器安装的推力 .
onPush()听听推收和通知窃听器.

服务器客户端 :

方法说明
issueTicket()开出一张订户业务的票. A 类 connect 罚单可以声明 capabilities 例如 presence.hint.subject.v1,则a leaseKey 用于套接字输入的显示表.
publish()向一个应用程序定义的用户发布事件 .
putInstallation()以可选的重试安全突变字段注册安装 .
observeInstallation()请检查date=中的日期值 (帮助).
deleteInstallation()只删除预期的安装化身.

创建浏览器客户端

提供经认证的用户身份证和 getTicket 函数。 该函数必须请求应用程序服务器的出票 .

import { createPubSubClient } from "@finueva/pub-sub";

const pubSub = await createPubSubClient({
  userId: currentUser.id,
  async getTicket({ action, signal }) {
    const response = await fetch("/api/pub-sub/ticket", {
      method: "POST",
      credentials: "include",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ action }),
      signal,
    });

    if (!response.ok) throw new Error("Pub Sub ticket unavailable");
    return ((await response.json()) as { ticket: string }).ticket;
  },
});

您的服务器必须从已认证的会话数据获取用户ID 。 不接受请求机构的用户ID. 从不向浏览器代码发送 Pub Sub API 令牌 .

生产是默认的环境. 没有明确的公开配置,客户端创建会让一个进入 /v1/configuration 在嵌入式生产服务来源上,没有饼干或Vault头. 它在3秒和16个KiB内接受一个完整的公用捆绑;重定向,失败,以及无效或部分的回放保留完整的嵌入捆绑而无需重试. 通过 serviceOrigin, (中文(简体) ), variables,或 push.firebase 跳过此请求,并将调用器值合并到选中的嵌入式捆绑上。 过 environment: "staging" 以选择中转服务和后退捆绑。 该服务返回其缓存配置快照, 而不是新读的 OpenBao 。 浏览器访问需要服务允许的来源 .

接收现场事件

打电话 connect() 和处理事件 onEvent。 。 。 .

const connection = await pubSub.connect({
  onEvent(event) {
    if (event.type === "order.updated") {
      refreshOrder(event.data);
    }
  },
});

// Close the connection on sign-out or account change.
connection.close();
await connection.closed;

event.data 实值 unknown在使用前验证。 SDK没有重新连接. 打电话 connect() 以创建新的连接。 断开时发送的事件不重放 .

注册的托管应用程序必须设置 deliveryMode: "acknowledged" 内 connect()此选择 finueva.pubsub.v2 而不退为v1. SDK验证了每个被捆绑的帧,在返回匹配的运输信用之前承认它为回调. 一个同步回调失败会关闭连接而无信用. 信用确认运输准入,而非同步持久性或电文读取状态.

主机服务在未完成的框架,字节,附件或最后期限界限被达到后会关闭缓慢的连接. 在重新连接或光标缺口后通过应用程序的 API 恢复当前授权状态 。 不保留活事件体进行运输回放. 独立的遗留应用命名空间保留其单独的现有协议.

每个浏览器共享一个连接

与 connectionSharing,每个标签的确认 connect() 加入浏览器中每个用户一个套接字, 而不是每个选项卡中每个经纪人的8个用户。 这个 connect() API和返回的连接不变.

import PubSubWorker from "@finueva/pub-sub/shared-connection-worker?sharedworker";

const pubSub = await createPubSubClient({
  userId,
  getTicket: async ({ action, signal, leaseKey }) => myTicket({ action, leaseKey }, signal),
  connectionSharing: { sharedWorker: () => new PubSubWorker({ name: "pub-sub" }) },
});
  • 套接字在一个共享工作人中运行, 当你提供一个, 否则在使用 Web Locks 选择的领袖标签中运行 BroadcastChannel。 。 。 . mode: "leader" 跳过共享工作者.
  • 没有网页锁定和 BroadcastChannel,每个标签单独连接,完全一样不共享.
  • 每个标签仍然用自己的票来证明自己的会话 getTicket。拒绝为另一个用户提供机票,不同的用户从来不共用套接字.
  • 每个分页都接收其用户的每个事件. 每分页都会确认一个事件 onEvent 已经返回.
  • 领头人交接,领头人损失或工人停手 通常每个分页 closed 州,所以重新连接 和赶超留在你的.
  • 共享连接通行证 leaseKey 改为 getTicket 联合国 connect 门票并曝光为 connection.leaseKey把它签入罚单 并用它来做套接字表.

见ADR0006(每个浏览器一个共享用户连接),用于设计及其取舍.

启用浏览器推

在控制您的应用程序来源的服务人员中安装收听器.

import { installPubSubServiceWorker } from "@finueva/pub-sub/service-worker";

installPubSubServiceWorker({
  notificationIcon: "/notification.png",
  openPath: "/inbox",
});

打电话 enablePush() 在用户动作后,例如点击按钮.

const stopPushEvents = pubSub.onPush((event) => {
  if (event.kind === "tapped") {
    openEvent(event.eventId, event.eventType);
  }
});

const enabled = await pubSub.enablePush();

// Disable push on opt-out, sign-out, or account change.
await pubSub.disablePush();
await enabled.unlisten();
await stopPushEvents();

按下事件包含事件 ID、事件类型、可选显示文本以及可选的 a tag 和路线 data 您的服务器所附带的条目 。 应用程序打开后从授权的 API 获取当前应用程序数据 .

服务- 员工帮助者也接受 onPush(metadata) 显示和返回前运行的钩子 "default" 或者说 "handled";扔出或拒绝返回到 "default"时 openPath 设置,一个水龙头导航一个同一来源的现有窗口。 默认情况下, SDK 将它的安装 ID 和 order 保存在 localStorage 在不限制用户范围的密钥下; 通过用户范围 push.storage 如果多个用户共享浏览器配置文件.

创建服务器客户端

仅从服务器代码导入服务器入口 .

import { createPubSubServerClient } from "@finueva/pub-sub/server";

const pubSub = createPubSubServerClient({
  apiToken: process.env.PUB_SUB_API_TOKEN!,
});

开罚单

const ticket = await pubSub.issueTicket({
  userId: authenticatedUser.id,
  action: "connect",
});

管理已注册的推力安装

已注册的安装写作可能省略了"一能"字段的相容性;每个这样的写作都是由服务器发行的新安装化身,没有再播放的收取. 移民意识召唤者应坚持UUIDv7 idempotencyKey一种新鲜的化身UUID,和 expiresAt 在第一次请求之前,再使用 每次重试时, 都会有确切的拖累。 固定的过期时间必须是钥匙嵌入时间戳后七天. 其结果包括不可改变的驱逐对夫妇installationId 加号 incarnation)和单独重算 authority 状况(owned, (中文(简体) ), unowned,或不透明 superseded) (中文(简体) ).

使用 observeInstallation() 以在修复或倒置前检查符号所有权。 服务器客户端 deleteInstallation() 是有条件的:通过符号和预期的化身;它称为单独的 /authority 结束点和返回 removed, (中文(简体) ), absent,或 superseded。浏览器/ Tauri 来宾 disablePush() 仍然以罚单为主,在遗留的DELETE路线上没有身体。 即使远程撤销失败,它也会耗尽听众,使本地提供者的代号失效,但拒绝者仍保留远程清理的不确定性。 它拒绝 PUSH_TOKEN_DELETE_FAILED 只有在服务回答安装被移除,本地提供者的代号无法被删除后,应用程序才能完成该代码上的选择退出或签名. 任何其他拒绝都未经证实.

发布事件

const result = await pubSub.publish({
  userId: recipient.id,
  event: {
    id: crypto.randomUUID(),
    type: "order.updated",
    occurredAt: new Date().toISOString(),
    data: { orderId: order.id },
    push: {
      title: "Order updated",
      body: "Open the application for details.",
    },
  },
});

奥米 push 发送此事件只用于实时连接。 将私人信息从推出显示文本中保留,因为操作系统可以在锁屏幕上显示.

处理错误

SDK 操作抛出 PubSubError。使用它的马厩 code 属性来选择重试或用户界面行为.

import { PubSubError } from "@finueva/pub-sub";

try {
  await pubSub.connect({
    onEvent(event) {
      handleApplicationEvent(event);
    },
  });
} catch (error) {
  if (error instanceof PubSubError && error.code === "OPERATION_TIMED_OUT") {
    showRetryAction();
  }
}

出版非一能. 未知结果后的重试可以不止一次地发送同一事件.

学多点

许可证

麻省理工学院

私人手表(未公布候选人)

服务器入口提供 registerPresenceWatch, (中文(简体) ), renewPresenceWatch 财务报告和审定财务报表 cancelPresenceWatch配置已注册 application 别名及其别名 apiToken生成新手表 UUID v4 并生成 UUID 每个新命令选择,然后保留返回的手柄进行更新/取消。 申请表必须在每次行动前重新授权听众和每个选定的对象; Pub Sub 注册证书不能确定组织成员。 返回的时间戳是不可改变的服务器元数据,而不是授权证明. 这些方法只有服务器;完整的应用程序存在和节点提供者的等同性仍未完成.

registerPresenceWatch 财务报告和审定财务报表 renewPresenceWatch 接受此选项 leaseKey 观众套接字连接(签名者: issueTicket({ action: "connect", leaseKey })) (中文(简体) ). 答案随即 leaseBinding数字 : socket 当服务保持租赁在套接字的原地重授权 并在最后一个套接字扣上钥匙后十五秒结束时, request 当你必须不断更新。 捆绑的手表仍然需要在十五分钟索引保留结束之前重新注册,申请方拥有吊销:在会员终止时取消手表. 参见嵌入式存在表租赁架构页面.

setPresenceVisibility 提交订购的批次,最多50个目前的应用程序自主政策修订。 它需要注册 application 别名,拒绝更改或部分回复,绝不接受呼叫时钟. leaseMs (60 000至900 000美元)要求延长租约;只有在每次政策过渡一次被写成新的订正时才使用,因为反复订正永远不会缩短长期租约。 失败的多硬性操作可能会将限定数额的赠款留给成功的硬性操作;从新读的政策中重试,保留应用程序的披露检查. 缺少或过期的控制被隐藏. 该候选人没有建立完整的应用程序存在或节点对等.

wakePresencePolicy 提交应用程序当前条形政策标识:正 sequence, (中文(简体) ), availabilityRevision, (中文(简体) ), dndRevision,一个UUID v4 changeId 财务报告和审定财务报表 reason. 申请登记必须载有获得许可的经营者 presence_policy_wake 能力。 收据系指一项活的持久义务被接受,从未交付. PRESENCE_POLICY_CONFLICT 指命令与所保留身份相矛盾(Stale sequence,已改变而无新序列的字段,被再利用的更改ID或被后退的修改);不重试它,取而代之的是重读犬形状态. PRESENCE_POLICY_RETIRED 指相同命令的工作已经完成或已过期;以新的顺序恢复并更改ID. PRESENCE_POLICY_RATE_LIMITED 表示稍后对同一命令的再试可能成功. 无法获取或模棱两可的结果对有限度的重试保留同样的命令。 客户端不进行自动重试 .

版本与发布记录

@finueva/pub-sub 共发布 16 个版本,首次发布于 2026/08/20;过去 12 个月发布了 16 个版本。

版本发布日期距今
0.14.0latest2026/10/3015 天前
0.13.02026/10/2817 天前
0.11.02026/10/1926 天前
0.10.02026/10/131 个月前
0.9.12026/10/131 个月前
0.9.02026/10/101 个月前

关于 @finueva/pub-sub 的常见问题

@finueva/pub-sub 是什么?

Finueva Pub 子网络 SDK

如何安装 @finueva/pub-sub?

在项目目录运行 npm install @finueva/pub-sub,或使用 pnpm add / yarn add / bun add。

@finueva/pub-sub 支持 TypeScript 吗?

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

@finueva/pub-sub 支持 ESM 还是 CommonJS?

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

@finueva/pub-sub 需要什么版本的 Node.js?

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

@finueva/pub-sub 可以商用吗?

@finueva/pub-sub 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@finueva/pub-sub 的下载量有多少?

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

@finueva/pub-sub 还在维护吗?

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