Skip to main content

Queries

About 2 min

Queries

The simplest way to read the items in a space is to use the space.db.query() method. It's also possible to obtain strongly typed results as described below.

Untyped Queries

Once access is obtained to a space, objects can be retrieved:

import { Client } from '@dxos/client';

const client = new Client();

async () => {
  await client.initialize();
  // get a list of all spaces
  const spaces = client.spaces.get();
  // grab a space
  const space = spaces[0];
  // get all items
  const allObjects = space.db.query();
  // get items that match a filter
  const tasks = space.db.query({ type: 'task' });
  // get items that match a predicate
  const finishedTasks = space.db.query(
    (doc) => doc.type == 'task' && doc.isCompleted
  );
};











 

 

 



The result is an iterable collection of objects that can be used like an array.

Typed Queries

It's possible to receive strongly typed results from query. This is done by declaring a Protobuf schema for the objects in the space.

Benefits of schema declarations
  • ability to generate type-safe data access code, which makes development faster and safer.

Protobufopen in new window is well oriented towards schema migrations, while at the same time being compact and efficient on the wire and in-memory.

Consider this expression of schema declared in protobufopen in new window:

syntax = "proto3";

package example.tasks;

message Task {
  option (object) = true;

  string title = 1;
  bool completed = 2;
}

message TaskList {
  option (object) = true;

  string title = 1;
  repeated Task tasks = 2;
}





 






 




Note

Note the directives option (object) = true; which instruct the framework to generate TypeScript classes from the marked messages.

DXOS provides a tool for conveniently generating entity classes that work with the query interface.

Using a tool called dxtype from @dxos/echo-typegen classes can be generated for use with DXOS Client.

dxtype <input protobuf file> <output typescript file>

Install the dxtype tool as a dev dependency:

npm install --save-dev @dxos/echo-typegen

Install base types for the generated code:

npm install @dxos/echo-schema

Now scripts have access to dxtype:

dxtype <input protobuf file> <output typescript file>

Tip

If you're using one of the DXOS application templates, this type generation step is pre-configured as a prebuildopen in new window script for you.

There are other utilities like a filter you can pass to useQuery to locate items of this type. :::

To use the type declarations, simply import the relevant type like Task from the typescript location out of dxtype and pass it to query<T>:

For example, defining types in a folder named schema:

The schema protobuf file:

schema/schema.proto
syntax = "proto3";

package example.tasks;

message Task {
  option (object) = true;

  string title = 1;
  bool completed = 2;
}

message TaskList {
  option (object) = true;

  string title = 1;
  repeated Task tasks = 2;
}





 






 




The script in package.json:

package.json
{
  "scripts": {
    "prebuild": "dxtype schema/schema.proto schema/index.ts"
  }
}

After executing npm run prebuild, types are available in schema/index.ts:

import { Client } from '@dxos/client';

import { Task, types } from './schema';

const client = new Client();

async () => {
  await client.initialize();
  client.addSchema(types);
  // get a list of all spaces
  const spaces = client.spaces.get();
  // grab a space
  const space = spaces[0];
  // get items that match a filter: type inferred from Task.filter()
  const tasks: Task[] = space.db.query(Task.filter()).objects;
};

Note the client.addSchema(types) call which registers the generated types with the client.