typed-binary
Version:
Describe binary structures with full TypeScript support. Encode and decode into pure JavaScript objects.
1,313 lines (1,291 loc) • 35.9 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
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 __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
// src/index.ts
var src_exports = {};
__export(src_exports, {
ArraySchema: () => ArraySchema,
BoolSchema: () => BoolSchema,
BufferReader: () => BufferReader,
BufferWriter: () => BufferWriter,
ByteSchema: () => Uint8Schema,
CharsSchema: () => CharsSchema,
DynamicArraySchema: () => DynamicArraySchema,
Float16Schema: () => Float16Schema,
Float32Schema: () => Float32Schema,
GenericObjectSchema: () => GenericObjectSchema,
Int16Schema: () => Int16Schema,
Int32Schema: () => Int32Schema,
Int8Schema: () => Int8Schema,
KeyedSchema: () => KeyedSchema,
MaxValue: () => MaxValue,
Measurer: () => Measurer,
ObjectSchema: () => ObjectSchema,
OptionalSchema: () => OptionalSchema,
Schema: () => Schema,
StringSchema: () => StringSchema,
SubTypeKey: () => SubTypeKey,
TupleSchema: () => TupleSchema,
TypedArraySchema: () => TypedArraySchema,
Uint16Schema: () => Uint16Schema,
Uint32Schema: () => Uint32Schema,
Uint8Schema: () => Uint8Schema,
UnresolvedReferenceError: () => UnresolvedReferenceError,
ValidationError: () => ValidationError,
arrayOf: () => arrayOf,
bin: () => main_api_exports,
bool: () => bool,
byte: () => byte,
chars: () => chars,
concat: () => concat,
default: () => src_default,
dynamicArrayOf: () => dynamicArrayOf,
f16: () => f16,
f32: () => f32,
f32Array: () => f32Array,
f64Array: () => f64Array,
generic: () => generic,
genericEnum: () => genericEnum,
getSystemEndianness: () => getSystemEndianness,
i16: () => i16,
i16Array: () => i16Array,
i32: () => i32,
i32Array: () => i32Array,
i8: () => i8,
i8Array: () => i8Array,
keyed: () => keyed,
object: () => object,
optional: () => optional,
string: () => string,
tupleOf: () => tupleOf,
u16: () => u16,
u16Array: () => u16Array,
u32: () => u32,
u32Array: () => u32Array,
u8: () => u8,
u8Array: () => u8Array,
u8ClampedArray: () => u8ClampedArray
});
module.exports = __toCommonJS(src_exports);
// src/main-api.ts
var main_api_exports = {};
__export(main_api_exports, {
BufferReader: () => BufferReader,
BufferWriter: () => BufferWriter,
MaxValue: () => MaxValue,
Measurer: () => Measurer,
UnresolvedReferenceError: () => UnresolvedReferenceError,
ValidationError: () => ValidationError,
arrayOf: () => arrayOf,
bool: () => bool,
byte: () => byte,
chars: () => chars,
concat: () => concat,
dynamicArrayOf: () => dynamicArrayOf,
f16: () => f16,
f32: () => f32,
f32Array: () => f32Array,
f64Array: () => f64Array,
generic: () => generic,
genericEnum: () => genericEnum,
i16: () => i16,
i16Array: () => i16Array,
i32: () => i32,
i32Array: () => i32Array,
i8: () => i8,
i8Array: () => i8Array,
keyed: () => keyed,
object: () => object,
optional: () => optional,
string: () => string,
tupleOf: () => tupleOf,
u16: () => u16,
u16Array: () => u16Array,
u32: () => u32,
u32Array: () => u32Array,
u8: () => u8,
u8Array: () => u8Array,
u8ClampedArray: () => u8ClampedArray
});
// src/error.ts
var UnresolvedReferenceError = class _UnresolvedReferenceError extends Error {
constructor(msg) {
super(msg);
Object.setPrototypeOf(this, _UnresolvedReferenceError.prototype);
}
};
var ValidationError = class _ValidationError extends Error {
constructor(msg) {
super(msg);
Object.setPrototypeOf(this, _ValidationError.prototype);
}
};
// src/io/measurer.ts
var UnboundedMeasurer = class {
constructor() {
__publicField(this, "size", Number.NaN);
__publicField(this, "unbounded", this);
__publicField(this, "isUnbounded", true);
}
add() {
return this;
}
fork() {
return this;
}
};
var unboundedMeasurer = new UnboundedMeasurer();
var Measurer = class _Measurer {
constructor() {
__publicField(this, "size", 0);
__publicField(this, "unbounded", unboundedMeasurer);
__publicField(this, "isUnbounded", false);
}
add(bytes) {
this.size += bytes;
return this;
}
fork() {
const forked = new _Measurer();
forked.size = this.size;
return forked;
}
};
// src/structure/types.ts
var MaxValue = Symbol(
"The biggest (in amount of bytes needed) value a schema can represent"
);
var Schema = class {
constructor() {
__publicField(this, "__unwrapped");
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
resolveReferences(ctx) {
}
seekProperty(_reference, _prop) {
return null;
}
};
var Ref = class {
constructor(key) {
this.key = key;
}
};
var SubTypeKey = {
STRING: "string",
ENUM: "enum"
};
// src/structure/array.ts
var ArraySchema = class extends Schema {
constructor(_unstableElementSchema, length) {
super();
this._unstableElementSchema = _unstableElementSchema;
this.length = length;
__publicField(this, "elementSchema");
this.elementSchema = _unstableElementSchema;
}
resolveReferences(ctx) {
this.elementSchema = ctx.resolve(this._unstableElementSchema);
}
write(output, values) {
if (values.length !== this.length) {
throw new ValidationError(
`Expected array of length ${this.length}, got ${values.length}`
);
}
for (const value of values) {
this.elementSchema.write(output, value);
}
}
read(input) {
const array = [];
for (let i = 0; i < this.length; ++i) {
array.push(this.elementSchema.read(input));
}
return array;
}
/**
* Returns the maximum number of bytes this schema can take up.
*
* Returns `NaN` if the schema is unbounded. If you would like to know
* how many bytes a particular value encoding will take up, use `.measure(value)`.
*
* Alias for `.measure(MaxValue).size`
*/
get maxSize() {
return this.elementSchema.measure(MaxValue).size * this.length;
}
measure(values, measurer = new Measurer()) {
for (let i = 0; i < this.length; ++i) {
this.elementSchema.measure(
values === MaxValue ? MaxValue : values[i],
measurer
);
}
return measurer;
}
};
// @__NO_SIDE_EFFECTS__
function arrayOf(elementSchema, length) {
return new ArraySchema(elementSchema, length);
}
// src/structure/baseTypes.ts
var BoolSchema = class extends Schema {
constructor() {
super(...arguments);
/**
* The maximum number of bytes this schema can take up.
*
* Alias for `.measure(MaxValue).size`
*/
__publicField(this, "maxSize", 1);
}
read(input) {
return input.readBool();
}
write(output, value) {
output.writeBool(value);
}
measure(_, measurer = new Measurer()) {
return measurer.add(1);
}
};
var bool = new BoolSchema();
var _StringSchema = class _StringSchema extends Schema {
static get _encoder() {
if (!_StringSchema._cachedEncoder) {
_StringSchema._cachedEncoder = new TextEncoder();
}
return _StringSchema._cachedEncoder;
}
read(input) {
return input.readString();
}
write(output, value) {
output.writeString(value);
}
measure(value, measurer = new Measurer()) {
if (value === MaxValue) {
return measurer.unbounded;
}
const encoded = _StringSchema._encoder.encode(value);
return measurer.add(encoded.byteLength + 1);
}
};
__publicField(_StringSchema, "_cachedEncoder");
var StringSchema = _StringSchema;
var string = new StringSchema();
var Int8Schema = class extends Schema {
constructor() {
super(...arguments);
/**
* The maximum number of bytes this schema can take up.
*
* Alias for `.measure(MaxValue).size`
*/
__publicField(this, "maxSize", 1);
}
read(input) {
return input.readInt8();
}
write(output, value) {
output.writeInt8(value);
}
measure(_, measurer = new Measurer()) {
return measurer.add(1);
}
};
var i8 = new Int8Schema();
var Uint8Schema = class extends Schema {
constructor() {
super(...arguments);
/**
* The maximum number of bytes this schema can take up.
*
* Alias for `.measure(MaxValue).size`
*/
__publicField(this, "maxSize", 1);
}
read(input) {
return input.readUint8();
}
write(output, value) {
output.writeUint8(value);
}
measure(_, measurer = new Measurer()) {
return measurer.add(1);
}
};
var u8 = new Uint8Schema();
var byte = u8;
var Int16Schema = class extends Schema {
constructor() {
super(...arguments);
/**
* The maximum number of bytes this schema can take up.
*
* Alias for `.measure(MaxValue).size`
*/
__publicField(this, "maxSize", 2);
}
read(input) {
return input.readInt16();
}
write(output, value) {
output.writeInt16(value);
}
measure(_, measurer = new Measurer()) {
return measurer.add(2);
}
};
var i16 = new Int16Schema();
var Uint16Schema = class extends Schema {
constructor() {
super(...arguments);
/**
* The maximum number of bytes this schema can take up.
*
* Alias for `.measure(MaxValue).size`
*/
__publicField(this, "maxSize", 2);
}
read(input) {
return input.readUint16();
}
write(output, value) {
output.writeUint16(value);
}
measure(_, measurer = new Measurer()) {
return measurer.add(2);
}
};
var u16 = new Uint16Schema();
var Int32Schema = class extends Schema {
constructor() {
super(...arguments);
/**
* The maximum number of bytes this schema can take up.
*
* Alias for `.measure(MaxValue).size`
*/
__publicField(this, "maxSize", 4);
}
read(input) {
return input.readInt32();
}
write(output, value) {
output.writeInt32(value);
}
measure(_, measurer = new Measurer()) {
return measurer.add(4);
}
};
var i32 = new Int32Schema();
var Uint32Schema = class extends Schema {
constructor() {
super(...arguments);
/**
* The maximum number of bytes this schema can take up.
*
* Alias for `.measure(MaxValue).size`
*/
__publicField(this, "maxSize", 4);
}
read(input) {
return input.readUint32();
}
write(output, value) {
output.writeUint32(value);
}
measure(_, measurer = new Measurer()) {
return measurer.add(4);
}
};
var u32 = new Uint32Schema();
var Float16Schema = class extends Schema {
constructor() {
super(...arguments);
/**
* The maximum number of bytes this schema can take up.
*
* Alias for `.measure(MaxValue).size`
*/
__publicField(this, "maxSize", 2);
}
read(input) {
return input.readFloat16();
}
write(output, value) {
output.writeFloat16(value);
}
measure(_, measurer = new Measurer()) {
return measurer.add(2);
}
};
var f16 = new Float16Schema();
var Float32Schema = class extends Schema {
constructor() {
super(...arguments);
/**
* The maximum number of bytes this schema can take up.
*
* Alias for `.measure(MaxValue).size`
*/
__publicField(this, "maxSize", 4);
}
read(input) {
return input.readFloat32();
}
write(output, value) {
output.writeFloat32(value);
}
measure(_, measurer = new Measurer()) {
return measurer.add(4);
}
};
var f32 = new Float32Schema();
// src/structure/chars.ts
var CharsSchema = class extends Schema {
constructor(length) {
super();
this.length = length;
}
write(output, value) {
if (value.length !== this.length) {
throw new ValidationError(
`Expected char-string of length ${this.length}, got ${value.length}`
);
}
for (let i = 0; i < value.length; ++i) {
output.writeUint8(value.charCodeAt(i));
}
}
read(input) {
let content = "";
for (let i = 0; i < this.length; ++i) {
content += String.fromCharCode(input.readByte());
}
return content;
}
measure(_, measurer = new Measurer()) {
return measurer.add(this.length);
}
};
// @__NO_SIDE_EFFECTS__
function chars(length) {
return new CharsSchema(length);
}
// src/structure/object.ts
// @__NO_SIDE_EFFECTS__
function exactEntries(record) {
return Object.entries(record);
}
// @__NO_SIDE_EFFECTS__
function resolveMap(ctx, refs) {
const props = {};
for (const [key, ref] of /* @__PURE__ */ exactEntries(refs)) {
props[key] = ctx.resolve(ref);
}
return props;
}
var ObjectSchema = class extends Schema {
constructor(_properties) {
super();
this._properties = _properties;
__publicField(this, "properties");
this.properties = _properties;
}
resolveReferences(ctx) {
this.properties = /* @__PURE__ */ resolveMap(ctx, this._properties);
}
write(output, value) {
for (const [key, property] of /* @__PURE__ */ exactEntries(this.properties)) {
property.write(output, value[key]);
}
}
read(input) {
const result = {};
for (const [key, property] of /* @__PURE__ */ exactEntries(this.properties)) {
result[key] = property.read(input);
}
return result;
}
/**
* The maximum number of bytes this schema can take up.
*
* Is `NaN` if the schema is unbounded. If you would like to know
* how many bytes a particular value encoding will take up, use `.measure(value)`.
*
* Alias for `.measure(MaxValue).size`
*/
get maxSize() {
const measurer = new Measurer();
for (const property of Object.values(this.properties)) {
property.measure(MaxValue, measurer);
}
return measurer.size;
}
measure(value, measurer = new Measurer()) {
for (const [key, property] of /* @__PURE__ */ exactEntries(this.properties)) {
property.measure(
value === MaxValue ? MaxValue : value[key],
measurer
);
}
return measurer;
}
seekProperty(reference, prop) {
let bufferOffset = 0;
for (const [key, property] of /* @__PURE__ */ exactEntries(this.properties)) {
if (key === prop) {
return {
bufferOffset,
schema: property
};
}
bufferOffset += property.measure(reference).size;
}
return null;
}
};
// @__NO_SIDE_EFFECTS__
function object(properties) {
return new ObjectSchema(properties);
}
var GenericObjectSchema = class extends Schema {
constructor(keyedBy, properties, _subTypeMap) {
super();
this.keyedBy = keyedBy;
this._subTypeMap = _subTypeMap;
__publicField(this, "_baseObject");
__publicField(this, "subTypeMap");
this._baseObject = new ObjectSchema(properties);
this.subTypeMap = _subTypeMap;
}
resolveReferences(ctx) {
this._baseObject.resolveReferences(ctx);
this.subTypeMap = /* @__PURE__ */ resolveMap(ctx, this._subTypeMap);
}
write(output, value) {
const subTypeKey = value.type;
const subTypeDescription = this.subTypeMap[subTypeKey] || null;
if (subTypeDescription === null) {
throw new Error(
`Unknown sub-type '${subTypeKey.toString()}' in among '${JSON.stringify(
Object.keys(this.subTypeMap)
)}'`
);
}
if (this.keyedBy === SubTypeKey.ENUM) {
output.writeUint8(value.type);
} else {
output.writeString(value.type);
}
this._baseObject.write(output, value);
for (const [key, extraProp] of /* @__PURE__ */ exactEntries(
subTypeDescription.properties
)) {
extraProp.write(output, value[key]);
}
}
read(input) {
const subTypeKey = this.keyedBy === SubTypeKey.ENUM ? input.readByte() : input.readString();
const subTypeDescription = this.subTypeMap[subTypeKey] || null;
if (subTypeDescription === null) {
throw new Error(
`Unknown sub-type '${subTypeKey}' in among '${JSON.stringify(
Object.keys(this.subTypeMap)
)}'`
);
}
const result = this._baseObject.read(input);
result.type = subTypeKey;
if (subTypeDescription !== null) {
for (const [key, extraProp] of /* @__PURE__ */ exactEntries(
subTypeDescription.properties
)) {
result[key] = extraProp.read(input);
}
}
return result;
}
measure(value, measurer = new Measurer()) {
this._baseObject.measure(
value,
measurer
);
if (this.keyedBy === SubTypeKey.ENUM) {
measurer.add(1);
} else if (value !== MaxValue) {
measurer.add(value.type.length + 1);
} else {
return measurer.unbounded;
}
if (value === MaxValue) {
const biggestSubType = Object.values(this.subTypeMap).map((subType) => {
const forkedMeasurer = measurer.fork();
for (const prop of Object.values(subType.properties)) {
prop.measure(MaxValue, forkedMeasurer);
}
return [subType, forkedMeasurer.size];
}).reduce((a, b) => a[1] > b[1] ? a : b)[0];
for (const prop of Object.values(biggestSubType.properties)) {
prop.measure(MaxValue, measurer);
}
} else {
const subTypeKey = value.type;
const subTypeDescription = this.subTypeMap[subTypeKey] || null;
if (subTypeDescription === null) {
throw new Error(
`Unknown sub-type '${subTypeKey.toString()}', expected one of '${JSON.stringify(
Object.keys(this.subTypeMap)
)}'`
);
}
for (const [key, prop] of /* @__PURE__ */ exactEntries(subTypeDescription.properties)) {
prop.measure(value[key], measurer);
}
}
return measurer;
}
};
// @__NO_SIDE_EFFECTS__
function generic(properties, subTypeMap) {
return new GenericObjectSchema(SubTypeKey.STRING, properties, subTypeMap);
}
// @__NO_SIDE_EFFECTS__
function genericEnum(properties, subTypeMap) {
return new GenericObjectSchema(SubTypeKey.ENUM, properties, subTypeMap);
}
// src/structure/concat.ts
// @__NO_SIDE_EFFECTS__
function concat(objs) {
return new ObjectSchema(
Object.fromEntries(
objs.flatMap(({ properties }) => Object.entries(properties))
)
);
}
// src/structure/dynamicArray.ts
var DynamicArraySchema = class extends Schema {
constructor(_unstableElementType) {
super();
this._unstableElementType = _unstableElementType;
__publicField(this, "elementType");
this.elementType = _unstableElementType;
}
resolveReferences(ctx) {
this.elementType = ctx.resolve(this._unstableElementType);
}
write(output, values) {
output.writeUint32(values.length);
for (const value of values) {
this.elementType.write(output, value);
}
}
read(input) {
const array = [];
const len = input.readUint32();
for (let i = 0; i < len; ++i) {
array.push(this.elementType.read(input));
}
return array;
}
/**
* The maximum number of bytes this schema can take up.
*
* Is `NaN` if the schema is unbounded. If you would like to know
* how many bytes a particular value encoding will take up, use `.measure(value)`.
*
* Alias for `.measure(MaxValue).size`
*/
get maxSize() {
return this.measure(MaxValue).size;
}
measure(values, measurer = new Measurer()) {
if (values === MaxValue) {
return measurer.unbounded;
}
measurer.add(4);
for (const value of values) {
this.elementType.measure(value, measurer);
}
return measurer;
}
seekProperty(reference, prop) {
if (typeof prop === "symbol") {
return null;
}
const indexProp = Number.parseInt(String(prop), 10);
if (Number.isNaN(indexProp)) {
return null;
}
if (reference === MaxValue) {
return {
bufferOffset: this.elementType.measure(MaxValue).size * indexProp,
schema: this.elementType
};
}
if (indexProp >= reference.length) {
return null;
}
const measurer = new Measurer();
for (let i = 0; i < indexProp; ++i) {
this.elementType.measure(reference[i], measurer);
}
return {
bufferOffset: measurer.size,
schema: this.elementType
};
}
};
// @__NO_SIDE_EFFECTS__
function dynamicArrayOf(elementSchema) {
return new DynamicArraySchema(elementSchema);
}
// src/structure/keyed.ts
var RefSchema = class {
constructor(key) {
__publicField(this, "__unwrapped");
__publicField(this, "ref");
this.ref = new Ref(key);
}
resolveReferences() {
throw new UnresolvedReferenceError(
"Tried to resolve a reference directly. Do it through a RefResolver instead."
);
}
read() {
throw new UnresolvedReferenceError(
"Tried to read a reference directly. Resolve it instead."
);
}
write() {
throw new UnresolvedReferenceError(
"Tried to write a reference directly. Resolve it instead."
);
}
measure() {
throw new UnresolvedReferenceError(
"Tried to measure size of a reference directly. Resolve it instead."
);
}
seekProperty() {
throw new UnresolvedReferenceError(
"Tried to seek property of a reference directly. Resolve it instead."
);
}
};
var RefResolve = class {
constructor() {
__publicField(this, "registry", {});
}
hasKey(key) {
return this.registry[key] !== void 0;
}
register(key, schema) {
this.registry[key] = schema;
}
resolve(unstableSchema) {
if (unstableSchema instanceof RefSchema) {
const ref = unstableSchema.ref;
const key = ref.key;
if (this.registry[key] !== void 0) {
return this.registry[key];
}
throw new UnresolvedReferenceError(
`Couldn't resolve reference to ${key}. Unknown key.`
);
}
unstableSchema.resolveReferences(this);
return unstableSchema;
}
};
var KeyedSchema = class {
constructor(key, innerResolver) {
this.key = key;
__publicField(this, "__unwrapped");
__publicField(this, "__keyDefinition");
__publicField(this, "innerType");
this.innerType = innerResolver(new RefSchema(key));
this.resolveReferences(new RefResolve());
}
resolveReferences(ctx) {
if (!ctx.hasKey(this.key)) {
ctx.register(this.key, this.innerType);
this.innerType.resolveReferences(ctx);
}
}
read(input) {
return this.innerType.read(input);
}
write(output, value) {
this.innerType.write(output, value);
}
/**
* The maximum number of bytes this schema can take up.
*
* Is `NaN` if the schema is unbounded. If you would like to know
* how many bytes a particular value encoding will take up, use `.measure(value)`.
*
* Alias for `.measure(MaxValue).size`
*/
get maxSize() {
return this.measure(MaxValue).size;
}
measure(value, measurer = new Measurer()) {
return this.innerType.measure(value, measurer);
}
seekProperty(reference, prop) {
return this.innerType.seekProperty(reference, prop);
}
};
// @__NO_SIDE_EFFECTS__
function keyed(key, inner) {
return new KeyedSchema(key, inner);
}
// src/structure/optional.ts
var OptionalSchema = class extends Schema {
constructor(_innerUnstableSchema) {
super();
this._innerUnstableSchema = _innerUnstableSchema;
__publicField(this, "innerSchema");
this.innerSchema = _innerUnstableSchema;
}
resolveReferences(ctx) {
this.innerSchema = ctx.resolve(this._innerUnstableSchema);
}
write(output, value) {
if (value !== void 0 && value !== null) {
output.writeBool(true);
this.innerSchema.write(output, value);
} else {
output.writeBool(false);
}
}
read(input) {
const valueExists = input.readBool();
if (valueExists) {
return this.innerSchema.read(input);
}
return void 0;
}
/**
* The maximum number of bytes this schema can take up.
*
* Is `NaN` if the schema is unbounded. If you would like to know
* how many bytes a particular value encoding will take up, use `.measure(value)`.
*
* Alias for `.measure(MaxValue).size`
*/
get maxSize() {
return this.measure(MaxValue).size;
}
measure(value, measurer = new Measurer()) {
if (value !== void 0) {
this.innerSchema.measure(value, measurer);
}
return measurer.add(1);
}
};
// @__NO_SIDE_EFFECTS__
function optional(innerType) {
return new OptionalSchema(innerType);
}
// src/structure/tuple.ts
// @__NO_SIDE_EFFECTS__
function resolveArray(ctx, refs) {
return refs.map((ref) => ctx.resolve(ref));
}
var TupleSchema = class extends Schema {
constructor(_unstableSchemas) {
super();
this._unstableSchemas = _unstableSchemas;
__publicField(this, "schemas");
this.schemas = _unstableSchemas;
}
resolveReferences(ctx) {
this.schemas = /* @__PURE__ */ resolveArray(ctx, this._unstableSchemas);
}
write(output, values) {
if (values.length !== this.schemas.length) {
throw new ValidationError(
`Expected tuple of length ${this.schemas.length}, got ${values.length}`
);
}
for (let i = 0; i < this.schemas.length; ++i) {
this.schemas[i].write(output, values[i]);
}
}
read(input) {
const array = [];
for (let i = 0; i < this.schemas.length; ++i) {
array.push(
this.schemas[i].read(input)
);
}
return array;
}
/**
* The maximum number of bytes this schema can take up.
*
* Is `NaN` if the schema is unbounded. If you would like to know
* how many bytes a particular value encoding will take up, use `.measure(value)`.
*
* Alias for `.measure(MaxValue).size`
*/
get maxSize() {
return this.measure(MaxValue).size;
}
measure(values, measurer = new Measurer()) {
for (let i = 0; i < this.schemas.length; ++i) {
this.schemas[i].measure(
values === MaxValue ? MaxValue : values[i],
measurer
);
}
return measurer;
}
};
// @__NO_SIDE_EFFECTS__
function tupleOf(schemas) {
return new TupleSchema(schemas);
}
// src/structure/typedArray.ts
var TypedArraySchema = class extends Schema {
constructor(length, _arrayConstructor) {
super();
this.length = length;
this._arrayConstructor = _arrayConstructor;
__publicField(this, "byteLength");
this.byteLength = length * _arrayConstructor.BYTES_PER_ELEMENT;
}
write(output, value) {
output.writeSlice(value);
}
read(input) {
const buffer = new ArrayBuffer(this.byteLength);
const view = new this._arrayConstructor(buffer, 0, this.length);
input.readSlice(view, 0, this.byteLength);
return view;
}
measure(_value, measurer = new Measurer()) {
return measurer.add(this.byteLength);
}
};
var u8Array = /* @__NO_SIDE_EFFECTS__ */ (length) => new TypedArraySchema(length, Uint8Array);
var u8ClampedArray = /* @__NO_SIDE_EFFECTS__ */ (length) => new TypedArraySchema(length, Uint8ClampedArray);
var u16Array = /* @__NO_SIDE_EFFECTS__ */ (length) => new TypedArraySchema(length, Uint16Array);
var u32Array = /* @__NO_SIDE_EFFECTS__ */ (length) => new TypedArraySchema(length, Uint32Array);
var i8Array = /* @__NO_SIDE_EFFECTS__ */ (length) => new TypedArraySchema(length, Int8Array);
var i16Array = /* @__NO_SIDE_EFFECTS__ */ (length) => new TypedArraySchema(length, Int16Array);
var i32Array = /* @__NO_SIDE_EFFECTS__ */ (length) => new TypedArraySchema(length, Int32Array);
var f32Array = /* @__NO_SIDE_EFFECTS__ */ (length) => new TypedArraySchema(length, Float32Array);
var f64Array = /* @__NO_SIDE_EFFECTS__ */ (length) => new TypedArraySchema(length, Float64Array);
// src/util.ts
// @__NO_SIDE_EFFECTS__
function isSystemBigEndian() {
const array = new Uint8Array(4);
const view = new Uint32Array(array.buffer);
view[0] = 1;
return array[0] === 0;
}
// @__NO_SIDE_EFFECTS__
function getSystemEndianness() {
return /* @__PURE__ */ isSystemBigEndian() ? "big" : "little";
}
// src/io/unwrapBuffer.ts
// @__NO_SIDE_EFFECTS__
function unwrapBuffer(buffer) {
let byteOffset = 0;
let innerBuffer = buffer;
if (!!innerBuffer && "buffer" in innerBuffer && "byteOffset" in innerBuffer) {
byteOffset += innerBuffer.byteOffset;
innerBuffer = innerBuffer.buffer;
}
return { buffer: innerBuffer, byteOffset, byteLength: buffer.byteLength };
}
// src/io/bufferIOBase.ts
var BufferIOBase = class {
constructor(buffer, options) {
__publicField(this, "dataView");
__publicField(this, "littleEndian");
__publicField(this, "byteOffset", 0);
__publicField(this, "endianness");
const { byteOffset = 0, endianness = "system" } = options != null ? options : {};
this.byteOffset = byteOffset;
const systemEndianness = getSystemEndianness();
this.endianness = endianness === "system" ? systemEndianness : endianness;
this.littleEndian = this.endianness === "little";
const unwrapped = unwrapBuffer(buffer);
this.byteOffset += unwrapped.byteOffset;
this.dataView = new DataView(unwrapped.buffer);
}
get currentByteOffset() {
return this.byteOffset;
}
seekTo(offset) {
this.byteOffset = offset;
}
skipBytes(bytes) {
this.byteOffset += bytes;
}
};
// src/io/float16converter.ts
function numberToFloat16(value) {
if (value === 0) return 0;
if (Number.isNaN(value)) return 32256;
if (!Number.isFinite(value)) return value > 0 ? 31744 : 64512;
const sign = value < 0 ? 1 : 0;
const absValue = Math.abs(value);
const exponent = Math.floor(Math.log2(absValue));
const mantissa = absValue / 2 ** exponent - 1;
const biasedExponent = exponent + 15;
const mantissaBits = Math.floor(mantissa * 1024);
return sign << 15 | biasedExponent << 10 | mantissaBits;
}
function float16ToNumber(uint16Encoding) {
const sign = (uint16Encoding & 32768) >> 15;
const exponent = (uint16Encoding & 31744) >> 10;
const mantissa = uint16Encoding & 1023;
if (exponent === 0) {
return sign === 0 ? mantissa / 1024 : -mantissa / 1024;
}
if (exponent === 31) {
return mantissa === 0 ? sign === 0 ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY : Number.NaN;
}
return (sign === 0 ? 1 : -1) * (1 + mantissa / 1024) * 2 ** (exponent - 15);
}
// src/io/bufferReader.ts
var BufferReader = class extends BufferIOBase {
constructor() {
super(...arguments);
__publicField(this, "_cachedTextDecoder");
}
get _textDecoder() {
if (!this._cachedTextDecoder) {
this._cachedTextDecoder = new TextDecoder(void 0, { fatal: true });
}
return this._cachedTextDecoder;
}
readBool() {
return this.dataView.getUint8(this.byteOffset++) !== 0;
}
readByte() {
return this.dataView.getUint8(this.byteOffset++);
}
readInt8() {
return this.dataView.getInt8(this.byteOffset++);
}
readUint8() {
return this.dataView.getUint8(this.byteOffset++);
}
readInt16() {
const value = this.dataView.getInt16(this.byteOffset, this.littleEndian);
this.byteOffset += 2;
return value;
}
readUint16() {
const value = this.dataView.getUint16(this.byteOffset, this.littleEndian);
this.byteOffset += 2;
return value;
}
readInt32() {
const value = this.dataView.getInt32(this.byteOffset, this.littleEndian);
this.byteOffset += 4;
return value;
}
readUint32() {
const value = this.dataView.getUint32(this.byteOffset, this.littleEndian);
this.byteOffset += 4;
return value;
}
readFloat16() {
const value = this.dataView.getUint16(this.byteOffset, this.littleEndian);
this.byteOffset += 2;
return float16ToNumber(value);
}
readFloat32() {
const value = this.dataView.getFloat32(this.byteOffset, this.littleEndian);
this.byteOffset += 4;
return value;
}
readString() {
let strLength = 0;
while (this.byteOffset + strLength < this.dataView.byteLength) {
if (this.dataView.getUint8(this.byteOffset + strLength++) === 0) {
break;
}
}
const result = this._textDecoder.decode(
new Uint8Array(this.dataView.buffer, this.byteOffset, strLength - 1)
);
this.byteOffset += strLength;
return result;
}
readSlice(bufferView, offset, byteLength) {
const unwrapped = unwrapBuffer(bufferView);
const destU8 = new Uint8Array(
unwrapped.buffer,
unwrapped.byteOffset + offset
);
for (let i = 0; i < byteLength; ++i) {
destU8[i] = this.dataView.getUint8(this.byteOffset++);
}
}
};
// src/io/bufferWriter.ts
var BufferWriter = class extends BufferIOBase {
constructor() {
super(...arguments);
__publicField(this, "_cachedTextEncoder");
}
get _textEncoder() {
if (!this._cachedTextEncoder) {
this._cachedTextEncoder = new TextEncoder();
}
return this._cachedTextEncoder;
}
writeBool(value) {
this.dataView.setUint8(this.byteOffset++, value ? 1 : 0);
}
writeByte(value) {
this.dataView.setUint8(this.byteOffset++, value);
}
writeInt8(value) {
this.dataView.setInt8(this.byteOffset++, value);
}
writeUint8(value) {
this.dataView.setUint8(this.byteOffset++, value);
}
writeInt16(value) {
this.dataView.setInt16(this.byteOffset, value, this.littleEndian);
this.byteOffset += 2;
}
writeUint16(value) {
this.dataView.setUint16(this.byteOffset, value, this.littleEndian);
this.byteOffset += 2;
}
writeInt32(value) {
this.dataView.setInt32(this.byteOffset, value, this.littleEndian);
this.byteOffset += 4;
}
writeUint32(value) {
this.dataView.setUint32(this.byteOffset, value, this.littleEndian);
this.byteOffset += 4;
}
writeFloat16(value) {
this.dataView.setUint16(
this.byteOffset,
numberToFloat16(value),
this.littleEndian
);
this.byteOffset += 2;
}
writeFloat32(value) {
this.dataView.setFloat32(this.byteOffset, value, this.littleEndian);
this.byteOffset += 4;
}
writeString(value) {
const result = this._textEncoder.encodeInto(
value,
new Uint8Array(this.dataView.buffer, this.byteOffset)
);
this.byteOffset += result.written;
this.dataView.setUint8(this.byteOffset++, 0);
}
writeSlice(bufferView) {
const unwrapped = unwrapBuffer(bufferView);
const srcU8 = new Uint8Array(
unwrapped.buffer,
unwrapped.byteOffset,
unwrapped.byteLength
);
for (const srcByte of srcU8) {
this.dataView.setUint8(this.byteOffset++, srcByte);
}
}
};
// src/index.ts
var src_default = main_api_exports;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
ArraySchema,
BoolSchema,
BufferReader,
BufferWriter,
ByteSchema,
CharsSchema,
DynamicArraySchema,
Float16Schema,
Float32Schema,
GenericObjectSchema,
Int16Schema,
Int32Schema,
Int8Schema,
KeyedSchema,
MaxValue,
Measurer,
ObjectSchema,
OptionalSchema,
Schema,
StringSchema,
SubTypeKey,
TupleSchema,
TypedArraySchema,
Uint16Schema,
Uint32Schema,
Uint8Schema,
UnresolvedReferenceError,
ValidationError,
arrayOf,
bin,
bool,
byte,
chars,
concat,
dynamicArrayOf,
f16,
f32,
f32Array,
f64Array,
generic,
genericEnum,
getSystemEndianness,
i16,
i16Array,
i32,
i32Array,
i8,
i8Array,
keyed,
object,
optional,
string,
tupleOf,
u16,
u16Array,
u32,
u32Array,
u8,
u8Array,
u8ClampedArray
});
//# sourceMappingURL=index.cjs.map