@anycon/protocol 0.1.1 → 0.2.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.
@@ -0,0 +1,554 @@
1
+ /**
2
+ * dev server 预览(ADR-39,docs/protocol.md § 11)的 TS 侧:启动参数的编解码、label 校验、预览 origin。
3
+ * 隧道消息 / 帧的编解码与 `crates/protocol/src/preview.rs` 的 `tunnel` 模块逐字节一致
4
+ * (`tests/vectors/preview.json`)。
5
+ */
6
+ import { decode, encode } from '@msgpack/msgpack';
7
+ import { ProtocolError } from './errors.js';
8
+ /** 预览 label:26 个字符的小写 base32(RFC 4648 字母表,无填充)。 */
9
+ export const PREVIEW_LABEL_LEN = 26;
10
+ export const PREVIEW_LABEL_ALPHABET = 'abcdefghijklmnopqrstuvwxyz234567';
11
+ /** `PreviewLaunch.v` 的当前版本。 */
12
+ export const PREVIEW_LAUNCH_VERSION = 1;
13
+ /** 预览页的入口路径:hub 在这里回引导页,启动参数放在 fragment 里。 */
14
+ export const PREVIEW_ENTER_PATH = '/__anycon/enter';
15
+ const LABEL_RE = /^[a-z2-7]{26}$/;
16
+ export function isValidPreviewLabel(label) {
17
+ return LABEL_RE.test(label);
18
+ }
19
+ /**
20
+ * 按 hub 的模板(`/api/config.preview_origin_template`,如 `https://{label}.aiplace.app`)算出预览 origin。
21
+ * label 不合法时抛错:它会成为主机名的一段。
22
+ */
23
+ export function previewOrigin(template, label) {
24
+ if (!isValidPreviewLabel(label))
25
+ throw new ProtocolError(`invalid preview label: ${label}`);
26
+ if (!template.includes('{label}'))
27
+ throw new ProtocolError('preview origin template has no {label}');
28
+ return template.replace('{label}', label);
29
+ }
30
+ function base64urlEncode(bytes) {
31
+ let bin = '';
32
+ for (const b of bytes)
33
+ bin += String.fromCharCode(b);
34
+ return btoa(bin).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
35
+ }
36
+ function base64urlDecode(text) {
37
+ if (!/^[A-Za-z0-9_-]*$/.test(text))
38
+ throw new ProtocolError('invalid base64url');
39
+ const std = text.replace(/-/g, '+').replace(/_/g, '/');
40
+ const padded = std + '='.repeat((4 - (std.length % 4)) % 4);
41
+ const bin = atob(padded);
42
+ const out = new Uint8Array(bin.length);
43
+ for (let i = 0; i < bin.length; i++)
44
+ out[i] = bin.charCodeAt(i);
45
+ return out;
46
+ }
47
+ /** `PreviewLaunch` → URL fragment(不含 `#`):JSON 的 UTF-8 字节做 base64url,无填充。 */
48
+ export function encodePreviewLaunch(launch) {
49
+ return base64urlEncode(new TextEncoder().encode(JSON.stringify(launch)));
50
+ }
51
+ /** `path` 里不许出现的字符:反斜杠和 ASCII 控制字符(U+0000–U+001F、U+007F)。 */
52
+ function hasForbiddenPathChar(path) {
53
+ for (let i = 0; i < path.length; i++) {
54
+ const c = path.charCodeAt(i);
55
+ if (c === 0x5c || c <= 0x1f || c === 0x7f)
56
+ return true;
57
+ }
58
+ return false;
59
+ }
60
+ const HEX32 = /^[0-9a-f]{32}$/;
61
+ const HEX64 = /^[0-9a-f]{64}$/;
62
+ /**
63
+ * URL fragment(可以带或不带开头的 `#`)→ `PreviewLaunch`。格式不对一律抛 `ProtocolError`:
64
+ * 版本、label、id 和密钥的格式、端口范围、`path` 以 `/` 开头且不是 `//`(协议相对 URL)、不含 `\` 和控制字符。
65
+ */
66
+ export function decodePreviewLaunch(fragment) {
67
+ const text = fragment.startsWith('#') ? fragment.slice(1) : fragment;
68
+ let value;
69
+ try {
70
+ value = JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(base64urlDecode(text)));
71
+ }
72
+ catch (err) {
73
+ if (err instanceof ProtocolError)
74
+ throw err;
75
+ throw new ProtocolError('invalid preview launch');
76
+ }
77
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
78
+ throw new ProtocolError('invalid preview launch');
79
+ }
80
+ const v = value;
81
+ const str = (k) => {
82
+ const x = v[k];
83
+ if (typeof x !== 'string')
84
+ throw new ProtocolError(`preview launch: ${k} must be a string`);
85
+ return x;
86
+ };
87
+ const int = (k, min, max) => {
88
+ const x = v[k];
89
+ if (typeof x !== 'number' || !Number.isInteger(x) || x < min || x > max) {
90
+ throw new ProtocolError(`preview launch: ${k} out of range`);
91
+ }
92
+ return x;
93
+ };
94
+ const launch = {
95
+ v: int('v', 0, Number.MAX_SAFE_INTEGER),
96
+ node: str('node'),
97
+ node_public: str('node_public'),
98
+ label: str('label'),
99
+ port: int('port', 1, 65535),
100
+ ticket_id: str('ticket_id'),
101
+ psk: str('psk'),
102
+ token: str('token'),
103
+ expires_at_ms: int('expires_at_ms', 0, Number.MAX_SAFE_INTEGER),
104
+ path: str('path'),
105
+ };
106
+ if (launch.v !== PREVIEW_LAUNCH_VERSION)
107
+ throw new ProtocolError(`unsupported preview launch version ${launch.v}`);
108
+ if (!isValidPreviewLabel(launch.label))
109
+ throw new ProtocolError('preview launch: invalid label');
110
+ if (!HEX32.test(launch.node) || !HEX32.test(launch.ticket_id))
111
+ throw new ProtocolError('preview launch: invalid id');
112
+ if (!HEX64.test(launch.node_public) || !HEX64.test(launch.psk))
113
+ throw new ProtocolError('preview launch: invalid key');
114
+ if (launch.token.length === 0)
115
+ throw new ProtocolError('preview launch: empty token');
116
+ if (!launch.path.startsWith('/') || launch.path.startsWith('//')) {
117
+ throw new ProtocolError('preview launch: path must start with a single /');
118
+ }
119
+ // 浏览器把 `\` 当 `/`、并且会去掉 tab / 换行:`/\evil.example` 会变成协议相对的 URL
120
+ if (hasForbiddenPathChar(launch.path)) {
121
+ throw new ProtocolError('preview launch: path must not contain a backslash or control characters');
122
+ }
123
+ return launch;
124
+ }
125
+ // ---------------------------------------------------------------------------
126
+ // 隧道(docs/protocol.md § 11):二进制格式和常量。与 `crates/protocol/src/preview.rs` 的 `tunnel` 模块
127
+ // 逐字节一致,`tests/vectors/preview.json`(Rust 生成)守着。
128
+ // ---------------------------------------------------------------------------
129
+ /** 票据 id 的字节数。 */
130
+ export const TUNNEL_TICKET_ID_LEN = 16;
131
+ /** 票据密钥(Noise PSK)的字节数。 */
132
+ export const TUNNEL_PSK_LEN = 32;
133
+ /** 握手第一条消息 body 的版本字节。 */
134
+ export const TUNNEL_HANDSHAKE_VERSION = 1;
135
+ /** 握手回复 body 的第一个字节:接受(后面是 Noise 第二条消息)。 */
136
+ export const TUNNEL_HANDSHAKE_ACCEPT = 0x00;
137
+ /** 握手回复 body 的第一个字节:拒绝(后面是 UTF-8 原因)。 */
138
+ export const TUNNEL_HANDSHAKE_REJECT = 0x01;
139
+ /** Noise prologue 的前缀。完整 prologue = 前缀 ‖ 0x00 ‖ label ‖ 0x00 ‖ ticket_id(16 字节)。 */
140
+ export const TUNNEL_PROLOGUE_PREFIX = 'anycon-preview-v1';
141
+ /** 一条隧道消息的明文上限(加密后仍小于一个 `WHOLE` 数据帧,所以预览隧道从不分片)。 */
142
+ export const TUNNEL_MAX_MESSAGE = 128 * 1024;
143
+ /** 单个 `DATA` / `WS_MESSAGE` 帧的数据上限。 */
144
+ export const TUNNEL_MAX_DATA_FRAME = 64 * 1024;
145
+ /** `REQUEST` / `RESPONSE` 头部(msgpack 编码后)上限。 */
146
+ export const TUNNEL_MAX_HEAD = 64 * 1024;
147
+ /** 一条 WebSocket 消息(拼起来之后)的上限。 */
148
+ export const TUNNEL_MAX_WS_MESSAGE = 16 * 1024 * 1024;
149
+ /** 每个 stream 每个方向初始的流量窗口(`DATA` 和 `WS_MESSAGE` 的数据字节)。 */
150
+ export const TUNNEL_STREAM_WINDOW = 256 * 1024;
151
+ /** 一条隧道上同时打开的 stream 上限。 */
152
+ export const TUNNEL_MAX_STREAMS = 256;
153
+ /** 发送方未被回执的密文上限:daemon → 预览页。 */
154
+ export const TUNNEL_DAEMON_INFLIGHT = 8 * 1024 * 1024;
155
+ /** 发送方未被回执的密文上限:预览页 → daemon。 */
156
+ export const TUNNEL_CLIENT_INFLIGHT = 2 * 1024 * 1024;
157
+ /** 收到这么多字节(或 `TUNNEL_ACK_EVERY_MESSAGES` 条)还没回执过、手里又没有别的要发时,立即发一条纯回执消息。 */
158
+ export const TUNNEL_ACK_EVERY_BYTES = 256 * 1024;
159
+ export const TUNNEL_ACK_EVERY_MESSAGES = 32;
160
+ /** 收到消息后最多等这么久就发纯回执。 */
161
+ export const TUNNEL_ACK_DELAY_MS = 50;
162
+ /** WebSocket 关闭原因的字节上限(RFC 6455)。 */
163
+ export const TUNNEL_WS_CLOSE_REASON_MAX = 123;
164
+ /** `WS_MESSAGE` 标志位:二进制消息(否则是文本)。 */
165
+ export const TUNNEL_WS_BINARY = 0x01;
166
+ /** `WS_MESSAGE` 标志位:这是这条 WebSocket 消息的最后一段。 */
167
+ export const TUNNEL_WS_FIN = 0x02;
168
+ /** 帧头:类型 1 字节 + stream 4 字节 + 长度 4 字节。 */
169
+ export const TUNNEL_FRAME_HEADER = 1 + 4 + 4;
170
+ const MESSAGE_HEADER = 8;
171
+ /** 帧类型(§ 11.3)。 */
172
+ export const TunnelFrameType = {
173
+ /** P→D,msgpack `PreviewRequestHead`,打开一个 stream。 */
174
+ Request: 0x01,
175
+ /** D→P,msgpack `PreviewResponseHead`。 */
176
+ Response: 0x02,
177
+ /** 双向,HTTP 消息体的一段。占流量窗口。 */
178
+ Data: 0x03,
179
+ /** 双向,无载荷:这个方向的消息体结束。 */
180
+ End: 0x04,
181
+ /** 双向,msgpack `PreviewReset`:终止 stream。 */
182
+ Reset: 0x05,
183
+ /** 双向,4 字节大端:给对端这个 stream 增加的窗口。 */
184
+ Window: 0x06,
185
+ /** 双向,1 字节标志 + 数据:WebSocket 消息的一段。占流量窗口。 */
186
+ WsMessage: 0x07,
187
+ /** 双向,2 字节大端关闭码 + UTF-8 原因。 */
188
+ WsClose: 0x08,
189
+ /** D→P,stream 0,msgpack `PreviewGoaway`。 */
190
+ Goaway: 0x09,
191
+ };
192
+ const FRAME_TYPES = new Set(Object.values(TunnelFrameType));
193
+ /** 隧道字节不合法。`code` 与 Rust 的 `TunnelError` 变体对应(snake_case)。 */
194
+ export class TunnelError extends ProtocolError {
195
+ code;
196
+ name = 'TunnelError';
197
+ constructor(code, message = code) {
198
+ super(message);
199
+ this.code = code;
200
+ }
201
+ }
202
+ export function newTunnelFrame(type, stream, payload = new Uint8Array(0)) {
203
+ return { type, stream, payload };
204
+ }
205
+ /** 一帧编码后的字节数。 */
206
+ export function tunnelFrameLen(frame) {
207
+ return TUNNEL_FRAME_HEADER + frame.payload.length;
208
+ }
209
+ /** 消息明文的字节数(编码前就能算,用来决定还能不能再塞一帧)。 */
210
+ export function messageLen(frames) {
211
+ let n = MESSAGE_HEADER;
212
+ for (const f of frames)
213
+ n += tunnelFrameLen(f);
214
+ return n;
215
+ }
216
+ /** 编码一条隧道消息。超过 `TUNNEL_MAX_MESSAGE` 抛 `TunnelError('too_large')`(调用方负责把帧分到多条消息里)。 */
217
+ export function encodeMessage(ack, frames) {
218
+ const len = messageLen(frames);
219
+ if (len > TUNNEL_MAX_MESSAGE)
220
+ throw new TunnelError('too_large', 'tunnel message too large');
221
+ const big = typeof ack === 'bigint' ? ack : BigInt(ack);
222
+ if (big < 0n || big > 0xffffffffffffffffn)
223
+ throw new TunnelError('malformed', 'ack out of range');
224
+ const out = new Uint8Array(len);
225
+ const view = new DataView(out.buffer);
226
+ view.setBigUint64(0, big, false);
227
+ let at = MESSAGE_HEADER;
228
+ for (const f of frames) {
229
+ if (!Number.isInteger(f.stream) || f.stream < 0 || f.stream > 0xffff_ffff) {
230
+ throw new TunnelError('malformed', 'stream id out of range');
231
+ }
232
+ out[at] = f.type;
233
+ view.setUint32(at + 1, f.stream, false);
234
+ view.setUint32(at + 5, f.payload.length, false);
235
+ out.set(f.payload, at + TUNNEL_FRAME_HEADER);
236
+ at += TUNNEL_FRAME_HEADER + f.payload.length;
237
+ }
238
+ return out;
239
+ }
240
+ /** 解码一条隧道消息。未知类型的帧跳过(前向兼容);长度越界抛 `truncated`,超过上限抛 `too_large`。载荷是拷贝。 */
241
+ export function decodeMessage(buf) {
242
+ if (buf.length > TUNNEL_MAX_MESSAGE)
243
+ throw new TunnelError('too_large', 'tunnel message too large');
244
+ if (buf.length < MESSAGE_HEADER)
245
+ throw new TunnelError('truncated', 'truncated tunnel message');
246
+ const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
247
+ const ack = view.getBigUint64(0, false);
248
+ const frames = [];
249
+ let at = MESSAGE_HEADER;
250
+ while (at < buf.length) {
251
+ if (buf.length - at < TUNNEL_FRAME_HEADER)
252
+ throw new TunnelError('truncated', 'truncated frame header');
253
+ const type = buf[at];
254
+ const stream = view.getUint32(at + 1, false);
255
+ const len = view.getUint32(at + 5, false);
256
+ if (buf.length - at - TUNNEL_FRAME_HEADER < len) {
257
+ throw new TunnelError('truncated', 'truncated frame payload');
258
+ }
259
+ const start = at + TUNNEL_FRAME_HEADER;
260
+ if (FRAME_TYPES.has(type)) {
261
+ frames.push({
262
+ type: type,
263
+ stream,
264
+ payload: buf.slice(start, start + len),
265
+ });
266
+ }
267
+ at = start + len;
268
+ }
269
+ return { ack, frames };
270
+ }
271
+ // ---------- 头部:msgpack,字段名为键,键序与 Rust 结构体的声明顺序一致 ----------
272
+ const REQUEST_HEAD_KEYS = ['method', 'path', 'headers', 'websocket'];
273
+ const RESPONSE_HEAD_KEYS = ['status', 'headers', 'encoding'];
274
+ const RESET_CODES = new Set([
275
+ 'refused',
276
+ 'timeout',
277
+ 'too_large',
278
+ 'cancelled',
279
+ 'flow_control',
280
+ 'protocol',
281
+ 'limit',
282
+ 'internal',
283
+ ]);
284
+ const GOAWAY_CODES = new Set([
285
+ 'expired',
286
+ 'closed',
287
+ 'revoked',
288
+ 'disabled',
289
+ 'port_not_allowed',
290
+ 'shutdown',
291
+ ]);
292
+ function packHead(value) {
293
+ const bytes = encode(value, { ignoreUndefined: true });
294
+ if (bytes.length > TUNNEL_MAX_HEAD)
295
+ throw new TunnelError('too_large', 'tunnel head too large');
296
+ return bytes;
297
+ }
298
+ function unpackHead(payload) {
299
+ if (payload.length > TUNNEL_MAX_HEAD)
300
+ throw new TunnelError('too_large', 'tunnel head too large');
301
+ let value;
302
+ try {
303
+ value = decode(payload);
304
+ }
305
+ catch {
306
+ throw new TunnelError('malformed', 'head decode');
307
+ }
308
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
309
+ throw new TunnelError('malformed', 'head decode');
310
+ }
311
+ return value;
312
+ }
313
+ function headerPairs(value) {
314
+ if (!Array.isArray(value))
315
+ throw new TunnelError('malformed', 'head headers');
316
+ return value.map((pair) => {
317
+ if (!Array.isArray(pair) ||
318
+ pair.length !== 2 ||
319
+ typeof pair[0] !== 'string' ||
320
+ typeof pair[1] !== 'string') {
321
+ throw new TunnelError('malformed', 'head headers');
322
+ }
323
+ return [pair[0], pair[1]];
324
+ });
325
+ }
326
+ function optionalMessage(value) {
327
+ if (value === undefined || value === null)
328
+ return undefined;
329
+ if (typeof value !== 'string')
330
+ throw new TunnelError('malformed', 'head message');
331
+ return value;
332
+ }
333
+ /** `REQUEST` 载荷。键序 `method, path, headers, websocket`(`websocket` 总是写出)。 */
334
+ export function encodeRequestHead(head) {
335
+ const src = { ...head, websocket: head.websocket ?? false };
336
+ return packHead(Object.fromEntries(REQUEST_HEAD_KEYS.map((k) => [k, src[k]])));
337
+ }
338
+ export function decodeRequestHead(payload) {
339
+ const v = unpackHead(payload);
340
+ if (typeof v.method !== 'string' || typeof v.path !== 'string') {
341
+ throw new TunnelError('malformed', 'request head');
342
+ }
343
+ if (v.websocket !== undefined && typeof v.websocket !== 'boolean') {
344
+ throw new TunnelError('malformed', 'request head');
345
+ }
346
+ return {
347
+ method: v.method,
348
+ path: v.path,
349
+ headers: headerPairs(v.headers),
350
+ websocket: v.websocket === true,
351
+ };
352
+ }
353
+ /** `RESPONSE` 载荷。键序 `status, headers, encoding`(`encoding` 总是写出)。 */
354
+ export function encodeResponseHead(head) {
355
+ const src = { ...head, encoding: head.encoding ?? 'identity' };
356
+ return packHead(Object.fromEntries(RESPONSE_HEAD_KEYS.map((k) => [k, src[k]])));
357
+ }
358
+ export function decodeResponseHead(payload) {
359
+ const v = unpackHead(payload);
360
+ if (typeof v.status !== 'number' ||
361
+ !Number.isInteger(v.status) ||
362
+ v.status < 0 ||
363
+ v.status > 0xffff) {
364
+ throw new TunnelError('malformed', 'response head');
365
+ }
366
+ const encoding = v.encoding ?? 'identity';
367
+ if (encoding !== 'identity' && encoding !== 'gzip')
368
+ throw new TunnelError('malformed', 'response head');
369
+ return { status: v.status, headers: headerPairs(v.headers), encoding };
370
+ }
371
+ /** `RESET` 载荷。键序 `code, message?`(`message` 为空时省略键)。 */
372
+ export function encodeReset(reset) {
373
+ return packHead(reset.message === undefined || reset.message === null
374
+ ? { code: reset.code }
375
+ : { code: reset.code, message: reset.message });
376
+ }
377
+ export function decodeReset(payload) {
378
+ const v = unpackHead(payload);
379
+ if (typeof v.code !== 'string' || !RESET_CODES.has(v.code))
380
+ throw new TunnelError('malformed', 'reset');
381
+ const message = optionalMessage(v.message);
382
+ return message === undefined
383
+ ? { code: v.code }
384
+ : { code: v.code, message };
385
+ }
386
+ /** `GOAWAY` 载荷(只有 daemon 发)。键序 `code, message?`。 */
387
+ export function encodeGoaway(goaway) {
388
+ return packHead(goaway.message === undefined || goaway.message === null
389
+ ? { code: goaway.code }
390
+ : { code: goaway.code, message: goaway.message });
391
+ }
392
+ export function decodeGoaway(payload) {
393
+ const v = unpackHead(payload);
394
+ if (typeof v.code !== 'string' || !GOAWAY_CODES.has(v.code))
395
+ throw new TunnelError('malformed', 'goaway');
396
+ const message = optionalMessage(v.message);
397
+ return message === undefined
398
+ ? { code: v.code }
399
+ : { code: v.code, message };
400
+ }
401
+ // ---------- 小载荷 ----------
402
+ /** `WINDOW` 载荷:u32 大端,给对端这个 stream 增加的窗口字节。 */
403
+ export function windowPayload(increment) {
404
+ if (!Number.isInteger(increment) || increment < 0 || increment > 0xffff_ffff) {
405
+ throw new TunnelError('malformed', 'window increment out of range');
406
+ }
407
+ const out = new Uint8Array(4);
408
+ new DataView(out.buffer).setUint32(0, increment, false);
409
+ return out;
410
+ }
411
+ export function parseWindow(payload) {
412
+ if (payload.length !== 4)
413
+ throw new TunnelError('malformed', 'window');
414
+ return new DataView(payload.buffer, payload.byteOffset, 4).getUint32(0, false);
415
+ }
416
+ /** `WS_MESSAGE` 载荷:标志(`TUNNEL_WS_BINARY` / `TUNNEL_WS_FIN`)‖ 数据。 */
417
+ export function wsMessage(flags, data) {
418
+ const out = new Uint8Array(1 + data.length);
419
+ out[0] = flags;
420
+ out.set(data, 1);
421
+ return out;
422
+ }
423
+ /** 返回 `{ flags, data }`;`data` 是 `payload` 的视图。 */
424
+ export function parseWsMessage(payload) {
425
+ if (payload.length === 0)
426
+ throw new TunnelError('malformed', 'ws message');
427
+ return { flags: payload[0], data: payload.subarray(1) };
428
+ }
429
+ /** `WS_CLOSE` 载荷:关闭码(u16 大端)‖ 原因。原因超过 `TUNNEL_WS_CLOSE_REASON_MAX` 字节时在 UTF-8 字符边界处截断。 */
430
+ export function wsClose(code, reason) {
431
+ if (!Number.isInteger(code) || code < 0 || code > 0xffff) {
432
+ throw new TunnelError('malformed', 'ws close code out of range');
433
+ }
434
+ const bytes = new TextEncoder().encode(reason);
435
+ let end = Math.min(bytes.length, TUNNEL_WS_CLOSE_REASON_MAX);
436
+ // 下标 `end` 处是 UTF-8 续字节(10xxxxxx)说明切在了字符中间,往回退到字符起点
437
+ while (end > 0 && end < bytes.length && (bytes[end] & 0xc0) === 0x80)
438
+ end--;
439
+ const out = new Uint8Array(2 + end);
440
+ new DataView(out.buffer).setUint16(0, code, false);
441
+ out.set(bytes.subarray(0, end), 2);
442
+ return out;
443
+ }
444
+ export function parseWsClose(payload) {
445
+ if (payload.length < 2)
446
+ throw new TunnelError('malformed', 'ws close');
447
+ const code = new DataView(payload.buffer, payload.byteOffset, 2).getUint16(0, false);
448
+ let reason;
449
+ try {
450
+ reason = new TextDecoder('utf-8', { fatal: true }).decode(payload.subarray(2));
451
+ }
452
+ catch {
453
+ throw new TunnelError('malformed', 'ws close reason');
454
+ }
455
+ return { code, reason };
456
+ }
457
+ // ---------- 握手 ----------
458
+ /** 握手第一条(P → D)的信封 body:版本 ‖ ticket_id ‖ Noise 消息。 */
459
+ export function handshakeInit(ticketId, noise) {
460
+ if (ticketId.length !== TUNNEL_TICKET_ID_LEN)
461
+ throw new TunnelError('malformed', 'ticket id length');
462
+ const out = new Uint8Array(1 + TUNNEL_TICKET_ID_LEN + noise.length);
463
+ out[0] = TUNNEL_HANDSHAKE_VERSION;
464
+ out.set(ticketId, 1);
465
+ out.set(noise, 1 + TUNNEL_TICKET_ID_LEN);
466
+ return out;
467
+ }
468
+ export function parseHandshakeInit(body) {
469
+ if (body.length === 0)
470
+ throw new TunnelError('truncated', 'empty handshake');
471
+ if (body[0] !== TUNNEL_HANDSHAKE_VERSION) {
472
+ throw new TunnelError('version', `unsupported handshake version ${body[0]}`);
473
+ }
474
+ if (body.length < 1 + TUNNEL_TICKET_ID_LEN)
475
+ throw new TunnelError('truncated', 'truncated handshake');
476
+ return {
477
+ ticketId: body.slice(1, 1 + TUNNEL_TICKET_ID_LEN),
478
+ noise: body.slice(1 + TUNNEL_TICKET_ID_LEN),
479
+ };
480
+ }
481
+ /** 握手回复(D → P)接受:`0x00` ‖ Noise 第二条。 */
482
+ export function handshakeAccept(noise) {
483
+ const out = new Uint8Array(1 + noise.length);
484
+ out[0] = TUNNEL_HANDSHAKE_ACCEPT;
485
+ out.set(noise, 1);
486
+ return out;
487
+ }
488
+ /** 握手回复拒绝:`0x01` ‖ 原因(UTF-8)。 */
489
+ export function handshakeReject(reason) {
490
+ const text = new TextEncoder().encode(reason);
491
+ const out = new Uint8Array(1 + text.length);
492
+ out[0] = TUNNEL_HANDSHAKE_REJECT;
493
+ out.set(text, 1);
494
+ return out;
495
+ }
496
+ export function parseHandshakeReply(body) {
497
+ if (body.length === 0)
498
+ throw new TunnelError('truncated', 'empty handshake reply');
499
+ if (body[0] === TUNNEL_HANDSHAKE_ACCEPT)
500
+ return { accept: true, noise: body.slice(1) };
501
+ if (body[0] === TUNNEL_HANDSHAKE_REJECT) {
502
+ try {
503
+ return {
504
+ accept: false,
505
+ reason: new TextDecoder('utf-8', { fatal: true }).decode(body.subarray(1)),
506
+ };
507
+ }
508
+ catch {
509
+ throw new TunnelError('malformed', 'reject reason');
510
+ }
511
+ }
512
+ throw new TunnelError('malformed', 'handshake reply');
513
+ }
514
+ /**
515
+ * Noise prologue:`"anycon-preview-v1" ‖ 0x00 ‖ label ‖ 0x00 ‖ ticket_id`。两端各自算:预览页取自己的主机名,
516
+ * daemon 取 `preview_peer.label`,hub 说谎只会让握手失败。
517
+ */
518
+ export function previewPrologue(label, ticketId) {
519
+ if (ticketId.length !== TUNNEL_TICKET_ID_LEN)
520
+ throw new TunnelError('malformed', 'ticket id length');
521
+ const enc = new TextEncoder();
522
+ const prefix = enc.encode(TUNNEL_PROLOGUE_PREFIX);
523
+ const text = enc.encode(label);
524
+ const out = new Uint8Array(prefix.length + 1 + text.length + 1 + TUNNEL_TICKET_ID_LEN);
525
+ out.set(prefix, 0);
526
+ let at = prefix.length;
527
+ out[at++] = 0;
528
+ out.set(text, at);
529
+ at += text.length;
530
+ out[at++] = 0;
531
+ out.set(ticketId, at);
532
+ return out;
533
+ }
534
+ /** 把 16 字节随机数编码成 label(base32 小写,无填充:128 bit → 26 个字符)。 */
535
+ export function labelFromBytes(bytes) {
536
+ if (bytes.length !== 16)
537
+ throw new TunnelError('malformed', 'label needs 16 bytes');
538
+ let out = '';
539
+ let acc = 0;
540
+ let bits = 0;
541
+ for (const b of bytes) {
542
+ acc = ((acc << 8) | b) >>> 0;
543
+ bits += 8;
544
+ while (bits >= 5) {
545
+ bits -= 5;
546
+ out += PREVIEW_LABEL_ALPHABET[(acc >>> bits) & 0x1f];
547
+ }
548
+ acc &= (1 << bits) - 1;
549
+ }
550
+ if (bits > 0)
551
+ out += PREVIEW_LABEL_ALPHABET[(acc << (5 - bits)) & 0x1f];
552
+ return out;
553
+ }
554
+ //# sourceMappingURL=preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview.js","sourceRoot":"","sources":["../src/preview.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anycon/protocol",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "TypeScript side of the Anycon protocol: generated types, envelope msgpack codec, JSON-RPC, and the Noise wasm wrapper.",
5
5
  "homepage": "https://github.com/anycon-ai/anycon/tree/main/packages/protocol#readme",
6
6
  "bugs": {
@@ -54,7 +54,7 @@
54
54
  "@msgpack/msgpack": "^3.1.3"
55
55
  },
56
56
  "devDependencies": {
57
- "@types/bun": "^1.4.2",
57
+ "@types/bun": "^1.4.4",
58
58
  "@types/node": "^24.0.0",
59
59
  "tsx": "^4.23.15",
60
60
  "typescript": "~5.9.3"
package/src/constants.ts CHANGED
@@ -44,6 +44,12 @@ export const METHODS = {
44
44
  NODE_DOCTOR: 'node.doctor',
45
45
  NODE_AUDIT: 'node.audit',
46
46
  NODE_SET_AGENT_DEFAULTS: 'node.set_agent_defaults',
47
+ /** 可以远程查看的配置项(白名单,ADR-43)。 */
48
+ NODE_GET_CONFIG: 'node.get_config',
49
+ /** 远程修改白名单里的配置项;安全相关的键只能收紧(ADR-43)。 */
50
+ NODE_SET_CONFIG: 'node.set_config',
51
+ /** daemon 日志文件的尾部。 */
52
+ NODE_LOGS: 'node.logs',
47
53
 
48
54
  // 账号内接入(ADR-36)
49
55
  /** 进行中的接入会话。 */
@@ -149,6 +155,16 @@ export const METHODS = {
149
155
  /** D→C notification,params = PermissionResolved */
150
156
  PERMISSION_RESOLVED: 'permission.resolved',
151
157
  PERMISSION_LIST: 'permission.list',
158
+
159
+ // dev server 预览(ADR-39)。隧道本身不走 JSON-RPC,见 `preview.ts`。
160
+ /** 为本机端口签发预览票据(params = PreviewOpenParams → PreviewOpenResult)。 */
161
+ PREVIEW_OPEN: 'preview.open',
162
+ /** 作废一个 label 的全部票据并断开隧道(params = PreviewCloseParams)。 */
163
+ PREVIEW_CLOSE: 'preview.close',
164
+ /** 未过期的票据(→ PreviewListResult)。 */
165
+ PREVIEW_LIST: 'preview.list',
166
+ /** 可以预览的本机端口(params = PreviewPortsParams → PreviewPortsResult)。 */
167
+ PREVIEW_PORTS: 'preview.ports',
152
168
  } as const
153
169
 
154
170
  export type MethodName = (typeof METHODS)[keyof typeof METHODS]