Skip to content

Complete SSE refactor: migrate consumers, extract invalidators, drop singleton#9261

Draft
ericpgreen2 wants to merge 5 commits intoericgreen/sse-client-cleanupfrom
ericgreen/sse-consumer-migrations
Draft

Complete SSE refactor: migrate consumers, extract invalidators, drop singleton#9261
ericpgreen2 wants to merge 5 commits intoericgreen/sse-client-cleanupfrom
ericgreen/sse-consumer-migrations

Conversation

@ericpgreen2
Copy link
Copy Markdown
Contributor

@ericpgreen2 ericpgreen2 commented Apr 20, 2026

Stacked on #9260. Migrates the three SSE consumers — FileAndResourceWatcher, Conversation, and ProjectLogsPage — onto the layered client.

Notable

  • fileAndResourceWatcher singleton replaced with per-mount instances via Svelte context.
  • File and resource invalidation extracted into pure, unit-tested modules under runtime-client/invalidation/.
  • Cloud editor wires onBeforeReconnect to invalidate GetProject before each reconnect, ensuring a fresh JWT.
  • All PR Refactor SSE client: tighter boundaries, new lifecycle and subscriber layers #9260 deprecation shims removed (old import paths, auto-close API, heartbeat() alias).
  • SSEConnection.handleError now emits close when retryOnError is false, so one-shot chat streams settle cleanly.

Stacking

Checklist:

  • Covered by tests
  • Ran it and it works as intended
  • Reviewed the diff before requesting a review
  • Checked for unhandled edge cases
  • Linked the issues it closes
  • Checked if the docs need to be updated. If so, create a separate Linear DOCS issue
  • Intend to cherry-pick into the release branch
  • I'm proud of this work!

Developed in collaboration with Claude Code

Completes the SSE refactor by moving the three consumers onto the new
layered API, extracting pure invalidator modules, wiring the cloud
editor's JWT refresh, and dropping the singleton/compat shims from PR 1.

Pure extractions (testable, injectable deps):
- `runtime-client/invalidation/file-invalidators.ts` — file WRITE/DELETE
  handling, rill.yaml side effects, throttled `ListFiles` refetch.
- `runtime-client/invalidation/resource-invalidators.ts` — per-kind
  dispatch for Connector, Source/Model, MetricsView, Explore, Canvas,
  and Component resources plus delete variants.
- `web-admin/.../status/logs/log-store.ts` — ProjectLogsPage state
  machine (monotonic ids, ring buffer, filter-by-level + search).

Consumer migrations:
- `FileAndResourceWatcher` is a thin per-mount class over
  `SSEConnection` + `SSESubscriber` + optional `SSELifecycle`. The
  singleton export is gone; the Svelte component constructs the watcher
  synchronously so `setContext` runs before descendants read it.
- `RuntimeTrafficLights` reads watcher state via the new
  `watcher-context.ts` key, with a safe fallback so it still renders
  outside a watcher provider.
- `Conversation` uses `SSESubscriber` for typed message/error routing;
  untagged frames normalize to the "message" decoder per the SSE spec.
  Transport vs. server errors stay on separate channels.
- `ProjectLogsPage` uses `SSEConnection` + typed `SSESubscriber<{ log,
  error }>` and delegates state to `LogStore`.

Call-site updates:
- `web-local/src/routes/+layout.svelte` → `lifecycle="aggressive"`.
- `web-admin/.../edit/+layout.svelte` → `lifecycle="none"` plus an
  `onBeforeReconnect` hook that invalidates the branch-scoped
  `GetProject` query key so the next `runtimeClient.getJwt()` returns a
  fresh token.

Also:
- `SSEConnection.handleError` now fires `close` when `retryOnError` is
  false so one-shot consumers (chat) can settle cleanly on failure.
- Deprecation shims removed: `sse-fetch-client.ts` and
  `sse-connection-manager.ts` at the old paths; auto-close methods and
  the `autoCloseTimeouts` param stripped from `SSEConnection`.
- New specs: `file-invalidators.spec.ts`,
  `resource-invalidators.spec.ts`, `file-and-resource-watcher.spec.ts`,
  `RuntimeTrafficLights.spec.ts`, `conversation-streaming.spec.ts`,
  `log-store.spec.ts`. `web-admin/package.json` gains a `test:unit`
  script for the latter.
…to ericgreen/sse-consumer-migrations

# Conflicts:
#	web-common/src/runtime-client/sse/sse-connection.ts
…er-migrations

# Conflicts:
#	web-common/src/runtime-client/sse/sse-connection.ts
With all consumers migrated off the deprecated auto-close API in the
previous commit, the last PR 1 shims can go:
- heartbeat() alias on SSEConnection (use resumeIfPaused() directly)
- SSEConnectionLifecycle's schedulePause / cancelScheduledPause are
  now private; no external caller drives them
@ericpgreen2 ericpgreen2 changed the title SSE consumer migrations + singleton removal Complete SSE refactor: migrate consumers, extract invalidators, drop singleton Apr 21, 2026
@ericpgreen2 ericpgreen2 self-assigned this Apr 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant