SharedState

client. SharedState

The SharedState is one of the most important and versatile abstraction provided by soundworks. It represents a set of parameters that are synchronized accross every nodes of the application (clients and server) that declared some interest to the shared state.

A SharedState is created according to a "schema" (in the sense of a database schema) that must be declared and registered server-side. Any number of SharedStates can be created from a single schema.

A shared state can be created both by the clients or by the server (in which case it is generally considered as a global state of the application). Similarly any node of the application (clients or server) can declare interest and "attach" to a state created by another node. All node attached to a state can modify its values and/or react to the modifications applied by other nodes.

Tutorial: https://soundworks.dev/guide/state-manager.html

// server-side
import { Server } from '@soundworks/server/index.js';

const server = new Server(config);
// declare and register the schema of a shared state.
server.stateManager.registerSchema('some-global-state', {
  myRandom: {
    type: 'float',
    default: 0,
  }
});

await server.start();

// create a global state server-side
const globalState = await server.stateManager.create('some-global-state');
// listen and react to the changes made by the clients
globalState.onUpdate(updates => console.log(updates));
// client-side
import { Client } from '@soundworks/client.index.js';

const client = new Client(config);
await client.start();

// attach to the global state created by the server
const globalState = await client.stateManager.attach('some-global-state');

// update the value of a `myRandom` parameter every seconds
setInterval(() => {
  globalState.set({ myRandom: Math.random() });
}, 1000);

Extends

Members

(readonly) id :Number

Description:
  • Id of the state

Source:
Inherited From:

Id of the state

Type:
  • Number

(readonly) isOwner :Boolean

Description:
  • Indicates if the node is the owner of the state

Source:
Inherited From:

Indicates if the node is the owner of the state

Type:
  • Boolean

(readonly) schemaName :String

Description:
  • Name of the schema

Source:
Inherited From:

Name of the schema

Type:
  • String

Methods

(async) delete()

Description:
  • Delete the state. Only the creator/owner of the state can use this method.

    All nodes attached to the state will be detached, triggering any registered onDetach callbacks. The creator of the state will also have its own onDelete callback triggered. The local onDeatch and onDelete callbacks will be executed before the returned Promise resolves

Source:
Inherited From:
Example
const state = await client.state.create('my-schema-name');
// later
await state.delete();
Throws:

Throws if the method is called by a node which is not the owner of the state.

(async) detach()

Description:
  • Detach from the state. If the client is the creator of the state, the state is deleted and all attached nodes get notified.

Source:
Inherited From:
Example
const state = await client.state.attach('globals');
// later
await state.detach();

get(name) → {mixed}

Description:
  • Get the value of a parameter of the state. If the parameter is of any type, a deep copy is returned.

Source:
Inherited From:
Example
const value = state.get('paramName');
Parameters:
Name Type Description
name string

Name of the param.

Throws:

Throws if name does not correspond to an existing field of the state.

Returns:
Type
mixed

getDefaults() → {object}

Description:
  • Get the default values as declared in the schema.

Source:
Inherited From:
Example
const defaults = state.getDefaults();
Returns:
Type
object

getInitValues() → {object}

Description:
  • Get the values with which the state has been created. May defer from the default values declared in the schema.

Source:
Inherited From:
Example
const initValues = state.getInitValues();
Returns:
Type
object

getSchema(nameopt) → {object}

Description:
  • Definition of schema from which the state has been created.

Source:
Inherited From:
Example
const schema = state.getSchema();
Parameters:
Name Type Attributes Default Description
name string <optional>
null

If given, returns only the definition corresponding to the given param name.

Throws:

Throws if name does not correspond to an existing field of the schema.

Returns:
Type
object

getUnsafe(name) → {mixed}

Description:
  • Similar to get but returns a reference to the underlying value in case of any type. May be usefull if the underlying value is big (e.g. sensors recordings, etc.) and deep cloning expensive. Be aware that if changes are made on the returned object, the state of your application will become inconsistent.

Source:
Inherited From:
Example
const value = state.getUnsafe('paramName');
Parameters:
Name Type Description
name string

Name of the param.

Throws:

Throws if name does not correspond to an existing field of the state.

Returns:
Type
mixed

getValues() → {object}

Description:
  • Get all the key / value pairs of the state. If a parameter is of any type, a deep copy is made.

Source:
Inherited From:
Example
const values = state.getValues();
Returns:
Type
object

getValuesUnsafe() → {object}

Description:
  • Get all the key / value pairs of the state. If a parameter is of any type, a deep copy is made. Similar to getValues but returns a reference to the underlying value in case of any type. May be usefull if the underlying value is big (e.g. sensors recordings, etc.) and deep cloning expensive. Be aware that if changes are made on the returned object, the state of your application will become inconsistent.

Source:
Inherited From:
Example
const values = state.getValues();
Returns:
Type
object

onDelete(callback)

Description:
  • Register a function to execute when the state is deleted. Only called if the node was the creator of the state. Is called after onDetach and executed before the delete Promise resolves.

Source:
Inherited From:
Parameters:
Name Type Description
callback function

Callback to execute when the state is deleted.

onDetach(callback)

Description:
  • Register a function to execute when detaching from the state. The function will be executed before the detach promise resolves.

Source:
Inherited From:
Parameters:
Name Type Description
callback function

Callback to execute when detaching from the state. Whether the client as called detach, or the state has been deleted by its creator.

onUpdate(callback, executeListeneropt) → {client.SharedState~deleteOnUpdateCallback|server.SharedState~deleteOnUpdateCallback}

Description:
  • Subscribe to state updates.

Source:
Inherited From:
Example
const unsubscribe = state.onUpdate(async (newValues, oldValues, context) =>  {
  for (let [key, value] of Object.entries(newValues)) {
     switch (key) {
       // do something
     }
  }
});

// later
unsubscribe();
Parameters:
Name Type Attributes Default Description
callback client.SharedState~onUpdateCallback | server.SharedState~onUpdateCallback

Callback to execute when an update is applied on the state.

executeListener Boolean <optional>
false

Execute the callback immediately with current state values. (oldValues will be set to {}, and context to null)

Returns:
Type
client.SharedState~deleteOnUpdateCallback | server.SharedState~deleteOnUpdateCallback

(async) set(updates, contextopt) → {Promise.<Object>}

Description:
  • Update values of the state.

    The returned Promise resolves on the applied updates, when all the onUpdate callbacks have resolved themselves, i.e.:

    server.stateManager.registerSchema('test', {
      myBool: { type: 'boolean', default: false },
    });
    const a = await server.stateManager.create('a');
    let asyncCallbackCalled = false;
    
    a.onUpdate(updates => {
      return new Promise(resolve => {
        setTimeout(() => {
          asyncCallbackCalled = true;
          resolve();
        }, 100);
      });
    });
    
    const updates = await a.set({ myBool: true });
    assert.equal(asyncCallbackCalled, true);
    assert.deepEqual(updates, { myBool: true });
    
Source:
Inherited From:
Example
const state = await client.state.attach('globals');
const updates = await state.set({ myParam: Math.random() });
Parameters:
Name Type Attributes Default Description
updates object

key / value pairs of updates to apply to the state.

context mixed <optional>
null

optionnal contextual object that will be propagated alongside the updates of the state. The context is valid only for the current call and will be passed as third argument to all update listeners.

Returns:

A promise to the (coerced) updates.

Type
Promise.<Object>

Type Definitions

deleteOnUpdateCallback()

Description:
Source:

onUpdateCallback(newValues, oldValues, contextopt)

Source:
Parameters:
Name Type Attributes Default Description
newValues Object

Key / value pairs of the updates that have been applied to the state.

oldValues Object

Key / value pairs of the updated params before the updates has been applied to the state.

context Mixed <optional>
null

Optionnal context object that has been passed with the values updates in the set call.