vg-x07df 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/.azure-pipelines/publish-public.yml +37 -0
- package/.azure-pipelines/publish.yml +39 -0
- package/.changeset/README.md +8 -0
- package/.changeset/config.json +11 -0
- package/AUTO_JOIN_GUIDE.md +411 -0
- package/README.md +215 -0
- package/Screenshot 2025-09-24 at 14.34.48.png +0 -0
- package/Screenshot 2025-10-04 at 12.58.54.png +0 -0
- package/biome.json +48 -0
- package/examples/demo/.env.example +19 -0
- package/examples/demo/CHANGELOG.md +22 -0
- package/examples/demo/README.md +72 -0
- package/examples/demo/eslint.config.js +23 -0
- package/examples/demo/index.html +13 -0
- package/examples/demo/package.json +34 -0
- package/examples/demo/pnpm-lock.yaml +2098 -0
- package/examples/demo/pnpm-workspace.yaml +1 -0
- package/examples/demo/public/vite.svg +1 -0
- package/examples/demo/src/App.css +52 -0
- package/examples/demo/src/App.tsx +176 -0
- package/examples/demo/src/assets/react.svg +1 -0
- package/examples/demo/src/components/auth/LoginForm.css +144 -0
- package/examples/demo/src/components/auth/LoginForm.tsx +80 -0
- package/examples/demo/src/components/calling/AutoJoinSettings.tsx +213 -0
- package/examples/demo/src/components/calling/AutoJoinStatus.tsx +72 -0
- package/examples/demo/src/components/calling/CallInitiator.css +258 -0
- package/examples/demo/src/components/calling/CallInitiator.tsx +142 -0
- package/examples/demo/src/components/calling/CallNotifications.css +119 -0
- package/examples/demo/src/components/calling/CallNotifications.tsx +108 -0
- package/examples/demo/src/components/calling/IncomingCallModal.css +192 -0
- package/examples/demo/src/components/calling/IncomingCallModal.tsx +78 -0
- package/examples/demo/src/components/calling/MinimizedCall.css +156 -0
- package/examples/demo/src/components/calling/MinimizedCall.tsx +78 -0
- package/examples/demo/src/components/conference/ConferenceHeader.css +265 -0
- package/examples/demo/src/components/conference/ConferenceHeader.tsx +78 -0
- package/examples/demo/src/components/conference/EnhancedControlBar.css +356 -0
- package/examples/demo/src/components/conference/EnhancedControlBar.tsx +262 -0
- package/examples/demo/src/components/conference/PaginationControls.css +67 -0
- package/examples/demo/src/components/conference/PaginationControls.tsx +64 -0
- package/examples/demo/src/components/conference/ParticipantGrid.css +153 -0
- package/examples/demo/src/components/conference/ParticipantGrid.tsx +87 -0
- package/examples/demo/src/components/conference/ParticipantTile.css +210 -0
- package/examples/demo/src/components/conference/ParticipantTile.tsx +114 -0
- package/examples/demo/src/components/conference/VideoConference.css +214 -0
- package/examples/demo/src/components/conference/VideoConference.tsx +93 -0
- package/examples/demo/src/contexts/AuthContext.tsx +105 -0
- package/examples/demo/src/hooks/useAuth.ts +5 -0
- package/examples/demo/src/hooks/useCallTimer.ts +42 -0
- package/examples/demo/src/index.css +68 -0
- package/examples/demo/src/main.tsx +10 -0
- package/examples/demo/src/services/auth.service.ts +153 -0
- package/examples/demo/src/types/auth.types.ts +31 -0
- package/examples/demo/tsconfig.app.json +28 -0
- package/examples/demo/tsconfig.json +7 -0
- package/examples/demo/tsconfig.node.json +26 -0
- package/examples/demo/vite.config.ts +15 -0
- package/images/callpad-without-ai.png +0 -0
- package/package.json +28 -0
- package/packages/sdk/CHANGELOG.md +33 -0
- package/packages/sdk/LICENSE +21 -0
- package/packages/sdk/README.md +97 -0
- package/packages/sdk/documentation.md +1132 -0
- package/packages/sdk/openapi-ts.config.ts +7 -0
- package/packages/sdk/package.json +88 -0
- package/packages/sdk/src/core/auth.manager.ts +52 -0
- package/packages/sdk/src/core/events/event-bus.ts +301 -0
- package/packages/sdk/src/core/events/index.ts +8 -0
- package/packages/sdk/src/core/events/types.ts +165 -0
- package/packages/sdk/src/core/index.ts +3 -0
- package/packages/sdk/src/core/signal/api.config.ts +49 -0
- package/packages/sdk/src/core/signal/index.ts +16 -0
- package/packages/sdk/src/core/signal/signal.client.ts +101 -0
- package/packages/sdk/src/core/signal/types.ts +110 -0
- package/packages/sdk/src/core/socketio/handlers/base.handler.ts +212 -0
- package/packages/sdk/src/core/socketio/handlers/call-accepted.handler.ts +34 -0
- package/packages/sdk/src/core/socketio/handlers/call-canceled.handler.ts +34 -0
- package/packages/sdk/src/core/socketio/handlers/call-declined.handler.ts +29 -0
- package/packages/sdk/src/core/socketio/handlers/call-ended.handler.ts +40 -0
- package/packages/sdk/src/core/socketio/handlers/call-incoming.handler.ts +72 -0
- package/packages/sdk/src/core/socketio/handlers/call-join-info.handler.ts +181 -0
- package/packages/sdk/src/core/socketio/handlers/call-participant-joined.handler.ts +42 -0
- package/packages/sdk/src/core/socketio/handlers/call-participant-joining.handler.ts +42 -0
- package/packages/sdk/src/core/socketio/handlers/call-timeout.handler.ts +31 -0
- package/packages/sdk/src/core/socketio/handlers/handler.registry.ts +62 -0
- package/packages/sdk/src/core/socketio/handlers/index.ts +21 -0
- package/packages/sdk/src/core/socketio/handlers/participant-left.handler.ts +37 -0
- package/packages/sdk/src/core/socketio/handlers/schema.ts +130 -0
- package/packages/sdk/src/core/socketio/index.ts +5 -0
- package/packages/sdk/src/core/socketio/socket.manager.ts +187 -0
- package/packages/sdk/src/core/socketio/types.ts +14 -0
- package/packages/sdk/src/core/types.ts +23 -0
- package/packages/sdk/src/generated/api/core/ApiError.ts +21 -0
- package/packages/sdk/src/generated/api/core/ApiRequestOptions.ts +13 -0
- package/packages/sdk/src/generated/api/core/ApiResult.ts +7 -0
- package/packages/sdk/src/generated/api/core/CancelablePromise.ts +126 -0
- package/packages/sdk/src/generated/api/core/OpenAPI.ts +55 -0
- package/packages/sdk/src/generated/api/core/request.ts +339 -0
- package/packages/sdk/src/generated/api/index.ts +5 -0
- package/packages/sdk/src/generated/api/models.ts +219 -0
- package/packages/sdk/src/generated/api/services.ts +225 -0
- package/packages/sdk/src/hooks/index.ts +21 -0
- package/packages/sdk/src/hooks/useAutoJoin.ts +66 -0
- package/packages/sdk/src/hooks/useCallActions.ts +28 -0
- package/packages/sdk/src/hooks/useCallQuality.ts +416 -0
- package/packages/sdk/src/hooks/useCallState.ts +23 -0
- package/packages/sdk/src/hooks/useConnection.ts +15 -0
- package/packages/sdk/src/hooks/useDevices.ts +296 -0
- package/packages/sdk/src/hooks/useErrorRecovery.ts +299 -0
- package/packages/sdk/src/hooks/useErrors.ts +84 -0
- package/packages/sdk/src/hooks/useEvent.ts +188 -0
- package/packages/sdk/src/hooks/useMediaControls.ts +215 -0
- package/packages/sdk/src/hooks/useParticipantStatus.ts +318 -0
- package/packages/sdk/src/hooks/useParticipants.ts +111 -0
- package/packages/sdk/src/index.ts +66 -0
- package/packages/sdk/src/livekit/constants.ts +76 -0
- package/packages/sdk/src/livekit/device.manager.ts +172 -0
- package/packages/sdk/src/livekit/error-classifier.ts +155 -0
- package/packages/sdk/src/livekit/events/eventBridge.ts +371 -0
- package/packages/sdk/src/livekit/events/trackRegistry.ts +114 -0
- package/packages/sdk/src/livekit/index.ts +49 -0
- package/packages/sdk/src/livekit/livekit.service.ts +110 -0
- package/packages/sdk/src/livekit/media.controls.ts +315 -0
- package/packages/sdk/src/livekit/room.manager.ts +79 -0
- package/packages/sdk/src/livekit/track.utils.ts +230 -0
- package/packages/sdk/src/livekit/types.ts +135 -0
- package/packages/sdk/src/provider/RtcProvider.tsx +78 -0
- package/packages/sdk/src/services/call-actions.ts +260 -0
- package/packages/sdk/src/services/error-recovery.ts +461 -0
- package/packages/sdk/src/services/index.ts +2 -0
- package/packages/sdk/src/services/sdk-builder.ts +104 -0
- package/packages/sdk/src/state/errors.ts +163 -0
- package/packages/sdk/src/state/selectors.ts +28 -0
- package/packages/sdk/src/state/store.ts +36 -0
- package/packages/sdk/src/state/types.ts +151 -0
- package/packages/sdk/src/utils/logger.ts +183 -0
- package/packages/sdk/tsconfig.json +49 -0
- package/packages/sdk/tsup.config.ts +51 -0
- package/pnpm-workspace.yaml +4 -0
- package/tsconfig.base.json +19 -0
- package/turbo.json +34 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
trigger:
|
|
2
|
+
branches:
|
|
3
|
+
include:
|
|
4
|
+
- main
|
|
5
|
+
|
|
6
|
+
pool:
|
|
7
|
+
vmImage: 'ubuntu-latest'
|
|
8
|
+
|
|
9
|
+
steps:
|
|
10
|
+
- task: Checkout@1
|
|
11
|
+
|
|
12
|
+
- task: NodeTool@0
|
|
13
|
+
inputs:
|
|
14
|
+
versionSpec: '20.x'
|
|
15
|
+
|
|
16
|
+
- script: npm install -g pnpm
|
|
17
|
+
displayName: 'Install pnpm'
|
|
18
|
+
|
|
19
|
+
- script: pnpm install
|
|
20
|
+
displayName: 'Install dependencies'
|
|
21
|
+
|
|
22
|
+
- script: |
|
|
23
|
+
pnpm build
|
|
24
|
+
displayName: "Build packages"
|
|
25
|
+
|
|
26
|
+
- script: |
|
|
27
|
+
pnpm changeset version
|
|
28
|
+
displayName: "Apply version bump"
|
|
29
|
+
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
|
|
30
|
+
|
|
31
|
+
- script: |
|
|
32
|
+
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
|
|
33
|
+
pnpm changeset publish
|
|
34
|
+
displayName: "Publish to npm"
|
|
35
|
+
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
|
|
36
|
+
env:
|
|
37
|
+
NPM_TOKEN: $(NPM_TOKEN) # <-- set this in Azure Pipelines secrets
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
trigger:
|
|
2
|
+
branches:
|
|
3
|
+
include:
|
|
4
|
+
- nil
|
|
5
|
+
|
|
6
|
+
pool:
|
|
7
|
+
vmImage: 'ubuntu-latest'
|
|
8
|
+
|
|
9
|
+
variables:
|
|
10
|
+
- name: NPM_TOKEN
|
|
11
|
+
value: $(npm-token) # Set this variable in Azure DevOps pipeline variables
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- task: NodeTool@0
|
|
15
|
+
inputs:
|
|
16
|
+
versionSpec: '18.x'
|
|
17
|
+
displayName: 'Install Node.js'
|
|
18
|
+
|
|
19
|
+
- script: npm install -g pnpm
|
|
20
|
+
displayName: 'Install pnpm'
|
|
21
|
+
|
|
22
|
+
- script: pnpm install
|
|
23
|
+
displayName: 'Install dependencies'
|
|
24
|
+
|
|
25
|
+
- script: pnpm run build
|
|
26
|
+
displayName: 'Build all packages'
|
|
27
|
+
|
|
28
|
+
- script: pnpm run check-types
|
|
29
|
+
displayName: 'Type check all packages'
|
|
30
|
+
|
|
31
|
+
- script: cp .npmrc.ci .npmrc
|
|
32
|
+
displayName: 'Setup npm authentication'
|
|
33
|
+
env:
|
|
34
|
+
NPM_TOKEN: $(NPM_TOKEN)
|
|
35
|
+
|
|
36
|
+
- script: pnpm publish-packages
|
|
37
|
+
displayName: 'Publish SDK to npm'
|
|
38
|
+
env:
|
|
39
|
+
NPM_TOKEN: $(NPM_TOKEN)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Changesets
|
|
2
|
+
|
|
3
|
+
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
|
|
4
|
+
with multi-package repos, or single-package repos to help you version and publish your code. You can
|
|
5
|
+
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
|
|
6
|
+
|
|
7
|
+
We have a quick list of common questions to get you started engaging with this project in
|
|
8
|
+
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json",
|
|
3
|
+
"changelog": "@changesets/cli/changelog",
|
|
4
|
+
"commit": true,
|
|
5
|
+
"fixed": [],
|
|
6
|
+
"linked": [],
|
|
7
|
+
"access": "public",
|
|
8
|
+
"baseBranch": "main",
|
|
9
|
+
"updateInternalDependencies": "patch",
|
|
10
|
+
"ignore": []
|
|
11
|
+
}
|
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
# Auto-Join Configuration Guide
|
|
2
|
+
|
|
3
|
+
The CallPad SDK now supports intelligent auto-join functionality that provides seamless call experiences while maintaining user control and robust error handling.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Auto-join automatically connects users to LiveKit media sessions based on configurable triggers, following industry best practices from platforms like Zoom, Teams, and Google Meet.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
### ✅ **Smart Triggers**
|
|
12
|
+
|
|
13
|
+
- **Caller**: Auto-join when first participant accepts
|
|
14
|
+
- **Callee**: Auto-join immediately after accepting call
|
|
15
|
+
- **Manual**: Complete user control for all scenarios
|
|
16
|
+
|
|
17
|
+
### ✅ **Robust Error Handling**
|
|
18
|
+
|
|
19
|
+
- **Exponential backoff retry**: 1s → 2s → 4s delays
|
|
20
|
+
- **Graceful fallback**: Failed auto-join → manual join button
|
|
21
|
+
- **Error categorization**: Network vs authentication failures
|
|
22
|
+
|
|
23
|
+
### ✅ **Real-time State Tracking**
|
|
24
|
+
|
|
25
|
+
- Live auto-join status: `idle`, `pending`, `retrying`, `succeeded`, `failed`
|
|
26
|
+
- Progress visibility: Current attempt count and error messages
|
|
27
|
+
- Performance metrics: Start/completion timestamps
|
|
28
|
+
|
|
29
|
+
### ✅ **Developer Experience**
|
|
30
|
+
|
|
31
|
+
- **Type-safe configuration**: Full TypeScript support
|
|
32
|
+
- **React hooks**: `useAutoJoin()`, `useAutoJoinForCurrentUser()`
|
|
33
|
+
- **Rich logging**: Detailed debug information
|
|
34
|
+
|
|
35
|
+
## Configuration
|
|
36
|
+
|
|
37
|
+
### Basic Setup
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
import { buildSdk } from 'vg-x07df'
|
|
41
|
+
|
|
42
|
+
const sdk = buildSdk({
|
|
43
|
+
appId: 'your-app',
|
|
44
|
+
signalHost: 'wss://your-host',
|
|
45
|
+
authProvider: () => getToken(),
|
|
46
|
+
|
|
47
|
+
// Auto-join configuration
|
|
48
|
+
autoJoin: {
|
|
49
|
+
caller: {
|
|
50
|
+
enabled: true,
|
|
51
|
+
trigger: 'first-accept' // Auto-join when first participant accepts
|
|
52
|
+
},
|
|
53
|
+
callee: {
|
|
54
|
+
enabled: true,
|
|
55
|
+
trigger: 'immediate' // Auto-join immediately after accepting
|
|
56
|
+
},
|
|
57
|
+
fallback: {
|
|
58
|
+
onFailure: 'retry', // Retry on failure vs 'manual' fallback
|
|
59
|
+
retryAttempts: 3 // Max retry attempts
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Configuration Options
|
|
66
|
+
|
|
67
|
+
#### Caller Settings
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
caller: {
|
|
71
|
+
enabled: boolean // Enable/disable auto-join for callers
|
|
72
|
+
trigger: 'first-accept' // Join when first participant accepts
|
|
73
|
+
| 'manual' // Always require manual join
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
#### Callee Settings
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
callee: {
|
|
81
|
+
enabled: boolean // Enable/disable auto-join for callees
|
|
82
|
+
trigger: 'immediate' // Join immediately after accepting call
|
|
83
|
+
| 'manual' // Always require manual join
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
#### Fallback Behavior
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
fallback: {
|
|
91
|
+
onFailure: 'retry' // Retry with exponential backoff
|
|
92
|
+
| 'manual' // Show manual join button immediately
|
|
93
|
+
retryAttempts: number // Max retry attempts (1-5)
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Usage in Components
|
|
98
|
+
|
|
99
|
+
### Access Configuration
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
import { useAutoJoin, useAutoJoinForCurrentUser } from 'vg-x07df'
|
|
103
|
+
|
|
104
|
+
function CallSettings() {
|
|
105
|
+
const autoJoin = useAutoJoin()
|
|
106
|
+
const userAutoJoin = useAutoJoinForCurrentUser()
|
|
107
|
+
|
|
108
|
+
return (
|
|
109
|
+
<div>
|
|
110
|
+
<p>Caller auto-join: {autoJoin.isCallerAutoJoinEnabled ? 'ON' : 'OFF'}</p>
|
|
111
|
+
<p>Your role: {userAutoJoin.shouldAutoJoin ? 'Auto-join enabled' : 'Manual join'}</p>
|
|
112
|
+
<p>Trigger: {userAutoJoin.trigger}</p>
|
|
113
|
+
</div>
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Monitor Auto-Join Status
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
import { useSdk } from 'vg-x07df'
|
|
122
|
+
|
|
123
|
+
function AutoJoinStatus() {
|
|
124
|
+
const sdk = useSdk()
|
|
125
|
+
const autoJoinState = sdk.store(state => state.autoJoin)
|
|
126
|
+
|
|
127
|
+
switch (autoJoinState.status) {
|
|
128
|
+
case 'pending':
|
|
129
|
+
return <div>🔄 Joining automatically...</div>
|
|
130
|
+
case 'retrying':
|
|
131
|
+
return <div>⏳ Retrying... ({autoJoinState.attempt}/{autoJoinState.maxAttempts})</div>
|
|
132
|
+
case 'failed':
|
|
133
|
+
return (
|
|
134
|
+
<div>
|
|
135
|
+
⚠️ Auto-join failed
|
|
136
|
+
<button onClick={() => sdk.join()}>Join Manually</button>
|
|
137
|
+
</div>
|
|
138
|
+
)
|
|
139
|
+
case 'succeeded':
|
|
140
|
+
return <div>✅ Connected!</div>
|
|
141
|
+
default:
|
|
142
|
+
return null
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Manual Join Fallback
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
function CallInterface() {
|
|
151
|
+
const { status } = useCallState()
|
|
152
|
+
const sdk = useSdk()
|
|
153
|
+
const userAutoJoin = useAutoJoinForCurrentUser()
|
|
154
|
+
|
|
155
|
+
const showManualJoinButton = status === 'READY_TO_JOIN' && !userAutoJoin.shouldAutoJoin
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
<div>
|
|
159
|
+
{showManualJoinButton && (
|
|
160
|
+
<button
|
|
161
|
+
onClick={() => sdk.join()}
|
|
162
|
+
className="join-button"
|
|
163
|
+
>
|
|
164
|
+
Join Call
|
|
165
|
+
</button>
|
|
166
|
+
)}
|
|
167
|
+
</div>
|
|
168
|
+
)
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Session States
|
|
173
|
+
|
|
174
|
+
The SDK introduces new session states to handle the auto-join flow:
|
|
175
|
+
|
|
176
|
+
| State | Description | User Action |
|
|
177
|
+
|-------|-------------|-------------|
|
|
178
|
+
| `IDLE` | No active call | - |
|
|
179
|
+
| `CALLING` | Caller initiated call, waiting | - |
|
|
180
|
+
| `RINGING` | Incoming call notification | Accept/Decline |
|
|
181
|
+
| `ACCEPTED` | Call accepted, getting join info | - |
|
|
182
|
+
| `READY_TO_JOIN` | Has join credentials, ready to connect | Auto-join or Manual |
|
|
183
|
+
| `CONNECTING` | Joining LiveKit room | - |
|
|
184
|
+
| `ACTIVE` | Connected to media session | Media controls |
|
|
185
|
+
| `ENDED` | Call completed | - |
|
|
186
|
+
|
|
187
|
+
## Industry Patterns
|
|
188
|
+
|
|
189
|
+
### Zoom/Teams Pattern (Default)
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
autoJoin: {
|
|
193
|
+
caller: { enabled: true, trigger: 'first-accept' },
|
|
194
|
+
callee: { enabled: true, trigger: 'immediate' },
|
|
195
|
+
fallback: { onFailure: 'manual', retryAttempts: 2 }
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Conservative Pattern
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
autoJoin: {
|
|
203
|
+
caller: { enabled: false, trigger: 'manual' },
|
|
204
|
+
callee: { enabled: false, trigger: 'manual' },
|
|
205
|
+
fallback: { onFailure: 'manual', retryAttempts: 1 }
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Aggressive Retry Pattern
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
autoJoin: {
|
|
213
|
+
caller: { enabled: true, trigger: 'first-accept' },
|
|
214
|
+
callee: { enabled: true, trigger: 'immediate' },
|
|
215
|
+
fallback: { onFailure: 'retry', retryAttempts: 5 }
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Events
|
|
220
|
+
|
|
221
|
+
The SDK emits auto-join related events:
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
// Listen for auto-join events
|
|
225
|
+
sdk.on('join-info:received', (event) => {
|
|
226
|
+
console.log('Join info received:', event.autoJoined)
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
sdk.on('participant:joined', (event) => {
|
|
230
|
+
console.log('Participant joined:', event.participant.role)
|
|
231
|
+
})
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## Error Handling
|
|
235
|
+
|
|
236
|
+
### Retry Logic
|
|
237
|
+
- **Exponential backoff**: 1s, 2s, 4s, 8s...
|
|
238
|
+
- **Network error detection**: Automatic retry for transient failures
|
|
239
|
+
- **Auth error handling**: Immediate fallback to manual join
|
|
240
|
+
|
|
241
|
+
### Error Recovery
|
|
242
|
+
```typescript
|
|
243
|
+
// Handle auto-join failures
|
|
244
|
+
sdk.store.subscribe(state => {
|
|
245
|
+
if (state.autoJoin.status === 'failed') {
|
|
246
|
+
// Show user-friendly error message
|
|
247
|
+
// Provide manual join option
|
|
248
|
+
showNotification('Connection failed. Please join manually.')
|
|
249
|
+
}
|
|
250
|
+
})
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Performance Considerations
|
|
254
|
+
|
|
255
|
+
### Resource Optimization
|
|
256
|
+
- **Lazy room creation**: Rooms only created when participants join
|
|
257
|
+
- **Efficient state updates**: Minimal re-renders during auto-join
|
|
258
|
+
- **Memory management**: Automatic cleanup on call end
|
|
259
|
+
|
|
260
|
+
### Network Resilience
|
|
261
|
+
- **Connection quality monitoring**: Adjust retry behavior based on network
|
|
262
|
+
- **Bandwidth detection**: Optimize media settings for auto-join
|
|
263
|
+
- **Fallback servers**: Multiple LiveKit server support
|
|
264
|
+
|
|
265
|
+
## Best Practices
|
|
266
|
+
|
|
267
|
+
### 1. **User Communication**
|
|
268
|
+
```typescript
|
|
269
|
+
// Always inform users about auto-join status
|
|
270
|
+
const AutoJoinFeedback = () => {
|
|
271
|
+
const autoJoinState = useSdk().store(state => state.autoJoin)
|
|
272
|
+
|
|
273
|
+
return (
|
|
274
|
+
<div className="auto-join-status">
|
|
275
|
+
{autoJoinState.status === 'pending' && '⏳ Connecting automatically...'}
|
|
276
|
+
{autoJoinState.status === 'retrying' && '🔄 Connection retry in progress...'}
|
|
277
|
+
{autoJoinState.status === 'failed' && '⚠️ Please join manually'}
|
|
278
|
+
</div>
|
|
279
|
+
)
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### 2. **Graceful Degradation**
|
|
284
|
+
```typescript
|
|
285
|
+
// Always provide manual fallback
|
|
286
|
+
const CallControls = () => {
|
|
287
|
+
const { status } = useCallState()
|
|
288
|
+
const sdk = useSdk()
|
|
289
|
+
|
|
290
|
+
return (
|
|
291
|
+
<div>
|
|
292
|
+
{status === 'READY_TO_JOIN' && (
|
|
293
|
+
<button onClick={() => sdk.join()}>
|
|
294
|
+
Join Call
|
|
295
|
+
</button>
|
|
296
|
+
)}
|
|
297
|
+
</div>
|
|
298
|
+
)
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### 3. **Configuration Validation**
|
|
303
|
+
```typescript
|
|
304
|
+
// Validate configuration at runtime
|
|
305
|
+
const validateAutoJoinConfig = (config: AutoJoinConfig) => {
|
|
306
|
+
if (config.fallback.retryAttempts > 5) {
|
|
307
|
+
console.warn('High retry attempts may impact user experience')
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
if (!config.caller.enabled && !config.callee.enabled) {
|
|
311
|
+
console.warn('All auto-join disabled - consider enabling for better UX')
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
## Migration Guide
|
|
317
|
+
|
|
318
|
+
### From Manual Join Only
|
|
319
|
+
```typescript
|
|
320
|
+
// Before
|
|
321
|
+
const sdk = buildSdk({
|
|
322
|
+
/* basic config */
|
|
323
|
+
})
|
|
324
|
+
|
|
325
|
+
// After
|
|
326
|
+
const sdk = buildSdk({
|
|
327
|
+
/* basic config */,
|
|
328
|
+
autoJoin: {
|
|
329
|
+
caller: { enabled: true, trigger: 'first-accept' },
|
|
330
|
+
callee: { enabled: true, trigger: 'immediate' },
|
|
331
|
+
fallback: { onFailure: 'manual', retryAttempts: 2 }
|
|
332
|
+
}
|
|
333
|
+
})
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### Update Components
|
|
337
|
+
```typescript
|
|
338
|
+
// Before
|
|
339
|
+
const CallInterface = () => {
|
|
340
|
+
const { status } = useCallState()
|
|
341
|
+
|
|
342
|
+
return (
|
|
343
|
+
<div>
|
|
344
|
+
{status === 'ACCEPTED' && <JoinButton />}
|
|
345
|
+
</div>
|
|
346
|
+
)
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// After
|
|
350
|
+
const CallInterface = () => {
|
|
351
|
+
const { status } = useCallState()
|
|
352
|
+
const userAutoJoin = useAutoJoinForCurrentUser()
|
|
353
|
+
|
|
354
|
+
return (
|
|
355
|
+
<div>
|
|
356
|
+
{status === 'READY_TO_JOIN' && !userAutoJoin.shouldAutoJoin && <JoinButton />}
|
|
357
|
+
<AutoJoinStatus />
|
|
358
|
+
</div>
|
|
359
|
+
)
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
## Demo Application
|
|
364
|
+
|
|
365
|
+
The demo app at `examples/demo` showcases all auto-join features:
|
|
366
|
+
|
|
367
|
+
1. **Settings Panel**: Configure auto-join behavior
|
|
368
|
+
2. **Status Indicators**: Real-time auto-join progress
|
|
369
|
+
3. **Manual Fallbacks**: Join buttons when auto-join fails
|
|
370
|
+
4. **Error Handling**: User-friendly error messages
|
|
371
|
+
|
|
372
|
+
Run the demo:
|
|
373
|
+
```bash
|
|
374
|
+
cd examples/demo
|
|
375
|
+
pnpm dev --port 3002
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Visit: http://localhost:3002
|
|
379
|
+
|
|
380
|
+
## Troubleshooting
|
|
381
|
+
|
|
382
|
+
### Common Issues
|
|
383
|
+
|
|
384
|
+
**Auto-join not working**
|
|
385
|
+
- Check `autoJoin.enabled` configuration
|
|
386
|
+
- Verify LiveKit credentials are valid
|
|
387
|
+
- Ensure network connectivity
|
|
388
|
+
|
|
389
|
+
**Frequent retries**
|
|
390
|
+
- Check LiveKit server status
|
|
391
|
+
- Verify token expiration
|
|
392
|
+
- Consider reducing `retryAttempts`
|
|
393
|
+
|
|
394
|
+
**UI not updating**
|
|
395
|
+
- Ensure components use `useSdk().store` hook
|
|
396
|
+
- Check React re-render optimization
|
|
397
|
+
- Verify state subscription setup
|
|
398
|
+
|
|
399
|
+
### Debug Logging
|
|
400
|
+
|
|
401
|
+
Enable debug logging for detailed auto-join information:
|
|
402
|
+
|
|
403
|
+
```typescript
|
|
404
|
+
const sdk = buildSdk({
|
|
405
|
+
// ... other config
|
|
406
|
+
logLevel: 'debug',
|
|
407
|
+
enableDebug: true
|
|
408
|
+
})
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
Look for log messages prefixed with `[callpad:socketio:call-join-info]` and `[callpad:socketio:call-accepted]`.
|