@livekit/rtc-node 0.13.4 → 0.13.5

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 (54) hide show
  1. package/dist/data_streams/index.d.cts +1 -1
  2. package/dist/data_streams/index.d.ts +1 -1
  3. package/dist/data_streams/stream_reader.cjs +5 -9
  4. package/dist/data_streams/stream_reader.cjs.map +1 -1
  5. package/dist/data_streams/stream_reader.d.cts +1 -1
  6. package/dist/data_streams/stream_reader.d.ts +1 -1
  7. package/dist/data_streams/stream_reader.d.ts.map +1 -1
  8. package/dist/data_streams/stream_reader.js +5 -9
  9. package/dist/data_streams/stream_reader.js.map +1 -1
  10. package/dist/data_streams/stream_writer.cjs +2 -2
  11. package/dist/data_streams/stream_writer.cjs.map +1 -1
  12. package/dist/data_streams/stream_writer.d.cts +5 -5
  13. package/dist/data_streams/stream_writer.d.ts +5 -5
  14. package/dist/data_streams/stream_writer.d.ts.map +1 -1
  15. package/dist/data_streams/stream_writer.js +2 -2
  16. package/dist/data_streams/stream_writer.js.map +1 -1
  17. package/dist/data_streams/types.cjs.map +1 -1
  18. package/dist/data_streams/types.d.cts +1 -1
  19. package/dist/data_streams/types.d.ts +1 -1
  20. package/dist/data_streams/types.d.ts.map +1 -1
  21. package/dist/index.d.cts +1 -1
  22. package/dist/index.d.ts +1 -1
  23. package/dist/participant.cjs +9 -20
  24. package/dist/participant.cjs.map +1 -1
  25. package/dist/participant.d.cts +1 -1
  26. package/dist/participant.d.ts +1 -1
  27. package/dist/participant.d.ts.map +1 -1
  28. package/dist/participant.js +9 -20
  29. package/dist/participant.js.map +1 -1
  30. package/dist/room.d.cts +1 -1
  31. package/dist/room.d.ts +1 -1
  32. package/dist/{types-BWsKf9LP.d.cts → types-B28ZM-Ci.d.cts} +3 -8
  33. package/dist/{types-Ca3IVRvo.d.ts → types-BDnbvXeD.d.ts} +3 -8
  34. package/dist/utils.cjs +15 -5
  35. package/dist/utils.cjs.map +1 -1
  36. package/dist/utils.d.cts +1 -1
  37. package/dist/utils.d.ts +1 -1
  38. package/dist/utils.d.ts.map +1 -1
  39. package/dist/utils.js +15 -5
  40. package/dist/utils.js.map +1 -1
  41. package/dist/version.cjs +1 -1
  42. package/dist/version.cjs.map +1 -1
  43. package/dist/version.d.cts +1 -1
  44. package/dist/version.d.ts +1 -1
  45. package/dist/version.js +1 -1
  46. package/dist/version.js.map +1 -1
  47. package/package.json +6 -6
  48. package/src/data_streams/stream_reader.ts +8 -15
  49. package/src/data_streams/stream_writer.ts +5 -5
  50. package/src/data_streams/types.ts +0 -6
  51. package/src/participant.ts +11 -25
  52. package/src/utils.test.ts +51 -0
  53. package/src/utils.ts +17 -8
  54. package/src/version.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\n/** convert bigints to numbers preserving undefined values */\nexport function bigIntToNumber<T extends bigint | undefined>(\n value: T,\n): T extends bigint ? number : undefined {\n return (value !== undefined ? Number(value) : undefined) as T extends bigint ? number : undefined;\n}\n\n/** convert numbers to bigints preserving undefined values */\nexport function numberToBigInt<T extends number | undefined>(\n value: T,\n): T extends number ? bigint : undefined {\n return (value !== undefined ? BigInt(value) : undefined) as T extends number ? bigint : undefined;\n}\n\nexport function splitUtf8(s: string, n: number): string[] {\n // adapted from https://stackoverflow.com/a/6043797\n const result: string[] = [];\n while (s.length > n) {\n let k = n;\n // Move back to find the start of a UTF-8 character\n while ((s.charCodeAt(k) & 0xc0) === 0x80) {\n k--;\n }\n result.push(s.slice(0, k));\n s = s.slice(k);\n }\n result.push(s);\n return result;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKO,SAAS,eACd,OACuC;AACvC,SAAQ,UAAU,SAAY,OAAO,KAAK,IAAI;AAChD;AAGO,SAAS,eACd,OACuC;AACvC,SAAQ,UAAU,SAAY,OAAO,KAAK,IAAI;AAChD;AAEO,SAAS,UAAU,GAAW,GAAqB;AAExD,QAAM,SAAmB,CAAC;AAC1B,SAAO,EAAE,SAAS,GAAG;AACnB,QAAI,IAAI;AAER,YAAQ,EAAE,WAAW,CAAC,IAAI,SAAU,KAAM;AACxC;AAAA,IACF;AACA,WAAO,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC;AACzB,QAAI,EAAE,MAAM,CAAC;AAAA,EACf;AACA,SAAO,KAAK,CAAC;AACb,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../src/utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\n/** convert bigints to numbers preserving undefined values */\nexport function bigIntToNumber<T extends bigint | undefined>(\n value: T,\n): T extends bigint ? number : undefined {\n return (value !== undefined ? Number(value) : undefined) as T extends bigint ? number : undefined;\n}\n\n/** convert numbers to bigints preserving undefined values */\nexport function numberToBigInt<T extends number | undefined>(\n value: T,\n): T extends number ? bigint : undefined {\n return (value !== undefined ? BigInt(value) : undefined) as T extends number ? bigint : undefined;\n}\n\nexport function splitUtf8(s: string, n: number): Uint8Array[] {\n if (n < 4) {\n throw new Error('n must be at least 4 due to utf8 encoding rules');\n }\n // adapted from https://stackoverflow.com/a/6043797\n const result: Uint8Array[] = [];\n let encoded = new TextEncoder().encode(s);\n while (encoded.length > n) {\n let k = n;\n while (k > 0) {\n const byte = encoded[k];\n if (byte !== undefined && (byte & 0xc0) !== 0x80) {\n break;\n }\n k--;\n }\n result.push(encoded.slice(0, k));\n encoded = encoded.slice(k);\n }\n if (encoded.length > 0) {\n result.push(encoded);\n }\n return result;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKO,SAAS,eACd,OACuC;AACvC,SAAQ,UAAU,SAAY,OAAO,KAAK,IAAI;AAChD;AAGO,SAAS,eACd,OACuC;AACvC,SAAQ,UAAU,SAAY,OAAO,KAAK,IAAI;AAChD;AAEO,SAAS,UAAU,GAAW,GAAyB;AAC5D,MAAI,IAAI,GAAG;AACT,UAAM,IAAI,MAAM,iDAAiD;AAAA,EACnE;AAEA,QAAM,SAAuB,CAAC;AAC9B,MAAI,UAAU,IAAI,YAAY,EAAE,OAAO,CAAC;AACxC,SAAO,QAAQ,SAAS,GAAG;AACzB,QAAI,IAAI;AACR,WAAO,IAAI,GAAG;AACZ,YAAM,OAAO,QAAQ,CAAC;AACtB,UAAI,SAAS,WAAc,OAAO,SAAU,KAAM;AAChD;AAAA,MACF;AACA;AAAA,IACF;AACA,WAAO,KAAK,QAAQ,MAAM,GAAG,CAAC,CAAC;AAC/B,cAAU,QAAQ,MAAM,CAAC;AAAA,EAC3B;AACA,MAAI,QAAQ,SAAS,GAAG;AACtB,WAAO,KAAK,OAAO;AAAA,EACrB;AACA,SAAO;AACT;","names":[]}
package/dist/utils.d.cts CHANGED
@@ -2,6 +2,6 @@
2
2
  declare function bigIntToNumber<T extends bigint | undefined>(value: T): T extends bigint ? number : undefined;
3
3
  /** convert numbers to bigints preserving undefined values */
4
4
  declare function numberToBigInt<T extends number | undefined>(value: T): T extends number ? bigint : undefined;
5
- declare function splitUtf8(s: string, n: number): string[];
5
+ declare function splitUtf8(s: string, n: number): Uint8Array[];
6
6
 
7
7
  export { bigIntToNumber, numberToBigInt, splitUtf8 };
package/dist/utils.d.ts CHANGED
@@ -2,6 +2,6 @@
2
2
  declare function bigIntToNumber<T extends bigint | undefined>(value: T): T extends bigint ? number : undefined;
3
3
  /** convert numbers to bigints preserving undefined values */
4
4
  declare function numberToBigInt<T extends number | undefined>(value: T): T extends number ? bigint : undefined;
5
- declare function splitUtf8(s: string, n: number): string[];
5
+ declare function splitUtf8(s: string, n: number): Uint8Array[];
6
6
 
7
7
  export { bigIntToNumber, numberToBigInt, splitUtf8 };
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAIA,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,SAAS,EACzD,KAAK,EAAE,CAAC,GACP,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,SAAS,CAEvC;AAED,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,SAAS,EACzD,KAAK,EAAE,CAAC,GACP,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,SAAS,CAEvC;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAcxD"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAIA,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,SAAS,EACzD,KAAK,EAAE,CAAC,GACP,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,SAAS,CAEvC;AAED,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,SAAS,EACzD,KAAK,EAAE,CAAC,GACP,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,SAAS,CAEvC;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE,CAuB5D"}
package/dist/utils.js CHANGED
@@ -5,16 +5,26 @@ function numberToBigInt(value) {
5
5
  return value !== void 0 ? BigInt(value) : void 0;
6
6
  }
7
7
  function splitUtf8(s, n) {
8
+ if (n < 4) {
9
+ throw new Error("n must be at least 4 due to utf8 encoding rules");
10
+ }
8
11
  const result = [];
9
- while (s.length > n) {
12
+ let encoded = new TextEncoder().encode(s);
13
+ while (encoded.length > n) {
10
14
  let k = n;
11
- while ((s.charCodeAt(k) & 192) === 128) {
15
+ while (k > 0) {
16
+ const byte = encoded[k];
17
+ if (byte !== void 0 && (byte & 192) !== 128) {
18
+ break;
19
+ }
12
20
  k--;
13
21
  }
14
- result.push(s.slice(0, k));
15
- s = s.slice(k);
22
+ result.push(encoded.slice(0, k));
23
+ encoded = encoded.slice(k);
24
+ }
25
+ if (encoded.length > 0) {
26
+ result.push(encoded);
16
27
  }
17
- result.push(s);
18
28
  return result;
19
29
  }
20
30
  export {
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\n/** convert bigints to numbers preserving undefined values */\nexport function bigIntToNumber<T extends bigint | undefined>(\n value: T,\n): T extends bigint ? number : undefined {\n return (value !== undefined ? Number(value) : undefined) as T extends bigint ? number : undefined;\n}\n\n/** convert numbers to bigints preserving undefined values */\nexport function numberToBigInt<T extends number | undefined>(\n value: T,\n): T extends number ? bigint : undefined {\n return (value !== undefined ? BigInt(value) : undefined) as T extends number ? bigint : undefined;\n}\n\nexport function splitUtf8(s: string, n: number): string[] {\n // adapted from https://stackoverflow.com/a/6043797\n const result: string[] = [];\n while (s.length > n) {\n let k = n;\n // Move back to find the start of a UTF-8 character\n while ((s.charCodeAt(k) & 0xc0) === 0x80) {\n k--;\n }\n result.push(s.slice(0, k));\n s = s.slice(k);\n }\n result.push(s);\n return result;\n}\n"],"mappings":"AAKO,SAAS,eACd,OACuC;AACvC,SAAQ,UAAU,SAAY,OAAO,KAAK,IAAI;AAChD;AAGO,SAAS,eACd,OACuC;AACvC,SAAQ,UAAU,SAAY,OAAO,KAAK,IAAI;AAChD;AAEO,SAAS,UAAU,GAAW,GAAqB;AAExD,QAAM,SAAmB,CAAC;AAC1B,SAAO,EAAE,SAAS,GAAG;AACnB,QAAI,IAAI;AAER,YAAQ,EAAE,WAAW,CAAC,IAAI,SAAU,KAAM;AACxC;AAAA,IACF;AACA,WAAO,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC;AACzB,QAAI,EAAE,MAAM,CAAC;AAAA,EACf;AACA,SAAO,KAAK,CAAC;AACb,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../src/utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\n/** convert bigints to numbers preserving undefined values */\nexport function bigIntToNumber<T extends bigint | undefined>(\n value: T,\n): T extends bigint ? number : undefined {\n return (value !== undefined ? Number(value) : undefined) as T extends bigint ? number : undefined;\n}\n\n/** convert numbers to bigints preserving undefined values */\nexport function numberToBigInt<T extends number | undefined>(\n value: T,\n): T extends number ? bigint : undefined {\n return (value !== undefined ? BigInt(value) : undefined) as T extends number ? bigint : undefined;\n}\n\nexport function splitUtf8(s: string, n: number): Uint8Array[] {\n if (n < 4) {\n throw new Error('n must be at least 4 due to utf8 encoding rules');\n }\n // adapted from https://stackoverflow.com/a/6043797\n const result: Uint8Array[] = [];\n let encoded = new TextEncoder().encode(s);\n while (encoded.length > n) {\n let k = n;\n while (k > 0) {\n const byte = encoded[k];\n if (byte !== undefined && (byte & 0xc0) !== 0x80) {\n break;\n }\n k--;\n }\n result.push(encoded.slice(0, k));\n encoded = encoded.slice(k);\n }\n if (encoded.length > 0) {\n result.push(encoded);\n }\n return result;\n}\n"],"mappings":"AAKO,SAAS,eACd,OACuC;AACvC,SAAQ,UAAU,SAAY,OAAO,KAAK,IAAI;AAChD;AAGO,SAAS,eACd,OACuC;AACvC,SAAQ,UAAU,SAAY,OAAO,KAAK,IAAI;AAChD;AAEO,SAAS,UAAU,GAAW,GAAyB;AAC5D,MAAI,IAAI,GAAG;AACT,UAAM,IAAI,MAAM,iDAAiD;AAAA,EACnE;AAEA,QAAM,SAAuB,CAAC;AAC9B,MAAI,UAAU,IAAI,YAAY,EAAE,OAAO,CAAC;AACxC,SAAO,QAAQ,SAAS,GAAG;AACzB,QAAI,IAAI;AACR,WAAO,IAAI,GAAG;AACZ,YAAM,OAAO,QAAQ,CAAC;AACtB,UAAI,SAAS,WAAc,OAAO,SAAU,KAAM;AAChD;AAAA,MACF;AACA;AAAA,IACF;AACA,WAAO,KAAK,QAAQ,MAAM,GAAG,CAAC,CAAC;AAC/B,cAAU,QAAQ,MAAM,CAAC;AAAA,EAC3B;AACA,MAAI,QAAQ,SAAS,GAAG;AACtB,WAAO,KAAK,OAAO;AAAA,EACrB;AACA,SAAO;AACT;","names":[]}
package/dist/version.cjs CHANGED
@@ -21,7 +21,7 @@ __export(version_exports, {
21
21
  SDK_VERSION: () => SDK_VERSION
22
22
  });
23
23
  module.exports = __toCommonJS(version_exports);
24
- const SDK_VERSION = "0.13.4";
24
+ const SDK_VERSION = "0.13.5";
25
25
  // Annotate the CommonJS export names for ESM import in node:
26
26
  0 && (module.exports = {
27
27
  SDK_VERSION
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/version.ts"],"sourcesContent":["export const SDK_VERSION = \"0.13.4\";\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,cAAc;","names":[]}
1
+ {"version":3,"sources":["../src/version.ts"],"sourcesContent":["export const SDK_VERSION = \"0.13.5\";\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,cAAc;","names":[]}
@@ -1,3 +1,3 @@
1
- declare const SDK_VERSION = "0.13.4";
1
+ declare const SDK_VERSION = "0.13.5";
2
2
 
3
3
  export { SDK_VERSION };
package/dist/version.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- declare const SDK_VERSION = "0.13.4";
1
+ declare const SDK_VERSION = "0.13.5";
2
2
 
3
3
  export { SDK_VERSION };
package/dist/version.js CHANGED
@@ -1,4 +1,4 @@
1
- const SDK_VERSION = "0.13.4";
1
+ const SDK_VERSION = "0.13.5";
2
2
  export {
3
3
  SDK_VERSION
4
4
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/version.ts"],"sourcesContent":["export const SDK_VERSION = \"0.13.4\";\n"],"mappings":"AAAO,MAAM,cAAc;","names":[]}
1
+ {"version":3,"sources":["../src/version.ts"],"sourcesContent":["export const SDK_VERSION = \"0.13.5\";\n"],"mappings":"AAAO,MAAM,cAAc;","names":[]}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "LiveKit RTC Node",
4
4
  "license": "Apache-2.0",
5
5
  "author": "LiveKit",
6
- "version": "0.13.4",
6
+ "version": "0.13.5",
7
7
  "main": "dist/index.js",
8
8
  "require": "dist/index.cjs",
9
9
  "types": "dist/index.d.ts",
@@ -61,11 +61,11 @@
61
61
  "@bufbuild/protoc-gen-es": "^1.10.0"
62
62
  },
63
63
  "optionalDependencies": {
64
- "@livekit/rtc-node-darwin-arm64": "0.13.4",
65
- "@livekit/rtc-node-darwin-x64": "0.13.4",
66
- "@livekit/rtc-node-linux-arm64-gnu": "0.13.4",
67
- "@livekit/rtc-node-linux-x64-gnu": "0.13.4",
68
- "@livekit/rtc-node-win32-x64-msvc": "0.13.4"
64
+ "@livekit/rtc-node-darwin-arm64": "0.13.5",
65
+ "@livekit/rtc-node-darwin-x64": "0.13.5",
66
+ "@livekit/rtc-node-linux-arm64-gnu": "0.13.5",
67
+ "@livekit/rtc-node-linux-x64-gnu": "0.13.5",
68
+ "@livekit/rtc-node-win32-x64-msvc": "0.13.5"
69
69
  },
70
70
  "engines": {
71
71
  "node": ">= 18"
@@ -5,7 +5,7 @@ import type { ReadableStream } from 'node:stream/web';
5
5
  import { log } from '../log.js';
6
6
  import type { DataStream_Chunk } from '../proto/room_pb.js';
7
7
  import { bigIntToNumber } from '../utils.js';
8
- import type { BaseStreamInfo, ByteStreamInfo, TextStreamChunk, TextStreamInfo } from './types.js';
8
+ import type { BaseStreamInfo, ByteStreamInfo, TextStreamInfo } from './types.js';
9
9
 
10
10
  abstract class BaseStreamReader<T extends BaseStreamInfo> {
11
11
  protected reader: ReadableStream<DataStream_Chunk>;
@@ -124,7 +124,7 @@ export class TextStreamReader extends BaseStreamReader<TextStreamInfo> {
124
124
  const decoder = new TextDecoder();
125
125
 
126
126
  return {
127
- next: async (): Promise<IteratorResult<TextStreamChunk>> => {
127
+ next: async (): Promise<IteratorResult<string>> => {
128
128
  try {
129
129
  const { done, value } = await reader.read();
130
130
  if (done) {
@@ -133,14 +133,7 @@ export class TextStreamReader extends BaseStreamReader<TextStreamInfo> {
133
133
  this.handleChunkReceived(value);
134
134
  return {
135
135
  done: false,
136
- value: {
137
- index: bigIntToNumber(value.chunkIndex)!,
138
- current: decoder.decode(value.content!),
139
- collected: Array.from(this.receivedChunks.values())
140
- .sort((a, b) => bigIntToNumber(a.chunkIndex!) - bigIntToNumber(b.chunkIndex!))
141
- .map((chunk) => decoder.decode(chunk.content!))
142
- .join(''),
143
- },
136
+ value: decoder.decode(value.content!),
144
137
  };
145
138
  }
146
139
  } catch (error) {
@@ -149,7 +142,7 @@ export class TextStreamReader extends BaseStreamReader<TextStreamInfo> {
149
142
  }
150
143
  },
151
144
 
152
- return(): IteratorResult<TextStreamChunk> {
145
+ return(): IteratorResult<string> {
153
146
  reader.releaseLock();
154
147
  return { done: true, value: undefined };
155
148
  },
@@ -157,10 +150,10 @@ export class TextStreamReader extends BaseStreamReader<TextStreamInfo> {
157
150
  }
158
151
 
159
152
  async readAll(): Promise<string> {
160
- let latestString: string = '';
161
- for await (const { collected } of this) {
162
- latestString = collected;
153
+ let finalString: string = '';
154
+ for await (const chunk of this) {
155
+ finalString += chunk;
163
156
  }
164
- return latestString;
157
+ return finalString;
165
158
  }
166
159
  }
@@ -5,23 +5,23 @@ import type { WritableStream } from 'node:stream/web';
5
5
  import type { BaseStreamInfo, ByteStreamInfo, TextStreamInfo } from './types.js';
6
6
 
7
7
  class BaseStreamWriter<T, InfoType extends BaseStreamInfo> {
8
- protected writableStream: WritableStream<[T, number?]>;
8
+ protected writableStream: WritableStream<T>;
9
9
 
10
- protected defaultWriter: WritableStreamDefaultWriter<[T, number?]>;
10
+ protected defaultWriter: WritableStreamDefaultWriter<T>;
11
11
 
12
12
  protected onClose?: () => void;
13
13
 
14
14
  readonly info: InfoType;
15
15
 
16
- constructor(writableStream: WritableStream<[T, number?]>, info: InfoType, onClose?: () => void) {
16
+ constructor(writableStream: WritableStream<T>, info: InfoType, onClose?: () => void) {
17
17
  this.writableStream = writableStream;
18
18
  this.defaultWriter = writableStream.getWriter();
19
19
  this.onClose = onClose;
20
20
  this.info = info;
21
21
  }
22
22
 
23
- write(chunk: T, chunkIndex?: number): Promise<void> {
24
- return this.defaultWriter.write([chunk, chunkIndex]);
23
+ write(chunk: T): Promise<void> {
24
+ return this.defaultWriter.write(chunk);
25
25
  }
26
26
 
27
27
  async close() {
@@ -27,12 +27,6 @@ export type ByteStreamInfo = BaseStreamInfo & {
27
27
 
28
28
  export type TextStreamInfo = BaseStreamInfo;
29
29
 
30
- export type TextStreamChunk = {
31
- index: number;
32
- current: string;
33
- collected: string;
34
- };
35
-
36
30
  export interface DataStreamOptions {
37
31
  topic?: string;
38
32
  destinationIdentities?: Array<string>;
@@ -293,40 +293,29 @@ export class LocalParticipant extends Participant {
293
293
 
294
294
  await this.sendStreamHeader(headerReq);
295
295
 
296
- let chunkId = 0;
296
+ let nextChunkId = 0;
297
297
  const localHandle = this.ffi_handle.handle;
298
298
  const sendTrailer = this.sendStreamTrailer;
299
299
  const sendChunk = this.sendStreamChunk;
300
300
 
301
- const writableStream = new WritableStream<[string, number?]>({
301
+ const writableStream = new WritableStream<string>({
302
302
  // Implement the sink
303
- write([textChunk, overrideChunkId]) {
304
- const textInBytes = new TextEncoder().encode(textChunk);
305
-
306
- if (textInBytes.byteLength > STREAM_CHUNK_SIZE) {
307
- this.abort?.();
308
- throw new Error('chunk size too large');
309
- }
310
-
311
- return new Promise(async (resolve) => {
303
+ async write(text) {
304
+ for (const textByteChunk of splitUtf8(text, STREAM_CHUNK_SIZE)) {
312
305
  const chunkRequest = new SendStreamChunkRequest({
313
306
  senderIdentity,
314
307
  localParticipantHandle: localHandle,
315
308
  destinationIdentities,
316
309
  chunk: new DataStream_Chunk({
317
- content: textInBytes,
310
+ content: textByteChunk,
318
311
  streamId,
319
- chunkIndex: numberToBigInt(overrideChunkId ?? chunkId),
312
+ chunkIndex: numberToBigInt(nextChunkId),
320
313
  }),
321
314
  });
322
315
 
323
316
  await sendChunk(chunkRequest);
324
-
325
- if (!overrideChunkId) {
326
- chunkId += 1;
327
- resolve();
328
- }
329
- });
317
+ nextChunkId += 1;
318
+ }
330
319
  },
331
320
  async close() {
332
321
  const trailerReq = new SendStreamTrailerRequest({
@@ -360,10 +349,7 @@ export class LocalParticipant extends Participant {
360
349
  },
361
350
  ) {
362
351
  const writer = await this.streamText(options);
363
-
364
- for (const chunk in splitUtf8(text, STREAM_CHUNK_SIZE)) {
365
- await writer.write(chunk);
366
- }
352
+ await writer.write(text);
367
353
  await writer.close();
368
354
  return writer.info;
369
355
  }
@@ -419,8 +405,8 @@ export class LocalParticipant extends Participant {
419
405
  const sendChunk = this.sendStreamChunk;
420
406
  const writeMutex = new Mutex();
421
407
 
422
- const writableStream = new WritableStream<[Uint8Array, number?]>({
423
- async write([chunk]) {
408
+ const writableStream = new WritableStream<Uint8Array>({
409
+ async write(chunk) {
424
410
  const unlock = await writeMutex.lock();
425
411
 
426
412
  let byteOffset = 0;
@@ -0,0 +1,51 @@
1
+ // SPDX-FileCopyrightText: 2024 LiveKit, Inc.
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ import { describe, expect, it } from 'vitest';
5
+ import { splitUtf8 } from './utils.js';
6
+
7
+ describe('splitUtf8', () => {
8
+ it('splits a string into chunks of the given size', () => {
9
+ expect(splitUtf8('hello world', 5)).toEqual([
10
+ new TextEncoder().encode('hello'),
11
+ new TextEncoder().encode(' worl'),
12
+ new TextEncoder().encode('d'),
13
+ ]);
14
+ });
15
+
16
+ it('splits a string with special characters into chunks of the given size', () => {
17
+ expect(splitUtf8('héllo wörld', 5)).toEqual([
18
+ new TextEncoder().encode('héll'),
19
+ new TextEncoder().encode('o wö'),
20
+ new TextEncoder().encode('rld'),
21
+ ]);
22
+ });
23
+
24
+ it('splits a string with multi-byte utf8 characters correctly', () => {
25
+ expect(splitUtf8('こんにちは世界', 5)).toEqual([
26
+ new TextEncoder().encode('こ'),
27
+ new TextEncoder().encode('ん'),
28
+ new TextEncoder().encode('に'),
29
+ new TextEncoder().encode('ち'),
30
+ new TextEncoder().encode('は'),
31
+ new TextEncoder().encode('世'),
32
+ new TextEncoder().encode('界'),
33
+ ]);
34
+ });
35
+
36
+ it('handles a string with a single multi-byte utf8 character', () => {
37
+ expect(splitUtf8('😊', 5)).toEqual([new TextEncoder().encode('😊')]);
38
+ });
39
+
40
+ it('handles a string with mixed single and multi-byte utf8 characters', () => {
41
+ expect(splitUtf8('a😊b', 4)).toEqual([
42
+ new TextEncoder().encode('a'),
43
+ new TextEncoder().encode('😊'),
44
+ new TextEncoder().encode('b'),
45
+ ]);
46
+ });
47
+
48
+ it('handles an empty string', () => {
49
+ expect(splitUtf8('', 5)).toEqual([]);
50
+ });
51
+ });
package/src/utils.ts CHANGED
@@ -16,18 +16,27 @@ export function numberToBigInt<T extends number | undefined>(
16
16
  return (value !== undefined ? BigInt(value) : undefined) as T extends number ? bigint : undefined;
17
17
  }
18
18
 
19
- export function splitUtf8(s: string, n: number): string[] {
19
+ export function splitUtf8(s: string, n: number): Uint8Array[] {
20
+ if (n < 4) {
21
+ throw new Error('n must be at least 4 due to utf8 encoding rules');
22
+ }
20
23
  // adapted from https://stackoverflow.com/a/6043797
21
- const result: string[] = [];
22
- while (s.length > n) {
24
+ const result: Uint8Array[] = [];
25
+ let encoded = new TextEncoder().encode(s);
26
+ while (encoded.length > n) {
23
27
  let k = n;
24
- // Move back to find the start of a UTF-8 character
25
- while ((s.charCodeAt(k) & 0xc0) === 0x80) {
28
+ while (k > 0) {
29
+ const byte = encoded[k];
30
+ if (byte !== undefined && (byte & 0xc0) !== 0x80) {
31
+ break;
32
+ }
26
33
  k--;
27
34
  }
28
- result.push(s.slice(0, k));
29
- s = s.slice(k);
35
+ result.push(encoded.slice(0, k));
36
+ encoded = encoded.slice(k);
37
+ }
38
+ if (encoded.length > 0) {
39
+ result.push(encoded);
30
40
  }
31
- result.push(s);
32
41
  return result;
33
42
  }
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const SDK_VERSION = "0.13.4";
1
+ export const SDK_VERSION = "0.13.5";