diff --git a/apps/typed-binary-docs/astro.config.mjs b/apps/typed-binary-docs/astro.config.mjs index 70f39dd..5a1b10d 100644 --- a/apps/typed-binary-docs/astro.config.mjs +++ b/apps/typed-binary-docs/astro.config.mjs @@ -1,6 +1,5 @@ import starlight from '@astrojs/starlight'; import { defineConfig } from 'astro/config'; -import starlightTypeDoc, { typeDocSidebarGroup } from 'starlight-typedoc'; // https://astro.build/config export default defineConfig({ @@ -17,29 +16,26 @@ export default defineConfig({ github: 'https://github.com/iwoplaza/typed-binary', }, sidebar: [ - { - label: 'Guides', - items: [ - // Each item here is one entry in the navigation menu. - { label: 'Why Typed Binary?', slug: 'guides/why-typed-binary' }, - { label: 'Getting Started', slug: 'guides/getting-started' }, - ], - }, + { label: 'Why Typed Binary?', slug: 'guides/why-typed-binary' }, { label: 'Learn the Basics', items: [ - // Each item here is one entry in the navigation menu. { label: 'Getting Started', slug: 'guides/getting-started' }, + { + label: 'Serialization and Deserialization', + slug: 'guides/serialization-and-deserialization', + }, + { label: 'Primitive Values', slug: 'guides/primitive-values' }, + { label: 'Objects', slug: 'guides/objects' }, + { label: 'Arrays and Tuples', slug: 'guides/arrays-and-tuples' }, + { label: 'Optionals', slug: 'guides/optionals' }, + { label: 'Recursive Types', slug: 'guides/recursive-types' }, + { + label: 'Custom Schema Types', + slug: 'guides/custom-schema-types', + }, ], }, - typeDocSidebarGroup, - ], - plugins: [ - // Generate the documentation. - starlightTypeDoc({ - entryPoints: ['../../packages/typed-binary/src'], - tsconfig: '../../packages/typed-binary/tsconfig.json', - }), ], }), ], diff --git a/apps/typed-binary-docs/package.json b/apps/typed-binary-docs/package.json index c9d9b3a..7a57b7c 100644 --- a/apps/typed-binary-docs/package.json +++ b/apps/typed-binary-docs/package.json @@ -14,9 +14,6 @@ "@astrojs/starlight": "^0.25.1", "astro": "^4.10.2", "sharp": "^0.32.5", - "starlight-typedoc": "^0.13.1", - "typedoc": "^0.26.5", - "typedoc-plugin-markdown": "^4.2.3", "typescript": "^5.5.3" } } 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 new file mode 100644 index 0000000..9225aef --- /dev/null +++ b/apps/typed-binary-docs/src/content/docs/guides/arrays-and-tuples.mdx @@ -0,0 +1,40 @@ +--- +title: Arrays and Tuples +description: A guide on how arrays and tuples can be represented in Typed Binary +--- + +## Arrays + +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 = arrayOf(f32, 2); +const Vector3 = arrayOf(f32, 3); +const Vector4 = arrayOf(f32, 4); +``` + +## Dynamic Arrays + +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 = dynamicArrayOf(i32); +``` + +## Tuple + +Encodes an ordered set of schemas, one next to another. + +```ts +import { f32, string, tupleOf } from 'typed-binary'; + +const Vec3f = tupleOf([f32, f32, f32]); +type Vec3f = Parsed; // [number, number, number] + +const RecordEntry = tupleOf([string, Vec3f]); +type RecordEntry = Parsed; // [string, [number, number, number]] +``` diff --git a/apps/typed-binary-docs/src/content/docs/guides/custom-schema-types.mdx b/apps/typed-binary-docs/src/content/docs/guides/custom-schema-types.mdx new file mode 100644 index 0000000..b27c59c --- /dev/null +++ b/apps/typed-binary-docs/src/content/docs/guides/custom-schema-types.mdx @@ -0,0 +1,51 @@ +--- +title: Custom Schema Types +description: A guide on how to create custom schema types in Typed Binary +--- + +Custom schema types can be defined. They are, under the hood, classes that extend the `Schema` base class. The generic `T` type represents what kind of data this schema serializes from and deserializes into. + +```ts +import { + ISerialInput, + ISerialOutput, + Schema, + IRefResolver, +} from 'typed-binary'; + +/** + * A schema storing radians with 2 bytes of precision. + */ +class RadiansSchema extends Schema { + read(input: ISerialInput): number { + const low = input.readByte(); + const high = input.readByte(); + + const discrete = (high << 8) | low; + return (discrete / 65535) * Math.PI; + } + + write(output: ISerialOutput, value: number): void { + // The value will be wrapped to be in range of [0, Math.PI) + const wrapped = ((value % Math.PI) + Math.PI) % Math.PI; + // Quantizing the value to range of [0, 65535] + const discrete = Math.min(Math.floor((wrapped / Math.PI) * 65535), 65535); + + const low = discrete & 0xff; + const high = (discrete >> 8) & 0xff; + + output.writeByte(low); + output.writeByte(high); + } + + measure(_: number, measurer: IMeasurer = new Measurer()): IMeasurer { + // The size of the data serialized by this schema + // doesn't depend on the actual value. It's always 2 bytes. + return measurer.add(2); + } +} + +// Creating a singleton instance of the schema, +// since it has no configuration properties. +export const radians = new RadiansSchema(); +``` 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 e715280..d464a1a 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 @@ -27,3 +27,29 @@ import { Tabs, TabItem } from '@astrojs/starlight/components'; ``` + +## Use in the browser + +```ts {7} +import { tupleOf, f32, MaxValue, BufferWriter } from 'typed-binary'; + +// Define a schema +const Vec2f = tupleOf([f32, f32]); +const Vec2fSize = Vec2f.measure(MaxValue).size; + +const buffer = new ArrayBuffer(Vec2fSize); +Vec2f.write(new BufferWriter(buffer), [0.5, 3.14]); +``` + +## Use in Node.js + +```ts {7} +import { tupleOf, f32, MaxValue, BufferWriter } from 'typed-binary'; + +// Define a schema +const Vec2f = tupleOf([f32, f32]); +const Vec2fSize = Vec2f.measure(MaxValue).size; + +const buffer = Buffer.alloc(Vec2fSize); +Vec2f.write(new 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 new file mode 100644 index 0000000..180956a --- /dev/null +++ b/apps/typed-binary-docs/src/content/docs/guides/objects.mdx @@ -0,0 +1,146 @@ +--- +title: Objects +description: Objects store their properties in key-ascending-alphabetical order, one next to another. +--- + +Primitive values in JavaScript can be composed into *Plain-Old-JavaScript-Objects*. This can be +easily represented using the `object()` schema constructor function. + +## Simple objects + +```ts +import { i32, string, object } from 'typed-binary'; + +// Simple object schema +const Person = object({ + firstName: string, + lastName: string, + age: i32, +}); + +// Writing a Person +Person.write(writer, { + firstName: 'John', + lastName: 'Doe', + age: 43, +}); + +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. +::: + +## Generic objects + +This feature allows for the parsing of a type that contains different fields depending on its previous values. For example, if you want to store an animal description, certain animal types might have differing features from one another. + +### Keyed by strings + +```ts +import { + i32, + string, + bool, + generic, + object, +} from 'typed-binary'; + +// Generic object schema +const Animal = generic( + { + nickname: string, + age: i32, + }, + { + dog: object({ + // Animal can be a dog + breed: string, + }), + cat: object({ + // Animal can be a cat + striped: bool, + }), + } +); + +// Writing an Animal +Animal.write(writer, { + type: 'cat', // We're specyfing which concrete type we want this object to be. + + // Base properties + nickname: 'James', + age: 5, + + // Concrete type specific properties + striped: true, +}); + +// Deserializing the animal +const animal = Animal.read(reader); +console.log(JSON.stringify(animal)); // { "age": 5, "striped": true ... } + +// -- Type checking works here! -- +// animal.type => 'cat' | 'dog' +if (animal.type === 'cat') { + // animal.type => 'cat' + console.log("It's a cat!"); + // animal.striped => bool + console.log(animal.striped ? 'Striped' : 'Not striped'); +} else { + // animal.type => 'dog' + console.log("It's a dog!"); + // animal.breed => string + console.log(`More specifically, a ${animal.breed}`); + + // This would result in a type error (Static typing FTW!) + // console.log(`Striped: ${animal.striped}`); +} +``` + +### Keyed by an enum (byte) + +```ts +import { BufferWriter, BufferReader, i32, string, genericEnum, object } from 'typed-binary'; + +enum AnimalType = { + DOG = 0, + CAT = 1, +}; + +// Generic (enum) object schema +const Animal = genericEnum({ + nickname: string, + age: i32, +}, { + [AnimalType.DOG]: object({ // Animal can be a dog + breed: string, + }), + [AnimalType.CAT]: object({ // Animal can be a cat + striped: bool, + }), +}); + +// ... +// Same as for the string keyed case +// ... + +// -- Type checking works here! -- +// animal.type => AnimalType +if (animal.type === AnimalType.CAT) { + // animal.type => AnimalType.CAT + console.log("It's a cat!"); + // animal.striped => bool + console.log(animal.striped ? "Striped" : "Not striped"); +} +else { + // animal.type => AnimalType.DOG + console.log("It's a dog!"); + // animal.breed => string + console.log(`More specifically, a ${animal.breed}`); + + // This would result in a type error (Static typing FTW!) + // console.log(`Striped: ${animal.striped}`); +} +``` diff --git a/apps/typed-binary-docs/src/content/docs/guides/optionals.mdx b/apps/typed-binary-docs/src/content/docs/guides/optionals.mdx new file mode 100644 index 0000000..fb382bd --- /dev/null +++ b/apps/typed-binary-docs/src/content/docs/guides/optionals.mdx @@ -0,0 +1,63 @@ +--- +title: Optionals +description: A guide on how optionals can be used to create variable-length schemas. +--- + +Optionals are a good way of ensuring that no excessive data is stored as binary. + +They are encoded as: + +- `0` given `value === undefined`. +- `1 encoded(value)` given `value !== undefined`. + +```ts +import { + BufferWriter, + BufferReader, + i32, + string, + object, + optional, +} from 'typed-binary'; + +const buffer = Buffer.alloc(16); +const writer = new BufferWriter(buffer); +const reader = new BufferReader(buffer); + +// Simple object schema +const Address = object({ + city: string, + street: string, + postalCode: string, +}); + +// Simple object schema (with optional field) +const Person = object({ + firstName: string, + lastName: string, + age: i32, + address: optional(Address), +}); + +// Writing a Person (no address) +Person.write(writer, { + firstName: 'John', + lastName: 'Doe', + age: 43, +}); + +// Writing a Person (with an address) +Person.write(writer, { + firstName: 'Jesse', + lastName: 'Doe', + age: 38, + address: { + city: 'New York', + street: 'Binary St.', + postalCode: '11-111', + }, +}); + +console.log(JSON.stringify(Person.read(reader).address)); // undefined +console.log(JSON.stringify(Person.read(reader).address)); // { "city": "New York", ... } +``` 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 new file mode 100644 index 0000000..6e345a6 --- /dev/null +++ b/apps/typed-binary-docs/src/content/docs/guides/primitive-values.mdx @@ -0,0 +1,33 @@ +--- +title: Primitive Values +description: There are a few primitives to choose from in Typed Binary, here is a quick rundown. +--- + +There are a few primitives to choose from: + +- `bool` is an 8-bit value representing either `true` or `false`. + - Encoded as `1` if true, and as `0` if false. +- `byte` is an 8-bit value representing an unsigned number between 0 and 255. + - Encoded as-is +- `i32` is a 32-bit signed integer number container. + - Encoded as-is +- `f32` is a 32-bit signed floating-point number container. + - Encoded as-is +- `string` is a variable-length string of ASCII characters. + - A string of characters followed by a `\0` terminal character. + +```ts +import { BufferWriter, BufferReader, byte, string } 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 reader = new BufferReader(buffer); +console.log(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 new file mode 100644 index 0000000..3cfb92b --- /dev/null +++ b/apps/typed-binary-docs/src/content/docs/guides/recursive-types.mdx @@ -0,0 +1,70 @@ +--- +title: Recursive Types +description: A guide on how to describe recursive types in Typed Binary +--- + +If you want an object type to be able to contain one of itself (recursion), then you have to start using **keyed** types. The basic pattern is this: + +```ts +/** + * Wrapping a schema with a 'keyed' call allows the inner code to + * use a reference to the type we're currently creating, instead + * of the type itself. + * + * The reference variable 'Recursive' doesn't have to be called + * the same as the actual variable we're storing the schema in, + * but it's a neat trick that makes the schema code more readable. + * + * The 'recursive-key' has to uniquely identify this type in this tree. + * There may be other distinct types using the same key, as long as they do + * not interact with each other (one doesn't contain the other). + * 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), + }) +); +``` + +### Recursive types alongside generics + +```ts +import { i32, string, object, keyed } from 'typed-binary'; + +type Expression = Parsed; +const Expression = keyed('expression', (Expression) => + generic( + {}, + { + multiply: object({ + a: Expression, + b: Expression, + }), + negate: object({ + inner: Expression, + }), + int_literal: object({ + value: i32, + }), + } + ) +); + +const expr: Parsed = { + type: 'multiply', + a: { + type: 'negate', + inner: { + type: 'int_literal', + value: 15, + }, + }, + b: { + type: 'int_literal', + value: 2, + }, +}; +``` 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 new file mode 100644 index 0000000..67adb85 --- /dev/null +++ b/apps/typed-binary-docs/src/content/docs/guides/serialization-and-deserialization.mdx @@ -0,0 +1,84 @@ +--- +title: Serialization and Deserialization +description: A guide on how to serialize and deserialize values in Typed Binary. +--- + +Each schema has the following methods: + +```ts +/** + * Writes the value (according to the schema's structure) to the output. + */ +write(output: ISerialOutput, value: T): void; + +/** + * Reads a value (according to the schema's structure) from the input. + */ +read(input: ISerialInput): T; + +/** + * Estimates the size of the value (according to the schema's structure) + */ +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'; + +// 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 +``` + +### Creating a buffer with the most optimal size + +Schemas can measure how many bytes a particular value will take up, which can be used +to create a buffer that will fit that value perfectly. + +```ts +import { object, u32, f32 } from 'typed-binary'; + +export const PlayerUpdatePacket = object({ + id: u32, + x: f32, + y: f32, +}); + +const packet = { + id: 0, + x: 2.4, + y: 1.6, +} as const; + +const packetSize = PlayerUpdatePacket.measure(packet).size; +const buffer = Buffer.alloc(packetSize); // or new ArrayBuffer(packetSize) on the browser +``` + +### Creating a shared buffer that fits all possible values + +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'; + +export const PlayerUpdatePacket = object({ + id: u32, + x: f32, + y: f32, +}); + +const maxPacketSize = PlayerUpdatePacket.measure(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/why-typed-binary.mdx b/apps/typed-binary-docs/src/content/docs/guides/why-typed-binary.mdx index 180d173..70d0820 100644 --- a/apps/typed-binary-docs/src/content/docs/guides/why-typed-binary.mdx +++ b/apps/typed-binary-docs/src/content/docs/guides/why-typed-binary.mdx @@ -1,43 +1,20 @@ --- title: Why Typed Binary? -description: Here is how Typed Binary can be used in your project, and what are its strengths. +description: Here is how Typed Binary can be used in your project, and what its strength are. --- -## Prioritising developer experience - -Serialise and deserialise typed schemas without the need for redundant interfaces or an external DSL. +**Typed Binary** introduces a composable TypeScript API for defining how JavaScript values are encoded into binary, and decoded from binary. +No need for manual type definitions or an external DSL. Schemas themselves define what type they encode and decode, and **your IDE knows it**! -```ts -// schema.ts - -import { object, u32, f32 } from 'typed-binary'; - -const vec2f = tupleOf([f32, f32]); - -export const PlayerUpdatePacket = object({ - id: u32, - pos: vec2f, -}); - -``` - -```ts -// main.ts -import { BufferWriter } from 'typed-binary'; -import { PlayerUpdatePacket } from './schema.ts'; +#### Customizable, with good defaults -const buffer = new ArrayBuffer(64); +Schemas can be simple primitives (integers, floats, null-terminated strings, and many more) or compositions +in the form of arrays or objects. Custom schema types can also be made to further customize the encoding and +decoding. -PlayerUpdatePacket.write( - new BufferWriter(buffer), - // Only accepts values that match the schema: - // { id: number, pos: [number, number] } - { - id: 0, - pos: [0.5, 3.14], - } -); -``` +#### Binary protocols no longer a last resort +**Typed Binary** aims to be environment agnostic, so schemas can be shared between the server and client to easily transport +compact binary packets when the network bandwith is of utmost importance. diff --git a/apps/typed-binary-docs/src/content/docs/index.mdx b/apps/typed-binary-docs/src/content/docs/index.mdx index 5859c65..407a2b5 100644 --- a/apps/typed-binary-docs/src/content/docs/index.mdx +++ b/apps/typed-binary-docs/src/content/docs/index.mdx @@ -15,22 +15,3 @@ hero: link: https://github.com/iwoplaza/typed-binary icon: external --- - -import { Card, CardGrid } from '@astrojs/starlight/components'; - -## Next steps - - - - Edit `src/content/docs/index.mdx` to see this page change. - - - Add Markdown or MDX files to `src/content/docs` to create new pages. - - - Edit your `sidebar` and other config in `astro.config.mjs`. - - - Learn more in [the Starlight Docs](https://starlight.astro.build/). - - diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e30cb43..6aecb11 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -66,15 +66,6 @@ importers: sharp: specifier: ^0.32.5 version: 0.32.6 - starlight-typedoc: - specifier: ^0.13.1 - version: 0.13.1(@astrojs/starlight@0.25.1)(astro@4.12.2)(typedoc-plugin-markdown@4.2.3)(typedoc@0.26.5) - typedoc: - specifier: ^0.26.5 - version: 0.26.5(typescript@5.5.3) - typedoc-plugin-markdown: - specifier: ^4.2.3 - version: 4.2.3(typedoc@0.26.5) typescript: specifier: ^5.5.3 version: 5.5.3 @@ -2027,6 +2018,7 @@ packages: /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true /bare-events@2.4.2: resolution: {integrity: sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==} @@ -2138,6 +2130,7 @@ packages: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} dependencies: balanced-match: 1.0.2 + dev: true /braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} @@ -3788,12 +3781,6 @@ packages: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} dev: true - /linkify-it@5.0.0: - resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} - dependencies: - uc.micro: 2.1.0 - dev: false - /listr2@3.14.0(enquirer@2.4.1): resolution: {integrity: sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==} engines: {node: '>=10.0.0'} @@ -3903,10 +3890,6 @@ packages: yallist: 3.1.1 dev: false - /lunr@2.3.9: - resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} - dev: false - /magic-string@0.30.10: resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} dependencies: @@ -3917,18 +3900,6 @@ packages: engines: {node: '>=16'} dev: false - /markdown-it@14.1.0: - resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} - hasBin: true - dependencies: - argparse: 2.0.1 - entities: 4.5.0 - linkify-it: 5.0.0 - mdurl: 2.0.0 - punycode.js: 2.3.1 - uc.micro: 2.1.0 - dev: false - /markdown-table@3.0.3: resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==} dev: false @@ -4151,10 +4122,6 @@ packages: '@types/mdast': 4.0.4 dev: false - /mdurl@2.0.0: - resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} - dev: false - /merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -4545,6 +4512,7 @@ packages: engines: {node: '>=16 || 14 >=14.17'} dependencies: brace-expansion: 2.0.1 + dev: true /minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -5008,11 +4976,6 @@ packages: end-of-stream: 1.4.4 once: 1.4.0 - /punycode.js@2.3.1: - resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} - engines: {node: '>=6'} - dev: false - /punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -5623,22 +5586,6 @@ packages: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} dev: true - /starlight-typedoc@0.13.1(@astrojs/starlight@0.25.1)(astro@4.12.2)(typedoc-plugin-markdown@4.2.3)(typedoc@0.26.5): - resolution: {integrity: sha512-nA85YXTPjL96CJkKxsCTdIBLT3051sfFvkajbEHjJ9GfW96nBF2qIL7NxOuFP4otDxS2ZFGSvvkkF7EwzOWj3w==} - engines: {node: '>=18.14.1'} - peerDependencies: - '@astrojs/starlight': '>=0.15.0' - astro: '>=4.0.0' - typedoc: '>=0.26.0' - typedoc-plugin-markdown: '>=4.0.0' - dependencies: - '@astrojs/starlight': 0.25.1(astro@4.12.2) - astro: 4.12.2(@types/node@20.14.11)(typescript@5.5.3) - github-slugger: 2.0.0 - typedoc: 0.26.5(typescript@5.5.3) - typedoc-plugin-markdown: 4.2.3(typedoc@0.26.5) - dev: false - /std-env@3.7.0: resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} dev: true @@ -6006,30 +5953,6 @@ packages: engines: {node: '>=12.20'} dev: false - /typedoc-plugin-markdown@4.2.3(typedoc@0.26.5): - resolution: {integrity: sha512-esucQj79SFYOv0f5XVha7QWdLUH5C5HRlDf7Z8CXzHedmVPn7jox6Gt7FdoBXN8AFxyHpa3Lbuxu65Dobwt+4Q==} - engines: {node: '>= 18'} - peerDependencies: - typedoc: 0.26.x - dependencies: - typedoc: 0.26.5(typescript@5.5.3) - dev: false - - /typedoc@0.26.5(typescript@5.5.3): - resolution: {integrity: sha512-Vn9YKdjKtDZqSk+by7beZ+xzkkr8T8CYoiasqyt4TTRFy5+UHzL/mF/o4wGBjRF+rlWQHDb0t6xCpA3JNL5phg==} - engines: {node: '>= 18'} - hasBin: true - peerDependencies: - typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x - dependencies: - lunr: 2.3.9 - markdown-it: 14.1.0 - minimatch: 9.0.5 - shiki: 1.10.3 - typescript: 5.5.3 - yaml: 2.4.5 - dev: false - /typesafe-path@0.2.2: resolution: {integrity: sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA==} dev: false @@ -6045,10 +5968,6 @@ packages: engines: {node: '>=14.17'} hasBin: true - /uc.micro@2.1.0: - resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} - dev: false - /ufo@1.5.3: resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} dev: true @@ -6626,6 +6545,7 @@ packages: resolution: {integrity: sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==} engines: {node: '>= 14'} hasBin: true + dev: true /yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}