@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
@@ -1,10 +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 { OwnedParticipant, ParticipantInfo, ParticipantKind } from './proto/participant_pb.js';
6
- import {
7
- ChatMessage as ChatMessageModel,
7
+ import type {
8
8
  PublishDataCallback,
9
9
  PublishDataResponse,
10
10
  PublishSipDtmfCallback,
@@ -26,23 +26,38 @@ import {
26
26
  UnpublishTrackResponse,
27
27
  } from './proto/room_pb.js';
28
28
  import {
29
- EditChatMessageRequest,
30
- TranscriptionSegment as ProtoTranscriptionSegment,
31
- PublishDataRequest,
32
- PublishSipDtmfRequest,
33
- PublishTrackRequest,
34
- PublishTranscriptionRequest,
35
- SendChatMessageRequest,
36
- SetLocalAttributesRequest,
37
- SetLocalMetadataRequest,
38
- SetLocalNameRequest,
39
- UnpublishTrackRequest,
29
+ ChatMessageSchema,
30
+ EditChatMessageRequestSchema,
31
+ PublishDataRequestSchema,
32
+ PublishSipDtmfRequestSchema,
33
+ PublishTrackRequestSchema,
34
+ PublishTranscriptionRequestSchema,
35
+ SendChatMessageRequestSchema,
36
+ SetLocalAttributesRequestSchema,
37
+ SetLocalMetadataRequestSchema,
38
+ SetLocalNameRequestSchema,
39
+ UnpublishTrackRequestSchema,
40
40
  } from './proto/room_pb.js';
41
+ import { TranscriptionSegmentSchema } from './proto/room_pb.js';
42
+ import {
43
+ PerformRpcRequestSchema,
44
+ RegisterRpcMethodRequestSchema,
45
+ RpcMethodInvocationResponseRequestSchema,
46
+ UnregisterRpcMethodRequestSchema,
47
+ } from './proto/rpc_pb.js';
48
+ import type {
49
+ PerformRpcCallback,
50
+ PerformRpcResponse,
51
+ RegisterRpcMethodResponse,
52
+ RpcMethodInvocationResponseResponse,
53
+ UnregisterRpcMethodResponse,
54
+ } from './proto/rpc_pb.js';
55
+ import { type PerformRpcParams, RpcError, type RpcInvocationData } from './rpc.js';
41
56
  import type { LocalTrack } from './track.js';
42
57
  import type { RemoteTrackPublication, TrackPublication } from './track_publication.js';
43
58
  import { LocalTrackPublication } from './track_publication.js';
44
59
  import type { Transcription } from './transcription.js';
45
- import { ChatMessage } from './types.js';
60
+ import type { ChatMessage } from './types.js';
46
61
 
47
62
  export abstract class Participant {
48
63
  /** @internal */
@@ -54,8 +69,8 @@ export abstract class Participant {
54
69
  trackPublications = new Map<string, TrackPublication>();
55
70
 
56
71
  constructor(owned_info: OwnedParticipant) {
57
- this.info = owned_info.info;
58
- this.ffi_handle = new FfiHandle(owned_info.handle.id);
72
+ this.info = owned_info.info!;
73
+ this.ffi_handle = new FfiHandle(owned_info.handle!.id);
59
74
  }
60
75
 
61
76
  get sid(): string {
@@ -100,10 +115,12 @@ export type DataPublishOptions = {
100
115
  };
101
116
 
102
117
  export class LocalParticipant extends Participant {
118
+ private rpcHandlers: Map<string, (data: RpcInvocationData) => Promise<string>> = new Map();
119
+
103
120
  trackPublications: Map<string, LocalTrackPublication> = new Map();
104
121
 
105
122
  async publishData(data: Uint8Array, options: DataPublishOptions) {
106
- const req = new PublishDataRequest({
123
+ const req = create(PublishDataRequestSchema, {
107
124
  localParticipantHandle: this.ffi_handle.handle,
108
125
  dataPtr: FfiClient.instance.retrievePtr(data),
109
126
  dataLen: BigInt(data.byteLength),
@@ -126,7 +143,7 @@ export class LocalParticipant extends Participant {
126
143
  }
127
144
 
128
145
  async publishDtmf(code: number, digit: string) {
129
- const req = new PublishSipDtmfRequest({
146
+ const req = create(PublishSipDtmfRequestSchema, {
130
147
  localParticipantHandle: this.ffi_handle.handle,
131
148
  code,
132
149
  digit,
@@ -146,19 +163,18 @@ export class LocalParticipant extends Participant {
146
163
  }
147
164
 
148
165
  async publishTranscription(transcription: Transcription) {
149
- const req = new PublishTranscriptionRequest({
166
+ const req = create(PublishTranscriptionRequestSchema, {
150
167
  localParticipantHandle: this.ffi_handle.handle,
151
168
  participantIdentity: transcription.participantIdentity,
152
- segments: transcription.segments.map(
153
- (s) =>
154
- new ProtoTranscriptionSegment({
155
- id: s.id,
156
- text: s.text,
157
- startTime: s.startTime,
158
- endTime: s.endTime,
159
- final: s.final,
160
- language: s.language,
161
- }),
169
+ segments: transcription.segments.map((s) =>
170
+ create(TranscriptionSegmentSchema, {
171
+ id: s.id,
172
+ text: s.text,
173
+ startTime: s.startTime,
174
+ endTime: s.endTime,
175
+ final: s.final,
176
+ language: s.language,
177
+ }),
162
178
  ),
163
179
  trackId: transcription.trackSid,
164
180
  });
@@ -177,7 +193,7 @@ export class LocalParticipant extends Participant {
177
193
  }
178
194
 
179
195
  async updateMetadata(metadata: string) {
180
- const req = new SetLocalMetadataRequest({
196
+ const req = create(SetLocalMetadataRequestSchema, {
181
197
  localParticipantHandle: this.ffi_handle.handle,
182
198
  metadata: metadata,
183
199
  });
@@ -192,6 +208,11 @@ export class LocalParticipant extends Participant {
192
208
  }
193
209
 
194
210
  /**
211
+ * Sends a chat message to participants in the room
212
+ *
213
+ * @param text - The text content of the chat message.
214
+ * @param destinationIdentities - An optional array of recipient identities to whom the message will be sent. If omitted, the message is broadcast to all participants.
215
+ * @param senderIdentity - An optional identity of the sender. If omitted, the default sender identity is used.
195
216
  *
196
217
  */
197
218
  async sendChatMessage(
@@ -199,7 +220,7 @@ export class LocalParticipant extends Participant {
199
220
  destinationIdentities?: Array<string>,
200
221
  senderIdentity?: string,
201
222
  ): Promise<ChatMessage> {
202
- const req = new SendChatMessageRequest({
223
+ const req = create(SendChatMessageRequestSchema, {
203
224
  localParticipantHandle: this.ffi_handle.handle,
204
225
  message: text,
205
226
  destinationIdentities,
@@ -214,20 +235,15 @@ export class LocalParticipant extends Participant {
214
235
  return ev.message.case == 'chatMessage' && ev.message.value.asyncId == res.asyncId;
215
236
  });
216
237
 
217
- if (cb.error) {
218
- throw new Error(cb.error);
238
+ if (cb.message.case !== 'chatMessage') {
239
+ throw new Error(cb.message.value ?? 'Unknown Error');
219
240
  }
220
- const { id, timestamp, editTimestamp, message } = cb.chatMessage;
241
+ const { id, timestamp, editTimestamp, message } = cb.message.value;
221
242
  return { id, timestamp: Number(timestamp), editTimestamp: Number(editTimestamp), message };
222
243
  }
223
244
 
224
245
  /**
225
- * Sends a chat message to participants in the room
226
- *
227
- * @param text - The text content of the chat message.
228
- * @param destinationIdentities - An optional array of recipient identities to whom the message will be sent. If omitted, the message is broadcast to all participants.
229
- * @param senderIdentity - An optional identity of the sender. If omitted, the default sender identity is used.
230
- *
246
+ * @experimental
231
247
  */
232
248
  async editChatMessage(
233
249
  editText: string,
@@ -235,13 +251,15 @@ export class LocalParticipant extends Participant {
235
251
  destinationIdentities?: Array<string>,
236
252
  senderIdentity?: string,
237
253
  ): Promise<ChatMessage> {
238
- const req = new EditChatMessageRequest({
254
+ const req = create(EditChatMessageRequestSchema, {
239
255
  localParticipantHandle: this.ffi_handle.handle,
240
256
  editText,
241
- originalMessage: new ChatMessageModel({
257
+ originalMessage: create(ChatMessageSchema, {
242
258
  ...originalMessage,
243
259
  timestamp: BigInt(originalMessage.timestamp),
244
- editTimestamp: BigInt(originalMessage.editTimestamp),
260
+ editTimestamp: originalMessage.editTimestamp
261
+ ? BigInt(originalMessage.editTimestamp)
262
+ : undefined,
245
263
  }),
246
264
  destinationIdentities,
247
265
  senderIdentity,
@@ -255,15 +273,15 @@ export class LocalParticipant extends Participant {
255
273
  return ev.message.case == 'chatMessage' && ev.message.value.asyncId == res.asyncId;
256
274
  });
257
275
 
258
- if (cb.error) {
259
- throw new Error(cb.error);
276
+ if (cb.message.case !== 'chatMessage') {
277
+ throw new Error(cb.message.value ?? 'Unknown Error');
260
278
  }
261
- const { id, timestamp, editTimestamp, message } = cb.chatMessage;
279
+ const { id, timestamp, editTimestamp, message } = cb.message.value;
262
280
  return { id, timestamp: Number(timestamp), editTimestamp: Number(editTimestamp), message };
263
281
  }
264
282
 
265
283
  async updateName(name: string) {
266
- const req = new SetLocalNameRequest({
284
+ const req = create(SetLocalNameRequestSchema, {
267
285
  localParticipantHandle: this.ffi_handle.handle,
268
286
  name: name,
269
287
  });
@@ -278,9 +296,11 @@ export class LocalParticipant extends Participant {
278
296
  }
279
297
 
280
298
  async setAttributes(attributes: Record<string, string>) {
281
- const req = new SetLocalAttributesRequest({
299
+ const req = create(SetLocalAttributesRequestSchema, {
282
300
  localParticipantHandle: this.ffi_handle.handle,
283
- attributes: attributes,
301
+ attributes: Array.from(Object.entries(attributes)).map(([key, value]) => {
302
+ return { key, value };
303
+ }),
284
304
  });
285
305
 
286
306
  const res = FfiClient.instance.request<SetLocalAttributesResponse>({
@@ -296,7 +316,7 @@ export class LocalParticipant extends Participant {
296
316
  track: LocalTrack,
297
317
  options: TrackPublishOptions,
298
318
  ): Promise<LocalTrackPublication> {
299
- const req = new PublishTrackRequest({
319
+ const req = create(PublishTrackRequestSchema, {
300
320
  localParticipantHandle: this.ffi_handle.handle,
301
321
  trackHandle: track.ffi_handle.handle,
302
322
  options: options,
@@ -310,11 +330,11 @@ export class LocalParticipant extends Participant {
310
330
  return ev.message.case == 'publishTrack' && ev.message.value.asyncId == res.asyncId;
311
331
  });
312
332
 
313
- if (cb.error) {
314
- throw new Error(cb.error);
333
+ if (cb.message.case !== 'publication') {
334
+ throw new Error(cb.message.value ?? 'Unknown Error');
315
335
  }
316
336
 
317
- const track_publication = new LocalTrackPublication(cb.publication);
337
+ const track_publication = new LocalTrackPublication(cb.message.value!);
318
338
  track_publication.track = track;
319
339
  this.trackPublications.set(track_publication.sid, track_publication);
320
340
 
@@ -322,7 +342,7 @@ export class LocalParticipant extends Participant {
322
342
  }
323
343
 
324
344
  async unpublishTrack(trackSid: string) {
325
- const req = new UnpublishTrackRequest({
345
+ const req = create(UnpublishTrackRequestSchema, {
326
346
  localParticipantHandle: this.ffi_handle.handle,
327
347
  trackSid: trackSid,
328
348
  });
@@ -340,9 +360,153 @@ export class LocalParticipant extends Participant {
340
360
  }
341
361
 
342
362
  const pub = this.trackPublications.get(trackSid);
343
- pub.track = undefined;
363
+ if (pub) {
364
+ pub.track = undefined;
365
+ }
344
366
  this.trackPublications.delete(trackSid);
345
367
  }
368
+
369
+ /**
370
+ * Initiate an RPC call to a remote participant.
371
+ * @param params - Parameters for initiating the RPC call, see {@link PerformRpcParams}
372
+ * @returns A promise that resolves with the response payload or rejects with an error.
373
+ * @throws Error on failure. Details in `message`.
374
+ */
375
+ async performRpc({
376
+ destinationIdentity,
377
+ method,
378
+ payload,
379
+ responseTimeout,
380
+ }: PerformRpcParams): Promise<string> {
381
+ const req = create(PerformRpcRequestSchema, {
382
+ localParticipantHandle: this.ffi_handle.handle,
383
+ destinationIdentity,
384
+ method,
385
+ payload,
386
+ responseTimeoutMs: responseTimeout,
387
+ });
388
+
389
+ const res = FfiClient.instance.request<PerformRpcResponse>({
390
+ message: { case: 'performRpc', value: req },
391
+ });
392
+
393
+ const cb = await FfiClient.instance.waitFor<PerformRpcCallback>((ev) => {
394
+ return ev.message.case === 'performRpc' && ev.message.value.asyncId === res.asyncId;
395
+ });
396
+
397
+ if (cb.error) {
398
+ throw RpcError.fromProto(cb.error);
399
+ }
400
+
401
+ return cb.payload;
402
+ }
403
+
404
+ /**
405
+ * Establishes the participant as a receiver for calls of the specified RPC method.
406
+ * Will overwrite any existing callback for the same method.
407
+ *
408
+ * @param method - The name of the indicated RPC method
409
+ * @param handler - Will be invoked when an RPC request for this method is received
410
+ * @returns A promise that resolves when the method is successfully registered
411
+ *
412
+ * @example
413
+ * ```typescript
414
+ * room.localParticipant?.registerRpcMethod(
415
+ * 'greet',
416
+ * async (data: RpcInvocationData) => {
417
+ * console.log(`Received greeting from ${data.callerIdentity}: ${data.payload}`);
418
+ * return `Hello, ${data.callerIdentity}!`;
419
+ * }
420
+ * );
421
+ * ```
422
+ *
423
+ * See {@link RpcInvocationData} for more details on invocation params.
424
+ *
425
+ * The handler should return a Promise that resolves to a string.
426
+ * If unable to respond within `responseTimeout`, the request will result in an error on the caller's side.
427
+ *
428
+ * You may throw errors of type `RpcError` with a string `message` in the handler,
429
+ * and they will be received on the caller's side with the message intact.
430
+ * Other errors thrown in your handler will not be transmitted as-is, and will instead arrive to the caller as `1500` ("Application Error").
431
+ */
432
+ registerRpcMethod(method: string, handler: (data: RpcInvocationData) => Promise<string>) {
433
+ this.rpcHandlers.set(method, handler);
434
+
435
+ const req = create(RegisterRpcMethodRequestSchema, {
436
+ localParticipantHandle: this.ffi_handle.handle,
437
+ method,
438
+ });
439
+
440
+ FfiClient.instance.request<RegisterRpcMethodResponse>({
441
+ message: { case: 'registerRpcMethod', value: req },
442
+ });
443
+ }
444
+
445
+ /**
446
+ * Unregisters a previously registered RPC method.
447
+ *
448
+ * @param method - The name of the RPC method to unregister
449
+ */
450
+ unregisterRpcMethod(method: string) {
451
+ this.rpcHandlers.delete(method);
452
+
453
+ const req = create(UnregisterRpcMethodRequestSchema, {
454
+ localParticipantHandle: this.ffi_handle.handle,
455
+ method,
456
+ });
457
+
458
+ FfiClient.instance.request<UnregisterRpcMethodResponse>({
459
+ message: { case: 'unregisterRpcMethod', value: req },
460
+ });
461
+ }
462
+
463
+ /** @internal */
464
+ async handleRpcMethodInvocation(
465
+ invocationId: bigint,
466
+ method: string,
467
+ requestId: string,
468
+ callerIdentity: string,
469
+ payload: string,
470
+ responseTimeout: number,
471
+ ) {
472
+ let responseError: RpcError | null = null;
473
+ let responsePayload: string | null = null;
474
+
475
+ const handler = this.rpcHandlers.get(method);
476
+
477
+ if (!handler) {
478
+ responseError = RpcError.builtIn('UNSUPPORTED_METHOD');
479
+ } else {
480
+ try {
481
+ responsePayload = await handler({ requestId, callerIdentity, payload, responseTimeout });
482
+ } catch (error) {
483
+ if (error instanceof RpcError) {
484
+ responseError = error;
485
+ } else {
486
+ console.warn(
487
+ `Uncaught error returned by RPC handler for ${method}. Returning APPLICATION_ERROR instead.`,
488
+ error,
489
+ );
490
+ responseError = RpcError.builtIn('APPLICATION_ERROR');
491
+ }
492
+ }
493
+ }
494
+
495
+ const req = create(RpcMethodInvocationResponseRequestSchema, {
496
+ localParticipantHandle: this.ffi_handle.handle,
497
+ invocationId,
498
+ error: responseError ? responseError.toProto() : undefined,
499
+ payload: responsePayload ?? undefined,
500
+ });
501
+
502
+ const res = FfiClient.instance.request<RpcMethodInvocationResponseResponse>({
503
+ message: { case: 'rpcMethodInvocationResponse', value: req },
504
+ });
505
+
506
+ if (res.error) {
507
+ console.warn(`error sending rpc method invocation response: ${res.error}`);
508
+ }
509
+ }
346
510
  }
347
511
 
348
512
  export class RemoteParticipant extends Participant {