@beignet/devtools 0.0.1 → 0.0.2

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 (60) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +1 -0
  3. package/dist/access.d.ts +20 -0
  4. package/dist/access.d.ts.map +1 -1
  5. package/dist/access.js +11 -0
  6. package/dist/access.js.map +1 -1
  7. package/dist/audit.d.ts +21 -0
  8. package/dist/audit.d.ts.map +1 -1
  9. package/dist/audit.js +6 -0
  10. package/dist/audit.js.map +1 -1
  11. package/dist/events.d.ts +18 -0
  12. package/dist/events.d.ts.map +1 -1
  13. package/dist/events.js +6 -0
  14. package/dist/events.js.map +1 -1
  15. package/dist/instrumentation.d.ts +40 -0
  16. package/dist/instrumentation.d.ts.map +1 -1
  17. package/dist/instrumentation.js +10 -0
  18. package/dist/instrumentation.js.map +1 -1
  19. package/dist/persistence.d.ts +24 -0
  20. package/dist/persistence.d.ts.map +1 -1
  21. package/dist/persistence.js +6 -0
  22. package/dist/persistence.js.map +1 -1
  23. package/dist/provider-instrumentation.d.ts +18 -0
  24. package/dist/provider-instrumentation.d.ts.map +1 -1
  25. package/dist/provider-instrumentation.js +9 -0
  26. package/dist/provider-instrumentation.js.map +1 -1
  27. package/dist/provider.d.ts +42 -0
  28. package/dist/provider.d.ts.map +1 -1
  29. package/dist/provider.js +3 -0
  30. package/dist/provider.js.map +1 -1
  31. package/dist/redaction.d.ts +9 -0
  32. package/dist/redaction.d.ts.map +1 -1
  33. package/dist/redaction.js +9 -0
  34. package/dist/redaction.js.map +1 -1
  35. package/dist/routes.d.ts +12 -0
  36. package/dist/routes.d.ts.map +1 -1
  37. package/dist/routes.js.map +1 -1
  38. package/dist/trace-context.d.ts +51 -0
  39. package/dist/trace-context.d.ts.map +1 -1
  40. package/dist/trace-context.js +18 -0
  41. package/dist/trace-context.js.map +1 -1
  42. package/dist/ui.js +7 -2
  43. package/dist/ui.js.map +1 -1
  44. package/dist/watchers.d.ts +43 -1
  45. package/dist/watchers.d.ts.map +1 -1
  46. package/dist/watchers.js +20 -0
  47. package/dist/watchers.js.map +1 -1
  48. package/package.json +1 -1
  49. package/src/access.ts +20 -0
  50. package/src/audit.ts +21 -0
  51. package/src/events.ts +18 -0
  52. package/src/instrumentation.ts +40 -0
  53. package/src/persistence.ts +24 -0
  54. package/src/provider-instrumentation.ts +20 -0
  55. package/src/provider.ts +42 -0
  56. package/src/redaction.ts +9 -0
  57. package/src/routes.ts +12 -0
  58. package/src/trace-context.ts +51 -0
  59. package/src/ui.ts +7 -2
  60. package/src/watchers.ts +50 -0
package/src/events.ts CHANGED
@@ -156,14 +156,23 @@ export type DevtoolsEvent =
156
156
  | ProviderEvent
157
157
  | CustomDevtoolsEvent;
158
158
 
159
+ /**
160
+ * Input accepted by `createDevtoolsEvent(...)`.
161
+ */
159
162
  export type DevtoolsEventInput = DevtoolsEvent extends infer Event
160
163
  ? Event extends DevtoolsEvent
161
164
  ? Omit<Event, "id" | "timestamp"> & Partial<Pick<Event, "id" | "timestamp">>
162
165
  : never
163
166
  : never;
164
167
 
168
+ /**
169
+ * Function that redacts a normalized devtools event before storage.
170
+ */
165
171
  export type DevtoolsRedactor = (event: DevtoolsEvent) => DevtoolsEvent;
166
172
 
173
+ /**
174
+ * Event emitted to live devtools subscribers.
175
+ */
167
176
  export type DevtoolsSubscriptionEvent =
168
177
  | {
169
178
  type: "record";
@@ -173,8 +182,14 @@ export type DevtoolsSubscriptionEvent =
173
182
  type: "clear";
174
183
  };
175
184
 
185
+ /**
186
+ * Devtools subscription listener.
187
+ */
176
188
  export type DevtoolsListener = (event: DevtoolsSubscriptionEvent) => void;
177
189
 
190
+ /**
191
+ * All built-in devtools event types.
192
+ */
178
193
  export const DEVTOOLS_EVENT_TYPES = [
179
194
  "request",
180
195
  "error",
@@ -186,6 +201,9 @@ export const DEVTOOLS_EVENT_TYPES = [
186
201
  "custom",
187
202
  ] as const satisfies readonly DevtoolsEvent["type"][];
188
203
 
204
+ /**
205
+ * Check whether a string is a built-in devtools event type.
206
+ */
189
207
  export function isDevtoolsEventType(
190
208
  value: string,
191
209
  ): value is DevtoolsEvent["type"] {
@@ -32,6 +32,9 @@ type ContextWithPorts = {
32
32
  };
33
33
  };
34
34
 
35
+ /**
36
+ * Options for server hooks that record request/error events to devtools.
37
+ */
35
38
  export interface DevtoolsHooksOptions<Ctx> {
36
39
  /**
37
40
  * Devtools route prefix. Requests under this path are ignored to avoid
@@ -41,6 +44,9 @@ export interface DevtoolsHooksOptions<Ctx> {
41
44
  */
42
45
  basePath?: string;
43
46
 
47
+ /**
48
+ * Resolve the request ID used for event correlation.
49
+ */
44
50
  getRequestId?: (args: {
45
51
  req: HttpRequestLike;
46
52
  ctx?: Ctx;
@@ -66,6 +72,9 @@ export interface DevtoolsHooksOptions<Ctx> {
66
72
  */
67
73
  traceContextHeader?: string | false;
68
74
 
75
+ /**
76
+ * Resolve a trace context from request/context/response data.
77
+ */
69
78
  getTraceContext?: (args: {
70
79
  req: HttpRequestLike;
71
80
  ctx?: Ctx;
@@ -78,6 +87,9 @@ export interface DevtoolsHooksOptions<Ctx> {
78
87
  */
79
88
  redact?: DevtoolsRedactor;
80
89
 
90
+ /**
91
+ * Decide whether to capture a completed request event.
92
+ */
81
93
  shouldCapture?: (args: {
82
94
  req: HttpRequestLike;
83
95
  ctx?: Ctx;
@@ -87,6 +99,9 @@ export interface DevtoolsHooksOptions<Ctx> {
87
99
  }) => boolean;
88
100
  }
89
101
 
102
+ /**
103
+ * Use-case run event shape consumed by the devtools observer.
104
+ */
90
105
  export interface DevtoolsUseCaseRunEvent<Ctx> {
91
106
  name: string;
92
107
  kind: "command" | "query";
@@ -96,10 +111,25 @@ export interface DevtoolsUseCaseRunEvent<Ctx> {
96
111
  ctx: Ctx;
97
112
  }
98
113
 
114
+ /**
115
+ * Options for `createDevtoolsUseCaseObserver(...)`.
116
+ */
99
117
  export interface DevtoolsUseCaseObserverOptions<Ctx> {
118
+ /**
119
+ * Resolve a devtools port from use-case context.
120
+ */
100
121
  getDevtools?: (ctx: Ctx) => DevtoolsPort | undefined;
122
+ /**
123
+ * Resolve the request ID used for event correlation.
124
+ */
101
125
  getRequestId?: (ctx: Ctx) => string | undefined;
126
+ /**
127
+ * Whether use-case error phases should also emit `error` events.
128
+ */
102
129
  logErrorEvents?: boolean;
130
+ /**
131
+ * Optional redactor applied before events are recorded.
132
+ */
103
133
  redact?: DevtoolsRedactor;
104
134
  }
105
135
 
@@ -175,6 +205,13 @@ function isWatcherEnabled(
175
205
  return devtools.isWatcherEnabled(name);
176
206
  }
177
207
 
208
+ /**
209
+ * Create server hooks that record Beignet request and error activity.
210
+ *
211
+ * Devtools routes under `basePath` are ignored so polling and SSE traffic do not
212
+ * fill the event buffer. Request IDs and trace context are also written to
213
+ * response headers unless disabled.
214
+ */
178
215
  export function createDevtoolsHooks<
179
216
  Ctx,
180
217
  Ports extends PortsWithDevtools = PortsWithDevtools,
@@ -359,6 +396,9 @@ export function createDevtoolsHooks<
359
396
  };
360
397
  }
361
398
 
399
+ /**
400
+ * Create a use-case observer compatible with `createUseCase({ onRun })`.
401
+ */
362
402
  export function createDevtoolsUseCaseObserver<Ctx>(
363
403
  options: DevtoolsUseCaseObserverOptions<Ctx> = {},
364
404
  ): (event: DevtoolsUseCaseRunEvent<Ctx>) => void {
@@ -1,15 +1,33 @@
1
1
  import type { DevtoolsEvent } from "./events";
2
2
 
3
+ /**
4
+ * Persistence interface for devtools event stores.
5
+ */
3
6
  export interface DevtoolsEventStore {
7
+ /**
8
+ * Store name used in diagnostics.
9
+ */
4
10
  name?: string;
11
+ /**
12
+ * Load persisted events at startup.
13
+ */
5
14
  load?(): DevtoolsEvent[] | Promise<DevtoolsEvent[]>;
15
+ /**
16
+ * Append one event. The second argument is the current bounded buffer.
17
+ */
6
18
  append?(
7
19
  event: DevtoolsEvent,
8
20
  events: readonly DevtoolsEvent[],
9
21
  ): void | Promise<void>;
22
+ /**
23
+ * Clear persisted events.
24
+ */
10
25
  clear?(): void | Promise<void>;
11
26
  }
12
27
 
28
+ /**
29
+ * Options for the Node-only file-backed devtools store.
30
+ */
13
31
  export interface FileDevtoolsStoreOptions {
14
32
  /**
15
33
  * JSONL file used for persisted devtools events.
@@ -80,6 +98,12 @@ async function loadNodeModules(): Promise<{
80
98
  return { fs, path };
81
99
  }
82
100
 
101
+ /**
102
+ * Create a JSONL file-backed devtools store.
103
+ *
104
+ * This store lazily imports Node fs/path modules and is intended for Node
105
+ * runtimes. It compacts periodically to keep the persisted file bounded.
106
+ */
83
107
  export function createFileDevtoolsStore(
84
108
  options: FileDevtoolsStoreOptions = {},
85
109
  ): DevtoolsEventStore {
@@ -7,11 +7,25 @@ import {
7
7
  } from "@beignet/core/providers";
8
8
  import type { DevtoolsPort } from "./index";
9
9
 
10
+ /**
11
+ * Provider devtools instrumentation options.
12
+ */
10
13
  export type ProviderDevtoolsOptions = ProviderInstrumentationOptions;
14
+
15
+ /**
16
+ * Custom provider event input accepted by provider devtools instrumentation.
17
+ */
11
18
  export type ProviderCustomDevtoolsEventInput =
12
19
  ProviderCustomInstrumentationEventInput;
20
+
21
+ /**
22
+ * Provider instrumentation object backed by devtools.
23
+ */
13
24
  export type ProviderDevtools = ProviderInstrumentation;
14
25
 
26
+ /**
27
+ * Check whether an unknown value implements the devtools port shape.
28
+ */
15
29
  export function isDevtoolsPort(value: unknown): value is DevtoolsPort {
16
30
  return (
17
31
  isProviderInstrumentationPort(value) &&
@@ -24,6 +38,9 @@ export function isDevtoolsPort(value: unknown): value is DevtoolsPort {
24
38
  );
25
39
  }
26
40
 
41
+ /**
42
+ * Resolve a devtools port from a direct port or `{ devtools }` object.
43
+ */
27
44
  export function resolveDevtoolsPort(target: unknown): DevtoolsPort | undefined {
28
45
  if (isDevtoolsPort(target)) return target;
29
46
 
@@ -39,6 +56,9 @@ export function resolveDevtoolsPort(target: unknown): DevtoolsPort | undefined {
39
56
  return undefined;
40
57
  }
41
58
 
59
+ /**
60
+ * Create provider instrumentation backed by a devtools port when available.
61
+ */
42
62
  export function createProviderDevtools(
43
63
  target: unknown,
44
64
  options: ProviderDevtoolsOptions,
package/src/provider.ts CHANGED
@@ -37,11 +37,29 @@ import {
37
37
  */
38
38
  const MAX_EVENTS = 500;
39
39
 
40
+ /**
41
+ * Options for `createInMemoryDevtools(...)`.
42
+ */
40
43
  export interface InMemoryDevtoolsOptions {
44
+ /**
45
+ * Maximum events kept in memory.
46
+ */
41
47
  maxEvents?: number;
48
+ /**
49
+ * Custom redactor applied after the default devtools redactor.
50
+ */
42
51
  redact?: DevtoolsRedactor;
52
+ /**
53
+ * Watcher configuration.
54
+ */
43
55
  watchers?: DevtoolsWatchersOptions;
56
+ /**
57
+ * Events loaded into the buffer at startup.
58
+ */
44
59
  initialEvents?: readonly DevtoolsEvent[];
60
+ /**
61
+ * Optional persistence store.
62
+ */
45
63
  store?: DevtoolsEventStore;
46
64
  }
47
65
 
@@ -52,6 +70,9 @@ function createEventId(): string {
52
70
  return `${Date.now()}-${Math.random().toString(16).slice(2)}`;
53
71
  }
54
72
 
73
+ /**
74
+ * Normalize a devtools event by filling `id` and `timestamp`.
75
+ */
55
76
  export function createDevtoolsEvent(event: DevtoolsEventInput): DevtoolsEvent {
56
77
  return {
57
78
  ...event,
@@ -247,13 +268,34 @@ const DevtoolsConfigSchema = z.object({
247
268
  PERSIST_PATH: z.string().optional(),
248
269
  });
249
270
 
271
+ /**
272
+ * Devtools provider config loaded from `DEVTOOLS_*` env vars.
273
+ */
250
274
  export type DevtoolsConfig = z.infer<typeof DevtoolsConfigSchema>;
251
275
 
276
+ /**
277
+ * Options for `createDevtoolsProvider(...)`.
278
+ */
252
279
  export interface DevtoolsProviderOptions {
280
+ /**
281
+ * Whether devtools are enabled. Defaults to non-production.
282
+ */
253
283
  enabled?: boolean;
284
+ /**
285
+ * Maximum events kept in memory.
286
+ */
254
287
  maxEvents?: number;
288
+ /**
289
+ * Custom redactor applied after the default redactor.
290
+ */
255
291
  redact?: DevtoolsRedactor;
292
+ /**
293
+ * Watcher configuration.
294
+ */
256
295
  watchers?: DevtoolsWatchersOptions;
296
+ /**
297
+ * Optional persistence store or async store factory.
298
+ */
257
299
  store?:
258
300
  | DevtoolsEventStore
259
301
  | (() => DevtoolsEventStore | Promise<DevtoolsEventStore>);
package/src/redaction.ts CHANGED
@@ -1,9 +1,15 @@
1
1
  import { redactValue } from "@beignet/core/ports";
2
2
  import type { DevtoolsEvent, DevtoolsRedactor } from "./events";
3
3
 
4
+ /**
5
+ * Default devtools event redactor.
6
+ */
4
7
  export const defaultDevtoolsRedactor: DevtoolsRedactor = (event) =>
5
8
  redactValue(event);
6
9
 
10
+ /**
11
+ * Apply default redaction and then an optional custom redactor.
12
+ */
7
13
  export function applyDevtoolsRedaction(
8
14
  event: DevtoolsEvent,
9
15
  redact?: DevtoolsRedactor,
@@ -13,6 +19,9 @@ export function applyDevtoolsRedaction(
13
19
  return redact(redacted);
14
20
  }
15
21
 
22
+ /**
23
+ * Create a devtools error event when redaction fails.
24
+ */
16
25
  export function createRedactionFailureEvent(error: unknown): DevtoolsEvent {
17
26
  return {
18
27
  id: `${Date.now()}-${Math.random().toString(16).slice(2)}`,
package/src/routes.ts CHANGED
@@ -13,6 +13,9 @@ import { isDevtoolsEventType } from "./events";
13
13
  import type { DevtoolsFilter, DevtoolsPort } from "./index";
14
14
  import { handleDevtoolsUIRequest } from "./ui";
15
15
 
16
+ /**
17
+ * Devtools route options shared by route handlers.
18
+ */
16
19
  export interface DevtoolsRequestOptions extends DevtoolsRouteAccessOptions {
17
20
  /**
18
21
  * URL path prefix where devtools routes are mounted.
@@ -22,8 +25,17 @@ export interface DevtoolsRequestOptions extends DevtoolsRouteAccessOptions {
22
25
  basePath: string;
23
26
  }
24
27
 
28
+ /**
29
+ * GET/POST route handlers returned by `createDevtoolsRoute(...)`.
30
+ */
25
31
  export interface DevtoolsRouteHandlers {
32
+ /**
33
+ * Handle devtools GET requests.
34
+ */
26
35
  GET(req: Request): Promise<Response>;
36
+ /**
37
+ * Handle devtools POST requests.
38
+ */
27
39
  POST(req: Request): Promise<Response>;
28
40
  }
29
41
 
@@ -1,19 +1,52 @@
1
1
  const TRACEPARENT_PATTERN = /^00-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/;
2
2
 
3
+ /**
4
+ * Devtools trace context used to correlate related events.
5
+ */
3
6
  export interface DevtoolsTraceContext {
7
+ /**
8
+ * W3C trace ID.
9
+ */
4
10
  traceId: string;
11
+ /**
12
+ * Current span ID.
13
+ */
5
14
  spanId: string;
15
+ /**
16
+ * Parent span ID when available.
17
+ */
6
18
  parentSpanId?: string;
19
+ /**
20
+ * W3C traceparent header value.
21
+ */
7
22
  traceparent: string;
8
23
  }
9
24
 
25
+ /**
26
+ * Parsed W3C traceparent header.
27
+ */
10
28
  export interface ParsedTraceparent {
29
+ /**
30
+ * W3C trace ID.
31
+ */
11
32
  traceId: string;
33
+ /**
34
+ * Span ID from the traceparent header.
35
+ */
12
36
  spanId: string;
37
+ /**
38
+ * Trace flags from the traceparent header.
39
+ */
13
40
  traceFlags: string;
41
+ /**
42
+ * Normalized traceparent header value.
43
+ */
14
44
  traceparent: string;
15
45
  }
16
46
 
47
+ /**
48
+ * Input accepted when creating devtools trace context.
49
+ */
17
50
  export interface DevtoolsTraceContextInput {
18
51
  traceId?: string;
19
52
  spanId?: string;
@@ -41,6 +74,9 @@ function isNonZeroHex(value: string): boolean {
41
74
  return !/^0+$/.test(value);
42
75
  }
43
76
 
77
+ /**
78
+ * Create a non-zero W3C trace ID.
79
+ */
44
80
  export function createTraceId(): string {
45
81
  let traceId = createHexId(32);
46
82
  while (!isNonZeroHex(traceId)) {
@@ -49,6 +85,9 @@ export function createTraceId(): string {
49
85
  return traceId;
50
86
  }
51
87
 
88
+ /**
89
+ * Create a non-zero W3C span ID.
90
+ */
52
91
  export function createSpanId(): string {
53
92
  let spanId = createHexId(16);
54
93
  while (!isNonZeroHex(spanId)) {
@@ -57,6 +96,9 @@ export function createSpanId(): string {
57
96
  return spanId;
58
97
  }
59
98
 
99
+ /**
100
+ * Create a W3C traceparent header value.
101
+ */
60
102
  export function createTraceparent(args: {
61
103
  traceId: string;
62
104
  spanId: string;
@@ -65,6 +107,9 @@ export function createTraceparent(args: {
65
107
  return `00-${args.traceId}-${args.spanId}-${args.traceFlags ?? "01"}`;
66
108
  }
67
109
 
110
+ /**
111
+ * Parse and validate a W3C traceparent header value.
112
+ */
68
113
  export function parseTraceparent(
69
114
  value: string | null | undefined,
70
115
  ): ParsedTraceparent | undefined {
@@ -84,6 +129,9 @@ export function parseTraceparent(
84
129
  };
85
130
  }
86
131
 
132
+ /**
133
+ * Create devtools trace context from explicit IDs or an existing traceparent.
134
+ */
87
135
  export function createDevtoolsTraceContext(
88
136
  input: DevtoolsTraceContextInput = {},
89
137
  ): DevtoolsTraceContext {
@@ -104,6 +152,9 @@ export function createDevtoolsTraceContext(
104
152
  };
105
153
  }
106
154
 
155
+ /**
156
+ * Create child trace context from a parent context.
157
+ */
107
158
  export function createChildDevtoolsTraceContext(
108
159
  parent: DevtoolsTraceContextInput,
109
160
  ): DevtoolsTraceContext {
package/src/ui.ts CHANGED
@@ -132,6 +132,7 @@ button.danger:hover{border-color:rgba(225,29,72,.24);background:#fff1f2}
132
132
  .badge-cache{background:#f7fee7;color:#4d7c0f;border-color:#d9f99d}
133
133
  .badge-db{background:#ecfeff;color:#0e7490;border-color:#cffafe}
134
134
  .badge-mail{background:#fdf2f8;color:#be185d;border-color:#fbcfe8}
135
+ .badge-notifications{background:#f5f3ff;color:#6d28d9;border-color:#ddd6fe}
135
136
  .badge-rateLimit{background:#fffbeb;color:#b45309;border-color:#fde68a}
136
137
  .badge-storage{background:#f0fdf4;color:#15803d;border-color:#bbf7d0}
137
138
  .request-id{font-family:var(--font-mono);font-size:10px;color:var(--text-muted);padding:2px 5px;background:var(--surface-2);border:1px solid var(--border);border-radius:4px}
@@ -222,13 +223,14 @@ button.danger:hover{border-color:rgba(225,29,72,.24);background:#fff1f2}
222
223
  {id:"cache",label:"Cache",type:"custom",watcher:"cache",watcherName:"cache"},
223
224
  {id:"storage",label:"Storage",type:"custom",watcher:"storage",watcherName:"storage"},
224
225
  {id:"mail",label:"Mail",type:"custom",watcher:"mail",watcherName:"mail"},
226
+ {id:"notifications",label:"Notifications",type:"custom",watcher:"notifications",watcherName:"notifications"},
225
227
  {id:"auth",label:"Auth",type:"custom",watcher:"auth",watcherName:"auth"},
226
228
  {id:"audit",label:"Audit",type:"custom",watcher:"audit",watcherName:"audit"},
227
229
  {id:"rateLimit",label:"Rate limits",type:"custom",watcher:"rateLimit",watcherName:"rateLimit"},
228
230
  {id:"custom",label:"Custom",type:"custom",watcher:"custom"}
229
231
  ];
230
- const FOCUS_PANEL_TABS={events:true,jobs:true,schedules:true,db:true,cache:true,storage:true,mail:true,auth:true,audit:true,rateLimit:true};
231
- const BUILT_IN_WATCHERS={requests:true,errors:true,useCases:true,eventBus:true,jobs:true,schedules:true,providers:true,db:true,cache:true,storage:true,mail:true,auth:true,audit:true,rateLimit:true,custom:true};
232
+ const FOCUS_PANEL_TABS={events:true,jobs:true,schedules:true,db:true,cache:true,storage:true,mail:true,notifications:true,auth:true,audit:true,rateLimit:true};
233
+ const BUILT_IN_WATCHERS={requests:true,errors:true,useCases:true,eventBus:true,jobs:true,schedules:true,providers:true,db:true,cache:true,storage:true,mail:true,notifications:true,auth:true,audit:true,rateLimit:true,custom:true};
232
234
  let events=[];
233
235
  let watchers=[];
234
236
  let activeTab=localStorage.getItem("beignet-devtools-tab")||"timeline";
@@ -331,6 +333,7 @@ button.danger:hover{border-color:rgba(225,29,72,.24);background:#fff1f2}
331
333
  case "cache": return "cache";
332
334
  case "db": return "database";
333
335
  case "mail": return "mail";
336
+ case "notifications": return "notifications";
334
337
  case "rateLimit": return "rate limit";
335
338
  case "storage": return "storage";
336
339
  default: return "custom";
@@ -347,6 +350,7 @@ button.danger:hover{border-color:rgba(225,29,72,.24);background:#fff1f2}
347
350
  case "cache": return "cache";
348
351
  case "db": return "db";
349
352
  case "mail": return "mail";
353
+ case "notifications": return "notifications";
350
354
  case "rateLimit": return "rateLimit";
351
355
  case "storage": return "storage";
352
356
  default: return "custom";
@@ -565,6 +569,7 @@ button.danger:hover{border-color:rgba(225,29,72,.24);background:#fff1f2}
565
569
  case "cache": return {title:"Cache",subtitle:"Reads, writes, deletes, and hit rates"};
566
570
  case "storage": return {title:"Storage",subtitle:"Object storage operations"};
567
571
  case "mail": return {title:"Mail",subtitle:"Delivery attempts and provider results"};
572
+ case "notifications": return {title:"Notifications",subtitle:"Notification intent and channel delivery"};
568
573
  case "auth": return {title:"Auth",subtitle:"Session and authentication activity"};
569
574
  case "audit": return {title:"Audit",subtitle:"Durable activity records emitted by application code"};
570
575
  case "rateLimit": return {title:"Rate limits",subtitle:"Allowed, blocked, and failed checks"};
package/src/watchers.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  import type { DevtoolsEvent } from "./events";
2
2
 
3
+ /**
4
+ * Built-in devtools watcher names.
5
+ */
3
6
  export const BUILT_IN_DEVTOOLS_WATCHER_NAMES = [
4
7
  "requests",
5
8
  "errors",
@@ -12,25 +15,53 @@ export const BUILT_IN_DEVTOOLS_WATCHER_NAMES = [
12
15
  "cache",
13
16
  "storage",
14
17
  "mail",
18
+ "notifications",
15
19
  "auth",
16
20
  "audit",
17
21
  "rateLimit",
18
22
  "custom",
19
23
  ] as const;
20
24
 
25
+ /**
26
+ * Name of a built-in devtools watcher.
27
+ */
21
28
  export type BuiltInDevtoolsWatcherName =
22
29
  (typeof BUILT_IN_DEVTOOLS_WATCHER_NAMES)[number];
23
30
 
31
+ /**
32
+ * Name of a built-in or app-defined devtools watcher.
33
+ */
24
34
  export type DevtoolsWatcherName = BuiltInDevtoolsWatcherName | (string & {});
25
35
 
36
+ /**
37
+ * Resolved devtools watcher configuration.
38
+ */
26
39
  export interface DevtoolsWatcher {
40
+ /**
41
+ * Watcher name.
42
+ */
27
43
  name: DevtoolsWatcherName;
44
+ /**
45
+ * Display label.
46
+ */
28
47
  label: string;
48
+ /**
49
+ * Display description.
50
+ */
29
51
  description?: string;
52
+ /**
53
+ * Event types this watcher owns.
54
+ */
30
55
  eventTypes: readonly DevtoolsEvent["type"][];
56
+ /**
57
+ * Whether events owned by this watcher should be stored.
58
+ */
31
59
  enabled: boolean;
32
60
  }
33
61
 
62
+ /**
63
+ * User-provided watcher override.
64
+ */
34
65
  export type DevtoolsWatcherOptions =
35
66
  | boolean
36
67
  | {
@@ -40,6 +71,9 @@ export type DevtoolsWatcherOptions =
40
71
  eventTypes?: readonly DevtoolsEvent["type"][];
41
72
  };
42
73
 
74
+ /**
75
+ * Watcher overrides keyed by built-in or custom watcher name.
76
+ */
43
77
  export type DevtoolsWatchersOptions = Partial<
44
78
  Record<BuiltInDevtoolsWatcherName, DevtoolsWatcherOptions>
45
79
  > &
@@ -124,6 +158,13 @@ const BUILT_IN_DEVTOOLS_WATCHERS = {
124
158
  eventTypes: ["custom"],
125
159
  enabled: true,
126
160
  },
161
+ notifications: {
162
+ name: "notifications",
163
+ label: "Notifications",
164
+ description: "Application notification intent and channel delivery.",
165
+ eventTypes: ["custom"],
166
+ enabled: true,
167
+ },
127
168
  auth: {
128
169
  name: "auth",
129
170
  label: "Auth",
@@ -184,6 +225,9 @@ function normalizeWatcherOptions(
184
225
  };
185
226
  }
186
227
 
228
+ /**
229
+ * Resolve built-in and custom watcher configuration.
230
+ */
187
231
  export function resolveDevtoolsWatchers(
188
232
  options: DevtoolsWatchersOptions = {},
189
233
  ): DevtoolsWatcher[] {
@@ -211,6 +255,9 @@ export function resolveDevtoolsWatchers(
211
255
  return watchers;
212
256
  }
213
257
 
258
+ /**
259
+ * Check whether a watcher is enabled.
260
+ */
214
261
  export function isDevtoolsWatcherEnabled(
215
262
  watchers: readonly DevtoolsWatcher[],
216
263
  name: DevtoolsWatcherName,
@@ -218,6 +265,9 @@ export function isDevtoolsWatcherEnabled(
218
265
  return watchers.find((watcher) => watcher.name === name)?.enabled ?? true;
219
266
  }
220
267
 
268
+ /**
269
+ * Check whether an event should be stored for a watcher configuration.
270
+ */
221
271
  export function isDevtoolsEventEnabled(
222
272
  watchers: readonly DevtoolsWatcher[],
223
273
  event: DevtoolsEvent,