UNPKG

@mysten/bcs

Version:

BCS - Canonical Binary Serialization implementation for JavaScript

407 lines (406 loc) • 12.4 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var bcs_exports = {}; __export(bcs_exports, { bcs: () => bcs }); module.exports = __toCommonJS(bcs_exports); var import_bcs_type = require("./bcs-type.js"); var import_uleb = require("./uleb.js"); function fixedArray(size, type, options) { return new import_bcs_type.BcsType({ read: (reader) => { const result = new Array(size); for (let i = 0; i < size; i++) { result[i] = type.read(reader); } return result; }, write: (value, writer) => { for (const item of value) { type.write(item, writer); } }, ...options, name: options?.name ?? `${type.name}[${size}]`, validate: (value) => { options?.validate?.(value); if (!value || typeof value !== "object" || !("length" in value)) { throw new TypeError(`Expected array, found ${typeof value}`); } if (value.length !== size) { throw new TypeError(`Expected array of length ${size}, found ${value.length}`); } } }); } function option(type) { return bcs.enum(`Option<${type.name}>`, { None: null, Some: type }).transform({ input: (value) => { if (value == null) { return { None: true }; } return { Some: value }; }, output: (value) => { if (value.$kind === "Some") { return value.Some; } return null; } }); } function vector(type, options) { return new import_bcs_type.BcsType({ read: (reader) => { const length = reader.readULEB(); const result = new Array(length); for (let i = 0; i < length; i++) { result[i] = type.read(reader); } return result; }, write: (value, writer) => { writer.writeULEB(value.length); for (const item of value) { type.write(item, writer); } }, ...options, name: options?.name ?? `vector<${type.name}>`, validate: (value) => { options?.validate?.(value); if (!value || typeof value !== "object" || !("length" in value)) { throw new TypeError(`Expected array, found ${typeof value}`); } } }); } function map(keyType, valueType) { return bcs.vector(bcs.tuple([keyType, valueType])).transform({ name: `Map<${keyType.name}, ${valueType.name}>`, input: (value) => { return [...value.entries()]; }, output: (value) => { const result = /* @__PURE__ */ new Map(); for (const [key, val] of value) { result.set(key, val); } return result; } }); } const bcs = { /** * Creates a BcsType that can be used to read and write an 8-bit unsigned integer. * @example * bcs.u8().serialize(255).toBytes() // Uint8Array [ 255 ] */ u8(options) { return (0, import_bcs_type.uIntBcsType)({ readMethod: "read8", writeMethod: "write8", size: 1, maxValue: 2 ** 8 - 1, ...options, name: options?.name ?? "u8" }); }, /** * Creates a BcsType that can be used to read and write a 16-bit unsigned integer. * @example * bcs.u16().serialize(65535).toBytes() // Uint8Array [ 255, 255 ] */ u16(options) { return (0, import_bcs_type.uIntBcsType)({ readMethod: "read16", writeMethod: "write16", size: 2, maxValue: 2 ** 16 - 1, ...options, name: options?.name ?? "u16" }); }, /** * Creates a BcsType that can be used to read and write a 32-bit unsigned integer. * @example * bcs.u32().serialize(4294967295).toBytes() // Uint8Array [ 255, 255, 255, 255 ] */ u32(options) { return (0, import_bcs_type.uIntBcsType)({ readMethod: "read32", writeMethod: "write32", size: 4, maxValue: 2 ** 32 - 1, ...options, name: options?.name ?? "u32" }); }, /** * Creates a BcsType that can be used to read and write a 64-bit unsigned integer. * @example * bcs.u64().serialize(1).toBytes() // Uint8Array [ 1, 0, 0, 0, 0, 0, 0, 0 ] */ u64(options) { return (0, import_bcs_type.bigUIntBcsType)({ readMethod: "read64", writeMethod: "write64", size: 8, maxValue: 2n ** 64n - 1n, ...options, name: options?.name ?? "u64" }); }, /** * Creates a BcsType that can be used to read and write a 128-bit unsigned integer. * @example * bcs.u128().serialize(1).toBytes() // Uint8Array [ 1, ..., 0 ] */ u128(options) { return (0, import_bcs_type.bigUIntBcsType)({ readMethod: "read128", writeMethod: "write128", size: 16, maxValue: 2n ** 128n - 1n, ...options, name: options?.name ?? "u128" }); }, /** * Creates a BcsType that can be used to read and write a 256-bit unsigned integer. * @example * bcs.u256().serialize(1).toBytes() // Uint8Array [ 1, ..., 0 ] */ u256(options) { return (0, import_bcs_type.bigUIntBcsType)({ readMethod: "read256", writeMethod: "write256", size: 32, maxValue: 2n ** 256n - 1n, ...options, name: options?.name ?? "u256" }); }, /** * Creates a BcsType that can be used to read and write boolean values. * @example * bcs.bool().serialize(true).toBytes() // Uint8Array [ 1 ] */ bool(options) { return (0, import_bcs_type.fixedSizeBcsType)({ size: 1, read: (reader) => reader.read8() === 1, write: (value, writer) => writer.write8(value ? 1 : 0), ...options, name: options?.name ?? "bool", validate: (value) => { options?.validate?.(value); if (typeof value !== "boolean") { throw new TypeError(`Expected boolean, found ${typeof value}`); } } }); }, /** * Creates a BcsType that can be used to read and write unsigned LEB encoded integers * @example * */ uleb128(options) { return (0, import_bcs_type.dynamicSizeBcsType)({ read: (reader) => reader.readULEB(), serialize: (value) => { return Uint8Array.from((0, import_uleb.ulebEncode)(value)); }, ...options, name: options?.name ?? "uleb128" }); }, /** * Creates a BcsType representing a fixed length byte array * @param size The number of bytes this types represents * @example * bcs.bytes(3).serialize(new Uint8Array([1, 2, 3])).toBytes() // Uint8Array [1, 2, 3] */ bytes(size, options) { return (0, import_bcs_type.fixedSizeBcsType)({ size, read: (reader) => reader.readBytes(size), write: (value, writer) => { writer.writeBytes(new Uint8Array(value)); }, ...options, name: options?.name ?? `bytes[${size}]`, validate: (value) => { options?.validate?.(value); if (!value || typeof value !== "object" || !("length" in value)) { throw new TypeError(`Expected array, found ${typeof value}`); } if (value.length !== size) { throw new TypeError(`Expected array of length ${size}, found ${value.length}`); } } }); }, /** * Creates a BcsType representing a variable length byte array * * @example * bcs.byteVector().serialize([1, 2, 3]).toBytes() // Uint8Array [3, 1, 2, 3] */ byteVector(options) { return new import_bcs_type.BcsType({ read: (reader) => { const length = reader.readULEB(); return reader.readBytes(length); }, write: (value, writer) => { const array = new Uint8Array(value); writer.writeULEB(array.length); writer.writeBytes(array); }, ...options, name: options?.name ?? "vector<u8>", serializedSize: (value) => { const length = "length" in value ? value.length : null; return length == null ? null : (0, import_uleb.ulebEncode)(length).length + length; }, validate: (value) => { options?.validate?.(value); if (!value || typeof value !== "object" || !("length" in value)) { throw new TypeError(`Expected array, found ${typeof value}`); } } }); }, /** * Creates a BcsType that can ser/de string values. Strings will be UTF-8 encoded * @example * bcs.string().serialize('a').toBytes() // Uint8Array [ 1, 97 ] */ string(options) { return (0, import_bcs_type.stringLikeBcsType)({ toBytes: (value) => new TextEncoder().encode(value), fromBytes: (bytes) => new TextDecoder().decode(bytes), ...options, name: options?.name ?? "string" }); }, /** * Creates a BcsType that represents a fixed length array of a given type * @param size The number of elements in the array * @param type The BcsType of each element in the array * @example * bcs.fixedArray(3, bcs.u8()).serialize([1, 2, 3]).toBytes() // Uint8Array [ 1, 2, 3 ] */ fixedArray, /** * Creates a BcsType representing an optional value * @param type The BcsType of the optional value * @example * bcs.option(bcs.u8()).serialize(null).toBytes() // Uint8Array [ 0 ] * bcs.option(bcs.u8()).serialize(1).toBytes() // Uint8Array [ 1, 1 ] */ option, /** * Creates a BcsType representing a variable length vector of a given type * @param type The BcsType of each element in the vector * * @example * bcs.vector(bcs.u8()).toBytes([1, 2, 3]) // Uint8Array [ 3, 1, 2, 3 ] */ vector, /** * Creates a BcsType representing a tuple of a given set of types * @param types The BcsTypes for each element in the tuple * * @example * const tuple = bcs.tuple([bcs.u8(), bcs.string(), bcs.bool()]) * tuple.serialize([1, 'a', true]).toBytes() // Uint8Array [ 1, 1, 97, 1 ] */ tuple(fields, options) { return new import_bcs_type.BcsTuple({ fields, ...options }); }, /** * Creates a BcsType representing a struct of a given set of fields * @param name The name of the struct * @param fields The fields of the struct. The order of the fields affects how data is serialized and deserialized * * @example * const struct = bcs.struct('MyStruct', { * a: bcs.u8(), * b: bcs.string(), * }) * struct.serialize({ a: 1, b: 'a' }).toBytes() // Uint8Array [ 1, 1, 97 ] */ struct(name, fields, options) { return new import_bcs_type.BcsStruct({ name, fields, ...options }); }, /** * Creates a BcsType representing an enum of a given set of options * @param name The name of the enum * @param values The values of the enum. The order of the values affects how data is serialized and deserialized. * null can be used to represent a variant with no data. * * @example * const enum = bcs.enum('MyEnum', { * A: bcs.u8(), * B: bcs.string(), * C: null, * }) * enum.serialize({ A: 1 }).toBytes() // Uint8Array [ 0, 1 ] * enum.serialize({ B: 'a' }).toBytes() // Uint8Array [ 1, 1, 97 ] * enum.serialize({ C: true }).toBytes() // Uint8Array [ 2 ] */ enum(name, fields, options) { return new import_bcs_type.BcsEnum({ name, fields, ...options }); }, /** * Creates a BcsType representing a map of a given key and value type * @param keyType The BcsType of the key * @param valueType The BcsType of the value * @example * const map = bcs.map(bcs.u8(), bcs.string()) * map.serialize(new Map([[2, 'a']])).toBytes() // Uint8Array [ 1, 2, 1, 97 ] */ map, /** * Creates a BcsType that wraps another BcsType which is lazily evaluated. This is useful for creating recursive types. * @param cb A callback that returns the BcsType */ lazy(cb) { return (0, import_bcs_type.lazyBcsType)(cb); } }; //# sourceMappingURL=bcs.js.map