refactor(events): self-contained pagination envelope + backend resumer registry#61
Draft
tompscanlan wants to merge 5 commits into
Draft
Conversation
Add a self-describing base64url(JSON {v,q,args?,raw}) continuation envelope
alongside the existing tagCursor/parseCursor. The token names a server-side
query and wraps the opaque backend cursor; no filters bag. decodeCursor never
throws and returns null on malformed/non-JSON/wrong-shape/unknown-q/oversized
input, fail-safing every legacy meili:/d1: tag. rawForQuery enforces the
deep-link query-match rule. Keeps tagCursor/parseCursor for the search/near-me
offset path.
runLoadMoreEvents decodes the envelope and dispatches through a flat registry
keyed by query name (events/hosting/past-events/topic/search-d1/search-meili) —
no routeMeili/if-else, no pipeline switch. Every filter value is
server-authoritative in the registry entry; the client supplies none. The
plain unlisted-inclusive listRecords pipeline has no entry, so no decoded
envelope can reach it (a tampered cursor cannot widen visibility, by
construction). listEventsInput now reads only { cursor, q }; legacy extra
fields are dropped. Shared orQueryFromSlug helper added to topics.ts so page-1
and load-more derive the topic search identically.
Server loads build the first envelope from their own server-authoritative
filters (events/hosting/past-events/search/topics) and consume inbound ?cursor=
via rawForQuery (deep-link query-match). EventList drops the fetchParams prop +
echo loop and POSTs only { cursor } (plus the search term q on the search page).
search D1-fallback and topics now return a real search-d1 / topic envelope
instead of cursor:null, so both paginate beyond page 1 with discoverable +
startsAtMin intact — closing the earlier "results stop after the first batch"
gap. near-me and query.ts untouched.
298e967 to
38f0875
Compare
…ference it Move the load-more continuation model — the cross-backend bug it solves, the self-describing envelope, the resumer registry, and the tamper-safety property — into a new README "load-more pagination" section, and thin the design-essay comments in cursor.ts / events-load-more.ts to point at it while keeping the local invariants. Also sharpen the parseCursor note to separate its permanent use (the Meilisearch offset codec for search + near-me) from the temporary pre-envelope-cursor fail-safe, which can be dropped once those cursors drain.
Remove the events-load-more "maps profile handles" test (a trivial did->handle mapping) and the pass-through assertions that only re-checked a mock's own return value (toHaveLength on mocked output, a flattenEventRecords call count). The security, per-query filter-construction, and route-branching tests — the ones that would actually catch a regression — are untouched.
bd1653f to
37d11a2
Compare
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.
Follow-up to #57. That fix stopped D1/Meili cursors from being cross-consumed; this retires the machinery that made the mistake possible.
fetchParamsquery-reconstruction path is gone.runLoadMoreEvents.Verification:
pnpm -C apps/web check(0 errors) andpnpm -C apps/web test(258 passed) on top of current main after rebasing over #60; also deployed to a test worker and exercised live load-more across the events, search, topics, hosting, and past-events pages.