phonic 0.32.9 → 0.32.10
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/cjs/BaseClient.js +2 -2
- package/dist/cjs/Client.d.ts +3 -2
- package/dist/cjs/api/resources/conversations/client/Client.d.ts +3 -3
- package/dist/cjs/custom/ReconnectableConversationsSocket.d.ts +5 -4
- package/dist/cjs/custom/ReconnectableConversationsSocket.js +25 -12
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/BaseClient.mjs +2 -2
- package/dist/esm/Client.d.mts +3 -2
- package/dist/esm/api/resources/conversations/client/Client.d.mts +3 -3
- package/dist/esm/custom/ReconnectableConversationsSocket.d.mts +5 -4
- package/dist/esm/custom/ReconnectableConversationsSocket.mjs +25 -12
- package/dist/esm/version.d.mts +1 -1
- package/dist/esm/version.mjs +1 -1
- package/package.json +1 -1
package/dist/cjs/BaseClient.js
CHANGED
|
@@ -43,8 +43,8 @@ function normalizeClientOptions(options) {
|
|
|
43
43
|
const headers = (0, headers_js_1.mergeHeaders)({
|
|
44
44
|
"X-Fern-Language": "JavaScript",
|
|
45
45
|
"X-Fern-SDK-Name": "phonic",
|
|
46
|
-
"X-Fern-SDK-Version": "0.32.
|
|
47
|
-
"User-Agent": "phonic/0.32.
|
|
46
|
+
"X-Fern-SDK-Version": "0.32.10",
|
|
47
|
+
"User-Agent": "phonic/0.32.10",
|
|
48
48
|
"X-Fern-Runtime": core.RUNTIME.type,
|
|
49
49
|
"X-Fern-Runtime-Version": core.RUNTIME.version,
|
|
50
50
|
}, options === null || options === void 0 ? void 0 : options.headers);
|
package/dist/cjs/Client.d.ts
CHANGED
|
@@ -15,8 +15,9 @@ import * as core from "./core/index.js";
|
|
|
15
15
|
export declare namespace PhonicClient {
|
|
16
16
|
type Options = BaseClientOptions & {
|
|
17
17
|
/**
|
|
18
|
-
* When `true`, conversation WebSockets automatically
|
|
19
|
-
*
|
|
18
|
+
* **Experimental.** When `true`, conversation WebSockets automatically
|
|
19
|
+
* reconnect and resume after a non-deliberate disconnect (WebSocket close
|
|
20
|
+
* codes 1006, 1012, or 1001/"restarting") using `reconnect_conv_id`.
|
|
20
21
|
* Defaults to `false` until the behavior is broadly validated in production;
|
|
21
22
|
* set to `true` to opt in early.
|
|
22
23
|
*/
|
|
@@ -6,9 +6,9 @@ import { ConversationsSocket } from "./Socket.js";
|
|
|
6
6
|
export declare namespace ConversationsClient {
|
|
7
7
|
type Options = BaseClientOptions & {
|
|
8
8
|
/**
|
|
9
|
-
* When `true`, `connect()` uses session-aware reconnection
|
|
10
|
-
* disconnect (
|
|
11
|
-
* `reconnectConversationOnAbnormalDisconnect`.
|
|
9
|
+
* **Experimental.** When `true`, `connect()` uses session-aware reconnection
|
|
10
|
+
* on a non-deliberate disconnect (close codes 1006, 1012, or 1001/"restarting").
|
|
11
|
+
* Set via `PhonicClient` options as `reconnectConversationOnAbnormalDisconnect`.
|
|
12
12
|
*/
|
|
13
13
|
reconnectConversationOnAbnormalDisconnect?: boolean;
|
|
14
14
|
};
|
|
@@ -2,7 +2,7 @@ import * as core from "../core/index.js";
|
|
|
2
2
|
import type * as Phonic from "../api/index.js";
|
|
3
3
|
import { ConversationsSocket } from "../api/resources/conversations/client/Socket.js";
|
|
4
4
|
export interface ReconnectableConversationsSocketArgs {
|
|
5
|
-
/** Called on
|
|
5
|
+
/** Called on a reconnectable close to create a new socket with reconnect_conv_id. May be async (e.g. fresh auth). */
|
|
6
6
|
createReconnectSocket: (conversationId: string) => core.ReconnectingWebSocket | Promise<core.ReconnectingWebSocket>;
|
|
7
7
|
/** Initial socket for the first connection. */
|
|
8
8
|
socket: core.ReconnectingWebSocket;
|
|
@@ -16,9 +16,10 @@ type EventHandlers = {
|
|
|
16
16
|
error?: (error: Error) => void;
|
|
17
17
|
};
|
|
18
18
|
/**
|
|
19
|
-
* Wraps ConversationsSocket with automatic reconnection on
|
|
19
|
+
* Wraps ConversationsSocket with automatic reconnection on a reconnectable
|
|
20
|
+
* close (1006, 1012, or 1001/"restarting" — see isReconnectableClose).
|
|
20
21
|
*
|
|
21
|
-
* On
|
|
22
|
+
* On such a close, creates a brand new ReconnectingWebSocket (via the
|
|
22
23
|
* createReconnectSocket factory) and wraps it in a fresh ConversationsSocket,
|
|
23
24
|
* forwarding all events to user-registered handlers.
|
|
24
25
|
*
|
|
@@ -60,7 +61,7 @@ export declare class ReconnectableConversationsSocket {
|
|
|
60
61
|
sendMute(message: Phonic.MutePayload): void;
|
|
61
62
|
sendUnmute(message: Phonic.UnmutePayload): void;
|
|
62
63
|
/**
|
|
63
|
-
* Not supported — reconnection after
|
|
64
|
+
* Not supported — reconnection after a dropped connection is handled automatically.
|
|
64
65
|
* To start a new conversation, create a new socket via client.conversations.connect().
|
|
65
66
|
*/
|
|
66
67
|
connect(): never;
|
|
@@ -46,20 +46,33 @@ exports.ReconnectableConversationsSocket = void 0;
|
|
|
46
46
|
const core = __importStar(require("../core/index.js"));
|
|
47
47
|
const Socket_js_1 = require("../api/resources/conversations/client/Socket.js");
|
|
48
48
|
const json_js_1 = require("../core/json.js");
|
|
49
|
-
/** 1006 is the only close code that indicates an unexpected disconnect
|
|
50
|
-
* worth reconnecting for. All other codes (1000, 4000, 4800, etc.)
|
|
51
|
-
* are intentional server-side closes. */
|
|
52
49
|
const ABNORMAL_CLOSURE = 1006;
|
|
50
|
+
const SERVICE_RESTART = 1012;
|
|
51
|
+
const GOING_AWAY = 1001;
|
|
52
|
+
/** Whether a close means the disconnect was NOT a deliberate end of the
|
|
53
|
+
* conversation, so the SDK should transparently reconnect and resume it:
|
|
54
|
+
* - 1006 abnormal closure (socket died with no close frame)
|
|
55
|
+
* - 1012 service restart — an edge proxy/load-balancer restart closes the
|
|
56
|
+
* client with 1012/"restarting"; the conversation is still alive
|
|
57
|
+
* server-side within the grace window
|
|
58
|
+
* - 1001 "going away" ONLY when the reason is "restarting" — a proxy drain
|
|
59
|
+
* can surface to the client as 1001/"restarting" instead of 1012. A bare
|
|
60
|
+
* 1001 (empty/other reason) is a deliberate close (the caller ended the
|
|
61
|
+
* conversation, tab closed/suspended) and must NOT reconnect.
|
|
62
|
+
* Matches the server's reconnect policy. All other codes (1000, 4000,
|
|
63
|
+
* 4800, ...) are intentional closes. */
|
|
64
|
+
const isReconnectableClose = (code, reason) => code === ABNORMAL_CLOSURE || code === SERVICE_RESTART || (code === GOING_AWAY && reason === "restarting");
|
|
53
65
|
const BASE_RECONNECT_DELAY_MS = 500;
|
|
54
66
|
const MAX_RECONNECT_DELAY_MS = 5000;
|
|
55
67
|
/** Safety cap: stop retrying if the server is completely unreachable.
|
|
56
68
|
* In normal operation the server's terminal codes (4800/4801) stop
|
|
57
|
-
* retries much sooner (within the
|
|
69
|
+
* retries much sooner (within the 30s grace period). */
|
|
58
70
|
const MAX_RECONNECT_ATTEMPTS = 10;
|
|
59
71
|
/**
|
|
60
|
-
* Wraps ConversationsSocket with automatic reconnection on
|
|
72
|
+
* Wraps ConversationsSocket with automatic reconnection on a reconnectable
|
|
73
|
+
* close (1006, 1012, or 1001/"restarting" — see isReconnectableClose).
|
|
61
74
|
*
|
|
62
|
-
* On
|
|
75
|
+
* On such a close, creates a brand new ReconnectingWebSocket (via the
|
|
63
76
|
* createReconnectSocket factory) and wraps it in a fresh ConversationsSocket,
|
|
64
77
|
* forwarding all events to user-registered handlers.
|
|
65
78
|
*
|
|
@@ -141,12 +154,12 @@ class ReconnectableConversationsSocket {
|
|
|
141
154
|
this._safeSend((inner) => inner.sendUnmute(message));
|
|
142
155
|
}
|
|
143
156
|
/**
|
|
144
|
-
* Not supported — reconnection after
|
|
157
|
+
* Not supported — reconnection after a dropped connection is handled automatically.
|
|
145
158
|
* To start a new conversation, create a new socket via client.conversations.connect().
|
|
146
159
|
*/
|
|
147
160
|
connect() {
|
|
148
161
|
throw new Error("connect() is not supported on ReconnectableConversationsSocket. "
|
|
149
|
-
+ "Reconnection after
|
|
162
|
+
+ "Reconnection after an abnormal close is automatic. To start a new conversation, "
|
|
150
163
|
+ "call client.conversations.connect() again.");
|
|
151
164
|
}
|
|
152
165
|
close() {
|
|
@@ -225,7 +238,7 @@ class ReconnectableConversationsSocket {
|
|
|
225
238
|
catch (_d) {
|
|
226
239
|
this._pendingReplacement = false;
|
|
227
240
|
// Connection failed — schedule another attempt.
|
|
228
|
-
// The server's grace period (
|
|
241
|
+
// The server's grace period (30s) is the natural limit;
|
|
229
242
|
// once it expires, the next attempt will get 4800 and stop.
|
|
230
243
|
this._scheduleReconnect();
|
|
231
244
|
}
|
|
@@ -265,7 +278,7 @@ class ReconnectableConversationsSocket {
|
|
|
265
278
|
if (this._isClosed) {
|
|
266
279
|
return;
|
|
267
280
|
}
|
|
268
|
-
if (event.code
|
|
281
|
+
if (isReconnectableClose(event.code, event.reason) && this._conversationId !== null) {
|
|
269
282
|
// We have a conversation to resume — cancel RWS's built-in
|
|
270
283
|
// auto-reconnect and handle it ourselves with reconnect_conv_id.
|
|
271
284
|
// _handleClose calls _connect() before notifying listeners,
|
|
@@ -275,8 +288,8 @@ class ReconnectableConversationsSocket {
|
|
|
275
288
|
rawSocket.close();
|
|
276
289
|
this._scheduleReconnect();
|
|
277
290
|
}
|
|
278
|
-
//
|
|
279
|
-
// reconnect normally (starts a fresh conversation).
|
|
291
|
+
// Reconnectable close without conversationId: let RWS handle
|
|
292
|
+
// transport-level reconnect normally (starts a fresh conversation).
|
|
280
293
|
};
|
|
281
294
|
rawSocket.addEventListener("message", onMessage);
|
|
282
295
|
rawSocket.addEventListener("close", onClose);
|
package/dist/cjs/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "0.32.
|
|
1
|
+
export declare const SDK_VERSION = "0.32.10";
|
package/dist/cjs/version.js
CHANGED
package/dist/esm/BaseClient.mjs
CHANGED
|
@@ -6,8 +6,8 @@ export function normalizeClientOptions(options) {
|
|
|
6
6
|
const headers = mergeHeaders({
|
|
7
7
|
"X-Fern-Language": "JavaScript",
|
|
8
8
|
"X-Fern-SDK-Name": "phonic",
|
|
9
|
-
"X-Fern-SDK-Version": "0.32.
|
|
10
|
-
"User-Agent": "phonic/0.32.
|
|
9
|
+
"X-Fern-SDK-Version": "0.32.10",
|
|
10
|
+
"User-Agent": "phonic/0.32.10",
|
|
11
11
|
"X-Fern-Runtime": core.RUNTIME.type,
|
|
12
12
|
"X-Fern-Runtime-Version": core.RUNTIME.version,
|
|
13
13
|
}, options === null || options === void 0 ? void 0 : options.headers);
|
package/dist/esm/Client.d.mts
CHANGED
|
@@ -15,8 +15,9 @@ import * as core from "./core/index.mjs";
|
|
|
15
15
|
export declare namespace PhonicClient {
|
|
16
16
|
type Options = BaseClientOptions & {
|
|
17
17
|
/**
|
|
18
|
-
* When `true`, conversation WebSockets automatically
|
|
19
|
-
*
|
|
18
|
+
* **Experimental.** When `true`, conversation WebSockets automatically
|
|
19
|
+
* reconnect and resume after a non-deliberate disconnect (WebSocket close
|
|
20
|
+
* codes 1006, 1012, or 1001/"restarting") using `reconnect_conv_id`.
|
|
20
21
|
* Defaults to `false` until the behavior is broadly validated in production;
|
|
21
22
|
* set to `true` to opt in early.
|
|
22
23
|
*/
|
|
@@ -6,9 +6,9 @@ import { ConversationsSocket } from "./Socket.mjs";
|
|
|
6
6
|
export declare namespace ConversationsClient {
|
|
7
7
|
type Options = BaseClientOptions & {
|
|
8
8
|
/**
|
|
9
|
-
* When `true`, `connect()` uses session-aware reconnection
|
|
10
|
-
* disconnect (
|
|
11
|
-
* `reconnectConversationOnAbnormalDisconnect`.
|
|
9
|
+
* **Experimental.** When `true`, `connect()` uses session-aware reconnection
|
|
10
|
+
* on a non-deliberate disconnect (close codes 1006, 1012, or 1001/"restarting").
|
|
11
|
+
* Set via `PhonicClient` options as `reconnectConversationOnAbnormalDisconnect`.
|
|
12
12
|
*/
|
|
13
13
|
reconnectConversationOnAbnormalDisconnect?: boolean;
|
|
14
14
|
};
|
|
@@ -2,7 +2,7 @@ import * as core from "../core/index.mjs";
|
|
|
2
2
|
import type * as Phonic from "../api/index.mjs";
|
|
3
3
|
import { ConversationsSocket } from "../api/resources/conversations/client/Socket.mjs";
|
|
4
4
|
export interface ReconnectableConversationsSocketArgs {
|
|
5
|
-
/** Called on
|
|
5
|
+
/** Called on a reconnectable close to create a new socket with reconnect_conv_id. May be async (e.g. fresh auth). */
|
|
6
6
|
createReconnectSocket: (conversationId: string) => core.ReconnectingWebSocket | Promise<core.ReconnectingWebSocket>;
|
|
7
7
|
/** Initial socket for the first connection. */
|
|
8
8
|
socket: core.ReconnectingWebSocket;
|
|
@@ -16,9 +16,10 @@ type EventHandlers = {
|
|
|
16
16
|
error?: (error: Error) => void;
|
|
17
17
|
};
|
|
18
18
|
/**
|
|
19
|
-
* Wraps ConversationsSocket with automatic reconnection on
|
|
19
|
+
* Wraps ConversationsSocket with automatic reconnection on a reconnectable
|
|
20
|
+
* close (1006, 1012, or 1001/"restarting" — see isReconnectableClose).
|
|
20
21
|
*
|
|
21
|
-
* On
|
|
22
|
+
* On such a close, creates a brand new ReconnectingWebSocket (via the
|
|
22
23
|
* createReconnectSocket factory) and wraps it in a fresh ConversationsSocket,
|
|
23
24
|
* forwarding all events to user-registered handlers.
|
|
24
25
|
*
|
|
@@ -60,7 +61,7 @@ export declare class ReconnectableConversationsSocket {
|
|
|
60
61
|
sendMute(message: Phonic.MutePayload): void;
|
|
61
62
|
sendUnmute(message: Phonic.UnmutePayload): void;
|
|
62
63
|
/**
|
|
63
|
-
* Not supported — reconnection after
|
|
64
|
+
* Not supported — reconnection after a dropped connection is handled automatically.
|
|
64
65
|
* To start a new conversation, create a new socket via client.conversations.connect().
|
|
65
66
|
*/
|
|
66
67
|
connect(): never;
|
|
@@ -10,20 +10,33 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
import * as core from "../core/index.mjs";
|
|
11
11
|
import { ConversationsSocket } from "../api/resources/conversations/client/Socket.mjs";
|
|
12
12
|
import { fromJson } from "../core/json.mjs";
|
|
13
|
-
/** 1006 is the only close code that indicates an unexpected disconnect
|
|
14
|
-
* worth reconnecting for. All other codes (1000, 4000, 4800, etc.)
|
|
15
|
-
* are intentional server-side closes. */
|
|
16
13
|
const ABNORMAL_CLOSURE = 1006;
|
|
14
|
+
const SERVICE_RESTART = 1012;
|
|
15
|
+
const GOING_AWAY = 1001;
|
|
16
|
+
/** Whether a close means the disconnect was NOT a deliberate end of the
|
|
17
|
+
* conversation, so the SDK should transparently reconnect and resume it:
|
|
18
|
+
* - 1006 abnormal closure (socket died with no close frame)
|
|
19
|
+
* - 1012 service restart — an edge proxy/load-balancer restart closes the
|
|
20
|
+
* client with 1012/"restarting"; the conversation is still alive
|
|
21
|
+
* server-side within the grace window
|
|
22
|
+
* - 1001 "going away" ONLY when the reason is "restarting" — a proxy drain
|
|
23
|
+
* can surface to the client as 1001/"restarting" instead of 1012. A bare
|
|
24
|
+
* 1001 (empty/other reason) is a deliberate close (the caller ended the
|
|
25
|
+
* conversation, tab closed/suspended) and must NOT reconnect.
|
|
26
|
+
* Matches the server's reconnect policy. All other codes (1000, 4000,
|
|
27
|
+
* 4800, ...) are intentional closes. */
|
|
28
|
+
const isReconnectableClose = (code, reason) => code === ABNORMAL_CLOSURE || code === SERVICE_RESTART || (code === GOING_AWAY && reason === "restarting");
|
|
17
29
|
const BASE_RECONNECT_DELAY_MS = 500;
|
|
18
30
|
const MAX_RECONNECT_DELAY_MS = 5000;
|
|
19
31
|
/** Safety cap: stop retrying if the server is completely unreachable.
|
|
20
32
|
* In normal operation the server's terminal codes (4800/4801) stop
|
|
21
|
-
* retries much sooner (within the
|
|
33
|
+
* retries much sooner (within the 30s grace period). */
|
|
22
34
|
const MAX_RECONNECT_ATTEMPTS = 10;
|
|
23
35
|
/**
|
|
24
|
-
* Wraps ConversationsSocket with automatic reconnection on
|
|
36
|
+
* Wraps ConversationsSocket with automatic reconnection on a reconnectable
|
|
37
|
+
* close (1006, 1012, or 1001/"restarting" — see isReconnectableClose).
|
|
25
38
|
*
|
|
26
|
-
* On
|
|
39
|
+
* On such a close, creates a brand new ReconnectingWebSocket (via the
|
|
27
40
|
* createReconnectSocket factory) and wraps it in a fresh ConversationsSocket,
|
|
28
41
|
* forwarding all events to user-registered handlers.
|
|
29
42
|
*
|
|
@@ -105,12 +118,12 @@ export class ReconnectableConversationsSocket {
|
|
|
105
118
|
this._safeSend((inner) => inner.sendUnmute(message));
|
|
106
119
|
}
|
|
107
120
|
/**
|
|
108
|
-
* Not supported — reconnection after
|
|
121
|
+
* Not supported — reconnection after a dropped connection is handled automatically.
|
|
109
122
|
* To start a new conversation, create a new socket via client.conversations.connect().
|
|
110
123
|
*/
|
|
111
124
|
connect() {
|
|
112
125
|
throw new Error("connect() is not supported on ReconnectableConversationsSocket. "
|
|
113
|
-
+ "Reconnection after
|
|
126
|
+
+ "Reconnection after an abnormal close is automatic. To start a new conversation, "
|
|
114
127
|
+ "call client.conversations.connect() again.");
|
|
115
128
|
}
|
|
116
129
|
close() {
|
|
@@ -189,7 +202,7 @@ export class ReconnectableConversationsSocket {
|
|
|
189
202
|
catch (_d) {
|
|
190
203
|
this._pendingReplacement = false;
|
|
191
204
|
// Connection failed — schedule another attempt.
|
|
192
|
-
// The server's grace period (
|
|
205
|
+
// The server's grace period (30s) is the natural limit;
|
|
193
206
|
// once it expires, the next attempt will get 4800 and stop.
|
|
194
207
|
this._scheduleReconnect();
|
|
195
208
|
}
|
|
@@ -229,7 +242,7 @@ export class ReconnectableConversationsSocket {
|
|
|
229
242
|
if (this._isClosed) {
|
|
230
243
|
return;
|
|
231
244
|
}
|
|
232
|
-
if (event.code
|
|
245
|
+
if (isReconnectableClose(event.code, event.reason) && this._conversationId !== null) {
|
|
233
246
|
// We have a conversation to resume — cancel RWS's built-in
|
|
234
247
|
// auto-reconnect and handle it ourselves with reconnect_conv_id.
|
|
235
248
|
// _handleClose calls _connect() before notifying listeners,
|
|
@@ -239,8 +252,8 @@ export class ReconnectableConversationsSocket {
|
|
|
239
252
|
rawSocket.close();
|
|
240
253
|
this._scheduleReconnect();
|
|
241
254
|
}
|
|
242
|
-
//
|
|
243
|
-
// reconnect normally (starts a fresh conversation).
|
|
255
|
+
// Reconnectable close without conversationId: let RWS handle
|
|
256
|
+
// transport-level reconnect normally (starts a fresh conversation).
|
|
244
257
|
};
|
|
245
258
|
rawSocket.addEventListener("message", onMessage);
|
|
246
259
|
rawSocket.addEventListener("close", onClose);
|
package/dist/esm/version.d.mts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "0.32.
|
|
1
|
+
export declare const SDK_VERSION = "0.32.10";
|
package/dist/esm/version.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = "0.32.
|
|
1
|
+
export const SDK_VERSION = "0.32.10";
|