assistant-stream 0.2.0 → 0.2.1

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 (129) hide show
  1. package/dist/ai-sdk/index.d.ts +5 -0
  2. package/dist/ai-sdk/index.d.ts.map +1 -0
  3. package/dist/ai-sdk/language-model.d.ts +6 -0
  4. package/dist/ai-sdk/language-model.d.ts.map +1 -0
  5. package/dist/ai-sdk.d.ts +3 -0
  6. package/dist/ai-sdk.d.ts.map +1 -0
  7. package/dist/core/AssistantStream.d.ts +12 -0
  8. package/dist/core/AssistantStream.d.ts.map +1 -0
  9. package/dist/core/AssistantStreamChunk.d.ts +64 -0
  10. package/dist/core/AssistantStreamChunk.d.ts.map +1 -0
  11. package/dist/core/accumulators/AssistantMessageStream.d.ts +13 -0
  12. package/dist/core/accumulators/AssistantMessageStream.d.ts.map +1 -0
  13. package/dist/core/accumulators/assistant-message-accumulator.d.ts +8 -0
  14. package/dist/core/accumulators/assistant-message-accumulator.d.ts.map +1 -0
  15. package/dist/core/index.d.ts +11 -0
  16. package/dist/core/index.d.ts.map +1 -0
  17. package/dist/core/modules/assistant-stream.d.ts +31 -0
  18. package/dist/core/modules/assistant-stream.d.ts.map +1 -0
  19. package/dist/core/modules/text.d.ts +9 -0
  20. package/dist/core/modules/text.d.ts.map +1 -0
  21. package/dist/core/modules/tool-call.d.ts +13 -0
  22. package/dist/core/modules/tool-call.d.ts.map +1 -0
  23. package/dist/core/serialization/PlainText.d.ts +11 -0
  24. package/dist/core/serialization/PlainText.d.ts.map +1 -0
  25. package/dist/core/serialization/data-stream/DataStream.d.ts +11 -0
  26. package/dist/core/serialization/data-stream/DataStream.d.ts.map +1 -0
  27. package/dist/core/serialization/data-stream/chunk-types.d.ts +86 -0
  28. package/dist/core/serialization/data-stream/chunk-types.d.ts.map +1 -0
  29. package/dist/core/serialization/data-stream/serialization.d.ts +8 -0
  30. package/dist/core/serialization/data-stream/serialization.d.ts.map +1 -0
  31. package/dist/core/tool/ToolCallReader.d.ts +33 -0
  32. package/dist/core/tool/ToolCallReader.d.ts.map +1 -0
  33. package/dist/core/tool/ToolExecutionStream.d.ts +24 -0
  34. package/dist/core/tool/ToolExecutionStream.d.ts.map +1 -0
  35. package/dist/core/tool/ToolResponse.d.ts +17 -0
  36. package/dist/core/tool/ToolResponse.d.ts.map +1 -0
  37. package/dist/core/tool/index.d.ts +6 -0
  38. package/dist/core/tool/index.d.ts.map +1 -0
  39. package/dist/core/tool/tool-types.d.ts +76 -0
  40. package/dist/core/tool/tool-types.d.ts.map +1 -0
  41. package/dist/core/tool/toolResultStream.d.ts +6 -0
  42. package/dist/core/tool/toolResultStream.d.ts.map +1 -0
  43. package/dist/core/tool/type-path-utils.d.ts +23 -0
  44. package/dist/core/tool/type-path-utils.d.ts.map +1 -0
  45. package/dist/core/utils/Counter.d.ts +5 -0
  46. package/dist/core/utils/Counter.d.ts.map +1 -0
  47. package/dist/core/utils/generateId.d.ts +2 -0
  48. package/dist/core/utils/generateId.d.ts.map +1 -0
  49. package/dist/core/utils/stream/AssistantMetaTransformStream.d.ts +20 -0
  50. package/dist/core/utils/stream/AssistantMetaTransformStream.d.ts.map +1 -0
  51. package/dist/core/utils/stream/AssistantTransformStream.d.ts +15 -0
  52. package/dist/core/utils/stream/AssistantTransformStream.d.ts.map +1 -0
  53. package/dist/core/utils/stream/LineDecoderStream.d.ts +5 -0
  54. package/dist/core/utils/stream/LineDecoderStream.d.ts.map +1 -0
  55. package/dist/core/utils/stream/PipeableTransformStream.d.ts +4 -0
  56. package/dist/core/utils/stream/PipeableTransformStream.d.ts.map +1 -0
  57. package/dist/core/utils/stream/UnderlyingReadable.d.ts +6 -0
  58. package/dist/core/utils/stream/UnderlyingReadable.d.ts.map +1 -0
  59. package/dist/core/utils/stream/merge.d.ts +9 -0
  60. package/dist/core/utils/stream/merge.d.ts.map +1 -0
  61. package/dist/core/utils/stream/path-utils.d.ts +12 -0
  62. package/dist/core/utils/stream/path-utils.d.ts.map +1 -0
  63. package/dist/core/utils/types.d.ts +102 -0
  64. package/dist/core/utils/types.d.ts.map +1 -0
  65. package/dist/core/utils/withPromiseOrValue.d.ts +2 -0
  66. package/dist/core/utils/withPromiseOrValue.d.ts.map +1 -0
  67. package/dist/index.d.ts +2 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/utils/AsyncIterableStream.d.ts +3 -0
  70. package/dist/utils/AsyncIterableStream.d.ts.map +1 -0
  71. package/dist/utils/json/fix-json.d.ts +2 -0
  72. package/dist/utils/json/fix-json.d.ts.map +1 -0
  73. package/dist/utils/json/is-json.d.ts +5 -0
  74. package/dist/utils/json/is-json.d.ts.map +1 -0
  75. package/dist/utils/json/json-value.d.ts +6 -0
  76. package/dist/utils/json/json-value.d.ts.map +1 -0
  77. package/dist/utils/json/parse-partial-json-object.d.ts +14 -0
  78. package/dist/utils/json/parse-partial-json-object.d.ts.map +1 -0
  79. package/dist/utils/json/parse-partial-json-object.test.d.ts +2 -0
  80. package/dist/utils/json/parse-partial-json-object.test.d.ts.map +1 -0
  81. package/dist/utils/promiseWithResolvers.d.ts +6 -0
  82. package/dist/utils/promiseWithResolvers.d.ts.map +1 -0
  83. package/dist/utils.d.ts +4 -0
  84. package/dist/utils.d.ts.map +1 -0
  85. package/package.json +3 -2
  86. package/src/ai-sdk/index.ts +204 -0
  87. package/src/ai-sdk/language-model.ts +122 -0
  88. package/src/ai-sdk.ts +2 -0
  89. package/src/core/AssistantStream.ts +39 -0
  90. package/src/core/AssistantStreamChunk.ts +93 -0
  91. package/src/core/accumulators/AssistantMessageStream.ts +56 -0
  92. package/src/core/accumulators/assistant-message-accumulator.ts +394 -0
  93. package/src/core/index.ts +17 -0
  94. package/src/core/modules/assistant-stream.ts +264 -0
  95. package/src/core/modules/text.ts +64 -0
  96. package/src/core/modules/tool-call.ts +105 -0
  97. package/src/core/serialization/PlainText.ts +68 -0
  98. package/src/core/serialization/data-stream/DataStream.ts +355 -0
  99. package/src/core/serialization/data-stream/chunk-types.ts +93 -0
  100. package/src/core/serialization/data-stream/serialization.ts +32 -0
  101. package/src/core/tool/ToolCallReader.ts +432 -0
  102. package/src/core/tool/ToolExecutionStream.ts +180 -0
  103. package/src/core/tool/ToolResponse.ts +31 -0
  104. package/src/core/tool/index.ts +8 -0
  105. package/src/core/tool/tool-types.ts +107 -0
  106. package/src/core/tool/toolResultStream.ts +119 -0
  107. package/src/core/tool/type-path-utils.ts +36 -0
  108. package/src/core/utils/Counter.ts +7 -0
  109. package/src/core/utils/generateId.tsx +6 -0
  110. package/src/core/utils/stream/AssistantMetaTransformStream.ts +74 -0
  111. package/src/core/utils/stream/AssistantTransformStream.ts +74 -0
  112. package/src/core/utils/stream/LineDecoderStream.ts +29 -0
  113. package/src/core/utils/stream/PipeableTransformStream.ts +10 -0
  114. package/src/core/utils/stream/UnderlyingReadable.ts +5 -0
  115. package/src/core/utils/stream/merge.ts +212 -0
  116. package/src/core/utils/stream/path-utils.ts +71 -0
  117. package/src/core/utils/types.ts +150 -0
  118. package/src/core/utils/withPromiseOrValue.ts +20 -0
  119. package/src/index.ts +1 -0
  120. package/src/utils/AsyncIterableStream.ts +24 -0
  121. package/src/utils/json/fix-json.ts +488 -0
  122. package/src/utils/json/is-json.ts +43 -0
  123. package/src/utils/json/json-value.ts +13 -0
  124. package/src/utils/json/parse-partial-json-object.test.ts +225 -0
  125. package/src/utils/json/parse-partial-json-object.ts +103 -0
  126. package/src/utils/promiseWithResolvers.ts +10 -0
  127. package/src/utils.ts +13 -0
  128. package/utils/README.md +0 -1
  129. package/utils/package.json +0 -5
@@ -0,0 +1,355 @@
1
+ import { AssistantStreamChunk } from "../../AssistantStreamChunk";
2
+ import { ToolCallStreamController } from "../../modules/tool-call";
3
+ import { AssistantTransformStream } from "../../utils/stream/AssistantTransformStream";
4
+ import { PipeableTransformStream } from "../../utils/stream/PipeableTransformStream";
5
+ import { DataStreamChunk, DataStreamStreamChunkType } from "./chunk-types";
6
+ import { LineDecoderStream } from "../../utils/stream/LineDecoderStream";
7
+ import {
8
+ DataStreamChunkDecoder,
9
+ DataStreamChunkEncoder,
10
+ } from "./serialization";
11
+ import {
12
+ AssistantMetaStreamChunk,
13
+ AssistantMetaTransformStream,
14
+ } from "../../utils/stream/AssistantMetaTransformStream";
15
+ import { TextStreamController } from "../../modules/text";
16
+ import { AssistantStreamEncoder } from "../../AssistantStream";
17
+
18
+ export class DataStreamEncoder
19
+ extends PipeableTransformStream<AssistantStreamChunk, Uint8Array>
20
+ implements AssistantStreamEncoder
21
+ {
22
+ headers = new Headers({
23
+ "Content-Type": "text/plain; charset=utf-8",
24
+ "x-vercel-ai-data-stream": "v1",
25
+ });
26
+
27
+ constructor() {
28
+ super((readable) => {
29
+ const transform = new TransformStream<
30
+ AssistantMetaStreamChunk,
31
+ DataStreamChunk
32
+ >({
33
+ transform(chunk, controller) {
34
+ const type = chunk.type;
35
+ switch (type) {
36
+ case "part-start": {
37
+ const part = chunk.part;
38
+ if (part.type === "tool-call") {
39
+ const { type, ...value } = part;
40
+ controller.enqueue({
41
+ type: DataStreamStreamChunkType.StartToolCall,
42
+ value,
43
+ });
44
+ }
45
+ if (part.type === "source") {
46
+ const { type, ...value } = part;
47
+ controller.enqueue({
48
+ type: DataStreamStreamChunkType.Source,
49
+ value,
50
+ });
51
+ }
52
+ break;
53
+ }
54
+ case "text-delta": {
55
+ const part = chunk.meta;
56
+ switch (part.type) {
57
+ case "text": {
58
+ controller.enqueue({
59
+ type: DataStreamStreamChunkType.TextDelta,
60
+ value: chunk.textDelta,
61
+ });
62
+ break;
63
+ }
64
+ case "reasoning": {
65
+ controller.enqueue({
66
+ type: DataStreamStreamChunkType.ReasoningDelta,
67
+ value: chunk.textDelta,
68
+ });
69
+ break;
70
+ }
71
+ case "tool-call": {
72
+ controller.enqueue({
73
+ type: DataStreamStreamChunkType.ToolCallArgsTextDelta,
74
+ value: {
75
+ toolCallId: part.toolCallId,
76
+ argsTextDelta: chunk.textDelta,
77
+ },
78
+ });
79
+ break;
80
+ }
81
+ default:
82
+ throw new Error(
83
+ `Unsupported part type for text-delta: ${part.type}`,
84
+ );
85
+ }
86
+ break;
87
+ }
88
+ case "result": {
89
+ // Only tool-call parts can have results.
90
+ const part = chunk.meta;
91
+ if (part.type !== "tool-call") {
92
+ throw new Error(
93
+ `Result chunk on non-tool-call part not supported: ${part.type}`,
94
+ );
95
+ }
96
+ controller.enqueue({
97
+ type: DataStreamStreamChunkType.ToolCallResult,
98
+ value: {
99
+ toolCallId: part.toolCallId,
100
+ result: chunk.result,
101
+ artifact: chunk.artifact,
102
+ ...(chunk.isError ? { isError: chunk.isError } : {}),
103
+ },
104
+ });
105
+ break;
106
+ }
107
+ case "step-start": {
108
+ const { type, ...value } = chunk;
109
+ controller.enqueue({
110
+ type: DataStreamStreamChunkType.StartStep,
111
+ value,
112
+ });
113
+ break;
114
+ }
115
+ case "step-finish": {
116
+ const { type, ...value } = chunk;
117
+ controller.enqueue({
118
+ type: DataStreamStreamChunkType.FinishStep,
119
+ value,
120
+ });
121
+ break;
122
+ }
123
+ case "message-finish": {
124
+ const { type, ...value } = chunk;
125
+ controller.enqueue({
126
+ type: DataStreamStreamChunkType.FinishMessage,
127
+ value,
128
+ });
129
+ break;
130
+ }
131
+ case "error": {
132
+ controller.enqueue({
133
+ type: DataStreamStreamChunkType.Error,
134
+ value: chunk.error,
135
+ });
136
+ break;
137
+ }
138
+ case "annotations": {
139
+ controller.enqueue({
140
+ type: DataStreamStreamChunkType.Annotation,
141
+ value: chunk.annotations,
142
+ });
143
+ break;
144
+ }
145
+ case "data": {
146
+ controller.enqueue({
147
+ type: DataStreamStreamChunkType.Data,
148
+ value: chunk.data,
149
+ });
150
+ break;
151
+ }
152
+
153
+ // TODO ignore for now
154
+ // in the future, we should create a handler that waits for text parts to finish before continuing
155
+ case "tool-call-args-text-finish":
156
+ case "part-finish":
157
+ break;
158
+
159
+ default: {
160
+ const exhaustiveCheck: never = type;
161
+ throw new Error(`Unsupported chunk type: ${exhaustiveCheck}`);
162
+ }
163
+ }
164
+ },
165
+ });
166
+
167
+ return readable
168
+ .pipeThrough(new AssistantMetaTransformStream())
169
+ .pipeThrough(transform)
170
+ .pipeThrough(new DataStreamChunkEncoder())
171
+ .pipeThrough(new TextEncoderStream());
172
+ });
173
+ }
174
+ }
175
+
176
+ const TOOL_CALL_ARGS_CLOSING_CHUNKS = [
177
+ DataStreamStreamChunkType.StartToolCall,
178
+ DataStreamStreamChunkType.ToolCall,
179
+ DataStreamStreamChunkType.TextDelta,
180
+ DataStreamStreamChunkType.ReasoningDelta,
181
+ DataStreamStreamChunkType.Source,
182
+ DataStreamStreamChunkType.Error,
183
+ DataStreamStreamChunkType.FinishStep,
184
+ DataStreamStreamChunkType.FinishMessage,
185
+ ];
186
+
187
+ export class DataStreamDecoder extends PipeableTransformStream<
188
+ Uint8Array,
189
+ AssistantStreamChunk
190
+ > {
191
+ constructor() {
192
+ super((readable) => {
193
+ const toolCallControllers = new Map<string, ToolCallStreamController>();
194
+ let activeToolCallArgsText: TextStreamController | undefined;
195
+ const transform = new AssistantTransformStream<DataStreamChunk>({
196
+ transform(chunk, controller) {
197
+ const { type, value } = chunk;
198
+
199
+ if (TOOL_CALL_ARGS_CLOSING_CHUNKS.includes(type)) {
200
+ activeToolCallArgsText?.close();
201
+ activeToolCallArgsText = undefined;
202
+ }
203
+
204
+ switch (type) {
205
+ case DataStreamStreamChunkType.ReasoningDelta:
206
+ controller.appendReasoning(value);
207
+ break;
208
+
209
+ case DataStreamStreamChunkType.TextDelta:
210
+ controller.appendText(value);
211
+ break;
212
+
213
+ case DataStreamStreamChunkType.StartToolCall: {
214
+ const { toolCallId, toolName } = value;
215
+ const toolCallController = controller.addToolCallPart({
216
+ toolCallId,
217
+ toolName,
218
+ });
219
+ toolCallControllers.set(toolCallId, toolCallController);
220
+
221
+ activeToolCallArgsText = toolCallController.argsText;
222
+ break;
223
+ }
224
+
225
+ case DataStreamStreamChunkType.ToolCallArgsTextDelta: {
226
+ const { toolCallId, argsTextDelta } = value;
227
+ const toolCallController = toolCallControllers.get(toolCallId);
228
+ if (!toolCallController)
229
+ throw new Error(
230
+ "Encountered tool call with unknown id: " + toolCallId,
231
+ );
232
+ toolCallController.argsText.append(argsTextDelta);
233
+ break;
234
+ }
235
+
236
+ case DataStreamStreamChunkType.ToolCallResult: {
237
+ const { toolCallId, artifact, result, isError } = value;
238
+ const toolCallController = toolCallControllers.get(toolCallId);
239
+ if (!toolCallController)
240
+ throw new Error(
241
+ "Encountered tool call result with unknown id: " + toolCallId,
242
+ );
243
+ toolCallController.setResponse({
244
+ artifact,
245
+ result,
246
+ isError,
247
+ });
248
+ break;
249
+ }
250
+
251
+ case DataStreamStreamChunkType.ToolCall: {
252
+ const { toolCallId, toolName, args } = value;
253
+
254
+ let toolCallController = toolCallControllers.get(toolCallId);
255
+ if (toolCallController) {
256
+ toolCallController.argsText.close();
257
+ } else {
258
+ toolCallController = controller.addToolCallPart({
259
+ toolCallId,
260
+ toolName,
261
+ args,
262
+ });
263
+ toolCallControllers.set(toolCallId, toolCallController);
264
+ }
265
+ break;
266
+ }
267
+
268
+ case DataStreamStreamChunkType.FinishMessage:
269
+ controller.enqueue({
270
+ type: "message-finish",
271
+ path: [],
272
+ ...value,
273
+ });
274
+ break;
275
+
276
+ case DataStreamStreamChunkType.StartStep:
277
+ controller.enqueue({
278
+ type: "step-start",
279
+ path: [],
280
+ ...value,
281
+ });
282
+ break;
283
+
284
+ case DataStreamStreamChunkType.FinishStep:
285
+ controller.enqueue({
286
+ type: "step-finish",
287
+ path: [],
288
+ ...value,
289
+ });
290
+ break;
291
+ case DataStreamStreamChunkType.Data:
292
+ controller.enqueue({
293
+ type: "data",
294
+ path: [],
295
+ data: value,
296
+ });
297
+ break;
298
+
299
+ case DataStreamStreamChunkType.Annotation:
300
+ controller.enqueue({
301
+ type: "annotations",
302
+ path: [],
303
+ annotations: value,
304
+ });
305
+ break;
306
+
307
+ case DataStreamStreamChunkType.Source:
308
+ controller.appendSource({
309
+ type: "source",
310
+ ...value,
311
+ });
312
+ break;
313
+
314
+ case DataStreamStreamChunkType.Error:
315
+ controller.enqueue({
316
+ type: "error",
317
+ path: [],
318
+ error: value,
319
+ });
320
+ break;
321
+
322
+ case DataStreamStreamChunkType.File:
323
+ controller.appendFile({
324
+ type: "file",
325
+ ...value,
326
+ });
327
+ break;
328
+
329
+ case DataStreamStreamChunkType.ReasoningSignature:
330
+ case DataStreamStreamChunkType.RedactedReasoning:
331
+ // ignore these for now
332
+ break;
333
+
334
+ default: {
335
+ const exhaustiveCheck: never = type;
336
+ throw new Error(`unsupported chunk type: ${exhaustiveCheck}`);
337
+ }
338
+ }
339
+ },
340
+ flush() {
341
+ activeToolCallArgsText?.close();
342
+ activeToolCallArgsText = undefined;
343
+ toolCallControllers.forEach((controller) => controller.close());
344
+ toolCallControllers.clear();
345
+ },
346
+ });
347
+
348
+ return readable
349
+ .pipeThrough(new TextDecoderStream())
350
+ .pipeThrough(new LineDecoderStream())
351
+ .pipeThrough(new DataStreamChunkDecoder())
352
+ .pipeThrough(transform);
353
+ });
354
+ }
355
+ }
@@ -0,0 +1,93 @@
1
+ import {
2
+ ReadonlyJSONObject,
3
+ ReadonlyJSONValue,
4
+ } from "../../../utils/json/json-value";
5
+
6
+ export type DataStreamChunk = {
7
+ [K in DataStreamStreamChunkType]: {
8
+ type: K;
9
+ value: DataStreamStreamChunkValue[K];
10
+ };
11
+ }[DataStreamStreamChunkType];
12
+
13
+ type LanguageModelV1FinishReason =
14
+ | "stop"
15
+ | "length"
16
+ | "content-filter"
17
+ | "tool-calls"
18
+ | "error"
19
+ | "other"
20
+ | "unknown";
21
+
22
+ type LanguageModelV1Usage = {
23
+ promptTokens: number;
24
+ completionTokens: number;
25
+ };
26
+
27
+ export enum DataStreamStreamChunkType {
28
+ TextDelta = "0",
29
+ Data = "2",
30
+ Error = "3",
31
+ Annotation = "8",
32
+ ToolCall = "9",
33
+ ToolCallResult = "a",
34
+ StartToolCall = "b",
35
+ ToolCallArgsTextDelta = "c",
36
+ FinishMessage = "d",
37
+ FinishStep = "e",
38
+ StartStep = "f",
39
+ ReasoningDelta = "g",
40
+ Source = "h",
41
+ RedactedReasoning = "i",
42
+ ReasoningSignature = "j",
43
+ File = "k",
44
+ }
45
+ type DataStreamStreamChunkValue = {
46
+ [DataStreamStreamChunkType.TextDelta]: string;
47
+ [DataStreamStreamChunkType.Data]: ReadonlyJSONValue[];
48
+ [DataStreamStreamChunkType.Annotation]: ReadonlyJSONValue[];
49
+ [DataStreamStreamChunkType.ToolCall]: {
50
+ toolCallId: string;
51
+ toolName: string;
52
+ args: ReadonlyJSONObject;
53
+ };
54
+ [DataStreamStreamChunkType.StartToolCall]: {
55
+ toolCallId: string;
56
+ toolName: string;
57
+ };
58
+ [DataStreamStreamChunkType.ToolCallArgsTextDelta]: {
59
+ toolCallId: string;
60
+ argsTextDelta: string;
61
+ };
62
+ [DataStreamStreamChunkType.ToolCallResult]: {
63
+ toolCallId: string;
64
+ result: ReadonlyJSONValue;
65
+
66
+ // aui-extensions
67
+ artifact?: ReadonlyJSONValue | undefined;
68
+ isError?: boolean;
69
+ };
70
+ [DataStreamStreamChunkType.Error]: string;
71
+ [DataStreamStreamChunkType.FinishStep]: {
72
+ finishReason: LanguageModelV1FinishReason;
73
+ usage: LanguageModelV1Usage;
74
+ isContinued: boolean;
75
+ };
76
+ [DataStreamStreamChunkType.FinishMessage]: {
77
+ finishReason: LanguageModelV1FinishReason;
78
+ usage: LanguageModelV1Usage;
79
+ };
80
+ [DataStreamStreamChunkType.StartStep]: {
81
+ messageId: string;
82
+ };
83
+ [DataStreamStreamChunkType.ReasoningDelta]: string;
84
+ [DataStreamStreamChunkType.Source]: {
85
+ sourceType: "url";
86
+ id: string;
87
+ url: string;
88
+ title?: string;
89
+ };
90
+ [DataStreamStreamChunkType.RedactedReasoning]: { data: string };
91
+ [DataStreamStreamChunkType.ReasoningSignature]: { signature: string };
92
+ [DataStreamStreamChunkType.File]: { data: string; mimeType: string };
93
+ };
@@ -0,0 +1,32 @@
1
+ import { DataStreamChunk, DataStreamStreamChunkType } from "./chunk-types";
2
+
3
+ export class DataStreamChunkEncoder extends TransformStream<
4
+ DataStreamChunk,
5
+ string
6
+ > {
7
+ constructor() {
8
+ super({
9
+ transform: (chunk, controller) => {
10
+ controller.enqueue(`${chunk.type}:${JSON.stringify(chunk.value)}\n`);
11
+ },
12
+ });
13
+ }
14
+ }
15
+
16
+ export class DataStreamChunkDecoder extends TransformStream<
17
+ string,
18
+ DataStreamChunk
19
+ > {
20
+ constructor() {
21
+ super({
22
+ transform: (chunk, controller) => {
23
+ const index = chunk.indexOf(":");
24
+ if (index === -1) throw new Error("Invalid stream part");
25
+ controller.enqueue({
26
+ type: chunk.slice(0, index) as DataStreamStreamChunkType,
27
+ value: JSON.parse(chunk.slice(index + 1)),
28
+ });
29
+ },
30
+ });
31
+ }
32
+ }