@enbox/dwn-clients 0.0.5 → 0.0.7
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/esm/dwn-registrar.js +87 -0
- package/dist/esm/dwn-registrar.js.map +1 -1
- package/dist/esm/http-dwn-rpc-client.js +145 -6
- package/dist/esm/http-dwn-rpc-client.js.map +1 -1
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/json-rpc-socket.js +187 -35
- package/dist/esm/json-rpc-socket.js.map +1 -1
- package/dist/esm/json-rpc.js +13 -0
- package/dist/esm/json-rpc.js.map +1 -1
- package/dist/esm/provider-directory-types.js +2 -0
- package/dist/esm/provider-directory-types.js.map +1 -0
- package/dist/esm/rate-limit-error.js +14 -0
- package/dist/esm/rate-limit-error.js.map +1 -0
- package/dist/esm/rpc-client.js +1 -1
- package/dist/esm/rpc-client.js.map +1 -1
- package/dist/esm/web-socket-clients.js +102 -16
- package/dist/esm/web-socket-clients.js.map +1 -1
- package/dist/types/dwn-registrar.d.ts +29 -0
- package/dist/types/dwn-registrar.d.ts.map +1 -1
- package/dist/types/dwn-rpc-types.d.ts +54 -4
- package/dist/types/dwn-rpc-types.d.ts.map +1 -1
- package/dist/types/http-dwn-rpc-client.d.ts +24 -2
- package/dist/types/http-dwn-rpc-client.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/json-rpc-socket.d.ts +63 -0
- package/dist/types/json-rpc-socket.d.ts.map +1 -1
- package/dist/types/json-rpc.d.ts +7 -1
- package/dist/types/json-rpc.d.ts.map +1 -1
- package/dist/types/provider-directory-types.d.ts +40 -0
- package/dist/types/provider-directory-types.d.ts.map +1 -0
- package/dist/types/rate-limit-error.d.ts +12 -0
- package/dist/types/rate-limit-error.d.ts.map +1 -0
- package/dist/types/registration-types.d.ts +46 -2
- package/dist/types/registration-types.d.ts.map +1 -1
- package/dist/types/server-info-types.d.ts +26 -0
- package/dist/types/server-info-types.d.ts.map +1 -1
- package/dist/types/web-socket-clients.d.ts +12 -2
- package/dist/types/web-socket-clients.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/dwn-registrar.ts +106 -3
- package/src/dwn-rpc-types.ts +69 -4
- package/src/http-dwn-rpc-client.ts +182 -6
- package/src/index.ts +2 -0
- package/src/json-rpc-socket.ts +244 -36
- package/src/json-rpc.ts +17 -0
- package/src/provider-directory-types.ts +41 -0
- package/src/rate-limit-error.ts +16 -0
- package/src/registration-types.ts +50 -3
- package/src/rpc-client.ts +1 -1
- package/src/server-info-types.ts +27 -0
- package/src/web-socket-clients.ts +156 -20
|
@@ -27,6 +27,7 @@ export class DwnRegistrar {
|
|
|
27
27
|
// fetch the terms-of-service
|
|
28
28
|
const termsOfServiceGetResponse = yield fetch(termsOfUseEndpoint, {
|
|
29
29
|
method: 'GET',
|
|
30
|
+
signal: AbortSignal.timeout(30000),
|
|
30
31
|
});
|
|
31
32
|
if (termsOfServiceGetResponse.status !== 200) {
|
|
32
33
|
const statusCode = termsOfServiceGetResponse.status;
|
|
@@ -38,6 +39,7 @@ export class DwnRegistrar {
|
|
|
38
39
|
// fetch the proof-of-work challenge
|
|
39
40
|
const proofOfWorkChallengeGetResponse = yield fetch(proofOfWorkEndpoint, {
|
|
40
41
|
method: 'GET',
|
|
42
|
+
signal: AbortSignal.timeout(30000),
|
|
41
43
|
});
|
|
42
44
|
const { challengeNonce, maximumAllowedHashValue } = yield proofOfWorkChallengeGetResponse.json();
|
|
43
45
|
// create registration data based on the hash of the terms-of-service and the DID
|
|
@@ -63,6 +65,7 @@ export class DwnRegistrar {
|
|
|
63
65
|
method: 'POST',
|
|
64
66
|
headers: { 'Content-Type': 'application/json' },
|
|
65
67
|
body: JSON.stringify(registrationRequest),
|
|
68
|
+
signal: AbortSignal.timeout(30000),
|
|
66
69
|
});
|
|
67
70
|
if (registrationResponse.status !== 200) {
|
|
68
71
|
const statusCode = registrationResponse.status;
|
|
@@ -115,5 +118,89 @@ export class DwnRegistrar {
|
|
|
115
118
|
return hexString;
|
|
116
119
|
});
|
|
117
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Exchange an authorization code (from the provider's auth redirect) for a registration token.
|
|
123
|
+
* The wallet calls this after the user completes the provider's auth flow.
|
|
124
|
+
*
|
|
125
|
+
* @param tokenUrl - The provider's token endpoint URL (from ServerInfo.providerAuth.tokenUrl)
|
|
126
|
+
* @param code - The authorization code from the provider redirect
|
|
127
|
+
* @param redirectUri - The redirect URI used in the authorize request (must match exactly)
|
|
128
|
+
* @returns Token exchange response containing the registration token and optional refresh token
|
|
129
|
+
*/
|
|
130
|
+
static exchangeAuthCode(tokenUrl, code, redirectUri) {
|
|
131
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
132
|
+
const response = yield fetch(tokenUrl, {
|
|
133
|
+
method: 'POST',
|
|
134
|
+
headers: { 'Content-Type': 'application/json' },
|
|
135
|
+
body: JSON.stringify({
|
|
136
|
+
grantType: 'authorization_code',
|
|
137
|
+
code,
|
|
138
|
+
redirectUri,
|
|
139
|
+
}),
|
|
140
|
+
signal: AbortSignal.timeout(30000),
|
|
141
|
+
});
|
|
142
|
+
if (response.status !== 200) {
|
|
143
|
+
const errorText = yield response.text();
|
|
144
|
+
throw new Error(`DwnRegistrar: Token exchange failed (${response.status}): ${errorText}`);
|
|
145
|
+
}
|
|
146
|
+
return response.json();
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Refresh an expired registration token using a refresh token.
|
|
151
|
+
*
|
|
152
|
+
* @param refreshUrl - The provider's refresh endpoint URL (from ServerInfo.providerAuth.refreshUrl)
|
|
153
|
+
* @param refreshToken - The refresh token from a previous token exchange
|
|
154
|
+
* @returns New token exchange response with fresh registration token
|
|
155
|
+
*/
|
|
156
|
+
static refreshRegistrationToken(refreshUrl, refreshToken) {
|
|
157
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
158
|
+
const response = yield fetch(refreshUrl, {
|
|
159
|
+
method: 'POST',
|
|
160
|
+
headers: { 'Content-Type': 'application/json' },
|
|
161
|
+
body: JSON.stringify({
|
|
162
|
+
grantType: 'refresh_token',
|
|
163
|
+
refreshToken,
|
|
164
|
+
}),
|
|
165
|
+
signal: AbortSignal.timeout(30000),
|
|
166
|
+
});
|
|
167
|
+
if (response.status !== 200) {
|
|
168
|
+
const errorText = yield response.text();
|
|
169
|
+
throw new Error(`DwnRegistrar: Token refresh failed (${response.status}): ${errorText}`);
|
|
170
|
+
}
|
|
171
|
+
return response.json();
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Register a DID as a tenant on a DWN server using a provider auth registration token.
|
|
176
|
+
* This is the paid-tier alternative to the PoW-based {@link registerTenant}.
|
|
177
|
+
*
|
|
178
|
+
* @param dwnEndpoint - The DWN server base URL
|
|
179
|
+
* @param did - The DID to register as a tenant
|
|
180
|
+
* @param registrationToken - The opaque registration token from the provider
|
|
181
|
+
* @param termsOfServiceHash - Optional ToS hash if the server requires it alongside provider auth
|
|
182
|
+
*/
|
|
183
|
+
static registerTenantWithToken(dwnEndpoint, did, registrationToken, termsOfServiceHash) {
|
|
184
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
185
|
+
const registrationEndpoint = concatenateUrl(dwnEndpoint, 'registration');
|
|
186
|
+
const registrationRequest = {
|
|
187
|
+
providerAuth: { registrationToken },
|
|
188
|
+
registrationData: {
|
|
189
|
+
did,
|
|
190
|
+
termsOfServiceHash,
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
const response = yield fetch(registrationEndpoint, {
|
|
194
|
+
method: 'POST',
|
|
195
|
+
headers: { 'Content-Type': 'application/json' },
|
|
196
|
+
body: JSON.stringify(registrationRequest),
|
|
197
|
+
signal: AbortSignal.timeout(30000),
|
|
198
|
+
});
|
|
199
|
+
if (response.status !== 200) {
|
|
200
|
+
const errorText = yield response.text();
|
|
201
|
+
throw new Error(`DwnRegistrar: Provider auth registration failed (${response.status}): ${errorText}`);
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
}
|
|
118
205
|
}
|
|
119
206
|
//# sourceMappingURL=dwn-registrar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dwn-registrar.js","sourceRoot":"","sources":["../../src/dwn-registrar.ts"],"names":[],"mappings":";;;;;;;;;AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEpD;;GAEG;AACH,MAAM,OAAO,YAAY;IACvB;;;;OAIG;IACI,MAAM,CAAO,cAAc,CAAC,WAAmB,EAAE,GAAW;;YAEjE,MAAM,oBAAoB,GAAG,cAAc,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;YACzE,MAAM,kBAAkB,GAAG,cAAc,CAAC,oBAAoB,EAAE,kBAAkB,CAAC,CAAC;YACpF,MAAM,mBAAmB,GAAG,cAAc,CAAC,oBAAoB,EAAE,eAAe,CAAC,CAAC;YAElF,6BAA6B;YAC7B,MAAM,yBAAyB,GAAG,MAAM,KAAK,CAAC,kBAAkB,EAAE;gBAChE,MAAM,
|
|
1
|
+
{"version":3,"file":"dwn-registrar.js","sourceRoot":"","sources":["../../src/dwn-registrar.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,17 +10,88 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
import { CryptoUtils } from '@enbox/crypto';
|
|
11
11
|
import { DataStream } from '@enbox/dwn-sdk-js';
|
|
12
12
|
import { DwnServerInfoCacheMemory } from './dwn-server-info-cache-memory.js';
|
|
13
|
-
import {
|
|
13
|
+
import { RateLimitError } from './rate-limit-error.js';
|
|
14
|
+
import { createJsonRpcRequest, JsonRpcErrorCodes, parseJson } from './json-rpc.js';
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Retry configuration
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
/** Default number of retry attempts for transient HTTP failures. */
|
|
19
|
+
const DEFAULT_MAX_RETRIES = 3;
|
|
20
|
+
/** Base delay in milliseconds for exponential backoff. */
|
|
21
|
+
const DEFAULT_BASE_DELAY_MS = 500;
|
|
22
|
+
/** Maximum backoff delay in milliseconds. */
|
|
23
|
+
const DEFAULT_MAX_DELAY_MS = 10000;
|
|
24
|
+
/** Per-request timeout in milliseconds (prevents hung connections / SSRF). */
|
|
25
|
+
const DEFAULT_REQUEST_TIMEOUT_MS = 30000;
|
|
26
|
+
/** HTTP status codes that are considered retryable. */
|
|
27
|
+
const RETRYABLE_STATUS_CODES = new Set([408, 429, 500, 502, 503, 504]);
|
|
14
28
|
/**
|
|
15
|
-
*
|
|
29
|
+
* Determines whether a fetch error or HTTP response warrants a retry.
|
|
30
|
+
* Network errors (TypeError from fetch) and specific HTTP status codes are retryable.
|
|
31
|
+
*/
|
|
32
|
+
function isRetryable(error, response) {
|
|
33
|
+
if (error instanceof TypeError) {
|
|
34
|
+
// TypeError is thrown by fetch for network-level failures (DNS, connection refused, etc.).
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
if (response) {
|
|
38
|
+
return RETRYABLE_STATUS_CODES.has(response.status);
|
|
39
|
+
}
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Computes the backoff delay with jitter for a given attempt.
|
|
44
|
+
* Uses exponential backoff: `min(baseDelay * 2^attempt, maxDelay) * jitter`.
|
|
45
|
+
*/
|
|
46
|
+
function computeBackoffDelay(attempt, baseDelayMs, maxDelayMs) {
|
|
47
|
+
const exponentialDelay = Math.min(baseDelayMs * Math.pow(2, attempt), maxDelayMs);
|
|
48
|
+
const jitter = 0.5 + Math.random() * 0.5;
|
|
49
|
+
return exponentialDelay * jitter;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Parses a `retry-after` header value into milliseconds.
|
|
53
|
+
* Supports both delay-seconds (e.g. "120") and HTTP-date formats.
|
|
54
|
+
* Returns `undefined` if the header is absent or unparseable.
|
|
55
|
+
*/
|
|
56
|
+
function parseRetryAfterMs(response) {
|
|
57
|
+
const retryAfter = response.headers.get('retry-after');
|
|
58
|
+
if (retryAfter === null) {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
// Try as integer seconds first.
|
|
62
|
+
const seconds = Number(retryAfter);
|
|
63
|
+
if (!Number.isNaN(seconds) && seconds >= 0) {
|
|
64
|
+
return seconds * 1000;
|
|
65
|
+
}
|
|
66
|
+
// Try as HTTP-date.
|
|
67
|
+
const date = new Date(retryAfter);
|
|
68
|
+
if (!Number.isNaN(date.getTime())) {
|
|
69
|
+
const delayMs = date.getTime() - Date.now();
|
|
70
|
+
return delayMs > 0 ? delayMs : 0;
|
|
71
|
+
}
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* HTTP client that can be used to communicate with Dwn Servers.
|
|
76
|
+
*
|
|
77
|
+
* Supports automatic retry with exponential backoff and jitter for transient
|
|
78
|
+
* network errors and retryable HTTP status codes (408, 429, 500, 502, 503, 504).
|
|
79
|
+
* Respects the `Retry-After` response header when present.
|
|
16
80
|
*/
|
|
17
81
|
export class HttpDwnRpcClient {
|
|
18
|
-
constructor(serverInfoCache) {
|
|
82
|
+
constructor(serverInfoCache, retryOptions) {
|
|
83
|
+
var _a, _b, _c;
|
|
19
84
|
this.serverInfoCache = serverInfoCache !== null && serverInfoCache !== void 0 ? serverInfoCache : new DwnServerInfoCacheMemory();
|
|
85
|
+
this._retryOptions = {
|
|
86
|
+
maxRetries: (_a = retryOptions === null || retryOptions === void 0 ? void 0 : retryOptions.maxRetries) !== null && _a !== void 0 ? _a : DEFAULT_MAX_RETRIES,
|
|
87
|
+
baseDelayMs: (_b = retryOptions === null || retryOptions === void 0 ? void 0 : retryOptions.baseDelayMs) !== null && _b !== void 0 ? _b : DEFAULT_BASE_DELAY_MS,
|
|
88
|
+
maxDelayMs: (_c = retryOptions === null || retryOptions === void 0 ? void 0 : retryOptions.maxDelayMs) !== null && _c !== void 0 ? _c : DEFAULT_MAX_DELAY_MS,
|
|
89
|
+
};
|
|
20
90
|
}
|
|
21
91
|
get transportProtocols() { return ['http:', 'https:']; }
|
|
22
92
|
sendDwnRequest(request) {
|
|
23
93
|
return __awaiter(this, void 0, void 0, function* () {
|
|
94
|
+
var _a, _b, _c;
|
|
24
95
|
const requestId = CryptoUtils.randomUuid();
|
|
25
96
|
const jsonRpcRequest = createJsonRpcRequest(requestId, 'dwn.processMessage', {
|
|
26
97
|
target: request.targetDid,
|
|
@@ -41,7 +112,14 @@ export class HttpDwnRpcClient {
|
|
|
41
112
|
// TypeScript's built-in RequestInit does not include `duplex` yet.
|
|
42
113
|
fetchOpts.duplex = 'half';
|
|
43
114
|
}
|
|
44
|
-
const resp = yield
|
|
115
|
+
const resp = yield this.fetchWithRetry(request.dwnUrl, fetchOpts);
|
|
116
|
+
// After retries are exhausted, a 429 means we're still rate-limited.
|
|
117
|
+
// Per-IP 429s return plain JSON (not a JSON-RPC envelope), so we must
|
|
118
|
+
// check the status before attempting JSON-RPC parsing.
|
|
119
|
+
if (resp.status === 429) {
|
|
120
|
+
const retryAfter = parseInt((_a = resp.headers.get('retry-after')) !== null && _a !== void 0 ? _a : '1', 10);
|
|
121
|
+
throw new RateLimitError(retryAfter);
|
|
122
|
+
}
|
|
45
123
|
let dwnRpcResponse;
|
|
46
124
|
// When the server streams record data back, the JSON-RPC envelope is in the
|
|
47
125
|
// `dwn-response` header and the body is the raw data stream. Otherwise the
|
|
@@ -56,10 +134,18 @@ export class HttpDwnRpcClient {
|
|
|
56
134
|
}
|
|
57
135
|
else {
|
|
58
136
|
const responseBody = yield resp.text();
|
|
59
|
-
|
|
137
|
+
const jsonRpcResponse = parseJson(responseBody);
|
|
138
|
+
if (jsonRpcResponse == null) {
|
|
139
|
+
throw new Error(`failed to parse json rpc response. dwn url: ${request.dwnUrl}, status: ${resp.status}`);
|
|
140
|
+
}
|
|
141
|
+
dwnRpcResponse = jsonRpcResponse;
|
|
60
142
|
}
|
|
61
143
|
if (dwnRpcResponse.error) {
|
|
62
144
|
const { code, message } = dwnRpcResponse.error;
|
|
145
|
+
if (code === JsonRpcErrorCodes.TooManyRequests) {
|
|
146
|
+
const retryAfter = (_c = (_b = dwnRpcResponse.error.data) === null || _b === void 0 ? void 0 : _b.retryAfterSec) !== null && _c !== void 0 ? _c : 1;
|
|
147
|
+
throw new RateLimitError(retryAfter);
|
|
148
|
+
}
|
|
63
149
|
throw new Error(`(${code}) - ${message}`);
|
|
64
150
|
}
|
|
65
151
|
// Materialise the response body before attaching to the reply.
|
|
@@ -84,6 +170,7 @@ export class HttpDwnRpcClient {
|
|
|
84
170
|
}
|
|
85
171
|
getServerInfo(dwnUrl) {
|
|
86
172
|
return __awaiter(this, void 0, void 0, function* () {
|
|
173
|
+
var _a;
|
|
87
174
|
const serverInfo = yield this.serverInfoCache.get(dwnUrl);
|
|
88
175
|
if (serverInfo) {
|
|
89
176
|
return serverInfo;
|
|
@@ -92,7 +179,11 @@ export class HttpDwnRpcClient {
|
|
|
92
179
|
// add `/info` to the dwn server url path
|
|
93
180
|
url.pathname.endsWith('/') ? url.pathname += 'info' : url.pathname += '/info';
|
|
94
181
|
try {
|
|
95
|
-
const response = yield
|
|
182
|
+
const response = yield this.fetchWithRetry(url.toString());
|
|
183
|
+
if (response.status === 429) {
|
|
184
|
+
const retryAfter = parseInt((_a = response.headers.get('retry-after')) !== null && _a !== void 0 ? _a : '1', 10);
|
|
185
|
+
throw new RateLimitError(retryAfter);
|
|
186
|
+
}
|
|
96
187
|
if (response.ok) {
|
|
97
188
|
const results = yield response.json();
|
|
98
189
|
const serverInfo = {
|
|
@@ -116,5 +207,53 @@ export class HttpDwnRpcClient {
|
|
|
116
207
|
}
|
|
117
208
|
});
|
|
118
209
|
}
|
|
210
|
+
// ---------------------------------------------------------------------------
|
|
211
|
+
// Retry logic
|
|
212
|
+
// ---------------------------------------------------------------------------
|
|
213
|
+
/**
|
|
214
|
+
* Wrapper around `fetch()` that retries on transient network errors and
|
|
215
|
+
* retryable HTTP status codes with exponential backoff and jitter.
|
|
216
|
+
* Honours the `Retry-After` response header when present.
|
|
217
|
+
*/
|
|
218
|
+
fetchWithRetry(url, init) {
|
|
219
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
220
|
+
const { maxRetries, baseDelayMs, maxDelayMs } = this._retryOptions;
|
|
221
|
+
let lastError;
|
|
222
|
+
let lastResponse;
|
|
223
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
224
|
+
try {
|
|
225
|
+
// Apply a per-attempt timeout to prevent hung connections / SSRF.
|
|
226
|
+
// If the caller already supplied a signal, combine it with the timeout
|
|
227
|
+
// via AbortSignal.any(); otherwise create a fresh timeout signal.
|
|
228
|
+
const timeoutSignal = AbortSignal.timeout(DEFAULT_REQUEST_TIMEOUT_MS);
|
|
229
|
+
const attemptInit = Object.assign(Object.assign({}, init), { signal: (init === null || init === void 0 ? void 0 : init.signal)
|
|
230
|
+
? AbortSignal.any([init.signal, timeoutSignal])
|
|
231
|
+
: timeoutSignal });
|
|
232
|
+
const response = yield fetch(url, attemptInit);
|
|
233
|
+
if (!RETRYABLE_STATUS_CODES.has(response.status) || attempt === maxRetries) {
|
|
234
|
+
return response;
|
|
235
|
+
}
|
|
236
|
+
// Retryable status — back off and try again.
|
|
237
|
+
lastResponse = response;
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
if (!isRetryable(error) || attempt === maxRetries) {
|
|
241
|
+
throw error;
|
|
242
|
+
}
|
|
243
|
+
lastError = error;
|
|
244
|
+
}
|
|
245
|
+
// Compute the delay, preferring Retry-After when available.
|
|
246
|
+
const retryAfterMs = lastResponse ? parseRetryAfterMs(lastResponse) : undefined;
|
|
247
|
+
const backoffMs = computeBackoffDelay(attempt, baseDelayMs, maxDelayMs);
|
|
248
|
+
const delayMs = retryAfterMs !== undefined ? Math.max(retryAfterMs, backoffMs) : backoffMs;
|
|
249
|
+
yield new Promise((resolve) => { setTimeout(resolve, delayMs); });
|
|
250
|
+
}
|
|
251
|
+
// Should not reach here, but satisfy the compiler.
|
|
252
|
+
if (lastResponse) {
|
|
253
|
+
return lastResponse;
|
|
254
|
+
}
|
|
255
|
+
throw lastError;
|
|
256
|
+
});
|
|
257
|
+
}
|
|
119
258
|
}
|
|
120
259
|
//# sourceMappingURL=http-dwn-rpc-client.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-dwn-rpc-client.js","sourceRoot":"","sources":["../../src/http-dwn-rpc-client.ts"],"names":[],"mappings":";;;;;;;;;AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"http-dwn-rpc-client.js","sourceRoot":"","sources":["../../src/http-dwn-rpc-client.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/index.js
CHANGED
|
@@ -4,6 +4,8 @@ export * from './dwn-server-info-cache-memory.js';
|
|
|
4
4
|
export * from './http-dwn-rpc-client.js';
|
|
5
5
|
export * from './json-rpc.js';
|
|
6
6
|
export * from './json-rpc-socket.js';
|
|
7
|
+
export * from './provider-directory-types.js';
|
|
8
|
+
export * from './rate-limit-error.js';
|
|
7
9
|
export * from './registration-types.js';
|
|
8
10
|
export * from './rpc-client.js';
|
|
9
11
|
export * from './server-info-types.js';
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mCAAmC,CAAC;AAClD,cAAc,0BAA0B,CAAC;AACzC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,YAAY,CAAC;AAC3B,cAAc,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mCAAmC,CAAC;AAClD,cAAc,0BAA0B,CAAC;AACzC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,YAAY,CAAC;AAC3B,cAAc,yBAAyB,CAAC"}
|
|
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { CryptoUtils } from '@enbox/crypto';
|
|
11
|
-
import { createJsonRpcSubscriptionRequest, parseJson } from './json-rpc.js';
|
|
11
|
+
import { createJsonRpcSubscriptionRequest, JsonRpcErrorCodes, parseJson } from './json-rpc.js';
|
|
12
12
|
/**
|
|
13
13
|
* Converts WebSocket message data to a string.
|
|
14
14
|
* Bun's native WebSocket delivers `event.data` as an `ArrayBuffer`,
|
|
@@ -30,55 +30,71 @@ function toText(data) {
|
|
|
30
30
|
// These were arbitrarily chosen, but can be modified via connect options
|
|
31
31
|
const CONNECT_TIMEOUT = 3000;
|
|
32
32
|
const RESPONSE_TIMEOUT = 30000;
|
|
33
|
+
/** Default reconnection settings. */
|
|
34
|
+
const DEFAULT_BASE_RECONNECT_DELAY = 1000;
|
|
35
|
+
const DEFAULT_MAX_RECONNECT_DELAY = 30000;
|
|
36
|
+
const DEFAULT_MAX_RECONNECT_ATTEMPTS = Infinity;
|
|
33
37
|
/**
|
|
34
38
|
* JSON RPC Socket Client for WebSocket request/response and long-running subscriptions.
|
|
39
|
+
*
|
|
40
|
+
* Supports automatic reconnection with exponential backoff when the connection
|
|
41
|
+
* drops unexpectedly. Subscription message handlers survive reconnection — they
|
|
42
|
+
* are re-registered on the new underlying socket automatically.
|
|
35
43
|
*/
|
|
36
44
|
export class JsonRpcSocket {
|
|
37
|
-
constructor(socket, responseTimeout) {
|
|
45
|
+
constructor(socket, responseTimeout, url, options) {
|
|
38
46
|
this.socket = socket;
|
|
39
47
|
this.responseTimeout = responseTimeout;
|
|
48
|
+
/**
|
|
49
|
+
* Map of JSON-RPC id → message handler. For one-shot `request()` calls, the
|
|
50
|
+
* handler is added before sending and removed on response or timeout.
|
|
51
|
+
* For subscriptions, the handler lives until explicitly closed.
|
|
52
|
+
*/
|
|
40
53
|
this.messageHandlers = new Map();
|
|
54
|
+
/**
|
|
55
|
+
* Set of JSON-RPC ids that belong to subscription handlers (as opposed to
|
|
56
|
+
* one-shot request handlers). Subscription handlers survive reconnection;
|
|
57
|
+
* one-shot handlers are rejected on unexpected close.
|
|
58
|
+
*/
|
|
59
|
+
this.subscriptionHandlerIds = new Set();
|
|
60
|
+
/** Whether `close()` was called intentionally by the user. */
|
|
61
|
+
this.closedByUser = false;
|
|
62
|
+
/** Whether a reconnection attempt is currently in progress. */
|
|
63
|
+
this.reconnecting = false;
|
|
64
|
+
/** Whether the socket is currently connected. */
|
|
65
|
+
this._isConnected = false;
|
|
66
|
+
this.url = url;
|
|
67
|
+
this.options = options;
|
|
68
|
+
this._isConnected = true;
|
|
69
|
+
}
|
|
70
|
+
/** Whether the socket is currently connected. */
|
|
71
|
+
get isConnected() {
|
|
72
|
+
return this._isConnected;
|
|
41
73
|
}
|
|
42
74
|
static connect(url_1) {
|
|
43
75
|
return __awaiter(this, arguments, void 0, function* (url, options = {}) {
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
socket.onclose = onclose;
|
|
76
|
+
var _a;
|
|
77
|
+
const { connectTimeout = CONNECT_TIMEOUT, responseTimeout = RESPONSE_TIMEOUT } = options;
|
|
78
|
+
let socket;
|
|
79
|
+
try {
|
|
80
|
+
socket = yield JsonRpcSocket.createWebSocket(url, connectTimeout);
|
|
53
81
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
socket.onerror = onerror;
|
|
82
|
+
catch (error) {
|
|
83
|
+
// Notify the onerror handler if one was provided, even for connection-time errors.
|
|
84
|
+
(_a = options.onerror) === null || _a === void 0 ? void 0 : _a.call(options, error);
|
|
85
|
+
throw error;
|
|
61
86
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
socket.addEventListener('message', (event) => {
|
|
66
|
-
const jsonRpcResponse = parseJson(toText(event.data));
|
|
67
|
-
const handler = jsonRpcSocket.messageHandlers.get(jsonRpcResponse.id);
|
|
68
|
-
if (handler) {
|
|
69
|
-
handler(event);
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
resolve(jsonRpcSocket);
|
|
73
|
-
});
|
|
74
|
-
socket.addEventListener('error', (error) => {
|
|
75
|
-
reject(error);
|
|
76
|
-
});
|
|
77
|
-
setTimeout(() => reject(new Error('connect timed out')), connectTimeout);
|
|
78
|
-
});
|
|
87
|
+
const jsonRpcSocket = new JsonRpcSocket(socket, responseTimeout, url, options);
|
|
88
|
+
jsonRpcSocket.wireSocket(socket);
|
|
89
|
+
return jsonRpcSocket;
|
|
79
90
|
});
|
|
80
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Closes the socket and stops reconnection attempts.
|
|
94
|
+
*/
|
|
81
95
|
close() {
|
|
96
|
+
this.closedByUser = true;
|
|
97
|
+
this._isConnected = false;
|
|
82
98
|
this.socket.close();
|
|
83
99
|
}
|
|
84
100
|
/**
|
|
@@ -130,6 +146,7 @@ export class JsonRpcSocket {
|
|
|
130
146
|
if (jsonRpcResponse.error !== undefined) {
|
|
131
147
|
// remove the event listener upon receipt of a JSON RPC Error.
|
|
132
148
|
this.messageHandlers.delete(subscriptionId);
|
|
149
|
+
this.subscriptionHandlerIds.delete(subscriptionId);
|
|
133
150
|
this.closeSubscription(subscriptionId).catch(() => {
|
|
134
151
|
// swallow timeout errors; the subscription is already cleaned up locally.
|
|
135
152
|
});
|
|
@@ -138,6 +155,7 @@ export class JsonRpcSocket {
|
|
|
138
155
|
}
|
|
139
156
|
};
|
|
140
157
|
this.messageHandlers.set(subscriptionId, socketEventListener);
|
|
158
|
+
this.subscriptionHandlerIds.add(subscriptionId);
|
|
141
159
|
const response = yield this.request(request);
|
|
142
160
|
if (response.error) {
|
|
143
161
|
// Restore the previous handler if one existed, otherwise clean up.
|
|
@@ -146,12 +164,14 @@ export class JsonRpcSocket {
|
|
|
146
164
|
}
|
|
147
165
|
else {
|
|
148
166
|
this.messageHandlers.delete(subscriptionId);
|
|
167
|
+
this.subscriptionHandlerIds.delete(subscriptionId);
|
|
149
168
|
}
|
|
150
169
|
return { response };
|
|
151
170
|
}
|
|
152
171
|
// clean up listener and create a `rpc.subscribe.close` message to use when closing this JSON RPC subscription
|
|
153
172
|
const close = () => __awaiter(this, void 0, void 0, function* () {
|
|
154
173
|
this.messageHandlers.delete(subscriptionId);
|
|
174
|
+
this.subscriptionHandlerIds.delete(subscriptionId);
|
|
155
175
|
yield this.closeSubscription(subscriptionId);
|
|
156
176
|
});
|
|
157
177
|
return {
|
|
@@ -171,5 +191,137 @@ export class JsonRpcSocket {
|
|
|
171
191
|
send(request) {
|
|
172
192
|
this.socket.send(JSON.stringify(request));
|
|
173
193
|
}
|
|
194
|
+
// ---------------------------------------------------------------------------
|
|
195
|
+
// Internal: socket wiring and reconnection
|
|
196
|
+
// ---------------------------------------------------------------------------
|
|
197
|
+
/**
|
|
198
|
+
* Creates and connects a raw WebSocket, resolving when `open` fires.
|
|
199
|
+
*/
|
|
200
|
+
static createWebSocket(url, connectTimeout) {
|
|
201
|
+
return new Promise((resolve, reject) => {
|
|
202
|
+
const ws = new WebSocket(url);
|
|
203
|
+
const onOpen = () => {
|
|
204
|
+
cleanup();
|
|
205
|
+
resolve(ws);
|
|
206
|
+
};
|
|
207
|
+
const onError = (error) => {
|
|
208
|
+
cleanup();
|
|
209
|
+
reject(error);
|
|
210
|
+
};
|
|
211
|
+
const timer = setTimeout(() => {
|
|
212
|
+
cleanup();
|
|
213
|
+
ws.close();
|
|
214
|
+
reject(new Error('connect timed out'));
|
|
215
|
+
}, connectTimeout);
|
|
216
|
+
const cleanup = () => {
|
|
217
|
+
clearTimeout(timer);
|
|
218
|
+
ws.removeEventListener('open', onOpen);
|
|
219
|
+
ws.removeEventListener('error', onError);
|
|
220
|
+
};
|
|
221
|
+
ws.addEventListener('open', onOpen);
|
|
222
|
+
ws.addEventListener('error', onError);
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Wires the `onmessage`, `onclose`, and `onerror` handlers for a given
|
|
227
|
+
* WebSocket instance. Called both on initial connect and on reconnect.
|
|
228
|
+
*/
|
|
229
|
+
wireSocket(ws) {
|
|
230
|
+
ws.addEventListener('message', (event) => {
|
|
231
|
+
const jsonRpcResponse = parseJson(toText(event.data));
|
|
232
|
+
if (jsonRpcResponse === null) {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
const handler = this.messageHandlers.get(jsonRpcResponse.id);
|
|
236
|
+
if (handler) {
|
|
237
|
+
handler(event);
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
ws.addEventListener('close', () => {
|
|
241
|
+
var _a, _b, _c, _d, _e;
|
|
242
|
+
this._isConnected = false;
|
|
243
|
+
if (this.closedByUser) {
|
|
244
|
+
(_b = (_a = this.options).onclose) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
// Reject all pending one-shot request handlers (non-subscription).
|
|
248
|
+
this.rejectPendingRequests();
|
|
249
|
+
// Notify the user handler if present.
|
|
250
|
+
(_d = (_c = this.options).onclose) === null || _d === void 0 ? void 0 : _d.call(_c);
|
|
251
|
+
// Attempt reconnection if enabled.
|
|
252
|
+
const autoReconnect = (_e = this.options.autoReconnect) !== null && _e !== void 0 ? _e : true;
|
|
253
|
+
if (autoReconnect && !this.reconnecting) {
|
|
254
|
+
this.attemptReconnect();
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
ws.addEventListener('error', (error) => {
|
|
258
|
+
var _a, _b;
|
|
259
|
+
(_b = (_a = this.options).onerror) === null || _b === void 0 ? void 0 : _b.call(_a, error);
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Rejects all pending one-shot request handlers (those not in `subscriptionHandlerIds`)
|
|
264
|
+
* by synthesizing a transport error event.
|
|
265
|
+
*/
|
|
266
|
+
rejectPendingRequests() {
|
|
267
|
+
for (const [id, handler] of this.messageHandlers) {
|
|
268
|
+
if (!this.subscriptionHandlerIds.has(id)) {
|
|
269
|
+
// Synthesize an error response to reject the pending promise.
|
|
270
|
+
const errorData = JSON.stringify({
|
|
271
|
+
jsonrpc: '2.0',
|
|
272
|
+
id,
|
|
273
|
+
error: { code: JsonRpcErrorCodes.TransportError, message: 'WebSocket connection closed unexpectedly' },
|
|
274
|
+
});
|
|
275
|
+
handler({ data: errorData });
|
|
276
|
+
this.messageHandlers.delete(id);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Exponential backoff reconnection loop with jitter.
|
|
282
|
+
*/
|
|
283
|
+
attemptReconnect() {
|
|
284
|
+
var _a, _b, _c, _d;
|
|
285
|
+
this.reconnecting = true;
|
|
286
|
+
const baseDelay = (_a = this.options.baseReconnectDelay) !== null && _a !== void 0 ? _a : DEFAULT_BASE_RECONNECT_DELAY;
|
|
287
|
+
const maxDelay = (_b = this.options.maxReconnectDelay) !== null && _b !== void 0 ? _b : DEFAULT_MAX_RECONNECT_DELAY;
|
|
288
|
+
const maxAttempts = (_c = this.options.maxReconnectAttempts) !== null && _c !== void 0 ? _c : DEFAULT_MAX_RECONNECT_ATTEMPTS;
|
|
289
|
+
const connectTimeout = (_d = this.options.connectTimeout) !== null && _d !== void 0 ? _d : CONNECT_TIMEOUT;
|
|
290
|
+
let attempt = 0;
|
|
291
|
+
const tryReconnect = () => __awaiter(this, void 0, void 0, function* () {
|
|
292
|
+
var _a, _b, _c, _d;
|
|
293
|
+
if (this.closedByUser) {
|
|
294
|
+
this.reconnecting = false;
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
attempt++;
|
|
298
|
+
if (attempt > maxAttempts) {
|
|
299
|
+
this.reconnecting = false;
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
(_b = (_a = this.options).onreconnecting) === null || _b === void 0 ? void 0 : _b.call(_a, attempt);
|
|
303
|
+
// Exponential backoff with jitter: delay = min(baseDelay * 2^(attempt-1), maxDelay) * (0.5 + random*0.5)
|
|
304
|
+
const expDelay = Math.min(baseDelay * Math.pow(2, attempt - 1), maxDelay);
|
|
305
|
+
const jitteredDelay = expDelay * (0.5 + Math.random() * 0.5);
|
|
306
|
+
yield new Promise(resolve => setTimeout(resolve, jitteredDelay));
|
|
307
|
+
if (this.closedByUser) {
|
|
308
|
+
this.reconnecting = false;
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
try {
|
|
312
|
+
const newSocket = yield JsonRpcSocket.createWebSocket(this.url, connectTimeout);
|
|
313
|
+
this.socket = newSocket;
|
|
314
|
+
this._isConnected = true;
|
|
315
|
+
this.reconnecting = false;
|
|
316
|
+
this.wireSocket(newSocket);
|
|
317
|
+
(_d = (_c = this.options).onreconnected) === null || _d === void 0 ? void 0 : _d.call(_c);
|
|
318
|
+
}
|
|
319
|
+
catch (_e) {
|
|
320
|
+
// Connection failed — retry.
|
|
321
|
+
yield tryReconnect();
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
tryReconnect();
|
|
325
|
+
}
|
|
174
326
|
}
|
|
175
327
|
//# sourceMappingURL=json-rpc-socket.js.map
|