perf(javascript): reuse validated immutable graphs (#1112)

* perf(javascript): reuse validated immutable graphs

* fix(ci): follow the moved process CLI boundary test
This commit is contained in:
Ysopwnable
2026-10-09 02:40:21 +08:00
committed by GitHub
parent 1f5be750bc
commit ec6db0f063
11 changed files with 582 additions and 117 deletions
@@ -1,7 +1,15 @@
import { z } from "zod";
import { javascriptApplicationGraphSchema } from "./javascriptApplicationGraph.js";
import { javaScriptSemanticGraphSchema } from "./javascriptSemanticGraph.js";
import {
javascriptApplicationGraphSchema,
isValidatedImmutableJavaScriptApplicationGraph,
type JavaScriptApplicationGraph,
} from "./javascriptApplicationGraph.js";
import {
javaScriptSemanticGraphSchema,
isValidatedImmutableJavaScriptSemanticGraph,
type JavaScriptSemanticGraph,
} from "./javascriptSemanticGraph.js";
import { digestSchema } from "../digests.js";
import { prefixedDigestSchema } from "../digests.js";
@@ -51,43 +59,62 @@ const reconstructionStatisticsSchema = z.strictObject({
truncated_scopes: countSchema,
});
/** JavaScript application analysis with an authenticated semantic companion. */
export const javascriptApplicationAnalysisResultSchema = z
.strictObject({
input_path: z.string().min(1),
format: z.enum(["asar", "directory"]),
root_artifact_sha256: digestSchema,
inventory_manifest_id: prefixedDigestSchema("agm"),
inventory_graph_sha256: digestSchema,
graph: javascriptApplicationGraphSchema,
summary: electronBoundarySummarySchema,
statistics: reconstructionStatisticsSchema,
limitations: z.array(z.string().min(1)),
semantic_graph: javaScriptSemanticGraphSchema,
})
.superRefine((result, context) => {
if (result.semantic_graph.application_graph_id !== result.graph.graph_id)
context.addIssue({
code: "custom",
path: ["semantic_graph", "application_graph_id"],
message: "Semantic graph must commit the containing application graph",
});
if (
result.semantic_graph.root_artifact_sha256 !== result.root_artifact_sha256
)
context.addIssue({
code: "custom",
path: ["semantic_graph", "root_artifact_sha256"],
message: "Semantic graph must commit the containing root artifact",
});
const applicationNodeIds = new Set(
result.graph.nodes.map(({ node_id }) => node_id),
);
for (const [nodeIndex, node] of result.semantic_graph.nodes.entries())
const applicationAnalysisResultShape = z.strictObject({
input_path: z.string().min(1),
format: z.enum(["asar", "directory"]),
root_artifact_sha256: digestSchema,
inventory_manifest_id: prefixedDigestSchema("agm"),
inventory_graph_sha256: digestSchema,
graph: javascriptApplicationGraphSchema,
summary: electronBoundarySummarySchema,
statistics: reconstructionStatisticsSchema,
limitations: z.array(z.string().min(1)),
semantic_graph: javaScriptSemanticGraphSchema,
});
type BindingIssue = {
readonly code: "custom";
readonly path: PropertyKey[];
readonly message: string;
};
function* checkApplicationBindingsSteps(
result: z.infer<typeof applicationAnalysisResultShape>,
context: { readonly addIssue: (issue: BindingIssue) => void },
): Generator<void> {
if (result.semantic_graph.application_graph_id !== result.graph.graph_id)
context.addIssue({
code: "custom",
path: ["semantic_graph", "application_graph_id"],
message: "Semantic graph must commit the containing application graph",
});
if (
result.semantic_graph.root_artifact_sha256 !== result.root_artifact_sha256
)
context.addIssue({
code: "custom",
path: ["semantic_graph", "root_artifact_sha256"],
message: "Semantic graph must commit the containing root artifact",
});
const applicationNodeIds = new Set<string>();
let examined = 0;
try {
for (const node of result.graph.nodes) {
applicationNodeIds.add(node.node_id);
if (++examined === 4096) {
examined = 0;
yield;
}
}
for (const [nodeIndex, node] of result.semantic_graph.nodes.entries()) {
if (++examined === 4096) {
examined = 0;
yield;
}
for (const [
identifierIndex,
identifier,
] of node.application_node_ids.entries())
] of node.application_node_ids.entries()) {
if (!applicationNodeIds.has(identifier))
context.addIssue({
code: "custom",
@@ -100,8 +127,52 @@ export const javascriptApplicationAnalysisResultSchema = z
],
message: "Semantic node references an absent application node",
});
if (++examined === 4096) {
examined = 0;
yield;
}
}
}
} finally {
applicationNodeIds.clear();
}
}
/** JavaScript application analysis with an authenticated semantic companion. */
export const javascriptApplicationAnalysisResultSchema =
applicationAnalysisResultShape.superRefine((result, context) => {
const steps = checkApplicationBindingsSteps(result, context);
while (!steps.next().done) {
// Public/imported results still receive complete synchronous validation.
}
});
const ownedAnalysisResultShape = applicationAnalysisResultShape.extend({
graph: z.custom<JavaScriptApplicationGraph>(
isValidatedImmutableJavaScriptApplicationGraph,
),
semantic_graph: z.custom<JavaScriptSemanticGraph>(
isValidatedImmutableJavaScriptSemanticGraph,
),
});
/** Reuse exact owned graphs while validating metadata and cross-graph bindings. */
export function* parseOwnedJavaScriptApplicationAnalysisSteps(
input: unknown,
): Generator<void, JavaScriptApplicationAnalysisResult> {
const prepared = ownedAnalysisResultShape.safeParse(input);
if (!prepared.success)
return javascriptApplicationAnalysisResultSchema.parse(input);
const issues: BindingIssue[] = [];
yield* checkApplicationBindingsSteps(prepared.data, {
addIssue: (issue) => {
issues.push(issue);
},
});
if (issues.length > 0) throw new z.ZodError(issues);
return prepared.data;
}
/** Parsed public JavaScript application analysis request. */
export type AnalyzeJavaScriptApplicationInput = z.infer<
typeof analyzeJavaScriptApplicationInputSchema