{"_id":"@athanx/asun","_rev":"7-f1eff51983c4be81863cf9976bfac99f","name":"@athanx/asun","dist-tags":{"latest":"1.0.5"},"versions":{"1.0.1":{"name":"@athanx/asun","version":"1.0.1","keywords":["asun","serialization","schema","llm","data-format"],"license":"MIT","_id":"@athanx/asun@1.0.1","maintainers":[{"name":"athanx","email":"athanseal@gmail.com"}],"homepage":"https://github.com/asun-lab/asun-js#readme","bugs":{"url":"https://github.com/asun-lab/asun-js/issues"},"dist":{"shasum":"124494e481b52c92e66c03ac524fd471c639f388","tarball":"https://registry.npmjs.org/@athanx/asun/-/asun-1.0.1.tgz","fileCount":2,"integrity":"sha512-xzkRS9UURvvyFeuzVxMJ063pZ2IuYac3Y81j/oBD0cuFDS3mfF33jQ5R8mP87O0TN3RJcEviNERGPfzVeTKUJA==","signatures":[{"sig":"MEYCIQDshv7Qc2kewEMX0pScFsiAv1syUESeGOZYo1/0AQx6RwIhAO6c/AC0j7AEAdvi0nSDzdE7OorhlDdYLZcytfPbFOgN","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":10802},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"scripts":{"test":"vitest run","build":"tsc --emitDeclarationOnly && node build.mjs","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"athanx","email":"athanseal@gmail.com"},"repository":{"url":"git+https://github.com/asun-lab/asun-js.git","type":"git","directory":"asun-js"},"_npmVersion":"11.11.0","description":"ASUN (Array-Schema Unified Notation) – high-performance, schema-driven data format for JS/TS","directories":{},"sideEffects":false,"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","esbuild":"^0.24.0","typescript":"^5.7.0"},"_npmOperationalInternal":{"tmp":"tmp/asun_1.0.1_1776464561288_0.37922467769384793","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@athanx/asun","version":"1.0.2","keywords":["asun","serialization","schema","llm","data-format"],"license":"MIT","_id":"@athanx/asun@1.0.2","maintainers":[{"name":"athanx","email":"athanseal@gmail.com"}],"homepage":"https://github.com/asunLab/asun-js#readme","bugs":{"url":"https://github.com/asunLab/asun-js/issues"},"dist":{"shasum":"3d2bbf632b96d9b6c321d8cffc1c78406ab62b6a","tarball":"https://registry.npmjs.org/@athanx/asun/-/asun-1.0.2.tgz","fileCount":6,"integrity":"sha512-VruxqgRfsyXFzE3jtNeV8ixdDT5MiQoCYjDfOhG74FOPyuL7iIoOp1MRL1RVObUr9kPxHC6w3dAhqdi1Fe+4ng==","signatures":[{"sig":"MEYCIQDZTHe7rf+s5U62En1et1Zb8BqXKcLeBJ+dZmPrD4/lAAIhAN/Hk0Ecp5w7qFuNA87GMb/CPVhmGhjtw9sW8jm4VYIi","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":104869},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"scripts":{"test":"vitest run","build":"tsc --emitDeclarationOnly && node build.mjs","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"athanx","email":"athanseal@gmail.com"},"repository":{"url":"git+https://github.com/asunLab/asun-js.git","type":"git","directory":"asun-js"},"_npmVersion":"11.11.0","description":"ASUN (Array-Schema Unified Notation) – high-performance, schema-driven data format for JS/TS","directories":{},"sideEffects":false,"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","esbuild":"^0.24.0","typescript":"^5.7.0"},"_npmOperationalInternal":{"tmp":"tmp/asun_1.0.2_1776554308344_0.844655527077459","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@athanx/asun","version":"1.0.3","keywords":["asun","serialization","schema","llm","data-format"],"license":"MIT","_id":"@athanx/asun@1.0.3","maintainers":[{"name":"athanx","email":"athanseal@gmail.com"}],"homepage":"https://github.com/asunLab/asun-js#readme","bugs":{"url":"https://github.com/asunLab/asun-js/issues"},"dist":{"shasum":"34c32e8958f53c65461e70e6a096be93765fa8e3","tarball":"https://registry.npmjs.org/@athanx/asun/-/asun-1.0.3.tgz","fileCount":6,"integrity":"sha512-mj7J5KIBqLga29+S2SvU4EeX9CKHq8e6sK4p+LmfxTAjLTC8hAVQntPZUSzFE6ZtWGaBAwkOvF/pqWnfUhnkRA==","signatures":[{"sig":"MEYCIQChibUl2urxh4dEflGBQrBxBDwfulZPyRA1KahG8empcgIhAIQFi8MJf1pirRJ4z0MmOCvdYRQFAnEGbTWrX59fqegQ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":104869},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"scripts":{"test":"vitest run","build":"tsc --emitDeclarationOnly && node build.mjs","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"athanx","email":"athanseal@gmail.com"},"repository":{"url":"git+https://github.com/asunLab/asun-js.git","type":"git","directory":"asun-js"},"_npmVersion":"11.11.0","description":"ASUN (Array-Schema Unified Notation) – high-performance, schema-driven data format for JS/TS","directories":{},"sideEffects":false,"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","esbuild":"^0.24.0","typescript":"^5.7.0"},"_npmOperationalInternal":{"tmp":"tmp/asun_1.0.3_1776569419171_0.08882974181145453","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@athanx/asun","version":"1.0.4","keywords":["asun","serialization","schema","llm","data-format"],"license":"MIT","_id":"@athanx/asun@1.0.4","maintainers":[{"name":"athanx","email":"athanseal@gmail.com"}],"homepage":"https://github.com/asunLab/asun-js#readme","bugs":{"url":"https://github.com/asunLab/asun-js/issues"},"dist":{"shasum":"5ecc2672123755c381e493d2e2c2cefa06a53242","tarball":"https://registry.npmjs.org/@athanx/asun/-/asun-1.0.4.tgz","fileCount":6,"integrity":"sha512-ah+h4yufYUgT3kZAW+JdpQITwKTgP4dQx3CPhWMiOCEYZR4oEp/6Y6NdveoZpJY5yJXD0oIQzQrPCFwtCUnU5A==","signatures":[{"sig":"MEYCIQD6sgTb7ogrpkIPM2ahORrZtNpNcNVjwLEIwVI5m5j+awIhANFhWdYtHL+u3YrbUAxcD0+L42ghF1e4mqU7pcyWvMVH","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":102591},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"scripts":{"test":"vitest run","build":"tsc --emitDeclarationOnly && node build.mjs","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"athanx","email":"athanseal@gmail.com"},"repository":{"url":"git+https://github.com/asunLab/asun-js.git","type":"git","directory":"asun-js"},"_npmVersion":"11.11.0","description":"ASUN (Array-Schema Unified Notation) – high-performance, schema-driven data format for JS/TS","directories":{},"sideEffects":false,"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","esbuild":"^0.24.0","typescript":"^5.7.0"},"_npmOperationalInternal":{"tmp":"tmp/asun_1.0.4_1776581456074_0.832022716707725","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@athanx/asun","version":"1.0.5","description":"ASUN (Array-Schema Unified Notation) – high-performance, schema-driven data format for JS/TS","license":"MIT","type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"publishConfig":{"access":"public"},"scripts":{"build":"tsc --emitDeclarationOnly && node build.mjs","test":"vitest run","test:watch":"vitest","typecheck":"tsc --noEmit"},"devDependencies":{"esbuild":"^0.24.0","typescript":"^5.7.0","vitest":"^3.0.0"},"repository":{"type":"git","url":"git+https://github.com/asunLab/asun-js.git","directory":"asun-js"},"homepage":"https://github.com/asunLab/asun-js#readme","bugs":{"url":"https://github.com/asunLab/asun-js/issues"},"keywords":["asun","serialization","schema","llm","data-format"],"sideEffects":false,"_id":"@athanx/asun@1.0.5","_nodeVersion":"24.14.1","_npmVersion":"11.11.0","dist":{"integrity":"sha512-L81ZWQ/cD2yJWgP5Nq3nGM+nrwwF6B7Rkk9JfGEN5nuy7IgPmkIHso3Ggu7b/erMfgLaktuPRXyiHVV2Zly17A==","shasum":"fa33841654b01d3da3573528bc9b2fd1e2ea3f35","tarball":"https://registry.npmjs.org/@athanx/asun/-/asun-1.0.5.tgz","fileCount":6,"unpackedSize":102401,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCICyJbtG2P2feDGoOC+HM9KT3yq1vwRuEtnFBzZwphuAxAiEAgSt+gf/LxM2d5jPTVHdgeFmBoNPUzHbXqyDzyhLemDw="}]},"_npmUser":{"name":"athanx","email":"athanseal@gmail.com"},"directories":{},"maintainers":[{"name":"athanx","email":"athanseal@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/asun_1.0.5_1776590235981_0.07711753736002813"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-17T22:22:41.218Z","modified":"2026-04-19T09:17:16.228Z","1.0.0":"2026-04-17T12:05:03.446Z","1.0.1":"2026-04-17T22:22:41.443Z","1.0.2":"2026-04-18T23:18:28.510Z","1.0.3":"2026-04-19T03:30:19.407Z","1.0.4":"2026-04-19T06:50:56.206Z","1.0.5":"2026-04-19T09:17:16.123Z"},"bugs":{"url":"https://github.com/asunLab/asun-js/issues"},"license":"MIT","homepage":"https://github.com/asunLab/asun-js#readme","keywords":["asun","serialization","schema","llm","data-format"],"repository":{"type":"git","url":"git+https://github.com/asunLab/asun-js.git","directory":"asun-js"},"description":"ASUN (Array-Schema Unified Notation) – high-performance, schema-driven data format for JS/TS","maintainers":[{"name":"athanx","email":"athanseal@gmail.com"}],"readme":"# @athanx/asun\n\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![npm](https://img.shields.io/badge/npm-%40athanx%2Fasun-blue)](https://www.npmjs.com/package/@athanx/asun)\n\n## Why ASUN?\n\n**json**\n\nStandard JSON repeats every field name in every record. When you send structured data to an LLM, over an API, or across services, that repetition wastes tokens, bytes, and attention:\n\n```json\n[\n  { \"id\": 1, \"name\": \"Alice\", \"active\": true },\n  { \"id\": 2, \"name\": \"Bob\", \"active\": false },\n  { \"id\": 3, \"name\": \"Carol\", \"active\": true }\n]\n```\n\n**asun**\n\nASUN declares the schema **once** and streams data as compact tuples:\n\n```asun\n[{id, name, active}]:\n  (1,Alice,true),\n  (2,Bob,false),\n  (3,Carol,true)\n```\n\n**Fewer tokens. Smaller payloads. Clearer structure, and faster parsing than repeated-object JSON.**\n\n---\n\nZero-dependency JavaScript/TypeScript library for **ASUN** (Array-Schema Unified Notation) — a token-efficient, schema-driven data format for LLM interactions and large-scale data transfer.\n\n`@athanx/asun` is the official runtime for both JavaScript and TypeScript users. It ships ESM/CJS builds and bundled `.d.ts` type declarations in a single package, so there is no separate `asun-ts` package to install.\n\nWorks in **browsers**, **Node.js**, **Deno**, **Bun** and any JS framework: **Vue**, **React**, **Svelte**, **SolidJS**, etc.\n\n[中文文档](README_CN.md)\n\n---\n\n## What is ASUN?\n\nASUN separates **schema** from **data**, eliminating repeated key names found in JSON. The schema is declared once; each data row carries only values:\n\n```text\nJSON (100 tokens):\n{\"users\":[{\"id\":1,\"name\":\"Alice\",\"active\":true},{\"id\":2,\"name\":\"Bob\",\"active\":false}]}\n\nASUN (~35 tokens, 65% saved):\n[{id@int, name@str, active@bool}]:(1,Alice,true),(2,Bob,false)\n```\n\n| Aspect           | JSON         | ASUN            |\n| ---------------- | ------------ | --------------- |\n| Token efficiency | 100%         | 30–70% ✓        |\n| Key repetition   | Every object | Declared once ✓ |\n| Human readable   | Yes          | Yes ✓           |\n| Type annotations | None         | Built-in ✓      |\n| Data size        | 100%         | **40–55%** ✓    |\n\n---\n\n## Install\n\n```bash\nnpm install @athanx/asun\n```\n\nOr copy `dist/asun.min.js` directly into a web page (exposes a global `ASUN` object).\n\nTypeScript users do not need a separate stub package. `npm run build` emits `dist/index.d.ts`, and the package exports it via the `types` field.\n\n---\n\n## Quick start\n\n```ts\nimport {\n  encode,\n  encodeTyped,\n  encodePretty,\n  encodePrettyTyped,\n  decode,\n  encodeBinary,\n  decodeBinary,\n} from \"@athanx/asun\";\n\nconst users = [\n  { id: 1, name: \"Alice\", score: 9.5 },\n  { id: 2, name: \"Bob\", score: 7.2 },\n];\n\n// Schema is inferred automatically — no schema string needed\nconst text = encode(users); // schema without scalar hints\nconst textTyped = encodeTyped(users); // schema with scalar hints (use for typed round-trip)\nconst pretty = encodePretty(users); // pretty + untyped\nconst prettyTyped = encodePrettyTyped(users); // pretty + scalar hints\nconst blob = encodeBinary(users); // binary (schema inferred internally)\n\nconsole.log(decode(textTyped)); // original array restored\nconsole.log(decode(prettyTyped)); // same from pretty\nconsole.log(decodeBinary(blob, \"[{id@int, name@str, score@float}]\")); // binary decode\n```\n\n> **Note on `encode` vs `encodeTyped`**\n> `encode(obj)` emits a schema without scalar hints (`{id,name}`) so the output is shorter.\n> When decoded, all values without explicit types are returned as strings.\n> Use `encodeTyped(obj)` when you need scalar hints to preserve numeric and boolean types on round-trip.\n\n---\n\n## API\n\n### Type inference rules\n\n| JS value             | Inferred ASUN type |\n| -------------------- | ------------------ |\n| whole `number`       | `int`              |\n| fractional `number`  | `float`            |\n| `true` / `false`     | `bool`             |\n| text                 | `str`              |\n| `null` / `undefined` | `str?` (optional)  |\n\n> **Note:** Schema is inferred from the **first element** of an array. To make a field optional (`str?`), ensure the first element has `null` for that field.\n\n### `encode(obj) → string`\n\nSerialize a plain object or array to ASUN text with an **inferred schema without scalar hints**.\nWhen decoded, all scalar fields without explicit hints come back as **strings**:\n\n```ts\nencode({ id: 1, name: \"Alice\" });\n// → '{id,name}:\\n(1,Alice)\\n'\n\nencode([{ id: 1 }, { id: 2 }]);\n// → '[{id}]:\\n(1),\\n(2)\\n'\n\ndecode(encode({ id: 1, name: \"Alice\" }));\n// → { id: '1', name: 'Alice' }  ← all strings when scalar hints are omitted\n```\n\nUse `encodeTyped` when you need `decode` to restore the original types.\n\n### `encodeTyped(obj) → string`\n\nSame as `encode` but emits an **inferred schema with scalar hints**. Use this when you want `decode()` to restore the original scalar types:\n\n```ts\nencodeTyped({ id: 1, name: \"Alice\", active: true });\n// → '{id@int,name@str,active@bool}:\\n(1,Alice,true)\\n'\n```\n\nNested object and array fields keep structural bindings even when scalar hints are omitted:\n\n```ts\nencode({\n  profile: { host: \"127.0.0.1\", port: 8080 },\n  tags: [\"blue\", \"fast\"],\n});\n// → '{profile@{host,port},tags@[]}:\\n((127.0.0.1,8080),[blue, fast])\\n'\n```\n\n### `encodePretty(obj) → string`\n\nPretty-printed ASUN text with **inferred untyped** schema.\n\n### `encodePrettyTyped(obj) → string`\n\nPretty-printed ASUN text with **inferred typed** schema.\n\n### `decode(text) → object | object[]`\n\nDeserialize ASUN text. The schema is embedded in the text itself:\n\n```ts\nconst rec = decode(\"{id@int, name@str}:\\n(1,Alice)\\n\");\nconst rows = decode(\"[{id@int, name@str}]:\\n(1,Alice),\\n(2,Bob)\\n\");\n```\n\n### `encodeBinary(obj) → Uint8Array`\n\nSerialize to binary format. **Schema is inferred internally** — no schema string needed:\n\n```ts\nconst data = encodeBinary(rows);\n```\n\n### `decodeBinary(data, schema) → object | object[]`\n\nDeserialize from binary format. **Schema is required** because the binary wire format carries no embedded type information:\n\n```ts\nconst rows = decodeBinary(data, \"[{id@int, name@str}]\");\n```\n\n---\n\n## Supported types\n\n| Schema type | JS value         | Example                  |\n| ----------- | ---------------- | ------------------------ |\n| `int`       | number (integer) | `42`, `-100`             |\n| `float`     | number           | `3.14`, `-0.5`           |\n| `bool`      | `true` / `false` | `true`, `false`          |\n| `str`       | text             | `Alice`, `\"Carol Smith\"` |\n| `T?`        | value or `null`  | `hello` / `null`         |\n\nOptional fields: append `?` to any type (`str?`, `int?`, `float?`, `bool?`).\n\n---\n\n## Browser (CDN) usage\n\n```html\n<script src=\"dist/asun.min.js\"></script>\n<script>\n  const text = ASUN.encodeTyped([{ id: 1, name: \"Alice\" }]);\n  console.log(ASUN.decode(text));\n</script>\n```\n\n## ESM in browser\n\n```html\n<script type=\"module\">\n  import { encodeTyped, decode } from \"./dist/index.js\";\n  const text = encodeTyped([{ id: 1, name: \"Alice\" }]);\n  console.log(decode(text));\n</script>\n```\n\n## Vue / React / Svelte / SolidJS\n\nWorks as a regular npm package — just import and use:\n\n```ts\n// Vue composable example\nimport { encodeTyped, decode } from \"@athanx/asun\";\n\nexport function useAsun() {\n  const serialize = (data: object[]) => encodeTyped(data);\n  const deserialize = (text: string) => decode(text);\n  return { serialize, deserialize };\n}\n```\n\n---\n\n## Binary format\n\nLittle-endian layout, byte-identical to asun-rs and asun-go:\n\n| Type     | Bytes                                  |\n| -------- | -------------------------------------- |\n| `int`    | 8 (i64 LE)                             |\n| `float`  | 8 (f64 LE)                             |\n| `bool`   | 1                                      |\n| `str`    | 4-byte length LE + UTF-8 bytes         |\n| optional | 1-byte tag (0=null, 1=present) + value |\n| slice    | 4-byte count LE + elements             |\n\n---\n\n## Build from source\n\n```bash\nnpm install\nnpm run build    # generates dist/index.js, dist/index.cjs, dist/index.d.ts, dist/asun.min.js\nnpm test         # vitest\n```\n\n---\n\n## Run examples\n\n```bash\nnode examples/basic.js     # 9 scenarios, basic usage\nnode examples/complex.js   # complex nested scenarios and legacy-syntax rejection\nnode examples/bench.js     # performance vs JSON.parse / JSON.stringify\n```\n\n---\n\n## Performance\n\nASUN JS produces **50–55% smaller** output than JSON. Because `JSON.parse` / `JSON.stringify` are implemented in C, raw speed is slower — but:\n\n- **Network bandwidth** is typically the bottleneck — 50% smaller payload saves more time than parse overhead costs\n- **LLM token cost** — 30–70% fewer tokens = lower API cost and faster responses\n- **Binary format** — `encodeBinary` / `decodeBinary` is fastest for machine-to-machine transfer\n\nFor latency-sensitive hot paths, use the [Rust](../asun-rs/) or [Go](../asun-go/) implementations if your stack supports them.\n\n---\n\n## License\n\nMIT\n\n## Contributors\n\n- [Athan](https://github.com/athxx)\n\n## Latest Benchmarks\n\nMeasured on this machine with Node `24.14.0`.\n\nHeadline numbers:\n\n- Flat 1,000-record dataset: ASUN text `58,539 B` vs JSON `121,451 B` (`51.8%` smaller)\n- Flat 5,000-record dataset: ASUN serialize `8.93ms` vs JSON `13.27ms`, but deserialize `20.10ms` vs JSON `16.92ms`\n- Large 10,000-record dataset: ASUN serialize `37.86ms` vs JSON `20.23ms`, deserialize `37.25ms` vs JSON `33.82ms`\n- Throughput summary on 10,000-record-style text path: ASUN text serialize ran at `0.30 M records/s` vs JSON `0.75 M`-class baseline, and deserialize was roughly at parity in this run\n- Binary path is mainly useful for decode and transport size here: on 1,000 records, BIN deserialize `4.68ms` vs JSON `2.08ms`, with payload `72,784 B` vs JSON `121,451 B`\n","readmeFilename":"README.md"}