Neurotic Programmer Masquerade


    0.0.0-alpha.0 • Public • Published


    Library dedicated at maintaining state(s) synchronized accross nodes of a network. The library doesn't implement any transport method, however it should work out of the box with popular socket libraries that implement an EventEmitter API (e.g., or a simple EventEmitter interface
    on top of WebSocket)


    npm install @ircam/shared-state --save


    import { Server } from '@ircam/shared-state';
    const server = new Server();
    server.registerSchema('my-schema', {
      myInteger: {
        type: 'integer',
        default: 0,
      // ....
    // `clientId` - unique id of a client
    // `transport` - some transport (WebSocket, EventEmitter) implementing a basic
    // event API (i.e. `emit`, `addListener`, `removeAllListeners`)
    server.addClient(clientId, transport);
    const state = await server.create(`my-schema`);
    await state.set({ myInterger: 2 })
    // > { myInteger: 2 }
    import { Client } from '@ircam/shared-state';
    const client = new Client(nodeId, transport);
    const state = await client.attach('my-schema');
    state.subscribe(updates => {
      // > updates = { myInteger: 2 }


    StateManager API

    stateManager.create(schemaName, synced = true) => Promise(State)

    Create a synced my-state state where owner is the server and creator is the client

    const state = await stateManager.create('my-schema');

    Create a local my-state state where owner and creator are owner @important - the state is purely local then no other node can attach to it

    const state = await stateManager.create('my-schema', false);

    stateManager.attach(schemaName, nodeId = SERVER_ID) => Promise(State)

    Attach to a state created by another client

    const state = await stateManager.attach('my-schema', clientId);

    client-side only: attach to a state created by the server

    const state = await stateManager.attach('my-schema');

    stateManager.observe(listener: Function) => void

    Observe the creation of new states, the callback is called a first time with a list of all already created states, and then each time a new state is created.

    // @note - unroll first set in the stateManager itself
    stateManager.observe((schemaName, nodeId) => {
        // the node is interested in 'whatever' schemaName
        if (schemaName === 'whatever') {
          const state = await stateManager.attach(schemaName, nodeId);
          // do things with `state`

    Client Only API

    StateManager API


    Server Only API

    @note: by convention the server nodeId is -1


    stateManager.registerSchema(schemaName, definitions);

    stateManager.addClient(nodeId, transport);


    State API

    A state cannot be instanciated manually, its always created using the StateManager factory methods create or attach.

    state.getSchema() => Object

    Returns the schema of the state as registered in the server.

    const schema = state.getSchema();

    async state.set(updates: Object) => Promise(newValues)

    Update state with new values. Given values may be ignored or sanitized according to the definition of the parameter.

    // given the schema
    //  {
    //    myInt: {
    //      type: 'integer',
    //      min: 0,
    //      max: 10,
    //    }
    //  }
    const updated = await state.set({ myInt: -4 })
    // updated.myInt === 0

    state.get(name: String) => Mixed

    Return the current value of the name state entry.

    state.getValues() => Object

    Return the current values of the state as flat <key, value> object

    state.subscribe(listener: Function) => Function

    Subscribe to modifications of the state. Return a function that allow to unsubscribe the listener.

    const unsubscribe = state.subscribe(updates => {
      for (let key in updates) {
        switch (key) {
          // ...
    // ...later

    state.detach() => Promise

    Detach from the state:

    • If the node is the creator of the state, then the state is destroyed and all other attached nodes will be detached.
    • If the node is not the creator of the state, the node stops receiving new updates about the state.

    Calling detach immediatly removes all listeners subscribed to the state, then requests the server (owner of the state) for detaching. Calls the onDetach listeners when acknoledgement is received from the server.


    state.onDetach(callback: Function) => void

    state.onDetach(() => {
      // clean everything related to the state






    npm i @ircam/shared-state

    DownloadsWeekly Downloads






    Unpacked Size

    39.2 kB

    Total Files


    Last publish


    • jipodine
    • norbert.schnell
    • b-ma