@hy-sde-org/dsh-zstd-frame 0.1.1-rc.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/LICENSE +21 -0
- package/README.md +62 -0
- package/dist/index.d.ts +85 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +143 -0
- package/dist/index.js.map +1 -0
- package/dist/invariant.d.ts +16 -0
- package/dist/invariant.d.ts.map +1 -0
- package/dist/invariant.js +22 -0
- package/dist/invariant.js.map +1 -0
- package/dist/zstd-private-decoder.d.ts +33 -0
- package/dist/zstd-private-decoder.d.ts.map +1 -0
- package/dist/zstd-private-decoder.js +142 -0
- package/dist/zstd-private-decoder.js.map +1 -0
- package/dist/zstd-public-decoder.d.ts +15 -0
- package/dist/zstd-public-decoder.d.ts.map +1 -0
- package/dist/zstd-public-decoder.js +40 -0
- package/dist/zstd-public-decoder.js.map +1 -0
- package/package.json +63 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 hy-sde
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# @hy-sde-org/dsh-zstd-frame
|
|
2
|
+
|
|
3
|
+
Zstandard frame primitives shared by the DeepSeek Harness session
|
|
4
|
+
persistence backend (`session.jsonl.zstd`) and the project memory bank
|
|
5
|
+
(`bank.jsonl.zstd`). Both store append-only, checksummed, per-batch zstd
|
|
6
|
+
frames; this package owns the structural scan, the one-shot compress /
|
|
7
|
+
decompress API with checksum, torn-frame recovery, and the interchangeable
|
|
8
|
+
multi-frame decoders, so consumers never reimplement frame layout or
|
|
9
|
+
Node-private decoder lifecycle.
|
|
10
|
+
|
|
11
|
+
Published standalone as `@hy-sde-org/dsh-zstd-frame`; it mirrors
|
|
12
|
+
`@deepseek-ai/dsh-zstd-frame` in the [hy-sde deepseek-harness fork](https://github.com/hy-sde/deepseek-harness).
|
|
13
|
+
|
|
14
|
+
Backed entirely by `node:zlib` — no native module, works in-process.
|
|
15
|
+
|
|
16
|
+
## API
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import {
|
|
20
|
+
compressZstdFrame,
|
|
21
|
+
decompressZstdFrame,
|
|
22
|
+
decompressZstdFrameSync,
|
|
23
|
+
decompressZstdPrefix,
|
|
24
|
+
scanZstdFrames,
|
|
25
|
+
createZstdFrameDecoder,
|
|
26
|
+
} from '@hy-sde-org/dsh-zstd-frame'
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
- `scanZstdFrames(buffer, maxFrames?)` → `{ frames: ZstdFrameRange[], tornStart? }` —
|
|
30
|
+
locate complete frames without decompressing their blocks; EOF inside the
|
|
31
|
+
final frame returns its start for repair.
|
|
32
|
+
- `compressZstdFrame(input)` — one independently decodable, checksummed frame.
|
|
33
|
+
- `decompressZstdFrame(input, maxOutput?)` / `decompressZstdFrameSync(...)` —
|
|
34
|
+
one-frame decompression with optional plaintext bound.
|
|
35
|
+
- `decompressZstdPrefix(input)` — recover available plaintext from a
|
|
36
|
+
structurally incomplete final frame.
|
|
37
|
+
- `createZstdFrameDecoder()` — `NodePrivateZstdFrameDecoder` when the running
|
|
38
|
+
Node shape is compatible, else `PublicZstdFrameDecoder`; both implement the
|
|
39
|
+
common `ZstdFrameDecoder` interface (`decode(source, frames)` generator +
|
|
40
|
+
`close()`).
|
|
41
|
+
|
|
42
|
+
## Known Limitations and Deferred Work
|
|
43
|
+
|
|
44
|
+
- The private-handle decoder (`NodePrivateZstdFrameDecoder`) depends on the
|
|
45
|
+
private `zlib._handle.writeSync` shape, which the public Node API does not
|
|
46
|
+
document; the decoder feature-probes at load and falls back to the
|
|
47
|
+
one-shot-based `PublicZstdFrameDecoder` when the shape is incompatible, so
|
|
48
|
+
correctness never depends on private internals.
|
|
49
|
+
- No streaming incremental compressor; frames are written whole per batch.
|
|
50
|
+
- Only *checksummed* frames are produced by `compressZstdFrame`
|
|
51
|
+
(`ZSTD_c_checksumFlag`), and `decompressZstdPrefix` deliberately suppresses
|
|
52
|
+
final-frame/checksum completion — callers must establish the torn boundary
|
|
53
|
+
themselves before using it.
|
|
54
|
+
|
|
55
|
+
The optional `./invariant` entry registers the package into a Cordis host's
|
|
56
|
+
`ctx.invariants` service (no-op) and needs `@deepseek-ai/cordis` +
|
|
57
|
+
`@deepseek-ai/dsh-invariants` peers only when you use that entry.
|
|
58
|
+
|
|
59
|
+
## License
|
|
60
|
+
|
|
61
|
+
MIT. Derived from the DeepSeek Harness codebase; see
|
|
62
|
+
`THIRD-PARTY-NOTICES.md` for provenance.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zstandard frame primitives shared by the JSONL session persistence backend
|
|
3
|
+
* and the project memory bank. Both store append-only, checksummed, per-batch
|
|
4
|
+
* zstd frames; this package owns the structural scan, the one-shot compress /
|
|
5
|
+
* decompress API, torn-frame recovery, and the interchangeable multi-frame
|
|
6
|
+
* decoders, so consumers never reimplement frame layout or Node-private
|
|
7
|
+
* decoder lifecycle.
|
|
8
|
+
*
|
|
9
|
+
* Backed entirely by `node:zlib` — no native module, works in-process.
|
|
10
|
+
* @module @hy-sde-org/dsh-zstd-frame
|
|
11
|
+
*/
|
|
12
|
+
export { NodePrivateZstdFrameDecoder } from './zstd-private-decoder.ts';
|
|
13
|
+
export { PublicZstdFrameDecoder } from './zstd-public-decoder.ts';
|
|
14
|
+
/** Byte range occupied by one structurally complete Zstandard frame. */
|
|
15
|
+
export interface ZstdFrameRange {
|
|
16
|
+
/** Inclusive frame start. */
|
|
17
|
+
start: number;
|
|
18
|
+
/** Exclusive frame end. */
|
|
19
|
+
end: number;
|
|
20
|
+
}
|
|
21
|
+
/** Structural scan result for a concatenated Zstandard stream. */
|
|
22
|
+
export interface ZstdFrameScan {
|
|
23
|
+
/** Complete frames in file order. */
|
|
24
|
+
frames: ZstdFrameRange[];
|
|
25
|
+
/** Start of an incomplete final frame, when EOF interrupts one. */
|
|
26
|
+
tornStart?: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Locate complete frames without decompressing their blocks. Invalid complete
|
|
30
|
+
* structure rejects; EOF inside the final frame returns its start for repair.
|
|
31
|
+
* @param buffer - complete bytes currently present in the session artifact.
|
|
32
|
+
* @param maxFrames - optional complete-frame limit for metadata-only readers.
|
|
33
|
+
* @returns complete frame ranges and an optional incomplete-final-frame start.
|
|
34
|
+
*/
|
|
35
|
+
export declare function scanZstdFrames(buffer: Buffer, maxFrames?: number): ZstdFrameScan;
|
|
36
|
+
/**
|
|
37
|
+
* Compress one independently decodable, checksummed Zstandard frame.
|
|
38
|
+
* @param input - JSONL bytes for a header or durable event batch.
|
|
39
|
+
* @returns the complete encoded frame.
|
|
40
|
+
*/
|
|
41
|
+
export declare function compressZstdFrame(input: Buffer | string): Promise<Buffer>;
|
|
42
|
+
/**
|
|
43
|
+
* Decompress one complete frame and validate its checksum.
|
|
44
|
+
* @param input - one structurally complete Zstandard frame.
|
|
45
|
+
* @param maxOutput - optional plaintext bound; oversized frames reject with the Node error.
|
|
46
|
+
* @returns the frame plaintext.
|
|
47
|
+
*/
|
|
48
|
+
export declare function decompressZstdFrame(input: Buffer, maxOutput?: number): Promise<Buffer>;
|
|
49
|
+
/**
|
|
50
|
+
* Synchronous one-frame decompression with an optional plaintext bound — for
|
|
51
|
+
* sync-only readers (the `memory:project` prompt section reads bank files with
|
|
52
|
+
* `readFileSync`). Keeps checksum validation identical to the async path.
|
|
53
|
+
* @param input - one structurally complete Zstandard frame.
|
|
54
|
+
* @param maxOutput - optional plaintext bound; oversized frames reject.
|
|
55
|
+
* @returns the frame plaintext.
|
|
56
|
+
*/
|
|
57
|
+
export declare function decompressZstdFrameSync(input: Buffer, maxOutput?: number): Buffer;
|
|
58
|
+
/** Common lifecycle for interchangeable synchronous multi-frame decoders. */
|
|
59
|
+
export interface ZstdFrameDecoder {
|
|
60
|
+
/**
|
|
61
|
+
* Decode and checksum complete frames in source order. Each yielded buffer
|
|
62
|
+
* remains valid only until the iterator advances to the next frame.
|
|
63
|
+
* @param source - concatenated Zstandard frame bytes.
|
|
64
|
+
* @param frames - structurally complete ranges within `source`.
|
|
65
|
+
* @returns one plaintext buffer per frame.
|
|
66
|
+
*/
|
|
67
|
+
decode(source: Buffer, frames: readonly ZstdFrameRange[]): Generator<Buffer, void, void>;
|
|
68
|
+
/** Release decoder-owned resources; repeated calls are harmless. */
|
|
69
|
+
close(): void;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Select the shared private decoder when the running Node 22/24/26 shape is
|
|
73
|
+
* compatible, otherwise preserve correctness with the public one-shot API.
|
|
74
|
+
* @returns a synchronous decoder with an implementation-independent lifecycle.
|
|
75
|
+
*/
|
|
76
|
+
export declare function createZstdFrameDecoder(): ZstdFrameDecoder;
|
|
77
|
+
/**
|
|
78
|
+
* Recover available plaintext from a structurally incomplete final frame.
|
|
79
|
+
* `ZSTD_e_flush` deliberately suppresses final-frame and checksum completion;
|
|
80
|
+
* callers must establish the torn frame boundary before using this helper.
|
|
81
|
+
* @param input - available bytes from a known incomplete Zstandard frame.
|
|
82
|
+
* @returns plaintext produced from the available input.
|
|
83
|
+
*/
|
|
84
|
+
export declare function decompressZstdPrefix(input: Buffer): Promise<Buffer>;
|
|
85
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AASH,OAAO,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAA;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAA;AAYjE,wEAAwE;AACxE,MAAM,WAAW,cAAc;IAC7B,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,2BAA2B;IAC3B,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,kEAAkE;AAClE,MAAM,WAAW,aAAa;IAC5B,qCAAqC;IACrC,MAAM,EAAE,cAAc,EAAE,CAAA;IACxB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,SAA2B,GAAG,aAAa,CAwDlG;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE/E;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG5F;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAGjF;AAED,6EAA6E;AAC7E,MAAM,WAAW,gBAAgB;IAC/B;;;;;;OAMG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,cAAc,EAAE,GAAG,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;IACxF,oEAAoE;IACpE,KAAK,IAAI,IAAI,CAAA;CACd;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,gBAAgB,CAEzD;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEzE"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zstandard frame primitives shared by the JSONL session persistence backend
|
|
3
|
+
* and the project memory bank. Both store append-only, checksummed, per-batch
|
|
4
|
+
* zstd frames; this package owns the structural scan, the one-shot compress /
|
|
5
|
+
* decompress API, torn-frame recovery, and the interchangeable multi-frame
|
|
6
|
+
* decoders, so consumers never reimplement frame layout or Node-private
|
|
7
|
+
* decoder lifecycle.
|
|
8
|
+
*
|
|
9
|
+
* Backed entirely by `node:zlib` — no native module, works in-process.
|
|
10
|
+
* @module @hy-sde-org/dsh-zstd-frame
|
|
11
|
+
*/
|
|
12
|
+
import { constants, zstdCompress, zstdDecompress, zstdDecompressSync, } from 'node:zlib';
|
|
13
|
+
import { promisify } from 'node:util';
|
|
14
|
+
import { NodePrivateZstdFrameDecoder } from "./zstd-private-decoder.js";
|
|
15
|
+
import { PublicZstdFrameDecoder } from "./zstd-public-decoder.js";
|
|
16
|
+
export { NodePrivateZstdFrameDecoder } from "./zstd-private-decoder.js";
|
|
17
|
+
export { PublicZstdFrameDecoder } from "./zstd-public-decoder.js";
|
|
18
|
+
const ZSTD_MAGIC = 0xFD2FB528;
|
|
19
|
+
const zstdCompressAsync = promisify(zstdCompress);
|
|
20
|
+
const zstdDecompressAsync = promisify(zstdDecompress);
|
|
21
|
+
const CHECKSUM_OPTIONS = {
|
|
22
|
+
params: { [constants.ZSTD_c_checksumFlag]: 1 },
|
|
23
|
+
};
|
|
24
|
+
const INCOMPLETE_FRAME_OPTIONS = {
|
|
25
|
+
finishFlush: constants.ZSTD_e_flush,
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Locate complete frames without decompressing their blocks. Invalid complete
|
|
29
|
+
* structure rejects; EOF inside the final frame returns its start for repair.
|
|
30
|
+
* @param buffer - complete bytes currently present in the session artifact.
|
|
31
|
+
* @param maxFrames - optional complete-frame limit for metadata-only readers.
|
|
32
|
+
* @returns complete frame ranges and an optional incomplete-final-frame start.
|
|
33
|
+
*/
|
|
34
|
+
export function scanZstdFrames(buffer, maxFrames = Number.POSITIVE_INFINITY) {
|
|
35
|
+
const frames = [];
|
|
36
|
+
let offset = 0;
|
|
37
|
+
while (offset < buffer.length) {
|
|
38
|
+
const start = offset;
|
|
39
|
+
if (buffer.length - offset < 4)
|
|
40
|
+
return { frames, tornStart: start };
|
|
41
|
+
if (buffer.readUInt32LE(offset) !== ZSTD_MAGIC) {
|
|
42
|
+
throw new Error(`corrupt Zstandard stream: invalid frame magic at byte ${offset}`);
|
|
43
|
+
}
|
|
44
|
+
offset += 4;
|
|
45
|
+
if (offset === buffer.length)
|
|
46
|
+
return { frames, tornStart: start };
|
|
47
|
+
const descriptor = buffer.readUInt8(offset);
|
|
48
|
+
offset += 1;
|
|
49
|
+
if ((descriptor & 0x18) !== 0) {
|
|
50
|
+
throw new Error(`corrupt Zstandard stream: reserved frame-header bit at byte ${offset - 1}`);
|
|
51
|
+
}
|
|
52
|
+
const contentSizeFlag = descriptor >>> 6;
|
|
53
|
+
const singleSegment = (descriptor & 0x20) !== 0;
|
|
54
|
+
const checksum = (descriptor & 0x04) !== 0;
|
|
55
|
+
const dictionaryFlag = descriptor & 0x03;
|
|
56
|
+
const dictionaryBytes = dictionaryFlag === 3 ? 4 : dictionaryFlag;
|
|
57
|
+
const contentSizeBytes = contentSizeFlag === 0
|
|
58
|
+
? (singleSegment ? 1 : 0)
|
|
59
|
+
: 1 << contentSizeFlag;
|
|
60
|
+
const remainingHeaderBytes = (singleSegment ? 0 : 1) + dictionaryBytes + contentSizeBytes;
|
|
61
|
+
if (buffer.length - offset < remainingHeaderBytes)
|
|
62
|
+
return { frames, tornStart: start };
|
|
63
|
+
offset += remainingHeaderBytes;
|
|
64
|
+
for (;;) {
|
|
65
|
+
if (buffer.length - offset < 3)
|
|
66
|
+
return { frames, tornStart: start };
|
|
67
|
+
const blockHeader = buffer.readUIntLE(offset, 3);
|
|
68
|
+
offset += 3;
|
|
69
|
+
const lastBlock = (blockHeader & 1) !== 0;
|
|
70
|
+
const blockType = (blockHeader >>> 1) & 0x03;
|
|
71
|
+
const blockSize = blockHeader >>> 3;
|
|
72
|
+
if (blockType === 0x03) {
|
|
73
|
+
throw new Error(`corrupt Zstandard stream: reserved block type at byte ${offset - 3}`);
|
|
74
|
+
}
|
|
75
|
+
const payloadBytes = blockType === 0x01 ? 1 : blockSize;
|
|
76
|
+
if (buffer.length - offset < payloadBytes)
|
|
77
|
+
return { frames, tornStart: start };
|
|
78
|
+
offset += payloadBytes;
|
|
79
|
+
if (lastBlock)
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
if (checksum) {
|
|
83
|
+
if (buffer.length - offset < 4)
|
|
84
|
+
return { frames, tornStart: start };
|
|
85
|
+
offset += 4;
|
|
86
|
+
}
|
|
87
|
+
frames.push({ start, end: offset });
|
|
88
|
+
if (frames.length === maxFrames)
|
|
89
|
+
return { frames };
|
|
90
|
+
}
|
|
91
|
+
return { frames };
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Compress one independently decodable, checksummed Zstandard frame.
|
|
95
|
+
* @param input - JSONL bytes for a header or durable event batch.
|
|
96
|
+
* @returns the complete encoded frame.
|
|
97
|
+
*/
|
|
98
|
+
export async function compressZstdFrame(input) {
|
|
99
|
+
return zstdCompressAsync(input, CHECKSUM_OPTIONS);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Decompress one complete frame and validate its checksum.
|
|
103
|
+
* @param input - one structurally complete Zstandard frame.
|
|
104
|
+
* @param maxOutput - optional plaintext bound; oversized frames reject with the Node error.
|
|
105
|
+
* @returns the frame plaintext.
|
|
106
|
+
*/
|
|
107
|
+
export async function decompressZstdFrame(input, maxOutput) {
|
|
108
|
+
if (maxOutput === undefined)
|
|
109
|
+
return zstdDecompressAsync(input);
|
|
110
|
+
return zstdDecompressAsync(input, { maxOutputLength: Math.max(1, maxOutput) });
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Synchronous one-frame decompression with an optional plaintext bound — for
|
|
114
|
+
* sync-only readers (the `memory:project` prompt section reads bank files with
|
|
115
|
+
* `readFileSync`). Keeps checksum validation identical to the async path.
|
|
116
|
+
* @param input - one structurally complete Zstandard frame.
|
|
117
|
+
* @param maxOutput - optional plaintext bound; oversized frames reject.
|
|
118
|
+
* @returns the frame plaintext.
|
|
119
|
+
*/
|
|
120
|
+
export function decompressZstdFrameSync(input, maxOutput) {
|
|
121
|
+
if (maxOutput === undefined)
|
|
122
|
+
return zstdDecompressSync(input);
|
|
123
|
+
return zstdDecompressSync(input, { maxOutputLength: Math.max(1, maxOutput) });
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Select the shared private decoder when the running Node 22/24/26 shape is
|
|
127
|
+
* compatible, otherwise preserve correctness with the public one-shot API.
|
|
128
|
+
* @returns a synchronous decoder with an implementation-independent lifecycle.
|
|
129
|
+
*/
|
|
130
|
+
export function createZstdFrameDecoder() {
|
|
131
|
+
return NodePrivateZstdFrameDecoder.create() ?? new PublicZstdFrameDecoder();
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Recover available plaintext from a structurally incomplete final frame.
|
|
135
|
+
* `ZSTD_e_flush` deliberately suppresses final-frame and checksum completion;
|
|
136
|
+
* callers must establish the torn frame boundary before using this helper.
|
|
137
|
+
* @param input - available bytes from a known incomplete Zstandard frame.
|
|
138
|
+
* @returns plaintext produced from the available input.
|
|
139
|
+
*/
|
|
140
|
+
export async function decompressZstdPrefix(input) {
|
|
141
|
+
return zstdDecompressAsync(input, INCOMPLETE_FRAME_OPTIONS);
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package-owned invariant companion for `@hy-sde-org/dsh-zstd-frame`.
|
|
3
|
+
* @module @hy-sde-org/dsh-zstd-frame/invariant
|
|
4
|
+
*/
|
|
5
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
6
|
+
/** Cordis companion plugin name. */
|
|
7
|
+
export declare const name = "zstd-frame-invariant";
|
|
8
|
+
/** Service required before the companion can reserve package ownership. */
|
|
9
|
+
export declare const inject: string[];
|
|
10
|
+
/**
|
|
11
|
+
* Register this package's invariant companion.
|
|
12
|
+
* @param ctx - Cordis context carrying the invariant service.
|
|
13
|
+
* @returns the installed registration's disposer after setup succeeds.
|
|
14
|
+
*/
|
|
15
|
+
export declare const apply: (ctx: Context) => Promise<() => void>;
|
|
16
|
+
//# sourceMappingURL=invariant.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invariant.d.ts","sourceRoot":"","sources":["../src/invariant.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAKlD,oCAAoC;AACpC,eAAO,MAAM,IAAI,yBAAyB,CAAA;AAC1C,2EAA2E;AAC3E,eAAO,MAAM,MAAM,UAAiB,CAAA;AAQpC;;;;GAIG;AACH,eAAO,MAAM,KAAK,GAAI,KAAK,OAAO,KAAG,OAAO,CAAC,MAAM,IAAI,CACU,CAAA"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package-owned invariant companion for `@hy-sde-org/dsh-zstd-frame`.
|
|
3
|
+
* @module @hy-sde-org/dsh-zstd-frame/invariant
|
|
4
|
+
*/
|
|
5
|
+
const PACKAGE_NAME = '@hy-sde-org/dsh-zstd-frame';
|
|
6
|
+
/** Cordis companion plugin name. */
|
|
7
|
+
export const name = 'zstd-frame-invariant';
|
|
8
|
+
/** Service required before the companion can reserve package ownership. */
|
|
9
|
+
export const inject = ['invariants'];
|
|
10
|
+
/**
|
|
11
|
+
* No runtime invariant: the frame layout algebra is enforced by the test suite
|
|
12
|
+
* and the structural scan rejects corrupt input at runtime.
|
|
13
|
+
*/
|
|
14
|
+
const install = () => { };
|
|
15
|
+
/**
|
|
16
|
+
* Register this package's invariant companion.
|
|
17
|
+
* @param ctx - Cordis context carrying the invariant service.
|
|
18
|
+
* @returns the installed registration's disposer after setup succeeds.
|
|
19
|
+
*/
|
|
20
|
+
export const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
|
|
21
|
+
/* jscpd:ignore-end */
|
|
22
|
+
//# sourceMappingURL=invariant.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invariant.js","sourceRoot":"","sources":["../src/invariant.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,YAAY,GAAG,4BAA4B,CAAA;AAEjD,oCAAoC;AACpC,MAAM,CAAC,MAAM,IAAI,GAAG,sBAAsB,CAAA;AAC1C,2EAA2E;AAC3E,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,YAAY,CAAC,CAAA;AAEpC;;;GAGG;AACH,MAAM,OAAO,GAAuB,GAAG,EAAE,GAAE,CAAC,CAAA;AAE5C;;;;GAIG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,GAAY,EAAuB,EAAE,CACzD,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAA;AACjE,sBAAsB"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node-private synchronous Zstandard frame decoder optimization.
|
|
3
|
+
* @module @hy-sde-org/dsh-zstd-frame/zstd-private-decoder
|
|
4
|
+
*/
|
|
5
|
+
import type { ZstdFrameDecoder, ZstdFrameRange } from './index.ts';
|
|
6
|
+
/**
|
|
7
|
+
* Synchronous multi-frame decoder backed by one Node Zstd stream handle. Node
|
|
8
|
+
* exposes synchronous decoding only as a one-shot API, so this adapter uses
|
|
9
|
+
* the stream's private handle contract to reuse its native context and output
|
|
10
|
+
* chunks across frames.
|
|
11
|
+
*/
|
|
12
|
+
export declare class NodePrivateZstdFrameDecoder implements ZstdFrameDecoder {
|
|
13
|
+
private readonly stream;
|
|
14
|
+
private readonly errorKey;
|
|
15
|
+
private readonly output;
|
|
16
|
+
private decoderError?;
|
|
17
|
+
private started;
|
|
18
|
+
private closed;
|
|
19
|
+
private constructor();
|
|
20
|
+
/**
|
|
21
|
+
* Create the optimized decoder when this Node release exposes the expected
|
|
22
|
+
* private stream shape.
|
|
23
|
+
* @returns a shared decoder, or `undefined` when callers must use the public fallback.
|
|
24
|
+
*/
|
|
25
|
+
static create(): NodePrivateZstdFrameDecoder | undefined;
|
|
26
|
+
/** @inheritdoc */
|
|
27
|
+
decode(source: Buffer, frames: readonly ZstdFrameRange[]): Generator<Buffer, void, void>;
|
|
28
|
+
/** Decode one frame; its returned scratch view remains valid until the next call. */
|
|
29
|
+
private decodeFrame;
|
|
30
|
+
/** @inheritdoc */
|
|
31
|
+
close(): void;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=zstd-private-decoder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zstd-private-decoder.d.ts","sourceRoot":"","sources":["../src/zstd-private-decoder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAiDlE;;;;;GAKG;AACH,qBAAa,2BAA4B,YAAW,gBAAgB;IAOhE,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAP3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwC;IAC/D,OAAO,CAAC,YAAY,CAAC,CAAO;IAC5B,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,MAAM,CAAQ;IAEtB,OAAO;IASP;;;;OAIG;IACH,MAAM,CAAC,MAAM,IAAI,2BAA2B,GAAG,SAAS;IAaxD,kBAAkB;IACV,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,cAAc,EAAE,GAAG,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC;IAmBhG,qFAAqF;IACrF,OAAO,CAAC,WAAW;IAuDnB,kBAAkB;IAClB,KAAK,IAAI,IAAI;CAKd"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node-private synchronous Zstandard frame decoder optimization.
|
|
3
|
+
* @module @hy-sde-org/dsh-zstd-frame/zstd-private-decoder
|
|
4
|
+
*/
|
|
5
|
+
import { constants as bufferConstants } from 'node:buffer';
|
|
6
|
+
import { createZstdDecompress } from 'node:zlib';
|
|
7
|
+
const DECODE_CHUNK_SIZE = 1024 * 1024;
|
|
8
|
+
/** Return the stream with its observed private Node contract, or reject that optimization. */
|
|
9
|
+
function privateZstdStream(stream) {
|
|
10
|
+
const candidate = stream;
|
|
11
|
+
const handle = candidate._handle;
|
|
12
|
+
const errorKey = Reflect.ownKeys(stream).find((key) => (typeof key === 'symbol' && key.description === 'kError'));
|
|
13
|
+
/* v8 ignore next -- one test runtime exposes one Node-private shape; the Node 22/24/26 matrix checks compatibility. */
|
|
14
|
+
if (typeof handle !== 'object' || handle === null
|
|
15
|
+
|| typeof handle.writeSync !== 'function'
|
|
16
|
+
|| !(candidate._writeState instanceof Uint32Array)
|
|
17
|
+
|| candidate._writeState.length < 2
|
|
18
|
+
|| typeof candidate._defaultFlushFlag !== 'number'
|
|
19
|
+
|| errorKey === undefined
|
|
20
|
+
|| candidate[errorKey] !== null)
|
|
21
|
+
return undefined;
|
|
22
|
+
return { stream: stream, errorKey };
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Synchronous multi-frame decoder backed by one Node Zstd stream handle. Node
|
|
26
|
+
* exposes synchronous decoding only as a one-shot API, so this adapter uses
|
|
27
|
+
* the stream's private handle contract to reuse its native context and output
|
|
28
|
+
* chunks across frames.
|
|
29
|
+
*/
|
|
30
|
+
export class NodePrivateZstdFrameDecoder {
|
|
31
|
+
stream;
|
|
32
|
+
errorKey;
|
|
33
|
+
output = Buffer.allocUnsafe(DECODE_CHUNK_SIZE);
|
|
34
|
+
decoderError;
|
|
35
|
+
started = false;
|
|
36
|
+
closed = false;
|
|
37
|
+
constructor(stream, errorKey) {
|
|
38
|
+
this.stream = stream;
|
|
39
|
+
this.errorKey = errorKey;
|
|
40
|
+
this.stream.on('error', (error) => {
|
|
41
|
+
this.decoderError ??= error;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Create the optimized decoder when this Node release exposes the expected
|
|
46
|
+
* private stream shape.
|
|
47
|
+
* @returns a shared decoder, or `undefined` when callers must use the public fallback.
|
|
48
|
+
*/
|
|
49
|
+
static create() {
|
|
50
|
+
const stream = createZstdDecompress({ chunkSize: DECODE_CHUNK_SIZE });
|
|
51
|
+
const privateAccess = privateZstdStream(stream);
|
|
52
|
+
/* v8 ignore next -- reached only when a supported Node release changes its private stream shape. */
|
|
53
|
+
if (privateAccess !== undefined) {
|
|
54
|
+
return new NodePrivateZstdFrameDecoder(privateAccess.stream, privateAccess.errorKey);
|
|
55
|
+
}
|
|
56
|
+
/* v8 ignore next -- the active Node runtime passed the private-shape probe above. */
|
|
57
|
+
stream.close();
|
|
58
|
+
/* v8 ignore next -- the active Node runtime passed the private-shape probe above. */
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
/** @inheritdoc */
|
|
62
|
+
*decode(source, frames) {
|
|
63
|
+
if (this.started)
|
|
64
|
+
throw new Error('Zstandard frame decoder was already started');
|
|
65
|
+
if (this.closed)
|
|
66
|
+
throw new Error('cannot start a closed Zstandard frame decoder');
|
|
67
|
+
this.started = true;
|
|
68
|
+
try {
|
|
69
|
+
for (const frame of frames) {
|
|
70
|
+
try {
|
|
71
|
+
yield this.decodeFrame(source.subarray(frame.start, frame.end));
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
throw new Error(`corrupt Zstandard stream: frame at byte ${frame.start} failed validation`, {
|
|
75
|
+
cause: error,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
this.close();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/** Decode one frame; its returned scratch view remains valid until the next call. */
|
|
85
|
+
decodeFrame(input) {
|
|
86
|
+
const handle = this.stream._handle;
|
|
87
|
+
/* v8 ignore next -- decode() rejects closed instances before entering this private frame operation. */
|
|
88
|
+
if (this.closed || handle === null)
|
|
89
|
+
throw new Error('cannot decode with a closed Zstandard frame decoder');
|
|
90
|
+
let inputOffset = 0;
|
|
91
|
+
let inputRemaining = input.length;
|
|
92
|
+
let outputBytes = 0;
|
|
93
|
+
const fullChunks = [];
|
|
94
|
+
for (;;) {
|
|
95
|
+
handle.writeSync(this.stream._defaultFlushFlag, input, inputOffset, inputRemaining, this.output, 0, this.output.length);
|
|
96
|
+
if (this.decoderError !== undefined)
|
|
97
|
+
throw this.decoderError;
|
|
98
|
+
const internalError = this.stream[this.errorKey];
|
|
99
|
+
if (internalError !== null) {
|
|
100
|
+
if (internalError instanceof Error)
|
|
101
|
+
throw internalError;
|
|
102
|
+
throw new Error('Zstandard decoder exposed a non-Error internal failure');
|
|
103
|
+
}
|
|
104
|
+
const outputAfter = this.stream._writeState[0];
|
|
105
|
+
const inputAfter = this.stream._writeState[1];
|
|
106
|
+
const consumed = inputRemaining - inputAfter;
|
|
107
|
+
const produced = this.output.length - outputAfter;
|
|
108
|
+
if (produced > 0) {
|
|
109
|
+
outputBytes += produced;
|
|
110
|
+
/* v8 ignore next -- Buffer cannot materialize a frame beyond its own process-wide maximum length. */
|
|
111
|
+
if (outputBytes > bufferConstants.MAX_LENGTH) {
|
|
112
|
+
throw new Error(`Zstandard frame output exceeds ${bufferConstants.MAX_LENGTH} bytes`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (outputAfter !== 0) {
|
|
116
|
+
/* v8 ignore next -- structurally scanned ranges contain exactly one complete frame and no trailing bytes. */
|
|
117
|
+
if (inputAfter !== 0)
|
|
118
|
+
throw new Error('Zstandard frame decoder left trailing input');
|
|
119
|
+
const finalChunk = this.output.subarray(0, produced);
|
|
120
|
+
if (fullChunks.length === 0)
|
|
121
|
+
return finalChunk;
|
|
122
|
+
if (produced > 0)
|
|
123
|
+
fullChunks.push(Buffer.from(finalChunk));
|
|
124
|
+
const onlyChunk = fullChunks[0];
|
|
125
|
+
return fullChunks.length === 1
|
|
126
|
+
? onlyChunk
|
|
127
|
+
: Buffer.concat(fullChunks, outputBytes);
|
|
128
|
+
}
|
|
129
|
+
fullChunks.push(Buffer.from(this.output));
|
|
130
|
+
inputOffset += consumed;
|
|
131
|
+
inputRemaining = inputAfter;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/** @inheritdoc */
|
|
135
|
+
close() {
|
|
136
|
+
if (this.closed)
|
|
137
|
+
return;
|
|
138
|
+
this.closed = true;
|
|
139
|
+
this.stream.close();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=zstd-private-decoder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zstd-private-decoder.js","sourceRoot":"","sources":["../src/zstd-private-decoder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public-API synchronous Zstandard frame decoder fallback.
|
|
3
|
+
* @module @hy-sde-org/dsh-zstd-frame/zstd-public-decoder
|
|
4
|
+
*/
|
|
5
|
+
import type { ZstdFrameDecoder, ZstdFrameRange } from './index.ts';
|
|
6
|
+
/** Multi-frame adapter built exclusively from Node's supported one-shot API. */
|
|
7
|
+
export declare class PublicZstdFrameDecoder implements ZstdFrameDecoder {
|
|
8
|
+
private started;
|
|
9
|
+
private closed;
|
|
10
|
+
/** @inheritdoc */
|
|
11
|
+
decode(source: Buffer, frames: readonly ZstdFrameRange[]): Generator<Buffer, void, void>;
|
|
12
|
+
/** @inheritdoc */
|
|
13
|
+
close(): void;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=zstd-public-decoder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zstd-public-decoder.d.ts","sourceRoot":"","sources":["../src/zstd-public-decoder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAElE,gFAAgF;AAChF,qBAAa,sBAAuB,YAAW,gBAAgB;IAC7D,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,MAAM,CAAQ;IAEtB,kBAAkB;IACV,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,cAAc,EAAE,GAAG,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC;IAqBhG,kBAAkB;IAClB,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public-API synchronous Zstandard frame decoder fallback.
|
|
3
|
+
* @module @hy-sde-org/dsh-zstd-frame/zstd-public-decoder
|
|
4
|
+
*/
|
|
5
|
+
import { zstdDecompressSync } from 'node:zlib';
|
|
6
|
+
/** Multi-frame adapter built exclusively from Node's supported one-shot API. */
|
|
7
|
+
export class PublicZstdFrameDecoder {
|
|
8
|
+
started = false;
|
|
9
|
+
closed = false;
|
|
10
|
+
/** @inheritdoc */
|
|
11
|
+
*decode(source, frames) {
|
|
12
|
+
if (this.started)
|
|
13
|
+
throw new Error('Zstandard frame decoder was already started');
|
|
14
|
+
if (this.closed)
|
|
15
|
+
throw new Error('cannot start a closed Zstandard frame decoder');
|
|
16
|
+
this.started = true;
|
|
17
|
+
try {
|
|
18
|
+
for (const { start, end } of frames) {
|
|
19
|
+
let decoded;
|
|
20
|
+
try {
|
|
21
|
+
decoded = zstdDecompressSync(source.subarray(start, end));
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
throw new Error(`corrupt Zstandard stream: frame at byte ${start} failed validation`, {
|
|
25
|
+
cause: error,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
yield decoded;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
this.close();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** @inheritdoc */
|
|
36
|
+
close() {
|
|
37
|
+
this.closed = true;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=zstd-public-decoder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zstd-public-decoder.js","sourceRoot":"","sources":["../src/zstd-public-decoder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAG9C,gFAAgF;AAChF,MAAM,OAAO,sBAAsB;IACzB,OAAO,GAAG,KAAK,CAAA;IACf,MAAM,GAAG,KAAK,CAAA;IAEtB,kBAAkB;IACX,CAAC,MAAM,CAAC,MAAc,EAAE,MAAiC;QAC9D,IAAI,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAA;QAChF,IAAI,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAA;QACjF,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QACnB,IAAI,CAAC;YACH,KAAK,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,MAAM,EAAE,CAAC;gBACpC,IAAI,OAAe,CAAA;gBACnB,IAAI,CAAC;oBACH,OAAO,GAAG,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAA;gBAC3D,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,IAAI,KAAK,CAAC,2CAA2C,KAAK,oBAAoB,EAAE;wBACpF,KAAK,EAAE,KAAK;qBACb,CAAC,CAAA;gBACJ,CAAC;gBACD,MAAM,OAAO,CAAA;YACf,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,KAAK,EAAE,CAAA;QACd,CAAC;IACH,CAAC;IAED,kBAAkB;IAClB,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;IACpB,CAAC;CACF"}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hy-sde-org/dsh-zstd-frame",
|
|
3
|
+
"version": "0.1.1-rc.2",
|
|
4
|
+
"description": "Zstandard frame primitives (scan / compress / decompress / multi-frame decoder) shared by the DeepSeek Harness session persistence backend and project memory bank, as a standalone npm package.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./invariant": {
|
|
14
|
+
"types": "./dist/invariant.d.ts",
|
|
15
|
+
"default": "./dist/invariant.js"
|
|
16
|
+
},
|
|
17
|
+
"./package.json": "./package.json"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"README.md",
|
|
22
|
+
"LICENSE"
|
|
23
|
+
],
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=22.19.0"
|
|
26
|
+
},
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public"
|
|
29
|
+
},
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/hy-sde/dsh-zstd-frame.git"
|
|
33
|
+
},
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
37
|
+
"@deepseek-ai/dsh-invariants": "^0.1.1-rc.2"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
41
|
+
"@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
|
|
42
|
+
"@types/node": "^24.0.0",
|
|
43
|
+
"typescript": "^5.9.3",
|
|
44
|
+
"vitest": "^3.2.7"
|
|
45
|
+
},
|
|
46
|
+
"keywords": [
|
|
47
|
+
"deepseek",
|
|
48
|
+
"agent",
|
|
49
|
+
"harness",
|
|
50
|
+
"dsh-plugin",
|
|
51
|
+
"zstd",
|
|
52
|
+
"zstandard",
|
|
53
|
+
"frame",
|
|
54
|
+
"checksum",
|
|
55
|
+
"torn-frame"
|
|
56
|
+
],
|
|
57
|
+
"scripts": {
|
|
58
|
+
"clean": "rm -rf dist",
|
|
59
|
+
"build": "tsc -p tsconfig.build.json",
|
|
60
|
+
"check": "tsc -p tsconfig.json --noEmit",
|
|
61
|
+
"test": "vitest run"
|
|
62
|
+
}
|
|
63
|
+
}
|