@arbidocs/client 0.5.57 → 0.5.58

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/index.cjs CHANGED
@@ -10,6 +10,60 @@ var sodium__default = /*#__PURE__*/_interopDefault(sodium);
10
10
 
11
11
  // src/client.ts
12
12
 
13
+ // src/http-transport.ts
14
+ function createHttpTransport(options = {}) {
15
+ const { timeoutMs } = options;
16
+ if (timeoutMs !== void 0 && (!Number.isFinite(timeoutMs) || timeoutMs <= 0)) {
17
+ throw new RangeError("transport.timeoutMs must be a positive finite number.");
18
+ }
19
+ const wrap = (adapter2) => async (input, init) => {
20
+ const url = new URL(input instanceof Request ? input.url : String(input), "http://localhost");
21
+ url.username = "";
22
+ url.password = "";
23
+ url.search = "";
24
+ url.hash = "";
25
+ const info = {
26
+ method: (init?.method ?? (input instanceof Request ? input.method : "GET")).toUpperCase(),
27
+ url: url.toString()
28
+ };
29
+ options.onRequest?.(info);
30
+ const started = performance.now();
31
+ let timer;
32
+ let requestInit = init;
33
+ if (timeoutMs !== void 0) {
34
+ const controller = new AbortController();
35
+ const own = init?.signal ?? (input instanceof Request ? input.signal : void 0);
36
+ timer = setTimeout(
37
+ () => controller.abort(
38
+ new DOMException("Waiting for HTTP response timed out.", "TimeoutError")
39
+ ),
40
+ timeoutMs
41
+ );
42
+ requestInit = {
43
+ ...init,
44
+ signal: own ? AbortSignal.any([own, controller.signal]) : controller.signal
45
+ };
46
+ }
47
+ let response;
48
+ try {
49
+ response = await adapter2(input, requestInit);
50
+ } catch (error) {
51
+ options.onError?.({ ...info, error, durationMs: performance.now() - started });
52
+ throw error;
53
+ } finally {
54
+ if (timer !== void 0) clearTimeout(timer);
55
+ }
56
+ options.onResponse?.({
57
+ ...info,
58
+ status: response.status,
59
+ durationMs: performance.now() - started
60
+ });
61
+ return response;
62
+ };
63
+ const adapter = options.fetch ?? ((input, init) => globalThis.fetch(input, init));
64
+ return { fetch: wrap(adapter), customFetch: options.fetch !== void 0, withFetch: wrap };
65
+ }
66
+
13
67
  // src/session.ts
14
68
  function createInitialState(isSsoMode = false) {
15
69
  return {
@@ -1161,11 +1215,11 @@ function createSessionGate() {
1161
1215
  }
1162
1216
  };
1163
1217
  }
1164
- function gatedFetch(gate, fetch2) {
1218
+ function gatedFetch(gate, fetch) {
1165
1219
  return (input, init) => {
1166
1220
  if (gate.closed) return Promise.reject(abortError());
1167
1221
  const own = init?.signal ?? (input instanceof Request ? input.signal : void 0);
1168
- return fetch2(input, { ...init, signal: eitherSignal(gate.signal, own) });
1222
+ return fetch(input, { ...init, signal: eitherSignal(gate.signal, own) });
1169
1223
  };
1170
1224
  }
1171
1225
  function createSessionGateMiddleware(gate) {
@@ -1379,7 +1433,7 @@ function createAutoReloginMiddleware(config) {
1379
1433
  if (workspaceId) {
1380
1434
  if (!await config.primeWorkspaceHandler(workspaceId)) return response;
1381
1435
  const retry = cloneCache.get(request) ?? safeClone(request);
1382
- if (retry) return fetch(retry);
1436
+ if (retry) return (config.fetch ?? globalThis.fetch)(retry);
1383
1437
  config.onRetryCloneFailed?.();
1384
1438
  return response;
1385
1439
  }
@@ -1395,7 +1449,7 @@ function createAutoReloginMiddleware(config) {
1395
1449
  const retry = cloneCache.get(request) ?? safeClone(request);
1396
1450
  if (retry) {
1397
1451
  if (token) retry.headers.set("Authorization", `Bearer ${token}`);
1398
- return fetch(retry);
1452
+ return (config.fetch ?? globalThis.fetch)(retry);
1399
1453
  }
1400
1454
  config.onRetryCloneFailed?.();
1401
1455
  return response;
@@ -1407,7 +1461,7 @@ function createAutoReloginMiddleware(config) {
1407
1461
  if (newToken) {
1408
1462
  const retryRequest = cloneCache.get(request) ?? request.clone();
1409
1463
  retryRequest.headers.set("Authorization", `Bearer ${newToken}`);
1410
- return fetch(retryRequest);
1464
+ return (config.fetch ?? globalThis.fetch)(retryRequest);
1411
1465
  }
1412
1466
  }
1413
1467
  }
@@ -1420,12 +1474,12 @@ function createAutoReloginMiddleware(config) {
1420
1474
  const cached = cloneCache.get(request);
1421
1475
  if (cached) {
1422
1476
  cached.headers.set("Authorization", `Bearer ${newToken}`);
1423
- return fetch(cached);
1477
+ return (config.fetch ?? globalThis.fetch)(cached);
1424
1478
  }
1425
1479
  try {
1426
1480
  const retryRequest = request.clone();
1427
1481
  retryRequest.headers.set("Authorization", `Bearer ${newToken}`);
1428
- return fetch(retryRequest);
1482
+ return (config.fetch ?? globalThis.fetch)(retryRequest);
1429
1483
  } catch {
1430
1484
  console.warn("[API] Could not retry request after re-login (body already consumed)");
1431
1485
  config.onRetryCloneFailed?.();
@@ -1874,22 +1928,26 @@ var RETRYABLE_CODES = /* @__PURE__ */ new Set([
1874
1928
  var MAX_RETRIES = 3;
1875
1929
  var BASE_DELAY_MS = 200;
1876
1930
  function isRetryableError(err) {
1877
- if (!(err instanceof Error)) return false;
1931
+ if (!(err instanceof Error) || isAbortError(err)) return false;
1878
1932
  const cause = err.cause;
1879
1933
  if (cause?.code && RETRYABLE_CODES.has(cause.code)) return true;
1880
1934
  const msg = err.message || "";
1881
1935
  return RETRYABLE_CODES.has(msg) || msg.includes("ECONNREFUSED") || msg.includes("ECONNRESET");
1882
1936
  }
1883
- function createRetryFetch() {
1937
+ function createRetryFetch(fetch) {
1884
1938
  return async (input, init) => {
1939
+ const method = (init?.method ?? (input instanceof Request ? input.method : "GET")).toUpperCase();
1940
+ const maxRetries = method === "GET" || method === "HEAD" ? MAX_RETRIES : 0;
1941
+ const signal = init?.signal ?? (input instanceof Request ? input.signal : void 0);
1885
1942
  let lastError;
1886
- for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
1943
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
1944
+ if (signal?.aborted) throw signal.reason ?? new DOMException("Request aborted.", "AbortError");
1887
1945
  try {
1888
1946
  const fetchInput = input instanceof Request ? input.clone() : input;
1889
- return await globalThis.fetch(fetchInput, init);
1947
+ return await fetch(fetchInput, init);
1890
1948
  } catch (err) {
1891
1949
  lastError = err;
1892
- if (attempt < MAX_RETRIES && isRetryableError(err)) {
1950
+ if (attempt < maxRetries && isRetryableError(err)) {
1893
1951
  await new Promise((r) => setTimeout(r, BASE_DELAY_MS * 2 ** attempt));
1894
1952
  continue;
1895
1953
  }
@@ -1911,9 +1969,9 @@ function readBaseUrlPerRequest(fetchClient, base) {
1911
1969
  }
1912
1970
  var deploymentDomainOf = ({ deploymentDomain }) => typeof deploymentDomain === "function" ? deploymentDomain() : deploymentDomain;
1913
1971
  function createArbiClient(options) {
1914
- const { fetch: fetch2, session, persistence, workspaceKeys, workspaceOpens, auth } = createTransport(options);
1972
+ const { fetch, http, session, persistence, workspaceKeys, workspaceOpens, auth } = createTransport(options);
1915
1973
  const authDeps = {
1916
- fetchClient: fetch2,
1974
+ fetchClient: fetch,
1917
1975
  session,
1918
1976
  get deploymentDomain() {
1919
1977
  return deploymentDomainOf(options);
@@ -1922,7 +1980,8 @@ function createArbiClient(options) {
1922
1980
  signIn: options.signIn
1923
1981
  };
1924
1982
  return {
1925
- fetch: fetch2,
1983
+ fetch,
1984
+ http,
1926
1985
  workspaceKeys,
1927
1986
  workspaceOpens,
1928
1987
  session,
@@ -1972,9 +2031,15 @@ function createTransport(options) {
1972
2031
  const persistence = options.persistence ?? { getSession, saveSession };
1973
2032
  const baseUrlOption = options.baseUrl;
1974
2033
  const base = typeof baseUrlOption === "function" ? baseUrlOption : () => baseUrlOption;
1975
- const retryFetch = createRetryFetch();
2034
+ const transport = createHttpTransport(options.transport);
2035
+ const retryFetch = createRetryFetch(transport.fetch);
1976
2036
  const gate = createSessionGate();
1977
2037
  const sessionFetch = gatedFetch(gate, retryFetch);
2038
+ const http = {
2039
+ fetch: gatedFetch(gate, transport.fetch),
2040
+ customFetch: transport.customFetch,
2041
+ withFetch: (adapter) => gatedFetch(gate, transport.withFetch(adapter))
2042
+ };
1978
2043
  const session = options.session ?? createSessionManager();
1979
2044
  if (userEmail) session.setUser(userEmail);
1980
2045
  const tokenProvider = createTokenProvider(session);
@@ -2171,6 +2236,7 @@ function createTransport(options) {
2171
2236
  for (const m of middleware) fetchClient.use(m);
2172
2237
  fetchClient.use(
2173
2238
  createAutoReloginMiddleware({
2239
+ fetch: sessionFetch,
2174
2240
  reloginHandler: relogin,
2175
2241
  reloginExcludePatterns,
2176
2242
  reopenWorkspaceHandler: reopenWorkspace,
@@ -2186,6 +2252,7 @@ function createTransport(options) {
2186
2252
  );
2187
2253
  return {
2188
2254
  fetch: fetchClient,
2255
+ http,
2189
2256
  session,
2190
2257
  persistence,
2191
2258
  workspaceKeys,
@@ -2336,6 +2403,7 @@ exports.createAuthMessage = createAuthMessage;
2336
2403
  exports.createAutoReloginMiddleware = createAutoReloginMiddleware;
2337
2404
  exports.createBearerAuthMiddleware = createBearerAuthMiddleware;
2338
2405
  exports.createContentHash = createContentHash;
2406
+ exports.createHttpTransport = createHttpTransport;
2339
2407
  exports.createOfflineSealer = createOfflineSealer;
2340
2408
  exports.createRecoveryFile = createRecoveryFile;
2341
2409
  exports.createRecoveryUrl = createRecoveryUrl;