@nijaru/pi-search 0.0.3 → 0.0.4
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/package.json +1 -1
- package/src/brave.ts +38 -18
package/package.json
CHANGED
package/src/brave.ts
CHANGED
|
@@ -25,7 +25,7 @@ export type BraveFetch = (input: string | URL | Request, init?: RequestInit) =>
|
|
|
25
25
|
export interface BraveCapacityTracker {
|
|
26
26
|
/** True when no known finite quota window currently blocks a call. */
|
|
27
27
|
readonly canAttempt: () => boolean;
|
|
28
|
-
/**
|
|
28
|
+
/** Wait for local admission, returning false when the caller canceled. */
|
|
29
29
|
readonly waitForTurn?: (signal: AbortSignal) => Promise<boolean>;
|
|
30
30
|
/** Record provider observations without inventing or persisting counters. */
|
|
31
31
|
readonly observe: (info: ProviderRateLimitInfo | undefined) => void;
|
|
@@ -48,6 +48,8 @@ export class BraveQuotaTracker implements BraveCapacityTracker {
|
|
|
48
48
|
private observedAtMs = 0;
|
|
49
49
|
private readonly minimumIntervalMs: number;
|
|
50
50
|
private nextRequestAtMs = 0;
|
|
51
|
+
private readonly waiting = new Set<{ signal: AbortSignal; finish: (admitted: boolean) => void }>();
|
|
52
|
+
private admissionTimer: ReturnType<typeof setTimeout> | undefined;
|
|
51
53
|
|
|
52
54
|
constructor(options: BraveQuotaTrackerOptions = {}) {
|
|
53
55
|
const minimumIntervalMs = options.minimumIntervalMs ?? 0;
|
|
@@ -57,30 +59,48 @@ export class BraveQuotaTracker implements BraveCapacityTracker {
|
|
|
57
59
|
this.minimumIntervalMs = minimumIntervalMs;
|
|
58
60
|
}
|
|
59
61
|
|
|
60
|
-
|
|
61
|
-
if (signal.aborted) return false;
|
|
62
|
-
|
|
63
|
-
const startAt = Math.max(now, this.nextRequestAtMs);
|
|
64
|
-
this.nextRequestAtMs = startAt + this.minimumIntervalMs;
|
|
65
|
-
const delayMs = startAt - now;
|
|
66
|
-
if (delayMs <= 0) return true;
|
|
62
|
+
waitForTurn(signal: AbortSignal): Promise<boolean> {
|
|
63
|
+
if (signal.aborted) return Promise.resolve(false);
|
|
64
|
+
if (this.minimumIntervalMs === 0) return Promise.resolve(true);
|
|
67
65
|
return new Promise<boolean>((resolve) => {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
66
|
+
const waiter = {
|
|
67
|
+
signal,
|
|
68
|
+
finish: (admitted: boolean): void => {
|
|
69
|
+
if (!this.waiting.delete(waiter)) return;
|
|
70
|
+
signal.removeEventListener("abort", onAbort);
|
|
71
|
+
if (this.waiting.size === 0 && this.admissionTimer !== undefined) {
|
|
72
|
+
clearTimeout(this.admissionTimer);
|
|
73
|
+
this.admissionTimer = undefined;
|
|
74
|
+
}
|
|
75
|
+
resolve(admitted);
|
|
76
|
+
},
|
|
76
77
|
};
|
|
77
|
-
const onAbort = (): void => finish(false);
|
|
78
|
-
|
|
78
|
+
const onAbort = (): void => { waiter.finish(false); };
|
|
79
|
+
this.waiting.add(waiter);
|
|
79
80
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
80
81
|
if (signal.aborted) onAbort();
|
|
82
|
+
this.admitNext();
|
|
81
83
|
});
|
|
82
84
|
}
|
|
83
85
|
|
|
86
|
+
private admitNext(): void {
|
|
87
|
+
if (this.admissionTimer !== undefined) return;
|
|
88
|
+
for (const waiter of this.waiting) {
|
|
89
|
+
if (waiter.signal.aborted) { waiter.finish(false); continue; }
|
|
90
|
+
const now = Date.now(), delayMs = this.nextRequestAtMs - now;
|
|
91
|
+
if (delayMs > 0) {
|
|
92
|
+
this.admissionTimer = setTimeout(() => {
|
|
93
|
+
this.admissionTimer = undefined;
|
|
94
|
+
this.admitNext();
|
|
95
|
+
}, delayMs);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
// Only actual admissions consume spacing. Late timers cannot release a burst.
|
|
99
|
+
this.nextRequestAtMs = now + this.minimumIntervalMs;
|
|
100
|
+
waiter.finish(true);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
84
104
|
canAttempt(): boolean {
|
|
85
105
|
const info = this.snapshot();
|
|
86
106
|
if (info === undefined) return true;
|