feat: Add filters on the realtime subscriptions - #4
Open
ivasilov wants to merge 8 commits into
Open
Conversation
ivasilov
force-pushed
the
feat/realtime-with-filter
branch
from
August 28, 2026 06:53
1cc92d5 to
3d598fd
Compare
saltcod
approved these changes
Aug 28, 2026
ivasilov
force-pushed
the
feat/realtime-with-filter
branch
from
September 6, 2026 20:33
3d598fd to
2e17006
Compare
- Match e2e channel lookup to the numbered topic names by exporting the topic prefix from db.ts. - Route realtime INSERT/UPDATE through writeUpsert and gate update/delete on the synced store, so an echo of an in-flight local mutation no longer throws. Apply the same to the mutation write-backs in functions.ts. - Only drop the previous channel once the replacement reports SUBSCRIBED. On CHANNEL_ERROR keep the working channel, remember the rejected filter set, and fall back to a catch-all subscription. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Taking main's postgrest-filters module during the rebase dropped the realtime branch's Date->ISO conversion, so Date values were rendered via Date.prototype.toString() (a locale string Postgres cannot cast). Route both the raw scalar path and quoteValue through a shared toScalarString helper, and cover the IN-members path with a test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ivasilov
force-pushed
the
feat/realtime-with-filter
branch
from
September 10, 2026 23:21
1bbf269 to
e37caa2
Compare
Gates whether each query's WHERE clause is pushed to the Realtime subscription as a server-side postgres_changes filter. Defaults to true (existing behavior); when false the table subscribes with a catch-all and filters client-side, trading more Realtime traffic for simplicity and avoiding the filter-rejection fallback path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the duplicated ISO-Date conversion and reserved-character quoting in realtime-filters-to-search.ts with the shared PostgREST quoteValue, gated by an isRealtimeScalar validator so null/objects/non-finite numbers still fall back to a catch-all subscription. Surrounding whitespace is now quoted, matching the request path. Add unit coverage for quoting parity, bigint/Date, and non-finite rejection, plus e2e tests that subscribe with reserved-character and whitespace values and assert the real Realtime server accepts the quoted filter and delivers matching inserts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add 15 e2e tests exercising the realtimeUseFilter path end to end, verifying the real Supabase Realtime server both accepts and evaluates the filter syntax realtimeFiltersToSearch emits (a rejected filter silently falls back to catch-all, so this was previously mock-only): - operator matrix: gt/gte/lt/lte, neq, not.gt, in/not.in, not.is.null, and a 100-member IN list — matching rows delivered, non-matching excluded - filter-window UPDATEs: a row updated out of the window stays fresh in the base collection (unfiltered UPDATE listener); one updated into the window is delivered (filtered UPDATE listener) - DELETE delivered while a server-side filter is active - multiple filtered queries stay isolated; an unsupported OR degrades to a catch-all subscription that still syncs Add the startFilteredRealtime(ctx, ...lives) helper (preload + channel-join wait + cleanup). is.null's positive case stays unit-only since the seed schema has no nullable column. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Server-side postgres_changes filtering is now opt-in: collections subscribe to every change and filter client-side unless realtimeUseFilter is explicitly enabled. Update the option's doc comment, point the realtime unit test helpers that exercise filtering at realtimeUseFilter: true, and add a test locking the new catch-all default. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
postgres_changesfilters derived from each active query'sWHEREclause, so a subscribed table only receives rows relevant to the queries currently observing it (falling back to an unfiltered/catch-all subscription when a query's conditions can't be expressed as Realtime filters).eq,neq,gt/gte/lt/lte(and their negations),in/not in,isNull/not isNull, and ANDed composite conditions, with PostgREST-safe value serialization (quoting, escaping) shared between the Realtime filter builder and the query builder.replica identity full).Test plan
pnpm test— 169 tests passpnpm build— builds cleanly