🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@toon-format/toon

Package Overview
Dependencies
Maintainers
1
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@toon-format/toon - npm Package Compare versions

Comparing version
1.3.0
to
1.4.0
+63
-33
dist/index.mjs

@@ -656,5 +656,26 @@ //#region src/constants.ts

if (line.content === LIST_ITEM_MARKER) {
yield { type: "startObject" };
yield { type: "endObject" };
return;
const followDepth = baseDepth + 1;
const nextLine = cursor.peekSync();
if (!nextLine || nextLine.depth < followDepth) {
yield { type: "startObject" };
yield { type: "endObject" };
return;
}
if (nextLine.depth === followDepth && !nextLine.content.startsWith(LIST_ITEM_PREFIX)) {
yield { type: "startObject" };
while (!cursor.atEndSync()) {
const fieldLine = cursor.peekSync();
if (!fieldLine || fieldLine.depth < followDepth) break;
if (fieldLine.depth === followDepth && !fieldLine.content.startsWith(LIST_ITEM_PREFIX)) {
cursor.advanceSync();
yield* decodeKeyValueSync(fieldLine.content, cursor, followDepth, options);
} else break;
}
yield { type: "endObject" };
return;
} else {
yield { type: "startObject" };
yield { type: "endObject" };
return;
}
} else if (line.content.startsWith(LIST_ITEM_PREFIX)) afterHyphen = line.content.slice(LIST_ITEM_PREFIX.length);

@@ -873,5 +894,26 @@ else throw new SyntaxError(`Expected list item to start with "${LIST_ITEM_PREFIX}"`);

if (line.content === LIST_ITEM_MARKER) {
yield { type: "startObject" };
yield { type: "endObject" };
return;
const followDepth = baseDepth + 1;
const nextLine = await cursor.peek();
if (!nextLine || nextLine.depth < followDepth) {
yield { type: "startObject" };
yield { type: "endObject" };
return;
}
if (nextLine.depth === followDepth && !nextLine.content.startsWith(LIST_ITEM_PREFIX)) {
yield { type: "startObject" };
while (!cursor.atEnd()) {
const fieldLine = await cursor.peek();
if (!fieldLine || fieldLine.depth < followDepth) break;
if (fieldLine.depth === followDepth && !fieldLine.content.startsWith(LIST_ITEM_PREFIX)) {
await cursor.advance();
yield* decodeKeyValueAsync(fieldLine.content, cursor, followDepth, options);
} else break;
}
yield { type: "endObject" };
return;
} else {
yield { type: "startObject" };
yield { type: "endObject" };
return;
}
} else if (line.content.startsWith(LIST_ITEM_PREFIX)) afterHyphen = line.content.slice(LIST_ITEM_PREFIX.length);

@@ -1507,31 +1549,19 @@ else throw new SyntaxError(`Expected list item to start with "${LIST_ITEM_PREFIX}"`);

const entries = Object.entries(obj);
const [firstKey, firstValue] = entries[0];
const encodedKey = encodeKey(firstKey);
if (isJsonPrimitive(firstValue)) yield indentedListItem(depth, `${encodedKey}: ${encodePrimitive(firstValue, options.delimiter)}`, options.indent);
else if (isJsonArray(firstValue)) if (isArrayOfPrimitives(firstValue)) yield indentedListItem(depth, encodeInlineArrayLine(firstValue, options.delimiter, firstKey), options.indent);
else if (isArrayOfObjects(firstValue)) {
const header = extractTabularHeader(firstValue);
if (header) {
yield indentedListItem(depth, formatHeader(firstValue.length, {
key: firstKey,
fields: header,
delimiter: options.delimiter
}), options.indent);
yield* writeTabularRowsLines(firstValue, header, depth + 1, options);
} else {
yield indentedListItem(depth, `${encodedKey}[${firstValue.length}]:`, options.indent);
for (const item of firstValue) yield* encodeObjectAsListItemLines(item, depth + 1, options);
if (entries.length === 1) {
const [key, value] = entries[0];
if (isJsonArray(value) && isArrayOfObjects(value)) {
const header = extractTabularHeader(value);
if (header) {
yield indentedListItem(depth, formatHeader(value.length, {
key,
fields: header,
delimiter: options.delimiter
}), options.indent);
yield* writeTabularRowsLines(value, header, depth + 1, options);
return;
}
}
} else {
yield indentedListItem(depth, `${encodedKey}[${firstValue.length}]:`, options.indent);
for (const item of firstValue) yield* encodeListItemValueLines(item, depth + 1, options);
}
else if (isJsonObject(firstValue)) {
yield indentedListItem(depth, `${encodedKey}:`, options.indent);
if (!isEmptyObject(firstValue)) yield* encodeObjectLines(firstValue, depth + 2, options);
}
for (let i = 1; i < entries.length; i++) {
const [key, value] = entries[i];
yield* encodeKeyValuePairLines(key, value, depth + 1, options);
}
yield indentedLine(depth, LIST_ITEM_MARKER, options.indent);
yield* encodeObjectLines(obj, depth + 1, options);
}

@@ -1538,0 +1568,0 @@ function* encodeListItemValueLines(value, depth, options) {

{
"name": "@toon-format/toon",
"type": "module",
"version": "1.3.0",
"version": "1.4.0",
"description": "Token-Oriented Object Notation (TOON) – Compact, human-readable, schema-aware encoding of JSON for LLM prompts",

@@ -36,3 +36,3 @@ "author": "Johann Schopplich <hello@johannschopplich.com>",

"devDependencies": {
"@toon-format/spec": "^2.0.1"
"@toon-format/spec": "^2.1.0"
},

@@ -39,0 +39,0 @@ "scripts": {

+15
-45

@@ -7,3 +7,3 @@ ![TOON logo with step‑by‑step guide](./.github/og.png)

[![npm version](https://img.shields.io/npm/v/@toon-format/toon.svg)](https://www.npmjs.com/package/@toon-format/toon)
[![SPEC v2.0](https://img.shields.io/badge/spec-v2.0-lightgray)](https://github.com/toon-format/spec)
[![SPEC v2.1](https://img.shields.io/badge/spec-v2.1-lightgray)](https://github.com/toon-format/spec)
[![npm downloads (total)](https://img.shields.io/npm/dt/@toon-format/toon.svg)](https://www.npmjs.com/package/@toon-format/toon)

@@ -140,2 +140,6 @@ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)

## Media Type & File Extension
By convention, TOON files use the `.toon` extension and the provisional media type `text/toon` for HTTP and content-type–aware contexts. TOON documents are always UTF-8 encoded; the `charset=utf-8` parameter may be specified but defaults to UTF-8 when omitted. See [SPEC.md §18.2](https://github.com/toon-format/spec/blob/main/SPEC.md#182-provisional-media-type) for normative details.
## When Not to Use TOON

@@ -782,42 +786,5 @@

**Streaming decode:**
> [!TIP]
> For streaming decode APIs, see [`decodeFromLines()`](/reference/api#decodeFromLines-lines-options) and [`decodeStream()`](/reference/api#decodeStream-source-options).
```ts
import { decodeFromLines, decodeStreamSync } from '@toon-format/toon'
// 1. Lines → value (build full JSON value)
const value = decodeFromLines([
'users[2]{id,name}:',
' 1,Alice',
' 2,Bob',
])
// { users: [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }] }
// 2. Lines → events (for custom streaming consumers)
const lines = [
'users[2]{id,name}:',
' 1,Alice',
' 2,Bob',
]
for (const event of decodeStreamSync(lines)) {
// { type: 'startObject' }, { type: 'key', key: 'users' }, ...
}
```
**Async streaming decode:**
```ts
// 3. Async streaming from files or network
import { createReadStream } from 'node:fs'
import { createInterface } from 'node:readline'
import { decodeStream } from '@toon-format/toon'
const fileStream = createReadStream('data.toon', 'utf-8')
const rl = createInterface({ input: fileStream })
for await (const event of decodeStream(rl)) {
// Process events as they arrive
}
```
## Playgrounds

@@ -895,3 +862,4 @@

**Getting Started**
### Getting Started
- [Introduction & Installation](https://toonformat.dev/guide/getting-started) – What TOON is, when to use it, first steps

@@ -901,3 +869,4 @@ - [Format Overview](https://toonformat.dev/guide/format-overview) – Complete syntax with examples

**Tools & Integration**
### Tools & Integration
- [CLI](https://toonformat.dev/cli/) – Command-line tool for JSON↔TOON conversions

@@ -907,6 +876,7 @@ - [Using TOON with LLMs](https://toonformat.dev/guide/llm-prompts) – Prompting strategies & validation

**Reference**
### References
- [API Reference](https://toonformat.dev/reference/api) – TypeScript/JavaScript encode/decode API
- [Syntax Cheatsheet](https://toonformat.dev/reference/syntax-cheatsheet) – Quick format lookup
- [Specification v2.0](https://github.com/toon-format/spec/blob/main/SPEC.md) – Normative rules for implementers
- [Specification v2.1](https://github.com/toon-format/spec/blob/main/SPEC.md) – Normative rules for implementers

@@ -916,3 +886,3 @@ ## Other Implementations

> [!NOTE]
> When implementing TOON in other languages, please follow the [specification](https://github.com/toon-format/spec/blob/main/SPEC.md) (currently v2.0) to ensure compatibility across implementations. The [conformance tests](https://github.com/toon-format/spec/tree/main/tests) provide language-agnostic test fixtures that validate your implementations.
> When implementing TOON in other languages, please follow the [Specification](https://github.com/toon-format/spec/blob/main/SPEC.md) (currently v2.1) to ensure compatibility across implementations. The [conformance tests](https://github.com/toon-format/spec/tree/main/tests) provide language-agnostic test fixtures that validate your implementations.

@@ -919,0 +889,0 @@ ### Official Implementations