@livekit/rtc-node 0.13.33 → 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.
- package/dist/{audio_stream-CnODFAmo.d.cts → audio_stream-BNVaONuH.d.cts} +36 -11
- package/dist/audio_stream.d.cts +2 -2
- package/dist/data_streams/index.d.cts +1 -1
- package/dist/data_streams/stream_reader.cjs +97 -58
- package/dist/data_streams/stream_reader.cjs.map +1 -1
- package/dist/data_streams/stream_reader.d.cts +1 -1
- package/dist/data_streams/stream_reader.d.ts +28 -11
- package/dist/data_streams/stream_reader.d.ts.map +1 -1
- package/dist/data_streams/stream_writer.d.cts +1 -1
- package/dist/data_streams/types.cjs.map +1 -1
- package/dist/data_streams/types.d.cts +1 -1
- package/dist/data_streams/types.d.ts +6 -0
- package/dist/data_streams/types.d.ts.map +1 -1
- package/dist/e2ee.cjs +5 -1
- package/dist/e2ee.cjs.map +1 -1
- package/dist/e2ee.d.cts +3 -1
- package/dist/e2ee.d.ts +3 -1
- package/dist/e2ee.d.ts.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/participant.cjs +178 -196
- package/dist/participant.cjs.map +1 -1
- package/dist/participant.d.cts +2 -2
- package/dist/participant.d.ts +22 -5
- package/dist/participant.d.ts.map +1 -1
- package/dist/room.cjs +166 -126
- package/dist/room.cjs.map +1 -1
- package/dist/room.d.cts +3 -3
- package/dist/room.d.ts +16 -8
- package/dist/room.d.ts.map +1 -1
- package/dist/tests/e2e_common.cjs +157 -0
- package/dist/tests/e2e_common.cjs.map +1 -0
- package/dist/tests/e2e_common.d.cts +56 -0
- package/dist/tests/e2e_common.d.ts +37 -0
- package/dist/tests/e2e_common.d.ts.map +1 -0
- package/dist/track.d.cts +2 -2
- package/dist/track_publication.d.cts +2 -2
- package/dist/{types-_PdPVish.d.cts → types-f7wTlFjs.d.cts} +34 -11
- package/dist/utils.cjs +27 -2
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +8 -1
- package/dist/utils.d.ts +6 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.d.cts +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/video_stream.d.cts +2 -2
- package/package.json +2 -2
- package/src/audio_stream_room_lifecycle.test.ts +4 -1
- package/src/data_streams/stream_reader.ts +132 -82
- package/src/data_streams/types.ts +6 -0
- package/src/e2ee.ts +7 -0
- package/src/participant.ts +251 -228
- package/src/room.ts +233 -144
- package/src/tests/e2e.test.ts +50 -139
- package/src/tests/e2e_common.ts +163 -0
- package/src/tests/e2e_data_streams.test.ts +639 -0
- package/src/utils.ts +30 -0
- package/src/version.ts +1 -1
|
@@ -6,7 +6,7 @@ import { FfiHandle, TrackPublicationInfo, OwnedTrackPublication, TrackKind, Trac
|
|
|
6
6
|
import { AudioSource } from './audio_source.cjs';
|
|
7
7
|
import './ffi_client.cjs';
|
|
8
8
|
import { TypedEventEmitter } from '@livekit/typed-emitter';
|
|
9
|
-
import { B as BaseStreamInfo, c as ByteStreamOptions, T as TextStreamHandler, a as ByteStreamHandler } from './types-
|
|
9
|
+
import { B as BaseStreamInfo, c as ByteStreamOptions, T as TextStreamHandler, a as ByteStreamHandler } from './types-f7wTlFjs.cjs';
|
|
10
10
|
import { E2EEManager, E2EEOptions } from './e2ee.cjs';
|
|
11
11
|
import { Mutex } from '@livekit/mutex';
|
|
12
12
|
import { PathLike } from 'node:fs';
|
|
@@ -92,6 +92,7 @@ declare class LocalParticipant extends Participant {
|
|
|
92
92
|
private rpcHandlers;
|
|
93
93
|
private ffiEventLock;
|
|
94
94
|
private disconnectSignal;
|
|
95
|
+
private openStreamWriters;
|
|
95
96
|
trackPublications: Map<string, LocalTrackPublication>;
|
|
96
97
|
constructor(info: OwnedParticipant, ffiEventLock: Mutex, disconnectSignal: AbortSignal);
|
|
97
98
|
publishData(data: Uint8Array, options: DataPublishOptions): Promise<void>;
|
|
@@ -108,13 +109,18 @@ declare class LocalParticipant extends Participant {
|
|
|
108
109
|
destinationIdentities?: Array<string>;
|
|
109
110
|
streamId?: string;
|
|
110
111
|
senderIdentity?: string;
|
|
111
|
-
totalSize?: number;
|
|
112
112
|
}): Promise<TextStreamWriter>;
|
|
113
113
|
sendText(text: string, options?: {
|
|
114
114
|
topic?: string;
|
|
115
115
|
attributes?: Record<string, string>;
|
|
116
116
|
destinationIdentities?: Array<string>;
|
|
117
117
|
streamId?: string;
|
|
118
|
+
/**
|
|
119
|
+
* Whether the payload may be compressed on the wire. Defaults to true;
|
|
120
|
+
* compression is only applied when it actually reduces the payload size
|
|
121
|
+
* and every recipient supports it.
|
|
122
|
+
*/
|
|
123
|
+
compress?: boolean;
|
|
118
124
|
}): Promise<BaseStreamInfo>;
|
|
119
125
|
streamBytes(options?: {
|
|
120
126
|
name?: string;
|
|
@@ -127,9 +133,20 @@ declare class LocalParticipant extends Participant {
|
|
|
127
133
|
}): Promise<ByteStreamWriter>;
|
|
128
134
|
/** Sends a file provided as PathLike to specified recipients */
|
|
129
135
|
sendFile(path: PathLike, options?: ByteStreamOptions): Promise<void>;
|
|
130
|
-
private
|
|
131
|
-
private
|
|
132
|
-
private
|
|
136
|
+
private textStreamWriterWrite;
|
|
137
|
+
private textStreamWriterClose;
|
|
138
|
+
private byteStreamWriterWrite;
|
|
139
|
+
private byteStreamWriterClose;
|
|
140
|
+
/**
|
|
141
|
+
* Drops the native writers of any data streams that were opened but never
|
|
142
|
+
* closed — a writer the caller abandoned, or one whose write failed. Their
|
|
143
|
+
* handles would otherwise be held by the FFI server for the lifetime of the
|
|
144
|
+
* process. The room is already gone at this point, so the handles are dropped
|
|
145
|
+
* directly rather than closed: there is no end-of-stream left to deliver.
|
|
146
|
+
*
|
|
147
|
+
* @internal
|
|
148
|
+
*/
|
|
149
|
+
disposeOpenStreamWriters(): void;
|
|
133
150
|
/**
|
|
134
151
|
* Sends a chat message to participants in the room
|
|
135
152
|
*
|
|
@@ -203,6 +220,14 @@ interface RtcConfiguration {
|
|
|
203
220
|
iceServers: IceServer[];
|
|
204
221
|
}
|
|
205
222
|
declare const defaultRtcConfiguration: RtcConfiguration;
|
|
223
|
+
interface RoomDataStreamOptions {
|
|
224
|
+
/**
|
|
225
|
+
* Maximum decompressed payload size in bytes accepted for a single incoming
|
|
226
|
+
* data stream. Incoming streams exceeding this limit terminate with an error
|
|
227
|
+
* on the receiving side. Unset falls back to the SDK default of 5gb.
|
|
228
|
+
*/
|
|
229
|
+
maxPayloadByteLength?: number;
|
|
230
|
+
}
|
|
206
231
|
interface RoomOptions {
|
|
207
232
|
autoSubscribe: boolean;
|
|
208
233
|
dynacast: boolean;
|
|
@@ -212,6 +237,8 @@ interface RoomOptions {
|
|
|
212
237
|
e2ee?: E2EEOptions;
|
|
213
238
|
encryption?: E2EEOptions;
|
|
214
239
|
rtcConfig?: RtcConfiguration;
|
|
240
|
+
/** Options controlling data stream behavior for this room. */
|
|
241
|
+
dataStream?: RoomDataStreamOptions;
|
|
215
242
|
}
|
|
216
243
|
declare const defaultRoomOptions: RoomOptions$1;
|
|
217
244
|
declare const Room_base: new () => TypedEventEmitter<RoomCallbacks>;
|
|
@@ -224,8 +251,7 @@ declare class Room extends Room_base {
|
|
|
224
251
|
* before processing the next events
|
|
225
252
|
*/
|
|
226
253
|
private ffiEventLock;
|
|
227
|
-
private
|
|
228
|
-
private textStreamControllers;
|
|
254
|
+
private streamReaders;
|
|
229
255
|
private byteStreamHandlers;
|
|
230
256
|
private textStreamHandlers;
|
|
231
257
|
private preConnectEvents;
|
|
@@ -317,9 +343,8 @@ declare class Room extends Room_base {
|
|
|
317
343
|
private requirePublicationOfParticipant;
|
|
318
344
|
private requirePublicationOfRemoteParticipant;
|
|
319
345
|
private createRemoteParticipant;
|
|
320
|
-
private
|
|
321
|
-
private
|
|
322
|
-
private handleStreamTrailer;
|
|
346
|
+
private handleByteStreamOpened;
|
|
347
|
+
private handleTextStreamOpened;
|
|
323
348
|
}
|
|
324
349
|
declare class ConnectError extends Error {
|
|
325
350
|
constructor(message: string);
|
|
@@ -521,4 +546,4 @@ declare class AudioStream extends ReadableStream<AudioFrame> {
|
|
|
521
546
|
constructor(track: Track, options: AudioStreamOptions);
|
|
522
547
|
}
|
|
523
548
|
|
|
524
|
-
export { AudioStream as A, ConnectError as C, type DataPublishOptions as D, LocalAudioTrack as L, type NoiseCancellationOptions as N, Participant as P, RemoteAudioTrack as R, Track as T, type VideoTrack as V, type AudioTrack as a, LocalParticipant as b, type LocalTrack as c, LocalTrackPublication as d, LocalVideoTrack as e, RemoteParticipant as f, type RemoteTrack as g, RemoteTrackPublication as h, RemoteVideoTrack as i, Room as j,
|
|
549
|
+
export { AudioStream as A, ConnectError as C, type DataPublishOptions as D, LocalAudioTrack as L, type NoiseCancellationOptions as N, Participant as P, RemoteAudioTrack as R, Track as T, type VideoTrack as V, type AudioTrack as a, LocalParticipant as b, type LocalTrack as c, LocalTrackPublication as d, LocalVideoTrack as e, RemoteParticipant as f, type RemoteTrack as g, RemoteTrackPublication as h, RemoteVideoTrack as i, Room as j, type RoomDataStreamOptions as k, RoomEvent as l, type RoomOptions as m, type RtcConfiguration as n, TrackPublication as o, type RoomCallbacks as p, defaultRoomOptions as q, defaultRtcConfiguration as r, type AudioStreamOptions as s, AudioStreamSource as t };
|
package/dist/audio_stream.d.cts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import 'node:stream/web';
|
|
2
2
|
import './audio_frame.cjs';
|
|
3
3
|
import './frame_processor.cjs';
|
|
4
|
-
export { A as AudioStream,
|
|
4
|
+
export { A as AudioStream, s as AudioStreamOptions, t as AudioStreamSource, N as NoiseCancellationOptions } from './audio_stream-BNVaONuH.cjs';
|
|
5
5
|
import '@livekit/rtc-ffi-bindings';
|
|
6
6
|
import './video_frame.cjs';
|
|
7
7
|
import './audio_source.cjs';
|
|
8
8
|
import './ffi_client.cjs';
|
|
9
9
|
import '@livekit/typed-emitter';
|
|
10
|
-
import './types-
|
|
10
|
+
import './types-f7wTlFjs.cjs';
|
|
11
11
|
import './e2ee.cjs';
|
|
12
12
|
import '@livekit/mutex';
|
|
13
13
|
import 'node:fs';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { B as BaseStreamInfo, a as ByteStreamHandler, b as ByteStreamInfo, c as ByteStreamOptions, d as ByteStreamReader, D as DataStreamOptions, S as StreamController, T as TextStreamHandler, e as TextStreamInfo, f as TextStreamOptions, g as TextStreamReader } from '../types-
|
|
1
|
+
export { B as BaseStreamInfo, a as ByteStreamHandler, b as ByteStreamInfo, c as ByteStreamOptions, d as ByteStreamReader, D as DataStreamOptions, S as StreamController, T as TextStreamHandler, e as TextStreamInfo, f as TextStreamOptions, g as TextStreamReader } from '../types-f7wTlFjs.cjs';
|
|
2
2
|
export { ByteStreamWriter, TextStreamWriter } from './stream_writer.cjs';
|
|
3
3
|
import '@livekit/rtc-ffi-bindings';
|
|
@@ -23,46 +23,105 @@ __export(stream_reader_exports, {
|
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(stream_reader_exports);
|
|
25
25
|
var import_log = require("../log.cjs");
|
|
26
|
-
var import_utils = require("../utils.cjs");
|
|
27
26
|
class BaseStreamReader {
|
|
28
|
-
get info() {
|
|
29
|
-
return this._info;
|
|
30
|
-
}
|
|
31
27
|
constructor(info, stream, totalByteSize) {
|
|
28
|
+
this.closed = false;
|
|
29
|
+
// The reader held by an in-progress iteration. Cancelling has to go through
|
|
30
|
+
// it, since it holds the stream's lock.
|
|
31
|
+
this.activeReader = null;
|
|
32
32
|
this.reader = stream;
|
|
33
33
|
this.totalByteSize = totalByteSize;
|
|
34
34
|
this._info = info;
|
|
35
35
|
this.bytesReceived = 0;
|
|
36
36
|
}
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
get info() {
|
|
38
|
+
return this._info;
|
|
39
|
+
}
|
|
39
40
|
handleChunkReceived(chunk) {
|
|
40
41
|
var _a;
|
|
41
42
|
this.bytesReceived += chunk.content.byteLength;
|
|
42
43
|
const currentProgress = this.totalByteSize ? this.bytesReceived / this.totalByteSize : void 0;
|
|
43
44
|
(_a = this.onProgress) == null ? void 0 : _a.call(this, currentProgress);
|
|
44
45
|
}
|
|
45
|
-
|
|
46
|
+
/** Takes the stream's reader for an iteration, remembering it so that
|
|
47
|
+
* close() can cancel a read that is still in flight. */
|
|
48
|
+
acquireReader() {
|
|
46
49
|
const reader = this.reader.getReader();
|
|
50
|
+
this.activeReader = reader;
|
|
51
|
+
return reader;
|
|
52
|
+
}
|
|
53
|
+
/** Releases the stream lock after an iteration ended on its own — because a
|
|
54
|
+
* read reported end-of-stream, or because the stream itself errored. Either
|
|
55
|
+
* way the stream is in a terminal state and the FFI subscription behind it
|
|
56
|
+
* was already dropped by that terminal event, so there is nothing to cancel.
|
|
57
|
+
*
|
|
58
|
+
* An error raised *around* a read rather than by it — a chunk that failed to
|
|
59
|
+
* process — leaves the stream live, so it has to go through close() instead. */
|
|
60
|
+
finishIteration(reader) {
|
|
61
|
+
this.closed = true;
|
|
62
|
+
if (this.activeReader === reader) {
|
|
63
|
+
this.activeReader = null;
|
|
64
|
+
}
|
|
65
|
+
reader.releaseLock();
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Stops receiving this stream and releases the resources behind it.
|
|
69
|
+
*
|
|
70
|
+
* A reader is subscribed to FFI events from the moment it is handed to a
|
|
71
|
+
* stream handler, and only unsubscribes once a read consumes the stream's
|
|
72
|
+
* end-of-stream event. So a reader that is abandoned part-way through, or
|
|
73
|
+
* that a handler never reads at all, has to be closed here or its
|
|
74
|
+
* subscription lives for the rest of the process. Reading to completion — or
|
|
75
|
+
* breaking out of a `for await` — closes the reader for you, and closing an
|
|
76
|
+
* already-closed reader is a no-op.
|
|
77
|
+
*/
|
|
78
|
+
async close() {
|
|
79
|
+
if (this.closed) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
this.closed = true;
|
|
83
|
+
const active = this.activeReader;
|
|
84
|
+
this.activeReader = null;
|
|
85
|
+
try {
|
|
86
|
+
if (active) {
|
|
87
|
+
await active.cancel();
|
|
88
|
+
active.releaseLock();
|
|
89
|
+
} else {
|
|
90
|
+
await this.reader.cancel();
|
|
91
|
+
}
|
|
92
|
+
} catch (error) {
|
|
93
|
+
import_log.log.debug("error closing stream reader: %s", error);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
class ByteStreamReader extends BaseStreamReader {
|
|
98
|
+
[Symbol.asyncIterator]() {
|
|
99
|
+
const reader = this.acquireReader();
|
|
47
100
|
return {
|
|
48
101
|
next: async () => {
|
|
102
|
+
let read;
|
|
49
103
|
try {
|
|
50
|
-
|
|
51
|
-
if (done) {
|
|
52
|
-
reader.releaseLock();
|
|
53
|
-
return { done: true, value: void 0 };
|
|
54
|
-
} else {
|
|
55
|
-
this.handleChunkReceived(value);
|
|
56
|
-
return { done: false, value: value.content };
|
|
57
|
-
}
|
|
104
|
+
read = await reader.read();
|
|
58
105
|
} catch (error) {
|
|
59
|
-
|
|
60
|
-
import_log.log.error("error
|
|
106
|
+
this.finishIteration(reader);
|
|
107
|
+
import_log.log.error("error reading stream: %s", error);
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
if (read.done) {
|
|
111
|
+
this.finishIteration(reader);
|
|
61
112
|
return { done: true, value: void 0 };
|
|
62
113
|
}
|
|
114
|
+
try {
|
|
115
|
+
this.handleChunkReceived(read.value);
|
|
116
|
+
return { done: false, value: read.value.content };
|
|
117
|
+
} catch (error) {
|
|
118
|
+
await this.close();
|
|
119
|
+
import_log.log.error("error processing stream update: %s", error);
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
63
122
|
},
|
|
64
|
-
return() {
|
|
65
|
-
|
|
123
|
+
return: async () => {
|
|
124
|
+
await this.close();
|
|
66
125
|
return { done: true, value: void 0 };
|
|
67
126
|
}
|
|
68
127
|
};
|
|
@@ -76,59 +135,39 @@ class ByteStreamReader extends BaseStreamReader {
|
|
|
76
135
|
}
|
|
77
136
|
}
|
|
78
137
|
class TextStreamReader extends BaseStreamReader {
|
|
79
|
-
/**
|
|
80
|
-
* A TextStreamReader instance can be used as an AsyncIterator that returns the entire string
|
|
81
|
-
* that has been received up to the current point in time.
|
|
82
|
-
*/
|
|
83
|
-
constructor(info, stream, totalChunkCount) {
|
|
84
|
-
super(info, stream, totalChunkCount);
|
|
85
|
-
this.receivedChunks = /* @__PURE__ */ new Map();
|
|
86
|
-
}
|
|
87
|
-
handleChunkReceived(chunk) {
|
|
88
|
-
var _a;
|
|
89
|
-
const index = (0, import_utils.bigIntToNumber)(chunk.chunkIndex);
|
|
90
|
-
const previousChunkAtIndex = this.receivedChunks.get(index);
|
|
91
|
-
if (previousChunkAtIndex && previousChunkAtIndex.version > chunk.version) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
this.receivedChunks.set(index, chunk);
|
|
95
|
-
const currentProgress = this.totalByteSize ? this.receivedChunks.size / this.totalByteSize : void 0;
|
|
96
|
-
(_a = this.onProgress) == null ? void 0 : _a.call(this, currentProgress);
|
|
97
|
-
}
|
|
98
138
|
/**
|
|
99
139
|
* Async iterator implementation to allow usage of `for await...of` syntax.
|
|
100
140
|
* Yields structured chunks from the stream.
|
|
101
141
|
*
|
|
102
142
|
*/
|
|
103
143
|
[Symbol.asyncIterator]() {
|
|
104
|
-
const reader = this.
|
|
144
|
+
const reader = this.acquireReader();
|
|
105
145
|
const decoder = new TextDecoder();
|
|
106
|
-
const receivedChunks = this.receivedChunks;
|
|
107
146
|
return {
|
|
108
147
|
next: async () => {
|
|
148
|
+
let read;
|
|
109
149
|
try {
|
|
110
|
-
|
|
111
|
-
if (done) {
|
|
112
|
-
reader.releaseLock();
|
|
113
|
-
receivedChunks.clear();
|
|
114
|
-
return { done: true, value: void 0 };
|
|
115
|
-
} else {
|
|
116
|
-
this.handleChunkReceived(value);
|
|
117
|
-
return {
|
|
118
|
-
done: false,
|
|
119
|
-
value: decoder.decode(value.content)
|
|
120
|
-
};
|
|
121
|
-
}
|
|
150
|
+
read = await reader.read();
|
|
122
151
|
} catch (error) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
152
|
+
this.finishIteration(reader);
|
|
153
|
+
import_log.log.error("error reading stream: %s", error);
|
|
154
|
+
throw error;
|
|
155
|
+
}
|
|
156
|
+
if (read.done) {
|
|
157
|
+
this.finishIteration(reader);
|
|
126
158
|
return { done: true, value: void 0 };
|
|
127
159
|
}
|
|
160
|
+
try {
|
|
161
|
+
this.handleChunkReceived(read.value);
|
|
162
|
+
return { done: false, value: decoder.decode(read.value.content) };
|
|
163
|
+
} catch (error) {
|
|
164
|
+
await this.close();
|
|
165
|
+
import_log.log.error("error processing stream update: %s", error);
|
|
166
|
+
throw error;
|
|
167
|
+
}
|
|
128
168
|
},
|
|
129
|
-
return() {
|
|
130
|
-
|
|
131
|
-
receivedChunks.clear();
|
|
169
|
+
return: async () => {
|
|
170
|
+
await this.close();
|
|
132
171
|
return { done: true, value: void 0 };
|
|
133
172
|
}
|
|
134
173
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/data_streams/stream_reader.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { DataStream_Chunk } from '@livekit/rtc-ffi-bindings';\nimport { log } from '../log.js';\nimport { bigIntToNumber } from '../utils.js';\nimport type { BaseStreamInfo, ByteStreamInfo, TextStreamInfo } from './types.js';\n\nabstract class BaseStreamReader<T extends BaseStreamInfo> {\n protected reader: ReadableStream<DataStream_Chunk>;\n\n protected totalByteSize?: number;\n\n protected _info: T;\n\n protected bytesReceived: number;\n\n get info() {\n return this._info;\n }\n\n constructor(info: T, stream: ReadableStream<DataStream_Chunk>, totalByteSize?: number) {\n this.reader = stream;\n this.totalByteSize = totalByteSize;\n this._info = info;\n this.bytesReceived = 0;\n }\n\n protected abstract handleChunkReceived(chunk: DataStream_Chunk): void;\n\n onProgress?: (progress: number | undefined) => void;\n\n abstract readAll(): Promise<string | Array<Uint8Array>>;\n}\n\n/**\n * A class to read chunks from a ReadableStream and provide them in a structured format.\n */\nexport class ByteStreamReader extends BaseStreamReader<ByteStreamInfo> {\n protected handleChunkReceived(chunk: DataStream_Chunk) {\n this.bytesReceived += chunk.content!.byteLength;\n const currentProgress = this.totalByteSize\n ? this.bytesReceived / this.totalByteSize\n : undefined;\n this.onProgress?.(currentProgress);\n }\n\n [Symbol.asyncIterator]() {\n const reader = this.reader.getReader();\n\n return {\n next: async (): Promise<IteratorResult<Uint8Array>> => {\n try {\n const { done, value } = await reader.read();\n if (done) {\n // Release the lock when the stream is exhausted so the\n // underlying ReadableStream can be garbage-collected.\n reader.releaseLock();\n return { done: true, value: undefined as unknown };\n } else {\n this.handleChunkReceived(value);\n return { done: false, value: value.content! };\n }\n } catch (error: unknown) {\n // Release the lock on error so it doesn't stay held when the\n // consumer never calls return() (e.g. breaking out of for-await).\n reader.releaseLock();\n log.error('error processing stream update: %s', error);\n return { done: true, value: undefined as unknown };\n }\n },\n\n return(): IteratorResult<Uint8Array> {\n reader.releaseLock();\n return { done: true, value: undefined };\n },\n };\n }\n\n async readAll(): Promise<Array<Uint8Array>> {\n const chunks: Set<Uint8Array> = new Set();\n for await (const chunk of this) {\n chunks.add(chunk);\n }\n return Array.from(chunks);\n }\n}\n\n/**\n * A class to read chunks from a ReadableStream and provide them in a structured format.\n */\nexport class TextStreamReader extends BaseStreamReader<TextStreamInfo> {\n private receivedChunks: Map<number, DataStream_Chunk>;\n\n /**\n * A TextStreamReader instance can be used as an AsyncIterator that returns the entire string\n * that has been received up to the current point in time.\n */\n constructor(\n info: TextStreamInfo,\n stream: ReadableStream<DataStream_Chunk>,\n totalChunkCount?: number,\n ) {\n super(info, stream, totalChunkCount);\n this.receivedChunks = new Map();\n }\n\n protected handleChunkReceived(chunk: DataStream_Chunk) {\n const index = bigIntToNumber(chunk.chunkIndex!);\n const previousChunkAtIndex = this.receivedChunks.get(index!);\n if (previousChunkAtIndex && previousChunkAtIndex.version! > chunk.version!) {\n // we have a newer version already, dropping the old one\n return;\n }\n this.receivedChunks.set(index, chunk);\n const currentProgress = this.totalByteSize\n ? this.receivedChunks.size / this.totalByteSize\n : undefined;\n this.onProgress?.(currentProgress);\n }\n\n /**\n * Async iterator implementation to allow usage of `for await...of` syntax.\n * Yields structured chunks from the stream.\n *\n */\n [Symbol.asyncIterator]() {\n const reader = this.reader.getReader();\n const decoder = new TextDecoder();\n const receivedChunks = this.receivedChunks;\n\n return {\n next: async (): Promise<IteratorResult<string>> => {\n try {\n const { done, value } = await reader.read();\n if (done) {\n // Release the lock when the stream is exhausted so the\n // underlying ReadableStream can be garbage-collected.\n reader.releaseLock();\n // Clear received chunks so the buffered data can be GC'd.\n receivedChunks.clear();\n return { done: true, value: undefined };\n } else {\n this.handleChunkReceived(value);\n return {\n done: false,\n value: decoder.decode(value.content!),\n };\n }\n } catch (error: unknown) {\n // Release the lock on error so it doesn't stay held when the\n // consumer never calls return() (e.g. breaking out of for-await).\n reader.releaseLock();\n receivedChunks.clear();\n log.error('error processing stream update: %s', error);\n return { done: true, value: undefined };\n }\n },\n\n return(): IteratorResult<string> {\n reader.releaseLock();\n // Clear received chunks so the buffered data can be GC'd.\n receivedChunks.clear();\n return { done: true, value: undefined };\n },\n };\n }\n\n async readAll(): Promise<string> {\n let finalString: string = '';\n for await (const chunk of this) {\n finalString += chunk;\n }\n return finalString;\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/data_streams/stream_reader.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { DataStream_Chunk } from '@livekit/rtc-ffi-bindings';\nimport { log } from '../log.js';\nimport type { BaseStreamInfo, ByteStreamInfo, TextStreamInfo } from './types.js';\n\nabstract class BaseStreamReader<T extends BaseStreamInfo> {\n protected reader: ReadableStream<DataStream_Chunk>;\n\n protected totalByteSize?: number;\n\n protected _info: T;\n\n protected bytesReceived: number;\n\n private closed = false;\n\n // The reader held by an in-progress iteration. Cancelling has to go through\n // it, since it holds the stream's lock.\n private activeReader: ReadableStreamDefaultReader<DataStream_Chunk> | null = null;\n\n get info() {\n return this._info;\n }\n\n constructor(info: T, stream: ReadableStream<DataStream_Chunk>, totalByteSize?: number) {\n this.reader = stream;\n this.totalByteSize = totalByteSize;\n this._info = info;\n this.bytesReceived = 0;\n }\n\n protected handleChunkReceived(chunk: DataStream_Chunk) {\n this.bytesReceived += chunk.content!.byteLength;\n const currentProgress = this.totalByteSize\n ? this.bytesReceived / this.totalByteSize\n : undefined;\n this.onProgress?.(currentProgress);\n }\n\n /** Takes the stream's reader for an iteration, remembering it so that\n * close() can cancel a read that is still in flight. */\n protected acquireReader(): ReadableStreamDefaultReader<DataStream_Chunk> {\n const reader = this.reader.getReader();\n this.activeReader = reader;\n return reader;\n }\n\n /** Releases the stream lock after an iteration ended on its own — because a\n * read reported end-of-stream, or because the stream itself errored. Either\n * way the stream is in a terminal state and the FFI subscription behind it\n * was already dropped by that terminal event, so there is nothing to cancel.\n *\n * An error raised *around* a read rather than by it — a chunk that failed to\n * process — leaves the stream live, so it has to go through close() instead. */\n protected finishIteration(reader: ReadableStreamDefaultReader<DataStream_Chunk>) {\n this.closed = true;\n if (this.activeReader === reader) {\n this.activeReader = null;\n }\n reader.releaseLock();\n }\n\n /**\n * Stops receiving this stream and releases the resources behind it.\n *\n * A reader is subscribed to FFI events from the moment it is handed to a\n * stream handler, and only unsubscribes once a read consumes the stream's\n * end-of-stream event. So a reader that is abandoned part-way through, or\n * that a handler never reads at all, has to be closed here or its\n * subscription lives for the rest of the process. Reading to completion — or\n * breaking out of a `for await` — closes the reader for you, and closing an\n * already-closed reader is a no-op.\n */\n async close(): Promise<void> {\n if (this.closed) {\n return;\n }\n this.closed = true;\n const active = this.activeReader;\n this.activeReader = null;\n try {\n if (active) {\n await active.cancel();\n active.releaseLock();\n } else {\n await this.reader.cancel();\n }\n } catch (error: unknown) {\n // The stream was already closed or errored (e.g. the room disconnected\n // mid-stream), in which case its subscription is already gone.\n log.debug('error closing stream reader: %s', error);\n }\n }\n\n onProgress?: (progress: number | undefined) => void;\n\n abstract readAll(): Promise<string | Array<Uint8Array>>;\n}\n\n/**\n * A class to read chunks from a ReadableStream and provide them in a structured format.\n */\nexport class ByteStreamReader extends BaseStreamReader<ByteStreamInfo> {\n [Symbol.asyncIterator]() {\n const reader = this.acquireReader();\n\n return {\n next: async (): Promise<IteratorResult<Uint8Array>> => {\n let read: Awaited<ReturnType<typeof reader.read>>;\n try {\n read = await reader.read();\n } catch (error: unknown) {\n // The stream errored, which is terminal: release the lock so it\n // doesn't stay held when the consumer never calls return() (a\n // rejecting next() doesn't trigger it).\n this.finishIteration(reader);\n log.error('error reading stream: %s', error);\n // Propagate abnormal termination (e.g. remote abort, payload over\n // the receiver's size limit) instead of presenting the truncated\n // payload as a clean EOF.\n throw error;\n }\n\n if (read.done) {\n // Release the lock when the stream is exhausted so the\n // underlying ReadableStream can be garbage-collected.\n this.finishIteration(reader);\n return { done: true, value: undefined as unknown };\n }\n\n try {\n this.handleChunkReceived(read.value);\n return { done: false, value: read.value.content! };\n } catch (error: unknown) {\n // The chunk arrived fine but handling it threw (e.g. a consumer's\n // onProgress callback). The stream is still live, so it has to be\n // cancelled to release its FFI subscription.\n await this.close();\n log.error('error processing stream update: %s', error);\n throw error;\n }\n },\n\n return: async (): Promise<IteratorResult<Uint8Array>> => {\n await this.close();\n return { done: true, value: undefined };\n },\n };\n }\n\n async readAll(): Promise<Array<Uint8Array>> {\n const chunks: Set<Uint8Array> = new Set();\n for await (const chunk of this) {\n chunks.add(chunk);\n }\n return Array.from(chunks);\n }\n}\n\n/**\n * A class to read chunks from a ReadableStream and provide them in a structured format.\n */\nexport class TextStreamReader extends BaseStreamReader<TextStreamInfo> {\n /**\n * Async iterator implementation to allow usage of `for await...of` syntax.\n * Yields structured chunks from the stream.\n *\n */\n [Symbol.asyncIterator]() {\n const reader = this.acquireReader();\n const decoder = new TextDecoder();\n\n return {\n next: async (): Promise<IteratorResult<string>> => {\n let read: Awaited<ReturnType<typeof reader.read>>;\n try {\n read = await reader.read();\n } catch (error: unknown) {\n // The stream errored, which is terminal: release the lock so it\n // doesn't stay held when the consumer never calls return() (a\n // rejecting next() doesn't trigger it).\n this.finishIteration(reader);\n log.error('error reading stream: %s', error);\n // Propagate abnormal termination (e.g. remote abort, payload over\n // the receiver's size limit) instead of presenting the truncated\n // payload as a clean EOF.\n throw error;\n }\n\n if (read.done) {\n // Release the lock when the stream is exhausted so the\n // underlying ReadableStream can be garbage-collected.\n this.finishIteration(reader);\n return { done: true, value: undefined };\n }\n\n try {\n this.handleChunkReceived(read.value);\n return { done: false, value: decoder.decode(read.value.content!) };\n } catch (error: unknown) {\n // The chunk arrived fine but handling it threw (e.g. a consumer's\n // onProgress callback). The stream is still live, so it has to be\n // cancelled to release its FFI subscription.\n await this.close();\n log.error('error processing stream update: %s', error);\n throw error;\n }\n },\n\n return: async (): Promise<IteratorResult<string>> => {\n await this.close();\n return { done: true, value: undefined };\n },\n };\n }\n\n async readAll(): Promise<string> {\n let finalString: string = '';\n for await (const chunk of this) {\n finalString += chunk;\n }\n return finalString;\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import '@livekit/rtc-ffi-bindings';
|
|
2
|
-
export { d as ByteStreamReader, g as TextStreamReader } from '../types-
|
|
2
|
+
export { d as ByteStreamReader, g as TextStreamReader } from '../types-f7wTlFjs.cjs';
|
|
@@ -5,9 +5,34 @@ declare abstract class BaseStreamReader<T extends BaseStreamInfo> {
|
|
|
5
5
|
protected totalByteSize?: number;
|
|
6
6
|
protected _info: T;
|
|
7
7
|
protected bytesReceived: number;
|
|
8
|
+
private closed;
|
|
9
|
+
private activeReader;
|
|
8
10
|
get info(): T;
|
|
9
11
|
constructor(info: T, stream: ReadableStream<DataStream_Chunk>, totalByteSize?: number);
|
|
10
|
-
protected
|
|
12
|
+
protected handleChunkReceived(chunk: DataStream_Chunk): void;
|
|
13
|
+
/** Takes the stream's reader for an iteration, remembering it so that
|
|
14
|
+
* close() can cancel a read that is still in flight. */
|
|
15
|
+
protected acquireReader(): ReadableStreamDefaultReader<DataStream_Chunk>;
|
|
16
|
+
/** Releases the stream lock after an iteration ended on its own — because a
|
|
17
|
+
* read reported end-of-stream, or because the stream itself errored. Either
|
|
18
|
+
* way the stream is in a terminal state and the FFI subscription behind it
|
|
19
|
+
* was already dropped by that terminal event, so there is nothing to cancel.
|
|
20
|
+
*
|
|
21
|
+
* An error raised *around* a read rather than by it — a chunk that failed to
|
|
22
|
+
* process — leaves the stream live, so it has to go through close() instead. */
|
|
23
|
+
protected finishIteration(reader: ReadableStreamDefaultReader<DataStream_Chunk>): void;
|
|
24
|
+
/**
|
|
25
|
+
* Stops receiving this stream and releases the resources behind it.
|
|
26
|
+
*
|
|
27
|
+
* A reader is subscribed to FFI events from the moment it is handed to a
|
|
28
|
+
* stream handler, and only unsubscribes once a read consumes the stream's
|
|
29
|
+
* end-of-stream event. So a reader that is abandoned part-way through, or
|
|
30
|
+
* that a handler never reads at all, has to be closed here or its
|
|
31
|
+
* subscription lives for the rest of the process. Reading to completion — or
|
|
32
|
+
* breaking out of a `for await` — closes the reader for you, and closing an
|
|
33
|
+
* already-closed reader is a no-op.
|
|
34
|
+
*/
|
|
35
|
+
close(): Promise<void>;
|
|
11
36
|
onProgress?: (progress: number | undefined) => void;
|
|
12
37
|
abstract readAll(): Promise<string | Array<Uint8Array>>;
|
|
13
38
|
}
|
|
@@ -15,10 +40,9 @@ declare abstract class BaseStreamReader<T extends BaseStreamInfo> {
|
|
|
15
40
|
* A class to read chunks from a ReadableStream and provide them in a structured format.
|
|
16
41
|
*/
|
|
17
42
|
export declare class ByteStreamReader extends BaseStreamReader<ByteStreamInfo> {
|
|
18
|
-
protected handleChunkReceived(chunk: DataStream_Chunk): void;
|
|
19
43
|
[Symbol.asyncIterator](): {
|
|
20
44
|
next: () => Promise<IteratorResult<Uint8Array>>;
|
|
21
|
-
return()
|
|
45
|
+
return: () => Promise<IteratorResult<Uint8Array>>;
|
|
22
46
|
};
|
|
23
47
|
readAll(): Promise<Array<Uint8Array>>;
|
|
24
48
|
}
|
|
@@ -26,13 +50,6 @@ export declare class ByteStreamReader extends BaseStreamReader<ByteStreamInfo> {
|
|
|
26
50
|
* A class to read chunks from a ReadableStream and provide them in a structured format.
|
|
27
51
|
*/
|
|
28
52
|
export declare class TextStreamReader extends BaseStreamReader<TextStreamInfo> {
|
|
29
|
-
private receivedChunks;
|
|
30
|
-
/**
|
|
31
|
-
* A TextStreamReader instance can be used as an AsyncIterator that returns the entire string
|
|
32
|
-
* that has been received up to the current point in time.
|
|
33
|
-
*/
|
|
34
|
-
constructor(info: TextStreamInfo, stream: ReadableStream<DataStream_Chunk>, totalChunkCount?: number);
|
|
35
|
-
protected handleChunkReceived(chunk: DataStream_Chunk): void;
|
|
36
53
|
/**
|
|
37
54
|
* Async iterator implementation to allow usage of `for await...of` syntax.
|
|
38
55
|
* Yields structured chunks from the stream.
|
|
@@ -40,7 +57,7 @@ export declare class TextStreamReader extends BaseStreamReader<TextStreamInfo> {
|
|
|
40
57
|
*/
|
|
41
58
|
[Symbol.asyncIterator](): {
|
|
42
59
|
next: () => Promise<IteratorResult<string>>;
|
|
43
|
-
return()
|
|
60
|
+
return: () => Promise<IteratorResult<string>>;
|
|
44
61
|
};
|
|
45
62
|
readAll(): Promise<string>;
|
|
46
63
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream_reader.d.ts","sourceRoot":"","sources":["../../src/data_streams/stream_reader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"stream_reader.d.ts","sourceRoot":"","sources":["../../src/data_streams/stream_reader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAElE,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjF,uBAAe,gBAAgB,CAAC,CAAC,SAAS,cAAc;IACtD,SAAS,CAAC,MAAM,EAAE,cAAc,CAAC,gBAAgB,CAAC,CAAC;IAEnD,SAAS,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAEjC,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC;IAEnB,SAAS,CAAC,aAAa,EAAE,MAAM,CAAC;IAEhC,OAAO,CAAC,MAAM,CAAS;IAIvB,OAAO,CAAC,YAAY,CAA8D;IAElF,IAAI,IAAI,MAEP;gBAEW,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,gBAAgB,CAAC,EAAE,aAAa,CAAC,EAAE,MAAM;IAOrF,SAAS,CAAC,mBAAmB,CAAC,KAAK,EAAE,gBAAgB;IAQrD;4DACwD;IACxD,SAAS,CAAC,aAAa,IAAI,2BAA2B,CAAC,gBAAgB,CAAC;IAMxE;;;;;;oFAMgF;IAChF,SAAS,CAAC,eAAe,CAAC,MAAM,EAAE,2BAA2B,CAAC,gBAAgB,CAAC;IAQ/E;;;;;;;;;;OAUG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB5B,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAEpD,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;CACxD;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,gBAAgB,CAAC,cAAc,CAAC;IACpE,CAAC,MAAM,CAAC,aAAa,CAAC;oBAIF,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;sBAoCjC,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;;IAOnD,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;CAO5C;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,gBAAgB,CAAC,cAAc,CAAC;IACpE;;;;OAIG;IACH,CAAC,MAAM,CAAC,aAAa,CAAC;oBAKF,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;sBAoC7B,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;;IAO/C,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;CAOjC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as BaseStreamInfo, e as TextStreamInfo, b as ByteStreamInfo } from '../types-
|
|
1
|
+
import { B as BaseStreamInfo, e as TextStreamInfo, b as ByteStreamInfo } from '../types-f7wTlFjs.cjs';
|
|
2
2
|
import '@livekit/rtc-ffi-bindings';
|
|
3
3
|
|
|
4
4
|
declare class BaseStreamWriter<T, InfoType extends BaseStreamInfo> {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/data_streams/types.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { DataStream_Chunk, DataStream_Header } from '@livekit/rtc-ffi-bindings';\nimport type { ByteStreamReader, TextStreamReader } from './stream_reader.js';\n\nexport interface StreamController<T extends DataStream_Chunk> {\n header: DataStream_Header;\n controller: ReadableStreamDefaultController<T>;\n startTime: number;\n endTime?: number;\n}\n\nexport interface BaseStreamInfo {\n streamId: string;\n mimeType: string;\n topic: string;\n timestamp: number;\n /** total size in bytes for finite streams and undefined for streams of unknown size */\n totalSize?: number;\n attributes?: Record<string, string>;\n}\n\nexport type ByteStreamInfo = BaseStreamInfo & {\n name: string;\n};\n\nexport type TextStreamInfo = BaseStreamInfo;\n\nexport interface DataStreamOptions {\n topic?: string;\n destinationIdentities?: Array<string>;\n attributes?: Record<string, string>;\n mimeType?: string;\n}\n\nexport interface TextStreamOptions extends DataStreamOptions {\n // replyToMessageId?: string;\n attachments?: [];\n}\n\nexport interface ByteStreamOptions extends DataStreamOptions {\n name?: string;\n onProgress?: (progress: number) => void;\n}\n\nexport type ByteStreamHandler = (\n reader: ByteStreamReader,\n participantInfo: { identity: string },\n) => void;\n\nexport type TextStreamHandler = (\n reader: TextStreamReader,\n participantInfo: { identity: string },\n) => void;\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/data_streams/types.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { DataStream_Chunk, DataStream_Header } from '@livekit/rtc-ffi-bindings';\nimport type { ByteStreamReader, TextStreamReader } from './stream_reader.js';\n\nexport interface StreamController<T extends DataStream_Chunk> {\n header: DataStream_Header;\n controller: ReadableStreamDefaultController<T>;\n startTime: number;\n endTime?: number;\n}\n\nexport interface BaseStreamInfo {\n streamId: string;\n mimeType: string;\n topic: string;\n timestamp: number;\n /** total size in bytes for finite streams and undefined for streams of unknown size */\n totalSize?: number;\n attributes?: Record<string, string>;\n}\n\nexport type ByteStreamInfo = BaseStreamInfo & {\n name: string;\n};\n\nexport type TextStreamInfo = BaseStreamInfo;\n\nexport interface DataStreamOptions {\n topic?: string;\n destinationIdentities?: Array<string>;\n attributes?: Record<string, string>;\n mimeType?: string;\n}\n\nexport interface TextStreamOptions extends DataStreamOptions {\n // replyToMessageId?: string;\n attachments?: [];\n}\n\nexport interface ByteStreamOptions extends DataStreamOptions {\n name?: string;\n onProgress?: (progress: number) => void;\n /**\n * Whether the payload may be compressed on the wire. Defaults to true;\n * compression is only applied when it actually reduces the payload size\n * and every recipient supports it.\n */\n compress?: boolean;\n}\n\nexport type ByteStreamHandler = (\n reader: ByteStreamReader,\n participantInfo: { identity: string },\n) => void;\n\nexport type TextStreamHandler = (\n reader: TextStreamReader,\n participantInfo: { identity: string },\n) => void;\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import '@livekit/rtc-ffi-bindings';
|
|
2
|
-
export { B as BaseStreamInfo, a as ByteStreamHandler, b as ByteStreamInfo, c as ByteStreamOptions, D as DataStreamOptions, S as StreamController, T as TextStreamHandler, e as TextStreamInfo, f as TextStreamOptions } from '../types-
|
|
2
|
+
export { B as BaseStreamInfo, a as ByteStreamHandler, b as ByteStreamInfo, c as ByteStreamOptions, D as DataStreamOptions, S as StreamController, T as TextStreamHandler, e as TextStreamInfo, f as TextStreamOptions } from '../types-f7wTlFjs.cjs';
|
|
@@ -31,6 +31,12 @@ export interface TextStreamOptions extends DataStreamOptions {
|
|
|
31
31
|
export interface ByteStreamOptions extends DataStreamOptions {
|
|
32
32
|
name?: string;
|
|
33
33
|
onProgress?: (progress: number) => void;
|
|
34
|
+
/**
|
|
35
|
+
* Whether the payload may be compressed on the wire. Defaults to true;
|
|
36
|
+
* compression is only applied when it actually reduces the payload size
|
|
37
|
+
* and every recipient supports it.
|
|
38
|
+
*/
|
|
39
|
+
compress?: boolean;
|
|
34
40
|
}
|
|
35
41
|
export type ByteStreamHandler = (reader: ByteStreamReader, participantInfo: {
|
|
36
42
|
identity: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/data_streams/types.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACrF,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE7E,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,gBAAgB;IAC1D,MAAM,EAAE,iBAAiB,CAAC;IAC1B,UAAU,EAAE,+BAA+B,CAAC,CAAC,CAAC,CAAC;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG;IAC5C,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,cAAc,CAAC;AAE5C,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAE1D,WAAW,CAAC,EAAE,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/data_streams/types.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACrF,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE7E,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,gBAAgB;IAC1D,MAAM,EAAE,iBAAiB,CAAC;IAC1B,UAAU,EAAE,+BAA+B,CAAC,CAAC,CAAC,CAAC;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG;IAC5C,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,cAAc,CAAC;AAE5C,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAE1D,WAAW,CAAC,EAAE,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,iBAAiB,GAAG,CAC9B,MAAM,EAAE,gBAAgB,EACxB,eAAe,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,KAClC,IAAI,CAAC;AAEV,MAAM,MAAM,iBAAiB,GAAG,CAC9B,MAAM,EAAE,gBAAgB,EACxB,eAAe,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,KAClC,IAAI,CAAC"}
|
package/dist/e2ee.cjs
CHANGED
|
@@ -30,10 +30,14 @@ var import_ffi_client = require("./ffi_client.cjs");
|
|
|
30
30
|
const DEFAULT_RATCHET_SALT = new TextEncoder().encode("LKFrameEncryptionKey");
|
|
31
31
|
const DEFAULT_RATCHET_WINDOW_SIZE = 16;
|
|
32
32
|
const DEFAULT_FAILURE_TOLERANCE = -1;
|
|
33
|
+
const DEFAULT_KEY_RING_SIZE = 16;
|
|
34
|
+
const DEFAULT_KEY_DERIVATION_FUNCTION = import_rtc_ffi_bindings.KeyDerivationFunction.PBKDF2;
|
|
33
35
|
const defaultKeyProviderOptions = {
|
|
34
36
|
ratchetSalt: DEFAULT_RATCHET_SALT,
|
|
35
37
|
ratchetWindowSize: DEFAULT_RATCHET_WINDOW_SIZE,
|
|
36
|
-
failureTolerance: DEFAULT_FAILURE_TOLERANCE
|
|
38
|
+
failureTolerance: DEFAULT_FAILURE_TOLERANCE,
|
|
39
|
+
keyRingSize: DEFAULT_KEY_RING_SIZE,
|
|
40
|
+
keyDerivationFunction: DEFAULT_KEY_DERIVATION_FUNCTION
|
|
37
41
|
};
|
|
38
42
|
const defaultE2EEOptions = {
|
|
39
43
|
keyProviderOptions: defaultKeyProviderOptions,
|
package/dist/e2ee.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/e2ee.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type {\n E2eeManagerGetFrameCryptorsResponse,\n E2eeResponse,\n GetKeyResponse,\n GetSharedKeyResponse,\n RatchetKeyResponse,\n RatchetSharedKeyResponse,\n} from '@livekit/rtc-ffi-bindings';\nimport {\n E2eeManagerSetEnabledRequest,\n E2eeRequest,\n EncryptionType,\n FrameCryptorSetEnabledRequest,\n FrameCryptorSetKeyIndexRequest,\n GetKeyRequest,\n GetSharedKeyRequest,\n RatchetKeyRequest,\n RatchetSharedKeyRequest,\n SetKeyRequest,\n SetSharedKeyRequest,\n} from '@livekit/rtc-ffi-bindings';\nimport { FfiClient } from './ffi_client.js';\n\nconst DEFAULT_RATCHET_SALT = new TextEncoder().encode('LKFrameEncryptionKey');\nconst DEFAULT_RATCHET_WINDOW_SIZE = 16;\nconst DEFAULT_FAILURE_TOLERANCE = -1;\n\nexport interface KeyProviderOptions {\n sharedKey?: Uint8Array;\n ratchetSalt?: Uint8Array;\n ratchetWindowSize?: number;\n failureTolerance?: number;\n}\n\nexport const defaultKeyProviderOptions: KeyProviderOptions = {\n ratchetSalt: DEFAULT_RATCHET_SALT,\n ratchetWindowSize: DEFAULT_RATCHET_WINDOW_SIZE,\n failureTolerance: DEFAULT_FAILURE_TOLERANCE,\n};\n\nexport interface E2EEOptions {\n keyProviderOptions: KeyProviderOptions;\n encryptionType?: EncryptionType;\n}\n\nexport const defaultE2EEOptions: E2EEOptions = {\n keyProviderOptions: defaultKeyProviderOptions,\n encryptionType: EncryptionType.GCM,\n};\n\nexport class KeyProvider {\n private roomHandle: bigint;\n options: KeyProviderOptions;\n\n /** internal */\n constructor(roomHandle: bigint, opts: KeyProviderOptions) {\n this.roomHandle = roomHandle;\n this.options = opts;\n }\n\n setSharedKey(sharedKey: Uint8Array, keyIndex: number) {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'setSharedKey',\n value: new SetSharedKeyRequest({\n keyIndex: keyIndex,\n sharedKey: sharedKey,\n }),\n },\n });\n\n FfiClient.instance.request({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n }\n\n exportSharedKey(keyIndex: number): Uint8Array {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'getSharedKey',\n value: new GetSharedKeyRequest({\n keyIndex: keyIndex,\n }),\n },\n });\n\n const res = FfiClient.instance.request<E2eeResponse>({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n\n return (res.message.value as GetSharedKeyResponse).key!;\n }\n\n ratchetSharedKey(keyIndex: number): Uint8Array {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'ratchetSharedKey',\n value: new RatchetSharedKeyRequest({\n keyIndex: keyIndex,\n }),\n },\n });\n\n const res = FfiClient.instance.request<E2eeResponse>({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n\n return (res.message.value as RatchetSharedKeyResponse).newKey!;\n }\n\n setKey(participantIdentity: string, keyIndex: number) {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'setKey',\n value: new SetKeyRequest({\n keyIndex: keyIndex,\n participantIdentity: participantIdentity,\n }),\n },\n });\n\n FfiClient.instance.request({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n }\n\n exportKey(participantIdentity: string, keyIndex: number): Uint8Array {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'getKey',\n value: new GetKeyRequest({\n keyIndex: keyIndex,\n participantIdentity: participantIdentity,\n }),\n },\n });\n\n const res = FfiClient.instance.request<E2eeResponse>({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n\n return (res.message.value as GetKeyResponse).key!;\n }\n\n ratchetKey(participantIdentity: string, keyIndex: number): Uint8Array {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'ratchetKey',\n value: new RatchetKeyRequest({\n keyIndex: keyIndex,\n participantIdentity: participantIdentity,\n }),\n },\n });\n\n const res = FfiClient.instance.request<E2eeResponse>({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n\n return (res.message.value as RatchetKeyResponse).newKey!;\n }\n}\n\nexport class FrameCryptor {\n private roomHandle = BigInt(0);\n participantIdentity: string;\n keyIndex: number;\n enabled: boolean;\n\n constructor(roomHandle: bigint, participantIdentity: string, keyIndex: number, enabled: boolean) {\n this.roomHandle = roomHandle;\n this.participantIdentity = participantIdentity;\n this.keyIndex = keyIndex;\n this.enabled = enabled;\n }\n\n setEnabled(enabled: boolean) {\n this.enabled = enabled;\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'cryptorSetEnabled',\n value: new FrameCryptorSetEnabledRequest({\n participantIdentity: this.participantIdentity,\n enabled: this.enabled,\n }),\n },\n });\n\n FfiClient.instance.request({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n }\n\n setKeyIndex(keyIndex: number) {\n this.keyIndex = keyIndex;\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'cryptorSetKeyIndex',\n value: new FrameCryptorSetKeyIndexRequest({\n participantIdentity: this.participantIdentity,\n keyIndex: this.keyIndex,\n }),\n },\n });\n\n FfiClient.instance.request({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n }\n}\n\nexport class E2EEManager {\n private roomHandle = BigInt(0);\n private options: E2EEOptions;\n private keyProvider: KeyProvider;\n\n enabled: boolean;\n\n constructor(roomHandle: bigint, opts?: E2EEOptions) {\n this.roomHandle = roomHandle;\n this.enabled = opts !== undefined;\n\n opts ??= defaultE2EEOptions;\n const options = { ...defaultE2EEOptions, ...opts };\n\n this.options = options;\n this.keyProvider = new KeyProvider(roomHandle, options.keyProviderOptions);\n }\n\n setEnabled(enabled: boolean) {\n this.enabled = enabled;\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'managerSetEnabled',\n value: new E2eeManagerSetEnabledRequest({\n enabled: this.enabled,\n }),\n },\n });\n\n FfiClient.instance.request({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n }\n\n frameCryptors(): FrameCryptor[] {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'managerGetFrameCryptors',\n value: {},\n },\n });\n\n const res = FfiClient.instance.request<E2eeResponse>({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n\n const frameCryptors = (\n res.message.value as E2eeManagerGetFrameCryptorsResponse\n ).frameCryptors.map(\n (cryptor) =>\n new FrameCryptor(\n this.roomHandle,\n cryptor.participantIdentity!,\n cryptor.keyIndex!,\n cryptor.enabled!,\n ),\n );\n\n return frameCryptors;\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/e2ee.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type {\n E2eeManagerGetFrameCryptorsResponse,\n E2eeResponse,\n GetKeyResponse,\n GetSharedKeyResponse,\n RatchetKeyResponse,\n RatchetSharedKeyResponse,\n} from '@livekit/rtc-ffi-bindings';\nimport {\n E2eeManagerSetEnabledRequest,\n E2eeRequest,\n EncryptionType,\n FrameCryptorSetEnabledRequest,\n FrameCryptorSetKeyIndexRequest,\n GetKeyRequest,\n GetSharedKeyRequest,\n KeyDerivationFunction,\n RatchetKeyRequest,\n RatchetSharedKeyRequest,\n SetKeyRequest,\n SetSharedKeyRequest,\n} from '@livekit/rtc-ffi-bindings';\nimport { FfiClient } from './ffi_client.js';\n\nconst DEFAULT_RATCHET_SALT = new TextEncoder().encode('LKFrameEncryptionKey');\nconst DEFAULT_RATCHET_WINDOW_SIZE = 16;\nconst DEFAULT_FAILURE_TOLERANCE = -1;\nconst DEFAULT_KEY_RING_SIZE = 16;\nconst DEFAULT_KEY_DERIVATION_FUNCTION = KeyDerivationFunction.PBKDF2;\n\nexport interface KeyProviderOptions {\n sharedKey?: Uint8Array;\n ratchetSalt?: Uint8Array;\n ratchetWindowSize?: number;\n failureTolerance?: number;\n keyRingSize?: number;\n keyDerivationFunction?: KeyDerivationFunction;\n}\n\nexport const defaultKeyProviderOptions: KeyProviderOptions = {\n ratchetSalt: DEFAULT_RATCHET_SALT,\n ratchetWindowSize: DEFAULT_RATCHET_WINDOW_SIZE,\n failureTolerance: DEFAULT_FAILURE_TOLERANCE,\n keyRingSize: DEFAULT_KEY_RING_SIZE,\n keyDerivationFunction: DEFAULT_KEY_DERIVATION_FUNCTION,\n};\n\nexport interface E2EEOptions {\n keyProviderOptions: KeyProviderOptions;\n encryptionType?: EncryptionType;\n}\n\nexport const defaultE2EEOptions: E2EEOptions = {\n keyProviderOptions: defaultKeyProviderOptions,\n encryptionType: EncryptionType.GCM,\n};\n\nexport class KeyProvider {\n private roomHandle: bigint;\n options: KeyProviderOptions;\n\n /** internal */\n constructor(roomHandle: bigint, opts: KeyProviderOptions) {\n this.roomHandle = roomHandle;\n this.options = opts;\n }\n\n setSharedKey(sharedKey: Uint8Array, keyIndex: number) {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'setSharedKey',\n value: new SetSharedKeyRequest({\n keyIndex: keyIndex,\n sharedKey: sharedKey,\n }),\n },\n });\n\n FfiClient.instance.request({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n }\n\n exportSharedKey(keyIndex: number): Uint8Array {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'getSharedKey',\n value: new GetSharedKeyRequest({\n keyIndex: keyIndex,\n }),\n },\n });\n\n const res = FfiClient.instance.request<E2eeResponse>({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n\n return (res.message.value as GetSharedKeyResponse).key!;\n }\n\n ratchetSharedKey(keyIndex: number): Uint8Array {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'ratchetSharedKey',\n value: new RatchetSharedKeyRequest({\n keyIndex: keyIndex,\n }),\n },\n });\n\n const res = FfiClient.instance.request<E2eeResponse>({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n\n return (res.message.value as RatchetSharedKeyResponse).newKey!;\n }\n\n setKey(participantIdentity: string, keyIndex: number) {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'setKey',\n value: new SetKeyRequest({\n keyIndex: keyIndex,\n participantIdentity: participantIdentity,\n }),\n },\n });\n\n FfiClient.instance.request({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n }\n\n exportKey(participantIdentity: string, keyIndex: number): Uint8Array {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'getKey',\n value: new GetKeyRequest({\n keyIndex: keyIndex,\n participantIdentity: participantIdentity,\n }),\n },\n });\n\n const res = FfiClient.instance.request<E2eeResponse>({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n\n return (res.message.value as GetKeyResponse).key!;\n }\n\n ratchetKey(participantIdentity: string, keyIndex: number): Uint8Array {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'ratchetKey',\n value: new RatchetKeyRequest({\n keyIndex: keyIndex,\n participantIdentity: participantIdentity,\n }),\n },\n });\n\n const res = FfiClient.instance.request<E2eeResponse>({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n\n return (res.message.value as RatchetKeyResponse).newKey!;\n }\n}\n\nexport class FrameCryptor {\n private roomHandle = BigInt(0);\n participantIdentity: string;\n keyIndex: number;\n enabled: boolean;\n\n constructor(roomHandle: bigint, participantIdentity: string, keyIndex: number, enabled: boolean) {\n this.roomHandle = roomHandle;\n this.participantIdentity = participantIdentity;\n this.keyIndex = keyIndex;\n this.enabled = enabled;\n }\n\n setEnabled(enabled: boolean) {\n this.enabled = enabled;\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'cryptorSetEnabled',\n value: new FrameCryptorSetEnabledRequest({\n participantIdentity: this.participantIdentity,\n enabled: this.enabled,\n }),\n },\n });\n\n FfiClient.instance.request({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n }\n\n setKeyIndex(keyIndex: number) {\n this.keyIndex = keyIndex;\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'cryptorSetKeyIndex',\n value: new FrameCryptorSetKeyIndexRequest({\n participantIdentity: this.participantIdentity,\n keyIndex: this.keyIndex,\n }),\n },\n });\n\n FfiClient.instance.request({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n }\n}\n\nexport class E2EEManager {\n private roomHandle = BigInt(0);\n private options: E2EEOptions;\n private keyProvider: KeyProvider;\n\n enabled: boolean;\n\n constructor(roomHandle: bigint, opts?: E2EEOptions) {\n this.roomHandle = roomHandle;\n this.enabled = opts !== undefined;\n\n opts ??= defaultE2EEOptions;\n const options = { ...defaultE2EEOptions, ...opts };\n\n this.options = options;\n this.keyProvider = new KeyProvider(roomHandle, options.keyProviderOptions);\n }\n\n setEnabled(enabled: boolean) {\n this.enabled = enabled;\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'managerSetEnabled',\n value: new E2eeManagerSetEnabledRequest({\n enabled: this.enabled,\n }),\n },\n });\n\n FfiClient.instance.request({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n }\n\n frameCryptors(): FrameCryptor[] {\n const req = new E2eeRequest({\n roomHandle: this.roomHandle,\n message: {\n case: 'managerGetFrameCryptors',\n value: {},\n },\n });\n\n const res = FfiClient.instance.request<E2eeResponse>({\n message: {\n case: 'e2ee',\n value: req,\n },\n });\n\n const frameCryptors = (\n res.message.value as E2eeManagerGetFrameCryptorsResponse\n ).frameCryptors.map(\n (cryptor) =>\n new FrameCryptor(\n this.roomHandle,\n cryptor.participantIdentity!,\n cryptor.keyIndex!,\n cryptor.enabled!,\n ),\n );\n\n return frameCryptors;\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/e2ee.d.cts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { EncryptionType } from '@livekit/rtc-ffi-bindings';
|
|
1
|
+
import { KeyDerivationFunction, EncryptionType } from '@livekit/rtc-ffi-bindings';
|
|
2
2
|
|
|
3
3
|
interface KeyProviderOptions {
|
|
4
4
|
sharedKey?: Uint8Array;
|
|
5
5
|
ratchetSalt?: Uint8Array;
|
|
6
6
|
ratchetWindowSize?: number;
|
|
7
7
|
failureTolerance?: number;
|
|
8
|
+
keyRingSize?: number;
|
|
9
|
+
keyDerivationFunction?: KeyDerivationFunction;
|
|
8
10
|
}
|
|
9
11
|
declare const defaultKeyProviderOptions: KeyProviderOptions;
|
|
10
12
|
interface E2EEOptions {
|
package/dist/e2ee.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { EncryptionType } from '@livekit/rtc-ffi-bindings';
|
|
1
|
+
import { EncryptionType, KeyDerivationFunction } from '@livekit/rtc-ffi-bindings';
|
|
2
2
|
export interface KeyProviderOptions {
|
|
3
3
|
sharedKey?: Uint8Array;
|
|
4
4
|
ratchetSalt?: Uint8Array;
|
|
5
5
|
ratchetWindowSize?: number;
|
|
6
6
|
failureTolerance?: number;
|
|
7
|
+
keyRingSize?: number;
|
|
8
|
+
keyDerivationFunction?: KeyDerivationFunction;
|
|
7
9
|
}
|
|
8
10
|
export declare const defaultKeyProviderOptions: KeyProviderOptions;
|
|
9
11
|
export interface E2EEOptions {
|
package/dist/e2ee.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"e2ee.d.ts","sourceRoot":"","sources":["../src/e2ee.ts"],"names":[],"mappings":"AAWA,OAAO,EAGL,cAAc,
|
|
1
|
+
{"version":3,"file":"e2ee.d.ts","sourceRoot":"","sources":["../src/e2ee.ts"],"names":[],"mappings":"AAWA,OAAO,EAGL,cAAc,EAKd,qBAAqB,EAKtB,MAAM,2BAA2B,CAAC;AASnC,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB,WAAW,CAAC,EAAE,UAAU,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qBAAqB,CAAC,EAAE,qBAAqB,CAAC;CAC/C;AAED,eAAO,MAAM,yBAAyB,EAAE,kBAMvC,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,eAAO,MAAM,kBAAkB,EAAE,WAGhC,CAAC;AAEF,qBAAa,WAAW;IACtB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,EAAE,kBAAkB,CAAC;IAE5B,eAAe;gBACH,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB;IAKxD,YAAY,CAAC,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM;IAoBpD,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU;IAqB7C,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU;IAqB9C,MAAM,CAAC,mBAAmB,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAoBpD,SAAS,CAAC,mBAAmB,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU;IAsBpE,UAAU,CAAC,mBAAmB,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU;CAqBtE;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,UAAU,CAAa;IAC/B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;gBAEL,UAAU,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IAO/F,UAAU,CAAC,OAAO,EAAE,OAAO;IAqB3B,WAAW,CAAC,QAAQ,EAAE,MAAM;CAoB7B;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,WAAW,CAAc;IAEjC,OAAO,EAAE,OAAO,CAAC;gBAEL,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW;IAWlD,UAAU,CAAC,OAAO,EAAE,OAAO;IAoB3B,aAAa,IAAI,YAAY,EAAE;CA8BhC"}
|