@haneullabs/bcs 2.1.0 → 2.1.3

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/bcs.mjs CHANGED
@@ -21,17 +21,22 @@ function fixedArray(size, type, options) {
21
21
  });
22
22
  }
23
23
  function option(type) {
24
- return bcs.enum(`Option<${type.name}>`, {
25
- None: null,
26
- Some: type
27
- }).transform({
28
- input: (value) => {
29
- if (value == null) return { None: true };
30
- return { Some: value };
24
+ const name = `Option<${type.name}>`;
25
+ return new BcsType({
26
+ name,
27
+ read: (reader) => {
28
+ const index = reader.readULEB();
29
+ if (index === 0) return null;
30
+ if (index === 1) return type.read(reader);
31
+ throw new TypeError(`Unknown value ${index} for enum ${name}`);
31
32
  },
32
- output: (value) => {
33
- if (value.$kind === "Some") return value.Some;
34
- return null;
33
+ write: (value, writer) => {
34
+ if (value == null) {
35
+ writer.write8(0);
36
+ return;
37
+ }
38
+ writer.write8(1);
39
+ type.write(value, writer);
35
40
  }
36
41
  });
37
42
  }
@@ -84,6 +89,27 @@ function map(keyType, valueType) {
84
89
  }
85
90
  });
86
91
  }
92
+ let utf8Encoder;
93
+ let utf8Decoder;
94
+ function decoder() {
95
+ return utf8Decoder ??= new TextDecoder("utf-8", {
96
+ fatal: true,
97
+ ignoreBOM: true
98
+ });
99
+ }
100
+ const ASCII_FAST_PATH_MAX_LENGTH = 64;
101
+ function decodeUtf8(bytes) {
102
+ if (bytes.length <= ASCII_FAST_PATH_MAX_LENGTH) {
103
+ let result = "";
104
+ for (let i = 0; i < bytes.length; i++) {
105
+ const byte = bytes[i];
106
+ if (byte >= 128) return decoder().decode(bytes);
107
+ result += String.fromCharCode(byte);
108
+ }
109
+ return result;
110
+ }
111
+ return decoder().decode(bytes);
112
+ }
87
113
  const bcs = {
88
114
  /**
89
115
  * Creates a BcsType that can be used to read and write an 8-bit unsigned integer.
@@ -95,7 +121,7 @@ const bcs = {
95
121
  readMethod: "read8",
96
122
  writeMethod: "write8",
97
123
  size: 1,
98
- maxValue: 2 ** 8 - 1,
124
+ maxValue: 255,
99
125
  ...options,
100
126
  name: options?.name ?? "u8"
101
127
  });
@@ -183,7 +209,11 @@ const bcs = {
183
209
  bool(options) {
184
210
  return fixedSizeBcsType({
185
211
  size: 1,
186
- read: (reader) => reader.read8() === 1,
212
+ read: (reader) => {
213
+ const value = reader.read8();
214
+ if (value > 1) throw new TypeError(`Invalid bool value: expected 0 or 1, found ${value}`);
215
+ return value === 1;
216
+ },
187
217
  write: (value, writer) => writer.write8(value ? 1 : 0),
188
218
  ...options,
189
219
  name: options?.name ?? "bool",
@@ -219,7 +249,7 @@ const bcs = {
219
249
  size,
220
250
  read: (reader) => reader.readBytes(size),
221
251
  write: (value, writer) => {
222
- writer.writeBytes(new Uint8Array(value));
252
+ writer.writeBytes(value instanceof Uint8Array ? value : new Uint8Array(value));
223
253
  },
224
254
  ...options,
225
255
  name: options?.name ?? `bytes[${size}]`,
@@ -243,7 +273,7 @@ const bcs = {
243
273
  return reader.readBytes(length);
244
274
  },
245
275
  write: (value, writer) => {
246
- const array = new Uint8Array(value);
276
+ const array = value instanceof Uint8Array ? value : new Uint8Array(value);
247
277
  writer.writeULEB(array.length);
248
278
  writer.writeBytes(array);
249
279
  },
@@ -266,8 +296,8 @@ const bcs = {
266
296
  */
267
297
  string(options) {
268
298
  return stringLikeBcsType({
269
- toBytes: (value) => new TextEncoder().encode(value),
270
- fromBytes: (bytes) => new TextDecoder().decode(bytes),
299
+ toBytes: (value) => (utf8Encoder ??= new TextEncoder()).encode(value),
300
+ fromBytes: decodeUtf8,
271
301
  ...options,
272
302
  name: options?.name ?? "string"
273
303
  });
package/dist/bcs.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bcs.mjs","names":[],"sources":["../src/bcs.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { BcsTypeOptions } from './bcs-type.js';\nimport {\n\tBcsEnum,\n\tBcsStruct,\n\tBcsTuple,\n\tBcsType,\n\tbigUIntBcsType,\n\tdynamicSizeBcsType,\n\tfixedSizeBcsType,\n\tlazyBcsType,\n\tstringLikeBcsType,\n\tuIntBcsType,\n} from './bcs-type.js';\nimport type {\n\tEnumInputShape,\n\tEnumOutputShape,\n\tInferBcsInput,\n\tInferBcsType,\n\tJoinString,\n} from './types.js';\nimport { ulebEncode } from './uleb.js';\n\nfunction fixedArray<T extends BcsType<any>, Name extends string = string>(\n\tsize: number,\n\ttype: T,\n\toptions?: BcsTypeOptions<\n\t\tInferBcsType<T>[],\n\t\tIterable<InferBcsInput<T>> & { length: number },\n\t\tName\n\t>,\n): BcsType<InferBcsType<T>[], Iterable<InferBcsInput<T>> & { length: number }, Name>;\nfunction fixedArray<T, Input, Name extends string = string>(\n\tsize: number,\n\ttype: BcsType<T, Input>,\n\toptions?: BcsTypeOptions<T[], Iterable<Input> & { length: number }, Name>,\n): BcsType<T[], Iterable<Input> & { length: number }, Name>;\nfunction fixedArray<T extends BcsType<any>, Name extends string = `${T['name']}[${number}]`>(\n\tsize: number,\n\ttype: T,\n\toptions?: BcsTypeOptions<\n\t\tInferBcsType<T>[],\n\t\tIterable<InferBcsInput<T>> & { length: number },\n\t\tName\n\t>,\n): BcsType<InferBcsType<T>[], Iterable<InferBcsInput<T>> & { length: number }, Name> {\n\treturn new BcsType<InferBcsType<T>[], Iterable<InferBcsInput<T>> & { length: number }, Name>({\n\t\tread: (reader) => {\n\t\t\tconst result: InferBcsType<T>[] = new Array(size);\n\t\t\tfor (let i = 0; i < size; i++) {\n\t\t\t\tresult[i] = type.read(reader);\n\t\t\t}\n\t\t\treturn result;\n\t\t},\n\t\twrite: (value, writer) => {\n\t\t\tfor (const item of value) {\n\t\t\t\ttype.write(item, writer);\n\t\t\t}\n\t\t},\n\t\t...options,\n\t\tname: (options?.name ?? `${type.name}[${size}]`) as Name,\n\t\tvalidate: (value) => {\n\t\t\toptions?.validate?.(value);\n\t\t\tif (!value || typeof value !== 'object' || !('length' in value)) {\n\t\t\t\tthrow new TypeError(`Expected array, found ${typeof value}`);\n\t\t\t}\n\t\t\tif (value.length !== size) {\n\t\t\t\tthrow new TypeError(`Expected array of length ${size}, found ${value.length}`);\n\t\t\t}\n\t\t},\n\t});\n}\n\nfunction option<T extends BcsType<any>>(\n\ttype: T,\n): BcsType<InferBcsType<T> | null, InferBcsInput<T> | null | undefined, `Option<${T['name']}>`>;\nfunction option<T, Input, Name extends string = string>(\n\ttype: BcsType<T, Input, Name>,\n): BcsType<T | null, Input | null | undefined>;\nfunction option<T extends BcsType<any>>(\n\ttype: T,\n): BcsType<InferBcsType<T> | null, InferBcsInput<T> | null | undefined, `Option<${T['name']}>`> {\n\treturn bcs\n\t\t.enum(`Option<${type.name}>`, {\n\t\t\tNone: null,\n\t\t\tSome: type,\n\t\t})\n\t\t.transform({\n\t\t\tinput: (value: InferBcsInput<T> | null | undefined) => {\n\t\t\t\tif (value == null) {\n\t\t\t\t\treturn { None: true };\n\t\t\t\t}\n\n\t\t\t\treturn { Some: value };\n\t\t\t},\n\t\t\toutput: (value) => {\n\t\t\t\tif (value.$kind === 'Some') {\n\t\t\t\t\treturn value.Some as InferBcsType<T>;\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t},\n\t\t});\n}\n\nfunction vector<T extends BcsType<any>, Name extends string = `vector<${T['name']}>`>(\n\ttype: T,\n\toptions?: BcsTypeOptions<\n\t\tInferBcsType<T>[],\n\t\tIterable<InferBcsInput<T>> & { length: number },\n\t\tName\n\t>,\n): BcsType<InferBcsType<T>[], Iterable<InferBcsInput<T>> & { length: number }, Name>;\nfunction vector<T, Input, Name extends string = string>(\n\ttype: BcsType<T, Input, Name>,\n\toptions?: BcsTypeOptions<T[], Iterable<Input> & { length: number }, `vector<${Name}>`>,\n): BcsType<T[], Iterable<Input> & { length: number }, `vector<${Name}>`>;\nfunction vector<T extends BcsType<any>, Name extends string = `vector<${T['name']}>`>(\n\ttype: T,\n\toptions?: BcsTypeOptions<\n\t\tInferBcsType<T>[],\n\t\tIterable<InferBcsInput<T>> & { length: number },\n\t\tName\n\t>,\n): BcsType<InferBcsType<T>[], Iterable<InferBcsInput<T>> & { length: number }, Name> {\n\treturn new BcsType<InferBcsType<T>[], Iterable<InferBcsInput<T>> & { length: number }, Name>({\n\t\tread: (reader) => {\n\t\t\tconst length = reader.readULEB();\n\t\t\tconst result: InferBcsType<T>[] = new Array(length);\n\t\t\tfor (let i = 0; i < length; i++) {\n\t\t\t\tresult[i] = type.read(reader);\n\t\t\t}\n\t\t\treturn result;\n\t\t},\n\t\twrite: (value, writer) => {\n\t\t\twriter.writeULEB(value.length);\n\t\t\tfor (const item of value) {\n\t\t\t\ttype.write(item, writer);\n\t\t\t}\n\t\t},\n\t\t...options,\n\t\tname: (options?.name ?? `vector<${type.name}>`) as Name,\n\t\tvalidate: (value) => {\n\t\t\toptions?.validate?.(value);\n\t\t\tif (!value || typeof value !== 'object' || !('length' in value)) {\n\t\t\t\tthrow new TypeError(`Expected array, found ${typeof value}`);\n\t\t\t}\n\t\t},\n\t});\n}\n\n/**\n * Compares two byte arrays using lexicographic ordering.\n * This matches Rust's Ord implementation for Vec<u8>/[u8] which is used for BTreeMap key ordering.\n * Comparison is done byte-by-byte first, then by length if all compared bytes are equal.\n */\nexport function compareBcsBytes(a: Uint8Array, b: Uint8Array): number {\n\tfor (let i = 0; i < Math.min(a.length, b.length); i++) {\n\t\tif (a[i] !== b[i]) {\n\t\t\treturn a[i] - b[i];\n\t\t}\n\t}\n\n\treturn a.length - b.length;\n}\n\nfunction map<K extends BcsType<any>, V extends BcsType<any>>(\n\tkeyType: K,\n\tvalueType: V,\n): BcsType<\n\tMap<InferBcsType<K>, InferBcsType<V>>,\n\tMap<InferBcsInput<K>, InferBcsInput<V>>,\n\t`Map<${K['name']}, ${V['name']}>`\n>;\nfunction map<K, V, InputK = K, InputV = V>(\n\tkeyType: BcsType<K, InputK>,\n\tvalueType: BcsType<V, InputV>,\n): BcsType<Map<K, V>, Map<InputK, InputV>, `Map<${string}, ${string}>`>;\nfunction map<K extends BcsType<any>, V extends BcsType<any>>(\n\tkeyType: K,\n\tvalueType: V,\n): BcsType<\n\tMap<InferBcsType<K>, InferBcsType<V>>,\n\tMap<InferBcsInput<K>, InferBcsInput<V>>,\n\t`Map<${K['name']}, ${V['name']}>`\n> {\n\treturn new BcsType({\n\t\tname: `Map<${keyType.name}, ${valueType.name}>`,\n\t\tread: (reader) => {\n\t\t\tconst length = reader.readULEB();\n\t\t\tconst result = new Map<InferBcsType<K>, InferBcsType<V>>();\n\t\t\tfor (let i = 0; i < length; i++) {\n\t\t\t\tresult.set(keyType.read(reader), valueType.read(reader));\n\t\t\t}\n\t\t\treturn result;\n\t\t},\n\t\twrite: (value, writer) => {\n\t\t\tconst entries = [...value.entries()].map(\n\t\t\t\t([key, val]) => [keyType.serialize(key).toBytes(), val] as const,\n\t\t\t);\n\t\t\tentries.sort(([a], [b]) => compareBcsBytes(a, b));\n\n\t\t\twriter.writeULEB(entries.length);\n\t\t\tfor (const [keyBytes, val] of entries) {\n\t\t\t\twriter.writeBytes(keyBytes);\n\t\t\t\tvalueType.write(val, writer);\n\t\t\t}\n\t\t},\n\t});\n}\n\nexport const bcs = {\n\t/**\n\t * Creates a BcsType that can be used to read and write an 8-bit unsigned integer.\n\t * @example\n\t * bcs.u8().serialize(255).toBytes() // Uint8Array [ 255 ]\n\t */\n\tu8(options?: BcsTypeOptions<number>) {\n\t\treturn uIntBcsType({\n\t\t\treadMethod: 'read8',\n\t\t\twriteMethod: 'write8',\n\t\t\tsize: 1,\n\t\t\tmaxValue: 2 ** 8 - 1,\n\t\t\t...options,\n\t\t\tname: (options?.name ?? 'u8') as 'u8',\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType that can be used to read and write a 16-bit unsigned integer.\n\t * @example\n\t * bcs.u16().serialize(65535).toBytes() // Uint8Array [ 255, 255 ]\n\t */\n\tu16(options?: BcsTypeOptions<number>) {\n\t\treturn uIntBcsType({\n\t\t\treadMethod: 'read16',\n\t\t\twriteMethod: 'write16',\n\t\t\tsize: 2,\n\t\t\tmaxValue: 2 ** 16 - 1,\n\t\t\t...options,\n\t\t\tname: (options?.name ?? 'u16') as 'u16',\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType that can be used to read and write a 32-bit unsigned integer.\n\t * @example\n\t * bcs.u32().serialize(4294967295).toBytes() // Uint8Array [ 255, 255, 255, 255 ]\n\t */\n\tu32(options?: BcsTypeOptions<number>) {\n\t\treturn uIntBcsType({\n\t\t\treadMethod: 'read32',\n\t\t\twriteMethod: 'write32',\n\t\t\tsize: 4,\n\t\t\tmaxValue: 2 ** 32 - 1,\n\t\t\t...options,\n\t\t\tname: (options?.name ?? 'u32') as 'u32',\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType that can be used to read and write a 64-bit unsigned integer.\n\t * @example\n\t * bcs.u64().serialize(1).toBytes() // Uint8Array [ 1, 0, 0, 0, 0, 0, 0, 0 ]\n\t */\n\tu64(options?: BcsTypeOptions<string, number | bigint | string>) {\n\t\treturn bigUIntBcsType({\n\t\t\treadMethod: 'read64',\n\t\t\twriteMethod: 'write64',\n\t\t\tsize: 8,\n\t\t\tmaxValue: 2n ** 64n - 1n,\n\t\t\t...options,\n\t\t\tname: (options?.name ?? 'u64') as 'u64',\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType that can be used to read and write a 128-bit unsigned integer.\n\t * @example\n\t * bcs.u128().serialize(1).toBytes() // Uint8Array [ 1, ..., 0 ]\n\t */\n\tu128(options?: BcsTypeOptions<string, number | bigint | string>) {\n\t\treturn bigUIntBcsType({\n\t\t\treadMethod: 'read128',\n\t\t\twriteMethod: 'write128',\n\t\t\tsize: 16,\n\t\t\tmaxValue: 2n ** 128n - 1n,\n\t\t\t...options,\n\t\t\tname: (options?.name ?? 'u128') as 'u128',\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType that can be used to read and write a 256-bit unsigned integer.\n\t * @example\n\t * bcs.u256().serialize(1).toBytes() // Uint8Array [ 1, ..., 0 ]\n\t */\n\tu256(options?: BcsTypeOptions<string, number | bigint | string>) {\n\t\treturn bigUIntBcsType({\n\t\t\treadMethod: 'read256',\n\t\t\twriteMethod: 'write256',\n\t\t\tsize: 32,\n\t\t\tmaxValue: 2n ** 256n - 1n,\n\t\t\t...options,\n\t\t\tname: (options?.name ?? 'u256') as 'u256',\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType that can be used to read and write boolean values.\n\t * @example\n\t * bcs.bool().serialize(true).toBytes() // Uint8Array [ 1 ]\n\t */\n\tbool(options?: BcsTypeOptions<boolean>) {\n\t\treturn fixedSizeBcsType({\n\t\t\tsize: 1,\n\t\t\tread: (reader) => reader.read8() === 1,\n\t\t\twrite: (value, writer) => writer.write8(value ? 1 : 0),\n\t\t\t...options,\n\t\t\tname: (options?.name ?? 'bool') as 'bool',\n\t\t\tvalidate: (value) => {\n\t\t\t\toptions?.validate?.(value);\n\t\t\t\tif (typeof value !== 'boolean') {\n\t\t\t\t\tthrow new TypeError(`Expected boolean, found ${typeof value}`);\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType that can be used to read and write unsigned LEB encoded integers\n\t * @example\n\t *\n\t */\n\tuleb128(options?: BcsTypeOptions<number>) {\n\t\treturn dynamicSizeBcsType({\n\t\t\tread: (reader) => reader.readULEB(),\n\t\t\tserialize: (value) => {\n\t\t\t\treturn Uint8Array.from(ulebEncode(value));\n\t\t\t},\n\t\t\t...options,\n\t\t\tname: (options?.name ?? 'uleb128') as 'uleb128',\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType representing a fixed length byte array\n\t * @param size The number of bytes this types represents\n\t * @example\n\t * bcs.bytes(3).serialize(new Uint8Array([1, 2, 3])).toBytes() // Uint8Array [1, 2, 3]\n\t */\n\tbytes<T extends number>(size: T, options?: BcsTypeOptions<Uint8Array, Iterable<number>>) {\n\t\treturn fixedSizeBcsType<Uint8Array, Iterable<number>, `bytes[${T}]`>({\n\t\t\tsize,\n\t\t\tread: (reader) => reader.readBytes(size),\n\t\t\twrite: (value, writer) => {\n\t\t\t\twriter.writeBytes(new Uint8Array(value));\n\t\t\t},\n\t\t\t...options,\n\t\t\tname: (options?.name ?? `bytes[${size}]`) as `bytes[${T}]`,\n\t\t\tvalidate: (value) => {\n\t\t\t\toptions?.validate?.(value);\n\t\t\t\tif (!value || typeof value !== 'object' || !('length' in value)) {\n\t\t\t\t\tthrow new TypeError(`Expected array, found ${typeof value}`);\n\t\t\t\t}\n\t\t\t\tif (value.length !== size) {\n\t\t\t\t\tthrow new TypeError(`Expected array of length ${size}, found ${value.length}`);\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType representing a variable length byte array\n\t *\n\t * @example\n\t * bcs.byteVector().serialize([1, 2, 3]).toBytes() // Uint8Array [3, 1, 2, 3]\n\t */\n\tbyteVector(options?: BcsTypeOptions<Uint8Array, Iterable<number>>) {\n\t\treturn new BcsType<Uint8Array, Iterable<number>, 'vector<u8>'>({\n\t\t\tread: (reader) => {\n\t\t\t\tconst length = reader.readULEB();\n\n\t\t\t\treturn reader.readBytes(length);\n\t\t\t},\n\t\t\twrite: (value, writer) => {\n\t\t\t\tconst array = new Uint8Array(value);\n\t\t\t\twriter.writeULEB(array.length);\n\t\t\t\twriter.writeBytes(array);\n\t\t\t},\n\t\t\t...options,\n\t\t\tname: (options?.name ?? 'vector<u8>') as 'vector<u8>',\n\t\t\tserializedSize: (value) => {\n\t\t\t\tconst length = 'length' in value ? (value.length as number) : null;\n\t\t\t\treturn length == null ? null : ulebEncode(length).length + length;\n\t\t\t},\n\t\t\tvalidate: (value) => {\n\t\t\t\toptions?.validate?.(value);\n\t\t\t\tif (!value || typeof value !== 'object' || !('length' in value)) {\n\t\t\t\t\tthrow new TypeError(`Expected array, found ${typeof value}`);\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType that can ser/de string values. Strings will be UTF-8 encoded\n\t * @example\n\t * bcs.string().serialize('a').toBytes() // Uint8Array [ 1, 97 ]\n\t */\n\tstring(options?: BcsTypeOptions<string>) {\n\t\treturn stringLikeBcsType({\n\t\t\ttoBytes: (value) => new TextEncoder().encode(value),\n\t\t\tfromBytes: (bytes) => new TextDecoder().decode(bytes),\n\t\t\t...options,\n\t\t\tname: (options?.name ?? 'string') as 'string',\n\t\t});\n\t},\n\t/**\n\t * Creates a BcsType that represents a fixed length array of a given type\n\t * @param size The number of elements in the array\n\t * @param type The BcsType of each element in the array\n\t * @example\n\t * bcs.fixedArray(3, bcs.u8()).serialize([1, 2, 3]).toBytes() // Uint8Array [ 1, 2, 3 ]\n\t */\n\tfixedArray,\n\n\t/**\n\t * Creates a BcsType representing an optional value\n\t * @param type The BcsType of the optional value\n\t * @example\n\t * bcs.option(bcs.u8()).serialize(null).toBytes() // Uint8Array [ 0 ]\n\t * bcs.option(bcs.u8()).serialize(1).toBytes() // Uint8Array [ 1, 1 ]\n\t */\n\toption,\n\n\t/**\n\t * Creates a BcsType representing a variable length vector of a given type\n\t * @param type The BcsType of each element in the vector\n\t *\n\t * @example\n\t * bcs.vector(bcs.u8()).toBytes([1, 2, 3]) // Uint8Array [ 3, 1, 2, 3 ]\n\t */\n\tvector,\n\n\t/**\n\t * Creates a BcsType representing a tuple of a given set of types\n\t * @param types The BcsTypes for each element in the tuple\n\t *\n\t * @example\n\t * const tuple = bcs.tuple([bcs.u8(), bcs.string(), bcs.bool()])\n\t * tuple.serialize([1, 'a', true]).toBytes() // Uint8Array [ 1, 1, 97, 1 ]\n\t */\n\ttuple<\n\t\tconst T extends readonly BcsType<any, any>[],\n\t\tconst Name extends string =\n\t\t\t`(${JoinString<{ [K in keyof T]: T[K] extends BcsType<any, any, infer T> ? T : never }, ', '>})`,\n\t>(\n\t\tfields: T,\n\t\toptions?: BcsTypeOptions<\n\t\t\t{\n\t\t\t\t-readonly [K in keyof T]: T[K] extends BcsType<infer T, any> ? T : never;\n\t\t\t},\n\t\t\t{\n\t\t\t\t[K in keyof T]: T[K] extends BcsType<any, infer T> ? T : never;\n\t\t\t},\n\t\t\tName\n\t\t>,\n\t) {\n\t\treturn new BcsTuple<T, Name>({\n\t\t\tfields,\n\t\t\t...options,\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType representing a struct of a given set of fields\n\t * @param name The name of the struct\n\t * @param fields The fields of the struct. The order of the fields affects how data is serialized and deserialized\n\t *\n\t * @example\n\t * const struct = bcs.struct('MyStruct', {\n\t * a: bcs.u8(),\n\t * b: bcs.string(),\n\t * })\n\t * struct.serialize({ a: 1, b: 'a' }).toBytes() // Uint8Array [ 1, 1, 97 ]\n\t */\n\tstruct<T extends Record<string, BcsType<any>>, const Name extends string = string>(\n\t\tname: Name,\n\t\tfields: T,\n\t\toptions?: Omit<\n\t\t\tBcsTypeOptions<\n\t\t\t\t{\n\t\t\t\t\t[K in keyof T]: T[K] extends BcsType<infer U, any> ? U : never;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t[K in keyof T]: T[K] extends BcsType<any, infer U> ? U : never;\n\t\t\t\t}\n\t\t\t>,\n\t\t\t'name'\n\t\t>,\n\t) {\n\t\treturn new BcsStruct<T>({\n\t\t\tname,\n\t\t\tfields,\n\t\t\t...options,\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType representing an enum of a given set of options\n\t * @param name The name of the enum\n\t * @param values The values of the enum. The order of the values affects how data is serialized and deserialized.\n\t * null can be used to represent a variant with no data.\n\t *\n\t * @example\n\t * const enum = bcs.enum('MyEnum', {\n\t * A: bcs.u8(),\n\t * B: bcs.string(),\n\t * C: null,\n\t * })\n\t * enum.serialize({ A: 1 }).toBytes() // Uint8Array [ 0, 1 ]\n\t * enum.serialize({ B: 'a' }).toBytes() // Uint8Array [ 1, 1, 97 ]\n\t * enum.serialize({ C: true }).toBytes() // Uint8Array [ 2 ]\n\t */\n\tenum<T extends Record<string, BcsType<any> | null>, const Name extends string = string>(\n\t\tname: Name,\n\t\tfields: T,\n\t\toptions?: Omit<\n\t\t\tBcsTypeOptions<\n\t\t\t\tEnumOutputShape<{\n\t\t\t\t\t[K in keyof T]: T[K] extends BcsType<infer U, any, any> ? U : true;\n\t\t\t\t}>,\n\t\t\t\tEnumInputShape<{\n\t\t\t\t\t[K in keyof T]: T[K] extends BcsType<any, infer U, any> ? U : boolean | object | null;\n\t\t\t\t}>,\n\t\t\t\tName\n\t\t\t>,\n\t\t\t'name'\n\t\t>,\n\t) {\n\t\treturn new BcsEnum<T, Name>({\n\t\t\tname,\n\t\t\tfields,\n\t\t\t...options,\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType representing a map of a given key and value type\n\t * @param keyType The BcsType of the key\n\t * @param valueType The BcsType of the value\n\t * @example\n\t * const map = bcs.map(bcs.u8(), bcs.string())\n\t * map.serialize(new Map([[2, 'a']])).toBytes() // Uint8Array [ 1, 2, 1, 97 ]\n\t */\n\tmap,\n\n\t/**\n\t * Creates a BcsType that wraps another BcsType which is lazily evaluated. This is useful for creating recursive types.\n\t * @param cb A callback that returns the BcsType\n\t */\n\tlazy<T extends BcsType<any>>(cb: () => T): T {\n\t\treturn lazyBcsType(cb) as T;\n\t},\n};\n"],"mappings":";;;AAuCA,SAAS,WACR,MACA,MACA,SAKoF;CACpF,OAAO,IAAI,QAAkF;EAC5F,OAAO,WAAW;GACjB,MAAM,SAA4B,IAAI,MAAM,IAAI;GAChD,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,KACzB,OAAO,KAAK,KAAK,KAAK,MAAM;GAE7B,OAAO;EACR;EACA,QAAQ,OAAO,WAAW;GACzB,KAAK,MAAM,QAAQ,OAClB,KAAK,MAAM,MAAM,MAAM;EAEzB;EACA,GAAG;EACH,MAAO,SAAS,QAAQ,GAAG,KAAK,KAAK,GAAG,KAAK;EAC7C,WAAW,UAAU;GACpB,SAAS,WAAW,KAAK;GACzB,IAAI,CAAC,SAAS,OAAO,UAAU,YAAY,EAAE,YAAY,QACxD,MAAM,IAAI,UAAU,yBAAyB,OAAO,OAAO;GAE5D,IAAI,MAAM,WAAW,MACpB,MAAM,IAAI,UAAU,4BAA4B,KAAK,UAAU,MAAM,QAAQ;EAE/E;CACD,CAAC;AACF;AAQA,SAAS,OACR,MAC+F;CAC/F,OAAO,IACL,KAAK,UAAU,KAAK,KAAK,IAAI;EAC7B,MAAM;EACN,MAAM;CACP,CAAC,CAAC,CACD,UAAU;EACV,QAAQ,UAA+C;GACtD,IAAI,SAAS,MACZ,OAAO,EAAE,MAAM,KAAK;GAGrB,OAAO,EAAE,MAAM,MAAM;EACtB;EACA,SAAS,UAAU;GAClB,IAAI,MAAM,UAAU,QACnB,OAAO,MAAM;GAGd,OAAO;EACR;CACD,CAAC;AACH;AAcA,SAAS,OACR,MACA,SAKoF;CACpF,OAAO,IAAI,QAAkF;EAC5F,OAAO,WAAW;GACjB,MAAM,SAAS,OAAO,SAAS;GAC/B,MAAM,SAA4B,IAAI,MAAM,MAAM;GAClD,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,KAC3B,OAAO,KAAK,KAAK,KAAK,MAAM;GAE7B,OAAO;EACR;EACA,QAAQ,OAAO,WAAW;GACzB,OAAO,UAAU,MAAM,MAAM;GAC7B,KAAK,MAAM,QAAQ,OAClB,KAAK,MAAM,MAAM,MAAM;EAEzB;EACA,GAAG;EACH,MAAO,SAAS,QAAQ,UAAU,KAAK,KAAK;EAC5C,WAAW,UAAU;GACpB,SAAS,WAAW,KAAK;GACzB,IAAI,CAAC,SAAS,OAAO,UAAU,YAAY,EAAE,YAAY,QACxD,MAAM,IAAI,UAAU,yBAAyB,OAAO,OAAO;EAE7D;CACD,CAAC;AACF;;;;;;AAOA,SAAgB,gBAAgB,GAAe,GAAuB;CACrE,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,KACjD,IAAI,EAAE,OAAO,EAAE,IACd,OAAO,EAAE,KAAK,EAAE;CAIlB,OAAO,EAAE,SAAS,EAAE;AACrB;AAcA,SAAS,IACR,SACA,WAKC;CACD,OAAO,IAAI,QAAQ;EAClB,MAAM,OAAO,QAAQ,KAAK,IAAI,UAAU,KAAK;EAC7C,OAAO,WAAW;GACjB,MAAM,SAAS,OAAO,SAAS;GAC/B,MAAM,yBAAS,IAAI,IAAsC;GACzD,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,KAC3B,OAAO,IAAI,QAAQ,KAAK,MAAM,GAAG,UAAU,KAAK,MAAM,CAAC;GAExD,OAAO;EACR;EACA,QAAQ,OAAO,WAAW;GACzB,MAAM,UAAU,CAAC,GAAG,MAAM,QAAQ,CAAC,CAAC,CAAC,KACnC,CAAC,KAAK,SAAS,CAAC,QAAQ,UAAU,GAAG,CAAC,CAAC,QAAQ,GAAG,GAAG,CACvD;GACA,QAAQ,MAAM,CAAC,IAAI,CAAC,OAAO,gBAAgB,GAAG,CAAC,CAAC;GAEhD,OAAO,UAAU,QAAQ,MAAM;GAC/B,KAAK,MAAM,CAAC,UAAU,QAAQ,SAAS;IACtC,OAAO,WAAW,QAAQ;IAC1B,UAAU,MAAM,KAAK,MAAM;GAC5B;EACD;CACD,CAAC;AACF;AAEA,MAAa,MAAM;;;;;;CAMlB,GAAG,SAAkC;EACpC,OAAO,YAAY;GAClB,YAAY;GACZ,aAAa;GACb,MAAM;GACN,UAAU,KAAK,IAAI;GACnB,GAAG;GACH,MAAO,SAAS,QAAQ;EACzB,CAAC;CACF;;;;;;CAOA,IAAI,SAAkC;EACrC,OAAO,YAAY;GAClB,YAAY;GACZ,aAAa;GACb,MAAM;GACN,UAAU,KAAK,KAAK;GACpB,GAAG;GACH,MAAO,SAAS,QAAQ;EACzB,CAAC;CACF;;;;;;CAOA,IAAI,SAAkC;EACrC,OAAO,YAAY;GAClB,YAAY;GACZ,aAAa;GACb,MAAM;GACN,UAAU,KAAK,KAAK;GACpB,GAAG;GACH,MAAO,SAAS,QAAQ;EACzB,CAAC;CACF;;;;;;CAOA,IAAI,SAA4D;EAC/D,OAAO,eAAe;GACrB,YAAY;GACZ,aAAa;GACb,MAAM;GACN,UAAU,MAAM,MAAM;GACtB,GAAG;GACH,MAAO,SAAS,QAAQ;EACzB,CAAC;CACF;;;;;;CAOA,KAAK,SAA4D;EAChE,OAAO,eAAe;GACrB,YAAY;GACZ,aAAa;GACb,MAAM;GACN,UAAU,MAAM,OAAO;GACvB,GAAG;GACH,MAAO,SAAS,QAAQ;EACzB,CAAC;CACF;;;;;;CAOA,KAAK,SAA4D;EAChE,OAAO,eAAe;GACrB,YAAY;GACZ,aAAa;GACb,MAAM;GACN,UAAU,MAAM,OAAO;GACvB,GAAG;GACH,MAAO,SAAS,QAAQ;EACzB,CAAC;CACF;;;;;;CAOA,KAAK,SAAmC;EACvC,OAAO,iBAAiB;GACvB,MAAM;GACN,OAAO,WAAW,OAAO,MAAM,MAAM;GACrC,QAAQ,OAAO,WAAW,OAAO,OAAO,QAAQ,IAAI,CAAC;GACrD,GAAG;GACH,MAAO,SAAS,QAAQ;GACxB,WAAW,UAAU;IACpB,SAAS,WAAW,KAAK;IACzB,IAAI,OAAO,UAAU,WACpB,MAAM,IAAI,UAAU,2BAA2B,OAAO,OAAO;GAE/D;EACD,CAAC;CACF;;;;;;CAOA,QAAQ,SAAkC;EACzC,OAAO,mBAAmB;GACzB,OAAO,WAAW,OAAO,SAAS;GAClC,YAAY,UAAU;IACrB,OAAO,WAAW,KAAK,WAAW,KAAK,CAAC;GACzC;GACA,GAAG;GACH,MAAO,SAAS,QAAQ;EACzB,CAAC;CACF;;;;;;;CAQA,MAAwB,MAAS,SAAwD;EACxF,OAAO,iBAA8D;GACpE;GACA,OAAO,WAAW,OAAO,UAAU,IAAI;GACvC,QAAQ,OAAO,WAAW;IACzB,OAAO,WAAW,IAAI,WAAW,KAAK,CAAC;GACxC;GACA,GAAG;GACH,MAAO,SAAS,QAAQ,SAAS,KAAK;GACtC,WAAW,UAAU;IACpB,SAAS,WAAW,KAAK;IACzB,IAAI,CAAC,SAAS,OAAO,UAAU,YAAY,EAAE,YAAY,QACxD,MAAM,IAAI,UAAU,yBAAyB,OAAO,OAAO;IAE5D,IAAI,MAAM,WAAW,MACpB,MAAM,IAAI,UAAU,4BAA4B,KAAK,UAAU,MAAM,QAAQ;GAE/E;EACD,CAAC;CACF;;;;;;;CAQA,WAAW,SAAwD;EAClE,OAAO,IAAI,QAAoD;GAC9D,OAAO,WAAW;IACjB,MAAM,SAAS,OAAO,SAAS;IAE/B,OAAO,OAAO,UAAU,MAAM;GAC/B;GACA,QAAQ,OAAO,WAAW;IACzB,MAAM,QAAQ,IAAI,WAAW,KAAK;IAClC,OAAO,UAAU,MAAM,MAAM;IAC7B,OAAO,WAAW,KAAK;GACxB;GACA,GAAG;GACH,MAAO,SAAS,QAAQ;GACxB,iBAAiB,UAAU;IAC1B,MAAM,SAAS,YAAY,QAAS,MAAM,SAAoB;IAC9D,OAAO,UAAU,OAAO,OAAO,WAAW,MAAM,CAAC,CAAC,SAAS;GAC5D;GACA,WAAW,UAAU;IACpB,SAAS,WAAW,KAAK;IACzB,IAAI,CAAC,SAAS,OAAO,UAAU,YAAY,EAAE,YAAY,QACxD,MAAM,IAAI,UAAU,yBAAyB,OAAO,OAAO;GAE7D;EACD,CAAC;CACF;;;;;;CAOA,OAAO,SAAkC;EACxC,OAAO,kBAAkB;GACxB,UAAU,UAAU,IAAI,YAAY,CAAC,CAAC,OAAO,KAAK;GAClD,YAAY,UAAU,IAAI,YAAY,CAAC,CAAC,OAAO,KAAK;GACpD,GAAG;GACH,MAAO,SAAS,QAAQ;EACzB,CAAC;CACF;;;;;;;;CAQA;;;;;;;;CASA;;;;;;;;CASA;;;;;;;;;CAUA,MAKC,QACA,SASC;EACD,OAAO,IAAI,SAAkB;GAC5B;GACA,GAAG;EACJ,CAAC;CACF;;;;;;;;;;;;;CAcA,OACC,MACA,QACA,SAWC;EACD,OAAO,IAAI,UAAa;GACvB;GACA;GACA,GAAG;EACJ,CAAC;CACF;;;;;;;;;;;;;;;;;CAkBA,KACC,MACA,QACA,SAYC;EACD,OAAO,IAAI,QAAiB;GAC3B;GACA;GACA,GAAG;EACJ,CAAC;CACF;;;;;;;;;CAUA;;;;;CAMA,KAA6B,IAAgB;EAC5C,OAAO,YAAY,EAAE;CACtB;AACD"}
1
+ {"version":3,"file":"bcs.mjs","names":[],"sources":["../src/bcs.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { BcsTypeOptions } from './bcs-type.js';\nimport {\n\tBcsEnum,\n\tBcsStruct,\n\tBcsTuple,\n\tBcsType,\n\tbigUIntBcsType,\n\tdynamicSizeBcsType,\n\tfixedSizeBcsType,\n\tlazyBcsType,\n\tstringLikeBcsType,\n\tuIntBcsType,\n} from './bcs-type.js';\nimport type {\n\tEnumInputShape,\n\tEnumOutputShape,\n\tInferBcsInput,\n\tInferBcsType,\n\tJoinString,\n} from './types.js';\nimport { ulebEncode } from './uleb.js';\n\nfunction fixedArray<T extends BcsType<any>, Name extends string = string>(\n\tsize: number,\n\ttype: T,\n\toptions?: BcsTypeOptions<\n\t\tInferBcsType<T>[],\n\t\tIterable<InferBcsInput<T>> & { length: number },\n\t\tName\n\t>,\n): BcsType<InferBcsType<T>[], Iterable<InferBcsInput<T>> & { length: number }, Name>;\nfunction fixedArray<T, Input, Name extends string = string>(\n\tsize: number,\n\ttype: BcsType<T, Input>,\n\toptions?: BcsTypeOptions<T[], Iterable<Input> & { length: number }, Name>,\n): BcsType<T[], Iterable<Input> & { length: number }, Name>;\nfunction fixedArray<T extends BcsType<any>, Name extends string = `${T['name']}[${number}]`>(\n\tsize: number,\n\ttype: T,\n\toptions?: BcsTypeOptions<\n\t\tInferBcsType<T>[],\n\t\tIterable<InferBcsInput<T>> & { length: number },\n\t\tName\n\t>,\n): BcsType<InferBcsType<T>[], Iterable<InferBcsInput<T>> & { length: number }, Name> {\n\treturn new BcsType<InferBcsType<T>[], Iterable<InferBcsInput<T>> & { length: number }, Name>({\n\t\tread: (reader) => {\n\t\t\tconst result: InferBcsType<T>[] = new Array(size);\n\t\t\tfor (let i = 0; i < size; i++) {\n\t\t\t\tresult[i] = type.read(reader);\n\t\t\t}\n\t\t\treturn result;\n\t\t},\n\t\twrite: (value, writer) => {\n\t\t\tfor (const item of value) {\n\t\t\t\ttype.write(item, writer);\n\t\t\t}\n\t\t},\n\t\t...options,\n\t\tname: (options?.name ?? `${type.name}[${size}]`) as Name,\n\t\tvalidate: (value) => {\n\t\t\toptions?.validate?.(value);\n\t\t\tif (!value || typeof value !== 'object' || !('length' in value)) {\n\t\t\t\tthrow new TypeError(`Expected array, found ${typeof value}`);\n\t\t\t}\n\t\t\tif (value.length !== size) {\n\t\t\t\tthrow new TypeError(`Expected array of length ${size}, found ${value.length}`);\n\t\t\t}\n\t\t},\n\t});\n}\n\nfunction option<T extends BcsType<any>>(\n\ttype: T,\n): BcsType<InferBcsType<T> | null, InferBcsInput<T> | null | undefined, `Option<${T['name']}>`>;\nfunction option<T, Input, Name extends string = string>(\n\ttype: BcsType<T, Input, Name>,\n): BcsType<T | null, Input | null | undefined>;\nfunction option<T extends BcsType<any>>(\n\ttype: T,\n): BcsType<InferBcsType<T> | null, InferBcsInput<T> | null | undefined, `Option<${T['name']}>`> {\n\t// Encoded like enum Option { None, Some(T) }, but read and written directly rather than\n\t// through an intermediate { None } / { Some } enum object\n\tconst name = `Option<${type.name}>` as const;\n\treturn new BcsType<\n\t\tInferBcsType<T> | null,\n\t\tInferBcsInput<T> | null | undefined,\n\t\t`Option<${T['name']}>`\n\t>({\n\t\tname,\n\t\tread: (reader) => {\n\t\t\tconst index = reader.readULEB();\n\t\t\tif (index === 0) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (index === 1) {\n\t\t\t\treturn type.read(reader);\n\t\t\t}\n\t\t\tthrow new TypeError(`Unknown value ${index} for enum ${name}`);\n\t\t},\n\t\twrite: (value, writer) => {\n\t\t\tif (value == null) {\n\t\t\t\twriter.write8(0);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\twriter.write8(1);\n\t\t\ttype.write(value, writer);\n\t\t},\n\t});\n}\n\nfunction vector<T extends BcsType<any>, Name extends string = `vector<${T['name']}>`>(\n\ttype: T,\n\toptions?: BcsTypeOptions<\n\t\tInferBcsType<T>[],\n\t\tIterable<InferBcsInput<T>> & { length: number },\n\t\tName\n\t>,\n): BcsType<InferBcsType<T>[], Iterable<InferBcsInput<T>> & { length: number }, Name>;\nfunction vector<T, Input, Name extends string = string>(\n\ttype: BcsType<T, Input, Name>,\n\toptions?: BcsTypeOptions<T[], Iterable<Input> & { length: number }, `vector<${Name}>`>,\n): BcsType<T[], Iterable<Input> & { length: number }, `vector<${Name}>`>;\nfunction vector<T extends BcsType<any>, Name extends string = `vector<${T['name']}>`>(\n\ttype: T,\n\toptions?: BcsTypeOptions<\n\t\tInferBcsType<T>[],\n\t\tIterable<InferBcsInput<T>> & { length: number },\n\t\tName\n\t>,\n): BcsType<InferBcsType<T>[], Iterable<InferBcsInput<T>> & { length: number }, Name> {\n\treturn new BcsType<InferBcsType<T>[], Iterable<InferBcsInput<T>> & { length: number }, Name>({\n\t\tread: (reader) => {\n\t\t\tconst length = reader.readULEB();\n\t\t\tconst result: InferBcsType<T>[] = new Array(length);\n\t\t\tfor (let i = 0; i < length; i++) {\n\t\t\t\tresult[i] = type.read(reader);\n\t\t\t}\n\t\t\treturn result;\n\t\t},\n\t\twrite: (value, writer) => {\n\t\t\twriter.writeULEB(value.length);\n\t\t\tfor (const item of value) {\n\t\t\t\ttype.write(item, writer);\n\t\t\t}\n\t\t},\n\t\t...options,\n\t\tname: (options?.name ?? `vector<${type.name}>`) as Name,\n\t\tvalidate: (value) => {\n\t\t\toptions?.validate?.(value);\n\t\t\tif (!value || typeof value !== 'object' || !('length' in value)) {\n\t\t\t\tthrow new TypeError(`Expected array, found ${typeof value}`);\n\t\t\t}\n\t\t},\n\t});\n}\n\n/**\n * Compares two byte arrays using lexicographic ordering.\n * This matches Rust's Ord implementation for Vec<u8>/[u8] which is used for BTreeMap key ordering.\n * Comparison is done byte-by-byte first, then by length if all compared bytes are equal.\n */\nexport function compareBcsBytes(a: Uint8Array, b: Uint8Array): number {\n\tfor (let i = 0; i < Math.min(a.length, b.length); i++) {\n\t\tif (a[i] !== b[i]) {\n\t\t\treturn a[i] - b[i];\n\t\t}\n\t}\n\n\treturn a.length - b.length;\n}\n\nfunction map<K extends BcsType<any>, V extends BcsType<any>>(\n\tkeyType: K,\n\tvalueType: V,\n): BcsType<\n\tMap<InferBcsType<K>, InferBcsType<V>>,\n\tMap<InferBcsInput<K>, InferBcsInput<V>>,\n\t`Map<${K['name']}, ${V['name']}>`\n>;\nfunction map<K, V, InputK = K, InputV = V>(\n\tkeyType: BcsType<K, InputK>,\n\tvalueType: BcsType<V, InputV>,\n): BcsType<Map<K, V>, Map<InputK, InputV>, `Map<${string}, ${string}>`>;\nfunction map<K extends BcsType<any>, V extends BcsType<any>>(\n\tkeyType: K,\n\tvalueType: V,\n): BcsType<\n\tMap<InferBcsType<K>, InferBcsType<V>>,\n\tMap<InferBcsInput<K>, InferBcsInput<V>>,\n\t`Map<${K['name']}, ${V['name']}>`\n> {\n\treturn new BcsType({\n\t\tname: `Map<${keyType.name}, ${valueType.name}>`,\n\t\tread: (reader) => {\n\t\t\tconst length = reader.readULEB();\n\t\t\tconst result = new Map<InferBcsType<K>, InferBcsType<V>>();\n\t\t\tfor (let i = 0; i < length; i++) {\n\t\t\t\tresult.set(keyType.read(reader), valueType.read(reader));\n\t\t\t}\n\t\t\treturn result;\n\t\t},\n\t\twrite: (value, writer) => {\n\t\t\tconst entries = [...value.entries()].map(\n\t\t\t\t([key, val]) => [keyType.serialize(key).toBytes(), val] as const,\n\t\t\t);\n\t\t\tentries.sort(([a], [b]) => compareBcsBytes(a, b));\n\n\t\t\twriter.writeULEB(entries.length);\n\t\t\tfor (const [keyBytes, val] of entries) {\n\t\t\t\twriter.writeBytes(keyBytes);\n\t\t\t\tvalueType.write(val, writer);\n\t\t\t}\n\t\t},\n\t});\n}\n\n// Created on first use, so importing the package doesn't require TextEncoder/TextDecoder\nlet utf8Encoder: TextEncoder | undefined;\nlet utf8Decoder: TextDecoder | undefined;\nfunction decoder() {\n\treturn (utf8Decoder ??= new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }));\n}\n\n// Most strings in Haneul data (module, function and type names) are short ASCII. Decoding those\n// directly avoids the fixed cost of a TextDecoder call; anything else goes through the decoder.\nconst ASCII_FAST_PATH_MAX_LENGTH = 64;\nfunction decodeUtf8(bytes: Uint8Array): string {\n\tif (bytes.length <= ASCII_FAST_PATH_MAX_LENGTH) {\n\t\tlet result = '';\n\t\tfor (let i = 0; i < bytes.length; i++) {\n\t\t\tconst byte = bytes[i];\n\t\t\tif (byte >= 0x80) {\n\t\t\t\treturn decoder().decode(bytes);\n\t\t\t}\n\t\t\tresult += String.fromCharCode(byte);\n\t\t}\n\t\treturn result;\n\t}\n\n\treturn decoder().decode(bytes);\n}\n\nexport const bcs = {\n\t/**\n\t * Creates a BcsType that can be used to read and write an 8-bit unsigned integer.\n\t * @example\n\t * bcs.u8().serialize(255).toBytes() // Uint8Array [ 255 ]\n\t */\n\tu8(options?: BcsTypeOptions<number>) {\n\t\treturn uIntBcsType({\n\t\t\treadMethod: 'read8',\n\t\t\twriteMethod: 'write8',\n\t\t\tsize: 1,\n\t\t\tmaxValue: 2 ** 8 - 1,\n\t\t\t...options,\n\t\t\tname: (options?.name ?? 'u8') as 'u8',\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType that can be used to read and write a 16-bit unsigned integer.\n\t * @example\n\t * bcs.u16().serialize(65535).toBytes() // Uint8Array [ 255, 255 ]\n\t */\n\tu16(options?: BcsTypeOptions<number>) {\n\t\treturn uIntBcsType({\n\t\t\treadMethod: 'read16',\n\t\t\twriteMethod: 'write16',\n\t\t\tsize: 2,\n\t\t\tmaxValue: 2 ** 16 - 1,\n\t\t\t...options,\n\t\t\tname: (options?.name ?? 'u16') as 'u16',\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType that can be used to read and write a 32-bit unsigned integer.\n\t * @example\n\t * bcs.u32().serialize(4294967295).toBytes() // Uint8Array [ 255, 255, 255, 255 ]\n\t */\n\tu32(options?: BcsTypeOptions<number>) {\n\t\treturn uIntBcsType({\n\t\t\treadMethod: 'read32',\n\t\t\twriteMethod: 'write32',\n\t\t\tsize: 4,\n\t\t\tmaxValue: 2 ** 32 - 1,\n\t\t\t...options,\n\t\t\tname: (options?.name ?? 'u32') as 'u32',\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType that can be used to read and write a 64-bit unsigned integer.\n\t * @example\n\t * bcs.u64().serialize(1).toBytes() // Uint8Array [ 1, 0, 0, 0, 0, 0, 0, 0 ]\n\t */\n\tu64(options?: BcsTypeOptions<string, number | bigint | string>) {\n\t\treturn bigUIntBcsType({\n\t\t\treadMethod: 'read64',\n\t\t\twriteMethod: 'write64',\n\t\t\tsize: 8,\n\t\t\tmaxValue: 2n ** 64n - 1n,\n\t\t\t...options,\n\t\t\tname: (options?.name ?? 'u64') as 'u64',\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType that can be used to read and write a 128-bit unsigned integer.\n\t * @example\n\t * bcs.u128().serialize(1).toBytes() // Uint8Array [ 1, ..., 0 ]\n\t */\n\tu128(options?: BcsTypeOptions<string, number | bigint | string>) {\n\t\treturn bigUIntBcsType({\n\t\t\treadMethod: 'read128',\n\t\t\twriteMethod: 'write128',\n\t\t\tsize: 16,\n\t\t\tmaxValue: 2n ** 128n - 1n,\n\t\t\t...options,\n\t\t\tname: (options?.name ?? 'u128') as 'u128',\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType that can be used to read and write a 256-bit unsigned integer.\n\t * @example\n\t * bcs.u256().serialize(1).toBytes() // Uint8Array [ 1, ..., 0 ]\n\t */\n\tu256(options?: BcsTypeOptions<string, number | bigint | string>) {\n\t\treturn bigUIntBcsType({\n\t\t\treadMethod: 'read256',\n\t\t\twriteMethod: 'write256',\n\t\t\tsize: 32,\n\t\t\tmaxValue: 2n ** 256n - 1n,\n\t\t\t...options,\n\t\t\tname: (options?.name ?? 'u256') as 'u256',\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType that can be used to read and write boolean values.\n\t * @example\n\t * bcs.bool().serialize(true).toBytes() // Uint8Array [ 1 ]\n\t */\n\tbool(options?: BcsTypeOptions<boolean>) {\n\t\treturn fixedSizeBcsType({\n\t\t\tsize: 1,\n\t\t\tread: (reader) => {\n\t\t\t\tconst value = reader.read8();\n\t\t\t\tif (value > 1) {\n\t\t\t\t\tthrow new TypeError(`Invalid bool value: expected 0 or 1, found ${value}`);\n\t\t\t\t}\n\t\t\t\treturn value === 1;\n\t\t\t},\n\t\t\twrite: (value, writer) => writer.write8(value ? 1 : 0),\n\t\t\t...options,\n\t\t\tname: (options?.name ?? 'bool') as 'bool',\n\t\t\tvalidate: (value) => {\n\t\t\t\toptions?.validate?.(value);\n\t\t\t\tif (typeof value !== 'boolean') {\n\t\t\t\t\tthrow new TypeError(`Expected boolean, found ${typeof value}`);\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType that can be used to read and write unsigned LEB encoded integers\n\t * @example\n\t *\n\t */\n\tuleb128(options?: BcsTypeOptions<number>) {\n\t\treturn dynamicSizeBcsType({\n\t\t\tread: (reader) => reader.readULEB(),\n\t\t\tserialize: (value) => {\n\t\t\t\treturn Uint8Array.from(ulebEncode(value));\n\t\t\t},\n\t\t\t...options,\n\t\t\tname: (options?.name ?? 'uleb128') as 'uleb128',\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType representing a fixed length byte array\n\t * @param size The number of bytes this types represents\n\t * @example\n\t * bcs.bytes(3).serialize(new Uint8Array([1, 2, 3])).toBytes() // Uint8Array [1, 2, 3]\n\t */\n\tbytes<T extends number>(size: T, options?: BcsTypeOptions<Uint8Array, Iterable<number>>) {\n\t\treturn fixedSizeBcsType<Uint8Array, Iterable<number>, `bytes[${T}]`>({\n\t\t\tsize,\n\t\t\tread: (reader) => reader.readBytes(size),\n\t\t\twrite: (value, writer) => {\n\t\t\t\twriter.writeBytes(value instanceof Uint8Array ? value : new Uint8Array(value));\n\t\t\t},\n\t\t\t...options,\n\t\t\tname: (options?.name ?? `bytes[${size}]`) as `bytes[${T}]`,\n\t\t\tvalidate: (value) => {\n\t\t\t\toptions?.validate?.(value);\n\t\t\t\tif (!value || typeof value !== 'object' || !('length' in value)) {\n\t\t\t\t\tthrow new TypeError(`Expected array, found ${typeof value}`);\n\t\t\t\t}\n\t\t\t\tif (value.length !== size) {\n\t\t\t\t\tthrow new TypeError(`Expected array of length ${size}, found ${value.length}`);\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType representing a variable length byte array\n\t *\n\t * @example\n\t * bcs.byteVector().serialize([1, 2, 3]).toBytes() // Uint8Array [3, 1, 2, 3]\n\t */\n\tbyteVector(options?: BcsTypeOptions<Uint8Array, Iterable<number>>) {\n\t\treturn new BcsType<Uint8Array, Iterable<number>, 'vector<u8>'>({\n\t\t\tread: (reader) => {\n\t\t\t\tconst length = reader.readULEB();\n\n\t\t\t\treturn reader.readBytes(length);\n\t\t\t},\n\t\t\twrite: (value, writer) => {\n\t\t\t\tconst array = value instanceof Uint8Array ? value : new Uint8Array(value);\n\t\t\t\twriter.writeULEB(array.length);\n\t\t\t\twriter.writeBytes(array);\n\t\t\t},\n\t\t\t...options,\n\t\t\tname: (options?.name ?? 'vector<u8>') as 'vector<u8>',\n\t\t\tserializedSize: (value) => {\n\t\t\t\tconst length = 'length' in value ? (value.length as number) : null;\n\t\t\t\treturn length == null ? null : ulebEncode(length).length + length;\n\t\t\t},\n\t\t\tvalidate: (value) => {\n\t\t\t\toptions?.validate?.(value);\n\t\t\t\tif (!value || typeof value !== 'object' || !('length' in value)) {\n\t\t\t\t\tthrow new TypeError(`Expected array, found ${typeof value}`);\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType that can ser/de string values. Strings will be UTF-8 encoded\n\t * @example\n\t * bcs.string().serialize('a').toBytes() // Uint8Array [ 1, 97 ]\n\t */\n\tstring(options?: BcsTypeOptions<string>) {\n\t\treturn stringLikeBcsType({\n\t\t\ttoBytes: (value) => (utf8Encoder ??= new TextEncoder()).encode(value),\n\t\t\tfromBytes: decodeUtf8,\n\t\t\t...options,\n\t\t\tname: (options?.name ?? 'string') as 'string',\n\t\t});\n\t},\n\t/**\n\t * Creates a BcsType that represents a fixed length array of a given type\n\t * @param size The number of elements in the array\n\t * @param type The BcsType of each element in the array\n\t * @example\n\t * bcs.fixedArray(3, bcs.u8()).serialize([1, 2, 3]).toBytes() // Uint8Array [ 1, 2, 3 ]\n\t */\n\tfixedArray,\n\n\t/**\n\t * Creates a BcsType representing an optional value\n\t * @param type The BcsType of the optional value\n\t * @example\n\t * bcs.option(bcs.u8()).serialize(null).toBytes() // Uint8Array [ 0 ]\n\t * bcs.option(bcs.u8()).serialize(1).toBytes() // Uint8Array [ 1, 1 ]\n\t */\n\toption,\n\n\t/**\n\t * Creates a BcsType representing a variable length vector of a given type\n\t * @param type The BcsType of each element in the vector\n\t *\n\t * @example\n\t * bcs.vector(bcs.u8()).toBytes([1, 2, 3]) // Uint8Array [ 3, 1, 2, 3 ]\n\t */\n\tvector,\n\n\t/**\n\t * Creates a BcsType representing a tuple of a given set of types\n\t * @param types The BcsTypes for each element in the tuple\n\t *\n\t * @example\n\t * const tuple = bcs.tuple([bcs.u8(), bcs.string(), bcs.bool()])\n\t * tuple.serialize([1, 'a', true]).toBytes() // Uint8Array [ 1, 1, 97, 1 ]\n\t */\n\ttuple<\n\t\tconst T extends readonly BcsType<any, any>[],\n\t\tconst Name extends string =\n\t\t\t`(${JoinString<{ [K in keyof T]: T[K] extends BcsType<any, any, infer T> ? T : never }, ', '>})`,\n\t>(\n\t\tfields: T,\n\t\toptions?: BcsTypeOptions<\n\t\t\t{\n\t\t\t\t-readonly [K in keyof T]: T[K] extends BcsType<infer T, any> ? T : never;\n\t\t\t},\n\t\t\t{\n\t\t\t\t[K in keyof T]: T[K] extends BcsType<any, infer T> ? T : never;\n\t\t\t},\n\t\t\tName\n\t\t>,\n\t) {\n\t\treturn new BcsTuple<T, Name>({\n\t\t\tfields,\n\t\t\t...options,\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType representing a struct of a given set of fields\n\t * @param name The name of the struct\n\t * @param fields The fields of the struct. The order of the fields affects how data is serialized and deserialized\n\t *\n\t * @example\n\t * const struct = bcs.struct('MyStruct', {\n\t * a: bcs.u8(),\n\t * b: bcs.string(),\n\t * })\n\t * struct.serialize({ a: 1, b: 'a' }).toBytes() // Uint8Array [ 1, 1, 97 ]\n\t */\n\tstruct<T extends Record<string, BcsType<any>>, const Name extends string = string>(\n\t\tname: Name,\n\t\tfields: T,\n\t\toptions?: Omit<\n\t\t\tBcsTypeOptions<\n\t\t\t\t{\n\t\t\t\t\t[K in keyof T]: T[K] extends BcsType<infer U, any> ? U : never;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t[K in keyof T]: T[K] extends BcsType<any, infer U> ? U : never;\n\t\t\t\t}\n\t\t\t>,\n\t\t\t'name'\n\t\t>,\n\t) {\n\t\treturn new BcsStruct<T>({\n\t\t\tname,\n\t\t\tfields,\n\t\t\t...options,\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType representing an enum of a given set of options\n\t * @param name The name of the enum\n\t * @param values The values of the enum. The order of the values affects how data is serialized and deserialized.\n\t * null can be used to represent a variant with no data.\n\t *\n\t * @example\n\t * const enum = bcs.enum('MyEnum', {\n\t * A: bcs.u8(),\n\t * B: bcs.string(),\n\t * C: null,\n\t * })\n\t * enum.serialize({ A: 1 }).toBytes() // Uint8Array [ 0, 1 ]\n\t * enum.serialize({ B: 'a' }).toBytes() // Uint8Array [ 1, 1, 97 ]\n\t * enum.serialize({ C: true }).toBytes() // Uint8Array [ 2 ]\n\t */\n\tenum<T extends Record<string, BcsType<any> | null>, const Name extends string = string>(\n\t\tname: Name,\n\t\tfields: T,\n\t\toptions?: Omit<\n\t\t\tBcsTypeOptions<\n\t\t\t\tEnumOutputShape<{\n\t\t\t\t\t[K in keyof T]: T[K] extends BcsType<infer U, any, any> ? U : true;\n\t\t\t\t}>,\n\t\t\t\tEnumInputShape<{\n\t\t\t\t\t[K in keyof T]: T[K] extends BcsType<any, infer U, any> ? U : boolean | object | null;\n\t\t\t\t}>,\n\t\t\t\tName\n\t\t\t>,\n\t\t\t'name'\n\t\t>,\n\t) {\n\t\treturn new BcsEnum<T, Name>({\n\t\t\tname,\n\t\t\tfields,\n\t\t\t...options,\n\t\t});\n\t},\n\n\t/**\n\t * Creates a BcsType representing a map of a given key and value type\n\t * @param keyType The BcsType of the key\n\t * @param valueType The BcsType of the value\n\t * @example\n\t * const map = bcs.map(bcs.u8(), bcs.string())\n\t * map.serialize(new Map([[2, 'a']])).toBytes() // Uint8Array [ 1, 2, 1, 97 ]\n\t */\n\tmap,\n\n\t/**\n\t * Creates a BcsType that wraps another BcsType which is lazily evaluated. This is useful for creating recursive types.\n\t * @param cb A callback that returns the BcsType\n\t */\n\tlazy<T extends BcsType<any>>(cb: () => T): T {\n\t\treturn lazyBcsType(cb) as T;\n\t},\n};\n"],"mappings":"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"}
package/dist/reader.d.mts CHANGED
@@ -31,6 +31,7 @@
31
31
  */
32
32
  declare class BcsReader {
33
33
  private dataView;
34
+ private bytes;
34
35
  private bytePosition;
35
36
  /**
36
37
  * @param {Uint8Array} data Data to use as a buffer.
@@ -1 +1 @@
1
- {"version":3,"file":"reader.d.mts","names":[],"sources":["../src/reader.ts"],"mappings":";;AAmCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAAa,SAAA;EAAA,QACJ,QAAA;EAAA,QACA,YAAA;EA8GyD;;;cAzGrD,IAAA,EAAM,UAAA;;;;;;;EASlB,KAAA,CAAM,KAAA;;;;;EAQN,KAAA;;;;;EASA,MAAA;;;;;EASA,MAAA;;;;;EASA,MAAA;;;;EAWA,OAAA;;;;;EAWA,OAAA;;;;;EAWA,SAAA,CAAU,GAAA,WAAc,UAAA;;;;;;EAaxB,QAAA;;;;;;;EAeA,OAAA,CAAQ,EAAA,GAAK,MAAA,EAAQ,SAAA,EAAW,CAAA,UAAW,MAAA;AAAA"}
1
+ {"version":3,"file":"reader.d.mts","names":[],"sources":["../src/reader.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAiCa;UACJ;UACA;UACA;;;;EAKR,YAAY,MAAM;;;;;;;EAUlB,MAAM;;;;;EAQN;;;;;EAYA;;;;;EASA;;;;;EASA;;;;EAQA;;;;;EAWA;;;;;EAWA,UAAU,cAAc;;;;;;EAiBxB;;;;;;;EAkCA,QAAQ,KAAK,QAAQ,WAAW,WAAW"}
package/dist/reader.mjs CHANGED
@@ -1,4 +1,3 @@
1
- import { ulebDecode } from "./uleb.mjs";
2
1
  //#region src/reader.ts
3
2
  /**
4
3
  * Class used for reading BCS data chunk by chunk. Meant to be used
@@ -37,6 +36,7 @@ var BcsReader = class {
37
36
  constructor(data) {
38
37
  this.bytePosition = 0;
39
38
  this.dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);
39
+ this.bytes = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
40
40
  }
41
41
  /**
42
42
  * Shift current cursor position by `bytes`.
@@ -53,9 +53,10 @@ var BcsReader = class {
53
53
  * @returns
54
54
  */
55
55
  read8() {
56
- const value = this.dataView.getUint8(this.bytePosition);
57
- this.shift(1);
58
- return value;
56
+ const position = this.bytePosition;
57
+ if (position >= this.bytes.length) throw new RangeError("Offset is outside the bounds of the DataView");
58
+ this.bytePosition = position + 1;
59
+ return this.bytes[position];
59
60
  }
60
61
  /**
61
62
  * Read U16 value from the buffer and shift cursor by 2.
@@ -80,9 +81,9 @@ var BcsReader = class {
80
81
  * @returns
81
82
  */
82
83
  read64() {
83
- const value1 = this.read32();
84
- const result = this.read32().toString(16) + value1.toString(16).padStart(8, "0");
85
- return BigInt("0x" + result).toString(10);
84
+ const value = this.dataView.getBigUint64(this.bytePosition, true);
85
+ this.shift(8);
86
+ return value.toString(10);
86
87
  }
87
88
  /**
88
89
  * Read U128 value from the buffer and shift cursor by 16.
@@ -106,6 +107,7 @@ var BcsReader = class {
106
107
  * @param num Number of bytes to read.
107
108
  */
108
109
  readBytes(num) {
110
+ if (this.bytePosition + num > this.bytes.length) throw new RangeError("Offset is outside the bounds of the DataView");
109
111
  const start = this.bytePosition + this.dataView.byteOffset;
110
112
  const value = new Uint8Array(this.dataView.buffer, start, num);
111
113
  this.shift(num);
@@ -117,9 +119,22 @@ var BcsReader = class {
117
119
  * @returns {Number} The ULEB value.
118
120
  */
119
121
  readULEB() {
120
- const start = this.bytePosition + this.dataView.byteOffset;
121
- const { value, length } = ulebDecode(new Uint8Array(this.dataView.buffer, start));
122
- this.shift(length);
122
+ const bytes = this.bytes;
123
+ let position = this.bytePosition;
124
+ let value = 0;
125
+ let multiplier = 1;
126
+ while (true) {
127
+ if (position >= bytes.length) throw new Error("ULEB decode error: buffer overflow");
128
+ const byte = bytes[position++];
129
+ value += (byte & 127) * multiplier;
130
+ if ((byte & 128) === 0) {
131
+ if (byte === 0 && position - this.bytePosition > 1) throw new Error("ULEB decode error: non-canonical encoding");
132
+ break;
133
+ }
134
+ multiplier *= 128;
135
+ }
136
+ if (!(value <= Number.MAX_SAFE_INTEGER)) throw new Error("ULEB decode error: value exceeds MAX_SAFE_INTEGER");
137
+ this.bytePosition = position;
123
138
  return value;
124
139
  }
125
140
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"reader.mjs","names":[],"sources":["../src/reader.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { ulebDecode } from './uleb.js';\n\n/**\n * Class used for reading BCS data chunk by chunk. Meant to be used\n * by some wrapper, which will make sure that data is valid and is\n * matching the desired format.\n *\n * @example\n * // data for this example is:\n * // { a: u8, b: u32, c: bool, d: u64 }\n *\n * let reader = new BcsReader(\"647f1a060001ffffe7890423c78a050102030405\");\n * let field1 = reader.read8();\n * let field2 = reader.read32();\n * let field3 = reader.read8() === '1'; // bool\n * let field4 = reader.read64();\n * // ....\n *\n * Reading vectors is another deal in bcs. To read a vector, you first need to read\n * its length using {@link readULEB}. Here's an example:\n * @example\n * // data encoded: { field: [1, 2, 3, 4, 5] }\n * let reader = new BcsReader(\"050102030405\");\n * let vec_length = reader.readULEB();\n * let elements = [];\n * for (let i = 0; i < vec_length; i++) {\n * elements.push(reader.read8());\n * }\n * console.log(elements); // [1,2,3,4,5]\n *\n * @param {String} data HEX-encoded data (serialized BCS)\n */\nexport class BcsReader {\n\tprivate dataView: DataView;\n\tprivate bytePosition: number = 0;\n\n\t/**\n\t * @param {Uint8Array} data Data to use as a buffer.\n\t */\n\tconstructor(data: Uint8Array) {\n\t\tthis.dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\t}\n\t/**\n\t * Shift current cursor position by `bytes`.\n\t *\n\t * @param {Number} bytes Number of bytes to\n\t * @returns {this} Self for possible chaining.\n\t */\n\tshift(bytes: number) {\n\t\tthis.bytePosition += bytes;\n\t\treturn this;\n\t}\n\t/**\n\t * Read U8 value from the buffer and shift cursor by 1.\n\t * @returns\n\t */\n\tread8(): number {\n\t\tconst value = this.dataView.getUint8(this.bytePosition);\n\t\tthis.shift(1);\n\t\treturn value;\n\t}\n\t/**\n\t * Read U16 value from the buffer and shift cursor by 2.\n\t * @returns\n\t */\n\tread16(): number {\n\t\tconst value = this.dataView.getUint16(this.bytePosition, true);\n\t\tthis.shift(2);\n\t\treturn value;\n\t}\n\t/**\n\t * Read U32 value from the buffer and shift cursor by 4.\n\t * @returns\n\t */\n\tread32(): number {\n\t\tconst value = this.dataView.getUint32(this.bytePosition, true);\n\t\tthis.shift(4);\n\t\treturn value;\n\t}\n\t/**\n\t * Read U64 value from the buffer and shift cursor by 8.\n\t * @returns\n\t */\n\tread64(): string {\n\t\tconst value1 = this.read32();\n\t\tconst value2 = this.read32();\n\n\t\tconst result = value2.toString(16) + value1.toString(16).padStart(8, '0');\n\n\t\treturn BigInt('0x' + result).toString(10);\n\t}\n\t/**\n\t * Read U128 value from the buffer and shift cursor by 16.\n\t */\n\tread128(): string {\n\t\tconst value1 = BigInt(this.read64());\n\t\tconst value2 = BigInt(this.read64());\n\t\tconst result = value2.toString(16) + value1.toString(16).padStart(16, '0');\n\n\t\treturn BigInt('0x' + result).toString(10);\n\t}\n\t/**\n\t * Read U128 value from the buffer and shift cursor by 32.\n\t * @returns\n\t */\n\tread256(): string {\n\t\tconst value1 = BigInt(this.read128());\n\t\tconst value2 = BigInt(this.read128());\n\t\tconst result = value2.toString(16) + value1.toString(16).padStart(32, '0');\n\n\t\treturn BigInt('0x' + result).toString(10);\n\t}\n\t/**\n\t * Read `num` number of bytes from the buffer and shift cursor by `num`.\n\t * @param num Number of bytes to read.\n\t */\n\treadBytes(num: number): Uint8Array {\n\t\tconst start = this.bytePosition + this.dataView.byteOffset;\n\t\tconst value = new Uint8Array(this.dataView.buffer, start, num);\n\n\t\tthis.shift(num);\n\n\t\treturn value;\n\t}\n\t/**\n\t * Read ULEB value - an integer of varying size. Used for enum indexes and\n\t * vector lengths.\n\t * @returns {Number} The ULEB value.\n\t */\n\treadULEB(): number {\n\t\tconst start = this.bytePosition + this.dataView.byteOffset;\n\t\tconst buffer = new Uint8Array(this.dataView.buffer, start);\n\t\tconst { value, length } = ulebDecode(buffer);\n\n\t\tthis.shift(length);\n\n\t\treturn value;\n\t}\n\t/**\n\t * Read a BCS vector: read a length and then apply function `cb` X times\n\t * where X is the length of the vector, defined as ULEB in BCS bytes.\n\t * @param cb Callback to process elements of vector.\n\t * @returns {Array<Any>} Array of the resulting values, returned by callback.\n\t */\n\treadVec(cb: (reader: BcsReader, i: number, length: number) => any): any[] {\n\t\tconst length = this.readULEB();\n\t\tconst result = [];\n\t\tfor (let i = 0; i < length; i++) {\n\t\t\tresult.push(cb(this, i, length));\n\t\t}\n\t\treturn result;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,IAAa,YAAb,MAAuB;;;;CAOtB,YAAY,MAAkB;sBALC;EAM9B,KAAK,WAAW,IAAI,SAAS,KAAK,QAAQ,KAAK,YAAY,KAAK,UAAU;CAC3E;;;;;;;CAOA,MAAM,OAAe;EACpB,KAAK,gBAAgB;EACrB,OAAO;CACR;;;;;CAKA,QAAgB;EACf,MAAM,QAAQ,KAAK,SAAS,SAAS,KAAK,YAAY;EACtD,KAAK,MAAM,CAAC;EACZ,OAAO;CACR;;;;;CAKA,SAAiB;EAChB,MAAM,QAAQ,KAAK,SAAS,UAAU,KAAK,cAAc,IAAI;EAC7D,KAAK,MAAM,CAAC;EACZ,OAAO;CACR;;;;;CAKA,SAAiB;EAChB,MAAM,QAAQ,KAAK,SAAS,UAAU,KAAK,cAAc,IAAI;EAC7D,KAAK,MAAM,CAAC;EACZ,OAAO;CACR;;;;;CAKA,SAAiB;EAChB,MAAM,SAAS,KAAK,OAAO;EAG3B,MAAM,SAFS,KAAK,OAEA,CAAC,CAAC,SAAS,EAAE,IAAI,OAAO,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG;EAExE,OAAO,OAAO,OAAO,MAAM,CAAC,CAAC,SAAS,EAAE;CACzC;;;;CAIA,UAAkB;EACjB,MAAM,SAAS,OAAO,KAAK,OAAO,CAAC;EAEnC,MAAM,SADS,OAAO,KAAK,OAAO,CACd,CAAC,CAAC,SAAS,EAAE,IAAI,OAAO,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,GAAG;EAEzE,OAAO,OAAO,OAAO,MAAM,CAAC,CAAC,SAAS,EAAE;CACzC;;;;;CAKA,UAAkB;EACjB,MAAM,SAAS,OAAO,KAAK,QAAQ,CAAC;EAEpC,MAAM,SADS,OAAO,KAAK,QAAQ,CACf,CAAC,CAAC,SAAS,EAAE,IAAI,OAAO,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,GAAG;EAEzE,OAAO,OAAO,OAAO,MAAM,CAAC,CAAC,SAAS,EAAE;CACzC;;;;;CAKA,UAAU,KAAyB;EAClC,MAAM,QAAQ,KAAK,eAAe,KAAK,SAAS;EAChD,MAAM,QAAQ,IAAI,WAAW,KAAK,SAAS,QAAQ,OAAO,GAAG;EAE7D,KAAK,MAAM,GAAG;EAEd,OAAO;CACR;;;;;;CAMA,WAAmB;EAClB,MAAM,QAAQ,KAAK,eAAe,KAAK,SAAS;EAEhD,MAAM,EAAE,OAAO,WAAW,WAAW,IADlB,WAAW,KAAK,SAAS,QAAQ,KACV,CAAC;EAE3C,KAAK,MAAM,MAAM;EAEjB,OAAO;CACR;;;;;;;CAOA,QAAQ,IAAkE;EACzE,MAAM,SAAS,KAAK,SAAS;EAC7B,MAAM,SAAS,CAAC;EAChB,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,KAC3B,OAAO,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;EAEhC,OAAO;CACR;AACD"}
1
+ {"version":3,"file":"reader.mjs","names":[],"sources":["../src/reader.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Class used for reading BCS data chunk by chunk. Meant to be used\n * by some wrapper, which will make sure that data is valid and is\n * matching the desired format.\n *\n * @example\n * // data for this example is:\n * // { a: u8, b: u32, c: bool, d: u64 }\n *\n * let reader = new BcsReader(\"647f1a060001ffffe7890423c78a050102030405\");\n * let field1 = reader.read8();\n * let field2 = reader.read32();\n * let field3 = reader.read8() === '1'; // bool\n * let field4 = reader.read64();\n * // ....\n *\n * Reading vectors is another deal in bcs. To read a vector, you first need to read\n * its length using {@link readULEB}. Here's an example:\n * @example\n * // data encoded: { field: [1, 2, 3, 4, 5] }\n * let reader = new BcsReader(\"050102030405\");\n * let vec_length = reader.readULEB();\n * let elements = [];\n * for (let i = 0; i < vec_length; i++) {\n * elements.push(reader.read8());\n * }\n * console.log(elements); // [1,2,3,4,5]\n *\n * @param {String} data HEX-encoded data (serialized BCS)\n */\nexport class BcsReader {\n\tprivate dataView: DataView;\n\tprivate bytes: Uint8Array;\n\tprivate bytePosition: number = 0;\n\n\t/**\n\t * @param {Uint8Array} data Data to use as a buffer.\n\t */\n\tconstructor(data: Uint8Array) {\n\t\tthis.dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\t\tthis.bytes = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n\t}\n\t/**\n\t * Shift current cursor position by `bytes`.\n\t *\n\t * @param {Number} bytes Number of bytes to\n\t * @returns {this} Self for possible chaining.\n\t */\n\tshift(bytes: number) {\n\t\tthis.bytePosition += bytes;\n\t\treturn this;\n\t}\n\t/**\n\t * Read U8 value from the buffer and shift cursor by 1.\n\t * @returns\n\t */\n\tread8(): number {\n\t\tconst position = this.bytePosition;\n\t\tif (position >= this.bytes.length) {\n\t\t\tthrow new RangeError('Offset is outside the bounds of the DataView');\n\t\t}\n\t\tthis.bytePosition = position + 1;\n\t\treturn this.bytes[position];\n\t}\n\t/**\n\t * Read U16 value from the buffer and shift cursor by 2.\n\t * @returns\n\t */\n\tread16(): number {\n\t\tconst value = this.dataView.getUint16(this.bytePosition, true);\n\t\tthis.shift(2);\n\t\treturn value;\n\t}\n\t/**\n\t * Read U32 value from the buffer and shift cursor by 4.\n\t * @returns\n\t */\n\tread32(): number {\n\t\tconst value = this.dataView.getUint32(this.bytePosition, true);\n\t\tthis.shift(4);\n\t\treturn value;\n\t}\n\t/**\n\t * Read U64 value from the buffer and shift cursor by 8.\n\t * @returns\n\t */\n\tread64(): string {\n\t\tconst value = this.dataView.getBigUint64(this.bytePosition, true);\n\t\tthis.shift(8);\n\t\treturn value.toString(10);\n\t}\n\t/**\n\t * Read U128 value from the buffer and shift cursor by 16.\n\t */\n\tread128(): string {\n\t\tconst value1 = BigInt(this.read64());\n\t\tconst value2 = BigInt(this.read64());\n\t\tconst result = value2.toString(16) + value1.toString(16).padStart(16, '0');\n\n\t\treturn BigInt('0x' + result).toString(10);\n\t}\n\t/**\n\t * Read U128 value from the buffer and shift cursor by 32.\n\t * @returns\n\t */\n\tread256(): string {\n\t\tconst value1 = BigInt(this.read128());\n\t\tconst value2 = BigInt(this.read128());\n\t\tconst result = value2.toString(16) + value1.toString(16).padStart(32, '0');\n\n\t\treturn BigInt('0x' + result).toString(10);\n\t}\n\t/**\n\t * Read `num` number of bytes from the buffer and shift cursor by `num`.\n\t * @param num Number of bytes to read.\n\t */\n\treadBytes(num: number): Uint8Array {\n\t\t// The underlying buffer may extend past this view, so check against the view's own length\n\t\tif (this.bytePosition + num > this.bytes.length) {\n\t\t\tthrow new RangeError('Offset is outside the bounds of the DataView');\n\t\t}\n\t\tconst start = this.bytePosition + this.dataView.byteOffset;\n\t\tconst value = new Uint8Array(this.dataView.buffer, start, num);\n\n\t\tthis.shift(num);\n\n\t\treturn value;\n\t}\n\t/**\n\t * Read ULEB value - an integer of varying size. Used for enum indexes and\n\t * vector lengths.\n\t * @returns {Number} The ULEB value.\n\t */\n\treadULEB(): number {\n\t\tconst bytes = this.bytes;\n\t\tlet position = this.bytePosition;\n\t\tlet value = 0;\n\t\tlet multiplier = 1;\n\t\twhile (true) {\n\t\t\tif (position >= bytes.length) {\n\t\t\t\tthrow new Error('ULEB decode error: buffer overflow');\n\t\t\t}\n\t\t\tconst byte = bytes[position++];\n\t\t\tvalue += (byte & 0x7f) * multiplier;\n\t\t\tif ((byte & 0x80) === 0) {\n\t\t\t\t// A trailing zero group adds no value, so the encoding is not minimal\n\t\t\t\tif (byte === 0 && position - this.bytePosition > 1) {\n\t\t\t\t\tthrow new Error('ULEB decode error: non-canonical encoding');\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmultiplier *= 128;\n\t\t}\n\n\t\t// Also rejects NaN, from very long encodings where multiplier overflows to Infinity\n\t\tif (!(value <= Number.MAX_SAFE_INTEGER)) {\n\t\t\tthrow new Error('ULEB decode error: value exceeds MAX_SAFE_INTEGER');\n\t\t}\n\t\tthis.bytePosition = position;\n\t\treturn value;\n\t}\n\t/**\n\t * Read a BCS vector: read a length and then apply function `cb` X times\n\t * where X is the length of the vector, defined as ULEB in BCS bytes.\n\t * @param cb Callback to process elements of vector.\n\t * @returns {Array<Any>} Array of the resulting values, returned by callback.\n\t */\n\treadVec(cb: (reader: BcsReader, i: number, length: number) => any): any[] {\n\t\tconst length = this.readULEB();\n\t\tconst result = [];\n\t\tfor (let i = 0; i < length; i++) {\n\t\t\tresult.push(cb(this, i, length));\n\t\t}\n\t\treturn result;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,IAAa,YAAb,MAAuB;;;;CAQtB,YAAY,MAAkB;EALC,KAAA,eAAA;EAM9B,KAAK,WAAW,IAAI,SAAS,KAAK,QAAQ,KAAK,YAAY,KAAK,UAAU;EAC1E,KAAK,QAAQ,IAAI,WAAW,KAAK,QAAQ,KAAK,YAAY,KAAK,UAAU;CAC1E;;;;;;;CAOA,MAAM,OAAe;EACpB,KAAK,gBAAgB;EACrB,OAAO;CACR;;;;;CAKA,QAAgB;EACf,MAAM,WAAW,KAAK;EACtB,IAAI,YAAY,KAAK,MAAM,QAC1B,MAAM,IAAI,WAAW,8CAA8C;EAEpE,KAAK,eAAe,WAAW;EAC/B,OAAO,KAAK,MAAM;CACnB;;;;;CAKA,SAAiB;EAChB,MAAM,QAAQ,KAAK,SAAS,UAAU,KAAK,cAAc,IAAI;EAC7D,KAAK,MAAM,CAAC;EACZ,OAAO;CACR;;;;;CAKA,SAAiB;EAChB,MAAM,QAAQ,KAAK,SAAS,UAAU,KAAK,cAAc,IAAI;EAC7D,KAAK,MAAM,CAAC;EACZ,OAAO;CACR;;;;;CAKA,SAAiB;EAChB,MAAM,QAAQ,KAAK,SAAS,aAAa,KAAK,cAAc,IAAI;EAChE,KAAK,MAAM,CAAC;EACZ,OAAO,MAAM,SAAS,EAAE;CACzB;;;;CAIA,UAAkB;EACjB,MAAM,SAAS,OAAO,KAAK,OAAO,CAAC;EAEnC,MAAM,SADS,OAAO,KAAK,OAAO,CACd,CAAC,CAAC,SAAS,EAAE,IAAI,OAAO,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,GAAG;EAEzE,OAAO,OAAO,OAAO,MAAM,CAAC,CAAC,SAAS,EAAE;CACzC;;;;;CAKA,UAAkB;EACjB,MAAM,SAAS,OAAO,KAAK,QAAQ,CAAC;EAEpC,MAAM,SADS,OAAO,KAAK,QAAQ,CACf,CAAC,CAAC,SAAS,EAAE,IAAI,OAAO,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,GAAG;EAEzE,OAAO,OAAO,OAAO,MAAM,CAAC,CAAC,SAAS,EAAE;CACzC;;;;;CAKA,UAAU,KAAyB;EAElC,IAAI,KAAK,eAAe,MAAM,KAAK,MAAM,QACxC,MAAM,IAAI,WAAW,8CAA8C;EAEpE,MAAM,QAAQ,KAAK,eAAe,KAAK,SAAS;EAChD,MAAM,QAAQ,IAAI,WAAW,KAAK,SAAS,QAAQ,OAAO,GAAG;EAE7D,KAAK,MAAM,GAAG;EAEd,OAAO;CACR;;;;;;CAMA,WAAmB;EAClB,MAAM,QAAQ,KAAK;EACnB,IAAI,WAAW,KAAK;EACpB,IAAI,QAAQ;EACZ,IAAI,aAAa;EACjB,OAAO,MAAM;GACZ,IAAI,YAAY,MAAM,QACrB,MAAM,IAAI,MAAM,oCAAoC;GAErD,MAAM,OAAO,MAAM;GACnB,UAAU,OAAO,OAAQ;GACzB,KAAK,OAAO,SAAU,GAAG;IAExB,IAAI,SAAS,KAAK,WAAW,KAAK,eAAe,GAChD,MAAM,IAAI,MAAM,2CAA2C;IAE5D;GACD;GACA,cAAc;EACf;EAGA,IAAI,EAAE,SAAS,OAAO,mBACrB,MAAM,IAAI,MAAM,mDAAmD;EAEpE,KAAK,eAAe;EACpB,OAAO;CACR;;;;;;;CAOA,QAAQ,IAAkE;EACzE,MAAM,SAAS,KAAK,SAAS;EAC7B,MAAM,SAAS,CAAC;EAChB,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,KAC3B,OAAO,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;EAEhC,OAAO;CACR;AACD"}
package/dist/types.d.mts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { BcsType } from "./bcs-type.mjs";
2
2
  import { Simplify } from "@haneullabs/utils";
3
-
4
3
  //#region src/types.d.ts
5
4
  /**
6
5
  * Supported encodings.
@@ -9,11 +8,11 @@ import { Simplify } from "@haneullabs/utils";
9
8
  type Encoding = 'base58' | 'base64' | 'hex';
10
9
  type InferBcsType<T extends BcsType<any>> = T extends BcsType<infer U, any> ? U : never;
11
10
  type InferBcsInput<T extends BcsType<any, any>> = T extends BcsType<any, infer U> ? U : never;
12
- type EnumOutputShape<T extends Record<string, unknown>, Keys extends string = Extract<keyof T, string>, Values = (T[keyof T] extends infer Type ? (Type extends BcsType<infer U> ? U : never) : never)> = 0 extends Values ? EnumOutputShapeWithKeys<T, never> : 0n extends Values ? EnumOutputShapeWithKeys<T, never> : '' extends Values ? EnumOutputShapeWithKeys<T, never> : false extends Values ? EnumOutputShapeWithKeys<T, never> : EnumOutputShapeWithKeys<T, Keys>;
13
- type EnumOutputShapeWithKeys<T extends Record<string, unknown>, Keys extends string> = { [K in keyof T]: Exclude<Keys, K> extends infer Empty extends string ? Simplify<{ [K2 in K]: T[K] } & { [K in Empty]?: never } & {
11
+ type EnumOutputShape<T extends Record<string, unknown>, Keys extends string = Extract<keyof T, string>, Values = T[keyof T] extends (infer Type) ? (Type extends BcsType<infer U> ? U : never) : never> = 0 extends Values ? EnumOutputShapeWithKeys<T, never> : 0n extends Values ? EnumOutputShapeWithKeys<T, never> : '' extends Values ? EnumOutputShapeWithKeys<T, never> : false extends Values ? EnumOutputShapeWithKeys<T, never> : EnumOutputShapeWithKeys<T, Keys>;
12
+ type EnumOutputShapeWithKeys<T extends Record<string, unknown>, Keys extends string> = { [K in keyof T]: Exclude<Keys, K> extends (infer Empty extends string) ? Simplify<{ [K2 in K]: T[K]; } & { [K in Empty]?: never; } & {
14
13
  $kind: K;
15
- }> : never }[keyof T];
16
- type EnumInputShape<T extends Record<string, unknown>> = { [K in keyof T]: { [K2 in K]: T[K] } }[keyof T];
14
+ }> : never; }[keyof T];
15
+ type EnumInputShape<T extends Record<string, unknown>> = { [K in keyof T]: { [K2 in K]: T[K]; }; }[keyof T];
17
16
  type JoinString<T, Sep extends string> = T extends readonly [infer F extends string, ...infer R extends string[]] ? [] extends R ? F : `${F}${Sep}${JoinString<R, Sep>}` : '';
18
17
  //#endregion
19
18
  export { Encoding, EnumInputShape, EnumOutputShape, EnumOutputShapeWithKeys, InferBcsInput, InferBcsType, JoinString };
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"mappings":";;;;;;AAUA;;KAAY,QAAA;AAAA,KAEA,YAAA,WAAuB,OAAA,SAAgB,CAAA,SAAU,OAAA,iBAAwB,CAAA;AAAA,KACzE,aAAA,WAAwB,OAAA,cACnC,CAAA,SAAU,OAAA,iBAAwB,CAAA;AAAA,KAEvB,eAAA,WACD,MAAA,yCACY,OAAA,OAAc,CAAA,qBAC3B,CAAA,OAAQ,CAAA,wBAAyB,IAAA,SAAa,OAAA,YAAmB,CAAA,gCAC7D,MAAA,GACX,uBAAA,CAAwB,CAAA,sBACb,MAAA,GACV,uBAAA,CAAwB,CAAA,sBACb,MAAA,GACV,uBAAA,CAAwB,CAAA,yBACV,MAAA,GACb,uBAAA,CAAwB,CAAA,WACxB,uBAAA,CAAwB,CAAA,EAAG,IAAA;AAAA,KAErB,uBAAA,WAAkC,MAAA,wDACjC,CAAA,GAAI,OAAA,CAAQ,IAAA,EAAM,CAAA,uCAC3B,QAAA,UACS,CAAA,GAAI,CAAA,CAAE,CAAA,cAAe,KAAA;EAC7B,KAAA,EAAO,CAAA;AAAA,mBAIJ,CAAA;AAAA,KAEI,cAAA,WAAyB,MAAA,mCACxB,CAAA,YAAa,CAAA,GAAI,CAAA,CAAE,CAAA,YACxB,CAAA;AAAA,KAEI,UAAA,0BAAoC,CAAA,qFAIlC,CAAA,GACV,CAAA,MACG,CAAA,GAAI,GAAA,GAAM,UAAA,CAAW,CAAA,EAAG,GAAA"}
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"mappings":";;;;;;;KAUY;KAEA,aAAa,UAAU,gBAAgB,UAAU,cAAc,UAAU;KACzE,cAAc,UAAU,qBACnC,UAAU,mBAAmB,KAAK;KAEvB,gBACX,UAAU,yBACV,sBAAsB,cAAc,YACpC,SAAS,QAAQ,kBAAiB,SAAQ,aAAa,cAAc,KAAK,gCAC7D,SACX,wBAAwB,uBACb,SACV,wBAAwB,uBACb,SACV,wBAAwB,0BACV,SACb,wBAAwB,YACxB,wBAAwB,GAAG;KAErB,wBAAwB,UAAU,yBAAyB,0BACrE,WAAW,IAAI,QAAQ,MAAM,kBAAiB,wBAC5C,YACG,MAAM,IAAI,EAAE,WAAU,KAAK;EAC7B,OAAO;oBAIJ;KAEI,eAAe,UAAU,8BACnC,WAAW,OAAO,MAAM,IAAI,EAAE,eACxB;KAEI,WAAW,GAAG,sBAAsB,0BACzC,2BACG,iCAEI,IACV,OACG,IAAI,MAAM,WAAW,GAAG"}
@@ -1 +1 @@
1
- {"version":3,"file":"uleb.d.mts","names":[],"sources":["../src/uleb.ts"],"mappings":";iBAKgB,UAAA,CAAW,GAAoB;AAAA,iBAuB/B,UAAA,CAAW,GAAA,aAAgB,UAAU;EACpD,KAAA;EACA,MAAA;AAAA"}
1
+ {"version":3,"file":"uleb.d.mts","names":[],"sources":["../src/uleb.ts"],"mappings":";iBAKgB,WAAW;iBAuBX,WAAW,gBAAgB;EAC1C;EACA"}
package/dist/uleb.mjs CHANGED
@@ -21,7 +21,10 @@ function ulebDecode(arr) {
21
21
  const byte = arr[len];
22
22
  len += 1;
23
23
  total += BigInt(byte & 127) << shift;
24
- if ((byte & 128) === 0) break;
24
+ if ((byte & 128) === 0) {
25
+ if (byte === 0 && len > 1) throw new Error("ULEB decode error: non-canonical encoding");
26
+ break;
27
+ }
25
28
  shift += 7n;
26
29
  }
27
30
  if (total > BigInt(Number.MAX_SAFE_INTEGER)) throw new Error("ULEB decode error: value exceeds MAX_SAFE_INTEGER");
package/dist/uleb.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"uleb.mjs","names":[],"sources":["../src/uleb.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\n// Helper utility: write number as an ULEB array.\n// Original code is taken from: https://www.npmjs.com/package/uleb128 (no longer exists)\nexport function ulebEncode(num: number | bigint): number[] {\n\tlet bigNum = BigInt(num);\n\tconst arr: number[] = [];\n\tlet len = 0;\n\n\tif (bigNum === 0n) {\n\t\treturn [0];\n\t}\n\n\twhile (bigNum > 0) {\n\t\tarr[len] = Number(bigNum & 0x7fn);\n\t\tbigNum >>= 7n;\n\t\tif (bigNum > 0n) {\n\t\t\tarr[len] |= 0x80;\n\t\t}\n\t\tlen += 1;\n\t}\n\n\treturn arr;\n}\n\n// Helper utility: decode ULEB as an array of numbers.\n// Original code is taken from: https://www.npmjs.com/package/uleb128 (no longer exists)\nexport function ulebDecode(arr: number[] | Uint8Array): {\n\tvalue: number;\n\tlength: number;\n} {\n\tlet total = 0n;\n\tlet shift = 0n;\n\tlet len = 0;\n\n\twhile (true) {\n\t\tif (len >= arr.length) {\n\t\t\tthrow new Error('ULEB decode error: buffer overflow');\n\t\t}\n\n\t\tconst byte = arr[len];\n\t\tlen += 1;\n\t\ttotal += BigInt(byte & 0x7f) << shift;\n\t\tif ((byte & 0x80) === 0) {\n\t\t\tbreak;\n\t\t}\n\t\tshift += 7n;\n\t}\n\n\t// TODO: return bigint in next major version\n\tif (total > BigInt(Number.MAX_SAFE_INTEGER)) {\n\t\tthrow new Error('ULEB decode error: value exceeds MAX_SAFE_INTEGER');\n\t}\n\n\treturn {\n\t\tvalue: Number(total),\n\t\tlength: len,\n\t};\n}\n"],"mappings":";AAKA,SAAgB,WAAW,KAAgC;CAC1D,IAAI,SAAS,OAAO,GAAG;CACvB,MAAM,MAAgB,CAAC;CACvB,IAAI,MAAM;CAEV,IAAI,WAAW,IACd,OAAO,CAAC,CAAC;CAGV,OAAO,SAAS,GAAG;EAClB,IAAI,OAAO,OAAO,SAAS,IAAK;EAChC,WAAW;EACX,IAAI,SAAS,IACZ,IAAI,QAAQ;EAEb,OAAO;CACR;CAEA,OAAO;AACR;AAIA,SAAgB,WAAW,KAGzB;CACD,IAAI,QAAQ;CACZ,IAAI,QAAQ;CACZ,IAAI,MAAM;CAEV,OAAO,MAAM;EACZ,IAAI,OAAO,IAAI,QACd,MAAM,IAAI,MAAM,oCAAoC;EAGrD,MAAM,OAAO,IAAI;EACjB,OAAO;EACP,SAAS,OAAO,OAAO,GAAI,KAAK;EAChC,KAAK,OAAO,SAAU,GACrB;EAED,SAAS;CACV;CAGA,IAAI,QAAQ,OAAO,OAAO,gBAAgB,GACzC,MAAM,IAAI,MAAM,mDAAmD;CAGpE,OAAO;EACN,OAAO,OAAO,KAAK;EACnB,QAAQ;CACT;AACD"}
1
+ {"version":3,"file":"uleb.mjs","names":[],"sources":["../src/uleb.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\n// Helper utility: write number as an ULEB array.\n// Original code is taken from: https://www.npmjs.com/package/uleb128 (no longer exists)\nexport function ulebEncode(num: number | bigint): number[] {\n\tlet bigNum = BigInt(num);\n\tconst arr: number[] = [];\n\tlet len = 0;\n\n\tif (bigNum === 0n) {\n\t\treturn [0];\n\t}\n\n\twhile (bigNum > 0) {\n\t\tarr[len] = Number(bigNum & 0x7fn);\n\t\tbigNum >>= 7n;\n\t\tif (bigNum > 0n) {\n\t\t\tarr[len] |= 0x80;\n\t\t}\n\t\tlen += 1;\n\t}\n\n\treturn arr;\n}\n\n// Helper utility: decode ULEB as an array of numbers.\n// Original code is taken from: https://www.npmjs.com/package/uleb128 (no longer exists)\nexport function ulebDecode(arr: number[] | Uint8Array): {\n\tvalue: number;\n\tlength: number;\n} {\n\tlet total = 0n;\n\tlet shift = 0n;\n\tlet len = 0;\n\n\twhile (true) {\n\t\tif (len >= arr.length) {\n\t\t\tthrow new Error('ULEB decode error: buffer overflow');\n\t\t}\n\n\t\tconst byte = arr[len];\n\t\tlen += 1;\n\t\ttotal += BigInt(byte & 0x7f) << shift;\n\t\tif ((byte & 0x80) === 0) {\n\t\t\t// A trailing zero group adds no value, so the encoding is not minimal\n\t\t\tif (byte === 0 && len > 1) {\n\t\t\t\tthrow new Error('ULEB decode error: non-canonical encoding');\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tshift += 7n;\n\t}\n\n\t// TODO: return bigint in next major version\n\tif (total > BigInt(Number.MAX_SAFE_INTEGER)) {\n\t\tthrow new Error('ULEB decode error: value exceeds MAX_SAFE_INTEGER');\n\t}\n\n\treturn {\n\t\tvalue: Number(total),\n\t\tlength: len,\n\t};\n}\n"],"mappings":";AAKA,SAAgB,WAAW,KAAgC;CAC1D,IAAI,SAAS,OAAO,GAAG;CACvB,MAAM,MAAgB,CAAC;CACvB,IAAI,MAAM;CAEV,IAAI,WAAW,IACd,OAAO,CAAC,CAAC;CAGV,OAAO,SAAS,GAAG;EAClB,IAAI,OAAO,OAAO,SAAS,IAAK;EAChC,WAAW;EACX,IAAI,SAAS,IACZ,IAAI,QAAQ;EAEb,OAAO;CACR;CAEA,OAAO;AACR;AAIA,SAAgB,WAAW,KAGzB;CACD,IAAI,QAAQ;CACZ,IAAI,QAAQ;CACZ,IAAI,MAAM;CAEV,OAAO,MAAM;EACZ,IAAI,OAAO,IAAI,QACd,MAAM,IAAI,MAAM,oCAAoC;EAGrD,MAAM,OAAO,IAAI;EACjB,OAAO;EACP,SAAS,OAAO,OAAO,GAAI,KAAK;EAChC,KAAK,OAAO,SAAU,GAAG;GAExB,IAAI,SAAS,KAAK,MAAM,GACvB,MAAM,IAAI,MAAM,2CAA2C;GAE5D;EACD;EACA,SAAS;CACV;CAGA,IAAI,QAAQ,OAAO,OAAO,gBAAgB,GACzC,MAAM,IAAI,MAAM,mDAAmD;CAGpE,OAAO;EACN,OAAO,OAAO,KAAK;EACnB,QAAQ;CACT;AACD"}
package/dist/utils.d.mts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { Encoding } from "./types.mjs";
2
-
3
2
  //#region src/utils.d.ts
4
3
  /**
5
4
  * Encode data with either `hex` or `base64`.
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.mts","names":[],"sources":["../src/utils.ts"],"mappings":";;;;;AAaA;;;;;iBAAgB,SAAA,CAAU,IAAA,EAAM,UAAA,EAAY,QAAA,EAAU,QAAQ;;;;AAAA;AAoB9D;;;iBAAgB,SAAA,CAAU,IAAA,UAAc,QAAA,EAAU,QAAA,GAAW,UAAU;AAAA,iBAavD,sBAAA,CACf,GAAA,UACA,iBAAgD"}
1
+ {"version":3,"file":"utils.d.mts","names":[],"sources":["../src/utils.ts"],"mappings":";;;;;;;;;iBAagB,UAAU,MAAM,YAAY,UAAU;;;;;;;;iBAoBtC,UAAU,cAAc,UAAU,WAAW;iBAa7C,uBACf,aACA"}
package/dist/writer.d.mts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { Encoding } from "./types.mjs";
2
-
3
2
  //#region src/writer.d.ts
4
3
  interface BcsWriterOptions {
5
4
  /** The initial size (in bytes) of the buffer tht will be allocated */
@@ -28,15 +27,12 @@ interface BcsWriterOptions {
28
27
  */
29
28
  declare class BcsWriter {
30
29
  private dataView;
30
+ private bytes;
31
31
  private bytePosition;
32
32
  private size;
33
33
  private maxSize;
34
34
  private allocateSize;
35
- constructor({
36
- initialSize,
37
- maxSize,
38
- allocateSize
39
- }?: BcsWriterOptions);
35
+ constructor({ initialSize, maxSize, allocateSize }?: BcsWriterOptions);
40
36
  private ensureSizeOrGrow;
41
37
  /**
42
38
  * Shift current cursor position by `bytes`.
@@ -89,6 +85,7 @@ declare class BcsWriter {
89
85
  * @returns {this}
90
86
  */
91
87
  write256(value: number | bigint): this;
88
+ private writeBigLittleEndian;
92
89
  /**
93
90
  * Write a ULEB value into a buffer and shift cursor position by number of bytes
94
91
  * written.
@@ -1 +1 @@
1
- {"version":3,"file":"writer.d.mts","names":[],"sources":["../src/writer.ts"],"mappings":";;;UAOiB,gBAAA;;EAEhB,WAAA;EAFgC;EAIhC,OAAA;EAJgC;EAMhC,YAAA;AAAA;;;AAAY;AAqBb;;;;;;;;;;;;;;cAAa,SAAA;EAAA,QACJ,QAAA;EAAA,QACA,YAAA;EAAA,QACA,IAAA;EAAA,QACA,OAAA;EAAA,QACA,YAAA;;IAGP,WAAA;IACA,OAAA;IACA;EAAA,IACE,gBAAA;EAAA,QAOK,gBAAA;;;;;;;EA0BR,KAAA,CAAM,KAAA;EAjCH;;;;;EA0CH,MAAA,CAAO,KAAA;EAWP;;;;;EAAA,UAAA,CAAW,KAAA,EAAO,UAAA;EAwBV;;;;;EAVR,OAAA,CAAQ,KAAA;EA0CC;;;;;EAhCT,OAAA,CAAQ,KAAA;EAuDqB;;;;;EA7C7B,OAAA,CAAQ,KAAA;EAwDC;;;;;;EA7CT,QAAA,CAAS,KAAA;EAgEU;;;AAAQ;;;EArD3B,QAAA,CAAS,KAAA;;;;;;;EAWT,SAAA,CAAU,KAAA;;;;;;;;;EAYV,QAAA,CAAS,MAAA,SAAe,EAAA,GAAK,MAAA,EAAQ,SAAA,EAAW,EAAA,OAAS,CAAA,UAAW,GAAA;;;;;GAWlE,MAAA,CAAO,QAAA,KAAa,QAAA,SAAiB,QAAA;;;;;EAWvC,OAAA,IAAW,UAAA,CAAW,WAAA;;;;;EAQtB,QAAA,CAAS,QAAA,EAAU,QAAA;AAAA"}
1
+ {"version":3,"file":"writer.d.mts","names":[],"sources":["../src/writer.ts"],"mappings":";;UAOiB;;EAEhB;;EAEA;;EAEA;;;;;;;;;;;;;;;;;;;cAqBY;UACJ;UACA;UACA;UACA;UACA;UACA;EAER,cACC,aACA,SACA,iBACE;UAQK;;;;;;;EA4BR,MAAM;;;;;;EASN,OAAO;;;;;;EAWP,WAAW,OAAO;;;;;;EAWlB,QAAQ;;;;;;EAUR,QAAQ;;;;;;EAUR,QAAQ;;;;;;;EASR,SAAS;;;;;;;EAST,SAAS;UAKD;;;;;;;EAgBR,UAAU;;;;;;;;;EAqBV,SAAS,eAAe,KAAK,QAAQ,WAAW,SAAS,WAAW;;;;;GAWlE,OAAO,aAAa,iBAAiB;;;;;EAWvC,WAAW,WAAW;;;;;EAQtB,SAAS,UAAU"}
package/dist/writer.mjs CHANGED
@@ -25,6 +25,7 @@ var BcsWriter = class {
25
25
  this.maxSize = maxSize;
26
26
  this.allocateSize = allocateSize;
27
27
  this.dataView = new DataView(new ArrayBuffer(initialSize));
28
+ this.bytes = new Uint8Array(this.dataView.buffer);
28
29
  }
29
30
  ensureSizeOrGrow(bytes) {
30
31
  const requiredSize = this.bytePosition + bytes;
@@ -33,8 +34,10 @@ var BcsWriter = class {
33
34
  if (requiredSize > nextSize) throw new Error(`Attempting to serialize to BCS, but buffer does not have enough size. Allocated size: ${this.size}, Max size: ${this.maxSize}, Required size: ${requiredSize}`);
34
35
  this.size = nextSize;
35
36
  const nextBuffer = new ArrayBuffer(this.size);
36
- new Uint8Array(nextBuffer).set(new Uint8Array(this.dataView.buffer));
37
+ const nextBytes = new Uint8Array(nextBuffer);
38
+ nextBytes.set(this.bytes);
37
39
  this.dataView = new DataView(nextBuffer);
40
+ this.bytes = nextBytes;
38
41
  }
39
42
  }
40
43
  /**
@@ -54,7 +57,7 @@ var BcsWriter = class {
54
57
  */
55
58
  write8(value) {
56
59
  this.ensureSizeOrGrow(1);
57
- this.dataView.setUint8(this.bytePosition, Number(value));
60
+ this.bytes[this.bytePosition] = Number(value);
58
61
  return this.shift(1);
59
62
  }
60
63
  /**
@@ -64,7 +67,7 @@ var BcsWriter = class {
64
67
  */
65
68
  writeBytes(bytes) {
66
69
  this.ensureSizeOrGrow(bytes.length);
67
- for (let i = 0; i < bytes.length; i++) this.dataView.setUint8(this.bytePosition + i, bytes[i]);
70
+ this.bytes.set(bytes, this.bytePosition);
68
71
  return this.shift(bytes.length);
69
72
  }
70
73
  /**
@@ -93,8 +96,7 @@ var BcsWriter = class {
93
96
  * @returns {this}
94
97
  */
95
98
  write64(value) {
96
- toLittleEndian(BigInt(value), 8).forEach((el) => this.write8(el));
97
- return this;
99
+ return this.writeBigLittleEndian(BigInt(value), 8);
98
100
  }
99
101
  /**
100
102
  * Write a U128 value into a buffer and shift cursor position by 16.
@@ -103,8 +105,7 @@ var BcsWriter = class {
103
105
  * @returns {this}
104
106
  */
105
107
  write128(value) {
106
- toLittleEndian(BigInt(value), 16).forEach((el) => this.write8(el));
107
- return this;
108
+ return this.writeBigLittleEndian(BigInt(value), 16);
108
109
  }
109
110
  /**
110
111
  * Write a U256 value into a buffer and shift cursor position by 16.
@@ -113,8 +114,16 @@ var BcsWriter = class {
113
114
  * @returns {this}
114
115
  */
115
116
  write256(value) {
116
- toLittleEndian(BigInt(value), 32).forEach((el) => this.write8(el));
117
- return this;
117
+ return this.writeBigLittleEndian(BigInt(value), 32);
118
+ }
119
+ writeBigLittleEndian(value, size) {
120
+ this.ensureSizeOrGrow(size);
121
+ let remaining = value > 0n ? value : 0n;
122
+ for (let offset = 0; offset < size; offset += 8) {
123
+ this.dataView.setBigUint64(this.bytePosition + offset, BigInt.asUintN(64, remaining), true);
124
+ remaining >>= 64n;
125
+ }
126
+ return this.shift(size);
118
127
  }
119
128
  /**
120
129
  * Write a ULEB value into a buffer and shift cursor position by number of bytes
@@ -123,6 +132,14 @@ var BcsWriter = class {
123
132
  * @returns {this}
124
133
  */
125
134
  writeULEB(value) {
135
+ if (value >= 0 && Number.isSafeInteger(value)) {
136
+ let remaining = value;
137
+ while (remaining >= 128) {
138
+ this.write8(remaining % 128 | 128);
139
+ remaining = Math.floor(remaining / 128);
140
+ }
141
+ return this.write8(remaining);
142
+ }
126
143
  ulebEncode(value).forEach((el) => this.write8(el));
127
144
  return this;
128
145
  }
@@ -162,16 +179,6 @@ var BcsWriter = class {
162
179
  return encodeStr(this.toBytes(), encoding);
163
180
  }
164
181
  };
165
- function toLittleEndian(bigint, size) {
166
- const result = new Uint8Array(size);
167
- let i = 0;
168
- while (bigint > 0) {
169
- result[i] = Number(bigint % BigInt(256));
170
- bigint = bigint / BigInt(256);
171
- i += 1;
172
- }
173
- return result;
174
- }
175
182
  //#endregion
176
183
  export { BcsWriter };
177
184