@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 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?: typeof globalThis.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
@@ -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;AAI5D,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAMD,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,mBAAwB,GAAG,YAAY,CAQ/E"}
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: opts.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
@@ -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;AAM5C,MAAM,gBAAgB,GAAG,4BAA4B,CAAA;AAQrD,SAAS,YAAY,CAAC,SAAkB;IACtC,OAAO,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;AACzE,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAA4B,EAAE;IAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,gBAAgB,CAAA;IAChD,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC;QACvB,GAAG,EAAE,IAAI,GAAG,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,IAAI;QACtC,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC;KACtC,CAAC,CAAA;IACF,OAAO,gBAAgB,CAAe,IAAI,CAAC,CAAA;AAC7C,CAAC"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drawcall/market",
3
- "version": "0.1.86",
3
+ "version": "0.1.87",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/drawcall-ai/market",
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?: typeof globalThis.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: opts.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
+ }