fix(web): make first wasm load work on remote deployment
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled

- Correct engine-manifest single wasm SHA and reuse cache for verification.
- Remove duplicate main-thread wasm fetch; raise init timeout to 300s.
- Record production deployment details and verification evidence.

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
mes123456
2026-11-12 22:38:04 +08:00
parent d5dd647881
commit c92cd933c5
6 changed files with 45 additions and 12 deletions

View File

@@ -326,7 +326,9 @@ export class WebEngineClient {
}
async init(): Promise<WebEngineStatus> {
return (await this.request({ type: "init" })).status;
// The first load fetches and instantiates the multi-hundred-MB engine wasm.
// A 30 s budget only fits loopback; remote deployments need a longer first-run window.
return (await this.request({ type: "init" }, [], undefined, undefined, undefined, 300_000)).status;
}
async gpuUICapabilities(): Promise<NonNullable<WebEngineResult["gpuUI"]>> {
@@ -1249,6 +1251,7 @@ export class WebEngineClient {
onProgress?: (progress: ProgressEvent) => void,
signal?: AbortSignal,
nativeInterrupt?: Int32Array,
timeoutMs = this.timeoutMs,
): Promise<WebEngineResult> {
if (this.shutdownTask && command.type !== "shutdown" && command.type !== "cancelOpen") return Promise.reject(this.report("INVALID_ARGUMENT", "SESSION_CLOSE_PENDING: native session persistence is in progress", true));
if (command.type === "openBlend" && signal?.aborted) return Promise.reject(this.report("OPEN_CANCELLED", "Blend open cancelled before dispatch", true));
@@ -1270,7 +1273,7 @@ export class WebEngineClient {
if (nativeInterrupt && Atomics.load(nativeInterrupt, 0) === 1 && !interruptGraceUsed) {
interruptGraceUsed = true;
const pending = this.pending.get(requestId);
if (pending) pending.timer = setTimeout(onTimeout, Math.min(this.timeoutMs, 5000));
if (pending) pending.timer = setTimeout(onTimeout, Math.min(timeoutMs, 5000));
return;
}
const pending = this.pending.get(requestId);
@@ -1279,9 +1282,9 @@ export class WebEngineClient {
pending.timedOut = true;
pending.timeoutError = this.report("WORKER_TERMINATED", `WebEngine 请求超时: ${command.type}`, true);
pending.cleanup?.(); pending.cleanup = undefined; pending.reject(pending.timeoutError!);
pending.timer = setTimeout(() => { if (this.pending.get(requestId) !== pending) return; this.pending.delete(requestId); this.retiredPending.set(requestId, pending); }, this.timeoutMs);
pending.timer = setTimeout(() => { if (this.pending.get(requestId) !== pending) return; this.pending.delete(requestId); this.retiredPending.set(requestId, pending); }, timeoutMs);
};
const timer = setTimeout(onTimeout, Math.max(this.timeoutMs,this.renderDeadline-Date.now()));
const timer = setTimeout(onTimeout, Math.max(timeoutMs,this.renderDeadline-Date.now()));
const abort = (): void => {
void this.request({ type: "cancelOpen", targetRequestId: requestId })
.catch(() => undefined);