From e549efcc37d13bf1f3be8400ad2bcd86e57265f3 Mon Sep 17 00:00:00 2001 From: Iwo Plaza Date: Wed, 18 Dec 2024 13:02:54 +0100 Subject: [PATCH] fix: Importing with .ts extensions (#42) --- apps/examples/customSchema/radians.ts | 4 +- packages/typed-binary/src/describe/index.ts | 141 ------------------ packages/typed-binary/src/index.ts | 48 +++++- packages/typed-binary/src/io/bufferIOBase.ts | 6 +- packages/typed-binary/src/io/bufferReader.ts | 8 +- .../src/io/bufferReaderWriter.test.ts | 18 ++- packages/typed-binary/src/io/bufferWriter.ts | 8 +- packages/typed-binary/src/io/index.ts | 4 - packages/typed-binary/src/io/measurer.ts | 2 +- .../typed-binary/src/io/unwrapBuffer.test.ts | 2 +- packages/typed-binary/src/main-api.ts | 53 ++++++- .../typed-binary/src/structure/_internal.ts | 10 -- packages/typed-binary/src/structure/array.ts | 32 ++-- .../typed-binary/src/structure/baseTypes.ts | 41 ++++- packages/typed-binary/src/structure/chars.ts | 18 +-- packages/typed-binary/src/structure/concat.ts | 17 +++ .../src/structure/dynamicArray.ts | 31 ++-- packages/typed-binary/src/structure/index.ts | 36 ----- packages/typed-binary/src/structure/keyed.ts | 21 +-- packages/typed-binary/src/structure/object.ts | 56 ++++--- .../typed-binary/src/structure/optional.ts | 24 +-- packages/typed-binary/src/structure/tuple.ts | 29 ++-- .../typed-binary/src/structure/typedArray.ts | 39 ++++- packages/typed-binary/src/structure/types.ts | 4 +- packages/typed-binary/src/test/bool.test.ts | 6 +- packages/typed-binary/src/test/chars.test.ts | 8 +- .../src/test/dynamicArray.test.ts | 17 ++- packages/typed-binary/src/test/float.test.ts | 8 +- .../typed-binary/src/test/helpers/mock.ts | 12 +- packages/typed-binary/src/test/int.test.ts | 8 +- packages/typed-binary/src/test/keyed.test.ts | 130 ++++++++-------- packages/typed-binary/src/test/object.test.ts | 99 ++++++------ .../typed-binary/src/test/optional.test.ts | 15 +- packages/typed-binary/src/test/parsed.test.ts | 116 +++++++------- .../src/test/socket-io-usage.test.ts | 21 ++- packages/typed-binary/src/test/string.test.ts | 17 ++- packages/typed-binary/src/test/tuple.test.ts | 19 +-- .../typed-binary/src/test/typedArray.test.ts | 37 ++--- packages/typed-binary/src/test/unwrap.test.ts | 6 +- .../typed-binary/src/utilityTypes.test.ts | 2 +- packages/typed-binary/src/utilityTypes.ts | 2 +- tsconfig.base.json | 1 + 42 files changed, 580 insertions(+), 596 deletions(-) delete mode 100644 packages/typed-binary/src/describe/index.ts delete mode 100644 packages/typed-binary/src/io/index.ts delete mode 100644 packages/typed-binary/src/structure/_internal.ts create mode 100644 packages/typed-binary/src/structure/concat.ts delete mode 100644 packages/typed-binary/src/structure/index.ts diff --git a/apps/examples/customSchema/radians.ts b/apps/examples/customSchema/radians.ts index c1f5c20..a57402f 100644 --- a/apps/examples/customSchema/radians.ts +++ b/apps/examples/customSchema/radians.ts @@ -28,8 +28,8 @@ class RadiansSchema extends Schema { const low = discrete & 0xff; const high = (discrete >> 8) & 0xff; - output.writeByte(low); - output.writeByte(high); + output.writeUint8(low); + output.writeUint8(high); } measure( diff --git a/packages/typed-binary/src/describe/index.ts b/packages/typed-binary/src/describe/index.ts deleted file mode 100644 index f134b7d..0000000 --- a/packages/typed-binary/src/describe/index.ts +++ /dev/null @@ -1,141 +0,0 @@ -import { - type AnyObjectSchema, - ArraySchema, - BoolSchema, - CharsSchema, - DynamicArraySchema, - Float16Schema, - Float32Schema, - GenericObjectSchema, - Int32Schema, - KeyedSchema, - ObjectSchema, - OptionalSchema, - StringSchema, - SubTypeKey, - TupleSchema, - TypedArraySchema, - Uint32Schema, -} from '../structure'; -import { - Int8Schema, - Int16Schema, - Uint8Schema, - Uint16Schema, -} from '../structure/baseTypes'; -import type { - AnySchema, - AnySchemaWithProperties, - ISchema, - PropertiesOf, - Ref, -} from '../structure/types'; -import type { MergeRecordUnion } from '../utilityTypes'; - -export const bool = new BoolSchema(); - -export const string = new StringSchema(); - -export const i8 = new Int8Schema(); -export const u8 = new Uint8Schema(); - -export const i16 = new Int16Schema(); -export const u16 = new Uint16Schema(); - -export const i32 = new Int32Schema(); -export const u32 = new Uint32Schema(); - -export const f16 = new Float16Schema(); -export const f32 = new Float32Schema(); - -/** - * Alias for `bin.u8` - */ -export const byte = u8; - -export const chars = (length: T) => new CharsSchema(length); - -export const object =

>(properties: P) => - new ObjectSchema(properties); - -export const generic = < - P extends Record, - S extends { - [Key in keyof S]: AnySchemaWithProperties; - }, ->( - properties: P, - subTypeMap: S, -) => new GenericObjectSchema(SubTypeKey.STRING, properties, subTypeMap); - -export const genericEnum = < - P extends Record, - S extends { - [Key in keyof S]: AnySchemaWithProperties; - }, ->( - properties: P, - subTypeMap: S, -) => new GenericObjectSchema(SubTypeKey.ENUM, properties, subTypeMap); - -export const dynamicArrayOf = ( - elementSchema: TSchema, -) => new DynamicArraySchema(elementSchema); - -export const arrayOf = ( - elementSchema: TSchema, - length: number, -) => new ArraySchema(elementSchema, length); - -export const tupleOf = ( - schemas: TSchema, -) => new TupleSchema(schemas); - -export const u8Array = (length: number) => - new TypedArraySchema(length, Uint8Array); - -export const u8ClampedArray = (length: number) => - new TypedArraySchema(length, Uint8ClampedArray); - -export const u16Array = (length: number) => - new TypedArraySchema(length, Uint16Array); - -export const u32Array = (length: number) => - new TypedArraySchema(length, Uint32Array); - -export const i8Array = (length: number) => - new TypedArraySchema(length, Int8Array); - -export const i16Array = (length: number) => - new TypedArraySchema(length, Int16Array); - -export const i32Array = (length: number) => - new TypedArraySchema(length, Int32Array); - -export const f32Array = (length: number) => - new TypedArraySchema(length, Float32Array); - -export const f64Array = (length: number) => - new TypedArraySchema(length, Float64Array); - -export const optional = (innerType: TSchema) => - new OptionalSchema(innerType); - -export const keyed = >( - key: K, - inner: (ref: ISchema>) => P, -) => new KeyedSchema(key, inner); - -type Concat = ObjectSchema< - MergeRecordUnion> ->; - -export const concat = ( - objs: Objs, -): Concat => { - return new ObjectSchema( - Object.fromEntries( - objs.flatMap(({ properties }) => Object.entries(properties)), - ) as unknown as Concat['properties'], - ); -}; diff --git a/packages/typed-binary/src/index.ts b/packages/typed-binary/src/index.ts index 4f2477a..2a44240 100644 --- a/packages/typed-binary/src/index.ts +++ b/packages/typed-binary/src/index.ts @@ -1,8 +1,46 @@ -import * as bin from './main-api'; -export * from './main-api'; +import * as bin from './main-api.ts'; +export * from './main-api.ts'; export { bin }; export default bin; -export * from './structure'; -export { getSystemEndianness } from './util'; -export type { ParseUnwrapped } from './utilityTypes'; +export { getSystemEndianness } from './util.ts'; +export { MaxValue, SubTypeKey } from './structure/types.ts'; +export { + BoolSchema, + Float16Schema, + Float32Schema, + Int16Schema, + Int32Schema, + Int8Schema, + StringSchema, + Uint16Schema, + Uint32Schema, + Uint8Schema, + /** @deprecated Use Uint8Schema instead. */ + Uint8Schema as ByteSchema, +} from './structure/baseTypes.ts'; +export { ArraySchema } from './structure/array.ts'; +export { CharsSchema } from './structure/chars.ts'; +export { DynamicArraySchema } from './structure/dynamicArray.ts'; +export { KeyedSchema } from './structure/keyed.ts'; +export { ObjectSchema, GenericObjectSchema } from './structure/object.ts'; +export { OptionalSchema } from './structure/optional.ts'; +export { TupleSchema } from './structure/tuple.ts'; +export { TypedArraySchema } from './structure/typedArray.ts'; + +export type { AnyObjectSchema } from './structure/object.ts'; +export type { + Unwrap, + UnwrapRecord, + UnwrapArray, + IKeyedSchema, + Ref, + IRefResolver, + Schema, + ISchema, + AnyKeyedSchema, + AnySchema, + AnySchemaWithProperties, + ISchemaWithProperties, +} from './structure/types.ts'; +export type { ParseUnwrapped } from './utilityTypes.ts'; diff --git a/packages/typed-binary/src/io/bufferIOBase.ts b/packages/typed-binary/src/io/bufferIOBase.ts index 02d5fab..2f27b6d 100644 --- a/packages/typed-binary/src/io/bufferIOBase.ts +++ b/packages/typed-binary/src/io/bufferIOBase.ts @@ -1,6 +1,6 @@ -import { getSystemEndianness } from '../util'; -import type { Endianness } from './types'; -import { unwrapBuffer } from './unwrapBuffer'; +import { getSystemEndianness } from '../util.ts'; +import type { Endianness } from './types.ts'; +import { unwrapBuffer } from './unwrapBuffer.ts'; export type BufferIOOptions = { /** diff --git a/packages/typed-binary/src/io/bufferReader.ts b/packages/typed-binary/src/io/bufferReader.ts index 870056d..7ca8494 100644 --- a/packages/typed-binary/src/io/bufferReader.ts +++ b/packages/typed-binary/src/io/bufferReader.ts @@ -1,7 +1,7 @@ -import { BufferIOBase } from './bufferIOBase'; -import { float16ToNumber } from './float16converter'; -import type { ISerialInput } from './types'; -import { unwrapBuffer } from './unwrapBuffer'; +import { BufferIOBase } from './bufferIOBase.ts'; +import { float16ToNumber } from './float16converter.ts'; +import type { ISerialInput } from './types.ts'; +import { unwrapBuffer } from './unwrapBuffer.ts'; export class BufferReader extends BufferIOBase implements ISerialInput { private _cachedTextDecoder: TextDecoder | undefined; diff --git a/packages/typed-binary/src/io/bufferReaderWriter.test.ts b/packages/typed-binary/src/io/bufferReaderWriter.test.ts index cb5f24c..9d5acd1 100644 --- a/packages/typed-binary/src/io/bufferReaderWriter.test.ts +++ b/packages/typed-binary/src/io/bufferReaderWriter.test.ts @@ -1,8 +1,10 @@ +import { Buffer } from 'node:buffer'; + import { describe, expect, it } from 'vitest'; -import { randBetween, randIntBetween } from '../test/random'; -import { getSystemEndianness } from '../util'; -import { BufferReader } from './bufferReader'; -import { BufferWriter } from './bufferWriter'; +import { randBetween, randIntBetween } from '../test/random.ts'; +import { getSystemEndianness } from '../util.ts'; +import { BufferReader } from './bufferReader.ts'; +import { BufferWriter } from './bufferWriter.ts'; describe('BufferWriter', () => { it('should encode a Uint8Array', () => { @@ -97,10 +99,10 @@ describe('BufferReader', () => { it('should decode a Uint8Array', () => { const buffer = Buffer.alloc(4); const writer = new BufferWriter(buffer); - writer.writeByte(0); - writer.writeByte(15); - writer.writeByte(64); - writer.writeByte(255); + writer.writeUint8(0); + writer.writeUint8(15); + writer.writeUint8(64); + writer.writeUint8(255); const destBuffer = new ArrayBuffer(4); const destU8 = new Uint8Array(destBuffer); diff --git a/packages/typed-binary/src/io/bufferWriter.ts b/packages/typed-binary/src/io/bufferWriter.ts index 7ee19b3..acffa97 100644 --- a/packages/typed-binary/src/io/bufferWriter.ts +++ b/packages/typed-binary/src/io/bufferWriter.ts @@ -1,7 +1,7 @@ -import { BufferIOBase } from './bufferIOBase'; -import { numberToFloat16 } from './float16converter'; -import type { ISerialOutput } from './types'; -import { unwrapBuffer } from './unwrapBuffer'; +import { BufferIOBase } from './bufferIOBase.ts'; +import { numberToFloat16 } from './float16converter.ts'; +import type { ISerialOutput } from './types.ts'; +import { unwrapBuffer } from './unwrapBuffer.ts'; export class BufferWriter extends BufferIOBase implements ISerialOutput { private _cachedTextEncoder: TextEncoder | undefined; diff --git a/packages/typed-binary/src/io/index.ts b/packages/typed-binary/src/io/index.ts deleted file mode 100644 index 87c9bb1..0000000 --- a/packages/typed-binary/src/io/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { Endianness, ISerialInput, ISerialOutput, IMeasurer } from './types'; -export { BufferWriter } from './bufferWriter'; -export { BufferReader } from './bufferReader'; -export { Measurer } from './measurer'; diff --git a/packages/typed-binary/src/io/measurer.ts b/packages/typed-binary/src/io/measurer.ts index 4ef3f1f..38b1396 100644 --- a/packages/typed-binary/src/io/measurer.ts +++ b/packages/typed-binary/src/io/measurer.ts @@ -1,4 +1,4 @@ -import type { IMeasurer } from './types'; +import type { IMeasurer } from './types.ts'; class UnboundedMeasurer implements IMeasurer { size = Number.NaN; diff --git a/packages/typed-binary/src/io/unwrapBuffer.test.ts b/packages/typed-binary/src/io/unwrapBuffer.test.ts index 08df521..9a33f8e 100644 --- a/packages/typed-binary/src/io/unwrapBuffer.test.ts +++ b/packages/typed-binary/src/io/unwrapBuffer.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { unwrapBuffer } from './unwrapBuffer'; +import { unwrapBuffer } from './unwrapBuffer.ts'; describe('unwrapBuffer', () => { it('returns the input if given an array buffer', () => { diff --git a/packages/typed-binary/src/main-api.ts b/packages/typed-binary/src/main-api.ts index 169c045..176e351 100644 --- a/packages/typed-binary/src/main-api.ts +++ b/packages/typed-binary/src/main-api.ts @@ -1,6 +1,49 @@ -export { MaxValue } from './structure'; -export * from './describe'; -export * from './io'; -export * from './error'; +export { arrayOf } from './structure/array.ts'; +export { + bool, + byte, + i8, + u8, + i16, + u16, + i32, + u32, + f16, + f32, + string, +} from './structure/baseTypes.ts'; +export { chars } from './structure/chars.ts'; +export { concat } from './structure/concat.ts'; +export { dynamicArrayOf } from './structure/dynamicArray.ts'; +export { keyed } from './structure/keyed.ts'; +export { object, generic, genericEnum } from './structure/object.ts'; +export { optional } from './structure/optional.ts'; +export { tupleOf } from './structure/tuple.ts'; +export { + f32Array, + f64Array, + i16Array, + i32Array, + i8Array, + u16Array, + u32Array, + u8Array, + u8ClampedArray, +} from './structure/typedArray.ts'; +export { MaxValue } from './structure/types.ts'; -export type { Parsed } from './utilityTypes'; +export { BufferReader } from './io/bufferReader.ts'; +export { BufferWriter } from './io/bufferWriter.ts'; +export { Measurer } from './io/measurer.ts'; +export { + UnresolvedReferenceError, + ValidationError, +} from './error.ts'; + +export type { + Endianness, + IMeasurer, + ISerialInput, + ISerialOutput, +} from './io/types.ts'; +export type { Parsed } from './utilityTypes.ts'; diff --git a/packages/typed-binary/src/structure/_internal.ts b/packages/typed-binary/src/structure/_internal.ts deleted file mode 100644 index d8de6f4..0000000 --- a/packages/typed-binary/src/structure/_internal.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './array'; -export * from './baseTypes'; -export * from './chars'; -export * from './dynamicArray'; -export * from './keyed'; -export * from './object'; -export * from './optional'; -export * from './tuple'; -export * from './typedArray'; -export * from './types'; diff --git a/packages/typed-binary/src/structure/array.ts b/packages/typed-binary/src/structure/array.ts index 1bc9702..3f9b95a 100644 --- a/packages/typed-binary/src/structure/array.ts +++ b/packages/typed-binary/src/structure/array.ts @@ -1,18 +1,14 @@ -import { ValidationError } from '../error'; -import { - type IMeasurer, - type ISerialInput, - type ISerialOutput, - Measurer, -} from '../io'; -import type { ParseUnwrapped } from '../utilityTypes'; +import { ValidationError } from '../error.ts'; +import { Measurer } from '../io/measurer.ts'; +import type { IMeasurer, ISerialInput, ISerialOutput } from '../io/types.ts'; +import type { ParseUnwrapped } from '../utilityTypes.ts'; import { type AnySchema, type IRefResolver, MaxValue, Schema, type Unwrap, -} from './types'; +} from './types.ts'; export class ArraySchema extends Schema< Unwrap[] @@ -30,11 +26,14 @@ export class ArraySchema extends Schema< this.elementSchema = _unstableElementSchema; } - resolveReferences(ctx: IRefResolver): void { + override resolveReferences(ctx: IRefResolver): void { this.elementSchema = ctx.resolve(this._unstableElementSchema); } - write(output: ISerialOutput, values: ParseUnwrapped[]): void { + override write( + output: ISerialOutput, + values: ParseUnwrapped[], + ): void { if (values.length !== this.length) { throw new ValidationError( `Expected array of length ${this.length}, got ${values.length}`, @@ -46,7 +45,7 @@ export class ArraySchema extends Schema< } } - read(input: ISerialInput): ParseUnwrapped[] { + override read(input: ISerialInput): ParseUnwrapped[] { const array: ParseUnwrapped[] = []; for (let i = 0; i < this.length; ++i) { @@ -68,7 +67,7 @@ export class ArraySchema extends Schema< return this.elementSchema.measure(MaxValue).size * this.length; } - measure( + override measure( values: ParseUnwrapped[] | MaxValue, measurer: IMeasurer = new Measurer(), ): IMeasurer { @@ -82,3 +81,10 @@ export class ArraySchema extends Schema< return measurer; } } + +export function arrayOf( + elementSchema: TSchema, + length: number, +) { + return new ArraySchema(elementSchema, length); +} diff --git a/packages/typed-binary/src/structure/baseTypes.ts b/packages/typed-binary/src/structure/baseTypes.ts index 802785a..2a4ef20 100644 --- a/packages/typed-binary/src/structure/baseTypes.ts +++ b/packages/typed-binary/src/structure/baseTypes.ts @@ -1,10 +1,6 @@ -import { - type IMeasurer, - type ISerialInput, - type ISerialOutput, - Measurer, -} from '../io'; -import { MaxValue, Schema } from './types'; +import { Measurer } from '../io/measurer.ts'; +import type { IMeasurer, ISerialInput, ISerialOutput } from '../io/types.ts'; +import { MaxValue, Schema } from './types.ts'; //// // BOOL @@ -34,6 +30,8 @@ export class BoolSchema extends Schema { } } +export const bool = new BoolSchema(); + //// // STRING //// @@ -69,6 +67,8 @@ export class StringSchema extends Schema { } } +export const string = new StringSchema(); + //// // i8 //// @@ -97,6 +97,8 @@ export class Int8Schema extends Schema { } } +export const i8 = new Int8Schema(); + //// // u8 //// @@ -125,6 +127,13 @@ export class Uint8Schema extends Schema { } } +export const u8 = new Uint8Schema(); + +/** + * Alias for `bin.u8` + */ +export const byte = u8; + //// // i16 //// @@ -153,6 +162,8 @@ export class Int16Schema extends Schema { } } +export const i16 = new Int16Schema(); + //// // u16 //// @@ -181,6 +192,8 @@ export class Uint16Schema extends Schema { } } +export const u16 = new Uint16Schema(); + //// // i32 //// @@ -209,6 +222,8 @@ export class Int32Schema extends Schema { } } +export const i32 = new Int32Schema(); + //// // u32 //// @@ -237,8 +252,10 @@ export class Uint32Schema extends Schema { } } +export const u32 = new Uint32Schema(); + //// -// FLOAT +// f16 //// export class Float16Schema extends Schema { @@ -265,6 +282,12 @@ export class Float16Schema extends Schema { } } +export const f16 = new Float16Schema(); + +//// +// f32 +//// + export class Float32Schema extends Schema { /** * The maximum number of bytes this schema can take up. @@ -288,3 +311,5 @@ export class Float32Schema extends Schema { return measurer.add(4); } } + +export const f32 = new Float32Schema(); diff --git a/packages/typed-binary/src/structure/chars.ts b/packages/typed-binary/src/structure/chars.ts index e41d82a..977bd6f 100644 --- a/packages/typed-binary/src/structure/chars.ts +++ b/packages/typed-binary/src/structure/chars.ts @@ -1,11 +1,7 @@ -import { ValidationError } from '../error'; -import { - type IMeasurer, - type ISerialInput, - type ISerialOutput, - Measurer, -} from '../io'; -import { Schema } from './types'; +import { ValidationError } from '../error.ts'; +import { Measurer } from '../io/measurer.ts'; +import type { IMeasurer, ISerialInput, ISerialOutput } from '../io/types.ts'; +import { Schema } from './types.ts'; export class CharsSchema extends Schema { constructor(public readonly length: number) { @@ -20,7 +16,7 @@ export class CharsSchema extends Schema { } for (let i = 0; i < value.length; ++i) { - output.writeByte(value.charCodeAt(i)); + output.writeUint8(value.charCodeAt(i)); } } @@ -38,3 +34,7 @@ export class CharsSchema extends Schema { return measurer.add(this.length); } } + +export function chars(length: T) { + return new CharsSchema(length); +} diff --git a/packages/typed-binary/src/structure/concat.ts b/packages/typed-binary/src/structure/concat.ts new file mode 100644 index 0000000..8ffafb0 --- /dev/null +++ b/packages/typed-binary/src/structure/concat.ts @@ -0,0 +1,17 @@ +import type { MergeRecordUnion } from '../utilityTypes.ts'; +import { type AnyObjectSchema, ObjectSchema } from './object.ts'; +import type { PropertiesOf } from './types.ts'; + +type Concat = ObjectSchema< + MergeRecordUnion> +>; + +export function concat( + objs: Objs, +): Concat { + return new ObjectSchema( + Object.fromEntries( + objs.flatMap(({ properties }) => Object.entries(properties)), + ) as unknown as Concat['properties'], + ); +} diff --git a/packages/typed-binary/src/structure/dynamicArray.ts b/packages/typed-binary/src/structure/dynamicArray.ts index 9dc434b..c87c45f 100644 --- a/packages/typed-binary/src/structure/dynamicArray.ts +++ b/packages/typed-binary/src/structure/dynamicArray.ts @@ -1,10 +1,6 @@ -import { - type IMeasurer, - type ISerialInput, - type ISerialOutput, - Measurer, -} from '../io'; -import type { ParseUnwrapped } from '../utilityTypes'; +import { Measurer } from '../io/measurer.ts'; +import type { IMeasurer, ISerialInput, ISerialOutput } from '../io/types.ts'; +import type { ParseUnwrapped } from '../utilityTypes.ts'; import { type AnySchema, type IRefResolver, @@ -12,7 +8,7 @@ import { type PropertyDescription, Schema, type Unwrap, -} from './types'; +} from './types.ts'; export class DynamicArraySchema extends Schema< Unwrap[] @@ -27,11 +23,14 @@ export class DynamicArraySchema extends Schema< this.elementType = _unstableElementType; } - resolveReferences(ctx: IRefResolver): void { + override resolveReferences(ctx: IRefResolver): void { this.elementType = ctx.resolve(this._unstableElementType); } - write(output: ISerialOutput, values: ParseUnwrapped[]): void { + override write( + output: ISerialOutput, + values: ParseUnwrapped[], + ): void { output.writeUint32(values.length); for (const value of values) { @@ -39,7 +38,7 @@ export class DynamicArraySchema extends Schema< } } - read(input: ISerialInput): ParseUnwrapped[] { + override read(input: ISerialInput): ParseUnwrapped[] { const array: ParseUnwrapped[] = []; const len = input.readUint32(); @@ -63,7 +62,7 @@ export class DynamicArraySchema extends Schema< return this.measure(MaxValue).size; } - measure( + override measure( values: ParseUnwrapped[] | typeof MaxValue, measurer: IMeasurer = new Measurer(), ): IMeasurer { @@ -83,7 +82,7 @@ export class DynamicArraySchema extends Schema< return measurer; } - seekProperty( + override seekProperty( reference: ParseUnwrapped[] | MaxValue, prop: number, ): PropertyDescription | null { @@ -119,3 +118,9 @@ export class DynamicArraySchema extends Schema< }; } } + +export function dynamicArrayOf( + elementSchema: TSchema, +) { + return new DynamicArraySchema(elementSchema); +} diff --git a/packages/typed-binary/src/structure/index.ts b/packages/typed-binary/src/structure/index.ts deleted file mode 100644 index b9169b2..0000000 --- a/packages/typed-binary/src/structure/index.ts +++ /dev/null @@ -1,36 +0,0 @@ -export { - MaxValue, - Ref, - IRefResolver, - Schema, - ISchema, - IKeyedSchema, - AnyKeyedSchema, - Unwrap, - UnwrapRecord, - ISchemaWithProperties, - AnySchema, - AnySchemaWithProperties, - // Specific schemas - BoolSchema, - StringSchema, - Int8Schema, - Uint8Schema, - Int16Schema, - Uint16Schema, - Int32Schema, - Uint32Schema, - Float16Schema, - Float32Schema, - ArraySchema, - CharsSchema, - DynamicArraySchema, - KeyedSchema, - ObjectSchema, - AnyObjectSchema, - GenericObjectSchema, - SubTypeKey, - OptionalSchema, - TupleSchema, - TypedArraySchema, -} from './_internal'; diff --git a/packages/typed-binary/src/structure/keyed.ts b/packages/typed-binary/src/structure/keyed.ts index bfd03d8..40ba82c 100644 --- a/packages/typed-binary/src/structure/keyed.ts +++ b/packages/typed-binary/src/structure/keyed.ts @@ -1,11 +1,7 @@ -import { UnresolvedReferenceError } from '../error'; -import { - type IMeasurer, - type ISerialInput, - type ISerialOutput, - Measurer, -} from '../io'; -import type { ParseUnwrapped, Parsed } from '../utilityTypes'; +import { UnresolvedReferenceError } from '../error.ts'; +import { Measurer } from '../io/measurer.ts'; +import type { IMeasurer, ISerialInput, ISerialOutput } from '../io/types.ts'; +import type { ParseUnwrapped, Parsed } from '../utilityTypes.ts'; import { type AnySchema, type IKeyedSchema, @@ -15,7 +11,7 @@ import { type PropertyDescription, Ref, type Unwrap, -} from './types'; +} from './types.ts'; class RefSchema implements ISchema> { public readonly __unwrapped!: Ref; @@ -148,3 +144,10 @@ export class KeyedSchema< return this.innerType.seekProperty(reference, prop as never); } } + +export function keyed>( + key: K, + inner: (ref: ISchema>) => P, +) { + return new KeyedSchema(key, inner); +} diff --git a/packages/typed-binary/src/structure/object.ts b/packages/typed-binary/src/structure/object.ts index 17f0695..bd4c0a3 100644 --- a/packages/typed-binary/src/structure/object.ts +++ b/packages/typed-binary/src/structure/object.ts @@ -1,10 +1,6 @@ -import { - type IMeasurer, - type ISerialInput, - type ISerialOutput, - Measurer, -} from '../io'; -import type { ParseUnwrappedRecord, Parsed } from '../utilityTypes'; +import { Measurer } from '../io/measurer.ts'; +import type { IMeasurer, ISerialInput, ISerialOutput } from '../io/types.ts'; +import type { ParseUnwrappedRecord, Parsed } from '../utilityTypes.ts'; import { type AnySchema, type AnySchemaWithProperties, @@ -17,7 +13,7 @@ import { SubTypeKey, type Unwrap, type UnwrapRecord, -} from './types'; +} from './types.ts'; export function exactEntries>( record: T, @@ -54,11 +50,14 @@ export class ObjectSchema> this.properties = _properties; } - resolveReferences(ctx: IRefResolver): void { + override resolveReferences(ctx: IRefResolver): void { this.properties = resolveMap(ctx, this._properties); } - write(output: ISerialOutput, value: ParseUnwrappedRecord): void { + override write( + output: ISerialOutput, + value: ParseUnwrappedRecord, + ): void { type Property = keyof ParseUnwrappedRecord; for (const [key, property] of exactEntries(this.properties)) { @@ -66,7 +65,7 @@ export class ObjectSchema> } } - read(input: ISerialInput): ParseUnwrappedRecord { + override read(input: ISerialInput): ParseUnwrappedRecord { type Property = keyof ParseUnwrappedRecord; const result = {} as ParseUnwrappedRecord; @@ -98,7 +97,7 @@ export class ObjectSchema> return measurer.size; } - measure( + override measure( value: ParseUnwrappedRecord | typeof MaxValue, measurer: IMeasurer = new Measurer(), ): IMeasurer { @@ -114,7 +113,7 @@ export class ObjectSchema> return measurer; } - seekProperty( + override seekProperty( reference: ParseUnwrappedRecord | MaxValue, prop: keyof UnwrapRecord, ): PropertyDescription | null { @@ -135,6 +134,9 @@ export class ObjectSchema> } } +export const object =

>(properties: P) => + new ObjectSchema(properties); + type UnwrapGeneric, Ext> = { [TKey in keyof Ext]: ISchema< UnwrapRecord & { type: TKey } & UnwrapRecord> @@ -162,12 +164,12 @@ export class GenericObjectSchema< this.subTypeMap = _subTypeMap; } - resolveReferences(ctx: IRefResolver): void { + override resolveReferences(ctx: IRefResolver): void { this._baseObject.resolveReferences(ctx); this.subTypeMap = resolveMap(ctx, this._subTypeMap); } - write( + override write( output: ISerialOutput, value: Parsed>, ): void { @@ -185,7 +187,7 @@ export class GenericObjectSchema< // Writing the sub-type out. if (this.keyedBy === SubTypeKey.ENUM) { - output.writeByte(value.type as number); + output.writeUint8(value.type as number); } else { output.writeString(value.type as string); } @@ -201,7 +203,9 @@ export class GenericObjectSchema< } } - read(input: ISerialInput): Parsed> { + override read( + input: ISerialInput, + ): Parsed> { const subTypeKey = this.keyedBy === SubTypeKey.ENUM ? input.readByte() : input.readString(); @@ -298,3 +302,21 @@ export class GenericObjectSchema< return measurer; } } + +export function generic< + P extends Record, + S extends { + [Key in keyof S]: AnySchemaWithProperties; + }, +>(properties: P, subTypeMap: S) { + return new GenericObjectSchema(SubTypeKey.STRING, properties, subTypeMap); +} + +export function genericEnum< + P extends Record, + S extends { + [Key in keyof S]: AnySchemaWithProperties; + }, +>(properties: P, subTypeMap: S) { + return new GenericObjectSchema(SubTypeKey.ENUM, properties, subTypeMap); +} diff --git a/packages/typed-binary/src/structure/optional.ts b/packages/typed-binary/src/structure/optional.ts index d6e0a21..2d6c315 100644 --- a/packages/typed-binary/src/structure/optional.ts +++ b/packages/typed-binary/src/structure/optional.ts @@ -1,17 +1,13 @@ -import { - type IMeasurer, - type ISerialInput, - type ISerialOutput, - Measurer, -} from '../io'; -import type { ParseUnwrapped } from '../utilityTypes'; +import { Measurer } from '../io/measurer.ts'; +import type { IMeasurer, ISerialInput, ISerialOutput } from '../io/types.ts'; +import type { ParseUnwrapped } from '../utilityTypes.ts'; import { type AnySchema, type IRefResolver, MaxValue, Schema, type Unwrap, -} from './types'; +} from './types.ts'; export class OptionalSchema extends Schema< Unwrap | undefined @@ -26,11 +22,11 @@ export class OptionalSchema extends Schema< this.innerSchema = _innerUnstableSchema; } - resolveReferences(ctx: IRefResolver): void { + override resolveReferences(ctx: IRefResolver): void { this.innerSchema = ctx.resolve(this._innerUnstableSchema); } - write( + override write( output: ISerialOutput, value: ParseUnwrapped | undefined, ): void { @@ -42,7 +38,7 @@ export class OptionalSchema extends Schema< } } - read(input: ISerialInput): ParseUnwrapped | undefined { + override read(input: ISerialInput): ParseUnwrapped | undefined { const valueExists = input.readBool(); if (valueExists) { @@ -64,7 +60,7 @@ export class OptionalSchema extends Schema< return this.measure(MaxValue).size; } - measure( + override measure( value: ParseUnwrapped | MaxValue | undefined, measurer: IMeasurer = new Measurer(), ): IMeasurer { @@ -75,3 +71,7 @@ export class OptionalSchema extends Schema< return measurer.add(1); } } + +export function optional(innerType: TSchema) { + return new OptionalSchema(innerType); +} diff --git a/packages/typed-binary/src/structure/tuple.ts b/packages/typed-binary/src/structure/tuple.ts index ba5d701..bcd8fa4 100644 --- a/packages/typed-binary/src/structure/tuple.ts +++ b/packages/typed-binary/src/structure/tuple.ts @@ -1,18 +1,14 @@ -import { ValidationError } from '../error'; -import { - type IMeasurer, - type ISerialInput, - type ISerialOutput, - Measurer, -} from '../io'; -import type { Parsed } from '../utilityTypes'; +import { ValidationError } from '../error.ts'; +import { Measurer } from '../io/measurer.ts'; +import type { IMeasurer, ISerialInput, ISerialOutput } from '../io/types.ts'; +import type { Parsed } from '../utilityTypes.ts'; import { type AnySchema, type IRefResolver, MaxValue, Schema, type UnwrapArray, -} from './types'; +} from './types.ts'; export function resolveArray( ctx: IRefResolver, @@ -34,11 +30,14 @@ export class TupleSchema< this.schemas = _unstableSchemas; } - resolveReferences(ctx: IRefResolver): void { + override resolveReferences(ctx: IRefResolver): void { this.schemas = resolveArray(ctx, this._unstableSchemas); } - write(output: ISerialOutput, values: Parsed>): void { + override write( + output: ISerialOutput, + values: Parsed>, + ): void { if (values.length !== this.schemas.length) { throw new ValidationError( `Expected tuple of length ${this.schemas.length}, got ${values.length}`, @@ -50,7 +49,7 @@ export class TupleSchema< } } - read(input: ISerialInput): Parsed> { + override read(input: ISerialInput): Parsed> { const array = [] as Parsed>; for (let i = 0; i < this.schemas.length; ++i) { @@ -88,3 +87,9 @@ export class TupleSchema< return measurer; } } + +export function tupleOf( + schemas: TSchema, +) { + return new TupleSchema(schemas); +} diff --git a/packages/typed-binary/src/structure/typedArray.ts b/packages/typed-binary/src/structure/typedArray.ts index 2b47a76..c427a4c 100644 --- a/packages/typed-binary/src/structure/typedArray.ts +++ b/packages/typed-binary/src/structure/typedArray.ts @@ -1,11 +1,7 @@ -import { - type IMeasurer, - type ISerialInput, - type ISerialOutput, - Measurer, -} from '../io'; -import type { Parsed } from '../utilityTypes'; -import { type MaxValue, Schema } from './types'; +import { Measurer } from '../io/measurer.ts'; +import type { IMeasurer, ISerialInput, ISerialOutput } from '../io/types.ts'; +import type { Parsed } from '../utilityTypes.ts'; +import { type MaxValue, Schema } from './types.ts'; type TypedArrayConstructor = { readonly BYTES_PER_ELEMENT: number; @@ -44,3 +40,30 @@ export class TypedArraySchema< return measurer.add(this.byteLength); } } + +export const u8Array = (length: number) => + new TypedArraySchema(length, Uint8Array); + +export const u8ClampedArray = (length: number) => + new TypedArraySchema(length, Uint8ClampedArray); + +export const u16Array = (length: number) => + new TypedArraySchema(length, Uint16Array); + +export const u32Array = (length: number) => + new TypedArraySchema(length, Uint32Array); + +export const i8Array = (length: number) => + new TypedArraySchema(length, Int8Array); + +export const i16Array = (length: number) => + new TypedArraySchema(length, Int16Array); + +export const i32Array = (length: number) => + new TypedArraySchema(length, Int32Array); + +export const f32Array = (length: number) => + new TypedArraySchema(length, Float32Array); + +export const f64Array = (length: number) => + new TypedArraySchema(length, Float64Array); diff --git a/packages/typed-binary/src/structure/types.ts b/packages/typed-binary/src/structure/types.ts index f3a8707..96d4118 100644 --- a/packages/typed-binary/src/structure/types.ts +++ b/packages/typed-binary/src/structure/types.ts @@ -1,5 +1,5 @@ -import type { IMeasurer, ISerialInput, ISerialOutput } from '../io'; -import type { Parsed } from '../utilityTypes'; +import type { IMeasurer, ISerialInput, ISerialOutput } from '../io/types.ts'; +import type { Parsed } from '../utilityTypes.ts'; export type MaxValue = typeof MaxValue; export const MaxValue = Symbol( diff --git a/packages/typed-binary/src/test/bool.test.ts b/packages/typed-binary/src/test/bool.test.ts index e7e48de..046cb05 100644 --- a/packages/typed-binary/src/test/bool.test.ts +++ b/packages/typed-binary/src/test/bool.test.ts @@ -1,7 +1,9 @@ import { describe, expect, it } from 'vitest'; -import { bool } from '../describe'; -import { encodeAndDecode } from './helpers/mock'; +// Importing from the public API +import { bool } from '../index.ts'; +// Helpers +import { encodeAndDecode } from './helpers/mock.ts'; describe('BoolSchema', () => { it('should encode and decode a bool value', () => { diff --git a/packages/typed-binary/src/test/chars.test.ts b/packages/typed-binary/src/test/chars.test.ts index b329016..e24071e 100644 --- a/packages/typed-binary/src/test/chars.test.ts +++ b/packages/typed-binary/src/test/chars.test.ts @@ -1,8 +1,10 @@ import { describe, expect, it } from 'vitest'; -import { CharsSchema } from '../structure'; -import { encodeAndDecode } from './helpers/mock'; -import { randIntBetween } from './random'; +// Importing from the public API +import { CharsSchema } from '../index.ts'; +// Helpers +import { encodeAndDecode } from './helpers/mock.ts'; +import { randIntBetween } from './random.ts'; describe('CharsSchema', () => { it('should encode and decode fixed-size char array', () => { diff --git a/packages/typed-binary/src/test/dynamicArray.test.ts b/packages/typed-binary/src/test/dynamicArray.test.ts index 27741af..58b3a7a 100644 --- a/packages/typed-binary/src/test/dynamicArray.test.ts +++ b/packages/typed-binary/src/test/dynamicArray.test.ts @@ -1,13 +1,14 @@ import { describe, expect, it } from 'vitest'; -import { dynamicArrayOf, i32 } from '../describe'; -import { DynamicArraySchema, MaxValue } from '../structure'; -import { makeIO } from './helpers/mock'; -import { randIntBetween } from './random'; +// Importing from the public API +import bin, { DynamicArraySchema, MaxValue } from '../index.ts'; +// Helpers +import { makeIO } from './helpers/mock.ts'; +import { randIntBetween } from './random.ts'; describe('DynamicArraySchema', () => { it('should estimate an int-array encoding size', () => { - const IntArray = dynamicArrayOf(i32); + const IntArray = bin.dynamicArrayOf(bin.i32); const length = randIntBetween(0, 200); const values = []; @@ -16,12 +17,12 @@ describe('DynamicArraySchema', () => { } expect(IntArray.measure(values).size).to.equal( - i32.measure(MaxValue).size + length * i32.measure(MaxValue).size, + bin.i32.measure(MaxValue).size + length * bin.i32.measure(MaxValue).size, ); }); it('should fail to estimate size of max value', () => { - const IntArray = dynamicArrayOf(i32); + const IntArray = bin.dynamicArrayOf(bin.i32); expect(IntArray.measure(MaxValue).isUnbounded).to.be.true; }); @@ -33,7 +34,7 @@ describe('DynamicArraySchema', () => { value.push(randIntBetween(-10000, 10000)); } - const description = new DynamicArraySchema(i32); + const description = new DynamicArraySchema(bin.i32); const { output, input } = makeIO(length * 4 + 4); // Extra 4 bytes for the length of the array description.write(output, value); diff --git a/packages/typed-binary/src/test/float.test.ts b/packages/typed-binary/src/test/float.test.ts index ad31168..a24e378 100644 --- a/packages/typed-binary/src/test/float.test.ts +++ b/packages/typed-binary/src/test/float.test.ts @@ -1,8 +1,10 @@ import { describe, expect, it } from 'vitest'; -import { f16, f32 } from '../describe'; -import { encodeAndDecode } from './helpers/mock'; -import { randBetween } from './random'; +// Importing from the public API +import { f16, f32 } from '../index.ts'; +// Helpers +import { encodeAndDecode } from './helpers/mock.ts'; +import { randBetween } from './random.ts'; describe('Float32Schema', () => { it('should encode and decode a f32 value', () => { diff --git a/packages/typed-binary/src/test/helpers/mock.ts b/packages/typed-binary/src/test/helpers/mock.ts index e269879..027b34f 100644 --- a/packages/typed-binary/src/test/helpers/mock.ts +++ b/packages/typed-binary/src/test/helpers/mock.ts @@ -1,9 +1,11 @@ -import { BufferReader, BufferWriter } from '../../io'; -import type { AnySchema } from '../../structure/types'; -import type { Parsed } from '../../utilityTypes'; +import { BufferReader } from '../../io/bufferReader.ts'; +import { BufferWriter } from '../../io/bufferWriter.ts'; +import type { AnySchema } from '../../structure/types.ts'; +import type { Parsed } from '../../utilityTypes.ts'; export function makeIO(bufferSize: number) { - const buffer = Buffer.alloc(bufferSize); + const buffer = new ArrayBuffer(bufferSize); + return { output: new BufferWriter(buffer), input: new BufferReader(buffer), @@ -14,7 +16,7 @@ export function encodeAndDecode( schema: T, value: Parsed, ): Parsed { - const buffer = Buffer.alloc(schema.measure(value).size); + const buffer = new ArrayBuffer(schema.measure(value).size); schema.write(new BufferWriter(buffer), value); diff --git a/packages/typed-binary/src/test/int.test.ts b/packages/typed-binary/src/test/int.test.ts index dff04b9..b7048f9 100644 --- a/packages/typed-binary/src/test/int.test.ts +++ b/packages/typed-binary/src/test/int.test.ts @@ -1,8 +1,10 @@ import { describe, expect, it } from 'vitest'; -import { i8, i16, i32, u8, u16, u32 } from '../describe'; -import { encodeAndDecode } from './helpers/mock'; -import { randIntBetween } from './random'; +// Importing from the public API +import { i8, i16, i32, u8, u16, u32 } from '../index.ts'; +// Helpers +import { encodeAndDecode } from './helpers/mock.ts'; +import { randIntBetween } from './random.ts'; describe('Int8Schema', () => { it('should encode and decode a signed int8 value', () => { diff --git a/packages/typed-binary/src/test/keyed.test.ts b/packages/typed-binary/src/test/keyed.test.ts index e1bbba5..119579e 100644 --- a/packages/typed-binary/src/test/keyed.test.ts +++ b/packages/typed-binary/src/test/keyed.test.ts @@ -1,23 +1,17 @@ import { describe, expect, it } from 'vitest'; -import { - generic, - genericEnum, - i32, - keyed, - object, - optional, - string, -} from '../describe'; -import type { Parsed } from '../utilityTypes'; -import { encodeAndDecode } from './helpers/mock'; +// Importing from the public API +import bin from '../index.ts'; +// Helpers +import type { Parsed } from '../utilityTypes.ts'; +import { encodeAndDecode } from './helpers/mock.ts'; describe('KeyedSchema', () => { it('should encode and decode a keyed object, no references', () => { - const Example = keyed('example', () => - object({ - value: i32, - label: string, + const Example = bin.keyed('example', () => + bin.object({ + value: bin.i32, + label: bin.string, }), ); @@ -31,11 +25,11 @@ describe('KeyedSchema', () => { }); it('should encode and decode a keyed object, with 0-level-deep references', () => { - const Example = keyed('example', (Example) => - object({ - value: i32, - label: string, - next: optional(Example), + const Example = bin.keyed('example', (Example) => + bin.object({ + value: bin.i32, + label: bin.string, + next: bin.optional(Example), }), ); @@ -50,11 +44,11 @@ describe('KeyedSchema', () => { }); it('should encode and decode a keyed object, with 1-level-deep references', () => { - const Example = keyed('example', (Example) => - object({ - value: i32, - label: string, - next: optional(Example), + const Example = bin.keyed('example', (Example) => + bin.object({ + value: bin.i32, + label: bin.string, + next: bin.optional(Example), }), ); @@ -73,11 +67,11 @@ describe('KeyedSchema', () => { }); it('should encode and decode a keyed object, with 2-level-deep references', () => { - const Example = keyed('example', (Example) => - object({ - value: i32, - label: string, - next: optional(Example), + const Example = bin.keyed('example', (Example) => + bin.object({ + value: bin.i32, + label: bin.string, + next: bin.optional(Example), }), ); @@ -101,14 +95,14 @@ describe('KeyedSchema', () => { it('should encode and decode a keyed object, with an inner keyed-object', () => { type Example = Parsed; - const Example = keyed('example', (Example) => - object({ - label: string, - next: optional(Example), - tree: keyed('tree', (Tree) => - object({ - value: i32, - child: optional(Tree), + const Example = bin.keyed('example', (Example) => + bin.object({ + label: bin.string, + next: bin.optional(Example), + tree: bin.keyed('tree', (Tree) => + bin.object({ + value: bin.i32, + child: bin.optional(Tree), }), ), }), @@ -139,17 +133,17 @@ describe('KeyedSchema', () => { it('should encode and decode a keyed generic object, no references', () => { type Example = Parsed; - const Example = keyed('example', () => - generic( + const Example = bin.keyed('example', () => + bin.generic( { - label: string, + label: bin.string, }, { - primary: object({ - primaryExtra: i32, + primary: bin.object({ + primaryExtra: bin.i32, }), - secondary: object({ - secondaryExtra: i32, + secondary: bin.object({ + secondaryExtra: bin.i32, }), }, ), @@ -167,18 +161,18 @@ describe('KeyedSchema', () => { it('should encode and decode a keyed generic object, with references', () => { type Example = Parsed; - const Example = keyed('example', (Example) => - generic( + const Example = bin.keyed('example', (Example) => + bin.generic( { - label: string, + label: bin.string, }, { - continuous: object({ - next: optional(Example), + continuous: bin.object({ + next: bin.optional(Example), }), - fork: object({ - left: optional(Example), - right: optional(Example), + fork: bin.object({ + left: bin.optional(Example), + right: bin.optional(Example), }), }, ), @@ -209,16 +203,16 @@ describe('KeyedSchema', () => { it('should encode and decode a keyed enum generic object, no base props, with references', () => { type Example = Parsed; - const Example = keyed('example', (Example) => - genericEnum( + const Example = bin.keyed('example', (Example) => + bin.genericEnum( {}, { - 0: object({ - next: optional(Example), + 0: bin.object({ + next: bin.optional(Example), }), - 1: object({ - left: optional(Example), - right: optional(Example), + 1: bin.object({ + left: bin.optional(Example), + right: bin.optional(Example), }), }, ), @@ -245,18 +239,18 @@ describe('KeyedSchema', () => { it('should encode and decode a keyed enum generic object, with references', () => { type Example = Parsed; - const Example = keyed('example', (Example) => - genericEnum( + const Example = bin.keyed('example', (Example) => + bin.genericEnum( { - label: string, + label: bin.string, }, { - 0: object({ - next: optional(Example), + 0: bin.object({ + next: bin.optional(Example), }), - 1: object({ - left: optional(Example), - right: optional(Example), + 1: bin.object({ + left: bin.optional(Example), + right: bin.optional(Example), }), }, ), diff --git a/packages/typed-binary/src/test/object.test.ts b/packages/typed-binary/src/test/object.test.ts index 79cdca7..dab3af3 100644 --- a/packages/typed-binary/src/test/object.test.ts +++ b/packages/typed-binary/src/test/object.test.ts @@ -1,35 +1,26 @@ import { describe, expect, expectTypeOf, it } from 'vitest'; -import { - byte, - concat, - generic, - genericEnum, - i32, - object, - optional, - string, - u32, -} from '../describe'; -import { type ISchema, MaxValue, type ObjectSchema } from '../structure'; -import type { Parsed } from '../utilityTypes'; -import { encodeAndDecode, makeIO } from './helpers/mock'; +// Importing from the public API +import bin, { type ISchema, MaxValue, type ObjectSchema } from '../index.ts'; +// Helpers +import type { Parsed } from '../utilityTypes.ts'; +import { encodeAndDecode, makeIO } from './helpers/mock.ts'; describe('ObjectSchema', () => { it('should properly estimate size of max value', () => { - const description = object({ - value: i32, - label: byte, + const description = bin.object({ + value: bin.i32, + label: bin.byte, }); expect(description.measure(MaxValue).size).to.equal(5); }); it('should encode and decode a simple object', () => { - const description = object({ - value: i32, - label: string, - extra: u32, + const description = bin.object({ + value: bin.i32, + label: bin.string, + extra: bin.u32, }); const value = { @@ -44,9 +35,9 @@ describe('ObjectSchema', () => { }); it('should treat optional properties as undefined', () => { - const OptionalString = optional(string); - const schema = object({ - required: string, + const OptionalString = bin.optional(bin.string); + const schema = bin.object({ + required: bin.string, optional: OptionalString, }); @@ -62,16 +53,16 @@ describe('ObjectSchema', () => { it('should encode and decode a generic object', () => { type GenericType = Parsed; - const GenericType = generic( + const GenericType = bin.generic( { - sharedValue: i32, + sharedValue: bin.i32, }, { - concrete: object({ - extraValue: i32, + concrete: bin.object({ + extraValue: bin.i32, }), - other: object({ - notImportant: i32, + other: bin.object({ + notImportant: bin.i32, }), }, ); @@ -91,16 +82,16 @@ describe('ObjectSchema', () => { it('should encode and decode an enum generic object', () => { type GenericType = Parsed; - const GenericType = genericEnum( + const GenericType = bin.genericEnum( { - sharedValue: i32, + sharedValue: bin.i32, }, { - 0: object({ - extraValue: i32, + 0: bin.object({ + extraValue: bin.i32, }), - 1: object({ - notImportant: i32, + 1: bin.object({ + notImportant: bin.i32, }), }, ); @@ -119,10 +110,10 @@ describe('ObjectSchema', () => { }); it('preserves insertion-order of properties', () => { - const schema = object({ - a: i32, - c: i32, - b: i32, + const schema = bin.object({ + a: bin.i32, + c: bin.i32, + b: bin.i32, }); // Purposefully out-of-order. @@ -141,16 +132,16 @@ describe('ObjectSchema', () => { }); it('allows to extend it with more properties', () => { - const schema = object({ - a: i32, - b: i32, + const schema = bin.object({ + a: bin.i32, + b: bin.i32, }); - const extended = concat([ + const extended = bin.concat([ schema, - object({ - c: i32, - d: i32, + bin.object({ + c: bin.i32, + d: bin.i32, }), ]); @@ -171,15 +162,15 @@ describe('ObjectSchema', () => { }); it('allows to prepend it with more properties', () => { - const schema = object({ - a: i32, - b: i32, + const schema = bin.object({ + a: bin.i32, + b: bin.i32, }); - const prepended = concat([ - object({ - c: i32, - d: i32, + const prepended = bin.concat([ + bin.object({ + c: bin.i32, + d: bin.i32, }), schema, ]); diff --git a/packages/typed-binary/src/test/optional.test.ts b/packages/typed-binary/src/test/optional.test.ts index 43fd7d4..2a3d31b 100644 --- a/packages/typed-binary/src/test/optional.test.ts +++ b/packages/typed-binary/src/test/optional.test.ts @@ -1,15 +1,16 @@ import { describe, expect, it } from 'vitest'; -import { i32 } from '../describe'; -import { OptionalSchema } from '../structure'; -import { makeIO } from './helpers/mock'; -import { randIntBetween } from './random'; +// Importing from the public API +import bin from '../index.ts'; +// Helpers +import { makeIO } from './helpers/mock.ts'; +import { randIntBetween } from './random.ts'; -describe('OptionalSchema', () => { +describe('bin.optional', () => { it('should encode and decode an optional int, with a value', () => { const innerValue = randIntBetween(-10000, 10000); - const description = new OptionalSchema(i32); + const description = bin.optional(bin.i32); const { output, input } = makeIO(1 + 4); // Extra 1 byte to hold the boolean value. description.write(output, innerValue); @@ -17,7 +18,7 @@ describe('OptionalSchema', () => { }); it('should encode and decode a nullable int, with UNDEFINED value', () => { - const description = new OptionalSchema(i32); + const description = bin.optional(bin.i32); const { output, input } = makeIO(1 + 4); // Extra 1 byte to hold the boolean value. description.write(output, undefined); diff --git a/packages/typed-binary/src/test/parsed.test.ts b/packages/typed-binary/src/test/parsed.test.ts index cd6d39d..d337d13 100644 --- a/packages/typed-binary/src/test/parsed.test.ts +++ b/packages/typed-binary/src/test/parsed.test.ts @@ -1,50 +1,38 @@ import { expectTypeOf, it } from 'vitest'; -import { - type Parsed, - bool, - dynamicArrayOf, - f32, - generic, - genericEnum, - i32, - keyed, - object, - optional, - string, - tupleOf, -} from '..'; +// Importing from the public API +import bin from '../index.ts'; it('parses `i32` properly', () => { - expectTypeOf>().toEqualTypeOf(); + expectTypeOf>().toEqualTypeOf(); }); it('parses `string` properly', () => { - expectTypeOf>().toEqualTypeOf(); + expectTypeOf>().toEqualTypeOf(); }); it('parses `optional(string)` properly', () => { - const Schema = optional(string); - expectTypeOf>().toEqualTypeOf(); + const Schema = bin.optional(bin.string); + expectTypeOf>().toEqualTypeOf(); }); it('parses `dynamicArrayOf(i32)` properly', () => { - const Schema = dynamicArrayOf(i32); - expectTypeOf>().toEqualTypeOf(); + const Schema = bin.dynamicArrayOf(bin.i32); + expectTypeOf>().toEqualTypeOf(); }); it('parses `dynamicArrayOf(string)` properly', () => { - const Schema = dynamicArrayOf(string); - expectTypeOf>().toEqualTypeOf(); + const Schema = bin.dynamicArrayOf(bin.string); + expectTypeOf>().toEqualTypeOf(); }); it('parses `object({ a: i32, b: string, c: bool })` properly', () => { - const Schema = object({ - a: i32, - b: string, - c: bool, + const Schema = bin.object({ + a: bin.i32, + b: bin.string, + c: bin.bool, }); - expectTypeOf>().toEqualTypeOf<{ + expectTypeOf>().toEqualTypeOf<{ a: number; b: string; c: boolean; @@ -57,20 +45,20 @@ it('parses `genericEnum` properly', () => { NEGATE = 1, } - const Expression = genericEnum( + const Expression = bin.genericEnum( {}, { - [ExpressionType.ADD]: object({ - leftHandSizeId: i32, - rightHandSizeId: i32, + [ExpressionType.ADD]: bin.object({ + leftHandSizeId: bin.i32, + rightHandSizeId: bin.i32, }), - [ExpressionType.NEGATE]: object({ - innerExpressionId: i32, + [ExpressionType.NEGATE]: bin.object({ + innerExpressionId: bin.i32, }), }, ); - type Result = Parsed; + type Result = bin.Parsed; expectTypeOf().toEqualTypeOf< | { @@ -86,26 +74,26 @@ it('parses `genericEnum` properly', () => { }); it('parses `generic` with base properties properly', () => { - const KeyframeNodeTemplate = generic( + const KeyframeNodeTemplate = bin.generic( { - connections: dynamicArrayOf(i32), + connections: bin.dynamicArrayOf(bin.i32), }, { - 'core:standard': object({ - animationKey: string, - startFrame: i32, - playbackSpeed: i32, - looping: bool, + 'core:standard': bin.object({ + animationKey: bin.string, + startFrame: bin.i32, + playbackSpeed: bin.i32, + looping: bin.bool, }), - 'core:movement': object({ - animationKey: string, - startFrame: i32, - playbackSpeed: i32, + 'core:movement': bin.object({ + animationKey: bin.string, + startFrame: bin.i32, + playbackSpeed: bin.i32, }), }, ); - type KeyframeNodeTemplate = Parsed; + type KeyframeNodeTemplate = bin.Parsed; expectTypeOf().toEqualTypeOf< | { type: 'core:standard'; @@ -126,26 +114,26 @@ it('parses `generic` with base properties properly', () => { }); it('parses simple recursive record properly', () => { - const InfiniteLink = keyed('infinite-link', (InfiniteLink) => - object({ - value: i32, + const InfiniteLink = bin.keyed('infinite-link', (InfiniteLink) => + bin.object({ + value: bin.i32, next: InfiniteLink, }), ); - expectTypeOf['next']>().toEqualTypeOf< - Parsed + expectTypeOf['next']>().toEqualTypeOf< + bin.Parsed >(); }); it('parses tuple schema properly', () => { - const Schema = tupleOf([i32, bool]); + const Schema = bin.tupleOf([bin.i32, bin.bool]); - expectTypeOf>().toEqualTypeOf<[number, boolean]>(); + expectTypeOf>().toEqualTypeOf<[number, boolean]>(); }); it('parses complex schema properly', () => { - const vec3f = tupleOf([f32, f32, f32]); + const vec3f = bin.tupleOf([bin.f32, bin.f32, bin.f32]); enum NodeType { // primitives @@ -157,29 +145,29 @@ it('parses complex schema properly', () => { UNION = 3, } - const Sphere = object({ + const Sphere = bin.object({ pos: vec3f, - radius: f32, + radius: bin.f32, }); - const Box3 = object({ + const Box3 = bin.object({ pos: vec3f, halfSize: vec3f, }); - const Plane = object({ + const Plane = bin.object({ pos: vec3f, normal: vec3f, }); - const Union = object({ - smoothRadius: f32, + const Union = bin.object({ + smoothRadius: bin.f32, }); - const SceneGraphNode = keyed('node', (SceneGraphNode) => - genericEnum( + const SceneGraphNode = bin.keyed('node', (SceneGraphNode) => + bin.genericEnum( { - children: dynamicArrayOf(SceneGraphNode), + children: bin.dynamicArrayOf(SceneGraphNode), }, { [NodeType.SPHERE]: Sphere, @@ -191,7 +179,7 @@ it('parses complex schema properly', () => { ), ); - type Actual = Parsed; + type Actual = bin.Parsed; type Expected = { children: Expected[]; diff --git a/packages/typed-binary/src/test/socket-io-usage.test.ts b/packages/typed-binary/src/test/socket-io-usage.test.ts index 57bdc1e..fd1bd9f 100644 --- a/packages/typed-binary/src/test/socket-io-usage.test.ts +++ b/packages/typed-binary/src/test/socket-io-usage.test.ts @@ -1,14 +1,13 @@ import { afterAll, beforeAll, describe, expect, it } from 'vitest'; +import { Buffer } from 'node:buffer'; import { createServer } from 'node:http'; import type { AddressInfo } from 'node:net'; import { Server, type Socket as ServerSocket } from 'socket.io'; import { type Socket as ClientSocket, io as ioClient } from 'socket.io-client'; -import { byte, dynamicArrayOf, object, string, u32 } from '../describe'; -import { BufferReader, BufferWriter } from '../io'; -import type { AnySchema } from '../structure/types'; -import type { Parsed } from '../utilityTypes'; +// Importing from the public API +import bin, { type AnySchema } from '../index.ts'; function waitFor(socket: ServerSocket | ClientSocket, event = 'message') { return new Promise((resolve) => { @@ -43,7 +42,7 @@ describe('Socket IO Usage', () => { async function sendAndReceive( direction: 'server-to-client' | 'client-to-server', schema: TSchema, - value: Parsed, + value: bin.Parsed, ) { const [from, to] = direction === 'server-to-client' @@ -51,12 +50,12 @@ describe('Socket IO Usage', () => { : [clientSocket, serverSocket]; const buffer = Buffer.alloc(schema.measure(value).size); - schema.write(new BufferWriter(buffer), value); + schema.write(new bin.BufferWriter(buffer), value); from.send(buffer); // Receiving - const response = schema.read(new BufferReader(await waitFor(to))); + const response = schema.read(new bin.BufferReader(await waitFor(to))); expect(response).to.deep.equal(value); } @@ -66,15 +65,15 @@ describe('Socket IO Usage', () => { }); it('should send a byte array successfully', async () => { - const schema = dynamicArrayOf(byte); + const schema = bin.dynamicArrayOf(bin.u8); await sendAndReceive('server-to-client', schema, [1, 2, 254, 255]); }); it('should send a basic struct successfully', async () => { - const schema = object({ - name: string, - age: u32, + const schema = bin.object({ + name: bin.string, + age: bin.u32, }); await sendAndReceive('server-to-client', schema, { diff --git a/packages/typed-binary/src/test/string.test.ts b/packages/typed-binary/src/test/string.test.ts index f9f559d..be3f54e 100644 --- a/packages/typed-binary/src/test/string.test.ts +++ b/packages/typed-binary/src/test/string.test.ts @@ -1,11 +1,14 @@ import { describe, expect, it } from 'vitest'; -import { string } from '../describe'; -import { encodeAndDecode } from './helpers/mock'; -import { randIntBetween } from './random'; + +// Importing from the public API +import bin from '../index.ts'; +// Helpers +import { encodeAndDecode } from './helpers/mock.ts'; +import { randIntBetween } from './random.ts'; describe('StringSchema', () => { it('should encode and decode an empty string value', () => { - const decoded = encodeAndDecode(string, ''); + const decoded = encodeAndDecode(bin.string, ''); expect(decoded).to.equal(''); }); @@ -25,19 +28,19 @@ describe('StringSchema', () => { ); } - const decoded = encodeAndDecode(string, value); + const decoded = encodeAndDecode(bin.string, value); expect(decoded).to.equal(value); }); it('should encode an emoji', () => { const value = '⛓️‍💥'; - const decoded = encodeAndDecode(string, value); + const decoded = encodeAndDecode(bin.string, value); expect(decoded).to.equal(value); }); it('should encode a unicode string', () => { const value = 'A wonderful 🌞 sunny day! 🌲🌲🌲 Forest trip.'; - const decoded = encodeAndDecode(string, value); + const decoded = encodeAndDecode(bin.string, value); expect(decoded).to.equal(value); }); }); diff --git a/packages/typed-binary/src/test/tuple.test.ts b/packages/typed-binary/src/test/tuple.test.ts index 7805a84..787b08c 100644 --- a/packages/typed-binary/src/test/tuple.test.ts +++ b/packages/typed-binary/src/test/tuple.test.ts @@ -1,28 +1,29 @@ import { describe, expect, it } from 'vitest'; -import { bool, i32, tupleOf } from '../describe'; -import { MaxValue } from '../structure'; -import { encodeAndDecode } from './helpers/mock'; +// Importing from the public API +import bin from '../index.ts'; +// Helpers +import { encodeAndDecode } from './helpers/mock.ts'; describe('TupleSchema', () => { it('should estimate an [i32, bool] encoding size', () => { - const Schema = tupleOf([i32, bool]); + const Schema = bin.tupleOf([bin.i32, bin.bool]); expect(Schema.measure([123, false]).size).toEqual( - i32.measure(MaxValue).size + bool.measure(MaxValue).size, + bin.i32.measure(bin.MaxValue).size + bin.bool.measure(bin.MaxValue).size, ); }); it('should properly estimate size of max value', () => { - const Schema = tupleOf([i32, bool]); + const Schema = bin.tupleOf([bin.i32, bin.bool]); - expect(Schema.measure(MaxValue).size).toEqual( - i32.measure(MaxValue).size + bool.measure(MaxValue).size, + expect(Schema.measure(bin.MaxValue).size).toEqual( + bin.i32.measure(bin.MaxValue).size + bin.bool.measure(bin.MaxValue).size, ); }); it('should encode and decode [i32, bool]', () => { - const Schema = tupleOf([i32, bool]); + const Schema = bin.tupleOf([bin.i32, bin.bool]); expect(encodeAndDecode(Schema, [123, false])).toEqual([123, false]); }); diff --git a/packages/typed-binary/src/test/typedArray.test.ts b/packages/typed-binary/src/test/typedArray.test.ts index a53b14b..b4f6000 100644 --- a/packages/typed-binary/src/test/typedArray.test.ts +++ b/packages/typed-binary/src/test/typedArray.test.ts @@ -1,23 +1,16 @@ import { describe, expect, it } from 'vitest'; -import { - f32Array, - f64Array, - i8Array, - i16Array, - i32Array, - u8Array, - u8ClampedArray, - u16Array, - u32Array, -} from '../describe'; -import { encodeAndDecode } from './helpers/mock'; + +// Importing from the public API +import bin from '../index.ts'; +// Helpers +import { encodeAndDecode } from './helpers/mock.ts'; describe('u8Array', () => { it('encodes and decodes a uint8 array', () => { const value = new Uint8Array([0, 1, 15, 255, 256]); expect(value[4]).toEqual(0); // not-clamping - expect([...encodeAndDecode(u8Array(5), value)]).toEqual([...value]); + expect([...encodeAndDecode(bin.u8Array(5), value)]).toEqual([...value]); }); }); @@ -26,7 +19,9 @@ describe('u8ClampedArray', () => { const value = new Uint8ClampedArray([0, 1, 15, 255, 256]); expect(value[4]).toEqual(255); // clamping - expect([...encodeAndDecode(u8ClampedArray(5), value)]).toEqual([...value]); + expect([...encodeAndDecode(bin.u8ClampedArray(5), value)]).toEqual([ + ...value, + ]); }); }); @@ -36,7 +31,7 @@ describe('u16Array', () => { expect(value[3]).toEqual(65_535); expect(value[4]).toEqual(0); // not-clamping - expect([...encodeAndDecode(u16Array(5), value)]).toEqual([...value]); + expect([...encodeAndDecode(bin.u16Array(5), value)]).toEqual([...value]); }); }); @@ -46,7 +41,7 @@ describe('u32Array', () => { expect(value[3]).toEqual(4_294_967_295); expect(value[4]).toEqual(0); // not-clamping - expect([...encodeAndDecode(u32Array(5), value)]).toEqual([...value]); + expect([...encodeAndDecode(bin.u32Array(5), value)]).toEqual([...value]); }); }); @@ -56,7 +51,7 @@ describe('i8Array', () => { expect(value[3]).toEqual(127); expect(value[4]).toEqual(-128); // one-over max interpreted as negative - expect([...encodeAndDecode(i8Array(5), value)]).toEqual([...value]); + expect([...encodeAndDecode(bin.i8Array(5), value)]).toEqual([...value]); }); }); @@ -66,7 +61,7 @@ describe('i16Array', () => { expect(value[3]).toEqual(32_767); expect(value[4]).toEqual(-32_768); // one-over max interpreted as negative - expect([...encodeAndDecode(i16Array(5), value)]).toEqual([...value]); + expect([...encodeAndDecode(bin.i16Array(5), value)]).toEqual([...value]); }); }); @@ -75,20 +70,20 @@ describe('i32Array', () => { const value = new Int32Array([ 16, -2_147_483_648, 2_147_483_647, 2_147_483_648, ]); - expect([...encodeAndDecode(i32Array(4), value)]).toEqual([...value]); + expect([...encodeAndDecode(bin.i32Array(4), value)]).toEqual([...value]); }); }); describe('f32Array', () => { it('encodes and decodes a float32 array', () => { const value = new Float32Array([0.1, 0.2, 0.3]); - expect([...encodeAndDecode(f32Array(3), value)]).toEqual([...value]); + expect([...encodeAndDecode(bin.f32Array(3), value)]).toEqual([...value]); }); }); describe('f64Array', () => { it('encodes and decodes a float64 array', () => { const value = new Float64Array([0.1, 0.2, 0.3]); - expect([...encodeAndDecode(f64Array(3), value)]).toEqual([...value]); + expect([...encodeAndDecode(bin.f64Array(3), value)]).toEqual([...value]); }); }); diff --git a/packages/typed-binary/src/test/unwrap.test.ts b/packages/typed-binary/src/test/unwrap.test.ts index d911b53..3337b6f 100644 --- a/packages/typed-binary/src/test/unwrap.test.ts +++ b/packages/typed-binary/src/test/unwrap.test.ts @@ -1,11 +1,13 @@ import { describe, expectTypeOf, it } from 'vitest'; -import type { ISchema, Unwrap } from '..'; +// Importing from the public API import type { IKeyedSchema, + ISchema, + Unwrap, UnwrapArray, UnwrapRecord, -} from '../structure/types'; +} from '../index.ts'; describe('Unwrap', () => { it('unwraps one level of wrapping properly', () => { diff --git a/packages/typed-binary/src/utilityTypes.test.ts b/packages/typed-binary/src/utilityTypes.test.ts index 4d68eb4..5287c4b 100644 --- a/packages/typed-binary/src/utilityTypes.test.ts +++ b/packages/typed-binary/src/utilityTypes.test.ts @@ -3,7 +3,7 @@ import type { DistributedKeyOf, MergeRecordUnion, MergeRecords, -} from './utilityTypes'; +} from './utilityTypes.ts'; describe('DistributedKeyOf', () => { it('should apply keyof to each union entry separately, then union the results together', () => { diff --git a/packages/typed-binary/src/utilityTypes.ts b/packages/typed-binary/src/utilityTypes.ts index bcf5874..a98b661 100644 --- a/packages/typed-binary/src/utilityTypes.ts +++ b/packages/typed-binary/src/utilityTypes.ts @@ -4,7 +4,7 @@ import type { Ref, Unwrap, UnwrapRecord, -} from './structure/types'; +} from './structure/types.ts'; /** * @example ``` diff --git a/tsconfig.base.json b/tsconfig.base.json index 657895e..89ca430 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -23,6 +23,7 @@ "allowSyntheticDefaultImports": true /* Allow 'import x from y' when a module doesn't have a default export. */, "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */, "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, + "allowImportingTsExtensions": true, /* Type Checking */ "strict": true /* Enable all strict type-checking options. */,