@platformatic/sqlite-js-stream 0.0.0-stage → 0.1.1
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/CHANGELOG.md +40 -0
- package/LICENSE +202 -0
- package/NOTICE +22 -0
- package/README.md +482 -2
- package/dist/backends/file/index.d.ts +4 -0
- package/dist/backends/file/index.d.ts.map +1 -0
- package/dist/backends/file/index.js +3 -0
- package/dist/backends/file/leaser.d.ts +20 -0
- package/dist/backends/file/leaser.d.ts.map +1 -0
- package/dist/backends/file/leaser.js +123 -0
- package/dist/backends/file/replica-client.d.ts +38 -0
- package/dist/backends/file/replica-client.d.ts.map +1 -0
- package/dist/backends/file/replica-client.js +209 -0
- package/dist/db.d.ts +80 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +484 -0
- package/dist/errors.d.ts +42 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +66 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/leaser.d.ts +55 -0
- package/dist/leaser.d.ts.map +1 -0
- package/dist/leaser.js +60 -0
- package/dist/ltx/byte-reader.d.ts +18 -0
- package/dist/ltx/byte-reader.d.ts.map +1 -0
- package/dist/ltx/byte-reader.js +38 -0
- package/dist/ltx/bytes.d.ts +20 -0
- package/dist/ltx/bytes.d.ts.map +1 -0
- package/dist/ltx/bytes.js +69 -0
- package/dist/ltx/checksum.d.ts +20 -0
- package/dist/ltx/checksum.d.ts.map +1 -0
- package/dist/ltx/checksum.js +42 -0
- package/dist/ltx/compaction-level.d.ts +58 -0
- package/dist/ltx/compaction-level.d.ts.map +1 -0
- package/dist/ltx/compaction-level.js +115 -0
- package/dist/ltx/compactor.d.ts +33 -0
- package/dist/ltx/compactor.d.ts.map +1 -0
- package/dist/ltx/compactor.js +137 -0
- package/dist/ltx/constants.d.ts +49 -0
- package/dist/ltx/constants.d.ts.map +1 -0
- package/dist/ltx/constants.js +58 -0
- package/dist/ltx/crc64.d.ts +29 -0
- package/dist/ltx/crc64.d.ts.map +1 -0
- package/dist/ltx/crc64.js +57 -0
- package/dist/ltx/decoder.d.ts +55 -0
- package/dist/ltx/decoder.d.ts.map +1 -0
- package/dist/ltx/decoder.js +236 -0
- package/dist/ltx/encoder.d.ts +49 -0
- package/dist/ltx/encoder.d.ts.map +1 -0
- package/dist/ltx/encoder.js +159 -0
- package/dist/ltx/file-info.d.ts +24 -0
- package/dist/ltx/file-info.d.ts.map +1 -0
- package/dist/ltx/file-info.js +74 -0
- package/dist/ltx/filename.d.ts +13 -0
- package/dist/ltx/filename.d.ts.map +1 -0
- package/dist/ltx/filename.js +23 -0
- package/dist/ltx/header.d.ts +17 -0
- package/dist/ltx/header.d.ts.map +1 -0
- package/dist/ltx/header.js +115 -0
- package/dist/ltx/index.d.ts +24 -0
- package/dist/ltx/index.d.ts.map +1 -0
- package/dist/ltx/index.js +25 -0
- package/dist/ltx/lz4.d.ts +41 -0
- package/dist/ltx/lz4.d.ts.map +1 -0
- package/dist/ltx/lz4.js +264 -0
- package/dist/ltx/page-index.d.ts +26 -0
- package/dist/ltx/page-index.d.ts.map +1 -0
- package/dist/ltx/page-index.js +118 -0
- package/dist/ltx/page.d.ts +27 -0
- package/dist/ltx/page.d.ts.map +1 -0
- package/dist/ltx/page.js +66 -0
- package/dist/ltx/sink.d.ts +17 -0
- package/dist/ltx/sink.d.ts.map +1 -0
- package/dist/ltx/sink.js +21 -0
- package/dist/ltx/stream.d.ts +64 -0
- package/dist/ltx/stream.d.ts.map +1 -0
- package/dist/ltx/stream.js +248 -0
- package/dist/ltx/streaming-compactor.d.ts +34 -0
- package/dist/ltx/streaming-compactor.d.ts.map +1 -0
- package/dist/ltx/streaming-compactor.js +140 -0
- package/dist/ltx/trailer.d.ts +12 -0
- package/dist/ltx/trailer.d.ts.map +1 -0
- package/dist/ltx/trailer.js +47 -0
- package/dist/ltx/types.d.ts +79 -0
- package/dist/ltx/types.d.ts.map +1 -0
- package/dist/ltx/types.js +70 -0
- package/dist/replica-client.d.ts +92 -0
- package/dist/replica-client.d.ts.map +1 -0
- package/dist/replica-client.js +122 -0
- package/dist/replica-url.d.ts +20 -0
- package/dist/replica-url.d.ts.map +1 -0
- package/dist/replica-url.js +49 -0
- package/dist/replica.d.ts +379 -0
- package/dist/replica.d.ts.map +1 -0
- package/dist/replica.js +1253 -0
- package/dist/store.d.ts +34 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +60 -0
- package/dist/util/fs.d.ts +28 -0
- package/dist/util/fs.d.ts.map +1 -0
- package/dist/util/fs.js +73 -0
- package/dist/util/logger.d.ts +10 -0
- package/dist/util/logger.d.ts.map +1 -0
- package/dist/util/logger.js +7 -0
- package/dist/util/stream.d.ts +11 -0
- package/dist/util/stream.d.ts.map +1 -0
- package/dist/util/stream.js +25 -0
- package/dist/wal/checksum.d.ts +17 -0
- package/dist/wal/checksum.d.ts.map +1 -0
- package/dist/wal/checksum.js +30 -0
- package/dist/wal/constants.d.ts +8 -0
- package/dist/wal/constants.d.ts.map +1 -0
- package/dist/wal/constants.js +7 -0
- package/dist/wal/index.d.ts +5 -0
- package/dist/wal/index.d.ts.map +1 -0
- package/dist/wal/index.js +4 -0
- package/dist/wal/reader.d.ts +61 -0
- package/dist/wal/reader.d.ts.map +1 -0
- package/dist/wal/reader.js +207 -0
- package/package.json +68 -3
- package/src/backends/file/index.ts +3 -0
- package/src/backends/file/leaser.ts +145 -0
- package/src/backends/file/replica-client.ts +246 -0
- package/src/db.ts +553 -0
- package/src/errors.ts +74 -0
- package/src/index.ts +26 -0
- package/src/leaser.ts +86 -0
- package/src/ltx/byte-reader.ts +46 -0
- package/src/ltx/bytes.ts +87 -0
- package/src/ltx/checksum.ts +46 -0
- package/src/ltx/compaction-level.ts +135 -0
- package/src/ltx/compactor.ts +167 -0
- package/src/ltx/constants.ts +71 -0
- package/src/ltx/crc64.ts +65 -0
- package/src/ltx/decoder.ts +282 -0
- package/src/ltx/encoder.ts +200 -0
- package/src/ltx/file-info.ts +81 -0
- package/src/ltx/filename.ts +27 -0
- package/src/ltx/header.ts +126 -0
- package/src/ltx/index.ts +27 -0
- package/src/ltx/lz4.ts +279 -0
- package/src/ltx/page-index.ts +140 -0
- package/src/ltx/page.ts +80 -0
- package/src/ltx/sink.ts +33 -0
- package/src/ltx/stream.ts +286 -0
- package/src/ltx/streaming-compactor.ts +169 -0
- package/src/ltx/trailer.ts +58 -0
- package/src/ltx/types.ts +152 -0
- package/src/lz4js.d.ts +27 -0
- package/src/replica-client.ts +222 -0
- package/src/replica-url.ts +72 -0
- package/src/replica.ts +1480 -0
- package/src/store.ts +71 -0
- package/src/util/fs.ts +82 -0
- package/src/util/logger.ts +15 -0
- package/src/util/stream.ts +28 -0
- package/src/wal/checksum.ts +39 -0
- package/src/wal/constants.ts +10 -0
- package/src/wal/index.ts +5 -0
- package/src/wal/reader.ts +264 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LTX encoder.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors Go's `ltx.Encoder`. The encoder streams header, page frames, page
|
|
5
|
+
* index, and trailer to a `ByteSink`, maintaining a running CRC-64 ISO file
|
|
6
|
+
* checksum over all logical content (header, page headers, compressed-size
|
|
7
|
+
* prefixes, *decompressed* page data, page index bytes, and the trailer's
|
|
8
|
+
* post-apply checksum) plus a byte counter for page-index offsets.
|
|
9
|
+
*/
|
|
10
|
+
import type { ByteSink } from './sink.js';
|
|
11
|
+
import type { Header, PageHeader, Trailer } from './types.js';
|
|
12
|
+
/** Encoder writes an LTX file to a ByteSink. */
|
|
13
|
+
export declare class Encoder {
|
|
14
|
+
private sink;
|
|
15
|
+
private state;
|
|
16
|
+
private header;
|
|
17
|
+
private trailer;
|
|
18
|
+
private hash;
|
|
19
|
+
private index;
|
|
20
|
+
private n;
|
|
21
|
+
private prevPgno;
|
|
22
|
+
private pagesWritten;
|
|
23
|
+
constructor(sink: ByteSink);
|
|
24
|
+
/** Returns the number of bytes written to the sink so far. */
|
|
25
|
+
N(): number;
|
|
26
|
+
/** Returns a shallow copy of the header. */
|
|
27
|
+
Header(): Header;
|
|
28
|
+
/** Returns the trailer (file checksum valid after Close()). */
|
|
29
|
+
Trailer(): Trailer;
|
|
30
|
+
/** Returns the replication position after applying this file. */
|
|
31
|
+
PostApplyPos(): {
|
|
32
|
+
txID: bigint;
|
|
33
|
+
postApplyChecksum: bigint;
|
|
34
|
+
};
|
|
35
|
+
/** SetPostApplyChecksum sets the database checksum to record in the trailer. */
|
|
36
|
+
setPostApplyChecksum(chk: bigint): void;
|
|
37
|
+
/** EncodeHeader writes the header frame and initializes the checksum. */
|
|
38
|
+
encodeHeader(h: Header): void;
|
|
39
|
+
/**
|
|
40
|
+
* EncodePage writes a single page frame. `data` must be exactly the page
|
|
41
|
+
* size and `hdr.pgno` must be in ascending order and not the lock page.
|
|
42
|
+
*/
|
|
43
|
+
encodePage(hdr: PageHeader, data: Uint8Array): void;
|
|
44
|
+
/** Close writes the end-of-pages marker, page index, and trailer. */
|
|
45
|
+
close(): void;
|
|
46
|
+
/** Writes to the sink, feeding the checksum and byte counter. */
|
|
47
|
+
private write;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=encoder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encoder.d.ts","sourceRoot":"","sources":["../../src/ltx/encoder.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAYH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAkB9D,gDAAgD;AAChD,qBAAa,OAAO;IAClB,OAAO,CAAC,IAAI,CAAW;IACvB,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,OAAO,CAAwD;IACvE,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,KAAK,CAAoB;IACjC,OAAO,CAAC,CAAC,CAAK;IACd,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,YAAY,CAAK;gBAEb,IAAI,EAAE,QAAQ;IAI1B,8DAA8D;IAC9D,CAAC,IAAI,MAAM;IAIX,4CAA4C;IAC5C,MAAM,IAAI,MAAM;IAIhB,+DAA+D;IAC/D,OAAO,IAAI,OAAO;IAIlB,iEAAiE;IACjE,YAAY;;;;IAOZ,gFAAgF;IAChF,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIvC,yEAAyE;IACzE,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAY7B;;;OAGG;IACH,UAAU,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI;IA4DnD,qEAAqE;IACrE,KAAK,IAAI,IAAI;IAgCb,iEAAiE;IACjE,OAAO,CAAC,KAAK;CAKd"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LTX encoder.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors Go's `ltx.Encoder`. The encoder streams header, page frames, page
|
|
5
|
+
* index, and trailer to a `ByteSink`, maintaining a running CRC-64 ISO file
|
|
6
|
+
* checksum over all logical content (header, page headers, compressed-size
|
|
7
|
+
* prefixes, *decompressed* page data, page index bytes, and the trailer's
|
|
8
|
+
* post-apply checksum) plus a byte counter for page-index offsets.
|
|
9
|
+
*/
|
|
10
|
+
import { ChecksumFlag, PageHeaderFlagSize, PageHeaderSize, TrailerChecksumOffset, TrailerSize, lockPgno, } from "./constants.js";
|
|
11
|
+
import { Crc64 } from "./crc64.js";
|
|
12
|
+
import { u32BE, u64BE } from "./bytes.js";
|
|
13
|
+
import { marshalHeader, validateHeader } from "./header.js";
|
|
14
|
+
import { marshalPageHeader, validatePageHeader } from "./page.js";
|
|
15
|
+
import { marshalTrailer, validateTrailer } from "./trailer.js";
|
|
16
|
+
import { encodePageIndexRecord, encodeUvarint } from "./page-index.js";
|
|
17
|
+
import { compressBlock } from "./lz4.js";
|
|
18
|
+
import { LTXFormatError } from "../errors.js";
|
|
19
|
+
const stateHeader = 'header';
|
|
20
|
+
const statePage = 'page';
|
|
21
|
+
const stateClosed = 'closed';
|
|
22
|
+
/** Encoder writes an LTX file to a ByteSink. */
|
|
23
|
+
export class Encoder {
|
|
24
|
+
sink;
|
|
25
|
+
state = stateHeader;
|
|
26
|
+
header;
|
|
27
|
+
trailer = { postApplyChecksum: 0n, fileChecksum: 0n };
|
|
28
|
+
hash = new Crc64();
|
|
29
|
+
index = [];
|
|
30
|
+
n = 0;
|
|
31
|
+
prevPgno = 0;
|
|
32
|
+
pagesWritten = 0;
|
|
33
|
+
constructor(sink) {
|
|
34
|
+
this.sink = sink;
|
|
35
|
+
}
|
|
36
|
+
/** Returns the number of bytes written to the sink so far. */
|
|
37
|
+
N() {
|
|
38
|
+
return this.n;
|
|
39
|
+
}
|
|
40
|
+
/** Returns a shallow copy of the header. */
|
|
41
|
+
Header() {
|
|
42
|
+
return this.header;
|
|
43
|
+
}
|
|
44
|
+
/** Returns the trailer (file checksum valid after Close()). */
|
|
45
|
+
Trailer() {
|
|
46
|
+
return this.trailer;
|
|
47
|
+
}
|
|
48
|
+
/** Returns the replication position after applying this file. */
|
|
49
|
+
PostApplyPos() {
|
|
50
|
+
return {
|
|
51
|
+
txID: this.header.maxTXID,
|
|
52
|
+
postApplyChecksum: this.trailer.postApplyChecksum,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/** SetPostApplyChecksum sets the database checksum to record in the trailer. */
|
|
56
|
+
setPostApplyChecksum(chk) {
|
|
57
|
+
this.trailer.postApplyChecksum = chk;
|
|
58
|
+
}
|
|
59
|
+
/** EncodeHeader writes the header frame and initializes the checksum. */
|
|
60
|
+
encodeHeader(h) {
|
|
61
|
+
if (this.state === stateClosed)
|
|
62
|
+
throw new LTXFormatError('ltx encoder closed');
|
|
63
|
+
if (this.state !== stateHeader) {
|
|
64
|
+
throw new LTXFormatError(`cannot encode header frame, expected ${this.state}`);
|
|
65
|
+
}
|
|
66
|
+
validateHeader(h);
|
|
67
|
+
this.header = h;
|
|
68
|
+
this.hash = new Crc64();
|
|
69
|
+
this.write(marshalHeader(h));
|
|
70
|
+
this.state = statePage;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* EncodePage writes a single page frame. `data` must be exactly the page
|
|
74
|
+
* size and `hdr.pgno` must be in ascending order and not the lock page.
|
|
75
|
+
*/
|
|
76
|
+
encodePage(hdr, data) {
|
|
77
|
+
if (this.state === stateClosed)
|
|
78
|
+
throw new LTXFormatError('ltx encoder closed');
|
|
79
|
+
if (this.state !== statePage) {
|
|
80
|
+
throw new LTXFormatError(`cannot encode page header, expected ${this.state}`);
|
|
81
|
+
}
|
|
82
|
+
if (hdr.pgno > this.header.commit) {
|
|
83
|
+
throw new LTXFormatError(`page number ${hdr.pgno} out-of-bounds for commit size ${this.header.commit}`);
|
|
84
|
+
}
|
|
85
|
+
validatePageHeader(hdr);
|
|
86
|
+
if (data.length !== this.header.pageSize) {
|
|
87
|
+
throw new LTXFormatError(`invalid page buffer size: ${data.length}, expecting ${this.header.pageSize}`);
|
|
88
|
+
}
|
|
89
|
+
const lockPg = lockPgno(this.header.pageSize);
|
|
90
|
+
if (hdr.pgno === lockPg) {
|
|
91
|
+
throw new LTXFormatError(`cannot encode lock page: pgno=${hdr.pgno}`);
|
|
92
|
+
}
|
|
93
|
+
// Enforce page ordering.
|
|
94
|
+
if (this.header.minTXID === 1n) {
|
|
95
|
+
// Snapshot files must include all pages up to commit, in order.
|
|
96
|
+
if (this.prevPgno === 0 && hdr.pgno !== 1) {
|
|
97
|
+
throw new LTXFormatError('snapshot transaction file must start with page number 1');
|
|
98
|
+
}
|
|
99
|
+
if (this.prevPgno === lockPg - 1) {
|
|
100
|
+
if (hdr.pgno !== this.prevPgno + 2) {
|
|
101
|
+
throw new LTXFormatError(`nonsequential page numbers in snapshot transaction (skip lock page): ${this.prevPgno},${hdr.pgno}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
else if (this.prevPgno !== 0 && hdr.pgno !== this.prevPgno + 1) {
|
|
105
|
+
throw new LTXFormatError(`nonsequential page numbers in snapshot transaction: ${this.prevPgno},${hdr.pgno}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
if (this.prevPgno >= hdr.pgno) {
|
|
110
|
+
throw new LTXFormatError(`out-of-order page numbers: ${this.prevPgno},${hdr.pgno}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const offset = this.n;
|
|
114
|
+
const compressed = compressBlock(data);
|
|
115
|
+
const fhdr = { pgno: hdr.pgno, flags: hdr.flags | PageHeaderFlagSize };
|
|
116
|
+
this.write(marshalPageHeader(fhdr));
|
|
117
|
+
this.write(u32BE(compressed.length));
|
|
118
|
+
this.sink.write(compressed);
|
|
119
|
+
this.hash.update(data); // hash the raw (uncompressed) page data
|
|
120
|
+
this.n += compressed.length;
|
|
121
|
+
this.pagesWritten++;
|
|
122
|
+
this.prevPgno = hdr.pgno;
|
|
123
|
+
this.index.push({ pgno: hdr.pgno, offset, size: this.n - offset });
|
|
124
|
+
}
|
|
125
|
+
/** Close writes the end-of-pages marker, page index, and trailer. */
|
|
126
|
+
close() {
|
|
127
|
+
if (this.state === stateClosed)
|
|
128
|
+
return;
|
|
129
|
+
if (this.state !== statePage) {
|
|
130
|
+
throw new LTXFormatError(`cannot close, expected ${this.state}`);
|
|
131
|
+
}
|
|
132
|
+
// Empty page header terminates the page block.
|
|
133
|
+
const zero = new Uint8Array(PageHeaderSize);
|
|
134
|
+
this.write(zero);
|
|
135
|
+
// Write the page index.
|
|
136
|
+
const start = this.n;
|
|
137
|
+
for (const e of this.index) {
|
|
138
|
+
this.write(encodePageIndexRecord(e.pgno, e.offset, e.size));
|
|
139
|
+
}
|
|
140
|
+
this.write(encodeUvarint(0n)); // end marker
|
|
141
|
+
this.write(u64BE(BigInt(this.n - start))); // size of index varint bytes
|
|
142
|
+
// Marshal trailer (post-apply checksum set, file checksum pending).
|
|
143
|
+
const t = marshalTrailer(this.trailer);
|
|
144
|
+
this.hash.update(t.subarray(0, TrailerChecksumOffset));
|
|
145
|
+
this.n += TrailerChecksumOffset;
|
|
146
|
+
this.trailer.fileChecksum = ChecksumFlag | this.hash.sum64();
|
|
147
|
+
validateTrailer(this.trailer, this.header);
|
|
148
|
+
// Remarshal with the file checksum and write to the sink (not hashed).
|
|
149
|
+
this.sink.write(marshalTrailer(this.trailer));
|
|
150
|
+
this.n += TrailerSize - TrailerChecksumOffset;
|
|
151
|
+
this.state = stateClosed;
|
|
152
|
+
}
|
|
153
|
+
/** Writes to the sink, feeding the checksum and byte counter. */
|
|
154
|
+
write(b) {
|
|
155
|
+
this.sink.write(b);
|
|
156
|
+
this.hash.update(b);
|
|
157
|
+
this.n += b.length;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LTX file metadata and iteration over a set of LTX files.
|
|
3
|
+
*/
|
|
4
|
+
import type { FileInfo, TXID } from './types.js';
|
|
5
|
+
import { isContiguous } from './types.js';
|
|
6
|
+
/** Sorts FileInfo by (level, minTXID, maxTXID), in place. */
|
|
7
|
+
export declare function sortFileInfo(a: FileInfo[]): FileInfo[];
|
|
8
|
+
/** MaxTXID returns the largest maxTXID in a slice, or 0n if empty. */
|
|
9
|
+
export declare function maxTXID(a: readonly FileInfo[]): TXID;
|
|
10
|
+
/** SliceFileIterator iterates over a sorted slice of LTX file metadata. */
|
|
11
|
+
export declare class FileInfoSliceIterator {
|
|
12
|
+
private a;
|
|
13
|
+
private init;
|
|
14
|
+
private current;
|
|
15
|
+
constructor(a: FileInfo[]);
|
|
16
|
+
next(): boolean;
|
|
17
|
+
err(): Error | null;
|
|
18
|
+
item(): FileInfo | null;
|
|
19
|
+
close(): void;
|
|
20
|
+
}
|
|
21
|
+
/** Returns all LTX files from an iterator as an array. */
|
|
22
|
+
export declare function sliceFileIterator(itr: FileInfoSliceIterator): FileInfo[];
|
|
23
|
+
export { isContiguous };
|
|
24
|
+
//# sourceMappingURL=file-info.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-info.d.ts","sourceRoot":"","sources":["../../src/ltx/file-info.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,6DAA6D;AAC7D,wBAAgB,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAOtD;AAED,sEAAsE;AACtE,wBAAgB,OAAO,CAAC,CAAC,EAAE,SAAS,QAAQ,EAAE,GAAG,IAAI,CAOpD;AAED,2EAA2E;AAC3E,qBAAa,qBAAqB;IAChC,OAAO,CAAC,CAAC,CAAa;IACtB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,OAAO,CAAyB;gBAE5B,CAAC,EAAE,QAAQ,EAAE;IAIzB,IAAI,IAAI,OAAO;IAmBf,GAAG,IAAI,KAAK,GAAG,IAAI;IAInB,IAAI,IAAI,QAAQ,GAAG,IAAI;IAIvB,KAAK,IAAI,IAAI;CAGd;AAED,0DAA0D;AAC1D,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,qBAAqB,GAAG,QAAQ,EAAE,CAQxE;AAED,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LTX file metadata and iteration over a set of LTX files.
|
|
3
|
+
*/
|
|
4
|
+
import { isContiguous } from "./types.js";
|
|
5
|
+
/** Sorts FileInfo by (level, minTXID, maxTXID), in place. */
|
|
6
|
+
export function sortFileInfo(a) {
|
|
7
|
+
a.sort((x, y) => {
|
|
8
|
+
if (x.level !== y.level)
|
|
9
|
+
return x.level - y.level;
|
|
10
|
+
if (x.minTXID !== y.minTXID)
|
|
11
|
+
return x.minTXID < y.minTXID ? -1 : 1;
|
|
12
|
+
return x.maxTXID < y.maxTXID ? -1 : x.maxTXID > y.maxTXID ? 1 : 0;
|
|
13
|
+
});
|
|
14
|
+
return a;
|
|
15
|
+
}
|
|
16
|
+
/** MaxTXID returns the largest maxTXID in a slice, or 0n if empty. */
|
|
17
|
+
export function maxTXID(a) {
|
|
18
|
+
if (a.length === 0)
|
|
19
|
+
return 0n;
|
|
20
|
+
let m = a[0].maxTXID;
|
|
21
|
+
for (const info of a) {
|
|
22
|
+
if (info.maxTXID > m)
|
|
23
|
+
m = info.maxTXID;
|
|
24
|
+
}
|
|
25
|
+
return m;
|
|
26
|
+
}
|
|
27
|
+
/** SliceFileIterator iterates over a sorted slice of LTX file metadata. */
|
|
28
|
+
export class FileInfoSliceIterator {
|
|
29
|
+
a;
|
|
30
|
+
init = false;
|
|
31
|
+
current = null;
|
|
32
|
+
constructor(a) {
|
|
33
|
+
this.a = sortFileInfo([...a]);
|
|
34
|
+
}
|
|
35
|
+
next() {
|
|
36
|
+
if (!this.init) {
|
|
37
|
+
this.init = true;
|
|
38
|
+
if (this.a.length === 0) {
|
|
39
|
+
this.current = null;
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
this.current = this.a[0];
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
this.a = this.a.slice(1);
|
|
46
|
+
if (this.a.length === 0) {
|
|
47
|
+
this.current = null;
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
this.current = this.a[0];
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
err() {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
item() {
|
|
57
|
+
return this.current;
|
|
58
|
+
}
|
|
59
|
+
close() {
|
|
60
|
+
/* nothing to release */
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/** Returns all LTX files from an iterator as an array. */
|
|
64
|
+
export function sliceFileIterator(itr) {
|
|
65
|
+
const out = [];
|
|
66
|
+
while (itr.next()) {
|
|
67
|
+
const item = itr.item();
|
|
68
|
+
if (item)
|
|
69
|
+
out.push(item);
|
|
70
|
+
}
|
|
71
|
+
itr.close();
|
|
72
|
+
return out;
|
|
73
|
+
}
|
|
74
|
+
export { isContiguous };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LTX filename parsing/formatting.
|
|
3
|
+
*
|
|
4
|
+
* Names are `{minTXID:016x}-{maxTXID:016x}.ltx`.
|
|
5
|
+
*/
|
|
6
|
+
/** FormatFilename returns an LTX filename representing a TXID range. */
|
|
7
|
+
export declare function formatFilename(minTXID: bigint, maxTXID: bigint): string;
|
|
8
|
+
/** ParseFilename parses a transaction range from an LTX filename. */
|
|
9
|
+
export declare function parseFilename(name: string): {
|
|
10
|
+
minTXID: bigint;
|
|
11
|
+
maxTXID: bigint;
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=filename.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filename.d.ts","sourceRoot":"","sources":["../../src/ltx/filename.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,wEAAwE;AACxE,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAEvE;AAED,qEAAqE;AACrE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAShF"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LTX filename parsing/formatting.
|
|
3
|
+
*
|
|
4
|
+
* Names are `{minTXID:016x}-{maxTXID:016x}.ltx`.
|
|
5
|
+
*/
|
|
6
|
+
import { formatTXID } from "./types.js";
|
|
7
|
+
import { LTXFormatError } from "../errors.js";
|
|
8
|
+
const FILENAME_RE = /^([0-9a-f]{16})-([0-9a-f]{16})\.ltx$/;
|
|
9
|
+
/** FormatFilename returns an LTX filename representing a TXID range. */
|
|
10
|
+
export function formatFilename(minTXID, maxTXID) {
|
|
11
|
+
return `${formatTXID(minTXID)}-${formatTXID(maxTXID)}.ltx`;
|
|
12
|
+
}
|
|
13
|
+
/** ParseFilename parses a transaction range from an LTX filename. */
|
|
14
|
+
export function parseFilename(name) {
|
|
15
|
+
const m = FILENAME_RE.exec(name);
|
|
16
|
+
if (m === null) {
|
|
17
|
+
throw new LTXFormatError(`invalid ltx filename: ${name}`);
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
minTXID: BigInt(`0x${m[1]}`),
|
|
21
|
+
maxTXID: BigInt(`0x${m[2]}`),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LTX header frame marshalling.
|
|
3
|
+
*/
|
|
4
|
+
import type { Header } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* MarshalBinary encodes a header to its 100-byte representation.
|
|
7
|
+
*/
|
|
8
|
+
export declare function marshalHeader(h: Header): Uint8Array;
|
|
9
|
+
/**
|
|
10
|
+
* UnmarshalBinary decodes a header from a byte slice.
|
|
11
|
+
* Sets `version` from the magic and returns the header.
|
|
12
|
+
*/
|
|
13
|
+
export declare function unmarshalHeader(b: Uint8Array): Header;
|
|
14
|
+
/** Validate returns an error (thrown) if h is invalid. */
|
|
15
|
+
export declare function validateHeader(h: Header): void;
|
|
16
|
+
export declare function headerLockPgno(h: Header): number;
|
|
17
|
+
//# sourceMappingURL=header.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"header.d.ts","sourceRoot":"","sources":["../../src/ltx/header.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAKzC;;GAEG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,UAAU,CAgBnD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAqBrD;AAMD,0DAA0D;AAC1D,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAoD9C;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEhD"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LTX header frame marshalling.
|
|
3
|
+
*/
|
|
4
|
+
import { HeaderSize, Magic, Version } from "./constants.js";
|
|
5
|
+
import { ChecksumFlag, isValidHeaderFlags, isValidPageSize, } from "./constants.js";
|
|
6
|
+
import { assertFull, readU32BE, readU64BE, writeU32BE, writeU64BE } from "./bytes.js";
|
|
7
|
+
import { isSnapshot } from "./types.js";
|
|
8
|
+
import { lockPgno } from "./constants.js";
|
|
9
|
+
import { LTXFormatError } from "../errors.js";
|
|
10
|
+
/**
|
|
11
|
+
* MarshalBinary encodes a header to its 100-byte representation.
|
|
12
|
+
*/
|
|
13
|
+
export function marshalHeader(h) {
|
|
14
|
+
const b = new Uint8Array(HeaderSize);
|
|
15
|
+
for (let i = 0; i < 4; i++)
|
|
16
|
+
b[i] = Magic.charCodeAt(i);
|
|
17
|
+
writeU32BE(b, 4, h.flags);
|
|
18
|
+
writeU32BE(b, 8, h.pageSize);
|
|
19
|
+
writeU32BE(b, 12, h.commit);
|
|
20
|
+
writeU64BE(b, 16, h.minTXID);
|
|
21
|
+
writeU64BE(b, 24, h.maxTXID);
|
|
22
|
+
writeU64BE(b, 32, h.timestamp);
|
|
23
|
+
writeU64BE(b, 40, h.preApplyChecksum);
|
|
24
|
+
writeU64BE(b, 48, h.walOffset);
|
|
25
|
+
writeU64BE(b, 56, h.walSize);
|
|
26
|
+
writeU32BE(b, 64, h.walSalt1);
|
|
27
|
+
writeU32BE(b, 68, h.walSalt2);
|
|
28
|
+
writeU64BE(b, 72, h.nodeID);
|
|
29
|
+
return b;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* UnmarshalBinary decodes a header from a byte slice.
|
|
33
|
+
* Sets `version` from the magic and returns the header.
|
|
34
|
+
*/
|
|
35
|
+
export function unmarshalHeader(b) {
|
|
36
|
+
assertFull(b, 0, HeaderSize);
|
|
37
|
+
const magic = String.fromCharCode(b[0], b[1], b[2], b[3]);
|
|
38
|
+
if (magic !== Magic) {
|
|
39
|
+
throw new LTXFormatError('invalid LTX file');
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
version: Version,
|
|
43
|
+
flags: readU32BE(b, 4),
|
|
44
|
+
pageSize: readU32BE(b, 8),
|
|
45
|
+
commit: readU32BE(b, 12),
|
|
46
|
+
minTXID: readU64BE(b, 16),
|
|
47
|
+
maxTXID: readU64BE(b, 24),
|
|
48
|
+
timestamp: readU64BE(b, 32),
|
|
49
|
+
preApplyChecksum: readU64BE(b, 40),
|
|
50
|
+
walOffset: readU64BE(b, 48),
|
|
51
|
+
walSize: readU64BE(b, 56),
|
|
52
|
+
walSalt1: readU32BE(b, 64),
|
|
53
|
+
walSalt2: readU32BE(b, 68),
|
|
54
|
+
nodeID: readU64BE(b, 72),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function noChecksum(flags) {
|
|
58
|
+
return (flags & 0x00000002) !== 0;
|
|
59
|
+
}
|
|
60
|
+
/** Validate returns an error (thrown) if h is invalid. */
|
|
61
|
+
export function validateHeader(h) {
|
|
62
|
+
if (h.version !== Version) {
|
|
63
|
+
throw new LTXFormatError('invalid version');
|
|
64
|
+
}
|
|
65
|
+
if (!isValidHeaderFlags(h.flags)) {
|
|
66
|
+
throw new LTXFormatError(`invalid flags: 0x${h.flags.toString(16)}`);
|
|
67
|
+
}
|
|
68
|
+
if (!isValidPageSize(h.pageSize)) {
|
|
69
|
+
throw new LTXFormatError(`invalid page size: ${h.pageSize}`);
|
|
70
|
+
}
|
|
71
|
+
if (h.minTXID === 0n) {
|
|
72
|
+
throw new LTXFormatError('minimum transaction id required');
|
|
73
|
+
}
|
|
74
|
+
if (h.maxTXID === 0n) {
|
|
75
|
+
throw new LTXFormatError('maximum transaction id required');
|
|
76
|
+
}
|
|
77
|
+
if (h.minTXID > h.maxTXID) {
|
|
78
|
+
throw new LTXFormatError(`transaction ids out of order: (${h.minTXID},${h.maxTXID})`);
|
|
79
|
+
}
|
|
80
|
+
if (h.walOffset < 0n) {
|
|
81
|
+
throw new LTXFormatError(`wal offset cannot be negative: ${h.walOffset}`);
|
|
82
|
+
}
|
|
83
|
+
if (h.walSize < 0n) {
|
|
84
|
+
throw new LTXFormatError(`wal size cannot be negative: ${h.walSize}`);
|
|
85
|
+
}
|
|
86
|
+
if ((h.walSalt1 !== 0 || h.walSalt2 !== 0) && h.walOffset === 0n) {
|
|
87
|
+
throw new LTXFormatError('wal offset required if salt exists');
|
|
88
|
+
}
|
|
89
|
+
if (h.walOffset === 0n && h.walSize !== 0n) {
|
|
90
|
+
throw new LTXFormatError('wal offset required if wal size exists');
|
|
91
|
+
}
|
|
92
|
+
const snap = isSnapshot(h);
|
|
93
|
+
const nc = noChecksum(h.flags);
|
|
94
|
+
if (snap) {
|
|
95
|
+
if (h.preApplyChecksum !== 0n) {
|
|
96
|
+
throw new LTXFormatError('pre-apply checksum must be zero on snapshots');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else if (nc) {
|
|
100
|
+
if (h.preApplyChecksum !== 0n) {
|
|
101
|
+
throw new LTXFormatError('pre-apply checksum not allowed');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
if (h.preApplyChecksum === 0n) {
|
|
106
|
+
throw new LTXFormatError('pre-apply checksum required on non-snapshot files');
|
|
107
|
+
}
|
|
108
|
+
if ((h.preApplyChecksum & ChecksumFlag) === 0n) {
|
|
109
|
+
throw new LTXFormatError('invalid pre-apply checksum format');
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
export function headerLockPgno(h) {
|
|
114
|
+
return lockPgno(h.pageSize);
|
|
115
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LTX format module — public surface for reading/writing LTX files.
|
|
3
|
+
*/
|
|
4
|
+
export * from './constants.js';
|
|
5
|
+
export * from './types.js';
|
|
6
|
+
export * from './crc64.js';
|
|
7
|
+
export * from './checksum.js';
|
|
8
|
+
export * from './bytes.js';
|
|
9
|
+
export * from './byte-reader.js';
|
|
10
|
+
export * from './filename.js';
|
|
11
|
+
export * from './page-index.js';
|
|
12
|
+
export * from './header.js';
|
|
13
|
+
export * from './page.js';
|
|
14
|
+
export * from './trailer.js';
|
|
15
|
+
export * from './sink.js';
|
|
16
|
+
export * from './encoder.js';
|
|
17
|
+
export * from './decoder.js';
|
|
18
|
+
export * from './stream.js';
|
|
19
|
+
export * from './compactor.js';
|
|
20
|
+
export * from './streaming-compactor.js';
|
|
21
|
+
export * from './file-info.js';
|
|
22
|
+
export * from './compaction-level.js';
|
|
23
|
+
export { compressBlock, decompressBlock } from './lz4.js';
|
|
24
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ltx/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AAItC,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LTX format module — public surface for reading/writing LTX files.
|
|
3
|
+
*/
|
|
4
|
+
export * from "./constants.js";
|
|
5
|
+
export * from "./types.js";
|
|
6
|
+
export * from "./crc64.js";
|
|
7
|
+
export * from "./checksum.js";
|
|
8
|
+
export * from "./bytes.js";
|
|
9
|
+
export * from "./byte-reader.js";
|
|
10
|
+
export * from "./filename.js";
|
|
11
|
+
export * from "./page-index.js";
|
|
12
|
+
export * from "./header.js";
|
|
13
|
+
export * from "./page.js";
|
|
14
|
+
export * from "./trailer.js";
|
|
15
|
+
export * from "./sink.js";
|
|
16
|
+
export * from "./encoder.js";
|
|
17
|
+
export * from "./decoder.js";
|
|
18
|
+
export * from "./stream.js";
|
|
19
|
+
export * from "./compactor.js";
|
|
20
|
+
export * from "./streaming-compactor.js";
|
|
21
|
+
export * from "./file-info.js";
|
|
22
|
+
export * from "./compaction-level.js";
|
|
23
|
+
// LZ4 block codec is internal (not part of the public LTX surface) but
|
|
24
|
+
// exposed for the WAL/DB layers.
|
|
25
|
+
export { compressBlock, decompressBlock } from "./lz4.js";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LZ4 block-codec adapter.
|
|
3
|
+
*
|
|
4
|
+
* The LTX format uses LZ4 **block** format (not frame format), matching Go's
|
|
5
|
+
* `github.com/pierrec/lz4/v4` `CompressBlock`/`UncompressBlock`.
|
|
6
|
+
*
|
|
7
|
+
* `compressBlock` is a direct TypeScript port of `pierrec/lz4/v4`'s internal
|
|
8
|
+
* `lz4block.Compressor.CompressBlock` (the default Fast compressor used by
|
|
9
|
+
* litestream). It is **byte-identical** to Go's output for the same input, so
|
|
10
|
+
* LTX files we write match Go's `superfly/ltx` encoder exactly (validated
|
|
11
|
+
* against the Go fixtures in `test/ltx/go-interop.test.ts` and CI's
|
|
12
|
+
* `interop-go` job).
|
|
13
|
+
*
|
|
14
|
+
* `decompressBlock`/`decompressBlockInto` delegate to the pure-JS `lz4js`
|
|
15
|
+
* implementation, which decodes any conforming LZ4 block (decompression does
|
|
16
|
+
* not need to be byte-identical).
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* compressBlockBound returns the maximum compressed size for `n` input bytes
|
|
20
|
+
* using the Fast compressor (`n + n/255 + 16`).
|
|
21
|
+
*/
|
|
22
|
+
export declare function compressBlockBound(n: number): number;
|
|
23
|
+
/**
|
|
24
|
+
* compressBlock compresses `data` as a Fast-mode LZ4 block and returns the
|
|
25
|
+
* compressed bytes. The result is byte-identical to Go's `pierrec/lz4/v4`
|
|
26
|
+
* `CompressBlock` for the same input.
|
|
27
|
+
*/
|
|
28
|
+
export declare function compressBlock(data: Uint8Array): Uint8Array;
|
|
29
|
+
/**
|
|
30
|
+
* decompressBlock decompresses an LZ4 block into a buffer of exactly
|
|
31
|
+
* `uncompressedSize` bytes. Throws if the block is invalid or produces a
|
|
32
|
+
* different size.
|
|
33
|
+
*/
|
|
34
|
+
export declare function decompressBlock(data: Uint8Array, uncompressedSize: number): Uint8Array;
|
|
35
|
+
/**
|
|
36
|
+
* decompressBlockInto decompresses an LZ4 block into `dst` and returns the
|
|
37
|
+
* number of bytes written. Does not require knowing the uncompressed size
|
|
38
|
+
* ahead of time.
|
|
39
|
+
*/
|
|
40
|
+
export declare function decompressBlockInto(data: Uint8Array, dst: Uint8Array): number;
|
|
41
|
+
//# sourceMappingURL=lz4.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lz4.d.ts","sourceRoot":"","sources":["../../src/ltx/lz4.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAqBH;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEpD;AA2MD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAI1D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,GAAG,UAAU,CAOtF;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,GAAG,MAAM,CAE7E"}
|