@quvel-kit/core 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. package/README.md +670 -0
  2. package/dist/auth/boot/defineAuthGuard.d.ts +54 -0
  3. package/dist/auth/boot/defineAuthGuard.d.ts.map +1 -0
  4. package/dist/auth/boot/defineAuthGuard.js +72 -0
  5. package/dist/auth/enums/AuthStatusEnum.d.ts +13 -0
  6. package/dist/auth/enums/AuthStatusEnum.d.ts.map +1 -0
  7. package/dist/auth/enums/AuthStatusEnum.js +13 -0
  8. package/dist/auth/index.d.ts +13 -0
  9. package/dist/auth/index.d.ts.map +1 -0
  10. package/dist/auth/index.js +13 -0
  11. package/dist/auth/services/AuthGuard.d.ts +58 -0
  12. package/dist/auth/services/AuthGuard.d.ts.map +1 -0
  13. package/dist/auth/services/AuthGuard.js +51 -0
  14. package/dist/auth/services/AuthService.d.ts +52 -0
  15. package/dist/auth/services/AuthService.d.ts.map +1 -0
  16. package/dist/auth/services/AuthService.js +67 -0
  17. package/dist/auth/services/PasswordResetService.d.ts +34 -0
  18. package/dist/auth/services/PasswordResetService.d.ts.map +1 -0
  19. package/dist/auth/services/PasswordResetService.js +45 -0
  20. package/dist/auth/services/TwoFactorChallengeService.d.ts +22 -0
  21. package/dist/auth/services/TwoFactorChallengeService.d.ts.map +1 -0
  22. package/dist/auth/services/TwoFactorChallengeService.js +29 -0
  23. package/dist/auth/services/TwoFactorService.d.ts +64 -0
  24. package/dist/auth/services/TwoFactorService.d.ts.map +1 -0
  25. package/dist/auth/services/TwoFactorService.js +68 -0
  26. package/dist/auth/services/index.d.ts +8 -0
  27. package/dist/auth/services/index.d.ts.map +1 -0
  28. package/dist/auth/services/index.js +5 -0
  29. package/dist/auth/types/auth-meta.d.ts +54 -0
  30. package/dist/auth/types/auth-meta.d.ts.map +1 -0
  31. package/dist/auth/types/auth-meta.js +6 -0
  32. package/dist/auth/types/index.d.ts +5 -0
  33. package/dist/auth/types/index.d.ts.map +1 -0
  34. package/dist/auth/types/index.js +4 -0
  35. package/dist/auth/utils/auth-meta.d.ts +75 -0
  36. package/dist/auth/utils/auth-meta.d.ts.map +1 -0
  37. package/dist/auth/utils/auth-meta.js +93 -0
  38. package/dist/boot/quvel.d.ts +26 -0
  39. package/dist/boot/quvel.d.ts.map +1 -0
  40. package/dist/boot/quvel.js +38 -0
  41. package/dist/build/index.d.ts +9 -0
  42. package/dist/build/index.d.ts.map +1 -0
  43. package/dist/build/index.js +8 -0
  44. package/dist/build/loadEnv.d.ts +14 -0
  45. package/dist/build/loadEnv.d.ts.map +1 -0
  46. package/dist/build/loadEnv.js +33 -0
  47. package/dist/build/quasarConfig.d.ts +67 -0
  48. package/dist/build/quasarConfig.d.ts.map +1 -0
  49. package/dist/build/quasarConfig.js +126 -0
  50. package/dist/components/Common/TaskErrors.vue +47 -0
  51. package/dist/components/Inputs/BaseInput.vue +88 -0
  52. package/dist/components/Misc/ClientOnly.vue +22 -0
  53. package/dist/components/Transitions/FadeInOut.vue +9 -0
  54. package/dist/components/Transitions/SlowExpand.vue +13 -0
  55. package/dist/components/WebSocketChannelManager.vue +634 -0
  56. package/dist/components/index.d.ts +12 -0
  57. package/dist/components/index.d.ts.map +1 -0
  58. package/dist/components/index.js +16 -0
  59. package/dist/composables/index.d.ts +19 -0
  60. package/dist/composables/index.d.ts.map +1 -0
  61. package/dist/composables/index.js +16 -0
  62. package/dist/composables/useClient.d.ts +16 -0
  63. package/dist/composables/useClient.d.ts.map +1 -0
  64. package/dist/composables/useClient.js +28 -0
  65. package/dist/composables/useMetaConfig.d.ts +14 -0
  66. package/dist/composables/useMetaConfig.d.ts.map +1 -0
  67. package/dist/composables/useMetaConfig.js +77 -0
  68. package/dist/composables/useQueryMessageHandler.d.ts +44 -0
  69. package/dist/composables/useQueryMessageHandler.d.ts.map +1 -0
  70. package/dist/composables/useQueryMessageHandler.js +74 -0
  71. package/dist/composables/useQuvel.d.ts +15 -0
  72. package/dist/composables/useQuvel.d.ts.map +1 -0
  73. package/dist/composables/useQuvel.js +38 -0
  74. package/dist/composables/useRecaptcha.d.ts +35 -0
  75. package/dist/composables/useRecaptcha.d.ts.map +1 -0
  76. package/dist/composables/useRecaptcha.js +87 -0
  77. package/dist/composables/useScopedService.d.ts +18 -0
  78. package/dist/composables/useScopedService.d.ts.map +1 -0
  79. package/dist/composables/useScopedService.js +25 -0
  80. package/dist/composables/useScript.d.ts +25 -0
  81. package/dist/composables/useScript.d.ts.map +1 -0
  82. package/dist/composables/useScript.js +106 -0
  83. package/dist/composables/useUrlQueryHandler.d.ts +38 -0
  84. package/dist/composables/useUrlQueryHandler.d.ts.map +1 -0
  85. package/dist/composables/useUrlQueryHandler.js +76 -0
  86. package/dist/composables/useWebSockets.d.ts +18 -0
  87. package/dist/composables/useWebSockets.d.ts.map +1 -0
  88. package/dist/composables/useWebSockets.js +55 -0
  89. package/dist/composables/useWindowEvent.d.ts +16 -0
  90. package/dist/composables/useWindowEvent.d.ts.map +1 -0
  91. package/dist/composables/useWindowEvent.js +27 -0
  92. package/dist/composables/useXsrf.d.ts +29 -0
  93. package/dist/composables/useXsrf.d.ts.map +1 -0
  94. package/dist/composables/useXsrf.js +59 -0
  95. package/dist/config/QuasarConfigBuilder.d.ts +100 -0
  96. package/dist/config/QuasarConfigBuilder.d.ts.map +1 -0
  97. package/dist/config/QuasarConfigBuilder.js +98 -0
  98. package/dist/config/i18n.d.ts +23 -0
  99. package/dist/config/i18n.d.ts.map +1 -0
  100. package/dist/config/i18n.js +43 -0
  101. package/dist/config/index.d.ts +8 -0
  102. package/dist/config/index.d.ts.map +1 -0
  103. package/dist/config/index.js +7 -0
  104. package/dist/config/moduleTransformer.d.ts +18 -0
  105. package/dist/config/moduleTransformer.d.ts.map +1 -0
  106. package/dist/config/moduleTransformer.js +76 -0
  107. package/dist/config/quvel.d.ts +40 -0
  108. package/dist/config/quvel.d.ts.map +1 -0
  109. package/dist/config/quvel.js +59 -0
  110. package/dist/config/quvel.types.d.ts +59 -0
  111. package/dist/config/quvel.types.d.ts.map +1 -0
  112. package/dist/config/quvel.types.js +6 -0
  113. package/dist/container/ServiceContainer.d.ts +107 -0
  114. package/dist/container/ServiceContainer.d.ts.map +1 -0
  115. package/dist/container/ServiceContainer.js +201 -0
  116. package/dist/container/types/vue.d.ts +9 -0
  117. package/dist/container/types.d.ts +81 -0
  118. package/dist/container/types.d.ts.map +1 -0
  119. package/dist/container/types.js +1 -0
  120. package/dist/i18n/en-US/common.d.ts +19 -0
  121. package/dist/i18n/en-US/common.d.ts.map +1 -0
  122. package/dist/i18n/en-US/common.js +17 -0
  123. package/dist/i18n/en-US/index.d.ts +21 -0
  124. package/dist/i18n/en-US/index.d.ts.map +1 -0
  125. package/dist/i18n/en-US/index.js +4 -0
  126. package/dist/i18n/es-MX/common.d.ts +19 -0
  127. package/dist/i18n/es-MX/common.d.ts.map +1 -0
  128. package/dist/i18n/es-MX/common.js +17 -0
  129. package/dist/i18n/es-MX/index.d.ts +21 -0
  130. package/dist/i18n/es-MX/index.d.ts.map +1 -0
  131. package/dist/i18n/es-MX/index.js +4 -0
  132. package/dist/index.d.ts +54 -0
  133. package/dist/index.d.ts.map +1 -0
  134. package/dist/index.js +67 -0
  135. package/dist/models/User.d.ts +32 -0
  136. package/dist/models/User.d.ts.map +1 -0
  137. package/dist/models/User.js +48 -0
  138. package/dist/module.d.ts +21 -0
  139. package/dist/module.d.ts.map +1 -0
  140. package/dist/module.js +45 -0
  141. package/dist/modules/helpers.d.ts +30 -0
  142. package/dist/modules/helpers.d.ts.map +1 -0
  143. package/dist/modules/helpers.js +45 -0
  144. package/dist/modules/index.d.ts +8 -0
  145. package/dist/modules/index.d.ts.map +1 -0
  146. package/dist/modules/index.js +6 -0
  147. package/dist/modules/types.d.ts +141 -0
  148. package/dist/modules/types.d.ts.map +1 -0
  149. package/dist/modules/types.js +7 -0
  150. package/dist/pages/ErrorNotFound.vue +300 -0
  151. package/dist/pages/index.d.ts +7 -0
  152. package/dist/pages/index.d.ts.map +1 -0
  153. package/dist/pages/index.js +6 -0
  154. package/dist/services/ApiService.d.ts +90 -0
  155. package/dist/services/ApiService.d.ts.map +1 -0
  156. package/dist/services/ApiService.js +159 -0
  157. package/dist/services/I18nService.d.ts +67 -0
  158. package/dist/services/I18nService.d.ts.map +1 -0
  159. package/dist/services/I18nService.js +92 -0
  160. package/dist/services/LogService.d.ts +31 -0
  161. package/dist/services/LogService.d.ts.map +1 -0
  162. package/dist/services/LogService.js +49 -0
  163. package/dist/services/Service.d.ts +10 -0
  164. package/dist/services/Service.d.ts.map +1 -0
  165. package/dist/services/Service.js +8 -0
  166. package/dist/services/TaskService.d.ts +64 -0
  167. package/dist/services/TaskService.d.ts.map +1 -0
  168. package/dist/services/TaskService.js +188 -0
  169. package/dist/services/ThemeService.d.ts +28 -0
  170. package/dist/services/ThemeService.d.ts.map +1 -0
  171. package/dist/services/ThemeService.js +77 -0
  172. package/dist/services/ValidationService.d.ts +55 -0
  173. package/dist/services/ValidationService.d.ts.map +1 -0
  174. package/dist/services/ValidationService.js +81 -0
  175. package/dist/services/WebSocketService.d.ts +59 -0
  176. package/dist/services/WebSocketService.d.ts.map +1 -0
  177. package/dist/services/WebSocketService.js +148 -0
  178. package/dist/services/logger/BaseLogger.d.ts +35 -0
  179. package/dist/services/logger/BaseLogger.d.ts.map +1 -0
  180. package/dist/services/logger/BaseLogger.js +66 -0
  181. package/dist/services/logger/ConsoleLogger.d.ts +21 -0
  182. package/dist/services/logger/ConsoleLogger.d.ts.map +1 -0
  183. package/dist/services/logger/ConsoleLogger.js +60 -0
  184. package/dist/services/logger/NullLogger.d.ts +10 -0
  185. package/dist/services/logger/NullLogger.d.ts.map +1 -0
  186. package/dist/services/logger/NullLogger.js +10 -0
  187. package/dist/stores/plugins/serviceContainer.d.ts +10 -0
  188. package/dist/stores/plugins/serviceContainer.d.ts.map +1 -0
  189. package/dist/stores/plugins/serviceContainer.js +14 -0
  190. package/dist/stores/sessionStore.d.ts +71 -0
  191. package/dist/stores/sessionStore.d.ts.map +1 -0
  192. package/dist/stores/sessionStore.js +125 -0
  193. package/dist/types/app.types.d.ts +202 -0
  194. package/dist/types/app.types.d.ts.map +1 -0
  195. package/dist/types/app.types.js +6 -0
  196. package/dist/types/config.types.d.ts +2 -0
  197. package/dist/types/config.types.d.ts.map +1 -0
  198. package/dist/types/config.types.js +1 -0
  199. package/dist/types/global.d.ts +33 -0
  200. package/dist/types/i18n.types.d.ts +21 -0
  201. package/dist/types/i18n.types.d.ts.map +1 -0
  202. package/dist/types/i18n.types.js +6 -0
  203. package/dist/types/laravel.types.d.ts +167 -0
  204. package/dist/types/laravel.types.d.ts.map +1 -0
  205. package/dist/types/laravel.types.js +6 -0
  206. package/dist/types/logging.types.d.ts +81 -0
  207. package/dist/types/logging.types.d.ts.map +1 -0
  208. package/dist/types/logging.types.js +22 -0
  209. package/dist/types/pinia.d.ts +24 -0
  210. package/dist/types/scripts.types.d.ts +31 -0
  211. package/dist/types/scripts.types.d.ts.map +1 -0
  212. package/dist/types/scripts.types.js +6 -0
  213. package/dist/types/ssr.d.ts +11 -0
  214. package/dist/types/task.types.d.ts +121 -0
  215. package/dist/types/task.types.d.ts.map +1 -0
  216. package/dist/types/task.types.js +7 -0
  217. package/dist/types/theme.types.d.ts +13 -0
  218. package/dist/types/theme.types.d.ts.map +1 -0
  219. package/dist/types/theme.types.js +17 -0
  220. package/dist/types/user.types.d.ts +24 -0
  221. package/dist/types/user.types.d.ts.map +1 -0
  222. package/dist/types/user.types.js +1 -0
  223. package/dist/types/vue-shim.d.ts +11 -0
  224. package/dist/types/websocket.types.d.ts +62 -0
  225. package/dist/types/websocket.types.d.ts.map +1 -0
  226. package/dist/types/websocket.types.js +6 -0
  227. package/dist/utils/apiInterceptors.d.ts +76 -0
  228. package/dist/utils/apiInterceptors.d.ts.map +1 -0
  229. package/dist/utils/apiInterceptors.js +149 -0
  230. package/dist/utils/assets.d.ts +40 -0
  231. package/dist/utils/assets.d.ts.map +1 -0
  232. package/dist/utils/assets.js +340 -0
  233. package/dist/utils/axios.d.ts +19 -0
  234. package/dist/utils/axios.d.ts.map +1 -0
  235. package/dist/utils/axios.js +113 -0
  236. package/dist/utils/config.d.ts +16 -0
  237. package/dist/utils/config.d.ts.map +1 -0
  238. package/dist/utils/config.js +48 -0
  239. package/dist/utils/container.d.ts +12 -0
  240. package/dist/utils/container.d.ts.map +1 -0
  241. package/dist/utils/container.js +11 -0
  242. package/dist/utils/deepMerge.d.ts +28 -0
  243. package/dist/utils/deepMerge.d.ts.map +1 -0
  244. package/dist/utils/deepMerge.js +59 -0
  245. package/dist/utils/envConfig.d.ts +73 -0
  246. package/dist/utils/envConfig.d.ts.map +1 -0
  247. package/dist/utils/envConfig.js +161 -0
  248. package/dist/utils/error.d.ts +44 -0
  249. package/dist/utils/error.d.ts.map +1 -0
  250. package/dist/utils/error.js +67 -0
  251. package/dist/utils/headers.d.ts +36 -0
  252. package/dist/utils/headers.d.ts.map +1 -0
  253. package/dist/utils/headers.js +54 -0
  254. package/dist/utils/i18n.d.ts +26 -0
  255. package/dist/utils/i18n.d.ts.map +1 -0
  256. package/dist/utils/i18n.js +56 -0
  257. package/dist/utils/index.d.ts +14 -0
  258. package/dist/utils/index.d.ts.map +1 -0
  259. package/dist/utils/index.js +13 -0
  260. package/dist/utils/loading.d.ts +29 -0
  261. package/dist/utils/loading.d.ts.map +1 -0
  262. package/dist/utils/loading.js +46 -0
  263. package/dist/utils/logging.d.ts +20 -0
  264. package/dist/utils/logging.d.ts.map +1 -0
  265. package/dist/utils/logging.js +54 -0
  266. package/dist/utils/notify.d.ts +15 -0
  267. package/dist/utils/notify.d.ts.map +1 -0
  268. package/dist/utils/notify.js +30 -0
  269. package/dist/utils/object.d.ts +28 -0
  270. package/dist/utils/object.d.ts.map +1 -0
  271. package/dist/utils/object.js +48 -0
  272. package/dist/utils/pagination.d.ts +60 -0
  273. package/dist/utils/pagination.d.ts.map +1 -0
  274. package/dist/utils/pagination.js +252 -0
  275. package/dist/utils/paths.d.ts +54 -0
  276. package/dist/utils/paths.d.ts.map +1 -0
  277. package/dist/utils/paths.js +48 -0
  278. package/dist/utils/platform.d.ts +25 -0
  279. package/dist/utils/platform.d.ts.map +1 -0
  280. package/dist/utils/platform.js +64 -0
  281. package/dist/utils/scripts.d.ts +20 -0
  282. package/dist/utils/scripts.d.ts.map +1 -0
  283. package/dist/utils/scripts.js +39 -0
  284. package/global.d.ts +29 -0
  285. package/package.json +119 -0
@@ -0,0 +1,634 @@
1
+ <script lang="ts">
2
+ import { defineComponent, ref, computed, onBeforeUnmount, nextTick, onMounted } from 'vue';
3
+ import { useWebSockets } from '../composables/useWebSockets';
4
+ import { WebSocketChannelType, SubscribeOptions } from '../types/websocket.types';
5
+ import { PublicChannelType, PrivateChannelType, PresenceChannelType, EncryptedChannelType } from '../types/websocket.types';
6
+ import { QScrollArea } from 'quasar';
7
+
8
+
9
+ type AnyChannel = PublicChannelType | PrivateChannelType | PresenceChannelType | EncryptedChannelType;
10
+
11
+ interface ChannelConfig {
12
+ name: string;
13
+ type: WebSocketChannelType;
14
+ event?: string | undefined;
15
+ channel: AnyChannel;
16
+ }
17
+
18
+ interface MessageLog {
19
+ channelName: string;
20
+ channelType: WebSocketChannelType;
21
+ event: string;
22
+ data: unknown;
23
+ timestamp: Date;
24
+ }
25
+
26
+ export default defineComponent({
27
+ name: 'WebSocketChannelManager',
28
+
29
+ setup() {
30
+ // WebSocket connection management
31
+ const { subscribe, unsubscribe } = useWebSockets();
32
+
33
+ // Dialog visibility control
34
+ const isDialogOpen = ref(false);
35
+ const isVisible = computed(() => isDialogOpen.value);
36
+
37
+ // Selected channel for filtering messages
38
+ const selectedChannelIndex = ref<number | null>(null);
39
+
40
+ // Register global methods to show/hide the component
41
+ onMounted(() => {
42
+ (window as unknown as { showWebSocketManager: () => void }).showWebSocketManager = () => {
43
+ isDialogOpen.value = true;
44
+
45
+ console.log('WebSocket Inspector is now open');
46
+ };
47
+
48
+ (window as unknown as { hideWebSocketManager: () => void }).hideWebSocketManager = () => {
49
+ hideManager();
50
+ };
51
+
52
+ // Log instructions to console
53
+ console.info(
54
+ '%cWebSocket Inspector available!',
55
+ 'color: #4CAF50; font-weight: bold; font-size: 14px;'
56
+ );
57
+ console.info(
58
+ '%cUse window.showWebSocketManager() to show the inspector',
59
+ 'color: #2196F3; font-size: 12px;'
60
+ );
61
+ });
62
+
63
+ // Hide the manager and clean up
64
+ const hideManager = () => {
65
+ isDialogOpen.value = false;
66
+ console.log('WebSocket Inspector is now closed');
67
+ };
68
+
69
+ // Select a channel to filter messages
70
+ const selectChannel = (index: number) => {
71
+ selectedChannelIndex.value = selectedChannelIndex.value === index ? null : index;
72
+ };
73
+
74
+ // Active channels
75
+ const activeChannels = ref<ChannelConfig[]>([]);
76
+
77
+ // Connection status
78
+ const connectionStatus = computed(() => {
79
+ const isConnected = activeChannels.value.length > 0;
80
+ return {
81
+ label: isConnected ? 'Connected' : 'Disconnected',
82
+ color: isConnected ? 'positive' : 'negative'
83
+ };
84
+ });
85
+
86
+ // Channel form
87
+ // Channel form with partial type to allow initialization without a channel
88
+ const newChannel = ref<Omit<ChannelConfig, 'channel'> & { channel?: AnyChannel }>({
89
+ name: '',
90
+ type: 'public',
91
+ event: ''
92
+ });
93
+
94
+ const isAddingChannel = ref(false);
95
+
96
+ // Available channel types
97
+ const channelTypes = [
98
+ { label: 'Public', value: 'public' },
99
+ { label: 'Private', value: 'private' },
100
+ { label: 'Presence', value: 'presence' },
101
+ { label: 'Encrypted', value: 'encrypted' },
102
+ { label: 'Public Notification', value: 'publicNotification' },
103
+ { label: 'Private Notification', value: 'privateNotification' }
104
+ ];
105
+
106
+ // Message log
107
+ const messages = ref<MessageLog[]>([]);
108
+ const messageLogRef = ref<QScrollArea | null>(null);
109
+
110
+ // Filtered messages based on selected channel
111
+ const filteredMessages = computed(() => {
112
+ if (selectedChannelIndex.value === null) {
113
+ return messages.value;
114
+ }
115
+
116
+ const selectedChannel = activeChannels.value[selectedChannelIndex.value];
117
+ return messages.value.filter(msg =>
118
+ msg.channelName === selectedChannel?.name &&
119
+ msg.channelType === selectedChannel?.type
120
+ );
121
+ });
122
+
123
+ // Add a new channel
124
+ const addChannel = async () => {
125
+ try {
126
+ isAddingChannel.value = true;
127
+
128
+ // Create channel options
129
+ const options: SubscribeOptions<unknown> = {
130
+ channelName: newChannel.value.name,
131
+ type: newChannel.value.type,
132
+ // Only include event if it's defined
133
+ ...(newChannel.value.event ? { event: newChannel.value.event } : {}),
134
+ callback: (data: unknown) => {
135
+ // Log the message
136
+ messages.value.push({
137
+ channelName: newChannel.value.name,
138
+ channelType: newChannel.value.type,
139
+ event: newChannel.value.event || 'notification',
140
+ data,
141
+ timestamp: new Date(),
142
+ });
143
+
144
+ // Scroll to bottom of message log
145
+ void nextTick(() => {
146
+ if (messageLogRef.value) {
147
+ messageLogRef.value.setScrollPosition('vertical', 999999);
148
+ }
149
+ });
150
+ },
151
+ presenceHandlers: {
152
+ onListening: {
153
+ event: 'listening',
154
+ callback: () => {
155
+ messages.value.push({
156
+ channelName: newChannel.value.name,
157
+ channelType: newChannel.value.type,
158
+ event: newChannel.value.event || 'notification',
159
+ data: 'Listening',
160
+ timestamp: new Date(),
161
+ });
162
+ },
163
+ },
164
+ onHere: (members: Record<string, unknown>) => {
165
+ messages.value.push({
166
+ channelName: newChannel.value.name,
167
+ channelType: newChannel.value.type,
168
+ event: newChannel.value.event || 'notification',
169
+ data: members,
170
+ timestamp: new Date(),
171
+ });
172
+ },
173
+ onJoining: (member: Record<string, unknown>) => {
174
+ messages.value.push({
175
+ channelName: newChannel.value.name,
176
+ channelType: newChannel.value.type,
177
+ event: newChannel.value.event || 'notification',
178
+ data: member,
179
+ timestamp: new Date(),
180
+ });
181
+ },
182
+ onLeaving: (member: Record<string, unknown>) => {
183
+ messages.value.push({
184
+ channelName: newChannel.value.name,
185
+ channelType: newChannel.value.type,
186
+ event: newChannel.value.event || 'notification',
187
+ data: member,
188
+ timestamp: new Date(),
189
+ });
190
+ },
191
+ },
192
+ };
193
+
194
+ // Subscribe to the channel
195
+ const channel = await subscribe(options);
196
+
197
+ // Add to active channels
198
+ activeChannels.value.push({
199
+ name: newChannel.value.name,
200
+ type: newChannel.value.type,
201
+ event: newChannel.value.event || undefined,
202
+ channel
203
+ });
204
+
205
+ // Reset form
206
+ newChannel.value = {
207
+ name: '',
208
+ type: 'public',
209
+ event: ''
210
+ };
211
+ } catch (error) {
212
+ console.error('Failed to add channel:', error);
213
+ } finally {
214
+ isAddingChannel.value = false;
215
+ }
216
+ };
217
+
218
+ // Remove a channel
219
+ const removeChannel = (index: number) => {
220
+ const channel = activeChannels.value[index];
221
+ if (channel?.channel) {
222
+ unsubscribe(channel.channel as AnyChannel);
223
+ }
224
+
225
+ activeChannels.value.splice(index, 1);
226
+ };
227
+
228
+ // Clear message log
229
+ const clearMessages = () => {
230
+ messages.value = [];
231
+ };
232
+
233
+ // Download logs as JSON
234
+ const downloadLogs = () => {
235
+ const data = JSON.stringify(messages.value, null, 2);
236
+ const blob = new Blob([data], { type: 'application/json' });
237
+ const url = URL.createObjectURL(blob);
238
+ const a = document.createElement('a');
239
+ a.href = url;
240
+ a.download = `websocket-logs-${new Date().toISOString()}.json`;
241
+ document.body.appendChild(a);
242
+ a.click();
243
+ document.body.removeChild(a);
244
+ URL.revokeObjectURL(url);
245
+ };
246
+
247
+ // Format timestamp
248
+ const formatTimestamp = (date: Date) => {
249
+ return date.toLocaleTimeString();
250
+ };
251
+
252
+ // Format message data for display
253
+ const formatMessageData = (data: unknown) => {
254
+ try {
255
+ return JSON.stringify(data, null, 2);
256
+ } catch {
257
+ return String(data);
258
+ }
259
+ };
260
+
261
+ // Get color for channel type
262
+ const getChannelTypeColor = (type: WebSocketChannelType) => {
263
+ switch (type) {
264
+ case 'public':
265
+ case 'publicNotification':
266
+ return 'teal';
267
+ case 'private':
268
+ case 'privateNotification':
269
+ return 'blue';
270
+ case 'presence':
271
+ return 'purple';
272
+ case 'encrypted':
273
+ return 'deep-orange';
274
+ default:
275
+ return 'grey';
276
+ }
277
+ };
278
+
279
+ // Clean up all channels when component unmounts
280
+ onBeforeUnmount(() => {
281
+ activeChannels.value.forEach(channelConfig => {
282
+ unsubscribe(channelConfig.channel as AnyChannel);
283
+ });
284
+
285
+ activeChannels.value = [];
286
+ });
287
+
288
+ return {
289
+ // Visibility control
290
+ isVisible,
291
+ isDialogOpen,
292
+ hideManager,
293
+
294
+ // Connection
295
+ connectionStatus,
296
+
297
+ // Channel form
298
+ newChannel,
299
+ channelTypes,
300
+ isAddingChannel,
301
+ addChannel,
302
+
303
+ // Active channels
304
+ activeChannels,
305
+ removeChannel,
306
+ getChannelTypeColor,
307
+ selectedChannelIndex,
308
+ selectChannel,
309
+
310
+ // Message log
311
+ messages,
312
+ filteredMessages,
313
+ messageLogRef,
314
+ clearMessages,
315
+ downloadLogs,
316
+ formatTimestamp,
317
+ formatMessageData
318
+ };
319
+ }
320
+ });
321
+ </script>
322
+
323
+ <template>
324
+ <q-dialog
325
+ v-model="isDialogOpen"
326
+ persistent
327
+ maximized
328
+ transition-show="slide-up"
329
+ transition-hide="slide-down"
330
+ >
331
+ <q-card class="websocket-channel-manager">
332
+ <q-card-section class="bg-dark text-white q-py-sm">
333
+ <div class="flex items-center justify-between">
334
+ <div class="flex items-center">
335
+ <q-icon
336
+ name="eva-wifi-outline"
337
+ size="md"
338
+ class="q-mr-sm"
339
+ />
340
+ <h5 class="text-h6 q-my-none">WebSocket Inspector</h5>
341
+ </div>
342
+ <q-chip
343
+ :color="connectionStatus.color"
344
+ text-color="white"
345
+ size="sm"
346
+ outline
347
+ >
348
+ {{ connectionStatus.label }}
349
+ </q-chip>
350
+
351
+ <q-btn
352
+ flat
353
+ round
354
+ color="grey-5"
355
+ icon="eva-close-outline"
356
+ @click="hideManager"
357
+ />
358
+ </div>
359
+ </q-card-section>
360
+
361
+ <q-card-section class="q-pa-md bg-dark-subtle">
362
+ <q-form
363
+ @submit="addChannel"
364
+ class="row q-col-gutter-sm items-end"
365
+ >
366
+ <div class="col-12 col-sm-4">
367
+ <q-input
368
+ v-model="newChannel.name"
369
+ label="Channel Name"
370
+ dense
371
+ filled
372
+ dark
373
+ class="bg-dark-page"
374
+ :rules="[val => !!val || 'Required']"
375
+ >
376
+ <template v-slot:prepend>
377
+ <q-icon name="eva-hash-outline" />
378
+ </template>
379
+ </q-input>
380
+ </div>
381
+ <div class="col-12 col-sm-3">
382
+ <q-select
383
+ v-model="newChannel.type"
384
+ :options="channelTypes"
385
+ :emit-value="true"
386
+ label="Channel Type"
387
+ dense
388
+ filled
389
+ dark
390
+ class="bg-dark-page"
391
+ :rules="[val => !!val || 'Required']"
392
+ >
393
+ <template v-slot:prepend>
394
+ <q-icon name="eva-eye-outline" />
395
+ </template>
396
+ </q-select>
397
+ </div>
398
+ <div class="col-12 col-sm-3">
399
+ <q-input
400
+ v-model="newChannel.event"
401
+ label="Event Name"
402
+ dense
403
+ filled
404
+ dark
405
+ class="bg-dark-page"
406
+ :rules="[val => newChannel.type !== 'presence' ? !!val || 'Required' : true]"
407
+ :disable="newChannel.type === 'presence'"
408
+ >
409
+ <template v-slot:prepend>
410
+ <q-icon name="eva-bell-outline" />
411
+ </template>
412
+ </q-input>
413
+ </div>
414
+ <div class="col-12 col-sm-2">
415
+ <q-btn
416
+ type="submit"
417
+ color="primary"
418
+ icon="eva-plus-outline"
419
+ label="Subscribe"
420
+ no-caps
421
+ unelevated
422
+ class="full-width"
423
+ :loading="isAddingChannel"
424
+ />
425
+ </div>
426
+ </q-form>
427
+ </q-card-section>
428
+
429
+ <q-separator dark />
430
+
431
+ <q-card-section class="q-pa-none">
432
+ <div class="row">
433
+ <div class="col-12 col-md-3 bg-dark-subtle">
434
+ <q-card-section class="q-py-sm">
435
+ <div class="text-subtitle1 text-weight-medium flex items-center">
436
+ <q-icon
437
+ name="eva-hash-outline"
438
+ class="q-mr-xs"
439
+ />
440
+ Active Channels
441
+ <q-badge
442
+ color="primary"
443
+ class="q-ml-sm"
444
+ >{{ activeChannels.length }}</q-badge>
445
+ </div>
446
+ </q-card-section>
447
+
448
+ <q-separator dark />
449
+
450
+ <q-list
451
+ dark
452
+ dense
453
+ class="channel-list"
454
+ >
455
+ <q-item
456
+ v-if="activeChannels.length === 0"
457
+ class="text-grey-6"
458
+ >
459
+ <q-item-section>
460
+ <q-item-label>No active channels</q-item-label>
461
+ <q-item-label caption>Add a channel to start listening</q-item-label>
462
+ </q-item-section>
463
+ </q-item>
464
+
465
+ <q-item
466
+ v-for="(channel, index) in activeChannels"
467
+ :key="index"
468
+ clickable
469
+ active-class="bg-primary text-white"
470
+ :active="selectedChannelIndex === index"
471
+ @click="selectChannel(index)"
472
+ >
473
+ <q-item-section avatar>
474
+ <q-icon
475
+ :color="getChannelTypeColor(channel.type)"
476
+ name="eva-radio-outline"
477
+ />
478
+ </q-item-section>
479
+
480
+ <q-item-section>
481
+ <q-item-label lines="1">{{ channel.name }}</q-item-label>
482
+ <q-item-label caption>
483
+ <q-badge
484
+ :color="getChannelTypeColor(channel.type)"
485
+ text-color="white"
486
+ size="xs"
487
+ >
488
+ {{ channel.type }}
489
+ </q-badge>
490
+ <span
491
+ v-if="channel.event"
492
+ class="q-ml-xs"
493
+ >{{ channel.event }}</span>
494
+ </q-item-label>
495
+ </q-item-section>
496
+
497
+ <q-item-section side>
498
+ <q-btn
499
+ flat
500
+ round
501
+ dense
502
+ color="negative"
503
+ icon="eva-close-outline"
504
+ @click.stop="removeChannel(index)"
505
+ />
506
+ </q-item-section>
507
+ </q-item>
508
+ </q-list>
509
+ </div>
510
+
511
+ <div class="col-12 col-md-9">
512
+ <q-card-section class="q-py-sm bg-dark-subtle">
513
+ <div class="row items-center justify-between">
514
+ <div class="text-subtitle1 text-weight-medium flex items-center">
515
+ <q-icon
516
+ name="eva-message-square-outline"
517
+ class="q-mr-xs"
518
+ />
519
+ Message Log
520
+ <q-badge
521
+ color="secondary"
522
+ class="q-ml-sm"
523
+ >{{ filteredMessages.length }}</q-badge>
524
+ </div>
525
+
526
+ <div>
527
+ <q-btn
528
+ flat
529
+ round
530
+ dense
531
+ color="grey"
532
+ icon="eva-refresh-outline"
533
+ @click="clearMessages"
534
+ class="q-mr-xs"
535
+ >
536
+ <q-tooltip>Clear Messages</q-tooltip>
537
+ </q-btn>
538
+ <q-btn
539
+ flat
540
+ round
541
+ dense
542
+ color="grey"
543
+ icon="eva-download-outline"
544
+ @click="downloadLogs"
545
+ >
546
+ <q-tooltip>Download Logs</q-tooltip>
547
+ </q-btn>
548
+ </div>
549
+ </div>
550
+ </q-card-section>
551
+
552
+ <q-separator dark />
553
+
554
+ <q-scroll-area
555
+ style="height: calc(100vh - 280px);"
556
+ ref="messageLogRef"
557
+ class="bg-dark-page"
558
+ >
559
+ <div
560
+ v-if="filteredMessages.length === 0"
561
+ class="text-center q-pa-md text-grey-7"
562
+ >
563
+ <q-icon
564
+ name="eva-message-square-outline"
565
+ size="2rem"
566
+ />
567
+ <div class="q-mt-sm">No messages received yet.</div>
568
+ </div>
569
+
570
+ <div
571
+ v-for="(message, index) in filteredMessages"
572
+ :key="index"
573
+ class="message-item q-pa-md q-my-sm"
574
+ >
575
+ <div class="flex items-center justify-between">
576
+ <div class="flex items-center">
577
+ <q-badge
578
+ :color="getChannelTypeColor(message.channelType)"
579
+ class="q-mr-sm"
580
+ >{{ message.channelType
581
+ }}</q-badge>
582
+ <div class="text-weight-medium">{{ message.channelName }}</div>
583
+ </div>
584
+ <div class="text-grey-7 text-caption">{{ formatTimestamp(message.timestamp) }}</div>
585
+ </div>
586
+
587
+ <div class="q-mt-xs">
588
+ <q-chip
589
+ size="sm"
590
+ outline
591
+ color="secondary"
592
+ class="q-mr-sm"
593
+ >{{ message.event }}</q-chip>
594
+ </div>
595
+
596
+ <q-card
597
+ flat
598
+ bordered
599
+ class="q-mt-sm bg-dark-subtle"
600
+ >
601
+ <q-card-section class="q-pa-sm">
602
+ <pre class="message-content text-grey-4">{{ formatMessageData(message.data) }}</pre>
603
+ </q-card-section>
604
+ </q-card>
605
+ </div>
606
+ </q-scroll-area>
607
+ </div>
608
+ </div>
609
+ </q-card-section>
610
+ </q-card>
611
+ </q-dialog>
612
+ </template>
613
+
614
+ <style lang="scss">
615
+ .websocket-channel-manager {
616
+ width: 100%;
617
+ height: 100%;
618
+ display: flex;
619
+ flex-direction: column;
620
+ background-color: #1e1e1e;
621
+ color: #e0e0e0;
622
+
623
+ .channel-list {
624
+ max-height: 300px;
625
+ overflow-y: auto;
626
+ }
627
+
628
+ .message-content {
629
+ overflow-x: auto;
630
+ white-space: pre-wrap;
631
+ word-break: break-word;
632
+ }
633
+ }
634
+ </style>
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Core Components
3
+ *
4
+ * Reusable Vue components for the Quvel UI framework
5
+ */
6
+ export { default as BaseInput } from './Inputs/BaseInput.vue';
7
+ export { default as TaskErrors } from './Common/TaskErrors.vue';
8
+ export { default as ClientOnly } from './Misc/ClientOnly.vue';
9
+ export { default as FadeInOut } from './Transitions/FadeInOut.vue';
10
+ export { default as SlowExpand } from './Transitions/SlowExpand.vue';
11
+ export { default as WebSocketChannelManager } from './WebSocketChannelManager.vue';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAG9D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAGhE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAG9D,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAGrE,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,+BAA+B,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Core Components
3
+ *
4
+ * Reusable Vue components for the Quvel UI framework
5
+ */
6
+ // Inputs Components
7
+ export { default as BaseInput } from './Inputs/BaseInput.vue';
8
+ // Common Components
9
+ export { default as TaskErrors } from './Common/TaskErrors.vue';
10
+ // Misc Components
11
+ export { default as ClientOnly } from './Misc/ClientOnly.vue';
12
+ // Transitions
13
+ export { default as FadeInOut } from './Transitions/FadeInOut.vue';
14
+ export { default as SlowExpand } from './Transitions/SlowExpand.vue';
15
+ // WebSocket
16
+ export { default as WebSocketChannelManager } from './WebSocketChannelManager.vue';
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Core Composables
3
+ *
4
+ * Vue composables for the Quvel UI framework
5
+ */
6
+ export { useQuvel, ContainerKey, setClientContainer } from './useQuvel.js';
7
+ export { useWindowEvent } from './useWindowEvent.js';
8
+ export { useClient } from './useClient.js';
9
+ export { useScript } from './useScript.js';
10
+ export { useMetaConfig } from './useMetaConfig.js';
11
+ export { useWebSockets } from './useWebSockets.js';
12
+ export { useScopedService } from './useScopedService.js';
13
+ export { useRecaptcha } from './useRecaptcha.js';
14
+ export { useXsrf } from './useXsrf.js';
15
+ export { useQueryMessageHandler, normalizeKey, mapStatusToType } from './useQueryMessageHandler.js';
16
+ export type { MessageHandlerOptions } from './useQueryMessageHandler.js';
17
+ export { useUrlQueryHandler } from './useUrlQueryHandler.js';
18
+ export type { UrlQueryHandlerOptions } from './useUrlQueryHandler.js';
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/composables/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACpG,YAAY,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,YAAY,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC"}