lens-content-processor 0.78.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.
Files changed (133) hide show
  1. package/dist/authoring-markup.d.ts +22 -0
  2. package/dist/authoring-markup.js +24 -0
  3. package/dist/authoring-markup.js.map +1 -1
  4. package/dist/cache.d.ts +10 -0
  5. package/dist/cache.js +6 -5
  6. package/dist/cache.js.map +1 -1
  7. package/dist/cli-steps.d.ts +37 -0
  8. package/dist/cli-steps.js +80 -0
  9. package/dist/cli-steps.js.map +1 -0
  10. package/dist/cli.d.ts +7 -0
  11. package/dist/cli.js +52 -70
  12. package/dist/cli.js.map +1 -1
  13. package/dist/course-graph.d.ts +2 -2
  14. package/dist/course-graph.js +7 -2
  15. package/dist/course-graph.js.map +1 -1
  16. package/dist/criticmarkup-forms.d.ts +8 -6
  17. package/dist/criticmarkup-forms.js +22 -19
  18. package/dist/criticmarkup-forms.js.map +1 -1
  19. package/dist/dedupe-errors.d.ts +16 -0
  20. package/dist/dedupe-errors.js +23 -9
  21. package/dist/dedupe-errors.js.map +1 -1
  22. package/dist/dependency-cache.d.ts +15 -5
  23. package/dist/dependency-cache.js +33 -74
  24. package/dist/dependency-cache.js.map +1 -1
  25. package/dist/dropped.d.ts +114 -0
  26. package/dist/dropped.js +253 -0
  27. package/dist/dropped.js.map +1 -0
  28. package/dist/engine/assemble.d.ts +44 -0
  29. package/dist/engine/assemble.js +132 -0
  30. package/dist/engine/assemble.js.map +1 -0
  31. package/dist/engine/build.d.ts +8 -0
  32. package/dist/engine/build.js +558 -0
  33. package/dist/engine/build.js.map +1 -0
  34. package/dist/engine/file-facts.d.ts +26 -0
  35. package/dist/engine/file-facts.js +63 -0
  36. package/dist/engine/file-facts.js.map +1 -0
  37. package/dist/engine/git-source.d.ts +35 -0
  38. package/dist/engine/git-source.js +242 -0
  39. package/dist/engine/git-source.js.map +1 -0
  40. package/dist/engine/overlay.d.ts +43 -0
  41. package/dist/engine/overlay.js +167 -0
  42. package/dist/engine/overlay.js.map +1 -0
  43. package/dist/engine/protocol.d.ts +146 -0
  44. package/dist/engine/protocol.js +40 -0
  45. package/dist/engine/protocol.js.map +1 -0
  46. package/dist/engine/reader.d.ts +133 -0
  47. package/dist/engine/reader.js +298 -0
  48. package/dist/engine/reader.js.map +1 -0
  49. package/dist/engine/sources.d.ts +39 -0
  50. package/dist/engine/sources.js +137 -0
  51. package/dist/engine/sources.js.map +1 -0
  52. package/dist/engine/sqlite-store.d.ts +99 -0
  53. package/dist/engine/sqlite-store.js +452 -0
  54. package/dist/engine/sqlite-store.js.map +1 -0
  55. package/dist/engine/store.d.ts +85 -0
  56. package/dist/engine/store.js +31 -0
  57. package/dist/engine/store.js.map +1 -0
  58. package/dist/engine/tables.d.ts +15 -0
  59. package/dist/engine/tables.js +70 -0
  60. package/dist/engine/tables.js.map +1 -0
  61. package/dist/engine/units.d.ts +58 -0
  62. package/dist/engine/units.js +186 -0
  63. package/dist/engine/units.js.map +1 -0
  64. package/dist/engine/version.d.ts +6 -0
  65. package/dist/engine/version.js +21 -0
  66. package/dist/engine/version.js.map +1 -0
  67. package/dist/engine/worker.d.ts +1 -0
  68. package/dist/engine/worker.js +220 -0
  69. package/dist/engine/worker.js.map +1 -0
  70. package/dist/flattener/index.d.ts +34 -17
  71. package/dist/flattener/index.js +247 -116
  72. package/dist/flattener/index.js.map +1 -1
  73. package/dist/flattener/resolve-text-links.d.ts +15 -14
  74. package/dist/flattener/resolve-text-links.js +24 -25
  75. package/dist/flattener/resolve-text-links.js.map +1 -1
  76. package/dist/glossary.d.ts +2 -2
  77. package/dist/glossary.js.map +1 -1
  78. package/dist/index.d.ts +168 -2
  79. package/dist/index.js +888 -616
  80. package/dist/index.js.map +1 -1
  81. package/dist/markdown-parse.d.ts +6 -0
  82. package/dist/markdown-parse.js +14 -0
  83. package/dist/markdown-parse.js.map +1 -1
  84. package/dist/parser/learning-outcome.js +11 -2
  85. package/dist/parser/learning-outcome.js.map +1 -1
  86. package/dist/parser/lens.d.ts +15 -2
  87. package/dist/parser/lens.js +38 -11
  88. package/dist/parser/lens.js.map +1 -1
  89. package/dist/parser/meeting-doc.d.ts +2 -1
  90. package/dist/parser/meeting-doc.js +2 -1
  91. package/dist/parser/meeting-doc.js.map +1 -1
  92. package/dist/parser/module.d.ts +3 -1
  93. package/dist/parser/module.js +7 -5
  94. package/dist/parser/module.js.map +1 -1
  95. package/dist/parser/question-embeds.d.ts +46 -0
  96. package/dist/parser/question-embeds.js +302 -0
  97. package/dist/parser/question-embeds.js.map +1 -0
  98. package/dist/parser/response-segments.js +12 -0
  99. package/dist/parser/response-segments.js.map +1 -1
  100. package/dist/parser/sections.d.ts +18 -0
  101. package/dist/parser/sections.js +31 -3
  102. package/dist/parser/sections.js.map +1 -1
  103. package/dist/parser/widget.d.ts +2 -1
  104. package/dist/parser/widget.js.map +1 -1
  105. package/dist/parser/wikilink.d.ts +13 -3
  106. package/dist/parser/wikilink.js +55 -34
  107. package/dist/parser/wikilink.js.map +1 -1
  108. package/dist/reference-graph.d.ts +21 -3
  109. package/dist/reference-graph.js +35 -12
  110. package/dist/reference-graph.js.map +1 -1
  111. package/dist/same-page-links.d.ts +11 -1
  112. package/dist/same-page-links.js +9 -0
  113. package/dist/same-page-links.js.map +1 -1
  114. package/dist/skill-tree.d.ts +2 -1
  115. package/dist/skill-tree.js.map +1 -1
  116. package/dist/source-location.d.ts +0 -4
  117. package/dist/source-location.js +0 -43
  118. package/dist/source-location.js.map +1 -1
  119. package/dist/validator/card-module-membership.d.ts +17 -1
  120. package/dist/validator/card-module-membership.js +60 -56
  121. package/dist/validator/card-module-membership.js.map +1 -1
  122. package/dist/validator/criticmarkup.js +1 -1
  123. package/dist/validator/criticmarkup.js.map +1 -1
  124. package/dist/validator/field-typos.d.ts +1 -1
  125. package/dist/validator/field-typos.js +21 -21
  126. package/dist/validator/field-typos.js.map +1 -1
  127. package/dist/validator/output-integrity.d.ts +9 -5
  128. package/dist/validator/output-integrity.js +43 -45
  129. package/dist/validator/output-integrity.js.map +1 -1
  130. package/dist/validator/tier.d.ts +2 -2
  131. package/dist/validator/tier.js.map +1 -1
  132. package/dist/validator/uuid.d.ts +1 -1
  133. package/package.json +2 -1
@@ -0,0 +1,63 @@
1
+ // What the engine keeps about each file between jobs. Each fact comes from
2
+ // the file's text alone and is computed again only when the file's version
3
+ // differs from the one the facts carry, so a job reads the texts of changed
4
+ // files and of the files its units read, never all of them; and facts that a
5
+ // job which stopped part way wrote for other content are never trusted:
6
+ //
7
+ // - tags: the lower-cased frontmatter tags (Markdown and widget files), from
8
+ // which every file's tier follows;
9
+ // - facts: the version of its link facts, which a `facts:` read sees;
10
+ // - refs: the wikilink targets it writes, for the course reachability map.
11
+ import { fileReferences } from "../reference-graph.js";
12
+ import { buildTagMap } from "../validator/tier.js";
13
+ import { byPath, factsVersion, linkFacts } from "./reader.js";
14
+ /** The facts of one file, whose text has this version. */
15
+ export function fileFacts(path, version, text) {
16
+ const tags = buildTagMap(new Map([[path, text]])).get(path);
17
+ return {
18
+ version,
19
+ ...(tags ? { tags } : {}),
20
+ facts: factsVersion(linkFacts(path, text)),
21
+ refs: fileReferences(path, text),
22
+ };
23
+ }
24
+ /** Every file's facts, as the build layer keeps them (one artifact, in path order). */
25
+ export class FileFactsTable {
26
+ byFile;
27
+ constructor(byFile) {
28
+ this.byFile = byFile;
29
+ }
30
+ static parse(json) {
31
+ return new FileFactsTable(new Map(json ? Object.entries(JSON.parse(json)) : []));
32
+ }
33
+ get(path) {
34
+ return this.byFile.get(path);
35
+ }
36
+ set(path, facts) {
37
+ if (facts)
38
+ this.byFile.set(path, facts);
39
+ else
40
+ this.byFile.delete(path);
41
+ }
42
+ paths() {
43
+ return [...this.byFile.keys()];
44
+ }
45
+ /** The tags of every Markdown and widget file, in path order. */
46
+ tags() {
47
+ return new Map(this.sorted().flatMap(([path, f]) => (f.tags ? [[path, f.tags]] : [])));
48
+ }
49
+ factsVersions() {
50
+ return new Map(this.sorted().map(([path, f]) => [path, f.facts]));
51
+ }
52
+ /** Every file's references, in path order. */
53
+ references() {
54
+ return new Map(this.sorted().map(([path, f]) => [path, f.refs]));
55
+ }
56
+ toJSON() {
57
+ return Object.fromEntries(this.sorted());
58
+ }
59
+ sorted() {
60
+ return [...this.byFile].sort(([a], [b]) => byPath(a, b));
61
+ }
62
+ }
63
+ //# sourceMappingURL=file-facts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-facts.js","sourceRoot":"","sources":["../../src/engine/file-facts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { ContentDirectories, ContentSource } from "./protocol.js";
2
+ /**
3
+ * True when `path` (relative, forward slashes) is content by `directories`: its
4
+ * first directory is listed, and its name has one of that directory's endings
5
+ * (core/content/git_fetcher.is_content_path).
6
+ */
7
+ export declare function isContentPath(path: string, directories: ContentDirectories): boolean;
8
+ /**
9
+ * Bytes to text as Python's Path.read_text(encoding="utf-8") does it: strict UTF-8
10
+ * (undefined when invalid), a byte order mark kept, and universal newlines ("\r\n"
11
+ * and a lone "\r" become "\n").
12
+ */
13
+ export declare function decodeLikePython(bytes: Uint8Array): string | undefined;
14
+ export declare class GitSource implements ContentSource {
15
+ private readonly repoDir;
16
+ private readonly commit;
17
+ private readonly directories;
18
+ private files;
19
+ private catFile;
20
+ private readonly trusted;
21
+ /**
22
+ * @param directories Which files are content: the job's, from the platform.
23
+ * @param trusted Blob ids already known to be valid UTF-8, such as the versions
24
+ * in the build layer. Files with other blob ids are read once by versions(), to
25
+ * leave out those that are not valid UTF-8, as the platform does.
26
+ */
27
+ constructor(repoDir: string, commit: string, directories: ContentDirectories, options?: {
28
+ trusted?: Iterable<string>;
29
+ });
30
+ versions(): Map<string, string>;
31
+ read(path: string): string;
32
+ /** Stop the `git cat-file` process. */
33
+ close(): void;
34
+ private fetch;
35
+ }
@@ -0,0 +1,242 @@
1
+ // The content of one commit of a content checkout, read from Git's object store.
2
+ //
3
+ // It gives the engine exactly the files and the text that the platform passes to the
4
+ // processor today (core/content/git_fetcher.read_all_files): the same selection (the
5
+ // platform's own list of content directories, which every job carries), the same
6
+ // decoding, the same newlines. It reads objects, never the working tree, so a
7
+ // `git reset` during a job cannot mix two commits into one build.
8
+ //
9
+ // Differences from reading the working tree, which the platform does after
10
+ // `git reset --hard`, are possible only in cases the content repository does not have
11
+ // (none at 4d37677ba: 5,808 regular files, no symlink, no submodule, no
12
+ // .gitattributes): a symbolic link (Python reads its target; this skips it, with a
13
+ // warning), a file Git does not track, a checkout filter or eol attribute, and a path
14
+ // that is not valid UTF-8.
15
+ //
16
+ // ContentSource.read is synchronous, but a pipe to a child process can only be read
17
+ // asynchronously. One `git cat-file --batch` process therefore runs inside a helper
18
+ // thread; read() posts the object ids to it and blocks on Atomics.wait until the
19
+ // thread has the bytes.
20
+ import { execFileSync } from "child_process";
21
+ import { MessageChannel, receiveMessageOnPort, Worker, } from "worker_threads";
22
+ /**
23
+ * True when `path` (relative, forward slashes) is content by `directories`: its
24
+ * first directory is listed, and its name has one of that directory's endings
25
+ * (core/content/git_fetcher.is_content_path).
26
+ */
27
+ export function isContentPath(path, directories) {
28
+ const slash = path.indexOf("/");
29
+ const dir = path.slice(0, slash);
30
+ if (slash < 0 || !Object.hasOwn(directories, dir))
31
+ return false;
32
+ const name = path.slice(path.lastIndexOf("/") + 1);
33
+ return directories[dir].some((ending) => name.endsWith(ending));
34
+ }
35
+ const utf8 = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
36
+ /**
37
+ * Bytes to text as Python's Path.read_text(encoding="utf-8") does it: strict UTF-8
38
+ * (undefined when invalid), a byte order mark kept, and universal newlines ("\r\n"
39
+ * and a lone "\r" become "\n").
40
+ */
41
+ export function decodeLikePython(bytes) {
42
+ let text;
43
+ try {
44
+ text = utf8.decode(bytes);
45
+ }
46
+ catch {
47
+ return undefined;
48
+ }
49
+ return text.includes("\r") ? text.replace(/\r\n?/g, "\n") : text;
50
+ }
51
+ /** Objects per request while checking new files, which keeps memory to a few MB. */
52
+ const VALIDATE_CHUNK = 256;
53
+ /** How long one request to `git cat-file` may take before read() gives up. */
54
+ const REQUEST_TIMEOUT_MS = 60_000;
55
+ export class GitSource {
56
+ repoDir;
57
+ commit;
58
+ directories;
59
+ files;
60
+ catFile;
61
+ trusted;
62
+ /**
63
+ * @param directories Which files are content: the job's, from the platform.
64
+ * @param trusted Blob ids already known to be valid UTF-8, such as the versions
65
+ * in the build layer. Files with other blob ids are read once by versions(), to
66
+ * leave out those that are not valid UTF-8, as the platform does.
67
+ */
68
+ constructor(repoDir, commit, directories, options = {}) {
69
+ this.repoDir = repoDir;
70
+ this.commit = commit;
71
+ this.directories = directories;
72
+ // With none, a commit job would find every file deleted and remove every page.
73
+ if (!directories || Object.keys(directories).length === 0)
74
+ throw new Error("A git source needs the platform's content directories (source.directories)");
75
+ this.trusted = new Set(options.trusted ?? []);
76
+ }
77
+ versions() {
78
+ if (this.files)
79
+ return this.files;
80
+ const listing = execFileSync("git", ["ls-tree", "-r", "-z", "--full-tree", this.commit], { cwd: this.repoDir, maxBuffer: 1 << 30 }).toString("utf-8");
81
+ const entries = [];
82
+ for (const entry of listing.split("\0")) {
83
+ const tab = entry.indexOf("\t");
84
+ if (tab < 0)
85
+ continue;
86
+ const [mode, type, oid] = entry.slice(0, tab).split(" ");
87
+ const path = entry.slice(tab + 1);
88
+ if (type !== "blob" || !isContentPath(path, this.directories))
89
+ continue;
90
+ if (mode === "120000")
91
+ console.warn(`Skipped ${path}: a symbolic link (the platform reads its target)`);
92
+ else
93
+ entries.push([path, oid]);
94
+ }
95
+ const unchecked = entries.filter(([, oid]) => !this.trusted.has(oid));
96
+ const invalid = new Set();
97
+ for (let i = 0; i < unchecked.length; i += VALIDATE_CHUNK) {
98
+ const chunk = unchecked.slice(i, i + VALIDATE_CHUNK);
99
+ const blobs = this.fetch(chunk.map(([, oid]) => oid));
100
+ chunk.forEach(([path], j) => {
101
+ if (decodeLikePython(blobs[j]) !== undefined)
102
+ return;
103
+ console.warn(`Failed to read ${path}: not valid UTF-8`);
104
+ invalid.add(path);
105
+ });
106
+ }
107
+ // Git's tree order, whatever was trusted: the CLI's last steps see this order.
108
+ this.files = new Map(entries.filter(([path]) => !invalid.has(path)));
109
+ return this.files;
110
+ }
111
+ read(path) {
112
+ const oid = this.versions().get(path);
113
+ if (oid === undefined)
114
+ throw new Error(`${path} is not a content file at ${this.commit}`);
115
+ const text = decodeLikePython(this.fetch([oid])[0]);
116
+ if (text === undefined)
117
+ throw new Error(`${path} (blob ${oid}) is not valid UTF-8`);
118
+ return text;
119
+ }
120
+ /** Stop the `git cat-file` process. */
121
+ close() {
122
+ this.catFile?.close();
123
+ this.catFile = undefined;
124
+ }
125
+ fetch(oids) {
126
+ this.catFile ??= new CatFile(this.repoDir);
127
+ return this.catFile.fetch(oids);
128
+ }
129
+ }
130
+ /**
131
+ * The helper thread: owns `git cat-file --batch`, writes each request's object ids to
132
+ * it, parses `<oid> <type> <size>\n<bytes>\n` answers, and posts the blobs back.
133
+ */
134
+ const HELPER = `
135
+ const { workerData } = require("worker_threads");
136
+ const { spawn } = require("child_process");
137
+ const { repoDir, port, signal } = workerData;
138
+ const git = spawn("git", ["cat-file", "--batch"], { cwd: repoDir });
139
+ let stderr = "";
140
+ let failure = null;
141
+ let request = null; // { oids, blobs, errors, body, filled }
142
+ let pending = Buffer.alloc(0);
143
+
144
+ function answer(message, transfer) {
145
+ request = null;
146
+ port.postMessage(message, transfer);
147
+ Atomics.store(signal, 0, 1);
148
+ Atomics.notify(signal, 0);
149
+ }
150
+ function fail(message) {
151
+ if (failure) return;
152
+ failure = message;
153
+ if (request) answer({ error: failure });
154
+ }
155
+ function settle() {
156
+ if (request.blobs.length + request.errors.length < request.oids.length) return;
157
+ if (request.errors.length) answer({ error: "git cat-file: " + request.errors.join("; ") });
158
+ else answer({ blobs: request.blobs }, request.blobs.map((blob) => blob.buffer));
159
+ }
160
+
161
+ git.stderr.setEncoding("utf8").on("data", (text) => (stderr += text));
162
+ git.on("error", (error) => fail("git cat-file did not start: " + error.message));
163
+ git.on("exit", (code, sig) => fail("git cat-file exited (" + (sig || code) + "): " + stderr.trim()));
164
+ git.stdin.on("error", () => {}); // a closed pipe is reported by the exit handler
165
+
166
+ port.on("close", () => git.stdin.end()); // git exits at the end of its input
167
+ port.on("message", (message) => {
168
+ if (failure) return answer({ error: failure });
169
+ request = { oids: message, blobs: [], errors: [], body: null, filled: 0, type: "" };
170
+ git.stdin.write(message.join("\\n") + "\\n");
171
+ });
172
+
173
+ git.stdout.on("data", (chunk) => {
174
+ const data = pending.length ? Buffer.concat([pending, chunk]) : chunk;
175
+ let at = 0;
176
+ while (request && at < data.length) {
177
+ if (!request.body) {
178
+ const end = data.indexOf(10, at);
179
+ if (end < 0) break;
180
+ const [oid, type, size] = data.toString("utf8", at, end).split(" ");
181
+ at = end + 1;
182
+ if (size === undefined) {
183
+ request.errors.push(oid + " " + type);
184
+ settle();
185
+ continue;
186
+ }
187
+ request.type = type;
188
+ request.body = new Uint8Array(Number(size) + 1);
189
+ request.filled = 0;
190
+ }
191
+ const n = Math.min(request.body.length - request.filled, data.length - at);
192
+ request.body.set(data.subarray(at, at + n), request.filled);
193
+ request.filled += n;
194
+ at += n;
195
+ if (request.filled === request.body.length) {
196
+ if (request.type === "blob") request.blobs.push(request.body.subarray(0, -1));
197
+ else request.errors.push("not a blob: " + request.type);
198
+ request.body = null;
199
+ settle();
200
+ }
201
+ }
202
+ pending = data.subarray(at);
203
+ });
204
+ `;
205
+ class CatFile {
206
+ worker;
207
+ port;
208
+ signal = new Int32Array(new SharedArrayBuffer(4));
209
+ constructor(repoDir) {
210
+ const { port1, port2 } = new MessageChannel();
211
+ this.worker = new Worker(HELPER, {
212
+ eval: true,
213
+ workerData: { repoDir, port: port2, signal: this.signal },
214
+ transferList: [port2],
215
+ });
216
+ this.worker.unref(); // an idle helper never keeps the process alive
217
+ this.port = port1;
218
+ this.port.unref();
219
+ }
220
+ fetch(oids) {
221
+ Atomics.store(this.signal, 0, 0);
222
+ this.port.postMessage(oids);
223
+ const deadline = Date.now() + REQUEST_TIMEOUT_MS;
224
+ for (;;) {
225
+ const received = receiveMessageOnPort(this.port);
226
+ if (received) {
227
+ const message = received.message;
228
+ if (message.error !== undefined)
229
+ throw new Error(message.error);
230
+ return message.blobs;
231
+ }
232
+ const left = deadline - Date.now();
233
+ if (left <= 0)
234
+ throw new Error(`git cat-file did not answer within ${REQUEST_TIMEOUT_MS} ms`);
235
+ Atomics.wait(this.signal, 0, 0, left);
236
+ }
237
+ }
238
+ close() {
239
+ this.port.close();
240
+ }
241
+ }
242
+ //# sourceMappingURL=git-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-source.js","sourceRoot":"","sources":["../../src/engine/git-source.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import { type BuildStore, type PageRecord, type PageSummary, type UnitRecord } from "./store.js";
2
+ /** What an overlay reads from the store under it. */
3
+ type StoreReader = Pick<BuildStore, "getMeta" | "getFileVersions" | "getUnit" | "listUnitIds" | "unitsReading" | "listPages" | "getPage" | "getArtifact" | "getFailedUnits">;
4
+ export declare class OverlayStore implements BuildStore {
5
+ private readonly base;
6
+ private readonly meta;
7
+ private readonly files;
8
+ private readonly units;
9
+ private readonly pages;
10
+ private readonly artifacts;
11
+ private readonly failed;
12
+ private running;
13
+ constructor(base?: StoreReader);
14
+ getMeta(key: string): string | undefined;
15
+ setMeta(key: string, value: string): void;
16
+ getFileVersions(): Map<string, string>;
17
+ setFileVersion(path: string, version: string | null): void;
18
+ getUnit(id: string): UnitRecord | undefined;
19
+ listUnitIds(prefix?: string): string[];
20
+ putUnit(record: UnitRecord): void;
21
+ deleteUnit(id: string): void;
22
+ unitsReading(keys: Iterable<string>): string[];
23
+ listPages(): PageSummary[];
24
+ getPage(sourcePath: string, index: number): PageRecord | undefined;
25
+ putPage(page: PageRecord): void;
26
+ deletePage(sourcePath: string, index: number): void;
27
+ getArtifact(name: string): string | undefined;
28
+ getArtifactHash(name: string): string;
29
+ putArtifact(name: string, json: string): void;
30
+ deleteArtifact(name: string): void;
31
+ setRunning(unitId: string | null): void;
32
+ getRunning(): string | null;
33
+ getFailedUnits(): Map<string, string>;
34
+ setFailedUnit(unitId: string, reason: string | null): void;
35
+ /** Nothing is written through to the base store. */
36
+ commit(): void;
37
+ atomically<T>(apply: () => T): T;
38
+ close(): void;
39
+ }
40
+ /** A store that lives in one process. Nothing is written to disk. */
41
+ export declare class MemoryStore extends OverlayStore {
42
+ }
43
+ export {};
@@ -0,0 +1,167 @@
1
+ // A copy-on-write view of a build store, for overlay jobs: the job reads the
2
+ // live build layer and keeps its own writes in memory, so it builds an edit
3
+ // that is not committed yet without changing what the platform serves. Over
4
+ // no store at all it is the store that lives in one process (MemoryStore).
5
+ import { NO_ARTIFACT, artifactHash, artifactMetaKey, comparePages, } from "./store.js";
6
+ import { pageKey, splitPageKey } from "./units.js";
7
+ /** No store: what a MemoryStore starts from. */
8
+ const EMPTY = {
9
+ getMeta: () => undefined,
10
+ getFileVersions: () => new Map(),
11
+ getUnit: () => undefined,
12
+ listUnitIds: () => [],
13
+ unitsReading: () => [],
14
+ listPages: () => [],
15
+ getPage: () => undefined,
16
+ getArtifact: () => undefined,
17
+ getFailedUnits: () => new Map(),
18
+ };
19
+ /** Local changes over `base`: a value, or null for deleted. */
20
+ class Layer {
21
+ read;
22
+ changes = new Map();
23
+ constructor(read) {
24
+ this.read = read;
25
+ }
26
+ get(key) {
27
+ const local = this.changes.get(key);
28
+ return local === null ? undefined : (local ?? this.read(key));
29
+ }
30
+ set(key, value) {
31
+ this.changes.set(key, value);
32
+ }
33
+ }
34
+ export class OverlayStore {
35
+ base;
36
+ meta;
37
+ files = new Map();
38
+ units;
39
+ pages;
40
+ artifacts;
41
+ failed = new Map();
42
+ running = null;
43
+ constructor(base = EMPTY) {
44
+ this.base = base;
45
+ this.meta = new Layer((key) => base.getMeta(key));
46
+ this.units = new Layer((id) => base.getUnit(id));
47
+ this.pages = new Layer((key) => {
48
+ const { sourcePath, index } = splitPageKey(key);
49
+ return base.getPage(sourcePath, index);
50
+ });
51
+ this.artifacts = new Layer((name) => base.getArtifact(name));
52
+ }
53
+ getMeta(key) {
54
+ return this.meta.get(key);
55
+ }
56
+ setMeta(key, value) {
57
+ this.meta.set(key, value);
58
+ }
59
+ getFileVersions() {
60
+ return merge(this.base.getFileVersions(), this.files);
61
+ }
62
+ setFileVersion(path, version) {
63
+ this.files.set(path, version);
64
+ }
65
+ getUnit(id) {
66
+ return this.units.get(id);
67
+ }
68
+ listUnitIds(prefix = "") {
69
+ const ids = new Set(this.base.listUnitIds(prefix));
70
+ for (const [id, record] of this.units.changes) {
71
+ if (!id.startsWith(prefix))
72
+ continue;
73
+ if (record)
74
+ ids.add(id);
75
+ else
76
+ ids.delete(id);
77
+ }
78
+ return [...ids].sort();
79
+ }
80
+ putUnit(record) {
81
+ this.units.set(record.id, record);
82
+ }
83
+ deleteUnit(id) {
84
+ this.units.set(id, null);
85
+ }
86
+ unitsReading(keys) {
87
+ const wanted = new Set(keys);
88
+ // The base index answers for every unit this layer has not replaced.
89
+ const ids = new Set(this.base
90
+ .unitsReading(wanted)
91
+ .filter((id) => !this.units.changes.has(id)));
92
+ for (const [id, record] of this.units.changes) {
93
+ if (record?.reads.some(({ key }) => wanted.has(key)))
94
+ ids.add(id);
95
+ }
96
+ return [...ids].sort();
97
+ }
98
+ listPages() {
99
+ const pages = new Map();
100
+ for (const page of this.base.listPages())
101
+ pages.set(pageKey(page.sourcePath, page.index), page);
102
+ for (const [key, page] of this.pages.changes) {
103
+ if (!page) {
104
+ pages.delete(key);
105
+ continue;
106
+ }
107
+ const { json: _json, ...summary } = page;
108
+ pages.set(key, summary);
109
+ }
110
+ return [...pages.values()].sort(comparePages);
111
+ }
112
+ getPage(sourcePath, index) {
113
+ return this.pages.get(pageKey(sourcePath, index));
114
+ }
115
+ putPage(page) {
116
+ this.pages.set(pageKey(page.sourcePath, page.index), page);
117
+ }
118
+ deletePage(sourcePath, index) {
119
+ this.pages.set(pageKey(sourcePath, index), null);
120
+ }
121
+ getArtifact(name) {
122
+ return this.artifacts.get(name);
123
+ }
124
+ getArtifactHash(name) {
125
+ return this.meta.get(artifactMetaKey(name)) ?? NO_ARTIFACT;
126
+ }
127
+ putArtifact(name, json) {
128
+ this.artifacts.set(name, json);
129
+ this.meta.set(artifactMetaKey(name), artifactHash(json));
130
+ }
131
+ deleteArtifact(name) {
132
+ this.artifacts.set(name, null);
133
+ this.meta.set(artifactMetaKey(name), NO_ARTIFACT);
134
+ }
135
+ setRunning(unitId) {
136
+ this.running = unitId;
137
+ }
138
+ getRunning() {
139
+ return this.running;
140
+ }
141
+ getFailedUnits() {
142
+ return merge(this.base.getFailedUnits(), this.failed);
143
+ }
144
+ setFailedUnit(unitId, reason) {
145
+ this.failed.set(unitId, reason);
146
+ }
147
+ /** Nothing is written through to the base store. */
148
+ commit() { }
149
+ atomically(apply) {
150
+ return apply();
151
+ }
152
+ close() { }
153
+ }
154
+ function merge(base, changes) {
155
+ const merged = new Map(base);
156
+ for (const [key, value] of changes) {
157
+ if (value === null)
158
+ merged.delete(key);
159
+ else
160
+ merged.set(key, value);
161
+ }
162
+ return merged;
163
+ }
164
+ /** A store that lives in one process. Nothing is written to disk. */
165
+ export class MemoryStore extends OverlayStore {
166
+ }
167
+ //# sourceMappingURL=overlay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlay.js","sourceRoot":"","sources":["../../src/engine/overlay.ts"],"names":[],"mappings":"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"}