@fougere/calls 0.9.3-alpha.0 → 0.11.0-alpha.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 (53) hide show
  1. package/README.md +1 -1
  2. package/dist/ErrorGroup.d.ts +20 -0
  3. package/dist/ErrorGroup.d.ts.map +1 -0
  4. package/dist/ErrorGroup.js +2 -0
  5. package/dist/ErrorGroup.js.map +1 -0
  6. package/dist/ErrorRing.d.ts +13 -0
  7. package/dist/ErrorRing.d.ts.map +1 -0
  8. package/dist/{rings.js → ErrorRing.js} +2 -54
  9. package/dist/ErrorRing.js.map +1 -0
  10. package/dist/KeepHandler.d.ts +3 -2
  11. package/dist/KeepHandler.d.ts.map +1 -1
  12. package/dist/KeepHandler.js +1 -1
  13. package/dist/KeepHandler.js.map +1 -1
  14. package/dist/LogLine.d.ts +12 -0
  15. package/dist/LogLine.d.ts.map +1 -0
  16. package/dist/LogLine.js +2 -0
  17. package/dist/LogLine.js.map +1 -0
  18. package/dist/LogRing.d.ts +8 -0
  19. package/dist/LogRing.d.ts.map +1 -0
  20. package/dist/LogRing.js +28 -0
  21. package/dist/LogRing.js.map +1 -0
  22. package/dist/QueryLine.d.ts +11 -0
  23. package/dist/QueryLine.d.ts.map +1 -0
  24. package/dist/QueryLine.js +2 -0
  25. package/dist/QueryLine.js.map +1 -0
  26. package/dist/QueryRing.d.ts +6 -0
  27. package/dist/QueryRing.d.ts.map +1 -0
  28. package/dist/QueryRing.js +7 -0
  29. package/dist/QueryRing.js.map +1 -0
  30. package/dist/Ring.d.ts +19 -0
  31. package/dist/Ring.d.ts.map +1 -0
  32. package/dist/Ring.js +23 -0
  33. package/dist/Ring.js.map +1 -0
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +3 -1
  36. package/dist/index.js.map +1 -1
  37. package/dist/panel.js +2 -2
  38. package/dist/panel.js.map +1 -1
  39. package/package.json +9 -9
  40. package/src/ErrorGroup.ts +16 -0
  41. package/src/ErrorRing.ts +53 -0
  42. package/src/KeepHandler.ts +3 -2
  43. package/src/LogLine.ts +12 -0
  44. package/src/LogRing.ts +28 -0
  45. package/src/QueryLine.ts +10 -0
  46. package/src/QueryRing.ts +8 -0
  47. package/src/Ring.ts +23 -0
  48. package/src/index.ts +3 -1
  49. package/src/panel.ts +2 -2
  50. package/dist/rings.d.ts +0 -74
  51. package/dist/rings.d.ts.map +0 -1
  52. package/dist/rings.js.map +0 -1
  53. package/src/rings.ts +0 -145
package/README.md CHANGED
@@ -9,7 +9,7 @@ extensions: [calls({ max: 500, panel: true })],
9
9
  ```
10
10
 
11
11
  What it sees that a middleware cannot: a call refused **before** any handler — an unknown
12
- route, an entity hosted elsewhere, a call arriving while the door drains — and the route
12
+ route, an entity hosted elsewhere, a call arriving while the facade drains — and the route
13
13
  kind of every call, so a local execution and a hop to another process read the same way.
14
14
  Beside the calls it keeps a bounded ring of log lines, of errors, and — when
15
15
  `@fougere/adapter-sql` is installed — of the statements each call issued.
@@ -0,0 +1,20 @@
1
+ /** One kind of refusal, and how often it happened. */
2
+ export interface ErrorGroup {
3
+ seq: number;
4
+ key: string;
5
+ code: string;
6
+ entity?: string;
7
+ operation?: string;
8
+ message: string;
9
+ count: number;
10
+ firstAt: number;
11
+ lastAt: number;
12
+ /** Which field was refused, for a VALIDATION_FAILED — the whole point of this source. */
13
+ fields: {
14
+ path: string;
15
+ message: string;
16
+ }[];
17
+ /** `dispatch` when a call carried it, `log` when it happened outside any call. */
18
+ from: 'dispatch' | 'log';
19
+ }
20
+ //# sourceMappingURL=ErrorGroup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorGroup.d.ts","sourceRoot":"","sources":["../src/ErrorGroup.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,yFAAyF;IACzF,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5C,kFAAkF;IAClF,IAAI,EAAE,UAAU,GAAG,KAAK,CAAC;CAC1B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ErrorGroup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorGroup.js","sourceRoot":"","sources":["../src/ErrorGroup.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ import { Ring } from './Ring.js';
2
+ import { type DispatchEvent, type LogRecord } from '@fougere/core';
3
+ import type { ErrorGroup } from './ErrorGroup.js';
4
+ /** What was refused, from TWO sources — and that is the point. */
5
+ export declare class ErrorRing extends Ring<ErrorGroup> {
6
+ private readonly byKey;
7
+ /** A refusal that a call carried. `details` reaches here intact, unlike a span's code. */
8
+ fromDispatch(event: DispatchEvent): void;
9
+ /** A line written at `error` level, which is how a failure outside any call speaks. */
10
+ fromLog(line: LogRecord): void;
11
+ private group;
12
+ }
13
+ //# sourceMappingURL=ErrorRing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorRing.d.ts","sourceRoot":"","sources":["../src/ErrorRing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAsB,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AACvF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,kEAAkE;AAClE,qBAAa,SAAU,SAAQ,IAAI,CAAC,UAAU,CAAC;IAC7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;IAEvD,0FAA0F;IAC1F,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAYvC;IAED,uFAAuF;IACvF,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAI7B;IAED,OAAO,CAAC,KAAK;CAqBd"}
@@ -1,45 +1,6 @@
1
+ import { Ring } from './Ring.js';
1
2
  import { dotted } from '@fougere/schema';
2
3
  import { validationErrorsOf } from '@fougere/core';
3
- /** How many each ring keeps. Bounded by a NUMBER, never by a duration. */
4
- const KEPT = 300;
5
- /** A bounded list that counts what it drops, so a busy moment never reads as a quiet one. */
6
- class Ring {
7
- max;
8
- held = [];
9
- seq = 0;
10
- lost = 0;
11
- constructor(max = KEPT) {
12
- this.max = max;
13
- }
14
- keep(make) {
15
- const record = make(++this.seq);
16
- this.held.push(record);
17
- if (this.held.length > this.max)
18
- this.lost += this.held.splice(0, this.held.length - this.max).length;
19
- return record;
20
- }
21
- since(cursor) {
22
- return { lines: this.held.filter((one) => one.seq > cursor), cursor: this.seq, dropped: this.lost };
23
- }
24
- }
25
- /** What this process logged. */
26
- export class LogRing extends Ring {
27
- record(line) {
28
- this.keep((seq) => ({
29
- seq,
30
- level: line.level,
31
- name: line.name,
32
- message: line.message,
33
- args: line.args.map(render),
34
- at: line.at,
35
- }));
36
- }
37
- }
38
- export class QueryRing extends Ring {
39
- record(event) {
40
- this.keep((seq) => ({ ...event, seq }));
41
- }
42
- }
43
4
  /** What was refused, from TWO sources — and that is the point. */
44
5
  export class ErrorRing extends Ring {
45
6
  byKey = new Map();
@@ -83,17 +44,4 @@ export class ErrorRing extends Ring {
83
44
  this.byKey.set(key, this.keep((seq) => ({ ...one, key, seq, count: 1, firstAt: at, lastAt: at })));
84
45
  }
85
46
  }
86
- /** An argument as one line. A live object would change under the reader; a string cannot. */
87
- function render(value) {
88
- if (typeof value === 'string')
89
- return value;
90
- if (value instanceof Error)
91
- return `${value.name}: ${value.message}`;
92
- try {
93
- return JSON.stringify(value) ?? String(value);
94
- }
95
- catch {
96
- return String(value);
97
- }
98
- }
99
- //# sourceMappingURL=rings.js.map
47
+ //# sourceMappingURL=ErrorRing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorRing.js","sourceRoot":"","sources":["../src/ErrorRing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAsC,MAAM,eAAe,CAAC;AAGvF,kEAAkE;AAClE,MAAM,OAAO,SAAU,SAAQ,IAAgB;IAC5B,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;IAEvD,0FAA0F;IAC1F,YAAY,CAAC,KAAoB;QAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,KAA2E,CAAC;QAChG,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;QAEjD,IAAI,CAAC,KAAK,CAAC;YACT,IAAI,EAAE,OAAO,KAAK,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB;YACrE,MAAM;YACN,SAAS;YACT,OAAO,EAAE,KAAK,EAAE,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;YAC9C,MAAM,EAAE,CAAC,kBAAkB,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAC1G,IAAI,EAAE,UAAU;SACjB,CAAC,CAAC;IACL,CAAC;IAED,uFAAuF;IACvF,OAAO,CAAC,IAAe;QACrB,IAAI,IAAI,CAAC,KAAK,KAAK,OAAO;YAAE,OAAO;QAEnC,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAClF,CAAC;IAEO,KAAK,CAAC,GAAqE;QACjF,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE,EAAE,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEtB,mFAAmF;QACnF,yDAAyD;QACzD,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;YAChB,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;YACjB,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;YAC3B,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;gBAAE,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;YACpD,kFAAkF;YAClF,mFAAmF;YACnF,yDAAyD;YACzD,IAAI,CAAC,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC;YACtB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACrG,CAAC;CACF"}
@@ -1,10 +1,11 @@
1
1
  import type { Fact, LogLine } from '@fougere/core';
2
- import { LogRing, ErrorRing } from './rings.js';
2
+ import { ErrorRing } from './ErrorRing.js';
3
+ import { LogRing } from './LogRing.js';
3
4
  /**
4
5
  * Every line this process logged, kept for the panel.
5
6
  *
6
7
  * A handler and not an `onLog` sink: accepting the fact IS the subscription, so the two
7
- * rings are filled by the same door every other reader goes through — with a validator,
8
+ * rings are filled by the same facade every other reader goes through — with a validator,
8
9
  * and with whatever middleware the app declared.
9
10
  *
10
11
  * The rings come from the container: the extension's `up` put them there, and this
@@ -1 +1 @@
1
- {"version":3,"file":"KeepHandler.d.ts","sourceRoot":"","sources":["../src/KeepHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEhD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,OAAO,OAAO,WAAW;IAClB,OAAO,CAAC,KAAK;IAAW,OAAO,CAAC,MAAM;IAAlD,YAAoB,KAAK,EAAE,OAAO,EAAU,MAAM,EAAE,SAAS,EAAI;IAEjE,0EAA0E;IACpE,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAI/C;CACF"}
1
+ {"version":3,"file":"KeepHandler.d.ts","sourceRoot":"","sources":["../src/KeepHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,OAAO,OAAO,WAAW;IAClB,OAAO,CAAC,KAAK;IAAW,OAAO,CAAC,MAAM;IAAlD,YAAoB,KAAK,EAAE,OAAO,EAAU,MAAM,EAAE,SAAS,EAAI;IAEjE,0EAA0E;IACpE,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAI/C;CACF"}
@@ -2,7 +2,7 @@
2
2
  * Every line this process logged, kept for the panel.
3
3
  *
4
4
  * A handler and not an `onLog` sink: accepting the fact IS the subscription, so the two
5
- * rings are filled by the same door every other reader goes through — with a validator,
5
+ * rings are filled by the same facade every other reader goes through — with a validator,
6
6
  * and with whatever middleware the app declared.
7
7
  *
8
8
  * The rings come from the container: the extension's `up` put them there, and this
@@ -1 +1 @@
1
- {"version":3,"file":"KeepHandler.js","sourceRoot":"","sources":["../src/KeepHandler.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,OAAO,OAAO,WAAW;IACV,KAAK;IAAmB,MAAM;IAAlD,YAAoB,KAAc,EAAU,MAAiB;qBAAzC,KAAK;sBAAmB,MAAM;IAAc,CAAC;IAEjE,0EAA0E;IAC1E,KAAK,CAAC,MAAM,CAAC,IAAmB;QAC9B,MAAM,MAAM,GAAG,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;QACzE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC1B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;CACF"}
1
+ {"version":3,"file":"KeepHandler.js","sourceRoot":"","sources":["../src/KeepHandler.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,OAAO,OAAO,WAAW;IACV,KAAK;IAAmB,MAAM;IAAlD,YAAoB,KAAc,EAAU,MAAiB;qBAAzC,KAAK;sBAAmB,MAAM;IAAc,CAAC;IAEjE,0EAA0E;IAC1E,KAAK,CAAC,MAAM,CAAC,IAAmB;QAC9B,MAAM,MAAM,GAAG,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;QACzE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC1B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ import { type LogRecord } from '@fougere/core';
2
+ /** One line this process wrote. `args` is the developer's own choice of what to record. */
3
+ export interface LogLine {
4
+ seq: number;
5
+ level: LogRecord['level'];
6
+ name: string;
7
+ message: string;
8
+ /** Rendered here, not held: a live object would let the panel show what it later became. */
9
+ args: string[];
10
+ at: number;
11
+ }
12
+ //# sourceMappingURL=LogLine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LogLine.d.ts","sourceRoot":"","sources":["../src/LogLine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,2FAA2F;AAC3F,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,4FAA4F;IAC5F,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;CACZ"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=LogLine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LogLine.js","sourceRoot":"","sources":["../src/LogLine.ts"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ import { Ring } from './Ring.js';
2
+ import { type LogRecord } from '@fougere/core';
3
+ import type { LogLine } from './LogLine.js';
4
+ /** What this process logged. */
5
+ export declare class LogRing extends Ring<LogLine> {
6
+ record(line: LogRecord): void;
7
+ }
8
+ //# sourceMappingURL=LogRing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LogRing.d.ts","sourceRoot":"","sources":["../src/LogRing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,gCAAgC;AAChC,qBAAa,OAAQ,SAAQ,IAAI,CAAC,OAAO,CAAC;IACxC,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAS5B;CACF"}
@@ -0,0 +1,28 @@
1
+ import { Ring } from './Ring.js';
2
+ /** What this process logged. */
3
+ export class LogRing extends Ring {
4
+ record(line) {
5
+ this.keep((seq) => ({
6
+ seq,
7
+ level: line.level,
8
+ name: line.name,
9
+ message: line.message,
10
+ args: line.args.map(render),
11
+ at: line.at,
12
+ }));
13
+ }
14
+ }
15
+ /** An argument as one line. A live object would change under the reader; a string cannot. */
16
+ function render(value) {
17
+ if (typeof value === 'string')
18
+ return value;
19
+ if (value instanceof Error)
20
+ return `${value.name}: ${value.message}`;
21
+ try {
22
+ return JSON.stringify(value) ?? String(value);
23
+ }
24
+ catch {
25
+ return String(value);
26
+ }
27
+ }
28
+ //# sourceMappingURL=LogRing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LogRing.js","sourceRoot":"","sources":["../src/LogRing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC,gCAAgC;AAChC,MAAM,OAAO,OAAQ,SAAQ,IAAa;IACxC,MAAM,CAAC,IAAe;QACpB,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YAClB,GAAG;YACH,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;YAC3B,EAAE,EAAE,IAAI,CAAC,EAAE;SACZ,CAAC,CAAC,CAAC;IACN,CAAC;CACF;AAED,6FAA6F;AAC7F,SAAS,MAAM,CAAC,KAAc;IAC5B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,KAAK,YAAY,KAAK;QAAE,OAAO,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;IACrE,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;AACH,CAAC"}
@@ -0,0 +1,11 @@
1
+ /** One statement, as the panel shows it — never a parameter's value. */
2
+ export interface QueryLine {
3
+ seq: number;
4
+ storage: string;
5
+ sql: string;
6
+ parameters: number;
7
+ ms: number;
8
+ failed: boolean;
9
+ at: number;
10
+ }
11
+ //# sourceMappingURL=QueryLine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryLine.d.ts","sourceRoot":"","sources":["../src/QueryLine.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,OAAO,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;CACZ"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=QueryLine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryLine.js","sourceRoot":"","sources":["../src/QueryLine.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import { Ring } from './Ring.js';
2
+ import type { QueryLine } from './QueryLine.js';
3
+ export declare class QueryRing extends Ring<QueryLine> {
4
+ record(event: Omit<QueryLine, 'seq'>): void;
5
+ }
6
+ //# sourceMappingURL=QueryRing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryRing.d.ts","sourceRoot":"","sources":["../src/QueryRing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,qBAAa,SAAU,SAAQ,IAAI,CAAC,SAAS,CAAC;IAC5C,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,IAAI,CAE1C;CACF"}
@@ -0,0 +1,7 @@
1
+ import { Ring } from './Ring.js';
2
+ export class QueryRing extends Ring {
3
+ record(event) {
4
+ this.keep((seq) => ({ ...event, seq }));
5
+ }
6
+ }
7
+ //# sourceMappingURL=QueryRing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryRing.js","sourceRoot":"","sources":["../src/QueryRing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,MAAM,OAAO,SAAU,SAAQ,IAAe;IAC5C,MAAM,CAAC,KAA6B;QAClC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;IAC1C,CAAC;CACF"}
package/dist/Ring.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ /** How many entries a ring keeps before the oldest falls off. */
2
+ export declare const KEPT = 300;
3
+ /** A bounded list that counts what it drops, so a busy moment never reads as a quiet one. */
4
+ export declare class Ring<T extends {
5
+ seq: number;
6
+ }> {
7
+ private readonly max;
8
+ protected readonly held: T[];
9
+ protected seq: number;
10
+ private lost;
11
+ constructor(max?: number);
12
+ protected keep(make: (seq: number) => T): T;
13
+ since(cursor: number): {
14
+ lines: T[];
15
+ cursor: number;
16
+ dropped: number;
17
+ };
18
+ }
19
+ //# sourceMappingURL=Ring.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Ring.d.ts","sourceRoot":"","sources":["../src/Ring.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,eAAO,MAAM,IAAI,MAAM,CAAC;AAExB,6FAA6F;AAC7F,qBAAa,IAAI,CAAC,CAAC,SAAS;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE;IAK7B,OAAO,CAAC,QAAQ,CAAC,GAAG;IAJhC,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,CAAM;IAClC,SAAS,CAAC,GAAG,SAAK;IAClB,OAAO,CAAC,IAAI,CAAK;IAEjB,YAA6B,GAAG,SAAO,EAAI;IAE3C,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,CAM1C;IAED,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAErE;CACF"}
package/dist/Ring.js ADDED
@@ -0,0 +1,23 @@
1
+ /** How many entries a ring keeps before the oldest falls off. */
2
+ export const KEPT = 300;
3
+ /** A bounded list that counts what it drops, so a busy moment never reads as a quiet one. */
4
+ export class Ring {
5
+ max;
6
+ held = [];
7
+ seq = 0;
8
+ lost = 0;
9
+ constructor(max = KEPT) {
10
+ this.max = max;
11
+ }
12
+ keep(make) {
13
+ const record = make(++this.seq);
14
+ this.held.push(record);
15
+ if (this.held.length > this.max)
16
+ this.lost += this.held.splice(0, this.held.length - this.max).length;
17
+ return record;
18
+ }
19
+ since(cursor) {
20
+ return { lines: this.held.filter((one) => one.seq > cursor), cursor: this.seq, dropped: this.lost };
21
+ }
22
+ }
23
+ //# sourceMappingURL=Ring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Ring.js","sourceRoot":"","sources":["../src/Ring.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,CAAC;AAExB,6FAA6F;AAC7F,MAAM,OAAO,IAAI;IAKc,GAAG;IAJb,IAAI,GAAQ,EAAE,CAAC;IACxB,GAAG,GAAG,CAAC,CAAC;IACV,IAAI,GAAG,CAAC,CAAC;IAEjB,YAA6B,GAAG,GAAG,IAAI;mBAAV,GAAG;IAAU,CAAC;IAEjC,IAAI,CAAC,IAAwB;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvB,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG;YAAE,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;QAEtG,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,MAAc;QAClB,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IACtG,CAAC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8D,KAAK,SAAS,EAA0B,MAAM,eAAe,CAAC;AAInI,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAE3D,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE1D,sDAAsD;AACtD,eAAO,MAAM,QAAQ,UAAU,CAAC;AAEhC,MAAM,WAAW,YAAY;IAC3B,oFAAoF;IACpF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,YAAY,CAAC;CACzC;AA+ED,2FAA2F;AAC3F,wBAAgB,KAAK,CAAC,OAAO,GAAE,YAAiB,GAAG,SAAS,CA+E3D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8D,KAAK,SAAS,EAA0B,MAAM,eAAe,CAAC;AAMnI,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAE3D,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE1D,sDAAsD;AACtD,eAAO,MAAM,QAAQ,UAAU,CAAC;AAEhC,MAAM,WAAW,YAAY;IAC3B,oFAAoF;IACpF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,YAAY,CAAC;CACzC;AA+ED,2FAA2F;AAC3F,wBAAgB,KAAK,CAAC,OAAO,GAAE,YAAiB,GAAG,SAAS,CA+E3D"}
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  import { CARRIES_LINE, declaredTopologyOf, frond, LogLine } from '@fougere/core';
2
2
  import KeepHandler from './KeepHandler.js';
3
3
  import { CallRing } from './CallRing.js';
4
- import { ErrorRing, LogRing, QueryRing } from './rings.js';
4
+ import { ErrorRing } from './ErrorRing.js';
5
+ import { LogRing } from './LogRing.js';
6
+ import { QueryRing } from './QueryRing.js';
5
7
  import { servePanel } from './panel.js';
6
8
  /** The rpc operation this extension answers under. */
7
9
  export const CALLS_OP = 'calls';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/panel.js CHANGED
@@ -41,7 +41,7 @@ export function servePanel(ring, options = {}) {
41
41
  request.on('close', () => readers.delete(response));
42
42
  return;
43
43
  }
44
- // One door per ring, each taking a cursor: a reader asks for what is above its own,
44
+ // One facade per ring, each taking a cursor: a reader asks for what is above its own,
45
45
  // which is the whole protocol — no subscription to hold, nothing to replay.
46
46
  for (const [name, read] of [['logs', options.logs], ['errors', options.errors], ['queries', options.queries]]) {
47
47
  if (path !== `/${name}.json`)
@@ -71,7 +71,7 @@ export function servePanel(ring, options = {}) {
71
71
  });
72
72
  return new Promise((ready, refuse) => {
73
73
  server.on('error', refuse);
74
- // Loopback only. This door has no validator — `serve()` refuses to start beyond loopback
74
+ // Loopback only. This facade has no validator — `serve()` refuses to start beyond loopback
75
75
  // without `verify`, and this one would not know how to refuse at all.
76
76
  server.listen(options.port ?? 0, '127.0.0.1', () => {
77
77
  const port = server.address().port;
package/dist/panel.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"panel.js","sourceRoot":"","sources":["../src/panel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"panel.js","sourceRoot":"","sources":["../src/panel.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fougere/calls",
3
- "version": "0.9.3-alpha.0",
3
+ "version": "0.11.0-alpha.0",
4
4
  "description": "Optional call log for Fougere: a bounded ring of every dispatch, served as an rpc operation. Read it with `fougere devtools`.",
5
5
  "keywords": [
6
6
  "fougere",
@@ -30,17 +30,17 @@
30
30
  "src"
31
31
  ],
32
32
  "peerDependencies": {
33
- "@fougere/adapter-sql": "^0.9.3-alpha.0",
34
- "@fougere/core": "^0.9.3-alpha.0"
33
+ "@fougere/core": "^0.11.0-alpha.0",
34
+ "@fougere/adapter-sql": "^0.11.0-alpha.0"
35
35
  },
36
36
  "devDependencies": {
37
37
  "vitest": "^4.1.0",
38
- "@fougere/adapter-sql": "0.9.3-alpha.0",
39
- "@fougere/core": "0.9.3-alpha.0",
40
- "@fougere/container": "0.9.3-alpha.0",
41
- "@fougere/schema": "0.9.3-alpha.0",
42
- "@fougere/transport-http": "0.9.3-alpha.0",
43
- "@fougere/compiler": "0.9.3-alpha.0"
38
+ "@fougere/adapter-sql": "0.11.0-alpha.0",
39
+ "@fougere/schema": "0.11.0-alpha.0",
40
+ "@fougere/container": "0.11.0-alpha.0",
41
+ "@fougere/core": "0.11.0-alpha.0",
42
+ "@fougere/transport-http": "0.11.0-alpha.0",
43
+ "@fougere/compiler": "0.11.0-alpha.0"
44
44
  },
45
45
  "publishConfig": {
46
46
  "access": "public"
@@ -0,0 +1,16 @@
1
+ /** One kind of refusal, and how often it happened. */
2
+ export interface ErrorGroup {
3
+ seq: number;
4
+ key: string;
5
+ code: string;
6
+ entity?: string;
7
+ operation?: string;
8
+ message: string;
9
+ count: number;
10
+ firstAt: number;
11
+ lastAt: number;
12
+ /** Which field was refused, for a VALIDATION_FAILED — the whole point of this source. */
13
+ fields: { path: string; message: string }[];
14
+ /** `dispatch` when a call carried it, `log` when it happened outside any call. */
15
+ from: 'dispatch' | 'log';
16
+ }
@@ -0,0 +1,53 @@
1
+ import { Ring } from './Ring.js';
2
+ import { dotted } from '@fougere/schema';
3
+ import { validationErrorsOf, type DispatchEvent, type LogRecord } from '@fougere/core';
4
+ import type { ErrorGroup } from './ErrorGroup.js';
5
+
6
+ /** What was refused, from TWO sources — and that is the point. */
7
+ export class ErrorRing extends Ring<ErrorGroup> {
8
+ private readonly byKey = new Map<string, ErrorGroup>();
9
+
10
+ /** A refusal that a call carried. `details` reaches here intact, unlike a span's code. */
11
+ fromDispatch(event: DispatchEvent): void {
12
+ const error = event.error as { code?: string; message?: string; details?: unknown } | undefined;
13
+ const { entity, operation } = event.call.address;
14
+
15
+ this.group({
16
+ code: typeof error?.code === 'string' ? error.code : 'INTERNAL_ERROR',
17
+ entity,
18
+ operation,
19
+ message: error?.message ?? String(event.error),
20
+ fields: (validationErrorsOf(error) ?? []).map((one) => ({ path: dotted(one.path), message: one.message })),
21
+ from: 'dispatch',
22
+ });
23
+ }
24
+
25
+ /** A line written at `error` level, which is how a failure outside any call speaks. */
26
+ fromLog(line: LogRecord): void {
27
+ if (line.level !== 'error') return;
28
+
29
+ this.group({ code: line.name, message: line.message, fields: [], from: 'log' });
30
+ }
31
+
32
+ private group(one: Omit<ErrorGroup, 'seq' | 'key' | 'count' | 'firstAt' | 'lastAt'>): void {
33
+ const key = [one.from, one.code, one.entity ?? '', one.operation ?? ''].join(' ');
34
+ const seen = this.byKey.get(key);
35
+ const at = Date.now();
36
+
37
+ // Grouped, because a refusal seen forty times is one line with a count — not forty
38
+ // lines that push everything else out of a bounded ring.
39
+ if (seen) {
40
+ seen.count += 1;
41
+ seen.lastAt = at;
42
+ seen.message = one.message;
43
+ if (one.fields.length > 0) seen.fields = one.fields;
44
+ // Re-numbered so a reader that already saw this group is handed the higher count.
45
+ // Without it a refusal seen forty times reports one, forever: the group is mutated
46
+ // in place, and a cursor asks only for what is above it.
47
+ seen.seq = ++this.seq;
48
+ return;
49
+ }
50
+
51
+ this.byKey.set(key, this.keep((seq) => ({ ...one, key, seq, count: 1, firstAt: at, lastAt: at })));
52
+ }
53
+ }
@@ -1,11 +1,12 @@
1
1
  import type { Fact, LogLine } from '@fougere/core';
2
- import { LogRing, ErrorRing } from './rings.js';
2
+ import { ErrorRing } from './ErrorRing.js';
3
+ import { LogRing } from './LogRing.js';
3
4
 
4
5
  /**
5
6
  * Every line this process logged, kept for the panel.
6
7
  *
7
8
  * A handler and not an `onLog` sink: accepting the fact IS the subscription, so the two
8
- * rings are filled by the same door every other reader goes through — with a validator,
9
+ * rings are filled by the same facade every other reader goes through — with a validator,
9
10
  * and with whatever middleware the app declared.
10
11
  *
11
12
  * The rings come from the container: the extension's `up` put them there, and this
package/src/LogLine.ts ADDED
@@ -0,0 +1,12 @@
1
+ import { type LogRecord } from '@fougere/core';
2
+
3
+ /** One line this process wrote. `args` is the developer's own choice of what to record. */
4
+ export interface LogLine {
5
+ seq: number;
6
+ level: LogRecord['level'];
7
+ name: string;
8
+ message: string;
9
+ /** Rendered here, not held: a live object would let the panel show what it later became. */
10
+ args: string[];
11
+ at: number;
12
+ }
package/src/LogRing.ts ADDED
@@ -0,0 +1,28 @@
1
+ import { Ring } from './Ring.js';
2
+ import { type LogRecord } from '@fougere/core';
3
+ import type { LogLine } from './LogLine.js';
4
+
5
+ /** What this process logged. */
6
+ export class LogRing extends Ring<LogLine> {
7
+ record(line: LogRecord): void {
8
+ this.keep((seq) => ({
9
+ seq,
10
+ level: line.level,
11
+ name: line.name,
12
+ message: line.message,
13
+ args: line.args.map(render),
14
+ at: line.at,
15
+ }));
16
+ }
17
+ }
18
+
19
+ /** An argument as one line. A live object would change under the reader; a string cannot. */
20
+ function render(value: unknown): string {
21
+ if (typeof value === 'string') return value;
22
+ if (value instanceof Error) return `${value.name}: ${value.message}`;
23
+ try {
24
+ return JSON.stringify(value) ?? String(value);
25
+ } catch {
26
+ return String(value);
27
+ }
28
+ }
@@ -0,0 +1,10 @@
1
+ /** One statement, as the panel shows it — never a parameter's value. */
2
+ export interface QueryLine {
3
+ seq: number;
4
+ storage: string;
5
+ sql: string;
6
+ parameters: number;
7
+ ms: number;
8
+ failed: boolean;
9
+ at: number;
10
+ }
@@ -0,0 +1,8 @@
1
+ import { Ring } from './Ring.js';
2
+ import type { QueryLine } from './QueryLine.js';
3
+
4
+ export class QueryRing extends Ring<QueryLine> {
5
+ record(event: Omit<QueryLine, 'seq'>): void {
6
+ this.keep((seq) => ({ ...event, seq }));
7
+ }
8
+ }
package/src/Ring.ts ADDED
@@ -0,0 +1,23 @@
1
+ /** How many entries a ring keeps before the oldest falls off. */
2
+ export const KEPT = 300;
3
+
4
+ /** A bounded list that counts what it drops, so a busy moment never reads as a quiet one. */
5
+ export class Ring<T extends { seq: number }> {
6
+ protected readonly held: T[] = [];
7
+ protected seq = 0;
8
+ private lost = 0;
9
+
10
+ constructor(private readonly max = KEPT) {}
11
+
12
+ protected keep(make: (seq: number) => T): T {
13
+ const record = make(++this.seq);
14
+ this.held.push(record);
15
+ if (this.held.length > this.max) this.lost += this.held.splice(0, this.held.length - this.max).length;
16
+
17
+ return record;
18
+ }
19
+
20
+ since(cursor: number): { lines: T[]; cursor: number; dropped: number } {
21
+ return { lines: this.held.filter((one) => one.seq > cursor), cursor: this.seq, dropped: this.lost };
22
+ }
23
+ }
package/src/index.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import { CARRIES_LINE, declaredTopologyOf, frond, LogLine, type App, type Extension, type InvocationContext } from '@fougere/core';
2
2
  import KeepHandler from './KeepHandler.js';
3
3
  import { CallRing } from './CallRing.js';
4
- import { ErrorRing, LogRing, QueryRing } from './rings.js';
4
+ import { ErrorRing } from './ErrorRing.js';
5
+ import { LogRing } from './LogRing.js';
6
+ import { QueryRing } from './QueryRing.js';
5
7
  import { servePanel, type PanelOptions } from './panel.js';
6
8
 
7
9
  export type { CallPage, CallRecord } from '@fougere/core';
package/src/panel.ts CHANGED
@@ -63,7 +63,7 @@ export function servePanel(ring: CallRing, options: PanelOptions = {}): Promise<
63
63
  return;
64
64
  }
65
65
 
66
- // One door per ring, each taking a cursor: a reader asks for what is above its own,
66
+ // One facade per ring, each taking a cursor: a reader asks for what is above its own,
67
67
  // which is the whole protocol — no subscription to hold, nothing to replay.
68
68
  for (const [name, read] of [['logs', options.logs], ['errors', options.errors], ['queries', options.queries]] as const) {
69
69
  if (path !== `/${name}.json`) continue;
@@ -97,7 +97,7 @@ export function servePanel(ring: CallRing, options: PanelOptions = {}): Promise<
97
97
 
98
98
  return new Promise((ready, refuse) => {
99
99
  server.on('error', refuse);
100
- // Loopback only. This door has no validator — `serve()` refuses to start beyond loopback
100
+ // Loopback only. This facade has no validator — `serve()` refuses to start beyond loopback
101
101
  // without `verify`, and this one would not know how to refuse at all.
102
102
  server.listen(options.port ?? 0, '127.0.0.1', () => {
103
103
  const port = (server.address() as { port: number }).port;
package/dist/rings.d.ts DELETED
@@ -1,74 +0,0 @@
1
- import { type DispatchEvent, type LogRecord } from '@fougere/core';
2
- /** One line this process wrote. `args` is the developer's own choice of what to record. */
3
- export interface LogLine {
4
- seq: number;
5
- level: LogRecord['level'];
6
- name: string;
7
- message: string;
8
- /** Rendered here, not held: a live object would let the panel show what it later became. */
9
- args: string[];
10
- at: number;
11
- }
12
- /** One statement, as the panel shows it — never a parameter's value. */
13
- export interface QueryLine {
14
- seq: number;
15
- storage: string;
16
- sql: string;
17
- parameters: number;
18
- ms: number;
19
- failed: boolean;
20
- at: number;
21
- }
22
- /** One kind of refusal, and how often it happened. */
23
- export interface ErrorGroup {
24
- seq: number;
25
- key: string;
26
- code: string;
27
- entity?: string;
28
- operation?: string;
29
- message: string;
30
- count: number;
31
- firstAt: number;
32
- lastAt: number;
33
- /** Which field was refused, for a VALIDATION_FAILED — the whole point of this source. */
34
- fields: {
35
- path: string;
36
- message: string;
37
- }[];
38
- /** `dispatch` when a call carried it, `log` when it happened outside any call. */
39
- from: 'dispatch' | 'log';
40
- }
41
- /** A bounded list that counts what it drops, so a busy moment never reads as a quiet one. */
42
- declare class Ring<T extends {
43
- seq: number;
44
- }> {
45
- private readonly max;
46
- protected readonly held: T[];
47
- protected seq: number;
48
- private lost;
49
- constructor(max?: number);
50
- protected keep(make: (seq: number) => T): T;
51
- since(cursor: number): {
52
- lines: T[];
53
- cursor: number;
54
- dropped: number;
55
- };
56
- }
57
- /** What this process logged. */
58
- export declare class LogRing extends Ring<LogLine> {
59
- record(line: LogRecord): void;
60
- }
61
- export declare class QueryRing extends Ring<QueryLine> {
62
- record(event: Omit<QueryLine, 'seq'>): void;
63
- }
64
- /** What was refused, from TWO sources — and that is the point. */
65
- export declare class ErrorRing extends Ring<ErrorGroup> {
66
- private readonly byKey;
67
- /** A refusal that a call carried. `details` reaches here intact, unlike a span's code. */
68
- fromDispatch(event: DispatchEvent): void;
69
- /** A line written at `error` level, which is how a failure outside any call speaks. */
70
- fromLog(line: LogRecord): void;
71
- private group;
72
- }
73
- export {};
74
- //# sourceMappingURL=rings.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rings.d.ts","sourceRoot":"","sources":["../src/rings.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAKvF,2FAA2F;AAC3F,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,4FAA4F;IAC5F,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,wEAAwE;AACxE,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,OAAO,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,sDAAsD;AACtD,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,yFAAyF;IACzF,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5C,kFAAkF;IAClF,IAAI,EAAE,UAAU,GAAG,KAAK,CAAC;CAC1B;AAED,6FAA6F;AAC7F,cAAM,IAAI,CAAC,CAAC,SAAS;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE;IAKtB,OAAO,CAAC,QAAQ,CAAC,GAAG;IAJhC,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,CAAM;IAClC,SAAS,CAAC,GAAG,SAAK;IAClB,OAAO,CAAC,IAAI,CAAK;IAEjB,YAA6B,GAAG,SAAO,EAAI;IAE3C,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,CAM1C;IAED,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAErE;CACF;AAED,gCAAgC;AAChC,qBAAa,OAAQ,SAAQ,IAAI,CAAC,OAAO,CAAC;IACxC,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAS5B;CACF;AAED,qBAAa,SAAU,SAAQ,IAAI,CAAC,SAAS,CAAC;IAC5C,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,IAAI,CAE1C;CACF;AAED,kEAAkE;AAClE,qBAAa,SAAU,SAAQ,IAAI,CAAC,UAAU,CAAC;IAC7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;IAEvD,0FAA0F;IAC1F,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAYvC;IAED,uFAAuF;IACvF,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAI7B;IAED,OAAO,CAAC,KAAK;CAqBd"}
package/dist/rings.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"rings.js","sourceRoot":"","sources":["../src/rings.ts"],"names":[],"mappings":"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"}
package/src/rings.ts DELETED
@@ -1,145 +0,0 @@
1
- import { dotted } from '@fougere/schema';
2
- import { validationErrorsOf, type DispatchEvent, type LogRecord } from '@fougere/core';
3
-
4
- /** How many each ring keeps. Bounded by a NUMBER, never by a duration. */
5
- const KEPT = 300;
6
-
7
- /** One line this process wrote. `args` is the developer's own choice of what to record. */
8
- export interface LogLine {
9
- seq: number;
10
- level: LogRecord['level'];
11
- name: string;
12
- message: string;
13
- /** Rendered here, not held: a live object would let the panel show what it later became. */
14
- args: string[];
15
- at: number;
16
- }
17
-
18
- /** One statement, as the panel shows it — never a parameter's value. */
19
- export interface QueryLine {
20
- seq: number;
21
- storage: string;
22
- sql: string;
23
- parameters: number;
24
- ms: number;
25
- failed: boolean;
26
- at: number;
27
- }
28
-
29
- /** One kind of refusal, and how often it happened. */
30
- export interface ErrorGroup {
31
- seq: number;
32
- key: string;
33
- code: string;
34
- entity?: string;
35
- operation?: string;
36
- message: string;
37
- count: number;
38
- firstAt: number;
39
- lastAt: number;
40
- /** Which field was refused, for a VALIDATION_FAILED — the whole point of this source. */
41
- fields: { path: string; message: string }[];
42
- /** `dispatch` when a call carried it, `log` when it happened outside any call. */
43
- from: 'dispatch' | 'log';
44
- }
45
-
46
- /** A bounded list that counts what it drops, so a busy moment never reads as a quiet one. */
47
- class Ring<T extends { seq: number }> {
48
- protected readonly held: T[] = [];
49
- protected seq = 0;
50
- private lost = 0;
51
-
52
- constructor(private readonly max = KEPT) {}
53
-
54
- protected keep(make: (seq: number) => T): T {
55
- const record = make(++this.seq);
56
- this.held.push(record);
57
- if (this.held.length > this.max) this.lost += this.held.splice(0, this.held.length - this.max).length;
58
-
59
- return record;
60
- }
61
-
62
- since(cursor: number): { lines: T[]; cursor: number; dropped: number } {
63
- return { lines: this.held.filter((one) => one.seq > cursor), cursor: this.seq, dropped: this.lost };
64
- }
65
- }
66
-
67
- /** What this process logged. */
68
- export class LogRing extends Ring<LogLine> {
69
- record(line: LogRecord): void {
70
- this.keep((seq) => ({
71
- seq,
72
- level: line.level,
73
- name: line.name,
74
- message: line.message,
75
- args: line.args.map(render),
76
- at: line.at,
77
- }));
78
- }
79
- }
80
-
81
- export class QueryRing extends Ring<QueryLine> {
82
- record(event: Omit<QueryLine, 'seq'>): void {
83
- this.keep((seq) => ({ ...event, seq }));
84
- }
85
- }
86
-
87
- /** What was refused, from TWO sources — and that is the point. */
88
- export class ErrorRing extends Ring<ErrorGroup> {
89
- private readonly byKey = new Map<string, ErrorGroup>();
90
-
91
- /** A refusal that a call carried. `details` reaches here intact, unlike a span's code. */
92
- fromDispatch(event: DispatchEvent): void {
93
- const error = event.error as { code?: string; message?: string; details?: unknown } | undefined;
94
- const { entity, operation } = event.call.address;
95
-
96
- this.group({
97
- code: typeof error?.code === 'string' ? error.code : 'INTERNAL_ERROR',
98
- entity,
99
- operation,
100
- message: error?.message ?? String(event.error),
101
- fields: (validationErrorsOf(error) ?? []).map((one) => ({ path: dotted(one.path), message: one.message })),
102
- from: 'dispatch',
103
- });
104
- }
105
-
106
- /** A line written at `error` level, which is how a failure outside any call speaks. */
107
- fromLog(line: LogRecord): void {
108
- if (line.level !== 'error') return;
109
-
110
- this.group({ code: line.name, message: line.message, fields: [], from: 'log' });
111
- }
112
-
113
- private group(one: Omit<ErrorGroup, 'seq' | 'key' | 'count' | 'firstAt' | 'lastAt'>): void {
114
- const key = [one.from, one.code, one.entity ?? '', one.operation ?? ''].join(' ');
115
- const seen = this.byKey.get(key);
116
- const at = Date.now();
117
-
118
- // Grouped, because a refusal seen forty times is one line with a count — not forty
119
- // lines that push everything else out of a bounded ring.
120
- if (seen) {
121
- seen.count += 1;
122
- seen.lastAt = at;
123
- seen.message = one.message;
124
- if (one.fields.length > 0) seen.fields = one.fields;
125
- // Re-numbered so a reader that already saw this group is handed the higher count.
126
- // Without it a refusal seen forty times reports one, forever: the group is mutated
127
- // in place, and a cursor asks only for what is above it.
128
- seen.seq = ++this.seq;
129
- return;
130
- }
131
-
132
- this.byKey.set(key, this.keep((seq) => ({ ...one, key, seq, count: 1, firstAt: at, lastAt: at })));
133
- }
134
- }
135
-
136
- /** An argument as one line. A live object would change under the reader; a string cannot. */
137
- function render(value: unknown): string {
138
- if (typeof value === 'string') return value;
139
- if (value instanceof Error) return `${value.name}: ${value.message}`;
140
- try {
141
- return JSON.stringify(value) ?? String(value);
142
- } catch {
143
- return String(value);
144
- }
145
- }