@xsai/stream-transcription 0.5.0-beta.1 → 0.5.0-beta.3
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/index.js +10 -64
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -1,60 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
const parseJSONChunk = (data) => {
|
|
4
|
-
if (data.startsWith("{") && data.includes('"error":')) {
|
|
5
|
-
throw new RemoteAPIError(`Error from server: ${data}`, {
|
|
6
|
-
responseBody: data
|
|
7
|
-
});
|
|
8
|
-
}
|
|
9
|
-
try {
|
|
10
|
-
return JSON.parse(data);
|
|
11
|
-
} catch (cause) {
|
|
12
|
-
throw new JSONParseError(`Failed to parse stream chunk JSON: ${data}`, {
|
|
13
|
-
cause,
|
|
14
|
-
text: data
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
const parseChunk = (text) => {
|
|
19
|
-
if (!text || !text.startsWith("data:"))
|
|
20
|
-
return [void 0, false];
|
|
21
|
-
const content = text.slice("data:".length);
|
|
22
|
-
const data = content.startsWith(" ") ? content.slice(1) : content;
|
|
23
|
-
if (data.includes("[DONE]")) {
|
|
24
|
-
return [void 0, true];
|
|
25
|
-
}
|
|
26
|
-
return [parseJSONChunk(data), false];
|
|
27
|
-
};
|
|
28
|
-
const transformChunk = () => {
|
|
29
|
-
const decoder = new TextDecoder();
|
|
30
|
-
let buffer = "";
|
|
31
|
-
return new TransformStream({
|
|
32
|
-
transform: async (chunk, controller) => {
|
|
33
|
-
const text = decoder.decode(chunk, { stream: true });
|
|
34
|
-
buffer += text;
|
|
35
|
-
const lines = buffer.split("\n");
|
|
36
|
-
buffer = lines.pop() ?? "";
|
|
37
|
-
for (const line of lines) {
|
|
38
|
-
try {
|
|
39
|
-
const [chunk2, isEnd] = parseChunk(line);
|
|
40
|
-
if (isEnd)
|
|
41
|
-
break;
|
|
42
|
-
if (chunk2)
|
|
43
|
-
controller.enqueue(chunk2);
|
|
44
|
-
} catch (error) {
|
|
45
|
-
controller.error(error);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
};
|
|
1
|
+
import { DelayedPromise, requestURL, requestHeaders, responseCatch } from '@xsai/shared';
|
|
2
|
+
import { createControlledStream, closeControllers, errorControllers, EventSourceParserStream, JsonMessageTransformStream } from '@xsai/shared-stream';
|
|
52
3
|
|
|
53
4
|
const streamTranscription = (options) => {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const fullStream = new ReadableStream({ start: (controller) => fullStreamCtrl = controller });
|
|
57
|
-
const textStream = new ReadableStream({ start: (controller) => textStreamCtrl = controller });
|
|
5
|
+
const [textStream, textStreamCtrl] = createControlledStream();
|
|
6
|
+
const [fullStream, fullStreamCtrl] = createControlledStream();
|
|
58
7
|
const fullText = new DelayedPromise();
|
|
59
8
|
let text = "";
|
|
60
9
|
const doStream = async () => {
|
|
@@ -76,18 +25,17 @@ const streamTranscription = (options) => {
|
|
|
76
25
|
});
|
|
77
26
|
await responseCatch(response);
|
|
78
27
|
const { body: stream } = response;
|
|
79
|
-
await stream.pipeThrough(
|
|
28
|
+
await stream.pipeThrough(new TextDecoderStream()).pipeThrough(new EventSourceParserStream()).pipeThrough(new JsonMessageTransformStream()).pipeTo(new WritableStream({
|
|
80
29
|
abort: (reason) => {
|
|
81
|
-
|
|
82
|
-
textStreamCtrl?.error(reason);
|
|
30
|
+
errorControllers(reason, fullStreamCtrl, textStreamCtrl);
|
|
83
31
|
},
|
|
84
32
|
close: () => {
|
|
85
33
|
},
|
|
86
34
|
write: (chunk) => {
|
|
87
35
|
if (chunk.type === "transcript.text.delta") {
|
|
88
|
-
textStreamCtrl?.enqueue(chunk.delta);
|
|
36
|
+
textStreamCtrl.current?.enqueue(chunk.delta);
|
|
89
37
|
text += chunk.delta;
|
|
90
|
-
fullStreamCtrl?.enqueue(chunk);
|
|
38
|
+
fullStreamCtrl.current?.enqueue(chunk);
|
|
91
39
|
} else if (chunk.type === "transcript.text.done") ;
|
|
92
40
|
}
|
|
93
41
|
}));
|
|
@@ -96,11 +44,9 @@ const streamTranscription = (options) => {
|
|
|
96
44
|
try {
|
|
97
45
|
await doStream();
|
|
98
46
|
fullText.resolve(text);
|
|
99
|
-
fullStreamCtrl
|
|
100
|
-
textStreamCtrl?.close();
|
|
47
|
+
closeControllers(fullStreamCtrl, textStreamCtrl);
|
|
101
48
|
} catch (err) {
|
|
102
|
-
|
|
103
|
-
textStreamCtrl?.error(err);
|
|
49
|
+
errorControllers(err, fullStreamCtrl, textStreamCtrl);
|
|
104
50
|
fullText.reject(err);
|
|
105
51
|
}
|
|
106
52
|
})();
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xsai/stream-transcription",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.5.0-beta.
|
|
4
|
+
"version": "0.5.0-beta.3",
|
|
5
5
|
"description": "extra-small AI SDK.",
|
|
6
6
|
"author": "Moeru AI",
|
|
7
7
|
"license": "MIT",
|
|
@@ -29,7 +29,8 @@
|
|
|
29
29
|
"dist"
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@xsai/shared": "
|
|
32
|
+
"@xsai/shared": "0.5.0-beta.3",
|
|
33
|
+
"@xsai/shared-stream": "0.5.0-beta.3"
|
|
33
34
|
},
|
|
34
35
|
"scripts": {
|
|
35
36
|
"build": "pkgroll",
|