@pushler/js 1.0.2 → 1.1.1

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.
@@ -203,6 +203,8 @@ class PushlerClient {
203
203
  this.wsUrl = options.wsUrl || `wss://ws.pushler.ru/app/${this.appKey}`;
204
204
  this.apiUrl = options.apiUrl;
205
205
  this.authEndpoint = options.authEndpoint || '/pushler/auth'; // Путь для авторизации каналов
206
+ this.authHeaders = options.authHeaders || null; // Кастомные заголовки для авторизации
207
+ this.getAuthHeaders = options.getAuthHeaders || null; // Функция для динамических заголовков
206
208
  this.autoConnect = options.autoConnect !== false;
207
209
  this.reconnectDelay = options.reconnectDelay || 1000;
208
210
  this.maxReconnectAttempts = options.maxReconnectAttempts || 5;
@@ -217,6 +219,11 @@ class PushlerClient {
217
219
  this.reconnectTimer = null;
218
220
  this.authTimeout = null;
219
221
 
222
+ // Promise для ожидания подключения
223
+ this.connectionPromise = null;
224
+ this.connectionResolve = null;
225
+ this.connectionReject = null;
226
+
220
227
  // Автоматическое подключение
221
228
  if (this.autoConnect) {
222
229
  this.connect();
@@ -252,13 +259,25 @@ class PushlerClient {
252
259
 
253
260
  /**
254
261
  * Подключение к WebSocket серверу
262
+ * @returns {Promise} Promise, который резолвится при успешном подключении
255
263
  */
256
264
  connect() {
257
- if (this.connectionState === ConnectionStates.CONNECTED ||
258
- this.connectionState === ConnectionStates.CONNECTING) {
259
- return;
265
+ // Если уже подключены - возвращаем резолвленный Promise
266
+ if (this.connectionState === ConnectionStates.CONNECTED) {
267
+ return Promise.resolve({ socketId: this.socketId });
268
+ }
269
+
270
+ // Если уже идёт подключение - возвращаем существующий Promise
271
+ if (this.connectionState === ConnectionStates.CONNECTING && this.connectionPromise) {
272
+ return this.connectionPromise;
260
273
  }
261
274
 
275
+ // Создаём новый Promise для ожидания подключения
276
+ this.connectionPromise = new Promise((resolve, reject) => {
277
+ this.connectionResolve = resolve;
278
+ this.connectionReject = reject;
279
+ });
280
+
262
281
  this.connectionState = ConnectionStates.CONNECTING;
263
282
  this.emit(Events.CONNECTION_STATE_CHANGED, this.connectionState);
264
283
 
@@ -273,7 +292,66 @@ class PushlerClient {
273
292
  } catch (error) {
274
293
  console.error('PushlerClient: Error creating WebSocket connection:', error);
275
294
  this.handleConnectionError(error);
295
+ if (this.connectionReject) {
296
+ this.connectionReject(error);
297
+ this.connectionPromise = null;
298
+ this.connectionResolve = null;
299
+ this.connectionReject = null;
300
+ }
276
301
  }
302
+
303
+ return this.connectionPromise;
304
+ }
305
+
306
+ /**
307
+ * Ожидание установления соединения
308
+ * @param {number} timeout - Таймаут в мс (по умолчанию 10000)
309
+ * @returns {Promise} Promise с socketId
310
+ */
311
+ waitForConnection(timeout = 10000) {
312
+ // Если уже подключены
313
+ if (this.connectionState === ConnectionStates.CONNECTED && this.socketId) {
314
+ return Promise.resolve({ socketId: this.socketId });
315
+ }
316
+
317
+ // Если есть активный Promise подключения
318
+ if (this.connectionPromise) {
319
+ return Promise.race([
320
+ this.connectionPromise,
321
+ new Promise((_, reject) =>
322
+ setTimeout(() => reject(new Error('Connection timeout')), timeout)
323
+ )
324
+ ]);
325
+ }
326
+
327
+ // Если не подключаемся - начинаем подключение
328
+ if (this.connectionState === ConnectionStates.DISCONNECTED) {
329
+ return this.connect();
330
+ }
331
+
332
+ // Для других состояний создаём Promise, который ждёт connected события
333
+ return new Promise((resolve, reject) => {
334
+ const timeoutId = setTimeout(() => {
335
+ this.off(Events.CONNECTED, onConnected);
336
+ this.off(Events.ERROR, onError);
337
+ reject(new Error('Connection timeout'));
338
+ }, timeout);
339
+
340
+ const onConnected = (data) => {
341
+ clearTimeout(timeoutId);
342
+ this.off(Events.ERROR, onError);
343
+ resolve(data);
344
+ };
345
+
346
+ const onError = (err) => {
347
+ clearTimeout(timeoutId);
348
+ this.off(Events.CONNECTED, onConnected);
349
+ reject(err);
350
+ };
351
+
352
+ this.on(Events.CONNECTED, onConnected);
353
+ this.on(Events.ERROR, onError);
354
+ });
277
355
  }
278
356
 
279
357
  /**
@@ -363,6 +441,14 @@ class PushlerClient {
363
441
 
364
442
  console.log('Connection established with socket ID:', this.socketId);
365
443
 
444
+ // Резолвим Promise подключения
445
+ if (this.connectionResolve) {
446
+ this.connectionResolve({ socketId: this.socketId });
447
+ this.connectionPromise = null;
448
+ this.connectionResolve = null;
449
+ this.connectionReject = null;
450
+ }
451
+
366
452
  // Переподписываемся на все каналы после переподключения
367
453
  this.resubscribeAllChannels();
368
454
 
@@ -539,6 +625,24 @@ class PushlerClient {
539
625
  }
540
626
  }
541
627
 
628
+ /**
629
+ * Получение заголовков для авторизации
630
+ */
631
+ getAuthRequestHeaders() {
632
+ const headers = { 'Content-Type': 'application/json' };
633
+
634
+ // Динамические заголовки имеют приоритет
635
+ if (typeof this.getAuthHeaders === 'function') {
636
+ const dynamicHeaders = this.getAuthHeaders();
637
+ Object.assign(headers, dynamicHeaders);
638
+ } else if (this.authHeaders) {
639
+ // Статические заголовки
640
+ Object.assign(headers, this.authHeaders);
641
+ }
642
+
643
+ return headers;
644
+ }
645
+
542
646
  /**
543
647
  * Получение подписи с бэкенда
544
648
  */
@@ -548,11 +652,15 @@ class PushlerClient {
548
652
  ? this.authEndpoint
549
653
  : `${this.apiUrl}${this.authEndpoint}`;
550
654
 
655
+ const headers = this.getAuthRequestHeaders();
656
+ const hasAuthHeaders = this.authHeaders || this.getAuthHeaders;
657
+
551
658
  const response = await fetch(authUrl, {
552
659
  method: 'POST',
553
- headers: {
554
- 'Content-Type': 'application/json',
555
- },
660
+ headers,
661
+ // Если есть authHeaders, не используем credentials (JWT режим)
662
+ // Если нет — используем cookies
663
+ ...(hasAuthHeaders ? {} : { credentials: 'include' }),
556
664
  body: JSON.stringify({
557
665
  channel_name: channelName,
558
666
  socket_id: socketId,
@@ -562,7 +670,7 @@ class PushlerClient {
562
670
  });
563
671
 
564
672
  if (!response.ok) {
565
- const error = await response.json();
673
+ const error = await response.json().catch(() => ({ error: 'Auth request failed' }));
566
674
  throw new Error(error.error || 'Failed to get channel signature');
567
675
  }
568
676
 
@@ -695,6 +803,14 @@ class PushlerClient {
695
803
 
696
804
  console.error('PushlerClient connection error:', fullErrorMessage);
697
805
 
806
+ // Реджектим Promise подключения
807
+ if (this.connectionReject) {
808
+ this.connectionReject(new Error(fullErrorMessage));
809
+ this.connectionPromise = null;
810
+ this.connectionResolve = null;
811
+ this.connectionReject = null;
812
+ }
813
+
698
814
  this.emit(Events.ERROR, {
699
815
  code: ErrorCodes.CONNECTION_FAILED,
700
816
  message: fullErrorMessage,
@@ -802,12 +918,13 @@ var PushlerClient$1 = PushlerClient;
802
918
  * Используется на сервере Node.js для отправки событий в каналы
803
919
  */
804
920
  class PushlerServer {
921
+ static API_URL = 'https://api.pushler.ru';
922
+
805
923
  /**
806
924
  * @param {Object} options - Параметры клиента
807
925
  * @param {string} options.appKey - Ключ приложения (key_xxx)
808
926
  * @param {string} options.appSecret - Секрет приложения (secret_xxx)
809
- * @param {string} [options.apiUrl='http://localhost:8000/api'] - URL API сервера
810
- * @param {number} [options.timeout=30000] - Таймаут запроса в мс
927
+ * @param {number} [options.timeout=10000] - Таймаут запроса в мс
811
928
  */
812
929
  constructor(options = {}) {
813
930
  if (!options.appKey) {
@@ -819,8 +936,7 @@ class PushlerServer {
819
936
 
820
937
  this.appKey = options.appKey;
821
938
  this.appSecret = options.appSecret;
822
- this.apiUrl = (options.apiUrl || 'http://localhost:8000/api').replace(/\/$/, '');
823
- this.timeout = options.timeout || 30000;
939
+ this.timeout = options.timeout || 10000;
824
940
  }
825
941
 
826
942
  /**
@@ -1103,7 +1219,7 @@ class PushlerServer {
1103
1219
  * @returns {Promise<Object>} Результат запроса
1104
1220
  */
1105
1221
  async makeSignedRequest(method, endpoint, data = null) {
1106
- const url = this.apiUrl + endpoint;
1222
+ const url = PushlerServer.API_URL + endpoint;
1107
1223
  const timestamp = Math.floor(Date.now() / 1000);
1108
1224
  const body = data ? JSON.stringify(data) : '';
1109
1225
  const signature = this.generateApiSignature(body, timestamp);
@@ -1151,7 +1267,7 @@ class PushlerServer {
1151
1267
  * @returns {Promise<Object>} Результат запроса
1152
1268
  */
1153
1269
  async makeHttpRequest(method, endpoint, data = null) {
1154
- const url = this.apiUrl + endpoint;
1270
+ const url = PushlerServer.API_URL + endpoint;
1155
1271
 
1156
1272
  const headers = {
1157
1273
  'Content-Type': 'application/json',
@@ -1192,7 +1308,7 @@ class PushlerServer {
1192
1308
  * @returns {string}
1193
1309
  */
1194
1310
  getApiUrl() {
1195
- return this.apiUrl;
1311
+ return PushlerServer.API_URL;
1196
1312
  }
1197
1313
  }
1198
1314
 
@@ -1 +1 @@
1
- {"version":3,"file":"pushler-ru.esm.js","sources":["../src/constants.js","../src/Channel.js","../src/PushlerClient.js","../src/PushlerServer.js","../src/utils.js","../src/index.js"],"sourcesContent":["/**\r\n * Типы каналов\r\n */\r\nexport const ChannelTypes = {\r\n PUBLIC: 'public',\r\n PRIVATE: 'private',\r\n PRESENCE: 'presence'\r\n};\r\n\r\n/**\r\n * Состояния подключения\r\n */\r\nexport const ConnectionStates = {\r\n CONNECTING: 'connecting',\r\n CONNECTED: 'connected',\r\n DISCONNECTED: 'disconnected',\r\n RECONNECTING: 'reconnecting',\r\n FAILED: 'failed'\r\n};\r\n\r\n/**\r\n * События WebSocket\r\n */\r\nexport const Events = {\r\n // События подключения\r\n CONNECTION_STATE_CHANGED: 'connection_state_changed',\r\n CONNECTED: 'connected',\r\n DISCONNECTED: 'disconnected',\r\n ERROR: 'error',\r\n \r\n // События каналов\r\n CHANNEL_SUBSCRIBED: 'channel_subscribed',\r\n CHANNEL_UNSUBSCRIBED: 'channel_unsubscribed',\r\n CHANNEL_AUTH_SUCCESS: 'pushler:auth_success',\r\n CHANNEL_AUTH_ERROR: 'pushler:auth_error',\r\n \r\n // События сообщений\r\n MESSAGE_RECEIVED: 'message_received'\r\n};\r\n\r\n/**\r\n * Коды ошибок\r\n */\r\nexport const ErrorCodes = {\r\n INVALID_APP_KEY: 'INVALID_APP_KEY',\r\n INVALID_SIGNATURE: 'INVALID_SIGNATURE',\r\n AUTHENTICATION_FAILED: 'AUTHENTICATION_FAILED',\r\n CHANNEL_ACCESS_DENIED: 'CHANNEL_ACCESS_DENIED',\r\n CONNECTION_FAILED: 'CONNECTION_FAILED',\r\n AUTHENTICATION_TIMEOUT: 'AUTHENTICATION_TIMEOUT'\r\n};\r\n","import { ChannelTypes, Events } from './constants';\n\n/**\n * Класс для управления каналом\n */\nclass Channel {\n constructor(client, name, options = {}) {\n this.client = client;\n this.name = name;\n this.options = options;\n this.subscribed = false;\n this.eventListeners = new Map();\n this.presenceData = null;\n }\n\n /**\n * Подписка на событие канала\n */\n on(event, callback) {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, []);\n }\n this.eventListeners.get(event).push(callback);\n }\n\n /**\n * Отписка от события канала\n */\n off(event, callback) {\n if (this.eventListeners.has(event)) {\n const listeners = this.eventListeners.get(event);\n const index = listeners.indexOf(callback);\n if (index > -1) {\n listeners.splice(index, 1);\n }\n }\n }\n\n /**\n * Вызов события канала\n */\n emit(event, data) {\n if (this.eventListeners.has(event)) {\n this.eventListeners.get(event).forEach(callback => {\n try {\n callback(data);\n } catch (error) {\n console.error('Error in channel event listener:', error);\n }\n });\n }\n }\n\n /**\n * Обработка успешной аутентификации\n */\n handleAuthSuccess(data) {\n this.subscribed = true;\n this.emit(Events.CHANNEL_SUBSCRIBED, data);\n \n // Для presence каналов сохраняем данные пользователя\n if (data.user) {\n this.presenceData = data.user;\n }\n }\n\n /**\n * Обработка входящих сообщений\n */\n handleMessage(event, data) {\n this.emit(event, data);\n }\n\n /**\n * Отписка от канала\n */\n unsubscribe() {\n if (this.subscribed && this.client.connectionState === 'connected') {\n this.client.sendMessage({\n event: 'pushler:unsubscribe',\n data: { channel: this.name }\n });\n }\n \n this.subscribed = false;\n this.emit(Events.CHANNEL_UNSUBSCRIBED);\n }\n\n /**\n * Проверка подписки на канал\n */\n isSubscribed() {\n return this.subscribed;\n }\n\n /**\n * Получение данных присутствия (для presence каналов)\n */\n getPresenceData() {\n return this.presenceData;\n }\n\n /**\n * Получение типа канала\n * Учитывает, что имя канала может иметь формат {appKey}:{channelName}\n */\n getType() {\n // Извлекаем базовое имя канала (без appKey)\n const baseName = this.getBaseName();\n \n if (baseName.startsWith('private-')) {\n return ChannelTypes.PRIVATE;\n }\n if (baseName.startsWith('presence-')) {\n return ChannelTypes.PRESENCE;\n }\n return ChannelTypes.PUBLIC;\n }\n\n /**\n * Получение базового имени канала (без appKey префикса)\n * @returns {string} Базовое имя канала\n */\n getBaseName() {\n // Имя канала может быть в формате {appKey}:{channelName}\n const colonIndex = this.name.indexOf(':');\n if (colonIndex !== -1) {\n return this.name.substring(colonIndex + 1);\n }\n return this.name;\n }\n\n /**\n * Получение полного имени канала (с appKey)\n * @returns {string} Полное имя канала\n */\n getFullName() {\n return this.name;\n }\n}\n\nexport default Channel;\n","import Channel from './Channel';\nimport { ChannelTypes, ConnectionStates, Events, ErrorCodes } from './constants';\n\n/**\n * Основной класс для подключения к Pushler.ru WebSocket серверу\n */\nclass PushlerClient {\n constructor(options = {}) {\n this.appKey = options.appKey;\n // wsUrl формируется автоматически на основе appKey, но можно переопределить для тестирования\n this.wsUrl = options.wsUrl || `wss://ws.pushler.ru/app/${this.appKey}`;\n this.apiUrl = options.apiUrl;\n this.authEndpoint = options.authEndpoint || '/pushler/auth'; // Путь для авторизации каналов\n this.autoConnect = options.autoConnect !== false;\n this.reconnectDelay = options.reconnectDelay || 1000;\n this.maxReconnectAttempts = options.maxReconnectAttempts || 5;\n \n this.connectionState = ConnectionStates.DISCONNECTED;\n this.socket = null;\n this.socketId = null;\n this.channels = new Map(); // Хранит каналы по полному имени (с appKey)\n this.channelAliases = new Map(); // Маппинг оригинальное имя -> полное имя\n this.eventListeners = new Map();\n this.reconnectAttempts = 0;\n this.reconnectTimer = null;\n this.authTimeout = null;\n \n // Автоматическое подключение\n if (this.autoConnect) {\n this.connect();\n }\n }\n\n /**\n * Формирование полного имени канала с префиксом appKey\n * Формат: {appKey}:{channelName}\n * @param {string} channelName - Оригинальное имя канала\n * @returns {string} Полное имя канала\n */\n formatChannelName(channelName) {\n // Если канал уже содержит appKey, возвращаем как есть\n if (channelName.startsWith(this.appKey + ':')) {\n return channelName;\n }\n return `${this.appKey}:${channelName}`;\n }\n\n /**\n * Извлечение оригинального имени канала (без appKey)\n * @param {string} fullChannelName - Полное имя канала\n * @returns {string} Оригинальное имя канала\n */\n extractChannelName(fullChannelName) {\n const prefix = this.appKey + ':';\n if (fullChannelName.startsWith(prefix)) {\n return fullChannelName.substring(prefix.length);\n }\n return fullChannelName;\n }\n\n /**\n * Подключение к WebSocket серверу\n */\n connect() {\n if (this.connectionState === ConnectionStates.CONNECTED || \n this.connectionState === ConnectionStates.CONNECTING) {\n return;\n }\n\n this.connectionState = ConnectionStates.CONNECTING;\n this.emit(Events.CONNECTION_STATE_CHANGED, this.connectionState);\n\n try {\n if (!this.wsUrl) {\n throw new Error('WebSocket URL is not configured');\n }\n \n console.log(`PushlerClient: Connecting to ${this.wsUrl}`);\n this.socket = new WebSocket(this.wsUrl);\n this.setupWebSocketHandlers();\n } catch (error) {\n console.error('PushlerClient: Error creating WebSocket connection:', error);\n this.handleConnectionError(error);\n }\n }\n\n /**\n * Настройка обработчиков WebSocket\n */\n setupWebSocketHandlers() {\n this.socket.onopen = () => {\n // Не устанавливаем CONNECTED здесь - ждем pushler:connection_established\n // Это предотвращает двойные события и проблемы с переподключением\n this.connectionState = ConnectionStates.CONNECTING;\n this.emit(Events.CONNECTION_STATE_CHANGED, this.connectionState);\n console.log('WebSocket connection opened, waiting for connection_established...');\n };\n\n this.socket.onmessage = (event) => {\n this.handleMessage(event);\n };\n\n this.socket.onclose = (event) => {\n this.connectionState = ConnectionStates.DISCONNECTED;\n this.emit(Events.CONNECTION_STATE_CHANGED, this.connectionState);\n this.emit(Events.DISCONNECTED, event);\n \n // Логируем причину закрытия для отладки\n if (event.code !== 1000) { // 1000 = нормальное закрытие\n console.warn('WebSocket closed unexpectedly:', {\n code: event.code,\n reason: event.reason || 'No reason provided',\n wasClean: event.wasClean,\n url: this.wsUrl\n });\n }\n \n // Автоматическое переподключение\n if (this.reconnectAttempts < this.maxReconnectAttempts) {\n this.scheduleReconnect();\n } else {\n // Если превышено количество попыток, отправляем ошибку\n this.emit(Events.ERROR, {\n code: ErrorCodes.CONNECTION_FAILED,\n message: `Failed to connect after ${this.maxReconnectAttempts} attempts. Please check if the WebSocket server is running at ${this.wsUrl}`,\n url: this.wsUrl\n });\n }\n };\n\n this.socket.onerror = (error) => {\n this.handleConnectionError(error);\n };\n }\n\n /**\n * Обработка входящих сообщений\n */\n handleMessage(event) {\n try {\n const message = JSON.parse(event.data);\n \n switch (message.event) {\n case 'pushler:connection_established':\n this.handleConnectionEstablished(message.data);\n break;\n case 'pushler:subscription_succeeded':\n this.handleSubscriptionSucceeded(message);\n break;\n case 'pushler:auth_success':\n this.handleAuthSuccess(message);\n break;\n case 'pushler:auth_error':\n this.handleAuthError(message);\n break;\n default:\n this.handleChannelMessage(message);\n }\n } catch (error) {\n console.error('Error parsing WebSocket message:', error);\n }\n }\n\n /**\n * Обработка установления соединения\n */\n handleConnectionEstablished(data) {\n this.socketId = data.socket_id;\n this.connectionState = ConnectionStates.CONNECTED;\n this.reconnectAttempts = 0;\n \n console.log('Connection established with socket ID:', this.socketId);\n \n // Переподписываемся на все каналы после переподключения\n this.resubscribeAllChannels();\n \n this.emit(Events.CONNECTED, { socketId: this.socketId });\n }\n \n /**\n * Переподписка на все каналы после переподключения\n */\n resubscribeAllChannels() {\n for (const [channelName, channel] of this.channels.entries()) {\n // Сбрасываем флаг подписки\n channel.subscribed = false;\n // Выполняем подписку заново\n this.performChannelSubscription(channel);\n }\n }\n\n /**\n * Обработка успешной подписки на канал\n */\n handleSubscriptionSucceeded(message) {\n const channel = message.channel;\n const channelInstance = this.channels.get(channel);\n \n if (channelInstance) {\n channelInstance.subscribed = true;\n channelInstance.emit(Events.CHANNEL_SUBSCRIBED, message.data || {});\n console.log(`Channel ${channel} subscribed successfully`);\n }\n }\n\n /**\n * Обработка успешной аутентификации\n */\n handleAuthSuccess(message) {\n const { channel } = message.data;\n const channelInstance = this.channels.get(channel);\n \n if (channelInstance) {\n // На сервере уже происходит подписка после успешной авторизации,\n // поэтому просто помечаем канал как подписанный\n channelInstance.handleAuthSuccess(message.data);\n }\n \n this.emit(Events.CHANNEL_AUTH_SUCCESS, message.data);\n }\n\n /**\n * Обработка ошибки аутентификации\n */\n handleAuthError(message) {\n const { error } = message.data;\n this.emit(Events.CHANNEL_AUTH_ERROR, error);\n this.emit(Events.ERROR, {\n code: ErrorCodes.AUTHENTICATION_FAILED,\n message: error\n });\n }\n\n /**\n * Обработка сообщений каналов\n */\n handleChannelMessage(message) {\n const { channel, event, data } = message;\n const channelInstance = this.channels.get(channel);\n \n if (channelInstance) {\n channelInstance.handleMessage(event, data);\n }\n \n // Для события возвращаем оригинальное имя канала (без appKey)\n const originalChannelName = this.extractChannelName(channel);\n this.emit(Events.MESSAGE_RECEIVED, { channel: originalChannelName, event, data });\n }\n\n /**\n * Подписка на канал\n * @param {string} channelName - Имя канала (без appKey, будет добавлен автоматически)\n * @param {Object} options - Опции подписки\n * @returns {Channel} Объект канала\n */\n subscribe(channelName, options = {}) {\n // Формируем полное имя канала с appKey\n const fullChannelName = this.formatChannelName(channelName);\n \n if (this.channels.has(fullChannelName)) {\n return this.channels.get(fullChannelName);\n }\n\n // Создаем канал с полным именем\n const channel = new Channel(this, fullChannelName, options);\n // Сохраняем оригинальное имя для удобства\n channel.originalName = channelName;\n \n this.channels.set(fullChannelName, channel);\n this.channelAliases.set(channelName, fullChannelName);\n \n // Если подключены, сразу подписываемся\n if (this.connectionState === ConnectionStates.CONNECTED) {\n this.performChannelSubscription(channel);\n }\n \n return channel;\n }\n\n /**\n * Отписка от канала\n * @param {string} channelName - Имя канала (можно использовать оригинальное или полное)\n */\n unsubscribe(channelName) {\n // Поддерживаем оба формата имени\n const fullChannelName = this.channelAliases.get(channelName) || this.formatChannelName(channelName);\n \n const channel = this.channels.get(fullChannelName);\n if (channel) {\n channel.unsubscribe();\n this.channels.delete(fullChannelName);\n this.channelAliases.delete(channel.originalName || channelName);\n }\n }\n\n /**\n * Выполнение подписки на канал\n */\n performChannelSubscription(channel) {\n if (this.connectionState !== ConnectionStates.CONNECTED) {\n return;\n }\n\n const channelType = this.getChannelType(channel.name);\n \n // Для публичных каналов подписываемся сразу\n if (channelType === ChannelTypes.PUBLIC) {\n this.sendMessage({\n event: 'pushler:subscribe',\n data: { \n channel: channel.name,\n app_key: this.appKey\n }\n });\n return;\n }\n\n // Для приватных и presence каналов нужна аутентификация\n this.authenticateChannel(channel);\n }\n\n /**\n * Аутентификация канала\n */\n async authenticateChannel(channel) {\n try {\n const authData = await this.getChannelAuthData(channel);\n \n this.sendMessage({\n event: 'pushler:auth',\n data: authData\n });\n \n // Устанавливаем таймаут аутентификации\n this.authTimeout = setTimeout(() => {\n this.emit(Events.ERROR, {\n code: ErrorCodes.AUTHENTICATION_TIMEOUT,\n message: 'Authentication timeout'\n });\n }, 10000);\n \n } catch (error) {\n this.emit(Events.ERROR, {\n code: ErrorCodes.AUTHENTICATION_FAILED,\n message: error.message\n });\n }\n }\n\n /**\n * Получение подписи с бэкенда\n */\n async getChannelSignature(channelName, socketId, userData = null) {\n // Формируем URL: если authEndpoint абсолютный — используем его, иначе добавляем к apiUrl\n const authUrl = this.authEndpoint.startsWith('http') \n ? this.authEndpoint \n : `${this.apiUrl}${this.authEndpoint}`;\n \n const response = await fetch(authUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n channel_name: channelName,\n socket_id: socketId,\n app_key: this.appKey,\n user_data: userData\n })\n });\n\n if (!response.ok) {\n const error = await response.json();\n throw new Error(error.error || 'Failed to get channel signature');\n }\n\n const data = await response.json();\n return data.signature;\n }\n\n /**\n * Получение данных для аутентификации канала\n */\n async getChannelAuthData(channel) {\n if (!this.socketId) {\n throw new Error('Socket ID not available. Connection not established.');\n }\n \n const channelType = this.getChannelType(channel.name);\n \n const authData = {\n app_key: this.appKey,\n channel: channel.name,\n socket_id: this.socketId\n };\n\n // Для приватных и presence каналов нужна подпись\n if (channelType === ChannelTypes.PRIVATE || channelType === ChannelTypes.PRESENCE) {\n // Если подпись уже предоставлена, используем её\n if (channel.options.signature) {\n authData.signature = channel.options.signature;\n console.log('Using provided signature:', {\n channel: channel.name,\n socketId: this.socketId,\n signatureLength: channel.options.signature.length,\n signature: channel.options.signature.substring(0, 20) + '...'\n });\n } else {\n // Иначе получаем подпись с бэкенда\n try {\n authData.signature = await this.getChannelSignature(\n channel.name, \n this.socketId, \n channel.options.user\n );\n } catch (error) {\n throw new Error(`Failed to get channel signature: ${error.message}`);\n }\n }\n }\n\n // Для presence каналов нужны данные пользователя\n if (channelType === ChannelTypes.PRESENCE) {\n if (!channel.options.user) {\n throw new Error('User data is required for presence channels');\n }\n \n authData.user = channel.options.user;\n }\n\n return authData;\n }\n\n /**\n * Определение типа канала\n * Формат канала: {appKey}:{type-}channelName\n */\n getChannelType(channelName) {\n // Извлекаем имя канала без appKey\n const baseName = this.extractChannelName(channelName);\n \n if (baseName.startsWith('private-')) {\n return ChannelTypes.PRIVATE;\n }\n if (baseName.startsWith('presence-')) {\n return ChannelTypes.PRESENCE;\n }\n return ChannelTypes.PUBLIC;\n }\n\n /**\n * Отправка сообщения через WebSocket\n */\n sendMessage(message) {\n if (this.socket && this.socket.readyState === WebSocket.OPEN) {\n this.socket.send(JSON.stringify(message));\n }\n }\n\n /**\n * Генерация уникального ID сокета\n */\n generateSocketId() {\n return Math.random().toString(36).substr(2, 9) + '.' + Math.floor(Math.random() * 1000000);\n }\n\n /**\n * Планирование переподключения\n */\n scheduleReconnect() {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n }\n\n this.reconnectAttempts++;\n this.connectionState = ConnectionStates.RECONNECTING;\n this.emit(Events.CONNECTION_STATE_CHANGED, this.connectionState);\n\n this.reconnectTimer = setTimeout(() => {\n this.connect();\n }, this.reconnectDelay * this.reconnectAttempts);\n }\n\n /**\n * Обработка ошибки подключения\n */\n handleConnectionError(error) {\n this.connectionState = ConnectionStates.FAILED;\n this.emit(Events.CONNECTION_STATE_CHANGED, this.connectionState);\n \n // Формируем более информативное сообщение об ошибке\n let errorMessage = 'Connection failed';\n if (error && error.message) {\n errorMessage = error.message;\n } else if (error && typeof error === 'object') {\n errorMessage = JSON.stringify(error);\n } else if (typeof error === 'string') {\n errorMessage = error;\n }\n \n // Добавляем информацию о URL для отладки\n const fullErrorMessage = `WebSocket connection to '${this.wsUrl}' failed: ${errorMessage}`;\n \n console.error('PushlerClient connection error:', fullErrorMessage);\n \n this.emit(Events.ERROR, {\n code: ErrorCodes.CONNECTION_FAILED,\n message: fullErrorMessage,\n url: this.wsUrl,\n originalError: error\n });\n }\n\n /**\n * Отключение от WebSocket сервера\n */\n disconnect() {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n \n if (this.authTimeout) {\n clearTimeout(this.authTimeout);\n this.authTimeout = null;\n }\n\n if (this.socket) {\n this.socket.close();\n this.socket = null;\n }\n\n // Очищаем каналы и алиасы\n this.channels.clear();\n this.channelAliases.clear();\n\n this.connectionState = ConnectionStates.DISCONNECTED;\n this.emit(Events.CONNECTION_STATE_CHANGED, this.connectionState);\n }\n\n /**\n * Подписка на событие\n */\n on(event, callback) {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, []);\n }\n this.eventListeners.get(event).push(callback);\n }\n\n /**\n * Отписка от события\n */\n off(event, callback) {\n if (this.eventListeners.has(event)) {\n const listeners = this.eventListeners.get(event);\n const index = listeners.indexOf(callback);\n if (index > -1) {\n listeners.splice(index, 1);\n }\n }\n }\n\n /**\n * Вызов события\n */\n emit(event, data) {\n if (this.eventListeners.has(event)) {\n this.eventListeners.get(event).forEach(callback => {\n try {\n callback(data);\n } catch (error) {\n console.error('Error in event listener:', error);\n }\n });\n }\n }\n\n /**\n * Получение состояния подключения\n */\n getConnectionState() {\n return this.connectionState;\n }\n\n /**\n * Получение всех каналов (возвращает оригинальные имена без appKey)\n */\n getChannels() {\n return Array.from(this.channels.values()).map(channel => \n channel.originalName || this.extractChannelName(channel.name)\n );\n }\n\n /**\n * Получение канала по имени\n * @param {string} channelName - Имя канала (можно использовать оригинальное или полное)\n * @returns {Channel|undefined} Объект канала\n */\n channel(channelName) {\n const fullChannelName = this.channelAliases.get(channelName) || this.formatChannelName(channelName);\n return this.channels.get(fullChannelName);\n }\n}\n\nexport default PushlerClient;\n","import { createHmac } from 'crypto';\n\n/**\n * Серверный SDK для отправки сообщений через Pushler.ru API\n * Используется на сервере Node.js для отправки событий в каналы\n */\nclass PushlerServer {\n /**\n * @param {Object} options - Параметры клиента\n * @param {string} options.appKey - Ключ приложения (key_xxx)\n * @param {string} options.appSecret - Секрет приложения (secret_xxx)\n * @param {string} [options.apiUrl='http://localhost:8000/api'] - URL API сервера\n * @param {number} [options.timeout=30000] - Таймаут запроса в мс\n */\n constructor(options = {}) {\n if (!options.appKey) {\n throw new Error('appKey is required');\n }\n if (!options.appSecret) {\n throw new Error('appSecret is required');\n }\n\n this.appKey = options.appKey;\n this.appSecret = options.appSecret;\n this.apiUrl = (options.apiUrl || 'http://localhost:8000/api').replace(/\\/$/, '');\n this.timeout = options.timeout || 30000;\n }\n\n /**\n * Формирование полного имени канала с префиксом appKey\n * Формат: {appKey}:{channelName}\n * @param {string} channelName - Оригинальное имя канала\n * @returns {string} Полное имя канала\n */\n formatChannelName(channelName) {\n // Если канал уже содержит appKey, возвращаем как есть\n if (channelName.startsWith(this.appKey + ':')) {\n return channelName;\n }\n return `${this.appKey}:${channelName}`;\n }\n\n /**\n * Извлечение оригинального имени канала (без appKey)\n * @param {string} fullChannelName - Полное имя канала\n * @returns {string} Оригинальное имя канала\n */\n extractChannelName(fullChannelName) {\n const prefix = this.appKey + ':';\n if (fullChannelName.startsWith(prefix)) {\n return fullChannelName.substring(prefix.length);\n }\n return fullChannelName;\n }\n\n /**\n * Генерация подписи для API запроса\n * \n * @param {string} body - JSON тело запроса\n * @param {number} timestamp - Unix timestamp\n * @returns {string} HMAC-SHA256 подпись\n */\n generateApiSignature(body, timestamp) {\n const signatureString = body + timestamp;\n return createHmac('sha256', this.appSecret)\n .update(signatureString)\n .digest('hex');\n }\n\n /**\n * Генерация подписи для авторизации канала\n * \n * @param {string} channelName - Название канала (полное с appKey)\n * @param {string} socketId - ID сокета\n * @returns {string} HMAC-SHA256 подпись\n */\n generateChannelSignature(channelName, socketId) {\n // Подпись генерируется для полного имени канала\n const fullChannelName = this.formatChannelName(channelName);\n const signatureString = socketId + ':' + fullChannelName;\n return createHmac('sha256', this.appSecret)\n .update(signatureString)\n .digest('hex');\n }\n\n /**\n * Авторизация приватного канала\n * \n * @param {string} channelName - Название канала (appKey будет добавлен автоматически)\n * @param {string} socketId - ID сокета\n * @returns {Object} Результат авторизации с полным именем канала\n */\n authorizeChannel(channelName, socketId) {\n const fullChannelName = this.formatChannelName(channelName);\n const signature = this.generateChannelSignature(fullChannelName, socketId);\n return {\n auth: this.appKey + ':' + signature,\n channel: fullChannelName\n };\n }\n\n /**\n * Авторизация presence канала\n * \n * @param {string} channelName - Название канала (appKey будет добавлен автоматически)\n * @param {string} socketId - ID сокета\n * @param {Object} userData - Данные пользователя\n * @param {string|number} userData.user_id - ID пользователя (обязательно)\n * @param {Object} [userData.user_info] - Дополнительная информация о пользователе\n * @returns {Object} Результат авторизации с полным именем канала\n */\n authorizePresenceChannel(channelName, socketId, userData) {\n if (!userData || !userData.user_id) {\n throw new Error('user_id is required for presence channels');\n }\n\n const fullChannelName = this.formatChannelName(channelName);\n const signature = this.generateChannelSignature(fullChannelName, socketId);\n \n return {\n auth: this.appKey + ':' + signature,\n channel: fullChannelName,\n channel_data: JSON.stringify({\n user_id: userData.user_id,\n user_info: userData.user_info || {}\n })\n };\n }\n\n /**\n * Аутентификация пользователя для WebSocket соединения\n * \n * @param {string} socketId - ID сокета\n * @param {Object} userData - Данные пользователя\n * @returns {Object} Результат аутентификации\n */\n authenticateUser(socketId, userData) {\n if (!userData || !userData.user_id) {\n throw new Error('user_id is required for user authentication');\n }\n\n const signature = this.generateChannelSignature('user-' + userData.user_id, socketId);\n \n return {\n auth: this.appKey + ':' + signature,\n user_data: JSON.stringify(userData)\n };\n }\n\n /**\n * Отправка события в канал\n * \n * @param {string|string[]} channels - Канал или массив каналов (appKey будет добавлен автоматически)\n * @param {string} event - Название события\n * @param {Object} data - Данные события\n * @param {string} [socketId] - ID сокета (для исключения отправителя)\n * @returns {Promise<Object>} Результат отправки\n */\n async trigger(channels, event, data, socketId = null) {\n const channelList = Array.isArray(channels) ? channels : [channels];\n \n // Добавляем appKey ко всем каналам\n const formattedChannels = channelList.map(ch => this.formatChannelName(ch));\n \n // Для одного канала используем /messages/send\n if (formattedChannels.length === 1) {\n const payload = {\n channel: formattedChannels[0],\n event,\n data\n };\n\n if (socketId) {\n payload.socket_id = socketId;\n }\n\n return this.makeSignedRequest('POST', '/messages/send', payload);\n }\n \n // Для нескольких каналов используем /messages/broadcast\n const payload = {\n channels: formattedChannels,\n event,\n data\n };\n\n if (socketId) {\n payload.socket_id = socketId;\n }\n\n return this.makeSignedRequest('POST', '/messages/broadcast', payload);\n }\n\n /**\n * Отправка события в несколько каналов одновременно\n * \n * @param {string[]} channels - Массив каналов\n * @param {string} event - Название события\n * @param {Object} data - Данные события\n * @param {string} [socketId] - ID сокета (для исключения отправителя)\n * @returns {Promise<Object>} Результат отправки\n */\n async triggerBatch(channels, event, data, socketId = null) {\n return this.trigger(channels, event, data, socketId);\n }\n\n /**\n * Получение статуса сообщения\n * \n * @param {string|number} messageId - ID сообщения\n * @returns {Promise<Object>} Статус сообщения\n */\n async getMessageStatus(messageId) {\n return this.makeSignedRequest('GET', `/messages/${messageId}/status`);\n }\n\n /**\n * Получение списка сообщений\n * \n * @param {Object} [params] - Параметры запроса\n * @param {string} [params.status] - Фильтр по статусу\n * @param {number} [params.per_page] - Количество на страницу\n * @returns {Promise<Object>} Список сообщений\n */\n async getMessages(params = {}) {\n const query = new URLSearchParams(params).toString();\n const endpoint = '/messages' + (query ? '?' + query : '');\n return this.makeSignedRequest('GET', endpoint);\n }\n\n /**\n * Проверка валидности приложения\n * \n * @returns {Promise<Object>} Информация о приложении\n */\n async validateApplication() {\n const response = await this.makeHttpRequest('GET', `/applications/validate/${this.appKey}`);\n \n if (!response.id) {\n throw new Error(response.error || 'Application validation failed');\n }\n\n return response;\n }\n\n /**\n * Получение информации о приложении\n * \n * @returns {Promise<Object>} Информация о приложении\n */\n async getApplicationInfo() {\n return this.validateApplication();\n }\n\n /**\n * Валидация вебхука\n * \n * @param {Object} headers - Заголовки запроса\n * @param {string} body - Тело запроса\n * @returns {Object} Данные вебхука\n * @throws {Error} При невалидной подписи\n */\n verifyWebhook(headers, body) {\n const signature = headers['X-Pushler-Signature'] || headers['x-pushler-signature'] || '';\n \n if (!signature) {\n throw new Error('Missing X-Pushler-Signature header');\n }\n\n const expectedSignature = 'sha256=' + createHmac('sha256', this.appSecret)\n .update(body)\n .digest('hex');\n \n // Timing-safe сравнение\n if (!this.timingSafeEqual(expectedSignature, signature)) {\n throw new Error('Invalid webhook signature');\n }\n\n const data = JSON.parse(body);\n return data;\n }\n\n /**\n * Timing-safe сравнение строк\n * @private\n */\n timingSafeEqual(a, b) {\n if (a.length !== b.length) {\n return false;\n }\n \n let result = 0;\n for (let i = 0; i < a.length; i++) {\n result |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return result === 0;\n }\n\n /**\n * Выполнение подписанного HTTP запроса\n * \n * @private\n * @param {string} method - HTTP метод\n * @param {string} endpoint - API endpoint\n * @param {Object} [data] - Данные запроса\n * @returns {Promise<Object>} Результат запроса\n */\n async makeSignedRequest(method, endpoint, data = null) {\n const url = this.apiUrl + endpoint;\n const timestamp = Math.floor(Date.now() / 1000);\n const body = data ? JSON.stringify(data) : '';\n const signature = this.generateApiSignature(body, timestamp);\n \n const headers = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'User-Agent': 'PushlerRu-JS-SDK/1.0.0',\n 'X-Pushler-Key': this.appKey,\n 'X-Pushler-Signature': signature,\n 'X-Pushler-Timestamp': String(timestamp)\n };\n\n const options = {\n method,\n headers,\n signal: AbortSignal.timeout(this.timeout)\n };\n\n if (method === 'POST' && body) {\n options.body = body;\n }\n\n const response = await fetch(url, options);\n const result = await response.json();\n\n if (!response.ok) {\n const message = result.message || `HTTP request failed with status: ${response.status}`;\n const error = new Error(message);\n error.statusCode = response.status;\n error.response = result;\n throw error;\n }\n\n return result;\n }\n\n /**\n * Выполнение обычного HTTP запроса (без подписи)\n * \n * @private\n * @param {string} method - HTTP метод\n * @param {string} endpoint - API endpoint\n * @param {Object} [data] - Данные запроса\n * @returns {Promise<Object>} Результат запроса\n */\n async makeHttpRequest(method, endpoint, data = null) {\n const url = this.apiUrl + endpoint;\n \n const headers = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'User-Agent': 'PushlerRu-JS-SDK/1.0.0'\n };\n\n const options = {\n method,\n headers,\n signal: AbortSignal.timeout(this.timeout)\n };\n\n if (method === 'POST' && data) {\n options.body = JSON.stringify(data);\n }\n\n const response = await fetch(url, options);\n const result = await response.json();\n\n if (!response.ok) {\n throw new Error(`HTTP request failed with status: ${response.status}`);\n }\n\n return result;\n }\n\n /**\n * Получение App Key\n * @returns {string}\n */\n getAppKey() {\n return this.appKey;\n }\n\n /**\n * Получение API URL\n * @returns {string}\n */\n getApiUrl() {\n return this.apiUrl;\n }\n}\n\nexport default PushlerServer;\n\n","/**\n * Валидация данных канала\n * @param {string} channelName - Название канала\n * @param {string} channelType - Тип канала\n * @param {Object} options - Опции канала\n * @returns {Object} - Результат валидации\n */\nexport function validateChannelOptions(channelName, channelType, options) {\n const errors = [];\n\n if (!channelName) {\n errors.push('Channel name is required');\n }\n\n if (channelType === 'private' || channelType === 'presence') {\n if (!options.signature && !options.autoAuth) {\n errors.push('Signature or autoAuth is required for private/presence channels');\n }\n }\n\n if (channelType === 'presence') {\n if (!options.user) {\n errors.push('User data is required for presence channels');\n } else if (!options.user.id) {\n errors.push('User ID is required for presence channels');\n }\n }\n\n return {\n isValid: errors.length === 0,\n errors\n };\n}\n\n/**\n * Генерация уникального ID\n * @returns {string} - Уникальный ID\n */\nexport function generateId() {\n return Math.random().toString(36).substr(2, 9) + Date.now();\n}\n\n/**\n * Генерация уникального ID сокета\n * @returns {string} - Уникальный ID сокета\n */\nexport function generateSocketId() {\n return Math.random().toString(36).substr(2, 9) + '.' + Math.floor(Math.random() * 1000000);\n}\n\n/**\n * Проверка поддержки WebSocket в браузере\n * @returns {boolean} - Поддерживается ли WebSocket\n */\nexport function isWebSocketSupported() {\n return typeof WebSocket !== 'undefined';\n}\n\n/**\n * Форматирование ошибки\n * @param {Error|string} error - Ошибка\n * @returns {Object} - Форматированная ошибка\n */\nexport function formatError(error) {\n if (typeof error === 'string') {\n return { message: error };\n }\n \n if (error instanceof Error) {\n return { message: error.message, stack: error.stack };\n }\n \n return { message: 'Unknown error' };\n}\n","import PushlerClient from './PushlerClient';\nimport PushlerServer from './PushlerServer';\nimport Channel from './Channel';\nimport { ChannelTypes, ConnectionStates } from './constants';\nimport { generateSocketId } from './utils';\n\n// Создаем объект с методами для удобного API\nconst Pushler = {\n // Клиентский SDK для браузера (WebSocket)\n CreateClient: (options) => new PushlerClient(options),\n Create: (options) => new PushlerClient(options), // Алиас для краткости\n \n // Серверный SDK для Node.js (отправка сообщений через API)\n CreateServer: (options) => new PushlerServer(options),\n Server: (options) => new PushlerServer(options), // Алиас для краткости\n \n Channel,\n ChannelTypes,\n ConnectionStates,\n generateSocketId\n};\n\nexport { PushlerClient, PushlerServer, Channel, ChannelTypes, ConnectionStates, generateSocketId, Pushler };\nexport default Pushler;\n"],"names":["Channel","PushlerClient","PushlerServer"],"mappings":"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"}
1
+ {"version":3,"file":"pushler-ru.esm.js","sources":["../src/constants.js","../src/Channel.js","../src/PushlerClient.js","../src/PushlerServer.js","../src/utils.js","../src/index.js"],"sourcesContent":["/**\r\n * Типы каналов\r\n */\r\nexport const ChannelTypes = {\r\n PUBLIC: 'public',\r\n PRIVATE: 'private',\r\n PRESENCE: 'presence'\r\n};\r\n\r\n/**\r\n * Состояния подключения\r\n */\r\nexport const ConnectionStates = {\r\n CONNECTING: 'connecting',\r\n CONNECTED: 'connected',\r\n DISCONNECTED: 'disconnected',\r\n RECONNECTING: 'reconnecting',\r\n FAILED: 'failed'\r\n};\r\n\r\n/**\r\n * События WebSocket\r\n */\r\nexport const Events = {\r\n // События подключения\r\n CONNECTION_STATE_CHANGED: 'connection_state_changed',\r\n CONNECTED: 'connected',\r\n DISCONNECTED: 'disconnected',\r\n ERROR: 'error',\r\n \r\n // События каналов\r\n CHANNEL_SUBSCRIBED: 'channel_subscribed',\r\n CHANNEL_UNSUBSCRIBED: 'channel_unsubscribed',\r\n CHANNEL_AUTH_SUCCESS: 'pushler:auth_success',\r\n CHANNEL_AUTH_ERROR: 'pushler:auth_error',\r\n \r\n // События сообщений\r\n MESSAGE_RECEIVED: 'message_received'\r\n};\r\n\r\n/**\r\n * Коды ошибок\r\n */\r\nexport const ErrorCodes = {\r\n INVALID_APP_KEY: 'INVALID_APP_KEY',\r\n INVALID_SIGNATURE: 'INVALID_SIGNATURE',\r\n AUTHENTICATION_FAILED: 'AUTHENTICATION_FAILED',\r\n CHANNEL_ACCESS_DENIED: 'CHANNEL_ACCESS_DENIED',\r\n CONNECTION_FAILED: 'CONNECTION_FAILED',\r\n AUTHENTICATION_TIMEOUT: 'AUTHENTICATION_TIMEOUT'\r\n};\r\n","import { ChannelTypes, Events } from './constants';\n\n/**\n * Класс для управления каналом\n */\nclass Channel {\n constructor(client, name, options = {}) {\n this.client = client;\n this.name = name;\n this.options = options;\n this.subscribed = false;\n this.eventListeners = new Map();\n this.presenceData = null;\n }\n\n /**\n * Подписка на событие канала\n */\n on(event, callback) {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, []);\n }\n this.eventListeners.get(event).push(callback);\n }\n\n /**\n * Отписка от события канала\n */\n off(event, callback) {\n if (this.eventListeners.has(event)) {\n const listeners = this.eventListeners.get(event);\n const index = listeners.indexOf(callback);\n if (index > -1) {\n listeners.splice(index, 1);\n }\n }\n }\n\n /**\n * Вызов события канала\n */\n emit(event, data) {\n if (this.eventListeners.has(event)) {\n this.eventListeners.get(event).forEach(callback => {\n try {\n callback(data);\n } catch (error) {\n console.error('Error in channel event listener:', error);\n }\n });\n }\n }\n\n /**\n * Обработка успешной аутентификации\n */\n handleAuthSuccess(data) {\n this.subscribed = true;\n this.emit(Events.CHANNEL_SUBSCRIBED, data);\n \n // Для presence каналов сохраняем данные пользователя\n if (data.user) {\n this.presenceData = data.user;\n }\n }\n\n /**\n * Обработка входящих сообщений\n */\n handleMessage(event, data) {\n this.emit(event, data);\n }\n\n /**\n * Отписка от канала\n */\n unsubscribe() {\n if (this.subscribed && this.client.connectionState === 'connected') {\n this.client.sendMessage({\n event: 'pushler:unsubscribe',\n data: { channel: this.name }\n });\n }\n \n this.subscribed = false;\n this.emit(Events.CHANNEL_UNSUBSCRIBED);\n }\n\n /**\n * Проверка подписки на канал\n */\n isSubscribed() {\n return this.subscribed;\n }\n\n /**\n * Получение данных присутствия (для presence каналов)\n */\n getPresenceData() {\n return this.presenceData;\n }\n\n /**\n * Получение типа канала\n * Учитывает, что имя канала может иметь формат {appKey}:{channelName}\n */\n getType() {\n // Извлекаем базовое имя канала (без appKey)\n const baseName = this.getBaseName();\n \n if (baseName.startsWith('private-')) {\n return ChannelTypes.PRIVATE;\n }\n if (baseName.startsWith('presence-')) {\n return ChannelTypes.PRESENCE;\n }\n return ChannelTypes.PUBLIC;\n }\n\n /**\n * Получение базового имени канала (без appKey префикса)\n * @returns {string} Базовое имя канала\n */\n getBaseName() {\n // Имя канала может быть в формате {appKey}:{channelName}\n const colonIndex = this.name.indexOf(':');\n if (colonIndex !== -1) {\n return this.name.substring(colonIndex + 1);\n }\n return this.name;\n }\n\n /**\n * Получение полного имени канала (с appKey)\n * @returns {string} Полное имя канала\n */\n getFullName() {\n return this.name;\n }\n}\n\nexport default Channel;\n","import Channel from './Channel';\nimport { ChannelTypes, ConnectionStates, Events, ErrorCodes } from './constants';\n\n/**\n * Основной класс для подключения к Pushler.ru WebSocket серверу\n */\nclass PushlerClient {\n constructor(options = {}) {\n this.appKey = options.appKey;\n // wsUrl формируется автоматически на основе appKey, но можно переопределить для тестирования\n this.wsUrl = options.wsUrl || `wss://ws.pushler.ru/app/${this.appKey}`;\n this.apiUrl = options.apiUrl;\n this.authEndpoint = options.authEndpoint || '/pushler/auth'; // Путь для авторизации каналов\n this.authHeaders = options.authHeaders || null; // Кастомные заголовки для авторизации\n this.getAuthHeaders = options.getAuthHeaders || null; // Функция для динамических заголовков\n this.autoConnect = options.autoConnect !== false;\n this.reconnectDelay = options.reconnectDelay || 1000;\n this.maxReconnectAttempts = options.maxReconnectAttempts || 5;\n \n this.connectionState = ConnectionStates.DISCONNECTED;\n this.socket = null;\n this.socketId = null;\n this.channels = new Map(); // Хранит каналы по полному имени (с appKey)\n this.channelAliases = new Map(); // Маппинг оригинальное имя -> полное имя\n this.eventListeners = new Map();\n this.reconnectAttempts = 0;\n this.reconnectTimer = null;\n this.authTimeout = null;\n \n // Promise для ожидания подключения\n this.connectionPromise = null;\n this.connectionResolve = null;\n this.connectionReject = null;\n \n // Автоматическое подключение\n if (this.autoConnect) {\n this.connect();\n }\n }\n\n /**\n * Формирование полного имени канала с префиксом appKey\n * Формат: {appKey}:{channelName}\n * @param {string} channelName - Оригинальное имя канала\n * @returns {string} Полное имя канала\n */\n formatChannelName(channelName) {\n // Если канал уже содержит appKey, возвращаем как есть\n if (channelName.startsWith(this.appKey + ':')) {\n return channelName;\n }\n return `${this.appKey}:${channelName}`;\n }\n\n /**\n * Извлечение оригинального имени канала (без appKey)\n * @param {string} fullChannelName - Полное имя канала\n * @returns {string} Оригинальное имя канала\n */\n extractChannelName(fullChannelName) {\n const prefix = this.appKey + ':';\n if (fullChannelName.startsWith(prefix)) {\n return fullChannelName.substring(prefix.length);\n }\n return fullChannelName;\n }\n\n /**\n * Подключение к WebSocket серверу\n * @returns {Promise} Promise, который резолвится при успешном подключении\n */\n connect() {\n // Если уже подключены - возвращаем резолвленный Promise\n if (this.connectionState === ConnectionStates.CONNECTED) {\n return Promise.resolve({ socketId: this.socketId });\n }\n \n // Если уже идёт подключение - возвращаем существующий Promise\n if (this.connectionState === ConnectionStates.CONNECTING && this.connectionPromise) {\n return this.connectionPromise;\n }\n\n // Создаём новый Promise для ожидания подключения\n this.connectionPromise = new Promise((resolve, reject) => {\n this.connectionResolve = resolve;\n this.connectionReject = reject;\n });\n\n this.connectionState = ConnectionStates.CONNECTING;\n this.emit(Events.CONNECTION_STATE_CHANGED, this.connectionState);\n\n try {\n if (!this.wsUrl) {\n throw new Error('WebSocket URL is not configured');\n }\n \n console.log(`PushlerClient: Connecting to ${this.wsUrl}`);\n this.socket = new WebSocket(this.wsUrl);\n this.setupWebSocketHandlers();\n } catch (error) {\n console.error('PushlerClient: Error creating WebSocket connection:', error);\n this.handleConnectionError(error);\n if (this.connectionReject) {\n this.connectionReject(error);\n this.connectionPromise = null;\n this.connectionResolve = null;\n this.connectionReject = null;\n }\n }\n \n return this.connectionPromise;\n }\n\n /**\n * Ожидание установления соединения\n * @param {number} timeout - Таймаут в мс (по умолчанию 10000)\n * @returns {Promise} Promise с socketId\n */\n waitForConnection(timeout = 10000) {\n // Если уже подключены\n if (this.connectionState === ConnectionStates.CONNECTED && this.socketId) {\n return Promise.resolve({ socketId: this.socketId });\n }\n \n // Если есть активный Promise подключения\n if (this.connectionPromise) {\n return Promise.race([\n this.connectionPromise,\n new Promise((_, reject) => \n setTimeout(() => reject(new Error('Connection timeout')), timeout)\n )\n ]);\n }\n \n // Если не подключаемся - начинаем подключение\n if (this.connectionState === ConnectionStates.DISCONNECTED) {\n return this.connect();\n }\n \n // Для других состояний создаём Promise, который ждёт connected события\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n this.off(Events.CONNECTED, onConnected);\n this.off(Events.ERROR, onError);\n reject(new Error('Connection timeout'));\n }, timeout);\n \n const onConnected = (data) => {\n clearTimeout(timeoutId);\n this.off(Events.ERROR, onError);\n resolve(data);\n };\n \n const onError = (err) => {\n clearTimeout(timeoutId);\n this.off(Events.CONNECTED, onConnected);\n reject(err);\n };\n \n this.on(Events.CONNECTED, onConnected);\n this.on(Events.ERROR, onError);\n });\n }\n\n /**\n * Настройка обработчиков WebSocket\n */\n setupWebSocketHandlers() {\n this.socket.onopen = () => {\n // Не устанавливаем CONNECTED здесь - ждем pushler:connection_established\n // Это предотвращает двойные события и проблемы с переподключением\n this.connectionState = ConnectionStates.CONNECTING;\n this.emit(Events.CONNECTION_STATE_CHANGED, this.connectionState);\n console.log('WebSocket connection opened, waiting for connection_established...');\n };\n\n this.socket.onmessage = (event) => {\n this.handleMessage(event);\n };\n\n this.socket.onclose = (event) => {\n this.connectionState = ConnectionStates.DISCONNECTED;\n this.emit(Events.CONNECTION_STATE_CHANGED, this.connectionState);\n this.emit(Events.DISCONNECTED, event);\n \n // Логируем причину закрытия для отладки\n if (event.code !== 1000) { // 1000 = нормальное закрытие\n console.warn('WebSocket closed unexpectedly:', {\n code: event.code,\n reason: event.reason || 'No reason provided',\n wasClean: event.wasClean,\n url: this.wsUrl\n });\n }\n \n // Автоматическое переподключение\n if (this.reconnectAttempts < this.maxReconnectAttempts) {\n this.scheduleReconnect();\n } else {\n // Если превышено количество попыток, отправляем ошибку\n this.emit(Events.ERROR, {\n code: ErrorCodes.CONNECTION_FAILED,\n message: `Failed to connect after ${this.maxReconnectAttempts} attempts. Please check if the WebSocket server is running at ${this.wsUrl}`,\n url: this.wsUrl\n });\n }\n };\n\n this.socket.onerror = (error) => {\n this.handleConnectionError(error);\n };\n }\n\n /**\n * Обработка входящих сообщений\n */\n handleMessage(event) {\n try {\n const message = JSON.parse(event.data);\n \n switch (message.event) {\n case 'pushler:connection_established':\n this.handleConnectionEstablished(message.data);\n break;\n case 'pushler:subscription_succeeded':\n this.handleSubscriptionSucceeded(message);\n break;\n case 'pushler:auth_success':\n this.handleAuthSuccess(message);\n break;\n case 'pushler:auth_error':\n this.handleAuthError(message);\n break;\n default:\n this.handleChannelMessage(message);\n }\n } catch (error) {\n console.error('Error parsing WebSocket message:', error);\n }\n }\n\n /**\n * Обработка установления соединения\n */\n handleConnectionEstablished(data) {\n this.socketId = data.socket_id;\n this.connectionState = ConnectionStates.CONNECTED;\n this.reconnectAttempts = 0;\n \n console.log('Connection established with socket ID:', this.socketId);\n \n // Резолвим Promise подключения\n if (this.connectionResolve) {\n this.connectionResolve({ socketId: this.socketId });\n this.connectionPromise = null;\n this.connectionResolve = null;\n this.connectionReject = null;\n }\n \n // Переподписываемся на все каналы после переподключения\n this.resubscribeAllChannels();\n \n this.emit(Events.CONNECTED, { socketId: this.socketId });\n }\n \n /**\n * Переподписка на все каналы после переподключения\n */\n resubscribeAllChannels() {\n for (const [channelName, channel] of this.channels.entries()) {\n // Сбрасываем флаг подписки\n channel.subscribed = false;\n // Выполняем подписку заново\n this.performChannelSubscription(channel);\n }\n }\n\n /**\n * Обработка успешной подписки на канал\n */\n handleSubscriptionSucceeded(message) {\n const channel = message.channel;\n const channelInstance = this.channels.get(channel);\n \n if (channelInstance) {\n channelInstance.subscribed = true;\n channelInstance.emit(Events.CHANNEL_SUBSCRIBED, message.data || {});\n console.log(`Channel ${channel} subscribed successfully`);\n }\n }\n\n /**\n * Обработка успешной аутентификации\n */\n handleAuthSuccess(message) {\n const { channel } = message.data;\n const channelInstance = this.channels.get(channel);\n \n if (channelInstance) {\n // На сервере уже происходит подписка после успешной авторизации,\n // поэтому просто помечаем канал как подписанный\n channelInstance.handleAuthSuccess(message.data);\n }\n \n this.emit(Events.CHANNEL_AUTH_SUCCESS, message.data);\n }\n\n /**\n * Обработка ошибки аутентификации\n */\n handleAuthError(message) {\n const { error } = message.data;\n this.emit(Events.CHANNEL_AUTH_ERROR, error);\n this.emit(Events.ERROR, {\n code: ErrorCodes.AUTHENTICATION_FAILED,\n message: error\n });\n }\n\n /**\n * Обработка сообщений каналов\n */\n handleChannelMessage(message) {\n const { channel, event, data } = message;\n const channelInstance = this.channels.get(channel);\n \n if (channelInstance) {\n channelInstance.handleMessage(event, data);\n }\n \n // Для события возвращаем оригинальное имя канала (без appKey)\n const originalChannelName = this.extractChannelName(channel);\n this.emit(Events.MESSAGE_RECEIVED, { channel: originalChannelName, event, data });\n }\n\n /**\n * Подписка на канал\n * @param {string} channelName - Имя канала (без appKey, будет добавлен автоматически)\n * @param {Object} options - Опции подписки\n * @returns {Channel} Объект канала\n */\n subscribe(channelName, options = {}) {\n // Формируем полное имя канала с appKey\n const fullChannelName = this.formatChannelName(channelName);\n \n if (this.channels.has(fullChannelName)) {\n return this.channels.get(fullChannelName);\n }\n\n // Создаем канал с полным именем\n const channel = new Channel(this, fullChannelName, options);\n // Сохраняем оригинальное имя для удобства\n channel.originalName = channelName;\n \n this.channels.set(fullChannelName, channel);\n this.channelAliases.set(channelName, fullChannelName);\n \n // Если подключены, сразу подписываемся\n if (this.connectionState === ConnectionStates.CONNECTED) {\n this.performChannelSubscription(channel);\n }\n \n return channel;\n }\n\n /**\n * Отписка от канала\n * @param {string} channelName - Имя канала (можно использовать оригинальное или полное)\n */\n unsubscribe(channelName) {\n // Поддерживаем оба формата имени\n const fullChannelName = this.channelAliases.get(channelName) || this.formatChannelName(channelName);\n \n const channel = this.channels.get(fullChannelName);\n if (channel) {\n channel.unsubscribe();\n this.channels.delete(fullChannelName);\n this.channelAliases.delete(channel.originalName || channelName);\n }\n }\n\n /**\n * Выполнение подписки на канал\n */\n performChannelSubscription(channel) {\n if (this.connectionState !== ConnectionStates.CONNECTED) {\n return;\n }\n\n const channelType = this.getChannelType(channel.name);\n \n // Для публичных каналов подписываемся сразу\n if (channelType === ChannelTypes.PUBLIC) {\n this.sendMessage({\n event: 'pushler:subscribe',\n data: { \n channel: channel.name,\n app_key: this.appKey\n }\n });\n return;\n }\n\n // Для приватных и presence каналов нужна аутентификация\n this.authenticateChannel(channel);\n }\n\n /**\n * Аутентификация канала\n */\n async authenticateChannel(channel) {\n try {\n const authData = await this.getChannelAuthData(channel);\n \n this.sendMessage({\n event: 'pushler:auth',\n data: authData\n });\n \n // Устанавливаем таймаут аутентификации\n this.authTimeout = setTimeout(() => {\n this.emit(Events.ERROR, {\n code: ErrorCodes.AUTHENTICATION_TIMEOUT,\n message: 'Authentication timeout'\n });\n }, 10000);\n \n } catch (error) {\n this.emit(Events.ERROR, {\n code: ErrorCodes.AUTHENTICATION_FAILED,\n message: error.message\n });\n }\n }\n\n /**\n * Получение заголовков для авторизации\n */\n getAuthRequestHeaders() {\n const headers = { 'Content-Type': 'application/json' };\n \n // Динамические заголовки имеют приоритет\n if (typeof this.getAuthHeaders === 'function') {\n const dynamicHeaders = this.getAuthHeaders();\n Object.assign(headers, dynamicHeaders);\n } else if (this.authHeaders) {\n // Статические заголовки\n Object.assign(headers, this.authHeaders);\n }\n \n return headers;\n }\n\n /**\n * Получение подписи с бэкенда\n */\n async getChannelSignature(channelName, socketId, userData = null) {\n // Формируем URL: если authEndpoint абсолютный — используем его, иначе добавляем к apiUrl\n const authUrl = this.authEndpoint.startsWith('http') \n ? this.authEndpoint \n : `${this.apiUrl}${this.authEndpoint}`;\n \n const headers = this.getAuthRequestHeaders();\n const hasAuthHeaders = this.authHeaders || this.getAuthHeaders;\n \n const response = await fetch(authUrl, {\n method: 'POST',\n headers,\n // Если есть authHeaders, не используем credentials (JWT режим)\n // Если нет — используем cookies\n ...(hasAuthHeaders ? {} : { credentials: 'include' }),\n body: JSON.stringify({\n channel_name: channelName,\n socket_id: socketId,\n app_key: this.appKey,\n user_data: userData\n })\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ error: 'Auth request failed' }));\n throw new Error(error.error || 'Failed to get channel signature');\n }\n\n const data = await response.json();\n return data.signature;\n }\n\n /**\n * Получение данных для аутентификации канала\n */\n async getChannelAuthData(channel) {\n if (!this.socketId) {\n throw new Error('Socket ID not available. Connection not established.');\n }\n \n const channelType = this.getChannelType(channel.name);\n \n const authData = {\n app_key: this.appKey,\n channel: channel.name,\n socket_id: this.socketId\n };\n\n // Для приватных и presence каналов нужна подпись\n if (channelType === ChannelTypes.PRIVATE || channelType === ChannelTypes.PRESENCE) {\n // Если подпись уже предоставлена, используем её\n if (channel.options.signature) {\n authData.signature = channel.options.signature;\n console.log('Using provided signature:', {\n channel: channel.name,\n socketId: this.socketId,\n signatureLength: channel.options.signature.length,\n signature: channel.options.signature.substring(0, 20) + '...'\n });\n } else {\n // Иначе получаем подпись с бэкенда\n try {\n authData.signature = await this.getChannelSignature(\n channel.name, \n this.socketId, \n channel.options.user\n );\n } catch (error) {\n throw new Error(`Failed to get channel signature: ${error.message}`);\n }\n }\n }\n\n // Для presence каналов нужны данные пользователя\n if (channelType === ChannelTypes.PRESENCE) {\n if (!channel.options.user) {\n throw new Error('User data is required for presence channels');\n }\n \n authData.user = channel.options.user;\n }\n\n return authData;\n }\n\n /**\n * Определение типа канала\n * Формат канала: {appKey}:{type-}channelName\n */\n getChannelType(channelName) {\n // Извлекаем имя канала без appKey\n const baseName = this.extractChannelName(channelName);\n \n if (baseName.startsWith('private-')) {\n return ChannelTypes.PRIVATE;\n }\n if (baseName.startsWith('presence-')) {\n return ChannelTypes.PRESENCE;\n }\n return ChannelTypes.PUBLIC;\n }\n\n /**\n * Отправка сообщения через WebSocket\n */\n sendMessage(message) {\n if (this.socket && this.socket.readyState === WebSocket.OPEN) {\n this.socket.send(JSON.stringify(message));\n }\n }\n\n /**\n * Генерация уникального ID сокета\n */\n generateSocketId() {\n return Math.random().toString(36).substr(2, 9) + '.' + Math.floor(Math.random() * 1000000);\n }\n\n /**\n * Планирование переподключения\n */\n scheduleReconnect() {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n }\n\n this.reconnectAttempts++;\n this.connectionState = ConnectionStates.RECONNECTING;\n this.emit(Events.CONNECTION_STATE_CHANGED, this.connectionState);\n\n this.reconnectTimer = setTimeout(() => {\n this.connect();\n }, this.reconnectDelay * this.reconnectAttempts);\n }\n\n /**\n * Обработка ошибки подключения\n */\n handleConnectionError(error) {\n this.connectionState = ConnectionStates.FAILED;\n this.emit(Events.CONNECTION_STATE_CHANGED, this.connectionState);\n \n // Формируем более информативное сообщение об ошибке\n let errorMessage = 'Connection failed';\n if (error && error.message) {\n errorMessage = error.message;\n } else if (error && typeof error === 'object') {\n errorMessage = JSON.stringify(error);\n } else if (typeof error === 'string') {\n errorMessage = error;\n }\n \n // Добавляем информацию о URL для отладки\n const fullErrorMessage = `WebSocket connection to '${this.wsUrl}' failed: ${errorMessage}`;\n \n console.error('PushlerClient connection error:', fullErrorMessage);\n \n // Реджектим Promise подключения\n if (this.connectionReject) {\n this.connectionReject(new Error(fullErrorMessage));\n this.connectionPromise = null;\n this.connectionResolve = null;\n this.connectionReject = null;\n }\n \n this.emit(Events.ERROR, {\n code: ErrorCodes.CONNECTION_FAILED,\n message: fullErrorMessage,\n url: this.wsUrl,\n originalError: error\n });\n }\n\n /**\n * Отключение от WebSocket сервера\n */\n disconnect() {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n \n if (this.authTimeout) {\n clearTimeout(this.authTimeout);\n this.authTimeout = null;\n }\n\n if (this.socket) {\n this.socket.close();\n this.socket = null;\n }\n\n // Очищаем каналы и алиасы\n this.channels.clear();\n this.channelAliases.clear();\n\n this.connectionState = ConnectionStates.DISCONNECTED;\n this.emit(Events.CONNECTION_STATE_CHANGED, this.connectionState);\n }\n\n /**\n * Подписка на событие\n */\n on(event, callback) {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, []);\n }\n this.eventListeners.get(event).push(callback);\n }\n\n /**\n * Отписка от события\n */\n off(event, callback) {\n if (this.eventListeners.has(event)) {\n const listeners = this.eventListeners.get(event);\n const index = listeners.indexOf(callback);\n if (index > -1) {\n listeners.splice(index, 1);\n }\n }\n }\n\n /**\n * Вызов события\n */\n emit(event, data) {\n if (this.eventListeners.has(event)) {\n this.eventListeners.get(event).forEach(callback => {\n try {\n callback(data);\n } catch (error) {\n console.error('Error in event listener:', error);\n }\n });\n }\n }\n\n /**\n * Получение состояния подключения\n */\n getConnectionState() {\n return this.connectionState;\n }\n\n /**\n * Получение всех каналов (возвращает оригинальные имена без appKey)\n */\n getChannels() {\n return Array.from(this.channels.values()).map(channel => \n channel.originalName || this.extractChannelName(channel.name)\n );\n }\n\n /**\n * Получение канала по имени\n * @param {string} channelName - Имя канала (можно использовать оригинальное или полное)\n * @returns {Channel|undefined} Объект канала\n */\n channel(channelName) {\n const fullChannelName = this.channelAliases.get(channelName) || this.formatChannelName(channelName);\n return this.channels.get(fullChannelName);\n }\n}\n\nexport default PushlerClient;\n","import { createHmac } from 'crypto';\n\n/**\n * Серверный SDK для отправки сообщений через Pushler.ru API\n * Используется на сервере Node.js для отправки событий в каналы\n */\nclass PushlerServer {\n static API_URL = 'https://api.pushler.ru';\n\n /**\n * @param {Object} options - Параметры клиента\n * @param {string} options.appKey - Ключ приложения (key_xxx)\n * @param {string} options.appSecret - Секрет приложения (secret_xxx)\n * @param {number} [options.timeout=10000] - Таймаут запроса в мс\n */\n constructor(options = {}) {\n if (!options.appKey) {\n throw new Error('appKey is required');\n }\n if (!options.appSecret) {\n throw new Error('appSecret is required');\n }\n\n this.appKey = options.appKey;\n this.appSecret = options.appSecret;\n this.timeout = options.timeout || 10000;\n }\n\n /**\n * Формирование полного имени канала с префиксом appKey\n * Формат: {appKey}:{channelName}\n * @param {string} channelName - Оригинальное имя канала\n * @returns {string} Полное имя канала\n */\n formatChannelName(channelName) {\n // Если канал уже содержит appKey, возвращаем как есть\n if (channelName.startsWith(this.appKey + ':')) {\n return channelName;\n }\n return `${this.appKey}:${channelName}`;\n }\n\n /**\n * Извлечение оригинального имени канала (без appKey)\n * @param {string} fullChannelName - Полное имя канала\n * @returns {string} Оригинальное имя канала\n */\n extractChannelName(fullChannelName) {\n const prefix = this.appKey + ':';\n if (fullChannelName.startsWith(prefix)) {\n return fullChannelName.substring(prefix.length);\n }\n return fullChannelName;\n }\n\n /**\n * Генерация подписи для API запроса\n * \n * @param {string} body - JSON тело запроса\n * @param {number} timestamp - Unix timestamp\n * @returns {string} HMAC-SHA256 подпись\n */\n generateApiSignature(body, timestamp) {\n const signatureString = body + timestamp;\n return createHmac('sha256', this.appSecret)\n .update(signatureString)\n .digest('hex');\n }\n\n /**\n * Генерация подписи для авторизации канала\n * \n * @param {string} channelName - Название канала (полное с appKey)\n * @param {string} socketId - ID сокета\n * @returns {string} HMAC-SHA256 подпись\n */\n generateChannelSignature(channelName, socketId) {\n // Подпись генерируется для полного имени канала\n const fullChannelName = this.formatChannelName(channelName);\n const signatureString = socketId + ':' + fullChannelName;\n return createHmac('sha256', this.appSecret)\n .update(signatureString)\n .digest('hex');\n }\n\n /**\n * Авторизация приватного канала\n * \n * @param {string} channelName - Название канала (appKey будет добавлен автоматически)\n * @param {string} socketId - ID сокета\n * @returns {Object} Результат авторизации с полным именем канала\n */\n authorizeChannel(channelName, socketId) {\n const fullChannelName = this.formatChannelName(channelName);\n const signature = this.generateChannelSignature(fullChannelName, socketId);\n return {\n auth: this.appKey + ':' + signature,\n channel: fullChannelName\n };\n }\n\n /**\n * Авторизация presence канала\n * \n * @param {string} channelName - Название канала (appKey будет добавлен автоматически)\n * @param {string} socketId - ID сокета\n * @param {Object} userData - Данные пользователя\n * @param {string|number} userData.user_id - ID пользователя (обязательно)\n * @param {Object} [userData.user_info] - Дополнительная информация о пользователе\n * @returns {Object} Результат авторизации с полным именем канала\n */\n authorizePresenceChannel(channelName, socketId, userData) {\n if (!userData || !userData.user_id) {\n throw new Error('user_id is required for presence channels');\n }\n\n const fullChannelName = this.formatChannelName(channelName);\n const signature = this.generateChannelSignature(fullChannelName, socketId);\n \n return {\n auth: this.appKey + ':' + signature,\n channel: fullChannelName,\n channel_data: JSON.stringify({\n user_id: userData.user_id,\n user_info: userData.user_info || {}\n })\n };\n }\n\n /**\n * Аутентификация пользователя для WebSocket соединения\n * \n * @param {string} socketId - ID сокета\n * @param {Object} userData - Данные пользователя\n * @returns {Object} Результат аутентификации\n */\n authenticateUser(socketId, userData) {\n if (!userData || !userData.user_id) {\n throw new Error('user_id is required for user authentication');\n }\n\n const signature = this.generateChannelSignature('user-' + userData.user_id, socketId);\n \n return {\n auth: this.appKey + ':' + signature,\n user_data: JSON.stringify(userData)\n };\n }\n\n /**\n * Отправка события в канал\n * \n * @param {string|string[]} channels - Канал или массив каналов (appKey будет добавлен автоматически)\n * @param {string} event - Название события\n * @param {Object} data - Данные события\n * @param {string} [socketId] - ID сокета (для исключения отправителя)\n * @returns {Promise<Object>} Результат отправки\n */\n async trigger(channels, event, data, socketId = null) {\n const channelList = Array.isArray(channels) ? channels : [channels];\n \n // Добавляем appKey ко всем каналам\n const formattedChannels = channelList.map(ch => this.formatChannelName(ch));\n \n // Для одного канала используем /messages/send\n if (formattedChannels.length === 1) {\n const payload = {\n channel: formattedChannels[0],\n event,\n data\n };\n\n if (socketId) {\n payload.socket_id = socketId;\n }\n\n return this.makeSignedRequest('POST', '/messages/send', payload);\n }\n \n // Для нескольких каналов используем /messages/broadcast\n const payload = {\n channels: formattedChannels,\n event,\n data\n };\n\n if (socketId) {\n payload.socket_id = socketId;\n }\n\n return this.makeSignedRequest('POST', '/messages/broadcast', payload);\n }\n\n /**\n * Отправка события в несколько каналов одновременно\n * \n * @param {string[]} channels - Массив каналов\n * @param {string} event - Название события\n * @param {Object} data - Данные события\n * @param {string} [socketId] - ID сокета (для исключения отправителя)\n * @returns {Promise<Object>} Результат отправки\n */\n async triggerBatch(channels, event, data, socketId = null) {\n return this.trigger(channels, event, data, socketId);\n }\n\n /**\n * Получение статуса сообщения\n * \n * @param {string|number} messageId - ID сообщения\n * @returns {Promise<Object>} Статус сообщения\n */\n async getMessageStatus(messageId) {\n return this.makeSignedRequest('GET', `/messages/${messageId}/status`);\n }\n\n /**\n * Получение списка сообщений\n * \n * @param {Object} [params] - Параметры запроса\n * @param {string} [params.status] - Фильтр по статусу\n * @param {number} [params.per_page] - Количество на страницу\n * @returns {Promise<Object>} Список сообщений\n */\n async getMessages(params = {}) {\n const query = new URLSearchParams(params).toString();\n const endpoint = '/messages' + (query ? '?' + query : '');\n return this.makeSignedRequest('GET', endpoint);\n }\n\n /**\n * Проверка валидности приложения\n * \n * @returns {Promise<Object>} Информация о приложении\n */\n async validateApplication() {\n const response = await this.makeHttpRequest('GET', `/applications/validate/${this.appKey}`);\n \n if (!response.id) {\n throw new Error(response.error || 'Application validation failed');\n }\n\n return response;\n }\n\n /**\n * Получение информации о приложении\n * \n * @returns {Promise<Object>} Информация о приложении\n */\n async getApplicationInfo() {\n return this.validateApplication();\n }\n\n /**\n * Валидация вебхука\n * \n * @param {Object} headers - Заголовки запроса\n * @param {string} body - Тело запроса\n * @returns {Object} Данные вебхука\n * @throws {Error} При невалидной подписи\n */\n verifyWebhook(headers, body) {\n const signature = headers['X-Pushler-Signature'] || headers['x-pushler-signature'] || '';\n \n if (!signature) {\n throw new Error('Missing X-Pushler-Signature header');\n }\n\n const expectedSignature = 'sha256=' + createHmac('sha256', this.appSecret)\n .update(body)\n .digest('hex');\n \n // Timing-safe сравнение\n if (!this.timingSafeEqual(expectedSignature, signature)) {\n throw new Error('Invalid webhook signature');\n }\n\n const data = JSON.parse(body);\n return data;\n }\n\n /**\n * Timing-safe сравнение строк\n * @private\n */\n timingSafeEqual(a, b) {\n if (a.length !== b.length) {\n return false;\n }\n \n let result = 0;\n for (let i = 0; i < a.length; i++) {\n result |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return result === 0;\n }\n\n /**\n * Выполнение подписанного HTTP запроса\n * \n * @private\n * @param {string} method - HTTP метод\n * @param {string} endpoint - API endpoint\n * @param {Object} [data] - Данные запроса\n * @returns {Promise<Object>} Результат запроса\n */\n async makeSignedRequest(method, endpoint, data = null) {\n const url = PushlerServer.API_URL + endpoint;\n const timestamp = Math.floor(Date.now() / 1000);\n const body = data ? JSON.stringify(data) : '';\n const signature = this.generateApiSignature(body, timestamp);\n \n const headers = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'User-Agent': 'PushlerRu-JS-SDK/1.0.0',\n 'X-Pushler-Key': this.appKey,\n 'X-Pushler-Signature': signature,\n 'X-Pushler-Timestamp': String(timestamp)\n };\n\n const options = {\n method,\n headers,\n signal: AbortSignal.timeout(this.timeout)\n };\n\n if (method === 'POST' && body) {\n options.body = body;\n }\n\n const response = await fetch(url, options);\n const result = await response.json();\n\n if (!response.ok) {\n const message = result.message || `HTTP request failed with status: ${response.status}`;\n const error = new Error(message);\n error.statusCode = response.status;\n error.response = result;\n throw error;\n }\n\n return result;\n }\n\n /**\n * Выполнение обычного HTTP запроса (без подписи)\n * \n * @private\n * @param {string} method - HTTP метод\n * @param {string} endpoint - API endpoint\n * @param {Object} [data] - Данные запроса\n * @returns {Promise<Object>} Результат запроса\n */\n async makeHttpRequest(method, endpoint, data = null) {\n const url = PushlerServer.API_URL + endpoint;\n \n const headers = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'User-Agent': 'PushlerRu-JS-SDK/1.0.0'\n };\n\n const options = {\n method,\n headers,\n signal: AbortSignal.timeout(this.timeout)\n };\n\n if (method === 'POST' && data) {\n options.body = JSON.stringify(data);\n }\n\n const response = await fetch(url, options);\n const result = await response.json();\n\n if (!response.ok) {\n throw new Error(`HTTP request failed with status: ${response.status}`);\n }\n\n return result;\n }\n\n /**\n * Получение App Key\n * @returns {string}\n */\n getAppKey() {\n return this.appKey;\n }\n\n /**\n * Получение API URL\n * @returns {string}\n */\n getApiUrl() {\n return PushlerServer.API_URL;\n }\n}\n\nexport default PushlerServer;\n\n","/**\n * Валидация данных канала\n * @param {string} channelName - Название канала\n * @param {string} channelType - Тип канала\n * @param {Object} options - Опции канала\n * @returns {Object} - Результат валидации\n */\nexport function validateChannelOptions(channelName, channelType, options) {\n const errors = [];\n\n if (!channelName) {\n errors.push('Channel name is required');\n }\n\n if (channelType === 'private' || channelType === 'presence') {\n if (!options.signature && !options.autoAuth) {\n errors.push('Signature or autoAuth is required for private/presence channels');\n }\n }\n\n if (channelType === 'presence') {\n if (!options.user) {\n errors.push('User data is required for presence channels');\n } else if (!options.user.id) {\n errors.push('User ID is required for presence channels');\n }\n }\n\n return {\n isValid: errors.length === 0,\n errors\n };\n}\n\n/**\n * Генерация уникального ID\n * @returns {string} - Уникальный ID\n */\nexport function generateId() {\n return Math.random().toString(36).substr(2, 9) + Date.now();\n}\n\n/**\n * Генерация уникального ID сокета\n * @returns {string} - Уникальный ID сокета\n */\nexport function generateSocketId() {\n return Math.random().toString(36).substr(2, 9) + '.' + Math.floor(Math.random() * 1000000);\n}\n\n/**\n * Проверка поддержки WebSocket в браузере\n * @returns {boolean} - Поддерживается ли WebSocket\n */\nexport function isWebSocketSupported() {\n return typeof WebSocket !== 'undefined';\n}\n\n/**\n * Форматирование ошибки\n * @param {Error|string} error - Ошибка\n * @returns {Object} - Форматированная ошибка\n */\nexport function formatError(error) {\n if (typeof error === 'string') {\n return { message: error };\n }\n \n if (error instanceof Error) {\n return { message: error.message, stack: error.stack };\n }\n \n return { message: 'Unknown error' };\n}\n","import PushlerClient from './PushlerClient';\nimport PushlerServer from './PushlerServer';\nimport Channel from './Channel';\nimport { ChannelTypes, ConnectionStates } from './constants';\nimport { generateSocketId } from './utils';\n\n// Создаем объект с методами для удобного API\nconst Pushler = {\n // Клиентский SDK для браузера (WebSocket)\n CreateClient: (options) => new PushlerClient(options),\n Create: (options) => new PushlerClient(options), // Алиас для краткости\n \n // Серверный SDK для Node.js (отправка сообщений через API)\n CreateServer: (options) => new PushlerServer(options),\n Server: (options) => new PushlerServer(options), // Алиас для краткости\n \n Channel,\n ChannelTypes,\n ConnectionStates,\n generateSocketId\n};\n\nexport { PushlerClient, PushlerServer, Channel, ChannelTypes, ConnectionStates, generateSocketId, Pushler };\nexport default Pushler;\n"],"names":["Channel","PushlerClient","PushlerServer"],"mappings":"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"}