@dvina/sdk 4.0.215 → 4.0.217

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.
Files changed (31) hide show
  1. package/dist/adapters/angular/index.cjs +4 -4
  2. package/dist/adapters/angular/index.d.cts +2 -2
  3. package/dist/adapters/angular/index.d.ts +2 -2
  4. package/dist/adapters/angular/index.js +2 -2
  5. package/dist/billing/index.cjs +5 -5
  6. package/dist/billing/index.js +1 -1
  7. package/dist/{chunk-Y4OD5SDF.cjs → chunk-5JLVHE5X.cjs} +2 -4
  8. package/dist/chunk-5JLVHE5X.cjs.map +1 -0
  9. package/dist/{chunk-Q5XGHH7D.js → chunk-GJXK5EID.js} +3 -3
  10. package/dist/chunk-GJXK5EID.js.map +1 -0
  11. package/dist/{chunk-BJDU4UX4.js → chunk-IM7TFRLL.js} +417 -220
  12. package/dist/chunk-IM7TFRLL.js.map +1 -0
  13. package/dist/{chunk-XK5PW7IX.cjs → chunk-SQ3TK5MI.cjs} +440 -243
  14. package/dist/chunk-SQ3TK5MI.cjs.map +1 -0
  15. package/dist/{client-Bn-0nJ8y.d.ts → client-B4c82App.d.ts} +1 -1
  16. package/dist/{client-Ca2wlmC4.d.cts → client-CluqWlY-.d.cts} +1 -1
  17. package/dist/{index-Ct2Mh0zl.d.cts → index-D2HJtzDx.d.cts} +1 -1
  18. package/dist/{index-D50r0Gl0.d.ts → index-DCrLPp9U.d.ts} +1 -1
  19. package/dist/index.cjs +387 -387
  20. package/dist/index.d.cts +6 -6
  21. package/dist/index.d.ts +6 -6
  22. package/dist/index.js +2 -2
  23. package/dist/pagination/index.d.cts +2 -2
  24. package/dist/pagination/index.d.ts +2 -2
  25. package/dist/{sync-engine-D35aV8Zc.d.ts → sync-engine-CBYlsAfA.d.ts} +1 -2
  26. package/dist/{sync-engine-21OlgS5_.d.cts → sync-engine-CvB6DrbK.d.cts} +1 -2
  27. package/package.json +1 -1
  28. package/dist/chunk-BJDU4UX4.js.map +0 -1
  29. package/dist/chunk-Q5XGHH7D.js.map +0 -1
  30. package/dist/chunk-XK5PW7IX.cjs.map +0 -1
  31. package/dist/chunk-Y4OD5SDF.cjs.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 chunkY4OD5SDF_cjs = require('./chunk-Y4OD5SDF.cjs');
5
+ var chunk5JLVHE5X_cjs = require('./chunk-5JLVHE5X.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,6 +6035,7 @@ 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;
6038
6039
  var MAX_CONSECUTIVE_AUTH_FAILURES = 3;
6039
6040
  var AuthChatStreamError = class extends Error {
6040
6041
  constructor(status) {
@@ -6048,63 +6049,24 @@ var ChatStreamConnection = class {
6048
6049
  this.chatId = chatId;
6049
6050
  this.options = options;
6050
6051
  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
- });
6096
6052
  }
6053
+ abortController;
6054
+ consecutiveAuthFailures = 0;
6097
6055
  destroyed = false;
6098
6056
  lastEventId;
6057
+ needsForceRefresh = false;
6058
+ reconnectDelay = INITIAL_RECONNECT_DELAY_MS;
6059
+ reconnectTimer;
6060
+ shouldReconnect = false;
6099
6061
  subscribers = /* @__PURE__ */ new Set();
6100
- supervisor;
6101
6062
  addSubscriber(subscriber) {
6102
6063
  if (this.destroyed) {
6103
6064
  throw new Error(`Chat stream '${this.chatId}' is closed`);
6104
6065
  }
6105
6066
  this.subscribers.add(subscriber);
6106
- if (this.subscribers.size === 1) {
6107
- void this.supervisor.start();
6067
+ if (!this.shouldReconnect) {
6068
+ this.shouldReconnect = true;
6069
+ void this.doConnect();
6108
6070
  }
6109
6071
  }
6110
6072
  removeSubscriber(subscriber) {
@@ -6114,17 +6076,30 @@ var ChatStreamConnection = class {
6114
6076
  }
6115
6077
  }
6116
6078
  reconnect() {
6117
- if (this.destroyed || this.subscribers.size === 0) {
6079
+ if (!this.shouldReconnect || this.destroyed || this.subscribers.size === 0) {
6118
6080
  return;
6119
6081
  }
6120
- this.supervisor.reconnect();
6082
+ if (this.reconnectTimer) {
6083
+ clearTimeout(this.reconnectTimer);
6084
+ this.reconnectTimer = void 0;
6085
+ }
6086
+ if (this.abortController) {
6087
+ this.abortController.abort();
6088
+ this.abortController = void 0;
6089
+ }
6090
+ void this.doConnect();
6121
6091
  }
6122
6092
  close(error) {
6123
- if (this.destroyed) {
6124
- return;
6125
- }
6093
+ this.shouldReconnect = false;
6126
6094
  this.destroyed = true;
6127
- this.supervisor.close();
6095
+ if (this.reconnectTimer) {
6096
+ clearTimeout(this.reconnectTimer);
6097
+ this.reconnectTimer = void 0;
6098
+ }
6099
+ if (this.abortController) {
6100
+ this.abortController.abort();
6101
+ this.abortController = void 0;
6102
+ }
6128
6103
  for (const subscriber of Array.from(this.subscribers)) {
6129
6104
  subscriber.finish(error);
6130
6105
  }
@@ -6134,7 +6109,94 @@ var ChatStreamConnection = class {
6134
6109
  get isDestroyed() {
6135
6110
  return this.destroyed;
6136
6111
  }
6137
- processEventBlock(block, requestTokenRefresh) {
6112
+ async doConnect() {
6113
+ if (!this.shouldReconnect || this.destroyed || this.subscribers.size === 0) {
6114
+ return;
6115
+ }
6116
+ this.abortController = new AbortController();
6117
+ try {
6118
+ const forceRefresh = this.needsForceRefresh;
6119
+ this.needsForceRefresh = false;
6120
+ const token = await this.options.getToken(forceRefresh ? { forceRefresh: true } : void 0);
6121
+ const url = new URL(`${this.options.baseUrl}/${encodeURIComponent(this.chatId)}/stream`);
6122
+ if (this.lastEventId) {
6123
+ url.searchParams.set("lastEventId", this.lastEventId);
6124
+ }
6125
+ const response = await fetch(url.toString(), {
6126
+ method: "GET",
6127
+ headers: {
6128
+ Accept: "text/event-stream",
6129
+ Authorization: `Bearer ${token}`,
6130
+ "Cache-Control": "no-cache",
6131
+ ...this.lastEventId ? { "Last-Event-ID": this.lastEventId } : {}
6132
+ },
6133
+ signal: this.abortController.signal
6134
+ });
6135
+ if (!response.ok) {
6136
+ if (response.status === 401 || response.status === 403) {
6137
+ throw new AuthChatStreamError(response.status);
6138
+ }
6139
+ throw new Error(`Chat stream connection failed: ${response.status} ${response.statusText}`);
6140
+ }
6141
+ if (!response.body) {
6142
+ throw new Error("Chat stream response has no body");
6143
+ }
6144
+ this.consecutiveAuthFailures = 0;
6145
+ this.reconnectDelay = INITIAL_RECONNECT_DELAY_MS;
6146
+ await this.parseSseStream(response.body, this.abortController.signal);
6147
+ } catch (error) {
6148
+ if (error.name === "AbortError") {
6149
+ return;
6150
+ }
6151
+ if (!this.shouldReconnect || this.destroyed || this.subscribers.size === 0) {
6152
+ return;
6153
+ }
6154
+ const isAuthError2 = error instanceof AuthChatStreamError;
6155
+ if (isAuthError2) {
6156
+ this.consecutiveAuthFailures += 1;
6157
+ if (this.consecutiveAuthFailures >= MAX_CONSECUTIVE_AUTH_FAILURES) {
6158
+ const authError = new chunkKV5SP7RP_cjs.DvinaAuthenticationError("Chat SSE stream authentication failed permanently");
6159
+ this.options.onError?.(authError);
6160
+ this.close(authError);
6161
+ return;
6162
+ }
6163
+ this.needsForceRefresh = true;
6164
+ }
6165
+ const delay = isAuthError2 ? INITIAL_RECONNECT_DELAY_MS : this.reconnectDelay;
6166
+ this.scheduleReconnect(delay);
6167
+ if (!isAuthError2) {
6168
+ this.reconnectDelay = Math.min(
6169
+ this.reconnectDelay * RECONNECT_BACKOFF_MULTIPLIER,
6170
+ MAX_RECONNECT_DELAY_MS
6171
+ );
6172
+ }
6173
+ }
6174
+ }
6175
+ async parseSseStream(body, signal) {
6176
+ const reader = body.getReader();
6177
+ const decoder = new TextDecoder();
6178
+ let buffer = "";
6179
+ try {
6180
+ while (!signal.aborted && this.shouldReconnect && !this.destroyed) {
6181
+ const { done, value } = await reader.read();
6182
+ if (done) {
6183
+ break;
6184
+ }
6185
+ buffer += decoder.decode(value, { stream: true });
6186
+ const parts = buffer.split(/(?:\r\n|\r|\n){2}/);
6187
+ buffer = parts.pop() ?? "";
6188
+ for (const part of parts) {
6189
+ this.processEventBlock(part.trim());
6190
+ }
6191
+ }
6192
+ } finally {
6193
+ reader.releaseLock();
6194
+ }
6195
+ if (this.shouldReconnect && !this.destroyed && this.subscribers.size > 0) {
6196
+ this.scheduleReconnect(this.reconnectDelay);
6197
+ }
6198
+ }
6199
+ processEventBlock(block) {
6138
6200
  if (!block || block.startsWith(":")) {
6139
6201
  return;
6140
6202
  }
@@ -6151,8 +6213,8 @@ var ChatStreamConnection = class {
6151
6213
  }
6152
6214
  }
6153
6215
  if (eventType === "token-expired") {
6154
- requestTokenRefresh();
6155
- throw new AuthChatStreamError(401);
6216
+ this.needsForceRefresh = true;
6217
+ return;
6156
6218
  }
6157
6219
  if (!eventId || dataLines.length === 0) {
6158
6220
  return;
@@ -6169,64 +6231,40 @@ var ChatStreamConnection = class {
6169
6231
  subscriber.push(value);
6170
6232
  }
6171
6233
  }
6234
+ scheduleReconnect(delay) {
6235
+ if (!this.shouldReconnect || this.destroyed || this.subscribers.size === 0) {
6236
+ return;
6237
+ }
6238
+ if (this.reconnectTimer) {
6239
+ clearTimeout(this.reconnectTimer);
6240
+ }
6241
+ this.reconnectTimer = setTimeout(() => {
6242
+ this.reconnectTimer = void 0;
6243
+ void this.doConnect();
6244
+ }, delay);
6245
+ }
6172
6246
  };
6173
6247
  var ActiveChatStreamConnection = class {
6174
6248
  constructor(options, onEmpty) {
6175
6249
  this.options = options;
6176
6250
  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
- });
6219
6251
  }
6252
+ abortController;
6253
+ consecutiveAuthFailures = 0;
6220
6254
  destroyed = false;
6255
+ needsForceRefresh = false;
6256
+ reconnectDelay = INITIAL_RECONNECT_DELAY_MS;
6257
+ reconnectTimer;
6258
+ shouldReconnect = false;
6221
6259
  subscribers = /* @__PURE__ */ new Set();
6222
- supervisor;
6223
6260
  addSubscriber(subscriber) {
6224
6261
  if (this.destroyed) {
6225
6262
  throw new Error("Active chat stream is closed");
6226
6263
  }
6227
6264
  this.subscribers.add(subscriber);
6228
- if (this.subscribers.size === 1) {
6229
- void this.supervisor.start();
6265
+ if (!this.shouldReconnect) {
6266
+ this.shouldReconnect = true;
6267
+ void this.doConnect();
6230
6268
  }
6231
6269
  }
6232
6270
  removeSubscriber(subscriber) {
@@ -6236,17 +6274,30 @@ var ActiveChatStreamConnection = class {
6236
6274
  }
6237
6275
  }
6238
6276
  reconnect() {
6239
- if (this.destroyed || this.subscribers.size === 0) {
6277
+ if (!this.shouldReconnect || this.destroyed || this.subscribers.size === 0) {
6240
6278
  return;
6241
6279
  }
6242
- this.supervisor.reconnect();
6280
+ if (this.reconnectTimer) {
6281
+ clearTimeout(this.reconnectTimer);
6282
+ this.reconnectTimer = void 0;
6283
+ }
6284
+ if (this.abortController) {
6285
+ this.abortController.abort();
6286
+ this.abortController = void 0;
6287
+ }
6288
+ void this.doConnect();
6243
6289
  }
6244
6290
  close(error) {
6245
- if (this.destroyed) {
6246
- return;
6247
- }
6291
+ this.shouldReconnect = false;
6248
6292
  this.destroyed = true;
6249
- this.supervisor.close();
6293
+ if (this.reconnectTimer) {
6294
+ clearTimeout(this.reconnectTimer);
6295
+ this.reconnectTimer = void 0;
6296
+ }
6297
+ if (this.abortController) {
6298
+ this.abortController.abort();
6299
+ this.abortController = void 0;
6300
+ }
6250
6301
  for (const subscriber of Array.from(this.subscribers)) {
6251
6302
  subscriber.finish(error);
6252
6303
  }
@@ -6256,7 +6307,91 @@ var ActiveChatStreamConnection = class {
6256
6307
  get isDestroyed() {
6257
6308
  return this.destroyed;
6258
6309
  }
6259
- processEventBlock(block, requestTokenRefresh) {
6310
+ async doConnect() {
6311
+ if (!this.shouldReconnect || this.destroyed || this.subscribers.size === 0) {
6312
+ return;
6313
+ }
6314
+ this.abortController = new AbortController();
6315
+ try {
6316
+ const forceRefresh = this.needsForceRefresh;
6317
+ this.needsForceRefresh = false;
6318
+ const token = await this.options.getToken(forceRefresh ? { forceRefresh: true } : void 0);
6319
+ const response = await fetch(new URL(`${this.options.baseUrl}/active`).toString(), {
6320
+ method: "GET",
6321
+ headers: {
6322
+ Accept: "text/event-stream",
6323
+ Authorization: `Bearer ${token}`,
6324
+ "Cache-Control": "no-cache"
6325
+ },
6326
+ signal: this.abortController.signal
6327
+ });
6328
+ if (!response.ok) {
6329
+ if (response.status === 401 || response.status === 403) {
6330
+ throw new AuthChatStreamError(response.status);
6331
+ }
6332
+ throw new Error(`Active chat stream connection failed: ${response.status} ${response.statusText}`);
6333
+ }
6334
+ if (!response.body) {
6335
+ throw new Error("Active chat stream response has no body");
6336
+ }
6337
+ this.consecutiveAuthFailures = 0;
6338
+ this.reconnectDelay = INITIAL_RECONNECT_DELAY_MS;
6339
+ await this.parseSseStream(response.body, this.abortController.signal);
6340
+ } catch (error) {
6341
+ if (error.name === "AbortError") {
6342
+ return;
6343
+ }
6344
+ if (!this.shouldReconnect || this.destroyed || this.subscribers.size === 0) {
6345
+ return;
6346
+ }
6347
+ const isAuthError2 = error instanceof AuthChatStreamError;
6348
+ if (isAuthError2) {
6349
+ this.consecutiveAuthFailures += 1;
6350
+ if (this.consecutiveAuthFailures >= MAX_CONSECUTIVE_AUTH_FAILURES) {
6351
+ const authError = new chunkKV5SP7RP_cjs.DvinaAuthenticationError(
6352
+ "Active chat SSE stream authentication failed permanently"
6353
+ );
6354
+ this.options.onError?.(authError);
6355
+ this.close(authError);
6356
+ return;
6357
+ }
6358
+ this.needsForceRefresh = true;
6359
+ }
6360
+ const delay = isAuthError2 ? INITIAL_RECONNECT_DELAY_MS : this.reconnectDelay;
6361
+ this.scheduleReconnect(delay);
6362
+ if (!isAuthError2) {
6363
+ this.reconnectDelay = Math.min(
6364
+ this.reconnectDelay * RECONNECT_BACKOFF_MULTIPLIER,
6365
+ MAX_RECONNECT_DELAY_MS
6366
+ );
6367
+ }
6368
+ }
6369
+ }
6370
+ async parseSseStream(body, signal) {
6371
+ const reader = body.getReader();
6372
+ const decoder = new TextDecoder();
6373
+ let buffer = "";
6374
+ try {
6375
+ while (!signal.aborted && this.shouldReconnect && !this.destroyed) {
6376
+ const { done, value } = await reader.read();
6377
+ if (done) {
6378
+ break;
6379
+ }
6380
+ buffer += decoder.decode(value, { stream: true });
6381
+ const parts = buffer.split(/(?:\r\n|\r|\n){2}/);
6382
+ buffer = parts.pop() ?? "";
6383
+ for (const part of parts) {
6384
+ this.processEventBlock(part.trim());
6385
+ }
6386
+ }
6387
+ } finally {
6388
+ reader.releaseLock();
6389
+ }
6390
+ if (this.shouldReconnect && !this.destroyed && this.subscribers.size > 0) {
6391
+ this.scheduleReconnect(this.reconnectDelay);
6392
+ }
6393
+ }
6394
+ processEventBlock(block) {
6260
6395
  if (!block || block.startsWith(":")) {
6261
6396
  return;
6262
6397
  }
@@ -6270,8 +6405,8 @@ var ActiveChatStreamConnection = class {
6270
6405
  }
6271
6406
  }
6272
6407
  if (eventType === "token-expired") {
6273
- requestTokenRefresh();
6274
- throw new AuthChatStreamError(401);
6408
+ this.needsForceRefresh = true;
6409
+ return;
6275
6410
  }
6276
6411
  if (eventType !== "active" || dataLines.length === 0) {
6277
6412
  return;
@@ -6290,6 +6425,18 @@ var ActiveChatStreamConnection = class {
6290
6425
  subscriber.push(value);
6291
6426
  }
6292
6427
  }
6428
+ scheduleReconnect(delay) {
6429
+ if (!this.shouldReconnect || this.destroyed || this.subscribers.size === 0) {
6430
+ return;
6431
+ }
6432
+ if (this.reconnectTimer) {
6433
+ clearTimeout(this.reconnectTimer);
6434
+ }
6435
+ this.reconnectTimer = setTimeout(() => {
6436
+ this.reconnectTimer = void 0;
6437
+ void this.doConnect();
6438
+ }, delay);
6439
+ }
6293
6440
  };
6294
6441
  function createChatStreamClient(options) {
6295
6442
  const connections = /* @__PURE__ */ new Map();
@@ -7227,7 +7374,7 @@ function createWsTransport(options) {
7227
7374
  let nextToken;
7228
7375
  let currentToken;
7229
7376
  async function refreshToken() {
7230
- const token = await chunkY4OD5SDF_cjs.refreshTokenSingleFlight(options.getToken, currentToken);
7377
+ const token = await chunk5JLVHE5X_cjs.refreshTokenSingleFlight(options.getToken, currentToken);
7231
7378
  if (!token) {
7232
7379
  throw new chunkKV5SP7RP_cjs.DvinaAuthenticationError("Token refresh did not produce a new token", currentToken);
7233
7380
  }
@@ -7279,7 +7426,7 @@ function createWsTransport(options) {
7279
7426
  }
7280
7427
  });
7281
7428
  function subscribe(document2, variables) {
7282
- const query = chunkY4OD5SDF_cjs.print(document2);
7429
+ const query = chunk5JLVHE5X_cjs.print(document2);
7283
7430
  const subscribeOnce = () => ({
7284
7431
  [Symbol.asyncIterator]() {
7285
7432
  const queue = [];
@@ -7967,47 +8114,44 @@ var AuthSseError = class extends Error {
7967
8114
  };
7968
8115
  var INITIAL_RECONNECT_DELAY_MS2 = 1e3;
7969
8116
  var MAX_RECONNECT_DELAY_MS2 = 3e4;
8117
+ var RECONNECT_BACKOFF_MULTIPLIER2 = 2;
7970
8118
  var MAX_CONSECUTIVE_AUTH_FAILURES2 = 3;
7971
8119
  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
- }
7981
8120
  function createSseTransport(options) {
8121
+ let abortController;
7982
8122
  let isConnected = false;
7983
- let currentLastSyncId;
8123
+ let reconnectDelay = INITIAL_RECONNECT_DELAY_MS2;
8124
+ let reconnectTimer;
7984
8125
  let refreshTimer;
8126
+ let shouldReconnect = false;
8127
+ let currentLastSyncId;
8128
+ let needsForceRefresh = false;
8129
+ let consecutiveAuthFailures = 0;
7985
8130
  let hasConnectedOnce = false;
7986
- let lastLegacyState;
7987
8131
  const activeSubscriptions = /* @__PURE__ */ new Map();
7988
- const emitLegacyState = (state) => {
7989
- const mapped = mapSupervisorState(state);
7990
- if (mapped === lastLegacyState) {
8132
+ async function connect(lastSyncId) {
8133
+ disconnect();
8134
+ shouldReconnect = true;
8135
+ currentLastSyncId = lastSyncId;
8136
+ await doConnect();
8137
+ }
8138
+ function reconnect() {
8139
+ const lastSyncId = currentLastSyncId;
8140
+ disconnect();
8141
+ shouldReconnect = true;
8142
+ currentLastSyncId = lastSyncId;
8143
+ void doConnect();
8144
+ }
8145
+ async function doConnect() {
8146
+ if (!shouldReconnect) {
7991
8147
  return;
7992
8148
  }
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) => {
8149
+ abortController = new AbortController();
8150
+ options.onStateChange?.("connecting");
8151
+ try {
8152
+ const forceRefresh = needsForceRefresh;
8153
+ needsForceRefresh = false;
8154
+ const token = await options.getToken(forceRefresh ? { forceRefresh: true } : void 0);
8011
8155
  const url = new URL(options.url);
8012
8156
  if (currentLastSyncId && currentLastSyncId !== "0") {
8013
8157
  url.searchParams.set("lastSyncId", currentLastSyncId);
@@ -8015,11 +8159,11 @@ function createSseTransport(options) {
8015
8159
  const response = await fetch(url.toString(), {
8016
8160
  method: "GET",
8017
8161
  headers: {
8018
- Authorization: `Bearer ${context.token}`,
8162
+ Authorization: `Bearer ${token}`,
8019
8163
  Accept: "text/event-stream",
8020
8164
  "Cache-Control": "no-cache"
8021
8165
  },
8022
- signal: context.signal
8166
+ signal: abortController.signal
8023
8167
  });
8024
8168
  if (!response.ok) {
8025
8169
  if (response.status === 401 || response.status === 403) {
@@ -8030,36 +8174,143 @@ function createSseTransport(options) {
8030
8174
  if (!response.body) {
8031
8175
  throw new Error("SSE response has no body");
8032
8176
  }
8177
+ isConnected = true;
8178
+ consecutiveAuthFailures = 0;
8179
+ reconnectDelay = INITIAL_RECONNECT_DELAY_MS2;
8180
+ options.onStateChange?.("connected");
8033
8181
  const isReconnect = hasConnectedOnce;
8034
8182
  hasConnectedOnce = true;
8035
- context.markConnected();
8036
- await syncActiveSubscriptions(context.token);
8183
+ await syncActiveSubscriptions(token);
8037
8184
  startSubscriptionRefresh();
8038
8185
  if (isReconnect && activeSubscriptions.size > 0) {
8039
8186
  options.onReconnect?.();
8040
8187
  }
8041
- await chunkY4OD5SDF_cjs.consumeSseStream(response.body, context.signal, {
8042
- onChunk: () => context.markActivity(),
8043
- onEventBlock: (block) => processEventBlock(block, context.requestTokenRefresh)
8044
- });
8188
+ await parseSseStream(response.body, abortController.signal);
8189
+ } catch (error) {
8190
+ if (error.name === "AbortError") {
8191
+ return;
8192
+ }
8193
+ isConnected = false;
8194
+ stopSubscriptionRefresh();
8195
+ options.onStateChange?.("disconnected");
8196
+ if (!shouldReconnect) {
8197
+ return;
8198
+ }
8199
+ const isAuthError2 = error instanceof AuthSseError;
8200
+ if (isAuthError2) {
8201
+ consecutiveAuthFailures += 1;
8202
+ if (consecutiveAuthFailures >= MAX_CONSECUTIVE_AUTH_FAILURES2) {
8203
+ disconnect();
8204
+ return;
8205
+ }
8206
+ needsForceRefresh = true;
8207
+ }
8208
+ const delay = isAuthError2 ? INITIAL_RECONNECT_DELAY_MS2 : reconnectDelay;
8209
+ reconnectTimer = setTimeout(() => {
8210
+ void doConnect();
8211
+ }, delay);
8212
+ if (!isAuthError2) {
8213
+ reconnectDelay = Math.min(reconnectDelay * RECONNECT_BACKOFF_MULTIPLIER2, MAX_RECONNECT_DELAY_MS2);
8214
+ }
8045
8215
  }
8046
- });
8047
- async function connect(lastSyncId) {
8048
- currentLastSyncId = lastSyncId;
8049
- disconnect();
8050
- await supervisor.start();
8051
8216
  }
8052
- function disconnect() {
8053
- supervisor.stop();
8217
+ async function parseSseStream(body, signal) {
8218
+ const reader = body.getReader();
8219
+ const decoder = new TextDecoder();
8220
+ let buffer = "";
8221
+ try {
8222
+ while (!signal.aborted) {
8223
+ const { done, value } = await reader.read();
8224
+ if (done) {
8225
+ break;
8226
+ }
8227
+ buffer += decoder.decode(value, { stream: true });
8228
+ const parts = buffer.split(/(?:\r\n|\r|\n){2}/);
8229
+ buffer = parts.pop() ?? "";
8230
+ for (const part of parts) {
8231
+ processEventBlock(part.trim());
8232
+ }
8233
+ }
8234
+ } finally {
8235
+ reader.releaseLock();
8236
+ }
8237
+ if (!shouldReconnect) {
8238
+ return;
8239
+ }
8054
8240
  isConnected = false;
8055
8241
  stopSubscriptionRefresh();
8056
- if (lastLegacyState !== "disconnected") {
8057
- lastLegacyState = "disconnected";
8058
- options.onStateChange?.("disconnected");
8242
+ options.onStateChange?.("disconnected");
8243
+ reconnectTimer = setTimeout(() => {
8244
+ void doConnect();
8245
+ }, reconnectDelay);
8246
+ }
8247
+ function processEventBlock(block) {
8248
+ if (!block || block.startsWith(":")) {
8249
+ return;
8250
+ }
8251
+ let eventId;
8252
+ let eventType;
8253
+ let eventData;
8254
+ for (const line of block.split(/\r\n|\r|\n/)) {
8255
+ if (line.startsWith("id: ")) {
8256
+ eventId = line.slice(4).trim();
8257
+ } else if (line.startsWith("event: ")) {
8258
+ eventType = line.slice(7).trim();
8259
+ } else if (line.startsWith("data: ")) {
8260
+ eventData = line.slice(6);
8261
+ }
8262
+ }
8263
+ if (eventType === "token-expired") {
8264
+ needsForceRefresh = true;
8265
+ return;
8266
+ }
8267
+ if (eventType === "full-resync") {
8268
+ options.onFullResync?.();
8269
+ return;
8270
+ }
8271
+ if ((eventType === "query-add" || eventType === "query-remove") && eventData) {
8272
+ try {
8273
+ const parsed = JSON.parse(eventData);
8274
+ options.onQueryEvent?.({
8275
+ type: eventType === "query-add" ? "add" : "remove",
8276
+ ...parsed
8277
+ });
8278
+ } catch {
8279
+ }
8280
+ return;
8281
+ }
8282
+ if (!eventId) {
8283
+ return;
8284
+ }
8285
+ currentLastSyncId = eventId;
8286
+ if (eventType === "cursor") {
8287
+ options.onCursor?.(eventId);
8288
+ return;
8289
+ }
8290
+ if (eventType === "sync" && eventData) {
8291
+ try {
8292
+ const parsed = JSON.parse(eventData);
8293
+ options.onEvent({
8294
+ id: eventId,
8295
+ ...parsed
8296
+ });
8297
+ } catch {
8298
+ }
8059
8299
  }
8060
8300
  }
8061
- function reconnect() {
8062
- supervisor.reconnect();
8301
+ function disconnect() {
8302
+ shouldReconnect = false;
8303
+ isConnected = false;
8304
+ stopSubscriptionRefresh();
8305
+ if (reconnectTimer) {
8306
+ clearTimeout(reconnectTimer);
8307
+ reconnectTimer = void 0;
8308
+ }
8309
+ if (abortController) {
8310
+ abortController.abort();
8311
+ abortController = void 0;
8312
+ }
8313
+ options.onStateChange?.("disconnected");
8063
8314
  }
8064
8315
  function subscribe(descriptor) {
8065
8316
  activeSubscriptions.set(descriptor.id, descriptor);
@@ -8120,61 +8371,7 @@ function createSseTransport(options) {
8120
8371
  if (response.status !== 401 && response.status !== 403) {
8121
8372
  return;
8122
8373
  }
8123
- resolvedToken = await chunkY4OD5SDF_cjs.refreshTokenSingleFlight(options.getToken, resolvedToken);
8124
- }
8125
- }
8126
- function processEventBlock(block, requestTokenRefresh) {
8127
- if (!block || block.startsWith(":")) {
8128
- return;
8129
- }
8130
- let eventId;
8131
- let eventType;
8132
- let eventData;
8133
- for (const line of block.split(/\r\n|\r|\n/)) {
8134
- if (line.startsWith("id: ")) {
8135
- eventId = line.slice(4).trim();
8136
- } else if (line.startsWith("event: ")) {
8137
- eventType = line.slice(7).trim();
8138
- } else if (line.startsWith("data: ")) {
8139
- eventData = line.slice(6);
8140
- }
8141
- }
8142
- if (eventType === "token-expired") {
8143
- requestTokenRefresh();
8144
- throw new AuthSseError(401);
8145
- }
8146
- if (eventType === "full-resync") {
8147
- options.onFullResync?.();
8148
- return;
8149
- }
8150
- if ((eventType === "query-add" || eventType === "query-remove") && eventData) {
8151
- try {
8152
- const parsed = JSON.parse(eventData);
8153
- options.onQueryEvent?.({
8154
- type: eventType === "query-add" ? "add" : "remove",
8155
- ...parsed
8156
- });
8157
- } catch {
8158
- }
8159
- return;
8160
- }
8161
- if (!eventId) {
8162
- return;
8163
- }
8164
- currentLastSyncId = eventId;
8165
- if (eventType === "cursor") {
8166
- options.onCursor?.(eventId);
8167
- return;
8168
- }
8169
- if (eventType === "sync" && eventData) {
8170
- try {
8171
- const parsed = JSON.parse(eventData);
8172
- options.onEvent({
8173
- id: eventId,
8174
- ...parsed
8175
- });
8176
- } catch {
8177
- }
8374
+ resolvedToken = await chunk5JLVHE5X_cjs.refreshTokenSingleFlight(options.getToken, resolvedToken);
8178
8375
  }
8179
8376
  }
8180
8377
  return {
@@ -10427,7 +10624,7 @@ function createDvinaClient(options) {
10427
10624
  const getToken = resolveGetToken(options);
10428
10625
  const getLanguage = resolveLanguage(options.language);
10429
10626
  const getUserTimezone = resolveUserTimezone();
10430
- const httpTransport = chunkY4OD5SDF_cjs.createHttpTransport({
10627
+ const httpTransport = chunk5JLVHE5X_cjs.createHttpTransport({
10431
10628
  url: httpUrl,
10432
10629
  getToken,
10433
10630
  getLanguage,
@@ -10486,7 +10683,7 @@ function createDvinaClient(options) {
10486
10683
  const billingBase = hasProtocol ? billingOverride.replace(/\/+$/, "") : `${httpProtocol}://${billingOverride ?? baseUrl.replace(/^api\./, "billing.")}`;
10487
10684
  const billingHttpUrl = `${billingBase}/graphql`;
10488
10685
  const billingSseUrl = `${billingBase}/subscriptions/stream`;
10489
- const billing = new chunkY4OD5SDF_cjs.BillingClient({ billingHttpUrl, billingSseUrl, getToken, onError: options.onError });
10686
+ const billing = new chunk5JLVHE5X_cjs.BillingClient({ billingHttpUrl, billingSseUrl, getToken, onError: options.onError });
10490
10687
  let lifecycleHintTimer;
10491
10688
  const lifecycle = {
10492
10689
  hint(_reason) {
@@ -10819,7 +11016,7 @@ function buildSmartQuery(baseDocument, rootFieldName, includes, baseVariables, i
10819
11016
  }
10820
11017
  const doc = cloneDocument(baseDocument);
10821
11018
  const mergedVariables = { ...baseVariables };
10822
- const opDef = doc.definitions.find((d) => d.kind === chunkY4OD5SDF_cjs.Kind.OPERATION_DEFINITION);
11019
+ const opDef = doc.definitions.find((d) => d.kind === chunk5JLVHE5X_cjs.Kind.OPERATION_DEFINITION);
10823
11020
  if (!opDef) {
10824
11021
  return { document: baseDocument, variables: baseVariables };
10825
11022
  }
@@ -10829,7 +11026,7 @@ function buildSmartQuery(baseDocument, rootFieldName, includes, baseVariables, i
10829
11026
  }
10830
11027
  const existingFragments = /* @__PURE__ */ new Set();
10831
11028
  for (const def of doc.definitions) {
10832
- if (def.kind === chunkY4OD5SDF_cjs.Kind.FRAGMENT_DEFINITION) {
11029
+ if (def.kind === chunk5JLVHE5X_cjs.Kind.FRAGMENT_DEFINITION) {
10833
11030
  existingFragments.add(def.name.value);
10834
11031
  }
10835
11032
  }
@@ -10853,10 +11050,10 @@ function buildSmartQuery(baseDocument, rootFieldName, includes, baseVariables, i
10853
11050
  }
10854
11051
  if (isConnection && connectionIncludeFields.length > 0) {
10855
11052
  const nodesWrapper = {
10856
- kind: chunkY4OD5SDF_cjs.Kind.FIELD,
10857
- name: { kind: chunkY4OD5SDF_cjs.Kind.NAME, value: "nodes" },
11053
+ kind: chunk5JLVHE5X_cjs.Kind.FIELD,
11054
+ name: { kind: chunk5JLVHE5X_cjs.Kind.NAME, value: "nodes" },
10858
11055
  selectionSet: {
10859
- kind: chunkY4OD5SDF_cjs.Kind.SELECTION_SET,
11056
+ kind: chunk5JLVHE5X_cjs.Kind.SELECTION_SET,
10860
11057
  selections: connectionIncludeFields
10861
11058
  }
10862
11059
  };
@@ -10870,14 +11067,14 @@ function buildSmartQuery(baseDocument, rootFieldName, includes, baseVariables, i
10870
11067
  function processIncludeDirective(include, prefix, opDef, mergedVariables, existingFragments, newDefinitions) {
10871
11068
  const fieldArgs = buildPrefixedArguments(include.fieldArguments ?? [], prefix);
10872
11069
  const fragmentDefs = include.fragmentDoc.definitions.filter(
10873
- (d) => d.kind === chunkY4OD5SDF_cjs.Kind.FRAGMENT_DEFINITION
11070
+ (d) => d.kind === chunk5JLVHE5X_cjs.Kind.FRAGMENT_DEFINITION
10874
11071
  );
10875
11072
  const mainFragment = fragmentDefs[0];
10876
11073
  if (!mainFragment) return void 0;
10877
11074
  const selections = [
10878
11075
  {
10879
- kind: chunkY4OD5SDF_cjs.Kind.FRAGMENT_SPREAD,
10880
- name: { kind: chunkY4OD5SDF_cjs.Kind.NAME, value: mainFragment.name.value }
11076
+ kind: chunk5JLVHE5X_cjs.Kind.FRAGMENT_SPREAD,
11077
+ name: { kind: chunk5JLVHE5X_cjs.Kind.NAME, value: mainFragment.name.value }
10881
11078
  }
10882
11079
  ];
10883
11080
  if (include.children && include.children.length > 0) {
@@ -10899,10 +11096,10 @@ function processIncludeDirective(include, prefix, opDef, mergedVariables, existi
10899
11096
  if (childFields.length > 0) {
10900
11097
  if (include.isConnection) {
10901
11098
  const nodesWrapper = {
10902
- kind: chunkY4OD5SDF_cjs.Kind.FIELD,
10903
- name: { kind: chunkY4OD5SDF_cjs.Kind.NAME, value: "nodes" },
11099
+ kind: chunk5JLVHE5X_cjs.Kind.FIELD,
11100
+ name: { kind: chunk5JLVHE5X_cjs.Kind.NAME, value: "nodes" },
10904
11101
  selectionSet: {
10905
- kind: chunkY4OD5SDF_cjs.Kind.SELECTION_SET,
11102
+ kind: chunk5JLVHE5X_cjs.Kind.SELECTION_SET,
10906
11103
  selections: childFields
10907
11104
  }
10908
11105
  };
@@ -10913,11 +11110,11 @@ function processIncludeDirective(include, prefix, opDef, mergedVariables, existi
10913
11110
  }
10914
11111
  }
10915
11112
  const includeField = {
10916
- kind: chunkY4OD5SDF_cjs.Kind.FIELD,
10917
- name: { kind: chunkY4OD5SDF_cjs.Kind.NAME, value: include.fieldName },
11113
+ kind: chunk5JLVHE5X_cjs.Kind.FIELD,
11114
+ name: { kind: chunk5JLVHE5X_cjs.Kind.NAME, value: include.fieldName },
10918
11115
  arguments: fieldArgs.length > 0 ? fieldArgs : void 0,
10919
11116
  selectionSet: {
10920
- kind: chunkY4OD5SDF_cjs.Kind.SELECTION_SET,
11117
+ kind: chunk5JLVHE5X_cjs.Kind.SELECTION_SET,
10921
11118
  selections
10922
11119
  }
10923
11120
  };
@@ -10944,7 +11141,7 @@ function processIncludeDirective(include, prefix, opDef, mergedVariables, existi
10944
11141
  }
10945
11142
  function findFieldInSelectionSet(selectionSet, fieldName) {
10946
11143
  for (const selection of selectionSet.selections) {
10947
- if (selection.kind === chunkY4OD5SDF_cjs.Kind.FIELD && selection.name.value === fieldName) {
11144
+ if (selection.kind === chunk5JLVHE5X_cjs.Kind.FIELD && selection.name.value === fieldName) {
10948
11145
  return selection;
10949
11146
  }
10950
11147
  }
@@ -10958,7 +11155,7 @@ function buildPrefixedArguments(args, prefix) {
10958
11155
  });
10959
11156
  }
10960
11157
  function prefixVariableReferences(node, prefix) {
10961
- if (node["kind"] === chunkY4OD5SDF_cjs.Kind.VARIABLE && typeof node["name"]?.["value"] === "string") {
11158
+ if (node["kind"] === chunk5JLVHE5X_cjs.Kind.VARIABLE && typeof node["name"]?.["value"] === "string") {
10962
11159
  node["name"]["value"] = `${prefix}${node["name"]["value"]}`;
10963
11160
  return;
10964
11161
  }
@@ -10983,7 +11180,7 @@ function buildPrefixedVariableDefinitions(varDefs, prefix) {
10983
11180
  }
10984
11181
  function extractIncludeInfo(nestedDocument, nestedFieldName, parentVarNames) {
10985
11182
  const opDef = nestedDocument.definitions.find(
10986
- (d) => d.kind === chunkY4OD5SDF_cjs.Kind.OPERATION_DEFINITION
11183
+ (d) => d.kind === chunk5JLVHE5X_cjs.Kind.OPERATION_DEFINITION
10987
11184
  );
10988
11185
  if (!opDef) {
10989
11186
  return { variableDefinitions: [], fieldArguments: [] };
@@ -10995,7 +11192,7 @@ function extractIncludeInfo(nestedDocument, nestedFieldName, parentVarNames) {
10995
11192
  let fieldArguments = [];
10996
11193
  function findNestedField(selectionSet) {
10997
11194
  for (const sel of selectionSet.selections) {
10998
- if (sel.kind === chunkY4OD5SDF_cjs.Kind.FIELD) {
11195
+ if (sel.kind === chunk5JLVHE5X_cjs.Kind.FIELD) {
10999
11196
  if (sel.name.value === nestedFieldName && sel.arguments) {
11000
11197
  fieldArguments = sel.arguments;
11001
11198
  return;
@@ -23060,5 +23257,5 @@ exports.getOrCreateDatabase = getOrCreateDatabase;
23060
23257
  exports.reconstructConnectionNodes = reconstructConnectionNodes;
23061
23258
  exports.reconstructEntity = reconstructEntity;
23062
23259
  exports.uploadFile = uploadFile;
23063
- //# sourceMappingURL=chunk-XK5PW7IX.cjs.map
23064
- //# sourceMappingURL=chunk-XK5PW7IX.cjs.map
23260
+ //# sourceMappingURL=chunk-SQ3TK5MI.cjs.map
23261
+ //# sourceMappingURL=chunk-SQ3TK5MI.cjs.map