@chronista-club/unison-client 1.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +130 -0
  2. package/dist/channel/async_queue.d.ts +20 -0
  3. package/dist/channel/async_queue.d.ts.map +1 -0
  4. package/dist/channel/datagram_channel.d.ts +28 -0
  5. package/dist/channel/datagram_channel.d.ts.map +1 -0
  6. package/dist/channel/default_codec.d.ts +12 -0
  7. package/dist/channel/default_codec.d.ts.map +1 -0
  8. package/dist/channel/dispatcher.d.ts +62 -0
  9. package/dist/channel/dispatcher.d.ts.map +1 -0
  10. package/dist/channel/frame.d.ts +52 -0
  11. package/dist/channel/frame.d.ts.map +1 -0
  12. package/dist/channel/identity.d.ts +47 -0
  13. package/dist/channel/identity.d.ts.map +1 -0
  14. package/dist/channel/types.d.ts +127 -0
  15. package/dist/channel/types.d.ts.map +1 -0
  16. package/dist/channel/unison_channel.d.ts +53 -0
  17. package/dist/channel/unison_channel.d.ts.map +1 -0
  18. package/dist/channel/varint.d.ts +20 -0
  19. package/dist/channel/varint.d.ts.map +1 -0
  20. package/dist/client.d.ts +69 -0
  21. package/dist/client.d.ts.map +1 -0
  22. package/dist/codec/codec.d.ts +33 -0
  23. package/dist/codec/codec.d.ts.map +1 -0
  24. package/dist/codec/json_codec.d.ts +24 -0
  25. package/dist/codec/json_codec.d.ts.map +1 -0
  26. package/dist/codec/proto_codec.d.ts +32 -0
  27. package/dist/codec/proto_codec.d.ts.map +1 -0
  28. package/dist/error/category.d.ts +19 -0
  29. package/dist/error/category.d.ts.map +1 -0
  30. package/dist/index.d.ts +38 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +2534 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/transport/errors.d.ts +19 -0
  35. package/dist/transport/errors.d.ts.map +1 -0
  36. package/dist/transport/trust.d.ts +10 -0
  37. package/dist/transport/trust.d.ts.map +1 -0
  38. package/dist/transport/types.d.ts +72 -0
  39. package/dist/transport/types.d.ts.map +1 -0
  40. package/dist/transport/web_transport.d.ts +35 -0
  41. package/dist/transport/web_transport.d.ts.map +1 -0
  42. package/dist/wire/packet.d.ts +45 -0
  43. package/dist/wire/packet.d.ts.map +1 -0
  44. package/dist/wire/packet_header.d.ts +59 -0
  45. package/dist/wire/packet_header.d.ts.map +1 -0
  46. package/dist/wire/proto.d.ts +57 -0
  47. package/dist/wire/proto.d.ts.map +1 -0
  48. package/dist/wire/protocol_message.d.ts +40 -0
  49. package/dist/wire/protocol_message.d.ts.map +1 -0
  50. package/package.json +65 -0
package/README.md ADDED
@@ -0,0 +1,130 @@
1
+ # @chronista-club/unison-client
2
+
3
+ > TypeScript client SDK for the [Unison protocol](https://github.com/chronista-club/club-unison).
4
+ > Part of the **v1.0 polyglot client base** (= server stays Rust, client polyglot for adoption surface).
5
+
6
+ **Status**: `1.0.0-alpha.2` — v1.0 sprint feature-complete. The SDK genuinely talks to the Rust server over **real WebTransport** (verified by `tests/integration/webtransport_e2e.test.ts`). See [design/typescript-client-api.md](../../design/typescript-client-api.md) for the SDK design contract.
7
+
8
+ ---
9
+
10
+ ## What this is
11
+
12
+ Unison is a KDL schema-driven, QUIC-based protocol with both **stream channels** (request/response + event) and **datagram channels** (broadcast event). The Rust crate `club-unison` ships the server and Rust client. This package is the **TypeScript client SDK** that lets:
13
+
14
+ - **Browsers** (via [WebTransport](https://www.w3.org/TR/webtransport/)) speak unison directly to a Rust server (= no REST gateway)
15
+ - **Node.js** clients connect server-to-server in TypeScript (= optional, v1.x)
16
+
17
+ The asymmetric design — **fat Rust server, thin polyglot clients** — keeps complexity (TLS, accept loops, connection management) in one language while broadening the adoption surface.
18
+
19
+ ## v1.0 status (= what shipped)
20
+
21
+ The v1.0 sprint is feature-complete. All phases are done:
22
+
23
+ - **Phase 1** ✅ — KDL-driven TypeScript code generation (type interfaces + channel metadata)
24
+ - **Phase 2a-e** ✅ — Package skeleton, WebTransport transport adapter, channel wrappers
25
+ (`UnisonChannel<M>` / `DatagramChannel<M>`), codecs (`JsonCodec` + `ProtoCodec`), tests + bundle build
26
+ - **Phase 3** ✅ — `connect()` facade + Vantage Point dashboard proof point demo
27
+ - **Phase 4-5** ✅ — `unison` developer CLI (ping / sniff / mock / schema-lint), `ErrorCategory` framework
28
+ - **Phase 6** ✅ — Rust-compatible wire format + **real WebTransport E2E** (TS SDK ↔ Rust server)
29
+ - **Phase 7** ✅ — Cross-language E2E integration tests in CI
30
+ - **Phase 8** ✅ — User-facing docs (this file + the guides below)
31
+
32
+ What is **v1.x deferred** (honest gaps):
33
+
34
+ - TypeScript codegen for datagram channels (Rust codegen has it; TS handwrites the meta for now)
35
+ - proto-descriptor codegen (`ProtoCodec` works, but KDL → descriptor generation is not automated)
36
+ - Node native WebTransport (Node needs the `@fails-components/webtransport` polyfill)
37
+ - Safari / Firefox WebTransport (Chromium-based browsers are the official support matrix)
38
+ - per-channel codec override, auto-reconnect helper
39
+
40
+ See [`design/typescript-client-api.md`](../../design/typescript-client-api.md) for the full API design contract.
41
+
42
+ ## Quickstart
43
+
44
+ For the full end-to-end walkthrough (KDL schema → Rust server → TS client), see
45
+ [`guides/quickstart.md`](../../guides/quickstart.md). API reference:
46
+ [`guides/typescript-sdk.md`](../../guides/typescript-sdk.md).
47
+
48
+ ```typescript
49
+ import { connect, type ChannelMeta } from "@chronista-club/unison-client";
50
+
51
+ const EchoMeta = {
52
+ name: "echo",
53
+ backend: "stream",
54
+ from: "client",
55
+ lifetime: "persistent",
56
+ events: [],
57
+ requests: { Echo: { request: "EchoReq", response: "EchoResp" } },
58
+ } as const satisfies ChannelMeta;
59
+
60
+ // Connect — cert pinning for a dev self-signed server (loopback only).
61
+ const client = await connect({
62
+ url: "https://127.0.0.1:4439",
63
+ trust: { certHash: "<CERT_HASH printed by the server>" },
64
+ awaitIdentity: false,
65
+ });
66
+
67
+ const echo = await client.openChannel(EchoMeta);
68
+ const reply = await echo.request("Echo", { text: "hello-unison" });
69
+ console.log(reply); // { text: "hello-unison" }
70
+
71
+ await echo.close();
72
+ await client.disconnect();
73
+ ```
74
+
75
+ ## Architecture
76
+
77
+ ```
78
+ clients/typescript/
79
+ ├── src/
80
+ │ ├── index.ts ← public entry (= re-exports the surface below)
81
+ │ ├── client.ts ← connect() + UnisonClient facade
82
+ │ ├── transport/ ← WebTransport adapter
83
+ │ ├── channel/ ← UnisonChannel / DatagramChannel + dispatcher + frame
84
+ │ ├── codec/ ← JsonCodec + ProtoCodec
85
+ │ ├── wire/ ← Rust-compatible packet / protocol-message encode/decode
86
+ │ └── error/ ← ErrorCategory framework
87
+ ├── examples/ ← vp-dashboard.ts (Vantage Point proof point demo)
88
+ ├── tests/ ← vitest unit + integration tests (incl. real WebTransport E2E)
89
+ ├── package.json
90
+ ├── tsconfig.json
91
+ ├── vite.config.ts
92
+ └── vitest.config.ts
93
+ ```
94
+
95
+ ## Building from source
96
+
97
+ ```bash
98
+ cd clients/typescript
99
+ npm install # install dev deps (typescript / vite / vitest)
100
+ npm run build # vite build → dist/index.js + tsc → dist/index.d.ts
101
+ npm test # vitest run
102
+ npm run typecheck # tsc --noEmit (= type safety verification)
103
+ ```
104
+
105
+ ## Versioning policy
106
+
107
+ - TS package version is kept in **major.minor sync** with the Rust crate `club-unison`
108
+ - `1.0.0-alpha.x` — implementation phases, breaking changes allowed (current)
109
+ - `1.0.0-rc.x` — feature complete, dogfood phase with the chronista-club ecosystem
110
+ - `1.0.0` — stability commitment, breaking changes require v2.0
111
+ (dogfood exit criteria: 3+ caller × 3+ months × critical bug 0)
112
+
113
+ ## Compatibility
114
+
115
+ | Component | Required |
116
+ |---|---|
117
+ | Browser | Chromium-based 95+ (= WebTransport native) |
118
+ | Node.js | 20+ (= ESM + modern features) |
119
+ | TypeScript | 5.7+ (= consumer's tsconfig.json target) |
120
+ | Rust server | `club-unison` major.minor 一致 |
121
+
122
+ Safari / Firefox WebTransport support: tracked in v1.x roadmap, polyfill via WebSocket fallback is deferred to caller demand.
123
+
124
+ ## License
125
+
126
+ MIT — see [LICENSE](../../LICENSE-MIT) in the repository root.
127
+
128
+ ## Contributing
129
+
130
+ This SDK is part of the `chronista-club/club-unison` monorepo. Issues + PRs at https://github.com/chronista-club/club-unison.
@@ -0,0 +1,20 @@
1
+ /**
2
+ * AsyncQueue (= Phase 2c 内部 util)。
3
+ *
4
+ * push 駆動の値を `for await` で pull できる単一消費者 queue。 channel の
5
+ * `events()` が server push / datagram demux の payload を AsyncIterable に
6
+ * 橋渡しするのに使う。 producer は非同期境界なしで `push` / `end` を呼べる。
7
+ */
8
+ /** push された値を AsyncIterable として配る単一消費者 queue */
9
+ export declare class AsyncQueue<T> implements AsyncIterableIterator<T> {
10
+ #private;
11
+ /** 値を 1 件投入 (= 待機中 consumer があれば即配送) */
12
+ push(value: T): void;
13
+ /** queue を終端 (= 以降の `next()` は done、 待機中 consumer を解放) */
14
+ end(): void;
15
+ next(): Promise<IteratorResult<T>>;
16
+ /** consumer が `break` した時の cleanup hook (= queue 終端) */
17
+ return(): Promise<IteratorResult<T>>;
18
+ [Symbol.asyncIterator](): AsyncIterableIterator<T>;
19
+ }
20
+ //# sourceMappingURL=async_queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async_queue.d.ts","sourceRoot":"","sources":["../../src/channel/async_queue.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,gDAAgD;AAChD,qBAAa,UAAU,CAAC,CAAC,CAAE,YAAW,qBAAqB,CAAC,CAAC,CAAC;;IAM5D,wCAAwC;IACxC,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI;IAWpB,0DAA0D;IAC1D,GAAG,IAAI,IAAI;IAUX,IAAI,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IAalC,wDAAwD;IACxD,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IAKpC,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,qBAAqB,CAAC,CAAC,CAAC;CAGnD"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Datagram channel wrapper (= Phase 2c)。
3
+ *
4
+ * 共有 datagram path 上の virtual stream。 受信は `DatagramDispatcher` が
5
+ * `channelId` で demux した payload を pull、 送信は `channelId` varint prefix +
6
+ * codec-encoded payload を組み立てて `Connection.sendDatagram` に渡す。
7
+ *
8
+ * Rust `network/datagram_channel.rs` の `DatagramChannel` に対応する TS port。
9
+ */
10
+ import type { Codec } from "../codec/codec.js";
11
+ import type { Connection } from "../transport/types.js";
12
+ import type { DatagramDispatcher } from "./dispatcher.js";
13
+ import type { ChannelPayload, DatagramChannel, DatagramChannelMeta, EventName, EventPayload, EventType } from "./types.js";
14
+ /**
15
+ * `DatagramChannel` の concrete impl。 `openDatagramChannel(meta)` から構築する
16
+ * (= caller は直接 new せず factory 経由)。
17
+ */
18
+ export declare class DatagramChannelImpl<M extends DatagramChannelMeta> implements DatagramChannel<M> {
19
+ #private;
20
+ readonly name: M["name"];
21
+ readonly channelId: M["channelId"];
22
+ /** @internal `openDatagramChannel` から呼ぶ。 */
23
+ constructor(meta: M, connection: Connection, dispatcher: DatagramDispatcher, codec?: Codec<ChannelPayload>);
24
+ events(): AsyncIterableIterator<EventType<M>>;
25
+ sendEvent<N extends EventName<M>>(_name: N, payload: EventPayload<M, N>): Promise<void>;
26
+ close(): Promise<void>;
27
+ }
28
+ //# sourceMappingURL=datagram_channel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"datagram_channel.d.ts","sourceRoot":"","sources":["../../src/channel/datagram_channel.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,KAAK,EAAE,kBAAkB,EAAgB,MAAM,iBAAiB,CAAC;AACxE,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,SAAS,EACT,YAAY,EACZ,SAAS,EACV,MAAM,YAAY,CAAC;AAGpB;;;GAGG;AACH,qBAAa,mBAAmB,CAAC,CAAC,SAAS,mBAAmB,CAC5D,YAAW,eAAe,CAAC,CAAC,CAAC;;IAE7B,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC;IAWnC,4CAA4C;gBAE1C,IAAI,EAAE,CAAC,EACP,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,kBAAkB,EAC9B,KAAK,GAAE,KAAK,CAAC,cAAc,CAAgB;IAuB7C,MAAM,IAAI,qBAAqB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAIvC,SAAS,CAAC,CAAC,SAAS,SAAS,CAAC,CAAC,CAAC,EACpC,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,GAC1B,OAAO,CAAC,IAAI,CAAC;IAUhB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAMvB"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Channel payload の default codec (= Phase 2c)。
3
+ *
4
+ * design §5.1 の通り全 channel が default で JSON wire。 `JsonCodec.shared` は
5
+ * 構造的で状態を持たないため、 `ChannelPayload` 型に narrow した 1 instance を
6
+ * 全 channel で再利用する (= ProtoCodec は KDL→proto-descriptor codegen 待ち)。
7
+ */
8
+ import type { Codec } from "../codec/codec.js";
9
+ import type { ChannelPayload } from "./types.js";
10
+ /** 全 channel 共有の default payload codec (= JsonCodec.shared を型 narrow) */
11
+ export declare const defaultCodec: Codec<ChannelPayload>;
12
+ //# sourceMappingURL=default_codec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default_codec.d.ts","sourceRoot":"","sources":["../../src/channel/default_codec.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,yEAAyE;AACzE,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,cAAc,CACJ,CAAC"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Datagram dispatcher (= Phase 2c) — Rust `network/datagram_dispatcher.rs` の TS port。
3
+ *
4
+ * `Connection.datagrams()` は単一の exclusive reader iterator しか払い出せない。
5
+ * dispatcher はその唯一の iterator を **占有** し、 受信 datagram 先頭の varint
6
+ * `channel_id` を decode、 登録済 channel handler に fan-out する。
7
+ *
8
+ * 配送特性 (= datagram semantics):
9
+ * - **Unreliable**: malformed varint / 未登録 channel_id / buffer 溢れは silently drop。
10
+ * - **Unordered**: 到着順 deliver、 sequence 保証なし。
11
+ * - **Best-effort**: dispatcher loop 自身は決して詰まらない (= 各 handler に try-push)。
12
+ */
13
+ import type { Connection } from "../transport/types.js";
14
+ /** 1 channel 分の受信 sink (= dispatcher が demux 後の payload を push) */
15
+ export interface DatagramSink {
16
+ /** demux 済 payload を push (= best-effort、 buffer 溢れは sink 側で drop) */
17
+ push(payload: Uint8Array): void;
18
+ /** channel close 時に dispatcher が呼ぶ (= pending iterator を終端) */
19
+ end(): void;
20
+ }
21
+ /**
22
+ * Datagram dispatch table の data 層 (= `quinn` 抜きで test 可能、 Rust の
23
+ * `DispatcherInner` 相当)。 純粋な `channel_id → sink` map 管理に責務限定。
24
+ */
25
+ export declare class DispatcherInner {
26
+ #private;
27
+ /** `channelId` に sink を登録 (= 既存は replace、 旧 sink は end) */
28
+ register(channelId: number, sink: DatagramSink): void;
29
+ /** `channelId` の登録解除 */
30
+ unregister(channelId: number): void;
31
+ /** 登録 channel 数 (= test / debug 用) */
32
+ get handlerCount(): number;
33
+ /**
34
+ * 1 datagram を dispatch (= varint decode → handler lookup → push)。
35
+ * malformed / 未登録 は silently drop (= unreliable semantics)。
36
+ */
37
+ dispatch(datagram: Uint8Array): void;
38
+ /** 全 handler を end して clear (= connection 終端時) */
39
+ clear(): void;
40
+ }
41
+ /**
42
+ * Per-connection datagram dispatcher の runtime 層 (= Rust `DatagramDispatcher` 相当)。
43
+ *
44
+ * `Connection.datagrams()` の単一 iterator を background loop で drain し、
45
+ * `DispatcherInner` に流す。 `register` / `unregister` で channel handler を出し入れ、
46
+ * `stop()` で loop 停止 + 全 handler clear。
47
+ */
48
+ export declare class DatagramDispatcher {
49
+ #private;
50
+ constructor(connection: Connection);
51
+ /** background drain loop を起動 (= idempotent、 初回 `register` で呼ぶ) */
52
+ start(): void;
53
+ /** `channelId` に sink を登録 (= 初回で drain loop を起動) */
54
+ register(channelId: number, sink: DatagramSink): void;
55
+ /** `channelId` の登録解除 */
56
+ unregister(channelId: number): void;
57
+ /** 登録 channel 数 (= test / debug 用) */
58
+ get handlerCount(): number;
59
+ /** dispatcher を停止 (= drain loop 終了 + 全 handler clear) */
60
+ stop(): void;
61
+ }
62
+ //# sourceMappingURL=dispatcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/channel/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGxD,mEAAmE;AACnE,MAAM,WAAW,YAAY;IAC3B,sEAAsE;IACtE,IAAI,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;IAChC,+DAA+D;IAC/D,GAAG,IAAI,IAAI,CAAC;CACb;AAED;;;GAGG;AACH,qBAAa,eAAe;;IAG1B,2DAA2D;IAC3D,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI;IAKrD,wBAAwB;IACxB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAOnC,sCAAsC;IACtC,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,UAAU,GAAG,IAAI;IAQpC,kDAAkD;IAClD,KAAK,IAAI,IAAI;CAId;AAED;;;;;;GAMG;AACH,qBAAa,kBAAkB;;gBAMjB,UAAU,EAAE,UAAU;IAIlC,kEAAkE;IAClE,KAAK,IAAI,IAAI;IAkBb,oDAAoD;IACpD,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI;IAKrD,wBAAwB;IACxB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAInC,sCAAsC;IACtC,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,yDAAyD;IACzD,IAAI,IAAI,IAAI;CAIb"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Channel stream の wire frame (= Phase 6b、 Rust server と byte 一致)。
3
+ *
4
+ * `UnisonChannel` (= QUIC / WebTransport bidi stream) を流れる typed frame の
5
+ * encode/decode。 Rust `crates/unison-protocol/src/network/quic.rs` の
6
+ * `read_typed_frame` / `write_typed_frame` と完全一致する layout:
7
+ *
8
+ * ```text
9
+ * [4B BE total_len] [1B frame_type] [payload]
10
+ * ```
11
+ *
12
+ * - `total_len` = frame_type (1B) + payload の合計
13
+ * - `frame_type` = 0x00 PROTOCOL (= UnisonPacket) / 0x01 RAW (= 生 bytes)
14
+ * - PROTOCOL frame の payload = UnisonPacket バイト列
15
+ * (= `[u32 BE header_len][buffa PacketHeader][buffa ProtocolMessage]`)
16
+ *
17
+ * 旧 Phase 2c の `[4B len][2B hdrLen][JSON header][payload]` 自家製 frame は
18
+ * 廃止 (= Rust server と通信不能だった)。
19
+ */
20
+ import { type PacketOptions } from "../wire/packet.js";
21
+ import { type ProtocolMessage } from "../wire/protocol_message.js";
22
+ /** frame type tag (= Rust `FRAME_TYPE_*`) */
23
+ export declare const FRAME_TYPE_PROTOCOL = 0;
24
+ export declare const FRAME_TYPE_RAW = 1;
25
+ /**
26
+ * `ProtocolMessage` を 1 本の PROTOCOL typed frame へ encode する。
27
+ *
28
+ * layout: `[4B total_len][0x00][UnisonPacket]`。 `UnisonPacket` の中身は
29
+ * `[u32 header_len][PacketHeader][ProtocolMessage]`。
30
+ */
31
+ export declare function encodeProtocolFrame(message: ProtocolMessage, packetOpts?: PacketOptions): Uint8Array;
32
+ /** 生 byte 列を 1 本の RAW typed frame へ encode する (= `[4B len][0x01][data]`) */
33
+ export declare function encodeRawFrame(data: Uint8Array): Uint8Array;
34
+ /** typed frame の decode 結果 */
35
+ export type DecodedFrame = {
36
+ type: "protocol";
37
+ message: ProtocolMessage;
38
+ } | {
39
+ type: "raw";
40
+ data: Uint8Array;
41
+ };
42
+ /**
43
+ * 1 本の typed frame body (= 4B length prefix を剥がした後の `[1B type][payload]`)
44
+ * を decode する。
45
+ */
46
+ export declare function decodeTypedFrame(body: Uint8Array): DecodedFrame;
47
+ /**
48
+ * `ReadableStream<Uint8Array>` から typed frame body (= `[1B type][payload]`) を
49
+ * 1 本ずつ取り出す async generator。 byte 跨ぎ chunk を内部 buffer で結合する。
50
+ */
51
+ export declare function readFrames(readable: ReadableStream<Uint8Array>): AsyncGenerator<Uint8Array>;
52
+ //# sourceMappingURL=frame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame.d.ts","sourceRoot":"","sources":["../../src/channel/frame.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAA8B,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACnF,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,6BAA6B,CAAC;AAErC,6CAA6C;AAC7C,eAAO,MAAM,mBAAmB,IAAO,CAAC;AACxC,eAAO,MAAM,cAAc,IAAO,CAAC;AAKnC;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,eAAe,EACxB,UAAU,GAAE,aAAkB,GAC7B,UAAU,CAIZ;AAED,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAE3D;AAYD,8BAA8B;AAC9B,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,eAAe,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC;AAEtC;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG,YAAY,CAc/D;AAED;;;GAGG;AACH,wBAAuB,UAAU,CAC/B,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,GACnC,cAAc,CAAC,UAAU,CAAC,CAgC5B"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Identity handshake — server 自己紹介の受信 (= Phase 6b)。
3
+ *
4
+ * Unison server は接続直後に bidi stream を 1 本 open し、 そこへ
5
+ * `__identity` の `ProtocolMessage` (= msgType event、 payload は JSON 化した
6
+ * `ServerIdentity`) を 1 本送って stream を finish する
7
+ * (= Rust `quic.rs::handle_connection` の identity 送出ロジック)。
8
+ *
9
+ * TS client は `connect()` 時にこの stream を accept し identity を読む。
10
+ */
11
+ import type { BidiStream, Connection } from "../transport/types.js";
12
+ /** identity handshake のデフォルト timeout */
13
+ export declare const DEFAULT_IDENTITY_TIMEOUT_MS = 5000;
14
+ /** channel の方向 (= Rust `ChannelDirection`、 snake_case) */
15
+ export type ChannelDirection = "server_to_client" | "client_to_server" | "bidirectional";
16
+ /** channel の状態 (= Rust `ChannelStatus`、 snake_case) */
17
+ export type ChannelStatus = "available" | "busy" | "unavailable";
18
+ /** server が advertise する 1 channel の情報 (= Rust `ChannelInfo`) */
19
+ export interface ChannelInfo {
20
+ name: string;
21
+ direction: ChannelDirection;
22
+ lifetime: string;
23
+ status: ChannelStatus;
24
+ }
25
+ /** server の自己紹介情報 (= Rust `ServerIdentity`) */
26
+ export interface ServerIdentity {
27
+ name: string;
28
+ version: string;
29
+ namespace: string;
30
+ channels: ChannelInfo[];
31
+ metadata: unknown;
32
+ }
33
+ /**
34
+ * 1 本の identity stream を drain して `ServerIdentity` を返す。
35
+ *
36
+ * stream の最初の PROTOCOL frame を読み、 `__identity` method なら payload を
37
+ * JSON parse する。 frame が無い / method 不一致なら reject。
38
+ */
39
+ export declare function readIdentity(stream: BidiStream): Promise<ServerIdentity>;
40
+ /**
41
+ * connection が server から identity stream を受けるのを待ち、 `ServerIdentity`
42
+ * を返す。 `timeoutMs` 内に来なければ reject する。
43
+ *
44
+ * `connect()` の中で 1 回だけ呼ぶ (= identity stream は接続あたり 1 本)。
45
+ */
46
+ export declare function performIdentityHandshake(connection: Connection, timeoutMs?: number): Promise<ServerIdentity>;
47
+ //# sourceMappingURL=identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/channel/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAKpE,wCAAwC;AACxC,eAAO,MAAM,2BAA2B,OAAQ,CAAC;AAEjD,0DAA0D;AAC1D,MAAM,MAAM,gBAAgB,GACxB,kBAAkB,GAClB,kBAAkB,GAClB,eAAe,CAAC;AAEpB,uDAAuD;AACvD,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,MAAM,GAAG,aAAa,CAAC;AAEjE,iEAAiE;AACjE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,gBAAgB,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,+CAA+C;AAC/C,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAID;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC,CAuB9E;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,UAAU,EACtB,SAAS,GAAE,MAAoC,GAC9C,OAAO,CAAC,cAAc,CAAC,CAwBzB"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Channel 抽象 (= Phase 2c)。
3
+ *
4
+ * 全通信は channel 経由 (RPC は廃止)。 channel には 2 系統ある:
5
+ * - `UnisonChannel` — stream backend (= QUIC bidi stream)、 request/response + event
6
+ * - `DatagramChannel` — datagram backend (= 共有 datagram path)、 broadcast event のみ
7
+ *
8
+ * 両 interface は Phase 1 codegen が出力する `<Name>ChannelMeta` const に対して
9
+ * generic。 `as const` literal narrowing により、 caller code で event 名 /
10
+ * request 名が compile-time に絞り込まれる。
11
+ *
12
+ * codegen は meta に **phantom `__types` field** を埋め込む (= 生成 interface への
13
+ * link)。 `EventType<M>` / `RequestType<M,N>` / `ResponseType<M,N>` はこの field
14
+ * 経由で event/request 名 → 実 interface を解決する (= design doc §3.2/§4.2)。
15
+ */
16
+ /**
17
+ * meta が `__types` 経由で運ぶ payload 型 map。 codegen が
18
+ * `<Channel>ChannelEventTypes` / `<Channel>ChannelRequestTypes` を生成し、
19
+ * これを `{ events; requests }` として束ねる。 runtime 値は `undefined`。
20
+ */
21
+ export interface ChannelTypeMap {
22
+ readonly events: Readonly<Record<string, unknown>>;
23
+ readonly requests: Readonly<Record<string, {
24
+ request: unknown;
25
+ response: unknown;
26
+ }>>;
27
+ }
28
+ /** Stream backend の channel meta 形状 (= Phase 1 codegen 出力の構造的 subset) */
29
+ export interface ChannelMeta {
30
+ readonly name: string;
31
+ readonly backend: "stream";
32
+ readonly from: "client" | "server" | "either";
33
+ readonly lifetime: "transient" | "persistent";
34
+ readonly events: readonly string[];
35
+ readonly requests: Readonly<Record<string, {
36
+ readonly request: string;
37
+ readonly response: string;
38
+ }>>;
39
+ /** codegen 埋め込みの phantom 型 carrier (= runtime undefined、 型のみ) */
40
+ readonly __types?: ChannelTypeMap;
41
+ }
42
+ /** Datagram backend の channel meta 形状 (= `channelId` 必須、 `requests` 空) */
43
+ export interface DatagramChannelMeta {
44
+ readonly name: string;
45
+ readonly backend: "datagram";
46
+ readonly channelId: number;
47
+ readonly from: "client" | "server" | "either";
48
+ readonly lifetime: "transient" | "persistent";
49
+ readonly events: readonly string[];
50
+ readonly requests: Readonly<Record<string, never>>;
51
+ /** codegen 埋め込みの phantom 型 carrier (= runtime undefined、 型のみ) */
52
+ readonly __types?: ChannelTypeMap;
53
+ }
54
+ /** meta の `events` 配列から event 名 union を導出 */
55
+ export type EventName<M> = M extends {
56
+ events: readonly (infer N)[];
57
+ } ? N & string : never;
58
+ /** meta の `requests` map から request 名 union を導出 */
59
+ export type RequestName<M> = M extends {
60
+ requests: infer R;
61
+ } ? keyof R & string : never;
62
+ /**
63
+ * Channel payload の構造型 fallback。 codegen meta を渡さなかった場合
64
+ * (= raw `ChannelMeta` で開いた場合) の event/request payload 型。
65
+ */
66
+ export type ChannelPayload = Record<string, unknown>;
67
+ /**
68
+ * meta `M` の全 event payload 型 union (= `events()` が yield する型)。
69
+ * `__types` を持つ生成 meta なら実 interface の union、 持たなければ
70
+ * `ChannelPayload` に degrade する。
71
+ */
72
+ export type EventType<M> = M extends {
73
+ __types?: infer T;
74
+ } ? T extends ChannelTypeMap ? T["events"][keyof T["events"]] : ChannelPayload : ChannelPayload;
75
+ /** meta `M` の event `N` の payload 型 (= `sendEvent()` 引数) */
76
+ export type EventPayload<M, N extends PropertyKey> = M extends {
77
+ __types?: infer T;
78
+ } ? T extends ChannelTypeMap ? N extends keyof T["events"] ? T["events"][N] : ChannelPayload : ChannelPayload : ChannelPayload;
79
+ /** meta `M` の request `N` の request payload 型 */
80
+ export type RequestType<M, N extends PropertyKey> = M extends {
81
+ __types?: infer T;
82
+ } ? T extends ChannelTypeMap ? N extends keyof T["requests"] ? T["requests"][N]["request"] : ChannelPayload : ChannelPayload : ChannelPayload;
83
+ /** meta `M` の request `N` の response payload 型 */
84
+ export type ResponseType<M, N extends PropertyKey> = M extends {
85
+ __types?: infer T;
86
+ } ? T extends ChannelTypeMap ? N extends keyof T["requests"] ? T["requests"][N]["response"] : ChannelPayload : ChannelPayload : ChannelPayload;
87
+ /**
88
+ * Stream channel — request/response + server-pushed event。
89
+ *
90
+ * QUIC bidi stream に対応、 ordered + reliable。 `request()` は length-prefixed
91
+ * frame を送り response frame を await、 `events()` は server push を AsyncIterable
92
+ * で配る。 payload 型は meta の `__types` 経由で生成 interface に narrow される。
93
+ */
94
+ export interface UnisonChannel<M extends ChannelMeta = ChannelMeta> {
95
+ /** KDL schema 上の channel 名 */
96
+ readonly name: M["name"];
97
+ /**
98
+ * Request を送り response を await する (= ordered/reliable)。
99
+ * `name` は `M["requests"]` の key に narrow、 戻り値は `ResponseType<M, N>`。
100
+ */
101
+ request<N extends RequestName<M>>(name: N, payload: RequestType<M, N>): Promise<ResponseType<M, N>>;
102
+ /** Server push event の購読 (= `for await`、 break で channel close cascade) */
103
+ events(): AsyncIterableIterator<EventType<M>>;
104
+ /** Event を送信 (= client → server、 応答なし) */
105
+ sendEvent<N extends EventName<M>>(name: N, payload: EventPayload<M, N>): Promise<void>;
106
+ /** Channel を閉じる (= 配下 stream を tear down、 idempotent) */
107
+ close(): Promise<void>;
108
+ }
109
+ /**
110
+ * Datagram channel — broadcast event のみ (= request 不可)。
111
+ *
112
+ * 共有 datagram path 上の virtual stream、 `channelId` varint prefix で demux。
113
+ * unordered + unreliable。 caller は基本 `events()` で subscribe するのみ。
114
+ */
115
+ export interface DatagramChannel<M extends DatagramChannelMeta = DatagramChannelMeta> {
116
+ /** KDL schema 上の channel 名 */
117
+ readonly name: M["name"];
118
+ /** schema-time fixed の demux 識別子 (= varint prefix として wire 出現) */
119
+ readonly channelId: M["channelId"];
120
+ /** Datagram broadcast event の購読 (= unordered/unreliable) */
121
+ events(): AsyncIterableIterator<EventType<M>>;
122
+ /** Event を datagram で送信 (= best-effort、 MTU 超過は reject) */
123
+ sendEvent<N extends EventName<M>>(name: N, payload: EventPayload<M, N>): Promise<void>;
124
+ /** Channel を閉じる (= dispatcher から unregister、 idempotent) */
125
+ close(): Promise<void>;
126
+ }
127
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/channel/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Stream channel wrapper (= Phase 2c、 Phase 6b で Rust wire 互換に再構築)。
3
+ *
4
+ * QUIC / WebTransport bidi stream 上の request/response + server-pushed event。
5
+ * 内部で 1 本の recv loop を持ち、 受信 `ProtocolMessage` を `msgType` で振り分ける:
6
+ * - `response` / `error` → `id` 対応の pending request を resolve/reject
7
+ * - `event` / `request` → events() の AsyncIterable queue に流す
8
+ *
9
+ * Rust `network/channel.rs` の `UnisonChannel` に対応する TS port。 wire は
10
+ * `frame.ts` の typed frame (= `[4B len][0x00][UnisonPacket]`) で Rust server と
11
+ * byte 一致する。
12
+ *
13
+ * ## channel open
14
+ *
15
+ * stream open 直後に `ProtocolMessage { method: "__channel:{name}",
16
+ * msgType: request }` を 1 本送る (= Rust `client.rs::open_channel` と同形)。
17
+ * Phase 6c 以降、 Rust server は同 stream へ `open_ack` (= method
18
+ * `__channel_ack`、 open request と同 id) を返す。 `waitAccepted` はこの ack を
19
+ * await し、 Response なら resolve / Error (= channel-not-found) なら reject /
20
+ * timeout なら reject する (= optimistic-resolve を廃止)。
21
+ */
22
+ import type { Codec } from "../codec/codec.js";
23
+ import type { BidiStream } from "../transport/types.js";
24
+ import type { ChannelMeta, ChannelPayload, EventName, EventPayload, EventType, RequestName, RequestType, ResponseType, UnisonChannel } from "./types.js";
25
+ /** channel open handshake のデフォルト timeout (= 後方互換のため引数に残す) */
26
+ export declare const DEFAULT_OPEN_TIMEOUT_MS = 5000;
27
+ /**
28
+ * `UnisonChannel` の concrete impl。 `openChannel(meta)` から構築する
29
+ * (= caller は直接 new せず factory 経由)。
30
+ */
31
+ export declare class UnisonChannelImpl<M extends ChannelMeta> implements UnisonChannel<M> {
32
+ #private;
33
+ readonly name: M["name"];
34
+ /** @internal `openChannel` から呼ぶ。 */
35
+ constructor(meta: M, stream: BidiStream, codec?: Codec<ChannelPayload>);
36
+ /**
37
+ * @internal `openChannel` から呼ぶ。 `__channel:{name}` open frame を送り、
38
+ * server の `open_ack` を await する (= Phase 6c、 real accept signal)。
39
+ *
40
+ * server は同 stream へ open request と同 id の `__channel_ack` frame を返す:
41
+ * - Response → accept、 resolve する
42
+ * - Error → nack (= channel-not-found 等)、 reject する
43
+ *
44
+ * `timeoutMs` 内に ack が来なければ reject する。 send 自体が失敗 / accept
45
+ * 前に stream が終端した場合も no-accept として reject する。
46
+ */
47
+ waitAccepted(timeoutMs?: number): Promise<void>;
48
+ request<N extends RequestName<M>>(name: N, payload: RequestType<M, N>): Promise<ResponseType<M, N>>;
49
+ events(): AsyncIterableIterator<EventType<M>>;
50
+ sendEvent<N extends EventName<M>>(name: N, payload: EventPayload<M, N>): Promise<void>;
51
+ close(): Promise<void>;
52
+ }
53
+ //# sourceMappingURL=unison_channel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unison_channel.d.ts","sourceRoot":"","sources":["../../src/channel/unison_channel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAgBxD,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,SAAS,EACT,YAAY,EACZ,SAAS,EACT,WAAW,EACX,WAAW,EACX,YAAY,EACZ,aAAa,EACd,MAAM,YAAY,CAAC;AAKpB,6DAA6D;AAC7D,eAAO,MAAM,uBAAuB,OAAQ,CAAC;AAc7C;;;GAGG;AACH,qBAAa,iBAAiB,CAAC,CAAC,SAAS,WAAW,CAClD,YAAW,aAAa,CAAC,CAAC,CAAC;;IAE3B,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IAgBzB,oCAAoC;gBAElC,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,UAAU,EAClB,KAAK,GAAE,KAAK,CAAC,cAAc,CAAgB;IAS7C;;;;;;;;;;OAUG;IACG,YAAY,CAAC,SAAS,GAAE,MAAgC,GAAG,OAAO,CAAC,IAAI,CAAC;IA8HxE,OAAO,CAAC,CAAC,SAAS,WAAW,CAAC,CAAC,CAAC,EACpC,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,GACzB,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IA2B9B,MAAM,IAAI,qBAAqB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAIvC,SAAS,CAAC,CAAC,SAAS,SAAS,CAAC,CAAC,CAAC,EACpC,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,GAC1B,OAAO,CAAC,IAAI,CAAC;IAYV,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAW7B"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * LEB128 varint (= Phase 2c)。
3
+ *
4
+ * datagram channel の `channel_id` prefix encoding。 Rust 側
5
+ * `network/datagram_channel.rs` の `encode_varint` / `decode_varint` と wire 互換。
6
+ * proto3 と同じ unsigned LEB128。
7
+ */
8
+ /** u64 を表す varint の最大 byte 数 (= LEB128 で 64 bit) */
9
+ export declare const VARINT_MAX_LEN = 10;
10
+ /** `value` を LEB128 varint として encode (= 非負整数のみ) */
11
+ export declare function encodeVarint(value: number): Uint8Array;
12
+ /**
13
+ * `bytes` 先頭から varint を読み `{ value, consumed }` を返す。
14
+ * malformed (= 10 byte 超え / premature EOF) は `null` (= caller が drop)。
15
+ */
16
+ export declare function decodeVarint(bytes: Uint8Array): {
17
+ value: number;
18
+ consumed: number;
19
+ } | null;
20
+ //# sourceMappingURL=varint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"varint.d.ts","sourceRoot":"","sources":["../../src/channel/varint.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,oDAAoD;AACpD,eAAO,MAAM,cAAc,KAAK,CAAC;AAEjC,oDAAoD;AACpD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAYtD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,UAAU,GAChB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAU5C"}