@0xinsider/sdk 0.14.0-bootstrap.0

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.
@@ -0,0 +1,68 @@
1
+ /**
2
+ * `Retry-After` parsing and the waits it drives, shared by the REST retry
3
+ * loop (`client.ts`) and the SSE reconnect loop (`stream.ts`) so the two
4
+ * cannot read the same header differently (#16249).
5
+ *
6
+ * Two facts shape this module:
7
+ *
8
+ * 1. `Retry-After` is either delta-seconds or an HTTP-date (RFC 9110 §10.2.3,
9
+ * https://www.rfc-editor.org/rfc/rfc9110.html#name-retry-after). Both
10
+ * loops parsed only the number and treated a date as "no header".
11
+ * 2. Node schedules a `setTimeout` delay above 2147483647 ms (about 24.8 days)
12
+ * as 1 ms, with a warning
13
+ * (https://nodejs.org/api/timers.html#settimeoutcallback-delay-args). The
14
+ * stream loop multiplied any `Retry-After` by 1000 and handed it straight
15
+ * to the timer, so a long server-requested wait -- `monthly_quota_exceeded`
16
+ * names the first of next month -- would have reconnected at once, the
17
+ * opposite of what the server asked.
18
+ *
19
+ * The policy is therefore: parse both forms into a non-negative number of
20
+ * seconds; never wait in-process past a ceiling the caller can see (60 s by
21
+ * default, the same for REST and SSE); when the server asks for longer, hand
22
+ * the caller a typed error carrying the not-before instant and the resume
23
+ * context, never a clamped earlier retry; and when a caller opts into waiting
24
+ * longer, wait in timer-sized chunks so the timer range is never exceeded.
25
+ */
26
+ /**
27
+ * The largest delay one `setTimeout` can hold in Node (2^31 - 1 ms). A larger
28
+ * value is scheduled as 1 ms, so every wait here is cut into chunks of at
29
+ * most this size.
30
+ */
31
+ export declare const MAX_TIMER_DELAY_MS = 2147483647;
32
+ /**
33
+ * The longest server-requested wait either loop holds in-process by default.
34
+ * A `Retry-After` beyond it is the caller's to schedule: the REST loop throws
35
+ * the response's error (`retryAfterSeconds`, `retryAt`), the stream loop
36
+ * throws `StreamRetryDeferredError`.
37
+ */
38
+ export declare const RETRY_AFTER_CEILING_MS = 60000;
39
+ /**
40
+ * Parse a `Retry-After` header value into seconds to wait, or `null` when
41
+ * there is no usable value.
42
+ *
43
+ * - Delta-seconds: a finite, non-negative number (`"60"`, `"1.5"`). A negative
44
+ * or non-finite number (`"-1"`, `"Infinity"`, `"NaN"`) is `null`: the
45
+ * grammar does not allow it, and guessing a wait from it would be inventing
46
+ * a server instruction.
47
+ * - HTTP-date (`"Wed, 01 Oct 2026 00:00:00 GMT"`): the seconds from `nowMs`
48
+ * to that instant. A date already past is `0` (the server said "after an
49
+ * instant that has passed", which is "now"), never negative.
50
+ * - Anything else (`""`, `"soon"`) is `null`.
51
+ *
52
+ * `null` means "as if the header were absent": the caller falls back to its
53
+ * own backoff. It never means "retry at once".
54
+ */
55
+ export declare function parseRetryAfter(header: string | null | undefined, nowMs?: number): number | null;
56
+ /** `parseRetryAfter` over a response's `Retry-After` header. */
57
+ export declare function retryAfterSeconds(response: Response): number | null;
58
+ /**
59
+ * Resolve after `ms`, or reject with the signal's reason the moment it
60
+ * aborts. A wait longer than `MAX_TIMER_DELAY_MS` runs as consecutive timers
61
+ * of at most that size, so it is never handed to `setTimeout` as one value
62
+ * that Node would schedule as 1 ms. `ms` must be a non-negative number;
63
+ * `Infinity` is refused because it can never elapse.
64
+ */
65
+ export declare function sleepUnlessAborted(ms: number, signal: AbortSignal | undefined): Promise<void>;
66
+ /** Resolve `true` after `ms`, or `false` the moment `signal` aborts. */
67
+ export declare function waitUnlessAborted(ms: number, signal: AbortSignal | undefined): Promise<boolean>;
68
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,aAAgB,CAAC;AAEhD;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,QAAS,CAAC;AAE7C;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACjC,KAAK,GAAE,MAAmB,GACzB,MAAM,GAAG,IAAI,CAaf;AAED,gEAAgE;AAChE,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,CAEnE;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,WAAW,GAAG,SAAS,GAC9B,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wEAAwE;AACxE,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,WAAW,GAAG,SAAS,GAC9B,OAAO,CAAC,OAAO,CAAC,CAQlB"}
package/dist/retry.js ADDED
@@ -0,0 +1,125 @@
1
+ /**
2
+ * `Retry-After` parsing and the waits it drives, shared by the REST retry
3
+ * loop (`client.ts`) and the SSE reconnect loop (`stream.ts`) so the two
4
+ * cannot read the same header differently (#16249).
5
+ *
6
+ * Two facts shape this module:
7
+ *
8
+ * 1. `Retry-After` is either delta-seconds or an HTTP-date (RFC 9110 §10.2.3,
9
+ * https://www.rfc-editor.org/rfc/rfc9110.html#name-retry-after). Both
10
+ * loops parsed only the number and treated a date as "no header".
11
+ * 2. Node schedules a `setTimeout` delay above 2147483647 ms (about 24.8 days)
12
+ * as 1 ms, with a warning
13
+ * (https://nodejs.org/api/timers.html#settimeoutcallback-delay-args). The
14
+ * stream loop multiplied any `Retry-After` by 1000 and handed it straight
15
+ * to the timer, so a long server-requested wait -- `monthly_quota_exceeded`
16
+ * names the first of next month -- would have reconnected at once, the
17
+ * opposite of what the server asked.
18
+ *
19
+ * The policy is therefore: parse both forms into a non-negative number of
20
+ * seconds; never wait in-process past a ceiling the caller can see (60 s by
21
+ * default, the same for REST and SSE); when the server asks for longer, hand
22
+ * the caller a typed error carrying the not-before instant and the resume
23
+ * context, never a clamped earlier retry; and when a caller opts into waiting
24
+ * longer, wait in timer-sized chunks so the timer range is never exceeded.
25
+ */
26
+ /**
27
+ * The largest delay one `setTimeout` can hold in Node (2^31 - 1 ms). A larger
28
+ * value is scheduled as 1 ms, so every wait here is cut into chunks of at
29
+ * most this size.
30
+ */
31
+ export const MAX_TIMER_DELAY_MS = 2_147_483_647;
32
+ /**
33
+ * The longest server-requested wait either loop holds in-process by default.
34
+ * A `Retry-After` beyond it is the caller's to schedule: the REST loop throws
35
+ * the response's error (`retryAfterSeconds`, `retryAt`), the stream loop
36
+ * throws `StreamRetryDeferredError`.
37
+ */
38
+ export const RETRY_AFTER_CEILING_MS = 60_000;
39
+ /**
40
+ * Parse a `Retry-After` header value into seconds to wait, or `null` when
41
+ * there is no usable value.
42
+ *
43
+ * - Delta-seconds: a finite, non-negative number (`"60"`, `"1.5"`). A negative
44
+ * or non-finite number (`"-1"`, `"Infinity"`, `"NaN"`) is `null`: the
45
+ * grammar does not allow it, and guessing a wait from it would be inventing
46
+ * a server instruction.
47
+ * - HTTP-date (`"Wed, 01 Oct 2026 00:00:00 GMT"`): the seconds from `nowMs`
48
+ * to that instant. A date already past is `0` (the server said "after an
49
+ * instant that has passed", which is "now"), never negative.
50
+ * - Anything else (`""`, `"soon"`) is `null`.
51
+ *
52
+ * `null` means "as if the header were absent": the caller falls back to its
53
+ * own backoff. It never means "retry at once".
54
+ */
55
+ export function parseRetryAfter(header, nowMs = Date.now()) {
56
+ if (header === null || header === undefined)
57
+ return null;
58
+ const text = header.trim();
59
+ if (text === "")
60
+ return null;
61
+ // `Number("")` is 0 and `Number(" 5 ")` is 5, so the trim above and the
62
+ // empty check keep a blank header from reading as "retry now".
63
+ const delta = Number(text);
64
+ if (!Number.isNaN(delta)) {
65
+ return Number.isFinite(delta) && delta >= 0 ? delta : null;
66
+ }
67
+ const dateMs = Date.parse(text);
68
+ if (Number.isNaN(dateMs))
69
+ return null;
70
+ return Math.max(0, (dateMs - nowMs) / 1000);
71
+ }
72
+ /** `parseRetryAfter` over a response's `Retry-After` header. */
73
+ export function retryAfterSeconds(response) {
74
+ return parseRetryAfter(response.headers.get("retry-after"));
75
+ }
76
+ /**
77
+ * Resolve after `ms`, or reject with the signal's reason the moment it
78
+ * aborts. A wait longer than `MAX_TIMER_DELAY_MS` runs as consecutive timers
79
+ * of at most that size, so it is never handed to `setTimeout` as one value
80
+ * that Node would schedule as 1 ms. `ms` must be a non-negative number;
81
+ * `Infinity` is refused because it can never elapse.
82
+ */
83
+ export async function sleepUnlessAborted(ms, signal) {
84
+ if (!(ms >= 0) || !Number.isFinite(ms)) {
85
+ throw new RangeError(`sleepUnlessAborted needs a finite non-negative delay, got ${String(ms)}`);
86
+ }
87
+ const notBefore = Date.now() + ms;
88
+ let remaining = ms;
89
+ for (;;) {
90
+ await timerUnlessAborted(Math.min(remaining, MAX_TIMER_DELAY_MS), signal);
91
+ remaining = notBefore - Date.now();
92
+ if (remaining <= 0)
93
+ return;
94
+ }
95
+ }
96
+ /** Resolve `true` after `ms`, or `false` the moment `signal` aborts. */
97
+ export async function waitUnlessAborted(ms, signal) {
98
+ try {
99
+ await sleepUnlessAborted(ms, signal);
100
+ return true;
101
+ }
102
+ catch (error) {
103
+ if (signal?.aborted)
104
+ return false;
105
+ throw error;
106
+ }
107
+ }
108
+ function timerUnlessAborted(ms, signal) {
109
+ return new Promise((resolve, reject) => {
110
+ if (signal?.aborted) {
111
+ reject(signal.reason);
112
+ return;
113
+ }
114
+ const onAbort = () => {
115
+ clearTimeout(timer);
116
+ reject(signal?.reason);
117
+ };
118
+ const timer = setTimeout(() => {
119
+ signal?.removeEventListener("abort", onAbort);
120
+ resolve();
121
+ }, ms);
122
+ signal?.addEventListener("abort", onAbort, { once: true });
123
+ });
124
+ }
125
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"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"}