@bagelink/sdk 1.8.39 → 1.8.41

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.cjs CHANGED
@@ -1162,10 +1162,8 @@ function generateTypes(schemas) {
1162
1162
  class StreamController {
1163
1163
  constructor(cleanup) {
1164
1164
  this.cleanup = cleanup;
1165
- this.controller = new AbortController();
1166
1165
  }
1167
1166
  handlers = /* @__PURE__ */ new Map();
1168
- controller;
1169
1167
  _closed = false;
1170
1168
  /**
1171
1169
  * Register an event handler (fully typed!)
@@ -1180,40 +1178,6 @@ class StreamController {
1180
1178
  this.handlers.get(event).add(handler);
1181
1179
  return this;
1182
1180
  }
1183
- /**
1184
- * Register a one-time event handler (fully typed!)
1185
- * @param event - Event type to listen for
1186
- * @param handler - Handler function (called once then removed)
1187
- * @returns this (for chaining)
1188
- */
1189
- once(event, handler) {
1190
- const wrappedHandler = (data) => {
1191
- handler(data);
1192
- this.off(event, wrappedHandler);
1193
- };
1194
- return this.on(event, wrappedHandler);
1195
- }
1196
- /**
1197
- * Remove an event handler (fully typed!)
1198
- * @param event - Event type
1199
- * @param handler - Handler to remove
1200
- * @returns this (for chaining)
1201
- */
1202
- off(event, handler) {
1203
- this.handlers.get(event)?.delete(handler);
1204
- return this;
1205
- }
1206
- /**
1207
- * Remove all handlers for an event (or all events if no event specified)
1208
- */
1209
- removeAllListeners(event) {
1210
- if (event === void 0) {
1211
- this.handlers.clear();
1212
- } else {
1213
- this.handlers.delete(event);
1214
- }
1215
- return this;
1216
- }
1217
1181
  /**
1218
1182
  * Emit an event to all registered handlers
1219
1183
  * @internal
@@ -1235,17 +1199,10 @@ class StreamController {
1235
1199
  */
1236
1200
  close() {
1237
1201
  if (!this._closed) {
1238
- this.controller.abort();
1239
1202
  this.cleanup();
1240
1203
  this._closed = true;
1241
1204
  }
1242
1205
  }
1243
- /**
1244
- * Check if stream is closed
1245
- */
1246
- get closed() {
1247
- return this._closed;
1248
- }
1249
1206
  }
1250
1207
 
1251
1208
  function createSSEStream(url, options = {}) {
@@ -1276,24 +1233,29 @@ function createSSEStream(url, options = {}) {
1276
1233
  while (true) {
1277
1234
  const { done, value } = await reader.read();
1278
1235
  if (done) {
1236
+ stream.emit("done", {});
1279
1237
  stream.emit("complete", {});
1280
1238
  break;
1281
1239
  }
1282
1240
  buffer += decoder.decode(value, { stream: true });
1283
1241
  const lines = buffer.split("\n");
1284
1242
  buffer = lines.pop() || "";
1285
- let eventData = "";
1243
+ let currentEvent = "message";
1244
+ let currentData = "";
1286
1245
  for (const line of lines) {
1287
- if (line.startsWith("data:")) {
1288
- eventData = line.slice(5).trim();
1289
- } else if (line === "" && eventData) {
1246
+ if (line.startsWith("event:")) {
1247
+ currentEvent = line.slice(6).trim();
1248
+ } else if (line.startsWith("data:")) {
1249
+ currentData = line.slice(5).trim();
1250
+ } else if (line === "" && currentData) {
1290
1251
  try {
1291
- const data = JSON.parse(eventData);
1292
- stream.emit(data.type || "message", data);
1293
- } catch (error) {
1294
- console.error("Failed to parse SSE event:", error);
1252
+ const parsed = JSON.parse(currentData);
1253
+ stream.emit(currentEvent, parsed);
1254
+ } catch {
1255
+ stream.emit(currentEvent, currentData);
1295
1256
  }
1296
- eventData = "";
1257
+ currentEvent = "message";
1258
+ currentData = "";
1297
1259
  }
1298
1260
  }
1299
1261
  }
@@ -1339,24 +1301,29 @@ function createSSEStreamPost(url, body, options = {}) {
1339
1301
  while (true) {
1340
1302
  const { done, value } = await reader.read();
1341
1303
  if (done) {
1304
+ stream.emit("done", {});
1342
1305
  stream.emit("complete", {});
1343
1306
  break;
1344
1307
  }
1345
1308
  buffer += decoder.decode(value, { stream: true });
1346
1309
  const lines = buffer.split("\n");
1347
1310
  buffer = lines.pop() || "";
1348
- let eventData = "";
1311
+ let currentEvent = "message";
1312
+ let currentData = "";
1349
1313
  for (const line of lines) {
1350
- if (line.startsWith("data:")) {
1351
- eventData = line.slice(5).trim();
1352
- } else if (line === "" && eventData) {
1314
+ if (line.startsWith("event:")) {
1315
+ currentEvent = line.slice(6).trim();
1316
+ } else if (line.startsWith("data:")) {
1317
+ currentData = line.slice(5).trim();
1318
+ } else if (line === "" && currentData) {
1353
1319
  try {
1354
- const data = JSON.parse(eventData);
1355
- stream.emit(data.type || "message", data);
1356
- } catch (error) {
1357
- console.error("Failed to parse SSE event:", error);
1320
+ const parsed = JSON.parse(currentData);
1321
+ stream.emit(currentEvent, parsed);
1322
+ } catch {
1323
+ stream.emit(currentEvent, currentData);
1358
1324
  }
1359
- eventData = "";
1325
+ currentEvent = "message";
1326
+ currentData = "";
1360
1327
  }
1361
1328
  }
1362
1329
  }
package/dist/index.d.cts CHANGED
@@ -5,14 +5,6 @@ import { Ref } from 'vue';
5
5
  * StreamController - Simple, reliable SSE stream management
6
6
  * Provides a type-safe API for consuming Server-Sent Events
7
7
  */
8
- interface SSEEvent<T = any> {
9
- /** Event type (e.g., "token", "tool_call", "done") */
10
- type: string;
11
- /** Event data payload */
12
- data: T;
13
- /** Raw event string */
14
- raw?: string;
15
- }
16
8
  type EventHandler<T = any> = (data: T) => void;
17
9
  /**
18
10
  * Type-safe event map for stream events
@@ -33,7 +25,6 @@ type StreamEventMap = Record<string, any>;
33
25
  declare class StreamController<TEventMap extends StreamEventMap = StreamEventMap> {
34
26
  private cleanup;
35
27
  private handlers;
36
- private controller;
37
28
  private _closed;
38
29
  constructor(cleanup: () => void);
39
30
  /**
@@ -42,25 +33,7 @@ declare class StreamController<TEventMap extends StreamEventMap = StreamEventMap
42
33
  * @param handler - Handler function (data type inferred from event)
43
34
  * @returns this (for chaining)
44
35
  */
45
- on<K extends keyof TEventMap | 'error' | 'complete'>(event: K, handler: K extends 'error' ? (error: Error) => void : K extends 'complete' ? () => void : K extends keyof TEventMap ? (data: TEventMap[K]) => void : EventHandler): this;
46
- /**
47
- * Register a one-time event handler (fully typed!)
48
- * @param event - Event type to listen for
49
- * @param handler - Handler function (called once then removed)
50
- * @returns this (for chaining)
51
- */
52
- once<K extends keyof TEventMap | 'error' | 'complete'>(event: K, handler: K extends 'error' ? (error: Error) => void : K extends 'complete' ? () => void : K extends keyof TEventMap ? (data: TEventMap[K]) => void : EventHandler): this;
53
- /**
54
- * Remove an event handler (fully typed!)
55
- * @param event - Event type
56
- * @param handler - Handler to remove
57
- * @returns this (for chaining)
58
- */
59
- off<K extends keyof TEventMap | 'error' | 'complete'>(event: K, handler: K extends 'error' ? (error: Error) => void : K extends 'complete' ? () => void : K extends keyof TEventMap ? (data: TEventMap[K]) => void : EventHandler): this;
60
- /**
61
- * Remove all handlers for an event (or all events if no event specified)
62
- */
63
- removeAllListeners(event?: keyof TEventMap | 'error' | 'complete'): this;
36
+ on<K extends keyof TEventMap | 'error' | 'complete' | 'done'>(event: K, handler: K extends 'error' ? (error: Error) => void : K extends 'complete' | 'done' ? (data?: any) => void : K extends keyof TEventMap ? (data: TEventMap[K]) => void : EventHandler): this;
64
37
  /**
65
38
  * Emit an event to all registered handlers
66
39
  * @internal
@@ -70,10 +43,6 @@ declare class StreamController<TEventMap extends StreamEventMap = StreamEventMap
70
43
  * Close the stream
71
44
  */
72
45
  close(): void;
73
- /**
74
- * Check if stream is closed
75
- */
76
- get closed(): boolean;
77
46
  }
78
47
 
79
48
  /**
@@ -799,4 +768,4 @@ declare class Bagel {
799
768
  }
800
769
 
801
770
  export { ApiResponse, Bagel, StreamController, createSSEStream, createSSEStreamPost, dereference, extractSSEEventInfo, extractSSEEventTypes, formatAPIErrorMessage, formatFieldErrors, getPath, isReferenceObject, isSSEStream, isSchemaObject, _default as openAPI, parseApiError, unwrap, useApiRequest, useCancellableRequest, wrapApiForDirectReturn };
802
- export type { ApiConfig, ApiRequestState, BaseParameterObject, CallbackObject, CallbacksObject, ComponentsObject, ContactObject, ContentObject, DiscriminatorObject, EncodingObject, EncodingPropertyObject, ExampleObject, ExamplesObject, ExternalDocumentationObject, FastAPIErrorResponse, FastAPIValidationError, HeaderObject, HeadersObject, InfoObject, LicenseObject, LinkObject, LinkParametersObject, LinksObject, MediaTypeObject, OAuthFlowObject, OAuthFlowsObject, OpenAPIObject, OperationObject, ParameterLocation, ParameterObject, ParameterStyle, ParsedError, PathItemObject, PathsObject, ReferenceObject, RequestBodyObject, RequestInterceptor, ResponseInterceptor, ResponseMetadata, ResponseObject, ResponsesObject, SSEEvent, SSEEventTypeInfo, SSEStreamOptions, SchemaObject, SchemaObjectType, SchemasObject, ScopesObject, SecurityRequirementObject, SecuritySchemeObject, SecuritySchemeType, ServerObject, ServerVariableObject, StreamEventMap, TableToTypeMapping, Tables, TagObject, TypeFormatT, Unwrap, Unwrapped, UploadOptions, User, XmlObject };
771
+ export type { ApiConfig, ApiRequestState, BaseParameterObject, CallbackObject, CallbacksObject, ComponentsObject, ContactObject, ContentObject, DiscriminatorObject, EncodingObject, EncodingPropertyObject, ExampleObject, ExamplesObject, ExternalDocumentationObject, FastAPIErrorResponse, FastAPIValidationError, HeaderObject, HeadersObject, InfoObject, LicenseObject, LinkObject, LinkParametersObject, LinksObject, MediaTypeObject, OAuthFlowObject, OAuthFlowsObject, OpenAPIObject, OperationObject, ParameterLocation, ParameterObject, ParameterStyle, ParsedError, PathItemObject, PathsObject, ReferenceObject, RequestBodyObject, RequestInterceptor, ResponseInterceptor, ResponseMetadata, ResponseObject, ResponsesObject, SSEEventTypeInfo, SSEStreamOptions, SchemaObject, SchemaObjectType, SchemasObject, ScopesObject, SecurityRequirementObject, SecuritySchemeObject, SecuritySchemeType, ServerObject, ServerVariableObject, StreamEventMap, TableToTypeMapping, Tables, TagObject, TypeFormatT, Unwrap, Unwrapped, UploadOptions, User, XmlObject };
package/dist/index.d.mts CHANGED
@@ -5,14 +5,6 @@ import { Ref } from 'vue';
5
5
  * StreamController - Simple, reliable SSE stream management
6
6
  * Provides a type-safe API for consuming Server-Sent Events
7
7
  */
8
- interface SSEEvent<T = any> {
9
- /** Event type (e.g., "token", "tool_call", "done") */
10
- type: string;
11
- /** Event data payload */
12
- data: T;
13
- /** Raw event string */
14
- raw?: string;
15
- }
16
8
  type EventHandler<T = any> = (data: T) => void;
17
9
  /**
18
10
  * Type-safe event map for stream events
@@ -33,7 +25,6 @@ type StreamEventMap = Record<string, any>;
33
25
  declare class StreamController<TEventMap extends StreamEventMap = StreamEventMap> {
34
26
  private cleanup;
35
27
  private handlers;
36
- private controller;
37
28
  private _closed;
38
29
  constructor(cleanup: () => void);
39
30
  /**
@@ -42,25 +33,7 @@ declare class StreamController<TEventMap extends StreamEventMap = StreamEventMap
42
33
  * @param handler - Handler function (data type inferred from event)
43
34
  * @returns this (for chaining)
44
35
  */
45
- on<K extends keyof TEventMap | 'error' | 'complete'>(event: K, handler: K extends 'error' ? (error: Error) => void : K extends 'complete' ? () => void : K extends keyof TEventMap ? (data: TEventMap[K]) => void : EventHandler): this;
46
- /**
47
- * Register a one-time event handler (fully typed!)
48
- * @param event - Event type to listen for
49
- * @param handler - Handler function (called once then removed)
50
- * @returns this (for chaining)
51
- */
52
- once<K extends keyof TEventMap | 'error' | 'complete'>(event: K, handler: K extends 'error' ? (error: Error) => void : K extends 'complete' ? () => void : K extends keyof TEventMap ? (data: TEventMap[K]) => void : EventHandler): this;
53
- /**
54
- * Remove an event handler (fully typed!)
55
- * @param event - Event type
56
- * @param handler - Handler to remove
57
- * @returns this (for chaining)
58
- */
59
- off<K extends keyof TEventMap | 'error' | 'complete'>(event: K, handler: K extends 'error' ? (error: Error) => void : K extends 'complete' ? () => void : K extends keyof TEventMap ? (data: TEventMap[K]) => void : EventHandler): this;
60
- /**
61
- * Remove all handlers for an event (or all events if no event specified)
62
- */
63
- removeAllListeners(event?: keyof TEventMap | 'error' | 'complete'): this;
36
+ on<K extends keyof TEventMap | 'error' | 'complete' | 'done'>(event: K, handler: K extends 'error' ? (error: Error) => void : K extends 'complete' | 'done' ? (data?: any) => void : K extends keyof TEventMap ? (data: TEventMap[K]) => void : EventHandler): this;
64
37
  /**
65
38
  * Emit an event to all registered handlers
66
39
  * @internal
@@ -70,10 +43,6 @@ declare class StreamController<TEventMap extends StreamEventMap = StreamEventMap
70
43
  * Close the stream
71
44
  */
72
45
  close(): void;
73
- /**
74
- * Check if stream is closed
75
- */
76
- get closed(): boolean;
77
46
  }
78
47
 
79
48
  /**
@@ -799,4 +768,4 @@ declare class Bagel {
799
768
  }
800
769
 
801
770
  export { ApiResponse, Bagel, StreamController, createSSEStream, createSSEStreamPost, dereference, extractSSEEventInfo, extractSSEEventTypes, formatAPIErrorMessage, formatFieldErrors, getPath, isReferenceObject, isSSEStream, isSchemaObject, _default as openAPI, parseApiError, unwrap, useApiRequest, useCancellableRequest, wrapApiForDirectReturn };
802
- export type { ApiConfig, ApiRequestState, BaseParameterObject, CallbackObject, CallbacksObject, ComponentsObject, ContactObject, ContentObject, DiscriminatorObject, EncodingObject, EncodingPropertyObject, ExampleObject, ExamplesObject, ExternalDocumentationObject, FastAPIErrorResponse, FastAPIValidationError, HeaderObject, HeadersObject, InfoObject, LicenseObject, LinkObject, LinkParametersObject, LinksObject, MediaTypeObject, OAuthFlowObject, OAuthFlowsObject, OpenAPIObject, OperationObject, ParameterLocation, ParameterObject, ParameterStyle, ParsedError, PathItemObject, PathsObject, ReferenceObject, RequestBodyObject, RequestInterceptor, ResponseInterceptor, ResponseMetadata, ResponseObject, ResponsesObject, SSEEvent, SSEEventTypeInfo, SSEStreamOptions, SchemaObject, SchemaObjectType, SchemasObject, ScopesObject, SecurityRequirementObject, SecuritySchemeObject, SecuritySchemeType, ServerObject, ServerVariableObject, StreamEventMap, TableToTypeMapping, Tables, TagObject, TypeFormatT, Unwrap, Unwrapped, UploadOptions, User, XmlObject };
771
+ export type { ApiConfig, ApiRequestState, BaseParameterObject, CallbackObject, CallbacksObject, ComponentsObject, ContactObject, ContentObject, DiscriminatorObject, EncodingObject, EncodingPropertyObject, ExampleObject, ExamplesObject, ExternalDocumentationObject, FastAPIErrorResponse, FastAPIValidationError, HeaderObject, HeadersObject, InfoObject, LicenseObject, LinkObject, LinkParametersObject, LinksObject, MediaTypeObject, OAuthFlowObject, OAuthFlowsObject, OpenAPIObject, OperationObject, ParameterLocation, ParameterObject, ParameterStyle, ParsedError, PathItemObject, PathsObject, ReferenceObject, RequestBodyObject, RequestInterceptor, ResponseInterceptor, ResponseMetadata, ResponseObject, ResponsesObject, SSEEventTypeInfo, SSEStreamOptions, SchemaObject, SchemaObjectType, SchemasObject, ScopesObject, SecurityRequirementObject, SecuritySchemeObject, SecuritySchemeType, ServerObject, ServerVariableObject, StreamEventMap, TableToTypeMapping, Tables, TagObject, TypeFormatT, Unwrap, Unwrapped, UploadOptions, User, XmlObject };
package/dist/index.d.ts CHANGED
@@ -5,14 +5,6 @@ import { Ref } from 'vue';
5
5
  * StreamController - Simple, reliable SSE stream management
6
6
  * Provides a type-safe API for consuming Server-Sent Events
7
7
  */
8
- interface SSEEvent<T = any> {
9
- /** Event type (e.g., "token", "tool_call", "done") */
10
- type: string;
11
- /** Event data payload */
12
- data: T;
13
- /** Raw event string */
14
- raw?: string;
15
- }
16
8
  type EventHandler<T = any> = (data: T) => void;
17
9
  /**
18
10
  * Type-safe event map for stream events
@@ -33,7 +25,6 @@ type StreamEventMap = Record<string, any>;
33
25
  declare class StreamController<TEventMap extends StreamEventMap = StreamEventMap> {
34
26
  private cleanup;
35
27
  private handlers;
36
- private controller;
37
28
  private _closed;
38
29
  constructor(cleanup: () => void);
39
30
  /**
@@ -42,25 +33,7 @@ declare class StreamController<TEventMap extends StreamEventMap = StreamEventMap
42
33
  * @param handler - Handler function (data type inferred from event)
43
34
  * @returns this (for chaining)
44
35
  */
45
- on<K extends keyof TEventMap | 'error' | 'complete'>(event: K, handler: K extends 'error' ? (error: Error) => void : K extends 'complete' ? () => void : K extends keyof TEventMap ? (data: TEventMap[K]) => void : EventHandler): this;
46
- /**
47
- * Register a one-time event handler (fully typed!)
48
- * @param event - Event type to listen for
49
- * @param handler - Handler function (called once then removed)
50
- * @returns this (for chaining)
51
- */
52
- once<K extends keyof TEventMap | 'error' | 'complete'>(event: K, handler: K extends 'error' ? (error: Error) => void : K extends 'complete' ? () => void : K extends keyof TEventMap ? (data: TEventMap[K]) => void : EventHandler): this;
53
- /**
54
- * Remove an event handler (fully typed!)
55
- * @param event - Event type
56
- * @param handler - Handler to remove
57
- * @returns this (for chaining)
58
- */
59
- off<K extends keyof TEventMap | 'error' | 'complete'>(event: K, handler: K extends 'error' ? (error: Error) => void : K extends 'complete' ? () => void : K extends keyof TEventMap ? (data: TEventMap[K]) => void : EventHandler): this;
60
- /**
61
- * Remove all handlers for an event (or all events if no event specified)
62
- */
63
- removeAllListeners(event?: keyof TEventMap | 'error' | 'complete'): this;
36
+ on<K extends keyof TEventMap | 'error' | 'complete' | 'done'>(event: K, handler: K extends 'error' ? (error: Error) => void : K extends 'complete' | 'done' ? (data?: any) => void : K extends keyof TEventMap ? (data: TEventMap[K]) => void : EventHandler): this;
64
37
  /**
65
38
  * Emit an event to all registered handlers
66
39
  * @internal
@@ -70,10 +43,6 @@ declare class StreamController<TEventMap extends StreamEventMap = StreamEventMap
70
43
  * Close the stream
71
44
  */
72
45
  close(): void;
73
- /**
74
- * Check if stream is closed
75
- */
76
- get closed(): boolean;
77
46
  }
78
47
 
79
48
  /**
@@ -799,4 +768,4 @@ declare class Bagel {
799
768
  }
800
769
 
801
770
  export { ApiResponse, Bagel, StreamController, createSSEStream, createSSEStreamPost, dereference, extractSSEEventInfo, extractSSEEventTypes, formatAPIErrorMessage, formatFieldErrors, getPath, isReferenceObject, isSSEStream, isSchemaObject, _default as openAPI, parseApiError, unwrap, useApiRequest, useCancellableRequest, wrapApiForDirectReturn };
802
- export type { ApiConfig, ApiRequestState, BaseParameterObject, CallbackObject, CallbacksObject, ComponentsObject, ContactObject, ContentObject, DiscriminatorObject, EncodingObject, EncodingPropertyObject, ExampleObject, ExamplesObject, ExternalDocumentationObject, FastAPIErrorResponse, FastAPIValidationError, HeaderObject, HeadersObject, InfoObject, LicenseObject, LinkObject, LinkParametersObject, LinksObject, MediaTypeObject, OAuthFlowObject, OAuthFlowsObject, OpenAPIObject, OperationObject, ParameterLocation, ParameterObject, ParameterStyle, ParsedError, PathItemObject, PathsObject, ReferenceObject, RequestBodyObject, RequestInterceptor, ResponseInterceptor, ResponseMetadata, ResponseObject, ResponsesObject, SSEEvent, SSEEventTypeInfo, SSEStreamOptions, SchemaObject, SchemaObjectType, SchemasObject, ScopesObject, SecurityRequirementObject, SecuritySchemeObject, SecuritySchemeType, ServerObject, ServerVariableObject, StreamEventMap, TableToTypeMapping, Tables, TagObject, TypeFormatT, Unwrap, Unwrapped, UploadOptions, User, XmlObject };
771
+ export type { ApiConfig, ApiRequestState, BaseParameterObject, CallbackObject, CallbacksObject, ComponentsObject, ContactObject, ContentObject, DiscriminatorObject, EncodingObject, EncodingPropertyObject, ExampleObject, ExamplesObject, ExternalDocumentationObject, FastAPIErrorResponse, FastAPIValidationError, HeaderObject, HeadersObject, InfoObject, LicenseObject, LinkObject, LinkParametersObject, LinksObject, MediaTypeObject, OAuthFlowObject, OAuthFlowsObject, OpenAPIObject, OperationObject, ParameterLocation, ParameterObject, ParameterStyle, ParsedError, PathItemObject, PathsObject, ReferenceObject, RequestBodyObject, RequestInterceptor, ResponseInterceptor, ResponseMetadata, ResponseObject, ResponsesObject, SSEEventTypeInfo, SSEStreamOptions, SchemaObject, SchemaObjectType, SchemasObject, ScopesObject, SecurityRequirementObject, SecuritySchemeObject, SecuritySchemeType, ServerObject, ServerVariableObject, StreamEventMap, TableToTypeMapping, Tables, TagObject, TypeFormatT, Unwrap, Unwrapped, UploadOptions, User, XmlObject };
package/dist/index.mjs CHANGED
@@ -1156,10 +1156,8 @@ function generateTypes(schemas) {
1156
1156
  class StreamController {
1157
1157
  constructor(cleanup) {
1158
1158
  this.cleanup = cleanup;
1159
- this.controller = new AbortController();
1160
1159
  }
1161
1160
  handlers = /* @__PURE__ */ new Map();
1162
- controller;
1163
1161
  _closed = false;
1164
1162
  /**
1165
1163
  * Register an event handler (fully typed!)
@@ -1174,40 +1172,6 @@ class StreamController {
1174
1172
  this.handlers.get(event).add(handler);
1175
1173
  return this;
1176
1174
  }
1177
- /**
1178
- * Register a one-time event handler (fully typed!)
1179
- * @param event - Event type to listen for
1180
- * @param handler - Handler function (called once then removed)
1181
- * @returns this (for chaining)
1182
- */
1183
- once(event, handler) {
1184
- const wrappedHandler = (data) => {
1185
- handler(data);
1186
- this.off(event, wrappedHandler);
1187
- };
1188
- return this.on(event, wrappedHandler);
1189
- }
1190
- /**
1191
- * Remove an event handler (fully typed!)
1192
- * @param event - Event type
1193
- * @param handler - Handler to remove
1194
- * @returns this (for chaining)
1195
- */
1196
- off(event, handler) {
1197
- this.handlers.get(event)?.delete(handler);
1198
- return this;
1199
- }
1200
- /**
1201
- * Remove all handlers for an event (or all events if no event specified)
1202
- */
1203
- removeAllListeners(event) {
1204
- if (event === void 0) {
1205
- this.handlers.clear();
1206
- } else {
1207
- this.handlers.delete(event);
1208
- }
1209
- return this;
1210
- }
1211
1175
  /**
1212
1176
  * Emit an event to all registered handlers
1213
1177
  * @internal
@@ -1229,17 +1193,10 @@ class StreamController {
1229
1193
  */
1230
1194
  close() {
1231
1195
  if (!this._closed) {
1232
- this.controller.abort();
1233
1196
  this.cleanup();
1234
1197
  this._closed = true;
1235
1198
  }
1236
1199
  }
1237
- /**
1238
- * Check if stream is closed
1239
- */
1240
- get closed() {
1241
- return this._closed;
1242
- }
1243
1200
  }
1244
1201
 
1245
1202
  function createSSEStream(url, options = {}) {
@@ -1270,24 +1227,29 @@ function createSSEStream(url, options = {}) {
1270
1227
  while (true) {
1271
1228
  const { done, value } = await reader.read();
1272
1229
  if (done) {
1230
+ stream.emit("done", {});
1273
1231
  stream.emit("complete", {});
1274
1232
  break;
1275
1233
  }
1276
1234
  buffer += decoder.decode(value, { stream: true });
1277
1235
  const lines = buffer.split("\n");
1278
1236
  buffer = lines.pop() || "";
1279
- let eventData = "";
1237
+ let currentEvent = "message";
1238
+ let currentData = "";
1280
1239
  for (const line of lines) {
1281
- if (line.startsWith("data:")) {
1282
- eventData = line.slice(5).trim();
1283
- } else if (line === "" && eventData) {
1240
+ if (line.startsWith("event:")) {
1241
+ currentEvent = line.slice(6).trim();
1242
+ } else if (line.startsWith("data:")) {
1243
+ currentData = line.slice(5).trim();
1244
+ } else if (line === "" && currentData) {
1284
1245
  try {
1285
- const data = JSON.parse(eventData);
1286
- stream.emit(data.type || "message", data);
1287
- } catch (error) {
1288
- console.error("Failed to parse SSE event:", error);
1246
+ const parsed = JSON.parse(currentData);
1247
+ stream.emit(currentEvent, parsed);
1248
+ } catch {
1249
+ stream.emit(currentEvent, currentData);
1289
1250
  }
1290
- eventData = "";
1251
+ currentEvent = "message";
1252
+ currentData = "";
1291
1253
  }
1292
1254
  }
1293
1255
  }
@@ -1333,24 +1295,29 @@ function createSSEStreamPost(url, body, options = {}) {
1333
1295
  while (true) {
1334
1296
  const { done, value } = await reader.read();
1335
1297
  if (done) {
1298
+ stream.emit("done", {});
1336
1299
  stream.emit("complete", {});
1337
1300
  break;
1338
1301
  }
1339
1302
  buffer += decoder.decode(value, { stream: true });
1340
1303
  const lines = buffer.split("\n");
1341
1304
  buffer = lines.pop() || "";
1342
- let eventData = "";
1305
+ let currentEvent = "message";
1306
+ let currentData = "";
1343
1307
  for (const line of lines) {
1344
- if (line.startsWith("data:")) {
1345
- eventData = line.slice(5).trim();
1346
- } else if (line === "" && eventData) {
1308
+ if (line.startsWith("event:")) {
1309
+ currentEvent = line.slice(6).trim();
1310
+ } else if (line.startsWith("data:")) {
1311
+ currentData = line.slice(5).trim();
1312
+ } else if (line === "" && currentData) {
1347
1313
  try {
1348
- const data = JSON.parse(eventData);
1349
- stream.emit(data.type || "message", data);
1350
- } catch (error) {
1351
- console.error("Failed to parse SSE event:", error);
1314
+ const parsed = JSON.parse(currentData);
1315
+ stream.emit(currentEvent, parsed);
1316
+ } catch {
1317
+ stream.emit(currentEvent, currentData);
1352
1318
  }
1353
- eventData = "";
1319
+ currentEvent = "message";
1320
+ currentData = "";
1354
1321
  }
1355
1322
  }
1356
1323
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bagelink/sdk",
3
3
  "type": "module",
4
- "version": "1.8.39",
4
+ "version": "1.8.41",
5
5
  "description": "Bagel core sdk packages",
6
6
  "author": {
7
7
  "name": "Bagel Studio",
package/src/index.ts CHANGED
@@ -8,7 +8,6 @@ export { default as openAPI } from './openAPITools'
8
8
  export {
9
9
  createSSEStream,
10
10
  createSSEStreamPost,
11
- type SSEEvent,
12
11
  type SSEStreamOptions,
13
12
  StreamController,
14
13
  type StreamEventMap
@@ -4,15 +4,6 @@
4
4
  * Provides a type-safe API for consuming Server-Sent Events
5
5
  */
6
6
 
7
- export interface SSEEvent<T = any> {
8
- /** Event type (e.g., "token", "tool_call", "done") */
9
- type: string
10
- /** Event data payload */
11
- data: T
12
- /** Raw event string */
13
- raw?: string
14
- }
15
-
16
7
  type EventHandler<T = any> = (data: T) => void
17
8
 
18
9
  /**
@@ -34,12 +25,9 @@ export type StreamEventMap = Record<string, any>
34
25
  */
35
26
  export class StreamController<TEventMap extends StreamEventMap = StreamEventMap> {
36
27
  private handlers = new Map<string, Set<EventHandler>>()
37
- private controller: AbortController
38
28
  private _closed = false
39
29
 
40
- constructor(private cleanup: () => void) {
41
- this.controller = new AbortController()
42
- }
30
+ constructor(private cleanup: () => void) {}
43
31
 
44
32
  /**
45
33
  * Register an event handler (fully typed!)
@@ -47,12 +35,12 @@ export class StreamController<TEventMap extends StreamEventMap = StreamEventMap>
47
35
  * @param handler - Handler function (data type inferred from event)
48
36
  * @returns this (for chaining)
49
37
  */
50
- on<K extends keyof TEventMap | 'error' | 'complete'>(
38
+ on<K extends keyof TEventMap | 'error' | 'complete' | 'done'>(
51
39
  event: K,
52
40
  handler: K extends 'error'
53
41
  ? (error: Error) => void
54
- : K extends 'complete'
55
- ? () => void
42
+ : K extends 'complete' | 'done'
43
+ ? (data?: any) => void
56
44
  : K extends keyof TEventMap
57
45
  ? (data: TEventMap[K]) => void
58
46
  : EventHandler
@@ -64,61 +52,6 @@ export class StreamController<TEventMap extends StreamEventMap = StreamEventMap>
64
52
  return this
65
53
  }
66
54
 
67
- /**
68
- * Register a one-time event handler (fully typed!)
69
- * @param event - Event type to listen for
70
- * @param handler - Handler function (called once then removed)
71
- * @returns this (for chaining)
72
- */
73
- once<K extends keyof TEventMap | 'error' | 'complete'>(
74
- event: K,
75
- handler: K extends 'error'
76
- ? (error: Error) => void
77
- : K extends 'complete'
78
- ? () => void
79
- : K extends keyof TEventMap
80
- ? (data: TEventMap[K]) => void
81
- : EventHandler
82
- ): this {
83
- const wrappedHandler = (data: any) => {
84
- (handler as any)(data)
85
- this.off(event, wrappedHandler as any)
86
- }
87
- return this.on(event, wrappedHandler as any)
88
- }
89
-
90
- /**
91
- * Remove an event handler (fully typed!)
92
- * @param event - Event type
93
- * @param handler - Handler to remove
94
- * @returns this (for chaining)
95
- */
96
- off<K extends keyof TEventMap | 'error' | 'complete'>(
97
- event: K,
98
- handler: K extends 'error'
99
- ? (error: Error) => void
100
- : K extends 'complete'
101
- ? () => void
102
- : K extends keyof TEventMap
103
- ? (data: TEventMap[K]) => void
104
- : EventHandler
105
- ): this {
106
- this.handlers.get(event as string)?.delete(handler as EventHandler)
107
- return this
108
- }
109
-
110
- /**
111
- * Remove all handlers for an event (or all events if no event specified)
112
- */
113
- removeAllListeners(event?: keyof TEventMap | 'error' | 'complete'): this {
114
- if (event === undefined) {
115
- this.handlers.clear()
116
- } else {
117
- this.handlers.delete(event as string)
118
- }
119
- return this
120
- }
121
-
122
55
  /**
123
56
  * Emit an event to all registered handlers
124
57
  * @internal
@@ -141,16 +74,8 @@ export class StreamController<TEventMap extends StreamEventMap = StreamEventMap>
141
74
  */
142
75
  close(): void {
143
76
  if (!this._closed) {
144
- this.controller.abort()
145
77
  this.cleanup()
146
78
  this._closed = true
147
79
  }
148
80
  }
149
-
150
- /**
151
- * Check if stream is closed
152
- */
153
- get closed(): boolean {
154
- return this._closed
155
- }
156
81
  }
@@ -10,7 +10,7 @@
10
10
  import type { StreamEventMap } from './StreamController'
11
11
  import { StreamController } from './StreamController'
12
12
 
13
- export { type SSEEvent, StreamController, type StreamEventMap } from './StreamController'
13
+ export { StreamController, type StreamEventMap } from './StreamController'
14
14
 
15
15
  export interface SSEStreamOptions {
16
16
  /** Additional headers to send with the request */
@@ -73,6 +73,7 @@ export function createSSEStream<TEventMap extends StreamEventMap = StreamEventMa
73
73
  const { done, value } = await reader.read()
74
74
 
75
75
  if (done) {
76
+ stream.emit('done', {})
76
77
  stream.emit('complete', {})
77
78
  break
78
79
  }
@@ -84,21 +85,26 @@ export function createSSEStream<TEventMap extends StreamEventMap = StreamEventMa
84
85
  const lines = buffer.split('\n')
85
86
  buffer = lines.pop() || '' // Keep incomplete line in buffer
86
87
 
87
- let eventData = ''
88
+ let currentEvent = 'message'
89
+ let currentData = ''
88
90
 
89
91
  for (const line of lines) {
90
- if (line.startsWith('data:')) {
91
- eventData = line.slice(5).trim()
92
- } else if (line === '' && eventData) {
92
+ if (line.startsWith('event:')) {
93
+ currentEvent = line.slice(6).trim()
94
+ } else if (line.startsWith('data:')) {
95
+ currentData = line.slice(5).trim()
96
+ } else if (line === '' && currentData) {
93
97
  // Empty line indicates end of event - emit immediately
94
98
  try {
95
- const data = JSON.parse(eventData)
96
- // Emit using data.type for the event name
97
- stream.emit(data.type || 'message', data)
98
- } catch (error) {
99
- console.error('Failed to parse SSE event:', error)
99
+ const parsed = JSON.parse(currentData)
100
+ stream.emit(currentEvent, parsed)
101
+ } catch {
102
+ // If not valid JSON, emit as string
103
+ stream.emit(currentEvent, currentData)
100
104
  }
101
- eventData = ''
105
+ // Reset for next event
106
+ currentEvent = 'message'
107
+ currentData = ''
102
108
  }
103
109
  }
104
110
  }
@@ -172,6 +178,7 @@ export function createSSEStreamPost<TEventMap extends StreamEventMap = StreamEve
172
178
  const { done, value } = await reader.read()
173
179
 
174
180
  if (done) {
181
+ stream.emit('done', {})
175
182
  stream.emit('complete', {})
176
183
  break
177
184
  }
@@ -183,21 +190,26 @@ export function createSSEStreamPost<TEventMap extends StreamEventMap = StreamEve
183
190
  const lines = buffer.split('\n')
184
191
  buffer = lines.pop() || '' // Keep incomplete line in buffer
185
192
 
186
- let eventData = ''
193
+ let currentEvent = 'message'
194
+ let currentData = ''
187
195
 
188
196
  for (const line of lines) {
189
- if (line.startsWith('data:')) {
190
- eventData = line.slice(5).trim()
191
- } else if (line === '' && eventData) {
197
+ if (line.startsWith('event:')) {
198
+ currentEvent = line.slice(6).trim()
199
+ } else if (line.startsWith('data:')) {
200
+ currentData = line.slice(5).trim()
201
+ } else if (line === '' && currentData) {
192
202
  // Empty line indicates end of event - emit immediately
193
203
  try {
194
- const data = JSON.parse(eventData)
195
- // Emit using data.type for the event name
196
- stream.emit(data.type || 'message', data)
197
- } catch (error) {
198
- console.error('Failed to parse SSE event:', error)
204
+ const parsed = JSON.parse(currentData)
205
+ stream.emit(currentEvent, parsed)
206
+ } catch {
207
+ // If not valid JSON, emit as string
208
+ stream.emit(currentEvent, currentData)
199
209
  }
200
- eventData = ''
210
+ // Reset for next event
211
+ currentEvent = 'message'
212
+ currentData = ''
201
213
  }
202
214
  }
203
215
  }