@livekit/rtc-node 0.10.3 → 0.11.0

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 (136) hide show
  1. package/README.md +54 -2
  2. package/build.rs +1 -1
  3. package/dist/audio_frame.d.ts +1 -1
  4. package/dist/audio_frame.d.ts.map +1 -1
  5. package/dist/audio_frame.js +4 -4
  6. package/dist/audio_frame.js.map +1 -1
  7. package/dist/audio_resampler.d.ts.map +1 -1
  8. package/dist/audio_resampler.js +8 -7
  9. package/dist/audio_resampler.js.map +1 -1
  10. package/dist/audio_source.d.ts.map +1 -1
  11. package/dist/audio_source.js +8 -4
  12. package/dist/audio_source.js.map +1 -1
  13. package/dist/audio_stream.d.ts +1 -1
  14. package/dist/audio_stream.d.ts.map +1 -1
  15. package/dist/audio_stream.js +4 -3
  16. package/dist/audio_stream.js.map +1 -1
  17. package/dist/e2ee.d.ts.map +1 -1
  18. package/dist/e2ee.js +25 -25
  19. package/dist/e2ee.js.map +1 -1
  20. package/dist/ffi_client.d.ts +3 -3
  21. package/dist/ffi_client.d.ts.map +1 -1
  22. package/dist/ffi_client.js +9 -7
  23. package/dist/ffi_client.js.map +1 -1
  24. package/dist/index.d.ts +29 -1
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +34 -4
  27. package/dist/index.js.map +1 -1
  28. package/dist/napi/native.d.ts +1 -0
  29. package/dist/participant.d.ts +52 -6
  30. package/dist/participant.d.ts.map +1 -1
  31. package/dist/participant.js +155 -32
  32. package/dist/participant.js.map +1 -1
  33. package/dist/proto/audio_frame_pb.d.ts +451 -526
  34. package/dist/proto/audio_frame_pb.d.ts.map +1 -1
  35. package/dist/proto/audio_frame_pb.js +200 -1179
  36. package/dist/proto/audio_frame_pb.js.map +1 -1
  37. package/dist/proto/e2ee_pb.d.ts +264 -333
  38. package/dist/proto/e2ee_pb.d.ts.map +1 -1
  39. package/dist/proto/e2ee_pb.js +136 -810
  40. package/dist/proto/e2ee_pb.js.map +1 -1
  41. package/dist/proto/ffi_pb.d.ts +175 -129
  42. package/dist/proto/ffi_pb.d.ts.map +1 -1
  43. package/dist/proto/ffi_pb.js +58 -395
  44. package/dist/proto/ffi_pb.js.map +1 -1
  45. package/dist/proto/handle_pb.d.ts +14 -13
  46. package/dist/proto/handle_pb.d.ts.map +1 -1
  47. package/dist/proto/handle_pb.js +8 -39
  48. package/dist/proto/handle_pb.js.map +1 -1
  49. package/dist/proto/participant_pb.d.ts +54 -52
  50. package/dist/proto/participant_pb.d.ts.map +1 -1
  51. package/dist/proto/participant_pb.js +18 -90
  52. package/dist/proto/participant_pb.js.map +1 -1
  53. package/dist/proto/room_pb.d.ts +1042 -1187
  54. package/dist/proto/room_pb.d.ts.map +1 -1
  55. package/dist/proto/room_pb.js +470 -2938
  56. package/dist/proto/room_pb.js.map +1 -1
  57. package/dist/proto/rpc_pb.d.ts +235 -0
  58. package/dist/proto/rpc_pb.d.ts.map +1 -0
  59. package/dist/proto/rpc_pb.js +74 -0
  60. package/dist/proto/rpc_pb.js.map +1 -0
  61. package/dist/proto/stats_pb.d.ts +738 -800
  62. package/dist/proto/stats_pb.d.ts.map +1 -1
  63. package/dist/proto/stats_pb.js +218 -1960
  64. package/dist/proto/stats_pb.js.map +1 -1
  65. package/dist/proto/track_pb.d.ts +225 -258
  66. package/dist/proto/track_pb.d.ts.map +1 -1
  67. package/dist/proto/track_pb.js +98 -591
  68. package/dist/proto/track_pb.js.map +1 -1
  69. package/dist/proto/video_frame_pb.d.ts +357 -390
  70. package/dist/proto/video_frame_pb.d.ts.map +1 -1
  71. package/dist/proto/video_frame_pb.js +137 -790
  72. package/dist/proto/video_frame_pb.js.map +1 -1
  73. package/dist/room.d.ts +21 -7
  74. package/dist/room.d.ts.map +1 -1
  75. package/dist/room.js +134 -54
  76. package/dist/room.js.map +1 -1
  77. package/dist/rpc.d.ts +78 -0
  78. package/dist/rpc.d.ts.map +1 -0
  79. package/dist/rpc.js +69 -0
  80. package/dist/rpc.js.map +1 -0
  81. package/dist/track.d.ts.map +1 -1
  82. package/dist/track.js +7 -3
  83. package/dist/track.js.map +1 -1
  84. package/dist/track_publication.d.ts.map +1 -1
  85. package/dist/track_publication.js +3 -2
  86. package/dist/track_publication.js.map +1 -1
  87. package/dist/version.d.ts +2 -0
  88. package/dist/version.d.ts.map +1 -0
  89. package/dist/version.js +2 -0
  90. package/dist/version.js.map +1 -0
  91. package/dist/video_frame.d.ts +2 -2
  92. package/dist/video_frame.d.ts.map +1 -1
  93. package/dist/video_frame.js +47 -25
  94. package/dist/video_frame.js.map +1 -1
  95. package/dist/video_source.d.ts.map +1 -1
  96. package/dist/video_source.js +4 -3
  97. package/dist/video_source.js.map +1 -1
  98. package/dist/video_stream.d.ts +1 -1
  99. package/dist/video_stream.d.ts.map +1 -1
  100. package/dist/video_stream.js +7 -3
  101. package/dist/video_stream.js.map +1 -1
  102. package/package.json +13 -10
  103. package/src/audio_frame.ts +6 -6
  104. package/src/audio_resampler.ts +10 -9
  105. package/src/audio_source.ts +9 -8
  106. package/src/audio_stream.ts +7 -6
  107. package/src/e2ee.ts +34 -34
  108. package/src/ffi_client.ts +23 -10
  109. package/src/index.ts +61 -2
  110. package/src/napi/native.d.ts +1 -0
  111. package/src/nodejs.rs +6 -3
  112. package/src/participant.ts +219 -55
  113. package/src/proto/audio_frame_pb.ts +562 -1279
  114. package/src/proto/e2ee_pb.ts +365 -886
  115. package/src/proto/ffi_pb.ts +206 -405
  116. package/src/proto/handle_pb.ts +21 -35
  117. package/src/proto/participant_pb.ts +71 -112
  118. package/src/proto/room_pb.ts +1284 -2995
  119. package/src/proto/rpc_pb.ts +310 -0
  120. package/src/proto/stats_pb.ts +1028 -1947
  121. package/src/proto/track_pb.ts +287 -621
  122. package/src/proto/video_frame_pb.ts +445 -905
  123. package/src/room.ts +181 -75
  124. package/src/rpc.ts +121 -0
  125. package/src/track.ts +8 -7
  126. package/src/track_publication.ts +5 -4
  127. package/src/version.ts +1 -0
  128. package/src/video_frame.ts +54 -27
  129. package/src/video_source.ts +7 -6
  130. package/src/video_stream.ts +7 -6
  131. package/dist/utils.d.ts +0 -7
  132. package/dist/utils.d.ts.map +0 -1
  133. package/dist/utils.js +0 -48
  134. package/dist/utils.js.map +0 -1
  135. package/src/utils.test.ts +0 -47
  136. package/src/utils.ts +0 -44
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "LiveKit RTC Node",
4
4
  "license": "Apache-2.0",
5
5
  "author": "LiveKit",
6
- "version": "0.10.3",
6
+ "version": "0.11.0",
7
7
  "main": "dist/index.js",
8
8
  "types": "dist/index.d.ts",
9
9
  "type": "module",
@@ -33,27 +33,30 @@
33
33
  }
34
34
  },
35
35
  "dependencies": {
36
- "@bufbuild/protobuf": "^1.4.2",
36
+ "@bufbuild/protobuf": "^2.2.0",
37
+ "@livekit/mutex": "^1.0.0",
37
38
  "@livekit/typed-emitter": "^3.0.0"
38
39
  },
39
40
  "devDependencies": {
41
+ "@bufbuild/protoc-gen-es": "^2.2.0",
40
42
  "@napi-rs/cli": "^2.18.0",
41
43
  "@types/node": "^20.9.2",
42
- "typescript": "^5.2.2",
43
- "prettier": "^3.0.3"
44
+ "prettier": "^3.0.3",
45
+ "typescript": "^5.2.2"
44
46
  },
45
47
  "optionalDependencies": {
46
- "@livekit/rtc-node-darwin-arm64": "0.10.3",
47
- "@livekit/rtc-node-darwin-x64": "0.10.3",
48
- "@livekit/rtc-node-linux-arm64-gnu": "0.10.3",
49
- "@livekit/rtc-node-linux-x64-gnu": "0.10.3",
50
- "@livekit/rtc-node-win32-x64-msvc": "0.10.3"
48
+ "@livekit/rtc-node-darwin-arm64": "0.11.0",
49
+ "@livekit/rtc-node-darwin-x64": "0.11.0",
50
+ "@livekit/rtc-node-linux-arm64-gnu": "0.11.0",
51
+ "@livekit/rtc-node-linux-x64-gnu": "0.11.0",
52
+ "@livekit/rtc-node-win32-x64-msvc": "0.11.0"
51
53
  },
52
54
  "engines": {
53
55
  "node": ">= 18"
54
56
  },
55
57
  "scripts": {
56
- "build:tsc": "tsc && cp -r src/napi dist/",
58
+ "prebuild": "node -p \"'export const SDK_VERSION = ' + JSON.stringify(require('./package.json').version) + ';'\" > src/version.ts",
59
+ "build:tsc": "pnpm prebuild && tsc && cp -r src/napi dist/",
57
60
  "build": "pnpm build:tsc && napi build --platform --release --dts native.d.ts --js native.cjs --pipe \"prettier -w\" src/napi",
58
61
  "artifacts": "pnpm build:tsc && napi artifacts",
59
62
  "build:debug": "napi build --platform",
@@ -1,9 +1,10 @@
1
1
  // SPDX-FileCopyrightText: 2024 LiveKit, Inc.
2
2
  //
3
3
  // SPDX-License-Identifier: Apache-2.0
4
+ import { create } from '@bufbuild/protobuf';
4
5
  import { FfiClient, FfiHandle } from './ffi_client.js';
5
6
  import type { OwnedAudioFrameBuffer } from './proto/audio_frame_pb.js';
6
- import { AudioFrameBufferInfo } from './proto/audio_frame_pb.js';
7
+ import { type AudioFrameBufferInfo, AudioFrameBufferInfoSchema } from './proto/audio_frame_pb.js';
7
8
 
8
9
  export class AudioFrame {
9
10
  data: Int16Array;
@@ -30,10 +31,10 @@ export class AudioFrame {
30
31
 
31
32
  /** @internal */
32
33
  static fromOwnedInfo(owned: OwnedAudioFrameBuffer): AudioFrame {
33
- const info = owned.info;
34
+ const info = owned.info!;
34
35
  const len = info.numChannels * info.samplesPerChannel * 2; // c_int16
35
36
  const data = FfiClient.instance.copyBuffer(info.dataPtr, len);
36
- new FfiHandle(owned.handle.id).dispose();
37
+ new FfiHandle(owned.handle!.id).dispose();
37
38
  return new AudioFrame(
38
39
  new Int16Array(data.buffer),
39
40
  info.sampleRate,
@@ -44,7 +45,7 @@ export class AudioFrame {
44
45
 
45
46
  /** @internal */
46
47
  protoInfo(): AudioFrameBufferInfo {
47
- return new AudioFrameBufferInfo({
48
+ return create(AudioFrameBufferInfoSchema, {
48
49
  dataPtr: FfiClient.instance.retrievePtr(new Uint8Array(this.data.buffer)),
49
50
  sampleRate: this.sampleRate,
50
51
  numChannels: this.channels,
@@ -63,10 +64,9 @@ export class AudioFrame {
63
64
  * @param buffer - a single AudioFrame or list thereof
64
65
  */
65
66
  export const combineAudioFrames = (buffer: AudioFrame | AudioFrame[]): AudioFrame => {
66
- if (!buffer['length']) {
67
+ if (!Array.isArray(buffer)) {
67
68
  return buffer as AudioFrame;
68
69
  }
69
- buffer = buffer as AudioFrame[];
70
70
 
71
71
  if (buffer.length === 0) {
72
72
  throw new Error('buffer is empty');
@@ -1,6 +1,7 @@
1
1
  // SPDX-FileCopyrightText: 2024 LiveKit, Inc.
2
2
  //
3
3
  // SPDX-License-Identifier: Apache-2.0
4
+ import { create } from '@bufbuild/protobuf';
4
5
  import { AudioFrame } from './audio_frame.js';
5
6
  import { FfiClient, FfiHandle } from './ffi_client.js';
6
7
  import type {
@@ -9,9 +10,9 @@ import type {
9
10
  PushSoxResamplerResponse,
10
11
  } from './proto/audio_frame_pb.js';
11
12
  import {
12
- FlushSoxResamplerRequest,
13
- NewSoxResamplerRequest,
14
- PushSoxResamplerRequest,
13
+ FlushSoxResamplerRequestSchema,
14
+ NewSoxResamplerRequestSchema,
15
+ PushSoxResamplerRequestSchema,
15
16
  SoxQualityRecipe,
16
17
  SoxResamplerDataType,
17
18
  } from './proto/audio_frame_pb.js';
@@ -58,7 +59,7 @@ export class AudioResampler {
58
59
  this.#outputRate = outputRate;
59
60
  this.#channels = channels;
60
61
 
61
- const req = new NewSoxResamplerRequest({
62
+ const req = create(NewSoxResamplerRequestSchema, {
62
63
  inputRate,
63
64
  outputRate,
64
65
  numChannels: channels,
@@ -75,11 +76,11 @@ export class AudioResampler {
75
76
  },
76
77
  });
77
78
 
78
- if (res.error) {
79
- throw new Error(res.error);
79
+ if (res.message.case !== 'resampler') {
80
+ throw new Error(res.message.value ?? 'Unknown Error');
80
81
  }
81
82
 
82
- this.#ffiHandle = new FfiHandle(res.resampler.handle.id);
83
+ this.#ffiHandle = new FfiHandle(res.message.value.handle!.id);
83
84
  }
84
85
 
85
86
  /**
@@ -94,7 +95,7 @@ export class AudioResampler {
94
95
  * be empty if no output data is available yet.
95
96
  */
96
97
  push(data: AudioFrame): AudioFrame[] {
97
- const req = new PushSoxResamplerRequest({
98
+ const req = create(PushSoxResamplerRequestSchema, {
98
99
  resamplerHandle: this.#ffiHandle.handle,
99
100
  dataPtr: data.protoInfo().dataPtr,
100
101
  size: data.data.byteLength,
@@ -134,7 +135,7 @@ export class AudioResampler {
134
135
  * internal buffers are processed and all resampled data is output.
135
136
  */
136
137
  flush(): AudioFrame[] {
137
- const req = new FlushSoxResamplerRequest({
138
+ const req = create(FlushSoxResamplerRequestSchema, {
138
139
  resamplerHandle: this.#ffiHandle.handle,
139
140
  });
140
141
 
@@ -1,6 +1,7 @@
1
1
  // SPDX-FileCopyrightText: 2024 LiveKit, Inc.
2
2
  //
3
3
  // SPDX-License-Identifier: Apache-2.0
4
+ import { create } from '@bufbuild/protobuf';
4
5
  import type { AudioFrame } from './audio_frame.js';
5
6
  import { FfiClient } from './ffi_client.js';
6
7
  import { FfiHandle } from './napi/native.js';
@@ -13,9 +14,9 @@ import type {
13
14
  } from './proto/audio_frame_pb.js';
14
15
  import {
15
16
  AudioSourceType,
16
- CaptureAudioFrameRequest,
17
- ClearAudioBufferRequest,
18
- NewAudioSourceRequest,
17
+ CaptureAudioFrameRequestSchema,
18
+ ClearAudioBufferRequestSchema,
19
+ NewAudioSourceRequestSchema,
19
20
  } from './proto/audio_frame_pb.js';
20
21
 
21
22
  export class AudioSource {
@@ -45,7 +46,7 @@ export class AudioSource {
45
46
  this.lastCapture = 0;
46
47
  this.currentQueueSize = 0;
47
48
 
48
- const req = new NewAudioSourceRequest({
49
+ const req = create(NewAudioSourceRequestSchema, {
49
50
  type: AudioSourceType.AUDIO_SOURCE_NATIVE,
50
51
  sampleRate: sampleRate,
51
52
  numChannels: numChannels,
@@ -59,8 +60,8 @@ export class AudioSource {
59
60
  },
60
61
  });
61
62
 
62
- this.info = res.source.info;
63
- this.ffiHandle = new FfiHandle(res.source.handle.id);
63
+ this.info = res.source!.info!;
64
+ this.ffiHandle = new FfiHandle(res.source!.handle!.id);
64
65
  }
65
66
 
66
67
  get queuedDuration(): number {
@@ -71,7 +72,7 @@ export class AudioSource {
71
72
  }
72
73
 
73
74
  clearQueue() {
74
- const req = new ClearAudioBufferRequest({
75
+ const req = create(ClearAudioBufferRequestSchema, {
75
76
  sourceHandle: this.ffiHandle.handle,
76
77
  });
77
78
 
@@ -116,7 +117,7 @@ export class AudioSource {
116
117
  // (e.g. using wait_for_playout for very small chunks)
117
118
  this.timeout = setTimeout(this.release, this.currentQueueSize - 50);
118
119
 
119
- const req = new CaptureAudioFrameRequest({
120
+ const req = create(CaptureAudioFrameRequestSchema, {
120
121
  sourceHandle: this.ffiHandle.handle,
121
122
  buffer: frame.protoInfo(),
122
123
  });
@@ -1,13 +1,14 @@
1
1
  // SPDX-FileCopyrightText: 2024 LiveKit, Inc.
2
2
  //
3
3
  // SPDX-License-Identifier: Apache-2.0
4
+ import { create } from '@bufbuild/protobuf';
5
+ import { Mutex } from '@livekit/mutex';
4
6
  import { AudioFrame } from './audio_frame.js';
5
7
  import type { FfiEvent } from './ffi_client.js';
6
8
  import { FfiClient, FfiClientEvent, FfiHandle } from './ffi_client.js';
7
9
  import type { AudioStreamInfo, NewAudioStreamResponse } from './proto/audio_frame_pb.js';
8
- import { AudioStreamType, NewAudioStreamRequest } from './proto/audio_frame_pb.js';
10
+ import { AudioStreamType, NewAudioStreamRequestSchema } from './proto/audio_frame_pb.js';
9
11
  import type { Track } from './track.js';
10
- import { Mutex } from './utils.js';
11
12
 
12
13
  export class AudioStream implements AsyncIterableIterator<AudioFrame> {
13
14
  /** @internal */
@@ -30,7 +31,7 @@ export class AudioStream implements AsyncIterableIterator<AudioFrame> {
30
31
  this.sampleRate = sampleRate;
31
32
  this.numChannels = numChannels;
32
33
 
33
- const req = new NewAudioStreamRequest({
34
+ const req = create(NewAudioStreamRequestSchema, {
34
35
  type: AudioStreamType.AUDIO_STREAM_NATIVE,
35
36
  trackHandle: track.ffi_handle.handle,
36
37
  sampleRate: sampleRate,
@@ -44,8 +45,8 @@ export class AudioStream implements AsyncIterableIterator<AudioFrame> {
44
45
  },
45
46
  });
46
47
 
47
- this.info = res.stream.info;
48
- this.ffiHandle = new FfiHandle(res.stream.handle.id);
48
+ this.info = res.stream!.info!;
49
+ this.ffiHandle = new FfiHandle(res.stream!.handle!.id);
49
50
 
50
51
  FfiClient.instance.on(FfiClientEvent.FfiEvent, this.onEvent);
51
52
  }
@@ -61,7 +62,7 @@ export class AudioStream implements AsyncIterableIterator<AudioFrame> {
61
62
  const streamEvent = ev.message.value.message;
62
63
  switch (streamEvent.case) {
63
64
  case 'frameReceived':
64
- const frame = AudioFrame.fromOwnedInfo(streamEvent.value.frame);
65
+ const frame = AudioFrame.fromOwnedInfo(streamEvent.value.frame!);
65
66
  if (this.queueResolve) {
66
67
  this.queueResolve({ done: false, value: frame });
67
68
  } else {
package/src/e2ee.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  // SPDX-FileCopyrightText: 2024 LiveKit, Inc.
2
2
  //
3
3
  // SPDX-License-Identifier: Apache-2.0
4
+ import { create } from '@bufbuild/protobuf';
4
5
  import { FfiClient } from './ffi_client.js';
5
6
  import type {
6
7
  E2eeManagerGetFrameCryptorsResponse,
@@ -11,17 +12,17 @@ import type {
11
12
  RatchetSharedKeyResponse,
12
13
  } from './proto/e2ee_pb.js';
13
14
  import {
14
- E2eeManagerSetEnabledRequest,
15
- E2eeRequest,
15
+ E2eeManagerSetEnabledRequestSchema,
16
+ E2eeRequestSchema,
16
17
  EncryptionType,
17
- FrameCryptorSetEnabledRequest,
18
- FrameCryptorSetKeyIndexRequest,
19
- GetKeyRequest,
20
- GetSharedKeyRequest,
21
- RatchetKeyRequest,
22
- RatchetSharedKeyRequest,
23
- SetKeyRequest,
24
- SetSharedKeyRequest,
18
+ FrameCryptorSetEnabledRequestSchema,
19
+ FrameCryptorSetKeyIndexRequestSchema,
20
+ GetKeyRequestSchema,
21
+ GetSharedKeyRequestSchema,
22
+ RatchetKeyRequestSchema,
23
+ RatchetSharedKeyRequestSchema,
24
+ SetKeyRequestSchema,
25
+ SetSharedKeyRequestSchema,
25
26
  } from './proto/e2ee_pb.js';
26
27
 
27
28
  const DEFAULT_RATCHET_SALT = new TextEncoder().encode('LKFrameEncryptionKey');
@@ -62,11 +63,11 @@ export class KeyProvider {
62
63
  }
63
64
 
64
65
  setSharedKey(sharedKey: Uint8Array, keyIndex: number) {
65
- const req = new E2eeRequest({
66
+ const req = create(E2eeRequestSchema, {
66
67
  roomHandle: this.roomHandle,
67
68
  message: {
68
69
  case: 'setSharedKey',
69
- value: new SetSharedKeyRequest({
70
+ value: create(SetSharedKeyRequestSchema, {
70
71
  keyIndex: keyIndex,
71
72
  sharedKey: sharedKey,
72
73
  }),
@@ -82,11 +83,11 @@ export class KeyProvider {
82
83
  }
83
84
 
84
85
  exportSharedKey(keyIndex: number): Uint8Array {
85
- const req = new E2eeRequest({
86
+ const req = create(E2eeRequestSchema, {
86
87
  roomHandle: this.roomHandle,
87
88
  message: {
88
89
  case: 'getSharedKey',
89
- value: new GetSharedKeyRequest({
90
+ value: create(GetSharedKeyRequestSchema, {
90
91
  keyIndex: keyIndex,
91
92
  }),
92
93
  },
@@ -103,11 +104,11 @@ export class KeyProvider {
103
104
  }
104
105
 
105
106
  ratchetSharedKey(keyIndex: number): Uint8Array {
106
- const req = new E2eeRequest({
107
+ const req = create(E2eeRequestSchema, {
107
108
  roomHandle: this.roomHandle,
108
109
  message: {
109
110
  case: 'ratchetSharedKey',
110
- value: new RatchetSharedKeyRequest({
111
+ value: create(RatchetSharedKeyRequestSchema, {
111
112
  keyIndex: keyIndex,
112
113
  }),
113
114
  },
@@ -124,11 +125,11 @@ export class KeyProvider {
124
125
  }
125
126
 
126
127
  setKey(participantIdentity: string, keyIndex: number) {
127
- const req = new E2eeRequest({
128
+ const req = create(E2eeRequestSchema, {
128
129
  roomHandle: this.roomHandle,
129
130
  message: {
130
131
  case: 'setKey',
131
- value: new SetKeyRequest({
132
+ value: create(SetKeyRequestSchema, {
132
133
  keyIndex: keyIndex,
133
134
  participantIdentity: participantIdentity,
134
135
  }),
@@ -144,11 +145,11 @@ export class KeyProvider {
144
145
  }
145
146
 
146
147
  exportKey(participantIdentity: string, keyIndex: number): Uint8Array {
147
- const req = new E2eeRequest({
148
+ const req = create(E2eeRequestSchema, {
148
149
  roomHandle: this.roomHandle,
149
150
  message: {
150
151
  case: 'getKey',
151
- value: new GetKeyRequest({
152
+ value: create(GetKeyRequestSchema, {
152
153
  keyIndex: keyIndex,
153
154
  participantIdentity: participantIdentity,
154
155
  }),
@@ -166,11 +167,11 @@ export class KeyProvider {
166
167
  }
167
168
 
168
169
  ratchetKey(participantIdentity: string, keyIndex: number): Uint8Array {
169
- const req = new E2eeRequest({
170
+ const req = create(E2eeRequestSchema, {
170
171
  roomHandle: this.roomHandle,
171
172
  message: {
172
173
  case: 'ratchetKey',
173
- value: new RatchetKeyRequest({
174
+ value: create(RatchetKeyRequestSchema, {
174
175
  keyIndex: keyIndex,
175
176
  participantIdentity: participantIdentity,
176
177
  }),
@@ -203,11 +204,11 @@ export class FrameCryptor {
203
204
 
204
205
  setEnabled(enabled: boolean) {
205
206
  this.enabled = enabled;
206
- const req = new E2eeRequest({
207
+ const req = create(E2eeRequestSchema, {
207
208
  roomHandle: this.roomHandle,
208
209
  message: {
209
210
  case: 'cryptorSetEnabled',
210
- value: new FrameCryptorSetEnabledRequest({
211
+ value: create(FrameCryptorSetEnabledRequestSchema, {
211
212
  participantIdentity: this.participantIdentity,
212
213
  enabled: this.enabled,
213
214
  }),
@@ -224,11 +225,11 @@ export class FrameCryptor {
224
225
 
225
226
  setKeyIndex(keyIndex: number) {
226
227
  this.keyIndex = keyIndex;
227
- const req = new E2eeRequest({
228
+ const req = create(E2eeRequestSchema, {
228
229
  roomHandle: this.roomHandle,
229
230
  message: {
230
231
  case: 'cryptorSetKeyIndex',
231
- value: new FrameCryptorSetKeyIndexRequest({
232
+ value: create(FrameCryptorSetKeyIndexRequestSchema, {
232
233
  participantIdentity: this.participantIdentity,
233
234
  keyIndex: this.keyIndex,
234
235
  }),
@@ -255,21 +256,20 @@ export class E2EEManager {
255
256
  this.roomHandle = roomHandle;
256
257
  this.enabled = opts !== undefined;
257
258
 
258
- if (opts !== undefined) {
259
- const options = { ...defaultE2EEOptions, ...opts };
259
+ opts ??= defaultE2EEOptions;
260
+ const options = { ...defaultE2EEOptions, ...opts };
260
261
 
261
- this.options = options;
262
- this.keyProvider = new KeyProvider(roomHandle, options.keyProviderOptions);
263
- }
262
+ this.options = options;
263
+ this.keyProvider = new KeyProvider(roomHandle, options.keyProviderOptions);
264
264
  }
265
265
 
266
266
  setEnabled(enabled: boolean) {
267
267
  this.enabled = enabled;
268
- const req = new E2eeRequest({
268
+ const req = create(E2eeRequestSchema, {
269
269
  roomHandle: this.roomHandle,
270
270
  message: {
271
271
  case: 'managerSetEnabled',
272
- value: new E2eeManagerSetEnabledRequest({
272
+ value: create(E2eeManagerSetEnabledRequestSchema, {
273
273
  enabled: this.enabled,
274
274
  }),
275
275
  },
@@ -284,7 +284,7 @@ export class E2EEManager {
284
284
  }
285
285
 
286
286
  frameCryptors(): FrameCryptor[] {
287
- const req = new E2eeRequest({
287
+ const req = create(E2eeRequestSchema, {
288
288
  roomHandle: this.roomHandle,
289
289
  message: {
290
290
  case: 'managerGetFrameCryptors',
package/src/ffi_client.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  // SPDX-FileCopyrightText: 2024 LiveKit, Inc.
2
2
  //
3
3
  // SPDX-License-Identifier: Apache-2.0
4
- import type { PartialMessage } from '@bufbuild/protobuf';
4
+ import type { MessageInitShape } from '@bufbuild/protobuf';
5
+ import { create, fromBinary, toBinary } from '@bufbuild/protobuf';
5
6
  import type { TypedEventEmitter as TypedEmitter } from '@livekit/typed-emitter';
6
7
  import EventEmitter from 'events';
7
8
  import {
@@ -12,7 +13,15 @@ import {
12
13
  livekitInitialize,
13
14
  livekitRetrievePtr,
14
15
  } from './napi/native.js';
15
- import { FfiEvent, FfiRequest, FfiResponse } from './proto/ffi_pb.js';
16
+ import {
17
+ FfiEvent,
18
+ FfiEventSchema,
19
+ FfiRequest,
20
+ FfiRequestSchema,
21
+ FfiResponse,
22
+ FfiResponseSchema,
23
+ } from './proto/ffi_pb.js';
24
+ import { SDK_VERSION } from './version.js';
16
25
 
17
26
  export { FfiHandle, FfiEvent, FfiResponse, FfiRequest, livekitDispose as dispose };
18
27
 
@@ -38,17 +47,21 @@ export class FfiClient extends (EventEmitter as new () => TypedEmitter<FfiClient
38
47
  super();
39
48
  this.setMaxListeners(0);
40
49
 
41
- livekitInitialize((event_data: Uint8Array) => {
42
- const event = FfiEvent.fromBinary(event_data);
43
- this.emit(FfiClientEvent.FfiEvent, event);
44
- }, true);
50
+ livekitInitialize(
51
+ (event_data: Uint8Array) => {
52
+ const event = fromBinary(FfiEventSchema, event_data);
53
+ this.emit(FfiClientEvent.FfiEvent, event);
54
+ },
55
+ true,
56
+ SDK_VERSION,
57
+ );
45
58
  }
46
59
 
47
- request<T>(req: PartialMessage<FfiRequest>): T {
48
- const request = new FfiRequest(req);
49
- const req_data = request.toBinary();
60
+ request<T>(req: MessageInitShape<typeof FfiRequestSchema>): T {
61
+ const request = create(FfiRequestSchema, req);
62
+ const req_data = toBinary(FfiRequestSchema, request);
50
63
  const res_data = livekitFfiRequest(req_data);
51
- return FfiResponse.fromBinary(res_data).message.value as T;
64
+ return fromBinary(FfiResponseSchema, res_data).message.value as T;
52
65
  }
53
66
 
54
67
  copyBuffer(ptr: bigint, len: number): Uint8Array {
package/src/index.ts CHANGED
@@ -1,6 +1,18 @@
1
1
  // SPDX-FileCopyrightText: 2024 LiveKit, Inc.
2
2
  //
3
3
  // SPDX-License-Identifier: Apache-2.0
4
+ import type { MessageInitShape } from '@bufbuild/protobuf';
5
+ import { create } from '@bufbuild/protobuf';
6
+ import type { AudioEncoding, TrackPublishOptionsSchema, VideoEncoding } from './proto/room_pb.js';
7
+ import {
8
+ AudioEncodingSchema,
9
+ IceServerSchema,
10
+ type IceServer as IceServerType,
11
+ type TrackPublishOptions as TrackPublishOptionsType,
12
+ VideoEncodingSchema,
13
+ } from './proto/room_pb.js';
14
+ import { TrackSource } from './proto/track_pb.js';
15
+ import { VideoCodec } from './proto/video_frame_pb.js';
4
16
 
5
17
  export { Room, RoomEvent, ConnectError, RoomOptions, RtcConfiguration } from './room.js';
6
18
  export { Participant, RemoteParticipant, LocalParticipant } from './participant.js';
@@ -29,18 +41,65 @@ export {
29
41
  } from './track_publication.js';
30
42
  export { Transcription, TranscriptionSegment } from './transcription.js';
31
43
  export { E2EEManager, E2EEOptions, KeyProviderOptions, KeyProvider, FrameCryptor } from './e2ee.js';
44
+
32
45
  export {
33
46
  ConnectionQuality,
34
- IceServer,
35
47
  IceTransportType,
36
48
  DataPacketKind,
37
49
  ContinualGatheringPolicy,
38
- TrackPublishOptions,
39
50
  ConnectionState,
40
51
  } from './proto/room_pb.js';
52
+ export { RpcError, type RpcInvocationData, type PerformRpcParams } from './rpc.js';
41
53
  export { EncryptionType, EncryptionState } from './proto/e2ee_pb.js';
42
54
  export { StreamState, TrackKind, TrackSource } from './proto/track_pb.js';
43
55
  export { VideoBufferType, VideoRotation, VideoCodec } from './proto/video_frame_pb.js';
44
56
  export { ParticipantKind } from './proto/participant_pb.js';
45
57
  export { dispose } from './ffi_client.js';
46
58
  export type { ChatMessage } from './types.js';
59
+
60
+ // exposing helpers for API compatibility with 1.x version of protobuf-es where these were class instances
61
+
62
+ type IceServerInit = MessageInitShape<typeof IceServerSchema> & {
63
+ urls: string[];
64
+ };
65
+ export class IceServer implements IceServerType {
66
+ $typeName = 'livekit.proto.IceServer' as const;
67
+ urls: string[];
68
+ username: string;
69
+ password: string;
70
+ constructor(init: IceServerInit) {
71
+ const { urls, username, password } = init;
72
+ this.urls = urls;
73
+ this.username = username ?? '';
74
+ this.password = password ?? '';
75
+ create(IceServerSchema, init);
76
+ }
77
+ }
78
+
79
+ export class TrackPublishOptions implements TrackPublishOptionsType {
80
+ $typeName = 'livekit.proto.TrackPublishOptions' as const;
81
+ videoCodec: VideoCodec;
82
+ videoEncoding?: VideoEncoding | undefined;
83
+ audioEncoding?: AudioEncoding | undefined;
84
+ dtx: boolean;
85
+ simulcast: boolean;
86
+ source: TrackSource;
87
+ stream: string;
88
+ red: boolean;
89
+
90
+ constructor(init: MessageInitShape<typeof TrackPublishOptionsSchema> = {}) {
91
+ const { videoCodec, videoEncoding, audioEncoding, dtx, simulcast, source, stream, red } = init;
92
+ this.videoCodec = videoCodec ?? VideoCodec.VP8;
93
+ if (videoEncoding) {
94
+ this.videoEncoding = create(VideoEncodingSchema, videoEncoding);
95
+ }
96
+ if (audioEncoding) {
97
+ this.audioEncoding = create(AudioEncodingSchema, audioEncoding);
98
+ }
99
+ this.dtx = dtx ?? false;
100
+ this.simulcast = simulcast ?? false;
101
+ this.source = source ?? TrackSource.SOURCE_UNKNOWN;
102
+ this.stream = stream ?? '';
103
+ this.red = red ?? false;
104
+ }
105
+ }
@@ -6,6 +6,7 @@
6
6
  export declare function livekitInitialize(
7
7
  callback: (data: Uint8Array) => void,
8
8
  captureLogs: boolean,
9
+ sdkVersion: string,
9
10
  ): void;
10
11
  export declare function livekitFfiRequest(data: Uint8Array): Uint8Array;
11
12
  export declare function livekitRetrievePtr(handle: Uint8Array): bigint;
package/src/nodejs.rs CHANGED
@@ -2,7 +2,6 @@
2
2
  //
3
3
  // SPDX-License-Identifier: Apache-2.0
4
4
 
5
- use livekit_ffi::FfiHandleId;
6
5
  use livekit_ffi::{proto, server, FFI_SERVER};
7
6
  use napi::{
8
7
  bindgen_prelude::*,
@@ -15,8 +14,10 @@ use napi_derive::napi;
15
14
  use prost::Message;
16
15
  use std::sync::Arc;
17
16
 
18
- #[napi(ts_args_type = "callback: (data: Uint8Array) => void, captureLogs: boolean")]
19
- fn livekit_initialize(cb: JsFunction, capture_logs: bool) {
17
+ #[napi(
18
+ ts_args_type = "callback: (data: Uint8Array) => void, captureLogs: boolean, sdkVersion: string"
19
+ )]
20
+ fn livekit_initialize(cb: JsFunction, capture_logs: bool, sdk_version: String) {
20
21
  let tsfn: ThreadsafeFunction<proto::FfiEvent, ErrorStrategy::Fatal> = cb
21
22
  .create_threadsafe_function(0, |ctx: ThreadSafeCallContext<proto::FfiEvent>| {
22
23
  let data = ctx.value.encode_to_vec();
@@ -33,6 +34,8 @@ fn livekit_initialize(cb: JsFunction, capture_logs: bool) {
33
34
  }
34
35
  }),
35
36
  capture_logs,
37
+ sdk: "node".to_string(),
38
+ sdk_version,
36
39
  });
37
40
  }
38
41