@zenoaihq/tson 1.0.0 → 1.0.2
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/README.md +3 -2
- package/dist/index.cjs +74 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +74 -11
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[](../LICENSE)
|
|
6
6
|
[](https://www.npmjs.com/package/@zenoaihq/tson)
|
|
7
|
+
[](https://www.npmjs.com/package/@zenoaihq/tson)
|
|
7
8
|
[](https://www.typescriptlang.org/)
|
|
8
9
|
|
|
9
10
|
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.
|
|
@@ -345,7 +346,7 @@ Run the test suite:
|
|
|
345
346
|
npm test
|
|
346
347
|
```
|
|
347
348
|
|
|
348
|
-
All
|
|
349
|
+
All 14 tests should pass:
|
|
349
350
|
|
|
350
351
|
```
|
|
351
352
|
✓ should handle simple objects
|
|
@@ -454,7 +455,7 @@ MIT License - see [LICENSE](../LICENSE) file for details.
|
|
|
454
455
|
---
|
|
455
456
|
|
|
456
457
|
**Package:** `@zenoaihq/tson`
|
|
457
|
-
**Version:** 1.0.
|
|
458
|
+
**Version:** 1.0.2
|
|
458
459
|
**Status:** Production Ready
|
|
459
460
|
**Node.js:** 16.0.0+
|
|
460
461
|
**TypeScript:** 5.3+
|
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
// src/utils.ts
|
|
4
|
-
var SPECIAL_CHARS = /* @__PURE__ */ new Set([",", "|", "@", "#", "{", "}", "[", "]", "\n", "\r", " ", " "]);
|
|
4
|
+
var SPECIAL_CHARS = /* @__PURE__ */ new Set([",", "|", "@", "#", "{", "}", "[", "]", "\n", "\r", " ", " ", '"', "(", ")"]);
|
|
5
5
|
function needsQuoting(value) {
|
|
6
6
|
if (value.length === 0) {
|
|
7
7
|
return true;
|
|
@@ -33,7 +33,36 @@ function escapeString(value) {
|
|
|
33
33
|
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
|
|
34
34
|
}
|
|
35
35
|
function unescapeString(value) {
|
|
36
|
-
|
|
36
|
+
const result = [];
|
|
37
|
+
let i = 0;
|
|
38
|
+
while (i < value.length) {
|
|
39
|
+
if (value[i] === "\\" && i + 1 < value.length) {
|
|
40
|
+
const nextChar = value[i + 1];
|
|
41
|
+
if (nextChar === "\\") {
|
|
42
|
+
result.push("\\");
|
|
43
|
+
i += 2;
|
|
44
|
+
} else if (nextChar === '"') {
|
|
45
|
+
result.push('"');
|
|
46
|
+
i += 2;
|
|
47
|
+
} else if (nextChar === "n") {
|
|
48
|
+
result.push("\n");
|
|
49
|
+
i += 2;
|
|
50
|
+
} else if (nextChar === "r") {
|
|
51
|
+
result.push("\r");
|
|
52
|
+
i += 2;
|
|
53
|
+
} else if (nextChar === "t") {
|
|
54
|
+
result.push(" ");
|
|
55
|
+
i += 2;
|
|
56
|
+
} else {
|
|
57
|
+
result.push(value[i]);
|
|
58
|
+
i += 1;
|
|
59
|
+
}
|
|
60
|
+
} else {
|
|
61
|
+
result.push(value[i]);
|
|
62
|
+
i += 1;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return result.join("");
|
|
37
66
|
}
|
|
38
67
|
function formatPrimitive(value) {
|
|
39
68
|
if (value === null) {
|
|
@@ -162,11 +191,17 @@ function splitByDelimiter(text, delimiter) {
|
|
|
162
191
|
}
|
|
163
192
|
function parseKeySchema(keyString) {
|
|
164
193
|
const trimmed = keyString.trim();
|
|
194
|
+
if (trimmed.startsWith('"') && trimmed.endsWith('"')) {
|
|
195
|
+
return { keyName: unescapeString(trimmed.slice(1, -1)), schema: null };
|
|
196
|
+
}
|
|
165
197
|
if (!trimmed.includes("(")) {
|
|
166
198
|
return { keyName: trimmed, schema: null };
|
|
167
199
|
}
|
|
168
200
|
const parenIdx = trimmed.indexOf("(");
|
|
169
|
-
|
|
201
|
+
let keyName = trimmed.slice(0, parenIdx).trim();
|
|
202
|
+
if (keyName.startsWith('"') && keyName.endsWith('"')) {
|
|
203
|
+
keyName = unescapeString(keyName.slice(1, -1));
|
|
204
|
+
}
|
|
170
205
|
if (!trimmed.endsWith(")")) {
|
|
171
206
|
throw new Error(`Invalid key schema syntax: ${keyString}`);
|
|
172
207
|
}
|
|
@@ -186,13 +221,35 @@ function buildSchemaMap(keys) {
|
|
|
186
221
|
return schemaMap;
|
|
187
222
|
}
|
|
188
223
|
function parseKeys(keysStr) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
const
|
|
224
|
+
let hashIdx = -1;
|
|
225
|
+
let inQuotes = false;
|
|
226
|
+
for (let i = keysStr.length - 1; i >= 0; i--) {
|
|
227
|
+
const char = keysStr[i];
|
|
228
|
+
if (char === '"') {
|
|
229
|
+
let backslashCount = 0;
|
|
230
|
+
for (let j = i - 1; j >= 0; j--) {
|
|
231
|
+
if (keysStr[j] === "\\") {
|
|
232
|
+
backslashCount++;
|
|
233
|
+
} else {
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
if (backslashCount % 2 === 0) {
|
|
238
|
+
inQuotes = !inQuotes;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
if (char === "#" && !inQuotes) {
|
|
242
|
+
hashIdx = i;
|
|
243
|
+
break;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if (hashIdx !== -1) {
|
|
247
|
+
const keysPart = keysStr.slice(0, hashIdx);
|
|
248
|
+
const countPart = keysStr.slice(hashIdx + 1).trim();
|
|
193
249
|
const count = parseInt(countPart, 10);
|
|
194
250
|
if (isNaN(count)) {
|
|
195
|
-
|
|
251
|
+
const keys2 = splitByDelimiter(keysStr, ",");
|
|
252
|
+
return { keys: keys2, count: null };
|
|
196
253
|
}
|
|
197
254
|
const keys = splitByDelimiter(keysPart, ",");
|
|
198
255
|
return { keys, count };
|
|
@@ -275,7 +332,13 @@ function serializeTabular(arr) {
|
|
|
275
332
|
}
|
|
276
333
|
if (key in nestedSchemas) {
|
|
277
334
|
const schemaKeys = nestedSchemas[key];
|
|
278
|
-
const
|
|
335
|
+
const formattedSchemaKeys = schemaKeys.map((sk) => {
|
|
336
|
+
if (needsQuoting(sk)) {
|
|
337
|
+
return `"${escapeString(sk)}"`;
|
|
338
|
+
}
|
|
339
|
+
return sk;
|
|
340
|
+
});
|
|
341
|
+
const schemaStr = formattedSchemaKeys.join(",");
|
|
279
342
|
keyStr = `${keyStr}(@${schemaStr})`;
|
|
280
343
|
}
|
|
281
344
|
keyParts.push(keyStr);
|
|
@@ -382,7 +445,7 @@ function parseKeyedObject(content) {
|
|
|
382
445
|
const keysPart = parts[0];
|
|
383
446
|
const { keys, count } = parseKeys(keysPart);
|
|
384
447
|
const schemaMap = buildSchemaMap(keys);
|
|
385
|
-
const fieldNames = keys.map((k) => k.
|
|
448
|
+
const fieldNames = keys.map((k) => parseKeySchema(k).keyName);
|
|
386
449
|
if (parts.length === 1) {
|
|
387
450
|
throw new Error("Invalid object format: missing values");
|
|
388
451
|
}
|
|
@@ -446,7 +509,7 @@ function parseSchematizedValue(valueStr, schema) {
|
|
|
446
509
|
);
|
|
447
510
|
}
|
|
448
511
|
const nestedSchemaMap = buildSchemaMap(schema);
|
|
449
|
-
const fieldNames = schema.map((k) => k.
|
|
512
|
+
const fieldNames = schema.map((k) => parseKeySchema(k).keyName);
|
|
450
513
|
const obj = {};
|
|
451
514
|
for (let i = 0; i < fieldNames.length; i++) {
|
|
452
515
|
const fieldName = fieldNames[i];
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts","../src/serializer.ts","../src/deserializer.ts"],"names":["valueStr"],"mappings":";;;AAWO,IAAM,gCAAgB,IAAI,GAAA,CAAI,CAAC,GAAA,EAAK,KAAK,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,KAAK,GAAA,EAAK,IAAA,EAAM,IAAA,EAAM,GAAA,EAAM,GAAG,CAAC,CAAA;AAY7F,SAAS,aAAa,KAAA,EAAwB;AACnD,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,IAAI,KAAA,KAAU,MAAA,IAAU,KAAA,KAAU,OAAA,IAAW,UAAU,MAAA,EAAQ;AAC7D,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,IAAI,KAAA,CAAM,CAAC,CAAA,CAAE,IAAA,EAAK,KAAM,EAAA,IAAM,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA,CAAE,IAAA,OAAW,EAAA,EAAI;AACnE,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,IAAI,eAAA,CAAgB,KAAK,CAAA,EAAG;AAC1B,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,IAAI,aAAA,CAAc,GAAA,CAAI,IAAI,CAAA,EAAG;AAC3B,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,KAAA;AACT;AAQO,SAAS,gBAAgB,KAAA,EAAwB;AACtD,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,MAAM,GAAA,GAAM,OAAO,KAAK,CAAA;AACxB,EAAA,OAAO,CAAC,MAAM,GAAG,CAAA,IAAK,MAAM,IAAA,EAAK,KAAM,KAAA,IAAS,QAAA,CAAS,GAAG,CAAA;AAC9D;AAOO,SAAS,aAAa,KAAA,EAAuB;AAElD,EAAA,OAAO,MACJ,OAAA,CAAQ,KAAA,EAAO,MAAM,CAAA,CACrB,OAAA,CAAQ,MAAM,KAAK,CAAA,CACnB,QAAQ,KAAA,EAAO,KAAK,EACpB,OAAA,CAAQ,KAAA,EAAO,KAAK,CAAA,CACpB,OAAA,CAAQ,OAAO,KAAK,CAAA;AACzB;AAOO,SAAS,eAAe,KAAA,EAAuB;AAEpD,EAAA,OAAO,MACJ,OAAA,CAAQ,MAAA,EAAQ,GAAI,CAAA,CACpB,OAAA,CAAQ,QAAQ,IAAI,CAAA,CACpB,QAAQ,MAAA,EAAQ,IAAI,EACpB,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA,CACnB,OAAA,CAAQ,SAAS,IAAI,CAAA;AAC1B;AAKO,SAAS,gBAAgB,KAAA,EAA0B;AACxD,EAAA,IAAI,UAAU,IAAA,EAAM;AAClB,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,IAAI,OAAO,UAAU,SAAA,EAAW;AAC9B,IAAA,OAAO,QAAQ,MAAA,GAAS,OAAA;AAAA,EAC1B;AAEA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAO,OAAO,KAAK,CAAA;AAAA,EACrB;AAEA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,IAAI,YAAA,CAAa,KAAK,CAAA,EAAG;AACvB,MAAA,OAAO,CAAA,CAAA,EAAI,YAAA,CAAa,KAAK,CAAC,CAAA,CAAA,CAAA;AAAA,IAChC;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kCAAA,EAAqC,OAAO,KAAK,CAAA,CAAE,CAAA;AACrE;AAKO,SAAS,eAAe,KAAA,EAA0B;AACvD,EAAA,MAAM,OAAA,GAAU,MAAM,IAAA,EAAK;AAE3B,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,OAAO,EAAA;AAAA,EACT;AAGA,EAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI,YAAY,OAAA,EAAS;AACvB,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,IAAI,QAAQ,UAAA,CAAW,GAAG,KAAK,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AACpD,IAAA,OAAO,cAAA,CAAe,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA;AAAA,EAC5C;AAGA,EAAA,IAAI,eAAA,CAAgB,OAAO,CAAA,EAAG;AAC5B,IAAA,MAAM,GAAA,GAAM,OAAO,OAAO,CAAA;AAC1B,IAAA,IAAI,CAAC,KAAA,CAAM,GAAG,CAAA,EAAG;AACf,MAAA,OAAO,GAAA;AAAA,IACT;AAAA,EACF;AAGA,EAAA,OAAO,OAAA;AACT;AAOO,SAAS,qBAAqB,IAAA,EAAqC;AACxE,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,IAAK,IAAA,CAAK,WAAW,CAAA,EAAG;AAC7C,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,IAAI,CAAC,IAAA,CAAK,KAAA,CAAM,UAAQ,aAAA,CAAc,IAAI,CAAC,CAAA,EAAG;AAC5C,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,MAAM,SAAA,GAAY,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,CAAC,CAAC,CAAA;AAGrC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAQ,CAAA,EAAA,EAAK;AACpC,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,CAAC,CAAC,CAAA;AAChC,IAAA,IAAI,IAAA,CAAK,MAAA,KAAW,SAAA,CAAU,MAAA,EAAQ;AACpC,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAQ,CAAA,EAAA,EAAK;AACpC,MAAA,IAAI,IAAA,CAAK,CAAC,CAAA,KAAM,SAAA,CAAU,CAAC,CAAA,EAAG;AAC5B,QAAA,OAAO,KAAA;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,IAAA;AACT;AAKA,SAAS,cAAc,KAAA,EAAqC;AAC1D,EAAA,OACE,OAAO,KAAA,KAAU,QAAA,IACjB,KAAA,KAAU,QACV,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,KACpB,MAAA,CAAO,SAAA,CAAU,QAAA,CAAS,IAAA,CAAK,KAAK,CAAA,KAAM,iBAAA;AAE9C;AAUO,SAAS,gBAAA,CAAiB,MAAc,SAAA,EAA6B;AAC1E,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,MAAM,UAAoB,EAAC;AAC3B,EAAA,IAAI,QAAA,GAAW,KAAA;AACf,EAAA,IAAI,UAAA,GAAa,KAAA;AACjB,EAAA,IAAI,UAAA,GAAa,CAAA;AACjB,EAAA,IAAI,WAAA,GAAc,CAAA;AAClB,EAAA,IAAI,UAAA,GAAa,CAAA;AAEjB,EAAA,KAAA,MAAW,QAAQ,IAAA,EAAM;AAEvB,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AACjB,MAAA,UAAA,GAAa,KAAA;AACb,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,SAAS,IAAA,EAAM;AACjB,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AACjB,MAAA,UAAA,GAAa,IAAA;AACb,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,SAAS,GAAA,EAAK;AAChB,MAAA,QAAA,GAAW,CAAC,QAAA;AACZ,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AACjB,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AACjB,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,SAAS,GAAA,EAAK;AAChB,MAAA,UAAA,EAAA;AACA,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,IACnB,CAAA,MAAA,IAAW,SAAS,GAAA,EAAK;AACvB,MAAA,UAAA,EAAA;AACA,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,IACnB,CAAA,MAAA,IAAW,SAAS,GAAA,EAAK;AACvB,MAAA,WAAA,EAAA;AACA,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,IACnB,CAAA,MAAA,IAAW,SAAS,GAAA,EAAK;AACvB,MAAA,WAAA,EAAA;AACA,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,IACnB,CAAA,MAAA,IAAW,SAAS,GAAA,EAAK;AACvB,MAAA,UAAA,EAAA;AACA,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,IACnB,CAAA,MAAA,IAAW,SAAS,GAAA,EAAK;AACvB,MAAA,UAAA,EAAA;AACA,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,IACnB,CAAA,MAAA,IACE,SAAS,SAAA,IACT,UAAA,KAAe,KACf,WAAA,KAAgB,CAAA,IAChB,eAAe,CAAA,EACf;AAEA,MAAA,MAAA,CAAO,KAAK,OAAA,CAAQ,IAAA,CAAK,EAAE,CAAA,CAAE,MAAM,CAAA;AACnC,MAAA,OAAA,CAAQ,MAAA,GAAS,CAAA;AAAA,IACnB,CAAA,MAAO;AACL,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,IACnB;AAAA,EACF;AAGA,EAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,IAAA,MAAA,CAAO,KAAK,OAAA,CAAQ,IAAA,CAAK,EAAE,CAAA,CAAE,MAAM,CAAA;AAAA,EACrC;AAEA,EAAA,OAAO,MAAA;AACT;AAUO,SAAS,eAAe,SAAA,EAA8B;AAC3D,EAAA,MAAM,OAAA,GAAU,UAAU,IAAA,EAAK;AAG/B,EAAA,IAAI,CAAC,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AAC1B,IAAA,OAAO,EAAE,OAAA,EAAS,OAAA,EAAS,MAAA,EAAQ,IAAA,EAAK;AAAA,EAC1C;AAGA,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,OAAA,CAAQ,GAAG,CAAA;AACpC,EAAA,MAAM,UAAU,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,QAAQ,EAAE,IAAA,EAAK;AAGhD,EAAA,IAAI,CAAC,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AAC1B,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,2BAAA,EAA8B,SAAS,CAAA,CAAE,CAAA;AAAA,EAC3D;AAEA,EAAA,IAAI,YAAY,OAAA,CAAQ,KAAA,CAAM,WAAW,CAAA,EAAG,EAAE,EAAE,IAAA,EAAK;AAGrD,EAAA,IAAI,SAAA,CAAU,UAAA,CAAW,GAAG,CAAA,EAAG;AAC7B,IAAA,SAAA,GAAY,SAAA,CAAU,MAAM,CAAC,CAAA;AAAA,EAC/B;AAGA,EAAA,MAAM,UAAA,GAAa,gBAAA,CAAiB,SAAA,EAAW,GAAG,CAAA;AAElD,EAAA,OAAO,EAAE,OAAA,EAAS,MAAA,EAAQ,UAAA,EAAW;AACvC;AASO,SAAS,eAAe,IAAA,EAA2B;AACxD,EAAA,MAAM,YAAuB,EAAC;AAE9B,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAO,GAAI,eAAe,GAAG,CAAA;AAC9C,IAAA,SAAA,CAAU,OAAO,CAAA,GAAI,MAAA;AAAA,EACvB;AAEA,EAAA,OAAO,SAAA;AACT;AAOO,SAAS,UAAU,OAAA,EAA6B;AAErD,EAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AAEzB,IAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,WAAA,CAAY,GAAG,CAAA;AAC3C,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,WAAW,CAAA;AAC7C,IAAA,MAAM,YAAY,OAAA,CAAQ,KAAA,CAAM,WAAA,GAAc,CAAC,EAAE,IAAA,EAAK;AAEtD,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,SAAA,EAAW,EAAE,CAAA;AACpC,IAAA,IAAI,KAAA,CAAM,KAAK,CAAA,EAAG;AAChB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,SAAS,CAAA,CAAE,CAAA;AAAA,IACnD;AAEA,IAAA,MAAM,IAAA,GAAO,gBAAA,CAAiB,QAAA,EAAU,GAAG,CAAA;AAC3C,IAAA,OAAO,EAAE,MAAM,KAAA,EAAM;AAAA,EACvB,CAAA,MAAO;AACL,IAAA,MAAM,IAAA,GAAO,gBAAA,CAAiB,OAAA,EAAS,GAAG,CAAA;AAC1C,IAAA,OAAO,EAAE,IAAA,EAAM,KAAA,EAAO,IAAA,EAAK;AAAA,EAC7B;AACF;;;AC/VO,SAAS,MAAM,IAAA,EAAyB;AAC7C,EAAA,OAAO,eAAe,IAAI,CAAA;AAC5B;AAQA,eAAsB,IAAA,CAAK,MAAiB,QAAA,EAAiC;AAE3E,EAAA,MAAM,EAAA,GAAK,MAAM,OAAO,aAAa,CAAA;AACrC,EAAA,MAAM,GAAG,SAAA,CAAU,QAAA,EAAU,KAAA,CAAM,IAAI,GAAG,OAAO,CAAA;AACnD;AAOO,SAAS,eAAe,KAAA,EAA0B;AAEvD,EAAA,IACE,KAAA,KAAU,IAAA,IACV,OAAO,KAAA,KAAU,SAAA,IACjB,OAAO,KAAA,KAAU,QAAA,IACjB,OAAO,KAAA,KAAU,QAAA,EACjB;AACA,IAAA,OAAO,gBAAgB,KAAK,CAAA;AAAA,EAC9B;AAGA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AAExB,IAAA,IAAI,oBAAA,CAAqB,KAAK,CAAA,EAAG;AAC/B,MAAA,OAAO,iBAAiB,KAAK,CAAA;AAAA,IAC/B,CAAA,MAAO;AACL,MAAA,OAAO,eAAe,KAAK,CAAA;AAAA,IAC7B;AAAA,EACF;AAGA,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA,EAAM;AAC/C,IAAA,OAAO,gBAAgB,KAAmB,CAAA;AAAA,EAC5C;AAEA,EAAA,MAAM,IAAI,SAAA,CAAU,CAAA,uBAAA,EAA0B,OAAO,KAAK,CAAA,CAAE,CAAA;AAC9D;AAOO,SAAS,gBAAgB,GAAA,EAAyB;AACvD,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA;AAE5B,EAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,MAAM,WAAqB,EAAC;AAC5B,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,IAAI,MAAA,GAAS,OAAO,GAAG,CAAA;AACvB,IAAA,IAAI,YAAA,CAAa,MAAM,CAAA,EAAG;AACxB,MAAA,MAAA,GAAS,CAAA,CAAA,EAAI,YAAA,CAAa,MAAM,CAAC,CAAA,CAAA,CAAA;AAAA,IACnC;AACA,IAAA,QAAA,CAAS,KAAK,MAAM,CAAA;AAAA,EACtB;AAGA,EAAA,MAAM,aAAuB,EAAC;AAC9B,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,UAAA,CAAW,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,GAAG,CAAC,CAAC,CAAA;AAAA,EAC1C;AAGA,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,IAAA,CAAK,GAAG,CAAA;AACjC,EAAA,MAAM,SAAA,GAAY,UAAA,CAAW,IAAA,CAAK,GAAG,CAAA;AAErC,EAAA,OAAO,CAAA,EAAA,EAAK,OAAO,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA,CAAA;AAClC;AAOO,SAAS,eAAe,GAAA,EAAwB;AACrD,EAAA,IAAI,GAAA,CAAI,WAAW,CAAA,EAAG;AACpB,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,MAAM,aAAuB,EAAC;AAC9B,EAAA,KAAA,MAAW,SAAS,GAAA,EAAK;AACvB,IAAA,UAAA,CAAW,IAAA,CAAK,cAAA,CAAe,KAAK,CAAC,CAAA;AAAA,EACvC;AAEA,EAAA,OAAO,GAAA,GAAM,UAAA,CAAW,IAAA,CAAK,GAAG,CAAA,GAAI,GAAA;AACtC;AAUO,SAAS,iBAAiB,GAAA,EAA2B;AAC1D,EAAA,IAAI,GAAA,CAAI,WAAW,CAAA,EAAG;AACpB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI,CAAC,oBAAA,CAAqB,GAAG,CAAA,EAAG;AAC9B,IAAA,MAAM,IAAI,MAAM,kDAAkD,CAAA;AAAA,EACpE;AAGA,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,GAAA,CAAI,CAAC,CAAC,CAAA;AAC/B,EAAA,MAAM,QAAQ,GAAA,CAAI,MAAA;AAGlB,EAAA,MAAM,aAAA,GAAgB,mBAAA,CAAoB,GAAA,EAAK,IAAI,CAAA;AAGnD,EAAA,MAAM,WAAqB,EAAC;AAC5B,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,IAAI,MAAA,GAAS,OAAO,GAAG,CAAA;AACvB,IAAA,IAAI,YAAA,CAAa,MAAM,CAAA,EAAG;AACxB,MAAA,MAAA,GAAS,CAAA,CAAA,EAAI,YAAA,CAAa,MAAM,CAAC,CAAA,CAAA,CAAA;AAAA,IACnC;AAGA,IAAA,IAAI,OAAO,aAAA,EAAe;AACxB,MAAA,MAAM,UAAA,GAAa,cAAc,GAAG,CAAA;AACpC,MAAA,MAAM,SAAA,GAAY,UAAA,CAAW,IAAA,CAAK,GAAG,CAAA;AACrC,MAAA,MAAA,GAAS,CAAA,EAAG,MAAM,CAAA,EAAA,EAAK,SAAS,CAAA,CAAA,CAAA;AAAA,IAClC;AAEA,IAAA,QAAA,CAAS,KAAK,MAAM,CAAA;AAAA,EACtB;AAEA,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,IAAA,CAAK,GAAG,CAAA;AAGjC,EAAA,MAAM,WAAqB,EAAC;AAC5B,EAAA,KAAA,MAAW,OAAO,GAAA,EAAK;AACrB,IAAA,MAAM,aAAuB,EAAC;AAC9B,IAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,MAAA,MAAM,KAAA,GAAQ,IAAI,GAAG,CAAA;AAGrB,MAAA,IAAI,OAAO,aAAA,EAAe;AACxB,QAAA,UAAA,CAAW,KAAK,0BAAA,CAA2B,KAAA,EAAqB,aAAA,CAAc,GAAG,CAAE,CAAC,CAAA;AAAA,MACtF,CAAA,MAAO;AACL,QAAA,UAAA,CAAW,IAAA,CAAK,cAAA,CAAe,KAAK,CAAC,CAAA;AAAA,MACvC;AAAA,IACF;AACA,IAAA,QAAA,CAAS,IAAA,CAAK,UAAA,CAAW,IAAA,CAAK,GAAG,CAAC,CAAA;AAAA,EACpC;AAEA,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,IAAA,CAAK,GAAG,CAAA;AAEjC,EAAA,OAAO,CAAA,EAAA,EAAK,OAAO,CAAA,CAAA,EAAI,KAAK,IAAI,OAAO,CAAA,CAAA,CAAA;AACzC;AAQO,SAAS,mBAAA,CAAoB,KAAmB,IAAA,EAA2B;AAChF,EAAA,MAAM,gBAA2B,EAAC;AAElC,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AAEtB,IAAA,MAAM,SAAS,GAAA,CAAI,GAAA,CAAI,CAAA,GAAA,KAAO,GAAA,CAAI,GAAG,CAAC,CAAA;AAGtC,IAAA,IAAI,CAAC,MAAA,CAAO,KAAA,CAAM,CAAA,CAAA,KAAK,OAAO,CAAA,KAAM,QAAA,IAAY,CAAA,KAAM,IAAA,IAAQ,CAAC,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAC,CAAA,EAAG;AAChF,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,SAAA,GAAY,MAAA,CAAO,IAAA,CAAK,MAAA,CAAO,CAAC,CAAe,CAAA;AACrD,IAAA,MAAM,UAAU,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA,CAAE,MAAM,CAAA,CAAA,KAAK;AACzC,MAAA,MAAM,OAAA,GAAU,MAAA,CAAO,IAAA,CAAK,CAAe,CAAA;AAC3C,MAAA,OACE,OAAA,CAAQ,MAAA,KAAW,SAAA,CAAU,MAAA,IAC7B,OAAA,CAAQ,KAAA,CAAM,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,KAAM,SAAA,CAAU,CAAC,CAAC,CAAA;AAAA,IAE9C,CAAC,CAAA;AAED,IAAA,IAAI,OAAA,EAAS;AAEX,MAAA,aAAA,CAAc,GAAG,CAAA,GAAI,SAAA;AAAA,IACvB;AAAA,EACF;AAEA,EAAA,OAAO,aAAA;AACT;AAUO,SAAS,0BAAA,CAA2B,KAAiB,MAAA,EAA0B;AACpF,EAAA,IAAI,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,CAAE,WAAW,CAAA,EAAG;AACjC,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,MAAM,aAAuB,EAAC;AAC9B,EAAA,KAAA,MAAW,OAAO,MAAA,EAAQ;AACxB,IAAA,MAAM,KAAA,GAAQ,IAAI,GAAG,CAAA;AACrB,IAAA,UAAA,CAAW,IAAA,CAAK,cAAA,CAAe,KAAK,CAAC,CAAA;AAAA,EACvC;AAEA,EAAA,OAAO,GAAA,GAAM,UAAA,CAAW,IAAA,CAAK,GAAG,CAAA,GAAI,GAAA;AACtC;;;ACxOO,SAAS,MAAM,CAAA,EAAsB;AAC1C,EAAA,MAAM,OAAA,GAAU,EAAE,IAAA,EAAK;AACvB,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO,WAAW,OAAO,CAAA;AAC3B;AAQA,eAAsB,KAAK,QAAA,EAAsC;AAE/D,EAAA,MAAM,EAAA,GAAK,MAAM,OAAO,aAAa,CAAA;AACrC,EAAA,MAAM,OAAA,GAAU,MAAM,EAAA,CAAG,QAAA,CAAS,UAAU,OAAO,CAAA;AACnD,EAAA,OAAO,MAAM,OAAO,CAAA;AACtB;AAQO,SAAS,WAAW,IAAA,EAAyB;AAClD,EAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAE1B,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,OAAO,EAAA;AAAA,EACT;AAGA,EAAA,MAAM,SAAA,GAAY,QAAQ,CAAC,CAAA;AAE3B,EAAA,IAAI,cAAc,GAAA,EAAK;AAErB,IAAA,OAAO,YAAY,OAAO,CAAA;AAAA,EAC5B,CAAA,MAAA,IAAW,cAAc,GAAA,EAAK;AAE5B,IAAA,OAAO,WAAW,OAAO,CAAA;AAAA,EAC3B,CAAA,MAAO;AAEL,IAAA,OAAO,eAAe,OAAO,CAAA;AAAA,EAC/B;AACF;AASO,SAAS,YAAY,IAAA,EAAyB;AACnD,EAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAE1B,EAAA,IAAI,CAAC,QAAQ,UAAA,CAAW,GAAG,KAAK,CAAC,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AACtD,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,uBAAA,EAA0B,IAAI,CAAA,CAAE,CAAA;AAAA,EAClD;AAGA,EAAA,MAAM,UAAU,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,EAAE,EAAE,IAAA,EAAK;AAG1C,EAAA,IAAI,OAAA,KAAY,GAAA,IAAO,OAAA,KAAY,EAAA,EAAI;AACrC,IAAA,OAAO,EAAC;AAAA,EACV;AAGA,EAAA,IAAI,OAAA,CAAQ,UAAA,CAAW,GAAG,CAAA,EAAG;AAC3B,IAAA,OAAO,gBAAA,CAAiB,OAAA,CAAQ,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,EAC1C,CAAA,MAAO;AAIL,IAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,OAAA,EAAS,GAAG,CAAA;AAC5C,IAAA,MAAM,eAAe,MAAA,CAAO,GAAA,CAAI,CAAA,CAAA,KAAK,UAAA,CAAW,CAAC,CAAC,CAAA;AAIlD,IAAA,OAAO,YAAA;AAAA,EACT;AACF;AAOO,SAAS,iBAAiB,OAAA,EAA4B;AAE3D,EAAA,MAAM,KAAA,GAAQ,gBAAA,CAAiB,OAAA,EAAS,GAAG,CAAA;AAE3C,EAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG;AACpB,IAAA,MAAM,IAAI,MAAM,qCAAqC,CAAA;AAAA,EACvD;AAGA,EAAA,MAAM,QAAA,GAAW,MAAM,CAAC,CAAA;AAGxB,EAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAM,GAAI,UAAU,QAAQ,CAAA;AAG1C,EAAA,MAAM,SAAA,GAAY,eAAe,IAAI,CAAA;AAGrC,EAAA,MAAM,UAAA,GAAa,KAAK,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAGhD,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,MAAM,IAAI,MAAM,uCAAuC,CAAA;AAAA,EACzD;AAIA,EAAA,MAAM,UAAA,GAAa,KAAA,CAAM,KAAA,CAAM,CAAC,CAAA;AAIhC,EAAA,MAAM,SAAA,GAAY,KAAA,KAAU,IAAA,IAAQ,UAAA,CAAW,MAAA,GAAS,CAAA;AAExD,EAAA,IAAI,SAAA,EAAW;AAEb,IAAA,OAAO,iBAAA,CAAkB,UAAA,EAAY,UAAA,EAAY,SAAA,EAAW,KAAK,CAAA;AAAA,EACnE,CAAA,MAAO;AAEL,IAAA,OAAO,iBAAA,CAAkB,UAAA,EAAY,UAAA,CAAW,CAAC,GAAG,SAAS,CAAA;AAAA,EAC/D;AACF;AAKO,SAAS,iBAAA,CACd,UAAA,EACA,SAAA,EACA,SAAA,EACY;AAEZ,EAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,SAAA,EAAW,GAAG,CAAA;AAE9C,EAAA,IAAI,MAAA,CAAO,MAAA,KAAW,UAAA,CAAW,MAAA,EAAQ;AACvC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,sBAAA,EAAyB,UAAA,CAAW,MAAM,CAAA,YAAA,EAAe,OAAO,MAAM,CAAA,OAAA;AAAA,KACxE;AAAA,EACF;AAGA,EAAA,MAAM,MAAkB,EAAC;AACzB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,UAAA,CAAW,QAAQ,CAAA,EAAA,EAAK;AAC1C,IAAA,MAAM,SAAA,GAAY,WAAW,CAAC,CAAA;AAC9B,IAAA,MAAM,QAAA,GAAW,OAAO,CAAC,CAAA;AAGzB,IAAA,MAAM,MAAA,GAAS,UAAU,SAAS,CAAA;AAElC,IAAA,IAAI,MAAA,EAAQ;AAEV,MAAA,GAAA,CAAI,SAAS,CAAA,GAAI,qBAAA,CAAsB,QAAA,EAAU,MAAM,CAAA;AAAA,IACzD,CAAA,MAAO;AAEL,MAAA,GAAA,CAAI,SAAS,CAAA,GAAI,UAAA,CAAW,QAAQ,CAAA;AAAA,IACtC;AAAA,EACF;AAEA,EAAA,OAAO,GAAA;AACT;AAKO,SAAS,iBAAA,CACd,UAAA,EACA,QAAA,EACA,SAAA,EACA,aAAA,EACc;AACd,EAAA,MAAM,SAAuB,EAAC;AAE9B,EAAA,KAAA,MAAW,UAAU,QAAA,EAAU;AAC7B,IAAA,IAAI,MAAA,CAAO,IAAA,EAAK,CAAE,MAAA,KAAW,CAAA,EAAG;AAC9B,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,GAAA,GAAM,iBAAA,CAAkB,UAAA,EAAY,MAAA,EAAQ,SAAS,CAAA;AAC3D,IAAA,MAAA,CAAO,KAAK,GAAG,CAAA;AAAA,EACjB;AAGA,EAAA,IAAI,aAAA,KAAkB,IAAA,IAAQ,MAAA,CAAO,MAAA,KAAW,aAAA,EAAe;AAC7D,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,6BAAA,EAAgC,aAAa,CAAA,cAAA,EAAiB,MAAA,CAAO,MAAM,CAAA;AAAA,KAC7E;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAQO,SAAS,qBAAA,CAAsB,UAAkB,MAAA,EAA8B;AACpF,EAAA,MAAM,OAAA,GAAU,SAAS,IAAA,EAAK;AAG9B,EAAA,IAAI,CAAC,QAAQ,UAAA,CAAW,GAAG,KAAK,CAAC,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AACtD,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,6CAAA,EAAgD,QAAQ,CAAA,CAAE,CAAA;AAAA,EAC5E;AAGA,EAAA,MAAM,UAAU,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,EAAE,EAAE,IAAA,EAAK;AAG1C,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,OAAO,EAAC;AAAA,EACV;AAGA,EAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,OAAA,EAAS,GAAG,CAAA;AAE5C,EAAA,IAAI,MAAA,CAAO,MAAA,KAAW,MAAA,CAAO,MAAA,EAAQ;AACnC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,iBAAA,EAAoB,MAAA,CAAO,MAAM,CAAA,UAAA,EAAa,OAAO,MAAM,CAAA,OAAA;AAAA,KAC7D;AAAA,EACF;AAGA,EAAA,MAAM,eAAA,GAAkB,eAAe,MAAM,CAAA;AAG7C,EAAA,MAAM,UAAA,GAAa,OAAO,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAGlD,EAAA,MAAM,MAAkB,EAAC;AACzB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,UAAA,CAAW,QAAQ,CAAA,EAAA,EAAK;AAC1C,IAAA,MAAM,SAAA,GAAY,WAAW,CAAC,CAAA;AAC9B,IAAA,MAAMA,SAAAA,GAAW,OAAO,CAAC,CAAA;AAGzB,IAAA,MAAM,YAAA,GAAe,gBAAgB,SAAS,CAAA;AAE9C,IAAA,IAAI,YAAA,EAAc;AAEhB,MAAA,GAAA,CAAI,SAAS,CAAA,GAAI,qBAAA,CAAsBA,SAAAA,EAAU,YAAY,CAAA;AAAA,IAC/D,CAAA,MAAO;AAEL,MAAA,GAAA,CAAI,SAAS,CAAA,GAAI,UAAA,CAAWA,SAAQ,CAAA;AAAA,IACtC;AAAA,EACF;AAEA,EAAA,OAAO,GAAA;AACT;AAOO,SAAS,WAAW,IAAA,EAAyB;AAClD,EAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAE1B,EAAA,IAAI,CAAC,QAAQ,UAAA,CAAW,GAAG,KAAK,CAAC,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AACtD,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,sBAAA,EAAyB,IAAI,CAAA,CAAE,CAAA;AAAA,EACjD;AAGA,EAAA,MAAM,UAAU,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,EAAE,EAAE,IAAA,EAAK;AAG1C,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,OAAO,EAAC;AAAA,EACV;AAGA,EAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,OAAA,EAAS,GAAG,CAAA;AAG5C,EAAA,MAAM,SAAoB,EAAC;AAC3B,EAAA,KAAA,MAAW,YAAY,MAAA,EAAQ;AAC7B,IAAA,IAAI,QAAA,CAAS,IAAA,EAAK,CAAE,MAAA,GAAS,CAAA,EAAG;AAE9B,MAAA,MAAA,CAAO,IAAA,CAAK,UAAA,CAAW,QAAQ,CAAC,CAAA;AAAA,IAClC;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT","file":"index.cjs","sourcesContent":["/**\n * TSON Utility Functions\n *\n * Helper functions for serialization, deserialization, and validation.\n */\n\nimport type { TSONValue, TSONObject, SchemaMap, KeySchema, ParsedKeys } from './types';\n\n/**\n * Special characters that require string quoting\n */\nexport const SPECIAL_CHARS = new Set([',', '|', '@', '#', '{', '}', '[', ']', '\\n', '\\r', '\\t', ' ']);\n\n/**\n * Determine if a string value needs to be quoted in TSON format.\n *\n * Strings need quoting if they:\n * - Are empty\n * - Contain special delimiter characters\n * - Have leading/trailing whitespace\n * - Look like numbers (to preserve them as strings)\n * - Look like reserved words (true/false/null) when we want them as strings\n */\nexport function needsQuoting(value: string): boolean {\n if (value.length === 0) {\n return true;\n }\n\n // Check for reserved words that we want to keep as strings\n if (value === 'true' || value === 'false' || value === 'null') {\n return true;\n }\n\n // Check for leading/trailing whitespace\n if (value[0].trim() === '' || value[value.length - 1].trim() === '') {\n return true;\n }\n\n // Check if it looks like a number (preserve type distinction)\n if (looksLikeNumber(value)) {\n return true;\n }\n\n // Check for special characters\n for (const char of value) {\n if (SPECIAL_CHARS.has(char)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if a string looks like a numeric value.\n *\n * Used to determine if we should quote a string to preserve it as a string\n * rather than having it parsed as a number.\n */\nexport function looksLikeNumber(value: string): boolean {\n if (value.length === 0) {\n return false;\n }\n\n // Try parsing as number\n const num = Number(value);\n return !isNaN(num) && value.trim() === value && isFinite(num);\n}\n\n/**\n * Escape special characters in a string for quoted representation.\n *\n * Uses standard JSON escape sequences.\n */\nexport function escapeString(value: string): string {\n // Order matters: backslash first to avoid double-escaping\n return value\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\n/g, '\\\\n')\n .replace(/\\r/g, '\\\\r')\n .replace(/\\t/g, '\\\\t');\n}\n\n/**\n * Unescape a quoted string back to its original form.\n *\n * Reverses the escaping done by escapeString().\n */\nexport function unescapeString(value: string): string {\n // Order matters: process in reverse order of escaping\n return value\n .replace(/\\\\t/g, '\\t')\n .replace(/\\\\r/g, '\\r')\n .replace(/\\\\n/g, '\\n')\n .replace(/\\\\\"/g, '\"')\n .replace(/\\\\\\\\/g, '\\\\');\n}\n\n/**\n * Format a primitive value as TSON string.\n */\nexport function formatPrimitive(value: TSONValue): string {\n if (value === null) {\n return 'null';\n }\n\n if (typeof value === 'boolean') {\n return value ? 'true' : 'false';\n }\n\n if (typeof value === 'number') {\n return String(value);\n }\n\n if (typeof value === 'string') {\n if (needsQuoting(value)) {\n return `\"${escapeString(value)}\"`;\n }\n return value;\n }\n\n throw new Error(`Cannot format non-primitive type: ${typeof value}`);\n}\n\n/**\n * Parse a TSON primitive value string to JavaScript type.\n */\nexport function parsePrimitive(value: string): TSONValue {\n const trimmed = value.trim();\n\n if (trimmed.length === 0) {\n return '';\n }\n\n // Check for boolean\n if (trimmed === 'true') {\n return true;\n }\n if (trimmed === 'false') {\n return false;\n }\n\n // Check for null\n if (trimmed === 'null') {\n return null;\n }\n\n // Check for quoted string\n if (trimmed.startsWith('\"') && trimmed.endsWith('\"')) {\n return unescapeString(trimmed.slice(1, -1));\n }\n\n // Try to parse as number\n if (looksLikeNumber(trimmed)) {\n const num = Number(trimmed);\n if (!isNaN(num)) {\n return num;\n }\n }\n\n // Otherwise it's an unquoted string\n return trimmed;\n}\n\n/**\n * Check if a value is an array of objects with identical keys.\n *\n * This determines if we can use tabular format optimization.\n */\nexport function isUniformObjectArray(data: unknown): data is TSONObject[] {\n if (!Array.isArray(data) || data.length === 0) {\n return false;\n }\n\n // All elements must be plain objects\n if (!data.every(item => isPlainObject(item))) {\n return false;\n }\n\n // Get keys from first element\n const firstKeys = Object.keys(data[0]);\n\n // Check that all elements have the same keys in the same order\n for (let i = 1; i < data.length; i++) {\n const keys = Object.keys(data[i]);\n if (keys.length !== firstKeys.length) {\n return false;\n }\n for (let j = 0; j < keys.length; j++) {\n if (keys[j] !== firstKeys[j]) {\n return false;\n }\n }\n }\n\n return true;\n}\n\n/**\n * Check if value is a plain object (not array, null, or other special object)\n */\nfunction isPlainObject(value: unknown): value is TSONObject {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.prototype.toString.call(value) === '[object Object]'\n );\n}\n\n/**\n * Split text by delimiter, respecting quoted strings and nested structures.\n *\n * This is more sophisticated than string.split() because it handles:\n * - Quoted strings (don't split on delimiters inside quotes)\n * - Nested braces/brackets/parentheses (don't split inside nested structures)\n * - Escaped characters\n */\nexport function splitByDelimiter(text: string, delimiter: string): string[] {\n const result: string[] = [];\n const current: string[] = [];\n let inQuotes = false;\n let escapeNext = false;\n let depthCurly = 0;\n let depthSquare = 0;\n let depthParen = 0;\n\n for (const char of text) {\n // Handle escape sequences\n if (escapeNext) {\n current.push(char);\n escapeNext = false;\n continue;\n }\n\n if (char === '\\\\') {\n current.push(char);\n escapeNext = true;\n continue;\n }\n\n // Handle quotes\n if (char === '\"') {\n inQuotes = !inQuotes;\n current.push(char);\n continue;\n }\n\n // Inside quotes, add everything\n if (inQuotes) {\n current.push(char);\n continue;\n }\n\n // Track nesting depth\n if (char === '{') {\n depthCurly++;\n current.push(char);\n } else if (char === '}') {\n depthCurly--;\n current.push(char);\n } else if (char === '[') {\n depthSquare++;\n current.push(char);\n } else if (char === ']') {\n depthSquare--;\n current.push(char);\n } else if (char === '(') {\n depthParen++;\n current.push(char);\n } else if (char === ')') {\n depthParen--;\n current.push(char);\n } else if (\n char === delimiter &&\n depthCurly === 0 &&\n depthSquare === 0 &&\n depthParen === 0\n ) {\n // Found unquoted, unnested delimiter - split here\n result.push(current.join('').trim());\n current.length = 0;\n } else {\n current.push(char);\n }\n }\n\n // Add final segment\n if (current.length > 0) {\n result.push(current.join('').trim());\n }\n\n return result;\n}\n\n/**\n * Parse a key which may include nested schema notation.\n *\n * Examples:\n * \"name\" -> { keyName: \"name\", schema: null }\n * \"address(@city,zip)\" -> { keyName: \"address\", schema: [\"city\", \"zip\"] }\n * \"location(@coords(@lat,lng))\" -> { keyName: \"location\", schema: [\"coords(@lat,lng)\"] }\n */\nexport function parseKeySchema(keyString: string): KeySchema {\n const trimmed = keyString.trim();\n\n // Check if key has nested schema\n if (!trimmed.includes('(')) {\n return { keyName: trimmed, schema: null };\n }\n\n // Find the opening parenthesis\n const parenIdx = trimmed.indexOf('(');\n const keyName = trimmed.slice(0, parenIdx).trim();\n\n // Extract schema (everything between outermost parentheses)\n if (!trimmed.endsWith(')')) {\n throw new Error(`Invalid key schema syntax: ${keyString}`);\n }\n\n let schemaStr = trimmed.slice(parenIdx + 1, -1).trim();\n\n // Strip leading @ if present (part of notation, not key name)\n if (schemaStr.startsWith('@')) {\n schemaStr = schemaStr.slice(1);\n }\n\n // Split schema by commas (respecting nested parentheses)\n const schemaKeys = splitByDelimiter(schemaStr, ',');\n\n return { keyName, schema: schemaKeys };\n}\n\n/**\n * Build a mapping of field names to their nested schemas.\n *\n * Example:\n * [\"id\", \"address(@city,zip)\"]\n * -> { id: null, address: [\"city\", \"zip\"] }\n */\nexport function buildSchemaMap(keys: string[]): SchemaMap {\n const schemaMap: SchemaMap = {};\n\n for (const key of keys) {\n const { keyName, schema } = parseKeySchema(key);\n schemaMap[keyName] = schema;\n }\n\n return schemaMap;\n}\n\n/**\n * Parse keys string and extract row count if present.\n *\n * Format: key1,key2,key3 or key1,key2,key3#N\n */\nexport function parseKeys(keysStr: string): ParsedKeys {\n // Check for row count marker\n if (keysStr.includes('#')) {\n // Split from right in case # appears in key name\n const lastHashIdx = keysStr.lastIndexOf('#');\n const keysPart = keysStr.slice(0, lastHashIdx);\n const countPart = keysStr.slice(lastHashIdx + 1).trim();\n\n const count = parseInt(countPart, 10);\n if (isNaN(count)) {\n throw new Error(`Invalid row count: ${countPart}`);\n }\n\n const keys = splitByDelimiter(keysPart, ',');\n return { keys, count };\n } else {\n const keys = splitByDelimiter(keysStr, ',');\n return { keys, count: null };\n }\n}\n","/**\n * TSON Serializer\n *\n * Converts JavaScript data structures to TSON format.\n */\n\nimport type { TSONValue, TSONObject, TSONArray, SchemaMap } from './types';\nimport {\n formatPrimitive,\n needsQuoting,\n escapeString,\n isUniformObjectArray,\n} from './utils';\n\n/**\n * Serialize JavaScript object to TSON formatted string.\n *\n * @example\n * dumps({ name: \"Alice\", age: 30 })\n * // Returns: '{@name,age|Alice,30}'\n *\n * @example\n * dumps([{ id: 1, name: \"Alice\" }, { id: 2, name: \"Bob\" }])\n * // Returns: '{@id,name#2|1,Alice|2,Bob}'\n */\nexport function dumps(data: TSONValue): string {\n return serializeValue(data);\n}\n\n/**\n * Serialize JavaScript object to TSON formatted file (Node.js only).\n *\n * @param data - JavaScript object to serialize\n * @param filePath - Path to file to write\n */\nexport async function dump(data: TSONValue, filePath: string): Promise<void> {\n // Dynamic import for Node.js fs module\n const fs = await import('fs/promises');\n await fs.writeFile(filePath, dumps(data), 'utf-8');\n}\n\n/**\n * Serialize any JavaScript value to TSON format.\n *\n * Dispatches to appropriate serializer based on type.\n */\nexport function serializeValue(value: TSONValue): string {\n // Handle primitives\n if (\n value === null ||\n typeof value === 'boolean' ||\n typeof value === 'number' ||\n typeof value === 'string'\n ) {\n return formatPrimitive(value);\n }\n\n // Handle arrays\n if (Array.isArray(value)) {\n // Check if it's a uniform array of objects (tabular optimization)\n if (isUniformObjectArray(value)) {\n return serializeTabular(value);\n } else {\n return serializeArray(value);\n }\n }\n\n // Handle objects\n if (typeof value === 'object' && value !== null) {\n return serializeObject(value as TSONObject);\n }\n\n throw new TypeError(`Cannot serialize type: ${typeof value}`);\n}\n\n/**\n * Serialize a JavaScript object to TSON object format.\n *\n * Format: {@key1,key2|value1,value2}\n */\nexport function serializeObject(obj: TSONObject): string {\n const keys = Object.keys(obj);\n\n if (keys.length === 0) {\n return '{@}';\n }\n\n // Format keys\n const keyParts: string[] = [];\n for (const key of keys) {\n let keyStr = String(key);\n if (needsQuoting(keyStr)) {\n keyStr = `\"${escapeString(keyStr)}\"`;\n }\n keyParts.push(keyStr);\n }\n\n // Format values\n const valueParts: string[] = [];\n for (const key of keys) {\n valueParts.push(serializeValue(obj[key]));\n }\n\n // Build object string\n const keysStr = keyParts.join(',');\n const valuesStr = valueParts.join(',');\n\n return `{@${keysStr}|${valuesStr}}`;\n}\n\n/**\n * Serialize a JavaScript array to TSON array format.\n *\n * Format: [value1,value2,value3]\n */\nexport function serializeArray(arr: TSONArray): string {\n if (arr.length === 0) {\n return '[]';\n }\n\n // Serialize each element\n const valueParts: string[] = [];\n for (const value of arr) {\n valueParts.push(serializeValue(value));\n }\n\n return '[' + valueParts.join(',') + ']';\n}\n\n/**\n * Serialize a uniform array of objects in tabular format.\n *\n * Format: {@key1,key2#N|val1,val2|val1,val2}\n *\n * This is the key optimization: keys are declared once instead of repeated\n * for each object in the array.\n */\nexport function serializeTabular(arr: TSONObject[]): string {\n if (arr.length === 0) {\n return '[]';\n }\n\n if (!isUniformObjectArray(arr)) {\n throw new Error('Array is not uniform - cannot use tabular format');\n }\n\n // Get keys from first object\n const keys = Object.keys(arr[0]);\n const count = arr.length;\n\n // Check if any values are objects with uniform structure (nested schema opportunity)\n const nestedSchemas = detectNestedSchemas(arr, keys);\n\n // Format keys (with nested schemas if applicable)\n const keyParts: string[] = [];\n for (const key of keys) {\n let keyStr = String(key);\n if (needsQuoting(keyStr)) {\n keyStr = `\"${escapeString(keyStr)}\"`;\n }\n\n // Add nested schema notation if applicable\n if (key in nestedSchemas) {\n const schemaKeys = nestedSchemas[key]!;\n const schemaStr = schemaKeys.join(',');\n keyStr = `${keyStr}(@${schemaStr})`;\n }\n\n keyParts.push(keyStr);\n }\n\n const keysStr = keyParts.join(',');\n\n // Format rows\n const rowParts: string[] = [];\n for (const obj of arr) {\n const valueParts: string[] = [];\n for (const key of keys) {\n const value = obj[key];\n\n // If this key has a nested schema, serialize as schematized object\n if (key in nestedSchemas) {\n valueParts.push(serializeSchematizedObject(value as TSONObject, nestedSchemas[key]!));\n } else {\n valueParts.push(serializeValue(value));\n }\n }\n rowParts.push(valueParts.join(','));\n }\n\n const rowsStr = rowParts.join('|');\n\n return `{@${keysStr}#${count}|${rowsStr}}`;\n}\n\n/**\n * Detect if any fields contain uniform nested objects that can use schema notation.\n *\n * For each key, checks if all values are objects with identical keys.\n * If so, that field can use nested schema notation.\n */\nexport function detectNestedSchemas(arr: TSONObject[], keys: string[]): SchemaMap {\n const nestedSchemas: SchemaMap = {};\n\n for (const key of keys) {\n // Get all values for this key\n const values = arr.map(obj => obj[key]);\n\n // Check if all values are plain objects\n if (!values.every(v => typeof v === 'object' && v !== null && !Array.isArray(v))) {\n continue;\n }\n\n if (values.length === 0) {\n continue;\n }\n\n // Check if all objects have the same keys\n const firstKeys = Object.keys(values[0] as TSONObject);\n const allSame = values.slice(1).every(v => {\n const objKeys = Object.keys(v as TSONObject);\n return (\n objKeys.length === firstKeys.length &&\n objKeys.every((k, i) => k === firstKeys[i])\n );\n });\n\n if (allSame) {\n // This field can use nested schema\n nestedSchemas[key] = firstKeys;\n }\n }\n\n return nestedSchemas;\n}\n\n/**\n * Serialize an object using a pre-declared schema.\n *\n * Format: {value1,value2} (no @ marker, values only)\n *\n * The @ marker is omitted because the schema was already declared in the\n * parent structure.\n */\nexport function serializeSchematizedObject(obj: TSONObject, schema: string[]): string {\n if (Object.keys(obj).length === 0) {\n return '{}';\n }\n\n // Serialize values in schema order\n const valueParts: string[] = [];\n for (const key of schema) {\n const value = obj[key];\n valueParts.push(serializeValue(value));\n }\n\n return '{' + valueParts.join(',') + '}';\n}\n","/**\n * TSON Deserializer\n *\n * Parses TSON format back to JavaScript data structures.\n */\n\nimport type { TSONValue, TSONObject, TSONArray, SchemaMap } from './types';\nimport {\n parsePrimitive,\n splitByDelimiter,\n buildSchemaMap,\n parseKeys,\n} from './utils';\n\n/**\n * Deserialize TSON formatted string to JavaScript object.\n *\n * @example\n * loads('{@name,age|Alice,30}')\n * // Returns: { name: 'Alice', age: 30 }\n *\n * @example\n * loads('{@id,name#2|1,Alice|2,Bob}')\n * // Returns: [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]\n */\nexport function loads(s: string): TSONValue {\n const trimmed = s.trim();\n if (trimmed.length === 0) {\n return null;\n }\n\n return parseValue(trimmed);\n}\n\n/**\n * Deserialize TSON formatted file to JavaScript object (Node.js only).\n *\n * @param filePath - Path to file to read\n * @returns Parsed JavaScript object\n */\nexport async function load(filePath: string): Promise<TSONValue> {\n // Dynamic import for Node.js fs module\n const fs = await import('fs/promises');\n const content = await fs.readFile(filePath, 'utf-8');\n return loads(content);\n}\n\n/**\n * Parse a TSON value of any type.\n *\n * Determines the type by looking at the first character and dispatches\n * to the appropriate parser.\n */\nexport function parseValue(text: string): TSONValue {\n const trimmed = text.trim();\n\n if (trimmed.length === 0) {\n return '';\n }\n\n // Check first character to determine type\n const firstChar = trimmed[0];\n\n if (firstChar === '{') {\n // Object (with @ marker) or schematized object\n return parseObject(trimmed);\n } else if (firstChar === '[') {\n // Array\n return parseArray(trimmed);\n } else {\n // Primitive value\n return parsePrimitive(trimmed);\n }\n}\n\n/**\n * Parse TSON object format.\n *\n * Handles both:\n * - {@key1,key2|val1,val2} - Single object or array of objects\n * - {val1,val2} - Schematized object (no @ marker)\n */\nexport function parseObject(text: string): TSONValue {\n const trimmed = text.trim();\n\n if (!trimmed.startsWith('{') || !trimmed.endsWith('}')) {\n throw new Error(`Invalid object format: ${text}`);\n }\n\n // Extract content between braces\n const content = trimmed.slice(1, -1).trim();\n\n // Empty object\n if (content === '@' || content === '') {\n return {};\n }\n\n // Check if this has @ marker (object with keys)\n if (content.startsWith('@')) {\n return parseKeyedObject(content.slice(1)); // Remove @ marker\n } else {\n // Schematized object without @ marker (just values)\n // This shouldn't happen at top level but can occur as nested value\n // Parse as comma-separated values\n const values = splitByDelimiter(content, ',');\n const parsedValues = values.map(v => parseValue(v));\n\n // Return as array (since we don't have keys)\n // In practice, this shouldn't be hit at top level\n return parsedValues;\n }\n}\n\n/**\n * Parse content after @ marker in object.\n *\n * Format: key1,key2|val1,val2 or key1,key2#N|val1,val2|val1,val2\n */\nexport function parseKeyedObject(content: string): TSONValue {\n // Split by pipe to separate keys from values\n const parts = splitByDelimiter(content, '|');\n\n if (parts.length < 1) {\n throw new Error('Invalid object format: missing keys');\n }\n\n // First part contains keys (and possibly row count)\n const keysPart = parts[0];\n\n // Parse keys and extract count if present\n const { keys, count } = parseKeys(keysPart);\n\n // Build schema map (maps field names to nested schemas)\n const schemaMap = buildSchemaMap(keys);\n\n // Get actual field names (without schema notation)\n const fieldNames = keys.map(k => k.split('(')[0]);\n\n // If only one part, it's an error (no values)\n if (parts.length === 1) {\n throw new Error('Invalid object format: missing values');\n }\n\n // If two parts, could be single object or array with one row\n // If more than two parts, definitely array (multiple rows)\n const valueParts = parts.slice(1);\n\n // Check if this is tabular format (array) or single object\n // If count is specified or multiple value parts, it's tabular\n const isTabular = count !== null || valueParts.length > 1;\n\n if (isTabular) {\n // Array of objects (tabular format)\n return parseTabularArray(fieldNames, valueParts, schemaMap, count);\n } else {\n // Single object\n return parseSingleObject(fieldNames, valueParts[0], schemaMap);\n }\n}\n\n/**\n * Parse a single object from keys and values.\n */\nexport function parseSingleObject(\n fieldNames: string[],\n valuesStr: string,\n schemaMap: SchemaMap\n): TSONObject {\n // Split values\n const values = splitByDelimiter(valuesStr, ',');\n\n if (values.length !== fieldNames.length) {\n throw new Error(\n `Field count mismatch: ${fieldNames.length} fields but ${values.length} values`\n );\n }\n\n // Build object\n const obj: TSONObject = {};\n for (let i = 0; i < fieldNames.length; i++) {\n const fieldName = fieldNames[i];\n const valueStr = values[i];\n\n // Check if this field has a nested schema\n const schema = schemaMap[fieldName];\n\n if (schema) {\n // Parse as schematized object\n obj[fieldName] = parseSchematizedValue(valueStr, schema);\n } else {\n // Parse as regular value\n obj[fieldName] = parseValue(valueStr);\n }\n }\n\n return obj;\n}\n\n/**\n * Parse tabular format into array of objects.\n */\nexport function parseTabularArray(\n fieldNames: string[],\n rowParts: string[],\n schemaMap: SchemaMap,\n expectedCount: number | null\n): TSONObject[] {\n const result: TSONObject[] = [];\n\n for (const rowStr of rowParts) {\n if (rowStr.trim().length === 0) {\n continue;\n }\n\n const obj = parseSingleObject(fieldNames, rowStr, schemaMap);\n result.push(obj);\n }\n\n // Verify count if specified\n if (expectedCount !== null && result.length !== expectedCount) {\n throw new Error(\n `Row count mismatch: expected ${expectedCount} rows but got ${result.length}`\n );\n }\n\n return result;\n}\n\n/**\n * Parse a value that uses a nested schema.\n *\n * The value should be in format {val1,val2} where values correspond to\n * the keys in the schema.\n */\nexport function parseSchematizedValue(valueStr: string, schema: string[]): TSONObject {\n const trimmed = valueStr.trim();\n\n // Should be wrapped in braces\n if (!trimmed.startsWith('{') || !trimmed.endsWith('}')) {\n throw new Error(`Schematized value must be wrapped in braces: ${valueStr}`);\n }\n\n // Extract content\n const content = trimmed.slice(1, -1).trim();\n\n // Empty object\n if (content.length === 0) {\n return {};\n }\n\n // Split by comma\n const values = splitByDelimiter(content, ',');\n\n if (values.length !== schema.length) {\n throw new Error(\n `Schema mismatch: ${schema.length} keys but ${values.length} values`\n );\n }\n\n // Build nested schema map for recursive schemas\n const nestedSchemaMap = buildSchemaMap(schema);\n\n // Get field names (without schema notation)\n const fieldNames = schema.map(k => k.split('(')[0]);\n\n // Build object\n const obj: TSONObject = {};\n for (let i = 0; i < fieldNames.length; i++) {\n const fieldName = fieldNames[i];\n const valueStr = values[i];\n\n // Check if this field itself has a nested schema\n const nestedSchema = nestedSchemaMap[fieldName];\n\n if (nestedSchema) {\n // Recursively parse with nested schema\n obj[fieldName] = parseSchematizedValue(valueStr, nestedSchema);\n } else {\n // Parse as regular value\n obj[fieldName] = parseValue(valueStr);\n }\n }\n\n return obj;\n}\n\n/**\n * Parse TSON array format.\n *\n * Format: [value1,value2,value3]\n */\nexport function parseArray(text: string): TSONArray {\n const trimmed = text.trim();\n\n if (!trimmed.startsWith('[') || !trimmed.endsWith(']')) {\n throw new Error(`Invalid array format: ${text}`);\n }\n\n // Extract content between brackets\n const content = trimmed.slice(1, -1).trim();\n\n // Empty array\n if (content.length === 0) {\n return [];\n }\n\n // Split by comma\n const values = splitByDelimiter(content, ',');\n\n // Parse each value\n const result: TSONArray = [];\n for (const valueStr of values) {\n if (valueStr.trim().length > 0) {\n // Skip empty strings from trailing commas\n result.push(parseValue(valueStr));\n }\n }\n\n return result;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/serializer.ts","../src/deserializer.ts"],"names":["keys","valueStr"],"mappings":";;;AAWO,IAAM,gCAAgB,IAAI,GAAA,CAAI,CAAC,GAAA,EAAK,GAAA,EAAK,KAAK,GAAA,EAAK,GAAA,EAAK,KAAK,GAAA,EAAK,GAAA,EAAK,MAAM,IAAA,EAAM,GAAA,EAAM,KAAK,GAAA,EAAK,GAAA,EAAK,GAAG,CAAC,CAAA;AAY5G,SAAS,aAAa,KAAA,EAAwB;AACnD,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,IAAI,KAAA,KAAU,MAAA,IAAU,KAAA,KAAU,OAAA,IAAW,UAAU,MAAA,EAAQ;AAC7D,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,IAAI,KAAA,CAAM,CAAC,CAAA,CAAE,IAAA,EAAK,KAAM,EAAA,IAAM,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA,CAAE,IAAA,OAAW,EAAA,EAAI;AACnE,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,IAAI,eAAA,CAAgB,KAAK,CAAA,EAAG;AAC1B,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,IAAI,aAAA,CAAc,GAAA,CAAI,IAAI,CAAA,EAAG;AAC3B,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,KAAA;AACT;AAQO,SAAS,gBAAgB,KAAA,EAAwB;AACtD,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,MAAM,GAAA,GAAM,OAAO,KAAK,CAAA;AACxB,EAAA,OAAO,CAAC,MAAM,GAAG,CAAA,IAAK,MAAM,IAAA,EAAK,KAAM,KAAA,IAAS,QAAA,CAAS,GAAG,CAAA;AAC9D;AAOO,SAAS,aAAa,KAAA,EAAuB;AAElD,EAAA,OAAO,MACJ,OAAA,CAAQ,KAAA,EAAO,MAAM,CAAA,CACrB,OAAA,CAAQ,MAAM,KAAK,CAAA,CACnB,QAAQ,KAAA,EAAO,KAAK,EACpB,OAAA,CAAQ,KAAA,EAAO,KAAK,CAAA,CACpB,OAAA,CAAQ,OAAO,KAAK,CAAA;AACzB;AAQO,SAAS,eAAe,KAAA,EAAuB;AACpD,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,IAAI,CAAA,GAAI,CAAA;AACR,EAAA,OAAO,CAAA,GAAI,MAAM,MAAA,EAAQ;AACvB,IAAA,IAAI,MAAM,CAAC,CAAA,KAAM,QAAQ,CAAA,GAAI,CAAA,GAAI,MAAM,MAAA,EAAQ;AAC7C,MAAA,MAAM,QAAA,GAAW,KAAA,CAAM,CAAA,GAAI,CAAC,CAAA;AAC5B,MAAA,IAAI,aAAa,IAAA,EAAM;AACrB,QAAA,MAAA,CAAO,KAAK,IAAI,CAAA;AAChB,QAAA,CAAA,IAAK,CAAA;AAAA,MACP,CAAA,MAAA,IAAW,aAAa,GAAA,EAAK;AAC3B,QAAA,MAAA,CAAO,KAAK,GAAG,CAAA;AACf,QAAA,CAAA,IAAK,CAAA;AAAA,MACP,CAAA,MAAA,IAAW,aAAa,GAAA,EAAK;AAC3B,QAAA,MAAA,CAAO,KAAK,IAAI,CAAA;AAChB,QAAA,CAAA,IAAK,CAAA;AAAA,MACP,CAAA,MAAA,IAAW,aAAa,GAAA,EAAK;AAC3B,QAAA,MAAA,CAAO,KAAK,IAAI,CAAA;AAChB,QAAA,CAAA,IAAK,CAAA;AAAA,MACP,CAAA,MAAA,IAAW,aAAa,GAAA,EAAK;AAC3B,QAAA,MAAA,CAAO,KAAK,GAAI,CAAA;AAChB,QAAA,CAAA,IAAK,CAAA;AAAA,MACP,CAAA,MAAO;AAEL,QAAA,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,CAAC,CAAC,CAAA;AACpB,QAAA,CAAA,IAAK,CAAA;AAAA,MACP;AAAA,IACF,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,CAAC,CAAC,CAAA;AACpB,MAAA,CAAA,IAAK,CAAA;AAAA,IACP;AAAA,EACF;AACA,EAAA,OAAO,MAAA,CAAO,KAAK,EAAE,CAAA;AACvB;AAKO,SAAS,gBAAgB,KAAA,EAA0B;AACxD,EAAA,IAAI,UAAU,IAAA,EAAM;AAClB,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,IAAI,OAAO,UAAU,SAAA,EAAW;AAC9B,IAAA,OAAO,QAAQ,MAAA,GAAS,OAAA;AAAA,EAC1B;AAEA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAO,OAAO,KAAK,CAAA;AAAA,EACrB;AAEA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,IAAI,YAAA,CAAa,KAAK,CAAA,EAAG;AACvB,MAAA,OAAO,CAAA,CAAA,EAAI,YAAA,CAAa,KAAK,CAAC,CAAA,CAAA,CAAA;AAAA,IAChC;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kCAAA,EAAqC,OAAO,KAAK,CAAA,CAAE,CAAA;AACrE;AAKO,SAAS,eAAe,KAAA,EAA0B;AACvD,EAAA,MAAM,OAAA,GAAU,MAAM,IAAA,EAAK;AAE3B,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,OAAO,EAAA;AAAA,EACT;AAGA,EAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI,YAAY,OAAA,EAAS;AACvB,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,IAAI,QAAQ,UAAA,CAAW,GAAG,KAAK,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AACpD,IAAA,OAAO,cAAA,CAAe,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA;AAAA,EAC5C;AAGA,EAAA,IAAI,eAAA,CAAgB,OAAO,CAAA,EAAG;AAC5B,IAAA,MAAM,GAAA,GAAM,OAAO,OAAO,CAAA;AAC1B,IAAA,IAAI,CAAC,KAAA,CAAM,GAAG,CAAA,EAAG;AACf,MAAA,OAAO,GAAA;AAAA,IACT;AAAA,EACF;AAGA,EAAA,OAAO,OAAA;AACT;AAOO,SAAS,qBAAqB,IAAA,EAAqC;AACxE,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,IAAK,IAAA,CAAK,WAAW,CAAA,EAAG;AAC7C,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,IAAI,CAAC,IAAA,CAAK,KAAA,CAAM,UAAQ,aAAA,CAAc,IAAI,CAAC,CAAA,EAAG;AAC5C,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,MAAM,SAAA,GAAY,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,CAAC,CAAC,CAAA;AAGrC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAQ,CAAA,EAAA,EAAK;AACpC,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,CAAC,CAAC,CAAA;AAChC,IAAA,IAAI,IAAA,CAAK,MAAA,KAAW,SAAA,CAAU,MAAA,EAAQ;AACpC,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAQ,CAAA,EAAA,EAAK;AACpC,MAAA,IAAI,IAAA,CAAK,CAAC,CAAA,KAAM,SAAA,CAAU,CAAC,CAAA,EAAG;AAC5B,QAAA,OAAO,KAAA;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,IAAA;AACT;AAKA,SAAS,cAAc,KAAA,EAAqC;AAC1D,EAAA,OACE,OAAO,KAAA,KAAU,QAAA,IACjB,KAAA,KAAU,QACV,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,KACpB,MAAA,CAAO,SAAA,CAAU,QAAA,CAAS,IAAA,CAAK,KAAK,CAAA,KAAM,iBAAA;AAE9C;AAUO,SAAS,gBAAA,CAAiB,MAAc,SAAA,EAA6B;AAC1E,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,MAAM,UAAoB,EAAC;AAC3B,EAAA,IAAI,QAAA,GAAW,KAAA;AACf,EAAA,IAAI,UAAA,GAAa,KAAA;AACjB,EAAA,IAAI,UAAA,GAAa,CAAA;AACjB,EAAA,IAAI,WAAA,GAAc,CAAA;AAClB,EAAA,IAAI,UAAA,GAAa,CAAA;AAEjB,EAAA,KAAA,MAAW,QAAQ,IAAA,EAAM;AAEvB,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AACjB,MAAA,UAAA,GAAa,KAAA;AACb,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,SAAS,IAAA,EAAM;AACjB,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AACjB,MAAA,UAAA,GAAa,IAAA;AACb,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,SAAS,GAAA,EAAK;AAChB,MAAA,QAAA,GAAW,CAAC,QAAA;AACZ,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AACjB,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AACjB,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,SAAS,GAAA,EAAK;AAChB,MAAA,UAAA,EAAA;AACA,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,IACnB,CAAA,MAAA,IAAW,SAAS,GAAA,EAAK;AACvB,MAAA,UAAA,EAAA;AACA,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,IACnB,CAAA,MAAA,IAAW,SAAS,GAAA,EAAK;AACvB,MAAA,WAAA,EAAA;AACA,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,IACnB,CAAA,MAAA,IAAW,SAAS,GAAA,EAAK;AACvB,MAAA,WAAA,EAAA;AACA,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,IACnB,CAAA,MAAA,IAAW,SAAS,GAAA,EAAK;AACvB,MAAA,UAAA,EAAA;AACA,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,IACnB,CAAA,MAAA,IAAW,SAAS,GAAA,EAAK;AACvB,MAAA,UAAA,EAAA;AACA,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,IACnB,CAAA,MAAA,IACE,SAAS,SAAA,IACT,UAAA,KAAe,KACf,WAAA,KAAgB,CAAA,IAChB,eAAe,CAAA,EACf;AAEA,MAAA,MAAA,CAAO,KAAK,OAAA,CAAQ,IAAA,CAAK,EAAE,CAAA,CAAE,MAAM,CAAA;AACnC,MAAA,OAAA,CAAQ,MAAA,GAAS,CAAA;AAAA,IACnB,CAAA,MAAO;AACL,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,IACnB;AAAA,EACF;AAGA,EAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,IAAA,MAAA,CAAO,KAAK,OAAA,CAAQ,IAAA,CAAK,EAAE,CAAA,CAAE,MAAM,CAAA;AAAA,EACrC;AAEA,EAAA,OAAO,MAAA;AACT;AAUO,SAAS,eAAe,SAAA,EAA8B;AAC3D,EAAA,MAAM,OAAA,GAAU,UAAU,IAAA,EAAK;AAI/B,EAAA,IAAI,QAAQ,UAAA,CAAW,GAAG,KAAK,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AACpD,IAAA,OAAO,EAAE,OAAA,EAAS,cAAA,CAAe,OAAA,CAAQ,KAAA,CAAM,GAAG,EAAE,CAAC,CAAA,EAAG,MAAA,EAAQ,IAAA,EAAK;AAAA,EACvE;AAGA,EAAA,IAAI,CAAC,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AAC1B,IAAA,OAAO,EAAE,OAAA,EAAS,OAAA,EAAS,MAAA,EAAQ,IAAA,EAAK;AAAA,EAC1C;AAGA,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,OAAA,CAAQ,GAAG,CAAA;AACpC,EAAA,IAAI,UAAU,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,QAAQ,EAAE,IAAA,EAAK;AAG9C,EAAA,IAAI,QAAQ,UAAA,CAAW,GAAG,KAAK,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AACpD,IAAA,OAAA,GAAU,cAAA,CAAe,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA;AAAA,EAC/C;AAGA,EAAA,IAAI,CAAC,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AAC1B,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,2BAAA,EAA8B,SAAS,CAAA,CAAE,CAAA;AAAA,EAC3D;AAEA,EAAA,IAAI,YAAY,OAAA,CAAQ,KAAA,CAAM,WAAW,CAAA,EAAG,EAAE,EAAE,IAAA,EAAK;AAGrD,EAAA,IAAI,SAAA,CAAU,UAAA,CAAW,GAAG,CAAA,EAAG;AAC7B,IAAA,SAAA,GAAY,SAAA,CAAU,MAAM,CAAC,CAAA;AAAA,EAC/B;AAGA,EAAA,MAAM,UAAA,GAAa,gBAAA,CAAiB,SAAA,EAAW,GAAG,CAAA;AAElD,EAAA,OAAO,EAAE,OAAA,EAAS,MAAA,EAAQ,UAAA,EAAW;AACvC;AASO,SAAS,eAAe,IAAA,EAA2B;AACxD,EAAA,MAAM,YAAuB,EAAC;AAE9B,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAO,GAAI,eAAe,GAAG,CAAA;AAC9C,IAAA,SAAA,CAAU,OAAO,CAAA,GAAI,MAAA;AAAA,EACvB;AAEA,EAAA,OAAO,SAAA;AACT;AAOO,SAAS,UAAU,OAAA,EAA6B;AAErD,EAAA,IAAI,OAAA,GAAU,EAAA;AACd,EAAA,IAAI,QAAA,GAAW,KAAA;AAGf,EAAA,KAAA,IAAS,IAAI,OAAA,CAAQ,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AAC5C,IAAA,MAAM,IAAA,GAAO,QAAQ,CAAC,CAAA;AAEtB,IAAA,IAAI,SAAS,GAAA,EAAK;AAEhB,MAAA,IAAI,cAAA,GAAiB,CAAA;AACrB,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AAC/B,QAAA,IAAI,OAAA,CAAQ,CAAC,CAAA,KAAM,IAAA,EAAM;AACvB,UAAA,cAAA,EAAA;AAAA,QACF,CAAA,MAAO;AACL,UAAA;AAAA,QACF;AAAA,MACF;AAGA,MAAA,IAAI,cAAA,GAAiB,MAAM,CAAA,EAAG;AAC5B,QAAA,QAAA,GAAW,CAAC,QAAA;AAAA,MACd;AAAA,IACF;AAEA,IAAA,IAAI,IAAA,KAAS,GAAA,IAAO,CAAC,QAAA,EAAU;AAC7B,MAAA,OAAA,GAAU,CAAA;AACV,MAAA;AAAA,IACF;AAAA,EACF;AAEA,EAAA,IAAI,YAAY,EAAA,EAAI;AAElB,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,OAAO,CAAA;AACzC,IAAA,MAAM,YAAY,OAAA,CAAQ,KAAA,CAAM,OAAA,GAAU,CAAC,EAAE,IAAA,EAAK;AAElD,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,SAAA,EAAW,EAAE,CAAA;AACpC,IAAA,IAAI,KAAA,CAAM,KAAK,CAAA,EAAG;AAKhB,MAAA,MAAMA,KAAAA,GAAO,gBAAA,CAAiB,OAAA,EAAS,GAAG,CAAA;AAC1C,MAAA,OAAO,EAAE,IAAA,EAAAA,KAAAA,EAAM,KAAA,EAAO,IAAA,EAAK;AAAA,IAC7B;AAEA,IAAA,MAAM,IAAA,GAAO,gBAAA,CAAiB,QAAA,EAAU,GAAG,CAAA;AAC3C,IAAA,OAAO,EAAE,MAAM,KAAA,EAAM;AAAA,EACvB,CAAA,MAAO;AACL,IAAA,MAAM,IAAA,GAAO,gBAAA,CAAiB,OAAA,EAAS,GAAG,CAAA;AAC1C,IAAA,OAAO,EAAE,IAAA,EAAM,KAAA,EAAO,IAAA,EAAK;AAAA,EAC7B;AACF;;;ACraO,SAAS,MAAM,IAAA,EAAyB;AAC7C,EAAA,OAAO,eAAe,IAAI,CAAA;AAC5B;AAQA,eAAsB,IAAA,CAAK,MAAiB,QAAA,EAAiC;AAE3E,EAAA,MAAM,EAAA,GAAK,MAAM,OAAO,aAAa,CAAA;AACrC,EAAA,MAAM,GAAG,SAAA,CAAU,QAAA,EAAU,KAAA,CAAM,IAAI,GAAG,OAAO,CAAA;AACnD;AAOO,SAAS,eAAe,KAAA,EAA0B;AAEvD,EAAA,IACE,KAAA,KAAU,IAAA,IACV,OAAO,KAAA,KAAU,SAAA,IACjB,OAAO,KAAA,KAAU,QAAA,IACjB,OAAO,KAAA,KAAU,QAAA,EACjB;AACA,IAAA,OAAO,gBAAgB,KAAK,CAAA;AAAA,EAC9B;AAGA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AAExB,IAAA,IAAI,oBAAA,CAAqB,KAAK,CAAA,EAAG;AAC/B,MAAA,OAAO,iBAAiB,KAAK,CAAA;AAAA,IAC/B,CAAA,MAAO;AACL,MAAA,OAAO,eAAe,KAAK,CAAA;AAAA,IAC7B;AAAA,EACF;AAGA,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA,EAAM;AAC/C,IAAA,OAAO,gBAAgB,KAAmB,CAAA;AAAA,EAC5C;AAEA,EAAA,MAAM,IAAI,SAAA,CAAU,CAAA,uBAAA,EAA0B,OAAO,KAAK,CAAA,CAAE,CAAA;AAC9D;AAOO,SAAS,gBAAgB,GAAA,EAAyB;AACvD,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA;AAE5B,EAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,MAAM,WAAqB,EAAC;AAC5B,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,IAAI,MAAA,GAAS,OAAO,GAAG,CAAA;AACvB,IAAA,IAAI,YAAA,CAAa,MAAM,CAAA,EAAG;AACxB,MAAA,MAAA,GAAS,CAAA,CAAA,EAAI,YAAA,CAAa,MAAM,CAAC,CAAA,CAAA,CAAA;AAAA,IACnC;AACA,IAAA,QAAA,CAAS,KAAK,MAAM,CAAA;AAAA,EACtB;AAGA,EAAA,MAAM,aAAuB,EAAC;AAC9B,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,UAAA,CAAW,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,GAAG,CAAC,CAAC,CAAA;AAAA,EAC1C;AAGA,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,IAAA,CAAK,GAAG,CAAA;AACjC,EAAA,MAAM,SAAA,GAAY,UAAA,CAAW,IAAA,CAAK,GAAG,CAAA;AAErC,EAAA,OAAO,CAAA,EAAA,EAAK,OAAO,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA,CAAA;AAClC;AAOO,SAAS,eAAe,GAAA,EAAwB;AACrD,EAAA,IAAI,GAAA,CAAI,WAAW,CAAA,EAAG;AACpB,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,MAAM,aAAuB,EAAC;AAC9B,EAAA,KAAA,MAAW,SAAS,GAAA,EAAK;AACvB,IAAA,UAAA,CAAW,IAAA,CAAK,cAAA,CAAe,KAAK,CAAC,CAAA;AAAA,EACvC;AAEA,EAAA,OAAO,GAAA,GAAM,UAAA,CAAW,IAAA,CAAK,GAAG,CAAA,GAAI,GAAA;AACtC;AAUO,SAAS,iBAAiB,GAAA,EAA2B;AAC1D,EAAA,IAAI,GAAA,CAAI,WAAW,CAAA,EAAG;AACpB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI,CAAC,oBAAA,CAAqB,GAAG,CAAA,EAAG;AAC9B,IAAA,MAAM,IAAI,MAAM,kDAAkD,CAAA;AAAA,EACpE;AAGA,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,GAAA,CAAI,CAAC,CAAC,CAAA;AAC/B,EAAA,MAAM,QAAQ,GAAA,CAAI,MAAA;AAGlB,EAAA,MAAM,aAAA,GAAgB,mBAAA,CAAoB,GAAA,EAAK,IAAI,CAAA;AAGnD,EAAA,MAAM,WAAqB,EAAC;AAC5B,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,IAAI,MAAA,GAAS,OAAO,GAAG,CAAA;AACvB,IAAA,IAAI,YAAA,CAAa,MAAM,CAAA,EAAG;AACxB,MAAA,MAAA,GAAS,CAAA,CAAA,EAAI,YAAA,CAAa,MAAM,CAAC,CAAA,CAAA,CAAA;AAAA,IACnC;AAGA,IAAA,IAAI,OAAO,aAAA,EAAe;AACxB,MAAA,MAAM,UAAA,GAAa,cAAc,GAAG,CAAA;AAEpC,MAAA,MAAM,mBAAA,GAAsB,UAAA,CAAW,GAAA,CAAI,CAAA,EAAA,KAAM;AAC/C,QAAA,IAAI,YAAA,CAAa,EAAE,CAAA,EAAG;AACpB,UAAA,OAAO,CAAA,CAAA,EAAI,YAAA,CAAa,EAAE,CAAC,CAAA,CAAA,CAAA;AAAA,QAC7B;AACA,QAAA,OAAO,EAAA;AAAA,MACT,CAAC,CAAA;AACD,MAAA,MAAM,SAAA,GAAY,mBAAA,CAAoB,IAAA,CAAK,GAAG,CAAA;AAC9C,MAAA,MAAA,GAAS,CAAA,EAAG,MAAM,CAAA,EAAA,EAAK,SAAS,CAAA,CAAA,CAAA;AAAA,IAClC;AAEA,IAAA,QAAA,CAAS,KAAK,MAAM,CAAA;AAAA,EACtB;AAEA,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,IAAA,CAAK,GAAG,CAAA;AAGjC,EAAA,MAAM,WAAqB,EAAC;AAC5B,EAAA,KAAA,MAAW,OAAO,GAAA,EAAK;AACrB,IAAA,MAAM,aAAuB,EAAC;AAC9B,IAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,MAAA,MAAM,KAAA,GAAQ,IAAI,GAAG,CAAA;AAGrB,MAAA,IAAI,OAAO,aAAA,EAAe;AACxB,QAAA,UAAA,CAAW,KAAK,0BAAA,CAA2B,KAAA,EAAqB,aAAA,CAAc,GAAG,CAAE,CAAC,CAAA;AAAA,MACtF,CAAA,MAAO;AACL,QAAA,UAAA,CAAW,IAAA,CAAK,cAAA,CAAe,KAAK,CAAC,CAAA;AAAA,MACvC;AAAA,IACF;AACA,IAAA,QAAA,CAAS,IAAA,CAAK,UAAA,CAAW,IAAA,CAAK,GAAG,CAAC,CAAA;AAAA,EACpC;AAEA,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,IAAA,CAAK,GAAG,CAAA;AAEjC,EAAA,OAAO,CAAA,EAAA,EAAK,OAAO,CAAA,CAAA,EAAI,KAAK,IAAI,OAAO,CAAA,CAAA,CAAA;AACzC;AAQO,SAAS,mBAAA,CAAoB,KAAmB,IAAA,EAA2B;AAChF,EAAA,MAAM,gBAA2B,EAAC;AAElC,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AAEtB,IAAA,MAAM,SAAS,GAAA,CAAI,GAAA,CAAI,CAAA,GAAA,KAAO,GAAA,CAAI,GAAG,CAAC,CAAA;AAGtC,IAAA,IAAI,CAAC,MAAA,CAAO,KAAA,CAAM,CAAA,CAAA,KAAK,OAAO,CAAA,KAAM,QAAA,IAAY,CAAA,KAAM,IAAA,IAAQ,CAAC,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAC,CAAA,EAAG;AAChF,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,SAAA,GAAY,MAAA,CAAO,IAAA,CAAK,MAAA,CAAO,CAAC,CAAe,CAAA;AACrD,IAAA,MAAM,UAAU,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA,CAAE,MAAM,CAAA,CAAA,KAAK;AACzC,MAAA,MAAM,OAAA,GAAU,MAAA,CAAO,IAAA,CAAK,CAAe,CAAA;AAC3C,MAAA,OACE,OAAA,CAAQ,MAAA,KAAW,SAAA,CAAU,MAAA,IAC7B,OAAA,CAAQ,KAAA,CAAM,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,KAAM,SAAA,CAAU,CAAC,CAAC,CAAA;AAAA,IAE9C,CAAC,CAAA;AAED,IAAA,IAAI,OAAA,EAAS;AAEX,MAAA,aAAA,CAAc,GAAG,CAAA,GAAI,SAAA;AAAA,IACvB;AAAA,EACF;AAEA,EAAA,OAAO,aAAA;AACT;AAUO,SAAS,0BAAA,CAA2B,KAAiB,MAAA,EAA0B;AACpF,EAAA,IAAI,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,CAAE,WAAW,CAAA,EAAG;AACjC,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,MAAM,aAAuB,EAAC;AAC9B,EAAA,KAAA,MAAW,OAAO,MAAA,EAAQ;AACxB,IAAA,MAAM,KAAA,GAAQ,IAAI,GAAG,CAAA;AACrB,IAAA,UAAA,CAAW,IAAA,CAAK,cAAA,CAAe,KAAK,CAAC,CAAA;AAAA,EACvC;AAEA,EAAA,OAAO,GAAA,GAAM,UAAA,CAAW,IAAA,CAAK,GAAG,CAAA,GAAI,GAAA;AACtC;;;AC9OO,SAAS,MAAM,CAAA,EAAsB;AAC1C,EAAA,MAAM,OAAA,GAAU,EAAE,IAAA,EAAK;AACvB,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO,WAAW,OAAO,CAAA;AAC3B;AAQA,eAAsB,KAAK,QAAA,EAAsC;AAE/D,EAAA,MAAM,EAAA,GAAK,MAAM,OAAO,aAAa,CAAA;AACrC,EAAA,MAAM,OAAA,GAAU,MAAM,EAAA,CAAG,QAAA,CAAS,UAAU,OAAO,CAAA;AACnD,EAAA,OAAO,MAAM,OAAO,CAAA;AACtB;AAQO,SAAS,WAAW,IAAA,EAAyB;AAClD,EAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAE1B,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,OAAO,EAAA;AAAA,EACT;AAGA,EAAA,MAAM,SAAA,GAAY,QAAQ,CAAC,CAAA;AAE3B,EAAA,IAAI,cAAc,GAAA,EAAK;AAErB,IAAA,OAAO,YAAY,OAAO,CAAA;AAAA,EAC5B,CAAA,MAAA,IAAW,cAAc,GAAA,EAAK;AAE5B,IAAA,OAAO,WAAW,OAAO,CAAA;AAAA,EAC3B,CAAA,MAAO;AAEL,IAAA,OAAO,eAAe,OAAO,CAAA;AAAA,EAC/B;AACF;AASO,SAAS,YAAY,IAAA,EAAyB;AACnD,EAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAE1B,EAAA,IAAI,CAAC,QAAQ,UAAA,CAAW,GAAG,KAAK,CAAC,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AACtD,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,uBAAA,EAA0B,IAAI,CAAA,CAAE,CAAA;AAAA,EAClD;AAGA,EAAA,MAAM,UAAU,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,EAAE,EAAE,IAAA,EAAK;AAG1C,EAAA,IAAI,OAAA,KAAY,GAAA,IAAO,OAAA,KAAY,EAAA,EAAI;AACrC,IAAA,OAAO,EAAC;AAAA,EACV;AAGA,EAAA,IAAI,OAAA,CAAQ,UAAA,CAAW,GAAG,CAAA,EAAG;AAC3B,IAAA,OAAO,gBAAA,CAAiB,OAAA,CAAQ,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,EAC1C,CAAA,MAAO;AAIL,IAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,OAAA,EAAS,GAAG,CAAA;AAC5C,IAAA,MAAM,eAAe,MAAA,CAAO,GAAA,CAAI,CAAA,CAAA,KAAK,UAAA,CAAW,CAAC,CAAC,CAAA;AAIlD,IAAA,OAAO,YAAA;AAAA,EACT;AACF;AAOO,SAAS,iBAAiB,OAAA,EAA4B;AAE3D,EAAA,MAAM,KAAA,GAAQ,gBAAA,CAAiB,OAAA,EAAS,GAAG,CAAA;AAE3C,EAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG;AACpB,IAAA,MAAM,IAAI,MAAM,qCAAqC,CAAA;AAAA,EACvD;AAGA,EAAA,MAAM,QAAA,GAAW,MAAM,CAAC,CAAA;AAGxB,EAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAM,GAAI,UAAU,QAAQ,CAAA;AAG1C,EAAA,MAAM,SAAA,GAAY,eAAe,IAAI,CAAA;AAGrC,EAAA,MAAM,aAAa,IAAA,CAAK,GAAA,CAAI,OAAK,cAAA,CAAe,CAAC,EAAE,OAAO,CAAA;AAG1D,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,MAAM,IAAI,MAAM,uCAAuC,CAAA;AAAA,EACzD;AAIA,EAAA,MAAM,UAAA,GAAa,KAAA,CAAM,KAAA,CAAM,CAAC,CAAA;AAIhC,EAAA,MAAM,SAAA,GAAY,KAAA,KAAU,IAAA,IAAQ,UAAA,CAAW,MAAA,GAAS,CAAA;AAExD,EAAA,IAAI,SAAA,EAAW;AAEb,IAAA,OAAO,iBAAA,CAAkB,UAAA,EAAY,UAAA,EAAY,SAAA,EAAW,KAAK,CAAA;AAAA,EACnE,CAAA,MAAO;AAEL,IAAA,OAAO,iBAAA,CAAkB,UAAA,EAAY,UAAA,CAAW,CAAC,GAAG,SAAS,CAAA;AAAA,EAC/D;AACF;AAKO,SAAS,iBAAA,CACd,UAAA,EACA,SAAA,EACA,SAAA,EACY;AAEZ,EAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,SAAA,EAAW,GAAG,CAAA;AAE9C,EAAA,IAAI,MAAA,CAAO,MAAA,KAAW,UAAA,CAAW,MAAA,EAAQ;AACvC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,sBAAA,EAAyB,UAAA,CAAW,MAAM,CAAA,YAAA,EAAe,OAAO,MAAM,CAAA,OAAA;AAAA,KACxE;AAAA,EACF;AAGA,EAAA,MAAM,MAAkB,EAAC;AACzB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,UAAA,CAAW,QAAQ,CAAA,EAAA,EAAK;AAC1C,IAAA,MAAM,SAAA,GAAY,WAAW,CAAC,CAAA;AAC9B,IAAA,MAAM,QAAA,GAAW,OAAO,CAAC,CAAA;AAGzB,IAAA,MAAM,MAAA,GAAS,UAAU,SAAS,CAAA;AAElC,IAAA,IAAI,MAAA,EAAQ;AAEV,MAAA,GAAA,CAAI,SAAS,CAAA,GAAI,qBAAA,CAAsB,QAAA,EAAU,MAAM,CAAA;AAAA,IACzD,CAAA,MAAO;AAEL,MAAA,GAAA,CAAI,SAAS,CAAA,GAAI,UAAA,CAAW,QAAQ,CAAA;AAAA,IACtC;AAAA,EACF;AAEA,EAAA,OAAO,GAAA;AACT;AAKO,SAAS,iBAAA,CACd,UAAA,EACA,QAAA,EACA,SAAA,EACA,aAAA,EACc;AACd,EAAA,MAAM,SAAuB,EAAC;AAE9B,EAAA,KAAA,MAAW,UAAU,QAAA,EAAU;AAC7B,IAAA,IAAI,MAAA,CAAO,IAAA,EAAK,CAAE,MAAA,KAAW,CAAA,EAAG;AAC9B,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,GAAA,GAAM,iBAAA,CAAkB,UAAA,EAAY,MAAA,EAAQ,SAAS,CAAA;AAC3D,IAAA,MAAA,CAAO,KAAK,GAAG,CAAA;AAAA,EACjB;AAGA,EAAA,IAAI,aAAA,KAAkB,IAAA,IAAQ,MAAA,CAAO,MAAA,KAAW,aAAA,EAAe;AAC7D,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,6BAAA,EAAgC,aAAa,CAAA,cAAA,EAAiB,MAAA,CAAO,MAAM,CAAA;AAAA,KAC7E;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAQO,SAAS,qBAAA,CAAsB,UAAkB,MAAA,EAA8B;AACpF,EAAA,MAAM,OAAA,GAAU,SAAS,IAAA,EAAK;AAG9B,EAAA,IAAI,CAAC,QAAQ,UAAA,CAAW,GAAG,KAAK,CAAC,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AACtD,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,6CAAA,EAAgD,QAAQ,CAAA,CAAE,CAAA;AAAA,EAC5E;AAGA,EAAA,MAAM,UAAU,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,EAAE,EAAE,IAAA,EAAK;AAG1C,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,OAAO,EAAC;AAAA,EACV;AAGA,EAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,OAAA,EAAS,GAAG,CAAA;AAE5C,EAAA,IAAI,MAAA,CAAO,MAAA,KAAW,MAAA,CAAO,MAAA,EAAQ;AACnC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,iBAAA,EAAoB,MAAA,CAAO,MAAM,CAAA,UAAA,EAAa,OAAO,MAAM,CAAA,OAAA;AAAA,KAC7D;AAAA,EACF;AAGA,EAAA,MAAM,eAAA,GAAkB,eAAe,MAAM,CAAA;AAG7C,EAAA,MAAM,aAAa,MAAA,CAAO,GAAA,CAAI,OAAK,cAAA,CAAe,CAAC,EAAE,OAAO,CAAA;AAG5D,EAAA,MAAM,MAAkB,EAAC;AACzB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,UAAA,CAAW,QAAQ,CAAA,EAAA,EAAK;AAC1C,IAAA,MAAM,SAAA,GAAY,WAAW,CAAC,CAAA;AAC9B,IAAA,MAAMC,SAAAA,GAAW,OAAO,CAAC,CAAA;AAGzB,IAAA,MAAM,YAAA,GAAe,gBAAgB,SAAS,CAAA;AAE9C,IAAA,IAAI,YAAA,EAAc;AAEhB,MAAA,GAAA,CAAI,SAAS,CAAA,GAAI,qBAAA,CAAsBA,SAAAA,EAAU,YAAY,CAAA;AAAA,IAC/D,CAAA,MAAO;AAEL,MAAA,GAAA,CAAI,SAAS,CAAA,GAAI,UAAA,CAAWA,SAAQ,CAAA;AAAA,IACtC;AAAA,EACF;AAEA,EAAA,OAAO,GAAA;AACT;AAOO,SAAS,WAAW,IAAA,EAAyB;AAClD,EAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAE1B,EAAA,IAAI,CAAC,QAAQ,UAAA,CAAW,GAAG,KAAK,CAAC,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AACtD,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,sBAAA,EAAyB,IAAI,CAAA,CAAE,CAAA;AAAA,EACjD;AAGA,EAAA,MAAM,UAAU,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,EAAE,EAAE,IAAA,EAAK;AAG1C,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,OAAO,EAAC;AAAA,EACV;AAGA,EAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,OAAA,EAAS,GAAG,CAAA;AAG5C,EAAA,MAAM,SAAoB,EAAC;AAC3B,EAAA,KAAA,MAAW,YAAY,MAAA,EAAQ;AAC7B,IAAA,IAAI,QAAA,CAAS,IAAA,EAAK,CAAE,MAAA,GAAS,CAAA,EAAG;AAE9B,MAAA,MAAA,CAAO,IAAA,CAAK,UAAA,CAAW,QAAQ,CAAC,CAAA;AAAA,IAClC;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT","file":"index.cjs","sourcesContent":["/**\n * TSON Utility Functions\n *\n * Helper functions for serialization, deserialization, and validation.\n */\n\nimport type { TSONValue, TSONObject, SchemaMap, KeySchema, ParsedKeys } from './types';\n\n/**\n * Special characters that require string quoting\n */\nexport const SPECIAL_CHARS = new Set([',', '|', '@', '#', '{', '}', '[', ']', '\\n', '\\r', '\\t', ' ', '\"', '(', ')']);\n\n/**\n * Determine if a string value needs to be quoted in TSON format.\n *\n * Strings need quoting if they:\n * - Are empty\n * - Contain special delimiter characters\n * - Have leading/trailing whitespace\n * - Look like numbers (to preserve them as strings)\n * - Look like reserved words (true/false/null) when we want them as strings\n */\nexport function needsQuoting(value: string): boolean {\n if (value.length === 0) {\n return true;\n }\n\n // Check for reserved words that we want to keep as strings\n if (value === 'true' || value === 'false' || value === 'null') {\n return true;\n }\n\n // Check for leading/trailing whitespace\n if (value[0].trim() === '' || value[value.length - 1].trim() === '') {\n return true;\n }\n\n // Check if it looks like a number (preserve type distinction)\n if (looksLikeNumber(value)) {\n return true;\n }\n\n // Check for special characters\n for (const char of value) {\n if (SPECIAL_CHARS.has(char)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if a string looks like a numeric value.\n *\n * Used to determine if we should quote a string to preserve it as a string\n * rather than having it parsed as a number.\n */\nexport function looksLikeNumber(value: string): boolean {\n if (value.length === 0) {\n return false;\n }\n\n // Try parsing as number\n const num = Number(value);\n return !isNaN(num) && value.trim() === value && isFinite(num);\n}\n\n/**\n * Escape special characters in a string for quoted representation.\n *\n * Uses standard JSON escape sequences.\n */\nexport function escapeString(value: string): string {\n // Order matters: backslash first to avoid double-escaping\n return value\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\n/g, '\\\\n')\n .replace(/\\r/g, '\\\\r')\n .replace(/\\t/g, '\\\\t');\n}\n\n/**\n * Unescape a quoted string back to its original form.\n *\n * Reverses the escaping done by escapeString().\n * Must process character by character to handle sequences like \\\\n correctly.\n */\nexport function unescapeString(value: string): string {\n const result: string[] = [];\n let i = 0;\n while (i < value.length) {\n if (value[i] === '\\\\' && i + 1 < value.length) {\n const nextChar = value[i + 1];\n if (nextChar === '\\\\') {\n result.push('\\\\');\n i += 2;\n } else if (nextChar === '\"') {\n result.push('\"');\n i += 2;\n } else if (nextChar === 'n') {\n result.push('\\n');\n i += 2;\n } else if (nextChar === 'r') {\n result.push('\\r');\n i += 2;\n } else if (nextChar === 't') {\n result.push('\\t');\n i += 2;\n } else {\n // Unknown escape, keep as-is\n result.push(value[i]);\n i += 1;\n }\n } else {\n result.push(value[i]);\n i += 1;\n }\n }\n return result.join('');\n}\n\n/**\n * Format a primitive value as TSON string.\n */\nexport function formatPrimitive(value: TSONValue): string {\n if (value === null) {\n return 'null';\n }\n\n if (typeof value === 'boolean') {\n return value ? 'true' : 'false';\n }\n\n if (typeof value === 'number') {\n return String(value);\n }\n\n if (typeof value === 'string') {\n if (needsQuoting(value)) {\n return `\"${escapeString(value)}\"`;\n }\n return value;\n }\n\n throw new Error(`Cannot format non-primitive type: ${typeof value}`);\n}\n\n/**\n * Parse a TSON primitive value string to JavaScript type.\n */\nexport function parsePrimitive(value: string): TSONValue {\n const trimmed = value.trim();\n\n if (trimmed.length === 0) {\n return '';\n }\n\n // Check for boolean\n if (trimmed === 'true') {\n return true;\n }\n if (trimmed === 'false') {\n return false;\n }\n\n // Check for null\n if (trimmed === 'null') {\n return null;\n }\n\n // Check for quoted string\n if (trimmed.startsWith('\"') && trimmed.endsWith('\"')) {\n return unescapeString(trimmed.slice(1, -1));\n }\n\n // Try to parse as number\n if (looksLikeNumber(trimmed)) {\n const num = Number(trimmed);\n if (!isNaN(num)) {\n return num;\n }\n }\n\n // Otherwise it's an unquoted string\n return trimmed;\n}\n\n/**\n * Check if a value is an array of objects with identical keys.\n *\n * This determines if we can use tabular format optimization.\n */\nexport function isUniformObjectArray(data: unknown): data is TSONObject[] {\n if (!Array.isArray(data) || data.length === 0) {\n return false;\n }\n\n // All elements must be plain objects\n if (!data.every(item => isPlainObject(item))) {\n return false;\n }\n\n // Get keys from first element\n const firstKeys = Object.keys(data[0]);\n\n // Check that all elements have the same keys in the same order\n for (let i = 1; i < data.length; i++) {\n const keys = Object.keys(data[i]);\n if (keys.length !== firstKeys.length) {\n return false;\n }\n for (let j = 0; j < keys.length; j++) {\n if (keys[j] !== firstKeys[j]) {\n return false;\n }\n }\n }\n\n return true;\n}\n\n/**\n * Check if value is a plain object (not array, null, or other special object)\n */\nfunction isPlainObject(value: unknown): value is TSONObject {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.prototype.toString.call(value) === '[object Object]'\n );\n}\n\n/**\n * Split text by delimiter, respecting quoted strings and nested structures.\n *\n * This is more sophisticated than string.split() because it handles:\n * - Quoted strings (don't split on delimiters inside quotes)\n * - Nested braces/brackets/parentheses (don't split inside nested structures)\n * - Escaped characters\n */\nexport function splitByDelimiter(text: string, delimiter: string): string[] {\n const result: string[] = [];\n const current: string[] = [];\n let inQuotes = false;\n let escapeNext = false;\n let depthCurly = 0;\n let depthSquare = 0;\n let depthParen = 0;\n\n for (const char of text) {\n // Handle escape sequences\n if (escapeNext) {\n current.push(char);\n escapeNext = false;\n continue;\n }\n\n if (char === '\\\\') {\n current.push(char);\n escapeNext = true;\n continue;\n }\n\n // Handle quotes\n if (char === '\"') {\n inQuotes = !inQuotes;\n current.push(char);\n continue;\n }\n\n // Inside quotes, add everything\n if (inQuotes) {\n current.push(char);\n continue;\n }\n\n // Track nesting depth\n if (char === '{') {\n depthCurly++;\n current.push(char);\n } else if (char === '}') {\n depthCurly--;\n current.push(char);\n } else if (char === '[') {\n depthSquare++;\n current.push(char);\n } else if (char === ']') {\n depthSquare--;\n current.push(char);\n } else if (char === '(') {\n depthParen++;\n current.push(char);\n } else if (char === ')') {\n depthParen--;\n current.push(char);\n } else if (\n char === delimiter &&\n depthCurly === 0 &&\n depthSquare === 0 &&\n depthParen === 0\n ) {\n // Found unquoted, unnested delimiter - split here\n result.push(current.join('').trim());\n current.length = 0;\n } else {\n current.push(char);\n }\n }\n\n // Add final segment\n if (current.length > 0) {\n result.push(current.join('').trim());\n }\n\n return result;\n}\n\n/**\n * Parse a key which may include nested schema notation.\n *\n * Examples:\n * \"name\" -> { keyName: \"name\", schema: null }\n * \"address(@city,zip)\" -> { keyName: \"address\", schema: [\"city\", \"zip\"] }\n * \"location(@coords(@lat,lng))\" -> { keyName: \"location\", schema: [\"coords(@lat,lng)\"] }\n */\nexport function parseKeySchema(keyString: string): KeySchema {\n const trimmed = keyString.trim();\n\n // If the entire key is quoted, it's a simple key (any parens inside are literal)\n // Must check this BEFORE looking for '(' to handle keys like \"company(\"\n if (trimmed.startsWith('\"') && trimmed.endsWith('\"')) {\n return { keyName: unescapeString(trimmed.slice(1, -1)), schema: null };\n }\n\n // Check if key has nested schema (only for unquoted keys)\n if (!trimmed.includes('(')) {\n return { keyName: trimmed, schema: null };\n }\n\n // Find the opening parenthesis\n const parenIdx = trimmed.indexOf('(');\n let keyName = trimmed.slice(0, parenIdx).trim();\n\n // Unquote the key name if it's quoted\n if (keyName.startsWith('\"') && keyName.endsWith('\"')) {\n keyName = unescapeString(keyName.slice(1, -1));\n }\n\n // Extract schema (everything between outermost parentheses)\n if (!trimmed.endsWith(')')) {\n throw new Error(`Invalid key schema syntax: ${keyString}`);\n }\n\n let schemaStr = trimmed.slice(parenIdx + 1, -1).trim();\n\n // Strip leading @ if present (part of notation, not key name)\n if (schemaStr.startsWith('@')) {\n schemaStr = schemaStr.slice(1);\n }\n\n // Split schema by commas (respecting nested parentheses)\n const schemaKeys = splitByDelimiter(schemaStr, ',');\n\n return { keyName, schema: schemaKeys };\n}\n\n/**\n * Build a mapping of field names to their nested schemas.\n *\n * Example:\n * [\"id\", \"address(@city,zip)\"]\n * -> { id: null, address: [\"city\", \"zip\"] }\n */\nexport function buildSchemaMap(keys: string[]): SchemaMap {\n const schemaMap: SchemaMap = {};\n\n for (const key of keys) {\n const { keyName, schema } = parseKeySchema(key);\n schemaMap[keyName] = schema;\n }\n\n return schemaMap;\n}\n\n/**\n * Parse keys string and extract row count if present.\n *\n * Format: key1,key2,key3 or key1,key2,key3#N\n */\nexport function parseKeys(keysStr: string): ParsedKeys {\n // Check for row count marker, respecting quotes\n let hashIdx = -1;\n let inQuotes = false;\n\n // Scan backwards to find the last # that is NOT inside quotes\n for (let i = keysStr.length - 1; i >= 0; i--) {\n const char = keysStr[i];\n\n if (char === '\"') {\n // Check for escaped quote (count preceding backslashes)\n let backslashCount = 0;\n for (let j = i - 1; j >= 0; j--) {\n if (keysStr[j] === '\\\\') {\n backslashCount++;\n } else {\n break;\n }\n }\n\n // If even number of backslashes, it's a real quote\n if (backslashCount % 2 === 0) {\n inQuotes = !inQuotes;\n }\n }\n\n if (char === '#' && !inQuotes) {\n hashIdx = i;\n break;\n }\n }\n\n if (hashIdx !== -1) {\n // Found separator\n const keysPart = keysStr.slice(0, hashIdx);\n const countPart = keysStr.slice(hashIdx + 1).trim();\n\n const count = parseInt(countPart, 10);\n if (isNaN(count)) {\n // If it's not a valid number, ignore the hash (treat as part of key)\n // This handles edge cases where # might appear unquoted but not as separator\n // though strictly that should be quoted according to spec.\n // Fallback to normal parsing\n const keys = splitByDelimiter(keysStr, ',');\n return { keys, count: null };\n }\n\n const keys = splitByDelimiter(keysPart, ',');\n return { keys, count };\n } else {\n const keys = splitByDelimiter(keysStr, ',');\n return { keys, count: null };\n }\n}\n","/**\n * TSON Serializer\n *\n * Converts JavaScript data structures to TSON format.\n */\n\nimport type { TSONValue, TSONObject, TSONArray, SchemaMap } from './types';\nimport {\n formatPrimitive,\n needsQuoting,\n escapeString,\n isUniformObjectArray,\n} from './utils';\n\n/**\n * Serialize JavaScript object to TSON formatted string.\n *\n * @example\n * dumps({ name: \"Alice\", age: 30 })\n * // Returns: '{@name,age|Alice,30}'\n *\n * @example\n * dumps([{ id: 1, name: \"Alice\" }, { id: 2, name: \"Bob\" }])\n * // Returns: '{@id,name#2|1,Alice|2,Bob}'\n */\nexport function dumps(data: TSONValue): string {\n return serializeValue(data);\n}\n\n/**\n * Serialize JavaScript object to TSON formatted file (Node.js only).\n *\n * @param data - JavaScript object to serialize\n * @param filePath - Path to file to write\n */\nexport async function dump(data: TSONValue, filePath: string): Promise<void> {\n // Dynamic import for Node.js fs module\n const fs = await import('fs/promises');\n await fs.writeFile(filePath, dumps(data), 'utf-8');\n}\n\n/**\n * Serialize any JavaScript value to TSON format.\n *\n * Dispatches to appropriate serializer based on type.\n */\nexport function serializeValue(value: TSONValue): string {\n // Handle primitives\n if (\n value === null ||\n typeof value === 'boolean' ||\n typeof value === 'number' ||\n typeof value === 'string'\n ) {\n return formatPrimitive(value);\n }\n\n // Handle arrays\n if (Array.isArray(value)) {\n // Check if it's a uniform array of objects (tabular optimization)\n if (isUniformObjectArray(value)) {\n return serializeTabular(value);\n } else {\n return serializeArray(value);\n }\n }\n\n // Handle objects\n if (typeof value === 'object' && value !== null) {\n return serializeObject(value as TSONObject);\n }\n\n throw new TypeError(`Cannot serialize type: ${typeof value}`);\n}\n\n/**\n * Serialize a JavaScript object to TSON object format.\n *\n * Format: {@key1,key2|value1,value2}\n */\nexport function serializeObject(obj: TSONObject): string {\n const keys = Object.keys(obj);\n\n if (keys.length === 0) {\n return '{@}';\n }\n\n // Format keys\n const keyParts: string[] = [];\n for (const key of keys) {\n let keyStr = String(key);\n if (needsQuoting(keyStr)) {\n keyStr = `\"${escapeString(keyStr)}\"`;\n }\n keyParts.push(keyStr);\n }\n\n // Format values\n const valueParts: string[] = [];\n for (const key of keys) {\n valueParts.push(serializeValue(obj[key]));\n }\n\n // Build object string\n const keysStr = keyParts.join(',');\n const valuesStr = valueParts.join(',');\n\n return `{@${keysStr}|${valuesStr}}`;\n}\n\n/**\n * Serialize a JavaScript array to TSON array format.\n *\n * Format: [value1,value2,value3]\n */\nexport function serializeArray(arr: TSONArray): string {\n if (arr.length === 0) {\n return '[]';\n }\n\n // Serialize each element\n const valueParts: string[] = [];\n for (const value of arr) {\n valueParts.push(serializeValue(value));\n }\n\n return '[' + valueParts.join(',') + ']';\n}\n\n/**\n * Serialize a uniform array of objects in tabular format.\n *\n * Format: {@key1,key2#N|val1,val2|val1,val2}\n *\n * This is the key optimization: keys are declared once instead of repeated\n * for each object in the array.\n */\nexport function serializeTabular(arr: TSONObject[]): string {\n if (arr.length === 0) {\n return '[]';\n }\n\n if (!isUniformObjectArray(arr)) {\n throw new Error('Array is not uniform - cannot use tabular format');\n }\n\n // Get keys from first object\n const keys = Object.keys(arr[0]);\n const count = arr.length;\n\n // Check if any values are objects with uniform structure (nested schema opportunity)\n const nestedSchemas = detectNestedSchemas(arr, keys);\n\n // Format keys (with nested schemas if applicable)\n const keyParts: string[] = [];\n for (const key of keys) {\n let keyStr = String(key);\n if (needsQuoting(keyStr)) {\n keyStr = `\"${escapeString(keyStr)}\"`;\n }\n\n // Add nested schema notation if applicable\n if (key in nestedSchemas) {\n const schemaKeys = nestedSchemas[key]!;\n // Quote schema keys that need quoting (contain special chars)\n const formattedSchemaKeys = schemaKeys.map(sk => {\n if (needsQuoting(sk)) {\n return `\"${escapeString(sk)}\"`;\n }\n return sk;\n });\n const schemaStr = formattedSchemaKeys.join(',');\n keyStr = `${keyStr}(@${schemaStr})`;\n }\n\n keyParts.push(keyStr);\n }\n\n const keysStr = keyParts.join(',');\n\n // Format rows\n const rowParts: string[] = [];\n for (const obj of arr) {\n const valueParts: string[] = [];\n for (const key of keys) {\n const value = obj[key];\n\n // If this key has a nested schema, serialize as schematized object\n if (key in nestedSchemas) {\n valueParts.push(serializeSchematizedObject(value as TSONObject, nestedSchemas[key]!));\n } else {\n valueParts.push(serializeValue(value));\n }\n }\n rowParts.push(valueParts.join(','));\n }\n\n const rowsStr = rowParts.join('|');\n\n return `{@${keysStr}#${count}|${rowsStr}}`;\n}\n\n/**\n * Detect if any fields contain uniform nested objects that can use schema notation.\n *\n * For each key, checks if all values are objects with identical keys.\n * If so, that field can use nested schema notation.\n */\nexport function detectNestedSchemas(arr: TSONObject[], keys: string[]): SchemaMap {\n const nestedSchemas: SchemaMap = {};\n\n for (const key of keys) {\n // Get all values for this key\n const values = arr.map(obj => obj[key]);\n\n // Check if all values are plain objects\n if (!values.every(v => typeof v === 'object' && v !== null && !Array.isArray(v))) {\n continue;\n }\n\n if (values.length === 0) {\n continue;\n }\n\n // Check if all objects have the same keys\n const firstKeys = Object.keys(values[0] as TSONObject);\n const allSame = values.slice(1).every(v => {\n const objKeys = Object.keys(v as TSONObject);\n return (\n objKeys.length === firstKeys.length &&\n objKeys.every((k, i) => k === firstKeys[i])\n );\n });\n\n if (allSame) {\n // This field can use nested schema\n nestedSchemas[key] = firstKeys;\n }\n }\n\n return nestedSchemas;\n}\n\n/**\n * Serialize an object using a pre-declared schema.\n *\n * Format: {value1,value2} (no @ marker, values only)\n *\n * The @ marker is omitted because the schema was already declared in the\n * parent structure.\n */\nexport function serializeSchematizedObject(obj: TSONObject, schema: string[]): string {\n if (Object.keys(obj).length === 0) {\n return '{}';\n }\n\n // Serialize values in schema order\n const valueParts: string[] = [];\n for (const key of schema) {\n const value = obj[key];\n valueParts.push(serializeValue(value));\n }\n\n return '{' + valueParts.join(',') + '}';\n}\n","/**\n * TSON Deserializer\n *\n * Parses TSON format back to JavaScript data structures.\n */\n\nimport type { TSONValue, TSONObject, TSONArray, SchemaMap } from './types';\nimport {\n parsePrimitive,\n splitByDelimiter,\n buildSchemaMap,\n parseKeys,\n parseKeySchema,\n} from './utils';\n\n/**\n * Deserialize TSON formatted string to JavaScript object.\n *\n * @example\n * loads('{@name,age|Alice,30}')\n * // Returns: { name: 'Alice', age: 30 }\n *\n * @example\n * loads('{@id,name#2|1,Alice|2,Bob}')\n * // Returns: [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]\n */\nexport function loads(s: string): TSONValue {\n const trimmed = s.trim();\n if (trimmed.length === 0) {\n return null;\n }\n\n return parseValue(trimmed);\n}\n\n/**\n * Deserialize TSON formatted file to JavaScript object (Node.js only).\n *\n * @param filePath - Path to file to read\n * @returns Parsed JavaScript object\n */\nexport async function load(filePath: string): Promise<TSONValue> {\n // Dynamic import for Node.js fs module\n const fs = await import('fs/promises');\n const content = await fs.readFile(filePath, 'utf-8');\n return loads(content);\n}\n\n/**\n * Parse a TSON value of any type.\n *\n * Determines the type by looking at the first character and dispatches\n * to the appropriate parser.\n */\nexport function parseValue(text: string): TSONValue {\n const trimmed = text.trim();\n\n if (trimmed.length === 0) {\n return '';\n }\n\n // Check first character to determine type\n const firstChar = trimmed[0];\n\n if (firstChar === '{') {\n // Object (with @ marker) or schematized object\n return parseObject(trimmed);\n } else if (firstChar === '[') {\n // Array\n return parseArray(trimmed);\n } else {\n // Primitive value\n return parsePrimitive(trimmed);\n }\n}\n\n/**\n * Parse TSON object format.\n *\n * Handles both:\n * - {@key1,key2|val1,val2} - Single object or array of objects\n * - {val1,val2} - Schematized object (no @ marker)\n */\nexport function parseObject(text: string): TSONValue {\n const trimmed = text.trim();\n\n if (!trimmed.startsWith('{') || !trimmed.endsWith('}')) {\n throw new Error(`Invalid object format: ${text}`);\n }\n\n // Extract content between braces\n const content = trimmed.slice(1, -1).trim();\n\n // Empty object\n if (content === '@' || content === '') {\n return {};\n }\n\n // Check if this has @ marker (object with keys)\n if (content.startsWith('@')) {\n return parseKeyedObject(content.slice(1)); // Remove @ marker\n } else {\n // Schematized object without @ marker (just values)\n // This shouldn't happen at top level but can occur as nested value\n // Parse as comma-separated values\n const values = splitByDelimiter(content, ',');\n const parsedValues = values.map(v => parseValue(v));\n\n // Return as array (since we don't have keys)\n // In practice, this shouldn't be hit at top level\n return parsedValues;\n }\n}\n\n/**\n * Parse content after @ marker in object.\n *\n * Format: key1,key2|val1,val2 or key1,key2#N|val1,val2|val1,val2\n */\nexport function parseKeyedObject(content: string): TSONValue {\n // Split by pipe to separate keys from values\n const parts = splitByDelimiter(content, '|');\n\n if (parts.length < 1) {\n throw new Error('Invalid object format: missing keys');\n }\n\n // First part contains keys (and possibly row count)\n const keysPart = parts[0];\n\n // Parse keys and extract count if present\n const { keys, count } = parseKeys(keysPart);\n\n // Build schema map (maps field names to nested schemas)\n const schemaMap = buildSchemaMap(keys);\n\n // Get actual field names (without schema notation)\n const fieldNames = keys.map(k => parseKeySchema(k).keyName);\n\n // If only one part, it's an error (no values)\n if (parts.length === 1) {\n throw new Error('Invalid object format: missing values');\n }\n\n // If two parts, could be single object or array with one row\n // If more than two parts, definitely array (multiple rows)\n const valueParts = parts.slice(1);\n\n // Check if this is tabular format (array) or single object\n // If count is specified or multiple value parts, it's tabular\n const isTabular = count !== null || valueParts.length > 1;\n\n if (isTabular) {\n // Array of objects (tabular format)\n return parseTabularArray(fieldNames, valueParts, schemaMap, count);\n } else {\n // Single object\n return parseSingleObject(fieldNames, valueParts[0], schemaMap);\n }\n}\n\n/**\n * Parse a single object from keys and values.\n */\nexport function parseSingleObject(\n fieldNames: string[],\n valuesStr: string,\n schemaMap: SchemaMap\n): TSONObject {\n // Split values\n const values = splitByDelimiter(valuesStr, ',');\n\n if (values.length !== fieldNames.length) {\n throw new Error(\n `Field count mismatch: ${fieldNames.length} fields but ${values.length} values`\n );\n }\n\n // Build object\n const obj: TSONObject = {};\n for (let i = 0; i < fieldNames.length; i++) {\n const fieldName = fieldNames[i];\n const valueStr = values[i];\n\n // Check if this field has a nested schema\n const schema = schemaMap[fieldName];\n\n if (schema) {\n // Parse as schematized object\n obj[fieldName] = parseSchematizedValue(valueStr, schema);\n } else {\n // Parse as regular value\n obj[fieldName] = parseValue(valueStr);\n }\n }\n\n return obj;\n}\n\n/**\n * Parse tabular format into array of objects.\n */\nexport function parseTabularArray(\n fieldNames: string[],\n rowParts: string[],\n schemaMap: SchemaMap,\n expectedCount: number | null\n): TSONObject[] {\n const result: TSONObject[] = [];\n\n for (const rowStr of rowParts) {\n if (rowStr.trim().length === 0) {\n continue;\n }\n\n const obj = parseSingleObject(fieldNames, rowStr, schemaMap);\n result.push(obj);\n }\n\n // Verify count if specified\n if (expectedCount !== null && result.length !== expectedCount) {\n throw new Error(\n `Row count mismatch: expected ${expectedCount} rows but got ${result.length}`\n );\n }\n\n return result;\n}\n\n/**\n * Parse a value that uses a nested schema.\n *\n * The value should be in format {val1,val2} where values correspond to\n * the keys in the schema.\n */\nexport function parseSchematizedValue(valueStr: string, schema: string[]): TSONObject {\n const trimmed = valueStr.trim();\n\n // Should be wrapped in braces\n if (!trimmed.startsWith('{') || !trimmed.endsWith('}')) {\n throw new Error(`Schematized value must be wrapped in braces: ${valueStr}`);\n }\n\n // Extract content\n const content = trimmed.slice(1, -1).trim();\n\n // Empty object\n if (content.length === 0) {\n return {};\n }\n\n // Split by comma\n const values = splitByDelimiter(content, ',');\n\n if (values.length !== schema.length) {\n throw new Error(\n `Schema mismatch: ${schema.length} keys but ${values.length} values`\n );\n }\n\n // Build nested schema map for recursive schemas\n const nestedSchemaMap = buildSchemaMap(schema);\n\n // Get field names (without schema notation)\n const fieldNames = schema.map(k => parseKeySchema(k).keyName);\n\n // Build object\n const obj: TSONObject = {};\n for (let i = 0; i < fieldNames.length; i++) {\n const fieldName = fieldNames[i];\n const valueStr = values[i];\n\n // Check if this field itself has a nested schema\n const nestedSchema = nestedSchemaMap[fieldName];\n\n if (nestedSchema) {\n // Recursively parse with nested schema\n obj[fieldName] = parseSchematizedValue(valueStr, nestedSchema);\n } else {\n // Parse as regular value\n obj[fieldName] = parseValue(valueStr);\n }\n }\n\n return obj;\n}\n\n/**\n * Parse TSON array format.\n *\n * Format: [value1,value2,value3]\n */\nexport function parseArray(text: string): TSONArray {\n const trimmed = text.trim();\n\n if (!trimmed.startsWith('[') || !trimmed.endsWith(']')) {\n throw new Error(`Invalid array format: ${text}`);\n }\n\n // Extract content between brackets\n const content = trimmed.slice(1, -1).trim();\n\n // Empty array\n if (content.length === 0) {\n return [];\n }\n\n // Split by comma\n const values = splitByDelimiter(content, ',');\n\n // Parse each value\n const result: TSONArray = [];\n for (const valueStr of values) {\n if (valueStr.trim().length > 0) {\n // Skip empty strings from trailing commas\n result.push(parseValue(valueStr));\n }\n }\n\n return result;\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -127,6 +127,7 @@ declare function escapeString(value: string): string;
|
|
|
127
127
|
* Unescape a quoted string back to its original form.
|
|
128
128
|
*
|
|
129
129
|
* Reverses the escaping done by escapeString().
|
|
130
|
+
* Must process character by character to handle sequences like \\n correctly.
|
|
130
131
|
*/
|
|
131
132
|
declare function unescapeString(value: string): string;
|
|
132
133
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -127,6 +127,7 @@ declare function escapeString(value: string): string;
|
|
|
127
127
|
* Unescape a quoted string back to its original form.
|
|
128
128
|
*
|
|
129
129
|
* Reverses the escaping done by escapeString().
|
|
130
|
+
* Must process character by character to handle sequences like \\n correctly.
|
|
130
131
|
*/
|
|
131
132
|
declare function unescapeString(value: string): string;
|
|
132
133
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/utils.ts
|
|
2
|
-
var SPECIAL_CHARS = /* @__PURE__ */ new Set([",", "|", "@", "#", "{", "}", "[", "]", "\n", "\r", " ", " "]);
|
|
2
|
+
var SPECIAL_CHARS = /* @__PURE__ */ new Set([",", "|", "@", "#", "{", "}", "[", "]", "\n", "\r", " ", " ", '"', "(", ")"]);
|
|
3
3
|
function needsQuoting(value) {
|
|
4
4
|
if (value.length === 0) {
|
|
5
5
|
return true;
|
|
@@ -31,7 +31,36 @@ function escapeString(value) {
|
|
|
31
31
|
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
|
|
32
32
|
}
|
|
33
33
|
function unescapeString(value) {
|
|
34
|
-
|
|
34
|
+
const result = [];
|
|
35
|
+
let i = 0;
|
|
36
|
+
while (i < value.length) {
|
|
37
|
+
if (value[i] === "\\" && i + 1 < value.length) {
|
|
38
|
+
const nextChar = value[i + 1];
|
|
39
|
+
if (nextChar === "\\") {
|
|
40
|
+
result.push("\\");
|
|
41
|
+
i += 2;
|
|
42
|
+
} else if (nextChar === '"') {
|
|
43
|
+
result.push('"');
|
|
44
|
+
i += 2;
|
|
45
|
+
} else if (nextChar === "n") {
|
|
46
|
+
result.push("\n");
|
|
47
|
+
i += 2;
|
|
48
|
+
} else if (nextChar === "r") {
|
|
49
|
+
result.push("\r");
|
|
50
|
+
i += 2;
|
|
51
|
+
} else if (nextChar === "t") {
|
|
52
|
+
result.push(" ");
|
|
53
|
+
i += 2;
|
|
54
|
+
} else {
|
|
55
|
+
result.push(value[i]);
|
|
56
|
+
i += 1;
|
|
57
|
+
}
|
|
58
|
+
} else {
|
|
59
|
+
result.push(value[i]);
|
|
60
|
+
i += 1;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return result.join("");
|
|
35
64
|
}
|
|
36
65
|
function formatPrimitive(value) {
|
|
37
66
|
if (value === null) {
|
|
@@ -160,11 +189,17 @@ function splitByDelimiter(text, delimiter) {
|
|
|
160
189
|
}
|
|
161
190
|
function parseKeySchema(keyString) {
|
|
162
191
|
const trimmed = keyString.trim();
|
|
192
|
+
if (trimmed.startsWith('"') && trimmed.endsWith('"')) {
|
|
193
|
+
return { keyName: unescapeString(trimmed.slice(1, -1)), schema: null };
|
|
194
|
+
}
|
|
163
195
|
if (!trimmed.includes("(")) {
|
|
164
196
|
return { keyName: trimmed, schema: null };
|
|
165
197
|
}
|
|
166
198
|
const parenIdx = trimmed.indexOf("(");
|
|
167
|
-
|
|
199
|
+
let keyName = trimmed.slice(0, parenIdx).trim();
|
|
200
|
+
if (keyName.startsWith('"') && keyName.endsWith('"')) {
|
|
201
|
+
keyName = unescapeString(keyName.slice(1, -1));
|
|
202
|
+
}
|
|
168
203
|
if (!trimmed.endsWith(")")) {
|
|
169
204
|
throw new Error(`Invalid key schema syntax: ${keyString}`);
|
|
170
205
|
}
|
|
@@ -184,13 +219,35 @@ function buildSchemaMap(keys) {
|
|
|
184
219
|
return schemaMap;
|
|
185
220
|
}
|
|
186
221
|
function parseKeys(keysStr) {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
const
|
|
222
|
+
let hashIdx = -1;
|
|
223
|
+
let inQuotes = false;
|
|
224
|
+
for (let i = keysStr.length - 1; i >= 0; i--) {
|
|
225
|
+
const char = keysStr[i];
|
|
226
|
+
if (char === '"') {
|
|
227
|
+
let backslashCount = 0;
|
|
228
|
+
for (let j = i - 1; j >= 0; j--) {
|
|
229
|
+
if (keysStr[j] === "\\") {
|
|
230
|
+
backslashCount++;
|
|
231
|
+
} else {
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (backslashCount % 2 === 0) {
|
|
236
|
+
inQuotes = !inQuotes;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (char === "#" && !inQuotes) {
|
|
240
|
+
hashIdx = i;
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (hashIdx !== -1) {
|
|
245
|
+
const keysPart = keysStr.slice(0, hashIdx);
|
|
246
|
+
const countPart = keysStr.slice(hashIdx + 1).trim();
|
|
191
247
|
const count = parseInt(countPart, 10);
|
|
192
248
|
if (isNaN(count)) {
|
|
193
|
-
|
|
249
|
+
const keys2 = splitByDelimiter(keysStr, ",");
|
|
250
|
+
return { keys: keys2, count: null };
|
|
194
251
|
}
|
|
195
252
|
const keys = splitByDelimiter(keysPart, ",");
|
|
196
253
|
return { keys, count };
|
|
@@ -273,7 +330,13 @@ function serializeTabular(arr) {
|
|
|
273
330
|
}
|
|
274
331
|
if (key in nestedSchemas) {
|
|
275
332
|
const schemaKeys = nestedSchemas[key];
|
|
276
|
-
const
|
|
333
|
+
const formattedSchemaKeys = schemaKeys.map((sk) => {
|
|
334
|
+
if (needsQuoting(sk)) {
|
|
335
|
+
return `"${escapeString(sk)}"`;
|
|
336
|
+
}
|
|
337
|
+
return sk;
|
|
338
|
+
});
|
|
339
|
+
const schemaStr = formattedSchemaKeys.join(",");
|
|
277
340
|
keyStr = `${keyStr}(@${schemaStr})`;
|
|
278
341
|
}
|
|
279
342
|
keyParts.push(keyStr);
|
|
@@ -380,7 +443,7 @@ function parseKeyedObject(content) {
|
|
|
380
443
|
const keysPart = parts[0];
|
|
381
444
|
const { keys, count } = parseKeys(keysPart);
|
|
382
445
|
const schemaMap = buildSchemaMap(keys);
|
|
383
|
-
const fieldNames = keys.map((k) => k.
|
|
446
|
+
const fieldNames = keys.map((k) => parseKeySchema(k).keyName);
|
|
384
447
|
if (parts.length === 1) {
|
|
385
448
|
throw new Error("Invalid object format: missing values");
|
|
386
449
|
}
|
|
@@ -444,7 +507,7 @@ function parseSchematizedValue(valueStr, schema) {
|
|
|
444
507
|
);
|
|
445
508
|
}
|
|
446
509
|
const nestedSchemaMap = buildSchemaMap(schema);
|
|
447
|
-
const fieldNames = schema.map((k) => k.
|
|
510
|
+
const fieldNames = schema.map((k) => parseKeySchema(k).keyName);
|
|
448
511
|
const obj = {};
|
|
449
512
|
for (let i = 0; i < fieldNames.length; i++) {
|
|
450
513
|
const fieldName = fieldNames[i];
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts","../src/serializer.ts","../src/deserializer.ts"],"names":["valueStr"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * TSON Utility Functions\n *\n * Helper functions for serialization, deserialization, and validation.\n */\n\nimport type { TSONValue, TSONObject, SchemaMap, KeySchema, ParsedKeys } from './types';\n\n/**\n * Special characters that require string quoting\n */\nexport const SPECIAL_CHARS = new Set([',', '|', '@', '#', '{', '}', '[', ']', '\\n', '\\r', '\\t', ' ']);\n\n/**\n * Determine if a string value needs to be quoted in TSON format.\n *\n * Strings need quoting if they:\n * - Are empty\n * - Contain special delimiter characters\n * - Have leading/trailing whitespace\n * - Look like numbers (to preserve them as strings)\n * - Look like reserved words (true/false/null) when we want them as strings\n */\nexport function needsQuoting(value: string): boolean {\n if (value.length === 0) {\n return true;\n }\n\n // Check for reserved words that we want to keep as strings\n if (value === 'true' || value === 'false' || value === 'null') {\n return true;\n }\n\n // Check for leading/trailing whitespace\n if (value[0].trim() === '' || value[value.length - 1].trim() === '') {\n return true;\n }\n\n // Check if it looks like a number (preserve type distinction)\n if (looksLikeNumber(value)) {\n return true;\n }\n\n // Check for special characters\n for (const char of value) {\n if (SPECIAL_CHARS.has(char)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if a string looks like a numeric value.\n *\n * Used to determine if we should quote a string to preserve it as a string\n * rather than having it parsed as a number.\n */\nexport function looksLikeNumber(value: string): boolean {\n if (value.length === 0) {\n return false;\n }\n\n // Try parsing as number\n const num = Number(value);\n return !isNaN(num) && value.trim() === value && isFinite(num);\n}\n\n/**\n * Escape special characters in a string for quoted representation.\n *\n * Uses standard JSON escape sequences.\n */\nexport function escapeString(value: string): string {\n // Order matters: backslash first to avoid double-escaping\n return value\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\n/g, '\\\\n')\n .replace(/\\r/g, '\\\\r')\n .replace(/\\t/g, '\\\\t');\n}\n\n/**\n * Unescape a quoted string back to its original form.\n *\n * Reverses the escaping done by escapeString().\n */\nexport function unescapeString(value: string): string {\n // Order matters: process in reverse order of escaping\n return value\n .replace(/\\\\t/g, '\\t')\n .replace(/\\\\r/g, '\\r')\n .replace(/\\\\n/g, '\\n')\n .replace(/\\\\\"/g, '\"')\n .replace(/\\\\\\\\/g, '\\\\');\n}\n\n/**\n * Format a primitive value as TSON string.\n */\nexport function formatPrimitive(value: TSONValue): string {\n if (value === null) {\n return 'null';\n }\n\n if (typeof value === 'boolean') {\n return value ? 'true' : 'false';\n }\n\n if (typeof value === 'number') {\n return String(value);\n }\n\n if (typeof value === 'string') {\n if (needsQuoting(value)) {\n return `\"${escapeString(value)}\"`;\n }\n return value;\n }\n\n throw new Error(`Cannot format non-primitive type: ${typeof value}`);\n}\n\n/**\n * Parse a TSON primitive value string to JavaScript type.\n */\nexport function parsePrimitive(value: string): TSONValue {\n const trimmed = value.trim();\n\n if (trimmed.length === 0) {\n return '';\n }\n\n // Check for boolean\n if (trimmed === 'true') {\n return true;\n }\n if (trimmed === 'false') {\n return false;\n }\n\n // Check for null\n if (trimmed === 'null') {\n return null;\n }\n\n // Check for quoted string\n if (trimmed.startsWith('\"') && trimmed.endsWith('\"')) {\n return unescapeString(trimmed.slice(1, -1));\n }\n\n // Try to parse as number\n if (looksLikeNumber(trimmed)) {\n const num = Number(trimmed);\n if (!isNaN(num)) {\n return num;\n }\n }\n\n // Otherwise it's an unquoted string\n return trimmed;\n}\n\n/**\n * Check if a value is an array of objects with identical keys.\n *\n * This determines if we can use tabular format optimization.\n */\nexport function isUniformObjectArray(data: unknown): data is TSONObject[] {\n if (!Array.isArray(data) || data.length === 0) {\n return false;\n }\n\n // All elements must be plain objects\n if (!data.every(item => isPlainObject(item))) {\n return false;\n }\n\n // Get keys from first element\n const firstKeys = Object.keys(data[0]);\n\n // Check that all elements have the same keys in the same order\n for (let i = 1; i < data.length; i++) {\n const keys = Object.keys(data[i]);\n if (keys.length !== firstKeys.length) {\n return false;\n }\n for (let j = 0; j < keys.length; j++) {\n if (keys[j] !== firstKeys[j]) {\n return false;\n }\n }\n }\n\n return true;\n}\n\n/**\n * Check if value is a plain object (not array, null, or other special object)\n */\nfunction isPlainObject(value: unknown): value is TSONObject {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.prototype.toString.call(value) === '[object Object]'\n );\n}\n\n/**\n * Split text by delimiter, respecting quoted strings and nested structures.\n *\n * This is more sophisticated than string.split() because it handles:\n * - Quoted strings (don't split on delimiters inside quotes)\n * - Nested braces/brackets/parentheses (don't split inside nested structures)\n * - Escaped characters\n */\nexport function splitByDelimiter(text: string, delimiter: string): string[] {\n const result: string[] = [];\n const current: string[] = [];\n let inQuotes = false;\n let escapeNext = false;\n let depthCurly = 0;\n let depthSquare = 0;\n let depthParen = 0;\n\n for (const char of text) {\n // Handle escape sequences\n if (escapeNext) {\n current.push(char);\n escapeNext = false;\n continue;\n }\n\n if (char === '\\\\') {\n current.push(char);\n escapeNext = true;\n continue;\n }\n\n // Handle quotes\n if (char === '\"') {\n inQuotes = !inQuotes;\n current.push(char);\n continue;\n }\n\n // Inside quotes, add everything\n if (inQuotes) {\n current.push(char);\n continue;\n }\n\n // Track nesting depth\n if (char === '{') {\n depthCurly++;\n current.push(char);\n } else if (char === '}') {\n depthCurly--;\n current.push(char);\n } else if (char === '[') {\n depthSquare++;\n current.push(char);\n } else if (char === ']') {\n depthSquare--;\n current.push(char);\n } else if (char === '(') {\n depthParen++;\n current.push(char);\n } else if (char === ')') {\n depthParen--;\n current.push(char);\n } else if (\n char === delimiter &&\n depthCurly === 0 &&\n depthSquare === 0 &&\n depthParen === 0\n ) {\n // Found unquoted, unnested delimiter - split here\n result.push(current.join('').trim());\n current.length = 0;\n } else {\n current.push(char);\n }\n }\n\n // Add final segment\n if (current.length > 0) {\n result.push(current.join('').trim());\n }\n\n return result;\n}\n\n/**\n * Parse a key which may include nested schema notation.\n *\n * Examples:\n * \"name\" -> { keyName: \"name\", schema: null }\n * \"address(@city,zip)\" -> { keyName: \"address\", schema: [\"city\", \"zip\"] }\n * \"location(@coords(@lat,lng))\" -> { keyName: \"location\", schema: [\"coords(@lat,lng)\"] }\n */\nexport function parseKeySchema(keyString: string): KeySchema {\n const trimmed = keyString.trim();\n\n // Check if key has nested schema\n if (!trimmed.includes('(')) {\n return { keyName: trimmed, schema: null };\n }\n\n // Find the opening parenthesis\n const parenIdx = trimmed.indexOf('(');\n const keyName = trimmed.slice(0, parenIdx).trim();\n\n // Extract schema (everything between outermost parentheses)\n if (!trimmed.endsWith(')')) {\n throw new Error(`Invalid key schema syntax: ${keyString}`);\n }\n\n let schemaStr = trimmed.slice(parenIdx + 1, -1).trim();\n\n // Strip leading @ if present (part of notation, not key name)\n if (schemaStr.startsWith('@')) {\n schemaStr = schemaStr.slice(1);\n }\n\n // Split schema by commas (respecting nested parentheses)\n const schemaKeys = splitByDelimiter(schemaStr, ',');\n\n return { keyName, schema: schemaKeys };\n}\n\n/**\n * Build a mapping of field names to their nested schemas.\n *\n * Example:\n * [\"id\", \"address(@city,zip)\"]\n * -> { id: null, address: [\"city\", \"zip\"] }\n */\nexport function buildSchemaMap(keys: string[]): SchemaMap {\n const schemaMap: SchemaMap = {};\n\n for (const key of keys) {\n const { keyName, schema } = parseKeySchema(key);\n schemaMap[keyName] = schema;\n }\n\n return schemaMap;\n}\n\n/**\n * Parse keys string and extract row count if present.\n *\n * Format: key1,key2,key3 or key1,key2,key3#N\n */\nexport function parseKeys(keysStr: string): ParsedKeys {\n // Check for row count marker\n if (keysStr.includes('#')) {\n // Split from right in case # appears in key name\n const lastHashIdx = keysStr.lastIndexOf('#');\n const keysPart = keysStr.slice(0, lastHashIdx);\n const countPart = keysStr.slice(lastHashIdx + 1).trim();\n\n const count = parseInt(countPart, 10);\n if (isNaN(count)) {\n throw new Error(`Invalid row count: ${countPart}`);\n }\n\n const keys = splitByDelimiter(keysPart, ',');\n return { keys, count };\n } else {\n const keys = splitByDelimiter(keysStr, ',');\n return { keys, count: null };\n }\n}\n","/**\n * TSON Serializer\n *\n * Converts JavaScript data structures to TSON format.\n */\n\nimport type { TSONValue, TSONObject, TSONArray, SchemaMap } from './types';\nimport {\n formatPrimitive,\n needsQuoting,\n escapeString,\n isUniformObjectArray,\n} from './utils';\n\n/**\n * Serialize JavaScript object to TSON formatted string.\n *\n * @example\n * dumps({ name: \"Alice\", age: 30 })\n * // Returns: '{@name,age|Alice,30}'\n *\n * @example\n * dumps([{ id: 1, name: \"Alice\" }, { id: 2, name: \"Bob\" }])\n * // Returns: '{@id,name#2|1,Alice|2,Bob}'\n */\nexport function dumps(data: TSONValue): string {\n return serializeValue(data);\n}\n\n/**\n * Serialize JavaScript object to TSON formatted file (Node.js only).\n *\n * @param data - JavaScript object to serialize\n * @param filePath - Path to file to write\n */\nexport async function dump(data: TSONValue, filePath: string): Promise<void> {\n // Dynamic import for Node.js fs module\n const fs = await import('fs/promises');\n await fs.writeFile(filePath, dumps(data), 'utf-8');\n}\n\n/**\n * Serialize any JavaScript value to TSON format.\n *\n * Dispatches to appropriate serializer based on type.\n */\nexport function serializeValue(value: TSONValue): string {\n // Handle primitives\n if (\n value === null ||\n typeof value === 'boolean' ||\n typeof value === 'number' ||\n typeof value === 'string'\n ) {\n return formatPrimitive(value);\n }\n\n // Handle arrays\n if (Array.isArray(value)) {\n // Check if it's a uniform array of objects (tabular optimization)\n if (isUniformObjectArray(value)) {\n return serializeTabular(value);\n } else {\n return serializeArray(value);\n }\n }\n\n // Handle objects\n if (typeof value === 'object' && value !== null) {\n return serializeObject(value as TSONObject);\n }\n\n throw new TypeError(`Cannot serialize type: ${typeof value}`);\n}\n\n/**\n * Serialize a JavaScript object to TSON object format.\n *\n * Format: {@key1,key2|value1,value2}\n */\nexport function serializeObject(obj: TSONObject): string {\n const keys = Object.keys(obj);\n\n if (keys.length === 0) {\n return '{@}';\n }\n\n // Format keys\n const keyParts: string[] = [];\n for (const key of keys) {\n let keyStr = String(key);\n if (needsQuoting(keyStr)) {\n keyStr = `\"${escapeString(keyStr)}\"`;\n }\n keyParts.push(keyStr);\n }\n\n // Format values\n const valueParts: string[] = [];\n for (const key of keys) {\n valueParts.push(serializeValue(obj[key]));\n }\n\n // Build object string\n const keysStr = keyParts.join(',');\n const valuesStr = valueParts.join(',');\n\n return `{@${keysStr}|${valuesStr}}`;\n}\n\n/**\n * Serialize a JavaScript array to TSON array format.\n *\n * Format: [value1,value2,value3]\n */\nexport function serializeArray(arr: TSONArray): string {\n if (arr.length === 0) {\n return '[]';\n }\n\n // Serialize each element\n const valueParts: string[] = [];\n for (const value of arr) {\n valueParts.push(serializeValue(value));\n }\n\n return '[' + valueParts.join(',') + ']';\n}\n\n/**\n * Serialize a uniform array of objects in tabular format.\n *\n * Format: {@key1,key2#N|val1,val2|val1,val2}\n *\n * This is the key optimization: keys are declared once instead of repeated\n * for each object in the array.\n */\nexport function serializeTabular(arr: TSONObject[]): string {\n if (arr.length === 0) {\n return '[]';\n }\n\n if (!isUniformObjectArray(arr)) {\n throw new Error('Array is not uniform - cannot use tabular format');\n }\n\n // Get keys from first object\n const keys = Object.keys(arr[0]);\n const count = arr.length;\n\n // Check if any values are objects with uniform structure (nested schema opportunity)\n const nestedSchemas = detectNestedSchemas(arr, keys);\n\n // Format keys (with nested schemas if applicable)\n const keyParts: string[] = [];\n for (const key of keys) {\n let keyStr = String(key);\n if (needsQuoting(keyStr)) {\n keyStr = `\"${escapeString(keyStr)}\"`;\n }\n\n // Add nested schema notation if applicable\n if (key in nestedSchemas) {\n const schemaKeys = nestedSchemas[key]!;\n const schemaStr = schemaKeys.join(',');\n keyStr = `${keyStr}(@${schemaStr})`;\n }\n\n keyParts.push(keyStr);\n }\n\n const keysStr = keyParts.join(',');\n\n // Format rows\n const rowParts: string[] = [];\n for (const obj of arr) {\n const valueParts: string[] = [];\n for (const key of keys) {\n const value = obj[key];\n\n // If this key has a nested schema, serialize as schematized object\n if (key in nestedSchemas) {\n valueParts.push(serializeSchematizedObject(value as TSONObject, nestedSchemas[key]!));\n } else {\n valueParts.push(serializeValue(value));\n }\n }\n rowParts.push(valueParts.join(','));\n }\n\n const rowsStr = rowParts.join('|');\n\n return `{@${keysStr}#${count}|${rowsStr}}`;\n}\n\n/**\n * Detect if any fields contain uniform nested objects that can use schema notation.\n *\n * For each key, checks if all values are objects with identical keys.\n * If so, that field can use nested schema notation.\n */\nexport function detectNestedSchemas(arr: TSONObject[], keys: string[]): SchemaMap {\n const nestedSchemas: SchemaMap = {};\n\n for (const key of keys) {\n // Get all values for this key\n const values = arr.map(obj => obj[key]);\n\n // Check if all values are plain objects\n if (!values.every(v => typeof v === 'object' && v !== null && !Array.isArray(v))) {\n continue;\n }\n\n if (values.length === 0) {\n continue;\n }\n\n // Check if all objects have the same keys\n const firstKeys = Object.keys(values[0] as TSONObject);\n const allSame = values.slice(1).every(v => {\n const objKeys = Object.keys(v as TSONObject);\n return (\n objKeys.length === firstKeys.length &&\n objKeys.every((k, i) => k === firstKeys[i])\n );\n });\n\n if (allSame) {\n // This field can use nested schema\n nestedSchemas[key] = firstKeys;\n }\n }\n\n return nestedSchemas;\n}\n\n/**\n * Serialize an object using a pre-declared schema.\n *\n * Format: {value1,value2} (no @ marker, values only)\n *\n * The @ marker is omitted because the schema was already declared in the\n * parent structure.\n */\nexport function serializeSchematizedObject(obj: TSONObject, schema: string[]): string {\n if (Object.keys(obj).length === 0) {\n return '{}';\n }\n\n // Serialize values in schema order\n const valueParts: string[] = [];\n for (const key of schema) {\n const value = obj[key];\n valueParts.push(serializeValue(value));\n }\n\n return '{' + valueParts.join(',') + '}';\n}\n","/**\n * TSON Deserializer\n *\n * Parses TSON format back to JavaScript data structures.\n */\n\nimport type { TSONValue, TSONObject, TSONArray, SchemaMap } from './types';\nimport {\n parsePrimitive,\n splitByDelimiter,\n buildSchemaMap,\n parseKeys,\n} from './utils';\n\n/**\n * Deserialize TSON formatted string to JavaScript object.\n *\n * @example\n * loads('{@name,age|Alice,30}')\n * // Returns: { name: 'Alice', age: 30 }\n *\n * @example\n * loads('{@id,name#2|1,Alice|2,Bob}')\n * // Returns: [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]\n */\nexport function loads(s: string): TSONValue {\n const trimmed = s.trim();\n if (trimmed.length === 0) {\n return null;\n }\n\n return parseValue(trimmed);\n}\n\n/**\n * Deserialize TSON formatted file to JavaScript object (Node.js only).\n *\n * @param filePath - Path to file to read\n * @returns Parsed JavaScript object\n */\nexport async function load(filePath: string): Promise<TSONValue> {\n // Dynamic import for Node.js fs module\n const fs = await import('fs/promises');\n const content = await fs.readFile(filePath, 'utf-8');\n return loads(content);\n}\n\n/**\n * Parse a TSON value of any type.\n *\n * Determines the type by looking at the first character and dispatches\n * to the appropriate parser.\n */\nexport function parseValue(text: string): TSONValue {\n const trimmed = text.trim();\n\n if (trimmed.length === 0) {\n return '';\n }\n\n // Check first character to determine type\n const firstChar = trimmed[0];\n\n if (firstChar === '{') {\n // Object (with @ marker) or schematized object\n return parseObject(trimmed);\n } else if (firstChar === '[') {\n // Array\n return parseArray(trimmed);\n } else {\n // Primitive value\n return parsePrimitive(trimmed);\n }\n}\n\n/**\n * Parse TSON object format.\n *\n * Handles both:\n * - {@key1,key2|val1,val2} - Single object or array of objects\n * - {val1,val2} - Schematized object (no @ marker)\n */\nexport function parseObject(text: string): TSONValue {\n const trimmed = text.trim();\n\n if (!trimmed.startsWith('{') || !trimmed.endsWith('}')) {\n throw new Error(`Invalid object format: ${text}`);\n }\n\n // Extract content between braces\n const content = trimmed.slice(1, -1).trim();\n\n // Empty object\n if (content === '@' || content === '') {\n return {};\n }\n\n // Check if this has @ marker (object with keys)\n if (content.startsWith('@')) {\n return parseKeyedObject(content.slice(1)); // Remove @ marker\n } else {\n // Schematized object without @ marker (just values)\n // This shouldn't happen at top level but can occur as nested value\n // Parse as comma-separated values\n const values = splitByDelimiter(content, ',');\n const parsedValues = values.map(v => parseValue(v));\n\n // Return as array (since we don't have keys)\n // In practice, this shouldn't be hit at top level\n return parsedValues;\n }\n}\n\n/**\n * Parse content after @ marker in object.\n *\n * Format: key1,key2|val1,val2 or key1,key2#N|val1,val2|val1,val2\n */\nexport function parseKeyedObject(content: string): TSONValue {\n // Split by pipe to separate keys from values\n const parts = splitByDelimiter(content, '|');\n\n if (parts.length < 1) {\n throw new Error('Invalid object format: missing keys');\n }\n\n // First part contains keys (and possibly row count)\n const keysPart = parts[0];\n\n // Parse keys and extract count if present\n const { keys, count } = parseKeys(keysPart);\n\n // Build schema map (maps field names to nested schemas)\n const schemaMap = buildSchemaMap(keys);\n\n // Get actual field names (without schema notation)\n const fieldNames = keys.map(k => k.split('(')[0]);\n\n // If only one part, it's an error (no values)\n if (parts.length === 1) {\n throw new Error('Invalid object format: missing values');\n }\n\n // If two parts, could be single object or array with one row\n // If more than two parts, definitely array (multiple rows)\n const valueParts = parts.slice(1);\n\n // Check if this is tabular format (array) or single object\n // If count is specified or multiple value parts, it's tabular\n const isTabular = count !== null || valueParts.length > 1;\n\n if (isTabular) {\n // Array of objects (tabular format)\n return parseTabularArray(fieldNames, valueParts, schemaMap, count);\n } else {\n // Single object\n return parseSingleObject(fieldNames, valueParts[0], schemaMap);\n }\n}\n\n/**\n * Parse a single object from keys and values.\n */\nexport function parseSingleObject(\n fieldNames: string[],\n valuesStr: string,\n schemaMap: SchemaMap\n): TSONObject {\n // Split values\n const values = splitByDelimiter(valuesStr, ',');\n\n if (values.length !== fieldNames.length) {\n throw new Error(\n `Field count mismatch: ${fieldNames.length} fields but ${values.length} values`\n );\n }\n\n // Build object\n const obj: TSONObject = {};\n for (let i = 0; i < fieldNames.length; i++) {\n const fieldName = fieldNames[i];\n const valueStr = values[i];\n\n // Check if this field has a nested schema\n const schema = schemaMap[fieldName];\n\n if (schema) {\n // Parse as schematized object\n obj[fieldName] = parseSchematizedValue(valueStr, schema);\n } else {\n // Parse as regular value\n obj[fieldName] = parseValue(valueStr);\n }\n }\n\n return obj;\n}\n\n/**\n * Parse tabular format into array of objects.\n */\nexport function parseTabularArray(\n fieldNames: string[],\n rowParts: string[],\n schemaMap: SchemaMap,\n expectedCount: number | null\n): TSONObject[] {\n const result: TSONObject[] = [];\n\n for (const rowStr of rowParts) {\n if (rowStr.trim().length === 0) {\n continue;\n }\n\n const obj = parseSingleObject(fieldNames, rowStr, schemaMap);\n result.push(obj);\n }\n\n // Verify count if specified\n if (expectedCount !== null && result.length !== expectedCount) {\n throw new Error(\n `Row count mismatch: expected ${expectedCount} rows but got ${result.length}`\n );\n }\n\n return result;\n}\n\n/**\n * Parse a value that uses a nested schema.\n *\n * The value should be in format {val1,val2} where values correspond to\n * the keys in the schema.\n */\nexport function parseSchematizedValue(valueStr: string, schema: string[]): TSONObject {\n const trimmed = valueStr.trim();\n\n // Should be wrapped in braces\n if (!trimmed.startsWith('{') || !trimmed.endsWith('}')) {\n throw new Error(`Schematized value must be wrapped in braces: ${valueStr}`);\n }\n\n // Extract content\n const content = trimmed.slice(1, -1).trim();\n\n // Empty object\n if (content.length === 0) {\n return {};\n }\n\n // Split by comma\n const values = splitByDelimiter(content, ',');\n\n if (values.length !== schema.length) {\n throw new Error(\n `Schema mismatch: ${schema.length} keys but ${values.length} values`\n );\n }\n\n // Build nested schema map for recursive schemas\n const nestedSchemaMap = buildSchemaMap(schema);\n\n // Get field names (without schema notation)\n const fieldNames = schema.map(k => k.split('(')[0]);\n\n // Build object\n const obj: TSONObject = {};\n for (let i = 0; i < fieldNames.length; i++) {\n const fieldName = fieldNames[i];\n const valueStr = values[i];\n\n // Check if this field itself has a nested schema\n const nestedSchema = nestedSchemaMap[fieldName];\n\n if (nestedSchema) {\n // Recursively parse with nested schema\n obj[fieldName] = parseSchematizedValue(valueStr, nestedSchema);\n } else {\n // Parse as regular value\n obj[fieldName] = parseValue(valueStr);\n }\n }\n\n return obj;\n}\n\n/**\n * Parse TSON array format.\n *\n * Format: [value1,value2,value3]\n */\nexport function parseArray(text: string): TSONArray {\n const trimmed = text.trim();\n\n if (!trimmed.startsWith('[') || !trimmed.endsWith(']')) {\n throw new Error(`Invalid array format: ${text}`);\n }\n\n // Extract content between brackets\n const content = trimmed.slice(1, -1).trim();\n\n // Empty array\n if (content.length === 0) {\n return [];\n }\n\n // Split by comma\n const values = splitByDelimiter(content, ',');\n\n // Parse each value\n const result: TSONArray = [];\n for (const valueStr of values) {\n if (valueStr.trim().length > 0) {\n // Skip empty strings from trailing commas\n result.push(parseValue(valueStr));\n }\n }\n\n return result;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/serializer.ts","../src/deserializer.ts"],"names":["keys","valueStr"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * TSON Utility Functions\n *\n * Helper functions for serialization, deserialization, and validation.\n */\n\nimport type { TSONValue, TSONObject, SchemaMap, KeySchema, ParsedKeys } from './types';\n\n/**\n * Special characters that require string quoting\n */\nexport const SPECIAL_CHARS = new Set([',', '|', '@', '#', '{', '}', '[', ']', '\\n', '\\r', '\\t', ' ', '\"', '(', ')']);\n\n/**\n * Determine if a string value needs to be quoted in TSON format.\n *\n * Strings need quoting if they:\n * - Are empty\n * - Contain special delimiter characters\n * - Have leading/trailing whitespace\n * - Look like numbers (to preserve them as strings)\n * - Look like reserved words (true/false/null) when we want them as strings\n */\nexport function needsQuoting(value: string): boolean {\n if (value.length === 0) {\n return true;\n }\n\n // Check for reserved words that we want to keep as strings\n if (value === 'true' || value === 'false' || value === 'null') {\n return true;\n }\n\n // Check for leading/trailing whitespace\n if (value[0].trim() === '' || value[value.length - 1].trim() === '') {\n return true;\n }\n\n // Check if it looks like a number (preserve type distinction)\n if (looksLikeNumber(value)) {\n return true;\n }\n\n // Check for special characters\n for (const char of value) {\n if (SPECIAL_CHARS.has(char)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if a string looks like a numeric value.\n *\n * Used to determine if we should quote a string to preserve it as a string\n * rather than having it parsed as a number.\n */\nexport function looksLikeNumber(value: string): boolean {\n if (value.length === 0) {\n return false;\n }\n\n // Try parsing as number\n const num = Number(value);\n return !isNaN(num) && value.trim() === value && isFinite(num);\n}\n\n/**\n * Escape special characters in a string for quoted representation.\n *\n * Uses standard JSON escape sequences.\n */\nexport function escapeString(value: string): string {\n // Order matters: backslash first to avoid double-escaping\n return value\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\n/g, '\\\\n')\n .replace(/\\r/g, '\\\\r')\n .replace(/\\t/g, '\\\\t');\n}\n\n/**\n * Unescape a quoted string back to its original form.\n *\n * Reverses the escaping done by escapeString().\n * Must process character by character to handle sequences like \\\\n correctly.\n */\nexport function unescapeString(value: string): string {\n const result: string[] = [];\n let i = 0;\n while (i < value.length) {\n if (value[i] === '\\\\' && i + 1 < value.length) {\n const nextChar = value[i + 1];\n if (nextChar === '\\\\') {\n result.push('\\\\');\n i += 2;\n } else if (nextChar === '\"') {\n result.push('\"');\n i += 2;\n } else if (nextChar === 'n') {\n result.push('\\n');\n i += 2;\n } else if (nextChar === 'r') {\n result.push('\\r');\n i += 2;\n } else if (nextChar === 't') {\n result.push('\\t');\n i += 2;\n } else {\n // Unknown escape, keep as-is\n result.push(value[i]);\n i += 1;\n }\n } else {\n result.push(value[i]);\n i += 1;\n }\n }\n return result.join('');\n}\n\n/**\n * Format a primitive value as TSON string.\n */\nexport function formatPrimitive(value: TSONValue): string {\n if (value === null) {\n return 'null';\n }\n\n if (typeof value === 'boolean') {\n return value ? 'true' : 'false';\n }\n\n if (typeof value === 'number') {\n return String(value);\n }\n\n if (typeof value === 'string') {\n if (needsQuoting(value)) {\n return `\"${escapeString(value)}\"`;\n }\n return value;\n }\n\n throw new Error(`Cannot format non-primitive type: ${typeof value}`);\n}\n\n/**\n * Parse a TSON primitive value string to JavaScript type.\n */\nexport function parsePrimitive(value: string): TSONValue {\n const trimmed = value.trim();\n\n if (trimmed.length === 0) {\n return '';\n }\n\n // Check for boolean\n if (trimmed === 'true') {\n return true;\n }\n if (trimmed === 'false') {\n return false;\n }\n\n // Check for null\n if (trimmed === 'null') {\n return null;\n }\n\n // Check for quoted string\n if (trimmed.startsWith('\"') && trimmed.endsWith('\"')) {\n return unescapeString(trimmed.slice(1, -1));\n }\n\n // Try to parse as number\n if (looksLikeNumber(trimmed)) {\n const num = Number(trimmed);\n if (!isNaN(num)) {\n return num;\n }\n }\n\n // Otherwise it's an unquoted string\n return trimmed;\n}\n\n/**\n * Check if a value is an array of objects with identical keys.\n *\n * This determines if we can use tabular format optimization.\n */\nexport function isUniformObjectArray(data: unknown): data is TSONObject[] {\n if (!Array.isArray(data) || data.length === 0) {\n return false;\n }\n\n // All elements must be plain objects\n if (!data.every(item => isPlainObject(item))) {\n return false;\n }\n\n // Get keys from first element\n const firstKeys = Object.keys(data[0]);\n\n // Check that all elements have the same keys in the same order\n for (let i = 1; i < data.length; i++) {\n const keys = Object.keys(data[i]);\n if (keys.length !== firstKeys.length) {\n return false;\n }\n for (let j = 0; j < keys.length; j++) {\n if (keys[j] !== firstKeys[j]) {\n return false;\n }\n }\n }\n\n return true;\n}\n\n/**\n * Check if value is a plain object (not array, null, or other special object)\n */\nfunction isPlainObject(value: unknown): value is TSONObject {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.prototype.toString.call(value) === '[object Object]'\n );\n}\n\n/**\n * Split text by delimiter, respecting quoted strings and nested structures.\n *\n * This is more sophisticated than string.split() because it handles:\n * - Quoted strings (don't split on delimiters inside quotes)\n * - Nested braces/brackets/parentheses (don't split inside nested structures)\n * - Escaped characters\n */\nexport function splitByDelimiter(text: string, delimiter: string): string[] {\n const result: string[] = [];\n const current: string[] = [];\n let inQuotes = false;\n let escapeNext = false;\n let depthCurly = 0;\n let depthSquare = 0;\n let depthParen = 0;\n\n for (const char of text) {\n // Handle escape sequences\n if (escapeNext) {\n current.push(char);\n escapeNext = false;\n continue;\n }\n\n if (char === '\\\\') {\n current.push(char);\n escapeNext = true;\n continue;\n }\n\n // Handle quotes\n if (char === '\"') {\n inQuotes = !inQuotes;\n current.push(char);\n continue;\n }\n\n // Inside quotes, add everything\n if (inQuotes) {\n current.push(char);\n continue;\n }\n\n // Track nesting depth\n if (char === '{') {\n depthCurly++;\n current.push(char);\n } else if (char === '}') {\n depthCurly--;\n current.push(char);\n } else if (char === '[') {\n depthSquare++;\n current.push(char);\n } else if (char === ']') {\n depthSquare--;\n current.push(char);\n } else if (char === '(') {\n depthParen++;\n current.push(char);\n } else if (char === ')') {\n depthParen--;\n current.push(char);\n } else if (\n char === delimiter &&\n depthCurly === 0 &&\n depthSquare === 0 &&\n depthParen === 0\n ) {\n // Found unquoted, unnested delimiter - split here\n result.push(current.join('').trim());\n current.length = 0;\n } else {\n current.push(char);\n }\n }\n\n // Add final segment\n if (current.length > 0) {\n result.push(current.join('').trim());\n }\n\n return result;\n}\n\n/**\n * Parse a key which may include nested schema notation.\n *\n * Examples:\n * \"name\" -> { keyName: \"name\", schema: null }\n * \"address(@city,zip)\" -> { keyName: \"address\", schema: [\"city\", \"zip\"] }\n * \"location(@coords(@lat,lng))\" -> { keyName: \"location\", schema: [\"coords(@lat,lng)\"] }\n */\nexport function parseKeySchema(keyString: string): KeySchema {\n const trimmed = keyString.trim();\n\n // If the entire key is quoted, it's a simple key (any parens inside are literal)\n // Must check this BEFORE looking for '(' to handle keys like \"company(\"\n if (trimmed.startsWith('\"') && trimmed.endsWith('\"')) {\n return { keyName: unescapeString(trimmed.slice(1, -1)), schema: null };\n }\n\n // Check if key has nested schema (only for unquoted keys)\n if (!trimmed.includes('(')) {\n return { keyName: trimmed, schema: null };\n }\n\n // Find the opening parenthesis\n const parenIdx = trimmed.indexOf('(');\n let keyName = trimmed.slice(0, parenIdx).trim();\n\n // Unquote the key name if it's quoted\n if (keyName.startsWith('\"') && keyName.endsWith('\"')) {\n keyName = unescapeString(keyName.slice(1, -1));\n }\n\n // Extract schema (everything between outermost parentheses)\n if (!trimmed.endsWith(')')) {\n throw new Error(`Invalid key schema syntax: ${keyString}`);\n }\n\n let schemaStr = trimmed.slice(parenIdx + 1, -1).trim();\n\n // Strip leading @ if present (part of notation, not key name)\n if (schemaStr.startsWith('@')) {\n schemaStr = schemaStr.slice(1);\n }\n\n // Split schema by commas (respecting nested parentheses)\n const schemaKeys = splitByDelimiter(schemaStr, ',');\n\n return { keyName, schema: schemaKeys };\n}\n\n/**\n * Build a mapping of field names to their nested schemas.\n *\n * Example:\n * [\"id\", \"address(@city,zip)\"]\n * -> { id: null, address: [\"city\", \"zip\"] }\n */\nexport function buildSchemaMap(keys: string[]): SchemaMap {\n const schemaMap: SchemaMap = {};\n\n for (const key of keys) {\n const { keyName, schema } = parseKeySchema(key);\n schemaMap[keyName] = schema;\n }\n\n return schemaMap;\n}\n\n/**\n * Parse keys string and extract row count if present.\n *\n * Format: key1,key2,key3 or key1,key2,key3#N\n */\nexport function parseKeys(keysStr: string): ParsedKeys {\n // Check for row count marker, respecting quotes\n let hashIdx = -1;\n let inQuotes = false;\n\n // Scan backwards to find the last # that is NOT inside quotes\n for (let i = keysStr.length - 1; i >= 0; i--) {\n const char = keysStr[i];\n\n if (char === '\"') {\n // Check for escaped quote (count preceding backslashes)\n let backslashCount = 0;\n for (let j = i - 1; j >= 0; j--) {\n if (keysStr[j] === '\\\\') {\n backslashCount++;\n } else {\n break;\n }\n }\n\n // If even number of backslashes, it's a real quote\n if (backslashCount % 2 === 0) {\n inQuotes = !inQuotes;\n }\n }\n\n if (char === '#' && !inQuotes) {\n hashIdx = i;\n break;\n }\n }\n\n if (hashIdx !== -1) {\n // Found separator\n const keysPart = keysStr.slice(0, hashIdx);\n const countPart = keysStr.slice(hashIdx + 1).trim();\n\n const count = parseInt(countPart, 10);\n if (isNaN(count)) {\n // If it's not a valid number, ignore the hash (treat as part of key)\n // This handles edge cases where # might appear unquoted but not as separator\n // though strictly that should be quoted according to spec.\n // Fallback to normal parsing\n const keys = splitByDelimiter(keysStr, ',');\n return { keys, count: null };\n }\n\n const keys = splitByDelimiter(keysPart, ',');\n return { keys, count };\n } else {\n const keys = splitByDelimiter(keysStr, ',');\n return { keys, count: null };\n }\n}\n","/**\n * TSON Serializer\n *\n * Converts JavaScript data structures to TSON format.\n */\n\nimport type { TSONValue, TSONObject, TSONArray, SchemaMap } from './types';\nimport {\n formatPrimitive,\n needsQuoting,\n escapeString,\n isUniformObjectArray,\n} from './utils';\n\n/**\n * Serialize JavaScript object to TSON formatted string.\n *\n * @example\n * dumps({ name: \"Alice\", age: 30 })\n * // Returns: '{@name,age|Alice,30}'\n *\n * @example\n * dumps([{ id: 1, name: \"Alice\" }, { id: 2, name: \"Bob\" }])\n * // Returns: '{@id,name#2|1,Alice|2,Bob}'\n */\nexport function dumps(data: TSONValue): string {\n return serializeValue(data);\n}\n\n/**\n * Serialize JavaScript object to TSON formatted file (Node.js only).\n *\n * @param data - JavaScript object to serialize\n * @param filePath - Path to file to write\n */\nexport async function dump(data: TSONValue, filePath: string): Promise<void> {\n // Dynamic import for Node.js fs module\n const fs = await import('fs/promises');\n await fs.writeFile(filePath, dumps(data), 'utf-8');\n}\n\n/**\n * Serialize any JavaScript value to TSON format.\n *\n * Dispatches to appropriate serializer based on type.\n */\nexport function serializeValue(value: TSONValue): string {\n // Handle primitives\n if (\n value === null ||\n typeof value === 'boolean' ||\n typeof value === 'number' ||\n typeof value === 'string'\n ) {\n return formatPrimitive(value);\n }\n\n // Handle arrays\n if (Array.isArray(value)) {\n // Check if it's a uniform array of objects (tabular optimization)\n if (isUniformObjectArray(value)) {\n return serializeTabular(value);\n } else {\n return serializeArray(value);\n }\n }\n\n // Handle objects\n if (typeof value === 'object' && value !== null) {\n return serializeObject(value as TSONObject);\n }\n\n throw new TypeError(`Cannot serialize type: ${typeof value}`);\n}\n\n/**\n * Serialize a JavaScript object to TSON object format.\n *\n * Format: {@key1,key2|value1,value2}\n */\nexport function serializeObject(obj: TSONObject): string {\n const keys = Object.keys(obj);\n\n if (keys.length === 0) {\n return '{@}';\n }\n\n // Format keys\n const keyParts: string[] = [];\n for (const key of keys) {\n let keyStr = String(key);\n if (needsQuoting(keyStr)) {\n keyStr = `\"${escapeString(keyStr)}\"`;\n }\n keyParts.push(keyStr);\n }\n\n // Format values\n const valueParts: string[] = [];\n for (const key of keys) {\n valueParts.push(serializeValue(obj[key]));\n }\n\n // Build object string\n const keysStr = keyParts.join(',');\n const valuesStr = valueParts.join(',');\n\n return `{@${keysStr}|${valuesStr}}`;\n}\n\n/**\n * Serialize a JavaScript array to TSON array format.\n *\n * Format: [value1,value2,value3]\n */\nexport function serializeArray(arr: TSONArray): string {\n if (arr.length === 0) {\n return '[]';\n }\n\n // Serialize each element\n const valueParts: string[] = [];\n for (const value of arr) {\n valueParts.push(serializeValue(value));\n }\n\n return '[' + valueParts.join(',') + ']';\n}\n\n/**\n * Serialize a uniform array of objects in tabular format.\n *\n * Format: {@key1,key2#N|val1,val2|val1,val2}\n *\n * This is the key optimization: keys are declared once instead of repeated\n * for each object in the array.\n */\nexport function serializeTabular(arr: TSONObject[]): string {\n if (arr.length === 0) {\n return '[]';\n }\n\n if (!isUniformObjectArray(arr)) {\n throw new Error('Array is not uniform - cannot use tabular format');\n }\n\n // Get keys from first object\n const keys = Object.keys(arr[0]);\n const count = arr.length;\n\n // Check if any values are objects with uniform structure (nested schema opportunity)\n const nestedSchemas = detectNestedSchemas(arr, keys);\n\n // Format keys (with nested schemas if applicable)\n const keyParts: string[] = [];\n for (const key of keys) {\n let keyStr = String(key);\n if (needsQuoting(keyStr)) {\n keyStr = `\"${escapeString(keyStr)}\"`;\n }\n\n // Add nested schema notation if applicable\n if (key in nestedSchemas) {\n const schemaKeys = nestedSchemas[key]!;\n // Quote schema keys that need quoting (contain special chars)\n const formattedSchemaKeys = schemaKeys.map(sk => {\n if (needsQuoting(sk)) {\n return `\"${escapeString(sk)}\"`;\n }\n return sk;\n });\n const schemaStr = formattedSchemaKeys.join(',');\n keyStr = `${keyStr}(@${schemaStr})`;\n }\n\n keyParts.push(keyStr);\n }\n\n const keysStr = keyParts.join(',');\n\n // Format rows\n const rowParts: string[] = [];\n for (const obj of arr) {\n const valueParts: string[] = [];\n for (const key of keys) {\n const value = obj[key];\n\n // If this key has a nested schema, serialize as schematized object\n if (key in nestedSchemas) {\n valueParts.push(serializeSchematizedObject(value as TSONObject, nestedSchemas[key]!));\n } else {\n valueParts.push(serializeValue(value));\n }\n }\n rowParts.push(valueParts.join(','));\n }\n\n const rowsStr = rowParts.join('|');\n\n return `{@${keysStr}#${count}|${rowsStr}}`;\n}\n\n/**\n * Detect if any fields contain uniform nested objects that can use schema notation.\n *\n * For each key, checks if all values are objects with identical keys.\n * If so, that field can use nested schema notation.\n */\nexport function detectNestedSchemas(arr: TSONObject[], keys: string[]): SchemaMap {\n const nestedSchemas: SchemaMap = {};\n\n for (const key of keys) {\n // Get all values for this key\n const values = arr.map(obj => obj[key]);\n\n // Check if all values are plain objects\n if (!values.every(v => typeof v === 'object' && v !== null && !Array.isArray(v))) {\n continue;\n }\n\n if (values.length === 0) {\n continue;\n }\n\n // Check if all objects have the same keys\n const firstKeys = Object.keys(values[0] as TSONObject);\n const allSame = values.slice(1).every(v => {\n const objKeys = Object.keys(v as TSONObject);\n return (\n objKeys.length === firstKeys.length &&\n objKeys.every((k, i) => k === firstKeys[i])\n );\n });\n\n if (allSame) {\n // This field can use nested schema\n nestedSchemas[key] = firstKeys;\n }\n }\n\n return nestedSchemas;\n}\n\n/**\n * Serialize an object using a pre-declared schema.\n *\n * Format: {value1,value2} (no @ marker, values only)\n *\n * The @ marker is omitted because the schema was already declared in the\n * parent structure.\n */\nexport function serializeSchematizedObject(obj: TSONObject, schema: string[]): string {\n if (Object.keys(obj).length === 0) {\n return '{}';\n }\n\n // Serialize values in schema order\n const valueParts: string[] = [];\n for (const key of schema) {\n const value = obj[key];\n valueParts.push(serializeValue(value));\n }\n\n return '{' + valueParts.join(',') + '}';\n}\n","/**\n * TSON Deserializer\n *\n * Parses TSON format back to JavaScript data structures.\n */\n\nimport type { TSONValue, TSONObject, TSONArray, SchemaMap } from './types';\nimport {\n parsePrimitive,\n splitByDelimiter,\n buildSchemaMap,\n parseKeys,\n parseKeySchema,\n} from './utils';\n\n/**\n * Deserialize TSON formatted string to JavaScript object.\n *\n * @example\n * loads('{@name,age|Alice,30}')\n * // Returns: { name: 'Alice', age: 30 }\n *\n * @example\n * loads('{@id,name#2|1,Alice|2,Bob}')\n * // Returns: [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]\n */\nexport function loads(s: string): TSONValue {\n const trimmed = s.trim();\n if (trimmed.length === 0) {\n return null;\n }\n\n return parseValue(trimmed);\n}\n\n/**\n * Deserialize TSON formatted file to JavaScript object (Node.js only).\n *\n * @param filePath - Path to file to read\n * @returns Parsed JavaScript object\n */\nexport async function load(filePath: string): Promise<TSONValue> {\n // Dynamic import for Node.js fs module\n const fs = await import('fs/promises');\n const content = await fs.readFile(filePath, 'utf-8');\n return loads(content);\n}\n\n/**\n * Parse a TSON value of any type.\n *\n * Determines the type by looking at the first character and dispatches\n * to the appropriate parser.\n */\nexport function parseValue(text: string): TSONValue {\n const trimmed = text.trim();\n\n if (trimmed.length === 0) {\n return '';\n }\n\n // Check first character to determine type\n const firstChar = trimmed[0];\n\n if (firstChar === '{') {\n // Object (with @ marker) or schematized object\n return parseObject(trimmed);\n } else if (firstChar === '[') {\n // Array\n return parseArray(trimmed);\n } else {\n // Primitive value\n return parsePrimitive(trimmed);\n }\n}\n\n/**\n * Parse TSON object format.\n *\n * Handles both:\n * - {@key1,key2|val1,val2} - Single object or array of objects\n * - {val1,val2} - Schematized object (no @ marker)\n */\nexport function parseObject(text: string): TSONValue {\n const trimmed = text.trim();\n\n if (!trimmed.startsWith('{') || !trimmed.endsWith('}')) {\n throw new Error(`Invalid object format: ${text}`);\n }\n\n // Extract content between braces\n const content = trimmed.slice(1, -1).trim();\n\n // Empty object\n if (content === '@' || content === '') {\n return {};\n }\n\n // Check if this has @ marker (object with keys)\n if (content.startsWith('@')) {\n return parseKeyedObject(content.slice(1)); // Remove @ marker\n } else {\n // Schematized object without @ marker (just values)\n // This shouldn't happen at top level but can occur as nested value\n // Parse as comma-separated values\n const values = splitByDelimiter(content, ',');\n const parsedValues = values.map(v => parseValue(v));\n\n // Return as array (since we don't have keys)\n // In practice, this shouldn't be hit at top level\n return parsedValues;\n }\n}\n\n/**\n * Parse content after @ marker in object.\n *\n * Format: key1,key2|val1,val2 or key1,key2#N|val1,val2|val1,val2\n */\nexport function parseKeyedObject(content: string): TSONValue {\n // Split by pipe to separate keys from values\n const parts = splitByDelimiter(content, '|');\n\n if (parts.length < 1) {\n throw new Error('Invalid object format: missing keys');\n }\n\n // First part contains keys (and possibly row count)\n const keysPart = parts[0];\n\n // Parse keys and extract count if present\n const { keys, count } = parseKeys(keysPart);\n\n // Build schema map (maps field names to nested schemas)\n const schemaMap = buildSchemaMap(keys);\n\n // Get actual field names (without schema notation)\n const fieldNames = keys.map(k => parseKeySchema(k).keyName);\n\n // If only one part, it's an error (no values)\n if (parts.length === 1) {\n throw new Error('Invalid object format: missing values');\n }\n\n // If two parts, could be single object or array with one row\n // If more than two parts, definitely array (multiple rows)\n const valueParts = parts.slice(1);\n\n // Check if this is tabular format (array) or single object\n // If count is specified or multiple value parts, it's tabular\n const isTabular = count !== null || valueParts.length > 1;\n\n if (isTabular) {\n // Array of objects (tabular format)\n return parseTabularArray(fieldNames, valueParts, schemaMap, count);\n } else {\n // Single object\n return parseSingleObject(fieldNames, valueParts[0], schemaMap);\n }\n}\n\n/**\n * Parse a single object from keys and values.\n */\nexport function parseSingleObject(\n fieldNames: string[],\n valuesStr: string,\n schemaMap: SchemaMap\n): TSONObject {\n // Split values\n const values = splitByDelimiter(valuesStr, ',');\n\n if (values.length !== fieldNames.length) {\n throw new Error(\n `Field count mismatch: ${fieldNames.length} fields but ${values.length} values`\n );\n }\n\n // Build object\n const obj: TSONObject = {};\n for (let i = 0; i < fieldNames.length; i++) {\n const fieldName = fieldNames[i];\n const valueStr = values[i];\n\n // Check if this field has a nested schema\n const schema = schemaMap[fieldName];\n\n if (schema) {\n // Parse as schematized object\n obj[fieldName] = parseSchematizedValue(valueStr, schema);\n } else {\n // Parse as regular value\n obj[fieldName] = parseValue(valueStr);\n }\n }\n\n return obj;\n}\n\n/**\n * Parse tabular format into array of objects.\n */\nexport function parseTabularArray(\n fieldNames: string[],\n rowParts: string[],\n schemaMap: SchemaMap,\n expectedCount: number | null\n): TSONObject[] {\n const result: TSONObject[] = [];\n\n for (const rowStr of rowParts) {\n if (rowStr.trim().length === 0) {\n continue;\n }\n\n const obj = parseSingleObject(fieldNames, rowStr, schemaMap);\n result.push(obj);\n }\n\n // Verify count if specified\n if (expectedCount !== null && result.length !== expectedCount) {\n throw new Error(\n `Row count mismatch: expected ${expectedCount} rows but got ${result.length}`\n );\n }\n\n return result;\n}\n\n/**\n * Parse a value that uses a nested schema.\n *\n * The value should be in format {val1,val2} where values correspond to\n * the keys in the schema.\n */\nexport function parseSchematizedValue(valueStr: string, schema: string[]): TSONObject {\n const trimmed = valueStr.trim();\n\n // Should be wrapped in braces\n if (!trimmed.startsWith('{') || !trimmed.endsWith('}')) {\n throw new Error(`Schematized value must be wrapped in braces: ${valueStr}`);\n }\n\n // Extract content\n const content = trimmed.slice(1, -1).trim();\n\n // Empty object\n if (content.length === 0) {\n return {};\n }\n\n // Split by comma\n const values = splitByDelimiter(content, ',');\n\n if (values.length !== schema.length) {\n throw new Error(\n `Schema mismatch: ${schema.length} keys but ${values.length} values`\n );\n }\n\n // Build nested schema map for recursive schemas\n const nestedSchemaMap = buildSchemaMap(schema);\n\n // Get field names (without schema notation)\n const fieldNames = schema.map(k => parseKeySchema(k).keyName);\n\n // Build object\n const obj: TSONObject = {};\n for (let i = 0; i < fieldNames.length; i++) {\n const fieldName = fieldNames[i];\n const valueStr = values[i];\n\n // Check if this field itself has a nested schema\n const nestedSchema = nestedSchemaMap[fieldName];\n\n if (nestedSchema) {\n // Recursively parse with nested schema\n obj[fieldName] = parseSchematizedValue(valueStr, nestedSchema);\n } else {\n // Parse as regular value\n obj[fieldName] = parseValue(valueStr);\n }\n }\n\n return obj;\n}\n\n/**\n * Parse TSON array format.\n *\n * Format: [value1,value2,value3]\n */\nexport function parseArray(text: string): TSONArray {\n const trimmed = text.trim();\n\n if (!trimmed.startsWith('[') || !trimmed.endsWith(']')) {\n throw new Error(`Invalid array format: ${text}`);\n }\n\n // Extract content between brackets\n const content = trimmed.slice(1, -1).trim();\n\n // Empty array\n if (content.length === 0) {\n return [];\n }\n\n // Split by comma\n const values = splitByDelimiter(content, ',');\n\n // Parse each value\n const result: TSONArray = [];\n for (const valueStr of values) {\n if (valueStr.trim().length > 0) {\n // Skip empty strings from trailing commas\n result.push(parseValue(valueStr));\n }\n }\n\n return result;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zenoaihq/tson",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Token-efficient Structured Object Notation – a compact serialization format designed for efficient data exchange with LLMs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -73,4 +73,4 @@
|
|
|
73
73
|
"typescript": "^5.3.3",
|
|
74
74
|
"vitest": "^1.2.0"
|
|
75
75
|
}
|
|
76
|
-
}
|
|
76
|
+
}
|