@chronista-club/unison-client 1.0.0 → 1.1.0

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.
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  > TypeScript client SDK for the [Unison protocol](https://github.com/chronista-club/club-unison).
4
4
  > Part of the **v1.0 polyglot client base** (= server stays Rust, client polyglot for adoption surface).
5
5
 
6
- **Status**: `1.0.0` — v1.0 GA. Protocol API is frozen and the SDK is shipped to npm. It 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.
6
+ **Status**: `1.1.0` — v1.0 GA + `/testing` subpath. Protocol API is frozen and the SDK is shipped to npm. It 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
7
 
8
8
  ---
9
9
 
@@ -72,6 +72,43 @@ await echo.close();
72
72
  await client.disconnect();
73
73
  ```
74
74
 
75
+ ## Testing utilities (`/testing` subpath)
76
+
77
+ Drive the SDK end-to-end without a real WebTransport stack or a Rust server —
78
+ `MockTransport` pairs in-memory endpoints and `StreamServerStub` speaks the same
79
+ byte-compatible frame protocol as the Rust server:
80
+
81
+ ```typescript
82
+ import { connect } from "@chronista-club/unison-client";
83
+ import {
84
+ MockTransport,
85
+ StreamServerStub,
86
+ } from "@chronista-club/unison-client/testing";
87
+
88
+ const transport = new MockTransport();
89
+ const { server } = transport.prepare(); // server-side endpoint of the memory pipe
90
+
91
+ const client = await connect({
92
+ url: "https://mock.local", // any URL — never dialed with a mock transport
93
+ transport,
94
+ awaitIdentity: false,
95
+ });
96
+
97
+ // Server side: accept the stream and answer with an echo handler.
98
+ const serverSide = (async () => {
99
+ const accepted = await server.acceptStream();
100
+ if (accepted.done) throw new Error("no stream");
101
+ return new StreamServerStub(accepted.value, (_method, payload) => payload);
102
+ })();
103
+ ```
104
+
105
+ `examples/vp-dashboard.ts` and `tests/integration/beta_freeze.test.ts` show the
106
+ full pattern (datagram channels, identity handshake via `sendIdentity`, nack
107
+ injection with `rejectOpen`).
108
+
109
+ The SDK's own integration tests (`tests/integration/`) import the same module,
110
+ so the published harness can never drift from what CI verifies.
111
+
75
112
  ## Architecture
76
113
 
77
114
  ```
@@ -83,7 +120,8 @@ clients/typescript/
83
120
  │ ├── channel/ ← UnisonChannel / DatagramChannel + dispatcher + frame
84
121
  │ ├── codec/ ← JsonCodec + ProtoCodec
85
122
  │ ├── wire/ ← Rust-compatible packet / protocol-message encode/decode
86
- └── error/ ← ErrorCategory framework
123
+ ├── error/ ← ErrorCategory framework
124
+ │ └── testing/ ← /testing subpath (MockTransport + StreamServerStub)
87
125
  ├── examples/ ← vp-dashboard.ts (Vantage Point proof point demo)
88
126
  ├── tests/ ← vitest unit + integration tests (incl. real WebTransport E2E)
89
127
  ├── package.json
@@ -105,7 +143,7 @@ npm run typecheck # tsc --noEmit (= type safety verification)
105
143
  ## Versioning policy
106
144
 
107
145
  - TS package version is kept in **major.minor sync** with the Rust crate `club-unison`
108
- - `1.0.0` (current) — protocol API frozen, stability committed; breaking changes to the public surface require v2.0
146
+ - `1.1.0` (current) — adds the `/testing` subpath + channel util re-exports; protocol API remains frozen since `1.0.0`; breaking changes to the public surface require v2.0
109
147
  - `1.x.0` — additive features (channels, codecs, error codes) that preserve API compatibility
110
148
  - `1.0.x` — patch fixes
111
149
 
@@ -1 +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"}
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,EACX,WAAW,EACX,cAAc,EACd,SAAS,EACT,YAAY,EACZ,SAAS,EACT,WAAW,EACX,WAAW,EACX,YAAY,EACZ,aAAa,EACb,MAAM,YAAY,CAAC;AAKpB,6DAA6D;AAC7D,eAAO,MAAM,uBAAuB,OAAQ,CAAC;AAc7C;;;GAGG;AACH,qBAAa,iBAAiB,CAAC,CAAC,SAAS,WAAW,CACnD,YAAW,aAAa,CAAC,CAAC,CAAC;;IAE3B,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IAgBzB,oCAAoC;gBAEnC,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,UAAU,EAClB,KAAK,GAAE,KAAK,CAAC,cAAc,CAAgB;IAS5C;;;;;;;;;;OAUG;IACG,YAAY,CACjB,SAAS,GAAE,MAAgC,GACzC,OAAO,CAAC,IAAI,CAAC;IA8HV,OAAO,CAAC,CAAC,SAAS,WAAW,CAAC,CAAC,CAAC,EACrC,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,GACxB,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IA+B9B,MAAM,IAAI,qBAAqB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAIvC,SAAS,CAAC,CAAC,SAAS,SAAS,CAAC,CAAC,CAAC,EACrC,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,GACzB,OAAO,CAAC,IAAI,CAAC;IAYV,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAW5B"}
@@ -0,0 +1,395 @@
1
+ class a extends Error {
2
+ constructor(e, t) {
3
+ super(e, t), this.name = new.target.name;
4
+ }
5
+ }
6
+ const N = new TextEncoder(), k = new TextDecoder("utf-8", { fatal: !0 });
7
+ class d {
8
+ format = "json";
9
+ /** 状態を持たない共有 instance (= 全 channel で再利用可) */
10
+ static shared = new d();
11
+ encode(e) {
12
+ try {
13
+ return N.encode(JSON.stringify(e));
14
+ } catch (t) {
15
+ throw new a(`JSON encode failed: ${i(t)}`, { cause: t });
16
+ }
17
+ }
18
+ decode(e) {
19
+ let t;
20
+ try {
21
+ t = k.decode(e);
22
+ } catch (r) {
23
+ throw new a(`invalid UTF-8 in JSON payload: ${i(r)}`, {
24
+ cause: r
25
+ });
26
+ }
27
+ try {
28
+ return JSON.parse(t);
29
+ } catch (r) {
30
+ throw new a(`JSON decode failed: ${i(r)}`, { cause: r });
31
+ }
32
+ }
33
+ }
34
+ function i(n) {
35
+ return n instanceof Error ? n.message : String(n);
36
+ }
37
+ class V {
38
+ #r = [];
39
+ /** 値待ちで suspend した consumer の resolver */
40
+ #e;
41
+ #t = !1;
42
+ /** 値を 1 件投入 (= 待機中 consumer があれば即配送) */
43
+ push(e) {
44
+ if (!this.#t)
45
+ if (this.#e !== void 0) {
46
+ const t = this.#e;
47
+ this.#e = void 0, t({ value: e, done: !1 });
48
+ } else
49
+ this.#r.push(e);
50
+ }
51
+ /** queue を終端 (= 以降の `next()` は done、 待機中 consumer を解放) */
52
+ end() {
53
+ if (!this.#t && (this.#t = !0, this.#e !== void 0)) {
54
+ const e = this.#e;
55
+ this.#e = void 0, e({ value: void 0, done: !0 });
56
+ }
57
+ }
58
+ next() {
59
+ const e = this.#r.shift();
60
+ return e !== void 0 ? Promise.resolve({ value: e, done: !1 }) : this.#t ? Promise.resolve({ value: void 0, done: !0 }) : new Promise((t) => {
61
+ this.#e = t;
62
+ });
63
+ }
64
+ /** consumer が `break` した時の cleanup hook (= queue 終端) */
65
+ return() {
66
+ return this.end(), Promise.resolve({ value: void 0, done: !0 });
67
+ }
68
+ [Symbol.asyncIterator]() {
69
+ return this;
70
+ }
71
+ }
72
+ const P = new TextEncoder(), I = new TextDecoder("utf-8", { fatal: !0 }), c = 0, f = 2;
73
+ class h {
74
+ #r = [];
75
+ /** 生 byte を 1 個追加 */
76
+ #e(e) {
77
+ this.#r.push(e & 255);
78
+ }
79
+ /** LEB128 unsigned varint を追加 (= bigint で 64bit 安全) */
80
+ #t(e) {
81
+ let t = e;
82
+ for (; t >= 0x80n; )
83
+ this.#e(Number(t & 0x7fn) | 128), t >>= 7n;
84
+ this.#e(Number(t));
85
+ }
86
+ /** field tag = (fieldNo << 3) | wireType */
87
+ #n(e, t) {
88
+ this.#t(BigInt(e << 3 | t));
89
+ }
90
+ /** uint32 field (= zero なら skip、 proto3 implicit presence) */
91
+ uint32(e, t) {
92
+ t !== 0 && (this.#n(e, c), this.#t(BigInt(t >>> 0)));
93
+ }
94
+ /** uint64 field (= zero なら skip)。 `value` は number か bigint */
95
+ uint64(e, t) {
96
+ const r = typeof t == "bigint" ? t : BigInt(Math.trunc(t));
97
+ r !== 0n && (this.#n(e, c), this.#t(r));
98
+ }
99
+ /** enum field (= uint32 と同じ wire、 zero なら skip) */
100
+ enum(e, t) {
101
+ this.uint32(e, t);
102
+ }
103
+ /** bytes field (= 空なら skip) */
104
+ bytes(e, t) {
105
+ if (t.length !== 0) {
106
+ this.#n(e, f), this.#t(BigInt(t.length));
107
+ for (const r of t) this.#e(r);
108
+ }
109
+ }
110
+ /** string field (= 空なら skip) */
111
+ string(e, t) {
112
+ t.length !== 0 && this.bytes(e, P.encode(t));
113
+ }
114
+ /** 蓄積した byte 列を確定する */
115
+ finish() {
116
+ return Uint8Array.from(this.#r);
117
+ }
118
+ }
119
+ class l {
120
+ #r;
121
+ #e = 0;
122
+ constructor(e) {
123
+ this.#r = e;
124
+ }
125
+ /** 残り byte があるか */
126
+ get hasMore() {
127
+ return this.#e < this.#r.length;
128
+ }
129
+ /** LEB128 varint を 1 個読む */
130
+ #t() {
131
+ let e = 0n, t = 0n;
132
+ for (; ; ) {
133
+ if (this.#e >= this.#r.length)
134
+ throw new Error("proto: varint overruns buffer");
135
+ const r = this.#r[this.#e++];
136
+ if (e |= BigInt(r & 127) << t, (r & 128) === 0) return e;
137
+ if (t += 7n, t > 70n) throw new Error("proto: varint too long");
138
+ }
139
+ }
140
+ /** 次の field を 1 個読む (= 無ければ null) */
141
+ next() {
142
+ if (!this.hasMore) return null;
143
+ const e = this.#t(), t = Number(e >> 3n), r = Number(e & 0x7n);
144
+ if (r === c)
145
+ return { fieldNo: t, wireType: r, varint: this.#t() };
146
+ if (r === f) {
147
+ const s = Number(this.#t());
148
+ if (this.#e + s > this.#r.length)
149
+ throw new Error("proto: LEN field overruns buffer");
150
+ const o = this.#r.subarray(this.#e, this.#e + s);
151
+ return this.#e += s, { fieldNo: t, wireType: r, bytes: o };
152
+ }
153
+ if (r === 1)
154
+ return this.#e += 8, { fieldNo: t, wireType: r };
155
+ if (r === 5)
156
+ return this.#e += 4, { fieldNo: t, wireType: r };
157
+ throw new Error(`proto: unsupported wire type ${r}`);
158
+ }
159
+ }
160
+ function x(n) {
161
+ return I.decode(n);
162
+ }
163
+ const A = 1, m = 0, L = 1;
164
+ function g(n = m) {
165
+ return {
166
+ version: A,
167
+ packetType: n,
168
+ flags: 0,
169
+ payloadLength: 0,
170
+ compressedLength: 0,
171
+ sequenceNumber: 0,
172
+ timestamp: 0,
173
+ streamId: 0,
174
+ messageId: 0,
175
+ responseTo: 0,
176
+ correlationId: new Uint8Array(0)
177
+ };
178
+ }
179
+ function S(n) {
180
+ const e = new h();
181
+ return e.uint32(1, n.version), e.uint32(2, n.packetType), e.uint32(3, n.flags), e.uint32(4, n.payloadLength), e.uint32(5, n.compressedLength), e.uint64(6, n.sequenceNumber), e.uint64(7, n.timestamp), e.uint64(8, n.streamId), e.uint64(9, n.messageId), e.uint64(10, n.responseTo), e.bytes(11, n.correlationId), e.finish();
182
+ }
183
+ function _(n) {
184
+ const e = g();
185
+ e.version = 0, e.packetType = 0;
186
+ const t = new l(n);
187
+ for (let r = t.next(); r !== null; r = t.next())
188
+ switch (r.fieldNo) {
189
+ case 1:
190
+ e.version = Number(r.varint ?? 0n);
191
+ break;
192
+ case 2:
193
+ e.packetType = Number(r.varint ?? 0n);
194
+ break;
195
+ case 3:
196
+ e.flags = Number(r.varint ?? 0n);
197
+ break;
198
+ case 4:
199
+ e.payloadLength = Number(r.varint ?? 0n);
200
+ break;
201
+ case 5:
202
+ e.compressedLength = Number(r.varint ?? 0n);
203
+ break;
204
+ case 6:
205
+ e.sequenceNumber = Number(r.varint ?? 0n);
206
+ break;
207
+ case 7:
208
+ e.timestamp = Number(r.varint ?? 0n);
209
+ break;
210
+ case 8:
211
+ e.streamId = Number(r.varint ?? 0n);
212
+ break;
213
+ case 9:
214
+ e.messageId = Number(r.varint ?? 0n);
215
+ break;
216
+ case 10:
217
+ e.responseTo = Number(r.varint ?? 0n);
218
+ break;
219
+ case 11:
220
+ e.correlationId = r.bytes ?? new Uint8Array(0);
221
+ break;
222
+ }
223
+ return e;
224
+ }
225
+ function R(n) {
226
+ return n.compressedLength > 0 && (n.flags & L) !== 0;
227
+ }
228
+ function M(n) {
229
+ return n.compressedLength > 0 ? n.compressedLength : n.payloadLength;
230
+ }
231
+ function U(n, e = {}) {
232
+ const t = g(
233
+ e.packetType ?? m
234
+ );
235
+ t.payloadLength = n.length, t.compressedLength = 0, t.sequenceNumber = e.sequenceNumber ?? 0, t.streamId = e.streamId ?? 0, t.messageId = e.messageId ?? 0, t.responseTo = e.responseTo ?? 0, e.correlationId !== void 0 && (t.correlationId = e.correlationId);
236
+ const r = S(t), s = new Uint8Array(4 + r.length + n.length);
237
+ return new DataView(s.buffer).setUint32(0, r.length, !1), s.set(r, 4), s.set(n, 4 + r.length), s;
238
+ }
239
+ function O(n) {
240
+ if (n.length < 4)
241
+ throw new Error("packet: too short for u32 header_len prefix");
242
+ const e = new DataView(
243
+ n.buffer,
244
+ n.byteOffset,
245
+ n.byteLength
246
+ ).getUint32(0, !1);
247
+ if (n.length < 4 + e)
248
+ throw new Error("packet: declared header_len overruns buffer");
249
+ const t = _(n.subarray(4, 4 + e)), r = n.subarray(4 + e), s = M(t);
250
+ if (r.length !== s)
251
+ throw new Error(
252
+ `packet: payload size ${r.length} != header-declared ${s}`
253
+ );
254
+ if (R(t))
255
+ throw new Error(
256
+ "packet: zstd-compressed payload not supported by TS client yet (= Phase 6d adds zstd decode; current fixtures stay < 2KB / uncompressed)"
257
+ );
258
+ return { header: t, payload: r };
259
+ }
260
+ const p = 0, w = 1, y = 2, b = 3;
261
+ function $(n) {
262
+ switch (n) {
263
+ case w:
264
+ return "response";
265
+ case y:
266
+ return "event";
267
+ case b:
268
+ return "error";
269
+ default:
270
+ return "request";
271
+ }
272
+ }
273
+ function C(n) {
274
+ switch (n) {
275
+ case "response":
276
+ return w;
277
+ case "event":
278
+ return y;
279
+ case "error":
280
+ return b;
281
+ default:
282
+ return p;
283
+ }
284
+ }
285
+ function F(n) {
286
+ const e = new h();
287
+ return e.uint64(1, n.id), e.string(2, n.method), e.enum(3, n.msgType), e.bytes(4, n.payload), e.finish();
288
+ }
289
+ function B(n) {
290
+ const e = {
291
+ id: 0,
292
+ method: "",
293
+ msgType: p,
294
+ payload: new Uint8Array(0)
295
+ }, t = new l(n);
296
+ for (let r = t.next(); r !== null; r = t.next())
297
+ switch (r.fieldNo) {
298
+ case 1:
299
+ e.id = Number(r.varint ?? 0n);
300
+ break;
301
+ case 2:
302
+ e.method = r.bytes !== void 0 ? x(r.bytes) : "";
303
+ break;
304
+ case 3:
305
+ e.msgType = Number(r.varint ?? 0n);
306
+ break;
307
+ case 4:
308
+ e.payload = r.bytes ?? new Uint8Array(0);
309
+ break;
310
+ }
311
+ return e;
312
+ }
313
+ const E = 0, v = 1, D = 8 * 1024 * 1024;
314
+ function Y(n, e = {}) {
315
+ const t = F(n), r = U(t, e);
316
+ return T(E, r);
317
+ }
318
+ function q(n) {
319
+ return T(v, n);
320
+ }
321
+ function T(n, e) {
322
+ const t = 1 + e.length, r = new Uint8Array(4 + t);
323
+ return new DataView(r.buffer).setUint32(0, t, !1), r[4] = n & 255, r.set(e, 5), r;
324
+ }
325
+ function J(n) {
326
+ if (n.length < 1)
327
+ throw new Error("frame: empty typed frame (missing type tag)");
328
+ const e = n[0], t = n.subarray(1);
329
+ if (e === E) {
330
+ const { payload: r } = O(t);
331
+ return { type: "protocol", message: B(r) };
332
+ }
333
+ if (e === v)
334
+ return { type: "raw", data: t };
335
+ throw new Error(`frame: unknown frame type tag 0x${e.toString(16)}`);
336
+ }
337
+ async function* G(n) {
338
+ const e = n.getReader();
339
+ let t = new Uint8Array(0);
340
+ try {
341
+ for (; ; ) {
342
+ for (; t.length < 4; ) {
343
+ const { value: s, done: o } = await e.read();
344
+ if (o) return;
345
+ s !== void 0 && (t = u(t, s));
346
+ }
347
+ const r = new DataView(
348
+ t.buffer,
349
+ t.byteOffset,
350
+ t.byteLength
351
+ ).getUint32(0, !1);
352
+ if (r === 0) throw new Error("frame: empty frame");
353
+ if (r > D)
354
+ throw new Error(`frame: too large (${r} bytes)`);
355
+ for (; t.length < 4 + r; ) {
356
+ const { value: s, done: o } = await e.read();
357
+ if (o) return;
358
+ s !== void 0 && (t = u(t, s));
359
+ }
360
+ yield t.subarray(4, 4 + r), t = t.slice(4 + r);
361
+ }
362
+ } finally {
363
+ e.releaseLock();
364
+ }
365
+ }
366
+ function u(n, e) {
367
+ const t = new Uint8Array(n.length + e.length);
368
+ return t.set(n, 0), t.set(e, n.length), t;
369
+ }
370
+ export {
371
+ V as A,
372
+ a as C,
373
+ E as F,
374
+ d as J,
375
+ b as M,
376
+ A as P,
377
+ v as a,
378
+ y as b,
379
+ p as c,
380
+ w as d,
381
+ O as e,
382
+ _ as f,
383
+ B as g,
384
+ J as h,
385
+ U as i,
386
+ S as j,
387
+ Y as k,
388
+ F as l,
389
+ q as m,
390
+ $ as n,
391
+ C as o,
392
+ g as p,
393
+ G as r
394
+ };
395
+ //# sourceMappingURL=frame-CG6S4SVc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame-CG6S4SVc.js","sources":["../src/codec/codec.ts","../src/codec/json_codec.ts","../src/channel/async_queue.ts","../src/wire/proto.ts","../src/wire/packet_header.ts","../src/wire/packet.ts","../src/wire/protocol_message.ts","../src/channel/frame.ts"],"sourcesContent":["/**\n * Codec 抽象 (= Phase 2d)。\n *\n * `Codec` は channel payload (= `ProtocolMessage.payload` バイト列) の\n * encode/decode を担う。 wire の packet framing は transport 層の責務であり、\n * codec はその内側のアプリケーションメッセージ部分のみを扱う。\n *\n * Rust 側の `Encodable<C>` / `Decodable<C>` トレイトペアに対応する。 channel は\n * `Codec<T>` を 1 個保持し、 codec を差し替えることで JSON / protobuf wire を\n * 切り替える (= `UnisonChannel<M>` が codec に対してジェネリック)。\n */\n\n/** codec layer error の基底 (= encode/decode 双方の失敗を表す) */\nexport class CodecError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = new.target.name;\n }\n}\n\n/**\n * メッセージ値 `T` を wire バイト列に相互変換する codec。\n *\n * 1 個の codec instance は 1 種類のメッセージ型に束縛される。 `JsonCodec` は\n * 構造的に任意の値を扱えるため共有可能だが、 `ProtoCodec` は proto descriptor\n * ごとに instance を持つ (= buf protobuf が descriptor 駆動のため)。\n */\nexport interface Codec<T> {\n /** wire format 識別子 (= \"json\" / \"proto\"、 診断・negotiation 用) */\n readonly format: CodecFormat;\n /** 値をバイト列にエンコード (= 失敗時 `CodecError`) */\n encode(value: T): Uint8Array;\n /** バイト列を値にデコード (= 失敗時 `CodecError`) */\n decode(bytes: Uint8Array): T;\n}\n\n/** 対応 wire format (= connection-level codec 選択肢、 design §5) */\nexport type CodecFormat = \"json\" | \"proto\";\n","/**\n * JsonCodec (= Phase 2d) — default wire codec。\n *\n * `JSON.stringify` / `JSON.parse` を `TextEncoder` / `TextDecoder` で\n * Uint8Array に橋渡しする。 Rust 側 `JsonCodec` (= serde_json) と wire 互換。\n *\n * 構造的 codec のため任意のメッセージ型を 1 instance で扱える (= schema 不要)。\n * dev/debug 用途では human-readable な wire を得られるのが利点。\n */\n\nimport { type Codec, CodecError } from \"./codec.js\";\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder(\"utf-8\", { fatal: true });\n\n/**\n * JSON ベースの `Codec`。\n *\n * 全メッセージ型を構造的に扱えるため `JsonCodec.shared` を再利用すればよい\n * (= 状態を持たない)。\n */\nexport class JsonCodec<T = unknown> implements Codec<T> {\n readonly format = \"json\" as const;\n\n /** 状態を持たない共有 instance (= 全 channel で再利用可) */\n static readonly shared = new JsonCodec();\n\n encode(value: T): Uint8Array {\n try {\n return encoder.encode(JSON.stringify(value));\n } catch (cause) {\n throw new CodecError(`JSON encode failed: ${describe(cause)}`, { cause });\n }\n }\n\n decode(bytes: Uint8Array): T {\n let text: string;\n try {\n text = decoder.decode(bytes);\n } catch (cause) {\n throw new CodecError(`invalid UTF-8 in JSON payload: ${describe(cause)}`, {\n cause,\n });\n }\n try {\n return JSON.parse(text) as T;\n } catch (cause) {\n throw new CodecError(`JSON decode failed: ${describe(cause)}`, { cause });\n }\n }\n}\n\nfunction describe(cause: unknown): string {\n return cause instanceof Error ? cause.message : String(cause);\n}\n","/**\n * AsyncQueue (= Phase 2c 内部 util)。\n *\n * push 駆動の値を `for await` で pull できる単一消費者 queue。 channel の\n * `events()` が server push / datagram demux の payload を AsyncIterable に\n * 橋渡しするのに使う。 producer は非同期境界なしで `push` / `end` を呼べる。\n */\n\n/** push された値を AsyncIterable として配る単一消費者 queue */\nexport class AsyncQueue<T> implements AsyncIterableIterator<T> {\n readonly #buffer: T[] = [];\n /** 値待ちで suspend した consumer の resolver */\n #pending: ((r: IteratorResult<T>) => void) | undefined;\n #closed = false;\n\n /** 値を 1 件投入 (= 待機中 consumer があれば即配送) */\n push(value: T): void {\n if (this.#closed) return;\n if (this.#pending !== undefined) {\n const resolve = this.#pending;\n this.#pending = undefined;\n resolve({ value, done: false });\n } else {\n this.#buffer.push(value);\n }\n }\n\n /** queue を終端 (= 以降の `next()` は done、 待機中 consumer を解放) */\n end(): void {\n if (this.#closed) return;\n this.#closed = true;\n if (this.#pending !== undefined) {\n const resolve = this.#pending;\n this.#pending = undefined;\n resolve({ value: undefined, done: true });\n }\n }\n\n next(): Promise<IteratorResult<T>> {\n const buffered = this.#buffer.shift();\n if (buffered !== undefined) {\n return Promise.resolve({ value: buffered, done: false });\n }\n if (this.#closed) {\n return Promise.resolve({ value: undefined, done: true });\n }\n return new Promise((resolve) => {\n this.#pending = resolve;\n });\n }\n\n /** consumer が `break` した時の cleanup hook (= queue 終端) */\n return(): Promise<IteratorResult<T>> {\n this.end();\n return Promise.resolve({ value: undefined, done: true });\n }\n\n [Symbol.asyncIterator](): AsyncIterableIterator<T> {\n return this;\n }\n}\n","/**\n * Minimal proto3 wire encoder/decoder (= Phase 6b).\n *\n * Rust server の wire format に byte 一致させるための proto3 primitive。\n * `PacketHeader` / `ProtocolMessage` は固定 protocol message (= user schema では\n * ない) のため、 ここで手書き codec を提供する。 buffa (Rust server 側) は標準\n * proto3 implicit-presence で encode する: scalar が zero / bytes が空のとき\n * field を **skip** する。 ここでも同じ規則を厳守する (= byte 一致の要)。\n *\n * 対応 wire type:\n * - 0 (VARINT) — uint32 / uint64 / enum\n * - 2 (LEN) — bytes / string\n *\n * field 番号は昇順で encode する (= buffa の生成 encode が field 宣言順 = 昇順)。\n */\n\nconst textEncoder = new TextEncoder();\nconst textDecoder = new TextDecoder(\"utf-8\", { fatal: true });\n\n/** proto3 wire type tag */\nconst WIRE_VARINT = 0;\nconst WIRE_LEN = 2;\n\n/** 可変長 byte buffer (= push only、 最後に 1 本の Uint8Array へ) */\nexport class ProtoWriter {\n #chunks: number[] = [];\n\n /** 生 byte を 1 個追加 */\n #byte(b: number): void {\n this.#chunks.push(b & 0xff);\n }\n\n /** LEB128 unsigned varint を追加 (= bigint で 64bit 安全) */\n #varint(value: bigint): void {\n let v = value;\n while (v >= 0x80n) {\n this.#byte(Number(v & 0x7fn) | 0x80);\n v >>= 7n;\n }\n this.#byte(Number(v));\n }\n\n /** field tag = (fieldNo << 3) | wireType */\n #tag(fieldNo: number, wireType: number): void {\n this.#varint(BigInt((fieldNo << 3) | wireType));\n }\n\n /** uint32 field (= zero なら skip、 proto3 implicit presence) */\n uint32(fieldNo: number, value: number): void {\n if (value === 0) return;\n this.#tag(fieldNo, WIRE_VARINT);\n this.#varint(BigInt(value >>> 0));\n }\n\n /** uint64 field (= zero なら skip)。 `value` は number か bigint */\n uint64(fieldNo: number, value: number | bigint): void {\n const v = typeof value === \"bigint\" ? value : BigInt(Math.trunc(value));\n if (v === 0n) return;\n this.#tag(fieldNo, WIRE_VARINT);\n this.#varint(v);\n }\n\n /** enum field (= uint32 と同じ wire、 zero なら skip) */\n enum(fieldNo: number, value: number): void {\n this.uint32(fieldNo, value);\n }\n\n /** bytes field (= 空なら skip) */\n bytes(fieldNo: number, value: Uint8Array): void {\n if (value.length === 0) return;\n this.#tag(fieldNo, WIRE_LEN);\n this.#varint(BigInt(value.length));\n for (const b of value) this.#byte(b);\n }\n\n /** string field (= 空なら skip) */\n string(fieldNo: number, value: string): void {\n if (value.length === 0) return;\n this.bytes(fieldNo, textEncoder.encode(value));\n }\n\n /** 蓄積した byte 列を確定する */\n finish(): Uint8Array {\n return Uint8Array.from(this.#chunks);\n }\n}\n\n/** 1 field の decode 結果 */\ninterface ProtoField {\n fieldNo: number;\n wireType: number;\n /** VARINT のときの値 */\n varint?: bigint;\n /** LEN のときの byte 列 */\n bytes?: Uint8Array;\n}\n\n/**\n * proto3 byte 列を field 単位で読み出す reader。\n *\n * 未知 field は wire type に応じて skip する (= forward compat)。\n */\nexport class ProtoReader {\n #buf: Uint8Array;\n #pos = 0;\n\n constructor(buf: Uint8Array) {\n this.#buf = buf;\n }\n\n /** 残り byte があるか */\n get hasMore(): boolean {\n return this.#pos < this.#buf.length;\n }\n\n /** LEB128 varint を 1 個読む */\n #readVarint(): bigint {\n let result = 0n;\n let shift = 0n;\n for (;;) {\n if (this.#pos >= this.#buf.length) {\n throw new Error(\"proto: varint overruns buffer\");\n }\n const b = this.#buf[this.#pos++] as number;\n result |= BigInt(b & 0x7f) << shift;\n if ((b & 0x80) === 0) return result;\n shift += 7n;\n if (shift > 70n) throw new Error(\"proto: varint too long\");\n }\n }\n\n /** 次の field を 1 個読む (= 無ければ null) */\n next(): ProtoField | null {\n if (!this.hasMore) return null;\n const tag = this.#readVarint();\n const fieldNo = Number(tag >> 3n);\n const wireType = Number(tag & 0x7n);\n if (wireType === WIRE_VARINT) {\n return { fieldNo, wireType, varint: this.#readVarint() };\n }\n if (wireType === WIRE_LEN) {\n const len = Number(this.#readVarint());\n if (this.#pos + len > this.#buf.length) {\n throw new Error(\"proto: LEN field overruns buffer\");\n }\n const bytes = this.#buf.subarray(this.#pos, this.#pos + len);\n this.#pos += len;\n return { fieldNo, wireType, bytes };\n }\n // 未対応 wire type (1 = I64, 5 = I32) — fixed 幅で skip\n if (wireType === 1) {\n this.#pos += 8;\n return { fieldNo, wireType };\n }\n if (wireType === 5) {\n this.#pos += 4;\n return { fieldNo, wireType };\n }\n throw new Error(`proto: unsupported wire type ${wireType}`);\n }\n}\n\n/** LEN field の byte 列を UTF-8 string へ */\nexport function decodeProtoString(bytes: Uint8Array): string {\n return textDecoder.decode(bytes);\n}\n","/**\n * `PacketHeader` proto3 codec (= Phase 6b)。\n *\n * Rust `crates/unison-protocol/proto/protocol.proto` の `PacketHeader` message\n * (= 固定 protocol message) と byte 一致する hand-written codec。 buffa が出力\n * する proto3 wire (= implicit presence、 zero field skip) を厳守する。\n *\n * field map (proto.PacketHeader):\n * 1 uint32 version\n * 2 uint32 packet_type\n * 3 uint32 flags\n * 4 uint32 payload_length\n * 5 uint32 compressed_length\n * 6 uint64 sequence_number\n * 7 uint64 timestamp\n * 8 uint64 stream_id\n * 9 uint64 message_id\n * 10 uint64 response_to\n * 11 bytes correlation_id (= UUID v7 の 16 byte raw、 空なら未設定)\n */\n\nimport { ProtoReader, ProtoWriter } from \"./proto.js\";\n\n/** プロトコルバージョン (= Rust `UnisonPacketHeader::CURRENT_VERSION`) */\nexport const PACKET_VERSION = 0x01;\n\n/** PacketType enum (= Rust `PacketType` を u8 cast した値) */\nexport const PACKET_TYPE_DATA = 0x00;\nexport const PACKET_TYPE_CONTROL = 0x01;\nexport const PACKET_TYPE_HEARTBEAT = 0x02;\nexport const PACKET_TYPE_HANDSHAKE = 0x03;\n\n/** PacketFlags bit (= Rust `PacketFlags`) */\nexport const FLAG_COMPRESSED = 0x0001;\n\n/**\n * `proto.PacketHeader` の TS 表現。\n *\n * 数値 field は number で扱う (= timestamp の ns は 2^53 未満で安全に収まる)。\n * `correlationId` は 16 byte の UUID raw、 未設定なら長さ 0。\n */\nexport interface PacketHeader {\n version: number;\n packetType: number;\n flags: number;\n payloadLength: number;\n compressedLength: number;\n sequenceNumber: number;\n timestamp: number;\n streamId: number;\n messageId: number;\n responseTo: number;\n correlationId: Uint8Array;\n}\n\n/** default 値で `PacketHeader` を作る (= version + packet_type 以外は zero) */\nexport function newPacketHeader(\n packetType: number = PACKET_TYPE_DATA,\n): PacketHeader {\n return {\n version: PACKET_VERSION,\n packetType,\n flags: 0,\n payloadLength: 0,\n compressedLength: 0,\n sequenceNumber: 0,\n timestamp: 0,\n streamId: 0,\n messageId: 0,\n responseTo: 0,\n correlationId: new Uint8Array(0),\n };\n}\n\n/** `PacketHeader` を proto3 byte 列へ encode (= field 番号昇順) */\nexport function encodePacketHeader(h: PacketHeader): Uint8Array {\n const w = new ProtoWriter();\n w.uint32(1, h.version);\n w.uint32(2, h.packetType);\n w.uint32(3, h.flags);\n w.uint32(4, h.payloadLength);\n w.uint32(5, h.compressedLength);\n w.uint64(6, h.sequenceNumber);\n w.uint64(7, h.timestamp);\n w.uint64(8, h.streamId);\n w.uint64(9, h.messageId);\n w.uint64(10, h.responseTo);\n w.bytes(11, h.correlationId);\n return w.finish();\n}\n\n/** proto3 byte 列から `PacketHeader` を decode (= 未設定 field は default) */\nexport function decodePacketHeader(bytes: Uint8Array): PacketHeader {\n const h = newPacketHeader();\n // version も含めて全 field を読み込み直す (= wire 値が source of truth)\n h.version = 0;\n h.packetType = 0;\n const r = new ProtoReader(bytes);\n for (let f = r.next(); f !== null; f = r.next()) {\n switch (f.fieldNo) {\n case 1:\n h.version = Number(f.varint ?? 0n);\n break;\n case 2:\n h.packetType = Number(f.varint ?? 0n);\n break;\n case 3:\n h.flags = Number(f.varint ?? 0n);\n break;\n case 4:\n h.payloadLength = Number(f.varint ?? 0n);\n break;\n case 5:\n h.compressedLength = Number(f.varint ?? 0n);\n break;\n case 6:\n h.sequenceNumber = Number(f.varint ?? 0n);\n break;\n case 7:\n h.timestamp = Number(f.varint ?? 0n);\n break;\n case 8:\n h.streamId = Number(f.varint ?? 0n);\n break;\n case 9:\n h.messageId = Number(f.varint ?? 0n);\n break;\n case 10:\n h.responseTo = Number(f.varint ?? 0n);\n break;\n case 11:\n h.correlationId = f.bytes ?? new Uint8Array(0);\n break;\n default:\n break; // 未知 field は無視 (= forward compat)\n }\n }\n return h;\n}\n\n/** compressed フラグが立っているか */\nexport function isCompressed(h: PacketHeader): boolean {\n return h.compressedLength > 0 && (h.flags & FLAG_COMPRESSED) !== 0;\n}\n\n/** payload bytes の実 size (= 圧縮時は compressed_length) */\nexport function actualPayloadSize(h: PacketHeader): number {\n return h.compressedLength > 0 ? h.compressedLength : h.payloadLength;\n}\n","/**\n * `UnisonPacket` wire layer (= Phase 6b)。\n *\n * Rust `crates/unison-protocol/src/packet/` の `[u32 BE header_len]\n * [buffa PacketHeader][payload bytes]` packet format と byte 一致する。\n *\n * ```text\n * [u32 BE header_len] [buffa-encoded PacketHeader] [payload bytes]\n * ```\n *\n * `payload` は `ProtocolMessage` を encode した buffa バイト列。 Rust 側は\n * payload ≥ 2048 byte で zstd 圧縮するが、 TS client は **常に非圧縮**で送る\n * (= `compressed_length = 0`、 wire-valid)。 受信時に圧縮 packet が来たら\n * 明示 error を投げる (= Phase 6d で zstd decode を入れるまでの正直な signal)。\n */\n\nimport {\n type PacketHeader,\n PACKET_TYPE_DATA,\n actualPayloadSize,\n decodePacketHeader,\n encodePacketHeader,\n isCompressed,\n newPacketHeader,\n} from \"./packet_header.js\";\n\n/** packet header に乗せる任意設定 (= 全 field 既定、 caller が必要分のみ上書き) */\nexport interface PacketOptions {\n packetType?: number;\n sequenceNumber?: number;\n streamId?: number;\n messageId?: number;\n responseTo?: number;\n correlationId?: Uint8Array;\n}\n\n/**\n * `payload` (= encode 済み `ProtocolMessage` バイト列) を 1 本の UnisonPacket\n * バイト列 (= `[u32 BE header_len][PacketHeader][payload]`) へ encode する。\n *\n * 非圧縮固定: `payload_length` に実 size、 `compressed_length = 0`。\n */\nexport function encodePacket(\n payload: Uint8Array,\n opts: PacketOptions = {},\n): Uint8Array {\n const header: PacketHeader = newPacketHeader(\n opts.packetType ?? PACKET_TYPE_DATA,\n );\n header.payloadLength = payload.length;\n header.compressedLength = 0;\n header.sequenceNumber = opts.sequenceNumber ?? 0;\n header.streamId = opts.streamId ?? 0;\n header.messageId = opts.messageId ?? 0;\n header.responseTo = opts.responseTo ?? 0;\n if (opts.correlationId !== undefined) {\n header.correlationId = opts.correlationId;\n }\n\n const headerBytes = encodePacketHeader(header);\n const out = new Uint8Array(4 + headerBytes.length + payload.length);\n new DataView(out.buffer).setUint32(0, headerBytes.length, false);\n out.set(headerBytes, 4);\n out.set(payload, 4 + headerBytes.length);\n return out;\n}\n\n/** packet decode 結果 (= header + 解凍済み payload バイト列) */\nexport interface DecodedPacket {\n header: PacketHeader;\n payload: Uint8Array;\n}\n\n/**\n * UnisonPacket バイト列を header + payload に分解する。\n *\n * 圧縮 packet (= `compressed_length > 0` かつ COMPRESSED flag) は現状 reject\n * する (= TS 側に zstd decode が無い、 Phase 6d で対応)。\n */\nexport function decodePacket(bytes: Uint8Array): DecodedPacket {\n if (bytes.length < 4) {\n throw new Error(\"packet: too short for u32 header_len prefix\");\n }\n const headerLen = new DataView(\n bytes.buffer,\n bytes.byteOffset,\n bytes.byteLength,\n ).getUint32(0, false);\n if (bytes.length < 4 + headerLen) {\n throw new Error(\"packet: declared header_len overruns buffer\");\n }\n const header = decodePacketHeader(bytes.subarray(4, 4 + headerLen));\n const payloadBytes = bytes.subarray(4 + headerLen);\n\n const expected = actualPayloadSize(header);\n if (payloadBytes.length !== expected) {\n throw new Error(\n `packet: payload size ${payloadBytes.length} != header-declared ${expected}`,\n );\n }\n if (isCompressed(header)) {\n throw new Error(\n \"packet: zstd-compressed payload not supported by TS client yet \" +\n \"(= Phase 6d adds zstd decode; current fixtures stay < 2KB / uncompressed)\",\n );\n }\n return { header, payload: payloadBytes };\n}\n","/**\n * `ProtocolMessage` proto3 codec (= Phase 6b)。\n *\n * Rust `proto.ProtocolMessage` (= 全 channel が運ぶ wire-level message) と byte\n * 一致する hand-written codec。 `payload` は channel codec (= JSON / proto) が\n * encode した application message のバイト列。\n *\n * field map (proto.ProtocolMessage):\n * 1 uint64 id (= Request は一意、 Event は 0 可)\n * 2 string method (= \"Query\" / \"__channel:control\" / \"__identity\" 等)\n * 3 MessageType msg_type (= enum)\n * 4 bytes payload\n */\n\nimport { ProtoReader, ProtoWriter, decodeProtoString } from \"./proto.js\";\n\n/** MessageType enum (= Rust `proto.MessageType` と同じ値) */\nexport const MSG_TYPE_REQUEST = 0;\nexport const MSG_TYPE_RESPONSE = 1;\nexport const MSG_TYPE_EVENT = 2;\nexport const MSG_TYPE_ERROR = 3;\n\n/** MessageType の string 表現 (= 診断用、 SDK API surface) */\nexport type MessageTypeName = \"request\" | \"response\" | \"event\" | \"error\";\n\n/** enum 値 → string 名 */\nexport function messageTypeName(v: number): MessageTypeName {\n switch (v) {\n case MSG_TYPE_RESPONSE:\n return \"response\";\n case MSG_TYPE_EVENT:\n return \"event\";\n case MSG_TYPE_ERROR:\n return \"error\";\n default:\n return \"request\";\n }\n}\n\n/** string 名 → enum 値 */\nexport function messageTypeValue(name: MessageTypeName): number {\n switch (name) {\n case \"response\":\n return MSG_TYPE_RESPONSE;\n case \"event\":\n return MSG_TYPE_EVENT;\n case \"error\":\n return MSG_TYPE_ERROR;\n default:\n return MSG_TYPE_REQUEST;\n }\n}\n\n/** `proto.ProtocolMessage` の TS 表現 */\nexport interface ProtocolMessage {\n /** message ID (= Request は一意、 Event は 0) */\n id: number;\n /** method 名 (= request/event 名、 または `__channel:` / `__identity` route) */\n method: string;\n /** メッセージ種別 */\n msgType: number;\n /** codec が encode した payload バイト列 */\n payload: Uint8Array;\n}\n\n/** `ProtocolMessage` を proto3 byte 列へ encode (= field 番号昇順) */\nexport function encodeProtocolMessage(m: ProtocolMessage): Uint8Array {\n const w = new ProtoWriter();\n w.uint64(1, m.id);\n w.string(2, m.method);\n w.enum(3, m.msgType);\n w.bytes(4, m.payload);\n return w.finish();\n}\n\n/** proto3 byte 列から `ProtocolMessage` を decode (= 未設定 field は default) */\nexport function decodeProtocolMessage(bytes: Uint8Array): ProtocolMessage {\n const m: ProtocolMessage = {\n id: 0,\n method: \"\",\n msgType: MSG_TYPE_REQUEST,\n payload: new Uint8Array(0),\n };\n const r = new ProtoReader(bytes);\n for (let f = r.next(); f !== null; f = r.next()) {\n switch (f.fieldNo) {\n case 1:\n m.id = Number(f.varint ?? 0n);\n break;\n case 2:\n m.method = f.bytes !== undefined ? decodeProtoString(f.bytes) : \"\";\n break;\n case 3:\n m.msgType = Number(f.varint ?? 0n);\n break;\n case 4:\n m.payload = f.bytes ?? new Uint8Array(0);\n break;\n default:\n break; // 未知 field は無視\n }\n }\n return m;\n}\n","/**\n * Channel stream の wire frame (= Phase 6b、 Rust server と byte 一致)。\n *\n * `UnisonChannel` (= QUIC / WebTransport bidi stream) を流れる typed frame の\n * encode/decode。 Rust `crates/unison-protocol/src/network/quic.rs` の\n * `read_typed_frame` / `write_typed_frame` と完全一致する layout:\n *\n * ```text\n * [4B BE total_len] [1B frame_type] [payload]\n * ```\n *\n * - `total_len` = frame_type (1B) + payload の合計\n * - `frame_type` = 0x00 PROTOCOL (= UnisonPacket) / 0x01 RAW (= 生 bytes)\n * - PROTOCOL frame の payload = UnisonPacket バイト列\n * (= `[u32 BE header_len][buffa PacketHeader][buffa ProtocolMessage]`)\n *\n * 旧 Phase 2c の `[4B len][2B hdrLen][JSON header][payload]` 自家製 frame は\n * 廃止 (= Rust server と通信不能だった)。\n */\n\nimport { decodePacket, encodePacket, type PacketOptions } from \"../wire/packet.js\";\nimport {\n decodeProtocolMessage,\n encodeProtocolMessage,\n type ProtocolMessage,\n} from \"../wire/protocol_message.js\";\n\n/** frame type tag (= Rust `FRAME_TYPE_*`) */\nexport const FRAME_TYPE_PROTOCOL = 0x00;\nexport const FRAME_TYPE_RAW = 0x01;\n\n/** typed frame の最大 size (= Rust `MAX_MESSAGE_SIZE`、 8MB) */\nconst MAX_FRAME_SIZE = 8 * 1024 * 1024;\n\n/**\n * `ProtocolMessage` を 1 本の PROTOCOL typed frame へ encode する。\n *\n * layout: `[4B total_len][0x00][UnisonPacket]`。 `UnisonPacket` の中身は\n * `[u32 header_len][PacketHeader][ProtocolMessage]`。\n */\nexport function encodeProtocolFrame(\n message: ProtocolMessage,\n packetOpts: PacketOptions = {},\n): Uint8Array {\n const msgBytes = encodeProtocolMessage(message);\n const packet = encodePacket(msgBytes, packetOpts);\n return wrapTypedFrame(FRAME_TYPE_PROTOCOL, packet);\n}\n\n/** 生 byte 列を 1 本の RAW typed frame へ encode する (= `[4B len][0x01][data]`) */\nexport function encodeRawFrame(data: Uint8Array): Uint8Array {\n return wrapTypedFrame(FRAME_TYPE_RAW, data);\n}\n\n/** type tag + payload を length-prefixed typed frame へ wrap */\nfunction wrapTypedFrame(frameType: number, payload: Uint8Array): Uint8Array {\n const totalLen = 1 + payload.length;\n const frame = new Uint8Array(4 + totalLen);\n new DataView(frame.buffer).setUint32(0, totalLen, false);\n frame[4] = frameType & 0xff;\n frame.set(payload, 5);\n return frame;\n}\n\n/** typed frame の decode 結果 */\nexport type DecodedFrame =\n | { type: \"protocol\"; message: ProtocolMessage }\n | { type: \"raw\"; data: Uint8Array };\n\n/**\n * 1 本の typed frame body (= 4B length prefix を剥がした後の `[1B type][payload]`)\n * を decode する。\n */\nexport function decodeTypedFrame(body: Uint8Array): DecodedFrame {\n if (body.length < 1) {\n throw new Error(\"frame: empty typed frame (missing type tag)\");\n }\n const frameType = body[0] as number;\n const payload = body.subarray(1);\n if (frameType === FRAME_TYPE_PROTOCOL) {\n const { payload: msgBytes } = decodePacket(payload);\n return { type: \"protocol\", message: decodeProtocolMessage(msgBytes) };\n }\n if (frameType === FRAME_TYPE_RAW) {\n return { type: \"raw\", data: payload };\n }\n throw new Error(`frame: unknown frame type tag 0x${frameType.toString(16)}`);\n}\n\n/**\n * `ReadableStream<Uint8Array>` から typed frame body (= `[1B type][payload]`) を\n * 1 本ずつ取り出す async generator。 byte 跨ぎ chunk を内部 buffer で結合する。\n */\nexport async function* readFrames(\n readable: ReadableStream<Uint8Array>,\n): AsyncGenerator<Uint8Array> {\n const reader = readable.getReader();\n let buffer: Uint8Array<ArrayBufferLike> = new Uint8Array(0);\n try {\n for (;;) {\n // length prefix (4B) が揃うまで読む\n while (buffer.length < 4) {\n const { value, done } = await reader.read();\n if (done) return;\n if (value !== undefined) buffer = concat(buffer, value);\n }\n const totalLen = new DataView(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength,\n ).getUint32(0, false);\n if (totalLen === 0) throw new Error(\"frame: empty frame\");\n if (totalLen > MAX_FRAME_SIZE) {\n throw new Error(`frame: too large (${totalLen} bytes)`);\n }\n // body 全体が揃うまで読む\n while (buffer.length < 4 + totalLen) {\n const { value, done } = await reader.read();\n if (done) return;\n if (value !== undefined) buffer = concat(buffer, value);\n }\n yield buffer.subarray(4, 4 + totalLen);\n buffer = buffer.slice(4 + totalLen);\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction concat(\n a: Uint8Array<ArrayBufferLike>,\n b: Uint8Array<ArrayBufferLike>,\n): Uint8Array<ArrayBuffer> {\n const out = new Uint8Array(a.length + b.length);\n out.set(a, 0);\n out.set(b, a.length);\n return out;\n}\n"],"names":["CodecError","message","options","encoder","decoder","JsonCodec","value","cause","describe","bytes","text","AsyncQueue","#buffer","#pending","#closed","resolve","buffered","textEncoder","textDecoder","WIRE_VARINT","WIRE_LEN","ProtoWriter","#chunks","#byte","b","#varint","v","#tag","fieldNo","wireType","ProtoReader","#buf","#pos","buf","#readVarint","result","shift","tag","len","decodeProtoString","PACKET_VERSION","PACKET_TYPE_DATA","FLAG_COMPRESSED","newPacketHeader","packetType","encodePacketHeader","h","w","decodePacketHeader","r","f","isCompressed","actualPayloadSize","encodePacket","payload","opts","header","headerBytes","out","decodePacket","headerLen","payloadBytes","expected","MSG_TYPE_REQUEST","MSG_TYPE_RESPONSE","MSG_TYPE_EVENT","MSG_TYPE_ERROR","messageTypeName","messageTypeValue","name","encodeProtocolMessage","m","decodeProtocolMessage","FRAME_TYPE_PROTOCOL","FRAME_TYPE_RAW","MAX_FRAME_SIZE","encodeProtocolFrame","packetOpts","msgBytes","packet","wrapTypedFrame","encodeRawFrame","data","frameType","totalLen","frame","decodeTypedFrame","body","readFrames","readable","reader","buffer","done","concat","a"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -18,14 +18,16 @@ export type { ChannelMeta, ChannelPayload, ChannelTypeMap, DatagramChannel, Data
18
18
  export { UnisonChannelImpl } from "./channel/unison_channel.js";
19
19
  export { DatagramChannelImpl } from "./channel/datagram_channel.js";
20
20
  export { DatagramDispatcher, DispatcherInner } from "./channel/dispatcher.js";
21
- export { FRAME_TYPE_PROTOCOL, FRAME_TYPE_RAW, decodeTypedFrame, encodeProtocolFrame, encodeRawFrame, } from "./channel/frame.js";
21
+ export { FRAME_TYPE_PROTOCOL, FRAME_TYPE_RAW, decodeTypedFrame, encodeProtocolFrame, encodeRawFrame, readFrames, } from "./channel/frame.js";
22
22
  export type { DecodedFrame } from "./channel/frame.js";
23
+ export { AsyncQueue } from "./channel/async_queue.js";
24
+ export { encodeVarint } from "./channel/varint.js";
23
25
  export { decodePacket, encodePacket } from "./wire/packet.js";
24
26
  export type { DecodedPacket, PacketOptions } from "./wire/packet.js";
25
27
  export { PACKET_VERSION, decodePacketHeader, encodePacketHeader, newPacketHeader, } from "./wire/packet_header.js";
26
28
  export type { PacketHeader } from "./wire/packet_header.js";
27
29
  export { MSG_TYPE_ERROR, MSG_TYPE_EVENT, MSG_TYPE_REQUEST, MSG_TYPE_RESPONSE, decodeProtocolMessage, encodeProtocolMessage, messageTypeName, messageTypeValue, } from "./wire/protocol_message.js";
28
- export type { MessageTypeName, ProtocolMessage } from "./wire/protocol_message.js";
30
+ export type { MessageTypeName, ProtocolMessage, } from "./wire/protocol_message.js";
29
31
  export { DEFAULT_IDENTITY_TIMEOUT_MS, performIdentityHandshake, readIdentity, } from "./channel/identity.js";
30
32
  export type { ChannelDirection, ChannelInfo, ChannelStatus, ServerIdentity, } from "./channel/identity.js";
31
33
  export type { Codec, CodecFormat } from "./codec/codec.js";
@@ -34,5 +36,5 @@ export { JsonCodec } from "./codec/json_codec.js";
34
36
  export { ProtoCodec } from "./codec/proto_codec.js";
35
37
  export type { UnisonConnectOptions } from "./client.js";
36
38
  export { UnisonClient, connect } from "./client.js";
37
- export declare const VERSION = "1.0.0-rc.1";
39
+ export declare const VERSION = "1.1.0";
38
40
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAGvD,YAAY,EACV,UAAU,EACV,UAAU,EACV,eAAe,EACf,cAAc,EACd,SAAS,EACT,SAAS,GACV,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,oBAAoB,EACpB,4BAA4B,GAC7B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EAGtB,OAAO,IAAI,gBAAgB,GAC5B,MAAM,8BAA8B,CAAC;AAGtC,YAAY,EACV,WAAW,EACX,cAAc,EACd,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,SAAS,EACT,YAAY,EACZ,SAAS,EACT,WAAW,EACX,WAAW,EACX,YAAY,EACZ,aAAa,GACd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG9E,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,GACf,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC9D,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,GAChB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EACL,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,EACf,gBAAgB,GACjB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAGnF,OAAO,EACL,2BAA2B,EAC3B,wBAAwB,EACxB,YAAY,GACb,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,cAAc,GACf,MAAM,uBAAuB,CAAC;AAG/B,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAIpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGpD,eAAO,MAAM,OAAO,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAGvD,YAAY,EACX,UAAU,EACV,UAAU,EACV,eAAe,EACf,cAAc,EACd,SAAS,EACT,SAAS,GACT,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACN,oBAAoB,EACpB,4BAA4B,GAC5B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACN,kBAAkB,EAClB,sBAAsB,EAGtB,OAAO,IAAI,gBAAgB,GAC3B,MAAM,8BAA8B,CAAC;AAGtC,YAAY,EACX,WAAW,EACX,cAAc,EACd,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,SAAS,EACT,YAAY,EACZ,SAAS,EACT,WAAW,EACX,WAAW,EACX,YAAY,EACZ,aAAa,GACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG9E,OAAO,EACN,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACd,UAAU,GACV,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC9D,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EACN,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,GACf,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EACN,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,EACf,gBAAgB,GAChB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACX,eAAe,EACf,eAAe,GACf,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EACN,2BAA2B,EAC3B,wBAAwB,EACxB,YAAY,GACZ,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACX,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,cAAc,GACd,MAAM,uBAAuB,CAAC;AAG/B,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAIpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGpD,eAAO,MAAM,OAAO,UAAU,CAAC"}