mirror of
https://github.com/morluto/rea.git
synced 2026-10-27 09:55:46 +00:00
105 lines
3.3 KiB
TypeScript
105 lines
3.3 KiB
TypeScript
import type {
|
|
WebModuleArtifactPort,
|
|
WebModuleArtifacts,
|
|
} from "../../application/WebModulePorts.js";
|
|
import type { WebScriptArtifactPort } from "../../application/WebScriptArtifactPort.js";
|
|
import type { ExecutionOptions } from "../../application/AnalysisProvider.js";
|
|
import { ArtifactResourceScope } from "../../artifacts/ArtifactResourceScope.js";
|
|
import { jsonObjectSchema } from "../../domain/jsonValue.js";
|
|
import { err, ok } from "../../domain/result.js";
|
|
import { closeWebArtifactResources } from "../WebArtifactCleanup.js";
|
|
import type { WebModuleTraceInput } from "../../domain/webModuleTrace.js";
|
|
import { LocalWebScriptArtifacts } from "../assets/LocalWebScriptArtifacts.js";
|
|
import {
|
|
readWebArtifactJson,
|
|
webArtifactReadError,
|
|
} from "../assets/WebArtifactReads.js";
|
|
|
|
/** Add an explicitly selected import map to a verified captured-script source. */
|
|
export class LocalWebModuleArtifacts implements WebModuleArtifactPort {
|
|
readonly scripts: WebScriptArtifactPort;
|
|
readonly #resources: ArtifactResourceScope;
|
|
|
|
constructor(
|
|
scripts?: WebScriptArtifactPort,
|
|
resources = scripts instanceof LocalWebScriptArtifacts
|
|
? scripts.resources
|
|
: new ArtifactResourceScope(),
|
|
) {
|
|
this.#resources = resources;
|
|
this.scripts =
|
|
scripts ??
|
|
new LocalWebScriptArtifacts("trace_web_module_imports", resources);
|
|
}
|
|
|
|
async close(): Promise<void> {
|
|
return closeWebArtifactResources(
|
|
"web-module-artifacts",
|
|
this.#resources,
|
|
this.scripts,
|
|
);
|
|
}
|
|
|
|
/** Read selected source and optional map without website requests. */
|
|
async load(input: WebModuleTraceInput, options?: ExecutionOptions) {
|
|
try {
|
|
return await this.#resources.run(() => this.#load(input, options));
|
|
} catch (cause: unknown) {
|
|
return err(
|
|
webArtifactReadError(
|
|
cause,
|
|
{
|
|
operation: "trace_web_module_imports",
|
|
field:
|
|
input.import_map === undefined
|
|
? ["manifest_path"]
|
|
: ["import_map", "path"],
|
|
targetPath: input.import_map?.path ?? input.manifest_path,
|
|
callerSelected: input.import_map !== undefined,
|
|
},
|
|
options?.signal,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
async #load(input: WebModuleTraceInput, options?: ExecutionOptions) {
|
|
const loaded = await this.scripts.load(input, options);
|
|
if (!loaded.ok) return loaded;
|
|
if (input.import_map === undefined)
|
|
return ok({ ...loaded.value, importMap: null });
|
|
const selected = input.import_map;
|
|
try {
|
|
const data = await readWebArtifactJson(
|
|
selected.path,
|
|
4 * 1024 * 1024,
|
|
options?.signal,
|
|
this.#resources,
|
|
);
|
|
const importMap: WebModuleArtifacts["importMap"] = {
|
|
file: {
|
|
path: selected.path,
|
|
sha256: data.sha256,
|
|
bytes: data.bytes.length,
|
|
},
|
|
baseUrl: selected.base_url,
|
|
value: jsonObjectSchema.parse(data.value),
|
|
};
|
|
return ok({ ...loaded.value, importMap });
|
|
} catch (cause: unknown) {
|
|
return err(
|
|
webArtifactReadError(
|
|
cause,
|
|
{
|
|
operation: "trace_web_module_imports",
|
|
field: ["import_map", "path"],
|
|
targetPath: selected.path,
|
|
callerSelected: true,
|
|
},
|
|
options?.signal,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
}
|