@livekit/rtc-node 0.13.24 → 0.13.26

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 (283) hide show
  1. package/dist/audio_filter.cjs +2 -2
  2. package/dist/audio_filter.cjs.map +1 -1
  3. package/dist/audio_filter.js +1 -1
  4. package/dist/audio_filter.js.map +1 -1
  5. package/dist/audio_frame.cjs +9 -5
  6. package/dist/audio_frame.cjs.map +1 -1
  7. package/dist/audio_frame.d.cts +2 -7
  8. package/dist/audio_frame.d.ts +2 -7
  9. package/dist/audio_frame.d.ts.map +1 -1
  10. package/dist/audio_frame.js +8 -4
  11. package/dist/audio_frame.js.map +1 -1
  12. package/dist/audio_mixer.cjs +10 -4
  13. package/dist/audio_mixer.cjs.map +1 -1
  14. package/dist/audio_mixer.d.cts +4 -7
  15. package/dist/audio_mixer.d.ts +4 -7
  16. package/dist/audio_mixer.d.ts.map +1 -1
  17. package/dist/audio_mixer.js +10 -4
  18. package/dist/audio_mixer.js.map +1 -1
  19. package/dist/audio_resampler.cjs +20 -12
  20. package/dist/audio_resampler.cjs.map +1 -1
  21. package/dist/audio_resampler.d.cts +6 -6
  22. package/dist/audio_resampler.d.ts +6 -6
  23. package/dist/audio_resampler.d.ts.map +1 -1
  24. package/dist/audio_resampler.js +12 -4
  25. package/dist/audio_resampler.js.map +1 -1
  26. package/dist/audio_source.cjs +11 -7
  27. package/dist/audio_source.cjs.map +1 -1
  28. package/dist/audio_source.d.cts +1 -7
  29. package/dist/audio_source.d.ts +1 -7
  30. package/dist/audio_source.d.ts.map +1 -1
  31. package/dist/audio_source.js +8 -3
  32. package/dist/audio_source.js.map +1 -1
  33. package/dist/audio_stream.cjs +16 -6
  34. package/dist/audio_stream.cjs.map +1 -1
  35. package/dist/audio_stream.d.cts +1 -14
  36. package/dist/audio_stream.d.ts +1 -14
  37. package/dist/audio_stream.d.ts.map +1 -1
  38. package/dist/audio_stream.js +15 -5
  39. package/dist/audio_stream.js.map +1 -1
  40. package/dist/data_streams/index.d.cts +2 -10
  41. package/dist/data_streams/index.d.ts +2 -10
  42. package/dist/data_streams/stream_reader.cjs +8 -0
  43. package/dist/data_streams/stream_reader.cjs.map +1 -1
  44. package/dist/data_streams/stream_reader.d.cts +2 -10
  45. package/dist/data_streams/stream_reader.d.ts +2 -10
  46. package/dist/data_streams/stream_reader.d.ts.map +1 -1
  47. package/dist/data_streams/stream_reader.js +8 -0
  48. package/dist/data_streams/stream_reader.js.map +1 -1
  49. package/dist/data_streams/stream_writer.d.cts +2 -10
  50. package/dist/data_streams/stream_writer.d.ts +2 -10
  51. package/dist/data_streams/types.cjs.map +1 -1
  52. package/dist/data_streams/types.d.cts +2 -10
  53. package/dist/data_streams/types.d.ts +2 -10
  54. package/dist/data_streams/types.d.ts.map +1 -1
  55. package/dist/e2ee.cjs +21 -21
  56. package/dist/e2ee.cjs.map +1 -1
  57. package/dist/e2ee.d.cts +1 -2
  58. package/dist/e2ee.d.ts +1 -2
  59. package/dist/e2ee.d.ts.map +1 -1
  60. package/dist/e2ee.js +2 -2
  61. package/dist/e2ee.js.map +1 -1
  62. package/dist/ffi_client.cjs +30 -15
  63. package/dist/ffi_client.cjs.map +1 -1
  64. package/dist/ffi_client.d.cts +6 -17
  65. package/dist/ffi_client.d.ts +6 -17
  66. package/dist/ffi_client.d.ts.map +1 -1
  67. package/dist/ffi_client.js +24 -6
  68. package/dist/ffi_client.js.map +1 -1
  69. package/dist/frame_processor.cjs +13 -2
  70. package/dist/frame_processor.cjs.map +1 -1
  71. package/dist/frame_processor.d.cts +5 -8
  72. package/dist/frame_processor.d.ts +5 -8
  73. package/dist/frame_processor.d.ts.map +1 -1
  74. package/dist/frame_processor.js +10 -1
  75. package/dist/frame_processor.js.map +1 -1
  76. package/dist/index.cjs +25 -23
  77. package/dist/index.cjs.map +1 -1
  78. package/dist/index.d.cts +3 -16
  79. package/dist/index.d.ts +3 -16
  80. package/dist/index.d.ts.map +1 -1
  81. package/dist/index.js +9 -7
  82. package/dist/index.js.map +1 -1
  83. package/dist/participant.cjs +146 -101
  84. package/dist/participant.cjs.map +1 -1
  85. package/dist/participant.d.cts +4 -16
  86. package/dist/participant.d.ts +4 -16
  87. package/dist/participant.d.ts.map +1 -1
  88. package/dist/participant.js +120 -75
  89. package/dist/participant.js.map +1 -1
  90. package/dist/room.cjs +116 -58
  91. package/dist/room.cjs.map +1 -1
  92. package/dist/room.d.cts +6 -15
  93. package/dist/room.d.ts +6 -15
  94. package/dist/room.d.ts.map +1 -1
  95. package/dist/room.js +113 -55
  96. package/dist/room.js.map +1 -1
  97. package/dist/rpc.cjs.map +1 -1
  98. package/dist/rpc.d.cts +1 -2
  99. package/dist/rpc.d.ts +1 -2
  100. package/dist/rpc.d.ts.map +1 -1
  101. package/dist/rpc.js.map +1 -1
  102. package/dist/{stream_reader-Ch2zvjU3.d.cts → stream_reader-CuG4b8Y-.d.cts} +1 -1
  103. package/dist/{stream_reader-DRyR29vo.d.ts → stream_reader-CuG4b8Y-.d.ts} +1 -1
  104. package/dist/track.cjs +3 -3
  105. package/dist/track.cjs.map +1 -1
  106. package/dist/track.d.cts +1 -14
  107. package/dist/track.d.ts +1 -14
  108. package/dist/track.d.ts.map +1 -1
  109. package/dist/track.js +1 -1
  110. package/dist/track.js.map +1 -1
  111. package/dist/track_publication.cjs +4 -4
  112. package/dist/track_publication.cjs.map +1 -1
  113. package/dist/track_publication.d.cts +1 -14
  114. package/dist/track_publication.d.ts +1 -14
  115. package/dist/track_publication.d.ts.map +1 -1
  116. package/dist/track_publication.js +2 -2
  117. package/dist/track_publication.js.map +1 -1
  118. package/dist/version.cjs +1 -1
  119. package/dist/version.cjs.map +1 -1
  120. package/dist/version.d.cts +1 -1
  121. package/dist/version.d.ts +1 -1
  122. package/dist/version.js +1 -1
  123. package/dist/version.js.map +1 -1
  124. package/dist/video_frame.cjs +42 -42
  125. package/dist/video_frame.cjs.map +1 -1
  126. package/dist/video_frame.d.cts +1 -6
  127. package/dist/video_frame.d.ts +1 -6
  128. package/dist/video_frame.d.ts.map +1 -1
  129. package/dist/video_frame.js +2 -2
  130. package/dist/video_frame.js.map +1 -1
  131. package/dist/video_source.cjs +5 -5
  132. package/dist/video_source.cjs.map +1 -1
  133. package/dist/video_source.d.cts +1 -14
  134. package/dist/video_source.d.ts +1 -14
  135. package/dist/video_source.d.ts.map +1 -1
  136. package/dist/video_source.js +2 -2
  137. package/dist/video_source.js.map +1 -1
  138. package/dist/video_stream.cjs +12 -4
  139. package/dist/video_stream.cjs.map +1 -1
  140. package/dist/video_stream.d.cts +1 -14
  141. package/dist/video_stream.d.ts +1 -14
  142. package/dist/video_stream.d.ts.map +1 -1
  143. package/dist/video_stream.js +10 -2
  144. package/dist/video_stream.js.map +1 -1
  145. package/package.json +7 -37
  146. package/src/audio_filter.ts +2 -2
  147. package/src/audio_frame.ts +17 -5
  148. package/src/audio_mixer.test.ts +102 -0
  149. package/src/audio_mixer.ts +10 -4
  150. package/src/audio_resampler.ts +14 -4
  151. package/src/audio_source.ts +13 -5
  152. package/src/audio_stream.ts +21 -6
  153. package/src/data_streams/stream_reader.ts +19 -1
  154. package/src/data_streams/types.ts +1 -1
  155. package/src/e2ee.ts +3 -3
  156. package/src/ffi_client.ts +33 -8
  157. package/src/frame_processor.ts +21 -0
  158. package/src/index.ts +6 -5
  159. package/src/participant.ts +117 -66
  160. package/src/room.ts +161 -69
  161. package/src/rpc.ts +1 -1
  162. package/src/tests/e2e.test.ts +179 -8
  163. package/src/track.ts +4 -4
  164. package/src/track_publication.ts +6 -6
  165. package/src/version.ts +1 -1
  166. package/src/video_frame.ts +3 -3
  167. package/src/video_source.ts +3 -3
  168. package/src/video_stream.ts +15 -3
  169. package/Cargo.toml +0 -25
  170. package/build.rs +0 -9
  171. package/dist/napi/native.cjs +0 -301
  172. package/dist/napi/native.d.cjs +0 -17
  173. package/dist/napi/native.d.cjs.map +0 -1
  174. package/dist/napi/native.d.d.cts +0 -21
  175. package/dist/napi/native.d.d.ts +0 -21
  176. package/dist/napi/native.d.js +0 -1
  177. package/dist/napi/native.d.js.map +0 -1
  178. package/dist/napi/native.d.ts +0 -19
  179. package/dist/napi/native.js +0 -15
  180. package/dist/native.cjs +0 -301
  181. package/dist/native.d.ts +0 -19
  182. package/dist/native.js +0 -15
  183. package/dist/proto/audio_frame_pb.cjs +0 -1357
  184. package/dist/proto/audio_frame_pb.cjs.map +0 -1
  185. package/dist/proto/audio_frame_pb.d.cts +0 -1183
  186. package/dist/proto/audio_frame_pb.d.ts +0 -1183
  187. package/dist/proto/audio_frame_pb.d.ts.map +0 -1
  188. package/dist/proto/audio_frame_pb.js +0 -1283
  189. package/dist/proto/audio_frame_pb.js.map +0 -1
  190. package/dist/proto/data_stream_pb.cjs +0 -1638
  191. package/dist/proto/data_stream_pb.cjs.map +0 -1
  192. package/dist/proto/data_stream_pb.d.cts +0 -1449
  193. package/dist/proto/data_stream_pb.d.ts +0 -1449
  194. package/dist/proto/data_stream_pb.d.ts.map +0 -1
  195. package/dist/proto/data_stream_pb.js +0 -1559
  196. package/dist/proto/data_stream_pb.js.map +0 -1
  197. package/dist/proto/e2ee_pb.cjs +0 -746
  198. package/dist/proto/e2ee_pb.cjs.map +0 -1
  199. package/dist/proto/e2ee_pb.d.cts +0 -653
  200. package/dist/proto/e2ee_pb.d.ts +0 -653
  201. package/dist/proto/e2ee_pb.d.ts.map +0 -1
  202. package/dist/proto/e2ee_pb.js +0 -696
  203. package/dist/proto/e2ee_pb.js.map +0 -1
  204. package/dist/proto/ffi_pb.cjs +0 -477
  205. package/dist/proto/ffi_pb.cjs.map +0 -1
  206. package/dist/proto/ffi_pb.d.cts +0 -1321
  207. package/dist/proto/ffi_pb.d.ts +0 -1321
  208. package/dist/proto/ffi_pb.d.ts.map +0 -1
  209. package/dist/proto/ffi_pb.js +0 -444
  210. package/dist/proto/ffi_pb.js.map +0 -1
  211. package/dist/proto/handle_pb.cjs +0 -53
  212. package/dist/proto/handle_pb.cjs.map +0 -1
  213. package/dist/proto/handle_pb.d.cts +0 -31
  214. package/dist/proto/handle_pb.d.ts +0 -31
  215. package/dist/proto/handle_pb.d.ts.map +0 -1
  216. package/dist/proto/handle_pb.js +0 -29
  217. package/dist/proto/handle_pb.js.map +0 -1
  218. package/dist/proto/participant_pb.cjs +0 -173
  219. package/dist/proto/participant_pb.cjs.map +0 -1
  220. package/dist/proto/participant_pb.d.cts +0 -218
  221. package/dist/proto/participant_pb.d.ts +0 -218
  222. package/dist/proto/participant_pb.d.ts.map +0 -1
  223. package/dist/proto/participant_pb.js +0 -145
  224. package/dist/proto/participant_pb.js.map +0 -1
  225. package/dist/proto/room_pb.cjs +0 -3374
  226. package/dist/proto/room_pb.cjs.map +0 -1
  227. package/dist/proto/room_pb.d.cts +0 -3028
  228. package/dist/proto/room_pb.d.ts +0 -3028
  229. package/dist/proto/room_pb.d.ts.map +0 -1
  230. package/dist/proto/room_pb.js +0 -3232
  231. package/dist/proto/room_pb.js.map +0 -1
  232. package/dist/proto/rpc_pb.cjs +0 -328
  233. package/dist/proto/rpc_pb.cjs.map +0 -1
  234. package/dist/proto/rpc_pb.d.cts +0 -267
  235. package/dist/proto/rpc_pb.d.ts +0 -267
  236. package/dist/proto/rpc_pb.d.ts.map +0 -1
  237. package/dist/proto/rpc_pb.js +0 -294
  238. package/dist/proto/rpc_pb.js.map +0 -1
  239. package/dist/proto/stats_pb.cjs +0 -1370
  240. package/dist/proto/stats_pb.cjs.map +0 -1
  241. package/dist/proto/stats_pb.d.cts +0 -1764
  242. package/dist/proto/stats_pb.d.ts +0 -1764
  243. package/dist/proto/stats_pb.d.ts.map +0 -1
  244. package/dist/proto/stats_pb.js +0 -1300
  245. package/dist/proto/stats_pb.js.map +0 -1
  246. package/dist/proto/track_pb.cjs +0 -630
  247. package/dist/proto/track_pb.cjs.map +0 -1
  248. package/dist/proto/track_pb.d.cts +0 -542
  249. package/dist/proto/track_pb.d.ts +0 -542
  250. package/dist/proto/track_pb.d.ts.map +0 -1
  251. package/dist/proto/track_pb.js +0 -584
  252. package/dist/proto/track_pb.js.map +0 -1
  253. package/dist/proto/track_publication_pb.cjs +0 -194
  254. package/dist/proto/track_publication_pb.cjs.map +0 -1
  255. package/dist/proto/track_publication_pb.d.cts +0 -135
  256. package/dist/proto/track_publication_pb.d.ts +0 -135
  257. package/dist/proto/track_publication_pb.d.ts.map +0 -1
  258. package/dist/proto/track_publication_pb.js +0 -164
  259. package/dist/proto/track_publication_pb.js.map +0 -1
  260. package/dist/proto/video_frame_pb.cjs +0 -723
  261. package/dist/proto/video_frame_pb.cjs.map +0 -1
  262. package/dist/proto/video_frame_pb.d.cts +0 -667
  263. package/dist/proto/video_frame_pb.d.ts +0 -667
  264. package/dist/proto/video_frame_pb.d.ts.map +0 -1
  265. package/dist/proto/video_frame_pb.js +0 -673
  266. package/dist/proto/video_frame_pb.js.map +0 -1
  267. package/src/lib.rs +0 -9
  268. package/src/napi/native.cjs +0 -301
  269. package/src/napi/native.d.ts +0 -19
  270. package/src/napi/native.js +0 -15
  271. package/src/nodejs.rs +0 -134
  272. package/src/proto/audio_frame_pb.ts +0 -2270
  273. package/src/proto/data_stream_pb.ts +0 -2674
  274. package/src/proto/e2ee_pb.ts +0 -1231
  275. package/src/proto/ffi_pb.ts +0 -1700
  276. package/src/proto/handle_pb.ts +0 -69
  277. package/src/proto/participant_pb.ts +0 -351
  278. package/src/proto/room_pb.ts +0 -5661
  279. package/src/proto/rpc_pb.ts +0 -539
  280. package/src/proto/stats_pb.ts +0 -3050
  281. package/src/proto/track_pb.ts +0 -1040
  282. package/src/proto/track_publication_pb.ts +0 -284
  283. package/src/proto/video_frame_pb.ts +0 -1236
@@ -1,10 +1,11 @@
1
+ import { AudioStreamType, NewAudioStreamRequest } from "@livekit/rtc-ffi-bindings";
1
2
  import { AudioFrame } from "./audio_frame.js";
2
3
  import { FfiClient, FfiClientEvent, FfiHandle } from "./ffi_client.js";
3
- import { FrameProcessor } from "./frame_processor.js";
4
+ import { isFrameProcessor } from "./frame_processor.js";
4
5
  import { log } from "./log.js";
5
- import { AudioStreamType, NewAudioStreamRequest } from "./proto/audio_frame_pb.js";
6
6
  class AudioStreamSource {
7
7
  constructor(track, sampleRateOrOptions, numChannels) {
8
+ this.disposed = false;
8
9
  this.onEvent = (ev) => {
9
10
  var _a;
10
11
  if (!this.controller) {
@@ -29,14 +30,18 @@ class AudioStreamSource {
29
30
  case "eos":
30
31
  FfiClient.instance.off(FfiClientEvent.FfiEvent, this.onEvent);
31
32
  this.controller.close();
32
- (_a = this.frameProcessor) == null ? void 0 : _a.close();
33
+ if (!this.disposed) {
34
+ this.disposed = true;
35
+ this.ffiHandle.dispose();
36
+ (_a = this.frameProcessor) == null ? void 0 : _a.close();
37
+ }
33
38
  break;
34
39
  }
35
40
  };
36
41
  if (sampleRateOrOptions !== void 0 && typeof sampleRateOrOptions !== "number") {
37
42
  this.sampleRate = sampleRateOrOptions.sampleRate ?? 48e3;
38
43
  this.numChannels = sampleRateOrOptions.numChannels ?? 1;
39
- if (sampleRateOrOptions.noiseCancellation instanceof FrameProcessor) {
44
+ if (isFrameProcessor(sampleRateOrOptions.noiseCancellation)) {
40
45
  this.frameProcessor = sampleRateOrOptions.noiseCancellation;
41
46
  } else {
42
47
  this.legacyNcOptions = sampleRateOrOptions.noiseCancellation;
@@ -70,8 +75,13 @@ class AudioStreamSource {
70
75
  this.controller = controller;
71
76
  }
72
77
  cancel() {
78
+ var _a;
73
79
  FfiClient.instance.off(FfiClientEvent.FfiEvent, this.onEvent);
74
- this.ffiHandle.dispose();
80
+ if (!this.disposed) {
81
+ this.disposed = true;
82
+ this.ffiHandle.dispose();
83
+ (_a = this.frameProcessor) == null ? void 0 : _a.close();
84
+ }
75
85
  }
76
86
  }
77
87
  class AudioStream extends ReadableStream {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/audio_stream.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { UnderlyingSource } from 'node:stream/web';\nimport { AudioFrame } from './audio_frame.js';\nimport type { FfiEvent } from './ffi_client.js';\nimport { FfiClient, FfiClientEvent, FfiHandle } from './ffi_client.js';\nimport { FrameProcessor } from './frame_processor.js';\nimport { log } from './log.js';\nimport type { NewAudioStreamResponse } from './proto/audio_frame_pb.js';\nimport { AudioStreamType, NewAudioStreamRequest } from './proto/audio_frame_pb.js';\nimport type { Track } from './track.js';\n\nexport interface AudioStreamOptions {\n noiseCancellation?: NoiseCancellationOptions | FrameProcessor<AudioFrame>;\n sampleRate?: number;\n numChannels?: number;\n frameSizeMs?: number;\n}\n\nexport interface NoiseCancellationOptions {\n moduleId: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n options: Record<string, any>;\n}\n\nclass AudioStreamSource implements UnderlyingSource<AudioFrame> {\n private controller?: ReadableStreamDefaultController<AudioFrame>;\n private ffiHandle: FfiHandle;\n private sampleRate: number;\n private numChannels: number;\n private legacyNcOptions?: NoiseCancellationOptions;\n private frameProcessor?: FrameProcessor<AudioFrame>;\n private frameSizeMs?: number;\n\n constructor(\n track: Track,\n sampleRateOrOptions?: number | AudioStreamOptions,\n numChannels?: number,\n ) {\n if (sampleRateOrOptions !== undefined && typeof sampleRateOrOptions !== 'number') {\n this.sampleRate = sampleRateOrOptions.sampleRate ?? 48000;\n this.numChannels = sampleRateOrOptions.numChannels ?? 1;\n if (sampleRateOrOptions.noiseCancellation instanceof FrameProcessor) {\n this.frameProcessor = sampleRateOrOptions.noiseCancellation;\n } else {\n this.legacyNcOptions = sampleRateOrOptions.noiseCancellation;\n }\n this.frameSizeMs = sampleRateOrOptions.frameSizeMs;\n } else {\n this.sampleRate = (sampleRateOrOptions as number) ?? 48000;\n this.numChannels = numChannels ?? 1;\n }\n\n const req = new NewAudioStreamRequest({\n type: AudioStreamType.AUDIO_STREAM_NATIVE,\n trackHandle: track.ffi_handle.handle,\n sampleRate: this.sampleRate,\n numChannels: this.numChannels,\n frameSizeMs: this.frameSizeMs,\n ...(this.legacyNcOptions\n ? {\n audioFilterModuleId: this.legacyNcOptions.moduleId,\n audioFilterOptions: JSON.stringify(this.legacyNcOptions.options),\n }\n : {}),\n });\n\n const res = FfiClient.instance.request<NewAudioStreamResponse>({\n message: {\n case: 'newAudioStream',\n value: req,\n },\n });\n\n this.ffiHandle = new FfiHandle(res.stream!.handle!.id!);\n\n FfiClient.instance.on(FfiClientEvent.FfiEvent, this.onEvent);\n }\n\n private onEvent = (ev: FfiEvent) => {\n if (!this.controller) {\n throw new Error('Stream controller not initialized');\n }\n\n if (\n ev.message.case != 'audioStreamEvent' ||\n ev.message.value.streamHandle != this.ffiHandle.handle\n ) {\n return;\n }\n\n const streamEvent = ev.message.value.message;\n switch (streamEvent.case) {\n case 'frameReceived':\n let frame = AudioFrame.fromOwnedInfo(streamEvent.value.frame!);\n if (this.frameProcessor && this.frameProcessor.isEnabled()) {\n try {\n frame = this.frameProcessor.process(frame);\n } catch (err: unknown) {\n log.warn(`Frame processing failed, passing through original frame: ${err}`);\n }\n }\n this.controller.enqueue(frame);\n break;\n case 'eos':\n FfiClient.instance.off(FfiClientEvent.FfiEvent, this.onEvent);\n this.controller.close();\n this.frameProcessor?.close();\n break;\n }\n };\n\n start(controller: ReadableStreamDefaultController<AudioFrame>) {\n this.controller = controller;\n }\n\n cancel() {\n FfiClient.instance.off(FfiClientEvent.FfiEvent, this.onEvent);\n this.ffiHandle.dispose();\n }\n}\n\nexport class AudioStream extends ReadableStream<AudioFrame> {\n constructor(track: Track);\n constructor(track: Track, sampleRate: number);\n constructor(track: Track, sampleRate: number, numChannels: number);\n constructor(track: Track, options: AudioStreamOptions);\n constructor(\n track: Track,\n sampleRateOrOptions?: number | AudioStreamOptions,\n numChannels?: number,\n ) {\n super(new AudioStreamSource(track, sampleRateOrOptions, numChannels));\n }\n}\n"],"mappings":"AAIA,SAAS,kBAAkB;AAE3B,SAAS,WAAW,gBAAgB,iBAAiB;AACrD,SAAS,sBAAsB;AAC/B,SAAS,WAAW;AAEpB,SAAS,iBAAiB,6BAA6B;AAgBvD,MAAM,kBAA0D;AAAA,EAS9D,YACE,OACA,qBACA,aACA;AAyCF,SAAQ,UAAU,CAAC,OAAiB;AAhFtC;AAiFI,UAAI,CAAC,KAAK,YAAY;AACpB,cAAM,IAAI,MAAM,mCAAmC;AAAA,MACrD;AAEA,UACE,GAAG,QAAQ,QAAQ,sBACnB,GAAG,QAAQ,MAAM,gBAAgB,KAAK,UAAU,QAChD;AACA;AAAA,MACF;AAEA,YAAM,cAAc,GAAG,QAAQ,MAAM;AACrC,cAAQ,YAAY,MAAM;AAAA,QACxB,KAAK;AACH,cAAI,QAAQ,WAAW,cAAc,YAAY,MAAM,KAAM;AAC7D,cAAI,KAAK,kBAAkB,KAAK,eAAe,UAAU,GAAG;AAC1D,gBAAI;AACF,sBAAQ,KAAK,eAAe,QAAQ,KAAK;AAAA,YAC3C,SAAS,KAAc;AACrB,kBAAI,KAAK,4DAA4D,GAAG,EAAE;AAAA,YAC5E;AAAA,UACF;AACA,eAAK,WAAW,QAAQ,KAAK;AAC7B;AAAA,QACF,KAAK;AACH,oBAAU,SAAS,IAAI,eAAe,UAAU,KAAK,OAAO;AAC5D,eAAK,WAAW,MAAM;AACtB,qBAAK,mBAAL,mBAAqB;AACrB;AAAA,MACJ;AAAA,IACF;AAvEE,QAAI,wBAAwB,UAAa,OAAO,wBAAwB,UAAU;AAChF,WAAK,aAAa,oBAAoB,cAAc;AACpD,WAAK,cAAc,oBAAoB,eAAe;AACtD,UAAI,oBAAoB,6BAA6B,gBAAgB;AACnE,aAAK,iBAAiB,oBAAoB;AAAA,MAC5C,OAAO;AACL,aAAK,kBAAkB,oBAAoB;AAAA,MAC7C;AACA,WAAK,cAAc,oBAAoB;AAAA,IACzC,OAAO;AACL,WAAK,aAAc,uBAAkC;AACrD,WAAK,cAAc,eAAe;AAAA,IACpC;AAEA,UAAM,MAAM,IAAI,sBAAsB;AAAA,MACpC,MAAM,gBAAgB;AAAA,MACtB,aAAa,MAAM,WAAW;AAAA,MAC9B,YAAY,KAAK;AAAA,MACjB,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,MAClB,GAAI,KAAK,kBACL;AAAA,QACE,qBAAqB,KAAK,gBAAgB;AAAA,QAC1C,oBAAoB,KAAK,UAAU,KAAK,gBAAgB,OAAO;AAAA,MACjE,IACA,CAAC;AAAA,IACP,CAAC;AAED,UAAM,MAAM,UAAU,SAAS,QAAgC;AAAA,MAC7D,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAED,SAAK,YAAY,IAAI,UAAU,IAAI,OAAQ,OAAQ,EAAG;AAEtD,cAAU,SAAS,GAAG,eAAe,UAAU,KAAK,OAAO;AAAA,EAC7D;AAAA,EAmCA,MAAM,YAAyD;AAC7D,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,SAAS;AACP,cAAU,SAAS,IAAI,eAAe,UAAU,KAAK,OAAO;AAC5D,SAAK,UAAU,QAAQ;AAAA,EACzB;AACF;AAEO,MAAM,oBAAoB,eAA2B;AAAA,EAK1D,YACE,OACA,qBACA,aACA;AACA,UAAM,IAAI,kBAAkB,OAAO,qBAAqB,WAAW,CAAC;AAAA,EACtE;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/audio_stream.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { NewAudioStreamResponse } from '@livekit/rtc-ffi-bindings';\nimport { AudioStreamType, NewAudioStreamRequest } from '@livekit/rtc-ffi-bindings';\nimport type { UnderlyingSource } from 'node:stream/web';\nimport { AudioFrame } from './audio_frame.js';\nimport type { FfiEvent } from './ffi_client.js';\nimport { FfiClient, FfiClientEvent, FfiHandle } from './ffi_client.js';\nimport { type FrameProcessor, isFrameProcessor } from './frame_processor.js';\nimport { log } from './log.js';\nimport type { Track } from './track.js';\n\nexport interface AudioStreamOptions {\n noiseCancellation?: NoiseCancellationOptions | FrameProcessor<AudioFrame>;\n sampleRate?: number;\n numChannels?: number;\n frameSizeMs?: number;\n}\n\nexport interface NoiseCancellationOptions {\n moduleId: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n options: Record<string, any>;\n}\n\nclass AudioStreamSource implements UnderlyingSource<AudioFrame> {\n private controller?: ReadableStreamDefaultController<AudioFrame>;\n private ffiHandle: FfiHandle;\n private disposed = false;\n private sampleRate: number;\n private numChannels: number;\n private legacyNcOptions?: NoiseCancellationOptions;\n private frameProcessor?: FrameProcessor<AudioFrame>;\n private frameSizeMs?: number;\n\n constructor(\n track: Track,\n sampleRateOrOptions?: number | AudioStreamOptions,\n numChannels?: number,\n ) {\n if (sampleRateOrOptions !== undefined && typeof sampleRateOrOptions !== 'number') {\n this.sampleRate = sampleRateOrOptions.sampleRate ?? 48000;\n this.numChannels = sampleRateOrOptions.numChannels ?? 1;\n if (isFrameProcessor(sampleRateOrOptions.noiseCancellation)) {\n this.frameProcessor = sampleRateOrOptions.noiseCancellation;\n } else {\n this.legacyNcOptions = sampleRateOrOptions.noiseCancellation;\n }\n this.frameSizeMs = sampleRateOrOptions.frameSizeMs;\n } else {\n this.sampleRate = (sampleRateOrOptions as number) ?? 48000;\n this.numChannels = numChannels ?? 1;\n }\n\n const req = new NewAudioStreamRequest({\n type: AudioStreamType.AUDIO_STREAM_NATIVE,\n trackHandle: track.ffi_handle.handle,\n sampleRate: this.sampleRate,\n numChannels: this.numChannels,\n frameSizeMs: this.frameSizeMs,\n ...(this.legacyNcOptions\n ? {\n audioFilterModuleId: this.legacyNcOptions.moduleId,\n audioFilterOptions: JSON.stringify(this.legacyNcOptions.options),\n }\n : {}),\n });\n\n const res = FfiClient.instance.request<NewAudioStreamResponse>({\n message: {\n case: 'newAudioStream',\n value: req,\n },\n });\n\n this.ffiHandle = new FfiHandle(res.stream!.handle!.id!);\n\n FfiClient.instance.on(FfiClientEvent.FfiEvent, this.onEvent);\n }\n\n private onEvent = (ev: FfiEvent) => {\n if (!this.controller) {\n throw new Error('Stream controller not initialized');\n }\n\n if (\n ev.message.case != 'audioStreamEvent' ||\n ev.message.value.streamHandle != this.ffiHandle.handle\n ) {\n return;\n }\n\n const streamEvent = ev.message.value.message;\n switch (streamEvent.case) {\n case 'frameReceived':\n let frame = AudioFrame.fromOwnedInfo(streamEvent.value.frame!);\n if (this.frameProcessor && this.frameProcessor.isEnabled()) {\n try {\n frame = this.frameProcessor.process(frame);\n } catch (err: unknown) {\n log.warn(`Frame processing failed, passing through original frame: ${err}`);\n }\n }\n this.controller.enqueue(frame);\n break;\n case 'eos':\n FfiClient.instance.off(FfiClientEvent.FfiEvent, this.onEvent);\n this.controller.close();\n // Dispose the native handle so the FD is released on stream end,\n // not just when cancel() is called explicitly by the consumer.\n // Guard against double-dispose if cancel() is called after EOS\n // while buffered frames are still in the ReadableStream queue.\n if (!this.disposed) {\n this.disposed = true;\n this.ffiHandle.dispose();\n this.frameProcessor?.close();\n }\n break;\n }\n };\n\n start(controller: ReadableStreamDefaultController<AudioFrame>) {\n this.controller = controller;\n }\n\n cancel() {\n FfiClient.instance.off(FfiClientEvent.FfiEvent, this.onEvent);\n if (!this.disposed) {\n this.disposed = true;\n this.ffiHandle.dispose();\n // Also close the frame processor on cancel for symmetry with the EOS path,\n // so resources are released regardless of how the stream ends.\n this.frameProcessor?.close();\n }\n }\n}\n\nexport class AudioStream extends ReadableStream<AudioFrame> {\n constructor(track: Track);\n constructor(track: Track, sampleRate: number);\n constructor(track: Track, sampleRate: number, numChannels: number);\n constructor(track: Track, options: AudioStreamOptions);\n constructor(\n track: Track,\n sampleRateOrOptions?: number | AudioStreamOptions,\n numChannels?: number,\n ) {\n super(new AudioStreamSource(track, sampleRateOrOptions, numChannels));\n }\n}\n"],"mappings":"AAIA,SAAS,iBAAiB,6BAA6B;AAEvD,SAAS,kBAAkB;AAE3B,SAAS,WAAW,gBAAgB,iBAAiB;AACrD,SAA8B,wBAAwB;AACtD,SAAS,WAAW;AAgBpB,MAAM,kBAA0D;AAAA,EAU9D,YACE,OACA,qBACA,aACA;AAXF,SAAQ,WAAW;AAoDnB,SAAQ,UAAU,CAAC,OAAiB;AAjFtC;AAkFI,UAAI,CAAC,KAAK,YAAY;AACpB,cAAM,IAAI,MAAM,mCAAmC;AAAA,MACrD;AAEA,UACE,GAAG,QAAQ,QAAQ,sBACnB,GAAG,QAAQ,MAAM,gBAAgB,KAAK,UAAU,QAChD;AACA;AAAA,MACF;AAEA,YAAM,cAAc,GAAG,QAAQ,MAAM;AACrC,cAAQ,YAAY,MAAM;AAAA,QACxB,KAAK;AACH,cAAI,QAAQ,WAAW,cAAc,YAAY,MAAM,KAAM;AAC7D,cAAI,KAAK,kBAAkB,KAAK,eAAe,UAAU,GAAG;AAC1D,gBAAI;AACF,sBAAQ,KAAK,eAAe,QAAQ,KAAK;AAAA,YAC3C,SAAS,KAAc;AACrB,kBAAI,KAAK,4DAA4D,GAAG,EAAE;AAAA,YAC5E;AAAA,UACF;AACA,eAAK,WAAW,QAAQ,KAAK;AAC7B;AAAA,QACF,KAAK;AACH,oBAAU,SAAS,IAAI,eAAe,UAAU,KAAK,OAAO;AAC5D,eAAK,WAAW,MAAM;AAKtB,cAAI,CAAC,KAAK,UAAU;AAClB,iBAAK,WAAW;AAChB,iBAAK,UAAU,QAAQ;AACvB,uBAAK,mBAAL,mBAAqB;AAAA,UACvB;AACA;AAAA,MACJ;AAAA,IACF;AA/EE,QAAI,wBAAwB,UAAa,OAAO,wBAAwB,UAAU;AAChF,WAAK,aAAa,oBAAoB,cAAc;AACpD,WAAK,cAAc,oBAAoB,eAAe;AACtD,UAAI,iBAAiB,oBAAoB,iBAAiB,GAAG;AAC3D,aAAK,iBAAiB,oBAAoB;AAAA,MAC5C,OAAO;AACL,aAAK,kBAAkB,oBAAoB;AAAA,MAC7C;AACA,WAAK,cAAc,oBAAoB;AAAA,IACzC,OAAO;AACL,WAAK,aAAc,uBAAkC;AACrD,WAAK,cAAc,eAAe;AAAA,IACpC;AAEA,UAAM,MAAM,IAAI,sBAAsB;AAAA,MACpC,MAAM,gBAAgB;AAAA,MACtB,aAAa,MAAM,WAAW;AAAA,MAC9B,YAAY,KAAK;AAAA,MACjB,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,MAClB,GAAI,KAAK,kBACL;AAAA,QACE,qBAAqB,KAAK,gBAAgB;AAAA,QAC1C,oBAAoB,KAAK,UAAU,KAAK,gBAAgB,OAAO;AAAA,MACjE,IACA,CAAC;AAAA,IACP,CAAC;AAED,UAAM,MAAM,UAAU,SAAS,QAAgC;AAAA,MAC7D,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAED,SAAK,YAAY,IAAI,UAAU,IAAI,OAAQ,OAAQ,EAAG;AAEtD,cAAU,SAAS,GAAG,eAAe,UAAU,KAAK,OAAO;AAAA,EAC7D;AAAA,EA2CA,MAAM,YAAyD;AAC7D,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,SAAS;AA9HX;AA+HI,cAAU,SAAS,IAAI,eAAe,UAAU,KAAK,OAAO;AAC5D,QAAI,CAAC,KAAK,UAAU;AAClB,WAAK,WAAW;AAChB,WAAK,UAAU,QAAQ;AAGvB,iBAAK,mBAAL,mBAAqB;AAAA,IACvB;AAAA,EACF;AACF;AAEO,MAAM,oBAAoB,eAA2B;AAAA,EAK1D,YACE,OACA,qBACA,aACA;AACA,UAAM,IAAI,kBAAkB,OAAO,qBAAqB,WAAW,CAAC;AAAA,EACtE;AACF;","names":[]}
@@ -1,11 +1,3 @@
1
- export { a as BaseStreamInfo, f as ByteStreamHandler, b as ByteStreamInfo, e as ByteStreamOptions, B as ByteStreamReader, D as DataStreamOptions, S as StreamController, g as TextStreamHandler, c as TextStreamInfo, d as TextStreamOptions, T as TextStreamReader } from '../stream_reader-Ch2zvjU3.cjs';
1
+ export { a as BaseStreamInfo, f as ByteStreamHandler, b as ByteStreamInfo, e as ByteStreamOptions, B as ByteStreamReader, D as DataStreamOptions, S as StreamController, g as TextStreamHandler, c as TextStreamInfo, d as TextStreamOptions, T as TextStreamReader } from '../stream_reader-CuG4b8Y-.cjs';
2
2
  export { ByteStreamWriter, TextStreamWriter } from './stream_writer.cjs';
3
- import '../proto/room_pb.cjs';
4
- import '@bufbuild/protobuf';
5
- import '../proto/participant_pb.cjs';
6
- import '../proto/handle_pb.cjs';
7
- import '../proto/track_pb.cjs';
8
- import '../proto/stats_pb.cjs';
9
- import '../proto/e2ee_pb.cjs';
10
- import '../proto/video_frame_pb.cjs';
11
- import '../proto/data_stream_pb.cjs';
3
+ import '@livekit/rtc-ffi-bindings';
@@ -1,11 +1,3 @@
1
- export { a as BaseStreamInfo, f as ByteStreamHandler, b as ByteStreamInfo, e as ByteStreamOptions, B as ByteStreamReader, D as DataStreamOptions, S as StreamController, g as TextStreamHandler, c as TextStreamInfo, d as TextStreamOptions, T as TextStreamReader } from '../stream_reader-DRyR29vo.js';
1
+ export { a as BaseStreamInfo, f as ByteStreamHandler, b as ByteStreamInfo, e as ByteStreamOptions, B as ByteStreamReader, D as DataStreamOptions, S as StreamController, g as TextStreamHandler, c as TextStreamInfo, d as TextStreamOptions, T as TextStreamReader } from '../stream_reader-CuG4b8Y-.js';
2
2
  export { ByteStreamWriter, TextStreamWriter } from './stream_writer.js';
3
- import '../proto/room_pb.js';
4
- import '@bufbuild/protobuf';
5
- import '../proto/participant_pb.js';
6
- import '../proto/handle_pb.js';
7
- import '../proto/track_pb.js';
8
- import '../proto/stats_pb.js';
9
- import '../proto/e2ee_pb.js';
10
- import '../proto/video_frame_pb.js';
11
- import '../proto/data_stream_pb.js';
3
+ import '@livekit/rtc-ffi-bindings';
@@ -49,12 +49,14 @@ class ByteStreamReader extends BaseStreamReader {
49
49
  try {
50
50
  const { done, value } = await reader.read();
51
51
  if (done) {
52
+ reader.releaseLock();
52
53
  return { done: true, value: void 0 };
53
54
  } else {
54
55
  this.handleChunkReceived(value);
55
56
  return { done: false, value: value.content };
56
57
  }
57
58
  } catch (error) {
59
+ reader.releaseLock();
58
60
  import_log.log.error("error processing stream update: %s", error);
59
61
  return { done: true, value: void 0 };
60
62
  }
@@ -101,11 +103,14 @@ class TextStreamReader extends BaseStreamReader {
101
103
  [Symbol.asyncIterator]() {
102
104
  const reader = this.reader.getReader();
103
105
  const decoder = new TextDecoder();
106
+ const receivedChunks = this.receivedChunks;
104
107
  return {
105
108
  next: async () => {
106
109
  try {
107
110
  const { done, value } = await reader.read();
108
111
  if (done) {
112
+ reader.releaseLock();
113
+ receivedChunks.clear();
109
114
  return { done: true, value: void 0 };
110
115
  } else {
111
116
  this.handleChunkReceived(value);
@@ -115,12 +120,15 @@ class TextStreamReader extends BaseStreamReader {
115
120
  };
116
121
  }
117
122
  } catch (error) {
123
+ reader.releaseLock();
124
+ receivedChunks.clear();
118
125
  import_log.log.error("error processing stream update: %s", error);
119
126
  return { done: true, value: void 0 };
120
127
  }
121
128
  },
122
129
  return() {
123
130
  reader.releaseLock();
131
+ receivedChunks.clear();
124
132
  return { done: true, value: void 0 };
125
133
  }
126
134
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/data_streams/stream_reader.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { log } from '../log.js';\nimport type { DataStream_Chunk } from '../proto/room_pb.js';\nimport { bigIntToNumber } from '../utils.js';\nimport type { BaseStreamInfo, ByteStreamInfo, TextStreamInfo } from './types.js';\n\nabstract class BaseStreamReader<T extends BaseStreamInfo> {\n protected reader: ReadableStream<DataStream_Chunk>;\n\n protected totalByteSize?: number;\n\n protected _info: T;\n\n protected bytesReceived: number;\n\n get info() {\n return this._info;\n }\n\n constructor(info: T, stream: ReadableStream<DataStream_Chunk>, totalByteSize?: number) {\n this.reader = stream;\n this.totalByteSize = totalByteSize;\n this._info = info;\n this.bytesReceived = 0;\n }\n\n protected abstract handleChunkReceived(chunk: DataStream_Chunk): void;\n\n onProgress?: (progress: number | undefined) => void;\n\n abstract readAll(): Promise<string | Array<Uint8Array>>;\n}\n\n/**\n * A class to read chunks from a ReadableStream and provide them in a structured format.\n */\nexport class ByteStreamReader extends BaseStreamReader<ByteStreamInfo> {\n protected handleChunkReceived(chunk: DataStream_Chunk) {\n this.bytesReceived += chunk.content!.byteLength;\n const currentProgress = this.totalByteSize\n ? this.bytesReceived / this.totalByteSize\n : undefined;\n this.onProgress?.(currentProgress);\n }\n\n [Symbol.asyncIterator]() {\n const reader = this.reader.getReader();\n\n return {\n next: async (): Promise<IteratorResult<Uint8Array>> => {\n try {\n const { done, value } = await reader.read();\n if (done) {\n return { done: true, value: undefined as unknown };\n } else {\n this.handleChunkReceived(value);\n return { done: false, value: value.content! };\n }\n } catch (error: unknown) {\n log.error('error processing stream update: %s', error);\n return { done: true, value: undefined as unknown };\n }\n },\n\n return(): IteratorResult<Uint8Array> {\n reader.releaseLock();\n return { done: true, value: undefined };\n },\n };\n }\n\n async readAll(): Promise<Array<Uint8Array>> {\n const chunks: Set<Uint8Array> = new Set();\n for await (const chunk of this) {\n chunks.add(chunk);\n }\n return Array.from(chunks);\n }\n}\n\n/**\n * A class to read chunks from a ReadableStream and provide them in a structured format.\n */\nexport class TextStreamReader extends BaseStreamReader<TextStreamInfo> {\n private receivedChunks: Map<number, DataStream_Chunk>;\n\n /**\n * A TextStreamReader instance can be used as an AsyncIterator that returns the entire string\n * that has been received up to the current point in time.\n */\n constructor(\n info: TextStreamInfo,\n stream: ReadableStream<DataStream_Chunk>,\n totalChunkCount?: number,\n ) {\n super(info, stream, totalChunkCount);\n this.receivedChunks = new Map();\n }\n\n protected handleChunkReceived(chunk: DataStream_Chunk) {\n const index = bigIntToNumber(chunk.chunkIndex!);\n const previousChunkAtIndex = this.receivedChunks.get(index!);\n if (previousChunkAtIndex && previousChunkAtIndex.version! > chunk.version!) {\n // we have a newer version already, dropping the old one\n return;\n }\n this.receivedChunks.set(index, chunk);\n const currentProgress = this.totalByteSize\n ? this.receivedChunks.size / this.totalByteSize\n : undefined;\n this.onProgress?.(currentProgress);\n }\n\n /**\n * Async iterator implementation to allow usage of `for await...of` syntax.\n * Yields structured chunks from the stream.\n *\n */\n [Symbol.asyncIterator]() {\n const reader = this.reader.getReader();\n const decoder = new TextDecoder();\n\n return {\n next: async (): Promise<IteratorResult<string>> => {\n try {\n const { done, value } = await reader.read();\n if (done) {\n return { done: true, value: undefined };\n } else {\n this.handleChunkReceived(value);\n return {\n done: false,\n value: decoder.decode(value.content!),\n };\n }\n } catch (error: unknown) {\n log.error('error processing stream update: %s', error);\n return { done: true, value: undefined };\n }\n },\n\n return(): IteratorResult<string> {\n reader.releaseLock();\n return { done: true, value: undefined };\n },\n };\n }\n\n async readAll(): Promise<string> {\n let finalString: string = '';\n for await (const chunk of this) {\n finalString += chunk;\n }\n return finalString;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/data_streams/stream_reader.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { DataStream_Chunk } from '@livekit/rtc-ffi-bindings';\nimport { log } from '../log.js';\nimport { bigIntToNumber } from '../utils.js';\nimport type { BaseStreamInfo, ByteStreamInfo, TextStreamInfo } from './types.js';\n\nabstract class BaseStreamReader<T extends BaseStreamInfo> {\n protected reader: ReadableStream<DataStream_Chunk>;\n\n protected totalByteSize?: number;\n\n protected _info: T;\n\n protected bytesReceived: number;\n\n get info() {\n return this._info;\n }\n\n constructor(info: T, stream: ReadableStream<DataStream_Chunk>, totalByteSize?: number) {\n this.reader = stream;\n this.totalByteSize = totalByteSize;\n this._info = info;\n this.bytesReceived = 0;\n }\n\n protected abstract handleChunkReceived(chunk: DataStream_Chunk): void;\n\n onProgress?: (progress: number | undefined) => void;\n\n abstract readAll(): Promise<string | Array<Uint8Array>>;\n}\n\n/**\n * A class to read chunks from a ReadableStream and provide them in a structured format.\n */\nexport class ByteStreamReader extends BaseStreamReader<ByteStreamInfo> {\n protected handleChunkReceived(chunk: DataStream_Chunk) {\n this.bytesReceived += chunk.content!.byteLength;\n const currentProgress = this.totalByteSize\n ? this.bytesReceived / this.totalByteSize\n : undefined;\n this.onProgress?.(currentProgress);\n }\n\n [Symbol.asyncIterator]() {\n const reader = this.reader.getReader();\n\n return {\n next: async (): Promise<IteratorResult<Uint8Array>> => {\n try {\n const { done, value } = await reader.read();\n if (done) {\n // Release the lock when the stream is exhausted so the\n // underlying ReadableStream can be garbage-collected.\n reader.releaseLock();\n return { done: true, value: undefined as unknown };\n } else {\n this.handleChunkReceived(value);\n return { done: false, value: value.content! };\n }\n } catch (error: unknown) {\n // Release the lock on error so it doesn't stay held when the\n // consumer never calls return() (e.g. breaking out of for-await).\n reader.releaseLock();\n log.error('error processing stream update: %s', error);\n return { done: true, value: undefined as unknown };\n }\n },\n\n return(): IteratorResult<Uint8Array> {\n reader.releaseLock();\n return { done: true, value: undefined };\n },\n };\n }\n\n async readAll(): Promise<Array<Uint8Array>> {\n const chunks: Set<Uint8Array> = new Set();\n for await (const chunk of this) {\n chunks.add(chunk);\n }\n return Array.from(chunks);\n }\n}\n\n/**\n * A class to read chunks from a ReadableStream and provide them in a structured format.\n */\nexport class TextStreamReader extends BaseStreamReader<TextStreamInfo> {\n private receivedChunks: Map<number, DataStream_Chunk>;\n\n /**\n * A TextStreamReader instance can be used as an AsyncIterator that returns the entire string\n * that has been received up to the current point in time.\n */\n constructor(\n info: TextStreamInfo,\n stream: ReadableStream<DataStream_Chunk>,\n totalChunkCount?: number,\n ) {\n super(info, stream, totalChunkCount);\n this.receivedChunks = new Map();\n }\n\n protected handleChunkReceived(chunk: DataStream_Chunk) {\n const index = bigIntToNumber(chunk.chunkIndex!);\n const previousChunkAtIndex = this.receivedChunks.get(index!);\n if (previousChunkAtIndex && previousChunkAtIndex.version! > chunk.version!) {\n // we have a newer version already, dropping the old one\n return;\n }\n this.receivedChunks.set(index, chunk);\n const currentProgress = this.totalByteSize\n ? this.receivedChunks.size / this.totalByteSize\n : undefined;\n this.onProgress?.(currentProgress);\n }\n\n /**\n * Async iterator implementation to allow usage of `for await...of` syntax.\n * Yields structured chunks from the stream.\n *\n */\n [Symbol.asyncIterator]() {\n const reader = this.reader.getReader();\n const decoder = new TextDecoder();\n const receivedChunks = this.receivedChunks;\n\n return {\n next: async (): Promise<IteratorResult<string>> => {\n try {\n const { done, value } = await reader.read();\n if (done) {\n // Release the lock when the stream is exhausted so the\n // underlying ReadableStream can be garbage-collected.\n reader.releaseLock();\n // Clear received chunks so the buffered data can be GC'd.\n receivedChunks.clear();\n return { done: true, value: undefined };\n } else {\n this.handleChunkReceived(value);\n return {\n done: false,\n value: decoder.decode(value.content!),\n };\n }\n } catch (error: unknown) {\n // Release the lock on error so it doesn't stay held when the\n // consumer never calls return() (e.g. breaking out of for-await).\n reader.releaseLock();\n receivedChunks.clear();\n log.error('error processing stream update: %s', error);\n return { done: true, value: undefined };\n }\n },\n\n return(): IteratorResult<string> {\n reader.releaseLock();\n // Clear received chunks so the buffered data can be GC'd.\n receivedChunks.clear();\n return { done: true, value: undefined };\n },\n };\n }\n\n async readAll(): Promise<string> {\n let finalString: string = '';\n for await (const chunk of this) {\n finalString += chunk;\n }\n return finalString;\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,10 +1,2 @@
1
- import '../proto/room_pb.cjs';
2
- export { B as ByteStreamReader, T as TextStreamReader } from '../stream_reader-Ch2zvjU3.cjs';
3
- import '@bufbuild/protobuf';
4
- import '../proto/participant_pb.cjs';
5
- import '../proto/handle_pb.cjs';
6
- import '../proto/track_pb.cjs';
7
- import '../proto/stats_pb.cjs';
8
- import '../proto/e2ee_pb.cjs';
9
- import '../proto/video_frame_pb.cjs';
10
- import '../proto/data_stream_pb.cjs';
1
+ import '@livekit/rtc-ffi-bindings';
2
+ export { B as ByteStreamReader, T as TextStreamReader } from '../stream_reader-CuG4b8Y-.cjs';
@@ -1,10 +1,2 @@
1
- import '../proto/room_pb.js';
2
- export { B as ByteStreamReader, T as TextStreamReader } from '../stream_reader-DRyR29vo.js';
3
- import '@bufbuild/protobuf';
4
- import '../proto/participant_pb.js';
5
- import '../proto/handle_pb.js';
6
- import '../proto/track_pb.js';
7
- import '../proto/stats_pb.js';
8
- import '../proto/e2ee_pb.js';
9
- import '../proto/video_frame_pb.js';
10
- import '../proto/data_stream_pb.js';
1
+ import '@livekit/rtc-ffi-bindings';
2
+ export { B as ByteStreamReader, T as TextStreamReader } from '../stream_reader-CuG4b8Y-.js';
@@ -1 +1 @@
1
- {"version":3,"file":"stream_reader.d.ts","sourceRoot":"","sources":["../../src/data_streams/stream_reader.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjF,uBAAe,gBAAgB,CAAC,CAAC,SAAS,cAAc;IACtD,SAAS,CAAC,MAAM,EAAE,cAAc,CAAC,gBAAgB,CAAC,CAAC;IAEnD,SAAS,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAEjC,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC;IAEnB,SAAS,CAAC,aAAa,EAAE,MAAM,CAAC;IAEhC,IAAI,IAAI,MAEP;gBAEW,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,gBAAgB,CAAC,EAAE,aAAa,CAAC,EAAE,MAAM;IAOrF,SAAS,CAAC,QAAQ,CAAC,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IAErE,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAEpD,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;CACxD;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,gBAAgB,CAAC,cAAc,CAAC;IACpE,SAAS,CAAC,mBAAmB,CAAC,KAAK,EAAE,gBAAgB;IAQrD,CAAC,MAAM,CAAC,aAAa,CAAC;oBAIF,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;kBAezC,cAAc,CAAC,UAAU,CAAC;;IAOlC,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;CAO5C;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,gBAAgB,CAAC,cAAc,CAAC;IACpE,OAAO,CAAC,cAAc,CAAgC;IAEtD;;;OAGG;gBAED,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,cAAc,CAAC,gBAAgB,CAAC,EACxC,eAAe,CAAC,EAAE,MAAM;IAM1B,SAAS,CAAC,mBAAmB,CAAC,KAAK,EAAE,gBAAgB;IAcrD;;;;OAIG;IACH,CAAC,MAAM,CAAC,aAAa,CAAC;oBAKF,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;kBAkBrC,cAAc,CAAC,MAAM,CAAC;;IAO9B,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;CAOjC"}
1
+ {"version":3,"file":"stream_reader.d.ts","sourceRoot":"","sources":["../../src/data_streams/stream_reader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAGlE,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjF,uBAAe,gBAAgB,CAAC,CAAC,SAAS,cAAc;IACtD,SAAS,CAAC,MAAM,EAAE,cAAc,CAAC,gBAAgB,CAAC,CAAC;IAEnD,SAAS,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAEjC,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC;IAEnB,SAAS,CAAC,aAAa,EAAE,MAAM,CAAC;IAEhC,IAAI,IAAI,MAEP;gBAEW,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,gBAAgB,CAAC,EAAE,aAAa,CAAC,EAAE,MAAM;IAOrF,SAAS,CAAC,QAAQ,CAAC,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IAErE,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAEpD,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;CACxD;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,gBAAgB,CAAC,cAAc,CAAC;IACpE,SAAS,CAAC,mBAAmB,CAAC,KAAK,EAAE,gBAAgB;IAQrD,CAAC,MAAM,CAAC,aAAa,CAAC;oBAIF,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;kBAqBzC,cAAc,CAAC,UAAU,CAAC;;IAOlC,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;CAO5C;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,gBAAgB,CAAC,cAAc,CAAC;IACpE,OAAO,CAAC,cAAc,CAAgC;IAEtD;;;OAGG;gBAED,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,cAAc,CAAC,gBAAgB,CAAC,EACxC,eAAe,CAAC,EAAE,MAAM;IAM1B,SAAS,CAAC,mBAAmB,CAAC,KAAK,EAAE,gBAAgB;IAcrD;;;;OAIG;IACH,CAAC,MAAM,CAAC,aAAa,CAAC;oBAMF,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;kBA2BrC,cAAc,CAAC,MAAM,CAAC;;IAS9B,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;CAOjC"}
@@ -25,12 +25,14 @@ class ByteStreamReader extends BaseStreamReader {
25
25
  try {
26
26
  const { done, value } = await reader.read();
27
27
  if (done) {
28
+ reader.releaseLock();
28
29
  return { done: true, value: void 0 };
29
30
  } else {
30
31
  this.handleChunkReceived(value);
31
32
  return { done: false, value: value.content };
32
33
  }
33
34
  } catch (error) {
35
+ reader.releaseLock();
34
36
  log.error("error processing stream update: %s", error);
35
37
  return { done: true, value: void 0 };
36
38
  }
@@ -77,11 +79,14 @@ class TextStreamReader extends BaseStreamReader {
77
79
  [Symbol.asyncIterator]() {
78
80
  const reader = this.reader.getReader();
79
81
  const decoder = new TextDecoder();
82
+ const receivedChunks = this.receivedChunks;
80
83
  return {
81
84
  next: async () => {
82
85
  try {
83
86
  const { done, value } = await reader.read();
84
87
  if (done) {
88
+ reader.releaseLock();
89
+ receivedChunks.clear();
85
90
  return { done: true, value: void 0 };
86
91
  } else {
87
92
  this.handleChunkReceived(value);
@@ -91,12 +96,15 @@ class TextStreamReader extends BaseStreamReader {
91
96
  };
92
97
  }
93
98
  } catch (error) {
99
+ reader.releaseLock();
100
+ receivedChunks.clear();
94
101
  log.error("error processing stream update: %s", error);
95
102
  return { done: true, value: void 0 };
96
103
  }
97
104
  },
98
105
  return() {
99
106
  reader.releaseLock();
107
+ receivedChunks.clear();
100
108
  return { done: true, value: void 0 };
101
109
  }
102
110
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/data_streams/stream_reader.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { log } from '../log.js';\nimport type { DataStream_Chunk } from '../proto/room_pb.js';\nimport { bigIntToNumber } from '../utils.js';\nimport type { BaseStreamInfo, ByteStreamInfo, TextStreamInfo } from './types.js';\n\nabstract class BaseStreamReader<T extends BaseStreamInfo> {\n protected reader: ReadableStream<DataStream_Chunk>;\n\n protected totalByteSize?: number;\n\n protected _info: T;\n\n protected bytesReceived: number;\n\n get info() {\n return this._info;\n }\n\n constructor(info: T, stream: ReadableStream<DataStream_Chunk>, totalByteSize?: number) {\n this.reader = stream;\n this.totalByteSize = totalByteSize;\n this._info = info;\n this.bytesReceived = 0;\n }\n\n protected abstract handleChunkReceived(chunk: DataStream_Chunk): void;\n\n onProgress?: (progress: number | undefined) => void;\n\n abstract readAll(): Promise<string | Array<Uint8Array>>;\n}\n\n/**\n * A class to read chunks from a ReadableStream and provide them in a structured format.\n */\nexport class ByteStreamReader extends BaseStreamReader<ByteStreamInfo> {\n protected handleChunkReceived(chunk: DataStream_Chunk) {\n this.bytesReceived += chunk.content!.byteLength;\n const currentProgress = this.totalByteSize\n ? this.bytesReceived / this.totalByteSize\n : undefined;\n this.onProgress?.(currentProgress);\n }\n\n [Symbol.asyncIterator]() {\n const reader = this.reader.getReader();\n\n return {\n next: async (): Promise<IteratorResult<Uint8Array>> => {\n try {\n const { done, value } = await reader.read();\n if (done) {\n return { done: true, value: undefined as unknown };\n } else {\n this.handleChunkReceived(value);\n return { done: false, value: value.content! };\n }\n } catch (error: unknown) {\n log.error('error processing stream update: %s', error);\n return { done: true, value: undefined as unknown };\n }\n },\n\n return(): IteratorResult<Uint8Array> {\n reader.releaseLock();\n return { done: true, value: undefined };\n },\n };\n }\n\n async readAll(): Promise<Array<Uint8Array>> {\n const chunks: Set<Uint8Array> = new Set();\n for await (const chunk of this) {\n chunks.add(chunk);\n }\n return Array.from(chunks);\n }\n}\n\n/**\n * A class to read chunks from a ReadableStream and provide them in a structured format.\n */\nexport class TextStreamReader extends BaseStreamReader<TextStreamInfo> {\n private receivedChunks: Map<number, DataStream_Chunk>;\n\n /**\n * A TextStreamReader instance can be used as an AsyncIterator that returns the entire string\n * that has been received up to the current point in time.\n */\n constructor(\n info: TextStreamInfo,\n stream: ReadableStream<DataStream_Chunk>,\n totalChunkCount?: number,\n ) {\n super(info, stream, totalChunkCount);\n this.receivedChunks = new Map();\n }\n\n protected handleChunkReceived(chunk: DataStream_Chunk) {\n const index = bigIntToNumber(chunk.chunkIndex!);\n const previousChunkAtIndex = this.receivedChunks.get(index!);\n if (previousChunkAtIndex && previousChunkAtIndex.version! > chunk.version!) {\n // we have a newer version already, dropping the old one\n return;\n }\n this.receivedChunks.set(index, chunk);\n const currentProgress = this.totalByteSize\n ? this.receivedChunks.size / this.totalByteSize\n : undefined;\n this.onProgress?.(currentProgress);\n }\n\n /**\n * Async iterator implementation to allow usage of `for await...of` syntax.\n * Yields structured chunks from the stream.\n *\n */\n [Symbol.asyncIterator]() {\n const reader = this.reader.getReader();\n const decoder = new TextDecoder();\n\n return {\n next: async (): Promise<IteratorResult<string>> => {\n try {\n const { done, value } = await reader.read();\n if (done) {\n return { done: true, value: undefined };\n } else {\n this.handleChunkReceived(value);\n return {\n done: false,\n value: decoder.decode(value.content!),\n };\n }\n } catch (error: unknown) {\n log.error('error processing stream update: %s', error);\n return { done: true, value: undefined };\n }\n },\n\n return(): IteratorResult<string> {\n reader.releaseLock();\n return { done: true, value: undefined };\n },\n };\n }\n\n async readAll(): Promise<string> {\n let finalString: string = '';\n for await (const chunk of this) {\n finalString += chunk;\n }\n return finalString;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/data_streams/stream_reader.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { DataStream_Chunk } from '@livekit/rtc-ffi-bindings';\nimport { log } from '../log.js';\nimport { bigIntToNumber } from '../utils.js';\nimport type { BaseStreamInfo, ByteStreamInfo, TextStreamInfo } from './types.js';\n\nabstract class BaseStreamReader<T extends BaseStreamInfo> {\n protected reader: ReadableStream<DataStream_Chunk>;\n\n protected totalByteSize?: number;\n\n protected _info: T;\n\n protected bytesReceived: number;\n\n get info() {\n return this._info;\n }\n\n constructor(info: T, stream: ReadableStream<DataStream_Chunk>, totalByteSize?: number) {\n this.reader = stream;\n this.totalByteSize = totalByteSize;\n this._info = info;\n this.bytesReceived = 0;\n }\n\n protected abstract handleChunkReceived(chunk: DataStream_Chunk): void;\n\n onProgress?: (progress: number | undefined) => void;\n\n abstract readAll(): Promise<string | Array<Uint8Array>>;\n}\n\n/**\n * A class to read chunks from a ReadableStream and provide them in a structured format.\n */\nexport class ByteStreamReader extends BaseStreamReader<ByteStreamInfo> {\n protected handleChunkReceived(chunk: DataStream_Chunk) {\n this.bytesReceived += chunk.content!.byteLength;\n const currentProgress = this.totalByteSize\n ? this.bytesReceived / this.totalByteSize\n : undefined;\n this.onProgress?.(currentProgress);\n }\n\n [Symbol.asyncIterator]() {\n const reader = this.reader.getReader();\n\n return {\n next: async (): Promise<IteratorResult<Uint8Array>> => {\n try {\n const { done, value } = await reader.read();\n if (done) {\n // Release the lock when the stream is exhausted so the\n // underlying ReadableStream can be garbage-collected.\n reader.releaseLock();\n return { done: true, value: undefined as unknown };\n } else {\n this.handleChunkReceived(value);\n return { done: false, value: value.content! };\n }\n } catch (error: unknown) {\n // Release the lock on error so it doesn't stay held when the\n // consumer never calls return() (e.g. breaking out of for-await).\n reader.releaseLock();\n log.error('error processing stream update: %s', error);\n return { done: true, value: undefined as unknown };\n }\n },\n\n return(): IteratorResult<Uint8Array> {\n reader.releaseLock();\n return { done: true, value: undefined };\n },\n };\n }\n\n async readAll(): Promise<Array<Uint8Array>> {\n const chunks: Set<Uint8Array> = new Set();\n for await (const chunk of this) {\n chunks.add(chunk);\n }\n return Array.from(chunks);\n }\n}\n\n/**\n * A class to read chunks from a ReadableStream and provide them in a structured format.\n */\nexport class TextStreamReader extends BaseStreamReader<TextStreamInfo> {\n private receivedChunks: Map<number, DataStream_Chunk>;\n\n /**\n * A TextStreamReader instance can be used as an AsyncIterator that returns the entire string\n * that has been received up to the current point in time.\n */\n constructor(\n info: TextStreamInfo,\n stream: ReadableStream<DataStream_Chunk>,\n totalChunkCount?: number,\n ) {\n super(info, stream, totalChunkCount);\n this.receivedChunks = new Map();\n }\n\n protected handleChunkReceived(chunk: DataStream_Chunk) {\n const index = bigIntToNumber(chunk.chunkIndex!);\n const previousChunkAtIndex = this.receivedChunks.get(index!);\n if (previousChunkAtIndex && previousChunkAtIndex.version! > chunk.version!) {\n // we have a newer version already, dropping the old one\n return;\n }\n this.receivedChunks.set(index, chunk);\n const currentProgress = this.totalByteSize\n ? this.receivedChunks.size / this.totalByteSize\n : undefined;\n this.onProgress?.(currentProgress);\n }\n\n /**\n * Async iterator implementation to allow usage of `for await...of` syntax.\n * Yields structured chunks from the stream.\n *\n */\n [Symbol.asyncIterator]() {\n const reader = this.reader.getReader();\n const decoder = new TextDecoder();\n const receivedChunks = this.receivedChunks;\n\n return {\n next: async (): Promise<IteratorResult<string>> => {\n try {\n const { done, value } = await reader.read();\n if (done) {\n // Release the lock when the stream is exhausted so the\n // underlying ReadableStream can be garbage-collected.\n reader.releaseLock();\n // Clear received chunks so the buffered data can be GC'd.\n receivedChunks.clear();\n return { done: true, value: undefined };\n } else {\n this.handleChunkReceived(value);\n return {\n done: false,\n value: decoder.decode(value.content!),\n };\n }\n } catch (error: unknown) {\n // Release the lock on error so it doesn't stay held when the\n // consumer never calls return() (e.g. breaking out of for-await).\n reader.releaseLock();\n receivedChunks.clear();\n log.error('error processing stream update: %s', error);\n return { done: true, value: undefined };\n }\n },\n\n return(): IteratorResult<string> {\n reader.releaseLock();\n // Clear received chunks so the buffered data can be GC'd.\n receivedChunks.clear();\n return { done: true, value: undefined };\n },\n };\n }\n\n async readAll(): Promise<string> {\n let finalString: string = '';\n for await (const chunk of this) {\n finalString += chunk;\n }\n return finalString;\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,13 +1,5 @@
1
- import { a as BaseStreamInfo, c as TextStreamInfo, b as ByteStreamInfo } from '../stream_reader-Ch2zvjU3.cjs';
2
- import '../proto/room_pb.cjs';
3
- import '@bufbuild/protobuf';
4
- import '../proto/participant_pb.cjs';
5
- import '../proto/handle_pb.cjs';
6
- import '../proto/track_pb.cjs';
7
- import '../proto/stats_pb.cjs';
8
- import '../proto/e2ee_pb.cjs';
9
- import '../proto/video_frame_pb.cjs';
10
- import '../proto/data_stream_pb.cjs';
1
+ import { a as BaseStreamInfo, c as TextStreamInfo, b as ByteStreamInfo } from '../stream_reader-CuG4b8Y-.cjs';
2
+ import '@livekit/rtc-ffi-bindings';
11
3
 
12
4
  declare class BaseStreamWriter<T, InfoType extends BaseStreamInfo> {
13
5
  protected writableStream: WritableStream<T>;
@@ -1,13 +1,5 @@
1
- import { a as BaseStreamInfo, c as TextStreamInfo, b as ByteStreamInfo } from '../stream_reader-DRyR29vo.js';
2
- import '../proto/room_pb.js';
3
- import '@bufbuild/protobuf';
4
- import '../proto/participant_pb.js';
5
- import '../proto/handle_pb.js';
6
- import '../proto/track_pb.js';
7
- import '../proto/stats_pb.js';
8
- import '../proto/e2ee_pb.js';
9
- import '../proto/video_frame_pb.js';
10
- import '../proto/data_stream_pb.js';
1
+ import { a as BaseStreamInfo, c as TextStreamInfo, b as ByteStreamInfo } from '../stream_reader-CuG4b8Y-.js';
2
+ import '@livekit/rtc-ffi-bindings';
11
3
 
12
4
  declare class BaseStreamWriter<T, InfoType extends BaseStreamInfo> {
13
5
  protected writableStream: WritableStream<T>;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/data_streams/types.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { DataStream_Chunk, DataStream_Header } from '../proto/room_pb.js';\nimport type { ByteStreamReader, TextStreamReader } from './stream_reader.js';\n\nexport interface StreamController<T extends DataStream_Chunk> {\n header: DataStream_Header;\n controller: ReadableStreamDefaultController<T>;\n startTime: number;\n endTime?: number;\n}\n\nexport interface BaseStreamInfo {\n streamId: string;\n mimeType: string;\n topic: string;\n timestamp: number;\n /** total size in bytes for finite streams and undefined for streams of unknown size */\n totalSize?: number;\n attributes?: Record<string, string>;\n}\n\nexport type ByteStreamInfo = BaseStreamInfo & {\n name: string;\n};\n\nexport type TextStreamInfo = BaseStreamInfo;\n\nexport interface DataStreamOptions {\n topic?: string;\n destinationIdentities?: Array<string>;\n attributes?: Record<string, string>;\n mimeType?: string;\n}\n\nexport interface TextStreamOptions extends DataStreamOptions {\n // replyToMessageId?: string;\n attachments?: [];\n}\n\nexport interface ByteStreamOptions extends DataStreamOptions {\n name?: string;\n onProgress?: (progress: number) => void;\n}\n\nexport type ByteStreamHandler = (\n reader: ByteStreamReader,\n participantInfo: { identity: string },\n) => void;\n\nexport type TextStreamHandler = (\n reader: TextStreamReader,\n participantInfo: { identity: string },\n) => void;\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../../src/data_streams/types.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { DataStream_Chunk, DataStream_Header } from '@livekit/rtc-ffi-bindings';\nimport type { ByteStreamReader, TextStreamReader } from './stream_reader.js';\n\nexport interface StreamController<T extends DataStream_Chunk> {\n header: DataStream_Header;\n controller: ReadableStreamDefaultController<T>;\n startTime: number;\n endTime?: number;\n}\n\nexport interface BaseStreamInfo {\n streamId: string;\n mimeType: string;\n topic: string;\n timestamp: number;\n /** total size in bytes for finite streams and undefined for streams of unknown size */\n totalSize?: number;\n attributes?: Record<string, string>;\n}\n\nexport type ByteStreamInfo = BaseStreamInfo & {\n name: string;\n};\n\nexport type TextStreamInfo = BaseStreamInfo;\n\nexport interface DataStreamOptions {\n topic?: string;\n destinationIdentities?: Array<string>;\n attributes?: Record<string, string>;\n mimeType?: string;\n}\n\nexport interface TextStreamOptions extends DataStreamOptions {\n // replyToMessageId?: string;\n attachments?: [];\n}\n\nexport interface ByteStreamOptions extends DataStreamOptions {\n name?: string;\n onProgress?: (progress: number) => void;\n}\n\nexport type ByteStreamHandler = (\n reader: ByteStreamReader,\n participantInfo: { identity: string },\n) => void;\n\nexport type TextStreamHandler = (\n reader: TextStreamReader,\n participantInfo: { identity: string },\n) => void;\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -1,10 +1,2 @@
1
- import '../proto/room_pb.cjs';
2
- export { a as BaseStreamInfo, f as ByteStreamHandler, b as ByteStreamInfo, e as ByteStreamOptions, D as DataStreamOptions, S as StreamController, g as TextStreamHandler, c as TextStreamInfo, d as TextStreamOptions } from '../stream_reader-Ch2zvjU3.cjs';
3
- import '@bufbuild/protobuf';
4
- import '../proto/participant_pb.cjs';
5
- import '../proto/handle_pb.cjs';
6
- import '../proto/track_pb.cjs';
7
- import '../proto/stats_pb.cjs';
8
- import '../proto/e2ee_pb.cjs';
9
- import '../proto/video_frame_pb.cjs';
10
- import '../proto/data_stream_pb.cjs';
1
+ import '@livekit/rtc-ffi-bindings';
2
+ export { a as BaseStreamInfo, f as ByteStreamHandler, b as ByteStreamInfo, e as ByteStreamOptions, D as DataStreamOptions, S as StreamController, g as TextStreamHandler, c as TextStreamInfo, d as TextStreamOptions } from '../stream_reader-CuG4b8Y-.cjs';
@@ -1,10 +1,2 @@
1
- import '../proto/room_pb.js';
2
- export { a as BaseStreamInfo, f as ByteStreamHandler, b as ByteStreamInfo, e as ByteStreamOptions, D as DataStreamOptions, S as StreamController, g as TextStreamHandler, c as TextStreamInfo, d as TextStreamOptions } from '../stream_reader-DRyR29vo.js';
3
- import '@bufbuild/protobuf';
4
- import '../proto/participant_pb.js';
5
- import '../proto/handle_pb.js';
6
- import '../proto/track_pb.js';
7
- import '../proto/stats_pb.js';
8
- import '../proto/e2ee_pb.js';
9
- import '../proto/video_frame_pb.js';
10
- import '../proto/data_stream_pb.js';
1
+ import '@livekit/rtc-ffi-bindings';
2
+ export { a as BaseStreamInfo, f as ByteStreamHandler, b as ByteStreamInfo, e as ByteStreamOptions, D as DataStreamOptions, S as StreamController, g as TextStreamHandler, c as TextStreamInfo, d as TextStreamOptions } from '../stream_reader-CuG4b8Y-.js';
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/data_streams/types.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE7E,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,gBAAgB;IAC1D,MAAM,EAAE,iBAAiB,CAAC;IAC1B,UAAU,EAAE,+BAA+B,CAAC,CAAC,CAAC,CAAC;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG;IAC5C,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,cAAc,CAAC;AAE5C,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAE1D,WAAW,CAAC,EAAE,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAED,MAAM,MAAM,iBAAiB,GAAG,CAC9B,MAAM,EAAE,gBAAgB,EACxB,eAAe,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,KAClC,IAAI,CAAC;AAEV,MAAM,MAAM,iBAAiB,GAAG,CAC9B,MAAM,EAAE,gBAAgB,EACxB,eAAe,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,KAClC,IAAI,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/data_streams/types.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACrF,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE7E,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,gBAAgB;IAC1D,MAAM,EAAE,iBAAiB,CAAC;IAC1B,UAAU,EAAE,+BAA+B,CAAC,CAAC,CAAC,CAAC;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG;IAC5C,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,cAAc,CAAC;AAE5C,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAE1D,WAAW,CAAC,EAAE,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAED,MAAM,MAAM,iBAAiB,GAAG,CAC9B,MAAM,EAAE,gBAAgB,EACxB,eAAe,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,KAClC,IAAI,CAAC;AAEV,MAAM,MAAM,iBAAiB,GAAG,CAC9B,MAAM,EAAE,gBAAgB,EACxB,eAAe,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,KAClC,IAAI,CAAC"}
package/dist/e2ee.cjs CHANGED
@@ -25,8 +25,8 @@ __export(e2ee_exports, {
25
25
  defaultKeyProviderOptions: () => defaultKeyProviderOptions
26
26
  });
27
27
  module.exports = __toCommonJS(e2ee_exports);
28
+ var import_rtc_ffi_bindings = require("@livekit/rtc-ffi-bindings");
28
29
  var import_ffi_client = require("./ffi_client.cjs");
29
- var import_e2ee_pb = require("./proto/e2ee_pb.cjs");
30
30
  const DEFAULT_RATCHET_SALT = new TextEncoder().encode("LKFrameEncryptionKey");
31
31
  const DEFAULT_RATCHET_WINDOW_SIZE = 16;
32
32
  const DEFAULT_FAILURE_TOLERANCE = -1;
@@ -37,7 +37,7 @@ const defaultKeyProviderOptions = {
37
37
  };
38
38
  const defaultE2EEOptions = {
39
39
  keyProviderOptions: defaultKeyProviderOptions,
40
- encryptionType: import_e2ee_pb.EncryptionType.GCM
40
+ encryptionType: import_rtc_ffi_bindings.EncryptionType.GCM
41
41
  };
42
42
  class KeyProvider {
43
43
  /** internal */
@@ -46,11 +46,11 @@ class KeyProvider {
46
46
  this.options = opts;
47
47
  }
48
48
  setSharedKey(sharedKey, keyIndex) {
49
- const req = new import_e2ee_pb.E2eeRequest({
49
+ const req = new import_rtc_ffi_bindings.E2eeRequest({
50
50
  roomHandle: this.roomHandle,
51
51
  message: {
52
52
  case: "setSharedKey",
53
- value: new import_e2ee_pb.SetSharedKeyRequest({
53
+ value: new import_rtc_ffi_bindings.SetSharedKeyRequest({
54
54
  keyIndex,
55
55
  sharedKey
56
56
  })
@@ -64,11 +64,11 @@ class KeyProvider {
64
64
  });
65
65
  }
66
66
  exportSharedKey(keyIndex) {
67
- const req = new import_e2ee_pb.E2eeRequest({
67
+ const req = new import_rtc_ffi_bindings.E2eeRequest({
68
68
  roomHandle: this.roomHandle,
69
69
  message: {
70
70
  case: "getSharedKey",
71
- value: new import_e2ee_pb.GetSharedKeyRequest({
71
+ value: new import_rtc_ffi_bindings.GetSharedKeyRequest({
72
72
  keyIndex
73
73
  })
74
74
  }
@@ -82,11 +82,11 @@ class KeyProvider {
82
82
  return res.message.value.key;
83
83
  }
84
84
  ratchetSharedKey(keyIndex) {
85
- const req = new import_e2ee_pb.E2eeRequest({
85
+ const req = new import_rtc_ffi_bindings.E2eeRequest({
86
86
  roomHandle: this.roomHandle,
87
87
  message: {
88
88
  case: "ratchetSharedKey",
89
- value: new import_e2ee_pb.RatchetSharedKeyRequest({
89
+ value: new import_rtc_ffi_bindings.RatchetSharedKeyRequest({
90
90
  keyIndex
91
91
  })
92
92
  }
@@ -100,11 +100,11 @@ class KeyProvider {
100
100
  return res.message.value.newKey;
101
101
  }
102
102
  setKey(participantIdentity, keyIndex) {
103
- const req = new import_e2ee_pb.E2eeRequest({
103
+ const req = new import_rtc_ffi_bindings.E2eeRequest({
104
104
  roomHandle: this.roomHandle,
105
105
  message: {
106
106
  case: "setKey",
107
- value: new import_e2ee_pb.SetKeyRequest({
107
+ value: new import_rtc_ffi_bindings.SetKeyRequest({
108
108
  keyIndex,
109
109
  participantIdentity
110
110
  })
@@ -118,11 +118,11 @@ class KeyProvider {
118
118
  });
119
119
  }
120
120
  exportKey(participantIdentity, keyIndex) {
121
- const req = new import_e2ee_pb.E2eeRequest({
121
+ const req = new import_rtc_ffi_bindings.E2eeRequest({
122
122
  roomHandle: this.roomHandle,
123
123
  message: {
124
124
  case: "getKey",
125
- value: new import_e2ee_pb.GetKeyRequest({
125
+ value: new import_rtc_ffi_bindings.GetKeyRequest({
126
126
  keyIndex,
127
127
  participantIdentity
128
128
  })
@@ -137,11 +137,11 @@ class KeyProvider {
137
137
  return res.message.value.key;
138
138
  }
139
139
  ratchetKey(participantIdentity, keyIndex) {
140
- const req = new import_e2ee_pb.E2eeRequest({
140
+ const req = new import_rtc_ffi_bindings.E2eeRequest({
141
141
  roomHandle: this.roomHandle,
142
142
  message: {
143
143
  case: "ratchetKey",
144
- value: new import_e2ee_pb.RatchetKeyRequest({
144
+ value: new import_rtc_ffi_bindings.RatchetKeyRequest({
145
145
  keyIndex,
146
146
  participantIdentity
147
147
  })
@@ -166,11 +166,11 @@ class FrameCryptor {
166
166
  }
167
167
  setEnabled(enabled) {
168
168
  this.enabled = enabled;
169
- const req = new import_e2ee_pb.E2eeRequest({
169
+ const req = new import_rtc_ffi_bindings.E2eeRequest({
170
170
  roomHandle: this.roomHandle,
171
171
  message: {
172
172
  case: "cryptorSetEnabled",
173
- value: new import_e2ee_pb.FrameCryptorSetEnabledRequest({
173
+ value: new import_rtc_ffi_bindings.FrameCryptorSetEnabledRequest({
174
174
  participantIdentity: this.participantIdentity,
175
175
  enabled: this.enabled
176
176
  })
@@ -185,11 +185,11 @@ class FrameCryptor {
185
185
  }
186
186
  setKeyIndex(keyIndex) {
187
187
  this.keyIndex = keyIndex;
188
- const req = new import_e2ee_pb.E2eeRequest({
188
+ const req = new import_rtc_ffi_bindings.E2eeRequest({
189
189
  roomHandle: this.roomHandle,
190
190
  message: {
191
191
  case: "cryptorSetKeyIndex",
192
- value: new import_e2ee_pb.FrameCryptorSetKeyIndexRequest({
192
+ value: new import_rtc_ffi_bindings.FrameCryptorSetKeyIndexRequest({
193
193
  participantIdentity: this.participantIdentity,
194
194
  keyIndex: this.keyIndex
195
195
  })
@@ -215,11 +215,11 @@ class E2EEManager {
215
215
  }
216
216
  setEnabled(enabled) {
217
217
  this.enabled = enabled;
218
- const req = new import_e2ee_pb.E2eeRequest({
218
+ const req = new import_rtc_ffi_bindings.E2eeRequest({
219
219
  roomHandle: this.roomHandle,
220
220
  message: {
221
221
  case: "managerSetEnabled",
222
- value: new import_e2ee_pb.E2eeManagerSetEnabledRequest({
222
+ value: new import_rtc_ffi_bindings.E2eeManagerSetEnabledRequest({
223
223
  enabled: this.enabled
224
224
  })
225
225
  }
@@ -232,7 +232,7 @@ class E2EEManager {
232
232
  });
233
233
  }
234
234
  frameCryptors() {
235
- const req = new import_e2ee_pb.E2eeRequest({
235
+ const req = new import_rtc_ffi_bindings.E2eeRequest({
236
236
  roomHandle: this.roomHandle,
237
237
  message: {
238
238
  case: "managerGetFrameCryptors",
package/dist/e2ee.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/e2ee.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { FfiClient } from './ffi_client.js';\nimport type {\n E2eeManagerGetFrameCryptorsResponse,\n E2eeResponse,\n GetKeyResponse,\n GetSharedKeyResponse,\n RatchetKeyResponse,\n RatchetSharedKeyResponse,\n} from './proto/e2ee_pb.js';\nimport {\n E2eeManagerSetEnabledRequest,\n E2eeRequest,\n EncryptionType,\n FrameCryptorSetEnabledRequest,\n FrameCryptorSetKeyIndexRequest,\n GetKeyRequest,\n GetSharedKeyRequest,\n RatchetKeyRequest,\n RatchetSharedKeyRequest,\n SetKeyRequest,\n SetSharedKeyRequest,\n} from './proto/e2ee_pb.js';\n\nconst DEFAULT_RATCHET_SALT = new TextEncoder().encode('LKFrameEncryptionKey');\nconst DEFAULT_RATCHET_WINDOW_SIZE = 16;\nconst DEFAULT_FAILURE_TOLERANCE = -1;\n\nexport interface KeyProviderOptions {\n sharedKey?: Uint8Array;\n ratchetSalt?: Uint8Array;\n ratchetWindowSize?: number;\n failureTolerance?: number;\n}\n\nexport const defaultKeyProviderOptions: KeyProviderOptions = {\n ratchetSalt: DEFAULT_RATCHET_SALT,\n ratchetWindowSize: DEFAULT_RATCHET_WINDOW_SIZE,\n failureTolerance: DEFAULT_FAILURE_TOLERANCE,\n};\n\nexport interface E2EEOptions {\n keyProviderOptions: KeyProviderOptions;\n encryptionType?: EncryptionType;\n}\n\nexport const defaultE2EEOptions: E2EEOptions = {\n keyProviderOptions: defaultKeyProviderOptions,\n encryptionType: EncryptionType.GCM,\n};\n\nexport class KeyProvider {\n private roomHandle: bigint;\n options: KeyProviderOptions;\n\n /** internal */\n constructor(roomHandle: bigint, opts: KeyProviderOptions) {\n this.roomHandle = roomHandle;\n this.options = opts;\n }\n\n setSharedKey(sharedKey: Uint8Array, keyIndex: number) {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'setSharedKey',\n value: new SetSharedKeyRequest({\n keyIndex: keyIndex,\n sharedKey: sharedKey,\n }),\n },\n });\n\n FfiClient.instance.request({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n }\n\n exportSharedKey(keyIndex: number): Uint8Array {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'getSharedKey',\n value: new GetSharedKeyRequest({\n keyIndex: keyIndex,\n }),\n },\n });\n\n const res = FfiClient.instance.request<E2eeResponse>({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n\n return (res.message.value as GetSharedKeyResponse).key!;\n }\n\n ratchetSharedKey(keyIndex: number): Uint8Array {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'ratchetSharedKey',\n value: new RatchetSharedKeyRequest({\n keyIndex: keyIndex,\n }),\n },\n });\n\n const res = FfiClient.instance.request<E2eeResponse>({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n\n return (res.message.value as RatchetSharedKeyResponse).newKey!;\n }\n\n setKey(participantIdentity: string, keyIndex: number) {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'setKey',\n value: new SetKeyRequest({\n keyIndex: keyIndex,\n participantIdentity: participantIdentity,\n }),\n },\n });\n\n FfiClient.instance.request({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n }\n\n exportKey(participantIdentity: string, keyIndex: number): Uint8Array {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'getKey',\n value: new GetKeyRequest({\n keyIndex: keyIndex,\n participantIdentity: participantIdentity,\n }),\n },\n });\n\n const res = FfiClient.instance.request<E2eeResponse>({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n\n return (res.message.value as GetKeyResponse).key!;\n }\n\n ratchetKey(participantIdentity: string, keyIndex: number): Uint8Array {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'ratchetKey',\n value: new RatchetKeyRequest({\n keyIndex: keyIndex,\n participantIdentity: participantIdentity,\n }),\n },\n });\n\n const res = FfiClient.instance.request<E2eeResponse>({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n\n return (res.message.value as RatchetKeyResponse).newKey!;\n }\n}\n\nexport class FrameCryptor {\n private roomHandle = BigInt(0);\n participantIdentity: string;\n keyIndex: number;\n enabled: boolean;\n\n constructor(roomHandle: bigint, participantIdentity: string, keyIndex: number, enabled: boolean) {\n this.roomHandle = roomHandle;\n this.participantIdentity = participantIdentity;\n this.keyIndex = keyIndex;\n this.enabled = enabled;\n }\n\n setEnabled(enabled: boolean) {\n this.enabled = enabled;\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'cryptorSetEnabled',\n value: new FrameCryptorSetEnabledRequest({\n participantIdentity: this.participantIdentity,\n enabled: this.enabled,\n }),\n },\n });\n\n FfiClient.instance.request({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n }\n\n setKeyIndex(keyIndex: number) {\n this.keyIndex = keyIndex;\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'cryptorSetKeyIndex',\n value: new FrameCryptorSetKeyIndexRequest({\n participantIdentity: this.participantIdentity,\n keyIndex: this.keyIndex,\n }),\n },\n });\n\n FfiClient.instance.request({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n }\n}\n\nexport class E2EEManager {\n private roomHandle = BigInt(0);\n private options: E2EEOptions;\n private keyProvider: KeyProvider;\n\n enabled: boolean;\n\n constructor(roomHandle: bigint, opts?: E2EEOptions) {\n this.roomHandle = roomHandle;\n this.enabled = opts !== undefined;\n\n opts ??= defaultE2EEOptions;\n const options = { ...defaultE2EEOptions, ...opts };\n\n this.options = options;\n this.keyProvider = new KeyProvider(roomHandle, options.keyProviderOptions);\n }\n\n setEnabled(enabled: boolean) {\n this.enabled = enabled;\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'managerSetEnabled',\n value: new E2eeManagerSetEnabledRequest({\n enabled: this.enabled,\n }),\n },\n });\n\n FfiClient.instance.request({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n }\n\n frameCryptors(): FrameCryptor[] {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'managerGetFrameCryptors',\n value: {},\n },\n });\n\n const res = FfiClient.instance.request<E2eeResponse>({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n\n const frameCryptors = (\n res.message.value as E2eeManagerGetFrameCryptorsResponse\n ).frameCryptors.map(\n (cryptor) =>\n new FrameCryptor(\n this.roomHandle,\n cryptor.participantIdentity!,\n cryptor.keyIndex!,\n cryptor.enabled!,\n ),\n );\n\n return frameCryptors;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/e2ee.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type {\n E2eeManagerGetFrameCryptorsResponse,\n E2eeResponse,\n GetKeyResponse,\n GetSharedKeyResponse,\n RatchetKeyResponse,\n RatchetSharedKeyResponse,\n} from '@livekit/rtc-ffi-bindings';\nimport {\n E2eeManagerSetEnabledRequest,\n E2eeRequest,\n EncryptionType,\n FrameCryptorSetEnabledRequest,\n FrameCryptorSetKeyIndexRequest,\n GetKeyRequest,\n GetSharedKeyRequest,\n RatchetKeyRequest,\n RatchetSharedKeyRequest,\n SetKeyRequest,\n SetSharedKeyRequest,\n} from '@livekit/rtc-ffi-bindings';\nimport { FfiClient } from './ffi_client.js';\n\nconst DEFAULT_RATCHET_SALT = new TextEncoder().encode('LKFrameEncryptionKey');\nconst DEFAULT_RATCHET_WINDOW_SIZE = 16;\nconst DEFAULT_FAILURE_TOLERANCE = -1;\n\nexport interface KeyProviderOptions {\n sharedKey?: Uint8Array;\n ratchetSalt?: Uint8Array;\n ratchetWindowSize?: number;\n failureTolerance?: number;\n}\n\nexport const defaultKeyProviderOptions: KeyProviderOptions = {\n ratchetSalt: DEFAULT_RATCHET_SALT,\n ratchetWindowSize: DEFAULT_RATCHET_WINDOW_SIZE,\n failureTolerance: DEFAULT_FAILURE_TOLERANCE,\n};\n\nexport interface E2EEOptions {\n keyProviderOptions: KeyProviderOptions;\n encryptionType?: EncryptionType;\n}\n\nexport const defaultE2EEOptions: E2EEOptions = {\n keyProviderOptions: defaultKeyProviderOptions,\n encryptionType: EncryptionType.GCM,\n};\n\nexport class KeyProvider {\n private roomHandle: bigint;\n options: KeyProviderOptions;\n\n /** internal */\n constructor(roomHandle: bigint, opts: KeyProviderOptions) {\n this.roomHandle = roomHandle;\n this.options = opts;\n }\n\n setSharedKey(sharedKey: Uint8Array, keyIndex: number) {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'setSharedKey',\n value: new SetSharedKeyRequest({\n keyIndex: keyIndex,\n sharedKey: sharedKey,\n }),\n },\n });\n\n FfiClient.instance.request({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n }\n\n exportSharedKey(keyIndex: number): Uint8Array {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'getSharedKey',\n value: new GetSharedKeyRequest({\n keyIndex: keyIndex,\n }),\n },\n });\n\n const res = FfiClient.instance.request<E2eeResponse>({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n\n return (res.message.value as GetSharedKeyResponse).key!;\n }\n\n ratchetSharedKey(keyIndex: number): Uint8Array {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'ratchetSharedKey',\n value: new RatchetSharedKeyRequest({\n keyIndex: keyIndex,\n }),\n },\n });\n\n const res = FfiClient.instance.request<E2eeResponse>({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n\n return (res.message.value as RatchetSharedKeyResponse).newKey!;\n }\n\n setKey(participantIdentity: string, keyIndex: number) {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'setKey',\n value: new SetKeyRequest({\n keyIndex: keyIndex,\n participantIdentity: participantIdentity,\n }),\n },\n });\n\n FfiClient.instance.request({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n }\n\n exportKey(participantIdentity: string, keyIndex: number): Uint8Array {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'getKey',\n value: new GetKeyRequest({\n keyIndex: keyIndex,\n participantIdentity: participantIdentity,\n }),\n },\n });\n\n const res = FfiClient.instance.request<E2eeResponse>({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n\n return (res.message.value as GetKeyResponse).key!;\n }\n\n ratchetKey(participantIdentity: string, keyIndex: number): Uint8Array {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'ratchetKey',\n value: new RatchetKeyRequest({\n keyIndex: keyIndex,\n participantIdentity: participantIdentity,\n }),\n },\n });\n\n const res = FfiClient.instance.request<E2eeResponse>({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n\n return (res.message.value as RatchetKeyResponse).newKey!;\n }\n}\n\nexport class FrameCryptor {\n private roomHandle = BigInt(0);\n participantIdentity: string;\n keyIndex: number;\n enabled: boolean;\n\n constructor(roomHandle: bigint, participantIdentity: string, keyIndex: number, enabled: boolean) {\n this.roomHandle = roomHandle;\n this.participantIdentity = participantIdentity;\n this.keyIndex = keyIndex;\n this.enabled = enabled;\n }\n\n setEnabled(enabled: boolean) {\n this.enabled = enabled;\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'cryptorSetEnabled',\n value: new FrameCryptorSetEnabledRequest({\n participantIdentity: this.participantIdentity,\n enabled: this.enabled,\n }),\n },\n });\n\n FfiClient.instance.request({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n }\n\n setKeyIndex(keyIndex: number) {\n this.keyIndex = keyIndex;\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'cryptorSetKeyIndex',\n value: new FrameCryptorSetKeyIndexRequest({\n participantIdentity: this.participantIdentity,\n keyIndex: this.keyIndex,\n }),\n },\n });\n\n FfiClient.instance.request({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n }\n}\n\nexport class E2EEManager {\n private roomHandle = BigInt(0);\n private options: E2EEOptions;\n private keyProvider: KeyProvider;\n\n enabled: boolean;\n\n constructor(roomHandle: bigint, opts?: E2EEOptions) {\n this.roomHandle = roomHandle;\n this.enabled = opts !== undefined;\n\n opts ??= defaultE2EEOptions;\n const options = { ...defaultE2EEOptions, ...opts };\n\n this.options = options;\n this.keyProvider = new KeyProvider(roomHandle, options.keyProviderOptions);\n }\n\n setEnabled(enabled: boolean) {\n this.enabled = enabled;\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'managerSetEnabled',\n value: new E2eeManagerSetEnabledRequest({\n enabled: this.enabled,\n }),\n },\n });\n\n FfiClient.instance.request({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n }\n\n frameCryptors(): FrameCryptor[] {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'managerGetFrameCryptors',\n value: {},\n },\n });\n\n const res = FfiClient.instance.request<E2eeResponse>({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n\n const frameCryptors = (\n res.message.value as E2eeManagerGetFrameCryptorsResponse\n ).frameCryptors.map(\n (cryptor) =>\n new FrameCryptor(\n this.roomHandle,\n cryptor.participantIdentity!,\n cryptor.keyIndex!,\n cryptor.enabled!,\n ),\n );\n\n return frameCryptors;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWA,8BAYO;AACP,wBAA0B;AAE1B,MAAM,uBAAuB,IAAI,YAAY,EAAE,OAAO,sBAAsB;AAC5E,MAAM,8BAA8B;AACpC,MAAM,4BAA4B;AAS3B,MAAM,4BAAgD;AAAA,EAC3D,aAAa;AAAA,EACb,mBAAmB;AAAA,EACnB,kBAAkB;AACpB;AAOO,MAAM,qBAAkC;AAAA,EAC7C,oBAAoB;AAAA,EACpB,gBAAgB,uCAAe;AACjC;AAEO,MAAM,YAAY;AAAA;AAAA,EAKvB,YAAY,YAAoB,MAA0B;AACxD,SAAK,aAAa;AAClB,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,aAAa,WAAuB,UAAkB;AACpD,UAAM,MAAM,IAAI,oCAAY;AAAA,MAC1B,YAAY,KAAK;AAAA,MACjB,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO,IAAI,4CAAoB;AAAA,UAC7B;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAED,gCAAU,SAAS,QAAQ;AAAA,MACzB,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,gBAAgB,UAA8B;AAC5C,UAAM,MAAM,IAAI,oCAAY;AAAA,MAC1B,YAAY,KAAK;AAAA,MACjB,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO,IAAI,4CAAoB;AAAA,UAC7B;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAED,UAAM,MAAM,4BAAU,SAAS,QAAsB;AAAA,MACnD,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAED,WAAQ,IAAI,QAAQ,MAA+B;AAAA,EACrD;AAAA,EAEA,iBAAiB,UAA8B;AAC7C,UAAM,MAAM,IAAI,oCAAY;AAAA,MAC1B,YAAY,KAAK;AAAA,MACjB,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO,IAAI,gDAAwB;AAAA,UACjC;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAED,UAAM,MAAM,4BAAU,SAAS,QAAsB;AAAA,MACnD,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAED,WAAQ,IAAI,QAAQ,MAAmC;AAAA,EACzD;AAAA,EAEA,OAAO,qBAA6B,UAAkB;AACpD,UAAM,MAAM,IAAI,oCAAY;AAAA,MAC1B,YAAY,KAAK;AAAA,MACjB,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO,IAAI,sCAAc;AAAA,UACvB;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAED,gCAAU,SAAS,QAAQ;AAAA,MACzB,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,UAAU,qBAA6B,UAA8B;AACnE,UAAM,MAAM,IAAI,oCAAY;AAAA,MAC1B,YAAY,KAAK;AAAA,MACjB,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO,IAAI,sCAAc;AAAA,UACvB;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAED,UAAM,MAAM,4BAAU,SAAS,QAAsB;AAAA,MACnD,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAED,WAAQ,IAAI,QAAQ,MAAyB;AAAA,EAC/C;AAAA,EAEA,WAAW,qBAA6B,UAA8B;AACpE,UAAM,MAAM,IAAI,oCAAY;AAAA,MAC1B,YAAY,KAAK;AAAA,MACjB,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO,IAAI,0CAAkB;AAAA,UAC3B;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAED,UAAM,MAAM,4BAAU,SAAS,QAAsB;AAAA,MACnD,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAED,WAAQ,IAAI,QAAQ,MAA6B;AAAA,EACnD;AACF;AAEO,MAAM,aAAa;AAAA,EAMxB,YAAY,YAAoB,qBAA6B,UAAkB,SAAkB;AALjG,SAAQ,aAAa,OAAO,CAAC;AAM3B,SAAK,aAAa;AAClB,SAAK,sBAAsB;AAC3B,SAAK,WAAW;AAChB,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,WAAW,SAAkB;AAC3B,SAAK,UAAU;AACf,UAAM,MAAM,IAAI,oCAAY;AAAA,MAC1B,YAAY,KAAK;AAAA,MACjB,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO,IAAI,sDAA8B;AAAA,UACvC,qBAAqB,KAAK;AAAA,UAC1B,SAAS,KAAK;AAAA,QAChB,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAED,gCAAU,SAAS,QAAQ;AAAA,MACzB,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,YAAY,UAAkB;AAC5B,SAAK,WAAW;AAChB,UAAM,MAAM,IAAI,oCAAY;AAAA,MAC1B,YAAY,KAAK;AAAA,MACjB,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO,IAAI,uDAA+B;AAAA,UACxC,qBAAqB,KAAK;AAAA,UAC1B,UAAU,KAAK;AAAA,QACjB,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAED,gCAAU,SAAS,QAAQ;AAAA,MACzB,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEO,MAAM,YAAY;AAAA,EAOvB,YAAY,YAAoB,MAAoB;AANpD,SAAQ,aAAa,OAAO,CAAC;AAO3B,SAAK,aAAa;AAClB,SAAK,UAAU,SAAS;AAExB,aAAS;AACT,UAAM,UAAU,EAAE,GAAG,oBAAoB,GAAG,KAAK;AAEjD,SAAK,UAAU;AACf,SAAK,cAAc,IAAI,YAAY,YAAY,QAAQ,kBAAkB;AAAA,EAC3E;AAAA,EAEA,WAAW,SAAkB;AAC3B,SAAK,UAAU;AACf,UAAM,MAAM,IAAI,oCAAY;AAAA,MAC1B,YAAY,KAAK;AAAA,MACjB,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO,IAAI,qDAA6B;AAAA,UACtC,SAAS,KAAK;AAAA,QAChB,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAED,gCAAU,SAAS,QAAQ;AAAA,MACzB,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,gBAAgC;AAC9B,UAAM,MAAM,IAAI,oCAAY;AAAA,MAC1B,YAAY,KAAK;AAAA,MACjB,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO,CAAC;AAAA,MACV;AAAA,IACF,CAAC;AAED,UAAM,MAAM,4BAAU,SAAS,QAAsB;AAAA,MACnD,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAED,UAAM,gBACJ,IAAI,QAAQ,MACZ,cAAc;AAAA,MACd,CAAC,YACC,IAAI;AAAA,QACF,KAAK;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,IACJ;AAEA,WAAO;AAAA,EACT;AACF;","names":[]}