@rudderjs/pulse 5.0.0 → 6.1.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 (86) hide show
  1. package/README.md +16 -16
  2. package/boost/guidelines.md +22 -11
  3. package/dist/api/routes.d.ts +11 -4
  4. package/dist/api/routes.d.ts.map +1 -1
  5. package/dist/api/routes.js +117 -135
  6. package/dist/api/routes.js.map +1 -1
  7. package/dist/index.d.ts +10 -9
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +35 -31
  10. package/dist/index.js.map +1 -1
  11. package/dist/recorders/cache.d.ts +11 -0
  12. package/dist/recorders/cache.d.ts.map +1 -0
  13. package/dist/{aggregators → recorders}/cache.js +2 -2
  14. package/dist/recorders/cache.js.map +1 -0
  15. package/dist/recorders/exception.d.ts +11 -0
  16. package/dist/recorders/exception.d.ts.map +1 -0
  17. package/dist/{aggregators → recorders}/exception.js +2 -2
  18. package/dist/recorders/exception.js.map +1 -0
  19. package/dist/{aggregators → recorders}/query.d.ts +3 -3
  20. package/dist/recorders/query.d.ts.map +1 -0
  21. package/dist/{aggregators → recorders}/query.js +2 -2
  22. package/dist/recorders/query.js.map +1 -0
  23. package/dist/recorders/queue.d.ts +19 -0
  24. package/dist/recorders/queue.d.ts.map +1 -0
  25. package/dist/recorders/queue.js +52 -0
  26. package/dist/recorders/queue.js.map +1 -0
  27. package/dist/{aggregators → recorders}/request.d.ts +3 -3
  28. package/dist/recorders/request.d.ts.map +1 -0
  29. package/dist/{aggregators → recorders}/request.js +2 -2
  30. package/dist/recorders/request.js.map +1 -0
  31. package/dist/{aggregators → recorders}/server.d.ts +3 -3
  32. package/dist/recorders/server.d.ts.map +1 -0
  33. package/dist/{aggregators → recorders}/server.js +2 -2
  34. package/dist/recorders/server.js.map +1 -0
  35. package/dist/{aggregators → recorders}/user.d.ts +3 -3
  36. package/dist/recorders/user.d.ts.map +1 -0
  37. package/dist/{aggregators → recorders}/user.js +2 -2
  38. package/dist/recorders/user.js.map +1 -0
  39. package/dist/routes.d.ts +23 -0
  40. package/dist/routes.d.ts.map +1 -0
  41. package/dist/routes.js +44 -0
  42. package/dist/routes.js.map +1 -0
  43. package/dist/types.d.ts +1 -1
  44. package/dist/types.d.ts.map +1 -1
  45. package/dist/types.js.map +1 -1
  46. package/dist/views/vanilla/Dashboard.d.ts +11 -0
  47. package/dist/views/vanilla/Dashboard.d.ts.map +1 -0
  48. package/dist/{ui/dashboard.js → views/vanilla/Dashboard.js} +11 -7
  49. package/dist/views/vanilla/Dashboard.js.map +1 -0
  50. package/dist/views/vanilla/Layout.d.ts +13 -0
  51. package/dist/views/vanilla/Layout.d.ts.map +1 -0
  52. package/dist/{ui/layout.js → views/vanilla/Layout.js} +8 -15
  53. package/dist/views/vanilla/Layout.js.map +1 -0
  54. package/dist/views/vanilla/_html.d.ts +28 -0
  55. package/dist/views/vanilla/_html.d.ts.map +1 -0
  56. package/dist/views/vanilla/_html.js +56 -0
  57. package/dist/views/vanilla/_html.js.map +1 -0
  58. package/dist/views/vanilla/index.d.ts +4 -0
  59. package/dist/views/vanilla/index.d.ts.map +1 -0
  60. package/dist/views/vanilla/index.js +4 -0
  61. package/dist/views/vanilla/index.js.map +1 -0
  62. package/package.json +9 -8
  63. package/dist/aggregators/cache.d.ts +0 -11
  64. package/dist/aggregators/cache.d.ts.map +0 -1
  65. package/dist/aggregators/cache.js.map +0 -1
  66. package/dist/aggregators/exception.d.ts +0 -11
  67. package/dist/aggregators/exception.d.ts.map +0 -1
  68. package/dist/aggregators/exception.js.map +0 -1
  69. package/dist/aggregators/query.d.ts.map +0 -1
  70. package/dist/aggregators/query.js.map +0 -1
  71. package/dist/aggregators/queue.d.ts +0 -12
  72. package/dist/aggregators/queue.d.ts.map +0 -1
  73. package/dist/aggregators/queue.js +0 -43
  74. package/dist/aggregators/queue.js.map +0 -1
  75. package/dist/aggregators/request.d.ts.map +0 -1
  76. package/dist/aggregators/request.js.map +0 -1
  77. package/dist/aggregators/server.d.ts.map +0 -1
  78. package/dist/aggregators/server.js.map +0 -1
  79. package/dist/aggregators/user.d.ts.map +0 -1
  80. package/dist/aggregators/user.js.map +0 -1
  81. package/dist/ui/dashboard.d.ts +0 -5
  82. package/dist/ui/dashboard.d.ts.map +0 -1
  83. package/dist/ui/dashboard.js.map +0 -1
  84. package/dist/ui/layout.d.ts +0 -6
  85. package/dist/ui/layout.d.ts.map +0 -1
  86. package/dist/ui/layout.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/recorders/cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAEzD;;GAEG;AACH,qBAAa,aAAc,YAAW,QAAQ;IAGhC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAFpC,QAAQ,CAAC,IAAI,oBAAmB;gBAEH,OAAO,EAAE,YAAY;IAE5C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAsBhC"}
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Tracks cache hit/miss ratio by wrapping the CacheRegistry adapter.
3
3
  */
4
- export class CacheAggregator {
4
+ export class CacheRecorder {
5
5
  storage;
6
- name = 'Cache Aggregator';
6
+ name = 'Cache Recorder';
7
7
  constructor(storage) {
8
8
  this.storage = storage;
9
9
  }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/recorders/cache.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,OAAO,aAAa;IAGK;IAFpB,IAAI,GAAG,gBAAgB,CAAA;IAEhC,YAA6B,OAAqB;QAArB,YAAO,GAAP,OAAO,CAAc;IAAG,CAAC;IAEtD,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC;YACH,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAA;YACzD,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,EAAE,CAAA;YACnC,IAAI,CAAC,OAAO;gBAAE,OAAM;YAEpB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;YAC5B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAExC;YAAC,OAA8C,CAAC,KAAK,CAAC,GAAG,KAAK,EAAe,GAAW,EAAqB,EAAE;gBAC9G,MAAM,KAAK,GAAG,MAAO,OAA8C,CAAC,GAAG,CAAC,CAAA;gBACxE,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;oBACnB,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAA;gBACjC,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAA;gBACnC,CAAC;gBACD,OAAO,KAAK,CAAA;YACd,CAAC,CAAA;QACH,CAAC;QAAC,MAAM,CAAC;YACP,uCAAuC;QACzC,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ import type { Recorder, PulseStorage } from '../types.js';
2
+ /**
3
+ * Tracks exception count over time by hooking into the exception reporter.
4
+ */
5
+ export declare class ExceptionRecorder implements Recorder {
6
+ private readonly storage;
7
+ readonly name = "Exception Recorder";
8
+ constructor(storage: PulseStorage);
9
+ register(): Promise<void>;
10
+ }
11
+ //# sourceMappingURL=exception.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exception.d.ts","sourceRoot":"","sources":["../../src/recorders/exception.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAEzD;;GAEG;AACH,qBAAa,iBAAkB,YAAW,QAAQ;IAGpC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAFpC,QAAQ,CAAC,IAAI,wBAAuB;gBAEP,OAAO,EAAE,YAAY;IAE5C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAuBhC"}
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Tracks exception count over time by hooking into the exception reporter.
3
3
  */
4
- export class ExceptionAggregator {
4
+ export class ExceptionRecorder {
5
5
  storage;
6
- name = 'Exception Aggregator';
6
+ name = 'Exception Recorder';
7
7
  constructor(storage) {
8
8
  this.storage = storage;
9
9
  }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exception.js","sourceRoot":"","sources":["../../src/recorders/exception.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,OAAO,iBAAiB;IAGC;IAFpB,IAAI,GAAG,oBAAoB,CAAA;IAEpC,YAA6B,OAAqB;QAArB,YAAO,GAAP,OAAO,CAAc;IAAG,CAAC;IAEtD,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC;YACH,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAGrE,CAAA;YAED,MAAM,OAAO,GAAU,IAAI,CAAC,OAAO,CAAA;YACnC,MAAM,cAAc,GAAG,MAAM,CAAA;YAE7B,oBAAoB,CAAC,CAAC,GAAY,EAAE,EAAE;gBACpC,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAA;gBAC/B,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAA;gBACpC,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE;oBAC9B,KAAK,EAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;oBACnD,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;iBAC7C,CAAC,CAAA;gBACF,cAAc,CAAC,GAAG,CAAC,CAAA;YACrB,CAAC,CAAC,CAAA;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,kBAAkB;QACpB,CAAC;IACH,CAAC;CACF"}
@@ -1,11 +1,11 @@
1
- import type { Aggregator, PulseStorage, PulseConfig } from '../types.js';
1
+ import type { Recorder, PulseStorage, PulseConfig } from '../types.js';
2
2
  /**
3
3
  * Tracks slow database queries by hooking into the ORM adapter.
4
4
  */
5
- export declare class QueryAggregator implements Aggregator {
5
+ export declare class QueryRecorder implements Recorder {
6
6
  private readonly storage;
7
7
  private readonly config;
8
- readonly name = "Query Aggregator";
8
+ readonly name = "Query Recorder";
9
9
  constructor(storage: PulseStorage, config: PulseConfig);
10
10
  register(): Promise<void>;
11
11
  }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/recorders/query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEtE;;GAEG;AACH,qBAAa,aAAc,YAAW,QAAQ;IAI1C,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJzB,QAAQ,CAAC,IAAI,oBAAmB;gBAGb,OAAO,EAAE,YAAY,EACrB,MAAM,EAAG,WAAW;IAGjC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CA4BhC"}
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * Tracks slow database queries by hooking into the ORM adapter.
3
3
  */
4
- export class QueryAggregator {
4
+ export class QueryRecorder {
5
5
  storage;
6
6
  config;
7
- name = 'Query Aggregator';
7
+ name = 'Query Recorder';
8
8
  constructor(storage, config) {
9
9
  this.storage = storage;
10
10
  this.config = config;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/recorders/query.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,OAAO,aAAa;IAIL;IACA;IAJV,IAAI,GAAG,gBAAgB,CAAA;IAEhC,YACmB,OAAqB,EACrB,MAAoB;QADpB,YAAO,GAAP,OAAO,CAAc;QACrB,WAAM,GAAN,MAAM,CAAc;IACpC,CAAC;IAEJ,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;YACzC,MAAM,QAAQ,GAAG,GAAG,CAAC,aAEpB,CAAA;YACD,IAAI,CAAC,QAAQ,CAAC,UAAU;gBAAE,OAAM;YAEhC,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU,EAAE,CAAA;YACrC,IAAI,CAAC,OAAO,EAAE,OAAO;gBAAE,OAAM;YAE7B,MAAM,OAAO,GAAK,IAAI,CAAC,OAAO,CAAA;YAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,kBAAkB,IAAI,GAAG,CAAA;YAEvD,OAAO,CAAC,OAAO,CAAC,CAAC,IAAe,EAAE,EAAE;gBAClC,IAAI,IAAI,CAAC,QAAQ,GAAG,SAAS,EAAE,CAAC;oBAC9B,OAAO,CAAC,UAAU,CAAC,YAAY,EAAE;wBAC/B,GAAG,EAAO,IAAI,CAAC,GAAG;wBAClB,QAAQ,EAAE,IAAI,CAAC,QAAQ;wBACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;wBACvB,KAAK,EAAK,IAAI,CAAC,KAAK;qBACrB,CAAC,CAAA;gBACJ,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,qCAAqC;QACvC,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,19 @@
1
+ import type { Recorder, PulseStorage } from '../types.js';
2
+ /**
3
+ * Tracks queue throughput, wait time, and failed jobs by subscribing to
4
+ * `@rudderjs/queue/observers`. Replaces the legacy `dispatch()`
5
+ * monkey-patch which only fired in the dispatching process — under
6
+ * BullMQ, worker-side completion and failure events were never recorded
7
+ * and `queue_wait_time` was actually the enqueue duration, not the
8
+ * queue-to-active wait.
9
+ */
10
+ export declare class QueueRecorder implements Recorder {
11
+ private readonly storage;
12
+ readonly name = "Queue Recorder";
13
+ private unsubscribe;
14
+ constructor(storage: PulseStorage);
15
+ register(): void;
16
+ /** @internal — used in tests + provider shutdown. */
17
+ unregister(): void;
18
+ }
19
+ //# sourceMappingURL=queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../src/recorders/queue.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAEzD;;;;;;;GAOG;AACH,qBAAa,aAAc,YAAW,QAAQ;IAIhC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC,QAAQ,CAAC,IAAI,oBAAmB;IAChC,OAAO,CAAC,WAAW,CAA4B;gBAElB,OAAO,EAAE,YAAY;IAElD,QAAQ,IAAI,IAAI;IA6BhB,qDAAqD;IACrD,UAAU,IAAI,IAAI;CAInB"}
@@ -0,0 +1,52 @@
1
+ import { queueObservers } from '@rudderjs/queue/observers';
2
+ /**
3
+ * Tracks queue throughput, wait time, and failed jobs by subscribing to
4
+ * `@rudderjs/queue/observers`. Replaces the legacy `dispatch()`
5
+ * monkey-patch which only fired in the dispatching process — under
6
+ * BullMQ, worker-side completion and failure events were never recorded
7
+ * and `queue_wait_time` was actually the enqueue duration, not the
8
+ * queue-to-active wait.
9
+ */
10
+ export class QueueRecorder {
11
+ storage;
12
+ name = 'Queue Recorder';
13
+ unsubscribe = null;
14
+ constructor(storage) {
15
+ this.storage = storage;
16
+ }
17
+ register() {
18
+ this.unsubscribe = queueObservers.subscribe((event) => {
19
+ try {
20
+ switch (event.kind) {
21
+ case 'job.active': {
22
+ const wait = event.startedAt.getTime() - event.dispatchedAt.getTime();
23
+ void this.storage.record('queue_wait_time', wait);
24
+ break;
25
+ }
26
+ case 'job.completed':
27
+ void this.storage.record('queue_throughput', 1);
28
+ break;
29
+ case 'job.failed':
30
+ void this.storage.record('queue_throughput', 1);
31
+ void this.storage.storeEntry('failed_job', {
32
+ class: event.name,
33
+ queue: event.queue,
34
+ jobId: event.jobId,
35
+ attempts: event.attempts,
36
+ exception: event.error,
37
+ });
38
+ break;
39
+ }
40
+ }
41
+ catch {
42
+ // observer errors must not break the queue layer
43
+ }
44
+ });
45
+ }
46
+ /** @internal — used in tests + provider shutdown. */
47
+ unregister() {
48
+ this.unsubscribe?.();
49
+ this.unsubscribe = null;
50
+ }
51
+ }
52
+ //# sourceMappingURL=queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/recorders/queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAG1D;;;;;;;GAOG;AACH,MAAM,OAAO,aAAa;IAIK;IAHpB,IAAI,GAAG,gBAAgB,CAAA;IACxB,WAAW,GAAwB,IAAI,CAAA;IAE/C,YAA6B,OAAqB;QAArB,YAAO,GAAP,OAAO,CAAc;IAAG,CAAC;IAEtD,QAAQ;QACN,IAAI,CAAC,WAAW,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;YACpD,IAAI,CAAC;gBACH,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;oBACnB,KAAK,YAAY,CAAC,CAAC,CAAC;wBAClB,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,CAAA;wBACrE,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAA;wBACjD,MAAK;oBACP,CAAC;oBACD,KAAK,eAAe;wBAClB,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAA;wBAC/C,MAAK;oBACP,KAAK,YAAY;wBACf,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAA;wBAC/C,KAAK,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,YAAY,EAAE;4BACzC,KAAK,EAAM,KAAK,CAAC,IAAI;4BACrB,KAAK,EAAM,KAAK,CAAC,KAAK;4BACtB,KAAK,EAAM,KAAK,CAAC,KAAK;4BACtB,QAAQ,EAAG,KAAK,CAAC,QAAQ;4BACzB,SAAS,EAAE,KAAK,CAAC,KAAK;yBACvB,CAAC,CAAA;wBACF,MAAK;gBACT,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,iDAAiD;YACnD,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,qDAAqD;IACrD,UAAU;QACR,IAAI,CAAC,WAAW,EAAE,EAAE,CAAA;QACpB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAA;IACzB,CAAC;CACF"}
@@ -1,13 +1,13 @@
1
1
  import type { AppRequest, AppResponse } from '@rudderjs/contracts';
2
- import type { Aggregator, PulseStorage, PulseConfig } from '../types.js';
2
+ import type { Recorder, PulseStorage, PulseConfig } from '../types.js';
3
3
  /**
4
4
  * Tracks request throughput, duration (p50/p95/p99), and slow requests.
5
5
  * Installs as global middleware.
6
6
  */
7
- export declare class RequestAggregator implements Aggregator {
7
+ export declare class RequestRecorder implements Recorder {
8
8
  private readonly storage;
9
9
  private readonly config;
10
- readonly name = "Request Aggregator";
10
+ readonly name = "Request Recorder";
11
11
  constructor(storage: PulseStorage, config: PulseConfig);
12
12
  register(): void;
13
13
  middleware(): (req: AppRequest, res: AppResponse, next: () => Promise<void>) => Promise<void>;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/recorders/request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAClE,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAGtE;;;GAGG;AACH,qBAAa,eAAgB,YAAW,QAAQ;IAI5C,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJzB,QAAQ,CAAC,IAAI,sBAAqB;gBAGf,OAAO,EAAE,YAAY,EACrB,MAAM,EAAG,WAAW;IAGvC,QAAQ,IAAI,IAAI;IAIhB,UAAU,KAKM,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,MAAM,OAAO,CAAC,IAAI,CAAC;CAyB7E"}
@@ -3,10 +3,10 @@ import { isAsset } from '../utils.js';
3
3
  * Tracks request throughput, duration (p50/p95/p99), and slow requests.
4
4
  * Installs as global middleware.
5
5
  */
6
- export class RequestAggregator {
6
+ export class RequestRecorder {
7
7
  storage;
8
8
  config;
9
- name = 'Request Aggregator';
9
+ name = 'Request Recorder';
10
10
  constructor(storage, config) {
11
11
  this.storage = storage;
12
12
  this.config = config;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/recorders/request.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAErC;;;GAGG;AACH,MAAM,OAAO,eAAe;IAIP;IACA;IAJV,IAAI,GAAG,kBAAkB,CAAA;IAElC,YACmB,OAAqB,EACrB,MAAoB;QADpB,YAAO,GAAP,OAAO,CAAc;QACrB,WAAM,GAAN,MAAM,CAAc;IACpC,CAAC;IAEJ,QAAQ;QACN,mDAAmD;IACrD,CAAC;IAED,UAAU;QACR,MAAM,OAAO,GAAK,IAAI,CAAC,OAAO,CAAA;QAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,oBAAoB,IAAI,IAAI,CAAA;QAC1D,MAAM,MAAM,GAAM,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,OAAO,CAAA;QAE7C,OAAO,KAAK,EAAE,GAAe,EAAE,GAAgB,EAAE,IAAyB,EAAE,EAAE;YAC5E,0BAA0B;YAC1B,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,MAAM,EAAE,CAAC;gBAAE,OAAO,IAAI,EAAE,CAAA;YACpD,uDAAuD;YACvD,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,OAAO,IAAI,EAAE,CAAA;YAEpC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;YACxB,MAAM,IAAI,EAAE,CAAA;YACZ,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAA;YAEnC,oBAAoB;YACpB,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,CAAA;YAClC,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAA;YAE5C,qBAAqB;YACrB,IAAI,QAAQ,GAAG,SAAS,EAAE,CAAC;gBACzB,OAAO,CAAC,UAAU,CAAC,cAAc,EAAE;oBACjC,MAAM,EAAI,GAAG,CAAC,MAAM;oBACpB,GAAG,EAAO,GAAG,CAAC,GAAG;oBACjB,IAAI,EAAM,GAAG,CAAC,IAAI;oBAClB,QAAQ;iBACT,CAAC,CAAA;YACJ,CAAC;QACH,CAAC,CAAA;IACH,CAAC;CACF"}
@@ -1,11 +1,11 @@
1
- import type { Aggregator, PulseStorage } from '../types.js';
1
+ import type { Recorder, PulseStorage } from '../types.js';
2
2
  /**
3
3
  * Periodically collects server resource metrics — CPU usage and memory.
4
4
  */
5
- export declare class ServerAggregator implements Aggregator {
5
+ export declare class ServerRecorder implements Recorder {
6
6
  private readonly storage;
7
7
  private readonly intervalMs;
8
- readonly name = "Server Aggregator";
8
+ readonly name = "Server Recorder";
9
9
  constructor(storage: PulseStorage, intervalMs?: number);
10
10
  register(): void;
11
11
  private collect;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/recorders/server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAEzD;;GAEG;AACH,qBAAa,cAAe,YAAW,QAAQ;IAI3C,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAJ7B,QAAQ,CAAC,IAAI,qBAAoB;gBAGd,OAAO,EAAE,YAAY,EACrB,UAAU,GAAE,MAAe;IAG9C,QAAQ,IAAI,IAAI;IAOhB,OAAO,CAAC,OAAO;CAiBhB"}
@@ -2,10 +2,10 @@ import { cpus, totalmem, freemem } from 'node:os';
2
2
  /**
3
3
  * Periodically collects server resource metrics — CPU usage and memory.
4
4
  */
5
- export class ServerAggregator {
5
+ export class ServerRecorder {
6
6
  storage;
7
7
  intervalMs;
8
- name = 'Server Aggregator';
8
+ name = 'Server Recorder';
9
9
  constructor(storage, intervalMs = 15_000) {
10
10
  this.storage = storage;
11
11
  this.intervalMs = intervalMs;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/recorders/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAGjD;;GAEG;AACH,MAAM,OAAO,cAAc;IAIN;IACA;IAJV,IAAI,GAAG,iBAAiB,CAAA;IAEjC,YACmB,OAAqB,EACrB,aAAqB,MAAM;QAD3B,YAAO,GAAP,OAAO,CAAc;QACrB,eAAU,GAAV,UAAU,CAAiB;IAC3C,CAAC;IAEJ,QAAQ;QACN,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;QAChE,KAAK,CAAC,KAAK,EAAE,CAAA;QACb,2BAA2B;QAC3B,IAAI,CAAC,OAAO,EAAE,CAAA;IAChB,CAAC;IAEO,OAAO;QACb,0CAA0C;QAC1C,MAAM,KAAK,GAAG,IAAI,EAAE,CAAA;QACpB,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;YAC5C,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;YAClE,MAAM,IAAI,GAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAA;YAC7B,OAAO,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,CAAA;QAC7C,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAA;QAEpB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAA;QAErE,2BAA2B;QAC3B,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAA;QACxB,MAAM,IAAI,GAAI,OAAO,EAAE,CAAA;QACvB,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,CAAA;QAClD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAA;IAC3E,CAAC;CACF"}
@@ -1,12 +1,12 @@
1
1
  import type { AppRequest, AppResponse } from '@rudderjs/contracts';
2
- import type { Aggregator, PulseStorage } from '../types.js';
2
+ import type { Recorder, PulseStorage } from '../types.js';
3
3
  /**
4
4
  * Tracks active (unique) users per minute bucket.
5
5
  * Identifies users by session cookie, auth header, or IP.
6
6
  */
7
- export declare class UserAggregator implements Aggregator {
7
+ export declare class UserRecorder implements Recorder {
8
8
  private readonly storage;
9
- readonly name = "User Aggregator";
9
+ readonly name = "User Recorder";
10
10
  private readonly seen;
11
11
  private currentMinute;
12
12
  constructor(storage: PulseStorage);
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../src/recorders/user.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAClE,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAGzD;;;GAGG;AACH,qBAAa,YAAa,YAAW,QAAQ;IAK/B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJpC,QAAQ,CAAC,IAAI,mBAAkB;IAC/B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAoB;IACzC,OAAO,CAAC,aAAa,CAAI;gBAEI,OAAO,EAAE,YAAY;IAElD,QAAQ,IAAI,IAAI;IAIhB,UAAU,KAGM,KAAK,UAAU,EAAE,MAAM,WAAW,EAAE,MAAM,MAAM,OAAO,CAAC,IAAI,CAAC;IAoB7E,OAAO,CAAC,YAAY;CAWrB"}
@@ -3,9 +3,9 @@ import { isAsset } from '../utils.js';
3
3
  * Tracks active (unique) users per minute bucket.
4
4
  * Identifies users by session cookie, auth header, or IP.
5
5
  */
6
- export class UserAggregator {
6
+ export class UserRecorder {
7
7
  storage;
8
- name = 'User Aggregator';
8
+ name = 'User Recorder';
9
9
  seen = new Set();
10
10
  currentMinute = 0;
11
11
  constructor(storage) {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/recorders/user.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAErC;;;GAGG;AACH,MAAM,OAAO,YAAY;IAKM;IAJpB,IAAI,GAAG,eAAe,CAAA;IACd,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;IACjC,aAAa,GAAG,CAAC,CAAA;IAEzB,YAA6B,OAAqB;QAArB,YAAO,GAAP,OAAO,CAAc;IAAG,CAAC;IAEtD,QAAQ;QACN,mDAAmD;IACrD,CAAC;IAED,UAAU;QACR,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;QAE5B,OAAO,KAAK,EAAE,GAAe,EAAE,IAAiB,EAAE,IAAyB,EAAE,EAAE;YAC7E,uDAAuD;YACvD,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,OAAO,IAAI,EAAE,CAAA;YAEpC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,CAAA;YAC9C,IAAI,MAAM,KAAK,IAAI,CAAC,aAAa,EAAE,CAAC;gBAClC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAA;gBACjB,IAAI,CAAC,aAAa,GAAG,MAAM,CAAA;YAC7B,CAAC;YAED,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAA;YACrC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC3B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;gBACrB,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAA;YACnC,CAAC;YAED,OAAO,IAAI,EAAE,CAAA;QACf,CAAC,CAAA;IACH,CAAC;IAEO,YAAY,CAAC,GAAe;QAClC,0CAA0C;QAC1C,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAA;QACzC,IAAI,IAAI;YAAE,OAAO,QAAQ,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAA;QAE5C,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAA;QAC1C,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,2BAA2B,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAC9D,IAAI,OAAO;YAAE,OAAO,WAAW,OAAO,EAAE,CAAA;QAExC,OAAO,MAAM,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,SAAS,EAAE,CAAA;IAC/G,CAAC;CACF"}
@@ -0,0 +1,23 @@
1
+ import type { MiddlewareHandler } from '@rudderjs/contracts';
2
+ import type { PulseStorage, PulseConfig } from './types.js';
3
+ export interface RegisterPulseRoutesOptions {
4
+ /** Path prefix for all pulse routes — default `/pulse` */
5
+ path?: string;
6
+ /** Auth gate — receives request, returns boolean. Same shape as `PulseConfig.auth`. */
7
+ auth?: PulseConfig['auth'];
8
+ /** Extra middleware to prepend to all routes */
9
+ middleware?: MiddlewareHandler[];
10
+ }
11
+ /**
12
+ * Register all Pulse routes — dashboard page and API endpoints. Called
13
+ * from `PulseProvider.boot()` once the router peer is resolved.
14
+ *
15
+ * Mirrors the package-UI shape established by `@rudderjs/auth`'s
16
+ * `registerAuthRoutes()`, `@rudderjs/telescope`'s
17
+ * `registerTelescopeRoutes()`, and `@rudderjs/horizon`'s
18
+ * `registerHorizonRoutes()`. Package-internal pages live under
19
+ * `views/vanilla/`, route registration is centralised here, the API
20
+ * handler implementations live in `api/routes.ts`.
21
+ */
22
+ export declare function registerPulseRoutes(storage: PulseStorage, opts?: RegisterPulseRoutesOptions): Promise<void>;
23
+ //# sourceMappingURL=routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA2B,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACrF,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAO3D,MAAM,WAAW,0BAA0B;IACzC,0DAA0D;IAC1D,IAAI,CAAC,EAAQ,MAAM,CAAA;IACnB,uFAAuF;IACvF,IAAI,CAAC,EAAQ,WAAW,CAAC,MAAM,CAAC,CAAA;IAChC,gDAAgD;IAChD,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAA;CACjC;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,YAAY,EACrB,IAAI,GAAK,0BAA+B,GACvC,OAAO,CAAC,IAAI,CAAC,CA2Cf"}
package/dist/routes.js ADDED
@@ -0,0 +1,44 @@
1
+ import { Dashboard } from './views/vanilla/index.js';
2
+ import { getOverview, getRequests, listSlowRequests, getQueues, listSlowQueries, getExceptions, getCache, getUsers, getServers, authMiddleware, } from './api/routes.js';
3
+ /**
4
+ * Register all Pulse routes — dashboard page and API endpoints. Called
5
+ * from `PulseProvider.boot()` once the router peer is resolved.
6
+ *
7
+ * Mirrors the package-UI shape established by `@rudderjs/auth`'s
8
+ * `registerAuthRoutes()`, `@rudderjs/telescope`'s
9
+ * `registerTelescopeRoutes()`, and `@rudderjs/horizon`'s
10
+ * `registerHorizonRoutes()`. Package-internal pages live under
11
+ * `views/vanilla/`, route registration is centralised here, the API
12
+ * handler implementations live in `api/routes.ts`.
13
+ */
14
+ export async function registerPulseRoutes(storage, opts = {}) {
15
+ let router;
16
+ try {
17
+ router = (await import('@rudderjs/router')).router;
18
+ }
19
+ catch {
20
+ return; // @rudderjs/router not installed — pulse routes disabled
21
+ }
22
+ const basePath = `/${(opts.path ?? 'pulse').replace(/^\/+/, '')}`;
23
+ const apiPrefix = `${basePath}/api`;
24
+ const middleware = [
25
+ ...(opts.middleware ?? []),
26
+ ...(opts.auth ? [authMiddleware({ auth: opts.auth })] : []),
27
+ ];
28
+ const html = (_req, res, content) => {
29
+ res.header('Content-Type', 'text/html').send(content);
30
+ };
31
+ // ── Dashboard UI ─────────────────────────────────────────
32
+ router.get(basePath, (r, s) => html(r, s, Dashboard({ apiPrefix })), middleware);
33
+ // ── API ──────────────────────────────────────────────────
34
+ router.get(`${apiPrefix}/overview`, (req, res) => getOverview(storage, req, res), middleware);
35
+ router.get(`${apiPrefix}/requests`, (req, res) => getRequests(storage, req, res), middleware);
36
+ router.get(`${apiPrefix}/slow-requests`, (req, res) => listSlowRequests(storage, req, res), middleware);
37
+ router.get(`${apiPrefix}/queues`, (req, res) => getQueues(storage, req, res), middleware);
38
+ router.get(`${apiPrefix}/slow-queries`, (req, res) => listSlowQueries(storage, req, res), middleware);
39
+ router.get(`${apiPrefix}/exceptions`, (req, res) => getExceptions(storage, req, res), middleware);
40
+ router.get(`${apiPrefix}/cache`, (req, res) => getCache(storage, req, res), middleware);
41
+ router.get(`${apiPrefix}/users`, (req, res) => getUsers(storage, req, res), middleware);
42
+ router.get(`${apiPrefix}/servers`, (req, res) => getServers(storage, req, res), middleware);
43
+ }
44
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -36,7 +36,7 @@ export interface EntryListOptions {
36
36
  perPage?: number | undefined;
37
37
  search?: string | undefined;
38
38
  }
39
- export interface Aggregator {
39
+ export interface Recorder {
40
40
  readonly name: string;
41
41
  register(): void | Promise<void>;
42
42
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAkG9D,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,OAAO,EAAgB,IAAI;IAC3B,IAAI,EAAmB,OAAO;IAC9B,OAAO,EAAgB,QAAiB;IACxC,UAAU,EAAa,WAAW;IAClC,eAAe,EAAQ,GAAG,EAAG,SAAS;IACtC,oBAAoB,EAAG,IAAI,EAAE,KAAK;IAClC,kBAAkB,EAAK,GAAG,EAAG,KAAK;IAClC,cAAc,EAAS,IAAI;IAC3B,YAAY,EAAW,IAAI;IAC3B,WAAW,EAAY,IAAI;IAC3B,gBAAgB,EAAO,IAAI;IAC3B,WAAW,EAAY,IAAI;IAC3B,aAAa,EAAU,IAAI;IAC3B,qBAAqB,EAAE,MAAM;IAC7B,IAAI,EAAmB,IAA6D;CACrF,CAAA"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAuG9D,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,OAAO,EAAgB,IAAI;IAC3B,IAAI,EAAmB,OAAO;IAC9B,OAAO,EAAgB,QAAiB;IACxC,UAAU,EAAa,WAAW;IAClC,eAAe,EAAQ,GAAG,EAAG,SAAS;IACtC,oBAAoB,EAAG,IAAI,EAAE,KAAK;IAClC,kBAAkB,EAAK,GAAG,EAAG,KAAK;IAClC,cAAc,EAAS,IAAI;IAC3B,YAAY,EAAW,IAAI;IAC3B,WAAW,EAAY,IAAI;IAC3B,gBAAgB,EAAO,IAAI;IAC3B,WAAW,EAAY,IAAI;IAC3B,aAAa,EAAU,IAAI;IAC3B,qBAAqB,EAAE,MAAM;IAC7B,IAAI,EAAmB,IAA6D;CACrF,CAAA"}
@@ -0,0 +1,11 @@
1
+ export interface DashboardProps {
2
+ apiPrefix: string;
3
+ }
4
+ /**
5
+ * Pulse single-page dashboard — metric cards (request throughput, cache
6
+ * hit rate, queue jobs, exceptions, active users, server CPU/memory)
7
+ * with sparklines + slow-request and recent-exception tables.
8
+ * Auto-refreshes every 10 seconds.
9
+ */
10
+ export declare function Dashboard(props: DashboardProps): string;
11
+ //# sourceMappingURL=Dashboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dashboard.d.ts","sourceRoot":"","sources":["../../../src/views/vanilla/Dashboard.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAuOvD"}
@@ -1,9 +1,13 @@
1
- import { layout } from './layout.js';
1
+ import { Layout } from './Layout.js';
2
2
  /**
3
- * Renders the Pulse dashboard — a single page with metric cards that auto-refresh.
3
+ * Pulse single-page dashboard — metric cards (request throughput, cache
4
+ * hit rate, queue jobs, exceptions, active users, server CPU/memory)
5
+ * with sparklines + slow-request and recent-exception tables.
6
+ * Auto-refreshes every 10 seconds.
4
7
  */
5
- export function dashboardPage(apiPrefix) {
6
- return layout('Dashboard', `
8
+ export function Dashboard(props) {
9
+ const { apiPrefix } = props;
10
+ const body = `
7
11
  <div x-data="dashboard()" x-init="load()" x-cloak>
8
12
  <!-- Metric Cards Grid -->
9
13
  <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
@@ -166,7 +170,6 @@ export function dashboardPage(apiPrefix) {
166
170
  </div>
167
171
  </div>
168
172
 
169
- <!-- Auto-refresh indicator -->
170
173
  <div class="mt-4 text-center text-xs text-gray-400">
171
174
  Auto-refreshes every 10 seconds
172
175
  </div>
@@ -229,6 +232,7 @@ export function dashboardPage(apiPrefix) {
229
232
  }
230
233
  }
231
234
  }
232
- </script>`, 'pulse');
235
+ </script>`;
236
+ return Layout({ title: 'Dashboard', body });
233
237
  }
234
- //# sourceMappingURL=dashboard.js.map
238
+ //# sourceMappingURL=Dashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dashboard.js","sourceRoot":"","sources":["../../../src/views/vanilla/Dashboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAMpC;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,KAAqB;IAC7C,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAA;IAE3B,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBA2LQ,SAAS;uBACT,SAAS;uBACT,SAAS;uBACT,SAAS;uBACT,SAAS;uBACT,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAiClB,CAAA;IAEZ,OAAO,MAAM,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;AAC7C,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Shared HTML chrome for Pulse dashboard pages.
3
+ *
4
+ * Vanilla mode — Alpine.js + Tailwind via CDN, no client framework
5
+ * dependency, no build step. Self-contained so pulse can run in any
6
+ * RudderJS app regardless of frontend stack.
7
+ */
8
+ export interface LayoutProps {
9
+ title: string;
10
+ body: string;
11
+ }
12
+ export declare function Layout(props: LayoutProps): string;
13
+ //# sourceMappingURL=Layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Layout.d.ts","sourceRoot":"","sources":["../../../src/views/vanilla/Layout.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAG,MAAM,CAAA;CACd;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CA6CjD"}
@@ -1,9 +1,7 @@
1
- /**
2
- * Shared HTML layout for Pulse UI pages.
3
- * Uses Tailwind CSS (CDN) + Alpine.js (CDN) for a zero-build UI.
4
- */
5
- export function layout(title, body, path) {
6
- return `<!DOCTYPE html>
1
+ import { html, raw } from './_html.js';
2
+ export function Layout(props) {
3
+ const { title, body } = props;
4
+ return html `<!DOCTYPE html>
7
5
  <html lang="en">
8
6
  <head>
9
7
  <meta charset="UTF-8">
@@ -20,14 +18,11 @@ export function layout(title, body, path) {
20
18
  </head>
21
19
  <body class="bg-gray-50 text-gray-900 font-sans antialiased">
22
20
  <div class="min-h-screen">
23
- <!-- Header -->
24
21
  <header class="bg-white border-b border-gray-200 px-6 py-4">
25
22
  <div class="max-w-7xl mx-auto flex items-center justify-between">
26
23
  <div class="flex items-center gap-3">
27
24
  <div class="w-8 h-8 bg-indigo-600 rounded-lg flex items-center justify-center">
28
- <svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
29
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
30
- </svg>
25
+ ${raw('<svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/></svg>')}
31
26
  </div>
32
27
  <h1 class="text-lg font-semibold">Pulse</h1>
33
28
  </div>
@@ -42,13 +37,11 @@ export function layout(title, body, path) {
42
37
  </div>
43
38
  </div>
44
39
  </header>
45
-
46
- <!-- Content -->
47
40
  <main class="max-w-7xl mx-auto px-6 py-8">
48
- ${body}
41
+ ${raw(body)}
49
42
  </main>
50
43
  </div>
51
44
  </body>
52
- </html>`;
45
+ </html>`.value;
53
46
  }
54
- //# sourceMappingURL=layout.js.map
47
+ //# sourceMappingURL=Layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Layout.js","sourceRoot":"","sources":["../../../src/views/vanilla/Layout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,YAAY,CAAA;AAetC,MAAM,UAAU,MAAM,CAAC,KAAkB;IACvC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,CAAA;IAE7B,OAAO,IAAI,CAAA;;;;;WAKF,KAAK;;;;;;;;;;;;;;;;cAgBF,GAAG,CAAC,8WAA8W,CAAC;;;;;;;;;;;;;;;;QAgBzX,GAAG,CAAC,IAAI,CAAC;;;;QAIT,CAAC,KAAK,CAAA;AACd,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Tiny HTML templating helper — inlined from `@rudderjs/view`'s `html\`\``,
3
+ * `escapeHtml`, and `SafeString` so pulse doesn't need to pull
4
+ * `@rudderjs/view` (which has a `vike` peer dep that's unwanted baggage
5
+ * for a self-contained debug tool).
6
+ *
7
+ * Mirrors the same helper used by `@rudderjs/telescope` and
8
+ * `@rudderjs/horizon`. If `@rudderjs/view` ever drops the Vike peer or
9
+ * splits the HTML helpers into a separate package, this file can be
10
+ * replaced with a one-line `export ... from '@rudderjs/view'`.
11
+ *
12
+ * Semantics:
13
+ * - Primitives are escaped via `escapeHtml`
14
+ * - `null`/`undefined`/`false` render as empty string
15
+ * - Arrays recursively render and join (no separator)
16
+ * - `SafeString` instances pass through unchanged (escape hatch for
17
+ * composing nested templates or injecting trusted markup)
18
+ */
19
+ export declare class SafeString {
20
+ readonly value: string;
21
+ constructor(value: string);
22
+ toString(): string;
23
+ }
24
+ export declare function escapeHtml(value: unknown): string;
25
+ export declare function html(strings: TemplateStringsArray, ...values: unknown[]): SafeString;
26
+ /** Wrap pre-rendered, trusted HTML so it passes through `html\`\`` interpolation unchanged. */
27
+ export declare function raw(value: string): SafeString;
28
+ //# sourceMappingURL=_html.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_html.d.ts","sourceRoot":"","sources":["../../../src/views/vanilla/_html.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,qBAAa,UAAU;aACO,KAAK,EAAE,MAAM;gBAAb,KAAK,EAAE,MAAM;IACzC,QAAQ,IAAI,MAAM;CACnB;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQjD;AASD,wBAAgB,IAAI,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAMpF;AAED,+FAA+F;AAC/F,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAE7C"}