From 0653c4ead8815a5a3fa98a4da755f61f256df576 Mon Sep 17 00:00:00 2001 From: aron <263346377+aron-cf@users.noreply.github.com> Date: Sat, 1 Aug 2026 10:14:13 +0000 Subject: [PATCH] computer: unify backend connect on a single host-injected signature The shell and module backend interfaces took different connect signatures: the shell kind a bare connect(), the module kind a connect(host) receiving the storage-layer handles the Workspace owns. The split was historical, not necessary; the host bag exists only because the Workspace builds db and fs after the caller constructs the backends. Give WorkspaceBackend.connect the same host parameter and pass the bag on every connect. Shell and container backends ignore it and reach the host through their own transport; the module backend uses it as before. Method-parameter bivariance lets the existing zero-argument implementations satisfy the wider signature unchanged. Collapse the duplicate WorkspaceModuleBackendHost onto the canonical WorkspaceBackendHost so there is one definition. --- packages/computer/src/backend.ts | 22 ++++++++++++++++++++-- packages/computer/src/runtime/types.ts | 9 +-------- packages/computer/src/workspace.ts | 9 ++++++++- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/packages/computer/src/backend.ts b/packages/computer/src/backend.ts index 0156fd2..ca9b517 100644 --- a/packages/computer/src/backend.ts +++ b/packages/computer/src/backend.ts @@ -20,6 +20,22 @@ import type { WorkspaceRPC } from "@cloudflare/computer-rpc"; +// The handles the Workspace owns and injects into a backend when +// it connects. The Workspace constructor builds `db`/`fs` itself, +// after the caller has already constructed the backends and passed +// them in, so a backend cannot capture them at its own +// construction time. `connect(host)` is how the Workspace hands +// over the storage-layer handles once they exist. Shell and +// container backends ignore the bag (they reach the host through +// their own transport); the in-process module backend uses it. +export interface WorkspaceBackendHost { + readonly db: import("@cloudflare/dofs").Database; + readonly waitUntil?: (promise: Promise) => void; + readonly fs: import("@cloudflare/dofs").WorkspaceFilesystem; + readonly git: import("./git/index.js").GitClient; + readonly artifacts: import("./artifacts/index.js").ArtifactClient; +} + export interface WorkspaceBackend { // User-supplied selector. Passed in `ExecOptions.backend` and // `Workspace.push(id)` / `Workspace.pull(id)` to address this @@ -48,8 +64,10 @@ export interface WorkspaceBackend { // Materialise a connection. Called lazily on first use, once // per backend per workspace lifetime. The Workspace caches the // resulting handle by `id`; subsequent exec / push / pull - // calls reuse it. - connect(): Promise; + // calls reuse it. The Workspace always passes its host bag; + // backends that reach the host through their own transport + // ignore it. + connect(host: WorkspaceBackendHost): Promise; } export interface BackendHandle { diff --git a/packages/computer/src/runtime/types.ts b/packages/computer/src/runtime/types.ts index 3fe7c34..52d505c 100644 --- a/packages/computer/src/runtime/types.ts +++ b/packages/computer/src/runtime/types.ts @@ -160,14 +160,7 @@ export interface WorkspaceModuleBackendHandle { close(): Promise; } -export interface WorkspaceModuleBackendHost { - readonly db: import("@cloudflare/dofs").Database; - /** Attach detached backend work to the host event lifetime. */ - readonly waitUntil?: (promise: Promise) => void; - readonly fs: import("@cloudflare/dofs").WorkspaceFilesystem; - readonly git: import("../git/index.js").GitClient; - readonly artifacts: import("../artifacts/index.js").ArtifactClient; -} +export type WorkspaceModuleBackendHost = import("../backend.js").WorkspaceBackendHost; export interface WorkspaceModuleBackend { readonly protocol: "module"; diff --git a/packages/computer/src/workspace.ts b/packages/computer/src/workspace.ts index 115504f..14a9111 100644 --- a/packages/computer/src/workspace.ts +++ b/packages/computer/src/workspace.ts @@ -830,7 +830,14 @@ export class Workspace { this.#observer, "workspace.connect", { "workspace.backend.id": id, "workspace.backend.type": backend.type }, - () => backend.connect(), + () => + backend.connect({ + db: this.#db, + waitUntil: this.#waitUntil, + fs: this.#fs, + git: this.git, + artifacts: this.#artifacts, + }), ); if (generation !== this.#connectionGeneration) { await handle.close().catch(() => undefined);