2021-08-03 11:22:57 +02:00
|
|
|
'use strict';
|
|
|
|
|
2021-09-13 12:03:12 +02:00
|
|
|
const assert = require('assert').strict;
|
|
|
|
|
2021-09-20 19:15:50 +02:00
|
|
|
const timestampsLifecyclesSubscriber = require('./subscribers/timestamps');
|
|
|
|
const modelLifecyclesSubscriber = require('./subscribers/models-lifecycles');
|
2021-09-13 12:03:12 +02:00
|
|
|
|
2022-08-08 23:33:39 +02:00
|
|
|
const isValidSubscriber = (subscriber) => {
|
2021-09-13 12:03:12 +02:00
|
|
|
return (
|
|
|
|
typeof subscriber === 'function' || (typeof subscriber === 'object' && subscriber !== null)
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2021-09-20 19:15:50 +02:00
|
|
|
/**
|
|
|
|
* @type {import('.').createLifecyclesProvider}
|
|
|
|
*/
|
2022-08-08 23:33:39 +02:00
|
|
|
const createLifecyclesProvider = (db) => {
|
2021-09-20 19:15:50 +02:00
|
|
|
let subscribers = [timestampsLifecyclesSubscriber, modelLifecyclesSubscriber];
|
2021-08-06 12:14:11 +02:00
|
|
|
|
2021-09-20 19:15:50 +02:00
|
|
|
return {
|
2021-08-03 11:22:57 +02:00
|
|
|
subscribe(subscriber) {
|
2021-09-13 12:03:12 +02:00
|
|
|
assert(isValidSubscriber(subscriber), 'Invalid subscriber. Expected function or object');
|
|
|
|
|
2021-08-06 12:14:11 +02:00
|
|
|
subscribers.push(subscriber);
|
2021-08-03 11:22:57 +02:00
|
|
|
|
2021-09-13 12:03:12 +02:00
|
|
|
return () => subscribers.splice(subscribers.indexOf(subscriber), 1);
|
2021-08-03 11:22:57 +02:00
|
|
|
},
|
|
|
|
|
2021-09-20 19:15:50 +02:00
|
|
|
clear() {
|
|
|
|
subscribers = [];
|
|
|
|
},
|
|
|
|
|
2022-04-04 19:22:05 +02:00
|
|
|
/**
|
|
|
|
* @param {string} action
|
|
|
|
* @param {string} uid
|
2022-05-20 13:31:48 +02:00
|
|
|
* @param {{ params?: any, result?: any }} properties
|
2022-04-04 19:22:05 +02:00
|
|
|
* @param {Map<any, any>} state
|
|
|
|
*/
|
2022-01-16 13:20:14 +01:00
|
|
|
createEvent(action, uid, properties, state) {
|
2021-08-03 11:22:57 +02:00
|
|
|
const model = db.metadata.get(uid);
|
|
|
|
|
|
|
|
return {
|
|
|
|
action,
|
|
|
|
model,
|
2022-01-16 13:20:14 +01:00
|
|
|
state,
|
2021-08-03 11:22:57 +02:00
|
|
|
...properties,
|
|
|
|
};
|
|
|
|
},
|
2021-08-04 17:47:38 +02:00
|
|
|
|
2022-04-04 19:22:05 +02:00
|
|
|
/**
|
|
|
|
* @param {string} action
|
|
|
|
* @param {string} uid
|
2022-05-20 13:31:48 +02:00
|
|
|
* @param {{ params?: any, result?: any }} properties
|
2022-04-04 19:22:05 +02:00
|
|
|
* @param {Map<any, any>} states
|
|
|
|
*/
|
|
|
|
async run(action, uid, properties, states = new Map()) {
|
2022-09-05 19:44:58 +02:00
|
|
|
for (let i = 0; i < subscribers.length; i += 1) {
|
2022-01-16 13:20:14 +01:00
|
|
|
const subscriber = subscribers[i];
|
2021-08-04 17:47:38 +02:00
|
|
|
if (typeof subscriber === 'function') {
|
2022-04-04 19:22:05 +02:00
|
|
|
const state = states.get(subscriber) || {};
|
|
|
|
const event = this.createEvent(action, uid, properties, state);
|
2021-08-09 10:53:25 +02:00
|
|
|
await subscriber(event);
|
2022-01-16 13:20:14 +01:00
|
|
|
if (event.state) {
|
2022-04-04 19:22:05 +02:00
|
|
|
states.set(subscriber, event.state || state);
|
2022-01-16 13:20:14 +01:00
|
|
|
}
|
2021-08-09 10:53:25 +02:00
|
|
|
continue;
|
2021-08-04 17:47:38 +02:00
|
|
|
}
|
|
|
|
|
2021-08-03 11:22:57 +02:00
|
|
|
const hasAction = action in subscriber;
|
|
|
|
const hasModel = !subscriber.models || subscriber.models.includes(uid);
|
|
|
|
|
|
|
|
if (hasAction && hasModel) {
|
2022-04-04 19:22:05 +02:00
|
|
|
const state = states.get(subscriber) || {};
|
|
|
|
const event = this.createEvent(action, uid, properties, state);
|
2021-08-03 11:22:57 +02:00
|
|
|
|
|
|
|
await subscriber[action](event);
|
2022-01-16 13:20:14 +01:00
|
|
|
if (event.state) {
|
2022-04-04 19:22:05 +02:00
|
|
|
states.set(subscriber, event.state);
|
2022-01-16 13:20:14 +01:00
|
|
|
}
|
2021-08-03 11:22:57 +02:00
|
|
|
}
|
|
|
|
}
|
2022-04-04 19:22:05 +02:00
|
|
|
|
|
|
|
return states;
|
2021-08-03 11:22:57 +02:00
|
|
|
},
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
module.exports = {
|
2021-09-20 19:15:50 +02:00
|
|
|
createLifecyclesProvider,
|
2021-08-03 11:22:57 +02:00
|
|
|
};
|