convex-tracer 0.1.0 → 0.1.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 (61) hide show
  1. package/dist/client/helpers.d.ts.map +1 -1
  2. package/dist/client/index.d.ts +24 -4
  3. package/dist/client/index.d.ts.map +1 -1
  4. package/dist/client/index.js +18 -1
  5. package/dist/client/index.js.map +1 -1
  6. package/dist/component/_generated/component.d.ts +55 -10
  7. package/dist/component/_generated/component.d.ts.map +1 -1
  8. package/dist/component/lib.d.ts +58 -25
  9. package/dist/component/lib.d.ts.map +1 -1
  10. package/dist/component/lib.js +60 -21
  11. package/dist/component/lib.js.map +1 -1
  12. package/dist/component/schema.d.ts +25 -18
  13. package/dist/component/schema.d.ts.map +1 -1
  14. package/dist/component/schema.js +6 -1
  15. package/dist/component/schema.js.map +1 -1
  16. package/dist/component/types.d.ts +138 -80
  17. package/dist/component/types.d.ts.map +1 -1
  18. package/dist/component/types.js +2 -0
  19. package/dist/component/types.js.map +1 -1
  20. package/package.json +1 -1
  21. package/src/client/helpers.ts +11 -1
  22. package/src/client/index.ts +42 -9
  23. package/src/component/_generated/component.ts +61 -10
  24. package/src/component/lib.ts +72 -28
  25. package/src/component/schema.ts +6 -1
  26. package/src/component/types.ts +4 -0
  27. package/dist/client/_generated/_ignore.d.ts +0 -1
  28. package/dist/client/_generated/_ignore.d.ts.map +0 -1
  29. package/dist/client/_generated/_ignore.js +0 -3
  30. package/dist/client/_generated/_ignore.js.map +0 -1
  31. package/dist/client/helpers.d.ts +0 -31
  32. package/dist/client/helpers.js +0 -177
  33. package/dist/client/helpers.js.map +0 -1
  34. package/dist/client/tracer-api/index.d.ts +0 -27
  35. package/dist/client/tracer-api/index.js +0 -177
  36. package/dist/client/tracer-api/index.js.map +0 -1
  37. package/dist/client/tracer-api/types.d.ts +0 -143
  38. package/dist/client/tracer-api/types.js +0 -2
  39. package/dist/client/tracer-api/types.js.map +0 -1
  40. package/dist/client/types.d.ts +0 -168
  41. package/dist/client/types.js +0 -2
  42. package/dist/client/types.js.map +0 -1
  43. package/dist/component/_generated/api.d.ts +0 -36
  44. package/dist/component/_generated/api.js +0 -31
  45. package/dist/component/_generated/api.js.map +0 -1
  46. package/dist/component/_generated/dataModel.d.ts +0 -46
  47. package/dist/component/_generated/dataModel.js +0 -11
  48. package/dist/component/_generated/dataModel.js.map +0 -1
  49. package/dist/component/_generated/server.d.ts +0 -121
  50. package/dist/component/_generated/server.js +0 -78
  51. package/dist/component/_generated/server.js.map +0 -1
  52. package/dist/component/convex.config.d.ts +0 -3
  53. package/dist/component/convex.config.d.ts.map +0 -1
  54. package/dist/component/convex.config.js +0 -3
  55. package/dist/component/convex.config.js.map +0 -1
  56. package/dist/react/index.d.ts +0 -6
  57. package/dist/react/index.js +0 -11
  58. package/dist/react/index.js.map +0 -1
  59. package/dist/react/types.d.ts +0 -8
  60. package/dist/react/types.js +0 -2
  61. package/dist/react/types.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/component/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAc,MAAM,eAAe,CAAC;AAC9C,OAAO,MAAM,MAAM,UAAU,CAAC;AAE9B,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC;IAC1D,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;CAC1B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS;KAC/C,IAAI,CAAC,cAAc,CAAC;KACpB,IAAI,CAAC,SAAS,CAAC;KACf,MAAM,CAAC;IACN,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,YAAY,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACpC,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;CAC1B,CAAC,CAAC;AAEL,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;IACrE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;CAC1B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC;IACxC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;CACvC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC;IAC1C,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC;CAC9B,CAAC,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/component/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,CAAC,EAAc,MAAM,eAAe,CAAC;AAC9C,OAAO,MAAM,MAAM,UAAU,CAAC;AAE9B,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC;IAC1D,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;CAC1B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;AAElE,MAAM,CAAC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS;KAC/C,IAAI,CAAC,cAAc,CAAC;KACpB,IAAI,CAAC,SAAS,CAAC;KACf,MAAM,CAAC;IACN,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,YAAY,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACpC,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;CAC1B,CAAC,CAAC;AAEL,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;IACrE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;CAC1B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC;IACxC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;CACvC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC;IAC1C,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC;CAC9B,CAAC,CAAC"}
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "bugs": {
10
10
  "url": "https://github.com/Moumen-io/convex-tracer/issues"
11
11
  },
12
- "version": "0.1.0",
12
+ "version": "0.1.1",
13
13
  "license": "Apache-2.0",
14
14
  "keywords": [
15
15
  "convex",
@@ -1,4 +1,4 @@
1
- import type { GenericDataModel } from "convex/server";
1
+ import type { Auth, GenericDataModel } from "convex/server";
2
2
  import type { ObjectType, PropertyValidators } from "convex/values";
3
3
  import type { ComponentApi } from "../component/_generated/component";
4
4
  import TracerAPI from "./tracer-api/index";
@@ -25,6 +25,14 @@ function pick<T extends Record<string, any>, Keys extends (keyof T)[]>(
25
25
  };
26
26
  }
27
27
 
28
+ async function getAuthUserId(ctx: { auth: Auth }) {
29
+ const identity = await ctx.auth.getUserIdentity();
30
+ if (identity === null) return "anonymous";
31
+
32
+ const [userId] = identity.subject.split("|");
33
+ return userId;
34
+ }
35
+
28
36
  export function extractTraceContext<Args extends Record<string, unknown>>(
29
37
  allArgs: ArgsWithTraceContext<Args>,
30
38
  ): { existingContext?: TraceContext; args: Args } {
@@ -90,11 +98,13 @@ export async function setupTraceContext(
90
98
  };
91
99
  }
92
100
 
101
+ const userId = await getAuthUserId(ctx);
93
102
  const traceId = await ctx.runMutation(component.lib.createTrace, {
94
103
  status: "pending",
95
104
  sampleRate,
96
105
  metadata: {},
97
106
  source: "backend",
107
+ userId,
98
108
  });
99
109
 
100
110
  const spanId = await ctx.runMutation(component.lib.createSpan, {
@@ -1,12 +1,16 @@
1
- import type { FunctionType, GenericQueryCtx } from "convex/server";
1
+ import type {
2
+ FunctionType,
3
+ GenericQueryCtx,
4
+ paginationOptsValidator,
5
+ } from "convex/server";
2
6
  import {
3
7
  actionGeneric,
4
- type GenericActionCtx,
5
- type GenericDataModel,
6
- type GenericMutationCtx,
7
8
  internalActionGeneric,
8
9
  internalMutationGeneric,
9
10
  mutationGeneric,
11
+ type GenericActionCtx,
12
+ type GenericDataModel,
13
+ type GenericMutationCtx,
10
14
  type RegisteredAction,
11
15
  type RegisteredMutation,
12
16
  } from "convex/server";
@@ -14,7 +18,7 @@ import type { Infer, PropertyValidators } from "convex/values";
14
18
  import { v } from "convex/values";
15
19
  import type { ComponentApi } from "../component/_generated/component";
16
20
  import { statusValidator } from "../component/schema";
17
- import type { CompleteTrace, Trace } from "../component/types";
21
+ import { type CompleteTrace, type paginatedTraces } from "../component/types";
18
22
  import type { EmptyObject } from "../react/types";
19
23
  import {
20
24
  executeTracedHandler,
@@ -40,6 +44,11 @@ import type {
40
44
  TracerHandler,
41
45
  } from "./types";
42
46
 
47
+ export {
48
+ severityValidator,
49
+ sourceValidator,
50
+ statusValidator,
51
+ } from "../component/schema";
43
52
  export * from "../component/types";
44
53
 
45
54
  const DEFAULT_CONFIG: Required<TracerConfig> = {
@@ -571,6 +580,9 @@ export class Tracer<DataModel extends GenericDataModel> {
571
580
  * @param status - The status of the traces to retrieve.
572
581
  * @param limit - The maximum number of traces to retrieve.
573
582
  * @param userId - The ID of the user to retrieve traces for.
583
+ * @param paginationOpts - Convex pagination options.
584
+ * @returns A pagination result containing the page of results and a
585
+ * cursor to continue paginating.
574
586
  * @example
575
587
  * ```ts
576
588
  * // In a convex function (query, mutation, or action)
@@ -580,13 +592,34 @@ export class Tracer<DataModel extends GenericDataModel> {
580
592
  */
581
593
  listTraces: async (
582
594
  ctx: GenericFunctionContext<DataModel>,
583
- args?: {
595
+ args: {
584
596
  status?: Infer<typeof statusValidator>;
585
- limit?: number;
586
597
  userId?: string;
598
+ paginationOpts: Infer<typeof paginationOptsValidator>;
599
+ },
600
+ ): Promise<paginatedTraces> => {
601
+ return await ctx.runQuery(this.component.lib.listTraces, args);
602
+ },
603
+
604
+ /**
605
+ * Searches for traces by function name.
606
+ * @param functionName - The name of the function to search for.
607
+ * @param userId - The ID of the user to search for.
608
+ * @param status - The status of the traces to search for.
609
+ * @param paginationOpts - Convex pagination options.
610
+ * @returns A pagination result containing the page of results and a
611
+ * cursor to continue paginating.
612
+ */
613
+ searchTraces: async (
614
+ ctx: GenericFunctionContext<DataModel>,
615
+ args: {
616
+ functionName: string;
617
+ userId?: string;
618
+ status?: Infer<typeof statusValidator>;
619
+ paginationOpts: Infer<typeof paginationOptsValidator>;
587
620
  },
588
- ): Promise<Trace[]> => {
589
- return await ctx.runQuery(this.component.lib.listTraces, { ...args });
621
+ ): Promise<paginatedTraces> => {
622
+ return await ctx.runQuery(this.component.lib.searchTraces, args);
590
623
  },
591
624
  };
592
625
  }
@@ -86,6 +86,7 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
86
86
  sampleRate: number;
87
87
  source: "frontend" | "backend";
88
88
  status: "pending" | "success" | "error";
89
+ userId: "anonymous" | string;
89
90
  },
90
91
  string,
91
92
  Name
@@ -97,6 +98,7 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
97
98
  null | {
98
99
  _creationTime: number;
99
100
  _id: string;
101
+ functionName?: string;
100
102
  metadata?: Record<string, any>;
101
103
  preserve?: boolean;
102
104
  sampleRate: number;
@@ -137,20 +139,69 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
137
139
  "query",
138
140
  "internal",
139
141
  {
140
- limit?: number;
142
+ paginationOpts: {
143
+ cursor: string | null;
144
+ endCursor?: string | null;
145
+ id?: number;
146
+ maximumBytesRead?: number;
147
+ maximumRowsRead?: number;
148
+ numItems: number;
149
+ };
141
150
  status?: "pending" | "success" | "error";
142
151
  userId?: string;
143
152
  },
144
- Array<{
145
- _creationTime: number;
146
- _id: string;
147
- metadata?: Record<string, any>;
148
- preserve?: boolean;
149
- sampleRate: number;
150
- status: "pending" | "success" | "error";
151
- updatedAt: number;
153
+ {
154
+ continueCursor: string;
155
+ isDone: boolean;
156
+ page: Array<{
157
+ _creationTime: number;
158
+ _id: string;
159
+ functionName?: string;
160
+ metadata?: Record<string, any>;
161
+ preserve?: boolean;
162
+ sampleRate: number;
163
+ status: "pending" | "success" | "error";
164
+ updatedAt: number;
165
+ userId?: string;
166
+ }>;
167
+ pageStatus?: "SplitRecommended" | "SplitRequired" | null;
168
+ splitCursor?: string | null;
169
+ },
170
+ Name
171
+ >;
172
+ searchTraces: FunctionReference<
173
+ "query",
174
+ "internal",
175
+ {
176
+ functionName: string;
177
+ paginationOpts: {
178
+ cursor: string | null;
179
+ endCursor?: string | null;
180
+ id?: number;
181
+ maximumBytesRead?: number;
182
+ maximumRowsRead?: number;
183
+ numItems: number;
184
+ };
185
+ status?: "pending" | "success" | "error";
152
186
  userId?: string;
153
- }>,
187
+ },
188
+ {
189
+ continueCursor: string;
190
+ isDone: boolean;
191
+ page: Array<{
192
+ _creationTime: number;
193
+ _id: string;
194
+ functionName?: string;
195
+ metadata?: Record<string, any>;
196
+ preserve?: boolean;
197
+ sampleRate: number;
198
+ status: "pending" | "success" | "error";
199
+ updatedAt: number;
200
+ userId?: string;
201
+ }>;
202
+ pageStatus?: "SplitRecommended" | "SplitRequired" | null;
203
+ splitCursor?: string | null;
204
+ },
154
205
  Name
155
206
  >;
156
207
  updateSpanMetadata: FunctionReference<
@@ -2,15 +2,16 @@
2
2
  * Internal mutations for managing traces, spans, and logs.
3
3
  * These are called automatically by the tracing system to persist data immediately.
4
4
  */
5
+ import { paginationOptsValidator } from "convex/server";
5
6
  import { v } from "convex/values";
6
7
  import type { Id } from "./_generated/dataModel.js";
7
8
  import { mutation, query, type MutationCtx } from "./_generated/server.js";
8
- import schema, {
9
+ import {
9
10
  severityValidator,
10
11
  sourceValidator,
11
12
  statusValidator,
12
13
  } from "./schema.js";
13
- import { vCompleteTrace } from "./types.js";
14
+ import { vCompleteTrace, vPaginatedTraces } from "./types.js";
14
15
 
15
16
  // ============================================================================
16
17
  // Trace Operations
@@ -26,6 +27,7 @@ export const createTrace = mutation({
26
27
  sampleRate: v.number(),
27
28
  metadata: v.optional(v.record(v.string(), v.any())),
28
29
  source: sourceValidator,
30
+ userId: v.union(v.literal("anonymous"), v.string()),
29
31
  },
30
32
  returns: v.id("traces"),
31
33
  handler: async (ctx, args): Promise<Id<"traces">> => {
@@ -34,6 +36,7 @@ export const createTrace = mutation({
34
36
  sampleRate: args.sampleRate,
35
37
  updatedAt: Date.now(),
36
38
  metadata: args.metadata,
39
+ userId: args.userId,
37
40
  });
38
41
  },
39
42
  });
@@ -305,34 +308,75 @@ export const getTrace = query({
305
308
  export const listTraces = query({
306
309
  args: {
307
310
  status: v.optional(statusValidator),
308
- limit: v.optional(v.number()),
309
311
  userId: v.optional(v.string()),
312
+ paginationOpts: paginationOptsValidator,
310
313
  },
311
- returns: v.array(
312
- schema.tables.traces.validator.extend({
313
- _id: v.id("traces"),
314
- _creationTime: v.number(),
315
- }),
316
- ),
317
- handler: async (ctx, { status, limit, userId }) => {
318
- const query =
319
- status && !userId
320
- ? ctx.db
321
- .query("traces")
322
- .withIndex("by_status", (q) => q.eq("status", status))
323
- : !status && userId
324
- ? ctx.db
325
- .query("traces")
326
- .withIndex("by_userId", (q) => q.eq("userId", userId))
327
- : status && userId
328
- ? ctx.db
329
- .query("traces")
330
- .withIndex("by_status_and_userId", (q) =>
331
- q.eq("status", status).eq("userId", userId),
332
- )
333
- : ctx.db.query("traces");
334
-
335
- return await query.order("desc").take(limit ?? 100);
314
+ returns: vPaginatedTraces,
315
+ handler: async (ctx, { status, userId, paginationOpts }) => {
316
+ const query = ctx.db.query("traces");
317
+
318
+ if (status && !userId) {
319
+ return await query
320
+ .withIndex("by_status", (q) => q.eq("status", status))
321
+ .order("desc")
322
+ .paginate(paginationOpts);
323
+ } else if (!status && userId) {
324
+ return await query
325
+ .withIndex("by_userId", (q) => q.eq("userId", userId))
326
+ .order("desc")
327
+ .paginate(paginationOpts);
328
+ } else if (status && userId) {
329
+ return await query
330
+ .withIndex("by_status_and_userId", (q) =>
331
+ q.eq("status", status).eq("userId", userId),
332
+ )
333
+ .order("desc")
334
+ .paginate(paginationOpts);
335
+ }
336
+
337
+ return await query.order("desc").paginate(paginationOpts);
338
+ },
339
+ });
340
+
341
+ export const searchTraces = query({
342
+ args: {
343
+ functionName: v.string(),
344
+ userId: v.optional(v.string()),
345
+ status: v.optional(statusValidator),
346
+ paginationOpts: paginationOptsValidator,
347
+ },
348
+ returns: vPaginatedTraces,
349
+ handler: async (ctx, { functionName, paginationOpts, userId, status }) => {
350
+ const query = ctx.db.query("traces");
351
+
352
+ if (userId && !status) {
353
+ return await query
354
+ .withSearchIndex("by_function_name", (q) =>
355
+ q.search("functionName", functionName).eq("userId", userId),
356
+ )
357
+ .paginate(paginationOpts);
358
+ } else if (status && !userId) {
359
+ return await query
360
+ .withSearchIndex("by_function_name", (q) =>
361
+ q.search("functionName", functionName).eq("status", status),
362
+ )
363
+ .paginate(paginationOpts);
364
+ } else if (userId && status) {
365
+ return await query
366
+ .withSearchIndex("by_function_name", (q) =>
367
+ q
368
+ .search("functionName", functionName)
369
+ .eq("userId", userId)
370
+ .eq("status", status),
371
+ )
372
+ .paginate(paginationOpts);
373
+ }
374
+
375
+ return await query
376
+ .withSearchIndex("by_function_name", (q) =>
377
+ q.search("functionName", functionName),
378
+ )
379
+ .paginate(paginationOpts);
336
380
  },
337
381
  });
338
382
 
@@ -25,11 +25,16 @@ export default defineSchema({
25
25
  preserve: v.optional(v.boolean()),
26
26
  updatedAt: v.number(),
27
27
  metadata: v.optional(v.record(v.string(), v.any())),
28
+ functionName: v.optional(v.string()),
28
29
  userId: v.optional(v.string()),
29
30
  })
30
31
  .index("by_status", ["status"])
31
32
  .index("by_userId", ["userId"])
32
- .index("by_status_and_userId", ["status", "userId"]),
33
+ .index("by_status_and_userId", ["status", "userId"])
34
+ .searchIndex("by_function_name", {
35
+ searchField: "functionName",
36
+ filterFields: ["status", "userId"],
37
+ }),
33
38
 
34
39
  spans: defineTable({
35
40
  traceId: v.id("traces"),
@@ -1,3 +1,4 @@
1
+ import { paginationResultValidator } from "convex/server";
1
2
  import { v, type Infer } from "convex/values";
2
3
  import schema from "./schema";
3
4
 
@@ -6,6 +7,8 @@ export const vTrace = schema.tables.traces.validator.extend({
6
7
  _creationTime: v.number(),
7
8
  });
8
9
 
10
+ export const vPaginatedTraces = paginationResultValidator(vTrace);
11
+
9
12
  export const vSpan = schema.tables.spans.validator
10
13
  .omit("parentSpanId")
11
14
  .omit("traceId")
@@ -36,3 +39,4 @@ export type Span = Infer<typeof vSpan>;
36
39
  export type Log = Infer<typeof vLog>;
37
40
  export type SpanWithLogs = Infer<typeof vSpanWithLogs>;
38
41
  export type CompleteTrace = Infer<typeof vCompleteTrace>;
42
+ export type paginatedTraces = Infer<typeof vPaginatedTraces>;
@@ -1 +0,0 @@
1
- //# sourceMappingURL=_ignore.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"_ignore.d.ts","sourceRoot":"","sources":["../../../src/client/_generated/_ignore.ts"],"names":[],"mappings":""}
@@ -1,3 +0,0 @@
1
- "use strict";
2
- // This is only here so convex-test can detect a _generated folder
3
- //# sourceMappingURL=_ignore.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"_ignore.js","sourceRoot":"","sources":["../../../src/client/_generated/_ignore.ts"],"names":[],"mappings":";AAAA,kEAAkE"}
@@ -1,31 +0,0 @@
1
- import type { GenericDataModel } from "convex/server";
2
- import type { ObjectType, PropertyValidators } from "convex/values";
3
- import type { ComponentApi } from "../component/_generated/component";
4
- import type { ArgsWithTraceContext, LogArgs, OptionalArgsObject, StrippedGenericFunctionContext, TraceContext, TracedFunctionOptions, TracedResult, TracerConfig, TracerHandler } from "./types";
5
- export declare function extractTraceContext<Args extends Record<string, unknown>>(allArgs: ArgsWithTraceContext<Args>): {
6
- existingContext?: TraceContext;
7
- args: Args;
8
- };
9
- export declare function prepareLogArgs<Args extends PropertyValidators>(args: ObjectType<Args>, logArgs: LogArgs<Args>): unknown | undefined;
10
- export declare function setupTraceContext(ctx: StrippedGenericFunctionContext<GenericDataModel>, component: ComponentApi, existingContext: TraceContext | undefined, startTime: number, functionName: string, sampleRate: number, retentionMinutes: number, preserveErrors: boolean, spanData: {
11
- functionName?: string;
12
- args?: unknown;
13
- }): Promise<{
14
- traceId: string;
15
- spanId: string;
16
- traceContext: TraceContext;
17
- isRoot: boolean;
18
- }>;
19
- export declare function executeTracedHandler<Args extends PropertyValidators, Output, EnhancedCtx>(params: {
20
- ctx: StrippedGenericFunctionContext<GenericDataModel>;
21
- component: ComponentApi;
22
- traceId: string;
23
- spanId: string;
24
- startTime: number;
25
- config: TracedFunctionOptions<EnhancedCtx, Args, Output> & TracerConfig;
26
- args: OptionalArgsObject<Args>;
27
- handler: TracerHandler<EnhancedCtx, Args>;
28
- enhancedCtx: EnhancedCtx;
29
- isRoot: boolean;
30
- }): Promise<TracedResult<Output>>;
31
- //# sourceMappingURL=helpers.d.ts.map
@@ -1,177 +0,0 @@
1
- import TracerAPI from "./tracer-api/index";
2
- function pick(obj, keys) {
3
- return Object.fromEntries(Object.entries(obj).filter(([k]) => keys.includes(k)));
4
- }
5
- export function extractTraceContext(allArgs) {
6
- const existingContext = allArgs.__traceContext;
7
- const args = { ...allArgs };
8
- delete args.__traceContext;
9
- return { existingContext, args };
10
- }
11
- export function prepareLogArgs(args, logArgs) {
12
- if (!logArgs)
13
- return undefined;
14
- if (logArgs === true)
15
- return args;
16
- if (Array.isArray(logArgs)) {
17
- return pick(args, logArgs);
18
- }
19
- return undefined;
20
- }
21
- export async function setupTraceContext(ctx, component, existingContext, startTime, functionName, sampleRate, retentionMinutes, preserveErrors, spanData) {
22
- if (existingContext?.traceId) {
23
- const spanId = await ctx.runMutation(component.lib.createSpan, {
24
- traceId: existingContext.traceId,
25
- span: {
26
- parentSpanId: existingContext.spanId,
27
- spanName: functionName,
28
- source: "backend",
29
- startTime,
30
- status: "pending",
31
- functionName: spanData.functionName,
32
- args: spanData.args,
33
- },
34
- });
35
- return {
36
- traceId: existingContext.traceId,
37
- spanId,
38
- traceContext: {
39
- traceId: existingContext.traceId,
40
- spanId,
41
- sampleRate: existingContext.sampleRate,
42
- retentionMinutes: existingContext.retentionMinutes,
43
- preserveErrors: existingContext.preserveErrors,
44
- },
45
- isRoot: false,
46
- };
47
- }
48
- const traceId = await ctx.runMutation(component.lib.createTrace, {
49
- status: "pending",
50
- sampleRate,
51
- metadata: {},
52
- source: "backend",
53
- });
54
- const spanId = await ctx.runMutation(component.lib.createSpan, {
55
- traceId,
56
- span: {
57
- spanName: functionName,
58
- source: "backend",
59
- startTime: Date.now(),
60
- status: "pending",
61
- functionName: spanData.functionName,
62
- args: spanData.args,
63
- },
64
- });
65
- return {
66
- traceId,
67
- spanId,
68
- traceContext: {
69
- traceId,
70
- spanId,
71
- sampleRate,
72
- retentionMinutes,
73
- preserveErrors,
74
- },
75
- isRoot: true,
76
- };
77
- }
78
- export async function executeTracedHandler(params) {
79
- const { ctx, component, traceId, spanId, startTime, config, args, handler, enhancedCtx, isRoot, } = params;
80
- const defaultConfig = enhancedCtx.tracer
81
- .config;
82
- try {
83
- // Reject any functions that pass a traceId that doesn't exist
84
- // These params can be passed from the frontend to break tracing
85
- // Running a tracedFunction without passing ids will create a new trace
86
- if (traceId) {
87
- const traceExists = await ctx.runQuery(component.lib.verifyTrace, {
88
- traceId,
89
- });
90
- if (!traceExists)
91
- throw new Error("Cannot pass a traceId for a trace that doesn't exist");
92
- }
93
- // Reject any functions that pass a spanId that doesn't exist
94
- // These params can be passed from the frontend to break tracing
95
- if (spanId) {
96
- const spanExists = await ctx.runQuery(component.lib.verifySpan, {
97
- spanId,
98
- });
99
- if (!spanExists)
100
- throw new Error("Cannot pass a spanId for a span that doesn't exist");
101
- }
102
- if (config.onStart) {
103
- await config.onStart(enhancedCtx, args);
104
- }
105
- const result = await handler(enhancedCtx, args);
106
- if (config.onSuccess) {
107
- await config.onSuccess(enhancedCtx, args, result);
108
- }
109
- const now = Date.now();
110
- await ctx
111
- .runMutation(component.lib.completeSpan, {
112
- spanId,
113
- endTime: now,
114
- duration: now - startTime,
115
- status: "success",
116
- result: config.logReturn ? result : undefined,
117
- })
118
- .catch((err) => console.error("[Tracer] Failed to complete span with success:", err));
119
- if (isRoot) {
120
- await ctx
121
- .runMutation(component.lib.updateTraceStatus, {
122
- traceId,
123
- status: "success",
124
- })
125
- .catch((err) => console.error("[Tracer] Failed to update trace status:", err));
126
- }
127
- return { success: true, data: result, error: undefined };
128
- }
129
- catch (e) {
130
- const error = e;
131
- if (config.onError) {
132
- await config.onError(enhancedCtx, args, error);
133
- }
134
- const preserveErrors = config.preserveErrors ?? defaultConfig.preserveErrors;
135
- if (preserveErrors) {
136
- const tracerAPI = new TracerAPI(ctx, component, traceId, spanId, config);
137
- await tracerAPI.preserve();
138
- }
139
- await ctx
140
- .runMutation(component.lib.completeSpan, {
141
- spanId,
142
- endTime: Date.now(),
143
- duration: Date.now() - startTime,
144
- status: "error",
145
- error: error.message,
146
- })
147
- .catch((err) => console.error("[Tracer] Failed to complete span with error:", err));
148
- if (isRoot) {
149
- await ctx
150
- .runMutation(component.lib.updateTraceStatus, {
151
- traceId,
152
- status: "error",
153
- })
154
- .catch((err) => console.error("[Tracer] Failed to update trace status:", err));
155
- }
156
- return { success: false, data: undefined, error: error.message };
157
- }
158
- finally {
159
- const retMins = config.retentionMinutes ?? defaultConfig.retentionMinutes;
160
- if (!retMins) {
161
- console.error("[Tracer] retentionMinutes is not defined");
162
- }
163
- const sampleRate = config.sampleRate ?? defaultConfig.sampleRate;
164
- if (!sampleRate) {
165
- console.error("[Tracer] sampleRate is not defined");
166
- }
167
- else if (sampleRate && sampleRate < 1) {
168
- const MINUTE = 60 * 1000;
169
- const delayMins = retMins ?? 120;
170
- const delay = delayMins * MINUTE;
171
- await ctx.scheduler.runAfter(delay, component.lib.cleanupTrace, {
172
- traceId,
173
- });
174
- }
175
- }
176
- }
177
- //# sourceMappingURL=helpers.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/client/helpers.ts"],"names":[],"mappings":"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"}