@voxevolv/client 0.3.15 → 0.3.16

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.
@@ -0,0 +1,20 @@
1
+ type SendRpc = (request: {
2
+ destinationIdentity: string;
3
+ method: string;
4
+ payload: string;
5
+ responseTimeout: number;
6
+ }) => Promise<string>;
7
+ /** Keeps concurrent and later deliveries of one presentation on the same promise. */
8
+ export declare class Presentations {
9
+ private readonly send;
10
+ private readonly isClosed;
11
+ private readonly receiptFailed;
12
+ private readonly results;
13
+ constructor(send: SendRpc, isClosed: () => boolean, receiptFailed: () => void);
14
+ invoke(id: string, worker: string, execute: () => Promise<string>): Promise<string>;
15
+ private execute;
16
+ private complete;
17
+ private request;
18
+ }
19
+ export {};
20
+ //# sourceMappingURL=presentations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentations.d.ts","sourceRoot":"","sources":["../src/presentations.ts"],"names":[],"mappings":"AAMA,KAAK,OAAO,GAAG,CAAC,OAAO,EAAE;IACvB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;CACzB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAItB,qFAAqF;AACrF,qBAAa,aAAa;IAItB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,aAAa;IALhC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyC;IAEjE,YACmB,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,MAAM,OAAO,EACvB,aAAa,EAAE,MAAM,IAAI,EACxC;IAEJ,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBlF;YAEa,OAAO;IAuCrB,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,OAAO;CAMhB"}
@@ -0,0 +1,91 @@
1
+ import { RpcError } from "livekit-client";
2
+ const PRESENTATION_METHOD = "voxevolv.presentation";
3
+ const MAX_CACHED_PRESENTATIONS = 64;
4
+ const MAX_RESULT_BYTES = 65_536;
5
+ /** Keeps concurrent and later deliveries of one presentation on the same promise. */
6
+ export class Presentations {
7
+ send;
8
+ isClosed;
9
+ receiptFailed;
10
+ results = new Map();
11
+ constructor(send, isClosed, receiptFailed) {
12
+ this.send = send;
13
+ this.isClosed = isClosed;
14
+ this.receiptFailed = receiptFailed;
15
+ }
16
+ invoke(id, worker, execute) {
17
+ const key = JSON.stringify([worker, id]);
18
+ const existing = this.results.get(key);
19
+ if (existing)
20
+ return existing.response;
21
+ if (this.results.size >= MAX_CACHED_PRESENTATIONS) {
22
+ const settled = [...this.results].find(([, item]) => item.settled);
23
+ if (!settled)
24
+ return Promise.reject(new RpcError(1500, "Too many pending presentations"));
25
+ this.results.delete(settled[0]);
26
+ }
27
+ // Defer execution until after insertion so reentrant calls also share ownership.
28
+ const cached = {
29
+ response: Promise.resolve().then(() => this.execute(id, worker, execute)),
30
+ settled: false,
31
+ };
32
+ this.results.set(key, cached);
33
+ void cached.response.then(() => { cached.settled = true; }, () => { cached.settled = true; });
34
+ return cached.response;
35
+ }
36
+ async execute(id, worker, execute) {
37
+ if (this.isClosed())
38
+ throw new RpcError(1500, "Session has ended");
39
+ const startedAt = performance.now();
40
+ let grant;
41
+ try {
42
+ grant = JSON.parse(await this.request(id, worker, { action: "claim" }));
43
+ }
44
+ catch (error) {
45
+ // No handler ran. A later delivery may retry authorization; the worker
46
+ // still rejects a second claim if the first response was merely lost.
47
+ // This pending entry cannot have been evicted or replaced in the cache.
48
+ this.results.delete(JSON.stringify([worker, id]));
49
+ throw error;
50
+ }
51
+ if (typeof grant.response === "string")
52
+ return grant.response;
53
+ if (typeof grant.error === "string")
54
+ throw new RpcError(1500, grant.error);
55
+ // Deduct the entire round trip, conservatively, without comparing wall clocks.
56
+ // A frozen tab must not execute a grant that sat waiting in its event queue.
57
+ if (this.isClosed() || typeof grant.remaining_ms !== "number"
58
+ || !Number.isFinite(grant.remaining_ms)
59
+ || performance.now() - startedAt >= grant.remaining_ms) {
60
+ throw new RpcError(1500, "Presentation authorization expired");
61
+ }
62
+ let response;
63
+ try {
64
+ response = await execute();
65
+ if (new TextEncoder().encode(response).byteLength > MAX_RESULT_BYTES) {
66
+ throw new RpcError(1500, "Presentation result is too large");
67
+ }
68
+ }
69
+ catch (error) {
70
+ const message = error instanceof Error ? error.message : "Presentation failed";
71
+ this.complete(id, worker, { error: message.slice(0, 1000) });
72
+ throw error;
73
+ }
74
+ this.complete(id, worker, { response });
75
+ return response;
76
+ }
77
+ complete(id, worker, result) {
78
+ // Do not delay the original RPC response. This independent receipt can reconcile
79
+ // an outcome after its original caller has already stopped waiting.
80
+ void this.request(id, worker, { action: "complete", ...result }).catch(() => {
81
+ this.receiptFailed();
82
+ });
83
+ }
84
+ request(id, worker, payload) {
85
+ return this.send({
86
+ destinationIdentity: worker, method: PRESENTATION_METHOD,
87
+ payload: JSON.stringify({ operation_id: id, ...payload }), responseTimeout: 2_000,
88
+ });
89
+ }
90
+ }
91
+ //# sourceMappingURL=presentations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentations.js","sourceRoot":"","sources":["../src/presentations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { ClientDiagnosticInput } from "./diagnostics.js";
2
+ /** Observe the pinned LiveKit build; never inspect or retain RPC arguments/results.
3
+ * A channel_send means RTCDataChannel.send returned, not remote receipt.
4
+ */
5
+ export declare function observeRpcTransport(engineValue: unknown, record: (entry: ClientDiagnosticInput) => void): () => void;
6
+ //# sourceMappingURL=rpc-transport-diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-transport-diagnostics.d.ts","sourceRoot":"","sources":["../src/rpc-transport-diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAwB9D;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,OAAO,EACpB,MAAM,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,GAC7C,MAAM,IAAI,CAuEZ"}
@@ -0,0 +1,84 @@
1
+ /** Observe the pinned LiveKit build; never inspect or retain RPC arguments/results.
2
+ * A channel_send means RTCDataChannel.send returned, not remote receipt.
3
+ */
4
+ export function observeRpcTransport(engineValue, record) {
5
+ const engine = engineValue;
6
+ const streams = new Map();
7
+ function metadata(packet, incoming) {
8
+ const value = packet.value?.value;
9
+ if (!value)
10
+ return;
11
+ const kind = packet.value?.case;
12
+ if (kind === "rpcRequest" || kind === "rpcAck" || kind === "rpcResponse") {
13
+ // Inline requests call their identifier `id`; ACKs/responses use requestId.
14
+ const requestId = kind === "rpcRequest" ? value.id : value.requestId;
15
+ if (!requestId)
16
+ return;
17
+ const packetKinds = { rpcRequest: "request", rpcAck: "ack", rpcResponse: "response" };
18
+ return { rpc_request_id: requestId, rpc_packet: packetKinds[kind] };
19
+ }
20
+ const key = `${incoming ? "in" : "out"}:${value.streamId}`;
21
+ if (kind === "streamHeader" && value.streamId
22
+ && (value.topic === "lk.rpc_request" || value.topic === "lk.rpc_response")) {
23
+ const requestId = value.attributes?.["lk.rpc_request_id"];
24
+ if (!requestId)
25
+ return;
26
+ const now = performance.now();
27
+ for (const [id, stream] of streams) {
28
+ if (now - stream.at >= 300_000)
29
+ streams.delete(id);
30
+ }
31
+ if (streams.size >= 128)
32
+ streams.delete(streams.keys().next().value);
33
+ const rpcKind = value.topic === "lk.rpc_request" ? "request" : "response";
34
+ streams.set(key, { requestId, kind: rpcKind, at: now });
35
+ return { rpc_request_id: requestId, rpc_packet: `${rpcKind}_header` };
36
+ }
37
+ if (kind === "streamTrailer") {
38
+ const stream = streams.get(key);
39
+ streams.delete(key);
40
+ if (stream)
41
+ return { rpc_request_id: stream.requestId, rpc_packet: `${stream.kind}_end` };
42
+ }
43
+ }
44
+ function observer(packet, incoming) {
45
+ const info = metadata(packet, incoming);
46
+ if (!info)
47
+ return;
48
+ const started = performance.now();
49
+ return (stage) => {
50
+ try {
51
+ const channel = engine.dataChannelForKind(0, incoming);
52
+ record({
53
+ operation: "rpc_transport", ...info, stage,
54
+ status: stage === "publish_failed" || stage === "channel_unavailable" ? "failed" : "started",
55
+ duration_ms: performance.now() - started,
56
+ channel_state: channel?.readyState,
57
+ buffered_bytes: channel?.bufferedAmount,
58
+ });
59
+ }
60
+ catch {
61
+ // Observers must never alter a packet's delivery or exception.
62
+ }
63
+ };
64
+ }
65
+ const outgoing = (packet) => observer(packet, false);
66
+ const incoming = (packet) => {
67
+ try {
68
+ observer(packet, true)?.("transport_received");
69
+ }
70
+ catch {
71
+ // A malformed diagnostic observation must not interrupt Room's listener.
72
+ }
73
+ };
74
+ engine.voxevolvObserveRpcPacket = outgoing;
75
+ // Observe decoded receipt before Room starts ACK publication or the handler.
76
+ engine.prependListener("dataPacketReceived", incoming);
77
+ return () => {
78
+ if (engine.voxevolvObserveRpcPacket === outgoing)
79
+ delete engine.voxevolvObserveRpcPacket;
80
+ engine.off("dataPacketReceived", incoming);
81
+ streams.clear();
82
+ };
83
+ }
84
+ //# sourceMappingURL=rpc-transport-diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-transport-diagnostics.js","sourceRoot":"","sources":["../src/rpc-transport-diagnostics.ts"],"names":[],"mappings":"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"}
@@ -22342,6 +22342,11 @@ class RTCEngine extends eventsExports.EventEmitter {
22342
22342
  sendDataPacket(packet, kind, signal) {
22343
22343
  return __awaiter(this, void 0, void 0, function* () {
22344
22344
  var _a, _b;
22345
+ let rpcObserver;
22346
+ try { rpcObserver = this.voxevolvObserveRpcPacket?.(packet); } catch {}
22347
+ const observeRpc = (stage) => { try { rpcObserver?.(stage); } catch {} };
22348
+ observeRpc("publish_started");
22349
+ try {
22345
22350
  signal?.throwIfAborted();
22346
22351
  // make sure we do have a data connection
22347
22352
  yield this.ensurePublisherConnected(kind);
@@ -22391,13 +22396,21 @@ class RTCEngine extends eventsExports.EventEmitter {
22391
22396
  sequence: packet.sequence
22392
22397
  });
22393
22398
  if (this.attemptingReconnect) {
22399
+ observeRpc("reconnect_buffered");
22394
22400
  return;
22395
22401
  }
22396
22402
  dc.send(msg);
22403
+ observeRpc("channel_send");
22404
+ } else {
22405
+ observeRpc("channel_unavailable");
22397
22406
  }
22398
22407
  this.updateAndEmitDCBufferStatus(kind);
22399
22408
  break;
22400
22409
  }
22410
+ } catch (error) {
22411
+ observeRpc("publish_failed");
22412
+ throw error;
22413
+ }
22401
22414
  });
22402
22415
  }
22403
22416
  /* @internal */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voxevolv/client",
3
- "version": "0.3.15",
3
+ "version": "0.3.16",
4
4
  "description": "Browser SDK for VoxEvolv multimodal realtime sessions",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -42,7 +42,7 @@
42
42
  "scripts": {
43
43
  "build": "tsc -p tsconfig.json && node scripts/build-browser.mjs",
44
44
  "typecheck": "tsc -p tsconfig.json --noEmit",
45
- "test": "npm run build && node scripts/protocol-smoke.mjs && node --test scripts/context-delivery.test.mjs scripts/context-cancellation.test.mjs scripts/diagnostic-delivery.test.mjs scripts/startup-recovery.test.mjs scripts/connection-lifecycle.test.mjs scripts/audio-recovery.test.mjs scripts/recovery-progress.test.mjs scripts/reliable-sequence.test.mjs && node scripts/transcript-smoke.mjs",
45
+ "test": "npm run build && node scripts/protocol-smoke.mjs && node --test scripts/context-delivery.test.mjs scripts/context-cancellation.test.mjs scripts/diagnostic-delivery.test.mjs scripts/presentations.test.mjs scripts/startup-recovery.test.mjs scripts/connection-lifecycle.test.mjs scripts/audio-recovery.test.mjs scripts/recovery-progress.test.mjs scripts/reliable-sequence.test.mjs && node scripts/transcript-smoke.mjs",
46
46
  "pack:check": "npm run build && npm pack --dry-run"
47
47
  },
48
48
  "dependencies": {