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,558 @@
|
|
|
1
|
+
// The incremental driver: one job brings the build layer up to date with a
|
|
2
|
+
// source, and reruns only the units whose reads changed.
|
|
3
|
+
//
|
|
4
|
+
// 1. Path units (runPathUnit), one per file. A job compares every file's
|
|
5
|
+
// version with the versions the build layer holds. The candidates are the
|
|
6
|
+
// units of changed and added files, and the units that recorded a read of
|
|
7
|
+
// anything a changed, added or removed file answers (its text, link facts,
|
|
8
|
+
// existence, tier and tags, the set of all paths, and the suggestions for
|
|
9
|
+
// broken links). Each stores its summary (path:) and its flattened pages
|
|
10
|
+
// (flat:).
|
|
11
|
+
// 2. The whole-content step (wholeContentStep), every job, over every unit's
|
|
12
|
+
// summary: the tables and the checks across files. It reads no page body.
|
|
13
|
+
// 3. Finish units (finishPage), one per page (page:). The candidates are the
|
|
14
|
+
// pages whose flattened page changed, and those that read a table entry,
|
|
15
|
+
// glossary entry, existence or tier whose version changed since the last
|
|
16
|
+
// job. Each starts from the stored flattened page and writes the finished
|
|
17
|
+
// page to the pages table.
|
|
18
|
+
// 4. The errors in today's order (assembleErrors), and the artifacts.
|
|
19
|
+
//
|
|
20
|
+
// A candidate runs again unless every read it recorded still has the version
|
|
21
|
+
// it saw, which also lets a job restarted after a kill keep the units it had
|
|
22
|
+
// committed. Path units read files; finish units read their flattened page,
|
|
23
|
+
// the tables and files. No unit reads another of its kind, so the dirty ones
|
|
24
|
+
// run in any order; they run in path (page) order.
|
|
25
|
+
//
|
|
26
|
+
// A job that stops part way (killed, or failed) leaves the build layer
|
|
27
|
+
// consistent for the next one:
|
|
28
|
+
// - A unit's record and what it made (its flattened pages, or its finished
|
|
29
|
+
// page) are written in one transaction.
|
|
30
|
+
// - The file versions, file facts and finish inputs that a job compares with
|
|
31
|
+
// are written at its end, so after a stop, unit records can be newer than
|
|
32
|
+
// them, and the content can go back to what they describe (an undone
|
|
33
|
+
// edit): then nothing "changed", yet those records are stale. A job that
|
|
34
|
+
// finds the last one unfinished (meta engine:job) checks every unit's reads.
|
|
35
|
+
// - A unit that fails is retried when an input it read before it failed
|
|
36
|
+
// changes (engine:failedReads), including one that never succeeded, and in
|
|
37
|
+
// a job with retryFailed.
|
|
38
|
+
// - A failure that is not about content (a Showstopper: the source or the
|
|
39
|
+
// build layer failed) ends the job instead of failing a unit.
|
|
40
|
+
import { finishPage, runPathUnit, summarizeUnit, wholeContentStep, } from "../index.js";
|
|
41
|
+
import { clearParsedMarkdown } from "../markdown-parse.js";
|
|
42
|
+
import { errorKey } from "../dedupe-errors.js";
|
|
43
|
+
import { assemble, writeFullOutput } from "./assemble.js";
|
|
44
|
+
import { FileFactsTable, fileFacts } from "./file-facts.js";
|
|
45
|
+
import { OverlayStore } from "./overlay.js";
|
|
46
|
+
import { ContentState, ReadLog, byPath, sha1, } from "./reader.js";
|
|
47
|
+
import { SourceTexts, draftsSource, overlaySource } from "./sources.js";
|
|
48
|
+
import { comparePages, } from "./store.js";
|
|
49
|
+
import { TableVersions, recordingTables } from "./tables.js";
|
|
50
|
+
import { Showstopper, UNIT_KINDS, decodeUnit, encodeUnit, flatIdOf, pageIdOf, pageKey, pageKeyOf, pathOfUnit, skippedPage, skippedUnit, splitPageKey, unitIdOf, } from "./units.js";
|
|
51
|
+
/** Engine state in the store's meta table (the artifacts table holds only outputs). */
|
|
52
|
+
const FILE_FACTS = "engine:fileFacts";
|
|
53
|
+
/** The version of every finish input (flat:, table:, glossary: keys) after the last job. */
|
|
54
|
+
const FINISH_INPUTS = "engine:finishInputs";
|
|
55
|
+
/** "running" from the start of a commit or cold job until its last write, then "done". */
|
|
56
|
+
const JOB_STATE = "engine:job";
|
|
57
|
+
/** What each failed unit read before it failed: unit id → reads. */
|
|
58
|
+
const FAILED_READS = "engine:failedReads";
|
|
59
|
+
/**
|
|
60
|
+
* A unit that fails keeps its last good result, so its pages stop updating
|
|
61
|
+
* and its file shows an error: degradable, however many there are. A unit
|
|
62
|
+
* that fails with no last good result leaves its pages out. One bad file
|
|
63
|
+
* does that to one unit, or to a few: blame and skip is for that (worker.ts).
|
|
64
|
+
* More than this many in one job points at a fault that is not about a file,
|
|
65
|
+
* typically a validator bug that a release brings, which shows first in the
|
|
66
|
+
* deploy's cold build, where no unit has a last good result. The job then
|
|
67
|
+
* fails instead of finishing "ok" with those pages missing, so the deploy
|
|
68
|
+
* fails its check and the old version keeps serving, as when today's
|
|
69
|
+
* processor throws; and the next job tries again.
|
|
70
|
+
*/
|
|
71
|
+
const MAX_LOST_UNITS = 5;
|
|
72
|
+
/**
|
|
73
|
+
* Run one job. Throws when the job cannot complete; the worker reports that
|
|
74
|
+
* as a result with status "error". The store must belong to the running
|
|
75
|
+
* validator version.
|
|
76
|
+
*/
|
|
77
|
+
export function runJob(job, store, source, hooks = {}) {
|
|
78
|
+
try {
|
|
79
|
+
if (job.draftPaths?.length && job.kind !== "overlay") {
|
|
80
|
+
throw new Error(`A ${job.kind} job cannot build the drafts view: the build layer holds the approved view`);
|
|
81
|
+
}
|
|
82
|
+
if (job.kind === "commit" || job.kind === "cold") {
|
|
83
|
+
return build(job, store, source, hooks).result;
|
|
84
|
+
}
|
|
85
|
+
if (job.kind === "overlay")
|
|
86
|
+
return overlayJob(job, store, source, hooks);
|
|
87
|
+
throw new Error(`Unknown job kind: ${job.kind}`);
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
// Parsed trees are memoized for one run (markdown-parse.ts).
|
|
91
|
+
clearParsedMarkdown();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function build(job, store, source, hooks) {
|
|
95
|
+
const timings = {};
|
|
96
|
+
let lapStart = performance.now();
|
|
97
|
+
const lap = (stage) => {
|
|
98
|
+
const now = performance.now();
|
|
99
|
+
timings[stage] = Math.round(now - lapStart);
|
|
100
|
+
lapStart = now;
|
|
101
|
+
};
|
|
102
|
+
const started = lapStart;
|
|
103
|
+
// --- What changed ---
|
|
104
|
+
const versions = source.versions();
|
|
105
|
+
const paths = [...versions.keys()].sort(byPath);
|
|
106
|
+
const texts = new SourceTexts(source, paths);
|
|
107
|
+
const cold = job.kind === "cold";
|
|
108
|
+
const unfinished = store.getMeta(JOB_STATE) === "running";
|
|
109
|
+
store.setMeta(JOB_STATE, "running");
|
|
110
|
+
store.commit();
|
|
111
|
+
const held = store.getFileVersions();
|
|
112
|
+
const changed = paths.filter((path) => held.get(path) !== versions.get(path));
|
|
113
|
+
const removed = [...held.keys()].filter((path) => !versions.has(path));
|
|
114
|
+
const files = FileFactsTable.parse(cold ? undefined : store.getMeta(FILE_FACTS));
|
|
115
|
+
for (const path of files.paths()) {
|
|
116
|
+
if (!versions.has(path))
|
|
117
|
+
files.set(path, undefined);
|
|
118
|
+
}
|
|
119
|
+
for (const path of paths) {
|
|
120
|
+
const version = versions.get(path);
|
|
121
|
+
if (files.get(path)?.version !== version)
|
|
122
|
+
files.set(path, fileFacts(path, version, texts.get(path)));
|
|
123
|
+
}
|
|
124
|
+
const state = new ContentState(versions, texts, files.tags(), files.factsVersions());
|
|
125
|
+
// The read keys whose answer a changed, added or removed file may change.
|
|
126
|
+
const fileKeys = [];
|
|
127
|
+
for (const path of [...changed, ...removed]) {
|
|
128
|
+
for (const kind of ["file", "facts", "exists", "tier", "tags"])
|
|
129
|
+
fileKeys.push(`${kind}:${path}`);
|
|
130
|
+
}
|
|
131
|
+
// A new path list changes every scan of it (paths:*), and can change the
|
|
132
|
+
// "did you mean" suggestion of a broken link: the units that asked for one
|
|
133
|
+
// (similar:*) are candidates, and each runs again only if an answer changed.
|
|
134
|
+
if (removed.length > 0 || changed.some((path) => !held.has(path))) {
|
|
135
|
+
fileKeys.push("paths:*", "similar:*");
|
|
136
|
+
}
|
|
137
|
+
lap("files");
|
|
138
|
+
const units = new Units(store, hooks, cold ? "every" : unfinished ? "check-all" : "changed", job.skipUnits ?? [], job.retryFailed ?? false);
|
|
139
|
+
// --- 1. Path units ---
|
|
140
|
+
const pathIds = paths.map(unitIdOf);
|
|
141
|
+
for (const id of store.listUnitIds(UNIT_KINDS.path)) {
|
|
142
|
+
if (!versions.has(pathOfUnit(id)))
|
|
143
|
+
store.deleteUnit(id);
|
|
144
|
+
}
|
|
145
|
+
const fresh = new Map();
|
|
146
|
+
for (const id of units.dirty(pathIds, UNIT_KINDS.path, fileKeys, state, [
|
|
147
|
+
...changed.map(unitIdOf),
|
|
148
|
+
])) {
|
|
149
|
+
const path = pathOfUnit(id);
|
|
150
|
+
const stored = units.run(id, state, (log) => {
|
|
151
|
+
const unit = runPathUnit(path, state.recordingViews(log));
|
|
152
|
+
const pages = unit.modules.map((page) => {
|
|
153
|
+
if (page.sourcePath !== path) {
|
|
154
|
+
throw new Error(`Page ${page.slug} of ${path} names ${page.sourcePath}`);
|
|
155
|
+
}
|
|
156
|
+
return encodeUnit(page);
|
|
157
|
+
});
|
|
158
|
+
return {
|
|
159
|
+
output: encodeUnit({
|
|
160
|
+
summary: summarizeUnit(unit),
|
|
161
|
+
flat: pages.map((page) => sha1(JSON.stringify(page))),
|
|
162
|
+
}),
|
|
163
|
+
save: () => pages.forEach((page, index) => store.putUnit({
|
|
164
|
+
id: flatIdOf(pageKey(path, index)),
|
|
165
|
+
reads: [],
|
|
166
|
+
output: page,
|
|
167
|
+
})),
|
|
168
|
+
};
|
|
169
|
+
});
|
|
170
|
+
if (stored !== undefined)
|
|
171
|
+
fresh.set(path, decodeUnit(stored));
|
|
172
|
+
}
|
|
173
|
+
// Finish units parse only glossary segments, not the texts flattened above.
|
|
174
|
+
clearParsedMarkdown();
|
|
175
|
+
lap("units");
|
|
176
|
+
// --- 2. The whole-content step, over every unit's summary in path order ---
|
|
177
|
+
const contributions = paths.map((path) => {
|
|
178
|
+
const id = unitIdOf(path);
|
|
179
|
+
const unit = fresh.get(path);
|
|
180
|
+
if (unit)
|
|
181
|
+
return unit;
|
|
182
|
+
const record = store.getUnit(id);
|
|
183
|
+
const lastGood = record && decodeUnit(record.output);
|
|
184
|
+
if (units.skipped(id))
|
|
185
|
+
return skippedUnit(path, units.reason(id), lastGood);
|
|
186
|
+
if (!lastGood)
|
|
187
|
+
throw new Error(`The build layer holds no result for ${id}`);
|
|
188
|
+
return lastGood;
|
|
189
|
+
});
|
|
190
|
+
lap("load");
|
|
191
|
+
const whole = wholeContentStep(contributions.map(({ summary }) => summary), state.views());
|
|
192
|
+
lap("whole");
|
|
193
|
+
// --- 3. Finish units ---
|
|
194
|
+
const pages = contributions.flatMap(({ summary, flat }) => flat.map((version, index) => ({
|
|
195
|
+
key: pageKey(summary.path, index),
|
|
196
|
+
sourcePath: summary.path,
|
|
197
|
+
index,
|
|
198
|
+
slug: summary.pages[index].slug,
|
|
199
|
+
version,
|
|
200
|
+
})));
|
|
201
|
+
const tables = new TableVersions(whole.tables);
|
|
202
|
+
const flatVersions = new Map(pages.map((p) => [flatIdOf(p.key), p.version]));
|
|
203
|
+
const finishVersions = {
|
|
204
|
+
versionOf: (key) => key.startsWith(UNIT_KINDS.flat)
|
|
205
|
+
? (flatVersions.get(key) ?? "missing")
|
|
206
|
+
: TableVersions.owns(key)
|
|
207
|
+
? tables.versionOf(key)
|
|
208
|
+
: state.versionOf(key),
|
|
209
|
+
};
|
|
210
|
+
// The finish inputs whose version changed since the last job.
|
|
211
|
+
const inputs = new Map([...flatVersions, ...tables.all()]);
|
|
212
|
+
const before = new Map(Object.entries(JSON.parse((cold ? undefined : store.getMeta(FINISH_INPUTS)) ?? "{}")));
|
|
213
|
+
const finishKeys = [...fileKeys];
|
|
214
|
+
for (const [key, version] of inputs) {
|
|
215
|
+
if (before.get(key) !== version)
|
|
216
|
+
finishKeys.push(key);
|
|
217
|
+
}
|
|
218
|
+
for (const key of before.keys())
|
|
219
|
+
if (!inputs.has(key))
|
|
220
|
+
finishKeys.push(key);
|
|
221
|
+
const live = new Set(pages.map((p) => p.key));
|
|
222
|
+
for (const kind of [UNIT_KINDS.page, UNIT_KINDS.flat]) {
|
|
223
|
+
for (const id of store.listUnitIds(kind)) {
|
|
224
|
+
if (!live.has(pageKeyOf(id)))
|
|
225
|
+
store.deleteUnit(id);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
const storedPages = new Map(store
|
|
229
|
+
.listPages()
|
|
230
|
+
.map((page) => [pageKey(page.sourcePath, page.index), page]));
|
|
231
|
+
const changedPages = [];
|
|
232
|
+
/** Store a finished page whose JSON changed; note it as added or changed. */
|
|
233
|
+
const savePage = (key, slug, json) => {
|
|
234
|
+
const hash = sha1(json);
|
|
235
|
+
const old = storedPages.get(key);
|
|
236
|
+
storedPages.delete(key);
|
|
237
|
+
if (old?.hash === hash)
|
|
238
|
+
return;
|
|
239
|
+
const { sourcePath, index } = splitPageKey(key);
|
|
240
|
+
store.putPage({ sourcePath, index, slug, hash, json });
|
|
241
|
+
changedPages.push({
|
|
242
|
+
sourcePath,
|
|
243
|
+
index,
|
|
244
|
+
slug,
|
|
245
|
+
change: old ? "changed" : "added",
|
|
246
|
+
});
|
|
247
|
+
};
|
|
248
|
+
const finished = new Map();
|
|
249
|
+
const pageIds = pages.map((p) => pageIdOf(p.key));
|
|
250
|
+
for (const id of units.dirty(pageIds, UNIT_KINDS.page, finishKeys, finishVersions)) {
|
|
251
|
+
const key = pageKeyOf(id);
|
|
252
|
+
// Read before the unit runs: a build layer that fails is not the page's fault.
|
|
253
|
+
const flat = store.getUnit(flatIdOf(key));
|
|
254
|
+
if (!flat)
|
|
255
|
+
throw new Error(`The build layer holds no flattened page ${key}`);
|
|
256
|
+
const finish = units.run(id, finishVersions, (log) => {
|
|
257
|
+
log.read(flatIdOf(key));
|
|
258
|
+
const page = decodeUnit(flat.output);
|
|
259
|
+
const output = encodeUnit(finishPage(page, key, recordingTables(whole.tables, log), state.recordingViews(log)));
|
|
260
|
+
const json = JSON.stringify(page);
|
|
261
|
+
return { output, save: () => savePage(key, page.slug, json) };
|
|
262
|
+
});
|
|
263
|
+
if (finish !== undefined)
|
|
264
|
+
finished.set(key, decodeUnit(finish));
|
|
265
|
+
}
|
|
266
|
+
const pageFinishes = [];
|
|
267
|
+
for (const { key, sourcePath } of pages) {
|
|
268
|
+
const id = pageIdOf(key);
|
|
269
|
+
let finish = finished.get(key);
|
|
270
|
+
if (!finish) {
|
|
271
|
+
const record = store.getUnit(id);
|
|
272
|
+
const lastGood = record && decodeUnit(record.output);
|
|
273
|
+
if (units.skipped(id)) {
|
|
274
|
+
const skipped = skippedPage(sourcePath, units.reason(id), lastGood);
|
|
275
|
+
finish = skipped.finish;
|
|
276
|
+
if (!skipped.dropped)
|
|
277
|
+
storedPages.delete(key);
|
|
278
|
+
}
|
|
279
|
+
else if (!lastGood) {
|
|
280
|
+
throw new Error(`The build layer holds no result for ${id}`);
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
finish = lastGood;
|
|
284
|
+
storedPages.delete(key);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
pageFinishes.push({ source: id, finish });
|
|
288
|
+
}
|
|
289
|
+
// Pages that are gone, or whose finish failed with no last good result.
|
|
290
|
+
for (const { sourcePath, index, slug } of storedPages.values()) {
|
|
291
|
+
store.deletePage(sourcePath, index);
|
|
292
|
+
changedPages.push({ sourcePath, index, slug, change: "removed" });
|
|
293
|
+
}
|
|
294
|
+
lap("finish");
|
|
295
|
+
// --- 4. Errors and artifacts ---
|
|
296
|
+
const { errors, changedArtifacts, urlReport } = assemble(store, contributions.map(({ summary }) => ({
|
|
297
|
+
source: unitIdOf(summary.path),
|
|
298
|
+
errors: summary.errors,
|
|
299
|
+
dropped: summary.dropped,
|
|
300
|
+
})), whole, pageFinishes, state, files.references());
|
|
301
|
+
units.saveFailures();
|
|
302
|
+
store.setMeta(FILE_FACTS, JSON.stringify(files));
|
|
303
|
+
store.setMeta(FINISH_INPUTS, JSON.stringify(Object.fromEntries([...inputs].sort(([a], [b]) => byPath(a, b)))));
|
|
304
|
+
for (const path of removed)
|
|
305
|
+
store.setFileVersion(path, null);
|
|
306
|
+
for (const path of changed)
|
|
307
|
+
store.setFileVersion(path, versions.get(path));
|
|
308
|
+
if (job.source.type === "git")
|
|
309
|
+
store.setMeta("commit", job.source.commit);
|
|
310
|
+
// Last: the build layer now describes this content, all of it.
|
|
311
|
+
store.setMeta(JOB_STATE, "done");
|
|
312
|
+
store.commit();
|
|
313
|
+
lap("artifacts");
|
|
314
|
+
if (job.fullOutputPath) {
|
|
315
|
+
writeFullOutput(job.fullOutputPath, store, whole, errors, texts, {
|
|
316
|
+
courseGraph: !job.skipCourseGraph,
|
|
317
|
+
});
|
|
318
|
+
lap("fullOutput");
|
|
319
|
+
}
|
|
320
|
+
const changedFiles = [
|
|
321
|
+
...changed.map((path) => ({
|
|
322
|
+
path,
|
|
323
|
+
change: held.has(path) ? "changed" : "added",
|
|
324
|
+
})),
|
|
325
|
+
...removed.map((path) => ({ path, change: "removed" })),
|
|
326
|
+
].sort((a, b) => byPath(a.path, b.path));
|
|
327
|
+
timings.total = Math.round(performance.now() - started);
|
|
328
|
+
return {
|
|
329
|
+
errors,
|
|
330
|
+
result: {
|
|
331
|
+
event: "result",
|
|
332
|
+
status: "ok",
|
|
333
|
+
validatorVersion: store.getMeta("validatorVersion") ?? "unknown",
|
|
334
|
+
...(job.source.type === "git" ? { commit: job.source.commit } : {}),
|
|
335
|
+
changedPages: changedPages.sort(comparePages),
|
|
336
|
+
changedArtifacts,
|
|
337
|
+
changedFiles,
|
|
338
|
+
unitsRun: units.ran(UNIT_KINDS.path),
|
|
339
|
+
finishUnitsRun: units.ran(UNIT_KINDS.page),
|
|
340
|
+
skippedUnits: units.skippedIds(),
|
|
341
|
+
...urlReport,
|
|
342
|
+
timings,
|
|
343
|
+
},
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Planning and running units, with blame and skip: a unit named in the
|
|
348
|
+
* job's skipUnits, or marked failed by an earlier job and not due again
|
|
349
|
+
* (retryFailed makes every one due), is not run; it contributes its last
|
|
350
|
+
* good result with an error.
|
|
351
|
+
*/
|
|
352
|
+
class Units {
|
|
353
|
+
store;
|
|
354
|
+
hooks;
|
|
355
|
+
planning;
|
|
356
|
+
retryFailed;
|
|
357
|
+
/** Failure marks: the store's, and this job's (written at its end). */
|
|
358
|
+
failed;
|
|
359
|
+
/** Marks that units which threw in this job add. */
|
|
360
|
+
thrown = new Map();
|
|
361
|
+
/** What each failed unit read before it failed, when known. */
|
|
362
|
+
failedReads;
|
|
363
|
+
/** Units that failed in this job and have no last good result. */
|
|
364
|
+
lost = new Set();
|
|
365
|
+
skip;
|
|
366
|
+
runs = new Map();
|
|
367
|
+
skippedSet = new Set();
|
|
368
|
+
constructor(store, hooks, planning, skipUnits, retryFailed) {
|
|
369
|
+
this.store = store;
|
|
370
|
+
this.hooks = hooks;
|
|
371
|
+
this.planning = planning;
|
|
372
|
+
this.retryFailed = retryFailed;
|
|
373
|
+
this.failed = store.getFailedUnits();
|
|
374
|
+
this.failedReads = new Map(Object.entries(JSON.parse(store.getMeta(FAILED_READS) ?? "{}")));
|
|
375
|
+
this.skip = new Set(skipUnits);
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* The units of `ids` (in order) that must run. The candidates are the units
|
|
379
|
+
* that recorded a read of any of `changedKeys`, the `extra` ones, and the
|
|
380
|
+
* units the store has no result for (unless they failed); a candidate runs
|
|
381
|
+
* unless every read it recorded still has its version. A failed unit runs
|
|
382
|
+
* again when a read it made before it failed has another version, when
|
|
383
|
+
* nothing is known of its reads, or with retryFailed. A failure mark goes
|
|
384
|
+
* with its unit, and when the unit's last good result fits the content
|
|
385
|
+
* again (the edit that broke it was undone).
|
|
386
|
+
*/
|
|
387
|
+
dirty(ids, kind, changedKeys, versions, extra = []) {
|
|
388
|
+
const wanted = new Set(ids);
|
|
389
|
+
const records = new Map();
|
|
390
|
+
const recordOf = (id) => {
|
|
391
|
+
if (!records.has(id))
|
|
392
|
+
records.set(id, this.store.getUnit(id));
|
|
393
|
+
return records.get(id);
|
|
394
|
+
};
|
|
395
|
+
const holds = (reads) => reads?.every(({ key, version }) => versions.versionOf(key) === version) ??
|
|
396
|
+
false;
|
|
397
|
+
const upToDate = (id) => holds(recordOf(id)?.reads);
|
|
398
|
+
// A unit killed in an earlier attempt of this job failed on this content.
|
|
399
|
+
// What it read died with the process, so its own input stands for it.
|
|
400
|
+
for (const id of this.skip) {
|
|
401
|
+
if (!id.startsWith(kind) || !wanted.has(id))
|
|
402
|
+
continue;
|
|
403
|
+
this.failedReads.set(id, readsOf(ownInputs(id), versions));
|
|
404
|
+
if (!recordOf(id))
|
|
405
|
+
this.lose(id);
|
|
406
|
+
}
|
|
407
|
+
for (const id of [...this.failed.keys()]) {
|
|
408
|
+
if (!id.startsWith(kind) || this.skip.has(id))
|
|
409
|
+
continue;
|
|
410
|
+
if (!wanted.has(id) || upToDate(id))
|
|
411
|
+
this.forget(id);
|
|
412
|
+
}
|
|
413
|
+
const runnable = (id) => !this.skip.has(id);
|
|
414
|
+
if (this.planning === "every")
|
|
415
|
+
return ids.filter(runnable);
|
|
416
|
+
const stored = new Set(this.store.listUnitIds(kind));
|
|
417
|
+
const candidates = new Set(this.planning === "check-all"
|
|
418
|
+
? ids.filter((id) => !this.failed.has(id))
|
|
419
|
+
: [
|
|
420
|
+
...this.store.unitsReading(changedKeys),
|
|
421
|
+
...extra,
|
|
422
|
+
...ids.filter((id) => !this.failed.has(id) && !stored.has(id)),
|
|
423
|
+
]);
|
|
424
|
+
for (const id of this.failed.keys()) {
|
|
425
|
+
if (id.startsWith(kind) &&
|
|
426
|
+
(this.retryFailed || !holds(this.failedReads.get(id))))
|
|
427
|
+
candidates.add(id);
|
|
428
|
+
}
|
|
429
|
+
return ids.filter((id) => candidates.has(id) && runnable(id) && !upToDate(id));
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Run one unit: tell the hooks (the worker records it as running, for blame
|
|
433
|
+
* and skip), compute its output with a fresh read log, and store it with
|
|
434
|
+
* its reads and its writes in one transaction. Returns the stored output,
|
|
435
|
+
* or undefined when the unit threw: it is then marked failed and skipped
|
|
436
|
+
* like one that hangs, so the rest of the content still builds. A
|
|
437
|
+
* Showstopper is not the unit's fault: it ends the job.
|
|
438
|
+
*/
|
|
439
|
+
run(id, versions, compute) {
|
|
440
|
+
this.hooks.beforeUnit?.(id);
|
|
441
|
+
const log = new ReadLog(versions);
|
|
442
|
+
let result;
|
|
443
|
+
try {
|
|
444
|
+
result = compute(log);
|
|
445
|
+
}
|
|
446
|
+
catch (error) {
|
|
447
|
+
if (error instanceof Showstopper)
|
|
448
|
+
throw error;
|
|
449
|
+
console.error(`Unit ${id} failed:`, error);
|
|
450
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
451
|
+
this.failed.set(id, reason);
|
|
452
|
+
this.thrown.set(id, reason);
|
|
453
|
+
const read = new Map(log.reads().map((r) => [r.key, r]));
|
|
454
|
+
for (const r of readsOf(ownInputs(id), versions))
|
|
455
|
+
read.set(r.key, r);
|
|
456
|
+
this.failedReads.set(id, [...read.values()]);
|
|
457
|
+
if (!this.store.getUnit(id))
|
|
458
|
+
this.lose(id);
|
|
459
|
+
}
|
|
460
|
+
if (result) {
|
|
461
|
+
const { output, save } = result;
|
|
462
|
+
this.store.atomically(() => {
|
|
463
|
+
save?.();
|
|
464
|
+
this.store.putUnit({ id, reads: log.reads(), output });
|
|
465
|
+
});
|
|
466
|
+
if (this.failed.has(id))
|
|
467
|
+
this.forget(id);
|
|
468
|
+
const kind = id.slice(0, id.indexOf(":") + 1);
|
|
469
|
+
this.runs.set(kind, (this.runs.get(kind) ?? 0) + 1);
|
|
470
|
+
}
|
|
471
|
+
this.hooks.afterUnit?.(id);
|
|
472
|
+
return result?.output;
|
|
473
|
+
}
|
|
474
|
+
/** True when the unit did not run in this job because it is to be skipped or failed: it gets skippedUnit's result. */
|
|
475
|
+
skipped(id) {
|
|
476
|
+
const skipped = this.skip.has(id) || this.failed.has(id);
|
|
477
|
+
if (skipped)
|
|
478
|
+
this.skippedSet.add(id);
|
|
479
|
+
return skipped;
|
|
480
|
+
}
|
|
481
|
+
reason(id) {
|
|
482
|
+
return this.failed.get(id);
|
|
483
|
+
}
|
|
484
|
+
ran(kind) {
|
|
485
|
+
return this.runs.get(kind) ?? 0;
|
|
486
|
+
}
|
|
487
|
+
skippedIds() {
|
|
488
|
+
return [...this.skippedSet];
|
|
489
|
+
}
|
|
490
|
+
/** Write this job's failure marks, and what every failed unit read. */
|
|
491
|
+
saveFailures() {
|
|
492
|
+
for (const [id, reason] of this.thrown)
|
|
493
|
+
this.store.setFailedUnit(id, reason);
|
|
494
|
+
const reads = [...this.failed.keys()].sort(byPath).flatMap((id) => {
|
|
495
|
+
const known = this.failedReads.get(id);
|
|
496
|
+
return known ? [[id, known]] : [];
|
|
497
|
+
});
|
|
498
|
+
this.store.setMeta(FAILED_READS, JSON.stringify(Object.fromEntries(reads)));
|
|
499
|
+
}
|
|
500
|
+
/** A unit is no longer failed: it succeeded, went away, or its last good result fits again. */
|
|
501
|
+
forget(id) {
|
|
502
|
+
this.failed.delete(id);
|
|
503
|
+
this.thrown.delete(id);
|
|
504
|
+
this.failedReads.delete(id);
|
|
505
|
+
this.store.setFailedUnit(id, null);
|
|
506
|
+
}
|
|
507
|
+
lose(id) {
|
|
508
|
+
this.lost.add(id);
|
|
509
|
+
if (this.lost.size <= MAX_LOST_UNITS)
|
|
510
|
+
return;
|
|
511
|
+
const named = [...this.lost]
|
|
512
|
+
.slice(0, MAX_LOST_UNITS + 1)
|
|
513
|
+
.map((unit) => `${unit} (${this.failed.get(unit) ?? "killed"})`);
|
|
514
|
+
throw new Showstopper(`${this.lost.size} units failed in this job with no earlier result, so ` +
|
|
515
|
+
`their pages would be missing: more than ${MAX_LOST_UNITS} points at a ` +
|
|
516
|
+
`fault in the validator or its environment, not in one file. The job ` +
|
|
517
|
+
`stops, and the next job tries again. ${named.join("; ")}`);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* The input a unit reads first: its file (a path unit), or its flattened page
|
|
522
|
+
* and the file it comes from (a finish unit).
|
|
523
|
+
*/
|
|
524
|
+
function ownInputs(id) {
|
|
525
|
+
if (id.startsWith(UNIT_KINDS.path))
|
|
526
|
+
return [`file:${pathOfUnit(id)}`];
|
|
527
|
+
const key = pageKeyOf(id);
|
|
528
|
+
return [flatIdOf(key), `file:${splitPageKey(key).sourcePath}`];
|
|
529
|
+
}
|
|
530
|
+
function readsOf(keys, versions) {
|
|
531
|
+
return keys.map((key) => ({ key, version: versions.versionOf(key) }));
|
|
532
|
+
}
|
|
533
|
+
/**
|
|
534
|
+
* Build the source with the job's overlays over a copy-on-write view of the
|
|
535
|
+
* store, and say what the overlays change; the store itself is not written.
|
|
536
|
+
* The draftPaths are built with their pending suggestions accepted. Issues on
|
|
537
|
+
* the focus paths (the overlaid paths when none are named) are the overlay's
|
|
538
|
+
* own; issues on other files that the stored build does not have are the ones
|
|
539
|
+
* it would cause. Every page it would change is listed.
|
|
540
|
+
*/
|
|
541
|
+
function overlayJob(job, store, source, hooks) {
|
|
542
|
+
const overlays = job.overlays ?? {};
|
|
543
|
+
const content = draftsSource(overlaySource(source, overlays), job.draftPaths ?? []);
|
|
544
|
+
const overlaid = new OverlayStore(store);
|
|
545
|
+
const { result, errors } = build(job, overlaid, content, hooks);
|
|
546
|
+
const focus = new Set(job.focusPaths ?? Object.keys(overlays));
|
|
547
|
+
const before = new Set(JSON.parse(store.getArtifact("errors") ?? "[]").map(errorKey));
|
|
548
|
+
return {
|
|
549
|
+
...result,
|
|
550
|
+
overlay: {
|
|
551
|
+
issues: errors.filter((error) => focus.has(error.file)),
|
|
552
|
+
causedIssues: errors.filter((error) => !focus.has(error.file) && !before.has(errorKey(error))),
|
|
553
|
+
changedPages: result.changedPages,
|
|
554
|
+
fileToCourses: JSON.parse(overlaid.getArtifact("fileToCourses") ?? "{}"),
|
|
555
|
+
},
|
|
556
|
+
};
|
|
557
|
+
}
|
|
558
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/engine/build.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type FileReferences } from "../reference-graph.js";
|
|
2
|
+
export interface FileFacts {
|
|
3
|
+
/** The version (Git blob id) of the text these facts come from. */
|
|
4
|
+
version: string;
|
|
5
|
+
tags?: string[];
|
|
6
|
+
facts: string;
|
|
7
|
+
refs: FileReferences;
|
|
8
|
+
}
|
|
9
|
+
/** The facts of one file, whose text has this version. */
|
|
10
|
+
export declare function fileFacts(path: string, version: string, text: string): FileFacts;
|
|
11
|
+
/** Every file's facts, as the build layer keeps them (one artifact, in path order). */
|
|
12
|
+
export declare class FileFactsTable {
|
|
13
|
+
private readonly byFile;
|
|
14
|
+
private constructor();
|
|
15
|
+
static parse(json: string | undefined): FileFactsTable;
|
|
16
|
+
get(path: string): FileFacts | undefined;
|
|
17
|
+
set(path: string, facts: FileFacts | undefined): void;
|
|
18
|
+
paths(): string[];
|
|
19
|
+
/** The tags of every Markdown and widget file, in path order. */
|
|
20
|
+
tags(): Map<string, string[]>;
|
|
21
|
+
factsVersions(): Map<string, string>;
|
|
22
|
+
/** Every file's references, in path order. */
|
|
23
|
+
references(): Map<string, FileReferences>;
|
|
24
|
+
toJSON(): Record<string, FileFacts>;
|
|
25
|
+
private sorted;
|
|
26
|
+
}
|