@livekit/rtc-node 0.13.32 → 0.13.34

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 (141) hide show
  1. package/dist/async_queue.d.ts +2 -3
  2. package/dist/audio_filter.d.ts +2 -3
  3. package/dist/audio_frame.d.ts +5 -6
  4. package/dist/audio_mixer.d.ts +3 -6
  5. package/dist/audio_resampler.d.ts +3 -6
  6. package/dist/audio_source.d.ts +5 -6
  7. package/dist/{audio_stream-4M8XlO4-.d.cts → audio_stream-BNVaONuH.d.cts} +36 -10
  8. package/dist/audio_stream.d.cts +2 -2
  9. package/dist/audio_stream.d.ts +61 -18
  10. package/dist/data_streams/index.d.cts +1 -1
  11. package/dist/data_streams/index.d.ts +4 -3
  12. package/dist/data_streams/stream_reader.cjs +97 -58
  13. package/dist/data_streams/stream_reader.cjs.map +1 -1
  14. package/dist/data_streams/stream_reader.d.cts +1 -1
  15. package/dist/data_streams/stream_reader.d.ts +65 -2
  16. package/dist/data_streams/stream_reader.d.ts.map +1 -1
  17. package/dist/data_streams/stream_writer.d.cts +1 -1
  18. package/dist/data_streams/stream_writer.d.ts +5 -7
  19. package/dist/data_streams/types.cjs.map +1 -1
  20. package/dist/data_streams/types.d.cts +1 -1
  21. package/dist/data_streams/types.d.ts +47 -2
  22. package/dist/data_streams/types.d.ts.map +1 -1
  23. package/dist/e2ee.cjs +5 -1
  24. package/dist/e2ee.cjs.map +1 -1
  25. package/dist/e2ee.d.cts +3 -1
  26. package/dist/e2ee.d.ts +11 -11
  27. package/dist/e2ee.d.ts.map +1 -1
  28. package/dist/ffi_client.d.ts +8 -10
  29. package/dist/frame_processor.d.ts +8 -11
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +2 -2
  32. package/dist/index.d.ts +22 -17
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +1 -107
  35. package/dist/log.d.ts +5 -7
  36. package/dist/participant.cjs +179 -192
  37. package/dist/participant.cjs.map +1 -1
  38. package/dist/participant.d.cts +2 -2
  39. package/dist/participant.d.ts +169 -18
  40. package/dist/participant.d.ts.map +1 -1
  41. package/dist/room.cjs +166 -120
  42. package/dist/room.cjs.map +1 -1
  43. package/dist/room.d.cts +2 -2
  44. package/dist/room.d.ts +228 -18
  45. package/dist/room.d.ts.map +1 -1
  46. package/dist/rpc.d.ts +7 -9
  47. package/dist/tests/e2e_common.cjs +157 -0
  48. package/dist/tests/e2e_common.cjs.map +1 -0
  49. package/dist/tests/e2e_common.d.cts +56 -0
  50. package/dist/tests/e2e_common.d.ts +37 -0
  51. package/dist/tests/e2e_common.d.ts.map +1 -0
  52. package/dist/track.d.cts +2 -2
  53. package/dist/track.d.ts +67 -18
  54. package/dist/track_publication.d.cts +2 -2
  55. package/dist/track_publication.d.ts +45 -18
  56. package/dist/transcription.d.ts +3 -4
  57. package/dist/{types-_PdPVish.d.ts → types-f7wTlFjs.d.cts} +34 -11
  58. package/dist/types.d.ts +2 -3
  59. package/dist/utils.cjs +27 -2
  60. package/dist/utils.cjs.map +1 -1
  61. package/dist/utils.d.cts +8 -1
  62. package/dist/utils.d.ts +10 -5
  63. package/dist/utils.d.ts.map +1 -1
  64. package/dist/version.cjs +1 -1
  65. package/dist/version.cjs.map +1 -1
  66. package/dist/version.d.cts +1 -1
  67. package/dist/version.d.ts +2 -3
  68. package/dist/video_frame.d.ts +4 -5
  69. package/dist/video_source.d.ts +6 -8
  70. package/dist/video_stream.d.cts +2 -2
  71. package/dist/video_stream.d.ts +5 -22
  72. package/package.json +6 -7
  73. package/src/audio_stream_room_lifecycle.test.ts +4 -1
  74. package/src/data_streams/stream_reader.ts +132 -82
  75. package/src/data_streams/types.ts +6 -0
  76. package/src/e2ee.ts +7 -0
  77. package/src/index.ts +8 -1
  78. package/src/participant.ts +252 -223
  79. package/src/room.ts +233 -134
  80. package/src/tests/e2e.test.ts +50 -139
  81. package/src/tests/e2e_common.ts +163 -0
  82. package/src/tests/e2e_data_streams.test.ts +639 -0
  83. package/src/utils.ts +30 -0
  84. package/src/version.ts +1 -1
  85. package/dist/async_queue.js +0 -56
  86. package/dist/async_queue.js.map +0 -1
  87. package/dist/audio_filter.js +0 -24
  88. package/dist/audio_filter.js.map +0 -1
  89. package/dist/audio_frame.js +0 -78
  90. package/dist/audio_frame.js.map +0 -1
  91. package/dist/audio_mixer.js +0 -269
  92. package/dist/audio_mixer.js.map +0 -1
  93. package/dist/audio_resampler.js +0 -154
  94. package/dist/audio_resampler.js.map +0 -1
  95. package/dist/audio_source.js +0 -134
  96. package/dist/audio_source.js.map +0 -1
  97. package/dist/audio_stream-CTyN1Ldy.d.ts +0 -523
  98. package/dist/audio_stream.js +0 -122
  99. package/dist/audio_stream.js.map +0 -1
  100. package/dist/data_streams/index.js +0 -3
  101. package/dist/data_streams/index.js.map +0 -1
  102. package/dist/data_streams/stream_reader.js +0 -124
  103. package/dist/data_streams/stream_reader.js.map +0 -1
  104. package/dist/data_streams/stream_writer.js +0 -26
  105. package/dist/data_streams/stream_writer.js.map +0 -1
  106. package/dist/data_streams/types.js +0 -1
  107. package/dist/data_streams/types.js.map +0 -1
  108. package/dist/e2ee.js +0 -251
  109. package/dist/e2ee.js.map +0 -1
  110. package/dist/ffi_client.js +0 -89
  111. package/dist/ffi_client.js.map +0 -1
  112. package/dist/frame_processor.js +0 -29
  113. package/dist/frame_processor.js.map +0 -1
  114. package/dist/index.js.map +0 -1
  115. package/dist/log.js +0 -9
  116. package/dist/log.js.map +0 -1
  117. package/dist/participant.js +0 -715
  118. package/dist/participant.js.map +0 -1
  119. package/dist/room.js +0 -900
  120. package/dist/room.js.map +0 -1
  121. package/dist/rpc.js +0 -65
  122. package/dist/rpc.js.map +0 -1
  123. package/dist/track.js +0 -234
  124. package/dist/track.js.map +0 -1
  125. package/dist/track_publication.js +0 -100
  126. package/dist/track_publication.js.map +0 -1
  127. package/dist/transcription.js +0 -1
  128. package/dist/transcription.js.map +0 -1
  129. package/dist/types-_PdPVish.d.cts +0 -87
  130. package/dist/types.js +0 -1
  131. package/dist/types.js.map +0 -1
  132. package/dist/utils.js +0 -35
  133. package/dist/utils.js.map +0 -1
  134. package/dist/version.js +0 -5
  135. package/dist/version.js.map +0 -1
  136. package/dist/video_frame.js +0 -207
  137. package/dist/video_frame.js.map +0 -1
  138. package/dist/video_source.js +0 -53
  139. package/dist/video_source.js.map +0 -1
  140. package/dist/video_stream.js +0 -70
  141. package/dist/video_stream.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\n/** convert bigints to numbers preserving undefined values */\nexport function bigIntToNumber<T extends bigint | undefined>(\n value: T,\n): T extends bigint ? number : undefined {\n return (value !== undefined ? Number(value) : undefined) as T extends bigint ? number : undefined;\n}\n\n/** convert numbers to bigints preserving undefined values */\nexport function numberToBigInt<T extends number | undefined>(\n value: T,\n): T extends number ? bigint : undefined {\n return (value !== undefined ? BigInt(value) : undefined) as T extends number ? bigint : undefined;\n}\n\nexport function splitUtf8(s: string, n: number): Uint8Array[] {\n if (n < 4) {\n throw new Error('n must be at least 4 due to utf8 encoding rules');\n }\n // adapted from https://stackoverflow.com/a/6043797\n const result: Uint8Array[] = [];\n let encoded = new TextEncoder().encode(s);\n while (encoded.length > n) {\n let k = n;\n while (k > 0) {\n const byte = encoded[k];\n if (byte !== undefined && (byte & 0xc0) !== 0x80) {\n break;\n }\n k--;\n }\n result.push(encoded.slice(0, k));\n encoded = encoded.slice(k);\n }\n if (encoded.length > 0) {\n result.push(encoded);\n }\n return result;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKO,SAAS,eACd,OACuC;AACvC,SAAQ,UAAU,SAAY,OAAO,KAAK,IAAI;AAChD;AAGO,SAAS,eACd,OACuC;AACvC,SAAQ,UAAU,SAAY,OAAO,KAAK,IAAI;AAChD;AAEO,SAAS,UAAU,GAAW,GAAyB;AAC5D,MAAI,IAAI,GAAG;AACT,UAAM,IAAI,MAAM,iDAAiD;AAAA,EACnE;AAEA,QAAM,SAAuB,CAAC;AAC9B,MAAI,UAAU,IAAI,YAAY,EAAE,OAAO,CAAC;AACxC,SAAO,QAAQ,SAAS,GAAG;AACzB,QAAI,IAAI;AACR,WAAO,IAAI,GAAG;AACZ,YAAM,OAAO,QAAQ,CAAC;AACtB,UAAI,SAAS,WAAc,OAAO,SAAU,KAAM;AAChD;AAAA,MACF;AACA;AAAA,IACF;AACA,WAAO,KAAK,QAAQ,MAAM,GAAG,CAAC,CAAC;AAC/B,cAAU,QAAQ,MAAM,CAAC;AAAA,EAC3B;AACA,MAAI,QAAQ,SAAS,GAAG;AACtB,WAAO,KAAK,OAAO;AAAA,EACrB;AACA,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../src/utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type {\n ByteStreamInfo as ProtoByteStreamInfo,\n TextStreamInfo as ProtoTextStreamInfo,\n} from '@livekit/rtc-ffi-bindings';\nimport type { ByteStreamInfo, TextStreamInfo } from './data_streams/types.js';\n\n/** convert bigints to numbers preserving undefined values */\nexport function bigIntToNumber<T extends bigint | undefined>(\n value: T,\n): T extends bigint ? number : undefined {\n return (value !== undefined ? Number(value) : undefined) as T extends bigint ? number : undefined;\n}\n\n/** convert numbers to bigints preserving undefined values */\nexport function numberToBigInt<T extends number | undefined>(\n value: T,\n): T extends number ? bigint : undefined {\n return (value !== undefined ? BigInt(value) : undefined) as T extends number ? bigint : undefined;\n}\n\nexport function splitUtf8(s: string, n: number): Uint8Array[] {\n if (n < 4) {\n throw new Error('n must be at least 4 due to utf8 encoding rules');\n }\n // adapted from https://stackoverflow.com/a/6043797\n const result: Uint8Array[] = [];\n let encoded = new TextEncoder().encode(s);\n while (encoded.length > n) {\n let k = n;\n while (k > 0) {\n const byte = encoded[k];\n if (byte !== undefined && (byte & 0xc0) !== 0x80) {\n break;\n }\n k--;\n }\n result.push(encoded.slice(0, k));\n encoded = encoded.slice(k);\n }\n if (encoded.length > 0) {\n result.push(encoded);\n }\n return result;\n}\n\n/** @internal */\nexport function textStreamInfoFromProto(info: ProtoTextStreamInfo): TextStreamInfo {\n return {\n streamId: info.streamId!,\n mimeType: info.mimeType!,\n topic: info.topic!,\n timestamp: bigIntToNumber(info.timestamp!),\n totalSize: info.totalLength ? bigIntToNumber(info.totalLength) : undefined,\n attributes: info.attributes,\n };\n}\n\n/** @internal */\nexport function byteStreamInfoFromProto(info: ProtoByteStreamInfo): ByteStreamInfo {\n return {\n streamId: info.streamId!,\n name: info.name ?? 'unknown',\n mimeType: info.mimeType!,\n topic: info.topic!,\n timestamp: bigIntToNumber(info.timestamp!),\n totalSize: info.totalLength !== undefined ? bigIntToNumber(info.totalLength) : undefined,\n attributes: info.attributes,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUO,SAAS,eACd,OACuC;AACvC,SAAQ,UAAU,SAAY,OAAO,KAAK,IAAI;AAChD;AAGO,SAAS,eACd,OACuC;AACvC,SAAQ,UAAU,SAAY,OAAO,KAAK,IAAI;AAChD;AAEO,SAAS,UAAU,GAAW,GAAyB;AAC5D,MAAI,IAAI,GAAG;AACT,UAAM,IAAI,MAAM,iDAAiD;AAAA,EACnE;AAEA,QAAM,SAAuB,CAAC;AAC9B,MAAI,UAAU,IAAI,YAAY,EAAE,OAAO,CAAC;AACxC,SAAO,QAAQ,SAAS,GAAG;AACzB,QAAI,IAAI;AACR,WAAO,IAAI,GAAG;AACZ,YAAM,OAAO,QAAQ,CAAC;AACtB,UAAI,SAAS,WAAc,OAAO,SAAU,KAAM;AAChD;AAAA,MACF;AACA;AAAA,IACF;AACA,WAAO,KAAK,QAAQ,MAAM,GAAG,CAAC,CAAC;AAC/B,cAAU,QAAQ,MAAM,CAAC;AAAA,EAC3B;AACA,MAAI,QAAQ,SAAS,GAAG;AACtB,WAAO,KAAK,OAAO;AAAA,EACrB;AACA,SAAO;AACT;AAGO,SAAS,wBAAwB,MAA2C;AACjF,SAAO;AAAA,IACL,UAAU,KAAK;AAAA,IACf,UAAU,KAAK;AAAA,IACf,OAAO,KAAK;AAAA,IACZ,WAAW,eAAe,KAAK,SAAU;AAAA,IACzC,WAAW,KAAK,cAAc,eAAe,KAAK,WAAW,IAAI;AAAA,IACjE,YAAY,KAAK;AAAA,EACnB;AACF;AAGO,SAAS,wBAAwB,MAA2C;AACjF,SAAO;AAAA,IACL,UAAU,KAAK;AAAA,IACf,MAAM,KAAK,QAAQ;AAAA,IACnB,UAAU,KAAK;AAAA,IACf,OAAO,KAAK;AAAA,IACZ,WAAW,eAAe,KAAK,SAAU;AAAA,IACzC,WAAW,KAAK,gBAAgB,SAAY,eAAe,KAAK,WAAW,IAAI;AAAA,IAC/E,YAAY,KAAK;AAAA,EACnB;AACF;","names":[]}
package/dist/utils.d.cts CHANGED
@@ -1,7 +1,14 @@
1
+ import { ByteStreamInfo, TextStreamInfo } from '@livekit/rtc-ffi-bindings';
2
+ import { b as ByteStreamInfo$1, e as TextStreamInfo$1 } from './types-f7wTlFjs.cjs';
3
+
1
4
  /** convert bigints to numbers preserving undefined values */
2
5
  declare function bigIntToNumber<T extends bigint | undefined>(value: T): T extends bigint ? number : undefined;
3
6
  /** convert numbers to bigints preserving undefined values */
4
7
  declare function numberToBigInt<T extends number | undefined>(value: T): T extends number ? bigint : undefined;
5
8
  declare function splitUtf8(s: string, n: number): Uint8Array[];
9
+ /** @internal */
10
+ declare function textStreamInfoFromProto(info: TextStreamInfo): TextStreamInfo$1;
11
+ /** @internal */
12
+ declare function byteStreamInfoFromProto(info: ByteStreamInfo): ByteStreamInfo$1;
6
13
 
7
- export { bigIntToNumber, numberToBigInt, splitUtf8 };
14
+ export { bigIntToNumber, byteStreamInfoFromProto, numberToBigInt, splitUtf8, textStreamInfoFromProto };
package/dist/utils.d.ts CHANGED
@@ -1,7 +1,12 @@
1
+ import type { ByteStreamInfo as ProtoByteStreamInfo, TextStreamInfo as ProtoTextStreamInfo } from '@livekit/rtc-ffi-bindings';
2
+ import type { ByteStreamInfo, TextStreamInfo } from './data_streams/types.js';
1
3
  /** convert bigints to numbers preserving undefined values */
2
- declare function bigIntToNumber<T extends bigint | undefined>(value: T): T extends bigint ? number : undefined;
4
+ export declare function bigIntToNumber<T extends bigint | undefined>(value: T): T extends bigint ? number : undefined;
3
5
  /** convert numbers to bigints preserving undefined values */
4
- declare function numberToBigInt<T extends number | undefined>(value: T): T extends number ? bigint : undefined;
5
- declare function splitUtf8(s: string, n: number): Uint8Array[];
6
-
7
- export { bigIntToNumber, numberToBigInt, splitUtf8 };
6
+ export declare function numberToBigInt<T extends number | undefined>(value: T): T extends number ? bigint : undefined;
7
+ export declare function splitUtf8(s: string, n: number): Uint8Array[];
8
+ /** @internal */
9
+ export declare function textStreamInfoFromProto(info: ProtoTextStreamInfo): TextStreamInfo;
10
+ /** @internal */
11
+ export declare function byteStreamInfoFromProto(info: ProtoByteStreamInfo): ByteStreamInfo;
12
+ //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAIA,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,SAAS,EACzD,KAAK,EAAE,CAAC,GACP,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,SAAS,CAEvC;AAED,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,SAAS,EACzD,KAAK,EAAE,CAAC,GACP,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,SAAS,CAEvC;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE,CAuB5D"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,cAAc,IAAI,mBAAmB,EACrC,cAAc,IAAI,mBAAmB,EACtC,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE9E,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,SAAS,EACzD,KAAK,EAAE,CAAC,GACP,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,SAAS,CAEvC;AAED,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,SAAS,EACzD,KAAK,EAAE,CAAC,GACP,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,SAAS,CAEvC;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE,CAuB5D;AAED,gBAAgB;AAChB,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,mBAAmB,GAAG,cAAc,CASjF;AAED,gBAAgB;AAChB,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,mBAAmB,GAAG,cAAc,CAUjF"}
package/dist/version.cjs CHANGED
@@ -21,7 +21,7 @@ __export(version_exports, {
21
21
  SDK_VERSION: () => SDK_VERSION
22
22
  });
23
23
  module.exports = __toCommonJS(version_exports);
24
- const SDK_VERSION = "0.13.32";
24
+ const SDK_VERSION = "0.13.34";
25
25
  // Annotate the CommonJS export names for ESM import in node:
26
26
  0 && (module.exports = {
27
27
  SDK_VERSION
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/version.ts"],"sourcesContent":["export const SDK_VERSION = \"0.13.32\";\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,cAAc;","names":[]}
1
+ {"version":3,"sources":["../src/version.ts"],"sourcesContent":["export const SDK_VERSION = \"0.13.34\";\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,cAAc;","names":[]}
@@ -1,3 +1,3 @@
1
- declare const SDK_VERSION = "0.13.32";
1
+ declare const SDK_VERSION = "0.13.34";
2
2
 
3
3
  export { SDK_VERSION };
package/dist/version.d.ts CHANGED
@@ -1,3 +1,2 @@
1
- declare const SDK_VERSION = "0.13.32";
2
-
3
- export { SDK_VERSION };
1
+ export declare const SDK_VERSION = "0.13.34";
2
+ //# sourceMappingURL=version.d.ts.map
@@ -1,6 +1,6 @@
1
- import { VideoBufferType, VideoBufferInfo, OwnedVideoBuffer } from '@livekit/rtc-ffi-bindings';
2
-
3
- declare class VideoFrame {
1
+ import type { OwnedVideoBuffer } from '@livekit/rtc-ffi-bindings';
2
+ import { VideoBufferInfo, VideoBufferType } from '@livekit/rtc-ffi-bindings';
3
+ export declare class VideoFrame {
4
4
  data: Uint8Array;
5
5
  width: number;
6
6
  height: number;
@@ -15,5 +15,4 @@ declare class VideoFrame {
15
15
  getPlane(planeNth: number): Uint8Array | void;
16
16
  convert(dstType: VideoBufferType, flipY?: boolean): VideoFrame;
17
17
  }
18
-
19
- export { VideoFrame };
18
+ //# sourceMappingURL=video_frame.d.ts.map
@@ -1,9 +1,8 @@
1
- import { VideoSourceInfo, FfiHandle, VideoRotation } from '@livekit/rtc-ffi-bindings';
2
- import './ffi_client.js';
3
- import { VideoFrame } from './video_frame.js';
4
- import '@livekit/typed-emitter';
5
-
6
- declare class VideoSource {
1
+ import type { VideoSourceInfo } from '@livekit/rtc-ffi-bindings';
2
+ import { VideoRotation } from '@livekit/rtc-ffi-bindings';
3
+ import { FfiHandle } from './ffi_client.js';
4
+ import type { VideoFrame } from './video_frame.js';
5
+ export declare class VideoSource {
7
6
  /** @internal */
8
7
  info?: VideoSourceInfo;
9
8
  /** @internal */
@@ -16,5 +15,4 @@ declare class VideoSource {
16
15
  captureFrame(frame: VideoFrame, timestampUs?: bigint, rotation?: VideoRotation): void;
17
16
  close(): Promise<void>;
18
17
  }
19
-
20
- export { VideoSource };
18
+ //# sourceMappingURL=video_source.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { VideoRotation } from '@livekit/rtc-ffi-bindings';
2
- import { T as Track } from './audio_stream-4M8XlO4-.cjs';
2
+ import { T as Track } from './audio_stream-BNVaONuH.cjs';
3
3
  import { VideoFrame } from './video_frame.cjs';
4
4
  import 'node:stream/web';
5
5
  import './audio_frame.cjs';
@@ -7,7 +7,7 @@ import './frame_processor.cjs';
7
7
  import './audio_source.cjs';
8
8
  import './ffi_client.cjs';
9
9
  import '@livekit/typed-emitter';
10
- import './types-_PdPVish.cjs';
10
+ import './types-f7wTlFjs.cjs';
11
11
  import './e2ee.cjs';
12
12
  import '@livekit/mutex';
13
13
  import 'node:fs';
@@ -1,29 +1,12 @@
1
- import { VideoRotation } from '@livekit/rtc-ffi-bindings';
2
- import { T as Track } from './audio_stream-CTyN1Ldy.js';
1
+ import type { VideoRotation } from '@livekit/rtc-ffi-bindings';
2
+ import type { Track } from './track.js';
3
3
  import { VideoFrame } from './video_frame.js';
4
- import 'node:stream/web';
5
- import './audio_frame.js';
6
- import './frame_processor.js';
7
- import './audio_source.js';
8
- import './ffi_client.js';
9
- import '@livekit/typed-emitter';
10
- import './types-_PdPVish.js';
11
- import './e2ee.js';
12
- import '@livekit/mutex';
13
- import 'node:fs';
14
- import './data_streams/stream_writer.js';
15
- import './rpc.js';
16
- import './transcription.js';
17
- import './types.js';
18
- import './video_source.js';
19
-
20
- type VideoFrameEvent = {
4
+ export type VideoFrameEvent = {
21
5
  frame: VideoFrame;
22
6
  timestampUs: bigint;
23
7
  rotation: VideoRotation;
24
8
  };
25
- declare class VideoStream extends ReadableStream<VideoFrameEvent> {
9
+ export declare class VideoStream extends ReadableStream<VideoFrameEvent> {
26
10
  constructor(track: Track);
27
11
  }
28
-
29
- export { type VideoFrameEvent, VideoStream };
12
+ //# sourceMappingURL=video_stream.d.ts.map
package/package.json CHANGED
@@ -3,10 +3,9 @@
3
3
  "description": "LiveKit RTC Node",
4
4
  "license": "Apache-2.0",
5
5
  "author": "LiveKit",
6
- "version": "0.13.32",
7
- "main": "dist/index.js",
8
- "require": "dist/index.cjs",
9
- "types": "dist/index.d.ts",
6
+ "version": "0.13.34",
7
+ "main": "dist/index.cjs",
8
+ "types": "dist/index.d.cts",
10
9
  "exports": {
11
10
  ".": {
12
11
  "import": {
@@ -32,7 +31,7 @@
32
31
  "dependencies": {
33
32
  "@datastructures-js/deque": "1.0.8",
34
33
  "@livekit/mutex": "^1.0.0",
35
- "@livekit/rtc-ffi-bindings": "0.12.68",
34
+ "@livekit/rtc-ffi-bindings": "0.12.73",
36
35
  "@livekit/typed-emitter": "^3.0.0",
37
36
  "pino": "^9.0.0",
38
37
  "pino-pretty": "^13.0.0"
@@ -44,14 +43,14 @@
44
43
  "tsup": "^8.3.5",
45
44
  "typescript": "5.8.2",
46
45
  "vitest": "^4.0.0",
47
- "livekit-server-sdk": "2.17.0"
46
+ "livekit-server-sdk": "2.18.0"
48
47
  },
49
48
  "engines": {
50
49
  "node": ">= 18"
51
50
  },
52
51
  "scripts": {
53
52
  "prebuild": "node -p \"'export const SDK_VERSION = ' + JSON.stringify(require('./package.json').version) + ';'\" > src/version.ts",
54
- "build": "pnpm prebuild && tsup --onSuccess \"tsc --declaration --emitDeclarationOnly\"",
53
+ "build": "pnpm prebuild && tsup && node scripts/postbuild.mjs",
55
54
  "lint": "eslint -f unix \"src/**/*.ts\" --ignore-pattern \"src/proto/*\"",
56
55
  "test": "vitest run src",
57
56
  "test:e2e": "node scripts/run-e2e.mjs"
@@ -146,12 +146,15 @@ function makeEndTrackingStream(): { stream: AudioStreamSource; endCount: () => n
146
146
 
147
147
  function makeLocalParticipant(identity: string): LocalParticipant {
148
148
  // Bypass the FFI-touching constructor; set only the fields the lifecycle
149
- // paths read (identity getter + trackPublications map).
149
+ // paths read (identity getter, trackPublications map, and the open data
150
+ // stream writers that disconnect cleanup disposes).
150
151
  const p = Object.create(LocalParticipant.prototype) as LocalParticipant;
151
152
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
152
153
  (p as any).info = { identity };
153
154
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
154
155
  (p as any).trackPublications = new Map();
156
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
157
+ (p as any).openStreamWriters = new Set();
155
158
  return p;
156
159
  }
157
160
 
@@ -3,7 +3,6 @@
3
3
  // SPDX-License-Identifier: Apache-2.0
4
4
  import type { DataStream_Chunk } from '@livekit/rtc-ffi-bindings';
5
5
  import { log } from '../log.js';
6
- import { bigIntToNumber } from '../utils.js';
7
6
  import type { BaseStreamInfo, ByteStreamInfo, TextStreamInfo } from './types.js';
8
7
 
9
8
  abstract class BaseStreamReader<T extends BaseStreamInfo> {
@@ -15,6 +14,12 @@ abstract class BaseStreamReader<T extends BaseStreamInfo> {
15
14
 
16
15
  protected bytesReceived: number;
17
16
 
17
+ private closed = false;
18
+
19
+ // The reader held by an in-progress iteration. Cancelling has to go through
20
+ // it, since it holds the stream's lock.
21
+ private activeReader: ReadableStreamDefaultReader<DataStream_Chunk> | null = null;
22
+
18
23
  get info() {
19
24
  return this._info;
20
25
  }
@@ -26,7 +31,68 @@ abstract class BaseStreamReader<T extends BaseStreamInfo> {
26
31
  this.bytesReceived = 0;
27
32
  }
28
33
 
29
- protected abstract handleChunkReceived(chunk: DataStream_Chunk): void;
34
+ protected handleChunkReceived(chunk: DataStream_Chunk) {
35
+ this.bytesReceived += chunk.content!.byteLength;
36
+ const currentProgress = this.totalByteSize
37
+ ? this.bytesReceived / this.totalByteSize
38
+ : undefined;
39
+ this.onProgress?.(currentProgress);
40
+ }
41
+
42
+ /** Takes the stream's reader for an iteration, remembering it so that
43
+ * close() can cancel a read that is still in flight. */
44
+ protected acquireReader(): ReadableStreamDefaultReader<DataStream_Chunk> {
45
+ const reader = this.reader.getReader();
46
+ this.activeReader = reader;
47
+ return reader;
48
+ }
49
+
50
+ /** Releases the stream lock after an iteration ended on its own — because a
51
+ * read reported end-of-stream, or because the stream itself errored. Either
52
+ * way the stream is in a terminal state and the FFI subscription behind it
53
+ * was already dropped by that terminal event, so there is nothing to cancel.
54
+ *
55
+ * An error raised *around* a read rather than by it — a chunk that failed to
56
+ * process — leaves the stream live, so it has to go through close() instead. */
57
+ protected finishIteration(reader: ReadableStreamDefaultReader<DataStream_Chunk>) {
58
+ this.closed = true;
59
+ if (this.activeReader === reader) {
60
+ this.activeReader = null;
61
+ }
62
+ reader.releaseLock();
63
+ }
64
+
65
+ /**
66
+ * Stops receiving this stream and releases the resources behind it.
67
+ *
68
+ * A reader is subscribed to FFI events from the moment it is handed to a
69
+ * stream handler, and only unsubscribes once a read consumes the stream's
70
+ * end-of-stream event. So a reader that is abandoned part-way through, or
71
+ * that a handler never reads at all, has to be closed here or its
72
+ * subscription lives for the rest of the process. Reading to completion — or
73
+ * breaking out of a `for await` — closes the reader for you, and closing an
74
+ * already-closed reader is a no-op.
75
+ */
76
+ async close(): Promise<void> {
77
+ if (this.closed) {
78
+ return;
79
+ }
80
+ this.closed = true;
81
+ const active = this.activeReader;
82
+ this.activeReader = null;
83
+ try {
84
+ if (active) {
85
+ await active.cancel();
86
+ active.releaseLock();
87
+ } else {
88
+ await this.reader.cancel();
89
+ }
90
+ } catch (error: unknown) {
91
+ // The stream was already closed or errored (e.g. the room disconnected
92
+ // mid-stream), in which case its subscription is already gone.
93
+ log.debug('error closing stream reader: %s', error);
94
+ }
95
+ }
30
96
 
31
97
  onProgress?: (progress: number | undefined) => void;
32
98
 
@@ -37,41 +103,48 @@ abstract class BaseStreamReader<T extends BaseStreamInfo> {
37
103
  * A class to read chunks from a ReadableStream and provide them in a structured format.
38
104
  */
39
105
  export class ByteStreamReader extends BaseStreamReader<ByteStreamInfo> {
40
- protected handleChunkReceived(chunk: DataStream_Chunk) {
41
- this.bytesReceived += chunk.content!.byteLength;
42
- const currentProgress = this.totalByteSize
43
- ? this.bytesReceived / this.totalByteSize
44
- : undefined;
45
- this.onProgress?.(currentProgress);
46
- }
47
-
48
106
  [Symbol.asyncIterator]() {
49
- const reader = this.reader.getReader();
107
+ const reader = this.acquireReader();
50
108
 
51
109
  return {
52
110
  next: async (): Promise<IteratorResult<Uint8Array>> => {
111
+ let read: Awaited<ReturnType<typeof reader.read>>;
53
112
  try {
54
- const { done, value } = await reader.read();
55
- if (done) {
56
- // Release the lock when the stream is exhausted so the
57
- // underlying ReadableStream can be garbage-collected.
58
- reader.releaseLock();
59
- return { done: true, value: undefined as unknown };
60
- } else {
61
- this.handleChunkReceived(value);
62
- return { done: false, value: value.content! };
63
- }
113
+ read = await reader.read();
64
114
  } catch (error: unknown) {
65
- // Release the lock on error so it doesn't stay held when the
66
- // consumer never calls return() (e.g. breaking out of for-await).
67
- reader.releaseLock();
68
- log.error('error processing stream update: %s', error);
115
+ // The stream errored, which is terminal: release the lock so it
116
+ // doesn't stay held when the consumer never calls return() (a
117
+ // rejecting next() doesn't trigger it).
118
+ this.finishIteration(reader);
119
+ log.error('error reading stream: %s', error);
120
+ // Propagate abnormal termination (e.g. remote abort, payload over
121
+ // the receiver's size limit) instead of presenting the truncated
122
+ // payload as a clean EOF.
123
+ throw error;
124
+ }
125
+
126
+ if (read.done) {
127
+ // Release the lock when the stream is exhausted so the
128
+ // underlying ReadableStream can be garbage-collected.
129
+ this.finishIteration(reader);
69
130
  return { done: true, value: undefined as unknown };
70
131
  }
132
+
133
+ try {
134
+ this.handleChunkReceived(read.value);
135
+ return { done: false, value: read.value.content! };
136
+ } catch (error: unknown) {
137
+ // The chunk arrived fine but handling it threw (e.g. a consumer's
138
+ // onProgress callback). The stream is still live, so it has to be
139
+ // cancelled to release its FFI subscription.
140
+ await this.close();
141
+ log.error('error processing stream update: %s', error);
142
+ throw error;
143
+ }
71
144
  },
72
145
 
73
- return(): IteratorResult<Uint8Array> {
74
- reader.releaseLock();
146
+ return: async (): Promise<IteratorResult<Uint8Array>> => {
147
+ await this.close();
75
148
  return { done: true, value: undefined };
76
149
  },
77
150
  };
@@ -90,77 +163,54 @@ export class ByteStreamReader extends BaseStreamReader<ByteStreamInfo> {
90
163
  * A class to read chunks from a ReadableStream and provide them in a structured format.
91
164
  */
92
165
  export class TextStreamReader extends BaseStreamReader<TextStreamInfo> {
93
- private receivedChunks: Map<number, DataStream_Chunk>;
94
-
95
- /**
96
- * A TextStreamReader instance can be used as an AsyncIterator that returns the entire string
97
- * that has been received up to the current point in time.
98
- */
99
- constructor(
100
- info: TextStreamInfo,
101
- stream: ReadableStream<DataStream_Chunk>,
102
- totalChunkCount?: number,
103
- ) {
104
- super(info, stream, totalChunkCount);
105
- this.receivedChunks = new Map();
106
- }
107
-
108
- protected handleChunkReceived(chunk: DataStream_Chunk) {
109
- const index = bigIntToNumber(chunk.chunkIndex!);
110
- const previousChunkAtIndex = this.receivedChunks.get(index!);
111
- if (previousChunkAtIndex && previousChunkAtIndex.version! > chunk.version!) {
112
- // we have a newer version already, dropping the old one
113
- return;
114
- }
115
- this.receivedChunks.set(index, chunk);
116
- const currentProgress = this.totalByteSize
117
- ? this.receivedChunks.size / this.totalByteSize
118
- : undefined;
119
- this.onProgress?.(currentProgress);
120
- }
121
-
122
166
  /**
123
167
  * Async iterator implementation to allow usage of `for await...of` syntax.
124
168
  * Yields structured chunks from the stream.
125
169
  *
126
170
  */
127
171
  [Symbol.asyncIterator]() {
128
- const reader = this.reader.getReader();
172
+ const reader = this.acquireReader();
129
173
  const decoder = new TextDecoder();
130
- const receivedChunks = this.receivedChunks;
131
174
 
132
175
  return {
133
176
  next: async (): Promise<IteratorResult<string>> => {
177
+ let read: Awaited<ReturnType<typeof reader.read>>;
134
178
  try {
135
- const { done, value } = await reader.read();
136
- if (done) {
137
- // Release the lock when the stream is exhausted so the
138
- // underlying ReadableStream can be garbage-collected.
139
- reader.releaseLock();
140
- // Clear received chunks so the buffered data can be GC'd.
141
- receivedChunks.clear();
142
- return { done: true, value: undefined };
143
- } else {
144
- this.handleChunkReceived(value);
145
- return {
146
- done: false,
147
- value: decoder.decode(value.content!),
148
- };
149
- }
179
+ read = await reader.read();
150
180
  } catch (error: unknown) {
151
- // Release the lock on error so it doesn't stay held when the
152
- // consumer never calls return() (e.g. breaking out of for-await).
153
- reader.releaseLock();
154
- receivedChunks.clear();
155
- log.error('error processing stream update: %s', error);
181
+ // The stream errored, which is terminal: release the lock so it
182
+ // doesn't stay held when the consumer never calls return() (a
183
+ // rejecting next() doesn't trigger it).
184
+ this.finishIteration(reader);
185
+ log.error('error reading stream: %s', error);
186
+ // Propagate abnormal termination (e.g. remote abort, payload over
187
+ // the receiver's size limit) instead of presenting the truncated
188
+ // payload as a clean EOF.
189
+ throw error;
190
+ }
191
+
192
+ if (read.done) {
193
+ // Release the lock when the stream is exhausted so the
194
+ // underlying ReadableStream can be garbage-collected.
195
+ this.finishIteration(reader);
156
196
  return { done: true, value: undefined };
157
197
  }
198
+
199
+ try {
200
+ this.handleChunkReceived(read.value);
201
+ return { done: false, value: decoder.decode(read.value.content!) };
202
+ } catch (error: unknown) {
203
+ // The chunk arrived fine but handling it threw (e.g. a consumer's
204
+ // onProgress callback). The stream is still live, so it has to be
205
+ // cancelled to release its FFI subscription.
206
+ await this.close();
207
+ log.error('error processing stream update: %s', error);
208
+ throw error;
209
+ }
158
210
  },
159
211
 
160
- return(): IteratorResult<string> {
161
- reader.releaseLock();
162
- // Clear received chunks so the buffered data can be GC'd.
163
- receivedChunks.clear();
212
+ return: async (): Promise<IteratorResult<string>> => {
213
+ await this.close();
164
214
  return { done: true, value: undefined };
165
215
  },
166
216
  };
@@ -42,6 +42,12 @@ export interface TextStreamOptions extends DataStreamOptions {
42
42
  export interface ByteStreamOptions extends DataStreamOptions {
43
43
  name?: string;
44
44
  onProgress?: (progress: number) => void;
45
+ /**
46
+ * Whether the payload may be compressed on the wire. Defaults to true;
47
+ * compression is only applied when it actually reduces the payload size
48
+ * and every recipient supports it.
49
+ */
50
+ compress?: boolean;
45
51
  }
46
52
 
47
53
  export type ByteStreamHandler = (
package/src/e2ee.ts CHANGED
@@ -17,6 +17,7 @@ import {
17
17
  FrameCryptorSetKeyIndexRequest,
18
18
  GetKeyRequest,
19
19
  GetSharedKeyRequest,
20
+ KeyDerivationFunction,
20
21
  RatchetKeyRequest,
21
22
  RatchetSharedKeyRequest,
22
23
  SetKeyRequest,
@@ -27,18 +28,24 @@ import { FfiClient } from './ffi_client.js';
27
28
  const DEFAULT_RATCHET_SALT = new TextEncoder().encode('LKFrameEncryptionKey');
28
29
  const DEFAULT_RATCHET_WINDOW_SIZE = 16;
29
30
  const DEFAULT_FAILURE_TOLERANCE = -1;
31
+ const DEFAULT_KEY_RING_SIZE = 16;
32
+ const DEFAULT_KEY_DERIVATION_FUNCTION = KeyDerivationFunction.PBKDF2;
30
33
 
31
34
  export interface KeyProviderOptions {
32
35
  sharedKey?: Uint8Array;
33
36
  ratchetSalt?: Uint8Array;
34
37
  ratchetWindowSize?: number;
35
38
  failureTolerance?: number;
39
+ keyRingSize?: number;
40
+ keyDerivationFunction?: KeyDerivationFunction;
36
41
  }
37
42
 
38
43
  export const defaultKeyProviderOptions: KeyProviderOptions = {
39
44
  ratchetSalt: DEFAULT_RATCHET_SALT,
40
45
  ratchetWindowSize: DEFAULT_RATCHET_WINDOW_SIZE,
41
46
  failureTolerance: DEFAULT_FAILURE_TOLERANCE,
47
+ keyRingSize: DEFAULT_KEY_RING_SIZE,
48
+ keyDerivationFunction: DEFAULT_KEY_DERIVATION_FUNCTION,
42
49
  };
43
50
 
44
51
  export interface E2EEOptions {
package/src/index.ts CHANGED
@@ -36,7 +36,14 @@ export {
36
36
  TrackSource,
37
37
  } from '@livekit/rtc-ffi-bindings';
38
38
  export { VideoBufferType, VideoCodec, VideoRotation } from '@livekit/rtc-ffi-bindings';
39
- export { ConnectError, Room, RoomEvent, type RoomOptions, type RtcConfiguration } from './room.js';
39
+ export {
40
+ ConnectError,
41
+ Room,
42
+ RoomEvent,
43
+ type RoomDataStreamOptions,
44
+ type RoomOptions,
45
+ type RtcConfiguration,
46
+ } from './room.js';
40
47
  export { RpcError, type PerformRpcParams, type RpcInvocationData } from './rpc.js';
41
48
  export {
42
49
  LocalAudioTrack,