Timespace has a powerful library for scripting reads and writes to records.

Warning! Never run scripts that you don't understand. Attackers can use them to gain access to your data.

Getting started

You can run these commands in the browser inspector. They work in Google Chrome, at least.

A Node.js library is also available, contact

Accessing the Session and the Broker

The Session has details about the current context and the Broker gives access to records.

const session = require('whitespace/browser/init-session');
const broker = session.get_broker();

Accessing records

The session can now be used to get a reference to the record open in the browser.

const record = session.get_selected_object();

You can get references to any object with their ID. The ID can be found as the first number part of the URL:<ID>/...

const record = broker.get(362109944);

Reading Data

The Record class contains Promise based accessors for reading record data.


record.get_name().then( console.log, console.warn );
record.get_modification_date().then( console.log, console.warn );
record.get_clouds().then( console.log, console.warn );

A cloud is also a Record:

record.get_clouds().then( (clouds) => {
  clouds[0].get_name().then( console.log, console.warn );
} );

Accessing fields

A Record is a collection of fields identified by name. The field name can either be plain text or a Record itself in which case it is referred to with the #ID syntax.

To get the cover image:

record.get_value( '#801708327', 'en' ).then( console.log, console.warn );

Source code

The source code for Record can be found in the browser inspector under Private methods are prefixed with underscores and should not be used.

Using Facades

Low level access to the fields in the Record class can be cumbersome. Facades provide a way to have business logic for a particular type of record.

const Activity = require('materia/facade/Activity');
const activity = record.get_facade(Activity);
activity.get_actors().then( console.log, console.warn );

Making Changes

Timespace has a robust system for making changes to records. Concurrent changes to different fields in the same record are automatically merged. A conflict is reported if a merge is not possible.

Warning! Records are versioned so that information is not lost, but if you make a change that removes your permissions to a record, you will be unable to undo your changes.

Creating a new version

You can't make changes to a record directly. Instead, create a local working copy.

record.create_new_version().then( function(working_copy) {
  working_copy.set_name( 'en', 'Scripted new name' ).then( function() { function() {
      // saved
    }, console.warn );
  }, console.warn );
}, console.warn );

You can make many changes to a working copy at the same time. Your changes are not saved until you call save().

Creating new records

You can create new records by copying existing records or record templates.

record.copy().then( function(working_copy) {
  // make changes, then function(new_record) {
    // An ID is assigned server-side on save
    console.log( new_record.get_numid() )
  }, console.warn );
}, console.warn );

While you can make a copy of any object you have access to, you may not be able to save it in the original cloud of the record. To overcome this, you can use:

record.copy_as_template(cloud_source).then( function(working_copy) ...

This will use the same clouds and languages as in the cloud_source record for the copy. This will also remove the special "Type template" type from the copy, used to designate a record as a template for other records.

When using a template as a basis for your copy, you can also use the simpler copy_as_template_lite method to create your copy, but then set the clouds and languages yourself, if necessary.

A complete example that creates an activity in your "Just me" user cloud and sets the actor as you, too.

// Init
const session = require('whitespace/browser/init-session');
const broker = session.get_broker();

// Deps
const TypeDefinition = require('materia/facade/TypeDefinition');
const Activity = require('materia/facade/Activity');
const activity_type = broker.get(Activity.TYPE_ID).get_facade(TypeDefinition);

activity_type.get_template().then( function(activity_template) {
  activity_template.copy_as_template_lite().then( function(working_copy) {
    working_copy.set_languages( ['en'] ); // Note: Not a Promise
    broker.get_user().then( function(my_user) {
      working_copy.set_clouds( [ my_user ] ).then( function() {
        working_copy.set_name( 'en', 'Scripting test' ).then( function() {
          const activity = working_copy.get_facade(Activity);
          activity.set_actors( [my_user] ).then( function() {
   function(new_record) {
              console.log( 'new activity' + new_record.get_numid() );
            }, console.warn );
          }, console.warn );
        }, console.warn );
      }, console.warn );
    }, console.warn );
  }, console.warn );
}, console.warn );

Adding records to the feed of another record

The feed shows records that reference the currently open record. Therefore to add a record A to the feed of record B, just set B as the value of any (object type) field in record A.

Example coming soon

Using Searches

Coming soon

Queuing Operations

Coming soon