@shrkcrft/compress 0.1.0-alpha.16 → 0.1.0-alpha.17
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/dist/compress-content.d.ts.map +1 -1
- package/dist/compress-content.js +11 -0
- package/dist/result/compress-options.d.ts +7 -0
- package/dist/result/compress-options.d.ts.map +1 -1
- package/dist/table/compact-object-array.d.ts.map +1 -1
- package/dist/table/compact-object-array.js +4 -1
- package/dist/table/object-map.d.ts.map +1 -1
- package/dist/table/object-map.js +3 -1
- package/dist/text/finalize.d.ts.map +1 -1
- package/dist/text/finalize.js +20 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compress-content.d.ts","sourceRoot":"","sources":["../src/compress-content.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"compress-content.d.ts","sourceRoot":"","sources":["../src/compress-content.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAYrE;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,gBAAqB,GAAG,kBAAkB,CAS7F"}
|
package/dist/compress-content.js
CHANGED
|
@@ -3,6 +3,7 @@ import { detectContentType } from "./content/detect-content-type.js";
|
|
|
3
3
|
import { segmentContent, isRichSegmentType } from "./content/segment.js";
|
|
4
4
|
import { ECompressionStrategy } from "./result/compression-strategy.js";
|
|
5
5
|
import { measureSavings } from "./tokens/estimate-tokens.js";
|
|
6
|
+
import { passthroughResult } from "./text/finalize.js";
|
|
6
7
|
import { compressJson } from "./json/compress-json.js";
|
|
7
8
|
import { compressLog } from "./text/compress-log.js";
|
|
8
9
|
import { compressSearch } from "./text/compress-search.js";
|
|
@@ -18,6 +19,16 @@ import { compressCode } from "./code/compress-code.js";
|
|
|
18
19
|
* and options always yield the same output.
|
|
19
20
|
*/
|
|
20
21
|
export function compressContent(text, opts = {}) {
|
|
22
|
+
const result = routeCompressContent(text, opts);
|
|
23
|
+
// `lossless` is a hard guard applied at the single entry point so it catches
|
|
24
|
+
// every lossy path (text elision, JSON row-sampling, mixed) uniformly: a
|
|
25
|
+
// result that drops information is replaced by the verbatim original.
|
|
26
|
+
if (opts.lossless && result.lossy) {
|
|
27
|
+
return passthroughResult(text, result.contentType, 'lossless requested — lossy reduction skipped');
|
|
28
|
+
}
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
function routeCompressContent(text, opts) {
|
|
21
32
|
const type = opts.contentType ?? detectContentType(text);
|
|
22
33
|
switch (type) {
|
|
23
34
|
case EContentType.JsonArray:
|
|
@@ -14,6 +14,13 @@ export interface ICompressOptions {
|
|
|
14
14
|
contentType?: EContentType;
|
|
15
15
|
/** Soft cap on retained items/lines/matches/hunks (compressor-specific). */
|
|
16
16
|
maxItems?: number;
|
|
17
|
+
/**
|
|
18
|
+
* Refuse any lossy reduction: a pass that would drop lines/rows/hunks
|
|
19
|
+
* returns the input untouched (passthrough) instead. Provably-lossless
|
|
20
|
+
* transforms (JSON columnar, dedup that round-trips) still apply. Lets a
|
|
21
|
+
* caller demand "shrink only if fully reconstructable from the output alone".
|
|
22
|
+
*/
|
|
23
|
+
lossless?: boolean;
|
|
17
24
|
/** Below this many lines a lossy text pass returns the input untouched. */
|
|
18
25
|
minLines?: number;
|
|
19
26
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compress-options.d.ts","sourceRoot":"","sources":["../../src/result/compress-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
|
|
1
|
+
{"version":3,"file":"compress-options.d.ts","sourceRoot":"","sources":["../../src/result/compress-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compact-object-array.d.ts","sourceRoot":"","sources":["../../src/table/compact-object-array.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAqC9D;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"compact-object-array.d.ts","sourceRoot":"","sources":["../../src/table/compact-object-array.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAqC9D;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAAI,CA2C1E"}
|
|
@@ -63,7 +63,10 @@ export function compactObjectArray(items) {
|
|
|
63
63
|
const row = [];
|
|
64
64
|
for (let c = 0; c < colNames.length; c += 1) {
|
|
65
65
|
const key = colNames[c];
|
|
66
|
-
|
|
66
|
+
// `key in item` walks the prototype chain, so a column named after an
|
|
67
|
+
// Object.prototype member (`toString`, `hasOwnProperty`, …) would read the
|
|
68
|
+
// inherited member as a cell value. Own-property check keeps it lossless.
|
|
69
|
+
const present = Object.prototype.hasOwnProperty.call(item, key) && item[key] !== undefined;
|
|
67
70
|
if (!present) {
|
|
68
71
|
absent.push([r, c]);
|
|
69
72
|
row.push(null);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"object-map.d.ts","sourceRoot":"","sources":["../../src/table/object-map.ts"],"names":[],"mappings":"AAyBA,sDAAsD;AACtD,MAAM,WAAW,UAAU;IACzB,uDAAuD;IACvD,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,qEAAqE;IACrE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,gFAAgF;IAChF,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC;IAClB,yFAAyF;IACzF,MAAM,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACjC;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"object-map.d.ts","sourceRoot":"","sources":["../../src/table/object-map.ts"],"names":[],"mappings":"AAyBA,sDAAsD;AACtD,MAAM,WAAW,UAAU;IACzB,uDAAuD;IACvD,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,qEAAqE;IACrE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,gFAAgF;IAChF,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC;IAClB,yFAAyF;IACzF,MAAM,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACjC;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,CAqClE;AAED,+DAA+D;AAC/D,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI;IAAE,KAAK,EAAE,UAAU,CAAA;CAAE,CAU1E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAmB9E"}
|
package/dist/table/object-map.js
CHANGED
|
@@ -46,7 +46,9 @@ export function compactObjectMap(value) {
|
|
|
46
46
|
const row = [];
|
|
47
47
|
for (let c = 0; c < cols.length; c += 1) {
|
|
48
48
|
const key = cols[c];
|
|
49
|
-
|
|
49
|
+
// Own-property check (not `key in entry`, which walks the prototype chain)
|
|
50
|
+
// so a column named after an Object.prototype member isn't read as a value.
|
|
51
|
+
if (Object.prototype.hasOwnProperty.call(entry, key) && entry[key] !== undefined) {
|
|
50
52
|
row.push(entry[key]);
|
|
51
53
|
}
|
|
52
54
|
else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"finalize.d.ts","sourceRoot":"","sources":["../../src/text/finalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAItE,0DAA0D;AAC1D,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,YAAY,EACzB,IAAI,SAAmC,GACtC,kBAAkB,CASpB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,YAAY,CAAC;IAC1B,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,kBAAkB,
|
|
1
|
+
{"version":3,"file":"finalize.d.ts","sourceRoot":"","sources":["../../src/text/finalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAItE,0DAA0D;AAC1D,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,YAAY,EACzB,IAAI,SAAmC,GACtC,kBAAkB,CASpB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,YAAY,CAAC;IAC1B,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,kBAAkB,CAsCrB"}
|
package/dist/text/finalize.js
CHANGED
|
@@ -30,13 +30,19 @@ export function finalizeLossy(params) {
|
|
|
30
30
|
let key;
|
|
31
31
|
if (opts.store) {
|
|
32
32
|
key = opts.store.put(original);
|
|
33
|
+
// Make inline `… N lines omitted` placeholders self-describing: a reader
|
|
34
|
+
// who only sees a clipped middle of the output otherwise can't tell the
|
|
35
|
+
// dropped detail is retrievable. Annotate each with the recovery key.
|
|
36
|
+
compressed = annotateElisionMarkers(body, key);
|
|
33
37
|
// Skip the trailing marker when the body already references THIS key inline
|
|
34
38
|
// (e.g. compressLog's per-drop elision hints) — no need to repeat it. A
|
|
35
39
|
// different inline key (e.g. a diff's per-section keys) still gets the
|
|
36
40
|
// whole-blob marker appended. The marker carries only the key: the human
|
|
37
41
|
// `note` is shipped separately in the result, so repeating it on the wire
|
|
38
42
|
// would just cost tokens.
|
|
39
|
-
compressed =
|
|
43
|
+
compressed = compressed.includes(`<<ccr:${key}`)
|
|
44
|
+
? compressed
|
|
45
|
+
: `${compressed}\n${formatCcrMarker(key)}`;
|
|
40
46
|
}
|
|
41
47
|
const savings = measureSavings(original, compressed, contentType);
|
|
42
48
|
if (savings.after >= savings.before) {
|
|
@@ -52,3 +58,16 @@ export function finalizeLossy(params) {
|
|
|
52
58
|
note,
|
|
53
59
|
};
|
|
54
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Append the recovery key to each `… N line(s) omitted` placeholder produced by
|
|
63
|
+
* {@link elide} (used by the markdown/search/lines compressors), so a clipped
|
|
64
|
+
* view still advertises that the dropped detail is retrievable via `shrk expand`.
|
|
65
|
+
* Deterministic; leaves bodies without such markers (logs/diffs use their own
|
|
66
|
+
* keyed hints) untouched.
|
|
67
|
+
*/
|
|
68
|
+
function annotateElisionMarkers(body, key) {
|
|
69
|
+
// Match ONLY a standalone-line `… N lines omitted` (what elide() emits, on its
|
|
70
|
+
// own line). The lookahead for end-of-line excludes compressLog's inline-keyed
|
|
71
|
+
// markers (`… N lines omitted → <<ccr:KEY>>`), which already carry the key.
|
|
72
|
+
return body.replace(/(… \d+ lines? omitted)(?=\n|$)/g, (marker) => `${marker} (shrk expand ${key})`);
|
|
73
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shrkcrft/compress",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.17",
|
|
4
4
|
"description": "SharkCraft deterministic context-compression engine: content routing, lossless columnar/table compaction, log/search/diff line reduction, and reversible Compress-Cache-Retrieve (CCR). No model inside — every transform is a pure function of its input.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "SharkCraft contributors",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@shrkcrft/core": "^0.1.0-alpha.
|
|
47
|
+
"@shrkcrft/core": "^0.1.0-alpha.17"
|
|
48
48
|
},
|
|
49
49
|
"publishConfig": {
|
|
50
50
|
"access": "public"
|