@specstream/sdk 1.3.0 → 1.3.2

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.js CHANGED
@@ -56,6 +56,17 @@ export function assertFamily(entityType) {
56
56
  }
57
57
  return entityType;
58
58
  }
59
+ const RETRY_AFTER_MAX_MS = 10_000;
60
+ /** Milliseconds to wait before the one retry of a 503 that names its Retry-After, or null. */
61
+ function retryAfterMs(response) {
62
+ if (response.status !== 503)
63
+ return null;
64
+ const value = (response.headers?.get("retry-after") || "").trim();
65
+ if (!value)
66
+ return null;
67
+ const ms = /^\d+(\.\d+)?$/.test(value) ? Number(value) * 1000 : Date.parse(value) - Date.now();
68
+ return Number.isFinite(ms) && ms >= 0 && ms <= RETRY_AFTER_MAX_MS ? ms : null;
69
+ }
59
70
  export class Client {
60
71
  apiKey;
61
72
  baseUrl;
@@ -1012,21 +1023,29 @@ export class Client {
1012
1023
  Authorization: token,
1013
1024
  Accept: "application/json",
1014
1025
  "Content-Type": "application/json",
1015
- "User-Agent": "specstream-typescript/1.3.0",
1026
+ "User-Agent": "specstream-typescript/1.3.2",
1016
1027
  };
1017
1028
  }
1018
1029
  async request(method, path, body) {
1019
1030
  const url = this.baseUrl + path;
1031
+ const send = () => this.fetchFn(url, {
1032
+ method,
1033
+ headers: this.headers(),
1034
+ redirect: "error",
1035
+ signal: AbortSignal.timeout(this.timeoutMs),
1036
+ body: body === undefined ? undefined : JSON.stringify(body),
1037
+ });
1020
1038
  let response;
1021
1039
  let text;
1022
1040
  try {
1023
- response = await this.fetchFn(url, {
1024
- method,
1025
- headers: this.headers(),
1026
- redirect: "error",
1027
- signal: AbortSignal.timeout(this.timeoutMs),
1028
- body: body === undefined ? undefined : JSON.stringify(body),
1029
- });
1041
+ response = await send();
1042
+ const wait = retryAfterMs(response);
1043
+ if (wait !== null) {
1044
+ // The server did nothing and names when to ask again: ask once more.
1045
+ await response.body?.cancel();
1046
+ await new Promise((resolve) => setTimeout(resolve, wait));
1047
+ response = await send();
1048
+ }
1030
1049
  text = await response.text();
1031
1050
  }
1032
1051
  catch (error) {
@@ -671,7 +671,7 @@ export interface Schemas {
671
671
  [key: string]: unknown;
672
672
  };
673
673
  };
674
- "ErrorCode": "unsupported_query" | "unsupported_predicate" | "unsupported_entity_family" | "ambiguous_geo" | "capability_pending" | "source_blocked" | "challenge_page" | "unquoted_plan" | "compiler_unavailable" | "parse_failed" | "payments_not_live" | "capacity" | "kill_switch" | "internal_failure" | "plan_required" | "invalid_token";
674
+ "ErrorCode": "unsupported_query" | "unsupported_predicate" | "unsupported_entity_family" | "ambiguous_geo" | "capability_pending" | "source_blocked" | "challenge_page" | "unquoted_plan" | "missing_api_key" | "owner_only" | "compiler_unavailable" | "parse_failed" | "payments_not_live" | "capacity" | "kill_switch" | "internal_failure" | "plan_required" | "invalid_token" | "insufficient_balance";
675
675
  "ErrorEnvelope": {
676
676
  "error": Schemas["ErrorBody"];
677
677
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@specstream/sdk",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "description": "TypeScript client for building lead lists and company lists from the live web. Every match comes with its source, priced before it runs.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",