diff --git a/src/client/ClientPluginManager.js b/src/client/ClientPluginManager.js index e586b915..932cadfb 100644 --- a/src/client/ClientPluginManager.js +++ b/src/client/ClientPluginManager.js @@ -99,7 +99,11 @@ class ClientPluginManager extends BasePluginManager { const ctor = factory(ClientPlugin); if (!(ctor.prototype instanceof ClientPlugin)) { - throw new Error(`[soundworks.ClientPluginManager] Invalid argument, "pluginManager.register" second argument should be a factory function returning a class extending the "Plugin" base class`); + throw new Error(`[ClientPluginManager] Invalid argument, "pluginManager.register" second argument should be a factory function returning a class extending the "Plugin" base class`); + } + + if (ctor.target === undefined || ctor.target !== 'client') { + throw new Error(`[ClientPluginManager] Invalid argument, The plugin class should implement a 'target' static field with value 'client'`); } super.register(id, ctor, options, deps); diff --git a/src/server/ServerPluginManager.js b/src/server/ServerPluginManager.js index dae6f281..a2afc7cc 100644 --- a/src/server/ServerPluginManager.js +++ b/src/server/ServerPluginManager.js @@ -141,7 +141,11 @@ class ServerPluginManager extends BasePluginManager { const ctor = factory(ServerPlugin); if (!(ctor.prototype instanceof ServerPlugin)) { - throw new Error(`[soundworks.PluginManager] Invalid argument, "pluginManager.register" second argument should be a factory function returning a class extending the "ServerPlugin" base class`); + throw new Error(`[ServerPluginManager] Invalid argument, "pluginManager.register" second argument should be a factory function returning a class extending the "ServerPlugin" base class`); + } + + if (ctor.target === undefined || ctor.target !== 'server') { + throw new Error(`[ServerPluginManager] Invalid argument, The plugin class should implement a 'target' static field with value 'server'`) } super.register(id, ctor, options, deps); diff --git a/src/server/ServerStateManager.js b/src/server/ServerStateManager.js index 978f4daf..450f3e89 100644 --- a/src/server/ServerStateManager.js +++ b/src/server/ServerStateManager.js @@ -154,7 +154,7 @@ class ServerStateManager extends BaseStateManager { /** @private */ async [kServerStateManagerDeletePrivateState](state) { this.#sharedStatePrivateById.delete(state.id); - // execute hooks + // @todo - could use getValuesUnsafe instead let currentValues = state[kSharedStatePrivateGetValues](); const hooks = this.#deleteHooksByClassName.get(state.className); @@ -186,8 +186,7 @@ class ServerStateManager extends BaseStateManager { * * This is automatically handled by the {@link Server} when a client connects. * - * @param {number} nodeId - Id of the client node, as given in - * {@link client.StateManager} + * @param {number} nodeId - Unique id of the client node * @param {object} transport - Transport mecanism to communicate with the * client. Must implement a basic EventEmitter API. * diff --git a/tests/essentials/Client.spec.js b/tests/essentials/Client.spec.js index ff6c3919..76894ae1 100644 --- a/tests/essentials/Client.spec.js +++ b/tests/essentials/Client.spec.js @@ -11,7 +11,7 @@ import { import pluginDelayClient from '../utils/PluginDelayClient.js'; import config from '../utils/config.js'; -describe('# client::Client', () => { +describe('# Client', () => { describe(`## new Client(config)`, () => { it(`should throw if no config is given`, () => { try { @@ -276,7 +276,9 @@ describe('# client::Client', () => { it(`should stop the contexts first and then the plugins`, async () => { const server = new Server(config); server.pluginManager.register('test-plugin', Plugin => { - return class TestPlugin extends Plugin {} + return class TestPlugin extends Plugin { + static target = 'server'; + } }); await server.init(); @@ -297,6 +299,7 @@ describe('# client::Client', () => { client.pluginManager.register('test-plugin', Plugin => { return class TestPlugin extends Plugin { + static target = 'client'; async start() { await super.start(); // just check that we are ok with that, and that we are not stuck diff --git a/tests/essentials/Server.spec.js b/tests/essentials/Server.spec.js index e91852d6..b772b67b 100644 --- a/tests/essentials/Server.spec.js +++ b/tests/essentials/Server.spec.js @@ -21,7 +21,7 @@ import config from '../utils/config.js'; const __filename = url.fileURLToPath(import.meta.url); const __dirname = url.fileURLToPath(new URL('.', import.meta.url)); -describe('# server::Server', () => { +describe('# Server', () => { describe(`## new Server(config)`, () => { it(`should throw if invalid config object`, () => { @@ -445,6 +445,8 @@ describe('# server::Server', () => { const server = new Server(config); server.pluginManager.register('test-plugin', Plugin => { return class TestPlugin extends Plugin { + static target = 'server'; + async start() { await super.start(); // just check that we are ok with that, and that we are not stuck diff --git a/tests/plugins/ClientPluginManager.spec.js b/tests/plugins/ClientPluginManager.spec.js index 71556742..61f34573 100644 --- a/tests/plugins/ClientPluginManager.spec.js +++ b/tests/plugins/ClientPluginManager.spec.js @@ -136,12 +136,11 @@ describe(`# PluginManagerClient`, () => { assert.ok('should not throw'); }); - it.skip(`[FIXME #83] should throw when registering server side plugin on client side`, async () => { - client.pluginManager.register('delay-1', pluginDelayServer, {}); - + it(`should throw when registering server side plugin on client side`, async () => { let errored = false; + try { - await client.init(); + client.pluginManager.register('delay-1', pluginDelayServer, {}); } catch (err) { console.log(err.message); errored = true; diff --git a/tests/plugins/Plugin.spec.js b/tests/plugins/Plugin.spec.js index c0f70f26..d80ae042 100644 --- a/tests/plugins/Plugin.spec.js +++ b/tests/plugins/Plugin.spec.js @@ -60,13 +60,13 @@ describe('# Plugin', () => { describe(`## [client] Plugin.state propagation`, () => { it(`should propagate its inner state`, async () => { const server = new Server(config); - server.pluginManager.register('stateful', (ServerPlugin) => class StatefulPlugin extends ServerPlugin {}); + server.pluginManager.register('stateful', (ServerPlugin) => class StatefulPlugin extends ServerPlugin { static target = 'server' }); await server.init(); await server.start(); const client = new Client({ role: 'test', ...config }); - client.pluginManager.register('stateful', (ClientPlugin) => class StatefulPlugin extends ClientPlugin {}); + client.pluginManager.register('stateful', (ClientPlugin) => class StatefulPlugin extends ClientPlugin { static target = 'client' }); await client.init(); const plugin = await client.pluginManager.get('stateful'); @@ -91,7 +91,9 @@ describe('# Plugin', () => { it(`should be forwarded by the stateManager`, async () => { const server = new Server(config); server.pluginManager.register('stateful', (Plugin) => { - return class StatefulPlugin extends Plugin {} + return class StatefulPlugin extends Plugin { + static target = 'server'; + } }); await server.init(); @@ -102,6 +104,8 @@ describe('# Plugin', () => { client.pluginManager.register('stateful', (Plugin) => { return class StatefulPlugin extends Plugin { + static target = 'client'; + constructor(client, id) { super(client, id); this.state = { rand: 0 }; @@ -141,6 +145,8 @@ describe('# Plugin', () => { server.pluginManager.register('dependent', (Plugin) => { return class Dependant extends Plugin { + static target = 'server'; + constructor(server, id) { super(server, id); @@ -177,6 +183,8 @@ describe('# Plugin', () => { client.pluginManager.register('dependent', (Plugin) => { return class Dependant extends Plugin { + static target = 'client'; + constructor(client, id) { super(client, id); @@ -215,8 +223,10 @@ describe('# Plugin', () => { describe(`## [server] Plugin.state propagation`, () => { it('PluginManager should properly propagate plugin state', async () => { const server = new Server(config); - server.pluginManager.register('stateful', (ClientPlugin) => { - return class StatefulPlugin extends ClientPlugin { + server.pluginManager.register('stateful', (Plugin) => { + return class StatefulPlugin extends Plugin { + static target = 'server'; + constructor(client, id) { super(client, id); this.state = { rand: 0 }; diff --git a/tests/plugins/ServerPluginManager.spec.js b/tests/plugins/ServerPluginManager.spec.js index d4328be4..85950e99 100644 --- a/tests/plugins/ServerPluginManager.spec.js +++ b/tests/plugins/ServerPluginManager.spec.js @@ -5,6 +5,7 @@ import { Client } from '../../src/client/index.js'; import ServerPluginManager from '../../src/server/ServerPluginManager.js'; import ServerPlugin from '../../src/server/ServerPlugin.js'; import pluginDelayServer from '../utils/PluginDelayServer.js'; +import pluginDelayClient from '../utils/PluginDelayClient.js'; import config from '../utils/config.js'; import { kStateManagerClientsByNodeId, @@ -121,6 +122,21 @@ describe(`# ServerPluginManager`, () => { assert.ok('should not throw'); }); + + it(`should throw when registering client side plugin on server side`, async () => { + let errored = false; + + try { + server.pluginManager.register('delay-1', pluginDelayClient, {}); + } catch (err) { + console.log(err.message); + errored = true; + } + + if (!errored) { + assert.fail(`should have thrown`); + } + }); }); describe(`## [private] async init()`, () => { @@ -297,6 +313,8 @@ describe(`# ServerPluginManager`, () => { function testPluginFactory(Plugin) { return class TestPlugin extends Plugin { + static target = 'server'; + async addClient(client) { await super.addClient(client); addClientCalled = true; @@ -311,7 +329,7 @@ describe(`# ServerPluginManager`, () => { const plugin = await server.pluginManager.get('test-plugin'); const client = new Client({ role: 'test', ...config }); - client.pluginManager.register('test-plugin', (Plugin) => class TestPlugin extends Plugin {}); + client.pluginManager.register('test-plugin', (Plugin) => class TestPlugin extends Plugin { static target = 'client' }); await client.init(); assert.equal(plugin.clients.size, 1); @@ -325,6 +343,8 @@ describe(`# ServerPluginManager`, () => { function testPluginFactory(Plugin) { return class TestPlugin extends Plugin { + static target = 'server'; + async addClient(client) { await super.addClient(client); assert.equal(this.clients.has(client), true); @@ -337,6 +357,8 @@ describe(`# ServerPluginManager`, () => { function testPluginFactory2(Plugin) { return class TestPlugin extends Plugin { + static target = 'server'; + async addClient(client) { await super.addClient(client); addClientCalled2 = true; @@ -351,7 +373,7 @@ describe(`# ServerPluginManager`, () => { await server.start(); const client = new Client({ role: 'test', ...config }); - client.pluginManager.register('test-plugin', (Plugin) => class TestPlugin extends Plugin {}); + client.pluginManager.register('test-plugin', (Plugin) => class TestPlugin extends Plugin { static target = 'client' }); await client.init(); await client.start(); @@ -368,6 +390,8 @@ describe(`# ServerPluginManager`, () => { function testPluginFactory(Plugin) { return class TestPlugin extends Plugin { + static target = 'server'; + async removeClient(client) { await super.removeClient(client); removeClientCalled = true; @@ -381,7 +405,7 @@ describe(`# ServerPluginManager`, () => { await server.start(); const client = new Client({ role: 'test', ...config }); - client.pluginManager.register('test-plugin', (Plugin) => class TestPlugin extends Plugin {}); + client.pluginManager.register('test-plugin', (Plugin) => class TestPlugin extends Plugin { static target = 'client' }); await client.init(); await client.start(); @@ -399,6 +423,8 @@ describe(`# ServerPluginManager`, () => { function testPluginFactory(Plugin) { return class TestPlugin extends Plugin { + static target = 'server'; + async removeClient(client) { await super.removeClient(client); @@ -415,7 +441,7 @@ describe(`# ServerPluginManager`, () => { await server.start(); const client = new Client({ role: 'test', ...config }); - client.pluginManager.register('test-plugin', (Plugin) => class TestPlugin extends Plugin {}); + client.pluginManager.register('test-plugin', (Plugin) => class TestPlugin extends Plugin { static target = 'client' }); await client.init(); await client.start(); @@ -432,6 +458,8 @@ describe(`# ServerPluginManager`, () => { function testPluginFactory(Plugin) { return class TestPlugin extends Plugin { + static target = 'server'; + async removeClient(client) { await super.removeClient(client); removeClientCalled = true; @@ -443,6 +471,8 @@ describe(`# ServerPluginManager`, () => { function testPluginFactory2(Plugin) { return class TestPlugin extends Plugin { + static target = 'server'; + async removeClient(client) { await super.removeClient(client); removeClientCalled2 = true; @@ -457,7 +487,7 @@ describe(`# ServerPluginManager`, () => { await server.start(); const client = new Client({ role: 'test', ...config }); - client.pluginManager.register('test-plugin', (Plugin) => class TestPlugin extends Plugin {}); + client.pluginManager.register('test-plugin', (Plugin) => class TestPlugin extends Plugin { static target = 'client' }); await client.init(); await client.start(); await client.stop(); diff --git a/tests/utils/PluginDelayClient.js b/tests/utils/PluginDelayClient.js index 8f11d3d5..51f86008 100644 --- a/tests/utils/PluginDelayClient.js +++ b/tests/utils/PluginDelayClient.js @@ -1,5 +1,7 @@ export default function(Plugin) { return class PluginDelayClient extends Plugin { + static target = 'client'; + constructor(client, id, options) { super(client, id); diff --git a/tests/utils/PluginDelayServer.js b/tests/utils/PluginDelayServer.js index d16babaa..aea243c6 100644 --- a/tests/utils/PluginDelayServer.js +++ b/tests/utils/PluginDelayServer.js @@ -1,5 +1,7 @@ export default function(Plugin) { return class PluginDelayServer extends Plugin { + static target = 'server'; + constructor(server, id, options) { super(server, id); diff --git a/types/common/BasePlugin.d.ts b/types/common/BasePlugin.d.ts index 05c6f782..0007ece8 100644 --- a/types/common/BasePlugin.d.ts +++ b/types/common/BasePlugin.d.ts @@ -5,7 +5,7 @@ export default BasePlugin; */ export type pluginOnStateChangeCallback = (#state: BasePlugin) => any; /** - * Delete the registered {@link pluginOnStateChangeCallback }. + * Delete the registered {@link pluginOnStateChangeCallback}. */ export type pluginDeleteOnStateChangeCallback = () => any; /** diff --git a/types/common/BasePluginManager.d.ts b/types/common/BasePluginManager.d.ts index a1c220c8..66b6c2c6 100644 --- a/types/common/BasePluginManager.d.ts +++ b/types/common/BasePluginManager.d.ts @@ -7,7 +7,7 @@ export default BasePluginManager; */ export type pluginManagerOnStateChangeCallback = (: object, initiator: ClientPlugin | ServerPlugin | null) => any; /** - * Delete the registered {@link pluginManagerOnStateChangeCallback }. + * Delete the registered {@link pluginManagerOnStateChangeCallback}. */ export type pluginManagerDeleteOnStateChangeCallback = () => any; /** diff --git a/types/common/BaseStateManager.d.ts b/types/common/BaseStateManager.d.ts index 52ce112c..9ea1143c 100644 --- a/types/common/BaseStateManager.d.ts +++ b/types/common/BaseStateManager.d.ts @@ -7,7 +7,7 @@ export default BaseStateManager; */ export type stateManagerObserveCallback = () => any; /** - * Callback to execute in order to remove a {@link stateManagerObserveCallback } + * Callback to execute in order to remove a {@link stateManagerObserveCallback} * from the list of observer. */ export type stateManagerDeleteObserveCallback = () => any; diff --git a/types/common/SharedState.d.ts b/types/common/SharedState.d.ts index 802c3a83..6f5585bf 100644 --- a/types/common/SharedState.d.ts +++ b/types/common/SharedState.d.ts @@ -1,11 +1,11 @@ export const kSharedStatePromiseStore: unique symbol; export default SharedState; /** - * Callback executed when updates are applied on a {@link SharedState }. + * Callback executed when updates are applied on a {@link SharedState}. */ export type sharedStateOnUpdateCallback = (newValues: any, oldValues: any) => any; /** - * Delete the registered {@link sharedStateOnUpdateCallback }. + * Delete the registered {@link sharedStateOnUpdateCallback}. */ export type sharedStateDeleteOnUpdateCallback = () => any; /** @@ -79,7 +79,16 @@ export type sharedStateDeleteOnUpdateCallback = () => any; * ``` */ declare class SharedState { - constructor(id: any, remoteId: any, className: any, classDescription: any, client: any, isOwner: any, manager: any, initValues: any, filter: any); + constructor({ stateId, instanceId, className, classDescription, isOwner, manager, initValues, filter, }: { + stateId: any; + instanceId: any; + className: any; + classDescription: any; + isOwner: any; + manager: any; + initValues: any; + filter: any; + }); /** * Id of the state * @type {Number} diff --git a/types/common/SharedStateCollection.d.ts b/types/common/SharedStateCollection.d.ts index 8915fb26..a1c0c0c9 100644 --- a/types/common/SharedStateCollection.d.ts +++ b/types/common/SharedStateCollection.d.ts @@ -1,7 +1,7 @@ export default SharedStateCollection; export type sharedStateCollectionOnUpdateCallback = (state: SharedState, newValues: any, oldValues: any) => any; /** - * Delete the registered {@link sharedStateCollectionOnUpdateCallback }. + * Delete the registered {@link sharedStateCollectionOnUpdateCallback}. */ export type sharedStateCollectionDeleteOnUpdateCallback = () => any; /** @@ -56,7 +56,7 @@ declare class SharedStateCollection { */ get className(): string; /** - * @deprecated Use ${@link SharedStateCollection#className} instead. + * @deprecated Use {@link SharedStateCollection#className} instead. */ get schemaName(): string; /** diff --git a/types/common/shared-state-types.d.ts b/types/common/shared-state-types.d.ts index 558c2d44..f3ef9abd 100644 --- a/types/common/shared-state-types.d.ts +++ b/types/common/shared-state-types.d.ts @@ -1,10 +1,10 @@ /** - * User defined name for a class of {@link SharedState } + * User defined name for a class of {@link SharedState} */ type SharedStateClassName = string; /** - * Description of a {@link SharedState } data structure that describes the structure - * of a class of {@link SharedState } to be registered by {@link ServerStateManagerdefineClass } + * Description of a {@link SharedState} data structure that describes the structure + * of a class of {@link SharedState} to be registered by {@link ServerStateManager#defineClass} * * A `SharedStateClassDescription` is the blueprint, or the definition from which * shared states from a given class can be created. @@ -15,17 +15,17 @@ type SharedStateClassName = string; */ type SharedStateClassDescription = any; /** - * User defined name of a parameter in a class of {@link SharedState } + * User defined name of a parameter in a class of {@link SharedState} */ type SharedStateParameterName = string; /** - * Description of a parameter in a class of {@link SharedState } + * Description of a parameter in a class of {@link SharedState} */ type SharedStateParameterDescription = { /** - * - Type of the parameter + * - Type of the parameter. */ - type: 'boolean' | 'string' | 'integer' | 'float' | 'enum' | 'any'; + type: "boolean" | "string" | "integer" | "float" | "enum" | "any"; /** * - Default value of the parameter. Optional only if * `nullable = true` or `event = true` @@ -61,6 +61,11 @@ type SharedStateParameterDescription = { * the listeners will be called again when the "real" value is received. */ immediate?: boolean; + /** + * - When set to true, the parameter must be + * provided in the initialization values when the state is created. + */ + required?: boolean; /** * - When set to true, the parameter is never * propagated on the network (hence it is no longer a shared parameter :). This diff --git a/types/server/ServerStateManager.d.ts b/types/server/ServerStateManager.d.ts index 35d7a427..50d92932 100644 --- a/types/server/ServerStateManager.d.ts +++ b/types/server/ServerStateManager.d.ts @@ -1,22 +1,36 @@ export const kServerStateManagerAddClient: unique symbol; export const kServerStateManagerRemoveClient: unique symbol; +export const kServerStateManagerHasClient: unique symbol; export const kServerStateManagerDeletePrivateState: unique symbol; -export const kServerStateManagerGetHooks: unique symbol; +export const kServerStateManagerGetUpdateHooks: unique symbol; export const kStateManagerClientsByNodeId: unique symbol; export default ServerStateManager; +export type serverStateManagerCreateHook = () => any; export type serverStateManagerUpdateHook = () => any; +export type serverStateManagerDeleteHook = () => any; +/** + * @callback serverStateManagerCreateHook + * @async + * + * @param {object} initValues - Initialization values object as given when the + * shared state is created + */ /** * @callback serverStateManagerUpdateHook * @async * - * @param {object} updates - Update object as given on a set callback, or - * result of the previous hook + * @param {object} updates - Update object as given on a `set` callback, or + * result of the previous hook. * @param {object} currentValues - Current values of the state. - * @param {object} [context=null] - Optionnal context passed by the creator - * of the update. - * * @returns {object} The "real" updates to be applied on the state. */ +/** + * @callback serverStateManagerDeleteHook + * @async + * + * @param {object} currentValues - Update object as given on a `set` callback, or + * result of the previous hook. + */ /** * The `StateManager` allows to create new {@link SharedState}s, or attach * to {@link SharedState}s created by other nodes (clients or server). It @@ -117,30 +131,98 @@ declare class ServerStateManager extends BaseStateManager { */ deleteSchema(className: any): void; /** - * Register a function for a given shared state class the be executed between + * Register a function for a given class of shared state class to be executed + * when a state is created. + * + * For example, this can be usefull to retrieve some initialization values stored + * in the filesystem, given the value (e.g. a hostname) of one the parameters. + * + * The hook is associated to each states created from the given class name. + * Note that the hooks are executed server-side regarless the node on which + * `create` has been called. + * + * @param {string} className - Kind of states on which applying the hook. + * @param {serverStateManagerUpdateHook} createHook - Function called on when + * a state of `className` is created on the network. + * + * @returns {function} deleteHook - Handler that deletes the hook when executed. + * + * @example + * server.stateManager.defineClass('hooked', { + * name: { type: 'string', required: true }, + * hookTriggered: { type: 'boolean', default: false }, + * }); + * server.stateManager.onCreateHook('hooked', initValues => { + * return { + * ...initValues + * hookTriggered: true, + * }; + * }); + * + * const state = await server.stateManager.create('hooked', { + * name: 'coucou', + * }); + * + * const values = state.getValues(); + * assert.deepEqual(result, { value: 'coucou', hookTriggered: true }); + */ + onCreateHook(className: string, createHook: serverStateManagerUpdateHook): Function; + /** + * Register a function for a given class of shared state class to be executed + * when a state is deleted. + * + * For example, this can be usefull to store the values of a given shared state + * in the filesystem. + * + * The hook is associated to each states created from the given class name. + * Note that the hooks are executed server-side regarless the node on which + * `delete` has been called. + * + * @param {string} className - Kind of states on which applying the hook. + * @param {serverStateManagerUpdateHook} createHook - Function called on when + * a state of `className` is created on the network. + * + * @returns {function} deleteHook - Handler that deletes the hook when executed. + * + * @example + * server.stateManager.defineClass('hooked', { + * name: { type: 'string', required: true }, + * hookTriggered: { type: 'boolean', default: false }, + * }); + * server.stateManager.onDeleteHook('hooked', async currentValues => { + * await doSomethingWithValues(currentValues) + * }); + * + * const state = await server.stateManager.create('hooked'); + * // later + * await state.delete(); + */ + onDeleteHook(className: string, deleteHook: any): Function; + /** + * Register a function for a given class of shared state to be executed between * `set` instructions and `onUpdate` callback(s). * - * For example, this could be used to implement a preset system - * where all the values of the state are updated from e.g. some data stored in - * filesystem while the consumer of the state only want to update the preset name. + * For example, this can be used to implement a preset system where all the values + * of the state are updated from e.g. some data stored in filesystem while the + * consumer of the state only want to update the preset name. * - * The hook is associated to each states created from the given class name + * The hook is associated to each states created from the given class name and * executed on each update (i.e. `state.set(updates)`). Note that the hooks are * executed server-side regarless the node on which `set` has been called and * before the call of the `onUpdate` callback of the shared state. * * @param {string} className - Kind of states on which applying the hook. - * @param {serverStateManagerUpdateHook} updateHook - Function called between - * the `set` call and the actual update. + * @param {serverStateManagerUpdateHook} updateHook - Function called on each update, + * to eventually modify the updates before they are actually applied. * - * @returns {Fuction} deleteHook - Handler that deletes the hook when executed. + * @returns {function} deleteHook - Handler that deletes the hook when executed. * * @example * server.stateManager.defineClass('hooked', { * value: { type: 'string', default: null, nullable: true }, * numUpdates: { type: 'integer', default: 0 }, * }); - * server.stateManager.registerUpdateHook('hooked', updates => { + * server.stateManager.onUpdateHook('hooked', updates => { * return { * ...updates * numUpdates: currentValues.numUpdates + 1, @@ -153,13 +235,19 @@ declare class ServerStateManager extends BaseStateManager { * const values = state.getValues(); * assert.deepEqual(result, { value: 'test', numUpdates: 1 }); */ - registerUpdateHook(className: string, updateHook: serverStateManagerUpdateHook): Fuction; + onUpdateHook(className: string, updateHook: serverStateManagerUpdateHook): Function; + /** + * @deprecated Use {@link ServerStateManager#onUpdateHook} instead. + */ + registerUpdateHook(className: any, updateHook: any): Function; /** @private */ private [kStateManagerInit]; /** @private */ private [kServerStateManagerDeletePrivateState]; /** @private */ - private [kServerStateManagerGetHooks]; + private [kServerStateManagerGetUpdateHooks]; + /** @private */ + private [kServerStateManagerHasClient]; /** * Add a client to the manager. * diff --git a/types/server/SharedStatePrivate.d.ts b/types/server/SharedStatePrivate.d.ts index e76ec1b3..7efe1230 100644 --- a/types/server/SharedStatePrivate.d.ts +++ b/types/server/SharedStatePrivate.d.ts @@ -1,5 +1,6 @@ export const kSharedStatePrivateAttachClient: unique symbol; export const kSharedStatePrivateDetachClient: unique symbol; +export const kSharedStatePrivateGetValues: unique symbol; export default SharedStatePrivate; /** * The "real" state, this instance is kept private by the server.StateManager. @@ -8,14 +9,15 @@ export default SharedStatePrivate; * @private */ declare class SharedStatePrivate { - constructor(id: any, className: any, classDefinition: any, manager: any, initValues?: {}); + constructor(manager: any, className: any, classDefinition: any, id: any, initValues?: {}); get id(): any; get className(): any; get creatorId(): any; - get creatorRemoteId(): any; + get creatorInstanceId(): any; get attachedClients(): Map; get parameters(): any; - [kSharedStatePrivateAttachClient](remoteId: any, client: any, isOwner: any, filter: any): void; - [kSharedStatePrivateDetachClient](remoteId: any, client: any): void; + [kSharedStatePrivateGetValues](): any; + [kSharedStatePrivateAttachClient](instanceId: any, client: any, isOwner: any, filter: any): void; + [kSharedStatePrivateDetachClient](instanceId: any, client: any): void; #private; }