Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ While pre-1.0, the public API may change between 0.x releases.
that arbitrary column. `assertSyncCompatible` now rejects both loudly at
`registerSync`, alongside the existing `INTEGER PRIMARY KEY` guard. Ordinary
rowid tables (the documented `id TEXT PRIMARY KEY` pattern) are unaffected.
- **`SyncMixin`'s declared `webSocketClose`/`webSocketError` now match their
implementation.** Both were typed as returning `Promise<void>` while the
mixin's overrides return `void` synchronously (there is nothing to await —
both just drop bookkeeping for the closed socket). Retyped to
`void | Promise<void>`, mirroring `@cloudflare/workers-types`'s own
`DurableObject` interface. `webSocketMessage` is genuinely `async` and is
unaffected. Cosmetic: no runtime behavior changed, only the emitted `.d.ts`.

## [0.5.0] — 2026-07-02

Expand Down
11 changes: 11 additions & 0 deletions docs/adr/0015-syncable-mixin.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,14 @@ tddc design gap; a PR against Actors is possible in principle but out of scope.
of CI, to keep the ~13 MB dep out of the package) that opens both socket types
on one DO, forces a hibernation wake, and asserts no cross-talk. The in-CI
host-matrix suite pins the same contract against a fake host.
- **The wake-time restore itself (discriminator 1's `getWebSockets(SYNC_TAG)`
call, `mixin.ts`'s constructor) is not exercised by an actual hibernation
eviction in the in-CI suite** — `@cloudflare/vitest-pool-workers@0.12.21`
(this repo's pinned version) predates the `evictDurableObject`/
`evictAllDurableObjects` helpers that ship a real evict-and-reconstruct
cycle (added in `0.16.20`, which requires `vitest@^4`, a major bump this
repo doesn't carry yet). Today the restore is verified by code-reading plus
the same-instance socket-tag assertions in `tests/host-matrix.test.ts`
(e.g. "sync and host sockets coexist"), not by a test that actually tears
the instance down and reconstructs it. Upgrading `vitest`/`vitest-pool-workers`
to unlock a real wake test is tracked as follow-up work, not bundled here.
4 changes: 2 additions & 2 deletions src/server/mixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ export interface SyncMixin<Env, TUser> {
readonly sync: SyncApi<Env, TUser>
fetch(request: Request): Promise<Response>
webSocketMessage(ws: WebSocket, message: string | ArrayBuffer): Promise<void>
webSocketClose(ws: WebSocket, code: number, reason: string, wasClean: boolean): Promise<void>
webSocketError(ws: WebSocket, error: unknown): Promise<void>
webSocketClose(ws: WebSocket, code: number, reason: string, wasClean: boolean): void | Promise<void>
webSocketError(ws: WebSocket, error: unknown): void | Promise<void>
}

/** The structural constructor shape the mixin needs from a host — nothing more
Expand Down
13 changes: 13 additions & 0 deletions tests/host-matrix.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,19 @@ import { type FakeHost, testSchema } from "./test-worker.ts"
// foreign traffic, no `sql` shadow, and trigger safety on a host with its own
// tables. The fake stands in for the real `agents` package so CI never carries a
// ~13 MB pre-1.0 dependency; a real-`agents` smoke gates version bumps.
//
// GAP (honest, not faked): none of these tests force a real hibernation
// eviction. They assert the tag partition (`getWebSockets(SYNC_TAG)` vs.
// `getWebSockets(HOST_TAG)`) on the SAME live instance — which pins the
// cohosting contract this file exists for, but not the wake-time restore
// itself (`mixin.ts`'s constructor, ADR-0015 discriminator 1) that reruns
// `getWebSockets(SYNC_TAG)` after a fresh eviction-and-reconstruct cycle. As
// of this repo's pinned `@cloudflare/vitest-pool-workers@0.12.21`, there is
// no in-process way to force that cycle: the `evictDurableObject`/
// `evictAllDurableObjects` helpers that do it were added in `0.16.20`, which
// requires `vitest@^4` — a major bump out of scope here. The restore is
// verified by code-reading only; see ADR-0015's Consequences for detail and
// the upgrade this is blocked on.

const codec = createFrameCodec()
const HOST_TAG = "__host"
Expand Down