@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 +66 -0
- package/dist/index.svelte.d.ts +29 -0
- package/dist/index.svelte.js +83 -0
- package/package.json +48 -0
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
|
+
}
|