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 { Expando, create } from '@dxos/client/echo';
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({ type: 'task' });
  const unsubscribeFn = query.subscribe(({ objects }) => {    objects.forEach((object) => {      if (object.type === 'task') {        // Do something with this task.      }    });  });
  try {    const taskObject = create(Expando, { type: 'task', title: 'buy milk' });    space.db.add(taskObject);    const eventObject = create(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 { effect } from '@preact/signals-core';
import { Client } from '@dxos/client';import { Expando, create } from '@dxos/client/echo';import { registerSignalsRuntime } from '@dxos/echo-signals';
registerSignalsRuntime();
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 = create(Expando, { type: 'task', name: 'buy milk' });  space.db.add(object);
  const names: string[] = [];
  const unsubscribeFn = effect(() => {    names.push(object.title);  });
  object.name = 'buy cookies';
  if (names.join() === ['buy milk', 'buy cookies'].join()) {    // Success.  }
  unsubscribeFn();};