lens-content-processor 0.79.0 → 0.80.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authoring-markup.d.ts +22 -0
- package/dist/authoring-markup.js +24 -0
- package/dist/authoring-markup.js.map +1 -1
- package/dist/cache.d.ts +10 -0
- package/dist/cache.js +6 -5
- package/dist/cache.js.map +1 -1
- package/dist/cli-steps.d.ts +37 -0
- package/dist/cli-steps.js +80 -0
- package/dist/cli-steps.js.map +1 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.js +52 -70
- package/dist/cli.js.map +1 -1
- package/dist/course-graph.d.ts +2 -2
- package/dist/course-graph.js +7 -2
- package/dist/course-graph.js.map +1 -1
- package/dist/criticmarkup-forms.d.ts +8 -6
- package/dist/criticmarkup-forms.js +22 -19
- package/dist/criticmarkup-forms.js.map +1 -1
- package/dist/dedupe-errors.d.ts +16 -0
- package/dist/dedupe-errors.js +23 -9
- package/dist/dedupe-errors.js.map +1 -1
- package/dist/dependency-cache.d.ts +15 -5
- package/dist/dependency-cache.js +33 -74
- package/dist/dependency-cache.js.map +1 -1
- package/dist/dropped.d.ts +114 -0
- package/dist/dropped.js +253 -0
- package/dist/dropped.js.map +1 -0
- package/dist/engine/assemble.d.ts +44 -0
- package/dist/engine/assemble.js +132 -0
- package/dist/engine/assemble.js.map +1 -0
- package/dist/engine/build.d.ts +8 -0
- package/dist/engine/build.js +558 -0
- package/dist/engine/build.js.map +1 -0
- package/dist/engine/file-facts.d.ts +26 -0
- package/dist/engine/file-facts.js +63 -0
- package/dist/engine/file-facts.js.map +1 -0
- package/dist/engine/git-source.d.ts +35 -0
- package/dist/engine/git-source.js +242 -0
- package/dist/engine/git-source.js.map +1 -0
- package/dist/engine/overlay.d.ts +43 -0
- package/dist/engine/overlay.js +167 -0
- package/dist/engine/overlay.js.map +1 -0
- package/dist/engine/protocol.d.ts +146 -0
- package/dist/engine/protocol.js +40 -0
- package/dist/engine/protocol.js.map +1 -0
- package/dist/engine/reader.d.ts +133 -0
- package/dist/engine/reader.js +298 -0
- package/dist/engine/reader.js.map +1 -0
- package/dist/engine/sources.d.ts +39 -0
- package/dist/engine/sources.js +137 -0
- package/dist/engine/sources.js.map +1 -0
- package/dist/engine/sqlite-store.d.ts +99 -0
- package/dist/engine/sqlite-store.js +452 -0
- package/dist/engine/sqlite-store.js.map +1 -0
- package/dist/engine/store.d.ts +85 -0
- package/dist/engine/store.js +31 -0
- package/dist/engine/store.js.map +1 -0
- package/dist/engine/tables.d.ts +15 -0
- package/dist/engine/tables.js +70 -0
- package/dist/engine/tables.js.map +1 -0
- package/dist/engine/units.d.ts +58 -0
- package/dist/engine/units.js +186 -0
- package/dist/engine/units.js.map +1 -0
- package/dist/engine/version.d.ts +6 -0
- package/dist/engine/version.js +21 -0
- package/dist/engine/version.js.map +1 -0
- package/dist/engine/worker.d.ts +1 -0
- package/dist/engine/worker.js +220 -0
- package/dist/engine/worker.js.map +1 -0
- package/dist/flattener/index.d.ts +34 -17
- package/dist/flattener/index.js +245 -114
- package/dist/flattener/index.js.map +1 -1
- package/dist/flattener/resolve-text-links.d.ts +15 -14
- package/dist/flattener/resolve-text-links.js +24 -25
- package/dist/flattener/resolve-text-links.js.map +1 -1
- package/dist/glossary.d.ts +2 -2
- package/dist/glossary.js.map +1 -1
- package/dist/index.d.ts +168 -2
- package/dist/index.js +883 -639
- package/dist/index.js.map +1 -1
- package/dist/markdown-parse.d.ts +6 -0
- package/dist/markdown-parse.js +14 -0
- package/dist/markdown-parse.js.map +1 -1
- package/dist/parser/learning-outcome.js +11 -2
- package/dist/parser/learning-outcome.js.map +1 -1
- package/dist/parser/lens.d.ts +5 -1
- package/dist/parser/lens.js +22 -7
- package/dist/parser/lens.js.map +1 -1
- package/dist/parser/meeting-doc.d.ts +2 -1
- package/dist/parser/meeting-doc.js +2 -1
- package/dist/parser/meeting-doc.js.map +1 -1
- package/dist/parser/module.d.ts +3 -1
- package/dist/parser/module.js +7 -5
- package/dist/parser/module.js.map +1 -1
- package/dist/parser/question-embeds.d.ts +4 -3
- package/dist/parser/question-embeds.js.map +1 -1
- package/dist/parser/sections.d.ts +10 -0
- package/dist/parser/sections.js +8 -3
- package/dist/parser/sections.js.map +1 -1
- package/dist/parser/widget.d.ts +2 -1
- package/dist/parser/widget.js.map +1 -1
- package/dist/parser/wikilink.d.ts +13 -3
- package/dist/parser/wikilink.js +55 -34
- package/dist/parser/wikilink.js.map +1 -1
- package/dist/reference-graph.d.ts +21 -3
- package/dist/reference-graph.js +35 -12
- package/dist/reference-graph.js.map +1 -1
- package/dist/same-page-links.d.ts +11 -1
- package/dist/same-page-links.js +9 -0
- package/dist/same-page-links.js.map +1 -1
- package/dist/skill-tree.d.ts +2 -1
- package/dist/skill-tree.js.map +1 -1
- package/dist/source-location.d.ts +0 -4
- package/dist/source-location.js +0 -43
- package/dist/source-location.js.map +1 -1
- package/dist/validator/card-module-membership.d.ts +17 -1
- package/dist/validator/card-module-membership.js +60 -56
- package/dist/validator/card-module-membership.js.map +1 -1
- package/dist/validator/criticmarkup.js +1 -1
- package/dist/validator/criticmarkup.js.map +1 -1
- package/dist/validator/field-typos.d.ts +1 -1
- package/dist/validator/field-typos.js +21 -21
- package/dist/validator/field-typos.js.map +1 -1
- package/dist/validator/output-integrity.d.ts +9 -5
- package/dist/validator/output-integrity.js +43 -45
- package/dist/validator/output-integrity.js.map +1 -1
- package/dist/validator/tier.d.ts +2 -2
- package/dist/validator/tier.js.map +1 -1
- package/dist/validator/uuid.d.ts +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
// The build layer on disk: a BuildStore in one SQLite file per validator version.
|
|
2
|
+
// SCHEMA below is what the platform's Python reads.
|
|
3
|
+
//
|
|
4
|
+
// Library: better-sqlite3 12.9.0, a devDependency, loaded on the first open, never at
|
|
5
|
+
// import time. The platform image runs Debian 13's Node 20.19, which has no node:sqlite
|
|
6
|
+
// (Node 22.13+), and 12.9.0 is the last release with prebuilt binaries for Node 20;
|
|
7
|
+
// later releases compile from source, which the slim image cannot. The npm package
|
|
8
|
+
// never installs it. The store uses only prepare/exec/close and run/get/all, so on
|
|
9
|
+
// Node 22+ node:sqlite can replace it by changing loadDriver() (and inTransaction,
|
|
10
|
+
// which node:sqlite calls isTransaction).
|
|
11
|
+
//
|
|
12
|
+
// Writes are batched: the first write opens a transaction, which commits after
|
|
13
|
+
// BATCH_WRITES writes or BATCH_MS ms (checked at each write and each setRunning), on
|
|
14
|
+
// commit() and on close(), but never inside atomically(), so writes that must agree
|
|
15
|
+
// (a unit's record and the pages it made) are committed together. A killed job keeps
|
|
16
|
+
// all but its last batch. A failed write rolls its batch back and the store then
|
|
17
|
+
// refuses writes (a Showstopper: the job fails), so a half-applied batch is never
|
|
18
|
+
// committed. WAL with synchronous=NORMAL: a commit survives the death of the
|
|
19
|
+
// process, which blame and skip needs, but not a power cut; the platform's disk is
|
|
20
|
+
// emptied on every deploy anyway.
|
|
21
|
+
//
|
|
22
|
+
// The running unit (blame and skip, worker.ts) is one line in the file
|
|
23
|
+
// `<store>-running`: the JSON string of the unit id, or null. It is rewritten in
|
|
24
|
+
// place, not a row: a row would commit the whole batch before every unit.
|
|
25
|
+
import { closeSync, ftruncateSync, mkdirSync, openSync, readFileSync, readdirSync, rmSync, writeSync, } from "fs";
|
|
26
|
+
import { createRequire } from "module";
|
|
27
|
+
import { basename, dirname, join } from "path";
|
|
28
|
+
import { deflateSync, inflateSync } from "zlib";
|
|
29
|
+
import { Showstopper } from "./units.js";
|
|
30
|
+
import { NO_ARTIFACT, artifactHash, artifactMetaKey, comparePages, } from "./store.js";
|
|
31
|
+
const SCHEMA_VERSION = "1";
|
|
32
|
+
/** Commit a batch after this many writes... */
|
|
33
|
+
export const BATCH_WRITES = 1000;
|
|
34
|
+
/** ...or once it is this old. A killed job loses at most this much finished work. */
|
|
35
|
+
export const BATCH_MS = 1000;
|
|
36
|
+
/** Level 1: 2.6× smaller page JSON at 1.2 s per 135 MB; level 6 is 3.1× at 4.0 s (measured, 5 Oct). */
|
|
37
|
+
const ZLIB_LEVEL = 1;
|
|
38
|
+
let driver;
|
|
39
|
+
function loadDriver() {
|
|
40
|
+
if (!driver) {
|
|
41
|
+
try {
|
|
42
|
+
driver = createRequire(import.meta.url)("better-sqlite3");
|
|
43
|
+
new driver(":memory:").close(); // a wrong binary fails here, not mid-job
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
driver = undefined;
|
|
47
|
+
throw new Error("The SQLite build layer needs better-sqlite3 (a devDependency of " +
|
|
48
|
+
"content_processor; the npm package does not install it). Run `npm ci` in " +
|
|
49
|
+
`content_processor, or use the store ":memory:". Cause: ${error}`, { cause: error });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return driver;
|
|
53
|
+
}
|
|
54
|
+
/** The store file for a validator version: `<dir>/build-<version>.sqlite`. */
|
|
55
|
+
export function storePathFor(dir, version) {
|
|
56
|
+
return join(dir, `build-${version}.sqlite`);
|
|
57
|
+
}
|
|
58
|
+
const STORE_SUFFIXES = ["", "-wal", "-shm", "-journal", "-running"];
|
|
59
|
+
const STORE_NAME = /^build-.+\.sqlite$/;
|
|
60
|
+
/** Delete a store file and the files SQLite and the running record keep beside it. */
|
|
61
|
+
export function removeStoreFiles(path) {
|
|
62
|
+
for (const suffix of STORE_SUFFIXES)
|
|
63
|
+
rmSync(path + suffix, { force: true });
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Delete every other `build-*.sqlite` store in the directory of `path`, once the
|
|
67
|
+
* store at `path` is complete. Returns the names of the stores removed. Does
|
|
68
|
+
* nothing when `path` itself is not named `build-*.sqlite`.
|
|
69
|
+
*/
|
|
70
|
+
export function removeOtherStores(path) {
|
|
71
|
+
const keep = basename(path);
|
|
72
|
+
if (!STORE_NAME.test(keep))
|
|
73
|
+
return [];
|
|
74
|
+
const removed = readdirSync(dirname(path)).filter((name) => STORE_NAME.test(name) && name !== keep);
|
|
75
|
+
for (const name of removed)
|
|
76
|
+
removeStoreFiles(join(dirname(path), name));
|
|
77
|
+
return removed;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* SQLite's answer when a file is not a database or its structure is broken,
|
|
81
|
+
* also when it is the cause of the error the store threw in its place.
|
|
82
|
+
*/
|
|
83
|
+
export function isDamagedStoreError(error) {
|
|
84
|
+
for (let e = error; e; e = e.cause) {
|
|
85
|
+
const code = e.code;
|
|
86
|
+
if (typeof code === "string" &&
|
|
87
|
+
(code === "SQLITE_NOTADB" || code.startsWith("SQLITE_CORRUPT")))
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
// The schema, version 1. A reader such as the platform's Python needs only the
|
|
93
|
+
// standard library: a BLOB is zlib (RFC 1950, level 1) of UTF-8 JSON text,
|
|
94
|
+
// zlib.decompress(blob).decode("utf-8"), and WAL mode gives it the last
|
|
95
|
+
// committed state while the worker writes. Canonical page order is by
|
|
96
|
+
// source_path in UTF-16 code-unit order (JavaScript's), then idx. SQL's ORDER BY
|
|
97
|
+
// compares UTF-8 bytes, which differs only for a character above U+FFFF, so
|
|
98
|
+
// Python sorts by (source_path.encode("utf-16-be"), idx). What a reader applies
|
|
99
|
+
// after a job: protocol.ts.
|
|
100
|
+
const SCHEMA = `
|
|
101
|
+
-- "schema" = "1", "validatorVersion", "commit" (git sources), the engine's own
|
|
102
|
+
-- "engine:*" keys, and "artifact:<name>": the SHA-1 (hex) of that artifact's
|
|
103
|
+
-- JSON text, or "-" once it is removed, written with its artifacts row
|
|
104
|
+
CREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT NOT NULL) WITHOUT ROWID;
|
|
105
|
+
-- content path -> Git blob id
|
|
106
|
+
CREATE TABLE IF NOT EXISTS files (path TEXT PRIMARY KEY, version TEXT NOT NULL) WITHOUT ROWID;
|
|
107
|
+
-- id: "path:<file>", "flat:<file>#<i>" or "page:<file>#<i>" (units.ts)
|
|
108
|
+
CREATE TABLE IF NOT EXISTS units (id TEXT PRIMARY KEY, output BLOB NOT NULL);
|
|
109
|
+
-- each unit's recorded reads, in the order it made them; reads_by_key is the
|
|
110
|
+
-- reverse index: SELECT DISTINCT unit FROM reads WHERE key = ?
|
|
111
|
+
CREATE TABLE IF NOT EXISTS reads (
|
|
112
|
+
unit TEXT NOT NULL, seq INTEGER NOT NULL, key TEXT NOT NULL, version TEXT NOT NULL,
|
|
113
|
+
PRIMARY KEY (unit, seq)) WITHOUT ROWID;
|
|
114
|
+
CREATE INDEX IF NOT EXISTS reads_by_key ON reads (key);
|
|
115
|
+
-- hash: the SHA-1 (hex) of the page's JSON text
|
|
116
|
+
CREATE TABLE IF NOT EXISTS pages (
|
|
117
|
+
source_path TEXT NOT NULL, idx INTEGER NOT NULL, slug TEXT NOT NULL,
|
|
118
|
+
hash TEXT NOT NULL, json BLOB NOT NULL, PRIMARY KEY (source_path, idx));
|
|
119
|
+
CREATE TABLE IF NOT EXISTS artifacts (name TEXT PRIMARY KEY, json BLOB NOT NULL);
|
|
120
|
+
-- reason: "timeout", "memory" or "crash", or the message of an error the unit threw
|
|
121
|
+
CREATE TABLE IF NOT EXISTS failed_units (unit TEXT PRIMARY KEY, reason TEXT NOT NULL) WITHOUT ROWID;
|
|
122
|
+
`;
|
|
123
|
+
/** Every statement the store runs, prepared once per connection. */
|
|
124
|
+
const SQL = {
|
|
125
|
+
getMeta: "SELECT value FROM meta WHERE key = ?",
|
|
126
|
+
setMeta: "INSERT OR REPLACE INTO meta VALUES (?, ?)",
|
|
127
|
+
files: "SELECT path, version FROM files",
|
|
128
|
+
setFile: "INSERT OR REPLACE INTO files VALUES (?, ?)",
|
|
129
|
+
deleteFile: "DELETE FROM files WHERE path = ?",
|
|
130
|
+
getUnit: "SELECT output FROM units WHERE id = ?",
|
|
131
|
+
getReads: "SELECT key, version FROM reads WHERE unit = ? ORDER BY seq",
|
|
132
|
+
unitIds: "SELECT id FROM units",
|
|
133
|
+
putUnit: "INSERT OR REPLACE INTO units VALUES (?, ?)",
|
|
134
|
+
putRead: "INSERT INTO reads VALUES (?, ?, ?, ?)",
|
|
135
|
+
deleteUnit: "DELETE FROM units WHERE id = ?",
|
|
136
|
+
deleteReads: "DELETE FROM reads WHERE unit = ?",
|
|
137
|
+
readers: "SELECT unit FROM reads WHERE key = ?",
|
|
138
|
+
pages: "SELECT source_path, idx, slug, hash FROM pages",
|
|
139
|
+
getPage: "SELECT slug, hash, json FROM pages WHERE source_path = ? AND idx = ?",
|
|
140
|
+
putPage: "INSERT OR REPLACE INTO pages VALUES (?, ?, ?, ?, ?)",
|
|
141
|
+
deletePage: "DELETE FROM pages WHERE source_path = ? AND idx = ?",
|
|
142
|
+
getArtifact: "SELECT json FROM artifacts WHERE name = ?",
|
|
143
|
+
putArtifact: "INSERT OR REPLACE INTO artifacts VALUES (?, ?)",
|
|
144
|
+
deleteArtifact: "DELETE FROM artifacts WHERE name = ?",
|
|
145
|
+
failed: "SELECT unit, reason FROM failed_units",
|
|
146
|
+
setFailed: "INSERT OR REPLACE INTO failed_units VALUES (?, ?)",
|
|
147
|
+
clearFailed: "DELETE FROM failed_units WHERE unit = ?",
|
|
148
|
+
};
|
|
149
|
+
function pack(json) {
|
|
150
|
+
return deflateSync(Buffer.from(json, "utf-8"), { level: ZLIB_LEVEL });
|
|
151
|
+
}
|
|
152
|
+
function unpack(blob) {
|
|
153
|
+
return inflateSync(blob).toString("utf-8");
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Open the store at `path`. A missing, damaged or foreign file (another schema or
|
|
157
|
+
* validator version) is replaced by an empty store, whose `fresh` is true: the next
|
|
158
|
+
* job builds everything. With `readonly`, such a file is an error instead.
|
|
159
|
+
*/
|
|
160
|
+
export function openSqliteStore(path, options = {}) {
|
|
161
|
+
const Driver = loadDriver();
|
|
162
|
+
if (options.readonly) {
|
|
163
|
+
const db = new Driver(path, { readonly: true, fileMustExist: true });
|
|
164
|
+
try {
|
|
165
|
+
db.exec("PRAGMA busy_timeout = 10000");
|
|
166
|
+
checkMeta(db, options.version, path);
|
|
167
|
+
db.exec("BEGIN");
|
|
168
|
+
db.prepare("SELECT 1 FROM meta LIMIT 1").get(); // the snapshot starts at the first read
|
|
169
|
+
return new SqliteStore(db, path, false, true);
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
db.close();
|
|
173
|
+
throw error;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
177
|
+
let fresh = false;
|
|
178
|
+
for (;;) {
|
|
179
|
+
let db;
|
|
180
|
+
try {
|
|
181
|
+
db = new Driver(path);
|
|
182
|
+
db.exec("PRAGMA journal_mode = WAL");
|
|
183
|
+
db.exec("PRAGMA synchronous = NORMAL");
|
|
184
|
+
db.exec("PRAGMA busy_timeout = 10000");
|
|
185
|
+
db.exec("PRAGMA journal_size_limit = 67108864");
|
|
186
|
+
const tables = db
|
|
187
|
+
.prepare("SELECT count(*) AS n FROM sqlite_master WHERE name = 'meta'")
|
|
188
|
+
.get();
|
|
189
|
+
if (tables.n === 0) {
|
|
190
|
+
db.exec(SCHEMA);
|
|
191
|
+
const set = db.prepare("INSERT INTO meta VALUES (?, ?)");
|
|
192
|
+
set.run("schema", SCHEMA_VERSION);
|
|
193
|
+
if (options.version)
|
|
194
|
+
set.run("validatorVersion", options.version);
|
|
195
|
+
fresh = true;
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
checkMeta(db, options.version, path);
|
|
199
|
+
}
|
|
200
|
+
return new SqliteStore(db, path, fresh, false);
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
db?.close();
|
|
204
|
+
if (fresh ||
|
|
205
|
+
!(isDamagedStoreError(error) || error instanceof ForeignStore))
|
|
206
|
+
throw error;
|
|
207
|
+
removeStoreFiles(path);
|
|
208
|
+
fresh = true;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
export class SqliteStore {
|
|
213
|
+
path;
|
|
214
|
+
readonly;
|
|
215
|
+
/** True when openSqliteStore started an empty store: the file was missing, damaged or foreign. */
|
|
216
|
+
fresh;
|
|
217
|
+
db;
|
|
218
|
+
q;
|
|
219
|
+
pending = 0;
|
|
220
|
+
batchStarted = 0;
|
|
221
|
+
/** Depth of atomically() calls: no batch commits while it is above 0. */
|
|
222
|
+
holding = 0;
|
|
223
|
+
runningFd;
|
|
224
|
+
closed = false;
|
|
225
|
+
/** The error of a write that failed; the store refuses to write after one. */
|
|
226
|
+
failure;
|
|
227
|
+
/** Use openSqliteStore. */
|
|
228
|
+
constructor(db, path, fresh, readonly) {
|
|
229
|
+
this.path = path;
|
|
230
|
+
this.readonly = readonly;
|
|
231
|
+
this.db = db;
|
|
232
|
+
this.fresh = fresh;
|
|
233
|
+
this.q = Object.fromEntries(Object.entries(SQL).map(([name, text]) => [name, db.prepare(text)]));
|
|
234
|
+
}
|
|
235
|
+
getMeta(key) {
|
|
236
|
+
const row = this.q.getMeta.get(key);
|
|
237
|
+
return row?.value;
|
|
238
|
+
}
|
|
239
|
+
setMeta(key, value) {
|
|
240
|
+
this.write(() => this.q.setMeta.run(key, value));
|
|
241
|
+
}
|
|
242
|
+
getFileVersions() {
|
|
243
|
+
const rows = this.q.files.all();
|
|
244
|
+
return new Map(rows.map((row) => [row.path, row.version]));
|
|
245
|
+
}
|
|
246
|
+
setFileVersion(path, version) {
|
|
247
|
+
this.write(() => version === null
|
|
248
|
+
? this.q.deleteFile.run(path)
|
|
249
|
+
: this.q.setFile.run(path, version));
|
|
250
|
+
}
|
|
251
|
+
getUnit(id) {
|
|
252
|
+
const row = this.q.getUnit.get(id);
|
|
253
|
+
if (!row)
|
|
254
|
+
return undefined;
|
|
255
|
+
const reads = this.q.getReads.all(id);
|
|
256
|
+
return { id, reads, output: JSON.parse(unpack(row.output)) };
|
|
257
|
+
}
|
|
258
|
+
listUnitIds(prefix = "") {
|
|
259
|
+
const ids = this.q.unitIds.all().map((r) => r.id);
|
|
260
|
+
return ids.filter((id) => id.startsWith(prefix)).sort();
|
|
261
|
+
}
|
|
262
|
+
putUnit(record) {
|
|
263
|
+
const json = JSON.stringify(record.output);
|
|
264
|
+
if (json === undefined)
|
|
265
|
+
throw new Error(`unit ${record.id}: output is not JSON-serialisable`);
|
|
266
|
+
const output = pack(json);
|
|
267
|
+
this.write(() => {
|
|
268
|
+
this.q.deleteReads.run(record.id);
|
|
269
|
+
this.q.putUnit.run(record.id, output);
|
|
270
|
+
record.reads.forEach(({ key, version }, seq) => this.q.putRead.run(record.id, seq, key, version));
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
deleteUnit(id) {
|
|
274
|
+
this.write(() => {
|
|
275
|
+
this.q.deleteUnit.run(id);
|
|
276
|
+
this.q.deleteReads.run(id);
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
unitsReading(keys) {
|
|
280
|
+
const ids = new Set();
|
|
281
|
+
for (const key of keys)
|
|
282
|
+
for (const row of this.q.readers.all(key))
|
|
283
|
+
ids.add(row.unit);
|
|
284
|
+
return [...ids].sort();
|
|
285
|
+
}
|
|
286
|
+
listPages() {
|
|
287
|
+
const rows = this.q.pages.all();
|
|
288
|
+
return rows
|
|
289
|
+
.map((row) => ({
|
|
290
|
+
sourcePath: row.source_path,
|
|
291
|
+
index: row.idx,
|
|
292
|
+
slug: row.slug,
|
|
293
|
+
hash: row.hash,
|
|
294
|
+
}))
|
|
295
|
+
.sort(comparePages);
|
|
296
|
+
}
|
|
297
|
+
getPage(sourcePath, index) {
|
|
298
|
+
const row = this.q.getPage.get(sourcePath, index);
|
|
299
|
+
if (!row)
|
|
300
|
+
return undefined;
|
|
301
|
+
const { slug, hash } = row;
|
|
302
|
+
return { sourcePath, index, slug, hash, json: unpack(row.json) };
|
|
303
|
+
}
|
|
304
|
+
putPage(page) {
|
|
305
|
+
const json = pack(page.json);
|
|
306
|
+
this.write(() => this.q.putPage.run(page.sourcePath, page.index, page.slug, page.hash, json));
|
|
307
|
+
}
|
|
308
|
+
deletePage(sourcePath, index) {
|
|
309
|
+
this.write(() => this.q.deletePage.run(sourcePath, index));
|
|
310
|
+
}
|
|
311
|
+
getArtifact(name) {
|
|
312
|
+
const row = this.q.getArtifact.get(name);
|
|
313
|
+
return row && unpack(row.json);
|
|
314
|
+
}
|
|
315
|
+
getArtifactHash(name) {
|
|
316
|
+
return this.getMeta(artifactMetaKey(name)) ?? NO_ARTIFACT;
|
|
317
|
+
}
|
|
318
|
+
// The artifact and its hash go in one write, so no batch commit falls between them.
|
|
319
|
+
putArtifact(name, json) {
|
|
320
|
+
const packed = pack(json);
|
|
321
|
+
this.write(() => {
|
|
322
|
+
this.q.putArtifact.run(name, packed);
|
|
323
|
+
this.q.setMeta.run(artifactMetaKey(name), artifactHash(json));
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
deleteArtifact(name) {
|
|
327
|
+
this.write(() => {
|
|
328
|
+
this.q.deleteArtifact.run(name);
|
|
329
|
+
this.q.setMeta.run(artifactMetaKey(name), NO_ARTIFACT);
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
setRunning(unitId) {
|
|
333
|
+
if (this.readonly)
|
|
334
|
+
throw new Error(`${this.path} is open read-only`);
|
|
335
|
+
this.commitIfDue();
|
|
336
|
+
const line = Buffer.from(`${JSON.stringify(unitId)}\n`);
|
|
337
|
+
this.runningFd ??= openSync(`${this.path}-running`, "w");
|
|
338
|
+
writeSync(this.runningFd, line, 0, line.length, 0);
|
|
339
|
+
ftruncateSync(this.runningFd, line.length);
|
|
340
|
+
}
|
|
341
|
+
getRunning() {
|
|
342
|
+
let text;
|
|
343
|
+
try {
|
|
344
|
+
text = readFileSync(`${this.path}-running`, "utf-8");
|
|
345
|
+
}
|
|
346
|
+
catch (error) {
|
|
347
|
+
if (error.code === "ENOENT")
|
|
348
|
+
return null;
|
|
349
|
+
throw error;
|
|
350
|
+
}
|
|
351
|
+
const end = text.indexOf("\n");
|
|
352
|
+
return end < 0 ? null : JSON.parse(text.slice(0, end));
|
|
353
|
+
}
|
|
354
|
+
getFailedUnits() {
|
|
355
|
+
const rows = this.q.failed.all();
|
|
356
|
+
return new Map(rows.map((row) => [row.unit, row.reason]));
|
|
357
|
+
}
|
|
358
|
+
setFailedUnit(unitId, reason) {
|
|
359
|
+
this.write(() => reason === null
|
|
360
|
+
? this.q.clearFailed.run(unitId)
|
|
361
|
+
: this.q.setFailed.run(unitId, reason));
|
|
362
|
+
}
|
|
363
|
+
commit() {
|
|
364
|
+
this.refuseAfterFailure();
|
|
365
|
+
if (!this.readonly && this.db.inTransaction)
|
|
366
|
+
this.db.exec("COMMIT");
|
|
367
|
+
this.pending = 0;
|
|
368
|
+
}
|
|
369
|
+
atomically(apply) {
|
|
370
|
+
this.holding++;
|
|
371
|
+
try {
|
|
372
|
+
return apply();
|
|
373
|
+
}
|
|
374
|
+
finally {
|
|
375
|
+
this.holding--;
|
|
376
|
+
this.commitIfDue();
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
close() {
|
|
380
|
+
if (this.closed)
|
|
381
|
+
return;
|
|
382
|
+
this.closed = true;
|
|
383
|
+
try {
|
|
384
|
+
if (this.readonly || this.failure !== undefined) {
|
|
385
|
+
if (this.db.inTransaction)
|
|
386
|
+
this.db.exec("ROLLBACK");
|
|
387
|
+
}
|
|
388
|
+
else
|
|
389
|
+
this.commit();
|
|
390
|
+
}
|
|
391
|
+
finally {
|
|
392
|
+
if (this.runningFd !== undefined)
|
|
393
|
+
closeSync(this.runningFd);
|
|
394
|
+
this.db.close();
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
/** Run one write inside the current batch, opening one if needed; commit when the batch is due. */
|
|
398
|
+
write(apply) {
|
|
399
|
+
if (this.readonly)
|
|
400
|
+
throw new Error(`${this.path} is open read-only`);
|
|
401
|
+
this.refuseAfterFailure();
|
|
402
|
+
try {
|
|
403
|
+
if (!this.db.inTransaction) {
|
|
404
|
+
this.db.exec("BEGIN IMMEDIATE");
|
|
405
|
+
this.batchStarted = Date.now();
|
|
406
|
+
this.pending = 0;
|
|
407
|
+
}
|
|
408
|
+
apply();
|
|
409
|
+
}
|
|
410
|
+
catch (error) {
|
|
411
|
+
this.failure = error;
|
|
412
|
+
this.pending = 0;
|
|
413
|
+
if (this.db.inTransaction)
|
|
414
|
+
this.db.exec("ROLLBACK");
|
|
415
|
+
throw new Showstopper(`${this.path}: a write failed: ${error}`, {
|
|
416
|
+
cause: error,
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
this.pending++;
|
|
420
|
+
this.commitIfDue();
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* The one batch rule: commit after BATCH_WRITES writes or once the batch is
|
|
424
|
+
* BATCH_MS old, but never inside atomically(), and never after a failed write.
|
|
425
|
+
*/
|
|
426
|
+
commitIfDue() {
|
|
427
|
+
if (this.holding === 0 &&
|
|
428
|
+
this.failure === undefined &&
|
|
429
|
+
this.pending > 0 &&
|
|
430
|
+
(this.pending >= BATCH_WRITES ||
|
|
431
|
+
Date.now() - this.batchStarted >= BATCH_MS))
|
|
432
|
+
this.commit();
|
|
433
|
+
}
|
|
434
|
+
refuseAfterFailure() {
|
|
435
|
+
if (this.failure !== undefined)
|
|
436
|
+
throw new Showstopper(`${this.path}: a write failed earlier in this job, so its batch was ` +
|
|
437
|
+
`rolled back and the store takes no more writes: ${this.failure}`, { cause: this.failure });
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
class ForeignStore extends Error {
|
|
441
|
+
}
|
|
442
|
+
/** Throw ForeignStore unless the file holds this schema (and this validator version, when given). */
|
|
443
|
+
function checkMeta(db, version, path) {
|
|
444
|
+
const get = (key) => db.prepare("SELECT value FROM meta WHERE key = ?").get(key)?.value;
|
|
445
|
+
const schema = get("schema");
|
|
446
|
+
if (schema !== SCHEMA_VERSION)
|
|
447
|
+
throw new ForeignStore(`${path}: schema ${schema}, expected ${SCHEMA_VERSION}`);
|
|
448
|
+
const stored = get("validatorVersion");
|
|
449
|
+
if (version && stored !== version)
|
|
450
|
+
throw new ForeignStore(`${path}: built by validator ${stored}, not ${version}`);
|
|
451
|
+
}
|
|
452
|
+
//# sourceMappingURL=sqlite-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-store.js","sourceRoot":"","sources":["../../src/engine/sqlite-store.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,oDAAoD;AACpD,EAAE;AACF,sFAAsF;AACtF,wFAAwF;AACxF,oFAAoF;AACpF,mFAAmF;AACnF,mFAAmF;AACnF,mFAAmF;AACnF,0CAA0C;AAC1C,EAAE;AACF,+EAA+E;AAC/E,qFAAqF;AACrF,oFAAoF;AACpF,qFAAqF;AACrF,iFAAiF;AACjF,kFAAkF;AAClF,6EAA6E;AAC7E,mFAAmF;AACnF,kCAAkC;AAClC,EAAE;AACF,uEAAuE;AACvE,iFAAiF;AACjF,0EAA0E;AAE1E,OAAO,EACL,SAAS,EACT,aAAa,EACb,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,MAAM,EACN,SAAS,GACV,MAAM,IAAI,CAAC;AACZ,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EACL,WAAW,EACX,YAAY,EACZ,eAAe,EACf,YAAY,GAKb,MAAM,YAAY,CAAC;AAEpB,MAAM,cAAc,GAAG,GAAG,CAAC;AAC3B,+CAA+C;AAC/C,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,CAAC;AACjC,qFAAqF;AACrF,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC;AAC7B,uGAAuG;AACvG,MAAM,UAAU,GAAG,CAAC,CAAC;AAmBrB,IAAI,MAAuC,CAAC;AAE5C,SAAS,UAAU;IACjB,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,IAAI,CAAC;YACH,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CACrC,gBAAgB,CACM,CAAC;YACzB,IAAI,MAAM,CAAC,UAAU,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,yCAAyC;QAC3E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,GAAG,SAAS,CAAC;YACnB,MAAM,IAAI,KAAK,CACb,kEAAkE;gBAChE,2EAA2E;gBAC3E,0DAA0D,KAAK,EAAE,EACnE,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,OAAe;IACvD,OAAO,IAAI,CAAC,GAAG,EAAE,SAAS,OAAO,SAAS,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,cAAc,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AACpE,MAAM,UAAU,GAAG,oBAAoB,CAAC;AAExC,sFAAsF;AACtF,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,KAAK,MAAM,MAAM,IAAI,cAAc;QAAE,MAAM,CAAC,IAAI,GAAG,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AAC9E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACtC,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAC/C,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,KAAK,IAAI,CACjD,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,OAAO;QAAE,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IACxE,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,CAAC,GAAI,CAAyB,CAAC,KAAK,EAAE,CAAC;QAC5D,MAAM,IAAI,GAAI,CAAwB,CAAC,IAAI,CAAC;QAC5C,IACE,OAAO,IAAI,KAAK,QAAQ;YACxB,CAAC,IAAI,KAAK,eAAe,IAAI,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;YAE/D,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAaD,+EAA+E;AAC/E,2EAA2E;AAC3E,wEAAwE;AACxE,sEAAsE;AACtE,iFAAiF;AACjF,4EAA4E;AAC5E,gFAAgF;AAChF,4BAA4B;AAC5B,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;CAsBd,CAAC;AAEF,oEAAoE;AACpE,MAAM,GAAG,GAAG;IACV,OAAO,EAAE,sCAAsC;IAC/C,OAAO,EAAE,2CAA2C;IACpD,KAAK,EAAE,iCAAiC;IACxC,OAAO,EAAE,4CAA4C;IACrD,UAAU,EAAE,kCAAkC;IAC9C,OAAO,EAAE,uCAAuC;IAChD,QAAQ,EAAE,4DAA4D;IACtE,OAAO,EAAE,sBAAsB;IAC/B,OAAO,EAAE,4CAA4C;IACrD,OAAO,EAAE,uCAAuC;IAChD,UAAU,EAAE,gCAAgC;IAC5C,WAAW,EAAE,kCAAkC;IAC/C,OAAO,EAAE,sCAAsC;IAC/C,KAAK,EAAE,gDAAgD;IACvD,OAAO,EACL,sEAAsE;IACxE,OAAO,EAAE,qDAAqD;IAC9D,UAAU,EAAE,qDAAqD;IACjE,WAAW,EAAE,2CAA2C;IACxD,WAAW,EAAE,gDAAgD;IAC7D,cAAc,EAAE,sCAAsC;IACtD,MAAM,EAAE,uCAAuC;IAC/C,SAAS,EAAE,mDAAmD;IAC9D,WAAW,EAAE,yCAAyC;CACvD,CAAC;AAEF,SAAS,IAAI,CAAC,IAAY;IACxB,OAAO,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;AACxE,CAAC;AAED,SAAS,MAAM,CAAC,IAAgB;IAC9B,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAC7C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAY,EACZ,UAAuB,EAAE;IAEzB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACrE,IAAI,CAAC;YACH,EAAE,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;YACvC,SAAS,CAAC,EAAE,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACrC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACjB,EAAE,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,wCAAwC;YACxF,OAAO,IAAI,WAAW,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IACD,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,SAAS,CAAC;QACR,IAAI,EAAwB,CAAC;QAC7B,IAAI,CAAC;YACH,EAAE,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;YACtB,EAAE,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;YACrC,EAAE,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;YACvC,EAAE,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;YACvC,EAAE,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;YAChD,MAAM,MAAM,GAAG,EAAE;iBACd,OAAO,CAAC,6DAA6D,CAAC;iBACtE,GAAG,EAAmB,CAAC;YAC1B,IAAI,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;gBACnB,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAChB,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC;gBACzD,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;gBAClC,IAAI,OAAO,CAAC,OAAO;oBAAE,GAAG,CAAC,GAAG,CAAC,kBAAkB,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;gBAClE,KAAK,GAAG,IAAI,CAAC;YACf,CAAC;iBAAM,CAAC;gBACN,SAAS,CAAC,EAAE,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACvC,CAAC;YACD,OAAO,IAAI,WAAW,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,EAAE,EAAE,KAAK,EAAE,CAAC;YACZ,IACE,KAAK;gBACL,CAAC,CAAC,mBAAmB,CAAC,KAAK,CAAC,IAAI,KAAK,YAAY,YAAY,CAAC;gBAE9D,MAAM,KAAK,CAAC;YACd,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACvB,KAAK,GAAG,IAAI,CAAC;QACf,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,OAAO,WAAW;IAiBH;IAEA;IAlBnB,kGAAkG;IACzF,KAAK,CAAU;IACP,EAAE,CAAW;IACb,CAAC,CAAsC;IAChD,OAAO,GAAG,CAAC,CAAC;IACZ,YAAY,GAAG,CAAC,CAAC;IACzB,yEAAyE;IACjE,OAAO,GAAG,CAAC,CAAC;IACZ,SAAS,CAAqB;IAC9B,MAAM,GAAG,KAAK,CAAC;IACvB,8EAA8E;IACtE,OAAO,CAAU;IAEzB,2BAA2B;IAC3B,YACE,EAAY,EACK,IAAY,EAC7B,KAAc,EACG,QAAiB;QAFjB,SAAI,GAAJ,IAAI,CAAQ;QAEZ,aAAQ,GAAR,QAAQ,CAAS;QAElC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,WAAW,CACzB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAC7B,CAAC;IAC3C,CAAC;IAED,OAAO,CAAC,GAAW;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAkC,CAAC;QACrE,OAAO,GAAG,EAAE,KAAK,CAAC;IACpB,CAAC;IACD,OAAO,CAAC,GAAW,EAAE,KAAa;QAChC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,eAAe;QACb,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAyC,CAAC;QACvE,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC;IACD,cAAc,CAAC,IAAY,EAAE,OAAsB;QACjD,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CACd,OAAO,KAAK,IAAI;YACd,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;YAC7B,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CACtC,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,EAAU;QAChB,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAuC,CAAC;QACzE,IAAI,CAAC,GAAG;YAAE,OAAO,SAAS,CAAC;QAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAwB,CAAC;QAC7D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;IAC/D,CAAC;IACD,WAAW,CAAC,MAAM,GAAG,EAAE;QACrB,MAAM,GAAG,GAAI,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAuB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACxE,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1D,CAAC;IACD,OAAO,CAAC,MAAkB;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3C,IAAI,IAAI,KAAK,SAAS;YACpB,MAAM,IAAI,KAAK,CAAC,QAAQ,MAAM,CAAC,EAAE,mCAAmC,CAAC,CAAC;QACxE,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAClC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YACtC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,EAAE,CAC7C,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,CACjD,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IACD,UAAU,CAAC,EAAU;QACnB,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC1B,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;IACL,CAAC;IACD,YAAY,CAAC,IAAsB;QACjC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;QAC9B,KAAK,MAAM,GAAG,IAAI,IAAI;YACpB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAuB;gBAC7D,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACtB,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACzB,CAAC;IAED,SAAS;QACP,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAK1B,CAAC;QACJ,OAAO,IAAI;aACR,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACb,UAAU,EAAE,GAAG,CAAC,WAAW;YAC3B,KAAK,EAAE,GAAG,CAAC,GAAG;YACd,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,IAAI,EAAE,GAAG,CAAC,IAAI;SACf,CAAC,CAAC;aACF,IAAI,CAAC,YAAY,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,CAAC,UAAkB,EAAE,KAAa;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,CAEnC,CAAC;QACd,IAAI,CAAC,GAAG;YAAE,OAAO,SAAS,CAAC;QAC3B,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC;QAC3B,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;IACnE,CAAC;IACD,OAAO,CAAC,IAAgB;QACtB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CACd,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAChB,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,IAAI,EACT,IAAI,CACL,CACF,CAAC;IACJ,CAAC;IACD,UAAU,CAAC,UAAkB,EAAE,KAAa;QAC1C,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;IAC7D,CAAC;IAED,WAAW,CAAC,IAAY;QACtB,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAE1B,CAAC;QACd,OAAO,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IACD,eAAe,CAAC,IAAY;QAC1B,OAAO,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,IAAI,WAAW,CAAC;IAC5D,CAAC;IACD,oFAAoF;IACpF,WAAW,CAAC,IAAY,EAAE,IAAY;QACpC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACrC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;IACL,CAAC;IACD,cAAc,CAAC,IAAY;QACzB,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;IACL,CAAC;IAED,UAAU,CAAC,MAAqB;QAC9B,IAAI,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,oBAAoB,CAAC,CAAC;QACrE,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxD,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,GAAG,IAAI,CAAC,IAAI,UAAU,EAAE,GAAG,CAAC,CAAC;QACzD,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACnD,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;IACD,UAAU;QACR,IAAI,IAAY,CAAC;QACjB,IAAI,CAAC;YACH,IAAI,GAAG,YAAY,CAAC,GAAG,IAAI,CAAC,IAAI,UAAU,EAAE,OAAO,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAC;YACpE,MAAM,KAAK,CAAC;QACd,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAmB,CAAC;IAC5E,CAAC;IACD,cAAc;QACZ,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,EAAwC,CAAC;QACvE,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC5D,CAAC;IACD,aAAa,CAAC,MAAc,EAAE,MAAqB;QACjD,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CACd,MAAM,KAAK,IAAI;YACb,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC;YAChC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CACzC,CAAC;IACJ,CAAC;IAED,MAAM;QACJ,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,EAAE,CAAC,aAAa;YAAE,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpE,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;IACnB,CAAC;IACD,UAAU,CAAI,KAAc;QAC1B,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,IAAI,CAAC;YACH,OAAO,KAAK,EAAE,CAAC;QACjB,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,CAAC;IACH,CAAC;IACD,KAAK;QACH,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;gBAChD,IAAI,IAAI,CAAC,EAAE,CAAC,aAAa;oBAAE,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACtD,CAAC;;gBAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,CAAC;gBAAS,CAAC;YACT,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;gBAAE,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC5D,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;QAClB,CAAC;IACH,CAAC;IAED,mGAAmG;IAC3F,KAAK,CAAC,KAAoB;QAChC,IAAI,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,oBAAoB,CAAC,CAAC;QACrE,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC;gBAC3B,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;gBAChC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC/B,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;YACnB,CAAC;YACD,KAAK,EAAE,CAAC;QACV,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;YACrB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;YACjB,IAAI,IAAI,CAAC,EAAE,CAAC,aAAa;gBAAE,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACpD,MAAM,IAAI,WAAW,CAAC,GAAG,IAAI,CAAC,IAAI,qBAAqB,KAAK,EAAE,EAAE;gBAC9D,KAAK,EAAE,KAAK;aACb,CAAC,CAAC;QACL,CAAC;QACD,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAED;;;OAGG;IACK,WAAW;QACjB,IACE,IAAI,CAAC,OAAO,KAAK,CAAC;YAClB,IAAI,CAAC,OAAO,KAAK,SAAS;YAC1B,IAAI,CAAC,OAAO,GAAG,CAAC;YAChB,CAAC,IAAI,CAAC,OAAO,IAAI,YAAY;gBAC3B,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,YAAY,IAAI,QAAQ,CAAC;YAE7C,IAAI,CAAC,MAAM,EAAE,CAAC;IAClB,CAAC;IAEO,kBAAkB;QACxB,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS;YAC5B,MAAM,IAAI,WAAW,CACnB,GAAG,IAAI,CAAC,IAAI,yDAAyD;gBACnE,mDAAmD,IAAI,CAAC,OAAO,EAAE,EACnE,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,CACxB,CAAC;IACN,CAAC;CACF;AAED,MAAM,YAAa,SAAQ,KAAK;CAAG;AAEnC,qGAAqG;AACrG,SAAS,SAAS,CAAC,EAAY,EAAE,OAA2B,EAAE,IAAY;IACxE,MAAM,GAAG,GAAG,CAAC,GAAW,EAAE,EAAE,CAExB,EAAE,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC,GAAG,CAAC,GAAG,CAG3D,EAAE,KAAK,CAAC;IACX,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC7B,IAAI,MAAM,KAAK,cAAc;QAC3B,MAAM,IAAI,YAAY,CACpB,GAAG,IAAI,YAAY,MAAM,cAAc,cAAc,EAAE,CACxD,CAAC;IACJ,MAAM,MAAM,GAAG,GAAG,CAAC,kBAAkB,CAAC,CAAC;IACvC,IAAI,OAAO,IAAI,MAAM,KAAK,OAAO;QAC/B,MAAM,IAAI,YAAY,CACpB,GAAG,IAAI,wBAAwB,MAAM,SAAS,OAAO,EAAE,CACxD,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/** One recorded read: a key such as `file:Lenses/X.md`, and the version the unit saw. */
|
|
2
|
+
export interface RecordedRead {
|
|
3
|
+
key: string;
|
|
4
|
+
version: string;
|
|
5
|
+
}
|
|
6
|
+
/** The stored result of one unit. */
|
|
7
|
+
export interface UnitRecord {
|
|
8
|
+
/** Unique id. The text before the first ":" names the unit kind, e.g. `path:Lenses/X.md`. */
|
|
9
|
+
id: string;
|
|
10
|
+
/** Every read the unit made, one entry per key. */
|
|
11
|
+
reads: RecordedRead[];
|
|
12
|
+
/** JSON-serialisable output, already encoded (units.ts encodeUnit). */
|
|
13
|
+
output: unknown;
|
|
14
|
+
}
|
|
15
|
+
/** One finished page: one entry of today's `modules` output array. */
|
|
16
|
+
export interface PageRecord {
|
|
17
|
+
/** The file the page comes from. Pages sort by (sourcePath, index): today's order. */
|
|
18
|
+
sourcePath: string;
|
|
19
|
+
/** Position of the page among the pages of its file (split modules have several). */
|
|
20
|
+
index: number;
|
|
21
|
+
slug: string;
|
|
22
|
+
/** Hash of `json`, so a reader can tell that a page changed without decoding it. */
|
|
23
|
+
hash: string;
|
|
24
|
+
/** The page exactly as today's output serialises it (JSON text, no indentation). */
|
|
25
|
+
json: string;
|
|
26
|
+
}
|
|
27
|
+
export type PageSummary = Omit<PageRecord, "json">;
|
|
28
|
+
export interface BuildStore {
|
|
29
|
+
getMeta(key: string): string | undefined;
|
|
30
|
+
setMeta(key: string, value: string): void;
|
|
31
|
+
/** The content this store holds results for: path → version (Git blob id). */
|
|
32
|
+
getFileVersions(): Map<string, string>;
|
|
33
|
+
/** Record a file's version; null removes the file. */
|
|
34
|
+
setFileVersion(path: string, version: string | null): void;
|
|
35
|
+
getUnit(id: string): UnitRecord | undefined;
|
|
36
|
+
/** Unit ids in sorted order, optionally only those that start with `prefix`. */
|
|
37
|
+
listUnitIds(prefix?: string): string[];
|
|
38
|
+
putUnit(record: UnitRecord): void;
|
|
39
|
+
deleteUnit(id: string): void;
|
|
40
|
+
/** Ids (sorted, unique) of the units that recorded a read of any of `keys`. */
|
|
41
|
+
unitsReading(keys: Iterable<string>): string[];
|
|
42
|
+
/** Every page, in canonical order, without its JSON. */
|
|
43
|
+
listPages(): PageSummary[];
|
|
44
|
+
getPage(sourcePath: string, index: number): PageRecord | undefined;
|
|
45
|
+
putPage(page: PageRecord): void;
|
|
46
|
+
deletePage(sourcePath: string, index: number): void;
|
|
47
|
+
/** Whole-content outputs by name ("errors", "courses", ...), as JSON text. */
|
|
48
|
+
getArtifact(name: string): string | undefined;
|
|
49
|
+
/** artifactHash of the stored JSON; NO_ARTIFACT when there is none. */
|
|
50
|
+
getArtifactHash(name: string): string;
|
|
51
|
+
/** Store the JSON and its hash (meta `artifact:<name>`) in one transaction. */
|
|
52
|
+
putArtifact(name: string, json: string): void;
|
|
53
|
+
/** Remove the artifact, and set its hash to NO_ARTIFACT in the same transaction. */
|
|
54
|
+
deleteArtifact(name: string): void;
|
|
55
|
+
/** The unit about to run, for blame and skip (worker.ts); durable when this returns. */
|
|
56
|
+
setRunning(unitId: string | null): void;
|
|
57
|
+
getRunning(): string | null;
|
|
58
|
+
/** Units that failed, with the reason; the engine skips them until they are due again (build.ts Units). */
|
|
59
|
+
getFailedUnits(): Map<string, string>;
|
|
60
|
+
setFailedUnit(unitId: string, reason: string | null): void;
|
|
61
|
+
/** Make every write since the last commit durable. A store may also commit on its own. */
|
|
62
|
+
commit(): void;
|
|
63
|
+
/**
|
|
64
|
+
* Run `apply`, whose writes become durable together or not at all: a store
|
|
65
|
+
* that commits on its own does not commit inside it.
|
|
66
|
+
*/
|
|
67
|
+
atomically<T>(apply: () => T): T;
|
|
68
|
+
close(): void;
|
|
69
|
+
}
|
|
70
|
+
/** A store that lives in one process: an overlay (overlay.ts) over no store. */
|
|
71
|
+
export { MemoryStore } from "./overlay.js";
|
|
72
|
+
/** The hash of an artifact's JSON text, as meta `artifact:<name>` holds it. */
|
|
73
|
+
export declare function artifactHash(json: string): string;
|
|
74
|
+
/** The hash of an artifact that is not stored. */
|
|
75
|
+
export declare const NO_ARTIFACT = "-";
|
|
76
|
+
/** The meta key that holds an artifact's hash: the platform reads them all (`artifact:*`). */
|
|
77
|
+
export declare function artifactMetaKey(name: string): string;
|
|
78
|
+
/** Canonical page order: by source path (code-unit order, as processContent sorts), then index. */
|
|
79
|
+
export declare function comparePages(a: {
|
|
80
|
+
sourcePath: string;
|
|
81
|
+
index: number;
|
|
82
|
+
}, b: {
|
|
83
|
+
sourcePath: string;
|
|
84
|
+
index: number;
|
|
85
|
+
}): number;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// The build layer: what the engine keeps between jobs.
|
|
2
|
+
//
|
|
3
|
+
// A store holds the result of every unit of the last build, every read each unit
|
|
4
|
+
// made (the reverse index: "which units read file X?"), and the outputs the
|
|
5
|
+
// platform reads (finished pages and whole-content artifacts). It depends only
|
|
6
|
+
// on the content and the validator version, so deleting it is always safe: the
|
|
7
|
+
// next job rebuilds it from scratch.
|
|
8
|
+
//
|
|
9
|
+
// Two implementations share this contract: MemoryStore (overlay.ts: one
|
|
10
|
+
// process, no disk; tests and the ":memory:" store) and the SQLite store on
|
|
11
|
+
// the platform's disk (sqlite-store.ts).
|
|
12
|
+
import { sha1 } from "./reader.js";
|
|
13
|
+
/** A store that lives in one process: an overlay (overlay.ts) over no store. */
|
|
14
|
+
export { MemoryStore } from "./overlay.js";
|
|
15
|
+
/** The hash of an artifact's JSON text, as meta `artifact:<name>` holds it. */
|
|
16
|
+
export function artifactHash(json) {
|
|
17
|
+
return sha1(json);
|
|
18
|
+
}
|
|
19
|
+
/** The hash of an artifact that is not stored. */
|
|
20
|
+
export const NO_ARTIFACT = "-";
|
|
21
|
+
/** The meta key that holds an artifact's hash: the platform reads them all (`artifact:*`). */
|
|
22
|
+
export function artifactMetaKey(name) {
|
|
23
|
+
return `artifact:${name}`;
|
|
24
|
+
}
|
|
25
|
+
/** Canonical page order: by source path (code-unit order, as processContent sorts), then index. */
|
|
26
|
+
export function comparePages(a, b) {
|
|
27
|
+
if (a.sourcePath !== b.sourcePath)
|
|
28
|
+
return a.sourcePath < b.sourcePath ? -1 : 1;
|
|
29
|
+
return a.index - b.index;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/engine/store.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,EAAE;AACF,iFAAiF;AACjF,4EAA4E;AAC5E,+EAA+E;AAC/E,+EAA+E;AAC/E,qCAAqC;AACrC,EAAE;AACF,wEAAwE;AACxE,4EAA4E;AAC5E,yCAAyC;AAEzC,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAkFnC,gFAAgF;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,+EAA+E;AAC/E,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC;AACpB,CAAC;AAED,kDAAkD;AAClD,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,CAAC;AAE/B,8FAA8F;AAC9F,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,YAAY,IAAI,EAAE,CAAC;AAC5B,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,YAAY,CAC1B,CAAwC,EACxC,CAAwC;IAExC,IAAI,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,UAAU;QAC/B,OAAO,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { FinishTables } from "../index.js";
|
|
2
|
+
import { type ReadLog, type Versions } from "./reader.js";
|
|
3
|
+
/** `tables` as views whose lookups `log` records. */
|
|
4
|
+
export declare function recordingTables(tables: FinishTables, log: ReadLog): FinishTables;
|
|
5
|
+
/** The versions of table read keys in one job's tables. */
|
|
6
|
+
export declare class TableVersions implements Versions {
|
|
7
|
+
private readonly tables;
|
|
8
|
+
private readonly memo;
|
|
9
|
+
constructor(tables: FinishTables);
|
|
10
|
+
/** True for a key that names a table entry. */
|
|
11
|
+
static owns(key: string): boolean;
|
|
12
|
+
versionOf(key: string): string;
|
|
13
|
+
/** Every entry's version, by read key: what the next job compares with. */
|
|
14
|
+
all(): Map<string, string>;
|
|
15
|
+
}
|