TILLCACHE · PUB/SUB

Fan-out, over one stream.

GA

Publish a message to a channel and every current subscriber gets it. Delivery runs over Server-Sent Events, so a subscriber is a long-lived HTTP stream — no extra protocol, no socket server to run.

01Publish

publish(channel, message)

ts
import { cache } from './cache'

// Fan a message out to everyone subscribed to the channel:
await cache.publish('presence', { user: 'ada', status: 'online' })

publish() delivers to whoever is subscribed right now. It’s fire-and-forget fan-out — for durable, replay-on-restart work that must not be missed, use a queue instead.

02Subscribe

subscribe(channel, onMessage, opts)

subscribe() opens an SSE stream and calls your onMessage for each event. Pass an AbortSignal to close the stream when you’re done:

ts
import { cache } from './cache'

const ac = new AbortController()

cache.subscribe('presence', (message) => {
  // message is the payload passed to publish(), deserialized
  console.log('presence update', message)
}, { signal: ac.signal })

// Later — stop receiving and close the SSE stream:
ac.abort()
Always pass a signal
A subscription is a live connection. Wire an AbortController to your component or request lifecycle and abort() it on teardown — otherwise streams leak.
03Pattern

Tearing down in React

The signal maps cleanly onto an effect cleanup — subscribe on mount, abort on unmount:

tsx
import { useEffect } from 'react'
import { cache } from './cache'

function usePresence(onUpdate: (m: unknown) => void) {
  useEffect(() => {
    const ac = new AbortController()
    cache.subscribe('presence', onUpdate, { signal: ac.signal })
    return () => ac.abort()   // tear down on unmount
  }, [onUpdate])
}
04Choosing

Pub/sub vs. a queue

  • Pub/sub — one-to-many, ephemeral, delivered to live subscribers. Great for presence, live dashboards, cache-invalidation pings, and UI updates.
  • Queues — one message, one worker, durable and retried until acked. Great for jobs that must run, where “nobody was subscribed” isn’t an acceptable outcome.

Back to the TillCache overview, or read up on Backends & vendors to see where a namespace’s channels are anchored.