@dvina/sdk 4.0.212 → 4.0.215
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/adapters/angular/index.cjs +4 -4
- package/dist/adapters/angular/index.d.cts +2 -2
- package/dist/adapters/angular/index.d.ts +2 -2
- package/dist/adapters/angular/index.js +2 -2
- package/dist/billing/index.cjs +5 -5
- package/dist/billing/index.d.cts +2 -12
- package/dist/billing/index.d.ts +2 -12
- package/dist/billing/index.js +1 -1
- package/dist/{chunk-CW5W3LEG.js → chunk-BJDU4UX4.js} +290 -408
- package/dist/chunk-BJDU4UX4.js.map +1 -0
- package/dist/{chunk-5TAY5I34.js → chunk-Q5XGHH7D.js} +471 -209
- package/dist/chunk-Q5XGHH7D.js.map +1 -0
- package/dist/{chunk-4EESBP3A.cjs → chunk-XK5PW7IX.cjs} +311 -429
- package/dist/chunk-XK5PW7IX.cjs.map +1 -0
- package/dist/{chunk-BL3GFOZR.cjs → chunk-Y4OD5SDF.cjs} +473 -208
- package/dist/chunk-Y4OD5SDF.cjs.map +1 -0
- package/dist/{client-mOcqT66b.d.ts → client-Bn-0nJ8y.d.ts} +9 -2
- package/dist/{client-DRS_ycOv.d.cts → client-Ca2wlmC4.d.cts} +9 -2
- package/dist/{index-BKyI_YQS.d.cts → index-Ct2Mh0zl.d.cts} +1 -1
- package/dist/{index-BrsbEcIx.d.ts → index-D50r0Gl0.d.ts} +1 -1
- package/dist/index.cjs +387 -387
- package/dist/index.d.cts +9 -7
- package/dist/index.d.ts +9 -7
- package/dist/index.js +2 -2
- package/dist/pagination/index.d.cts +2 -2
- package/dist/pagination/index.d.ts +2 -2
- package/dist/{sync-engine-DN0tSqtg.d.cts → sync-engine-21OlgS5_.d.cts} +5 -16
- package/dist/{sync-engine-BmE8-rhX.d.ts → sync-engine-D35aV8Zc.d.ts} +5 -16
- package/package.json +1 -1
- package/dist/chunk-4EESBP3A.cjs.map +0 -1
- package/dist/chunk-5TAY5I34.js.map +0 -1
- package/dist/chunk-BL3GFOZR.cjs.map +0 -1
- package/dist/chunk-CW5W3LEG.js.map +0 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var chunk342BFYZZ_cjs = require('./chunk-342BFYZZ.cjs');
|
|
4
4
|
var chunkUELAE75E_cjs = require('./chunk-UELAE75E.cjs');
|
|
5
|
-
var
|
|
5
|
+
var chunkY4OD5SDF_cjs = require('./chunk-Y4OD5SDF.cjs');
|
|
6
6
|
var chunkKV5SP7RP_cjs = require('./chunk-KV5SP7RP.cjs');
|
|
7
7
|
var chunk32A6N4YK_cjs = require('./chunk-32A6N4YK.cjs');
|
|
8
8
|
var chunkDZUJEN5N_cjs = require('./chunk-DZUJEN5N.cjs');
|
|
@@ -6035,7 +6035,6 @@ var require_dexie = chunkDZUJEN5N_cjs.__commonJS({
|
|
|
6035
6035
|
// src/chat-stream.ts
|
|
6036
6036
|
var INITIAL_RECONNECT_DELAY_MS = 1e3;
|
|
6037
6037
|
var MAX_RECONNECT_DELAY_MS = 3e4;
|
|
6038
|
-
var RECONNECT_BACKOFF_MULTIPLIER = 2;
|
|
6039
6038
|
var MAX_CONSECUTIVE_AUTH_FAILURES = 3;
|
|
6040
6039
|
var AuthChatStreamError = class extends Error {
|
|
6041
6040
|
constructor(status) {
|
|
@@ -6049,24 +6048,63 @@ var ChatStreamConnection = class {
|
|
|
6049
6048
|
this.chatId = chatId;
|
|
6050
6049
|
this.options = options;
|
|
6051
6050
|
this.onEmpty = onEmpty;
|
|
6051
|
+
this.supervisor = new chunkY4OD5SDF_cjs.ConnectionSupervisor({
|
|
6052
|
+
authRetryDelayMs: INITIAL_RECONNECT_DELAY_MS,
|
|
6053
|
+
baseReconnectDelayMs: INITIAL_RECONNECT_DELAY_MS,
|
|
6054
|
+
getToken: options.getToken,
|
|
6055
|
+
id: chatId,
|
|
6056
|
+
isAuthError: (error) => error instanceof AuthChatStreamError,
|
|
6057
|
+
kind: "chat-sse",
|
|
6058
|
+
maxConsecutiveAuthFailures: MAX_CONSECUTIVE_AUTH_FAILURES,
|
|
6059
|
+
maxReconnectDelayMs: MAX_RECONNECT_DELAY_MS,
|
|
6060
|
+
onFatalError: () => {
|
|
6061
|
+
const authError = new chunkKV5SP7RP_cjs.DvinaAuthenticationError("Chat SSE stream authentication failed permanently");
|
|
6062
|
+
this.options.onError?.(authError);
|
|
6063
|
+
this.close(authError);
|
|
6064
|
+
},
|
|
6065
|
+
dial: async (context) => {
|
|
6066
|
+
const url = new URL(`${this.options.baseUrl}/${encodeURIComponent(this.chatId)}/stream`);
|
|
6067
|
+
if (this.lastEventId) {
|
|
6068
|
+
url.searchParams.set("lastEventId", this.lastEventId);
|
|
6069
|
+
}
|
|
6070
|
+
const response = await fetch(url.toString(), {
|
|
6071
|
+
method: "GET",
|
|
6072
|
+
headers: {
|
|
6073
|
+
Accept: "text/event-stream",
|
|
6074
|
+
Authorization: `Bearer ${context.token}`,
|
|
6075
|
+
"Cache-Control": "no-cache",
|
|
6076
|
+
...this.lastEventId ? { "Last-Event-ID": this.lastEventId } : {}
|
|
6077
|
+
},
|
|
6078
|
+
signal: context.signal
|
|
6079
|
+
});
|
|
6080
|
+
if (!response.ok) {
|
|
6081
|
+
if (response.status === 401 || response.status === 403) {
|
|
6082
|
+
throw new AuthChatStreamError(response.status);
|
|
6083
|
+
}
|
|
6084
|
+
throw new Error(`Chat stream connection failed: ${response.status} ${response.statusText}`);
|
|
6085
|
+
}
|
|
6086
|
+
if (!response.body) {
|
|
6087
|
+
throw new Error("Chat stream response has no body");
|
|
6088
|
+
}
|
|
6089
|
+
context.markConnected();
|
|
6090
|
+
await chunkY4OD5SDF_cjs.consumeSseStream(response.body, context.signal, {
|
|
6091
|
+
onChunk: () => context.markActivity(),
|
|
6092
|
+
onEventBlock: (block) => this.processEventBlock(block, context.requestTokenRefresh)
|
|
6093
|
+
});
|
|
6094
|
+
}
|
|
6095
|
+
});
|
|
6052
6096
|
}
|
|
6053
|
-
abortController;
|
|
6054
|
-
consecutiveAuthFailures = 0;
|
|
6055
6097
|
destroyed = false;
|
|
6056
6098
|
lastEventId;
|
|
6057
|
-
needsForceRefresh = false;
|
|
6058
|
-
reconnectDelay = INITIAL_RECONNECT_DELAY_MS;
|
|
6059
|
-
reconnectTimer;
|
|
6060
|
-
shouldReconnect = false;
|
|
6061
6099
|
subscribers = /* @__PURE__ */ new Set();
|
|
6100
|
+
supervisor;
|
|
6062
6101
|
addSubscriber(subscriber) {
|
|
6063
6102
|
if (this.destroyed) {
|
|
6064
6103
|
throw new Error(`Chat stream '${this.chatId}' is closed`);
|
|
6065
6104
|
}
|
|
6066
6105
|
this.subscribers.add(subscriber);
|
|
6067
|
-
if (
|
|
6068
|
-
this.
|
|
6069
|
-
void this.doConnect();
|
|
6106
|
+
if (this.subscribers.size === 1) {
|
|
6107
|
+
void this.supervisor.start();
|
|
6070
6108
|
}
|
|
6071
6109
|
}
|
|
6072
6110
|
removeSubscriber(subscriber) {
|
|
@@ -6075,17 +6113,18 @@ var ChatStreamConnection = class {
|
|
|
6075
6113
|
this.close();
|
|
6076
6114
|
}
|
|
6077
6115
|
}
|
|
6078
|
-
|
|
6079
|
-
this.
|
|
6080
|
-
|
|
6081
|
-
if (this.reconnectTimer) {
|
|
6082
|
-
clearTimeout(this.reconnectTimer);
|
|
6083
|
-
this.reconnectTimer = void 0;
|
|
6116
|
+
reconnect() {
|
|
6117
|
+
if (this.destroyed || this.subscribers.size === 0) {
|
|
6118
|
+
return;
|
|
6084
6119
|
}
|
|
6085
|
-
|
|
6086
|
-
|
|
6087
|
-
|
|
6120
|
+
this.supervisor.reconnect();
|
|
6121
|
+
}
|
|
6122
|
+
close(error) {
|
|
6123
|
+
if (this.destroyed) {
|
|
6124
|
+
return;
|
|
6088
6125
|
}
|
|
6126
|
+
this.destroyed = true;
|
|
6127
|
+
this.supervisor.close();
|
|
6089
6128
|
for (const subscriber of Array.from(this.subscribers)) {
|
|
6090
6129
|
subscriber.finish(error);
|
|
6091
6130
|
}
|
|
@@ -6095,94 +6134,7 @@ var ChatStreamConnection = class {
|
|
|
6095
6134
|
get isDestroyed() {
|
|
6096
6135
|
return this.destroyed;
|
|
6097
6136
|
}
|
|
6098
|
-
|
|
6099
|
-
if (!this.shouldReconnect || this.destroyed || this.subscribers.size === 0) {
|
|
6100
|
-
return;
|
|
6101
|
-
}
|
|
6102
|
-
this.abortController = new AbortController();
|
|
6103
|
-
try {
|
|
6104
|
-
const forceRefresh = this.needsForceRefresh;
|
|
6105
|
-
this.needsForceRefresh = false;
|
|
6106
|
-
const token = await this.options.getToken(forceRefresh ? { forceRefresh: true } : void 0);
|
|
6107
|
-
const url = new URL(`${this.options.baseUrl}/${encodeURIComponent(this.chatId)}/stream`);
|
|
6108
|
-
if (this.lastEventId) {
|
|
6109
|
-
url.searchParams.set("lastEventId", this.lastEventId);
|
|
6110
|
-
}
|
|
6111
|
-
const response = await fetch(url.toString(), {
|
|
6112
|
-
method: "GET",
|
|
6113
|
-
headers: {
|
|
6114
|
-
Accept: "text/event-stream",
|
|
6115
|
-
Authorization: `Bearer ${token}`,
|
|
6116
|
-
"Cache-Control": "no-cache",
|
|
6117
|
-
...this.lastEventId ? { "Last-Event-ID": this.lastEventId } : {}
|
|
6118
|
-
},
|
|
6119
|
-
signal: this.abortController.signal
|
|
6120
|
-
});
|
|
6121
|
-
if (!response.ok) {
|
|
6122
|
-
if (response.status === 401 || response.status === 403) {
|
|
6123
|
-
throw new AuthChatStreamError(response.status);
|
|
6124
|
-
}
|
|
6125
|
-
throw new Error(`Chat stream connection failed: ${response.status} ${response.statusText}`);
|
|
6126
|
-
}
|
|
6127
|
-
if (!response.body) {
|
|
6128
|
-
throw new Error("Chat stream response has no body");
|
|
6129
|
-
}
|
|
6130
|
-
this.consecutiveAuthFailures = 0;
|
|
6131
|
-
this.reconnectDelay = INITIAL_RECONNECT_DELAY_MS;
|
|
6132
|
-
await this.parseSseStream(response.body, this.abortController.signal);
|
|
6133
|
-
} catch (error) {
|
|
6134
|
-
if (error.name === "AbortError") {
|
|
6135
|
-
return;
|
|
6136
|
-
}
|
|
6137
|
-
if (!this.shouldReconnect || this.destroyed || this.subscribers.size === 0) {
|
|
6138
|
-
return;
|
|
6139
|
-
}
|
|
6140
|
-
const isAuthError2 = error instanceof AuthChatStreamError;
|
|
6141
|
-
if (isAuthError2) {
|
|
6142
|
-
this.consecutiveAuthFailures += 1;
|
|
6143
|
-
if (this.consecutiveAuthFailures >= MAX_CONSECUTIVE_AUTH_FAILURES) {
|
|
6144
|
-
const authError = new chunkKV5SP7RP_cjs.DvinaAuthenticationError("Chat SSE stream authentication failed permanently");
|
|
6145
|
-
this.options.onError?.(authError);
|
|
6146
|
-
this.close(authError);
|
|
6147
|
-
return;
|
|
6148
|
-
}
|
|
6149
|
-
this.needsForceRefresh = true;
|
|
6150
|
-
}
|
|
6151
|
-
const delay = isAuthError2 ? INITIAL_RECONNECT_DELAY_MS : this.reconnectDelay;
|
|
6152
|
-
this.scheduleReconnect(delay);
|
|
6153
|
-
if (!isAuthError2) {
|
|
6154
|
-
this.reconnectDelay = Math.min(
|
|
6155
|
-
this.reconnectDelay * RECONNECT_BACKOFF_MULTIPLIER,
|
|
6156
|
-
MAX_RECONNECT_DELAY_MS
|
|
6157
|
-
);
|
|
6158
|
-
}
|
|
6159
|
-
}
|
|
6160
|
-
}
|
|
6161
|
-
async parseSseStream(body, signal) {
|
|
6162
|
-
const reader = body.getReader();
|
|
6163
|
-
const decoder = new TextDecoder();
|
|
6164
|
-
let buffer = "";
|
|
6165
|
-
try {
|
|
6166
|
-
while (!signal.aborted && this.shouldReconnect && !this.destroyed) {
|
|
6167
|
-
const { done, value } = await reader.read();
|
|
6168
|
-
if (done) {
|
|
6169
|
-
break;
|
|
6170
|
-
}
|
|
6171
|
-
buffer += decoder.decode(value, { stream: true });
|
|
6172
|
-
const parts = buffer.split(/(?:\r\n|\r|\n){2}/);
|
|
6173
|
-
buffer = parts.pop() ?? "";
|
|
6174
|
-
for (const part of parts) {
|
|
6175
|
-
this.processEventBlock(part.trim());
|
|
6176
|
-
}
|
|
6177
|
-
}
|
|
6178
|
-
} finally {
|
|
6179
|
-
reader.releaseLock();
|
|
6180
|
-
}
|
|
6181
|
-
if (this.shouldReconnect && !this.destroyed && this.subscribers.size > 0) {
|
|
6182
|
-
this.scheduleReconnect(this.reconnectDelay);
|
|
6183
|
-
}
|
|
6184
|
-
}
|
|
6185
|
-
processEventBlock(block) {
|
|
6137
|
+
processEventBlock(block, requestTokenRefresh) {
|
|
6186
6138
|
if (!block || block.startsWith(":")) {
|
|
6187
6139
|
return;
|
|
6188
6140
|
}
|
|
@@ -6199,8 +6151,8 @@ var ChatStreamConnection = class {
|
|
|
6199
6151
|
}
|
|
6200
6152
|
}
|
|
6201
6153
|
if (eventType === "token-expired") {
|
|
6202
|
-
|
|
6203
|
-
|
|
6154
|
+
requestTokenRefresh();
|
|
6155
|
+
throw new AuthChatStreamError(401);
|
|
6204
6156
|
}
|
|
6205
6157
|
if (!eventId || dataLines.length === 0) {
|
|
6206
6158
|
return;
|
|
@@ -6217,40 +6169,64 @@ var ChatStreamConnection = class {
|
|
|
6217
6169
|
subscriber.push(value);
|
|
6218
6170
|
}
|
|
6219
6171
|
}
|
|
6220
|
-
scheduleReconnect(delay) {
|
|
6221
|
-
if (!this.shouldReconnect || this.destroyed || this.subscribers.size === 0) {
|
|
6222
|
-
return;
|
|
6223
|
-
}
|
|
6224
|
-
if (this.reconnectTimer) {
|
|
6225
|
-
clearTimeout(this.reconnectTimer);
|
|
6226
|
-
}
|
|
6227
|
-
this.reconnectTimer = setTimeout(() => {
|
|
6228
|
-
this.reconnectTimer = void 0;
|
|
6229
|
-
void this.doConnect();
|
|
6230
|
-
}, delay);
|
|
6231
|
-
}
|
|
6232
6172
|
};
|
|
6233
6173
|
var ActiveChatStreamConnection = class {
|
|
6234
6174
|
constructor(options, onEmpty) {
|
|
6235
6175
|
this.options = options;
|
|
6236
6176
|
this.onEmpty = onEmpty;
|
|
6177
|
+
this.supervisor = new chunkY4OD5SDF_cjs.ConnectionSupervisor({
|
|
6178
|
+
authRetryDelayMs: INITIAL_RECONNECT_DELAY_MS,
|
|
6179
|
+
baseReconnectDelayMs: INITIAL_RECONNECT_DELAY_MS,
|
|
6180
|
+
getToken: options.getToken,
|
|
6181
|
+
id: "active",
|
|
6182
|
+
isAuthError: (error) => error instanceof AuthChatStreamError,
|
|
6183
|
+
kind: "active-chat-sse",
|
|
6184
|
+
maxConsecutiveAuthFailures: MAX_CONSECUTIVE_AUTH_FAILURES,
|
|
6185
|
+
maxReconnectDelayMs: MAX_RECONNECT_DELAY_MS,
|
|
6186
|
+
onFatalError: () => {
|
|
6187
|
+
const authError = new chunkKV5SP7RP_cjs.DvinaAuthenticationError(
|
|
6188
|
+
"Active chat SSE stream authentication failed permanently"
|
|
6189
|
+
);
|
|
6190
|
+
this.options.onError?.(authError);
|
|
6191
|
+
this.close(authError);
|
|
6192
|
+
},
|
|
6193
|
+
dial: async (context) => {
|
|
6194
|
+
const response = await fetch(new URL(`${this.options.baseUrl}/active`).toString(), {
|
|
6195
|
+
method: "GET",
|
|
6196
|
+
headers: {
|
|
6197
|
+
Accept: "text/event-stream",
|
|
6198
|
+
Authorization: `Bearer ${context.token}`,
|
|
6199
|
+
"Cache-Control": "no-cache"
|
|
6200
|
+
},
|
|
6201
|
+
signal: context.signal
|
|
6202
|
+
});
|
|
6203
|
+
if (!response.ok) {
|
|
6204
|
+
if (response.status === 401 || response.status === 403) {
|
|
6205
|
+
throw new AuthChatStreamError(response.status);
|
|
6206
|
+
}
|
|
6207
|
+
throw new Error(`Active chat stream connection failed: ${response.status} ${response.statusText}`);
|
|
6208
|
+
}
|
|
6209
|
+
if (!response.body) {
|
|
6210
|
+
throw new Error("Active chat stream response has no body");
|
|
6211
|
+
}
|
|
6212
|
+
context.markConnected();
|
|
6213
|
+
await chunkY4OD5SDF_cjs.consumeSseStream(response.body, context.signal, {
|
|
6214
|
+
onChunk: () => context.markActivity(),
|
|
6215
|
+
onEventBlock: (block) => this.processEventBlock(block, context.requestTokenRefresh)
|
|
6216
|
+
});
|
|
6217
|
+
}
|
|
6218
|
+
});
|
|
6237
6219
|
}
|
|
6238
|
-
abortController;
|
|
6239
|
-
consecutiveAuthFailures = 0;
|
|
6240
6220
|
destroyed = false;
|
|
6241
|
-
needsForceRefresh = false;
|
|
6242
|
-
reconnectDelay = INITIAL_RECONNECT_DELAY_MS;
|
|
6243
|
-
reconnectTimer;
|
|
6244
|
-
shouldReconnect = false;
|
|
6245
6221
|
subscribers = /* @__PURE__ */ new Set();
|
|
6222
|
+
supervisor;
|
|
6246
6223
|
addSubscriber(subscriber) {
|
|
6247
6224
|
if (this.destroyed) {
|
|
6248
6225
|
throw new Error("Active chat stream is closed");
|
|
6249
6226
|
}
|
|
6250
6227
|
this.subscribers.add(subscriber);
|
|
6251
|
-
if (
|
|
6252
|
-
this.
|
|
6253
|
-
void this.doConnect();
|
|
6228
|
+
if (this.subscribers.size === 1) {
|
|
6229
|
+
void this.supervisor.start();
|
|
6254
6230
|
}
|
|
6255
6231
|
}
|
|
6256
6232
|
removeSubscriber(subscriber) {
|
|
@@ -6259,17 +6235,18 @@ var ActiveChatStreamConnection = class {
|
|
|
6259
6235
|
this.close();
|
|
6260
6236
|
}
|
|
6261
6237
|
}
|
|
6262
|
-
|
|
6263
|
-
this.
|
|
6264
|
-
|
|
6265
|
-
if (this.reconnectTimer) {
|
|
6266
|
-
clearTimeout(this.reconnectTimer);
|
|
6267
|
-
this.reconnectTimer = void 0;
|
|
6238
|
+
reconnect() {
|
|
6239
|
+
if (this.destroyed || this.subscribers.size === 0) {
|
|
6240
|
+
return;
|
|
6268
6241
|
}
|
|
6269
|
-
|
|
6270
|
-
|
|
6271
|
-
|
|
6242
|
+
this.supervisor.reconnect();
|
|
6243
|
+
}
|
|
6244
|
+
close(error) {
|
|
6245
|
+
if (this.destroyed) {
|
|
6246
|
+
return;
|
|
6272
6247
|
}
|
|
6248
|
+
this.destroyed = true;
|
|
6249
|
+
this.supervisor.close();
|
|
6273
6250
|
for (const subscriber of Array.from(this.subscribers)) {
|
|
6274
6251
|
subscriber.finish(error);
|
|
6275
6252
|
}
|
|
@@ -6279,91 +6256,7 @@ var ActiveChatStreamConnection = class {
|
|
|
6279
6256
|
get isDestroyed() {
|
|
6280
6257
|
return this.destroyed;
|
|
6281
6258
|
}
|
|
6282
|
-
|
|
6283
|
-
if (!this.shouldReconnect || this.destroyed || this.subscribers.size === 0) {
|
|
6284
|
-
return;
|
|
6285
|
-
}
|
|
6286
|
-
this.abortController = new AbortController();
|
|
6287
|
-
try {
|
|
6288
|
-
const forceRefresh = this.needsForceRefresh;
|
|
6289
|
-
this.needsForceRefresh = false;
|
|
6290
|
-
const token = await this.options.getToken(forceRefresh ? { forceRefresh: true } : void 0);
|
|
6291
|
-
const response = await fetch(new URL(`${this.options.baseUrl}/active`).toString(), {
|
|
6292
|
-
method: "GET",
|
|
6293
|
-
headers: {
|
|
6294
|
-
Accept: "text/event-stream",
|
|
6295
|
-
Authorization: `Bearer ${token}`,
|
|
6296
|
-
"Cache-Control": "no-cache"
|
|
6297
|
-
},
|
|
6298
|
-
signal: this.abortController.signal
|
|
6299
|
-
});
|
|
6300
|
-
if (!response.ok) {
|
|
6301
|
-
if (response.status === 401 || response.status === 403) {
|
|
6302
|
-
throw new AuthChatStreamError(response.status);
|
|
6303
|
-
}
|
|
6304
|
-
throw new Error(`Active chat stream connection failed: ${response.status} ${response.statusText}`);
|
|
6305
|
-
}
|
|
6306
|
-
if (!response.body) {
|
|
6307
|
-
throw new Error("Active chat stream response has no body");
|
|
6308
|
-
}
|
|
6309
|
-
this.consecutiveAuthFailures = 0;
|
|
6310
|
-
this.reconnectDelay = INITIAL_RECONNECT_DELAY_MS;
|
|
6311
|
-
await this.parseSseStream(response.body, this.abortController.signal);
|
|
6312
|
-
} catch (error) {
|
|
6313
|
-
if (error.name === "AbortError") {
|
|
6314
|
-
return;
|
|
6315
|
-
}
|
|
6316
|
-
if (!this.shouldReconnect || this.destroyed || this.subscribers.size === 0) {
|
|
6317
|
-
return;
|
|
6318
|
-
}
|
|
6319
|
-
const isAuthError2 = error instanceof AuthChatStreamError;
|
|
6320
|
-
if (isAuthError2) {
|
|
6321
|
-
this.consecutiveAuthFailures += 1;
|
|
6322
|
-
if (this.consecutiveAuthFailures >= MAX_CONSECUTIVE_AUTH_FAILURES) {
|
|
6323
|
-
const authError = new chunkKV5SP7RP_cjs.DvinaAuthenticationError(
|
|
6324
|
-
"Active chat SSE stream authentication failed permanently"
|
|
6325
|
-
);
|
|
6326
|
-
this.options.onError?.(authError);
|
|
6327
|
-
this.close(authError);
|
|
6328
|
-
return;
|
|
6329
|
-
}
|
|
6330
|
-
this.needsForceRefresh = true;
|
|
6331
|
-
}
|
|
6332
|
-
const delay = isAuthError2 ? INITIAL_RECONNECT_DELAY_MS : this.reconnectDelay;
|
|
6333
|
-
this.scheduleReconnect(delay);
|
|
6334
|
-
if (!isAuthError2) {
|
|
6335
|
-
this.reconnectDelay = Math.min(
|
|
6336
|
-
this.reconnectDelay * RECONNECT_BACKOFF_MULTIPLIER,
|
|
6337
|
-
MAX_RECONNECT_DELAY_MS
|
|
6338
|
-
);
|
|
6339
|
-
}
|
|
6340
|
-
}
|
|
6341
|
-
}
|
|
6342
|
-
async parseSseStream(body, signal) {
|
|
6343
|
-
const reader = body.getReader();
|
|
6344
|
-
const decoder = new TextDecoder();
|
|
6345
|
-
let buffer = "";
|
|
6346
|
-
try {
|
|
6347
|
-
while (!signal.aborted && this.shouldReconnect && !this.destroyed) {
|
|
6348
|
-
const { done, value } = await reader.read();
|
|
6349
|
-
if (done) {
|
|
6350
|
-
break;
|
|
6351
|
-
}
|
|
6352
|
-
buffer += decoder.decode(value, { stream: true });
|
|
6353
|
-
const parts = buffer.split(/(?:\r\n|\r|\n){2}/);
|
|
6354
|
-
buffer = parts.pop() ?? "";
|
|
6355
|
-
for (const part of parts) {
|
|
6356
|
-
this.processEventBlock(part.trim());
|
|
6357
|
-
}
|
|
6358
|
-
}
|
|
6359
|
-
} finally {
|
|
6360
|
-
reader.releaseLock();
|
|
6361
|
-
}
|
|
6362
|
-
if (this.shouldReconnect && !this.destroyed && this.subscribers.size > 0) {
|
|
6363
|
-
this.scheduleReconnect(this.reconnectDelay);
|
|
6364
|
-
}
|
|
6365
|
-
}
|
|
6366
|
-
processEventBlock(block) {
|
|
6259
|
+
processEventBlock(block, requestTokenRefresh) {
|
|
6367
6260
|
if (!block || block.startsWith(":")) {
|
|
6368
6261
|
return;
|
|
6369
6262
|
}
|
|
@@ -6377,8 +6270,8 @@ var ActiveChatStreamConnection = class {
|
|
|
6377
6270
|
}
|
|
6378
6271
|
}
|
|
6379
6272
|
if (eventType === "token-expired") {
|
|
6380
|
-
|
|
6381
|
-
|
|
6273
|
+
requestTokenRefresh();
|
|
6274
|
+
throw new AuthChatStreamError(401);
|
|
6382
6275
|
}
|
|
6383
6276
|
if (eventType !== "active" || dataLines.length === 0) {
|
|
6384
6277
|
return;
|
|
@@ -6397,18 +6290,6 @@ var ActiveChatStreamConnection = class {
|
|
|
6397
6290
|
subscriber.push(value);
|
|
6398
6291
|
}
|
|
6399
6292
|
}
|
|
6400
|
-
scheduleReconnect(delay) {
|
|
6401
|
-
if (!this.shouldReconnect || this.destroyed || this.subscribers.size === 0) {
|
|
6402
|
-
return;
|
|
6403
|
-
}
|
|
6404
|
-
if (this.reconnectTimer) {
|
|
6405
|
-
clearTimeout(this.reconnectTimer);
|
|
6406
|
-
}
|
|
6407
|
-
this.reconnectTimer = setTimeout(() => {
|
|
6408
|
-
this.reconnectTimer = void 0;
|
|
6409
|
-
void this.doConnect();
|
|
6410
|
-
}, delay);
|
|
6411
|
-
}
|
|
6412
6293
|
};
|
|
6413
6294
|
function createChatStreamClient(options) {
|
|
6414
6295
|
const connections = /* @__PURE__ */ new Map();
|
|
@@ -6577,6 +6458,12 @@ function createChatStreamClient(options) {
|
|
|
6577
6458
|
}
|
|
6578
6459
|
};
|
|
6579
6460
|
}
|
|
6461
|
+
function reconnectAll() {
|
|
6462
|
+
for (const connection of connections.values()) {
|
|
6463
|
+
connection.reconnect();
|
|
6464
|
+
}
|
|
6465
|
+
activeConnection?.reconnect();
|
|
6466
|
+
}
|
|
6580
6467
|
function destroy() {
|
|
6581
6468
|
for (const connection of Array.from(connections.values())) {
|
|
6582
6469
|
connection.close();
|
|
@@ -6591,6 +6478,7 @@ function createChatStreamClient(options) {
|
|
|
6591
6478
|
},
|
|
6592
6479
|
listen,
|
|
6593
6480
|
stream,
|
|
6481
|
+
reconnectAll,
|
|
6594
6482
|
destroy
|
|
6595
6483
|
};
|
|
6596
6484
|
}
|
|
@@ -7338,20 +7226,12 @@ function createWsTransport(options) {
|
|
|
7338
7226
|
let lastCloseCode = null;
|
|
7339
7227
|
let nextToken;
|
|
7340
7228
|
let currentToken;
|
|
7341
|
-
let refreshPromise = null;
|
|
7342
7229
|
async function refreshToken() {
|
|
7343
|
-
|
|
7344
|
-
|
|
7345
|
-
|
|
7346
|
-
if (!token || token === failedToken) {
|
|
7347
|
-
throw new chunkKV5SP7RP_cjs.DvinaAuthenticationError("Token refresh did not produce a new token", failedToken);
|
|
7348
|
-
}
|
|
7349
|
-
nextToken = token;
|
|
7350
|
-
}).finally(() => {
|
|
7351
|
-
refreshPromise = null;
|
|
7352
|
-
});
|
|
7230
|
+
const token = await chunkY4OD5SDF_cjs.refreshTokenSingleFlight(options.getToken, currentToken);
|
|
7231
|
+
if (!token) {
|
|
7232
|
+
throw new chunkKV5SP7RP_cjs.DvinaAuthenticationError("Token refresh did not produce a new token", currentToken);
|
|
7353
7233
|
}
|
|
7354
|
-
|
|
7234
|
+
nextToken = token;
|
|
7355
7235
|
}
|
|
7356
7236
|
async function prepareSubscriptionConnection() {
|
|
7357
7237
|
const token = nextToken ?? await options.getToken();
|
|
@@ -7399,7 +7279,7 @@ function createWsTransport(options) {
|
|
|
7399
7279
|
}
|
|
7400
7280
|
});
|
|
7401
7281
|
function subscribe(document2, variables) {
|
|
7402
|
-
const query =
|
|
7282
|
+
const query = chunkY4OD5SDF_cjs.print(document2);
|
|
7403
7283
|
const subscribeOnce = () => ({
|
|
7404
7284
|
[Symbol.asyncIterator]() {
|
|
7405
7285
|
const queue = [];
|
|
@@ -8087,35 +7967,47 @@ var AuthSseError = class extends Error {
|
|
|
8087
7967
|
};
|
|
8088
7968
|
var INITIAL_RECONNECT_DELAY_MS2 = 1e3;
|
|
8089
7969
|
var MAX_RECONNECT_DELAY_MS2 = 3e4;
|
|
8090
|
-
var RECONNECT_BACKOFF_MULTIPLIER2 = 2;
|
|
8091
7970
|
var MAX_CONSECUTIVE_AUTH_FAILURES2 = 3;
|
|
8092
7971
|
var SUBSCRIPTION_REFRESH_INTERVAL_MS = 5 * 60 * 1e3;
|
|
7972
|
+
function mapSupervisorState(state) {
|
|
7973
|
+
if (state === "connected") {
|
|
7974
|
+
return "connected";
|
|
7975
|
+
}
|
|
7976
|
+
if (state === "connecting") {
|
|
7977
|
+
return "connecting";
|
|
7978
|
+
}
|
|
7979
|
+
return "disconnected";
|
|
7980
|
+
}
|
|
8093
7981
|
function createSseTransport(options) {
|
|
8094
|
-
let abortController;
|
|
8095
7982
|
let isConnected = false;
|
|
8096
|
-
let reconnectDelay = INITIAL_RECONNECT_DELAY_MS2;
|
|
8097
|
-
let reconnectTimer;
|
|
8098
|
-
let refreshTimer;
|
|
8099
|
-
let shouldReconnect = false;
|
|
8100
7983
|
let currentLastSyncId;
|
|
8101
|
-
let
|
|
8102
|
-
let consecutiveAuthFailures = 0;
|
|
7984
|
+
let refreshTimer;
|
|
8103
7985
|
let hasConnectedOnce = false;
|
|
7986
|
+
let lastLegacyState;
|
|
8104
7987
|
const activeSubscriptions = /* @__PURE__ */ new Map();
|
|
8105
|
-
|
|
8106
|
-
|
|
8107
|
-
|
|
8108
|
-
|
|
8109
|
-
|
|
8110
|
-
|
|
8111
|
-
|
|
8112
|
-
if (!
|
|
8113
|
-
|
|
8114
|
-
|
|
8115
|
-
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
|
|
7988
|
+
const emitLegacyState = (state) => {
|
|
7989
|
+
const mapped = mapSupervisorState(state);
|
|
7990
|
+
if (mapped === lastLegacyState) {
|
|
7991
|
+
return;
|
|
7992
|
+
}
|
|
7993
|
+
lastLegacyState = mapped;
|
|
7994
|
+
isConnected = mapped === "connected";
|
|
7995
|
+
if (!isConnected) {
|
|
7996
|
+
stopSubscriptionRefresh();
|
|
7997
|
+
}
|
|
7998
|
+
options.onStateChange?.(mapped);
|
|
7999
|
+
};
|
|
8000
|
+
const supervisor = new chunkY4OD5SDF_cjs.ConnectionSupervisor({
|
|
8001
|
+
authRetryDelayMs: INITIAL_RECONNECT_DELAY_MS2,
|
|
8002
|
+
baseReconnectDelayMs: INITIAL_RECONNECT_DELAY_MS2,
|
|
8003
|
+
getToken: options.getToken,
|
|
8004
|
+
id: "primary",
|
|
8005
|
+
isAuthError: (error) => error instanceof AuthSseError,
|
|
8006
|
+
kind: "sync-sse",
|
|
8007
|
+
maxConsecutiveAuthFailures: MAX_CONSECUTIVE_AUTH_FAILURES2,
|
|
8008
|
+
maxReconnectDelayMs: MAX_RECONNECT_DELAY_MS2,
|
|
8009
|
+
onStateChange: (snapshot) => emitLegacyState(snapshot.state),
|
|
8010
|
+
dial: async (context) => {
|
|
8119
8011
|
const url = new URL(options.url);
|
|
8120
8012
|
if (currentLastSyncId && currentLastSyncId !== "0") {
|
|
8121
8013
|
url.searchParams.set("lastSyncId", currentLastSyncId);
|
|
@@ -8123,11 +8015,11 @@ function createSseTransport(options) {
|
|
|
8123
8015
|
const response = await fetch(url.toString(), {
|
|
8124
8016
|
method: "GET",
|
|
8125
8017
|
headers: {
|
|
8126
|
-
Authorization: `Bearer ${token}`,
|
|
8018
|
+
Authorization: `Bearer ${context.token}`,
|
|
8127
8019
|
Accept: "text/event-stream",
|
|
8128
8020
|
"Cache-Control": "no-cache"
|
|
8129
8021
|
},
|
|
8130
|
-
signal:
|
|
8022
|
+
signal: context.signal
|
|
8131
8023
|
});
|
|
8132
8024
|
if (!response.ok) {
|
|
8133
8025
|
if (response.status === 401 || response.status === 403) {
|
|
@@ -8138,73 +8030,100 @@ function createSseTransport(options) {
|
|
|
8138
8030
|
if (!response.body) {
|
|
8139
8031
|
throw new Error("SSE response has no body");
|
|
8140
8032
|
}
|
|
8141
|
-
isConnected = true;
|
|
8142
|
-
consecutiveAuthFailures = 0;
|
|
8143
|
-
reconnectDelay = INITIAL_RECONNECT_DELAY_MS2;
|
|
8144
|
-
options.onStateChange?.("connected");
|
|
8145
8033
|
const isReconnect = hasConnectedOnce;
|
|
8146
8034
|
hasConnectedOnce = true;
|
|
8147
|
-
|
|
8035
|
+
context.markConnected();
|
|
8036
|
+
await syncActiveSubscriptions(context.token);
|
|
8148
8037
|
startSubscriptionRefresh();
|
|
8149
8038
|
if (isReconnect && activeSubscriptions.size > 0) {
|
|
8150
8039
|
options.onReconnect?.();
|
|
8151
8040
|
}
|
|
8152
|
-
await
|
|
8153
|
-
|
|
8154
|
-
|
|
8155
|
-
|
|
8156
|
-
|
|
8157
|
-
|
|
8158
|
-
|
|
8041
|
+
await chunkY4OD5SDF_cjs.consumeSseStream(response.body, context.signal, {
|
|
8042
|
+
onChunk: () => context.markActivity(),
|
|
8043
|
+
onEventBlock: (block) => processEventBlock(block, context.requestTokenRefresh)
|
|
8044
|
+
});
|
|
8045
|
+
}
|
|
8046
|
+
});
|
|
8047
|
+
async function connect(lastSyncId) {
|
|
8048
|
+
currentLastSyncId = lastSyncId;
|
|
8049
|
+
disconnect();
|
|
8050
|
+
await supervisor.start();
|
|
8051
|
+
}
|
|
8052
|
+
function disconnect() {
|
|
8053
|
+
supervisor.stop();
|
|
8054
|
+
isConnected = false;
|
|
8055
|
+
stopSubscriptionRefresh();
|
|
8056
|
+
if (lastLegacyState !== "disconnected") {
|
|
8057
|
+
lastLegacyState = "disconnected";
|
|
8159
8058
|
options.onStateChange?.("disconnected");
|
|
8160
|
-
if (shouldReconnect) {
|
|
8161
|
-
const isAuth = err instanceof AuthSseError;
|
|
8162
|
-
if (isAuth) {
|
|
8163
|
-
consecutiveAuthFailures++;
|
|
8164
|
-
if (consecutiveAuthFailures >= MAX_CONSECUTIVE_AUTH_FAILURES2) {
|
|
8165
|
-
disconnect();
|
|
8166
|
-
return;
|
|
8167
|
-
}
|
|
8168
|
-
needsForceRefresh = true;
|
|
8169
|
-
}
|
|
8170
|
-
const delay = isAuth ? INITIAL_RECONNECT_DELAY_MS2 : reconnectDelay;
|
|
8171
|
-
reconnectTimer = setTimeout(() => {
|
|
8172
|
-
doConnect();
|
|
8173
|
-
}, delay);
|
|
8174
|
-
if (!isAuth) {
|
|
8175
|
-
reconnectDelay = Math.min(reconnectDelay * RECONNECT_BACKOFF_MULTIPLIER2, MAX_RECONNECT_DELAY_MS2);
|
|
8176
|
-
}
|
|
8177
|
-
}
|
|
8178
8059
|
}
|
|
8179
8060
|
}
|
|
8180
|
-
|
|
8181
|
-
|
|
8182
|
-
|
|
8183
|
-
|
|
8184
|
-
|
|
8185
|
-
|
|
8186
|
-
|
|
8187
|
-
if (done) break;
|
|
8188
|
-
buffer += decoder.decode(value, { stream: true });
|
|
8189
|
-
const parts = buffer.split(/(?:\r\n|\r|\n){2}/);
|
|
8190
|
-
buffer = parts.pop() ?? "";
|
|
8191
|
-
for (const part of parts) {
|
|
8192
|
-
processEventBlock(part.trim());
|
|
8193
|
-
}
|
|
8194
|
-
}
|
|
8195
|
-
} finally {
|
|
8196
|
-
reader.releaseLock();
|
|
8061
|
+
function reconnect() {
|
|
8062
|
+
supervisor.reconnect();
|
|
8063
|
+
}
|
|
8064
|
+
function subscribe(descriptor) {
|
|
8065
|
+
activeSubscriptions.set(descriptor.id, descriptor);
|
|
8066
|
+
if (isConnected) {
|
|
8067
|
+
startSubscriptionRefresh();
|
|
8197
8068
|
}
|
|
8198
|
-
|
|
8199
|
-
|
|
8069
|
+
void postMessage({ type: "subscribe", subscription: descriptor });
|
|
8070
|
+
}
|
|
8071
|
+
function unsubscribe(subscriptionId) {
|
|
8072
|
+
activeSubscriptions.delete(subscriptionId);
|
|
8073
|
+
if (activeSubscriptions.size === 0) {
|
|
8200
8074
|
stopSubscriptionRefresh();
|
|
8201
|
-
options.onStateChange?.("disconnected");
|
|
8202
|
-
reconnectTimer = setTimeout(() => {
|
|
8203
|
-
doConnect();
|
|
8204
|
-
}, reconnectDelay);
|
|
8205
8075
|
}
|
|
8076
|
+
void postMessage({ type: "unsubscribe", subscriptionId });
|
|
8077
|
+
}
|
|
8078
|
+
function startSubscriptionRefresh() {
|
|
8079
|
+
if (!isConnected || activeSubscriptions.size === 0 || refreshTimer) {
|
|
8080
|
+
return;
|
|
8081
|
+
}
|
|
8082
|
+
refreshTimer = setInterval(() => {
|
|
8083
|
+
void syncActiveSubscriptions();
|
|
8084
|
+
}, SUBSCRIPTION_REFRESH_INTERVAL_MS);
|
|
8085
|
+
}
|
|
8086
|
+
function stopSubscriptionRefresh() {
|
|
8087
|
+
if (!refreshTimer) {
|
|
8088
|
+
return;
|
|
8089
|
+
}
|
|
8090
|
+
clearInterval(refreshTimer);
|
|
8091
|
+
refreshTimer = void 0;
|
|
8092
|
+
}
|
|
8093
|
+
async function syncActiveSubscriptions(token) {
|
|
8094
|
+
if (activeSubscriptions.size === 0) {
|
|
8095
|
+
return;
|
|
8096
|
+
}
|
|
8097
|
+
const resolvedToken = token ?? await options.getToken().catch(() => void 0);
|
|
8098
|
+
if (!resolvedToken) {
|
|
8099
|
+
return;
|
|
8100
|
+
}
|
|
8101
|
+
await Promise.all(
|
|
8102
|
+
Array.from(activeSubscriptions.values()).map(
|
|
8103
|
+
(descriptor) => postMessage({ type: "subscribe", subscription: descriptor }, resolvedToken).catch(() => {
|
|
8104
|
+
})
|
|
8105
|
+
)
|
|
8106
|
+
);
|
|
8206
8107
|
}
|
|
8207
|
-
function
|
|
8108
|
+
async function postMessage(body, token) {
|
|
8109
|
+
let resolvedToken = token ?? await options.getToken();
|
|
8110
|
+
const url = new URL(options.url);
|
|
8111
|
+
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
8112
|
+
const response = await fetch(url.toString(), {
|
|
8113
|
+
method: "POST",
|
|
8114
|
+
headers: {
|
|
8115
|
+
Authorization: `Bearer ${resolvedToken}`,
|
|
8116
|
+
"Content-Type": "application/json"
|
|
8117
|
+
},
|
|
8118
|
+
body: JSON.stringify(body)
|
|
8119
|
+
});
|
|
8120
|
+
if (response.status !== 401 && response.status !== 403) {
|
|
8121
|
+
return;
|
|
8122
|
+
}
|
|
8123
|
+
resolvedToken = await chunkY4OD5SDF_cjs.refreshTokenSingleFlight(options.getToken, resolvedToken);
|
|
8124
|
+
}
|
|
8125
|
+
}
|
|
8126
|
+
function processEventBlock(block, requestTokenRefresh) {
|
|
8208
8127
|
if (!block || block.startsWith(":")) {
|
|
8209
8128
|
return;
|
|
8210
8129
|
}
|
|
@@ -8221,8 +8140,8 @@ function createSseTransport(options) {
|
|
|
8221
8140
|
}
|
|
8222
8141
|
}
|
|
8223
8142
|
if (eventType === "token-expired") {
|
|
8224
|
-
|
|
8225
|
-
|
|
8143
|
+
requestTokenRefresh();
|
|
8144
|
+
throw new AuthSseError(401);
|
|
8226
8145
|
}
|
|
8227
8146
|
if (eventType === "full-resync") {
|
|
8228
8147
|
options.onFullResync?.();
|
|
@@ -8239,7 +8158,9 @@ function createSseTransport(options) {
|
|
|
8239
8158
|
}
|
|
8240
8159
|
return;
|
|
8241
8160
|
}
|
|
8242
|
-
if (!eventId)
|
|
8161
|
+
if (!eventId) {
|
|
8162
|
+
return;
|
|
8163
|
+
}
|
|
8243
8164
|
currentLastSyncId = eventId;
|
|
8244
8165
|
if (eventType === "cursor") {
|
|
8245
8166
|
options.onCursor?.(eventId);
|
|
@@ -8256,82 +8177,10 @@ function createSseTransport(options) {
|
|
|
8256
8177
|
}
|
|
8257
8178
|
}
|
|
8258
8179
|
}
|
|
8259
|
-
function disconnect() {
|
|
8260
|
-
shouldReconnect = false;
|
|
8261
|
-
isConnected = false;
|
|
8262
|
-
stopSubscriptionRefresh();
|
|
8263
|
-
if (reconnectTimer) {
|
|
8264
|
-
clearTimeout(reconnectTimer);
|
|
8265
|
-
reconnectTimer = void 0;
|
|
8266
|
-
}
|
|
8267
|
-
if (abortController) {
|
|
8268
|
-
abortController.abort();
|
|
8269
|
-
abortController = void 0;
|
|
8270
|
-
}
|
|
8271
|
-
options.onStateChange?.("disconnected");
|
|
8272
|
-
}
|
|
8273
|
-
function subscribe(descriptor) {
|
|
8274
|
-
activeSubscriptions.set(descriptor.id, descriptor);
|
|
8275
|
-
if (isConnected) {
|
|
8276
|
-
startSubscriptionRefresh();
|
|
8277
|
-
}
|
|
8278
|
-
postMessage({ type: "subscribe", subscription: descriptor }).catch(() => {
|
|
8279
|
-
});
|
|
8280
|
-
}
|
|
8281
|
-
function unsubscribe(subscriptionId) {
|
|
8282
|
-
activeSubscriptions.delete(subscriptionId);
|
|
8283
|
-
if (activeSubscriptions.size === 0) {
|
|
8284
|
-
stopSubscriptionRefresh();
|
|
8285
|
-
}
|
|
8286
|
-
postMessage({ type: "unsubscribe", subscriptionId }).catch(() => {
|
|
8287
|
-
});
|
|
8288
|
-
}
|
|
8289
|
-
function startSubscriptionRefresh() {
|
|
8290
|
-
if (!isConnected || activeSubscriptions.size === 0 || refreshTimer) {
|
|
8291
|
-
return;
|
|
8292
|
-
}
|
|
8293
|
-
refreshTimer = setInterval(() => {
|
|
8294
|
-
syncActiveSubscriptions().catch(() => {
|
|
8295
|
-
});
|
|
8296
|
-
}, SUBSCRIPTION_REFRESH_INTERVAL_MS);
|
|
8297
|
-
}
|
|
8298
|
-
function stopSubscriptionRefresh() {
|
|
8299
|
-
if (!refreshTimer) {
|
|
8300
|
-
return;
|
|
8301
|
-
}
|
|
8302
|
-
clearInterval(refreshTimer);
|
|
8303
|
-
refreshTimer = void 0;
|
|
8304
|
-
}
|
|
8305
|
-
async function syncActiveSubscriptions(token) {
|
|
8306
|
-
if (activeSubscriptions.size === 0) {
|
|
8307
|
-
return;
|
|
8308
|
-
}
|
|
8309
|
-
const resolvedToken = token ?? await options.getToken().catch(() => void 0);
|
|
8310
|
-
if (!resolvedToken) {
|
|
8311
|
-
return;
|
|
8312
|
-
}
|
|
8313
|
-
await Promise.all(
|
|
8314
|
-
Array.from(activeSubscriptions.values()).map(
|
|
8315
|
-
(descriptor) => postMessage({ type: "subscribe", subscription: descriptor }, resolvedToken).catch(() => {
|
|
8316
|
-
})
|
|
8317
|
-
)
|
|
8318
|
-
);
|
|
8319
|
-
}
|
|
8320
|
-
async function postMessage(body, token) {
|
|
8321
|
-
const resolvedToken = token ?? await options.getToken();
|
|
8322
|
-
const url = new URL(options.url);
|
|
8323
|
-
await fetch(url.toString(), {
|
|
8324
|
-
method: "POST",
|
|
8325
|
-
headers: {
|
|
8326
|
-
Authorization: `Bearer ${resolvedToken}`,
|
|
8327
|
-
"Content-Type": "application/json"
|
|
8328
|
-
},
|
|
8329
|
-
body: JSON.stringify(body)
|
|
8330
|
-
});
|
|
8331
|
-
}
|
|
8332
8180
|
return {
|
|
8333
8181
|
connect,
|
|
8334
8182
|
disconnect,
|
|
8183
|
+
reconnect,
|
|
8335
8184
|
subscribe,
|
|
8336
8185
|
unsubscribe,
|
|
8337
8186
|
get connected() {
|
|
@@ -10242,6 +10091,8 @@ async function applyRemoteCacheEpoch(db, engine, syncPolicyUrl, getToken) {
|
|
|
10242
10091
|
function createLazySyncEngine(httpTransport, sseUrl, syncPolicyUrl, getToken, getDb) {
|
|
10243
10092
|
let realEngine;
|
|
10244
10093
|
let initPromise;
|
|
10094
|
+
let activeSseTransport;
|
|
10095
|
+
let shouldKeepSyncRunning = false;
|
|
10245
10096
|
async function getEngine() {
|
|
10246
10097
|
if (realEngine) return realEngine;
|
|
10247
10098
|
if (initPromise) return initPromise;
|
|
@@ -10274,10 +10125,12 @@ function createLazySyncEngine(httpTransport, sseUrl, syncPolicyUrl, getToken, ge
|
|
|
10274
10125
|
}
|
|
10275
10126
|
});
|
|
10276
10127
|
sseTransport = transport;
|
|
10128
|
+
activeSseTransport = transport;
|
|
10277
10129
|
}
|
|
10278
10130
|
realEngine = new SyncEngine({ db, httpTransport, sseTransport });
|
|
10279
10131
|
await applyRemoteCacheEpoch(db, realEngine, syncPolicyUrl, getToken);
|
|
10280
10132
|
if (sseTransport) {
|
|
10133
|
+
shouldKeepSyncRunning = true;
|
|
10281
10134
|
realEngine.startSync().catch(() => {
|
|
10282
10135
|
});
|
|
10283
10136
|
}
|
|
@@ -10323,11 +10176,19 @@ function createLazySyncEngine(httpTransport, sseUrl, syncPolicyUrl, getToken, ge
|
|
|
10323
10176
|
};
|
|
10324
10177
|
lazy.startSync = async function() {
|
|
10325
10178
|
const engine = await getEngine();
|
|
10179
|
+
shouldKeepSyncRunning = true;
|
|
10326
10180
|
return engine.startSync();
|
|
10327
10181
|
};
|
|
10328
10182
|
lazy.stopSync = function() {
|
|
10183
|
+
shouldKeepSyncRunning = false;
|
|
10329
10184
|
realEngine?.stopSync();
|
|
10330
10185
|
};
|
|
10186
|
+
lazy.reconnectActiveSync = function() {
|
|
10187
|
+
if (!shouldKeepSyncRunning) {
|
|
10188
|
+
return;
|
|
10189
|
+
}
|
|
10190
|
+
activeSseTransport?.reconnect();
|
|
10191
|
+
};
|
|
10331
10192
|
lazy.processSyncEvent = async function(event) {
|
|
10332
10193
|
const engine = await getEngine();
|
|
10333
10194
|
return engine.processSyncEvent(event);
|
|
@@ -10516,6 +10377,7 @@ function isBrowserRuntime() {
|
|
|
10516
10377
|
var DEFAULT_BASE_URL = "api.dvina.ai";
|
|
10517
10378
|
var DB_INIT_TOKEN_POLL_INTERVAL_MS = 100;
|
|
10518
10379
|
var DB_INIT_TOKEN_TIMEOUT_MS = 15e3;
|
|
10380
|
+
var LIFECYCLE_HINT_DEBOUNCE_MS = 250;
|
|
10519
10381
|
function resolveGetToken(options) {
|
|
10520
10382
|
if ("getToken" in options && options.getToken) {
|
|
10521
10383
|
return options.getToken;
|
|
@@ -10565,7 +10427,7 @@ function createDvinaClient(options) {
|
|
|
10565
10427
|
const getToken = resolveGetToken(options);
|
|
10566
10428
|
const getLanguage = resolveLanguage(options.language);
|
|
10567
10429
|
const getUserTimezone = resolveUserTimezone();
|
|
10568
|
-
const httpTransport =
|
|
10430
|
+
const httpTransport = chunkY4OD5SDF_cjs.createHttpTransport({
|
|
10569
10431
|
url: httpUrl,
|
|
10570
10432
|
getToken,
|
|
10571
10433
|
getLanguage,
|
|
@@ -10613,6 +10475,7 @@ function createDvinaClient(options) {
|
|
|
10613
10475
|
});
|
|
10614
10476
|
}
|
|
10615
10477
|
const syncEngine = createLazySyncEngine(httpTransport, sseUrl, syncPolicyUrl, getToken, getDb);
|
|
10478
|
+
const recoverableSyncEngine = syncEngine;
|
|
10616
10479
|
const request = async (document2, variables, _options) => {
|
|
10617
10480
|
return syncEngine.query(document2, variables);
|
|
10618
10481
|
};
|
|
@@ -10623,7 +10486,22 @@ function createDvinaClient(options) {
|
|
|
10623
10486
|
const billingBase = hasProtocol ? billingOverride.replace(/\/+$/, "") : `${httpProtocol}://${billingOverride ?? baseUrl.replace(/^api\./, "billing.")}`;
|
|
10624
10487
|
const billingHttpUrl = `${billingBase}/graphql`;
|
|
10625
10488
|
const billingSseUrl = `${billingBase}/subscriptions/stream`;
|
|
10626
|
-
const billing = new
|
|
10489
|
+
const billing = new chunkY4OD5SDF_cjs.BillingClient({ billingHttpUrl, billingSseUrl, getToken, onError: options.onError });
|
|
10490
|
+
let lifecycleHintTimer;
|
|
10491
|
+
const lifecycle = {
|
|
10492
|
+
hint(_reason) {
|
|
10493
|
+
if (lifecycleHintTimer) {
|
|
10494
|
+
return;
|
|
10495
|
+
}
|
|
10496
|
+
lifecycleHintTimer = setTimeout(() => {
|
|
10497
|
+
lifecycleHintTimer = void 0;
|
|
10498
|
+
recoverableSyncEngine.reconnectActiveSync();
|
|
10499
|
+
chatStream.reconnectAll();
|
|
10500
|
+
wsTransport?.terminate();
|
|
10501
|
+
billing.reconnectAll();
|
|
10502
|
+
}, LIFECYCLE_HINT_DEBOUNCE_MS);
|
|
10503
|
+
}
|
|
10504
|
+
};
|
|
10627
10505
|
return {
|
|
10628
10506
|
syncEngine,
|
|
10629
10507
|
request,
|
|
@@ -10641,6 +10519,7 @@ function createDvinaClient(options) {
|
|
|
10641
10519
|
},
|
|
10642
10520
|
inference,
|
|
10643
10521
|
billing,
|
|
10522
|
+
lifecycle,
|
|
10644
10523
|
baseUrl
|
|
10645
10524
|
};
|
|
10646
10525
|
}
|
|
@@ -10940,7 +10819,7 @@ function buildSmartQuery(baseDocument, rootFieldName, includes, baseVariables, i
|
|
|
10940
10819
|
}
|
|
10941
10820
|
const doc = cloneDocument(baseDocument);
|
|
10942
10821
|
const mergedVariables = { ...baseVariables };
|
|
10943
|
-
const opDef = doc.definitions.find((d) => d.kind ===
|
|
10822
|
+
const opDef = doc.definitions.find((d) => d.kind === chunkY4OD5SDF_cjs.Kind.OPERATION_DEFINITION);
|
|
10944
10823
|
if (!opDef) {
|
|
10945
10824
|
return { document: baseDocument, variables: baseVariables };
|
|
10946
10825
|
}
|
|
@@ -10950,7 +10829,7 @@ function buildSmartQuery(baseDocument, rootFieldName, includes, baseVariables, i
|
|
|
10950
10829
|
}
|
|
10951
10830
|
const existingFragments = /* @__PURE__ */ new Set();
|
|
10952
10831
|
for (const def of doc.definitions) {
|
|
10953
|
-
if (def.kind ===
|
|
10832
|
+
if (def.kind === chunkY4OD5SDF_cjs.Kind.FRAGMENT_DEFINITION) {
|
|
10954
10833
|
existingFragments.add(def.name.value);
|
|
10955
10834
|
}
|
|
10956
10835
|
}
|
|
@@ -10974,10 +10853,10 @@ function buildSmartQuery(baseDocument, rootFieldName, includes, baseVariables, i
|
|
|
10974
10853
|
}
|
|
10975
10854
|
if (isConnection && connectionIncludeFields.length > 0) {
|
|
10976
10855
|
const nodesWrapper = {
|
|
10977
|
-
kind:
|
|
10978
|
-
name: { kind:
|
|
10856
|
+
kind: chunkY4OD5SDF_cjs.Kind.FIELD,
|
|
10857
|
+
name: { kind: chunkY4OD5SDF_cjs.Kind.NAME, value: "nodes" },
|
|
10979
10858
|
selectionSet: {
|
|
10980
|
-
kind:
|
|
10859
|
+
kind: chunkY4OD5SDF_cjs.Kind.SELECTION_SET,
|
|
10981
10860
|
selections: connectionIncludeFields
|
|
10982
10861
|
}
|
|
10983
10862
|
};
|
|
@@ -10991,14 +10870,14 @@ function buildSmartQuery(baseDocument, rootFieldName, includes, baseVariables, i
|
|
|
10991
10870
|
function processIncludeDirective(include, prefix, opDef, mergedVariables, existingFragments, newDefinitions) {
|
|
10992
10871
|
const fieldArgs = buildPrefixedArguments(include.fieldArguments ?? [], prefix);
|
|
10993
10872
|
const fragmentDefs = include.fragmentDoc.definitions.filter(
|
|
10994
|
-
(d) => d.kind ===
|
|
10873
|
+
(d) => d.kind === chunkY4OD5SDF_cjs.Kind.FRAGMENT_DEFINITION
|
|
10995
10874
|
);
|
|
10996
10875
|
const mainFragment = fragmentDefs[0];
|
|
10997
10876
|
if (!mainFragment) return void 0;
|
|
10998
10877
|
const selections = [
|
|
10999
10878
|
{
|
|
11000
|
-
kind:
|
|
11001
|
-
name: { kind:
|
|
10879
|
+
kind: chunkY4OD5SDF_cjs.Kind.FRAGMENT_SPREAD,
|
|
10880
|
+
name: { kind: chunkY4OD5SDF_cjs.Kind.NAME, value: mainFragment.name.value }
|
|
11002
10881
|
}
|
|
11003
10882
|
];
|
|
11004
10883
|
if (include.children && include.children.length > 0) {
|
|
@@ -11020,10 +10899,10 @@ function processIncludeDirective(include, prefix, opDef, mergedVariables, existi
|
|
|
11020
10899
|
if (childFields.length > 0) {
|
|
11021
10900
|
if (include.isConnection) {
|
|
11022
10901
|
const nodesWrapper = {
|
|
11023
|
-
kind:
|
|
11024
|
-
name: { kind:
|
|
10902
|
+
kind: chunkY4OD5SDF_cjs.Kind.FIELD,
|
|
10903
|
+
name: { kind: chunkY4OD5SDF_cjs.Kind.NAME, value: "nodes" },
|
|
11025
10904
|
selectionSet: {
|
|
11026
|
-
kind:
|
|
10905
|
+
kind: chunkY4OD5SDF_cjs.Kind.SELECTION_SET,
|
|
11027
10906
|
selections: childFields
|
|
11028
10907
|
}
|
|
11029
10908
|
};
|
|
@@ -11034,11 +10913,11 @@ function processIncludeDirective(include, prefix, opDef, mergedVariables, existi
|
|
|
11034
10913
|
}
|
|
11035
10914
|
}
|
|
11036
10915
|
const includeField = {
|
|
11037
|
-
kind:
|
|
11038
|
-
name: { kind:
|
|
10916
|
+
kind: chunkY4OD5SDF_cjs.Kind.FIELD,
|
|
10917
|
+
name: { kind: chunkY4OD5SDF_cjs.Kind.NAME, value: include.fieldName },
|
|
11039
10918
|
arguments: fieldArgs.length > 0 ? fieldArgs : void 0,
|
|
11040
10919
|
selectionSet: {
|
|
11041
|
-
kind:
|
|
10920
|
+
kind: chunkY4OD5SDF_cjs.Kind.SELECTION_SET,
|
|
11042
10921
|
selections
|
|
11043
10922
|
}
|
|
11044
10923
|
};
|
|
@@ -11065,7 +10944,7 @@ function processIncludeDirective(include, prefix, opDef, mergedVariables, existi
|
|
|
11065
10944
|
}
|
|
11066
10945
|
function findFieldInSelectionSet(selectionSet, fieldName) {
|
|
11067
10946
|
for (const selection of selectionSet.selections) {
|
|
11068
|
-
if (selection.kind ===
|
|
10947
|
+
if (selection.kind === chunkY4OD5SDF_cjs.Kind.FIELD && selection.name.value === fieldName) {
|
|
11069
10948
|
return selection;
|
|
11070
10949
|
}
|
|
11071
10950
|
}
|
|
@@ -11079,7 +10958,7 @@ function buildPrefixedArguments(args, prefix) {
|
|
|
11079
10958
|
});
|
|
11080
10959
|
}
|
|
11081
10960
|
function prefixVariableReferences(node, prefix) {
|
|
11082
|
-
if (node["kind"] ===
|
|
10961
|
+
if (node["kind"] === chunkY4OD5SDF_cjs.Kind.VARIABLE && typeof node["name"]?.["value"] === "string") {
|
|
11083
10962
|
node["name"]["value"] = `${prefix}${node["name"]["value"]}`;
|
|
11084
10963
|
return;
|
|
11085
10964
|
}
|
|
@@ -11104,7 +10983,7 @@ function buildPrefixedVariableDefinitions(varDefs, prefix) {
|
|
|
11104
10983
|
}
|
|
11105
10984
|
function extractIncludeInfo(nestedDocument, nestedFieldName, parentVarNames) {
|
|
11106
10985
|
const opDef = nestedDocument.definitions.find(
|
|
11107
|
-
(d) => d.kind ===
|
|
10986
|
+
(d) => d.kind === chunkY4OD5SDF_cjs.Kind.OPERATION_DEFINITION
|
|
11108
10987
|
);
|
|
11109
10988
|
if (!opDef) {
|
|
11110
10989
|
return { variableDefinitions: [], fieldArguments: [] };
|
|
@@ -11116,7 +10995,7 @@ function extractIncludeInfo(nestedDocument, nestedFieldName, parentVarNames) {
|
|
|
11116
10995
|
let fieldArguments = [];
|
|
11117
10996
|
function findNestedField(selectionSet) {
|
|
11118
10997
|
for (const sel of selectionSet.selections) {
|
|
11119
|
-
if (sel.kind ===
|
|
10998
|
+
if (sel.kind === chunkY4OD5SDF_cjs.Kind.FIELD) {
|
|
11120
10999
|
if (sel.name.value === nestedFieldName && sel.arguments) {
|
|
11121
11000
|
fieldArguments = sel.arguments;
|
|
11122
11001
|
return;
|
|
@@ -22136,6 +22015,8 @@ var DvinaSdk = class extends chunk342BFYZZ_cjs.Request {
|
|
|
22136
22015
|
syncEngine;
|
|
22137
22016
|
/** Chat SSE client for chat-scoped stream listeners. */
|
|
22138
22017
|
chatStream;
|
|
22018
|
+
/** Semantic lifecycle bridge for connectivity and foreground recovery hints. */
|
|
22019
|
+
lifecycle;
|
|
22139
22020
|
_getToken;
|
|
22140
22021
|
_terminateWs;
|
|
22141
22022
|
_closeDb;
|
|
@@ -22144,10 +22025,11 @@ var DvinaSdk = class extends chunk342BFYZZ_cjs.Request {
|
|
|
22144
22025
|
/** Billing client for the Dvina Billing API (plans, subscriptions, seats, sessions). */
|
|
22145
22026
|
billing;
|
|
22146
22027
|
constructor(options) {
|
|
22147
|
-
const { syncEngine, request, subscribe, chatStream, getToken, terminateWs, closeDb, inference, billing, baseUrl } = createDvinaClient(options);
|
|
22028
|
+
const { syncEngine, request, subscribe, chatStream, lifecycle, getToken, terminateWs, closeDb, inference, billing, baseUrl } = createDvinaClient(options);
|
|
22148
22029
|
super(request, syncEngine, subscribe, baseUrl);
|
|
22149
22030
|
this.syncEngine = syncEngine;
|
|
22150
22031
|
this.chatStream = chatStream;
|
|
22032
|
+
this.lifecycle = lifecycle;
|
|
22151
22033
|
this._getToken = getToken;
|
|
22152
22034
|
this._terminateWs = terminateWs;
|
|
22153
22035
|
this._closeDb = closeDb;
|
|
@@ -23178,5 +23060,5 @@ exports.getOrCreateDatabase = getOrCreateDatabase;
|
|
|
23178
23060
|
exports.reconstructConnectionNodes = reconstructConnectionNodes;
|
|
23179
23061
|
exports.reconstructEntity = reconstructEntity;
|
|
23180
23062
|
exports.uploadFile = uploadFile;
|
|
23181
|
-
//# sourceMappingURL=chunk-
|
|
23182
|
-
//# sourceMappingURL=chunk-
|
|
23063
|
+
//# sourceMappingURL=chunk-XK5PW7IX.cjs.map
|
|
23064
|
+
//# sourceMappingURL=chunk-XK5PW7IX.cjs.map
|