@naeemo/capnp 0.5.0 → 0.5.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["RpcConnection","SchemaNodeType","SchemaNodeType","SchemaFormat","SchemaNodeType","deserializeSchemaRequest","serializeSchemaResponse"],"sources":["../src/core/pointer.ts","../src/core/segment.ts","../src/core/message-builder.ts","../src/core/list.ts","../src/core/message-reader.ts","../src/core/union.ts","../src/rpc/message-serializer.ts","../src/rpc/websocket-transport.ts","../src/rpc/capability-client.ts","../src/rpc/sturdyrefs.ts","../src/rpc/performance.ts","../src/rpc/connection-manager.ts","../src/rpc/level3-handlers.ts","../src/rpc/level4-types.ts","../src/rpc/level4-handlers.ts","../src/rpc/stream.ts","../src/rpc/bulk.ts","../src/rpc/realtime.ts","../src/rpc/stream-manager.ts","../src/rpc/streaming-connection.ts","../src/rpc/dynamic-reader.ts","../src/rpc/dynamic-writer.ts","../src/rpc/schema-capability.ts"],"sourcesContent":["/**\n * Cap'n Proto 指针编解码\n * 纯 TypeScript 实现\n */\n\nexport enum PointerTag {\n STRUCT = 0,\n LIST = 1,\n FAR = 2,\n OTHER = 3,\n}\n\nexport enum ElementSize {\n VOID = 0,\n BIT = 1,\n BYTE = 2,\n TWO_BYTES = 3,\n FOUR_BYTES = 4,\n EIGHT_BYTES = 5,\n POINTER = 6,\n COMPOSITE = 7,\n INLINE_COMPOSITE = 7, // Alias for COMPOSITE\n}\n\nexport interface StructPointer {\n tag: PointerTag.STRUCT;\n offset: number; // 字偏移(有符号)\n dataWords: number; // 数据段字数\n pointerCount: number; // 指针段字数\n}\n\nexport interface ListPointer {\n tag: PointerTag.LIST;\n offset: number;\n elementSize: ElementSize;\n elementCount: number;\n}\n\nexport interface FarPointer {\n tag: PointerTag.FAR;\n doubleFar: boolean;\n targetSegment: number;\n targetOffset: number;\n}\n\nexport type Pointer = StructPointer | ListPointer | FarPointer | { tag: PointerTag.OTHER };\n\n/**\n * 解码指针(64位)\n */\nexport function decodePointer(ptr: bigint): Pointer {\n const tag = Number(ptr & BigInt(3)) as PointerTag;\n\n switch (tag) {\n case PointerTag.STRUCT: {\n const offset = Number(ptr >> BigInt(2)) & 0x3fffffff;\n const signedOffset = offset >= 0x20000000 ? offset - 0x40000000 : offset;\n const dataWords = Number((ptr >> BigInt(32)) & BigInt(0xffff));\n const pointerCount = Number((ptr >> BigInt(48)) & BigInt(0xffff));\n return { tag, offset: signedOffset, dataWords, pointerCount };\n }\n\n case PointerTag.LIST: {\n const offset = Number(ptr >> BigInt(2)) & 0x3fffffff;\n const signedOffset = offset >= 0x20000000 ? offset - 0x40000000 : offset;\n const elementSize = Number((ptr >> BigInt(32)) & BigInt(7)) as ElementSize;\n const elementCount = Number((ptr >> BigInt(35)) & BigInt(0x1fffffff));\n return { tag, offset: signedOffset, elementSize, elementCount };\n }\n\n case PointerTag.FAR: {\n const doubleFar = Boolean((ptr >> BigInt(2)) & BigInt(1));\n const targetOffset = Number((ptr >> BigInt(3)) & BigInt(0x1fffffff));\n const targetSegment = Number((ptr >> BigInt(32)) & BigInt(0xffffffff));\n return { tag, doubleFar, targetSegment, targetOffset };\n }\n\n default:\n return { tag: PointerTag.OTHER };\n }\n}\n\n/**\n * 编码 Struct 指针\n */\nexport function encodeStructPointer(\n offset: number,\n dataWords: number,\n pointerCount: number\n): bigint {\n const offsetBits = BigInt(offset < 0 ? offset + 0x40000000 : offset) & BigInt(0x3fffffff);\n return (\n (offsetBits << BigInt(2)) |\n (BigInt(dataWords) << BigInt(32)) |\n (BigInt(pointerCount) << BigInt(48))\n );\n}\n\n/**\n * 编码 List 指针\n */\nexport function encodeListPointer(\n offset: number,\n elementSize: ElementSize,\n elementCount: number\n): bigint {\n const offsetBits = BigInt(offset < 0 ? offset + 0x40000000 : offset) & BigInt(0x3fffffff);\n return (\n (offsetBits << BigInt(2)) |\n BigInt(1) | // LIST tag\n (BigInt(elementSize) << BigInt(32)) |\n (BigInt(elementCount) << BigInt(35))\n );\n}\n\n/**\n * 编码 Far 指针\n */\nexport function encodeFarPointer(segment: number, offset: number, doubleFar = false): bigint {\n const offsetBits = BigInt(offset) & BigInt(0x1fffffff);\n const segmentBits = BigInt(segment) & BigInt(0xffffffff);\n\n return (\n (segmentBits << BigInt(32)) |\n (offsetBits << BigInt(3)) |\n (doubleFar ? BigInt(1) << BigInt(2) : BigInt(0)) |\n BigInt(2)\n ); // FAR tag\n}\n","/**\n * Cap'n Proto Segment 管理\n * 纯 TypeScript 实现\n */\n\nexport const WORD_SIZE = 8;\n\nexport class Segment {\n private buffer: ArrayBuffer;\n private view: DataView;\n private _size: number; // 当前已使用字节数\n\n constructor(initialCapacity = 1024) {\n this.buffer = new ArrayBuffer(initialCapacity);\n this.view = new DataView(this.buffer);\n this._size = 0;\n }\n\n /**\n * 从现有 buffer 创建(用于读取)\n */\n static fromBuffer(buffer: ArrayBuffer): Segment {\n const seg = new Segment(0);\n seg.buffer = buffer;\n seg.view = new DataView(buffer);\n seg._size = buffer.byteLength;\n return seg;\n }\n\n /**\n * 确保容量足够\n */\n private ensureCapacity(minBytes: number): void {\n if (this.buffer.byteLength >= minBytes) return;\n\n // 双倍扩展\n let newCapacity = this.buffer.byteLength * 2;\n while (newCapacity < minBytes) {\n newCapacity *= 2;\n }\n\n const newBuffer = new ArrayBuffer(newCapacity);\n new Uint8Array(newBuffer).set(new Uint8Array(this.buffer, 0, this._size));\n this.buffer = newBuffer;\n this.view = new DataView(newBuffer);\n }\n\n /**\n * 分配空间,返回字偏移\n */\n allocate(words: number): number {\n const bytes = words * WORD_SIZE;\n const offset = this._size;\n this.ensureCapacity(offset + bytes);\n this._size = offset + bytes;\n return offset / WORD_SIZE;\n }\n\n /**\n * 获取字(64位)\n */\n getWord(wordOffset: number): bigint {\n const byteOffset = wordOffset * WORD_SIZE;\n const low = BigInt(this.view.getUint32(byteOffset, true));\n const high = BigInt(this.view.getUint32(byteOffset + 4, true));\n return (high << BigInt(32)) | low;\n }\n\n /**\n * 设置字(64位)\n */\n setWord(wordOffset: number, value: bigint): void {\n const byteOffset = wordOffset * WORD_SIZE;\n this.view.setUint32(byteOffset, Number(value & BigInt(0xffffffff)), true);\n this.view.setUint32(byteOffset + 4, Number(value >> BigInt(32)), true);\n }\n\n /**\n * 获取原始 buffer(只读到 _size)\n */\n asUint8Array(): Uint8Array {\n return new Uint8Array(this.buffer, 0, this._size);\n }\n\n /**\n * 获取底层 ArrayBuffer\n */\n getArrayBuffer(): ArrayBuffer {\n return this.buffer;\n }\n\n /**\n * 获取字数量\n */\n get wordCount(): number {\n return this._size / WORD_SIZE;\n }\n\n /**\n * 获取字节数量\n */\n get byteLength(): number {\n return this._size;\n }\n\n /**\n * 获取 DataView\n */\n get dataView(): DataView {\n return this.view;\n }\n}\n","/**\n * Cap'n Proto MessageBuilder\n * 纯 TypeScript 实现\n */\n\nimport { ListBuilder } from './list.js';\nimport { ElementSize, PointerTag, encodeListPointer, encodeStructPointer } from './pointer.js';\nimport { Segment, WORD_SIZE } from './segment.js';\n\nexport class MessageBuilder {\n private segment: Segment;\n private rootSet = false;\n\n constructor() {\n // 预留消息头空间(假设单段)\n this.segment = new Segment(1024);\n // 预留 8 字节给段大小\n this.segment.allocate(1);\n }\n\n /**\n * 初始化根结构\n */\n initRoot(dataWords: number, pointerCount: number): StructBuilder {\n if (this.rootSet) {\n throw new Error('Root already initialized');\n }\n\n // 分配根结构空间\n const size = dataWords + pointerCount;\n const structOffset = this.segment.allocate(size);\n\n // 在位置 0 写入根指针\n const rootPtr = encodeStructPointer(structOffset - 1, dataWords, pointerCount);\n this.segment.setWord(0, rootPtr);\n\n this.rootSet = true;\n\n return new StructBuilder(this, 0, structOffset, dataWords, pointerCount);\n }\n\n /**\n * 序列化为 ArrayBuffer\n */\n toArrayBuffer(): ArrayBuffer {\n const segmentData = this.segment.asUint8Array();\n const wordCount = this.segment.wordCount;\n\n // 构建消息头\n // 第一个字:段数量-1(低32位)和第一段大小(高32位)\n const header = new ArrayBuffer(8);\n const headerView = new DataView(header);\n headerView.setUint32(0, 0, true); // 段数量-1 = 0(单段)\n headerView.setUint32(4, wordCount, true); // 第一段大小\n\n // 合并头和数据\n const result = new Uint8Array(8 + segmentData.byteLength);\n result.set(new Uint8Array(header), 0);\n result.set(segmentData, 8);\n\n return result.buffer;\n }\n\n /**\n * 获取段(内部使用)\n */\n getSegment(): Segment {\n return this.segment;\n }\n}\n\n/**\n * 结构构建器\n */\nexport class StructBuilder {\n constructor(\n private message: MessageBuilder,\n private segmentIndex: number,\n private wordOffset: number,\n private dataWords: number,\n private pointerCount: number\n ) {}\n\n /**\n * 设置 bool 字段\n */\n setBool(bitOffset: number, value: boolean): void {\n const byteOffset = Math.floor(bitOffset / 8);\n const bitInByte = bitOffset % 8;\n const segment = this.message.getSegment();\n const view = segment.dataView;\n const offset = this.wordOffset * WORD_SIZE + byteOffset;\n\n const current = view.getUint8(offset);\n const newValue = value ? current | (1 << bitInByte) : current & ~(1 << bitInByte);\n view.setUint8(offset, newValue);\n }\n\n /**\n * 设置 int8 字段\n */\n setInt8(byteOffset: number, value: number): void {\n const segment = this.message.getSegment();\n segment.dataView.setInt8(this.wordOffset * WORD_SIZE + byteOffset, value);\n }\n\n /**\n * 设置 int16 字段\n */\n setInt16(byteOffset: number, value: number): void {\n const segment = this.message.getSegment();\n segment.dataView.setInt16(this.wordOffset * WORD_SIZE + byteOffset, value, true);\n }\n\n /**\n * 设置 int32 字段\n */\n setInt32(byteOffset: number, value: number): void {\n const segment = this.message.getSegment();\n segment.dataView.setInt32(this.wordOffset * WORD_SIZE + byteOffset, value, true);\n }\n\n /**\n * 设置 int64 字段\n */\n setInt64(byteOffset: number, value: bigint): void {\n const segment = this.message.getSegment();\n const offset = this.wordOffset * WORD_SIZE + byteOffset;\n segment.dataView.setUint32(offset, Number(value & BigInt(0xffffffff)), true);\n segment.dataView.setInt32(offset + 4, Number(value >> BigInt(32)), true);\n }\n\n /**\n * 设置 uint8 字段\n */\n setUint8(byteOffset: number, value: number): void {\n const segment = this.message.getSegment();\n segment.dataView.setUint8(this.wordOffset * WORD_SIZE + byteOffset, value);\n }\n\n /**\n * 设置 uint16 字段\n */\n setUint16(byteOffset: number, value: number): void {\n const segment = this.message.getSegment();\n segment.dataView.setUint16(this.wordOffset * WORD_SIZE + byteOffset, value, true);\n }\n\n /**\n * 设置 uint32 字段\n */\n setUint32(byteOffset: number, value: number): void {\n const segment = this.message.getSegment();\n segment.dataView.setUint32(this.wordOffset * WORD_SIZE + byteOffset, value, true);\n }\n\n /**\n * 设置 uint64 字段\n */\n setUint64(byteOffset: number, value: bigint): void {\n const segment = this.message.getSegment();\n const offset = this.wordOffset * WORD_SIZE + byteOffset;\n segment.dataView.setUint32(offset, Number(value & BigInt(0xffffffff)), true);\n segment.dataView.setUint32(offset + 4, Number(value >> BigInt(32)), true);\n }\n\n /**\n * 设置 float32 字段\n */\n setFloat32(byteOffset: number, value: number): void {\n const segment = this.message.getSegment();\n segment.dataView.setFloat32(this.wordOffset * WORD_SIZE + byteOffset, value, true);\n }\n\n /**\n * 设置 float64 字段\n */\n setFloat64(byteOffset: number, value: number): void {\n const segment = this.message.getSegment();\n segment.dataView.setFloat64(this.wordOffset * WORD_SIZE + byteOffset, value, true);\n }\n\n /**\n * 获取 uint16 字段(用于 UnionBuilder 读取 tag)\n */\n getUint16(byteOffset: number): number {\n const segment = this.message.getSegment();\n return segment.dataView.getUint16(this.wordOffset * WORD_SIZE + byteOffset, true);\n }\n\n /**\n * 设置文本字段\n */\n setText(pointerIndex: number, value: string): void {\n const ptrOffset = this.wordOffset + this.dataWords + pointerIndex;\n const segment = this.message.getSegment();\n\n // 编码文本\n const bytes = new TextEncoder().encode(`${value}\\0`);\n const wordCount = Math.ceil(bytes.length / WORD_SIZE);\n const listOffset = segment.allocate(wordCount);\n\n // 写入文本数据\n new Uint8Array(segment.dataView.buffer, listOffset * WORD_SIZE, bytes.length).set(bytes);\n\n // 写入指针\n const ptr = encodeListPointer(listOffset - ptrOffset - 1, ElementSize.BYTE, bytes.length);\n segment.setWord(ptrOffset, ptr);\n }\n\n /**\n * 初始化嵌套结构\n */\n initStruct(pointerIndex: number, dataWords: number, pointerCount: number): StructBuilder {\n const ptrOffset = this.wordOffset + this.dataWords + pointerIndex;\n const segment = this.message.getSegment();\n\n // 分配结构空间\n const size = dataWords + pointerCount;\n const structOffset = segment.allocate(size);\n\n // 写入指针\n const ptr = encodeStructPointer(structOffset - ptrOffset - 1, dataWords, pointerCount);\n segment.setWord(ptrOffset, ptr);\n\n return new StructBuilder(this.message, 0, structOffset, dataWords, pointerCount);\n }\n\n /**\n * 初始化列表\n */\n initList<T>(\n pointerIndex: number,\n elementSize: ElementSize,\n elementCount: number,\n structSize?: { dataWords: number; pointerCount: number }\n ): ListBuilder<T> {\n const ptrOffset = this.wordOffset + this.dataWords + pointerIndex;\n const segment = this.message.getSegment();\n\n // 计算列表大小\n let elementWords = 1;\n if (elementSize === ElementSize.BYTE) elementWords = 1;\n else if (elementSize === ElementSize.TWO_BYTES) elementWords = 1;\n else if (elementSize === ElementSize.FOUR_BYTES) elementWords = 1;\n else if (elementSize === ElementSize.EIGHT_BYTES) elementWords = 1;\n else if (elementSize === ElementSize.COMPOSITE && structSize) {\n elementWords = structSize.dataWords + structSize.pointerCount;\n }\n\n const totalWords = elementWords * elementCount;\n const listOffset = segment.allocate(totalWords);\n\n // 写入指针\n const ptr = encodeListPointer(listOffset - ptrOffset - 1, elementSize, elementCount);\n segment.setWord(ptrOffset, ptr);\n\n return new ListBuilder<T>(this.message, elementSize, elementCount, structSize, listOffset);\n }\n}\n","/**\n * Cap'n Proto List 实现\n * 纯 TypeScript\n */\n\nimport { type MessageBuilder, StructBuilder } from './message-builder.js';\nimport { type MessageReader, StructReader } from './message-reader.js';\nimport { ElementSize, type ListPointer, PointerTag, decodePointer } from './pointer.js';\nimport { type Segment, WORD_SIZE } from './segment.js';\n\n/**\n * ListReader - 读取列表\n */\nexport class ListReader<T> {\n private segment: Segment;\n private startOffset: number; // 字偏移\n private segmentIndex: number;\n\n constructor(\n private message: MessageReader,\n segmentIndex: number,\n private elementSize: ElementSize,\n private elementCount: number,\n private structSize: { dataWords: number; pointerCount: number } | undefined,\n wordOffset: number\n ) {\n this.segmentIndex = segmentIndex;\n this.segment = message.getSegment(segmentIndex)!;\n this.startOffset = wordOffset;\n }\n\n /**\n * 列表长度\n */\n get length(): number {\n return this.elementCount;\n }\n\n /**\n * 获取元素(基础类型)\n */\n getPrimitive(index: number): number | bigint {\n if (index < 0 || index >= this.elementCount) {\n throw new RangeError('Index out of bounds');\n }\n\n switch (this.elementSize) {\n case ElementSize.BIT: {\n const byteOffset = Math.floor(index / 8);\n const bitInByte = index % 8;\n const byte = this.segment.dataView.getUint8(this.startOffset * WORD_SIZE + byteOffset);\n return (byte & (1 << bitInByte)) !== 0 ? 1 : 0;\n }\n\n case ElementSize.BYTE:\n return this.segment.dataView.getUint8(this.startOffset * WORD_SIZE + index);\n\n case ElementSize.TWO_BYTES:\n return this.segment.dataView.getUint16(this.startOffset * WORD_SIZE + index * 2, true);\n\n case ElementSize.FOUR_BYTES:\n return this.segment.dataView.getUint32(this.startOffset * WORD_SIZE + index * 4, true);\n\n case ElementSize.EIGHT_BYTES: {\n const offset = this.startOffset * WORD_SIZE + index * 8;\n const low = BigInt(this.segment.dataView.getUint32(offset, true));\n const high = BigInt(this.segment.dataView.getUint32(offset + 4, true));\n return (high << BigInt(32)) | low;\n }\n\n default:\n throw new Error(`Unsupported element size: ${this.elementSize}`);\n }\n }\n\n /**\n * 获取结构元素\n */\n getStruct(index: number): StructReader {\n if (!this.structSize) {\n throw new Error('Not a struct list');\n }\n\n const { dataWords, pointerCount } = this.structSize;\n const size = dataWords + pointerCount;\n const offset = this.startOffset + index * size;\n\n return new StructReader(this.message, this.segmentIndex, offset, dataWords, pointerCount);\n }\n\n /**\n * 迭代器\n */\n *[Symbol.iterator](): Iterator<T> {\n for (let i = 0; i < this.elementCount; i++) {\n yield this.getPrimitive(i) as T;\n }\n }\n}\n\n/**\n * ListBuilder - 构建列表\n */\nexport class ListBuilder<_T> {\n private segment: Segment;\n private startOffset: number;\n\n constructor(\n private message: MessageBuilder,\n private elementSize: ElementSize,\n private elementCount: number,\n private structSize: { dataWords: number; pointerCount: number } | undefined,\n wordOffset: number\n ) {\n this.segment = message.getSegment();\n this.startOffset = wordOffset;\n }\n\n /**\n * 列表长度\n */\n get length(): number {\n return this.elementCount;\n }\n\n /**\n * 设置基础类型元素\n */\n setPrimitive(index: number, value: number | bigint): void {\n if (index < 0 || index >= this.elementCount) {\n throw new RangeError('Index out of bounds');\n }\n\n switch (this.elementSize) {\n case ElementSize.BIT: {\n const byteOffset = Math.floor(index / 8);\n const bitInByte = index % 8;\n const offset = this.startOffset * WORD_SIZE + byteOffset;\n const current = this.segment.dataView.getUint8(offset);\n const newValue = value ? current | (1 << bitInByte) : current & ~(1 << bitInByte);\n this.segment.dataView.setUint8(offset, newValue);\n break;\n }\n\n case ElementSize.BYTE:\n this.segment.dataView.setUint8(this.startOffset * WORD_SIZE + index, Number(value));\n break;\n\n case ElementSize.TWO_BYTES:\n this.segment.dataView.setUint16(\n this.startOffset * WORD_SIZE + index * 2,\n Number(value),\n true\n );\n break;\n\n case ElementSize.FOUR_BYTES:\n this.segment.dataView.setUint32(\n this.startOffset * WORD_SIZE + index * 4,\n Number(value),\n true\n );\n break;\n\n case ElementSize.EIGHT_BYTES: {\n const offset = this.startOffset * WORD_SIZE + index * 8;\n const bigValue = value as bigint;\n this.segment.dataView.setUint32(offset, Number(bigValue & BigInt(0xffffffff)), true);\n this.segment.dataView.setUint32(offset + 4, Number(bigValue >> BigInt(32)), true);\n break;\n }\n\n default:\n throw new Error(`Unsupported element size: ${this.elementSize}`);\n }\n }\n\n /**\n * 获取结构元素(用于修改)\n */\n getStruct(index: number): StructBuilder {\n if (!this.structSize) {\n throw new Error('Not a struct list');\n }\n\n const { dataWords, pointerCount } = this.structSize;\n const size = dataWords + pointerCount;\n const offset = this.startOffset + index * size;\n\n return new StructBuilder(this.message, 0, offset, dataWords, pointerCount);\n }\n}\n","/**\n * Cap'n Proto MessageReader\n * 纯 TypeScript 实现\n */\n\nimport { ListReader } from './list.js';\nimport {\n ElementSize,\n type FarPointer,\n type ListPointer,\n PointerTag,\n type StructPointer,\n decodePointer,\n} from './pointer.js';\nimport { Segment, WORD_SIZE } from './segment.js';\n\nexport class MessageReader {\n private segments: Segment[];\n\n constructor(buffer: ArrayBuffer | Uint8Array) {\n const uint8Array = buffer instanceof ArrayBuffer ? new Uint8Array(buffer) : buffer;\n\n // 初始化空段数组(用于无效消息)\n this.segments = [];\n\n // 检查最小大小(至少需要8字节的头部)\n if (uint8Array.byteLength < 8) {\n // 消息太小,视为空消息\n return;\n }\n\n // 解析消息头\n // 第一个字:段数量-1(低32位)和第一段大小(高32位)\n const view = new DataView(uint8Array.buffer, uint8Array.byteOffset, uint8Array.byteLength);\n const firstWordLow = view.getUint32(0, true);\n const firstWordHigh = view.getUint32(4, true);\n\n const segmentCount = (firstWordLow & 0xffffffff) + 1;\n const firstSegmentSize = firstWordHigh;\n\n let offset = 8;\n const segmentSizes: number[] = [firstSegmentSize];\n\n // 读取剩余段大小\n for (let i = 1; i < segmentCount; i++) {\n if (offset + 4 > uint8Array.byteLength) {\n // 消息过早结束,视为空消息\n this.segments = [];\n return;\n }\n segmentSizes.push(view.getUint32(offset, true));\n offset += 4;\n }\n\n // 对齐到 8 字节\n offset = (offset + 7) & ~7;\n\n // 检查是否有足够的空间容纳段表\n if (offset > uint8Array.byteLength) {\n this.segments = [];\n return;\n }\n\n // 创建段\n this.segments = [];\n for (const size of segmentSizes) {\n if (offset + size * WORD_SIZE > uint8Array.byteLength) {\n // 段数据不足,截断或视为空消息\n // 官方实现:返回已读取的部分\n break;\n }\n const segmentBuffer = uint8Array.slice(offset, offset + size * WORD_SIZE);\n this.segments.push(Segment.fromBuffer(segmentBuffer.buffer));\n offset += size * WORD_SIZE;\n }\n }\n\n /**\n * 获取根结构\n */\n getRoot(_dataWords: number, _pointerCount: number): StructReader {\n // root 指针在位置 0,解析它找到实际数据位置\n const segment = this.segments[0];\n const ptr = decodePointer(segment.getWord(0));\n\n if (ptr.tag === PointerTag.STRUCT) {\n const structPtr = ptr as StructPointer;\n const dataOffset = 1 + structPtr.offset; // 跳过指针本身\n return new StructReader(this, 0, dataOffset, structPtr.dataWords, structPtr.pointerCount);\n }\n\n if (ptr.tag === PointerTag.FAR) {\n // Far pointer: 指向另一个 segment 中的 landing pad\n const farPtr = ptr as FarPointer;\n const targetSegment = this.getSegment(farPtr.targetSegment);\n if (!targetSegment) {\n throw new Error(`Far pointer references non-existent segment ${farPtr.targetSegment}`);\n }\n\n if (farPtr.doubleFar) {\n // Double-far: landing pad 本身也是一个 far 指针\n // landing pad 位置: targetOffset 指向的位置\n const landingPadPtr = decodePointer(targetSegment.getWord(farPtr.targetOffset));\n if (landingPadPtr.tag !== PointerTag.FAR) {\n throw new Error('Double-far landing pad is not a far pointer');\n }\n const innerFarPtr = landingPadPtr as FarPointer;\n const finalSegment = this.getSegment(innerFarPtr.targetSegment);\n if (!finalSegment) {\n throw new Error(\n `Double-far references non-existent segment ${innerFarPtr.targetSegment}`\n );\n }\n // 实际的 struct 指针在 innerFarPtr.targetOffset\n const structPtr = decodePointer(\n finalSegment.getWord(innerFarPtr.targetOffset)\n ) as StructPointer;\n const dataOffset = innerFarPtr.targetOffset + 1 + structPtr.offset;\n return new StructReader(\n this,\n innerFarPtr.targetSegment,\n dataOffset,\n structPtr.dataWords,\n structPtr.pointerCount\n );\n }\n // Single-far: landing pad 是实际的 struct 指针\n const structPtr = decodePointer(targetSegment.getWord(farPtr.targetOffset)) as StructPointer;\n const dataOffset = farPtr.targetOffset + 1 + structPtr.offset;\n return new StructReader(\n this,\n farPtr.targetSegment,\n dataOffset,\n structPtr.dataWords,\n structPtr.pointerCount\n );\n }\n\n throw new Error(`Root pointer is not a struct or far pointer: ${ptr.tag}`);\n }\n\n /**\n * 获取段\n */\n getSegment(index: number): Segment | undefined {\n return this.segments[index];\n }\n\n /**\n * 解析指针,处理 far pointer 间接寻址\n * 返回 { segmentIndex, wordOffset, pointer },其中 pointer 是实际的 struct/list 指针\n */\n resolvePointer(\n segmentIndex: number,\n wordOffset: number\n ): { segmentIndex: number; wordOffset: number; pointer: StructPointer | ListPointer } | null {\n const segment = this.getSegment(segmentIndex);\n if (!segment) return null;\n\n const ptrValue = segment.getWord(wordOffset);\n if (ptrValue === 0n) return null;\n\n const ptr = decodePointer(ptrValue);\n\n if (ptr.tag === PointerTag.STRUCT || ptr.tag === PointerTag.LIST) {\n // 直接指针,计算目标偏移\n const targetOffset = wordOffset + 1 + ptr.offset;\n return {\n segmentIndex,\n wordOffset: targetOffset,\n pointer: ptr as StructPointer | ListPointer,\n };\n }\n\n if (ptr.tag === PointerTag.FAR) {\n const farPtr = ptr as FarPointer;\n const targetSegment = this.getSegment(farPtr.targetSegment);\n if (!targetSegment) return null;\n\n if (farPtr.doubleFar) {\n // Double-far: landing pad 指向另一个 far 指针\n const landingPadPtr = decodePointer(targetSegment.getWord(farPtr.targetOffset));\n if (landingPadPtr.tag !== PointerTag.FAR) return null;\n const innerFarPtr = landingPadPtr as FarPointer;\n const finalSegment = this.getSegment(innerFarPtr.targetSegment);\n if (!finalSegment) return null;\n const finalPtr = decodePointer(finalSegment.getWord(innerFarPtr.targetOffset));\n if (finalPtr.tag !== PointerTag.STRUCT && finalPtr.tag !== PointerTag.LIST) return null;\n const targetOffset = innerFarPtr.targetOffset + 1 + finalPtr.offset;\n return {\n segmentIndex: innerFarPtr.targetSegment,\n wordOffset: targetOffset,\n pointer: finalPtr as StructPointer | ListPointer,\n };\n }\n // Single-far: landing pad 是实际的指针\n const landingPadPtr = decodePointer(targetSegment.getWord(farPtr.targetOffset));\n if (landingPadPtr.tag !== PointerTag.STRUCT && landingPadPtr.tag !== PointerTag.LIST)\n return null;\n const targetOffset = farPtr.targetOffset + 1 + landingPadPtr.offset;\n return {\n segmentIndex: farPtr.targetSegment,\n wordOffset: targetOffset,\n pointer: landingPadPtr as StructPointer | ListPointer,\n };\n }\n\n return null;\n }\n\n /**\n * 段数量\n */\n get segmentCount(): number {\n return this.segments.length;\n }\n}\n\n/**\n * 结构读取器\n */\nexport class StructReader {\n constructor(\n private message: MessageReader,\n private segmentIndex: number,\n private wordOffset: number,\n private dataWords: number,\n private pointerCount: number\n ) {}\n\n /**\n * 获取 bool 字段\n */\n getBool(bitOffset: number): boolean {\n const byteOffset = Math.floor(bitOffset / 8);\n const bitInByte = bitOffset % 8;\n const segment = this.message.getSegment(this.segmentIndex)!;\n const byte = segment.dataView.getUint8(this.wordOffset * WORD_SIZE + byteOffset);\n return (byte & (1 << bitInByte)) !== 0;\n }\n\n /**\n * 获取 int8 字段\n */\n getInt8(byteOffset: number): number {\n const segment = this.message.getSegment(this.segmentIndex)!;\n return segment.dataView.getInt8(this.wordOffset * WORD_SIZE + byteOffset);\n }\n\n /**\n * 获取 int16 字段\n */\n getInt16(byteOffset: number): number {\n const segment = this.message.getSegment(this.segmentIndex)!;\n return segment.dataView.getInt16(this.wordOffset * WORD_SIZE + byteOffset, true);\n }\n\n /**\n * 获取 int32 字段\n */\n getInt32(byteOffset: number): number {\n const segment = this.message.getSegment(this.segmentIndex)!;\n return segment.dataView.getInt32(this.wordOffset * WORD_SIZE + byteOffset, true);\n }\n\n /**\n * 获取 int64 字段\n */\n getInt64(byteOffset: number): bigint {\n const segment = this.message.getSegment(this.segmentIndex)!;\n const offset = this.wordOffset * WORD_SIZE + byteOffset;\n const low = BigInt(segment.dataView.getUint32(offset, true));\n const high = BigInt(segment.dataView.getInt32(offset + 4, true));\n return (high << BigInt(32)) | low;\n }\n\n /**\n * 获取 uint8 字段\n */\n getUint8(byteOffset: number): number {\n const segment = this.message.getSegment(this.segmentIndex)!;\n return segment.dataView.getUint8(this.wordOffset * WORD_SIZE + byteOffset);\n }\n\n /**\n * 获取 uint16 字段\n */\n getUint16(byteOffset: number): number {\n const segment = this.message.getSegment(this.segmentIndex)!;\n return segment.dataView.getUint16(this.wordOffset * WORD_SIZE + byteOffset, true);\n }\n\n /**\n * 获取 uint32 字段\n */\n getUint32(byteOffset: number): number {\n const segment = this.message.getSegment(this.segmentIndex)!;\n return segment.dataView.getUint32(this.wordOffset * WORD_SIZE + byteOffset, true);\n }\n\n /**\n * 获取 uint64 字段\n */\n getUint64(byteOffset: number): bigint {\n const segment = this.message.getSegment(this.segmentIndex)!;\n const offset = this.wordOffset * WORD_SIZE + byteOffset;\n const low = BigInt(segment.dataView.getUint32(offset, true));\n const high = BigInt(segment.dataView.getUint32(offset + 4, true));\n return (high << BigInt(32)) | low;\n }\n\n /**\n * 获取 float32 字段\n */\n getFloat32(byteOffset: number): number {\n const segment = this.message.getSegment(this.segmentIndex)!;\n return segment.dataView.getFloat32(this.wordOffset * WORD_SIZE + byteOffset, true);\n }\n\n /**\n * 获取 float64 字段\n */\n getFloat64(byteOffset: number): number {\n const segment = this.message.getSegment(this.segmentIndex)!;\n return segment.dataView.getFloat64(this.wordOffset * WORD_SIZE + byteOffset, true);\n }\n\n /**\n * 获取文本字段\n */\n getText(pointerIndex: number): string {\n const ptrOffset = this.wordOffset + this.dataWords + pointerIndex;\n const resolved = this.message.resolvePointer(this.segmentIndex, ptrOffset);\n\n if (!resolved) return '';\n\n const { segmentIndex, wordOffset, pointer } = resolved;\n if (pointer.tag !== PointerTag.LIST) return '';\n\n const listPtr = pointer as ListPointer;\n const segment = this.message.getSegment(segmentIndex)!;\n\n // Text is stored as List(UInt8) with NUL terminator\n // elementCount includes the NUL terminator\n const byteLength = listPtr.elementCount > 0 ? listPtr.elementCount - 1 : 0;\n if (byteLength === 0) return '';\n\n // 读取文本字节\n const bytes = new Uint8Array(segment.dataView.buffer, wordOffset * WORD_SIZE, byteLength);\n return new TextDecoder().decode(bytes);\n }\n\n /**\n * 获取嵌套结构\n */\n getStruct(\n pointerIndex: number,\n _dataWords: number,\n _pointerCount: number\n ): StructReader | undefined {\n const ptrOffset = this.wordOffset + this.dataWords + pointerIndex;\n const resolved = this.message.resolvePointer(this.segmentIndex, ptrOffset);\n\n if (!resolved) return undefined;\n\n const { segmentIndex, wordOffset, pointer } = resolved;\n if (pointer.tag !== PointerTag.STRUCT) return undefined;\n\n const structPtr = pointer as StructPointer;\n\n return new StructReader(\n this.message,\n segmentIndex,\n wordOffset,\n structPtr.dataWords,\n structPtr.pointerCount\n );\n }\n\n /**\n * 获取列表\n */\n getList<T>(\n pointerIndex: number,\n _elementSize: ElementSize,\n structSize?: { dataWords: number; pointerCount: number }\n ): ListReader<T> | undefined {\n const ptrOffset = this.wordOffset + this.dataWords + pointerIndex;\n const resolved = this.message.resolvePointer(this.segmentIndex, ptrOffset);\n\n if (!resolved) return undefined;\n\n const { segmentIndex, wordOffset, pointer } = resolved;\n if (pointer.tag !== PointerTag.LIST) return undefined;\n\n const listPtr = pointer as ListPointer;\n let targetOffset = wordOffset;\n let elementCount = listPtr.elementCount;\n let actualStructSize = structSize;\n const segment = this.message.getSegment(segmentIndex)!;\n\n // For INLINE_COMPOSITE lists, read the tag word\n if (listPtr.elementSize === ElementSize.COMPOSITE) {\n const tagWord = segment.getWord(targetOffset);\n // Tag word: elementCount (32 bits) | dataWords (16 bits) | pointerCount (16 bits)\n elementCount = Number(tagWord & BigInt(0xffffffff));\n const dataWords = Number((tagWord >> BigInt(32)) & BigInt(0xffff));\n const pointerCount = Number((tagWord >> BigInt(48)) & BigInt(0xffff));\n actualStructSize = { dataWords, pointerCount };\n targetOffset += 1; // Skip tag word\n }\n\n return new ListReader<T>(\n this.message,\n segmentIndex,\n listPtr.elementSize,\n elementCount,\n actualStructSize,\n targetOffset\n );\n }\n}\n","/**\n * Cap'n Proto Union 支持\n * 纯 TypeScript 实现\n */\n\nimport { MessageBuilder, type StructBuilder } from './message-builder.js';\nimport { MessageReader, type StructReader } from './message-reader.js';\nimport { ElementSize } from './pointer.js';\n\n/**\n * UnionReader - 读取 Union 的 tag 和 variant\n */\nexport class UnionReader {\n constructor(\n private struct: StructReader,\n private tagOffset: number, // tag 的字节偏移\n private variants: Map<number, string> // tag 值 -> variant 名称\n ) {}\n\n /**\n * 获取当前激活的 variant tag\n */\n getTag(): number {\n return this.struct.getUint16(this.tagOffset);\n }\n\n /**\n * 获取当前激活的 variant 名称\n */\n getVariantName(): string | undefined {\n return this.variants.get(this.getTag());\n }\n\n /**\n * 检查是否是某个 variant\n */\n is(variantTag: number): boolean {\n return this.getTag() === variantTag;\n }\n}\n\n/**\n * UnionBuilder - 设置 Union 的 tag 和 variant\n */\nexport class UnionBuilder {\n constructor(\n private struct: StructBuilder,\n private tagOffset: number\n ) {}\n\n /**\n * 获取当前 tag\n */\n getTag(): number {\n return this.struct.getUint16(this.tagOffset);\n }\n\n /**\n * 设置 tag\n */\n setTag(tag: number): void {\n this.struct.setUint16(this.tagOffset, tag);\n }\n\n /**\n * 初始化某个 variant(自动设置 tag)\n */\n initVariant(tag: number, initFn: () => void): void {\n this.setTag(tag);\n initFn();\n }\n}\n\n/**\n * 创建 UnionReader 的工厂函数\n */\nexport function createUnionReader(\n struct: StructReader,\n tagOffset: number,\n variants: Record<number, string>\n): UnionReader {\n return new UnionReader(\n struct,\n tagOffset,\n new Map(Object.entries(variants).map(([k, v]) => [Number(k), v]))\n );\n}\n\n/**\n * 创建 UnionBuilder 的工厂函数\n */\nexport function createUnionBuilder(struct: StructBuilder, tagOffset: number): UnionBuilder {\n return new UnionBuilder(struct, tagOffset);\n}\n","/**\n * RPC Message Serialization\n *\n * Implements full serialization/deserialization of RPC messages using\n * the existing MessageBuilder/MessageReader infrastructure.\n *\n * Reference: rpc.capnp schema\n */\n\nimport { MessageBuilder, type StructBuilder } from '../core/message-builder.js';\nimport { MessageReader, type StructReader } from '../core/message-reader.js';\nimport { ElementSize } from '../core/pointer.js';\nimport type {\n Bootstrap,\n Call,\n CapDescriptor,\n Disembargo,\n Exception,\n Finish,\n MessageTarget,\n Payload,\n PromisedAnswer,\n PromisedAnswerOp,\n Provide,\n Release,\n Resolve,\n Return,\n RpcMessage,\n SendResultsTo,\n} from './rpc-types.js';\n\n// ========================================================================================\n// Constants from rpc.capnp schema\n// ========================================================================================\n\n// Message union tags\nconst MSG_UNIMPLEMENTED = 0;\nconst MSG_ABORT = 1;\nconst MSG_BOOTSTRAP = 8;\nconst MSG_CALL = 2;\nconst MSG_RETURN = 3;\nconst MSG_FINISH = 4;\nconst MSG_RESOLVE = 5;\nconst MSG_RELEASE = 6;\nconst MSG_DISEMBARGO = 13;\nconst MSG_PROVIDE = 10;\nconst MSG_ACCEPT = 11;\nconst MSG_JOIN = 12;\n\n// Return union tags\nconst RET_RESULTS = 0;\nconst RET_EXCEPTION = 1;\nconst RET_CANCELED = 2;\nconst RET_RESULTS_SENT_ELSEWHERE = 3;\nconst RET_TAKE_FROM_OTHER_QUESTION = 4;\nconst RET_ACCEPT_FROM_THIRD_PARTY = 5;\n\n// SendResultsTo union tags\nconst SEND_TO_CALLER = 0;\nconst SEND_TO_YOURSELF = 1;\nconst SEND_TO_THIRD_PARTY = 2;\n\n// MessageTarget union tags\nconst TARGET_IMPORTED_CAP = 0;\nconst TARGET_PROMISED_ANSWER = 1;\n\n// CapDescriptor union tags\nconst CAP_NONE = 0;\nconst CAP_SENDER_HOSTED = 1;\nconst CAP_SENDER_PROMISE = 2;\nconst CAP_RECEIVER_HOSTED = 3;\nconst CAP_RECEIVER_ANSWER = 4;\nconst CAP_THIRD_PARTY_HOSTED = 5;\n\n// Resolve union tags\nconst RESOLVE_CAP = 0;\nconst RESOLVE_EXCEPTION = 1;\n\n// Disembargo context union tags\nconst DISEMBARGO_SENDER_LOOPBACK = 0;\nconst DISEMBARGO_RECEIVER_LOOPBACK = 1;\nconst DISEMBARGO_ACCEPT = 2;\nconst DISEMBARGO_PROVIDE = 3;\n\n// PromisedAnswer.Op union tags\nconst OP_NOOP = 0;\nconst OP_GET_POINTER_FIELD = 1;\n\n// Exception type union tags\nconst EXC_FAILED = 0;\nconst EXC_OVERLOADED = 1;\nconst EXC_DISCONNECTED = 2;\nconst EXC_UNIMPLEMENTED = 3;\n\n// ========================================================================================\n// Serialization: RpcMessage -> Uint8Array\n// ========================================================================================\n\nexport function serializeRpcMessage(message: RpcMessage): Uint8Array {\n const builder = new MessageBuilder();\n // Message struct: 6 data words, 1 pointer\n // union + questionId/answerId/promiseId/etc + padding\n const root = builder.initRoot(6, 1);\n\n switch (message.type) {\n case 'unimplemented':\n serializeUnimplemented(root, message.message);\n break;\n case 'abort':\n serializeAbort(root, message.exception);\n break;\n case 'bootstrap':\n serializeBootstrap(root, message.bootstrap);\n break;\n case 'call':\n serializeCall(root, message.call);\n break;\n case 'return':\n serializeReturn(root, message.return);\n break;\n case 'finish':\n serializeFinish(root, message.finish);\n break;\n case 'resolve':\n serializeResolve(root, message.resolve);\n break;\n case 'release':\n serializeRelease(root, message.release);\n break;\n case 'disembargo':\n serializeDisembargo(root, message.disembargo);\n break;\n case 'provide':\n serializeProvide(root, message.provide);\n break;\n case 'accept':\n serializeAccept(root, message.accept);\n break;\n case 'join':\n serializeJoin(root, message.join);\n break;\n }\n\n return new Uint8Array(builder.toArrayBuffer());\n}\n\nfunction serializeUnimplemented(root: StructBuilder, message: RpcMessage): void {\n // Set union tag\n root.setUint16(0, MSG_UNIMPLEMENTED);\n // Serialize nested message in pointer 0\n const _nestedData = serializeRpcMessage(message);\n const nestedBuilder = root.initStruct(0, 0, 1);\n // Copy nested data into the struct's content pointer\n // For simplicity, we store the serialized message as data bytes\n // In a full implementation, we'd properly embed the message structure\n const _contentPtr = nestedBuilder.initStruct(0, 0, 0);\n // Store length and data\n // This is a simplified approach - proper implementation would parse the nested message\n}\n\nfunction serializeAbort(root: StructBuilder, exception: Exception): void {\n root.setUint16(0, MSG_ABORT);\n serializeException(root, 0, exception);\n}\n\nfunction serializeBootstrap(root: StructBuilder, bootstrap: Bootstrap): void {\n root.setUint16(0, MSG_BOOTSTRAP);\n root.setUint32(8, bootstrap.questionId);\n // deprecatedObjectId is deprecated, skip\n}\n\nfunction serializeCall(root: StructBuilder, call: Call): void {\n root.setUint16(0, MSG_CALL);\n root.setUint32(8, call.questionId);\n root.setUint64(16, call.interfaceId);\n root.setUint16(24, call.methodId);\n root.setBool(208, call.allowThirdPartyTailCall); // bit 208 = word 26, bit 0\n root.setBool(209, call.noPromisePipelining); // bit 209\n root.setBool(210, call.onlyPromisePipeline); // bit 210\n\n // Serialize target in pointer 0\n serializeMessageTarget(root.initStruct(0, 2, 1), call.target);\n\n // Serialize params in pointer 1\n serializePayload(root.initStruct(1, 2, 2), call.params);\n\n // Serialize sendResultsTo in pointer 2\n serializeSendResultsTo(root.initStruct(2, 2, 1), call.sendResultsTo);\n}\n\nfunction serializeReturn(root: StructBuilder, ret: Return): void {\n root.setUint16(0, MSG_RETURN);\n root.setUint32(8, ret.answerId);\n root.setBool(192, ret.releaseParamCaps); // bit 192 = word 24, bit 0\n root.setBool(193, ret.noFinishNeeded); // bit 193\n\n // Serialize result based on type\n switch (ret.result.type) {\n case 'results':\n root.setUint16(2, RET_RESULTS);\n serializePayload(root.initStruct(0, 2, 2), ret.result.payload);\n break;\n case 'exception':\n root.setUint16(2, RET_EXCEPTION);\n serializeException(root, 0, ret.result.exception);\n break;\n case 'canceled':\n root.setUint16(2, RET_CANCELED);\n break;\n case 'resultsSentElsewhere':\n root.setUint16(2, RET_RESULTS_SENT_ELSEWHERE);\n break;\n case 'takeFromOtherQuestion':\n root.setUint16(2, RET_TAKE_FROM_OTHER_QUESTION);\n root.setUint32(12, ret.result.questionId);\n break;\n case 'acceptFromThirdParty':\n root.setUint16(2, RET_ACCEPT_FROM_THIRD_PARTY);\n // ThirdPartyCapId in pointer 0\n break;\n }\n}\n\nfunction serializeFinish(root: StructBuilder, finish: Finish): void {\n root.setUint16(0, MSG_FINISH);\n root.setUint32(8, finish.questionId);\n root.setBool(192, finish.releaseResultCaps); // bit 192\n root.setBool(193, finish.requireEarlyCancellationWorkaround); // bit 193\n}\n\nfunction serializeResolve(root: StructBuilder, resolve: Resolve): void {\n root.setUint16(0, MSG_RESOLVE);\n root.setUint32(8, resolve.promiseId);\n\n switch (resolve.resolution.type) {\n case 'cap':\n root.setUint16(2, RESOLVE_CAP);\n serializeCapDescriptor(root.initStruct(0, 2, 1), resolve.resolution.cap);\n break;\n case 'exception':\n root.setUint16(2, RESOLVE_EXCEPTION);\n serializeException(root, 0, resolve.resolution.exception);\n break;\n }\n}\n\nfunction serializeRelease(root: StructBuilder, release: Release): void {\n root.setUint16(0, MSG_RELEASE);\n root.setUint32(8, release.id);\n root.setUint32(12, release.referenceCount);\n}\n\nfunction serializeDisembargo(root: StructBuilder, disembargo: Disembargo): void {\n root.setUint16(0, MSG_DISEMBARGO);\n serializeMessageTarget(root.initStruct(0, 2, 1), disembargo.target);\n\n switch (disembargo.context.type) {\n case 'senderLoopback':\n root.setUint16(2, DISEMBARGO_SENDER_LOOPBACK);\n root.setUint32(12, disembargo.context.embargoId);\n break;\n case 'receiverLoopback':\n root.setUint16(2, DISEMBARGO_RECEIVER_LOOPBACK);\n root.setUint32(12, disembargo.context.embargoId);\n break;\n case 'accept':\n root.setUint16(2, DISEMBARGO_ACCEPT);\n break;\n case 'provide':\n root.setUint16(2, DISEMBARGO_PROVIDE);\n root.setUint32(12, disembargo.context.questionId);\n break;\n }\n}\n\nfunction serializeProvide(root: StructBuilder, provide: Provide): void {\n root.setUint16(0, MSG_PROVIDE);\n root.setUint32(8, provide.questionId);\n serializeMessageTarget(root.initStruct(0, 2, 1), provide.target);\n // RecipientId in pointer 1 - placeholder\n}\n\nfunction serializeAccept(\n _root: StructBuilder,\n _accept: { provision: { id: Uint8Array }; embargo: boolean }\n): void {\n // Level 3 - not fully implemented\n}\n\nfunction serializeJoin(\n _root: StructBuilder,\n _join: { otherCap: MessageTarget; joinId: number }\n): void {\n // Level 4 - not fully implemented\n}\n\n// ========================================================================================\n// Supporting Type Serialization\n// ========================================================================================\n\nfunction serializeMessageTarget(builder: StructBuilder, target: MessageTarget): void {\n switch (target.type) {\n case 'importedCap':\n builder.setUint16(0, TARGET_IMPORTED_CAP);\n builder.setUint32(8, target.importId);\n break;\n case 'promisedAnswer':\n builder.setUint16(0, TARGET_PROMISED_ANSWER);\n serializePromisedAnswer(builder.initStruct(0, 2, 1), target.promisedAnswer);\n break;\n }\n}\n\nfunction serializePromisedAnswer(builder: StructBuilder, promisedAnswer: PromisedAnswer): void {\n builder.setUint32(0, promisedAnswer.questionId);\n // Transform list in pointer 0\n if (promisedAnswer.transform.length > 0) {\n const listBuilder = builder.initList(\n 0,\n ElementSize.INLINE_COMPOSITE,\n promisedAnswer.transform.length,\n {\n dataWords: 2,\n pointerCount: 0,\n }\n );\n for (let i = 0; i < promisedAnswer.transform.length; i++) {\n serializePromisedAnswerOp(listBuilder.getStruct(i), promisedAnswer.transform[i]);\n }\n }\n}\n\nfunction serializePromisedAnswerOp(builder: StructBuilder, op: PromisedAnswerOp): void {\n switch (op.type) {\n case 'noop':\n builder.setUint16(0, OP_NOOP);\n break;\n case 'getPointerField':\n builder.setUint16(0, OP_GET_POINTER_FIELD);\n builder.setUint16(8, op.fieldIndex);\n break;\n }\n}\n\nfunction serializePayload(builder: StructBuilder, payload: Payload): void {\n // Content (AnyPointer) - store as data bytes in pointer 0\n if (payload.content.length > 0) {\n // For now, store raw bytes - in full implementation this would be a proper struct\n const _contentBuilder = builder.initStruct(0, Math.ceil(payload.content.length / 8), 0);\n // Copy bytes into the struct\n }\n\n // Cap table list in pointer 1\n if (payload.capTable.length > 0) {\n const listBuilder = builder.initList(1, ElementSize.EIGHT_BYTES, payload.capTable.length, {\n dataWords: 2,\n pointerCount: 1,\n });\n for (let i = 0; i < payload.capTable.length; i++) {\n serializeCapDescriptor(listBuilder.getStruct(i), payload.capTable[i]);\n }\n }\n}\n\nfunction serializeCapDescriptor(builder: StructBuilder, cap: CapDescriptor): void {\n switch (cap.type) {\n case 'none':\n builder.setUint16(0, CAP_NONE);\n break;\n case 'senderHosted':\n builder.setUint16(0, CAP_SENDER_HOSTED);\n builder.setUint32(8, cap.exportId);\n break;\n case 'senderPromise':\n builder.setUint16(0, CAP_SENDER_PROMISE);\n builder.setUint32(8, cap.exportId);\n break;\n case 'receiverHosted':\n builder.setUint16(0, CAP_RECEIVER_HOSTED);\n builder.setUint32(8, cap.importId);\n break;\n case 'receiverAnswer':\n builder.setUint16(0, CAP_RECEIVER_ANSWER);\n serializePromisedAnswer(builder.initStruct(0, 2, 1), cap.promisedAnswer);\n break;\n case 'thirdPartyHosted':\n builder.setUint16(0, CAP_THIRD_PARTY_HOSTED);\n // ThirdPartyCapId in pointer 0\n break;\n }\n}\n\nfunction serializeSendResultsTo(builder: StructBuilder, sendTo: SendResultsTo): void {\n switch (sendTo.type) {\n case 'caller':\n builder.setUint16(0, SEND_TO_CALLER);\n break;\n case 'yourself':\n builder.setUint16(0, SEND_TO_YOURSELF);\n break;\n case 'thirdParty':\n builder.setUint16(0, SEND_TO_THIRD_PARTY);\n // RecipientId in pointer 0\n break;\n }\n}\n\nfunction serializeException(\n builder: StructBuilder,\n pointerIndex: number,\n exception: Exception\n): void {\n const excBuilder = builder.initStruct(pointerIndex, 2, 1);\n excBuilder.setText(0, exception.reason);\n\n // Exception type union\n switch (exception.type) {\n case 'failed':\n excBuilder.setUint16(0, EXC_FAILED);\n break;\n case 'overloaded':\n excBuilder.setUint16(0, EXC_OVERLOADED);\n break;\n case 'disconnected':\n excBuilder.setUint16(0, EXC_DISCONNECTED);\n break;\n case 'unimplemented':\n excBuilder.setUint16(0, EXC_UNIMPLEMENTED);\n break;\n }\n}\n\n// ========================================================================================\n// Deserialization: Uint8Array -> RpcMessage\n// ========================================================================================\n\nexport function deserializeRpcMessage(data: Uint8Array): RpcMessage {\n const reader = new MessageReader(data);\n const root = reader.getRoot(6, 1);\n\n const unionTag = root.getUint16(0);\n\n switch (unionTag) {\n case MSG_UNIMPLEMENTED:\n return { type: 'unimplemented', message: deserializeUnimplemented(root) };\n case MSG_ABORT:\n return { type: 'abort', exception: deserializeException(root, 0) };\n case MSG_BOOTSTRAP:\n return { type: 'bootstrap', bootstrap: deserializeBootstrap(root) };\n case MSG_CALL:\n return { type: 'call', call: deserializeCall(root) };\n case MSG_RETURN:\n return { type: 'return', return: deserializeReturn(root) };\n case MSG_FINISH:\n return { type: 'finish', finish: deserializeFinish(root) };\n case MSG_RESOLVE:\n return { type: 'resolve', resolve: deserializeResolve(root) };\n case MSG_RELEASE:\n return { type: 'release', release: deserializeRelease(root) };\n case MSG_DISEMBARGO:\n return { type: 'disembargo', disembargo: deserializeDisembargo(root) };\n case MSG_PROVIDE:\n return { type: 'provide', provide: deserializeProvide(root) };\n case MSG_ACCEPT:\n return { type: 'accept', accept: deserializeAccept(root) };\n case MSG_JOIN:\n return { type: 'join', join: deserializeJoin(root) };\n default:\n throw new Error(`Unknown message union tag: ${unionTag}`);\n }\n}\n\nfunction deserializeUnimplemented(_root: StructReader): RpcMessage {\n // For now, return a placeholder - full implementation would deserialize nested message\n return {\n type: 'abort',\n exception: { reason: 'Unimplemented message received', type: 'unimplemented' },\n };\n}\n\nfunction deserializeBootstrap(root: StructReader): Bootstrap {\n return {\n questionId: root.getUint32(8),\n };\n}\n\nfunction deserializeCall(root: StructReader): Call {\n const targetStruct = root.getStruct(0, 2, 1);\n const paramsStruct = root.getStruct(1, 2, 2);\n const sendToStruct = root.getStruct(2, 2, 1);\n\n return {\n questionId: root.getUint32(8),\n interfaceId: root.getUint64(16),\n methodId: root.getUint16(24),\n allowThirdPartyTailCall: root.getBool(208),\n noPromisePipelining: root.getBool(209),\n onlyPromisePipeline: root.getBool(210),\n target: targetStruct\n ? deserializeMessageTarget(targetStruct)\n : { type: 'importedCap', importId: 0 },\n params: paramsStruct\n ? deserializePayload(paramsStruct)\n : { content: new Uint8Array(0), capTable: [] },\n sendResultsTo: sendToStruct ? deserializeSendResultsTo(sendToStruct) : { type: 'caller' },\n };\n}\n\nfunction deserializeReturn(root: StructReader): Return {\n const resultTag = root.getUint16(2);\n let result: Return['result'];\n\n switch (resultTag) {\n case RET_RESULTS:\n result = {\n type: 'results',\n payload: root.getStruct(0, 2, 2)\n ? deserializePayload(root.getStruct(0, 2, 2)!)\n : { content: new Uint8Array(0), capTable: [] },\n };\n break;\n case RET_EXCEPTION:\n result = { type: 'exception', exception: deserializeException(root, 0) };\n break;\n case RET_CANCELED:\n result = { type: 'canceled' };\n break;\n case RET_RESULTS_SENT_ELSEWHERE:\n result = { type: 'resultsSentElsewhere' };\n break;\n case RET_TAKE_FROM_OTHER_QUESTION:\n result = { type: 'takeFromOtherQuestion', questionId: root.getUint32(12) };\n break;\n case RET_ACCEPT_FROM_THIRD_PARTY:\n result = { type: 'acceptFromThirdParty', thirdPartyCapId: { id: new Uint8Array(0) } };\n break;\n default:\n result = { type: 'canceled' };\n }\n\n return {\n answerId: root.getUint32(8),\n releaseParamCaps: root.getBool(192),\n noFinishNeeded: root.getBool(193),\n result,\n };\n}\n\nfunction deserializeFinish(root: StructReader): Finish {\n return {\n questionId: root.getUint32(8),\n releaseResultCaps: root.getBool(192),\n requireEarlyCancellationWorkaround: root.getBool(193),\n };\n}\n\nfunction deserializeResolve(root: StructReader): Resolve {\n const resolutionTag = root.getUint16(2);\n let resolution: Resolve['resolution'];\n\n switch (resolutionTag) {\n case RESOLVE_CAP:\n resolution = {\n type: 'cap',\n cap: root.getStruct(0, 2, 1)\n ? deserializeCapDescriptor(root.getStruct(0, 2, 1)!)\n : { type: 'none' },\n };\n break;\n case RESOLVE_EXCEPTION:\n resolution = { type: 'exception', exception: deserializeException(root, 0) };\n break;\n default:\n resolution = {\n type: 'exception',\n exception: { reason: 'Unknown resolution type', type: 'failed' },\n };\n }\n\n return {\n promiseId: root.getUint32(8),\n resolution,\n };\n}\n\nfunction deserializeRelease(root: StructReader): Release {\n return {\n id: root.getUint32(8),\n referenceCount: root.getUint32(12),\n };\n}\n\nfunction deserializeDisembargo(root: StructReader): Disembargo {\n const targetStruct = root.getStruct(0, 2, 1);\n const contextTag = root.getUint16(2);\n let context: Disembargo['context'];\n\n switch (contextTag) {\n case DISEMBARGO_SENDER_LOOPBACK:\n context = { type: 'senderLoopback', embargoId: root.getUint32(12) };\n break;\n case DISEMBARGO_RECEIVER_LOOPBACK:\n context = { type: 'receiverLoopback', embargoId: root.getUint32(12) };\n break;\n case DISEMBARGO_ACCEPT:\n context = { type: 'accept' };\n break;\n case DISEMBARGO_PROVIDE:\n context = { type: 'provide', questionId: root.getUint32(12) };\n break;\n default:\n context = { type: 'accept' };\n }\n\n return {\n target: targetStruct\n ? deserializeMessageTarget(targetStruct)\n : { type: 'importedCap', importId: 0 },\n context,\n };\n}\n\nfunction deserializeProvide(root: StructReader): Provide {\n const targetStruct = root.getStruct(0, 2, 1);\n return {\n questionId: root.getUint32(8),\n target: targetStruct\n ? deserializeMessageTarget(targetStruct)\n : { type: 'importedCap', importId: 0 },\n recipient: { id: new Uint8Array(0) },\n };\n}\n\nfunction deserializeAccept(_root: StructReader): {\n questionId: number;\n provision: { id: Uint8Array };\n embargo: boolean;\n} {\n // Level 3 - placeholder\n return { questionId: 0, provision: { id: new Uint8Array(0) }, embargo: false };\n}\n\nfunction deserializeJoin(_root: StructReader): {\n questionId: number;\n target: MessageTarget;\n otherCap: MessageTarget;\n joinId: number;\n} {\n // Level 4 - placeholder\n return {\n questionId: 0,\n target: { type: 'importedCap', importId: 0 },\n otherCap: { type: 'importedCap', importId: 0 },\n joinId: 0,\n };\n}\n\n// ========================================================================================\n// Supporting Type Deserialization\n// ========================================================================================\n\nfunction deserializeMessageTarget(root: StructReader): MessageTarget {\n const tag = root.getUint16(0);\n\n switch (tag) {\n case TARGET_IMPORTED_CAP:\n return { type: 'importedCap', importId: root.getUint32(8) };\n case TARGET_PROMISED_ANSWER: {\n const promisedAnswerStruct = root.getStruct(0, 2, 1);\n return {\n type: 'promisedAnswer',\n promisedAnswer: promisedAnswerStruct\n ? deserializePromisedAnswer(promisedAnswerStruct)\n : { questionId: 0, transform: [] },\n };\n }\n default:\n return { type: 'importedCap', importId: 0 };\n }\n}\n\nfunction deserializePromisedAnswer(root: StructReader): PromisedAnswer {\n const transformList = root.getList<StructReader>(0, ElementSize.INLINE_COMPOSITE, {\n dataWords: 2,\n pointerCount: 0,\n });\n const transform: PromisedAnswerOp[] = [];\n\n if (transformList) {\n for (let i = 0; i < transformList.length; i++) {\n transform.push(deserializePromisedAnswerOp(transformList.getStruct(i)));\n }\n }\n\n return {\n questionId: root.getUint32(0),\n transform,\n };\n}\n\nfunction deserializePromisedAnswerOp(root: StructReader): PromisedAnswerOp {\n const tag = root.getUint16(0);\n\n switch (tag) {\n case OP_NOOP:\n return { type: 'noop' };\n case OP_GET_POINTER_FIELD:\n return { type: 'getPointerField', fieldIndex: root.getUint16(8) };\n default:\n return { type: 'noop' };\n }\n}\n\nfunction deserializePayload(root: StructReader): Payload {\n // Content - for now, return empty\n // In full implementation, would deserialize the AnyPointer content\n const capTableList = root.getList<StructReader>(1, ElementSize.EIGHT_BYTES, {\n dataWords: 2,\n pointerCount: 1,\n });\n const capTable: CapDescriptor[] = [];\n\n if (capTableList) {\n for (let i = 0; i < capTableList.length; i++) {\n capTable.push(deserializeCapDescriptor(capTableList.getStruct(i)));\n }\n }\n\n return {\n content: new Uint8Array(0),\n capTable,\n };\n}\n\nfunction deserializeCapDescriptor(root: StructReader): CapDescriptor {\n const tag = root.getUint16(0);\n\n switch (tag) {\n case CAP_NONE:\n return { type: 'none' };\n case CAP_SENDER_HOSTED:\n return { type: 'senderHosted', exportId: root.getUint32(8) };\n case CAP_SENDER_PROMISE:\n return { type: 'senderPromise', exportId: root.getUint32(8) };\n case CAP_RECEIVER_HOSTED:\n return { type: 'receiverHosted', importId: root.getUint32(8) };\n case CAP_RECEIVER_ANSWER: {\n const promisedAnswerStruct = root.getStruct(0, 2, 1);\n return {\n type: 'receiverAnswer',\n promisedAnswer: promisedAnswerStruct\n ? deserializePromisedAnswer(promisedAnswerStruct)\n : { questionId: 0, transform: [] },\n };\n }\n case CAP_THIRD_PARTY_HOSTED:\n return { type: 'thirdPartyHosted', thirdPartyCapId: { id: new Uint8Array(0) } };\n default:\n return { type: 'none' };\n }\n}\n\nfunction deserializeSendResultsTo(root: StructReader): SendResultsTo {\n const tag = root.getUint16(0);\n\n switch (tag) {\n case SEND_TO_CALLER:\n return { type: 'caller' };\n case SEND_TO_YOURSELF:\n return { type: 'yourself' };\n case SEND_TO_THIRD_PARTY:\n return { type: 'thirdParty', recipientId: { id: new Uint8Array(0) } };\n default:\n return { type: 'caller' };\n }\n}\n\nfunction deserializeException(root: StructReader, pointerIndex: number): Exception {\n const excStruct = root.getStruct(pointerIndex, 2, 1);\n if (!excStruct) {\n return { reason: 'Unknown error', type: 'failed' };\n }\n\n const typeTag = excStruct.getUint16(0);\n let type: Exception['type'];\n\n switch (typeTag) {\n case EXC_FAILED:\n type = 'failed';\n break;\n case EXC_OVERLOADED:\n type = 'overloaded';\n break;\n case EXC_DISCONNECTED:\n type = 'disconnected';\n break;\n case EXC_UNIMPLEMENTED:\n type = 'unimplemented';\n break;\n default:\n type = 'failed';\n }\n\n return {\n reason: excStruct.getText(0),\n type,\n };\n}\n","/**\n * WebSocket Transport Implementation\n *\n * Implements RpcTransport over WebSocket for browser and Node.js compatibility.\n */\n\nimport { deserializeRpcMessage, serializeRpcMessage } from './message-serializer.js';\nimport type { RpcMessage } from './rpc-types.js';\nimport type { RpcTransport, WebSocketTransportOptions } from './transport.js';\n\n// Message framing: length-prefixed binary messages\n// Format: [4 bytes: message length (little-endian)] [N bytes: message data]\n\nexport class WebSocketTransport implements RpcTransport {\n private ws: WebSocket | null = null;\n private messageQueue: RpcMessage[] = [];\n private receiveQueue: Array<{\n resolve: (msg: RpcMessage | null) => void;\n reject: (err: Error) => void;\n }> = [];\n private _connected = false;\n private pendingBuffer: Uint8Array | null = null;\n private pendingLength = 0;\n\n onClose?: (reason?: Error) => void;\n onError?: (error: Error) => void;\n\n constructor(\n url: string,\n private options: WebSocketTransportOptions = {}\n ) {\n this.connect(url);\n }\n\n static async connect(\n url: string,\n options?: WebSocketTransportOptions\n ): Promise<WebSocketTransport> {\n const transport = new WebSocketTransport(url, options);\n await transport.waitForConnection();\n return transport;\n }\n\n static fromWebSocket(ws: WebSocket, options?: WebSocketTransportOptions): WebSocketTransport {\n const transport = new WebSocketTransport('internal', options);\n transport.attachWebSocket(ws);\n return transport;\n }\n\n get connected(): boolean {\n return this._connected;\n }\n\n private connect(url: string): void {\n this.ws = new WebSocket(url);\n this.ws.binaryType = this.options.binaryType ?? 'arraybuffer';\n\n this.ws.onopen = () => {\n this._connected = true;\n };\n\n this.ws.onmessage = (event) => {\n this.handleMessage(event.data);\n };\n\n this.ws.onclose = () => {\n this._connected = false;\n this.flushReceiveQueue(null);\n this.onClose?.();\n };\n\n this.ws.onerror = (_error) => {\n const err = new Error('WebSocket error');\n this.onError?.(err);\n };\n }\n\n private attachWebSocket(ws: WebSocket): void {\n this.ws = ws;\n this.ws.binaryType = this.options.binaryType ?? 'arraybuffer';\n this._connected = ws.readyState === WebSocket.OPEN;\n\n this.ws.onmessage = (event) => {\n this.handleMessage(event.data);\n };\n\n this.ws.onclose = () => {\n this._connected = false;\n this.flushReceiveQueue(null);\n this.onClose?.();\n };\n\n this.ws.onerror = (_error) => {\n const err = new Error('WebSocket error');\n this.onError?.(err);\n };\n }\n\n private waitForConnection(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (this._connected) {\n resolve();\n return;\n }\n\n const timeout = setTimeout(() => {\n reject(new Error('Connection timeout'));\n }, this.options.connectTimeoutMs ?? 10000);\n\n const checkConnection = () => {\n if (this._connected) {\n clearTimeout(timeout);\n resolve();\n } else if (!this.ws || this.ws.readyState === WebSocket.CLOSED) {\n clearTimeout(timeout);\n reject(new Error('Connection failed'));\n } else {\n setTimeout(checkConnection, 10);\n }\n };\n\n checkConnection();\n });\n }\n\n private handleMessage(data: ArrayBuffer | Blob): void {\n // For Phase 1, we'll implement basic message handling\n // Full implementation would parse the Cap'n Proto message\n if (data instanceof ArrayBuffer) {\n this.processBinaryMessage(new Uint8Array(data));\n } else {\n // Blob handling for browser compatibility\n const reader = new FileReader();\n reader.onload = () => {\n this.processBinaryMessage(new Uint8Array(reader.result as ArrayBuffer));\n };\n reader.readAsArrayBuffer(data);\n }\n }\n\n private processBinaryMessage(data: Uint8Array): void {\n // Length-prefixed framing\n let offset = 0;\n\n while (offset < data.length) {\n if (this.pendingBuffer === null) {\n // Start of new message\n if (offset + 4 > data.length) {\n // Not enough data for length header\n this.pendingBuffer = data.slice(offset);\n this.pendingLength = -1;\n break;\n }\n\n const length = new DataView(data.buffer, data.byteOffset + offset, 4).getUint32(0, true);\n offset += 4;\n\n if (offset + length > data.length) {\n // Not enough data for full message\n this.pendingBuffer = data.slice(offset - 4);\n this.pendingLength = length;\n break;\n }\n\n const messageData = data.slice(offset, offset + length);\n offset += length;\n this.handleRpcMessage(messageData);\n } else {\n // Continuation of pending message\n if (this.pendingLength === -1) {\n // Still need length header\n const needed = 4 - this.pendingBuffer.length;\n if (data.length - offset < needed) {\n this.pendingBuffer = new Uint8Array([...this.pendingBuffer, ...data.slice(offset)]);\n break;\n }\n\n const tempBuffer = new Uint8Array(this.pendingBuffer.length + needed);\n tempBuffer.set(this.pendingBuffer);\n tempBuffer.set(data.slice(offset, offset + needed), this.pendingBuffer.length);\n\n this.pendingLength = new DataView(tempBuffer.buffer, 0, 4).getUint32(0, true);\n this.pendingBuffer = null;\n offset += needed;\n } else {\n // Have length, need message body\n const needed = this.pendingLength - this.pendingBuffer.length;\n if (data.length - offset < needed) {\n this.pendingBuffer = new Uint8Array([...this.pendingBuffer, ...data.slice(offset)]);\n break;\n }\n\n const messageData = new Uint8Array(this.pendingLength);\n messageData.set(this.pendingBuffer);\n messageData.set(data.slice(offset, offset + needed), this.pendingBuffer.length);\n\n offset += needed;\n this.pendingBuffer = null;\n this.handleRpcMessage(messageData);\n }\n }\n }\n }\n\n private handleRpcMessage(data: Uint8Array): void {\n // Parse the RPC message from binary data\n // For Phase 1, this is a placeholder - full implementation would deserialize\n const message = this.deserializeMessage(data);\n\n // Fulfill pending receive\n if (this.receiveQueue.length > 0) {\n const { resolve } = this.receiveQueue.shift()!;\n resolve(message);\n } else {\n this.messageQueue.push(message);\n }\n }\n\n private deserializeMessage(data: Uint8Array): RpcMessage {\n return deserializeRpcMessage(data);\n }\n\n private serializeMessage(message: RpcMessage): Uint8Array {\n return serializeRpcMessage(message);\n }\n\n async send(message: RpcMessage): Promise<void> {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n throw new Error('WebSocket not connected');\n }\n\n const data = this.serializeMessage(message);\n const frame = new Uint8Array(4 + data.length);\n new DataView(frame.buffer).setUint32(0, data.length, true);\n frame.set(data, 4);\n\n this.ws.send(frame);\n }\n\n async receive(): Promise<RpcMessage | null> {\n // Check queued messages first\n if (this.messageQueue.length > 0) {\n return this.messageQueue.shift()!;\n }\n\n // If closed, return null\n if (!this._connected) {\n return null;\n }\n\n // Wait for next message\n return new Promise((resolve, reject) => {\n this.receiveQueue.push({ resolve, reject });\n });\n }\n\n close(reason?: Error): void {\n this._connected = false;\n this.ws?.close();\n this.flushReceiveQueue(null);\n this.onClose?.(reason);\n }\n\n private flushReceiveQueue(value: RpcMessage | null): void {\n while (this.receiveQueue.length > 0) {\n const { resolve } = this.receiveQueue.shift()!;\n resolve(value);\n }\n }\n}\n","/**\n * CapabilityClient\n *\n * Base class for client-side capability references.\n * Provides the foundation for making method calls on remote objects.\n */\n\nimport type { PipelineClient } from './pipeline.js';\nimport type { RpcConnection } from './rpc-connection.js';\nimport type { ImportId, InterfaceId, MethodId, Payload } from './rpc-types.js';\n\n/** Base interface for all capability clients */\nexport interface CapabilityClient {\n /** The connection this capability belongs to */\n readonly connection: RpcConnection;\n\n /** The import ID for this capability (if imported) */\n readonly importId?: ImportId;\n\n /** Check if this capability is still valid */\n isValid(): boolean;\n\n /** Release this capability reference */\n release(): void;\n}\n\n/** Base class for capability client implementations */\nexport abstract class BaseCapabilityClient implements CapabilityClient {\n constructor(\n public readonly connection: RpcConnection,\n public readonly importId?: ImportId\n ) {}\n\n isValid(): boolean {\n // In full implementation, check if the import is still valid\n return true;\n }\n\n release(): void {\n if (this.importId !== undefined) {\n this.connection.release(this.importId, 1);\n }\n }\n\n /** Make a method call on this capability and return a PipelineClient */\n protected _call(_interfaceId: InterfaceId, _methodId: MethodId, params: unknown): PipelineClient {\n if (!this.importId) {\n throw new Error('Cannot call method on capability without import ID');\n }\n\n // Serialize params to Payload\n const _payload = this.serializeParams(params);\n\n // Use callPipelined to get a PipelineClient\n // Note: callPipelined returns Promise<PipelineClient>, but we need to await it\n // This is a design issue - for now, we throw an error indicating async is needed\n throw new Error('Use _callAsync instead for async call support');\n }\n\n /** Make an async method call on this capability */\n protected async _callAsync(\n interfaceId: InterfaceId,\n methodId: MethodId,\n params: unknown\n ): Promise<PipelineClient> {\n if (!this.importId) {\n throw new Error('Cannot call method on capability without import ID');\n }\n\n // Serialize params to Payload\n const payload = this.serializeParams(params);\n\n // Use callPipelined to get a PipelineClient\n return this.connection.callPipelined(this.importId, interfaceId, methodId, payload);\n }\n\n /** Serialize parameters to Payload */\n protected serializeParams(_params: unknown): Payload {\n // TODO: Implement proper parameter serialization\n // For now, return empty payload\n return {\n content: new Uint8Array(),\n capTable: [],\n };\n }\n}\n\n/** Factory for creating capability clients */\nexport interface CapabilityClientFactory<T extends CapabilityClient> {\n create(connection: RpcConnection, importId?: ImportId): T;\n}\n","/**\n * SturdyRefs - Level 2 RPC Feature\n *\n * SturdyRefs provide persistent capability references that survive\n * connection disconnections and can be restored on reconnection.\n *\n * Key concepts:\n * - SturdyRef: A persistent reference to a capability\n * - Restore: Reconnect to a capability using its SturdyRef\n * - Save: Create a SturdyRef from a live capability\n */\n\nimport type { RpcConnection } from './rpc-connection.js';\nimport type { ExportId, ImportId, QuestionId, RpcMessage } from './rpc-types.js';\n\n// ========================================================================================\n// Types\n// ========================================================================================\n\n/**\n * A SturdyRef token that can be persisted and later used to restore a capability\n */\nexport interface SturdyRef {\n /** The vat ID where the capability lives */\n vatId: string;\n /** The local ID of the capability within that vat */\n localId: string;\n /** Optional: Version or generation number for validation */\n version?: number;\n /** Optional: Expiration timestamp */\n expiresAt?: number;\n /** Optional: Additional metadata */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * A stored SturdyRef with its associated capability info\n */\ninterface StoredSturdyRef {\n ref: SturdyRef;\n exportId: ExportId;\n capability: unknown;\n createdAt: number;\n lastAccessedAt: number;\n}\n\n/**\n * Options for saving a capability as a SturdyRef\n */\nexport interface SaveOptions {\n /** Custom local ID (auto-generated if not provided) */\n localId?: string;\n /** Expiration time in milliseconds from now */\n ttlMs?: number;\n /** Metadata to attach to the SturdyRef */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Options for restoring a capability from a SturdyRef\n */\nexport interface RestoreOptions {\n /** Timeout for the restore operation */\n timeoutMs?: number;\n}\n\n// ========================================================================================\n// SturdyRef Manager (Server-side)\n// ========================================================================================\n\n/**\n * Manages SturdyRefs on the server side.\n * Stores the mapping between SturdyRef tokens and live capabilities.\n */\nexport class SturdyRefManager {\n private vatId: string;\n private storedRefs = new Map<string, StoredSturdyRef>();\n private localIdCounter = 0;\n\n constructor(vatId: string) {\n this.vatId = vatId;\n }\n\n /**\n * Save a capability as a SturdyRef\n */\n saveCapability(capability: unknown, exportId: ExportId, options?: SaveOptions): SturdyRef {\n const localId = options?.localId ?? this.generateLocalId();\n const now = Date.now();\n\n const ref: SturdyRef = {\n vatId: this.vatId,\n localId,\n version: 1,\n expiresAt: options?.ttlMs ? now + options.ttlMs : undefined,\n metadata: options?.metadata,\n };\n\n const stored: StoredSturdyRef = {\n ref,\n exportId,\n capability,\n createdAt: now,\n lastAccessedAt: now,\n };\n\n this.storedRefs.set(localId, stored);\n return ref;\n }\n\n /**\n * Restore a capability from a SturdyRef token\n */\n restoreCapability(ref: SturdyRef): { capability: unknown; exportId: ExportId } | null {\n // Validate the SturdyRef belongs to this vat\n if (ref.vatId !== this.vatId) {\n console.warn(`SturdyRef vatId mismatch: ${ref.vatId} !== ${this.vatId}`);\n return null;\n }\n\n const stored = this.storedRefs.get(ref.localId);\n if (!stored) {\n console.warn(`SturdyRef not found: ${ref.localId}`);\n return null;\n }\n\n // Check expiration\n if (stored.ref.expiresAt && Date.now() > stored.ref.expiresAt) {\n console.warn(`SturdyRef expired: ${ref.localId}`);\n this.storedRefs.delete(ref.localId);\n return null;\n }\n\n // Update last accessed time\n stored.lastAccessedAt = Date.now();\n\n return {\n capability: stored.capability,\n exportId: stored.exportId,\n };\n }\n\n /**\n * Drop a SturdyRef\n */\n dropSturdyRef(localId: string): boolean {\n return this.storedRefs.delete(localId);\n }\n\n /**\n * Get all active SturdyRefs\n */\n getActiveRefs(): SturdyRef[] {\n const now = Date.now();\n const active: SturdyRef[] = [];\n\n for (const [localId, stored] of this.storedRefs) {\n // Clean up expired refs\n if (stored.ref.expiresAt && now > stored.ref.expiresAt) {\n this.storedRefs.delete(localId);\n continue;\n }\n active.push(stored.ref);\n }\n\n return active;\n }\n\n /**\n * Clean up expired SturdyRefs\n */\n cleanupExpired(): number {\n const now = Date.now();\n let cleaned = 0;\n\n for (const [localId, stored] of this.storedRefs) {\n if (stored.ref.expiresAt && now > stored.ref.expiresAt) {\n this.storedRefs.delete(localId);\n cleaned++;\n }\n }\n\n return cleaned;\n }\n\n private generateLocalId(): string {\n return `ref-${++this.localIdCounter}-${Date.now()}`;\n }\n}\n\n// ========================================================================================\n// Restore Handler (Client-side)\n// ========================================================================================\n\n/**\n * Handles Restore messages on the client side.\n * Manages reconnecting to capabilities after disconnections.\n */\nexport class RestoreHandler {\n private connection: RpcConnection;\n private pendingRestores = new Map<\n QuestionId,\n {\n resolve: (importId: ImportId) => void;\n reject: (error: Error) => void;\n timeout: ReturnType<typeof setTimeout>;\n }\n >();\n private questionIdCounter = 0;\n\n constructor(connection: RpcConnection) {\n this.connection = connection;\n }\n\n /**\n * Send a Restore message to restore a capability from a SturdyRef\n */\n async restore(ref: SturdyRef, options?: RestoreOptions): Promise<ImportId> {\n const questionId = ++this.questionIdCounter;\n const timeoutMs = options?.timeoutMs ?? 30000;\n\n return new Promise((resolve, reject) => {\n // Set up timeout\n const timeout = setTimeout(() => {\n this.pendingRestores.delete(questionId);\n reject(new Error(`Restore timeout after ${timeoutMs}ms`));\n }, timeoutMs);\n\n this.pendingRestores.set(questionId, { resolve, reject, timeout });\n\n // Send Restore message (using Call message with special interface)\n // In the actual protocol, this would be a specific Restore message type\n // For now, we use a special method call\n this.sendRestoreMessage(questionId, ref).catch((error) => {\n clearTimeout(timeout);\n this.pendingRestores.delete(questionId);\n reject(error);\n });\n });\n }\n\n /**\n * Handle a Restore response\n */\n handleRestoreResponse(questionId: QuestionId, importId: ImportId): void {\n const pending = this.pendingRestores.get(questionId);\n if (pending) {\n clearTimeout(pending.timeout);\n this.pendingRestores.delete(questionId);\n pending.resolve(importId);\n }\n }\n\n /**\n * Handle a Restore failure\n */\n handleRestoreFailure(questionId: QuestionId, reason: string): void {\n const pending = this.pendingRestores.get(questionId);\n if (pending) {\n clearTimeout(pending.timeout);\n this.pendingRestores.delete(questionId);\n pending.reject(new Error(`Restore failed: ${reason}`));\n }\n }\n\n /**\n * Cancel all pending restores (e.g., on disconnect)\n */\n cancelAll(reason: string): void {\n for (const [_questionId, pending] of this.pendingRestores) {\n clearTimeout(pending.timeout);\n pending.reject(new Error(`Restore canceled: ${reason}`));\n }\n this.pendingRestores.clear();\n }\n\n private async sendRestoreMessage(questionId: QuestionId, ref: SturdyRef): Promise<void> {\n // Serialize the SturdyRef\n const refData = JSON.stringify(ref);\n\n // In the actual implementation, this would send a proper Restore message\n // For now, we simulate it\n const restoreMsg: RpcMessage = {\n type: 'call',\n call: {\n questionId,\n target: { type: 'importedCap', importId: 0 }, // Special import for restore service\n interfaceId: BigInt('0xffffffffffffffff'), // Special interface ID for restore\n methodId: 0, // restore method\n allowThirdPartyTailCall: false,\n noPromisePipelining: false,\n onlyPromisePipeline: false,\n params: {\n content: new TextEncoder().encode(refData),\n capTable: [],\n },\n sendResultsTo: { type: 'caller' },\n },\n };\n\n // This would be sent through the connection\n // await this.connection.send(restoreMsg);\n console.log('Sending restore message:', restoreMsg);\n }\n}\n\n// ========================================================================================\n// SturdyRef Utilities\n// ========================================================================================\n\n/**\n * Serialize a SturdyRef to a string for storage\n */\nexport function serializeSturdyRef(ref: SturdyRef): string {\n return JSON.stringify(ref);\n}\n\n/**\n * Deserialize a SturdyRef from a string\n */\nexport function deserializeSturdyRef(data: string): SturdyRef | null {\n try {\n const parsed = JSON.parse(data);\n\n // Validate required fields\n if (typeof parsed.vatId !== 'string' || typeof parsed.localId !== 'string') {\n return null;\n }\n\n return {\n vatId: parsed.vatId,\n localId: parsed.localId,\n version: parsed.version,\n expiresAt: parsed.expiresAt,\n metadata: parsed.metadata,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Check if a SturdyRef is valid (not expired)\n */\nexport function isSturdyRefValid(ref: SturdyRef): boolean {\n if (ref.expiresAt && Date.now() > ref.expiresAt) {\n return false;\n }\n return true;\n}\n\n/**\n * Create a SturdyRef from components\n */\nexport function createSturdyRef(\n vatId: string,\n localId: string,\n options?: Omit<SaveOptions, 'localId'>\n): SturdyRef {\n return {\n vatId,\n localId,\n version: 1,\n expiresAt: options?.ttlMs ? Date.now() + options.ttlMs : undefined,\n metadata: options?.metadata,\n };\n}\n","/**\n * Performance Optimizations for RPC\n *\n * Phase 3: Performance improvements\n * - Multi-segment message support\n * - Memory pooling\n * - Zero-copy paths where possible\n */\n\nimport { Segment } from '../core/segment.js';\n\n// ========================================================================================\n// Memory Pool\n// ========================================================================================\n\ninterface PooledBuffer {\n buffer: ArrayBuffer;\n size: number;\n lastUsed: number;\n}\n\n/**\n * Memory pool for reusing ArrayBuffers\n * Reduces GC pressure for frequent allocations\n */\nexport class MemoryPool {\n private pools = new Map<number, PooledBuffer[]>();\n private maxPoolSize: number;\n private maxBufferAge: number;\n\n constructor(options?: { maxPoolSize?: number; maxBufferAgeMs?: number }) {\n this.maxPoolSize = options?.maxPoolSize ?? 100;\n this.maxBufferAge = options?.maxBufferAgeMs ?? 60000; // 1 minute\n }\n\n /**\n * Acquire a buffer of at least the requested size\n */\n acquire(size: number): ArrayBuffer {\n // Round up to nearest power of 2 for better pooling\n const pooledSize = this.roundUpSize(size);\n const pool = this.pools.get(pooledSize);\n\n if (pool && pool.length > 0) {\n const now = Date.now();\n // Find a buffer that's not too old\n const index = pool.findIndex((b) => now - b.lastUsed < this.maxBufferAge);\n\n if (index >= 0) {\n const pooled = pool.splice(index, 1)[0];\n return pooled.buffer;\n }\n }\n\n // Allocate new buffer\n return new ArrayBuffer(pooledSize);\n }\n\n /**\n * Release a buffer back to the pool\n */\n release(buffer: ArrayBuffer): void {\n const size = buffer.byteLength;\n\n // Don't pool very small or very large buffers\n if (size < 64 || size > 1024 * 1024) {\n return;\n }\n\n let pool = this.pools.get(size);\n if (!pool) {\n pool = [];\n this.pools.set(size, pool);\n }\n\n if (pool.length < this.maxPoolSize) {\n pool.push({\n buffer,\n size,\n lastUsed: Date.now(),\n });\n }\n }\n\n /**\n * Clear all pooled buffers\n */\n clear(): void {\n this.pools.clear();\n }\n\n /**\n * Get pool statistics\n */\n getStats(): { totalBuffers: number; totalBytes: number; sizes: number[] } {\n let totalBuffers = 0;\n let totalBytes = 0;\n const sizes: number[] = [];\n\n for (const [size, pool] of this.pools) {\n totalBuffers += pool.length;\n totalBytes += size * pool.length;\n sizes.push(size);\n }\n\n return { totalBuffers, totalBytes, sizes };\n }\n\n private roundUpSize(size: number): number {\n // Round up to nearest power of 2, minimum 64 bytes\n if (size <= 64) return 64;\n if (size <= 128) return 128;\n if (size <= 256) return 256;\n if (size <= 512) return 512;\n if (size <= 1024) return 1024;\n if (size <= 2048) return 2048;\n if (size <= 4096) return 4096;\n if (size <= 8192) return 8192;\n if (size <= 16384) return 16384;\n if (size <= 32768) return 32768;\n if (size <= 65536) return 65536;\n return size;\n }\n}\n\n// ========================================================================================\n// Multi-Segment Message Builder\n// ========================================================================================\n\n/**\n * Options for multi-segment message building\n */\nexport interface MultiSegmentOptions {\n /** Initial segment size */\n initialSegmentSize?: number;\n /** Maximum segment size */\n maxSegmentSize?: number;\n /** Whether to allow multiple segments */\n allowMultipleSegments?: boolean;\n}\n\n/**\n * Builder for multi-segment messages\n * Optimizes memory usage for large messages\n */\nexport class MultiSegmentMessageBuilder {\n private segments: Segment[] = [];\n private options: Required<MultiSegmentOptions>;\n private currentSegment: Segment;\n private totalSize = 0;\n\n constructor(options?: MultiSegmentOptions) {\n this.options = {\n initialSegmentSize: options?.initialSegmentSize ?? 8192,\n maxSegmentSize: options?.maxSegmentSize ?? 65536,\n allowMultipleSegments: options?.allowMultipleSegments ?? true,\n };\n\n this.currentSegment = new Segment(this.options.initialSegmentSize);\n this.segments.push(this.currentSegment);\n }\n\n /**\n * Allocate space in the message\n */\n allocate(size: number): { segment: Segment; offset: number } {\n // Align to 8 bytes and convert to words\n const alignedBytes = (size + 7) & ~7;\n const words = alignedBytes / 8;\n\n // Check if current segment has enough space\n // Segment capacity is the buffer size, not the current size\n const currentCapacity = this.currentSegment.byteLength;\n const currentUsed = this.currentSegment.wordCount * 8; // wordCount * 8 = bytes used\n const remainingSpace = currentCapacity - currentUsed;\n\n if (remainingSpace >= alignedBytes) {\n // Current segment has enough space\n const wordOffset = this.currentSegment.allocate(words);\n this.totalSize += alignedBytes;\n return { segment: this.currentSegment, offset: wordOffset * 8 };\n }\n\n // Need a new segment\n if (!this.options.allowMultipleSegments) {\n throw new Error('Message too large for single segment');\n }\n\n // Create new segment\n const newSegmentSize = Math.min(\n Math.max(alignedBytes, this.options.initialSegmentSize),\n this.options.maxSegmentSize\n );\n this.currentSegment = new Segment(newSegmentSize);\n this.segments.push(this.currentSegment);\n\n const newWordOffset = this.currentSegment.allocate(words);\n this.totalSize += alignedBytes;\n return { segment: this.currentSegment, offset: newWordOffset * 8 };\n }\n\n /**\n * Get all segments\n */\n getSegments(): readonly Segment[] {\n return this.segments;\n }\n\n /**\n * Get the total size of all segments\n */\n getTotalSize(): number {\n return this.totalSize;\n }\n\n /**\n * Get the number of segments\n */\n getSegmentCount(): number {\n return this.segments.length;\n }\n\n /**\n * Serialize to a single buffer (for transport)\n */\n toBuffer(): ArrayBuffer {\n if (this.segments.length === 1) {\n // Single segment - use asUint8Array to get the used portion\n const segmentData = this.segments[0].asUint8Array();\n return segmentData.buffer.slice(\n segmentData.byteOffset,\n segmentData.byteOffset + segmentData.byteLength\n ) as ArrayBuffer;\n }\n\n // Multi-segment - need to serialize with segment table\n // This is a simplified version - full implementation would include\n // the segment table at the beginning\n const totalSize = this.segments.reduce((sum, seg) => sum + seg.byteLength, 0);\n const result = new ArrayBuffer(totalSize + 8 * this.segments.length); // Space for segment table\n const view = new DataView(result);\n const bytes = new Uint8Array(result);\n\n // Write segment table\n view.setUint32(0, this.segments.length - 1, true); // Segment count - 1\n view.setUint32(4, 0, true); // Padding for first segment size (in words)\n\n let offset = 8;\n for (let i = 0; i < this.segments.length; i++) {\n const segment = this.segments[i];\n if (i > 0) {\n view.setUint32(offset, segment.byteLength / 8, true); // Segment size in words\n offset += 4;\n }\n\n // Copy segment data\n const segmentBuffer = new Uint8Array(segment.byteLength);\n // Copy data from segment's DataView\n const segmentData = segment.dataView;\n for (let i = 0; i < segment.byteLength; i++) {\n segmentBuffer[i] = segmentData.getUint8(i);\n }\n bytes.set(segmentBuffer, offset);\n offset += segment.byteLength;\n }\n\n return result;\n }\n}\n\n// ========================================================================================\n// Zero-Copy Utilities\n// ========================================================================================\n\n/**\n * View into a buffer without copying\n */\nexport interface ZeroCopyView {\n buffer: ArrayBuffer;\n byteOffset: number;\n byteLength: number;\n}\n\n/**\n * Create a zero-copy view of a buffer\n */\nexport function createZeroCopyView(\n buffer: ArrayBuffer,\n byteOffset = 0,\n byteLength?: number\n): ZeroCopyView {\n return {\n buffer,\n byteOffset,\n byteLength: byteLength ?? buffer.byteLength - byteOffset,\n };\n}\n\n/**\n * Check if two buffers are the same underlying memory\n */\nexport function isSameBuffer(a: ArrayBuffer, b: ArrayBuffer): boolean {\n try {\n // This is a hack to check if two buffers are the same\n // In a real implementation, we'd use a more reliable method\n return a === b;\n } catch {\n return false;\n }\n}\n\n/**\n * Copy data between buffers using the fastest available method\n */\nexport function fastCopy(\n src: ArrayBuffer,\n dst: ArrayBuffer,\n srcOffset = 0,\n dstOffset = 0,\n length?: number\n): void {\n const len = length ?? Math.min(src.byteLength - srcOffset, dst.byteLength - dstOffset);\n const srcView = new Uint8Array(src, srcOffset, len);\n const dstView = new Uint8Array(dst, dstOffset, len);\n dstView.set(srcView);\n}\n\n// ========================================================================================\n// RPC Message Optimization\n// ========================================================================================\n\n/**\n * Options for RPC message building\n */\nexport interface RpcMessageOptions {\n /** Use multi-segment messages */\n useMultiSegment?: boolean;\n /** Initial segment size */\n initialSegmentSize?: number;\n /** Use memory pooling */\n useMemoryPool?: boolean;\n /** Memory pool instance */\n memoryPool?: MemoryPool;\n}\n\n/**\n * Optimized RPC message builder\n */\nexport class OptimizedRpcMessageBuilder {\n private options: Required<RpcMessageOptions>;\n private pool: MemoryPool;\n\n constructor(options?: RpcMessageOptions) {\n this.options = {\n useMultiSegment: options?.useMultiSegment ?? true,\n initialSegmentSize: options?.initialSegmentSize ?? 8192,\n useMemoryPool: options?.useMemoryPool ?? true,\n memoryPool: options?.memoryPool ?? new MemoryPool(),\n };\n this.pool = this.options.memoryPool;\n }\n\n /**\n * Build a message with optimizations applied\n */\n buildMessage(content: Uint8Array): ArrayBuffer {\n const totalSize = 8 + content.length; // Header + content\n\n if (this.options.useMemoryPool) {\n const buffer = this.pool.acquire(totalSize);\n const view = new DataView(buffer);\n const bytes = new Uint8Array(buffer);\n\n // Write header (simplified)\n view.setUint32(0, 0, true); // Single segment indicator\n view.setUint32(4, content.length / 8, true); // Size in words\n\n // Copy content\n bytes.set(content, 8);\n\n return buffer;\n }\n\n // Standard allocation\n const buffer = new ArrayBuffer(totalSize);\n const view = new DataView(buffer);\n const bytes = new Uint8Array(buffer);\n\n view.setUint32(0, 0, true);\n view.setUint32(4, content.length / 8, true);\n bytes.set(content, 8);\n\n return buffer;\n }\n\n /**\n * Release a buffer back to the pool\n */\n releaseBuffer(buffer: ArrayBuffer): void {\n if (this.options.useMemoryPool) {\n this.pool.release(buffer);\n }\n }\n\n /**\n * Get pool statistics\n */\n getPoolStats(): { totalBuffers: number; totalBytes: number; sizes: number[] } {\n return this.pool.getStats();\n }\n}\n\n// ========================================================================================\n// Global Memory Pool (Singleton)\n// ========================================================================================\n\nlet globalMemoryPool: MemoryPool | null = null;\n\n/**\n * Get the global memory pool instance\n */\nexport function getGlobalMemoryPool(): MemoryPool {\n if (!globalMemoryPool) {\n globalMemoryPool = new MemoryPool();\n }\n return globalMemoryPool;\n}\n\n/**\n * Configure the global memory pool\n */\nexport function configureGlobalMemoryPool(options: {\n maxPoolSize?: number;\n maxBufferAgeMs?: number;\n}): void {\n globalMemoryPool = new MemoryPool(options);\n}\n","/**\n * Connection Manager\n *\n * Manages multiple RPC connections for Level 3 RPC (Three-way introductions).\n * Handles connection pooling, automatic connection establishment, and routing\n * of messages between vats.\n *\n * Level 3 RPC allows capabilities to be passed between vats that don't have\n * a direct connection, and enables those vats to form direct connections.\n */\n\nimport type { RpcConnection, RpcConnectionOptions } from './rpc-connection.js';\nimport type { ProvisionId, RecipientId, ThirdPartyCapId } from './rpc-types.js';\nimport type { RpcTransport } from './transport.js';\n\n/** Unique identifier for a vat */\nexport interface VatId {\n /** The raw vat identifier */\n id: Uint8Array;\n}\n\n/** Connection metadata */\nexport interface ConnectionInfo {\n /** The connection instance */\n connection: RpcConnection;\n /** The vat ID of the remote peer */\n remoteVatId: VatId;\n /** When the connection was established */\n establishedAt: Date;\n /** Last activity timestamp */\n lastActivity: Date;\n /** Connection state */\n state: 'connecting' | 'connected' | 'closing' | 'closed';\n}\n\n/** Pending provision waiting for acceptance */\nexport interface PendingProvision {\n /** Unique provision ID */\n provisionId: ProvisionId;\n /** The vat ID of the intended recipient */\n recipientId: VatId;\n /** The capability being provided */\n targetExportId: number;\n /** When the provision was created */\n createdAt: Date;\n /** Question ID from the Provide message */\n questionId: number;\n /** Whether this provision is embargoed (for cycle breaking) */\n embargoed: boolean;\n}\n\n/** Options for ConnectionManager */\nexport interface ConnectionManagerOptions {\n /** This vat's own ID */\n selfVatId: VatId;\n /** Factory function to create connections */\n connectionFactory: (vatId: VatId, address?: string) => Promise<RpcTransport>;\n /** Default connection options */\n connectionOptions?: RpcConnectionOptions;\n /** Maximum number of concurrent connections */\n maxConnections?: number;\n /** Connection idle timeout in milliseconds */\n idleTimeoutMs?: number;\n /** Whether to automatically establish connections to third parties */\n autoConnect?: boolean;\n}\n\n/**\n * ConnectionManager manages multiple RPC connections for Level 3 RPC.\n *\n * Key responsibilities:\n * 1. Maintain a pool of connections to other vats\n * 2. Handle automatic connection establishment for third-party capabilities\n * 3. Manage pending provisions (capabilities waiting to be picked up)\n * 4. Route messages to the appropriate connection\n * 5. Handle connection lifecycle (connect, disconnect, reconnect)\n */\nexport class ConnectionManager {\n private options: ConnectionManagerOptions;\n private connections = new Map<string, ConnectionInfo>();\n private pendingProvisions = new Map<string, PendingProvision>();\n private connectionPromises = new Map<string, Promise<RpcConnection>>();\n\n constructor(options: ConnectionManagerOptions) {\n this.options = {\n maxConnections: 100,\n idleTimeoutMs: 300000, // 5 minutes\n autoConnect: true,\n ...options,\n };\n }\n\n // ========================================================================================\n // Connection Management\n // ========================================================================================\n\n /**\n * Register an existing connection with the manager.\n * This is called when a connection is established (either inbound or outbound).\n */\n registerConnection(vatId: VatId, connection: RpcConnection): ConnectionInfo {\n const vatIdKey = this.vatIdToKey(vatId);\n\n const info: ConnectionInfo = {\n connection,\n remoteVatId: vatId,\n establishedAt: new Date(),\n lastActivity: new Date(),\n state: 'connected',\n };\n\n this.connections.set(vatIdKey, info);\n\n // Set up cleanup on connection close\n // Note: The connection's onClose handler should be set by the caller\n\n return info;\n }\n\n /**\n * Get or establish a connection to a vat.\n * If autoConnect is enabled and no connection exists, a new one will be created.\n */\n async getConnection(vatId: VatId): Promise<RpcConnection | undefined> {\n const vatIdKey = this.vatIdToKey(vatId);\n\n // Check for existing connection\n const existing = this.connections.get(vatIdKey);\n if (existing && existing.state === 'connected') {\n existing.lastActivity = new Date();\n return existing.connection;\n }\n\n // Check for in-progress connection\n const pending = this.connectionPromises.get(vatIdKey);\n if (pending) {\n return pending;\n }\n\n // Auto-connect if enabled\n if (this.options.autoConnect) {\n return this.establishConnection(vatId);\n }\n\n return undefined;\n }\n\n /**\n * Establish a new connection to a vat.\n */\n async establishConnection(vatId: VatId, address?: string): Promise<RpcConnection> {\n const vatIdKey = this.vatIdToKey(vatId);\n\n // Check if already connecting\n if (this.connectionPromises.has(vatIdKey)) {\n return this.connectionPromises.get(vatIdKey)!;\n }\n\n // Create connection promise\n const connectPromise = this.doEstablishConnection(vatId, address);\n this.connectionPromises.set(vatIdKey, connectPromise);\n\n try {\n const connection = await connectPromise;\n return connection;\n } finally {\n this.connectionPromises.delete(vatIdKey);\n }\n }\n\n private async doEstablishConnection(vatId: VatId, address?: string): Promise<RpcConnection> {\n const { RpcConnection } = await import('./rpc-connection.js');\n\n // Create transport using the factory\n const transport = await this.options.connectionFactory(vatId, address);\n\n // Create and start the connection\n const connection = new RpcConnection(transport, this.options.connectionOptions);\n await connection.start();\n\n // Register the connection\n this.registerConnection(vatId, connection);\n\n return connection;\n }\n\n /**\n * Close a connection to a vat.\n */\n async closeConnection(vatId: VatId): Promise<void> {\n const vatIdKey = this.vatIdToKey(vatId);\n const info = this.connections.get(vatIdKey);\n\n if (info) {\n info.state = 'closing';\n await info.connection.stop();\n this.connections.delete(vatIdKey);\n }\n }\n\n /**\n * Close all connections.\n */\n async closeAll(): Promise<void> {\n const closePromises: Promise<void>[] = [];\n\n for (const [_vatIdKey, info] of this.connections) {\n info.state = 'closing';\n closePromises.push(\n info.connection.stop().catch(() => {\n // Ignore errors during shutdown\n })\n );\n }\n\n await Promise.all(closePromises);\n this.connections.clear();\n this.pendingProvisions.clear();\n }\n\n // ========================================================================================\n // Provision Management (for Provide/Accept)\n // ========================================================================================\n\n /**\n * Create a pending provision for a third-party capability.\n * Called when we receive a Provide message.\n */\n createPendingProvision(\n provisionId: ProvisionId,\n recipientId: VatId,\n targetExportId: number,\n questionId: number,\n embargoed: boolean\n ): PendingProvision {\n const provisionKey = this.provisionIdToKey(provisionId);\n\n const provision: PendingProvision = {\n provisionId,\n recipientId,\n targetExportId,\n questionId,\n createdAt: new Date(),\n embargoed,\n };\n\n this.pendingProvisions.set(provisionKey, provision);\n return provision;\n }\n\n /**\n * Get a pending provision by ID.\n */\n getPendingProvision(provisionId: ProvisionId): PendingProvision | undefined {\n const provisionKey = this.provisionIdToKey(provisionId);\n return this.pendingProvisions.get(provisionKey);\n }\n\n /**\n * Remove a pending provision (when it's been accepted or expired).\n */\n removePendingProvision(provisionId: ProvisionId): boolean {\n const provisionKey = this.provisionIdToKey(provisionId);\n return this.pendingProvisions.delete(provisionKey);\n }\n\n /**\n * Find provisions for a specific recipient.\n */\n findProvisionsForRecipient(recipientId: VatId): PendingProvision[] {\n const recipientKey = this.vatIdToKey(recipientId);\n const result: PendingProvision[] = [];\n\n for (const provision of this.pendingProvisions.values()) {\n if (this.vatIdToKey(provision.recipientId) === recipientKey) {\n result.push(provision);\n }\n }\n\n return result;\n }\n\n /**\n * Clean up expired provisions.\n */\n cleanupExpiredProvisions(maxAgeMs = 300000): number {\n const now = Date.now();\n let removed = 0;\n\n for (const [key, provision] of this.pendingProvisions) {\n if (now - provision.createdAt.getTime() > maxAgeMs) {\n this.pendingProvisions.delete(key);\n removed++;\n }\n }\n\n return removed;\n }\n\n // ========================================================================================\n // Third-Party Capability Resolution\n // ========================================================================================\n\n /**\n * Resolve a third-party capability ID to a connection.\n * This is the core of Level 3 RPC - automatically establishing connections\n * to third parties when capabilities are passed between vats.\n */\n async resolveThirdPartyCap(thirdPartyCapId: ThirdPartyCapId): Promise<\n | {\n connection: RpcConnection;\n provisionId: ProvisionId;\n }\n | undefined\n > {\n // Parse the ThirdPartyCapId to extract vat ID and provision ID\n const parsed = this.parseThirdPartyCapId(thirdPartyCapId);\n if (!parsed) {\n return undefined;\n }\n\n // Get or establish connection to the third party\n const connection = await this.getConnection(parsed.vatId);\n if (!connection) {\n return undefined;\n }\n\n return {\n connection,\n provisionId: parsed.provisionId,\n };\n }\n\n /**\n * Parse a ThirdPartyCapId to extract vat ID and provision ID.\n * The format is implementation-specific, but typically:\n * - First N bytes: vat ID\n * - Remaining bytes: provision ID\n */\n private parseThirdPartyCapId(thirdPartyCapId: ThirdPartyCapId):\n | {\n vatId: VatId;\n provisionId: ProvisionId;\n }\n | undefined {\n // Default implementation: first 32 bytes are vat ID, rest is provision ID\n // This can be overridden by the application\n const data = thirdPartyCapId.id;\n\n if (data.length < 32) {\n return undefined;\n }\n\n const vatIdBytes = data.slice(0, 32);\n const provisionIdBytes = data.slice(32);\n\n return {\n vatId: { id: vatIdBytes },\n provisionId: { id: provisionIdBytes },\n };\n }\n\n // ========================================================================================\n // Utility Methods\n // ========================================================================================\n\n /**\n * Get all active connections.\n */\n getAllConnections(): ConnectionInfo[] {\n return Array.from(this.connections.values());\n }\n\n /**\n * Get the number of active connections.\n */\n getConnectionCount(): number {\n return this.connections.size;\n }\n\n /**\n * Get the number of pending provisions.\n */\n getPendingProvisionCount(): number {\n return this.pendingProvisions.size;\n }\n\n /**\n * Check if a connection exists to a vat.\n */\n hasConnection(vatId: VatId): boolean {\n const vatIdKey = this.vatIdToKey(vatId);\n const info = this.connections.get(vatIdKey);\n return info !== undefined && info.state === 'connected';\n }\n\n /**\n * Update the last activity timestamp for a connection.\n */\n touchConnection(vatId: VatId): void {\n const vatIdKey = this.vatIdToKey(vatId);\n const info = this.connections.get(vatIdKey);\n if (info) {\n info.lastActivity = new Date();\n }\n }\n\n // ========================================================================================\n // Private Helpers\n // ========================================================================================\n\n private vatIdToKey(vatId: VatId): string {\n // Convert Uint8Array to hex string for use as Map key\n return Array.from(vatId.id)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n }\n\n private provisionIdToKey(provisionId: ProvisionId): string {\n return Array.from(provisionId.id)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n }\n}\n\n/**\n * Create a ThirdPartyCapId from vat ID and provision ID.\n */\nexport function createThirdPartyCapId(vatId: VatId, provisionId: ProvisionId): ThirdPartyCapId {\n // Concatenate vat ID and provision ID\n const combined = new Uint8Array(vatId.id.length + provisionId.id.length);\n combined.set(vatId.id, 0);\n combined.set(provisionId.id, vatId.id.length);\n\n return { id: combined };\n}\n\n/**\n * Create a RecipientId from a vat ID.\n */\nexport function createRecipientId(vatId: VatId): RecipientId {\n return { id: vatId.id };\n}\n\n/**\n * Create a ProvisionId from raw bytes.\n */\nexport function createProvisionId(id: Uint8Array): ProvisionId {\n return { id };\n}\n\n/**\n * Generate a random provision ID.\n */\nexport function generateProvisionId(): ProvisionId {\n const id = new Uint8Array(32);\n if (typeof crypto !== 'undefined' && crypto.getRandomValues) {\n crypto.getRandomValues(id);\n } else {\n // Fallback for Node.js\n const { randomBytes } = require('node:crypto');\n randomBytes(32).copy(id);\n }\n return { id };\n}\n\n/**\n * Generate a random vat ID.\n */\nexport function generateVatId(): VatId {\n const id = new Uint8Array(32);\n if (typeof crypto !== 'undefined' && crypto.getRandomValues) {\n crypto.getRandomValues(id);\n } else {\n // Fallback for Node.js\n const { randomBytes } = require('node:crypto');\n randomBytes(32).copy(id);\n }\n return { id };\n}\n","/**\n * Level 3 RPC Message Handlers\n *\n * Implements the three-way introduction protocol for Level 3 RPC:\n * - Provide: Offer a capability to a third party\n * - Accept: Accept a capability from a third party\n * - Embargo handling for cycle breaking\n *\n * The three-way introduction protocol allows capabilities to be passed between\n * vats that don't have a direct connection, enabling those vats to form direct\n * connections.\n */\n\nimport type { ConnectionManager, PendingProvision, VatId } from './connection-manager.js';\nimport { createThirdPartyCapId, generateProvisionId } from './connection-manager.js';\nimport type { RpcConnection } from './rpc-connection.js';\nimport type {\n Accept,\n CapDescriptor,\n Disembargo,\n ExportId,\n ImportId,\n MessageTarget,\n Provide,\n RecipientId,\n RpcMessage,\n ThirdPartyCapId,\n} from './rpc-types.js';\n\n/** Options for Level3Handlers */\nexport interface Level3HandlersOptions {\n /** The connection this handler is attached to */\n connection: RpcConnection;\n /** The connection manager for managing third-party connections */\n connectionManager: ConnectionManager;\n /** This vat's ID */\n selfVatId: VatId;\n /** Handler for incoming Provide messages */\n onProvide?: (provide: Provide) => Promise<void>;\n /** Handler for incoming Accept messages */\n onAccept?: (accept: Accept) => Promise<void>;\n}\n\n/**\n * Manages Level 3 RPC message handling for a connection.\n *\n * This class handles:\n * 1. Provide messages - when someone wants to give us a capability to share with a third party\n * 2. Accept messages - when a third party wants to pick up a capability we provided\n * 3. Embargo handling - breaking cycles in introduction graphs\n */\nexport class Level3Handlers {\n private options: Level3HandlersOptions;\n private pendingAccepts = new Map<number, PendingAccept>();\n private embargoedCalls = new Map<number, EmbargoedCall[]>();\n private nextEmbargoId = 1;\n\n constructor(options: Level3HandlersOptions) {\n this.options = options;\n }\n\n // ========================================================================================\n // Provide Message Handling\n // ========================================================================================\n\n /**\n * Handle an incoming Provide message.\n *\n * When we receive a Provide message, it means someone wants us to hold a capability\n * and make it available to a specific third party. We:\n * 1. Create a pending provision\n * 2. Return an answer acknowledging receipt\n * 3. Wait for the third party to Accept\n */\n async handleProvide(provide: Provide): Promise<void> {\n const { questionId, target, recipient } = provide;\n const { connectionManager } = this.options;\n\n // Generate a unique provision ID\n const provisionId = generateProvisionId();\n\n // Extract the target export ID from the MessageTarget\n const targetExportId = this.extractTargetExportId(target);\n if (targetExportId === undefined) {\n // Can't provide this target - send exception\n await this.sendReturnException(\n questionId,\n 'Invalid provide target: must be a hosted capability'\n );\n return;\n }\n\n // Create the pending provision\n const _provision: PendingProvision = connectionManager.createPendingProvision(\n provisionId,\n this.recipientIdToVatId(recipient),\n targetExportId,\n questionId,\n false // Not embargoed by default\n );\n\n // Call the custom handler if provided\n if (this.options.onProvide) {\n await this.options.onProvide(provide);\n }\n\n // Send Return with the provision info\n // The provision ID is embedded in the answer for reference\n await this.sendReturnResults(questionId, {\n provisionId: provisionId.id,\n });\n }\n\n /**\n * Send a Provide message to offer a capability to a third party.\n *\n * This is called when we want to introduce a third party to a capability we hold.\n * For example, Alice calls this to offer Bob access to Carol's capability.\n */\n async sendProvide(\n target: MessageTarget,\n recipient: RecipientId\n ): Promise<{ questionId: number; provisionId: ThirdPartyCapId }> {\n const { connection } = this.options;\n\n // Create a question for this provide\n const questionId = connection.createQuestion();\n\n const provideMsg: RpcMessage = {\n type: 'provide',\n provide: {\n questionId,\n target,\n recipient,\n },\n };\n\n await connection.sendCall(provideMsg.provide as any);\n\n // Wait for the return to get the provision ID\n const _result = await connection.waitForAnswer(questionId);\n\n // Extract provision ID from result\n // In a full implementation, we'd parse the result payload\n const provisionId: ThirdPartyCapId = {\n id: new Uint8Array(0),\n };\n\n return { questionId, provisionId };\n }\n\n // ========================================================================================\n // Accept Message Handling\n // ========================================================================================\n\n /**\n * Handle an incoming Accept message.\n *\n * When we receive an Accept message, it means a third party wants to pick up\n * a capability we previously agreed to provide. We:\n * 1. Look up the pending provision\n * 2. Verify the recipient matches\n * 3. Return the capability\n */\n async handleAccept(accept: Accept): Promise<void> {\n const { questionId, provision, embargo } = accept;\n const { connectionManager } = this.options;\n\n // Find the pending provision\n const pendingProvision = connectionManager.getPendingProvision(provision);\n\n if (!pendingProvision) {\n // No such provision - send exception\n await this.sendReturnException(\n questionId,\n 'Invalid provision ID: no pending provision found'\n );\n return;\n }\n\n // Remove the pending provision\n connectionManager.removePendingProvision(provision);\n\n // If embargoed, set up embargo handling\n if (embargo || pendingProvision.embargoed) {\n await this.handleEmbargoedAccept(questionId, pendingProvision);\n return;\n }\n\n // Return the capability\n const capDescriptor: CapDescriptor = {\n type: 'senderHosted',\n exportId: pendingProvision.targetExportId as ExportId,\n };\n\n await this.sendReturnCapability(questionId, capDescriptor);\n\n // Call the custom handler if provided\n if (this.options.onAccept) {\n await this.options.onAccept(accept);\n }\n }\n\n /**\n * Send an Accept message to pick up a capability from a third party.\n *\n * This is called when we receive a third-party capability and want to\n * establish a direct connection to use it.\n */\n async sendAccept(\n targetConnection: RpcConnection,\n provision: { id: Uint8Array },\n embargo = false\n ): Promise<ImportId> {\n const questionId = targetConnection.createQuestion();\n\n const acceptMsg: RpcMessage = {\n type: 'accept',\n accept: {\n questionId,\n provision: provision as any,\n embargo,\n },\n };\n\n await targetConnection.sendCall(acceptMsg.accept as any);\n\n // Wait for the return\n const _result = await targetConnection.waitForAnswer(questionId);\n\n // In a full implementation, we'd extract the import ID from the result\n // For now, return a placeholder\n return 0 as ImportId;\n }\n\n // ========================================================================================\n // Embargo Handling (Cycle Breaking)\n // ========================================================================================\n\n /**\n * Handle an embargoed accept.\n *\n * Embargoes are used to break cycles in the introduction graph. For example,\n * if Alice introduces Bob to Carol and Carol to Bob simultaneously, both\n * introductions use embargo=true to prevent deadlock.\n */\n private async handleEmbargoedAccept(\n questionId: number,\n provision: PendingProvision\n ): Promise<void> {\n // Store the pending accept\n const pendingAccept: PendingAccept = {\n questionId,\n provision,\n embargoId: this.nextEmbargoId++,\n };\n\n this.pendingAccepts.set(questionId, pendingAccept);\n\n // Send a Return with resultsSentElsewhere to indicate we're waiting\n await this.sendReturnResultsSentElsewhere(questionId);\n\n // The embargo will be lifted when we receive a Disembargo message\n }\n\n /**\n * Handle a Disembargo message.\n *\n * Disembargo messages are used to lift embargoes on capabilities.\n */\n async handleDisembargo(disembargo: Disembargo): Promise<void> {\n const { target, context } = disembargo;\n\n switch (context.type) {\n case 'senderLoopback':\n // Echo back as receiverLoopback\n await this.sendDisembargoEcho(disembargo);\n break;\n\n case 'receiverLoopback':\n // Embargo lifted - process any pending calls\n await this.liftEmbargo(context.embargoId);\n break;\n\n case 'accept':\n // Embargo on a third-party accept can be lifted\n await this.liftAcceptEmbargo(target);\n break;\n\n case 'provide':\n // Embargo on a provision can be lifted\n await this.liftProvideEmbargo(context.questionId);\n break;\n }\n }\n\n /**\n * Lift an embargo by ID.\n */\n private async liftEmbargo(embargoId: number): Promise<void> {\n // Find and process embargoed calls\n const calls = this.embargoedCalls.get(embargoId);\n if (calls) {\n for (const call of calls) {\n // Re-send the call\n await this.resendEmbargoedCall(call);\n }\n this.embargoedCalls.delete(embargoId);\n }\n }\n\n /**\n * Lift an embargo on an accept.\n */\n private async liftAcceptEmbargo(target: MessageTarget): Promise<void> {\n // Find pending accepts for this target and complete them\n for (const [questionId, pendingAccept] of this.pendingAccepts) {\n if (this.matchesTarget(pendingAccept.provision.targetExportId, target)) {\n // Return the capability\n const capDescriptor: CapDescriptor = {\n type: 'senderHosted',\n exportId: pendingAccept.provision.targetExportId as ExportId,\n };\n\n await this.sendReturnCapability(pendingAccept.questionId, capDescriptor);\n this.pendingAccepts.delete(questionId);\n }\n }\n }\n\n /**\n * Lift an embargo on a provide.\n */\n private async liftProvideEmbargo(_questionId: number): Promise<void> {\n // Find the pending provision and mark it as no longer embargoed\n const { connectionManager } = this.options;\n\n for (const _provision of connectionManager.getAllConnections()) {\n // This is a simplified implementation\n // In a full implementation, we'd track provisions by question ID\n }\n }\n\n // ========================================================================================\n // Third-Party Capability Handling\n // ========================================================================================\n\n /**\n * Handle receiving a third-party capability.\n *\n * When we receive a CapDescriptor with type 'thirdPartyHosted', we need to:\n * 1. Establish a connection to the third party (if not already connected)\n * 2. Send an Accept message to pick up the capability\n * 3. Return a local import ID for the capability\n */\n async handleThirdPartyCapability(\n thirdPartyCapId: ThirdPartyCapId\n ): Promise<ImportId | undefined> {\n const { connectionManager } = this.options;\n\n // Resolve the third-party capability\n const resolved = await connectionManager.resolveThirdPartyCap(thirdPartyCapId);\n if (!resolved) {\n return undefined;\n }\n\n const { connection, provisionId } = resolved;\n\n // Send Accept to pick up the capability\n const importId = await this.sendAccept(connection, provisionId);\n\n return importId;\n }\n\n /**\n * Create a third-party capability descriptor.\n *\n * This is called when we want to pass a capability to a peer, but the capability\n * is actually hosted by a third party. We create a ThirdPartyCapId that allows\n * the recipient to connect directly to the third party.\n */\n createThirdPartyCapDescriptor(\n _hostedConnection: RpcConnection,\n exportId: ExportId,\n recipientVatId: VatId\n ): CapDescriptor {\n const { connectionManager, selfVatId } = this.options;\n\n // Generate a provision ID\n const provisionId = generateProvisionId();\n\n // Create the ThirdPartyCapId\n // Format: [selfVatId (32 bytes)] [provisionId (32 bytes)]\n const thirdPartyCapId = createThirdPartyCapId(selfVatId, provisionId);\n\n // Create a pending provision for this\n connectionManager.createPendingProvision(\n provisionId,\n recipientVatId,\n exportId,\n 0, // No question ID for this type of provision\n false\n );\n\n return {\n type: 'thirdPartyHosted',\n thirdPartyCapId,\n };\n }\n\n // ========================================================================================\n // Helper Methods\n // ========================================================================================\n\n private extractTargetExportId(target: MessageTarget): number | undefined {\n if (target.type === 'importedCap') {\n return target.importId;\n }\n // promisedAnswer targets are not supported for Provide\n return undefined;\n }\n\n private recipientIdToVatId(recipient: RecipientId): VatId {\n return { id: recipient.id };\n }\n\n private matchesTarget(exportId: number, target: MessageTarget): boolean {\n if (target.type === 'importedCap') {\n return target.importId === exportId;\n }\n return false;\n }\n\n private async sendReturnResults(questionId: number, _results: unknown): Promise<void> {\n const { connection } = this.options;\n\n // In a full implementation, we'd serialize the results\n const returnMsg: RpcMessage = {\n type: 'return',\n return: {\n answerId: questionId,\n releaseParamCaps: true,\n noFinishNeeded: false,\n result: {\n type: 'results',\n payload: {\n content: new Uint8Array(0),\n capTable: [],\n },\n },\n },\n };\n\n // @ts-ignore - accessing internal method\n await connection.sendReturn(returnMsg.return);\n }\n\n private async sendReturnCapability(questionId: number, cap: CapDescriptor): Promise<void> {\n const { connection } = this.options;\n\n const returnMsg: RpcMessage = {\n type: 'return',\n return: {\n answerId: questionId,\n releaseParamCaps: true,\n noFinishNeeded: false,\n result: {\n type: 'results',\n payload: {\n content: new Uint8Array(0),\n capTable: [cap],\n },\n },\n },\n };\n\n // @ts-ignore - accessing internal method\n await connection.sendReturn(returnMsg.return);\n }\n\n private async sendReturnException(questionId: number, reason: string): Promise<void> {\n const { connection } = this.options;\n\n const returnMsg: RpcMessage = {\n type: 'return',\n return: {\n answerId: questionId,\n releaseParamCaps: true,\n noFinishNeeded: false,\n result: {\n type: 'exception',\n exception: {\n reason,\n type: 'failed',\n },\n },\n },\n };\n\n // @ts-ignore - accessing internal method\n await connection.sendReturn(returnMsg.return);\n }\n\n private async sendReturnResultsSentElsewhere(questionId: number): Promise<void> {\n const { connection } = this.options;\n\n const returnMsg: RpcMessage = {\n type: 'return',\n return: {\n answerId: questionId,\n releaseParamCaps: true,\n noFinishNeeded: false,\n result: {\n type: 'resultsSentElsewhere',\n },\n },\n };\n\n // @ts-ignore - accessing internal method\n await connection.sendReturn(returnMsg.return);\n }\n\n private async sendDisembargoEcho(disembargo: Disembargo): Promise<void> {\n const { connection } = this.options;\n\n if (disembargo.context.type !== 'senderLoopback') {\n return;\n }\n\n const echoMsg: RpcMessage = {\n type: 'disembargo',\n disembargo: {\n target: disembargo.target,\n context: {\n type: 'receiverLoopback',\n embargoId: disembargo.context.embargoId,\n },\n },\n };\n\n // @ts-ignore - accessing internal method\n await connection.sendDisembargo(echoMsg.disembargo);\n }\n\n private async resendEmbargoedCall(_call: EmbargoedCall): Promise<void> {\n // In a full implementation, we'd re-send the call\n // For now, this is a placeholder\n }\n}\n\n/** Pending accept waiting for embargo to be lifted */\ninterface PendingAccept {\n questionId: number;\n provision: PendingProvision;\n embargoId: number;\n}\n\n/** An embargoed call waiting to be re-sent */\ninterface EmbargoedCall {\n questionId: number;\n target: MessageTarget;\n interfaceId: bigint;\n methodId: number;\n params: unknown;\n embargoId: number;\n}\n","/**\n * Level 4 RPC: Reference Equality / Join Operations\n *\n * Level 4 RPC allows verifying that capability references received from different\n * sources point to the same underlying object. This is crucial for:\n *\n * 1. **Escrow Agents**: Verifying that two parties are referring to the same object\n * before acting as a trusted intermediary.\n * 2. **Consensus Verification**: Ensuring multiple parties agree on the identity\n * of an object.\n * 3. **Security**: Preventing spoofing attacks where an attacker might try to\n * substitute a different object.\n *\n * ## Core Concept\n *\n * When Alice receives capability references from both Bob and Carol that should\n * point to the same object (e.g., a shared resource), she can use Join to verify\n * this:\n *\n * ```\n * Alice receives cap1 from Bob → points to object X (via proxy P1)\n * Alice receives cap2 from Carol → points to object X (via proxy P2)\n * Alice sends Join(cap1, cap2) to P1\n * P1 verifies that both caps point to the same underlying object\n * Result: confirmed equal or not equal\n * ```\n *\n * ## Object Identity\n *\n * Object identity is determined by:\n * - **Vat ID**: The vat hosting the object\n * - **Object ID**: A unique identifier within that vat\n * - **Identity Hash**: A cryptographic hash of the object's identity\n *\n * ## Join Protocol\n *\n * 1. Alice sends Join message to the first capability's host (P1)\n * 2. P1 receives the Join request with two capability references\n * 3. P1 verifies that both references resolve to the same underlying object\n * 4. P1 returns the result (equal or not equal)\n *\n * ## Escrow Agent Pattern\n *\n * ```\n * Bob wants to sell an object to Carol\n * Alice acts as escrow agent\n * Bob sends Alice a reference to the object\n * Carol sends Alice a reference to the same object\n * Alice verifies (via Join) that both refer to the same object\n * Alice holds payment from Carol\n * Bob transfers object to Carol\n * Alice releases payment to Bob\n * ```\n *\n * ## Implementation Notes\n *\n * - Join operations are idempotent\n * - Results are cached to avoid redundant verification\n * - Multiple capabilities can be joined in a single operation\n * - The operation may involve network calls to resolve proxies\n *\n * @module level4-handlers\n */\n\n/**\n * Object identity information used for equality verification.\n */\nexport interface ObjectIdentity {\n /** The vat ID of the object host */\n vatId: Uint8Array;\n\n /** The unique object ID within the vat */\n objectId: Uint8Array;\n\n /** Optional identity hash/fingerprint for verification */\n identityHash?: Uint8Array;\n\n /** Timestamp when this identity was established */\n establishedAt: number;\n}\n\n/**\n * Result of a Join operation.\n */\nexport interface JoinResult {\n /** Whether the capabilities are equal (point to the same object) */\n equal: boolean;\n\n /** If equal, the shared object identity */\n identity?: ObjectIdentity;\n\n /** If not equal, reasons for inequality */\n inequalityReason?: string;\n\n /** The join operation ID */\n joinId: number;\n}\n\n/**\n * Options for a Join operation.\n */\nexport interface JoinOptions {\n /** Timeout for the join operation in milliseconds */\n timeoutMs?: number;\n\n /** Whether to require cryptographic verification */\n requireCryptoVerification?: boolean;\n\n /** Whether to cache the result */\n cacheResult?: boolean;\n\n /** TTL for cached results in milliseconds */\n cacheTtlMs?: number;\n}\n\n/**\n * Default join options.\n */\nexport const DEFAULT_JOIN_OPTIONS: Required<JoinOptions> = {\n timeoutMs: 30000,\n requireCryptoVerification: true,\n cacheResult: true,\n cacheTtlMs: 300000, // 5 minutes\n};\n\n/**\n * Status of a pending Join operation.\n */\nexport interface PendingJoin {\n /** The join operation ID */\n joinId: number;\n\n /** The first capability target */\n target1: unknown;\n\n /** The second capability target */\n target2: unknown;\n\n /** When the join was initiated */\n startedAt: number;\n\n /** Resolve function for the promise */\n resolve: (result: JoinResult) => void;\n\n /** Reject function for the promise */\n reject: (error: Error) => void;\n}\n\n/**\n * Cached join result.\n */\nexport interface CachedJoinResult {\n /** The cached result */\n result: JoinResult;\n\n /** When the result was cached */\n cachedAt: number;\n\n /** The targets that were joined */\n targets: [string, string]; // Hashed target identifiers\n}\n\n/**\n * Configuration for the escrow agent mode.\n */\nexport interface EscrowConfig {\n /** Whether escrow mode is enabled */\n enabled: boolean;\n\n /** Required number of parties for consensus */\n requiredParties: number;\n\n /** Timeout for escrow operations */\n timeoutMs: number;\n\n /** Callback when consensus is reached */\n onConsensus?: (identity: ObjectIdentity, parties: string[]) => void;\n\n /** Callback when consensus fails */\n onConsensusFailure?: (reason: string, parties: string[]) => void;\n}\n\n/**\n * Default escrow configuration.\n */\nexport const DEFAULT_ESCROW_CONFIG: EscrowConfig = {\n enabled: false,\n requiredParties: 2,\n timeoutMs: 60000,\n};\n\n/**\n * Security policy for Join operations.\n */\nexport interface JoinSecurityPolicy {\n /** Whether to verify identity hashes */\n verifyIdentityHashes: boolean;\n\n /** Whether to check for revoked objects */\n checkRevocation: boolean;\n\n /** Maximum depth for proxy resolution */\n maxProxyDepth: number;\n\n /** Whether to log all join operations */\n auditLog: boolean;\n\n /** Allowed vats for join operations (empty = all allowed) */\n allowedVats: Uint8Array[];\n}\n\n/**\n * Default join security policy.\n */\nexport const DEFAULT_JOIN_SECURITY_POLICY: JoinSecurityPolicy = {\n verifyIdentityHashes: true,\n checkRevocation: true,\n maxProxyDepth: 10,\n auditLog: true,\n allowedVats: [],\n};\n","/**\n * Level 4 RPC: Reference Equality / Join Operations\n *\n * This module implements the Level 4 RPC protocol for verifying that capability\n * references point to the same underlying object.\n *\n * Reference: https://capnproto.org/rpc.html (Level 4: Reference equality / joining)\n */\n\nimport type { ConnectionManager, VatId } from './connection-manager.js';\nimport type { Level3Handlers } from './level3-handlers.js';\nimport {\n type CachedJoinResult,\n DEFAULT_ESCROW_CONFIG,\n DEFAULT_JOIN_OPTIONS,\n DEFAULT_JOIN_SECURITY_POLICY,\n type EscrowConfig,\n type JoinOptions,\n type JoinResult,\n type JoinSecurityPolicy,\n type ObjectIdentity,\n type PendingJoin,\n} from './level4-types.js';\nimport type { RpcConnection } from './rpc-connection.js';\nimport type { Join, MessageTarget, QuestionId, RpcMessage } from './rpc-types.js';\n\n/** Options for Level4Handlers */\nexport interface Level4HandlersOptions {\n /** The connection this handler is attached to */\n connection: RpcConnection;\n\n /** The connection manager for multi-vat scenarios */\n connectionManager?: ConnectionManager;\n\n /** Level 3 handlers (required for proxy resolution) */\n level3Handlers?: Level3Handlers;\n\n /** This vat's ID */\n selfVatId?: VatId;\n\n /** Join operation options */\n joinOptions?: JoinOptions;\n\n /** Escrow agent configuration */\n escrowConfig?: EscrowConfig;\n\n /** Security policy */\n securityPolicy?: JoinSecurityPolicy;\n\n /** Handler for incoming Join messages */\n onJoin?: (join: Join) => Promise<JoinResult>;\n}\n\n/**\n * Manages Level 4 RPC message handling for reference equality verification.\n *\n * This class handles:\n * 1. Join messages - verifying that two capabilities point to the same object\n * 2. Object identity tracking and caching\n * 3. Escrow agent functionality for consensus verification\n * 4. Security verification (anti-spoofing)\n *\n * ## Usage Example\n *\n * ```typescript\n * const level4Handlers = new Level4Handlers({\n * connection,\n * connectionManager,\n * level3Handlers,\n * selfVatId,\n * });\n *\n * // Enable escrow mode for consensus verification\n * level4Handlers.setEscrowConfig({\n * enabled: true,\n * requiredParties: 2,\n * });\n *\n * // Send a Join request\n * const result = await level4Handlers.sendJoin(target1, target2);\n * if (result.equal) {\n * console.log('Capabilities point to the same object!');\n * }\n * ```\n */\nexport class Level4Handlers {\n private options: Level4HandlersOptions;\n private pendingJoins = new Map<number, PendingJoin>();\n private joinResultsCache = new Map<string, CachedJoinResult>();\n private objectIdentities = new Map<number, ObjectIdentity>();\n private nextJoinId = 1;\n private escrowConfig: EscrowConfig;\n private securityPolicy: JoinSecurityPolicy;\n private joinOptions: Required<JoinOptions>;\n\n // Escrow state\n private escrowParties = new Map<string, { target: unknown; identity?: ObjectIdentity }>();\n private escrowConsensus?: {\n identity: ObjectIdentity;\n parties: string[];\n };\n\n constructor(options: Level4HandlersOptions) {\n this.options = options;\n this.escrowConfig = { ...DEFAULT_ESCROW_CONFIG, ...options.escrowConfig };\n this.securityPolicy = { ...DEFAULT_JOIN_SECURITY_POLICY, ...options.securityPolicy };\n this.joinOptions = { ...DEFAULT_JOIN_OPTIONS, ...options.joinOptions };\n }\n\n // ========================================================================================\n // Join Message Handling\n // ========================================================================================\n\n /**\n * Handle an incoming Join message.\n *\n * When we receive a Join message, we need to verify whether the two\n * capability references point to the same underlying object.\n *\n * The verification process:\n * 1. Resolve both targets to their underlying objects\n * 2. Compare object identities (vat ID + object ID)\n * 3. Optionally verify identity hashes cryptographically\n * 4. Return the result\n */\n async handleJoin(join: Join): Promise<void> {\n const { questionId, target, otherCap, joinId } = join;\n\n try {\n // Check cache first\n const cacheKey = this.getCacheKey(target, otherCap);\n const cached = this.joinResultsCache.get(cacheKey);\n if (cached && Date.now() - cached.cachedAt < this.joinOptions.cacheTtlMs) {\n await this.sendJoinResult(questionId, cached.result);\n return;\n }\n\n // Resolve both targets to their identities\n const identity1 = await this.resolveTargetToIdentity(target);\n const identity2 = await this.resolveTargetToIdentity(otherCap);\n\n // Compare identities\n const result = this.compareIdentities(identity1, identity2, joinId);\n\n // Cache the result if enabled\n if (this.joinOptions.cacheResult) {\n this.joinResultsCache.set(cacheKey, {\n result,\n cachedAt: Date.now(),\n targets: [this.hashTarget(target), this.hashTarget(otherCap)],\n });\n }\n\n // Log for audit if enabled\n if (this.securityPolicy.auditLog) {\n this.logJoinOperation(target, otherCap, result);\n }\n\n // Send the result\n await this.sendJoinResult(questionId, result);\n\n // Call custom handler if provided\n if (this.options.onJoin) {\n await this.options.onJoin(join);\n }\n } catch (error) {\n // Send exception result\n await this.sendJoinException(\n questionId,\n error instanceof Error ? error.message : 'Join operation failed'\n );\n }\n }\n\n /**\n * Send a Join message to verify that two capabilities point to the same object.\n *\n * @param target1 First capability target\n * @param target2 Second capability target\n * @returns Promise resolving to the join result\n */\n async sendJoin(target1: MessageTarget, target2: MessageTarget): Promise<JoinResult> {\n const { connection } = this.options;\n const joinId = this.nextJoinId++;\n const questionId = connection.createQuestion();\n\n // Create pending join\n const pendingJoin: PendingJoin = {\n joinId,\n target1,\n target2,\n startedAt: Date.now(),\n resolve: () => {},\n reject: () => {},\n };\n\n const completionPromise = new Promise<JoinResult>((resolve, reject) => {\n pendingJoin.resolve = resolve;\n pendingJoin.reject = reject;\n });\n\n this.pendingJoins.set(joinId, pendingJoin);\n\n // Set timeout\n const timeoutMs = this.joinOptions.timeoutMs;\n const timeoutId = setTimeout(() => {\n this.pendingJoins.delete(joinId);\n pendingJoin.reject(new Error(`Join operation timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n\n // Override resolve to clear timeout\n const originalResolve = pendingJoin.resolve;\n pendingJoin.resolve = (result: JoinResult) => {\n clearTimeout(timeoutId);\n this.pendingJoins.delete(joinId);\n originalResolve(result);\n };\n\n try {\n const joinMsg: RpcMessage = {\n type: 'join',\n join: {\n questionId,\n target: target1,\n otherCap: target2,\n joinId,\n },\n };\n\n await connection.sendCall(joinMsg.join as any);\n\n // Wait for the result\n const result = await completionPromise;\n return result;\n } catch (error) {\n clearTimeout(timeoutId);\n this.pendingJoins.delete(joinId);\n throw error;\n }\n }\n\n /**\n * Complete a pending join operation with the result.\n * This is called when we receive a Return message for a Join.\n */\n completeJoin(joinId: number, result: JoinResult): void {\n const pending = this.pendingJoins.get(joinId);\n if (pending) {\n pending.resolve(result);\n this.pendingJoins.delete(joinId);\n }\n }\n\n // ========================================================================================\n // Object Identity Resolution\n // ========================================================================================\n\n /**\n * Resolve a MessageTarget to its ObjectIdentity.\n *\n * This may involve:\n * 1. Looking up local exports\n * 2. Resolving promises\n * 3. Following third-party capabilities\n * 4. Verifying proxy chains\n */\n private async resolveTargetToIdentity(target: MessageTarget): Promise<ObjectIdentity | null> {\n if (target.type === 'importedCap') {\n // Check if we have cached identity for this import\n const cached = this.objectIdentities.get(target.importId);\n if (cached) {\n return cached;\n }\n\n // Get the import and resolve its identity\n const importEntry = this.options.connection.getImport(target.importId);\n if (!importEntry) {\n return null;\n }\n\n // For local imports, we need to query the remote vat for identity\n // In a full implementation, this would involve a network call\n // For now, return a placeholder\n return null;\n }\n\n if (target.type === 'promisedAnswer') {\n // Wait for the promise to resolve\n const { questionId } = target.promisedAnswer;\n\n // Wait for the answer\n try {\n const _answer = await this.options.connection.waitForAnswer(questionId);\n // Extract capability from answer and resolve identity\n // This is simplified - full implementation would handle transforms\n return null;\n } catch {\n return null;\n }\n }\n\n return null;\n }\n\n /**\n * Compare two object identities for equality.\n */\n private compareIdentities(\n identity1: ObjectIdentity | null,\n identity2: ObjectIdentity | null,\n joinId: number\n ): JoinResult {\n // Both null = equal (both are null capabilities)\n if (!identity1 && !identity2) {\n return { equal: true, joinId };\n }\n\n // One null, one not = not equal\n if (!identity1 || !identity2) {\n return {\n equal: false,\n joinId,\n inequalityReason: 'One capability is null, the other is not',\n };\n }\n\n // Compare vat IDs\n if (!this.arraysEqual(identity1.vatId, identity2.vatId)) {\n return {\n equal: false,\n joinId,\n inequalityReason: 'Capabilities hosted by different vats',\n };\n }\n\n // Compare object IDs\n if (!this.arraysEqual(identity1.objectId, identity2.objectId)) {\n return {\n equal: false,\n joinId,\n inequalityReason: 'Different object IDs within the same vat',\n };\n }\n\n // Verify identity hashes if required\n if (this.securityPolicy.verifyIdentityHashes) {\n if (identity1.identityHash && identity2.identityHash) {\n if (!this.arraysEqual(identity1.identityHash, identity2.identityHash)) {\n return {\n equal: false,\n joinId,\n inequalityReason: 'Identity hash mismatch (possible spoofing attempt)',\n };\n }\n }\n }\n\n // All checks passed - identities are equal\n return {\n equal: true,\n joinId,\n identity: identity1,\n };\n }\n\n // ========================================================================================\n // Escrow Agent Functionality\n // ========================================================================================\n\n /**\n * Set the escrow configuration.\n */\n setEscrowConfig(config: Partial<EscrowConfig>): void {\n this.escrowConfig = { ...this.escrowConfig, ...config };\n }\n\n /**\n * Register a party in an escrow consensus verification.\n *\n * This is used when multiple parties need to verify they are referring\n * to the same object (e.g., in a trade or agreement).\n *\n * @param partyId Unique identifier for the party\n * @param target The capability reference from this party\n * @returns Whether consensus has been reached\n */\n async registerEscrowParty(\n partyId: string,\n target: unknown\n ): Promise<{ consensus: boolean; identity?: ObjectIdentity }> {\n if (!this.escrowConfig.enabled) {\n throw new Error('Escrow mode is not enabled');\n }\n\n // Check if party already registered\n if (this.escrowParties.has(partyId)) {\n throw new Error(`Party ${partyId} is already registered`);\n }\n\n // Register the party\n this.escrowParties.set(partyId, { target });\n\n // If we have enough parties, verify consensus\n if (this.escrowParties.size >= this.escrowConfig.requiredParties) {\n const consensus = await this.verifyEscrowConsensus();\n\n if (consensus.consensus) {\n this.escrowConsensus = {\n identity: consensus.identity!,\n parties: Array.from(this.escrowParties.keys()),\n };\n\n if (this.escrowConfig.onConsensus) {\n this.escrowConfig.onConsensus(consensus.identity!, Array.from(this.escrowParties.keys()));\n }\n } else {\n if (this.escrowConfig.onConsensusFailure) {\n this.escrowConfig.onConsensusFailure(\n consensus.reason!,\n Array.from(this.escrowParties.keys())\n );\n }\n }\n\n return { consensus: consensus.consensus, identity: consensus.identity };\n }\n\n return { consensus: false };\n }\n\n /**\n * Verify that all registered escrow parties refer to the same object.\n */\n private async verifyEscrowConsensus(): Promise<{\n consensus: boolean;\n identity?: ObjectIdentity;\n reason?: string;\n }> {\n const parties = Array.from(this.escrowParties.entries());\n\n if (parties.length < this.escrowConfig.requiredParties) {\n return { consensus: false, reason: 'Not enough parties registered' };\n }\n\n // Use the first party's target as the reference\n const [firstPartyId, firstParty] = parties[0];\n\n // Resolve first party's identity\n const firstIdentity = await this.resolveTargetToIdentity(firstParty.target as MessageTarget);\n if (!firstIdentity) {\n return { consensus: false, reason: `Could not resolve identity for party ${firstPartyId}` };\n }\n\n // Compare with all other parties\n for (const [partyId, party] of parties.slice(1)) {\n const identity = await this.resolveTargetToIdentity(party.target as MessageTarget);\n const comparison = this.compareIdentities(firstIdentity, identity, 0);\n\n if (!comparison.equal) {\n return {\n consensus: false,\n reason: `Party ${partyId} refers to a different object: ${comparison.inequalityReason}`,\n };\n }\n }\n\n // All parties refer to the same object\n return { consensus: true, identity: firstIdentity };\n }\n\n /**\n * Clear all escrow state.\n */\n clearEscrow(): void {\n this.escrowParties.clear();\n this.escrowConsensus = undefined;\n }\n\n /**\n * Get the current escrow consensus if reached.\n */\n getEscrowConsensus(): { identity: ObjectIdentity; parties: string[] } | undefined {\n return this.escrowConsensus;\n }\n\n // ========================================================================================\n // Security & Anti-Spoofing\n // ========================================================================================\n\n /**\n * Set the security policy.\n */\n setSecurityPolicy(policy: Partial<JoinSecurityPolicy>): void {\n this.securityPolicy = { ...this.securityPolicy, ...policy };\n }\n\n /**\n * Verify that a vat is allowed to participate in join operations.\n */\n private isVatAllowed(vatId: Uint8Array): boolean {\n if (this.securityPolicy.allowedVats.length === 0) {\n return true; // All vats allowed if no restrictions\n }\n\n return this.securityPolicy.allowedVats.some((allowed) => this.arraysEqual(allowed, vatId));\n }\n\n /**\n * Generate a cryptographic identity hash for an object.\n *\n * This creates a verifiable fingerprint of the object's identity\n * that can be used to detect spoofing attempts.\n */\n async generateIdentityHash(vatId: Uint8Array, objectId: Uint8Array): Promise<Uint8Array> {\n // Combine vat ID and object ID\n const combined = new Uint8Array(vatId.length + objectId.length);\n combined.set(vatId, 0);\n combined.set(objectId, vatId.length);\n\n // Use SubtleCrypto for hashing if available\n if (typeof crypto !== 'undefined' && crypto.subtle) {\n const hashBuffer = await crypto.subtle.digest('SHA-256', combined);\n return new Uint8Array(hashBuffer);\n }\n\n // Fallback: simple hash for Node.js\n const { createHash } = require('node:crypto');\n const hash = createHash('sha256');\n hash.update(combined);\n return hash.digest();\n }\n\n // ========================================================================================\n // Caching & Cleanup\n // ========================================================================================\n\n /**\n * Clear the join results cache.\n */\n clearCache(): void {\n this.joinResultsCache.clear();\n }\n\n /**\n * Clean up expired cache entries.\n */\n cleanupExpiredCache(): number {\n const now = Date.now();\n let removed = 0;\n\n for (const [key, entry] of this.joinResultsCache) {\n if (now - entry.cachedAt > this.joinOptions.cacheTtlMs) {\n this.joinResultsCache.delete(key);\n removed++;\n }\n }\n\n return removed;\n }\n\n /**\n * Get cache statistics.\n */\n getCacheStats(): { size: number; hitRate: number } {\n return {\n size: this.joinResultsCache.size,\n hitRate: 0, // Would need to track hits/misses\n };\n }\n\n // ========================================================================================\n // Helper Methods\n // ========================================================================================\n\n private getCacheKey(target1: MessageTarget, target2: MessageTarget): string {\n // Create a consistent cache key regardless of order\n const hash1 = this.hashTarget(target1);\n const hash2 = this.hashTarget(target2);\n\n // Sort to ensure (A,B) and (B,A) have the same key\n const sorted = [hash1, hash2].sort();\n return `join:${sorted[0]}:${sorted[1]}`;\n }\n\n private hashTarget(target: MessageTarget): string {\n if (target.type === 'importedCap') {\n return `import:${target.importId}`;\n }\n if (target.type === 'promisedAnswer') {\n return `answer:${target.promisedAnswer.questionId}`;\n }\n return 'unknown';\n }\n\n private arraysEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n }\n\n private async sendJoinResult(questionId: QuestionId, result: JoinResult): Promise<void> {\n const { connection } = this.options;\n\n const returnMsg: RpcMessage = {\n type: 'return',\n return: {\n answerId: questionId,\n releaseParamCaps: true,\n noFinishNeeded: false,\n result: {\n type: 'results',\n payload: {\n content: this.serializeJoinResult(result),\n capTable: [],\n },\n },\n },\n };\n\n // @ts-ignore - accessing internal method\n await connection.sendReturn(returnMsg.return);\n }\n\n private async sendJoinException(questionId: QuestionId, reason: string): Promise<void> {\n const { connection } = this.options;\n\n const returnMsg: RpcMessage = {\n type: 'return',\n return: {\n answerId: questionId,\n releaseParamCaps: true,\n noFinishNeeded: false,\n result: {\n type: 'exception',\n exception: {\n reason,\n type: 'failed',\n },\n },\n },\n };\n\n // @ts-ignore - accessing internal method\n await connection.sendReturn(returnMsg.return);\n }\n\n private serializeJoinResult(result: JoinResult): Uint8Array {\n // Simple serialization - in production, use proper Cap'n Proto encoding\n const obj = {\n equal: result.equal,\n joinId: result.joinId,\n inequalityReason: result.inequalityReason,\n };\n return new TextEncoder().encode(JSON.stringify(obj));\n }\n\n private logJoinOperation(\n target1: MessageTarget,\n target2: MessageTarget,\n result: JoinResult\n ): void {\n console.log('[Level4] Join operation:', {\n target1: this.hashTarget(target1),\n target2: this.hashTarget(target2),\n equal: result.equal,\n joinId: result.joinId,\n timestamp: new Date().toISOString(),\n });\n }\n}\n\n// Re-export types\nexport type {\n JoinOptions,\n ObjectIdentity,\n PendingJoin,\n CachedJoinResult,\n EscrowConfig,\n JoinSecurityPolicy,\n} from './level4-types.js';\nexport {\n DEFAULT_JOIN_OPTIONS,\n DEFAULT_ESCROW_CONFIG,\n DEFAULT_JOIN_SECURITY_POLICY,\n} from './level4-types.js';\n","/**\n * Stream Abstraction for Cap'n Proto RPC\n *\n * Phase 5: Flow Control and Realtime Communication\n *\n * Provides Stream interface for bidirectional streaming with:\n * - Backpressure handling\n * - Flow control window management\n * - Chunked transfer\n * - Progress notifications\n */\n\nimport type { RpcMessage } from './rpc-types.js';\nimport type { RpcTransport } from './transport.js';\n\n/** Stream state */\nexport type StreamState = 'connecting' | 'open' | 'closing' | 'closed' | 'error';\n\n/** Stream direction */\nexport type StreamDirection = 'inbound' | 'outbound' | 'bidirectional';\n\n/** Stream priority levels */\nexport enum StreamPriority {\n CRITICAL = 0, // Must not drop, immediate delivery\n HIGH = 1, // High priority, minimal delay\n NORMAL = 2, // Normal priority (default)\n LOW = 3, // Low priority, can be delayed\n BACKGROUND = 4, // Background tasks, lowest priority\n}\n\n/** Flow control window configuration */\nexport interface FlowControlConfig {\n /** Initial window size in bytes */\n initialWindowSize: number;\n /** Maximum window size in bytes */\n maxWindowSize: number;\n /** Minimum window size before backpressure */\n minWindowSize: number;\n /** Window update threshold (update when window drops below this) */\n windowUpdateThreshold: number;\n /** Window update increment size */\n windowUpdateIncrement: number;\n}\n\n/** Default flow control configuration */\nexport const DEFAULT_FLOW_CONTROL: FlowControlConfig = {\n initialWindowSize: 65536, // 64KB\n maxWindowSize: 1048576, // 1MB\n minWindowSize: 4096, // 4KB\n windowUpdateThreshold: 16384, // 16KB\n windowUpdateIncrement: 32768, // 32KB\n};\n\n/** Stream configuration options */\nexport interface StreamOptions {\n /** Stream ID (unique within connection) */\n streamId: number;\n /** Stream direction */\n direction: StreamDirection;\n /** Stream priority */\n priority?: StreamPriority;\n /** Flow control configuration */\n flowControl?: Partial<FlowControlConfig>;\n /** Enable progress notifications */\n enableProgress?: boolean;\n /** Progress notification interval in bytes */\n progressInterval?: number;\n /** Stream metadata */\n metadata?: Record<string, string>;\n}\n\n/** Chunk of data in a stream */\nexport interface StreamChunk {\n /** Chunk data */\n data: Uint8Array;\n /** Whether this is the final chunk */\n endOfStream?: boolean;\n /** Chunk sequence number (for ordering) */\n sequenceNumber?: number;\n /** Timestamp when chunk was sent */\n timestamp?: number;\n}\n\n/** Progress notification */\nexport interface StreamProgress {\n /** Stream ID */\n streamId: number;\n /** Total bytes sent/received */\n bytesTransferred: number;\n /** Total bytes expected (if known) */\n totalBytes?: number;\n /** Progress percentage (0-100) */\n percentage?: number;\n /** Transfer rate in bytes per second */\n transferRate?: number;\n /** Estimated time remaining in milliseconds */\n estimatedTimeRemaining?: number;\n}\n\n/** Flow control window state */\ninterface FlowControlWindow {\n /** Current window size */\n currentSize: number;\n /** Maximum window size */\n maxSize: number;\n /** Bytes sent/received in current window */\n bytesInWindow: number;\n /** Whether backpressure is active */\n backpressureActive: boolean;\n}\n\n/** Stream event handlers */\nexport interface StreamEventHandlers {\n /** Called when data is received */\n onData?: (chunk: StreamChunk) => void | Promise<void>;\n /** Called when stream is opened */\n onOpen?: () => void;\n /** Called when stream is closed */\n onClose?: () => void;\n /** Called when progress updates */\n onProgress?: (progress: StreamProgress) => void;\n /** Called when backpressure state changes */\n onBackpressure?: (active: boolean) => void;\n /** Called when an error occurs */\n onError?: (error: Error) => void;\n}\n\n/**\n * Stream abstraction for Cap'n Proto RPC\n *\n * Manages bidirectional streaming with flow control and backpressure.\n */\nexport class Stream {\n private options: StreamOptions;\n private handlers: StreamEventHandlers;\n private state: StreamState = 'connecting';\n private error?: Error;\n\n // Flow control\n private sendWindow: FlowControlWindow;\n private receiveWindow: FlowControlWindow;\n private flowControlConfig: FlowControlConfig;\n\n // Data buffering\n private sendBuffer: StreamChunk[] = [];\n private receiveBuffer: StreamChunk[] = [];\n private maxBufferSize = 1048576; // 1MB max buffer\n\n // Progress tracking\n private bytesSent = 0;\n private bytesReceived = 0;\n private totalBytesExpected?: number;\n private lastProgressUpdate = 0;\n private progressUpdateInterval: number;\n private transferStartTime?: number;\n\n // Chunk sequencing\n private nextSendSequence = 0;\n private nextExpectedSequence = 0;\n\n // Promise resolvers for async operations\n private openResolver?: () => void;\n private openRejector?: (error: Error) => void;\n private closeResolver?: () => void;\n\n constructor(options: StreamOptions, handlers: StreamEventHandlers = {}) {\n this.options = options;\n this.handlers = handlers;\n\n // Initialize flow control\n this.flowControlConfig = {\n ...DEFAULT_FLOW_CONTROL,\n ...options.flowControl,\n };\n\n this.sendWindow = {\n currentSize: this.flowControlConfig.initialWindowSize,\n maxSize: this.flowControlConfig.maxWindowSize,\n bytesInWindow: 0,\n backpressureActive: false,\n };\n\n this.receiveWindow = {\n currentSize: this.flowControlConfig.initialWindowSize,\n maxSize: this.flowControlConfig.maxWindowSize,\n bytesInWindow: 0,\n backpressureActive: false,\n };\n\n this.progressUpdateInterval = options.progressInterval ?? 65536; // 64KB default\n }\n\n /** Get stream ID */\n get id(): number {\n return this.options.streamId;\n }\n\n /** Get stream direction */\n get direction(): StreamDirection {\n return this.options.direction;\n }\n\n /** Get stream priority */\n get priority(): StreamPriority {\n return this.options.priority ?? StreamPriority.NORMAL;\n }\n\n /** Get current stream state */\n get currentState(): StreamState {\n return this.state;\n }\n\n /** Get whether stream is open */\n get isOpen(): boolean {\n return this.state === 'open';\n }\n\n /** Get whether backpressure is active for sending */\n get isBackpressureActive(): boolean {\n return this.sendWindow.backpressureActive;\n }\n\n /** Get bytes sent */\n get bytesSentCount(): number {\n return this.bytesSent;\n }\n\n /** Get bytes received */\n get bytesReceivedCount(): number {\n return this.bytesReceived;\n }\n\n /** Get metadata */\n get metadata(): Record<string, string> | undefined {\n return this.options.metadata;\n }\n\n /**\n * Open the stream\n */\n async open(): Promise<void> {\n if (this.state !== 'connecting') {\n throw new Error(`Cannot open stream in state: ${this.state}`);\n }\n\n return new Promise((resolve, reject) => {\n this.openResolver = resolve;\n this.openRejector = reject;\n\n // Transition to open state\n this.transitionState('open');\n this.transferStartTime = Date.now();\n\n // Notify handlers\n this.handlers.onOpen?.();\n });\n }\n\n /**\n * Send data through the stream\n *\n * Respects flow control and handles backpressure.\n */\n async send(data: Uint8Array, endOfStream = false): Promise<void> {\n if (this.state !== 'open') {\n throw new Error(`Cannot send in state: ${this.state}`);\n }\n\n // Check if we need to wait for window update\n if (this.sendWindow.bytesInWindow + data.length > this.sendWindow.currentSize) {\n // Wait for window update\n await this.waitForWindowUpdate();\n }\n\n // Create chunk\n const chunk: StreamChunk = {\n data,\n endOfStream,\n sequenceNumber: this.nextSendSequence++,\n timestamp: Date.now(),\n };\n\n // Update flow control\n this.sendWindow.bytesInWindow += data.length;\n this.bytesSent += data.length;\n\n // Check for backpressure\n this.checkBackpressure();\n\n // Send the chunk\n await this.sendChunk(chunk);\n\n // Report progress\n this.reportProgress();\n }\n\n /**\n * Send a chunk of data\n *\n * Override in subclasses to implement actual transport.\n */\n protected async sendChunk(chunk: StreamChunk): Promise<void> {\n // To be implemented by transport-specific subclass\n // This base class just buffers\n this.sendBuffer.push(chunk);\n }\n\n /**\n * Receive data from the stream\n *\n * Returns buffered data or waits for new data.\n */\n async receive(): Promise<StreamChunk | null> {\n if (this.receiveBuffer.length > 0) {\n return this.receiveBuffer.shift()!;\n }\n\n if (this.state === 'closed') {\n return null;\n }\n\n // Wait for data\n return new Promise((resolve, reject) => {\n const checkBuffer = () => {\n if (this.receiveBuffer.length > 0) {\n resolve(this.receiveBuffer.shift()!);\n } else if (this.state === 'closed') {\n resolve(null);\n } else if (this.state === 'error') {\n reject(this.error ?? new Error('Stream error'));\n } else {\n setTimeout(checkBuffer, 10);\n }\n };\n checkBuffer();\n });\n }\n\n /**\n * Handle incoming chunk from transport\n */\n handleIncomingChunk(chunk: StreamChunk): void {\n if (this.state !== 'open' && this.state !== 'closing') {\n return;\n }\n\n // Update receive window\n this.receiveWindow.bytesInWindow += chunk.data.length;\n this.bytesReceived += chunk.data.length;\n\n // Check if we need to send window update\n this.checkReceiveWindow();\n\n // Buffer or deliver chunk\n if (this.handlers.onData) {\n // Deliver immediately if handler is registered\n Promise.resolve(this.handlers.onData(chunk)).catch((err) => {\n this.handleError(err);\n });\n } else {\n // Buffer for later\n this.receiveBuffer.push(chunk);\n }\n\n // Report progress\n this.reportProgress();\n\n // Handle end of stream\n if (chunk.endOfStream) {\n this.transitionState('closing');\n }\n }\n\n /**\n * Update the send window (called when receiving window update from peer)\n */\n updateSendWindow(increment: number): void {\n this.sendWindow.currentSize = Math.min(\n this.sendWindow.currentSize + increment,\n this.sendWindow.maxSize\n );\n\n // Check if we can release backpressure\n if (this.sendWindow.backpressureActive) {\n const available = this.sendWindow.currentSize - this.sendWindow.bytesInWindow;\n if (available >= this.flowControlConfig.minWindowSize) {\n this.sendWindow.backpressureActive = false;\n this.handlers.onBackpressure?.(false);\n }\n }\n }\n\n /**\n * Acknowledge received bytes (called to update peer's send window)\n */\n acknowledgeBytes(bytes: number): void {\n this.receiveWindow.bytesInWindow = Math.max(0, this.receiveWindow.bytesInWindow - bytes);\n\n // Check if we should send window update\n if (this.receiveWindow.bytesInWindow < this.flowControlConfig.windowUpdateThreshold) {\n this.sendWindowUpdate();\n }\n }\n\n /**\n * Close the stream gracefully\n */\n async close(): Promise<void> {\n if (this.state === 'closed' || this.state === 'closing') {\n return;\n }\n\n this.transitionState('closing');\n\n // Wait for any pending sends to complete\n await this.drainSendBuffer();\n\n // Send end-of-stream marker\n await this.sendChunk({ data: new Uint8Array(0), endOfStream: true });\n\n this.transitionState('closed');\n this.handlers.onClose?.();\n }\n\n /**\n * Abort the stream with an error\n */\n abort(error: Error): void {\n this.error = error;\n this.transitionState('error');\n this.handlers.onError?.(error);\n }\n\n /**\n * Set total bytes expected (for progress calculation)\n */\n setTotalBytesExpected(total: number): void {\n this.totalBytesExpected = total;\n }\n\n /**\n * Wait for the stream to be ready for sending\n */\n async ready(): Promise<void> {\n if (this.state === 'open' && !this.sendWindow.backpressureActive) {\n return;\n }\n\n if (this.state !== 'open') {\n throw new Error(`Stream not open: ${this.state}`);\n }\n\n return this.waitForWindowUpdate();\n }\n\n // =============================================================================\n // Private Methods\n // =============================================================================\n\n private transitionState(newState: StreamState): void {\n const _oldState = this.state;\n this.state = newState;\n\n // Resolve/reject pending promises\n if (newState === 'open' && this.openResolver) {\n this.openResolver();\n this.openResolver = undefined;\n this.openRejector = undefined;\n } else if (newState === 'error' && this.openRejector) {\n this.openRejector(this.error ?? new Error('Stream error'));\n this.openResolver = undefined;\n this.openRejector = undefined;\n }\n\n if (newState === 'closed' && this.closeResolver) {\n this.closeResolver();\n this.closeResolver = undefined;\n }\n }\n\n private checkBackpressure(): void {\n const available = this.sendWindow.currentSize - this.sendWindow.bytesInWindow;\n\n if (available < this.flowControlConfig.minWindowSize && !this.sendWindow.backpressureActive) {\n this.sendWindow.backpressureActive = true;\n this.handlers.onBackpressure?.(true);\n }\n }\n\n private checkReceiveWindow(): void {\n if (this.receiveWindow.bytesInWindow < this.flowControlConfig.windowUpdateThreshold) {\n this.sendWindowUpdate();\n }\n }\n\n private async waitForWindowUpdate(): Promise<void> {\n return new Promise((resolve, reject) => {\n const checkWindow = () => {\n const available = this.sendWindow.currentSize - this.sendWindow.bytesInWindow;\n\n if (this.state === 'error') {\n reject(this.error ?? new Error('Stream error'));\n return;\n }\n\n if (this.state !== 'open') {\n reject(new Error('Stream closed'));\n return;\n }\n\n if (available >= this.flowControlConfig.minWindowSize) {\n resolve();\n return;\n }\n\n setTimeout(checkWindow, 10);\n };\n\n checkWindow();\n });\n }\n\n private async drainSendBuffer(): Promise<void> {\n // In the base Stream class, sendBuffer is just for buffering\n // Subclasses that actually send data should override this\n // For now, just clear the buffer\n this.sendBuffer.length = 0;\n }\n\n private sendWindowUpdate(): void {\n // To be implemented by transport layer\n // This would send a window update message to the peer\n }\n\n private reportProgress(): void {\n if (!this.options.enableProgress || !this.handlers.onProgress) {\n return;\n }\n\n const now = Date.now();\n const bytesTransferred = Math.max(this.bytesSent, this.bytesReceived);\n\n // Check if it's time to report progress\n if (bytesTransferred - this.lastProgressUpdate < this.progressUpdateInterval) {\n return;\n }\n\n this.lastProgressUpdate = bytesTransferred;\n\n // Calculate transfer rate\n let transferRate: number | undefined;\n if (this.transferStartTime) {\n const elapsed = (now - this.transferStartTime) / 1000;\n if (elapsed > 0) {\n transferRate = bytesTransferred / elapsed;\n }\n }\n\n // Calculate percentage and ETA\n let percentage: number | undefined;\n let estimatedTimeRemaining: number | undefined;\n\n if (this.totalBytesExpected && this.totalBytesExpected > 0) {\n percentage = Math.min(100, (bytesTransferred / this.totalBytesExpected) * 100);\n\n if (transferRate && transferRate > 0) {\n const remaining = this.totalBytesExpected - bytesTransferred;\n estimatedTimeRemaining = (remaining / transferRate) * 1000;\n }\n }\n\n const progress: StreamProgress = {\n streamId: this.id,\n bytesTransferred,\n totalBytes: this.totalBytesExpected,\n percentage,\n transferRate,\n estimatedTimeRemaining,\n };\n\n this.handlers.onProgress(progress);\n }\n\n private handleError(error: Error): void {\n this.error = error;\n this.transitionState('error');\n this.handlers.onError?.(error);\n }\n}\n\n/**\n * Create a new stream\n */\nexport function createStream(options: StreamOptions, handlers?: StreamEventHandlers): Stream {\n return new Stream(options, handlers);\n}\n\n/**\n * Check if an object is a Stream\n */\nexport function isStream(obj: unknown): obj is Stream {\n return obj instanceof Stream;\n}\n","/**\n * Bulk API - High-volume data transfer with flow control\n *\n * Phase 5: Flow Control and Realtime Communication\n *\n * Features:\n * - Backpressure mechanism\n * - Flow control window management\n * - Chunked transfer\n * - Progress notifications\n */\n\nimport type { RpcConnection } from './rpc-connection.js';\nimport {\n DEFAULT_FLOW_CONTROL,\n type FlowControlConfig,\n Stream,\n type StreamChunk,\n type StreamEventHandlers,\n type StreamOptions,\n StreamPriority,\n type StreamProgress,\n} from './stream.js';\n\n/** Bulk transfer configuration */\nexport interface BulkTransferConfig {\n /** Chunk size for transfer */\n chunkSize: number;\n /** Flow control configuration */\n flowControl?: Partial<FlowControlConfig>;\n /** Enable progress notifications */\n enableProgress?: boolean;\n /** Progress notification interval in bytes */\n progressInterval?: number;\n /** Maximum concurrent chunks in flight */\n maxConcurrentChunks?: number;\n /** Timeout for chunk acknowledgment */\n chunkAckTimeoutMs?: number;\n}\n\n/** Default bulk transfer configuration */\nexport const DEFAULT_BULK_CONFIG: BulkTransferConfig = {\n chunkSize: 16384, // 16KB chunks\n enableProgress: true,\n progressInterval: 65536, // 64KB\n maxConcurrentChunks: 8, // 8 concurrent chunks\n chunkAckTimeoutMs: 30000, // 30 seconds\n};\n\n/** Bulk transfer state */\nexport type BulkTransferState =\n | 'pending'\n | 'transferring'\n | 'paused'\n | 'completed'\n | 'cancelled'\n | 'error';\n\n/** Bulk transfer direction */\nexport type BulkTransferDirection = 'upload' | 'download';\n\n/** Bulk transfer metadata */\nexport interface BulkTransferMetadata {\n /** Transfer ID */\n id: string;\n /** File or resource name */\n name?: string;\n /** Total size in bytes (if known) */\n totalSize?: number;\n /** MIME type */\n contentType?: string;\n /** Custom metadata */\n custom?: Record<string, string>;\n}\n\n/** Bulk transfer statistics */\nexport interface BulkTransferStats {\n /** Bytes transferred */\n bytesTransferred: number;\n /** Total bytes (if known) */\n totalBytes?: number;\n /** Transfer rate in bytes per second */\n transferRate: number;\n /** Time elapsed in milliseconds */\n elapsedTime: number;\n /** Estimated time remaining in milliseconds */\n estimatedTimeRemaining?: number;\n /** Number of chunks transferred */\n chunksTransferred: number;\n /** Number of chunks acknowledged */\n chunksAcknowledged: number;\n /** Current window size */\n currentWindowSize: number;\n /** Whether backpressure is active */\n backpressureActive: boolean;\n}\n\n/** Chunk acknowledgment */\ninterface ChunkAck {\n sequenceNumber: number;\n bytesAcknowledged: number;\n}\n\n/** Bulk transfer event handlers */\nexport interface BulkTransferHandlers {\n /** Called when transfer starts */\n onStart?: () => void;\n /** Called when progress updates */\n onProgress?: (progress: StreamProgress) => void;\n /** Called when backpressure state changes */\n onBackpressure?: (active: boolean) => void;\n /** Called when transfer completes */\n onComplete?: () => void;\n /** Called when transfer is cancelled */\n onCancel?: () => void;\n /** Called when an error occurs */\n onError?: (error: Error) => void;\n}\n\n/**\n * Bulk transfer manager\n *\n * Manages high-volume data transfers with flow control and backpressure.\n */\nexport class BulkTransfer {\n private stream: Stream;\n private config: BulkTransferConfig;\n private handlers: BulkTransferHandlers;\n private metadata: BulkTransferMetadata;\n private direction: BulkTransferDirection;\n\n // State\n private state: BulkTransferState = 'pending';\n private error?: Error;\n\n // Transfer tracking\n private chunksInFlight = 0;\n private chunksAcknowledged = 0;\n private totalChunks = 0;\n private startTime?: number;\n private endTime?: number;\n\n // Chunk tracking\n private pendingChunks: Map<\n number,\n { chunk: StreamChunk; timeout: ReturnType<typeof setTimeout> }\n > = new Map();\n private chunkAckCallbacks: Map<number, () => void> = new Map();\n\n // Flow control\n private currentWindowSize: number;\n\n // Data source/sink\n private dataSource?: AsyncIterable<Uint8Array> | (() => Promise<Uint8Array | null>);\n private dataSink?: (chunk: Uint8Array) => Promise<void>;\n\n constructor(\n stream: Stream,\n direction: BulkTransferDirection,\n metadata: BulkTransferMetadata,\n config: Partial<BulkTransferConfig> = {},\n handlers: BulkTransferHandlers = {}\n ) {\n this.stream = stream;\n this.direction = direction;\n this.metadata = metadata;\n this.config = { ...DEFAULT_BULK_CONFIG, ...config };\n this.handlers = handlers;\n this.currentWindowSize =\n this.config.flowControl?.initialWindowSize ?? DEFAULT_FLOW_CONTROL.initialWindowSize;\n\n // Set up stream event handlers\n this.setupStreamHandlers();\n }\n\n /** Get transfer ID */\n get id(): string {\n return this.metadata.id;\n }\n\n /** Get current state */\n get currentState(): BulkTransferState {\n return this.state;\n }\n\n /** Get transfer statistics */\n get stats(): BulkTransferStats {\n const now = Date.now();\n const elapsed = this.startTime ? (this.endTime ?? now) - this.startTime : 0;\n const bytesTransferred = this.stream.bytesSentCount + this.stream.bytesReceivedCount;\n\n let transferRate = 0;\n if (elapsed > 0) {\n transferRate = (bytesTransferred / elapsed) * 1000;\n }\n\n let estimatedTimeRemaining: number | undefined;\n if (this.metadata.totalSize && transferRate > 0) {\n const remaining = this.metadata.totalSize - bytesTransferred;\n estimatedTimeRemaining = (remaining / transferRate) * 1000;\n }\n\n return {\n bytesTransferred,\n totalBytes: this.metadata.totalSize,\n transferRate,\n elapsedTime: elapsed,\n estimatedTimeRemaining,\n chunksTransferred: this.chunksAcknowledged + this.pendingChunks.size,\n chunksAcknowledged: this.chunksAcknowledged,\n currentWindowSize: this.currentWindowSize,\n backpressureActive: this.stream.isBackpressureActive,\n };\n }\n\n /**\n * Set the data source for upload\n */\n setDataSource(source: AsyncIterable<Uint8Array> | (() => Promise<Uint8Array | null>)): void {\n if (this.direction !== 'upload') {\n throw new Error('Data source only valid for uploads');\n }\n this.dataSource = source;\n }\n\n /**\n * Set the data sink for download\n */\n setDataSink(sink: (chunk: Uint8Array) => Promise<void>): void {\n if (this.direction !== 'download') {\n throw new Error('Data sink only valid for downloads');\n }\n this.dataSink = sink;\n }\n\n /**\n * Start the bulk transfer\n */\n async start(): Promise<void> {\n if (this.state !== 'pending') {\n throw new Error(`Cannot start transfer in state: ${this.state}`);\n }\n\n this.state = 'transferring';\n this.startTime = Date.now();\n this.handlers.onStart?.();\n\n // Set total size for progress tracking\n if (this.metadata.totalSize) {\n this.stream.setTotalBytesExpected(this.metadata.totalSize);\n }\n\n try {\n if (this.direction === 'upload') {\n await this.performUpload();\n } else {\n await this.performDownload();\n }\n\n if (this.state === 'transferring') {\n this.state = 'completed';\n this.endTime = Date.now();\n this.handlers.onComplete?.();\n }\n } catch (err) {\n this.handleError(err as Error);\n }\n }\n\n /**\n * Pause the transfer\n */\n pause(): void {\n if (this.state === 'transferring') {\n this.state = 'paused';\n }\n }\n\n /**\n * Resume the transfer\n */\n resume(): void {\n if (this.state === 'paused') {\n this.state = 'transferring';\n }\n }\n\n /**\n * Cancel the transfer\n */\n cancel(): void {\n if (this.state === 'completed' || this.state === 'error' || this.state === 'cancelled') {\n return;\n }\n\n this.state = 'cancelled';\n this.endTime = Date.now();\n\n // Clear pending timeouts\n for (const { timeout } of this.pendingChunks.values()) {\n clearTimeout(timeout);\n }\n this.pendingChunks.clear();\n\n this.handlers.onCancel?.();\n }\n\n /**\n * Handle chunk acknowledgment from peer\n */\n handleChunkAck(ack: ChunkAck): void {\n const pending = this.pendingChunks.get(ack.sequenceNumber);\n if (pending) {\n clearTimeout(pending.timeout);\n this.pendingChunks.delete(ack.sequenceNumber);\n this.chunksAcknowledged++;\n this.chunksInFlight--;\n\n // Update window size\n this.currentWindowSize += ack.bytesAcknowledged;\n\n // Resolve pending ack callback\n const callback = this.chunkAckCallbacks.get(ack.sequenceNumber);\n if (callback) {\n callback();\n this.chunkAckCallbacks.delete(ack.sequenceNumber);\n }\n }\n }\n\n /**\n * Update flow control window\n */\n updateWindow(newWindowSize: number): void {\n this.currentWindowSize = newWindowSize;\n this.stream.updateSendWindow(newWindowSize);\n }\n\n // =============================================================================\n // Private Methods\n // =============================================================================\n\n private setupStreamHandlers(): void {\n const _streamHandlers: StreamEventHandlers = {\n onData: async (chunk) => {\n // Handle incoming data for downloads\n if (this.direction === 'download' && this.dataSink) {\n await this.dataSink(chunk.data);\n\n // Send acknowledgment\n await this.sendChunkAck(chunk.sequenceNumber ?? 0, chunk.data.length);\n }\n },\n onBackpressure: (active) => {\n this.handlers.onBackpressure?.(active);\n },\n onProgress: (progress) => {\n this.handlers.onProgress?.(progress);\n },\n onError: (error) => {\n this.handleError(error);\n },\n };\n\n // Note: Stream handlers are set during construction\n // This is a simplified implementation\n }\n\n private async performUpload(): Promise<void> {\n if (!this.dataSource) {\n throw new Error('No data source set for upload');\n }\n\n if (Symbol.asyncIterator in this.dataSource) {\n // AsyncIterable source\n for await (const data of this.dataSource as AsyncIterable<Uint8Array>) {\n if (this.state !== 'transferring') {\n break;\n }\n\n await this.sendChunkWithFlowControl(data);\n }\n } else {\n // Function source\n const sourceFn = this.dataSource as () => Promise<Uint8Array | null>;\n while (this.state === 'transferring') {\n const data = await sourceFn();\n if (!data || data.length === 0) {\n break;\n }\n\n await this.sendChunkWithFlowControl(data);\n }\n }\n\n // Wait for all chunks to be acknowledged\n await this.waitForAllAcks();\n }\n\n private async performDownload(): Promise<void> {\n if (!this.dataSink) {\n throw new Error('No data sink set for download');\n }\n\n // Download is handled by onData callback\n // Just wait for completion\n while (this.state === 'transferring') {\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n }\n\n private async sendChunkWithFlowControl(data: Uint8Array): Promise<void> {\n // Wait for available window\n while (this.chunksInFlight >= (this.config.maxConcurrentChunks ?? 8)) {\n if (this.state !== 'transferring') {\n return;\n }\n await new Promise((resolve) => setTimeout(resolve, 10));\n }\n\n // Wait for stream to be ready (backpressure)\n await this.stream.ready();\n\n const sequenceNumber = this.totalChunks++;\n\n // Send the chunk\n await this.stream.send(data, false);\n this.chunksInFlight++;\n\n // Set up acknowledgment timeout\n const timeout = setTimeout(() => {\n this.handleChunkTimeout(sequenceNumber);\n }, this.config.chunkAckTimeoutMs ?? 30000);\n\n this.pendingChunks.set(sequenceNumber, {\n chunk: { data, sequenceNumber, timestamp: Date.now() },\n timeout,\n });\n }\n\n private async sendChunkAck(_sequenceNumber: number, _bytes: number): Promise<void> {\n // Send acknowledgment to peer\n // This would be implemented via the RPC connection\n }\n\n private handleChunkTimeout(sequenceNumber: number): void {\n const pending = this.pendingChunks.get(sequenceNumber);\n if (pending) {\n this.pendingChunks.delete(sequenceNumber);\n this.chunksInFlight--;\n\n // Could implement retry logic here\n this.handleError(new Error(`Chunk ${sequenceNumber} acknowledgment timeout`));\n }\n }\n\n private async waitForAllAcks(): Promise<void> {\n // In a real implementation, we would wait for acknowledgments from the peer\n // For now, just clear pending chunks immediately (simulating immediate ack)\n // This allows the transfer to complete without actual network acknowledgments\n for (const [sequenceNumber, { timeout }] of this.pendingChunks) {\n clearTimeout(timeout);\n this.handleChunkAck({\n sequenceNumber,\n bytesAcknowledged: 0, // Unknown, but doesn't matter for completion\n });\n }\n this.pendingChunks.clear();\n }\n\n private handleError(error: Error): void {\n if (this.state === 'completed' || this.state === 'error') {\n return;\n }\n\n this.error = error;\n this.state = 'error';\n this.endTime = Date.now();\n\n // Clear pending timeouts\n for (const { timeout } of this.pendingChunks.values()) {\n clearTimeout(timeout);\n }\n\n this.handlers.onError?.(error);\n }\n}\n\n/**\n * Bulk transfer manager\n *\n * Manages multiple concurrent bulk transfers.\n */\nexport class BulkTransferManager {\n private transfers: Map<string, BulkTransfer> = new Map();\n private streams: Map<number, Stream> = new Map();\n private nextStreamId = 1;\n\n /**\n * Create a new bulk transfer\n */\n createTransfer(\n direction: BulkTransferDirection,\n metadata: BulkTransferMetadata,\n config?: Partial<BulkTransferConfig>,\n handlers?: BulkTransferHandlers\n ): BulkTransfer {\n const streamId = this.nextStreamId++;\n\n const streamOptions: StreamOptions = {\n streamId,\n direction: direction === 'upload' ? 'outbound' : 'inbound',\n priority: StreamPriority.NORMAL,\n enableProgress: config?.enableProgress ?? true,\n progressInterval: config?.progressInterval,\n flowControl: config?.flowControl,\n };\n\n const stream = new Stream(streamOptions, {\n onProgress: handlers?.onProgress,\n onBackpressure: handlers?.onBackpressure,\n onError: handlers?.onError,\n });\n\n this.streams.set(streamId, stream);\n\n const transfer = new BulkTransfer(stream, direction, metadata, config, handlers);\n this.transfers.set(metadata.id, transfer);\n\n return transfer;\n }\n\n /**\n * Get a transfer by ID\n */\n getTransfer(id: string): BulkTransfer | undefined {\n return this.transfers.get(id);\n }\n\n /**\n * Get a stream by ID\n */\n getStream(id: number): Stream | undefined {\n return this.streams.get(id);\n }\n\n /**\n * Remove a transfer\n */\n removeTransfer(id: string): boolean {\n const transfer = this.transfers.get(id);\n if (transfer) {\n transfer.cancel();\n this.transfers.delete(id);\n return true;\n }\n return false;\n }\n\n /**\n * Get all active transfers\n */\n getActiveTransfers(): BulkTransfer[] {\n return Array.from(this.transfers.values()).filter(\n (t) =>\n t.currentState === 'pending' ||\n t.currentState === 'transferring' ||\n t.currentState === 'paused'\n );\n }\n\n /**\n * Get transfer statistics summary\n */\n getStatsSummary(): {\n totalTransfers: number;\n activeTransfers: number;\n completedTransfers: number;\n totalBytesTransferred: number;\n } {\n const transfers = Array.from(this.transfers.values());\n const active = transfers.filter((t) => t.currentState === 'transferring');\n const completed = transfers.filter((t) => t.currentState === 'completed');\n\n const totalBytes = transfers.reduce((sum, t) => sum + t.stats.bytesTransferred, 0);\n\n return {\n totalTransfers: transfers.length,\n activeTransfers: active.length,\n completedTransfers: completed.length,\n totalBytesTransferred: totalBytes,\n };\n }\n\n /**\n * Close all transfers\n */\n async closeAll(): Promise<void> {\n for (const transfer of this.transfers.values()) {\n transfer.cancel();\n }\n this.transfers.clear();\n this.streams.clear();\n }\n}\n\n/**\n * Create a bulk transfer manager\n */\nexport function createBulkTransferManager(): BulkTransferManager {\n return new BulkTransferManager();\n}\n","/**\n * Realtime API - Real-time communication with prioritization\n *\n * Phase 5: Flow Control and Realtime Communication\n *\n * Features:\n * - Message priority queues\n * - Message drop policies for latency-sensitive scenarios\n * - Bandwidth adaptation\n * - Jitter buffer management\n */\n\nimport {\n type FlowControlConfig,\n type Stream,\n type StreamChunk,\n type StreamOptions,\n StreamPriority,\n} from './stream.js';\n\n/** Message priority levels (extends StreamPriority) */\nexport { StreamPriority as MessagePriority };\n\n/** Message drop policy for latency-sensitive scenarios */\nexport enum DropPolicy {\n /** Never drop messages */\n NEVER = 'never',\n /** Drop oldest messages when queue is full */\n DROP_OLDEST = 'drop_oldest',\n /** Drop newest messages when queue is full */\n DROP_NEWEST = 'drop_newest',\n /** Drop low priority messages first */\n DROP_LOW_PRIORITY = 'drop_low_priority',\n /** Drop messages that exceed max latency */\n DROP_STALE = 'drop_stale',\n}\n\n/** Realtime stream configuration */\nexport interface RealtimeConfig {\n /** Target latency in milliseconds */\n targetLatencyMs: number;\n /** Maximum acceptable latency in milliseconds */\n maxLatencyMs: number;\n /** Jitter buffer size in milliseconds */\n jitterBufferMs: number;\n /** Message queue size limit */\n maxQueueSize: number;\n /** Drop policy for queue management */\n dropPolicy: DropPolicy;\n /** Enable adaptive bitrate */\n adaptiveBitrate: boolean;\n /** Minimum bitrate in bytes per second */\n minBitrate: number;\n /** Maximum bitrate in bytes per second */\n maxBitrate: number;\n /** Bandwidth measurement window in milliseconds */\n bandwidthWindowMs: number;\n}\n\n/** Default realtime configuration */\nexport const DEFAULT_REALTIME_CONFIG: RealtimeConfig = {\n targetLatencyMs: 50,\n maxLatencyMs: 200,\n jitterBufferMs: 30,\n maxQueueSize: 1000,\n dropPolicy: DropPolicy.DROP_STALE,\n adaptiveBitrate: true,\n minBitrate: 16000, // 16 KB/s\n maxBitrate: 10485760, // 10 MB/s\n bandwidthWindowMs: 1000,\n};\n\n/** Realtime message */\nexport interface RealtimeMessage {\n /** Message ID */\n id: string;\n /** Message priority */\n priority: StreamPriority;\n /** Message timestamp */\n timestamp: number;\n /** Message data */\n data: Uint8Array;\n /** Message type/category */\n type?: string;\n /** Sequence number for ordering */\n sequenceNumber: number;\n /** Whether message is critical (cannot be dropped) */\n critical?: boolean;\n}\n\n/** Bandwidth statistics */\nexport interface BandwidthStats {\n /** Current bitrate in bytes per second */\n currentBitrate: number;\n /** Measured bandwidth in bytes per second */\n measuredBandwidth: number;\n /** Packet loss rate (0-1) */\n packetLossRate: number;\n /** Average latency in milliseconds */\n averageLatencyMs: number;\n /** Jitter in milliseconds */\n jitterMs: number;\n /** Congestion level (0-1) */\n congestionLevel: number;\n}\n\n/** Jitter buffer entry */\ninterface JitterBufferEntry {\n message: RealtimeMessage;\n receivedAt: number;\n playoutTime: number;\n}\n\n/** Realtime stream event handlers */\nexport interface RealtimeStreamHandlers {\n /** Called when a message is received */\n onMessage?: (message: RealtimeMessage) => void | Promise<void>;\n /** Called when messages are dropped */\n onDrop?: (messages: RealtimeMessage[], reason: string) => void;\n /** Called when bandwidth is adapted */\n onBandwidthAdapt?: (newBitrate: number, stats: BandwidthStats) => void;\n /** Called when latency changes */\n onLatencyChange?: (latencyMs: number) => void;\n /** Called when stream is ready to play */\n onReady?: () => void;\n /** Called on error */\n onError?: (error: Error) => void;\n}\n\n/**\n * Priority queue for realtime messages\n */\nclass PriorityMessageQueue {\n private queues: Map<StreamPriority, RealtimeMessage[]> = new Map();\n private totalSize = 0;\n private maxSize: number;\n private dropPolicy: DropPolicy;\n private maxLatencyMs: number;\n\n constructor(maxSize: number, dropPolicy: DropPolicy, maxLatencyMs: number) {\n this.maxSize = maxSize;\n this.dropPolicy = dropPolicy;\n this.maxLatencyMs = maxLatencyMs;\n\n // Initialize queues for each priority level\n for (let i = 0; i <= 4; i++) {\n this.queues.set(i as StreamPriority, []);\n }\n }\n\n /** Get total queue size */\n get size(): number {\n return this.totalSize;\n }\n\n /** Check if queue is empty */\n get isEmpty(): boolean {\n return this.totalSize === 0;\n }\n\n /** Enqueue a message */\n enqueue(message: RealtimeMessage): boolean {\n // Check if message is stale\n if (this.dropPolicy === DropPolicy.DROP_STALE) {\n const age = Date.now() - message.timestamp;\n if (age > this.maxLatencyMs && !message.critical) {\n return false; // Message dropped\n }\n }\n\n // Check if queue is full\n if (this.totalSize >= this.maxSize) {\n if (!this.handleQueueFull(message)) {\n return false;\n }\n }\n\n const queue = this.queues.get(message.priority)!;\n queue.push(message);\n this.totalSize++;\n\n return true;\n }\n\n /** Dequeue the highest priority message */\n dequeue(): RealtimeMessage | undefined {\n // Check queues from highest to lowest priority\n for (let priority = 0; priority <= 4; priority++) {\n const queue = this.queues.get(priority as StreamPriority)!;\n if (queue.length > 0) {\n this.totalSize--;\n return queue.shift()!;\n }\n }\n return undefined;\n }\n\n /** Peek at the highest priority message without removing */\n peek(): RealtimeMessage | undefined {\n for (let priority = 0; priority <= 4; priority++) {\n const queue = this.queues.get(priority as StreamPriority)!;\n if (queue.length > 0) {\n return queue[0];\n }\n }\n return undefined;\n }\n\n /** Remove stale messages */\n removeStale(): RealtimeMessage[] {\n const now = Date.now();\n const removed: RealtimeMessage[] = [];\n\n for (const [priority, queue] of this.queues) {\n const remaining: RealtimeMessage[] = [];\n for (const msg of queue) {\n if (now - msg.timestamp <= this.maxLatencyMs || msg.critical) {\n remaining.push(msg);\n } else {\n removed.push(msg);\n this.totalSize--;\n }\n }\n this.queues.set(priority, remaining);\n }\n\n return removed;\n }\n\n /** Clear all messages */\n clear(): RealtimeMessage[] {\n const all: RealtimeMessage[] = [];\n for (const queue of this.queues.values()) {\n all.push(...queue);\n }\n for (const queue of this.queues.values()) {\n queue.length = 0;\n }\n this.totalSize = 0;\n return all;\n }\n\n private handleQueueFull(newMessage: RealtimeMessage): boolean {\n switch (this.dropPolicy) {\n case DropPolicy.NEVER:\n return false;\n\n case DropPolicy.DROP_OLDEST:\n // Remove oldest message from lowest priority queue\n for (let priority = 4; priority >= 0; priority--) {\n const queue = this.queues.get(priority as StreamPriority)!;\n if (queue.length > 0 && priority >= newMessage.priority) {\n queue.shift();\n this.totalSize--;\n return true;\n }\n }\n return false;\n\n case DropPolicy.DROP_NEWEST:\n // Don't add the new message if it's lower priority\n if (newMessage.priority >= StreamPriority.NORMAL) {\n return false;\n }\n return true;\n\n case DropPolicy.DROP_LOW_PRIORITY:\n // Remove a message from lower priority than the new message\n for (let priority = 4; priority > newMessage.priority; priority--) {\n const queue = this.queues.get(priority as StreamPriority)!;\n if (queue.length > 0) {\n queue.shift();\n this.totalSize--;\n return true;\n }\n }\n return false;\n\n case DropPolicy.DROP_STALE: {\n // Remove stale messages first\n const stale = this.removeStale();\n if (stale.length > 0) {\n return true;\n }\n // Fall through to DROP_OLDEST\n for (let priority = 4; priority >= 0; priority--) {\n const queue = this.queues.get(priority as StreamPriority)!;\n if (queue.length > 0 && priority >= newMessage.priority) {\n queue.shift();\n this.totalSize--;\n return true;\n }\n }\n return false;\n }\n\n default:\n return false;\n }\n }\n}\n\n/**\n * Realtime stream for low-latency communication\n *\n * Manages message prioritization, jitter buffering, and bandwidth adaptation.\n */\nexport class RealtimeStream {\n private stream: Stream;\n private config: RealtimeConfig;\n private handlers: RealtimeStreamHandlers;\n\n // Message queues\n private sendQueue: PriorityMessageQueue;\n private receiveQueue: PriorityMessageQueue;\n\n // Jitter buffer\n private jitterBuffer: JitterBufferEntry[] = [];\n private jitterBufferTargetSize: number;\n\n // Bandwidth adaptation\n private bandwidthStats: BandwidthStats = {\n currentBitrate: 0,\n measuredBandwidth: 0,\n packetLossRate: 0,\n averageLatencyMs: 0,\n jitterMs: 0,\n congestionLevel: 0,\n };\n private bitrateHistory: number[] = [];\n private latencyHistory: number[] = [];\n private lastBandwidthUpdate = 0;\n\n // Sequence numbers\n private nextSendSequence = 0;\n private nextExpectedSequence = 0;\n private receivedSequences: Set<number> = new Set();\n\n // State\n private isRunning = false;\n private sendInterval?: ReturnType<typeof setInterval>;\n private jitterInterval?: ReturnType<typeof setInterval>;\n private bandwidthInterval?: ReturnType<typeof setInterval>;\n\n constructor(\n stream: Stream,\n config: Partial<RealtimeConfig> = {},\n handlers: RealtimeStreamHandlers = {}\n ) {\n this.stream = stream;\n this.config = { ...DEFAULT_REALTIME_CONFIG, ...config };\n this.handlers = handlers;\n\n this.sendQueue = new PriorityMessageQueue(\n this.config.maxQueueSize,\n this.config.dropPolicy,\n this.config.maxLatencyMs\n );\n\n this.receiveQueue = new PriorityMessageQueue(\n this.config.maxQueueSize,\n this.config.dropPolicy,\n this.config.maxLatencyMs\n );\n\n // Calculate jitter buffer target size based on jitter buffer time\n this.jitterBufferTargetSize = Math.ceil(\n this.config.jitterBufferMs / this.config.targetLatencyMs\n );\n\n this.setupStreamHandlers();\n }\n\n /** Get current bandwidth statistics */\n get stats(): BandwidthStats {\n return { ...this.bandwidthStats };\n }\n\n /** Get current send queue size */\n get sendQueueSize(): number {\n return this.sendQueue.size;\n }\n\n /** Get current receive queue size */\n get receiveQueueSize(): number {\n return this.receiveQueue.size;\n }\n\n /** Get jitter buffer size */\n get jitterBufferSize(): number {\n return this.jitterBuffer.length;\n }\n\n /**\n * Start the realtime stream\n */\n start(): void {\n if (this.isRunning) return;\n\n this.isRunning = true;\n\n // Start send loop\n this.sendInterval = setInterval(() => {\n this.processSendQueue();\n }, this.config.targetLatencyMs / 2);\n\n // Start jitter buffer processing\n this.jitterInterval = setInterval(() => {\n this.processJitterBuffer();\n }, this.config.targetLatencyMs / 4);\n\n // Start bandwidth monitoring\n if (this.config.adaptiveBitrate) {\n this.bandwidthInterval = setInterval(() => {\n this.updateBandwidthStats();\n }, this.config.bandwidthWindowMs);\n }\n\n this.handlers.onReady?.();\n }\n\n /**\n * Stop the realtime stream\n */\n stop(): void {\n this.isRunning = false;\n\n if (this.sendInterval) {\n clearInterval(this.sendInterval);\n this.sendInterval = undefined;\n }\n\n if (this.jitterInterval) {\n clearInterval(this.jitterInterval);\n this.jitterInterval = undefined;\n }\n\n if (this.bandwidthInterval) {\n clearInterval(this.bandwidthInterval);\n this.bandwidthInterval = undefined;\n }\n\n // Clear queues\n const dropped = this.sendQueue.clear();\n if (dropped.length > 0) {\n this.handlers.onDrop?.(dropped, 'stream stopped');\n }\n }\n\n /**\n * Send a realtime message\n */\n sendMessage(\n data: Uint8Array,\n priority: StreamPriority = StreamPriority.NORMAL,\n options: { type?: string; critical?: boolean } = {}\n ): boolean {\n if (!this.isRunning) {\n return false;\n }\n\n const message: RealtimeMessage = {\n id: this.generateMessageId(),\n priority,\n timestamp: Date.now(),\n data,\n type: options.type,\n sequenceNumber: this.nextSendSequence++,\n critical: options.critical,\n };\n\n const enqueued = this.sendQueue.enqueue(message);\n\n if (!enqueued) {\n this.handlers.onDrop?.([message], 'queue full');\n return false;\n }\n\n return true;\n }\n\n /**\n * Receive the next message (blocking)\n */\n async receiveMessage(): Promise<RealtimeMessage | undefined> {\n return new Promise((resolve) => {\n const checkQueue = () => {\n const message = this.receiveQueue.dequeue();\n if (message) {\n resolve(message);\n } else if (!this.isRunning) {\n resolve(undefined);\n } else {\n setTimeout(checkQueue, 5);\n }\n };\n checkQueue();\n });\n }\n\n /**\n * Set target bitrate (for manual bitrate control)\n */\n setTargetBitrate(bitrate: number): void {\n this.bandwidthStats.currentBitrate = Math.max(\n this.config.minBitrate,\n Math.min(this.config.maxBitrate, bitrate)\n );\n }\n\n // =============================================================================\n // Private Methods\n // =============================================================================\n\n private setupStreamHandlers(): void {\n // Set up stream data handler\n const originalOnData = (\n this.stream as unknown as { handlers?: { onData?: (chunk: StreamChunk) => void } }\n ).handlers?.onData;\n\n (this.stream as unknown as { handlers: { onData?: (chunk: StreamChunk) => void } }).handlers = {\n ...(this.stream as unknown as { handlers: { onData?: (chunk: StreamChunk) => void } })\n .handlers,\n onData: (chunk: StreamChunk) => {\n this.handleIncomingData(chunk);\n originalOnData?.(chunk);\n },\n };\n }\n\n private handleIncomingData(chunk: StreamChunk): void {\n try {\n // Parse message from chunk\n const message = this.deserializeMessage(chunk.data);\n\n // Track sequence number for packet loss calculation\n if (message.sequenceNumber > this.nextExpectedSequence) {\n // Packet loss detected\n const lost = message.sequenceNumber - this.nextExpectedSequence;\n this.bandwidthStats.packetLossRate = this.bandwidthStats.packetLossRate * 0.9 + lost * 0.1;\n }\n this.nextExpectedSequence = message.sequenceNumber + 1;\n\n // Calculate latency\n const latency = Date.now() - message.timestamp;\n this.latencyHistory.push(latency);\n if (this.latencyHistory.length > 100) {\n this.latencyHistory.shift();\n }\n\n // Add to jitter buffer\n const playoutTime = Date.now() + this.config.jitterBufferMs;\n this.jitterBuffer.push({\n message,\n receivedAt: Date.now(),\n playoutTime,\n });\n\n // Sort jitter buffer by sequence number\n this.jitterBuffer.sort((a, b) => a.message.sequenceNumber - b.message.sequenceNumber);\n } catch (error) {\n this.handlers.onError?.(error as Error);\n }\n }\n\n private processSendQueue(): void {\n if (!this.isRunning || this.sendQueue.isEmpty) {\n return;\n }\n\n // Check bandwidth limit\n if (this.config.adaptiveBitrate) {\n const currentBitrate = this.bandwidthStats.currentBitrate;\n const maxBytesPerInterval = (currentBitrate * this.config.targetLatencyMs) / 1000 / 2;\n\n let bytesSent = 0;\n while (bytesSent < maxBytesPerInterval) {\n const message = this.sendQueue.dequeue();\n if (!message) break;\n\n this.sendMessageToStream(message);\n bytesSent += message.data.length;\n }\n } else {\n // Send one message per interval\n const message = this.sendQueue.dequeue();\n if (message) {\n this.sendMessageToStream(message);\n }\n }\n\n // Remove stale messages from queue\n if (this.config.dropPolicy === DropPolicy.DROP_STALE) {\n const stale = this.sendQueue.removeStale();\n if (stale.length > 0) {\n this.handlers.onDrop?.(stale, 'stale');\n }\n }\n }\n\n private sendMessageToStream(message: RealtimeMessage): void {\n try {\n const data = this.serializeMessage(message);\n this.stream.send(data).catch((err) => {\n this.handlers.onError?.(err);\n });\n\n // Track bitrate\n this.bitrateHistory.push(data.length);\n if (this.bitrateHistory.length > 100) {\n this.bitrateHistory.shift();\n }\n } catch (error) {\n this.handlers.onError?.(error as Error);\n }\n }\n\n private processJitterBuffer(): void {\n if (!this.isRunning || this.jitterBuffer.length === 0) {\n return;\n }\n\n const now = Date.now();\n\n // Process messages that have reached their playout time\n while (this.jitterBuffer.length > 0) {\n const entry = this.jitterBuffer[0];\n\n // Wait until we have enough messages in the buffer\n if (this.jitterBuffer.length < this.jitterBufferTargetSize && entry.playoutTime > now) {\n break;\n }\n\n if (entry.playoutTime <= now) {\n this.jitterBuffer.shift();\n this.receiveQueue.enqueue(entry.message);\n this.handlers.onMessage?.(entry.message);\n } else {\n break;\n }\n }\n\n // Remove stale messages from jitter buffer\n const maxAge = this.config.maxLatencyMs * 2;\n const stale: RealtimeMessage[] = [];\n this.jitterBuffer = this.jitterBuffer.filter((entry) => {\n if (now - entry.receivedAt > maxAge && !entry.message.critical) {\n stale.push(entry.message);\n return false;\n }\n return true;\n });\n\n if (stale.length > 0) {\n this.handlers.onDrop?.(stale, 'jitter buffer stale');\n }\n }\n\n private updateBandwidthStats(): void {\n const now = Date.now();\n const windowMs = this.config.bandwidthWindowMs;\n\n // Calculate measured bandwidth\n if (this.bitrateHistory.length >= 2) {\n const totalBytes = this.bitrateHistory.reduce((a, b) => a + b, 0);\n this.bandwidthStats.measuredBandwidth = (totalBytes / windowMs) * 1000;\n }\n\n // Calculate average latency\n if (this.latencyHistory.length > 0) {\n const avgLatency =\n this.latencyHistory.reduce((a, b) => a + b, 0) / this.latencyHistory.length;\n this.bandwidthStats.averageLatencyMs = avgLatency;\n\n // Calculate jitter (standard deviation of latency)\n const variance =\n this.latencyHistory.reduce((sum, lat) => sum + (lat - avgLatency) ** 2, 0) /\n this.latencyHistory.length;\n this.bandwidthStats.jitterMs = Math.sqrt(variance);\n\n this.handlers.onLatencyChange?.(avgLatency);\n }\n\n // Calculate congestion level\n const queueUtilization = this.sendQueue.size / this.config.maxQueueSize;\n const latencyRatio = this.bandwidthStats.averageLatencyMs / this.config.targetLatencyMs;\n this.bandwidthStats.congestionLevel = Math.min(1, (queueUtilization + latencyRatio) / 2);\n\n // Adapt bitrate\n if (this.config.adaptiveBitrate) {\n this.adaptBitrate();\n }\n\n this.lastBandwidthUpdate = now;\n }\n\n private adaptBitrate(): void {\n const { congestionLevel, packetLossRate } = this.bandwidthStats;\n let newBitrate = this.bandwidthStats.currentBitrate;\n\n if (congestionLevel > 0.7 || packetLossRate > 0.05) {\n // Decrease bitrate\n newBitrate = newBitrate * 0.8;\n } else if (congestionLevel < 0.3 && packetLossRate < 0.01) {\n // Increase bitrate\n newBitrate = newBitrate * 1.05;\n }\n\n // Clamp to min/max\n newBitrate = Math.max(this.config.minBitrate, Math.min(this.config.maxBitrate, newBitrate));\n\n if (newBitrate !== this.bandwidthStats.currentBitrate) {\n this.bandwidthStats.currentBitrate = newBitrate;\n this.handlers.onBandwidthAdapt?.(newBitrate, this.bandwidthStats);\n }\n }\n\n private serializeMessage(message: RealtimeMessage): Uint8Array {\n // Simple serialization: JSON header + binary data\n const header = JSON.stringify({\n id: message.id,\n priority: message.priority,\n timestamp: message.timestamp,\n type: message.type,\n sequenceNumber: message.sequenceNumber,\n critical: message.critical,\n dataLength: message.data.length,\n });\n\n const headerBytes = new TextEncoder().encode(header);\n const headerLength = new Uint8Array(4);\n new DataView(headerLength.buffer).setUint32(0, headerBytes.length, true);\n\n const result = new Uint8Array(4 + headerBytes.length + message.data.length);\n result.set(headerLength, 0);\n result.set(headerBytes, 4);\n result.set(message.data, 4 + headerBytes.length);\n\n return result;\n }\n\n private deserializeMessage(data: Uint8Array): RealtimeMessage {\n const headerLength = new DataView(data.buffer, data.byteOffset, 4).getUint32(0, true);\n const headerBytes = data.slice(4, 4 + headerLength);\n const header = JSON.parse(new TextDecoder().decode(headerBytes));\n\n return {\n id: header.id,\n priority: header.priority,\n timestamp: header.timestamp,\n type: header.type,\n sequenceNumber: header.sequenceNumber,\n critical: header.critical,\n data: data.slice(4 + headerLength, 4 + headerLength + header.dataLength),\n };\n }\n\n private generateMessageId(): string {\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n}\n\n/**\n * Realtime stream manager\n */\nexport class RealtimeStreamManager {\n private streams: Map<number, RealtimeStream> = new Map();\n private nextStreamId = 1;\n\n /**\n * Create a new realtime stream\n */\n createStream(\n baseStream: Stream,\n config?: Partial<RealtimeConfig>,\n handlers?: RealtimeStreamHandlers\n ): RealtimeStream {\n const streamId = this.nextStreamId++;\n const stream = new RealtimeStream(baseStream, config, handlers);\n this.streams.set(streamId, stream);\n return stream;\n }\n\n /**\n * Get a stream by ID\n */\n getStream(id: number): RealtimeStream | undefined {\n return this.streams.get(id);\n }\n\n /**\n * Remove a stream\n */\n removeStream(id: number): boolean {\n const stream = this.streams.get(id);\n if (stream) {\n stream.stop();\n this.streams.delete(id);\n return true;\n }\n return false;\n }\n\n /**\n * Get all active streams\n */\n getActiveStreams(): RealtimeStream[] {\n return Array.from(this.streams.values());\n }\n\n /**\n * Stop all streams\n */\n stopAll(): void {\n for (const stream of this.streams.values()) {\n stream.stop();\n }\n this.streams.clear();\n }\n}\n\n/**\n * Create a realtime stream manager\n */\nexport function createRealtimeStreamManager(): RealtimeStreamManager {\n return new RealtimeStreamManager();\n}\n","/**\n * Stream Management - Unified stream lifecycle management\n *\n * Phase 5: Flow Control and Realtime Communication\n *\n * Manages:\n * - Stream creation and registration\n * - Bidirectional stream support\n * - Stream lifecycle (open, close, error handling)\n * - Stream multiplexing over a single connection\n */\n\nimport {\n type BulkTransfer,\n type BulkTransferConfig,\n BulkTransferManager,\n type BulkTransferMetadata,\n} from './bulk.js';\nimport {\n type RealtimeConfig,\n type RealtimeStream,\n type RealtimeStreamHandlers,\n RealtimeStreamManager,\n} from './realtime.js';\nimport type { RpcConnection } from './rpc-connection.js';\nimport {\n Stream,\n type StreamDirection,\n type StreamOptions,\n StreamPriority,\n type StreamState,\n} from './stream.js';\nimport type { RpcTransport } from './transport.js';\n\n/** Stream type */\nexport enum StreamType {\n /** Standard stream */\n STANDARD = 'standard',\n /** Bulk transfer stream */\n BULK = 'bulk',\n /** Realtime stream */\n REALTIME = 'realtime',\n}\n\n/** Stream info */\nexport interface StreamInfo {\n /** Stream ID */\n id: number;\n /** Stream type */\n type: StreamType;\n /** Stream direction */\n direction: StreamDirection;\n /** Stream priority */\n priority: StreamPriority;\n /** Current state */\n state: StreamState;\n /** Creation timestamp */\n createdAt: number;\n /** Bytes transferred */\n bytesTransferred: number;\n /** Metadata */\n metadata?: Record<string, string>;\n}\n\n/** Stream manager configuration */\nexport interface StreamManagerConfig {\n /** Maximum number of concurrent streams */\n maxStreams: number;\n /** Default stream priority */\n defaultPriority: StreamPriority;\n /** Enable stream multiplexing */\n enableMultiplexing: boolean;\n /** Idle timeout in milliseconds */\n idleTimeoutMs: number;\n}\n\n/** Default stream manager configuration */\nexport const DEFAULT_STREAM_MANAGER_CONFIG: StreamManagerConfig = {\n maxStreams: 100,\n defaultPriority: StreamPriority.NORMAL,\n enableMultiplexing: true,\n idleTimeoutMs: 300000, // 5 minutes\n};\n\n/** Stream creation options */\nexport interface CreateStreamOptions {\n /** Stream type */\n type?: StreamType;\n /** Stream direction */\n direction?: StreamDirection;\n /** Stream priority */\n priority?: StreamPriority;\n /** Stream metadata */\n metadata?: Record<string, string>;\n /** Flow control configuration */\n flowControl?: Partial<import('./stream.js').FlowControlConfig>;\n}\n\n/** Stream manager event handlers */\nexport interface StreamManagerHandlers {\n /** Called when a stream is created */\n onStreamCreate?: (info: StreamInfo) => void;\n /** Called when a stream is opened */\n onStreamOpen?: (info: StreamInfo) => void;\n /** Called when a stream is closed */\n onStreamClose?: (info: StreamInfo) => void;\n /** Called when a stream errors */\n onStreamError?: (info: StreamInfo, error: Error) => void;\n /** Called when stream count changes */\n onStreamCountChange?: (count: number) => void;\n}\n\n/**\n * Stream manager\n *\n * Manages all streams for an RPC connection.\n */\nexport class StreamManager {\n private config: StreamManagerConfig;\n private handlers: StreamManagerHandlers;\n private connection?: RpcConnection;\n private transport?: RpcTransport;\n\n // Stream registries\n private streams: Map<number, Stream> = new Map();\n private streamTypes: Map<number, StreamType> = new Map();\n private streamInfos: Map<number, StreamInfo> = new Map();\n private nextStreamId = 1;\n\n // Sub-managers\n private bulkManager: BulkTransferManager;\n private realtimeManager: RealtimeStreamManager;\n\n // Lifecycle\n private idleTimeout?: ReturnType<typeof setTimeout>;\n private isRunning = false;\n\n constructor(config: Partial<StreamManagerConfig> = {}, handlers: StreamManagerHandlers = {}) {\n this.config = { ...DEFAULT_STREAM_MANAGER_CONFIG, ...config };\n this.handlers = handlers;\n this.bulkManager = new BulkTransferManager();\n this.realtimeManager = new RealtimeStreamManager();\n }\n\n /** Get the number of active streams */\n get streamCount(): number {\n return this.streams.size;\n }\n\n /** Get the maximum number of streams */\n get maxStreams(): number {\n return this.config.maxStreams;\n }\n\n /** Get all stream infos */\n get allStreamInfos(): StreamInfo[] {\n return Array.from(this.streamInfos.values());\n }\n\n /**\n * Attach to an RPC connection\n */\n attach(connection: RpcConnection, transport?: RpcTransport): void {\n this.connection = connection;\n this.transport = transport;\n this.isRunning = true;\n this.resetIdleTimeout();\n }\n\n /**\n * Detach from connection\n */\n detach(): void {\n this.closeAllStreams();\n this.isRunning = false;\n this.connection = undefined;\n this.transport = undefined;\n\n if (this.idleTimeout) {\n clearTimeout(this.idleTimeout);\n this.idleTimeout = undefined;\n }\n }\n\n /**\n * Create a new stream\n */\n createStream(options: CreateStreamOptions = {}): Stream {\n if (this.streams.size >= this.config.maxStreams) {\n throw new Error(`Maximum number of streams (${this.config.maxStreams}) reached`);\n }\n\n const streamId = this.nextStreamId++;\n const type = options.type ?? StreamType.STANDARD;\n\n const streamOptions: StreamOptions = {\n streamId,\n direction: options.direction ?? 'bidirectional',\n priority: options.priority ?? this.config.defaultPriority ?? StreamPriority.NORMAL,\n metadata: options.metadata,\n flowControl: options.flowControl,\n };\n\n const stream = new Stream(streamOptions, {\n onOpen: () => {\n this.updateStreamState(streamId, 'open');\n this.handlers.onStreamOpen?.(this.getStreamInfo(streamId)!);\n },\n onClose: () => {\n this.updateStreamState(streamId, 'closed');\n this.handlers.onStreamClose?.(this.getStreamInfo(streamId)!);\n this.removeStream(streamId);\n },\n onError: (error) => {\n this.updateStreamState(streamId, 'error');\n const info = this.getStreamInfo(streamId);\n if (info) {\n this.handlers.onStreamError?.(info, error);\n }\n },\n });\n\n this.streams.set(streamId, stream);\n this.streamTypes.set(streamId, type);\n\n const info: StreamInfo = {\n id: streamId,\n type,\n direction: streamOptions.direction,\n priority: streamOptions.priority ?? StreamPriority.NORMAL,\n state: 'connecting',\n createdAt: Date.now(),\n bytesTransferred: 0,\n metadata: options.metadata,\n };\n this.streamInfos.set(streamId, info);\n\n this.handlers.onStreamCreate?.(info);\n this.handlers.onStreamCountChange?.(this.streams.size);\n\n this.resetIdleTimeout();\n\n return stream;\n }\n\n /**\n * Create a bulk transfer stream\n */\n createBulkStream(\n direction: 'upload' | 'download',\n metadata: BulkTransferMetadata,\n config?: Partial<BulkTransferConfig>,\n handlers?: import('./bulk.js').BulkTransferHandlers\n ): BulkTransfer {\n const _stream = this.createStream({\n type: StreamType.BULK,\n direction: direction === 'upload' ? 'outbound' : 'inbound',\n priority: StreamPriority.NORMAL,\n metadata: metadata.custom,\n });\n\n return this.bulkManager.createTransfer(direction, metadata, config, handlers);\n }\n\n /**\n * Create a realtime stream\n */\n createRealtimeStream(\n config?: Partial<RealtimeConfig>,\n handlers?: RealtimeStreamHandlers\n ): RealtimeStream {\n const stream = this.createStream({\n type: StreamType.REALTIME,\n direction: 'bidirectional',\n priority: StreamPriority.HIGH,\n });\n\n return this.realtimeManager.createStream(stream, config, handlers);\n }\n\n /**\n * Get a stream by ID\n */\n getStream(id: number): Stream | undefined {\n return this.streams.get(id);\n }\n\n /**\n * Get stream info by ID\n */\n getStreamInfo(id: number): StreamInfo | undefined {\n return this.streamInfos.get(id);\n }\n\n /**\n * Get stream type by ID\n */\n getStreamType(id: number): StreamType | undefined {\n return this.streamTypes.get(id);\n }\n\n /**\n * Get bulk transfer by ID\n */\n getBulkTransfer(id: string): BulkTransfer | undefined {\n return this.bulkManager.getTransfer(id);\n }\n\n /**\n * Get realtime stream by ID\n */\n getRealtimeStream(id: number): RealtimeStream | undefined {\n return this.realtimeManager.getStream(id);\n }\n\n /**\n * Close a specific stream\n */\n async closeStream(id: number): Promise<boolean> {\n const stream = this.streams.get(id);\n if (!stream) {\n return false;\n }\n\n await stream.close();\n this.removeStream(id);\n return true;\n }\n\n /**\n * Close all streams\n */\n async closeAllStreams(): Promise<void> {\n const closePromises: Promise<void>[] = [];\n\n for (const [_id, stream] of this.streams) {\n closePromises.push(\n stream.close().catch(() => {\n // Ignore errors during bulk close\n })\n );\n }\n\n await Promise.all(closePromises);\n\n this.streams.clear();\n this.streamTypes.clear();\n this.streamInfos.clear();\n this.bulkManager.closeAll();\n this.realtimeManager.stopAll();\n\n this.handlers.onStreamCountChange?.(0);\n }\n\n /**\n * Get streams by type\n */\n getStreamsByType(type: StreamType): StreamInfo[] {\n return this.allStreamInfos.filter((info) => info.type === type);\n }\n\n /**\n * Get streams by state\n */\n getStreamsByState(state: StreamState): StreamInfo[] {\n return this.allStreamInfos.filter((info) => info.state === state);\n }\n\n /**\n * Get statistics\n */\n getStatistics(): {\n totalStreams: number;\n activeStreams: number;\n streamsByType: Record<StreamType, number>;\n streamsByState: Record<StreamState, number>;\n totalBytesTransferred: number;\n } {\n const infos = this.allStreamInfos;\n const active = infos.filter((i) => i.state === 'open');\n\n const byType: Record<StreamType, number> = {\n [StreamType.STANDARD]: 0,\n [StreamType.BULK]: 0,\n [StreamType.REALTIME]: 0,\n };\n\n const byState: Record<StreamState, number> = {\n connecting: 0,\n open: 0,\n closing: 0,\n closed: 0,\n error: 0,\n };\n\n let totalBytes = 0;\n\n for (const info of infos) {\n byType[info.type]++;\n byState[info.state]++;\n totalBytes += info.bytesTransferred;\n }\n\n return {\n totalStreams: infos.length,\n activeStreams: active.length,\n streamsByType: byType,\n streamsByState: byState,\n totalBytesTransferred: totalBytes,\n };\n }\n\n /**\n * Update stream priority\n */\n updatePriority(id: number, priority: StreamPriority): boolean {\n const info = this.streamInfos.get(id);\n if (!info) {\n return false;\n }\n\n info.priority = priority;\n return true;\n }\n\n /**\n * Pause all streams (backpressure)\n */\n pauseAll(): void {\n for (const _stream of this.streams.values()) {\n // Streams don't have a direct pause method, but we can use backpressure\n // This is a simplified implementation\n }\n }\n\n /**\n * Resume all streams\n */\n resumeAll(): void {\n for (const _stream of this.streams.values()) {\n // Resume from backpressure\n }\n }\n\n // =============================================================================\n // Private Methods\n // =============================================================================\n\n private removeStream(id: number): void {\n this.streams.delete(id);\n this.streamTypes.delete(id);\n this.streamInfos.delete(id);\n\n this.handlers.onStreamCountChange?.(this.streams.size);\n this.resetIdleTimeout();\n }\n\n private updateStreamState(id: number, state: StreamState): void {\n const info = this.streamInfos.get(id);\n if (info) {\n info.state = state;\n }\n }\n\n private resetIdleTimeout(): void {\n if (this.idleTimeout) {\n clearTimeout(this.idleTimeout);\n }\n\n if (!this.isRunning || this.streams.size > 0) {\n return;\n }\n\n this.idleTimeout = setTimeout(() => {\n if (this.streams.size === 0) {\n // No active streams, could emit an event or take action\n }\n }, this.config.idleTimeoutMs);\n }\n}\n\n/**\n * Create a stream manager\n */\nexport function createStreamManager(\n config?: Partial<StreamManagerConfig>,\n handlers?: StreamManagerHandlers\n): StreamManager {\n return new StreamManager(config, handlers);\n}\n\n// Re-export types\nexport type { Stream, StreamOptions, StreamState, StreamDirection } from './stream.js';\nexport { StreamPriority } from './stream.js';\nexport type {\n BulkTransfer,\n BulkTransferConfig,\n BulkTransferMetadata,\n} from './bulk.js';\nexport { BulkTransferManager } from './bulk.js';\nexport type {\n RealtimeStream,\n RealtimeConfig,\n RealtimeStreamHandlers,\n} from './realtime.js';\nexport { RealtimeStreamManager } from './realtime.js';\n","/**\n * Streaming RpcConnection Extension\n *\n * Phase 5: Flow Control and Realtime Communication\n *\n * Extends RpcConnection with streaming capabilities:\n * - Stream creation and management\n * - Integration with existing Pipeline\n * * Stream capability negotiation\n */\n\nimport type { BulkTransferConfig, BulkTransferHandlers, BulkTransferMetadata } from './bulk.js';\nimport type { RealtimeConfig, RealtimeStreamHandlers } from './realtime.js';\nimport { RpcConnection, type RpcConnectionOptions } from './rpc-connection.js';\nimport type { ExportId, ImportId, RpcMessage } from './rpc-types.js';\nimport {\n type BulkTransfer,\n type CreateStreamOptions,\n type RealtimeStream,\n type Stream,\n StreamManager,\n type StreamManagerConfig,\n type StreamManagerHandlers,\n StreamType,\n} from './stream-manager.js';\nimport type { RpcTransport } from './transport.js';\n\n/** Streaming capability flags */\nexport interface StreamingCapabilities {\n /** Standard streaming supported */\n standardStreams: boolean;\n /** Bulk transfer supported */\n bulkTransfer: boolean;\n /** Realtime streaming supported */\n realtimeStreams: boolean;\n /** Maximum concurrent streams */\n maxConcurrentStreams: number;\n /** Maximum stream window size */\n maxWindowSize: number;\n /** Supported flow control algorithms */\n flowControlAlgorithms: string[];\n}\n\n/** Default streaming capabilities */\nexport const DEFAULT_STREAMING_CAPABILITIES: StreamingCapabilities = {\n standardStreams: true,\n bulkTransfer: true,\n realtimeStreams: true,\n maxConcurrentStreams: 100,\n maxWindowSize: 1048576, // 1MB\n flowControlAlgorithms: ['sliding-window', 'rate-based'],\n};\n\n/** Extended RPC connection options with streaming */\nexport interface StreamingRpcConnectionOptions extends RpcConnectionOptions {\n /** Stream manager configuration */\n streamManagerConfig?: Partial<StreamManagerConfig>;\n /** Stream manager event handlers */\n streamManagerHandlers?: StreamManagerHandlers;\n /** Local streaming capabilities */\n localCapabilities?: Partial<StreamingCapabilities>;\n /** Enable streaming support */\n enableStreaming?: boolean;\n}\n\n/**\n * Extended RPC connection with streaming support\n *\n * This class wraps RpcConnection and adds stream management capabilities.\n * It can be used as a drop-in replacement for RpcConnection.\n */\nexport class StreamingRpcConnection extends RpcConnection {\n private streamManager: StreamManager;\n private localCapabilities: StreamingCapabilities;\n private remoteCapabilities?: StreamingCapabilities;\n private streamingEnabled: boolean;\n\n constructor(transport: RpcTransport, options: StreamingRpcConnectionOptions = {}) {\n super(transport, options);\n\n this.streamingEnabled = options.enableStreaming ?? true;\n this.localCapabilities = { ...DEFAULT_STREAMING_CAPABILITIES, ...options.localCapabilities };\n\n // Create stream manager\n this.streamManager = new StreamManager(\n options.streamManagerConfig,\n options.streamManagerHandlers\n );\n\n // Attach to this connection\n this.streamManager.attach(this, transport);\n\n // Set up capability negotiation if streaming is enabled\n if (this.streamingEnabled) {\n this.negotiateCapabilities();\n }\n }\n\n /** Get the stream manager */\n get streams(): StreamManager {\n return this.streamManager;\n }\n\n /** Get local streaming capabilities */\n get capabilities(): StreamingCapabilities {\n return this.localCapabilities;\n }\n\n /** Get remote streaming capabilities (if negotiated) */\n get remoteStreamingCapabilities(): StreamingCapabilities | undefined {\n return this.remoteCapabilities;\n }\n\n /** Check if streaming is enabled */\n get isStreamingEnabled(): boolean {\n return this.streamingEnabled;\n }\n\n /**\n * Create a new standard stream\n */\n createStream(options?: CreateStreamOptions): Stream {\n this.ensureStreamingEnabled();\n return this.streamManager.createStream(options);\n }\n\n /**\n * Create a bulk transfer stream\n */\n createBulkTransfer(\n direction: 'upload' | 'download',\n metadata: BulkTransferMetadata,\n config?: Partial<BulkTransferConfig>,\n handlers?: BulkTransferHandlers\n ): BulkTransfer {\n this.ensureStreamingEnabled();\n this.ensureCapability('bulkTransfer');\n return this.streamManager.createBulkStream(direction, metadata, config, handlers);\n }\n\n /**\n * Create a realtime stream\n */\n createRealtimeStream(\n config?: Partial<RealtimeConfig>,\n handlers?: RealtimeStreamHandlers\n ): RealtimeStream {\n this.ensureStreamingEnabled();\n this.ensureCapability('realtimeStreams');\n return this.streamManager.createRealtimeStream(config, handlers);\n }\n\n /**\n * Get stream statistics\n */\n getStreamStatistics(): ReturnType<StreamManager['getStatistics']> {\n return this.streamManager.getStatistics();\n }\n\n /**\n * Close all streams gracefully\n */\n async closeAllStreams(): Promise<void> {\n await this.streamManager.closeAllStreams();\n }\n\n /**\n * Override stop to properly clean up streams\n */\n override async stop(): Promise<void> {\n await this.closeAllStreams();\n this.streamManager.detach();\n await super.stop();\n }\n\n // =============================================================================\n // Capability Negotiation\n // =============================================================================\n\n /**\n * Negotiate streaming capabilities with remote peer\n *\n * This would typically be done during bootstrap or connection setup.\n * For now, we assume the remote has the same capabilities.\n */\n private async negotiateCapabilities(): Promise<void> {\n // In a full implementation, this would exchange capability messages\n // with the remote peer during connection setup.\n\n // For now, assume remote has same capabilities\n this.remoteCapabilities = { ...this.localCapabilities };\n\n // TODO: Implement actual capability exchange via RPC\n }\n\n /**\n * Update remote capabilities (called when received from peer)\n */\n setRemoteCapabilities(capabilities: StreamingCapabilities): void {\n this.remoteCapabilities = capabilities;\n }\n\n /**\n * Check if a specific capability is supported by both peers\n */\n isCapabilitySupported(capability: keyof StreamingCapabilities): boolean {\n const localValue = this.localCapabilities[capability];\n const remoteValue = this.remoteCapabilities?.[capability];\n\n // For boolean capabilities, both must be true\n if (typeof localValue === 'boolean' && typeof remoteValue === 'boolean') {\n return localValue && remoteValue;\n }\n\n // For numeric capabilities, use the minimum\n if (typeof localValue === 'number' && typeof remoteValue === 'number') {\n return localValue > 0 && remoteValue > 0;\n }\n\n return false;\n }\n\n // =============================================================================\n // Integration with Pipeline\n // =============================================================================\n\n /**\n * Create a stream for pipeline results\n *\n * This allows large pipeline results to be streamed instead of buffered.\n */\n createPipelineStream(questionId: number, options?: CreateStreamOptions): Stream {\n this.ensureStreamingEnabled();\n\n const stream = this.createStream({\n ...options,\n type: StreamType.STANDARD,\n metadata: {\n ...options?.metadata,\n pipelineQuestionId: questionId.toString(),\n },\n });\n\n return stream;\n }\n\n /**\n * Associate a stream with a capability\n *\n * This enables streaming data to/from a capability.\n */\n associateStreamWithCapability(streamId: number, _importId: ImportId | ExportId): void {\n const stream = this.streamManager.getStream(streamId);\n if (!stream) {\n throw new Error(`Stream ${streamId} not found`);\n }\n\n // Store association (would be used by the RPC layer)\n // This is a simplified implementation\n }\n\n // =============================================================================\n // Private Methods\n // =============================================================================\n\n private ensureStreamingEnabled(): void {\n if (!this.streamingEnabled) {\n throw new Error('Streaming is not enabled on this connection');\n }\n }\n\n private ensureCapability(capability: keyof StreamingCapabilities): void {\n if (!this.isCapabilitySupported(capability)) {\n throw new Error(`Capability '${capability}' is not supported by both peers`);\n }\n }\n}\n\n/**\n * Create a streaming RPC connection\n */\nexport function createStreamingConnection(\n transport: RpcTransport,\n options?: StreamingRpcConnectionOptions\n): StreamingRpcConnection {\n return new StreamingRpcConnection(transport, options);\n}\n\n/**\n * Check if a connection supports streaming\n */\nexport function supportsStreaming(connection: RpcConnection): connection is StreamingRpcConnection {\n return connection instanceof StreamingRpcConnection;\n}\n\n// Re-export types from stream-manager\nexport type {\n StreamManager,\n StreamType,\n CreateStreamOptions,\n StreamManagerConfig,\n StreamManagerHandlers,\n Stream,\n BulkTransfer,\n RealtimeStream,\n};\n","/**\n * Phase 7: Dynamic Schema Reader\n *\n * This module provides runtime reading of Cap'n Proto messages using\n * dynamically loaded schema information. This allows reading messages\n * for types not known at compile time.\n */\n\nimport type { ListReader } from '../core/list.js';\nimport { MessageReader, type StructReader } from '../core/message-reader.js';\nimport { ElementSize } from '../core/pointer.js';\nimport type {\n SchemaField,\n SchemaNode,\n SchemaType,\n SchemaTypeKind,\n SchemaValue,\n} from './schema-types.js';\nimport { SchemaNodeType } from './schema-types.js';\n\n/**\n * Dynamic reader for Cap'n Proto messages\n * Provides runtime field access based on schema information\n */\nexport interface DynamicReader {\n /** Get a field value by name */\n get(fieldName: string): unknown;\n\n /** Check if a field exists */\n has(fieldName: string): boolean;\n\n /** Get all field names */\n getFieldNames(): string[];\n\n /** Get the underlying schema node */\n getSchema(): SchemaNode;\n\n /** Get nested struct reader */\n getStruct(fieldName: string): DynamicReader | undefined;\n\n /** Get list field */\n getList(fieldName: string): unknown[] | undefined;\n\n /** Get the raw StructReader */\n getRawReader(): StructReader;\n}\n\n/**\n * Create a dynamic reader from schema and buffer\n *\n * @param schema - The schema node describing the struct type\n * @param buffer - The Cap'n Proto message buffer\n * @returns A DynamicReader for accessing the message fields\n */\nexport function createDynamicReader(\n schema: SchemaNode,\n buffer: ArrayBuffer | Uint8Array\n): DynamicReader {\n const messageReader = new MessageReader(buffer);\n\n if (!schema.structInfo) {\n throw new Error(`Schema node ${schema.displayName} is not a struct`);\n }\n\n const { dataWordCount, pointerCount } = schema.structInfo;\n const structReader = messageReader.getRoot(dataWordCount, pointerCount);\n\n return new DynamicReaderImpl(schema, structReader, messageReader);\n}\n\n/**\n * Create a dynamic reader from an existing StructReader\n *\n * @param schema - The schema node describing the struct type\n * @param structReader - The StructReader to wrap\n * @param messageReader - The underlying MessageReader\n * @returns A DynamicReader for accessing the message fields\n */\nexport function createDynamicReaderFromStruct(\n schema: SchemaNode,\n structReader: StructReader,\n messageReader: MessageReader\n): DynamicReader {\n return new DynamicReaderImpl(schema, structReader, messageReader);\n}\n\n/**\n * Implementation of DynamicReader\n */\nclass DynamicReaderImpl implements DynamicReader {\n private fieldCache: Map<string, SchemaField>;\n private pointerOffset: number;\n\n constructor(\n private schema: SchemaNode,\n private structReader: StructReader,\n private messageReader: MessageReader\n ) {\n this.fieldCache = new Map();\n this.pointerOffset = schema.structInfo?.dataWordCount ?? 0;\n\n // Build field cache\n if (schema.structInfo?.fields) {\n for (const field of schema.structInfo.fields) {\n this.fieldCache.set(field.name, field);\n }\n }\n }\n\n get(fieldName: string): unknown {\n const field = this.fieldCache.get(fieldName);\n if (!field) {\n throw new Error(`Field '${fieldName}' not found in schema ${this.schema.displayName}`);\n }\n\n return this.readFieldValue(field);\n }\n\n has(fieldName: string): boolean {\n return this.fieldCache.has(fieldName);\n }\n\n getFieldNames(): string[] {\n return Array.from(this.fieldCache.keys());\n }\n\n getSchema(): SchemaNode {\n return this.schema;\n }\n\n getStruct(fieldName: string): DynamicReader | undefined {\n const field = this.fieldCache.get(fieldName);\n if (!field) {\n return undefined;\n }\n\n // Check if field is a struct type\n if (field.type.kind.type !== 'struct') {\n return undefined;\n }\n\n // Get the nested struct reader\n const pointerIndex = this.getPointerIndex(field);\n const nestedStruct = this.structReader.getStruct(pointerIndex, 0, 0);\n if (!nestedStruct) {\n return undefined;\n }\n\n // Note: We don't have the nested schema here, so we return a limited reader\n // In a full implementation, we'd look up the schema by typeId\n return new DynamicStructReaderWithoutSchema(nestedStruct, this.messageReader);\n }\n\n getList(fieldName: string): unknown[] | undefined {\n const field = this.fieldCache.get(fieldName);\n if (!field) {\n return undefined;\n }\n\n if (field.type.kind.type !== 'list') {\n return undefined;\n }\n\n const pointerIndex = this.getPointerIndex(field);\n const elementType = field.type.kind.elementType;\n\n return this.readListField(pointerIndex, elementType);\n }\n\n getRawReader(): StructReader {\n return this.structReader;\n }\n\n /**\n * Read a field value based on its type\n */\n private readFieldValue(field: SchemaField): unknown {\n const kind = field.type.kind;\n\n switch (kind.type) {\n case 'void':\n return undefined;\n case 'bool':\n return this.structReader.getBool(field.offset);\n case 'int8':\n return this.structReader.getInt8(field.offset);\n case 'int16':\n return this.structReader.getInt16(field.offset);\n case 'int32':\n return this.structReader.getInt32(field.offset);\n case 'int64':\n return this.structReader.getInt64(field.offset);\n case 'uint8':\n return this.structReader.getUint8(field.offset);\n case 'uint16':\n return this.structReader.getUint16(field.offset);\n case 'uint32':\n return this.structReader.getUint32(field.offset);\n case 'uint64':\n return this.structReader.getUint64(field.offset);\n case 'float32':\n return this.structReader.getFloat32(field.offset);\n case 'float64':\n return this.structReader.getFloat64(field.offset);\n case 'text':\n return this.readTextField(field);\n case 'data':\n return this.readDataField(field);\n case 'list':\n return this.readListFieldBySchema(field);\n case 'enum':\n return this.readEnumField(field);\n case 'struct':\n return this.readStructField(field);\n case 'interface':\n return this.readInterfaceField(field);\n case 'anyPointer':\n return this.readAnyPointerField(field);\n default:\n throw new Error(`Unsupported field type: ${(kind as SchemaTypeKind).type}`);\n }\n }\n\n /**\n * Get the pointer index for a field\n * In Cap'n Proto, pointer fields have offsets that start from 0 for the first pointer\n * The offset is measured in bits from the start of the data section\n * For pointer fields, offset = dataWordCount * 64 + pointerIndex * 64\n * So pointerIndex = (offset - dataWordCount * 64) / 64\n */\n private getPointerIndex(field: SchemaField): number {\n const dataSectionBits = (this.schema.structInfo?.dataWordCount ?? 0) * 64;\n // Pointer offset is measured from the start of the pointer section\n // Each pointer is 64 bits (1 word)\n const pointerIndex = (field.offset - dataSectionBits) / 64;\n return pointerIndex;\n }\n\n /**\n * Read a text field\n */\n private readTextField(field: SchemaField): string {\n const pointerIndex = this.getPointerIndex(field);\n return this.structReader.getText(pointerIndex);\n }\n\n /**\n * Read a data field\n */\n private readDataField(field: SchemaField): Uint8Array {\n const pointerIndex = this.getPointerIndex(field);\n // Data is stored similarly to text but without null terminator\n // For now, we use the same mechanism\n const text = this.structReader.getText(pointerIndex);\n return new TextEncoder().encode(text);\n }\n\n /**\n * Read a list field using schema information\n */\n private readListFieldBySchema(field: SchemaField): unknown[] {\n if (field.type.kind.type !== 'list') {\n throw new Error(`Field '${field.name}' is not a list type`);\n }\n\n const pointerIndex = this.getPointerIndex(field);\n const elementType = field.type.kind.elementType;\n\n return this.readListField(pointerIndex, elementType);\n }\n\n /**\n * Read a list field\n */\n private readListField(pointerIndex: number, elementType: SchemaType): unknown[] {\n // Map element type to ElementSize\n const elementSize = this.mapTypeToElementSize(elementType);\n\n const listReader = this.structReader.getList<unknown>(pointerIndex, elementSize);\n if (!listReader) {\n return [];\n }\n\n // Convert list reader to array\n const result: unknown[] = [];\n const length = listReader.length;\n\n for (let i = 0; i < length; i++) {\n result.push(this.readListElement(listReader, i, elementType));\n }\n\n return result;\n }\n\n /**\n * Map schema type to ElementSize\n */\n private mapTypeToElementSize(type: SchemaType): ElementSize {\n switch (type.kind.type) {\n case 'void':\n return ElementSize.VOID;\n case 'bool':\n return ElementSize.BIT;\n case 'int8':\n case 'uint8':\n return ElementSize.BYTE;\n case 'int16':\n case 'uint16':\n return ElementSize.TWO_BYTES;\n case 'int32':\n case 'uint32':\n case 'float32':\n return ElementSize.FOUR_BYTES;\n case 'int64':\n case 'uint64':\n case 'float64':\n return ElementSize.EIGHT_BYTES;\n case 'struct':\n return ElementSize.COMPOSITE;\n default:\n return ElementSize.POINTER;\n }\n }\n\n /**\n * Read a single list element\n */\n private readListElement(\n listReader: ListReader<unknown>,\n index: number,\n elementType: SchemaType\n ): unknown {\n const kind = elementType.kind;\n\n switch (kind.type) {\n case 'void':\n return undefined;\n case 'bool':\n return listReader.getPrimitive(index) !== 0;\n case 'int8':\n return listReader.getPrimitive(index);\n case 'int16':\n return listReader.getPrimitive(index);\n case 'int32':\n return listReader.getPrimitive(index);\n case 'int64':\n return listReader.getPrimitive(index);\n case 'uint8':\n return listReader.getPrimitive(index);\n case 'uint16':\n return listReader.getPrimitive(index);\n case 'uint32':\n return listReader.getPrimitive(index);\n case 'uint64':\n return listReader.getPrimitive(index);\n case 'float32':\n return listReader.getPrimitive(index);\n case 'float64':\n return listReader.getPrimitive(index);\n case 'struct': {\n const structReader = listReader.getStruct(index);\n if (!structReader) return undefined;\n // Return a wrapper without full schema\n return new DynamicStructReaderWithoutSchema(structReader, this.messageReader);\n }\n default:\n return undefined;\n }\n }\n\n /**\n * Read an enum field\n */\n private readEnumField(field: SchemaField): number {\n // Enums are stored as uint16\n return this.structReader.getUint16(field.offset);\n }\n\n /**\n * Read a struct field\n */\n private readStructField(field: SchemaField): DynamicReader | undefined {\n const pointerIndex = this.getPointerIndex(field);\n const nestedStruct = this.structReader.getStruct(pointerIndex, 0, 0);\n if (!nestedStruct) {\n return undefined;\n }\n\n // Without the nested schema, we return a limited reader\n return new DynamicStructReaderWithoutSchema(nestedStruct, this.messageReader);\n }\n\n /**\n * Read an interface field (capability)\n */\n private readInterfaceField(_field: SchemaField): unknown {\n // Capabilities are stored in the cap table\n // This would require access to the capability table\n throw new Error('Interface fields not yet supported in dynamic reader');\n }\n\n /**\n * Read an anyPointer field\n */\n private readAnyPointerField(_field: SchemaField): unknown {\n // anyPointer can be any type, requires runtime type detection\n throw new Error('anyPointer fields not yet supported in dynamic reader');\n }\n}\n\n/**\n * A limited dynamic reader for structs without schema information\n * Provides basic field access but no type information\n */\nclass DynamicStructReaderWithoutSchema implements DynamicReader {\n constructor(\n private structReader: StructReader,\n private messageReader: MessageReader\n ) {}\n\n get(_fieldName: string): unknown {\n throw new Error('Cannot access fields without schema information');\n }\n\n has(_fieldName: string): boolean {\n return false;\n }\n\n getFieldNames(): string[] {\n return [];\n }\n\n getSchema(): SchemaNode {\n throw new Error('No schema information available');\n }\n\n getStruct(_fieldName: string): DynamicReader | undefined {\n return undefined;\n }\n\n getList(_fieldName: string): unknown[] | undefined {\n return undefined;\n }\n\n getRawReader(): StructReader {\n return this.structReader;\n }\n}\n\n/**\n * Create a dynamic reader for a specific type ID\n * This looks up the schema in a registry and creates the appropriate reader\n *\n * @param typeId - The type ID of the struct\n * @param buffer - The Cap'n Proto message buffer\n * @param schemaRegistry - A map of type IDs to schema nodes\n * @returns A DynamicReader for the message\n */\nexport function createDynamicReaderByTypeId(\n typeId: bigint,\n buffer: ArrayBuffer | Uint8Array,\n schemaRegistry: Map<bigint, SchemaNode>\n): DynamicReader {\n const schema = schemaRegistry.get(typeId);\n if (!schema) {\n throw new Error(`Schema not found for type ID: ${typeId}`);\n }\n\n if (schema.type !== SchemaNodeType.STRUCT) {\n throw new Error(`Type ${typeId} is not a struct`);\n }\n\n return createDynamicReader(schema, buffer);\n}\n\n/**\n * Utility function to dump all fields from a dynamic reader\n * Useful for debugging and exploration\n *\n * @param reader - The DynamicReader to dump\n * @returns An object with all field names and values\n */\nexport function dumpDynamicReader(reader: DynamicReader): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const fieldName of reader.getFieldNames()) {\n try {\n result[fieldName] = reader.get(fieldName);\n } catch (error) {\n result[fieldName] = `<error: ${error}>`;\n }\n }\n\n return result;\n}\n","/**\n * Phase 7: Dynamic Schema Writer\n *\n * This module provides runtime writing of Cap'n Proto messages using\n * dynamically loaded schema information. This allows writing messages\n * for types not known at compile time.\n */\n\nimport type { ListBuilder } from '../core/list.js';\nimport { MessageBuilder, type StructBuilder } from '../core/message-builder.js';\nimport { ElementSize } from '../core/pointer.js';\nimport type { SchemaField, SchemaNode, SchemaType, SchemaValue } from './schema-types.js';\nimport { SchemaNodeType } from './schema-types.js';\n\n/**\n * Dynamic writer for Cap'n Proto messages\n * Provides runtime field setting based on schema information\n */\nexport interface DynamicWriter {\n /** Set a field value by name */\n set(fieldName: string, value: unknown): void;\n\n /** Set multiple fields at once */\n setFields(fields: Record<string, unknown>): void;\n\n /** Initialize a nested struct field */\n initStruct(fieldName: string): DynamicWriter;\n\n /** Initialize a list field */\n initList(fieldName: string, size: number): DynamicListWriter;\n\n /** Set a text field */\n setText(fieldName: string, value: string): void;\n\n /** Set a data field */\n setData(fieldName: string, value: Uint8Array): void;\n\n /** Get the underlying schema node */\n getSchema(): SchemaNode;\n\n /** Get the raw StructBuilder */\n getRawBuilder(): StructBuilder;\n\n /** Serialize the message to a buffer */\n toBuffer(): ArrayBuffer;\n}\n\n/**\n * Dynamic list writer\n * Provides runtime element setting for list fields\n */\nexport interface DynamicListWriter {\n /** Set an element at the specified index */\n set(index: number, value: unknown): void;\n\n /** Get the list size */\n getSize(): number;\n\n /** Initialize a nested struct element */\n initStruct(index: number): DynamicWriter;\n\n /** Set multiple elements at once */\n setAll(values: unknown[]): void;\n}\n\n/**\n * Create a dynamic writer from schema\n *\n * @param schema - The schema node describing the struct type\n * @returns A DynamicWriter for setting message fields\n */\nexport function createDynamicWriter(schema: SchemaNode): DynamicWriter {\n if (!schema.structInfo) {\n throw new Error(`Schema node ${schema.displayName} is not a struct`);\n }\n\n const { dataWordCount, pointerCount } = schema.structInfo;\n const messageBuilder = new MessageBuilder();\n const structBuilder = messageBuilder.initRoot(dataWordCount, pointerCount);\n\n return new DynamicWriterImpl(schema, structBuilder, messageBuilder);\n}\n\n/**\n * Create a dynamic writer for a nested struct\n *\n * @param schema - The schema node describing the struct type\n * @param structBuilder - The StructBuilder to wrap\n * @param messageBuilder - The underlying MessageBuilder\n * @returns A DynamicWriter for setting message fields\n */\nexport function createNestedDynamicWriter(\n schema: SchemaNode,\n structBuilder: StructBuilder,\n messageBuilder: MessageBuilder\n): DynamicWriter {\n return new DynamicWriterImpl(schema, structBuilder, messageBuilder);\n}\n\n/**\n * Implementation of DynamicWriter\n */\nclass DynamicWriterImpl implements DynamicWriter {\n private fieldCache: Map<string, SchemaField>;\n private pointerOffset: number;\n\n constructor(\n private schema: SchemaNode,\n private structBuilder: StructBuilder,\n private messageBuilder: MessageBuilder\n ) {\n this.fieldCache = new Map();\n this.pointerOffset = schema.structInfo?.dataWordCount ?? 0;\n\n // Build field cache\n if (schema.structInfo?.fields) {\n for (const field of schema.structInfo.fields) {\n this.fieldCache.set(field.name, field);\n }\n }\n }\n\n set(fieldName: string, value: unknown): void {\n const field = this.fieldCache.get(fieldName);\n if (!field) {\n throw new Error(`Field '${fieldName}' not found in schema ${this.schema.displayName}`);\n }\n\n this.writeFieldValue(field, value);\n }\n\n setFields(fields: Record<string, unknown>): void {\n for (const [name, value] of Object.entries(fields)) {\n this.set(name, value);\n }\n }\n\n initStruct(fieldName: string): DynamicWriter {\n const field = this.fieldCache.get(fieldName);\n if (!field) {\n throw new Error(`Field '${fieldName}' not found in schema ${this.schema.displayName}`);\n }\n\n if (field.type.kind.type !== 'struct') {\n throw new Error(`Field '${fieldName}' is not a struct type`);\n }\n\n // For nested structs, we need the nested schema\n // Since we don't have it here, we'll create a placeholder\n const pointerIndex = this.getPointerIndex(field);\n const nestedBuilder = this.structBuilder.initStruct(pointerIndex, 0, 0);\n\n // Return a writer without schema - limited functionality\n return new DynamicWriterWithoutSchema(nestedBuilder, this.messageBuilder);\n }\n\n initList(fieldName: string, size: number): DynamicListWriter {\n const field = this.fieldCache.get(fieldName);\n if (!field) {\n throw new Error(`Field '${fieldName}' not found in schema ${this.schema.displayName}`);\n }\n\n if (field.type.kind.type !== 'list') {\n throw new Error(`Field '${fieldName}' is not a list type`);\n }\n\n const pointerIndex = this.getPointerIndex(field);\n const elementType = field.type.kind.elementType;\n\n return this.createListWriter(pointerIndex, size, elementType);\n }\n\n setText(fieldName: string, value: string): void {\n const field = this.fieldCache.get(fieldName);\n if (!field) {\n throw new Error(`Field '${fieldName}' not found in schema ${this.schema.displayName}`);\n }\n\n if (field.type.kind.type !== 'text') {\n throw new Error(`Field '${fieldName}' is not a text type`);\n }\n\n const pointerIndex = this.getPointerIndex(field);\n this.structBuilder.setText(pointerIndex, value);\n }\n\n setData(fieldName: string, value: Uint8Array): void {\n const field = this.fieldCache.get(fieldName);\n if (!field) {\n throw new Error(`Field '${fieldName}' not found in schema ${this.schema.displayName}`);\n }\n\n if (field.type.kind.type !== 'data') {\n throw new Error(`Field '${fieldName}' is not a data type`);\n }\n\n // Data is stored similarly to text but as bytes\n const pointerIndex = this.getPointerIndex(field);\n const textValue = new TextDecoder().decode(value);\n this.structBuilder.setText(pointerIndex, `${textValue}\\0`);\n }\n\n getSchema(): SchemaNode {\n return this.schema;\n }\n\n getRawBuilder(): StructBuilder {\n return this.structBuilder;\n }\n\n toBuffer(): ArrayBuffer {\n return this.messageBuilder.toArrayBuffer();\n }\n\n /**\n * Write a field value based on its type\n */\n private writeFieldValue(field: SchemaField, value: unknown): void {\n const kind = field.type.kind;\n\n switch (kind.type) {\n case 'void':\n // Void fields don't store any data\n break;\n case 'bool':\n this.structBuilder.setBool(field.offset, Boolean(value));\n break;\n case 'int8':\n this.structBuilder.setInt8(field.offset, Number(value));\n break;\n case 'int16':\n this.structBuilder.setInt16(field.offset, Number(value));\n break;\n case 'int32':\n this.structBuilder.setInt32(field.offset, Number(value));\n break;\n case 'int64':\n this.structBuilder.setInt64(field.offset, BigInt(value as string | number | bigint));\n break;\n case 'uint8':\n this.structBuilder.setUint8(field.offset, Number(value));\n break;\n case 'uint16':\n this.structBuilder.setUint16(field.offset, Number(value));\n break;\n case 'uint32':\n this.structBuilder.setUint32(field.offset, Number(value));\n break;\n case 'uint64':\n this.structBuilder.setUint64(field.offset, BigInt(value as string | number | bigint));\n break;\n case 'float32':\n this.structBuilder.setFloat32(field.offset, Number(value));\n break;\n case 'float64':\n this.structBuilder.setFloat64(field.offset, Number(value));\n break;\n case 'text':\n this.setText(field.name, String(value));\n break;\n case 'data':\n if (value instanceof Uint8Array) {\n this.setData(field.name, value);\n } else {\n throw new Error(`Field '${field.name}' expects Uint8Array`);\n }\n break;\n case 'list':\n if (Array.isArray(value)) {\n const listWriter = this.initList(field.name, value.length);\n listWriter.setAll(value);\n } else {\n throw new Error(`Field '${field.name}' expects an array`);\n }\n break;\n case 'enum':\n this.structBuilder.setUint16(field.offset, Number(value));\n break;\n case 'struct':\n if (typeof value === 'object' && value !== null) {\n const structWriter = this.initStruct(field.name);\n // If value is a record, set its fields\n if (!(value instanceof Uint8Array) && !Array.isArray(value)) {\n structWriter.setFields(value as Record<string, unknown>);\n }\n } else {\n throw new Error(`Field '${field.name}' expects an object`);\n }\n break;\n case 'interface':\n throw new Error('Interface fields not yet supported in dynamic writer');\n case 'anyPointer':\n throw new Error('anyPointer fields not yet supported in dynamic writer');\n default:\n throw new Error(`Unsupported field type: ${(kind as { type: string }).type}`);\n }\n }\n\n /**\n * Get the pointer index for a field\n * In Cap'n Proto, pointer fields have offsets that start from 0 for the first pointer\n * The offset is measured in bits from the start of the data section\n * For pointer fields, offset = dataWordCount * 64 + pointerIndex * 64\n * So pointerIndex = (offset - dataWordCount * 64) / 64\n */\n private getPointerIndex(field: SchemaField): number {\n const dataSectionBits = (this.schema.structInfo?.dataWordCount ?? 0) * 64;\n // Pointer offset is measured from the start of the pointer section\n // Each pointer is 64 bits (1 word)\n const pointerIndex = (field.offset - dataSectionBits) / 64;\n return pointerIndex;\n }\n\n /**\n * Create a list writer for a field\n */\n private createListWriter(\n pointerIndex: number,\n size: number,\n elementType: SchemaType\n ): DynamicListWriter {\n // Map element type to ElementSize\n const elementSize = this.mapTypeToElementSize(elementType);\n\n let structSize: { dataWords: number; pointerCount: number } | undefined;\n if (elementSize === ElementSize.COMPOSITE) {\n // For composite types, we need struct size info\n // Default to 0,0 if not available\n structSize = { dataWords: 0, pointerCount: 0 };\n }\n\n const listBuilder = this.structBuilder.initList<unknown>(\n pointerIndex,\n elementSize,\n size,\n structSize\n );\n\n return new DynamicListWriterImpl(listBuilder, elementType, this.messageBuilder);\n }\n\n /**\n * Map schema type to ElementSize\n */\n private mapTypeToElementSize(type: SchemaType): ElementSize {\n switch (type.kind.type) {\n case 'void':\n return ElementSize.VOID;\n case 'bool':\n return ElementSize.BIT;\n case 'int8':\n case 'uint8':\n return ElementSize.BYTE;\n case 'int16':\n case 'uint16':\n return ElementSize.TWO_BYTES;\n case 'int32':\n case 'uint32':\n case 'float32':\n return ElementSize.FOUR_BYTES;\n case 'int64':\n case 'uint64':\n case 'float64':\n return ElementSize.EIGHT_BYTES;\n case 'struct':\n return ElementSize.COMPOSITE;\n default:\n return ElementSize.POINTER;\n }\n }\n}\n\n/**\n * Implementation of DynamicListWriter\n */\nclass DynamicListWriterImpl implements DynamicListWriter {\n constructor(\n private listBuilder: ListBuilder<unknown>,\n private elementType: SchemaType,\n private messageBuilder: MessageBuilder\n ) {}\n\n set(index: number, value: unknown): void {\n if (index < 0 || index >= this.listBuilder.length) {\n throw new Error(`Index ${index} out of bounds`);\n }\n\n const kind = this.elementType.kind;\n\n switch (kind.type) {\n case 'void':\n // Nothing to set for void\n break;\n case 'bool':\n this.listBuilder.setPrimitive(index, value ? 1 : 0);\n break;\n case 'int8':\n case 'uint8':\n case 'int16':\n case 'uint16':\n case 'int32':\n case 'uint32':\n case 'float32':\n this.listBuilder.setPrimitive(index, Number(value));\n break;\n case 'int64':\n case 'uint64':\n case 'float64':\n this.listBuilder.setPrimitive(index, BigInt(value as string | number | bigint));\n break;\n case 'struct':\n // For struct lists, value should be an object to set fields\n if (typeof value === 'object' && value !== null && !(value instanceof Uint8Array)) {\n const structWriter = this.initStruct(index);\n structWriter.setFields(value as Record<string, unknown>);\n }\n break;\n default:\n throw new Error(`Unsupported list element type: ${kind.type}`);\n }\n }\n\n getSize(): number {\n return this.listBuilder.length;\n }\n\n getLength(): number {\n return this.listBuilder.length;\n }\n\n initStruct(index: number): DynamicWriter {\n const structBuilder = this.listBuilder.getStruct(index);\n return new DynamicWriterWithoutSchema(structBuilder, this.messageBuilder);\n }\n\n setAll(values: unknown[]): void {\n if (values.length > this.getSize()) {\n throw new Error(`Cannot set ${values.length} values in list of size ${this.getSize()}`);\n }\n\n for (let i = 0; i < values.length; i++) {\n this.set(i, values[i]);\n }\n }\n}\n\n/**\n * A limited dynamic writer for structs without full schema information\n * Provides basic field setting but no type validation\n */\nclass DynamicWriterWithoutSchema implements DynamicWriter {\n constructor(\n private structBuilder: StructBuilder,\n private messageBuilder: MessageBuilder\n ) {}\n\n set(fieldName: string, _value: unknown): void {\n // Without schema, we can only support basic operations\n // This is a placeholder that could be extended\n throw new Error(`Cannot set field '${fieldName}' without schema information`);\n }\n\n setFields(_fields: Record<string, unknown>): void {\n throw new Error('Cannot set fields without schema information');\n }\n\n initStruct(_fieldName: string): DynamicWriter {\n throw new Error('Cannot init struct without schema information');\n }\n\n initList(_fieldName: string, _size: number): DynamicListWriter {\n throw new Error('Cannot init list without schema information');\n }\n\n setText(_fieldName: string, _value: string): void {\n throw new Error('Cannot set text without schema information');\n }\n\n setData(_fieldName: string, _value: Uint8Array): void {\n throw new Error('Cannot set data without schema information');\n }\n\n getSchema(): SchemaNode {\n throw new Error('No schema information available');\n }\n\n getRawBuilder(): StructBuilder {\n return this.structBuilder;\n }\n\n toBuffer(): ArrayBuffer {\n return this.messageBuilder.toArrayBuffer();\n }\n}\n\n/**\n * Create a dynamic writer for a specific type ID\n * This looks up the schema in a registry and creates the appropriate writer\n *\n * @param typeId - The type ID of the struct\n * @param schemaRegistry - A map of type IDs to schema nodes\n * @returns A DynamicWriter for the message\n */\nexport function createDynamicWriterByTypeId(\n typeId: bigint,\n schemaRegistry: Map<bigint, SchemaNode>\n): DynamicWriter {\n const schema = schemaRegistry.get(typeId);\n if (!schema) {\n throw new Error(`Schema not found for type ID: ${typeId}`);\n }\n\n if (schema.type !== SchemaNodeType.STRUCT) {\n throw new Error(`Type ${typeId} is not a struct`);\n }\n\n return createDynamicWriter(schema);\n}\n\n/**\n * Utility function to create a message from a plain object\n * Uses schema information to properly serialize the data\n *\n * @param schema - The schema node describing the struct type\n * @param data - The data object to serialize\n * @returns The serialized message buffer\n */\nexport function serializeDynamic(schema: SchemaNode, data: Record<string, unknown>): ArrayBuffer {\n const writer = createDynamicWriter(schema);\n writer.setFields(data);\n return writer.toBuffer();\n}\n\n/**\n * Utility function to create a message from a plain object using type ID\n *\n * @param typeId - The type ID of the struct\n * @param data - The data object to serialize\n * @param schemaRegistry - A map of type IDs to schema nodes\n * @returns The serialized message buffer\n */\nexport function serializeDynamicByTypeId(\n typeId: bigint,\n data: Record<string, unknown>,\n schemaRegistry: Map<bigint, SchemaNode>\n): ArrayBuffer {\n const writer = createDynamicWriterByTypeId(typeId, schemaRegistry);\n writer.setFields(data);\n return writer.toBuffer();\n}\n","/**\n * Phase 7: Schema Capability Implementation\n *\n * Implements the SchemaCapability interface defined in rpc.capnp\n * Provides server-side schema serving and client-side schema fetching\n */\n\nimport type { RpcConnection } from './rpc-connection.js';\nimport { createSchemaRegistry, parseSchemaNodes } from './schema-parser.js';\nimport {\n deserializeSchemaRequest,\n serializeGetSchemaResults,\n serializeListSchemasResults,\n serializeSchemaResponse,\n} from './schema-serializer.js';\nimport type {\n AvailableSchema,\n GetSchemaParams,\n GetSchemaResults,\n ListSchemasResults,\n SchemaNode,\n SchemaPayload,\n SchemaTarget,\n} from './schema-types.js';\nimport { SchemaFormat, SchemaNodeType } from './schema-types.js';\n\n// ============================================================================\n// Schema Capability Server\n// ============================================================================\n\n/**\n * Server-side implementation of the SchemaCapability interface.\n * Provides schema information to remote clients.\n */\nexport class SchemaCapabilityServer {\n private registry: Map<bigint, SchemaNode>;\n private schemasByName: Map<string, SchemaNode>;\n\n /**\n * Create a new SchemaCapabilityServer\n * @param initialSchemas - Optional map of schemas to register initially\n */\n constructor(initialSchemas?: Map<bigint, SchemaNode>) {\n this.registry = new Map(initialSchemas);\n this.schemasByName = new Map();\n\n // Build name index\n for (const schema of this.registry.values()) {\n this.schemasByName.set(schema.displayName, schema);\n }\n }\n\n /**\n * Register a schema node\n * @param node - The schema node to register\n */\n registerSchema(node: SchemaNode): void {\n this.registry.set(node.id, node);\n this.schemasByName.set(node.displayName, node);\n }\n\n /**\n * Unregister a schema by ID\n * @param typeId - The type ID to unregister\n */\n unregisterSchema(typeId: bigint): void {\n const node = this.registry.get(typeId);\n if (node) {\n this.registry.delete(typeId);\n this.schemasByName.delete(node.displayName);\n }\n }\n\n /**\n * Get schema information based on target specification\n * @param params - GetSchemaParams containing target and format\n * @returns GetSchemaResults with the schema payload\n */\n async getSchema(params: GetSchemaParams): Promise<GetSchemaResults> {\n const { target, format = SchemaFormat.BINARY } = params;\n\n let schemaData: Uint8Array;\n let dependencies: Array<{ fileId: bigint; fileName: string; schemaHash?: Uint8Array }> = [];\n\n switch (target.type) {\n case 'byTypeId': {\n const node = this.registry.get(target.typeId);\n if (!node) {\n throw new Error(`Schema not found for type ID: ${target.typeId.toString(16)}`);\n }\n schemaData = this.serializeSchemaNode(node, format);\n dependencies = this.collectDependencies(node);\n break;\n }\n\n case 'byTypeName': {\n const node = this.schemasByName.get(target.typeName);\n if (!node) {\n throw new Error(`Schema not found for type name: ${target.typeName}`);\n }\n schemaData = this.serializeSchemaNode(node, format);\n dependencies = this.collectDependencies(node);\n break;\n }\n\n case 'byFileId': {\n // Get all schemas in a file\n const nodes = this.getSchemasByFileId(target.fileId);\n schemaData = this.serializeSchemaNodes(nodes, format);\n break;\n }\n\n case 'byFileName': {\n // Get all schemas in a file by name\n const nodes = this.getSchemasByFileName(target.fileName);\n schemaData = this.serializeSchemaNodes(nodes, format);\n break;\n }\n\n case 'allSchemas': {\n // Get all schemas\n const nodes = Array.from(this.registry.values());\n schemaData = this.serializeSchemaNodes(nodes, format);\n break;\n }\n\n case 'bootstrapInterface': {\n // Get bootstrap interface schema (if available)\n const bootstrapSchema = this.findBootstrapSchema();\n if (!bootstrapSchema) {\n throw new Error('Bootstrap interface schema not available');\n }\n schemaData = this.serializeSchemaNode(bootstrapSchema, format);\n dependencies = this.collectDependencies(bootstrapSchema);\n break;\n }\n\n default:\n throw new Error(`Unsupported schema target type: ${(target as SchemaTarget).type}`);\n }\n\n return {\n payload: {\n schemaData,\n format,\n dependencies,\n },\n };\n }\n\n /**\n * List all available schemas\n * @returns ListSchemasResults with available schema information\n */\n async listAvailableSchemas(): Promise<ListSchemasResults> {\n const schemas: AvailableSchema[] = [];\n\n for (const node of this.registry.values()) {\n schemas.push({\n typeId: node.id,\n displayName: node.displayName,\n fileId: node.scopeId, // Using scopeId as fileId proxy\n fileName: this.inferFileName(node),\n isInterface: node.type === SchemaNodeType.INTERFACE,\n isStruct: node.type === SchemaNodeType.STRUCT,\n isEnum: node.type === SchemaNodeType.ENUM,\n });\n }\n\n return { schemas };\n }\n\n /**\n * Handle a raw schema request (for RPC integration)\n * @param requestData - The serialized SchemaRequest\n * @returns The serialized SchemaResponse\n */\n handleRequest(requestData: Uint8Array): Uint8Array {\n try {\n const request = deserializeSchemaRequest(requestData);\n\n const _result = this.getSchema({\n target: request.targetSchema,\n });\n\n // Since getSchema is async, we need to handle the promise\n // In a real implementation, this would be properly async\n throw new Error('Async handling not implemented in handleRequest');\n } catch (error) {\n // Return error response\n const errorResponse = {\n answerId: 0,\n result: {\n type: 'exception' as const,\n exception: {\n reason: error instanceof Error ? error.message : 'Unknown error',\n type: 'failed' as const,\n obsoleteIsCallersFault: false,\n obsoleteDurability: 0,\n },\n },\n };\n\n return serializeSchemaResponse(errorResponse);\n }\n }\n\n /**\n * Get the number of registered schemas\n */\n getSchemaCount(): number {\n return this.registry.size;\n }\n\n /**\n * Check if a schema is registered\n */\n hasSchema(typeId: bigint): boolean {\n return this.registry.has(typeId);\n }\n\n // --------------------------------------------------------------------------\n // Private Helper Methods\n // --------------------------------------------------------------------------\n\n private serializeSchemaNode(node: SchemaNode, format: SchemaFormat): Uint8Array {\n switch (format) {\n case SchemaFormat.BINARY:\n return this.serializeToBinary([node]);\n case SchemaFormat.JSON:\n return this.serializeToJson([node]);\n case SchemaFormat.CAPNP:\n return this.serializeToCapnp([node]);\n default:\n throw new Error(`Unsupported schema format: ${format}`);\n }\n }\n\n private serializeSchemaNodes(nodes: SchemaNode[], format: SchemaFormat): Uint8Array {\n switch (format) {\n case SchemaFormat.BINARY:\n return this.serializeToBinary(nodes);\n case SchemaFormat.JSON:\n return this.serializeToJson(nodes);\n case SchemaFormat.CAPNP:\n return this.serializeToCapnp(nodes);\n default:\n throw new Error(`Unsupported schema format: ${format}`);\n }\n }\n\n private serializeToBinary(nodes: SchemaNode[]): Uint8Array {\n // Simplified binary serialization\n // In a full implementation, this would serialize to the actual Cap'n Proto format\n const encoder = new TextEncoder();\n const json = JSON.stringify(nodes, (_key, value) => {\n if (typeof value === 'bigint') {\n return value.toString();\n }\n return value;\n });\n return encoder.encode(json);\n }\n\n private serializeToJson(nodes: SchemaNode[]): Uint8Array {\n const encoder = new TextEncoder();\n const json = JSON.stringify({\n nodes: nodes.map((node) => ({\n id: node.id.toString(),\n displayName: node.displayName,\n displayNamePrefixLength: node.displayNamePrefixLength,\n scopeId: node.scopeId.toString(),\n type: node.type,\n structInfo: node.structInfo,\n enumInfo: node.enumInfo,\n interfaceInfo: node.interfaceInfo,\n })),\n });\n return encoder.encode(json);\n }\n\n private serializeToCapnp(nodes: SchemaNode[]): Uint8Array {\n // Placeholder for actual Cap'n Proto schema language serialization\n // This would generate .capnp source code from the schema nodes\n const lines: string[] = [];\n\n for (const node of nodes) {\n if (node.structInfo) {\n lines.push(`struct ${node.displayName} {`);\n for (const field of node.structInfo.fields) {\n lines.push(` ${field.name} @${field.codeOrder} :${this.typeToCapnp(field.type)};`);\n }\n lines.push('}');\n }\n }\n\n return new TextEncoder().encode(lines.join('\\n'));\n }\n\n private typeToCapnp(type: { kind: { type: string } }): string {\n const kind = type.kind;\n switch (kind.type) {\n case 'void':\n return 'Void';\n case 'bool':\n return 'Bool';\n case 'int8':\n return 'Int8';\n case 'int16':\n return 'Int16';\n case 'int32':\n return 'Int32';\n case 'int64':\n return 'Int64';\n case 'uint8':\n return 'UInt8';\n case 'uint16':\n return 'UInt16';\n case 'uint32':\n return 'UInt32';\n case 'uint64':\n return 'UInt64';\n case 'float32':\n return 'Float32';\n case 'float64':\n return 'Float64';\n case 'text':\n return 'Text';\n case 'data':\n return 'Data';\n case 'list':\n return 'List';\n case 'enum':\n return 'UInt16';\n case 'struct':\n return 'AnyPointer';\n case 'interface':\n return 'Capability';\n default:\n return 'AnyPointer';\n }\n }\n\n private collectDependencies(\n _node: SchemaNode\n ): Array<{ fileId: bigint; fileName: string; schemaHash?: Uint8Array }> {\n // In a full implementation, this would analyze the schema and collect\n // all imported schema dependencies\n return [];\n }\n\n private getSchemasByFileId(fileId: bigint): SchemaNode[] {\n return Array.from(this.registry.values()).filter((node) => node.scopeId === fileId);\n }\n\n private getSchemasByFileName(fileName: string): SchemaNode[] {\n // Infer file name from display name prefix\n return Array.from(this.registry.values()).filter((node) => {\n const inferredFileName = this.inferFileName(node);\n return inferredFileName === fileName || node.displayName.startsWith(fileName);\n });\n }\n\n private inferFileName(node: SchemaNode): string {\n // Infer file name from display name\n // e.g., \"foo.bar.MyStruct\" -> \"foo/bar.capnp\"\n const parts = node.displayName.split('.');\n if (parts.length > 1) {\n return `${parts.slice(0, -1).join('/')}.capnp`;\n }\n return 'unknown.capnp';\n }\n\n private findBootstrapSchema(): SchemaNode | undefined {\n // Look for a schema that might be the bootstrap interface\n // This is a heuristic - in practice, the bootstrap interface would be\n // explicitly registered\n for (const node of this.registry.values()) {\n if (node.type === SchemaNodeType.INTERFACE) {\n return node;\n }\n }\n return undefined;\n }\n}\n\n// ============================================================================\n// Schema Capability Client\n// ============================================================================\n\n/**\n * Client-side implementation for accessing remote SchemaCapability\n */\nexport class SchemaCapabilityClient {\n private connection: RpcConnection;\n\n /**\n * Create a new SchemaCapabilityClient\n * @param connection - The RPC connection to use\n */\n constructor(connection: RpcConnection) {\n this.connection = connection;\n }\n\n /**\n * Fetch schema information from the remote server\n * @param target - The schema target specification\n * @param format - The desired format (defaults to BINARY)\n * @returns The schema node\n */\n async getSchema(\n target: SchemaTarget,\n format: SchemaFormat = SchemaFormat.BINARY\n ): Promise<SchemaNode> {\n // Use the connection's getDynamicSchema method for type ID lookups\n if (target.type === 'byTypeId') {\n return this.connection.getDynamicSchema(target.typeId);\n }\n\n // For other target types, we need to use the schema capability interface\n // This is a simplified implementation\n const _params: GetSchemaParams = { target, format };\n\n // In a full implementation, this would make an RPC call to the schema capability\n // For now, we delegate to the connection's method\n if (target.type === 'byTypeName') {\n return this.connection.getDynamicSchemaByName(target.typeName);\n }\n\n throw new Error(`Schema target type not implemented: ${target.type}`);\n }\n\n /**\n * Fetch schema by type ID\n * @param typeId - The type ID\n * @returns The schema node\n */\n async getSchemaById(typeId: bigint): Promise<SchemaNode> {\n return this.connection.getDynamicSchema(typeId);\n }\n\n /**\n * Fetch schema by type name\n * @param typeName - The fully qualified type name\n * @returns The schema node\n */\n async getSchemaByName(typeName: string): Promise<SchemaNode> {\n return this.connection.getDynamicSchemaByName(typeName);\n }\n\n /**\n * List all available schemas from the remote server\n * @returns Array of available schema information\n */\n async listAvailableSchemas(): Promise<AvailableSchema[]> {\n const schemas = await this.connection.listAvailableSchemas();\n return schemas.map((s) => ({\n typeId: s.typeId,\n displayName: s.displayName,\n fileId: BigInt(0), // Not provided by connection method\n fileName: '', // Not provided by connection method\n isInterface: false, // Not provided by connection method\n isStruct: true,\n isEnum: false,\n }));\n }\n\n /**\n * Fetch multiple schemas at once\n * @param typeIds - Array of type IDs to fetch\n * @returns Map of type ID to schema node\n */\n async getSchemas(typeIds: bigint[]): Promise<Map<bigint, SchemaNode>> {\n const results = new Map<bigint, SchemaNode>();\n\n // Fetch schemas in parallel\n await Promise.all(\n typeIds.map(async (typeId) => {\n try {\n const schema = await this.getSchemaById(typeId);\n results.set(typeId, schema);\n } catch (error) {\n console.warn(`Failed to fetch schema ${typeId.toString(16)}:`, error);\n }\n })\n );\n\n return results;\n }\n\n /**\n * Check if a schema is available on the remote server\n * @param typeId - The type ID to check\n * @returns True if the schema is available\n */\n async hasSchema(typeId: bigint): Promise<boolean> {\n try {\n await this.getSchemaById(typeId);\n return true;\n } catch {\n return false;\n }\n }\n}\n\n// ============================================================================\n// Schema Provider Registration Helper\n// ============================================================================\n\n// Note: RpcConnection.registerSchemaProvider is defined in rpc-connection.ts\n// to avoid circular imports. This file only defines the SchemaCapabilityServer\n// and SchemaCapabilityClient classes.\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["net","net","RpcConnection","SchemaNodeType","SchemaNodeType","SchemaFormat","SchemaNodeType","deserializeSchemaRequest","serializeSchemaResponse"],"sources":["../src/core/pointer.ts","../src/core/segment.ts","../src/core/message-builder.ts","../src/core/list.ts","../src/core/message-reader.ts","../src/core/union.ts","../src/rpc/message-serializer.ts","../src/rpc/websocket-transport.ts","../src/rpc/tcp-transport.ts","../src/rpc/ezrpc-transport.ts","../src/rpc/capability-client.ts","../src/rpc/sturdyrefs.ts","../src/rpc/performance.ts","../src/rpc/connection-manager.ts","../src/rpc/level3-handlers.ts","../src/rpc/level4-types.ts","../src/rpc/level4-handlers.ts","../src/rpc/stream.ts","../src/rpc/bulk.ts","../src/rpc/realtime.ts","../src/rpc/stream-manager.ts","../src/rpc/streaming-connection.ts","../src/rpc/dynamic-reader.ts","../src/rpc/dynamic-writer.ts","../src/rpc/schema-capability.ts"],"sourcesContent":["/**\n * Cap'n Proto 指针编解码\n * 纯 TypeScript 实现\n */\n\nexport enum PointerTag {\n STRUCT = 0,\n LIST = 1,\n FAR = 2,\n OTHER = 3,\n}\n\nexport enum ElementSize {\n VOID = 0,\n BIT = 1,\n BYTE = 2,\n TWO_BYTES = 3,\n FOUR_BYTES = 4,\n EIGHT_BYTES = 5,\n POINTER = 6,\n COMPOSITE = 7,\n INLINE_COMPOSITE = 7, // Alias for COMPOSITE\n}\n\nexport interface StructPointer {\n tag: PointerTag.STRUCT;\n offset: number; // 字偏移(有符号)\n dataWords: number; // 数据段字数\n pointerCount: number; // 指针段字数\n}\n\nexport interface ListPointer {\n tag: PointerTag.LIST;\n offset: number;\n elementSize: ElementSize;\n elementCount: number;\n}\n\nexport interface FarPointer {\n tag: PointerTag.FAR;\n doubleFar: boolean;\n targetSegment: number;\n targetOffset: number;\n}\n\nexport type Pointer = StructPointer | ListPointer | FarPointer | { tag: PointerTag.OTHER };\n\n/**\n * 解码指针(64位)\n */\nexport function decodePointer(ptr: bigint): Pointer {\n const tag = Number(ptr & BigInt(3)) as PointerTag;\n\n switch (tag) {\n case PointerTag.STRUCT: {\n const offset = Number(ptr >> BigInt(2)) & 0x3fffffff;\n const signedOffset = offset >= 0x20000000 ? offset - 0x40000000 : offset;\n const dataWords = Number((ptr >> BigInt(32)) & BigInt(0xffff));\n const pointerCount = Number((ptr >> BigInt(48)) & BigInt(0xffff));\n return { tag, offset: signedOffset, dataWords, pointerCount };\n }\n\n case PointerTag.LIST: {\n const offset = Number(ptr >> BigInt(2)) & 0x3fffffff;\n const signedOffset = offset >= 0x20000000 ? offset - 0x40000000 : offset;\n const elementSize = Number((ptr >> BigInt(32)) & BigInt(7)) as ElementSize;\n const elementCount = Number((ptr >> BigInt(35)) & BigInt(0x1fffffff));\n return { tag, offset: signedOffset, elementSize, elementCount };\n }\n\n case PointerTag.FAR: {\n const doubleFar = Boolean((ptr >> BigInt(2)) & BigInt(1));\n const targetOffset = Number((ptr >> BigInt(3)) & BigInt(0x1fffffff));\n const targetSegment = Number((ptr >> BigInt(32)) & BigInt(0xffffffff));\n return { tag, doubleFar, targetSegment, targetOffset };\n }\n\n default:\n return { tag: PointerTag.OTHER };\n }\n}\n\n/**\n * 编码 Struct 指针\n */\nexport function encodeStructPointer(\n offset: number,\n dataWords: number,\n pointerCount: number\n): bigint {\n const offsetBits = BigInt(offset < 0 ? offset + 0x40000000 : offset) & BigInt(0x3fffffff);\n return (\n (offsetBits << BigInt(2)) |\n (BigInt(dataWords) << BigInt(32)) |\n (BigInt(pointerCount) << BigInt(48))\n );\n}\n\n/**\n * 编码 List 指针\n */\nexport function encodeListPointer(\n offset: number,\n elementSize: ElementSize,\n elementCount: number\n): bigint {\n const offsetBits = BigInt(offset < 0 ? offset + 0x40000000 : offset) & BigInt(0x3fffffff);\n return (\n (offsetBits << BigInt(2)) |\n BigInt(1) | // LIST tag\n (BigInt(elementSize) << BigInt(32)) |\n (BigInt(elementCount) << BigInt(35))\n );\n}\n\n/**\n * 编码 Far 指针\n */\nexport function encodeFarPointer(segment: number, offset: number, doubleFar = false): bigint {\n const offsetBits = BigInt(offset) & BigInt(0x1fffffff);\n const segmentBits = BigInt(segment) & BigInt(0xffffffff);\n\n return (\n (segmentBits << BigInt(32)) |\n (offsetBits << BigInt(3)) |\n (doubleFar ? BigInt(1) << BigInt(2) : BigInt(0)) |\n BigInt(2)\n ); // FAR tag\n}\n","/**\n * Cap'n Proto Segment 管理\n * 纯 TypeScript 实现\n */\n\nexport const WORD_SIZE = 8;\n\nexport class Segment {\n private buffer: ArrayBuffer;\n private view: DataView;\n private _size: number; // 当前已使用字节数\n\n constructor(initialCapacity = 1024) {\n this.buffer = new ArrayBuffer(initialCapacity);\n this.view = new DataView(this.buffer);\n this._size = 0;\n }\n\n /**\n * 从现有 buffer 创建(用于读取)\n */\n static fromBuffer(buffer: ArrayBuffer): Segment {\n const seg = new Segment(0);\n seg.buffer = buffer;\n seg.view = new DataView(buffer);\n seg._size = buffer.byteLength;\n return seg;\n }\n\n /**\n * 确保容量足够\n */\n private ensureCapacity(minBytes: number): void {\n if (this.buffer.byteLength >= minBytes) return;\n\n // 双倍扩展\n let newCapacity = this.buffer.byteLength * 2;\n while (newCapacity < minBytes) {\n newCapacity *= 2;\n }\n\n const newBuffer = new ArrayBuffer(newCapacity);\n new Uint8Array(newBuffer).set(new Uint8Array(this.buffer, 0, this._size));\n this.buffer = newBuffer;\n this.view = new DataView(newBuffer);\n }\n\n /**\n * 分配空间,返回字偏移\n */\n allocate(words: number): number {\n const bytes = words * WORD_SIZE;\n const offset = this._size;\n this.ensureCapacity(offset + bytes);\n this._size = offset + bytes;\n return offset / WORD_SIZE;\n }\n\n /**\n * 获取字(64位)\n */\n getWord(wordOffset: number): bigint {\n const byteOffset = wordOffset * WORD_SIZE;\n if (byteOffset + 8 > this._size) {\n throw new Error(\n `Offset ${wordOffset} is outside the bounds of the segment (${this.wordCount} words)`\n );\n }\n const low = BigInt(this.view.getUint32(byteOffset, true));\n const high = BigInt(this.view.getUint32(byteOffset + 4, true));\n return (high << BigInt(32)) | low;\n }\n\n /**\n * 设置字(64位)\n */\n setWord(wordOffset: number, value: bigint): void {\n const byteOffset = wordOffset * WORD_SIZE;\n if (byteOffset + 8 > this.buffer.byteLength) {\n throw new Error(`Offset ${wordOffset} is outside the bounds of the segment`);\n }\n this.view.setUint32(byteOffset, Number(value & BigInt(0xffffffff)), true);\n this.view.setUint32(byteOffset + 4, Number(value >> BigInt(32)), true);\n }\n\n /**\n * 获取原始 buffer(只读到 _size)\n */\n asUint8Array(): Uint8Array {\n return new Uint8Array(this.buffer, 0, this._size);\n }\n\n /**\n * 获取底层 ArrayBuffer\n */\n getArrayBuffer(): ArrayBuffer {\n return this.buffer;\n }\n\n /**\n * 获取字数量\n */\n get wordCount(): number {\n return this._size / WORD_SIZE;\n }\n\n /**\n * 获取字节数量\n */\n get byteLength(): number {\n return this._size;\n }\n\n /**\n * 获取 DataView\n */\n get dataView(): DataView {\n return this.view;\n }\n}\n","/**\n * Cap'n Proto MessageBuilder\n * 纯 TypeScript 实现\n */\n\nimport { ListBuilder } from './list.js';\nimport { ElementSize, PointerTag, encodeListPointer, encodeStructPointer } from './pointer.js';\nimport { Segment, WORD_SIZE } from './segment.js';\n\nexport class MessageBuilder {\n private segment: Segment;\n private rootSet = false;\n\n constructor() {\n // 预留消息头空间(假设单段)\n this.segment = new Segment(1024);\n // 预留 8 字节给段大小\n this.segment.allocate(1);\n }\n\n /**\n * 初始化根结构\n */\n initRoot(dataWords: number, pointerCount: number): StructBuilder {\n if (this.rootSet) {\n throw new Error('Root already initialized');\n }\n\n // 分配根结构空间\n const size = dataWords + pointerCount;\n const structOffset = this.segment.allocate(size);\n\n // 在位置 0 写入根指针\n const rootPtr = encodeStructPointer(structOffset - 1, dataWords, pointerCount);\n this.segment.setWord(0, rootPtr);\n\n this.rootSet = true;\n\n return new StructBuilder(this, 0, structOffset, dataWords, pointerCount);\n }\n\n /**\n * 序列化为 ArrayBuffer\n */\n toArrayBuffer(): ArrayBuffer {\n const segmentData = this.segment.asUint8Array();\n const wordCount = this.segment.wordCount;\n\n // 构建消息头\n // 第一个字:段数量-1(低32位)和第一段大小(高32位)\n const header = new ArrayBuffer(8);\n const headerView = new DataView(header);\n headerView.setUint32(0, 0, true); // 段数量-1 = 0(单段)\n headerView.setUint32(4, wordCount, true); // 第一段大小\n\n // 合并头和数据\n const result = new Uint8Array(8 + segmentData.byteLength);\n result.set(new Uint8Array(header), 0);\n result.set(segmentData, 8);\n\n return result.buffer;\n }\n\n /**\n * 获取段(内部使用)\n */\n getSegment(): Segment {\n return this.segment;\n }\n}\n\n/**\n * 结构构建器\n */\nexport class StructBuilder {\n constructor(\n private message: MessageBuilder,\n private segmentIndex: number,\n private wordOffset: number,\n private dataWords: number,\n private pointerCount: number\n ) {}\n\n /**\n * 设置 bool 字段\n */\n setBool(bitOffset: number, value: boolean): void {\n const byteOffset = Math.floor(bitOffset / 8);\n const bitInByte = bitOffset % 8;\n const segment = this.message.getSegment();\n const view = segment.dataView;\n const offset = this.wordOffset * WORD_SIZE + byteOffset;\n\n const current = view.getUint8(offset);\n const newValue = value ? current | (1 << bitInByte) : current & ~(1 << bitInByte);\n view.setUint8(offset, newValue);\n }\n\n /**\n * 设置 int8 字段\n */\n setInt8(byteOffset: number, value: number): void {\n const segment = this.message.getSegment();\n segment.dataView.setInt8(this.wordOffset * WORD_SIZE + byteOffset, value);\n }\n\n /**\n * 设置 int16 字段\n */\n setInt16(byteOffset: number, value: number): void {\n const segment = this.message.getSegment();\n segment.dataView.setInt16(this.wordOffset * WORD_SIZE + byteOffset, value, true);\n }\n\n /**\n * 设置 int32 字段\n */\n setInt32(byteOffset: number, value: number): void {\n const segment = this.message.getSegment();\n segment.dataView.setInt32(this.wordOffset * WORD_SIZE + byteOffset, value, true);\n }\n\n /**\n * 设置 int64 字段\n */\n setInt64(byteOffset: number, value: bigint): void {\n const segment = this.message.getSegment();\n const offset = this.wordOffset * WORD_SIZE + byteOffset;\n segment.dataView.setUint32(offset, Number(value & BigInt(0xffffffff)), true);\n segment.dataView.setInt32(offset + 4, Number(value >> BigInt(32)), true);\n }\n\n /**\n * 设置 uint8 字段\n */\n setUint8(byteOffset: number, value: number): void {\n const segment = this.message.getSegment();\n segment.dataView.setUint8(this.wordOffset * WORD_SIZE + byteOffset, value);\n }\n\n /**\n * 设置 uint16 字段\n */\n setUint16(byteOffset: number, value: number): void {\n const segment = this.message.getSegment();\n segment.dataView.setUint16(this.wordOffset * WORD_SIZE + byteOffset, value, true);\n }\n\n /**\n * 设置 uint32 字段\n */\n setUint32(byteOffset: number, value: number): void {\n const segment = this.message.getSegment();\n segment.dataView.setUint32(this.wordOffset * WORD_SIZE + byteOffset, value, true);\n }\n\n /**\n * 设置 uint64 字段\n */\n setUint64(byteOffset: number, value: bigint): void {\n const segment = this.message.getSegment();\n const offset = this.wordOffset * WORD_SIZE + byteOffset;\n segment.dataView.setUint32(offset, Number(value & BigInt(0xffffffff)), true);\n segment.dataView.setUint32(offset + 4, Number(value >> BigInt(32)), true);\n }\n\n /**\n * 设置 float32 字段\n */\n setFloat32(byteOffset: number, value: number): void {\n const segment = this.message.getSegment();\n segment.dataView.setFloat32(this.wordOffset * WORD_SIZE + byteOffset, value, true);\n }\n\n /**\n * 设置 float64 字段\n */\n setFloat64(byteOffset: number, value: number): void {\n const segment = this.message.getSegment();\n segment.dataView.setFloat64(this.wordOffset * WORD_SIZE + byteOffset, value, true);\n }\n\n /**\n * 获取 uint16 字段(用于 UnionBuilder 读取 tag)\n */\n getUint16(byteOffset: number): number {\n const segment = this.message.getSegment();\n return segment.dataView.getUint16(this.wordOffset * WORD_SIZE + byteOffset, true);\n }\n\n /**\n * 设置文本字段\n */\n setText(pointerIndex: number, value: string): void {\n const ptrOffset = this.wordOffset + this.dataWords + pointerIndex;\n const segment = this.message.getSegment();\n\n // 编码文本\n const bytes = new TextEncoder().encode(`${value}\\0`);\n const wordCount = Math.ceil(bytes.length / WORD_SIZE);\n const listOffset = segment.allocate(wordCount);\n\n // 写入文本数据\n new Uint8Array(segment.dataView.buffer, listOffset * WORD_SIZE, bytes.length).set(bytes);\n\n // 写入指针\n const ptr = encodeListPointer(listOffset - ptrOffset - 1, ElementSize.BYTE, bytes.length);\n segment.setWord(ptrOffset, ptr);\n }\n\n /**\n * 初始化嵌套结构\n */\n initStruct(pointerIndex: number, dataWords: number, pointerCount: number): StructBuilder {\n const ptrOffset = this.wordOffset + this.dataWords + pointerIndex;\n const segment = this.message.getSegment();\n\n // 分配结构空间\n const size = dataWords + pointerCount;\n const structOffset = segment.allocate(size);\n\n // 写入指针\n const ptr = encodeStructPointer(structOffset - ptrOffset - 1, dataWords, pointerCount);\n segment.setWord(ptrOffset, ptr);\n\n return new StructBuilder(this.message, 0, structOffset, dataWords, pointerCount);\n }\n\n /**\n * 初始化列表\n */\n initList<T>(\n pointerIndex: number,\n elementSize: ElementSize,\n elementCount: number,\n structSize?: { dataWords: number; pointerCount: number }\n ): ListBuilder<T> {\n const ptrOffset = this.wordOffset + this.dataWords + pointerIndex;\n const segment = this.message.getSegment();\n\n // 计算列表大小\n let elementWords = 1;\n if (elementSize === ElementSize.BYTE) elementWords = 1;\n else if (elementSize === ElementSize.TWO_BYTES) elementWords = 1;\n else if (elementSize === ElementSize.FOUR_BYTES) elementWords = 1;\n else if (elementSize === ElementSize.EIGHT_BYTES) elementWords = 1;\n else if (elementSize === ElementSize.COMPOSITE && structSize) {\n elementWords = structSize.dataWords + structSize.pointerCount;\n }\n\n const totalWords = elementWords * elementCount;\n const listOffset = segment.allocate(totalWords);\n\n // 写入指针\n const ptr = encodeListPointer(listOffset - ptrOffset - 1, elementSize, elementCount);\n segment.setWord(ptrOffset, ptr);\n\n return new ListBuilder<T>(this.message, elementSize, elementCount, structSize, listOffset);\n }\n}\n","/**\n * Cap'n Proto List 实现\n * 纯 TypeScript\n */\n\nimport { type MessageBuilder, StructBuilder } from './message-builder.js';\nimport { type MessageReader, StructReader } from './message-reader.js';\nimport { ElementSize, type ListPointer, PointerTag, decodePointer } from './pointer.js';\nimport { type Segment, WORD_SIZE } from './segment.js';\n\n/**\n * ListReader - 读取列表\n */\nexport class ListReader<T> {\n private segment: Segment;\n private startOffset: number; // 字偏移\n private segmentIndex: number;\n\n constructor(\n private message: MessageReader,\n segmentIndex: number,\n private elementSize: ElementSize,\n private elementCount: number,\n private structSize: { dataWords: number; pointerCount: number } | undefined,\n wordOffset: number\n ) {\n this.segmentIndex = segmentIndex;\n this.segment = message.getSegment(segmentIndex)!;\n this.startOffset = wordOffset;\n }\n\n /**\n * 列表长度\n */\n get length(): number {\n return this.elementCount;\n }\n\n /**\n * 获取元素(基础类型)\n */\n getPrimitive(index: number): number | bigint {\n if (index < 0 || index >= this.elementCount) {\n throw new RangeError('Index out of bounds');\n }\n\n switch (this.elementSize) {\n case ElementSize.BIT: {\n const byteOffset = Math.floor(index / 8);\n const bitInByte = index % 8;\n const byte = this.segment.dataView.getUint8(this.startOffset * WORD_SIZE + byteOffset);\n return (byte & (1 << bitInByte)) !== 0 ? 1 : 0;\n }\n\n case ElementSize.BYTE:\n return this.segment.dataView.getUint8(this.startOffset * WORD_SIZE + index);\n\n case ElementSize.TWO_BYTES:\n return this.segment.dataView.getUint16(this.startOffset * WORD_SIZE + index * 2, true);\n\n case ElementSize.FOUR_BYTES:\n return this.segment.dataView.getUint32(this.startOffset * WORD_SIZE + index * 4, true);\n\n case ElementSize.EIGHT_BYTES: {\n const offset = this.startOffset * WORD_SIZE + index * 8;\n const low = BigInt(this.segment.dataView.getUint32(offset, true));\n const high = BigInt(this.segment.dataView.getUint32(offset + 4, true));\n return (high << BigInt(32)) | low;\n }\n\n default:\n throw new Error(`Unsupported element size: ${this.elementSize}`);\n }\n }\n\n /**\n * 获取结构元素\n */\n getStruct(index: number): StructReader {\n if (!this.structSize) {\n throw new Error('Not a struct list');\n }\n\n const { dataWords, pointerCount } = this.structSize;\n const size = dataWords + pointerCount;\n const offset = this.startOffset + index * size;\n\n return new StructReader(this.message, this.segmentIndex, offset, dataWords, pointerCount);\n }\n\n /**\n * 迭代器\n */\n *[Symbol.iterator](): Iterator<T> {\n for (let i = 0; i < this.elementCount; i++) {\n yield this.getPrimitive(i) as T;\n }\n }\n}\n\n/**\n * ListBuilder - 构建列表\n */\nexport class ListBuilder<_T> {\n private segment: Segment;\n private startOffset: number;\n\n constructor(\n private message: MessageBuilder,\n private elementSize: ElementSize,\n private elementCount: number,\n private structSize: { dataWords: number; pointerCount: number } | undefined,\n wordOffset: number\n ) {\n this.segment = message.getSegment();\n this.startOffset = wordOffset;\n }\n\n /**\n * 列表长度\n */\n get length(): number {\n return this.elementCount;\n }\n\n /**\n * 设置基础类型元素\n */\n setPrimitive(index: number, value: number | bigint): void {\n if (index < 0 || index >= this.elementCount) {\n throw new RangeError('Index out of bounds');\n }\n\n switch (this.elementSize) {\n case ElementSize.BIT: {\n const byteOffset = Math.floor(index / 8);\n const bitInByte = index % 8;\n const offset = this.startOffset * WORD_SIZE + byteOffset;\n const current = this.segment.dataView.getUint8(offset);\n const newValue = value ? current | (1 << bitInByte) : current & ~(1 << bitInByte);\n this.segment.dataView.setUint8(offset, newValue);\n break;\n }\n\n case ElementSize.BYTE:\n this.segment.dataView.setUint8(this.startOffset * WORD_SIZE + index, Number(value));\n break;\n\n case ElementSize.TWO_BYTES:\n this.segment.dataView.setUint16(\n this.startOffset * WORD_SIZE + index * 2,\n Number(value),\n true\n );\n break;\n\n case ElementSize.FOUR_BYTES:\n this.segment.dataView.setUint32(\n this.startOffset * WORD_SIZE + index * 4,\n Number(value),\n true\n );\n break;\n\n case ElementSize.EIGHT_BYTES: {\n const offset = this.startOffset * WORD_SIZE + index * 8;\n const bigValue = value as bigint;\n this.segment.dataView.setUint32(offset, Number(bigValue & BigInt(0xffffffff)), true);\n this.segment.dataView.setUint32(offset + 4, Number(bigValue >> BigInt(32)), true);\n break;\n }\n\n default:\n throw new Error(`Unsupported element size: ${this.elementSize}`);\n }\n }\n\n /**\n * 获取结构元素(用于修改)\n */\n getStruct(index: number): StructBuilder {\n if (!this.structSize) {\n throw new Error('Not a struct list');\n }\n\n const { dataWords, pointerCount } = this.structSize;\n const size = dataWords + pointerCount;\n const offset = this.startOffset + index * size;\n\n return new StructBuilder(this.message, 0, offset, dataWords, pointerCount);\n }\n}\n","/**\n * Cap'n Proto MessageReader\n * 纯 TypeScript 实现\n */\n\nimport { ListReader } from './list.js';\nimport {\n ElementSize,\n type FarPointer,\n type ListPointer,\n PointerTag,\n type StructPointer,\n decodePointer,\n} from './pointer.js';\nimport { Segment, WORD_SIZE } from './segment.js';\n\nexport class MessageReader {\n private segments: Segment[];\n\n constructor(buffer: ArrayBuffer | Uint8Array) {\n const uint8Array = buffer instanceof ArrayBuffer ? new Uint8Array(buffer) : buffer;\n\n // 初始化空段数组(用于无效消息)\n this.segments = [];\n\n // 检查最小大小(至少需要8字节的头部)\n if (uint8Array.byteLength < 8) {\n // 消息太小,视为空消息\n return;\n }\n\n // 解析消息头\n // 第一个字:段数量-1(低32位)和第一段大小(高32位)\n const view = new DataView(uint8Array.buffer, uint8Array.byteOffset, uint8Array.byteLength);\n const firstWordLow = view.getUint32(0, true);\n const firstWordHigh = view.getUint32(4, true);\n\n const segmentCount = (firstWordLow & 0xffffffff) + 1;\n const firstSegmentSize = firstWordHigh;\n\n let offset = 8;\n const segmentSizes: number[] = [firstSegmentSize];\n\n // 读取剩余段大小\n for (let i = 1; i < segmentCount; i++) {\n if (offset + 4 > uint8Array.byteLength) {\n // 消息过早结束,视为空消息\n this.segments = [];\n return;\n }\n segmentSizes.push(view.getUint32(offset, true));\n offset += 4;\n }\n\n // 对齐到 8 字节\n offset = (offset + 7) & ~7;\n\n // 检查是否有足够的空间容纳段表\n if (offset > uint8Array.byteLength) {\n this.segments = [];\n return;\n }\n\n // 创建段\n this.segments = [];\n for (const size of segmentSizes) {\n if (offset + size * WORD_SIZE > uint8Array.byteLength) {\n // 段数据不足,截断或视为空消息\n // 官方实现:返回已读取的部分\n break;\n }\n const segmentBuffer = uint8Array.slice(offset, offset + size * WORD_SIZE);\n this.segments.push(Segment.fromBuffer(segmentBuffer.buffer));\n offset += size * WORD_SIZE;\n }\n }\n\n /**\n * 获取根结构\n */\n getRoot(_dataWords: number, _pointerCount: number): StructReader {\n // root 指针在位置 0,解析它找到实际数据位置\n const segment = this.segments[0];\n const ptr = decodePointer(segment.getWord(0));\n\n if (ptr.tag === PointerTag.STRUCT) {\n const structPtr = ptr as StructPointer;\n const dataOffset = 1 + structPtr.offset; // 跳过指针本身\n return new StructReader(this, 0, dataOffset, structPtr.dataWords, structPtr.pointerCount);\n }\n\n if (ptr.tag === PointerTag.FAR) {\n // Far pointer: 指向另一个 segment 中的 landing pad\n const farPtr = ptr as FarPointer;\n const targetSegment = this.getSegment(farPtr.targetSegment);\n if (!targetSegment) {\n throw new Error(`Far pointer references non-existent segment ${farPtr.targetSegment}`);\n }\n\n if (farPtr.doubleFar) {\n // Double-far: landing pad 本身也是一个 far 指针\n // landing pad 位置: targetOffset 指向的位置\n const landingPadPtr = decodePointer(targetSegment.getWord(farPtr.targetOffset));\n if (landingPadPtr.tag !== PointerTag.FAR) {\n throw new Error('Double-far landing pad is not a far pointer');\n }\n const innerFarPtr = landingPadPtr as FarPointer;\n const finalSegment = this.getSegment(innerFarPtr.targetSegment);\n if (!finalSegment) {\n throw new Error(\n `Double-far references non-existent segment ${innerFarPtr.targetSegment}`\n );\n }\n // 实际的 struct 指针在 innerFarPtr.targetOffset\n const structPtr = decodePointer(\n finalSegment.getWord(innerFarPtr.targetOffset)\n ) as StructPointer;\n const dataOffset = innerFarPtr.targetOffset + 1 + structPtr.offset;\n return new StructReader(\n this,\n innerFarPtr.targetSegment,\n dataOffset,\n structPtr.dataWords,\n structPtr.pointerCount\n );\n }\n // Single-far: landing pad 是实际的 struct 指针\n const structPtr = decodePointer(targetSegment.getWord(farPtr.targetOffset)) as StructPointer;\n const dataOffset = farPtr.targetOffset + 1 + structPtr.offset;\n return new StructReader(\n this,\n farPtr.targetSegment,\n dataOffset,\n structPtr.dataWords,\n structPtr.pointerCount\n );\n }\n\n throw new Error(`Root pointer is not a struct or far pointer: ${ptr.tag}`);\n }\n\n /**\n * 获取段\n */\n getSegment(index: number): Segment | undefined {\n return this.segments[index];\n }\n\n /**\n * 解析指针,处理 far pointer 间接寻址\n * 返回 { segmentIndex, wordOffset, pointer },其中 pointer 是实际的 struct/list 指针\n */\n resolvePointer(\n segmentIndex: number,\n wordOffset: number\n ): { segmentIndex: number; wordOffset: number; pointer: StructPointer | ListPointer } | null {\n const segment = this.getSegment(segmentIndex);\n if (!segment) return null;\n\n const ptrValue = segment.getWord(wordOffset);\n if (ptrValue === 0n) return null;\n\n const ptr = decodePointer(ptrValue);\n\n if (ptr.tag === PointerTag.STRUCT || ptr.tag === PointerTag.LIST) {\n // 直接指针,计算目标偏移\n const targetOffset = wordOffset + 1 + ptr.offset;\n return {\n segmentIndex,\n wordOffset: targetOffset,\n pointer: ptr as StructPointer | ListPointer,\n };\n }\n\n if (ptr.tag === PointerTag.FAR) {\n const farPtr = ptr as FarPointer;\n const targetSegment = this.getSegment(farPtr.targetSegment);\n if (!targetSegment) return null;\n\n if (farPtr.doubleFar) {\n // Double-far: landing pad 指向另一个 far 指针\n const landingPadPtr = decodePointer(targetSegment.getWord(farPtr.targetOffset));\n if (landingPadPtr.tag !== PointerTag.FAR) return null;\n const innerFarPtr = landingPadPtr as FarPointer;\n const finalSegment = this.getSegment(innerFarPtr.targetSegment);\n if (!finalSegment) return null;\n const finalPtr = decodePointer(finalSegment.getWord(innerFarPtr.targetOffset));\n if (finalPtr.tag !== PointerTag.STRUCT && finalPtr.tag !== PointerTag.LIST) return null;\n const targetOffset = innerFarPtr.targetOffset + 1 + finalPtr.offset;\n return {\n segmentIndex: innerFarPtr.targetSegment,\n wordOffset: targetOffset,\n pointer: finalPtr as StructPointer | ListPointer,\n };\n }\n // Single-far: landing pad 是实际的指针\n const landingPadPtr = decodePointer(targetSegment.getWord(farPtr.targetOffset));\n if (landingPadPtr.tag !== PointerTag.STRUCT && landingPadPtr.tag !== PointerTag.LIST)\n return null;\n const targetOffset = farPtr.targetOffset + 1 + landingPadPtr.offset;\n return {\n segmentIndex: farPtr.targetSegment,\n wordOffset: targetOffset,\n pointer: landingPadPtr as StructPointer | ListPointer,\n };\n }\n\n return null;\n }\n\n /**\n * 段数量\n */\n get segmentCount(): number {\n return this.segments.length;\n }\n}\n\n/**\n * 结构读取器\n */\nexport class StructReader {\n constructor(\n private message: MessageReader,\n private segmentIndex: number,\n private wordOffset: number,\n private dataWords: number,\n private pointerCount: number\n ) {}\n\n /**\n * 获取 bool 字段\n */\n getBool(bitOffset: number): boolean {\n const byteOffset = Math.floor(bitOffset / 8);\n const bitInByte = bitOffset % 8;\n const segment = this.message.getSegment(this.segmentIndex)!;\n const dataOffset = this.wordOffset * WORD_SIZE + byteOffset;\n\n // 边界检查:确保在 data section 内\n const dataSectionEnd = this.wordOffset * WORD_SIZE + this.dataWords * WORD_SIZE;\n if (dataOffset < 0 || dataOffset >= dataSectionEnd) {\n return false; // 越界返回默认值\n }\n\n const byte = segment.dataView.getUint8(dataOffset);\n return (byte & (1 << bitInByte)) !== 0;\n }\n\n /**\n * 获取 int8 字段\n */\n getInt8(byteOffset: number): number {\n const segment = this.message.getSegment(this.segmentIndex)!;\n const dataOffset = this.wordOffset * WORD_SIZE + byteOffset;\n\n // 边界检查\n const dataSectionEnd = this.wordOffset * WORD_SIZE + this.dataWords * WORD_SIZE;\n if (dataOffset < 0 || dataOffset >= dataSectionEnd) {\n return 0;\n }\n\n return segment.dataView.getInt8(dataOffset);\n }\n\n /**\n * 获取 int16 字段\n */\n getInt16(byteOffset: number): number {\n const segment = this.message.getSegment(this.segmentIndex)!;\n const dataOffset = this.wordOffset * WORD_SIZE + byteOffset;\n\n // 边界检查\n const dataSectionEnd = this.wordOffset * WORD_SIZE + this.dataWords * WORD_SIZE;\n if (dataOffset < 0 || dataOffset + 2 > dataSectionEnd) {\n return 0;\n }\n\n return segment.dataView.getInt16(dataOffset, true);\n }\n\n /**\n * 获取 int32 字段\n */\n getInt32(byteOffset: number): number {\n const segment = this.message.getSegment(this.segmentIndex)!;\n const dataOffset = this.wordOffset * WORD_SIZE + byteOffset;\n\n // 边界检查\n const dataSectionEnd = this.wordOffset * WORD_SIZE + this.dataWords * WORD_SIZE;\n if (dataOffset < 0 || dataOffset + 4 > dataSectionEnd) {\n return 0;\n }\n\n return segment.dataView.getInt32(dataOffset, true);\n }\n\n /**\n * 获取 int64 字段\n */\n getInt64(byteOffset: number): bigint {\n const segment = this.message.getSegment(this.segmentIndex)!;\n const dataOffset = this.wordOffset * WORD_SIZE + byteOffset;\n\n // 边界检查\n const dataSectionEnd = this.wordOffset * WORD_SIZE + this.dataWords * WORD_SIZE;\n if (dataOffset < 0 || dataOffset + 8 > dataSectionEnd) {\n return BigInt(0);\n }\n\n const low = BigInt(segment.dataView.getUint32(dataOffset, true));\n const high = BigInt(segment.dataView.getInt32(dataOffset + 4, true));\n return (high << BigInt(32)) | low;\n }\n\n /**\n * 获取 uint8 字段\n */\n getUint8(byteOffset: number): number {\n const segment = this.message.getSegment(this.segmentIndex)!;\n const dataOffset = this.wordOffset * WORD_SIZE + byteOffset;\n\n // 边界检查\n const dataSectionEnd = this.wordOffset * WORD_SIZE + this.dataWords * WORD_SIZE;\n if (dataOffset < 0 || dataOffset >= dataSectionEnd) {\n return 0;\n }\n\n return segment.dataView.getUint8(dataOffset);\n }\n\n /**\n * 获取 uint16 字段\n */\n getUint16(byteOffset: number): number {\n const segment = this.message.getSegment(this.segmentIndex)!;\n const dataOffset = this.wordOffset * WORD_SIZE + byteOffset;\n\n // 边界检查\n const dataSectionEnd = this.wordOffset * WORD_SIZE + this.dataWords * WORD_SIZE;\n if (dataOffset < 0 || dataOffset + 2 > dataSectionEnd) {\n return 0;\n }\n\n return segment.dataView.getUint16(dataOffset, true);\n }\n\n /**\n * 获取 uint32 字段\n */\n getUint32(byteOffset: number): number {\n const segment = this.message.getSegment(this.segmentIndex)!;\n const dataOffset = this.wordOffset * WORD_SIZE + byteOffset;\n\n // 边界检查\n const dataSectionEnd = this.wordOffset * WORD_SIZE + this.dataWords * WORD_SIZE;\n if (dataOffset < 0 || dataOffset + 4 > dataSectionEnd) {\n return 0;\n }\n\n return segment.dataView.getUint32(dataOffset, true);\n }\n\n /**\n * 获取 uint64 字段\n */\n getUint64(byteOffset: number): bigint {\n const segment = this.message.getSegment(this.segmentIndex)!;\n const dataOffset = this.wordOffset * WORD_SIZE + byteOffset;\n\n // 边界检查\n const dataSectionEnd = this.wordOffset * WORD_SIZE + this.dataWords * WORD_SIZE;\n if (dataOffset < 0 || dataOffset + 8 > dataSectionEnd) {\n return BigInt(0);\n }\n\n const low = BigInt(segment.dataView.getUint32(dataOffset, true));\n const high = BigInt(segment.dataView.getUint32(dataOffset + 4, true));\n return (high << BigInt(32)) | low;\n }\n\n /**\n * 获取 float32 字段\n */\n getFloat32(byteOffset: number): number {\n const segment = this.message.getSegment(this.segmentIndex)!;\n const dataOffset = this.wordOffset * WORD_SIZE + byteOffset;\n\n // 边界检查\n const dataSectionEnd = this.wordOffset * WORD_SIZE + this.dataWords * WORD_SIZE;\n if (dataOffset < 0 || dataOffset + 4 > dataSectionEnd) {\n return 0;\n }\n\n return segment.dataView.getFloat32(dataOffset, true);\n }\n\n /**\n * 获取 float64 字段\n */\n getFloat64(byteOffset: number): number {\n const segment = this.message.getSegment(this.segmentIndex)!;\n const dataOffset = this.wordOffset * WORD_SIZE + byteOffset;\n\n // 边界检查\n const dataSectionEnd = this.wordOffset * WORD_SIZE + this.dataWords * WORD_SIZE;\n if (dataOffset < 0 || dataOffset + 8 > dataSectionEnd) {\n return 0;\n }\n\n return segment.dataView.getFloat64(dataOffset, true);\n }\n\n /**\n * 获取文本字段\n */\n getText(pointerIndex: number): string {\n const ptrOffset = this.wordOffset + this.dataWords + pointerIndex;\n const resolved = this.message.resolvePointer(this.segmentIndex, ptrOffset);\n\n if (!resolved) return '';\n\n const { segmentIndex, wordOffset, pointer } = resolved;\n if (pointer.tag !== PointerTag.LIST) return '';\n\n const listPtr = pointer as ListPointer;\n const segment = this.message.getSegment(segmentIndex)!;\n\n // Text is stored as List(UInt8) with NUL terminator\n // elementCount includes the NUL terminator\n const byteLength = listPtr.elementCount > 0 ? listPtr.elementCount - 1 : 0;\n if (byteLength === 0) return '';\n\n // 读取文本字节\n const bytes = new Uint8Array(segment.dataView.buffer, wordOffset * WORD_SIZE, byteLength);\n return new TextDecoder().decode(bytes);\n }\n\n /**\n * 获取嵌套结构\n */\n getStruct(\n pointerIndex: number,\n _dataWords: number,\n _pointerCount: number\n ): StructReader | undefined {\n const ptrOffset = this.wordOffset + this.dataWords + pointerIndex;\n const resolved = this.message.resolvePointer(this.segmentIndex, ptrOffset);\n\n if (!resolved) return undefined;\n\n const { segmentIndex, wordOffset, pointer } = resolved;\n if (pointer.tag !== PointerTag.STRUCT) return undefined;\n\n const structPtr = pointer as StructPointer;\n\n return new StructReader(\n this.message,\n segmentIndex,\n wordOffset,\n structPtr.dataWords,\n structPtr.pointerCount\n );\n }\n\n /**\n * 获取列表\n */\n getList<T>(\n pointerIndex: number,\n _elementSize: ElementSize,\n structSize?: { dataWords: number; pointerCount: number }\n ): ListReader<T> | undefined {\n const ptrOffset = this.wordOffset + this.dataWords + pointerIndex;\n const resolved = this.message.resolvePointer(this.segmentIndex, ptrOffset);\n\n if (!resolved) return undefined;\n\n const { segmentIndex, wordOffset, pointer } = resolved;\n if (pointer.tag !== PointerTag.LIST) return undefined;\n\n const listPtr = pointer as ListPointer;\n let targetOffset = wordOffset;\n let elementCount = listPtr.elementCount;\n let actualStructSize = structSize;\n const segment = this.message.getSegment(segmentIndex)!;\n\n // For INLINE_COMPOSITE lists, read the tag word\n if (listPtr.elementSize === ElementSize.COMPOSITE) {\n // 边界检查:确保有足够的空间读取 tag word\n if (targetOffset < 0 || targetOffset >= segment.wordCount) {\n return undefined;\n }\n\n try {\n const tagWord = segment.getWord(targetOffset);\n // Tag word: elementCount (32 bits) | dataWords (16 bits) | pointerCount (16 bits)\n elementCount = Number(tagWord & BigInt(0xffffffff));\n const dataWords = Number((tagWord >> BigInt(32)) & BigInt(0xffff));\n const pointerCount = Number((tagWord >> BigInt(48)) & BigInt(0xffff));\n actualStructSize = { dataWords, pointerCount };\n targetOffset += 1; // Skip tag word\n } catch {\n return undefined;\n }\n }\n\n return new ListReader<T>(\n this.message,\n segmentIndex,\n listPtr.elementSize,\n elementCount,\n actualStructSize,\n targetOffset\n );\n }\n}\n","/**\n * Cap'n Proto Union 支持\n * 纯 TypeScript 实现\n */\n\nimport { MessageBuilder, type StructBuilder } from './message-builder.js';\nimport { MessageReader, type StructReader } from './message-reader.js';\nimport { ElementSize } from './pointer.js';\n\n/**\n * UnionReader - 读取 Union 的 tag 和 variant\n */\nexport class UnionReader {\n constructor(\n private struct: StructReader,\n private tagOffset: number, // tag 的字节偏移\n private variants: Map<number, string> // tag 值 -> variant 名称\n ) {}\n\n /**\n * 获取当前激活的 variant tag\n */\n getTag(): number {\n return this.struct.getUint16(this.tagOffset);\n }\n\n /**\n * 获取当前激活的 variant 名称\n */\n getVariantName(): string | undefined {\n return this.variants.get(this.getTag());\n }\n\n /**\n * 检查是否是某个 variant\n */\n is(variantTag: number): boolean {\n return this.getTag() === variantTag;\n }\n}\n\n/**\n * UnionBuilder - 设置 Union 的 tag 和 variant\n */\nexport class UnionBuilder {\n constructor(\n private struct: StructBuilder,\n private tagOffset: number\n ) {}\n\n /**\n * 获取当前 tag\n */\n getTag(): number {\n return this.struct.getUint16(this.tagOffset);\n }\n\n /**\n * 设置 tag\n */\n setTag(tag: number): void {\n this.struct.setUint16(this.tagOffset, tag);\n }\n\n /**\n * 初始化某个 variant(自动设置 tag)\n */\n initVariant(tag: number, initFn: () => void): void {\n this.setTag(tag);\n initFn();\n }\n}\n\n/**\n * 创建 UnionReader 的工厂函数\n */\nexport function createUnionReader(\n struct: StructReader,\n tagOffset: number,\n variants: Record<number, string>\n): UnionReader {\n return new UnionReader(\n struct,\n tagOffset,\n new Map(Object.entries(variants).map(([k, v]) => [Number(k), v]))\n );\n}\n\n/**\n * 创建 UnionBuilder 的工厂函数\n */\nexport function createUnionBuilder(struct: StructBuilder, tagOffset: number): UnionBuilder {\n return new UnionBuilder(struct, tagOffset);\n}\n","/**\n * RPC Message Serialization\n *\n * Implements full serialization/deserialization of RPC messages using\n * the existing MessageBuilder/MessageReader infrastructure.\n *\n * Reference: rpc.capnp schema\n */\n\nimport { MessageBuilder, type StructBuilder } from '../core/message-builder.js';\nimport { MessageReader, type StructReader } from '../core/message-reader.js';\nimport { ElementSize } from '../core/pointer.js';\nimport type {\n Bootstrap,\n Call,\n CapDescriptor,\n Disembargo,\n Exception,\n Finish,\n MessageTarget,\n Payload,\n PromisedAnswer,\n PromisedAnswerOp,\n Provide,\n Release,\n Resolve,\n Return,\n RpcMessage,\n SendResultsTo,\n} from './rpc-types.js';\n\n// ========================================================================================\n// Constants from rpc.capnp schema\n// ========================================================================================\n\n// Message union tags\nconst MSG_UNIMPLEMENTED = 0;\nconst MSG_ABORT = 1;\nconst MSG_BOOTSTRAP = 8;\nconst MSG_CALL = 2;\nconst MSG_RETURN = 3;\nconst MSG_FINISH = 4;\nconst MSG_RESOLVE = 5;\nconst MSG_RELEASE = 6;\nconst MSG_DISEMBARGO = 13;\nconst MSG_PROVIDE = 10;\nconst MSG_ACCEPT = 11;\nconst MSG_JOIN = 12;\n\n// Return union tags\nconst RET_RESULTS = 0;\nconst RET_EXCEPTION = 1;\nconst RET_CANCELED = 2;\nconst RET_RESULTS_SENT_ELSEWHERE = 3;\nconst RET_TAKE_FROM_OTHER_QUESTION = 4;\nconst RET_ACCEPT_FROM_THIRD_PARTY = 5;\n\n// SendResultsTo union tags\nconst SEND_TO_CALLER = 0;\nconst SEND_TO_YOURSELF = 1;\nconst SEND_TO_THIRD_PARTY = 2;\n\n// MessageTarget union tags\nconst TARGET_IMPORTED_CAP = 0;\nconst TARGET_PROMISED_ANSWER = 1;\n\n// CapDescriptor union tags\nconst CAP_NONE = 0;\nconst CAP_SENDER_HOSTED = 1;\nconst CAP_SENDER_PROMISE = 2;\nconst CAP_RECEIVER_HOSTED = 3;\nconst CAP_RECEIVER_ANSWER = 4;\nconst CAP_THIRD_PARTY_HOSTED = 5;\n\n// Resolve union tags\nconst RESOLVE_CAP = 0;\nconst RESOLVE_EXCEPTION = 1;\n\n// Disembargo context union tags\nconst DISEMBARGO_SENDER_LOOPBACK = 0;\nconst DISEMBARGO_RECEIVER_LOOPBACK = 1;\nconst DISEMBARGO_ACCEPT = 2;\nconst DISEMBARGO_PROVIDE = 3;\n\n// PromisedAnswer.Op union tags\nconst OP_NOOP = 0;\nconst OP_GET_POINTER_FIELD = 1;\n\n// Exception type union tags\nconst EXC_FAILED = 0;\nconst EXC_OVERLOADED = 1;\nconst EXC_DISCONNECTED = 2;\nconst EXC_UNIMPLEMENTED = 3;\n\n// ========================================================================================\n// Serialization: RpcMessage -> Uint8Array\n// ========================================================================================\n\nexport function serializeRpcMessage(message: RpcMessage): Uint8Array {\n const builder = new MessageBuilder();\n // Message struct: 6 data words, 1 pointer\n // union + questionId/answerId/promiseId/etc + padding\n const root = builder.initRoot(6, 1);\n\n switch (message.type) {\n case 'unimplemented':\n serializeUnimplemented(root, message.message);\n break;\n case 'abort':\n serializeAbort(root, message.exception);\n break;\n case 'bootstrap':\n serializeBootstrap(root, message.bootstrap);\n break;\n case 'call':\n serializeCall(root, message.call);\n break;\n case 'return':\n serializeReturn(root, message.return);\n break;\n case 'finish':\n serializeFinish(root, message.finish);\n break;\n case 'resolve':\n serializeResolve(root, message.resolve);\n break;\n case 'release':\n serializeRelease(root, message.release);\n break;\n case 'disembargo':\n serializeDisembargo(root, message.disembargo);\n break;\n case 'provide':\n serializeProvide(root, message.provide);\n break;\n case 'accept':\n serializeAccept(root, message.accept);\n break;\n case 'join':\n serializeJoin(root, message.join);\n break;\n }\n\n return new Uint8Array(builder.toArrayBuffer());\n}\n\nfunction serializeUnimplemented(root: StructBuilder, message: RpcMessage): void {\n // Set union tag\n root.setUint16(0, MSG_UNIMPLEMENTED);\n // Serialize nested message in pointer 0\n const _nestedData = serializeRpcMessage(message);\n const nestedBuilder = root.initStruct(0, 0, 1);\n // Copy nested data into the struct's content pointer\n // For simplicity, we store the serialized message as data bytes\n // In a full implementation, we'd properly embed the message structure\n const _contentPtr = nestedBuilder.initStruct(0, 0, 0);\n // Store length and data\n // This is a simplified approach - proper implementation would parse the nested message\n}\n\nfunction serializeAbort(root: StructBuilder, exception: Exception): void {\n root.setUint16(0, MSG_ABORT);\n serializeException(root, 0, exception);\n}\n\nfunction serializeBootstrap(root: StructBuilder, bootstrap: Bootstrap): void {\n root.setUint16(0, MSG_BOOTSTRAP);\n root.setUint32(8, bootstrap.questionId);\n // deprecatedObjectId is deprecated, skip\n}\n\nfunction serializeCall(root: StructBuilder, call: Call): void {\n root.setUint16(0, MSG_CALL);\n root.setUint32(8, call.questionId);\n root.setUint64(16, call.interfaceId);\n root.setUint16(24, call.methodId);\n root.setBool(208, call.allowThirdPartyTailCall); // bit 208 = word 26, bit 0\n root.setBool(209, call.noPromisePipelining); // bit 209\n root.setBool(210, call.onlyPromisePipeline); // bit 210\n\n // Serialize target in pointer 0\n serializeMessageTarget(root.initStruct(0, 2, 1), call.target);\n\n // Serialize params in pointer 1\n serializePayload(root.initStruct(1, 2, 2), call.params);\n\n // Serialize sendResultsTo in pointer 2\n serializeSendResultsTo(root.initStruct(2, 2, 1), call.sendResultsTo);\n}\n\nfunction serializeReturn(root: StructBuilder, ret: Return): void {\n root.setUint16(0, MSG_RETURN);\n root.setUint32(8, ret.answerId);\n root.setBool(192, ret.releaseParamCaps); // bit 192 = word 24, bit 0\n root.setBool(193, ret.noFinishNeeded); // bit 193\n\n // Serialize result based on type\n switch (ret.result.type) {\n case 'results':\n root.setUint16(2, RET_RESULTS);\n serializePayload(root.initStruct(0, 2, 2), ret.result.payload);\n break;\n case 'exception':\n root.setUint16(2, RET_EXCEPTION);\n serializeException(root, 0, ret.result.exception);\n break;\n case 'canceled':\n root.setUint16(2, RET_CANCELED);\n break;\n case 'resultsSentElsewhere':\n root.setUint16(2, RET_RESULTS_SENT_ELSEWHERE);\n break;\n case 'takeFromOtherQuestion':\n root.setUint16(2, RET_TAKE_FROM_OTHER_QUESTION);\n root.setUint32(12, ret.result.questionId);\n break;\n case 'acceptFromThirdParty':\n root.setUint16(2, RET_ACCEPT_FROM_THIRD_PARTY);\n // ThirdPartyCapId in pointer 0\n break;\n }\n}\n\nfunction serializeFinish(root: StructBuilder, finish: Finish): void {\n root.setUint16(0, MSG_FINISH);\n root.setUint32(8, finish.questionId);\n root.setBool(192, finish.releaseResultCaps); // bit 192\n root.setBool(193, finish.requireEarlyCancellationWorkaround); // bit 193\n}\n\nfunction serializeResolve(root: StructBuilder, resolve: Resolve): void {\n root.setUint16(0, MSG_RESOLVE);\n root.setUint32(8, resolve.promiseId);\n\n switch (resolve.resolution.type) {\n case 'cap':\n root.setUint16(2, RESOLVE_CAP);\n serializeCapDescriptor(root.initStruct(0, 2, 1), resolve.resolution.cap);\n break;\n case 'exception':\n root.setUint16(2, RESOLVE_EXCEPTION);\n serializeException(root, 0, resolve.resolution.exception);\n break;\n }\n}\n\nfunction serializeRelease(root: StructBuilder, release: Release): void {\n root.setUint16(0, MSG_RELEASE);\n root.setUint32(8, release.id);\n root.setUint32(12, release.referenceCount);\n}\n\nfunction serializeDisembargo(root: StructBuilder, disembargo: Disembargo): void {\n root.setUint16(0, MSG_DISEMBARGO);\n serializeMessageTarget(root.initStruct(0, 2, 1), disembargo.target);\n\n switch (disembargo.context.type) {\n case 'senderLoopback':\n root.setUint16(2, DISEMBARGO_SENDER_LOOPBACK);\n root.setUint32(12, disembargo.context.embargoId);\n break;\n case 'receiverLoopback':\n root.setUint16(2, DISEMBARGO_RECEIVER_LOOPBACK);\n root.setUint32(12, disembargo.context.embargoId);\n break;\n case 'accept':\n root.setUint16(2, DISEMBARGO_ACCEPT);\n break;\n case 'provide':\n root.setUint16(2, DISEMBARGO_PROVIDE);\n root.setUint32(12, disembargo.context.questionId);\n break;\n }\n}\n\nfunction serializeProvide(root: StructBuilder, provide: Provide): void {\n root.setUint16(0, MSG_PROVIDE);\n root.setUint32(8, provide.questionId);\n serializeMessageTarget(root.initStruct(0, 2, 1), provide.target);\n // RecipientId in pointer 1 - placeholder\n}\n\nfunction serializeAccept(\n _root: StructBuilder,\n _accept: { provision: { id: Uint8Array }; embargo: boolean }\n): void {\n // Level 3 - not fully implemented\n}\n\nfunction serializeJoin(\n _root: StructBuilder,\n _join: { otherCap: MessageTarget; joinId: number }\n): void {\n // Level 4 - not fully implemented\n}\n\n// ========================================================================================\n// Supporting Type Serialization\n// ========================================================================================\n\nfunction serializeMessageTarget(builder: StructBuilder, target: MessageTarget): void {\n switch (target.type) {\n case 'importedCap':\n builder.setUint16(0, TARGET_IMPORTED_CAP);\n builder.setUint32(8, target.importId);\n break;\n case 'promisedAnswer':\n builder.setUint16(0, TARGET_PROMISED_ANSWER);\n serializePromisedAnswer(builder.initStruct(0, 2, 1), target.promisedAnswer);\n break;\n }\n}\n\nfunction serializePromisedAnswer(builder: StructBuilder, promisedAnswer: PromisedAnswer): void {\n builder.setUint32(0, promisedAnswer.questionId);\n // Transform list in pointer 0\n if (promisedAnswer.transform.length > 0) {\n const listBuilder = builder.initList(\n 0,\n ElementSize.INLINE_COMPOSITE,\n promisedAnswer.transform.length,\n {\n dataWords: 2,\n pointerCount: 0,\n }\n );\n for (let i = 0; i < promisedAnswer.transform.length; i++) {\n serializePromisedAnswerOp(listBuilder.getStruct(i), promisedAnswer.transform[i]);\n }\n }\n}\n\nfunction serializePromisedAnswerOp(builder: StructBuilder, op: PromisedAnswerOp): void {\n switch (op.type) {\n case 'noop':\n builder.setUint16(0, OP_NOOP);\n break;\n case 'getPointerField':\n builder.setUint16(0, OP_GET_POINTER_FIELD);\n builder.setUint16(8, op.fieldIndex);\n break;\n }\n}\n\nfunction serializePayload(builder: StructBuilder, payload: Payload): void {\n // Content (AnyPointer) - store as data bytes in pointer 0\n if (payload.content.length > 0) {\n // For now, store raw bytes - in full implementation this would be a proper struct\n const _contentBuilder = builder.initStruct(0, Math.ceil(payload.content.length / 8), 0);\n // Copy bytes into the struct\n }\n\n // Cap table list in pointer 1\n if (payload.capTable.length > 0) {\n const listBuilder = builder.initList(1, ElementSize.EIGHT_BYTES, payload.capTable.length, {\n dataWords: 2,\n pointerCount: 1,\n });\n for (let i = 0; i < payload.capTable.length; i++) {\n serializeCapDescriptor(listBuilder.getStruct(i), payload.capTable[i]);\n }\n }\n}\n\nfunction serializeCapDescriptor(builder: StructBuilder, cap: CapDescriptor): void {\n switch (cap.type) {\n case 'none':\n builder.setUint16(0, CAP_NONE);\n break;\n case 'senderHosted':\n builder.setUint16(0, CAP_SENDER_HOSTED);\n builder.setUint32(8, cap.exportId);\n break;\n case 'senderPromise':\n builder.setUint16(0, CAP_SENDER_PROMISE);\n builder.setUint32(8, cap.exportId);\n break;\n case 'receiverHosted':\n builder.setUint16(0, CAP_RECEIVER_HOSTED);\n builder.setUint32(8, cap.importId);\n break;\n case 'receiverAnswer':\n builder.setUint16(0, CAP_RECEIVER_ANSWER);\n serializePromisedAnswer(builder.initStruct(0, 2, 1), cap.promisedAnswer);\n break;\n case 'thirdPartyHosted':\n builder.setUint16(0, CAP_THIRD_PARTY_HOSTED);\n // ThirdPartyCapId in pointer 0\n break;\n }\n}\n\nfunction serializeSendResultsTo(builder: StructBuilder, sendTo: SendResultsTo): void {\n switch (sendTo.type) {\n case 'caller':\n builder.setUint16(0, SEND_TO_CALLER);\n break;\n case 'yourself':\n builder.setUint16(0, SEND_TO_YOURSELF);\n break;\n case 'thirdParty':\n builder.setUint16(0, SEND_TO_THIRD_PARTY);\n // RecipientId in pointer 0\n break;\n }\n}\n\nfunction serializeException(\n builder: StructBuilder,\n pointerIndex: number,\n exception: Exception\n): void {\n const excBuilder = builder.initStruct(pointerIndex, 2, 1);\n excBuilder.setText(0, exception.reason);\n\n // Exception type union\n switch (exception.type) {\n case 'failed':\n excBuilder.setUint16(0, EXC_FAILED);\n break;\n case 'overloaded':\n excBuilder.setUint16(0, EXC_OVERLOADED);\n break;\n case 'disconnected':\n excBuilder.setUint16(0, EXC_DISCONNECTED);\n break;\n case 'unimplemented':\n excBuilder.setUint16(0, EXC_UNIMPLEMENTED);\n break;\n }\n}\n\n// ========================================================================================\n// Deserialization: Uint8Array -> RpcMessage\n// ========================================================================================\n\nexport function deserializeRpcMessage(data: Uint8Array): RpcMessage {\n const reader = new MessageReader(data);\n const root = reader.getRoot(6, 1);\n\n const unionTag = root.getUint16(0);\n\n switch (unionTag) {\n case MSG_UNIMPLEMENTED:\n return { type: 'unimplemented', message: deserializeUnimplemented(root) };\n case MSG_ABORT:\n return { type: 'abort', exception: deserializeException(root, 0) };\n case MSG_BOOTSTRAP:\n return { type: 'bootstrap', bootstrap: deserializeBootstrap(root) };\n case MSG_CALL:\n return { type: 'call', call: deserializeCall(root) };\n case MSG_RETURN:\n return { type: 'return', return: deserializeReturn(root) };\n case MSG_FINISH:\n return { type: 'finish', finish: deserializeFinish(root) };\n case MSG_RESOLVE:\n return { type: 'resolve', resolve: deserializeResolve(root) };\n case MSG_RELEASE:\n return { type: 'release', release: deserializeRelease(root) };\n case MSG_DISEMBARGO:\n return { type: 'disembargo', disembargo: deserializeDisembargo(root) };\n case MSG_PROVIDE:\n return { type: 'provide', provide: deserializeProvide(root) };\n case MSG_ACCEPT:\n return { type: 'accept', accept: deserializeAccept(root) };\n case MSG_JOIN:\n return { type: 'join', join: deserializeJoin(root) };\n default:\n throw new Error(`Unknown message union tag: ${unionTag}`);\n }\n}\n\nfunction deserializeUnimplemented(_root: StructReader): RpcMessage {\n // For now, return a placeholder - full implementation would deserialize nested message\n return {\n type: 'abort',\n exception: { reason: 'Unimplemented message received', type: 'unimplemented' },\n };\n}\n\nfunction deserializeBootstrap(root: StructReader): Bootstrap {\n return {\n questionId: root.getUint32(8),\n };\n}\n\nfunction deserializeCall(root: StructReader): Call {\n const targetStruct = root.getStruct(0, 2, 1);\n const paramsStruct = root.getStruct(1, 2, 2);\n const sendToStruct = root.getStruct(2, 2, 1);\n\n return {\n questionId: root.getUint32(8),\n interfaceId: root.getUint64(16),\n methodId: root.getUint16(24),\n allowThirdPartyTailCall: root.getBool(208),\n noPromisePipelining: root.getBool(209),\n onlyPromisePipeline: root.getBool(210),\n target: targetStruct\n ? deserializeMessageTarget(targetStruct)\n : { type: 'importedCap', importId: 0 },\n params: paramsStruct\n ? deserializePayload(paramsStruct)\n : { content: new Uint8Array(0), capTable: [] },\n sendResultsTo: sendToStruct ? deserializeSendResultsTo(sendToStruct) : { type: 'caller' },\n };\n}\n\nfunction deserializeReturn(root: StructReader): Return {\n const resultTag = root.getUint16(2);\n let result: Return['result'];\n\n switch (resultTag) {\n case RET_RESULTS:\n result = {\n type: 'results',\n payload: root.getStruct(0, 2, 2)\n ? deserializePayload(root.getStruct(0, 2, 2)!)\n : { content: new Uint8Array(0), capTable: [] },\n };\n break;\n case RET_EXCEPTION:\n result = { type: 'exception', exception: deserializeException(root, 0) };\n break;\n case RET_CANCELED:\n result = { type: 'canceled' };\n break;\n case RET_RESULTS_SENT_ELSEWHERE:\n result = { type: 'resultsSentElsewhere' };\n break;\n case RET_TAKE_FROM_OTHER_QUESTION:\n result = { type: 'takeFromOtherQuestion', questionId: root.getUint32(12) };\n break;\n case RET_ACCEPT_FROM_THIRD_PARTY:\n result = { type: 'acceptFromThirdParty', thirdPartyCapId: { id: new Uint8Array(0) } };\n break;\n default:\n result = { type: 'canceled' };\n }\n\n return {\n answerId: root.getUint32(8),\n releaseParamCaps: root.getBool(192),\n noFinishNeeded: root.getBool(193),\n result,\n };\n}\n\nfunction deserializeFinish(root: StructReader): Finish {\n return {\n questionId: root.getUint32(8),\n releaseResultCaps: root.getBool(192),\n requireEarlyCancellationWorkaround: root.getBool(193),\n };\n}\n\nfunction deserializeResolve(root: StructReader): Resolve {\n const resolutionTag = root.getUint16(2);\n let resolution: Resolve['resolution'];\n\n switch (resolutionTag) {\n case RESOLVE_CAP:\n resolution = {\n type: 'cap',\n cap: root.getStruct(0, 2, 1)\n ? deserializeCapDescriptor(root.getStruct(0, 2, 1)!)\n : { type: 'none' },\n };\n break;\n case RESOLVE_EXCEPTION:\n resolution = { type: 'exception', exception: deserializeException(root, 0) };\n break;\n default:\n resolution = {\n type: 'exception',\n exception: { reason: 'Unknown resolution type', type: 'failed' },\n };\n }\n\n return {\n promiseId: root.getUint32(8),\n resolution,\n };\n}\n\nfunction deserializeRelease(root: StructReader): Release {\n return {\n id: root.getUint32(8),\n referenceCount: root.getUint32(12),\n };\n}\n\nfunction deserializeDisembargo(root: StructReader): Disembargo {\n const targetStruct = root.getStruct(0, 2, 1);\n const contextTag = root.getUint16(2);\n let context: Disembargo['context'];\n\n switch (contextTag) {\n case DISEMBARGO_SENDER_LOOPBACK:\n context = { type: 'senderLoopback', embargoId: root.getUint32(12) };\n break;\n case DISEMBARGO_RECEIVER_LOOPBACK:\n context = { type: 'receiverLoopback', embargoId: root.getUint32(12) };\n break;\n case DISEMBARGO_ACCEPT:\n context = { type: 'accept' };\n break;\n case DISEMBARGO_PROVIDE:\n context = { type: 'provide', questionId: root.getUint32(12) };\n break;\n default:\n context = { type: 'accept' };\n }\n\n return {\n target: targetStruct\n ? deserializeMessageTarget(targetStruct)\n : { type: 'importedCap', importId: 0 },\n context,\n };\n}\n\nfunction deserializeProvide(root: StructReader): Provide {\n const targetStruct = root.getStruct(0, 2, 1);\n return {\n questionId: root.getUint32(8),\n target: targetStruct\n ? deserializeMessageTarget(targetStruct)\n : { type: 'importedCap', importId: 0 },\n recipient: { id: new Uint8Array(0) },\n };\n}\n\nfunction deserializeAccept(_root: StructReader): {\n questionId: number;\n provision: { id: Uint8Array };\n embargo: boolean;\n} {\n // Level 3 - placeholder\n return { questionId: 0, provision: { id: new Uint8Array(0) }, embargo: false };\n}\n\nfunction deserializeJoin(_root: StructReader): {\n questionId: number;\n target: MessageTarget;\n otherCap: MessageTarget;\n joinId: number;\n} {\n // Level 4 - placeholder\n return {\n questionId: 0,\n target: { type: 'importedCap', importId: 0 },\n otherCap: { type: 'importedCap', importId: 0 },\n joinId: 0,\n };\n}\n\n// ========================================================================================\n// Supporting Type Deserialization\n// ========================================================================================\n\nfunction deserializeMessageTarget(root: StructReader): MessageTarget {\n const tag = root.getUint16(0);\n\n switch (tag) {\n case TARGET_IMPORTED_CAP:\n return { type: 'importedCap', importId: root.getUint32(8) };\n case TARGET_PROMISED_ANSWER: {\n const promisedAnswerStruct = root.getStruct(0, 2, 1);\n return {\n type: 'promisedAnswer',\n promisedAnswer: promisedAnswerStruct\n ? deserializePromisedAnswer(promisedAnswerStruct)\n : { questionId: 0, transform: [] },\n };\n }\n default:\n return { type: 'importedCap', importId: 0 };\n }\n}\n\nfunction deserializePromisedAnswer(root: StructReader): PromisedAnswer {\n const transformList = root.getList<StructReader>(0, ElementSize.INLINE_COMPOSITE, {\n dataWords: 2,\n pointerCount: 0,\n });\n const transform: PromisedAnswerOp[] = [];\n\n if (transformList) {\n for (let i = 0; i < transformList.length; i++) {\n transform.push(deserializePromisedAnswerOp(transformList.getStruct(i)));\n }\n }\n\n return {\n questionId: root.getUint32(0),\n transform,\n };\n}\n\nfunction deserializePromisedAnswerOp(root: StructReader): PromisedAnswerOp {\n const tag = root.getUint16(0);\n\n switch (tag) {\n case OP_NOOP:\n return { type: 'noop' };\n case OP_GET_POINTER_FIELD:\n return { type: 'getPointerField', fieldIndex: root.getUint16(8) };\n default:\n return { type: 'noop' };\n }\n}\n\nfunction deserializePayload(root: StructReader): Payload {\n // Content - for now, return empty\n // In full implementation, would deserialize the AnyPointer content\n const capTableList = root.getList<StructReader>(1, ElementSize.EIGHT_BYTES, {\n dataWords: 2,\n pointerCount: 1,\n });\n const capTable: CapDescriptor[] = [];\n\n if (capTableList) {\n for (let i = 0; i < capTableList.length; i++) {\n capTable.push(deserializeCapDescriptor(capTableList.getStruct(i)));\n }\n }\n\n return {\n content: new Uint8Array(0),\n capTable,\n };\n}\n\nfunction deserializeCapDescriptor(root: StructReader): CapDescriptor {\n const tag = root.getUint16(0);\n\n switch (tag) {\n case CAP_NONE:\n return { type: 'none' };\n case CAP_SENDER_HOSTED:\n return { type: 'senderHosted', exportId: root.getUint32(8) };\n case CAP_SENDER_PROMISE:\n return { type: 'senderPromise', exportId: root.getUint32(8) };\n case CAP_RECEIVER_HOSTED:\n return { type: 'receiverHosted', importId: root.getUint32(8) };\n case CAP_RECEIVER_ANSWER: {\n const promisedAnswerStruct = root.getStruct(0, 2, 1);\n return {\n type: 'receiverAnswer',\n promisedAnswer: promisedAnswerStruct\n ? deserializePromisedAnswer(promisedAnswerStruct)\n : { questionId: 0, transform: [] },\n };\n }\n case CAP_THIRD_PARTY_HOSTED:\n return { type: 'thirdPartyHosted', thirdPartyCapId: { id: new Uint8Array(0) } };\n default:\n return { type: 'none' };\n }\n}\n\nfunction deserializeSendResultsTo(root: StructReader): SendResultsTo {\n const tag = root.getUint16(0);\n\n switch (tag) {\n case SEND_TO_CALLER:\n return { type: 'caller' };\n case SEND_TO_YOURSELF:\n return { type: 'yourself' };\n case SEND_TO_THIRD_PARTY:\n return { type: 'thirdParty', recipientId: { id: new Uint8Array(0) } };\n default:\n return { type: 'caller' };\n }\n}\n\nfunction deserializeException(root: StructReader, pointerIndex: number): Exception {\n const excStruct = root.getStruct(pointerIndex, 2, 1);\n if (!excStruct) {\n return { reason: 'Unknown error', type: 'failed' };\n }\n\n const typeTag = excStruct.getUint16(0);\n let type: Exception['type'];\n\n switch (typeTag) {\n case EXC_FAILED:\n type = 'failed';\n break;\n case EXC_OVERLOADED:\n type = 'overloaded';\n break;\n case EXC_DISCONNECTED:\n type = 'disconnected';\n break;\n case EXC_UNIMPLEMENTED:\n type = 'unimplemented';\n break;\n default:\n type = 'failed';\n }\n\n return {\n reason: excStruct.getText(0),\n type,\n };\n}\n","/**\n * WebSocket Transport Implementation\n *\n * Implements RpcTransport over WebSocket for browser and Node.js compatibility.\n */\n\nimport { deserializeRpcMessage, serializeRpcMessage } from './message-serializer.js';\nimport type { RpcMessage } from './rpc-types.js';\nimport type { RpcTransport, WebSocketTransportOptions } from './transport.js';\n\n// Message framing: length-prefixed binary messages\n// Format: [4 bytes: message length (little-endian)] [N bytes: message data]\n\nexport class WebSocketTransport implements RpcTransport {\n private ws: WebSocket | null = null;\n private messageQueue: RpcMessage[] = [];\n private receiveQueue: Array<{\n resolve: (msg: RpcMessage | null) => void;\n reject: (err: Error) => void;\n }> = [];\n private _connected = false;\n private pendingBuffer: Uint8Array | null = null;\n private pendingLength = 0;\n\n onClose?: (reason?: Error) => void;\n onError?: (error: Error) => void;\n\n constructor(\n url: string,\n private options: WebSocketTransportOptions = {}\n ) {\n this.connect(url);\n }\n\n static async connect(\n url: string,\n options?: WebSocketTransportOptions\n ): Promise<WebSocketTransport> {\n const transport = new WebSocketTransport(url, options);\n await transport.waitForConnection();\n return transport;\n }\n\n static fromWebSocket(ws: WebSocket, options?: WebSocketTransportOptions): WebSocketTransport {\n const transport = new WebSocketTransport('internal', options);\n transport.attachWebSocket(ws);\n return transport;\n }\n\n get connected(): boolean {\n return this._connected;\n }\n\n private connect(url: string): void {\n this.ws = new WebSocket(url);\n this.ws.binaryType = this.options.binaryType ?? 'arraybuffer';\n\n this.ws.onopen = () => {\n this._connected = true;\n };\n\n this.ws.onmessage = (event) => {\n this.handleMessage(event.data);\n };\n\n this.ws.onclose = () => {\n this._connected = false;\n this.flushReceiveQueue(null);\n this.onClose?.();\n };\n\n this.ws.onerror = (_error) => {\n const err = new Error('WebSocket error');\n this.onError?.(err);\n };\n }\n\n private attachWebSocket(ws: WebSocket): void {\n this.ws = ws;\n this.ws.binaryType = this.options.binaryType ?? 'arraybuffer';\n this._connected = ws.readyState === WebSocket.OPEN;\n\n this.ws.onmessage = (event) => {\n this.handleMessage(event.data);\n };\n\n this.ws.onclose = () => {\n this._connected = false;\n this.flushReceiveQueue(null);\n this.onClose?.();\n };\n\n this.ws.onerror = (_error) => {\n const err = new Error('WebSocket error');\n this.onError?.(err);\n };\n }\n\n private waitForConnection(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (this._connected) {\n resolve();\n return;\n }\n\n const timeout = setTimeout(() => {\n reject(new Error('Connection timeout'));\n }, this.options.connectTimeoutMs ?? 10000);\n\n const checkConnection = () => {\n if (this._connected) {\n clearTimeout(timeout);\n resolve();\n } else if (!this.ws || this.ws.readyState === WebSocket.CLOSED) {\n clearTimeout(timeout);\n reject(new Error('Connection failed'));\n } else {\n setTimeout(checkConnection, 10);\n }\n };\n\n checkConnection();\n });\n }\n\n private handleMessage(data: ArrayBuffer | Blob): void {\n // For Phase 1, we'll implement basic message handling\n // Full implementation would parse the Cap'n Proto message\n if (data instanceof ArrayBuffer) {\n this.processBinaryMessage(new Uint8Array(data));\n } else {\n // Blob handling for browser compatibility\n const reader = new FileReader();\n reader.onload = () => {\n this.processBinaryMessage(new Uint8Array(reader.result as ArrayBuffer));\n };\n reader.readAsArrayBuffer(data);\n }\n }\n\n private processBinaryMessage(data: Uint8Array): void {\n // Length-prefixed framing\n let offset = 0;\n\n while (offset < data.length) {\n if (this.pendingBuffer === null) {\n // Start of new message\n if (offset + 4 > data.length) {\n // Not enough data for length header\n this.pendingBuffer = data.slice(offset);\n this.pendingLength = -1;\n break;\n }\n\n const length = new DataView(data.buffer, data.byteOffset + offset, 4).getUint32(0, true);\n offset += 4;\n\n if (offset + length > data.length) {\n // Not enough data for full message\n this.pendingBuffer = data.slice(offset - 4);\n this.pendingLength = length;\n break;\n }\n\n const messageData = data.slice(offset, offset + length);\n offset += length;\n this.handleRpcMessage(messageData);\n } else {\n // Continuation of pending message\n if (this.pendingLength === -1) {\n // Still need length header\n const needed = 4 - this.pendingBuffer.length;\n if (data.length - offset < needed) {\n this.pendingBuffer = new Uint8Array([...this.pendingBuffer, ...data.slice(offset)]);\n break;\n }\n\n const tempBuffer = new Uint8Array(this.pendingBuffer.length + needed);\n tempBuffer.set(this.pendingBuffer);\n tempBuffer.set(data.slice(offset, offset + needed), this.pendingBuffer.length);\n\n this.pendingLength = new DataView(tempBuffer.buffer, 0, 4).getUint32(0, true);\n this.pendingBuffer = null;\n offset += needed;\n } else {\n // Have length, need message body\n const needed = this.pendingLength - this.pendingBuffer.length;\n if (data.length - offset < needed) {\n this.pendingBuffer = new Uint8Array([...this.pendingBuffer, ...data.slice(offset)]);\n break;\n }\n\n const messageData = new Uint8Array(this.pendingLength);\n messageData.set(this.pendingBuffer);\n messageData.set(data.slice(offset, offset + needed), this.pendingBuffer.length);\n\n offset += needed;\n this.pendingBuffer = null;\n this.handleRpcMessage(messageData);\n }\n }\n }\n }\n\n private handleRpcMessage(data: Uint8Array): void {\n // Parse the RPC message from binary data\n // For Phase 1, this is a placeholder - full implementation would deserialize\n const message = this.deserializeMessage(data);\n\n // Fulfill pending receive\n if (this.receiveQueue.length > 0) {\n const { resolve } = this.receiveQueue.shift()!;\n resolve(message);\n } else {\n this.messageQueue.push(message);\n }\n }\n\n private deserializeMessage(data: Uint8Array): RpcMessage {\n return deserializeRpcMessage(data);\n }\n\n private serializeMessage(message: RpcMessage): Uint8Array {\n return serializeRpcMessage(message);\n }\n\n async send(message: RpcMessage): Promise<void> {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n throw new Error('WebSocket not connected');\n }\n\n const data = this.serializeMessage(message);\n const frame = new Uint8Array(4 + data.length);\n new DataView(frame.buffer).setUint32(0, data.length, true);\n frame.set(data, 4);\n\n this.ws.send(frame);\n }\n\n async receive(): Promise<RpcMessage | null> {\n // Check queued messages first\n if (this.messageQueue.length > 0) {\n return this.messageQueue.shift()!;\n }\n\n // If closed, return null\n if (!this._connected) {\n return null;\n }\n\n // Wait for next message\n return new Promise((resolve, reject) => {\n this.receiveQueue.push({ resolve, reject });\n });\n }\n\n close(reason?: Error): void {\n this._connected = false;\n this.ws?.close();\n this.flushReceiveQueue(null);\n this.onClose?.(reason);\n }\n\n private flushReceiveQueue(value: RpcMessage | null): void {\n while (this.receiveQueue.length > 0) {\n const { resolve } = this.receiveQueue.shift()!;\n resolve(value);\n }\n }\n}\n","/**\n * TCP Transport Implementation for Node.js\n *\n * Implements RpcTransport over raw TCP socket for C++ interop testing.\n * This allows direct communication with the official Cap'n Proto C++ implementation.\n */\n\nimport * as net from 'node:net';\nimport { deserializeRpcMessage, serializeRpcMessage } from './message-serializer.js';\nimport type { RpcMessage } from './rpc-types.js';\nimport type { RpcTransport } from './transport.js';\n\nexport interface TcpTransportOptions {\n /** Connection timeout in milliseconds */\n connectTimeoutMs?: number;\n}\n\n/**\n * TCP Transport for Cap'n Proto RPC\n *\n * Uses length-prefixed binary message framing compatible with Cap'n Proto C++ implementation.\n * Format: [4 bytes: message length (little-endian)] [N bytes: message data]\n */\nexport class TcpTransport implements RpcTransport {\n private socket: net.Socket | null = null;\n private messageQueue: RpcMessage[] = [];\n private receiveQueue: Array<{\n resolve: (msg: RpcMessage | null) => void;\n reject: (err: Error) => void;\n }> = [];\n private _connected = false;\n private pendingBuffer: Buffer = Buffer.alloc(0);\n private pendingLength = 0;\n private hasPendingLength = false;\n\n onClose?: (reason?: Error) => void;\n onError?: (error: Error) => void;\n\n constructor(\n private host: string,\n private port: number,\n private options: TcpTransportOptions = {}\n ) {}\n\n static async connect(\n host: string,\n port: number,\n options?: TcpTransportOptions\n ): Promise<TcpTransport> {\n const transport = new TcpTransport(host, port, options);\n await transport.connect();\n return transport;\n }\n\n static fromSocket(socket: net.Socket, options?: TcpTransportOptions): TcpTransport {\n const transport = new TcpTransport('', 0, options);\n transport.attachSocket(socket);\n return transport;\n }\n\n get connected(): boolean {\n return this._connected && this.socket?.readyState === 'open';\n }\n\n private connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.socket?.destroy();\n reject(new Error('Connection timeout'));\n }, this.options.connectTimeoutMs ?? 10000);\n\n this.socket = new net.Socket();\n\n this.socket.on('connect', () => {\n clearTimeout(timeout);\n this._connected = true;\n resolve();\n });\n\n this.socket.on('data', (data: Buffer) => {\n this.handleData(data);\n });\n\n this.socket.on('close', (hadError: boolean) => {\n this._connected = false;\n this.flushReceiveQueue(null);\n if (hadError) {\n this.onClose?.(new Error('Connection closed with error'));\n } else {\n this.onClose?.();\n }\n });\n\n this.socket.on('error', (err: Error) => {\n clearTimeout(timeout);\n this._connected = false;\n this.onError?.(err);\n reject(err);\n });\n\n this.socket.on('end', () => {\n this._connected = false;\n });\n\n this.socket.connect(this.port, this.host);\n });\n }\n\n private attachSocket(socket: net.Socket): void {\n this.socket = socket;\n this._connected = socket.readyState === 'open';\n\n socket.on('data', (data: Buffer) => {\n this.handleData(data);\n });\n\n socket.on('close', (hadError: boolean) => {\n this._connected = false;\n this.flushReceiveQueue(null);\n if (hadError) {\n this.onClose?.(new Error('Connection closed with error'));\n } else {\n this.onClose?.();\n }\n });\n\n socket.on('error', (err: Error) => {\n this._connected = false;\n this.onError?.(err);\n });\n\n socket.on('end', () => {\n this._connected = false;\n });\n }\n\n private handleData(data: Buffer): void {\n // Append new data to pending buffer\n this.pendingBuffer = Buffer.concat([this.pendingBuffer, data]);\n\n // Process complete messages\n while (this.pendingBuffer.length >= 4) {\n if (!this.hasPendingLength) {\n // Read message length (4 bytes, little-endian)\n this.pendingLength = this.pendingBuffer.readUInt32LE(0);\n this.hasPendingLength = true;\n\n // Sanity check: max message size 64MB\n if (this.pendingLength > 64 * 1024 * 1024) {\n this.onError?.(new Error(`Message too large: ${this.pendingLength} bytes`));\n this.close(new Error('Message too large'));\n return;\n }\n }\n\n // Check if we have the full message\n const totalLength = 4 + this.pendingLength;\n if (this.pendingBuffer.length < totalLength) {\n break; // Wait for more data\n }\n\n // Extract message data\n const messageData = this.pendingBuffer.subarray(4, totalLength);\n this.pendingBuffer = this.pendingBuffer.subarray(totalLength);\n this.hasPendingLength = false;\n\n // Parse and handle the message\n try {\n const message = deserializeRpcMessage(new Uint8Array(messageData));\n this.handleRpcMessage(message);\n } catch (err) {\n this.onError?.(err instanceof Error ? err : new Error(String(err)));\n }\n }\n }\n\n private handleRpcMessage(message: RpcMessage): void {\n if (this.receiveQueue.length > 0) {\n const { resolve } = this.receiveQueue.shift()!;\n resolve(message);\n } else {\n this.messageQueue.push(message);\n }\n }\n\n async send(message: RpcMessage): Promise<void> {\n if (!this.socket || this.socket.readyState !== 'open') {\n throw new Error('Socket not connected');\n }\n\n const data = serializeRpcMessage(message);\n const frame = Buffer.allocUnsafe(4 + data.length);\n frame.writeUInt32LE(data.length, 0);\n frame.set(data, 4);\n\n return new Promise((resolve, reject) => {\n this.socket!.write(frame, (err) => {\n if (err) {\n reject(err);\n } else {\n resolve();\n }\n });\n });\n }\n\n async receive(): Promise<RpcMessage | null> {\n // Check queued messages first\n if (this.messageQueue.length > 0) {\n return this.messageQueue.shift()!;\n }\n\n // If closed, return null\n if (!this._connected) {\n return null;\n }\n\n // Wait for next message\n return new Promise((resolve, reject) => {\n this.receiveQueue.push({ resolve, reject });\n });\n }\n\n close(reason?: Error): void {\n this._connected = false;\n this.socket?.end();\n this.socket?.destroy();\n this.flushReceiveQueue(null);\n this.onClose?.(reason);\n }\n\n private flushReceiveQueue(value: RpcMessage | null): void {\n while (this.receiveQueue.length > 0) {\n const { resolve } = this.receiveQueue.shift()!;\n resolve(value);\n }\n }\n}\n","/**\n * EzRpc TCP Transport\n *\n * Implements RpcTransport over raw TCP socket for C++ EzRpc compatibility.\n * Does NOT use length-prefixed framing - sends raw Cap'n Proto messages.\n */\n\nimport * as net from 'node:net';\nimport { deserializeRpcMessage, serializeRpcMessage } from './message-serializer.js';\nimport type { RpcMessage } from './rpc-types.js';\nimport type { RpcTransport } from './transport.js';\n\nexport interface EzRpcTransportOptions {\n connectTimeoutMs?: number;\n}\n\n/**\n * EzRpc TCP Transport\n *\n * Compatible with Cap'n Proto C++ EzRpcServer/EzRpcClient.\n * Sends raw Cap'n Proto messages without length prefix.\n */\nexport class EzRpcTransport implements RpcTransport {\n private socket: net.Socket | null = null;\n private messageQueue: RpcMessage[] = [];\n private receiveQueue: Array<{\n resolve: (msg: RpcMessage | null) => void;\n reject: (err: Error) => void;\n }> = [];\n private _connected = false;\n private pendingBuffer = Buffer.alloc(0);\n\n onClose?: (reason?: Error) => void;\n onError?: (error: Error) => void;\n\n constructor(\n private host: string,\n private port: number,\n private options: EzRpcTransportOptions = {}\n ) {}\n\n static async connect(\n host: string,\n port: number,\n options?: EzRpcTransportOptions\n ): Promise<EzRpcTransport> {\n const transport = new EzRpcTransport(host, port, options);\n await transport.doConnect();\n return transport;\n }\n\n get connected(): boolean {\n return this._connected && this.socket !== null && !this.socket.destroyed;\n }\n\n private doConnect(): Promise<void> {\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.socket?.destroy();\n reject(new Error(`Connection timeout: failed to connect to ${this.host}:${this.port}`));\n }, this.options.connectTimeoutMs ?? 10000);\n\n this.socket = new net.Socket();\n\n this.socket.on('connect', () => {\n clearTimeout(timeout);\n this._connected = true;\n resolve();\n });\n\n this.socket.on('data', (data: Buffer) => {\n try {\n this.handleData(data);\n } catch (err) {\n this.onError?.(err instanceof Error ? err : new Error(String(err)));\n }\n });\n\n this.socket.on('close', (hadError: boolean) => {\n const wasConnected = this._connected;\n this._connected = false;\n\n // Reject pending receive calls\n const error = hadError\n ? new Error('Connection closed with error')\n : new Error('Connection closed');\n this.flushReceiveQueueWithError(error);\n\n if (wasConnected) {\n this.onClose?.(hadError ? error : undefined);\n }\n });\n\n this.socket.on('error', (err: Error) => {\n clearTimeout(timeout);\n this._connected = false;\n this.flushReceiveQueueWithError(err);\n this.onError?.(err);\n reject(err);\n });\n\n this.socket.connect(this.port, this.host);\n });\n }\n\n private handleData(data: Buffer): void {\n // For EzRpc, we assume each 'data' event contains exactly one message\n // This is how KJ async I/O typically works\n\n // If we have pending data, append it\n if (this.pendingBuffer.length > 0) {\n this.pendingBuffer = Buffer.concat([this.pendingBuffer, data]);\n } else {\n this.pendingBuffer = Buffer.from(data);\n }\n\n // Try to parse messages from the buffer\n // Cap'n Proto messages have an 8-byte header we can use to determine size\n while (this.pendingBuffer.length >= 8) {\n const segmentCount = this.pendingBuffer.readUInt32LE(0) + 1;\n const firstSegmentSize = this.pendingBuffer.readUInt32LE(4);\n\n // Calculate total message size\n // Header: 8 bytes\n // Segment sizes: (segmentCount - 1) * 4 bytes (if segmentCount > 1)\n // Data: sum of all segment sizes * 8 bytes\n let headerSize = 8;\n if (segmentCount > 1) {\n headerSize += (segmentCount - 1) * 4;\n }\n\n // For now, assume single segment\n const messageSize = headerSize + firstSegmentSize * 8;\n\n if (this.pendingBuffer.length < messageSize) {\n // Not enough data yet\n break;\n }\n\n // Extract the message\n const messageData = this.pendingBuffer.subarray(0, messageSize);\n this.pendingBuffer = this.pendingBuffer.subarray(messageSize);\n\n try {\n const message = deserializeRpcMessage(new Uint8Array(messageData));\n if (this.receiveQueue.length > 0) {\n const { resolve } = this.receiveQueue.shift()!;\n resolve(message);\n } else {\n this.messageQueue.push(message);\n }\n } catch (err) {\n this.onError?.(err instanceof Error ? err : new Error(String(err)));\n }\n }\n }\n\n async send(message: RpcMessage): Promise<void> {\n if (!this.connected) {\n throw new Error(`Cannot send: socket not connected to ${this.host}:${this.port}`);\n }\n\n const data = serializeRpcMessage(message);\n\n return new Promise((resolve, reject) => {\n this.socket!.write(Buffer.from(data), (err) => {\n if (err) {\n reject(new Error(`Failed to send message: ${err.message}`));\n } else {\n resolve();\n }\n });\n });\n }\n\n async receive(): Promise<RpcMessage | null> {\n // 先检查队列中的消息\n if (this.messageQueue.length > 0) {\n return this.messageQueue.shift()!;\n }\n\n // 如果已断开连接,返回 null\n if (!this.connected) {\n return null;\n }\n\n // 等待下一条消息\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n // 从队列中移除自己\n const index = this.receiveQueue.findIndex((item) => item.resolve === resolve);\n if (index !== -1) {\n this.receiveQueue.splice(index, 1);\n }\n reject(new Error('Receive timeout'));\n }, 30000); // 30 秒超时\n\n this.receiveQueue.push({\n resolve: (msg) => {\n clearTimeout(timeoutId);\n resolve(msg);\n },\n reject: (err) => {\n clearTimeout(timeoutId);\n reject(err);\n },\n });\n });\n }\n\n close(reason?: Error): void {\n this._connected = false;\n this.socket?.end();\n this.socket?.destroy();\n this.flushReceiveQueue(null);\n this.onClose?.(reason);\n }\n\n private flushReceiveQueueWithError(error: Error): void {\n while (this.receiveQueue.length > 0) {\n const { reject } = this.receiveQueue.shift()!;\n reject(error);\n }\n }\n\n private flushReceiveQueue(value: RpcMessage | null): void {\n while (this.receiveQueue.length > 0) {\n const { resolve } = this.receiveQueue.shift()!;\n resolve(value);\n }\n }\n}\n","/**\n * CapabilityClient\n *\n * Base class for client-side capability references.\n * Provides the foundation for making method calls on remote objects.\n */\n\nimport type { PipelineClient } from './pipeline.js';\nimport type { RpcConnection } from './rpc-connection.js';\nimport type { ImportId, InterfaceId, MethodId, Payload } from './rpc-types.js';\n\n/** Base interface for all capability clients */\nexport interface CapabilityClient {\n /** The connection this capability belongs to */\n readonly connection: RpcConnection;\n\n /** The import ID for this capability (if imported) */\n readonly importId?: ImportId;\n\n /** Check if this capability is still valid */\n isValid(): boolean;\n\n /** Release this capability reference */\n release(): void;\n}\n\n/** Base class for capability client implementations */\nexport abstract class BaseCapabilityClient implements CapabilityClient {\n constructor(\n public readonly connection: RpcConnection,\n public readonly importId?: ImportId\n ) {}\n\n isValid(): boolean {\n // In full implementation, check if the import is still valid\n return true;\n }\n\n release(): void {\n if (this.importId !== undefined) {\n this.connection.release(this.importId, 1);\n }\n }\n\n /** Make a method call on this capability and return a PipelineClient */\n protected _call(_interfaceId: InterfaceId, _methodId: MethodId, params: unknown): PipelineClient {\n if (!this.importId) {\n throw new Error('Cannot call method on capability without import ID');\n }\n\n // Serialize params to Payload\n const _payload = this.serializeParams(params);\n\n // Use callPipelined to get a PipelineClient\n // Note: callPipelined returns Promise<PipelineClient>, but we need to await it\n // This is a design issue - for now, we throw an error indicating async is needed\n throw new Error('Use _callAsync instead for async call support');\n }\n\n /** Make an async method call on this capability */\n protected async _callAsync(\n interfaceId: InterfaceId,\n methodId: MethodId,\n params: unknown\n ): Promise<PipelineClient> {\n if (!this.importId) {\n throw new Error('Cannot call method on capability without import ID');\n }\n\n // Serialize params to Payload\n const payload = this.serializeParams(params);\n\n // Use callPipelined to get a PipelineClient\n return this.connection.callPipelined(this.importId, interfaceId, methodId, payload);\n }\n\n /** Serialize parameters to Payload */\n protected serializeParams(_params: unknown): Payload {\n // TODO: Implement proper parameter serialization\n // For now, return empty payload\n return {\n content: new Uint8Array(),\n capTable: [],\n };\n }\n}\n\n/** Factory for creating capability clients */\nexport interface CapabilityClientFactory<T extends CapabilityClient> {\n create(connection: RpcConnection, importId?: ImportId): T;\n}\n","/**\n * SturdyRefs - Level 2 RPC Feature\n *\n * SturdyRefs provide persistent capability references that survive\n * connection disconnections and can be restored on reconnection.\n *\n * Key concepts:\n * - SturdyRef: A persistent reference to a capability\n * - Restore: Reconnect to a capability using its SturdyRef\n * - Save: Create a SturdyRef from a live capability\n */\n\nimport type { RpcConnection } from './rpc-connection.js';\nimport type { ExportId, ImportId, QuestionId, RpcMessage } from './rpc-types.js';\n\n// ========================================================================================\n// Types\n// ========================================================================================\n\n/**\n * A SturdyRef token that can be persisted and later used to restore a capability\n */\nexport interface SturdyRef {\n /** The vat ID where the capability lives */\n vatId: string;\n /** The local ID of the capability within that vat */\n localId: string;\n /** Optional: Version or generation number for validation */\n version?: number;\n /** Optional: Expiration timestamp */\n expiresAt?: number;\n /** Optional: Additional metadata */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * A stored SturdyRef with its associated capability info\n */\ninterface StoredSturdyRef {\n ref: SturdyRef;\n exportId: ExportId;\n capability: unknown;\n createdAt: number;\n lastAccessedAt: number;\n}\n\n/**\n * Options for saving a capability as a SturdyRef\n */\nexport interface SaveOptions {\n /** Custom local ID (auto-generated if not provided) */\n localId?: string;\n /** Expiration time in milliseconds from now */\n ttlMs?: number;\n /** Metadata to attach to the SturdyRef */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Options for restoring a capability from a SturdyRef\n */\nexport interface RestoreOptions {\n /** Timeout for the restore operation */\n timeoutMs?: number;\n}\n\n// ========================================================================================\n// SturdyRef Manager (Server-side)\n// ========================================================================================\n\n/**\n * Manages SturdyRefs on the server side.\n * Stores the mapping between SturdyRef tokens and live capabilities.\n */\nexport class SturdyRefManager {\n private vatId: string;\n private storedRefs = new Map<string, StoredSturdyRef>();\n private localIdCounter = 0;\n\n constructor(vatId: string) {\n this.vatId = vatId;\n }\n\n /**\n * Save a capability as a SturdyRef\n */\n saveCapability(capability: unknown, exportId: ExportId, options?: SaveOptions): SturdyRef {\n const localId = options?.localId ?? this.generateLocalId();\n const now = Date.now();\n\n const ref: SturdyRef = {\n vatId: this.vatId,\n localId,\n version: 1,\n expiresAt: options?.ttlMs ? now + options.ttlMs : undefined,\n metadata: options?.metadata,\n };\n\n const stored: StoredSturdyRef = {\n ref,\n exportId,\n capability,\n createdAt: now,\n lastAccessedAt: now,\n };\n\n this.storedRefs.set(localId, stored);\n return ref;\n }\n\n /**\n * Restore a capability from a SturdyRef token\n */\n restoreCapability(ref: SturdyRef): { capability: unknown; exportId: ExportId } | null {\n // Validate the SturdyRef belongs to this vat\n if (ref.vatId !== this.vatId) {\n console.warn(`SturdyRef vatId mismatch: ${ref.vatId} !== ${this.vatId}`);\n return null;\n }\n\n const stored = this.storedRefs.get(ref.localId);\n if (!stored) {\n console.warn(`SturdyRef not found: ${ref.localId}`);\n return null;\n }\n\n // Check expiration\n if (stored.ref.expiresAt && Date.now() > stored.ref.expiresAt) {\n console.warn(`SturdyRef expired: ${ref.localId}`);\n this.storedRefs.delete(ref.localId);\n return null;\n }\n\n // Update last accessed time\n stored.lastAccessedAt = Date.now();\n\n return {\n capability: stored.capability,\n exportId: stored.exportId,\n };\n }\n\n /**\n * Drop a SturdyRef\n */\n dropSturdyRef(localId: string): boolean {\n return this.storedRefs.delete(localId);\n }\n\n /**\n * Get all active SturdyRefs\n */\n getActiveRefs(): SturdyRef[] {\n const now = Date.now();\n const active: SturdyRef[] = [];\n\n for (const [localId, stored] of this.storedRefs) {\n // Clean up expired refs\n if (stored.ref.expiresAt && now > stored.ref.expiresAt) {\n this.storedRefs.delete(localId);\n continue;\n }\n active.push(stored.ref);\n }\n\n return active;\n }\n\n /**\n * Clean up expired SturdyRefs\n */\n cleanupExpired(): number {\n const now = Date.now();\n let cleaned = 0;\n\n for (const [localId, stored] of this.storedRefs) {\n if (stored.ref.expiresAt && now > stored.ref.expiresAt) {\n this.storedRefs.delete(localId);\n cleaned++;\n }\n }\n\n return cleaned;\n }\n\n private generateLocalId(): string {\n return `ref-${++this.localIdCounter}-${Date.now()}`;\n }\n}\n\n// ========================================================================================\n// Restore Handler (Client-side)\n// ========================================================================================\n\n/**\n * Handles Restore messages on the client side.\n * Manages reconnecting to capabilities after disconnections.\n */\nexport class RestoreHandler {\n private connection: RpcConnection;\n private pendingRestores = new Map<\n QuestionId,\n {\n resolve: (importId: ImportId) => void;\n reject: (error: Error) => void;\n timeout: ReturnType<typeof setTimeout>;\n }\n >();\n private questionIdCounter = 0;\n\n constructor(connection: RpcConnection) {\n this.connection = connection;\n }\n\n /**\n * Send a Restore message to restore a capability from a SturdyRef\n */\n async restore(ref: SturdyRef, options?: RestoreOptions): Promise<ImportId> {\n const questionId = ++this.questionIdCounter;\n const timeoutMs = options?.timeoutMs ?? 30000;\n\n return new Promise((resolve, reject) => {\n // Set up timeout\n const timeout = setTimeout(() => {\n this.pendingRestores.delete(questionId);\n reject(new Error(`Restore timeout after ${timeoutMs}ms`));\n }, timeoutMs);\n\n this.pendingRestores.set(questionId, { resolve, reject, timeout });\n\n // Send Restore message (using Call message with special interface)\n // In the actual protocol, this would be a specific Restore message type\n // For now, we use a special method call\n this.sendRestoreMessage(questionId, ref).catch((error) => {\n clearTimeout(timeout);\n this.pendingRestores.delete(questionId);\n reject(error);\n });\n });\n }\n\n /**\n * Handle a Restore response\n */\n handleRestoreResponse(questionId: QuestionId, importId: ImportId): void {\n const pending = this.pendingRestores.get(questionId);\n if (pending) {\n clearTimeout(pending.timeout);\n this.pendingRestores.delete(questionId);\n pending.resolve(importId);\n }\n }\n\n /**\n * Handle a Restore failure\n */\n handleRestoreFailure(questionId: QuestionId, reason: string): void {\n const pending = this.pendingRestores.get(questionId);\n if (pending) {\n clearTimeout(pending.timeout);\n this.pendingRestores.delete(questionId);\n pending.reject(new Error(`Restore failed: ${reason}`));\n }\n }\n\n /**\n * Cancel all pending restores (e.g., on disconnect)\n */\n cancelAll(reason: string): void {\n for (const [_questionId, pending] of this.pendingRestores) {\n clearTimeout(pending.timeout);\n pending.reject(new Error(`Restore canceled: ${reason}`));\n }\n this.pendingRestores.clear();\n }\n\n private async sendRestoreMessage(questionId: QuestionId, ref: SturdyRef): Promise<void> {\n // Serialize the SturdyRef\n const refData = JSON.stringify(ref);\n\n // In the actual implementation, this would send a proper Restore message\n // For now, we simulate it\n const restoreMsg: RpcMessage = {\n type: 'call',\n call: {\n questionId,\n target: { type: 'importedCap', importId: 0 }, // Special import for restore service\n interfaceId: BigInt('0xffffffffffffffff'), // Special interface ID for restore\n methodId: 0, // restore method\n allowThirdPartyTailCall: false,\n noPromisePipelining: false,\n onlyPromisePipeline: false,\n params: {\n content: new TextEncoder().encode(refData),\n capTable: [],\n },\n sendResultsTo: { type: 'caller' },\n },\n };\n\n // This would be sent through the connection\n // await this.connection.send(restoreMsg);\n console.log('Sending restore message:', restoreMsg);\n }\n}\n\n// ========================================================================================\n// SturdyRef Utilities\n// ========================================================================================\n\n/**\n * Serialize a SturdyRef to a string for storage\n */\nexport function serializeSturdyRef(ref: SturdyRef): string {\n return JSON.stringify(ref);\n}\n\n/**\n * Deserialize a SturdyRef from a string\n */\nexport function deserializeSturdyRef(data: string): SturdyRef | null {\n try {\n const parsed = JSON.parse(data);\n\n // Validate required fields\n if (typeof parsed.vatId !== 'string' || typeof parsed.localId !== 'string') {\n return null;\n }\n\n return {\n vatId: parsed.vatId,\n localId: parsed.localId,\n version: parsed.version,\n expiresAt: parsed.expiresAt,\n metadata: parsed.metadata,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Check if a SturdyRef is valid (not expired)\n */\nexport function isSturdyRefValid(ref: SturdyRef): boolean {\n if (ref.expiresAt && Date.now() > ref.expiresAt) {\n return false;\n }\n return true;\n}\n\n/**\n * Create a SturdyRef from components\n */\nexport function createSturdyRef(\n vatId: string,\n localId: string,\n options?: Omit<SaveOptions, 'localId'>\n): SturdyRef {\n return {\n vatId,\n localId,\n version: 1,\n expiresAt: options?.ttlMs ? Date.now() + options.ttlMs : undefined,\n metadata: options?.metadata,\n };\n}\n","/**\n * Performance Optimizations for RPC\n *\n * Phase 3: Performance improvements\n * - Multi-segment message support\n * - Memory pooling\n * - Zero-copy paths where possible\n */\n\nimport { Segment } from '../core/segment.js';\n\n// ========================================================================================\n// Memory Pool\n// ========================================================================================\n\ninterface PooledBuffer {\n buffer: ArrayBuffer;\n size: number;\n lastUsed: number;\n}\n\n/**\n * Memory pool for reusing ArrayBuffers\n * Reduces GC pressure for frequent allocations\n */\nexport class MemoryPool {\n private pools = new Map<number, PooledBuffer[]>();\n private maxPoolSize: number;\n private maxBufferAge: number;\n\n constructor(options?: { maxPoolSize?: number; maxBufferAgeMs?: number }) {\n this.maxPoolSize = options?.maxPoolSize ?? 100;\n this.maxBufferAge = options?.maxBufferAgeMs ?? 60000; // 1 minute\n }\n\n /**\n * Acquire a buffer of at least the requested size\n */\n acquire(size: number): ArrayBuffer {\n // Round up to nearest power of 2 for better pooling\n const pooledSize = this.roundUpSize(size);\n const pool = this.pools.get(pooledSize);\n\n if (pool && pool.length > 0) {\n const now = Date.now();\n // Find a buffer that's not too old\n const index = pool.findIndex((b) => now - b.lastUsed < this.maxBufferAge);\n\n if (index >= 0) {\n const pooled = pool.splice(index, 1)[0];\n return pooled.buffer;\n }\n }\n\n // Allocate new buffer\n return new ArrayBuffer(pooledSize);\n }\n\n /**\n * Release a buffer back to the pool\n */\n release(buffer: ArrayBuffer): void {\n const size = buffer.byteLength;\n\n // Don't pool very small or very large buffers\n if (size < 64 || size > 1024 * 1024) {\n return;\n }\n\n let pool = this.pools.get(size);\n if (!pool) {\n pool = [];\n this.pools.set(size, pool);\n }\n\n if (pool.length < this.maxPoolSize) {\n pool.push({\n buffer,\n size,\n lastUsed: Date.now(),\n });\n }\n }\n\n /**\n * Clear all pooled buffers\n */\n clear(): void {\n this.pools.clear();\n }\n\n /**\n * Get pool statistics\n */\n getStats(): { totalBuffers: number; totalBytes: number; sizes: number[] } {\n let totalBuffers = 0;\n let totalBytes = 0;\n const sizes: number[] = [];\n\n for (const [size, pool] of this.pools) {\n totalBuffers += pool.length;\n totalBytes += size * pool.length;\n sizes.push(size);\n }\n\n return { totalBuffers, totalBytes, sizes };\n }\n\n private roundUpSize(size: number): number {\n // Round up to nearest power of 2, minimum 64 bytes\n if (size <= 64) return 64;\n if (size <= 128) return 128;\n if (size <= 256) return 256;\n if (size <= 512) return 512;\n if (size <= 1024) return 1024;\n if (size <= 2048) return 2048;\n if (size <= 4096) return 4096;\n if (size <= 8192) return 8192;\n if (size <= 16384) return 16384;\n if (size <= 32768) return 32768;\n if (size <= 65536) return 65536;\n return size;\n }\n}\n\n// ========================================================================================\n// Multi-Segment Message Builder\n// ========================================================================================\n\n/**\n * Options for multi-segment message building\n */\nexport interface MultiSegmentOptions {\n /** Initial segment size */\n initialSegmentSize?: number;\n /** Maximum segment size */\n maxSegmentSize?: number;\n /** Whether to allow multiple segments */\n allowMultipleSegments?: boolean;\n}\n\n/**\n * Builder for multi-segment messages\n * Optimizes memory usage for large messages\n */\nexport class MultiSegmentMessageBuilder {\n private segments: Segment[] = [];\n private options: Required<MultiSegmentOptions>;\n private currentSegment: Segment;\n private totalSize = 0;\n\n constructor(options?: MultiSegmentOptions) {\n this.options = {\n initialSegmentSize: options?.initialSegmentSize ?? 8192,\n maxSegmentSize: options?.maxSegmentSize ?? 65536,\n allowMultipleSegments: options?.allowMultipleSegments ?? true,\n };\n\n this.currentSegment = new Segment(this.options.initialSegmentSize);\n this.segments.push(this.currentSegment);\n }\n\n /**\n * Allocate space in the message\n */\n allocate(size: number): { segment: Segment; offset: number } {\n // Align to 8 bytes and convert to words\n const alignedBytes = (size + 7) & ~7;\n const words = alignedBytes / 8;\n\n // Check if current segment has enough space\n // Segment capacity is the buffer size, not the current size\n const currentCapacity = this.currentSegment.byteLength;\n const currentUsed = this.currentSegment.wordCount * 8; // wordCount * 8 = bytes used\n const remainingSpace = currentCapacity - currentUsed;\n\n if (remainingSpace >= alignedBytes) {\n // Current segment has enough space\n const wordOffset = this.currentSegment.allocate(words);\n this.totalSize += alignedBytes;\n return { segment: this.currentSegment, offset: wordOffset * 8 };\n }\n\n // Need a new segment\n if (!this.options.allowMultipleSegments) {\n throw new Error('Message too large for single segment');\n }\n\n // Create new segment\n const newSegmentSize = Math.min(\n Math.max(alignedBytes, this.options.initialSegmentSize),\n this.options.maxSegmentSize\n );\n this.currentSegment = new Segment(newSegmentSize);\n this.segments.push(this.currentSegment);\n\n const newWordOffset = this.currentSegment.allocate(words);\n this.totalSize += alignedBytes;\n return { segment: this.currentSegment, offset: newWordOffset * 8 };\n }\n\n /**\n * Get all segments\n */\n getSegments(): readonly Segment[] {\n return this.segments;\n }\n\n /**\n * Get the total size of all segments\n */\n getTotalSize(): number {\n return this.totalSize;\n }\n\n /**\n * Get the number of segments\n */\n getSegmentCount(): number {\n return this.segments.length;\n }\n\n /**\n * Serialize to a single buffer (for transport)\n */\n toBuffer(): ArrayBuffer {\n if (this.segments.length === 1) {\n // Single segment - use asUint8Array to get the used portion\n const segmentData = this.segments[0].asUint8Array();\n return segmentData.buffer.slice(\n segmentData.byteOffset,\n segmentData.byteOffset + segmentData.byteLength\n ) as ArrayBuffer;\n }\n\n // Multi-segment - need to serialize with segment table\n // This is a simplified version - full implementation would include\n // the segment table at the beginning\n const totalSize = this.segments.reduce((sum, seg) => sum + seg.byteLength, 0);\n const result = new ArrayBuffer(totalSize + 8 * this.segments.length); // Space for segment table\n const view = new DataView(result);\n const bytes = new Uint8Array(result);\n\n // Write segment table\n view.setUint32(0, this.segments.length - 1, true); // Segment count - 1\n view.setUint32(4, 0, true); // Padding for first segment size (in words)\n\n let offset = 8;\n for (let i = 0; i < this.segments.length; i++) {\n const segment = this.segments[i];\n if (i > 0) {\n view.setUint32(offset, segment.byteLength / 8, true); // Segment size in words\n offset += 4;\n }\n\n // Copy segment data\n const segmentBuffer = new Uint8Array(segment.byteLength);\n // Copy data from segment's DataView\n const segmentData = segment.dataView;\n for (let i = 0; i < segment.byteLength; i++) {\n segmentBuffer[i] = segmentData.getUint8(i);\n }\n bytes.set(segmentBuffer, offset);\n offset += segment.byteLength;\n }\n\n return result;\n }\n}\n\n// ========================================================================================\n// Zero-Copy Utilities\n// ========================================================================================\n\n/**\n * View into a buffer without copying\n */\nexport interface ZeroCopyView {\n buffer: ArrayBuffer;\n byteOffset: number;\n byteLength: number;\n}\n\n/**\n * Create a zero-copy view of a buffer\n */\nexport function createZeroCopyView(\n buffer: ArrayBuffer,\n byteOffset = 0,\n byteLength?: number\n): ZeroCopyView {\n return {\n buffer,\n byteOffset,\n byteLength: byteLength ?? buffer.byteLength - byteOffset,\n };\n}\n\n/**\n * Check if two buffers are the same underlying memory\n */\nexport function isSameBuffer(a: ArrayBuffer, b: ArrayBuffer): boolean {\n try {\n // This is a hack to check if two buffers are the same\n // In a real implementation, we'd use a more reliable method\n return a === b;\n } catch {\n return false;\n }\n}\n\n/**\n * Copy data between buffers using the fastest available method\n */\nexport function fastCopy(\n src: ArrayBuffer,\n dst: ArrayBuffer,\n srcOffset = 0,\n dstOffset = 0,\n length?: number\n): void {\n const len = length ?? Math.min(src.byteLength - srcOffset, dst.byteLength - dstOffset);\n const srcView = new Uint8Array(src, srcOffset, len);\n const dstView = new Uint8Array(dst, dstOffset, len);\n dstView.set(srcView);\n}\n\n// ========================================================================================\n// RPC Message Optimization\n// ========================================================================================\n\n/**\n * Options for RPC message building\n */\nexport interface RpcMessageOptions {\n /** Use multi-segment messages */\n useMultiSegment?: boolean;\n /** Initial segment size */\n initialSegmentSize?: number;\n /** Use memory pooling */\n useMemoryPool?: boolean;\n /** Memory pool instance */\n memoryPool?: MemoryPool;\n}\n\n/**\n * Optimized RPC message builder\n */\nexport class OptimizedRpcMessageBuilder {\n private options: Required<RpcMessageOptions>;\n private pool: MemoryPool;\n\n constructor(options?: RpcMessageOptions) {\n this.options = {\n useMultiSegment: options?.useMultiSegment ?? true,\n initialSegmentSize: options?.initialSegmentSize ?? 8192,\n useMemoryPool: options?.useMemoryPool ?? true,\n memoryPool: options?.memoryPool ?? new MemoryPool(),\n };\n this.pool = this.options.memoryPool;\n }\n\n /**\n * Build a message with optimizations applied\n */\n buildMessage(content: Uint8Array): ArrayBuffer {\n const totalSize = 8 + content.length; // Header + content\n\n if (this.options.useMemoryPool) {\n const buffer = this.pool.acquire(totalSize);\n const view = new DataView(buffer);\n const bytes = new Uint8Array(buffer);\n\n // Write header (simplified)\n view.setUint32(0, 0, true); // Single segment indicator\n view.setUint32(4, content.length / 8, true); // Size in words\n\n // Copy content\n bytes.set(content, 8);\n\n return buffer;\n }\n\n // Standard allocation\n const buffer = new ArrayBuffer(totalSize);\n const view = new DataView(buffer);\n const bytes = new Uint8Array(buffer);\n\n view.setUint32(0, 0, true);\n view.setUint32(4, content.length / 8, true);\n bytes.set(content, 8);\n\n return buffer;\n }\n\n /**\n * Release a buffer back to the pool\n */\n releaseBuffer(buffer: ArrayBuffer): void {\n if (this.options.useMemoryPool) {\n this.pool.release(buffer);\n }\n }\n\n /**\n * Get pool statistics\n */\n getPoolStats(): { totalBuffers: number; totalBytes: number; sizes: number[] } {\n return this.pool.getStats();\n }\n}\n\n// ========================================================================================\n// Global Memory Pool (Singleton)\n// ========================================================================================\n\nlet globalMemoryPool: MemoryPool | null = null;\n\n/**\n * Get the global memory pool instance\n */\nexport function getGlobalMemoryPool(): MemoryPool {\n if (!globalMemoryPool) {\n globalMemoryPool = new MemoryPool();\n }\n return globalMemoryPool;\n}\n\n/**\n * Configure the global memory pool\n */\nexport function configureGlobalMemoryPool(options: {\n maxPoolSize?: number;\n maxBufferAgeMs?: number;\n}): void {\n globalMemoryPool = new MemoryPool(options);\n}\n","/**\n * Connection Manager\n *\n * Manages multiple RPC connections for Level 3 RPC (Three-way introductions).\n * Handles connection pooling, automatic connection establishment, and routing\n * of messages between vats.\n *\n * Level 3 RPC allows capabilities to be passed between vats that don't have\n * a direct connection, and enables those vats to form direct connections.\n */\n\nimport type { RpcConnection, RpcConnectionOptions } from './rpc-connection.js';\nimport type { ProvisionId, RecipientId, ThirdPartyCapId } from './rpc-types.js';\nimport type { RpcTransport } from './transport.js';\n\n/** Unique identifier for a vat */\nexport interface VatId {\n /** The raw vat identifier */\n id: Uint8Array;\n}\n\n/** Connection metadata */\nexport interface ConnectionInfo {\n /** The connection instance */\n connection: RpcConnection;\n /** The vat ID of the remote peer */\n remoteVatId: VatId;\n /** When the connection was established */\n establishedAt: Date;\n /** Last activity timestamp */\n lastActivity: Date;\n /** Connection state */\n state: 'connecting' | 'connected' | 'closing' | 'closed';\n}\n\n/** Pending provision waiting for acceptance */\nexport interface PendingProvision {\n /** Unique provision ID */\n provisionId: ProvisionId;\n /** The vat ID of the intended recipient */\n recipientId: VatId;\n /** The capability being provided */\n targetExportId: number;\n /** When the provision was created */\n createdAt: Date;\n /** Question ID from the Provide message */\n questionId: number;\n /** Whether this provision is embargoed (for cycle breaking) */\n embargoed: boolean;\n}\n\n/** Options for ConnectionManager */\nexport interface ConnectionManagerOptions {\n /** This vat's own ID */\n selfVatId: VatId;\n /** Factory function to create connections */\n connectionFactory: (vatId: VatId, address?: string) => Promise<RpcTransport>;\n /** Default connection options */\n connectionOptions?: RpcConnectionOptions;\n /** Maximum number of concurrent connections */\n maxConnections?: number;\n /** Connection idle timeout in milliseconds */\n idleTimeoutMs?: number;\n /** Whether to automatically establish connections to third parties */\n autoConnect?: boolean;\n}\n\n/**\n * ConnectionManager manages multiple RPC connections for Level 3 RPC.\n *\n * Key responsibilities:\n * 1. Maintain a pool of connections to other vats\n * 2. Handle automatic connection establishment for third-party capabilities\n * 3. Manage pending provisions (capabilities waiting to be picked up)\n * 4. Route messages to the appropriate connection\n * 5. Handle connection lifecycle (connect, disconnect, reconnect)\n */\nexport class ConnectionManager {\n private options: ConnectionManagerOptions;\n private connections = new Map<string, ConnectionInfo>();\n private pendingProvisions = new Map<string, PendingProvision>();\n private connectionPromises = new Map<string, Promise<RpcConnection>>();\n\n constructor(options: ConnectionManagerOptions) {\n this.options = {\n maxConnections: 100,\n idleTimeoutMs: 300000, // 5 minutes\n autoConnect: true,\n ...options,\n };\n }\n\n // ========================================================================================\n // Connection Management\n // ========================================================================================\n\n /**\n * Register an existing connection with the manager.\n * This is called when a connection is established (either inbound or outbound).\n */\n registerConnection(vatId: VatId, connection: RpcConnection): ConnectionInfo {\n const vatIdKey = this.vatIdToKey(vatId);\n\n const info: ConnectionInfo = {\n connection,\n remoteVatId: vatId,\n establishedAt: new Date(),\n lastActivity: new Date(),\n state: 'connected',\n };\n\n this.connections.set(vatIdKey, info);\n\n // Set up cleanup on connection close\n // Note: The connection's onClose handler should be set by the caller\n\n return info;\n }\n\n /**\n * Get or establish a connection to a vat.\n * If autoConnect is enabled and no connection exists, a new one will be created.\n */\n async getConnection(vatId: VatId): Promise<RpcConnection | undefined> {\n const vatIdKey = this.vatIdToKey(vatId);\n\n // Check for existing connection\n const existing = this.connections.get(vatIdKey);\n if (existing && existing.state === 'connected') {\n existing.lastActivity = new Date();\n return existing.connection;\n }\n\n // Check for in-progress connection\n const pending = this.connectionPromises.get(vatIdKey);\n if (pending) {\n return pending;\n }\n\n // Auto-connect if enabled\n if (this.options.autoConnect) {\n return this.establishConnection(vatId);\n }\n\n return undefined;\n }\n\n /**\n * Establish a new connection to a vat.\n */\n async establishConnection(vatId: VatId, address?: string): Promise<RpcConnection> {\n const vatIdKey = this.vatIdToKey(vatId);\n\n // Check if already connecting\n if (this.connectionPromises.has(vatIdKey)) {\n return this.connectionPromises.get(vatIdKey)!;\n }\n\n // Create connection promise\n const connectPromise = this.doEstablishConnection(vatId, address);\n this.connectionPromises.set(vatIdKey, connectPromise);\n\n try {\n const connection = await connectPromise;\n return connection;\n } finally {\n this.connectionPromises.delete(vatIdKey);\n }\n }\n\n private async doEstablishConnection(vatId: VatId, address?: string): Promise<RpcConnection> {\n const { RpcConnection } = await import('./rpc-connection.js');\n\n // Create transport using the factory\n const transport = await this.options.connectionFactory(vatId, address);\n\n // Create and start the connection\n const connection = new RpcConnection(transport, this.options.connectionOptions);\n await connection.start();\n\n // Register the connection\n this.registerConnection(vatId, connection);\n\n return connection;\n }\n\n /**\n * Close a connection to a vat.\n */\n async closeConnection(vatId: VatId): Promise<void> {\n const vatIdKey = this.vatIdToKey(vatId);\n const info = this.connections.get(vatIdKey);\n\n if (info) {\n info.state = 'closing';\n await info.connection.stop();\n this.connections.delete(vatIdKey);\n }\n }\n\n /**\n * Close all connections.\n */\n async closeAll(): Promise<void> {\n const closePromises: Promise<void>[] = [];\n\n for (const [_vatIdKey, info] of this.connections) {\n info.state = 'closing';\n closePromises.push(\n info.connection.stop().catch(() => {\n // Ignore errors during shutdown\n })\n );\n }\n\n await Promise.all(closePromises);\n this.connections.clear();\n this.pendingProvisions.clear();\n }\n\n // ========================================================================================\n // Provision Management (for Provide/Accept)\n // ========================================================================================\n\n /**\n * Create a pending provision for a third-party capability.\n * Called when we receive a Provide message.\n */\n createPendingProvision(\n provisionId: ProvisionId,\n recipientId: VatId,\n targetExportId: number,\n questionId: number,\n embargoed: boolean\n ): PendingProvision {\n const provisionKey = this.provisionIdToKey(provisionId);\n\n const provision: PendingProvision = {\n provisionId,\n recipientId,\n targetExportId,\n questionId,\n createdAt: new Date(),\n embargoed,\n };\n\n this.pendingProvisions.set(provisionKey, provision);\n return provision;\n }\n\n /**\n * Get a pending provision by ID.\n */\n getPendingProvision(provisionId: ProvisionId): PendingProvision | undefined {\n const provisionKey = this.provisionIdToKey(provisionId);\n return this.pendingProvisions.get(provisionKey);\n }\n\n /**\n * Remove a pending provision (when it's been accepted or expired).\n */\n removePendingProvision(provisionId: ProvisionId): boolean {\n const provisionKey = this.provisionIdToKey(provisionId);\n return this.pendingProvisions.delete(provisionKey);\n }\n\n /**\n * Find provisions for a specific recipient.\n */\n findProvisionsForRecipient(recipientId: VatId): PendingProvision[] {\n const recipientKey = this.vatIdToKey(recipientId);\n const result: PendingProvision[] = [];\n\n for (const provision of this.pendingProvisions.values()) {\n if (this.vatIdToKey(provision.recipientId) === recipientKey) {\n result.push(provision);\n }\n }\n\n return result;\n }\n\n /**\n * Clean up expired provisions.\n */\n cleanupExpiredProvisions(maxAgeMs = 300000): number {\n const now = Date.now();\n let removed = 0;\n\n for (const [key, provision] of this.pendingProvisions) {\n if (now - provision.createdAt.getTime() > maxAgeMs) {\n this.pendingProvisions.delete(key);\n removed++;\n }\n }\n\n return removed;\n }\n\n // ========================================================================================\n // Third-Party Capability Resolution\n // ========================================================================================\n\n /**\n * Resolve a third-party capability ID to a connection.\n * This is the core of Level 3 RPC - automatically establishing connections\n * to third parties when capabilities are passed between vats.\n */\n async resolveThirdPartyCap(thirdPartyCapId: ThirdPartyCapId): Promise<\n | {\n connection: RpcConnection;\n provisionId: ProvisionId;\n }\n | undefined\n > {\n // Parse the ThirdPartyCapId to extract vat ID and provision ID\n const parsed = this.parseThirdPartyCapId(thirdPartyCapId);\n if (!parsed) {\n return undefined;\n }\n\n // Get or establish connection to the third party\n const connection = await this.getConnection(parsed.vatId);\n if (!connection) {\n return undefined;\n }\n\n return {\n connection,\n provisionId: parsed.provisionId,\n };\n }\n\n /**\n * Parse a ThirdPartyCapId to extract vat ID and provision ID.\n * The format is implementation-specific, but typically:\n * - First N bytes: vat ID\n * - Remaining bytes: provision ID\n */\n private parseThirdPartyCapId(thirdPartyCapId: ThirdPartyCapId):\n | {\n vatId: VatId;\n provisionId: ProvisionId;\n }\n | undefined {\n // Default implementation: first 32 bytes are vat ID, rest is provision ID\n // This can be overridden by the application\n const data = thirdPartyCapId.id;\n\n if (data.length < 32) {\n return undefined;\n }\n\n const vatIdBytes = data.slice(0, 32);\n const provisionIdBytes = data.slice(32);\n\n return {\n vatId: { id: vatIdBytes },\n provisionId: { id: provisionIdBytes },\n };\n }\n\n // ========================================================================================\n // Utility Methods\n // ========================================================================================\n\n /**\n * Get all active connections.\n */\n getAllConnections(): ConnectionInfo[] {\n return Array.from(this.connections.values());\n }\n\n /**\n * Get the number of active connections.\n */\n getConnectionCount(): number {\n return this.connections.size;\n }\n\n /**\n * Get the number of pending provisions.\n */\n getPendingProvisionCount(): number {\n return this.pendingProvisions.size;\n }\n\n /**\n * Check if a connection exists to a vat.\n */\n hasConnection(vatId: VatId): boolean {\n const vatIdKey = this.vatIdToKey(vatId);\n const info = this.connections.get(vatIdKey);\n return info !== undefined && info.state === 'connected';\n }\n\n /**\n * Update the last activity timestamp for a connection.\n */\n touchConnection(vatId: VatId): void {\n const vatIdKey = this.vatIdToKey(vatId);\n const info = this.connections.get(vatIdKey);\n if (info) {\n info.lastActivity = new Date();\n }\n }\n\n // ========================================================================================\n // Private Helpers\n // ========================================================================================\n\n private vatIdToKey(vatId: VatId): string {\n // Convert Uint8Array to hex string for use as Map key\n return Array.from(vatId.id)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n }\n\n private provisionIdToKey(provisionId: ProvisionId): string {\n return Array.from(provisionId.id)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n }\n}\n\n/**\n * Create a ThirdPartyCapId from vat ID and provision ID.\n */\nexport function createThirdPartyCapId(vatId: VatId, provisionId: ProvisionId): ThirdPartyCapId {\n // Concatenate vat ID and provision ID\n const combined = new Uint8Array(vatId.id.length + provisionId.id.length);\n combined.set(vatId.id, 0);\n combined.set(provisionId.id, vatId.id.length);\n\n return { id: combined };\n}\n\n/**\n * Create a RecipientId from a vat ID.\n */\nexport function createRecipientId(vatId: VatId): RecipientId {\n return { id: vatId.id };\n}\n\n/**\n * Create a ProvisionId from raw bytes.\n */\nexport function createProvisionId(id: Uint8Array): ProvisionId {\n return { id };\n}\n\n/**\n * Generate a random provision ID.\n */\nexport function generateProvisionId(): ProvisionId {\n const id = new Uint8Array(32);\n if (typeof crypto !== 'undefined' && crypto.getRandomValues) {\n crypto.getRandomValues(id);\n } else {\n // Fallback for Node.js\n const { randomBytes } = require('node:crypto');\n randomBytes(32).copy(id);\n }\n return { id };\n}\n\n/**\n * Generate a random vat ID.\n */\nexport function generateVatId(): VatId {\n const id = new Uint8Array(32);\n if (typeof crypto !== 'undefined' && crypto.getRandomValues) {\n crypto.getRandomValues(id);\n } else {\n // Fallback for Node.js\n const { randomBytes } = require('node:crypto');\n randomBytes(32).copy(id);\n }\n return { id };\n}\n","/**\n * Level 3 RPC Message Handlers\n *\n * Implements the three-way introduction protocol for Level 3 RPC:\n * - Provide: Offer a capability to a third party\n * - Accept: Accept a capability from a third party\n * - Embargo handling for cycle breaking\n *\n * The three-way introduction protocol allows capabilities to be passed between\n * vats that don't have a direct connection, enabling those vats to form direct\n * connections.\n */\n\nimport type { ConnectionManager, PendingProvision, VatId } from './connection-manager.js';\nimport { createThirdPartyCapId, generateProvisionId } from './connection-manager.js';\nimport type { RpcConnection } from './rpc-connection.js';\nimport type {\n Accept,\n CapDescriptor,\n Disembargo,\n ExportId,\n ImportId,\n MessageTarget,\n Provide,\n RecipientId,\n RpcMessage,\n ThirdPartyCapId,\n} from './rpc-types.js';\n\n/** Options for Level3Handlers */\nexport interface Level3HandlersOptions {\n /** The connection this handler is attached to */\n connection: RpcConnection;\n /** The connection manager for managing third-party connections */\n connectionManager: ConnectionManager;\n /** This vat's ID */\n selfVatId: VatId;\n /** Handler for incoming Provide messages */\n onProvide?: (provide: Provide) => Promise<void>;\n /** Handler for incoming Accept messages */\n onAccept?: (accept: Accept) => Promise<void>;\n}\n\n/**\n * Manages Level 3 RPC message handling for a connection.\n *\n * This class handles:\n * 1. Provide messages - when someone wants to give us a capability to share with a third party\n * 2. Accept messages - when a third party wants to pick up a capability we provided\n * 3. Embargo handling - breaking cycles in introduction graphs\n */\nexport class Level3Handlers {\n private options: Level3HandlersOptions;\n private pendingAccepts = new Map<number, PendingAccept>();\n private embargoedCalls = new Map<number, EmbargoedCall[]>();\n private nextEmbargoId = 1;\n\n constructor(options: Level3HandlersOptions) {\n this.options = options;\n }\n\n // ========================================================================================\n // Provide Message Handling\n // ========================================================================================\n\n /**\n * Handle an incoming Provide message.\n *\n * When we receive a Provide message, it means someone wants us to hold a capability\n * and make it available to a specific third party. We:\n * 1. Create a pending provision\n * 2. Return an answer acknowledging receipt\n * 3. Wait for the third party to Accept\n */\n async handleProvide(provide: Provide): Promise<void> {\n const { questionId, target, recipient } = provide;\n const { connectionManager } = this.options;\n\n // Generate a unique provision ID\n const provisionId = generateProvisionId();\n\n // Extract the target export ID from the MessageTarget\n const targetExportId = this.extractTargetExportId(target);\n if (targetExportId === undefined) {\n // Can't provide this target - send exception\n await this.sendReturnException(\n questionId,\n 'Invalid provide target: must be a hosted capability'\n );\n return;\n }\n\n // Create the pending provision\n const _provision: PendingProvision = connectionManager.createPendingProvision(\n provisionId,\n this.recipientIdToVatId(recipient),\n targetExportId,\n questionId,\n false // Not embargoed by default\n );\n\n // Call the custom handler if provided\n if (this.options.onProvide) {\n await this.options.onProvide(provide);\n }\n\n // Send Return with the provision info\n // The provision ID is embedded in the answer for reference\n await this.sendReturnResults(questionId, {\n provisionId: provisionId.id,\n });\n }\n\n /**\n * Send a Provide message to offer a capability to a third party.\n *\n * This is called when we want to introduce a third party to a capability we hold.\n * For example, Alice calls this to offer Bob access to Carol's capability.\n */\n async sendProvide(\n target: MessageTarget,\n recipient: RecipientId\n ): Promise<{ questionId: number; provisionId: ThirdPartyCapId }> {\n const { connection } = this.options;\n\n // Create a question for this provide\n const questionId = connection.createQuestion();\n\n const provideMsg: RpcMessage = {\n type: 'provide',\n provide: {\n questionId,\n target,\n recipient,\n },\n };\n\n await connection.sendCall(provideMsg.provide as any);\n\n // Wait for the return to get the provision ID\n const _result = await connection.waitForAnswer(questionId);\n\n // Extract provision ID from result\n // In a full implementation, we'd parse the result payload\n const provisionId: ThirdPartyCapId = {\n id: new Uint8Array(0),\n };\n\n return { questionId, provisionId };\n }\n\n // ========================================================================================\n // Accept Message Handling\n // ========================================================================================\n\n /**\n * Handle an incoming Accept message.\n *\n * When we receive an Accept message, it means a third party wants to pick up\n * a capability we previously agreed to provide. We:\n * 1. Look up the pending provision\n * 2. Verify the recipient matches\n * 3. Return the capability\n */\n async handleAccept(accept: Accept): Promise<void> {\n const { questionId, provision, embargo } = accept;\n const { connectionManager } = this.options;\n\n // Find the pending provision\n const pendingProvision = connectionManager.getPendingProvision(provision);\n\n if (!pendingProvision) {\n // No such provision - send exception\n await this.sendReturnException(\n questionId,\n 'Invalid provision ID: no pending provision found'\n );\n return;\n }\n\n // Remove the pending provision\n connectionManager.removePendingProvision(provision);\n\n // If embargoed, set up embargo handling\n if (embargo || pendingProvision.embargoed) {\n await this.handleEmbargoedAccept(questionId, pendingProvision);\n return;\n }\n\n // Return the capability\n const capDescriptor: CapDescriptor = {\n type: 'senderHosted',\n exportId: pendingProvision.targetExportId as ExportId,\n };\n\n await this.sendReturnCapability(questionId, capDescriptor);\n\n // Call the custom handler if provided\n if (this.options.onAccept) {\n await this.options.onAccept(accept);\n }\n }\n\n /**\n * Send an Accept message to pick up a capability from a third party.\n *\n * This is called when we receive a third-party capability and want to\n * establish a direct connection to use it.\n */\n async sendAccept(\n targetConnection: RpcConnection,\n provision: { id: Uint8Array },\n embargo = false\n ): Promise<ImportId> {\n const questionId = targetConnection.createQuestion();\n\n const acceptMsg: RpcMessage = {\n type: 'accept',\n accept: {\n questionId,\n provision: provision as any,\n embargo,\n },\n };\n\n await targetConnection.sendCall(acceptMsg.accept as any);\n\n // Wait for the return\n const _result = await targetConnection.waitForAnswer(questionId);\n\n // In a full implementation, we'd extract the import ID from the result\n // For now, return a placeholder\n return 0 as ImportId;\n }\n\n // ========================================================================================\n // Embargo Handling (Cycle Breaking)\n // ========================================================================================\n\n /**\n * Handle an embargoed accept.\n *\n * Embargoes are used to break cycles in the introduction graph. For example,\n * if Alice introduces Bob to Carol and Carol to Bob simultaneously, both\n * introductions use embargo=true to prevent deadlock.\n */\n private async handleEmbargoedAccept(\n questionId: number,\n provision: PendingProvision\n ): Promise<void> {\n // Store the pending accept\n const pendingAccept: PendingAccept = {\n questionId,\n provision,\n embargoId: this.nextEmbargoId++,\n };\n\n this.pendingAccepts.set(questionId, pendingAccept);\n\n // Send a Return with resultsSentElsewhere to indicate we're waiting\n await this.sendReturnResultsSentElsewhere(questionId);\n\n // The embargo will be lifted when we receive a Disembargo message\n }\n\n /**\n * Handle a Disembargo message.\n *\n * Disembargo messages are used to lift embargoes on capabilities.\n */\n async handleDisembargo(disembargo: Disembargo): Promise<void> {\n const { target, context } = disembargo;\n\n switch (context.type) {\n case 'senderLoopback':\n // Echo back as receiverLoopback\n await this.sendDisembargoEcho(disembargo);\n break;\n\n case 'receiverLoopback':\n // Embargo lifted - process any pending calls\n await this.liftEmbargo(context.embargoId);\n break;\n\n case 'accept':\n // Embargo on a third-party accept can be lifted\n await this.liftAcceptEmbargo(target);\n break;\n\n case 'provide':\n // Embargo on a provision can be lifted\n await this.liftProvideEmbargo(context.questionId);\n break;\n }\n }\n\n /**\n * Lift an embargo by ID.\n */\n private async liftEmbargo(embargoId: number): Promise<void> {\n // Find and process embargoed calls\n const calls = this.embargoedCalls.get(embargoId);\n if (calls) {\n for (const call of calls) {\n // Re-send the call\n await this.resendEmbargoedCall(call);\n }\n this.embargoedCalls.delete(embargoId);\n }\n }\n\n /**\n * Lift an embargo on an accept.\n */\n private async liftAcceptEmbargo(target: MessageTarget): Promise<void> {\n // Find pending accepts for this target and complete them\n for (const [questionId, pendingAccept] of this.pendingAccepts) {\n if (this.matchesTarget(pendingAccept.provision.targetExportId, target)) {\n // Return the capability\n const capDescriptor: CapDescriptor = {\n type: 'senderHosted',\n exportId: pendingAccept.provision.targetExportId as ExportId,\n };\n\n await this.sendReturnCapability(pendingAccept.questionId, capDescriptor);\n this.pendingAccepts.delete(questionId);\n }\n }\n }\n\n /**\n * Lift an embargo on a provide.\n */\n private async liftProvideEmbargo(_questionId: number): Promise<void> {\n // Find the pending provision and mark it as no longer embargoed\n const { connectionManager } = this.options;\n\n for (const _provision of connectionManager.getAllConnections()) {\n // This is a simplified implementation\n // In a full implementation, we'd track provisions by question ID\n }\n }\n\n // ========================================================================================\n // Third-Party Capability Handling\n // ========================================================================================\n\n /**\n * Handle receiving a third-party capability.\n *\n * When we receive a CapDescriptor with type 'thirdPartyHosted', we need to:\n * 1. Establish a connection to the third party (if not already connected)\n * 2. Send an Accept message to pick up the capability\n * 3. Return a local import ID for the capability\n */\n async handleThirdPartyCapability(\n thirdPartyCapId: ThirdPartyCapId\n ): Promise<ImportId | undefined> {\n const { connectionManager } = this.options;\n\n // Resolve the third-party capability\n const resolved = await connectionManager.resolveThirdPartyCap(thirdPartyCapId);\n if (!resolved) {\n return undefined;\n }\n\n const { connection, provisionId } = resolved;\n\n // Send Accept to pick up the capability\n const importId = await this.sendAccept(connection, provisionId);\n\n return importId;\n }\n\n /**\n * Create a third-party capability descriptor.\n *\n * This is called when we want to pass a capability to a peer, but the capability\n * is actually hosted by a third party. We create a ThirdPartyCapId that allows\n * the recipient to connect directly to the third party.\n */\n createThirdPartyCapDescriptor(\n _hostedConnection: RpcConnection,\n exportId: ExportId,\n recipientVatId: VatId\n ): CapDescriptor {\n const { connectionManager, selfVatId } = this.options;\n\n // Generate a provision ID\n const provisionId = generateProvisionId();\n\n // Create the ThirdPartyCapId\n // Format: [selfVatId (32 bytes)] [provisionId (32 bytes)]\n const thirdPartyCapId = createThirdPartyCapId(selfVatId, provisionId);\n\n // Create a pending provision for this\n connectionManager.createPendingProvision(\n provisionId,\n recipientVatId,\n exportId,\n 0, // No question ID for this type of provision\n false\n );\n\n return {\n type: 'thirdPartyHosted',\n thirdPartyCapId,\n };\n }\n\n // ========================================================================================\n // Helper Methods\n // ========================================================================================\n\n private extractTargetExportId(target: MessageTarget): number | undefined {\n if (target.type === 'importedCap') {\n return target.importId;\n }\n // promisedAnswer targets are not supported for Provide\n return undefined;\n }\n\n private recipientIdToVatId(recipient: RecipientId): VatId {\n return { id: recipient.id };\n }\n\n private matchesTarget(exportId: number, target: MessageTarget): boolean {\n if (target.type === 'importedCap') {\n return target.importId === exportId;\n }\n return false;\n }\n\n private async sendReturnResults(questionId: number, _results: unknown): Promise<void> {\n const { connection } = this.options;\n\n // In a full implementation, we'd serialize the results\n const returnMsg: RpcMessage = {\n type: 'return',\n return: {\n answerId: questionId,\n releaseParamCaps: true,\n noFinishNeeded: false,\n result: {\n type: 'results',\n payload: {\n content: new Uint8Array(0),\n capTable: [],\n },\n },\n },\n };\n\n // @ts-ignore - accessing internal method\n await connection.sendReturn(returnMsg.return);\n }\n\n private async sendReturnCapability(questionId: number, cap: CapDescriptor): Promise<void> {\n const { connection } = this.options;\n\n const returnMsg: RpcMessage = {\n type: 'return',\n return: {\n answerId: questionId,\n releaseParamCaps: true,\n noFinishNeeded: false,\n result: {\n type: 'results',\n payload: {\n content: new Uint8Array(0),\n capTable: [cap],\n },\n },\n },\n };\n\n // @ts-ignore - accessing internal method\n await connection.sendReturn(returnMsg.return);\n }\n\n private async sendReturnException(questionId: number, reason: string): Promise<void> {\n const { connection } = this.options;\n\n const returnMsg: RpcMessage = {\n type: 'return',\n return: {\n answerId: questionId,\n releaseParamCaps: true,\n noFinishNeeded: false,\n result: {\n type: 'exception',\n exception: {\n reason,\n type: 'failed',\n },\n },\n },\n };\n\n // @ts-ignore - accessing internal method\n await connection.sendReturn(returnMsg.return);\n }\n\n private async sendReturnResultsSentElsewhere(questionId: number): Promise<void> {\n const { connection } = this.options;\n\n const returnMsg: RpcMessage = {\n type: 'return',\n return: {\n answerId: questionId,\n releaseParamCaps: true,\n noFinishNeeded: false,\n result: {\n type: 'resultsSentElsewhere',\n },\n },\n };\n\n // @ts-ignore - accessing internal method\n await connection.sendReturn(returnMsg.return);\n }\n\n private async sendDisembargoEcho(disembargo: Disembargo): Promise<void> {\n const { connection } = this.options;\n\n if (disembargo.context.type !== 'senderLoopback') {\n return;\n }\n\n const echoMsg: RpcMessage = {\n type: 'disembargo',\n disembargo: {\n target: disembargo.target,\n context: {\n type: 'receiverLoopback',\n embargoId: disembargo.context.embargoId,\n },\n },\n };\n\n // @ts-ignore - accessing internal method\n await connection.sendDisembargo(echoMsg.disembargo);\n }\n\n private async resendEmbargoedCall(_call: EmbargoedCall): Promise<void> {\n // In a full implementation, we'd re-send the call\n // For now, this is a placeholder\n }\n}\n\n/** Pending accept waiting for embargo to be lifted */\ninterface PendingAccept {\n questionId: number;\n provision: PendingProvision;\n embargoId: number;\n}\n\n/** An embargoed call waiting to be re-sent */\ninterface EmbargoedCall {\n questionId: number;\n target: MessageTarget;\n interfaceId: bigint;\n methodId: number;\n params: unknown;\n embargoId: number;\n}\n","/**\n * Level 4 RPC: Reference Equality / Join Operations\n *\n * Level 4 RPC allows verifying that capability references received from different\n * sources point to the same underlying object. This is crucial for:\n *\n * 1. **Escrow Agents**: Verifying that two parties are referring to the same object\n * before acting as a trusted intermediary.\n * 2. **Consensus Verification**: Ensuring multiple parties agree on the identity\n * of an object.\n * 3. **Security**: Preventing spoofing attacks where an attacker might try to\n * substitute a different object.\n *\n * ## Core Concept\n *\n * When Alice receives capability references from both Bob and Carol that should\n * point to the same object (e.g., a shared resource), she can use Join to verify\n * this:\n *\n * ```\n * Alice receives cap1 from Bob → points to object X (via proxy P1)\n * Alice receives cap2 from Carol → points to object X (via proxy P2)\n * Alice sends Join(cap1, cap2) to P1\n * P1 verifies that both caps point to the same underlying object\n * Result: confirmed equal or not equal\n * ```\n *\n * ## Object Identity\n *\n * Object identity is determined by:\n * - **Vat ID**: The vat hosting the object\n * - **Object ID**: A unique identifier within that vat\n * - **Identity Hash**: A cryptographic hash of the object's identity\n *\n * ## Join Protocol\n *\n * 1. Alice sends Join message to the first capability's host (P1)\n * 2. P1 receives the Join request with two capability references\n * 3. P1 verifies that both references resolve to the same underlying object\n * 4. P1 returns the result (equal or not equal)\n *\n * ## Escrow Agent Pattern\n *\n * ```\n * Bob wants to sell an object to Carol\n * Alice acts as escrow agent\n * Bob sends Alice a reference to the object\n * Carol sends Alice a reference to the same object\n * Alice verifies (via Join) that both refer to the same object\n * Alice holds payment from Carol\n * Bob transfers object to Carol\n * Alice releases payment to Bob\n * ```\n *\n * ## Implementation Notes\n *\n * - Join operations are idempotent\n * - Results are cached to avoid redundant verification\n * - Multiple capabilities can be joined in a single operation\n * - The operation may involve network calls to resolve proxies\n *\n * @module level4-handlers\n */\n\n/**\n * Object identity information used for equality verification.\n */\nexport interface ObjectIdentity {\n /** The vat ID of the object host */\n vatId: Uint8Array;\n\n /** The unique object ID within the vat */\n objectId: Uint8Array;\n\n /** Optional identity hash/fingerprint for verification */\n identityHash?: Uint8Array;\n\n /** Timestamp when this identity was established */\n establishedAt: number;\n}\n\n/**\n * Result of a Join operation.\n */\nexport interface JoinResult {\n /** Whether the capabilities are equal (point to the same object) */\n equal: boolean;\n\n /** If equal, the shared object identity */\n identity?: ObjectIdentity;\n\n /** If not equal, reasons for inequality */\n inequalityReason?: string;\n\n /** The join operation ID */\n joinId: number;\n}\n\n/**\n * Options for a Join operation.\n */\nexport interface JoinOptions {\n /** Timeout for the join operation in milliseconds */\n timeoutMs?: number;\n\n /** Whether to require cryptographic verification */\n requireCryptoVerification?: boolean;\n\n /** Whether to cache the result */\n cacheResult?: boolean;\n\n /** TTL for cached results in milliseconds */\n cacheTtlMs?: number;\n}\n\n/**\n * Default join options.\n */\nexport const DEFAULT_JOIN_OPTIONS: Required<JoinOptions> = {\n timeoutMs: 30000,\n requireCryptoVerification: true,\n cacheResult: true,\n cacheTtlMs: 300000, // 5 minutes\n};\n\n/**\n * Status of a pending Join operation.\n */\nexport interface PendingJoin {\n /** The join operation ID */\n joinId: number;\n\n /** The first capability target */\n target1: unknown;\n\n /** The second capability target */\n target2: unknown;\n\n /** When the join was initiated */\n startedAt: number;\n\n /** Resolve function for the promise */\n resolve: (result: JoinResult) => void;\n\n /** Reject function for the promise */\n reject: (error: Error) => void;\n}\n\n/**\n * Cached join result.\n */\nexport interface CachedJoinResult {\n /** The cached result */\n result: JoinResult;\n\n /** When the result was cached */\n cachedAt: number;\n\n /** The targets that were joined */\n targets: [string, string]; // Hashed target identifiers\n}\n\n/**\n * Configuration for the escrow agent mode.\n */\nexport interface EscrowConfig {\n /** Whether escrow mode is enabled */\n enabled: boolean;\n\n /** Required number of parties for consensus */\n requiredParties: number;\n\n /** Timeout for escrow operations */\n timeoutMs: number;\n\n /** Callback when consensus is reached */\n onConsensus?: (identity: ObjectIdentity, parties: string[]) => void;\n\n /** Callback when consensus fails */\n onConsensusFailure?: (reason: string, parties: string[]) => void;\n}\n\n/**\n * Default escrow configuration.\n */\nexport const DEFAULT_ESCROW_CONFIG: EscrowConfig = {\n enabled: false,\n requiredParties: 2,\n timeoutMs: 60000,\n};\n\n/**\n * Security policy for Join operations.\n */\nexport interface JoinSecurityPolicy {\n /** Whether to verify identity hashes */\n verifyIdentityHashes: boolean;\n\n /** Whether to check for revoked objects */\n checkRevocation: boolean;\n\n /** Maximum depth for proxy resolution */\n maxProxyDepth: number;\n\n /** Whether to log all join operations */\n auditLog: boolean;\n\n /** Allowed vats for join operations (empty = all allowed) */\n allowedVats: Uint8Array[];\n}\n\n/**\n * Default join security policy.\n */\nexport const DEFAULT_JOIN_SECURITY_POLICY: JoinSecurityPolicy = {\n verifyIdentityHashes: true,\n checkRevocation: true,\n maxProxyDepth: 10,\n auditLog: true,\n allowedVats: [],\n};\n","/**\n * Level 4 RPC: Reference Equality / Join Operations\n *\n * This module implements the Level 4 RPC protocol for verifying that capability\n * references point to the same underlying object.\n *\n * Reference: https://capnproto.org/rpc.html (Level 4: Reference equality / joining)\n */\n\nimport type { ConnectionManager, VatId } from './connection-manager.js';\nimport type { Level3Handlers } from './level3-handlers.js';\nimport {\n type CachedJoinResult,\n DEFAULT_ESCROW_CONFIG,\n DEFAULT_JOIN_OPTIONS,\n DEFAULT_JOIN_SECURITY_POLICY,\n type EscrowConfig,\n type JoinOptions,\n type JoinResult,\n type JoinSecurityPolicy,\n type ObjectIdentity,\n type PendingJoin,\n} from './level4-types.js';\nimport type { RpcConnection } from './rpc-connection.js';\nimport type { Join, MessageTarget, QuestionId, RpcMessage } from './rpc-types.js';\n\n/** Options for Level4Handlers */\nexport interface Level4HandlersOptions {\n /** The connection this handler is attached to */\n connection: RpcConnection;\n\n /** The connection manager for multi-vat scenarios */\n connectionManager?: ConnectionManager;\n\n /** Level 3 handlers (required for proxy resolution) */\n level3Handlers?: Level3Handlers;\n\n /** This vat's ID */\n selfVatId?: VatId;\n\n /** Join operation options */\n joinOptions?: JoinOptions;\n\n /** Escrow agent configuration */\n escrowConfig?: EscrowConfig;\n\n /** Security policy */\n securityPolicy?: JoinSecurityPolicy;\n\n /** Handler for incoming Join messages */\n onJoin?: (join: Join) => Promise<JoinResult>;\n}\n\n/**\n * Manages Level 4 RPC message handling for reference equality verification.\n *\n * This class handles:\n * 1. Join messages - verifying that two capabilities point to the same object\n * 2. Object identity tracking and caching\n * 3. Escrow agent functionality for consensus verification\n * 4. Security verification (anti-spoofing)\n *\n * ## Usage Example\n *\n * ```typescript\n * const level4Handlers = new Level4Handlers({\n * connection,\n * connectionManager,\n * level3Handlers,\n * selfVatId,\n * });\n *\n * // Enable escrow mode for consensus verification\n * level4Handlers.setEscrowConfig({\n * enabled: true,\n * requiredParties: 2,\n * });\n *\n * // Send a Join request\n * const result = await level4Handlers.sendJoin(target1, target2);\n * if (result.equal) {\n * console.log('Capabilities point to the same object!');\n * }\n * ```\n */\nexport class Level4Handlers {\n private options: Level4HandlersOptions;\n private pendingJoins = new Map<number, PendingJoin>();\n private joinResultsCache = new Map<string, CachedJoinResult>();\n private objectIdentities = new Map<number, ObjectIdentity>();\n private nextJoinId = 1;\n private escrowConfig: EscrowConfig;\n private securityPolicy: JoinSecurityPolicy;\n private joinOptions: Required<JoinOptions>;\n\n // Escrow state\n private escrowParties = new Map<string, { target: unknown; identity?: ObjectIdentity }>();\n private escrowConsensus?: {\n identity: ObjectIdentity;\n parties: string[];\n };\n\n constructor(options: Level4HandlersOptions) {\n this.options = options;\n this.escrowConfig = { ...DEFAULT_ESCROW_CONFIG, ...options.escrowConfig };\n this.securityPolicy = { ...DEFAULT_JOIN_SECURITY_POLICY, ...options.securityPolicy };\n this.joinOptions = { ...DEFAULT_JOIN_OPTIONS, ...options.joinOptions };\n }\n\n // ========================================================================================\n // Join Message Handling\n // ========================================================================================\n\n /**\n * Handle an incoming Join message.\n *\n * When we receive a Join message, we need to verify whether the two\n * capability references point to the same underlying object.\n *\n * The verification process:\n * 1. Resolve both targets to their underlying objects\n * 2. Compare object identities (vat ID + object ID)\n * 3. Optionally verify identity hashes cryptographically\n * 4. Return the result\n */\n async handleJoin(join: Join): Promise<void> {\n const { questionId, target, otherCap, joinId } = join;\n\n try {\n // Check cache first\n const cacheKey = this.getCacheKey(target, otherCap);\n const cached = this.joinResultsCache.get(cacheKey);\n if (cached && Date.now() - cached.cachedAt < this.joinOptions.cacheTtlMs) {\n await this.sendJoinResult(questionId, cached.result);\n return;\n }\n\n // Resolve both targets to their identities\n const identity1 = await this.resolveTargetToIdentity(target);\n const identity2 = await this.resolveTargetToIdentity(otherCap);\n\n // Compare identities\n const result = this.compareIdentities(identity1, identity2, joinId);\n\n // Cache the result if enabled\n if (this.joinOptions.cacheResult) {\n this.joinResultsCache.set(cacheKey, {\n result,\n cachedAt: Date.now(),\n targets: [this.hashTarget(target), this.hashTarget(otherCap)],\n });\n }\n\n // Log for audit if enabled\n if (this.securityPolicy.auditLog) {\n this.logJoinOperation(target, otherCap, result);\n }\n\n // Send the result\n await this.sendJoinResult(questionId, result);\n\n // Call custom handler if provided\n if (this.options.onJoin) {\n await this.options.onJoin(join);\n }\n } catch (error) {\n // Send exception result\n await this.sendJoinException(\n questionId,\n error instanceof Error ? error.message : 'Join operation failed'\n );\n }\n }\n\n /**\n * Send a Join message to verify that two capabilities point to the same object.\n *\n * @param target1 First capability target\n * @param target2 Second capability target\n * @returns Promise resolving to the join result\n */\n async sendJoin(target1: MessageTarget, target2: MessageTarget): Promise<JoinResult> {\n const { connection } = this.options;\n const joinId = this.nextJoinId++;\n const questionId = connection.createQuestion();\n\n // Create pending join\n const pendingJoin: PendingJoin = {\n joinId,\n target1,\n target2,\n startedAt: Date.now(),\n resolve: () => {},\n reject: () => {},\n };\n\n const completionPromise = new Promise<JoinResult>((resolve, reject) => {\n pendingJoin.resolve = resolve;\n pendingJoin.reject = reject;\n });\n\n this.pendingJoins.set(joinId, pendingJoin);\n\n // Set timeout\n const timeoutMs = this.joinOptions.timeoutMs;\n const timeoutId = setTimeout(() => {\n this.pendingJoins.delete(joinId);\n pendingJoin.reject(new Error(`Join operation timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n\n // Override resolve to clear timeout\n const originalResolve = pendingJoin.resolve;\n pendingJoin.resolve = (result: JoinResult) => {\n clearTimeout(timeoutId);\n this.pendingJoins.delete(joinId);\n originalResolve(result);\n };\n\n try {\n const joinMsg: RpcMessage = {\n type: 'join',\n join: {\n questionId,\n target: target1,\n otherCap: target2,\n joinId,\n },\n };\n\n await connection.sendCall(joinMsg.join as any);\n\n // Wait for the result\n const result = await completionPromise;\n return result;\n } catch (error) {\n clearTimeout(timeoutId);\n this.pendingJoins.delete(joinId);\n throw error;\n }\n }\n\n /**\n * Complete a pending join operation with the result.\n * This is called when we receive a Return message for a Join.\n */\n completeJoin(joinId: number, result: JoinResult): void {\n const pending = this.pendingJoins.get(joinId);\n if (pending) {\n pending.resolve(result);\n this.pendingJoins.delete(joinId);\n }\n }\n\n // ========================================================================================\n // Object Identity Resolution\n // ========================================================================================\n\n /**\n * Resolve a MessageTarget to its ObjectIdentity.\n *\n * This may involve:\n * 1. Looking up local exports\n * 2. Resolving promises\n * 3. Following third-party capabilities\n * 4. Verifying proxy chains\n */\n private async resolveTargetToIdentity(target: MessageTarget): Promise<ObjectIdentity | null> {\n if (target.type === 'importedCap') {\n // Check if we have cached identity for this import\n const cached = this.objectIdentities.get(target.importId);\n if (cached) {\n return cached;\n }\n\n // Get the import and resolve its identity\n const importEntry = this.options.connection.getImport(target.importId);\n if (!importEntry) {\n return null;\n }\n\n // For local imports, we need to query the remote vat for identity\n // In a full implementation, this would involve a network call\n // For now, return a placeholder\n return null;\n }\n\n if (target.type === 'promisedAnswer') {\n // Wait for the promise to resolve\n const { questionId } = target.promisedAnswer;\n\n // Wait for the answer\n try {\n const _answer = await this.options.connection.waitForAnswer(questionId);\n // Extract capability from answer and resolve identity\n // This is simplified - full implementation would handle transforms\n return null;\n } catch {\n return null;\n }\n }\n\n return null;\n }\n\n /**\n * Compare two object identities for equality.\n */\n private compareIdentities(\n identity1: ObjectIdentity | null,\n identity2: ObjectIdentity | null,\n joinId: number\n ): JoinResult {\n // Both null = equal (both are null capabilities)\n if (!identity1 && !identity2) {\n return { equal: true, joinId };\n }\n\n // One null, one not = not equal\n if (!identity1 || !identity2) {\n return {\n equal: false,\n joinId,\n inequalityReason: 'One capability is null, the other is not',\n };\n }\n\n // Compare vat IDs\n if (!this.arraysEqual(identity1.vatId, identity2.vatId)) {\n return {\n equal: false,\n joinId,\n inequalityReason: 'Capabilities hosted by different vats',\n };\n }\n\n // Compare object IDs\n if (!this.arraysEqual(identity1.objectId, identity2.objectId)) {\n return {\n equal: false,\n joinId,\n inequalityReason: 'Different object IDs within the same vat',\n };\n }\n\n // Verify identity hashes if required\n if (this.securityPolicy.verifyIdentityHashes) {\n if (identity1.identityHash && identity2.identityHash) {\n if (!this.arraysEqual(identity1.identityHash, identity2.identityHash)) {\n return {\n equal: false,\n joinId,\n inequalityReason: 'Identity hash mismatch (possible spoofing attempt)',\n };\n }\n }\n }\n\n // All checks passed - identities are equal\n return {\n equal: true,\n joinId,\n identity: identity1,\n };\n }\n\n // ========================================================================================\n // Escrow Agent Functionality\n // ========================================================================================\n\n /**\n * Set the escrow configuration.\n */\n setEscrowConfig(config: Partial<EscrowConfig>): void {\n this.escrowConfig = { ...this.escrowConfig, ...config };\n }\n\n /**\n * Register a party in an escrow consensus verification.\n *\n * This is used when multiple parties need to verify they are referring\n * to the same object (e.g., in a trade or agreement).\n *\n * @param partyId Unique identifier for the party\n * @param target The capability reference from this party\n * @returns Whether consensus has been reached\n */\n async registerEscrowParty(\n partyId: string,\n target: unknown\n ): Promise<{ consensus: boolean; identity?: ObjectIdentity }> {\n if (!this.escrowConfig.enabled) {\n throw new Error('Escrow mode is not enabled');\n }\n\n // Check if party already registered\n if (this.escrowParties.has(partyId)) {\n throw new Error(`Party ${partyId} is already registered`);\n }\n\n // Register the party\n this.escrowParties.set(partyId, { target });\n\n // If we have enough parties, verify consensus\n if (this.escrowParties.size >= this.escrowConfig.requiredParties) {\n const consensus = await this.verifyEscrowConsensus();\n\n if (consensus.consensus) {\n this.escrowConsensus = {\n identity: consensus.identity!,\n parties: Array.from(this.escrowParties.keys()),\n };\n\n if (this.escrowConfig.onConsensus) {\n this.escrowConfig.onConsensus(consensus.identity!, Array.from(this.escrowParties.keys()));\n }\n } else {\n if (this.escrowConfig.onConsensusFailure) {\n this.escrowConfig.onConsensusFailure(\n consensus.reason!,\n Array.from(this.escrowParties.keys())\n );\n }\n }\n\n return { consensus: consensus.consensus, identity: consensus.identity };\n }\n\n return { consensus: false };\n }\n\n /**\n * Verify that all registered escrow parties refer to the same object.\n */\n private async verifyEscrowConsensus(): Promise<{\n consensus: boolean;\n identity?: ObjectIdentity;\n reason?: string;\n }> {\n const parties = Array.from(this.escrowParties.entries());\n\n if (parties.length < this.escrowConfig.requiredParties) {\n return { consensus: false, reason: 'Not enough parties registered' };\n }\n\n // Use the first party's target as the reference\n const [firstPartyId, firstParty] = parties[0];\n\n // Resolve first party's identity\n const firstIdentity = await this.resolveTargetToIdentity(firstParty.target as MessageTarget);\n if (!firstIdentity) {\n return { consensus: false, reason: `Could not resolve identity for party ${firstPartyId}` };\n }\n\n // Compare with all other parties\n for (const [partyId, party] of parties.slice(1)) {\n const identity = await this.resolveTargetToIdentity(party.target as MessageTarget);\n const comparison = this.compareIdentities(firstIdentity, identity, 0);\n\n if (!comparison.equal) {\n return {\n consensus: false,\n reason: `Party ${partyId} refers to a different object: ${comparison.inequalityReason}`,\n };\n }\n }\n\n // All parties refer to the same object\n return { consensus: true, identity: firstIdentity };\n }\n\n /**\n * Clear all escrow state.\n */\n clearEscrow(): void {\n this.escrowParties.clear();\n this.escrowConsensus = undefined;\n }\n\n /**\n * Get the current escrow consensus if reached.\n */\n getEscrowConsensus(): { identity: ObjectIdentity; parties: string[] } | undefined {\n return this.escrowConsensus;\n }\n\n // ========================================================================================\n // Security & Anti-Spoofing\n // ========================================================================================\n\n /**\n * Set the security policy.\n */\n setSecurityPolicy(policy: Partial<JoinSecurityPolicy>): void {\n this.securityPolicy = { ...this.securityPolicy, ...policy };\n }\n\n /**\n * Verify that a vat is allowed to participate in join operations.\n */\n private isVatAllowed(vatId: Uint8Array): boolean {\n if (this.securityPolicy.allowedVats.length === 0) {\n return true; // All vats allowed if no restrictions\n }\n\n return this.securityPolicy.allowedVats.some((allowed) => this.arraysEqual(allowed, vatId));\n }\n\n /**\n * Generate a cryptographic identity hash for an object.\n *\n * This creates a verifiable fingerprint of the object's identity\n * that can be used to detect spoofing attempts.\n */\n async generateIdentityHash(vatId: Uint8Array, objectId: Uint8Array): Promise<Uint8Array> {\n // Combine vat ID and object ID\n const combined = new Uint8Array(vatId.length + objectId.length);\n combined.set(vatId, 0);\n combined.set(objectId, vatId.length);\n\n // Use SubtleCrypto for hashing if available\n if (typeof crypto !== 'undefined' && crypto.subtle) {\n const hashBuffer = await crypto.subtle.digest('SHA-256', combined);\n return new Uint8Array(hashBuffer);\n }\n\n // Fallback: simple hash for Node.js\n const { createHash } = require('node:crypto');\n const hash = createHash('sha256');\n hash.update(combined);\n return hash.digest();\n }\n\n // ========================================================================================\n // Caching & Cleanup\n // ========================================================================================\n\n /**\n * Clear the join results cache.\n */\n clearCache(): void {\n this.joinResultsCache.clear();\n }\n\n /**\n * Clean up expired cache entries.\n */\n cleanupExpiredCache(): number {\n const now = Date.now();\n let removed = 0;\n\n for (const [key, entry] of this.joinResultsCache) {\n if (now - entry.cachedAt > this.joinOptions.cacheTtlMs) {\n this.joinResultsCache.delete(key);\n removed++;\n }\n }\n\n return removed;\n }\n\n /**\n * Get cache statistics.\n */\n getCacheStats(): { size: number; hitRate: number } {\n return {\n size: this.joinResultsCache.size,\n hitRate: 0, // Would need to track hits/misses\n };\n }\n\n // ========================================================================================\n // Helper Methods\n // ========================================================================================\n\n private getCacheKey(target1: MessageTarget, target2: MessageTarget): string {\n // Create a consistent cache key regardless of order\n const hash1 = this.hashTarget(target1);\n const hash2 = this.hashTarget(target2);\n\n // Sort to ensure (A,B) and (B,A) have the same key\n const sorted = [hash1, hash2].sort();\n return `join:${sorted[0]}:${sorted[1]}`;\n }\n\n private hashTarget(target: MessageTarget): string {\n if (target.type === 'importedCap') {\n return `import:${target.importId}`;\n }\n if (target.type === 'promisedAnswer') {\n return `answer:${target.promisedAnswer.questionId}`;\n }\n return 'unknown';\n }\n\n private arraysEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n }\n\n private async sendJoinResult(questionId: QuestionId, result: JoinResult): Promise<void> {\n const { connection } = this.options;\n\n const returnMsg: RpcMessage = {\n type: 'return',\n return: {\n answerId: questionId,\n releaseParamCaps: true,\n noFinishNeeded: false,\n result: {\n type: 'results',\n payload: {\n content: this.serializeJoinResult(result),\n capTable: [],\n },\n },\n },\n };\n\n // @ts-ignore - accessing internal method\n await connection.sendReturn(returnMsg.return);\n }\n\n private async sendJoinException(questionId: QuestionId, reason: string): Promise<void> {\n const { connection } = this.options;\n\n const returnMsg: RpcMessage = {\n type: 'return',\n return: {\n answerId: questionId,\n releaseParamCaps: true,\n noFinishNeeded: false,\n result: {\n type: 'exception',\n exception: {\n reason,\n type: 'failed',\n },\n },\n },\n };\n\n // @ts-ignore - accessing internal method\n await connection.sendReturn(returnMsg.return);\n }\n\n private serializeJoinResult(result: JoinResult): Uint8Array {\n // Simple serialization - in production, use proper Cap'n Proto encoding\n const obj = {\n equal: result.equal,\n joinId: result.joinId,\n inequalityReason: result.inequalityReason,\n };\n return new TextEncoder().encode(JSON.stringify(obj));\n }\n\n private logJoinOperation(\n target1: MessageTarget,\n target2: MessageTarget,\n result: JoinResult\n ): void {\n console.log('[Level4] Join operation:', {\n target1: this.hashTarget(target1),\n target2: this.hashTarget(target2),\n equal: result.equal,\n joinId: result.joinId,\n timestamp: new Date().toISOString(),\n });\n }\n}\n\n// Re-export types\nexport type {\n JoinOptions,\n ObjectIdentity,\n PendingJoin,\n CachedJoinResult,\n EscrowConfig,\n JoinSecurityPolicy,\n} from './level4-types.js';\nexport {\n DEFAULT_JOIN_OPTIONS,\n DEFAULT_ESCROW_CONFIG,\n DEFAULT_JOIN_SECURITY_POLICY,\n} from './level4-types.js';\n","/**\n * Stream Abstraction for Cap'n Proto RPC\n *\n * Phase 5: Flow Control and Realtime Communication\n *\n * Provides Stream interface for bidirectional streaming with:\n * - Backpressure handling\n * - Flow control window management\n * - Chunked transfer\n * - Progress notifications\n */\n\nimport type { RpcMessage } from './rpc-types.js';\nimport type { RpcTransport } from './transport.js';\n\n/** Stream state */\nexport type StreamState = 'connecting' | 'open' | 'closing' | 'closed' | 'error';\n\n/** Stream direction */\nexport type StreamDirection = 'inbound' | 'outbound' | 'bidirectional';\n\n/** Stream priority levels */\nexport enum StreamPriority {\n CRITICAL = 0, // Must not drop, immediate delivery\n HIGH = 1, // High priority, minimal delay\n NORMAL = 2, // Normal priority (default)\n LOW = 3, // Low priority, can be delayed\n BACKGROUND = 4, // Background tasks, lowest priority\n}\n\n/** Flow control window configuration */\nexport interface FlowControlConfig {\n /** Initial window size in bytes */\n initialWindowSize: number;\n /** Maximum window size in bytes */\n maxWindowSize: number;\n /** Minimum window size before backpressure */\n minWindowSize: number;\n /** Window update threshold (update when window drops below this) */\n windowUpdateThreshold: number;\n /** Window update increment size */\n windowUpdateIncrement: number;\n}\n\n/** Default flow control configuration */\nexport const DEFAULT_FLOW_CONTROL: FlowControlConfig = {\n initialWindowSize: 65536, // 64KB\n maxWindowSize: 1048576, // 1MB\n minWindowSize: 4096, // 4KB\n windowUpdateThreshold: 16384, // 16KB\n windowUpdateIncrement: 32768, // 32KB\n};\n\n/** Stream configuration options */\nexport interface StreamOptions {\n /** Stream ID (unique within connection) */\n streamId: number;\n /** Stream direction */\n direction: StreamDirection;\n /** Stream priority */\n priority?: StreamPriority;\n /** Flow control configuration */\n flowControl?: Partial<FlowControlConfig>;\n /** Enable progress notifications */\n enableProgress?: boolean;\n /** Progress notification interval in bytes */\n progressInterval?: number;\n /** Stream metadata */\n metadata?: Record<string, string>;\n}\n\n/** Chunk of data in a stream */\nexport interface StreamChunk {\n /** Chunk data */\n data: Uint8Array;\n /** Whether this is the final chunk */\n endOfStream?: boolean;\n /** Chunk sequence number (for ordering) */\n sequenceNumber?: number;\n /** Timestamp when chunk was sent */\n timestamp?: number;\n}\n\n/** Progress notification */\nexport interface StreamProgress {\n /** Stream ID */\n streamId: number;\n /** Total bytes sent/received */\n bytesTransferred: number;\n /** Total bytes expected (if known) */\n totalBytes?: number;\n /** Progress percentage (0-100) */\n percentage?: number;\n /** Transfer rate in bytes per second */\n transferRate?: number;\n /** Estimated time remaining in milliseconds */\n estimatedTimeRemaining?: number;\n}\n\n/** Flow control window state */\ninterface FlowControlWindow {\n /** Current window size */\n currentSize: number;\n /** Maximum window size */\n maxSize: number;\n /** Bytes sent/received in current window */\n bytesInWindow: number;\n /** Whether backpressure is active */\n backpressureActive: boolean;\n}\n\n/** Stream event handlers */\nexport interface StreamEventHandlers {\n /** Called when data is received */\n onData?: (chunk: StreamChunk) => void | Promise<void>;\n /** Called when stream is opened */\n onOpen?: () => void;\n /** Called when stream is closed */\n onClose?: () => void;\n /** Called when progress updates */\n onProgress?: (progress: StreamProgress) => void;\n /** Called when backpressure state changes */\n onBackpressure?: (active: boolean) => void;\n /** Called when an error occurs */\n onError?: (error: Error) => void;\n}\n\n/**\n * Stream abstraction for Cap'n Proto RPC\n *\n * Manages bidirectional streaming with flow control and backpressure.\n */\nexport class Stream {\n private options: StreamOptions;\n private handlers: StreamEventHandlers;\n private state: StreamState = 'connecting';\n private error?: Error;\n\n // Flow control\n private sendWindow: FlowControlWindow;\n private receiveWindow: FlowControlWindow;\n private flowControlConfig: FlowControlConfig;\n\n // Data buffering\n private sendBuffer: StreamChunk[] = [];\n private receiveBuffer: StreamChunk[] = [];\n private maxBufferSize = 1048576; // 1MB max buffer\n\n // Progress tracking\n private bytesSent = 0;\n private bytesReceived = 0;\n private totalBytesExpected?: number;\n private lastProgressUpdate = 0;\n private progressUpdateInterval: number;\n private transferStartTime?: number;\n\n // Chunk sequencing\n private nextSendSequence = 0;\n private nextExpectedSequence = 0;\n\n // Promise resolvers for async operations\n private openResolver?: () => void;\n private openRejector?: (error: Error) => void;\n private closeResolver?: () => void;\n\n constructor(options: StreamOptions, handlers: StreamEventHandlers = {}) {\n this.options = options;\n this.handlers = handlers;\n\n // Initialize flow control\n this.flowControlConfig = {\n ...DEFAULT_FLOW_CONTROL,\n ...options.flowControl,\n };\n\n this.sendWindow = {\n currentSize: this.flowControlConfig.initialWindowSize,\n maxSize: this.flowControlConfig.maxWindowSize,\n bytesInWindow: 0,\n backpressureActive: false,\n };\n\n this.receiveWindow = {\n currentSize: this.flowControlConfig.initialWindowSize,\n maxSize: this.flowControlConfig.maxWindowSize,\n bytesInWindow: 0,\n backpressureActive: false,\n };\n\n this.progressUpdateInterval = options.progressInterval ?? 65536; // 64KB default\n }\n\n /** Get stream ID */\n get id(): number {\n return this.options.streamId;\n }\n\n /** Get stream direction */\n get direction(): StreamDirection {\n return this.options.direction;\n }\n\n /** Get stream priority */\n get priority(): StreamPriority {\n return this.options.priority ?? StreamPriority.NORMAL;\n }\n\n /** Get current stream state */\n get currentState(): StreamState {\n return this.state;\n }\n\n /** Get whether stream is open */\n get isOpen(): boolean {\n return this.state === 'open';\n }\n\n /** Get whether backpressure is active for sending */\n get isBackpressureActive(): boolean {\n return this.sendWindow.backpressureActive;\n }\n\n /** Get bytes sent */\n get bytesSentCount(): number {\n return this.bytesSent;\n }\n\n /** Get bytes received */\n get bytesReceivedCount(): number {\n return this.bytesReceived;\n }\n\n /** Get metadata */\n get metadata(): Record<string, string> | undefined {\n return this.options.metadata;\n }\n\n /**\n * Open the stream\n */\n async open(): Promise<void> {\n if (this.state !== 'connecting') {\n throw new Error(`Cannot open stream in state: ${this.state}`);\n }\n\n return new Promise((resolve, reject) => {\n this.openResolver = resolve;\n this.openRejector = reject;\n\n // Transition to open state\n this.transitionState('open');\n this.transferStartTime = Date.now();\n\n // Notify handlers\n this.handlers.onOpen?.();\n });\n }\n\n /**\n * Send data through the stream\n *\n * Respects flow control and handles backpressure.\n */\n async send(data: Uint8Array, endOfStream = false): Promise<void> {\n if (this.state !== 'open') {\n throw new Error(`Cannot send in state: ${this.state}`);\n }\n\n // Check if we need to wait for window update\n if (this.sendWindow.bytesInWindow + data.length > this.sendWindow.currentSize) {\n // Wait for window update\n await this.waitForWindowUpdate();\n }\n\n // Create chunk\n const chunk: StreamChunk = {\n data,\n endOfStream,\n sequenceNumber: this.nextSendSequence++,\n timestamp: Date.now(),\n };\n\n // Update flow control\n this.sendWindow.bytesInWindow += data.length;\n this.bytesSent += data.length;\n\n // Check for backpressure\n this.checkBackpressure();\n\n // Send the chunk\n await this.sendChunk(chunk);\n\n // Report progress\n this.reportProgress();\n }\n\n /**\n * Send a chunk of data\n *\n * Override in subclasses to implement actual transport.\n */\n protected async sendChunk(chunk: StreamChunk): Promise<void> {\n // To be implemented by transport-specific subclass\n // This base class just buffers\n this.sendBuffer.push(chunk);\n }\n\n /**\n * Receive data from the stream\n *\n * Returns buffered data or waits for new data.\n */\n async receive(): Promise<StreamChunk | null> {\n if (this.receiveBuffer.length > 0) {\n return this.receiveBuffer.shift()!;\n }\n\n if (this.state === 'closed') {\n return null;\n }\n\n // Wait for data\n return new Promise((resolve, reject) => {\n const checkBuffer = () => {\n if (this.receiveBuffer.length > 0) {\n resolve(this.receiveBuffer.shift()!);\n } else if (this.state === 'closed') {\n resolve(null);\n } else if (this.state === 'error') {\n reject(this.error ?? new Error('Stream error'));\n } else {\n setTimeout(checkBuffer, 10);\n }\n };\n checkBuffer();\n });\n }\n\n /**\n * Handle incoming chunk from transport\n */\n handleIncomingChunk(chunk: StreamChunk): void {\n if (this.state !== 'open' && this.state !== 'closing') {\n return;\n }\n\n // Update receive window\n this.receiveWindow.bytesInWindow += chunk.data.length;\n this.bytesReceived += chunk.data.length;\n\n // Check if we need to send window update\n this.checkReceiveWindow();\n\n // Buffer or deliver chunk\n if (this.handlers.onData) {\n // Deliver immediately if handler is registered\n Promise.resolve(this.handlers.onData(chunk)).catch((err) => {\n this.handleError(err);\n });\n } else {\n // Buffer for later\n this.receiveBuffer.push(chunk);\n }\n\n // Report progress\n this.reportProgress();\n\n // Handle end of stream\n if (chunk.endOfStream) {\n this.transitionState('closing');\n }\n }\n\n /**\n * Update the send window (called when receiving window update from peer)\n */\n updateSendWindow(increment: number): void {\n this.sendWindow.currentSize = Math.min(\n this.sendWindow.currentSize + increment,\n this.sendWindow.maxSize\n );\n\n // Check if we can release backpressure\n if (this.sendWindow.backpressureActive) {\n const available = this.sendWindow.currentSize - this.sendWindow.bytesInWindow;\n if (available >= this.flowControlConfig.minWindowSize) {\n this.sendWindow.backpressureActive = false;\n this.handlers.onBackpressure?.(false);\n }\n }\n }\n\n /**\n * Acknowledge received bytes (called to update peer's send window)\n */\n acknowledgeBytes(bytes: number): void {\n this.receiveWindow.bytesInWindow = Math.max(0, this.receiveWindow.bytesInWindow - bytes);\n\n // Check if we should send window update\n if (this.receiveWindow.bytesInWindow < this.flowControlConfig.windowUpdateThreshold) {\n this.sendWindowUpdate();\n }\n }\n\n /**\n * Close the stream gracefully\n */\n async close(): Promise<void> {\n if (this.state === 'closed' || this.state === 'closing') {\n return;\n }\n\n this.transitionState('closing');\n\n // Wait for any pending sends to complete\n await this.drainSendBuffer();\n\n // Send end-of-stream marker\n await this.sendChunk({ data: new Uint8Array(0), endOfStream: true });\n\n this.transitionState('closed');\n this.handlers.onClose?.();\n }\n\n /**\n * Abort the stream with an error\n */\n abort(error: Error): void {\n this.error = error;\n this.transitionState('error');\n this.handlers.onError?.(error);\n }\n\n /**\n * Set total bytes expected (for progress calculation)\n */\n setTotalBytesExpected(total: number): void {\n this.totalBytesExpected = total;\n }\n\n /**\n * Wait for the stream to be ready for sending\n */\n async ready(): Promise<void> {\n if (this.state === 'open' && !this.sendWindow.backpressureActive) {\n return;\n }\n\n if (this.state !== 'open') {\n throw new Error(`Stream not open: ${this.state}`);\n }\n\n return this.waitForWindowUpdate();\n }\n\n // =============================================================================\n // Private Methods\n // =============================================================================\n\n private transitionState(newState: StreamState): void {\n const _oldState = this.state;\n this.state = newState;\n\n // Resolve/reject pending promises\n if (newState === 'open' && this.openResolver) {\n this.openResolver();\n this.openResolver = undefined;\n this.openRejector = undefined;\n } else if (newState === 'error' && this.openRejector) {\n this.openRejector(this.error ?? new Error('Stream error'));\n this.openResolver = undefined;\n this.openRejector = undefined;\n }\n\n if (newState === 'closed' && this.closeResolver) {\n this.closeResolver();\n this.closeResolver = undefined;\n }\n }\n\n private checkBackpressure(): void {\n const available = this.sendWindow.currentSize - this.sendWindow.bytesInWindow;\n\n if (available < this.flowControlConfig.minWindowSize && !this.sendWindow.backpressureActive) {\n this.sendWindow.backpressureActive = true;\n this.handlers.onBackpressure?.(true);\n }\n }\n\n private checkReceiveWindow(): void {\n if (this.receiveWindow.bytesInWindow < this.flowControlConfig.windowUpdateThreshold) {\n this.sendWindowUpdate();\n }\n }\n\n private async waitForWindowUpdate(): Promise<void> {\n return new Promise((resolve, reject) => {\n const checkWindow = () => {\n const available = this.sendWindow.currentSize - this.sendWindow.bytesInWindow;\n\n if (this.state === 'error') {\n reject(this.error ?? new Error('Stream error'));\n return;\n }\n\n if (this.state !== 'open') {\n reject(new Error('Stream closed'));\n return;\n }\n\n if (available >= this.flowControlConfig.minWindowSize) {\n resolve();\n return;\n }\n\n setTimeout(checkWindow, 10);\n };\n\n checkWindow();\n });\n }\n\n private async drainSendBuffer(): Promise<void> {\n // In the base Stream class, sendBuffer is just for buffering\n // Subclasses that actually send data should override this\n // For now, just clear the buffer\n this.sendBuffer.length = 0;\n }\n\n private sendWindowUpdate(): void {\n // To be implemented by transport layer\n // This would send a window update message to the peer\n }\n\n private reportProgress(): void {\n if (!this.options.enableProgress || !this.handlers.onProgress) {\n return;\n }\n\n const now = Date.now();\n const bytesTransferred = Math.max(this.bytesSent, this.bytesReceived);\n\n // Check if it's time to report progress\n if (bytesTransferred - this.lastProgressUpdate < this.progressUpdateInterval) {\n return;\n }\n\n this.lastProgressUpdate = bytesTransferred;\n\n // Calculate transfer rate\n let transferRate: number | undefined;\n if (this.transferStartTime) {\n const elapsed = (now - this.transferStartTime) / 1000;\n if (elapsed > 0) {\n transferRate = bytesTransferred / elapsed;\n }\n }\n\n // Calculate percentage and ETA\n let percentage: number | undefined;\n let estimatedTimeRemaining: number | undefined;\n\n if (this.totalBytesExpected && this.totalBytesExpected > 0) {\n percentage = Math.min(100, (bytesTransferred / this.totalBytesExpected) * 100);\n\n if (transferRate && transferRate > 0) {\n const remaining = this.totalBytesExpected - bytesTransferred;\n estimatedTimeRemaining = (remaining / transferRate) * 1000;\n }\n }\n\n const progress: StreamProgress = {\n streamId: this.id,\n bytesTransferred,\n totalBytes: this.totalBytesExpected,\n percentage,\n transferRate,\n estimatedTimeRemaining,\n };\n\n this.handlers.onProgress(progress);\n }\n\n private handleError(error: Error): void {\n this.error = error;\n this.transitionState('error');\n this.handlers.onError?.(error);\n }\n}\n\n/**\n * Create a new stream\n */\nexport function createStream(options: StreamOptions, handlers?: StreamEventHandlers): Stream {\n return new Stream(options, handlers);\n}\n\n/**\n * Check if an object is a Stream\n */\nexport function isStream(obj: unknown): obj is Stream {\n return obj instanceof Stream;\n}\n","/**\n * Bulk API - High-volume data transfer with flow control\n *\n * Phase 5: Flow Control and Realtime Communication\n *\n * Features:\n * - Backpressure mechanism\n * - Flow control window management\n * - Chunked transfer\n * - Progress notifications\n */\n\nimport type { RpcConnection } from './rpc-connection.js';\nimport {\n DEFAULT_FLOW_CONTROL,\n type FlowControlConfig,\n Stream,\n type StreamChunk,\n type StreamEventHandlers,\n type StreamOptions,\n StreamPriority,\n type StreamProgress,\n} from './stream.js';\n\n/** Bulk transfer configuration */\nexport interface BulkTransferConfig {\n /** Chunk size for transfer */\n chunkSize: number;\n /** Flow control configuration */\n flowControl?: Partial<FlowControlConfig>;\n /** Enable progress notifications */\n enableProgress?: boolean;\n /** Progress notification interval in bytes */\n progressInterval?: number;\n /** Maximum concurrent chunks in flight */\n maxConcurrentChunks?: number;\n /** Timeout for chunk acknowledgment */\n chunkAckTimeoutMs?: number;\n}\n\n/** Default bulk transfer configuration */\nexport const DEFAULT_BULK_CONFIG: BulkTransferConfig = {\n chunkSize: 16384, // 16KB chunks\n enableProgress: true,\n progressInterval: 65536, // 64KB\n maxConcurrentChunks: 8, // 8 concurrent chunks\n chunkAckTimeoutMs: 30000, // 30 seconds\n};\n\n/** Bulk transfer state */\nexport type BulkTransferState =\n | 'pending'\n | 'transferring'\n | 'paused'\n | 'completed'\n | 'cancelled'\n | 'error';\n\n/** Bulk transfer direction */\nexport type BulkTransferDirection = 'upload' | 'download';\n\n/** Bulk transfer metadata */\nexport interface BulkTransferMetadata {\n /** Transfer ID */\n id: string;\n /** File or resource name */\n name?: string;\n /** Total size in bytes (if known) */\n totalSize?: number;\n /** MIME type */\n contentType?: string;\n /** Custom metadata */\n custom?: Record<string, string>;\n}\n\n/** Bulk transfer statistics */\nexport interface BulkTransferStats {\n /** Bytes transferred */\n bytesTransferred: number;\n /** Total bytes (if known) */\n totalBytes?: number;\n /** Transfer rate in bytes per second */\n transferRate: number;\n /** Time elapsed in milliseconds */\n elapsedTime: number;\n /** Estimated time remaining in milliseconds */\n estimatedTimeRemaining?: number;\n /** Number of chunks transferred */\n chunksTransferred: number;\n /** Number of chunks acknowledged */\n chunksAcknowledged: number;\n /** Current window size */\n currentWindowSize: number;\n /** Whether backpressure is active */\n backpressureActive: boolean;\n}\n\n/** Chunk acknowledgment */\ninterface ChunkAck {\n sequenceNumber: number;\n bytesAcknowledged: number;\n}\n\n/** Bulk transfer event handlers */\nexport interface BulkTransferHandlers {\n /** Called when transfer starts */\n onStart?: () => void;\n /** Called when progress updates */\n onProgress?: (progress: StreamProgress) => void;\n /** Called when backpressure state changes */\n onBackpressure?: (active: boolean) => void;\n /** Called when transfer completes */\n onComplete?: () => void;\n /** Called when transfer is cancelled */\n onCancel?: () => void;\n /** Called when an error occurs */\n onError?: (error: Error) => void;\n}\n\n/**\n * Bulk transfer manager\n *\n * Manages high-volume data transfers with flow control and backpressure.\n */\nexport class BulkTransfer {\n private stream: Stream;\n private config: BulkTransferConfig;\n private handlers: BulkTransferHandlers;\n private metadata: BulkTransferMetadata;\n private direction: BulkTransferDirection;\n\n // State\n private state: BulkTransferState = 'pending';\n private error?: Error;\n\n // Transfer tracking\n private chunksInFlight = 0;\n private chunksAcknowledged = 0;\n private totalChunks = 0;\n private startTime?: number;\n private endTime?: number;\n\n // Chunk tracking\n private pendingChunks: Map<\n number,\n { chunk: StreamChunk; timeout: ReturnType<typeof setTimeout> }\n > = new Map();\n private chunkAckCallbacks: Map<number, () => void> = new Map();\n\n // Flow control\n private currentWindowSize: number;\n\n // Data source/sink\n private dataSource?: AsyncIterable<Uint8Array> | (() => Promise<Uint8Array | null>);\n private dataSink?: (chunk: Uint8Array) => Promise<void>;\n\n constructor(\n stream: Stream,\n direction: BulkTransferDirection,\n metadata: BulkTransferMetadata,\n config: Partial<BulkTransferConfig> = {},\n handlers: BulkTransferHandlers = {}\n ) {\n this.stream = stream;\n this.direction = direction;\n this.metadata = metadata;\n this.config = { ...DEFAULT_BULK_CONFIG, ...config };\n this.handlers = handlers;\n this.currentWindowSize =\n this.config.flowControl?.initialWindowSize ?? DEFAULT_FLOW_CONTROL.initialWindowSize;\n\n // Set up stream event handlers\n this.setupStreamHandlers();\n }\n\n /** Get transfer ID */\n get id(): string {\n return this.metadata.id;\n }\n\n /** Get current state */\n get currentState(): BulkTransferState {\n return this.state;\n }\n\n /** Get transfer statistics */\n get stats(): BulkTransferStats {\n const now = Date.now();\n const elapsed = this.startTime ? (this.endTime ?? now) - this.startTime : 0;\n const bytesTransferred = this.stream.bytesSentCount + this.stream.bytesReceivedCount;\n\n let transferRate = 0;\n if (elapsed > 0) {\n transferRate = (bytesTransferred / elapsed) * 1000;\n }\n\n let estimatedTimeRemaining: number | undefined;\n if (this.metadata.totalSize && transferRate > 0) {\n const remaining = this.metadata.totalSize - bytesTransferred;\n estimatedTimeRemaining = (remaining / transferRate) * 1000;\n }\n\n return {\n bytesTransferred,\n totalBytes: this.metadata.totalSize,\n transferRate,\n elapsedTime: elapsed,\n estimatedTimeRemaining,\n chunksTransferred: this.chunksAcknowledged + this.pendingChunks.size,\n chunksAcknowledged: this.chunksAcknowledged,\n currentWindowSize: this.currentWindowSize,\n backpressureActive: this.stream.isBackpressureActive,\n };\n }\n\n /**\n * Set the data source for upload\n */\n setDataSource(source: AsyncIterable<Uint8Array> | (() => Promise<Uint8Array | null>)): void {\n if (this.direction !== 'upload') {\n throw new Error('Data source only valid for uploads');\n }\n this.dataSource = source;\n }\n\n /**\n * Set the data sink for download\n */\n setDataSink(sink: (chunk: Uint8Array) => Promise<void>): void {\n if (this.direction !== 'download') {\n throw new Error('Data sink only valid for downloads');\n }\n this.dataSink = sink;\n }\n\n /**\n * Start the bulk transfer\n */\n async start(): Promise<void> {\n if (this.state !== 'pending') {\n throw new Error(`Cannot start transfer in state: ${this.state}`);\n }\n\n this.state = 'transferring';\n this.startTime = Date.now();\n this.handlers.onStart?.();\n\n // Set total size for progress tracking\n if (this.metadata.totalSize) {\n this.stream.setTotalBytesExpected(this.metadata.totalSize);\n }\n\n try {\n if (this.direction === 'upload') {\n await this.performUpload();\n } else {\n await this.performDownload();\n }\n\n if (this.state === 'transferring') {\n this.state = 'completed';\n this.endTime = Date.now();\n this.handlers.onComplete?.();\n }\n } catch (err) {\n this.handleError(err as Error);\n }\n }\n\n /**\n * Pause the transfer\n */\n pause(): void {\n if (this.state === 'transferring') {\n this.state = 'paused';\n }\n }\n\n /**\n * Resume the transfer\n */\n resume(): void {\n if (this.state === 'paused') {\n this.state = 'transferring';\n }\n }\n\n /**\n * Cancel the transfer\n */\n cancel(): void {\n if (this.state === 'completed' || this.state === 'error' || this.state === 'cancelled') {\n return;\n }\n\n this.state = 'cancelled';\n this.endTime = Date.now();\n\n // Clear pending timeouts\n for (const { timeout } of this.pendingChunks.values()) {\n clearTimeout(timeout);\n }\n this.pendingChunks.clear();\n\n this.handlers.onCancel?.();\n }\n\n /**\n * Handle chunk acknowledgment from peer\n */\n handleChunkAck(ack: ChunkAck): void {\n const pending = this.pendingChunks.get(ack.sequenceNumber);\n if (pending) {\n clearTimeout(pending.timeout);\n this.pendingChunks.delete(ack.sequenceNumber);\n this.chunksAcknowledged++;\n this.chunksInFlight--;\n\n // Update window size\n this.currentWindowSize += ack.bytesAcknowledged;\n\n // Resolve pending ack callback\n const callback = this.chunkAckCallbacks.get(ack.sequenceNumber);\n if (callback) {\n callback();\n this.chunkAckCallbacks.delete(ack.sequenceNumber);\n }\n }\n }\n\n /**\n * Update flow control window\n */\n updateWindow(newWindowSize: number): void {\n this.currentWindowSize = newWindowSize;\n this.stream.updateSendWindow(newWindowSize);\n }\n\n // =============================================================================\n // Private Methods\n // =============================================================================\n\n private setupStreamHandlers(): void {\n const _streamHandlers: StreamEventHandlers = {\n onData: async (chunk) => {\n // Handle incoming data for downloads\n if (this.direction === 'download' && this.dataSink) {\n await this.dataSink(chunk.data);\n\n // Send acknowledgment\n await this.sendChunkAck(chunk.sequenceNumber ?? 0, chunk.data.length);\n }\n },\n onBackpressure: (active) => {\n this.handlers.onBackpressure?.(active);\n },\n onProgress: (progress) => {\n this.handlers.onProgress?.(progress);\n },\n onError: (error) => {\n this.handleError(error);\n },\n };\n\n // Note: Stream handlers are set during construction\n // This is a simplified implementation\n }\n\n private async performUpload(): Promise<void> {\n if (!this.dataSource) {\n throw new Error('No data source set for upload');\n }\n\n if (Symbol.asyncIterator in this.dataSource) {\n // AsyncIterable source\n for await (const data of this.dataSource as AsyncIterable<Uint8Array>) {\n if (this.state !== 'transferring') {\n break;\n }\n\n await this.sendChunkWithFlowControl(data);\n }\n } else {\n // Function source\n const sourceFn = this.dataSource as () => Promise<Uint8Array | null>;\n while (this.state === 'transferring') {\n const data = await sourceFn();\n if (!data || data.length === 0) {\n break;\n }\n\n await this.sendChunkWithFlowControl(data);\n }\n }\n\n // Wait for all chunks to be acknowledged\n await this.waitForAllAcks();\n }\n\n private async performDownload(): Promise<void> {\n if (!this.dataSink) {\n throw new Error('No data sink set for download');\n }\n\n // Download is handled by onData callback\n // Just wait for completion\n while (this.state === 'transferring') {\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n }\n\n private async sendChunkWithFlowControl(data: Uint8Array): Promise<void> {\n // Wait for available window\n while (this.chunksInFlight >= (this.config.maxConcurrentChunks ?? 8)) {\n if (this.state !== 'transferring') {\n return;\n }\n await new Promise((resolve) => setTimeout(resolve, 10));\n }\n\n // Wait for stream to be ready (backpressure)\n await this.stream.ready();\n\n const sequenceNumber = this.totalChunks++;\n\n // Send the chunk\n await this.stream.send(data, false);\n this.chunksInFlight++;\n\n // Set up acknowledgment timeout\n const timeout = setTimeout(() => {\n this.handleChunkTimeout(sequenceNumber);\n }, this.config.chunkAckTimeoutMs ?? 30000);\n\n this.pendingChunks.set(sequenceNumber, {\n chunk: { data, sequenceNumber, timestamp: Date.now() },\n timeout,\n });\n }\n\n private async sendChunkAck(_sequenceNumber: number, _bytes: number): Promise<void> {\n // Send acknowledgment to peer\n // This would be implemented via the RPC connection\n }\n\n private handleChunkTimeout(sequenceNumber: number): void {\n const pending = this.pendingChunks.get(sequenceNumber);\n if (pending) {\n this.pendingChunks.delete(sequenceNumber);\n this.chunksInFlight--;\n\n // Could implement retry logic here\n this.handleError(new Error(`Chunk ${sequenceNumber} acknowledgment timeout`));\n }\n }\n\n private async waitForAllAcks(): Promise<void> {\n // In a real implementation, we would wait for acknowledgments from the peer\n // For now, just clear pending chunks immediately (simulating immediate ack)\n // This allows the transfer to complete without actual network acknowledgments\n for (const [sequenceNumber, { timeout }] of this.pendingChunks) {\n clearTimeout(timeout);\n this.handleChunkAck({\n sequenceNumber,\n bytesAcknowledged: 0, // Unknown, but doesn't matter for completion\n });\n }\n this.pendingChunks.clear();\n }\n\n private handleError(error: Error): void {\n if (this.state === 'completed' || this.state === 'error') {\n return;\n }\n\n this.error = error;\n this.state = 'error';\n this.endTime = Date.now();\n\n // Clear pending timeouts\n for (const { timeout } of this.pendingChunks.values()) {\n clearTimeout(timeout);\n }\n\n this.handlers.onError?.(error);\n }\n}\n\n/**\n * Bulk transfer manager\n *\n * Manages multiple concurrent bulk transfers.\n */\nexport class BulkTransferManager {\n private transfers: Map<string, BulkTransfer> = new Map();\n private streams: Map<number, Stream> = new Map();\n private nextStreamId = 1;\n\n /**\n * Create a new bulk transfer\n */\n createTransfer(\n direction: BulkTransferDirection,\n metadata: BulkTransferMetadata,\n config?: Partial<BulkTransferConfig>,\n handlers?: BulkTransferHandlers\n ): BulkTransfer {\n const streamId = this.nextStreamId++;\n\n const streamOptions: StreamOptions = {\n streamId,\n direction: direction === 'upload' ? 'outbound' : 'inbound',\n priority: StreamPriority.NORMAL,\n enableProgress: config?.enableProgress ?? true,\n progressInterval: config?.progressInterval,\n flowControl: config?.flowControl,\n };\n\n const stream = new Stream(streamOptions, {\n onProgress: handlers?.onProgress,\n onBackpressure: handlers?.onBackpressure,\n onError: handlers?.onError,\n });\n\n this.streams.set(streamId, stream);\n\n const transfer = new BulkTransfer(stream, direction, metadata, config, handlers);\n this.transfers.set(metadata.id, transfer);\n\n return transfer;\n }\n\n /**\n * Get a transfer by ID\n */\n getTransfer(id: string): BulkTransfer | undefined {\n return this.transfers.get(id);\n }\n\n /**\n * Get a stream by ID\n */\n getStream(id: number): Stream | undefined {\n return this.streams.get(id);\n }\n\n /**\n * Remove a transfer\n */\n removeTransfer(id: string): boolean {\n const transfer = this.transfers.get(id);\n if (transfer) {\n transfer.cancel();\n this.transfers.delete(id);\n return true;\n }\n return false;\n }\n\n /**\n * Get all active transfers\n */\n getActiveTransfers(): BulkTransfer[] {\n return Array.from(this.transfers.values()).filter(\n (t) =>\n t.currentState === 'pending' ||\n t.currentState === 'transferring' ||\n t.currentState === 'paused'\n );\n }\n\n /**\n * Get transfer statistics summary\n */\n getStatsSummary(): {\n totalTransfers: number;\n activeTransfers: number;\n completedTransfers: number;\n totalBytesTransferred: number;\n } {\n const transfers = Array.from(this.transfers.values());\n const active = transfers.filter((t) => t.currentState === 'transferring');\n const completed = transfers.filter((t) => t.currentState === 'completed');\n\n const totalBytes = transfers.reduce((sum, t) => sum + t.stats.bytesTransferred, 0);\n\n return {\n totalTransfers: transfers.length,\n activeTransfers: active.length,\n completedTransfers: completed.length,\n totalBytesTransferred: totalBytes,\n };\n }\n\n /**\n * Close all transfers\n */\n async closeAll(): Promise<void> {\n for (const transfer of this.transfers.values()) {\n transfer.cancel();\n }\n this.transfers.clear();\n this.streams.clear();\n }\n}\n\n/**\n * Create a bulk transfer manager\n */\nexport function createBulkTransferManager(): BulkTransferManager {\n return new BulkTransferManager();\n}\n","/**\n * Realtime API - Real-time communication with prioritization\n *\n * Phase 5: Flow Control and Realtime Communication\n *\n * Features:\n * - Message priority queues\n * - Message drop policies for latency-sensitive scenarios\n * - Bandwidth adaptation\n * - Jitter buffer management\n */\n\nimport {\n type FlowControlConfig,\n type Stream,\n type StreamChunk,\n type StreamOptions,\n StreamPriority,\n} from './stream.js';\n\n/** Message priority levels (extends StreamPriority) */\nexport { StreamPriority as MessagePriority };\n\n/** Message drop policy for latency-sensitive scenarios */\nexport enum DropPolicy {\n /** Never drop messages */\n NEVER = 'never',\n /** Drop oldest messages when queue is full */\n DROP_OLDEST = 'drop_oldest',\n /** Drop newest messages when queue is full */\n DROP_NEWEST = 'drop_newest',\n /** Drop low priority messages first */\n DROP_LOW_PRIORITY = 'drop_low_priority',\n /** Drop messages that exceed max latency */\n DROP_STALE = 'drop_stale',\n}\n\n/** Realtime stream configuration */\nexport interface RealtimeConfig {\n /** Target latency in milliseconds */\n targetLatencyMs: number;\n /** Maximum acceptable latency in milliseconds */\n maxLatencyMs: number;\n /** Jitter buffer size in milliseconds */\n jitterBufferMs: number;\n /** Message queue size limit */\n maxQueueSize: number;\n /** Drop policy for queue management */\n dropPolicy: DropPolicy;\n /** Enable adaptive bitrate */\n adaptiveBitrate: boolean;\n /** Minimum bitrate in bytes per second */\n minBitrate: number;\n /** Maximum bitrate in bytes per second */\n maxBitrate: number;\n /** Bandwidth measurement window in milliseconds */\n bandwidthWindowMs: number;\n}\n\n/** Default realtime configuration */\nexport const DEFAULT_REALTIME_CONFIG: RealtimeConfig = {\n targetLatencyMs: 50,\n maxLatencyMs: 200,\n jitterBufferMs: 30,\n maxQueueSize: 1000,\n dropPolicy: DropPolicy.DROP_STALE,\n adaptiveBitrate: true,\n minBitrate: 16000, // 16 KB/s\n maxBitrate: 10485760, // 10 MB/s\n bandwidthWindowMs: 1000,\n};\n\n/** Realtime message */\nexport interface RealtimeMessage {\n /** Message ID */\n id: string;\n /** Message priority */\n priority: StreamPriority;\n /** Message timestamp */\n timestamp: number;\n /** Message data */\n data: Uint8Array;\n /** Message type/category */\n type?: string;\n /** Sequence number for ordering */\n sequenceNumber: number;\n /** Whether message is critical (cannot be dropped) */\n critical?: boolean;\n}\n\n/** Bandwidth statistics */\nexport interface BandwidthStats {\n /** Current bitrate in bytes per second */\n currentBitrate: number;\n /** Measured bandwidth in bytes per second */\n measuredBandwidth: number;\n /** Packet loss rate (0-1) */\n packetLossRate: number;\n /** Average latency in milliseconds */\n averageLatencyMs: number;\n /** Jitter in milliseconds */\n jitterMs: number;\n /** Congestion level (0-1) */\n congestionLevel: number;\n}\n\n/** Jitter buffer entry */\ninterface JitterBufferEntry {\n message: RealtimeMessage;\n receivedAt: number;\n playoutTime: number;\n}\n\n/** Realtime stream event handlers */\nexport interface RealtimeStreamHandlers {\n /** Called when a message is received */\n onMessage?: (message: RealtimeMessage) => void | Promise<void>;\n /** Called when messages are dropped */\n onDrop?: (messages: RealtimeMessage[], reason: string) => void;\n /** Called when bandwidth is adapted */\n onBandwidthAdapt?: (newBitrate: number, stats: BandwidthStats) => void;\n /** Called when latency changes */\n onLatencyChange?: (latencyMs: number) => void;\n /** Called when stream is ready to play */\n onReady?: () => void;\n /** Called on error */\n onError?: (error: Error) => void;\n}\n\n/**\n * Priority queue for realtime messages\n */\nclass PriorityMessageQueue {\n private queues: Map<StreamPriority, RealtimeMessage[]> = new Map();\n private totalSize = 0;\n private maxSize: number;\n private dropPolicy: DropPolicy;\n private maxLatencyMs: number;\n\n constructor(maxSize: number, dropPolicy: DropPolicy, maxLatencyMs: number) {\n this.maxSize = maxSize;\n this.dropPolicy = dropPolicy;\n this.maxLatencyMs = maxLatencyMs;\n\n // Initialize queues for each priority level\n for (let i = 0; i <= 4; i++) {\n this.queues.set(i as StreamPriority, []);\n }\n }\n\n /** Get total queue size */\n get size(): number {\n return this.totalSize;\n }\n\n /** Check if queue is empty */\n get isEmpty(): boolean {\n return this.totalSize === 0;\n }\n\n /** Enqueue a message */\n enqueue(message: RealtimeMessage): boolean {\n // Check if message is stale\n if (this.dropPolicy === DropPolicy.DROP_STALE) {\n const age = Date.now() - message.timestamp;\n if (age > this.maxLatencyMs && !message.critical) {\n return false; // Message dropped\n }\n }\n\n // Check if queue is full\n if (this.totalSize >= this.maxSize) {\n if (!this.handleQueueFull(message)) {\n return false;\n }\n }\n\n const queue = this.queues.get(message.priority)!;\n queue.push(message);\n this.totalSize++;\n\n return true;\n }\n\n /** Dequeue the highest priority message */\n dequeue(): RealtimeMessage | undefined {\n // Check queues from highest to lowest priority\n for (let priority = 0; priority <= 4; priority++) {\n const queue = this.queues.get(priority as StreamPriority)!;\n if (queue.length > 0) {\n this.totalSize--;\n return queue.shift()!;\n }\n }\n return undefined;\n }\n\n /** Peek at the highest priority message without removing */\n peek(): RealtimeMessage | undefined {\n for (let priority = 0; priority <= 4; priority++) {\n const queue = this.queues.get(priority as StreamPriority)!;\n if (queue.length > 0) {\n return queue[0];\n }\n }\n return undefined;\n }\n\n /** Remove stale messages */\n removeStale(): RealtimeMessage[] {\n const now = Date.now();\n const removed: RealtimeMessage[] = [];\n\n for (const [priority, queue] of this.queues) {\n const remaining: RealtimeMessage[] = [];\n for (const msg of queue) {\n if (now - msg.timestamp <= this.maxLatencyMs || msg.critical) {\n remaining.push(msg);\n } else {\n removed.push(msg);\n this.totalSize--;\n }\n }\n this.queues.set(priority, remaining);\n }\n\n return removed;\n }\n\n /** Clear all messages */\n clear(): RealtimeMessage[] {\n const all: RealtimeMessage[] = [];\n for (const queue of this.queues.values()) {\n all.push(...queue);\n }\n for (const queue of this.queues.values()) {\n queue.length = 0;\n }\n this.totalSize = 0;\n return all;\n }\n\n private handleQueueFull(newMessage: RealtimeMessage): boolean {\n switch (this.dropPolicy) {\n case DropPolicy.NEVER:\n return false;\n\n case DropPolicy.DROP_OLDEST:\n // Remove oldest message from lowest priority queue\n for (let priority = 4; priority >= 0; priority--) {\n const queue = this.queues.get(priority as StreamPriority)!;\n if (queue.length > 0 && priority >= newMessage.priority) {\n queue.shift();\n this.totalSize--;\n return true;\n }\n }\n return false;\n\n case DropPolicy.DROP_NEWEST:\n // Don't add the new message if it's lower priority\n if (newMessage.priority >= StreamPriority.NORMAL) {\n return false;\n }\n return true;\n\n case DropPolicy.DROP_LOW_PRIORITY:\n // Remove a message from lower priority than the new message\n for (let priority = 4; priority > newMessage.priority; priority--) {\n const queue = this.queues.get(priority as StreamPriority)!;\n if (queue.length > 0) {\n queue.shift();\n this.totalSize--;\n return true;\n }\n }\n return false;\n\n case DropPolicy.DROP_STALE: {\n // Remove stale messages first\n const stale = this.removeStale();\n if (stale.length > 0) {\n return true;\n }\n // Fall through to DROP_OLDEST\n for (let priority = 4; priority >= 0; priority--) {\n const queue = this.queues.get(priority as StreamPriority)!;\n if (queue.length > 0 && priority >= newMessage.priority) {\n queue.shift();\n this.totalSize--;\n return true;\n }\n }\n return false;\n }\n\n default:\n return false;\n }\n }\n}\n\n/**\n * Realtime stream for low-latency communication\n *\n * Manages message prioritization, jitter buffering, and bandwidth adaptation.\n */\nexport class RealtimeStream {\n private stream: Stream;\n private config: RealtimeConfig;\n private handlers: RealtimeStreamHandlers;\n\n // Message queues\n private sendQueue: PriorityMessageQueue;\n private receiveQueue: PriorityMessageQueue;\n\n // Jitter buffer\n private jitterBuffer: JitterBufferEntry[] = [];\n private jitterBufferTargetSize: number;\n\n // Bandwidth adaptation\n private bandwidthStats: BandwidthStats = {\n currentBitrate: 0,\n measuredBandwidth: 0,\n packetLossRate: 0,\n averageLatencyMs: 0,\n jitterMs: 0,\n congestionLevel: 0,\n };\n private bitrateHistory: number[] = [];\n private latencyHistory: number[] = [];\n private lastBandwidthUpdate = 0;\n\n // Sequence numbers\n private nextSendSequence = 0;\n private nextExpectedSequence = 0;\n private receivedSequences: Set<number> = new Set();\n\n // State\n private isRunning = false;\n private sendInterval?: ReturnType<typeof setInterval>;\n private jitterInterval?: ReturnType<typeof setInterval>;\n private bandwidthInterval?: ReturnType<typeof setInterval>;\n\n constructor(\n stream: Stream,\n config: Partial<RealtimeConfig> = {},\n handlers: RealtimeStreamHandlers = {}\n ) {\n this.stream = stream;\n this.config = { ...DEFAULT_REALTIME_CONFIG, ...config };\n this.handlers = handlers;\n\n this.sendQueue = new PriorityMessageQueue(\n this.config.maxQueueSize,\n this.config.dropPolicy,\n this.config.maxLatencyMs\n );\n\n this.receiveQueue = new PriorityMessageQueue(\n this.config.maxQueueSize,\n this.config.dropPolicy,\n this.config.maxLatencyMs\n );\n\n // Calculate jitter buffer target size based on jitter buffer time\n this.jitterBufferTargetSize = Math.ceil(\n this.config.jitterBufferMs / this.config.targetLatencyMs\n );\n\n this.setupStreamHandlers();\n }\n\n /** Get current bandwidth statistics */\n get stats(): BandwidthStats {\n return { ...this.bandwidthStats };\n }\n\n /** Get current send queue size */\n get sendQueueSize(): number {\n return this.sendQueue.size;\n }\n\n /** Get current receive queue size */\n get receiveQueueSize(): number {\n return this.receiveQueue.size;\n }\n\n /** Get jitter buffer size */\n get jitterBufferSize(): number {\n return this.jitterBuffer.length;\n }\n\n /**\n * Start the realtime stream\n */\n start(): void {\n if (this.isRunning) return;\n\n this.isRunning = true;\n\n // Start send loop\n this.sendInterval = setInterval(() => {\n this.processSendQueue();\n }, this.config.targetLatencyMs / 2);\n\n // Start jitter buffer processing\n this.jitterInterval = setInterval(() => {\n this.processJitterBuffer();\n }, this.config.targetLatencyMs / 4);\n\n // Start bandwidth monitoring\n if (this.config.adaptiveBitrate) {\n this.bandwidthInterval = setInterval(() => {\n this.updateBandwidthStats();\n }, this.config.bandwidthWindowMs);\n }\n\n this.handlers.onReady?.();\n }\n\n /**\n * Stop the realtime stream\n */\n stop(): void {\n this.isRunning = false;\n\n if (this.sendInterval) {\n clearInterval(this.sendInterval);\n this.sendInterval = undefined;\n }\n\n if (this.jitterInterval) {\n clearInterval(this.jitterInterval);\n this.jitterInterval = undefined;\n }\n\n if (this.bandwidthInterval) {\n clearInterval(this.bandwidthInterval);\n this.bandwidthInterval = undefined;\n }\n\n // Clear queues\n const dropped = this.sendQueue.clear();\n if (dropped.length > 0) {\n this.handlers.onDrop?.(dropped, 'stream stopped');\n }\n }\n\n /**\n * Send a realtime message\n */\n sendMessage(\n data: Uint8Array,\n priority: StreamPriority = StreamPriority.NORMAL,\n options: { type?: string; critical?: boolean } = {}\n ): boolean {\n if (!this.isRunning) {\n return false;\n }\n\n const message: RealtimeMessage = {\n id: this.generateMessageId(),\n priority,\n timestamp: Date.now(),\n data,\n type: options.type,\n sequenceNumber: this.nextSendSequence++,\n critical: options.critical,\n };\n\n const enqueued = this.sendQueue.enqueue(message);\n\n if (!enqueued) {\n this.handlers.onDrop?.([message], 'queue full');\n return false;\n }\n\n return true;\n }\n\n /**\n * Receive the next message (blocking)\n */\n async receiveMessage(): Promise<RealtimeMessage | undefined> {\n return new Promise((resolve) => {\n const checkQueue = () => {\n const message = this.receiveQueue.dequeue();\n if (message) {\n resolve(message);\n } else if (!this.isRunning) {\n resolve(undefined);\n } else {\n setTimeout(checkQueue, 5);\n }\n };\n checkQueue();\n });\n }\n\n /**\n * Set target bitrate (for manual bitrate control)\n */\n setTargetBitrate(bitrate: number): void {\n this.bandwidthStats.currentBitrate = Math.max(\n this.config.minBitrate,\n Math.min(this.config.maxBitrate, bitrate)\n );\n }\n\n // =============================================================================\n // Private Methods\n // =============================================================================\n\n private setupStreamHandlers(): void {\n // Set up stream data handler\n const originalOnData = (\n this.stream as unknown as { handlers?: { onData?: (chunk: StreamChunk) => void } }\n ).handlers?.onData;\n\n (this.stream as unknown as { handlers: { onData?: (chunk: StreamChunk) => void } }).handlers = {\n ...(this.stream as unknown as { handlers: { onData?: (chunk: StreamChunk) => void } })\n .handlers,\n onData: (chunk: StreamChunk) => {\n this.handleIncomingData(chunk);\n originalOnData?.(chunk);\n },\n };\n }\n\n private handleIncomingData(chunk: StreamChunk): void {\n try {\n // Parse message from chunk\n const message = this.deserializeMessage(chunk.data);\n\n // Track sequence number for packet loss calculation\n if (message.sequenceNumber > this.nextExpectedSequence) {\n // Packet loss detected\n const lost = message.sequenceNumber - this.nextExpectedSequence;\n this.bandwidthStats.packetLossRate = this.bandwidthStats.packetLossRate * 0.9 + lost * 0.1;\n }\n this.nextExpectedSequence = message.sequenceNumber + 1;\n\n // Calculate latency\n const latency = Date.now() - message.timestamp;\n this.latencyHistory.push(latency);\n if (this.latencyHistory.length > 100) {\n this.latencyHistory.shift();\n }\n\n // Add to jitter buffer\n const playoutTime = Date.now() + this.config.jitterBufferMs;\n this.jitterBuffer.push({\n message,\n receivedAt: Date.now(),\n playoutTime,\n });\n\n // Sort jitter buffer by sequence number\n this.jitterBuffer.sort((a, b) => a.message.sequenceNumber - b.message.sequenceNumber);\n } catch (error) {\n this.handlers.onError?.(error as Error);\n }\n }\n\n private processSendQueue(): void {\n if (!this.isRunning || this.sendQueue.isEmpty) {\n return;\n }\n\n // Check bandwidth limit\n if (this.config.adaptiveBitrate) {\n const currentBitrate = this.bandwidthStats.currentBitrate;\n const maxBytesPerInterval = (currentBitrate * this.config.targetLatencyMs) / 1000 / 2;\n\n let bytesSent = 0;\n while (bytesSent < maxBytesPerInterval) {\n const message = this.sendQueue.dequeue();\n if (!message) break;\n\n this.sendMessageToStream(message);\n bytesSent += message.data.length;\n }\n } else {\n // Send one message per interval\n const message = this.sendQueue.dequeue();\n if (message) {\n this.sendMessageToStream(message);\n }\n }\n\n // Remove stale messages from queue\n if (this.config.dropPolicy === DropPolicy.DROP_STALE) {\n const stale = this.sendQueue.removeStale();\n if (stale.length > 0) {\n this.handlers.onDrop?.(stale, 'stale');\n }\n }\n }\n\n private sendMessageToStream(message: RealtimeMessage): void {\n try {\n const data = this.serializeMessage(message);\n this.stream.send(data).catch((err) => {\n this.handlers.onError?.(err);\n });\n\n // Track bitrate\n this.bitrateHistory.push(data.length);\n if (this.bitrateHistory.length > 100) {\n this.bitrateHistory.shift();\n }\n } catch (error) {\n this.handlers.onError?.(error as Error);\n }\n }\n\n private processJitterBuffer(): void {\n if (!this.isRunning || this.jitterBuffer.length === 0) {\n return;\n }\n\n const now = Date.now();\n\n // Process messages that have reached their playout time\n while (this.jitterBuffer.length > 0) {\n const entry = this.jitterBuffer[0];\n\n // Wait until we have enough messages in the buffer\n if (this.jitterBuffer.length < this.jitterBufferTargetSize && entry.playoutTime > now) {\n break;\n }\n\n if (entry.playoutTime <= now) {\n this.jitterBuffer.shift();\n this.receiveQueue.enqueue(entry.message);\n this.handlers.onMessage?.(entry.message);\n } else {\n break;\n }\n }\n\n // Remove stale messages from jitter buffer\n const maxAge = this.config.maxLatencyMs * 2;\n const stale: RealtimeMessage[] = [];\n this.jitterBuffer = this.jitterBuffer.filter((entry) => {\n if (now - entry.receivedAt > maxAge && !entry.message.critical) {\n stale.push(entry.message);\n return false;\n }\n return true;\n });\n\n if (stale.length > 0) {\n this.handlers.onDrop?.(stale, 'jitter buffer stale');\n }\n }\n\n private updateBandwidthStats(): void {\n const now = Date.now();\n const windowMs = this.config.bandwidthWindowMs;\n\n // Calculate measured bandwidth\n if (this.bitrateHistory.length >= 2) {\n const totalBytes = this.bitrateHistory.reduce((a, b) => a + b, 0);\n this.bandwidthStats.measuredBandwidth = (totalBytes / windowMs) * 1000;\n }\n\n // Calculate average latency\n if (this.latencyHistory.length > 0) {\n const avgLatency =\n this.latencyHistory.reduce((a, b) => a + b, 0) / this.latencyHistory.length;\n this.bandwidthStats.averageLatencyMs = avgLatency;\n\n // Calculate jitter (standard deviation of latency)\n const variance =\n this.latencyHistory.reduce((sum, lat) => sum + (lat - avgLatency) ** 2, 0) /\n this.latencyHistory.length;\n this.bandwidthStats.jitterMs = Math.sqrt(variance);\n\n this.handlers.onLatencyChange?.(avgLatency);\n }\n\n // Calculate congestion level\n const queueUtilization = this.sendQueue.size / this.config.maxQueueSize;\n const latencyRatio = this.bandwidthStats.averageLatencyMs / this.config.targetLatencyMs;\n this.bandwidthStats.congestionLevel = Math.min(1, (queueUtilization + latencyRatio) / 2);\n\n // Adapt bitrate\n if (this.config.adaptiveBitrate) {\n this.adaptBitrate();\n }\n\n this.lastBandwidthUpdate = now;\n }\n\n private adaptBitrate(): void {\n const { congestionLevel, packetLossRate } = this.bandwidthStats;\n let newBitrate = this.bandwidthStats.currentBitrate;\n\n if (congestionLevel > 0.7 || packetLossRate > 0.05) {\n // Decrease bitrate\n newBitrate = newBitrate * 0.8;\n } else if (congestionLevel < 0.3 && packetLossRate < 0.01) {\n // Increase bitrate\n newBitrate = newBitrate * 1.05;\n }\n\n // Clamp to min/max\n newBitrate = Math.max(this.config.minBitrate, Math.min(this.config.maxBitrate, newBitrate));\n\n if (newBitrate !== this.bandwidthStats.currentBitrate) {\n this.bandwidthStats.currentBitrate = newBitrate;\n this.handlers.onBandwidthAdapt?.(newBitrate, this.bandwidthStats);\n }\n }\n\n private serializeMessage(message: RealtimeMessage): Uint8Array {\n // Simple serialization: JSON header + binary data\n const header = JSON.stringify({\n id: message.id,\n priority: message.priority,\n timestamp: message.timestamp,\n type: message.type,\n sequenceNumber: message.sequenceNumber,\n critical: message.critical,\n dataLength: message.data.length,\n });\n\n const headerBytes = new TextEncoder().encode(header);\n const headerLength = new Uint8Array(4);\n new DataView(headerLength.buffer).setUint32(0, headerBytes.length, true);\n\n const result = new Uint8Array(4 + headerBytes.length + message.data.length);\n result.set(headerLength, 0);\n result.set(headerBytes, 4);\n result.set(message.data, 4 + headerBytes.length);\n\n return result;\n }\n\n private deserializeMessage(data: Uint8Array): RealtimeMessage {\n const headerLength = new DataView(data.buffer, data.byteOffset, 4).getUint32(0, true);\n const headerBytes = data.slice(4, 4 + headerLength);\n const header = JSON.parse(new TextDecoder().decode(headerBytes));\n\n return {\n id: header.id,\n priority: header.priority,\n timestamp: header.timestamp,\n type: header.type,\n sequenceNumber: header.sequenceNumber,\n critical: header.critical,\n data: data.slice(4 + headerLength, 4 + headerLength + header.dataLength),\n };\n }\n\n private generateMessageId(): string {\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n}\n\n/**\n * Realtime stream manager\n */\nexport class RealtimeStreamManager {\n private streams: Map<number, RealtimeStream> = new Map();\n private nextStreamId = 1;\n\n /**\n * Create a new realtime stream\n */\n createStream(\n baseStream: Stream,\n config?: Partial<RealtimeConfig>,\n handlers?: RealtimeStreamHandlers\n ): RealtimeStream {\n const streamId = this.nextStreamId++;\n const stream = new RealtimeStream(baseStream, config, handlers);\n this.streams.set(streamId, stream);\n return stream;\n }\n\n /**\n * Get a stream by ID\n */\n getStream(id: number): RealtimeStream | undefined {\n return this.streams.get(id);\n }\n\n /**\n * Remove a stream\n */\n removeStream(id: number): boolean {\n const stream = this.streams.get(id);\n if (stream) {\n stream.stop();\n this.streams.delete(id);\n return true;\n }\n return false;\n }\n\n /**\n * Get all active streams\n */\n getActiveStreams(): RealtimeStream[] {\n return Array.from(this.streams.values());\n }\n\n /**\n * Stop all streams\n */\n stopAll(): void {\n for (const stream of this.streams.values()) {\n stream.stop();\n }\n this.streams.clear();\n }\n}\n\n/**\n * Create a realtime stream manager\n */\nexport function createRealtimeStreamManager(): RealtimeStreamManager {\n return new RealtimeStreamManager();\n}\n","/**\n * Stream Management - Unified stream lifecycle management\n *\n * Phase 5: Flow Control and Realtime Communication\n *\n * Manages:\n * - Stream creation and registration\n * - Bidirectional stream support\n * - Stream lifecycle (open, close, error handling)\n * - Stream multiplexing over a single connection\n */\n\nimport {\n type BulkTransfer,\n type BulkTransferConfig,\n BulkTransferManager,\n type BulkTransferMetadata,\n} from './bulk.js';\nimport {\n type RealtimeConfig,\n type RealtimeStream,\n type RealtimeStreamHandlers,\n RealtimeStreamManager,\n} from './realtime.js';\nimport type { RpcConnection } from './rpc-connection.js';\nimport {\n Stream,\n type StreamDirection,\n type StreamOptions,\n StreamPriority,\n type StreamState,\n} from './stream.js';\nimport type { RpcTransport } from './transport.js';\n\n/** Stream type */\nexport enum StreamType {\n /** Standard stream */\n STANDARD = 'standard',\n /** Bulk transfer stream */\n BULK = 'bulk',\n /** Realtime stream */\n REALTIME = 'realtime',\n}\n\n/** Stream info */\nexport interface StreamInfo {\n /** Stream ID */\n id: number;\n /** Stream type */\n type: StreamType;\n /** Stream direction */\n direction: StreamDirection;\n /** Stream priority */\n priority: StreamPriority;\n /** Current state */\n state: StreamState;\n /** Creation timestamp */\n createdAt: number;\n /** Bytes transferred */\n bytesTransferred: number;\n /** Metadata */\n metadata?: Record<string, string>;\n}\n\n/** Stream manager configuration */\nexport interface StreamManagerConfig {\n /** Maximum number of concurrent streams */\n maxStreams: number;\n /** Default stream priority */\n defaultPriority: StreamPriority;\n /** Enable stream multiplexing */\n enableMultiplexing: boolean;\n /** Idle timeout in milliseconds */\n idleTimeoutMs: number;\n}\n\n/** Default stream manager configuration */\nexport const DEFAULT_STREAM_MANAGER_CONFIG: StreamManagerConfig = {\n maxStreams: 100,\n defaultPriority: StreamPriority.NORMAL,\n enableMultiplexing: true,\n idleTimeoutMs: 300000, // 5 minutes\n};\n\n/** Stream creation options */\nexport interface CreateStreamOptions {\n /** Stream type */\n type?: StreamType;\n /** Stream direction */\n direction?: StreamDirection;\n /** Stream priority */\n priority?: StreamPriority;\n /** Stream metadata */\n metadata?: Record<string, string>;\n /** Flow control configuration */\n flowControl?: Partial<import('./stream.js').FlowControlConfig>;\n}\n\n/** Stream manager event handlers */\nexport interface StreamManagerHandlers {\n /** Called when a stream is created */\n onStreamCreate?: (info: StreamInfo) => void;\n /** Called when a stream is opened */\n onStreamOpen?: (info: StreamInfo) => void;\n /** Called when a stream is closed */\n onStreamClose?: (info: StreamInfo) => void;\n /** Called when a stream errors */\n onStreamError?: (info: StreamInfo, error: Error) => void;\n /** Called when stream count changes */\n onStreamCountChange?: (count: number) => void;\n}\n\n/**\n * Stream manager\n *\n * Manages all streams for an RPC connection.\n */\nexport class StreamManager {\n private config: StreamManagerConfig;\n private handlers: StreamManagerHandlers;\n private connection?: RpcConnection;\n private transport?: RpcTransport;\n\n // Stream registries\n private streams: Map<number, Stream> = new Map();\n private streamTypes: Map<number, StreamType> = new Map();\n private streamInfos: Map<number, StreamInfo> = new Map();\n private nextStreamId = 1;\n\n // Sub-managers\n private bulkManager: BulkTransferManager;\n private realtimeManager: RealtimeStreamManager;\n\n // Lifecycle\n private idleTimeout?: ReturnType<typeof setTimeout>;\n private isRunning = false;\n\n constructor(config: Partial<StreamManagerConfig> = {}, handlers: StreamManagerHandlers = {}) {\n this.config = { ...DEFAULT_STREAM_MANAGER_CONFIG, ...config };\n this.handlers = handlers;\n this.bulkManager = new BulkTransferManager();\n this.realtimeManager = new RealtimeStreamManager();\n }\n\n /** Get the number of active streams */\n get streamCount(): number {\n return this.streams.size;\n }\n\n /** Get the maximum number of streams */\n get maxStreams(): number {\n return this.config.maxStreams;\n }\n\n /** Get all stream infos */\n get allStreamInfos(): StreamInfo[] {\n return Array.from(this.streamInfos.values());\n }\n\n /**\n * Attach to an RPC connection\n */\n attach(connection: RpcConnection, transport?: RpcTransport): void {\n this.connection = connection;\n this.transport = transport;\n this.isRunning = true;\n this.resetIdleTimeout();\n }\n\n /**\n * Detach from connection\n */\n detach(): void {\n this.closeAllStreams();\n this.isRunning = false;\n this.connection = undefined;\n this.transport = undefined;\n\n if (this.idleTimeout) {\n clearTimeout(this.idleTimeout);\n this.idleTimeout = undefined;\n }\n }\n\n /**\n * Create a new stream\n */\n createStream(options: CreateStreamOptions = {}): Stream {\n if (this.streams.size >= this.config.maxStreams) {\n throw new Error(`Maximum number of streams (${this.config.maxStreams}) reached`);\n }\n\n const streamId = this.nextStreamId++;\n const type = options.type ?? StreamType.STANDARD;\n\n const streamOptions: StreamOptions = {\n streamId,\n direction: options.direction ?? 'bidirectional',\n priority: options.priority ?? this.config.defaultPriority ?? StreamPriority.NORMAL,\n metadata: options.metadata,\n flowControl: options.flowControl,\n };\n\n const stream = new Stream(streamOptions, {\n onOpen: () => {\n this.updateStreamState(streamId, 'open');\n this.handlers.onStreamOpen?.(this.getStreamInfo(streamId)!);\n },\n onClose: () => {\n this.updateStreamState(streamId, 'closed');\n this.handlers.onStreamClose?.(this.getStreamInfo(streamId)!);\n this.removeStream(streamId);\n },\n onError: (error) => {\n this.updateStreamState(streamId, 'error');\n const info = this.getStreamInfo(streamId);\n if (info) {\n this.handlers.onStreamError?.(info, error);\n }\n },\n });\n\n this.streams.set(streamId, stream);\n this.streamTypes.set(streamId, type);\n\n const info: StreamInfo = {\n id: streamId,\n type,\n direction: streamOptions.direction,\n priority: streamOptions.priority ?? StreamPriority.NORMAL,\n state: 'connecting',\n createdAt: Date.now(),\n bytesTransferred: 0,\n metadata: options.metadata,\n };\n this.streamInfos.set(streamId, info);\n\n this.handlers.onStreamCreate?.(info);\n this.handlers.onStreamCountChange?.(this.streams.size);\n\n this.resetIdleTimeout();\n\n return stream;\n }\n\n /**\n * Create a bulk transfer stream\n */\n createBulkStream(\n direction: 'upload' | 'download',\n metadata: BulkTransferMetadata,\n config?: Partial<BulkTransferConfig>,\n handlers?: import('./bulk.js').BulkTransferHandlers\n ): BulkTransfer {\n const _stream = this.createStream({\n type: StreamType.BULK,\n direction: direction === 'upload' ? 'outbound' : 'inbound',\n priority: StreamPriority.NORMAL,\n metadata: metadata.custom,\n });\n\n return this.bulkManager.createTransfer(direction, metadata, config, handlers);\n }\n\n /**\n * Create a realtime stream\n */\n createRealtimeStream(\n config?: Partial<RealtimeConfig>,\n handlers?: RealtimeStreamHandlers\n ): RealtimeStream {\n const stream = this.createStream({\n type: StreamType.REALTIME,\n direction: 'bidirectional',\n priority: StreamPriority.HIGH,\n });\n\n return this.realtimeManager.createStream(stream, config, handlers);\n }\n\n /**\n * Get a stream by ID\n */\n getStream(id: number): Stream | undefined {\n return this.streams.get(id);\n }\n\n /**\n * Get stream info by ID\n */\n getStreamInfo(id: number): StreamInfo | undefined {\n return this.streamInfos.get(id);\n }\n\n /**\n * Get stream type by ID\n */\n getStreamType(id: number): StreamType | undefined {\n return this.streamTypes.get(id);\n }\n\n /**\n * Get bulk transfer by ID\n */\n getBulkTransfer(id: string): BulkTransfer | undefined {\n return this.bulkManager.getTransfer(id);\n }\n\n /**\n * Get realtime stream by ID\n */\n getRealtimeStream(id: number): RealtimeStream | undefined {\n return this.realtimeManager.getStream(id);\n }\n\n /**\n * Close a specific stream\n */\n async closeStream(id: number): Promise<boolean> {\n const stream = this.streams.get(id);\n if (!stream) {\n return false;\n }\n\n await stream.close();\n this.removeStream(id);\n return true;\n }\n\n /**\n * Close all streams\n */\n async closeAllStreams(): Promise<void> {\n const closePromises: Promise<void>[] = [];\n\n for (const [_id, stream] of this.streams) {\n closePromises.push(\n stream.close().catch(() => {\n // Ignore errors during bulk close\n })\n );\n }\n\n await Promise.all(closePromises);\n\n this.streams.clear();\n this.streamTypes.clear();\n this.streamInfos.clear();\n this.bulkManager.closeAll();\n this.realtimeManager.stopAll();\n\n this.handlers.onStreamCountChange?.(0);\n }\n\n /**\n * Get streams by type\n */\n getStreamsByType(type: StreamType): StreamInfo[] {\n return this.allStreamInfos.filter((info) => info.type === type);\n }\n\n /**\n * Get streams by state\n */\n getStreamsByState(state: StreamState): StreamInfo[] {\n return this.allStreamInfos.filter((info) => info.state === state);\n }\n\n /**\n * Get statistics\n */\n getStatistics(): {\n totalStreams: number;\n activeStreams: number;\n streamsByType: Record<StreamType, number>;\n streamsByState: Record<StreamState, number>;\n totalBytesTransferred: number;\n } {\n const infos = this.allStreamInfos;\n const active = infos.filter((i) => i.state === 'open');\n\n const byType: Record<StreamType, number> = {\n [StreamType.STANDARD]: 0,\n [StreamType.BULK]: 0,\n [StreamType.REALTIME]: 0,\n };\n\n const byState: Record<StreamState, number> = {\n connecting: 0,\n open: 0,\n closing: 0,\n closed: 0,\n error: 0,\n };\n\n let totalBytes = 0;\n\n for (const info of infos) {\n byType[info.type]++;\n byState[info.state]++;\n totalBytes += info.bytesTransferred;\n }\n\n return {\n totalStreams: infos.length,\n activeStreams: active.length,\n streamsByType: byType,\n streamsByState: byState,\n totalBytesTransferred: totalBytes,\n };\n }\n\n /**\n * Update stream priority\n */\n updatePriority(id: number, priority: StreamPriority): boolean {\n const info = this.streamInfos.get(id);\n if (!info) {\n return false;\n }\n\n info.priority = priority;\n return true;\n }\n\n /**\n * Pause all streams (backpressure)\n */\n pauseAll(): void {\n for (const _stream of this.streams.values()) {\n // Streams don't have a direct pause method, but we can use backpressure\n // This is a simplified implementation\n }\n }\n\n /**\n * Resume all streams\n */\n resumeAll(): void {\n for (const _stream of this.streams.values()) {\n // Resume from backpressure\n }\n }\n\n // =============================================================================\n // Private Methods\n // =============================================================================\n\n private removeStream(id: number): void {\n this.streams.delete(id);\n this.streamTypes.delete(id);\n this.streamInfos.delete(id);\n\n this.handlers.onStreamCountChange?.(this.streams.size);\n this.resetIdleTimeout();\n }\n\n private updateStreamState(id: number, state: StreamState): void {\n const info = this.streamInfos.get(id);\n if (info) {\n info.state = state;\n }\n }\n\n private resetIdleTimeout(): void {\n if (this.idleTimeout) {\n clearTimeout(this.idleTimeout);\n }\n\n if (!this.isRunning || this.streams.size > 0) {\n return;\n }\n\n this.idleTimeout = setTimeout(() => {\n if (this.streams.size === 0) {\n // No active streams, could emit an event or take action\n }\n }, this.config.idleTimeoutMs);\n }\n}\n\n/**\n * Create a stream manager\n */\nexport function createStreamManager(\n config?: Partial<StreamManagerConfig>,\n handlers?: StreamManagerHandlers\n): StreamManager {\n return new StreamManager(config, handlers);\n}\n\n// Re-export types\nexport type { Stream, StreamOptions, StreamState, StreamDirection } from './stream.js';\nexport { StreamPriority } from './stream.js';\nexport type {\n BulkTransfer,\n BulkTransferConfig,\n BulkTransferMetadata,\n} from './bulk.js';\nexport { BulkTransferManager } from './bulk.js';\nexport type {\n RealtimeStream,\n RealtimeConfig,\n RealtimeStreamHandlers,\n} from './realtime.js';\nexport { RealtimeStreamManager } from './realtime.js';\n","/**\n * Streaming RpcConnection Extension\n *\n * Phase 5: Flow Control and Realtime Communication\n *\n * Extends RpcConnection with streaming capabilities:\n * - Stream creation and management\n * - Integration with existing Pipeline\n * * Stream capability negotiation\n */\n\nimport type { BulkTransferConfig, BulkTransferHandlers, BulkTransferMetadata } from './bulk.js';\nimport type { RealtimeConfig, RealtimeStreamHandlers } from './realtime.js';\nimport { RpcConnection, type RpcConnectionOptions } from './rpc-connection.js';\nimport type { ExportId, ImportId, RpcMessage } from './rpc-types.js';\nimport {\n type BulkTransfer,\n type CreateStreamOptions,\n type RealtimeStream,\n type Stream,\n StreamManager,\n type StreamManagerConfig,\n type StreamManagerHandlers,\n StreamType,\n} from './stream-manager.js';\nimport type { RpcTransport } from './transport.js';\n\n/** Streaming capability flags */\nexport interface StreamingCapabilities {\n /** Standard streaming supported */\n standardStreams: boolean;\n /** Bulk transfer supported */\n bulkTransfer: boolean;\n /** Realtime streaming supported */\n realtimeStreams: boolean;\n /** Maximum concurrent streams */\n maxConcurrentStreams: number;\n /** Maximum stream window size */\n maxWindowSize: number;\n /** Supported flow control algorithms */\n flowControlAlgorithms: string[];\n}\n\n/** Default streaming capabilities */\nexport const DEFAULT_STREAMING_CAPABILITIES: StreamingCapabilities = {\n standardStreams: true,\n bulkTransfer: true,\n realtimeStreams: true,\n maxConcurrentStreams: 100,\n maxWindowSize: 1048576, // 1MB\n flowControlAlgorithms: ['sliding-window', 'rate-based'],\n};\n\n/** Extended RPC connection options with streaming */\nexport interface StreamingRpcConnectionOptions extends RpcConnectionOptions {\n /** Stream manager configuration */\n streamManagerConfig?: Partial<StreamManagerConfig>;\n /** Stream manager event handlers */\n streamManagerHandlers?: StreamManagerHandlers;\n /** Local streaming capabilities */\n localCapabilities?: Partial<StreamingCapabilities>;\n /** Enable streaming support */\n enableStreaming?: boolean;\n}\n\n/**\n * Extended RPC connection with streaming support\n *\n * This class wraps RpcConnection and adds stream management capabilities.\n * It can be used as a drop-in replacement for RpcConnection.\n */\nexport class StreamingRpcConnection extends RpcConnection {\n private streamManager: StreamManager;\n private localCapabilities: StreamingCapabilities;\n private remoteCapabilities?: StreamingCapabilities;\n private streamingEnabled: boolean;\n\n constructor(transport: RpcTransport, options: StreamingRpcConnectionOptions = {}) {\n super(transport, options);\n\n this.streamingEnabled = options.enableStreaming ?? true;\n this.localCapabilities = { ...DEFAULT_STREAMING_CAPABILITIES, ...options.localCapabilities };\n\n // Create stream manager\n this.streamManager = new StreamManager(\n options.streamManagerConfig,\n options.streamManagerHandlers\n );\n\n // Attach to this connection\n this.streamManager.attach(this, transport);\n\n // Set up capability negotiation if streaming is enabled\n if (this.streamingEnabled) {\n this.negotiateCapabilities();\n }\n }\n\n /** Get the stream manager */\n get streams(): StreamManager {\n return this.streamManager;\n }\n\n /** Get local streaming capabilities */\n get capabilities(): StreamingCapabilities {\n return this.localCapabilities;\n }\n\n /** Get remote streaming capabilities (if negotiated) */\n get remoteStreamingCapabilities(): StreamingCapabilities | undefined {\n return this.remoteCapabilities;\n }\n\n /** Check if streaming is enabled */\n get isStreamingEnabled(): boolean {\n return this.streamingEnabled;\n }\n\n /**\n * Create a new standard stream\n */\n createStream(options?: CreateStreamOptions): Stream {\n this.ensureStreamingEnabled();\n return this.streamManager.createStream(options);\n }\n\n /**\n * Create a bulk transfer stream\n */\n createBulkTransfer(\n direction: 'upload' | 'download',\n metadata: BulkTransferMetadata,\n config?: Partial<BulkTransferConfig>,\n handlers?: BulkTransferHandlers\n ): BulkTransfer {\n this.ensureStreamingEnabled();\n this.ensureCapability('bulkTransfer');\n return this.streamManager.createBulkStream(direction, metadata, config, handlers);\n }\n\n /**\n * Create a realtime stream\n */\n createRealtimeStream(\n config?: Partial<RealtimeConfig>,\n handlers?: RealtimeStreamHandlers\n ): RealtimeStream {\n this.ensureStreamingEnabled();\n this.ensureCapability('realtimeStreams');\n return this.streamManager.createRealtimeStream(config, handlers);\n }\n\n /**\n * Get stream statistics\n */\n getStreamStatistics(): ReturnType<StreamManager['getStatistics']> {\n return this.streamManager.getStatistics();\n }\n\n /**\n * Close all streams gracefully\n */\n async closeAllStreams(): Promise<void> {\n await this.streamManager.closeAllStreams();\n }\n\n /**\n * Override stop to properly clean up streams\n */\n override async stop(): Promise<void> {\n await this.closeAllStreams();\n this.streamManager.detach();\n await super.stop();\n }\n\n // =============================================================================\n // Capability Negotiation\n // =============================================================================\n\n /**\n * Negotiate streaming capabilities with remote peer\n *\n * This would typically be done during bootstrap or connection setup.\n * For now, we assume the remote has the same capabilities.\n */\n private async negotiateCapabilities(): Promise<void> {\n // In a full implementation, this would exchange capability messages\n // with the remote peer during connection setup.\n\n // For now, assume remote has same capabilities\n this.remoteCapabilities = { ...this.localCapabilities };\n\n // TODO: Implement actual capability exchange via RPC\n }\n\n /**\n * Update remote capabilities (called when received from peer)\n */\n setRemoteCapabilities(capabilities: StreamingCapabilities): void {\n this.remoteCapabilities = capabilities;\n }\n\n /**\n * Check if a specific capability is supported by both peers\n */\n isCapabilitySupported(capability: keyof StreamingCapabilities): boolean {\n const localValue = this.localCapabilities[capability];\n const remoteValue = this.remoteCapabilities?.[capability];\n\n // For boolean capabilities, both must be true\n if (typeof localValue === 'boolean' && typeof remoteValue === 'boolean') {\n return localValue && remoteValue;\n }\n\n // For numeric capabilities, use the minimum\n if (typeof localValue === 'number' && typeof remoteValue === 'number') {\n return localValue > 0 && remoteValue > 0;\n }\n\n return false;\n }\n\n // =============================================================================\n // Integration with Pipeline\n // =============================================================================\n\n /**\n * Create a stream for pipeline results\n *\n * This allows large pipeline results to be streamed instead of buffered.\n */\n createPipelineStream(questionId: number, options?: CreateStreamOptions): Stream {\n this.ensureStreamingEnabled();\n\n const stream = this.createStream({\n ...options,\n type: StreamType.STANDARD,\n metadata: {\n ...options?.metadata,\n pipelineQuestionId: questionId.toString(),\n },\n });\n\n return stream;\n }\n\n /**\n * Associate a stream with a capability\n *\n * This enables streaming data to/from a capability.\n */\n associateStreamWithCapability(streamId: number, _importId: ImportId | ExportId): void {\n const stream = this.streamManager.getStream(streamId);\n if (!stream) {\n throw new Error(`Stream ${streamId} not found`);\n }\n\n // Store association (would be used by the RPC layer)\n // This is a simplified implementation\n }\n\n // =============================================================================\n // Private Methods\n // =============================================================================\n\n private ensureStreamingEnabled(): void {\n if (!this.streamingEnabled) {\n throw new Error('Streaming is not enabled on this connection');\n }\n }\n\n private ensureCapability(capability: keyof StreamingCapabilities): void {\n if (!this.isCapabilitySupported(capability)) {\n throw new Error(`Capability '${capability}' is not supported by both peers`);\n }\n }\n}\n\n/**\n * Create a streaming RPC connection\n */\nexport function createStreamingConnection(\n transport: RpcTransport,\n options?: StreamingRpcConnectionOptions\n): StreamingRpcConnection {\n return new StreamingRpcConnection(transport, options);\n}\n\n/**\n * Check if a connection supports streaming\n */\nexport function supportsStreaming(connection: RpcConnection): connection is StreamingRpcConnection {\n return connection instanceof StreamingRpcConnection;\n}\n\n// Re-export types from stream-manager\nexport type {\n StreamManager,\n StreamType,\n CreateStreamOptions,\n StreamManagerConfig,\n StreamManagerHandlers,\n Stream,\n BulkTransfer,\n RealtimeStream,\n};\n","/**\n * Phase 7: Dynamic Schema Reader\n *\n * This module provides runtime reading of Cap'n Proto messages using\n * dynamically loaded schema information. This allows reading messages\n * for types not known at compile time.\n */\n\nimport type { ListReader } from '../core/list.js';\nimport { MessageReader, type StructReader } from '../core/message-reader.js';\nimport { ElementSize } from '../core/pointer.js';\nimport type {\n SchemaField,\n SchemaNode,\n SchemaType,\n SchemaTypeKind,\n SchemaValue,\n} from './schema-types.js';\nimport { SchemaNodeType } from './schema-types.js';\n\n/**\n * Dynamic reader for Cap'n Proto messages\n * Provides runtime field access based on schema information\n */\nexport interface DynamicReader {\n /** Get a field value by name */\n get(fieldName: string): unknown;\n\n /** Check if a field exists */\n has(fieldName: string): boolean;\n\n /** Get all field names */\n getFieldNames(): string[];\n\n /** Get the underlying schema node */\n getSchema(): SchemaNode;\n\n /** Get nested struct reader */\n getStruct(fieldName: string): DynamicReader | undefined;\n\n /** Get list field */\n getList(fieldName: string): unknown[] | undefined;\n\n /** Get the raw StructReader */\n getRawReader(): StructReader;\n}\n\n/**\n * Create a dynamic reader from schema and buffer\n *\n * @param schema - The schema node describing the struct type\n * @param buffer - The Cap'n Proto message buffer\n * @returns A DynamicReader for accessing the message fields\n */\nexport function createDynamicReader(\n schema: SchemaNode,\n buffer: ArrayBuffer | Uint8Array\n): DynamicReader {\n const messageReader = new MessageReader(buffer);\n\n if (!schema.structInfo) {\n throw new Error(`Schema node ${schema.displayName} is not a struct`);\n }\n\n const { dataWordCount, pointerCount } = schema.structInfo;\n const structReader = messageReader.getRoot(dataWordCount, pointerCount);\n\n return new DynamicReaderImpl(schema, structReader, messageReader);\n}\n\n/**\n * Create a dynamic reader from an existing StructReader\n *\n * @param schema - The schema node describing the struct type\n * @param structReader - The StructReader to wrap\n * @param messageReader - The underlying MessageReader\n * @returns A DynamicReader for accessing the message fields\n */\nexport function createDynamicReaderFromStruct(\n schema: SchemaNode,\n structReader: StructReader,\n messageReader: MessageReader\n): DynamicReader {\n return new DynamicReaderImpl(schema, structReader, messageReader);\n}\n\n/**\n * Implementation of DynamicReader\n */\nclass DynamicReaderImpl implements DynamicReader {\n private fieldCache: Map<string, SchemaField>;\n private pointerOffset: number;\n\n constructor(\n private schema: SchemaNode,\n private structReader: StructReader,\n private messageReader: MessageReader\n ) {\n this.fieldCache = new Map();\n this.pointerOffset = schema.structInfo?.dataWordCount ?? 0;\n\n // Build field cache\n if (schema.structInfo?.fields) {\n for (const field of schema.structInfo.fields) {\n this.fieldCache.set(field.name, field);\n }\n }\n }\n\n get(fieldName: string): unknown {\n const field = this.fieldCache.get(fieldName);\n if (!field) {\n throw new Error(`Field '${fieldName}' not found in schema ${this.schema.displayName}`);\n }\n\n return this.readFieldValue(field);\n }\n\n has(fieldName: string): boolean {\n return this.fieldCache.has(fieldName);\n }\n\n getFieldNames(): string[] {\n return Array.from(this.fieldCache.keys());\n }\n\n getSchema(): SchemaNode {\n return this.schema;\n }\n\n getStruct(fieldName: string): DynamicReader | undefined {\n const field = this.fieldCache.get(fieldName);\n if (!field) {\n return undefined;\n }\n\n // Check if field is a struct type\n if (field.type.kind.type !== 'struct') {\n return undefined;\n }\n\n // Get the nested struct reader\n const pointerIndex = this.getPointerIndex(field);\n const nestedStruct = this.structReader.getStruct(pointerIndex, 0, 0);\n if (!nestedStruct) {\n return undefined;\n }\n\n // Note: We don't have the nested schema here, so we return a limited reader\n // In a full implementation, we'd look up the schema by typeId\n return new DynamicStructReaderWithoutSchema(nestedStruct, this.messageReader);\n }\n\n getList(fieldName: string): unknown[] | undefined {\n const field = this.fieldCache.get(fieldName);\n if (!field) {\n return undefined;\n }\n\n if (field.type.kind.type !== 'list') {\n return undefined;\n }\n\n const pointerIndex = this.getPointerIndex(field);\n const elementType = field.type.kind.elementType;\n\n return this.readListField(pointerIndex, elementType);\n }\n\n getRawReader(): StructReader {\n return this.structReader;\n }\n\n /**\n * Read a field value based on its type\n */\n private readFieldValue(field: SchemaField): unknown {\n const kind = field.type.kind;\n\n switch (kind.type) {\n case 'void':\n return undefined;\n case 'bool':\n return this.structReader.getBool(field.offset);\n case 'int8':\n return this.structReader.getInt8(field.offset);\n case 'int16':\n return this.structReader.getInt16(field.offset);\n case 'int32':\n return this.structReader.getInt32(field.offset);\n case 'int64':\n return this.structReader.getInt64(field.offset);\n case 'uint8':\n return this.structReader.getUint8(field.offset);\n case 'uint16':\n return this.structReader.getUint16(field.offset);\n case 'uint32':\n return this.structReader.getUint32(field.offset);\n case 'uint64':\n return this.structReader.getUint64(field.offset);\n case 'float32':\n return this.structReader.getFloat32(field.offset);\n case 'float64':\n return this.structReader.getFloat64(field.offset);\n case 'text':\n return this.readTextField(field);\n case 'data':\n return this.readDataField(field);\n case 'list':\n return this.readListFieldBySchema(field);\n case 'enum':\n return this.readEnumField(field);\n case 'struct':\n return this.readStructField(field);\n case 'interface':\n return this.readInterfaceField(field);\n case 'anyPointer':\n return this.readAnyPointerField(field);\n default:\n throw new Error(`Unsupported field type: ${(kind as SchemaTypeKind).type}`);\n }\n }\n\n /**\n * Get the pointer index for a field\n * In Cap'n Proto, pointer fields have offsets that start from 0 for the first pointer\n * The offset is measured in bits from the start of the data section\n * For pointer fields, offset = dataWordCount * 64 + pointerIndex * 64\n * So pointerIndex = (offset - dataWordCount * 64) / 64\n */\n private getPointerIndex(field: SchemaField): number {\n const dataSectionBits = (this.schema.structInfo?.dataWordCount ?? 0) * 64;\n // Pointer offset is measured from the start of the pointer section\n // Each pointer is 64 bits (1 word)\n const pointerIndex = (field.offset - dataSectionBits) / 64;\n return pointerIndex;\n }\n\n /**\n * Read a text field\n */\n private readTextField(field: SchemaField): string {\n const pointerIndex = this.getPointerIndex(field);\n return this.structReader.getText(pointerIndex);\n }\n\n /**\n * Read a data field\n */\n private readDataField(field: SchemaField): Uint8Array {\n const pointerIndex = this.getPointerIndex(field);\n // Data is stored similarly to text but without null terminator\n // For now, we use the same mechanism\n const text = this.structReader.getText(pointerIndex);\n return new TextEncoder().encode(text);\n }\n\n /**\n * Read a list field using schema information\n */\n private readListFieldBySchema(field: SchemaField): unknown[] {\n if (field.type.kind.type !== 'list') {\n throw new Error(`Field '${field.name}' is not a list type`);\n }\n\n const pointerIndex = this.getPointerIndex(field);\n const elementType = field.type.kind.elementType;\n\n return this.readListField(pointerIndex, elementType);\n }\n\n /**\n * Read a list field\n */\n private readListField(pointerIndex: number, elementType: SchemaType): unknown[] {\n // Map element type to ElementSize\n const elementSize = this.mapTypeToElementSize(elementType);\n\n const listReader = this.structReader.getList<unknown>(pointerIndex, elementSize);\n if (!listReader) {\n return [];\n }\n\n // Convert list reader to array\n const result: unknown[] = [];\n const length = listReader.length;\n\n for (let i = 0; i < length; i++) {\n result.push(this.readListElement(listReader, i, elementType));\n }\n\n return result;\n }\n\n /**\n * Map schema type to ElementSize\n */\n private mapTypeToElementSize(type: SchemaType): ElementSize {\n switch (type.kind.type) {\n case 'void':\n return ElementSize.VOID;\n case 'bool':\n return ElementSize.BIT;\n case 'int8':\n case 'uint8':\n return ElementSize.BYTE;\n case 'int16':\n case 'uint16':\n return ElementSize.TWO_BYTES;\n case 'int32':\n case 'uint32':\n case 'float32':\n return ElementSize.FOUR_BYTES;\n case 'int64':\n case 'uint64':\n case 'float64':\n return ElementSize.EIGHT_BYTES;\n case 'struct':\n return ElementSize.COMPOSITE;\n default:\n return ElementSize.POINTER;\n }\n }\n\n /**\n * Read a single list element\n */\n private readListElement(\n listReader: ListReader<unknown>,\n index: number,\n elementType: SchemaType\n ): unknown {\n const kind = elementType.kind;\n\n switch (kind.type) {\n case 'void':\n return undefined;\n case 'bool':\n return listReader.getPrimitive(index) !== 0;\n case 'int8':\n return listReader.getPrimitive(index);\n case 'int16':\n return listReader.getPrimitive(index);\n case 'int32':\n return listReader.getPrimitive(index);\n case 'int64':\n return listReader.getPrimitive(index);\n case 'uint8':\n return listReader.getPrimitive(index);\n case 'uint16':\n return listReader.getPrimitive(index);\n case 'uint32':\n return listReader.getPrimitive(index);\n case 'uint64':\n return listReader.getPrimitive(index);\n case 'float32':\n return listReader.getPrimitive(index);\n case 'float64':\n return listReader.getPrimitive(index);\n case 'struct': {\n const structReader = listReader.getStruct(index);\n if (!structReader) return undefined;\n // Return a wrapper without full schema\n return new DynamicStructReaderWithoutSchema(structReader, this.messageReader);\n }\n default:\n return undefined;\n }\n }\n\n /**\n * Read an enum field\n */\n private readEnumField(field: SchemaField): number {\n // Enums are stored as uint16\n return this.structReader.getUint16(field.offset);\n }\n\n /**\n * Read a struct field\n */\n private readStructField(field: SchemaField): DynamicReader | undefined {\n const pointerIndex = this.getPointerIndex(field);\n const nestedStruct = this.structReader.getStruct(pointerIndex, 0, 0);\n if (!nestedStruct) {\n return undefined;\n }\n\n // Without the nested schema, we return a limited reader\n return new DynamicStructReaderWithoutSchema(nestedStruct, this.messageReader);\n }\n\n /**\n * Read an interface field (capability)\n */\n private readInterfaceField(_field: SchemaField): unknown {\n // Capabilities are stored in the cap table\n // This would require access to the capability table\n throw new Error('Interface fields not yet supported in dynamic reader');\n }\n\n /**\n * Read an anyPointer field\n */\n private readAnyPointerField(_field: SchemaField): unknown {\n // anyPointer can be any type, requires runtime type detection\n throw new Error('anyPointer fields not yet supported in dynamic reader');\n }\n}\n\n/**\n * A limited dynamic reader for structs without schema information\n * Provides basic field access but no type information\n */\nclass DynamicStructReaderWithoutSchema implements DynamicReader {\n constructor(\n private structReader: StructReader,\n private messageReader: MessageReader\n ) {}\n\n get(_fieldName: string): unknown {\n throw new Error('Cannot access fields without schema information');\n }\n\n has(_fieldName: string): boolean {\n return false;\n }\n\n getFieldNames(): string[] {\n return [];\n }\n\n getSchema(): SchemaNode {\n throw new Error('No schema information available');\n }\n\n getStruct(_fieldName: string): DynamicReader | undefined {\n return undefined;\n }\n\n getList(_fieldName: string): unknown[] | undefined {\n return undefined;\n }\n\n getRawReader(): StructReader {\n return this.structReader;\n }\n}\n\n/**\n * Create a dynamic reader for a specific type ID\n * This looks up the schema in a registry and creates the appropriate reader\n *\n * @param typeId - The type ID of the struct\n * @param buffer - The Cap'n Proto message buffer\n * @param schemaRegistry - A map of type IDs to schema nodes\n * @returns A DynamicReader for the message\n */\nexport function createDynamicReaderByTypeId(\n typeId: bigint,\n buffer: ArrayBuffer | Uint8Array,\n schemaRegistry: Map<bigint, SchemaNode>\n): DynamicReader {\n const schema = schemaRegistry.get(typeId);\n if (!schema) {\n throw new Error(`Schema not found for type ID: ${typeId}`);\n }\n\n if (schema.type !== SchemaNodeType.STRUCT) {\n throw new Error(`Type ${typeId} is not a struct`);\n }\n\n return createDynamicReader(schema, buffer);\n}\n\n/**\n * Utility function to dump all fields from a dynamic reader\n * Useful for debugging and exploration\n *\n * @param reader - The DynamicReader to dump\n * @returns An object with all field names and values\n */\nexport function dumpDynamicReader(reader: DynamicReader): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const fieldName of reader.getFieldNames()) {\n try {\n result[fieldName] = reader.get(fieldName);\n } catch (error) {\n result[fieldName] = `<error: ${error}>`;\n }\n }\n\n return result;\n}\n","/**\n * Phase 7: Dynamic Schema Writer\n *\n * This module provides runtime writing of Cap'n Proto messages using\n * dynamically loaded schema information. This allows writing messages\n * for types not known at compile time.\n */\n\nimport type { ListBuilder } from '../core/list.js';\nimport { MessageBuilder, type StructBuilder } from '../core/message-builder.js';\nimport { ElementSize } from '../core/pointer.js';\nimport type { SchemaField, SchemaNode, SchemaType, SchemaValue } from './schema-types.js';\nimport { SchemaNodeType } from './schema-types.js';\n\n/**\n * Dynamic writer for Cap'n Proto messages\n * Provides runtime field setting based on schema information\n */\nexport interface DynamicWriter {\n /** Set a field value by name */\n set(fieldName: string, value: unknown): void;\n\n /** Set multiple fields at once */\n setFields(fields: Record<string, unknown>): void;\n\n /** Initialize a nested struct field */\n initStruct(fieldName: string): DynamicWriter;\n\n /** Initialize a list field */\n initList(fieldName: string, size: number): DynamicListWriter;\n\n /** Set a text field */\n setText(fieldName: string, value: string): void;\n\n /** Set a data field */\n setData(fieldName: string, value: Uint8Array): void;\n\n /** Get the underlying schema node */\n getSchema(): SchemaNode;\n\n /** Get the raw StructBuilder */\n getRawBuilder(): StructBuilder;\n\n /** Serialize the message to a buffer */\n toBuffer(): ArrayBuffer;\n}\n\n/**\n * Dynamic list writer\n * Provides runtime element setting for list fields\n */\nexport interface DynamicListWriter {\n /** Set an element at the specified index */\n set(index: number, value: unknown): void;\n\n /** Get the list size */\n getSize(): number;\n\n /** Initialize a nested struct element */\n initStruct(index: number): DynamicWriter;\n\n /** Set multiple elements at once */\n setAll(values: unknown[]): void;\n}\n\n/**\n * Create a dynamic writer from schema\n *\n * @param schema - The schema node describing the struct type\n * @returns A DynamicWriter for setting message fields\n */\nexport function createDynamicWriter(schema: SchemaNode): DynamicWriter {\n if (!schema.structInfo) {\n throw new Error(`Schema node ${schema.displayName} is not a struct`);\n }\n\n const { dataWordCount, pointerCount } = schema.structInfo;\n const messageBuilder = new MessageBuilder();\n const structBuilder = messageBuilder.initRoot(dataWordCount, pointerCount);\n\n return new DynamicWriterImpl(schema, structBuilder, messageBuilder);\n}\n\n/**\n * Create a dynamic writer for a nested struct\n *\n * @param schema - The schema node describing the struct type\n * @param structBuilder - The StructBuilder to wrap\n * @param messageBuilder - The underlying MessageBuilder\n * @returns A DynamicWriter for setting message fields\n */\nexport function createNestedDynamicWriter(\n schema: SchemaNode,\n structBuilder: StructBuilder,\n messageBuilder: MessageBuilder\n): DynamicWriter {\n return new DynamicWriterImpl(schema, structBuilder, messageBuilder);\n}\n\n/**\n * Implementation of DynamicWriter\n */\nclass DynamicWriterImpl implements DynamicWriter {\n private fieldCache: Map<string, SchemaField>;\n private pointerOffset: number;\n\n constructor(\n private schema: SchemaNode,\n private structBuilder: StructBuilder,\n private messageBuilder: MessageBuilder\n ) {\n this.fieldCache = new Map();\n this.pointerOffset = schema.structInfo?.dataWordCount ?? 0;\n\n // Build field cache\n if (schema.structInfo?.fields) {\n for (const field of schema.structInfo.fields) {\n this.fieldCache.set(field.name, field);\n }\n }\n }\n\n set(fieldName: string, value: unknown): void {\n const field = this.fieldCache.get(fieldName);\n if (!field) {\n throw new Error(`Field '${fieldName}' not found in schema ${this.schema.displayName}`);\n }\n\n this.writeFieldValue(field, value);\n }\n\n setFields(fields: Record<string, unknown>): void {\n for (const [name, value] of Object.entries(fields)) {\n this.set(name, value);\n }\n }\n\n initStruct(fieldName: string): DynamicWriter {\n const field = this.fieldCache.get(fieldName);\n if (!field) {\n throw new Error(`Field '${fieldName}' not found in schema ${this.schema.displayName}`);\n }\n\n if (field.type.kind.type !== 'struct') {\n throw new Error(`Field '${fieldName}' is not a struct type`);\n }\n\n // For nested structs, we need the nested schema\n // Since we don't have it here, we'll create a placeholder\n const pointerIndex = this.getPointerIndex(field);\n const nestedBuilder = this.structBuilder.initStruct(pointerIndex, 0, 0);\n\n // Return a writer without schema - limited functionality\n return new DynamicWriterWithoutSchema(nestedBuilder, this.messageBuilder);\n }\n\n initList(fieldName: string, size: number): DynamicListWriter {\n const field = this.fieldCache.get(fieldName);\n if (!field) {\n throw new Error(`Field '${fieldName}' not found in schema ${this.schema.displayName}`);\n }\n\n if (field.type.kind.type !== 'list') {\n throw new Error(`Field '${fieldName}' is not a list type`);\n }\n\n const pointerIndex = this.getPointerIndex(field);\n const elementType = field.type.kind.elementType;\n\n return this.createListWriter(pointerIndex, size, elementType);\n }\n\n setText(fieldName: string, value: string): void {\n const field = this.fieldCache.get(fieldName);\n if (!field) {\n throw new Error(`Field '${fieldName}' not found in schema ${this.schema.displayName}`);\n }\n\n if (field.type.kind.type !== 'text') {\n throw new Error(`Field '${fieldName}' is not a text type`);\n }\n\n const pointerIndex = this.getPointerIndex(field);\n this.structBuilder.setText(pointerIndex, value);\n }\n\n setData(fieldName: string, value: Uint8Array): void {\n const field = this.fieldCache.get(fieldName);\n if (!field) {\n throw new Error(`Field '${fieldName}' not found in schema ${this.schema.displayName}`);\n }\n\n if (field.type.kind.type !== 'data') {\n throw new Error(`Field '${fieldName}' is not a data type`);\n }\n\n // Data is stored similarly to text but as bytes\n const pointerIndex = this.getPointerIndex(field);\n const textValue = new TextDecoder().decode(value);\n this.structBuilder.setText(pointerIndex, `${textValue}\\0`);\n }\n\n getSchema(): SchemaNode {\n return this.schema;\n }\n\n getRawBuilder(): StructBuilder {\n return this.structBuilder;\n }\n\n toBuffer(): ArrayBuffer {\n return this.messageBuilder.toArrayBuffer();\n }\n\n /**\n * Write a field value based on its type\n */\n private writeFieldValue(field: SchemaField, value: unknown): void {\n const kind = field.type.kind;\n\n switch (kind.type) {\n case 'void':\n // Void fields don't store any data\n break;\n case 'bool':\n this.structBuilder.setBool(field.offset, Boolean(value));\n break;\n case 'int8':\n this.structBuilder.setInt8(field.offset, Number(value));\n break;\n case 'int16':\n this.structBuilder.setInt16(field.offset, Number(value));\n break;\n case 'int32':\n this.structBuilder.setInt32(field.offset, Number(value));\n break;\n case 'int64':\n this.structBuilder.setInt64(field.offset, BigInt(value as string | number | bigint));\n break;\n case 'uint8':\n this.structBuilder.setUint8(field.offset, Number(value));\n break;\n case 'uint16':\n this.structBuilder.setUint16(field.offset, Number(value));\n break;\n case 'uint32':\n this.structBuilder.setUint32(field.offset, Number(value));\n break;\n case 'uint64':\n this.structBuilder.setUint64(field.offset, BigInt(value as string | number | bigint));\n break;\n case 'float32':\n this.structBuilder.setFloat32(field.offset, Number(value));\n break;\n case 'float64':\n this.structBuilder.setFloat64(field.offset, Number(value));\n break;\n case 'text':\n this.setText(field.name, String(value));\n break;\n case 'data':\n if (value instanceof Uint8Array) {\n this.setData(field.name, value);\n } else {\n throw new Error(`Field '${field.name}' expects Uint8Array`);\n }\n break;\n case 'list':\n if (Array.isArray(value)) {\n const listWriter = this.initList(field.name, value.length);\n listWriter.setAll(value);\n } else {\n throw new Error(`Field '${field.name}' expects an array`);\n }\n break;\n case 'enum':\n this.structBuilder.setUint16(field.offset, Number(value));\n break;\n case 'struct':\n if (typeof value === 'object' && value !== null) {\n const structWriter = this.initStruct(field.name);\n // If value is a record, set its fields\n if (!(value instanceof Uint8Array) && !Array.isArray(value)) {\n structWriter.setFields(value as Record<string, unknown>);\n }\n } else {\n throw new Error(`Field '${field.name}' expects an object`);\n }\n break;\n case 'interface':\n throw new Error('Interface fields not yet supported in dynamic writer');\n case 'anyPointer':\n throw new Error('anyPointer fields not yet supported in dynamic writer');\n default:\n throw new Error(`Unsupported field type: ${(kind as { type: string }).type}`);\n }\n }\n\n /**\n * Get the pointer index for a field\n * In Cap'n Proto, pointer fields have offsets that start from 0 for the first pointer\n * The offset is measured in bits from the start of the data section\n * For pointer fields, offset = dataWordCount * 64 + pointerIndex * 64\n * So pointerIndex = (offset - dataWordCount * 64) / 64\n */\n private getPointerIndex(field: SchemaField): number {\n const dataSectionBits = (this.schema.structInfo?.dataWordCount ?? 0) * 64;\n // Pointer offset is measured from the start of the pointer section\n // Each pointer is 64 bits (1 word)\n const pointerIndex = (field.offset - dataSectionBits) / 64;\n return pointerIndex;\n }\n\n /**\n * Create a list writer for a field\n */\n private createListWriter(\n pointerIndex: number,\n size: number,\n elementType: SchemaType\n ): DynamicListWriter {\n // Map element type to ElementSize\n const elementSize = this.mapTypeToElementSize(elementType);\n\n let structSize: { dataWords: number; pointerCount: number } | undefined;\n if (elementSize === ElementSize.COMPOSITE) {\n // For composite types, we need struct size info\n // Default to 0,0 if not available\n structSize = { dataWords: 0, pointerCount: 0 };\n }\n\n const listBuilder = this.structBuilder.initList<unknown>(\n pointerIndex,\n elementSize,\n size,\n structSize\n );\n\n return new DynamicListWriterImpl(listBuilder, elementType, this.messageBuilder);\n }\n\n /**\n * Map schema type to ElementSize\n */\n private mapTypeToElementSize(type: SchemaType): ElementSize {\n switch (type.kind.type) {\n case 'void':\n return ElementSize.VOID;\n case 'bool':\n return ElementSize.BIT;\n case 'int8':\n case 'uint8':\n return ElementSize.BYTE;\n case 'int16':\n case 'uint16':\n return ElementSize.TWO_BYTES;\n case 'int32':\n case 'uint32':\n case 'float32':\n return ElementSize.FOUR_BYTES;\n case 'int64':\n case 'uint64':\n case 'float64':\n return ElementSize.EIGHT_BYTES;\n case 'struct':\n return ElementSize.COMPOSITE;\n default:\n return ElementSize.POINTER;\n }\n }\n}\n\n/**\n * Implementation of DynamicListWriter\n */\nclass DynamicListWriterImpl implements DynamicListWriter {\n constructor(\n private listBuilder: ListBuilder<unknown>,\n private elementType: SchemaType,\n private messageBuilder: MessageBuilder\n ) {}\n\n set(index: number, value: unknown): void {\n if (index < 0 || index >= this.listBuilder.length) {\n throw new Error(`Index ${index} out of bounds`);\n }\n\n const kind = this.elementType.kind;\n\n switch (kind.type) {\n case 'void':\n // Nothing to set for void\n break;\n case 'bool':\n this.listBuilder.setPrimitive(index, value ? 1 : 0);\n break;\n case 'int8':\n case 'uint8':\n case 'int16':\n case 'uint16':\n case 'int32':\n case 'uint32':\n case 'float32':\n this.listBuilder.setPrimitive(index, Number(value));\n break;\n case 'int64':\n case 'uint64':\n case 'float64':\n this.listBuilder.setPrimitive(index, BigInt(value as string | number | bigint));\n break;\n case 'struct':\n // For struct lists, value should be an object to set fields\n if (typeof value === 'object' && value !== null && !(value instanceof Uint8Array)) {\n const structWriter = this.initStruct(index);\n structWriter.setFields(value as Record<string, unknown>);\n }\n break;\n default:\n throw new Error(`Unsupported list element type: ${kind.type}`);\n }\n }\n\n getSize(): number {\n return this.listBuilder.length;\n }\n\n getLength(): number {\n return this.listBuilder.length;\n }\n\n initStruct(index: number): DynamicWriter {\n const structBuilder = this.listBuilder.getStruct(index);\n return new DynamicWriterWithoutSchema(structBuilder, this.messageBuilder);\n }\n\n setAll(values: unknown[]): void {\n if (values.length > this.getSize()) {\n throw new Error(`Cannot set ${values.length} values in list of size ${this.getSize()}`);\n }\n\n for (let i = 0; i < values.length; i++) {\n this.set(i, values[i]);\n }\n }\n}\n\n/**\n * A limited dynamic writer for structs without full schema information\n * Provides basic field setting but no type validation\n */\nclass DynamicWriterWithoutSchema implements DynamicWriter {\n constructor(\n private structBuilder: StructBuilder,\n private messageBuilder: MessageBuilder\n ) {}\n\n set(fieldName: string, _value: unknown): void {\n // Without schema, we can only support basic operations\n // This is a placeholder that could be extended\n throw new Error(`Cannot set field '${fieldName}' without schema information`);\n }\n\n setFields(_fields: Record<string, unknown>): void {\n throw new Error('Cannot set fields without schema information');\n }\n\n initStruct(_fieldName: string): DynamicWriter {\n throw new Error('Cannot init struct without schema information');\n }\n\n initList(_fieldName: string, _size: number): DynamicListWriter {\n throw new Error('Cannot init list without schema information');\n }\n\n setText(_fieldName: string, _value: string): void {\n throw new Error('Cannot set text without schema information');\n }\n\n setData(_fieldName: string, _value: Uint8Array): void {\n throw new Error('Cannot set data without schema information');\n }\n\n getSchema(): SchemaNode {\n throw new Error('No schema information available');\n }\n\n getRawBuilder(): StructBuilder {\n return this.structBuilder;\n }\n\n toBuffer(): ArrayBuffer {\n return this.messageBuilder.toArrayBuffer();\n }\n}\n\n/**\n * Create a dynamic writer for a specific type ID\n * This looks up the schema in a registry and creates the appropriate writer\n *\n * @param typeId - The type ID of the struct\n * @param schemaRegistry - A map of type IDs to schema nodes\n * @returns A DynamicWriter for the message\n */\nexport function createDynamicWriterByTypeId(\n typeId: bigint,\n schemaRegistry: Map<bigint, SchemaNode>\n): DynamicWriter {\n const schema = schemaRegistry.get(typeId);\n if (!schema) {\n throw new Error(`Schema not found for type ID: ${typeId}`);\n }\n\n if (schema.type !== SchemaNodeType.STRUCT) {\n throw new Error(`Type ${typeId} is not a struct`);\n }\n\n return createDynamicWriter(schema);\n}\n\n/**\n * Utility function to create a message from a plain object\n * Uses schema information to properly serialize the data\n *\n * @param schema - The schema node describing the struct type\n * @param data - The data object to serialize\n * @returns The serialized message buffer\n */\nexport function serializeDynamic(schema: SchemaNode, data: Record<string, unknown>): ArrayBuffer {\n const writer = createDynamicWriter(schema);\n writer.setFields(data);\n return writer.toBuffer();\n}\n\n/**\n * Utility function to create a message from a plain object using type ID\n *\n * @param typeId - The type ID of the struct\n * @param data - The data object to serialize\n * @param schemaRegistry - A map of type IDs to schema nodes\n * @returns The serialized message buffer\n */\nexport function serializeDynamicByTypeId(\n typeId: bigint,\n data: Record<string, unknown>,\n schemaRegistry: Map<bigint, SchemaNode>\n): ArrayBuffer {\n const writer = createDynamicWriterByTypeId(typeId, schemaRegistry);\n writer.setFields(data);\n return writer.toBuffer();\n}\n","/**\n * Phase 7: Schema Capability Implementation\n *\n * Implements the SchemaCapability interface defined in rpc.capnp\n * Provides server-side schema serving and client-side schema fetching\n */\n\nimport type { RpcConnection } from './rpc-connection.js';\nimport { createSchemaRegistry, parseSchemaNodes } from './schema-parser.js';\nimport {\n deserializeSchemaRequest,\n serializeGetSchemaResults,\n serializeListSchemasResults,\n serializeSchemaResponse,\n} from './schema-serializer.js';\nimport type {\n AvailableSchema,\n GetSchemaParams,\n GetSchemaResults,\n ListSchemasResults,\n SchemaNode,\n SchemaPayload,\n SchemaTarget,\n} from './schema-types.js';\nimport { SchemaFormat, SchemaNodeType } from './schema-types.js';\n\n// ============================================================================\n// Schema Capability Server\n// ============================================================================\n\n/**\n * Server-side implementation of the SchemaCapability interface.\n * Provides schema information to remote clients.\n */\nexport class SchemaCapabilityServer {\n private registry: Map<bigint, SchemaNode>;\n private schemasByName: Map<string, SchemaNode>;\n\n /**\n * Create a new SchemaCapabilityServer\n * @param initialSchemas - Optional map of schemas to register initially\n */\n constructor(initialSchemas?: Map<bigint, SchemaNode>) {\n this.registry = new Map(initialSchemas);\n this.schemasByName = new Map();\n\n // Build name index\n for (const schema of this.registry.values()) {\n this.schemasByName.set(schema.displayName, schema);\n }\n }\n\n /**\n * Register a schema node\n * @param node - The schema node to register\n */\n registerSchema(node: SchemaNode): void {\n this.registry.set(node.id, node);\n this.schemasByName.set(node.displayName, node);\n }\n\n /**\n * Unregister a schema by ID\n * @param typeId - The type ID to unregister\n */\n unregisterSchema(typeId: bigint): void {\n const node = this.registry.get(typeId);\n if (node) {\n this.registry.delete(typeId);\n this.schemasByName.delete(node.displayName);\n }\n }\n\n /**\n * Get schema information based on target specification\n * @param params - GetSchemaParams containing target and format\n * @returns GetSchemaResults with the schema payload\n */\n async getSchema(params: GetSchemaParams): Promise<GetSchemaResults> {\n const { target, format = SchemaFormat.BINARY } = params;\n\n let schemaData: Uint8Array;\n let dependencies: Array<{ fileId: bigint; fileName: string; schemaHash?: Uint8Array }> = [];\n\n switch (target.type) {\n case 'byTypeId': {\n const node = this.registry.get(target.typeId);\n if (!node) {\n throw new Error(`Schema not found for type ID: ${target.typeId.toString(16)}`);\n }\n schemaData = this.serializeSchemaNode(node, format);\n dependencies = this.collectDependencies(node);\n break;\n }\n\n case 'byTypeName': {\n const node = this.schemasByName.get(target.typeName);\n if (!node) {\n throw new Error(`Schema not found for type name: ${target.typeName}`);\n }\n schemaData = this.serializeSchemaNode(node, format);\n dependencies = this.collectDependencies(node);\n break;\n }\n\n case 'byFileId': {\n // Get all schemas in a file\n const nodes = this.getSchemasByFileId(target.fileId);\n schemaData = this.serializeSchemaNodes(nodes, format);\n break;\n }\n\n case 'byFileName': {\n // Get all schemas in a file by name\n const nodes = this.getSchemasByFileName(target.fileName);\n schemaData = this.serializeSchemaNodes(nodes, format);\n break;\n }\n\n case 'allSchemas': {\n // Get all schemas\n const nodes = Array.from(this.registry.values());\n schemaData = this.serializeSchemaNodes(nodes, format);\n break;\n }\n\n case 'bootstrapInterface': {\n // Get bootstrap interface schema (if available)\n const bootstrapSchema = this.findBootstrapSchema();\n if (!bootstrapSchema) {\n throw new Error('Bootstrap interface schema not available');\n }\n schemaData = this.serializeSchemaNode(bootstrapSchema, format);\n dependencies = this.collectDependencies(bootstrapSchema);\n break;\n }\n\n default:\n throw new Error(`Unsupported schema target type: ${(target as SchemaTarget).type}`);\n }\n\n return {\n payload: {\n schemaData,\n format,\n dependencies,\n },\n };\n }\n\n /**\n * List all available schemas\n * @returns ListSchemasResults with available schema information\n */\n async listAvailableSchemas(): Promise<ListSchemasResults> {\n const schemas: AvailableSchema[] = [];\n\n for (const node of this.registry.values()) {\n schemas.push({\n typeId: node.id,\n displayName: node.displayName,\n fileId: node.scopeId, // Using scopeId as fileId proxy\n fileName: this.inferFileName(node),\n isInterface: node.type === SchemaNodeType.INTERFACE,\n isStruct: node.type === SchemaNodeType.STRUCT,\n isEnum: node.type === SchemaNodeType.ENUM,\n });\n }\n\n return { schemas };\n }\n\n /**\n * Handle a raw schema request (for RPC integration)\n * @param requestData - The serialized SchemaRequest\n * @returns The serialized SchemaResponse\n */\n handleRequest(requestData: Uint8Array): Uint8Array {\n try {\n const request = deserializeSchemaRequest(requestData);\n\n const _result = this.getSchema({\n target: request.targetSchema,\n });\n\n // Since getSchema is async, we need to handle the promise\n // In a real implementation, this would be properly async\n throw new Error('Async handling not implemented in handleRequest');\n } catch (error) {\n // Return error response\n const errorResponse = {\n answerId: 0,\n result: {\n type: 'exception' as const,\n exception: {\n reason: error instanceof Error ? error.message : 'Unknown error',\n type: 'failed' as const,\n obsoleteIsCallersFault: false,\n obsoleteDurability: 0,\n },\n },\n };\n\n return serializeSchemaResponse(errorResponse);\n }\n }\n\n /**\n * Get the number of registered schemas\n */\n getSchemaCount(): number {\n return this.registry.size;\n }\n\n /**\n * Check if a schema is registered\n */\n hasSchema(typeId: bigint): boolean {\n return this.registry.has(typeId);\n }\n\n // --------------------------------------------------------------------------\n // Private Helper Methods\n // --------------------------------------------------------------------------\n\n private serializeSchemaNode(node: SchemaNode, format: SchemaFormat): Uint8Array {\n switch (format) {\n case SchemaFormat.BINARY:\n return this.serializeToBinary([node]);\n case SchemaFormat.JSON:\n return this.serializeToJson([node]);\n case SchemaFormat.CAPNP:\n return this.serializeToCapnp([node]);\n default:\n throw new Error(`Unsupported schema format: ${format}`);\n }\n }\n\n private serializeSchemaNodes(nodes: SchemaNode[], format: SchemaFormat): Uint8Array {\n switch (format) {\n case SchemaFormat.BINARY:\n return this.serializeToBinary(nodes);\n case SchemaFormat.JSON:\n return this.serializeToJson(nodes);\n case SchemaFormat.CAPNP:\n return this.serializeToCapnp(nodes);\n default:\n throw new Error(`Unsupported schema format: ${format}`);\n }\n }\n\n private serializeToBinary(nodes: SchemaNode[]): Uint8Array {\n // Simplified binary serialization\n // In a full implementation, this would serialize to the actual Cap'n Proto format\n const encoder = new TextEncoder();\n const json = JSON.stringify(nodes, (_key, value) => {\n if (typeof value === 'bigint') {\n return value.toString();\n }\n return value;\n });\n return encoder.encode(json);\n }\n\n private serializeToJson(nodes: SchemaNode[]): Uint8Array {\n const encoder = new TextEncoder();\n const json = JSON.stringify({\n nodes: nodes.map((node) => ({\n id: node.id.toString(),\n displayName: node.displayName,\n displayNamePrefixLength: node.displayNamePrefixLength,\n scopeId: node.scopeId.toString(),\n type: node.type,\n structInfo: node.structInfo,\n enumInfo: node.enumInfo,\n interfaceInfo: node.interfaceInfo,\n })),\n });\n return encoder.encode(json);\n }\n\n private serializeToCapnp(nodes: SchemaNode[]): Uint8Array {\n // Placeholder for actual Cap'n Proto schema language serialization\n // This would generate .capnp source code from the schema nodes\n const lines: string[] = [];\n\n for (const node of nodes) {\n if (node.structInfo) {\n lines.push(`struct ${node.displayName} {`);\n for (const field of node.structInfo.fields) {\n lines.push(` ${field.name} @${field.codeOrder} :${this.typeToCapnp(field.type)};`);\n }\n lines.push('}');\n }\n }\n\n return new TextEncoder().encode(lines.join('\\n'));\n }\n\n private typeToCapnp(type: { kind: { type: string } }): string {\n const kind = type.kind;\n switch (kind.type) {\n case 'void':\n return 'Void';\n case 'bool':\n return 'Bool';\n case 'int8':\n return 'Int8';\n case 'int16':\n return 'Int16';\n case 'int32':\n return 'Int32';\n case 'int64':\n return 'Int64';\n case 'uint8':\n return 'UInt8';\n case 'uint16':\n return 'UInt16';\n case 'uint32':\n return 'UInt32';\n case 'uint64':\n return 'UInt64';\n case 'float32':\n return 'Float32';\n case 'float64':\n return 'Float64';\n case 'text':\n return 'Text';\n case 'data':\n return 'Data';\n case 'list':\n return 'List';\n case 'enum':\n return 'UInt16';\n case 'struct':\n return 'AnyPointer';\n case 'interface':\n return 'Capability';\n default:\n return 'AnyPointer';\n }\n }\n\n private collectDependencies(\n _node: SchemaNode\n ): Array<{ fileId: bigint; fileName: string; schemaHash?: Uint8Array }> {\n // In a full implementation, this would analyze the schema and collect\n // all imported schema dependencies\n return [];\n }\n\n private getSchemasByFileId(fileId: bigint): SchemaNode[] {\n return Array.from(this.registry.values()).filter((node) => node.scopeId === fileId);\n }\n\n private getSchemasByFileName(fileName: string): SchemaNode[] {\n // Infer file name from display name prefix\n return Array.from(this.registry.values()).filter((node) => {\n const inferredFileName = this.inferFileName(node);\n return inferredFileName === fileName || node.displayName.startsWith(fileName);\n });\n }\n\n private inferFileName(node: SchemaNode): string {\n // Infer file name from display name\n // e.g., \"foo.bar.MyStruct\" -> \"foo/bar.capnp\"\n const parts = node.displayName.split('.');\n if (parts.length > 1) {\n return `${parts.slice(0, -1).join('/')}.capnp`;\n }\n return 'unknown.capnp';\n }\n\n private findBootstrapSchema(): SchemaNode | undefined {\n // Look for a schema that might be the bootstrap interface\n // This is a heuristic - in practice, the bootstrap interface would be\n // explicitly registered\n for (const node of this.registry.values()) {\n if (node.type === SchemaNodeType.INTERFACE) {\n return node;\n }\n }\n return undefined;\n }\n}\n\n// ============================================================================\n// Schema Capability Client\n// ============================================================================\n\n/**\n * Client-side implementation for accessing remote SchemaCapability\n */\nexport class SchemaCapabilityClient {\n private connection: RpcConnection;\n\n /**\n * Create a new SchemaCapabilityClient\n * @param connection - The RPC connection to use\n */\n constructor(connection: RpcConnection) {\n this.connection = connection;\n }\n\n /**\n * Fetch schema information from the remote server\n * @param target - The schema target specification\n * @param format - The desired format (defaults to BINARY)\n * @returns The schema node\n */\n async getSchema(\n target: SchemaTarget,\n format: SchemaFormat = SchemaFormat.BINARY\n ): Promise<SchemaNode> {\n // Use the connection's getDynamicSchema method for type ID lookups\n if (target.type === 'byTypeId') {\n return this.connection.getDynamicSchema(target.typeId);\n }\n\n // For other target types, we need to use the schema capability interface\n // This is a simplified implementation\n const _params: GetSchemaParams = { target, format };\n\n // In a full implementation, this would make an RPC call to the schema capability\n // For now, we delegate to the connection's method\n if (target.type === 'byTypeName') {\n return this.connection.getDynamicSchemaByName(target.typeName);\n }\n\n throw new Error(`Schema target type not implemented: ${target.type}`);\n }\n\n /**\n * Fetch schema by type ID\n * @param typeId - The type ID\n * @returns The schema node\n */\n async getSchemaById(typeId: bigint): Promise<SchemaNode> {\n return this.connection.getDynamicSchema(typeId);\n }\n\n /**\n * Fetch schema by type name\n * @param typeName - The fully qualified type name\n * @returns The schema node\n */\n async getSchemaByName(typeName: string): Promise<SchemaNode> {\n return this.connection.getDynamicSchemaByName(typeName);\n }\n\n /**\n * List all available schemas from the remote server\n * @returns Array of available schema information\n */\n async listAvailableSchemas(): Promise<AvailableSchema[]> {\n const schemas = await this.connection.listAvailableSchemas();\n return schemas.map((s) => ({\n typeId: s.typeId,\n displayName: s.displayName,\n fileId: BigInt(0), // Not provided by connection method\n fileName: '', // Not provided by connection method\n isInterface: false, // Not provided by connection method\n isStruct: true,\n isEnum: false,\n }));\n }\n\n /**\n * Fetch multiple schemas at once\n * @param typeIds - Array of type IDs to fetch\n * @returns Map of type ID to schema node\n */\n async getSchemas(typeIds: bigint[]): Promise<Map<bigint, SchemaNode>> {\n const results = new Map<bigint, SchemaNode>();\n\n // Fetch schemas in parallel\n await Promise.all(\n typeIds.map(async (typeId) => {\n try {\n const schema = await this.getSchemaById(typeId);\n results.set(typeId, schema);\n } catch (error) {\n console.warn(`Failed to fetch schema ${typeId.toString(16)}:`, error);\n }\n })\n );\n\n return results;\n }\n\n /**\n * Check if a schema is available on the remote server\n * @param typeId - The type ID to check\n * @returns True if the schema is available\n */\n async hasSchema(typeId: bigint): Promise<boolean> {\n try {\n await this.getSchemaById(typeId);\n return true;\n } catch {\n return false;\n }\n }\n}\n\n// ============================================================================\n// Schema Provider Registration Helper\n// ============================================================================\n\n// Note: RpcConnection.registerSchemaProvider is defined in rpc-connection.ts\n// to avoid circular imports. This file only defines the SchemaCapabilityServer\n// and SchemaCapabilityClient classes.\n"],"mappings":"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"}