@ozdao/martyrs 0.2.497 → 0.2.498

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.
Files changed (34) hide show
  1. package/dist/martyrs/src/components/Block/Block.vue.cjs +1 -1
  2. package/dist/martyrs/src/components/Block/Block.vue.js +1 -1
  3. package/dist/martyrs/src/components/Tooltip/{Tooltip.vue.cjs → Tooltip.vue2.cjs} +2 -2
  4. package/dist/martyrs/src/components/Tooltip/Tooltip.vue2.cjs.map +1 -0
  5. package/dist/martyrs/src/components/Tooltip/{Tooltip.vue.js → Tooltip.vue2.js} +2 -2
  6. package/dist/martyrs/src/components/Tooltip/{Tooltip.vue.cjs.map → Tooltip.vue2.js.map} +1 -1
  7. package/dist/martyrs/src/modules/globals/views/classes/globals.websocket.cjs +5 -1
  8. package/dist/martyrs/src/modules/globals/views/classes/globals.websocket.cjs.map +1 -1
  9. package/dist/martyrs/src/modules/globals/views/classes/globals.websocket.js +5 -1
  10. package/dist/martyrs/src/modules/globals/views/classes/globals.websocket.js.map +1 -1
  11. package/dist/martyrs/src/modules/globals/views/components/blocks/CardHeader.vue.cjs +1 -1
  12. package/dist/martyrs/src/modules/globals/views/components/blocks/CardHeader.vue.js +1 -1
  13. package/dist/martyrs/src/modules/music/router/music.cjs +1 -1
  14. package/dist/martyrs/src/modules/music/router/music.js +1 -1
  15. package/dist/martyrs/src/modules/notifications/notifications.client.cjs +8 -3
  16. package/dist/martyrs/src/modules/notifications/notifications.client.cjs.map +1 -1
  17. package/dist/martyrs/src/modules/notifications/notifications.client.js +8 -3
  18. package/dist/martyrs/src/modules/notifications/notifications.client.js.map +1 -1
  19. package/dist/martyrs/src/modules/orders/components/blocks/CardOrderUser.vue.cjs +1 -1
  20. package/dist/martyrs/src/modules/orders/components/blocks/CardOrderUser.vue.js +1 -1
  21. package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.cjs +1 -1
  22. package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.js +1 -1
  23. package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.cjs +1 -1
  24. package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.js +1 -1
  25. package/dist/martyrs/src/modules/pages/views/components/pages/PageEdit.vue.cjs +1 -1
  26. package/dist/martyrs/src/modules/pages/views/components/pages/PageEdit.vue.js +1 -1
  27. package/dist/martyrs/src/modules/products/components/blocks/ProductDiscounts.vue.cjs +1 -1
  28. package/dist/martyrs/src/modules/products/components/blocks/ProductDiscounts.vue.js +1 -1
  29. package/dist/martyrs/src/modules/wallet/views/components/pages/Wallet.vue.cjs +1 -1
  30. package/dist/martyrs/src/modules/wallet/views/components/pages/Wallet.vue.js +1 -1
  31. package/package.json +1 -1
  32. package/src/modules/globals/views/classes/globals.websocket.js +6 -1
  33. package/src/modules/notifications/notifications.client.js +7 -0
  34. package/dist/martyrs/src/components/Tooltip/Tooltip.vue.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
3
  const vue = require("vue");
4
- const Tooltip = require("../Tooltip/Tooltip.vue.cjs");
4
+ const Tooltip = require("../Tooltip/Tooltip.vue2.cjs");
5
5
  const _hoisted_1 = { class: "bg-light pd-medium radius-medium" };
6
6
  const _hoisted_2 = {
7
7
  key: 0,
@@ -1,5 +1,5 @@
1
1
  import { useSlots, createElementBlock, openBlock, createCommentVNode, renderSlot, createBlock, toDisplayString, Fragment, renderList, normalizeClass, withCtx, createElementVNode, Comment } from "vue";
2
- import _sfc_main$1 from "../Tooltip/Tooltip.vue.js";
2
+ import _sfc_main$1 from "../Tooltip/Tooltip.vue2.js";
3
3
  const _hoisted_1 = { class: "bg-light pd-medium radius-medium" };
4
4
  const _hoisted_2 = {
5
5
  key: 0,
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
3
  const vue = require("vue");
4
- ;/* empty css */
4
+ ;/* empty css */
5
5
  const _sfc_main = {
6
6
  __name: "Tooltip",
7
7
  props: {
@@ -51,4 +51,4 @@ const _sfc_main = {
51
51
  }
52
52
  };
53
53
  exports.default = _sfc_main;
54
- //# sourceMappingURL=Tooltip.vue.cjs.map
54
+ //# sourceMappingURL=Tooltip.vue2.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tooltip.vue2.cjs","sources":["../../../../../src/components/Tooltip/Tooltip.vue"],"sourcesContent":["<template>\n <div class=\"cursor-pointer tooltip-container\" @mouseover=\"showTooltip\" @mouseleave=\"hideTooltip\">\n <slot></slot>\n <div class=\"tooltip-content\" :style=\"tooltipStyle\">\n <span>{{ text }}</span>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, reactive } from 'vue';\n\nconst props = defineProps({\n text: {\n type: String,\n required: true\n }\n});\n\nconst visible = ref(false);\n\nconst tooltipStyle = reactive({\n position: 'absolute',\n width: 'max-content',\n zIndex: 1000,\n background: '#333',\n color: '#fff',\n padding: '5px',\n borderRadius: '3px',\n fontSize: '14px',\n display: 'none',\n});\n\nfunction showTooltip(event) {\n visible.value = true;\n tooltipStyle.left = `${(event.clientX / 100) + 10 }px`;\n tooltipStyle.top = `${(event.clientY / 100) + 10 }px`;\n tooltipStyle.display = 'block';\n}\n\nfunction hideTooltip() {\n visible.value = false;\n tooltipStyle.display = 'none';\n}\n</script>\n\n<style >\n.tooltip-container {\n position: relative;\n display: inline-block;\n}\n\n.tooltip-content {\n pointer-events: none;\n}\n</style>"],"names":["ref","reactive"],"mappings":";;;;;;;;;;;;;AAmBA,UAAM,UAAUA,IAAAA,IAAI,KAAK;AAEzB,UAAM,eAAeC,IAAAA,SAAS;AAAA,MAC5B,UAAU;AAAA,MACV,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,OAAO;AAAA,MACP,SAAS;AAAA,MACT,cAAc;AAAA,MACd,UAAU;AAAA,MACV,SAAS;AAAA,IACX,CAAC;AAED,aAAS,YAAY,OAAO;AAC1B,cAAQ,QAAQ;AAChB,mBAAa,OAAO,GAAI,MAAM,UAAU,MAAO,EAAE;AACjD,mBAAa,MAAM,GAAI,MAAM,UAAU,MAAO,EAAE;AAChD,mBAAa,UAAU;AAAA,IACzB;AAEA,aAAS,cAAc;AACrB,cAAQ,QAAQ;AAChB,mBAAa,UAAU;AAAA,IACzB;;;;;;;;;;;;;;;;;;;"}
@@ -1,5 +1,5 @@
1
1
  import { ref, reactive, createElementBlock, openBlock, renderSlot, createElementVNode, normalizeStyle, toDisplayString } from "vue";
2
- /* empty css */
2
+ /* empty css */
3
3
  const _sfc_main = {
4
4
  __name: "Tooltip",
5
5
  props: {
@@ -51,4 +51,4 @@ const _sfc_main = {
51
51
  export {
52
52
  _sfc_main as default
53
53
  };
54
- //# sourceMappingURL=Tooltip.vue.js.map
54
+ //# sourceMappingURL=Tooltip.vue2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.vue.cjs","sources":["../../../../../src/components/Tooltip/Tooltip.vue"],"sourcesContent":["<template>\n <div class=\"cursor-pointer tooltip-container\" @mouseover=\"showTooltip\" @mouseleave=\"hideTooltip\">\n <slot></slot>\n <div class=\"tooltip-content\" :style=\"tooltipStyle\">\n <span>{{ text }}</span>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, reactive } from 'vue';\n\nconst props = defineProps({\n text: {\n type: String,\n required: true\n }\n});\n\nconst visible = ref(false);\n\nconst tooltipStyle = reactive({\n position: 'absolute',\n width: 'max-content',\n zIndex: 1000,\n background: '#333',\n color: '#fff',\n padding: '5px',\n borderRadius: '3px',\n fontSize: '14px',\n display: 'none',\n});\n\nfunction showTooltip(event) {\n visible.value = true;\n tooltipStyle.left = `${(event.clientX / 100) + 10 }px`;\n tooltipStyle.top = `${(event.clientY / 100) + 10 }px`;\n tooltipStyle.display = 'block';\n}\n\nfunction hideTooltip() {\n visible.value = false;\n tooltipStyle.display = 'none';\n}\n</script>\n\n<style >\n.tooltip-container {\n position: relative;\n display: inline-block;\n}\n\n.tooltip-content {\n pointer-events: none;\n}\n</style>"],"names":["ref","reactive"],"mappings":";;;;;;;;;;;;;AAmBA,UAAM,UAAUA,IAAAA,IAAI,KAAK;AAEzB,UAAM,eAAeC,IAAAA,SAAS;AAAA,MAC5B,UAAU;AAAA,MACV,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,OAAO;AAAA,MACP,SAAS;AAAA,MACT,cAAc;AAAA,MACd,UAAU;AAAA,MACV,SAAS;AAAA,IACX,CAAC;AAED,aAAS,YAAY,OAAO;AAC1B,cAAQ,QAAQ;AAChB,mBAAa,OAAO,GAAI,MAAM,UAAU,MAAO,EAAE;AACjD,mBAAa,MAAM,GAAI,MAAM,UAAU,MAAO,EAAE;AAChD,mBAAa,UAAU;AAAA,IACzB;AAEA,aAAS,cAAc;AACrB,cAAQ,QAAQ;AAChB,mBAAa,UAAU;AAAA,IACzB;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"Tooltip.vue2.js","sources":["../../../../../src/components/Tooltip/Tooltip.vue"],"sourcesContent":["<template>\n <div class=\"cursor-pointer tooltip-container\" @mouseover=\"showTooltip\" @mouseleave=\"hideTooltip\">\n <slot></slot>\n <div class=\"tooltip-content\" :style=\"tooltipStyle\">\n <span>{{ text }}</span>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, reactive } from 'vue';\n\nconst props = defineProps({\n text: {\n type: String,\n required: true\n }\n});\n\nconst visible = ref(false);\n\nconst tooltipStyle = reactive({\n position: 'absolute',\n width: 'max-content',\n zIndex: 1000,\n background: '#333',\n color: '#fff',\n padding: '5px',\n borderRadius: '3px',\n fontSize: '14px',\n display: 'none',\n});\n\nfunction showTooltip(event) {\n visible.value = true;\n tooltipStyle.left = `${(event.clientX / 100) + 10 }px`;\n tooltipStyle.top = `${(event.clientY / 100) + 10 }px`;\n tooltipStyle.display = 'block';\n}\n\nfunction hideTooltip() {\n visible.value = false;\n tooltipStyle.display = 'none';\n}\n</script>\n\n<style >\n.tooltip-container {\n position: relative;\n display: inline-block;\n}\n\n.tooltip-content {\n pointer-events: none;\n}\n</style>"],"names":[],"mappings":";;;;;;;;;;;AAmBA,UAAM,UAAU,IAAI,KAAK;AAEzB,UAAM,eAAe,SAAS;AAAA,MAC5B,UAAU;AAAA,MACV,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,OAAO;AAAA,MACP,SAAS;AAAA,MACT,cAAc;AAAA,MACd,UAAU;AAAA,MACV,SAAS;AAAA,IACX,CAAC;AAED,aAAS,YAAY,OAAO;AAC1B,cAAQ,QAAQ;AAChB,mBAAa,OAAO,GAAI,MAAM,UAAU,MAAO,EAAE;AACjD,mBAAa,MAAM,GAAI,MAAM,UAAU,MAAO,EAAE;AAChD,mBAAa,UAAU;AAAA,IACzB;AAEA,aAAS,cAAc;AACrB,cAAQ,QAAQ;AAChB,mBAAa,UAAU;AAAA,IACzB;;;;;;;;;;;;;;;;;;"}
@@ -19,6 +19,10 @@ class GlobalWebSocket {
19
19
  this.rpcIdCounter = 0;
20
20
  }
21
21
  initialize(options = {}) {
22
+ console.log("WSS initialize options:", options);
23
+ console.log("options.wsUrl:", options.wsUrl);
24
+ console.log("window.location.protocol:", window.location.protocol);
25
+ console.log("window.location.host:", window.location.host);
22
26
  this.maxReconnectAttempts = options.maxReconnectAttempts || this.maxReconnectAttempts;
23
27
  this.reconnectDelay = options.reconnectDelay || this.reconnectDelay;
24
28
  this.baseUrl = options.wsUrl || this._getDefaultWsUrl();
@@ -28,7 +32,7 @@ class GlobalWebSocket {
28
32
  _getDefaultWsUrl() {
29
33
  if (typeof window === "undefined") return "/api/ws";
30
34
  const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
31
- const host = window.location.host;
35
+ const host = window.location.hostname;
32
36
  return `${protocol}//${host}/api/ws`;
33
37
  }
34
38
  connect(userId) {
@@ -1 +1 @@
1
- {"version":3,"file":"globals.websocket.cjs","sources":["../../../../../../../src/modules/globals/views/classes/globals.websocket.js"],"sourcesContent":["class GlobalWebSocket {\n constructor() {\n this.socket = null;\n this.isConnected = false;\n this.reconnectAttempts = 0;\n this.maxReconnectAttempts = 5;\n this.reconnectDelay = 3000;\n this.baseUrl = null;\n this.pingInterval = null;\n this.pingIntervalTime = 30000;\n this.listeners = {};\n this.userId = null;\n this.connectPromise = null;\n this.subscribedModules = new Set();\n\n // RPC-специфичные свойства\n this.rpcCallbacks = new Map();\n this.rpcTimeout = 30000; // 30 секунд таймаут по умолчанию\n this.rpcIdCounter = 0;\n }\n\n initialize(options = {}) {\n this.maxReconnectAttempts = options.maxReconnectAttempts || this.maxReconnectAttempts;\n this.reconnectDelay = options.reconnectDelay || this.reconnectDelay;\n this.baseUrl = options.wsUrl || this._getDefaultWsUrl();\n this.pingIntervalTime = options.pingInterval || this.pingIntervalTime;\n this.rpcTimeout = options.rpcTimeout || this.rpcTimeout;\n }\n\n _getDefaultWsUrl() {\n if (typeof window === 'undefined') return '/api/ws';\n const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';\n const host = window.location.host;\n return `${protocol}//${host}/api/ws`;\n }\n\n connect(userId) {\n if (typeof window === 'undefined') return Promise.resolve(false);\n this.userId = userId;\n\n // Проверяем существующее соединение\n if (this.isConnected && this.socket?.readyState === WebSocket.OPEN) {\n return Promise.resolve(this.socket);\n }\n\n // Предотвращаем создание множества промисов при параллельных вызовах\n if (this.connectPromise) {\n return this.connectPromise;\n }\n\n this.connectPromise = new Promise((resolve, reject) => {\n this.disconnect();\n\n // Используем baseUrl без параметров, так как аутентификация через cookie\n this.socket = new WebSocket(this.baseUrl);\n\n this.socket.onopen = () => {\n this._handleOpen();\n resolve(this.socket);\n };\n\n this.socket.onmessage = this._handleMessage.bind(this);\n this.socket.onerror = err => {\n this._handleError(err);\n reject(err);\n };\n this.socket.onclose = this._handleClose.bind(this);\n\n setTimeout(() => {\n if (!this.isConnected) {\n reject(new Error('WebSocket connection timeout'));\n }\n }, 10000);\n }).finally(() => {\n this.connectPromise = null;\n });\n\n return this.connectPromise;\n }\n\n disconnect() {\n if (typeof window === 'undefined') return;\n\n if (this.socket) {\n this.socket.onopen = null;\n this.socket.onmessage = null;\n this.socket.onerror = null;\n this.socket.onclose = null;\n if (this.socket.readyState === WebSocket.OPEN || this.socket.readyState === WebSocket.CONNECTING) {\n this.socket.close();\n }\n this.socket = null;\n }\n\n if (this.pingInterval) {\n clearInterval(this.pingInterval);\n this.pingInterval = null;\n }\n\n // Отменяем все ожидающие RPC вызовы\n for (const [id, { reject }] of this.rpcCallbacks.entries()) {\n reject(new Error('WebSocket disconnected'));\n this.rpcCallbacks.delete(id);\n }\n\n this.isConnected = false;\n this.userId = null;\n this.subscribedModules.clear(); // Очищаем подписки при отключении\n }\n\n async send(data) {\n if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {\n console.error('Cannot send message: WebSocket is not connected');\n return false;\n }\n\n try {\n const msg = typeof data === 'string' ? data : JSON.stringify(data);\n this.socket.send(msg);\n return true;\n } catch (err) {\n console.error('Error sending message:', err);\n return false;\n }\n }\n\n /**\n * Выполняет RPC вызов на сервере\n * @param {string} module - Имя модуля\n * @param {string} method - Имя метода\n * @param {object} params - Параметры метода\n * @param {object} [options] - Опции вызова\n * @param {number} [options.timeout] - Таймаут в миллисекундах\n * @returns {Promise<any>} - Результат вызова\n */\n rpc(module, method, params = {}, options = {}) {\n if (!this.isConnected || this.socket?.readyState !== WebSocket.OPEN) {\n return Promise.reject(new Error('WebSocket is not connected'));\n }\n\n if (!module || !method) {\n return Promise.reject(new Error('Module and method are required'));\n }\n\n // Генерируем уникальный ID для вызова\n const id = `${++this.rpcIdCounter}`;\n const timeout = options.timeout || this.rpcTimeout;\n\n return new Promise((resolve, reject) => {\n // Записываем информацию о вызове для последующей обработки ответа\n this.rpcCallbacks.set(id, {\n resolve,\n reject,\n timeoutId: setTimeout(() => {\n if (this.rpcCallbacks.has(id)) {\n this.rpcCallbacks.delete(id);\n reject(new Error(`RPC call to ${module}.${method} timed out after ${timeout}ms`));\n }\n }, timeout),\n });\n\n // Отправляем RPC запрос\n this.send({\n type: 'rpc',\n module,\n method,\n params,\n id,\n }).catch(err => {\n if (this.rpcCallbacks.has(id)) {\n clearTimeout(this.rpcCallbacks.get(id).timeoutId);\n this.rpcCallbacks.delete(id);\n reject(err);\n }\n });\n });\n }\n\n addEventListener(eventType, callback, options = {}) {\n const listenerId = `${options.module || 'global'}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n if (!this.listeners[eventType]) this.listeners[eventType] = {};\n this.listeners[eventType][listenerId] = callback;\n return listenerId;\n }\n\n removeEventListener(eventType, listenerId) {\n if (this.listeners[eventType]?.[listenerId]) {\n delete this.listeners[eventType][listenerId];\n }\n }\n\n removeModuleListeners(moduleName) {\n Object.keys(this.listeners).forEach(eventType => {\n Object.keys(this.listeners[eventType]).forEach(listenerId => {\n if (listenerId.startsWith(`${moduleName}_`)) {\n delete this.listeners[eventType][listenerId];\n }\n });\n });\n }\n\n async subscribeModule(moduleName) {\n if (!moduleName || this.subscribedModules.has(moduleName)) return;\n const success = await this.send({ type: 'subscribe', module: moduleName });\n if (success) {\n this.subscribedModules.add(moduleName);\n }\n }\n\n async unsubscribeModule(moduleName) {\n if (!moduleName || !this.subscribedModules.has(moduleName)) return;\n const success = await this.send({ type: 'unsubscribe', module: moduleName });\n if (success) {\n this.subscribedModules.delete(moduleName);\n }\n }\n\n _resubscribeAllModules() {\n for (const moduleName of this.subscribedModules) {\n this.send({ type: 'subscribe', module: moduleName });\n }\n }\n\n _handleOpen() {\n this.isConnected = true;\n this.reconnectAttempts = 0;\n\n this.pingInterval = setInterval(() => {\n if (this.socket?.readyState === WebSocket.OPEN) {\n this.socket.send(JSON.stringify({ type: 'ping' }));\n }\n }, this.pingIntervalTime);\n\n this._resubscribeAllModules();\n this._notifyListeners('open', { isConnected: true });\n }\n\n _handleMessage(event) {\n // Проверка на типы сообщений - пропускаем бинарные сообщения\n if (typeof event.data !== 'string') {\n console.warn('Received binary message, but only JSON is supported');\n return;\n }\n\n try {\n const data = JSON.parse(event.data);\n\n // Обрабатываем ответы на RPC вызовы\n if (data.type === 'rpc_response' && data.id && this.rpcCallbacks.has(data.id)) {\n const { resolve, reject, timeoutId } = this.rpcCallbacks.get(data.id);\n clearTimeout(timeoutId);\n this.rpcCallbacks.delete(data.id);\n\n if (data.error) {\n reject(Object.assign(new Error(data.error.message), data.error));\n } else {\n resolve(data.result);\n }\n\n return;\n }\n\n // Обрабатываем обычные сообщения\n this._notifyListeners('message', data);\n if (data.type) {\n this._notifyListeners(data.type, data);\n }\n } catch (err) {\n console.error('WebSocket message error:', err);\n }\n }\n\n _handleError(error) {\n console.error('WebSocket error:', error);\n this._notifyListeners('error', { error });\n\n // Отменяем все RPC вызовы с ошибкой соединения\n for (const [id, { reject, timeoutId }] of this.rpcCallbacks.entries()) {\n clearTimeout(timeoutId);\n reject(new Error('WebSocket connection error'));\n this.rpcCallbacks.delete(id);\n }\n }\n\n _handleClose(event) {\n this.isConnected = false;\n if (this.pingInterval) {\n clearInterval(this.pingInterval);\n this.pingInterval = null;\n }\n\n // Отменяем все RPC вызовы при закрытии соединения\n for (const [id, { reject, timeoutId }] of this.rpcCallbacks.entries()) {\n clearTimeout(timeoutId);\n reject(new Error('WebSocket connection closed'));\n this.rpcCallbacks.delete(id);\n }\n\n this._notifyListeners('close', { code: event.code, reason: event.reason });\n\n if (event.code !== 1000 && this.userId && this.reconnectAttempts < this.maxReconnectAttempts) {\n this.reconnectAttempts++;\n const delay = this.reconnectDelay * this.reconnectAttempts;\n setTimeout(() => {\n this.connect(this.userId).catch(err => {\n console.error('Reconnection failed:', err);\n });\n }, delay);\n }\n }\n\n _notifyListeners(eventType, data) {\n Object.values(this.listeners[eventType] || {}).forEach(fn => {\n try {\n fn(data);\n } catch (err) {\n console.error(`Listener for ${eventType} failed:`, err);\n }\n });\n }\n\n isSocketConnected() {\n return this.isConnected && this.socket?.readyState === WebSocket.OPEN;\n }\n}\n\nconst globalWebSocket = new GlobalWebSocket();\nexport default globalWebSocket;\n"],"names":["module"],"mappings":"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"}
1
+ {"version":3,"file":"globals.websocket.cjs","sources":["../../../../../../../src/modules/globals/views/classes/globals.websocket.js"],"sourcesContent":["class GlobalWebSocket {\n constructor() {\n this.socket = null;\n this.isConnected = false;\n this.reconnectAttempts = 0;\n this.maxReconnectAttempts = 5;\n this.reconnectDelay = 3000;\n this.baseUrl = null;\n this.pingInterval = null;\n this.pingIntervalTime = 30000;\n this.listeners = {};\n this.userId = null;\n this.connectPromise = null;\n this.subscribedModules = new Set();\n\n // RPC-специфичные свойства\n this.rpcCallbacks = new Map();\n this.rpcTimeout = 30000; // 30 секунд таймаут по умолчанию\n this.rpcIdCounter = 0;\n }\n\n initialize(options = {}) {\n console.log('WSS initialize options:', options);\n console.log('options.wsUrl:', options.wsUrl);\n console.log('window.location.protocol:', window.location.protocol);\n console.log('window.location.host:', window.location.host);\n \n this.maxReconnectAttempts = options.maxReconnectAttempts || this.maxReconnectAttempts;\n this.reconnectDelay = options.reconnectDelay || this.reconnectDelay;\n this.baseUrl = options.wsUrl || this._getDefaultWsUrl();\n this.pingIntervalTime = options.pingInterval || this.pingIntervalTime;\n this.rpcTimeout = options.rpcTimeout || this.rpcTimeout;\n }\n\n _getDefaultWsUrl() {\n if (typeof window === 'undefined') return '/api/ws';\n const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';\n const host = window.location.hostname;\n return `${protocol}//${host}/api/ws`;\n }\n\n connect(userId) {\n if (typeof window === 'undefined') return Promise.resolve(false);\n this.userId = userId;\n\n // Проверяем существующее соединение\n if (this.isConnected && this.socket?.readyState === WebSocket.OPEN) {\n return Promise.resolve(this.socket);\n }\n\n // Предотвращаем создание множества промисов при параллельных вызовах\n if (this.connectPromise) {\n return this.connectPromise;\n }\n\n this.connectPromise = new Promise((resolve, reject) => {\n this.disconnect();\n\n // Используем baseUrl без параметров, так как аутентификация через cookie\n this.socket = new WebSocket(this.baseUrl);\n\n this.socket.onopen = () => {\n this._handleOpen();\n resolve(this.socket);\n };\n\n this.socket.onmessage = this._handleMessage.bind(this);\n this.socket.onerror = err => {\n this._handleError(err);\n reject(err);\n };\n this.socket.onclose = this._handleClose.bind(this);\n\n setTimeout(() => {\n if (!this.isConnected) {\n reject(new Error('WebSocket connection timeout'));\n }\n }, 10000);\n }).finally(() => {\n this.connectPromise = null;\n });\n\n return this.connectPromise;\n }\n\n disconnect() {\n if (typeof window === 'undefined') return;\n\n if (this.socket) {\n this.socket.onopen = null;\n this.socket.onmessage = null;\n this.socket.onerror = null;\n this.socket.onclose = null;\n if (this.socket.readyState === WebSocket.OPEN || this.socket.readyState === WebSocket.CONNECTING) {\n this.socket.close();\n }\n this.socket = null;\n }\n\n if (this.pingInterval) {\n clearInterval(this.pingInterval);\n this.pingInterval = null;\n }\n\n // Отменяем все ожидающие RPC вызовы\n for (const [id, { reject }] of this.rpcCallbacks.entries()) {\n reject(new Error('WebSocket disconnected'));\n this.rpcCallbacks.delete(id);\n }\n\n this.isConnected = false;\n this.userId = null;\n this.subscribedModules.clear(); // Очищаем подписки при отключении\n }\n\n async send(data) {\n if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {\n console.error('Cannot send message: WebSocket is not connected');\n return false;\n }\n\n try {\n const msg = typeof data === 'string' ? data : JSON.stringify(data);\n this.socket.send(msg);\n return true;\n } catch (err) {\n console.error('Error sending message:', err);\n return false;\n }\n }\n\n /**\n * Выполняет RPC вызов на сервере\n * @param {string} module - Имя модуля\n * @param {string} method - Имя метода\n * @param {object} params - Параметры метода\n * @param {object} [options] - Опции вызова\n * @param {number} [options.timeout] - Таймаут в миллисекундах\n * @returns {Promise<any>} - Результат вызова\n */\n rpc(module, method, params = {}, options = {}) {\n if (!this.isConnected || this.socket?.readyState !== WebSocket.OPEN) {\n return Promise.reject(new Error('WebSocket is not connected'));\n }\n\n if (!module || !method) {\n return Promise.reject(new Error('Module and method are required'));\n }\n\n // Генерируем уникальный ID для вызова\n const id = `${++this.rpcIdCounter}`;\n const timeout = options.timeout || this.rpcTimeout;\n\n return new Promise((resolve, reject) => {\n // Записываем информацию о вызове для последующей обработки ответа\n this.rpcCallbacks.set(id, {\n resolve,\n reject,\n timeoutId: setTimeout(() => {\n if (this.rpcCallbacks.has(id)) {\n this.rpcCallbacks.delete(id);\n reject(new Error(`RPC call to ${module}.${method} timed out after ${timeout}ms`));\n }\n }, timeout),\n });\n\n // Отправляем RPC запрос\n this.send({\n type: 'rpc',\n module,\n method,\n params,\n id,\n }).catch(err => {\n if (this.rpcCallbacks.has(id)) {\n clearTimeout(this.rpcCallbacks.get(id).timeoutId);\n this.rpcCallbacks.delete(id);\n reject(err);\n }\n });\n });\n }\n\n addEventListener(eventType, callback, options = {}) {\n const listenerId = `${options.module || 'global'}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n if (!this.listeners[eventType]) this.listeners[eventType] = {};\n this.listeners[eventType][listenerId] = callback;\n return listenerId;\n }\n\n removeEventListener(eventType, listenerId) {\n if (this.listeners[eventType]?.[listenerId]) {\n delete this.listeners[eventType][listenerId];\n }\n }\n\n removeModuleListeners(moduleName) {\n Object.keys(this.listeners).forEach(eventType => {\n Object.keys(this.listeners[eventType]).forEach(listenerId => {\n if (listenerId.startsWith(`${moduleName}_`)) {\n delete this.listeners[eventType][listenerId];\n }\n });\n });\n }\n\n async subscribeModule(moduleName) {\n if (!moduleName || this.subscribedModules.has(moduleName)) return;\n const success = await this.send({ type: 'subscribe', module: moduleName });\n if (success) {\n this.subscribedModules.add(moduleName);\n }\n }\n\n async unsubscribeModule(moduleName) {\n if (!moduleName || !this.subscribedModules.has(moduleName)) return;\n const success = await this.send({ type: 'unsubscribe', module: moduleName });\n if (success) {\n this.subscribedModules.delete(moduleName);\n }\n }\n\n _resubscribeAllModules() {\n for (const moduleName of this.subscribedModules) {\n this.send({ type: 'subscribe', module: moduleName });\n }\n }\n\n _handleOpen() {\n this.isConnected = true;\n this.reconnectAttempts = 0;\n\n this.pingInterval = setInterval(() => {\n if (this.socket?.readyState === WebSocket.OPEN) {\n this.socket.send(JSON.stringify({ type: 'ping' }));\n }\n }, this.pingIntervalTime);\n\n this._resubscribeAllModules();\n this._notifyListeners('open', { isConnected: true });\n }\n\n _handleMessage(event) {\n // Проверка на типы сообщений - пропускаем бинарные сообщения\n if (typeof event.data !== 'string') {\n console.warn('Received binary message, but only JSON is supported');\n return;\n }\n\n try {\n const data = JSON.parse(event.data);\n\n // Обрабатываем ответы на RPC вызовы\n if (data.type === 'rpc_response' && data.id && this.rpcCallbacks.has(data.id)) {\n const { resolve, reject, timeoutId } = this.rpcCallbacks.get(data.id);\n clearTimeout(timeoutId);\n this.rpcCallbacks.delete(data.id);\n\n if (data.error) {\n reject(Object.assign(new Error(data.error.message), data.error));\n } else {\n resolve(data.result);\n }\n\n return;\n }\n\n // Обрабатываем обычные сообщения\n this._notifyListeners('message', data);\n if (data.type) {\n this._notifyListeners(data.type, data);\n }\n } catch (err) {\n console.error('WebSocket message error:', err);\n }\n }\n\n _handleError(error) {\n console.error('WebSocket error:', error);\n this._notifyListeners('error', { error });\n\n // Отменяем все RPC вызовы с ошибкой соединения\n for (const [id, { reject, timeoutId }] of this.rpcCallbacks.entries()) {\n clearTimeout(timeoutId);\n reject(new Error('WebSocket connection error'));\n this.rpcCallbacks.delete(id);\n }\n }\n\n _handleClose(event) {\n this.isConnected = false;\n if (this.pingInterval) {\n clearInterval(this.pingInterval);\n this.pingInterval = null;\n }\n\n // Отменяем все RPC вызовы при закрытии соединения\n for (const [id, { reject, timeoutId }] of this.rpcCallbacks.entries()) {\n clearTimeout(timeoutId);\n reject(new Error('WebSocket connection closed'));\n this.rpcCallbacks.delete(id);\n }\n\n this._notifyListeners('close', { code: event.code, reason: event.reason });\n\n if (event.code !== 1000 && this.userId && this.reconnectAttempts < this.maxReconnectAttempts) {\n this.reconnectAttempts++;\n const delay = this.reconnectDelay * this.reconnectAttempts;\n setTimeout(() => {\n this.connect(this.userId).catch(err => {\n console.error('Reconnection failed:', err);\n });\n }, delay);\n }\n }\n\n _notifyListeners(eventType, data) {\n Object.values(this.listeners[eventType] || {}).forEach(fn => {\n try {\n fn(data);\n } catch (err) {\n console.error(`Listener for ${eventType} failed:`, err);\n }\n });\n }\n\n isSocketConnected() {\n return this.isConnected && this.socket?.readyState === WebSocket.OPEN;\n }\n}\n\nconst globalWebSocket = new GlobalWebSocket();\nexport default globalWebSocket;\n"],"names":["module"],"mappings":"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"}
@@ -17,6 +17,10 @@ class GlobalWebSocket {
17
17
  this.rpcIdCounter = 0;
18
18
  }
19
19
  initialize(options = {}) {
20
+ console.log("WSS initialize options:", options);
21
+ console.log("options.wsUrl:", options.wsUrl);
22
+ console.log("window.location.protocol:", window.location.protocol);
23
+ console.log("window.location.host:", window.location.host);
20
24
  this.maxReconnectAttempts = options.maxReconnectAttempts || this.maxReconnectAttempts;
21
25
  this.reconnectDelay = options.reconnectDelay || this.reconnectDelay;
22
26
  this.baseUrl = options.wsUrl || this._getDefaultWsUrl();
@@ -26,7 +30,7 @@ class GlobalWebSocket {
26
30
  _getDefaultWsUrl() {
27
31
  if (typeof window === "undefined") return "/api/ws";
28
32
  const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
29
- const host = window.location.host;
33
+ const host = window.location.hostname;
30
34
  return `${protocol}//${host}/api/ws`;
31
35
  }
32
36
  connect(userId) {
@@ -1 +1 @@
1
- {"version":3,"file":"globals.websocket.js","sources":["../../../../../../../src/modules/globals/views/classes/globals.websocket.js"],"sourcesContent":["class GlobalWebSocket {\n constructor() {\n this.socket = null;\n this.isConnected = false;\n this.reconnectAttempts = 0;\n this.maxReconnectAttempts = 5;\n this.reconnectDelay = 3000;\n this.baseUrl = null;\n this.pingInterval = null;\n this.pingIntervalTime = 30000;\n this.listeners = {};\n this.userId = null;\n this.connectPromise = null;\n this.subscribedModules = new Set();\n\n // RPC-специфичные свойства\n this.rpcCallbacks = new Map();\n this.rpcTimeout = 30000; // 30 секунд таймаут по умолчанию\n this.rpcIdCounter = 0;\n }\n\n initialize(options = {}) {\n this.maxReconnectAttempts = options.maxReconnectAttempts || this.maxReconnectAttempts;\n this.reconnectDelay = options.reconnectDelay || this.reconnectDelay;\n this.baseUrl = options.wsUrl || this._getDefaultWsUrl();\n this.pingIntervalTime = options.pingInterval || this.pingIntervalTime;\n this.rpcTimeout = options.rpcTimeout || this.rpcTimeout;\n }\n\n _getDefaultWsUrl() {\n if (typeof window === 'undefined') return '/api/ws';\n const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';\n const host = window.location.host;\n return `${protocol}//${host}/api/ws`;\n }\n\n connect(userId) {\n if (typeof window === 'undefined') return Promise.resolve(false);\n this.userId = userId;\n\n // Проверяем существующее соединение\n if (this.isConnected && this.socket?.readyState === WebSocket.OPEN) {\n return Promise.resolve(this.socket);\n }\n\n // Предотвращаем создание множества промисов при параллельных вызовах\n if (this.connectPromise) {\n return this.connectPromise;\n }\n\n this.connectPromise = new Promise((resolve, reject) => {\n this.disconnect();\n\n // Используем baseUrl без параметров, так как аутентификация через cookie\n this.socket = new WebSocket(this.baseUrl);\n\n this.socket.onopen = () => {\n this._handleOpen();\n resolve(this.socket);\n };\n\n this.socket.onmessage = this._handleMessage.bind(this);\n this.socket.onerror = err => {\n this._handleError(err);\n reject(err);\n };\n this.socket.onclose = this._handleClose.bind(this);\n\n setTimeout(() => {\n if (!this.isConnected) {\n reject(new Error('WebSocket connection timeout'));\n }\n }, 10000);\n }).finally(() => {\n this.connectPromise = null;\n });\n\n return this.connectPromise;\n }\n\n disconnect() {\n if (typeof window === 'undefined') return;\n\n if (this.socket) {\n this.socket.onopen = null;\n this.socket.onmessage = null;\n this.socket.onerror = null;\n this.socket.onclose = null;\n if (this.socket.readyState === WebSocket.OPEN || this.socket.readyState === WebSocket.CONNECTING) {\n this.socket.close();\n }\n this.socket = null;\n }\n\n if (this.pingInterval) {\n clearInterval(this.pingInterval);\n this.pingInterval = null;\n }\n\n // Отменяем все ожидающие RPC вызовы\n for (const [id, { reject }] of this.rpcCallbacks.entries()) {\n reject(new Error('WebSocket disconnected'));\n this.rpcCallbacks.delete(id);\n }\n\n this.isConnected = false;\n this.userId = null;\n this.subscribedModules.clear(); // Очищаем подписки при отключении\n }\n\n async send(data) {\n if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {\n console.error('Cannot send message: WebSocket is not connected');\n return false;\n }\n\n try {\n const msg = typeof data === 'string' ? data : JSON.stringify(data);\n this.socket.send(msg);\n return true;\n } catch (err) {\n console.error('Error sending message:', err);\n return false;\n }\n }\n\n /**\n * Выполняет RPC вызов на сервере\n * @param {string} module - Имя модуля\n * @param {string} method - Имя метода\n * @param {object} params - Параметры метода\n * @param {object} [options] - Опции вызова\n * @param {number} [options.timeout] - Таймаут в миллисекундах\n * @returns {Promise<any>} - Результат вызова\n */\n rpc(module, method, params = {}, options = {}) {\n if (!this.isConnected || this.socket?.readyState !== WebSocket.OPEN) {\n return Promise.reject(new Error('WebSocket is not connected'));\n }\n\n if (!module || !method) {\n return Promise.reject(new Error('Module and method are required'));\n }\n\n // Генерируем уникальный ID для вызова\n const id = `${++this.rpcIdCounter}`;\n const timeout = options.timeout || this.rpcTimeout;\n\n return new Promise((resolve, reject) => {\n // Записываем информацию о вызове для последующей обработки ответа\n this.rpcCallbacks.set(id, {\n resolve,\n reject,\n timeoutId: setTimeout(() => {\n if (this.rpcCallbacks.has(id)) {\n this.rpcCallbacks.delete(id);\n reject(new Error(`RPC call to ${module}.${method} timed out after ${timeout}ms`));\n }\n }, timeout),\n });\n\n // Отправляем RPC запрос\n this.send({\n type: 'rpc',\n module,\n method,\n params,\n id,\n }).catch(err => {\n if (this.rpcCallbacks.has(id)) {\n clearTimeout(this.rpcCallbacks.get(id).timeoutId);\n this.rpcCallbacks.delete(id);\n reject(err);\n }\n });\n });\n }\n\n addEventListener(eventType, callback, options = {}) {\n const listenerId = `${options.module || 'global'}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n if (!this.listeners[eventType]) this.listeners[eventType] = {};\n this.listeners[eventType][listenerId] = callback;\n return listenerId;\n }\n\n removeEventListener(eventType, listenerId) {\n if (this.listeners[eventType]?.[listenerId]) {\n delete this.listeners[eventType][listenerId];\n }\n }\n\n removeModuleListeners(moduleName) {\n Object.keys(this.listeners).forEach(eventType => {\n Object.keys(this.listeners[eventType]).forEach(listenerId => {\n if (listenerId.startsWith(`${moduleName}_`)) {\n delete this.listeners[eventType][listenerId];\n }\n });\n });\n }\n\n async subscribeModule(moduleName) {\n if (!moduleName || this.subscribedModules.has(moduleName)) return;\n const success = await this.send({ type: 'subscribe', module: moduleName });\n if (success) {\n this.subscribedModules.add(moduleName);\n }\n }\n\n async unsubscribeModule(moduleName) {\n if (!moduleName || !this.subscribedModules.has(moduleName)) return;\n const success = await this.send({ type: 'unsubscribe', module: moduleName });\n if (success) {\n this.subscribedModules.delete(moduleName);\n }\n }\n\n _resubscribeAllModules() {\n for (const moduleName of this.subscribedModules) {\n this.send({ type: 'subscribe', module: moduleName });\n }\n }\n\n _handleOpen() {\n this.isConnected = true;\n this.reconnectAttempts = 0;\n\n this.pingInterval = setInterval(() => {\n if (this.socket?.readyState === WebSocket.OPEN) {\n this.socket.send(JSON.stringify({ type: 'ping' }));\n }\n }, this.pingIntervalTime);\n\n this._resubscribeAllModules();\n this._notifyListeners('open', { isConnected: true });\n }\n\n _handleMessage(event) {\n // Проверка на типы сообщений - пропускаем бинарные сообщения\n if (typeof event.data !== 'string') {\n console.warn('Received binary message, but only JSON is supported');\n return;\n }\n\n try {\n const data = JSON.parse(event.data);\n\n // Обрабатываем ответы на RPC вызовы\n if (data.type === 'rpc_response' && data.id && this.rpcCallbacks.has(data.id)) {\n const { resolve, reject, timeoutId } = this.rpcCallbacks.get(data.id);\n clearTimeout(timeoutId);\n this.rpcCallbacks.delete(data.id);\n\n if (data.error) {\n reject(Object.assign(new Error(data.error.message), data.error));\n } else {\n resolve(data.result);\n }\n\n return;\n }\n\n // Обрабатываем обычные сообщения\n this._notifyListeners('message', data);\n if (data.type) {\n this._notifyListeners(data.type, data);\n }\n } catch (err) {\n console.error('WebSocket message error:', err);\n }\n }\n\n _handleError(error) {\n console.error('WebSocket error:', error);\n this._notifyListeners('error', { error });\n\n // Отменяем все RPC вызовы с ошибкой соединения\n for (const [id, { reject, timeoutId }] of this.rpcCallbacks.entries()) {\n clearTimeout(timeoutId);\n reject(new Error('WebSocket connection error'));\n this.rpcCallbacks.delete(id);\n }\n }\n\n _handleClose(event) {\n this.isConnected = false;\n if (this.pingInterval) {\n clearInterval(this.pingInterval);\n this.pingInterval = null;\n }\n\n // Отменяем все RPC вызовы при закрытии соединения\n for (const [id, { reject, timeoutId }] of this.rpcCallbacks.entries()) {\n clearTimeout(timeoutId);\n reject(new Error('WebSocket connection closed'));\n this.rpcCallbacks.delete(id);\n }\n\n this._notifyListeners('close', { code: event.code, reason: event.reason });\n\n if (event.code !== 1000 && this.userId && this.reconnectAttempts < this.maxReconnectAttempts) {\n this.reconnectAttempts++;\n const delay = this.reconnectDelay * this.reconnectAttempts;\n setTimeout(() => {\n this.connect(this.userId).catch(err => {\n console.error('Reconnection failed:', err);\n });\n }, delay);\n }\n }\n\n _notifyListeners(eventType, data) {\n Object.values(this.listeners[eventType] || {}).forEach(fn => {\n try {\n fn(data);\n } catch (err) {\n console.error(`Listener for ${eventType} failed:`, err);\n }\n });\n }\n\n isSocketConnected() {\n return this.isConnected && this.socket?.readyState === WebSocket.OPEN;\n }\n}\n\nconst globalWebSocket = new GlobalWebSocket();\nexport default globalWebSocket;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"globals.websocket.js","sources":["../../../../../../../src/modules/globals/views/classes/globals.websocket.js"],"sourcesContent":["class GlobalWebSocket {\n constructor() {\n this.socket = null;\n this.isConnected = false;\n this.reconnectAttempts = 0;\n this.maxReconnectAttempts = 5;\n this.reconnectDelay = 3000;\n this.baseUrl = null;\n this.pingInterval = null;\n this.pingIntervalTime = 30000;\n this.listeners = {};\n this.userId = null;\n this.connectPromise = null;\n this.subscribedModules = new Set();\n\n // RPC-специфичные свойства\n this.rpcCallbacks = new Map();\n this.rpcTimeout = 30000; // 30 секунд таймаут по умолчанию\n this.rpcIdCounter = 0;\n }\n\n initialize(options = {}) {\n console.log('WSS initialize options:', options);\n console.log('options.wsUrl:', options.wsUrl);\n console.log('window.location.protocol:', window.location.protocol);\n console.log('window.location.host:', window.location.host);\n \n this.maxReconnectAttempts = options.maxReconnectAttempts || this.maxReconnectAttempts;\n this.reconnectDelay = options.reconnectDelay || this.reconnectDelay;\n this.baseUrl = options.wsUrl || this._getDefaultWsUrl();\n this.pingIntervalTime = options.pingInterval || this.pingIntervalTime;\n this.rpcTimeout = options.rpcTimeout || this.rpcTimeout;\n }\n\n _getDefaultWsUrl() {\n if (typeof window === 'undefined') return '/api/ws';\n const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';\n const host = window.location.hostname;\n return `${protocol}//${host}/api/ws`;\n }\n\n connect(userId) {\n if (typeof window === 'undefined') return Promise.resolve(false);\n this.userId = userId;\n\n // Проверяем существующее соединение\n if (this.isConnected && this.socket?.readyState === WebSocket.OPEN) {\n return Promise.resolve(this.socket);\n }\n\n // Предотвращаем создание множества промисов при параллельных вызовах\n if (this.connectPromise) {\n return this.connectPromise;\n }\n\n this.connectPromise = new Promise((resolve, reject) => {\n this.disconnect();\n\n // Используем baseUrl без параметров, так как аутентификация через cookie\n this.socket = new WebSocket(this.baseUrl);\n\n this.socket.onopen = () => {\n this._handleOpen();\n resolve(this.socket);\n };\n\n this.socket.onmessage = this._handleMessage.bind(this);\n this.socket.onerror = err => {\n this._handleError(err);\n reject(err);\n };\n this.socket.onclose = this._handleClose.bind(this);\n\n setTimeout(() => {\n if (!this.isConnected) {\n reject(new Error('WebSocket connection timeout'));\n }\n }, 10000);\n }).finally(() => {\n this.connectPromise = null;\n });\n\n return this.connectPromise;\n }\n\n disconnect() {\n if (typeof window === 'undefined') return;\n\n if (this.socket) {\n this.socket.onopen = null;\n this.socket.onmessage = null;\n this.socket.onerror = null;\n this.socket.onclose = null;\n if (this.socket.readyState === WebSocket.OPEN || this.socket.readyState === WebSocket.CONNECTING) {\n this.socket.close();\n }\n this.socket = null;\n }\n\n if (this.pingInterval) {\n clearInterval(this.pingInterval);\n this.pingInterval = null;\n }\n\n // Отменяем все ожидающие RPC вызовы\n for (const [id, { reject }] of this.rpcCallbacks.entries()) {\n reject(new Error('WebSocket disconnected'));\n this.rpcCallbacks.delete(id);\n }\n\n this.isConnected = false;\n this.userId = null;\n this.subscribedModules.clear(); // Очищаем подписки при отключении\n }\n\n async send(data) {\n if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {\n console.error('Cannot send message: WebSocket is not connected');\n return false;\n }\n\n try {\n const msg = typeof data === 'string' ? data : JSON.stringify(data);\n this.socket.send(msg);\n return true;\n } catch (err) {\n console.error('Error sending message:', err);\n return false;\n }\n }\n\n /**\n * Выполняет RPC вызов на сервере\n * @param {string} module - Имя модуля\n * @param {string} method - Имя метода\n * @param {object} params - Параметры метода\n * @param {object} [options] - Опции вызова\n * @param {number} [options.timeout] - Таймаут в миллисекундах\n * @returns {Promise<any>} - Результат вызова\n */\n rpc(module, method, params = {}, options = {}) {\n if (!this.isConnected || this.socket?.readyState !== WebSocket.OPEN) {\n return Promise.reject(new Error('WebSocket is not connected'));\n }\n\n if (!module || !method) {\n return Promise.reject(new Error('Module and method are required'));\n }\n\n // Генерируем уникальный ID для вызова\n const id = `${++this.rpcIdCounter}`;\n const timeout = options.timeout || this.rpcTimeout;\n\n return new Promise((resolve, reject) => {\n // Записываем информацию о вызове для последующей обработки ответа\n this.rpcCallbacks.set(id, {\n resolve,\n reject,\n timeoutId: setTimeout(() => {\n if (this.rpcCallbacks.has(id)) {\n this.rpcCallbacks.delete(id);\n reject(new Error(`RPC call to ${module}.${method} timed out after ${timeout}ms`));\n }\n }, timeout),\n });\n\n // Отправляем RPC запрос\n this.send({\n type: 'rpc',\n module,\n method,\n params,\n id,\n }).catch(err => {\n if (this.rpcCallbacks.has(id)) {\n clearTimeout(this.rpcCallbacks.get(id).timeoutId);\n this.rpcCallbacks.delete(id);\n reject(err);\n }\n });\n });\n }\n\n addEventListener(eventType, callback, options = {}) {\n const listenerId = `${options.module || 'global'}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n if (!this.listeners[eventType]) this.listeners[eventType] = {};\n this.listeners[eventType][listenerId] = callback;\n return listenerId;\n }\n\n removeEventListener(eventType, listenerId) {\n if (this.listeners[eventType]?.[listenerId]) {\n delete this.listeners[eventType][listenerId];\n }\n }\n\n removeModuleListeners(moduleName) {\n Object.keys(this.listeners).forEach(eventType => {\n Object.keys(this.listeners[eventType]).forEach(listenerId => {\n if (listenerId.startsWith(`${moduleName}_`)) {\n delete this.listeners[eventType][listenerId];\n }\n });\n });\n }\n\n async subscribeModule(moduleName) {\n if (!moduleName || this.subscribedModules.has(moduleName)) return;\n const success = await this.send({ type: 'subscribe', module: moduleName });\n if (success) {\n this.subscribedModules.add(moduleName);\n }\n }\n\n async unsubscribeModule(moduleName) {\n if (!moduleName || !this.subscribedModules.has(moduleName)) return;\n const success = await this.send({ type: 'unsubscribe', module: moduleName });\n if (success) {\n this.subscribedModules.delete(moduleName);\n }\n }\n\n _resubscribeAllModules() {\n for (const moduleName of this.subscribedModules) {\n this.send({ type: 'subscribe', module: moduleName });\n }\n }\n\n _handleOpen() {\n this.isConnected = true;\n this.reconnectAttempts = 0;\n\n this.pingInterval = setInterval(() => {\n if (this.socket?.readyState === WebSocket.OPEN) {\n this.socket.send(JSON.stringify({ type: 'ping' }));\n }\n }, this.pingIntervalTime);\n\n this._resubscribeAllModules();\n this._notifyListeners('open', { isConnected: true });\n }\n\n _handleMessage(event) {\n // Проверка на типы сообщений - пропускаем бинарные сообщения\n if (typeof event.data !== 'string') {\n console.warn('Received binary message, but only JSON is supported');\n return;\n }\n\n try {\n const data = JSON.parse(event.data);\n\n // Обрабатываем ответы на RPC вызовы\n if (data.type === 'rpc_response' && data.id && this.rpcCallbacks.has(data.id)) {\n const { resolve, reject, timeoutId } = this.rpcCallbacks.get(data.id);\n clearTimeout(timeoutId);\n this.rpcCallbacks.delete(data.id);\n\n if (data.error) {\n reject(Object.assign(new Error(data.error.message), data.error));\n } else {\n resolve(data.result);\n }\n\n return;\n }\n\n // Обрабатываем обычные сообщения\n this._notifyListeners('message', data);\n if (data.type) {\n this._notifyListeners(data.type, data);\n }\n } catch (err) {\n console.error('WebSocket message error:', err);\n }\n }\n\n _handleError(error) {\n console.error('WebSocket error:', error);\n this._notifyListeners('error', { error });\n\n // Отменяем все RPC вызовы с ошибкой соединения\n for (const [id, { reject, timeoutId }] of this.rpcCallbacks.entries()) {\n clearTimeout(timeoutId);\n reject(new Error('WebSocket connection error'));\n this.rpcCallbacks.delete(id);\n }\n }\n\n _handleClose(event) {\n this.isConnected = false;\n if (this.pingInterval) {\n clearInterval(this.pingInterval);\n this.pingInterval = null;\n }\n\n // Отменяем все RPC вызовы при закрытии соединения\n for (const [id, { reject, timeoutId }] of this.rpcCallbacks.entries()) {\n clearTimeout(timeoutId);\n reject(new Error('WebSocket connection closed'));\n this.rpcCallbacks.delete(id);\n }\n\n this._notifyListeners('close', { code: event.code, reason: event.reason });\n\n if (event.code !== 1000 && this.userId && this.reconnectAttempts < this.maxReconnectAttempts) {\n this.reconnectAttempts++;\n const delay = this.reconnectDelay * this.reconnectAttempts;\n setTimeout(() => {\n this.connect(this.userId).catch(err => {\n console.error('Reconnection failed:', err);\n });\n }, delay);\n }\n }\n\n _notifyListeners(eventType, data) {\n Object.values(this.listeners[eventType] || {}).forEach(fn => {\n try {\n fn(data);\n } catch (err) {\n console.error(`Listener for ${eventType} failed:`, err);\n }\n });\n }\n\n isSocketConnected() {\n return this.isConnected && this.socket?.readyState === WebSocket.OPEN;\n }\n}\n\nconst globalWebSocket = new GlobalWebSocket();\nexport default globalWebSocket;\n"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
3
  const vue = require("vue");
4
4
  const vueRouter = require("vue-router");
5
- const Tooltip = require("../../../../../components/Tooltip/Tooltip.vue.cjs");
5
+ const Tooltip = require("../../../../../components/Tooltip/Tooltip.vue2.cjs");
6
6
  const Dropdown = require("../../../../../components/Dropdown/Dropdown.vue2.cjs");
7
7
  const PlaceholderUserpic = require("../../../../icons/placeholders/PlaceholderUserpic.vue.cjs");
8
8
  const PlaceholderOrganizationPic = require("../../../../icons/placeholders/PlaceholderOrganizationPic.vue.cjs");
@@ -1,6 +1,6 @@
1
1
  import { resolveComponent, createElementBlock, createCommentVNode, openBlock, createElementVNode, createBlock, withModifiers, resolveDynamicComponent, toDisplayString, withCtx, createTextVNode, Fragment, renderList, normalizeClass } from "vue";
2
2
  import { useRouter } from "vue-router";
3
- import _sfc_main$1 from "../../../../../components/Tooltip/Tooltip.vue.js";
3
+ import _sfc_main$1 from "../../../../../components/Tooltip/Tooltip.vue2.js";
4
4
  import _sfc_main$3 from "../../../../../components/Dropdown/Dropdown.vue2.js";
5
5
  import PlaceholderUserpic from "../../../../icons/placeholders/PlaceholderUserpic.vue.js";
6
6
  import PlaceholderOrganizationPic from "../../../../icons/placeholders/PlaceholderOrganizationPic.vue.js";
@@ -16,7 +16,7 @@ require("../../globals/views/store/globals.cjs");
16
16
  ;/* empty css */
17
17
  ;/* empty css */
18
18
  ;/* empty css */
19
- ;/* empty css */
19
+ ;/* empty css */
20
20
  require("axios");
21
21
  ;/* empty css */
22
22
  require("../store/playlists.cjs");
@@ -14,7 +14,7 @@ import "../../globals/views/store/globals.js";
14
14
  /* empty css */
15
15
  /* empty css */
16
16
  /* empty css */
17
- /* empty css */
17
+ /* empty css */
18
18
  import "axios";
19
19
  /* empty css */
20
20
  import "../store/playlists.js";
@@ -158,6 +158,11 @@ class NotificationManager {
158
158
  return;
159
159
  }
160
160
  console.log("Connecting to websockets via notifications");
161
+ globals_websocket.default.initialize({
162
+ wsUrl: app.config.globalProperties.WSS_URL,
163
+ maxReconnectAttempts: 10,
164
+ reconnectDelay: 2e3
165
+ });
161
166
  await globals_websocket.default.connect(userId);
162
167
  globals_websocket.default.removeModuleListeners("notification");
163
168
  await globals_websocket.default.subscribeModule("notification");
@@ -199,12 +204,12 @@ const SSRUtils = {
199
204
  }
200
205
  }
201
206
  };
202
- function initializeNotifications(app, store, router, options = {}) {
207
+ function initializeNotifications(app2, store, router, options = {}) {
203
208
  const route = options.route || "User Profile Root";
204
209
  router.addRoute(route, notifications_router.default);
205
210
  store.addStore("notifications", notifications_store);
206
211
  if (options.wsUrl) {
207
- globals_websocket.default.initialize({ wsUrl: app.config.globalProperties.WSS_URL });
212
+ globals_websocket.default.initialize({ wsUrl: app2.config.globalProperties.WSS_URL });
208
213
  }
209
214
  const notificationManager = new NotificationManager(store, {
210
215
  enablePush: options.enablePush !== false,
@@ -233,7 +238,7 @@ function initializeNotifications(app, store, router, options = {}) {
233
238
  }
234
239
  );
235
240
  }
236
- app.provide("useNotifications", () => {
241
+ app2.provide("useNotifications", () => {
237
242
  return {
238
243
  ...vue.toRefs(store.notifications.state),
239
244
  ...store.notifications.actions,
@@ -1 +1 @@
1
- {"version":3,"file":"notifications.client.cjs","sources":["../../../../../src/modules/notifications/notifications.client.js"],"sourcesContent":["import { toRefs, watch } from 'vue';\n// Router import\nimport routerNotifications from './router/notifications.router.js';\n// Store\nimport * as storeNotifications from './store/notifications.store.js';\n// Auth store import\n// Global WebSocket import\nimport globalWebSocket from '@martyrs/src/modules/globals/views/classes/globals.websocket.js';\n// Layouts\nimport NotificationsLayout from './components/layouts/NotificationsLayout.vue';\n// Sections\nimport NotificationPreferences from './components/sections/NotificationPreferences.vue';\nimport NotificationsList from './components/sections/NotificationsList.vue';\n// Pages\nimport Notifications from './components/pages/Notifications.vue';\n// Components\nimport NotificationItem from './components/blocks/NotificationItem.vue';\nimport NotificationBadge from './components/elements/NotificationBadge.vue';\n\n/**\n * Capacitor Push Notification handler\n */\nclass CapacitorPushHandler {\n constructor(store) {\n this.store = store;\n this.pushNotifications = null;\n this.device = null;\n this.isInitialized = false;\n }\n\n /**\n * Initialize Capacitor plugins\n */\n async initialize() {\n // Skip if running in SSR\n if (typeof window === 'undefined') {\n return false;\n }\n\n try {\n // Dynamic imports to prevent errors in web environment\n const { Capacitor } = await import('@capacitor/core');\n const { PushNotifications } = await import('@capacitor/push-notifications');\n const { Device } = await import('@capacitor/device');\n\n this.capacitor = Capacitor;\n this.pushNotifications = PushNotifications;\n this.device = Device;\n\n // Only proceed if running on a native platform\n if (!this.capacitor.isNativePlatform()) {\n return false;\n }\n\n this.isInitialized = true;\n return true;\n } catch (error) {\n console.error('Error importing Capacitor plugins:', error);\n return false;\n }\n }\n\n /**\n * Request permission and register for push notifications\n */\n async requestPermissions() {\n // Skip if running in SSR\n if (typeof window === 'undefined') {\n return false;\n }\n\n if (!this.isInitialized) {\n const initialized = await this.initialize();\n if (!initialized) return false;\n }\n\n try {\n // Request permission\n const permissionResult = await this.pushNotifications.requestPermissions();\n if (permissionResult.receive !== 'granted') {\n console.log('Push notification permission denied');\n return false;\n }\n\n // Set up event listeners\n this._setupListeners();\n\n // Register with Apple/Google\n await this.pushNotifications.register();\n return true;\n } catch (error) {\n console.error('Error requesting push notification permissions:', error);\n return false;\n }\n }\n\n /**\n * Setup push notification event listeners\n */\n _setupListeners() {\n // Registration event\n this.pushNotifications.addListener('registration', this._handleRegistration.bind(this));\n\n // Notification received event\n this.pushNotifications.addListener('pushNotificationReceived', this._handleNotificationReceived.bind(this));\n\n // Notification action performed event\n this.pushNotifications.addListener('pushNotificationActionPerformed', this._handleNotificationAction.bind(this));\n }\n\n /**\n * Handle registration token received\n */\n async _handleRegistration(token) {\n try {\n // Get device info\n const deviceInfo = await this.device.getInfo();\n const deviceId = await this.device.getId();\n\n // Prepare device data\n const deviceData = {\n deviceId: deviceId.uuid,\n deviceType: deviceInfo.platform.toLowerCase(),\n deviceToken: token.value,\n };\n\n // Register device with backend\n await this.store.notifications.actions.registerDevice(deviceData);\n } catch (error) {\n console.error('Error handling push registration:', error);\n }\n }\n\n /**\n * Handle received notification\n */\n _handleNotificationReceived(notification) {\n // Add notification to store\n this.store.notifications.actions.addLocalNotification({\n title: notification.title,\n body: notification.body,\n data: notification.data || {},\n });\n }\n\n /**\n * Handle notification action (when user taps on notification)\n */\n _handleNotificationAction(actionData) {\n if (actionData.notification && actionData.notification.data) {\n this.store.notifications.actions.handleNotificationAction(actionData.notification.data);\n }\n }\n\n /**\n * Remove push notification listeners\n */\n removeListeners() {\n if (typeof window === 'undefined') {\n return;\n }\n\n if (this.pushNotifications) {\n this.pushNotifications.removeAllListeners();\n }\n }\n}\n\n/**\n * Notification Manager for coordinating WebSocket and Push notifications\n */\n\nclass NotificationManager {\n constructor(store, options = {}) {\n this.store = store;\n this.options = options;\n this.pushHandler = new CapacitorPushHandler(store);\n this.initialized = false;\n this.isServer = typeof window === 'undefined';\n }\n\n async registerWebPush(store) {\n if (!('Notification' in window) || !('serviceWorker' in navigator) || !('PushManager' in window)) {\n console.warn('Web Push не поддерживается в браузере');\n return;\n }\n\n const permission = await Notification.requestPermission();\n if (permission !== 'granted') {\n console.warn('Разрешение на уведомления не получено');\n return;\n }\n\n const registration = await navigator.serviceWorker.ready;\n const subscription = await registration.pushManager.subscribe({\n userVisibleOnly: true,\n applicationServerKey: 'BJtNnRrx05VQS0abnkHC-8gHJWpnmoqC_iQveENCmZOZIs-adWzqAiqFCdGVVd7CbiaLW-Q5iuIBDRgM9G-VnKg',\n });\n\n console.log('New subscription:', JSON.stringify(subscription));\n\n // Отправь подписку на сервер\n await store.notifications.actions.registerDevice({\n deviceToken: JSON.stringify(subscription),\n deviceType: 'web',\n });\n }\n\n async initialize() {\n if (this.initialized || this.isServer) return;\n\n const userId = this.store.auth.state.user?._id;\n if (!userId) {\n console.warn('Cannot initialize notifications: No user ID found in auth store');\n return;\n }\n\n console.log('Connecting to websockets via notifications');\n await globalWebSocket.connect(userId);\n\n globalWebSocket.removeModuleListeners('notification');\n\n await globalWebSocket.subscribeModule('notification');\n\n globalWebSocket.addEventListener(\n 'notification',\n data => {\n this.store.notifications.actions.addLocalNotification(data.data);\n },\n { module: 'notification' }\n );\n\n // 🎯 Опционально включаем push\n if (this.options.enablePush !== false) {\n await this.pushHandler.requestPermissions();\n await this.registerWebPush(this.store);\n }\n\n this.initialized = true;\n\n // ✅ Загружаем список уведомлений из API\n await this.store.notifications.actions.getNotifications(userId);\n }\n\n disconnect() {\n if (this.isServer) return;\n\n globalWebSocket.removeModuleListeners('notification');\n this.pushHandler.removeListeners();\n this.initialized = false;\n }\n}\n\n/**\n * Server-side utility for pre-fetching notification data\n */\nconst SSRUtils = {\n /**\n * Pre-fetch notifications for SSR\n * @param {Object} store - Store instance\n * @param {Object} context - SSR context\n */\n async prefetchNotifications(store, context) {\n try {\n const userId = store.auth.state.user?._id;\n if (userId) {\n // Fetch notifications without WebSocket or push setup\n await store.notifications.actions.getNotifications(userId);\n }\n } catch (error) {\n console.error('Error pre-fetching notifications for SSR:', error);\n }\n },\n};\n\n/**\n * Function to initialize the notifications module\n * @param {Object} app - Vue app instance\n * @param {Object} store - Vuex/Pinia store\n * @param {Object} router - Vue Router instance\n * @param {Object} options - Configuration options\n */\nfunction initializeNotifications(app, store, router, options = {}) {\n // Add routes and store\n const route = options.route || 'User Profile Root';\n router.addRoute(route, routerNotifications);\n store.addStore('notifications', storeNotifications);\n\n // Initialize global WebSocket if needed\n if (options.wsUrl) {\n globalWebSocket.initialize({ wsUrl: app.config.globalProperties.WSS_URL });\n }\n\n // Create notification manager\n const notificationManager = new NotificationManager(store, {\n enablePush: options.enablePush !== false,\n maxReconnectAttempts: options.maxReconnectAttempts || 5,\n reconnectDelay: options.reconnectDelay || 3000,\n pingInterval: options.pingInterval || 30000,\n });\n\n // Attach notification manager to store for access in components\n store.notificationManager = notificationManager;\n\n // Don't auto-initialize on server\n const isServer = typeof window === 'undefined';\n const autoInit = !isServer && options.autoInit !== false;\n\n if (autoInit) {\n // Initialize after auth is confirmed\n const isAuthenticated = store.auth.state.access.status;\n const userId = store.auth.state.user?._id;\n\n if (isAuthenticated && userId) {\n notificationManager.initialize();\n }\n\n // Watch for user login/logout using auth store\n watch(\n () => store.auth.state.access.status,\n isAuthenticated => {\n if (isAuthenticated) {\n notificationManager.initialize();\n } else {\n notificationManager.disconnect();\n store.notifications.mutations.resetNotifications();\n }\n }\n );\n }\n\n // Provide composable for components to access notification functionality\n app.provide('useNotifications', () => {\n return {\n ...toRefs(store.notifications.state),\n ...store.notifications.actions,\n ...store.notifications.mutations,\n init: notificationManager.initialize.bind(notificationManager),\n disconnect: notificationManager.disconnect.bind(notificationManager),\n isServer,\n };\n });\n\n return notificationManager;\n}\n\n// Module export\nconst ModuleNotifications = {\n initialize: initializeNotifications,\n SSR: SSRUtils, // Export SSR utilities\n views: {\n store: {\n storeNotifications,\n },\n router: {\n routerNotifications,\n },\n components: {\n // Elements\n NotificationBadge,\n // Blocks\n NotificationItem,\n // Sections\n NotificationsList,\n NotificationPreferences,\n // Pages\n Notifications,\n // Layouts\n NotificationsLayout,\n },\n },\n};\n\n// Component exports\nexport {\n // Elements\n NotificationBadge,\n // Blocks\n NotificationItem,\n NotificationPreferences,\n // Pages\n Notifications,\n // Layouts\n NotificationsLayout,\n // Sections\n NotificationsList,\n // SSR Utilities\n SSRUtils,\n};\n\nexport default ModuleNotifications;\n"],"names":["globalWebSocket","routerNotifications","storeNotifications","watch","isAuthenticated","toRefs","NotificationBadge","NotificationItem","NotificationsList","NotificationPreferences","Notifications","NotificationsLayout"],"mappings":"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"}
1
+ {"version":3,"file":"notifications.client.cjs","sources":["../../../../../src/modules/notifications/notifications.client.js"],"sourcesContent":["import { toRefs, watch } from 'vue';\n// Router import\nimport routerNotifications from './router/notifications.router.js';\n// Store\nimport * as storeNotifications from './store/notifications.store.js';\n// Auth store import\n// Global WebSocket import\nimport globalWebSocket from '@martyrs/src/modules/globals/views/classes/globals.websocket.js';\n// Layouts\nimport NotificationsLayout from './components/layouts/NotificationsLayout.vue';\n// Sections\nimport NotificationPreferences from './components/sections/NotificationPreferences.vue';\nimport NotificationsList from './components/sections/NotificationsList.vue';\n// Pages\nimport Notifications from './components/pages/Notifications.vue';\n// Components\nimport NotificationItem from './components/blocks/NotificationItem.vue';\nimport NotificationBadge from './components/elements/NotificationBadge.vue';\n\n/**\n * Capacitor Push Notification handler\n */\nclass CapacitorPushHandler {\n constructor(store) {\n this.store = store;\n this.pushNotifications = null;\n this.device = null;\n this.isInitialized = false;\n }\n\n /**\n * Initialize Capacitor plugins\n */\n async initialize() {\n // Skip if running in SSR\n if (typeof window === 'undefined') {\n return false;\n }\n\n try {\n // Dynamic imports to prevent errors in web environment\n const { Capacitor } = await import('@capacitor/core');\n const { PushNotifications } = await import('@capacitor/push-notifications');\n const { Device } = await import('@capacitor/device');\n\n this.capacitor = Capacitor;\n this.pushNotifications = PushNotifications;\n this.device = Device;\n\n // Only proceed if running on a native platform\n if (!this.capacitor.isNativePlatform()) {\n return false;\n }\n\n this.isInitialized = true;\n return true;\n } catch (error) {\n console.error('Error importing Capacitor plugins:', error);\n return false;\n }\n }\n\n /**\n * Request permission and register for push notifications\n */\n async requestPermissions() {\n // Skip if running in SSR\n if (typeof window === 'undefined') {\n return false;\n }\n\n if (!this.isInitialized) {\n const initialized = await this.initialize();\n if (!initialized) return false;\n }\n\n try {\n // Request permission\n const permissionResult = await this.pushNotifications.requestPermissions();\n if (permissionResult.receive !== 'granted') {\n console.log('Push notification permission denied');\n return false;\n }\n\n // Set up event listeners\n this._setupListeners();\n\n // Register with Apple/Google\n await this.pushNotifications.register();\n return true;\n } catch (error) {\n console.error('Error requesting push notification permissions:', error);\n return false;\n }\n }\n\n /**\n * Setup push notification event listeners\n */\n _setupListeners() {\n // Registration event\n this.pushNotifications.addListener('registration', this._handleRegistration.bind(this));\n\n // Notification received event\n this.pushNotifications.addListener('pushNotificationReceived', this._handleNotificationReceived.bind(this));\n\n // Notification action performed event\n this.pushNotifications.addListener('pushNotificationActionPerformed', this._handleNotificationAction.bind(this));\n }\n\n /**\n * Handle registration token received\n */\n async _handleRegistration(token) {\n try {\n // Get device info\n const deviceInfo = await this.device.getInfo();\n const deviceId = await this.device.getId();\n\n // Prepare device data\n const deviceData = {\n deviceId: deviceId.uuid,\n deviceType: deviceInfo.platform.toLowerCase(),\n deviceToken: token.value,\n };\n\n // Register device with backend\n await this.store.notifications.actions.registerDevice(deviceData);\n } catch (error) {\n console.error('Error handling push registration:', error);\n }\n }\n\n /**\n * Handle received notification\n */\n _handleNotificationReceived(notification) {\n // Add notification to store\n this.store.notifications.actions.addLocalNotification({\n title: notification.title,\n body: notification.body,\n data: notification.data || {},\n });\n }\n\n /**\n * Handle notification action (when user taps on notification)\n */\n _handleNotificationAction(actionData) {\n if (actionData.notification && actionData.notification.data) {\n this.store.notifications.actions.handleNotificationAction(actionData.notification.data);\n }\n }\n\n /**\n * Remove push notification listeners\n */\n removeListeners() {\n if (typeof window === 'undefined') {\n return;\n }\n\n if (this.pushNotifications) {\n this.pushNotifications.removeAllListeners();\n }\n }\n}\n\n/**\n * Notification Manager for coordinating WebSocket and Push notifications\n */\n\nclass NotificationManager {\n constructor(store, options = {}) {\n this.store = store;\n this.options = options;\n this.pushHandler = new CapacitorPushHandler(store);\n this.initialized = false;\n this.isServer = typeof window === 'undefined';\n }\n\n async registerWebPush(store) {\n if (!('Notification' in window) || !('serviceWorker' in navigator) || !('PushManager' in window)) {\n console.warn('Web Push не поддерживается в браузере');\n return;\n }\n\n const permission = await Notification.requestPermission();\n if (permission !== 'granted') {\n console.warn('Разрешение на уведомления не получено');\n return;\n }\n\n const registration = await navigator.serviceWorker.ready;\n const subscription = await registration.pushManager.subscribe({\n userVisibleOnly: true,\n applicationServerKey: 'BJtNnRrx05VQS0abnkHC-8gHJWpnmoqC_iQveENCmZOZIs-adWzqAiqFCdGVVd7CbiaLW-Q5iuIBDRgM9G-VnKg',\n });\n\n console.log('New subscription:', JSON.stringify(subscription));\n\n // Отправь подписку на сервер\n await store.notifications.actions.registerDevice({\n deviceToken: JSON.stringify(subscription),\n deviceType: 'web',\n });\n }\n\n async initialize() {\n if (this.initialized || this.isServer) return;\n\n const userId = this.store.auth.state.user?._id;\n if (!userId) {\n console.warn('Cannot initialize notifications: No user ID found in auth store');\n return;\n }\n\n \n console.log('Connecting to websockets via notifications');\n globalWebSocket.initialize({\n wsUrl: app.config.globalProperties.WSS_URL,\n maxReconnectAttempts: 10,\n reconnectDelay: 2000,\n });\n\n await globalWebSocket.connect(userId);\n\n globalWebSocket.removeModuleListeners('notification');\n\n await globalWebSocket.subscribeModule('notification');\n\n globalWebSocket.addEventListener(\n 'notification',\n data => {\n this.store.notifications.actions.addLocalNotification(data.data);\n },\n { module: 'notification' }\n );\n\n // 🎯 Опционально включаем push\n if (this.options.enablePush !== false) {\n await this.pushHandler.requestPermissions();\n await this.registerWebPush(this.store);\n }\n\n this.initialized = true;\n\n // ✅ Загружаем список уведомлений из API\n await this.store.notifications.actions.getNotifications(userId);\n }\n\n disconnect() {\n if (this.isServer) return;\n\n globalWebSocket.removeModuleListeners('notification');\n this.pushHandler.removeListeners();\n this.initialized = false;\n }\n}\n\n/**\n * Server-side utility for pre-fetching notification data\n */\nconst SSRUtils = {\n /**\n * Pre-fetch notifications for SSR\n * @param {Object} store - Store instance\n * @param {Object} context - SSR context\n */\n async prefetchNotifications(store, context) {\n try {\n const userId = store.auth.state.user?._id;\n if (userId) {\n // Fetch notifications without WebSocket or push setup\n await store.notifications.actions.getNotifications(userId);\n }\n } catch (error) {\n console.error('Error pre-fetching notifications for SSR:', error);\n }\n },\n};\n\n/**\n * Function to initialize the notifications module\n * @param {Object} app - Vue app instance\n * @param {Object} store - Vuex/Pinia store\n * @param {Object} router - Vue Router instance\n * @param {Object} options - Configuration options\n */\nfunction initializeNotifications(app, store, router, options = {}) {\n // Add routes and store\n const route = options.route || 'User Profile Root';\n router.addRoute(route, routerNotifications);\n store.addStore('notifications', storeNotifications);\n\n // Initialize global WebSocket if needed\n if (options.wsUrl) {\n globalWebSocket.initialize({ wsUrl: app.config.globalProperties.WSS_URL });\n }\n\n // Create notification manager\n const notificationManager = new NotificationManager(store, {\n enablePush: options.enablePush !== false,\n maxReconnectAttempts: options.maxReconnectAttempts || 5,\n reconnectDelay: options.reconnectDelay || 3000,\n pingInterval: options.pingInterval || 30000,\n });\n\n // Attach notification manager to store for access in components\n store.notificationManager = notificationManager;\n\n // Don't auto-initialize on server\n const isServer = typeof window === 'undefined';\n const autoInit = !isServer && options.autoInit !== false;\n\n if (autoInit) {\n // Initialize after auth is confirmed\n const isAuthenticated = store.auth.state.access.status;\n const userId = store.auth.state.user?._id;\n\n if (isAuthenticated && userId) {\n notificationManager.initialize();\n }\n\n // Watch for user login/logout using auth store\n watch(\n () => store.auth.state.access.status,\n isAuthenticated => {\n if (isAuthenticated) {\n notificationManager.initialize();\n } else {\n notificationManager.disconnect();\n store.notifications.mutations.resetNotifications();\n }\n }\n );\n }\n\n // Provide composable for components to access notification functionality\n app.provide('useNotifications', () => {\n return {\n ...toRefs(store.notifications.state),\n ...store.notifications.actions,\n ...store.notifications.mutations,\n init: notificationManager.initialize.bind(notificationManager),\n disconnect: notificationManager.disconnect.bind(notificationManager),\n isServer,\n };\n });\n\n return notificationManager;\n}\n\n// Module export\nconst ModuleNotifications = {\n initialize: initializeNotifications,\n SSR: SSRUtils, // Export SSR utilities\n views: {\n store: {\n storeNotifications,\n },\n router: {\n routerNotifications,\n },\n components: {\n // Elements\n NotificationBadge,\n // Blocks\n NotificationItem,\n // Sections\n NotificationsList,\n NotificationPreferences,\n // Pages\n Notifications,\n // Layouts\n NotificationsLayout,\n },\n },\n};\n\n// Component exports\nexport {\n // Elements\n NotificationBadge,\n // Blocks\n NotificationItem,\n NotificationPreferences,\n // Pages\n Notifications,\n // Layouts\n NotificationsLayout,\n // Sections\n NotificationsList,\n // SSR Utilities\n SSRUtils,\n};\n\nexport default ModuleNotifications;\n"],"names":["globalWebSocket","app","routerNotifications","storeNotifications","watch","isAuthenticated","toRefs","NotificationBadge","NotificationItem","NotificationsList","NotificationPreferences","Notifications","NotificationsLayout"],"mappings":"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"}
@@ -156,6 +156,11 @@ class NotificationManager {
156
156
  return;
157
157
  }
158
158
  console.log("Connecting to websockets via notifications");
159
+ globalWebSocket.initialize({
160
+ wsUrl: app.config.globalProperties.WSS_URL,
161
+ maxReconnectAttempts: 10,
162
+ reconnectDelay: 2e3
163
+ });
159
164
  await globalWebSocket.connect(userId);
160
165
  globalWebSocket.removeModuleListeners("notification");
161
166
  await globalWebSocket.subscribeModule("notification");
@@ -197,12 +202,12 @@ const SSRUtils = {
197
202
  }
198
203
  }
199
204
  };
200
- function initializeNotifications(app, store, router, options = {}) {
205
+ function initializeNotifications(app2, store, router, options = {}) {
201
206
  const route = options.route || "User Profile Root";
202
207
  router.addRoute(route, nofitications);
203
208
  store.addStore("notifications", notifications_store);
204
209
  if (options.wsUrl) {
205
- globalWebSocket.initialize({ wsUrl: app.config.globalProperties.WSS_URL });
210
+ globalWebSocket.initialize({ wsUrl: app2.config.globalProperties.WSS_URL });
206
211
  }
207
212
  const notificationManager = new NotificationManager(store, {
208
213
  enablePush: options.enablePush !== false,
@@ -231,7 +236,7 @@ function initializeNotifications(app, store, router, options = {}) {
231
236
  }
232
237
  );
233
238
  }
234
- app.provide("useNotifications", () => {
239
+ app2.provide("useNotifications", () => {
235
240
  return {
236
241
  ...toRefs(store.notifications.state),
237
242
  ...store.notifications.actions,
@@ -1 +1 @@
1
- {"version":3,"file":"notifications.client.js","sources":["../../../../../src/modules/notifications/notifications.client.js"],"sourcesContent":["import { toRefs, watch } from 'vue';\n// Router import\nimport routerNotifications from './router/notifications.router.js';\n// Store\nimport * as storeNotifications from './store/notifications.store.js';\n// Auth store import\n// Global WebSocket import\nimport globalWebSocket from '@martyrs/src/modules/globals/views/classes/globals.websocket.js';\n// Layouts\nimport NotificationsLayout from './components/layouts/NotificationsLayout.vue';\n// Sections\nimport NotificationPreferences from './components/sections/NotificationPreferences.vue';\nimport NotificationsList from './components/sections/NotificationsList.vue';\n// Pages\nimport Notifications from './components/pages/Notifications.vue';\n// Components\nimport NotificationItem from './components/blocks/NotificationItem.vue';\nimport NotificationBadge from './components/elements/NotificationBadge.vue';\n\n/**\n * Capacitor Push Notification handler\n */\nclass CapacitorPushHandler {\n constructor(store) {\n this.store = store;\n this.pushNotifications = null;\n this.device = null;\n this.isInitialized = false;\n }\n\n /**\n * Initialize Capacitor plugins\n */\n async initialize() {\n // Skip if running in SSR\n if (typeof window === 'undefined') {\n return false;\n }\n\n try {\n // Dynamic imports to prevent errors in web environment\n const { Capacitor } = await import('@capacitor/core');\n const { PushNotifications } = await import('@capacitor/push-notifications');\n const { Device } = await import('@capacitor/device');\n\n this.capacitor = Capacitor;\n this.pushNotifications = PushNotifications;\n this.device = Device;\n\n // Only proceed if running on a native platform\n if (!this.capacitor.isNativePlatform()) {\n return false;\n }\n\n this.isInitialized = true;\n return true;\n } catch (error) {\n console.error('Error importing Capacitor plugins:', error);\n return false;\n }\n }\n\n /**\n * Request permission and register for push notifications\n */\n async requestPermissions() {\n // Skip if running in SSR\n if (typeof window === 'undefined') {\n return false;\n }\n\n if (!this.isInitialized) {\n const initialized = await this.initialize();\n if (!initialized) return false;\n }\n\n try {\n // Request permission\n const permissionResult = await this.pushNotifications.requestPermissions();\n if (permissionResult.receive !== 'granted') {\n console.log('Push notification permission denied');\n return false;\n }\n\n // Set up event listeners\n this._setupListeners();\n\n // Register with Apple/Google\n await this.pushNotifications.register();\n return true;\n } catch (error) {\n console.error('Error requesting push notification permissions:', error);\n return false;\n }\n }\n\n /**\n * Setup push notification event listeners\n */\n _setupListeners() {\n // Registration event\n this.pushNotifications.addListener('registration', this._handleRegistration.bind(this));\n\n // Notification received event\n this.pushNotifications.addListener('pushNotificationReceived', this._handleNotificationReceived.bind(this));\n\n // Notification action performed event\n this.pushNotifications.addListener('pushNotificationActionPerformed', this._handleNotificationAction.bind(this));\n }\n\n /**\n * Handle registration token received\n */\n async _handleRegistration(token) {\n try {\n // Get device info\n const deviceInfo = await this.device.getInfo();\n const deviceId = await this.device.getId();\n\n // Prepare device data\n const deviceData = {\n deviceId: deviceId.uuid,\n deviceType: deviceInfo.platform.toLowerCase(),\n deviceToken: token.value,\n };\n\n // Register device with backend\n await this.store.notifications.actions.registerDevice(deviceData);\n } catch (error) {\n console.error('Error handling push registration:', error);\n }\n }\n\n /**\n * Handle received notification\n */\n _handleNotificationReceived(notification) {\n // Add notification to store\n this.store.notifications.actions.addLocalNotification({\n title: notification.title,\n body: notification.body,\n data: notification.data || {},\n });\n }\n\n /**\n * Handle notification action (when user taps on notification)\n */\n _handleNotificationAction(actionData) {\n if (actionData.notification && actionData.notification.data) {\n this.store.notifications.actions.handleNotificationAction(actionData.notification.data);\n }\n }\n\n /**\n * Remove push notification listeners\n */\n removeListeners() {\n if (typeof window === 'undefined') {\n return;\n }\n\n if (this.pushNotifications) {\n this.pushNotifications.removeAllListeners();\n }\n }\n}\n\n/**\n * Notification Manager for coordinating WebSocket and Push notifications\n */\n\nclass NotificationManager {\n constructor(store, options = {}) {\n this.store = store;\n this.options = options;\n this.pushHandler = new CapacitorPushHandler(store);\n this.initialized = false;\n this.isServer = typeof window === 'undefined';\n }\n\n async registerWebPush(store) {\n if (!('Notification' in window) || !('serviceWorker' in navigator) || !('PushManager' in window)) {\n console.warn('Web Push не поддерживается в браузере');\n return;\n }\n\n const permission = await Notification.requestPermission();\n if (permission !== 'granted') {\n console.warn('Разрешение на уведомления не получено');\n return;\n }\n\n const registration = await navigator.serviceWorker.ready;\n const subscription = await registration.pushManager.subscribe({\n userVisibleOnly: true,\n applicationServerKey: 'BJtNnRrx05VQS0abnkHC-8gHJWpnmoqC_iQveENCmZOZIs-adWzqAiqFCdGVVd7CbiaLW-Q5iuIBDRgM9G-VnKg',\n });\n\n console.log('New subscription:', JSON.stringify(subscription));\n\n // Отправь подписку на сервер\n await store.notifications.actions.registerDevice({\n deviceToken: JSON.stringify(subscription),\n deviceType: 'web',\n });\n }\n\n async initialize() {\n if (this.initialized || this.isServer) return;\n\n const userId = this.store.auth.state.user?._id;\n if (!userId) {\n console.warn('Cannot initialize notifications: No user ID found in auth store');\n return;\n }\n\n console.log('Connecting to websockets via notifications');\n await globalWebSocket.connect(userId);\n\n globalWebSocket.removeModuleListeners('notification');\n\n await globalWebSocket.subscribeModule('notification');\n\n globalWebSocket.addEventListener(\n 'notification',\n data => {\n this.store.notifications.actions.addLocalNotification(data.data);\n },\n { module: 'notification' }\n );\n\n // 🎯 Опционально включаем push\n if (this.options.enablePush !== false) {\n await this.pushHandler.requestPermissions();\n await this.registerWebPush(this.store);\n }\n\n this.initialized = true;\n\n // ✅ Загружаем список уведомлений из API\n await this.store.notifications.actions.getNotifications(userId);\n }\n\n disconnect() {\n if (this.isServer) return;\n\n globalWebSocket.removeModuleListeners('notification');\n this.pushHandler.removeListeners();\n this.initialized = false;\n }\n}\n\n/**\n * Server-side utility for pre-fetching notification data\n */\nconst SSRUtils = {\n /**\n * Pre-fetch notifications for SSR\n * @param {Object} store - Store instance\n * @param {Object} context - SSR context\n */\n async prefetchNotifications(store, context) {\n try {\n const userId = store.auth.state.user?._id;\n if (userId) {\n // Fetch notifications without WebSocket or push setup\n await store.notifications.actions.getNotifications(userId);\n }\n } catch (error) {\n console.error('Error pre-fetching notifications for SSR:', error);\n }\n },\n};\n\n/**\n * Function to initialize the notifications module\n * @param {Object} app - Vue app instance\n * @param {Object} store - Vuex/Pinia store\n * @param {Object} router - Vue Router instance\n * @param {Object} options - Configuration options\n */\nfunction initializeNotifications(app, store, router, options = {}) {\n // Add routes and store\n const route = options.route || 'User Profile Root';\n router.addRoute(route, routerNotifications);\n store.addStore('notifications', storeNotifications);\n\n // Initialize global WebSocket if needed\n if (options.wsUrl) {\n globalWebSocket.initialize({ wsUrl: app.config.globalProperties.WSS_URL });\n }\n\n // Create notification manager\n const notificationManager = new NotificationManager(store, {\n enablePush: options.enablePush !== false,\n maxReconnectAttempts: options.maxReconnectAttempts || 5,\n reconnectDelay: options.reconnectDelay || 3000,\n pingInterval: options.pingInterval || 30000,\n });\n\n // Attach notification manager to store for access in components\n store.notificationManager = notificationManager;\n\n // Don't auto-initialize on server\n const isServer = typeof window === 'undefined';\n const autoInit = !isServer && options.autoInit !== false;\n\n if (autoInit) {\n // Initialize after auth is confirmed\n const isAuthenticated = store.auth.state.access.status;\n const userId = store.auth.state.user?._id;\n\n if (isAuthenticated && userId) {\n notificationManager.initialize();\n }\n\n // Watch for user login/logout using auth store\n watch(\n () => store.auth.state.access.status,\n isAuthenticated => {\n if (isAuthenticated) {\n notificationManager.initialize();\n } else {\n notificationManager.disconnect();\n store.notifications.mutations.resetNotifications();\n }\n }\n );\n }\n\n // Provide composable for components to access notification functionality\n app.provide('useNotifications', () => {\n return {\n ...toRefs(store.notifications.state),\n ...store.notifications.actions,\n ...store.notifications.mutations,\n init: notificationManager.initialize.bind(notificationManager),\n disconnect: notificationManager.disconnect.bind(notificationManager),\n isServer,\n };\n });\n\n return notificationManager;\n}\n\n// Module export\nconst ModuleNotifications = {\n initialize: initializeNotifications,\n SSR: SSRUtils, // Export SSR utilities\n views: {\n store: {\n storeNotifications,\n },\n router: {\n routerNotifications,\n },\n components: {\n // Elements\n NotificationBadge,\n // Blocks\n NotificationItem,\n // Sections\n NotificationsList,\n NotificationPreferences,\n // Pages\n Notifications,\n // Layouts\n NotificationsLayout,\n },\n },\n};\n\n// Component exports\nexport {\n // Elements\n NotificationBadge,\n // Blocks\n NotificationItem,\n NotificationPreferences,\n // Pages\n Notifications,\n // Layouts\n NotificationsLayout,\n // Sections\n NotificationsList,\n // SSR Utilities\n SSRUtils,\n};\n\nexport default ModuleNotifications;\n"],"names":["routerNotifications","storeNotifications","isAuthenticated","Notifications","NotificationsLayout"],"mappings":"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"}
1
+ {"version":3,"file":"notifications.client.js","sources":["../../../../../src/modules/notifications/notifications.client.js"],"sourcesContent":["import { toRefs, watch } from 'vue';\n// Router import\nimport routerNotifications from './router/notifications.router.js';\n// Store\nimport * as storeNotifications from './store/notifications.store.js';\n// Auth store import\n// Global WebSocket import\nimport globalWebSocket from '@martyrs/src/modules/globals/views/classes/globals.websocket.js';\n// Layouts\nimport NotificationsLayout from './components/layouts/NotificationsLayout.vue';\n// Sections\nimport NotificationPreferences from './components/sections/NotificationPreferences.vue';\nimport NotificationsList from './components/sections/NotificationsList.vue';\n// Pages\nimport Notifications from './components/pages/Notifications.vue';\n// Components\nimport NotificationItem from './components/blocks/NotificationItem.vue';\nimport NotificationBadge from './components/elements/NotificationBadge.vue';\n\n/**\n * Capacitor Push Notification handler\n */\nclass CapacitorPushHandler {\n constructor(store) {\n this.store = store;\n this.pushNotifications = null;\n this.device = null;\n this.isInitialized = false;\n }\n\n /**\n * Initialize Capacitor plugins\n */\n async initialize() {\n // Skip if running in SSR\n if (typeof window === 'undefined') {\n return false;\n }\n\n try {\n // Dynamic imports to prevent errors in web environment\n const { Capacitor } = await import('@capacitor/core');\n const { PushNotifications } = await import('@capacitor/push-notifications');\n const { Device } = await import('@capacitor/device');\n\n this.capacitor = Capacitor;\n this.pushNotifications = PushNotifications;\n this.device = Device;\n\n // Only proceed if running on a native platform\n if (!this.capacitor.isNativePlatform()) {\n return false;\n }\n\n this.isInitialized = true;\n return true;\n } catch (error) {\n console.error('Error importing Capacitor plugins:', error);\n return false;\n }\n }\n\n /**\n * Request permission and register for push notifications\n */\n async requestPermissions() {\n // Skip if running in SSR\n if (typeof window === 'undefined') {\n return false;\n }\n\n if (!this.isInitialized) {\n const initialized = await this.initialize();\n if (!initialized) return false;\n }\n\n try {\n // Request permission\n const permissionResult = await this.pushNotifications.requestPermissions();\n if (permissionResult.receive !== 'granted') {\n console.log('Push notification permission denied');\n return false;\n }\n\n // Set up event listeners\n this._setupListeners();\n\n // Register with Apple/Google\n await this.pushNotifications.register();\n return true;\n } catch (error) {\n console.error('Error requesting push notification permissions:', error);\n return false;\n }\n }\n\n /**\n * Setup push notification event listeners\n */\n _setupListeners() {\n // Registration event\n this.pushNotifications.addListener('registration', this._handleRegistration.bind(this));\n\n // Notification received event\n this.pushNotifications.addListener('pushNotificationReceived', this._handleNotificationReceived.bind(this));\n\n // Notification action performed event\n this.pushNotifications.addListener('pushNotificationActionPerformed', this._handleNotificationAction.bind(this));\n }\n\n /**\n * Handle registration token received\n */\n async _handleRegistration(token) {\n try {\n // Get device info\n const deviceInfo = await this.device.getInfo();\n const deviceId = await this.device.getId();\n\n // Prepare device data\n const deviceData = {\n deviceId: deviceId.uuid,\n deviceType: deviceInfo.platform.toLowerCase(),\n deviceToken: token.value,\n };\n\n // Register device with backend\n await this.store.notifications.actions.registerDevice(deviceData);\n } catch (error) {\n console.error('Error handling push registration:', error);\n }\n }\n\n /**\n * Handle received notification\n */\n _handleNotificationReceived(notification) {\n // Add notification to store\n this.store.notifications.actions.addLocalNotification({\n title: notification.title,\n body: notification.body,\n data: notification.data || {},\n });\n }\n\n /**\n * Handle notification action (when user taps on notification)\n */\n _handleNotificationAction(actionData) {\n if (actionData.notification && actionData.notification.data) {\n this.store.notifications.actions.handleNotificationAction(actionData.notification.data);\n }\n }\n\n /**\n * Remove push notification listeners\n */\n removeListeners() {\n if (typeof window === 'undefined') {\n return;\n }\n\n if (this.pushNotifications) {\n this.pushNotifications.removeAllListeners();\n }\n }\n}\n\n/**\n * Notification Manager for coordinating WebSocket and Push notifications\n */\n\nclass NotificationManager {\n constructor(store, options = {}) {\n this.store = store;\n this.options = options;\n this.pushHandler = new CapacitorPushHandler(store);\n this.initialized = false;\n this.isServer = typeof window === 'undefined';\n }\n\n async registerWebPush(store) {\n if (!('Notification' in window) || !('serviceWorker' in navigator) || !('PushManager' in window)) {\n console.warn('Web Push не поддерживается в браузере');\n return;\n }\n\n const permission = await Notification.requestPermission();\n if (permission !== 'granted') {\n console.warn('Разрешение на уведомления не получено');\n return;\n }\n\n const registration = await navigator.serviceWorker.ready;\n const subscription = await registration.pushManager.subscribe({\n userVisibleOnly: true,\n applicationServerKey: 'BJtNnRrx05VQS0abnkHC-8gHJWpnmoqC_iQveENCmZOZIs-adWzqAiqFCdGVVd7CbiaLW-Q5iuIBDRgM9G-VnKg',\n });\n\n console.log('New subscription:', JSON.stringify(subscription));\n\n // Отправь подписку на сервер\n await store.notifications.actions.registerDevice({\n deviceToken: JSON.stringify(subscription),\n deviceType: 'web',\n });\n }\n\n async initialize() {\n if (this.initialized || this.isServer) return;\n\n const userId = this.store.auth.state.user?._id;\n if (!userId) {\n console.warn('Cannot initialize notifications: No user ID found in auth store');\n return;\n }\n\n \n console.log('Connecting to websockets via notifications');\n globalWebSocket.initialize({\n wsUrl: app.config.globalProperties.WSS_URL,\n maxReconnectAttempts: 10,\n reconnectDelay: 2000,\n });\n\n await globalWebSocket.connect(userId);\n\n globalWebSocket.removeModuleListeners('notification');\n\n await globalWebSocket.subscribeModule('notification');\n\n globalWebSocket.addEventListener(\n 'notification',\n data => {\n this.store.notifications.actions.addLocalNotification(data.data);\n },\n { module: 'notification' }\n );\n\n // 🎯 Опционально включаем push\n if (this.options.enablePush !== false) {\n await this.pushHandler.requestPermissions();\n await this.registerWebPush(this.store);\n }\n\n this.initialized = true;\n\n // ✅ Загружаем список уведомлений из API\n await this.store.notifications.actions.getNotifications(userId);\n }\n\n disconnect() {\n if (this.isServer) return;\n\n globalWebSocket.removeModuleListeners('notification');\n this.pushHandler.removeListeners();\n this.initialized = false;\n }\n}\n\n/**\n * Server-side utility for pre-fetching notification data\n */\nconst SSRUtils = {\n /**\n * Pre-fetch notifications for SSR\n * @param {Object} store - Store instance\n * @param {Object} context - SSR context\n */\n async prefetchNotifications(store, context) {\n try {\n const userId = store.auth.state.user?._id;\n if (userId) {\n // Fetch notifications without WebSocket or push setup\n await store.notifications.actions.getNotifications(userId);\n }\n } catch (error) {\n console.error('Error pre-fetching notifications for SSR:', error);\n }\n },\n};\n\n/**\n * Function to initialize the notifications module\n * @param {Object} app - Vue app instance\n * @param {Object} store - Vuex/Pinia store\n * @param {Object} router - Vue Router instance\n * @param {Object} options - Configuration options\n */\nfunction initializeNotifications(app, store, router, options = {}) {\n // Add routes and store\n const route = options.route || 'User Profile Root';\n router.addRoute(route, routerNotifications);\n store.addStore('notifications', storeNotifications);\n\n // Initialize global WebSocket if needed\n if (options.wsUrl) {\n globalWebSocket.initialize({ wsUrl: app.config.globalProperties.WSS_URL });\n }\n\n // Create notification manager\n const notificationManager = new NotificationManager(store, {\n enablePush: options.enablePush !== false,\n maxReconnectAttempts: options.maxReconnectAttempts || 5,\n reconnectDelay: options.reconnectDelay || 3000,\n pingInterval: options.pingInterval || 30000,\n });\n\n // Attach notification manager to store for access in components\n store.notificationManager = notificationManager;\n\n // Don't auto-initialize on server\n const isServer = typeof window === 'undefined';\n const autoInit = !isServer && options.autoInit !== false;\n\n if (autoInit) {\n // Initialize after auth is confirmed\n const isAuthenticated = store.auth.state.access.status;\n const userId = store.auth.state.user?._id;\n\n if (isAuthenticated && userId) {\n notificationManager.initialize();\n }\n\n // Watch for user login/logout using auth store\n watch(\n () => store.auth.state.access.status,\n isAuthenticated => {\n if (isAuthenticated) {\n notificationManager.initialize();\n } else {\n notificationManager.disconnect();\n store.notifications.mutations.resetNotifications();\n }\n }\n );\n }\n\n // Provide composable for components to access notification functionality\n app.provide('useNotifications', () => {\n return {\n ...toRefs(store.notifications.state),\n ...store.notifications.actions,\n ...store.notifications.mutations,\n init: notificationManager.initialize.bind(notificationManager),\n disconnect: notificationManager.disconnect.bind(notificationManager),\n isServer,\n };\n });\n\n return notificationManager;\n}\n\n// Module export\nconst ModuleNotifications = {\n initialize: initializeNotifications,\n SSR: SSRUtils, // Export SSR utilities\n views: {\n store: {\n storeNotifications,\n },\n router: {\n routerNotifications,\n },\n components: {\n // Elements\n NotificationBadge,\n // Blocks\n NotificationItem,\n // Sections\n NotificationsList,\n NotificationPreferences,\n // Pages\n Notifications,\n // Layouts\n NotificationsLayout,\n },\n },\n};\n\n// Component exports\nexport {\n // Elements\n NotificationBadge,\n // Blocks\n NotificationItem,\n NotificationPreferences,\n // Pages\n Notifications,\n // Layouts\n NotificationsLayout,\n // Sections\n NotificationsList,\n // SSR Utilities\n SSRUtils,\n};\n\nexport default ModuleNotifications;\n"],"names":["app","routerNotifications","storeNotifications","isAuthenticated","Notifications","NotificationsLayout"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
3
  const vue = require("vue");
4
- const Tooltip = require("../../../../components/Tooltip/Tooltip.vue.cjs");
4
+ const Tooltip = require("../../../../components/Tooltip/Tooltip.vue2.cjs");
5
5
  const IconStatusCreated = require("../icons/IconStatusCreated.vue.cjs");
6
6
  const IconStatusConfirmed = require("../icons/IconStatusConfirmed.vue.cjs");
7
7
  const IconStatusInUse = require("../icons/IconStatusInUse.vue.cjs");
@@ -1,5 +1,5 @@
1
1
  import { computed, createElementBlock, openBlock, createElementVNode, createCommentVNode, normalizeClass, Fragment, renderList, toDisplayString, createVNode, withCtx, createBlock, resolveDynamicComponent } from "vue";
2
- import _sfc_main$7 from "../../../../components/Tooltip/Tooltip.vue.js";
2
+ import _sfc_main$7 from "../../../../components/Tooltip/Tooltip.vue2.js";
3
3
  import _sfc_main$6 from "../icons/IconStatusCreated.vue.js";
4
4
  import _sfc_main$5 from "../icons/IconStatusConfirmed.vue.js";
5
5
  import _sfc_main$2 from "../icons/IconStatusInUse.vue.js";
@@ -10,7 +10,7 @@ const CardOrderItem = require("../blocks/CardOrderItem.vue.cjs");
10
10
  const CardOrganization = require("../../../organizations/components/blocks/CardOrganization.vue.cjs");
11
11
  const ChatPage = require("../../../chats/components/pages/ChatPage.vue.cjs");
12
12
  const PriceTotal = require("../elements/PriceTotal.vue.cjs");
13
- ;/* empty css */
13
+ ;/* empty css */
14
14
  const globals = require("../../../globals/views/store/globals.cjs");
15
15
  const auth = require("../../../auth/views/store/auth.cjs");
16
16
  const orders = require("../../store/orders.cjs");
@@ -8,7 +8,7 @@ import _sfc_main$3 from "../blocks/CardOrderItem.vue.js";
8
8
  import _sfc_main$5 from "../../../organizations/components/blocks/CardOrganization.vue.js";
9
9
  import _sfc_main$6 from "../../../chats/components/pages/ChatPage.vue.js";
10
10
  import _sfc_main$4 from "../elements/PriceTotal.vue.js";
11
- /* empty css */
11
+ /* empty css */
12
12
  import { state } from "../../../globals/views/store/globals.js";
13
13
  import { state as state$1 } from "../../../auth/views/store/auth.js";
14
14
  import { actions, state as state$2, getters, mutations } from "../../store/orders.js";
@@ -4,7 +4,7 @@ const vue = require("vue");
4
4
  const vueRouter = require("vue-router");
5
5
  const Feed = require("../../../../components/Feed/Feed.vue.cjs");
6
6
  ;/* empty css */
7
- ;/* empty css */
7
+ ;/* empty css */
8
8
  const Popup = require("../../../../components/Popup/Popup.vue.cjs");
9
9
  const SectionPageTitle = require("../../../globals/views/components/sections/SectionPageTitle.vue.cjs");
10
10
  const MembersAdd = require("../sections/MembersAdd.vue.cjs");
@@ -2,7 +2,7 @@ import { ref, onMounted, computed, resolveComponent, createElementBlock, openBlo
2
2
  import { useRoute, useRouter } from "vue-router";
3
3
  import _sfc_main$4 from "../../../../components/Feed/Feed.vue.js";
4
4
  /* empty css */
5
- /* empty css */
5
+ /* empty css */
6
6
  import _sfc_main$2 from "../../../../components/Popup/Popup.vue.js";
7
7
  import _sfc_main$1 from "../../../globals/views/components/sections/SectionPageTitle.vue.js";
8
8
  import _sfc_main$3 from "../sections/MembersAdd.vue.js";
@@ -7,7 +7,7 @@ const pages = require("../../store/pages.cjs");
7
7
  const Button = require("../../../../../components/Button/Button.vue2.cjs");
8
8
  ;/* empty css */
9
9
  ;/* empty css */
10
- ;/* empty css */
10
+ ;/* empty css */
11
11
  const Constructor = require("../../../../constructor/components/sections/Constructor.vue.cjs");
12
12
  const _hoisted_1 = { key: 0 };
13
13
  const _hoisted_2 = {
@@ -5,7 +5,7 @@ import { actions, state } from "../../store/pages.js";
5
5
  import _sfc_main$2 from "../../../../../components/Button/Button.vue2.js";
6
6
  /* empty css */
7
7
  /* empty css */
8
- /* empty css */
8
+ /* empty css */
9
9
  import _sfc_main$1 from "../../../../constructor/components/sections/Constructor.vue.js";
10
10
  const _hoisted_1 = { key: 0 };
11
11
  const _hoisted_2 = {
@@ -3,7 +3,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
3
3
  const vue = require("vue");
4
4
  const IconDiscount = require("../../../icons/entities/IconDiscount.vue.cjs");
5
5
  const Chips = require("../../../../components/Chips/Chips.vue2.cjs");
6
- const Tooltip = require("../../../../components/Tooltip/Tooltip.vue.cjs");
6
+ const Tooltip = require("../../../../components/Tooltip/Tooltip.vue2.cjs");
7
7
  ;/* empty css */
8
8
  const _pluginVue_exportHelper = require("../../../../../../_virtual/_plugin-vue_export-helper.cjs");
9
9
  const _hoisted_1 = { key: 0 };
@@ -1,7 +1,7 @@
1
1
  import { computed, createElementBlock, createCommentVNode, openBlock, createElementVNode, createVNode, Fragment, renderList, withCtx, toDisplayString } from "vue";
2
2
  import _sfc_main$1 from "../../../icons/entities/IconDiscount.vue.js";
3
3
  import _sfc_main$3 from "../../../../components/Chips/Chips.vue2.js";
4
- import _sfc_main$2 from "../../../../components/Tooltip/Tooltip.vue.js";
4
+ import _sfc_main$2 from "../../../../components/Tooltip/Tooltip.vue2.js";
5
5
  /* empty css */
6
6
  import _export_sfc from "../../../../../../_virtual/_plugin-vue_export-helper.js";
7
7
  const _hoisted_1 = { key: 0 };
@@ -8,7 +8,7 @@ const wallet = require("../../localization/wallet.json.cjs");
8
8
  const Popup = require("../../../../../components/Popup/Popup.vue.cjs");
9
9
  const Button = require("../../../../../components/Button/Button.vue2.cjs");
10
10
  require("vue-router");
11
- ;/* empty css */
11
+ ;/* empty css */
12
12
  ;/* empty css */
13
13
  ;/* empty css */
14
14
  require("../../../../reports/store/reports.cjs");
@@ -6,7 +6,7 @@ import text from "../../localization/wallet.json.js";
6
6
  import _sfc_main$3 from "../../../../../components/Popup/Popup.vue.js";
7
7
  import _sfc_main$1 from "../../../../../components/Button/Button.vue2.js";
8
8
  import "vue-router";
9
- /* empty css */
9
+ /* empty css */
10
10
  /* empty css */
11
11
  /* empty css */
12
12
  import "../../../../reports/store/reports.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ozdao/martyrs",
3
- "version": "0.2.497",
3
+ "version": "0.2.498",
4
4
  "description": "Fullstack framework focused on user experience and ease of development.",
5
5
  "author": "OZ DAO <hello@ozdao.dev>",
6
6
  "license": "GPL-3.0-or-later",
@@ -20,6 +20,11 @@ class GlobalWebSocket {
20
20
  }
21
21
 
22
22
  initialize(options = {}) {
23
+ console.log('WSS initialize options:', options);
24
+ console.log('options.wsUrl:', options.wsUrl);
25
+ console.log('window.location.protocol:', window.location.protocol);
26
+ console.log('window.location.host:', window.location.host);
27
+
23
28
  this.maxReconnectAttempts = options.maxReconnectAttempts || this.maxReconnectAttempts;
24
29
  this.reconnectDelay = options.reconnectDelay || this.reconnectDelay;
25
30
  this.baseUrl = options.wsUrl || this._getDefaultWsUrl();
@@ -30,7 +35,7 @@ class GlobalWebSocket {
30
35
  _getDefaultWsUrl() {
31
36
  if (typeof window === 'undefined') return '/api/ws';
32
37
  const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
33
- const host = window.location.host;
38
+ const host = window.location.hostname;
34
39
  return `${protocol}//${host}/api/ws`;
35
40
  }
36
41
 
@@ -215,7 +215,14 @@ class NotificationManager {
215
215
  return;
216
216
  }
217
217
 
218
+
218
219
  console.log('Connecting to websockets via notifications');
220
+ globalWebSocket.initialize({
221
+ wsUrl: app.config.globalProperties.WSS_URL,
222
+ maxReconnectAttempts: 10,
223
+ reconnectDelay: 2000,
224
+ });
225
+
219
226
  await globalWebSocket.connect(userId);
220
227
 
221
228
  globalWebSocket.removeModuleListeners('notification');
@@ -1 +0,0 @@
1
- {"version":3,"file":"Tooltip.vue.js","sources":["../../../../../src/components/Tooltip/Tooltip.vue"],"sourcesContent":["<template>\n <div class=\"cursor-pointer tooltip-container\" @mouseover=\"showTooltip\" @mouseleave=\"hideTooltip\">\n <slot></slot>\n <div class=\"tooltip-content\" :style=\"tooltipStyle\">\n <span>{{ text }}</span>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, reactive } from 'vue';\n\nconst props = defineProps({\n text: {\n type: String,\n required: true\n }\n});\n\nconst visible = ref(false);\n\nconst tooltipStyle = reactive({\n position: 'absolute',\n width: 'max-content',\n zIndex: 1000,\n background: '#333',\n color: '#fff',\n padding: '5px',\n borderRadius: '3px',\n fontSize: '14px',\n display: 'none',\n});\n\nfunction showTooltip(event) {\n visible.value = true;\n tooltipStyle.left = `${(event.clientX / 100) + 10 }px`;\n tooltipStyle.top = `${(event.clientY / 100) + 10 }px`;\n tooltipStyle.display = 'block';\n}\n\nfunction hideTooltip() {\n visible.value = false;\n tooltipStyle.display = 'none';\n}\n</script>\n\n<style >\n.tooltip-container {\n position: relative;\n display: inline-block;\n}\n\n.tooltip-content {\n pointer-events: none;\n}\n</style>"],"names":[],"mappings":";;;;;;;;;;;AAmBA,UAAM,UAAU,IAAI,KAAK;AAEzB,UAAM,eAAe,SAAS;AAAA,MAC5B,UAAU;AAAA,MACV,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,OAAO;AAAA,MACP,SAAS;AAAA,MACT,cAAc;AAAA,MACd,UAAU;AAAA,MACV,SAAS;AAAA,IACX,CAAC;AAED,aAAS,YAAY,OAAO;AAC1B,cAAQ,QAAQ;AAChB,mBAAa,OAAO,GAAI,MAAM,UAAU,MAAO,EAAE;AACjD,mBAAa,MAAM,GAAI,MAAM,UAAU,MAAO,EAAE;AAChD,mBAAa,UAAU;AAAA,IACzB;AAEA,aAAS,cAAc;AACrB,cAAQ,QAAQ;AAChB,mBAAa,UAAU;AAAA,IACzB;;;;;;;;;;;;;;;;;;"}