{"_id":"1n-destructure","_rev":"5-b136100ac0486fada0981f861fcbd7f5","name":"1n-destructure","dist-tags":{"alpha":"0.0.1-alpha.2","latest":"0.1.0"},"versions":{"0.0.1-alpha.0":{"name":"1n-destructure","version":"0.0.1-alpha.0","keywords":["destructure","serialisation","binary-data","memory-manipulation","buffer"],"author":{"name":"Oghenevwegba Obire"},"license":"MIT","_id":"1n-destructure@0.0.1-alpha.0","maintainers":[{"name":"1natsie","email":"jesseoghenevwegba@outlook.com"}],"homepage":"https://github.com/1natsie/destructure#readme","bugs":{"url":"https://github.com/1natsie/destructure/issues"},"dist":{"shasum":"b52457b75725ca34fb77859d3c074635d40defc9","tarball":"https://registry.npmjs.org/1n-destructure/-/1n-destructure-0.0.1-alpha.0.tgz","fileCount":26,"integrity":"sha512-7meDb7RIosHhrSTAwIZ0HWEZjMB7EdkHe8ZSFn/TReXAqq4dimc192W8eu1s8Nig1xw5ojfOxvijXs+I39Kmtg==","signatures":[{"sig":"MEYCIQDgVUcCWwGfsv8Kgf76fNa2bgXoKnyCmZ3A4EDC/9jH1AIhALoQmPICpxwPVVsrNp1z9TQ2REDxclxy02szwLNlw0tf","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":56246},"type":"module","exports":{"./decode":{"types":"./dist/decoder/decoder.d.ts","import":"./dist/decoder/decoder.js"},"./encode":{"types":"./dist/encoder/encoder.d.ts","import":"./dist/encoder/encoder.js"},"./schema":{"types":"./dist/schema/schema.d.ts","import":"./dist/schema/schema.js"}},"gitHead":"009932567c5a2e6eb0b12189d3518d6b47317bf6","scripts":{"dev":"node ./scripts/dev.js","build":"node ./scripts/build.js","build:watch":"node ./scripts/build-watch.js"},"_npmUser":{"name":"1natsie","email":"jesseoghenevwegba@outlook.com"},"repository":{"url":"git+https://github.com/1natsie/destructure.git","type":"git"},"_npmVersion":"11.15.0","description":"A library for serialisation and deserialisation of structured data.","directories":{},"_nodeVersion":"25.2.1","_hasShrinkwrap":false,"devDependencies":{"prettier":"^3.8.3","typescript":"^6.0.3","@types/node":"^25.7.0"},"_npmOperationalInternal":{"tmp":"tmp/1n-destructure_0.0.1-alpha.0_1779726518878_0.9790112848892212","host":"s3://npm-registry-packages-npm-production"}},"0.0.1-alpha.1":{"name":"1n-destructure","version":"0.0.1-alpha.1","keywords":["destructure","serialisation","binary-data","memory-manipulation","performance","buffer","encoding","decoding","binary","bytes","data-schema","schema"],"author":{"name":"Oghenevwegba Obire"},"license":"MIT","_id":"1n-destructure@0.0.1-alpha.1","maintainers":[{"name":"1natsie","email":"jesseoghenevwegba@outlook.com"}],"homepage":"https://github.com/1natsie/destructure#readme","bugs":{"url":"https://github.com/1natsie/destructure/issues"},"dist":{"shasum":"11ef2d4d40a7f6a61f63ae6a2bdc4eae063d1913","tarball":"https://registry.npmjs.org/1n-destructure/-/1n-destructure-0.0.1-alpha.1.tgz","fileCount":26,"integrity":"sha512-BIpmH/bO6E8YpzfCREqoCre3jB9QDGgjdSbmTAS7PPws2QCSg8Ti9ezd6Ex95b0QUHSn49YnwP2VoHJn/wq25w==","signatures":[{"sig":"MEUCID1DUTuWt+qPKqbrJTERO5L8Xobq7BNVFfvrehTa0q4mAiEA7Excamiif3s2EIRR3/WmqXAGGRfCjTNstI/bdKm0+k0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":71486},"type":"module","exports":{"./decode":{"types":"./dist/decoder/decoder.d.ts","import":"./dist/decoder/decoder.js"},"./encode":{"types":"./dist/encoder/encoder.d.ts","import":"./dist/encoder/encoder.js"},"./schema":{"types":"./dist/schema/schema.d.ts","import":"./dist/schema/schema.js"}},"gitHead":"b67fd0e0de1386f3061946a539896d2d821e8d39","scripts":{"dev":"node ./scripts/dev.js","build":"node ./scripts/build.js","build:watch":"node ./scripts/build-watch.js"},"_npmUser":{"name":"1natsie","email":"jesseoghenevwegba@outlook.com"},"repository":{"url":"git+https://github.com/1natsie/destructure.git","type":"git"},"_npmVersion":"11.15.0","description":"A library for serialisation and deserialisation of structured data.","directories":{},"_nodeVersion":"25.2.1","_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"chai":"^6.2.2","prettier":"^3.8.3","typescript":"^6.0.3","@types/node":"^25.7.0"},"_npmOperationalInternal":{"tmp":"tmp/1n-destructure_0.0.1-alpha.1_1780094114522_0.24323461329099194","host":"s3://npm-registry-packages-npm-production"}},"0.0.1-alpha.2":{"name":"1n-destructure","version":"0.0.1-alpha.2","keywords":["destructure","serialisation","binary-data","memory-manipulation","performance","buffer","encoding","decoding","binary","bytes","data-schema","schema"],"author":{"name":"Oghenevwegba Obire"},"license":"MIT","_id":"1n-destructure@0.0.1-alpha.2","maintainers":[{"name":"1natsie","email":"jesseoghenevwegba@outlook.com"}],"homepage":"https://github.com/1natsie/destructure#readme","bugs":{"url":"https://github.com/1natsie/destructure/issues"},"dist":{"shasum":"1096e7d082f057fc8cd6be88965c3fc99ff7175c","tarball":"https://registry.npmjs.org/1n-destructure/-/1n-destructure-0.0.1-alpha.2.tgz","fileCount":26,"integrity":"sha512-t1+rs/ggf3+I9Vjme73TFDM9NL9zC17z5NSNRbKj/AsUVDj4WppVySFiGvBLWwGUuALuCCJsuJwnE6g03D3UyA==","signatures":[{"sig":"MEQCICqnmRuKt6FckImHoH5s5uPwssfN22PW0E9v1o8d9PVIAiBlc4K4UdvUouRB48RMt7d94H18B24bnjULp9f0jg02ig==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":71486},"type":"module","exports":{"./decode":{"types":"./dist/decoder/decoder.d.ts","import":"./dist/decoder/decoder.js"},"./encode":{"types":"./dist/encoder/encoder.d.ts","import":"./dist/encoder/encoder.js"},"./schema":{"types":"./dist/schema/schema.d.ts","import":"./dist/schema/schema.js"}},"gitHead":"c57dd5f43d24d0f18b119f03ff17a8c93fa9f5c8","scripts":{"dev":"node ./scripts/dev.js","build":"node ./scripts/build.js","build:watch":"node ./scripts/build-watch.js"},"_npmUser":{"name":"1natsie","email":"jesseoghenevwegba@outlook.com"},"repository":{"url":"git+https://github.com/1natsie/destructure.git","type":"git"},"_npmVersion":"11.15.0","description":"A library for serialisation and deserialisation of structured data.","directories":{},"_nodeVersion":"25.2.1","_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"chai":"^6.2.2","prettier":"^3.8.3","typescript":"^6.0.3","@types/node":"^25.7.0"},"_npmOperationalInternal":{"tmp":"tmp/1n-destructure_0.0.1-alpha.2_1780095460855_0.39699915732402546","host":"s3://npm-registry-packages-npm-production"}},"0.0.1-alpha.3":{"name":"1n-destructure","version":"0.0.1-alpha.3","keywords":["destructure","serialisation","binary-data","memory-manipulation","performance","buffer","encoding","decoding","binary","bytes","data-schema","schema"],"author":{"name":"Oghenevwegba Obire"},"license":"MIT","_id":"1n-destructure@0.0.1-alpha.3","maintainers":[{"name":"1natsie","email":"jesseoghenevwegba@outlook.com"}],"homepage":"https://github.com/1natsie/destructure#readme","bugs":{"url":"https://github.com/1natsie/destructure/issues"},"dist":{"shasum":"142bdcb33a2f9fc3888a7351c1af5a5e01fdf48c","tarball":"https://registry.npmjs.org/1n-destructure/-/1n-destructure-0.0.1-alpha.3.tgz","fileCount":26,"integrity":"sha512-aDPge1CK0hQBS/eM19213/i2l3Z4caAIgKt/oBpab++HxifUFmU8jylOacrD3fLlTXh5fbefR7JTdAtlXgt21Q==","signatures":[{"sig":"MEYCIQDnzVmOeQIf4x2ChoIYaxiC9H5AjWTMIKRpYr8/KarMTgIhAJ+jYoVpjufg84dh92NHbrJZy17Wl6AWJe1hRmYfSEEL","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":71486},"type":"module","exports":{"./decode":{"types":"./dist/decoder/decoder.d.ts","import":"./dist/decoder/decoder.js"},"./encode":{"types":"./dist/encoder/encoder.d.ts","import":"./dist/encoder/encoder.js"},"./schema":{"types":"./dist/schema/schema.d.ts","import":"./dist/schema/schema.js"}},"gitHead":"c57dd5f43d24d0f18b119f03ff17a8c93fa9f5c8","scripts":{"dev":"node ./scripts/dev.js","build":"node ./scripts/build.js","build:watch":"node ./scripts/build-watch.js"},"_npmUser":{"name":"1natsie","email":"jesseoghenevwegba@outlook.com"},"repository":{"url":"git+https://github.com/1natsie/destructure.git","type":"git"},"_npmVersion":"11.15.0","description":"A library for serialisation and deserialisation of structured data.","directories":{},"_nodeVersion":"25.2.1","_hasShrinkwrap":false,"devDependencies":{"chai":"^6.2.2","prettier":"^3.8.3","typescript":"^6.0.3","@types/node":"^25.7.0"},"_npmOperationalInternal":{"tmp":"tmp/1n-destructure_0.0.1-alpha.3_1780095615646_0.9235276391613372","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"1n-destructure","version":"0.1.0","description":"A library for serialisation and deserialisation of structured data.","homepage":"https://github.com/1natsie/destructure#readme","author":{"name":"Oghenevwegba Obire"},"license":"MIT","keywords":["destructure","serialisation","binary-data","memory-manipulation","performance","buffer","encoding","decoding","binary","bytes","data-schema","schema"],"type":"module","scripts":{"build":"rm -rf dist && npx tsc","dev":"rm -rf dist && npx tsc --watch","format":"npx prettier --write src tests","test":"node --test tests/destructure.test.ts","typecheck":"npx tsc --noEmit"},"exports":{"./decode":{"import":"./dist/decoder/decoder.js","types":"./dist/decoder/decoder.d.ts"},"./encode":{"import":"./dist/encoder/encoder.js","types":"./dist/encoder/encoder.d.ts"},"./schema":{"import":"./dist/schema/schema.js","types":"./dist/schema/schema.d.ts"}},"dependencies":{},"devDependencies":{"@types/chai":"^5.2.3","@types/node":"^26.1.2","chai":"^6.2.2","prettier":"^3.9.6","typescript":"^7.0.2"},"bugs":{"url":"https://github.com/1natsie/destructure/issues"},"repository":{"type":"git","url":"git+https://github.com/1natsie/destructure.git"},"gitHead":"c28cce1893e9b45c528ade34914f73a5c79f2c4f","_id":"1n-destructure@0.1.0","_nodeVersion":"26.7.0","_npmVersion":"12.0.2","dist":{"integrity":"sha512-k3F2Q6maCxnSTkFeh2Lb6WQ/kFpQiIfcjM779NzCDOhNs35skNLiPsmNC7vmcqs7QSlP8BMcFgAlcP7s2Ylz8w==","shasum":"85f373121e9ae742d9600f7ccb940a337ea8811c","tarball":"https://registry.npmjs.org/1n-destructure/-/1n-destructure-0.1.0.tgz","fileCount":28,"unpackedSize":124754,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCuSwi4YhQrMfUOe4FXEMJaKoGNdzdelvcP/GxVGOEndwIge6hPBI5h4DWfrBvrjhcR9zTlob3R2aK33aUOPeMhvRY="}]},"_npmUser":{"name":"1natsie","email":"jesseoghenevwegba@outlook.com"},"directories":{},"maintainers":[{"name":"1natsie","email":"jesseoghenevwegba@outlook.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/1n-destructure_0.1.0_1786371569523_0.6149203816859556"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-25T16:28:38.839Z","modified":"2026-08-10T14:19:29.796Z","0.0.1-alpha.0":"2026-05-25T16:28:39.021Z","0.0.1-alpha.1":"2026-05-29T22:35:14.659Z","0.0.1-alpha.2":"2026-05-29T22:57:40.985Z","0.0.1-alpha.3":"2026-05-29T23:00:15.768Z","0.1.0":"2026-08-10T14:19:29.665Z"},"bugs":{"url":"https://github.com/1natsie/destructure/issues"},"author":{"name":"Oghenevwegba Obire"},"license":"MIT","homepage":"https://github.com/1natsie/destructure#readme","keywords":["destructure","serialisation","binary-data","memory-manipulation","performance","buffer","encoding","decoding","binary","bytes","data-schema","schema"],"repository":{"type":"git","url":"git+https://github.com/1natsie/destructure.git"},"description":"A library for serialisation and deserialisation of structured data.","maintainers":[{"name":"1natsie","email":"jesseoghenevwegba@outlook.com"}],"readme":"# destructure\n\n[![JSR](https://jsr.io/badges/@1natsie/destructure)](https://jsr.io/@1natsie/destructure)\n[![npm version](https://img.shields.io/npm/v/1n-destructure.svg)](https://www.npmjs.com/package/1n-destructure)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n[![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)\n\nA powerful, type-safe, and high-performance TypeScript/JavaScript library for serializing and deserializing complex structured data into compact binary formats.\n\n---\n\n## Features\n\n- **⚡ Blazing Fast**: Engineered for high-throughput encoding and decoding with zero unnecessary allocations.\n- **📦 Minimal Binary Size**: Packed byte representations with explicit primitive types, string length headers, and bit packing.\n- **🛡️ Full Type Safety**: Automatic TypeScript inference for both input types (`Data.Input<typeof schema>`) and output types (`Data.Output<typeof schema>`).\n- **🧩 Rich Schema Model**: Built-in support for numeric primitives, 64-bit & 128-bit integers, floats, chars, arrays, tuples, objects, optionals, bit packing, raw byte streams, and custom encoders/decoders.\n- **🔀 Schema Composition**: Modular schema composition with `merge`, `augment`, `append`, and `concatenate`.\n- **❄️ Immutable & Pre-Compiled Schemas**: Pre-compile schemas with `schema()` for frozen, thread-safe, re-usable execution trees.\n- **🌐 Universal Runtime**: Works seamlessly in Node.js, Deno, Bun, and web browsers.\n\n---\n\n## Installation\n\n### Via JSR (Modern ESM / Deno / Bun / Node)\n\n```bash\n# Deno\ndeno add jsr:@1natsie/destructure\n\n# Node.js\nnpx jsr add @1natsie/destructure\n\n# Bun\nbunx jsr add @1natsie/destructure\n\n# pnpm\npnpm dlx jsr add @1natsie/destructure\n```\n\n### Via npm / yarn / pnpm\n\n```bash\nnpm install 1n-destructure\n```\n\n---\n\n## Quick Start\n\n```typescript\nimport { encode } from \"@1natsie/destructure/encode\";\nimport { decode } from \"@1natsie/destructure/decode\";\nimport { schema, string, optional, array, bitpack, type Data } from \"@1natsie/destructure/schema\";\n\n// 1. Define and pre-compile a schema\nconst playerSchema = schema({\n  id: \"u32\",\n  username: string.prefixedLength,\n  score: \"f64\",\n  inventory: \"u16[4]\", // Fixed-size 4-element array syntax\n  statusFlags: bitpack(8), // 8 boolean flags packed into 1 byte\n  guild: optional(string.nullTerminated), // Nullable C-style string\n});\n\n// 2. Derive TypeScript types automatically\ntype PlayerInput = Data.Input<typeof playerSchema>;\ntype PlayerOutput = Data.Output<typeof playerSchema>;\n\nconst player: PlayerInput = {\n  id: 42,\n  username: \"Alice\",\n  score: 9950.5,\n  inventory: [101, 102, 201, 305],\n  statusFlags: [true, false, true, true, false, false, true, false],\n  guild: \"Knights of Code\",\n};\n\n// 3. Encode JavaScript object into Uint8Array\nconst binary = encode(playerSchema, player);\nconsole.log(\"Encoded binary size:\", binary.length, \"bytes\");\n\n// 4. DecodeUint8Array back into typed object\nconst decoded: PlayerOutput = decode(playerSchema, binary);\nconsole.log(\"Decoded Player Username:\", decoded.username);\nconsole.log(\"Decoded Status Flags:\", decoded.statusFlags);\n```\n\n---\n\n## Core API Reference\n\n### `encode<T>(schema, data): Uint8Array`\n\nSerializes structured data into a `Uint8Array` according to the provided schema definition or pre-compiled schema.\n\n```typescript\nimport { encode } from \"@1natsie/destructure/encode\";\n\nconst binary = encode(mySchema, payload);\n```\n\n### `decode<T>(schema, buffer, offset?): Data.Output<T>`\n\nDeserializes a `Uint8Array` back into structured JavaScript data based on the schema. An optional byte `offset` (default `0`) can be specified to start decoding from a specific byte index.\n\n```typescript\nimport { decode } from \"@1natsie/destructure/decode\";\n\nconst data = decode(mySchema, binaryBuffer, 0);\n```\n\n### `schema<T>(definition): CompiledSchema<T>`\n\nPre-compiles and deeply freezes a schema definition into an immutable schema object. Pre-compiling resolves nested key ordering, parses primitive array strings, and maximizes encoding/decoding performance.\n\n```typescript\nimport { schema } from \"@1natsie/destructure/schema\";\n\nconst compiled = schema({\n  id: \"u64\",\n  title: \"char[16]\",\n});\n```\n\n---\n\n## Dedicated Schema Types & Usage Examples\n\n### 1. Primitive Numeric & Character Schemas\n\nPrimitive strings represent fixed-width numeric scalars, floating-point numbers, and individual single-byte characters.\n\n| Schema Type              | Description                              | Byte Size     | Input Type       | Output Type |\n| :----------------------- | :--------------------------------------- | :------------ | :--------------- | :---------- |\n| `\"u8\"`, `\"u16\"`, `\"u32\"` | Unsigned integers (8, 16, 32-bit)        | 1, 2, 4 bytes | `number`         | `number`    |\n| `\"i8\"`, `\"i16\"`, `\"i32\"` | Signed integers (8, 16, 32-bit)          | 1, 2, 4 bytes | `number`         | `number`    |\n| `\"f32\"`, `\"f64\"`         | Floating point (IEEE 754 float & double) | 4, 8 bytes    | `number`         | `number`    |\n| `\"char\"`                 | Single ASCII / 1-byte UTF-8 character    | 1 byte        | `string` (len 1) | `string`    |\n\n#### Usage Example\n\n```typescript\nimport { encode, decode } from \"@1natsie/destructure\";\n\nconst statsSchema = {\n  hp: \"u16\",\n  mana: \"i16\",\n  ratio: \"f32\",\n  rank: \"char\",\n};\n\nconst encoded = encode(statsSchema, {\n  hp: 65000,\n  mana: -120,\n  ratio: 3.14,\n  rank: \"S\",\n});\nconst decoded = decode(statsSchema, encoded);\n```\n\n---\n\n### 2. Large Integers (`u64`, `i64`, `u128`, `i128`)\n\nFor numbers exceeding standard JavaScript 32-bit integer limits, `destructure` provides 64-bit and 128-bit signed and unsigned integer primitives.\n\n- **Output Type**: Always decoded as a `bigint`.\n- **Input Type**: Accepts a `bigint`, a standard `number`, or an array of 32-bit unsigned integer segments (`[low, high]` for 64-bit; `[w0, w1, w2, w3]` for 128-bit).\n\n| Schema Type        | Description      | Byte Size | Input Type                                 | Output Type |\n| :----------------- | :--------------- | :-------- | :----------------------------------------- | :---------- |\n| `\"u64\"`, `\"i64\"`   | 64-bit Integers  | 8 bytes   | `bigint \\| number \\| [u32, u32]`           | `bigint`    |\n| `\"u128\"`, `\"i128\"` | 128-bit Integers | 16 bytes  | `bigint \\| number \\| [u32, u32, u32, u32]` | `bigint`    |\n\n#### Usage Example\n\n```typescript\nconst cryptoSchema = {\n  balance: \"u64\",\n  largeId: \"u128\",\n};\n\n// Input using BigInt or 32-bit segments array\nconst encoded = encode(cryptoSchema, {\n  balance: 18446744073709551615n, // 64-bit unsigned max\n  largeId: [0x76543210, 0xfedcba98, 0x89abcdef, 0x01234567], // 4 x 32-bit words\n});\n\nconst decoded = decode(cryptoSchema, encoded);\nconsole.log(typeof decoded.balance); // \"bigint\"\nconsole.log(decoded.balance); // 18446744073709551615n\n```\n\n---\n\n### 3. Primitive Array Shorthand Syntax\n\nYou can append `[]` (dynamic array) or `[N]` (fixed-length array) to any primitive type string.\n\n- **Fixed-size array (`\"type[N]\"`)**: Encodes exactly `N` elements without length overhead.\n- **Dynamic array (`\"type[]\"`)**: Encodes a 4-byte `uint32` length prefix followed by the array elements.\n\n#### Usage Example\n\n```typescript\nconst vectorSchema = {\n  position: \"f32[3]\", // Fixed 3-element array of floats\n  matrix: \"i16[9]\", // Fixed 9-element array\n  readings: \"u8[]\", // Dynamic length-prefixed byte array\n  initials: \"char[3]\", // Fixed 3-character tuple\n};\n\nconst encoded = encode(vectorSchema, {\n  position: [1.0, 2.0, 3.0],\n  matrix: [1, 0, 0, 0, 1, 0, 0, 0, 1],\n  readings: [10, 20, 30, 40, 50],\n  initials: [\"J\", \"D\", \"O\"],\n});\n```\n\n---\n\n### 4. Objects (Deterministic Key Ordering)\n\nPlain JavaScript objects define key-value structures.\n\n> **Note on Key Ordering**: Object keys are **automatically sorted in lexicographical (alphabetical) order** during schema processing and binary encoding. This guarantees deterministic binary output regardless of JavaScript object key insert ordering.\n\n#### Usage Example\n\n```typescript\nconst userSchema = {\n  username: \"char[8]\",\n  id: \"u32\",\n  active: \"u8\",\n};\n\n// Key order in object payload does not affect encoded binary layout\nconst encoded = encode(userSchema, {\n  active: 1,\n  id: 100,\n  username: [\"A\", \"l\", \"i\", \"c\", \"e\", \" \", \" \", \" \"],\n});\n```\n\n---\n\n### 5. Tuples\n\nTuples are fixed-length ordered arrays of heterogeneous schemas defined using JavaScript arrays with `as const`.\n\n#### Usage Example\n\n```typescript\nconst point3DSchema = [\"f64\", \"f64\", \"f64\"] as const;\n\nconst recordSchema = {\n  header: [\"u8\", \"u16\"] as const,\n  location: point3DSchema,\n};\n\nconst encoded = encode(recordSchema, {\n  header: [1, 200],\n  location: [12.34, 56.78, 90.12],\n});\n```\n\n---\n\n### 6. Complex Arrays (`array`)\n\nUse the `array(elementSchema, count?)` helper to create arrays of complex nested schemas (objects, tuples, optionals, custom types).\n\n- `count` omitted (or `-1`): Dynamic length-prefixed array (4-byte `u32` header).\n- `count >= 0`: Fixed-length array of exactly `count` elements.\n\n#### Usage Example\n\n```typescript\nimport { array, string } from \"@1natsie/destructure/schema\";\n\nconst itemSchema = {\n  id: \"u32\",\n  name: string.prefixedLength,\n};\n\nconst inventorySchema = {\n  // Dynamic array of items\n  items: array(itemSchema),\n  // Fixed array of 2 equipment items\n  equipment: array(itemSchema, 2),\n};\n\nconst encoded = encode(inventorySchema, {\n  items: [\n    { id: 1, name: \"Health Potion\" },\n    { id: 2, name: \"Mana Potion\" },\n  ],\n  equipment: [\n    { id: 10, name: \"Iron Sword\" },\n    { id: 11, name: \"Wooden Shield\" },\n  ],\n});\n```\n\n---\n\n### 7. Bitpacking (`bitpack`)\n\nThe `bitpack(bitCount)` helper packs boolean arrays densely into bytes (8 booleans per byte, ordered from Most Significant Bit to Least Significant Bit).\n\n- Input / Output: `boolean[]` with length equal to `bitCount`.\n- Byte Size: `Math.ceil(bitCount / 8)` bytes.\n\n#### Usage Example\n\n```typescript\nimport { bitpack } from \"@1natsie/destructure/schema\";\n\n// Pack 10 boolean flags into 2 bytes (16 bits)\nconst flagsSchema = bitpack(10);\n\nconst flags = [true, false, true, true, false, false, false, true, false, true];\n\nconst encoded = encode(flagsSchema, flags);\nconsole.log(encoded.length); // 2 bytes instead of 10 bytes!\n\nconst decoded = decode(flagsSchema, encoded);\nconsole.log(decoded); // Array of 10 boolean values\n```\n\n---\n\n### 8. Optional Fields (`optional`)\n\nWrap any schema with `optional(innerSchema)` to allow `null` or `undefined` values.\n\n- Presence Flag: Encodes a 1-byte boolean (`1` if present, `0` if absent).\n- If present, the inner value is encoded immediately after the flag.\n- Output: Returns the decoded value or `null`.\n\n#### Usage Example\n\n```typescript\nimport { optional, string } from \"@1natsie/destructure/schema\";\n\nconst profileSchema = {\n  userId: \"u32\",\n  bio: optional(string.prefixedLength),\n  secondaryEmail: optional(string.nullTerminated),\n};\n\nconst encoded = encode(profileSchema, {\n  userId: 42,\n  bio: null, // Encodes byte flag 0\n  secondaryEmail: \"alt@example.com\", // Encodes byte flag 1 + string bytes\n});\n\nconst decoded = decode(profileSchema, encoded);\nconsole.log(decoded.bio); // null\n```\n\n---\n\n### 9. Raw Bytes & Strings (`bytes`, `string`)\n\nBuilt-in custom schemas for raw byte buffers and UTF-8 strings.\n\n- **`bytes`**: Accepts `Uint8Array` or `ArrayLike<number>`. Encodes a 4-byte uint32 length header followed by raw bytes. Returns `Uint8Array`.\n- **`string.prefixedLength`**: Length-prefixed UTF-8 string (4-byte length header + UTF-8 payload).\n- **`string.nullTerminated`**: C-style UTF-8 string terminated by a `\\0` null byte.\n\n#### Usage Example\n\n```typescript\nimport { bytes, string } from \"@1natsie/destructure/schema\";\n\nconst payloadSchema = {\n  rawBuffer: bytes,\n  title: string.prefixedLength,\n  cString: string.nullTerminated,\n};\n\nconst encoded = encode(payloadSchema, {\n  rawBuffer: new Uint8Array([0xde, 0xad, 0xbe, 0xef]),\n  title: \"Hello World 🔥\",\n  cString: \"Null terminated string\",\n});\n```\n\n---\n\n### 10. Custom Schemas (`custom`)\n\nCreate domain-specific custom encoders and decoders for types such as `Date`, custom classes, compressed data, or third-party formats.\n\n```typescript\nimport { custom } from \"@1natsie/destructure/schema\";\n\n// Custom schema handler for JavaScript Date objects (stored as 64-bit int ms)\nconst dateSchema = custom<Date>({\n  encode: (date) => {\n    const buf = new Uint8Array(8);\n    new DataView(buf.buffer).setBigInt64(0, BigInt(date.getTime()), true);\n    return buf;\n  },\n  decode: (bytes, offset) => {\n    const timestamp = bytes.view.getBigInt64(offset, true);\n    return {\n      value: new Date(Number(timestamp)),\n      nextOffset: offset + 8,\n    };\n  },\n  size: () => ({ min: 8, max: 8 }),\n});\n\n// Usage\nconst eventSchema = {\n  eventId: \"u32\",\n  timestamp: dateSchema,\n};\n\nconst encoded = encode(eventSchema, {\n  eventId: 1001,\n  timestamp: new Date(\"2026-01-01T00:00:00Z\"),\n});\n```\n\n---\n\n### 11. Schema Composition (`combine`)\n\nThe `combine` namespace provides functional combinators to merge, extend, or join schemas safely.\n\n#### `combine.merge(schemaA, schemaB)`\n\nMerges two object schemas. Fields in `schemaB` overwrite matching fields in `schemaA`.\n\n#### `combine.augment(schemaA, schemaB)`\n\nAugments `schemaA` with fields from `schemaB`. Fields in `schemaA` take precedence.\n\n#### `combine.append(schemaA, schemaB)`\n\nAppends two disjoint object schemas. Throws a `ReferenceError` if duplicate keys exist.\n\n#### `combine.concatenate(tupleA, tupleB)`\n\nConcatenates two tuple schemas in order `[...tupleA, ...tupleB]`.\n\n#### Usage Example\n\n```typescript\nimport { combine, schema } from \"@1natsie/destructure/schema\";\n\nconst baseEntity = schema({ id: \"u32\", createdAt: \"u64\" });\nconst userFields = schema({ username: \"u8[16]\", email: \"u8[32]\" });\nconst auditFields = schema({ createdAt: \"f64\" }); // Overwrites createdAt type\n\n// 1. Merge (userFields + auditFields overwriting createdAt)\nconst merged = combine.merge(baseEntity, auditFields);\n\n// 2. Append disjoint schemas\nconst userSchema = combine.append(baseEntity, userFields);\n\n// 3. Concatenate tuples\nconst tupleA = [\"u8\", \"u16\"] as const;\nconst tupleB = [\"f32\", \"f64\"] as const;\nconst combinedTuple = combine.concatenate(tupleA, tupleB);\n```\n\n---\n\n## TypeScript Type Inference (`Data.Input` & `Data.Output`)\n\nUse `Data.Input<typeof schema>` and `Data.Output<typeof schema>` to extract TypeScript types directly from your schema definitions.\n\n```typescript\nimport { schema, string, optional, type Data } from \"@1natsie/destructure/schema\";\n\nconst productSchema = schema({\n  sku: \"u32\",\n  name: string.prefixedLength,\n  discount: optional(\"f32\"),\n});\n\n// Input type for encoding\ntype ProductInput = Data.Input<typeof productSchema>;\n// Equivalent to:\n// { sku: number; name: string; discount?: number | null }\n\n// Output type for decoding\ntype ProductOutput = Data.Output<typeof productSchema>;\n// Equivalent to:\n// { sku: number; name: string; discount: number | null }\n```\n\n---\n\n## Running Tests\n\nRun the comprehensive unit test suite to verify encoding and decoding behavior across all schema types:\n\n```bash\nnpm test\n```\n\n---\n\n## License\n\n[MIT](LICENSE) © Oghenevwegba Obire\n","readmeFilename":"README.md"}