@mysten/bcs
Advanced tools
Comparing version 0.0.0-experimental-20240209003231 to 0.0.0-experimental-20240529040124
# Change Log | ||
## 0.0.0-experimental-20240209003231 | ||
## 0.0.0-experimental-20240529040124 | ||
### Major Changes | ||
- a92b03de42: The Typescript SDK has been renamed to `@mysten/sui` and includes many new features and breaking changes. | ||
See the [full migration guide](https://sdk.mystenlabs.com/typescript/migrations/sui-1.0) for details on how to upgrade. | ||
## 0.11.1 | ||
### Patch Changes | ||
@@ -6,0 +13,0 @@ |
@@ -27,3 +27,6 @@ import { BcsReader } from './reader.js'; | ||
parse(bytes: Uint8Array): T; | ||
transform<T2, Input2>({ name, input, output, }: { | ||
fromHex(hex: string): T; | ||
fromBase58(b64: string): T; | ||
fromBase64(b64: string): T; | ||
transform<T2, Input2>({ name, input, output, validate, }: { | ||
input: (val: Input2) => Input; | ||
@@ -30,0 +33,0 @@ output: (value: T) => T2; |
@@ -66,3 +66,6 @@ "use strict"; | ||
__privateSet(this, _serialize, options.serialize ?? ((value, options2) => { | ||
const writer = new import_writer.BcsWriter({ size: this.serializedSize(value) ?? void 0, ...options2 }); | ||
const writer = new import_writer.BcsWriter({ | ||
initialSize: this.serializedSize(value) ?? void 0, | ||
...options2 | ||
}); | ||
__privateGet(this, _write).call(this, value, writer); | ||
@@ -86,6 +89,16 @@ return writer.toBytes(); | ||
} | ||
fromHex(hex) { | ||
return this.parse((0, import_hex.fromHEX)(hex)); | ||
} | ||
fromBase58(b64) { | ||
return this.parse((0, import_b58.fromB58)(b64)); | ||
} | ||
fromBase64(b64) { | ||
return this.parse((0, import_b64.fromB64)(b64)); | ||
} | ||
transform({ | ||
name, | ||
input, | ||
output | ||
output, | ||
validate | ||
}) { | ||
@@ -98,3 +111,6 @@ return new _BcsType({ | ||
serialize: (value, options) => __privateGet(this, _serialize).call(this, input(value), options), | ||
validate: (value) => this.validate(input(value)) | ||
validate: (value) => { | ||
validate?.(value); | ||
this.validate(input(value)); | ||
} | ||
}); | ||
@@ -101,0 +117,0 @@ } |
import type { BcsTypeOptions } from './bcs-type.js'; | ||
import { BcsType } from './bcs-type.js'; | ||
import type { GenericPlaceholder, ReplaceBcsGenerics } from './types.js'; | ||
import type { EnumInputShape, EnumOutputShape } from './types.js'; | ||
export declare const bcs: { | ||
@@ -85,3 +85,3 @@ /** | ||
*/ | ||
option<T_2, Input_1>(type: BcsType<T_2, Input_1>): BcsType<T_2 | null, Input_1 | null | undefined>; | ||
option<T_2, Input_1>(type: BcsType<T_2, Input_1>): BcsType<T_2 | null | undefined, Input_1 | null | undefined>; | ||
/** | ||
@@ -137,3 +137,3 @@ * Creates a BcsType representing a variable length vector of a given type | ||
*/ | ||
enum<T_9 extends Record<string, BcsType<any, any> | null>>(name: string, values: T_9, options?: Omit<BcsTypeOptions<{ [K_8 in keyof T_9]: T_9[K_8] extends BcsType<infer U_4, any> ? { [K2 in K_8]: U_4; } : { [K2_1 in K_8]: true; }; }[keyof T_9], { [K_9 in keyof T_9]: T_9[K_9] extends BcsType<any, infer U_5> ? { [K2_2 in K_9]: U_5; } : { [K2_3 in K_9]: unknown; }; }[keyof T_9]>, "name"> | undefined): BcsType<{ [K_10 in keyof T_9]: T_9[K_10] extends BcsType<infer U_6, any> ? { [K2_4 in K_10]: U_6; } : { [K2_5 in K_10]: true; }; }[keyof T_9], { [K_11 in keyof T_9]: T_9[K_11] extends BcsType<any, infer U_7> ? { [K2_6 in K_11]: U_7; } : { [K2_7 in K_11]: unknown; }; }[keyof T_9]>; | ||
enum<T_9 extends Record<string, BcsType<any, any> | null>>(name: string, values: T_9, options?: Omit<BcsTypeOptions<EnumOutputShape<{ [K_8 in keyof T_9]: T_9[K_8] extends BcsType<infer U_4, any> ? U_4 : true; }>, EnumInputShape<{ [K_9 in keyof T_9]: T_9[K_9] extends BcsType<any, infer U_5> ? U_5 : boolean | object | null; }>>, "name"> | undefined): BcsType<EnumOutputShape<{ [K_10 in keyof T_9]: T_9[K_10] extends BcsType<infer U_6, any> ? U_6 : true; }>, EnumInputShape<{ [K_11 in keyof T_9]: T_9[K_11] extends BcsType<any, infer U_7> ? U_7 : boolean | object | null; }>>; | ||
/** | ||
@@ -149,21 +149,6 @@ * Creates a BcsType representing a map of a given key and value type | ||
/** | ||
* @deprecated | ||
* | ||
* Generics should be implemented as generic typescript functions instead: | ||
* | ||
* ```ts | ||
* function VecMap<K, V>, (K: BcsType<K>, V: BcsType<V>) { | ||
* return bcs.struct('VecMap<K, V>', { | ||
* keys: bcs.vector(K), | ||
* values: bcs.vector(V), | ||
* }) | ||
* } | ||
* ``` | ||
*/ | ||
generic<const Names extends readonly string[], const Type extends BcsType<any, any>>(_names: Names, cb: (...types: { [K_13 in keyof Names]: BcsType<GenericPlaceholder<Names[K_13]>, GenericPlaceholder<Names[K_13]>>; }) => Type): <T_10 extends { [K_14 in keyof Names]: BcsType<any, any>; }>(...types: T_10) => ReplaceBcsGenerics<Type, Names, T_10>; | ||
/** | ||
* 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<T_11 extends BcsType<any, any>>(cb: () => T_11): T_11; | ||
lazy<T_10 extends BcsType<any, any>>(cb: () => T_10): T_10; | ||
}; |
@@ -404,7 +404,10 @@ "use strict"; | ||
return { | ||
[name2]: type?.read(reader) ?? true | ||
[name2]: type?.read(reader) ?? true, | ||
$kind: name2 | ||
}; | ||
}, | ||
write: (value, writer) => { | ||
const [name2, val] = Object.entries(value)[0]; | ||
const [name2, val] = Object.entries(value).filter( | ||
([name3]) => Object.hasOwn(values, name3) | ||
)[0]; | ||
for (let i = 0; i < canonicalOrder.length; i++) { | ||
@@ -425,9 +428,13 @@ const [optionName, optionType] = canonicalOrder[i]; | ||
} | ||
const keys = Object.keys(value); | ||
const keys = Object.keys(value).filter( | ||
(k) => value[k] !== void 0 && Object.hasOwn(values, k) | ||
); | ||
if (keys.length !== 1) { | ||
throw new TypeError(`Expected object with one key, found ${keys.length}`); | ||
throw new TypeError( | ||
`Expected object with one key, but found ${keys.length} for type ${name}}` | ||
); | ||
} | ||
const [name2] = keys; | ||
if (!Object.hasOwn(values, name2)) { | ||
throw new TypeError(`Invalid enum variant ${name2}`); | ||
const [variant] = keys; | ||
if (!Object.hasOwn(values, variant)) { | ||
throw new TypeError(`Invalid enum variant ${variant}`); | ||
} | ||
@@ -461,25 +468,2 @@ } | ||
/** | ||
* @deprecated | ||
* | ||
* Generics should be implemented as generic typescript functions instead: | ||
* | ||
* ```ts | ||
* function VecMap<K, V>, (K: BcsType<K>, V: BcsType<V>) { | ||
* return bcs.struct('VecMap<K, V>', { | ||
* keys: bcs.vector(K), | ||
* values: bcs.vector(V), | ||
* }) | ||
* } | ||
* ``` | ||
*/ | ||
generic(_names, cb) { | ||
return (...types) => { | ||
return cb(...types).transform({ | ||
name: `${cb.name}<${types.map((t) => t.name).join(", ")}>`, | ||
input: (value) => value, | ||
output: (value) => value | ||
}); | ||
}; | ||
}, | ||
/** | ||
* Creates a BcsType that wraps another BcsType which is lazily evaluated. This is useful for creating recursive types. | ||
@@ -486,0 +470,0 @@ * @param cb A callback that returns the BcsType |
@@ -8,7 +8,6 @@ import { fromB58, toB58 } from './b58.js'; | ||
import { BcsReader } from './reader.js'; | ||
import type { InferBcsInput, InferBcsType } from './types.js'; | ||
import type { EnumInputShape, EnumOutputShape, EnumOutputShapeWithKeys, InferBcsInput, InferBcsType } from './types.js'; | ||
import { decodeStr, encodeStr, splitGenericParameters } from './utils.js'; | ||
import type { BcsWriterOptions } from './writer.js'; | ||
import { BcsWriter } from './writer.js'; | ||
export * from './legacy-registry.js'; | ||
export { bcs, BcsType, type BcsTypeOptions, SerializedBcs, isSerializedBcs, toB58, fromB58, toB64, fromB64, fromHEX, toHEX, encodeStr, decodeStr, splitGenericParameters, BcsReader, BcsWriter, type BcsWriterOptions, type InferBcsInput, type InferBcsType, }; | ||
export { bcs, BcsType, type BcsTypeOptions, SerializedBcs, isSerializedBcs, toB58, fromB58, toB64, fromB64, fromHEX, toHEX, encodeStr, decodeStr, splitGenericParameters, BcsReader, BcsWriter, type BcsWriterOptions, type InferBcsInput, type InferBcsType, type EnumOutputShape, type EnumInputShape, type EnumOutputShapeWithKeys, }; |
@@ -18,3 +18,2 @@ "use strict"; | ||
}; | ||
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default")); | ||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
@@ -48,3 +47,2 @@ var src_exports = {}; | ||
var import_writer = require("./writer.js"); | ||
__reExport(src_exports, require("./legacy-registry.js"), module.exports); | ||
//# sourceMappingURL=index.js.map |
@@ -7,25 +7,22 @@ import type { BcsType } from './bcs-type.js'; | ||
export type Encoding = 'base58' | 'base64' | 'hex'; | ||
type UnionToIntersection<T> = (T extends any ? (x: T) => any : never) extends (x: infer R) => any ? { | ||
[K in keyof R]: R[K]; | ||
} : never; | ||
type RecursivelyReplacePlaceholder<T, R extends Record<string, unknown>> = T extends GenericPlaceholder<infer K extends keyof R> ? R[K] : T extends Record<string, unknown> | unknown[] ? { | ||
[K in keyof T]: RecursivelyReplacePlaceholder<T[K], R>; | ||
} : T extends Map<infer K, infer V> ? Map<RecursivelyReplacePlaceholder<K, R>, RecursivelyReplacePlaceholder<V, R>> : T; | ||
declare const bcsGenericPlaceholder: unique symbol; | ||
export interface GenericPlaceholder<T> { | ||
[bcsGenericPlaceholder]: T; | ||
} | ||
export type ReplaceBcsGenerics<Type extends BcsType<any>, Names extends readonly string[], Types extends { | ||
[K in keyof Names]: BcsType<any>; | ||
}> = Type extends BcsType<infer U, any> ? BcsType<RecursivelyReplacePlaceholder<U, UnionToIntersection<{ | ||
[K in keyof Names]: Types[K] extends BcsType<infer R, any> ? { | ||
[K2 in Names[K]]: R; | ||
} : never; | ||
}[number]>>, RecursivelyReplacePlaceholder<U, UnionToIntersection<{ | ||
[K in keyof Names]: Types[K] extends BcsType<any, infer R> ? { | ||
[K2 in Names[K]]: R; | ||
} : never; | ||
}[number]>>> : never; | ||
export type InferBcsType<T extends BcsType<any>> = T extends BcsType<infer U, any> ? U : never; | ||
export type InferBcsInput<T extends BcsType<any, any>> = T extends BcsType<any, infer U> ? U : never; | ||
type Merge<T> = T extends object ? { | ||
[K in keyof T]: T[K]; | ||
} : never; | ||
export 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>; | ||
export type EnumOutputShapeWithKeys<T extends Record<string, unknown>, Keys extends string> = { | ||
[K in keyof T]: Exclude<Keys, K> extends infer Empty extends string ? Merge<{ | ||
[K2 in K]: T[K]; | ||
} & { | ||
[K in Empty]?: never; | ||
} & { | ||
$kind: K; | ||
}> : never; | ||
}[keyof T]; | ||
export type EnumInputShape<T extends Record<string, unknown>> = { | ||
[K in keyof T]: { | ||
[K2 in K]: T[K]; | ||
}; | ||
}[keyof T]; | ||
export {}; |
@@ -17,3 +17,2 @@ "use strict"; | ||
module.exports = __toCommonJS(types_exports); | ||
const bcsGenericPlaceholder = Symbol("bcsPlaceholder"); | ||
//# sourceMappingURL=types.js.map |
import type { Encoding } from './types.js'; | ||
export interface BcsWriterOptions { | ||
/** The initial size (in bytes) of the buffer tht will be allocated */ | ||
size?: number; | ||
initialSize?: number; | ||
/** The maximum size (in bytes) that the buffer is allowed to grow to */ | ||
@@ -33,3 +33,3 @@ maxSize?: number; | ||
private allocateSize; | ||
constructor({ size, maxSize, allocateSize }?: BcsWriterOptions); | ||
constructor({ initialSize, maxSize, allocateSize, }?: BcsWriterOptions); | ||
private ensureSizeOrGrow; | ||
@@ -36,0 +36,0 @@ /** |
@@ -27,8 +27,12 @@ "use strict"; | ||
class BcsWriter { | ||
constructor({ size = 1024, maxSize, allocateSize = 1024 } = {}) { | ||
constructor({ | ||
initialSize = 1024, | ||
maxSize = Infinity, | ||
allocateSize = 1024 | ||
} = {}) { | ||
this.bytePosition = 0; | ||
this.size = size; | ||
this.maxSize = maxSize || size; | ||
this.size = initialSize; | ||
this.maxSize = maxSize; | ||
this.allocateSize = allocateSize; | ||
this.dataView = new DataView(new ArrayBuffer(size)); | ||
this.dataView = new DataView(new ArrayBuffer(initialSize)); | ||
} | ||
@@ -35,0 +39,0 @@ ensureSizeOrGrow(bytes) { |
@@ -27,3 +27,6 @@ import { BcsReader } from './reader.js'; | ||
parse(bytes: Uint8Array): T; | ||
transform<T2, Input2>({ name, input, output, }: { | ||
fromHex(hex: string): T; | ||
fromBase58(b64: string): T; | ||
fromBase64(b64: string): T; | ||
transform<T2, Input2>({ name, input, output, validate, }: { | ||
input: (val: Input2) => Input; | ||
@@ -30,0 +33,0 @@ output: (value: T) => T2; |
@@ -20,5 +20,5 @@ var __accessCheck = (obj, member, msg) => { | ||
var _write, _serialize, _schema, _bytes; | ||
import { toB58 } from "./b58.js"; | ||
import { toB64 } from "./b64.js"; | ||
import { toHEX } from "./hex.js"; | ||
import { fromB58, toB58 } from "./b58.js"; | ||
import { fromB64, toB64 } from "./b64.js"; | ||
import { fromHEX, toHEX } from "./hex.js"; | ||
import { BcsReader } from "./reader.js"; | ||
@@ -36,3 +36,6 @@ import { ulebEncode } from "./uleb.js"; | ||
__privateSet(this, _serialize, options.serialize ?? ((value, options2) => { | ||
const writer = new BcsWriter({ size: this.serializedSize(value) ?? void 0, ...options2 }); | ||
const writer = new BcsWriter({ | ||
initialSize: this.serializedSize(value) ?? void 0, | ||
...options2 | ||
}); | ||
__privateGet(this, _write).call(this, value, writer); | ||
@@ -56,6 +59,16 @@ return writer.toBytes(); | ||
} | ||
fromHex(hex) { | ||
return this.parse(fromHEX(hex)); | ||
} | ||
fromBase58(b64) { | ||
return this.parse(fromB58(b64)); | ||
} | ||
fromBase64(b64) { | ||
return this.parse(fromB64(b64)); | ||
} | ||
transform({ | ||
name, | ||
input, | ||
output | ||
output, | ||
validate | ||
}) { | ||
@@ -68,3 +81,6 @@ return new _BcsType({ | ||
serialize: (value, options) => __privateGet(this, _serialize).call(this, input(value), options), | ||
validate: (value) => this.validate(input(value)) | ||
validate: (value) => { | ||
validate?.(value); | ||
this.validate(input(value)); | ||
} | ||
}); | ||
@@ -71,0 +87,0 @@ } |
import type { BcsTypeOptions } from './bcs-type.js'; | ||
import { BcsType } from './bcs-type.js'; | ||
import type { GenericPlaceholder, ReplaceBcsGenerics } from './types.js'; | ||
import type { EnumInputShape, EnumOutputShape } from './types.js'; | ||
export declare const bcs: { | ||
@@ -85,3 +85,3 @@ /** | ||
*/ | ||
option<T_2, Input_1>(type: BcsType<T_2, Input_1>): BcsType<T_2 | null, Input_1 | null | undefined>; | ||
option<T_2, Input_1>(type: BcsType<T_2, Input_1>): BcsType<T_2 | null | undefined, Input_1 | null | undefined>; | ||
/** | ||
@@ -137,3 +137,3 @@ * Creates a BcsType representing a variable length vector of a given type | ||
*/ | ||
enum<T_9 extends Record<string, BcsType<any, any> | null>>(name: string, values: T_9, options?: Omit<BcsTypeOptions<{ [K_8 in keyof T_9]: T_9[K_8] extends BcsType<infer U_4, any> ? { [K2 in K_8]: U_4; } : { [K2_1 in K_8]: true; }; }[keyof T_9], { [K_9 in keyof T_9]: T_9[K_9] extends BcsType<any, infer U_5> ? { [K2_2 in K_9]: U_5; } : { [K2_3 in K_9]: unknown; }; }[keyof T_9]>, "name"> | undefined): BcsType<{ [K_10 in keyof T_9]: T_9[K_10] extends BcsType<infer U_6, any> ? { [K2_4 in K_10]: U_6; } : { [K2_5 in K_10]: true; }; }[keyof T_9], { [K_11 in keyof T_9]: T_9[K_11] extends BcsType<any, infer U_7> ? { [K2_6 in K_11]: U_7; } : { [K2_7 in K_11]: unknown; }; }[keyof T_9]>; | ||
enum<T_9 extends Record<string, BcsType<any, any> | null>>(name: string, values: T_9, options?: Omit<BcsTypeOptions<EnumOutputShape<{ [K_8 in keyof T_9]: T_9[K_8] extends BcsType<infer U_4, any> ? U_4 : true; }>, EnumInputShape<{ [K_9 in keyof T_9]: T_9[K_9] extends BcsType<any, infer U_5> ? U_5 : boolean | object | null; }>>, "name"> | undefined): BcsType<EnumOutputShape<{ [K_10 in keyof T_9]: T_9[K_10] extends BcsType<infer U_6, any> ? U_6 : true; }>, EnumInputShape<{ [K_11 in keyof T_9]: T_9[K_11] extends BcsType<any, infer U_7> ? U_7 : boolean | object | null; }>>; | ||
/** | ||
@@ -149,21 +149,6 @@ * Creates a BcsType representing a map of a given key and value type | ||
/** | ||
* @deprecated | ||
* | ||
* Generics should be implemented as generic typescript functions instead: | ||
* | ||
* ```ts | ||
* function VecMap<K, V>, (K: BcsType<K>, V: BcsType<V>) { | ||
* return bcs.struct('VecMap<K, V>', { | ||
* keys: bcs.vector(K), | ||
* values: bcs.vector(V), | ||
* }) | ||
* } | ||
* ``` | ||
*/ | ||
generic<const Names extends readonly string[], const Type extends BcsType<any, any>>(_names: Names, cb: (...types: { [K_13 in keyof Names]: BcsType<GenericPlaceholder<Names[K_13]>, GenericPlaceholder<Names[K_13]>>; }) => Type): <T_10 extends { [K_14 in keyof Names]: BcsType<any, any>; }>(...types: T_10) => ReplaceBcsGenerics<Type, Names, T_10>; | ||
/** | ||
* 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<T_11 extends BcsType<any, any>>(cb: () => T_11): T_11; | ||
lazy<T_10 extends BcsType<any, any>>(cb: () => T_10): T_10; | ||
}; |
@@ -389,7 +389,10 @@ import { | ||
return { | ||
[name2]: type?.read(reader) ?? true | ||
[name2]: type?.read(reader) ?? true, | ||
$kind: name2 | ||
}; | ||
}, | ||
write: (value, writer) => { | ||
const [name2, val] = Object.entries(value)[0]; | ||
const [name2, val] = Object.entries(value).filter( | ||
([name3]) => Object.hasOwn(values, name3) | ||
)[0]; | ||
for (let i = 0; i < canonicalOrder.length; i++) { | ||
@@ -410,9 +413,13 @@ const [optionName, optionType] = canonicalOrder[i]; | ||
} | ||
const keys = Object.keys(value); | ||
const keys = Object.keys(value).filter( | ||
(k) => value[k] !== void 0 && Object.hasOwn(values, k) | ||
); | ||
if (keys.length !== 1) { | ||
throw new TypeError(`Expected object with one key, found ${keys.length}`); | ||
throw new TypeError( | ||
`Expected object with one key, but found ${keys.length} for type ${name}}` | ||
); | ||
} | ||
const [name2] = keys; | ||
if (!Object.hasOwn(values, name2)) { | ||
throw new TypeError(`Invalid enum variant ${name2}`); | ||
const [variant] = keys; | ||
if (!Object.hasOwn(values, variant)) { | ||
throw new TypeError(`Invalid enum variant ${variant}`); | ||
} | ||
@@ -446,25 +453,2 @@ } | ||
/** | ||
* @deprecated | ||
* | ||
* Generics should be implemented as generic typescript functions instead: | ||
* | ||
* ```ts | ||
* function VecMap<K, V>, (K: BcsType<K>, V: BcsType<V>) { | ||
* return bcs.struct('VecMap<K, V>', { | ||
* keys: bcs.vector(K), | ||
* values: bcs.vector(V), | ||
* }) | ||
* } | ||
* ``` | ||
*/ | ||
generic(_names, cb) { | ||
return (...types) => { | ||
return cb(...types).transform({ | ||
name: `${cb.name}<${types.map((t) => t.name).join(", ")}>`, | ||
input: (value) => value, | ||
output: (value) => value | ||
}); | ||
}; | ||
}, | ||
/** | ||
* Creates a BcsType that wraps another BcsType which is lazily evaluated. This is useful for creating recursive types. | ||
@@ -471,0 +455,0 @@ * @param cb A callback that returns the BcsType |
@@ -8,7 +8,6 @@ import { fromB58, toB58 } from './b58.js'; | ||
import { BcsReader } from './reader.js'; | ||
import type { InferBcsInput, InferBcsType } from './types.js'; | ||
import type { EnumInputShape, EnumOutputShape, EnumOutputShapeWithKeys, InferBcsInput, InferBcsType } from './types.js'; | ||
import { decodeStr, encodeStr, splitGenericParameters } from './utils.js'; | ||
import type { BcsWriterOptions } from './writer.js'; | ||
import { BcsWriter } from './writer.js'; | ||
export * from './legacy-registry.js'; | ||
export { bcs, BcsType, type BcsTypeOptions, SerializedBcs, isSerializedBcs, toB58, fromB58, toB64, fromB64, fromHEX, toHEX, encodeStr, decodeStr, splitGenericParameters, BcsReader, BcsWriter, type BcsWriterOptions, type InferBcsInput, type InferBcsType, }; | ||
export { bcs, BcsType, type BcsTypeOptions, SerializedBcs, isSerializedBcs, toB58, fromB58, toB64, fromB64, fromHEX, toHEX, encodeStr, decodeStr, splitGenericParameters, BcsReader, BcsWriter, type BcsWriterOptions, type InferBcsInput, type InferBcsType, type EnumOutputShape, type EnumInputShape, type EnumOutputShapeWithKeys, }; |
@@ -9,3 +9,2 @@ import { fromB58, toB58 } from "./b58.js"; | ||
import { BcsWriter } from "./writer.js"; | ||
export * from "./legacy-registry.js"; | ||
export { | ||
@@ -12,0 +11,0 @@ BcsReader, |
@@ -7,25 +7,22 @@ import type { BcsType } from './bcs-type.js'; | ||
export type Encoding = 'base58' | 'base64' | 'hex'; | ||
type UnionToIntersection<T> = (T extends any ? (x: T) => any : never) extends (x: infer R) => any ? { | ||
[K in keyof R]: R[K]; | ||
} : never; | ||
type RecursivelyReplacePlaceholder<T, R extends Record<string, unknown>> = T extends GenericPlaceholder<infer K extends keyof R> ? R[K] : T extends Record<string, unknown> | unknown[] ? { | ||
[K in keyof T]: RecursivelyReplacePlaceholder<T[K], R>; | ||
} : T extends Map<infer K, infer V> ? Map<RecursivelyReplacePlaceholder<K, R>, RecursivelyReplacePlaceholder<V, R>> : T; | ||
declare const bcsGenericPlaceholder: unique symbol; | ||
export interface GenericPlaceholder<T> { | ||
[bcsGenericPlaceholder]: T; | ||
} | ||
export type ReplaceBcsGenerics<Type extends BcsType<any>, Names extends readonly string[], Types extends { | ||
[K in keyof Names]: BcsType<any>; | ||
}> = Type extends BcsType<infer U, any> ? BcsType<RecursivelyReplacePlaceholder<U, UnionToIntersection<{ | ||
[K in keyof Names]: Types[K] extends BcsType<infer R, any> ? { | ||
[K2 in Names[K]]: R; | ||
} : never; | ||
}[number]>>, RecursivelyReplacePlaceholder<U, UnionToIntersection<{ | ||
[K in keyof Names]: Types[K] extends BcsType<any, infer R> ? { | ||
[K2 in Names[K]]: R; | ||
} : never; | ||
}[number]>>> : never; | ||
export type InferBcsType<T extends BcsType<any>> = T extends BcsType<infer U, any> ? U : never; | ||
export type InferBcsInput<T extends BcsType<any, any>> = T extends BcsType<any, infer U> ? U : never; | ||
type Merge<T> = T extends object ? { | ||
[K in keyof T]: T[K]; | ||
} : never; | ||
export 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>; | ||
export type EnumOutputShapeWithKeys<T extends Record<string, unknown>, Keys extends string> = { | ||
[K in keyof T]: Exclude<Keys, K> extends infer Empty extends string ? Merge<{ | ||
[K2 in K]: T[K]; | ||
} & { | ||
[K in Empty]?: never; | ||
} & { | ||
$kind: K; | ||
}> : never; | ||
}[keyof T]; | ||
export type EnumInputShape<T extends Record<string, unknown>> = { | ||
[K in keyof T]: { | ||
[K2 in K]: T[K]; | ||
}; | ||
}[keyof T]; | ||
export {}; |
@@ -1,2 +0,1 @@ | ||
const bcsGenericPlaceholder = Symbol("bcsPlaceholder"); | ||
//# sourceMappingURL=types.js.map |
import type { Encoding } from './types.js'; | ||
export interface BcsWriterOptions { | ||
/** The initial size (in bytes) of the buffer tht will be allocated */ | ||
size?: number; | ||
initialSize?: number; | ||
/** The maximum size (in bytes) that the buffer is allowed to grow to */ | ||
@@ -33,3 +33,3 @@ maxSize?: number; | ||
private allocateSize; | ||
constructor({ size, maxSize, allocateSize }?: BcsWriterOptions); | ||
constructor({ initialSize, maxSize, allocateSize, }?: BcsWriterOptions); | ||
private ensureSizeOrGrow; | ||
@@ -36,0 +36,0 @@ /** |
import { ulebEncode } from "./uleb.js"; | ||
import { encodeStr } from "./utils.js"; | ||
class BcsWriter { | ||
constructor({ size = 1024, maxSize, allocateSize = 1024 } = {}) { | ||
constructor({ | ||
initialSize = 1024, | ||
maxSize = Infinity, | ||
allocateSize = 1024 | ||
} = {}) { | ||
this.bytePosition = 0; | ||
this.size = size; | ||
this.maxSize = maxSize || size; | ||
this.size = initialSize; | ||
this.maxSize = maxSize; | ||
this.allocateSize = allocateSize; | ||
this.dataView = new DataView(new ArrayBuffer(size)); | ||
this.dataView = new DataView(new ArrayBuffer(initialSize)); | ||
} | ||
@@ -11,0 +15,0 @@ ensureSizeOrGrow(bytes) { |
{ | ||
"name": "@mysten/bcs", | ||
"version": "0.0.0-experimental-20240209003231", | ||
"version": "0.0.0-experimental-20240529040124", | ||
"description": "BCS - Canonical Binary Serialization implementation for JavaScript", | ||
@@ -53,3 +53,3 @@ "license": "Apache-2.0", | ||
"typescript": "^5.3.3", | ||
"vitest": "^0.33.0", | ||
"vitest": "^1.6.0", | ||
"@mysten/build-scripts": "0.0.0" | ||
@@ -56,0 +56,0 @@ }, |
@@ -22,5 +22,5 @@ # BCS - Binary Canonical Serialization | ||
// define UID as a 32-byte array, then add a transform to/from hex strings | ||
const UID = bcs.array(32, bcs.u8()).transform({ | ||
input: (id: string) => fromHex(id), | ||
output: (id) => toHex(id), | ||
const UID = bcs.fixedArray(32, bcs.u8()).transform({ | ||
input: (id: string) => fromHEX(id), | ||
output: (id) => toHEX(Uint8Array.from(id)), | ||
}); | ||
@@ -55,4 +55,4 @@ | ||
The `@mysten/bcs` library can be used to define schemas that can serialize and deserialize BCS | ||
encoded data, and and can infer the correct TypeScript for the schema from the definitions | ||
themselves rather than having to define them manually. | ||
encoded data, and can infer the correct TypeScript for the schema from the definitions themselves | ||
rather than having to define them manually. | ||
@@ -152,6 +152,11 @@ ## Basic types | ||
// Map | ||
const map = bcs.map(bcs.u8(), bcs.string()).serialize(.toBytes()[ | ||
[1, 'one'], | ||
[2, 'two'], | ||
]); | ||
const map = bcs | ||
.map(bcs.u8(), bcs.string()) | ||
.serialize( | ||
new Map([ | ||
[1, 'one'], | ||
[2, 'two'], | ||
]), | ||
) | ||
.toBytes(); | ||
@@ -259,3 +264,3 @@ // Parsing data back into original types | ||
transforms can also handle more complex types. For instance, `@mysten/sui.js` uses the following | ||
transforms can also handle more complex types. For instance, `@mysten/sui` uses the following | ||
definition to transform enums into a more TypeScript friends format: | ||
@@ -262,0 +267,0 @@ |
// Copyright (c) Mysten Labs, Inc. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
import { toB58 } from './b58.js'; | ||
import { toB64 } from './b64.js'; | ||
import { toHEX } from './hex.js'; | ||
import { fromB58, toB58 } from './b58.js'; | ||
import { fromB64, toB64 } from './b64.js'; | ||
import { fromHEX, toHEX } from './hex.js'; | ||
import { BcsReader } from './reader.js'; | ||
@@ -44,3 +44,6 @@ import { ulebEncode } from './uleb.js'; | ||
((value, options) => { | ||
const writer = new BcsWriter({ size: this.serializedSize(value) ?? undefined, ...options }); | ||
const writer = new BcsWriter({ | ||
initialSize: this.serializedSize(value) ?? undefined, | ||
...options, | ||
}); | ||
this.#write(value, writer); | ||
@@ -68,2 +71,14 @@ return writer.toBytes(); | ||
fromHex(hex: string) { | ||
return this.parse(fromHEX(hex)); | ||
} | ||
fromBase58(b64: string) { | ||
return this.parse(fromB58(b64)); | ||
} | ||
fromBase64(b64: string) { | ||
return this.parse(fromB64(b64)); | ||
} | ||
transform<T2, Input2>({ | ||
@@ -73,2 +88,3 @@ name, | ||
output, | ||
validate, | ||
}: { | ||
@@ -84,3 +100,6 @@ input: (val: Input2) => Input; | ||
serialize: (value, options) => this.#serialize(input(value), options), | ||
validate: (value) => this.validate(input(value)), | ||
validate: (value) => { | ||
validate?.(value); | ||
this.validate(input(value)); | ||
}, | ||
}); | ||
@@ -87,0 +106,0 @@ } |
@@ -14,3 +14,3 @@ // Copyright (c) Mysten Labs, Inc. | ||
} from './bcs-type.js'; | ||
import type { GenericPlaceholder, ReplaceBcsGenerics } from './types.js'; | ||
import type { EnumInputShape, EnumOutputShape } from './types.js'; | ||
import { ulebEncode } from './uleb.js'; | ||
@@ -463,12 +463,8 @@ | ||
BcsTypeOptions< | ||
{ | ||
[K in keyof T]: T[K] extends BcsType<infer U, any> | ||
? { [K2 in K]: U } | ||
: { [K2 in K]: true }; | ||
}[keyof T], | ||
{ | ||
[K in keyof T]: T[K] extends BcsType<any, infer U> | ||
? { [K2 in K]: U } | ||
: { [K2 in K]: unknown }; | ||
}[keyof T] | ||
EnumOutputShape<{ | ||
[K in keyof T]: T[K] extends BcsType<infer U, any> ? U : true; | ||
}>, | ||
EnumInputShape<{ | ||
[K in keyof T]: T[K] extends BcsType<any, infer U> ? U : boolean | object | null; | ||
}> | ||
>, | ||
@@ -480,10 +476,8 @@ 'name' | ||
return new BcsType< | ||
{ | ||
[K in keyof T]: T[K] extends BcsType<infer U, any> ? { [K2 in K]: U } : { [K2 in K]: true }; | ||
}[keyof T], | ||
{ | ||
[K in keyof T]: T[K] extends BcsType<any, infer U> | ||
? { [K2 in K]: U } | ||
: { [K2 in K]: unknown }; | ||
}[keyof T] | ||
EnumOutputShape<{ | ||
[K in keyof T]: T[K] extends BcsType<infer U, any> ? U : true; | ||
}>, | ||
EnumInputShape<{ | ||
[K in keyof T]: T[K] extends BcsType<any, infer U> ? U : boolean | object | null; | ||
}> | ||
>({ | ||
@@ -496,6 +490,10 @@ name, | ||
[name]: type?.read(reader) ?? true, | ||
$kind: name, | ||
} as never; | ||
}, | ||
write: (value, writer) => { | ||
const [name, val] = Object.entries(value)[0]; | ||
const [name, val] = Object.entries(value).filter(([name]) => | ||
Object.hasOwn(values, name), | ||
)[0]; | ||
for (let i = 0; i < canonicalOrder.length; i++) { | ||
@@ -517,11 +515,16 @@ const [optionName, optionType] = canonicalOrder[i]; | ||
const keys = Object.keys(value); | ||
const keys = Object.keys(value).filter( | ||
(k) => value[k] !== undefined && Object.hasOwn(values, k), | ||
); | ||
if (keys.length !== 1) { | ||
throw new TypeError(`Expected object with one key, found ${keys.length}`); | ||
throw new TypeError( | ||
`Expected object with one key, but found ${keys.length} for type ${name}}`, | ||
); | ||
} | ||
const [name] = keys; | ||
const [variant] = keys; | ||
if (!Object.hasOwn(values, name)) { | ||
throw new TypeError(`Invalid enum variant ${name}`); | ||
if (!Object.hasOwn(values, variant)) { | ||
throw new TypeError(`Invalid enum variant ${variant}`); | ||
} | ||
@@ -557,31 +560,2 @@ }, | ||
/** | ||
* @deprecated | ||
* | ||
* Generics should be implemented as generic typescript functions instead: | ||
* | ||
* ```ts | ||
* function VecMap<K, V>, (K: BcsType<K>, V: BcsType<V>) { | ||
* return bcs.struct('VecMap<K, V>', { | ||
* keys: bcs.vector(K), | ||
* values: bcs.vector(V), | ||
* }) | ||
* } | ||
* ``` | ||
*/ | ||
generic<const Names extends readonly string[], const Type extends BcsType<any>>( | ||
_names: Names, | ||
cb: (...types: { [K in keyof Names]: BcsType<GenericPlaceholder<Names[K]>> }) => Type, | ||
): <T extends { [K in keyof Names]: BcsType<any> }>( | ||
...types: T | ||
) => ReplaceBcsGenerics<Type, Names, T> { | ||
return (...types) => { | ||
return cb(...types).transform({ | ||
name: `${cb.name}<${types.map((t) => t.name).join(', ')}>`, | ||
input: (value) => value, | ||
output: (value) => value, | ||
}) as never; | ||
}; | ||
}, | ||
/** | ||
* Creates a BcsType that wraps another BcsType which is lazily evaluated. This is useful for creating recursive types. | ||
@@ -588,0 +562,0 @@ * @param cb A callback that returns the BcsType |
@@ -21,3 +21,9 @@ // Copyright (c) Mysten Labs, Inc. | ||
import { BcsReader } from './reader.js'; | ||
import type { InferBcsInput, InferBcsType } from './types.js'; | ||
import type { | ||
EnumInputShape, | ||
EnumOutputShape, | ||
EnumOutputShapeWithKeys, | ||
InferBcsInput, | ||
InferBcsType, | ||
} from './types.js'; | ||
import { decodeStr, encodeStr, splitGenericParameters } from './utils.js'; | ||
@@ -27,4 +33,2 @@ import type { BcsWriterOptions } from './writer.js'; | ||
export * from './legacy-registry.js'; | ||
// Re-export all encoding dependencies. | ||
@@ -51,2 +55,5 @@ export { | ||
type InferBcsType, | ||
type EnumOutputShape, | ||
type EnumInputShape, | ||
type EnumOutputShapeWithKeys, | ||
}; |
@@ -12,55 +12,34 @@ // Copyright (c) Mysten Labs, Inc. | ||
type UnionToIntersection<T> = (T extends any ? (x: T) => any : never) extends (x: infer R) => any | ||
? { [K in keyof R]: R[K] } | ||
export type InferBcsType<T extends BcsType<any>> = T extends BcsType<infer U, any> ? U : never; | ||
export type InferBcsInput<T extends BcsType<any, any>> = T extends BcsType<any, infer U> | ||
? U | ||
: never; | ||
type RecursivelyReplacePlaceholder< | ||
T, | ||
R extends Record<string, unknown>, | ||
> = T extends GenericPlaceholder<infer K extends keyof R> | ||
? R[K] | ||
: T extends Record<string, unknown> | unknown[] | ||
? { [K in keyof T]: RecursivelyReplacePlaceholder<T[K], R> } | ||
: T extends Map<infer K, infer V> | ||
? Map<RecursivelyReplacePlaceholder<K, R>, RecursivelyReplacePlaceholder<V, R>> | ||
: T; | ||
type Merge<T> = T extends object ? { [K in keyof T]: T[K] } : never; | ||
export 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>; | ||
const bcsGenericPlaceholder = Symbol('bcsPlaceholder'); | ||
export type EnumOutputShapeWithKeys<T extends Record<string, unknown>, Keys extends string> = { | ||
[K in keyof T]: Exclude<Keys, K> extends infer Empty extends string | ||
? Merge< | ||
{ [K2 in K]: T[K] } & { [K in Empty]?: never } & { | ||
$kind: K; | ||
} | ||
> | ||
: never; | ||
}[keyof T]; | ||
export interface GenericPlaceholder<T> { | ||
[bcsGenericPlaceholder]: T; | ||
} | ||
export type ReplaceBcsGenerics< | ||
Type extends BcsType<any>, | ||
Names extends readonly string[], | ||
Types extends { [K in keyof Names]: BcsType<any> }, | ||
> = Type extends BcsType<infer U, any> | ||
? BcsType< | ||
RecursivelyReplacePlaceholder< | ||
U, | ||
UnionToIntersection< | ||
{ | ||
[K in keyof Names]: Types[K] extends BcsType<infer R, any> | ||
? { [K2 in Names[K]]: R } | ||
: never; | ||
}[number] | ||
> | ||
>, | ||
RecursivelyReplacePlaceholder< | ||
U, | ||
UnionToIntersection< | ||
{ | ||
[K in keyof Names]: Types[K] extends BcsType<any, infer R> | ||
? { [K2 in Names[K]]: R } | ||
: never; | ||
}[number] | ||
> | ||
> | ||
> | ||
: never; | ||
export type InferBcsType<T extends BcsType<any>> = T extends BcsType<infer U, any> ? U : never; | ||
export type InferBcsInput<T extends BcsType<any, any>> = T extends BcsType<any, infer U> | ||
? U | ||
: never; | ||
export type EnumInputShape<T extends Record<string, unknown>> = { | ||
[K in keyof T]: { [K2 in K]: T[K] }; | ||
}[keyof T]; |
@@ -10,3 +10,3 @@ // Copyright (c) Mysten Labs, Inc. | ||
/** The initial size (in bytes) of the buffer tht will be allocated */ | ||
size?: number; | ||
initialSize?: number; | ||
/** The maximum size (in bytes) that the buffer is allowed to grow to */ | ||
@@ -43,7 +43,11 @@ maxSize?: number; | ||
constructor({ size = 1024, maxSize, allocateSize = 1024 }: BcsWriterOptions = {}) { | ||
this.size = size; | ||
this.maxSize = maxSize || size; | ||
constructor({ | ||
initialSize = 1024, | ||
maxSize = Infinity, | ||
allocateSize = 1024, | ||
}: BcsWriterOptions = {}) { | ||
this.size = initialSize; | ||
this.maxSize = maxSize; | ||
this.allocateSize = allocateSize; | ||
this.dataView = new DataView(new ArrayBuffer(size)); | ||
this.dataView = new DataView(new ArrayBuffer(initialSize)); | ||
} | ||
@@ -50,0 +54,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
357
345574
85
4887