WorkflowState.js 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /* eslint-disable no-param-reassign */
  2. class WorkflowState {
  3. constructor({ storage, key = 'workflowState' }) {
  4. this.key = key;
  5. this.storage = storage;
  6. this.states = new Map();
  7. this.eventListeners = {};
  8. }
  9. _saveToStorage() {
  10. const states = Object.fromEntries(this.states);
  11. return this.storage.set(this.key, states);
  12. }
  13. dispatchEvent(name, params) {
  14. const listeners = this.eventListeners[name];
  15. if (!listeners) return;
  16. listeners.forEach((callback) => {
  17. callback(params);
  18. });
  19. }
  20. on(name, listener) {
  21. (this.eventListeners[name] = this.eventListeners[name] || []).push(
  22. listener
  23. );
  24. }
  25. off(name, listener) {
  26. const listeners = this.eventListeners[name];
  27. if (!listeners) return;
  28. const index = listeners.indexOf(listener);
  29. if (index !== -1) listeners.splice(index, 1);
  30. }
  31. get getAll() {
  32. return this.states;
  33. }
  34. async get(stateId) {
  35. let { states } = this;
  36. if (typeof stateId === 'function') {
  37. states = Array.from(states.entries()).find(({ 1: state }) =>
  38. stateId(state)
  39. );
  40. } else if (stateId) {
  41. states = this.states.get(stateId);
  42. }
  43. return states;
  44. }
  45. async add(id, data = {}) {
  46. this.states.set(id, data);
  47. await this._saveToStorage(this.key);
  48. }
  49. async stop(id) {
  50. const isStateExist = await this.get(id);
  51. if (!isStateExist) {
  52. await this.delete(id);
  53. this.dispatchEvent('stop', id);
  54. return id;
  55. }
  56. await this.update(id, { isDestroyed: true });
  57. this.dispatchEvent('stop', id);
  58. return id;
  59. }
  60. async update(id, data = {}) {
  61. const state = this.states.get(id);
  62. this.states.set(id, { ...state, ...data });
  63. this.dispatchEvent('update', { id, data });
  64. await this._saveToStorage();
  65. }
  66. async delete(id) {
  67. this.states.delete(id);
  68. this.dispatchEvent('delete', id);
  69. await this._saveToStorage();
  70. }
  71. }
  72. export default WorkflowState;