From 395fe98753fde198ae50726ae6bd784478a611eb Mon Sep 17 00:00:00 2001 From: Stephen DeRosa Date: Wed, 20 May 2026 15:50:44 -0700 Subject: [PATCH 1/4] ReadyForRoomEvent --- packages/livekit-rtc/package.json | 6 ++-- packages/livekit-rtc/src/room.ts | 10 ++++++ pnpm-lock.yaml | 52 ++++++++++++++++--------------- 3 files changed, 40 insertions(+), 28 deletions(-) diff --git a/packages/livekit-rtc/package.json b/packages/livekit-rtc/package.json index 4a3cca00..c5a74862 100644 --- a/packages/livekit-rtc/package.json +++ b/packages/livekit-rtc/package.json @@ -32,19 +32,19 @@ "dependencies": { "@datastructures-js/deque": "1.0.8", "@livekit/mutex": "^1.0.0", + "@livekit/rtc-ffi-bindings": "0.12.59", "@livekit/typed-emitter": "^3.0.0", - "@livekit/rtc-ffi-bindings": "0.12.56", "pino": "^9.0.0", "pino-pretty": "^13.0.0" }, "devDependencies": { "@bufbuild/protobuf": "^1.10.1", "@types/node": "^22.13.10", - "vitest": "^3.0.0", + "livekit-server-sdk": "workspace:*", "prettier": "^3.0.3", "tsup": "^8.3.5", "typescript": "5.8.2", - "livekit-server-sdk": "workspace:*" + "vitest": "^3.0.0" }, "engines": { "node": ">= 18" diff --git a/packages/livekit-rtc/src/room.ts b/packages/livekit-rtc/src/room.ts index 3958e72c..18c76ccd 100644 --- a/packages/livekit-rtc/src/room.ts +++ b/packages/livekit-rtc/src/room.ts @@ -25,6 +25,7 @@ import { type DataStream_Chunk, type DataStream_Header, type DisconnectResponse, + type ReadyForRoomEventResponse, RoomOptions as FfiRoomOptions, type IceServer, IceTransportType, @@ -326,6 +327,15 @@ export class Room extends (EventEmitter as new () => TypedEmitter } } this.updateConnectionState(ConnectionState.CONN_CONNECTED); + // Release the FFI room event gate after our listener and local state are ready. + FfiClient.instance.request({ + message: { + case: 'readyForRoomEvent', + value: { + roomHandle: this.ffiHandle.handle, + }, + }, + }); break; case 'error': default: diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4c4ce02c..420cb128 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -210,8 +210,8 @@ importers: specifier: ^1.0.0 version: 1.1.1 '@livekit/rtc-ffi-bindings': - specifier: 0.12.56 - version: 0.12.56 + specifier: 0.12.59 + version: 0.12.59 '@livekit/typed-emitter': specifier: ^3.0.0 version: 3.0.0 @@ -965,40 +965,40 @@ packages: '@livekit/protocol@1.45.6': resolution: {integrity: sha512-YPDmrUiVe1EY/q/2bD+Fp+69DWq6LZgeH+G/KEbz07OIVf8hgAYzfb1FgiOdWLRpSj06+SuTmrOY604fWNuD3w==} - '@livekit/rtc-ffi-bindings-darwin-arm64@0.12.56': - resolution: {integrity: sha512-ohKFUgZPpXGrtinfbgYML/P7n+ov4IXLx1jyL6p/xcpsgVQfFdLR0tRxmFfBypbcnfaBZMpgosOzV+/IgK2ddg==} + '@livekit/rtc-ffi-bindings-darwin-arm64@0.12.59': + resolution: {integrity: sha512-K6TqcchR32d7Pjhp0jSpQD7v6mzuL0nRdI6ccIFZe01/aUn7ZbGm+Dt9NsK8ErhxUza8i1UJdClptx8+15yjKw==} engines: {node: '>= 18'} cpu: [arm64] os: [darwin] - '@livekit/rtc-ffi-bindings-darwin-x64@0.12.56': - resolution: {integrity: sha512-q1scIsnbV2BQhktSpE/YSqni8NgJk/iExD6ASb4LdXU0jbibdwePs07A0SmO+/Sn7ROqQApFGeg2xDIXzACK/w==} + '@livekit/rtc-ffi-bindings-darwin-x64@0.12.59': + resolution: {integrity: sha512-hxbe+g2wVMTD+706BU49UEtI+Q4oqU2EXuAzX/r0A4hGa0KoJkZy7nZBKBvX9243rOHtt3h4Sd3W8Q5C8IrknQ==} engines: {node: '>= 18'} cpu: [x64] os: [darwin] - '@livekit/rtc-ffi-bindings-linux-arm64-gnu@0.12.56': - resolution: {integrity: sha512-Wk+68CyWWiDYmB3XKkw7nOpidh+RgwE2Dfag5KBazzjgC2Nj0m1pReXlDMgKGPByaVTrVmphER3gs8phPx5Rzw==} + '@livekit/rtc-ffi-bindings-linux-arm64-gnu@0.12.59': + resolution: {integrity: sha512-AMDN9/CwmP+qI00BvVph84AtRQNF5yAy5rUpKj7km8tOsnApqUCz6EAQI4LmW7Qp4udg9U/30rIwWfdBcILCCw==} engines: {node: '>= 18'} cpu: [arm64] os: [linux] libc: [glibc] - '@livekit/rtc-ffi-bindings-linux-x64-gnu@0.12.56': - resolution: {integrity: sha512-fF0USwEkELhnVFBEgYUCHT50qfug3VluzforlEL5MKBn8/gu8m12MGckq9K1zkOsuA9jNhLVUhrSpSgaCowbTw==} + '@livekit/rtc-ffi-bindings-linux-x64-gnu@0.12.59': + resolution: {integrity: sha512-x39lx1YXTZUmuj8yLBOBcU3roW5qf/IgYYxa9uuu00hQ1flDbL8U0J0jyjpmDe8RX321i3euRoydHQM8hMepgA==} engines: {node: '>= 18'} cpu: [x64] os: [linux] libc: [glibc] - '@livekit/rtc-ffi-bindings-win32-x64-msvc@0.12.56': - resolution: {integrity: sha512-uPK1k43h7HHt2rhRObVNLhhH+x3YvA8DPcTMP8OpRwMeq16TdD/44BdgFKvmlHQoJJfzMFty74MyEkr4nTdqAw==} + '@livekit/rtc-ffi-bindings-win32-x64-msvc@0.12.59': + resolution: {integrity: sha512-WjFb1k6TI7PHLPY083d/DUs6Ri6jtv3QUtYTbhIXvD+dY9rTMR5beN9AN8rXivX6WzquWtWuRrQfEWaU8BBKIA==} engines: {node: '>= 18'} cpu: [x64] os: [win32] - '@livekit/rtc-ffi-bindings@0.12.56': - resolution: {integrity: sha512-BCirumGTO7iQYk2KidsqraSNqCbveYGBEQGJS/9lMSeJOFXwwlWHWL9N9ZThBNjAdCQdcvSthWB33FApob8H1w==} + '@livekit/rtc-ffi-bindings@0.12.59': + resolution: {integrity: sha512-I0snu2+khYOrf1NWogozQNVrEtI/1Sf+qcI/t89FZyOQ5/C1KwNnmrZ2BnqztyzYZmMHj8UpcYu0cxNRWoZ14w==} engines: {node: '>= 18'} '@livekit/typed-emitter@3.0.0': @@ -1699,9 +1699,11 @@ packages: '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + deprecated: Potential CWE-502 - Update to 1.3.1 or higher '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + deprecated: Potential CWE-502 - Update to 1.3.1 or higher '@unrs/resolver-binding-android-arm-eabi@1.11.1': resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} @@ -4624,30 +4626,30 @@ snapshots: dependencies: '@bufbuild/protobuf': 1.10.1 - '@livekit/rtc-ffi-bindings-darwin-arm64@0.12.56': + '@livekit/rtc-ffi-bindings-darwin-arm64@0.12.59': optional: true - '@livekit/rtc-ffi-bindings-darwin-x64@0.12.56': + '@livekit/rtc-ffi-bindings-darwin-x64@0.12.59': optional: true - '@livekit/rtc-ffi-bindings-linux-arm64-gnu@0.12.56': + '@livekit/rtc-ffi-bindings-linux-arm64-gnu@0.12.59': optional: true - '@livekit/rtc-ffi-bindings-linux-x64-gnu@0.12.56': + '@livekit/rtc-ffi-bindings-linux-x64-gnu@0.12.59': optional: true - '@livekit/rtc-ffi-bindings-win32-x64-msvc@0.12.56': + '@livekit/rtc-ffi-bindings-win32-x64-msvc@0.12.59': optional: true - '@livekit/rtc-ffi-bindings@0.12.56': + '@livekit/rtc-ffi-bindings@0.12.59': dependencies: '@bufbuild/protobuf': 1.10.1 optionalDependencies: - '@livekit/rtc-ffi-bindings-darwin-arm64': 0.12.56 - '@livekit/rtc-ffi-bindings-darwin-x64': 0.12.56 - '@livekit/rtc-ffi-bindings-linux-arm64-gnu': 0.12.56 - '@livekit/rtc-ffi-bindings-linux-x64-gnu': 0.12.56 - '@livekit/rtc-ffi-bindings-win32-x64-msvc': 0.12.56 + '@livekit/rtc-ffi-bindings-darwin-arm64': 0.12.59 + '@livekit/rtc-ffi-bindings-darwin-x64': 0.12.59 + '@livekit/rtc-ffi-bindings-linux-arm64-gnu': 0.12.59 + '@livekit/rtc-ffi-bindings-linux-x64-gnu': 0.12.59 + '@livekit/rtc-ffi-bindings-win32-x64-msvc': 0.12.59 '@livekit/typed-emitter@3.0.0': {} From 0b4d9f0950ddb4141d6b27b83e5e6da66e21c0b3 Mon Sep 17 00:00:00 2001 From: lukasIO Date: Thu, 21 May 2026 11:24:15 +0200 Subject: [PATCH 2/4] fix import order --- packages/livekit-rtc/src/room.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/livekit-rtc/src/room.ts b/packages/livekit-rtc/src/room.ts index 18c76ccd..7bc1f0c5 100644 --- a/packages/livekit-rtc/src/room.ts +++ b/packages/livekit-rtc/src/room.ts @@ -25,10 +25,10 @@ import { type DataStream_Chunk, type DataStream_Header, type DisconnectResponse, - type ReadyForRoomEventResponse, RoomOptions as FfiRoomOptions, type IceServer, IceTransportType, + type ReadyForRoomEventResponse, type RoomInfo, type SimulateScenarioCallback, type SimulateScenarioKind, From 6c534114c618d61ce38c63697de63d816825aa1d Mon Sep 17 00:00:00 2001 From: lukasIO Date: Thu, 21 May 2026 17:14:54 +0200 Subject: [PATCH 3/4] Create breezy-sloths-mate.md --- .changeset/breezy-sloths-mate.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/breezy-sloths-mate.md diff --git a/.changeset/breezy-sloths-mate.md b/.changeset/breezy-sloths-mate.md new file mode 100644 index 00000000..8a7404b6 --- /dev/null +++ b/.changeset/breezy-sloths-mate.md @@ -0,0 +1,5 @@ +--- +"@livekit/rtc-node": patch +--- + +bump ffi bindings, includes rpc v2 support From c97238284a9a7ef1534f816ce3e11396ded22d0f Mon Sep 17 00:00:00 2001 From: Ryan Gaus Date: Thu, 21 May 2026 11:51:14 -0400 Subject: [PATCH 4/4] feat: add long rpc cases (rpc v2) to rpc example --- examples/rpc/index.ts | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/examples/rpc/index.ts b/examples/rpc/index.ts index c70652b8..8775662f 100644 --- a/examples/rpc/index.ts +++ b/examples/rpc/index.ts @@ -32,6 +32,13 @@ async function main() { console.error('Error:', error); } + try { + console.log('\n\nRunning send long info example...'); + await Promise.all([performSendVeryLongInfo(callersRoom)]); + } catch (error) { + console.error('Error:', error); + } + try { console.log('\n\nRunning error handling example...'); await Promise.all([performDivision(callersRoom)]); @@ -70,6 +77,17 @@ const registerReceiverMethods = (greetersRoom: Room, mathGeniusRoom: Room) => { }, ); + greetersRoom.localParticipant?.registerRpcMethod( + 'exchanging-long-info', + async (data: RpcInvocationData) => { + console.log( + `[Greeter] ${data.callerIdentity} has arrived and said that its long info is ${data.payload.length} chars long and starts with: "${data.payload.slice(0, 20)}..."`, + ); + await new Promise((resolve) => setTimeout(resolve, 2000)); + return new Array(20_000).fill('Y').join(''); + }, + ); + mathGeniusRoom.localParticipant?.registerRpcMethod( 'square-root', async (data: RpcInvocationData) => { @@ -124,6 +142,23 @@ const performGreeting = async (room: Room): Promise => { } }; +const performSendVeryLongInfo = async (room: Room): Promise => { + console.log('[Caller] Sending the greeter a very long message'); + try { + const response = await room.localParticipant!.performRpc({ + destinationIdentity: 'greeter', + method: 'exchanging-long-info', + payload: new Array(20_000).fill('X').join(''), + }); + console.log( + `[Caller] The greeter's long info is ${response.length} chars long and starts with: "${response.slice(0, 20)}..."`, + ); + } catch (error) { + console.error('[Caller] RPC call failed:', error); + throw error; + } +}; + const performSquareRoot = async (room: Room): Promise => { console.log("[Caller] What's the square root of 16?"); try {