@rudderjs/telescope 0.0.1

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 (72) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +111 -0
  3. package/boost/guidelines.md +38 -0
  4. package/dist/api/routes.d.ts +7 -0
  5. package/dist/api/routes.d.ts.map +1 -0
  6. package/dist/api/routes.js +99 -0
  7. package/dist/api/routes.js.map +1 -0
  8. package/dist/collectors/cache.d.ts +13 -0
  9. package/dist/collectors/cache.d.ts.map +1 -0
  10. package/dist/collectors/cache.js +48 -0
  11. package/dist/collectors/cache.js.map +1 -0
  12. package/dist/collectors/event.d.ts +13 -0
  13. package/dist/collectors/event.d.ts.map +1 -0
  14. package/dist/collectors/event.js +36 -0
  15. package/dist/collectors/event.js.map +1 -0
  16. package/dist/collectors/exception.d.ts +13 -0
  17. package/dist/collectors/exception.d.ts.map +1 -0
  18. package/dist/collectors/exception.js +38 -0
  19. package/dist/collectors/exception.js.map +1 -0
  20. package/dist/collectors/job.d.ts +12 -0
  21. package/dist/collectors/job.d.ts.map +1 -0
  22. package/dist/collectors/job.js +53 -0
  23. package/dist/collectors/job.js.map +1 -0
  24. package/dist/collectors/log.d.ts +13 -0
  25. package/dist/collectors/log.d.ts.map +1 -0
  26. package/dist/collectors/log.js +35 -0
  27. package/dist/collectors/log.js.map +1 -0
  28. package/dist/collectors/mail.d.ts +12 -0
  29. package/dist/collectors/mail.d.ts.map +1 -0
  30. package/dist/collectors/mail.js +38 -0
  31. package/dist/collectors/mail.js.map +1 -0
  32. package/dist/collectors/model.d.ts +15 -0
  33. package/dist/collectors/model.d.ts.map +1 -0
  34. package/dist/collectors/model.js +49 -0
  35. package/dist/collectors/model.js.map +1 -0
  36. package/dist/collectors/notification.d.ts +12 -0
  37. package/dist/collectors/notification.d.ts.map +1 -0
  38. package/dist/collectors/notification.js +41 -0
  39. package/dist/collectors/notification.js.map +1 -0
  40. package/dist/collectors/query.d.ts +13 -0
  41. package/dist/collectors/query.d.ts.map +1 -0
  42. package/dist/collectors/query.js +45 -0
  43. package/dist/collectors/query.js.map +1 -0
  44. package/dist/collectors/request.d.ts +20 -0
  45. package/dist/collectors/request.d.ts.map +1 -0
  46. package/dist/collectors/request.js +73 -0
  47. package/dist/collectors/request.js.map +1 -0
  48. package/dist/collectors/schedule.d.ts +14 -0
  49. package/dist/collectors/schedule.d.ts.map +1 -0
  50. package/dist/collectors/schedule.js +50 -0
  51. package/dist/collectors/schedule.js.map +1 -0
  52. package/dist/index.d.ts +42 -0
  53. package/dist/index.d.ts.map +1 -0
  54. package/dist/index.js +170 -0
  55. package/dist/index.js.map +1 -0
  56. package/dist/storage.d.ts +35 -0
  57. package/dist/storage.d.ts.map +1 -0
  58. package/dist/storage.js +201 -0
  59. package/dist/storage.js.map +1 -0
  60. package/dist/types.d.ts +67 -0
  61. package/dist/types.d.ts.map +1 -0
  62. package/dist/types.js +24 -0
  63. package/dist/types.js.map +1 -0
  64. package/dist/ui/layout.d.ts +11 -0
  65. package/dist/ui/layout.d.ts.map +1 -0
  66. package/dist/ui/layout.js +69 -0
  67. package/dist/ui/layout.js.map +1 -0
  68. package/dist/ui/pages.d.ts +21 -0
  69. package/dist/ui/pages.d.ts.map +1 -0
  70. package/dist/ui/pages.js +225 -0
  71. package/dist/ui/pages.js.map +1 -0
  72. package/package.json +78 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Suleiman Shahbari
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # @rudderjs/telescope
2
+
3
+ Debug assistant for RudderJS — records requests, queries, jobs, exceptions, logs, mail, notifications, events, cache operations, scheduled tasks, and model changes.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @rudderjs/telescope
9
+ ```
10
+
11
+ ## Setup
12
+
13
+ ```ts
14
+ // bootstrap/providers.ts
15
+ import { telescope } from '@rudderjs/telescope'
16
+ import configs from '../config/index.js'
17
+ export default [..., telescope(configs.telescope), ...]
18
+ ```
19
+
20
+ ## Telescope Facade
21
+
22
+ ```ts
23
+ import { Telescope } from '@rudderjs/telescope'
24
+
25
+ // List entries by type
26
+ const requests = await Telescope.list({ type: 'request', perPage: 25 })
27
+ const exceptions = await Telescope.list({ type: 'exception' })
28
+ const queries = await Telescope.list({ type: 'query', search: 'SELECT' })
29
+
30
+ // Find a single entry
31
+ const entry = await Telescope.find('entry-id')
32
+
33
+ // Count entries
34
+ const total = await Telescope.count()
35
+ const jobCount = await Telescope.count('job')
36
+
37
+ // Prune entries
38
+ await Telescope.prune('log') // prune by type
39
+ await Telescope.prune() // prune all
40
+ ```
41
+
42
+ ## `Telescope` Methods
43
+
44
+ | Method | Returns | Description |
45
+ |--------|---------|-------------|
46
+ | `list(options?)` | `TelescopeEntry[]` | List entries with type/tag/search/pagination filters |
47
+ | `find(id)` | `TelescopeEntry \| null` | Find a single entry by ID |
48
+ | `count(type?)` | `number` | Count entries, optionally filtered by type |
49
+ | `prune(type?)` | `void` | Delete entries, optionally by type |
50
+ | `record(entry)` | `void` | Manually record an entry |
51
+
52
+ ## Entry Types
53
+
54
+ Telescope records 11 entry types:
55
+
56
+ | Type | Collector | Description |
57
+ |------|-----------|-------------|
58
+ | `request` | RequestCollector | HTTP requests and responses |
59
+ | `query` | QueryCollector | Database queries (flags slow queries) |
60
+ | `job` | JobCollector | Queue job dispatch and execution |
61
+ | `exception` | ExceptionCollector | Unhandled exceptions |
62
+ | `log` | LogCollector | Log messages |
63
+ | `mail` | MailCollector | Sent emails |
64
+ | `notification` | NotificationCollector | Dispatched notifications |
65
+ | `event` | EventCollector | Dispatched events |
66
+ | `cache` | CacheCollector | Cache hits, misses, writes |
67
+ | `schedule` | ScheduleCollector | Scheduled task execution |
68
+ | `model` | ModelCollector | Model create/update/delete |
69
+
70
+ ## Storage Drivers
71
+
72
+ - **`memory`** (default) — In-process, bounded by `maxEntries`. Good for development.
73
+ - **`sqlite`** — Persistent storage via `better-sqlite3`. Run `pnpm add better-sqlite3` to enable.
74
+
75
+ ## Configuration
76
+
77
+ ```ts
78
+ // config/telescope.ts
79
+ export default {
80
+ enabled: true,
81
+ path: 'telescope',
82
+ storage: 'memory',
83
+ sqlitePath: '.telescope.db',
84
+ maxEntries: 1000,
85
+ pruneAfterHours: 24,
86
+ recordRequests: true,
87
+ recordQueries: true,
88
+ recordJobs: true,
89
+ recordExceptions: true,
90
+ recordLogs: true,
91
+ recordMail: true,
92
+ recordNotifications: true,
93
+ recordEvents: true,
94
+ recordCache: true,
95
+ recordSchedule: true,
96
+ recordModels: true,
97
+ ignoreRequests: ['/telescope*', '/health'],
98
+ slowQueryThreshold: 100,
99
+ auth: null,
100
+ } satisfies TelescopeConfig
101
+ ```
102
+
103
+ ## Dashboard
104
+
105
+ Telescope serves a built-in UI at `/{path}` with dedicated pages for each entry type, detail views, and a search interface.
106
+
107
+ ## Notes
108
+
109
+ - Auto-prune runs on a background interval.
110
+ - Optional peers: `@rudderjs/log`, `@rudderjs/orm`, `@rudderjs/cache`, `@rudderjs/queue`, `@rudderjs/mail`, `@rudderjs/notification`, `@rudderjs/schedule`.
111
+ - `createEntry()` helper is exported for manually constructing entries.
@@ -0,0 +1,38 @@
1
+ # @rudderjs/telescope — AI Coding Guidelines
2
+
3
+ ## What This Package Does
4
+
5
+ Telescope is a development inspector for RudderJS applications. It records requests, queries, jobs, exceptions, logs, mail, notifications, events, cache operations, scheduled tasks, and model changes — providing a JSON API and (future) UI for introspection.
6
+
7
+ ## Architecture
8
+
9
+ Three layers:
10
+ 1. **Collectors** — Middleware, event listeners, and hooks that passively record app activity
11
+ 2. **Storage** — In-memory (default) or SQLite backend for entry persistence
12
+ 3. **API** — RESTful JSON endpoints at `/{path}/api/*`
13
+
14
+ ## Key Patterns
15
+
16
+ - Each collector implements the `Collector` interface with `register()` method
17
+ - Collectors hook into framework subsystems via dynamic imports (graceful skip if not installed)
18
+ - All entries share the `TelescopeEntry` shape with `type`, `content` (JSON), and `tags`
19
+ - Related entries within a request share a `batchId` for correlation
20
+ - Storage is accessed via `TelescopeRegistry.get()` or the `Telescope` facade
21
+
22
+ ## Common Tasks
23
+
24
+ ### Adding a new collector
25
+ 1. Create `src/collectors/my-collector.ts` implementing `Collector`
26
+ 2. Use dynamic `import()` to hook into the relevant package
27
+ 3. Store entries via `storage.store(createEntry(type, content, options))`
28
+ 4. Register in `src/index.ts` provider boot
29
+
30
+ ### Extending the API
31
+ 1. Add route in `src/api/routes.ts` using `router.get/post/delete()`
32
+ 2. Follow existing pattern: parse query params, call storage, return JSON
33
+
34
+ ## Do NOT
35
+
36
+ - Import peer dependencies statically — always use dynamic `import()` with try/catch
37
+ - Record Telescope's own API requests (the request collector ignores `/telescope*`)
38
+ - Block the request pipeline — storage writes are fire-and-forget
@@ -0,0 +1,7 @@
1
+ import type { TelescopeStorage, TelescopeConfig } from '../types.js';
2
+ /**
3
+ * Register all Telescope API routes on the router.
4
+ * Called during the service provider's boot phase.
5
+ */
6
+ export declare function registerRoutes(storage: TelescopeStorage, config: TelescopeConfig): Promise<void>;
7
+ //# sourceMappingURL=routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/api/routes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAa,MAAM,aAAa,CAAA;AAW/E;;;GAGG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAG,eAAe,GACvB,OAAO,CAAC,IAAI,CAAC,CA0Df"}
@@ -0,0 +1,99 @@
1
+ import { dashboardPage, requestsPage, queriesPage, jobsPage, exceptionsPage, logsPage, mailPage, notificationsPage, eventsPage, cachePage, schedulePage, modelsPage, } from '../ui/pages.js';
2
+ const ENTRY_TYPES = [
3
+ 'request', 'query', 'job', 'exception', 'log',
4
+ 'mail', 'notification', 'event', 'cache', 'schedule', 'model',
5
+ ];
6
+ /**
7
+ * Register all Telescope API routes on the router.
8
+ * Called during the service provider's boot phase.
9
+ */
10
+ export async function registerRoutes(storage, config) {
11
+ const { router } = await import('@rudderjs/router');
12
+ const basePath = `/${config.path ?? 'telescope'}`;
13
+ const prefix = `${basePath}/api`;
14
+ const middleware = config.auth ? [authMiddleware(config)] : [];
15
+ // ── UI Pages ─────────────────────────────────────────────
16
+ const html = (_req, res, content) => res.header('Content-Type', 'text/html').send(content);
17
+ router.get(basePath, (r, s) => html(r, s, dashboardPage(basePath, prefix)), middleware);
18
+ router.get(`${basePath}/requests`, (r, s) => html(r, s, requestsPage(basePath, prefix)), middleware);
19
+ router.get(`${basePath}/queries`, (r, s) => html(r, s, queriesPage(basePath, prefix)), middleware);
20
+ router.get(`${basePath}/jobs`, (r, s) => html(r, s, jobsPage(basePath, prefix)), middleware);
21
+ router.get(`${basePath}/exceptions`, (r, s) => html(r, s, exceptionsPage(basePath, prefix)), middleware);
22
+ router.get(`${basePath}/logs`, (r, s) => html(r, s, logsPage(basePath, prefix)), middleware);
23
+ router.get(`${basePath}/mail`, (r, s) => html(r, s, mailPage(basePath, prefix)), middleware);
24
+ router.get(`${basePath}/notifications`, (r, s) => html(r, s, notificationsPage(basePath, prefix)), middleware);
25
+ router.get(`${basePath}/events`, (r, s) => html(r, s, eventsPage(basePath, prefix)), middleware);
26
+ router.get(`${basePath}/cache`, (r, s) => html(r, s, cachePage(basePath, prefix)), middleware);
27
+ router.get(`${basePath}/schedule`, (r, s) => html(r, s, schedulePage(basePath, prefix)), middleware);
28
+ router.get(`${basePath}/models`, (r, s) => html(r, s, modelsPage(basePath, prefix)), middleware);
29
+ // ── List routes for each entry type ──────────────────────
30
+ for (const type of ENTRY_TYPES) {
31
+ router.get(`${prefix}/${type === 'query' ? 'queries' : `${type}s`}`, (req, res) => listEntries(storage, type, req, res), middleware);
32
+ router.get(`${prefix}/${type === 'query' ? 'queries' : `${type}s`}/:id`, (req, res) => showEntry(storage, req, res), middleware);
33
+ }
34
+ // ── Overview ─────────────────────────────────────────────
35
+ router.get(`${prefix}/overview`, async (_req, res) => {
36
+ const counts = {};
37
+ for (const type of ENTRY_TYPES) {
38
+ counts[type] = await storage.count(type);
39
+ }
40
+ res.json({ counts, total: await storage.count() });
41
+ }, middleware);
42
+ // ── Prune ────────────────────────────────────────────────
43
+ router.delete(`${prefix}/entries`, async (req, res) => {
44
+ const type = req.query['type'];
45
+ if (type && ENTRY_TYPES.includes(type)) {
46
+ await storage.prune(type);
47
+ }
48
+ else {
49
+ await storage.prune();
50
+ }
51
+ res.json({ message: 'Entries pruned.' });
52
+ }, middleware);
53
+ }
54
+ // ─── Handlers ──────────────────────────────────────────────
55
+ async function listEntries(storage, type, req, res) {
56
+ const page = parseInt(req.query['page'] ?? '1', 10);
57
+ const perPage = parseInt(req.query['per_page'] ?? '50', 10);
58
+ const tag = req.query['tag'];
59
+ const search = req.query['search'];
60
+ const batchId = req.query['batch_id'];
61
+ const entries = await storage.list({ type, page, perPage, tag, search, batchId });
62
+ const total = await storage.count(type);
63
+ res.json({
64
+ data: entries,
65
+ meta: {
66
+ total,
67
+ page,
68
+ per_page: perPage,
69
+ last_page: Math.ceil(total / perPage),
70
+ },
71
+ });
72
+ }
73
+ async function showEntry(storage, req, res) {
74
+ const entry = await storage.find(req.params['id'] ?? '');
75
+ if (!entry) {
76
+ res.status(404).json({ message: 'Entry not found.' });
77
+ return;
78
+ }
79
+ // If this entry has a batchId, include related entries
80
+ let related = [];
81
+ if (entry.batchId) {
82
+ related = await storage.list({ batchId: entry.batchId, perPage: 100 });
83
+ }
84
+ res.json({ data: entry, related });
85
+ }
86
+ // ─── Auth Middleware ────────────────────────────────────────
87
+ function authMiddleware(config) {
88
+ return async (req, res, next) => {
89
+ if (config.auth) {
90
+ const allowed = await config.auth(req);
91
+ if (!allowed) {
92
+ res.status(403).json({ message: 'Unauthorized.' });
93
+ return;
94
+ }
95
+ }
96
+ return next();
97
+ };
98
+ }
99
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/api/routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { Collector, TelescopeStorage } from '../types.js';
2
+ /**
3
+ * Records cache operations by wrapping the CacheRegistry adapter methods.
4
+ * Intercepts get/set/forget/flush and records hit/miss/set/forget ops.
5
+ */
6
+ export declare class CacheCollector implements Collector {
7
+ private readonly storage;
8
+ readonly name = "Cache Collector";
9
+ readonly type: "cache";
10
+ constructor(storage: TelescopeStorage);
11
+ register(): Promise<void>;
12
+ }
13
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/collectors/cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAG9D;;;GAGG;AACH,qBAAa,cAAe,YAAW,SAAS;IAIlC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC,QAAQ,CAAC,IAAI,qBAAoB;IACjC,QAAQ,CAAC,IAAI,EAAG,OAAO,CAAS;gBAEH,OAAO,EAAE,gBAAgB;IAEhD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAsChC"}
@@ -0,0 +1,48 @@
1
+ import { createEntry } from '../storage.js';
2
+ /**
3
+ * Records cache operations by wrapping the CacheRegistry adapter methods.
4
+ * Intercepts get/set/forget/flush and records hit/miss/set/forget ops.
5
+ */
6
+ export class CacheCollector {
7
+ storage;
8
+ name = 'Cache Collector';
9
+ type = 'cache';
10
+ constructor(storage) {
11
+ this.storage = storage;
12
+ }
13
+ async register() {
14
+ try {
15
+ const { CacheRegistry } = await import('@rudderjs/cache');
16
+ const original = CacheRegistry.get();
17
+ if (!original)
18
+ return;
19
+ const storage = this.storage;
20
+ const origGet = original.get.bind(original);
21
+ const origSet = original.set.bind(original);
22
+ const origForget = original.forget.bind(original);
23
+ const origFlush = original.flush.bind(original);
24
+ original.get = async (key) => {
25
+ const value = await origGet(key);
26
+ const op = value !== null ? 'hit' : 'miss';
27
+ storage.store(createEntry('cache', { key, operation: op }, { tags: [`cache:${op}`] }));
28
+ return value;
29
+ };
30
+ original.set = async (key, value, ttl) => {
31
+ await origSet(key, value, ttl);
32
+ storage.store(createEntry('cache', { key, operation: 'set', ttl }, { tags: ['cache:set'] }));
33
+ };
34
+ original.forget = async (key) => {
35
+ await origForget(key);
36
+ storage.store(createEntry('cache', { key, operation: 'forget' }, { tags: ['cache:forget'] }));
37
+ };
38
+ original.flush = async () => {
39
+ await origFlush();
40
+ storage.store(createEntry('cache', { operation: 'flush' }, { tags: ['cache:flush'] }));
41
+ };
42
+ }
43
+ catch {
44
+ // @rudderjs/cache not installed — skip
45
+ }
46
+ }
47
+ }
48
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/collectors/cache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAE3C;;;GAGG;AACH,MAAM,OAAO,cAAc;IAII;IAHpB,IAAI,GAAG,iBAAiB,CAAA;IACxB,IAAI,GAAG,OAAgB,CAAA;IAEhC,YAA6B,OAAyB;QAAzB,YAAO,GAAP,OAAO,CAAkB;IAAG,CAAC;IAE1D,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC;YACH,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAA;YACzD,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,EAAE,CAAA;YACpC,IAAI,CAAC,QAAQ;gBAAE,OAAM;YAErB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;YAE5B,MAAM,OAAO,GAAM,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YAC9C,MAAM,OAAO,GAAM,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YAC9C,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YACjD,MAAM,SAAS,GAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YAEhD,QAAQ,CAAC,GAAG,GAAG,KAAK,EAAe,GAAW,EAAqB,EAAE;gBACnE,MAAM,KAAK,GAAG,MAAO,OAA8C,CAAC,GAAG,CAAC,CAAA;gBACxE,MAAM,EAAE,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAA;gBAC1C,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;gBACtF,OAAO,KAAK,CAAA;YACd,CAAC,CAAA;YAED,QAAQ,CAAC,GAAG,GAAG,KAAK,EAAE,GAAW,EAAE,KAAc,EAAE,GAAY,EAAiB,EAAE;gBAChF,MAAO,OAAwE,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,CAAA;gBAChG,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAA;YAC9F,CAAC,CAAA;YAED,QAAQ,CAAC,MAAM,GAAG,KAAK,EAAE,GAAW,EAAiB,EAAE;gBACrD,MAAO,UAA6C,CAAC,GAAG,CAAC,CAAA;gBACzD,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAA;YAC/F,CAAC,CAAA;YAED,QAAQ,CAAC,KAAK,GAAG,KAAK,IAAmB,EAAE;gBACzC,MAAO,SAAiC,EAAE,CAAA;gBAC1C,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAA;YACxF,CAAC,CAAA;QACH,CAAC;QAAC,MAAM,CAAC;YACP,uCAAuC;QACzC,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ import type { Collector, TelescopeStorage } from '../types.js';
2
+ /**
3
+ * Records dispatched events by registering a wildcard ('*') listener.
4
+ */
5
+ export declare class EventCollector implements Collector {
6
+ private readonly storage;
7
+ readonly name = "Event Collector";
8
+ readonly type: "event";
9
+ constructor(storage: TelescopeStorage);
10
+ register(): Promise<void>;
11
+ private record;
12
+ }
13
+ //# sourceMappingURL=event.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../src/collectors/event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAG9D;;GAEG;AACH,qBAAa,cAAe,YAAW,SAAS;IAIlC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC,QAAQ,CAAC,IAAI,qBAAoB;IACjC,QAAQ,CAAC,IAAI,EAAG,OAAO,CAAS;gBAEH,OAAO,EAAE,gBAAgB;IAEhD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB/B,OAAO,CAAC,MAAM;CAaf"}
@@ -0,0 +1,36 @@
1
+ import { createEntry } from '../storage.js';
2
+ /**
3
+ * Records dispatched events by registering a wildcard ('*') listener.
4
+ */
5
+ export class EventCollector {
6
+ storage;
7
+ name = 'Event Collector';
8
+ type = 'event';
9
+ constructor(storage) {
10
+ this.storage = storage;
11
+ }
12
+ async register() {
13
+ try {
14
+ const { dispatcher } = await import('@rudderjs/core');
15
+ dispatcher.register('*', {
16
+ handle: (event) => this.record(event),
17
+ });
18
+ }
19
+ catch {
20
+ // @rudderjs/core events not available — skip
21
+ }
22
+ }
23
+ record(event) {
24
+ const name = event && typeof event === 'object' ? event.constructor.name : 'Unknown';
25
+ // Don't record Telescope's own internal events
26
+ if (name.startsWith('Telescope'))
27
+ return;
28
+ this.storage.store(createEntry('event', {
29
+ name,
30
+ payload: event && typeof event === 'object'
31
+ ? JSON.parse(JSON.stringify(event))
32
+ : { value: event },
33
+ }, { tags: [`event:${name}`] }));
34
+ }
35
+ }
36
+ //# sourceMappingURL=event.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event.js","sourceRoot":"","sources":["../../src/collectors/event.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAE3C;;GAEG;AACH,MAAM,OAAO,cAAc;IAII;IAHpB,IAAI,GAAG,iBAAiB,CAAA;IACxB,IAAI,GAAG,OAAgB,CAAA;IAEhC,YAA6B,OAAyB;QAAzB,YAAO,GAAP,OAAO,CAAkB;IAAG,CAAC;IAE1D,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC;YACH,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAInD,CAAA;YAED,UAAU,CAAC,QAAQ,CAAC,GAAG,EAAE;gBACvB,MAAM,EAAE,CAAC,KAAc,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;aAC/C,CAAC,CAAA;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,6CAA6C;QAC/C,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,KAAc;QAC3B,MAAM,IAAI,GAAG,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;QAEpF,+CAA+C;QAC/C,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;YAAE,OAAM;QAExC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE;YACtC,IAAI;YACJ,OAAO,EAAE,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;gBACzC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;gBACnC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE;SACrB,EAAE,EAAE,IAAI,EAAE,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IAClC,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ import type { Collector, TelescopeStorage } from '../types.js';
2
+ /**
3
+ * Records exceptions by wrapping the global exception reporter.
4
+ */
5
+ export declare class ExceptionCollector implements Collector {
6
+ private readonly storage;
7
+ readonly name = "Exception Collector";
8
+ readonly type: "exception";
9
+ constructor(storage: TelescopeStorage);
10
+ register(): Promise<void>;
11
+ private record;
12
+ }
13
+ //# sourceMappingURL=exception.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exception.d.ts","sourceRoot":"","sources":["../../src/collectors/exception.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAG9D;;GAEG;AACH,qBAAa,kBAAmB,YAAW,SAAS;IAItC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC,QAAQ,CAAC,IAAI,yBAAwB;IACrC,QAAQ,CAAC,IAAI,EAAG,WAAW,CAAS;gBAEP,OAAO,EAAE,gBAAgB;IAEhD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB/B,OAAO,CAAC,MAAM;CAWf"}
@@ -0,0 +1,38 @@
1
+ import { createEntry } from '../storage.js';
2
+ /**
3
+ * Records exceptions by wrapping the global exception reporter.
4
+ */
5
+ export class ExceptionCollector {
6
+ storage;
7
+ name = 'Exception Collector';
8
+ type = 'exception';
9
+ constructor(storage) {
10
+ this.storage = storage;
11
+ }
12
+ async register() {
13
+ try {
14
+ const { setExceptionReporter, report } = await import('@rudderjs/core');
15
+ // Chain: record the exception, then forward to the previous reporter
16
+ const previousReport = report;
17
+ setExceptionReporter((err) => {
18
+ this.record(err);
19
+ previousReport(err);
20
+ });
21
+ }
22
+ catch {
23
+ // Should never fail since @rudderjs/core is a direct dep
24
+ }
25
+ }
26
+ record(err) {
27
+ const isError = err instanceof Error;
28
+ const tags = ['error'];
29
+ if (isError)
30
+ tags.push(`class:${err.constructor.name}`);
31
+ this.storage.store(createEntry('exception', {
32
+ class: isError ? err.constructor.name : 'Unknown',
33
+ message: isError ? err.message : String(err),
34
+ stack: isError && err.stack ? err.stack.split('\n').map(l => l.trim()) : [],
35
+ }, { tags, ...(isError ? { familyHash: err.constructor.name } : {}) }));
36
+ }
37
+ }
38
+ //# sourceMappingURL=exception.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exception.js","sourceRoot":"","sources":["../../src/collectors/exception.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAE3C;;GAEG;AACH,MAAM,OAAO,kBAAkB;IAIA;IAHpB,IAAI,GAAG,qBAAqB,CAAA;IAC5B,IAAI,GAAG,WAAoB,CAAA;IAEpC,YAA6B,OAAyB;QAAzB,YAAO,GAAP,OAAO,CAAkB;IAAG,CAAC;IAE1D,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC;YACH,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAGrE,CAAA;YAED,qEAAqE;YACrE,MAAM,cAAc,GAAG,MAAM,CAAA;YAC7B,oBAAoB,CAAC,CAAC,GAAY,EAAE,EAAE;gBACpC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;gBAChB,cAAc,CAAC,GAAG,CAAC,CAAA;YACrB,CAAC,CAAC,CAAA;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,yDAAyD;QAC3D,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,GAAY;QACzB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAA;QACpC,MAAM,IAAI,GAAa,CAAC,OAAO,CAAC,CAAA;QAChC,IAAI,OAAO;YAAE,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAA;QAEvD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,WAAW,EAAE;YAC1C,KAAK,EAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;YACnD,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;YAC5C,KAAK,EAAI,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;SAC9E,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IACzE,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ import type { Collector, TelescopeStorage } from '../types.js';
2
+ /**
3
+ * Records queue job dispatches by wrapping the QueueRegistry adapter's dispatch method.
4
+ */
5
+ export declare class JobCollector implements Collector {
6
+ private readonly storage;
7
+ readonly name = "Job Collector";
8
+ readonly type: "job";
9
+ constructor(storage: TelescopeStorage);
10
+ register(): Promise<void>;
11
+ }
12
+ //# sourceMappingURL=job.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"job.d.ts","sourceRoot":"","sources":["../../src/collectors/job.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAG9D;;GAEG;AACH,qBAAa,YAAa,YAAW,SAAS;IAIhC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC,QAAQ,CAAC,IAAI,mBAAkB;IAC/B,QAAQ,CAAC,IAAI,EAAG,KAAK,CAAS;gBAED,OAAO,EAAE,gBAAgB;IAEhD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAuChC"}
@@ -0,0 +1,53 @@
1
+ import { createEntry } from '../storage.js';
2
+ /**
3
+ * Records queue job dispatches by wrapping the QueueRegistry adapter's dispatch method.
4
+ */
5
+ export class JobCollector {
6
+ storage;
7
+ name = 'Job Collector';
8
+ type = 'job';
9
+ constructor(storage) {
10
+ this.storage = storage;
11
+ }
12
+ async register() {
13
+ try {
14
+ const { QueueRegistry } = await import('@rudderjs/queue');
15
+ const original = QueueRegistry.get();
16
+ if (!original)
17
+ return;
18
+ const storage = this.storage;
19
+ const originalDispatch = original.dispatch.bind(original);
20
+ original.dispatch = async (job, options) => {
21
+ const j = job;
22
+ const ctor = j.constructor;
23
+ const start = Date.now();
24
+ try {
25
+ await originalDispatch(job, options);
26
+ const duration = Date.now() - start;
27
+ storage.store(createEntry('job', {
28
+ class: j.constructor.name,
29
+ queue: ctor['queue'] ?? 'default',
30
+ status: 'dispatched',
31
+ duration,
32
+ payload: JSON.parse(JSON.stringify(job)),
33
+ }, { tags: [`job:${j.constructor.name}`, 'status:dispatched'] }));
34
+ }
35
+ catch (err) {
36
+ const duration = Date.now() - start;
37
+ storage.store(createEntry('job', {
38
+ class: j.constructor.name,
39
+ queue: ctor['queue'] ?? 'default',
40
+ status: 'failed',
41
+ duration,
42
+ exception: err instanceof Error ? err.message : String(err),
43
+ }, { tags: [`job:${j.constructor.name}`, 'status:failed'] }));
44
+ throw err;
45
+ }
46
+ };
47
+ }
48
+ catch {
49
+ // @rudderjs/queue not installed — skip
50
+ }
51
+ }
52
+ }
53
+ //# sourceMappingURL=job.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"job.js","sourceRoot":"","sources":["../../src/collectors/job.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAE3C;;GAEG;AACH,MAAM,OAAO,YAAY;IAIM;IAHpB,IAAI,GAAG,eAAe,CAAA;IACtB,IAAI,GAAG,KAAc,CAAA;IAE9B,YAA6B,OAAyB;QAAzB,YAAO,GAAP,OAAO,CAAkB;IAAG,CAAC;IAE1D,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC;YACH,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAA;YACzD,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,EAAE,CAAA;YACpC,IAAI,CAAC,QAAQ;gBAAE,OAAM;YAErB,MAAM,OAAO,GAAY,IAAI,CAAC,OAAO,CAAA;YACrC,MAAM,gBAAgB,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YAEzD,QAAQ,CAAC,QAAQ,GAAG,KAAK,EAAE,GAAY,EAAE,OAAiB,EAAiB,EAAE;gBAC3E,MAAM,CAAC,GAAM,GAAkE,CAAA;gBAC/E,MAAM,IAAI,GAAG,CAAC,CAAC,WAAiD,CAAA;gBAChE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;gBACxB,IAAI,CAAC;oBACH,MAAO,gBAAuE,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;oBAC5F,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAA;oBACnC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE;wBAC/B,KAAK,EAAK,CAAC,CAAC,WAAW,CAAC,IAAI;wBAC5B,KAAK,EAAK,IAAI,CAAC,OAAO,CAAC,IAAI,SAAS;wBACpC,MAAM,EAAI,YAAY;wBACtB,QAAQ;wBACR,OAAO,EAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;qBAC1C,EAAE,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,mBAAmB,CAAC,EAAE,CAAC,CAAC,CAAA;gBACnE,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAA;oBACnC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE;wBAC/B,KAAK,EAAM,CAAC,CAAC,WAAW,CAAC,IAAI;wBAC7B,KAAK,EAAM,IAAI,CAAC,OAAO,CAAC,IAAI,SAAS;wBACrC,MAAM,EAAK,QAAQ;wBACnB,QAAQ;wBACR,SAAS,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;qBAC5D,EAAE,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,eAAe,CAAC,EAAE,CAAC,CAAC,CAAA;oBAC7D,MAAM,GAAG,CAAA;gBACX,CAAC;YACH,CAAC,CAAA;QACH,CAAC;QAAC,MAAM,CAAC;YACP,uCAAuC;QACzC,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ import type { Collector, TelescopeStorage } from '../types.js';
2
+ /**
3
+ * Records log entries by hooking into @rudderjs/log's listener API.
4
+ */
5
+ export declare class LogCollector implements Collector {
6
+ private readonly storage;
7
+ readonly name = "Log Collector";
8
+ readonly type: "log";
9
+ constructor(storage: TelescopeStorage);
10
+ register(): Promise<void>;
11
+ private record;
12
+ }
13
+ //# sourceMappingURL=log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/collectors/log.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAG9D;;GAEG;AACH,qBAAa,YAAa,YAAW,SAAS;IAIhC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC,QAAQ,CAAC,IAAI,mBAAkB;IAC/B,QAAQ,CAAC,IAAI,EAAG,KAAK,CAAS;gBAED,OAAO,EAAE,gBAAgB;IAEhD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAW/B,OAAO,CAAC,MAAM;CAcf"}
@@ -0,0 +1,35 @@
1
+ import { createEntry } from '../storage.js';
2
+ /**
3
+ * Records log entries by hooking into @rudderjs/log's listener API.
4
+ */
5
+ export class LogCollector {
6
+ storage;
7
+ name = 'Log Collector';
8
+ type = 'log';
9
+ constructor(storage) {
10
+ this.storage = storage;
11
+ }
12
+ async register() {
13
+ try {
14
+ const { Log } = await import('@rudderjs/log');
15
+ Log.listen((entry) => this.record(entry));
16
+ }
17
+ catch {
18
+ // @rudderjs/log not installed — skip
19
+ }
20
+ }
21
+ record(entry) {
22
+ const tags = [`level:${entry.level}`];
23
+ if (['error', 'critical', 'alert', 'emergency'].includes(entry.level)) {
24
+ tags.push('error');
25
+ }
26
+ this.storage.store(createEntry('log', {
27
+ level: entry.level,
28
+ message: entry.message,
29
+ context: entry.context,
30
+ channel: entry.channel,
31
+ timestamp: entry.timestamp.toISOString(),
32
+ }, { tags }));
33
+ }
34
+ }
35
+ //# sourceMappingURL=log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/collectors/log.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAE3C;;GAEG;AACH,MAAM,OAAO,YAAY;IAIM;IAHpB,IAAI,GAAG,eAAe,CAAA;IACtB,IAAI,GAAG,KAAc,CAAA;IAE9B,YAA6B,OAAyB;QAAzB,YAAO,GAAP,OAAO,CAAkB;IAAG,CAAC;IAE1D,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAE3C,CAAA;YACD,GAAG,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;QAC3C,CAAC;QAAC,MAAM,CAAC;YACP,qCAAqC;QACvC,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,KAAe;QAC5B,MAAM,IAAI,GAAa,CAAC,SAAS,KAAK,CAAC,KAAK,EAAE,CAAC,CAAA;QAC/C,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACtE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACpB,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE;YACpC,KAAK,EAAM,KAAK,CAAC,KAAK;YACtB,OAAO,EAAI,KAAK,CAAC,OAAO;YACxB,OAAO,EAAI,KAAK,CAAC,OAAO;YACxB,OAAO,EAAI,KAAK,CAAC,OAAO;YACxB,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,EAAE;SACzC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;IACf,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ import type { Collector, TelescopeStorage } from '../types.js';
2
+ /**
3
+ * Records mail sends by wrapping the MailRegistry adapter's send method.
4
+ */
5
+ export declare class MailCollector implements Collector {
6
+ private readonly storage;
7
+ readonly name = "Mail Collector";
8
+ readonly type: "mail";
9
+ constructor(storage: TelescopeStorage);
10
+ register(): Promise<void>;
11
+ }
12
+ //# sourceMappingURL=mail.d.ts.map