Skip to content

Commit

Permalink
refactor(breaking): rename register[Create|Update|Delete]Hook to `s…
Browse files Browse the repository at this point in the history
…et[Create|Update|Delete]Hook`
  • Loading branch information
b-ma committed Oct 9, 2024
1 parent 45a160c commit 87b21c2
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 65 deletions.
62 changes: 50 additions & 12 deletions src/server/ServerStateManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ class ServerStateManager extends BaseStateManager {
this.deleteClass(className);
}

/**
/**
* Register a function for a given class of shared state class to be executed
* when a state is created.
*
Expand All @@ -564,7 +564,7 @@ class ServerStateManager extends BaseStateManager {
* name: { type: 'string', required: true },
* hookTriggered: { type: 'boolean', default: false },
* });
* server.stateManager.registerCreateHook('hooked', initValues => {
* server.stateManager.setCreateHook('hooked', initValues => {
* return {
* ...initValues
* hookTriggered: true,
Expand All @@ -578,13 +578,13 @@ class ServerStateManager extends BaseStateManager {
* const values = state.getValues();
* assert.deepEqual(result, { value: 'coucou', hookTriggered: true });
*/
registerCreateHook(className, createHook) {
setCreateHook(className, createHook) {
if (!this.#classes.has(className)) {
throw new TypeError(`Cannot execute 'registerCreateHook' on 'BaseStateManager': SharedState class '${className}' does not exists`);
throw new TypeError(`Cannot execute 'setCreateHook' on 'BaseStateManager': SharedState class '${className}' does not exists`);
}

if (!isFunction(createHook)) {
throw new TypeError(`Cannot execute 'registerCreateHook' on 'BaseStateManager': argument 2 must be a function`);
throw new TypeError(`Cannot execute 'setCreateHook' on 'BaseStateManager': argument 2 must be a function`);
}

const hooks = this.#createHooksByClassName.get(className);
Expand All @@ -593,13 +593,43 @@ class ServerStateManager extends BaseStateManager {
return () => hooks.delete(createHook);
}

registerDeleteHook(className, deleteHook) {
/**
* 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.setDeleteHook('hooked', async currentValues => {
* await doSomethingWithValues(currentValues)
* });
*
* const state = await server.stateManager.create('hooked');
* // later
* await state.delete();
*/
setDeleteHook(className, deleteHook) {
if (!this.#classes.has(className)) {
throw new TypeError(`Cannot execute 'registerDeleteHook' on 'BaseStateManager': SharedState class '${className}' does not exists`);
throw new TypeError(`Cannot execute 'setDeleteHook' on 'BaseStateManager': SharedState class '${className}' does not exists`);
}

if (!isFunction(deleteHook)) {
throw new TypeError(`Cannot execute 'registerDeleteHook' on 'BaseStateManager': argument 2 must be a function`);
throw new TypeError(`Cannot execute 'setDeleteHook' on 'BaseStateManager': argument 2 must be a function`);
}

const hooks = this.#deleteHooksByClassName.get(className);
Expand Down Expand Up @@ -632,7 +662,7 @@ class ServerStateManager extends BaseStateManager {
* value: { type: 'string', default: null, nullable: true },
* numUpdates: { type: 'integer', default: 0 },
* });
* server.stateManager.registerUpdateHook('hooked', updates => {
* server.stateManager.setUpdateHook('hooked', updates => {
* return {
* ...updates
* numUpdates: currentValues.numUpdates + 1,
Expand All @@ -645,20 +675,28 @@ class ServerStateManager extends BaseStateManager {
* const values = state.getValues();
* assert.deepEqual(result, { value: 'test', numUpdates: 1 });
*/
registerUpdateHook(className, updateHook) {
setUpdateHook(className, updateHook) {
if (!this.#classes.has(className)) {
throw new TypeError(`Cannot execute 'registerUpdateHook' on 'BaseStateManager': SharedState class '${className}' does not exists`);
throw new TypeError(`Cannot execute 'setUpdateHook' on 'BaseStateManager': SharedState class '${className}' does not exists`);
}

if (!isFunction(updateHook)) {
throw new TypeError(`Cannot execute 'registerUpdateHook' on 'BaseStateManager': argument 2 must be a function`);
throw new TypeError(`Cannot execute 'setUpdateHook' on 'BaseStateManager': argument 2 must be a function`);
}

const hooks = this.#updateHooksByClassName.get(className);
hooks.add(updateHook);

return () => hooks.delete(updateHook);
}

/**
* @deprecated Use {@link ServerStateManager#setUpdateHook} instead.
*/
registerUpdateHook(className, updateHook) {
logger.deprecated('ServerStateManager#registerUpdateHook', 'ServerStateManager#setUpdateHook', '4.0.0-alpha.29');
return this.setUpdateHook(className, updateHook);
}
}

export default ServerStateManager;
14 changes: 13 additions & 1 deletion tests/misc/deprecated.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ describe('from v4.0.0-alpha.29', () => {
await server.stop();
});

it('SharedStateManager#getSchema()', async () => {
it('StateManager#getSchema()', async () => {
const server = new Server(config);
server.stateManager.defineClass('a', a);
await server.start();
Expand All @@ -70,6 +70,18 @@ describe('from v4.0.0-alpha.29', () => {
server.stateManager.deleteClass('a');
await server.stop();
});

it('ServerStateManager#registerUpdateHook()', async () => {
const server = new Server(config);
server.stateManager.defineClass('a', a);
await server.start();

await server.stateManager.setUpdateHook('a', () => {}); // actual
await server.stateManager.registerUpdateHook('a', () => {}); // deprecated

server.stateManager.deleteClass('a');
await server.stop();
});
});

describe('# removed API', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
import config from '../utils/config.js';
import { a } from '../utils/class-description.js';

describe('# SharedState - schema options', () => {
describe('# SharedStateParameterDescription', () => {
let server;
let client1;
let client2;
Expand All @@ -23,8 +23,6 @@ describe('# SharedState - schema options', () => {
// ---------------------------------------------------
server = new Server(config);
server.stateManager.defineClass('a', a);
// server.stateManager.defineClass('b', b);

await server.start();

// ---------------------------------------------------
Expand Down Expand Up @@ -172,7 +170,7 @@ describe('# SharedState - schema options', () => {

let subscribeCalledBeforeHook = false;

server.stateManager.registerUpdateHook('immediate-test', (updates, currentValues) => {
server.stateManager.setUpdateHook('immediate-test', (updates, currentValues) => {
try {
// assert.fail();
assert.isTrue(subscribeCalledBeforeHook, 'subscribe should be called before hook');
Expand Down
Loading

0 comments on commit 87b21c2

Please sign in to comment.