useEvents.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import { onBeforeUnmount, ref } from "vue";
  2. import { forEachIn } from "@common/utils/forEachIn";
  3. import { useWebsocketStore } from "@/stores/websocket";
  4. export const useEvents = () => {
  5. const websocketStore = useWebsocketStore();
  6. const readySubscriptions = ref({});
  7. const subscriptions = ref({});
  8. const onReady = async callback => {
  9. const uuid = await websocketStore.onReady(callback);
  10. readySubscriptions.value[uuid] = { callback };
  11. return uuid;
  12. };
  13. const removeReadyCallback = uuid => {
  14. if (!readySubscriptions.value[uuid]) return;
  15. websocketStore.removeReadyCallback(uuid);
  16. delete readySubscriptions.value[uuid];
  17. };
  18. const subscribe = async (channel, callback) => {
  19. const uuid = await websocketStore.subscribe(channel, callback);
  20. subscriptions.value[uuid] = { channel, callback };
  21. return uuid;
  22. };
  23. const subscribeMany = async channels => {
  24. const _subscriptions = await websocketStore.subscribeMany(channels);
  25. await forEachIn(
  26. Object.entries(_subscriptions),
  27. async ([uuid, { channel, callback }]) => {
  28. subscriptions.value[uuid] = { channel, callback };
  29. }
  30. );
  31. return Object.fromEntries(
  32. Object.entries(_subscriptions).map(([uuid, { channel }]) => [
  33. channel,
  34. uuid
  35. ])
  36. );
  37. };
  38. const unsubscribe = async uuid => {
  39. if (!subscriptions.value[uuid]) return;
  40. const { channel } = subscriptions.value[uuid];
  41. await websocketStore.unsubscribe(channel, uuid);
  42. delete subscriptions.value[uuid];
  43. };
  44. const unsubscribeMany = async uuids => {
  45. if (uuids.length === 0) return;
  46. const _subscriptions = Object.fromEntries(
  47. Object.entries(subscriptions.value)
  48. .filter(([uuid]) => uuids.includes(uuid))
  49. .map(([uuid, { channel }]) => [uuid, channel])
  50. );
  51. await websocketStore.unsubscribeMany(_subscriptions);
  52. await forEachIn(uuids, async uuid => {
  53. delete subscriptions.value[uuid];
  54. });
  55. };
  56. onBeforeUnmount(async () => {
  57. await forEachIn(
  58. Object.keys(subscriptions.value),
  59. uuid => unsubscribe(uuid),
  60. { onError: Promise.resolve }
  61. );
  62. await forEachIn(
  63. Object.keys(readySubscriptions.value),
  64. async uuid => removeReadyCallback(uuid),
  65. { onError: Promise.resolve }
  66. );
  67. });
  68. return {
  69. readySubscriptions,
  70. subscriptions,
  71. onReady,
  72. removeReadyCallback,
  73. subscribe,
  74. subscribeMany,
  75. unsubscribe,
  76. unsubscribeMany
  77. };
  78. };