@aviaryhq/cloudglue-js 0.6.1 → 0.6.2

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.
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EnhancedResponseApi = void 0;
4
- const string_decoder_1 = require("string_decoder");
5
4
  const error_1 = require("../error");
6
5
  /**
7
6
  * Process buffered lines, yielding parsed SSE events.
@@ -32,29 +31,39 @@ function* processLines(buffer) {
32
31
  }
33
32
  }
34
33
  /**
35
- * Parse an SSE stream from an IncomingMessage into an async iterable of typed events.
36
- * Uses StringDecoder to correctly handle multi-byte UTF-8 characters split across chunks.
34
+ * Parse an SSE stream into an async iterable of typed events.
35
+ * Uses the web-standard ReadableStream and TextDecoder APIs for cross-environment compatibility
36
+ * (works in both Node.js 18+ and modern browsers).
37
37
  */
38
38
  async function* parseSSEStream(stream) {
39
- const decoder = new string_decoder_1.StringDecoder('utf-8');
39
+ const decoder = new TextDecoder('utf-8');
40
40
  const buffer = { value: '' };
41
- for await (const chunk of stream) {
42
- buffer.value += typeof chunk === 'string' ? chunk : decoder.write(chunk);
43
- for (const event of processLines(buffer)) {
44
- if (event === 'DONE')
45
- return;
46
- yield event;
41
+ const reader = stream.getReader();
42
+ try {
43
+ while (true) {
44
+ const { done, value } = await reader.read();
45
+ if (done)
46
+ break;
47
+ buffer.value += decoder.decode(value, { stream: true });
48
+ for (const event of processLines(buffer)) {
49
+ if (event === 'DONE')
50
+ return;
51
+ yield event;
52
+ }
47
53
  }
48
- }
49
- // Flush any remaining bytes from the decoder and process trailing lines
50
- buffer.value += decoder.end();
51
- if (buffer.value) {
52
- for (const event of processLines(buffer)) {
53
- if (event === 'DONE')
54
- return;
55
- yield event;
54
+ // Flush any remaining bytes from the decoder and process trailing lines
55
+ buffer.value += decoder.decode();
56
+ if (buffer.value) {
57
+ for (const event of processLines(buffer)) {
58
+ if (event === 'DONE')
59
+ return;
60
+ yield event;
61
+ }
56
62
  }
57
63
  }
64
+ finally {
65
+ reader.releaseLock();
66
+ }
58
67
  }
59
68
  class EnhancedResponseApi {
60
69
  constructor(api) {
@@ -83,16 +92,42 @@ class EnhancedResponseApi {
83
92
  stream: true,
84
93
  background: false,
85
94
  };
86
- const response = await this.api.axios({
87
- method: 'post',
88
- url: '/responses',
89
- data: body,
95
+ const baseURL = this.api.axios.defaults.baseURL;
96
+ const url = `${baseURL}/responses`;
97
+ // Headers are set at the top level of defaults.headers by Object.assign in client.ts
98
+ const h = this.api.axios.defaults.headers;
99
+ const response = await fetch(url, {
100
+ method: 'POST',
90
101
  headers: {
102
+ 'Content-Type': 'application/json',
91
103
  Accept: 'text/event-stream',
104
+ Authorization: h['Authorization'],
105
+ 'x-sdk-client': h['x-sdk-client'],
106
+ 'x-sdk-version': h['x-sdk-version'],
92
107
  },
93
- responseType: 'stream',
108
+ body: JSON.stringify(body),
94
109
  });
95
- return parseSSEStream(response.data);
110
+ if (!response.ok) {
111
+ let errorMessage = `Request failed with status ${response.status}`;
112
+ let responseData;
113
+ try {
114
+ responseData = await response.json();
115
+ if (typeof responseData?.error === 'string') {
116
+ errorMessage = responseData.error;
117
+ }
118
+ else if (responseData?.error?.message) {
119
+ errorMessage = responseData.error.message;
120
+ }
121
+ }
122
+ catch {
123
+ // Could not parse error body
124
+ }
125
+ throw new error_1.CloudGlueError(errorMessage, response.status, JSON.stringify(body), Object.fromEntries(response.headers.entries()), responseData);
126
+ }
127
+ if (!response.body) {
128
+ throw new error_1.CloudGlueError('Response body is empty — streaming not supported in this environment');
129
+ }
130
+ return parseSSEStream(response.body);
96
131
  }
97
132
  /**
98
133
  * List all responses with pagination and filtering options.
@@ -50,7 +50,7 @@ class CloudGlue {
50
50
  headers: {
51
51
  Authorization: `Bearer ${this.apiKey}`,
52
52
  'x-sdk-client': 'cloudglue-js',
53
- 'x-sdk-version': '0.6.1',
53
+ 'x-sdk-version': '0.6.2',
54
54
  },
55
55
  baseURL: this.baseUrl,
56
56
  timeout: this.timeout,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aviaryhq/cloudglue-js",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "description": "Cloudglue API client for Node.js",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",