aweshare 0.6.8 → 0.7.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.
Files changed (47) hide show
  1. package/README.md +6 -3
  2. package/apps/agent/dist/cli.js +3 -4
  3. package/apps/agent/dist/cli.js.map +1 -1
  4. package/apps/agent/dist/config.d.ts +4 -1
  5. package/apps/agent/dist/config.js +5 -0
  6. package/apps/agent/dist/config.js.map +1 -1
  7. package/apps/agent/dist/connection.js +4 -0
  8. package/apps/agent/dist/connection.js.map +1 -1
  9. package/apps/agent/dist/doctor.js +3 -1
  10. package/apps/agent/dist/doctor.js.map +1 -1
  11. package/apps/agent/dist/table.js +7 -7
  12. package/apps/agent/dist/table.js.map +1 -1
  13. package/apps/consumer/dist/cli.js +65 -8
  14. package/apps/consumer/dist/cli.js.map +1 -1
  15. package/apps/consumer/dist/table.js +2 -2
  16. package/apps/consumer/dist/table.js.map +1 -1
  17. package/apps/consumer/dist/watch.d.ts +18 -0
  18. package/apps/consumer/dist/watch.js +69 -0
  19. package/apps/consumer/dist/watch.js.map +1 -0
  20. package/apps/hub/dist/cli.js +3 -4
  21. package/apps/hub/dist/cli.js.map +1 -1
  22. package/apps/hub/dist/consumer.d.ts +1 -1
  23. package/apps/hub/dist/consumer.js +4 -4
  24. package/apps/hub/dist/consumer.js.map +1 -1
  25. package/apps/hub/dist/local.d.ts +1 -1
  26. package/apps/hub/dist/local.js +5 -1
  27. package/apps/hub/dist/local.js.map +1 -1
  28. package/apps/hub/dist/table.js +14 -8
  29. package/apps/hub/dist/table.js.map +1 -1
  30. package/apps/hub/dist/tunnel.d.ts +1 -1
  31. package/apps/hub/dist/tunnel.js +4 -1
  32. package/apps/hub/dist/tunnel.js.map +1 -1
  33. package/package.json +1 -1
  34. package/packages/producer-core/dist/catalog.d.ts +7 -0
  35. package/packages/producer-core/dist/catalog.js +5 -1
  36. package/packages/producer-core/dist/catalog.js.map +1 -1
  37. package/packages/producer-core/dist/health.d.ts +28 -8
  38. package/packages/producer-core/dist/health.js +63 -8
  39. package/packages/producer-core/dist/health.js.map +1 -1
  40. package/packages/protocol/dist/format.d.ts +6 -0
  41. package/packages/protocol/dist/format.js +9 -0
  42. package/packages/protocol/dist/format.js.map +1 -0
  43. package/packages/protocol/dist/index.d.ts +1 -0
  44. package/packages/protocol/dist/index.js +1 -0
  45. package/packages/protocol/dist/index.js.map +1 -1
  46. package/packages/protocol/dist/messages.d.ts +7 -3
  47. package/packages/protocol/dist/messages.js.map +1 -1
@@ -1,5 +1,15 @@
1
+ /** Consecutive upstream 5xx failures >= threshold -> 'unstable': report-only
2
+ * middle state — the alias stays listed and dispatch continues, consumers just
3
+ * see the warning and the errors keep passing through verbatim. */
4
+ const UNSTABLE_THRESHOLD = 2;
1
5
  /** AUTH/QUOTA consecutive failures >= threshold -> degraded until a success. */
2
6
  const DEGRADE_THRESHOLD = 2;
7
+ /** SERVER (upstream 5xx) consecutive failures >= threshold -> degraded, and
8
+ * only when `degradeOn5xx` opted in. Higher than AUTH/QUOTA's 2: a 401 is a
9
+ * deterministic account verdict, while 5xx pairs also come from transient
10
+ * upstream blips — degrading those would turn a momentary hiccup into a
11
+ * full 503 outage for every consumer on the alias. */
12
+ const SERVER_DEGRADE_THRESHOLD = 3;
3
13
  // Recovery-probe backoff, awewarm-style: while degraded, each failed probe
4
14
  // doubles the wait before the next one, so an exhausted quota isn't pinged at
5
15
  // the base cadence for hours on end. Any success clears the degraded state
@@ -21,14 +31,20 @@ const PROBE_CAP_SCHEDULE = [
21
31
  ];
22
32
  /**
23
33
  * Per-backend health state. Degraded backends are reported in heartbeats and
24
- * the hub stops dispatching to their offerings until they recover. The
25
- * ladder is two rungs — healthy -> degraded, latched until a success — which
34
+ * the hub stops dispatching to their offerings until they recover. The ladder
35
+ * is two rungs — healthy -> degraded, latched until a success — which
26
36
  * for a relay is what awewarm's deeper ladder collapses to: its intermediate
27
37
  * rungs trade probe expense against recovery speed, and a relay's probes are
28
38
  * cheap pings, not quota-consuming activations. What does carry over from
29
39
  * awewarm is the escalating probe schedule above: the longer a backend has
30
40
  * been continuously degraded, the quieter its recovery probes become, down
31
41
  * to a daily last gasp that never fully gives up.
42
+ *
43
+ * Upstream 5xx gets its own two-step path: 2 consecutive SERVER failures
44
+ * enter the report-only 'unstable' state (alias stays listed and dispatched,
45
+ * consumers see the warning), and with `degradeOn5xx` opted in, 3
46
+ * consecutive degrade for real. AUTH/QUOTA verdicts skip the middle state —
47
+ * they are deterministic account facts, not symptoms.
32
48
  */
33
49
  export class HealthGate {
34
50
  now;
@@ -38,6 +54,13 @@ export class HealthGate {
38
54
  probeDelayMs = new Map();
39
55
  probeNotBefore = new Map();
40
56
  lastOk = new Map();
57
+ /** Backends sitting in the report-only middle state (2+ consecutive 5xx). */
58
+ unstable = new Set();
59
+ /** Opt-in enforcement step for upstream 5xx: 3+ consecutive SERVER failures
60
+ * degrade the backend (dispatch stops). Off by default — a 5xx is a symptom,
61
+ * not a verdict, so by default it only ever reports (unstable). Hot-reloaded
62
+ * by the config watcher; flipping it mid-flight affects the next failure. */
63
+ degradeOn5xx = false;
41
64
  /** The clock is injected so tests can walk the cap ladder without waiting. */
42
65
  constructor(now = Date.now) {
43
66
  this.now = now;
@@ -47,10 +70,11 @@ export class HealthGate {
47
70
  this.lastOk.set(backendId, this.now());
48
71
  this.consecutive.delete(backendId);
49
72
  const wasDegraded = this.degraded.delete(backendId);
73
+ const wasUnstable = this.unstable.delete(backendId);
50
74
  this.degradedSince.delete(backendId);
51
75
  this.probeDelayMs.delete(backendId);
52
76
  this.probeNotBefore.delete(backendId);
53
- return wasDegraded ? 'recovered' : null;
77
+ return wasDegraded || wasUnstable ? 'recovered' : null;
54
78
  }
55
79
  if (reason === undefined || reason === 'CANCELLED')
56
80
  return null;
@@ -64,12 +88,23 @@ export class HealthGate {
64
88
  const count = current?.reason === reason ? current.count + 1 : 1;
65
89
  this.consecutive.set(backendId, { reason, count });
66
90
  let transition = null;
67
- if ((reason === 'AUTH' || reason === 'QUOTA') && count >= DEGRADE_THRESHOLD) {
91
+ const degradeNow = ((reason === 'AUTH' || reason === 'QUOTA') && count >= DEGRADE_THRESHOLD) ||
92
+ (reason === 'SERVER' && this.degradeOn5xx && count >= SERVER_DEGRADE_THRESHOLD);
93
+ if (degradeNow) {
68
94
  if (!wasDegraded) {
69
95
  transition = 'degraded';
70
96
  this.degradedSince.set(backendId, this.now());
71
97
  }
72
98
  this.degraded.set(backendId, { state: 'degraded', reason });
99
+ this.unstable.delete(backendId);
100
+ }
101
+ else if (reason === 'SERVER' && count >= UNSTABLE_THRESHOLD && !wasDegraded) {
102
+ // first crossing of the 5xx threshold: report only — dispatch keeps
103
+ // flowing so a transient upstream blip never becomes a full outage
104
+ if (!this.unstable.has(backendId)) {
105
+ this.unstable.add(backendId);
106
+ transition = 'unstable';
107
+ }
73
108
  }
74
109
  if (wasDegraded) {
75
110
  const since = this.degradedSince.get(backendId) ?? this.now();
@@ -90,10 +125,17 @@ export class HealthGate {
90
125
  isDegraded(backendId) {
91
126
  return this.degraded.has(backendId);
92
127
  }
128
+ /** The report-only middle state — listed and dispatched, just flagged. */
129
+ isUnstable(backendId) {
130
+ return this.unstable.has(backendId);
131
+ }
93
132
  statusMap() {
94
133
  const out = {};
95
134
  for (const [id, status] of this.degraded)
96
135
  out[id] = status;
136
+ for (const id of this.unstable)
137
+ if (out[id] === undefined)
138
+ out[id] = { state: 'unstable' };
97
139
  return out;
98
140
  }
99
141
  /** Epoch ms of the backend's last success (request or recovery probe); null
@@ -104,8 +146,9 @@ export class HealthGate {
104
146
  }
105
147
  /** Heartbeat payload covering every backend, not just the degraded ones:
106
148
  * one 'ok' entry carrying lastOkAt per healthy backend, the degraded entry
107
- * as statusMap would emit it. Old hubs ignore the extra 'ok' entries (their
108
- * status check only looks for state === 'degraded'). */
149
+ * as statusMap would emit it, and 'unstable' for 2+ consecutive-5xx
150
+ * backends. Old hubs ignore the extra entries (their status check only
151
+ * looks for state === 'degraded', so unstable renders as online there). */
109
152
  snapshot(ids) {
110
153
  const out = {};
111
154
  for (const id of ids) {
@@ -115,7 +158,10 @@ export class HealthGate {
115
158
  continue;
116
159
  }
117
160
  const at = this.lastOk.get(id);
118
- out[id] = at === undefined ? { state: 'ok' } : { state: 'ok', lastOkAt: at };
161
+ const lastOkAt = at === undefined ? {} : { lastOkAt: at };
162
+ out[id] = this.unstable.has(id)
163
+ ? { state: 'unstable', ...lastOkAt }
164
+ : { state: 'ok', ...lastOkAt };
119
165
  }
120
166
  return out;
121
167
  }
@@ -126,11 +172,18 @@ export function logHealthTransition(log, backendId, transition, detail) {
126
172
  if (transition === 'degraded') {
127
173
  log.warn(`backend ${backendId} degraded${detail ? ` (${detail})` : ''}`);
128
174
  }
175
+ else if (transition === 'unstable') {
176
+ log.warn(`backend ${backendId} unstable — upstream failing, still dispatching${detail ? ` (${detail})` : ''}`);
177
+ }
129
178
  else if (transition === 'recovered') {
130
179
  log.info(`backend ${backendId} recovered${detail ? ` — ${detail}` : ''}`);
131
180
  }
132
181
  }
133
- /** Map an upstream HTTP status to a failure class (ok responses pass null). */
182
+ /** Map an upstream HTTP status to a failure class (ok responses pass null).
183
+ * SERVER (5xx) means the upstream itself is failing — a symptom that reports
184
+ * early (unstable) and, opted-in, degrades when persistent. HTTP (other 4xx)
185
+ * is request-shaped trouble — one consumer's malformed request — and never
186
+ * touches the ladder. */
134
187
  export function classifyStatus(status) {
135
188
  if (status < 400)
136
189
  return null;
@@ -138,6 +191,8 @@ export function classifyStatus(status) {
138
191
  return 'AUTH';
139
192
  if (status === 402 || status === 429)
140
193
  return 'QUOTA';
194
+ if (status >= 500)
195
+ return 'SERVER';
141
196
  return 'HTTP';
142
197
  }
143
198
  //# sourceMappingURL=health.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"health.js","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"health.js","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /** Human-facing number rendering, kept alongside the time formatters: the
2
+ * wire, the SQLite rows and `--json` stay raw integers — only what a human
3
+ * reads is grouped. */
4
+ /** Thousands grouping with a fixed ',' — locale-independent so CLI output
5
+ * stays stable and diffable ('1000000' → '1,000,000'). Integers only. */
6
+ export declare function fmtTokens(n: number): string;
@@ -0,0 +1,9 @@
1
+ /** Human-facing number rendering, kept alongside the time formatters: the
2
+ * wire, the SQLite rows and `--json` stay raw integers — only what a human
3
+ * reads is grouped. */
4
+ /** Thousands grouping with a fixed ',' — locale-independent so CLI output
5
+ * stays stable and diffable ('1000000' → '1,000,000'). Integers only. */
6
+ export function fmtTokens(n) {
7
+ return String(n).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
8
+ }
9
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA;;uBAEuB;AAEvB;yEACyE;AACzE,MAAM,UAAU,SAAS,CAAC,CAAS;IACjC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAA;AACxD,CAAC"}
@@ -1,5 +1,6 @@
1
1
  export * from './alias.js';
2
2
  export * from './errors.js';
3
+ export * from './format.js';
3
4
  export * from './frames.js';
4
5
  export * from './messages.js';
5
6
  export * from './models.js';
@@ -1,5 +1,6 @@
1
1
  export * from './alias.js';
2
2
  export * from './errors.js';
3
+ export * from './format.js';
3
4
  export * from './frames.js';
4
5
  export * from './messages.js';
5
6
  export * from './models.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA"}
@@ -25,14 +25,18 @@ export interface Offering {
25
25
  /** Shared per-alias token budget per UTC day; hub default 1000000, 0 = unlimited. */
26
26
  dailyTokens?: number;
27
27
  }
28
- export type BackendState = 'ok' | 'degraded';
28
+ export type BackendState = 'ok' | 'unstable' | 'degraded';
29
29
  export interface BackendStatus {
30
30
  state: BackendState;
31
- /** Failure class when degraded: AUTH | QUOTA | HTTP | NETWORK | CANCELLED */
31
+ /** Failure class when degraded: AUTH | QUOTA | SERVER | HTTP | NETWORK | CANCELLED.
32
+ * 'unstable' entries carry no reason — they are always 2+ consecutive
33
+ * upstream 5xx (SERVER). Old hubs only check for state === 'degraded', so
34
+ * the extra 'unstable' state degrades gracefully to online there. */
32
35
  reason?: string;
33
36
  /** Epoch ms of the last successful upstream interaction (a relayed request
34
37
  * or a recovery probe); absent when the backend has never succeeded. Only
35
- * meaningful on 'ok' entries — the hub's freshness evidence for consumers. */
38
+ * meaningful on non-degraded entries — the hub's freshness evidence for
39
+ * consumers. */
36
40
  lastOkAt?: number;
37
41
  }
38
42
  export interface RegisterMessage {
@@ -1 +1 @@
1
- {"version":3,"file":"messages.js","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAA;AAI7B,MAAM,CAAC,MAAM,SAAS,GAAwB,CAAC,QAAQ,EAAE,WAAW,EAAE,WAAW,CAAC,CAAA;AAElF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAA6B;IACvD,MAAM,EAAE,aAAa;IACrB,SAAS,EAAE,kBAAkB;IAC7B,SAAS,EAAE,WAAW;CACvB,CAAA;AAED,gFAAgF;AAChF,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,OAAQ,eAA0C,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAA;AAC1E,CAAC;AAqHD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAS;IAClC,UAAU;IACV,WAAW;IACX,eAAe;IACf,cAAc;IACd,gBAAgB;IAChB,OAAO;IACP,YAAY;IACZ,eAAe;IACf,aAAa;IACb,gBAAgB;CACjB,CAAC,CAAA;AAEF,yEAAyE;AACzE,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,IAAI,MAAe,CAAA;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;IACpD,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;IACnD,CAAC;IACD,MAAM,IAAI,GAAI,MAA6B,CAAC,IAAI,CAAA;IAChD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,iCAAiC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAClE,CAAC;IACD,OAAO,MAAwB,CAAA;AACjC,CAAC"}
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAA;AAI7B,MAAM,CAAC,MAAM,SAAS,GAAwB,CAAC,QAAQ,EAAE,WAAW,EAAE,WAAW,CAAC,CAAA;AAElF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAA6B;IACvD,MAAM,EAAE,aAAa;IACrB,SAAS,EAAE,kBAAkB;IAC7B,SAAS,EAAE,WAAW;CACvB,CAAA;AAED,gFAAgF;AAChF,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,OAAQ,eAA0C,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAA;AAC1E,CAAC;AAyHD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAS;IAClC,UAAU;IACV,WAAW;IACX,eAAe;IACf,cAAc;IACd,gBAAgB;IAChB,OAAO;IACP,YAAY;IACZ,eAAe;IACf,aAAa;IACb,gBAAgB;CACjB,CAAC,CAAA;AAEF,yEAAyE;AACzE,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,IAAI,MAAe,CAAA;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;IACpD,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;IACnD,CAAC;IACD,MAAM,IAAI,GAAI,MAA6B,CAAC,IAAI,CAAA;IAChD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,iCAAiC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAClE,CAAC;IACD,OAAO,MAAwB,CAAA;AACjC,CAAC"}