mirror of
https://github.com/morluto/rea.git
synced 2026-11-13 18:22:42 +00:00
fix(javascript): preserve wide async chunk collection (#10362)
* fix(javascript): collect async chunks without call spreads * test(javascript): bound the public checkpoint control
This commit is contained in:
1 parent
e841fb16e4
commit
4b26f38d6f
4 files changed
+125
-1
No files matched your search
@@ -230,7 +230,7 @@ const recoverBundlerModules = (
|
||||
);
|
||||
if (recovered === null) continue;
|
||||
modules.push(recovered.module);
|
||||
asyncChunkKeys.push(...recovered.asyncChunkKeys);
|
||||
for (const key of recovered.asyncChunkKeys) asyncChunkKeys.push(key);
|
||||
unknownAsyncChunkKeys += recovered.unknownAsyncChunkKeys;
|
||||
}
|
||||
return {
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
import { writeFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { expect } from "vitest";
|
||||
import { parseEvidence } from "../../src/domain/evidence.js";
|
||||
import { javascriptApplicationAnalysisResultSchema } from "../../src/domain/javascript/javascriptApplicationAnalysis.js";
|
||||
import { JAVASCRIPT_STATIC_FACT_BYTES } from "../../src/domain/javascript/javascriptAnalysisResourceControls.js";
|
||||
import { javascriptAsyncChunkCapacity } from "../fixtures/javascriptAsyncChunkCapacity.js";
|
||||
import { createTestTempDirectory } from "../fixtures/temporaryDirectory.js";
|
||||
import { cliTest } from "../support/cli/cliFixture.js";
|
||||
|
||||
cliTest(
|
||||
"reports the complete-fact ceiling for wide async chunk metadata",
|
||||
{ timeout: 60_000 },
|
||||
async ({ cli }) => {
|
||||
// This bounded public control exceeds the complete-fact allowance. The
|
||||
// forked boundary regression separately owns call-argument capacity.
|
||||
const { source } = javascriptAsyncChunkCapacity(50_000);
|
||||
const root = await createTestTempDirectory("rea-async-chunk-budget-");
|
||||
await writeFile(join(root, "entry.cjs"), source);
|
||||
const response = await cli.run({
|
||||
arguments: [
|
||||
"analyze-javascript-application",
|
||||
root,
|
||||
"--max-semantic-nodes",
|
||||
"1",
|
||||
"--max-semantic-nodes-per-file",
|
||||
"1",
|
||||
"--max-heap-mb",
|
||||
"2048",
|
||||
"--analysis-timeout-ms",
|
||||
"30000",
|
||||
"--json",
|
||||
],
|
||||
timeoutMs: 55_000,
|
||||
});
|
||||
// Analysis retains the interrupted file rather than failing the command.
|
||||
expect(response.exitCode, `${response.stdout}\n${response.stderr}`).toBe(0);
|
||||
const result = javascriptApplicationAnalysisResultSchema.parse(
|
||||
parseEvidence(response.json).normalized_result,
|
||||
);
|
||||
const failures = result.graph.nodes.flatMap(({ observations }) =>
|
||||
observations.flatMap(({ properties }) =>
|
||||
properties.analysis_failure === undefined
|
||||
? []
|
||||
: [properties.analysis_failure],
|
||||
),
|
||||
);
|
||||
expect(failures).toEqual([
|
||||
expect.objectContaining({
|
||||
code: "resource_constraint",
|
||||
retryable: false,
|
||||
message: expect.stringContaining("static checkpoint"),
|
||||
remediation: {
|
||||
action: expect.stringContaining("no runtime override"),
|
||||
},
|
||||
details: expect.objectContaining({
|
||||
resource: "transport",
|
||||
reported_limits: expect.objectContaining({
|
||||
checkpoint_bytes: expect.any(Number),
|
||||
checkpoint_limit_bytes: JAVASCRIPT_STATIC_FACT_BYTES,
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
]);
|
||||
expect(JSON.stringify(failures)).not.toContain("call stack");
|
||||
expect(JSON.stringify(failures)).toContain(
|
||||
"Raising max_heap_mb does not raise it",
|
||||
);
|
||||
},
|
||||
);
|
||||
@@ -0,0 +1,41 @@
|
||||
import { createHash } from "node:crypto";
|
||||
import { expect, it } from "vitest";
|
||||
import { javascriptAsyncChunkCapacity } from "../../fixtures/javascriptAsyncChunkCapacity.js";
|
||||
import { analyzeJavaScriptStaticSource } from "../../fixtures/javascriptStaticAnalysis.js";
|
||||
|
||||
it("retains a wide factory's async keys before normalizing the registration", () => {
|
||||
// The forked boundary project preserves the default main-thread stack.
|
||||
const count = 130_000;
|
||||
const { source, factory } = javascriptAsyncChunkCapacity(count);
|
||||
const result = analyzeJavaScriptStaticSource(source);
|
||||
expect(result.parse_status).toBe("partial");
|
||||
expect(result.analysis_coverage?.syntax).toEqual({
|
||||
status: "complete",
|
||||
error_count: 0,
|
||||
});
|
||||
expect(result.bundler_registrations).toHaveLength(1);
|
||||
const registration = result.bundler_registrations[0];
|
||||
if (registration === undefined) throw new Error("Missing registration");
|
||||
const keys = new Set(registration.async_chunk_keys);
|
||||
expect(registration.async_chunk_keys).toHaveLength(count + 1);
|
||||
expect(keys.size).toBe(count + 1);
|
||||
expect(
|
||||
Array.from({ length: count }, (_, index) => String(index)).every((key) =>
|
||||
keys.has(key),
|
||||
),
|
||||
).toBe(true);
|
||||
expect(registration.async_chunk_keys[0]).toBe("0");
|
||||
expect(registration.async_chunk_keys.at(-1)).toBe("later");
|
||||
expect(registration.unknown_async_chunk_keys).toBe(1);
|
||||
expect(registration.modules).toHaveLength(2);
|
||||
const start = source.indexOf(factory);
|
||||
expect(registration.modules[0]).toMatchObject({
|
||||
module_key: "1",
|
||||
factory_require_name: "r",
|
||||
source_sha256: createHash("sha256").update(factory).digest("hex"),
|
||||
location: {
|
||||
start: { line: 1, column: start },
|
||||
end: { line: 1, column: start + factory.length },
|
||||
},
|
||||
});
|
||||
}, 30_000);
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
/** Inert generated Webpack source; no fixture code is executed. */
|
||||
export const javascriptAsyncChunkCapacity = (count: number) => {
|
||||
const factory = `(m,e,r)=>{${Array.from(
|
||||
{ length: count },
|
||||
(_, index) => `r.e(${String(index)});`,
|
||||
).join("")}}`;
|
||||
return {
|
||||
factory,
|
||||
source:
|
||||
`self.webpackChunkapp.push([[1],{1:${factory},` +
|
||||
"2:(m,e,r)=>{r.e(0);r.e('later');r.e(dynamic);}}]);",
|
||||
};
|
||||
};
|
||||
Reference in new issue
Block a user