@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 @@
|
|
|
1
|
+
{"version":3,"file":"replica-client.d.ts","sourceRoot":"","sources":["../../../src/backends/file/replica-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EAKL,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,QAAQ,EAAU,MAAM,oBAAoB,CAAC;AAI3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAKnD,eAAO,MAAM,iBAAiB,SAAS,CAAC;AAExC,+DAA+D;AAC/D,qBAAa,iBAAkB,YAAW,aAAa;IACrD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAsB;gBAExB,IAAI,EAAE,MAAM;IAIxB,IAAI,IAAI,MAAM;IAIR,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI/B,yCAAyC;IACzC,IAAI,IAAI,MAAM;IAId,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAIlC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAI7D,QAAQ,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE,GAAG,aAAa,CAAC,QAAQ,CAAC;IAyC/F,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAqBxD,YAAY,CAAC,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,aAAa,CAAC,UAAU,GAAG,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC;IAiEpG,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBhD,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;CAOjC;AAED,2EAA2E;AAC3E,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,eAAe,GAAG,IAAI,EAC9B,SAAS,EAAE,MAAM,GAAG,IAAI,GACvB,aAAa,CAKf"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File replica client — replicates LTX files to a local directory.
|
|
3
|
+
*
|
|
4
|
+
* Layout: `<root>/ltx/<level>/<minTXID>-<maxTXID>.ltx`
|
|
5
|
+
* Writes are atomic: data is streamed to a `.tmp` file, fsync'd, then renamed,
|
|
6
|
+
* the directory is fsync'd, and the file mtime is set from the LTX header
|
|
7
|
+
* timestamp to preserve original creation time.
|
|
8
|
+
*/
|
|
9
|
+
import { createReadStream } from 'node:fs';
|
|
10
|
+
import { open, readdir, rename, rm, stat, utimes } from 'node:fs/promises';
|
|
11
|
+
import nodePath from 'node:path';
|
|
12
|
+
import { Readable } from 'node:stream';
|
|
13
|
+
import { ltxFilePath as sharedLTXFilePath, ltxLevelDir as sharedLTXLevelDir, LTXError, parseFilename, } from "../../replica-client.js";
|
|
14
|
+
import { HeaderSize, unmarshalHeader } from "../../ltx/index.js";
|
|
15
|
+
import { concatBytes } from "../../util/stream.js";
|
|
16
|
+
import { fsyncDir, mkdirAll } from "../../util/fs.js";
|
|
17
|
+
import { FileReplicaError, InvalidArgumentError } from "../../errors.js";
|
|
18
|
+
import { noopLogger } from "../../util/logger.js";
|
|
19
|
+
import { registerReplicaClientFactory } from "../../replica-url.js";
|
|
20
|
+
export const ReplicaClientType = 'file';
|
|
21
|
+
/** FileReplicaClient writes LTX files to a local directory. */
|
|
22
|
+
export class FileReplicaClient {
|
|
23
|
+
pathVal;
|
|
24
|
+
logger = noopLogger;
|
|
25
|
+
constructor(path) {
|
|
26
|
+
this.pathVal = path;
|
|
27
|
+
}
|
|
28
|
+
type() {
|
|
29
|
+
return ReplicaClientType;
|
|
30
|
+
}
|
|
31
|
+
async init() {
|
|
32
|
+
/* no initialization required */
|
|
33
|
+
}
|
|
34
|
+
setLogger(logger) {
|
|
35
|
+
this.logger = logger;
|
|
36
|
+
}
|
|
37
|
+
/** Returns the destination root path. */
|
|
38
|
+
path() {
|
|
39
|
+
return this.pathVal;
|
|
40
|
+
}
|
|
41
|
+
ltxLevelDir(level) {
|
|
42
|
+
return sharedLTXLevelDir(this.pathVal, level);
|
|
43
|
+
}
|
|
44
|
+
ltxFilePath(level, minTXID, maxTXID) {
|
|
45
|
+
return sharedLTXFilePath(this.pathVal, level, minTXID, maxTXID);
|
|
46
|
+
}
|
|
47
|
+
async *ltxFiles(opts) {
|
|
48
|
+
const dir = this.ltxLevelDir(opts.level);
|
|
49
|
+
let entries;
|
|
50
|
+
try {
|
|
51
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
if (err.code === 'ENOENT')
|
|
55
|
+
return;
|
|
56
|
+
throw err;
|
|
57
|
+
}
|
|
58
|
+
const infos = [];
|
|
59
|
+
for (const entry of entries) {
|
|
60
|
+
if (!entry.isFile())
|
|
61
|
+
continue;
|
|
62
|
+
let minTXID;
|
|
63
|
+
let maxTXID;
|
|
64
|
+
try {
|
|
65
|
+
({ minTXID, maxTXID } = parseFilename(entry.name));
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
continue; // skip non-conforming files
|
|
69
|
+
}
|
|
70
|
+
if (minTXID < opts.seek)
|
|
71
|
+
continue;
|
|
72
|
+
const full = nodePath.join(dir, entry.name);
|
|
73
|
+
const st = await stat(full);
|
|
74
|
+
infos.push({
|
|
75
|
+
level: opts.level,
|
|
76
|
+
minTXID,
|
|
77
|
+
maxTXID,
|
|
78
|
+
size: st.size,
|
|
79
|
+
createdAt: st.mtimeMs,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
infos.sort((a, b) => {
|
|
83
|
+
if (a.minTXID !== b.minTXID)
|
|
84
|
+
return a.minTXID < b.minTXID ? -1 : 1;
|
|
85
|
+
return a.maxTXID < b.maxTXID ? -1 : a.maxTXID > b.maxTXID ? 1 : 0;
|
|
86
|
+
});
|
|
87
|
+
for (const info of infos)
|
|
88
|
+
yield info;
|
|
89
|
+
}
|
|
90
|
+
async openLtxFile(opts) {
|
|
91
|
+
const p = this.ltxFilePath(opts.level, opts.minTXID, opts.maxTXID);
|
|
92
|
+
let st;
|
|
93
|
+
try {
|
|
94
|
+
st = await stat(p);
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
throw new LTXError('open', p, opts.level, opts.minTXID, opts.maxTXID, err);
|
|
98
|
+
}
|
|
99
|
+
if (opts.offset >= st.size) {
|
|
100
|
+
return Readable.from([]);
|
|
101
|
+
}
|
|
102
|
+
const end = opts.size > 0
|
|
103
|
+
? Math.min(opts.offset + opts.size - 1, st.size - 1)
|
|
104
|
+
: st.size - 1;
|
|
105
|
+
return createReadStream(p, { start: opts.offset, end });
|
|
106
|
+
}
|
|
107
|
+
async writeLtxFile(opts, body) {
|
|
108
|
+
const dir = this.ltxLevelDir(opts.level);
|
|
109
|
+
await mkdirAll(dir);
|
|
110
|
+
const filename = this.ltxFilePath(opts.level, opts.minTXID, opts.maxTXID);
|
|
111
|
+
const tmp = `${filename}.tmp`;
|
|
112
|
+
let fh = null;
|
|
113
|
+
try {
|
|
114
|
+
fh = await open(tmp, 'w');
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
throw new LTXError('create', tmp, opts.level, opts.minTXID, opts.maxTXID, err);
|
|
118
|
+
}
|
|
119
|
+
let headerBytes = null;
|
|
120
|
+
let collected = [];
|
|
121
|
+
let collectedLen = 0;
|
|
122
|
+
let size = 0;
|
|
123
|
+
try {
|
|
124
|
+
for await (const chunk of body) {
|
|
125
|
+
const bytes = typeof chunk === 'string' ? new TextEncoder().encode(chunk) : Uint8Array.from(chunk);
|
|
126
|
+
if (headerBytes === null) {
|
|
127
|
+
collected.push(bytes);
|
|
128
|
+
collectedLen += bytes.length;
|
|
129
|
+
if (collectedLen >= HeaderSize) {
|
|
130
|
+
const concat = concatBytes(collected);
|
|
131
|
+
headerBytes = concat.subarray(0, HeaderSize);
|
|
132
|
+
collected = [];
|
|
133
|
+
collectedLen = 0;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
await writeAll(fh, bytes);
|
|
137
|
+
size += bytes.length;
|
|
138
|
+
}
|
|
139
|
+
if (headerBytes === null) {
|
|
140
|
+
throw new FileReplicaError('write ltx file: input too short to contain a header');
|
|
141
|
+
}
|
|
142
|
+
const hdr = unmarshalHeader(headerBytes);
|
|
143
|
+
const timestamp = Number(hdr.timestamp);
|
|
144
|
+
await fh.sync();
|
|
145
|
+
await fh.close();
|
|
146
|
+
fh = null;
|
|
147
|
+
await rename(tmp, filename);
|
|
148
|
+
await fsyncDir(dir);
|
|
149
|
+
await utimes(filename, new Date(timestamp), new Date(timestamp));
|
|
150
|
+
return {
|
|
151
|
+
level: opts.level,
|
|
152
|
+
minTXID: opts.minTXID,
|
|
153
|
+
maxTXID: opts.maxTXID,
|
|
154
|
+
size,
|
|
155
|
+
createdAt: timestamp,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
if (fh !== null)
|
|
160
|
+
await fh.close().catch(() => { });
|
|
161
|
+
await rm(tmp, { force: true }).catch(() => { });
|
|
162
|
+
throw err;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
async deleteLtxFiles(infos) {
|
|
166
|
+
for (const info of infos) {
|
|
167
|
+
const p = this.ltxFilePath(info.level, info.minTXID, info.maxTXID);
|
|
168
|
+
this.logger.debug('deleting ltx file', {
|
|
169
|
+
level: info.level,
|
|
170
|
+
minTXID: info.minTXID,
|
|
171
|
+
maxTXID: info.maxTXID,
|
|
172
|
+
path: p,
|
|
173
|
+
});
|
|
174
|
+
try {
|
|
175
|
+
await rm(p);
|
|
176
|
+
}
|
|
177
|
+
catch (err) {
|
|
178
|
+
if (err.code !== 'ENOENT')
|
|
179
|
+
throw err;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
async deleteAll() {
|
|
184
|
+
try {
|
|
185
|
+
await rm(this.pathVal, { recursive: true, force: true });
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
if (err.code !== 'ENOENT')
|
|
189
|
+
throw err;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/** NewReplicaClientFromURL creates a FileReplicaClient from a URL path. */
|
|
194
|
+
export function NewReplicaClientFromURL(_scheme, _host, urlPath, _query, _userinfo) {
|
|
195
|
+
if (!urlPath) {
|
|
196
|
+
throw new InvalidArgumentError('file replica path required');
|
|
197
|
+
}
|
|
198
|
+
return new FileReplicaClient(urlPath);
|
|
199
|
+
}
|
|
200
|
+
// Mirrors Go's init(): register the file factory when this module loads.
|
|
201
|
+
registerReplicaClientFactory('file', NewReplicaClientFromURL);
|
|
202
|
+
/** Writes all of `bytes` to a FileHandle, handling partial writes. */
|
|
203
|
+
async function writeAll(handle, bytes) {
|
|
204
|
+
let offset = 0;
|
|
205
|
+
while (offset < bytes.length) {
|
|
206
|
+
const { bytesWritten } = await handle.write(bytes, offset, bytes.length - offset);
|
|
207
|
+
offset += bytesWritten;
|
|
208
|
+
}
|
|
209
|
+
}
|
package/dist/db.d.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LocalDatabase is the internal engine that reads a SQLite database and its
|
|
3
|
+
* `-wal` file and writes LTX files into a local cache (`<path>-litestream/ltx/`).
|
|
4
|
+
*
|
|
5
|
+
* It is deliberately NOT part of the public API: `Replica`/`Store` take a
|
|
6
|
+
* database `path` and read directly, so the library is agnostic to whatever
|
|
7
|
+
* SQLite driver the application uses. To keep snapshots consistent, it holds a
|
|
8
|
+
* short-lived **read-only** `node:sqlite` read transaction that pins the WAL
|
|
9
|
+
* (SQLite will not checkpoint/truncate the WAL past an active reader), while
|
|
10
|
+
* reading the database + WAL files directly.
|
|
11
|
+
*/
|
|
12
|
+
import { type FileInfo } from './ltx/index.js';
|
|
13
|
+
/**
|
|
14
|
+
* LocalDatabase reads a database + WAL from disk, tracks the local replicated
|
|
15
|
+
* position, and builds LTX files in the local cache.
|
|
16
|
+
*/
|
|
17
|
+
export declare class LocalDatabase {
|
|
18
|
+
readonly path: string;
|
|
19
|
+
readonly metaPath: string;
|
|
20
|
+
readonly pageSize: number;
|
|
21
|
+
private conn;
|
|
22
|
+
private constructor();
|
|
23
|
+
/**
|
|
24
|
+
* Open opens a local database reader for `path`. It does not create the
|
|
25
|
+
* database — the application owns it. `pageSize` is read from the database
|
|
26
|
+
* header; a missing file falls back to the default page size.
|
|
27
|
+
*/
|
|
28
|
+
static open(path: string): Promise<LocalDatabase>;
|
|
29
|
+
/** WalPath returns the path to the database's WAL file. */
|
|
30
|
+
walPath(): string;
|
|
31
|
+
/** LTXDir returns the local LTX root directory. */
|
|
32
|
+
ltxDir(): string;
|
|
33
|
+
/** LTXLevelDir returns the local LTX directory for a level. */
|
|
34
|
+
ltxLevelDir(level: number): string;
|
|
35
|
+
/** LTXPath returns the local path of a single LTX file. */
|
|
36
|
+
ltxPath(level: number, minTXID: bigint, maxTXID: bigint): string;
|
|
37
|
+
/** Lists local level-0 LTX files, sorted by TXID. */
|
|
38
|
+
l0Files(): Promise<FileInfo[]>;
|
|
39
|
+
/** Lists local LTX files for any level, sorted by TXID. */
|
|
40
|
+
filesForLevel(level: number): Promise<FileInfo[]>;
|
|
41
|
+
/** Pos returns the maximum TXID in the local level-0 cache (0 if none). */
|
|
42
|
+
pos(): Promise<bigint>;
|
|
43
|
+
/** Returns the local LTX file with the highest maxTXID across all levels. */
|
|
44
|
+
private maxFile;
|
|
45
|
+
/**
|
|
46
|
+
* Opens (and caches) a read-only connection used to hold a snapshot during
|
|
47
|
+
* sync/snapshot. Not part of the public API; the DB file must exist.
|
|
48
|
+
*/
|
|
49
|
+
private ensureConn;
|
|
50
|
+
/**
|
|
51
|
+
* Pins a WAL snapshot by starting a read transaction and issuing a read that
|
|
52
|
+
* touches the database (a plain `SELECT 1` does not acquire the WAL read lock).
|
|
53
|
+
*/
|
|
54
|
+
private beginRead;
|
|
55
|
+
/** Releases the pinned read snapshot. */
|
|
56
|
+
private commitRead;
|
|
57
|
+
/** Current committed database size, in pages (as seen by the pinned reader). */
|
|
58
|
+
private pageCount;
|
|
59
|
+
/** Sync builds a level-0 LTX file and writes it to the local cache. */
|
|
60
|
+
sync(): Promise<FileInfo | null>;
|
|
61
|
+
/** Writes a full snapshot: every committed page, preferring WAL pages. */
|
|
62
|
+
private writePagesFromDB;
|
|
63
|
+
/** Writes an incremental file: changed WAL pages + DB growth pages. */
|
|
64
|
+
private writePagesFromWAL;
|
|
65
|
+
/**
|
|
66
|
+
* Snapshot writes a full-database LTX file at `SnapshotLevel` (9) with
|
|
67
|
+
* MinTXID=1 and MaxTXID equal to the current local position. Returns null if
|
|
68
|
+
* a snapshot would cover no data (empty database).
|
|
69
|
+
*/
|
|
70
|
+
snapshot(): Promise<FileInfo | null>;
|
|
71
|
+
/** Reads a single page, preferring the WAL over the database file. */
|
|
72
|
+
private readPage;
|
|
73
|
+
/** Reads the WAL file bytes, returning empty if it does not exist. */
|
|
74
|
+
private readWalOrEmpty;
|
|
75
|
+
/** Decodes the header of the max-TXID local L0 file (or null if none). */
|
|
76
|
+
private prevSyncInfo;
|
|
77
|
+
/** Close releases the internal read-only connection. */
|
|
78
|
+
close(): void;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=db.d.ts.map
|
package/dist/db.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,EAQL,KAAK,QAAQ,EAEd,MAAM,gBAAgB,CAAC;AAoBxB;;;GAGG;AACH,qBAAa,aAAa;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,IAAI,CAA6B;IAEzC,OAAO;IAMP;;;;OAIG;WACU,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAkBvD,2DAA2D;IAC3D,OAAO,IAAI,MAAM;IAIjB,mDAAmD;IACnD,MAAM,IAAI,MAAM;IAIhB,+DAA+D;IAC/D,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAIlC,2DAA2D;IAC3D,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAIhE,qDAAqD;IAC/C,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAIpC,2DAA2D;IACrD,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IA0BvD,2EAA2E;IACrE,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;IAK5B,6EAA6E;YAC/D,OAAO;IAUrB;;;OAGG;IACH,OAAO,CAAC,UAAU;IAQlB;;;OAGG;IACH,OAAO,CAAC,SAAS;IAMjB,yCAAyC;IACzC,OAAO,CAAC,UAAU;IAMlB,gFAAgF;IAChF,OAAO,CAAC,SAAS;IAKjB,uEAAuE;IACjE,IAAI,IAAI,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAwHtC,0EAA0E;YAC5D,gBAAgB;IAe9B,uEAAuE;YACzD,iBAAiB;IAoC/B;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAmF1C,sEAAsE;YACxD,QAAQ;IAiBtB,sEAAsE;YACxD,cAAc;IAQ5B,0EAA0E;YAC5D,YAAY;IAiC1B,wDAAwD;IACxD,KAAK,IAAI,IAAI;CAMd"}
|