@treyorr/voca-svelte 0.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.
package/README.md ADDED
@@ -0,0 +1,66 @@
1
+ # @treyorr/voca-svelte
2
+
3
+ Svelte 5 Runes wrapper for Voca WebRTC voice chat.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @treyorr/voca-svelte
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ### Create a Room
14
+ ```typescript
15
+ import { VocaClient } from '@treyorr/voca-client';
16
+
17
+ async function createRoom() {
18
+ const client = await VocaClient.createRoom();
19
+ goto(`/room/${client.roomId}`);
20
+ }
21
+ ```
22
+
23
+ ### Join a Room
24
+ ```svelte
25
+ <script lang="ts">
26
+ import { VocaRoom } from '@treyorr/voca-svelte';
27
+
28
+ const room = new VocaRoom('my-room');
29
+
30
+ $effect(() => {
31
+ room.connect();
32
+ return () => room.disconnect();
33
+ });
34
+ </script>
35
+
36
+ <p>Status: {room.status}</p>
37
+ <p>Peers: {room.peers.size}</p>
38
+
39
+ <button onclick={() => room.toggleMute()}>
40
+ {room.isMuted ? 'Unmute' : 'Mute'}
41
+ </button>
42
+ ```
43
+
44
+ ## API
45
+
46
+ ### `new VocaRoom(roomId, config?)`
47
+
48
+ Creates a reactive room instance with Svelte 5 runes.
49
+
50
+ ### Reactive Properties
51
+
52
+ - `room.status` - Connection status
53
+ - `room.peers` - Map of connected peers
54
+ - `room.isMuted` - Mute state
55
+ - `room.localAudioLevel` - Local audio level (0-1)
56
+ - `room.localStream` - Local MediaStream
57
+
58
+ ### Methods
59
+
60
+ - `room.connect()` - Connect to room
61
+ - `room.disconnect()` - Disconnect from room
62
+ - `room.toggleMute()` - Toggle mute
63
+
64
+ ## License
65
+
66
+ MIT
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Voca WebRTC State Manager
3
+ *
4
+ * Svelte 5 runes-based wrapper around @treyorr/voca-client SDK.
5
+ */
6
+ import { VocaClient, type ConnectionStatus, type Peer, type VocaConfig } from '@treyorr/voca-client';
7
+ export { VocaClient };
8
+ export type { ConnectionStatus, Peer, VocaConfig };
9
+ export declare class VocaRoom {
10
+ peers: Map<string, Peer>;
11
+ localStream: MediaStream | null;
12
+ isMuted: boolean;
13
+ isConnected: boolean;
14
+ error: string | null;
15
+ localAudioLevel: number;
16
+ status: ConnectionStatus;
17
+ errorCode: string | null;
18
+ roomCapacity: number;
19
+ peerCount: number;
20
+ private client;
21
+ constructor(roomId: string, config?: VocaConfig);
22
+ private setupListeners;
23
+ private updatePeers;
24
+ connect(): Promise<void>;
25
+ disconnect(): void;
26
+ toggleMute(): void;
27
+ getPulseStyle(level: number): string;
28
+ getStatusLabel(): string;
29
+ }
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Voca WebRTC State Manager
3
+ *
4
+ * Svelte 5 runes-based wrapper around @treyorr/voca-client SDK.
5
+ */
6
+ import { VocaClient } from '@treyorr/voca-client';
7
+ export { VocaClient };
8
+ export class VocaRoom {
9
+ constructor(roomId, config = {}) {
10
+ // Reactive state
11
+ this.peers = $state(new Map());
12
+ this.localStream = $state(null);
13
+ this.isMuted = $state(false);
14
+ this.isConnected = $state(false);
15
+ this.error = $state(null);
16
+ this.localAudioLevel = $state(0);
17
+ this.status = $state('connecting');
18
+ this.errorCode = $state(null);
19
+ this.roomCapacity = $state(6);
20
+ this.peerCount = $state(1); // Start at 1 (self)
21
+ this.client = new VocaClient(roomId, config);
22
+ this.setupListeners();
23
+ }
24
+ setupListeners() {
25
+ this.client.on('status', (s) => {
26
+ this.status = s;
27
+ this.isConnected = s === 'connected';
28
+ });
29
+ this.client.on('error', (e) => {
30
+ this.errorCode = e.code;
31
+ this.error = e.message;
32
+ });
33
+ this.client.on('peer-joined', () => this.updatePeers());
34
+ this.client.on('peer-left', () => this.updatePeers());
35
+ this.client.on('track', () => this.updatePeers()); // Updates stream references
36
+ this.client.on('peer-audio-level', (id, level) => {
37
+ // Trigger reactivity by creating a new Map reference
38
+ // The underlying peer objects are mutation in the SDK, so we just need to let Svelte know something changed
39
+ // Optimization: In a real app we might want granular reactivity per peer, but this matches original behavior
40
+ this.peers = new Map(this.client.peers);
41
+ });
42
+ this.client.on('local-audio-level', (level) => {
43
+ this.localAudioLevel = level;
44
+ });
45
+ }
46
+ updatePeers() {
47
+ this.peers = new Map(this.client.peers);
48
+ this.peerCount = this.peers.size + 1;
49
+ }
50
+ async connect() {
51
+ try {
52
+ await this.client.connect();
53
+ this.localStream = this.client.localStream;
54
+ }
55
+ catch (err) {
56
+ // Error handling is done via events mostly, but connect() throws
57
+ console.error('Connection failed', err);
58
+ }
59
+ }
60
+ disconnect() {
61
+ this.client.disconnect();
62
+ this.peers = new Map();
63
+ this.localStream = null;
64
+ this.isConnected = false;
65
+ }
66
+ toggleMute() {
67
+ this.isMuted = this.client.toggleMute();
68
+ }
69
+ getPulseStyle(level) {
70
+ return `--pulse: ${1 + Math.round(level * 7)}px`;
71
+ }
72
+ getStatusLabel() {
73
+ const labels = {
74
+ connecting: 'CONNECTING...',
75
+ connected: 'CONNECTED',
76
+ reconnecting: 'RECONNECTING...',
77
+ full: 'ROOM FULL',
78
+ error: 'ERROR',
79
+ disconnected: 'DISCONNECTED'
80
+ };
81
+ return labels[this.status] ?? 'UNKNOWN';
82
+ }
83
+ }
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@treyorr/voca-svelte",
3
+ "version": "0.1.0",
4
+ "description": "Svelte 5 Runes wrapper for Voca Client SDK",
5
+ "svelte": "./dist/index.svelte.js",
6
+ "types": "./dist/index.svelte.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.svelte.d.ts",
10
+ "svelte": "./dist/index.svelte.js",
11
+ "default": "./dist/index.svelte.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "!dist/**/*.test.*",
17
+ "!dist/**/*.spec.*"
18
+ ],
19
+ "scripts": {
20
+ "check": "svelte-check --tsconfig ./tsconfig.json",
21
+ "build": "svelte-package -i src/lib",
22
+ "prepublishOnly": "npm run build"
23
+ },
24
+ "peerDependencies": {
25
+ "svelte": "^5.0.0"
26
+ },
27
+ "author": "Trey Orr",
28
+ "license": "MIT",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/treyorr/voca.git",
32
+ "directory": "packages/voca-svelte"
33
+ },
34
+ "homepage": "https://voca.vc",
35
+ "bugs": "https://github.com/treyorr/voca/issues",
36
+ "publishConfig": {
37
+ "access": "public"
38
+ },
39
+ "dependencies": {
40
+ "@treyorr/voca-client": "*"
41
+ },
42
+ "devDependencies": {
43
+ "@sveltejs/package": "^2.3.7",
44
+ "typescript": "^5.9.3",
45
+ "svelte": "^5.46.1",
46
+ "svelte-check": "^4.3.5"
47
+ }
48
+ }