@arbidocs/client 0.5.57 → 0.5.59
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 +122 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +48 -6
- package/dist/index.d.ts +48 -6
- package/dist/index.js +121 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -10,6 +10,90 @@ var sodium__default = /*#__PURE__*/_interopDefault(sodium);
|
|
|
10
10
|
|
|
11
11
|
// src/client.ts
|
|
12
12
|
|
|
13
|
+
// src/memory-persistence.ts
|
|
14
|
+
function copy(keys) {
|
|
15
|
+
return {
|
|
16
|
+
...keys,
|
|
17
|
+
signingPrivateKey: keys.signingPrivateKey.slice(),
|
|
18
|
+
...keys.serverSessionKey ? { serverSessionKey: keys.serverSessionKey.slice() } : {}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function createMemorySessionPersistence() {
|
|
22
|
+
let saved = null;
|
|
23
|
+
const clear = () => {
|
|
24
|
+
saved?.signingPrivateKey.fill(0);
|
|
25
|
+
saved?.serverSessionKey?.fill(0);
|
|
26
|
+
saved = null;
|
|
27
|
+
};
|
|
28
|
+
return {
|
|
29
|
+
async getSession() {
|
|
30
|
+
return saved ? copy(saved) : null;
|
|
31
|
+
},
|
|
32
|
+
async saveSession(keys) {
|
|
33
|
+
const next = copy(keys);
|
|
34
|
+
clear();
|
|
35
|
+
saved = next;
|
|
36
|
+
},
|
|
37
|
+
async clearSession() {
|
|
38
|
+
clear();
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// src/http-transport.ts
|
|
44
|
+
function createHttpTransport(options = {}) {
|
|
45
|
+
const { timeoutMs } = options;
|
|
46
|
+
if (timeoutMs !== void 0 && (!Number.isFinite(timeoutMs) || timeoutMs <= 0)) {
|
|
47
|
+
throw new RangeError("transport.timeoutMs must be a positive finite number.");
|
|
48
|
+
}
|
|
49
|
+
const wrap = (adapter2) => async (input, init) => {
|
|
50
|
+
const url = new URL(input instanceof Request ? input.url : String(input), "http://localhost");
|
|
51
|
+
url.username = "";
|
|
52
|
+
url.password = "";
|
|
53
|
+
url.search = "";
|
|
54
|
+
url.hash = "";
|
|
55
|
+
const info = {
|
|
56
|
+
method: (init?.method ?? (input instanceof Request ? input.method : "GET")).toUpperCase(),
|
|
57
|
+
url: url.toString()
|
|
58
|
+
};
|
|
59
|
+
options.onRequest?.(info);
|
|
60
|
+
const started = performance.now();
|
|
61
|
+
let timer;
|
|
62
|
+
let requestInit = init;
|
|
63
|
+
if (timeoutMs !== void 0) {
|
|
64
|
+
const controller = new AbortController();
|
|
65
|
+
const own = init?.signal ?? (input instanceof Request ? input.signal : void 0);
|
|
66
|
+
timer = setTimeout(
|
|
67
|
+
() => controller.abort(
|
|
68
|
+
new DOMException("Waiting for HTTP response timed out.", "TimeoutError")
|
|
69
|
+
),
|
|
70
|
+
timeoutMs
|
|
71
|
+
);
|
|
72
|
+
requestInit = {
|
|
73
|
+
...init,
|
|
74
|
+
signal: own ? AbortSignal.any([own, controller.signal]) : controller.signal
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
let response;
|
|
78
|
+
try {
|
|
79
|
+
response = await adapter2(input, requestInit);
|
|
80
|
+
} catch (error) {
|
|
81
|
+
options.onError?.({ ...info, error, durationMs: performance.now() - started });
|
|
82
|
+
throw error;
|
|
83
|
+
} finally {
|
|
84
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
85
|
+
}
|
|
86
|
+
options.onResponse?.({
|
|
87
|
+
...info,
|
|
88
|
+
status: response.status,
|
|
89
|
+
durationMs: performance.now() - started
|
|
90
|
+
});
|
|
91
|
+
return response;
|
|
92
|
+
};
|
|
93
|
+
const adapter = options.fetch ?? ((input, init) => globalThis.fetch(input, init));
|
|
94
|
+
return { fetch: wrap(adapter), customFetch: options.fetch !== void 0, withFetch: wrap };
|
|
95
|
+
}
|
|
96
|
+
|
|
13
97
|
// src/session.ts
|
|
14
98
|
function createInitialState(isSsoMode = false) {
|
|
15
99
|
return {
|
|
@@ -1161,11 +1245,11 @@ function createSessionGate() {
|
|
|
1161
1245
|
}
|
|
1162
1246
|
};
|
|
1163
1247
|
}
|
|
1164
|
-
function gatedFetch(gate,
|
|
1248
|
+
function gatedFetch(gate, fetch) {
|
|
1165
1249
|
return (input, init) => {
|
|
1166
1250
|
if (gate.closed) return Promise.reject(abortError());
|
|
1167
1251
|
const own = init?.signal ?? (input instanceof Request ? input.signal : void 0);
|
|
1168
|
-
return
|
|
1252
|
+
return fetch(input, { ...init, signal: eitherSignal(gate.signal, own) });
|
|
1169
1253
|
};
|
|
1170
1254
|
}
|
|
1171
1255
|
function createSessionGateMiddleware(gate) {
|
|
@@ -1379,7 +1463,7 @@ function createAutoReloginMiddleware(config) {
|
|
|
1379
1463
|
if (workspaceId) {
|
|
1380
1464
|
if (!await config.primeWorkspaceHandler(workspaceId)) return response;
|
|
1381
1465
|
const retry = cloneCache.get(request) ?? safeClone(request);
|
|
1382
|
-
if (retry) return fetch(retry);
|
|
1466
|
+
if (retry) return (config.fetch ?? globalThis.fetch)(retry);
|
|
1383
1467
|
config.onRetryCloneFailed?.();
|
|
1384
1468
|
return response;
|
|
1385
1469
|
}
|
|
@@ -1395,7 +1479,7 @@ function createAutoReloginMiddleware(config) {
|
|
|
1395
1479
|
const retry = cloneCache.get(request) ?? safeClone(request);
|
|
1396
1480
|
if (retry) {
|
|
1397
1481
|
if (token) retry.headers.set("Authorization", `Bearer ${token}`);
|
|
1398
|
-
return fetch(retry);
|
|
1482
|
+
return (config.fetch ?? globalThis.fetch)(retry);
|
|
1399
1483
|
}
|
|
1400
1484
|
config.onRetryCloneFailed?.();
|
|
1401
1485
|
return response;
|
|
@@ -1407,7 +1491,7 @@ function createAutoReloginMiddleware(config) {
|
|
|
1407
1491
|
if (newToken) {
|
|
1408
1492
|
const retryRequest = cloneCache.get(request) ?? request.clone();
|
|
1409
1493
|
retryRequest.headers.set("Authorization", `Bearer ${newToken}`);
|
|
1410
|
-
return fetch(retryRequest);
|
|
1494
|
+
return (config.fetch ?? globalThis.fetch)(retryRequest);
|
|
1411
1495
|
}
|
|
1412
1496
|
}
|
|
1413
1497
|
}
|
|
@@ -1420,12 +1504,12 @@ function createAutoReloginMiddleware(config) {
|
|
|
1420
1504
|
const cached = cloneCache.get(request);
|
|
1421
1505
|
if (cached) {
|
|
1422
1506
|
cached.headers.set("Authorization", `Bearer ${newToken}`);
|
|
1423
|
-
return fetch(cached);
|
|
1507
|
+
return (config.fetch ?? globalThis.fetch)(cached);
|
|
1424
1508
|
}
|
|
1425
1509
|
try {
|
|
1426
1510
|
const retryRequest = request.clone();
|
|
1427
1511
|
retryRequest.headers.set("Authorization", `Bearer ${newToken}`);
|
|
1428
|
-
return fetch(retryRequest);
|
|
1512
|
+
return (config.fetch ?? globalThis.fetch)(retryRequest);
|
|
1429
1513
|
} catch {
|
|
1430
1514
|
console.warn("[API] Could not retry request after re-login (body already consumed)");
|
|
1431
1515
|
config.onRetryCloneFailed?.();
|
|
@@ -1874,22 +1958,26 @@ var RETRYABLE_CODES = /* @__PURE__ */ new Set([
|
|
|
1874
1958
|
var MAX_RETRIES = 3;
|
|
1875
1959
|
var BASE_DELAY_MS = 200;
|
|
1876
1960
|
function isRetryableError(err) {
|
|
1877
|
-
if (!(err instanceof Error)) return false;
|
|
1961
|
+
if (!(err instanceof Error) || isAbortError(err)) return false;
|
|
1878
1962
|
const cause = err.cause;
|
|
1879
1963
|
if (cause?.code && RETRYABLE_CODES.has(cause.code)) return true;
|
|
1880
1964
|
const msg = err.message || "";
|
|
1881
1965
|
return RETRYABLE_CODES.has(msg) || msg.includes("ECONNREFUSED") || msg.includes("ECONNRESET");
|
|
1882
1966
|
}
|
|
1883
|
-
function createRetryFetch() {
|
|
1967
|
+
function createRetryFetch(fetch) {
|
|
1884
1968
|
return async (input, init) => {
|
|
1969
|
+
const method = (init?.method ?? (input instanceof Request ? input.method : "GET")).toUpperCase();
|
|
1970
|
+
const maxRetries = method === "GET" || method === "HEAD" ? MAX_RETRIES : 0;
|
|
1971
|
+
const signal = init?.signal ?? (input instanceof Request ? input.signal : void 0);
|
|
1885
1972
|
let lastError;
|
|
1886
|
-
for (let attempt = 0; attempt <=
|
|
1973
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
1974
|
+
if (signal?.aborted) throw signal.reason ?? new DOMException("Request aborted.", "AbortError");
|
|
1887
1975
|
try {
|
|
1888
1976
|
const fetchInput = input instanceof Request ? input.clone() : input;
|
|
1889
|
-
return await
|
|
1977
|
+
return await fetch(fetchInput, init);
|
|
1890
1978
|
} catch (err) {
|
|
1891
1979
|
lastError = err;
|
|
1892
|
-
if (attempt <
|
|
1980
|
+
if (attempt < maxRetries && isRetryableError(err)) {
|
|
1893
1981
|
await new Promise((r) => setTimeout(r, BASE_DELAY_MS * 2 ** attempt));
|
|
1894
1982
|
continue;
|
|
1895
1983
|
}
|
|
@@ -1911,9 +1999,9 @@ function readBaseUrlPerRequest(fetchClient, base) {
|
|
|
1911
1999
|
}
|
|
1912
2000
|
var deploymentDomainOf = ({ deploymentDomain }) => typeof deploymentDomain === "function" ? deploymentDomain() : deploymentDomain;
|
|
1913
2001
|
function createArbiClient(options) {
|
|
1914
|
-
const { fetch
|
|
2002
|
+
const { fetch, http, session, persistence, workspaceKeys, workspaceOpens, auth } = createTransport(options);
|
|
1915
2003
|
const authDeps = {
|
|
1916
|
-
fetchClient:
|
|
2004
|
+
fetchClient: fetch,
|
|
1917
2005
|
session,
|
|
1918
2006
|
get deploymentDomain() {
|
|
1919
2007
|
return deploymentDomainOf(options);
|
|
@@ -1922,7 +2010,8 @@ function createArbiClient(options) {
|
|
|
1922
2010
|
signIn: options.signIn
|
|
1923
2011
|
};
|
|
1924
2012
|
return {
|
|
1925
|
-
fetch
|
|
2013
|
+
fetch,
|
|
2014
|
+
http,
|
|
1926
2015
|
workspaceKeys,
|
|
1927
2016
|
workspaceOpens,
|
|
1928
2017
|
session,
|
|
@@ -1954,8 +2043,8 @@ function createArbiClient(options) {
|
|
|
1954
2043
|
decryptMessageWithSharedSecret
|
|
1955
2044
|
},
|
|
1956
2045
|
storage: {
|
|
1957
|
-
getSession,
|
|
1958
|
-
saveSession
|
|
2046
|
+
getSession: () => persistence.getSession(),
|
|
2047
|
+
saveSession: (data) => persistence.saveSession(data)
|
|
1959
2048
|
}
|
|
1960
2049
|
};
|
|
1961
2050
|
}
|
|
@@ -1969,12 +2058,18 @@ function createTransport(options) {
|
|
|
1969
2058
|
onRetryCloneFailed,
|
|
1970
2059
|
userEmail
|
|
1971
2060
|
} = options;
|
|
1972
|
-
const persistence = options.persistence ?? { getSession, saveSession };
|
|
2061
|
+
const persistence = options.persistence ?? (typeof indexedDB === "undefined" ? createMemorySessionPersistence() : { getSession, saveSession, clearSession: clearAllData });
|
|
1973
2062
|
const baseUrlOption = options.baseUrl;
|
|
1974
2063
|
const base = typeof baseUrlOption === "function" ? baseUrlOption : () => baseUrlOption;
|
|
1975
|
-
const
|
|
2064
|
+
const transport = createHttpTransport(options.transport);
|
|
2065
|
+
const retryFetch = createRetryFetch(transport.fetch);
|
|
1976
2066
|
const gate = createSessionGate();
|
|
1977
2067
|
const sessionFetch = gatedFetch(gate, retryFetch);
|
|
2068
|
+
const http = {
|
|
2069
|
+
fetch: gatedFetch(gate, transport.fetch),
|
|
2070
|
+
customFetch: transport.customFetch,
|
|
2071
|
+
withFetch: (adapter) => gatedFetch(gate, transport.withFetch(adapter))
|
|
2072
|
+
};
|
|
1978
2073
|
const session = options.session ?? createSessionManager();
|
|
1979
2074
|
if (userEmail) session.setUser(userEmail);
|
|
1980
2075
|
const tokenProvider = createTokenProvider(session);
|
|
@@ -2171,6 +2266,7 @@ function createTransport(options) {
|
|
|
2171
2266
|
for (const m of middleware) fetchClient.use(m);
|
|
2172
2267
|
fetchClient.use(
|
|
2173
2268
|
createAutoReloginMiddleware({
|
|
2269
|
+
fetch: sessionFetch,
|
|
2174
2270
|
reloginHandler: relogin,
|
|
2175
2271
|
reloginExcludePatterns,
|
|
2176
2272
|
reopenWorkspaceHandler: reopenWorkspace,
|
|
@@ -2186,6 +2282,7 @@ function createTransport(options) {
|
|
|
2186
2282
|
);
|
|
2187
2283
|
return {
|
|
2188
2284
|
fetch: fetchClient,
|
|
2285
|
+
http,
|
|
2189
2286
|
session,
|
|
2190
2287
|
persistence,
|
|
2191
2288
|
workspaceKeys,
|
|
@@ -2223,7 +2320,10 @@ function createTransport(options) {
|
|
|
2223
2320
|
}).catch((error) => console.warn("[API] Server logout failed:", error));
|
|
2224
2321
|
}
|
|
2225
2322
|
session.clear();
|
|
2226
|
-
if (everywhere)
|
|
2323
|
+
if (everywhere) {
|
|
2324
|
+
if (persistence.clearSession) await persistence.clearSession();
|
|
2325
|
+
else if (typeof indexedDB !== "undefined") await clearAllData();
|
|
2326
|
+
}
|
|
2227
2327
|
} finally {
|
|
2228
2328
|
gate.reopen();
|
|
2229
2329
|
}
|
|
@@ -2336,6 +2436,8 @@ exports.createAuthMessage = createAuthMessage;
|
|
|
2336
2436
|
exports.createAutoReloginMiddleware = createAutoReloginMiddleware;
|
|
2337
2437
|
exports.createBearerAuthMiddleware = createBearerAuthMiddleware;
|
|
2338
2438
|
exports.createContentHash = createContentHash;
|
|
2439
|
+
exports.createHttpTransport = createHttpTransport;
|
|
2440
|
+
exports.createMemorySessionPersistence = createMemorySessionPersistence;
|
|
2339
2441
|
exports.createOfflineSealer = createOfflineSealer;
|
|
2340
2442
|
exports.createRecoveryFile = createRecoveryFile;
|
|
2341
2443
|
exports.createRecoveryUrl = createRecoveryUrl;
|