@depup/openai 7.34.0-depup.0 → 7.35.0-depup.0
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/CHANGELOG.md +28 -0
- package/README.md +2 -2
- package/changes.json +1 -1
- package/client.d.mts +2 -2
- package/client.d.mts.map +1 -1
- package/client.d.ts +2 -2
- package/client.d.ts.map +1 -1
- package/client.js.map +1 -1
- package/client.mjs.map +1 -1
- package/internal/responses-ws-credentials.d.mts +4 -21
- package/internal/responses-ws-credentials.d.mts.map +1 -1
- package/internal/responses-ws-credentials.d.ts +4 -21
- package/internal/responses-ws-credentials.d.ts.map +1 -1
- package/internal/responses-ws-credentials.js +4 -100
- package/internal/responses-ws-credentials.js.map +1 -1
- package/internal/responses-ws-credentials.mjs +4 -100
- package/internal/responses-ws-credentials.mjs.map +1 -1
- package/internal/ws-connection-controller.d.mts +95 -0
- package/internal/ws-connection-controller.d.mts.map +1 -0
- package/internal/ws-connection-controller.d.ts +95 -0
- package/internal/ws-connection-controller.d.ts.map +1 -0
- package/internal/ws-connection-controller.js +457 -0
- package/internal/ws-connection-controller.js.map +1 -0
- package/internal/ws-connection-controller.mjs +453 -0
- package/internal/ws-connection-controller.mjs.map +1 -0
- package/internal/ws-connection.d.mts +18 -0
- package/internal/ws-connection.d.mts.map +1 -0
- package/internal/ws-connection.d.ts +18 -0
- package/internal/ws-connection.d.ts.map +1 -0
- package/internal/ws-connection.js +94 -0
- package/internal/ws-connection.js.map +1 -0
- package/internal/ws-connection.mjs +88 -0
- package/internal/ws-connection.mjs.map +1 -0
- package/internal/ws-credentials.d.mts +25 -0
- package/internal/ws-credentials.d.mts.map +1 -0
- package/internal/ws-credentials.d.ts +25 -0
- package/internal/ws-credentials.d.ts.map +1 -0
- package/internal/ws-credentials.js +109 -0
- package/internal/ws-credentials.js.map +1 -0
- package/internal/ws-credentials.mjs +105 -0
- package/internal/ws-credentials.mjs.map +1 -0
- package/lib/live/webrtc.d.mts +5 -1
- package/lib/live/webrtc.d.mts.map +1 -1
- package/lib/live/webrtc.d.ts +5 -1
- package/lib/live/webrtc.d.ts.map +1 -1
- package/lib/live/webrtc.js.map +1 -1
- package/lib/live/webrtc.mjs.map +1 -1
- package/package.json +3 -3
- package/resources/admin/organization/projects/api-keys.d.mts +28 -5
- package/resources/admin/organization/projects/api-keys.d.mts.map +1 -1
- package/resources/admin/organization/projects/api-keys.d.ts +28 -5
- package/resources/admin/organization/projects/api-keys.d.ts.map +1 -1
- package/resources/admin/organization/projects/api-keys.js +18 -3
- package/resources/admin/organization/projects/api-keys.js.map +1 -1
- package/resources/admin/organization/projects/api-keys.mjs +18 -3
- package/resources/admin/organization/projects/api-keys.mjs.map +1 -1
- package/resources/audio/speech.d.mts +2 -1
- package/resources/audio/speech.d.mts.map +1 -1
- package/resources/audio/speech.d.ts +2 -1
- package/resources/audio/speech.d.ts.map +1 -1
- package/resources/audio/voices.d.mts +47 -12
- package/resources/audio/voices.d.mts.map +1 -1
- package/resources/audio/voices.d.ts +47 -12
- package/resources/audio/voices.d.ts.map +1 -1
- package/resources/audio/voices.js +9 -9
- package/resources/audio/voices.mjs +9 -9
- package/resources/beta/realtime/realtime.d.mts +4 -0
- package/resources/beta/realtime/realtime.d.mts.map +1 -1
- package/resources/beta/realtime/realtime.d.ts +4 -0
- package/resources/beta/realtime/realtime.d.ts.map +1 -1
- package/resources/beta/realtime/realtime.js.map +1 -1
- package/resources/beta/realtime/realtime.mjs.map +1 -1
- package/resources/beta/responses/responses.d.mts +8 -0
- package/resources/beta/responses/responses.d.mts.map +1 -1
- package/resources/beta/responses/responses.d.ts +8 -0
- package/resources/beta/responses/responses.d.ts.map +1 -1
- package/resources/beta/responses/responses.js.map +1 -1
- package/resources/beta/responses/responses.mjs.map +1 -1
- package/resources/beta/responses/ws-base.d.mts +2 -24
- package/resources/beta/responses/ws-base.d.mts.map +1 -1
- package/resources/beta/responses/ws-base.d.ts +2 -24
- package/resources/beta/responses/ws-base.d.ts.map +1 -1
- package/resources/beta/responses/ws-base.js +93 -519
- package/resources/beta/responses/ws-base.js.map +1 -1
- package/resources/beta/responses/ws-base.mjs +94 -520
- package/resources/beta/responses/ws-base.mjs.map +1 -1
- package/resources/chat/completions/completions.d.mts +1 -1
- package/resources/chat/completions/completions.d.ts +1 -1
- package/resources/decisions.d.mts +68 -1
- package/resources/decisions.d.mts.map +1 -1
- package/resources/decisions.d.ts +68 -1
- package/resources/decisions.d.ts.map +1 -1
- package/resources/index.d.mts +1 -1
- package/resources/index.d.mts.map +1 -1
- package/resources/index.d.ts +1 -1
- package/resources/index.d.ts.map +1 -1
- package/resources/index.js.map +1 -1
- package/resources/index.mjs.map +1 -1
- package/resources/live/forks/forks.d.mts +2 -2
- package/resources/live/forks/forks.d.mts.map +1 -1
- package/resources/live/forks/forks.d.ts +2 -2
- package/resources/live/forks/forks.d.ts.map +1 -1
- package/resources/live/forks/ws-base.d.mts +2 -23
- package/resources/live/forks/ws-base.d.mts.map +1 -1
- package/resources/live/forks/ws-base.d.ts +2 -23
- package/resources/live/forks/ws-base.d.ts.map +1 -1
- package/resources/live/forks/ws-base.js +84 -485
- package/resources/live/forks/ws-base.js.map +1 -1
- package/resources/live/forks/ws-base.mjs +83 -484
- package/resources/live/forks/ws-base.mjs.map +1 -1
- package/resources/live/live.d.mts +523 -29
- package/resources/live/live.d.mts.map +1 -1
- package/resources/live/live.d.ts +523 -29
- package/resources/live/live.d.ts.map +1 -1
- package/resources/live/live.js.map +1 -1
- package/resources/live/live.mjs.map +1 -1
- package/resources/live/sessions.d.mts +16 -4
- package/resources/live/sessions.d.mts.map +1 -1
- package/resources/live/sessions.d.ts +16 -4
- package/resources/live/sessions.d.ts.map +1 -1
- package/resources/live/sideband/sideband.d.mts +4 -4
- package/resources/live/sideband/sideband.d.mts.map +1 -1
- package/resources/live/sideband/sideband.d.ts +4 -4
- package/resources/live/sideband/sideband.d.ts.map +1 -1
- package/resources/live/sideband/ws-base.d.mts +2 -23
- package/resources/live/sideband/ws-base.d.mts.map +1 -1
- package/resources/live/sideband/ws-base.d.ts +2 -23
- package/resources/live/sideband/ws-base.d.ts.map +1 -1
- package/resources/live/sideband/ws-base.js +84 -485
- package/resources/live/sideband/ws-base.js.map +1 -1
- package/resources/live/sideband/ws-base.mjs +83 -484
- package/resources/live/sideband/ws-base.mjs.map +1 -1
- package/resources/live/ws-base.d.mts +2 -23
- package/resources/live/ws-base.d.mts.map +1 -1
- package/resources/live/ws-base.d.ts +2 -23
- package/resources/live/ws-base.d.ts.map +1 -1
- package/resources/live/ws-base.js +84 -485
- package/resources/live/ws-base.js.map +1 -1
- package/resources/live/ws-base.mjs +83 -484
- package/resources/live/ws-base.mjs.map +1 -1
- package/resources/realtime/realtime.d.mts +8 -2
- package/resources/realtime/realtime.d.mts.map +1 -1
- package/resources/realtime/realtime.d.ts +8 -2
- package/resources/realtime/realtime.d.ts.map +1 -1
- package/resources/realtime/realtime.js.map +1 -1
- package/resources/realtime/realtime.mjs.map +1 -1
- package/resources/responses/responses.d.mts +8 -0
- package/resources/responses/responses.d.mts.map +1 -1
- package/resources/responses/responses.d.ts +8 -0
- package/resources/responses/responses.d.ts.map +1 -1
- package/resources/responses/responses.js.map +1 -1
- package/resources/responses/responses.mjs.map +1 -1
- package/resources/responses/ws-base.d.mts +2 -24
- package/resources/responses/ws-base.d.mts.map +1 -1
- package/resources/responses/ws-base.d.ts +2 -24
- package/resources/responses/ws-base.d.ts.map +1 -1
- package/resources/responses/ws-base.js +93 -519
- package/resources/responses/ws-base.js.map +1 -1
- package/resources/responses/ws-base.mjs +94 -520
- package/resources/responses/ws-base.mjs.map +1 -1
- package/resources/shared.d.mts +7 -0
- package/resources/shared.d.mts.map +1 -1
- package/resources/shared.d.ts +7 -0
- package/resources/shared.d.ts.map +1 -1
- package/resources/videos.d.mts +8 -0
- package/resources/videos.d.mts.map +1 -1
- package/resources/videos.d.ts +8 -0
- package/resources/videos.d.ts.map +1 -1
- package/src/client.ts +2 -0
- package/src/internal/responses-ws-credentials.ts +5 -157
- package/src/internal/ws-connection-controller.ts +632 -0
- package/src/internal/ws-connection.ts +116 -0
- package/src/internal/ws-credentials.ts +165 -0
- package/src/lib/live/webrtc.ts +4 -1
- package/src/resources/admin/organization/projects/api-keys.ts +29 -5
- package/src/resources/audio/speech.ts +2 -1
- package/src/resources/audio/voices.ts +53 -12
- package/src/resources/beta/realtime/realtime.ts +5 -0
- package/src/resources/beta/responses/responses.ts +10 -0
- package/src/resources/beta/responses/ws-base.ts +106 -604
- package/src/resources/chat/completions/completions.ts +1 -1
- package/src/resources/decisions.ts +75 -0
- package/src/resources/index.ts +1 -0
- package/src/resources/live/api.md +12 -0
- package/src/resources/live/forks/forks.ts +9 -0
- package/src/resources/live/forks/ws-base.ts +98 -558
- package/src/resources/live/live.ts +668 -26
- package/src/resources/live/sessions.ts +19 -4
- package/src/resources/live/sideband/sideband.ts +11 -2
- package/src/resources/live/sideband/ws-base.ts +98 -562
- package/src/resources/live/ws-base.ts +98 -558
- package/src/resources/realtime/realtime.ts +9 -2
- package/src/resources/responses/responses.ts +10 -0
- package/src/resources/responses/ws-base.ts +106 -600
- package/src/resources/shared.ts +7 -0
- package/src/resources/videos.ts +10 -0
- package/src/version.ts +1 -1
- package/version.d.mts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.mjs +1 -1
|
@@ -1,25 +1,18 @@
|
|
|
1
1
|
// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details.
|
|
2
2
|
|
|
3
3
|
import { ResponsesEmitter, ResponsesStreamMessage, WebSocketError, buildURL } from './internal-base';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { type WebSocketLike, ReadyState } from '../../../internal/ws-adapter';
|
|
4
|
+
import { WebSocketConnection } from '../../../internal/ws-connection-controller';
|
|
5
|
+
import type { WebSocketLike } from '../../../internal/ws-adapter';
|
|
7
6
|
import {
|
|
8
|
-
SendQueue,
|
|
9
|
-
getMaxBufferedEvents,
|
|
10
|
-
recordWebSocketError,
|
|
11
|
-
rawByteLength,
|
|
12
7
|
type WebSocketStreamOptions,
|
|
13
|
-
flattenRawData,
|
|
14
|
-
isRecoverableClose,
|
|
15
8
|
type RawWebSocketData,
|
|
16
9
|
type ReconnectingEvent,
|
|
17
10
|
type ReconnectingOverrides,
|
|
18
|
-
|
|
11
|
+
recordWebSocketError,
|
|
12
|
+
rawByteLength,
|
|
19
13
|
} from '../../../internal/ws';
|
|
20
14
|
import * as ResponsesAPI from './responses';
|
|
21
15
|
import { OpenAI } from '../../../client';
|
|
22
|
-
import { OpenAIError } from '../../../core/error';
|
|
23
16
|
|
|
24
17
|
const webSocketEventPayloads = new WeakMap<object, string>();
|
|
25
18
|
const webSocketEventBytes = new WeakMap<object, number>();
|
|
@@ -83,39 +76,64 @@ export abstract class ResponsesWSBase<TSocket extends WebSocketLike> extends Res
|
|
|
83
76
|
|
|
84
77
|
protected _client: OpenAI;
|
|
85
78
|
protected _parameters: Record<string, unknown> | null | undefined;
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
private _lastCloseReason: string = '';
|
|
94
|
-
|
|
95
|
-
// Necessary to keep the public event interface clean while we manage reconnecting
|
|
96
|
-
private _internalEvents = new InternalEventEmitter<{
|
|
97
|
-
socketSwap: (oldSocket: TSocket, newSocket: TSocket) => void;
|
|
98
|
-
reconnecting: (event: ReconnectingEvent<Record<string, unknown>>) => void;
|
|
99
|
-
reconnected: () => void;
|
|
100
|
-
close: (
|
|
101
|
-
code: number,
|
|
102
|
-
reason: string,
|
|
103
|
-
unsent: UnsentMessage<ResponsesAPI.BetaResponsesClientEvent>[],
|
|
104
|
-
) => void;
|
|
105
|
-
}>();
|
|
79
|
+
#connection: WebSocketConnection<
|
|
80
|
+
TSocket,
|
|
81
|
+
ResponsesAPI.BetaResponsesClientEvent,
|
|
82
|
+
ResponsesAPI.BetaResponsesServerEvent,
|
|
83
|
+
WebSocketError,
|
|
84
|
+
Record<string, unknown>
|
|
85
|
+
>;
|
|
106
86
|
|
|
107
87
|
constructor(client: OpenAI, options?: ResponsesWSBaseOptions | undefined) {
|
|
108
88
|
super();
|
|
109
89
|
this._client = client;
|
|
110
90
|
this._parameters = undefined;
|
|
111
|
-
|
|
112
|
-
this
|
|
91
|
+
const owner = this;
|
|
92
|
+
this.#connection = new WebSocketConnection<
|
|
93
|
+
TSocket,
|
|
94
|
+
ResponsesAPI.BetaResponsesClientEvent,
|
|
95
|
+
ResponsesAPI.BetaResponsesServerEvent,
|
|
96
|
+
WebSocketError,
|
|
97
|
+
Record<string, unknown>
|
|
98
|
+
>(
|
|
99
|
+
this,
|
|
100
|
+
{
|
|
101
|
+
buildURL: () => buildURL(this._client, this._parameters ?? {}),
|
|
102
|
+
createSocket: (url) => this._createSocket(url, this._authHeaders()),
|
|
103
|
+
get parameters() {
|
|
104
|
+
return owner._parameters;
|
|
105
|
+
},
|
|
106
|
+
set parameters(parameters) {
|
|
107
|
+
owner._parameters = parameters;
|
|
108
|
+
},
|
|
109
|
+
isErrorEvent: (event) => event.type === 'error',
|
|
110
|
+
onMessage: (data, isBinary) => this.#onMessage(data, isBinary),
|
|
111
|
+
onError: (message, cause) => this._onError(null, message, cause),
|
|
112
|
+
createError: (message) => new WebSocketError(message, null),
|
|
113
|
+
subscribe: (onEvent, onRaw, onError) => {
|
|
114
|
+
this.on('event', onEvent);
|
|
115
|
+
this.on('raw', onRaw);
|
|
116
|
+
this.on('error', onError);
|
|
117
|
+
},
|
|
118
|
+
unsubscribe: (onEvent, onRaw, onError) => {
|
|
119
|
+
this.off('event', onEvent);
|
|
120
|
+
this.off('raw', onRaw);
|
|
121
|
+
this.off('error', onError);
|
|
122
|
+
},
|
|
123
|
+
emitReconnecting: (event) => this._emit('reconnecting', event),
|
|
124
|
+
emitReconnected: () => this._emit('reconnected'),
|
|
125
|
+
emitClose: (code, reason, unsent) => this._emit('close', code, reason, unsent),
|
|
126
|
+
onSocketError: recordWebSocketError,
|
|
127
|
+
prepareReconnectSocket: () => this._prepareReconnectSocket(),
|
|
128
|
+
},
|
|
129
|
+
options,
|
|
130
|
+
);
|
|
113
131
|
}
|
|
114
132
|
|
|
115
133
|
/** Establishes the initial WebSocket connection. */
|
|
116
134
|
protected _connectInitial(): void {
|
|
117
135
|
this.url = buildURL(this._client, {});
|
|
118
|
-
this.socket = this.
|
|
136
|
+
this.socket = this.#connection.connect();
|
|
119
137
|
}
|
|
120
138
|
|
|
121
139
|
/**
|
|
@@ -125,66 +143,16 @@ export abstract class ResponsesWSBase<TSocket extends WebSocketLike> extends Res
|
|
|
125
143
|
*/
|
|
126
144
|
protected abstract _createSocket(url: URL, authHeaders: Record<string, string>): TSocket;
|
|
127
145
|
|
|
128
|
-
private _cancelRefresh: (() => void) | undefined;
|
|
129
|
-
|
|
130
146
|
send(event: ResponsesAPI.BetaResponsesClientEvent) {
|
|
131
|
-
|
|
132
|
-
throw new OpenAIError('Internal error: failed to initialize socket. Please report this issue.');
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
if (this._isReconnecting || this.socket.readyState === ReadyState.CONNECTING) {
|
|
136
|
-
if (!this._sendQueue.enqueue(event)) {
|
|
137
|
-
this._onError(null, 'send queue is full, message discarded', undefined);
|
|
138
|
-
}
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
if (this.socket.readyState !== ReadyState.OPEN) {
|
|
142
|
-
this._onError(null, 'cannot send on a closed WebSocket', undefined);
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
try {
|
|
146
|
-
this.socket.send(JSON.stringify(event));
|
|
147
|
-
} catch (err) {
|
|
148
|
-
this._onError(null, 'could not send data', err);
|
|
149
|
-
}
|
|
147
|
+
this.#connection.send(event);
|
|
150
148
|
}
|
|
151
149
|
|
|
152
150
|
sendRaw(data: RawWebSocketData) {
|
|
153
|
-
|
|
154
|
-
throw new OpenAIError('Internal error: failed to initialize socket. Please report this issue.');
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
if (this._isReconnecting || this.socket.readyState === ReadyState.CONNECTING) {
|
|
158
|
-
if (!this._sendQueue.enqueueRaw(data)) {
|
|
159
|
-
this._onError(null, 'send queue is full, message discarded', undefined);
|
|
160
|
-
}
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
if (this.socket.readyState !== ReadyState.OPEN) {
|
|
164
|
-
this._onError(null, 'cannot send on a closed WebSocket', undefined);
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
try {
|
|
168
|
-
this.socket.send(flattenRawData(data));
|
|
169
|
-
} catch (err) {
|
|
170
|
-
this._onError(null, 'could not send data', err);
|
|
171
|
-
}
|
|
151
|
+
this.#connection.sendRaw(data);
|
|
172
152
|
}
|
|
173
153
|
|
|
174
154
|
close(props?: { code: number; reason: string }) {
|
|
175
|
-
|
|
176
|
-
throw new OpenAIError('Internal error: failed to initialize socket. Please report this issue.');
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
this._intentionallyClosed = true;
|
|
180
|
-
this._closeCode = props?.code ?? 1000;
|
|
181
|
-
this._closeReason = props?.reason ?? 'OK';
|
|
182
|
-
this._cancelRefresh?.();
|
|
183
|
-
try {
|
|
184
|
-
this.socket.close(this._closeCode, this._closeReason);
|
|
185
|
-
} catch (err) {
|
|
186
|
-
this._onError(null, 'could not close the connection', err);
|
|
187
|
-
}
|
|
155
|
+
this.#connection.close(props);
|
|
188
156
|
}
|
|
189
157
|
|
|
190
158
|
/**
|
|
@@ -220,536 +188,70 @@ export abstract class ResponsesWSBase<TSocket extends WebSocketLike> extends Res
|
|
|
220
188
|
}
|
|
221
189
|
|
|
222
190
|
[Symbol.asyncIterator](options?: WebSocketStreamOptions): AsyncIterableIterator<ResponsesStreamMessage> {
|
|
223
|
-
|
|
224
|
-
throw new OpenAIError('Internal error: failed to initialize socket. Please report this issue.');
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
const maxBufferedEvents = getMaxBufferedEvents(options);
|
|
228
|
-
|
|
229
|
-
// Two-queue async iterator: `queue` buffers incoming messages,
|
|
230
|
-
// `resolvers` buffers waiting next() calls. A push wakes the
|
|
231
|
-
// oldest next(); a next() drains the oldest message.
|
|
232
|
-
const queue: (ResponsesStreamMessage | undefined)[] = [];
|
|
233
|
-
const resolvers: ((() => void) | undefined)[] = [];
|
|
234
|
-
let queueHead = 0;
|
|
235
|
-
let resolverHead = 0;
|
|
236
|
-
let done = false;
|
|
237
|
-
let failure: WebSocketError | undefined;
|
|
238
|
-
let currentSocket = this.socket;
|
|
239
|
-
|
|
240
|
-
const wakeResolver = () => {
|
|
241
|
-
if (resolverHead >= resolvers.length) return;
|
|
242
|
-
|
|
243
|
-
const resolver = resolvers[resolverHead];
|
|
244
|
-
resolvers[resolverHead] = undefined;
|
|
245
|
-
resolverHead += 1;
|
|
246
|
-
if (resolverHead >= 64 && resolverHead * 2 >= resolvers.length) {
|
|
247
|
-
resolvers.splice(0, resolverHead);
|
|
248
|
-
resolverHead = 0;
|
|
249
|
-
}
|
|
250
|
-
resolver?.();
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
const push = (msg: ResponsesStreamMessage) => {
|
|
254
|
-
if (done) return;
|
|
255
|
-
|
|
256
|
-
if (maxBufferedEvents !== undefined && queue.length - queueHead >= maxBufferedEvents) {
|
|
257
|
-
failure = new WebSocketError(
|
|
258
|
-
`WebSocket stream exceeded maxBufferedEvents (${maxBufferedEvents})`,
|
|
259
|
-
null,
|
|
260
|
-
);
|
|
261
|
-
done = true;
|
|
262
|
-
queue.length = 0;
|
|
263
|
-
queueHead = 0;
|
|
264
|
-
cleanup();
|
|
265
|
-
flushResolvers();
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
queue.push(msg);
|
|
270
|
-
wakeResolver();
|
|
271
|
-
};
|
|
272
|
-
|
|
273
|
-
const onEvent = (event: ResponsesAPI.BetaResponsesServerEvent) => {
|
|
274
|
-
if (event.type === 'error') return; // handled by onEmitterError
|
|
275
|
-
push({ type: 'message', message: event });
|
|
276
|
-
};
|
|
277
|
-
|
|
278
|
-
const onRaw = (data: RawWebSocketData) => {
|
|
279
|
-
push({ type: 'raw', data });
|
|
280
|
-
};
|
|
281
|
-
|
|
282
|
-
// All errors (API + socket) funnel through _onError → 'error' event
|
|
283
|
-
const onEmitterError = (err: WebSocketError) => {
|
|
284
|
-
push({ type: 'error', error: err });
|
|
285
|
-
};
|
|
286
|
-
|
|
287
|
-
const onOpen = () => {
|
|
288
|
-
push({ type: 'open' });
|
|
289
|
-
};
|
|
290
|
-
|
|
291
|
-
const onReconnecting = (evt: ReconnectingEvent<Record<string, unknown>>) => {
|
|
292
|
-
push({ type: 'reconnecting', reconnect: evt });
|
|
293
|
-
};
|
|
294
|
-
|
|
295
|
-
const onReconnected = () => {
|
|
296
|
-
push({ type: 'reconnected' });
|
|
297
|
-
};
|
|
298
|
-
|
|
299
|
-
const flushResolvers = () => {
|
|
300
|
-
while (resolverHead < resolvers.length) {
|
|
301
|
-
const resolver = resolvers[resolverHead];
|
|
302
|
-
resolvers[resolverHead] = undefined;
|
|
303
|
-
resolverHead += 1;
|
|
304
|
-
resolver?.();
|
|
305
|
-
}
|
|
306
|
-
resolvers.length = 0;
|
|
307
|
-
resolverHead = 0;
|
|
308
|
-
};
|
|
309
|
-
|
|
310
|
-
const onClose = (
|
|
311
|
-
code: number,
|
|
312
|
-
reason: string,
|
|
313
|
-
unsent: UnsentMessage<ResponsesAPI.BetaResponsesClientEvent>[],
|
|
314
|
-
) => {
|
|
315
|
-
push({ type: 'close', code, reason, unsent });
|
|
316
|
-
done = true;
|
|
317
|
-
flushResolvers();
|
|
318
|
-
cleanup();
|
|
319
|
-
};
|
|
320
|
-
|
|
321
|
-
const onSocketSwap = (_oldSocket: TSocket, newSocket: TSocket) => {
|
|
322
|
-
if (currentSocket === newSocket) return;
|
|
323
|
-
currentSocket.off('open', onOpen);
|
|
324
|
-
newSocket.on('open', onOpen);
|
|
325
|
-
currentSocket = newSocket;
|
|
326
|
-
};
|
|
327
|
-
|
|
328
|
-
const cleanup = () => {
|
|
329
|
-
this.off('event', onEvent);
|
|
330
|
-
this.off('raw', onRaw);
|
|
331
|
-
this.off('error', onEmitterError);
|
|
332
|
-
currentSocket.off('open', onOpen);
|
|
333
|
-
this._internalEvents.off('close', onClose);
|
|
334
|
-
this._internalEvents.off('socketSwap', onSocketSwap);
|
|
335
|
-
this._internalEvents.off('reconnecting', onReconnecting);
|
|
336
|
-
this._internalEvents.off('reconnected', onReconnected);
|
|
337
|
-
};
|
|
338
|
-
|
|
339
|
-
this.on('event', onEvent);
|
|
340
|
-
this.on('raw', onRaw);
|
|
341
|
-
this.on('error', onEmitterError);
|
|
342
|
-
this.socket.on('open', onOpen);
|
|
343
|
-
this._internalEvents.on('close', onClose);
|
|
344
|
-
this._internalEvents.on('socketSwap', onSocketSwap);
|
|
345
|
-
this._internalEvents.on('reconnecting', onReconnecting);
|
|
346
|
-
this._internalEvents.on('reconnected', onReconnected);
|
|
347
|
-
|
|
348
|
-
if (this._isReconnecting) {
|
|
349
|
-
// A reconnect is already in flight. The socket may be CLOSED but the
|
|
350
|
-
// instance is still alive. Emit 'reconnecting' so the iterator stays
|
|
351
|
-
// open and receives the upcoming reconnected/message events.
|
|
352
|
-
push({
|
|
353
|
-
type: 'reconnecting',
|
|
354
|
-
reconnect: { attempt: 0, maxAttempts: 0, delay: 0, closeCode: 0, parameters: undefined },
|
|
355
|
-
});
|
|
356
|
-
} else {
|
|
357
|
-
switch (this.socket.readyState) {
|
|
358
|
-
case ReadyState.CONNECTING:
|
|
359
|
-
push({ type: 'connecting' });
|
|
360
|
-
break;
|
|
361
|
-
case ReadyState.OPEN:
|
|
362
|
-
push({ type: 'open' });
|
|
363
|
-
break;
|
|
364
|
-
case ReadyState.CLOSING:
|
|
365
|
-
push({ type: 'closing' });
|
|
366
|
-
break;
|
|
367
|
-
case ReadyState.CLOSED:
|
|
368
|
-
push({
|
|
369
|
-
type: 'close',
|
|
370
|
-
code: this._lastCloseCode,
|
|
371
|
-
reason: this._lastCloseReason,
|
|
372
|
-
unsent: this._sendQueue.drain(),
|
|
373
|
-
});
|
|
374
|
-
done = true;
|
|
375
|
-
cleanup();
|
|
376
|
-
break;
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
const resolve = (
|
|
381
|
-
res: (value: IteratorResult<ResponsesStreamMessage>) => void,
|
|
382
|
-
reject: (error: WebSocketError) => void,
|
|
383
|
-
) => {
|
|
384
|
-
if (failure) {
|
|
385
|
-
reject(failure);
|
|
386
|
-
} else if (queueHead < queue.length) {
|
|
387
|
-
const queued = queue[queueHead]!;
|
|
388
|
-
queue[queueHead] = undefined;
|
|
389
|
-
queueHead += 1;
|
|
390
|
-
if (queueHead >= 64 && queueHead * 2 >= queue.length) {
|
|
391
|
-
queue.splice(0, queueHead);
|
|
392
|
-
queueHead = 0;
|
|
393
|
-
}
|
|
394
|
-
res({ value: queued, done: false });
|
|
395
|
-
} else if (done) {
|
|
396
|
-
res({ value: undefined, done: true });
|
|
397
|
-
} else {
|
|
398
|
-
return false;
|
|
399
|
-
}
|
|
400
|
-
return true;
|
|
401
|
-
};
|
|
402
|
-
|
|
403
|
-
const next = (): Promise<IteratorResult<ResponsesStreamMessage>> =>
|
|
404
|
-
new Promise((res, reject) => {
|
|
405
|
-
if (resolve(res, reject)) return;
|
|
406
|
-
resolvers.push(() => {
|
|
407
|
-
resolve(res, reject);
|
|
408
|
-
});
|
|
409
|
-
});
|
|
410
|
-
|
|
411
|
-
return {
|
|
412
|
-
next,
|
|
413
|
-
return: (): Promise<IteratorReturnResult<undefined>> => {
|
|
414
|
-
done = true;
|
|
415
|
-
queue.length = 0;
|
|
416
|
-
queueHead = 0;
|
|
417
|
-
cleanup();
|
|
418
|
-
flushResolvers();
|
|
419
|
-
return Promise.resolve({ value: undefined, done: true });
|
|
420
|
-
},
|
|
421
|
-
[Symbol.asyncIterator]() {
|
|
422
|
-
return this;
|
|
423
|
-
},
|
|
424
|
-
};
|
|
191
|
+
return this.#connection.iterate(options);
|
|
425
192
|
}
|
|
426
193
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
this.url = url;
|
|
432
|
-
|
|
433
|
-
const socket = createSocket(this.url);
|
|
434
|
-
|
|
435
|
-
socket.on('message', (data: string | ArrayBuffer | ArrayBufferView, isBinary: boolean) => {
|
|
436
|
-
if (isBinary) {
|
|
437
|
-
this._emit('raw', data);
|
|
438
|
-
return;
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
// Coerce to string in case the adapter delivers a typed-array for text frames.
|
|
442
|
-
const text = typeof data === 'string' ? data : String(data);
|
|
443
|
-
|
|
444
|
-
let event: ResponsesAPI.BetaResponsesServerEvent;
|
|
445
|
-
try {
|
|
446
|
-
event = JSON.parse(text) as ResponsesAPI.BetaResponsesServerEvent;
|
|
447
|
-
} catch {
|
|
448
|
-
this._emit('raw', data);
|
|
449
|
-
return;
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
if (
|
|
453
|
-
event === null ||
|
|
454
|
-
typeof event !== 'object' ||
|
|
455
|
-
Array.isArray(event) ||
|
|
456
|
-
!Object.prototype.hasOwnProperty.call(event, 'type') ||
|
|
457
|
-
typeof event.type !== 'string'
|
|
458
|
-
) {
|
|
459
|
-
this._onError(
|
|
460
|
-
null,
|
|
461
|
-
'received invalid WebSocket event: expected an object with an own string type',
|
|
462
|
-
undefined,
|
|
463
|
-
);
|
|
464
|
-
return;
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
const eventType: string = event.type;
|
|
468
|
-
const reservedEventType =
|
|
469
|
-
eventType === 'raw' ||
|
|
470
|
-
eventType === 'close' ||
|
|
471
|
-
eventType === 'event' ||
|
|
472
|
-
eventType === 'reconnecting' ||
|
|
473
|
-
eventType === 'reconnected' ||
|
|
474
|
-
eventType === 'open' ||
|
|
475
|
-
eventType === 'error';
|
|
476
|
-
if (reservedEventType && eventType !== 'error') {
|
|
477
|
-
this._onError(null, 'received reserved WebSocket event type', undefined);
|
|
478
|
-
return;
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
webSocketEventBytes.set(event, rawByteLength(data));
|
|
482
|
-
webSocketEventPayloads.set(event, text);
|
|
483
|
-
try {
|
|
484
|
-
this._emit('event', event);
|
|
485
|
-
} finally {
|
|
486
|
-
webSocketEventBytes.delete(event);
|
|
487
|
-
webSocketEventPayloads.delete(event);
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
if (event.type === 'error') {
|
|
491
|
-
this._onError(event);
|
|
492
|
-
} else {
|
|
493
|
-
// @ts-ignore TS isn't smart enough to get the relationship right here
|
|
494
|
-
this._emit(event.type, event);
|
|
495
|
-
}
|
|
496
|
-
});
|
|
497
|
-
|
|
498
|
-
socket.on('error', (err: Error) => {
|
|
499
|
-
recordWebSocketError(socket, err);
|
|
500
|
-
// Suppress transient errors during reconnection — the retry loop
|
|
501
|
-
// already handles them and will surface a close if retries exhaust.
|
|
502
|
-
if (this._isReconnecting) return;
|
|
503
|
-
this._onError(null, err.message, err);
|
|
504
|
-
});
|
|
505
|
-
|
|
506
|
-
socket.on('open', () => {
|
|
507
|
-
this._flushSendQueue();
|
|
508
|
-
});
|
|
509
|
-
|
|
510
|
-
socket.on('close', (code: number, reason: string) => {
|
|
511
|
-
// Ignore close events from superseded sockets — a stale socket's
|
|
512
|
-
// late close must not kick off a second reconnect loop.
|
|
513
|
-
if (socket !== this.socket) return;
|
|
514
|
-
if (!this._intentionallyClosed && this._canReconnect(code)) {
|
|
515
|
-
this._reconnect(code);
|
|
516
|
-
} else if (!this._isReconnecting) {
|
|
517
|
-
this._emitPermanentClose(code, reason);
|
|
518
|
-
}
|
|
519
|
-
});
|
|
520
|
-
|
|
521
|
-
return socket;
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
// Reconnect is opt-in via onReconnecting so callers can pass
|
|
525
|
-
// state (e.g. session IDs) into the new connection.
|
|
526
|
-
private _canReconnect(code: number): boolean {
|
|
527
|
-
if (this._intentionallyClosed) return false;
|
|
528
|
-
if (!this._reconnectOptions) return false;
|
|
529
|
-
if (this._reconnectOptions.maxRetries === 0) return false;
|
|
530
|
-
if (!this._reconnectOptions.onReconnecting) return false;
|
|
531
|
-
return isRecoverableClose(code);
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
private async _reconnect(closeCode: number): Promise<void> {
|
|
535
|
-
if (!this.socket) {
|
|
536
|
-
throw new OpenAIError('Internal error: failed to initialize socket. Please report this issue.');
|
|
194
|
+
#onMessage(data: string | ArrayBuffer | ArrayBufferView, isBinary: boolean): void {
|
|
195
|
+
if (isBinary) {
|
|
196
|
+
this._emit('raw', data);
|
|
197
|
+
return;
|
|
537
198
|
}
|
|
538
199
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
const maxRetries = this._reconnectOptions.maxRetries ?? 5;
|
|
543
|
-
const initialDelay = this._reconnectOptions.initialDelay ?? 500;
|
|
544
|
-
const maxDelay = this._reconnectOptions.maxDelay ?? 8000;
|
|
545
|
-
|
|
546
|
-
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
547
|
-
if (!this._canReconnect(closeCode)) {
|
|
548
|
-
this._isReconnecting = false;
|
|
549
|
-
if (!this._intentionallyClosed) {
|
|
550
|
-
this._onError(
|
|
551
|
-
null,
|
|
552
|
-
`WebSocket reconnect aborted: non-recoverable close code ${closeCode}`,
|
|
553
|
-
undefined,
|
|
554
|
-
);
|
|
555
|
-
}
|
|
556
|
-
this._emitPermanentClose(
|
|
557
|
-
this._intentionallyClosed ? this._closeCode : closeCode,
|
|
558
|
-
this._intentionallyClosed ? this._closeReason : 'reconnect aborted',
|
|
559
|
-
);
|
|
560
|
-
return;
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
const baseDelay = Math.min(initialDelay * Math.pow(2, attempt - 1), maxDelay);
|
|
564
|
-
// Jitter: rand [0.75, 1.0] to spread out connection attempts without over-delaying
|
|
565
|
-
const jitter = 0.75 + Math.random() * 0.25;
|
|
566
|
-
const actualDelay = Math.round(baseDelay * jitter);
|
|
567
|
-
|
|
568
|
-
let reconnectingEvent: ReconnectingEvent<Record<string, unknown>> = {
|
|
569
|
-
attempt,
|
|
570
|
-
maxAttempts: maxRetries,
|
|
571
|
-
delay: actualDelay,
|
|
572
|
-
closeCode,
|
|
573
|
-
parameters: this._parameters ? { ...this._parameters } : undefined,
|
|
574
|
-
};
|
|
200
|
+
// Coerce to string in case the adapter delivers a typed-array for text frames.
|
|
201
|
+
const text = typeof data === 'string' ? data : String(data);
|
|
575
202
|
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
this._emitPermanentClose(closeCode, 'onReconnecting callback threw');
|
|
583
|
-
return;
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
if (overrides && 'abort' in overrides && overrides.abort) {
|
|
587
|
-
this._isReconnecting = false;
|
|
588
|
-
this._emitPermanentClose(closeCode, 'reconnect aborted by handler');
|
|
589
|
-
return;
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
if (overrides && 'parameters' in overrides) {
|
|
593
|
-
this._parameters = overrides.parameters;
|
|
594
|
-
reconnectingEvent = { ...reconnectingEvent, parameters: this._parameters };
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
try {
|
|
598
|
-
this._emit('reconnecting', reconnectingEvent);
|
|
599
|
-
} catch (err) {
|
|
600
|
-
this._onError(null, 'onReconnecting callback threw', err);
|
|
601
|
-
}
|
|
602
|
-
this._internalEvents._emit('reconnecting', reconnectingEvent);
|
|
603
|
-
|
|
604
|
-
if (!this._canReconnect(closeCode)) {
|
|
605
|
-
this._isReconnecting = false;
|
|
606
|
-
if (!this._intentionallyClosed) {
|
|
607
|
-
this._onError(
|
|
608
|
-
null,
|
|
609
|
-
`WebSocket reconnect aborted: non-recoverable close code ${closeCode}`,
|
|
610
|
-
undefined,
|
|
611
|
-
);
|
|
612
|
-
}
|
|
613
|
-
this._emitPermanentClose(
|
|
614
|
-
this._intentionallyClosed ? this._closeCode : closeCode,
|
|
615
|
-
this._intentionallyClosed ? this._closeReason : 'reconnect aborted',
|
|
616
|
-
);
|
|
617
|
-
return;
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
await sleep(actualDelay);
|
|
621
|
-
|
|
622
|
-
if (!this._canReconnect(closeCode)) {
|
|
623
|
-
this._isReconnecting = false;
|
|
624
|
-
if (!this._intentionallyClosed) {
|
|
625
|
-
this._onError(
|
|
626
|
-
null,
|
|
627
|
-
`WebSocket reconnect aborted: non-recoverable close code ${closeCode}`,
|
|
628
|
-
undefined,
|
|
629
|
-
);
|
|
630
|
-
}
|
|
631
|
-
this._emitPermanentClose(
|
|
632
|
-
this._intentionallyClosed ? this._closeCode : closeCode,
|
|
633
|
-
this._intentionallyClosed ? this._closeReason : 'reconnect aborted',
|
|
634
|
-
);
|
|
635
|
-
return;
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
let closeCodePromise: Promise<number> | undefined;
|
|
639
|
-
try {
|
|
640
|
-
const oldSocket = this.socket;
|
|
641
|
-
const url = buildURL(this._client, this._parameters ?? {});
|
|
642
|
-
const canceled = new Promise<undefined>((resolve) => {
|
|
643
|
-
this._cancelRefresh = () => resolve(undefined);
|
|
644
|
-
});
|
|
645
|
-
let createSocket: ((url: URL) => TSocket) | undefined;
|
|
646
|
-
try {
|
|
647
|
-
createSocket = await Promise.race([this._prepareReconnectSocket(), canceled]);
|
|
648
|
-
} finally {
|
|
649
|
-
this._cancelRefresh = undefined;
|
|
650
|
-
}
|
|
651
|
-
if (!this._canReconnect(closeCode)) {
|
|
652
|
-
this._isReconnecting = false;
|
|
653
|
-
this._emitPermanentClose(this._closeCode, this._closeReason);
|
|
654
|
-
return;
|
|
655
|
-
}
|
|
656
|
-
this.socket = this._connect(createSocket, url);
|
|
657
|
-
// Registered synchronously after _connect() and before any
|
|
658
|
-
// await so the code is captured even when ws emits 'close'
|
|
659
|
-
// in the same tick as 'error' (e.g. abortHandshake).
|
|
660
|
-
closeCodePromise = new Promise<number>((resolve) => {
|
|
661
|
-
this.socket.once('close', resolve);
|
|
662
|
-
});
|
|
663
|
-
|
|
664
|
-
await this._awaitOpen(this.socket);
|
|
665
|
-
|
|
666
|
-
this._internalEvents._emit('socketSwap', oldSocket, this.socket);
|
|
667
|
-
this._isReconnecting = false;
|
|
668
|
-
this._flushSendQueue();
|
|
669
|
-
this._emit('reconnected');
|
|
670
|
-
this._internalEvents._emit('reconnected');
|
|
671
|
-
return;
|
|
672
|
-
} catch {
|
|
673
|
-
if (this._intentionallyClosed) {
|
|
674
|
-
// A public close observer may have thrown after lifecycle cleanup.
|
|
675
|
-
// Only emit here if the reconnect itself had not already closed.
|
|
676
|
-
if (this._isReconnecting) {
|
|
677
|
-
this._isReconnecting = false;
|
|
678
|
-
this._emitPermanentClose(this._closeCode, this._closeReason);
|
|
679
|
-
}
|
|
680
|
-
return;
|
|
681
|
-
}
|
|
682
|
-
if (closeCodePromise) {
|
|
683
|
-
// ws may emit 'error' before 'close', so await the code
|
|
684
|
-
// rather than reading it synchronously.
|
|
685
|
-
closeCode = await closeCodePromise;
|
|
686
|
-
}
|
|
687
|
-
}
|
|
203
|
+
let event: ResponsesAPI.BetaResponsesServerEvent;
|
|
204
|
+
try {
|
|
205
|
+
event = JSON.parse(text) as ResponsesAPI.BetaResponsesServerEvent;
|
|
206
|
+
} catch {
|
|
207
|
+
this._emit('raw', data);
|
|
208
|
+
return;
|
|
688
209
|
}
|
|
689
210
|
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
private _awaitOpen(socket: TSocket): Promise<void> {
|
|
705
|
-
return new Promise<void>((resolve, reject) => {
|
|
706
|
-
const cleanup = () => {
|
|
707
|
-
socket.off('open', onOpen);
|
|
708
|
-
socket.off('error', onError);
|
|
709
|
-
socket.off('close', onFail);
|
|
710
|
-
};
|
|
711
|
-
const onOpen = () => {
|
|
712
|
-
cleanup();
|
|
713
|
-
resolve();
|
|
714
|
-
};
|
|
715
|
-
const onError = (err: Error) => {
|
|
716
|
-
cleanup();
|
|
717
|
-
reject(err);
|
|
718
|
-
};
|
|
719
|
-
const onFail = () => {
|
|
720
|
-
cleanup();
|
|
721
|
-
reject(new Error('socket closed before open'));
|
|
722
|
-
};
|
|
723
|
-
socket.once('open', onOpen);
|
|
724
|
-
socket.once('error', onError);
|
|
725
|
-
socket.once('close', onFail);
|
|
726
|
-
});
|
|
727
|
-
}
|
|
211
|
+
if (
|
|
212
|
+
event === null ||
|
|
213
|
+
typeof event !== 'object' ||
|
|
214
|
+
Array.isArray(event) ||
|
|
215
|
+
!Object.prototype.hasOwnProperty.call(event, 'type') ||
|
|
216
|
+
typeof event.type !== 'string'
|
|
217
|
+
) {
|
|
218
|
+
this._onError(
|
|
219
|
+
null,
|
|
220
|
+
'received invalid WebSocket event: expected an object with an own string type',
|
|
221
|
+
undefined,
|
|
222
|
+
);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
728
225
|
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
226
|
+
const eventType: string = event.type;
|
|
227
|
+
const reservedEventType =
|
|
228
|
+
eventType === 'raw' ||
|
|
229
|
+
eventType === 'close' ||
|
|
230
|
+
eventType === 'event' ||
|
|
231
|
+
eventType === 'reconnecting' ||
|
|
232
|
+
eventType === 'reconnected' ||
|
|
233
|
+
eventType === 'open' ||
|
|
234
|
+
eventType === 'error';
|
|
235
|
+
if (reservedEventType && eventType !== 'error') {
|
|
236
|
+
this._onError(null, 'received reserved WebSocket event type', undefined);
|
|
237
|
+
return;
|
|
732
238
|
}
|
|
733
239
|
|
|
240
|
+
webSocketEventBytes.set(event, rawByteLength(data));
|
|
241
|
+
webSocketEventPayloads.set(event, text);
|
|
734
242
|
try {
|
|
735
|
-
this.
|
|
736
|
-
}
|
|
737
|
-
|
|
243
|
+
this._emit('event', event);
|
|
244
|
+
} finally {
|
|
245
|
+
webSocketEventBytes.delete(event);
|
|
246
|
+
webSocketEventPayloads.delete(event);
|
|
738
247
|
}
|
|
739
|
-
}
|
|
740
248
|
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
this._lastCloseReason = reason;
|
|
748
|
-
const unsent = this._sendQueue.drain();
|
|
749
|
-
// Internal close fires first so the async iterator is guaranteed to
|
|
750
|
-
// terminate even if a public 'close' listener throws.
|
|
751
|
-
this._internalEvents._emit('close', code, reason, unsent);
|
|
752
|
-
this._emit('close', code, reason, unsent);
|
|
249
|
+
if (event.type === 'error') {
|
|
250
|
+
this._onError(event);
|
|
251
|
+
} else {
|
|
252
|
+
// @ts-ignore TS isn't smart enough to get the relationship right here
|
|
253
|
+
this._emit(event.type, event);
|
|
254
|
+
}
|
|
753
255
|
}
|
|
754
256
|
|
|
755
257
|
protected _prepareReconnectSocket(): Promise<(url: URL) => TSocket> {
|