搜尋完整文件

輸入關鍵字,例如 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 需要 apiUrl。userId 可讓這些 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_state、presence_diff、msg:new、catch_up:truncated 與 unread_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 可以組合 ChatProvider、useChannel、useMessages 與 usePresence,或直接使用 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 可以是 shadow 或 iframe。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 提供 useChat、useChannel、useMessages 與 usePresence。這些 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 概覽