@ircam/shared-state v0.0.0-alpha.0
shared-state
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
EventEmitterAPI (e.g.socket.io, or a simpleEventEmitterinterface
on top ofWebSocket)
Installation
npm install @ircam/shared-state --saveUsage
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 })
state.getValues();
// > { 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 }
});API
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
StateManager.constructor(client);
Server Only API
@note: by convention the server nodeId is -1
StateManager.constructor();
stateManager.registerSchema(schemaName, definitions);
stateManager.addClient(nodeId, transport);
stateManager.removeClient(nodeId)
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 === 0state.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) {
// ...
}
}
doSomethingWithAll(state.getValues());
});
// ...later
unsubscribe();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.detach();state.onDetach(callback: Function) => void
state.onDetach(() => {
// clean everything related to the state
});License
BSD-3-Clause
6 years ago