mirror of
https://github.com/morluto/rea
synced 2026-10-26 06:16:17 -04:00
refactor(javascript): own paired graph evidence resolution
This commit is contained in:
@@ -37,6 +37,7 @@ import {
|
||||
applicationGraphEvidenceInputError,
|
||||
parseApplicationGraphEvidence,
|
||||
parseNativeApplicationEvidence,
|
||||
type ApplicationGraphEvidenceSource,
|
||||
} from "./JavaScriptApplicationEvidenceGraph.js";
|
||||
import {
|
||||
createApplicationFeatureTraceEvidence,
|
||||
@@ -81,6 +82,36 @@ const resolveWorkflowEvidence = (
|
||||
: ok(raw);
|
||||
};
|
||||
|
||||
/** Resolve both selections before authenticating either graph, retaining diagnostic inputs. */
|
||||
const resolveApplicationGraphPair = (
|
||||
operation: string,
|
||||
input: { readonly left: unknown; readonly right: unknown },
|
||||
lookup: EvidenceLookup | undefined,
|
||||
): Result<
|
||||
{
|
||||
readonly left: ApplicationGraphEvidenceSource;
|
||||
readonly right: ApplicationGraphEvidenceSource;
|
||||
readonly selected: { readonly left: unknown; readonly right: unknown };
|
||||
},
|
||||
AnalysisError
|
||||
> => {
|
||||
const selectedLeft = resolveWorkflowEvidence(input.left, lookup);
|
||||
if (!selectedLeft.ok) return selectedLeft;
|
||||
const selectedRight = resolveWorkflowEvidence(input.right, lookup);
|
||||
if (!selectedRight.ok) return selectedRight;
|
||||
const left = parseApplicationGraphEvidence(selectedLeft.value, ["left"]);
|
||||
if (!left.ok)
|
||||
return err(applicationGraphEvidenceInputError(operation, left.error));
|
||||
const right = parseApplicationGraphEvidence(selectedRight.value, ["right"]);
|
||||
if (!right.ok)
|
||||
return err(applicationGraphEvidenceInputError(operation, right.error));
|
||||
return ok({
|
||||
left: left.value,
|
||||
right: right.value,
|
||||
selected: { left: selectedLeft.value, right: selectedRight.value },
|
||||
});
|
||||
};
|
||||
|
||||
/** Authenticate Evidence and derive one bounded cross-layer feature trace. */
|
||||
export const traceApplicationFeatureEvidence = (
|
||||
rawInput: unknown,
|
||||
@@ -163,23 +194,10 @@ export const compareApplicationVersionsEvidence = (
|
||||
cause: request.error,
|
||||
}),
|
||||
);
|
||||
const selectedLeft = resolveWorkflowEvidence(request.data.left, lookup);
|
||||
if (!selectedLeft.ok) return selectedLeft;
|
||||
const selectedRight = resolveWorkflowEvidence(request.data.right, lookup);
|
||||
if (!selectedRight.ok) return selectedRight;
|
||||
const input = {
|
||||
...request.data,
|
||||
left: selectedLeft.value,
|
||||
right: selectedRight.value,
|
||||
};
|
||||
const leftResult = parseApplicationGraphEvidence(input.left, ["left"]);
|
||||
if (!leftResult.ok)
|
||||
return err(applicationGraphEvidenceInputError(operation, leftResult.error));
|
||||
const rightResult = parseApplicationGraphEvidence(input.right, ["right"]);
|
||||
if (!rightResult.ok)
|
||||
return err(
|
||||
applicationGraphEvidenceInputError(operation, rightResult.error),
|
||||
);
|
||||
const pair = resolveApplicationGraphPair(operation, request.data, lookup);
|
||||
if (!pair.ok) return pair;
|
||||
const { left, right } = pair.value;
|
||||
const input = { ...request.data, ...pair.value.selected };
|
||||
const leftNativeResult = parseNativeApplicationEvidence(
|
||||
input.left_native_observations,
|
||||
["left_native_observations"],
|
||||
@@ -196,8 +214,6 @@ export const compareApplicationVersionsEvidence = (
|
||||
return err(
|
||||
applicationGraphEvidenceInputError(operation, rightNativeResult.error),
|
||||
);
|
||||
const left = leftResult.value;
|
||||
const right = rightResult.value;
|
||||
const leftNative = leftNativeResult.value;
|
||||
const rightNative = rightNativeResult.value;
|
||||
const identities = applicationVersionIdentitiesSchema.safeParse({
|
||||
@@ -297,25 +313,10 @@ export const compareJavaScriptExportShapesEvidence = (
|
||||
cause: request.error,
|
||||
}),
|
||||
);
|
||||
const selectedLeft = resolveWorkflowEvidence(request.data.left, lookup);
|
||||
if (!selectedLeft.ok) return selectedLeft;
|
||||
const selectedRight = resolveWorkflowEvidence(request.data.right, lookup);
|
||||
if (!selectedRight.ok) return selectedRight;
|
||||
const input = {
|
||||
...request.data,
|
||||
left: selectedLeft.value,
|
||||
right: selectedRight.value,
|
||||
};
|
||||
const leftResult = parseApplicationGraphEvidence(input.left, ["left"]);
|
||||
if (!leftResult.ok)
|
||||
return err(applicationGraphEvidenceInputError(operation, leftResult.error));
|
||||
const rightResult = parseApplicationGraphEvidence(input.right, ["right"]);
|
||||
if (!rightResult.ok)
|
||||
return err(
|
||||
applicationGraphEvidenceInputError(operation, rightResult.error),
|
||||
);
|
||||
const left = leftResult.value;
|
||||
const right = rightResult.value;
|
||||
const pair = resolveApplicationGraphPair(operation, request.data, lookup);
|
||||
if (!pair.ok) return pair;
|
||||
const { left, right } = pair.value;
|
||||
const input = { ...request.data, ...pair.value.selected };
|
||||
const identities = javaScriptExportShapeIdentitiesSchema.safeParse({
|
||||
left: left.evidence,
|
||||
right: right.evidence,
|
||||
|
||||
@@ -239,6 +239,35 @@ const checkMalformedEvidenceBeforeIdentities = async ({
|
||||
details: { issues: [{ path, reason: "invalid_type" }] },
|
||||
});
|
||||
}
|
||||
const missingLeft = {
|
||||
kind: "retained-evidence",
|
||||
evidence_id: `ev_${"a".repeat(64)}`,
|
||||
};
|
||||
const missingRight = {
|
||||
kind: "retained-evidence",
|
||||
evidence_id: `ev_${"b".repeat(64)}`,
|
||||
};
|
||||
for (const [command, extra] of [
|
||||
["compare-application-versions", {}],
|
||||
["compare-javascript-export-shapes", selectors],
|
||||
] as const) {
|
||||
// Lookup of both selected sources precedes graph authentication.
|
||||
for (const [left, right, evidenceId] of [
|
||||
[malformed, missingRight, missingRight.evidence_id],
|
||||
[missingLeft, missingRight, missingLeft.evidence_id],
|
||||
] as const) {
|
||||
const rejected = await runJson(cli, root, command, {
|
||||
left,
|
||||
right,
|
||||
...extra,
|
||||
});
|
||||
expect(rejected.exitCode).toBe(1);
|
||||
expect(rejected.json).toMatchObject({
|
||||
code: "evidence_integrity_mismatch",
|
||||
details: { evidence_id: evidenceId, reason: "missing" },
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
cliTest(
|
||||
|
||||
@@ -198,6 +198,8 @@ describe("complete comparison projections", () => {
|
||||
]);
|
||||
const compared = compareApplicationVersionsEvidence({ left, right });
|
||||
if (!compared.ok) throw compared.error;
|
||||
expect(compared.value.sources[0]).toBe(left);
|
||||
expect(compared.value.sources[1]).toBe(right);
|
||||
const result = compared.value.result;
|
||||
expectFullComparisonResultSchema(result);
|
||||
const modules = result.items.filter(
|
||||
|
||||
@@ -7,6 +7,7 @@ import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
|
||||
import { analyzeJavaScriptApplication } from "../../support/javascriptApplicationScope.js";
|
||||
import { parseApplicationGraphEvidence } from "../../../src/application/javascript/JavaScriptApplicationEvidenceGraph.js";
|
||||
import { compareJavaScriptExportShapesEvidence } from "../../../src/application/javascript/JavaScriptApplicationWorkflowService.js";
|
||||
import { compareJavaScriptExportShapes } from "../../../src/domain/javascript/javascriptExportShapeComparison.js";
|
||||
import {
|
||||
javaScriptExportShapeComparisonResultSchema,
|
||||
@@ -40,6 +41,18 @@ describe("JavaScript export return-shape comparison", () => {
|
||||
|
||||
const first = compare(left, right);
|
||||
const second = compare(left, right);
|
||||
const execution = compareJavaScriptExportShapesEvidence({
|
||||
left: left.evidence,
|
||||
right: right.evidence,
|
||||
left_module_path: "parser.mjs",
|
||||
left_export_name: "default",
|
||||
right_module_path: "parser.mjs",
|
||||
right_export_name: "default",
|
||||
});
|
||||
if (!execution.ok) throw execution.error;
|
||||
expect(execution.value.result).toEqual(first);
|
||||
expect(execution.value.sources[0]).toBe(left.evidence);
|
||||
expect(execution.value.sources[1]).toBe(right.evidence);
|
||||
|
||||
expect(first.comparison_id).toBe(second.comparison_id);
|
||||
expect(() =>
|
||||
|
||||
Reference in New Issue
Block a user