import { bindWebEngineRelease, selectWebEngineVariant, type WasmThreadingCapabilities, type WebEngineReleaseBinding, type WebEngineVariantPolicy, } from "../../../protocol/engine-variant"; import type { CapabilityGateResult } from "../../../protocol/capability-gates"; import type { WebEngineManifestV2, WebEngineVariantV2 } from "../../../protocol/manifest"; export interface EngineVariantResourceState { handles: number; workers: number; timers: number; pendingRequests: number; } export interface EngineVariantSession { readonly variant: WebEngineVariantV2; openProject(project: Project): Promise; dispose(): Promise; resourceState(): EngineVariantResourceState; testOnlySeedTrackedResources?(): void; } export interface EngineVariantFallbackReason { code: "PTHREAD_INITIALIZATION_FAILED"; message: string; } export interface EngineVariantBootstrapResult { status: "READY"; selected: "single" | "pthread"; attempted: Array<"single" | "pthread">; fallbackReason: EngineVariantFallbackReason | null; pthreadGate: CapabilityGateResult; openCount: number; failedAttemptCleanup: EngineVariantResourceState | null; } export interface EngineVariantBootstrapOutcome { result: EngineVariantBootstrapResult; session: EngineVariantSession; } export type WebEngineRefreshRequired = Extract; export type WebEngineReleaseBootstrapOutcome = | EngineVariantBootstrapOutcome | { result: WebEngineRefreshRequired; session: null }; export interface EngineVariantBootstrapDependencies { initialize(variant: WebEngineVariantV2): Promise>; } export interface EngineVariantBootstrapTestHooks { failPthreadAfterInitialize?: boolean; seedTrackedPthreadResources?: boolean; } export class EngineVariantLoadError extends Error { readonly code: "ENGINE_VARIANT_RESOURCE_REQUEST_FAILED" | "ENGINE_VARIANT_RESOURCE_HASH_MISMATCH"; constructor(code: EngineVariantLoadError["code"], message: string, options?: ErrorOptions) { super(message, options); this.name = "EngineVariantLoadError"; this.code = code; } } export class EngineVariantBootstrapError extends Error { readonly code: "ENGINE_VARIANT_INTEGRITY_FAILED"; readonly attempted: Array<"single" | "pthread">; constructor(attempted: Array<"single" | "pthread">, cause: EngineVariantLoadError) { super(`${cause.code}: ${cause.message}`, { cause }); this.name = "EngineVariantBootstrapError"; this.code = "ENGINE_VARIANT_INTEGRITY_FAILED"; this.attempted = [...attempted]; } } function failureMessage(error: unknown): string { return error instanceof Error && error.message ? error.message : "pthread engine initialization failed"; } function rejectIntegrityFailure( error: unknown, attempted: Array<"single" | "pthread">, ): void { if (error instanceof EngineVariantLoadError && error.code === "ENGINE_VARIANT_RESOURCE_HASH_MISMATCH") { throw new EngineVariantBootstrapError(attempted, error); } } async function bootstrapSelectedWebEngineVariant( manifest: WebEngineManifestV2, policy: WebEngineVariantPolicy, capabilities: WasmThreadingCapabilities, dependencies: EngineVariantBootstrapDependencies, pendingProject?: Project, testHooks?: EngineVariantBootstrapTestHooks, ): Promise> { const selection = selectWebEngineVariant(manifest, policy, capabilities); if (!selection.selectedVariant) throw new Error("PTHREAD_REQUIRED_CAPABILITY_BLOCKED"); const attempted: Array<"single" | "pthread"> = []; let failedAttemptCleanup: EngineVariantResourceState | null = null; let fallbackReason: EngineVariantFallbackReason | null = null; let session: EngineVariantSession | null = null; const initialize = async (variant: WebEngineVariantV2): Promise> => { attempted.push(variant.id); return dependencies.initialize(variant); }; try { session = await initialize(selection.selectedVariant); if (selection.selectedVariant.id === "pthread") { if (testHooks?.seedTrackedPthreadResources) session.testOnlySeedTrackedResources?.(); if (testHooks?.failPthreadAfterInitialize) throw new Error("TEST_PTHREAD_INITIALIZATION_FAILURE"); } } catch (error) { const failedSession = session; if (failedSession) failedAttemptCleanup = await failedSession.dispose(); rejectIntegrityFailure(error, attempted); if (policy !== "AUTO" || selection.selectedVariant.id !== "pthread") throw error; fallbackReason = { code: "PTHREAD_INITIALIZATION_FAILED", message: failureMessage(error) }; const single = manifest.variants.find((variant) => variant.id === "single"); if (!single) throw new Error("ENGINE_MANIFEST_VARIANTS_MISSING", { cause: error }); try { session = await initialize(single); } catch (fallbackError) { rejectIntegrityFailure(fallbackError, attempted); throw fallbackError; } } if (!session) throw new Error("ENGINE_VARIANT_INITIALIZATION_FAILED"); let openCount = 0; if (pendingProject !== undefined) { try { await session.openProject(pendingProject); openCount = 1; } catch (error) { await session.dispose(); throw error; } } return { result: { status: "READY", selected: session.variant.id, attempted, fallbackReason, pthreadGate: selection.pthreadGate, openCount, failedAttemptCleanup, }, session, }; } export async function bootstrapWebEngineRelease( expectedReleaseId: string, manifest: WebEngineManifestV2, policy: WebEngineVariantPolicy, capabilities: WasmThreadingCapabilities, dependencies: EngineVariantBootstrapDependencies, pendingProject?: Project, testHooks?: EngineVariantBootstrapTestHooks, ): Promise> { const binding = bindWebEngineRelease(expectedReleaseId, manifest); if (binding.status === "REFRESH_REQUIRED") { return { result: binding, session: null }; } return bootstrapSelectedWebEngineVariant( binding.manifest, policy, capabilities, dependencies, pendingProject, testHooks, ); } export function engineVariantStatusLabel(result: EngineVariantBootstrapResult): string { if (result.selected === "pthread") return "Runtime: pthread"; return result.fallbackReason ? `Runtime: single (pthread fallback: ${result.fallbackReason.code})` : "Runtime: single"; }