@pushler/vue 1.0.3 → 1.1.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.
- package/README.md +58 -1
- package/dist/pushler-vue.cjs.js +129 -6
- package/dist/pushler-vue.cjs.js.map +1 -1
- package/dist/pushler-vue.esm.js +129 -6
- package/dist/pushler-vue.esm.js.map +1 -1
- package/dist/pushler-vue.umd.js +129 -6
- package/dist/pushler-vue.umd.js.map +1 -1
- package/dist/pushler-vue.umd.min.js +2 -2
- package/dist/pushler-vue.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/src/index.d.ts +15 -1
- package/src/usePushler.js +128 -5
package/README.md
CHANGED
|
@@ -153,7 +153,7 @@ pushler.isReconnecting // ComputedRef<boolean>
|
|
|
153
153
|
|
|
154
154
|
```js
|
|
155
155
|
// Подключение к серверу
|
|
156
|
-
pushler.connect(options?: { appKey
|
|
156
|
+
pushler.connect(options?: { appKey? })
|
|
157
157
|
|
|
158
158
|
// Отключение
|
|
159
159
|
pushler.disconnect()
|
|
@@ -271,6 +271,63 @@ Route::post('/pushler/auth', function (Request $request) {
|
|
|
271
271
|
});
|
|
272
272
|
```
|
|
273
273
|
|
|
274
|
+
### Кастомные заголовки авторизации
|
|
275
|
+
|
|
276
|
+
Вы можете передать дополнительные заголовки для запросов авторизации:
|
|
277
|
+
|
|
278
|
+
```js
|
|
279
|
+
// Статические заголовки
|
|
280
|
+
const pushler = usePushler({
|
|
281
|
+
appKey: 'your-app-key',
|
|
282
|
+
authEndpoint: '/api/pushler/auth',
|
|
283
|
+
authHeaders: {
|
|
284
|
+
'Authorization': 'Bearer your-token',
|
|
285
|
+
'X-Custom-Header': 'value'
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
// Динамические заголовки (рекомендуется)
|
|
290
|
+
const pushler = usePushler({
|
|
291
|
+
appKey: 'your-app-key',
|
|
292
|
+
authEndpoint: '/api/pushler/auth',
|
|
293
|
+
getAuthHeaders: () => ({
|
|
294
|
+
'Authorization': `Bearer ${authStore.token}`
|
|
295
|
+
})
|
|
296
|
+
});
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
При использовании `authHeaders` или `getAuthHeaders` SDK не отправляет cookies (`credentials: 'include'`).
|
|
300
|
+
|
|
301
|
+
## Promise-based API
|
|
302
|
+
|
|
303
|
+
### Ожидание подключения
|
|
304
|
+
|
|
305
|
+
`connect()` возвращает Promise, который резолвится при успешном подключении:
|
|
306
|
+
|
|
307
|
+
```js
|
|
308
|
+
const pushler = usePushler({ appKey: 'your-app-key' });
|
|
309
|
+
|
|
310
|
+
// Ожидаем подключения
|
|
311
|
+
const { socketId } = await pushler.connect();
|
|
312
|
+
console.log('Подключены с socketId:', socketId);
|
|
313
|
+
|
|
314
|
+
// Теперь можно подписываться на приватные каналы
|
|
315
|
+
pushler.subscribe('private-user-123');
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Метод `waitForConnection()`
|
|
319
|
+
|
|
320
|
+
Для случаев, когда нужно дождаться соединения с таймаутом:
|
|
321
|
+
|
|
322
|
+
```js
|
|
323
|
+
try {
|
|
324
|
+
await pushler.waitForConnection(10000); // 10 секунд
|
|
325
|
+
console.log('Подключены!');
|
|
326
|
+
} catch (error) {
|
|
327
|
+
console.error('Не удалось подключиться:', error.message);
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
274
331
|
### `usePushlerChannel(pushler, channelName, options)`
|
|
275
332
|
|
|
276
333
|
Composable для работы с отдельным каналом.
|
package/dist/pushler-vue.cjs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @pushler/vue v1.0
|
|
2
|
+
* @pushler/vue v1.1.0
|
|
3
3
|
* (c) 2026 Pushler.ru
|
|
4
4
|
* @license MIT
|
|
5
5
|
*/
|
|
@@ -36,6 +36,8 @@ const ChannelTypes = {
|
|
|
36
36
|
* @param {string} options.appKey - Ключ приложения
|
|
37
37
|
* @param {string} options.wsUrl - URL WebSocket сервера
|
|
38
38
|
* @param {string} options.authEndpoint - Эндпоинт авторизации для приватных каналов
|
|
39
|
+
* @param {Object} options.authHeaders - Статические заголовки для авторизации (например, { Authorization: 'Bearer token' })
|
|
40
|
+
* @param {Function} options.getAuthHeaders - Функция для динамического получения заголовков авторизации
|
|
39
41
|
* @param {boolean} options.autoConnect - Автоматическое подключение (по умолчанию false)
|
|
40
42
|
* @param {number} options.reconnectDelay - Задержка переподключения в мс (по умолчанию 1000)
|
|
41
43
|
* @param {number} options.maxReconnectAttempts - Максимум попыток переподключения (по умолчанию 5)
|
|
@@ -57,6 +59,11 @@ function usePushler(options = {}) {
|
|
|
57
59
|
let reconnectTimer = null;
|
|
58
60
|
const eventListeners = new Map();
|
|
59
61
|
|
|
62
|
+
// Promise для ожидания подключения
|
|
63
|
+
let connectionPromise = null;
|
|
64
|
+
let connectionResolve = null;
|
|
65
|
+
let connectionReject = null;
|
|
66
|
+
|
|
60
67
|
// Конфигурация
|
|
61
68
|
const appKey = options.appKey || '';
|
|
62
69
|
const config = {
|
|
@@ -64,6 +71,8 @@ function usePushler(options = {}) {
|
|
|
64
71
|
// wsUrl формируется автоматически из appKey, но можно переопределить
|
|
65
72
|
wsUrl: options.wsUrl || `wss://ws.pushler.ru/app/${appKey}`,
|
|
66
73
|
authEndpoint: options.authEndpoint || '/pushler/auth',
|
|
74
|
+
authHeaders: options.authHeaders || null,
|
|
75
|
+
getAuthHeaders: options.getAuthHeaders || null,
|
|
67
76
|
autoConnect: options.autoConnect || false,
|
|
68
77
|
reconnectDelay: options.reconnectDelay || 1000,
|
|
69
78
|
maxReconnectAttempts: options.maxReconnectAttempts || 5,
|
|
@@ -107,18 +116,33 @@ function usePushler(options = {}) {
|
|
|
107
116
|
|
|
108
117
|
/**
|
|
109
118
|
* Подключение к WebSocket серверу
|
|
119
|
+
* @param {Object} connectOptions - Опции подключения
|
|
120
|
+
* @returns {Promise} Promise, который резолвится при успешном подключении
|
|
110
121
|
*/
|
|
111
122
|
function connect(connectOptions = {}) {
|
|
112
123
|
// Обновляем конфигурацию если переданы новые параметры
|
|
113
124
|
if (connectOptions.appKey) config.appKey = connectOptions.appKey;
|
|
114
125
|
if (connectOptions.wsUrl) config.wsUrl = connectOptions.wsUrl;
|
|
115
126
|
if (connectOptions.authEndpoint) config.authEndpoint = connectOptions.authEndpoint;
|
|
127
|
+
if (connectOptions.authHeaders) config.authHeaders = connectOptions.authHeaders;
|
|
128
|
+
if (connectOptions.getAuthHeaders) config.getAuthHeaders = connectOptions.getAuthHeaders;
|
|
116
129
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
return;
|
|
130
|
+
// Если уже подключены - возвращаем резолвленный Promise
|
|
131
|
+
if (connectionState.value === ConnectionStates.CONNECTED) {
|
|
132
|
+
return Promise.resolve({ socketId: socketId.value });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Если уже идёт подключение - возвращаем существующий Promise
|
|
136
|
+
if (connectionState.value === ConnectionStates.CONNECTING && connectionPromise) {
|
|
137
|
+
return connectionPromise;
|
|
120
138
|
}
|
|
121
139
|
|
|
140
|
+
// Создаём новый Promise для ожидания подключения
|
|
141
|
+
connectionPromise = new Promise((resolve, reject) => {
|
|
142
|
+
connectionResolve = resolve;
|
|
143
|
+
connectionReject = reject;
|
|
144
|
+
});
|
|
145
|
+
|
|
122
146
|
connectionState.value = ConnectionStates.CONNECTING;
|
|
123
147
|
error.value = null;
|
|
124
148
|
|
|
@@ -131,7 +155,66 @@ function usePushler(options = {}) {
|
|
|
131
155
|
console.error('[Pushler Vue] Connection error:', err);
|
|
132
156
|
connectionState.value = ConnectionStates.FAILED;
|
|
133
157
|
error.value = err.message;
|
|
158
|
+
if (connectionReject) {
|
|
159
|
+
connectionReject(err);
|
|
160
|
+
connectionPromise = null;
|
|
161
|
+
connectionResolve = null;
|
|
162
|
+
connectionReject = null;
|
|
163
|
+
}
|
|
134
164
|
}
|
|
165
|
+
|
|
166
|
+
return connectionPromise;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Ожидание установления соединения
|
|
171
|
+
* @param {number} timeout - Таймаут в мс (по умолчанию 10000)
|
|
172
|
+
* @returns {Promise} Promise с socketId
|
|
173
|
+
*/
|
|
174
|
+
function waitForConnection(timeout = 10000) {
|
|
175
|
+
// Если уже подключены
|
|
176
|
+
if (connectionState.value === ConnectionStates.CONNECTED && socketId.value) {
|
|
177
|
+
return Promise.resolve({ socketId: socketId.value });
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Если есть активный Promise подключения
|
|
181
|
+
if (connectionPromise) {
|
|
182
|
+
return Promise.race([
|
|
183
|
+
connectionPromise,
|
|
184
|
+
new Promise((_, reject) =>
|
|
185
|
+
setTimeout(() => reject(new Error('Connection timeout')), timeout)
|
|
186
|
+
)
|
|
187
|
+
]);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Если не подключаемся - начинаем подключение
|
|
191
|
+
if (connectionState.value === ConnectionStates.DISCONNECTED) {
|
|
192
|
+
return connect();
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Для других состояний создаём Promise, который ждёт connected события
|
|
196
|
+
return new Promise((resolve, reject) => {
|
|
197
|
+
const timeoutId = setTimeout(() => {
|
|
198
|
+
off('connected', onConnected);
|
|
199
|
+
off('error', onError);
|
|
200
|
+
reject(new Error('Connection timeout'));
|
|
201
|
+
}, timeout);
|
|
202
|
+
|
|
203
|
+
const onConnected = (data) => {
|
|
204
|
+
clearTimeout(timeoutId);
|
|
205
|
+
off('error', onError);
|
|
206
|
+
resolve(data);
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
const onError = (err) => {
|
|
210
|
+
clearTimeout(timeoutId);
|
|
211
|
+
off('connected', onConnected);
|
|
212
|
+
reject(err);
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
on('connected', onConnected);
|
|
216
|
+
on('error', onError);
|
|
217
|
+
});
|
|
135
218
|
}
|
|
136
219
|
|
|
137
220
|
/**
|
|
@@ -161,6 +244,14 @@ function usePushler(options = {}) {
|
|
|
161
244
|
console.error('[Pushler Vue] WebSocket error:', err);
|
|
162
245
|
connectionState.value = ConnectionStates.FAILED;
|
|
163
246
|
error.value = 'Connection failed';
|
|
247
|
+
|
|
248
|
+
// Реджектим Promise подключения
|
|
249
|
+
if (connectionReject) {
|
|
250
|
+
connectionReject(new Error('Connection failed'));
|
|
251
|
+
connectionPromise = null;
|
|
252
|
+
connectionResolve = null;
|
|
253
|
+
connectionReject = null;
|
|
254
|
+
}
|
|
164
255
|
};
|
|
165
256
|
}
|
|
166
257
|
|
|
@@ -212,6 +303,14 @@ function usePushler(options = {}) {
|
|
|
212
303
|
|
|
213
304
|
console.log('[Pushler Vue] Connected with socket ID:', socketId.value);
|
|
214
305
|
|
|
306
|
+
// Резолвим Promise подключения
|
|
307
|
+
if (connectionResolve) {
|
|
308
|
+
connectionResolve({ socketId: socketId.value });
|
|
309
|
+
connectionPromise = null;
|
|
310
|
+
connectionResolve = null;
|
|
311
|
+
connectionReject = null;
|
|
312
|
+
}
|
|
313
|
+
|
|
215
314
|
// Переподписка на все каналы
|
|
216
315
|
resubscribeAllChannels();
|
|
217
316
|
|
|
@@ -466,6 +565,24 @@ function usePushler(options = {}) {
|
|
|
466
565
|
return authData;
|
|
467
566
|
}
|
|
468
567
|
|
|
568
|
+
/**
|
|
569
|
+
* Получение заголовков для авторизации
|
|
570
|
+
*/
|
|
571
|
+
function getAuthRequestHeaders() {
|
|
572
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
573
|
+
|
|
574
|
+
// Динамические заголовки имеют приоритет
|
|
575
|
+
if (typeof config.getAuthHeaders === 'function') {
|
|
576
|
+
const dynamicHeaders = config.getAuthHeaders();
|
|
577
|
+
Object.assign(headers, dynamicHeaders);
|
|
578
|
+
} else if (config.authHeaders) {
|
|
579
|
+
// Статические заголовки
|
|
580
|
+
Object.assign(headers, config.authHeaders);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
return headers;
|
|
584
|
+
}
|
|
585
|
+
|
|
469
586
|
/**
|
|
470
587
|
* Запрос подписи с бэкенда
|
|
471
588
|
*
|
|
@@ -475,10 +592,15 @@ function usePushler(options = {}) {
|
|
|
475
592
|
* 3. Вернуть подпись клиенту
|
|
476
593
|
*/
|
|
477
594
|
async function fetchSignature(channel) {
|
|
595
|
+
const headers = getAuthRequestHeaders();
|
|
596
|
+
const hasAuthHeaders = config.authHeaders || config.getAuthHeaders;
|
|
597
|
+
|
|
478
598
|
const response = await fetch(config.authEndpoint, {
|
|
479
599
|
method: 'POST',
|
|
480
|
-
headers
|
|
481
|
-
|
|
600
|
+
headers,
|
|
601
|
+
// Если есть authHeaders, не используем credentials (JWT режим)
|
|
602
|
+
// Если нет — используем cookies для обратной совместимости
|
|
603
|
+
...(hasAuthHeaders ? {} : { credentials: 'include' }),
|
|
482
604
|
body: JSON.stringify({
|
|
483
605
|
channel_name: channel.name,
|
|
484
606
|
socket_id: socketId.value,
|
|
@@ -597,6 +719,7 @@ function usePushler(options = {}) {
|
|
|
597
719
|
// Методы
|
|
598
720
|
connect,
|
|
599
721
|
disconnect,
|
|
722
|
+
waitForConnection,
|
|
600
723
|
subscribe,
|
|
601
724
|
unsubscribe,
|
|
602
725
|
channel,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pushler-vue.cjs.js","sources":["../src/usePushler.js","../src/usePushlerChannel.js","../src/plugin.js","../src/index.js"],"sourcesContent":["import { ref, reactive, readonly, onUnmounted, watch, computed } from 'vue';\n\n/**\n * Состояния подключения\n */\nexport const ConnectionStates = {\n CONNECTING: 'connecting',\n CONNECTED: 'connected',\n DISCONNECTED: 'disconnected',\n RECONNECTING: 'reconnecting',\n FAILED: 'failed'\n};\n\n/**\n * Типы каналов\n */\nexport const ChannelTypes = {\n PUBLIC: 'public',\n PRIVATE: 'private',\n PRESENCE: 'presence'\n};\n\n/**\n * Vue composable для работы с Pushler WebSocket\n * \n * @param {Object} options - Опции подключения\n * @param {string} options.appKey - Ключ приложения\n * @param {string} options.wsUrl - URL WebSocket сервера\n * @param {string} options.authEndpoint - Эндпоинт авторизации для приватных каналов\n * @param {boolean} options.autoConnect - Автоматическое подключение (по умолчанию false)\n * @param {number} options.reconnectDelay - Задержка переподключения в мс (по умолчанию 1000)\n * @param {number} options.maxReconnectAttempts - Максимум попыток переподключения (по умолчанию 5)\n * @returns {Object} Реактивный объект с методами и состоянием\n */\nexport function usePushler(options = {}) {\n // Реактивное состояние\n const connectionState = ref(ConnectionStates.DISCONNECTED);\n const socketId = ref(null);\n const error = ref(null);\n const reconnectAttempts = ref(0);\n \n // Каналы\n const channels = reactive(new Map());\n const channelAliases = reactive(new Map());\n \n // Внутренние переменные\n let socket = null;\n let reconnectTimer = null;\n const eventListeners = new Map();\n \n // Конфигурация\n const appKey = options.appKey || '';\n const config = {\n appKey: appKey,\n // wsUrl формируется автоматически из appKey, но можно переопределить\n wsUrl: options.wsUrl || `wss://ws.pushler.ru/app/${appKey}`,\n authEndpoint: options.authEndpoint || '/pushler/auth',\n autoConnect: options.autoConnect || false,\n reconnectDelay: options.reconnectDelay || 1000,\n maxReconnectAttempts: options.maxReconnectAttempts || 5,\n };\n \n // Вычисляемые свойства\n const isConnected = computed(() => connectionState.value === ConnectionStates.CONNECTED);\n const isConnecting = computed(() => connectionState.value === ConnectionStates.CONNECTING);\n const isReconnecting = computed(() => connectionState.value === ConnectionStates.RECONNECTING);\n \n /**\n * Форматирование имени канала с префиксом appKey\n */\n function formatChannelName(channelName) {\n if (channelName.startsWith(config.appKey + ':')) {\n return channelName;\n }\n return `${config.appKey}:${channelName}`;\n }\n \n /**\n * Извлечение оригинального имени канала\n */\n function extractChannelName(fullChannelName) {\n const prefix = config.appKey + ':';\n if (fullChannelName.startsWith(prefix)) {\n return fullChannelName.substring(prefix.length);\n }\n return fullChannelName;\n }\n \n /**\n * Определение типа канала\n */\n function getChannelType(channelName) {\n const baseName = extractChannelName(channelName);\n if (baseName.startsWith('private-')) return ChannelTypes.PRIVATE;\n if (baseName.startsWith('presence-')) return ChannelTypes.PRESENCE;\n return ChannelTypes.PUBLIC;\n }\n \n /**\n * Подключение к WebSocket серверу\n */\n function connect(connectOptions = {}) {\n // Обновляем конфигурацию если переданы новые параметры\n if (connectOptions.appKey) config.appKey = connectOptions.appKey;\n if (connectOptions.wsUrl) config.wsUrl = connectOptions.wsUrl;\n if (connectOptions.authEndpoint) config.authEndpoint = connectOptions.authEndpoint;\n \n if (connectionState.value === ConnectionStates.CONNECTED ||\n connectionState.value === ConnectionStates.CONNECTING) {\n return;\n }\n \n connectionState.value = ConnectionStates.CONNECTING;\n error.value = null;\n \n try {\n // wsUrl уже содержит appKey из конфигурации\n console.log('[Pushler Vue] Connecting to:', config.wsUrl);\n socket = new WebSocket(config.wsUrl);\n setupSocketHandlers();\n } catch (err) {\n console.error('[Pushler Vue] Connection error:', err);\n connectionState.value = ConnectionStates.FAILED;\n error.value = err.message;\n }\n }\n \n /**\n * Настройка обработчиков WebSocket\n */\n function setupSocketHandlers() {\n socket.onopen = () => {\n console.log('[Pushler Vue] WebSocket opened, waiting for connection_established...');\n };\n \n socket.onmessage = (event) => {\n handleMessage(event);\n };\n \n socket.onclose = (event) => {\n console.log('[Pushler Vue] WebSocket closed:', event.code, event.reason);\n connectionState.value = ConnectionStates.DISCONNECTED;\n socketId.value = null;\n \n // Автопереподключение\n if (event.code !== 1000 && reconnectAttempts.value < config.maxReconnectAttempts) {\n scheduleReconnect();\n }\n };\n \n socket.onerror = (err) => {\n console.error('[Pushler Vue] WebSocket error:', err);\n connectionState.value = ConnectionStates.FAILED;\n error.value = 'Connection failed';\n };\n }\n \n /**\n * Обработка входящих сообщений\n */\n function handleMessage(event) {\n try {\n // Поддержка нескольких сообщений в одном event\n const messages = event.data.trim().split('\\n').filter(line => line.trim());\n \n for (const msgData of messages) {\n processMessage(JSON.parse(msgData));\n }\n } catch (err) {\n console.error('[Pushler Vue] Error parsing message:', err);\n }\n }\n \n /**\n * Обработка отдельного сообщения\n */\n function processMessage(message) {\n switch (message.event) {\n case 'pushler:connection_established':\n handleConnectionEstablished(message.data);\n break;\n case 'pushler:subscription_succeeded':\n handleSubscriptionSucceeded(message);\n break;\n case 'pushler:auth_success':\n handleAuthSuccess(message);\n break;\n case 'pushler:auth_error':\n handleAuthError(message);\n break;\n default:\n handleChannelMessage(message);\n }\n }\n \n /**\n * Обработка установления соединения\n */\n function handleConnectionEstablished(data) {\n socketId.value = data.socket_id;\n connectionState.value = ConnectionStates.CONNECTED;\n reconnectAttempts.value = 0;\n \n console.log('[Pushler Vue] Connected with socket ID:', socketId.value);\n \n // Переподписка на все каналы\n resubscribeAllChannels();\n \n emit('connected', { socketId: socketId.value });\n }\n \n /**\n * Переподписка на все каналы\n */\n function resubscribeAllChannels() {\n for (const [name, channel] of channels.entries()) {\n channel.subscribed = false;\n performChannelSubscription(channel);\n }\n }\n \n /**\n * Обработка успешной подписки\n */\n function handleSubscriptionSucceeded(message) {\n const channel = channels.get(message.channel);\n if (channel) {\n channel.subscribed = true;\n channel.emit('subscribed', message.data || {});\n }\n }\n \n /**\n * Обработка успешной авторизации\n */\n function handleAuthSuccess(message) {\n const channel = channels.get(message.data.channel);\n if (channel) {\n channel.subscribed = true;\n channel.emit('subscribed', message.data);\n }\n emit('auth_success', message.data);\n }\n \n /**\n * Обработка ошибки авторизации\n */\n function handleAuthError(message) {\n error.value = message.data.error;\n emit('auth_error', message.data);\n }\n \n /**\n * Обработка сообщения канала\n */\n function handleChannelMessage(message) {\n const { channel: channelName, event, data } = message;\n const channel = channels.get(channelName);\n \n if (channel) {\n channel.emit(event, data);\n }\n \n emit('message', { \n channel: extractChannelName(channelName), \n event, \n data \n });\n }\n \n /**\n * Планирование переподключения\n */\n function scheduleReconnect() {\n if (reconnectTimer) {\n clearTimeout(reconnectTimer);\n }\n \n reconnectAttempts.value++;\n connectionState.value = ConnectionStates.RECONNECTING;\n \n const delay = config.reconnectDelay * reconnectAttempts.value;\n console.log(`[Pushler Vue] Reconnecting in ${delay}ms (attempt ${reconnectAttempts.value}/${config.maxReconnectAttempts})`);\n \n reconnectTimer = setTimeout(() => {\n connect();\n }, delay);\n }\n \n /**\n * Отключение от сервера\n */\n function disconnect() {\n if (reconnectTimer) {\n clearTimeout(reconnectTimer);\n reconnectTimer = null;\n }\n \n if (socket) {\n socket.close(1000, 'User disconnect');\n socket = null;\n }\n \n connectionState.value = ConnectionStates.DISCONNECTED;\n socketId.value = null;\n channels.clear();\n channelAliases.clear();\n reconnectAttempts.value = 0;\n \n emit('disconnected');\n }\n \n /**\n * Отправка сообщения через WebSocket\n */\n function sendMessage(message) {\n if (socket && socket.readyState === WebSocket.OPEN) {\n socket.send(JSON.stringify(message));\n }\n }\n \n /**\n * Подписка на канал\n * @param {string} channelName - Имя канала\n * @param {Object} options - Опции (signature для приватных, user для presence)\n * @returns {Object} Реактивный объект канала\n */\n function subscribe(channelName, subscribeOptions = {}) {\n const fullChannelName = formatChannelName(channelName);\n \n if (channels.has(fullChannelName)) {\n return channels.get(fullChannelName);\n }\n \n // Создаем реактивный канал\n const channel = reactive({\n name: fullChannelName,\n originalName: channelName,\n type: getChannelType(channelName),\n subscribed: false,\n options: subscribeOptions,\n listeners: new Map(),\n \n // Методы канала\n on(event, callback) {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, []);\n }\n this.listeners.get(event).push(callback);\n return this;\n },\n \n off(event, callback) {\n if (this.listeners.has(event)) {\n const list = this.listeners.get(event);\n const idx = list.indexOf(callback);\n if (idx > -1) list.splice(idx, 1);\n }\n return this;\n },\n \n emit(event, data) {\n if (this.listeners.has(event)) {\n this.listeners.get(event).forEach(cb => {\n try {\n cb(data);\n } catch (err) {\n console.error('[Pushler Vue] Channel event error:', err);\n }\n });\n }\n },\n \n unsubscribe() {\n unsubscribe(channelName);\n }\n });\n \n channels.set(fullChannelName, channel);\n channelAliases.set(channelName, fullChannelName);\n \n // Подписываемся если уже подключены\n if (connectionState.value === ConnectionStates.CONNECTED) {\n performChannelSubscription(channel);\n }\n \n return channel;\n }\n \n /**\n * Выполнение подписки на канал\n */\n async function performChannelSubscription(channel) {\n if (connectionState.value !== ConnectionStates.CONNECTED) {\n return;\n }\n \n const channelType = channel.type;\n \n // Публичные каналы\n if (channelType === ChannelTypes.PUBLIC) {\n sendMessage({\n event: 'pushler:subscribe',\n data: {\n channel: channel.name,\n app_key: config.appKey\n }\n });\n return;\n }\n \n // Приватные и presence каналы требуют авторизации\n try {\n const authData = await getAuthData(channel);\n sendMessage({\n event: 'pushler:auth',\n data: authData\n });\n } catch (err) {\n console.error('[Pushler Vue] Auth error:', err);\n error.value = err.message;\n }\n }\n \n /**\n * Получение данных авторизации для приватных/presence каналов\n * \n * Для приватных каналов подпись ДОЛЖНА быть получена с вашего бэкенда,\n * либо передана в options.signature при подписке.\n * \n * НИКОГДА не храните секретный ключ в клиентском коде!\n */\n async function getAuthData(channel) {\n if (!socketId.value) {\n throw new Error('Socket ID not available');\n }\n \n const authData = {\n app_key: config.appKey,\n channel: channel.name,\n socket_id: socketId.value\n };\n \n // Если подпись уже предоставлена в options\n if (channel.options.signature) {\n authData.signature = channel.options.signature;\n } else {\n // Запрашиваем подпись с бэкенда\n authData.signature = await fetchSignature(channel);\n }\n \n // Данные пользователя для presence каналов\n if (channel.type === ChannelTypes.PRESENCE && channel.options.user) {\n authData.user = channel.options.user;\n }\n \n return authData;\n }\n \n /**\n * Запрос подписи с бэкенда\n * \n * Ваш бэкенд должен:\n * 1. Проверить авторизацию пользователя\n * 2. Сгенерировать HMAC-SHA256 подпись с секретным ключом\n * 3. Вернуть подпись клиенту\n */\n async function fetchSignature(channel) {\n const response = await fetch(config.authEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n credentials: 'include', // Включаем куки для авторизации\n body: JSON.stringify({\n channel_name: channel.name,\n socket_id: socketId.value,\n app_key: config.appKey,\n user_data: channel.options.user\n })\n });\n \n if (!response.ok) {\n const err = await response.json().catch(() => ({ error: 'Auth request failed' }));\n throw new Error(err.error || 'Failed to get signature');\n }\n \n const data = await response.json();\n return data.signature;\n }\n \n /**\n * Отписка от канала\n */\n function unsubscribe(channelName) {\n const fullChannelName = channelAliases.get(channelName) || formatChannelName(channelName);\n const channel = channels.get(fullChannelName);\n \n if (channel) {\n if (channel.subscribed && connectionState.value === ConnectionStates.CONNECTED) {\n sendMessage({\n event: 'pushler:unsubscribe',\n data: { channel: fullChannelName }\n });\n }\n \n channels.delete(fullChannelName);\n channelAliases.delete(channelName);\n }\n }\n \n /**\n * Получение канала по имени\n */\n function channel(channelName) {\n const fullChannelName = channelAliases.get(channelName) || formatChannelName(channelName);\n return channels.get(fullChannelName);\n }\n \n /**\n * Получение списка каналов\n */\n function getChannels() {\n return Array.from(channels.values()).map(ch => ({\n name: ch.originalName,\n fullName: ch.name,\n type: ch.type,\n subscribed: ch.subscribed\n }));\n }\n \n /**\n * Подписка на глобальное событие\n */\n function on(event, callback) {\n if (!eventListeners.has(event)) {\n eventListeners.set(event, []);\n }\n eventListeners.get(event).push(callback);\n }\n \n /**\n * Отписка от глобального события\n */\n function off(event, callback) {\n if (eventListeners.has(event)) {\n const list = eventListeners.get(event);\n const idx = list.indexOf(callback);\n if (idx > -1) list.splice(idx, 1);\n }\n }\n \n /**\n * Вызов глобального события\n */\n function emit(event, data) {\n if (eventListeners.has(event)) {\n eventListeners.get(event).forEach(cb => {\n try {\n cb(data);\n } catch (err) {\n console.error('[Pushler Vue] Event error:', err);\n }\n });\n }\n }\n \n // Автоматическое отключение при размонтировании компонента\n onUnmounted(() => {\n disconnect();\n });\n \n // Автоподключение если указано\n if (config.autoConnect && config.appKey) {\n connect();\n }\n \n return {\n // Состояние (readonly для защиты от внешних изменений)\n connectionState: readonly(connectionState),\n socketId: readonly(socketId),\n error: readonly(error),\n reconnectAttempts: readonly(reconnectAttempts),\n \n // Вычисляемые свойства\n isConnected,\n isConnecting,\n isReconnecting,\n \n // Методы\n connect,\n disconnect,\n subscribe,\n unsubscribe,\n channel,\n getChannels,\n on,\n off,\n \n // Утилиты\n formatChannelName,\n extractChannelName,\n getChannelType,\n \n // Константы\n ConnectionStates,\n ChannelTypes,\n };\n}\n\nexport default usePushler;\n","import { ref, reactive, onUnmounted, watch } from 'vue';\n\n/**\n * Vue composable для работы с отдельным каналом Pushler\n * \n * Можно использовать автономно или совместно с usePushler\n * \n * @param {Object} pushler - Инстанс usePushler\n * @param {string} channelName - Имя канала\n * @param {Object} options - Опции канала\n * @returns {Object} Реактивный объект канала с событиями\n */\nexport function usePushlerChannel(pushler, channelName, options = {}) {\n const channel = ref(null);\n const isSubscribed = ref(false);\n const lastEvent = ref(null);\n const events = reactive([]);\n const eventHandlers = new Map();\n \n /**\n * Максимальное количество событий в буфере\n */\n const maxEvents = options.maxEvents || 100;\n \n /**\n * Подписка на канал\n */\n function subscribe() {\n if (!pushler || !channelName) return;\n \n channel.value = pushler.subscribe(channelName, options);\n \n // Отслеживаем статус подписки\n channel.value.on('subscribed', () => {\n isSubscribed.value = true;\n });\n \n return channel.value;\n }\n \n /**\n * Отписка от канала\n */\n function unsubscribe() {\n if (pushler && channelName) {\n pushler.unsubscribe(channelName);\n channel.value = null;\n isSubscribed.value = false;\n }\n }\n \n /**\n * Подписка на событие канала\n * @param {string} eventName - Имя события\n * @param {Function} callback - Обработчик\n */\n function on(eventName, callback) {\n if (!channel.value) {\n subscribe();\n }\n \n const handler = (data) => {\n // Сохраняем последнее событие\n lastEvent.value = {\n event: eventName,\n data,\n timestamp: new Date()\n };\n \n // Добавляем в буфер событий\n events.unshift(lastEvent.value);\n if (events.length > maxEvents) {\n events.pop();\n }\n \n // Вызываем пользовательский обработчик\n callback(data);\n };\n \n eventHandlers.set(eventName, handler);\n channel.value.on(eventName, handler);\n \n return () => off(eventName);\n }\n \n /**\n * Отписка от события канала\n */\n function off(eventName) {\n if (channel.value && eventHandlers.has(eventName)) {\n channel.value.off(eventName, eventHandlers.get(eventName));\n eventHandlers.delete(eventName);\n }\n }\n \n /**\n * Очистка буфера событий\n */\n function clearEvents() {\n events.length = 0;\n lastEvent.value = null;\n }\n \n // Автоматическая подписка если указано\n if (options.autoSubscribe !== false && pushler?.isConnected?.value) {\n subscribe();\n }\n \n // Подписываемся при подключении\n if (pushler) {\n watch(() => pushler.isConnected.value, (connected) => {\n if (connected && options.autoSubscribe !== false && !channel.value) {\n subscribe();\n }\n });\n }\n \n // Автоматическая отписка при размонтировании\n onUnmounted(() => {\n unsubscribe();\n });\n \n return {\n channel,\n isSubscribed,\n lastEvent,\n events,\n \n subscribe,\n unsubscribe,\n on,\n off,\n clearEvents,\n };\n}\n\nexport default usePushlerChannel;\n","import { usePushler, ConnectionStates, ChannelTypes } from './usePushler';\n\n/**\n * Символ для инъекции Pushler\n */\nexport const PushlerKey = Symbol('pushler');\n\n/**\n * Vue Plugin для глобальной инициализации Pushler\n * \n * Использование:\n * \n * ```js\n * import { createApp } from 'vue';\n * import { PushlerPlugin } from '@pushler/vue';\n * \n * const app = createApp(App);\n * app.use(PushlerPlugin, {\n * appKey: 'your-app-key',\n * autoConnect: true\n * });\n * ```\n * \n * Затем в компонентах:\n * \n * ```js\n * import { inject } from 'vue';\n * import { PushlerKey } from '@pushler/vue';\n * \n * const pushler = inject(PushlerKey);\n * ```\n */\nexport const PushlerPlugin = {\n install(app, options = {}) {\n // Создаем глобальный инстанс Pushler\n const pushler = usePushler(options);\n \n // Предоставляем через provide/inject\n app.provide(PushlerKey, pushler);\n \n // Также добавляем как глобальное свойство (для Options API)\n app.config.globalProperties.$pushler = pushler;\n \n // Экспортируем константы\n app.config.globalProperties.$PushlerConnectionStates = ConnectionStates;\n app.config.globalProperties.$PushlerChannelTypes = ChannelTypes;\n }\n};\n\n/**\n * Хелпер для получения инстанса Pushler в setup()\n */\nexport function usePushlerInstance() {\n const pushler = inject(PushlerKey);\n if (!pushler) {\n throw new Error(\n '[Pushler Vue] No Pushler instance found. ' +\n 'Make sure to install PushlerPlugin or provide a Pushler instance.'\n );\n }\n return pushler;\n}\n\nexport default PushlerPlugin;\n","/**\n * Pushler Vue SDK\n * \n * Реактивный Vue.js SDK для работы с Pushler.ru WebSocket сервером\n * \n * @example Базовое использование\n * ```vue\n * <script setup>\n * import { usePushler } from '@pushler/vue';\n * \n * const pushler = usePushler({\n * appKey: 'your-app-key'\n * });\n * \n * // Подключение\n * pushler.connect();\n * \n * // Подписка на канал\n * const channel = pushler.subscribe('my-channel');\n * channel.on('message', (data) => {\n * console.log('Received:', data);\n * });\n * </script>\n * \n * <template>\n * <div>\n * <p>Status: {{ pushler.connectionState }}</p>\n * <p>Socket ID: {{ pushler.socketId }}</p>\n * </div>\n * </template>\n * ```\n * \n * @example С Vue Plugin\n * ```js\n * // main.js\n * import { createApp } from 'vue';\n * import { PushlerPlugin } from '@pushler/vue';\n * \n * const app = createApp(App);\n * app.use(PushlerPlugin, {\n * appKey: 'your-app-key',\n * autoConnect: true\n * });\n * ```\n */\n\n// Основные composables\nexport { usePushler, ConnectionStates, ChannelTypes } from './usePushler';\nexport { usePushlerChannel } from './usePushlerChannel';\n\n// Plugin\nexport { PushlerPlugin, PushlerKey, usePushlerInstance } from './plugin';\n\n// Default export\nimport { usePushler } from './usePushler';\nexport default usePushler;\n"],"names":["ref","reactive","computed","onUnmounted","readonly","watch"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pushler-vue.cjs.js","sources":["../src/usePushler.js","../src/usePushlerChannel.js","../src/plugin.js","../src/index.js"],"sourcesContent":["import { ref, reactive, readonly, onUnmounted, watch, computed } from 'vue';\n\n/**\n * Состояния подключения\n */\nexport const ConnectionStates = {\n CONNECTING: 'connecting',\n CONNECTED: 'connected',\n DISCONNECTED: 'disconnected',\n RECONNECTING: 'reconnecting',\n FAILED: 'failed'\n};\n\n/**\n * Типы каналов\n */\nexport const ChannelTypes = {\n PUBLIC: 'public',\n PRIVATE: 'private',\n PRESENCE: 'presence'\n};\n\n/**\n * Vue composable для работы с Pushler WebSocket\n * \n * @param {Object} options - Опции подключения\n * @param {string} options.appKey - Ключ приложения\n * @param {string} options.wsUrl - URL WebSocket сервера\n * @param {string} options.authEndpoint - Эндпоинт авторизации для приватных каналов\n * @param {Object} options.authHeaders - Статические заголовки для авторизации (например, { Authorization: 'Bearer token' })\n * @param {Function} options.getAuthHeaders - Функция для динамического получения заголовков авторизации\n * @param {boolean} options.autoConnect - Автоматическое подключение (по умолчанию false)\n * @param {number} options.reconnectDelay - Задержка переподключения в мс (по умолчанию 1000)\n * @param {number} options.maxReconnectAttempts - Максимум попыток переподключения (по умолчанию 5)\n * @returns {Object} Реактивный объект с методами и состоянием\n */\nexport function usePushler(options = {}) {\n // Реактивное состояние\n const connectionState = ref(ConnectionStates.DISCONNECTED);\n const socketId = ref(null);\n const error = ref(null);\n const reconnectAttempts = ref(0);\n \n // Каналы\n const channels = reactive(new Map());\n const channelAliases = reactive(new Map());\n \n // Внутренние переменные\n let socket = null;\n let reconnectTimer = null;\n const eventListeners = new Map();\n \n // Promise для ожидания подключения\n let connectionPromise = null;\n let connectionResolve = null;\n let connectionReject = null;\n \n // Конфигурация\n const appKey = options.appKey || '';\n const config = {\n appKey: appKey,\n // wsUrl формируется автоматически из appKey, но можно переопределить\n wsUrl: options.wsUrl || `wss://ws.pushler.ru/app/${appKey}`,\n authEndpoint: options.authEndpoint || '/pushler/auth',\n authHeaders: options.authHeaders || null,\n getAuthHeaders: options.getAuthHeaders || null,\n autoConnect: options.autoConnect || false,\n reconnectDelay: options.reconnectDelay || 1000,\n maxReconnectAttempts: options.maxReconnectAttempts || 5,\n };\n \n // Вычисляемые свойства\n const isConnected = computed(() => connectionState.value === ConnectionStates.CONNECTED);\n const isConnecting = computed(() => connectionState.value === ConnectionStates.CONNECTING);\n const isReconnecting = computed(() => connectionState.value === ConnectionStates.RECONNECTING);\n \n /**\n * Форматирование имени канала с префиксом appKey\n */\n function formatChannelName(channelName) {\n if (channelName.startsWith(config.appKey + ':')) {\n return channelName;\n }\n return `${config.appKey}:${channelName}`;\n }\n \n /**\n * Извлечение оригинального имени канала\n */\n function extractChannelName(fullChannelName) {\n const prefix = config.appKey + ':';\n if (fullChannelName.startsWith(prefix)) {\n return fullChannelName.substring(prefix.length);\n }\n return fullChannelName;\n }\n \n /**\n * Определение типа канала\n */\n function getChannelType(channelName) {\n const baseName = extractChannelName(channelName);\n if (baseName.startsWith('private-')) return ChannelTypes.PRIVATE;\n if (baseName.startsWith('presence-')) return ChannelTypes.PRESENCE;\n return ChannelTypes.PUBLIC;\n }\n \n /**\n * Подключение к WebSocket серверу\n * @param {Object} connectOptions - Опции подключения\n * @returns {Promise} Promise, который резолвится при успешном подключении\n */\n function connect(connectOptions = {}) {\n // Обновляем конфигурацию если переданы новые параметры\n if (connectOptions.appKey) config.appKey = connectOptions.appKey;\n if (connectOptions.wsUrl) config.wsUrl = connectOptions.wsUrl;\n if (connectOptions.authEndpoint) config.authEndpoint = connectOptions.authEndpoint;\n if (connectOptions.authHeaders) config.authHeaders = connectOptions.authHeaders;\n if (connectOptions.getAuthHeaders) config.getAuthHeaders = connectOptions.getAuthHeaders;\n \n // Если уже подключены - возвращаем резолвленный Promise\n if (connectionState.value === ConnectionStates.CONNECTED) {\n return Promise.resolve({ socketId: socketId.value });\n }\n \n // Если уже идёт подключение - возвращаем существующий Promise\n if (connectionState.value === ConnectionStates.CONNECTING && connectionPromise) {\n return connectionPromise;\n }\n \n // Создаём новый Promise для ожидания подключения\n connectionPromise = new Promise((resolve, reject) => {\n connectionResolve = resolve;\n connectionReject = reject;\n });\n \n connectionState.value = ConnectionStates.CONNECTING;\n error.value = null;\n \n try {\n // wsUrl уже содержит appKey из конфигурации\n console.log('[Pushler Vue] Connecting to:', config.wsUrl);\n socket = new WebSocket(config.wsUrl);\n setupSocketHandlers();\n } catch (err) {\n console.error('[Pushler Vue] Connection error:', err);\n connectionState.value = ConnectionStates.FAILED;\n error.value = err.message;\n if (connectionReject) {\n connectionReject(err);\n connectionPromise = null;\n connectionResolve = null;\n connectionReject = null;\n }\n }\n \n return connectionPromise;\n }\n \n /**\n * Ожидание установления соединения\n * @param {number} timeout - Таймаут в мс (по умолчанию 10000)\n * @returns {Promise} Promise с socketId\n */\n function waitForConnection(timeout = 10000) {\n // Если уже подключены\n if (connectionState.value === ConnectionStates.CONNECTED && socketId.value) {\n return Promise.resolve({ socketId: socketId.value });\n }\n \n // Если есть активный Promise подключения\n if (connectionPromise) {\n return Promise.race([\n connectionPromise,\n new Promise((_, reject) => \n setTimeout(() => reject(new Error('Connection timeout')), timeout)\n )\n ]);\n }\n \n // Если не подключаемся - начинаем подключение\n if (connectionState.value === ConnectionStates.DISCONNECTED) {\n return connect();\n }\n \n // Для других состояний создаём Promise, который ждёт connected события\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n off('connected', onConnected);\n off('error', onError);\n reject(new Error('Connection timeout'));\n }, timeout);\n \n const onConnected = (data) => {\n clearTimeout(timeoutId);\n off('error', onError);\n resolve(data);\n };\n \n const onError = (err) => {\n clearTimeout(timeoutId);\n off('connected', onConnected);\n reject(err);\n };\n \n on('connected', onConnected);\n on('error', onError);\n });\n }\n \n /**\n * Настройка обработчиков WebSocket\n */\n function setupSocketHandlers() {\n socket.onopen = () => {\n console.log('[Pushler Vue] WebSocket opened, waiting for connection_established...');\n };\n \n socket.onmessage = (event) => {\n handleMessage(event);\n };\n \n socket.onclose = (event) => {\n console.log('[Pushler Vue] WebSocket closed:', event.code, event.reason);\n connectionState.value = ConnectionStates.DISCONNECTED;\n socketId.value = null;\n \n // Автопереподключение\n if (event.code !== 1000 && reconnectAttempts.value < config.maxReconnectAttempts) {\n scheduleReconnect();\n }\n };\n \n socket.onerror = (err) => {\n console.error('[Pushler Vue] WebSocket error:', err);\n connectionState.value = ConnectionStates.FAILED;\n error.value = 'Connection failed';\n \n // Реджектим Promise подключения\n if (connectionReject) {\n connectionReject(new Error('Connection failed'));\n connectionPromise = null;\n connectionResolve = null;\n connectionReject = null;\n }\n };\n }\n \n /**\n * Обработка входящих сообщений\n */\n function handleMessage(event) {\n try {\n // Поддержка нескольких сообщений в одном event\n const messages = event.data.trim().split('\\n').filter(line => line.trim());\n \n for (const msgData of messages) {\n processMessage(JSON.parse(msgData));\n }\n } catch (err) {\n console.error('[Pushler Vue] Error parsing message:', err);\n }\n }\n \n /**\n * Обработка отдельного сообщения\n */\n function processMessage(message) {\n switch (message.event) {\n case 'pushler:connection_established':\n handleConnectionEstablished(message.data);\n break;\n case 'pushler:subscription_succeeded':\n handleSubscriptionSucceeded(message);\n break;\n case 'pushler:auth_success':\n handleAuthSuccess(message);\n break;\n case 'pushler:auth_error':\n handleAuthError(message);\n break;\n default:\n handleChannelMessage(message);\n }\n }\n \n /**\n * Обработка установления соединения\n */\n function handleConnectionEstablished(data) {\n socketId.value = data.socket_id;\n connectionState.value = ConnectionStates.CONNECTED;\n reconnectAttempts.value = 0;\n \n console.log('[Pushler Vue] Connected with socket ID:', socketId.value);\n \n // Резолвим Promise подключения\n if (connectionResolve) {\n connectionResolve({ socketId: socketId.value });\n connectionPromise = null;\n connectionResolve = null;\n connectionReject = null;\n }\n \n // Переподписка на все каналы\n resubscribeAllChannels();\n \n emit('connected', { socketId: socketId.value });\n }\n \n /**\n * Переподписка на все каналы\n */\n function resubscribeAllChannels() {\n for (const [name, channel] of channels.entries()) {\n channel.subscribed = false;\n performChannelSubscription(channel);\n }\n }\n \n /**\n * Обработка успешной подписки\n */\n function handleSubscriptionSucceeded(message) {\n const channel = channels.get(message.channel);\n if (channel) {\n channel.subscribed = true;\n channel.emit('subscribed', message.data || {});\n }\n }\n \n /**\n * Обработка успешной авторизации\n */\n function handleAuthSuccess(message) {\n const channel = channels.get(message.data.channel);\n if (channel) {\n channel.subscribed = true;\n channel.emit('subscribed', message.data);\n }\n emit('auth_success', message.data);\n }\n \n /**\n * Обработка ошибки авторизации\n */\n function handleAuthError(message) {\n error.value = message.data.error;\n emit('auth_error', message.data);\n }\n \n /**\n * Обработка сообщения канала\n */\n function handleChannelMessage(message) {\n const { channel: channelName, event, data } = message;\n const channel = channels.get(channelName);\n \n if (channel) {\n channel.emit(event, data);\n }\n \n emit('message', { \n channel: extractChannelName(channelName), \n event, \n data \n });\n }\n \n /**\n * Планирование переподключения\n */\n function scheduleReconnect() {\n if (reconnectTimer) {\n clearTimeout(reconnectTimer);\n }\n \n reconnectAttempts.value++;\n connectionState.value = ConnectionStates.RECONNECTING;\n \n const delay = config.reconnectDelay * reconnectAttempts.value;\n console.log(`[Pushler Vue] Reconnecting in ${delay}ms (attempt ${reconnectAttempts.value}/${config.maxReconnectAttempts})`);\n \n reconnectTimer = setTimeout(() => {\n connect();\n }, delay);\n }\n \n /**\n * Отключение от сервера\n */\n function disconnect() {\n if (reconnectTimer) {\n clearTimeout(reconnectTimer);\n reconnectTimer = null;\n }\n \n if (socket) {\n socket.close(1000, 'User disconnect');\n socket = null;\n }\n \n connectionState.value = ConnectionStates.DISCONNECTED;\n socketId.value = null;\n channels.clear();\n channelAliases.clear();\n reconnectAttempts.value = 0;\n \n emit('disconnected');\n }\n \n /**\n * Отправка сообщения через WebSocket\n */\n function sendMessage(message) {\n if (socket && socket.readyState === WebSocket.OPEN) {\n socket.send(JSON.stringify(message));\n }\n }\n \n /**\n * Подписка на канал\n * @param {string} channelName - Имя канала\n * @param {Object} options - Опции (signature для приватных, user для presence)\n * @returns {Object} Реактивный объект канала\n */\n function subscribe(channelName, subscribeOptions = {}) {\n const fullChannelName = formatChannelName(channelName);\n \n if (channels.has(fullChannelName)) {\n return channels.get(fullChannelName);\n }\n \n // Создаем реактивный канал\n const channel = reactive({\n name: fullChannelName,\n originalName: channelName,\n type: getChannelType(channelName),\n subscribed: false,\n options: subscribeOptions,\n listeners: new Map(),\n \n // Методы канала\n on(event, callback) {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, []);\n }\n this.listeners.get(event).push(callback);\n return this;\n },\n \n off(event, callback) {\n if (this.listeners.has(event)) {\n const list = this.listeners.get(event);\n const idx = list.indexOf(callback);\n if (idx > -1) list.splice(idx, 1);\n }\n return this;\n },\n \n emit(event, data) {\n if (this.listeners.has(event)) {\n this.listeners.get(event).forEach(cb => {\n try {\n cb(data);\n } catch (err) {\n console.error('[Pushler Vue] Channel event error:', err);\n }\n });\n }\n },\n \n unsubscribe() {\n unsubscribe(channelName);\n }\n });\n \n channels.set(fullChannelName, channel);\n channelAliases.set(channelName, fullChannelName);\n \n // Подписываемся если уже подключены\n if (connectionState.value === ConnectionStates.CONNECTED) {\n performChannelSubscription(channel);\n }\n \n return channel;\n }\n \n /**\n * Выполнение подписки на канал\n */\n async function performChannelSubscription(channel) {\n if (connectionState.value !== ConnectionStates.CONNECTED) {\n return;\n }\n \n const channelType = channel.type;\n \n // Публичные каналы\n if (channelType === ChannelTypes.PUBLIC) {\n sendMessage({\n event: 'pushler:subscribe',\n data: {\n channel: channel.name,\n app_key: config.appKey\n }\n });\n return;\n }\n \n // Приватные и presence каналы требуют авторизации\n try {\n const authData = await getAuthData(channel);\n sendMessage({\n event: 'pushler:auth',\n data: authData\n });\n } catch (err) {\n console.error('[Pushler Vue] Auth error:', err);\n error.value = err.message;\n }\n }\n \n /**\n * Получение данных авторизации для приватных/presence каналов\n * \n * Для приватных каналов подпись ДОЛЖНА быть получена с вашего бэкенда,\n * либо передана в options.signature при подписке.\n * \n * НИКОГДА не храните секретный ключ в клиентском коде!\n */\n async function getAuthData(channel) {\n if (!socketId.value) {\n throw new Error('Socket ID not available');\n }\n \n const authData = {\n app_key: config.appKey,\n channel: channel.name,\n socket_id: socketId.value\n };\n \n // Если подпись уже предоставлена в options\n if (channel.options.signature) {\n authData.signature = channel.options.signature;\n } else {\n // Запрашиваем подпись с бэкенда\n authData.signature = await fetchSignature(channel);\n }\n \n // Данные пользователя для presence каналов\n if (channel.type === ChannelTypes.PRESENCE && channel.options.user) {\n authData.user = channel.options.user;\n }\n \n return authData;\n }\n \n /**\n * Получение заголовков для авторизации\n */\n function getAuthRequestHeaders() {\n const headers = { 'Content-Type': 'application/json' };\n \n // Динамические заголовки имеют приоритет\n if (typeof config.getAuthHeaders === 'function') {\n const dynamicHeaders = config.getAuthHeaders();\n Object.assign(headers, dynamicHeaders);\n } else if (config.authHeaders) {\n // Статические заголовки\n Object.assign(headers, config.authHeaders);\n }\n \n return headers;\n }\n \n /**\n * Запрос подписи с бэкенда\n * \n * Ваш бэкенд должен:\n * 1. Проверить авторизацию пользователя\n * 2. Сгенерировать HMAC-SHA256 подпись с секретным ключом\n * 3. Вернуть подпись клиенту\n */\n async function fetchSignature(channel) {\n const headers = getAuthRequestHeaders();\n const hasAuthHeaders = config.authHeaders || config.getAuthHeaders;\n \n const response = await fetch(config.authEndpoint, {\n method: 'POST',\n headers,\n // Если есть authHeaders, не используем credentials (JWT режим)\n // Если нет — используем cookies для обратной совместимости\n ...(hasAuthHeaders ? {} : { credentials: 'include' }),\n body: JSON.stringify({\n channel_name: channel.name,\n socket_id: socketId.value,\n app_key: config.appKey,\n user_data: channel.options.user\n })\n });\n \n if (!response.ok) {\n const err = await response.json().catch(() => ({ error: 'Auth request failed' }));\n throw new Error(err.error || 'Failed to get signature');\n }\n \n const data = await response.json();\n return data.signature;\n }\n \n /**\n * Отписка от канала\n */\n function unsubscribe(channelName) {\n const fullChannelName = channelAliases.get(channelName) || formatChannelName(channelName);\n const channel = channels.get(fullChannelName);\n \n if (channel) {\n if (channel.subscribed && connectionState.value === ConnectionStates.CONNECTED) {\n sendMessage({\n event: 'pushler:unsubscribe',\n data: { channel: fullChannelName }\n });\n }\n \n channels.delete(fullChannelName);\n channelAliases.delete(channelName);\n }\n }\n \n /**\n * Получение канала по имени\n */\n function channel(channelName) {\n const fullChannelName = channelAliases.get(channelName) || formatChannelName(channelName);\n return channels.get(fullChannelName);\n }\n \n /**\n * Получение списка каналов\n */\n function getChannels() {\n return Array.from(channels.values()).map(ch => ({\n name: ch.originalName,\n fullName: ch.name,\n type: ch.type,\n subscribed: ch.subscribed\n }));\n }\n \n /**\n * Подписка на глобальное событие\n */\n function on(event, callback) {\n if (!eventListeners.has(event)) {\n eventListeners.set(event, []);\n }\n eventListeners.get(event).push(callback);\n }\n \n /**\n * Отписка от глобального события\n */\n function off(event, callback) {\n if (eventListeners.has(event)) {\n const list = eventListeners.get(event);\n const idx = list.indexOf(callback);\n if (idx > -1) list.splice(idx, 1);\n }\n }\n \n /**\n * Вызов глобального события\n */\n function emit(event, data) {\n if (eventListeners.has(event)) {\n eventListeners.get(event).forEach(cb => {\n try {\n cb(data);\n } catch (err) {\n console.error('[Pushler Vue] Event error:', err);\n }\n });\n }\n }\n \n // Автоматическое отключение при размонтировании компонента\n onUnmounted(() => {\n disconnect();\n });\n \n // Автоподключение если указано\n if (config.autoConnect && config.appKey) {\n connect();\n }\n \n return {\n // Состояние (readonly для защиты от внешних изменений)\n connectionState: readonly(connectionState),\n socketId: readonly(socketId),\n error: readonly(error),\n reconnectAttempts: readonly(reconnectAttempts),\n \n // Вычисляемые свойства\n isConnected,\n isConnecting,\n isReconnecting,\n \n // Методы\n connect,\n disconnect,\n waitForConnection,\n subscribe,\n unsubscribe,\n channel,\n getChannels,\n on,\n off,\n \n // Утилиты\n formatChannelName,\n extractChannelName,\n getChannelType,\n \n // Константы\n ConnectionStates,\n ChannelTypes,\n };\n}\n\nexport default usePushler;\n","import { ref, reactive, onUnmounted, watch } from 'vue';\n\n/**\n * Vue composable для работы с отдельным каналом Pushler\n * \n * Можно использовать автономно или совместно с usePushler\n * \n * @param {Object} pushler - Инстанс usePushler\n * @param {string} channelName - Имя канала\n * @param {Object} options - Опции канала\n * @returns {Object} Реактивный объект канала с событиями\n */\nexport function usePushlerChannel(pushler, channelName, options = {}) {\n const channel = ref(null);\n const isSubscribed = ref(false);\n const lastEvent = ref(null);\n const events = reactive([]);\n const eventHandlers = new Map();\n \n /**\n * Максимальное количество событий в буфере\n */\n const maxEvents = options.maxEvents || 100;\n \n /**\n * Подписка на канал\n */\n function subscribe() {\n if (!pushler || !channelName) return;\n \n channel.value = pushler.subscribe(channelName, options);\n \n // Отслеживаем статус подписки\n channel.value.on('subscribed', () => {\n isSubscribed.value = true;\n });\n \n return channel.value;\n }\n \n /**\n * Отписка от канала\n */\n function unsubscribe() {\n if (pushler && channelName) {\n pushler.unsubscribe(channelName);\n channel.value = null;\n isSubscribed.value = false;\n }\n }\n \n /**\n * Подписка на событие канала\n * @param {string} eventName - Имя события\n * @param {Function} callback - Обработчик\n */\n function on(eventName, callback) {\n if (!channel.value) {\n subscribe();\n }\n \n const handler = (data) => {\n // Сохраняем последнее событие\n lastEvent.value = {\n event: eventName,\n data,\n timestamp: new Date()\n };\n \n // Добавляем в буфер событий\n events.unshift(lastEvent.value);\n if (events.length > maxEvents) {\n events.pop();\n }\n \n // Вызываем пользовательский обработчик\n callback(data);\n };\n \n eventHandlers.set(eventName, handler);\n channel.value.on(eventName, handler);\n \n return () => off(eventName);\n }\n \n /**\n * Отписка от события канала\n */\n function off(eventName) {\n if (channel.value && eventHandlers.has(eventName)) {\n channel.value.off(eventName, eventHandlers.get(eventName));\n eventHandlers.delete(eventName);\n }\n }\n \n /**\n * Очистка буфера событий\n */\n function clearEvents() {\n events.length = 0;\n lastEvent.value = null;\n }\n \n // Автоматическая подписка если указано\n if (options.autoSubscribe !== false && pushler?.isConnected?.value) {\n subscribe();\n }\n \n // Подписываемся при подключении\n if (pushler) {\n watch(() => pushler.isConnected.value, (connected) => {\n if (connected && options.autoSubscribe !== false && !channel.value) {\n subscribe();\n }\n });\n }\n \n // Автоматическая отписка при размонтировании\n onUnmounted(() => {\n unsubscribe();\n });\n \n return {\n channel,\n isSubscribed,\n lastEvent,\n events,\n \n subscribe,\n unsubscribe,\n on,\n off,\n clearEvents,\n };\n}\n\nexport default usePushlerChannel;\n","import { usePushler, ConnectionStates, ChannelTypes } from './usePushler';\n\n/**\n * Символ для инъекции Pushler\n */\nexport const PushlerKey = Symbol('pushler');\n\n/**\n * Vue Plugin для глобальной инициализации Pushler\n * \n * Использование:\n * \n * ```js\n * import { createApp } from 'vue';\n * import { PushlerPlugin } from '@pushler/vue';\n * \n * const app = createApp(App);\n * app.use(PushlerPlugin, {\n * appKey: 'your-app-key',\n * autoConnect: true\n * });\n * ```\n * \n * Затем в компонентах:\n * \n * ```js\n * import { inject } from 'vue';\n * import { PushlerKey } from '@pushler/vue';\n * \n * const pushler = inject(PushlerKey);\n * ```\n */\nexport const PushlerPlugin = {\n install(app, options = {}) {\n // Создаем глобальный инстанс Pushler\n const pushler = usePushler(options);\n \n // Предоставляем через provide/inject\n app.provide(PushlerKey, pushler);\n \n // Также добавляем как глобальное свойство (для Options API)\n app.config.globalProperties.$pushler = pushler;\n \n // Экспортируем константы\n app.config.globalProperties.$PushlerConnectionStates = ConnectionStates;\n app.config.globalProperties.$PushlerChannelTypes = ChannelTypes;\n }\n};\n\n/**\n * Хелпер для получения инстанса Pushler в setup()\n */\nexport function usePushlerInstance() {\n const pushler = inject(PushlerKey);\n if (!pushler) {\n throw new Error(\n '[Pushler Vue] No Pushler instance found. ' +\n 'Make sure to install PushlerPlugin or provide a Pushler instance.'\n );\n }\n return pushler;\n}\n\nexport default PushlerPlugin;\n","/**\n * Pushler Vue SDK\n * \n * Реактивный Vue.js SDK для работы с Pushler.ru WebSocket сервером\n * \n * @example Базовое использование\n * ```vue\n * <script setup>\n * import { usePushler } from '@pushler/vue';\n * \n * const pushler = usePushler({\n * appKey: 'your-app-key'\n * });\n * \n * // Подключение\n * pushler.connect();\n * \n * // Подписка на канал\n * const channel = pushler.subscribe('my-channel');\n * channel.on('message', (data) => {\n * console.log('Received:', data);\n * });\n * </script>\n * \n * <template>\n * <div>\n * <p>Status: {{ pushler.connectionState }}</p>\n * <p>Socket ID: {{ pushler.socketId }}</p>\n * </div>\n * </template>\n * ```\n * \n * @example С Vue Plugin\n * ```js\n * // main.js\n * import { createApp } from 'vue';\n * import { PushlerPlugin } from '@pushler/vue';\n * \n * const app = createApp(App);\n * app.use(PushlerPlugin, {\n * appKey: 'your-app-key',\n * autoConnect: true\n * });\n * ```\n */\n\n// Основные composables\nexport { usePushler, ConnectionStates, ChannelTypes } from './usePushler';\nexport { usePushlerChannel } from './usePushlerChannel';\n\n// Plugin\nexport { PushlerPlugin, PushlerKey, usePushlerInstance } from './plugin';\n\n// Default export\nimport { usePushler } from './usePushler';\nexport default usePushler;\n"],"names":["ref","reactive","computed","onUnmounted","readonly","watch"],"mappings":"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"}
|