Scripting

Introduction

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 support@timespace.co.

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: https://timespace.co/<ID>/...

const record = broker.get(362109944);

Reading Data

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

Examples:

await record.get_name();
await record.get_modification_date();

A cloud is also a Record:

const clouds = await record.get_clouds();
await clouds[0].get_name();

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 (also a Record):

await record.get_value( '#801708327', 'en' );

Autocompletion

Start typing e.g. record.get_ to see what getters are available. Methods that are considered private are prefixed with underscores.

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 record = broker.get(<activity-id-here>);
const activity = record.get_facade(Activity);
await activity.get_actors();

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.

const working_copy = await record.create_new_version();
await working_copy.set_name( 'en', 'Scripted new name' );
await working_copy.save();

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.

const working_copy = await record.copy();
// make changes, then
const new_record = await working_copy.save();
// An ID is assigned on save. Temporary local-only offline numerical IDs are negative, while globally unique server-side IDs are positive.
new_record.get_numid();

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:

const working_copy = await record.copy_as_template(cloud_source);

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 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);

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

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