semantifold 0.8.0 → 0.10.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/README.md +11 -5
- package/bin/semantifold.js +6 -0
- package/build/bin/semantifold.d.ts +3 -0
- package/build/bin/semantifold.d.ts.map +1 -0
- package/build/bin/semantifold.js +5 -0
- package/build/index.d.ts +9 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +10 -1
- package/build/src/artifact-path.d.ts +16 -0
- package/build/src/artifact-path.d.ts.map +1 -1
- package/build/src/artifact-path.js +29 -3
- package/build/src/backends/c-check.d.ts +7 -0
- package/build/src/backends/c-check.d.ts.map +1 -0
- package/build/src/backends/c-check.js +65 -0
- package/build/src/backends/check-plan.d.ts +96 -0
- package/build/src/backends/check-plan.d.ts.map +1 -0
- package/build/src/backends/check-plan.js +135 -0
- package/build/src/backends/cpp-check.d.ts +7 -0
- package/build/src/backends/cpp-check.d.ts.map +1 -0
- package/build/src/backends/cpp-check.js +59 -0
- package/build/src/backends/csharp-check.d.ts +7 -0
- package/build/src/backends/csharp-check.d.ts.map +1 -0
- package/build/src/backends/csharp-check.js +125 -0
- package/build/src/backends/csharp.d.ts +1 -0
- package/build/src/backends/csharp.d.ts.map +1 -1
- package/build/src/backends/csharp.js +5 -4
- package/build/src/backends/dart-check.d.ts +7 -0
- package/build/src/backends/dart-check.d.ts.map +1 -0
- package/build/src/backends/dart-check.js +103 -0
- package/build/src/backends/dart.d.ts +2 -0
- package/build/src/backends/dart.d.ts.map +1 -1
- package/build/src/backends/dart.js +5 -5
- package/build/src/backends/go-check.d.ts +7 -0
- package/build/src/backends/go-check.d.ts.map +1 -0
- package/build/src/backends/go-check.js +77 -0
- package/build/src/backends/go.d.ts +1 -0
- package/build/src/backends/go.d.ts.map +1 -1
- package/build/src/backends/go.js +3 -3
- package/build/src/backends/java-check.d.ts +21 -0
- package/build/src/backends/java-check.d.ts.map +1 -0
- package/build/src/backends/java-check.js +73 -0
- package/build/src/backends/javascript-check.d.ts +7 -0
- package/build/src/backends/javascript-check.d.ts.map +1 -0
- package/build/src/backends/javascript-check.js +29 -0
- package/build/src/backends/kotlin-check.d.ts +7 -0
- package/build/src/backends/kotlin-check.d.ts.map +1 -0
- package/build/src/backends/kotlin-check.js +31 -0
- package/build/src/backends/php-check.d.ts +7 -0
- package/build/src/backends/php-check.d.ts.map +1 -0
- package/build/src/backends/php-check.js +21 -0
- package/build/src/backends/program.d.ts +7 -0
- package/build/src/backends/program.d.ts.map +1 -1
- package/build/src/backends/program.js +16 -1
- package/build/src/backends/python-check.d.ts +7 -0
- package/build/src/backends/python-check.d.ts.map +1 -0
- package/build/src/backends/python-check.js +28 -0
- package/build/src/backends/ruby-check.d.ts +7 -0
- package/build/src/backends/ruby-check.d.ts.map +1 -0
- package/build/src/backends/ruby-check.js +21 -0
- package/build/src/backends/rust-check.d.ts +7 -0
- package/build/src/backends/rust-check.d.ts.map +1 -0
- package/build/src/backends/rust-check.js +65 -0
- package/build/src/backends/swift-check.d.ts +7 -0
- package/build/src/backends/swift-check.d.ts.map +1 -0
- package/build/src/backends/swift-check.js +77 -0
- package/build/src/backends/typescript-check.d.ts +7 -0
- package/build/src/backends/typescript-check.d.ts.map +1 -0
- package/build/src/backends/typescript-check.js +33 -0
- package/build/src/backends/zig-check.d.ts +7 -0
- package/build/src/backends/zig-check.d.ts.map +1 -0
- package/build/src/backends/zig-check.js +70 -0
- package/build/src/diagnostic.d.ts +13 -1
- package/build/src/diagnostic.d.ts.map +1 -1
- package/build/src/diagnostic.js +14 -2
- package/build/src/frontends/program.d.ts +6 -0
- package/build/src/frontends/program.d.ts.map +1 -1
- package/build/src/frontends/program.js +9 -1
- package/build/src/language-registry.d.ts +54 -0
- package/build/src/language-registry.d.ts.map +1 -1
- package/build/src/language-registry.js +107 -5
- package/build/src/project-build.d.ts +172 -0
- package/build/src/project-build.d.ts.map +1 -0
- package/build/src/project-build.js +320 -0
- package/build/src/project-cli.d.ts +40 -0
- package/build/src/project-cli.d.ts.map +1 -0
- package/build/src/project-cli.js +145 -0
- package/build/src/project-manifest.d.ts +148 -0
- package/build/src/project-manifest.d.ts.map +1 -0
- package/build/src/project-manifest.js +432 -0
- package/build/src/project-reporter.d.ts +81 -0
- package/build/src/project-reporter.d.ts.map +1 -0
- package/build/src/project-reporter.js +293 -0
- package/build/src/project-snapshot.d.ts +129 -0
- package/build/src/project-snapshot.d.ts.map +1 -0
- package/build/src/project-snapshot.js +362 -0
- package/build/src/project-watch-reporter.d.ts +125 -0
- package/build/src/project-watch-reporter.d.ts.map +1 -0
- package/build/src/project-watch-reporter.js +280 -0
- package/build/src/project-watch.d.ts +133 -0
- package/build/src/project-watch.d.ts.map +1 -0
- package/build/src/project-watch.js +839 -0
- package/build/src/publication.d.ts +218 -0
- package/build/src/publication.d.ts.map +1 -0
- package/build/src/publication.js +1832 -0
- package/build/src/semantic/types.d.ts +613 -0
- package/build/src/semantic/types.d.ts.map +1 -1
- package/build/src/semantic/types.js +163 -1
- package/build/src/subprocess.d.ts +8 -0
- package/build/src/subprocess.d.ts.map +1 -1
- package/build/src/subprocess.js +50 -9
- package/build/src/target-check.d.ts +52 -0
- package/build/src/target-check.d.ts.map +1 -0
- package/build/src/target-check.js +796 -0
- package/build/src/toolchains.d.ts.map +1 -1
- package/build/src/toolchains.js +3 -3
- package/docs/architecture.md +3 -1
- package/docs/c.md +4 -0
- package/docs/cpp.md +4 -0
- package/docs/dart.md +4 -0
- package/docs/generated-artifact-publication.md +98 -0
- package/docs/kotlin.md +2 -2
- package/docs/language-support.md +29 -3
- package/docs/project-build-cli.md +147 -0
- package/docs/project-watch.md +60 -0
- package/docs/rust.md +4 -0
- package/docs/swift.md +2 -0
- package/docs/testing.md +70 -3
- package/docs/watch-build-pipeline.md +42 -26
- package/docs/zig.md +2 -0
- package/examples/jsdoc-java-watch/expected-output.txt +3 -0
- package/examples/jsdoc-java-watch/semantifold.json +23 -0
- package/examples/jsdoc-java-watch/src/main.js +21 -0
- package/index.js +9 -0
- package/package.json +6 -1
- package/src/artifact-path.js +31 -2
- package/src/backends/c-check.js +80 -0
- package/src/backends/check-plan.js +147 -0
- package/src/backends/cpp-check.js +73 -0
- package/src/backends/csharp-check.js +139 -0
- package/src/backends/csharp.js +4 -3
- package/src/backends/dart-check.js +117 -0
- package/src/backends/dart.js +4 -4
- package/src/backends/go-check.js +89 -0
- package/src/backends/go.js +2 -2
- package/src/backends/java-check.js +77 -0
- package/src/backends/javascript-check.js +33 -0
- package/src/backends/kotlin-check.js +41 -0
- package/src/backends/php-check.js +23 -0
- package/src/backends/program.js +17 -0
- package/src/backends/python-check.js +30 -0
- package/src/backends/ruby-check.js +23 -0
- package/src/backends/rust-check.js +78 -0
- package/src/backends/swift-check.js +89 -0
- package/src/backends/typescript-check.js +37 -0
- package/src/backends/zig-check.js +81 -0
- package/src/diagnostic.js +9 -1
- package/src/frontends/program.js +9 -0
- package/src/language-registry.js +113 -4
- package/src/project-build.js +353 -0
- package/src/project-cli.js +155 -0
- package/src/project-manifest.js +479 -0
- package/src/project-reporter.js +320 -0
- package/src/project-snapshot.js +403 -0
- package/src/project-watch-reporter.js +303 -0
- package/src/project-watch.js +870 -0
- package/src/publication.js +2071 -0
- package/src/semantic/types.js +184 -0
- package/src/subprocess.js +49 -8
- package/src/target-check.js +844 -0
- package/src/toolchains.js +3 -2
- package/tsconfig.json +1 -1
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { constants } from "node:fs";
|
|
4
|
+
import { lstat, open, realpath } from "node:fs/promises";
|
|
5
|
+
import { SemantifoldDiagnostic } from "./diagnostic.js";
|
|
6
|
+
import { SemantifoldProject } from "./project-manifest.js";
|
|
7
|
+
const snapshotAttempts = 2;
|
|
8
|
+
/** @type {WeakMap<ProjectSnapshotBuilder, (event: Readonly<{attempt: number, pass: number, path: string}>) => Promise<void> | void>} */
|
|
9
|
+
const snapshotReadObservers = new WeakMap();
|
|
10
|
+
/**
|
|
11
|
+
* Installs an internal deterministic read observer for real-filesystem snapshot specs.
|
|
12
|
+
* This helper is intentionally not part of the package root API.
|
|
13
|
+
* @param {ProjectSnapshotBuilder} builder - Snapshot builder instance.
|
|
14
|
+
* @param {(event: Readonly<{attempt: number, pass: number, path: string}>) => Promise<void> | void} observer - Ordered read observer.
|
|
15
|
+
* @returns {void}
|
|
16
|
+
*/
|
|
17
|
+
export function observeProjectSnapshotReads(builder, observer) {
|
|
18
|
+
if (!(builder instanceof ProjectSnapshotBuilder) || typeof observer != "function") {
|
|
19
|
+
throw new TypeError("Invalid project snapshot read observer.");
|
|
20
|
+
}
|
|
21
|
+
snapshotReadObservers.set(builder, observer);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* One complete immutable ordered source snapshot.
|
|
25
|
+
*/
|
|
26
|
+
export class ProjectSnapshot {
|
|
27
|
+
/**
|
|
28
|
+
* Constructs a trusted snapshot value.
|
|
29
|
+
* @param {{hash: string, manifestText: string, projectId: string, sources: SnapshotSource[]}} value - Stable snapshot fields.
|
|
30
|
+
*/
|
|
31
|
+
constructor(value) {
|
|
32
|
+
this.hash = value.hash;
|
|
33
|
+
this.manifestText = value.manifestText;
|
|
34
|
+
this.projectId = value.projectId;
|
|
35
|
+
this.sources = Object.freeze(value.sources.map(source => Object.freeze({ ...source })));
|
|
36
|
+
Object.freeze(this);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Reads one complete graph twice before exposing an immutable source snapshot.
|
|
41
|
+
*/
|
|
42
|
+
export class ProjectSnapshotBuilder {
|
|
43
|
+
/**
|
|
44
|
+
* Builds a stable snapshot with one bounded retry when the graph changes mid-read.
|
|
45
|
+
* @param {SemantifoldProject} project - Validated immutable project.
|
|
46
|
+
* @returns {Promise<ProjectSnapshot>} Stable complete snapshot.
|
|
47
|
+
*/
|
|
48
|
+
async build(project) {
|
|
49
|
+
if (!(project instanceof SemantifoldProject)) {
|
|
50
|
+
snapshotFailure("INVALID_PROJECT_SNAPSHOT", "project", "Snapshot building requires a validated Semantifold project.");
|
|
51
|
+
}
|
|
52
|
+
let unstablePath = "semantifold.json";
|
|
53
|
+
for (let attempt = 0; attempt < snapshotAttempts; attempt += 1) {
|
|
54
|
+
try {
|
|
55
|
+
const first = await readProjectGraph(project, this, attempt + 1, 1);
|
|
56
|
+
const second = await readProjectGraph(project, this, attempt + 1, 2);
|
|
57
|
+
const difference = graphDifference(first, second, project);
|
|
58
|
+
if (difference !== null) {
|
|
59
|
+
unstablePath = difference;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const finalDifference = await graphStateDifference(project, second);
|
|
63
|
+
if (finalDifference !== null) {
|
|
64
|
+
unstablePath = finalDifference;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
const manifestText = decodeUtf8(first.manifestBytes, "semantifold.json", project.id);
|
|
68
|
+
if (manifestText != project.manifestText) {
|
|
69
|
+
snapshotFailure("UNSTABLE_PROJECT_SNAPSHOT", project.id, "Project manifest changed after it was validated; restart the build from the new manifest.", manifestLocation());
|
|
70
|
+
}
|
|
71
|
+
const sources = project.sources.map((source, index) => ({
|
|
72
|
+
id: source.id,
|
|
73
|
+
language: source.language,
|
|
74
|
+
path: source.path,
|
|
75
|
+
source: decodeUtf8(first.sourceBytes[index], source.path, project.id)
|
|
76
|
+
}));
|
|
77
|
+
return new ProjectSnapshot({
|
|
78
|
+
hash: snapshotHash(first.manifestBytes, sources),
|
|
79
|
+
manifestText,
|
|
80
|
+
projectId: project.id,
|
|
81
|
+
sources
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
if (!(error instanceof UnstableSnapshotRead))
|
|
86
|
+
throw error;
|
|
87
|
+
unstablePath = error.path;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return snapshotFailure("UNSTABLE_PROJECT_SNAPSHOT", project.id, "Project manifest or source files changed repeatedly while the snapshot was loading.", sourceLocation(unstablePath));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Reads every declared file in stable manifest order.
|
|
95
|
+
* @param {SemantifoldProject} project - Validated project.
|
|
96
|
+
* @param {ProjectSnapshotBuilder} builder - Active builder.
|
|
97
|
+
* @param {number} attempt - One-based bounded attempt.
|
|
98
|
+
* @param {number} pass - One-based verification pass.
|
|
99
|
+
* @returns {Promise<ProjectGraphRead>} Complete graph bytes.
|
|
100
|
+
*/
|
|
101
|
+
async function readProjectGraph(project, builder, attempt, pass) {
|
|
102
|
+
const manifest = await readStableRegularFile(project.manifestPath, "semantifold.json", project.id, true);
|
|
103
|
+
await snapshotReadObservers.get(builder)?.(Object.freeze({ attempt, pass, path: "semantifold.json" }));
|
|
104
|
+
/** @type {Buffer[]} */
|
|
105
|
+
const sourceBytes = [];
|
|
106
|
+
/** @type {string[]} */
|
|
107
|
+
const sourceIdentities = [];
|
|
108
|
+
/** @type {string[]} */
|
|
109
|
+
const sourceStates = [];
|
|
110
|
+
const uniqueSourceIdentities = new Set();
|
|
111
|
+
for (const source of project.sources) {
|
|
112
|
+
const read = await readStableRegularFile(source.absolutePath, source.path, project.id, false);
|
|
113
|
+
if (uniqueSourceIdentities.has(read.identity)) {
|
|
114
|
+
snapshotFailure("PROJECT_SOURCE_ALIAS", project.id, "Project source paths must not alias the same file.", sourceLocation(source.path));
|
|
115
|
+
}
|
|
116
|
+
uniqueSourceIdentities.add(read.identity);
|
|
117
|
+
sourceBytes.push(read.bytes);
|
|
118
|
+
sourceIdentities.push(read.identity);
|
|
119
|
+
sourceStates.push(read.state);
|
|
120
|
+
await snapshotReadObservers.get(builder)?.(Object.freeze({ attempt, pass, path: source.path }));
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
manifestBytes: manifest.bytes,
|
|
124
|
+
manifestIdentity: manifest.identity,
|
|
125
|
+
manifestState: manifest.state,
|
|
126
|
+
sourceBytes,
|
|
127
|
+
sourceIdentities,
|
|
128
|
+
sourceStates
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Reads exact bytes through one descriptor while detecting replacement or mutation.
|
|
133
|
+
* @param {string} filename - Canonical absolute path.
|
|
134
|
+
* @param {string} displayPath - Project-relative diagnostic path.
|
|
135
|
+
* @param {string} projectId - Project identity.
|
|
136
|
+
* @param {boolean} manifest - Whether this is the project manifest.
|
|
137
|
+
* @returns {Promise<StableFileRead>} Stable bytes and filesystem identity.
|
|
138
|
+
*/
|
|
139
|
+
async function readStableRegularFile(filename, displayPath, projectId, manifest) {
|
|
140
|
+
let handle;
|
|
141
|
+
try {
|
|
142
|
+
handle = await open(filename, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0));
|
|
143
|
+
const beforePath = await realpath(filename);
|
|
144
|
+
const before = await handle.stat({ bigint: true });
|
|
145
|
+
const beforeEntry = await lstat(filename, { bigint: true });
|
|
146
|
+
if (!before.isFile() || !beforeEntry.isFile() || beforePath != filename || !sameFileIdentity(before, beforeEntry)) {
|
|
147
|
+
throw new UnstableSnapshotRead(displayPath);
|
|
148
|
+
}
|
|
149
|
+
const bytes = await handle.readFile();
|
|
150
|
+
const after = await handle.stat({ bigint: true });
|
|
151
|
+
const afterPath = await realpath(filename);
|
|
152
|
+
const afterEntry = await lstat(filename, { bigint: true });
|
|
153
|
+
if (!after.isFile() || !afterEntry.isFile() || afterPath != filename || !sameFileState(before, after) ||
|
|
154
|
+
!sameFileIdentity(after, afterEntry) || BigInt(bytes.byteLength) != after.size) {
|
|
155
|
+
throw new UnstableSnapshotRead(displayPath);
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
bytes,
|
|
159
|
+
identity: `${String(before.dev)}:${String(before.ino)}`,
|
|
160
|
+
state: stableFileState(before)
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
if (error instanceof UnstableSnapshotRead)
|
|
165
|
+
throw error;
|
|
166
|
+
return snapshotFailure(manifest ? "PROJECT_MANIFEST_READ_FAILED" : "PROJECT_SOURCE_READ_FAILED", projectId, manifest ? "Project manifest could not be read into a stable snapshot." : "Declared source could not be read into a stable snapshot.", sourceLocation(displayPath), error);
|
|
167
|
+
}
|
|
168
|
+
finally {
|
|
169
|
+
await handle?.close();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Compares descriptor state around one read.
|
|
174
|
+
* @param {import("node:fs").BigIntStats} left - State before the read.
|
|
175
|
+
* @param {import("node:fs").BigIntStats} right - State after the read.
|
|
176
|
+
* @returns {boolean} Whether identity and mutation-sensitive metadata agree.
|
|
177
|
+
*/
|
|
178
|
+
function sameFileState(left, right) {
|
|
179
|
+
return left.dev == right.dev && left.ino == right.ino && left.size == right.size &&
|
|
180
|
+
left.mtimeNs == right.mtimeNs && left.ctimeNs == right.ctimeNs;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Compares the path entry with the opened descriptor identity.
|
|
184
|
+
* @param {import("node:fs").BigIntStats} left - Open descriptor or path state.
|
|
185
|
+
* @param {import("node:fs").BigIntStats} right - Open descriptor or path state.
|
|
186
|
+
* @returns {boolean} Whether both identify the same filesystem node.
|
|
187
|
+
*/
|
|
188
|
+
function sameFileIdentity(left, right) {
|
|
189
|
+
return left.dev == right.dev && left.ino == right.ino;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Serializes mutation-sensitive descriptor state for complete-graph comparison.
|
|
193
|
+
* @param {import("node:fs").BigIntStats} status - Stable descriptor state.
|
|
194
|
+
* @returns {string} Internal state identity.
|
|
195
|
+
*/
|
|
196
|
+
function stableFileState(status) {
|
|
197
|
+
return [status.dev, status.ino, status.size, status.mtimeNs, status.ctimeNs].map(String).join(":");
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Locates the first byte difference between two complete graph reads.
|
|
201
|
+
* @param {ProjectGraphRead} left - First graph.
|
|
202
|
+
* @param {ProjectGraphRead} right - Second graph.
|
|
203
|
+
* @param {SemantifoldProject} project - Ordered path authority.
|
|
204
|
+
* @returns {string | null} Project-relative changed path, or null.
|
|
205
|
+
*/
|
|
206
|
+
function graphDifference(left, right, project) {
|
|
207
|
+
if (left.manifestIdentity != right.manifestIdentity || left.manifestState != right.manifestState ||
|
|
208
|
+
!left.manifestBytes.equals(right.manifestBytes)) {
|
|
209
|
+
return "semantifold.json";
|
|
210
|
+
}
|
|
211
|
+
if (left.sourceBytes.length != right.sourceBytes.length)
|
|
212
|
+
return "semantifold.json";
|
|
213
|
+
const index = left.sourceBytes.findIndex((bytes, sourceIndex) => left.sourceIdentities[sourceIndex] != right.sourceIdentities[sourceIndex] ||
|
|
214
|
+
left.sourceStates[sourceIndex] != right.sourceStates[sourceIndex] || !bytes.equals(right.sourceBytes[sourceIndex]));
|
|
215
|
+
return index == -1 ? null : project.sources[index].path;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Revalidates every path entry after the final complete graph read.
|
|
219
|
+
* @param {SemantifoldProject} project - Ordered path authority.
|
|
220
|
+
* @param {ProjectGraphRead} graph - Final complete graph read.
|
|
221
|
+
* @returns {Promise<string | null>} First changed project-relative path, or null.
|
|
222
|
+
*/
|
|
223
|
+
async function graphStateDifference(project, graph) {
|
|
224
|
+
const entries = [{
|
|
225
|
+
filename: project.manifestPath,
|
|
226
|
+
identity: graph.manifestIdentity,
|
|
227
|
+
path: "semantifold.json",
|
|
228
|
+
state: graph.manifestState
|
|
229
|
+
}, ...project.sources.map((source, index) => ({
|
|
230
|
+
filename: source.absolutePath,
|
|
231
|
+
identity: graph.sourceIdentities[index],
|
|
232
|
+
path: source.path,
|
|
233
|
+
state: graph.sourceStates[index]
|
|
234
|
+
}))];
|
|
235
|
+
for (const entry of entries) {
|
|
236
|
+
try {
|
|
237
|
+
const status = await lstat(entry.filename, { bigint: true });
|
|
238
|
+
const exact = await realpath(entry.filename);
|
|
239
|
+
if (!status.isFile() || exact != entry.filename || `${String(status.dev)}:${String(status.ino)}` != entry.identity ||
|
|
240
|
+
stableFileState(status) != entry.state)
|
|
241
|
+
return entry.path;
|
|
242
|
+
}
|
|
243
|
+
catch (_error) {
|
|
244
|
+
return entry.path;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Computes a framed deterministic SHA-256 identity over exact manifest and ordered source inputs.
|
|
251
|
+
* @param {Buffer} manifestBytes - Exact manifest bytes.
|
|
252
|
+
* @param {readonly SnapshotSource[]} sources - Ordered decoded sources.
|
|
253
|
+
* @returns {string} Lowercase SHA-256 digest.
|
|
254
|
+
*/
|
|
255
|
+
function snapshotHash(manifestBytes, sources) {
|
|
256
|
+
const hash = createHash("sha256");
|
|
257
|
+
updateHash(hash, "SemantifoldProjectSnapshot/1");
|
|
258
|
+
updateHash(hash, manifestBytes);
|
|
259
|
+
for (const source of sources) {
|
|
260
|
+
updateHash(hash, source.id);
|
|
261
|
+
updateHash(hash, source.path);
|
|
262
|
+
updateHash(hash, source.language);
|
|
263
|
+
updateHash(hash, source.source);
|
|
264
|
+
}
|
|
265
|
+
return hash.digest("hex");
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Adds one length-framed field to a content hash.
|
|
269
|
+
* @param {import("node:crypto").Hash} hash - Active hash.
|
|
270
|
+
* @param {string | Buffer} value - Field bytes.
|
|
271
|
+
* @returns {void}
|
|
272
|
+
*/
|
|
273
|
+
function updateHash(hash, value) {
|
|
274
|
+
const bytes = Buffer.isBuffer(value) ? value : Buffer.from(value, "utf8");
|
|
275
|
+
const length = Buffer.alloc(8);
|
|
276
|
+
length.writeBigUInt64BE(BigInt(bytes.byteLength));
|
|
277
|
+
hash.update(length);
|
|
278
|
+
hash.update(bytes);
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Decodes strict UTF-8 for parser inputs.
|
|
282
|
+
* @param {Buffer} bytes - Exact file bytes.
|
|
283
|
+
* @param {string} filename - Project-relative filename.
|
|
284
|
+
* @param {string} projectId - Project identity.
|
|
285
|
+
* @returns {string} Decoded source.
|
|
286
|
+
*/
|
|
287
|
+
function decodeUtf8(bytes, filename, projectId) {
|
|
288
|
+
try {
|
|
289
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
return snapshotFailure("INVALID_PROJECT_SOURCE_ENCODING", projectId, "Project manifests and sources must be valid UTF-8.", sourceLocation(filename), error);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
/** Internal marker for a read that may safely use the bounded retry. */
|
|
296
|
+
class UnstableSnapshotRead extends Error {
|
|
297
|
+
/**
|
|
298
|
+
* Creates an internal retry marker.
|
|
299
|
+
* @param {string} path - Project-relative unstable path.
|
|
300
|
+
*/
|
|
301
|
+
constructor(path) {
|
|
302
|
+
super("Unstable project snapshot read.");
|
|
303
|
+
this.path = path;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Creates the stable manifest boundary location.
|
|
308
|
+
* @returns {import("./semantic/types.js").SourceLocation} Manifest location.
|
|
309
|
+
*/
|
|
310
|
+
function manifestLocation() {
|
|
311
|
+
return sourceLocation("semantifold.json");
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Creates a stable project-relative file location.
|
|
315
|
+
* @param {string} filename - Project-relative filename.
|
|
316
|
+
* @returns {import("./semantic/types.js").SourceLocation} Start-of-file location.
|
|
317
|
+
*/
|
|
318
|
+
function sourceLocation(filename) {
|
|
319
|
+
const point = { column: 1, line: 1, offset: 0 };
|
|
320
|
+
return { end: point, filename, start: point };
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Throws one stable snapshot diagnostic.
|
|
324
|
+
* @param {string} code - Stable diagnostic code.
|
|
325
|
+
* @param {string} projectId - Project identity.
|
|
326
|
+
* @param {string} message - Stable detail.
|
|
327
|
+
* @param {import("./semantic/types.js").SourceLocation} [location] - Project-relative location.
|
|
328
|
+
* @param {unknown} [error] - Preserved cause.
|
|
329
|
+
* @returns {never} Always throws.
|
|
330
|
+
*/
|
|
331
|
+
function snapshotFailure(code, projectId, message, location, error) {
|
|
332
|
+
throw new SemantifoldDiagnostic({
|
|
333
|
+
cause: error instanceof Error ? error : undefined,
|
|
334
|
+
code,
|
|
335
|
+
language: projectId,
|
|
336
|
+
location,
|
|
337
|
+
message
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* @typedef SnapshotSource
|
|
342
|
+
* @property {string} id - Stable semantic module identity.
|
|
343
|
+
* @property {import("./semantic/types.js").SemanticLanguage} language - Registered source language.
|
|
344
|
+
* @property {string} path - Project-relative source path.
|
|
345
|
+
* @property {string} source - Exact decoded source text.
|
|
346
|
+
*/
|
|
347
|
+
/**
|
|
348
|
+
* @typedef ProjectGraphRead
|
|
349
|
+
* @property {Buffer} manifestBytes - Exact manifest bytes.
|
|
350
|
+
* @property {string} manifestIdentity - Stable manifest device/inode identity.
|
|
351
|
+
* @property {string} manifestState - Stable manifest mutation-sensitive state.
|
|
352
|
+
* @property {Buffer[]} sourceBytes - Exact source bytes in manifest order.
|
|
353
|
+
* @property {string[]} sourceIdentities - Stable source device/inode identities in manifest order.
|
|
354
|
+
* @property {string[]} sourceStates - Stable source mutation-sensitive states in manifest order.
|
|
355
|
+
*/
|
|
356
|
+
/**
|
|
357
|
+
* @typedef StableFileRead
|
|
358
|
+
* @property {Buffer} bytes - Exact stable file bytes.
|
|
359
|
+
* @property {string} identity - Stable device/inode identity.
|
|
360
|
+
* @property {string} state - Stable mutation-sensitive file state.
|
|
361
|
+
*/
|
|
362
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvamVjdC1zbmFwc2hvdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wcm9qZWN0LXNuYXBzaG90LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sYUFBYSxDQUFBO0FBQ3RDLE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxTQUFTLENBQUE7QUFDakMsT0FBTyxFQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFDLE1BQU0sa0JBQWtCLENBQUE7QUFDdEQsT0FBTyxFQUFDLHFCQUFxQixFQUFDLE1BQU0saUJBQWlCLENBQUE7QUFDckQsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0sdUJBQXVCLENBQUE7QUFFeEQsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLENBQUE7QUFDMUIsd0lBQXdJO0FBQ3hJLE1BQU0scUJBQXFCLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQTtBQUUzQzs7Ozs7O0dBTUc7QUFDSCxNQUFNLFVBQVUsMkJBQTJCLENBQUMsT0FBTyxFQUFFLFFBQVE7SUFDM0QsSUFBSSxDQUFDLENBQUMsT0FBTyxZQUFZLHNCQUFzQixDQUFDLElBQUksT0FBTyxRQUFRLElBQUksVUFBVSxFQUFFLENBQUM7UUFDbEYsTUFBTSxJQUFJLFNBQVMsQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFBO0lBQ2hFLENBQUM7SUFDRCxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFBO0FBQzlDLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQU0sT0FBTyxlQUFlO0lBQzFCOzs7T0FHRztJQUNILFlBQVksS0FBSztRQUNmLElBQUksQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQTtRQUN0QixJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQyxZQUFZLENBQUE7UUFDdEMsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUMsU0FB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QUksRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBQyxDQUFBO0lBRTdDLE9BQU8sRUFBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFDLENBQUE7QUFDN0MsQ0FBQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsU0FBUyxlQUFlLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLEtBQUs7SUFDaEUsTUFBTSxJQUFJLHFCQUFxQixDQUFDO1FBQzlCLEtBQUssRUFBRSxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFNBQVM7UUFDakQsSUFBSTtRQUNKLFFBQVEsRUFBRSxTQUFTO1FBQ25CLFFBQVE7UUFDUixPQUFPO0tBQ1IsQ0FBQyxDQUFBO0FBQ0osQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUVIOzs7Ozs7OztHQVFHO0FBRUg7Ozs7O0dBS0ciLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHtjcmVhdGVIYXNofSBmcm9tIFwibm9kZTpjcnlwdG9cIlxuaW1wb3J0IHtjb25zdGFudHN9IGZyb20gXCJub2RlOmZzXCJcbmltcG9ydCB7bHN0YXQsIG9wZW4sIHJlYWxwYXRofSBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiXG5pbXBvcnQge1NlbWFudGlmb2xkRGlhZ25vc3RpY30gZnJvbSBcIi4vZGlhZ25vc3RpYy5qc1wiXG5pbXBvcnQge1NlbWFudGlmb2xkUHJvamVjdH0gZnJvbSBcIi4vcHJvamVjdC1tYW5pZmVzdC5qc1wiXG5cbmNvbnN0IHNuYXBzaG90QXR0ZW1wdHMgPSAyXG4vKiogQHR5cGUge1dlYWtNYXA8UHJvamVjdFNuYXBzaG90QnVpbGRlciwgKGV2ZW50OiBSZWFkb25seTx7YXR0ZW1wdDogbnVtYmVyLCBwYXNzOiBudW1iZXIsIHBhdGg6IHN0cmluZ30+KSA9PiBQcm9taXNlPHZvaWQ+IHwgdm9pZD59ICovXG5jb25zdCBzbmFwc2hvdFJlYWRPYnNlcnZlcnMgPSBuZXcgV2Vha01hcCgpXG5cbi8qKlxuICogSW5zdGFsbHMgYW4gaW50ZXJuYWwgZGV0ZXJtaW5pc3RpYyByZWFkIG9ic2VydmVyIGZvciByZWFsLWZpbGVzeXN0ZW0gc25hcHNob3Qgc3BlY3MuXG4gKiBUaGlzIGhlbHBlciBpcyBpbnRlbnRpb25hbGx5IG5vdCBwYXJ0IG9mIHRoZSBwYWNrYWdlIHJvb3QgQVBJLlxuICogQHBhcmFtIHtQcm9qZWN0U25hcHNob3RCdWlsZGVyfSBidWlsZGVyIC0gU25hcHNob3QgYnVpbGRlciBpbnN0YW5jZS5cbiAqIEBwYXJhbSB7KGV2ZW50OiBSZWFkb25seTx7YXR0ZW1wdDogbnVtYmVyLCBwYXNzOiBudW1iZXIsIHBhdGg6IHN0cmluZ30+KSA9PiBQcm9taXNlPHZvaWQ+IHwgdm9pZH0gb2JzZXJ2ZXIgLSBPcmRlcmVkIHJlYWQgb2JzZXJ2ZXIuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9ic2VydmVQcm9qZWN0U25hcHNob3RSZWFkcyhidWlsZGVyLCBvYnNlcnZlcikge1xuICBpZiAoIShidWlsZGVyIGluc3RhbmNlb2YgUHJvamVjdFNuYXBzaG90QnVpbGRlcikgfHwgdHlwZW9mIG9ic2VydmVyICE9IFwiZnVuY3Rpb25cIikge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIHByb2plY3Qgc25hcHNob3QgcmVhZCBvYnNlcnZlci5cIilcbiAgfVxuICBzbmFwc2hvdFJlYWRPYnNlcnZlcnMuc2V0KGJ1aWxkZXIsIG9ic2VydmVyKVxufVxuXG4vKipcbiAqIE9uZSBjb21wbGV0ZSBpbW11dGFibGUgb3JkZXJlZCBzb3VyY2Ugc25hcHNob3QuXG4gKi9cbmV4cG9ydCBjbGFzcyBQcm9qZWN0U25hcHNob3Qge1xuICAvKipcbiAgICogQ29uc3RydWN0cyBhIHRydXN0ZWQgc25hcHNob3QgdmFsdWUuXG4gICAqIEBwYXJhbSB7e2hhc2g6IHN0cmluZywgbWFuaWZlc3RUZXh0OiBzdHJpbmcsIHByb2plY3RJZDogc3RyaW5nLCBzb3VyY2VzOiBTbmFwc2hvdFNvdXJjZVtdfX0gdmFsdWUgLSBTdGFibGUgc25hcHNob3QgZmllbGRzLlxuICAgKi9cbiAgY29uc3RydWN0b3IodmFsdWUpIHtcbiAgICB0aGlzLmhhc2ggPSB2YWx1ZS5oYXNoXG4gICAgdGhpcy5tYW5pZmVzdFRleHQgPSB2YWx1ZS5tYW5pZmVzdFRleHRcbiAgICB0aGlzLnByb2plY3RJZCA9IHZhbHVlLnByb2plY3RJZFxuICAgIHRoaXMuc291cmNlcyA9IE9iamVjdC5mcmVlemUodmFsdWUuc291cmNlcy5tYXAoc291cmNlID0+IE9iamVjdC5mcmVlemUoey4uLnNvdXJjZX0pKSlcbiAgICBPYmplY3QuZnJlZXplKHRoaXMpXG4gIH1cbn1cblxuLyoqXG4gKiBSZWFkcyBvbmUgY29tcGxldGUgZ3JhcGggdHdpY2UgYmVmb3JlIGV4cG9zaW5nIGFuIGltbXV0YWJsZSBzb3VyY2Ugc25hcHNob3QuXG4gKi9cbmV4cG9ydCBjbGFzcyBQcm9qZWN0U25hcHNob3RCdWlsZGVyIHtcbiAgLyoqXG4gICAqIEJ1aWxkcyBhIHN0YWJsZSBzbmFwc2hvdCB3aXRoIG9uZSBib3VuZGVkIHJldHJ5IHdoZW4gdGhlIGdyYXBoIGNoYW5nZXMgbWlkLXJlYWQuXG4gICAqIEBwYXJhbSB7U2VtYW50aWZvbGRQcm9qZWN0fSBwcm9qZWN0IC0gVmFsaWRhdGVkIGltbXV0YWJsZSBwcm9qZWN0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxQcm9qZWN0U25hcHNob3Q+fSBTdGFibGUgY29tcGxldGUgc25hcHNob3QuXG4gICAqL1xuICBhc3luYyBidWlsZChwcm9qZWN0KSB7XG4gICAgaWYgKCEocHJvamVjdCBpbnN0YW5jZW9mIFNlbWFudGlmb2xkUHJvamVjdCkpIHtcbiAgICAgIHNuYXBzaG90RmFpbHVyZShcIklOVkFMSURfUFJPSkVDVF9TTkFQU0hPVFwiLCBcInByb2plY3RcIiwgXCJTbmFwc2hvdCBidWlsZGluZyByZXF1aXJlcyBhIHZhbGlkYXRlZCBTZW1hbnRpZm9sZCBwcm9qZWN0LlwiKVxuICAgIH1cbiAgICBsZXQgdW5zdGFibGVQYXRoID0gXCJzZW1hbnRpZm9sZC5qc29uXCJcblxuICAgIGZvciAobGV0IGF0dGVtcHQgPSAwOyBhdHRlbXB0IDwgc25hcHNob3RBdHRlbXB0czsgYXR0ZW1wdCArPSAxKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBmaXJzdCA9IGF3YWl0IHJlYWRQcm9qZWN0R3JhcGgocHJvamVjdCwgdGhpcywgYXR0ZW1wdCArIDEsIDEpXG4gICAgICAgIGNvbnN0IHNlY29uZCA9IGF3YWl0IHJlYWRQcm9qZWN0R3JhcGgocHJvamVjdCwgdGhpcywgYXR0ZW1wdCArIDEsIDIpXG4gICAgICAgIGNvbnN0IGRpZmZlcmVuY2UgPSBncmFwaERpZmZlcmVuY2UoZmlyc3QsIHNlY29uZCwgcHJvamVjdClcblxuICAgICAgICBpZiAoZGlmZmVyZW5jZSAhPT0gbnVsbCkge1xuICAgICAgICAgIHVuc3RhYmxlUGF0aCA9IGRpZmZlcmVuY2VcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGZpbmFsRGlmZmVyZW5jZSA9IGF3YWl0IGdyYXBoU3RhdGVEaWZmZXJlbmNlKHByb2plY3QsIHNlY29uZClcblxuICAgICAgICBpZiAoZmluYWxEaWZmZXJlbmNlICE9PSBudWxsKSB7XG4gICAgICAgICAgdW5zdGFibGVQYXRoID0gZmluYWxEaWZmZXJlbmNlXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBtYW5pZmVzdFRleHQgPSBkZWNvZGVVdGY4KGZpcnN0Lm1hbmlmZXN0Qnl0ZXMsIFwic2VtYW50aWZvbGQuanNvblwiLCBwcm9qZWN0LmlkKVxuXG4gICAgICAgIGlmIChtYW5pZmVzdFRleHQgIT0gcHJvamVjdC5tYW5pZmVzdFRleHQpIHtcbiAgICAgICAgICBzbmFwc2hvdEZhaWx1cmUoXCJVTlNUQUJMRV9QUk9KRUNUX1NOQVBTSE9UXCIsIHByb2plY3QuaWQsXG4gICAgICAgICAgICBcIlByb2plY3QgbWFuaWZlc3QgY2hhbmdlZCBhZnRlciBpdCB3YXMgdmFsaWRhdGVkOyByZXN0YXJ0IHRoZSBidWlsZCBmcm9tIHRoZSBuZXcgbWFuaWZlc3QuXCIsIG1hbmlmZXN0TG9jYXRpb24oKSlcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzb3VyY2VzID0gcHJvamVjdC5zb3VyY2VzLm1hcCgoc291cmNlLCBpbmRleCkgPT4gKHtcbiAgICAgICAgICBpZDogc291cmNlLmlkLFxuICAgICAgICAgIGxhbmd1YWdlOiBzb3VyY2UubGFuZ3VhZ2UsXG4gICAgICAgICAgcGF0aDogc291cmNlLnBhdGgsXG4gICAgICAgICAgc291cmNlOiBkZWNvZGVVdGY4KGZpcnN0LnNvdXJjZUJ5dGVzW2luZGV4XSwgc291cmNlLnBhdGgsIHByb2plY3QuaWQpXG4gICAgICAgIH0pKVxuXG4gICAgICAgIHJldHVybiBuZXcgUHJvamVjdFNuYXBzaG90KHtcbiAgICAgICAgICBoYXNoOiBzbmFwc2hvdEhhc2goZmlyc3QubWFuaWZlc3RCeXRlcywgc291cmNlcyksXG4gICAgICAgICAgbWFuaWZlc3RUZXh0LFxuICAgICAgICAgIHByb2plY3RJZDogcHJvamVjdC5pZCxcbiAgICAgICAgICBzb3VyY2VzXG4gICAgICAgIH0pXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoIShlcnJvciBpbnN0YW5jZW9mIFVuc3RhYmxlU25hcHNob3RSZWFkKSkgdGhyb3cgZXJyb3JcbiAgICAgICAgdW5zdGFibGVQYXRoID0gZXJyb3IucGF0aFxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBzbmFwc2hvdEZhaWx1cmUoXCJVTlNUQUJMRV9QUk9KRUNUX1NOQVBTSE9UXCIsIHByb2plY3QuaWQsXG4gICAgICBcIlByb2plY3QgbWFuaWZlc3Qgb3Igc291cmNlIGZpbGVzIGNoYW5nZWQgcmVwZWF0ZWRseSB3aGlsZSB0aGUgc25hcHNob3Qgd2FzIGxvYWRpbmcuXCIsIHNvdXJjZUxvY2F0aW9uKHVuc3RhYmxlUGF0aCkpXG4gIH1cbn1cblxuLyoqXG4gKiBSZWFkcyBldmVyeSBkZWNsYXJlZCBmaWxlIGluIHN0YWJsZSBtYW5pZmVzdCBvcmRlci5cbiAqIEBwYXJhbSB7U2VtYW50aWZvbGRQcm9qZWN0fSBwcm9qZWN0IC0gVmFsaWRhdGVkIHByb2plY3QuXG4gKiBAcGFyYW0ge1Byb2plY3RTbmFwc2hvdEJ1aWxkZXJ9IGJ1aWxkZXIgLSBBY3RpdmUgYnVpbGRlci5cbiAqIEBwYXJhbSB7bnVtYmVyfSBhdHRlbXB0IC0gT25lLWJhc2VkIGJvdW5kZWQgYXR0ZW1wdC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBwYXNzIC0gT25lLWJhc2VkIHZlcmlmaWNhdGlvbiBwYXNzLlxuICogQHJldHVybnMge1Byb21pc2U8UHJvamVjdEdyYXBoUmVhZD59IENvbXBsZXRlIGdyYXBoIGJ5dGVzLlxuICovXG5hc3luYyBmdW5jdGlvbiByZWFkUHJvamVjdEdyYXBoKHByb2plY3QsIGJ1aWxkZXIsIGF0dGVtcHQsIHBhc3MpIHtcbiAgY29uc3QgbWFuaWZlc3QgPSBhd2FpdCByZWFkU3RhYmxlUmVndWxhckZpbGUocHJvamVjdC5tYW5pZmVzdFBhdGgsIFwic2VtYW50aWZvbGQuanNvblwiLCBwcm9qZWN0LmlkLCB0cnVlKVxuXG4gIGF3YWl0IHNuYXBzaG90UmVhZE9ic2VydmVycy5nZXQoYnVpbGRlcik/LihPYmplY3QuZnJlZXplKHthdHRlbXB0LCBwYXNzLCBwYXRoOiBcInNlbWFudGlmb2xkLmpzb25cIn0pKVxuICAvKiogQHR5cGUge0J1ZmZlcltdfSAqL1xuICBjb25zdCBzb3VyY2VCeXRlcyA9IFtdXG4gIC8qKiBAdHlwZSB7c3RyaW5nW119ICovXG4gIGNvbnN0IHNvdXJjZUlkZW50aXRpZXMgPSBbXVxuICAvKiogQHR5cGUge3N0cmluZ1tdfSAqL1xuICBjb25zdCBzb3VyY2VTdGF0ZXMgPSBbXVxuICBjb25zdCB1bmlxdWVTb3VyY2VJZGVudGl0aWVzID0gbmV3IFNldCgpXG5cbiAgZm9yIChjb25zdCBzb3VyY2Ugb2YgcHJvamVjdC5zb3VyY2VzKSB7XG4gICAgY29uc3QgcmVhZCA9IGF3YWl0IHJlYWRTdGFibGVSZWd1bGFyRmlsZShzb3VyY2UuYWJzb2x1dGVQYXRoLCBzb3VyY2UucGF0aCwgcHJvamVjdC5pZCwgZmFsc2UpXG5cbiAgICBpZiAodW5pcXVlU291cmNlSWRlbnRpdGllcy5oYXMocmVhZC5pZGVudGl0eSkpIHtcbiAgICAgIHNuYXBzaG90RmFpbHVyZShcIlBST0pFQ1RfU09VUkNFX0FMSUFTXCIsIHByb2plY3QuaWQsXG4gICAgICAgIFwiUHJvamVjdCBzb3VyY2UgcGF0aHMgbXVzdCBub3QgYWxpYXMgdGhlIHNhbWUgZmlsZS5cIiwgc291cmNlTG9jYXRpb24oc291cmNlLnBhdGgpKVxuICAgIH1cbiAgICB1bmlxdWVTb3VyY2VJZGVudGl0aWVzLmFkZChyZWFkLmlkZW50aXR5KVxuICAgIHNvdXJjZUJ5dGVzLnB1c2gocmVhZC5ieXRlcylcbiAgICBzb3VyY2VJZGVudGl0aWVzLnB1c2gocmVhZC5pZGVudGl0eSlcbiAgICBzb3VyY2VTdGF0ZXMucHVzaChyZWFkLnN0YXRlKVxuICAgIGF3YWl0IHNuYXBzaG90UmVhZE9ic2VydmVycy5nZXQoYnVpbGRlcik/LihPYmplY3QuZnJlZXplKHthdHRlbXB0LCBwYXNzLCBwYXRoOiBzb3VyY2UucGF0aH0pKVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBtYW5pZmVzdEJ5dGVzOiBtYW5pZmVzdC5ieXRlcyxcbiAgICBtYW5pZmVzdElkZW50aXR5OiBtYW5pZmVzdC5pZGVudGl0eSxcbiAgICBtYW5pZmVzdFN0YXRlOiBtYW5pZmVzdC5zdGF0ZSxcbiAgICBzb3VyY2VCeXRlcyxcbiAgICBzb3VyY2VJZGVudGl0aWVzLFxuICAgIHNvdXJjZVN0YXRlc1xuICB9XG59XG5cbi8qKlxuICogUmVhZHMgZXhhY3QgYnl0ZXMgdGhyb3VnaCBvbmUgZGVzY3JpcHRvciB3aGlsZSBkZXRlY3RpbmcgcmVwbGFjZW1lbnQgb3IgbXV0YXRpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBDYW5vbmljYWwgYWJzb2x1dGUgcGF0aC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBkaXNwbGF5UGF0aCAtIFByb2plY3QtcmVsYXRpdmUgZGlhZ25vc3RpYyBwYXRoLlxuICogQHBhcmFtIHtzdHJpbmd9IHByb2plY3RJZCAtIFByb2plY3QgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IG1hbmlmZXN0IC0gV2hldGhlciB0aGlzIGlzIHRoZSBwcm9qZWN0IG1hbmlmZXN0LlxuICogQHJldHVybnMge1Byb21pc2U8U3RhYmxlRmlsZVJlYWQ+fSBTdGFibGUgYnl0ZXMgYW5kIGZpbGVzeXN0ZW0gaWRlbnRpdHkuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlYWRTdGFibGVSZWd1bGFyRmlsZShmaWxlbmFtZSwgZGlzcGxheVBhdGgsIHByb2plY3RJZCwgbWFuaWZlc3QpIHtcbiAgbGV0IGhhbmRsZVxuXG4gIHRyeSB7XG4gICAgaGFuZGxlID0gYXdhaXQgb3BlbihmaWxlbmFtZSwgY29uc3RhbnRzLk9fUkRPTkxZIHwgKGNvbnN0YW50cy5PX05PRk9MTE9XID8/IDApKVxuICAgIGNvbnN0IGJlZm9yZVBhdGggPSBhd2FpdCByZWFscGF0aChmaWxlbmFtZSlcbiAgICBjb25zdCBiZWZvcmUgPSBhd2FpdCBoYW5kbGUuc3RhdCh7YmlnaW50OiB0cnVlfSlcbiAgICBjb25zdCBiZWZvcmVFbnRyeSA9IGF3YWl0IGxzdGF0KGZpbGVuYW1lLCB7YmlnaW50OiB0cnVlfSlcblxuICAgIGlmICghYmVmb3JlLmlzRmlsZSgpIHx8ICFiZWZvcmVFbnRyeS5pc0ZpbGUoKSB8fCBiZWZvcmVQYXRoICE9IGZpbGVuYW1lIHx8ICFzYW1lRmlsZUlkZW50aXR5KGJlZm9yZSwgYmVmb3JlRW50cnkpKSB7XG4gICAgICB0aHJvdyBuZXcgVW5zdGFibGVTbmFwc2hvdFJlYWQoZGlzcGxheVBhdGgpXG4gICAgfVxuICAgIGNvbnN0IGJ5dGVzID0gYXdhaXQgaGFuZGxlLnJlYWRGaWxlKClcbiAgICBjb25zdCBhZnRlciA9IGF3YWl0IGhhbmRsZS5zdGF0KHtiaWdpbnQ6IHRydWV9KVxuICAgIGNvbnN0IGFmdGVyUGF0aCA9IGF3YWl0IHJlYWxwYXRoKGZpbGVuYW1lKVxuICAgIGNvbnN0IGFmdGVyRW50cnkgPSBhd2FpdCBsc3RhdChmaWxlbmFtZSwge2JpZ2ludDogdHJ1ZX0pXG5cbiAgICBpZiAoIWFmdGVyLmlzRmlsZSgpIHx8ICFhZnRlckVudHJ5LmlzRmlsZSgpIHx8IGFmdGVyUGF0aCAhPSBmaWxlbmFtZSB8fCAhc2FtZUZpbGVTdGF0ZShiZWZvcmUsIGFmdGVyKSB8fFxuICAgICAgIXNhbWVGaWxlSWRlbnRpdHkoYWZ0ZXIsIGFmdGVyRW50cnkpIHx8IEJpZ0ludChieXRlcy5ieXRlTGVuZ3RoKSAhPSBhZnRlci5zaXplKSB7XG4gICAgICB0aHJvdyBuZXcgVW5zdGFibGVTbmFwc2hvdFJlYWQoZGlzcGxheVBhdGgpXG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGJ5dGVzLFxuICAgICAgaWRlbnRpdHk6IGAke1N0cmluZyhiZWZvcmUuZGV2KX06JHtTdHJpbmcoYmVmb3JlLmlubyl9YCxcbiAgICAgIHN0YXRlOiBzdGFibGVGaWxlU3RhdGUoYmVmb3JlKVxuICAgIH1cbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBVbnN0YWJsZVNuYXBzaG90UmVhZCkgdGhyb3cgZXJyb3JcbiAgICByZXR1cm4gc25hcHNob3RGYWlsdXJlKG1hbmlmZXN0ID8gXCJQUk9KRUNUX01BTklGRVNUX1JFQURfRkFJTEVEXCIgOiBcIlBST0pFQ1RfU09VUkNFX1JFQURfRkFJTEVEXCIsIHByb2plY3RJZCxcbiAgICAgIG1hbmlmZXN0ID8gXCJQcm9qZWN0IG1hbmlmZXN0IGNvdWxkIG5vdCBiZSByZWFkIGludG8gYSBzdGFibGUgc25hcHNob3QuXCIgOiBcIkRlY2xhcmVkIHNvdXJjZSBjb3VsZCBub3QgYmUgcmVhZCBpbnRvIGEgc3RhYmxlIHNuYXBzaG90LlwiLFxuICAgICAgc291cmNlTG9jYXRpb24oZGlzcGxheVBhdGgpLCBlcnJvcilcbiAgfSBmaW5hbGx5IHtcbiAgICBhd2FpdCBoYW5kbGU/LmNsb3NlKClcbiAgfVxufVxuXG4vKipcbiAqIENvbXBhcmVzIGRlc2NyaXB0b3Igc3RhdGUgYXJvdW5kIG9uZSByZWFkLlxuICogQHBhcmFtIHtpbXBvcnQoXCJub2RlOmZzXCIpLkJpZ0ludFN0YXRzfSBsZWZ0IC0gU3RhdGUgYmVmb3JlIHRoZSByZWFkLlxuICogQHBhcmFtIHtpbXBvcnQoXCJub2RlOmZzXCIpLkJpZ0ludFN0YXRzfSByaWdodCAtIFN0YXRlIGFmdGVyIHRoZSByZWFkLlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgaWRlbnRpdHkgYW5kIG11dGF0aW9uLXNlbnNpdGl2ZSBtZXRhZGF0YSBhZ3JlZS5cbiAqL1xuZnVuY3Rpb24gc2FtZUZpbGVTdGF0ZShsZWZ0LCByaWdodCkge1xuICByZXR1cm4gbGVmdC5kZXYgPT0gcmlnaHQuZGV2ICYmIGxlZnQuaW5vID09IHJpZ2h0LmlubyAmJiBsZWZ0LnNpemUgPT0gcmlnaHQuc2l6ZSAmJlxuICAgIGxlZnQubXRpbWVOcyA9PSByaWdodC5tdGltZU5zICYmIGxlZnQuY3RpbWVOcyA9PSByaWdodC5jdGltZU5zXG59XG5cbi8qKlxuICogQ29tcGFyZXMgdGhlIHBhdGggZW50cnkgd2l0aCB0aGUgb3BlbmVkIGRlc2NyaXB0b3IgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIm5vZGU6ZnNcIikuQmlnSW50U3RhdHN9IGxlZnQgLSBPcGVuIGRlc2NyaXB0b3Igb3IgcGF0aCBzdGF0ZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwibm9kZTpmc1wiKS5CaWdJbnRTdGF0c30gcmlnaHQgLSBPcGVuIGRlc2NyaXB0b3Igb3IgcGF0aCBzdGF0ZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIGJvdGggaWRlbnRpZnkgdGhlIHNhbWUgZmlsZXN5c3RlbSBub2RlLlxuICovXG5mdW5jdGlvbiBzYW1lRmlsZUlkZW50aXR5KGxlZnQsIHJpZ2h0KSB7XG4gIHJldHVybiBsZWZ0LmRldiA9PSByaWdodC5kZXYgJiYgbGVmdC5pbm8gPT0gcmlnaHQuaW5vXG59XG5cbi8qKlxuICogU2VyaWFsaXplcyBtdXRhdGlvbi1zZW5zaXRpdmUgZGVzY3JpcHRvciBzdGF0ZSBmb3IgY29tcGxldGUtZ3JhcGggY29tcGFyaXNvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwibm9kZTpmc1wiKS5CaWdJbnRTdGF0c30gc3RhdHVzIC0gU3RhYmxlIGRlc2NyaXB0b3Igc3RhdGUuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBJbnRlcm5hbCBzdGF0ZSBpZGVudGl0eS5cbiAqL1xuZnVuY3Rpb24gc3RhYmxlRmlsZVN0YXRlKHN0YXR1cykge1xuICByZXR1cm4gW3N0YXR1cy5kZXYsIHN0YXR1cy5pbm8sIHN0YXR1cy5zaXplLCBzdGF0dXMubXRpbWVOcywgc3RhdHVzLmN0aW1lTnNdLm1hcChTdHJpbmcpLmpvaW4oXCI6XCIpXG59XG5cbi8qKlxuICogTG9jYXRlcyB0aGUgZmlyc3QgYnl0ZSBkaWZmZXJlbmNlIGJldHdlZW4gdHdvIGNvbXBsZXRlIGdyYXBoIHJlYWRzLlxuICogQHBhcmFtIHtQcm9qZWN0R3JhcGhSZWFkfSBsZWZ0IC0gRmlyc3QgZ3JhcGguXG4gKiBAcGFyYW0ge1Byb2plY3RHcmFwaFJlYWR9IHJpZ2h0IC0gU2Vjb25kIGdyYXBoLlxuICogQHBhcmFtIHtTZW1hbnRpZm9sZFByb2plY3R9IHByb2plY3QgLSBPcmRlcmVkIHBhdGggYXV0aG9yaXR5LlxuICogQHJldHVybnMge3N0cmluZyB8IG51bGx9IFByb2plY3QtcmVsYXRpdmUgY2hhbmdlZCBwYXRoLCBvciBudWxsLlxuICovXG5mdW5jdGlvbiBncmFwaERpZmZlcmVuY2UobGVmdCwgcmlnaHQsIHByb2plY3QpIHtcbiAgaWYgKGxlZnQubWFuaWZlc3RJZGVudGl0eSAhPSByaWdodC5tYW5pZmVzdElkZW50aXR5IHx8IGxlZnQubWFuaWZlc3RTdGF0ZSAhPSByaWdodC5tYW5pZmVzdFN0YXRlIHx8XG4gICAgIWxlZnQubWFuaWZlc3RCeXRlcy5lcXVhbHMocmlnaHQubWFuaWZlc3RCeXRlcykpIHtcbiAgICByZXR1cm4gXCJzZW1hbnRpZm9sZC5qc29uXCJcbiAgfVxuICBpZiAobGVmdC5zb3VyY2VCeXRlcy5sZW5ndGggIT0gcmlnaHQuc291cmNlQnl0ZXMubGVuZ3RoKSByZXR1cm4gXCJzZW1hbnRpZm9sZC5qc29uXCJcbiAgY29uc3QgaW5kZXggPSBsZWZ0LnNvdXJjZUJ5dGVzLmZpbmRJbmRleCgoYnl0ZXMsIHNvdXJjZUluZGV4KSA9PlxuICAgIGxlZnQuc291cmNlSWRlbnRpdGllc1tzb3VyY2VJbmRleF0gIT0gcmlnaHQuc291cmNlSWRlbnRpdGllc1tzb3VyY2VJbmRleF0gfHxcbiAgICBsZWZ0LnNvdXJjZVN0YXRlc1tzb3VyY2VJbmRleF0gIT0gcmlnaHQuc291cmNlU3RhdGVzW3NvdXJjZUluZGV4XSB8fCAhYnl0ZXMuZXF1YWxzKHJpZ2h0LnNvdXJjZUJ5dGVzW3NvdXJjZUluZGV4XSkpXG5cbiAgcmV0dXJuIGluZGV4ID09IC0xID8gbnVsbCA6IHByb2plY3Quc291cmNlc1tpbmRleF0ucGF0aFxufVxuXG4vKipcbiAqIFJldmFsaWRhdGVzIGV2ZXJ5IHBhdGggZW50cnkgYWZ0ZXIgdGhlIGZpbmFsIGNvbXBsZXRlIGdyYXBoIHJlYWQuXG4gKiBAcGFyYW0ge1NlbWFudGlmb2xkUHJvamVjdH0gcHJvamVjdCAtIE9yZGVyZWQgcGF0aCBhdXRob3JpdHkuXG4gKiBAcGFyYW0ge1Byb2plY3RHcmFwaFJlYWR9IGdyYXBoIC0gRmluYWwgY29tcGxldGUgZ3JhcGggcmVhZC5cbiAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZyB8IG51bGw+fSBGaXJzdCBjaGFuZ2VkIHByb2plY3QtcmVsYXRpdmUgcGF0aCwgb3IgbnVsbC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZ3JhcGhTdGF0ZURpZmZlcmVuY2UocHJvamVjdCwgZ3JhcGgpIHtcbiAgY29uc3QgZW50cmllcyA9IFt7XG4gICAgZmlsZW5hbWU6IHByb2plY3QubWFuaWZlc3RQYXRoLFxuICAgIGlkZW50aXR5OiBncmFwaC5tYW5pZmVzdElkZW50aXR5LFxuICAgIHBhdGg6IFwic2VtYW50aWZvbGQuanNvblwiLFxuICAgIHN0YXRlOiBncmFwaC5tYW5pZmVzdFN0YXRlXG4gIH0sIC4uLnByb2plY3Quc291cmNlcy5tYXAoKHNvdXJjZSwgaW5kZXgpID0+ICh7XG4gICAgZmlsZW5hbWU6IHNvdXJjZS5hYnNvbHV0ZVBhdGgsXG4gICAgaWRlbnRpdHk6IGdyYXBoLnNvdXJjZUlkZW50aXRpZXNbaW5kZXhdLFxuICAgIHBhdGg6IHNvdXJjZS5wYXRoLFxuICAgIHN0YXRlOiBncmFwaC5zb3VyY2VTdGF0ZXNbaW5kZXhdXG4gIH0pKV1cblxuICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc3RhdHVzID0gYXdhaXQgbHN0YXQoZW50cnkuZmlsZW5hbWUsIHtiaWdpbnQ6IHRydWV9KVxuICAgICAgY29uc3QgZXhhY3QgPSBhd2FpdCByZWFscGF0aChlbnRyeS5maWxlbmFtZSlcblxuICAgICAgaWYgKCFzdGF0dXMuaXNGaWxlKCkgfHwgZXhhY3QgIT0gZW50cnkuZmlsZW5hbWUgfHwgYCR7U3RyaW5nKHN0YXR1cy5kZXYpfToke1N0cmluZyhzdGF0dXMuaW5vKX1gICE9IGVudHJ5LmlkZW50aXR5IHx8XG4gICAgICAgIHN0YWJsZUZpbGVTdGF0ZShzdGF0dXMpICE9IGVudHJ5LnN0YXRlKSByZXR1cm4gZW50cnkucGF0aFxuICAgIH0gY2F0Y2ggKF9lcnJvcikge1xuICAgICAgcmV0dXJuIGVudHJ5LnBhdGhcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbFxufVxuXG4vKipcbiAqIENvbXB1dGVzIGEgZnJhbWVkIGRldGVybWluaXN0aWMgU0hBLTI1NiBpZGVudGl0eSBvdmVyIGV4YWN0IG1hbmlmZXN0IGFuZCBvcmRlcmVkIHNvdXJjZSBpbnB1dHMuXG4gKiBAcGFyYW0ge0J1ZmZlcn0gbWFuaWZlc3RCeXRlcyAtIEV4YWN0IG1hbmlmZXN0IGJ5dGVzLlxuICogQHBhcmFtIHtyZWFkb25seSBTbmFwc2hvdFNvdXJjZVtdfSBzb3VyY2VzIC0gT3JkZXJlZCBkZWNvZGVkIHNvdXJjZXMuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBMb3dlcmNhc2UgU0hBLTI1NiBkaWdlc3QuXG4gKi9cbmZ1bmN0aW9uIHNuYXBzaG90SGFzaChtYW5pZmVzdEJ5dGVzLCBzb3VyY2VzKSB7XG4gIGNvbnN0IGhhc2ggPSBjcmVhdGVIYXNoKFwic2hhMjU2XCIpXG5cbiAgdXBkYXRlSGFzaChoYXNoLCBcIlNlbWFudGlmb2xkUHJvamVjdFNuYXBzaG90LzFcIilcbiAgdXBkYXRlSGFzaChoYXNoLCBtYW5pZmVzdEJ5dGVzKVxuICBmb3IgKGNvbnN0IHNvdXJjZSBvZiBzb3VyY2VzKSB7XG4gICAgdXBkYXRlSGFzaChoYXNoLCBzb3VyY2UuaWQpXG4gICAgdXBkYXRlSGFzaChoYXNoLCBzb3VyY2UucGF0aClcbiAgICB1cGRhdGVIYXNoKGhhc2gsIHNvdXJjZS5sYW5ndWFnZSlcbiAgICB1cGRhdGVIYXNoKGhhc2gsIHNvdXJjZS5zb3VyY2UpXG4gIH1cblxuICByZXR1cm4gaGFzaC5kaWdlc3QoXCJoZXhcIilcbn1cblxuLyoqXG4gKiBBZGRzIG9uZSBsZW5ndGgtZnJhbWVkIGZpZWxkIHRvIGEgY29udGVudCBoYXNoLlxuICogQHBhcmFtIHtpbXBvcnQoXCJub2RlOmNyeXB0b1wiKS5IYXNofSBoYXNoIC0gQWN0aXZlIGhhc2guXG4gKiBAcGFyYW0ge3N0cmluZyB8IEJ1ZmZlcn0gdmFsdWUgLSBGaWVsZCBieXRlcy5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB1cGRhdGVIYXNoKGhhc2gsIHZhbHVlKSB7XG4gIGNvbnN0IGJ5dGVzID0gQnVmZmVyLmlzQnVmZmVyKHZhbHVlKSA/IHZhbHVlIDogQnVmZmVyLmZyb20odmFsdWUsIFwidXRmOFwiKVxuICBjb25zdCBsZW5ndGggPSBCdWZmZXIuYWxsb2MoOClcblxuICBsZW5ndGgud3JpdGVCaWdVSW50NjRCRShCaWdJbnQoYnl0ZXMuYnl0ZUxlbmd0aCkpXG4gIGhhc2gudXBkYXRlKGxlbmd0aClcbiAgaGFzaC51cGRhdGUoYnl0ZXMpXG59XG5cbi8qKlxuICogRGVjb2RlcyBzdHJpY3QgVVRGLTggZm9yIHBhcnNlciBpbnB1dHMuXG4gKiBAcGFyYW0ge0J1ZmZlcn0gYnl0ZXMgLSBFeGFjdCBmaWxlIGJ5dGVzLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gUHJvamVjdC1yZWxhdGl2ZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9qZWN0SWQgLSBQcm9qZWN0IGlkZW50aXR5LlxuICogQHJldHVybnMge3N0cmluZ30gRGVjb2RlZCBzb3VyY2UuXG4gKi9cbmZ1bmN0aW9uIGRlY29kZVV0ZjgoYnl0ZXMsIGZpbGVuYW1lLCBwcm9qZWN0SWQpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gbmV3IFRleHREZWNvZGVyKFwidXRmLThcIiwge2ZhdGFsOiB0cnVlfSkuZGVjb2RlKGJ5dGVzKVxuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiBzbmFwc2hvdEZhaWx1cmUoXCJJTlZBTElEX1BST0pFQ1RfU09VUkNFX0VOQ09ESU5HXCIsIHByb2plY3RJZCxcbiAgICAgIFwiUHJvamVjdCBtYW5pZmVzdHMgYW5kIHNvdXJjZXMgbXVzdCBiZSB2YWxpZCBVVEYtOC5cIiwgc291cmNlTG9jYXRpb24oZmlsZW5hbWUpLCBlcnJvcilcbiAgfVxufVxuXG4vKiogSW50ZXJuYWwgbWFya2VyIGZvciBhIHJlYWQgdGhhdCBtYXkgc2FmZWx5IHVzZSB0aGUgYm91bmRlZCByZXRyeS4gKi9cbmNsYXNzIFVuc3RhYmxlU25hcHNob3RSZWFkIGV4dGVuZHMgRXJyb3Ige1xuICAvKipcbiAgICogQ3JlYXRlcyBhbiBpbnRlcm5hbCByZXRyeSBtYXJrZXIuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gUHJvamVjdC1yZWxhdGl2ZSB1bnN0YWJsZSBwYXRoLlxuICAgKi9cbiAgY29uc3RydWN0b3IocGF0aCkge1xuICAgIHN1cGVyKFwiVW5zdGFibGUgcHJvamVjdCBzbmFwc2hvdCByZWFkLlwiKVxuICAgIHRoaXMucGF0aCA9IHBhdGhcbiAgfVxufVxuXG4vKipcbiAqIENyZWF0ZXMgdGhlIHN0YWJsZSBtYW5pZmVzdCBib3VuZGFyeSBsb2NhdGlvbi5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBNYW5pZmVzdCBsb2NhdGlvbi5cbiAqL1xuZnVuY3Rpb24gbWFuaWZlc3RMb2NhdGlvbigpIHtcbiAgcmV0dXJuIHNvdXJjZUxvY2F0aW9uKFwic2VtYW50aWZvbGQuanNvblwiKVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBzdGFibGUgcHJvamVjdC1yZWxhdGl2ZSBmaWxlIGxvY2F0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gUHJvamVjdC1yZWxhdGl2ZSBmaWxlbmFtZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBTdGFydC1vZi1maWxlIGxvY2F0aW9uLlxuICovXG5mdW5jdGlvbiBzb3VyY2VMb2NhdGlvbihmaWxlbmFtZSkge1xuICBjb25zdCBwb2ludCA9IHtjb2x1bW46IDEsIGxpbmU6IDEsIG9mZnNldDogMH1cblxuICByZXR1cm4ge2VuZDogcG9pbnQsIGZpbGVuYW1lLCBzdGFydDogcG9pbnR9XG59XG5cbi8qKlxuICogVGhyb3dzIG9uZSBzdGFibGUgc25hcHNob3QgZGlhZ25vc3RpYy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjb2RlIC0gU3RhYmxlIGRpYWdub3N0aWMgY29kZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9qZWN0SWQgLSBQcm9qZWN0IGlkZW50aXR5LlxuICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgLSBTdGFibGUgZGV0YWlsLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBbbG9jYXRpb25dIC0gUHJvamVjdC1yZWxhdGl2ZSBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7dW5rbm93bn0gW2Vycm9yXSAtIFByZXNlcnZlZCBjYXVzZS5cbiAqIEByZXR1cm5zIHtuZXZlcn0gQWx3YXlzIHRocm93cy5cbiAqL1xuZnVuY3Rpb24gc25hcHNob3RGYWlsdXJlKGNvZGUsIHByb2plY3RJZCwgbWVzc2FnZSwgbG9jYXRpb24sIGVycm9yKSB7XG4gIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe1xuICAgIGNhdXNlOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiB1bmRlZmluZWQsXG4gICAgY29kZSxcbiAgICBsYW5ndWFnZTogcHJvamVjdElkLFxuICAgIGxvY2F0aW9uLFxuICAgIG1lc3NhZ2VcbiAgfSlcbn1cblxuLyoqXG4gKiBAdHlwZWRlZiBTbmFwc2hvdFNvdXJjZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IGlkIC0gU3RhYmxlIHNlbWFudGljIG1vZHVsZSBpZGVudGl0eS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfSBsYW5ndWFnZSAtIFJlZ2lzdGVyZWQgc291cmNlIGxhbmd1YWdlLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHBhdGggLSBQcm9qZWN0LXJlbGF0aXZlIHNvdXJjZSBwYXRoLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHNvdXJjZSAtIEV4YWN0IGRlY29kZWQgc291cmNlIHRleHQuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiBQcm9qZWN0R3JhcGhSZWFkXG4gKiBAcHJvcGVydHkge0J1ZmZlcn0gbWFuaWZlc3RCeXRlcyAtIEV4YWN0IG1hbmlmZXN0IGJ5dGVzLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IG1hbmlmZXN0SWRlbnRpdHkgLSBTdGFibGUgbWFuaWZlc3QgZGV2aWNlL2lub2RlIGlkZW50aXR5LlxuICogQHByb3BlcnR5IHtzdHJpbmd9IG1hbmlmZXN0U3RhdGUgLSBTdGFibGUgbWFuaWZlc3QgbXV0YXRpb24tc2Vuc2l0aXZlIHN0YXRlLlxuICogQHByb3BlcnR5IHtCdWZmZXJbXX0gc291cmNlQnl0ZXMgLSBFeGFjdCBzb3VyY2UgYnl0ZXMgaW4gbWFuaWZlc3Qgb3JkZXIuXG4gKiBAcHJvcGVydHkge3N0cmluZ1tdfSBzb3VyY2VJZGVudGl0aWVzIC0gU3RhYmxlIHNvdXJjZSBkZXZpY2UvaW5vZGUgaWRlbnRpdGllcyBpbiBtYW5pZmVzdCBvcmRlci5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW119IHNvdXJjZVN0YXRlcyAtIFN0YWJsZSBzb3VyY2UgbXV0YXRpb24tc2Vuc2l0aXZlIHN0YXRlcyBpbiBtYW5pZmVzdCBvcmRlci5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIFN0YWJsZUZpbGVSZWFkXG4gKiBAcHJvcGVydHkge0J1ZmZlcn0gYnl0ZXMgLSBFeGFjdCBzdGFibGUgZmlsZSBieXRlcy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBpZGVudGl0eSAtIFN0YWJsZSBkZXZpY2UvaW5vZGUgaWRlbnRpdHkuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gc3RhdGUgLSBTdGFibGUgbXV0YXRpb24tc2Vuc2l0aXZlIGZpbGUgc3RhdGUuXG4gKi9cbiJdfQ==
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Emits long-lived watch state with one terminal record for every admitted cycle and one for the watcher.
|
|
3
|
+
*/
|
|
4
|
+
export declare class ProjectWatchReporter {
|
|
5
|
+
#private;
|
|
6
|
+
/**
|
|
7
|
+
* Creates a watch reporter.
|
|
8
|
+
* @param {{format?: "human" | "ndjson", now?: () => number, stderr?: import("./project-reporter.js").WritableOutput, stdout?: import("./project-reporter.js").WritableOutput}} [options] - Output mode, clock, and sinks.
|
|
9
|
+
*/
|
|
10
|
+
constructor(options?: {
|
|
11
|
+
format?: "human" | "ndjson";
|
|
12
|
+
now?: () => number;
|
|
13
|
+
stderr?: import("./project-reporter.js").WritableOutput;
|
|
14
|
+
stdout?: import("./project-reporter.js").WritableOutput;
|
|
15
|
+
});
|
|
16
|
+
/**
|
|
17
|
+
* Reports validated watch startup.
|
|
18
|
+
* @param {string} projectId - Stable initial project identity.
|
|
19
|
+
* @returns {void}
|
|
20
|
+
*/
|
|
21
|
+
watchStarted(projectId: string): void;
|
|
22
|
+
/**
|
|
23
|
+
* Reports the selected event backend.
|
|
24
|
+
* @param {"native" | "polling"} backend - Active event backend.
|
|
25
|
+
* @returns {void}
|
|
26
|
+
*/
|
|
27
|
+
watchBackend(backend: "native" | "polling"): void;
|
|
28
|
+
/**
|
|
29
|
+
* Begins one admitted build cycle.
|
|
30
|
+
* @param {ProjectWatchCycleContext} cycle - Cycle context.
|
|
31
|
+
* @returns {void}
|
|
32
|
+
*/
|
|
33
|
+
cycleStarted(cycle: ProjectWatchCycleContext): void;
|
|
34
|
+
/**
|
|
35
|
+
* Reports the cycle's validated project identity.
|
|
36
|
+
* @param {string} projectId - Validated project identity.
|
|
37
|
+
* @returns {void}
|
|
38
|
+
*/
|
|
39
|
+
projectLoaded(projectId: string): void;
|
|
40
|
+
/**
|
|
41
|
+
* Reports the cycle's complete source snapshot.
|
|
42
|
+
* @param {string} snapshotHash - Complete source snapshot hash.
|
|
43
|
+
* @returns {void}
|
|
44
|
+
*/
|
|
45
|
+
snapshotLoaded(snapshotHash: string): void;
|
|
46
|
+
/**
|
|
47
|
+
* Reports one generated target.
|
|
48
|
+
* @param {import("./project-build.js").ProjectBuildTargetResult} target - Generated target.
|
|
49
|
+
* @returns {void}
|
|
50
|
+
*/
|
|
51
|
+
targetGenerated(target: import("./project-build.js").ProjectBuildTargetResult): void;
|
|
52
|
+
/**
|
|
53
|
+
* Reports one completed target-check stage.
|
|
54
|
+
* @param {{id: string, language: string, stage: import("./semantic/types.js").TargetCheckStageResult}} checked - Check stage.
|
|
55
|
+
* @returns {void}
|
|
56
|
+
*/
|
|
57
|
+
targetChecked(checked: {
|
|
58
|
+
id: string;
|
|
59
|
+
language: string;
|
|
60
|
+
stage: import("./semantic/types.js").TargetCheckStageResult;
|
|
61
|
+
}): void;
|
|
62
|
+
/**
|
|
63
|
+
* Emits one successful or recovered cycle terminal.
|
|
64
|
+
* @param {import("./project-build.js").ProjectBuildSuccess} result - Published result.
|
|
65
|
+
* @param {boolean} recovered - Whether the prior ordinary cycle failed.
|
|
66
|
+
* @returns {void}
|
|
67
|
+
*/
|
|
68
|
+
cycleSucceeded(result: import("./project-build.js").ProjectBuildSuccess, recovered: boolean): void;
|
|
69
|
+
/**
|
|
70
|
+
* Emits one failed, cancelled, or superseded cycle terminal.
|
|
71
|
+
* @param {unknown} failure - Preserved cycle failure.
|
|
72
|
+
* @param {"cancelled" | "failed" | "superseded"} status - Terminal classification.
|
|
73
|
+
* @returns {void}
|
|
74
|
+
*/
|
|
75
|
+
cycleFailed(failure: unknown, status: "cancelled" | "failed" | "superseded"): void;
|
|
76
|
+
/**
|
|
77
|
+
* Reports reconciliation whose complete content hash did not change.
|
|
78
|
+
* @param {readonly string[]} changedPaths - Coalesced hint paths.
|
|
79
|
+
* @returns {void}
|
|
80
|
+
*/
|
|
81
|
+
unchanged(changedPaths: readonly string[]): void;
|
|
82
|
+
/**
|
|
83
|
+
* Reports the first filesystem hint admitted while the current cycle remains active.
|
|
84
|
+
* @returns {void}
|
|
85
|
+
*/
|
|
86
|
+
cycleDirty(): void;
|
|
87
|
+
/**
|
|
88
|
+
* Emits the sole clean watcher terminal.
|
|
89
|
+
* @param {string} reason - Shutdown reason.
|
|
90
|
+
* @returns {void}
|
|
91
|
+
*/
|
|
92
|
+
watchStopped(reason: string): void;
|
|
93
|
+
/**
|
|
94
|
+
* Emits the sole startup/configuration watcher terminal.
|
|
95
|
+
* @param {unknown} failure - Startup/configuration failure.
|
|
96
|
+
* @returns {void}
|
|
97
|
+
*/
|
|
98
|
+
watchFailed(failure: unknown): void;
|
|
99
|
+
}
|
|
100
|
+
export type ProjectWatchCycleContext = {
|
|
101
|
+
/**
|
|
102
|
+
* - Stable changed paths.
|
|
103
|
+
*/
|
|
104
|
+
changedPaths: readonly string[];
|
|
105
|
+
/**
|
|
106
|
+
* - One-based cycle number.
|
|
107
|
+
*/
|
|
108
|
+
cycle: number;
|
|
109
|
+
/**
|
|
110
|
+
* - Stable project identity.
|
|
111
|
+
*/
|
|
112
|
+
projectId: string;
|
|
113
|
+
/**
|
|
114
|
+
* - Complete snapshot hash when reconciliation succeeded.
|
|
115
|
+
*/
|
|
116
|
+
snapshotHash?: string;
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* @typedef ProjectWatchCycleContext
|
|
120
|
+
* @property {readonly string[]} changedPaths - Stable changed paths.
|
|
121
|
+
* @property {number} cycle - One-based cycle number.
|
|
122
|
+
* @property {string} projectId - Stable project identity.
|
|
123
|
+
* @property {string} [snapshotHash] - Complete snapshot hash when reconciliation succeeded.
|
|
124
|
+
*/
|
|
125
|
+
//# sourceMappingURL=project-watch-reporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-watch-reporter.d.ts","sourceRoot":"","sources":["../../src/project-watch-reporter.js"],"names":[],"mappings":"AAIA;;GAEG;AACH,qBAAa,oBAAoB;;IAqB/B;;;OAGG;IACH,YAAY,OAAO,AAFhB,CACF,EADU;QAAC,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,uBAAuB,EAAE,cAAc,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,uBAAuB,EAAE,cAAc,CAAA;KAErJ,EAavB;IAED;;;;OAIG;IACH,YAAY,CAAC,SAAS,EAHX,MAGW,GAFT,IAAI,CAKhB;IAED;;;;OAIG;IACH,YAAY,CAAC,OAAO,EAHT,QAAQ,GAAG,SAGF,GAFP,IAAI,CAIhB;IAED;;;;OAIG;IACH,YAAY,CAAC,KAAK,EAHP,wBAGO,GAFL,IAAI,CAWhB;IAED;;;;OAIG;IACH,aAAa,CAAC,SAAS,EAHZ,MAGY,GAFV,IAAI,CAKhB;IAED;;;;OAIG;IACH,cAAc,CAAC,YAAY,EAHhB,MAGgB,GAFd,IAAI,CAKhB;IAED;;;;OAIG;IACH,eAAe,CAAC,MAAM,EAHX,OAAO,oBAAoB,EAAE,wBAGlB,GAFT,IAAI,CAUhB;IAED;;;;OAIG;IACH,aAAa,CAAC,OAAO,EAHV;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,qBAAqB,EAAE,sBAAsB,CAAA;KAGhF,GAFR,IAAI,CAgBhB;IAED;;;;;OAKG;IACH,cAAc,CAAC,MAAM,EAJV,OAAO,oBAAoB,EAAE,mBAInB,EAAE,SAAS,EAHrB,OAGqB,GAFnB,IAAI,CAyBhB;IAED;;;;;OAKG;IACH,WAAW,CAAC,OAAO,EAJR,OAIQ,EAAE,MAAM,EAHhB,WAAW,GAAG,QAAQ,GAAG,YAGT,GAFd,IAAI,CAoBhB;IAED;;;;OAIG;IACH,SAAS,CAAC,YAAY,EAHX,SAAS,MAAM,EAGJ,GAFT,IAAI,CAIhB;IAED;;;OAGG;IACH,UAAU,IAFG,IAAI,CAKhB;IAED;;;;OAIG;IACH,YAAY,CAAC,MAAM,EAHR,MAGQ,GAFN,IAAI,CAUhB;IAED;;;;OAIG;IACH,WAAW,CAAC,OAAO,EAHR,OAGQ,GAFN,IAAI,CAYhB;CAmDF;AAGE,YAAS,wBAAwB,GACjC;;;;IAA8B,YAAY,EAA/B,SAAS,MAAM,EAAE,CAC5B;;;;IAAmB,KAAK,EAAb,MAAM,CACjB;;;;IAAmB,SAAS,EAAjB,MAAM,CACjB;;;;IAAoB,YAAY,AAAhC,CACF,EADa,MAAM,CACnB;CAAA,CAAA;AAND;;;;;;GAMG"}
|