@orbitconnect/react 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.
Files changed (103) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/LICENSE +21 -0
  3. package/README.md +374 -0
  4. package/dist/OrbitContext.d.ts +87 -0
  5. package/dist/OrbitProvider.d.ts +24 -0
  6. package/dist/api/client.d.ts +44 -0
  7. package/dist/api/index.d.ts +2 -0
  8. package/dist/bg.svg +1 -0
  9. package/dist/call/CallContext.d.ts +27 -0
  10. package/dist/call/CallProvider.d.ts +4 -0
  11. package/dist/components/call/CallControls.d.ts +18 -0
  12. package/dist/components/call/CallHistory.d.ts +22 -0
  13. package/dist/components/call/CallScreen.d.ts +11 -0
  14. package/dist/components/call/InCallChatPanel.d.ts +7 -0
  15. package/dist/components/call/IncomingCallModal.d.ts +8 -0
  16. package/dist/components/call/OutgoingCallScreen.d.ts +8 -0
  17. package/dist/components/call/VideoCallScreen.d.ts +23 -0
  18. package/dist/components/call/index.d.ts +11 -0
  19. package/dist/components/chat/AttachmentPicker.d.ts +23 -0
  20. package/dist/components/chat/AttachmentRenderer.d.ts +15 -0
  21. package/dist/components/chat/AudioRecorder.d.ts +6 -0
  22. package/dist/components/chat/BatchToolbar.d.ts +8 -0
  23. package/dist/components/chat/CallBanner.d.ts +14 -0
  24. package/dist/components/chat/ChatBox.d.ts +90 -0
  25. package/dist/components/chat/Composer.d.ts +15 -0
  26. package/dist/components/chat/ConversationList.d.ts +32 -0
  27. package/dist/components/chat/ConversationPicker.d.ts +7 -0
  28. package/dist/components/chat/ConversationProfile.d.ts +13 -0
  29. package/dist/components/chat/DocumentViewer.d.ts +2 -0
  30. package/dist/components/chat/EmojiPicker.d.ts +5 -0
  31. package/dist/components/chat/ImageViewer.d.ts +2 -0
  32. package/dist/components/chat/LinkPreview.d.ts +7 -0
  33. package/dist/components/chat/MediaMessage.d.ts +5 -0
  34. package/dist/components/chat/MediaViewer.d.ts +13 -0
  35. package/dist/components/chat/MessageActionMenu.d.ts +16 -0
  36. package/dist/components/chat/MessageBubble.d.ts +61 -0
  37. package/dist/components/chat/MessageInfoSheet.d.ts +7 -0
  38. package/dist/components/chat/MessageInput.d.ts +12 -0
  39. package/dist/components/chat/MessageList.d.ts +7 -0
  40. package/dist/components/chat/QuickMessages.d.ts +17 -0
  41. package/dist/components/chat/ReactionDialog.d.ts +6 -0
  42. package/dist/components/chat/ReplyComposer.d.ts +8 -0
  43. package/dist/components/chat/StickerPicker.d.ts +21 -0
  44. package/dist/components/chat/VideoViewer.d.ts +2 -0
  45. package/dist/components/chat/emojiData.d.ts +9 -0
  46. package/dist/components/chat/index.d.ts +44 -0
  47. package/dist/components/chat/mediaViewerRegistry.d.ts +22 -0
  48. package/dist/components/chat/urlUtils.d.ts +1 -0
  49. package/dist/components/index.d.ts +4 -0
  50. package/dist/components/meeting/MeetingControls.d.ts +15 -0
  51. package/dist/components/meeting/MeetingRoom.d.ts +27 -0
  52. package/dist/components/meeting/ParticipantGrid.d.ts +6 -0
  53. package/dist/components/meeting/ParticipantsPanel.d.ts +8 -0
  54. package/dist/components/meeting/ReactionBurst.d.ts +9 -0
  55. package/dist/components/meeting/ScreenShareView.d.ts +5 -0
  56. package/dist/components/meeting/WaitingRoom.d.ts +7 -0
  57. package/dist/components/meeting/index.d.ts +8 -0
  58. package/dist/components/ui/Avatar.d.ts +13 -0
  59. package/dist/components/ui/BottomNav.d.ts +8 -0
  60. package/dist/components/ui/EscalationButton.d.ts +12 -0
  61. package/dist/components/ui/IconBtn.d.ts +8 -0
  62. package/dist/components/ui/PoweredBy.d.ts +1 -0
  63. package/dist/components/ui/index.d.ts +5 -0
  64. package/dist/favicon.svg +1 -0
  65. package/dist/hooks/index.d.ts +20 -0
  66. package/dist/hooks/useAppBrand.d.ts +6 -0
  67. package/dist/hooks/useCall.d.ts +2 -0
  68. package/dist/hooks/useCallHistory.d.ts +5 -0
  69. package/dist/hooks/useConversations.d.ts +7 -0
  70. package/dist/hooks/useMedia.d.ts +19 -0
  71. package/dist/hooks/useMeeting.d.ts +22 -0
  72. package/dist/hooks/useMeetingWebRTC.d.ts +28 -0
  73. package/dist/hooks/useMessages.d.ts +11 -0
  74. package/dist/hooks/useNotifications.d.ts +19 -0
  75. package/dist/hooks/usePresence.d.ts +8 -0
  76. package/dist/hooks/usePushToken.d.ts +11 -0
  77. package/dist/hooks/useRealtime.d.ts +21 -0
  78. package/dist/hooks/useRecording.d.ts +16 -0
  79. package/dist/hooks/useSound.d.ts +9 -0
  80. package/dist/hooks/useWebRTC.d.ts +12 -0
  81. package/dist/icons.svg +24 -0
  82. package/dist/index.css +1 -0
  83. package/dist/index.d.ts +16 -0
  84. package/dist/index.js +12441 -0
  85. package/dist/meeting/MeetingContext.d.ts +19 -0
  86. package/dist/meeting/MeetingProvider.d.ts +4 -0
  87. package/dist/meeting/index.d.ts +3 -0
  88. package/dist/socket/OrbitListenerProvider.d.ts +14 -0
  89. package/dist/socket/OrbitSocket.d.ts +97 -0
  90. package/dist/socket/config.d.ts +10 -0
  91. package/dist/socket/context.d.ts +10 -0
  92. package/dist/socket/events.d.ts +283 -0
  93. package/dist/socket/index.d.ts +8 -0
  94. package/dist/socket/useOrbitEvent.d.ts +8 -0
  95. package/dist/theme/ThemeProvider.d.ts +17 -0
  96. package/dist/theme/defaults.d.ts +3 -0
  97. package/dist/theme/index.d.ts +3 -0
  98. package/dist/theme/types.d.ts +85 -0
  99. package/dist/widgets/Chat.d.ts +13 -0
  100. package/dist/widgets/MeetingWidget.d.ts +6 -0
  101. package/dist/widgets/VideoCall.d.ts +1 -0
  102. package/dist/widgets/index.d.ts +6 -0
  103. package/package.json +79 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,56 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@orbitconnect/react` will be documented here.
4
+
5
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ---
8
+
9
+ ## [0.1.0] — 2025-04-27
10
+
11
+ Initial public release.
12
+
13
+ ### Added
14
+
15
+ **Core**
16
+ - `OrbitProvider` — root context provider with WebSocket lifecycle, token refresh (`onTokenExpired`), and theming
17
+ - `useOrbit` — access `apiClient`, `appUserId`, `clientId`, `baseUrl`, `appConfig` from any child
18
+ - `useAppConfig` — resolved feature flags and icon overrides from `AppConfig`
19
+
20
+ **Widgets**
21
+ - `Chat` — full-featured chat UI: conversation list, message bubbles, composer, reactions, reply/quote, file/image/video/audio attachments, voice recording, emoji & sticker picker, message search, pin, batch select/delete/forward, presence, call history
22
+ - `VideoCall` — floating WebRTC call overlay, renders automatically when a call is active
23
+ - `MeetingWidget` — full video-conferencing room with participant grid, screen share, reactions, and hand-raise
24
+
25
+ **Hooks**
26
+ - `useMessages` — real-time messages with typing indicators, pinned messages, read receipts, reactions, recall, edit
27
+ - `useConversations` — conversation list with live presence, typing, and delivery status
28
+ - `useCall` — full call lifecycle: initiate, accept, reject, end, mute, camera toggle
29
+ - `useMeeting` — meeting lifecycle: join, leave, mute, screen share, raise hand, reactions
30
+ - `useMedia` — file upload with `upload()` and `getUrl()`
31
+ - `useNotifications` — in-app notification feed with unread count, mark read, mark all read, clear
32
+ - `usePresence` — real-time presence status per user (`online` / `away` / `offline`)
33
+ - `useCallHistory` — call records with caller/callee info
34
+ - `useRealtime` — session lifecycle with transitions (chat → call → meeting) and custom event emission
35
+ - `useOrbitEvent` — subscribe to any raw WebSocket event
36
+ - `useOrbitListener` — access the raw socket and connection status
37
+
38
+ **Meeting context**
39
+ - `MeetingProvider`, `MeetingContext`, `useMeetingContext` — standalone meeting context for custom meeting UIs
40
+
41
+ **Theme**
42
+ - `ThemeProvider`, `useTheme`, `darkTheme`, `lightTheme`
43
+ - Full CSS variable token set: backgrounds, foregrounds, bubbles, composer, borders, radii, fonts
44
+ - `PartialTheme` type for partial overrides via `OrbitProvider`
45
+
46
+ **Stylesheet**
47
+ - `dist/index.css` — pre-built Tailwind CSS stylesheet, import once via `import '@orbitconnect/react/index.css'`
48
+
49
+ **Build**
50
+ - Vite library build (ESM only) with React Compiler (babel-plugin-react-compiler)
51
+ - TypeScript declarations emitted to `dist/` via `tsc -p tsconfig.build.json`
52
+ - Tailwind CSS minified and bundled to `dist/index.css`
53
+
54
+ ---
55
+
56
+ [0.1.0]: https://github.com/core-dynamics/orbitconnect-sdk/releases/tag/react-v0.1.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 OrbitConnect
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,374 @@
1
+ # @orbitconnect/react
2
+
3
+ React SDK for OrbitConnect — drop in real-time chat, voice/video calls, and meetings into any React app.
4
+
5
+ > The SDK connects exclusively to `https://orbitxyz.muvle.org/api/v1`. This base URL is fixed and cannot be overridden.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @orbitconnect/react
11
+ ```
12
+
13
+ Also import the stylesheet once in your entry file:
14
+
15
+ ```ts
16
+ import '@orbitconnect/react/index.css'
17
+ ```
18
+
19
+ ## Quick start
20
+
21
+ ### 1. Backend — issue a user token
22
+
23
+ ```ts
24
+ // Express / Next.js API route
25
+ import { OrbitServer } from '@orbitconnect/server'
26
+
27
+ const orbit = new OrbitServer({ secretKey: process.env.ORBIT_SECRET_KEY! })
28
+
29
+ app.post('/auth/token', async (req, res) => {
30
+ const user = await orbit.users.create({
31
+ external_id: req.user.id,
32
+ display_name: req.user.name,
33
+ })
34
+ const { token } = await orbit.users.createToken(user.id)
35
+ res.json({ token, userId: user.id, clientId: process.env.ORBIT_CLIENT_ID })
36
+ })
37
+ ```
38
+
39
+ ### 2. Frontend — wrap with OrbitProvider
40
+
41
+ ```tsx
42
+ import { OrbitProvider, Chat } from '@orbitconnect/react'
43
+ import '@orbitconnect/react/index.css'
44
+
45
+ export function App() {
46
+ const [auth, setAuth] = useState(null)
47
+
48
+ async function login() {
49
+ const data = await fetch('/auth/token', { method: 'POST' }).then(r => r.json())
50
+ setAuth(data)
51
+ }
52
+
53
+ if (!auth) return <button onClick={login}>Sign in</button>
54
+
55
+ return (
56
+ <OrbitProvider
57
+ clientId={auth.clientId}
58
+ userToken={auth.token}
59
+ appUserId={auth.userId}
60
+ >
61
+ <Chat />
62
+ </OrbitProvider>
63
+ )
64
+ }
65
+ ```
66
+
67
+ That's it — you now have a fully functional chat with real-time messaging, presence, reactions, file attachments, and voice/video calls.
68
+
69
+ ---
70
+
71
+ ## OrbitProvider
72
+
73
+ The root context provider. Wrap your app (or the section that uses OrbitConnect) with it once.
74
+
75
+ ```tsx
76
+ <OrbitProvider
77
+ clientId="pk_live_..."
78
+ userToken={token}
79
+ appUserId={userId}
80
+ baseTheme={darkTheme}
81
+ theme={{ primary: '#7c3aed', bubbleSender: '#7c3aed' }}
82
+ appConfig={{ name: 'MyApp', showPoweredBy: false }}
83
+ onTokenExpired={async () => fetchFreshToken()}
84
+ >
85
+ <App />
86
+ </OrbitProvider>
87
+ ```
88
+
89
+ | Prop | Type | Required | Description |
90
+ | --- | --- | --- | --- |
91
+ | `clientId` | `string` | ✓ | Publishable key (`pk_live_…` or `pk_test_…`) |
92
+ | `userToken` | `string` | ✓ | Short-lived token from `orbit.users.createToken()` |
93
+ | `appUserId` | `string` | ✓ | The authenticated app user ID |
94
+ | `theme` | `PartialTheme` | | CSS variable overrides — see [Theming](#theming) |
95
+ | `baseTheme` | `OrbitTheme` | | Base theme object (default: `darkTheme`) |
96
+ | `appConfig` | `AppConfig` | | Branding, icons, sounds — see [AppConfig](#appconfig) |
97
+ | `onTokenExpired` | `() => Promise<string>` | | Called on WS close 4001 — return a fresh token to reconnect |
98
+
99
+ ---
100
+
101
+ ## Widgets
102
+
103
+ Drop-in components that work out of the box inside `OrbitProvider`.
104
+
105
+ ### Chat
106
+
107
+ Full-featured chat UI — conversation list, message bubbles, composer, reactions, file attachments, voice messages, call buttons, and more.
108
+
109
+ ```tsx
110
+ import { Chat } from '@orbitconnect/react'
111
+
112
+ <Chat
113
+ onCallRequest={(userId, type) => initiateCall(userId, type)}
114
+ chatBanner={<div>Support hours: Mon–Fri 9am–5pm</div>}
115
+ defaultQuickMessages={[
116
+ { id: '1', label: 'Greeting', text: 'Hi! How can I help?' },
117
+ ]}
118
+ />
119
+ ```
120
+
121
+ | Prop | Type | Description |
122
+ | --- | --- | --- |
123
+ | `conversationId` | `string` | Open directly to a specific conversation |
124
+ | `onCallRequest` | `(userId, type) => void` | Called when the user taps the call/video button |
125
+ | `renderHeader` | `(info: ChatHeaderInfo) => ReactNode` | Replace the default header |
126
+ | `chatBanner` | `ReactNode` | Rendered above the message list |
127
+ | `defaultQuickMessages` | `QuickMessage[]` | Seed the quick-message picker |
128
+
129
+ Included out of the box: real-time messaging, typing indicators, read receipts, reactions, reply/quote, file/image/video/audio attachments, voice recording, sticker & GIF picker, message search, pin messages, batch select/delete/forward, presence, call history.
130
+
131
+ ### VideoCall
132
+
133
+ Floating WebRTC call overlay — renders automatically when a call is active.
134
+
135
+ ```tsx
136
+ import { VideoCall, useCall } from '@orbitconnect/react'
137
+
138
+ function App() {
139
+ const { initiateCall } = useCall()
140
+ return (
141
+ <>
142
+ <button onClick={() => initiateCall(userId, 'video')}>Start call</button>
143
+ <VideoCall /> {/* place once at the root */}
144
+ </>
145
+ )
146
+ }
147
+ ```
148
+
149
+ ### MeetingWidget
150
+
151
+ Full video-conferencing room with participant grid, screen share, reactions, and hand-raise.
152
+
153
+ ```tsx
154
+ import { MeetingWidget } from '@orbitconnect/react'
155
+
156
+ <MeetingWidget
157
+ meetingId={activeMeetingId}
158
+ title="Team Standup"
159
+ onEnd={() => setScreen('lobby')}
160
+ />
161
+ ```
162
+
163
+ | Prop | Type | Required | Description |
164
+ | --- | --- | --- | --- |
165
+ | `meetingId` | `string` | ✓ | The meeting ID to join |
166
+ | `title` | `string` | | Display title (default: `"Meeting"`) |
167
+ | `onEnd` | `() => void` | | Called when the meeting ends or the user leaves |
168
+
169
+ ---
170
+
171
+ ## Hooks
172
+
173
+ All hooks must be used inside `OrbitProvider`.
174
+
175
+ ### useMessages(conversationId)
176
+
177
+ ```ts
178
+ const {
179
+ messages, // MessageBubbleProps[]
180
+ loading,
181
+ typingUsers, // string[] — display names of typing users
182
+ pinnedMessages,
183
+ sendMessage, // (text, mediaId?, meta?) => Promise<void>
184
+ sendTyping,
185
+ markRead,
186
+ editMessageLocally,
187
+ } = useMessages(conversationId)
188
+ ```
189
+
190
+ ### useConversations()
191
+
192
+ ```ts
193
+ const {
194
+ conversations, // Conversation[]
195
+ loading,
196
+ createDirect, // (participantId: string) => Promise<string>
197
+ refresh,
198
+ } = useConversations()
199
+ ```
200
+
201
+ ### useCall()
202
+
203
+ ```ts
204
+ const {
205
+ call, // ActiveCall | null
206
+ localStream, // MediaStream | null
207
+ remoteStream, // MediaStream | null
208
+ initiateCall, // (userId, type, conversationId?) => void
209
+ acceptCall,
210
+ rejectCall,
211
+ endCall,
212
+ toggleMute, // (muted: boolean) => void
213
+ toggleCamera, // (enabled: boolean) => void
214
+ dismissEnded,
215
+ } = useCall()
216
+ ```
217
+
218
+ ### useNotifications()
219
+
220
+ ```ts
221
+ const {
222
+ notifications, // OrbitNotification[]
223
+ unreadCount,
224
+ markRead, // (id: string) => void
225
+ markAllRead,
226
+ clearAll,
227
+ } = useNotifications()
228
+ ```
229
+
230
+ ### usePresence(userId)
231
+
232
+ ```ts
233
+ const status = usePresence(userId) // 'online' | 'away' | 'offline'
234
+ ```
235
+
236
+ ### useMedia()
237
+
238
+ ```ts
239
+ const {
240
+ upload, // (file: File) => Promise<MediaObject>
241
+ getUrl, // (mediaId: string) => Promise<string>
242
+ } = useMedia()
243
+ ```
244
+
245
+ ### useRealtime()
246
+
247
+ ```ts
248
+ const {
249
+ session,
250
+ createSession, // (input: CreateSessionInput) => Promise<void>
251
+ endSession,
252
+ transition, // (type: TransitionType, contextId?: string) => Promise<void>
253
+ emitEvent, // (eventType: string, payload: object) => Promise<void>
254
+ } = useRealtime()
255
+ ```
256
+
257
+ ### useOrbitEvent(eventType, handler)
258
+
259
+ Subscribe to any raw WebSocket event.
260
+
261
+ ```ts
262
+ import { useOrbitEvent } from '@orbitconnect/react'
263
+
264
+ useOrbitEvent('message:new', ({ conversation_id, message }) => {
265
+ console.log('New message:', message)
266
+ })
267
+
268
+ useOrbitEvent('notification:received', ({ payload }) => {
269
+ toast(payload.title as string)
270
+ })
271
+ ```
272
+
273
+ ### useCallHistory()
274
+
275
+ ```ts
276
+ const { records } = useCallHistory() // CallRecord[]
277
+ ```
278
+
279
+ ### useOrbit()
280
+
281
+ Access the raw context from any child component.
282
+
283
+ ```ts
284
+ const { apiClient, appUserId, clientId, baseUrl, appConfig } = useOrbit()
285
+ ```
286
+
287
+ ---
288
+
289
+ ## Theming
290
+
291
+ Every colour, radius, and font is a CSS variable you can override.
292
+
293
+ ```tsx
294
+ import { OrbitProvider, darkTheme, lightTheme } from '@orbitconnect/react'
295
+ import type { PartialTheme } from '@orbitconnect/react'
296
+
297
+ const myTheme: PartialTheme = {
298
+ primary: '#7c3aed',
299
+ bubbleSender: '#7c3aed',
300
+ bubbleSenderForeground: '#fff',
301
+ }
302
+
303
+ <OrbitProvider baseTheme={darkTheme} theme={myTheme} ...>
304
+ ```
305
+
306
+ Key token groups: `background`, `foreground`, `card`, `border`, `primary`, `bubbleSender`, `bubbleReceiver`, `composerBg`, `radiusSm/Md/Lg/Xl`, `fontBody`.
307
+
308
+ ---
309
+
310
+ ## AppConfig
311
+
312
+ White-label every aspect of the UI — name, logo, icons, sounds, and feature flags.
313
+
314
+ ```tsx
315
+ <OrbitProvider
316
+ appConfig={{
317
+ name: 'MyApp',
318
+ logo: <MyLogo />,
319
+ showPoweredBy: false,
320
+
321
+ // feature flags
322
+ showAudioIcon: true,
323
+ showVideoIcon: true,
324
+ showSearchIcon: true,
325
+ showAttachMentButton: true,
326
+ showQuickMessageButton: true,
327
+ useRichTextEditor: true,
328
+ enableMeetingUi: true,
329
+
330
+ // icon overrides (any ReactNode)
331
+ sendIcon: <IoPaperPlaneOutline />,
332
+ callIcon: <IoCallOutline />,
333
+ VideoCallIcon: <IoVideocamOutline />,
334
+
335
+ // custom sounds
336
+ sounds: {
337
+ messageSent: '/sounds/sent.mp3',
338
+ messageReceived: '/sounds/received.mp3',
339
+ incomingCall: '/sounds/ring.mp3',
340
+ },
341
+ }}
342
+ >
343
+ ```
344
+
345
+ ---
346
+
347
+ ## Token refresh
348
+
349
+ When the server closes the WebSocket with code `4001` (token expired), the SDK calls `onTokenExpired`. Return a fresh token to reconnect automatically.
350
+
351
+ ```tsx
352
+ <OrbitProvider
353
+ onTokenExpired={async () => {
354
+ const res = await fetch('/auth/refresh', { method: 'POST' })
355
+ const data = await res.json()
356
+ return data.token
357
+ }}
358
+ ...
359
+ >
360
+ ```
361
+
362
+ ---
363
+
364
+ ## Build
365
+
366
+ ```bash
367
+ npm run build # tsc + vite build + tailwind CSS
368
+ npm run dev # vite dev server (for SDK development)
369
+ npm run lint # eslint
370
+ ```
371
+
372
+ ## License
373
+
374
+ MIT
@@ -0,0 +1,87 @@
1
+ import { type ReactNode } from 'react';
2
+ import type { ApiClient } from './api/client';
3
+ /** Sound asset URLs for SDK events */
4
+ export interface SoundConfig {
5
+ /** Played when the user sends a message */
6
+ messageSent?: string;
7
+ /** Played when a new message is received */
8
+ messageReceived?: string;
9
+ /** Played when the remote user is typing */
10
+ typing?: string;
11
+ /** Played when a reaction is added to a message */
12
+ messageReaction?: string;
13
+ /** Played when an incoming call arrives */
14
+ incomingCall?: string;
15
+ /** Played when a call ends */
16
+ callEnded?: string;
17
+ /** Played when a meeting reaction burst fires */
18
+ meetingReaction?: string;
19
+ }
20
+ /** Branding / white-label config passed to OrbitProvider */
21
+ export interface AppConfig {
22
+ /** Your app name — replaces "OrbitConnect" everywhere */
23
+ name?: string;
24
+ /** A React component rendered as the logo */
25
+ logo?: ReactNode;
26
+ /** Show both name and logo (default when both are provided) */
27
+ showNameAndLogo?: boolean;
28
+ /** Show name only, even if logo is provided */
29
+ showNameOnly?: boolean;
30
+ /** Show logo only, even if name is provided */
31
+ showLogoOnly?: boolean;
32
+ /** Custom sound assets */
33
+ sounds?: SoundConfig;
34
+ /** Show the chat header bar (default: true) */
35
+ showChatHeader?: boolean;
36
+ /** Show the quick-message button in the composer (default: true) */
37
+ showQuickMessageButton?: boolean;
38
+ /** Use the rich-text (contentEditable) editor; false = plain textarea (default: true) */
39
+ useRichTextEditor?: boolean;
40
+ /** Show the attachment button in the composer (default: true) */
41
+ showAttachMentButton?: boolean;
42
+ /** Show the search icon in the chat header (default: true) */
43
+ showSearchIcon?: boolean;
44
+ /** Show the audio-call icon in the chat header (default: true) */
45
+ showAudioIcon?: boolean;
46
+ /** Show the video-call icon in the chat header (default: true) */
47
+ showVideoIcon?: boolean;
48
+ /** Show the meeting tab / meeting UI (default: true) */
49
+ enableMeetingUi?: boolean;
50
+ /** Show "Powered by OrbitConnect" footer in Chat and Meeting widgets (default: true) */
51
+ showPoweredBy?: boolean;
52
+ /** Custom attachment button icon */
53
+ attachmentIcon?: ReactNode;
54
+ /** Custom voice-record button icon */
55
+ recordIcon?: ReactNode;
56
+ /** Custom quick-message button icon */
57
+ QuickmessageIcon?: ReactNode;
58
+ /** Custom emoji button icon */
59
+ emojIcon?: ReactNode;
60
+ /** Custom sticker button icon */
61
+ stickerIcon?: ReactNode;
62
+ /** Custom send button icon */
63
+ sendIcon?: ReactNode;
64
+ /** Custom "delivered" status icon */
65
+ deliveredIcon?: ReactNode;
66
+ /** Custom "sent" status icon */
67
+ sentIcon?: ReactNode;
68
+ /** Custom "read" status icon */
69
+ readIcon?: ReactNode;
70
+ /** Custom audio-call icon (header) */
71
+ callIcon?: ReactNode;
72
+ /** Custom video-call icon (header) */
73
+ VideoCallIcon?: ReactNode;
74
+ }
75
+ export interface OrbitContextValue {
76
+ apiClient: ApiClient;
77
+ /** The authenticated app_user ID */
78
+ appUserId: string;
79
+ clientId: string;
80
+ baseUrl: string;
81
+ /** Optional branding config */
82
+ appConfig?: AppConfig;
83
+ }
84
+ export declare const OrbitContext: import("react").Context<OrbitContextValue | null>;
85
+ export declare function useOrbit(): OrbitContextValue;
86
+ /** Convenience hook — returns appConfig with safe defaults applied */
87
+ export declare function useAppConfig(): Required<Pick<AppConfig, 'showChatHeader' | 'showQuickMessageButton' | 'useRichTextEditor' | 'showAttachMentButton' | 'showSearchIcon' | 'showAudioIcon' | 'showVideoIcon' | 'enableMeetingUi' | 'showPoweredBy'>> & Pick<AppConfig, 'attachmentIcon' | 'recordIcon' | 'QuickmessageIcon' | 'emojIcon' | 'stickerIcon' | 'sendIcon' | 'deliveredIcon' | 'sentIcon' | 'readIcon' | 'callIcon' | 'VideoCallIcon'>;
@@ -0,0 +1,24 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type AppConfig } from './OrbitContext';
3
+ import type { PartialTheme, OrbitTheme } from './theme/types';
4
+ export interface OrbitProviderProps {
5
+ /**
6
+ * Your publishable client ID — safe for the browser.
7
+ * Format: "pk_live_..." or "pk_test_..."
8
+ */
9
+ clientId: string;
10
+ /** Short-lived user token from orbit.users.createToken() on your backend */
11
+ userToken: string;
12
+ /** The authenticated app_user's ID */
13
+ appUserId: string;
14
+ /** Theme overrides */
15
+ theme?: PartialTheme;
16
+ /** Base theme. Defaults to darkTheme */
17
+ baseTheme?: OrbitTheme;
18
+ /** Called when the WS connection closes with code 4001 (token expired). Should return a fresh token. */
19
+ onTokenExpired?: () => Promise<string>;
20
+ /** Branding / white-label config — replaces "OrbitConnect" with your app name/logo */
21
+ appConfig?: AppConfig;
22
+ children: ReactNode;
23
+ }
24
+ export declare function OrbitProvider({ clientId, userToken, appUserId, theme, baseTheme, onTokenExpired, appConfig, children, }: OrbitProviderProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Lightweight fetch client for the client SDK.
3
+ * Uses the user token + client ID — never the secret API key.
4
+ */
5
+ export interface ApiClientOptions {
6
+ baseUrl: string;
7
+ userToken: string;
8
+ clientId: string;
9
+ /** The authenticated app_user ID — forwarded as X-App-User-Id for per-user rate limiting */
10
+ appUserId: string;
11
+ }
12
+ export declare class ApiClient {
13
+ private readonly opts;
14
+ constructor(opts: ApiClientOptions);
15
+ get baseUrl(): string;
16
+ get userToken(): string;
17
+ get clientId(): string;
18
+ private headers;
19
+ request<T>(method: string, path: string, body?: unknown): Promise<T>;
20
+ get<T>(path: string): Promise<T>;
21
+ post<T>(path: string, body?: unknown): Promise<T>;
22
+ patch<T>(path: string, body?: unknown): Promise<T>;
23
+ delete<T>(path: string): Promise<T>;
24
+ /** Register a device push token so the backend can send FCM/APNs wakeup pushes */
25
+ registerPushToken(token: string, platform: 'android' | 'ios'): Promise<void>;
26
+ /** Send a test notification to yourself (dev/demo use) */
27
+ sendTestNotification(opts?: {
28
+ type?: string;
29
+ title?: string;
30
+ body?: string;
31
+ icon?: string;
32
+ channel?: string;
33
+ actions?: Array<{
34
+ id: string;
35
+ label: string;
36
+ url?: string;
37
+ }>;
38
+ }): Promise<void>;
39
+ }
40
+ export declare class OrbitClientError extends Error {
41
+ readonly status: number;
42
+ readonly code: string | undefined;
43
+ constructor(message: string, status: number, code?: string);
44
+ }
@@ -0,0 +1,2 @@
1
+ export { ApiClient, OrbitClientError } from './client';
2
+ export type { ApiClientOptions } from './client';