From 8c0e9e2fd965b3934d387ecf497f01b6ba274256 Mon Sep 17 00:00:00 2001 From: Izan Gil <66965250+SrIzan10@users.noreply.github.com> Date: Fri, 17 Jan 2025 19:34:55 +0100 Subject: [PATCH] feat: very barebones stream viewer --- package.json | 3 + src/app/(protected)/[username]/page.tsx | 8 + .../api/livekit/broadcasterToken/route.ts | 25 +++ .../api/livekit/viewerToken/route.ts | 29 +++ src/components/app/Livestream/Livestream.tsx | 107 +++++++++++ src/lib/services/livekit.ts | 13 ++ yarn.lock | 179 +++++++++++++++++- 7 files changed, 361 insertions(+), 3 deletions(-) create mode 100644 src/app/(protected)/[username]/page.tsx create mode 100644 src/app/(protected)/api/livekit/broadcasterToken/route.ts create mode 100644 src/app/(protected)/api/livekit/viewerToken/route.ts create mode 100644 src/components/app/Livestream/Livestream.tsx create mode 100644 src/lib/services/livekit.ts diff --git a/package.json b/package.json index 4801b59..05b6728 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ }, "dependencies": { "@hookform/resolvers": "^3.9.1", + "@livekit/components-react": "^2.7.0", "@lucia-auth/adapter-prisma": "^4.0.1", "@node-rs/argon2": "^2.0.2", "@prisma/client": "^6.0.1", @@ -24,6 +25,8 @@ "arctic": "^3.1.1", "class-variance-authority": "^0.7.1", "clsx": "^2.1.0", + "livekit-client": "^2.8.0", + "livekit-server-sdk": "^2.9.7", "lucia": "^3.2.2", "lucide-react": "^0.368.0", "next": "^15.1.2", diff --git a/src/app/(protected)/[username]/page.tsx b/src/app/(protected)/[username]/page.tsx new file mode 100644 index 0000000..de54a65 --- /dev/null +++ b/src/app/(protected)/[username]/page.tsx @@ -0,0 +1,8 @@ +import LiveStream from "@/components/app/Livestream/Livestream"; + +export default async function Page({ params }: { params: Promise<{ username: string }> }) { + const { username } = await params; + return ( + + ); +} diff --git a/src/app/(protected)/api/livekit/broadcasterToken/route.ts b/src/app/(protected)/api/livekit/broadcasterToken/route.ts new file mode 100644 index 0000000..d248867 --- /dev/null +++ b/src/app/(protected)/api/livekit/broadcasterToken/route.ts @@ -0,0 +1,25 @@ +import { ingressClient, roomService } from '@/lib/services/livekit'; +import { IngressInput } from 'livekit-server-sdk'; + +export async function GET(request: Request) { + const { searchParams } = new URL(request.url); + const room = searchParams.get('room'); + + if (!room) { + return new Response('Missing room', { status: 400 }); + } + + await roomService.createRoom({ + name: room, + }) + const ingress = await ingressClient.createIngress( + IngressInput.RTMP_INPUT, + { + name: room, + roomName: room, + participantIdentity: 'streamer', + } + ) + + return Response.json({ key: ingress.streamKey }); +} \ No newline at end of file diff --git a/src/app/(protected)/api/livekit/viewerToken/route.ts b/src/app/(protected)/api/livekit/viewerToken/route.ts new file mode 100644 index 0000000..ce8e4a4 --- /dev/null +++ b/src/app/(protected)/api/livekit/viewerToken/route.ts @@ -0,0 +1,29 @@ +import { validateRequest } from '@/lib/auth'; +import { AccessToken } from 'livekit-server-sdk'; +import { NextRequest } from 'next/server'; + +export async function GET(request: NextRequest) { + const { user } = await validateRequest(); + const room = request.nextUrl.searchParams.get('room'); + if (!room) { + return new Response('Room is required', { status: 400 }); + } + if (!user) { + return new Response('Unauthorized', { status: 401 }); + } + + const at = new AccessToken(process.env.LIVEKIT_API_KEY, process.env.LIVEKIT_SECRET, { + identity: user.id, + ttl: 3600, + }); + + at.addGrant({ + room, + roomJoin: true, + canPublish: false, + canSubscribe: true, + canPublishData: false, + }); + + return Response.json({ token: await at.toJwt() }); +} diff --git a/src/components/app/Livestream/Livestream.tsx b/src/components/app/Livestream/Livestream.tsx new file mode 100644 index 0000000..ed5586d --- /dev/null +++ b/src/components/app/Livestream/Livestream.tsx @@ -0,0 +1,107 @@ +'use client'; + +import { + LiveKitRoom, + useTracks, + VideoTrack, + TrackRefContext, + useConnectionState, + useParticipants, + AudioTrack, + StartAudio, +} from '@livekit/components-react'; +import { getTrackReferenceId } from '@livekit/components-core'; +import { Track } from 'livekit-client'; +import { LoaderCircleIcon } from 'lucide-react'; +import { useEffect, useState } from 'react'; + +export default function LiveStream({ username }: { username: string }) { + const [token, setToken] = useState(''); + + useEffect(() => { + fetch(`/api/livekit/viewerToken?room=${username}`) + .then((res) => res.json()) + .then((data) => setToken(data.token)); + }, [username]); + + if (!token) return
Loading...
; + + return ( + + + + ); +} + +function StreamView() { + const tracks = useTracks([ + Track.Source.Camera, + Track.Source.Microphone, + Track.Source.ScreenShare, + Track.Source.ScreenShareAudio, + ]); + const participants = useParticipants(); + const connectionState = useConnectionState(); + const [isConnecting, setIsConnecting] = useState(true); + + const broadcasterTracks = tracks.filter((track) => track.participant.identity === 'streamer'); + + // very hacky but works + useEffect(() => { + if (connectionState === 'connected') { + const timer = setTimeout(() => setIsConnecting(false), 2000); + return () => clearTimeout(timer); + } + }, [connectionState]); + useEffect(() => { + console.log('participants', participants); + }, [participants]); + + if (connectionState === 'connecting' || isConnecting) { + return ( +
+
+ +

Connecting to stream...

+
+
+ ); + } + if (connectionState === 'disconnected') { + return ( +
+

Connection lost. Trying to reconnect...

+
+ ); + } + + if (!broadcasterTracks.length) { + return ( +
+

Stream is currently offline

+
+ ); + } + + const trackRef = broadcasterTracks[0]; + + return ( +
+ + + + {broadcasterTracks.map((trackRef) => ( + + ))} + +
+ ); +} diff --git a/src/lib/services/livekit.ts b/src/lib/services/livekit.ts new file mode 100644 index 0000000..066ed61 --- /dev/null +++ b/src/lib/services/livekit.ts @@ -0,0 +1,13 @@ +import { IngressClient, RoomServiceClient } from 'livekit-server-sdk'; + +export const roomService = new RoomServiceClient( + process.env.NEXT_PUBLIC_LIVEKIT_URL!, + process.env.LIVEKIT_API_KEY, + process.env.LIVEKIT_SECRET +); + +export const ingressClient = new IngressClient( + process.env.NEXT_PUBLIC_LIVEKIT_URL!, + process.env.LIVEKIT_API_KEY, + process.env.LIVEKIT_SECRET +); diff --git a/yarn.lock b/yarn.lock index 59723cd..1241f8d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -229,6 +229,11 @@ "@babel/helper-string-parser" "^7.25.9" "@babel/helper-validator-identifier" "^7.25.9" +"@bufbuild/protobuf@^1.10.0", "@bufbuild/protobuf@^1.7.2": + version "1.10.0" + resolved "https://registry.yarnpkg.com/@bufbuild/protobuf/-/protobuf-1.10.0.tgz#1a67ac889c2d464a3492b3e54c38f80517963b16" + integrity sha512-QDdVFLoN93Zjg36NoQPZfsVH9tZew7wKDKyV5qRdj8ntT4wQCOradQjRaTdwMhWUYsgKsvCINKKm87FdEk96Ag== + "@emnapi/core@^1.3.1": version "1.3.1" resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.3.1.tgz#9c62d185372d1bddc94682b87f376e03dfac3f16" @@ -290,6 +295,14 @@ dependencies: "@floating-ui/utils" "^0.2.9" +"@floating-ui/dom@1.6.11": + version "1.6.11" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.11.tgz#8631857838d34ee5712339eb7cbdfb8ad34da723" + integrity sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ== + dependencies: + "@floating-ui/core" "^1.6.0" + "@floating-ui/utils" "^0.2.8" + "@floating-ui/dom@^1.0.0": version "1.6.13" resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.13.tgz#a8a938532aea27a95121ec16e667a7cbe8c59e34" @@ -305,7 +318,7 @@ dependencies: "@floating-ui/dom" "^1.0.0" -"@floating-ui/utils@^0.2.9": +"@floating-ui/utils@^0.2.8", "@floating-ui/utils@^0.2.9": version "0.2.9" resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.9.tgz#50dea3616bc8191fb8e112283b49eaff03e78429" integrity sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg== @@ -491,6 +504,43 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@livekit/components-core@0.12.0": + version "0.12.0" + resolved "https://registry.yarnpkg.com/@livekit/components-core/-/components-core-0.12.0.tgz#fb339b3bc81bc7a34b78256fe45f41b8867c3e33" + integrity sha512-nF3yd0R9NYUb85/VGJoAYV4GrydTWifrRUvZ4l9vDGJtRsI5yxNjlLM8p9tq2Qe1CU7bgv/Idb6lbKyIWNKT0w== + dependencies: + "@floating-ui/dom" "1.6.11" + loglevel "1.9.1" + rxjs "7.8.1" + +"@livekit/components-react@^2.7.0": + version "2.7.0" + resolved "https://registry.yarnpkg.com/@livekit/components-react/-/components-react-2.7.0.tgz#6d7e2ec1155841c1f7d89072c9e156a5cf857c7a" + integrity sha512-My7FktLPo+TQGutkrC3nyAWECO+MUrUdW4qpfgOOdAeBLjhULgoxMY34Dmw676frFvtPZavDdt33Kn3lf8Ub1Q== + dependencies: + "@livekit/components-core" "0.12.0" + clsx "2.1.1" + usehooks-ts "3.1.0" + +"@livekit/mutex@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@livekit/mutex/-/mutex-1.1.1.tgz#72492b611d55be8130ba2271b7a436d94b1bc6d4" + integrity sha512-EsshAucklmpuUAfkABPxJNhzj9v2sG7JuzFDL4ML1oJQSV14sqrpTYnsaOudMAw9yOaW53NU3QQTlUQoRs4czw== + +"@livekit/protocol@1.30.0": + version "1.30.0" + resolved "https://registry.yarnpkg.com/@livekit/protocol/-/protocol-1.30.0.tgz#c79e98aca2a822f9bd217d016c6efd0f472f206f" + integrity sha512-SDI9ShVKj8N3oOSinr8inaxD3FXgmgoJlqN35uU/Yx1sdoDeQbzAuBFox7bYjM+VhnZ1V22ivIDjAsKr00H+XQ== + dependencies: + "@bufbuild/protobuf" "^1.10.0" + +"@livekit/protocol@^1.30.0": + version "1.31.0" + resolved "https://registry.yarnpkg.com/@livekit/protocol/-/protocol-1.31.0.tgz#a8344a46b9e914a846cd0a2218f28635e7768b05" + integrity sha512-3uoMY1JUqDuoFtAlgjHLKZ9KBfqDBbBRq1GwPKB1hMiH1RVyPOV5TG7XVE4wm/vdAgUKgawtX2anZPJBIi6QQA== + dependencies: + "@bufbuild/protobuf" "^1.10.0" + "@lucia-auth/adapter-prisma@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@lucia-auth/adapter-prisma/-/adapter-prisma-4.0.1.tgz#8f8aa95bf0ac266fd2fb8ac3dc6dd9faec53342f" @@ -1455,6 +1505,21 @@ camelcase-css@^2.0.1: resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== +camelcase-keys@^9.0.0: + version "9.1.3" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-9.1.3.tgz#6367b2f9ec5724af541f58f0dcfee9b200022e5c" + integrity sha512-Rircqi9ch8AnZscQcsA1C47NFdaO3wukpmIRzYcDOrmvgt78hM/sj5pZhZNec2NM12uk5vTwRHZ4anGcrC4ZTg== + dependencies: + camelcase "^8.0.0" + map-obj "5.0.0" + quick-lru "^6.1.1" + type-fest "^4.3.2" + +camelcase@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-8.0.0.tgz#c0d36d418753fb6ad9c5e0437579745c1c14a534" + integrity sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA== + caniuse-lite@^1.0.30001579, caniuse-lite@^1.0.30001688: version "1.0.30001692" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001692.tgz#4585729d95e6b95be5b439da6ab55250cd125bf9" @@ -1517,7 +1582,7 @@ clone@^1.0.2: resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== -clsx@^2.1.0, clsx@^2.1.1: +clsx@2.1.1, clsx@^2.1.0, clsx@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999" integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== @@ -2126,6 +2191,11 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +events@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + execa@^7.0.0: version "7.2.0" resolved "https://registry.yarnpkg.com/execa/-/execa-7.2.0.tgz#657e75ba984f42a70f38928cedc87d6f2d4fe4e9" @@ -2797,6 +2867,11 @@ jiti@^1.21.6: resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.7.tgz#9dd81043424a3d28458b193d965f0d18a2300ba9" integrity sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A== +jose@^5.1.2: + version "5.9.6" + resolved "https://registry.yarnpkg.com/jose/-/jose-5.9.6.tgz#77f1f901d88ebdc405e57cce08d2a91f47521883" + integrity sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -2912,6 +2987,31 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== +livekit-client@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/livekit-client/-/livekit-client-2.8.0.tgz#76e0c39b0f1ec231a6747fa91c4631604e666c80" + integrity sha512-8/IXhacAFYdXMU1wFyc8/MSGCzHr02Hn9T5o3MX19TR03RHSaBKBF2xK8fQFINBmpcYkiMAnQL0P6K3nfcifQA== + dependencies: + "@livekit/mutex" "1.1.1" + "@livekit/protocol" "1.30.0" + events "^3.3.0" + loglevel "^1.8.0" + sdp-transform "^2.14.1" + ts-debounce "^4.0.0" + tslib "2.8.1" + typed-emitter "^2.1.0" + webrtc-adapter "^9.0.0" + +livekit-server-sdk@^2.9.7: + version "2.9.7" + resolved "https://registry.yarnpkg.com/livekit-server-sdk/-/livekit-server-sdk-2.9.7.tgz#b782b04611ee7878e1946aecbb494e25302a3abc" + integrity sha512-uIkFOaqBCJnVgYOidZdanPWQH5G0LMxe0+Qp5zbx7MZCkJ7lGiju//yonfEvFofriJBKACjMq/KQHBex96QpeA== + dependencies: + "@bufbuild/protobuf" "^1.7.2" + "@livekit/protocol" "^1.30.0" + camelcase-keys "^9.0.0" + jose "^5.1.2" + locate-path@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" @@ -2924,6 +3024,11 @@ lodash._reinterpolate@^3.0.0: resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" integrity sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA== +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== + lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" @@ -2952,6 +3057,16 @@ log-symbols@^5.1.0: chalk "^5.0.0" is-unicode-supported "^1.1.0" +loglevel@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.9.1.tgz#d63976ac9bcd03c7c873116d41c2a85bafff1be7" + integrity sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg== + +loglevel@^1.8.0: + version "1.9.2" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.9.2.tgz#c2e028d6c757720107df4e64508530db6621ba08" + integrity sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg== + loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -2984,6 +3099,11 @@ lucide-react@^0.368.0: resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.368.0.tgz#3c0ee63f4f7d30ae63b621b2b8f04f9e409ee6e7" integrity sha512-soryVrCjheZs8rbXKdINw9B8iPi5OajBJZMJ1HORig89ljcOcEokKKAgGbg3QWxSXel7JwHOfDFUdDHAKyUAMw== +map-obj@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-5.0.0.tgz#126c98596b63927d7360f287cccc67177aa1938b" + integrity sha512-2L3MIgJynYrZ3TYMriLDLWocz15okFakV6J12HXvMXDHui2x/zgChzg1u9mFFGbbGWE+GsLpQByt4POb9Or+uA== + math-intrinsics@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" @@ -3470,6 +3590,11 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +quick-lru@^6.1.1: + version "6.1.2" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-6.1.2.tgz#e9a90524108629be35287d0b864e7ad6ceb3659e" + integrity sha512-AAFUA5O1d83pIHEhJwWCq/RQcRukCkn/NSm2QsTEMle5f2hP0ChI2+3Xb051PZCkLryI/Ir1MVKviT2FIloaTQ== + react-dom@19: version "19.0.0" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.0.0.tgz#43446f1f01c65a4cd7f7588083e686a6726cfb57" @@ -3634,6 +3759,13 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" +rxjs@7.8.1, rxjs@^7.5.2: + version "7.8.1" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== + dependencies: + tslib "^2.1.0" + safe-array-concat@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.3.tgz#c9e54ec4f603b0bbb8e7e5007a5ee7aecd1538c3" @@ -3672,6 +3804,16 @@ scheduler@^0.25.0: resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.25.0.tgz#336cd9768e8cceebf52d3c80e3dcf5de23e7e015" integrity sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA== +sdp-transform@^2.14.1: + version "2.15.0" + resolved "https://registry.yarnpkg.com/sdp-transform/-/sdp-transform-2.15.0.tgz#79d37a2481916f36a0534e07b32ceaa87f71df42" + integrity sha512-KrOH82c/W+GYQ0LHqtr3caRpM3ITglq3ljGUIb8LTki7ByacJZ9z+piSGiwZDsRyhQbYBOBJgr2k6X4BZXi3Kw== + +sdp@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/sdp/-/sdp-3.2.0.tgz#8961420552b36663b4d13ddba6f478d1461896a5" + integrity sha512-d7wDPgDV3DDiqulJjKiV2865wKsJ34YI+NDREbm+FySq6WuKOikwyNQcm+doLAZ1O6ltdO0SeKle2xMpN3Brgw== + semver@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" @@ -4135,6 +4277,11 @@ ts-api-utils@^2.0.0: resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.0.0.tgz#b9d7d5f7ec9f736f4d0f09758b8607979044a900" integrity sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ== +ts-debounce@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/ts-debounce/-/ts-debounce-4.0.0.tgz#33440ef64fab53793c3d546a8ca6ae539ec15841" + integrity sha512-+1iDGY6NmOGidq7i7xZGA4cm8DAa6fqdYcvO5Z6yBevH++Bdo9Qt/mN0TzHUgcCcKv1gmh9+W5dHqz8pMWbCbg== + ts-interface-checker@^0.1.9: version "0.1.13" resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" @@ -4167,7 +4314,7 @@ tsconfig-paths@^4.2.0: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@^2.0.0, tslib@^2.0.1, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.8.0: +tslib@2.8.1, tslib@^2.0.0, tslib@^2.0.1, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.8.0: version "2.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== @@ -4184,6 +4331,11 @@ type-fest@^0.20.2: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== +type-fest@^4.3.2: + version "4.32.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.32.0.tgz#55bacdd6f2cf1392b7e9cde894e9b1d726807e97" + integrity sha512-rfgpoi08xagF3JSdtJlCwMq9DGNDE0IMh3Mkpc1wUypg9vPi786AiqeBBKcqvIkq42azsBM85N490fyZjeUftw== + typed-array-buffer@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz#a72395450a4869ec033fd549371b47af3a2ee536" @@ -4229,6 +4381,13 @@ typed-array-length@^1.0.7: possible-typed-array-names "^1.0.0" reflect.getprototypeof "^1.0.6" +typed-emitter@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/typed-emitter/-/typed-emitter-2.1.0.tgz#ca78e3d8ef1476f228f548d62e04e3d4d3fd77fb" + integrity sha512-g/KzbYKbH5C2vPkaXGu8DJlHrGKHLsM25Zg9WuC9pMGfuvT+X25tZQWo5fK1BjBm8+UrVE9LDCvaY0CQk+fXDA== + optionalDependencies: + rxjs "^7.5.2" + typescript@^5: version "5.7.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.7.3.tgz#919b44a7dbb8583a9b856d162be24a54bf80073e" @@ -4284,6 +4443,13 @@ use-sidecar@^1.1.2: detect-node-es "^1.1.0" tslib "^2.0.0" +usehooks-ts@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/usehooks-ts/-/usehooks-ts-3.1.0.tgz#156119f36efc85f1b1952616c02580f140950eca" + integrity sha512-bBIa7yUyPhE1BCc0GmR96VU/15l/9gP1Ch5mYdLcFBaFGQsdmXkvjV0TtOqW1yUd6VjIwDunm+flSciCQXujiw== + dependencies: + lodash.debounce "^4.0.8" + util-deprecate@^1.0.1, util-deprecate@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -4301,6 +4467,13 @@ web-streams-polyfill@^3.0.3: resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz#2073b91a2fdb1fbfbd401e7de0ac9f8214cecb4b" integrity sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw== +webrtc-adapter@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/webrtc-adapter/-/webrtc-adapter-9.0.1.tgz#d4efa22ca9604cb2c8cdb9e492815ba37acfa0b2" + integrity sha512-1AQO+d4ElfVSXyzNVTOewgGT/tAomwwztX/6e3totvyyzXPvXIIuUUjAmyZGbKBKbZOXauuJooZm3g6IuFuiNQ== + dependencies: + sdp "^3.2.0" + which-boxed-primitive@^1.1.0, which-boxed-primitive@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz#d76ec27df7fa165f18d5808374a5fe23c29b176e"