brevit 0.1.1 → 0.1.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 CHANGED
@@ -83,26 +83,26 @@ const optimized = await brevit.brevity(data);
83
83
  ### npm
84
84
 
85
85
  ```bash
86
- npm install brevit-js
86
+ npm install brevit
87
87
  ```
88
88
 
89
89
  ### yarn
90
90
 
91
91
  ```bash
92
- yarn add brevit-js
92
+ yarn add brevit
93
93
  ```
94
94
 
95
95
  ### pnpm
96
96
 
97
97
  ```bash
98
- pnpm add brevit-js
98
+ pnpm add brevit
99
99
  ```
100
100
 
101
101
  ### CDN (Browser)
102
102
 
103
103
  ```html
104
104
  <script type="module">
105
- import { BrevitClient, BrevitConfig, JsonOptimizationMode } from 'https://cdn.jsdelivr.net/npm/brevit-js@latest/src/brevit.js';
105
+ import { BrevitClient, BrevitConfig, JsonOptimizationMode } from 'https://cdn.jsdelivr.net/npm/brevit@latest/src/brevit.js';
106
106
  </script>
107
107
  ```
108
108
 
@@ -118,7 +118,7 @@ import {
118
118
  BrevitConfig,
119
119
  JsonOptimizationMode,
120
120
  type BrevitConfigOptions,
121
- } from 'brevit-js';
121
+ } from 'brevit';
122
122
 
123
123
  const config: BrevitConfigOptions = {
124
124
  jsonMode: JsonOptimizationMode.Flatten,
@@ -137,7 +137,7 @@ Brevit.js supports three main data types: **JSON objects/strings**, **text files
137
137
  #### Example 1.1: Simple JSON Object
138
138
 
139
139
  ```javascript
140
- import { BrevitClient, BrevitConfig, JsonOptimizationMode } from 'brevit-js';
140
+ import { BrevitClient, BrevitConfig, JsonOptimizationMode } from 'brevit';
141
141
 
142
142
  const brevit = new BrevitClient(new BrevitConfig({
143
143
  jsonMode: JsonOptimizationMode.Flatten
@@ -153,15 +153,59 @@ const data = {
153
153
 
154
154
  // Method 1: Automatic optimization (recommended)
155
155
  const optimized = await brevit.brevity(data);
156
- // Output:
157
- // user.name:John Doe
158
- // user.email:john@example.com
159
- // user.age:30
156
+ // Output (with abbreviations enabled by default):
157
+ // @u=user
158
+ // @u.name:John Doe
159
+ // @u.email:john@example.com
160
+ // @u.age:30
160
161
 
161
162
  // Method 2: Explicit optimization
162
163
  const explicit = await brevit.optimize(data);
163
164
  ```
164
165
 
166
+ #### Example 1.1a: Abbreviation Feature (New in v0.1.2)
167
+
168
+ Brevit automatically creates abbreviations for frequently repeated prefixes, reducing token usage by 10-25%:
169
+
170
+ ```javascript
171
+ import { BrevitClient, BrevitConfig, JsonOptimizationMode } from 'brevit';
172
+
173
+ const brevit = new BrevitClient(new BrevitConfig({
174
+ jsonMode: JsonOptimizationMode.Flatten,
175
+ enableAbbreviations: true, // Enabled by default
176
+ abbreviationThreshold: 2 // Minimum occurrences to abbreviate
177
+ }));
178
+
179
+ const data = {
180
+ user: {
181
+ name: "John Doe",
182
+ email: "john@example.com",
183
+ age: 30
184
+ },
185
+ order: {
186
+ id: "o-456",
187
+ status: "SHIPPED",
188
+ items: [
189
+ { sku: "A-88", quantity: 1 }
190
+ ]
191
+ }
192
+ };
193
+
194
+ const optimized = await brevit.brevity(data);
195
+ // Output with abbreviations:
196
+ // @u=user
197
+ // @o=order
198
+ // @u.name:John Doe
199
+ // @u.email:john@example.com
200
+ // @u.age:30
201
+ // @o.id:o-456
202
+ // @o.status:SHIPPED
203
+ // @o.items[1]{quantity,sku}:
204
+ // 1,A-88
205
+ ```
206
+
207
+ **Token Savings**: The abbreviation feature reduces tokens by replacing repeated prefixes like "user." and "order." with short aliases like "@u" and "@o", saving 10-25% on typical nested JSON structures.
208
+
165
209
  #### Example 1.2: JSON String
166
210
 
167
211
  ```javascript
@@ -614,7 +658,7 @@ import {
614
658
  type BrevitClientOptions,
615
659
  type TextOptimizerFunction,
616
660
  type ImageOptimizerFunction,
617
- } from 'brevit-js';
661
+ } from 'brevit';
618
662
  ```
619
663
 
620
664
  ### Type-Safe Configuration
@@ -1126,9 +1170,9 @@ Brevit is available in multiple languages:
1126
1170
 
1127
1171
  | Language | Package | Status |
1128
1172
  |----------|---------|--------|
1129
- | JavaScript | `brevit-js` | ✅ Stable (This) |
1130
- | C# (.NET) | `Brevit.NET` | ✅ Stable |
1131
- | Python | `brevit-py` | ✅ Stable |
1173
+ | JavaScript | `brevit` | ✅ Stable (This) |
1174
+ | C# (.NET) | `Brevit` | ✅ Stable |
1175
+ | Python | `brevit` | ✅ Stable |
1132
1176
 
1133
1177
  ## Full Specification
1134
1178
 
@@ -1228,7 +1272,7 @@ MIT License - see LICENSE file for details.
1228
1272
  ## Support
1229
1273
 
1230
1274
  - **Documentation**: [https://brevit.dev/docs](https://brevit.dev/docs)
1231
- - **Issues**: [https://github.com/brevit/brevit-js/issues](https://github.com/brevit/brevit-js/issues)
1275
+ - **Issues**: [https://github.com/JavianDev/Brevit.js/issues](https://github.com/JavianDev/Brevit.js/issues)
1232
1276
  - **Email**: support@javianpicardo.com
1233
1277
 
1234
1278
  ## Version History
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brevit",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "A high-performance JavaScript library for semantically compressing and optimizing data before sending it to a Large Language Model (LLM).",
5
5
  "main": "src/brevit.js",
6
6
  "types": "src/brevit.d.ts",
package/src/brevit.d.ts CHANGED
@@ -81,6 +81,18 @@ export interface BrevitConfigOptions {
81
81
  * @default 500
82
82
  */
83
83
  longTextThreshold?: number;
84
+
85
+ /**
86
+ * Enable abbreviation feature for frequently repeated key prefixes
87
+ * @default true
88
+ */
89
+ enableAbbreviations?: boolean;
90
+
91
+ /**
92
+ * Minimum number of occurrences required to create an abbreviation
93
+ * @default 2
94
+ */
95
+ abbreviationThreshold?: number;
84
96
  }
85
97
 
86
98
  /**
@@ -112,6 +124,16 @@ export class BrevitConfig {
112
124
  */
113
125
  longTextThreshold: number;
114
126
 
127
+ /**
128
+ * Enable abbreviation feature
129
+ */
130
+ enableAbbreviations: boolean;
131
+
132
+ /**
133
+ * Abbreviation threshold
134
+ */
135
+ abbreviationThreshold: number;
136
+
115
137
  /**
116
138
  * Creates a new BrevitConfig instance
117
139
  * @param options Configuration options
package/src/brevit.js CHANGED
@@ -43,6 +43,8 @@ export class BrevitConfig {
43
43
  * @param {string} options.imageMode - Strategy for Image optimization.
44
44
  * @param {string[]} options.jsonPathsToKeep - Paths to keep for Filter mode.
45
45
  * @param {number} options.longTextThreshold - Char count to trigger text optimization.
46
+ * @param {boolean} options.enableAbbreviations - Enable abbreviation feature for repeated prefixes.
47
+ * @param {number} options.abbreviationThreshold - Minimum occurrences to create abbreviation.
46
48
  */
47
49
  constructor({
48
50
  jsonMode = JsonOptimizationMode.Flatten,
@@ -50,12 +52,16 @@ export class BrevitConfig {
50
52
  imageMode = ImageOptimizationMode.Ocr,
51
53
  jsonPathsToKeep = [],
52
54
  longTextThreshold = 500,
55
+ enableAbbreviations = true,
56
+ abbreviationThreshold = 2,
53
57
  } = {}) {
54
58
  this.jsonMode = jsonMode;
55
59
  this.textMode = textMode;
56
60
  this.imageMode = imageMode;
57
61
  this.jsonPathsToKeep = jsonPathsToKeep;
58
62
  this.longTextThreshold = longTextThreshold;
63
+ this.enableAbbreviations = enableAbbreviations;
64
+ this.abbreviationThreshold = abbreviationThreshold;
59
65
  }
60
66
  }
61
67
 
@@ -220,7 +226,131 @@ export class BrevitClient {
220
226
  }
221
227
 
222
228
  /**
223
- * Flattens a JS object into a token-efficient string with tabular optimization.
229
+ * Generates abbreviations for frequently repeated prefixes.
230
+ * @param {Array<string>} paths - Array of flattened paths
231
+ * @returns {Object} Object with abbreviation map and definitions array
232
+ * @private
233
+ */
234
+ _generateAbbreviations(paths) {
235
+ if (!this._config.enableAbbreviations) {
236
+ return { map: new Map(), definitions: [] };
237
+ }
238
+
239
+ // Count prefix frequencies
240
+ const prefixCounts = new Map();
241
+
242
+ paths.forEach(path => {
243
+ // Extract all prefixes (e.g., "user", "user.name", "order.items")
244
+ const parts = path.split('.');
245
+ for (let i = 1; i < parts.length; i++) {
246
+ const prefix = parts.slice(0, i).join('.');
247
+ prefixCounts.set(prefix, (prefixCounts.get(prefix) || 0) + 1);
248
+ }
249
+ });
250
+
251
+ // Filter prefixes that meet threshold
252
+ const frequentPrefixes = Array.from(prefixCounts.entries())
253
+ .filter(([prefix, count]) => count >= this._config.abbreviationThreshold)
254
+ .sort((a, b) => {
255
+ // Sort by: 1) count (desc), 2) length (asc) - prefer shorter, more frequent
256
+ if (b[1] !== a[1]) return b[1] - a[1];
257
+ return a[0].length - b[0].length;
258
+ });
259
+
260
+ // Generate abbreviations
261
+ const abbreviationMap = new Map();
262
+ const definitions = [];
263
+ let abbrCounter = 0;
264
+ const usedAbbrs = new Set();
265
+
266
+ frequentPrefixes.forEach(([prefix, count]) => {
267
+ // Calculate savings: (prefix.length - abbr.length) * count
268
+ // Only abbreviate if it saves tokens
269
+ const abbr = this._generateAbbreviation(prefix, abbrCounter, usedAbbrs);
270
+ const definitionCost = prefix.length + abbr.length + 3; // "@x=prefix"
271
+ const savings = (prefix.length - abbr.length - 1) * count; // -1 for "@"
272
+
273
+ // Only create abbreviation if it saves tokens (accounting for definition)
274
+ if (savings > definitionCost) {
275
+ abbreviationMap.set(prefix, abbr);
276
+ definitions.push(`@${abbr}=${prefix}`);
277
+ abbrCounter++;
278
+ }
279
+ });
280
+
281
+ return { map: abbreviationMap, definitions };
282
+ }
283
+
284
+ /**
285
+ * Generates a short abbreviation for a prefix.
286
+ * @param {string} prefix - The prefix to abbreviate
287
+ * @param {number} counter - Counter for fallback abbreviations
288
+ * @param {Set<string>} usedAbbrs - Set of already used abbreviations
289
+ * @returns {string} The abbreviation
290
+ * @private
291
+ */
292
+ _generateAbbreviation(prefix, counter, usedAbbrs) {
293
+ // Strategy 1: Use first letter if available and not used
294
+ const firstLetter = prefix.split('.')[0][0].toLowerCase();
295
+ if (!usedAbbrs.has(firstLetter)) {
296
+ usedAbbrs.add(firstLetter);
297
+ return firstLetter;
298
+ }
299
+
300
+ // Strategy 2: Use first letter of each part (e.g., "order.items" -> "oi")
301
+ const parts = prefix.split('.');
302
+ if (parts.length > 1) {
303
+ const multiLetter = parts.map(p => p[0]).join('').toLowerCase();
304
+ if (!usedAbbrs.has(multiLetter) && multiLetter.length <= 3) {
305
+ usedAbbrs.add(multiLetter);
306
+ return multiLetter;
307
+ }
308
+ }
309
+
310
+ // Strategy 3: Use counter-based abbreviation (a, b, c, ..., z, aa, ab, ...)
311
+ let abbr = '';
312
+ let num = counter;
313
+ do {
314
+ abbr = String.fromCharCode(97 + (num % 26)) + abbr; // 97 = 'a'
315
+ num = Math.floor(num / 26) - 1;
316
+ } while (num >= 0);
317
+
318
+ usedAbbrs.add(abbr);
319
+ return abbr;
320
+ }
321
+
322
+ /**
323
+ * Applies abbreviations to a path string.
324
+ * @param {string} path - The path to abbreviate
325
+ * @param {Map<string, string>} abbreviationMap - Map of prefix to abbreviation
326
+ * @returns {string} The abbreviated path
327
+ * @private
328
+ */
329
+ _applyAbbreviations(path, abbreviationMap) {
330
+ if (!this._config.enableAbbreviations || abbreviationMap.size === 0) {
331
+ return path;
332
+ }
333
+
334
+ // Find the longest matching prefix
335
+ let bestMatch = '';
336
+ let bestAbbr = '';
337
+
338
+ for (const [prefix, abbr] of abbreviationMap.entries()) {
339
+ if (path.startsWith(prefix + '.') && prefix.length > bestMatch.length) {
340
+ bestMatch = prefix;
341
+ bestAbbr = abbr;
342
+ }
343
+ }
344
+
345
+ if (bestMatch) {
346
+ return `@${bestAbbr}.${path.substring(bestMatch.length + 1)}`;
347
+ }
348
+
349
+ return path;
350
+ }
351
+
352
+ /**
353
+ * Flattens a JS object into a token-efficient string with tabular optimization and abbreviations.
224
354
  * @param {object} obj - The object to flatten.
225
355
  * @returns {string} The flattened string.
226
356
  * @private
@@ -228,7 +358,57 @@ export class BrevitClient {
228
358
  _flattenObject(obj) {
229
359
  const output = [];
230
360
  this._flatten(obj, '', output);
231
- return output.join('\n');
361
+
362
+ // Extract paths from output (before values)
363
+ const paths = output.map(line => {
364
+ const colonIndex = line.indexOf(':');
365
+ if (colonIndex > 0) {
366
+ const pathPart = line.substring(0, colonIndex);
367
+ // Handle tabular arrays: "key[count]{fields}:"
368
+ const bracketIndex = pathPart.indexOf('[');
369
+ if (bracketIndex > 0) {
370
+ return pathPart.substring(0, bracketIndex);
371
+ }
372
+ return pathPart;
373
+ }
374
+ return line.split(':')[0];
375
+ });
376
+
377
+ // Generate abbreviations
378
+ const { map: abbreviationMap, definitions } = this._generateAbbreviations(paths);
379
+
380
+ // Apply abbreviations to output
381
+ const abbreviatedOutput = output.map(line => {
382
+ // Handle different line formats:
383
+ // 1. "key:value"
384
+ // 2. "key[count]:value1,value2"
385
+ // 3. "key[count]{fields}:\nrow1\nrow2"
386
+
387
+ const colonIndex = line.indexOf(':');
388
+ if (colonIndex === -1) return line;
389
+
390
+ const pathPart = line.substring(0, colonIndex);
391
+ const valuePart = line.substring(colonIndex);
392
+
393
+ // Handle tabular arrays - abbreviate the base path
394
+ const bracketIndex = pathPart.indexOf('[');
395
+ if (bracketIndex > 0) {
396
+ const basePath = pathPart.substring(0, bracketIndex);
397
+ const rest = pathPart.substring(bracketIndex);
398
+ const abbreviatedBase = this._applyAbbreviations(basePath, abbreviationMap);
399
+ return abbreviatedBase + rest + valuePart;
400
+ }
401
+
402
+ const abbreviatedPath = this._applyAbbreviations(pathPart, abbreviationMap);
403
+ return abbreviatedPath + valuePart;
404
+ });
405
+
406
+ // Combine: definitions first, then abbreviated output
407
+ if (definitions.length > 0) {
408
+ return definitions.join('\n') + '\n' + abbreviatedOutput.join('\n');
409
+ }
410
+
411
+ return abbreviatedOutput.join('\n');
232
412
  }
233
413
 
234
414
  /**