@drawcall/market 0.1.86 → 0.1.87
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/client.d.ts +10 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +50 -1
- package/dist/client.js.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +67 -2
package/dist/client.d.ts
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import type { ContractRouterClient } from '@orpc/contract';
|
|
2
2
|
import type { AppContract } from './contract.js';
|
|
3
3
|
export type MarketClient = ContractRouterClient<AppContract>;
|
|
4
|
+
type RequestFetch = (request: Request, init?: {
|
|
5
|
+
redirect?: Request['redirect'];
|
|
6
|
+
}) => Promise<Response>;
|
|
4
7
|
export interface MarketClientOptions {
|
|
5
8
|
baseUrl?: string;
|
|
6
|
-
fetch?:
|
|
9
|
+
fetch?: RequestFetch;
|
|
7
10
|
authToken?: string;
|
|
8
11
|
}
|
|
12
|
+
interface RetryOptions {
|
|
13
|
+
attempts?: number;
|
|
14
|
+
delayMs?: number;
|
|
15
|
+
}
|
|
9
16
|
export declare function createMarketClient(opts?: MarketClientOptions): MarketClient;
|
|
17
|
+
export declare function createRetryingFetch(fetchImpl: RequestFetch, options?: RetryOptions): RequestFetch;
|
|
18
|
+
export {};
|
|
10
19
|
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAEhD,MAAM,MAAM,YAAY,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAEhD,MAAM,MAAM,YAAY,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAA;AAC5D,KAAK,YAAY,GAAG,CAClB,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAA;CAAE,KACtC,OAAO,CAAC,QAAQ,CAAC,CAAA;AAgBtB,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,YAAY,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,UAAU,YAAY;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAMD,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,mBAAwB,GAAG,YAAY,CAY/E;AAED,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,YAAY,EACvB,OAAO,GAAE,YAAiB,GACzB,YAAY,CA2Bd"}
|
package/dist/client.js
CHANGED
|
@@ -1,16 +1,65 @@
|
|
|
1
1
|
import { createORPCClient } from '@orpc/client';
|
|
2
2
|
import { RPCLink } from '@orpc/client/fetch';
|
|
3
3
|
const DEFAULT_BASE_URL = 'https://market.drawcall.ai';
|
|
4
|
+
const RETRYABLE_RPC_PATHS = new Set([
|
|
5
|
+
'/api/rpc/asset/search',
|
|
6
|
+
'/api/rpc/asset/exact',
|
|
7
|
+
'/api/rpc/asset/downloadZip',
|
|
8
|
+
'/api/rpc/asset/files',
|
|
9
|
+
'/api/rpc/asset/fileManifest',
|
|
10
|
+
'/api/rpc/asset/generateStatus',
|
|
11
|
+
'/api/rpc/asset/installMetadata',
|
|
12
|
+
'/api/rpc/asset/agent/status',
|
|
13
|
+
'/api/rpc/user/getProfile',
|
|
14
|
+
'/api/rpc/user/getAuthToken',
|
|
15
|
+
]);
|
|
4
16
|
function buildHeaders(authToken) {
|
|
5
17
|
return authToken ? { authorization: `Bearer ${authToken}` } : undefined;
|
|
6
18
|
}
|
|
7
19
|
export function createMarketClient(opts = {}) {
|
|
8
20
|
const baseUrl = opts.baseUrl ?? DEFAULT_BASE_URL;
|
|
21
|
+
const fetch = opts.fetch ??
|
|
22
|
+
((request, init) => globalThis.fetch(new Request(request), init));
|
|
9
23
|
const link = new RPCLink({
|
|
10
24
|
url: new URL('/api/rpc', baseUrl).href,
|
|
11
|
-
fetch:
|
|
25
|
+
fetch: createRetryingFetch(fetch),
|
|
12
26
|
headers: buildHeaders(opts.authToken),
|
|
13
27
|
});
|
|
14
28
|
return createORPCClient(link);
|
|
15
29
|
}
|
|
30
|
+
export function createRetryingFetch(fetchImpl, options = {}) {
|
|
31
|
+
const attempts = options.attempts ?? 4;
|
|
32
|
+
const delayMs = options.delayMs ?? 250;
|
|
33
|
+
return async (request, init) => {
|
|
34
|
+
if (!RETRYABLE_RPC_PATHS.has(new URL(request.url).pathname)) {
|
|
35
|
+
return fetchImpl(request, init);
|
|
36
|
+
}
|
|
37
|
+
const body = request.body ? new Uint8Array(await request.clone().arrayBuffer()) : undefined;
|
|
38
|
+
const nextRequest = () => new Request(request.url, {
|
|
39
|
+
method: request.method,
|
|
40
|
+
headers: request.headers,
|
|
41
|
+
body,
|
|
42
|
+
credentials: request.credentials,
|
|
43
|
+
signal: request.signal,
|
|
44
|
+
});
|
|
45
|
+
for (let attempt = 1;; attempt += 1) {
|
|
46
|
+
try {
|
|
47
|
+
const response = await fetchImpl(nextRequest(), init);
|
|
48
|
+
if (attempt === attempts || !isTransientStatus(response.status))
|
|
49
|
+
return response;
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
if (attempt === attempts)
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
await delay(delayMs * 2 ** (attempt - 1));
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function isTransientStatus(status) {
|
|
60
|
+
return status === 429 || status >= 500;
|
|
61
|
+
}
|
|
62
|
+
function delay(ms) {
|
|
63
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
64
|
+
}
|
|
16
65
|
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -4,25 +4,90 @@ import type { ContractRouterClient } from '@orpc/contract'
|
|
|
4
4
|
import type { AppContract } from './contract.js'
|
|
5
5
|
|
|
6
6
|
export type MarketClient = ContractRouterClient<AppContract>
|
|
7
|
+
type RequestFetch = (
|
|
8
|
+
request: Request,
|
|
9
|
+
init?: { redirect?: Request['redirect'] },
|
|
10
|
+
) => Promise<Response>
|
|
7
11
|
|
|
8
12
|
const DEFAULT_BASE_URL = 'https://market.drawcall.ai'
|
|
13
|
+
const RETRYABLE_RPC_PATHS = new Set([
|
|
14
|
+
'/api/rpc/asset/search',
|
|
15
|
+
'/api/rpc/asset/exact',
|
|
16
|
+
'/api/rpc/asset/downloadZip',
|
|
17
|
+
'/api/rpc/asset/files',
|
|
18
|
+
'/api/rpc/asset/fileManifest',
|
|
19
|
+
'/api/rpc/asset/generateStatus',
|
|
20
|
+
'/api/rpc/asset/installMetadata',
|
|
21
|
+
'/api/rpc/asset/agent/status',
|
|
22
|
+
'/api/rpc/user/getProfile',
|
|
23
|
+
'/api/rpc/user/getAuthToken',
|
|
24
|
+
])
|
|
9
25
|
|
|
10
26
|
export interface MarketClientOptions {
|
|
11
27
|
baseUrl?: string
|
|
12
|
-
fetch?:
|
|
28
|
+
fetch?: RequestFetch
|
|
13
29
|
authToken?: string
|
|
14
30
|
}
|
|
15
31
|
|
|
32
|
+
interface RetryOptions {
|
|
33
|
+
attempts?: number
|
|
34
|
+
delayMs?: number
|
|
35
|
+
}
|
|
36
|
+
|
|
16
37
|
function buildHeaders(authToken?: string): Record<string, string> | undefined {
|
|
17
38
|
return authToken ? { authorization: `Bearer ${authToken}` } : undefined
|
|
18
39
|
}
|
|
19
40
|
|
|
20
41
|
export function createMarketClient(opts: MarketClientOptions = {}): MarketClient {
|
|
21
42
|
const baseUrl = opts.baseUrl ?? DEFAULT_BASE_URL
|
|
43
|
+
const fetch =
|
|
44
|
+
opts.fetch ??
|
|
45
|
+
((request: Request, init?: { redirect?: Request['redirect'] }) =>
|
|
46
|
+
globalThis.fetch(new Request(request), init))
|
|
22
47
|
const link = new RPCLink({
|
|
23
48
|
url: new URL('/api/rpc', baseUrl).href,
|
|
24
|
-
fetch:
|
|
49
|
+
fetch: createRetryingFetch(fetch),
|
|
25
50
|
headers: buildHeaders(opts.authToken),
|
|
26
51
|
})
|
|
27
52
|
return createORPCClient<MarketClient>(link)
|
|
28
53
|
}
|
|
54
|
+
|
|
55
|
+
export function createRetryingFetch(
|
|
56
|
+
fetchImpl: RequestFetch,
|
|
57
|
+
options: RetryOptions = {},
|
|
58
|
+
): RequestFetch {
|
|
59
|
+
const attempts = options.attempts ?? 4
|
|
60
|
+
const delayMs = options.delayMs ?? 250
|
|
61
|
+
|
|
62
|
+
return async (request, init) => {
|
|
63
|
+
if (!RETRYABLE_RPC_PATHS.has(new URL(request.url).pathname)) {
|
|
64
|
+
return fetchImpl(request, init)
|
|
65
|
+
}
|
|
66
|
+
const body = request.body ? new Uint8Array(await request.clone().arrayBuffer()) : undefined
|
|
67
|
+
const nextRequest = () =>
|
|
68
|
+
new Request(request.url, {
|
|
69
|
+
method: request.method,
|
|
70
|
+
headers: request.headers,
|
|
71
|
+
body,
|
|
72
|
+
credentials: request.credentials,
|
|
73
|
+
signal: request.signal,
|
|
74
|
+
})
|
|
75
|
+
for (let attempt = 1; ; attempt += 1) {
|
|
76
|
+
try {
|
|
77
|
+
const response = await fetchImpl(nextRequest(), init)
|
|
78
|
+
if (attempt === attempts || !isTransientStatus(response.status)) return response
|
|
79
|
+
} catch (error) {
|
|
80
|
+
if (attempt === attempts) throw error
|
|
81
|
+
}
|
|
82
|
+
await delay(delayMs * 2 ** (attempt - 1))
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function isTransientStatus(status: number): boolean {
|
|
88
|
+
return status === 429 || status >= 500
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function delay(ms: number): Promise<void> {
|
|
92
|
+
return new Promise((resolve) => setTimeout(resolve, ms))
|
|
93
|
+
}
|