@adonis-agora/telescope 0.2.0 → 0.3.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 (120) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/providers/telescope_provider.d.ts +16 -0
  3. package/dist/providers/telescope_provider.d.ts.map +1 -1
  4. package/dist/providers/telescope_provider.js +33 -2
  5. package/dist/providers/telescope_provider.js.map +1 -1
  6. package/dist/providers/telescope_ui_provider.d.ts.map +1 -1
  7. package/dist/providers/telescope_ui_provider.js +87 -1
  8. package/dist/providers/telescope_ui_provider.js.map +1 -1
  9. package/dist/providers/telescope_watchers_provider.d.ts +11 -0
  10. package/dist/providers/telescope_watchers_provider.d.ts.map +1 -1
  11. package/dist/providers/telescope_watchers_provider.js +58 -0
  12. package/dist/providers/telescope_watchers_provider.js.map +1 -1
  13. package/dist/src/define_config.d.ts +50 -0
  14. package/dist/src/define_config.d.ts.map +1 -1
  15. package/dist/src/define_config.js +9 -0
  16. package/dist/src/define_config.js.map +1 -1
  17. package/dist/src/index.d.ts +23 -2
  18. package/dist/src/index.d.ts.map +1 -1
  19. package/dist/src/index.js +17 -1
  20. package/dist/src/index.js.map +1 -1
  21. package/dist/src/metrics/metrics_service.d.ts +63 -0
  22. package/dist/src/metrics/metrics_service.d.ts.map +1 -0
  23. package/dist/src/metrics/metrics_service.js +116 -0
  24. package/dist/src/metrics/metrics_service.js.map +1 -0
  25. package/dist/src/metrics/rollup.d.ts +61 -0
  26. package/dist/src/metrics/rollup.d.ts.map +1 -0
  27. package/dist/src/metrics/rollup.js +114 -0
  28. package/dist/src/metrics/rollup.js.map +1 -0
  29. package/dist/src/metrics/stats.d.ts +112 -0
  30. package/dist/src/metrics/stats.d.ts.map +1 -0
  31. package/dist/src/metrics/stats.js +255 -0
  32. package/dist/src/metrics/stats.js.map +1 -0
  33. package/dist/src/metrics/timeseries.d.ts +22 -0
  34. package/dist/src/metrics/timeseries.d.ts.map +1 -0
  35. package/dist/src/metrics/timeseries.js +34 -0
  36. package/dist/src/metrics/timeseries.js.map +1 -0
  37. package/dist/src/metrics/traces.d.ts +27 -0
  38. package/dist/src/metrics/traces.d.ts.map +1 -0
  39. package/dist/src/metrics/traces.js +71 -0
  40. package/dist/src/metrics/traces.js.map +1 -0
  41. package/dist/src/metrics/waterfall.d.ts +44 -0
  42. package/dist/src/metrics/waterfall.d.ts.map +1 -0
  43. package/dist/src/metrics/waterfall.js +99 -0
  44. package/dist/src/metrics/waterfall.js.map +1 -0
  45. package/dist/src/query/n_plus_one.d.ts +60 -0
  46. package/dist/src/query/n_plus_one.d.ts.map +1 -0
  47. package/dist/src/query/n_plus_one.js +102 -0
  48. package/dist/src/query/n_plus_one.js.map +1 -0
  49. package/dist/src/registry.d.ts +9 -0
  50. package/dist/src/registry.d.ts.map +1 -1
  51. package/dist/src/registry.js +6 -0
  52. package/dist/src/registry.js.map +1 -1
  53. package/dist/src/sampling/sampling.d.ts +52 -0
  54. package/dist/src/sampling/sampling.d.ts.map +1 -0
  55. package/dist/src/sampling/sampling.js +111 -0
  56. package/dist/src/sampling/sampling.js.map +1 -0
  57. package/dist/src/sampling/sampling_store.d.ts +33 -0
  58. package/dist/src/sampling/sampling_store.d.ts.map +1 -0
  59. package/dist/src/sampling/sampling_store.js +65 -0
  60. package/dist/src/sampling/sampling_store.js.map +1 -0
  61. package/dist/src/stream/entry_events.d.ts +45 -0
  62. package/dist/src/stream/entry_events.d.ts.map +1 -0
  63. package/dist/src/stream/entry_events.js +56 -0
  64. package/dist/src/stream/entry_events.js.map +1 -0
  65. package/dist/src/stream/index.d.ts +6 -0
  66. package/dist/src/stream/index.d.ts.map +1 -0
  67. package/dist/src/stream/index.js +5 -0
  68. package/dist/src/stream/index.js.map +1 -0
  69. package/dist/src/stream/stream_handler.d.ts +42 -0
  70. package/dist/src/stream/stream_handler.d.ts.map +1 -0
  71. package/dist/src/stream/stream_handler.js +48 -0
  72. package/dist/src/stream/stream_handler.js.map +1 -0
  73. package/dist/src/stream/streaming_store.d.ts +31 -0
  74. package/dist/src/stream/streaming_store.d.ts.map +1 -0
  75. package/dist/src/stream/streaming_store.js +49 -0
  76. package/dist/src/stream/streaming_store.js.map +1 -0
  77. package/dist/src/ui/api.d.ts +39 -1
  78. package/dist/src/ui/api.d.ts.map +1 -1
  79. package/dist/src/ui/api.js +116 -1
  80. package/dist/src/ui/api.js.map +1 -1
  81. package/dist/src/ui/define_config.d.ts +27 -0
  82. package/dist/src/ui/define_config.d.ts.map +1 -1
  83. package/dist/src/ui/define_config.js +6 -0
  84. package/dist/src/ui/define_config.js.map +1 -1
  85. package/dist/src/ui/http.d.ts +40 -0
  86. package/dist/src/ui/http.d.ts.map +1 -1
  87. package/dist/src/ui/http.js +43 -0
  88. package/dist/src/ui/http.js.map +1 -1
  89. package/dist/src/ui/index.d.ts +5 -3
  90. package/dist/src/ui/index.d.ts.map +1 -1
  91. package/dist/src/ui/index.js +3 -1
  92. package/dist/src/ui/index.js.map +1 -1
  93. package/dist/src/ui/request_replay.d.ts +56 -0
  94. package/dist/src/ui/request_replay.d.ts.map +1 -0
  95. package/dist/src/ui/request_replay.js +120 -0
  96. package/dist/src/ui/request_replay.js.map +1 -0
  97. package/dist/src/watchers/define_config.d.ts +17 -1
  98. package/dist/src/watchers/define_config.d.ts.map +1 -1
  99. package/dist/src/watchers/define_config.js +13 -0
  100. package/dist/src/watchers/define_config.js.map +1 -1
  101. package/dist/src/watchers/events_watcher.d.ts +63 -0
  102. package/dist/src/watchers/events_watcher.d.ts.map +1 -0
  103. package/dist/src/watchers/events_watcher.js +81 -0
  104. package/dist/src/watchers/events_watcher.js.map +1 -0
  105. package/dist/src/watchers/index.d.ts +6 -0
  106. package/dist/src/watchers/index.d.ts.map +1 -1
  107. package/dist/src/watchers/index.js +6 -0
  108. package/dist/src/watchers/index.js.map +1 -1
  109. package/dist/src/watchers/queue_watcher.d.ts +97 -0
  110. package/dist/src/watchers/queue_watcher.d.ts.map +1 -0
  111. package/dist/src/watchers/queue_watcher.js +114 -0
  112. package/dist/src/watchers/queue_watcher.js.map +1 -0
  113. package/dist/src/watchers/redis_watcher.d.ts +103 -0
  114. package/dist/src/watchers/redis_watcher.d.ts.map +1 -0
  115. package/dist/src/watchers/redis_watcher.js +161 -0
  116. package/dist/src/watchers/redis_watcher.js.map +1 -0
  117. package/dist/stubs/config/telescope.stub +9 -0
  118. package/dist/stubs/config/telescope_ui.stub +13 -0
  119. package/dist/stubs/config/telescope_watchers.stub +14 -3
  120. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/ui/http.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA4BH;;;GAGG;AACH,MAAM,OAAO,iBAAiB;IAC5B,UAAU,GAAG,GAAG,CAAC;IACR,OAAO,GAA2B,EAAE,CAAC;IAC9C,IAAI,GAAY,SAAS,CAAC;IAC1B,IAAI,GAAG,KAAK,CAAC;IAEb,MAAM,CAAC,IAAY;QACjB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,IAAY,EAAE,KAAa;QAChC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,IAAa;QAChB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED,gFAAgF;AAChF,MAAM,UAAU,WAAW,CACzB,MAAc,EACd,KAA8B,EAAE,EAChC,UAAkC,EAAE;IAEpC,MAAM,KAAK,GAA2B,EAAE,CAAC;IACzC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC;IACrF,OAAO;QACL,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM;QACpB,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE;QACZ,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;KAC5C,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/ui/http.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA4BH;;;GAGG;AACH,MAAM,OAAO,iBAAiB;IAC5B,UAAU,GAAG,GAAG,CAAC;IACR,OAAO,GAA2B,EAAE,CAAC;IAC9C,IAAI,GAAY,SAAS,CAAC;IAC1B,IAAI,GAAG,KAAK,CAAC;IAEb,MAAM,CAAC,IAAY;QACjB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,IAAY,EAAE,KAAa;QAChC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,IAAa;QAChB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAmBD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAAC,IAAa,EAAE,KAAc;IAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9D,OAAO,GAAG,MAAM,SAAS,OAAO,MAAM,CAAC;AACzC,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,kBAAkB;IAChC,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,aAAa;IACf,MAAM,GAAa,EAAE,CAAC;IAC/B,MAAM,GAAG,KAAK,CAAC;IACE,aAAa,GAAsB,EAAE,CAAC;IAEvD,KAAK,CAAC,KAAa;QACjB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,CAAC,OAAmB;QACzB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,gFAAgF;IAChF,KAAK;QACH,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;YAAE,OAAO,EAAE,CAAC;IAChE,CAAC;CACF;AAED,gFAAgF;AAChF,MAAM,UAAU,WAAW,CACzB,MAAc,EACd,KAA8B,EAAE,EAChC,UAAkC,EAAE;IAEpC,MAAM,KAAK,GAA2B,EAAE,CAAC;IACzC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC;IACrF,OAAO;QACL,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM;QACpB,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE;QACZ,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;KAC5C,CAAC;AACJ,CAAC"}
@@ -1,12 +1,14 @@
1
1
  /** Keep in sync with this package's `version` in package.json. */
2
2
  export declare const VERSION = "0.1.0";
3
3
  export { defineConfig, resolveConfig, normalizePath, defaultAuthorize } from './define_config.js';
4
- export type { AuthorizeHook, ResolvedTelescopeUiConfig, TelescopeUiConfig, UiCredentials, } from './define_config.js';
5
- export { RecordingResponse, makeRequest } from './http.js';
6
- export type { UiHttpContext, UiRequest, UiResponse } from './http.js';
4
+ export type { AuthorizeHook, ReplayConfig, ResolvedTelescopeUiConfig, TelescopeUiConfig, UiCredentials, } from './define_config.js';
5
+ export { RecordingResponse, RecordingSink, formatSseFrame, formatSseHeartbeat, makeRequest, } from './http.js';
6
+ export type { SseSink, UiHttpContext, UiRequest, UiResponse } from './http.js';
7
7
  export { enforceGuard, runGuard } from './guard.js';
8
8
  export type { GuardResult } from './guard.js';
9
9
  export { TelescopeApi, buildQuery, toSummary } from './api.js';
10
10
  export type { EntrySummary } from './api.js';
11
+ export { replayRequest, REPLAY_BODY_CAP, REPLAY_STRIPPED_HEADERS, REPLAY_TIMEOUT_MS, } from './request_replay.js';
12
+ export type { ReplayOptions, ReplayResult, ReplayTransport } from './request_replay.js';
11
13
  export { renderDashboard } from './dashboard.js';
12
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAClG,YAAY,EACV,aAAa,EACb,yBAAyB,EACzB,iBAAiB,EACjB,aAAa,GACd,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC3D,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAGtE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACpD,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC/D,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG7C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAClG,YAAY,EACV,aAAa,EACb,YAAY,EACZ,yBAAyB,EACzB,iBAAiB,EACjB,aAAa,GACd,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,WAAW,GACZ,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAG/E,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACpD,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC/D,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG7C,OAAO,EACL,aAAa,EACb,eAAe,EACf,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAGxF,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
@@ -3,11 +3,13 @@ export const VERSION = '0.1.0';
3
3
  // — config —
4
4
  export { defineConfig, resolveConfig, normalizePath, defaultAuthorize } from './define_config.js';
5
5
  // — HTTP shapes (framework-light) —
6
- export { RecordingResponse, makeRequest } from './http.js';
6
+ export { RecordingResponse, RecordingSink, formatSseFrame, formatSseHeartbeat, makeRequest, } from './http.js';
7
7
  // — auth guard —
8
8
  export { enforceGuard, runGuard } from './guard.js';
9
9
  // — JSON API —
10
10
  export { TelescopeApi, buildQuery, toSummary } from './api.js';
11
+ // — request replay —
12
+ export { replayRequest, REPLAY_BODY_CAP, REPLAY_STRIPPED_HEADERS, REPLAY_TIMEOUT_MS, } from './request_replay.js';
11
13
  // — dashboard —
12
14
  export { renderDashboard } from './dashboard.js';
13
15
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,aAAa;AACb,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAQlG,oCAAoC;AACpC,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAG3D,iBAAiB;AACjB,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGpD,eAAe;AACf,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAG/D,gBAAgB;AAChB,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,aAAa;AACb,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AASlG,oCAAoC;AACpC,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,WAAW,GACZ,MAAM,WAAW,CAAC;AAGnB,iBAAiB;AACjB,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGpD,eAAe;AACf,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAG/D,qBAAqB;AACrB,OAAO,EACL,aAAa,EACb,eAAe,EACf,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAG7B,gBAAgB;AAChB,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,56 @@
1
+ import type { RequestEntryContent } from '../request_watcher.js';
2
+ /** A minimal `fetch`-shaped transport, injectable so tests don't hit the network. */
3
+ export type ReplayTransport = (url: string, init: {
4
+ method: string;
5
+ headers: Record<string, string>;
6
+ body?: string;
7
+ signal: AbortSignal;
8
+ redirect: 'manual';
9
+ }) => Promise<{
10
+ status: number;
11
+ text(): Promise<string>;
12
+ }>;
13
+ /** Options for {@link replayRequest} (all injectable for tests). */
14
+ export interface ReplayOptions {
15
+ /** Transport used to re-issue the call. Defaults to the global `fetch`,
16
+ * marked internal so the http-client watcher skips it. */
17
+ transport?: ReplayTransport;
18
+ /** The local server port to target. Defaults to `PORT` env or 3000. */
19
+ port?: number;
20
+ /** Per-call timeout in ms. Default {@link REPLAY_TIMEOUT_MS}. */
21
+ timeoutMs?: number;
22
+ /** Time source; injectable for tests. Default `Date.now`. */
23
+ clock?: {
24
+ now(): number;
25
+ };
26
+ }
27
+ /** Outcome of a request replay. */
28
+ export interface ReplayResult {
29
+ /** HTTP status of the replayed response, or `0` when the call never completed. */
30
+ status: number;
31
+ /** Wall-clock duration of the replay in ms. */
32
+ durationMs: number;
33
+ /** The response body, capped at {@link REPLAY_BODY_CAP} bytes. */
34
+ body: string;
35
+ /** Present when the replay failed to complete (timeout / network error). */
36
+ error?: string;
37
+ }
38
+ /** Default per-call timeout for a replay (30s). */
39
+ export declare const REPLAY_TIMEOUT_MS = 30000;
40
+ /** Max bytes of the replayed response body returned (4 KB). */
41
+ export declare const REPLAY_BODY_CAP = 4096;
42
+ /** Headers stripped from the replayed request (auth/session/routing leakage). */
43
+ export declare const REPLAY_STRIPPED_HEADERS: Set<string>;
44
+ /**
45
+ * Re-issue a captured `request` entry against the LOCAL server (127.0.0.1:<port>)
46
+ * so a developer can reproduce it from the dashboard.
47
+ *
48
+ * The Adonis `request` watcher only captures `method` + `url` (path), so the
49
+ * replay reconstructs exactly that: a GET-style call to the same local path. The
50
+ * call carries `x-telescope-replay: 1`, strips cookie/authorization/host headers
51
+ * (see the SAFETY POSTURE at the top of this file), is bounded by a timeout, and
52
+ * caps the returned body at 4 KB. Never throws — a failed call returns
53
+ * `status: 0` with an `error`.
54
+ */
55
+ export declare function replayRequest(content: RequestEntryContent, options?: ReplayOptions): Promise<ReplayResult>;
56
+ //# sourceMappingURL=request_replay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request_replay.d.ts","sourceRoot":"","sources":["../../../src/ui/request_replay.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEjE,qFAAqF;AACrF,MAAM,MAAM,eAAe,GAAG,CAC5B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IACJ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC;CACpB,KACE,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC,CAAC;AAE1D,oEAAoE;AACpE,MAAM,WAAW,aAAa;IAC5B;+DAC2D;IAC3D,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,KAAK,CAAC,EAAE;QAAE,GAAG,IAAI,MAAM,CAAA;KAAE,CAAC;CAC3B;AAED,mCAAmC;AACnC,MAAM,WAAW,YAAY;IAC3B,kFAAkF;IAClF,MAAM,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,mDAAmD;AACnD,eAAO,MAAM,iBAAiB,QAAS,CAAC;AACxC,+DAA+D;AAC/D,eAAO,MAAM,eAAe,OAAO,CAAC;AACpC,iFAAiF;AACjF,eAAO,MAAM,uBAAuB,aAKlC,CAAC;AAEH;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,mBAAmB,EAC5B,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC,CAqCvB"}
@@ -0,0 +1,120 @@
1
+ // packages/core/src/ui/request_replay.ts
2
+ //
3
+ // Request REPLAY subsystem: re-issue a captured `request` entry against the LOCAL
4
+ // server so a developer can reproduce it from the dashboard. Ported from the
5
+ // NestJS `nestjs-telescope` `nest/request-replay.ts` (the source of truth) and
6
+ // adapted to the Adonis telescope data model and outbound-fetch conventions.
7
+ //
8
+ // SAFETY POSTURE (read before changing anything here):
9
+ // - DISABLED BY DEFAULT. Replaying re-issues a real request that may MUTATE
10
+ // application state (a captured `POST`/`DELETE` will run again), so the host
11
+ // must opt in via `config/telescope_ui.ts` → `replay: { enabled: true }`.
12
+ // This mirrors the NestJS original, which gates replay behind a default-deny
13
+ // `authorizeAction` mutation gate. A disabled replay never issues a call.
14
+ // - SAME-ORIGIN ONLY. The replay always targets `127.0.0.1:<port>` (the local
15
+ // server) — never an arbitrary URL — so it can't be turned into an SSRF
16
+ // primitive against internal services. Only the captured PATH is reused.
17
+ // - CREDENTIAL STRIPPING. `cookie` / `authorization` / `host` / `content-length`
18
+ // are stripped (see {@link REPLAY_STRIPPED_HEADERS}): a replay must not
19
+ // silently reuse the original caller's credentials or session.
20
+ // - SELF-IDENTIFYING. The replay carries `x-telescope-replay: 1` so the host
21
+ // can recognize/skip it, and the outbound fetch is marked internal so the
22
+ // http-client watcher never records (or recurses on) it.
23
+ // - BOUNDED. A 30s timeout and a 4 KB response-body cap; never throws — a
24
+ // failed call resolves to `status: 0` with an `error`.
25
+ //
26
+ // REDACTION / CAPTURED-DATA LIMITATION:
27
+ // The Adonis `request` watcher records only `method` + `url` (path, no query
28
+ // string), `status` and timing — it deliberately does NOT capture request
29
+ // headers or the request body (the NestJS original captured `headers`/`payload`
30
+ // and so could replay them; this port has no such fields to replay). A stored
31
+ // entry's `content` is also run through telescope's redaction before
32
+ // persistence, so even where a value exists it may be `[REDACTED]`. We therefore
33
+ // reconstruct only what is safe and present (method + path) and NEVER forward a
34
+ // redacted value upstream — there is nothing to leak.
35
+ /** Default per-call timeout for a replay (30s). */
36
+ export const REPLAY_TIMEOUT_MS = 30_000;
37
+ /** Max bytes of the replayed response body returned (4 KB). */
38
+ export const REPLAY_BODY_CAP = 4096;
39
+ /** Headers stripped from the replayed request (auth/session/routing leakage). */
40
+ export const REPLAY_STRIPPED_HEADERS = new Set([
41
+ 'cookie',
42
+ 'authorization',
43
+ 'host',
44
+ 'content-length',
45
+ ]);
46
+ /**
47
+ * Re-issue a captured `request` entry against the LOCAL server (127.0.0.1:<port>)
48
+ * so a developer can reproduce it from the dashboard.
49
+ *
50
+ * The Adonis `request` watcher only captures `method` + `url` (path), so the
51
+ * replay reconstructs exactly that: a GET-style call to the same local path. The
52
+ * call carries `x-telescope-replay: 1`, strips cookie/authorization/host headers
53
+ * (see the SAFETY POSTURE at the top of this file), is bounded by a timeout, and
54
+ * caps the returned body at 4 KB. Never throws — a failed call returns
55
+ * `status: 0` with an `error`.
56
+ */
57
+ export async function replayRequest(content, options = {}) {
58
+ const transport = options.transport ?? defaultTransport;
59
+ const clock = options.clock ?? { now: () => Date.now() };
60
+ const timeoutMs = options.timeoutMs ?? REPLAY_TIMEOUT_MS;
61
+ const port = resolvePort(options.port);
62
+ const path = content.url.startsWith('/') ? content.url : `/${content.url}`;
63
+ const url = `http://127.0.0.1:${port}${path}`;
64
+ const headers = buildReplayHeaders();
65
+ const method = (content.method || 'GET').toUpperCase();
66
+ const controller = new AbortController();
67
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
68
+ const startedAt = clock.now();
69
+ try {
70
+ const response = await transport(url, {
71
+ method,
72
+ headers,
73
+ signal: controller.signal,
74
+ redirect: 'manual',
75
+ });
76
+ const text = await response.text();
77
+ return {
78
+ status: response.status,
79
+ durationMs: clock.now() - startedAt,
80
+ body: text.slice(0, REPLAY_BODY_CAP),
81
+ };
82
+ }
83
+ catch (error) {
84
+ return {
85
+ status: 0,
86
+ durationMs: clock.now() - startedAt,
87
+ body: '',
88
+ error: error instanceof Error ? error.message : String(error),
89
+ };
90
+ }
91
+ finally {
92
+ clearTimeout(timer);
93
+ }
94
+ }
95
+ /**
96
+ * Build the replay request headers. Because the Adonis watcher captures no
97
+ * request headers, there is nothing to copy (and so nothing to leak) — we only
98
+ * force the self-identifying `x-telescope-replay: 1` marker. The
99
+ * {@link REPLAY_STRIPPED_HEADERS} set is documented/exported so the safety
100
+ * contract is explicit and unit-testable even though no source headers exist.
101
+ */
102
+ function buildReplayHeaders() {
103
+ return { 'x-telescope-replay': '1' };
104
+ }
105
+ /** Resolve the local server port: explicit override, then `PORT` env, then 3000. */
106
+ function resolvePort(explicit) {
107
+ if (typeof explicit === 'number' && Number.isFinite(explicit) && explicit > 0) {
108
+ return explicit;
109
+ }
110
+ const envPort = Number(process.env.PORT);
111
+ return Number.isFinite(envPort) && envPort > 0 ? envPort : 3000;
112
+ }
113
+ /** The default transport: the global `fetch`, marked internal so the http-client
114
+ * watcher never records (or recurses on) the replay call. */
115
+ const defaultTransport = (url, init) => fetch(url, { ...init, [INTERNAL]: true });
116
+ /** Mirror of `markInternalFetch`'s marker (`@agora/telescope:internalFetch`) so a
117
+ * replay's outbound fetch is skipped by the http-client watcher without creating
118
+ * a hard import cycle through the watcher module. */
119
+ const INTERNAL = Symbol.for('@agora/telescope:internalFetch');
120
+ //# sourceMappingURL=request_replay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request_replay.js","sourceRoot":"","sources":["../../../src/ui/request_replay.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,18 @@
1
+ /**
2
+ * NOTE — no `'schedule'` watcher is shipped, intentionally. The NestJS original
3
+ * (`@dudousxd/nestjs-telescope`'s schedule package) wraps `@nestjs/schedule`'s
4
+ * `@Cron`/`@Interval`/`@Timeout` decorators via its `SchedulerRegistry`. AdonisJS
5
+ * has NO first-party scheduler, and the popular community schedulers
6
+ * (`adonisjs-scheduler` et al.) emit nothing on the app emitter and expose no
7
+ * lifecycle hooks — so a generic schedule watcher could only be built by inventing
8
+ * /wrapping a private API. It is therefore deliberately omitted. In the Agora
9
+ * ecosystem, `@adonis-agora/durable` already bridges its scheduled/cron + workflow
10
+ * run events onto the diagnostics bus, which the generic {@link DiagnosticsWatcher}
11
+ * records — so scheduled-run observability is covered there, not by a bespoke
12
+ * schedule watcher.
13
+ */
1
14
  /** The per-technology watchers this package ships. */
2
- export type WatcherName = 'query' | 'mail' | 'cache' | 'http-client' | 'logs';
15
+ export type WatcherName = 'query' | 'mail' | 'cache' | 'http-client' | 'logs' | 'queue' | 'events' | 'redis';
3
16
  /**
4
17
  * The shape of `config/telescope_watchers.ts`. Everything is optional: by default
5
18
  * only the Lucid `query` watcher is enabled (it is the one whose events are
@@ -18,6 +31,9 @@ export interface TelescopeWatchersConfig {
18
31
  * - `'cache'` — records `@adonisjs/cache` hit/miss/write/delete events.
19
32
  * - `'http-client'` — records every outbound `fetch` call.
20
33
  * - `'logs'` — records AdonisJS logger output as `log` entries.
34
+ * - `'queue'` — records `@adonisjs/queue` job executions (optional peer).
35
+ * - `'events'` — records every event emitted through the core Emitter.
36
+ * - `'redis'` — records `@adonisjs/redis` commands (optional peer).
21
37
  */
22
38
  watchers?: WatcherName[];
23
39
  }
@@ -1 +1 @@
1
- {"version":3,"file":"define_config.d.ts","sourceRoot":"","sources":["../../../src/watchers/define_config.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,aAAa,GAAG,MAAM,CAAC;AAE9E;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;CAC1B;AAED,8EAA8E;AAC9E,MAAM,WAAW,+BAA+B;IAC9C,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;CAC5B;AAED,mFAAmF;AACnF,eAAO,MAAM,gBAAgB,EAAE,WAAW,EAAc,CAAC;AAEzD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,uBAAuB,GAAG,uBAAuB,CAErF;AAED,qDAAqD;AACrD,wBAAgB,aAAa,CAC3B,MAAM,GAAE,uBAA4B,GACnC,+BAA+B,CAKjC"}
1
+ {"version":3,"file":"define_config.d.ts","sourceRoot":"","sources":["../../../src/watchers/define_config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,sDAAsD;AACtD,MAAM,MAAM,WAAW,GACnB,OAAO,GACP,MAAM,GACN,OAAO,GACP,aAAa,GACb,MAAM,GACN,OAAO,GACP,QAAQ,GACR,OAAO,CAAC;AAEZ;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;CAC1B;AAED,8EAA8E;AAC9E,MAAM,WAAW,+BAA+B;IAC9C,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;CAC5B;AAED,mFAAmF;AACnF,eAAO,MAAM,gBAAgB,EAAE,WAAW,EAAc,CAAC;AAEzD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,uBAAuB,GAAG,uBAAuB,CAErF;AAED,qDAAqD;AACrD,wBAAgB,aAAa,CAC3B,MAAM,GAAE,uBAA4B,GACnC,+BAA+B,CAKjC"}
@@ -1,3 +1,16 @@
1
+ /**
2
+ * NOTE — no `'schedule'` watcher is shipped, intentionally. The NestJS original
3
+ * (`@dudousxd/nestjs-telescope`'s schedule package) wraps `@nestjs/schedule`'s
4
+ * `@Cron`/`@Interval`/`@Timeout` decorators via its `SchedulerRegistry`. AdonisJS
5
+ * has NO first-party scheduler, and the popular community schedulers
6
+ * (`adonisjs-scheduler` et al.) emit nothing on the app emitter and expose no
7
+ * lifecycle hooks — so a generic schedule watcher could only be built by inventing
8
+ * /wrapping a private API. It is therefore deliberately omitted. In the Agora
9
+ * ecosystem, `@adonis-agora/durable` already bridges its scheduled/cron + workflow
10
+ * run events onto the diagnostics bus, which the generic {@link DiagnosticsWatcher}
11
+ * records — so scheduled-run observability is covered there, not by a bespoke
12
+ * schedule watcher.
13
+ */
1
14
  /** The default set of enabled watchers — the verified Lucid query watcher only. */
2
15
  export const DEFAULT_WATCHERS = ['query'];
3
16
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"define_config.js","sourceRoot":"","sources":["../../../src/watchers/define_config.ts"],"names":[],"mappings":"AAgCA,mFAAmF;AACnF,MAAM,CAAC,MAAM,gBAAgB,GAAkB,CAAC,OAAO,CAAC,CAAC;AAEzD;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,MAA+B;IAC1D,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,aAAa,CAC3B,SAAkC,EAAE;IAEpC,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,IAAI;QAC/B,QAAQ,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,gBAAgB,CAAC;KACvD,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"define_config.js","sourceRoot":"","sources":["../../../src/watchers/define_config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA6CH,mFAAmF;AACnF,MAAM,CAAC,MAAM,gBAAgB,GAAkB,CAAC,OAAO,CAAC,CAAC;AAEzD;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,MAA+B;IAC1D,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,aAAa,CAC3B,SAAkC,EAAE;IAEpC,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,IAAI;QAC/B,QAAQ,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,gBAAgB,CAAC;KACvD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,63 @@
1
+ import { type RecordInput } from '../entry.js';
2
+ /**
3
+ * The narrow structural slice of the `@adonisjs/core` Emitter this watcher needs:
4
+ * `onAny(listener)` to observe EVERY emitted event, returning an unsubscribe
5
+ * function (the exact contract `@adonisjs/events` ships — its emitter, built on
6
+ * `emittery`, returns `() => void` from `onAny`). Mirrored structurally rather than
7
+ * imported so the watcher stays unit-testable with a plain double and carries no
8
+ * build-time coupling to a specific emitter version.
9
+ *
10
+ * The listener receives `(event, data)`: the event NAME (a string, or a class
11
+ * constructor for class-based events) and the single emitted payload.
12
+ */
13
+ export interface EmitterAnyLike {
14
+ onAny(listener: (event: unknown, data: unknown) => unknown): () => void;
15
+ }
16
+ /** Narrow an arbitrary resolved provider to one with a usable `onAny`. */
17
+ export declare function hasOnAny(value: unknown): value is EmitterAnyLike;
18
+ /** The recorded body of an `event` entry. */
19
+ export interface EventEntryContent {
20
+ /** The emitted event name (string events) or class name (class-based events). */
21
+ name: string;
22
+ /** The single emitted payload, recorded as-is (redaction applies downstream). */
23
+ payload: unknown;
24
+ /** The active trace id at emit time, or `null`. */
25
+ traceId: string | null;
26
+ }
27
+ /**
28
+ * Captures EVERY event emitted through the core `@adonisjs/core` Emitter and
29
+ * records one `event` telescope entry per emit — the name and payload — correlated
30
+ * to the active request via the trace id. It attaches a single wildcard listener
31
+ * via `emitter.onAny(...)`.
32
+ *
33
+ * An ignore-list (constructor option, matched against the resolved event name)
34
+ * filters out noisy or already-watched events — e.g. `'db:query'` (the Lucid query
35
+ * watcher already records those) or `'mail:sent'`. Mirrors the filtering of the
36
+ * NestJS `EventsWatcher` original.
37
+ *
38
+ * Recording is fire-and-forget and fully guarded: a telescope failure can never
39
+ * break or block an emit.
40
+ */
41
+ export declare class EventsWatcher {
42
+ readonly type: "event";
43
+ private readonly ignore;
44
+ private unsubscribe;
45
+ constructor(ignore?: string[]);
46
+ /**
47
+ * Begin recording. A no-op when the emitter has no `onAny` (degrades gracefully
48
+ * rather than throwing). Idempotent: a second call is ignored.
49
+ */
50
+ start(emitter: unknown): void;
51
+ /** Detach the wildcard listener. Safe to call when never started. */
52
+ stop(): void;
53
+ private handle;
54
+ }
55
+ /**
56
+ * The events the watcher ignores by default. These are emitted by Adonis surfaces
57
+ * that already have a dedicated telescope watcher, so capturing them here would
58
+ * double-record. A host can override the set via the constructor.
59
+ */
60
+ export declare const DEFAULT_IGNORED_EVENTS: string[];
61
+ /** Map an emitted event name + payload to a telescope {@link RecordInput}. */
62
+ export declare function buildEventEntry(name: string, payload: unknown): RecordInput<EventEntryContent>;
63
+ //# sourceMappingURL=events_watcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events_watcher.d.ts","sourceRoot":"","sources":["../../../src/watchers/events_watcher.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1D;;;;;;;;;;GAUG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,KAAK,OAAO,GAAG,MAAM,IAAI,CAAC;CACzE;AAED,0EAA0E;AAC1E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAMhE;AAED,6CAA6C;AAC7C,MAAM,WAAW,iBAAiB;IAChC,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,OAAO,EAAE,OAAO,CAAC;IACjB,mDAAmD;IACnD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAWD;;;;;;;;;;;;;GAaG;AACH,qBAAa,aAAa;IACxB,QAAQ,CAAC,IAAI,UAAmB;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,WAAW,CAA6B;gBAEpC,MAAM,GAAE,MAAM,EAA2B;IAIrD;;;OAGG;IACH,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAM7B,qEAAqE;IACrE,IAAI,IAAI,IAAI;IAKZ,OAAO,CAAC,MAAM;CAKf;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,EAA8B,CAAC;AAE1E,8EAA8E;AAC9E,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,WAAW,CAAC,iBAAiB,CAAC,CAU9F"}
@@ -0,0 +1,81 @@
1
+ import { currentTraceId } from '../context_accessor.js';
2
+ import { EntryType } from '../entry.js';
3
+ import { safeRecord } from './record.js';
4
+ /** Narrow an arbitrary resolved provider to one with a usable `onAny`. */
5
+ export function hasOnAny(value) {
6
+ return (typeof value === 'object' &&
7
+ value !== null &&
8
+ typeof value.onAny === 'function');
9
+ }
10
+ /** Coerce an Adonis event identifier (string, or a class constructor) to a name. */
11
+ function eventName(event) {
12
+ if (typeof event === 'string')
13
+ return event;
14
+ if (typeof event === 'function' && typeof event.name === 'string' && event.name) {
15
+ return event.name;
16
+ }
17
+ return String(event);
18
+ }
19
+ /**
20
+ * Captures EVERY event emitted through the core `@adonisjs/core` Emitter and
21
+ * records one `event` telescope entry per emit — the name and payload — correlated
22
+ * to the active request via the trace id. It attaches a single wildcard listener
23
+ * via `emitter.onAny(...)`.
24
+ *
25
+ * An ignore-list (constructor option, matched against the resolved event name)
26
+ * filters out noisy or already-watched events — e.g. `'db:query'` (the Lucid query
27
+ * watcher already records those) or `'mail:sent'`. Mirrors the filtering of the
28
+ * NestJS `EventsWatcher` original.
29
+ *
30
+ * Recording is fire-and-forget and fully guarded: a telescope failure can never
31
+ * break or block an emit.
32
+ */
33
+ export class EventsWatcher {
34
+ type = EntryType.Event;
35
+ ignore;
36
+ unsubscribe = null;
37
+ constructor(ignore = DEFAULT_IGNORED_EVENTS) {
38
+ this.ignore = new Set(ignore);
39
+ }
40
+ /**
41
+ * Begin recording. A no-op when the emitter has no `onAny` (degrades gracefully
42
+ * rather than throwing). Idempotent: a second call is ignored.
43
+ */
44
+ start(emitter) {
45
+ if (this.unsubscribe)
46
+ return;
47
+ if (!hasOnAny(emitter))
48
+ return;
49
+ this.unsubscribe = emitter.onAny((event, data) => this.handle(event, data));
50
+ }
51
+ /** Detach the wildcard listener. Safe to call when never started. */
52
+ stop() {
53
+ this.unsubscribe?.();
54
+ this.unsubscribe = null;
55
+ }
56
+ handle(event, data) {
57
+ const name = eventName(event);
58
+ if (this.ignore.has(name))
59
+ return;
60
+ safeRecord(buildEventEntry(name, data), 'EventsWatcher');
61
+ }
62
+ }
63
+ /**
64
+ * The events the watcher ignores by default. These are emitted by Adonis surfaces
65
+ * that already have a dedicated telescope watcher, so capturing them here would
66
+ * double-record. A host can override the set via the constructor.
67
+ */
68
+ export const DEFAULT_IGNORED_EVENTS = ['db:query', 'mail:sent'];
69
+ /** Map an emitted event name + payload to a telescope {@link RecordInput}. */
70
+ export function buildEventEntry(name, payload) {
71
+ const traceId = currentTraceId();
72
+ const content = { name, payload, traceId };
73
+ return {
74
+ type: EntryType.Event,
75
+ familyHash: `event:${name}`,
76
+ content,
77
+ traceId,
78
+ tags: ['event', `event:${name}`],
79
+ };
80
+ }
81
+ //# sourceMappingURL=events_watcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events_watcher.js","sourceRoot":"","sources":["../../../src/watchers/events_watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAoB,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAiBzC,0EAA0E;AAC1E,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,OAAQ,KAA6B,CAAC,KAAK,KAAK,UAAU,CAC3D,CAAC;AACJ,CAAC;AAYD,oFAAoF;AACpF,SAAS,SAAS,CAAC,KAAc;IAC/B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,OAAO,KAAK,KAAK,UAAU,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QAChF,OAAO,KAAK,CAAC,IAAI,CAAC;IACpB,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,aAAa;IACf,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC;IACf,MAAM,CAAc;IAC7B,WAAW,GAAwB,IAAI,CAAC;IAEhD,YAAY,SAAmB,sBAAsB;QACnD,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,OAAgB;QACpB,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAC7B,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,OAAO;QAC/B,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;IAC9E,CAAC;IAED,qEAAqE;IACrE,IAAI;QACF,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACrB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAC1B,CAAC;IAEO,MAAM,CAAC,KAAc,EAAE,IAAa;QAC1C,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO;QAClC,UAAU,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,eAAe,CAAC,CAAC;IAC3D,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAa,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;AAE1E,8EAA8E;AAC9E,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,OAAgB;IAC5D,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,MAAM,OAAO,GAAsB,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;IAC9D,OAAO;QACL,IAAI,EAAE,SAAS,CAAC,KAAK;QACrB,UAAU,EAAE,SAAS,IAAI,EAAE;QAC3B,OAAO;QACP,OAAO;QACP,IAAI,EAAE,CAAC,OAAO,EAAE,SAAS,IAAI,EAAE,CAAC;KACjC,CAAC;AACJ,CAAC"}
@@ -14,6 +14,12 @@ export type { HttpClientEntryContent, HttpClientWatcherOptions, } from './http_c
14
14
  export { normalizeHttpTarget } from './normalize_http_target.js';
15
15
  export { buildLogEntry, extractLog, LOG_LEVELS, LogsWatcher } from './logs_watcher.js';
16
16
  export type { LogEntryContent, LoggerLike, LogLevel, LogsWatcherOptions, } from './logs_watcher.js';
17
+ export { buildJobEntry, QUEUE_EXECUTE_CHANNEL, QueueWatcher } from './queue_watcher.js';
18
+ export type { AcquiredJobLike, JobEntryContent, JobExecuteMessageLike, JobStatus, QueueWatcherOptions, } from './queue_watcher.js';
19
+ export { buildEventEntry, DEFAULT_IGNORED_EVENTS, EventsWatcher, hasOnAny, } from './events_watcher.js';
20
+ export type { EmitterAnyLike, EventEntryContent } from './events_watcher.js';
21
+ export { buildRedisEntry, RedisWatcher } from './redis_watcher.js';
22
+ export type { RedisClientLike, RedisCommandLike, RedisConnectionLike, RedisEntryContent, RedisManagerLike, } from './redis_watcher.js';
17
23
  export { DEFAULT_WATCHERS, defineConfig, resolveConfig, } from './define_config.js';
18
24
  export type { ResolvedTelescopeWatchersConfig, TelescopeWatchersConfig, WatcherName, } from './define_config.js';
19
25
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/watchers/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGzD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGvD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC9F,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACpF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACjF,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG7E,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACjF,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAG5F,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAGjE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACvF,YAAY,EACV,eAAe,EACf,UAAU,EACV,QAAQ,EACR,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,aAAa,GACd,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,+BAA+B,EAC/B,uBAAuB,EACvB,WAAW,GACZ,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/watchers/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGzD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGvD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC9F,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACpF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACjF,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG7E,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACjF,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAG5F,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAGjE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACvF,YAAY,EACV,eAAe,EACf,UAAU,EACV,QAAQ,EACR,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACxF,YAAY,EACV,eAAe,EACf,eAAe,EACf,qBAAqB,EACrB,SAAS,EACT,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,aAAa,EACb,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAG7E,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACnE,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,aAAa,GACd,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,+BAA+B,EAC/B,uBAAuB,EACvB,WAAW,GACZ,MAAM,oBAAoB,CAAC"}
@@ -14,6 +14,12 @@ export { buildHttpClientEntry, HttpClientWatcher, markInternalFetch, } from './h
14
14
  export { normalizeHttpTarget } from './normalize_http_target.js';
15
15
  // — logs watcher —
16
16
  export { buildLogEntry, extractLog, LOG_LEVELS, LogsWatcher } from './logs_watcher.js';
17
+ // — queue/jobs watcher (optional peer: @adonisjs/queue) —
18
+ export { buildJobEntry, QUEUE_EXECUTE_CHANNEL, QueueWatcher } from './queue_watcher.js';
19
+ // — events watcher (core @adonisjs/core Emitter) —
20
+ export { buildEventEntry, DEFAULT_IGNORED_EVENTS, EventsWatcher, hasOnAny, } from './events_watcher.js';
21
+ // — redis watcher (optional peer: @adonisjs/redis) —
22
+ export { buildRedisEntry, RedisWatcher } from './redis_watcher.js';
17
23
  // — config —
18
24
  export { DEFAULT_WATCHERS, defineConfig, resolveConfig, } from './define_config.js';
19
25
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/watchers/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAK/B,mCAAmC;AACnC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEvD,iDAAiD;AACjD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE9F,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,mBAAmB;AACnB,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGjF,oBAAoB;AACpB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGjF,qCAAqC;AACrC,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAKlC,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,mBAAmB;AACnB,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAQvF,aAAa;AACb,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,aAAa,GACd,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/watchers/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAK/B,mCAAmC;AACnC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEvD,iDAAiD;AACjD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE9F,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,mBAAmB;AACnB,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGjF,oBAAoB;AACpB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGjF,qCAAqC;AACrC,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAKlC,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,mBAAmB;AACnB,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAQvF,0DAA0D;AAC1D,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AASxF,mDAAmD;AACnD,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,aAAa,EACb,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAG7B,qDAAqD;AACrD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AASnE,aAAa;AACb,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,aAAa,GACd,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,97 @@
1
+ import { type RecordInput } from '../entry.js';
2
+ /**
3
+ * The `node:diagnostics_channel` tracing channel `@boringnode/queue` (the engine
4
+ * behind the OPTIONAL peer `@adonisjs/queue`) publishes a job EXECUTION trace on.
5
+ * A tracing channel fires the sub-channels `<name>:start`, `:end`, `:asyncStart`,
6
+ * `:asyncEnd`, and `:error` around the traced async operation; we read the outcome
7
+ * off `:asyncEnd` (status/duration/error are mutated onto the same message during
8
+ * the trace's async lifecycle).
9
+ *
10
+ * `@adonisjs/queue` is not installed in this repo, so this channel name + payload
11
+ * shape are sourced from the engine's `src/tracing_channels.ts` rather than
12
+ * verified against installed types (the engine is pre-1.0, so this surface can
13
+ * drift). The watcher degrades to a pure no-op when nobody publishes on the
14
+ * channel — i.e. when the peer is absent.
15
+ */
16
+ export declare const QUEUE_EXECUTE_CHANNEL = "boringqueue.job.execute";
17
+ /** The terminal outcome of a single job execution attempt. */
18
+ export type JobStatus = 'completed' | 'failed' | 'retrying';
19
+ /**
20
+ * The structural slice of a single acquired job, as `@boringnode/queue` shapes it
21
+ * (`AcquiredJob`). Read defensively (every field optional) — the exact runtime
22
+ * shape is owned by the engine and could not be verified here.
23
+ */
24
+ export interface AcquiredJobLike {
25
+ id?: string;
26
+ name?: string;
27
+ payload?: unknown;
28
+ attempts?: number;
29
+ }
30
+ /**
31
+ * The structural slice of the `boringqueue.job.execute` tracing message read at
32
+ * `:asyncEnd`. `status`, `duration`, and `error` are populated by the engine on the
33
+ * way out of the trace.
34
+ */
35
+ export interface JobExecuteMessageLike {
36
+ job?: AcquiredJobLike;
37
+ queue?: string;
38
+ status?: JobStatus;
39
+ /** Execution duration in ms, set by the engine on completion. */
40
+ duration?: number;
41
+ error?: unknown;
42
+ }
43
+ /** The recorded body of a `job` entry. */
44
+ export interface JobEntryContent {
45
+ /** The job id, or `null` when the engine did not carry one. */
46
+ id: string | null;
47
+ /** The job class name (e.g. `'SendWelcomeEmail'`), or `null`. */
48
+ name: string | null;
49
+ /** The queue the job ran on (e.g. `'default'`), or `null`. */
50
+ queue: string | null;
51
+ /** The job payload (redaction applies downstream). `null` when absent. */
52
+ payload: unknown;
53
+ /** The execution outcome. */
54
+ status: JobStatus;
55
+ /** How many attempts the job had made, or `null`. */
56
+ attempts: number | null;
57
+ /** The failure message when `status` is `'failed'`/`'retrying'`, else `null`. */
58
+ failureReason: string | null;
59
+ /** The active trace id at execution time, or `null`. */
60
+ traceId: string | null;
61
+ }
62
+ /** Options for {@link QueueWatcher}. */
63
+ export interface QueueWatcherOptions {
64
+ /** Jobs whose execution time is >= this (ms) get a `slow` tag. Default 1000. */
65
+ slowMs?: number;
66
+ }
67
+ /**
68
+ * Records every `@adonisjs/queue` job EXECUTION as a `job` telescope entry —
69
+ * capturing the queue, job name, payload, outcome (completed/failed/retrying),
70
+ * attempts and duration, correlated to the active trace.
71
+ *
72
+ * ## How it works
73
+ * `@adonisjs/queue`'s engine (`@boringnode/queue`) publishes a
74
+ * `node:diagnostics_channel` TRACING channel per execution attempt
75
+ * ({@link QUEUE_EXECUTE_CHANNEL}). The watcher subscribes to its `:asyncEnd`
76
+ * sub-channel — fired once the execution settles, with `status`/`duration`/`error`
77
+ * populated — and records one entry per attempt. Subscribing is what flips the
78
+ * channel's `hasSubscribers` on; with no publisher (peer absent) it is a no-op.
79
+ *
80
+ * Like the other watchers, recording is fire-and-forget and fully guarded: a
81
+ * telescope failure can never break or block a job.
82
+ */
83
+ export declare class QueueWatcher {
84
+ readonly type: "job";
85
+ private readonly slowMs;
86
+ private handler;
87
+ constructor(options?: QueueWatcherOptions);
88
+ /** Subscribe to the queue execution trace. Idempotent. */
89
+ start(): void;
90
+ /** Unsubscribe from the queue execution trace. Safe to call when never started. */
91
+ stop(): void;
92
+ private handle;
93
+ }
94
+ /** Map a queue execution message to a telescope {@link RecordInput}. Exported so
95
+ * the entry shape can be unit-tested without a real diagnostics publish. */
96
+ export declare function buildJobEntry(message: JobExecuteMessageLike, slowMs?: number): RecordInput<JobEntryContent>;
97
+ //# sourceMappingURL=queue_watcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue_watcher.d.ts","sourceRoot":"","sources":["../../../src/watchers/queue_watcher.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qBAAqB,4BAA4B,CAAC;AAK/D,8DAA8D;AAC9D,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE5D;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,GAAG,CAAC,EAAE,eAAe,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,0CAA0C;AAC1C,MAAM,WAAW,eAAe;IAC9B,+DAA+D;IAC/D,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,iEAAiE;IACjE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,8DAA8D;IAC9D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,0EAA0E;IAC1E,OAAO,EAAE,OAAO,CAAC;IACjB,6BAA6B;IAC7B,MAAM,EAAE,SAAS,CAAC;IAClB,qDAAqD;IACrD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,iFAAiF;IACjF,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,wDAAwD;IACxD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,wCAAwC;AACxC,MAAM,WAAW,mBAAmB;IAClC,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAUD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,YAAY;IACvB,QAAQ,CAAC,IAAI,QAAiB;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,OAAO,CAAyC;gBAE5C,OAAO,GAAE,mBAAwB;IAI7C,0DAA0D;IAC1D,KAAK,IAAI,IAAI;IAOb,mFAAmF;IACnF,IAAI,IAAI,IAAI;IAMZ,OAAO,CAAC,MAAM;CAGf;AAED;6EAC6E;AAC7E,wBAAgB,aAAa,CAC3B,OAAO,EAAE,qBAAqB,EAC9B,MAAM,SAAkB,GACvB,WAAW,CAAC,eAAe,CAAC,CAqC9B"}