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 collectionrecords
: array of full record data structured as{id, record}
pairsversion
: starting version number of the collectionsuccess
: 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