@zenoaihq/tson 1.0.1 → 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 +1 -1
- package/dist/index.cjs +41 -6
- 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 +41 -6
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
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,10 +191,10 @@ 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
|
-
if (trimmed.startsWith('"') && trimmed.endsWith('"')) {
|
|
167
|
-
return { keyName: unescapeString(trimmed.slice(1, -1)), schema: null };
|
|
168
|
-
}
|
|
169
198
|
return { keyName: trimmed, schema: null };
|
|
170
199
|
}
|
|
171
200
|
const parenIdx = trimmed.indexOf("(");
|
|
@@ -303,7 +332,13 @@ function serializeTabular(arr) {
|
|
|
303
332
|
}
|
|
304
333
|
if (key in nestedSchemas) {
|
|
305
334
|
const schemaKeys = nestedSchemas[key];
|
|
306
|
-
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(",");
|
|
307
342
|
keyStr = `${keyStr}(@${schemaStr})`;
|
|
308
343
|
}
|
|
309
344
|
keyParts.push(keyStr);
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts","../src/serializer.ts","../src/deserializer.ts"],"names":["keys","valueStr"],"mappings":"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","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 // Unquote the key name if it's quoted\n if (trimmed.startsWith('\"') && trimmed.endsWith('\"')) {\n return { keyName: unescapeString(trimmed.slice(1, -1)), schema: null };\n }\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 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 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"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/serializer.ts","../src/deserializer.ts"],"names":["keys","valueStr"],"mappings":"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","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,10 +189,10 @@ 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
|
-
if (trimmed.startsWith('"') && trimmed.endsWith('"')) {
|
|
165
|
-
return { keyName: unescapeString(trimmed.slice(1, -1)), schema: null };
|
|
166
|
-
}
|
|
167
196
|
return { keyName: trimmed, schema: null };
|
|
168
197
|
}
|
|
169
198
|
const parenIdx = trimmed.indexOf("(");
|
|
@@ -301,7 +330,13 @@ function serializeTabular(arr) {
|
|
|
301
330
|
}
|
|
302
331
|
if (key in nestedSchemas) {
|
|
303
332
|
const schemaKeys = nestedSchemas[key];
|
|
304
|
-
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(",");
|
|
305
340
|
keyStr = `${keyStr}(@${schemaStr})`;
|
|
306
341
|
}
|
|
307
342
|
keyParts.push(keyStr);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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 */\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 // Unquote the key name if it's quoted\n if (trimmed.startsWith('\"') && trimmed.endsWith('\"')) {\n return { keyName: unescapeString(trimmed.slice(1, -1)), schema: null };\n }\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 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 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"]}
|
|
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
|
+
}
|