@naeemo/capnp 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_rpc_connection = require('./rpc-connection-BKWQQ7f9.js');
2
+ const require_rpc_connection = require('./rpc-connection-CnyIwb0Z.js');
3
3
 
4
4
  //#region src/core/pointer.ts
5
5
  /**
@@ -2306,7 +2306,7 @@ var ConnectionManager = class {
2306
2306
  }
2307
2307
  }
2308
2308
  async doEstablishConnection(vatId, address) {
2309
- const { RpcConnection } = await Promise.resolve().then(() => require("./rpc-connection-BKWQQ7f9.js")).then((n) => n.rpc_connection_exports);
2309
+ const { RpcConnection } = await Promise.resolve().then(() => require("./rpc-connection-CnyIwb0Z.js")).then((n) => n.rpc_connection_exports);
2310
2310
  const connection = new RpcConnection(await this.options.connectionFactory(vatId, address), this.options.connectionOptions);
2311
2311
  await connection.start();
2312
2312
  this.registerConnection(vatId, connection);
@@ -4901,6 +4901,934 @@ function supportsStreaming(connection) {
4901
4901
  return connection instanceof StreamingRpcConnection;
4902
4902
  }
4903
4903
 
4904
+ //#endregion
4905
+ //#region src/rpc/dynamic-reader.ts
4906
+ /**
4907
+ * Create a dynamic reader from schema and buffer
4908
+ *
4909
+ * @param schema - The schema node describing the struct type
4910
+ * @param buffer - The Cap'n Proto message buffer
4911
+ * @returns A DynamicReader for accessing the message fields
4912
+ */
4913
+ function createDynamicReader(schema, buffer) {
4914
+ const messageReader = new MessageReader(buffer);
4915
+ if (!schema.structInfo) throw new Error(`Schema node ${schema.displayName} is not a struct`);
4916
+ const { dataWordCount, pointerCount } = schema.structInfo;
4917
+ return new DynamicReaderImpl(schema, messageReader.getRoot(dataWordCount, pointerCount), messageReader);
4918
+ }
4919
+ /**
4920
+ * Create a dynamic reader from an existing StructReader
4921
+ *
4922
+ * @param schema - The schema node describing the struct type
4923
+ * @param structReader - The StructReader to wrap
4924
+ * @param messageReader - The underlying MessageReader
4925
+ * @returns A DynamicReader for accessing the message fields
4926
+ */
4927
+ function createDynamicReaderFromStruct(schema, structReader, messageReader) {
4928
+ return new DynamicReaderImpl(schema, structReader, messageReader);
4929
+ }
4930
+ /**
4931
+ * Implementation of DynamicReader
4932
+ */
4933
+ var DynamicReaderImpl = class {
4934
+ fieldCache;
4935
+ pointerOffset;
4936
+ constructor(schema, structReader, messageReader) {
4937
+ this.schema = schema;
4938
+ this.structReader = structReader;
4939
+ this.messageReader = messageReader;
4940
+ this.fieldCache = /* @__PURE__ */ new Map();
4941
+ this.pointerOffset = schema.structInfo?.dataWordCount ?? 0;
4942
+ if (schema.structInfo?.fields) for (const field of schema.structInfo.fields) this.fieldCache.set(field.name, field);
4943
+ }
4944
+ get(fieldName) {
4945
+ const field = this.fieldCache.get(fieldName);
4946
+ if (!field) throw new Error(`Field '${fieldName}' not found in schema ${this.schema.displayName}`);
4947
+ return this.readFieldValue(field);
4948
+ }
4949
+ has(fieldName) {
4950
+ return this.fieldCache.has(fieldName);
4951
+ }
4952
+ getFieldNames() {
4953
+ return Array.from(this.fieldCache.keys());
4954
+ }
4955
+ getSchema() {
4956
+ return this.schema;
4957
+ }
4958
+ getStruct(fieldName) {
4959
+ const field = this.fieldCache.get(fieldName);
4960
+ if (!field) return;
4961
+ if (field.type.kind.type !== "struct") return;
4962
+ const pointerIndex = this.getPointerIndex(field);
4963
+ const nestedStruct = this.structReader.getStruct(pointerIndex, 0, 0);
4964
+ if (!nestedStruct) return;
4965
+ return new DynamicStructReaderWithoutSchema(nestedStruct, this.messageReader);
4966
+ }
4967
+ getList(fieldName) {
4968
+ const field = this.fieldCache.get(fieldName);
4969
+ if (!field) return;
4970
+ if (field.type.kind.type !== "list") return;
4971
+ const pointerIndex = this.getPointerIndex(field);
4972
+ const elementType = field.type.kind.elementType;
4973
+ return this.readListField(pointerIndex, elementType);
4974
+ }
4975
+ getRawReader() {
4976
+ return this.structReader;
4977
+ }
4978
+ /**
4979
+ * Read a field value based on its type
4980
+ */
4981
+ readFieldValue(field) {
4982
+ const kind = field.type.kind;
4983
+ switch (kind.type) {
4984
+ case "void": return;
4985
+ case "bool": return this.structReader.getBool(field.offset);
4986
+ case "int8": return this.structReader.getInt8(field.offset);
4987
+ case "int16": return this.structReader.getInt16(field.offset);
4988
+ case "int32": return this.structReader.getInt32(field.offset);
4989
+ case "int64": return this.structReader.getInt64(field.offset);
4990
+ case "uint8": return this.structReader.getUint8(field.offset);
4991
+ case "uint16": return this.structReader.getUint16(field.offset);
4992
+ case "uint32": return this.structReader.getUint32(field.offset);
4993
+ case "uint64": return this.structReader.getUint64(field.offset);
4994
+ case "float32": return this.structReader.getFloat32(field.offset);
4995
+ case "float64": return this.structReader.getFloat64(field.offset);
4996
+ case "text": return this.readTextField(field);
4997
+ case "data": return this.readDataField(field);
4998
+ case "list": return this.readListFieldBySchema(field);
4999
+ case "enum": return this.readEnumField(field);
5000
+ case "struct": return this.readStructField(field);
5001
+ case "interface": return this.readInterfaceField(field);
5002
+ case "anyPointer": return this.readAnyPointerField(field);
5003
+ default: throw new Error(`Unsupported field type: ${kind.type}`);
5004
+ }
5005
+ }
5006
+ /**
5007
+ * Get the pointer index for a field
5008
+ * In Cap'n Proto, pointer fields have offsets that start from 0 for the first pointer
5009
+ * The offset is measured in bits from the start of the data section
5010
+ * For pointer fields, offset = dataWordCount * 64 + pointerIndex * 64
5011
+ * So pointerIndex = (offset - dataWordCount * 64) / 64
5012
+ */
5013
+ getPointerIndex(field) {
5014
+ const dataSectionBits = (this.schema.structInfo?.dataWordCount ?? 0) * 64;
5015
+ return (field.offset - dataSectionBits) / 64;
5016
+ }
5017
+ /**
5018
+ * Read a text field
5019
+ */
5020
+ readTextField(field) {
5021
+ const pointerIndex = this.getPointerIndex(field);
5022
+ return this.structReader.getText(pointerIndex);
5023
+ }
5024
+ /**
5025
+ * Read a data field
5026
+ */
5027
+ readDataField(field) {
5028
+ const pointerIndex = this.getPointerIndex(field);
5029
+ const text = this.structReader.getText(pointerIndex);
5030
+ return new TextEncoder().encode(text);
5031
+ }
5032
+ /**
5033
+ * Read a list field using schema information
5034
+ */
5035
+ readListFieldBySchema(field) {
5036
+ if (field.type.kind.type !== "list") throw new Error(`Field '${field.name}' is not a list type`);
5037
+ const pointerIndex = this.getPointerIndex(field);
5038
+ const elementType = field.type.kind.elementType;
5039
+ return this.readListField(pointerIndex, elementType);
5040
+ }
5041
+ /**
5042
+ * Read a list field
5043
+ */
5044
+ readListField(pointerIndex, elementType) {
5045
+ const elementSize = this.mapTypeToElementSize(elementType);
5046
+ const listReader = this.structReader.getList(pointerIndex, elementSize);
5047
+ if (!listReader) return [];
5048
+ const result = [];
5049
+ const length = listReader.length;
5050
+ for (let i = 0; i < length; i++) result.push(this.readListElement(listReader, i, elementType));
5051
+ return result;
5052
+ }
5053
+ /**
5054
+ * Map schema type to ElementSize
5055
+ */
5056
+ mapTypeToElementSize(type) {
5057
+ switch (type.kind.type) {
5058
+ case "void": return ElementSize.VOID;
5059
+ case "bool": return ElementSize.BIT;
5060
+ case "int8":
5061
+ case "uint8": return ElementSize.BYTE;
5062
+ case "int16":
5063
+ case "uint16": return ElementSize.TWO_BYTES;
5064
+ case "int32":
5065
+ case "uint32":
5066
+ case "float32": return ElementSize.FOUR_BYTES;
5067
+ case "int64":
5068
+ case "uint64":
5069
+ case "float64": return ElementSize.EIGHT_BYTES;
5070
+ case "struct": return ElementSize.COMPOSITE;
5071
+ default: return ElementSize.POINTER;
5072
+ }
5073
+ }
5074
+ /**
5075
+ * Read a single list element
5076
+ */
5077
+ readListElement(listReader, index, elementType) {
5078
+ switch (elementType.kind.type) {
5079
+ case "void": return;
5080
+ case "bool": return listReader.getPrimitive(index) !== 0;
5081
+ case "int8": return listReader.getPrimitive(index);
5082
+ case "int16": return listReader.getPrimitive(index);
5083
+ case "int32": return listReader.getPrimitive(index);
5084
+ case "int64": return listReader.getPrimitive(index);
5085
+ case "uint8": return listReader.getPrimitive(index);
5086
+ case "uint16": return listReader.getPrimitive(index);
5087
+ case "uint32": return listReader.getPrimitive(index);
5088
+ case "uint64": return listReader.getPrimitive(index);
5089
+ case "float32": return listReader.getPrimitive(index);
5090
+ case "float64": return listReader.getPrimitive(index);
5091
+ case "struct": {
5092
+ const structReader = listReader.getStruct(index);
5093
+ if (!structReader) return void 0;
5094
+ return new DynamicStructReaderWithoutSchema(structReader, this.messageReader);
5095
+ }
5096
+ default: return;
5097
+ }
5098
+ }
5099
+ /**
5100
+ * Read an enum field
5101
+ */
5102
+ readEnumField(field) {
5103
+ return this.structReader.getUint16(field.offset);
5104
+ }
5105
+ /**
5106
+ * Read a struct field
5107
+ */
5108
+ readStructField(field) {
5109
+ const pointerIndex = this.getPointerIndex(field);
5110
+ const nestedStruct = this.structReader.getStruct(pointerIndex, 0, 0);
5111
+ if (!nestedStruct) return;
5112
+ return new DynamicStructReaderWithoutSchema(nestedStruct, this.messageReader);
5113
+ }
5114
+ /**
5115
+ * Read an interface field (capability)
5116
+ */
5117
+ readInterfaceField(_field) {
5118
+ throw new Error("Interface fields not yet supported in dynamic reader");
5119
+ }
5120
+ /**
5121
+ * Read an anyPointer field
5122
+ */
5123
+ readAnyPointerField(_field) {
5124
+ throw new Error("anyPointer fields not yet supported in dynamic reader");
5125
+ }
5126
+ };
5127
+ /**
5128
+ * A limited dynamic reader for structs without schema information
5129
+ * Provides basic field access but no type information
5130
+ */
5131
+ var DynamicStructReaderWithoutSchema = class {
5132
+ constructor(structReader, messageReader) {
5133
+ this.structReader = structReader;
5134
+ this.messageReader = messageReader;
5135
+ }
5136
+ get(_fieldName) {
5137
+ throw new Error("Cannot access fields without schema information");
5138
+ }
5139
+ has(_fieldName) {
5140
+ return false;
5141
+ }
5142
+ getFieldNames() {
5143
+ return [];
5144
+ }
5145
+ getSchema() {
5146
+ throw new Error("No schema information available");
5147
+ }
5148
+ getStruct(_fieldName) {}
5149
+ getList(_fieldName) {}
5150
+ getRawReader() {
5151
+ return this.structReader;
5152
+ }
5153
+ };
5154
+ /**
5155
+ * Create a dynamic reader for a specific type ID
5156
+ * This looks up the schema in a registry and creates the appropriate reader
5157
+ *
5158
+ * @param typeId - The type ID of the struct
5159
+ * @param buffer - The Cap'n Proto message buffer
5160
+ * @param schemaRegistry - A map of type IDs to schema nodes
5161
+ * @returns A DynamicReader for the message
5162
+ */
5163
+ function createDynamicReaderByTypeId(typeId, buffer, schemaRegistry) {
5164
+ const schema = schemaRegistry.get(typeId);
5165
+ if (!schema) throw new Error(`Schema not found for type ID: ${typeId}`);
5166
+ if (schema.type !== require_rpc_connection.SchemaNodeType.STRUCT) throw new Error(`Type ${typeId} is not a struct`);
5167
+ return createDynamicReader(schema, buffer);
5168
+ }
5169
+ /**
5170
+ * Utility function to dump all fields from a dynamic reader
5171
+ * Useful for debugging and exploration
5172
+ *
5173
+ * @param reader - The DynamicReader to dump
5174
+ * @returns An object with all field names and values
5175
+ */
5176
+ function dumpDynamicReader(reader) {
5177
+ const result = {};
5178
+ for (const fieldName of reader.getFieldNames()) try {
5179
+ result[fieldName] = reader.get(fieldName);
5180
+ } catch (error) {
5181
+ result[fieldName] = `<error: ${error}>`;
5182
+ }
5183
+ return result;
5184
+ }
5185
+
5186
+ //#endregion
5187
+ //#region src/rpc/dynamic-writer.ts
5188
+ /**
5189
+ * Create a dynamic writer from schema
5190
+ *
5191
+ * @param schema - The schema node describing the struct type
5192
+ * @returns A DynamicWriter for setting message fields
5193
+ */
5194
+ function createDynamicWriter(schema) {
5195
+ if (!schema.structInfo) throw new Error(`Schema node ${schema.displayName} is not a struct`);
5196
+ const { dataWordCount, pointerCount } = schema.structInfo;
5197
+ const messageBuilder = new MessageBuilder();
5198
+ return new DynamicWriterImpl(schema, messageBuilder.initRoot(dataWordCount, pointerCount), messageBuilder);
5199
+ }
5200
+ /**
5201
+ * Create a dynamic writer for a nested struct
5202
+ *
5203
+ * @param schema - The schema node describing the struct type
5204
+ * @param structBuilder - The StructBuilder to wrap
5205
+ * @param messageBuilder - The underlying MessageBuilder
5206
+ * @returns A DynamicWriter for setting message fields
5207
+ */
5208
+ function createNestedDynamicWriter(schema, structBuilder, messageBuilder) {
5209
+ return new DynamicWriterImpl(schema, structBuilder, messageBuilder);
5210
+ }
5211
+ /**
5212
+ * Implementation of DynamicWriter
5213
+ */
5214
+ var DynamicWriterImpl = class {
5215
+ fieldCache;
5216
+ pointerOffset;
5217
+ constructor(schema, structBuilder, messageBuilder) {
5218
+ this.schema = schema;
5219
+ this.structBuilder = structBuilder;
5220
+ this.messageBuilder = messageBuilder;
5221
+ this.fieldCache = /* @__PURE__ */ new Map();
5222
+ this.pointerOffset = schema.structInfo?.dataWordCount ?? 0;
5223
+ if (schema.structInfo?.fields) for (const field of schema.structInfo.fields) this.fieldCache.set(field.name, field);
5224
+ }
5225
+ set(fieldName, value) {
5226
+ const field = this.fieldCache.get(fieldName);
5227
+ if (!field) throw new Error(`Field '${fieldName}' not found in schema ${this.schema.displayName}`);
5228
+ this.writeFieldValue(field, value);
5229
+ }
5230
+ setFields(fields) {
5231
+ for (const [name, value] of Object.entries(fields)) this.set(name, value);
5232
+ }
5233
+ initStruct(fieldName) {
5234
+ const field = this.fieldCache.get(fieldName);
5235
+ if (!field) throw new Error(`Field '${fieldName}' not found in schema ${this.schema.displayName}`);
5236
+ if (field.type.kind.type !== "struct") throw new Error(`Field '${fieldName}' is not a struct type`);
5237
+ const pointerIndex = this.getPointerIndex(field);
5238
+ return new DynamicWriterWithoutSchema(this.structBuilder.initStruct(pointerIndex, 0, 0), this.messageBuilder);
5239
+ }
5240
+ initList(fieldName, size) {
5241
+ const field = this.fieldCache.get(fieldName);
5242
+ if (!field) throw new Error(`Field '${fieldName}' not found in schema ${this.schema.displayName}`);
5243
+ if (field.type.kind.type !== "list") throw new Error(`Field '${fieldName}' is not a list type`);
5244
+ const pointerIndex = this.getPointerIndex(field);
5245
+ const elementType = field.type.kind.elementType;
5246
+ return this.createListWriter(pointerIndex, size, elementType);
5247
+ }
5248
+ setText(fieldName, value) {
5249
+ const field = this.fieldCache.get(fieldName);
5250
+ if (!field) throw new Error(`Field '${fieldName}' not found in schema ${this.schema.displayName}`);
5251
+ if (field.type.kind.type !== "text") throw new Error(`Field '${fieldName}' is not a text type`);
5252
+ const pointerIndex = this.getPointerIndex(field);
5253
+ this.structBuilder.setText(pointerIndex, value);
5254
+ }
5255
+ setData(fieldName, value) {
5256
+ const field = this.fieldCache.get(fieldName);
5257
+ if (!field) throw new Error(`Field '${fieldName}' not found in schema ${this.schema.displayName}`);
5258
+ if (field.type.kind.type !== "data") throw new Error(`Field '${fieldName}' is not a data type`);
5259
+ const pointerIndex = this.getPointerIndex(field);
5260
+ const textValue = new TextDecoder().decode(value);
5261
+ this.structBuilder.setText(pointerIndex, `${textValue}\0`);
5262
+ }
5263
+ getSchema() {
5264
+ return this.schema;
5265
+ }
5266
+ getRawBuilder() {
5267
+ return this.structBuilder;
5268
+ }
5269
+ toBuffer() {
5270
+ return this.messageBuilder.toArrayBuffer();
5271
+ }
5272
+ /**
5273
+ * Write a field value based on its type
5274
+ */
5275
+ writeFieldValue(field, value) {
5276
+ const kind = field.type.kind;
5277
+ switch (kind.type) {
5278
+ case "void": break;
5279
+ case "bool":
5280
+ this.structBuilder.setBool(field.offset, Boolean(value));
5281
+ break;
5282
+ case "int8":
5283
+ this.structBuilder.setInt8(field.offset, Number(value));
5284
+ break;
5285
+ case "int16":
5286
+ this.structBuilder.setInt16(field.offset, Number(value));
5287
+ break;
5288
+ case "int32":
5289
+ this.structBuilder.setInt32(field.offset, Number(value));
5290
+ break;
5291
+ case "int64":
5292
+ this.structBuilder.setInt64(field.offset, BigInt(value));
5293
+ break;
5294
+ case "uint8":
5295
+ this.structBuilder.setUint8(field.offset, Number(value));
5296
+ break;
5297
+ case "uint16":
5298
+ this.structBuilder.setUint16(field.offset, Number(value));
5299
+ break;
5300
+ case "uint32":
5301
+ this.structBuilder.setUint32(field.offset, Number(value));
5302
+ break;
5303
+ case "uint64":
5304
+ this.structBuilder.setUint64(field.offset, BigInt(value));
5305
+ break;
5306
+ case "float32":
5307
+ this.structBuilder.setFloat32(field.offset, Number(value));
5308
+ break;
5309
+ case "float64":
5310
+ this.structBuilder.setFloat64(field.offset, Number(value));
5311
+ break;
5312
+ case "text":
5313
+ this.setText(field.name, String(value));
5314
+ break;
5315
+ case "data":
5316
+ if (value instanceof Uint8Array) this.setData(field.name, value);
5317
+ else throw new Error(`Field '${field.name}' expects Uint8Array`);
5318
+ break;
5319
+ case "list":
5320
+ if (Array.isArray(value)) this.initList(field.name, value.length).setAll(value);
5321
+ else throw new Error(`Field '${field.name}' expects an array`);
5322
+ break;
5323
+ case "enum":
5324
+ this.structBuilder.setUint16(field.offset, Number(value));
5325
+ break;
5326
+ case "struct":
5327
+ if (typeof value === "object" && value !== null) {
5328
+ const structWriter = this.initStruct(field.name);
5329
+ if (!(value instanceof Uint8Array) && !Array.isArray(value)) structWriter.setFields(value);
5330
+ } else throw new Error(`Field '${field.name}' expects an object`);
5331
+ break;
5332
+ case "interface": throw new Error("Interface fields not yet supported in dynamic writer");
5333
+ case "anyPointer": throw new Error("anyPointer fields not yet supported in dynamic writer");
5334
+ default: throw new Error(`Unsupported field type: ${kind.type}`);
5335
+ }
5336
+ }
5337
+ /**
5338
+ * Get the pointer index for a field
5339
+ * In Cap'n Proto, pointer fields have offsets that start from 0 for the first pointer
5340
+ * The offset is measured in bits from the start of the data section
5341
+ * For pointer fields, offset = dataWordCount * 64 + pointerIndex * 64
5342
+ * So pointerIndex = (offset - dataWordCount * 64) / 64
5343
+ */
5344
+ getPointerIndex(field) {
5345
+ const dataSectionBits = (this.schema.structInfo?.dataWordCount ?? 0) * 64;
5346
+ return (field.offset - dataSectionBits) / 64;
5347
+ }
5348
+ /**
5349
+ * Create a list writer for a field
5350
+ */
5351
+ createListWriter(pointerIndex, size, elementType) {
5352
+ const elementSize = this.mapTypeToElementSize(elementType);
5353
+ let structSize;
5354
+ if (elementSize === ElementSize.COMPOSITE) structSize = {
5355
+ dataWords: 0,
5356
+ pointerCount: 0
5357
+ };
5358
+ return new DynamicListWriterImpl(this.structBuilder.initList(pointerIndex, elementSize, size, structSize), elementType, this.messageBuilder);
5359
+ }
5360
+ /**
5361
+ * Map schema type to ElementSize
5362
+ */
5363
+ mapTypeToElementSize(type) {
5364
+ switch (type.kind.type) {
5365
+ case "void": return ElementSize.VOID;
5366
+ case "bool": return ElementSize.BIT;
5367
+ case "int8":
5368
+ case "uint8": return ElementSize.BYTE;
5369
+ case "int16":
5370
+ case "uint16": return ElementSize.TWO_BYTES;
5371
+ case "int32":
5372
+ case "uint32":
5373
+ case "float32": return ElementSize.FOUR_BYTES;
5374
+ case "int64":
5375
+ case "uint64":
5376
+ case "float64": return ElementSize.EIGHT_BYTES;
5377
+ case "struct": return ElementSize.COMPOSITE;
5378
+ default: return ElementSize.POINTER;
5379
+ }
5380
+ }
5381
+ };
5382
+ /**
5383
+ * Implementation of DynamicListWriter
5384
+ */
5385
+ var DynamicListWriterImpl = class {
5386
+ constructor(listBuilder, elementType, messageBuilder) {
5387
+ this.listBuilder = listBuilder;
5388
+ this.elementType = elementType;
5389
+ this.messageBuilder = messageBuilder;
5390
+ }
5391
+ set(index, value) {
5392
+ if (index < 0 || index >= this.listBuilder.length) throw new Error(`Index ${index} out of bounds`);
5393
+ const kind = this.elementType.kind;
5394
+ switch (kind.type) {
5395
+ case "void": break;
5396
+ case "bool":
5397
+ this.listBuilder.setPrimitive(index, value ? 1 : 0);
5398
+ break;
5399
+ case "int8":
5400
+ case "uint8":
5401
+ case "int16":
5402
+ case "uint16":
5403
+ case "int32":
5404
+ case "uint32":
5405
+ case "float32":
5406
+ this.listBuilder.setPrimitive(index, Number(value));
5407
+ break;
5408
+ case "int64":
5409
+ case "uint64":
5410
+ case "float64":
5411
+ this.listBuilder.setPrimitive(index, BigInt(value));
5412
+ break;
5413
+ case "struct":
5414
+ if (typeof value === "object" && value !== null && !(value instanceof Uint8Array)) this.initStruct(index).setFields(value);
5415
+ break;
5416
+ default: throw new Error(`Unsupported list element type: ${kind.type}`);
5417
+ }
5418
+ }
5419
+ getSize() {
5420
+ return this.listBuilder.length;
5421
+ }
5422
+ getLength() {
5423
+ return this.listBuilder.length;
5424
+ }
5425
+ initStruct(index) {
5426
+ return new DynamicWriterWithoutSchema(this.listBuilder.getStruct(index), this.messageBuilder);
5427
+ }
5428
+ setAll(values) {
5429
+ if (values.length > this.getSize()) throw new Error(`Cannot set ${values.length} values in list of size ${this.getSize()}`);
5430
+ for (let i = 0; i < values.length; i++) this.set(i, values[i]);
5431
+ }
5432
+ };
5433
+ /**
5434
+ * A limited dynamic writer for structs without full schema information
5435
+ * Provides basic field setting but no type validation
5436
+ */
5437
+ var DynamicWriterWithoutSchema = class {
5438
+ constructor(structBuilder, messageBuilder) {
5439
+ this.structBuilder = structBuilder;
5440
+ this.messageBuilder = messageBuilder;
5441
+ }
5442
+ set(fieldName, _value) {
5443
+ throw new Error(`Cannot set field '${fieldName}' without schema information`);
5444
+ }
5445
+ setFields(_fields) {
5446
+ throw new Error("Cannot set fields without schema information");
5447
+ }
5448
+ initStruct(_fieldName) {
5449
+ throw new Error("Cannot init struct without schema information");
5450
+ }
5451
+ initList(_fieldName, _size) {
5452
+ throw new Error("Cannot init list without schema information");
5453
+ }
5454
+ setText(_fieldName, _value) {
5455
+ throw new Error("Cannot set text without schema information");
5456
+ }
5457
+ setData(_fieldName, _value) {
5458
+ throw new Error("Cannot set data without schema information");
5459
+ }
5460
+ getSchema() {
5461
+ throw new Error("No schema information available");
5462
+ }
5463
+ getRawBuilder() {
5464
+ return this.structBuilder;
5465
+ }
5466
+ toBuffer() {
5467
+ return this.messageBuilder.toArrayBuffer();
5468
+ }
5469
+ };
5470
+ /**
5471
+ * Create a dynamic writer for a specific type ID
5472
+ * This looks up the schema in a registry and creates the appropriate writer
5473
+ *
5474
+ * @param typeId - The type ID of the struct
5475
+ * @param schemaRegistry - A map of type IDs to schema nodes
5476
+ * @returns A DynamicWriter for the message
5477
+ */
5478
+ function createDynamicWriterByTypeId(typeId, schemaRegistry) {
5479
+ const schema = schemaRegistry.get(typeId);
5480
+ if (!schema) throw new Error(`Schema not found for type ID: ${typeId}`);
5481
+ if (schema.type !== require_rpc_connection.SchemaNodeType.STRUCT) throw new Error(`Type ${typeId} is not a struct`);
5482
+ return createDynamicWriter(schema);
5483
+ }
5484
+ /**
5485
+ * Utility function to create a message from a plain object
5486
+ * Uses schema information to properly serialize the data
5487
+ *
5488
+ * @param schema - The schema node describing the struct type
5489
+ * @param data - The data object to serialize
5490
+ * @returns The serialized message buffer
5491
+ */
5492
+ function serializeDynamic(schema, data) {
5493
+ const writer = createDynamicWriter(schema);
5494
+ writer.setFields(data);
5495
+ return writer.toBuffer();
5496
+ }
5497
+ /**
5498
+ * Utility function to create a message from a plain object using type ID
5499
+ *
5500
+ * @param typeId - The type ID of the struct
5501
+ * @param data - The data object to serialize
5502
+ * @param schemaRegistry - A map of type IDs to schema nodes
5503
+ * @returns The serialized message buffer
5504
+ */
5505
+ function serializeDynamicByTypeId(typeId, data, schemaRegistry) {
5506
+ const writer = createDynamicWriterByTypeId(typeId, schemaRegistry);
5507
+ writer.setFields(data);
5508
+ return writer.toBuffer();
5509
+ }
5510
+
5511
+ //#endregion
5512
+ //#region src/rpc/schema-capability.ts
5513
+ /**
5514
+ * Server-side implementation of the SchemaCapability interface.
5515
+ * Provides schema information to remote clients.
5516
+ */
5517
+ var SchemaCapabilityServer = class {
5518
+ registry;
5519
+ schemasByName;
5520
+ /**
5521
+ * Create a new SchemaCapabilityServer
5522
+ * @param initialSchemas - Optional map of schemas to register initially
5523
+ */
5524
+ constructor(initialSchemas) {
5525
+ this.registry = new Map(initialSchemas);
5526
+ this.schemasByName = /* @__PURE__ */ new Map();
5527
+ for (const schema of this.registry.values()) this.schemasByName.set(schema.displayName, schema);
5528
+ }
5529
+ /**
5530
+ * Register a schema node
5531
+ * @param node - The schema node to register
5532
+ */
5533
+ registerSchema(node) {
5534
+ this.registry.set(node.id, node);
5535
+ this.schemasByName.set(node.displayName, node);
5536
+ }
5537
+ /**
5538
+ * Unregister a schema by ID
5539
+ * @param typeId - The type ID to unregister
5540
+ */
5541
+ unregisterSchema(typeId) {
5542
+ const node = this.registry.get(typeId);
5543
+ if (node) {
5544
+ this.registry.delete(typeId);
5545
+ this.schemasByName.delete(node.displayName);
5546
+ }
5547
+ }
5548
+ /**
5549
+ * Get schema information based on target specification
5550
+ * @param params - GetSchemaParams containing target and format
5551
+ * @returns GetSchemaResults with the schema payload
5552
+ */
5553
+ async getSchema(params) {
5554
+ const { target, format = require_rpc_connection.SchemaFormat.BINARY } = params;
5555
+ let schemaData;
5556
+ let dependencies = [];
5557
+ switch (target.type) {
5558
+ case "byTypeId": {
5559
+ const node = this.registry.get(target.typeId);
5560
+ if (!node) throw new Error(`Schema not found for type ID: ${target.typeId.toString(16)}`);
5561
+ schemaData = this.serializeSchemaNode(node, format);
5562
+ dependencies = this.collectDependencies(node);
5563
+ break;
5564
+ }
5565
+ case "byTypeName": {
5566
+ const node = this.schemasByName.get(target.typeName);
5567
+ if (!node) throw new Error(`Schema not found for type name: ${target.typeName}`);
5568
+ schemaData = this.serializeSchemaNode(node, format);
5569
+ dependencies = this.collectDependencies(node);
5570
+ break;
5571
+ }
5572
+ case "byFileId": {
5573
+ const nodes = this.getSchemasByFileId(target.fileId);
5574
+ schemaData = this.serializeSchemaNodes(nodes, format);
5575
+ break;
5576
+ }
5577
+ case "byFileName": {
5578
+ const nodes = this.getSchemasByFileName(target.fileName);
5579
+ schemaData = this.serializeSchemaNodes(nodes, format);
5580
+ break;
5581
+ }
5582
+ case "allSchemas": {
5583
+ const nodes = Array.from(this.registry.values());
5584
+ schemaData = this.serializeSchemaNodes(nodes, format);
5585
+ break;
5586
+ }
5587
+ case "bootstrapInterface": {
5588
+ const bootstrapSchema = this.findBootstrapSchema();
5589
+ if (!bootstrapSchema) throw new Error("Bootstrap interface schema not available");
5590
+ schemaData = this.serializeSchemaNode(bootstrapSchema, format);
5591
+ dependencies = this.collectDependencies(bootstrapSchema);
5592
+ break;
5593
+ }
5594
+ default: throw new Error(`Unsupported schema target type: ${target.type}`);
5595
+ }
5596
+ return { payload: {
5597
+ schemaData,
5598
+ format,
5599
+ dependencies
5600
+ } };
5601
+ }
5602
+ /**
5603
+ * List all available schemas
5604
+ * @returns ListSchemasResults with available schema information
5605
+ */
5606
+ async listAvailableSchemas() {
5607
+ const schemas = [];
5608
+ for (const node of this.registry.values()) schemas.push({
5609
+ typeId: node.id,
5610
+ displayName: node.displayName,
5611
+ fileId: node.scopeId,
5612
+ fileName: this.inferFileName(node),
5613
+ isInterface: node.type === require_rpc_connection.SchemaNodeType.INTERFACE,
5614
+ isStruct: node.type === require_rpc_connection.SchemaNodeType.STRUCT,
5615
+ isEnum: node.type === require_rpc_connection.SchemaNodeType.ENUM
5616
+ });
5617
+ return { schemas };
5618
+ }
5619
+ /**
5620
+ * Handle a raw schema request (for RPC integration)
5621
+ * @param requestData - The serialized SchemaRequest
5622
+ * @returns The serialized SchemaResponse
5623
+ */
5624
+ handleRequest(requestData) {
5625
+ try {
5626
+ const request = require_rpc_connection.deserializeSchemaRequest(requestData);
5627
+ this.getSchema({ target: request.targetSchema });
5628
+ throw new Error("Async handling not implemented in handleRequest");
5629
+ } catch (error) {
5630
+ return require_rpc_connection.serializeSchemaResponse({
5631
+ answerId: 0,
5632
+ result: {
5633
+ type: "exception",
5634
+ exception: {
5635
+ reason: error instanceof Error ? error.message : "Unknown error",
5636
+ type: "failed",
5637
+ obsoleteIsCallersFault: false,
5638
+ obsoleteDurability: 0
5639
+ }
5640
+ }
5641
+ });
5642
+ }
5643
+ }
5644
+ /**
5645
+ * Get the number of registered schemas
5646
+ */
5647
+ getSchemaCount() {
5648
+ return this.registry.size;
5649
+ }
5650
+ /**
5651
+ * Check if a schema is registered
5652
+ */
5653
+ hasSchema(typeId) {
5654
+ return this.registry.has(typeId);
5655
+ }
5656
+ serializeSchemaNode(node, format) {
5657
+ switch (format) {
5658
+ case require_rpc_connection.SchemaFormat.BINARY: return this.serializeToBinary([node]);
5659
+ case require_rpc_connection.SchemaFormat.JSON: return this.serializeToJson([node]);
5660
+ case require_rpc_connection.SchemaFormat.CAPNP: return this.serializeToCapnp([node]);
5661
+ default: throw new Error(`Unsupported schema format: ${format}`);
5662
+ }
5663
+ }
5664
+ serializeSchemaNodes(nodes, format) {
5665
+ switch (format) {
5666
+ case require_rpc_connection.SchemaFormat.BINARY: return this.serializeToBinary(nodes);
5667
+ case require_rpc_connection.SchemaFormat.JSON: return this.serializeToJson(nodes);
5668
+ case require_rpc_connection.SchemaFormat.CAPNP: return this.serializeToCapnp(nodes);
5669
+ default: throw new Error(`Unsupported schema format: ${format}`);
5670
+ }
5671
+ }
5672
+ serializeToBinary(nodes) {
5673
+ const encoder = new TextEncoder();
5674
+ const json = JSON.stringify(nodes, (_key, value) => {
5675
+ if (typeof value === "bigint") return value.toString();
5676
+ return value;
5677
+ });
5678
+ return encoder.encode(json);
5679
+ }
5680
+ serializeToJson(nodes) {
5681
+ const encoder = new TextEncoder();
5682
+ const json = JSON.stringify({ nodes: nodes.map((node) => ({
5683
+ id: node.id.toString(),
5684
+ displayName: node.displayName,
5685
+ displayNamePrefixLength: node.displayNamePrefixLength,
5686
+ scopeId: node.scopeId.toString(),
5687
+ type: node.type,
5688
+ structInfo: node.structInfo,
5689
+ enumInfo: node.enumInfo,
5690
+ interfaceInfo: node.interfaceInfo
5691
+ })) });
5692
+ return encoder.encode(json);
5693
+ }
5694
+ serializeToCapnp(nodes) {
5695
+ const lines = [];
5696
+ for (const node of nodes) if (node.structInfo) {
5697
+ lines.push(`struct ${node.displayName} {`);
5698
+ for (const field of node.structInfo.fields) lines.push(` ${field.name} @${field.codeOrder} :${this.typeToCapnp(field.type)};`);
5699
+ lines.push("}");
5700
+ }
5701
+ return new TextEncoder().encode(lines.join("\n"));
5702
+ }
5703
+ typeToCapnp(type) {
5704
+ switch (type.kind.type) {
5705
+ case "void": return "Void";
5706
+ case "bool": return "Bool";
5707
+ case "int8": return "Int8";
5708
+ case "int16": return "Int16";
5709
+ case "int32": return "Int32";
5710
+ case "int64": return "Int64";
5711
+ case "uint8": return "UInt8";
5712
+ case "uint16": return "UInt16";
5713
+ case "uint32": return "UInt32";
5714
+ case "uint64": return "UInt64";
5715
+ case "float32": return "Float32";
5716
+ case "float64": return "Float64";
5717
+ case "text": return "Text";
5718
+ case "data": return "Data";
5719
+ case "list": return "List";
5720
+ case "enum": return "UInt16";
5721
+ case "struct": return "AnyPointer";
5722
+ case "interface": return "Capability";
5723
+ default: return "AnyPointer";
5724
+ }
5725
+ }
5726
+ collectDependencies(_node) {
5727
+ return [];
5728
+ }
5729
+ getSchemasByFileId(fileId) {
5730
+ return Array.from(this.registry.values()).filter((node) => node.scopeId === fileId);
5731
+ }
5732
+ getSchemasByFileName(fileName) {
5733
+ return Array.from(this.registry.values()).filter((node) => {
5734
+ return this.inferFileName(node) === fileName || node.displayName.startsWith(fileName);
5735
+ });
5736
+ }
5737
+ inferFileName(node) {
5738
+ const parts = node.displayName.split(".");
5739
+ if (parts.length > 1) return `${parts.slice(0, -1).join("/")}.capnp`;
5740
+ return "unknown.capnp";
5741
+ }
5742
+ findBootstrapSchema() {
5743
+ for (const node of this.registry.values()) if (node.type === require_rpc_connection.SchemaNodeType.INTERFACE) return node;
5744
+ }
5745
+ };
5746
+ /**
5747
+ * Client-side implementation for accessing remote SchemaCapability
5748
+ */
5749
+ var SchemaCapabilityClient = class {
5750
+ connection;
5751
+ /**
5752
+ * Create a new SchemaCapabilityClient
5753
+ * @param connection - The RPC connection to use
5754
+ */
5755
+ constructor(connection) {
5756
+ this.connection = connection;
5757
+ }
5758
+ /**
5759
+ * Fetch schema information from the remote server
5760
+ * @param target - The schema target specification
5761
+ * @param format - The desired format (defaults to BINARY)
5762
+ * @returns The schema node
5763
+ */
5764
+ async getSchema(target, format = require_rpc_connection.SchemaFormat.BINARY) {
5765
+ if (target.type === "byTypeId") return this.connection.getDynamicSchema(target.typeId);
5766
+ if (target.type === "byTypeName") return this.connection.getDynamicSchemaByName(target.typeName);
5767
+ throw new Error(`Schema target type not implemented: ${target.type}`);
5768
+ }
5769
+ /**
5770
+ * Fetch schema by type ID
5771
+ * @param typeId - The type ID
5772
+ * @returns The schema node
5773
+ */
5774
+ async getSchemaById(typeId) {
5775
+ return this.connection.getDynamicSchema(typeId);
5776
+ }
5777
+ /**
5778
+ * Fetch schema by type name
5779
+ * @param typeName - The fully qualified type name
5780
+ * @returns The schema node
5781
+ */
5782
+ async getSchemaByName(typeName) {
5783
+ return this.connection.getDynamicSchemaByName(typeName);
5784
+ }
5785
+ /**
5786
+ * List all available schemas from the remote server
5787
+ * @returns Array of available schema information
5788
+ */
5789
+ async listAvailableSchemas() {
5790
+ return (await this.connection.listAvailableSchemas()).map((s) => ({
5791
+ typeId: s.typeId,
5792
+ displayName: s.displayName,
5793
+ fileId: BigInt(0),
5794
+ fileName: "",
5795
+ isInterface: false,
5796
+ isStruct: true,
5797
+ isEnum: false
5798
+ }));
5799
+ }
5800
+ /**
5801
+ * Fetch multiple schemas at once
5802
+ * @param typeIds - Array of type IDs to fetch
5803
+ * @returns Map of type ID to schema node
5804
+ */
5805
+ async getSchemas(typeIds) {
5806
+ const results = /* @__PURE__ */ new Map();
5807
+ await Promise.all(typeIds.map(async (typeId) => {
5808
+ try {
5809
+ const schema = await this.getSchemaById(typeId);
5810
+ results.set(typeId, schema);
5811
+ } catch (error) {
5812
+ console.warn(`Failed to fetch schema ${typeId.toString(16)}:`, error);
5813
+ }
5814
+ }));
5815
+ return results;
5816
+ }
5817
+ /**
5818
+ * Check if a schema is available on the remote server
5819
+ * @param typeId - The type ID to check
5820
+ * @returns True if the schema is available
5821
+ */
5822
+ async hasSchema(typeId) {
5823
+ try {
5824
+ await this.getSchemaById(typeId);
5825
+ return true;
5826
+ } catch {
5827
+ return false;
5828
+ }
5829
+ }
5830
+ };
5831
+
4904
5832
  //#endregion
4905
5833
  exports.AnswerTable = require_rpc_connection.AnswerTable;
4906
5834
  exports.BaseCapabilityClient = BaseCapabilityClient;
@@ -4937,6 +5865,10 @@ exports.RealtimeStream = RealtimeStream;
4937
5865
  exports.RealtimeStreamManager = RealtimeStreamManager;
4938
5866
  exports.RestoreHandler = RestoreHandler;
4939
5867
  exports.RpcConnection = require_rpc_connection.RpcConnection;
5868
+ exports.SCHEMA_MESSAGE_TYPES = require_rpc_connection.SCHEMA_MESSAGE_TYPES;
5869
+ exports.SchemaCapabilityClient = SchemaCapabilityClient;
5870
+ exports.SchemaCapabilityServer = SchemaCapabilityServer;
5871
+ exports.SchemaFormat = require_rpc_connection.SchemaFormat;
4940
5872
  exports.Segment = Segment;
4941
5873
  exports.Stream = Stream;
4942
5874
  exports.StreamManager = StreamManager;
@@ -4952,10 +5884,17 @@ exports.WORD_SIZE = WORD_SIZE;
4952
5884
  exports.WebSocketTransport = WebSocketTransport;
4953
5885
  exports.configureGlobalMemoryPool = configureGlobalMemoryPool;
4954
5886
  exports.createBulkTransferManager = createBulkTransferManager;
5887
+ exports.createDynamicReader = createDynamicReader;
5888
+ exports.createDynamicReaderByTypeId = createDynamicReaderByTypeId;
5889
+ exports.createDynamicReaderFromStruct = createDynamicReaderFromStruct;
5890
+ exports.createDynamicWriter = createDynamicWriter;
5891
+ exports.createDynamicWriterByTypeId = createDynamicWriterByTypeId;
5892
+ exports.createNestedDynamicWriter = createNestedDynamicWriter;
4955
5893
  exports.createPipelineClient = require_rpc_connection.createPipelineClient;
4956
5894
  exports.createProvisionId = createProvisionId;
4957
5895
  exports.createRealtimeStreamManager = createRealtimeStreamManager;
4958
5896
  exports.createRecipientId = createRecipientId;
5897
+ exports.createSchemaRegistry = require_rpc_connection.createSchemaRegistry;
4959
5898
  exports.createStream = createStream;
4960
5899
  exports.createStreamManager = createStreamManager;
4961
5900
  exports.createStreamingConnection = createStreamingConnection;
@@ -4966,7 +5905,10 @@ exports.createUnionReader = createUnionReader;
4966
5905
  exports.createZeroCopyView = createZeroCopyView;
4967
5906
  exports.decodePointer = decodePointer;
4968
5907
  exports.deserializeRpcMessage = deserializeRpcMessage;
5908
+ exports.deserializeSchemaRequest = require_rpc_connection.deserializeSchemaRequest;
5909
+ exports.deserializeSchemaResponse = require_rpc_connection.deserializeSchemaResponse;
4969
5910
  exports.deserializeSturdyRef = deserializeSturdyRef;
5911
+ exports.dumpDynamicReader = dumpDynamicReader;
4970
5912
  exports.encodeListPointer = encodeListPointer;
4971
5913
  exports.encodeStructPointer = encodeStructPointer;
4972
5914
  exports.fastCopy = fastCopy;
@@ -4977,7 +5919,15 @@ exports.isPipelineClient = require_rpc_connection.isPipelineClient;
4977
5919
  exports.isSameBuffer = isSameBuffer;
4978
5920
  exports.isStream = isStream;
4979
5921
  exports.isSturdyRefValid = isSturdyRefValid;
5922
+ exports.parseSchemaNodes = require_rpc_connection.parseSchemaNodes;
5923
+ exports.serializeDynamic = serializeDynamic;
5924
+ exports.serializeDynamicByTypeId = serializeDynamicByTypeId;
5925
+ exports.serializeGetSchemaParams = require_rpc_connection.serializeGetSchemaParams;
5926
+ exports.serializeGetSchemaResults = require_rpc_connection.serializeGetSchemaResults;
5927
+ exports.serializeListSchemasResults = require_rpc_connection.serializeListSchemasResults;
4980
5928
  exports.serializeRpcMessage = serializeRpcMessage;
5929
+ exports.serializeSchemaRequest = require_rpc_connection.serializeSchemaRequest;
5930
+ exports.serializeSchemaResponse = require_rpc_connection.serializeSchemaResponse;
4981
5931
  exports.serializeSturdyRef = serializeSturdyRef;
4982
5932
  exports.supportsStreaming = supportsStreaming;
4983
5933
  //# sourceMappingURL=index.cjs.map