Queries
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. :::
Protobuf
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 protobuf
:
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 prebuild
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.