Surfaced while implementing #16378 (option (c), the wss:// / ws:// refusal, PR #16616). Filed bare and unassigned for triage; outside that card's scope by ruling.
Contract text
TursoDriverConfig.timeout (packages/drivers/driver-turso/src/turso-driver.ts): "Operation timeout in milliseconds for remote operations. Effective in replica and remote modes; 0 or unset means no bound. … Remote mode over HTTP (libsql://, https://, http://): every request the client's HTTP transport makes. The driver hands @libsql/client a fetch that aborts once the window elapses …"
TursoDriverConfig.client: "Pre-configured @libsql/client instance. When provided, TursoDriver uses this client directly instead of creating its own. … Only effective in remote and replica modes." Nothing there says timeout stops applying.
What the code does (read on origin/main at 434ca2d64, after PR #16376)
The window is applied in exactly one place: createRemoteClient() spreads { fetch: fetchBoundedBy(timeoutMs) } into createClient(...). Both remote-mode client sites bypass it when client is set:
connect(): this.libsqlClient = this.tursoConfig.client ?? (await this.createRemoteClient())
- the lazy-connect factory registered in the constructor (
setConnectFactory): the same expression.
So new TursoDriver({ url: 'https://…', client: myClient, timeout: 30000 }) constructs, connects, and every request runs unbounded, with nothing said — the declared-but-unenforced shape ADR-0049 names, narrowed to one composition, and the same shape #16378 addresses for the WebSocket schemes. The replica arm is NOT affected: sync() is bounded by boundedBy whatever client is in use.
Not measured
Whether any deployment composes a pre-built client with timeout. The datasource seam (buildTursoDriverConfig in @objectstack/service-datasource) never emits client — it is a host-composition escape hatch, "never authorable config" — so this reaches only direct new TursoDriver(...) / createTursoDriver(...) callers.
Options (none recommended here)
Related: #16378 · #16024 · ADR-0049
Surfaced while implementing #16378 (option (c), the
wss:///ws://refusal, PR #16616). Filed bare and unassigned for triage; outside that card's scope by ruling.Contract text
TursoDriverConfig.timeout(packages/drivers/driver-turso/src/turso-driver.ts): "Operation timeout in milliseconds for remote operations. Effective in replica and remote modes;0or unset means no bound. … Remote mode over HTTP (libsql://,https://,http://): every request the client's HTTP transport makes. The driver hands@libsql/clientafetchthat aborts once the window elapses …"TursoDriverConfig.client: "Pre-configured @libsql/client instance. When provided, TursoDriver uses this client directly instead of creating its own. … Only effective in remote and replica modes." Nothing there saystimeoutstops applying.What the code does (read on
origin/mainat434ca2d64, after PR #16376)The window is applied in exactly one place:
createRemoteClient()spreads{ fetch: fetchBoundedBy(timeoutMs) }intocreateClient(...). Both remote-mode client sites bypass it whenclientis set:connect():this.libsqlClient = this.tursoConfig.client ?? (await this.createRemoteClient())setConnectFactory): the same expression.So
new TursoDriver({ url: 'https://…', client: myClient, timeout: 30000 })constructs, connects, and every request runs unbounded, with nothing said — the declared-but-unenforced shape ADR-0049 names, narrowed to one composition, and the same shape #16378 addresses for the WebSocket schemes. The replica arm is NOT affected:sync()is bounded byboundedBywhatever client is in use.Not measured
Whether any deployment composes a pre-built client with
timeout. The datasource seam (buildTursoDriverConfigin@objectstack/service-datasource) never emitsclient— it is a host-composition escape hatch, "never authorable config" — so this reaches only directnew TursoDriver(...)/createTursoDriver(...)callers.Options (none recommended here)
timeoutbesideclientin remote mode at construction — theTursoDriverConfig.timeouthas no seam on the WebSocket transport (wss:///ws://) in @libsql/client 0.17.4 — documented as unbounded, not delivered #16378 shape one composition over; loud, changes nothing on the wire;@libsql/client, the window ridesConfig.fetchat client creation;clientas taking over the window — the ADR-0049 leg that "documenting" must argue for rather than default into.Related: #16378 · #16024 · ADR-0049