@pushler/vue 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,137 @@
1
+ import { ref, reactive, onUnmounted, watch } from 'vue';
2
+
3
+ /**
4
+ * Vue composable для работы с отдельным каналом Pushler
5
+ *
6
+ * Можно использовать автономно или совместно с usePushler
7
+ *
8
+ * @param {Object} pushler - Инстанс usePushler
9
+ * @param {string} channelName - Имя канала
10
+ * @param {Object} options - Опции канала
11
+ * @returns {Object} Реактивный объект канала с событиями
12
+ */
13
+ export function usePushlerChannel(pushler, channelName, options = {}) {
14
+ const channel = ref(null);
15
+ const isSubscribed = ref(false);
16
+ const lastEvent = ref(null);
17
+ const events = reactive([]);
18
+ const eventHandlers = new Map();
19
+
20
+ /**
21
+ * Максимальное количество событий в буфере
22
+ */
23
+ const maxEvents = options.maxEvents || 100;
24
+
25
+ /**
26
+ * Подписка на канал
27
+ */
28
+ function subscribe() {
29
+ if (!pushler || !channelName) return;
30
+
31
+ channel.value = pushler.subscribe(channelName, options);
32
+
33
+ // Отслеживаем статус подписки
34
+ channel.value.on('subscribed', () => {
35
+ isSubscribed.value = true;
36
+ });
37
+
38
+ return channel.value;
39
+ }
40
+
41
+ /**
42
+ * Отписка от канала
43
+ */
44
+ function unsubscribe() {
45
+ if (pushler && channelName) {
46
+ pushler.unsubscribe(channelName);
47
+ channel.value = null;
48
+ isSubscribed.value = false;
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Подписка на событие канала
54
+ * @param {string} eventName - Имя события
55
+ * @param {Function} callback - Обработчик
56
+ */
57
+ function on(eventName, callback) {
58
+ if (!channel.value) {
59
+ subscribe();
60
+ }
61
+
62
+ const handler = (data) => {
63
+ // Сохраняем последнее событие
64
+ lastEvent.value = {
65
+ event: eventName,
66
+ data,
67
+ timestamp: new Date()
68
+ };
69
+
70
+ // Добавляем в буфер событий
71
+ events.unshift(lastEvent.value);
72
+ if (events.length > maxEvents) {
73
+ events.pop();
74
+ }
75
+
76
+ // Вызываем пользовательский обработчик
77
+ callback(data);
78
+ };
79
+
80
+ eventHandlers.set(eventName, handler);
81
+ channel.value.on(eventName, handler);
82
+
83
+ return () => off(eventName);
84
+ }
85
+
86
+ /**
87
+ * Отписка от события канала
88
+ */
89
+ function off(eventName) {
90
+ if (channel.value && eventHandlers.has(eventName)) {
91
+ channel.value.off(eventName, eventHandlers.get(eventName));
92
+ eventHandlers.delete(eventName);
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Очистка буфера событий
98
+ */
99
+ function clearEvents() {
100
+ events.length = 0;
101
+ lastEvent.value = null;
102
+ }
103
+
104
+ // Автоматическая подписка если указано
105
+ if (options.autoSubscribe !== false && pushler?.isConnected?.value) {
106
+ subscribe();
107
+ }
108
+
109
+ // Подписываемся при подключении
110
+ if (pushler) {
111
+ watch(() => pushler.isConnected.value, (connected) => {
112
+ if (connected && options.autoSubscribe !== false && !channel.value) {
113
+ subscribe();
114
+ }
115
+ });
116
+ }
117
+
118
+ // Автоматическая отписка при размонтировании
119
+ onUnmounted(() => {
120
+ unsubscribe();
121
+ });
122
+
123
+ return {
124
+ channel,
125
+ isSubscribed,
126
+ lastEvent,
127
+ events,
128
+
129
+ subscribe,
130
+ unsubscribe,
131
+ on,
132
+ off,
133
+ clearEvents,
134
+ };
135
+ }
136
+
137
+ export default usePushlerChannel;