Skip to content

Networking-first rewrite with events in mind#349

Open
noahm wants to merge 250 commits into
mainfrom
partykit
Open

Networking-first rewrite with events in mind#349
noahm wants to merge 250 commits into
mainfrom
partykit

Conversation

@noahm

@noahm noahm commented Jul 12, 2024

Copy link
Copy Markdown
Owner

This will be the future form of networking in the app. The whole app uses a shared state that is sync'd between as many users as you see fit. Multiple configuration presets are supported, and users/matches can even be pulled/pushed from a start.gg event. For a more guided tour of all the new features here, see this somewhat outdated video walk-through: https://youtu.be/4Gpj9jTNcfM

The main thing keeping this from merging and replacing our current main branch is the lack of some features that many people still expect, like local-only ITG imports. This can be solved in party by supporting these only in the "classic mode" (no networking) and eventually supporting some sort of external hosting for custom imports.

This PR is perpetually deployed at next.ddr.tools

Current known blockers

  • Support custom/imported data (requires move to separate CDN?)
  • better streamlining for classic mode
  • polished experience for smaller mobile screens

@vercel

vercel Bot commented Jul 12, 2024

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ddr-tools Ready Ready Preview Jul 12, 2026 5:10am

noahm and others added 30 commits March 28, 2026 09:02
resetChart deleted the chart's winner along with its bans/protects/
pocketPicks, so removing a protect/pocket label on a card that also had
a winner marked would wipe the winner.

A chart can legitimately have both an action and a winner at once, and
winners have their own removal control, so resetChart no longer deletes
the winner.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WLriWZavKpUVqb9VRoB6vL
When the websocket to the party server dies, a persistent danger toast
tells users the connection was lost and that changes are disabled. A new
middleware drops locally-dispatched redux actions while the connection
is down (server-originated messages still pass), surfacing a warning
toast if the user attempts a change. On reconnect the toast is replaced
with a success notice and dispatch is re-enabled; the server re-sends
room state to resync the client. Toasts are suppressed inside OBS
browser sources.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AdFh3nxa4T3SdnYgGkDizY
Clients now tag each outgoing action with a unique message id, and the
server confirms receipt with an ack after applying and persisting it. A
client-side tracker re-sends any action that goes unconfirmed for 5
seconds (up to 4 transmissions on a live connection, then a danger
toast announces the change was abandoned). The server remembers
recently applied action ids so re-sends are acked again but never
applied twice.

Actions still unconfirmed across a reconnect are replayed after the
fresh roomstate is applied: the server now includes its recently
applied ids in the roomstate message so replays that actually landed
before the disconnect are dropped instead of duplicated. Dispatch now
stays gated from disconnect until this resync completes (previously it
reopened on socket-open, leaving a window where a local action could be
silently erased by the arriving roomstate).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AdFh3nxa4T3SdnYgGkDizY
Implements step 1 of docs/partykit-sync-roadmap.md: the party server
stamps every accepted action with a monotonic seq and broadcasts it to
all clients including the sender — the echo replaces the separate ack
as receipt confirmation. Clients (SyncManager, formerly
PendingActionTracker) now maintain a confirmed state built only from
server-ordered actions, with unconfirmed local actions rebased on top,
so concurrent edits from multiple clients converge to identical state
in canonical order instead of applying in whatever order each replica
saw. A seq gap (missed broadcast) triggers a reconnect for a fresh
roomstate, and giving up on an undeliverable action now also rolls it
back out of the local display state.

Also fixes event/addCab minting its cab id inside the reducer: replayed
actions must be deterministic, so the id now rides in the payload via a
prepare callback. Previously the sender's local cab id never matched
the id the server and other clients generated for the same action.

Legacy interop: id-less actions from pre-protocol clients are relayed
unstamped excluding the sender (no echo they can't recognize), and a
seq-less server downgrades new clients to plain optimistic apply.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AdFh3nxa4T3SdnYgGkDizY
Adds docs/partykit-sync-design.md: a developer-targeted tour of the
partykit room server, wire protocol, and client replication model as
they exist today, with mermaid sequence diagrams for the connect,
happy-path, concurrent-edit rebase, retry/dedupe, and reconnect flows,
and pointers to the source file implementing each piece. Cross-linked
with the forward-looking roadmap doc.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AdFh3nxa4T3SdnYgGkDizY
…b87r5

Partykit sync: health notifications, delivery confirmation, and server-sequenced replication
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.

3 participants