Skip to Content
Client SDKCollections

Client: Collections

When subscribing to a collection, the client receives:

  • A list of current record IDs and their data
  • All collection changes (additions, removals, and record updates) through a single onDiff handler

This is useful for filtered lists, dashboards, multiplayer rooms, etc.

Subscribing to a collection

Use subscribeCollection(...) to subscribe:

const result = await client.subscribeCollection("collection:all-tasks", { onDiff: ({ added, removed, changed, version }) => { // Called for all collection changes: // - When records are added to or removed from the collection // - When records within the collection are updated }, });

The subscribeCollection() call returns a promise that resolves with:

  • ids: array of current member IDs in the collection
  • records: array of full record data structured as {id, record} pairs
  • version: starting version number of the collection
  • success: boolean indicating if the subscription was successful
const result = await client.subscribeCollection("collection:all-tasks", { onDiff: ({ added, removed, changed, version }) => { // Handle changes... }, }); console.log(result.ids); // ["task:1", "task:2", "task:3"] console.log(result.records); // [{id: "task:1", record: {...}}, ...] console.log(result.version); // 1 console.log(result.success); // true

Handling all collection changes

The onDiff callback is triggered for all collection changes with three arrays:

onDiff: ({ added, removed, changed, version }) => { // added: {id: string, record: any}[] - records added to the collection // removed: {id: string, record: any}[] - records removed from the collection // changed: {id: string, record: any}[] - records updated within the collection (always exactly 1 item) // version: number - the new version number of the collection added.forEach(({ id, record }) => { myLocalRecords.set(id, record); }); removed.forEach(({ id }) => { myLocalRecords.delete(id); }); changed.forEach(({ id, record }) => { myLocalRecords.set(id, record); }); }

Change consistency

The changed array will always contain exactly one record when a record update occurs, maintaining consistency with the added and removed arrays which can contain multiple items during bulk operations.

Record updates within collections

Collections always provide full record data for all changes. Collections do not support patch mode - they always send complete record objects for simplicity.

await client.subscribeCollection("collection:all-tasks", { onDiff: ({ added, removed, changed, version }) => { // All arrays contain full record objects console.log("Added records:", added); console.log("Removed records:", removed); console.log("Changed records:", changed); }, });

Version tracking and resyncing

Internally, Mesh uses version tracking. If your client misses a version (e.g. network drop), Mesh automatically resyncs the full list.

Unsubscribing

When done, unsubscribe:

await client.unsubscribeCollection("collection:all-tasks");

This stops receiving diffs and updates for that collection.

Reconnection

Collections are automatically resubscribed on reconnect, including handlers.

Notes

  • All changes flow through a single onDiff callback for consistency
  • You may still want to subscribe to individual records if you need patch-based updates
  • The changed array always contains exactly one item when triggered
  • Consistent array shapes: All arrays (added, removed, changed) use the same {id, record} structure for consistency

Use cases

  • Live filtered lists: completed vs active, by tag or assignee
  • Per-user dashboards: synced queries scoped to auth context
  • Multiplayer rooms: users in room, players in game
  • Workspace views: synced list of active docs or projects
  • Real-time notifications: unified handling of all list changes
Last updated on
© 2025