搜尋完整文件

輸入關鍵字,例如 idempotency、proposal lifecycle 或權限。

選擇 開啟
English
瀏覽文件

Relay · Client integration

SDK 與 Widget

Relay 提供 TypeScript core SDK、React binding 與 UI、Vue composable、script-tag widget,以及 browser streaming renderer。應選擇符合產品需要的最薄一層。Authentication、channel membership 與 business authorization 仍由 host 負責。

Distribution status

@tonetify/relay@0.1.0-beta.1 已透過 npm 的 beta tag 公開發布。Package 包含 ESM、CommonJS、type declaration、streaming style 與 IIFE widget bundle,採用 MIT 授權,且不包含 source map。

明確安裝測試版本:

npm install @tonetify/relay@0.1.0-beta.1

Production automation 應固定使用完整的 beta version。Package 已公開,但 Relay 尚未提供 server-to-SDK compatibility matrix 或 upgrade policy。

Relay + Govern

SDK 傳遞 turn,Govern 約束 reply

組合路徑

  1. Host

    從 Govern 取得有 scope 的 Relay session。

  2. Relay SDK

    加入 channel,傳送 user message。

  3. Govern

    處理 message.created,並選擇 effect。

  4. Relay

    提交並送出最後的 reply。

Core SDK

Host 必須提供 JWT、tenant ID、channel ID 與 WebSocket URL。只有 reaction inspection、notification mute 等 REST convenience helper 需要 apiUrluserId 可讓這些 helper 計算 viewer-specific state。

import { ChatClient } from "@tonetify/relay";

const client = new ChatClient({
  url: "wss://relay.example.com/socket",
  apiUrl: "https://relay.example.com",
  token,
  userId
});

client.connect();

const channel = client.channel(channelId, tenantId);

channel.on("msg:new", (message) => {
  console.log(message.seq, message.body);
});

await channel.join();
await channel.send("Hello from Relay", {
  nonce: crypto.randomUUID()
});

只能在 browser 呼叫 connect(),server-side rendering 期間呼叫會直接 throw。應在 React effect、Vue client scope,或相等的 browser lifecycle 內 mount,並在 integration dispose 時呼叫 disconnect()

穩定核心與預覽介面

契約測試版的穩定核心包括:

  • join、leave、可安全重試的 send 與 cursor update;
  • 穩定的 presence_statepresence_diffmsg:newcatch_up:truncatedunread_count 事件;
  • 連線狀態與生命週期事件;
  • notification mute helper。

ChatChannel 也提供 edit、retract、pin、unpin、thread、reaction 與 typing 能力。這些目前屬於預覽介面。方法可以使用,但相關 WebSocket event name、payload 與恢復行為在契約測試期間仍可能改變。

如果 caller 沒有提供 nonce,channel.send() 會自動產生一個。Send result 不確定而需要 retry 時,host 必須保留原 nonce。再次呼叫 send() 卻沒有傳回原 nonce,代表新的 logical send。

React integration

需要 minimal conversation UI 時,可以使用 RelayWidget

import { RelayWidget } from "@tonetify/relay/react";

export function SupportChat({ token }: { token: string }) {
  return (
    <RelayWidget
      url="wss://relay.example.com/socket"
      apiUrl="https://relay.example.com"
      token={token}
      userId="current-user-id"
      tenantId="tenant-uuid"
      channelId="channel-uuid"
      channelName="Support"
    />
  );
}

Product-owned UI 可以組合 ChatProvideruseChanneluseMessagesusePresence,或直接使用 core SDK。React layer 會在 mount 時 connect、join 指定 channel、套用 optimistic send,並在 unmount 時 disconnect。

Script-tag widget

Build 會產生 dist/tonetify-relay-widget.global.js。Host 需要託管這份確切 artifact,再明確 mount:

<div id="chat-root"></div>
<script src="/assets/tonetify-relay-widget.global.js"></script>
<script>
  window.TonetifyRelay.init({
    url: "wss://relay.example.com/socket",
    token: "host-signed-jwt",
    tenantId: "tenant-uuid",
    channelId: "channel-uuid",
    target: "#chat-root",
    mode: "shadow",
    theme: { primaryColor: "#3158d3" }
  });
</script>

mode 可以是 shadowiframe。Iframe mode 使用 same-document srcdoc,只是 styling boundary,不是 cross-origin security boundary。Widget 會顯示 minimal live timeline、presence status、connection error 與 message composer。它不是完整的 support desk 或 moderation UI。

再次呼叫 TonetifyRelay.init() 時,會先 destroy 前一個 singleton widget,再 mount 新 instance。

Vue 與 streaming

@tonetify/relay/vue 提供 useChatuseChanneluseMessagesusePresence。這些 composable 已實作並有測試,但仍是 preview integration surface。在公開 compatibility policy 建立前,它們仍可能變更。

@tonetify/relay/streaming 提供 browser-only renderer,可逐步顯示 text 或 Markdown,也包含有上限的 CJK tokenization。它只影響 presentation。Relay 仍只儲存一份 final message body,沒有 server streaming-message contract。

Recovery boundary

Phoenix 會 reconnect socket 並 rejoin channel,但 default React、Vue 與 script widget store 都只存在 memory。Page reload 後會失去 last known seq。High-level binding 目前也不會 persist 或完整 drain truncated catch-up window。

需要可靠的 history recovery 時,應 persist 最新 confirmed seq、呼叫 channel.join(lastSeq)、監聽 catch_up:truncated,再透過 REST history contract 取得後續 page。不能把目前 SDK 描述成具備 offline storage 或 exactly-once client rendering。

SDK 目前沒有 attachment upload、search、channel administration、user export 或 tenant operation helper。這些 surface 請使用已公開的 HTTP API。

Artifact verification

Distribute build 前執行:

cd sdk
npm run build
npm test
npm run typecheck
npm run pack:check

這些 command 能證明 repository 內的 package 可以 build、typecheck、test 與 pack。公開的 0.1.0-beta.1 artifact 也已從 npm 讀回驗證。這不代表已建立 browser compatibility target、跨版本 server compatibility、semantic-version support 或 managed upgrade service。

相關文件:即時事件與重新連線 · 身分驗證 · Relay 概覽