@beignet/devtools 0.0.1 → 0.0.3

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 +31 -0
  2. package/README.md +2 -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 +19 -1
  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 +12 -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 +28 -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 +25 -1
  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 +12 -2
  60. package/src/watchers.ts +58 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beignet/devtools",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "type": "module",
5
5
  "description": "Development-time devtools for Beignet - mini Telescope for the server runtime",
6
6
  "main": "./dist/index.js",
package/src/access.ts CHANGED
@@ -1,9 +1,18 @@
1
+ /**
2
+ * Result returned by a devtools authorization check.
3
+ */
1
4
  export type DevtoolsAuthorizeResult = boolean | Response;
2
5
 
6
+ /**
7
+ * App-owned authorization callback for devtools routes.
8
+ */
3
9
  export type DevtoolsAuthorize = (
4
10
  req: Request,
5
11
  ) => DevtoolsAuthorizeResult | Promise<DevtoolsAuthorizeResult>;
6
12
 
13
+ /**
14
+ * Access control options for devtools HTTP routes.
15
+ */
7
16
  export interface DevtoolsRouteAccessOptions {
8
17
  /**
9
18
  * Whether the devtools route should be exposed.
@@ -21,16 +30,27 @@ export interface DevtoolsRouteAccessOptions {
21
30
  authorize?: DevtoolsAuthorize;
22
31
  }
23
32
 
33
+ /**
34
+ * Resolve whether devtools routes should be exposed.
35
+ *
36
+ * Defaults to disabled in production and enabled elsewhere.
37
+ */
24
38
  export function isDevtoolsRouteEnabled(
25
39
  options: DevtoolsRouteAccessOptions = {},
26
40
  ): boolean {
27
41
  return options.enabled ?? process.env.NODE_ENV !== "production";
28
42
  }
29
43
 
44
+ /**
45
+ * Return the standard hidden devtools response.
46
+ */
30
47
  export function devtoolsNotFoundResponse(): Response {
31
48
  return new Response("Not Found", { status: 404 });
32
49
  }
33
50
 
51
+ /**
52
+ * Authorize a devtools request and return a denial response when blocked.
53
+ */
34
54
  export async function authorizeDevtoolsRequest(
35
55
  req: Request,
36
56
  options: DevtoolsRouteAccessOptions = {},
package/src/audit.ts CHANGED
@@ -7,10 +7,25 @@ import {
7
7
  } from "@beignet/core/ports";
8
8
  import type { DevtoolsPort } from "./index";
9
9
 
10
+ /**
11
+ * Options for wrapping an audit log with devtools emission.
12
+ */
10
13
  export interface DevtoolsAuditLogOptions {
14
+ /**
15
+ * Durable audit log to write first.
16
+ */
11
17
  audit: AuditLogPort;
18
+ /**
19
+ * Optional devtools port that receives audit events.
20
+ */
12
21
  devtools?: DevtoolsPort;
22
+ /**
23
+ * Whether to emit devtools events. Defaults to true.
24
+ */
13
25
  emit?: boolean;
26
+ /**
27
+ * Optional app-owned redactor applied after Beignet's audit redaction.
28
+ */
14
29
  redact?: (entry: AuditLogEntry) => AuditLogEntry;
15
30
  }
16
31
 
@@ -32,6 +47,12 @@ function auditSummary(entry: AuditLogEntry): string {
32
47
  : `${entry.action} ${outcome}`;
33
48
  }
34
49
 
50
+ /**
51
+ * Wrap an audit log so durable audit writes can also appear in devtools.
52
+ *
53
+ * Devtools observer failures are ignored so audit persistence remains the
54
+ * source of truth.
55
+ */
35
56
  export function createDevtoolsAuditLog(
36
57
  options: DevtoolsAuditLogOptions,
37
58
  ): AuditLogPort {
package/src/events.ts CHANGED
@@ -110,7 +110,13 @@ export interface EventBusEvent extends BaseDevtoolsEvent {
110
110
  export interface JobEvent extends BaseDevtoolsEvent {
111
111
  type: "job";
112
112
  jobName: string;
113
- status: "scheduled" | "started" | "completed" | "failed";
113
+ status:
114
+ | "scheduled"
115
+ | "started"
116
+ | "completed"
117
+ | "failed"
118
+ | "retryScheduled"
119
+ | "deadLettered";
114
120
  }
115
121
 
116
122
  /**
@@ -156,14 +162,23 @@ export type DevtoolsEvent =
156
162
  | ProviderEvent
157
163
  | CustomDevtoolsEvent;
158
164
 
165
+ /**
166
+ * Input accepted by `createDevtoolsEvent(...)`.
167
+ */
159
168
  export type DevtoolsEventInput = DevtoolsEvent extends infer Event
160
169
  ? Event extends DevtoolsEvent
161
170
  ? Omit<Event, "id" | "timestamp"> & Partial<Pick<Event, "id" | "timestamp">>
162
171
  : never
163
172
  : never;
164
173
 
174
+ /**
175
+ * Function that redacts a normalized devtools event before storage.
176
+ */
165
177
  export type DevtoolsRedactor = (event: DevtoolsEvent) => DevtoolsEvent;
166
178
 
179
+ /**
180
+ * Event emitted to live devtools subscribers.
181
+ */
167
182
  export type DevtoolsSubscriptionEvent =
168
183
  | {
169
184
  type: "record";
@@ -173,8 +188,14 @@ export type DevtoolsSubscriptionEvent =
173
188
  type: "clear";
174
189
  };
175
190
 
191
+ /**
192
+ * Devtools subscription listener.
193
+ */
176
194
  export type DevtoolsListener = (event: DevtoolsSubscriptionEvent) => void;
177
195
 
196
+ /**
197
+ * All built-in devtools event types.
198
+ */
178
199
  export const DEVTOOLS_EVENT_TYPES = [
179
200
  "request",
180
201
  "error",
@@ -186,6 +207,9 @@ export const DEVTOOLS_EVENT_TYPES = [
186
207
  "custom",
187
208
  ] as const satisfies readonly DevtoolsEvent["type"][];
188
209
 
210
+ /**
211
+ * Check whether a string is a built-in devtools event type.
212
+ */
189
213
  export function isDevtoolsEventType(
190
214
  value: string,
191
215
  ): 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,8 +132,10 @@ 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}
138
+ .badge-uploads{background:#f0f9ff;color:#0369a1;border-color:#bae6fd}
137
139
  .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}
138
140
  .trace-id{font-family:var(--font-mono);font-size:10px;color:var(--accent-strong);padding:2px 5px;background:#eef2ff;border:1px solid rgba(79,70,229,.16);border-radius:4px}
139
141
  @media(max-width:760px){
@@ -221,14 +223,16 @@ button.danger:hover{border-color:rgba(225,29,72,.24);background:#fff1f2}
221
223
  {id:"db",label:"Database",type:"custom",watcher:"db",watcherName:"db"},
222
224
  {id:"cache",label:"Cache",type:"custom",watcher:"cache",watcherName:"cache"},
223
225
  {id:"storage",label:"Storage",type:"custom",watcher:"storage",watcherName:"storage"},
226
+ {id:"uploads",label:"Uploads",type:"custom",watcher:"uploads",watcherName:"uploads"},
224
227
  {id:"mail",label:"Mail",type:"custom",watcher:"mail",watcherName:"mail"},
228
+ {id:"notifications",label:"Notifications",type:"custom",watcher:"notifications",watcherName:"notifications"},
225
229
  {id:"auth",label:"Auth",type:"custom",watcher:"auth",watcherName:"auth"},
226
230
  {id:"audit",label:"Audit",type:"custom",watcher:"audit",watcherName:"audit"},
227
231
  {id:"rateLimit",label:"Rate limits",type:"custom",watcher:"rateLimit",watcherName:"rateLimit"},
228
232
  {id:"custom",label:"Custom",type:"custom",watcher:"custom"}
229
233
  ];
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};
234
+ const FOCUS_PANEL_TABS={events:true,jobs:true,schedules:true,db:true,cache:true,storage:true,uploads:true,mail:true,notifications:true,auth:true,audit:true,rateLimit:true};
235
+ const BUILT_IN_WATCHERS={requests:true,errors:true,useCases:true,eventBus:true,jobs:true,schedules:true,providers:true,db:true,cache:true,storage:true,uploads:true,mail:true,notifications:true,auth:true,audit:true,rateLimit:true,custom:true};
232
236
  let events=[];
233
237
  let watchers=[];
234
238
  let activeTab=localStorage.getItem("beignet-devtools-tab")||"timeline";
@@ -331,8 +335,10 @@ button.danger:hover{border-color:rgba(225,29,72,.24);background:#fff1f2}
331
335
  case "cache": return "cache";
332
336
  case "db": return "database";
333
337
  case "mail": return "mail";
338
+ case "notifications": return "notifications";
334
339
  case "rateLimit": return "rate limit";
335
340
  case "storage": return "storage";
341
+ case "uploads": return "uploads";
336
342
  default: return "custom";
337
343
  }
338
344
  }
@@ -347,8 +353,10 @@ button.danger:hover{border-color:rgba(225,29,72,.24);background:#fff1f2}
347
353
  case "cache": return "cache";
348
354
  case "db": return "db";
349
355
  case "mail": return "mail";
356
+ case "notifications": return "notifications";
350
357
  case "rateLimit": return "rateLimit";
351
358
  case "storage": return "storage";
359
+ case "uploads": return "uploads";
352
360
  default: return "custom";
353
361
  }
354
362
  }
@@ -564,7 +572,9 @@ button.danger:hover{border-color:rgba(225,29,72,.24);background:#fff1f2}
564
572
  case "db": return {title:"Database",subtitle:"Queries and database provider diagnostics"};
565
573
  case "cache": return {title:"Cache",subtitle:"Reads, writes, deletes, and hit rates"};
566
574
  case "storage": return {title:"Storage",subtitle:"Object storage operations"};
575
+ case "uploads": return {title:"Uploads",subtitle:"Upload preparation, signing, and completion"};
567
576
  case "mail": return {title:"Mail",subtitle:"Delivery attempts and provider results"};
577
+ case "notifications": return {title:"Notifications",subtitle:"Notification intent and channel delivery"};
568
578
  case "auth": return {title:"Auth",subtitle:"Session and authentication activity"};
569
579
  case "audit": return {title:"Audit",subtitle:"Durable activity records emitted by application code"};
570
580
  case "rateLimit": return {title:"Rate limits",subtitle:"Allowed, blocked, and failed checks"};