@pushler/vue 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +499 -0
- package/dist/index.d.ts +176 -0
- package/dist/pushler-vue.cjs.js +872 -0
- package/dist/pushler-vue.cjs.js.map +1 -0
- package/dist/pushler-vue.esm.js +861 -0
- package/dist/pushler-vue.esm.js.map +1 -0
- package/dist/pushler-vue.umd.js +876 -0
- package/dist/pushler-vue.umd.js.map +1 -0
- package/dist/pushler-vue.umd.min.js +7 -0
- package/dist/pushler-vue.umd.min.js.map +1 -0
- package/package.json +58 -0
- package/src/index.d.ts +176 -0
- package/src/index.js +58 -0
- package/src/plugin.js +65 -0
- package/src/usePushler.js +611 -0
- package/src/usePushlerChannel.js +137 -0
package/README.md
ADDED
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
# Pushler Vue SDK
|
|
2
|
+
|
|
3
|
+
Реактивный Vue.js SDK для работы с Pushler.ru WebSocket сервером.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@pushler/vue)
|
|
6
|
+
[](https://www.npmjs.com/package/@pushler/vue)
|
|
7
|
+
[](https://github.com/pushler/vue-sdk/blob/main/LICENSE)
|
|
8
|
+
|
|
9
|
+
## Установка
|
|
10
|
+
|
|
11
|
+
### npm / yarn / pnpm
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @pushler/vue
|
|
15
|
+
|
|
16
|
+
# или
|
|
17
|
+
yarn add @pushler/vue
|
|
18
|
+
|
|
19
|
+
# или
|
|
20
|
+
pnpm add @pushler/vue
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### CDN
|
|
24
|
+
|
|
25
|
+
```html
|
|
26
|
+
<!-- Последняя версия -->
|
|
27
|
+
<script src="https://unpkg.com/@pushler/vue"></script>
|
|
28
|
+
|
|
29
|
+
<!-- Конкретная версия -->
|
|
30
|
+
<script src="https://unpkg.com/@pushler/vue@1.0.0/dist/pushler-vue.umd.min.js"></script>
|
|
31
|
+
|
|
32
|
+
<!-- jsDelivr -->
|
|
33
|
+
<script src="https://cdn.jsdelivr.net/npm/@pushler/vue"></script>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Быстрый старт
|
|
37
|
+
|
|
38
|
+
### Использование composable
|
|
39
|
+
|
|
40
|
+
```vue
|
|
41
|
+
<script setup>
|
|
42
|
+
import { usePushler } from '@pushler/vue';
|
|
43
|
+
|
|
44
|
+
// Создаём экземпляр Pushler
|
|
45
|
+
const pushler = usePushler({
|
|
46
|
+
appKey: 'your-app-key',
|
|
47
|
+
wsUrl: 'wss://ws.pushler.ru/app',
|
|
48
|
+
autoConnect: true, // Автоматическое подключение
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// Подписка на канал
|
|
52
|
+
const channel = pushler.subscribe('my-channel');
|
|
53
|
+
|
|
54
|
+
// Слушаем события
|
|
55
|
+
channel.on('message', (data) => {
|
|
56
|
+
console.log('Получено сообщение:', data);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
channel.on('notification', (data) => {
|
|
60
|
+
console.log('Уведомление:', data);
|
|
61
|
+
});
|
|
62
|
+
</script>
|
|
63
|
+
|
|
64
|
+
<template>
|
|
65
|
+
<div>
|
|
66
|
+
<p>Статус: {{ pushler.connectionState }}</p>
|
|
67
|
+
<p v-if="pushler.socketId">Socket ID: {{ pushler.socketId }}</p>
|
|
68
|
+
<button @click="pushler.connect()" :disabled="pushler.isConnected.value">
|
|
69
|
+
Подключиться
|
|
70
|
+
</button>
|
|
71
|
+
<button @click="pushler.disconnect()" :disabled="!pushler.isConnected.value">
|
|
72
|
+
Отключиться
|
|
73
|
+
</button>
|
|
74
|
+
</div>
|
|
75
|
+
</template>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Использование Vue Plugin
|
|
79
|
+
|
|
80
|
+
```js
|
|
81
|
+
// main.js
|
|
82
|
+
import { createApp } from 'vue';
|
|
83
|
+
import { PushlerPlugin } from '@pushler/vue';
|
|
84
|
+
import App from './App.vue';
|
|
85
|
+
|
|
86
|
+
const app = createApp(App);
|
|
87
|
+
|
|
88
|
+
app.use(PushlerPlugin, {
|
|
89
|
+
appKey: 'your-app-key',
|
|
90
|
+
wsUrl: 'wss://ws.pushler.ru/app',
|
|
91
|
+
autoConnect: true,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
app.mount('#app');
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Затем в любом компоненте:
|
|
98
|
+
|
|
99
|
+
```vue
|
|
100
|
+
<script setup>
|
|
101
|
+
import { inject } from 'vue';
|
|
102
|
+
import { PushlerKey } from '@pushler/vue';
|
|
103
|
+
|
|
104
|
+
const pushler = inject(PushlerKey);
|
|
105
|
+
|
|
106
|
+
const channel = pushler.subscribe('notifications');
|
|
107
|
+
channel.on('new', (data) => {
|
|
108
|
+
console.log('Новое уведомление:', data);
|
|
109
|
+
});
|
|
110
|
+
</script>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## API Reference
|
|
114
|
+
|
|
115
|
+
### `usePushler(options)`
|
|
116
|
+
|
|
117
|
+
Основной composable для работы с WebSocket подключением.
|
|
118
|
+
|
|
119
|
+
#### Опции
|
|
120
|
+
|
|
121
|
+
| Параметр | Тип | По умолчанию | Описание |
|
|
122
|
+
|----------|-----|--------------|----------|
|
|
123
|
+
| `appKey` | `string` | `''` | Ключ приложения Pushler |
|
|
124
|
+
| `wsUrl` | `string` | `'ws://localhost:8081/app'` | URL WebSocket сервера |
|
|
125
|
+
| `authEndpoint` | `string` | `'/pushler/auth'` | Эндпоинт для авторизации приватных каналов |
|
|
126
|
+
| `autoConnect` | `boolean` | `false` | Автоматическое подключение при инициализации |
|
|
127
|
+
| `reconnectDelay` | `number` | `1000` | Задержка между попытками переподключения (мс) |
|
|
128
|
+
| `maxReconnectAttempts` | `number` | `5` | Максимальное количество попыток переподключения |
|
|
129
|
+
|
|
130
|
+
#### Возвращаемые значения
|
|
131
|
+
|
|
132
|
+
##### Реактивное состояние
|
|
133
|
+
|
|
134
|
+
```js
|
|
135
|
+
const pushler = usePushler(options);
|
|
136
|
+
|
|
137
|
+
// Состояние подключения: 'connecting' | 'connected' | 'disconnected' | 'reconnecting' | 'failed'
|
|
138
|
+
pushler.connectionState // Ref<string>
|
|
139
|
+
|
|
140
|
+
// ID сокета (после подключения)
|
|
141
|
+
pushler.socketId // Ref<string | null>
|
|
142
|
+
|
|
143
|
+
// Ошибка (если есть)
|
|
144
|
+
pushler.error // Ref<string | null>
|
|
145
|
+
|
|
146
|
+
// Количество попыток переподключения
|
|
147
|
+
pushler.reconnectAttempts // Ref<number>
|
|
148
|
+
|
|
149
|
+
// Вычисляемые свойства
|
|
150
|
+
pushler.isConnected // ComputedRef<boolean>
|
|
151
|
+
pushler.isConnecting // ComputedRef<boolean>
|
|
152
|
+
pushler.isReconnecting // ComputedRef<boolean>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
##### Методы
|
|
156
|
+
|
|
157
|
+
```js
|
|
158
|
+
// Подключение к серверу
|
|
159
|
+
pushler.connect(options?: { appKey?, wsUrl?, secret? })
|
|
160
|
+
|
|
161
|
+
// Отключение
|
|
162
|
+
pushler.disconnect()
|
|
163
|
+
|
|
164
|
+
// Подписка на канал
|
|
165
|
+
const channel = pushler.subscribe('channel-name', {
|
|
166
|
+
signature?: 'pre-signed-signature',
|
|
167
|
+
user?: { id: 1, name: 'User' } // для presence-каналов
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
// Отписка от канала
|
|
171
|
+
pushler.unsubscribe('channel-name')
|
|
172
|
+
|
|
173
|
+
// Получение канала
|
|
174
|
+
const channel = pushler.channel('channel-name')
|
|
175
|
+
|
|
176
|
+
// Получение списка каналов
|
|
177
|
+
const channels = pushler.getChannels()
|
|
178
|
+
// [{ name, fullName, type, subscribed }]
|
|
179
|
+
|
|
180
|
+
// Подписка на глобальные события
|
|
181
|
+
pushler.on('connected', (data) => console.log('Connected:', data.socketId))
|
|
182
|
+
pushler.on('message', (msg) => console.log('Message:', msg))
|
|
183
|
+
pushler.on('auth_error', (err) => console.error('Auth error:', err))
|
|
184
|
+
|
|
185
|
+
// Отписка от событий
|
|
186
|
+
pushler.off('connected', handler)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Канал
|
|
190
|
+
|
|
191
|
+
```js
|
|
192
|
+
const channel = pushler.subscribe('my-channel');
|
|
193
|
+
|
|
194
|
+
// Свойства канала
|
|
195
|
+
channel.name // Полное имя с appKey
|
|
196
|
+
channel.originalName // Оригинальное имя
|
|
197
|
+
channel.type // 'public' | 'private' | 'presence'
|
|
198
|
+
channel.subscribed // boolean
|
|
199
|
+
|
|
200
|
+
// Методы
|
|
201
|
+
channel.on('event-name', callback)
|
|
202
|
+
channel.off('event-name', callback)
|
|
203
|
+
channel.unsubscribe()
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Типы каналов
|
|
207
|
+
|
|
208
|
+
```js
|
|
209
|
+
// Публичные каналы (без авторизации)
|
|
210
|
+
pushler.subscribe('public-channel')
|
|
211
|
+
|
|
212
|
+
// Приватные каналы (требуют авторизации через бэкенд)
|
|
213
|
+
pushler.subscribe('private-channel')
|
|
214
|
+
// SDK автоматически запросит подпись с authEndpoint
|
|
215
|
+
|
|
216
|
+
// Или можно передать предварительно полученную подпись
|
|
217
|
+
pushler.subscribe('private-channel', {
|
|
218
|
+
signature: 'hmac-signature-from-backend'
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
// Presence-каналы (информация о присутствии)
|
|
222
|
+
pushler.subscribe('presence-chat', {
|
|
223
|
+
user: {
|
|
224
|
+
id: 123,
|
|
225
|
+
name: 'Иван Петров',
|
|
226
|
+
avatar: 'https://...'
|
|
227
|
+
}
|
|
228
|
+
})
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Безопасность
|
|
232
|
+
|
|
233
|
+
### ⚠️ Важно: Секретный ключ
|
|
234
|
+
|
|
235
|
+
**НИКОГДА не храните секретный ключ в клиентском коде!**
|
|
236
|
+
|
|
237
|
+
Секретный ключ (`secret`) должен храниться только на вашем бэкенде. Для приватных каналов SDK автоматически запрашивает подпись с вашего бэкенда через `authEndpoint`.
|
|
238
|
+
|
|
239
|
+
### Схема авторизации приватных каналов
|
|
240
|
+
|
|
241
|
+
```
|
|
242
|
+
┌─────────────┐ 1. subscribe('private-chat') ┌─────────────────┐
|
|
243
|
+
│ Browser │ ──────────────────────────────────►│ Pushler WS │
|
|
244
|
+
│ (SDK) │ │ Server │
|
|
245
|
+
└──────┬──────┘ └────────┬────────┘
|
|
246
|
+
│ │
|
|
247
|
+
│ 2. POST /pushler/auth │
|
|
248
|
+
│ { channel, socket_id } │
|
|
249
|
+
▼ │
|
|
250
|
+
┌─────────────┐ 3. Проверка авторизации │
|
|
251
|
+
│ Ваш │ + генерация подписи (с secret) │
|
|
252
|
+
│ Backend │ ───────────────────────────────────────────►│
|
|
253
|
+
└─────────────┘ 4. signature │
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Пример бэкенда для авторизации
|
|
257
|
+
|
|
258
|
+
```php
|
|
259
|
+
// Laravel пример
|
|
260
|
+
Route::post('/pushler/auth', function (Request $request) {
|
|
261
|
+
$user = auth()->user();
|
|
262
|
+
|
|
263
|
+
// Проверяем право доступа к каналу
|
|
264
|
+
$channelName = $request->channel_name;
|
|
265
|
+
if (!$user->canAccessChannel($channelName)) {
|
|
266
|
+
return response()->json(['error' => 'Forbidden'], 403);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Генерируем подпись
|
|
270
|
+
$socketId = $request->socket_id;
|
|
271
|
+
$signature = hash_hmac('sha256', "{$socketId}:{$channelName}", env('PUSHLER_SECRET'));
|
|
272
|
+
|
|
273
|
+
return response()->json(['signature' => $signature]);
|
|
274
|
+
});
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### `usePushlerChannel(pushler, channelName, options)`
|
|
278
|
+
|
|
279
|
+
Composable для работы с отдельным каналом.
|
|
280
|
+
|
|
281
|
+
```vue
|
|
282
|
+
<script setup>
|
|
283
|
+
import { usePushler, usePushlerChannel } from '@pushler/vue';
|
|
284
|
+
|
|
285
|
+
const pushler = usePushler({ ... });
|
|
286
|
+
const { channel, isSubscribed, events, lastEvent, on, clearEvents } = usePushlerChannel(
|
|
287
|
+
pushler,
|
|
288
|
+
'notifications',
|
|
289
|
+
{
|
|
290
|
+
autoSubscribe: true,
|
|
291
|
+
maxEvents: 50
|
|
292
|
+
}
|
|
293
|
+
);
|
|
294
|
+
|
|
295
|
+
on('new', (data) => {
|
|
296
|
+
console.log('Новое уведомление:', data);
|
|
297
|
+
});
|
|
298
|
+
</script>
|
|
299
|
+
|
|
300
|
+
<template>
|
|
301
|
+
<div>
|
|
302
|
+
<p>Подписан: {{ isSubscribed }}</p>
|
|
303
|
+
<p>Последнее событие: {{ lastEvent }}</p>
|
|
304
|
+
<ul>
|
|
305
|
+
<li v-for="event in events" :key="event.timestamp">
|
|
306
|
+
{{ event.event }}: {{ event.data }}
|
|
307
|
+
</li>
|
|
308
|
+
</ul>
|
|
309
|
+
<button @click="clearEvents">Очистить</button>
|
|
310
|
+
</div>
|
|
311
|
+
</template>
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## Константы
|
|
315
|
+
|
|
316
|
+
```js
|
|
317
|
+
import { ConnectionStates, ChannelTypes } from '@pushler/vue';
|
|
318
|
+
|
|
319
|
+
// Состояния подключения
|
|
320
|
+
ConnectionStates.CONNECTING // 'connecting'
|
|
321
|
+
ConnectionStates.CONNECTED // 'connected'
|
|
322
|
+
ConnectionStates.DISCONNECTED // 'disconnected'
|
|
323
|
+
ConnectionStates.RECONNECTING // 'reconnecting'
|
|
324
|
+
ConnectionStates.FAILED // 'failed'
|
|
325
|
+
|
|
326
|
+
// Типы каналов
|
|
327
|
+
ChannelTypes.PUBLIC // 'public'
|
|
328
|
+
ChannelTypes.PRIVATE // 'private'
|
|
329
|
+
ChannelTypes.PRESENCE // 'presence'
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## Примеры
|
|
333
|
+
|
|
334
|
+
### Чат в реальном времени
|
|
335
|
+
|
|
336
|
+
```vue
|
|
337
|
+
<script setup>
|
|
338
|
+
import { ref } from 'vue';
|
|
339
|
+
import { usePushler } from '@pushler/vue';
|
|
340
|
+
|
|
341
|
+
const pushler = usePushler({
|
|
342
|
+
appKey: 'chat-app-key',
|
|
343
|
+
wsUrl: 'wss://ws.pushler.ru/app',
|
|
344
|
+
autoConnect: true,
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
const messages = ref([]);
|
|
348
|
+
const newMessage = ref('');
|
|
349
|
+
|
|
350
|
+
// Подписка на канал чата
|
|
351
|
+
const chatChannel = pushler.subscribe('chat-room-1');
|
|
352
|
+
|
|
353
|
+
chatChannel.on('message', (data) => {
|
|
354
|
+
messages.value.push(data);
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
chatChannel.on('user_joined', (data) => {
|
|
358
|
+
messages.value.push({
|
|
359
|
+
type: 'system',
|
|
360
|
+
text: `${data.name} присоединился к чату`
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
async function sendMessage() {
|
|
365
|
+
// Отправка через ваш API
|
|
366
|
+
await fetch('/api/chat/send', {
|
|
367
|
+
method: 'POST',
|
|
368
|
+
body: JSON.stringify({
|
|
369
|
+
channel: 'chat-room-1',
|
|
370
|
+
message: newMessage.value
|
|
371
|
+
})
|
|
372
|
+
});
|
|
373
|
+
newMessage.value = '';
|
|
374
|
+
}
|
|
375
|
+
</script>
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### Уведомления
|
|
379
|
+
|
|
380
|
+
```vue
|
|
381
|
+
<script setup>
|
|
382
|
+
import { usePushler } from '@pushler/vue';
|
|
383
|
+
import { useNotifications } from './composables/useNotifications';
|
|
384
|
+
|
|
385
|
+
const pushler = usePushler({ autoConnect: true, ... });
|
|
386
|
+
const { show } = useNotifications();
|
|
387
|
+
|
|
388
|
+
// Приватный канал для уведомлений пользователя
|
|
389
|
+
const notificationChannel = pushler.subscribe('private-user-notifications');
|
|
390
|
+
|
|
391
|
+
notificationChannel.on('new', (data) => {
|
|
392
|
+
show({
|
|
393
|
+
title: data.title,
|
|
394
|
+
message: data.message,
|
|
395
|
+
type: data.type || 'info'
|
|
396
|
+
});
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
notificationChannel.on('badge_update', (data) => {
|
|
400
|
+
// Обновление счётчика непрочитанных
|
|
401
|
+
document.title = data.count > 0
|
|
402
|
+
? `(${data.count}) Мой сайт`
|
|
403
|
+
: 'Мой сайт';
|
|
404
|
+
});
|
|
405
|
+
</script>
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### Индикатор набора текста (Typing indicator)
|
|
409
|
+
|
|
410
|
+
```vue
|
|
411
|
+
<script setup>
|
|
412
|
+
import { ref, computed } from 'vue';
|
|
413
|
+
import { usePushler } from '@pushler/vue';
|
|
414
|
+
|
|
415
|
+
const pushler = usePushler({ ... });
|
|
416
|
+
const typingUsers = ref(new Set());
|
|
417
|
+
|
|
418
|
+
const channel = pushler.subscribe('presence-chat', {
|
|
419
|
+
user: { id: currentUserId, name: currentUserName }
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
channel.on('typing_start', (data) => {
|
|
423
|
+
typingUsers.value.add(data.user_name);
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
channel.on('typing_stop', (data) => {
|
|
427
|
+
typingUsers.value.delete(data.user_name);
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
const typingText = computed(() => {
|
|
431
|
+
const users = Array.from(typingUsers.value);
|
|
432
|
+
if (users.length === 0) return '';
|
|
433
|
+
if (users.length === 1) return `${users[0]} печатает...`;
|
|
434
|
+
if (users.length === 2) return `${users.join(' и ')} печатают...`;
|
|
435
|
+
return `${users.length} человек печатают...`;
|
|
436
|
+
});
|
|
437
|
+
</script>
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
## Использование через CDN
|
|
441
|
+
|
|
442
|
+
```html
|
|
443
|
+
<!DOCTYPE html>
|
|
444
|
+
<html>
|
|
445
|
+
<head>
|
|
446
|
+
<title>Pushler Vue Example</title>
|
|
447
|
+
<script src="https://unpkg.com/vue@3"></script>
|
|
448
|
+
<script src="https://unpkg.com/@pushler/vue"></script>
|
|
449
|
+
</head>
|
|
450
|
+
<body>
|
|
451
|
+
<div id="app">
|
|
452
|
+
<p>Status: {{ connectionState }}</p>
|
|
453
|
+
<p v-if="socketId">Socket ID: {{ socketId }}</p>
|
|
454
|
+
<button @click="connect" :disabled="isConnected">Connect</button>
|
|
455
|
+
<button @click="disconnect" :disabled="!isConnected">Disconnect</button>
|
|
456
|
+
</div>
|
|
457
|
+
|
|
458
|
+
<script>
|
|
459
|
+
const { createApp } = Vue;
|
|
460
|
+
const { usePushler } = PushlerVue;
|
|
461
|
+
|
|
462
|
+
createApp({
|
|
463
|
+
setup() {
|
|
464
|
+
const pushler = usePushler({
|
|
465
|
+
appKey: 'your-app-key',
|
|
466
|
+
wsUrl: 'wss://ws.pushler.ru/app'
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
return {
|
|
470
|
+
connectionState: pushler.connectionState,
|
|
471
|
+
socketId: pushler.socketId,
|
|
472
|
+
isConnected: pushler.isConnected,
|
|
473
|
+
connect: () => pushler.connect(),
|
|
474
|
+
disconnect: () => pushler.disconnect()
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
}).mount('#app');
|
|
478
|
+
</script>
|
|
479
|
+
</body>
|
|
480
|
+
</html>
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
## TypeScript
|
|
484
|
+
|
|
485
|
+
SDK включает TypeScript определения. Импортируйте типы:
|
|
486
|
+
|
|
487
|
+
```ts
|
|
488
|
+
import type {
|
|
489
|
+
UsePushlerReturn,
|
|
490
|
+
PushlerChannel,
|
|
491
|
+
ChannelInfo,
|
|
492
|
+
ConnectionState,
|
|
493
|
+
ChannelType
|
|
494
|
+
} from '@pushler/vue';
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
## Лицензия
|
|
498
|
+
|
|
499
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { Ref, ComputedRef } from 'vue';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Состояния подключения
|
|
5
|
+
*/
|
|
6
|
+
export declare const ConnectionStates: {
|
|
7
|
+
readonly CONNECTING: 'connecting';
|
|
8
|
+
readonly CONNECTED: 'connected';
|
|
9
|
+
readonly DISCONNECTED: 'disconnected';
|
|
10
|
+
readonly RECONNECTING: 'reconnecting';
|
|
11
|
+
readonly FAILED: 'failed';
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type ConnectionState = typeof ConnectionStates[keyof typeof ConnectionStates];
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Типы каналов
|
|
18
|
+
*/
|
|
19
|
+
export declare const ChannelTypes: {
|
|
20
|
+
readonly PUBLIC: 'public';
|
|
21
|
+
readonly PRIVATE: 'private';
|
|
22
|
+
readonly PRESENCE: 'presence';
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type ChannelType = typeof ChannelTypes[keyof typeof ChannelTypes];
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Опции подключения
|
|
29
|
+
*/
|
|
30
|
+
export interface PushlerOptions {
|
|
31
|
+
appKey?: string;
|
|
32
|
+
wsUrl?: string;
|
|
33
|
+
authEndpoint?: string;
|
|
34
|
+
autoConnect?: boolean;
|
|
35
|
+
reconnectDelay?: number;
|
|
36
|
+
maxReconnectAttempts?: number;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Опции подписки на канал
|
|
41
|
+
*/
|
|
42
|
+
export interface ChannelOptions {
|
|
43
|
+
signature?: string;
|
|
44
|
+
user?: {
|
|
45
|
+
id: string | number;
|
|
46
|
+
name?: string;
|
|
47
|
+
[key: string]: any;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Реактивный канал
|
|
53
|
+
*/
|
|
54
|
+
export interface PushlerChannel {
|
|
55
|
+
name: string;
|
|
56
|
+
originalName: string;
|
|
57
|
+
type: ChannelType;
|
|
58
|
+
subscribed: boolean;
|
|
59
|
+
options: ChannelOptions;
|
|
60
|
+
|
|
61
|
+
on(event: string, callback: (data: any) => void): PushlerChannel;
|
|
62
|
+
off(event: string, callback: (data: any) => void): PushlerChannel;
|
|
63
|
+
emit(event: string, data: any): void;
|
|
64
|
+
unsubscribe(): void;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Информация о канале
|
|
69
|
+
*/
|
|
70
|
+
export interface ChannelInfo {
|
|
71
|
+
name: string;
|
|
72
|
+
fullName: string;
|
|
73
|
+
type: ChannelType;
|
|
74
|
+
subscribed: boolean;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Возвращаемое значение usePushler
|
|
79
|
+
*/
|
|
80
|
+
export interface UsePushlerReturn {
|
|
81
|
+
// Состояние
|
|
82
|
+
connectionState: Readonly<Ref<ConnectionState>>;
|
|
83
|
+
socketId: Readonly<Ref<string | null>>;
|
|
84
|
+
error: Readonly<Ref<string | null>>;
|
|
85
|
+
reconnectAttempts: Readonly<Ref<number>>;
|
|
86
|
+
|
|
87
|
+
// Вычисляемые свойства
|
|
88
|
+
isConnected: ComputedRef<boolean>;
|
|
89
|
+
isConnecting: ComputedRef<boolean>;
|
|
90
|
+
isReconnecting: ComputedRef<boolean>;
|
|
91
|
+
|
|
92
|
+
// Методы
|
|
93
|
+
connect(options?: PushlerOptions): void;
|
|
94
|
+
disconnect(): void;
|
|
95
|
+
subscribe(channelName: string, options?: ChannelOptions): PushlerChannel;
|
|
96
|
+
unsubscribe(channelName: string): void;
|
|
97
|
+
channel(channelName: string): PushlerChannel | undefined;
|
|
98
|
+
getChannels(): ChannelInfo[];
|
|
99
|
+
on(event: string, callback: (data: any) => void): void;
|
|
100
|
+
off(event: string, callback: (data: any) => void): void;
|
|
101
|
+
|
|
102
|
+
// Утилиты
|
|
103
|
+
formatChannelName(channelName: string): string;
|
|
104
|
+
extractChannelName(fullChannelName: string): string;
|
|
105
|
+
getChannelType(channelName: string): ChannelType;
|
|
106
|
+
|
|
107
|
+
// Константы
|
|
108
|
+
ConnectionStates: typeof ConnectionStates;
|
|
109
|
+
ChannelTypes: typeof ChannelTypes;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Vue composable для работы с Pushler WebSocket
|
|
114
|
+
*/
|
|
115
|
+
export declare function usePushler(options?: PushlerOptions): UsePushlerReturn;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Опции usePushlerChannel
|
|
119
|
+
*/
|
|
120
|
+
export interface ChannelHookOptions extends ChannelOptions {
|
|
121
|
+
autoSubscribe?: boolean;
|
|
122
|
+
maxEvents?: number;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Событие канала
|
|
127
|
+
*/
|
|
128
|
+
export interface ChannelEvent {
|
|
129
|
+
event: string;
|
|
130
|
+
data: any;
|
|
131
|
+
timestamp: Date;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Возвращаемое значение usePushlerChannel
|
|
136
|
+
*/
|
|
137
|
+
export interface UsePushlerChannelReturn {
|
|
138
|
+
channel: Ref<PushlerChannel | null>;
|
|
139
|
+
isSubscribed: Ref<boolean>;
|
|
140
|
+
lastEvent: Ref<ChannelEvent | null>;
|
|
141
|
+
events: ChannelEvent[];
|
|
142
|
+
|
|
143
|
+
subscribe(): PushlerChannel | undefined;
|
|
144
|
+
unsubscribe(): void;
|
|
145
|
+
on(event: string, callback: (data: any) => void): () => void;
|
|
146
|
+
off(event: string): void;
|
|
147
|
+
clearEvents(): void;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Vue composable для работы с отдельным каналом
|
|
152
|
+
*/
|
|
153
|
+
export declare function usePushlerChannel(
|
|
154
|
+
pushler: UsePushlerReturn,
|
|
155
|
+
channelName: string,
|
|
156
|
+
options?: ChannelHookOptions
|
|
157
|
+
): UsePushlerChannelReturn;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Символ для инъекции Pushler
|
|
161
|
+
*/
|
|
162
|
+
export declare const PushlerKey: symbol;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Vue Plugin
|
|
166
|
+
*/
|
|
167
|
+
export declare const PushlerPlugin: {
|
|
168
|
+
install(app: any, options?: PushlerOptions): void;
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Хелпер для получения инстанса Pushler
|
|
173
|
+
*/
|
|
174
|
+
export declare function usePushlerInstance(): UsePushlerReturn;
|
|
175
|
+
|
|
176
|
+
export default usePushler;
|