diff --git a/apps/examples/binaryMesh/index.ts b/apps/examples/binaryMesh/index.ts index bf66f0c..b9b7dbc 100644 --- a/apps/examples/binaryMesh/index.ts +++ b/apps/examples/binaryMesh/index.ts @@ -1,5 +1,5 @@ import fs from 'node:fs/promises'; -import { BufferReader, BufferWriter } from 'typed-binary'; +import bin from 'typed-binary'; import { Mesh } from './schemas'; const DEFAULT_MESH: Mesh = { @@ -17,7 +17,7 @@ const DEFAULT_MESH: Mesh = { async function loadMesh(): Promise { try { const buffer = await fs.readFile('./binaryMesh/mesh.bin'); - const reader = new BufferReader(buffer); + const reader = new bin.BufferReader(buffer); return Mesh.read(reader); } catch (e) { @@ -28,7 +28,7 @@ async function loadMesh(): Promise { async function saveMesh(mesh: Mesh): Promise { try { const buffer = Buffer.alloc(Mesh.measure(mesh).size); - const writer = new BufferWriter(buffer); + const writer = new bin.BufferWriter(buffer); Mesh.write(writer, mesh); diff --git a/apps/examples/binaryMesh/schemas.ts b/apps/examples/binaryMesh/schemas.ts index c6189f0..70d8307 100644 --- a/apps/examples/binaryMesh/schemas.ts +++ b/apps/examples/binaryMesh/schemas.ts @@ -1,19 +1,18 @@ -import type { Parsed } from 'typed-binary'; -import { arrayOf, dynamicArrayOf, i32, object } from 'typed-binary'; +import bin from 'typed-binary'; -export const Vertex = object({ - x: i32, - y: i32, - z: i32, +export const Vertex = bin.object({ + x: bin.i32, + y: bin.i32, + z: bin.i32, }); -export const Polygon = object({ - vertices: arrayOf(Vertex, 3), +export const Polygon = bin.object({ + vertices: bin.arrayOf(Vertex, 3), }); -export const Mesh = object({ - faces: dynamicArrayOf(Polygon), +export const Mesh = bin.object({ + faces: bin.dynamicArrayOf(Polygon), }); // Helpful for the top-most level element -export type Mesh = Parsed; +export type Mesh = bin.Parsed; diff --git a/apps/examples/customSchema/index.ts b/apps/examples/customSchema/index.ts index 4c7d4bb..ba81288 100644 --- a/apps/examples/customSchema/index.ts +++ b/apps/examples/customSchema/index.ts @@ -2,7 +2,7 @@ // Run with `npm run example:customSchema` // -import { type Parsed, object } from 'typed-binary'; +import bin from 'typed-binary'; import { writeAndRead } from '../__util'; import { radians } from './radians'; @@ -10,8 +10,8 @@ import { radians } from './radians'; * ROTATION */ -type Rotation = Parsed; -const Rotation = object({ +type Rotation = bin.Parsed; +const Rotation = bin.object({ roll: radians, pitch: radians, yaw: radians, diff --git a/apps/examples/dog/index.ts b/apps/examples/dog/index.ts index 9410953..2fd5e51 100644 --- a/apps/examples/dog/index.ts +++ b/apps/examples/dog/index.ts @@ -2,17 +2,17 @@ // Run with `npm run example:dog` // -import { type Parsed, f32, i32, object, string, tupleOf } from 'typed-binary'; +import bin from 'typed-binary'; // Describing the Dog schema -const Dog = object({ - name: string, - position: tupleOf([f32, f32, f32]), - age: i32, +const Dog = bin.object({ + name: bin.string, + position: bin.tupleOf([bin.f32, bin.f32, bin.f32]), + age: bin.i32, }); // Creating a type-alias for ease-of-use. -type Dog = Parsed; +type Dog = bin.Parsed; // Creating a 'Dog' object. const dog: Dog = { diff --git a/apps/examples/genericEnumTypes/index.ts b/apps/examples/genericEnumTypes/index.ts index 1a1d158..c4f1669 100644 --- a/apps/examples/genericEnumTypes/index.ts +++ b/apps/examples/genericEnumTypes/index.ts @@ -2,15 +2,7 @@ // Run with `npm run example:genericEnumTypes` // -import { - BufferReader, - BufferWriter, - bool, - genericEnum, - i32, - object, - string, -} from 'typed-binary'; +import bin from 'typed-binary'; enum AnimalType { DOG = 0, @@ -18,27 +10,27 @@ enum AnimalType { } // Generic (enum) object schema -const Animal = genericEnum( +const Animal = bin.genericEnum( { - nickname: string, - age: i32, + nickname: bin.string, + age: bin.i32, }, { - [AnimalType.DOG]: object({ + [AnimalType.DOG]: bin.object({ // Animal can be a dog - breed: string, + breed: bin.string, }), - [AnimalType.CAT]: object({ + [AnimalType.CAT]: bin.object({ // Animal can be a cat - striped: bool, + striped: bin.bool, }), }, ); // A buffer to serialize into/out of const buffer = Buffer.alloc(16); -const writer = new BufferWriter(buffer); -const reader = new BufferReader(buffer); +const writer = new bin.BufferWriter(buffer); +const reader = new bin.BufferReader(buffer); // Writing an Animal Animal.write(writer, { diff --git a/apps/examples/genericTypes/index.ts b/apps/examples/genericTypes/index.ts index 5a66744..09b4ca9 100644 --- a/apps/examples/genericTypes/index.ts +++ b/apps/examples/genericTypes/index.ts @@ -2,38 +2,30 @@ // Run with `npm run example:genericTypes` // -import { - BufferReader, - BufferWriter, - bool, - generic, - i32, - object, - string, -} from 'typed-binary'; +import bin from 'typed-binary'; // Generic object schema -const Animal = generic( +const Animal = bin.generic( { - nickname: string, - age: i32, + nickname: bin.string, + age: bin.i32, }, { - dog: object({ + dog: bin.object({ // Animal can be a dog - breed: string, + breed: bin.string, }), - cat: object({ + cat: bin.object({ // Animal can be a cat - striped: bool, + striped: bin.bool, }), }, ); // A buffer to serialize into/out of const buffer = Buffer.alloc(16); -const writer = new BufferWriter(buffer); -const reader = new BufferReader(buffer); +const writer = new bin.BufferWriter(buffer); +const reader = new bin.BufferReader(buffer); // Writing an Animal Animal.write(writer, { diff --git a/apps/examples/inferredShowcase/index.ts b/apps/examples/inferredShowcase/index.ts index b27d397..a17c267 100644 --- a/apps/examples/inferredShowcase/index.ts +++ b/apps/examples/inferredShowcase/index.ts @@ -1,15 +1,15 @@ -import { type Parsed, i32, object, string } from 'typed-binary'; +import bin from 'typed-binary'; // Describing the Dog schema. -const Dog = object({ +const Dog = bin.object({ /** The name of the doggy. */ - name: string, + name: bin.string, /** The dog's age in dog years. */ - age: i32, + age: bin.i32, }); // Creating a type-alias for ease-of-use. -type Dog = Parsed; +type Dog = bin.Parsed; // Creating a 'Dog' object. const dog: Dog = { diff --git a/apps/examples/recursiveTypes/index.ts b/apps/examples/recursiveTypes/index.ts index af3bba7..56572ab 100644 --- a/apps/examples/recursiveTypes/index.ts +++ b/apps/examples/recursiveTypes/index.ts @@ -2,29 +2,28 @@ // Run with `npm run example:recursiveTypes` // -import type { Parsed } from 'typed-binary'; -import { generic, i32, keyed, object, optional, string } from 'typed-binary'; +import bin from 'typed-binary'; -type Expression = Parsed; -const Expression = keyed('expression', (Expression) => - generic( +type Expression = bin.Parsed; +const Expression = bin.keyed('expression', (Expression) => + bin.generic( {}, { - multiply: object({ + multiply: bin.object({ a: Expression, b: Expression, }), - negate: object({ + negate: bin.object({ inner: Expression, }), - int_literal: object({ - value: i32, + int_literal: bin.object({ + value: bin.i32, }), }, ), ); -const expr: Parsed = { +const expr: bin.Parsed = { type: 'multiply', a: { type: 'negate', @@ -39,21 +38,21 @@ const expr: Parsed = { }, }; -type Instruction = Parsed; -const Instruction = object({ - target_variable: string, - expression: optional(Expression), +type Instruction = bin.Parsed; +const Instruction = bin.object({ + target_variable: bin.string, + expression: bin.optional(Expression), }); -type Complex = Parsed; -const Complex = keyed('complex' as const, (Complex) => - object({ - label: string, - inner: optional(Complex), - cycle: keyed('cycle' as const, (Cycle) => - object({ - value: string, - next: optional(Cycle), +type Complex = bin.Parsed; +const Complex = bin.keyed('complex' as const, (Complex) => + bin.object({ + label: bin.string, + inner: bin.optional(Complex), + cycle: bin.keyed('cycle' as const, (Cycle) => + bin.object({ + value: bin.string, + next: bin.optional(Cycle), }), ), }), diff --git a/apps/examples/stateMachine/connection.ts b/apps/examples/stateMachine/connection.ts index 649aff6..1358518 100644 --- a/apps/examples/stateMachine/connection.ts +++ b/apps/examples/stateMachine/connection.ts @@ -1,13 +1,13 @@ -import { byte, f32, i32, object } from 'typed-binary'; +import bin from 'typed-binary'; import { TriggerCondition } from './triggerCondition'; -export const ConnectionTemplate = object({ - targetNodeIndex: i32, +export const ConnectionTemplate = bin.object({ + targetNodeIndex: bin.i32, /** * The duration of the transition in Minecraft ticks */ - transitionDuration: f32, - transitionEasing: byte, + transitionDuration: bin.f32, + transitionEasing: bin.byte, triggerCondition: TriggerCondition, }); diff --git a/apps/examples/stateMachine/graph.ts b/apps/examples/stateMachine/graph.ts index ac9df32..2da10da 100644 --- a/apps/examples/stateMachine/graph.ts +++ b/apps/examples/stateMachine/graph.ts @@ -1,7 +1,7 @@ -import { dynamicArrayOf, i32, object } from 'typed-binary'; +import bin from 'typed-binary'; import { NodeTemplate } from './node'; -export const Graph = object({ - entryNode: i32, - nodes: dynamicArrayOf(NodeTemplate), +export const Graph = bin.object({ + entryNode: bin.i32, + nodes: bin.dynamicArrayOf(NodeTemplate), }); diff --git a/apps/examples/stateMachine/node.ts b/apps/examples/stateMachine/node.ts index 360b3d0..2d6a66a 100644 --- a/apps/examples/stateMachine/node.ts +++ b/apps/examples/stateMachine/node.ts @@ -1,10 +1,10 @@ -import { bool, dynamicArrayOf, f32, i32, object, string } from 'typed-binary'; +import bin from 'typed-binary'; import { ConnectionTemplate } from './connection'; -export const NodeTemplate = object({ - animationKey: string, - startFrame: i32, - playbackSpeed: f32, - looping: bool, - connections: dynamicArrayOf(ConnectionTemplate), +export const NodeTemplate = bin.object({ + animationKey: bin.string, + startFrame: bin.i32, + playbackSpeed: bin.f32, + looping: bin.bool, + connections: bin.dynamicArrayOf(ConnectionTemplate), }); diff --git a/apps/examples/stateMachine/triggerCondition.ts b/apps/examples/stateMachine/triggerCondition.ts index 59c3eec..1794a27 100644 --- a/apps/examples/stateMachine/triggerCondition.ts +++ b/apps/examples/stateMachine/triggerCondition.ts @@ -1,20 +1,21 @@ -import { byte, generic, keyed, object } from 'typed-binary'; -import type { Parsed } from 'typed-binary'; +import bin from 'typed-binary'; -type TriggerCondition = Parsed; -export const TriggerCondition = keyed('trigger-condition', (TriggerCondition) => - generic( - {}, - { - 'core:state': object({ - state: byte, - }), - 'core:animation_finished': object({}), - 'core:not': object({ - condition: TriggerCondition, - }), - }, - ), +type TriggerCondition = bin.Parsed; +export const TriggerCondition = bin.keyed( + 'trigger-condition', + (TriggerCondition) => + bin.generic( + {}, + { + 'core:state': bin.object({ + state: bin.byte, + }), + 'core:animation_finished': bin.object({}), + 'core:not': bin.object({ + condition: TriggerCondition, + }), + }, + ), ); export enum MobState { diff --git a/apps/typed-binary-docs/src/content/docs/guides/arrays-and-tuples.mdx b/apps/typed-binary-docs/src/content/docs/guides/arrays-and-tuples.mdx index 9225aef..957a11e 100644 --- a/apps/typed-binary-docs/src/content/docs/guides/arrays-and-tuples.mdx +++ b/apps/typed-binary-docs/src/content/docs/guides/arrays-and-tuples.mdx @@ -8,11 +8,13 @@ description: A guide on how arrays and tuples can be represented in Typed Binary The items are encoded right next to each other. No need to store length information, as that is constant (built into the schema). ```ts -import { f32, arrayOf } from 'typed-binary'; +const Vector2 = bin.arrayOf(bin.f32, 2); +const Vector3 = bin.arrayOf(bin.f32, 3); +const Vector4 = bin.arrayOf(bin.f32, 4); -const Vector2 = arrayOf(f32, 2); -const Vector3 = arrayOf(f32, 3); -const Vector4 = arrayOf(f32, 4); +type Vector2 = bin.Parsed; // number[] +type Vector3 = bin.Parsed; // number[] +type Vector4 = bin.Parsed; // number[] ``` ## Dynamic Arrays @@ -20,9 +22,9 @@ const Vector4 = arrayOf(f32, 4); First 4 bytes of encoding are the length of the array, then its items next to one another. ```ts -import { i32, dynamicArrayOf } from 'typed-binary'; +const IntArray = bin.dynamicArrayOf(bin.i32); -const IntArray = dynamicArrayOf(i32); +type IntArray = bin.Parsed; // number[] ``` ## Tuple @@ -30,11 +32,9 @@ const IntArray = dynamicArrayOf(i32); Encodes an ordered set of schemas, one next to another. ```ts -import { f32, string, tupleOf } from 'typed-binary'; +const Vec3f = bin.tupleOf([bin.f32, bin.f32, bin.f32]); +type Vec3f = bin.Parsed; // [number, number, number] -const Vec3f = tupleOf([f32, f32, f32]); -type Vec3f = Parsed; // [number, number, number] - -const RecordEntry = tupleOf([string, Vec3f]); -type RecordEntry = Parsed; // [string, [number, number, number]] +const RecordEntry = bin.tupleOf([bin.string, Vec3f]); +type RecordEntry = bin.Parsed; // [string, [number, number, number]] ``` diff --git a/apps/typed-binary-docs/src/content/docs/guides/getting-started.mdx b/apps/typed-binary-docs/src/content/docs/guides/getting-started.mdx index d464a1a..d32baa1 100644 --- a/apps/typed-binary-docs/src/content/docs/guides/getting-started.mdx +++ b/apps/typed-binary-docs/src/content/docs/guides/getting-started.mdx @@ -31,25 +31,25 @@ import { Tabs, TabItem } from '@astrojs/starlight/components'; ## Use in the browser ```ts {7} -import { tupleOf, f32, MaxValue, BufferWriter } from 'typed-binary'; +import bin from 'typed-binary'; // Define a schema -const Vec2f = tupleOf([f32, f32]); -const Vec2fSize = Vec2f.measure(MaxValue).size; +const Vec2f = bin.tupleOf([bin.f32, bin.f32]); +const Vec2fSize = Vec2f.measure(bin.MaxValue).size; const buffer = new ArrayBuffer(Vec2fSize); -Vec2f.write(new BufferWriter(buffer), [0.5, 3.14]); +Vec2f.write(new bin.BufferWriter(buffer), [0.5, 3.14]); ``` ## Use in Node.js ```ts {7} -import { tupleOf, f32, MaxValue, BufferWriter } from 'typed-binary'; +import bin from 'typed-binary'; // Define a schema -const Vec2f = tupleOf([f32, f32]); -const Vec2fSize = Vec2f.measure(MaxValue).size; +const Vec2f = bin.tupleOf([bin.f32, bin.f32]); +const Vec2fSize = Vec2f.measure(bin.MaxValue).size; const buffer = Buffer.alloc(Vec2fSize); -Vec2f.write(new BufferWriter(buffer), [0.5, 3.14]); +Vec2f.write(new bin.BufferWriter(buffer), [0.5, 3.14]); ``` \ No newline at end of file diff --git a/apps/typed-binary-docs/src/content/docs/guides/objects.mdx b/apps/typed-binary-docs/src/content/docs/guides/objects.mdx index 180956a..229e3d2 100644 --- a/apps/typed-binary-docs/src/content/docs/guides/objects.mdx +++ b/apps/typed-binary-docs/src/content/docs/guides/objects.mdx @@ -4,18 +4,18 @@ description: Objects store their properties in key-ascending-alphabetical order, --- Primitive values in JavaScript can be composed into *Plain-Old-JavaScript-Objects*. This can be -easily represented using the `object()` schema constructor function. +easily represented using the `bin.object()` schema constructor function. ## Simple objects ```ts -import { i32, string, object } from 'typed-binary'; +import bin from 'typed-binary'; // Simple object schema -const Person = object({ - firstName: string, - lastName: string, - age: i32, +const Person = bin.object({ + firstName: bin.string, + lastName: bin.string, + age: bin.i32, }); // Writing a Person @@ -29,7 +29,7 @@ console.log(JSON.stringify(Person.read(reader))); // { "firstName": "John", ... ``` :::note -Objects store their properties in the order they are defined in the record passed into the `object()` constructor function. +Objects store their properties in the order they are defined in the record passed into the `bin.object()` constructor function. ::: ## Generic objects @@ -39,28 +39,22 @@ This feature allows for the parsing of a type that contains different fields dep ### Keyed by strings ```ts -import { - i32, - string, - bool, - generic, - object, -} from 'typed-binary'; +import bin from 'typed-binary'; // Generic object schema -const Animal = generic( +const Animal = bin.generic( { - nickname: string, - age: i32, + nickname: bin.string, + age: bin.i32, }, { - dog: object({ + dog: bin.object({ // Animal can be a dog - breed: string, + breed: bin.string, }), - cat: object({ + cat: bin.object({ // Animal can be a cat - striped: bool, + striped: bin.bool, }), } ); @@ -102,7 +96,7 @@ if (animal.type === 'cat') { ### Keyed by an enum (byte) ```ts -import { BufferWriter, BufferReader, i32, string, genericEnum, object } from 'typed-binary'; +import bin from 'typed-binary'; enum AnimalType = { DOG = 0, @@ -110,15 +104,15 @@ enum AnimalType = { }; // Generic (enum) object schema -const Animal = genericEnum({ - nickname: string, - age: i32, +const Animal = bin.genericEnum({ + nickname: bin.string, + age: bin.i32, }, { - [AnimalType.DOG]: object({ // Animal can be a dog - breed: string, + [AnimalType.DOG]: bin.object({ // Animal can be a dog + breed: bin.string, }), - [AnimalType.CAT]: object({ // Animal can be a cat - striped: bool, + [AnimalType.CAT]: bin.object({ // Animal can be a cat + striped: bin.bool, }), }); diff --git a/apps/typed-binary-docs/src/content/docs/guides/optionals.mdx b/apps/typed-binary-docs/src/content/docs/guides/optionals.mdx index fb382bd..ad4f444 100644 --- a/apps/typed-binary-docs/src/content/docs/guides/optionals.mdx +++ b/apps/typed-binary-docs/src/content/docs/guides/optionals.mdx @@ -11,32 +11,25 @@ They are encoded as: - `1 encoded(value)` given `value !== undefined`. ```ts -import { - BufferWriter, - BufferReader, - i32, - string, - object, - optional, -} from 'typed-binary'; +import bin from 'typed-binary'; const buffer = Buffer.alloc(16); -const writer = new BufferWriter(buffer); -const reader = new BufferReader(buffer); +const writer = new bin.BufferWriter(buffer); +const reader = new bin.BufferReader(buffer); // Simple object schema -const Address = object({ - city: string, - street: string, - postalCode: string, +const Address = bin.object({ + city: bin.string, + street: bin.string, + postalCode: bin.string, }); // Simple object schema (with optional field) -const Person = object({ - firstName: string, - lastName: string, - age: i32, - address: optional(Address), +const Person = bin.object({ + firstName: bin.string, + lastName: bin.string, + age: bin.i32, + address: bin.optional(Address), }); // Writing a Person (no address) diff --git a/apps/typed-binary-docs/src/content/docs/guides/primitive-values.mdx b/apps/typed-binary-docs/src/content/docs/guides/primitive-values.mdx index 6e345a6..cc244c9 100644 --- a/apps/typed-binary-docs/src/content/docs/guides/primitive-values.mdx +++ b/apps/typed-binary-docs/src/content/docs/guides/primitive-values.mdx @@ -17,17 +17,17 @@ There are a few primitives to choose from: - A string of characters followed by a `\0` terminal character. ```ts -import { BufferWriter, BufferReader, byte, string } from 'typed-binary'; +import bin from 'typed-binary'; const buffer = Buffer.alloc(16); // Writing four bytes into the buffer -const writer = new BufferWriter(buffer); -byte.write(writer, 'W'.charCodeAt(0)); -byte.write(writer, 'o'.charCodeAt(0)); -byte.write(writer, 'w'.charCodeAt(0)); -byte.write(writer, 0); +const writer = new bin.BufferWriter(buffer); +bin.byte.write(writer, 'W'.charCodeAt(0)); +bin.byte.write(writer, 'o'.charCodeAt(0)); +bin.byte.write(writer, 'w'.charCodeAt(0)); +bin.byte.write(writer, 0); -const reader = new BufferReader(buffer); -console.log(string.read(reader)); // > Wow +const reader = new bin.BufferReader(buffer); +console.log(bin.string.read(reader)); // > Wow ``` diff --git a/apps/typed-binary-docs/src/content/docs/guides/recursive-types.mdx b/apps/typed-binary-docs/src/content/docs/guides/recursive-types.mdx index 3cfb92b..89d74bf 100644 --- a/apps/typed-binary-docs/src/content/docs/guides/recursive-types.mdx +++ b/apps/typed-binary-docs/src/content/docs/guides/recursive-types.mdx @@ -7,7 +7,7 @@ If you want an object type to be able to contain one of itself (recursion), then ```ts /** - * Wrapping a schema with a 'keyed' call allows the inner code to + * Wrapping a schema with a 'bin.keyed' call allows the inner code to * use a reference to the type we're currently creating, instead * of the type itself. * @@ -21,10 +21,10 @@ If you want an object type to be able to contain one of itself (recursion), then * This is because references are resolved recursively once the method * passed as the 2nd argument to 'keyed' returns the schema. */ -const Recursive = keyed('recursive-key', (Recursive) => - object({ - value: i32, - next: optional(Recursive), +const Recursive = bin.keyed('recursive-key', (Recursive) => + bin.object({ + value: bin.i32, + next: bin.optional(Recursive), }) ); ``` @@ -32,28 +32,29 @@ const Recursive = keyed('recursive-key', (Recursive) => ### Recursive types alongside generics ```ts -import { i32, string, object, keyed } from 'typed-binary'; +import bin from 'typed-binary'; -type Expression = Parsed; -const Expression = keyed('expression', (Expression) => - generic( +const Expression = bin.keyed('expression', (Expression) => + bin.generic( {}, { - multiply: object({ + multiply: bin.object({ a: Expression, b: Expression, }), - negate: object({ + negate: bin.object({ inner: Expression, }), - int_literal: object({ - value: i32, + int_literal: bin.object({ + value: bin.i32, }), } ) ); -const expr: Parsed = { +type Expression = bin.Parsed; + +const expr: Expression = { type: 'multiply', a: { type: 'negate', diff --git a/apps/typed-binary-docs/src/content/docs/guides/serialization-and-deserialization.mdx b/apps/typed-binary-docs/src/content/docs/guides/serialization-and-deserialization.mdx index 67adb85..e504f88 100644 --- a/apps/typed-binary-docs/src/content/docs/guides/serialization-and-deserialization.mdx +++ b/apps/typed-binary-docs/src/content/docs/guides/serialization-and-deserialization.mdx @@ -25,20 +25,20 @@ measure(value: T | MaxValue, measurer: IMeasurer): IMeasurer; The `ISerialInput/Output` interfaces have a basic built-in implementation that reads/writes to a buffer: ```ts -import { BufferReader, BufferWriter, byte, string } from 'typed-binary'; +import bin from 'typed-binary'; // Creating a fixed-length buffer of arbitrary size (64 bytes). const buffer = Buffer.alloc(64); // Or new ArrayBuffer(64); on browsers. // Writing four bytes into the buffer -const writer = new BufferWriter(buffer); // Implements ISerialOutput -byte.write(writer, 'W'.charCodeAt(0)); -byte.write(writer, 'o'.charCodeAt(0)); -byte.write(writer, 'w'.charCodeAt(0)); -byte.write(writer, 0); - -const reader = new BufferReader(buffer); // Implements ISerialInput -console.log(string.read(reader)); // > Wow +const writer = new bin.BufferWriter(buffer); // Implements ISerialOutput +bin.byte.write(writer, 'W'.charCodeAt(0)); +bin.byte.write(writer, 'o'.charCodeAt(0)); +bin.byte.write(writer, 'w'.charCodeAt(0)); +bin.byte.write(writer, 0); + +const reader = new bin.BufferReader(buffer); // Implements ISerialInput +console.log(bin.string.read(reader)); // > Wow ``` ### Creating a buffer with the most optimal size @@ -47,12 +47,12 @@ Schemas can measure how many bytes a particular value will take up, which can be to create a buffer that will fit that value perfectly. ```ts -import { object, u32, f32 } from 'typed-binary'; +import bin from 'typed-binary'; -export const PlayerUpdatePacket = object({ - id: u32, - x: f32, - y: f32, +export const PlayerUpdatePacket = bin.object({ + id: bin.u32, + x: bin.f32, + y: bin.f32, }); const packet = { @@ -70,15 +70,15 @@ const buffer = Buffer.alloc(packetSize); // or new ArrayBuffer(packetSize) on th If a schema's size is bounded (there is a max size that no value encodings will surpass), we can create a shared buffer of the maximum size the schema can take. -```ts "MaxValue" -import { object, u32, f32, MaxValue } from 'typed-binary'; +```ts "bin.MaxValue" +import bin from 'typed-binary'; -export const PlayerUpdatePacket = object({ - id: u32, - x: f32, - y: f32, +export const PlayerUpdatePacket = bin.object({ + id: bin.u32, + x: bin.f32, + y: bin.f32, }); -const maxPacketSize = PlayerUpdatePacket.measure(MaxValue).size; +const maxPacketSize = PlayerUpdatePacket.measure(bin.MaxValue).size; const sharedBuffer = Buffer.alloc(maxPacketSize); // or new ArrayBuffer(maxPacketSize) on the browser ``` diff --git a/apps/typed-binary-docs/src/content/docs/guides/typed-arrays.mdx b/apps/typed-binary-docs/src/content/docs/guides/typed-arrays.mdx index e78d21d..dac9a06 100644 --- a/apps/typed-binary-docs/src/content/docs/guides/typed-arrays.mdx +++ b/apps/typed-binary-docs/src/content/docs/guides/typed-arrays.mdx @@ -7,9 +7,9 @@ Sometimes binary is the format that we want to work with directly. [Typed array] allow that data to be nested in plain objects or arrays. ```ts -const Image = object({ - size: tupleOf([u32, u32]), - bitmap: u8Array(256 * 256), +const Image = bin.object({ + size: bin.tupleOf([bin.u32, bin.u32]), + bitmap: bin.u8Array(256 * 256), }); // { @@ -26,12 +26,12 @@ Below is the list of available typed array schemas. Schema constructor | Encoded as | JavaScript value ---|---|--- -`u8Array` | consecutive 8-bit unsigned integers | `Uint8Array` -`u8ClampedArray` | consecutive 8-bit unsigned integers | `Uint8ClampedArray` -`u16Array` | consecutive 16-bit unsigned integers | `Uint16Array` -`u32Array` | consecutive 32-bit unsigned integers | `Uint32Array` -`i8Array` | consecutive 8-bit signed integers | `Int8Array` -`i16Array` | consecutive 16-bit signed integers | `Int16Array` -`i32Array` | consecutive 32-bit signed integers | `Int32Array` -`f32Array` | consecutive 32-bit floats | `Float32Array` -`f64Array` | consecutive 64-bit floats | `Float64Array` +`bin.u8Array` | consecutive 8-bit unsigned integers | `Uint8Array` +`bin.u8ClampedArray` | consecutive 8-bit unsigned integers | `Uint8ClampedArray` +`bin.u16Array` | consecutive 16-bit unsigned integers | `Uint16Array` +`bin.u32Array` | consecutive 32-bit unsigned integers | `Uint32Array` +`bin.i8Array` | consecutive 8-bit signed integers | `Int8Array` +`bin.i16Array` | consecutive 16-bit signed integers | `Int16Array` +`bin.i32Array` | consecutive 32-bit signed integers | `Int32Array` +`bin.f32Array` | consecutive 32-bit floats | `Float32Array` +`bin.f64Array` | consecutive 64-bit floats | `Float64Array` diff --git a/packages/typed-binary/src/describe/index.ts b/packages/typed-binary/src/describe/index.ts index 92ac68d..7c10d99 100644 --- a/packages/typed-binary/src/describe/index.ts +++ b/packages/typed-binary/src/describe/index.ts @@ -1,15 +1,22 @@ import { + type AnyObjectSchema, + ArraySchema, + BoolSchema, + ByteSchema, CharsSchema, + DynamicArraySchema, + Float32Schema, + GenericObjectSchema, + Int32Schema, + KeyedSchema, ObjectSchema, + OptionalSchema, + StringSchema, SubTypeKey, TupleSchema, + TypedArraySchema, + Uint32Schema, } from '../structure'; -import { ArraySchema } from '../structure/array'; -import { DynamicArraySchema } from '../structure/dynamicArray'; -import { KeyedSchema } from '../structure/keyed'; -import { type AnyObjectSchema, GenericObjectSchema } from '../structure/object'; -import { OptionalSchema } from '../structure/optional'; -import { TypedArraySchema } from '../structure/typedArray'; import type { AnySchema, AnySchemaWithProperties, @@ -19,6 +26,18 @@ import type { } from '../structure/types'; import type { MergeRecordUnion } from '../utilityTypes'; +export const bool = new BoolSchema(); + +export const string = new StringSchema(); + +export const byte = new ByteSchema(); + +export const i32 = new Int32Schema(); + +export const u32 = new Uint32Schema(); + +export const f32 = new Float32Schema(); + export const chars = (length: T) => new CharsSchema(length); export const object =

>(properties: P) => diff --git a/packages/typed-binary/src/index.ts b/packages/typed-binary/src/index.ts index 58a5522..4f2477a 100644 --- a/packages/typed-binary/src/index.ts +++ b/packages/typed-binary/src/index.ts @@ -1,7 +1,8 @@ -export * from './structure'; -export * from './describe'; -export * from './io'; -export * from './error'; +import * as bin from './main-api'; +export * from './main-api'; +export { bin }; +export default bin; +export * from './structure'; export { getSystemEndianness } from './util'; -export type { Parsed, ParseUnwrapped } from './utilityTypes'; +export type { ParseUnwrapped } from './utilityTypes'; diff --git a/packages/typed-binary/src/main-api.ts b/packages/typed-binary/src/main-api.ts new file mode 100644 index 0000000..169c045 --- /dev/null +++ b/packages/typed-binary/src/main-api.ts @@ -0,0 +1,6 @@ +export { MaxValue } from './structure'; +export * from './describe'; +export * from './io'; +export * from './error'; + +export type { Parsed } from './utilityTypes'; diff --git a/packages/typed-binary/src/structure/_internal.ts b/packages/typed-binary/src/structure/_internal.ts index f488798..d8de6f4 100644 --- a/packages/typed-binary/src/structure/_internal.ts +++ b/packages/typed-binary/src/structure/_internal.ts @@ -6,4 +6,5 @@ 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/baseTypes.ts b/packages/typed-binary/src/structure/baseTypes.ts index f530fb8..4148803 100644 --- a/packages/typed-binary/src/structure/baseTypes.ts +++ b/packages/typed-binary/src/structure/baseTypes.ts @@ -27,8 +27,6 @@ export class BoolSchema extends Schema { } } -export const bool = new BoolSchema(); - //// // STRING //// @@ -54,8 +52,6 @@ export class StringSchema extends Schema { } } -export const string = new StringSchema(); - //// // BYTE //// @@ -77,8 +73,6 @@ export class ByteSchema extends Schema { } } -export const byte = new ByteSchema(); - //// // i32 //// @@ -100,8 +94,6 @@ export class Int32Schema extends Schema { } } -export const i32 = new Int32Schema(); - //// // u32 //// @@ -123,8 +115,6 @@ export class Uint32Schema extends Schema { } } -export const u32 = new Uint32Schema(); - //// // FLOAT //// @@ -145,5 +135,3 @@ export class Float32Schema extends Schema { return measurer.add(4); } } - -export const f32 = new Float32Schema(); diff --git a/packages/typed-binary/src/structure/dynamicArray.ts b/packages/typed-binary/src/structure/dynamicArray.ts index e167c48..13d226b 100644 --- a/packages/typed-binary/src/structure/dynamicArray.ts +++ b/packages/typed-binary/src/structure/dynamicArray.ts @@ -5,7 +5,6 @@ import { Measurer, } from '../io'; import type { ParseUnwrapped } from '../utilityTypes'; -import { u32 } from './baseTypes'; import { type AnySchema, type IRefResolver, @@ -62,7 +61,7 @@ export class DynamicArraySchema extends Schema< } // Length encoding - u32.measure(values.length, measurer); + measurer.add(4); // u32 // Values encoding for (const value of values) { diff --git a/packages/typed-binary/src/structure/index.ts b/packages/typed-binary/src/structure/index.ts index 8f94685..89e8c77 100644 --- a/packages/typed-binary/src/structure/index.ts +++ b/packages/typed-binary/src/structure/index.ts @@ -1,10 +1,4 @@ export { - bool, - byte, - i32, - u32, - f32, - string, MaxValue, Ref, IRefResolver, @@ -34,4 +28,5 @@ export { SubTypeKey, OptionalSchema, TupleSchema, + TypedArraySchema, } from './_internal'; diff --git a/packages/typed-binary/src/structure/object.ts b/packages/typed-binary/src/structure/object.ts index 679dba9..66a27e3 100644 --- a/packages/typed-binary/src/structure/object.ts +++ b/packages/typed-binary/src/structure/object.ts @@ -5,7 +5,6 @@ import { Measurer, } from '../io'; import type { ParseUnwrappedRecord, Parsed } from '../utilityTypes'; -import { byte, string } from './baseTypes'; import { type AnySchema, type AnySchemaWithProperties, @@ -229,9 +228,9 @@ export class GenericObjectSchema< // We're a generic object trying to encode a concrete value. if (this.keyedBy === SubTypeKey.ENUM) { - byte.measure(0, measurer); + measurer.add(1); } else if (value !== MaxValue) { - string.measure(value.type as string, measurer); + measurer.add((value.type as string).length + 1); } else { // 'type' can be a string of any length, so the schema is unbounded. return measurer.unbounded; diff --git a/packages/typed-binary/src/test/bool.test.ts b/packages/typed-binary/src/test/bool.test.ts index 81568b1..e7e48de 100644 --- a/packages/typed-binary/src/test/bool.test.ts +++ b/packages/typed-binary/src/test/bool.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; -import { bool } from '../structure'; +import { bool } from '../describe'; import { encodeAndDecode } from './helpers/mock'; describe('BoolSchema', () => { diff --git a/packages/typed-binary/src/test/byte.test.ts b/packages/typed-binary/src/test/byte.test.ts index 6029d97..6c93aa1 100644 --- a/packages/typed-binary/src/test/byte.test.ts +++ b/packages/typed-binary/src/test/byte.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; -import { byte } from '../structure'; +import { byte } from '../describe'; import { encodeAndDecode } from './helpers/mock'; import { randIntBetween } from './random'; diff --git a/packages/typed-binary/src/test/dynamicArray.test.ts b/packages/typed-binary/src/test/dynamicArray.test.ts index bcfc014..27741af 100644 --- a/packages/typed-binary/src/test/dynamicArray.test.ts +++ b/packages/typed-binary/src/test/dynamicArray.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from 'vitest'; -import { dynamicArrayOf } from '../describe'; -import { DynamicArraySchema, MaxValue, i32 } from '../structure'; +import { dynamicArrayOf, i32 } from '../describe'; +import { DynamicArraySchema, MaxValue } from '../structure'; import { makeIO } from './helpers/mock'; import { randIntBetween } from './random'; diff --git a/packages/typed-binary/src/test/float.test.ts b/packages/typed-binary/src/test/float.test.ts index 88b44e4..577c249 100644 --- a/packages/typed-binary/src/test/float.test.ts +++ b/packages/typed-binary/src/test/float.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; -import { f32 } from '../structure'; +import { f32 } from '../describe'; import { encodeAndDecode } from './helpers/mock'; import { randBetween } from './random'; diff --git a/packages/typed-binary/src/test/int.test.ts b/packages/typed-binary/src/test/int.test.ts index c31da8f..68aeb93 100644 --- a/packages/typed-binary/src/test/int.test.ts +++ b/packages/typed-binary/src/test/int.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; -import { i32, u32 } from '../structure'; +import { i32, u32 } from '../describe'; import { encodeAndDecode } from './helpers/mock'; import { randIntBetween } from './random'; diff --git a/packages/typed-binary/src/test/keyed.test.ts b/packages/typed-binary/src/test/keyed.test.ts index eb85170..e1bbba5 100644 --- a/packages/typed-binary/src/test/keyed.test.ts +++ b/packages/typed-binary/src/test/keyed.test.ts @@ -1,7 +1,14 @@ import { describe, expect, it } from 'vitest'; -import { generic, genericEnum, keyed, object, optional } from '../describe'; -import { i32, string } from '../structure/baseTypes'; +import { + generic, + genericEnum, + i32, + keyed, + object, + optional, + string, +} from '../describe'; import type { Parsed } from '../utilityTypes'; import { encodeAndDecode } from './helpers/mock'; diff --git a/packages/typed-binary/src/test/object.test.ts b/packages/typed-binary/src/test/object.test.ts index 328c396..2337ddf 100644 --- a/packages/typed-binary/src/test/object.test.ts +++ b/packages/typed-binary/src/test/object.test.ts @@ -1,14 +1,16 @@ import { describe, expect, expectTypeOf, it } from 'vitest'; -import { concat, generic, genericEnum, object, optional } from '../describe'; import { - type ISchema, - MaxValue, - type ObjectSchema, byte, + concat, + generic, + genericEnum, i32, + object, + optional, string, -} from '../structure'; +} from '../describe'; +import { type ISchema, MaxValue, type ObjectSchema } from '../structure'; import type { Parsed } from '../utilityTypes'; import { encodeAndDecode, makeIO } from './helpers/mock'; diff --git a/packages/typed-binary/src/test/optional.test.ts b/packages/typed-binary/src/test/optional.test.ts index c41e403..43fd7d4 100644 --- a/packages/typed-binary/src/test/optional.test.ts +++ b/packages/typed-binary/src/test/optional.test.ts @@ -1,6 +1,7 @@ import { describe, expect, it } from 'vitest'; -import { OptionalSchema, i32 } from '../structure'; +import { i32 } from '../describe'; +import { OptionalSchema } from '../structure'; import { makeIO } from './helpers/mock'; import { randIntBetween } from './random'; 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 5517c2c..57bdc1e 100644 --- a/packages/typed-binary/src/test/socket-io-usage.test.ts +++ b/packages/typed-binary/src/test/socket-io-usage.test.ts @@ -5,9 +5,8 @@ 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 { dynamicArrayOf, object } from '../describe'; +import { byte, dynamicArrayOf, object, string, u32 } from '../describe'; import { BufferReader, BufferWriter } from '../io'; -import { byte, string, u32 } from '../structure'; import type { AnySchema } from '../structure/types'; import type { Parsed } from '../utilityTypes'; diff --git a/packages/typed-binary/src/test/string.test.ts b/packages/typed-binary/src/test/string.test.ts index 3719e86..0595932 100644 --- a/packages/typed-binary/src/test/string.test.ts +++ b/packages/typed-binary/src/test/string.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { string } from '../structure'; +import { string } from '../describe'; import { encodeAndDecode } from './helpers/mock'; import { randIntBetween } from './random'; diff --git a/packages/typed-binary/src/test/tuple.test.ts b/packages/typed-binary/src/test/tuple.test.ts index 3a8cbfa..7805a84 100644 --- a/packages/typed-binary/src/test/tuple.test.ts +++ b/packages/typed-binary/src/test/tuple.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from 'vitest'; -import { tupleOf } from '../describe'; -import { MaxValue, bool, i32 } from '../structure'; +import { bool, i32, tupleOf } from '../describe'; +import { MaxValue } from '../structure'; import { encodeAndDecode } from './helpers/mock'; describe('TupleSchema', () => {