vue-streaming 0.1.4 → 2.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.
Files changed (39) hide show
  1. package/README.md +425 -699
  2. package/dist/WebSocketStream.vue_vue_type_script_setup_true_lang-C_F2vNNk.js +1081 -0
  3. package/dist/WebSocketStream.vue_vue_type_script_setup_true_lang-C_F2vNNk.js.map +1 -0
  4. package/dist/WebSocketStream.vue_vue_type_script_setup_true_lang-EzMJEQkx.cjs +2 -0
  5. package/dist/WebSocketStream.vue_vue_type_script_setup_true_lang-EzMJEQkx.cjs.map +1 -0
  6. package/dist/components/index.cjs +2 -0
  7. package/dist/components/index.cjs.map +1 -0
  8. package/dist/components/index.js +15 -0
  9. package/dist/components/index.js.map +1 -0
  10. package/dist/composables/index.cjs +2 -0
  11. package/dist/composables/index.cjs.map +1 -0
  12. package/dist/composables/index.js +15 -0
  13. package/dist/composables/index.js.map +1 -0
  14. package/dist/index.cjs +1 -3
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.js +62 -2
  17. package/dist/index.js.map +1 -1
  18. package/dist/types.cjs +2 -0
  19. package/dist/types.cjs.map +1 -0
  20. package/dist/types.js +2 -0
  21. package/dist/types.js.map +1 -0
  22. package/dist/usePointCloud-D0qcpYFY.js +115 -0
  23. package/dist/usePointCloud-D0qcpYFY.js.map +1 -0
  24. package/dist/usePointCloud-D2csBAs8.cjs +2 -0
  25. package/dist/usePointCloud-D2csBAs8.cjs.map +1 -0
  26. package/dist/useWebSocket-7-qar6to.cjs +4 -0
  27. package/dist/useWebSocket-7-qar6to.cjs.map +1 -0
  28. package/dist/useWebSocket-CrE6QkTW.js +1278 -0
  29. package/dist/useWebSocket-CrE6QkTW.js.map +1 -0
  30. package/dist/utils/index.cjs +2 -0
  31. package/dist/utils/index.cjs.map +1 -0
  32. package/dist/utils/index.js +503 -0
  33. package/dist/utils/index.js.map +1 -0
  34. package/dist/vue-streaming.css +1 -0
  35. package/package.json +126 -69
  36. package/dist/index.d.cts +0 -49
  37. package/dist/index.d.ts +0 -49
  38. package/dist/index.global.js +0 -8
  39. package/dist/index.global.js.map +0 -1
package/README.md CHANGED
@@ -1,699 +1,425 @@
1
- # vue-streaming
2
-
3
- <div align="center">
4
- **Universal Vue 3 streaming component for real-time data and media**
5
-
6
- [![npm version](https://img.shields.io/npm/v/vue-streaming.svg)](https://github.com/package/vue-streaming)
7
- [![Vue 3](https://img.shields.io/badge/vue-3.3%2B-brightgreen.svg)](https://vuejs.org/)
8
- [![TypeScript](https://img.shields.io/badge/typescript-ready-blue.svg)](https://www.typescriptlang.org/)
9
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
10
- [![Bundle Size](https://img.shields.io/bundlephobia/minzip/vue-streaming)](https://bundlephobia.com/package/vue-streaming)
11
-
12
- </div>
13
-
14
- ## 🌟 Features
15
-
16
- Vue Streaming provides a unified `<StreamPlayer>` component that handles **6 different streaming protocols** with a consistent, declarative API:
17
-
18
- - 🔌 **WebSocket** - Real-time bidirectional communication
19
- - 📡 **Server-Sent Events (SSE)** - Server-to-client event streams
20
- - 🌊 **HTTP Streaming** - Chunked transfer encoding streams
21
- - 🔄 **Long Polling** - HTTP-based persistent connections
22
- - 📺 **HLS Video** - HTTP Live Streaming for adaptive video
23
- - 🎥 **WebRTC** - Peer-to-peer real-time communication
24
-
25
- ### ✨ Why Choose Vue Streaming?
26
-
27
- - **One API, Many Protocols**: Switch between streaming types with just a prop change
28
- - **Vue 3 Native**: Built for Composition API with full TypeScript support
29
- - **Headless Design**: No imposed styling - complete UI control
30
- - **Production Ready**: Auto-reconnection, error handling, and backoff strategies
31
- - **Lightweight**: Thin wrapper around `js-streaming` core library
32
- - **Extensible**: Custom slots and event system for any use case
33
-
34
- ## 📦 Installation
35
-
36
- ```bash
37
- # npm
38
- npm install vue-streaming js-streaming
39
-
40
- # yarn
41
- yarn add vue-streaming js-streaming
42
-
43
- # pnpm
44
- pnpm add vue-streaming js-streaming
45
- ```
46
-
47
- > **Note**: Both `vue-streaming` and `js-streaming` are required. Vue Streaming is a wrapper that leverages the core `js-streaming` library.
48
-
49
- ### Requirements
50
-
51
- - **Vue**: 3.3.0 or higher
52
- - **Node**: 16+ (for build tools)
53
- - **Build System**: Vite, Nuxt 3, or Vue CLI with TypeScript support
54
-
55
- ## 🚀 Quick Start
56
-
57
- ### Basic WebSocket Example
58
-
59
- ```vue
60
- <script setup lang="ts">
61
- import { ref } from "vue";
62
- import { StreamPlayer } from "vue-streaming";
63
-
64
- const player = ref<InstanceType<typeof StreamPlayer>>();
65
- const config = {
66
- url: "wss://echo.websocket.events",
67
- protocols: ["echo-protocol"],
68
- };
69
-
70
- function sendMessage() {
71
- player.value?.send("Hello WebSocket!");
72
- }
73
- </script>
74
-
75
- <template>
76
- <div>
77
- <h2>WebSocket Demo</h2>
78
- <StreamPlayer
79
- ref="player"
80
- type="websocket"
81
- :config="config"
82
- :auto-open="true"
83
- @message="console.log('Received:', $event)"
84
- @status="console.log('Status:', $event)"
85
- />
86
- <button @click="sendMessage">Send Message</button>
87
- </div>
88
- </template>
89
- ```
90
-
91
- ### HLS Video Streaming
92
-
93
- ```vue
94
- <script setup lang="ts">
95
- import { StreamPlayer } from "vue-streaming";
96
-
97
- const hlsConfig = {
98
- url: "https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8",
99
- };
100
- </script>
101
-
102
- <template>
103
- <StreamPlayer
104
- type="hls"
105
- :config="hlsConfig"
106
- :auto-open="true"
107
- :autoplay="true"
108
- :controls="true"
109
- :muted="false"
110
- />
111
- </template>
112
- ```
113
-
114
- ### Server-Sent Events
115
-
116
- ```vue
117
- <script setup lang="ts">
118
- import { StreamPlayer } from "vue-streaming";
119
-
120
- const sseConfig = {
121
- url: "/api/events",
122
- headers: { Authorization: "Bearer token" },
123
- };
124
- </script>
125
-
126
- <template>
127
- <StreamPlayer
128
- type="sse"
129
- :config="sseConfig"
130
- :auto-open="true"
131
- @message="handleServerEvent"
132
- />
133
- </template>
134
- ```
135
-
136
- ## 📚 API Reference
137
-
138
- ### Props
139
-
140
- | Prop | Type | Default | Description |
141
- | ------------- | ------------ | ---------- | -------------------------------------------------------------------------- |
142
- | `type` | `StreamType` | _required_ | Protocol type: `websocket`, `sse`, `http`, `long-polling`, `hls`, `webrtc` |
143
- | `config` | `object` | _required_ | Protocol-specific configuration object |
144
- | `autoOpen` | `boolean` | `false` | Automatically open connection on mount |
145
- | `autoplay` | `boolean` | `false` | Auto-play for video streams (HLS/WebRTC) |
146
- | `controls` | `boolean` | `true` | Show video controls |
147
- | `playsInline` | `boolean` | `true` | Play video inline on mobile |
148
- | `muted` | `boolean` | `false` | Start video muted |
149
- | `logLimit` | `number` | `500` | Maximum messages to keep in memory |
150
- | `videoAttrs` | `object` | `{}` | Additional HTML video element attributes |
151
-
152
- ### Events
153
-
154
- | Event | Payload | Description |
155
- | ---------- | -------------- | ------------------------------------------------------------------------- |
156
- | `@open` | `void` | Connection established |
157
- | `@close` | `void` | Connection closed |
158
- | `@status` | `StreamStatus` | Status change: `idle`, `connecting`, `open`, `closing`, `closed`, `error` |
159
- | `@error` | `Error` | Error occurred |
160
- | `@message` | `any` | New message/data received |
161
-
162
- ### Exposed Methods & Properties
163
-
164
- ```typescript
165
- interface StreamPlayerInstance {
166
- // Methods
167
- open(): Promise<void>;
168
- close(): Promise<void>;
169
- send(data: unknown): void; // Available for WebSocket/WebRTC
170
-
171
- // Reactive State
172
- status: Ref<StreamStatus>;
173
- isOpen: Ref<boolean>;
174
- error: Ref<Error | null>;
175
- messages: Ref<unknown[]>;
176
- }
177
- ```
178
-
179
- ### Configuration Objects
180
-
181
- Each stream type accepts different configuration options:
182
-
183
- #### WebSocket Config
184
-
185
- ```typescript
186
- {
187
- url: string
188
- protocols?: string[]
189
- headers?: Record<string, string>
190
- binaryType?: 'blob' | 'arraybuffer'
191
- }
192
- ```
193
-
194
- #### SSE Config
195
-
196
- ```typescript
197
- {
198
- url: string
199
- headers?: Record<string, string>
200
- withCredentials?: boolean
201
- eventSourceInitDict?: EventSourceInit
202
- }
203
- ```
204
-
205
- #### HTTP Streaming Config
206
-
207
- ```typescript
208
- {
209
- url: string
210
- method?: string
211
- headers?: Record<string, string>
212
- body?: any
213
- signal?: AbortSignal
214
- }
215
- ```
216
-
217
- #### Long Polling Config
218
-
219
- ```typescript
220
- {
221
- url: string
222
- interval?: number
223
- headers?: Record<string, string>
224
- timeout?: number
225
- }
226
- ```
227
-
228
- #### HLS Config
229
-
230
- ```typescript
231
- {
232
- url: string
233
- hlsConfig?: any // Passed to HLS.js
234
- }
235
- ```
236
-
237
- #### WebRTC Config
238
-
239
- ```typescript
240
- {
241
- configuration?: RTCConfiguration
242
- attachVideo?: boolean // Auto-attach video stream
243
- // Additional WebRTC-specific options
244
- }
245
- ```
246
-
247
- ## 🎨 Customization with Slots
248
-
249
- ### Custom Log Display
250
-
251
- ```vue
252
- <template>
253
- <StreamPlayer type="websocket" :config="config">
254
- <template #log="{ messages, status, error }">
255
- <div class="custom-log">
256
- <div class="status-bar">
257
- Status: <span :class="status">{{ status }}</span>
258
- </div>
259
- <div v-if="error" class="error">{{ error.message }}</div>
260
- <div class="messages">
261
- <div v-for="(msg, i) in messages" :key="i" class="message">
262
- {{ typeof msg === "string" ? msg : JSON.stringify(msg) }}
263
- </div>
264
- </div>
265
- </div>
266
- </template>
267
- </StreamPlayer>
268
- </template>
269
-
270
- <style scoped>
271
- .custom-log {
272
- border: 2px solid #007acc;
273
- border-radius: 8px;
274
- padding: 16px;
275
- background: #f8f9fa;
276
- }
277
- .status-bar {
278
- font-weight: bold;
279
- }
280
- .status.open {
281
- color: green;
282
- }
283
- .status.error {
284
- color: red;
285
- }
286
- .messages {
287
- max-height: 300px;
288
- overflow-y: auto;
289
- }
290
- .message {
291
- padding: 4px 0;
292
- border-bottom: 1px solid #eee;
293
- }
294
- </style>
295
- ```
296
-
297
- ### Custom Action Buttons
298
-
299
- ```vue
300
- <template>
301
- <StreamPlayer type="websocket" :config="config">
302
- <template #actions="{ open, close, send, isOpen, status }">
303
- <div class="action-bar">
304
- <button @click="open" :disabled="isOpen">Connect</button>
305
- <button @click="close" :disabled="!isOpen">Disconnect</button>
306
- <button @click="send('ping')" :disabled="!isOpen">Ping</button>
307
- <span class="status-indicator" :class="status">{{ status }}</span>
308
- </div>
309
- </template>
310
- </StreamPlayer>
311
- </template>
312
- ```
313
-
314
- ## 🛠️ Advanced Usage
315
-
316
- ### Auto-Reconnection and Error Handling
317
-
318
- ```vue
319
- <script setup lang="ts">
320
- import { ref } from "vue";
321
- import { StreamPlayer } from "vue-streaming";
322
-
323
- const config = ref({
324
- url: "wss://api.example.com/ws",
325
- // Auto-reconnection settings
326
- autoReconnect: true,
327
- maxRetries: 5,
328
- heartbeatMs: 30000,
329
- backoff: {
330
- baseMs: 1000,
331
- maxMs: 10000,
332
- factor: 1.5,
333
- jitter: true,
334
- },
335
- });
336
-
337
- function handleError(error: Error) {
338
- console.error("Stream error:", error);
339
- // Custom error handling logic
340
- }
341
-
342
- function handleStatusChange(status: string) {
343
- if (status === "error") {
344
- // Handle connection errors
345
- } else if (status === "open") {
346
- console.log("Successfully connected!");
347
- }
348
- }
349
- </script>
350
-
351
- <template>
352
- <StreamPlayer
353
- type="websocket"
354
- :config="config"
355
- @error="handleError"
356
- @status="handleStatusChange"
357
- />
358
- </template>
359
- ```
360
-
361
- ### Dynamic Configuration
362
-
363
- ```vue
364
- <script setup lang="ts">
365
- import { ref, computed } from "vue";
366
- import { StreamPlayer } from "vue-streaming";
367
-
368
- const apiEndpoint = ref("wss://api.example.com");
369
- const authToken = ref("");
370
-
371
- const dynamicConfig = computed(() => ({
372
- url: `${apiEndpoint.value}/ws`,
373
- headers: {
374
- Authorization: `Bearer ${authToken.value}`,
375
- },
376
- }));
377
-
378
- // Configuration changes will automatically recreate the stream
379
- </script>
380
-
381
- <template>
382
- <div>
383
- <input v-model="apiEndpoint" placeholder="WebSocket URL" />
384
- <input v-model="authToken" placeholder="Auth Token" />
385
-
386
- <StreamPlayer
387
- type="websocket"
388
- :config="dynamicConfig"
389
- :auto-open="!!authToken"
390
- />
391
- </div>
392
- </template>
393
- ```
394
-
395
- ### Programmatic Control
396
-
397
- ```vue
398
- <script setup lang="ts">
399
- import { ref, onMounted } from "vue";
400
- import { StreamPlayer } from "vue-streaming";
401
-
402
- const player = ref<InstanceType<typeof StreamPlayer>>();
403
-
404
- onMounted(() => {
405
- // Programmatic control
406
- setTimeout(() => {
407
- player.value?.open();
408
- }, 1000);
409
-
410
- // Send periodic messages
411
- setInterval(() => {
412
- if (player.value?.isOpen) {
413
- player.value.send({
414
- type: "heartbeat",
415
- timestamp: Date.now(),
416
- });
417
- }
418
- }, 10000);
419
- });
420
-
421
- // Access reactive state
422
- const connectionStatus = computed(() => player.value?.status || "idle");
423
- const messageCount = computed(() => player.value?.messages.length || 0);
424
- </script>
425
- ```
426
-
427
- ## 🔧 TypeScript Support
428
-
429
- Vue Streaming is fully typed. Import types for enhanced development experience:
430
-
431
- ```typescript
432
- import type {
433
- StreamType,
434
- StreamStatus,
435
- StreamState,
436
- StreamAPI,
437
- } from "vue-streaming";
438
-
439
- // Component instance type
440
- import { StreamPlayer } from "vue-streaming";
441
- type StreamPlayerInstance = InstanceType<typeof StreamPlayer>;
442
-
443
- // Usage in composition function
444
- function useStreamPlayer() {
445
- const player = ref<StreamPlayerInstance>();
446
- const status = computed(() => player.value?.status || "idle");
447
-
448
- return { player, status };
449
- }
450
- ```
451
-
452
- ## 🌐 Nuxt 3 / SSR Usage
453
-
454
- For server-side rendering, wrap the component to prevent hydration issues:
455
-
456
- ```vue
457
- <template>
458
- <div>
459
- <ClientOnly>
460
- <StreamPlayer type="websocket" :config="config" :auto-open="true" />
461
- <template #fallback>
462
- <div>Loading stream player...</div>
463
- </template>
464
- </ClientOnly>
465
- </div>
466
- </template>
467
- ```
468
-
469
- Or create an async component:
470
-
471
- ```vue
472
- <script setup lang="ts">
473
- import { defineAsyncComponent } from "vue";
474
-
475
- const StreamPlayer = defineAsyncComponent(() =>
476
- import("vue-streaming").then((m) => m.StreamPlayer)
477
- );
478
- </script>
479
- ```
480
-
481
- ## 📱 Real-World Examples
482
-
483
- ### Chat Application
484
-
485
- ```vue
486
- <script setup lang="ts">
487
- import { ref } from "vue";
488
- import { StreamPlayer } from "vue-streaming";
489
-
490
- const message = ref("");
491
- const chatPlayer = ref<InstanceType<typeof StreamPlayer>>();
492
-
493
- const config = {
494
- url: "wss://chat.example.com/ws",
495
- protocols: ["chat-v1"],
496
- };
497
-
498
- function sendMessage() {
499
- if (message.value.trim()) {
500
- chatPlayer.value?.send({
501
- type: "message",
502
- content: message.value,
503
- timestamp: new Date().toISOString(),
504
- });
505
- message.value = "";
506
- }
507
- }
508
-
509
- function handleChatMessage(msg: any) {
510
- if (msg.type === "message") {
511
- // Handle incoming chat message
512
- console.log(`${msg.user}: ${msg.content}`);
513
- }
514
- }
515
- </script>
516
-
517
- <template>
518
- <div class="chat-container">
519
- <StreamPlayer
520
- ref="chatPlayer"
521
- type="websocket"
522
- :config="config"
523
- :auto-open="true"
524
- @message="handleChatMessage"
525
- >
526
- <template #log="{ messages }">
527
- <div class="chat-messages">
528
- <div v-for="msg in messages" :key="msg.id" class="message">
529
- <strong>{{ msg.user }}:</strong> {{ msg.content }}
530
- </div>
531
- </div>
532
- </template>
533
-
534
- <template #actions="{ isOpen }">
535
- <div class="chat-input">
536
- <input
537
- v-model="message"
538
- @keyup.enter="sendMessage"
539
- :disabled="!isOpen"
540
- placeholder="Type a message..."
541
- />
542
- <button @click="sendMessage" :disabled="!isOpen">Send</button>
543
- </div>
544
- </template>
545
- </StreamPlayer>
546
- </div>
547
- </template>
548
- ```
549
-
550
- ### Live Data Dashboard
551
-
552
- ```vue
553
- <script setup lang="ts">
554
- import { ref, computed } from "vue";
555
- import { StreamPlayer } from "vue-streaming";
556
-
557
- const metrics = ref<any[]>([]);
558
-
559
- const config = {
560
- url: "/api/metrics/stream",
561
- headers: { Accept: "text/event-stream" },
562
- };
563
-
564
- function handleMetricsUpdate(data: any) {
565
- if (data.type === "metrics") {
566
- metrics.value = [...metrics.value, data.payload].slice(-50); // Keep last 50
567
- }
568
- }
569
-
570
- const latestMetrics = computed(
571
- () => metrics.value[metrics.value.length - 1]?.payload || {}
572
- );
573
- </script>
574
-
575
- <template>
576
- <div class="dashboard">
577
- <h1>Live Metrics Dashboard</h1>
578
-
579
- <div class="metrics-grid">
580
- <div class="metric-card">
581
- <h3>CPU Usage</h3>
582
- <div class="metric-value">{{ latestMetrics.cpu }}%</div>
583
- </div>
584
- <div class="metric-card">
585
- <h3>Memory</h3>
586
- <div class="metric-value">{{ latestMetrics.memory }}MB</div>
587
- </div>
588
- </div>
589
-
590
- <StreamPlayer
591
- type="sse"
592
- :config="config"
593
- :auto-open="true"
594
- @message="handleMetricsUpdate"
595
- >
596
- <template #log="{ messages, status }">
597
- <div class="connection-status">
598
- Status: <span :class="status">{{ status }}</span> | Updates:
599
- {{ messages.length }}
600
- </div>
601
- </template>
602
- </StreamPlayer>
603
- </div>
604
- </template>
605
- ```
606
-
607
- ## 🐛 Troubleshooting
608
-
609
- ### Common Issues
610
-
611
- **Connection fails immediately**
612
-
613
- ```typescript
614
- // Check if the URL is correct and accessible
615
- const config = {
616
- url: "ws://localhost:3000/ws", // http:// for ws://, https:// for wss://
617
- };
618
- ```
619
-
620
- **CORS issues with SSE/HTTP**
621
-
622
- ```typescript
623
- const config = {
624
- url: "/api/stream",
625
- headers: {
626
- "Access-Control-Allow-Origin": "*",
627
- },
628
- };
629
- ```
630
-
631
- **Video not playing (HLS/WebRTC)**
632
-
633
- ```vue
634
- <StreamPlayer
635
- type="hls"
636
- :config="hlsConfig"
637
- :autoplay="true"
638
- :muted="true" <!-- Required for autoplay in most browsers -->
639
- :plays-inline="true"
640
- />
641
- ```
642
-
643
- **Messages not displaying**
644
-
645
- ```javascript
646
- // Check if logLimit is sufficient
647
- <StreamPlayer :log-limit="1000" />
648
-
649
- // Or handle messages manually
650
- @message="msg => console.log('Received:', msg)"
651
- ```
652
-
653
- ### Browser Compatibility
654
-
655
- - **WebSocket**: All modern browsers
656
- - **SSE**: All modern browsers (IE/Edge requires polyfill)
657
- - **HLS**: Requires HLS.js for non-Safari browsers
658
- - **WebRTC**: Modern browsers (check specific API support)
659
-
660
- ### Performance Tips
661
-
662
- 1. **Limit message history**: Use reasonable `logLimit` values
663
- 2. **Debounce rapid updates**: Use `shallowRef` for message arrays
664
- 3. **Clean up properly**: Component handles cleanup automatically
665
- 4. **Use object URLs**: For large binary data in WebRTC/HLS
666
-
667
- ## 🤝 Contributing
668
-
669
- We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
670
-
671
- ### Development Setup
672
-
673
- ```bash
674
- git clone https://github.com/yourusername/vue-streaming.git
675
- cd vue-streaming
676
- npm install
677
- npm run dev
678
- ```
679
-
680
- ### Building
681
-
682
- ```bash
683
- npm run build
684
- npm run test
685
- ```
686
-
687
- ## 📄 License
688
-
689
- MIT © Vue Streaming Contributors
690
-
691
- ---
692
-
693
- <div align="center">
694
-
695
- **[Documentation](https://github.com/yourusername/vue-streaming#readme) • [Examples](https://github.com/yourusername/vue-streaming/tree/main/examples) • [Issues](https://github.com/yourusername/vue-streaming/issues)**
696
-
697
- Made with ❤️ for the Vue.js community
698
-
699
- </div>
1
+ # vue-streaming
2
+
3
+ <p align="center">
4
+ <a href="https://www.npmjs.com/package/keroloszakaria/vue-streaming">
5
+ <img src="https://img.shields.io/npm/v/keroloszakaria/vue-streaming.svg" alt="npm version" />
6
+ </a>
7
+ <a href="https://www.npmjs.com/package/keroloszakaria/vue-streaming">
8
+ <img src="https://img.shields.io/npm/dm/keroloszakaria/vue-streaming.svg" alt="npm downloads" />
9
+ </a>
10
+ <a href="https://vuejs.org/">
11
+ <img src="https://img.shields.io/badge/Vue-3.3%2B-brightgreen.svg" alt="Vue 3" />
12
+ </a>
13
+ <a href="https://www.typescriptlang.org/">
14
+ <img src="https://img.shields.io/badge/TypeScript-Ready-blue.svg" alt="TypeScript" />
15
+ </a>
16
+ <a href="LICENSE">
17
+ <img src="https://img.shields.io/badge/license-MIT-yellow.svg" alt="License" />
18
+ </a>
19
+ </p>
20
+
21
+ <p align="center">
22
+ Comprehensive <b>Vue 3 streaming library</b> with composables for WebSocket, Socket.IO, HLS, Laravel Echo, WebRTC, Point Cloud, and Data Streaming.
23
+ </p>
24
+
25
+ ---
26
+
27
+ ## Features
28
+
29
+ - **useWebSocket** - Native WebSocket with auto-reconnect and heartbeat
30
+ - **useSocketIO** - Full Socket.IO support with rooms and events
31
+ - **useHLS** - HTTP Live Streaming with quality control
32
+ - **useLaravelEcho** - Pusher/Reverb broadcasting integration
33
+ - **useWebRTC** - Peer connections with data channels for point cloud/detection
34
+ - **usePointCloud** - LiDAR/3D point cloud streaming and decoding
35
+ - **useDataStream** - Generic data streaming with buffering and deduplication
36
+ - **Components** - StreamViewer, HLSPlayer, PointCloudViewer, WebRTCViewer
37
+ - **TypeScript** - Full TypeScript support with exported types
38
+ - **Tree-shakeable** - Import only what you need
39
+
40
+ ---
41
+
42
+ ## Installation
43
+
44
+ `bash
45
+ npm install vue-streaming
46
+
47
+ # yarn
48
+
49
+ yarn add vue-streaming
50
+
51
+ # pnpm
52
+
53
+ pnpm add vue-streaming
54
+ `
55
+
56
+ ### Optional Dependencies
57
+
58
+ Install based on the features you need:
59
+
60
+ `bash
61
+
62
+ # For HLS streaming
63
+
64
+ npm install hls.js
65
+
66
+ # For Socket.IO
67
+
68
+ npm install socket.io-client
69
+
70
+ # For Laravel Echo
71
+
72
+ npm install laravel-echo pusher-js
73
+
74
+ # For Point Cloud visualization
75
+
76
+ npm install three @types/three
77
+
78
+ # For DRACO compression
79
+
80
+ npm install draco3d
81
+ `
82
+
83
+ ---
84
+
85
+ ## Quick Start
86
+
87
+ ### WebSocket
88
+
89
+ `vue
90
+
91
+ <script setup lang="ts">
92
+ import { useWebSocket } from 'vue-streaming'
93
+
94
+ const { isConnected, lastMessage, connect, send, disconnect } = useWebSocket({
95
+ url: 'wss://example.com/ws',
96
+ autoConnect: true,
97
+ autoReconnect: true
98
+ }, {
99
+ onMessage: (data) => console.log('Received:', data)
100
+ })
101
+ </script>
102
+
103
+ `
104
+
105
+ ### Socket.IO
106
+
107
+ `vue
108
+
109
+ <script setup lang="ts">
110
+ import { useSocketIO } from 'vue-streaming'
111
+
112
+ const { isConnected, connect, emit, on } = useSocketIO({
113
+ url: 'https://example.com',
114
+ autoConnect: true
115
+ })
116
+
117
+ // Listen to events
118
+ on('chat:message', (msg) => console.log(msg))
119
+
120
+ // Emit events
121
+ emit('chat:send', { text: 'Hello!' })
122
+ </script>
123
+
124
+ `
125
+
126
+ ### HLS Streaming
127
+
128
+ `vue
129
+
130
+ <script setup lang="ts">
131
+ import { ref, onMounted } from 'vue'
132
+ import { useHLS } from 'vue-streaming'
133
+
134
+ const videoRef = ref<HTMLVideoElement | null>(null)
135
+
136
+ const { attach, play, levels, setLevel } = useHLS({
137
+ url: 'https://example.com/stream.m3u8',
138
+ autoPlay: true
139
+ })
140
+
141
+ onMounted(() => {
142
+ if (videoRef.value) {
143
+ attach(videoRef.value)
144
+ }
145
+ })
146
+ </script>
147
+
148
+ <template>
149
+ <video ref="videoRef" controls />
150
+ </template>
151
+ `
152
+
153
+ ### Laravel Echo
154
+
155
+ `vue
156
+
157
+ <script setup lang="ts">
158
+ import { useLaravelEcho } from 'vue-streaming'
159
+
160
+ const { channel, privateChannel, presenceChannel } = useLaravelEcho({
161
+ broadcaster: 'pusher',
162
+ key: 'your-pusher-key',
163
+ cluster: 'mt1'
164
+ })
165
+
166
+ // Public channel
167
+ const chat = channel('chat')
168
+ chat.listen('MessageSent', (e) => console.log(e))
169
+
170
+ // Private channel
171
+ const user = privateChannel('user.1')
172
+ user.listen('NotificationReceived', (e) => console.log(e))
173
+
174
+ // Presence channel
175
+ const room = presenceChannel('room.1')
176
+ room.here((users) => console.log('Online:', users))
177
+ room.joining((user) => console.log('Joined:', user))
178
+ room.leaving((user) => console.log('Left:', user))
179
+ </script>
180
+
181
+ `
182
+
183
+ ### WebRTC with Point Cloud
184
+
185
+ `vue
186
+
187
+ <script setup lang="ts">
188
+ import { useWebRTC } from 'vue-streaming'
189
+
190
+ const {
191
+ isRunning,
192
+ connectionState,
193
+ lastPointCloudFrame,
194
+ lastBoundingBoxes,
195
+ start,
196
+ stop
197
+ } = useWebRTC({
198
+ signalingUrl: 'wss://example.com/signaling',
199
+ enablePointCloud: true,
200
+ enableDetections: true
201
+ }, {
202
+ onPointCloudFrame: (frame) => {
203
+ console.log(Received ${frame.points.length} points)
204
+ },
205
+ onBoundingBoxData: (boxes) => {
206
+ console.log(Received ${boxes.length} detections)
207
+ }
208
+ })
209
+ </script>
210
+
211
+ `
212
+
213
+ ### Point Cloud Decoding
214
+
215
+ `vue
216
+
217
+ <script setup lang="ts">
218
+ import { usePointCloud } from 'vue-streaming'
219
+
220
+ const { decode, points, bounds, isDecoding } = usePointCloud({
221
+ format: 'auto',
222
+ maxPoints: 100000,
223
+ downsampleFactor: 2
224
+ })
225
+
226
+ // Decode point cloud data
227
+ const result = await decode(arrayBuffer)
228
+ console.log(Decoded ${result.points.length} points)
229
+ </script>
230
+
231
+ `
232
+
233
+ ### Data Streaming
234
+
235
+ `vue
236
+
237
+ <script setup lang="ts">
238
+ import { useDataStream } from 'vue-streaming'
239
+
240
+ interface SensorData {
241
+ id: string
242
+ value: number
243
+ timestamp: number
244
+ }
245
+
246
+ const { data, buffer, push, subscribe, stats } = useDataStream<SensorData>({
247
+ bufferSize: 1000,
248
+ deduplicate: true,
249
+ deduplicateKey: 'id',
250
+ throttleMs: 100
251
+ })
252
+
253
+ // Subscribe to data
254
+ subscribe((item) => console.log('New data:', item))
255
+
256
+ // Push data manually
257
+ push({ id: 'sensor-1', value: 42, timestamp: Date.now() })
258
+ </script>
259
+
260
+ `
261
+
262
+ ---
263
+
264
+ ## Components
265
+
266
+ ### StreamViewer
267
+
268
+ Generic stream viewer for displaying real-time data:
269
+
270
+ `vue
271
+ <template>
272
+ <StreamViewer
273
+ :data="streamData"
274
+ :max-lines="100"
275
+ :auto-scroll="true"
276
+ :show-timestamps="true"
277
+ />
278
+ </template>
279
+ `
280
+
281
+ ### HLSPlayer
282
+
283
+ HLS video player with quality controls:
284
+
285
+ `vue
286
+ <template>
287
+ <HLSPlayer
288
+ src="https://example.com/stream.m3u8"
289
+ :auto-play="true"
290
+ :controls="true"
291
+ :low-latency="true"
292
+ @ready="onReady"
293
+ @level-change="onQualityChange"
294
+ />
295
+ </template>
296
+ `
297
+
298
+ ### PointCloudViewer
299
+
300
+ 3D point cloud visualization (requires three.js):
301
+
302
+ `vue
303
+ <template>
304
+ <PointCloudViewer
305
+ :points="pointCloudData"
306
+ :point-size="0.02"
307
+ :auto-rotate="true"
308
+ :show-grid="true"
309
+ />
310
+ </template>
311
+ `
312
+
313
+ ### WebRTCViewer
314
+
315
+ WebRTC stream viewer with connection controls:
316
+
317
+ `vue
318
+ <template>
319
+ <WebRTCViewer
320
+ signaling-url="wss://example.com/signaling"
321
+ :enable-point-cloud="true"
322
+ :enable-detections="true"
323
+ :auto-connect="true"
324
+ @pointcloud="onPointCloud"
325
+ @detections="onDetections"
326
+ />
327
+ </template>
328
+ `
329
+
330
+ ---
331
+
332
+ ## API Reference
333
+
334
+ ### useWebSocket
335
+
336
+ | Option | Type | Default | Description |
337
+ | ---------------------- | -------------------- | -------- | ---------------------------- |
338
+ | `url` | `string` | required | WebSocket URL |
339
+ | `protocols` | `string \| string[]` | - | Subprotocols |
340
+ | `autoConnect` | `boolean` | `true` | Auto-connect on mount |
341
+ | `autoReconnect` | `boolean` | `true` | Auto-reconnect on disconnect |
342
+ | `maxReconnectAttempts` | `number` | `5` | Max reconnection attempts |
343
+ | `reconnectDelay` | `number` | `1000` | Initial reconnect delay (ms) |
344
+ | `heartbeatInterval` | `number` | - | Heartbeat interval (ms) |
345
+
346
+ ### useSocketIO
347
+
348
+ | Option | Type | Default | Description |
349
+ | ------------- | --------- | -------- | ------------------------ |
350
+ | `url` | `string` | required | Server URL |
351
+ | `options` | `object` | - | Socket.IO client options |
352
+ | `autoConnect` | `boolean` | `true` | Auto-connect on mount |
353
+
354
+ ### useHLS
355
+
356
+ | Option | Type | Default | Description |
357
+ | ---------------- | --------- | -------- | ----------------------------- |
358
+ | `url` | `string` | required | HLS manifest URL |
359
+ | `autoPlay` | `boolean` | `true` | Auto-play on attach |
360
+ | `lowLatencyMode` | `boolean` | `false` | Enable low-latency mode |
361
+ | `startLevel` | `number` | `-1` | Initial quality (-1 for auto) |
362
+
363
+ ### useLaravelEcho
364
+
365
+ | Option | Type | Default | Description |
366
+ | ------------- | ------------------------------------- | -------- | ---------------- |
367
+ | `broadcaster` | `'pusher' \| 'socket.io' \| 'reverb'` | required | Broadcaster type |
368
+ | `key` | `string` | - | Pusher app key |
369
+ | `cluster` | `string` | - | Pusher cluster |
370
+ | `wsHost` | `string` | - | WebSocket host |
371
+ | `wsPort` | `number` | - | WebSocket port |
372
+
373
+ ### useWebRTC
374
+
375
+ | Option | Type | Default | Description |
376
+ | ------------------ | ---------------- | -------- | -------------------------- |
377
+ | `signalingUrl` | `string` | required | Signaling server URL |
378
+ | `iceServers` | `RTCIceServer[]` | STUN | ICE servers |
379
+ | `enablePointCloud` | `boolean` | `true` | Enable point cloud channel |
380
+ | `enableDetections` | `boolean` | `true` | Enable detection channel |
381
+
382
+ ### usePointCloud
383
+
384
+ | Option | Type | Default | Description |
385
+ | ------------------ | ------------------ | -------- | --------------------- |
386
+ | `format` | `PointCloudFormat` | `'auto'` | Point cloud format |
387
+ | `maxPoints` | `number` | - | Max points to decode |
388
+ | `downsampleFactor` | `number` | `1` | Downsample factor |
389
+ | `dracoPath` | `string` | - | Path to DRACO decoder |
390
+
391
+ ### useDataStream
392
+
393
+ | Option | Type | Default | Description |
394
+ | ------------- | --------- | ------- | ------------------------ |
395
+ | `bufferSize` | `number` | `1000` | Max buffer size |
396
+ | `throttleMs` | `number` | - | Throttle interval |
397
+ | `deduplicate` | `boolean` | `false` | Enable deduplication |
398
+ | `batchSize` | `number` | - | Batch size for callbacks |
399
+
400
+ ---
401
+
402
+ ## Legacy Support
403
+
404
+ The package still exports the legacy `StreamPlayer` component for backward compatibility:
405
+
406
+ `vue
407
+
408
+ <script setup>
409
+ import { StreamPlayer } from 'vue-streaming'
410
+ </script>
411
+
412
+ <template>
413
+ <StreamPlayer
414
+ type="websocket"
415
+ :config="{ url: 'wss://example.com' }"
416
+ :auto-open="true"
417
+ />
418
+ </template>
419
+ `
420
+
421
+ ---
422
+
423
+ ## License
424
+
425
+ MIT (c) [Kerolos Zakaria](https://keroloszakaria.surge.sh)