@openlimiter/core 0.2.0 → 0.4.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.
- package/dist/cache.d.ts +64 -0
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +132 -9
- package/dist/cache.js.map +1 -1
- package/dist/collection.d.ts +151 -0
- package/dist/collection.d.ts.map +1 -0
- package/dist/collection.js +218 -0
- package/dist/collection.js.map +1 -0
- package/dist/connection-state.d.ts +178 -0
- package/dist/connection-state.d.ts.map +1 -0
- package/dist/connection-state.js +304 -0
- package/dist/connection-state.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/merge.d.ts +1 -0
- package/dist/merge.d.ts.map +1 -1
- package/dist/merge.js +12 -4
- package/dist/merge.js.map +1 -1
- package/dist/normalizer.d.ts.map +1 -1
- package/dist/normalizer.js +50 -2
- package/dist/normalizer.js.map +1 -1
- package/dist/schedule.d.ts +75 -0
- package/dist/schedule.d.ts.map +1 -0
- package/dist/schedule.js +131 -0
- package/dist/schedule.js.map +1 -0
- package/dist/types.d.ts +66 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +54 -0
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The connection lifecycle, as one pure function and two human tables.
|
|
3
|
+
*
|
|
4
|
+
* A parser is not a connection. The product's central honesty problem is that
|
|
5
|
+
* an implemented parser has been able to look like a live account, so the state
|
|
6
|
+
* a connection is in has to be a value the whole product agrees on rather than
|
|
7
|
+
* a sentence each surface invents. Everything here is data and arithmetic: no
|
|
8
|
+
* clock, no network, no storage, so a surface can replay a connection's whole
|
|
9
|
+
* history and get the same answer every time.
|
|
10
|
+
*/
|
|
11
|
+
export const CONNECTION_STATES = [
|
|
12
|
+
"NOT_CONFIGURED",
|
|
13
|
+
"DETECTED",
|
|
14
|
+
"NEEDS_AUTH",
|
|
15
|
+
"READY_TO_ENABLE",
|
|
16
|
+
"CONNECTING",
|
|
17
|
+
"CONNECTED",
|
|
18
|
+
"DEGRADED",
|
|
19
|
+
"STALE",
|
|
20
|
+
"AUTH_EXPIRED",
|
|
21
|
+
"IMPORT_ONLY",
|
|
22
|
+
"MANUAL",
|
|
23
|
+
"UNSUPPORTED",
|
|
24
|
+
"ERROR"
|
|
25
|
+
];
|
|
26
|
+
/**
|
|
27
|
+
* How many consecutive network failures turn a degraded connection into a
|
|
28
|
+
* broken one. One timeout is a bad moment; three in a row is a fault worth
|
|
29
|
+
* showing a person.
|
|
30
|
+
*/
|
|
31
|
+
export const NETWORK_FAILURE_ERROR_THRESHOLD = 3;
|
|
32
|
+
/**
|
|
33
|
+
* States that describe something the product declared rather than something it
|
|
34
|
+
* attempted. A response cannot arrive in any of them, so a stray one is ignored
|
|
35
|
+
* instead of quietly promoting an import only source to Connected.
|
|
36
|
+
*/
|
|
37
|
+
const declaredStates = new Set([
|
|
38
|
+
"NOT_CONFIGURED",
|
|
39
|
+
"IMPORT_ONLY",
|
|
40
|
+
"MANUAL",
|
|
41
|
+
"UNSUPPORTED"
|
|
42
|
+
]);
|
|
43
|
+
function afterResponse(state, status, parsed, context) {
|
|
44
|
+
if (declaredStates.has(state))
|
|
45
|
+
return state;
|
|
46
|
+
if (status === 401 || status === 403) {
|
|
47
|
+
return context.everConnected ? "AUTH_EXPIRED" : "NEEDS_AUTH";
|
|
48
|
+
}
|
|
49
|
+
if (status === 429 || (status >= 500 && status <= 599))
|
|
50
|
+
return "DEGRADED";
|
|
51
|
+
if (status < 200 || status > 299)
|
|
52
|
+
return "ERROR";
|
|
53
|
+
/*
|
|
54
|
+
* The response arrived and was refused by our own parser. The connection is
|
|
55
|
+
* healthy and our understanding of it is not, which is the exact failure the
|
|
56
|
+
* Claude statusline contract mismatch was, so it reads as an error rather
|
|
57
|
+
* than as a provider problem.
|
|
58
|
+
*/
|
|
59
|
+
return parsed ? "CONNECTED" : "ERROR";
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Advance a connection by one event.
|
|
63
|
+
*
|
|
64
|
+
* Total and pure: every state, event and context triple has an answer, and an
|
|
65
|
+
* event that makes no sense where it arrived leaves the state exactly as it was
|
|
66
|
+
* rather than inventing a transition. The context is required rather than
|
|
67
|
+
* defaulted, because a caller that forgets it would silently get the wrong
|
|
68
|
+
* authentication answer, and a compiler error is cheaper than that.
|
|
69
|
+
*/
|
|
70
|
+
export function nextConnectionState(state, event, context) {
|
|
71
|
+
switch (event.kind) {
|
|
72
|
+
case "disconnected":
|
|
73
|
+
return "NOT_CONFIGURED";
|
|
74
|
+
case "declared_import_only":
|
|
75
|
+
return "IMPORT_ONLY";
|
|
76
|
+
case "declared_manual":
|
|
77
|
+
return "MANUAL";
|
|
78
|
+
case "declared_unsupported":
|
|
79
|
+
return "UNSUPPORTED";
|
|
80
|
+
case "detected":
|
|
81
|
+
return state === "NOT_CONFIGURED" ? "DETECTED" : state;
|
|
82
|
+
case "credential_required":
|
|
83
|
+
return state === "NOT_CONFIGURED" ||
|
|
84
|
+
state === "DETECTED" ||
|
|
85
|
+
state === "READY_TO_ENABLE"
|
|
86
|
+
? "NEEDS_AUTH"
|
|
87
|
+
: state;
|
|
88
|
+
case "credential_stored":
|
|
89
|
+
return state === "NEEDS_AUTH" ||
|
|
90
|
+
state === "AUTH_EXPIRED" ||
|
|
91
|
+
state === "DETECTED"
|
|
92
|
+
? "READY_TO_ENABLE"
|
|
93
|
+
: state;
|
|
94
|
+
case "enable_requested":
|
|
95
|
+
/*
|
|
96
|
+
* A connection missing its credential cannot start collecting no matter
|
|
97
|
+
* how many times the button is pressed, so those two states hold.
|
|
98
|
+
*/
|
|
99
|
+
return state === "NEEDS_AUTH" ||
|
|
100
|
+
state === "AUTH_EXPIRED" ||
|
|
101
|
+
declaredStates.has(state)
|
|
102
|
+
? state
|
|
103
|
+
: "CONNECTING";
|
|
104
|
+
case "http_response":
|
|
105
|
+
return afterResponse(state, event.status, event.parsed, context);
|
|
106
|
+
case "local_read":
|
|
107
|
+
if (declaredStates.has(state))
|
|
108
|
+
return state;
|
|
109
|
+
return event.parsed ? "CONNECTED" : "ERROR";
|
|
110
|
+
case "network_failure":
|
|
111
|
+
if (declaredStates.has(state))
|
|
112
|
+
return state;
|
|
113
|
+
return event.consecutive >= NETWORK_FAILURE_ERROR_THRESHOLD
|
|
114
|
+
? "ERROR"
|
|
115
|
+
: "DEGRADED";
|
|
116
|
+
case "expiry_passed":
|
|
117
|
+
/*
|
|
118
|
+
* Stale means the last reading is too old to trust, which only makes
|
|
119
|
+
* sense once a reading exists. Nothing else ages.
|
|
120
|
+
*/
|
|
121
|
+
return state === "CONNECTED" || state === "DEGRADED" ? "STALE" : state;
|
|
122
|
+
default: {
|
|
123
|
+
const unreachable = event;
|
|
124
|
+
return unreachable;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/** One sentence per state, written for a person rather than for a log. */
|
|
129
|
+
export const connectionSentence = {
|
|
130
|
+
NOT_CONFIGURED: "Not connected.",
|
|
131
|
+
DETECTED: "Found on this machine but not collecting yet.",
|
|
132
|
+
NEEDS_AUTH: "Waiting for a credential.",
|
|
133
|
+
READY_TO_ENABLE: "Ready to start collecting.",
|
|
134
|
+
CONNECTING: "Connecting.",
|
|
135
|
+
CONNECTED: "Connected and collecting.",
|
|
136
|
+
DEGRADED: "The provider is refusing reads for now.",
|
|
137
|
+
STALE: "The last reading is older than it should be.",
|
|
138
|
+
AUTH_EXPIRED: "The stored credential stopped working.",
|
|
139
|
+
IMPORT_ONLY: "Reads only what you import. Nothing is collected automatically.",
|
|
140
|
+
MANUAL: "Shows the plan you entered yourself.",
|
|
141
|
+
UNSUPPORTED: "No safe automatic source exists for this product yet.",
|
|
142
|
+
ERROR: "This connection failed and needs a look."
|
|
143
|
+
};
|
|
144
|
+
/** The one thing to do next, in the words of the button that does it. */
|
|
145
|
+
export const connectionNextAction = {
|
|
146
|
+
NOT_CONFIGURED: "Connect",
|
|
147
|
+
DETECTED: "Enable local integration",
|
|
148
|
+
NEEDS_AUTH: "Add credential",
|
|
149
|
+
READY_TO_ENABLE: "Enable",
|
|
150
|
+
CONNECTING: "Wait",
|
|
151
|
+
CONNECTED: "Refresh now",
|
|
152
|
+
DEGRADED: "Wait for the next retry",
|
|
153
|
+
STALE: "Refresh now",
|
|
154
|
+
AUTH_EXPIRED: "Reconnect",
|
|
155
|
+
IMPORT_ONLY: "Import a payload",
|
|
156
|
+
MANUAL: "Edit plan",
|
|
157
|
+
UNSUPPORTED: "Add manual plan",
|
|
158
|
+
ERROR: "View diagnostics"
|
|
159
|
+
};
|
|
160
|
+
/** The five providers on the Connect and See catalogue surface. */
|
|
161
|
+
export const CATALOGUE_PROVIDER_IDS = [
|
|
162
|
+
"claude",
|
|
163
|
+
"openrouter",
|
|
164
|
+
"codex",
|
|
165
|
+
"antigravity",
|
|
166
|
+
"opencode"
|
|
167
|
+
];
|
|
168
|
+
const supported = {
|
|
169
|
+
mode: "automatic",
|
|
170
|
+
maturity: "supported",
|
|
171
|
+
label: "Supported"
|
|
172
|
+
};
|
|
173
|
+
const eventDriven = {
|
|
174
|
+
mode: "event_driven",
|
|
175
|
+
maturity: "supported",
|
|
176
|
+
label: "Event driven"
|
|
177
|
+
};
|
|
178
|
+
const experimental = {
|
|
179
|
+
mode: "automatic",
|
|
180
|
+
maturity: "experimental",
|
|
181
|
+
label: "Experimental"
|
|
182
|
+
};
|
|
183
|
+
const manual = {
|
|
184
|
+
mode: "manual",
|
|
185
|
+
maturity: "supported",
|
|
186
|
+
label: "Manual"
|
|
187
|
+
};
|
|
188
|
+
const manualExperimental = {
|
|
189
|
+
mode: "manual",
|
|
190
|
+
maturity: "experimental",
|
|
191
|
+
label: "Manual experimental"
|
|
192
|
+
};
|
|
193
|
+
const catalogueCapabilities = {
|
|
194
|
+
claude: { windows: eventDriven, macos: eventDriven, linux: eventDriven },
|
|
195
|
+
openrouter: { windows: supported, macos: supported, linux: supported },
|
|
196
|
+
codex: { windows: supported, macos: supported, linux: supported },
|
|
197
|
+
antigravity: { windows: experimental, macos: manual, linux: manual },
|
|
198
|
+
opencode: {
|
|
199
|
+
windows: manualExperimental,
|
|
200
|
+
macos: manualExperimental,
|
|
201
|
+
linux: manualExperimental
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
function isCatalogueProviderId(value) {
|
|
205
|
+
return typeof value === "string" &&
|
|
206
|
+
CATALOGUE_PROVIDER_IDS.includes(value);
|
|
207
|
+
}
|
|
208
|
+
function isCatalogueAuthMode(value) {
|
|
209
|
+
return value === "existing_local_cli" || value === "api_key" || value === "manual";
|
|
210
|
+
}
|
|
211
|
+
function catalogueState(value) {
|
|
212
|
+
return typeof value === "string" &&
|
|
213
|
+
CONNECTION_STATES.includes(value)
|
|
214
|
+
? value
|
|
215
|
+
: "NOT_CONFIGURED";
|
|
216
|
+
}
|
|
217
|
+
function actionFor(providerId, state) {
|
|
218
|
+
if (providerId === "codex" && (state === "NEEDS_AUTH" || state === "AUTH_EXPIRED")) {
|
|
219
|
+
return "Run codex login";
|
|
220
|
+
}
|
|
221
|
+
return connectionNextAction[state];
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Join generated provider facts to the closed connection state model.
|
|
225
|
+
*
|
|
226
|
+
* The generated document supplies identity, display name, auth mode and the
|
|
227
|
+
* platform set. Product capability maturity is the frozen overlay above. No
|
|
228
|
+
* site or local application is inspected at runtime.
|
|
229
|
+
*/
|
|
230
|
+
export function queryProviderCatalogue(generated, states = {}) {
|
|
231
|
+
if (!Array.isArray(generated.providers))
|
|
232
|
+
return [];
|
|
233
|
+
const found = new Map();
|
|
234
|
+
for (const candidate of generated.providers) {
|
|
235
|
+
if (candidate === null || typeof candidate !== "object")
|
|
236
|
+
continue;
|
|
237
|
+
const entry = candidate;
|
|
238
|
+
const providerId = entry.honesty?.connectorId;
|
|
239
|
+
if (!isCatalogueProviderId(providerId))
|
|
240
|
+
continue;
|
|
241
|
+
found.set(providerId, entry);
|
|
242
|
+
}
|
|
243
|
+
const catalogue = [];
|
|
244
|
+
for (const providerId of CATALOGUE_PROVIDER_IDS) {
|
|
245
|
+
const source = found.get(providerId);
|
|
246
|
+
if (source === undefined || typeof source.displayName !== "string")
|
|
247
|
+
continue;
|
|
248
|
+
if (!Array.isArray(source.authModes) || !isCatalogueAuthMode(source.authModes[0]))
|
|
249
|
+
continue;
|
|
250
|
+
const platforms = source.platforms;
|
|
251
|
+
if (!Array.isArray(platforms))
|
|
252
|
+
continue;
|
|
253
|
+
const hasEveryPlatform = ["windows", "macos", "linux"]
|
|
254
|
+
.every((platform) => platforms.includes(platform));
|
|
255
|
+
if (!hasEveryPlatform)
|
|
256
|
+
continue;
|
|
257
|
+
const connectionState = catalogueState(states[providerId]);
|
|
258
|
+
catalogue.push({
|
|
259
|
+
providerId,
|
|
260
|
+
displayName: source.displayName,
|
|
261
|
+
connectionState,
|
|
262
|
+
capabilities: catalogueCapabilities[providerId],
|
|
263
|
+
authMode: source.authModes[0],
|
|
264
|
+
action: actionFor(providerId, connectionState)
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
return catalogue;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* The connections surface showing connectable providers and planned products.
|
|
271
|
+
*
|
|
272
|
+
* The product catalogue presents every supported or planned provider in document
|
|
273
|
+
* order after the connectable set. Planned rows carry no connection state because
|
|
274
|
+
* no background collector or credential exists for them.
|
|
275
|
+
*/
|
|
276
|
+
export function queryCatalogueRows(generated, states = {}) {
|
|
277
|
+
const connectableRows = queryProviderCatalogue(generated, states).map((entry) => ({
|
|
278
|
+
availability: "connectable",
|
|
279
|
+
...entry
|
|
280
|
+
}));
|
|
281
|
+
if (!Array.isArray(generated.providers))
|
|
282
|
+
return connectableRows;
|
|
283
|
+
const plannedRows = [];
|
|
284
|
+
for (const candidate of generated.providers) {
|
|
285
|
+
if (candidate === null || typeof candidate !== "object")
|
|
286
|
+
continue;
|
|
287
|
+
const entry = candidate;
|
|
288
|
+
const connectorId = entry.honesty?.connectorId;
|
|
289
|
+
if (connectorId === "manual")
|
|
290
|
+
continue;
|
|
291
|
+
if (isCatalogueProviderId(connectorId))
|
|
292
|
+
continue;
|
|
293
|
+
if (typeof entry.id !== "string" || typeof entry.displayName !== "string")
|
|
294
|
+
continue;
|
|
295
|
+
plannedRows.push({
|
|
296
|
+
availability: "planned",
|
|
297
|
+
specId: entry.id,
|
|
298
|
+
displayName: entry.displayName,
|
|
299
|
+
action: "Planned"
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
return [...connectableRows, ...plannedRows];
|
|
303
|
+
}
|
|
304
|
+
//# sourceMappingURL=connection-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-state.js","sourceRoot":"","sources":["../src/connection-state.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export * from "./cache.js";
|
|
2
|
+
export * from "./collection.js";
|
|
3
|
+
export * from "./connection-state.js";
|
|
2
4
|
export * from "./failures.js";
|
|
3
5
|
export * from "./forecast.js";
|
|
4
6
|
export * from "./format.js";
|
|
@@ -6,5 +8,6 @@ export * from "./freshness.js";
|
|
|
6
8
|
export * from "./merge.js";
|
|
7
9
|
export * from "./normalizer.js";
|
|
8
10
|
export * from "./policy.js";
|
|
11
|
+
export * from "./schedule.js";
|
|
9
12
|
export * from "./types.js";
|
|
10
13
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export * from "./cache.js";
|
|
2
|
+
export * from "./collection.js";
|
|
3
|
+
export * from "./connection-state.js";
|
|
2
4
|
export * from "./failures.js";
|
|
3
5
|
export * from "./forecast.js";
|
|
4
6
|
export * from "./format.js";
|
|
@@ -6,5 +8,6 @@ export * from "./freshness.js";
|
|
|
6
8
|
export * from "./merge.js";
|
|
7
9
|
export * from "./normalizer.js";
|
|
8
10
|
export * from "./policy.js";
|
|
11
|
+
export * from "./schedule.js";
|
|
9
12
|
export * from "./types.js";
|
|
10
13
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC"}
|
package/dist/merge.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Snapshot } from "./types.js";
|
|
2
2
|
/** Hard ceiling on how many snapshots one cache file may carry. */
|
|
3
3
|
export declare const MAX_CACHE_ENTRIES = 64;
|
|
4
|
+
export declare function snapshotIdentity(snapshot: Snapshot): string;
|
|
4
5
|
/**
|
|
5
6
|
* Combine cached snapshots with freshly observed ones.
|
|
6
7
|
*
|
package/dist/merge.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../src/merge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,mEAAmE;AACnE,eAAO,MAAM,iBAAiB,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../src/merge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,mEAAmE;AACnE,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAYpC,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAG3D;AAeD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,SAAS,QAAQ,EAAE,EAC7B,QAAQ,EAAE,SAAS,QAAQ,EAAE,EAC7B,KAAK,SAAoB,GACxB,QAAQ,EAAE,CAUZ"}
|
package/dist/merge.js
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
/** Hard ceiling on how many snapshots one cache file may carry. */
|
|
2
2
|
export const MAX_CACHE_ENTRIES = 64;
|
|
3
3
|
/*
|
|
4
|
-
* A provider code
|
|
5
|
-
* no spaces, so joining them with one space cannot collide.
|
|
4
|
+
* A provider code, a meter name and an account id are all closed identifiers
|
|
5
|
+
* with no spaces, so joining them with one space cannot collide.
|
|
6
|
+
*
|
|
7
|
+
* The account id joins the key only when the row states one. A row without an
|
|
8
|
+
* account therefore keys exactly as it always did, which is what lets a cache
|
|
9
|
+
* written before accounts existed merge with one written after without any row
|
|
10
|
+
* changing identity or duplicating itself. Two rows for the same meter under
|
|
11
|
+
* different accounts are two rows, which is the whole point of the field.
|
|
6
12
|
*/
|
|
7
|
-
function
|
|
8
|
-
|
|
13
|
+
export function snapshotIdentity(snapshot) {
|
|
14
|
+
const base = snapshot.provider + " " + snapshot.meter;
|
|
15
|
+
return snapshot.accountId === undefined ? base : base + " " + snapshot.accountId;
|
|
9
16
|
}
|
|
17
|
+
const identity = snapshotIdentity;
|
|
10
18
|
function compareIdentity(left, right) {
|
|
11
19
|
const leftKey = identity(left);
|
|
12
20
|
const rightKey = identity(right);
|
package/dist/merge.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge.js","sourceRoot":"","sources":["../src/merge.ts"],"names":[],"mappings":"AAEA,mEAAmE;AACnE,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAEpC
|
|
1
|
+
{"version":3,"file":"merge.js","sourceRoot":"","sources":["../src/merge.ts"],"names":[],"mappings":"AAEA,mEAAmE;AACnE,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAEpC;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAkB;IACjD,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,GAAG,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC;IACtD,OAAO,QAAQ,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC;AACnF,CAAC;AAED,MAAM,QAAQ,GAAG,gBAAgB,CAAC;AAElC,SAAS,eAAe,CAAC,IAAc,EAAE,KAAe;IACtD,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACjC,OAAO,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,oBAAoB,CAAC,QAAkB;IAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC/C,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAC5B,QAA6B,EAC7B,QAA6B,EAC7B,KAAK,GAAG,iBAAiB;IAEzB,MAAM,UAAU,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC/C,KAAK,MAAM,QAAQ,IAAI,QAAQ;QAAE,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC9E,KAAK,MAAM,QAAQ,IAAI,QAAQ;QAAE,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC9E,MAAM,MAAM,GAAG,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;IACxC,IAAI,MAAM,CAAC,MAAM,IAAI,KAAK;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAChE,OAAO,MAAM;SACV,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,oBAAoB,CAAC,KAAK,CAAC,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;SAC/E,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;SACf,IAAI,CAAC,eAAe,CAAC,CAAC;AAC3B,CAAC"}
|
package/dist/normalizer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalizer.d.ts","sourceRoot":"","sources":["../src/normalizer.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"normalizer.d.ts","sourceRoot":"","sources":["../src/normalizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,YAAY,EACjB,KAAK,QAAQ,EACb,KAAK,QAAQ,EAUd,MAAM,YAAY,CAAC;AAyIpB,wBAAgB,cAAc,CAAC,GAAG,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI,CA0C7D;AAED,wBAAgB,eAAe,CAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAK1E;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,sEAAsE;IACtE,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IAClC,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,SAAS,QAAQ,EAAE,GAC7B,eAAe,CAgBjB;AAUD,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEpD"}
|
package/dist/normalizer.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MAX_SNAPSHOT_AMOUNT, PROVIDER_CODES } from "./types.js";
|
|
1
|
+
import { ACCOUNT_ID_PATTERN, MAX_SNAPSHOT_AMOUNT, PROVIDER_CODES, SNAPSHOT_OBSERVED_VIA, SNAPSHOT_SOURCE_KINDS, UNKNOWN_PROVENANCE } from "./types.js";
|
|
2
2
|
const units = new Set(["PERCENT", "CREDITS", "TOKENS", "REQUESTS"]);
|
|
3
3
|
const sources = new Set([
|
|
4
4
|
"native_payload",
|
|
@@ -10,6 +10,8 @@ const sources = new Set([
|
|
|
10
10
|
const precisions = new Set(["exact", "estimated", "manual"]);
|
|
11
11
|
const currencies = new Set(["USD"]);
|
|
12
12
|
const providerCodes = new Set(PROVIDER_CODES);
|
|
13
|
+
const sourceKinds = new Set(SNAPSHOT_SOURCE_KINDS);
|
|
14
|
+
const observedVia = new Set(SNAPSHOT_OBSERVED_VIA);
|
|
13
15
|
const safeMeter = /^[A-Z][A-Z0-9_]{0,31}$/u;
|
|
14
16
|
function isRecord(value) {
|
|
15
17
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -96,6 +98,46 @@ function normalizeAmounts(raw) {
|
|
|
96
98
|
return null;
|
|
97
99
|
return { usedAmount: used, limitAmount: limit, currency: currency };
|
|
98
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Read the account this reading belongs to.
|
|
103
|
+
*
|
|
104
|
+
* Absent is the ordinary case and means one unnamed account. Present but
|
|
105
|
+
* malformed is the dangerous case, because an identity we cannot trust would
|
|
106
|
+
* quietly split or merge a user's meters in the cache, so that row is refused
|
|
107
|
+
* outright rather than stripped back to the unnamed account.
|
|
108
|
+
*/
|
|
109
|
+
function readAccountId(value) {
|
|
110
|
+
if (value === undefined)
|
|
111
|
+
return { ok: true, accountId: null };
|
|
112
|
+
if (typeof value !== "string" || !ACCOUNT_ID_PATTERN.test(value))
|
|
113
|
+
return { ok: false };
|
|
114
|
+
return { ok: true, accountId: value };
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Read how the observation arrived.
|
|
118
|
+
*
|
|
119
|
+
* The opposite call to the one above, and deliberately so. Provenance is a
|
|
120
|
+
* label on a reading, not part of its identity, so a provenance we cannot read
|
|
121
|
+
* costs the reading nothing: it becomes unknown and the number survives. Either
|
|
122
|
+
* field failing makes the whole thing unknown, because half a provenance would
|
|
123
|
+
* invite a surface to describe a source it cannot actually vouch for.
|
|
124
|
+
*/
|
|
125
|
+
function readProvenance(value) {
|
|
126
|
+
if (value === undefined)
|
|
127
|
+
return null;
|
|
128
|
+
if (!isRecord(value))
|
|
129
|
+
return UNKNOWN_PROVENANCE;
|
|
130
|
+
const kind = value["sourceKind"];
|
|
131
|
+
const via = value["observedVia"];
|
|
132
|
+
if (typeof kind !== "string" || !sourceKinds.has(kind))
|
|
133
|
+
return UNKNOWN_PROVENANCE;
|
|
134
|
+
if (typeof via !== "string" || !observedVia.has(via))
|
|
135
|
+
return UNKNOWN_PROVENANCE;
|
|
136
|
+
return {
|
|
137
|
+
sourceKind: kind,
|
|
138
|
+
observedVia: via
|
|
139
|
+
};
|
|
140
|
+
}
|
|
99
141
|
export function normalizeMeter(raw) {
|
|
100
142
|
if (typeof raw.provider !== "string" || !providerCodes.has(raw.provider))
|
|
101
143
|
return null;
|
|
@@ -126,6 +168,10 @@ export function normalizeMeter(raw) {
|
|
|
126
168
|
return null;
|
|
127
169
|
if (Date.parse(raw.expiresAt) < Date.parse(raw.observedAt))
|
|
128
170
|
return null;
|
|
171
|
+
const account = readAccountId(raw.accountId);
|
|
172
|
+
if (!account.ok)
|
|
173
|
+
return null;
|
|
174
|
+
const provenance = readProvenance(raw.provenance);
|
|
129
175
|
const amounts = normalizeAmounts(raw);
|
|
130
176
|
return {
|
|
131
177
|
provider: raw.provider,
|
|
@@ -139,7 +185,9 @@ export function normalizeMeter(raw) {
|
|
|
139
185
|
observedAt: raw.observedAt,
|
|
140
186
|
expiresAt: raw.expiresAt,
|
|
141
187
|
labels,
|
|
142
|
-
...(amounts === null ? {} : amounts)
|
|
188
|
+
...(amounts === null ? {} : amounts),
|
|
189
|
+
...(account.accountId === null ? {} : { accountId: account.accountId }),
|
|
190
|
+
...(provenance === null ? {} : { provenance })
|
|
143
191
|
};
|
|
144
192
|
}
|
|
145
193
|
export function normalizeMeters(rawMeters) {
|
package/dist/normalizer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalizer.js","sourceRoot":"","sources":["../src/normalizer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,cAAc,
|
|
1
|
+
{"version":3,"file":"normalizer.js","sourceRoot":"","sources":["../src/normalizer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* When a connection may next ask its provider a question.
|
|
3
|
+
*
|
|
4
|
+
* Background collection is the difference between a quota monitor and a file
|
|
5
|
+
* viewer, and a collector that retries a failing provider on a fixed interval
|
|
6
|
+
* is how a monitor gets an account rate limited. The whole policy lives here as
|
|
7
|
+
* arithmetic over injected values: the caller supplies the clock and the random
|
|
8
|
+
* source, so a schedule is exactly reproducible in a test and identical on all
|
|
9
|
+
* three operating systems.
|
|
10
|
+
*/
|
|
11
|
+
/** Longest our own backoff will ever grow to on its own. */
|
|
12
|
+
export declare const REFRESH_BACKOFF_CEILING_SECONDS = 3600;
|
|
13
|
+
/**
|
|
14
|
+
* Longest a provider may push us out with Retry-After.
|
|
15
|
+
*
|
|
16
|
+
* The header is honoured because the provider knows its own limits better than
|
|
17
|
+
* we do, but a header is still input from outside, and a day is already far
|
|
18
|
+
* past the point where a person would reconnect by hand.
|
|
19
|
+
*/
|
|
20
|
+
export declare const REFRESH_RETRY_AFTER_CEILING_SECONDS = 86400;
|
|
21
|
+
/** How far either side of the computed delay the jitter may move it. */
|
|
22
|
+
export declare const REFRESH_JITTER_RATIO = 0.2;
|
|
23
|
+
/** The reader supplied sentinel for a connection that only refreshes by hand. */
|
|
24
|
+
export declare const SCHEDULE_EXEMPT_BASE_SECONDS = 0;
|
|
25
|
+
/** Missing wire cadence fails closed to the most conservative live default. */
|
|
26
|
+
export declare const REFRESH_FALLBACK_BASE_SECONDS = 300;
|
|
27
|
+
/** A stable scheduled instant for a connection exempt from background reads. */
|
|
28
|
+
export declare const SCHEDULE_EXEMPT_INSTANT = "9999-12-31T23:59:59.999Z";
|
|
29
|
+
export interface RefreshInput {
|
|
30
|
+
/**
|
|
31
|
+
* Consecutive failures behind this schedule. Zero means the last attempt
|
|
32
|
+
* succeeded, so the delay is the plain interval with jitter on it.
|
|
33
|
+
*/
|
|
34
|
+
attempt: number;
|
|
35
|
+
/** The interval this connection uses when nothing is failing, in seconds. */
|
|
36
|
+
baseSeconds: number;
|
|
37
|
+
/** Retry-After in seconds when the provider sent one, otherwise null. */
|
|
38
|
+
retryAfterSeconds?: number | null;
|
|
39
|
+
/** Injected uniform random in the range zero to one. */
|
|
40
|
+
random: () => number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The delay before the next attempt, in seconds.
|
|
44
|
+
*
|
|
45
|
+
* Doubling per consecutive failure, capped at an hour, then jittered by up to
|
|
46
|
+
* a fifth either way so a hundred installations that all failed at the same
|
|
47
|
+
* moment do not all come back at the same moment.
|
|
48
|
+
*
|
|
49
|
+
* The order matters and is the whole subtlety here. Jitter is applied to OUR
|
|
50
|
+
* backoff and to nothing else, and the provider's Retry-After is then taken as
|
|
51
|
+
* a floor underneath the jittered result. Jittering a Retry-After instead would
|
|
52
|
+
* subtract up to a fifth from an instruction the provider gave us: a header
|
|
53
|
+
* asking for a day back would come back as nineteen hours and knock on the door
|
|
54
|
+
* almost five hours early, which is precisely the behaviour that gets an account
|
|
55
|
+
* limited harder. Jitter exists to spread our own retries, so it may only ever
|
|
56
|
+
* move our own number. A Retry-After shorter than our backoff changes nothing,
|
|
57
|
+
* because a provider cannot talk us out of backing off.
|
|
58
|
+
*/
|
|
59
|
+
export declare function refreshDelaySeconds(input: RefreshInput): number;
|
|
60
|
+
/**
|
|
61
|
+
* The instant of the next attempt, or null when the supplied clock is not a
|
|
62
|
+
* readable instant. Nothing is guessed from a clock we cannot read.
|
|
63
|
+
*/
|
|
64
|
+
export declare function nextRefreshAt(now: string, input: RefreshInput): string | null;
|
|
65
|
+
/**
|
|
66
|
+
* Whether a scheduled instant has arrived.
|
|
67
|
+
*
|
|
68
|
+
* A schedule we cannot read counts as due. The alternative is a connection that
|
|
69
|
+
* never refreshes again because one unreadable value got written once, and the
|
|
70
|
+
* first successful attempt replaces it with a readable one. A clock we cannot
|
|
71
|
+
* read is the opposite case and counts as not due, because with no present
|
|
72
|
+
* moment there is nothing to compare against.
|
|
73
|
+
*/
|
|
74
|
+
export declare function isDue(nextAt: string | null, now: string): boolean;
|
|
75
|
+
//# sourceMappingURL=schedule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../src/schedule.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,4DAA4D;AAC5D,eAAO,MAAM,+BAA+B,OAAQ,CAAC;AAErD;;;;;;GAMG;AACH,eAAO,MAAM,mCAAmC,QAAS,CAAC;AAE1D,wEAAwE;AACxE,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC,iFAAiF;AACjF,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAE9C,+EAA+E;AAC/E,eAAO,MAAM,6BAA6B,MAAM,CAAC;AAEjD,gFAAgF;AAChF,eAAO,MAAM,uBAAuB,6BAA6B,CAAC;AAElE,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,WAAW,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,wDAAwD;IACxD,MAAM,EAAE,MAAM,MAAM,CAAC;CACtB;AAuCD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAY/D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAU7E;AAED;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAOjE"}
|