Testnet is now LIVE at testnet.spacetimedb.com! NOTE: This is a testnet, and all data will be wiped periodically.

1.0 RC1

Login

The SpacetimeDB Typescript client SDK

The SpacetimeDB client SDK for TypeScript contains all the tools you need to build clients for SpacetimeDB modules using Typescript, either in the browser or with NodeJS.

Note

You need a database created before use the client, so make sure to follow the Rust or C# Module Quickstart guides if need one.

Install the SDK

First, create a new client project, and add the following to your tsconfig.json file:

{
  "compilerOptions": {
    //You can use any target higher than this one
    //https://www.typescriptlang.org/tsconfig#target
    "target": "es2015"
  }
} 

Then add the SpacetimeDB SDK to your dependencies:

cd client
npm install @clockworklabs/spacetimedb-sdk 

You should have this folder layout starting from the root of your project:

quickstart-chat
├── client
   ├── node_modules
   ├── public
   └── src
└── server
    └── src 

Tip for utilities/scripts

If want to create a quick script to test your module bindings from the command line, you can use https://www.npmjs.com/package/tsx to execute TypeScript files.

Then you create a script.ts file and add the imports, code and execute with:

npx tsx src/script.ts 

Generate module bindings

Each SpacetimeDB client depends on some bindings specific to your module. Create a module_bindings directory in your project's src directory and generate the Typescript interface files using the Spacetime CLI. From your project directory, run:

mkdir -p client/src/module_bindings
spacetime generate --lang typescript \
    --out-dir client/src/module_bindings \
    --project-path server 

And now you will get the files for the reducers & tables:

quickstart-chat
├── client
   ├── node_modules
   ├── public
   └── src
|       └── module_bindings
|           ├── add_reducer.ts
|           ├── person.ts
|           └── say_hello_reducer.ts
└── server
    └── src 

Import the module_bindings in your client's main file:

import { SpacetimeDBClient, Identity } from '@clockworklabs/spacetimedb-sdk';

import Person from './module_bindings/person';
import AddReducer from './module_bindings/add_reducer';
import SayHelloReducer from './module_bindings/say_hello_reducer';
console.log(Person, AddReducer, SayHelloReducer); 

Note

There is a known issue where if you do not use every type in your file, it will not pull them into the published build. To fix this, we are using console.log to force them to get pulled in.

API at a glance

Classes

Class Description
SpacetimeDBClient The database client connection to a SpacetimeDB server.
Identity The user's public identity.
Address An opaque identifier for differentiating connections by the same Identity.
{Table} {Table} is a placeholder for each of the generated tables.
{Reducer} {Reducer} is a placeholder for each of the generated reducers.

Class SpacetimeDBClient

The database client connection to a SpacetimeDB server.

Defined in spacetimedb-sdk.spacetimedb:

Constructors Description
SpacetimeDBClient.constructor Creates a new SpacetimeDBClient database client.
Properties
SpacetimeDBClient.identity The user's public identity.
SpacetimeDBClient.live Whether the client is connected.
SpacetimeDBClient.token The user's private authentication token.
Methods
SpacetimeDBClient.connect Connect to a SpacetimeDB module.
SpacetimeDBClient.disconnect Close the current connection.
SpacetimeDBClient.subscribe Subscribe to a set of queries.
Events
SpacetimeDBClient.onConnect Register a callback to be invoked upon authentication with the database.
SpacetimeDBClient.onError Register a callback to be invoked upon a error.

Constructors

SpacetimeDBClient constructor

Creates a new SpacetimeDBClient database client and set the initial parameters.

new SpacetimeDBClient(host: string, name_or_address: string, auth_token?: string, protocol?: "binary" | "json") 

Parameters

Name Type Description
host string The host of the SpacetimeDB server.
name_or_address string The name or address of the SpacetimeDB module.
auth_token? string The credentials to use to connect to authenticate with SpacetimeDB.
protocol? "binary" | "json" Define how encode the messages: "binary" | "json". Binary is more efficient and compact, but JSON provides human-readable debug information.

Example

const host = 'ws://localhost:3000';
const name_or_address = 'database_name';
const auth_token = undefined;
const protocol = 'binary';

var spacetimeDBClient = new SpacetimeDBClient(
  host,
  name_or_address,
  auth_token,
  protocol
); 

Class methods

SpacetimeDBClient.registerReducers

Registers reducer classes for use with a SpacetimeDBClient

registerReducers(...reducerClasses: ReducerClass[]) 

Parameters

Name Type Description
reducerClasses ReducerClass A list of classes to register

Example

import SayHelloReducer from './types/say_hello_reducer';
import AddReducer from './types/add_reducer';

SpacetimeDBClient.registerReducers(SayHelloReducer, AddReducer); 

SpacetimeDBClient.registerTables

Registers table classes for use with a SpacetimeDBClient

registerTables(...reducerClasses: TableClass[]) 

Parameters

Name Type Description
tableClasses TableClass A list of classes to register

Example

import User from './types/user';
import Player from './types/player';

SpacetimeDBClient.registerTables(User, Player); 

Properties

SpacetimeDBClient identity

The user's public Identity.

identity: Identity | undefined 

SpacetimeDBClient live

Whether the client is connected.

live: boolean; 

SpacetimeDBClient token

The user's private authentication token.

token: string | undefined 

Parameters

Name Type Description
reducerName string The name of the reducer to call
serializer Serializer -

SpacetimeDBClient connect

Connect to The SpacetimeDB Websocket For Your Module. By default, this will use a secure websocket connection. The parameters are optional, and if not provided, will use the values provided on construction of the client.

connect(host: string?, name_or_address: string?, auth_token: string?): Promise<void> 

Parameters

Name Type Description
host? string The hostname of the SpacetimeDB server. Defaults to the value passed to the constructor.
name_or_address? string The name or address of the SpacetimeDB module. Defaults to the value passed to the constructor.
auth_token? string The credentials to use to authenticate with SpacetimeDB. Defaults to the value passed to the constructor.

Returns

Promise<void>

Example

const host = 'ws://localhost:3000';
const name_or_address = 'database_name';
const auth_token = undefined;

var spacetimeDBClient = new SpacetimeDBClient(
  host,
  name_or_address,
  auth_token
);
// Connect with the initial parameters
spacetimeDBClient.connect();
//Set the `auth_token`
spacetimeDBClient.connect(undefined, undefined, NEW_TOKEN); 

SpacetimeDBClient disconnect

Close the current connection.

disconnect(): void 

Example

var spacetimeDBClient = new SpacetimeDBClient(
  'ws://localhost:3000',
  'database_name'
);

spacetimeDBClient.disconnect(); 

SpacetimeDBClient subscribe

Subscribe to a set of queries, to be notified when rows which match those queries are altered.

A new call to subscribe will remove all previous subscriptions and replace them with the new queries. If any rows matched the previous subscribed queries but do not match the new queries, those rows will be removed from the client cache, and {Table}.on_delete callbacks will be invoked for them.

subscribe(queryOrQueries: string | string[]): void 

Parameters

Name Type Description
queryOrQueries string | string[] A SQL query or list of queries

Example

spacetimeDBClient.subscribe(['SELECT * FROM User', 'SELECT * FROM Message']); 

Events

SpacetimeDBClient onConnect

Register a callback to be invoked upon authentication with the database.

onConnect(callback: (token: string, identity: Identity) => void): void 

The callback will be invoked with the public user Identity, private authentication token and connection Address provided by the database. If credentials were supplied to connect, those passed to the callback will be equivalent to the ones used to connect. If the initial connection was anonymous, a new set of credentials will be generated by the database to identify this user.

The credentials passed to the callback can be saved and used to authenticate the same user in future connections.

Parameters

Name Type
callback (token: string, identity: Identity, address: Address) => void

Example

spacetimeDBClient.onConnect((token, identity, address) => {
  console.log('Connected to SpacetimeDB');
  console.log('Token', token);
  console.log('Identity', identity);
  console.log('Address', address);
}); 

SpacetimeDBClient onError

Register a callback to be invoked upon an error.

onError(callback: (...args: any[]) => void): void 

Parameters

Name Type
callback (...args: any[]) => void

Example

spacetimeDBClient.onError((...args: any[]) => {
  console.error('ERROR', args);
}); 

Class Identity

A unique public identifier for a user of a database.

Defined in spacetimedb-sdk.identity:

Constructors Description
Identity.constructor Creates a new Identity.
Methods
Identity.isEqual Compare two identities for equality.
Identity.toHexString Print the identity as a hexadecimal string.
Static methods
Identity.fromString Parse an Identity from a hexadecimal string.

Constructors

Identity constructor

new Identity(data: Uint8Array) 

Parameters

Name Type
data Uint8Array

Methods

Identity isEqual

Compare two identities for equality.

isEqual(other: Identity): boolean 

Parameters

Name Type
other Identity

Returns

boolean


Identity toHexString

Print an Identity as a hexadecimal string.

toHexString(): string 

Returns

string


Identity fromString

Static method; parse an Identity from a hexadecimal string.

Identity.fromString(str: string): Identity 

Parameters

Name Type
str string

Returns

Identity

Class Address

An opaque identifier for a client connection to a database, intended to differentiate between connections from the same Identity.

Defined in spacetimedb-sdk.address:

Constructors Description
Address.constructor Creates a new Address.
Methods
Address.isEqual Compare two identities for equality.
Address.toHexString Print the address as a hexadecimal string.
Static methods
Address.fromString Parse an Address from a hexadecimal string.

Constructors

Address constructor

new Address(data: Uint8Array) 

Parameters

Name Type
data Uint8Array

Methods

Address isEqual

Compare two addresses for equality.

isEqual(other: Address): boolean 

Parameters

Name Type
other Address

Returns

boolean


Address toHexString

Print an Address as a hexadecimal string.

toHexString(): string 

Returns

string


Address fromString

Static method; parse an Address from a hexadecimal string.

Address.fromString(str: string): Address 

Parameters

Name Type
str string

Returns

Address

Class {Table}

For each table defined by a module, spacetime generate generates a class in the module_bindings folder whose name is that table's name converted to PascalCase.

The generated class has a field for each of the table's columns, whose names are the column names converted to snake_case.

Properties Description
Table.name The name of the class.
Table.tableName The name of the table in the database.
Methods
Table.isEqual Method to compare two identities.
Table.all Return all the subscribed rows in the table.
Table.filterBy{COLUMN} Autogenerated; return subscribed rows with a given value in a particular column. {COLUMN} is a placeholder for a column name.
Table.findBy{COLUMN} Autogenerated; return a subscribed row with a given value in a particular unique column. {COLUMN} is a placeholder for a column name.
Events
Table.onInsert Register an onInsert callback for when a subscribed row is newly inserted into the database.
Table.removeOnInsert Unregister a previously-registered onInsert callback.
Table.onUpdate Register an onUpdate callback for when an existing row is modified.
Table.removeOnUpdate Unregister a previously-registered onUpdate callback.
Table.onDelete Register an onDelete callback for when a subscribed row is removed from the database.
Table.removeOnDelete Unregister a previously-registered onDelete callback.

Properties

{Table} name

name: string

The name of the Class.


{Table} tableName

The name of the table in the database.

▪ Static tableName: string = "Person"

Methods

{Table} all

Return all the subscribed rows in the table.

{Table}.all(): {Table}[] 

Returns

{Table}[]

Example

var spacetimeDBClient = new SpacetimeDBClient(
  'ws://localhost:3000',
  'database_name'
);

spacetimeDBClient.onConnect((token, identity, address) => {
  spacetimeDBClient.subscribe(['SELECT * FROM Person']);

  setTimeout(() => {
    console.log(Person.all()); // Prints all the `Person` rows in the database.
  }, 5000);
}); 

{Table} count

Return the number of subscribed rows in the table, or 0 if there is no active connection.

{Table}.count(): number 

Returns

number

Example

var spacetimeDBClient = new SpacetimeDBClient(
  'ws://localhost:3000',
  'database_name'
);

spacetimeDBClient.onConnect((token, identity, address) => {
  spacetimeDBClient.subscribe(['SELECT * FROM Person']);

  setTimeout(() => {
    console.log(Person.count());
  }, 5000);
}); 

{Table} filterBy{COLUMN}

For each column of a table, spacetime generate generates a static method on the Class to filter subscribed rows where that column matches a requested value.

These methods are named filterBy{COLUMN}, where {COLUMN} is the column name converted to camelCase.

{Table}.filterBy{COLUMN}(value): Iterable<{Table}> 

Parameters

Name Type
value The type of the {COLUMN}.

Returns

Iterable<{Table}>

Example

var spacetimeDBClient = new SpacetimeDBClient(
  'ws://localhost:3000',
  'database_name'
);

spacetimeDBClient.onConnect((token, identity, address) => {
  spacetimeDBClient.subscribe(['SELECT * FROM Person']);

  setTimeout(() => {
    console.log(...Person.filterByName('John')); // prints all the `Person` rows named John.
  }, 5000);
}); 

{Table} findBy{COLUMN}

For each unique column of a table, spacetime generate generates a static method on the Class to find the subscribed row where that column matches a requested value.

These methods are named findBy{COLUMN}, where {COLUMN} is the column name converted to camelCase.

{Table}.findBy{COLUMN}(value): {Table} | undefined 

Parameters

Name Type
value The type of the {COLUMN}.

Returns

{Table} | undefined

Example

var spacetimeDBClient = new SpacetimeDBClient(
  'ws://localhost:3000',
  'database_name'
);

spacetimeDBClient.onConnect((token, identity, address) => {
  spacetimeDBClient.subscribe(['SELECT * FROM Person']);

  setTimeout(() => {
    console.log(Person.findById(0)); // prints a `Person` row with id 0.
  }, 5000);
}); 

{Table} fromValue

Deserialize an AlgebraicType into this {Table}.

 {Table}.fromValue(value: AlgebraicValue): {Table} 

Parameters

Name Type
value AlgebraicValue

Returns

{Table}


{Table} getAlgebraicType

Serialize this into an AlgebraicType.

Example

{Table}.getAlgebraicType(): AlgebraicType 

Returns

AlgebraicType


{Table} onInsert

Register an onInsert callback for when a subscribed row is newly inserted into the database.

{Table}.onInsert(callback: (value: {Table}, reducerEvent: ReducerEvent | undefined) => void): void 

Parameters

Name Type Description
callback (value: {Table}, reducerEvent: undefined | ReducerEvent) => void Callback to run whenever a subscribed row is inserted.

Example

var spacetimeDBClient = new SpacetimeDBClient(
  'ws://localhost:3000',
  'database_name'
);
spacetimeDBClient.onConnect((token, identity, address) => {
  spacetimeDBClient.subscribe(['SELECT * FROM Person']);
});

Person.onInsert((person, reducerEvent) => {
  if (reducerEvent) {
    console.log('New person inserted by reducer', reducerEvent, person);
  } else {
    console.log('New person received during subscription update', person);
  }
}); 

{Table} removeOnInsert

Unregister a previously-registered onInsert callback.

{Table}.removeOnInsert(callback: (value: Person, reducerEvent: ReducerEvent | undefined) => void): void 

Parameters

Name Type
callback (value: {Table}, reducerEvent: undefined | ReducerEvent) => void

{Table} onUpdate

Register an onUpdate callback to run when an existing row is modified by primary key.

{Table}.onUpdate(callback: (oldValue: {Table}, newValue: {Table}, reducerEvent: ReducerEvent | undefined) => void): void 

onUpdate callbacks are only meaningful for tables with a column declared as a primary key. Tables without primary keys will never fire onUpdate callbacks.

Parameters

Name Type Description
callback (oldValue: {Table}, newValue: {Table}, reducerEvent: undefined | ReducerEvent) => void Callback to run whenever a subscribed row is updated.

Example

var spacetimeDBClient = new SpacetimeDBClient(
  'ws://localhost:3000',
  'database_name'
);
spacetimeDBClient.onConnect((token, identity, address) => {
  spacetimeDBClient.subscribe(['SELECT * FROM Person']);
});

Person.onUpdate((oldPerson, newPerson, reducerEvent) => {
  console.log('Person updated by reducer', reducerEvent, oldPerson, newPerson);
}); 

{Table} removeOnUpdate

Unregister a previously-registered onUpdate callback.

{Table}.removeOnUpdate(callback: (oldValue: {Table}, newValue: {Table}, reducerEvent: ReducerEvent | undefined) => void): void 

Parameters

Name Type
callback (oldValue: {Table}, newValue: {Table}, reducerEvent: undefined | ReducerEvent) => void

{Table} onDelete

Register an onDelete callback for when a subscribed row is removed from the database.

{Table}.onDelete(callback: (value: {Table}, reducerEvent: ReducerEvent | undefined) => void): void 

Parameters

Name Type Description
callback (value: {Table}, reducerEvent: undefined | ReducerEvent) => void Callback to run whenever a subscribed row is removed.

Example

var spacetimeDBClient = new SpacetimeDBClient(
  'ws://localhost:3000',
  'database_name'
);
spacetimeDBClient.onConnect((token, identity, address) => {
  spacetimeDBClient.subscribe(['SELECT * FROM Person']);
});

Person.onDelete((person, reducerEvent) => {
  if (reducerEvent) {
    console.log('Person deleted by reducer', reducerEvent, person);
  } else {
    console.log(
      'Person no longer subscribed during subscription update',
      person
    );
  }
}); 

{Table} removeOnDelete

Unregister a previously-registered onDelete callback.

{Table}.removeOnDelete(callback: (value: {Table}, reducerEvent: ReducerEvent | undefined) => void): void 

Parameters

Name Type
callback (value: {Table}, reducerEvent: undefined | ReducerEvent) => void

Class {Reducer}

spacetime generate defines an {Reducer} class in the module_bindings folder for each reducer defined by a module.

The class's name will be the reducer's name converted to PascalCase.

Static methods Description
Reducer.call Executes the reducer.
Events
Reducer.on Register a callback to run each time the reducer is invoked.

Static methods

{Reducer} call

Executes the reducer.

{Reducer}.call(): void 

Example

SayHelloReducer.call(); 

Events

{Reducer} on

Register a callback to run each time the reducer is invoked.

{Reducer}.on(callback: (reducerEvent: ReducerEvent, ...reducerArgs: any[]) => void): void 

Clients will only be notified of reducer runs if either of two criteria is met:

  • The reducer inserted, deleted or updated at least one row to which the client is subscribed.
  • The reducer invocation was requested by this client, and the run failed.

Parameters

Name Type
callback (reducerEvent: ReducerEvent, ...reducerArgs: any[]) => void)

Example

SayHelloReducer.on((reducerEvent, ...reducerArgs) => {
  console.log('SayHelloReducer called', reducerEvent, reducerArgs);
}); 
Edit On Github