@jtml/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +370 -0
- package/dist/chunk-SHDXMADE.mjs +675 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +684 -0
- package/dist/cli.mjs +168 -0
- package/dist/index.d.mts +262 -0
- package/dist/index.d.ts +262 -0
- package/dist/index.js +726 -0
- package/dist/index.mjs +58 -0
- package/package.json +62 -0
package/dist/cli.mjs
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
compareTokens,
|
|
4
|
+
decode,
|
|
5
|
+
encode,
|
|
6
|
+
formatTokenStats
|
|
7
|
+
} from "./chunk-SHDXMADE.mjs";
|
|
8
|
+
|
|
9
|
+
// src/cli.ts
|
|
10
|
+
import { readFileSync, writeFileSync } from "fs";
|
|
11
|
+
var args = process.argv.slice(2);
|
|
12
|
+
function printUsage() {
|
|
13
|
+
console.log(`
|
|
14
|
+
JTML - JSON Token-Minimized Language
|
|
15
|
+
|
|
16
|
+
Usage:
|
|
17
|
+
jtml encode <input.json> [output.jtml] Convert JSON to JTML
|
|
18
|
+
jtml decode <input.jtml> [output.json] Convert JTML to JSON
|
|
19
|
+
jtml compare <input.json> Compare token efficiency
|
|
20
|
+
jtml validate <input.jtml> Validate JTML format
|
|
21
|
+
jtml schema <input.json> Generate schema only
|
|
22
|
+
|
|
23
|
+
Options:
|
|
24
|
+
-h, --help Show this help message
|
|
25
|
+
-v, --version Show version
|
|
26
|
+
--schema-id <id> Set schema ID
|
|
27
|
+
--no-schema Encode without schema
|
|
28
|
+
--tokenizer <gpt|claude|llama> Set tokenizer for comparison
|
|
29
|
+
|
|
30
|
+
Examples:
|
|
31
|
+
jtml encode api-response.json # Output to stdout
|
|
32
|
+
jtml encode data.json output.jtml # Save to file
|
|
33
|
+
jtml decode data.jtml # Output to stdout
|
|
34
|
+
jtml compare large-api.json # Show token savings
|
|
35
|
+
`);
|
|
36
|
+
}
|
|
37
|
+
function getVersion() {
|
|
38
|
+
try {
|
|
39
|
+
const pkg = JSON.parse(readFileSync("./package.json", "utf-8"));
|
|
40
|
+
return pkg.version;
|
|
41
|
+
} catch {
|
|
42
|
+
return "unknown";
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function main() {
|
|
46
|
+
if (args.length === 0 || args.includes("-h") || args.includes("--help")) {
|
|
47
|
+
printUsage();
|
|
48
|
+
process.exit(0);
|
|
49
|
+
}
|
|
50
|
+
if (args.includes("-v") || args.includes("--version")) {
|
|
51
|
+
console.log(`jtml v${getVersion()}`);
|
|
52
|
+
process.exit(0);
|
|
53
|
+
}
|
|
54
|
+
const command = args[0];
|
|
55
|
+
const inputFile = args[1];
|
|
56
|
+
const outputFile = args[2];
|
|
57
|
+
const schemaIdIndex = args.indexOf("--schema-id");
|
|
58
|
+
const schemaId = schemaIdIndex >= 0 ? args[schemaIdIndex + 1] : void 0;
|
|
59
|
+
const noSchema = args.includes("--no-schema");
|
|
60
|
+
const tokenizerIndex = args.indexOf("--tokenizer");
|
|
61
|
+
const tokenizer = tokenizerIndex >= 0 ? args[tokenizerIndex + 1] : "claude";
|
|
62
|
+
try {
|
|
63
|
+
switch (command) {
|
|
64
|
+
case "encode": {
|
|
65
|
+
if (!inputFile) {
|
|
66
|
+
console.error("Error: Input file required");
|
|
67
|
+
printUsage();
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
const jsonText = readFileSync(inputFile, "utf-8");
|
|
71
|
+
const data = JSON.parse(jsonText);
|
|
72
|
+
const jtml = encode(data, {
|
|
73
|
+
schemaId,
|
|
74
|
+
includeSchema: !noSchema,
|
|
75
|
+
autoInferTypes: true
|
|
76
|
+
});
|
|
77
|
+
if (outputFile) {
|
|
78
|
+
writeFileSync(outputFile, jtml, "utf-8");
|
|
79
|
+
console.log(`\u2713 Encoded to ${outputFile}`);
|
|
80
|
+
const stats = compareTokens(jsonText, jtml, tokenizer);
|
|
81
|
+
console.log(formatTokenStats(stats));
|
|
82
|
+
} else {
|
|
83
|
+
console.log(jtml);
|
|
84
|
+
}
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
case "decode": {
|
|
88
|
+
if (!inputFile) {
|
|
89
|
+
console.error("Error: Input file required");
|
|
90
|
+
printUsage();
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
const jtml = readFileSync(inputFile, "utf-8");
|
|
94
|
+
const data = decode(jtml);
|
|
95
|
+
const jsonText = JSON.stringify(data, null, 2);
|
|
96
|
+
if (outputFile) {
|
|
97
|
+
writeFileSync(outputFile, jsonText, "utf-8");
|
|
98
|
+
console.log(`\u2713 Decoded to ${outputFile}`);
|
|
99
|
+
} else {
|
|
100
|
+
console.log(jsonText);
|
|
101
|
+
}
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
case "compare": {
|
|
105
|
+
if (!inputFile) {
|
|
106
|
+
console.error("Error: Input file required");
|
|
107
|
+
printUsage();
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
const jsonText = readFileSync(inputFile, "utf-8");
|
|
111
|
+
const data = JSON.parse(jsonText);
|
|
112
|
+
const jtml = encode(data);
|
|
113
|
+
const stats = compareTokens(jsonText, jtml, tokenizer);
|
|
114
|
+
console.log("\n=== Token Efficiency Comparison ===\n");
|
|
115
|
+
console.log(formatTokenStats(stats));
|
|
116
|
+
console.log(`
|
|
117
|
+
Tokenizer: ${tokenizer}`);
|
|
118
|
+
console.log(`JSON size: ${jsonText.length} chars`);
|
|
119
|
+
console.log(`JTML size: ${jtml.length} chars`);
|
|
120
|
+
console.log(`Compression: ${((jsonText.length - jtml.length) / jsonText.length * 100).toFixed(2)}%`);
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
case "validate": {
|
|
124
|
+
if (!inputFile) {
|
|
125
|
+
console.error("Error: Input file required");
|
|
126
|
+
printUsage();
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
const jtml = readFileSync(inputFile, "utf-8");
|
|
130
|
+
try {
|
|
131
|
+
decode(jtml);
|
|
132
|
+
console.log("\u2713 Valid JTML format");
|
|
133
|
+
} catch (error) {
|
|
134
|
+
console.error("\u2717 Invalid JTML format");
|
|
135
|
+
if (error instanceof Error) {
|
|
136
|
+
console.error(` ${error.message}`);
|
|
137
|
+
}
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
case "schema": {
|
|
143
|
+
if (!inputFile) {
|
|
144
|
+
console.error("Error: Input file required");
|
|
145
|
+
printUsage();
|
|
146
|
+
process.exit(1);
|
|
147
|
+
}
|
|
148
|
+
const jsonText = readFileSync(inputFile, "utf-8");
|
|
149
|
+
const data = JSON.parse(jsonText);
|
|
150
|
+
const jtml = encode(data, {
|
|
151
|
+
schemaId: schemaId || "generated",
|
|
152
|
+
includeSchema: true
|
|
153
|
+
});
|
|
154
|
+
const schemaOnly = jtml.split("@data")[0].trim();
|
|
155
|
+
console.log(schemaOnly);
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
default:
|
|
159
|
+
console.error(`Error: Unknown command '${command}'`);
|
|
160
|
+
printUsage();
|
|
161
|
+
process.exit(1);
|
|
162
|
+
}
|
|
163
|
+
} catch (error) {
|
|
164
|
+
console.error("Error:", error instanceof Error ? error.message : String(error));
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
main();
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JTML Type Definitions
|
|
3
|
+
*/
|
|
4
|
+
type JTMLType = 'i' | 'f' | 's' | 'b' | 't' | 'n' | 'o' | 'a' | 'e' | 'ref';
|
|
5
|
+
interface JTMLTypeInfo {
|
|
6
|
+
type: JTMLType;
|
|
7
|
+
arrayOf?: JTMLType;
|
|
8
|
+
enumValues?: string[];
|
|
9
|
+
refSchema?: string;
|
|
10
|
+
optional?: boolean;
|
|
11
|
+
}
|
|
12
|
+
interface JTMLField {
|
|
13
|
+
name: string;
|
|
14
|
+
typeInfo: JTMLTypeInfo;
|
|
15
|
+
}
|
|
16
|
+
interface JTMLSchema {
|
|
17
|
+
id: string;
|
|
18
|
+
fields: JTMLField[];
|
|
19
|
+
version?: string;
|
|
20
|
+
}
|
|
21
|
+
interface JTMLEncodeOptions {
|
|
22
|
+
schemaId?: string;
|
|
23
|
+
schemaRef?: string;
|
|
24
|
+
autoInferTypes?: boolean;
|
|
25
|
+
compress?: boolean;
|
|
26
|
+
includeSchema?: boolean;
|
|
27
|
+
}
|
|
28
|
+
interface JTMLDecodeOptions {
|
|
29
|
+
schemaCache?: Map<string, JTMLSchema>;
|
|
30
|
+
strict?: boolean;
|
|
31
|
+
}
|
|
32
|
+
interface JTMLDocument {
|
|
33
|
+
schema?: JTMLSchema;
|
|
34
|
+
data: unknown;
|
|
35
|
+
metadata?: Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
interface TokenStats {
|
|
38
|
+
jsonTokens: number;
|
|
39
|
+
jtmlTokens: number;
|
|
40
|
+
savings: number;
|
|
41
|
+
savingsPercent: number;
|
|
42
|
+
}
|
|
43
|
+
type JTMLValue = string | number | boolean | null | JTMLValue[] | {
|
|
44
|
+
[key: string]: JTMLValue;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Type mapping:
|
|
48
|
+
* i - integer
|
|
49
|
+
* f - float
|
|
50
|
+
* s - string
|
|
51
|
+
* b - boolean
|
|
52
|
+
* t - timestamp/datetime
|
|
53
|
+
* n - null
|
|
54
|
+
* o - object
|
|
55
|
+
* a - array
|
|
56
|
+
* e - enum
|
|
57
|
+
* ref - reference to another schema
|
|
58
|
+
*/
|
|
59
|
+
declare const TYPE_MAP: Record<JTMLType, string>;
|
|
60
|
+
declare class JTMLError extends Error {
|
|
61
|
+
code: string;
|
|
62
|
+
constructor(message: string, code: string);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
declare class JTMLEncoder {
|
|
66
|
+
/**
|
|
67
|
+
* Encode JSON data to JTML format
|
|
68
|
+
*/
|
|
69
|
+
encode(data: unknown, options?: JTMLEncodeOptions): string;
|
|
70
|
+
/**
|
|
71
|
+
* Encode with explicit schema
|
|
72
|
+
*/
|
|
73
|
+
private encodeWithSchema;
|
|
74
|
+
/**
|
|
75
|
+
* Encode a single row according to schema
|
|
76
|
+
*/
|
|
77
|
+
private encodeRow;
|
|
78
|
+
/**
|
|
79
|
+
* Encode a single value
|
|
80
|
+
*/
|
|
81
|
+
private encodeValue;
|
|
82
|
+
/**
|
|
83
|
+
* Simple encoding without schema (fallback)
|
|
84
|
+
*/
|
|
85
|
+
private encodeSimple;
|
|
86
|
+
/**
|
|
87
|
+
* Encode with metadata
|
|
88
|
+
*/
|
|
89
|
+
encodeWithMetadata(data: unknown, metadata: Record<string, unknown>, options?: JTMLEncodeOptions): string;
|
|
90
|
+
}
|
|
91
|
+
declare const encoder: JTMLEncoder;
|
|
92
|
+
/**
|
|
93
|
+
* Convenience function to encode JSON to JTML
|
|
94
|
+
*/
|
|
95
|
+
declare function encode(data: unknown, options?: JTMLEncodeOptions): string;
|
|
96
|
+
/**
|
|
97
|
+
* Encode multiple datasets with shared schema
|
|
98
|
+
*/
|
|
99
|
+
declare function encodeBatch(datasets: unknown[], schemaId?: string): string;
|
|
100
|
+
|
|
101
|
+
declare class JTMLDecoder {
|
|
102
|
+
/**
|
|
103
|
+
* Decode JTML format to JSON
|
|
104
|
+
*/
|
|
105
|
+
decode(jtml: string, options?: JTMLDecodeOptions): unknown;
|
|
106
|
+
/**
|
|
107
|
+
* Decode a single row according to schema
|
|
108
|
+
*/
|
|
109
|
+
private decodeRow;
|
|
110
|
+
/**
|
|
111
|
+
* Split row by pipe delimiter, handling escaped pipes
|
|
112
|
+
*/
|
|
113
|
+
private splitRow;
|
|
114
|
+
/**
|
|
115
|
+
* Decode a single value
|
|
116
|
+
*/
|
|
117
|
+
private decodeValue;
|
|
118
|
+
}
|
|
119
|
+
declare const decoder: JTMLDecoder;
|
|
120
|
+
/**
|
|
121
|
+
* Convenience function to decode JTML to JSON
|
|
122
|
+
*/
|
|
123
|
+
declare function decode(jtml: string, options?: JTMLDecodeOptions): unknown;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Approximate token counting for different tokenizers
|
|
127
|
+
* Based on heuristics - for exact counts, use actual tokenizer libraries
|
|
128
|
+
*/
|
|
129
|
+
type TokenizerType = 'gpt' | 'claude' | 'llama';
|
|
130
|
+
/**
|
|
131
|
+
* Estimate token count using simple heuristics
|
|
132
|
+
* GPT/Claude: ~4 chars per token average
|
|
133
|
+
* More accurate for estimation than character count
|
|
134
|
+
*/
|
|
135
|
+
declare function estimateTokens(text: string, tokenizer?: TokenizerType): number;
|
|
136
|
+
/**
|
|
137
|
+
* Compare token efficiency between JSON and JTML
|
|
138
|
+
*/
|
|
139
|
+
declare function compareTokens(jsonText: string, jtmlText: string, tokenizer?: TokenizerType): TokenStats;
|
|
140
|
+
/**
|
|
141
|
+
* Calculate token efficiency ratio
|
|
142
|
+
*/
|
|
143
|
+
declare function calculateEfficiency(jsonText: string, jtmlText: string): number;
|
|
144
|
+
/**
|
|
145
|
+
* Detailed token analysis
|
|
146
|
+
*/
|
|
147
|
+
interface DetailedTokenStats {
|
|
148
|
+
json: {
|
|
149
|
+
total: number;
|
|
150
|
+
structural: number;
|
|
151
|
+
keys: number;
|
|
152
|
+
values: number;
|
|
153
|
+
};
|
|
154
|
+
jtml: {
|
|
155
|
+
total: number;
|
|
156
|
+
schema: number;
|
|
157
|
+
data: number;
|
|
158
|
+
delimiters: number;
|
|
159
|
+
};
|
|
160
|
+
comparison: TokenStats;
|
|
161
|
+
}
|
|
162
|
+
declare function analyzeTokens(jsonText: string, jtmlText: string, tokenizer?: TokenizerType): DetailedTokenStats;
|
|
163
|
+
/**
|
|
164
|
+
* Format token stats for display
|
|
165
|
+
*/
|
|
166
|
+
declare function formatTokenStats(stats: TokenStats): string;
|
|
167
|
+
/**
|
|
168
|
+
* Estimate cost savings (based on typical LLM pricing)
|
|
169
|
+
*/
|
|
170
|
+
interface CostSavings {
|
|
171
|
+
tokensSaved: number;
|
|
172
|
+
costSavedPer1M: number;
|
|
173
|
+
costSavedPer1K: number;
|
|
174
|
+
}
|
|
175
|
+
declare function estimateCostSavings(stats: TokenStats, pricePerMillion?: number): CostSavings;
|
|
176
|
+
|
|
177
|
+
declare class SchemaManager {
|
|
178
|
+
private schemas;
|
|
179
|
+
/**
|
|
180
|
+
* Register a schema for reuse
|
|
181
|
+
*/
|
|
182
|
+
register(schema: JTMLSchema): void;
|
|
183
|
+
/**
|
|
184
|
+
* Get a registered schema
|
|
185
|
+
*/
|
|
186
|
+
get(id: string): JTMLSchema | undefined;
|
|
187
|
+
/**
|
|
188
|
+
* Check if schema exists
|
|
189
|
+
*/
|
|
190
|
+
has(id: string): boolean;
|
|
191
|
+
/**
|
|
192
|
+
* Clear all schemas
|
|
193
|
+
*/
|
|
194
|
+
clear(): void;
|
|
195
|
+
/**
|
|
196
|
+
* Export all schemas
|
|
197
|
+
*/
|
|
198
|
+
export(): JTMLSchema[];
|
|
199
|
+
/**
|
|
200
|
+
* Import schemas
|
|
201
|
+
*/
|
|
202
|
+
import(schemas: JTMLSchema[]): void;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Infer JTML type from JavaScript value
|
|
206
|
+
*/
|
|
207
|
+
declare function inferType(value: unknown): JTMLTypeInfo;
|
|
208
|
+
/**
|
|
209
|
+
* Infer schema from JSON data
|
|
210
|
+
*/
|
|
211
|
+
declare function inferSchema(data: unknown, schemaId: string): JTMLSchema;
|
|
212
|
+
/**
|
|
213
|
+
* Serialize schema to JTML format
|
|
214
|
+
*/
|
|
215
|
+
declare function serializeSchema(schema: JTMLSchema): string;
|
|
216
|
+
/**
|
|
217
|
+
* Parse schema from JTML format
|
|
218
|
+
*/
|
|
219
|
+
declare function parseSchema(schemaStr: string): JTMLSchema;
|
|
220
|
+
/**
|
|
221
|
+
* Validate data against schema
|
|
222
|
+
*/
|
|
223
|
+
declare function validateAgainstSchema(data: unknown, schema: JTMLSchema): boolean;
|
|
224
|
+
declare const schemaManager: SchemaManager;
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Quick conversion utilities
|
|
228
|
+
*/
|
|
229
|
+
/**
|
|
230
|
+
* Convert JSON to JTML (one-liner)
|
|
231
|
+
*/
|
|
232
|
+
declare function jsonToJtml(json: unknown, schemaId?: string): string;
|
|
233
|
+
/**
|
|
234
|
+
* Convert JTML to JSON (one-liner)
|
|
235
|
+
*/
|
|
236
|
+
declare function jtmlToJson(jtml: string): unknown;
|
|
237
|
+
/**
|
|
238
|
+
* Convert JSON string to JTML string
|
|
239
|
+
*/
|
|
240
|
+
declare function convertJsonString(jsonStr: string, schemaId?: string): string;
|
|
241
|
+
/**
|
|
242
|
+
* Round-trip conversion test
|
|
243
|
+
*/
|
|
244
|
+
declare function roundTrip(data: unknown): {
|
|
245
|
+
success: boolean;
|
|
246
|
+
original: unknown;
|
|
247
|
+
recovered: unknown;
|
|
248
|
+
jtml: string;
|
|
249
|
+
};
|
|
250
|
+
declare const _default: {
|
|
251
|
+
encode: typeof encode;
|
|
252
|
+
decode: typeof decode;
|
|
253
|
+
jsonToJtml: typeof jsonToJtml;
|
|
254
|
+
jtmlToJson: typeof jtmlToJson;
|
|
255
|
+
convertJsonString: typeof convertJsonString;
|
|
256
|
+
roundTrip: typeof roundTrip;
|
|
257
|
+
schemaManager: SchemaManager;
|
|
258
|
+
estimateTokens: typeof estimateTokens;
|
|
259
|
+
compareTokens: typeof compareTokens;
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
export { type CostSavings, type DetailedTokenStats, type JTMLDecodeOptions, JTMLDecoder, type JTMLDocument, type JTMLEncodeOptions, JTMLEncoder, JTMLError, type JTMLField, type JTMLSchema, type JTMLType, type JTMLTypeInfo, type JTMLValue, SchemaManager, TYPE_MAP, type TokenStats, type TokenizerType, analyzeTokens, calculateEfficiency, compareTokens, convertJsonString, decode, decoder, _default as default, encode, encodeBatch, encoder, estimateCostSavings, estimateTokens, formatTokenStats, inferSchema, inferType, jsonToJtml, jtmlToJson, parseSchema, roundTrip, schemaManager, serializeSchema, validateAgainstSchema };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JTML Type Definitions
|
|
3
|
+
*/
|
|
4
|
+
type JTMLType = 'i' | 'f' | 's' | 'b' | 't' | 'n' | 'o' | 'a' | 'e' | 'ref';
|
|
5
|
+
interface JTMLTypeInfo {
|
|
6
|
+
type: JTMLType;
|
|
7
|
+
arrayOf?: JTMLType;
|
|
8
|
+
enumValues?: string[];
|
|
9
|
+
refSchema?: string;
|
|
10
|
+
optional?: boolean;
|
|
11
|
+
}
|
|
12
|
+
interface JTMLField {
|
|
13
|
+
name: string;
|
|
14
|
+
typeInfo: JTMLTypeInfo;
|
|
15
|
+
}
|
|
16
|
+
interface JTMLSchema {
|
|
17
|
+
id: string;
|
|
18
|
+
fields: JTMLField[];
|
|
19
|
+
version?: string;
|
|
20
|
+
}
|
|
21
|
+
interface JTMLEncodeOptions {
|
|
22
|
+
schemaId?: string;
|
|
23
|
+
schemaRef?: string;
|
|
24
|
+
autoInferTypes?: boolean;
|
|
25
|
+
compress?: boolean;
|
|
26
|
+
includeSchema?: boolean;
|
|
27
|
+
}
|
|
28
|
+
interface JTMLDecodeOptions {
|
|
29
|
+
schemaCache?: Map<string, JTMLSchema>;
|
|
30
|
+
strict?: boolean;
|
|
31
|
+
}
|
|
32
|
+
interface JTMLDocument {
|
|
33
|
+
schema?: JTMLSchema;
|
|
34
|
+
data: unknown;
|
|
35
|
+
metadata?: Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
interface TokenStats {
|
|
38
|
+
jsonTokens: number;
|
|
39
|
+
jtmlTokens: number;
|
|
40
|
+
savings: number;
|
|
41
|
+
savingsPercent: number;
|
|
42
|
+
}
|
|
43
|
+
type JTMLValue = string | number | boolean | null | JTMLValue[] | {
|
|
44
|
+
[key: string]: JTMLValue;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Type mapping:
|
|
48
|
+
* i - integer
|
|
49
|
+
* f - float
|
|
50
|
+
* s - string
|
|
51
|
+
* b - boolean
|
|
52
|
+
* t - timestamp/datetime
|
|
53
|
+
* n - null
|
|
54
|
+
* o - object
|
|
55
|
+
* a - array
|
|
56
|
+
* e - enum
|
|
57
|
+
* ref - reference to another schema
|
|
58
|
+
*/
|
|
59
|
+
declare const TYPE_MAP: Record<JTMLType, string>;
|
|
60
|
+
declare class JTMLError extends Error {
|
|
61
|
+
code: string;
|
|
62
|
+
constructor(message: string, code: string);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
declare class JTMLEncoder {
|
|
66
|
+
/**
|
|
67
|
+
* Encode JSON data to JTML format
|
|
68
|
+
*/
|
|
69
|
+
encode(data: unknown, options?: JTMLEncodeOptions): string;
|
|
70
|
+
/**
|
|
71
|
+
* Encode with explicit schema
|
|
72
|
+
*/
|
|
73
|
+
private encodeWithSchema;
|
|
74
|
+
/**
|
|
75
|
+
* Encode a single row according to schema
|
|
76
|
+
*/
|
|
77
|
+
private encodeRow;
|
|
78
|
+
/**
|
|
79
|
+
* Encode a single value
|
|
80
|
+
*/
|
|
81
|
+
private encodeValue;
|
|
82
|
+
/**
|
|
83
|
+
* Simple encoding without schema (fallback)
|
|
84
|
+
*/
|
|
85
|
+
private encodeSimple;
|
|
86
|
+
/**
|
|
87
|
+
* Encode with metadata
|
|
88
|
+
*/
|
|
89
|
+
encodeWithMetadata(data: unknown, metadata: Record<string, unknown>, options?: JTMLEncodeOptions): string;
|
|
90
|
+
}
|
|
91
|
+
declare const encoder: JTMLEncoder;
|
|
92
|
+
/**
|
|
93
|
+
* Convenience function to encode JSON to JTML
|
|
94
|
+
*/
|
|
95
|
+
declare function encode(data: unknown, options?: JTMLEncodeOptions): string;
|
|
96
|
+
/**
|
|
97
|
+
* Encode multiple datasets with shared schema
|
|
98
|
+
*/
|
|
99
|
+
declare function encodeBatch(datasets: unknown[], schemaId?: string): string;
|
|
100
|
+
|
|
101
|
+
declare class JTMLDecoder {
|
|
102
|
+
/**
|
|
103
|
+
* Decode JTML format to JSON
|
|
104
|
+
*/
|
|
105
|
+
decode(jtml: string, options?: JTMLDecodeOptions): unknown;
|
|
106
|
+
/**
|
|
107
|
+
* Decode a single row according to schema
|
|
108
|
+
*/
|
|
109
|
+
private decodeRow;
|
|
110
|
+
/**
|
|
111
|
+
* Split row by pipe delimiter, handling escaped pipes
|
|
112
|
+
*/
|
|
113
|
+
private splitRow;
|
|
114
|
+
/**
|
|
115
|
+
* Decode a single value
|
|
116
|
+
*/
|
|
117
|
+
private decodeValue;
|
|
118
|
+
}
|
|
119
|
+
declare const decoder: JTMLDecoder;
|
|
120
|
+
/**
|
|
121
|
+
* Convenience function to decode JTML to JSON
|
|
122
|
+
*/
|
|
123
|
+
declare function decode(jtml: string, options?: JTMLDecodeOptions): unknown;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Approximate token counting for different tokenizers
|
|
127
|
+
* Based on heuristics - for exact counts, use actual tokenizer libraries
|
|
128
|
+
*/
|
|
129
|
+
type TokenizerType = 'gpt' | 'claude' | 'llama';
|
|
130
|
+
/**
|
|
131
|
+
* Estimate token count using simple heuristics
|
|
132
|
+
* GPT/Claude: ~4 chars per token average
|
|
133
|
+
* More accurate for estimation than character count
|
|
134
|
+
*/
|
|
135
|
+
declare function estimateTokens(text: string, tokenizer?: TokenizerType): number;
|
|
136
|
+
/**
|
|
137
|
+
* Compare token efficiency between JSON and JTML
|
|
138
|
+
*/
|
|
139
|
+
declare function compareTokens(jsonText: string, jtmlText: string, tokenizer?: TokenizerType): TokenStats;
|
|
140
|
+
/**
|
|
141
|
+
* Calculate token efficiency ratio
|
|
142
|
+
*/
|
|
143
|
+
declare function calculateEfficiency(jsonText: string, jtmlText: string): number;
|
|
144
|
+
/**
|
|
145
|
+
* Detailed token analysis
|
|
146
|
+
*/
|
|
147
|
+
interface DetailedTokenStats {
|
|
148
|
+
json: {
|
|
149
|
+
total: number;
|
|
150
|
+
structural: number;
|
|
151
|
+
keys: number;
|
|
152
|
+
values: number;
|
|
153
|
+
};
|
|
154
|
+
jtml: {
|
|
155
|
+
total: number;
|
|
156
|
+
schema: number;
|
|
157
|
+
data: number;
|
|
158
|
+
delimiters: number;
|
|
159
|
+
};
|
|
160
|
+
comparison: TokenStats;
|
|
161
|
+
}
|
|
162
|
+
declare function analyzeTokens(jsonText: string, jtmlText: string, tokenizer?: TokenizerType): DetailedTokenStats;
|
|
163
|
+
/**
|
|
164
|
+
* Format token stats for display
|
|
165
|
+
*/
|
|
166
|
+
declare function formatTokenStats(stats: TokenStats): string;
|
|
167
|
+
/**
|
|
168
|
+
* Estimate cost savings (based on typical LLM pricing)
|
|
169
|
+
*/
|
|
170
|
+
interface CostSavings {
|
|
171
|
+
tokensSaved: number;
|
|
172
|
+
costSavedPer1M: number;
|
|
173
|
+
costSavedPer1K: number;
|
|
174
|
+
}
|
|
175
|
+
declare function estimateCostSavings(stats: TokenStats, pricePerMillion?: number): CostSavings;
|
|
176
|
+
|
|
177
|
+
declare class SchemaManager {
|
|
178
|
+
private schemas;
|
|
179
|
+
/**
|
|
180
|
+
* Register a schema for reuse
|
|
181
|
+
*/
|
|
182
|
+
register(schema: JTMLSchema): void;
|
|
183
|
+
/**
|
|
184
|
+
* Get a registered schema
|
|
185
|
+
*/
|
|
186
|
+
get(id: string): JTMLSchema | undefined;
|
|
187
|
+
/**
|
|
188
|
+
* Check if schema exists
|
|
189
|
+
*/
|
|
190
|
+
has(id: string): boolean;
|
|
191
|
+
/**
|
|
192
|
+
* Clear all schemas
|
|
193
|
+
*/
|
|
194
|
+
clear(): void;
|
|
195
|
+
/**
|
|
196
|
+
* Export all schemas
|
|
197
|
+
*/
|
|
198
|
+
export(): JTMLSchema[];
|
|
199
|
+
/**
|
|
200
|
+
* Import schemas
|
|
201
|
+
*/
|
|
202
|
+
import(schemas: JTMLSchema[]): void;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Infer JTML type from JavaScript value
|
|
206
|
+
*/
|
|
207
|
+
declare function inferType(value: unknown): JTMLTypeInfo;
|
|
208
|
+
/**
|
|
209
|
+
* Infer schema from JSON data
|
|
210
|
+
*/
|
|
211
|
+
declare function inferSchema(data: unknown, schemaId: string): JTMLSchema;
|
|
212
|
+
/**
|
|
213
|
+
* Serialize schema to JTML format
|
|
214
|
+
*/
|
|
215
|
+
declare function serializeSchema(schema: JTMLSchema): string;
|
|
216
|
+
/**
|
|
217
|
+
* Parse schema from JTML format
|
|
218
|
+
*/
|
|
219
|
+
declare function parseSchema(schemaStr: string): JTMLSchema;
|
|
220
|
+
/**
|
|
221
|
+
* Validate data against schema
|
|
222
|
+
*/
|
|
223
|
+
declare function validateAgainstSchema(data: unknown, schema: JTMLSchema): boolean;
|
|
224
|
+
declare const schemaManager: SchemaManager;
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Quick conversion utilities
|
|
228
|
+
*/
|
|
229
|
+
/**
|
|
230
|
+
* Convert JSON to JTML (one-liner)
|
|
231
|
+
*/
|
|
232
|
+
declare function jsonToJtml(json: unknown, schemaId?: string): string;
|
|
233
|
+
/**
|
|
234
|
+
* Convert JTML to JSON (one-liner)
|
|
235
|
+
*/
|
|
236
|
+
declare function jtmlToJson(jtml: string): unknown;
|
|
237
|
+
/**
|
|
238
|
+
* Convert JSON string to JTML string
|
|
239
|
+
*/
|
|
240
|
+
declare function convertJsonString(jsonStr: string, schemaId?: string): string;
|
|
241
|
+
/**
|
|
242
|
+
* Round-trip conversion test
|
|
243
|
+
*/
|
|
244
|
+
declare function roundTrip(data: unknown): {
|
|
245
|
+
success: boolean;
|
|
246
|
+
original: unknown;
|
|
247
|
+
recovered: unknown;
|
|
248
|
+
jtml: string;
|
|
249
|
+
};
|
|
250
|
+
declare const _default: {
|
|
251
|
+
encode: typeof encode;
|
|
252
|
+
decode: typeof decode;
|
|
253
|
+
jsonToJtml: typeof jsonToJtml;
|
|
254
|
+
jtmlToJson: typeof jtmlToJson;
|
|
255
|
+
convertJsonString: typeof convertJsonString;
|
|
256
|
+
roundTrip: typeof roundTrip;
|
|
257
|
+
schemaManager: SchemaManager;
|
|
258
|
+
estimateTokens: typeof estimateTokens;
|
|
259
|
+
compareTokens: typeof compareTokens;
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
export { type CostSavings, type DetailedTokenStats, type JTMLDecodeOptions, JTMLDecoder, type JTMLDocument, type JTMLEncodeOptions, JTMLEncoder, JTMLError, type JTMLField, type JTMLSchema, type JTMLType, type JTMLTypeInfo, type JTMLValue, SchemaManager, TYPE_MAP, type TokenStats, type TokenizerType, analyzeTokens, calculateEfficiency, compareTokens, convertJsonString, decode, decoder, _default as default, encode, encodeBatch, encoder, estimateCostSavings, estimateTokens, formatTokenStats, inferSchema, inferType, jsonToJtml, jtmlToJson, parseSchema, roundTrip, schemaManager, serializeSchema, validateAgainstSchema };
|