Remote / foldkit-remote-drizzle

pollLive

function · packages/remote-drizzle/src/poll.ts:101

function pollLive<P, R>(
  source: EntitySource<P, R>,
  options?: {
    readonly every?: Duration.Input | undefined
    readonly changes?: RowLog<R> | undefined
  },
): LiveSource<P, R>

A live source that polls from inside the subscriber's own request. Each tick reads the subscribed rows again through the entity's source as a read answers the subscriber (RemoteServer.readAs: its authorize and filter applied, so a member it may not read is never sent), and patches what moved since the last tick: a row absent at one tick and present at the next patches whole, and one present and then gone, or no longer visible to the subscriber, is deleted. A field compares by what it holds (Equal.equals), since a read makes a new value of a relation's refs or a date every time, and comparing by identity would patch it on every tick. It names source as the one it reads, so GuardServer.validate accepts it over the guarded source it checks.

A stream also diffs each list its subscriber reads live (Data.query(…, { live: true }), admitted and run by handlers as the subscriber reads it): a listed row's change is a patch, a row that joined a patch and then an insert, one that left a delete and then a remove, each by the fields the read selects. Its first read is silent, and then invalidates the list once, so a page read before the stream opened (or while it was down) asks again. A list's window is run again each tick that may have moved it (every tick without a log, a tick the log names a row of the entity with one), so a row joins by the query's own filter and window. A row that leaves it and is still there to the principal is only removed from the list; one gone, or no longer readable, is deleted too.

With changes, a tick asks the log first and reads only the rows it names: none on a quiet tick. The log is read before the rows, so a write between the two shows on the next tick. A log that fails, or no longer reaches back to the last entry read, reads everything, as with no log. A list whose read fails is asked again from the same entry on the next tick; a subscribed row's failed read fails the stream, and the client's reconnect reads again. The subscribed rows are read in one read a tick, of every field any of them asks the principal may read; RemoteServer.handlers admits no more of them than its maxIdsPerEntity.