@naviedu/room-platform-react 0.0.1 → 0.0.3-8.1

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 (70) hide show
  1. package/README.md +262 -0
  2. package/index.d.ts +766 -32
  3. package/index.esm.js +19621 -7892
  4. package/package.json +4 -7
  5. package/styles.css +199 -24
  6. package/assets/ATTRIBUTION.md +0 -46
  7. package/assets/presets/alpine-lake-mirror.jpg +0 -0
  8. package/assets/presets/alpine-lake.jpg +0 -0
  9. package/assets/presets/canyon-view-mirror.jpg +0 -0
  10. package/assets/presets/canyon-view.jpg +0 -0
  11. package/assets/presets/desert-dunes-mirror.jpg +0 -0
  12. package/assets/presets/desert-dunes.jpg +0 -0
  13. package/assets/presets/flower-meadow-mirror.jpg +0 -0
  14. package/assets/presets/flower-meadow.jpg +0 -0
  15. package/assets/presets/forest-road-mirror.jpg +0 -0
  16. package/assets/presets/forest-road.jpg +0 -0
  17. package/assets/presets/naviedu-mirror.jpg +0 -0
  18. package/assets/presets/naviedu.jpg +0 -0
  19. package/assets/presets/ocean-cliffs-mirror.jpg +0 -0
  20. package/assets/presets/ocean-cliffs.jpg +0 -0
  21. package/assets/presets/tropical-beach-mirror.jpg +0 -0
  22. package/assets/presets/tropical-beach.jpg +0 -0
  23. package/assets/presets/waterfall-mist-mirror.jpg +0 -0
  24. package/assets/presets/waterfall-mist.jpg +0 -0
  25. package/extensions/room-platform-extensions.d.ts +0 -8
  26. package/room-action-button.d.ts +0 -11
  27. package/room-participant-actions.d.ts +0 -9
  28. package/room-participant-list.d.ts +0 -7
  29. package/room-participant-tab.d.ts +0 -6
  30. package/room-platform-active-speaker.d.ts +0 -4
  31. package/room-platform-background-settings.d.ts +0 -15
  32. package/room-platform-camera-background-presets.d.ts +0 -8
  33. package/room-platform-camera-background-storage.d.ts +0 -38
  34. package/room-platform-control-anchor.d.ts +0 -10
  35. package/room-platform-control-bar.d.ts +0 -11
  36. package/room-platform-control-state.d.ts +0 -12
  37. package/room-platform-current-operation-strip.d.ts +0 -13
  38. package/room-platform-device-selection.d.ts +0 -7
  39. package/room-platform-device-settings.d.ts +0 -8
  40. package/room-platform-local-preview.d.ts +0 -6
  41. package/room-platform-media-controls.d.ts +0 -1
  42. package/room-platform-media-runtime.d.ts +0 -2
  43. package/room-platform-monitor-stage.d.ts +0 -7
  44. package/room-platform-monitor-video-tile.d.ts +0 -20
  45. package/room-platform-monitor-viewer.d.ts +0 -8
  46. package/room-platform-private-room-connection.d.ts +0 -11
  47. package/room-platform-private-room-context.d.ts +0 -8
  48. package/room-platform-private-room-control-bar.d.ts +0 -12
  49. package/room-platform-private-room-experience.d.ts +0 -14
  50. package/room-platform-private-room-overlay.d.ts +0 -7
  51. package/room-platform-private-room-stage.d.ts +0 -9
  52. package/room-platform-private-room-status-banner.d.ts +0 -8
  53. package/room-platform-provider.d.ts +0 -35
  54. package/room-platform-room.d.ts +0 -2
  55. package/room-platform-screen-share-whiteboard-frame.d.ts +0 -11
  56. package/room-platform-shell.d.ts +0 -17
  57. package/room-platform-speak-queue.d.ts +0 -16
  58. package/room-platform-stage-selection.d.ts +0 -14
  59. package/room-platform-stage.d.ts +0 -13
  60. package/room-platform-surface-boundary.d.ts +0 -13
  61. package/room-platform-top-bar.d.ts +0 -7
  62. package/room-platform-types.d.ts +0 -154
  63. package/room-platform-ui-primitives.d.ts +0 -60
  64. package/room-platform-video-tile.d.ts +0 -13
  65. package/room-platform-video-tracks.d.ts +0 -6
  66. package/use-room-platform-camera-background.d.ts +0 -34
  67. package/use-room-platform-private-room-control-actions.d.ts +0 -21
  68. package/use-room-platform-private-room.d.ts +0 -43
  69. package/use-room-platform-stage.d.ts +0 -2
  70. package/use-room-presence.d.ts +0 -2
package/README.md ADDED
@@ -0,0 +1,262 @@
1
+ # @naviedu/room-platform-react
2
+
3
+ Embeddable React UI and runtime for NaviEdu Room Platform rooms. The package
4
+ owns the default room experience, LiveKit connection, media controls, speaker
5
+ requests, private rooms, responsive layout, and optional chat and whiteboard
6
+ surfaces.
7
+
8
+ ## Requirements
9
+
10
+ - React 18 or 19
11
+ - A Room Platform launch ticket issued by the host backend
12
+ - A public Room Platform API base URL
13
+ - A browser running in a secure context when camera, microphone, or screen
14
+ sharing is required
15
+
16
+ The launch ticket is short-lived and must be obtained server-side. Do not put
17
+ backend credentials or long-lived signing secrets in the browser bundle.
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install @naviedu/room-platform-react
23
+ ```
24
+
25
+ `react` and `react-dom` are peer dependencies. Room Platform's published
26
+ runtime dependencies are installed automatically with the package.
27
+
28
+ ## Basic usage
29
+
30
+ Render `RoomPlatformRoom` with the launch ticket returned by your backend:
31
+
32
+ ```tsx
33
+ 'use client'
34
+
35
+ import { type RoomLaunchTicketRenewalReason, RoomPlatformRoom } from '@naviedu/room-platform-react'
36
+
37
+ type RoomTicketResponse = { launchToken: string }
38
+
39
+ export function Room({ launchToken }: { launchToken: string }) {
40
+ async function renewLaunchTicket(_reason: RoomLaunchTicketRenewalReason): Promise<RoomTicketResponse> {
41
+ const response = await fetch('/api/room-platform/launch-ticket', {
42
+ method: 'POST',
43
+ credentials: 'include',
44
+ })
45
+
46
+ if (!response.ok) throw new Error('Unable to renew the Room Platform launch ticket')
47
+
48
+ return (await response.json()) as RoomTicketResponse
49
+ }
50
+
51
+ return (
52
+ <RoomPlatformRoom
53
+ apiBaseUrl="https://api.example.com/room-platform"
54
+ launchToken={launchToken}
55
+ onLaunchTicketRequired={renewLaunchTicket}
56
+ onExit={() => window.history.back()}
57
+ />
58
+ )
59
+ }
60
+ ```
61
+
62
+ `RoomPlatformRoom` renders its default room UI in an isolated Shadow Root and installs the package stylesheet itself. Do not import `@naviedu/room-platform-react/styles.css` for the default component.
63
+
64
+ `RoomPlatformProvider` is advanced composition only; a consumer using it instead of `RoomPlatformRoom` owns its own DOM and stylesheet boundary.
65
+
66
+ `apiBaseUrl` is the URL prefix before `/rooms`. The package calls these routes
67
+ relative to it:
68
+
69
+ - `POST /rooms/exchange`
70
+ - `GET /rooms/:roomId/control-state`
71
+ - `POST /rooms/:roomId/actions`
72
+
73
+ For example, with `apiBaseUrl="https://api.example.com/room-platform"`, the
74
+ exchange request is sent to
75
+ `https://api.example.com/room-platform/rooms/exchange`.
76
+
77
+ The package renders a full viewport room (`100dvh`). Mount it in a page or
78
+ layout that allows the room to occupy the viewport.
79
+
80
+ ## `RoomPlatformRoom` props
81
+
82
+ | Prop | Required | Description |
83
+ | ------------------------ | -------- | ------------------------------------------------------------------------------------ |
84
+ | `apiBaseUrl` | Yes | Room Platform API prefix. Do not append `/rooms`. |
85
+ | `launchToken` | Yes | Initial server-issued launch ticket. |
86
+ | `onLaunchTicketRequired` | Yes | Returns `{ launchToken }` when the current ticket or access session must be renewed. |
87
+ | `extensions` | No | Host-provided top-bar, workspace, sidebar, monitor, and participant extensions. |
88
+ | `onError` | No | Receives connection, media, and action errors. |
89
+ | `onLifecycleEvent` | No | Receives exchange, renewal, and reconnect lifecycle events. |
90
+ | `onExit` | No | Called when the user chooses to leave the room. |
91
+ | `children` | No | Replaces the default workspace while keeping the provider and room runtime. |
92
+
93
+ The default teaching stage selects the available participant camera carrying
94
+ the canonical `room:moderate` capability. Screen share remains primary and the
95
+ moderator camera becomes its overlay. If no moderator camera is available, the
96
+ stage keeps its waiting state and never promotes a student camera. The local
97
+ sidebar preview is hidden only when that selected moderator camera is local;
98
+ its existing desktop breakpoint remains unchanged.
99
+
100
+ The public room keeps one canonical local camera track. It may be preview-only
101
+ before publication, and preview visibility never grants `media:publish_video`.
102
+
103
+ ### Error and lifecycle callbacks
104
+
105
+ ```tsx
106
+ <RoomPlatformRoom
107
+ // ...required props
108
+ onError={({ error, recoverable, scope }) => {
109
+ console.error(`[room-platform:${scope}]`, error)
110
+ if (!recoverable) {
111
+ // Show the host application's unavailable-room state.
112
+ }
113
+ }}
114
+ onLifecycleEvent={(event) => {
115
+ // Send telemetry to the host backend if needed.
116
+ console.info('Room Platform lifecycle:', event)
117
+ }}
118
+ />
119
+ ```
120
+
121
+ Lifecycle events are `exchange.succeeded`, `exchange.failed`,
122
+ `renewal.succeeded`, `renewal.failed`, `reconnect.succeeded`, and
123
+ `reconnect.failed`.
124
+
125
+ ## Chat and whiteboard boundary
126
+
127
+ Chat and Whiteboard are owned by the Room Platform exchange. The host only
128
+ passes the launch ticket and public Room Platform API base URL shown above;
129
+ there is no public `integrations` prop.
130
+
131
+ After the launch ticket exchange succeeds and LiveKit connects, the package
132
+ hydrates the Chat and Whiteboard projection returned by Room Platform. The
133
+ projection contains only the short-lived, already-authorized runtime data
134
+ needed by the package. On renewal, the complete projection is replaced.
135
+
136
+ Each integration degrades independently. An `available: false` Chat or
137
+ Whiteboard projection disables only that surface; LiveKit, the other
138
+ integration, and private-room invite, accept, and media flows remain usable.
139
+ LiveKit exchange/connection failure is the only fatal case for mounting the
140
+ room integrations.
141
+
142
+ Consumers must not provide or derive Chat/Whiteboard credentials, internal or
143
+ service endpoints, integration room IDs, or permission objects. Do not expose
144
+ app/HMAC secrets or call Chat/Whiteboard services directly from the host. The
145
+ Room Platform exchange is the trust boundary and supplies the public runtime
146
+ projection after server-side authorization.
147
+
148
+ Whiteboard uses the exchanged Room Platform `roomId` for its room context and
149
+ is created lazily only when Whiteboard is available and a screen share starts.
150
+ Stopping a share deactivates its board; every new share receives a new
151
+ `shareSessionKey`. No board is mounted before sharing begins.
152
+
153
+ ## Extensions
154
+
155
+ Extensions keep host-specific UI outside the shared room implementation. Every
156
+ extension receives `RoomPlatformExtensionProps`:
157
+
158
+ Host extensions with independent framework CSS must own their own DOM and
159
+ stylesheet boundary.
160
+
161
+ ```tsx
162
+ import type { RoomPlatformExtensionProps } from '@naviedu/room-platform-react'
163
+
164
+ function HostToolbar({ actions, capabilities, connectionStatus, roomId }: RoomPlatformExtensionProps) {
165
+ const canModerate = capabilities.includes('room:moderate')
166
+
167
+ return (
168
+ <div>
169
+ <span>{connectionStatus}</span>
170
+ <span>{roomId}</span>
171
+ {canModerate ? (
172
+ <button type="button" onClick={() => void actions.perform('speak.request')}>
173
+ Request to speak
174
+ </button>
175
+ ) : null}
176
+ </div>
177
+ )
178
+ }
179
+
180
+ ;<RoomPlatformRoom
181
+ // ...required props
182
+ extensions={{
183
+ topBarTrailing: HostToolbar,
184
+ sidebarTabs: [{ id: 'materials', title: 'Materials', component: HostMaterialsTab }],
185
+ mainWorkspace: {
186
+ component: HostWorkspace,
187
+ },
188
+ }}
189
+ />
190
+ ```
191
+
192
+ Available extension slots are:
193
+
194
+ - `topBarLeading` and `topBarTrailing`
195
+ - `mainWorkspace` for the practice workspace overlay
196
+ - `sidebarTabs`
197
+ - `participantTab` in `default` or `replace` mode
198
+ - `monitor` with a host-provided participant roster and eligibility flag
199
+
200
+ `actions.perform` sends a Room Platform action and accepts an optional string
201
+ payload. Check `actions.hasCapability(...)` before rendering privileged
202
+ controls, and use `actions.isPending(...)` to disable controls during an
203
+ in-flight action.
204
+
205
+ ## Advanced composition
206
+
207
+ Use `RoomPlatformProvider` and `useRoomPlatform` when the host needs to render
208
+ a custom room surface instead of `RoomPlatformRoom`'s default workspace:
209
+
210
+ ```tsx
211
+ import { RoomPlatformProvider, type RoomPlatformProviderProps, useRoomPlatform } from '@naviedu/room-platform-react'
212
+
213
+ function CustomRoomSurface() {
214
+ const { localMedia, setLocalMediaEnabled, status } = useRoomPlatform()
215
+
216
+ return (
217
+ <button
218
+ type="button"
219
+ disabled={status !== 'connected'}
220
+ onClick={() => void setLocalMediaEnabled('camera', !localMedia.camera)}
221
+ >
222
+ {localMedia.camera ? 'Turn camera off' : 'Turn camera on'}
223
+ </button>
224
+ )
225
+ }
226
+
227
+ export function CustomRoom(props: {
228
+ apiBaseUrl: string
229
+ launchToken: string
230
+ onLaunchTicketRequired: RoomPlatformProviderProps['onLaunchTicketRequired']
231
+ }) {
232
+ return (
233
+ <RoomPlatformProvider {...props}>
234
+ <CustomRoomSurface />
235
+ </RoomPlatformProvider>
236
+ )
237
+ }
238
+ ```
239
+
240
+ Use `RoomPlatformRoom` unless a custom surface is required. It composes the
241
+ provider, LiveKit media runtime, private-room runtime, default stage, controls,
242
+ and sidebar for you.
243
+
244
+ ## Publishing and local verification
245
+
246
+ From the repository root:
247
+
248
+ ```bash
249
+ yarn nx run @naviedu/room-platform-react:build
250
+ ```
251
+
252
+ The publishable package is written to
253
+ `dist/libs/features/room-platform-react`. Inspect it before publishing:
254
+
255
+ ```bash
256
+ cd dist/libs/features/room-platform-react
257
+ npm pack --dry-run
258
+ npm publish --access public
259
+ ```
260
+
261
+ The package embeds the required shared UI source during bundling, so consumers
262
+ do not need private workspace aliases such as `@navi/ui` or `@navi/utils`.