livekit-client 2.15.4 → 2.15.6

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 (84) hide show
  1. package/dist/livekit-client.e2ee.worker.js +1 -1
  2. package/dist/livekit-client.e2ee.worker.js.map +1 -1
  3. package/dist/livekit-client.e2ee.worker.mjs +373 -164
  4. package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
  5. package/dist/livekit-client.esm.mjs +982 -643
  6. package/dist/livekit-client.esm.mjs.map +1 -1
  7. package/dist/livekit-client.umd.js +1 -1
  8. package/dist/livekit-client.umd.js.map +1 -1
  9. package/dist/src/e2ee/E2eeManager.d.ts.map +1 -1
  10. package/dist/src/e2ee/worker/FrameCryptor.d.ts +0 -47
  11. package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
  12. package/dist/src/e2ee/worker/naluUtils.d.ts +27 -0
  13. package/dist/src/e2ee/worker/naluUtils.d.ts.map +1 -0
  14. package/dist/src/e2ee/worker/sifPayload.d.ts +22 -0
  15. package/dist/src/e2ee/worker/sifPayload.d.ts.map +1 -0
  16. package/dist/src/index.d.ts +2 -2
  17. package/dist/src/index.d.ts.map +1 -1
  18. package/dist/src/room/Room.d.ts +6 -10
  19. package/dist/src/room/Room.d.ts.map +1 -1
  20. package/dist/src/room/data-stream/incoming/IncomingDataStreamManager.d.ts +20 -0
  21. package/dist/src/room/data-stream/incoming/IncomingDataStreamManager.d.ts.map +1 -0
  22. package/dist/{ts4.2/src/room → src/room/data-stream/incoming}/StreamReader.d.ts +82 -56
  23. package/dist/src/room/data-stream/incoming/StreamReader.d.ts.map +1 -0
  24. package/dist/src/room/data-stream/outgoing/OutgoingDataStreamManager.d.ts +27 -0
  25. package/dist/src/room/data-stream/outgoing/OutgoingDataStreamManager.d.ts.map +1 -0
  26. package/dist/src/room/{StreamWriter.d.ts → data-stream/outgoing/StreamWriter.d.ts} +1 -1
  27. package/dist/src/room/data-stream/outgoing/StreamWriter.d.ts.map +1 -0
  28. package/dist/src/room/errors.d.ts +13 -0
  29. package/dist/src/room/errors.d.ts.map +1 -1
  30. package/dist/src/room/participant/LocalParticipant.d.ts +32 -19
  31. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  32. package/dist/src/room/track/LocalTrack.d.ts +7 -2
  33. package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
  34. package/dist/src/room/track/RemoteVideoTrack.d.ts +1 -0
  35. package/dist/src/room/track/RemoteVideoTrack.d.ts.map +1 -1
  36. package/dist/src/room/track/Track.d.ts +4 -1
  37. package/dist/src/room/track/Track.d.ts.map +1 -1
  38. package/dist/src/room/types.d.ts +17 -1
  39. package/dist/src/room/types.d.ts.map +1 -1
  40. package/dist/src/room/utils.d.ts +8 -0
  41. package/dist/src/room/utils.d.ts.map +1 -1
  42. package/dist/ts4.2/src/e2ee/worker/FrameCryptor.d.ts +0 -47
  43. package/dist/ts4.2/src/e2ee/worker/naluUtils.d.ts +27 -0
  44. package/dist/ts4.2/src/e2ee/worker/sifPayload.d.ts +22 -0
  45. package/dist/ts4.2/src/index.d.ts +2 -2
  46. package/dist/ts4.2/src/room/Room.d.ts +6 -10
  47. package/dist/ts4.2/src/room/data-stream/incoming/IncomingDataStreamManager.d.ts +20 -0
  48. package/dist/{src/room → ts4.2/src/room/data-stream/incoming}/StreamReader.d.ts +82 -56
  49. package/dist/ts4.2/src/room/data-stream/outgoing/OutgoingDataStreamManager.d.ts +27 -0
  50. package/dist/ts4.2/src/room/{StreamWriter.d.ts → data-stream/outgoing/StreamWriter.d.ts} +1 -1
  51. package/dist/ts4.2/src/room/errors.d.ts +13 -0
  52. package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +32 -19
  53. package/dist/ts4.2/src/room/track/LocalTrack.d.ts +7 -2
  54. package/dist/ts4.2/src/room/track/RemoteVideoTrack.d.ts +1 -0
  55. package/dist/ts4.2/src/room/track/Track.d.ts +4 -1
  56. package/dist/ts4.2/src/room/types.d.ts +17 -1
  57. package/dist/ts4.2/src/room/utils.d.ts +8 -0
  58. package/package.json +7 -7
  59. package/src/e2ee/E2eeManager.ts +18 -1
  60. package/src/e2ee/worker/FrameCryptor.ts +56 -157
  61. package/src/e2ee/worker/e2ee.worker.ts +6 -1
  62. package/src/e2ee/worker/naluUtils.ts +328 -0
  63. package/src/e2ee/worker/sifPayload.ts +75 -0
  64. package/src/index.ts +2 -2
  65. package/src/room/Room.ts +104 -208
  66. package/src/room/data-stream/incoming/IncomingDataStreamManager.ts +247 -0
  67. package/src/room/data-stream/incoming/StreamReader.ts +317 -0
  68. package/src/room/data-stream/outgoing/OutgoingDataStreamManager.ts +316 -0
  69. package/src/room/{StreamWriter.ts → data-stream/outgoing/StreamWriter.ts} +1 -1
  70. package/src/room/errors.ts +34 -0
  71. package/src/room/participant/LocalParticipant.ts +39 -295
  72. package/src/room/track/LocalAudioTrack.ts +2 -2
  73. package/src/room/track/LocalTrack.ts +70 -50
  74. package/src/room/track/RemoteVideoTrack.ts +12 -2
  75. package/src/room/track/Track.ts +10 -1
  76. package/src/room/types.ts +22 -1
  77. package/src/room/utils.ts +14 -5
  78. package/dist/src/e2ee/worker/SifGuard.d.ts +0 -11
  79. package/dist/src/e2ee/worker/SifGuard.d.ts.map +0 -1
  80. package/dist/src/room/StreamReader.d.ts.map +0 -1
  81. package/dist/src/room/StreamWriter.d.ts.map +0 -1
  82. package/dist/ts4.2/src/e2ee/worker/SifGuard.d.ts +0 -11
  83. package/src/e2ee/worker/SifGuard.ts +0 -47
  84. package/src/room/StreamReader.ts +0 -170
@@ -37,6 +37,8 @@ export abstract class Track<
37
37
 
38
38
  source: Track.Source;
39
39
 
40
+ private _streamState: Track.StreamState = Track.StreamState.Active;
41
+
40
42
  /**
41
43
  * sid is set after track is published to server, or if it's a remote track
42
44
  */
@@ -51,7 +53,14 @@ export abstract class Track<
51
53
  * indicates current state of stream, it'll indicate `paused` if the track
52
54
  * has been paused by congestion controller
53
55
  */
54
- streamState: Track.StreamState = Track.StreamState.Active;
56
+ get streamState(): Track.StreamState {
57
+ return this._streamState;
58
+ }
59
+
60
+ /** @internal */
61
+ setStreamState(value: Track.StreamState) {
62
+ this._streamState = value;
63
+ }
55
64
 
56
65
  /** @internal */
57
66
  rtpTimestamp: number | undefined;
package/src/room/types.ts CHANGED
@@ -1,4 +1,5 @@
1
- import type { DataStream_Chunk } from '@livekit/protocol';
1
+ import type { DataStream_Chunk, Encryption_Type } from '@livekit/protocol';
2
+ import type { Future } from './utils';
2
3
 
3
4
  export type SimulationOptions = {
4
5
  publish?: {
@@ -35,6 +36,24 @@ export interface StreamTextOptions {
35
36
  attributes?: Record<string, string>;
36
37
  }
37
38
 
39
+ export type StreamBytesOptions = {
40
+ name?: string;
41
+ topic?: string;
42
+ attributes?: Record<string, string>;
43
+ destinationIdentities?: Array<string>;
44
+ streamId?: string;
45
+ mimeType?: string;
46
+ totalSize?: number;
47
+ };
48
+
49
+ export type SendFileOptions = Pick<
50
+ StreamBytesOptions,
51
+ 'topic' | 'mimeType' | 'destinationIdentities'
52
+ > & {
53
+ onProgress?: (progress: number) => void;
54
+ encryptionType?: Encryption_Type.NONE;
55
+ };
56
+
38
57
  export type DataPublishOptions = {
39
58
  /**
40
59
  * whether to send this as reliable or lossy.
@@ -105,6 +124,8 @@ export interface StreamController<T extends DataStream_Chunk> {
105
124
  controller: ReadableStreamDefaultController<T>;
106
125
  startTime: number;
107
126
  endTime?: number;
127
+ sendingParticipantIdentity: string;
128
+ outOfBandFailureRejectingFuture: Future<never>;
108
129
  }
109
130
 
110
131
  export interface BaseStreamInfo {
package/src/room/utils.ts CHANGED
@@ -64,8 +64,9 @@ export function supportsAV1(): boolean {
64
64
  if (!('getCapabilities' in RTCRtpSender)) {
65
65
  return false;
66
66
  }
67
- if (isSafari()) {
67
+ if (isSafari() || isFireFox()) {
68
68
  // Safari 17 on iPhone14 reports AV1 capability, but does not actually support it
69
+ // Firefox does support AV1, but SVC publishing is not supported
69
70
  return false;
70
71
  }
71
72
  const capabilities = RTCRtpSender.getCapabilities('video');
@@ -214,12 +215,12 @@ export function isE2EESimulcastSupported() {
214
215
  } else if (
215
216
  browser.os === 'iOS' &&
216
217
  browser.osVersion &&
217
- compareVersions(supportedSafariVersion, browser.osVersion) >= 0
218
+ compareVersions(browser.osVersion, supportedSafariVersion) >= 0
218
219
  ) {
219
220
  return true;
220
221
  } else if (
221
222
  browser.name === 'Safari' &&
222
- compareVersions(supportedSafariVersion, browser.version) >= 0
223
+ compareVersions(browser.version, supportedSafariVersion) >= 0
223
224
  ) {
224
225
  return true;
225
226
  } else {
@@ -282,6 +283,14 @@ export function getDevicePixelRatio(): number {
282
283
  return 1;
283
284
  }
284
285
 
286
+ /**
287
+ * @param v1 - The first version string to compare.
288
+ * @param v2 - The second version string to compare.
289
+ * @returns A number indicating the order of the versions:
290
+ * - 1 if v1 is greater than v2
291
+ * - -1 if v1 is less than v2
292
+ * - 0 if v1 and v2 are equal
293
+ */
285
294
  export function compareVersions(v1: string, v2: string): number {
286
295
  const parts1 = v1.split('.');
287
296
  const parts2 = v2.split('.');
@@ -538,13 +547,13 @@ export function unwrapConstraint(constraint: ConstrainDOMString | ConstrainULong
538
547
  if (Array.isArray(constraint)) {
539
548
  return constraint[0];
540
549
  }
541
- if (constraint.exact) {
550
+ if (constraint.exact !== undefined) {
542
551
  if (Array.isArray(constraint.exact)) {
543
552
  return constraint.exact[0];
544
553
  }
545
554
  return constraint.exact;
546
555
  }
547
- if (constraint.ideal) {
556
+ if (constraint.ideal !== undefined) {
548
557
  if (Array.isArray(constraint.ideal)) {
549
558
  return constraint.ideal[0];
550
559
  }
@@ -1,11 +0,0 @@
1
- export declare class SifGuard {
2
- private consecutiveSifCount;
3
- private sifSequenceStartedAt;
4
- private lastSifReceivedAt;
5
- private userFramesSinceSif;
6
- recordSif(): void;
7
- recordUserFrame(): void;
8
- isSifAllowed(): boolean;
9
- reset(): void;
10
- }
11
- //# sourceMappingURL=SifGuard.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SifGuard.d.ts","sourceRoot":"","sources":["../../../../src/e2ee/worker/SifGuard.ts"],"names":[],"mappings":"AAEA,qBAAa,QAAQ;IACnB,OAAO,CAAC,mBAAmB,CAAK;IAEhC,OAAO,CAAC,oBAAoB,CAAqB;IAEjD,OAAO,CAAC,iBAAiB,CAAa;IAEtC,OAAO,CAAC,kBAAkB,CAAa;IAEvC,SAAS;IAMT,eAAe;IAgBf,YAAY;IAQZ,KAAK;CAKN"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"StreamReader.d.ts","sourceRoot":"","sources":["../../../src/room/StreamReader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG9E,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,IAAI,IAAI,MAEP;gBAEW,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,gBAAgB,CAAC,EAAE,aAAa,CAAC,EAAE,MAAM;IAOrF,SAAS,CAAC,QAAQ,CAAC,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IAErE,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,qBAAa,gBAAiB,SAAQ,gBAAgB,CAAC,cAAc,CAAC;IACpE,SAAS,CAAC,mBAAmB,CAAC,KAAK,EAAE,gBAAgB;IAQrD,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAEpD,CAAC,MAAM,CAAC,aAAa,CAAC;oBAIF,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;kBAenC,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;;IAOjD,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;CAO5C;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,gBAAgB,CAAC,cAAc,CAAC;IACpE,OAAO,CAAC,cAAc,CAAgC;IAEtD;;;OAGG;gBAED,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,cAAc,CAAC,gBAAgB,CAAC,EACxC,eAAe,CAAC,EAAE,MAAM;IAM1B,SAAS,CAAC,mBAAmB,CAAC,KAAK,EAAE,gBAAgB;IAerD;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAEpD;;;;OAIG;IACH,CAAC,MAAM,CAAC,aAAa,CAAC;oBAKF,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;kBAmB/B,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;;IAO7C,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;CAOjC;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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"StreamWriter.d.ts","sourceRoot":"","sources":["../../../src/room/StreamWriter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9E,cAAM,gBAAgB,CAAC,CAAC,EAAE,QAAQ,SAAS,cAAc;IACvD,SAAS,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IAE5C,SAAS,CAAC,aAAa,EAAE,2BAA2B,CAAC,CAAC,CAAC,CAAC;IAExD,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAE/B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;gBAEZ,cAAc,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,MAAM,IAAI;IAOnF,KAAK,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxB,KAAK;CAKZ;AAED,qBAAa,gBAAiB,SAAQ,gBAAgB,CAAC,MAAM,EAAE,cAAc,CAAC;CAAG;AAEjF,qBAAa,gBAAiB,SAAQ,gBAAgB,CAAC,UAAU,EAAE,cAAc,CAAC;CAAG"}
@@ -1,11 +0,0 @@
1
- export declare class SifGuard {
2
- private consecutiveSifCount;
3
- private sifSequenceStartedAt;
4
- private lastSifReceivedAt;
5
- private userFramesSinceSif;
6
- recordSif(): void;
7
- recordUserFrame(): void;
8
- isSifAllowed(): boolean;
9
- reset(): void;
10
- }
11
- //# sourceMappingURL=SifGuard.d.ts.map
@@ -1,47 +0,0 @@
1
- import { MAX_SIF_COUNT, MAX_SIF_DURATION } from '../constants';
2
-
3
- export class SifGuard {
4
- private consecutiveSifCount = 0;
5
-
6
- private sifSequenceStartedAt: number | undefined;
7
-
8
- private lastSifReceivedAt: number = 0;
9
-
10
- private userFramesSinceSif: number = 0;
11
-
12
- recordSif() {
13
- this.consecutiveSifCount += 1;
14
- this.sifSequenceStartedAt ??= Date.now();
15
- this.lastSifReceivedAt = Date.now();
16
- }
17
-
18
- recordUserFrame() {
19
- if (this.sifSequenceStartedAt === undefined) {
20
- return;
21
- } else {
22
- this.userFramesSinceSif += 1;
23
- }
24
- if (
25
- // reset if we received more user frames than SIFs
26
- this.userFramesSinceSif > this.consecutiveSifCount ||
27
- // also reset if we got a new user frame and the latest SIF frame hasn't been updated in a while
28
- Date.now() - this.lastSifReceivedAt > MAX_SIF_DURATION
29
- ) {
30
- this.reset();
31
- }
32
- }
33
-
34
- isSifAllowed() {
35
- return (
36
- this.consecutiveSifCount < MAX_SIF_COUNT &&
37
- (this.sifSequenceStartedAt === undefined ||
38
- Date.now() - this.sifSequenceStartedAt < MAX_SIF_DURATION)
39
- );
40
- }
41
-
42
- reset() {
43
- this.userFramesSinceSif = 0;
44
- this.consecutiveSifCount = 0;
45
- this.sifSequenceStartedAt = undefined;
46
- }
47
- }
@@ -1,170 +0,0 @@
1
- import type { DataStream_Chunk } from '@livekit/protocol';
2
- import type { BaseStreamInfo, ByteStreamInfo, TextStreamInfo } from './types';
3
- import { bigIntToNumber } from './utils';
4
-
5
- abstract class BaseStreamReader<T extends BaseStreamInfo> {
6
- protected reader: ReadableStream<DataStream_Chunk>;
7
-
8
- protected totalByteSize?: number;
9
-
10
- protected _info: T;
11
-
12
- protected bytesReceived: number;
13
-
14
- get info() {
15
- return this._info;
16
- }
17
-
18
- constructor(info: T, stream: ReadableStream<DataStream_Chunk>, totalByteSize?: number) {
19
- this.reader = stream;
20
- this.totalByteSize = totalByteSize;
21
- this._info = info;
22
- this.bytesReceived = 0;
23
- }
24
-
25
- protected abstract handleChunkReceived(chunk: DataStream_Chunk): void;
26
-
27
- onProgress?: (progress: number | undefined) => void;
28
-
29
- abstract readAll(): Promise<string | Array<Uint8Array>>;
30
- }
31
-
32
- export class ByteStreamReader extends BaseStreamReader<ByteStreamInfo> {
33
- protected handleChunkReceived(chunk: DataStream_Chunk) {
34
- this.bytesReceived += chunk.content.byteLength;
35
- const currentProgress = this.totalByteSize
36
- ? this.bytesReceived / this.totalByteSize
37
- : undefined;
38
- this.onProgress?.(currentProgress);
39
- }
40
-
41
- onProgress?: (progress: number | undefined) => void;
42
-
43
- [Symbol.asyncIterator]() {
44
- const reader = this.reader.getReader();
45
-
46
- return {
47
- next: async (): Promise<IteratorResult<Uint8Array>> => {
48
- try {
49
- const { done, value } = await reader.read();
50
- if (done) {
51
- return { done: true, value: undefined as any };
52
- } else {
53
- this.handleChunkReceived(value);
54
- return { done: false, value: value.content };
55
- }
56
- } catch (error) {
57
- // TODO handle errors
58
- return { done: true, value: undefined };
59
- }
60
- },
61
-
62
- async return(): Promise<IteratorResult<Uint8Array>> {
63
- reader.releaseLock();
64
- return { done: true, value: undefined };
65
- },
66
- };
67
- }
68
-
69
- async readAll(): Promise<Array<Uint8Array>> {
70
- let chunks: Set<Uint8Array> = new Set();
71
- for await (const chunk of this) {
72
- chunks.add(chunk);
73
- }
74
- return Array.from(chunks);
75
- }
76
- }
77
-
78
- /**
79
- * A class to read chunks from a ReadableStream and provide them in a structured format.
80
- */
81
- export class TextStreamReader extends BaseStreamReader<TextStreamInfo> {
82
- private receivedChunks: Map<number, DataStream_Chunk>;
83
-
84
- /**
85
- * A TextStreamReader instance can be used as an AsyncIterator that returns the entire string
86
- * that has been received up to the current point in time.
87
- */
88
- constructor(
89
- info: TextStreamInfo,
90
- stream: ReadableStream<DataStream_Chunk>,
91
- totalChunkCount?: number,
92
- ) {
93
- super(info, stream, totalChunkCount);
94
- this.receivedChunks = new Map();
95
- }
96
-
97
- protected handleChunkReceived(chunk: DataStream_Chunk) {
98
- const index = bigIntToNumber(chunk.chunkIndex);
99
- const previousChunkAtIndex = this.receivedChunks.get(index);
100
- if (previousChunkAtIndex && previousChunkAtIndex.version > chunk.version) {
101
- // we have a newer version already, dropping the old one
102
- return;
103
- }
104
- this.receivedChunks.set(index, chunk);
105
- this.bytesReceived += chunk.content.byteLength;
106
- const currentProgress = this.totalByteSize
107
- ? this.bytesReceived / this.totalByteSize
108
- : undefined;
109
- this.onProgress?.(currentProgress);
110
- }
111
-
112
- /**
113
- * @param progress - progress of the stream between 0 and 1. Undefined for streams of unknown size
114
- */
115
- onProgress?: (progress: number | undefined) => void;
116
-
117
- /**
118
- * Async iterator implementation to allow usage of `for await...of` syntax.
119
- * Yields structured chunks from the stream.
120
- *
121
- */
122
- [Symbol.asyncIterator]() {
123
- const reader = this.reader.getReader();
124
- const decoder = new TextDecoder();
125
-
126
- return {
127
- next: async (): Promise<IteratorResult<string>> => {
128
- try {
129
- const { done, value } = await reader.read();
130
- if (done) {
131
- return { done: true, value: undefined };
132
- } else {
133
- this.handleChunkReceived(value);
134
-
135
- return {
136
- done: false,
137
- value: decoder.decode(value.content),
138
- };
139
- }
140
- } catch (error) {
141
- // TODO handle errors
142
- return { done: true, value: undefined };
143
- }
144
- },
145
-
146
- async return(): Promise<IteratorResult<string>> {
147
- reader.releaseLock();
148
- return { done: true, value: undefined };
149
- },
150
- };
151
- }
152
-
153
- async readAll(): Promise<string> {
154
- let finalString: string = '';
155
- for await (const chunk of this) {
156
- finalString += chunk;
157
- }
158
- return finalString;
159
- }
160
- }
161
-
162
- export type ByteStreamHandler = (
163
- reader: ByteStreamReader,
164
- participantInfo: { identity: string },
165
- ) => void;
166
-
167
- export type TextStreamHandler = (
168
- reader: TextStreamReader,
169
- participantInfo: { identity: string },
170
- ) => void;