{"_id":"@alexa.kitsune/ale","_rev":"2-6a33eb92f512c5623ff7604f57908404","name":"@alexa.kitsune/ale","dist-tags":{"latest":"0.0.2"},"versions":{"0.0.1":{"name":"@alexa.kitsune/ale","version":"0.0.1","keywords":["parser","serializer","dsl","data-format","ale"],"license":"MIT","_id":"@alexa.kitsune/ale@0.0.1","maintainers":[{"name":"alexa.kitsune","email":"alexa.nc.kitsune@gmail.com"}],"dist":{"shasum":"5abbd8f14b9a459e22ae4469c8de505409a1b707","tarball":"https://registry.npmjs.org/@alexa.kitsune/ale/-/ale-0.0.1.tgz","fileCount":3,"integrity":"sha512-BTSh1AouomircMXynbBZwA891U62s/sG22yuFVnoq1jmpDDERIbyXv3+MWdPdw6XEdDteNDCZtjI417h8YLvYg==","signatures":[{"sig":"MEYCIQDRP2rf5/5jqwGROCclLMKG1haG7X9kh0ez6PBCY9YnlQIhAODZziAFx9dbJdpiRPm5vmYe76XI6w1sycRIc/Y+DPUN","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":51979},"main":"./ale.js","type":"module","exports":{".":"./ale.js"},"scripts":{"test":"node -e \"import('./ale.js').then(m=>{ if(!m.parseALE) throw new Error('parseALE missing'); console.log('ok'); })\"","prepublishOnly":"npm test"},"_npmUser":{"name":"alexa.kitsune","email":"alexa.nc.kitsune@gmail.com"},"_npmVersion":"10.9.2","description":"ALE v0.2 parser + stringifier (JSON ⇄ ALE)","directories":{},"_nodeVersion":"22.14.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/ale_0.0.1_1769530380380_0.6432305138078724","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@alexa.kitsune/ale","version":"0.0.2","description":"ALE v0.0.2 parser + stringifier (JSON ⇄ ALE)","type":"module","main":"./ale.js","exports":{".":"./ale.js"},"scripts":{"test":"node -e \"import('./ale.js').then(m=>{ if(!m.parseALE) throw new Error('parseALE missing'); console.log('ok'); })\"","prepublishOnly":"npm test"},"keywords":["parser","serializer","dsl","data-format","ale"],"license":"MIT","_id":"@alexa.kitsune/ale@0.0.2","_nodeVersion":"22.14.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-/mYaSftQcdyZu0DNWELnmmg4WSHdmKKklH7Gmluaiavf2WyN7wpnHZkCAA2zZuoBFyoSgwmLNQHSS9yktcGVdA==","shasum":"13c26b5326a1f9927686ee1abe8ce052d8bcbae6","tarball":"https://registry.npmjs.org/@alexa.kitsune/ale/-/ale-0.0.2.tgz","fileCount":3,"unpackedSize":52224,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIB6izgoc9AMrTPgxK3CNGGcU38iJKeTGyHEwi2kcR/KFAiEA+U5HGijzpR6lYz0OkXhDpmwCn/jHkNLO6kOxFhQcT0A="}]},"_npmUser":{"name":"alexa.kitsune","email":"alexa.nc.kitsune@gmail.com"},"directories":{},"maintainers":[{"name":"alexa.kitsune","email":"alexa.nc.kitsune@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ale_0.0.2_1769531549091_0.8214788012335046"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-27T16:13:00.299Z","modified":"2026-01-27T16:32:29.362Z","0.0.1":"2026-01-27T16:13:00.524Z","0.0.2":"2026-01-27T16:32:29.233Z"},"license":"MIT","keywords":["parser","serializer","dsl","data-format","ale"],"description":"ALE v0.0.2 parser + stringifier (JSON ⇄ ALE)","maintainers":[{"name":"alexa.kitsune","email":"alexa.nc.kitsune@gmail.com"}],"readme":"# ALE — Abstract List Expression\n\n## Specification v0.0.2\n\nALE is a human-readable, token-efficient data notation inspired by JSON, TOON, and YAML. It is designed to represent structured data deterministically with minimal syntax overhead, making it especially suitable for configs, datasets, and LLM prompts.\n\n---\n\n### 0. Goals\n- High human readability\n- Low syntactic noise (token-efficient)\n- Deterministic parsing (no heuristics)\n- Native support for:\n- implicit objects\n- heterogeneous arrays\n- homogeneous tables (arrays of objects)\n- complex nested blocks (slots)\n\nALE is data-only (no execution, no expressions).\n\n---\n\n### 1. Indentation & Structure\n- Hierarchy is defined only by indentation.\n- Tabs or spaces are allowed but must be consistent.\n- Dedentation closes the current block.\n- Empty lines are ignored.\n\n---\n\n### 2. Supported Data Types\n\nALE can represent:\n- Object\n- Array\n- String\n- Number (int / float)\n- Boolean\n- Null\n\n---\n\n### 3. Objects (Implicit)\n\n3.1 Key–Value Pair\n\n```\nkey: value\n```\n\n3.2 Object Continuity Rule\n\nConsecutive key: value lines belong to the same object unless:\n- a > appears (new sibling), or\n- indentation level decreases.\n\nExample:\n\n```\nid: 1\nname: Booker\ntags: [shark, friend]\n```\n```json\n{ \"id\": 1, \"name\": \"Booker\", \"tags\": [\"shark\", \"friend\"] }\n```\n\n---\n\n### 4. Arrays\n\n4.1 Block-Inferred Array\n\n```\nitems:\n    1\n    \"hello\"\n    [1,2]\n```\n\nIf a key ends with : and the indented block does not start with key: value, the key is an array.\n\n4.2 Inline Array\n\n```json\n[1, 2, 3, 4.5]\n```\n\n4.3 Empty Array\n\n```\ntags: []\n```\n\n---\n\n### 5. Tables (Homogeneous Arrays of Objects)\n\n5.1 Table Header\n\n```\nkey{a, b, c}:\n    v1, v2, v3\n    v1, v2, v3\n```\n\nEach row produces an object by column position.\n\nExample:\n\n```\ncharacters{id, name}:\n    1, Eleanor\n    2, Swifty\n```\n```json\n[\n  { \"id\": 1, \"name\": \"Eleanor\" },\n  { \"id\": 2, \"name\": \"Swifty\" }\n]\n```\n\n5.2 Null Values in Tables\n- `-` → `null`\n- Empty cell (`Booker,`) → `null`\n\n---\n\n### 6. Arrays Inside Arrays\n\n6.1 `[{a,b}]` — Array as a Single Element\n\n```\nmixed:\n    [{name, age}]:\n        Alexa, 28\n        Booker, -\n```\n```json\n[\n  [\n    { \"name\": \"Alexa\", \"age\": 28 },\n    { \"name\": \"Booker\", \"age\": null }\n  ]\n]\n```\n\n6.2 ...{a,b} — Spread / Unpack\n\n```\nmixed:\n    ...{name, age}:\n        Alexa, 28\n        Booker, -\n```\n```json\n[\n  { \"name\": \"Alexa\", \"age\": 28 },\n  { \"name\": \"Booker\", \"age\": null }\n]\n```\n\n---\n\n### 7. Sibling Separator >\n\nInside arrays, > starts a new sibling element.\n\n```\nmixed:\n    id: 1\n    name: Booker\n    >id: 0\n    name: Alexa\n```\n```json\n[\n  { \"id\": 1, \"name\": \"Booker\" },\n  { \"id\": 0, \"name\": \"Alexa\" }\n]\n```\n\n---\n\n### 8. Boolean Shortcuts\n\nSyntax  | Result\n--------|------------\n`!flag` | `flag: false`\n`¡flag` | `flag: true`\n\nExplicit booleans are also valid:\n\n`active: true`\n\n---\n\n### 9. Null\n\n`value: -`\n\n---\n\n### 10. Strings\n\n10.1 Bare Strings\n\nname: Alexa\n\n10.2 Escaping\n- \\n → newline\n- \\, → literal comma\n- \\\" → quote\n\n```\ntext: Hola\\, soy Ale\\nEncantada\n```\n\n10.3 Quoted Strings\n\nRequired when containing commas, structural symbols, or leading spaces:\n\n```\ntext: \"Hola, soy \\\"Ale\\\" (Alexa)\"\n```\n\n---\n\n### 11. Slots ([:]) — Complex Blocks\n\n11.1 Definition\n\n`[:]` defines a slot, not a normal empty array.\n- Slots always resolve to arrays\n- Empty slot → []\n- Slots accept only free elements\n\nConceptually:\n\nlet arr = [];\narr.push(...)\n\nExample:\n\n```\nnotes: [:]\n    \"text\"\n    word: konnichiwa\n```\n\n---\n\n### 12. Slot Selection — < and <name\n\nWhen multiple slots exist:\n- < → move to next slot\n- <name → move to specific slot\n\n```\ngerman, 0, [:], {aspect, difficulty, attempts}\n    word: -\n    meaning: -\n    >word: fuchs\n    ¡favAnimal\n\n    <easy\n    declination, 80, 4\n    pronunciation, 90, 2\n```\n\n---\n\n### 13. Free Text Inside Slots\n\nIndented lines that are not:\n- key: value\n- flags\n- \\> or <\n- table rows\n\nare treated as string literals and appended to the active slot.\n\n---\n\n### 14. Keys with Spaces\n\nKeys may contain spaces if quoted:\n\n```\n\"full name\": Alexa\n\"user tags\": [fox, artist]\n```\n\n---\n\n### 15. Parsing Order (Deterministic)\n\t1.\tIndentation\n\t2.\t> / <\n\t3.\tFlags (!, ¡)\n\t4.\tTable headers {}\n\t5.\tSpread ...{}\n\t6.\tArray-as-element [{ } ]\n\t7.\tInline arrays []\n\t8.\tScalars (null → bool → number → string)\n\n---\n\n## Token Efficiency (Measured)\n\nUsing [OpenAI Tokenizer](https://platform.openai.com/tokenizer) (model: GPT-4o / GPT-4o mini):\n\nFormat | Tokens\n-------|--------\nJSON   | 544\nTOON   | 385\nALE    | 278\n\nALE achieves ~49% token reduction vs JSON and ~28% vs TOON.\n\nExamples used:\n\n### JSON\n\n```json\n{\n\n    \"name\": \"Alexa\",\n    \"age\": 28,\n    \"characters\": [\n        { \"id\": 1, \"name\": \"Eleanor\" },\n        { \"id\": 2, \"name\": \"Swifty\" }\n    ],\n    \"mixedArray\": [\n        1,\n        [1, 2, 3, 4.5],\n        {\n            \"id\": 1,\n            \"name\": \"Booker\",\n            \"tags\": [\"shark\", \"friend\"]\n        },\n        {\n            \"id\": 0,\n            \"name\": \"Alexa\",\n            \"active\": false,\n            \"isFox\": true,\n            \"languages\": [\n                {\n                    \"name\": \"spanish\",\n                    \"level\": 100,\n                    \"notes\": \"lingua franca\",\n                    \"easy\": true\n                },\n                {\n                    \"name\": \"english\",\n                    \"level\": 70,\n                    \"notes\": [\"Oskar\", \"Kilo\"],\n                    \"easy\": true\n                },\n                {\n                    \"name\": \"japanese\",\n                    \"level\": 20,\n                    \"notes\": [\n                        {\n                            \"word\": \"konnichiwa\",\n                            \"easy\": true\n                        },\n                        {\n                            \"katakana\": \"キツネ\",\n                            \"meaning\": \"fox\"\n                        },\n                        \"same\",\n                        \"neko\",\n                        \"shika\"\n                    ],\n                    \"easy\": false\n                },{\n                    \"name\": \"german\",\n                    \"level\": 0,\n                    \"notes\": [\n                        {\n                            \"word\": null,\n                            \"meaning\": null\n                        },\n                        {\n                            \"word\": \"fuchs\",\n                            \"favAnimal\": true\n                        }\n                    ],\n                    \"easy\": [\n                        {\n                            \"aspect\": \"declination\",\n                            \"difficulty\": 80,\n                            \"attempts\": 4\n                        },\n                        {\n                            \"aspect\": \"pronunciation\",\n                            \"difficulty\": 90,\n                            \"attempts\": 2\n                        },\n                        {\n                            \"aspect\": \"vocabulary\",\n                            \"difficulty\": 40,\n                            \"attempts\": 5\n                        }\n                    ]\n                }\n            ]\n        },\n        { \"name\": \"Alexa\", \"age\": 28 },\n        { \"name\": \"Booker\", \"age\": null },\n        { \"name\": \"Eleanor\", \"age\": 30 },\n        [\n            { \"name\": \"Alexa\", \"age\": 28 },\n            { \"name\": \"Booker\", \"age\": null },\n            { \"name\": \"Eleanor\", \"age\": 30 }\n        ]\n    ]\n}\n```\n\n### TOON\n\n```\nname: Alexa\nage: 28\ncharacters: items[2]{id,name}:\n    1,Eleanor\n    2,Swifty\nmixedArray: items[8]:\n    - 1\n    - items[4]:\n      - 1\n      - 2\n      - 3\n      - 4.5\n    - id: 1\n    name: Booker\n    tags: items[2]:\n        - shark\n        - friend\n    - id: 0\n    name: Alexa\n    active: false\n    isFox: true\n    languages: items[4]:\n        - name: spanish\n        level: 100\n        notes: lingua franca\n        easy: true\n        - name: english\n        level: 70\n        notes: items[2]:\n            - Oskar\n            - Kilo\n        easy: true\n        - name: japanese\n        level: 20\n        notes: items[5]:\n            - word: konnichiwa\n            easy: true\n            - katakana: キツネ\n            meaning: fox\n            - same\n            - neko\n            - shika\n        easy: false\n        - name: german\n        level: 0\n        notes: items[2]:\n            - word: \n            meaning: \n            - word: fuchs\n            favAnimal: true\n        easy: items[3]{aspect,difficulty,attempts}:\n            declination,80,4\n            pronunciation,90,2\n            vocabulary,40,5\n    - name: Alexa\n    age: 28\n    - name: Booker\n    age: \n    - name: Eleanor\n    age: 30\n    - items[3]{name,age}:\n      Alexa,28\n      Booker,\n      Eleanor,30\n```\n\n### ALE\n\n```\nname: Alexa\nage: 28\ncharacters{id, name}:\n    1, Eleanor\n    2, Swifty\nmixedArray:\n    1\n    [1, 2, 3, 4.5]\n    id: 1\n    name: Booker\n    tags: [shark, friend]\n    >id: 0\n    name: Alexa\n    !active\n    ¡isFox\n    languages{name, level, notes, easy}:\n        spanish, 100, lingua franca, ¡\n        english, 70, [Oskar, Kilo], ¡\n        japanese, 20, [:], !\n            word: konnichiwa\n            ¡easy\n            >katakana: キツネ\n            meaning: fox\n            same\n            neko\n            shika\n        german, 0, [:], {aspect, difficulty, attempts}\n            word:\n            meaning:\n            >word: fuchs\n            ¡favAnimal\n            <declination, 80, 4\n            pronunciation, 90, 2\n            vocabulary, 40, 5\n    ...{name, age}:\n        Alexa, 28\n        Booker,\n        Eleanor, 30\n    {name, age}:\n    Alexa, 28\n    Booker,\n    Eleanor, 30\n```\n\n---\n\n## Status\n- v0.2 — Stable specification\n- Deterministic, human-friendly, LLM-efficient\n- Suitable for bidirectional ALE ⇄ JSON parsing\n\n## Usage\n\n### Install\n\n```bash\nnpm i @alexa.kitsune/ale\n```\n\n### Parse ALE → JSON\n```js\nimport { parseALE } from \"@alexa.kitsune/ale\";\n\nconst src = `\nname: Alexa\nage: 28\ncharacters{id, name}:\n    1, Eleanor\n    2, Swifty\n`;\n\nconst data = parseALE(src);\nconsole.log(data);\n```\n\n### Stringify JSON → ALE\n```js\nimport { stringifyALE } from \"@alexa.kitsune/ale\";\n\nconst obj = {\n    name: \"Alexa\",\n    age: 28,\n    characters: [\n        { id: 1, name: \"Eleanor\" },\n        { id: 2, name: \"Swifty\" }\n    ]\n};\n\nconsole.log(stringifyALE(obj));\n```\n\n> NOTE\n> The package is published as ESM (type: \"module\"). Use import ... (Node >= 16).\n\n---\n\nEnd of specification.","readmeFilename":"README.md"}