Package the Guestbook app
Status#
Done. Guestbook is packaged behind one combined fetch/event factory, config retains only migration bridges, source and state migrations pass, and the live browser, ingress, preview, and telemetry proofs are clean.
Move the Guestbook implementation from generated config repos into iterate/starter-apps/guestbook. This is the combined app case: one factory instance must expose both HTTP fetch and committed project-stream processEvent.
Decisions#
- Export
GuestbookApp.create(env)with{ fetch, processEvent }. - Keep the physical Durable Object stateful, under the existing
app-guestbook-streamdurable key. - Keep
/guestbookas the canonical event stream and preserve the existing processor state contract. fetchdispatches through the project's ITX worker bridge.processEventfilters Guestbook events and wakes the packaged stateful worker so externally appended events reach its derived state and live clients.- Preserve or supersede the existing WAKE subscription safely so upgraded projects do not retain a config-source worker reference.
- The package must own the server, processor, browser client, and configured-worker artifact. Generated config repos only compose the factory.
- The independently deployed Tasks proxy is follow-up work, not part of this change.
Checklist#
- Add a failing public contract test for one factory exposing both
fetchandprocessEvent. Red import failure, then green dispatch + event-delivery contract inguestbook.test.ts. - Export the packaged Guestbook runtime and physical configured-worker artifact.
iterate/starter-apps/guestbookowns the factory;dist/starter-apps/guestbook/configured-worker.mjsowns the stateful runtime. - Embed a browser-ready Guestbook client with a guard against bare browser imports. The client build emits one self-contained asset and the manifest-driven bundle checker rejects imports.
- Preserve durable identity, stream history, processor state, and subscription migration. The deployed createApp→createWorker test kept
app-guestbook-stream, its folded entry, and retiredapp-guestbook#guestbook. - Compose both Guestbook methods in the generated config-repo worker. One
GuestbookApp.create(this.env)instance receives routed HTTP and committed events. - Remove Guestbook implementation source from generated config repos. Only two temporary one-line source-upgrade bridges remain at paths persisted by old WAKE refs.
- Prove browser signing and reload still work. The real preview browser signed and reloaded an entry in 24.0s.
- Prove an externally appended Guestbook event reaches state through
processEvent. The live ingress test appended directly to/guestbookand observed packaged state. - Prove existing Guestbook state survives the source move. The exact deployed source-swap test passed in 16.2s.
- Update the paired
iterate/configpull request. iterate/config#19 imports the package factory on both lanes and deletes the processor/ref. - Run package, type, lint, format, browser, preview, and trace checks. All local checks and the 4m38 preview rollup pass; the exact telemetry window has zero errors.
Implementation log#
- Assumption: keeping the current durable key and processor storage shape is the compatibility boundary; source ownership may move without changing application identity.
- Assumption: duplicate wakeups during subscription migration are acceptable only if they are bounded and idempotent. They must not create duplicate entries or unexplained error telemetry.
- Red/green: the public contract test first failed because
./index.tsdid not exist, then passed after the factory dispatched HTTP to the physical ref and forwarded only/guestbookevents. - The packaged app appends an idempotent
subscription-removedfact forapp-guestbook#guestbook; project-workerprocessEventis now the sole durable delivery spine. project-ingress.e2e.test.tsnow appends an entry directly to the stream and waits for packaged state, whileguestbook-package-migration.e2e.test.tscrosses from the formercreateAppref to the physical worker with the same durable key.- Local package build, package tests (170), full typecheck, lint, template typecheck, and template unit tests pass.
- Deployed preview proof: ingress/WebSocket suite 3/3 (45.1s), source migration 1/1 (16.2s), and browser sign/reload 1/1 (24.0s).
- Cloudflare audit for
os-preview-11, 2026-07-24T13:43:00Z–13:46:00Z: 92 Guestbook-matching events, 82 info + 10 unset request rows, nine explicitokoutcomes, zero error-level events, script versionaf7df206-50ce-490b-8675-aab60015c222. Example trace:a9989722bad8c475cfe044caa96c589e.