mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2026-04-13 16:56:54 +00:00
feat: Livekit bare no recording nor pipeline
This commit is contained in:
@@ -74,6 +74,7 @@ const recordingTypeOptions: SelectOption[] = [
|
||||
const platformOptions: SelectOption[] = [
|
||||
{ label: "Whereby", value: "whereby" },
|
||||
{ label: "Daily", value: "daily" },
|
||||
{ label: "LiveKit", value: "livekit" },
|
||||
];
|
||||
|
||||
const roomInitialState = {
|
||||
@@ -309,10 +310,7 @@ export default function RoomsList() {
|
||||
return;
|
||||
}
|
||||
|
||||
const platform: "whereby" | "daily" =
|
||||
room.platform === "whereby" || room.platform === "daily"
|
||||
? room.platform
|
||||
: "daily";
|
||||
const platform = room.platform as "whereby" | "daily" | "livekit";
|
||||
|
||||
const roomData = {
|
||||
name: room.name,
|
||||
@@ -544,7 +542,10 @@ export default function RoomsList() {
|
||||
<Select.Root
|
||||
value={[room.platform]}
|
||||
onValueChange={(e) => {
|
||||
const newPlatform = e.value[0] as "whereby" | "daily";
|
||||
const newPlatform = e.value[0] as
|
||||
| "whereby"
|
||||
| "daily"
|
||||
| "livekit";
|
||||
const updates: Partial<typeof room> = {
|
||||
platform: newPlatform,
|
||||
};
|
||||
|
||||
212
www/app/[roomName]/components/LiveKitRoom.tsx
Normal file
212
www/app/[roomName]/components/LiveKitRoom.tsx
Normal file
@@ -0,0 +1,212 @@
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { Box, Spinner, Center, Text, IconButton } from "@chakra-ui/react";
|
||||
import { useRouter, useParams } from "next/navigation";
|
||||
import {
|
||||
LiveKitRoom as LKRoom,
|
||||
VideoConference,
|
||||
RoomAudioRenderer,
|
||||
} from "@livekit/components-react";
|
||||
// LiveKit component styles — imported in the global layout to avoid
|
||||
// Next.js CSS import restrictions in client components.
|
||||
// See: app/[roomName]/layout.tsx
|
||||
import type { components } from "../../reflector-api";
|
||||
import { useAuth } from "../../lib/AuthProvider";
|
||||
import { useRoomJoinMeeting } from "../../lib/apiHooks";
|
||||
import { assertMeetingId } from "../../lib/types";
|
||||
import {
|
||||
ConsentDialogButton,
|
||||
RecordingIndicator,
|
||||
useConsentDialog,
|
||||
} from "../../lib/consent";
|
||||
import { useEmailTranscriptDialog } from "../../lib/emailTranscript";
|
||||
import { featureEnabled } from "../../lib/features";
|
||||
import { LuMail } from "react-icons/lu";
|
||||
|
||||
type Meeting = components["schemas"]["Meeting"];
|
||||
type Room = components["schemas"]["RoomDetails"];
|
||||
|
||||
interface LiveKitRoomProps {
|
||||
meeting: Meeting;
|
||||
room: Room;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract LiveKit WebSocket URL, room name, and token from the room_url.
|
||||
*
|
||||
* The backend returns room_url like: ws://host:7880?room=<name>&token=<jwt>
|
||||
* We split these for the LiveKit React SDK.
|
||||
*/
|
||||
function parseLiveKitUrl(roomUrl: string): {
|
||||
serverUrl: string;
|
||||
roomName: string | null;
|
||||
token: string | null;
|
||||
} {
|
||||
try {
|
||||
const url = new URL(roomUrl);
|
||||
const token = url.searchParams.get("token");
|
||||
const roomName = url.searchParams.get("room");
|
||||
url.searchParams.delete("token");
|
||||
url.searchParams.delete("room");
|
||||
// Strip trailing slash and leftover ? from URL API
|
||||
const serverUrl = url.toString().replace(/[?/]+$/, "");
|
||||
return { serverUrl, roomName, token };
|
||||
} catch {
|
||||
return { serverUrl: roomUrl, roomName: null, token: null };
|
||||
}
|
||||
}
|
||||
|
||||
export default function LiveKitRoom({ meeting, room }: LiveKitRoomProps) {
|
||||
const router = useRouter();
|
||||
const params = useParams();
|
||||
const auth = useAuth();
|
||||
const authLastUserId = auth.lastUserId;
|
||||
const roomName = params?.roomName as string;
|
||||
const meetingId = assertMeetingId(meeting.id);
|
||||
|
||||
const joinMutation = useRoomJoinMeeting();
|
||||
const [joinedMeeting, setJoinedMeeting] = useState<Meeting | null>(null);
|
||||
const [connectionError, setConnectionError] = useState(false);
|
||||
|
||||
// ── Consent dialog (same hooks as Daily/Whereby) ──────────
|
||||
const { showConsentButton, showRecordingIndicator } = useConsentDialog({
|
||||
meetingId,
|
||||
recordingType: meeting.recording_type,
|
||||
skipConsent: room.skip_consent,
|
||||
});
|
||||
|
||||
// ── Email transcript dialog ───────────────────────────────
|
||||
const userEmail =
|
||||
auth.status === "authenticated" || auth.status === "refreshing"
|
||||
? auth.user.email
|
||||
: null;
|
||||
const { showEmailModal } = useEmailTranscriptDialog({
|
||||
meetingId,
|
||||
userEmail,
|
||||
});
|
||||
const showEmailFeature = featureEnabled("emailTranscript");
|
||||
|
||||
// ── Join meeting via backend API to get token ─────────────
|
||||
useEffect(() => {
|
||||
if (authLastUserId === undefined || !meeting?.id || !roomName) return;
|
||||
let cancelled = false;
|
||||
|
||||
async function join() {
|
||||
try {
|
||||
const result = await joinMutation.mutateAsync({
|
||||
params: {
|
||||
path: { room_name: roomName, meeting_id: meeting.id },
|
||||
},
|
||||
});
|
||||
if (!cancelled) setJoinedMeeting(result);
|
||||
} catch (err) {
|
||||
console.error("Failed to join LiveKit meeting:", err);
|
||||
if (!cancelled) setConnectionError(true);
|
||||
}
|
||||
}
|
||||
|
||||
join();
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [meeting?.id, roomName, authLastUserId]);
|
||||
|
||||
const handleDisconnected = useCallback(() => {
|
||||
router.push("/browse");
|
||||
}, [router]);
|
||||
|
||||
// ── Loading / error states ────────────────────────────────
|
||||
if (connectionError) {
|
||||
return (
|
||||
<Center h="100vh" bg="gray.50">
|
||||
<Text fontSize="lg">Failed to connect to meeting</Text>
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
|
||||
if (!joinedMeeting) {
|
||||
return (
|
||||
<Center h="100vh" bg="gray.50">
|
||||
<Spinner color="blue.500" size="xl" />
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
|
||||
const {
|
||||
serverUrl,
|
||||
roomName: lkRoomName,
|
||||
token,
|
||||
} = parseLiveKitUrl(joinedMeeting.room_url);
|
||||
|
||||
if (
|
||||
serverUrl &&
|
||||
!serverUrl.startsWith("ws://") &&
|
||||
!serverUrl.startsWith("wss://")
|
||||
) {
|
||||
console.warn(
|
||||
`LiveKit serverUrl has unexpected scheme: ${serverUrl}. Expected ws:// or wss://`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!token || !lkRoomName) {
|
||||
return (
|
||||
<Center h="100vh" bg="gray.50">
|
||||
<Text fontSize="lg">
|
||||
{!token
|
||||
? "No access token received from server"
|
||||
: "No room name received from server"}
|
||||
</Text>
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
|
||||
// ── Render ────────────────────────────────────────────────
|
||||
// The token already encodes the room name (in VideoGrants.room),
|
||||
// so LiveKit SDK joins the correct room from the token alone.
|
||||
return (
|
||||
<Box w="100vw" h="100vh" bg="black" position="relative">
|
||||
<LKRoom
|
||||
serverUrl={serverUrl}
|
||||
token={token}
|
||||
connect={true}
|
||||
audio={true}
|
||||
video={true}
|
||||
onDisconnected={handleDisconnected}
|
||||
data-lk-theme="default"
|
||||
style={{ height: "100%" }}
|
||||
>
|
||||
<VideoConference />
|
||||
<RoomAudioRenderer />
|
||||
</LKRoom>
|
||||
|
||||
{/* ── Floating overlay buttons (consent, email, extensible) ── */}
|
||||
{showConsentButton && (
|
||||
<ConsentDialogButton
|
||||
meetingId={meetingId}
|
||||
recordingType={meeting.recording_type}
|
||||
skipConsent={room.skip_consent}
|
||||
/>
|
||||
)}
|
||||
|
||||
{showRecordingIndicator && <RecordingIndicator />}
|
||||
|
||||
{showEmailFeature && (
|
||||
<IconButton
|
||||
aria-label="Email transcript"
|
||||
position="absolute"
|
||||
top="56px"
|
||||
right="8px"
|
||||
zIndex={1000}
|
||||
colorPalette="blue"
|
||||
size="sm"
|
||||
onClick={showEmailModal}
|
||||
variant="solid"
|
||||
borderRadius="full"
|
||||
>
|
||||
<LuMail />
|
||||
</IconButton>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import MeetingSelection from "../MeetingSelection";
|
||||
import useRoomDefaultMeeting from "../useRoomDefaultMeeting";
|
||||
import WherebyRoom from "./WherebyRoom";
|
||||
import DailyRoom from "./DailyRoom";
|
||||
import LiveKitRoom from "./LiveKitRoom";
|
||||
import { useAuth } from "../../lib/AuthProvider";
|
||||
import { useError } from "../../(errors)/errorContext";
|
||||
import { parseNonEmptyString } from "../../lib/utils";
|
||||
@@ -199,8 +200,9 @@ export default function RoomContainer(details: RoomDetails) {
|
||||
return <DailyRoom meeting={meeting} room={room} />;
|
||||
case "whereby":
|
||||
return <WherebyRoom meeting={meeting} room={room} />;
|
||||
default: {
|
||||
const _exhaustive: never = platform;
|
||||
case "livekit":
|
||||
return <LiveKitRoom meeting={meeting} room={room} />;
|
||||
default:
|
||||
return (
|
||||
<Box
|
||||
display="flex"
|
||||
@@ -213,6 +215,5 @@ export default function RoomContainer(details: RoomDetails) {
|
||||
<Text fontSize="lg">Unknown platform: {platform}</Text>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import "./styles/globals.scss";
|
||||
import "@livekit/components-styles";
|
||||
import { Metadata, Viewport } from "next";
|
||||
import { Poppins } from "next/font/google";
|
||||
import { ErrorProvider } from "./(errors)/errorContext";
|
||||
|
||||
56
www/app/reflector-api.d.ts
vendored
56
www/app/reflector-api.d.ts
vendored
@@ -911,6 +911,32 @@ export interface paths {
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/v1/livekit/webhook": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
/**
|
||||
* Livekit Webhook
|
||||
* @description Handle LiveKit webhook events.
|
||||
*
|
||||
* LiveKit webhook events include:
|
||||
* - participant_joined / participant_left
|
||||
* - egress_started / egress_updated / egress_ended
|
||||
* - room_started / room_finished
|
||||
* - track_published / track_unpublished
|
||||
*/
|
||||
post: operations["v1_livekit_webhook"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/v1/auth/login": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
@@ -1100,7 +1126,7 @@ export interface components {
|
||||
* Platform
|
||||
* @enum {string}
|
||||
*/
|
||||
platform: "whereby" | "daily";
|
||||
platform: "whereby" | "daily" | "livekit";
|
||||
/**
|
||||
* Skip Consent
|
||||
* @default false
|
||||
@@ -1821,7 +1847,7 @@ export interface components {
|
||||
* Platform
|
||||
* @enum {string}
|
||||
*/
|
||||
platform: "whereby" | "daily";
|
||||
platform: "whereby" | "daily" | "livekit";
|
||||
/** Daily Composed Video S3 Key */
|
||||
daily_composed_video_s3_key?: string | null;
|
||||
/** Daily Composed Video Duration */
|
||||
@@ -1921,7 +1947,7 @@ export interface components {
|
||||
* Platform
|
||||
* @enum {string}
|
||||
*/
|
||||
platform: "whereby" | "daily";
|
||||
platform: "whereby" | "daily" | "livekit";
|
||||
/**
|
||||
* Skip Consent
|
||||
* @default false
|
||||
@@ -1979,7 +2005,7 @@ export interface components {
|
||||
* Platform
|
||||
* @enum {string}
|
||||
*/
|
||||
platform: "whereby" | "daily";
|
||||
platform: "whereby" | "daily" | "livekit";
|
||||
/**
|
||||
* Skip Consent
|
||||
* @default false
|
||||
@@ -2358,7 +2384,7 @@ export interface components {
|
||||
/** Ics Enabled */
|
||||
ics_enabled?: boolean | null;
|
||||
/** Platform */
|
||||
platform?: ("whereby" | "daily") | null;
|
||||
platform?: ("whereby" | "daily" | "livekit") | null;
|
||||
/** Skip Consent */
|
||||
skip_consent?: boolean | null;
|
||||
/** Email Transcript To */
|
||||
@@ -4504,6 +4530,26 @@ export interface operations {
|
||||
};
|
||||
};
|
||||
};
|
||||
v1_livekit_webhook: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": unknown;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
v1_login: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
"@fortawesome/fontawesome-svg-core": "^7.2.0",
|
||||
"@fortawesome/free-solid-svg-icons": "^7.2.0",
|
||||
"@fortawesome/react-fontawesome": "^3.2.0",
|
||||
"@livekit/components-react": "2.9.20",
|
||||
"@livekit/components-styles": "1.2.0",
|
||||
"@sentry/nextjs": "^10.40.0",
|
||||
"@tanstack/react-query": "^5.90.21",
|
||||
"@whereby.com/browser-sdk": "^3.18.21",
|
||||
@@ -30,6 +32,7 @@
|
||||
"fontawesome": "^5.6.3",
|
||||
"ioredis": "^5.10.0",
|
||||
"jest-worker": "^30.2.0",
|
||||
"livekit-client": "2.18.0",
|
||||
"lucide-react": "^0.575.0",
|
||||
"next": "16.1.7",
|
||||
"next-auth": "^4.24.13",
|
||||
|
||||
150
www/pnpm-lock.yaml
generated
150
www/pnpm-lock.yaml
generated
@@ -34,6 +34,12 @@ importers:
|
||||
'@fortawesome/react-fontawesome':
|
||||
specifier: ^3.2.0
|
||||
version: 3.2.0(@fortawesome/fontawesome-svg-core@7.2.0)(react@19.2.4)
|
||||
'@livekit/components-react':
|
||||
specifier: 2.9.20
|
||||
version: 2.9.20(livekit-client@2.18.0(@types/dom-mediacapture-record@1.0.22))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(tslib@2.8.1)
|
||||
'@livekit/components-styles':
|
||||
specifier: 1.2.0
|
||||
version: 1.2.0
|
||||
'@sentry/nextjs':
|
||||
specifier: ^10.40.0
|
||||
version: 10.40.0(@opentelemetry/context-async-hooks@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.5.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.5.1(@opentelemetry/api@1.9.0))(next@16.1.7(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.97.3))(react@19.2.4)(webpack@5.105.3)
|
||||
@@ -64,6 +70,9 @@ importers:
|
||||
jest-worker:
|
||||
specifier: ^30.2.0
|
||||
version: 30.2.0
|
||||
livekit-client:
|
||||
specifier: 2.18.0
|
||||
version: 2.18.0(@types/dom-mediacapture-record@1.0.22)
|
||||
lucide-react:
|
||||
specifier: ^0.575.0
|
||||
version: 0.575.0(react@19.2.4)
|
||||
@@ -343,6 +352,9 @@ packages:
|
||||
'@bcoe/v8-coverage@0.2.3':
|
||||
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
|
||||
|
||||
'@bufbuild/protobuf@1.10.1':
|
||||
resolution: {integrity: sha512-wJ8ReQbHxsAfXhrf9ixl0aYbZorRuOWpBNzm8pL8ftmSxQx/wnJD5Eg861NwJU/czy2VXFIebCeZnZrI9rktIQ==}
|
||||
|
||||
'@chakra-ui/react@3.33.0':
|
||||
resolution: {integrity: sha512-HNbUFsFABjVL5IHBxsqtuT+AH/vQT1+xsEWrxnG0GBM2VjlzlMqlqCxNiDyQOsjLZXQC1ciCMbzPNcSCc63Y9w==}
|
||||
peerDependencies:
|
||||
@@ -445,6 +457,9 @@ packages:
|
||||
'@floating-ui/core@1.7.4':
|
||||
resolution: {integrity: sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg==}
|
||||
|
||||
'@floating-ui/dom@1.7.4':
|
||||
resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==}
|
||||
|
||||
'@floating-ui/dom@1.7.5':
|
||||
resolution: {integrity: sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg==}
|
||||
|
||||
@@ -767,6 +782,36 @@ packages:
|
||||
'@jridgewell/trace-mapping@0.3.31':
|
||||
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
|
||||
|
||||
'@livekit/components-core@0.12.13':
|
||||
resolution: {integrity: sha512-DQmi84afHoHjZ62wm8y+XPNIDHTwFHAltjd3lmyXj8UZHOY7wcza4vFt1xnghJOD5wLRY58L1dkAgAw59MgWvw==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
livekit-client: ^2.17.2
|
||||
tslib: ^2.6.2
|
||||
|
||||
'@livekit/components-react@2.9.20':
|
||||
resolution: {integrity: sha512-hjkYOsJj9Jbghb7wM5cI8HoVisKeL6Zcy1VnRWTLm0sqVbto8GJp/17T4Udx85mCPY6Jgh8I1Cv0yVzgz7CQtg==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
'@livekit/krisp-noise-filter': ^0.2.12 || ^0.3.0
|
||||
livekit-client: ^2.17.2
|
||||
react: '>=18'
|
||||
react-dom: '>=18'
|
||||
tslib: ^2.6.2
|
||||
peerDependenciesMeta:
|
||||
'@livekit/krisp-noise-filter':
|
||||
optional: true
|
||||
|
||||
'@livekit/components-styles@1.2.0':
|
||||
resolution: {integrity: sha512-74/rt0lDh6aHmOPmWAeDE9C4OrNW9RIdmhX/YRbovQBVNGNVWojRjl3FgQZ5LPFXO6l1maKB4JhXcBFENVxVvw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@livekit/mutex@1.1.1':
|
||||
resolution: {integrity: sha512-EsshAucklmpuUAfkABPxJNhzj9v2sG7JuzFDL4ML1oJQSV14sqrpTYnsaOudMAw9yOaW53NU3QQTlUQoRs4czw==}
|
||||
|
||||
'@livekit/protocol@1.44.0':
|
||||
resolution: {integrity: sha512-/vfhDUGcUKO8Q43r6i+5FrDhl5oZjm/X3U4x2Iciqvgn5C8qbj+57YPcWSJ1kyIZm5Cm6AV2nAPjMm3ETD/iyg==}
|
||||
|
||||
'@lukeed/csprng@1.1.0':
|
||||
resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -1886,6 +1931,9 @@ packages:
|
||||
'@types/debug@4.1.12':
|
||||
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
|
||||
|
||||
'@types/dom-mediacapture-record@1.0.22':
|
||||
resolution: {integrity: sha512-mUMZLK3NvwRLcAAT9qmcK+9p7tpU2FHdDsntR3YI4+GY88XrgG4XiE7u1Q2LAN2/FZOz/tdMDC3GQCR4T8nFuw==}
|
||||
|
||||
'@types/eslint-scope@3.7.7':
|
||||
resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==}
|
||||
|
||||
@@ -3839,6 +3887,9 @@ packages:
|
||||
jose@4.15.9:
|
||||
resolution: {integrity: sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==}
|
||||
|
||||
jose@6.2.2:
|
||||
resolution: {integrity: sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==}
|
||||
|
||||
js-levenshtein@1.1.6:
|
||||
resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -3984,6 +4035,11 @@ packages:
|
||||
lines-and-columns@1.2.4:
|
||||
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
|
||||
|
||||
livekit-client@2.18.0:
|
||||
resolution: {integrity: sha512-wjH4y0rw5fnkPmmaxutPhD4XcAq6goQszS8lw9PEpGXVwiRE6sI/ZH+mOT/s8AHJnEC3tjmfiMZ4MQt8BlaWew==}
|
||||
peerDependencies:
|
||||
'@types/dom-mediacapture-record': ^1
|
||||
|
||||
loader-runner@4.3.1:
|
||||
resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==}
|
||||
engines: {node: '>=6.11.5'}
|
||||
@@ -3996,6 +4052,9 @@ packages:
|
||||
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
lodash.debounce@4.0.8:
|
||||
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
|
||||
|
||||
lodash.defaults@4.2.0:
|
||||
resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==}
|
||||
|
||||
@@ -4005,6 +4064,14 @@ packages:
|
||||
lodash.memoize@4.1.2:
|
||||
resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==}
|
||||
|
||||
loglevel@1.9.1:
|
||||
resolution: {integrity: sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==}
|
||||
engines: {node: '>= 0.6.0'}
|
||||
|
||||
loglevel@1.9.2:
|
||||
resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==}
|
||||
engines: {node: '>= 0.6.0'}
|
||||
|
||||
longest-streak@3.1.0:
|
||||
resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
|
||||
|
||||
@@ -4752,6 +4819,9 @@ packages:
|
||||
resolution: {integrity: sha512-K6p9y4ZyL9wPzA+PMDloNQPfoDGTiFYDvdlXznyGKgD10BJpcAosvATKrExRKOrNLgD8E7Um7WGW0lxsnOuNLg==}
|
||||
engines: {node: '>=4.0.0'}
|
||||
|
||||
rxjs@7.8.2:
|
||||
resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==}
|
||||
|
||||
safe-array-concat@1.1.3:
|
||||
resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==}
|
||||
engines: {node: '>=0.4'}
|
||||
@@ -5133,6 +5203,9 @@ packages:
|
||||
resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
typed-emitter@2.1.0:
|
||||
resolution: {integrity: sha512-g/KzbYKbH5C2vPkaXGu8DJlHrGKHLsM25Zg9WuC9pMGfuvT+X25tZQWo5fK1BjBm8+UrVE9LDCvaY0CQk+fXDA==}
|
||||
|
||||
typescript-eslint@8.56.1:
|
||||
resolution: {integrity: sha512-U4lM6pjmBX7J5wk4szltF7I1cGBHXZopnAXCMXb3+fZ3B/0Z3hq3wS/CCUB2NZBNAExK92mCU2tEohWuwVMsDQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
@@ -5228,6 +5301,12 @@ packages:
|
||||
'@types/react':
|
||||
optional: true
|
||||
|
||||
usehooks-ts@3.1.1:
|
||||
resolution: {integrity: sha512-I4diPp9Cq6ieSUH2wu+fDAVQO43xwtulo+fKEidHUwZPnYImbtkTjzIJYcDcJqxgmX31GVqNFURodvcgHcW0pA==}
|
||||
engines: {node: '>=16.15.0'}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17 || ^18 || ^19 || ^19.0.0-rc
|
||||
|
||||
util-deprecate@1.0.2:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
|
||||
@@ -5662,6 +5741,8 @@ snapshots:
|
||||
|
||||
'@bcoe/v8-coverage@0.2.3': {}
|
||||
|
||||
'@bufbuild/protobuf@1.10.1': {}
|
||||
|
||||
'@chakra-ui/react@3.33.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
|
||||
dependencies:
|
||||
'@ark-ui/react': 5.34.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
@@ -5811,6 +5892,11 @@ snapshots:
|
||||
dependencies:
|
||||
'@floating-ui/utils': 0.2.10
|
||||
|
||||
'@floating-ui/dom@1.7.4':
|
||||
dependencies:
|
||||
'@floating-ui/core': 1.7.4
|
||||
'@floating-ui/utils': 0.2.10
|
||||
|
||||
'@floating-ui/dom@1.7.5':
|
||||
dependencies:
|
||||
'@floating-ui/core': 1.7.4
|
||||
@@ -6179,6 +6265,34 @@ snapshots:
|
||||
'@jridgewell/resolve-uri': 3.1.2
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
|
||||
'@livekit/components-core@0.12.13(livekit-client@2.18.0(@types/dom-mediacapture-record@1.0.22))(tslib@2.8.1)':
|
||||
dependencies:
|
||||
'@floating-ui/dom': 1.7.4
|
||||
livekit-client: 2.18.0(@types/dom-mediacapture-record@1.0.22)
|
||||
loglevel: 1.9.1
|
||||
rxjs: 7.8.2
|
||||
tslib: 2.8.1
|
||||
|
||||
'@livekit/components-react@2.9.20(livekit-client@2.18.0(@types/dom-mediacapture-record@1.0.22))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(tslib@2.8.1)':
|
||||
dependencies:
|
||||
'@livekit/components-core': 0.12.13(livekit-client@2.18.0(@types/dom-mediacapture-record@1.0.22))(tslib@2.8.1)
|
||||
clsx: 2.1.1
|
||||
events: 3.3.0
|
||||
jose: 6.2.2
|
||||
livekit-client: 2.18.0(@types/dom-mediacapture-record@1.0.22)
|
||||
react: 19.2.4
|
||||
react-dom: 19.2.4(react@19.2.4)
|
||||
tslib: 2.8.1
|
||||
usehooks-ts: 3.1.1(react@19.2.4)
|
||||
|
||||
'@livekit/components-styles@1.2.0': {}
|
||||
|
||||
'@livekit/mutex@1.1.1': {}
|
||||
|
||||
'@livekit/protocol@1.44.0':
|
||||
dependencies:
|
||||
'@bufbuild/protobuf': 1.10.1
|
||||
|
||||
'@lukeed/csprng@1.1.0': {}
|
||||
|
||||
'@lukeed/uuid@2.0.1':
|
||||
@@ -7259,6 +7373,8 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/ms': 2.1.0
|
||||
|
||||
'@types/dom-mediacapture-record@1.0.22': {}
|
||||
|
||||
'@types/eslint-scope@3.7.7':
|
||||
dependencies:
|
||||
'@types/eslint': 9.6.1
|
||||
@@ -9986,6 +10102,8 @@ snapshots:
|
||||
|
||||
jose@4.15.9: {}
|
||||
|
||||
jose@6.2.2: {}
|
||||
|
||||
js-levenshtein@1.1.6: {}
|
||||
|
||||
js-tokens@4.0.0: {}
|
||||
@@ -10101,6 +10219,19 @@ snapshots:
|
||||
|
||||
lines-and-columns@1.2.4: {}
|
||||
|
||||
livekit-client@2.18.0(@types/dom-mediacapture-record@1.0.22):
|
||||
dependencies:
|
||||
'@livekit/mutex': 1.1.1
|
||||
'@livekit/protocol': 1.44.0
|
||||
'@types/dom-mediacapture-record': 1.0.22
|
||||
events: 3.3.0
|
||||
jose: 6.2.2
|
||||
loglevel: 1.9.2
|
||||
sdp-transform: 2.15.0
|
||||
tslib: 2.8.1
|
||||
typed-emitter: 2.1.0
|
||||
webrtc-adapter: 9.0.4
|
||||
|
||||
loader-runner@4.3.1: {}
|
||||
|
||||
locate-path@5.0.0:
|
||||
@@ -10111,12 +10242,18 @@ snapshots:
|
||||
dependencies:
|
||||
p-locate: 5.0.0
|
||||
|
||||
lodash.debounce@4.0.8: {}
|
||||
|
||||
lodash.defaults@4.2.0: {}
|
||||
|
||||
lodash.isarguments@3.1.0: {}
|
||||
|
||||
lodash.memoize@4.1.2: {}
|
||||
|
||||
loglevel@1.9.1: {}
|
||||
|
||||
loglevel@1.9.2: {}
|
||||
|
||||
longest-streak@3.1.0: {}
|
||||
|
||||
loose-envify@1.4.0:
|
||||
@@ -11009,6 +11146,10 @@ snapshots:
|
||||
|
||||
runes@0.4.3: {}
|
||||
|
||||
rxjs@7.8.2:
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
|
||||
safe-array-concat@1.1.3:
|
||||
dependencies:
|
||||
call-bind: 1.0.8
|
||||
@@ -11462,6 +11603,10 @@ snapshots:
|
||||
possible-typed-array-names: 1.1.0
|
||||
reflect.getprototypeof: 1.0.10
|
||||
|
||||
typed-emitter@2.1.0:
|
||||
optionalDependencies:
|
||||
rxjs: 7.8.2
|
||||
|
||||
typescript-eslint@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@typescript-eslint/eslint-plugin': 8.56.1(@typescript-eslint/parser@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
|
||||
@@ -11585,6 +11730,11 @@ snapshots:
|
||||
optionalDependencies:
|
||||
'@types/react': 19.2.14
|
||||
|
||||
usehooks-ts@3.1.1(react@19.2.4):
|
||||
dependencies:
|
||||
lodash.debounce: 4.0.8
|
||||
react: 19.2.4
|
||||
|
||||
util-deprecate@1.0.2: {}
|
||||
|
||||
uuid-validate@0.0.3: {}
|
||||
|
||||
Reference in New Issue
Block a user