Subscriptions
Use subscriptions to listen for changes to objects in a space.
Subscribe to a query
Use the subscribe method on a query to listen for changes to objects in a space. The callback will be called with an object containing the new objects that match the query. The return value of subscribe is a function that can be called to stop the subscription.
import { Client } from '@dxos/client';import { Filter, Obj } from '@dxos/echo';import { Expando } from '@dxos/schema';
const client = new Client();
async () => { await client.initialize(); if (!client.halo.identity.get()) { await client.halo.createIdentity(); }
const space = await client.spaces.create();
const query = space.db.query(Filter.type(Expando.Expando, { type: 'task' }));
const unsubscribeFn = query.subscribe((query) => { query.results.forEach((object) => { if (object.type === 'task') { // Do something with this task. } }); });
try { const taskObject = Obj.make(Expando.Expando, { type: 'task', title: 'buy milk', }); space.db.add(taskObject); const eventObject = Obj.make(Expando.Expando, { type: 'event', title: 'arrived at store', }); space.db.add(eventObject); } finally { unsubscribeFn(); }};Subscribe to an object
Objects returned from ECHO queries are based on ReactiveObject, which are a kind of Proxy object that will trigger reactivity and subscriptions like a Preact signal. Unlike signals, the values are read and modified directly rather than through .value.
You can use the effect closure from @preact/signals-core to re-run code whenever the object changes. Any properties of ECHO objects accessed inside effect closures will be tracked and re-run the closure when they change.
import { Client } from '@dxos/client';import { Obj } from '@dxos/echo';import { Expando } from '@dxos/schema';
const client = new Client();
async () => { await client.initialize();
if (!client.halo.identity.get()) { await client.halo.createIdentity(); }
const space = await client.spaces.create();
const object = Obj.make(Expando.Expando, { type: 'task', name: 'buy milk', }); space.db.add(object);
const names: string[] = [object.name];
const unsubscribeFn = Obj.subscribe(object, () => { names.push(object.name); });
Obj.change(object, (o) => { o.name = 'buy cookies'; });
if (names.join() === ['buy milk', 'buy cookies'].join()) { // Success. }
unsubscribeFn();};