@zenoaihq/tson 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +463 -0
- package/dist/index.cjs +498 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +179 -0
- package/dist/index.d.ts +179 -0
- package/dist/index.js +482 -0
- package/dist/index.js.map +1 -0
- package/package.json +76 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Zeno AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
# TSON for JavaScript/TypeScript
|
|
2
|
+
|
|
3
|
+
**Token-efficient Structured Object Notation - JavaScript/TypeScript Implementation**
|
|
4
|
+
|
|
5
|
+
[](../LICENSE)
|
|
6
|
+
[](https://www.npmjs.com/package/@zenoaihq/tson)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
|
|
9
|
+
A compact serialization format designed for efficient data exchange with Large Language Models (LLMs). TSON achieves **25-70% token savings** compared to JSON while maintaining perfect round-trip conversion.
|
|
10
|
+
|
|
11
|
+
## Why TSON?
|
|
12
|
+
|
|
13
|
+
When working with LLMs, every token costs money and context space. JSON's verbose syntax wastes tokens on formatting rather than data:
|
|
14
|
+
|
|
15
|
+
- Repeated keys in arrays of objects
|
|
16
|
+
- Excessive punctuation (quotes, colons, brackets)
|
|
17
|
+
- Unnecessary whitespace in compact mode
|
|
18
|
+
|
|
19
|
+
TSON solves this with a delimiter-based format optimized for token efficiency.
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @zenoaihq/tson
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pnpm add @zenoaihq/tson
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
yarn add @zenoaihq/tson
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Quick Start
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { dumps, loads } from '@zenoaihq/tson';
|
|
39
|
+
|
|
40
|
+
// Simple object
|
|
41
|
+
const data = { name: 'Alice', age: 30, active: true };
|
|
42
|
+
const encoded = dumps(data);
|
|
43
|
+
console.log(encoded);
|
|
44
|
+
// Output: {@name,age,active|Alice,30,true}
|
|
45
|
+
|
|
46
|
+
// Perfect round-trip
|
|
47
|
+
const decoded = loads(encoded);
|
|
48
|
+
console.log(decoded); // { name: 'Alice', age: 30, active: true }
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Token Savings Example
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import { dumps } from '@zenoaihq/tson';
|
|
55
|
+
|
|
56
|
+
const data = [
|
|
57
|
+
{ id: 1, name: 'Alice', email: 'alice@example.com' },
|
|
58
|
+
{ id: 2, name: 'Bob', email: 'bob@example.com' },
|
|
59
|
+
{ id: 3, name: 'Carol', email: 'carol@example.com' },
|
|
60
|
+
];
|
|
61
|
+
|
|
62
|
+
// JSON: 153 characters
|
|
63
|
+
const json = JSON.stringify(data);
|
|
64
|
+
console.log(json.length); // 153
|
|
65
|
+
|
|
66
|
+
// TSON: 90 characters (41% savings!)
|
|
67
|
+
const tson = dumps(data);
|
|
68
|
+
console.log(tson.length); // 90
|
|
69
|
+
console.log(tson);
|
|
70
|
+
// {@id,name,email#3|1,Alice,alice@example.com|2,Bob,bob@example.com|3,Carol,carol@example.com}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Keys are written **once**, not repeated for each row!
|
|
74
|
+
|
|
75
|
+
## API Reference
|
|
76
|
+
|
|
77
|
+
### Serialization
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
import { dumps, dump } from '@zenoaihq/tson';
|
|
81
|
+
|
|
82
|
+
// Serialize JavaScript data to TSON string
|
|
83
|
+
const tsonString = dumps(data);
|
|
84
|
+
|
|
85
|
+
// Serialize to file (Node.js only)
|
|
86
|
+
await dump(data, 'data.tson');
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Deserialization
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import { loads, load } from '@zenoaihq/tson';
|
|
93
|
+
|
|
94
|
+
// Deserialize TSON string to JavaScript data
|
|
95
|
+
const data = loads(tsonString);
|
|
96
|
+
|
|
97
|
+
// Deserialize from file (Node.js only)
|
|
98
|
+
const data = await load('data.tson');
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## TypeScript Support
|
|
102
|
+
|
|
103
|
+
Full TypeScript support with comprehensive type definitions:
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
import { dumps, loads, TSONValue, TSONObject, TSONArray } from '@zenoaihq/tson';
|
|
107
|
+
|
|
108
|
+
const data: TSONObject = {
|
|
109
|
+
name: 'Alice',
|
|
110
|
+
age: 30,
|
|
111
|
+
tags: ['developer', 'typescript'],
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const encoded: string = dumps(data);
|
|
115
|
+
const decoded: TSONValue = loads(encoded);
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Examples
|
|
119
|
+
|
|
120
|
+
### 1. Simple Objects
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
const data = { name: 'Alice', age: 30, active: true };
|
|
124
|
+
const encoded = dumps(data);
|
|
125
|
+
// {@name,age,active|Alice,30,true}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### 2. Arrays
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
const data = [1, 2, 3, 4, 5];
|
|
132
|
+
const encoded = dumps(data);
|
|
133
|
+
// [1,2,3,4,5]
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### 3. Array of Objects (Tabular Format)
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
const data = [
|
|
140
|
+
{ id: 1, name: 'Alice', email: 'alice@example.com' },
|
|
141
|
+
{ id: 2, name: 'Bob', email: 'bob@example.com' },
|
|
142
|
+
{ id: 3, name: 'Carol', email: 'carol@example.com' },
|
|
143
|
+
];
|
|
144
|
+
const encoded = dumps(data);
|
|
145
|
+
// {@id,name,email#3|1,Alice,alice@example.com|2,Bob,bob@example.com|3,Carol,carol@example.com}
|
|
146
|
+
|
|
147
|
+
const decoded = loads(encoded);
|
|
148
|
+
// Perfect round-trip!
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### 4. Nested Schema Notation
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
const data = [
|
|
155
|
+
{ id: 1, name: 'Alice', address: { city: 'NYC', zip: '10001' } },
|
|
156
|
+
{ id: 2, name: 'Bob', address: { city: 'LA', zip: '90001' } },
|
|
157
|
+
];
|
|
158
|
+
const encoded = dumps(data);
|
|
159
|
+
// {@id,name,address(@city,zip)#2|1,Alice,{NYC,"10001"}|2,Bob,{LA,"90001"}}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Address keys (`city`, `zip`) are declared once in the schema notation `address(@city,zip)`, then only values appear in rows!
|
|
163
|
+
|
|
164
|
+
### 5. Complex Nested Structures
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
const data = {
|
|
168
|
+
company: 'Acme Corp',
|
|
169
|
+
employees: [
|
|
170
|
+
{
|
|
171
|
+
id: 1,
|
|
172
|
+
name: 'Alice',
|
|
173
|
+
skills: ['Python', 'Go'],
|
|
174
|
+
contact: { email: 'alice@acme.com', phone: '555-0101' },
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
id: 2,
|
|
178
|
+
name: 'Bob',
|
|
179
|
+
skills: ['Java'],
|
|
180
|
+
contact: { email: 'bob@acme.com', phone: '555-0102' },
|
|
181
|
+
},
|
|
182
|
+
],
|
|
183
|
+
metadata: {
|
|
184
|
+
created: '2025-01-27',
|
|
185
|
+
version: '1.0',
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
const encoded = dumps(data);
|
|
190
|
+
const decoded = loads(encoded);
|
|
191
|
+
// Perfect round-trip with complex nesting!
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### 6. Type Preservation
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
const data = {
|
|
198
|
+
zip_string: '10001', // String
|
|
199
|
+
zip_number: 10001, // Number
|
|
200
|
+
version_string: '1.0', // String
|
|
201
|
+
version_number: 1.0, // Float
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
const encoded = dumps(data);
|
|
205
|
+
// {@zip_string,zip_number,version_string,version_number|"10001",10001,"1.0",1.0}
|
|
206
|
+
|
|
207
|
+
const decoded = loads(encoded);
|
|
208
|
+
console.log(typeof decoded.zip_string); // "string"
|
|
209
|
+
console.log(typeof decoded.zip_number); // "number"
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### 7. Empty Values
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
const data = {
|
|
216
|
+
empty_string: '',
|
|
217
|
+
empty_array: [],
|
|
218
|
+
empty_object: {},
|
|
219
|
+
null_value: null,
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
const encoded = dumps(data);
|
|
223
|
+
// {@empty_string,empty_array,empty_object,null_value|"",[],{@},null}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### 8. Special Characters
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
const data = {
|
|
230
|
+
comma: 'hello, world',
|
|
231
|
+
pipe: 'a|b|c',
|
|
232
|
+
quotes: 'She said "hello"',
|
|
233
|
+
newline: 'line1\nline2',
|
|
234
|
+
at_sign: '@username',
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
const encoded = dumps(data);
|
|
238
|
+
const decoded = loads(encoded);
|
|
239
|
+
// Special characters are automatically escaped and preserved
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## LLM Integration
|
|
243
|
+
|
|
244
|
+
### Quick Example
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
import { dumps } from '@zenoaihq/tson';
|
|
248
|
+
|
|
249
|
+
// Prepare data for LLM
|
|
250
|
+
const data = [
|
|
251
|
+
{ date: '2025-01-01', sales: 5000, region: 'North' },
|
|
252
|
+
{ date: '2025-01-02', sales: 6000, region: 'South' },
|
|
253
|
+
{ date: '2025-01-03', sales: 5500, region: 'East' },
|
|
254
|
+
];
|
|
255
|
+
|
|
256
|
+
const tsonData = dumps(data);
|
|
257
|
+
|
|
258
|
+
// System prompt for LLM
|
|
259
|
+
const systemPrompt = `
|
|
260
|
+
TSON format (compact JSON):
|
|
261
|
+
• {@k1,k2|v1,v2} = object
|
|
262
|
+
• {@k1,k2#N|v1,v2|v1,v2} = array of objects
|
|
263
|
+
• Delimiters: @ (keys), | (rows), , (fields), # (count)
|
|
264
|
+
`;
|
|
265
|
+
|
|
266
|
+
const userPrompt = `Analyze this sales data: ${tsonData}`;
|
|
267
|
+
|
|
268
|
+
// Send to LLM API...
|
|
269
|
+
// Token savings: 30-50% compared to JSON!
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
See [../prompts.md](../prompts.md) for complete LLM prompt templates.
|
|
273
|
+
|
|
274
|
+
## Platform Support
|
|
275
|
+
|
|
276
|
+
- **Node.js**: 16.0.0 or higher
|
|
277
|
+
- **Browser**: All modern browsers (ES2020+)
|
|
278
|
+
- **Deno**: Compatible (use npm: specifier)
|
|
279
|
+
- **Bun**: Compatible
|
|
280
|
+
|
|
281
|
+
### Node.js
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
import { dumps, loads, dump, load } from '@zenoaihq/tson';
|
|
285
|
+
|
|
286
|
+
// File I/O available
|
|
287
|
+
await dump(data, 'data.tson');
|
|
288
|
+
const data = await load('data.tson');
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Browser
|
|
292
|
+
|
|
293
|
+
```typescript
|
|
294
|
+
import { dumps, loads } from '@zenoaihq/tson';
|
|
295
|
+
|
|
296
|
+
// File I/O not available in browser
|
|
297
|
+
// Use dumps/loads for string serialization
|
|
298
|
+
const encoded = dumps(data);
|
|
299
|
+
const decoded = loads(encoded);
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## Type Support
|
|
303
|
+
|
|
304
|
+
TSON supports all JSON-compatible types:
|
|
305
|
+
|
|
306
|
+
| JavaScript Type | TSON Representation | Example |
|
|
307
|
+
| --------------- | ------------------------ | --------------------------- |
|
|
308
|
+
| `string` | String (quoted if needed)| `Alice` or `"Hello, World"` |
|
|
309
|
+
| `number` | Number | `42`, `3.14`, `-17` |
|
|
310
|
+
| `boolean` | Boolean | `true`, `false` |
|
|
311
|
+
| `null` | Null | `null` |
|
|
312
|
+
| `Array` | Array | `[1,2,3]` |
|
|
313
|
+
| `Object` | Object | `{@key|value}` |
|
|
314
|
+
|
|
315
|
+
## Performance
|
|
316
|
+
|
|
317
|
+
TSON is optimized for:
|
|
318
|
+
|
|
319
|
+
- **Token efficiency**: 25-70% savings vs JSON
|
|
320
|
+
- **Fast parsing**: Simple delimiter-based parsing
|
|
321
|
+
- **Low memory**: Minimal overhead
|
|
322
|
+
- **Zero dependencies**: Pure TypeScript implementation
|
|
323
|
+
- **Tree-shakeable**: ESM with no side effects
|
|
324
|
+
|
|
325
|
+
## Syntax Guide
|
|
326
|
+
|
|
327
|
+
See [../SPEC.md](../SPEC.md) for complete syntax specification.
|
|
328
|
+
|
|
329
|
+
**Quick reference:**
|
|
330
|
+
|
|
331
|
+
| Delimiter | Purpose | Example |
|
|
332
|
+
| --------- | -------------------- | ---------------------- |
|
|
333
|
+
| `{` `}` | Object boundaries | `{@name|Alice}` |
|
|
334
|
+
| `[` `]` | Array boundaries | `[1,2,3]` |
|
|
335
|
+
| `@` | Object marker | `{@key1,key2|...}` |
|
|
336
|
+
| `,` | Field/value separator| `name,age,city` |
|
|
337
|
+
| `|` | Row separator | `val1,val2|val1,val2` |
|
|
338
|
+
| `#` | Row count (optional) | `#3` |
|
|
339
|
+
|
|
340
|
+
## Testing
|
|
341
|
+
|
|
342
|
+
Run the test suite:
|
|
343
|
+
|
|
344
|
+
```bash
|
|
345
|
+
npm test
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
All 13 tests should pass:
|
|
349
|
+
|
|
350
|
+
```
|
|
351
|
+
✓ should handle simple objects
|
|
352
|
+
✓ should handle simple arrays
|
|
353
|
+
✓ should handle array of objects in tabular format
|
|
354
|
+
✓ should handle nested objects
|
|
355
|
+
✓ should handle mixed type arrays
|
|
356
|
+
✓ should handle empty values
|
|
357
|
+
✓ should handle special characters
|
|
358
|
+
✓ should preserve numeric strings vs numbers
|
|
359
|
+
✓ should handle nested arrays
|
|
360
|
+
✓ should handle array with nested objects using nested schema
|
|
361
|
+
✓ should handle complex real-world-like structures
|
|
362
|
+
✓ should handle boolean values
|
|
363
|
+
✓ should handle various numeric types
|
|
364
|
+
|
|
365
|
+
Test Files 1 passed (1)
|
|
366
|
+
Tests 13 passed (13)
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
## Examples
|
|
370
|
+
|
|
371
|
+
Run the examples:
|
|
372
|
+
|
|
373
|
+
```bash
|
|
374
|
+
npm run dev examples/basic-usage.ts
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
Or with ts-node:
|
|
378
|
+
|
|
379
|
+
```bash
|
|
380
|
+
npx tsx examples/basic-usage.ts
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
## Building
|
|
384
|
+
|
|
385
|
+
Build the package:
|
|
386
|
+
|
|
387
|
+
```bash
|
|
388
|
+
npm run build
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
This generates:
|
|
392
|
+
|
|
393
|
+
- `dist/index.js` - ESM build
|
|
394
|
+
- `dist/index.cjs` - CommonJS build
|
|
395
|
+
- `dist/index.d.ts` - TypeScript declarations
|
|
396
|
+
|
|
397
|
+
## Development
|
|
398
|
+
|
|
399
|
+
```bash
|
|
400
|
+
# Install dependencies
|
|
401
|
+
npm install
|
|
402
|
+
|
|
403
|
+
# Run tests in watch mode
|
|
404
|
+
npm run test:watch
|
|
405
|
+
|
|
406
|
+
# Type check
|
|
407
|
+
npm run typecheck
|
|
408
|
+
|
|
409
|
+
# Lint
|
|
410
|
+
npm run lint
|
|
411
|
+
|
|
412
|
+
# Format
|
|
413
|
+
npm run format
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
## Contributing
|
|
417
|
+
|
|
418
|
+
Contributions are welcome! Please see [../CONTRIBUTING.md](../CONTRIBUTING.md) for guidelines.
|
|
419
|
+
|
|
420
|
+
## Documentation
|
|
421
|
+
|
|
422
|
+
- **[../SPEC.md](../SPEC.md)** - Complete format specification (v1.0)
|
|
423
|
+
- **[QUICKSTART.md](QUICKSTART.md)** - 5-minute quick start guide
|
|
424
|
+
- **[../prompts.md](../prompts.md)** - LLM integration guide
|
|
425
|
+
- **[examples/](examples/)** - Usage examples
|
|
426
|
+
|
|
427
|
+
## Comparison with JSON
|
|
428
|
+
|
|
429
|
+
**Example: Array of 100 user objects**
|
|
430
|
+
|
|
431
|
+
```typescript
|
|
432
|
+
// JSON: ~8,500 characters
|
|
433
|
+
// TSON: ~4,200 characters
|
|
434
|
+
// Savings: 50%+ (scales with more rows!)
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
**Why TSON wins:**
|
|
438
|
+
|
|
439
|
+
- Keys written once (tabular format)
|
|
440
|
+
- No quotes around simple strings
|
|
441
|
+
- No colons, minimal brackets
|
|
442
|
+
- Optional whitespace
|
|
443
|
+
- Nested schema notation for complex structures
|
|
444
|
+
|
|
445
|
+
## Related Projects
|
|
446
|
+
|
|
447
|
+
- [Python Implementation](../python/) - Production ready
|
|
448
|
+
- [TOON by Johann Schopplich](https://github.com/johannschopplich/toon) - Alternative format
|
|
449
|
+
|
|
450
|
+
## License
|
|
451
|
+
|
|
452
|
+
MIT License - see [LICENSE](../LICENSE) file for details.
|
|
453
|
+
|
|
454
|
+
---
|
|
455
|
+
|
|
456
|
+
**Package:** `@zenoaihq/tson`
|
|
457
|
+
**Version:** 1.0.0
|
|
458
|
+
**Status:** Production Ready
|
|
459
|
+
**Node.js:** 16.0.0+
|
|
460
|
+
**TypeScript:** 5.3+
|
|
461
|
+
**Dependencies:** 0
|
|
462
|
+
|
|
463
|
+
*Built by [Zeno AI](https://zenoai.tech) for efficient LLM communication*
|