convex-tracer 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +592 -0
  3. package/dist/client/_generated/_ignore.d.ts +1 -0
  4. package/dist/client/_generated/_ignore.d.ts.map +1 -0
  5. package/dist/client/_generated/_ignore.js +3 -0
  6. package/dist/client/_generated/_ignore.js.map +1 -0
  7. package/dist/client/helpers.d.ts +31 -0
  8. package/dist/client/helpers.d.ts.map +1 -0
  9. package/dist/client/helpers.js +177 -0
  10. package/dist/client/helpers.js.map +1 -0
  11. package/dist/client/index.d.ts +210 -0
  12. package/dist/client/index.d.ts.map +1 -0
  13. package/dist/client/index.js +355 -0
  14. package/dist/client/index.js.map +1 -0
  15. package/dist/client/tracer-api/index.d.ts +27 -0
  16. package/dist/client/tracer-api/index.d.ts.map +1 -0
  17. package/dist/client/tracer-api/index.js +177 -0
  18. package/dist/client/tracer-api/index.js.map +1 -0
  19. package/dist/client/tracer-api/types.d.ts +143 -0
  20. package/dist/client/tracer-api/types.d.ts.map +1 -0
  21. package/dist/client/tracer-api/types.js +2 -0
  22. package/dist/client/tracer-api/types.js.map +1 -0
  23. package/dist/client/types.d.ts +168 -0
  24. package/dist/client/types.d.ts.map +1 -0
  25. package/dist/client/types.js +2 -0
  26. package/dist/client/types.js.map +1 -0
  27. package/dist/component/_generated/api.d.ts +36 -0
  28. package/dist/component/_generated/api.d.ts.map +1 -0
  29. package/dist/component/_generated/api.js +31 -0
  30. package/dist/component/_generated/api.js.map +1 -0
  31. package/dist/component/_generated/component.d.ts +139 -0
  32. package/dist/component/_generated/component.d.ts.map +1 -0
  33. package/dist/component/_generated/component.js +11 -0
  34. package/dist/component/_generated/component.js.map +1 -0
  35. package/dist/component/_generated/dataModel.d.ts +46 -0
  36. package/dist/component/_generated/dataModel.d.ts.map +1 -0
  37. package/dist/component/_generated/dataModel.js +11 -0
  38. package/dist/component/_generated/dataModel.js.map +1 -0
  39. package/dist/component/_generated/server.d.ts +121 -0
  40. package/dist/component/_generated/server.d.ts.map +1 -0
  41. package/dist/component/_generated/server.js +78 -0
  42. package/dist/component/_generated/server.js.map +1 -0
  43. package/dist/component/convex.config.d.ts +3 -0
  44. package/dist/component/convex.config.d.ts.map +1 -0
  45. package/dist/component/convex.config.js +3 -0
  46. package/dist/component/convex.config.js.map +1 -0
  47. package/dist/component/lib.d.ts +161 -0
  48. package/dist/component/lib.d.ts.map +1 -0
  49. package/dist/component/lib.js +349 -0
  50. package/dist/component/lib.js.map +1 -0
  51. package/dist/component/schema.d.ts +75 -0
  52. package/dist/component/schema.d.ts.map +1 -0
  53. package/dist/component/schema.js +46 -0
  54. package/dist/component/schema.js.map +1 -0
  55. package/dist/component/types.d.ts +286 -0
  56. package/dist/component/types.d.ts.map +1 -0
  57. package/dist/component/types.js +28 -0
  58. package/dist/component/types.js.map +1 -0
  59. package/dist/react/index.d.ts +6 -0
  60. package/dist/react/index.d.ts.map +1 -0
  61. package/dist/react/index.js +11 -0
  62. package/dist/react/index.js.map +1 -0
  63. package/dist/react/types.d.ts +8 -0
  64. package/dist/react/types.d.ts.map +1 -0
  65. package/dist/react/types.js +2 -0
  66. package/dist/react/types.js.map +1 -0
  67. package/package.json +121 -0
  68. package/src/client/_generated/_ignore.ts +1 -0
  69. package/src/client/helpers.ts +278 -0
  70. package/src/client/index.ts +593 -0
  71. package/src/client/setup.test.ts +26 -0
  72. package/src/client/tracer-api/index.ts +235 -0
  73. package/src/client/tracer-api/types.ts +168 -0
  74. package/src/client/types.ts +257 -0
  75. package/src/component/_generated/api.ts +52 -0
  76. package/src/component/_generated/component.ts +199 -0
  77. package/src/component/_generated/dataModel.ts +60 -0
  78. package/src/component/_generated/server.ts +161 -0
  79. package/src/component/convex.config.ts +3 -0
  80. package/src/component/lib.ts +399 -0
  81. package/src/component/schema.ts +62 -0
  82. package/src/component/setup.test.ts +11 -0
  83. package/src/component/types.ts +38 -0
  84. package/src/react/index.ts +36 -0
  85. package/src/react/types.ts +15 -0
  86. package/src/test.ts +18 -0
@@ -0,0 +1,235 @@
1
+ import type {
2
+ GenericActionCtx,
3
+ GenericDataModel,
4
+ GenericMutationCtx,
5
+ } from "convex/server";
6
+
7
+ import type { ComponentApi } from "../../component/_generated/component";
8
+ import type { TracerConfig } from "../types";
9
+ import type { SpanAPI, TraceAPI } from "./types";
10
+
11
+ export default class TracingAPI implements TraceAPI {
12
+ constructor(
13
+ private ctx:
14
+ | GenericMutationCtx<GenericDataModel>
15
+ | GenericActionCtx<GenericDataModel>,
16
+ private component: ComponentApi,
17
+ private traceId: string,
18
+ private spanId: string,
19
+ private config: TracerConfig,
20
+ ) {}
21
+
22
+ private async addLog(
23
+ severity: "info" | "warn" | "error",
24
+ message: string,
25
+ metadata?: Record<string, any>,
26
+ ): Promise<void> {
27
+ await this.ctx
28
+ .runMutation(this.component.lib.addLog, {
29
+ spanId: this.spanId,
30
+ log: { timestamp: Date.now(), severity, message, metadata },
31
+ })
32
+ .catch((err) =>
33
+ console.error(`[Tracer] Failed to add ${severity} log:`, err),
34
+ );
35
+ }
36
+
37
+ getTraceId(): string {
38
+ return this.traceId;
39
+ }
40
+
41
+ getSpanId(): string {
42
+ return this.spanId;
43
+ }
44
+
45
+ async info(message: string, metadata?: Record<string, any>): Promise<void> {
46
+ await this.addLog("info", message, metadata);
47
+ }
48
+ async warn(message: string, metadata?: Record<string, any>): Promise<void> {
49
+ await this.addLog("warn", message, metadata);
50
+ }
51
+ async error(message: string, metadata?: Record<string, any>): Promise<void> {
52
+ await this.addLog("error", message, metadata);
53
+ }
54
+
55
+ async preserve(): Promise<void> {
56
+ await this.ctx
57
+ .runMutation(this.component.lib.updateTracePreserve, {
58
+ traceId: this.traceId,
59
+ preserve: true,
60
+ })
61
+ .catch((err) => console.error("[Tracer] Failed to preserve trace:", err));
62
+ }
63
+
64
+ async discard(): Promise<void> {
65
+ await this.ctx
66
+ .runMutation(this.component.lib.updateTracePreserve, {
67
+ traceId: this.traceId,
68
+ preserve: false,
69
+ })
70
+ .catch((err) => console.error("[Tracer] Failed to discard trace:", err));
71
+ }
72
+
73
+ async sample(sampleRate?: number): Promise<void> {
74
+ await this.ctx
75
+ .runMutation(this.component.lib.updateTracePreserve, {
76
+ traceId: this.traceId,
77
+ preserve: undefined,
78
+ sampleRate,
79
+ })
80
+ .catch((err) =>
81
+ console.error("[Tracer] Failed to reset trace sampling:", err),
82
+ );
83
+ }
84
+
85
+ async withSpan<T>(
86
+ spanName: string,
87
+ fn: (span: SpanAPI) => Promise<T>,
88
+ ): Promise<T> {
89
+ return await this.createAndRunSpan(this.spanId, spanName, fn);
90
+ }
91
+
92
+ async updateMetadata(metadata: Record<string, any>): Promise<void> {
93
+ await this.ctx
94
+ .runMutation(this.component.lib.updateSpanMetadata, {
95
+ spanId: this.spanId,
96
+ metadata,
97
+ })
98
+ .catch((err) => console.error("[Tracer] Failed to set metadata:", err));
99
+ }
100
+
101
+ private createSpanAPI(spanId: string): SpanAPI {
102
+ return {
103
+ info: async (message: string, metadata?: Record<string, any>) => {
104
+ await this.ctx
105
+ .runMutation(this.component.lib.addLog, {
106
+ spanId,
107
+ log: { timestamp: Date.now(), severity: "info", message, metadata },
108
+ })
109
+ .catch((err) =>
110
+ console.error(
111
+ "[Tracer] Failed to add info log to child span:",
112
+ err,
113
+ ),
114
+ );
115
+ },
116
+ warn: async (message: string, metadata?: Record<string, any>) => {
117
+ await this.ctx
118
+ .runMutation(this.component.lib.addLog, {
119
+ spanId,
120
+ log: { timestamp: Date.now(), severity: "warn", message, metadata },
121
+ })
122
+ .catch((err) =>
123
+ console.error(
124
+ "[Tracer] Failed to add warn log to child span:",
125
+ err,
126
+ ),
127
+ );
128
+ },
129
+ error: async (message: string, metadata?: Record<string, any>) => {
130
+ await this.ctx
131
+ .runMutation(this.component.lib.addLog, {
132
+ spanId,
133
+ log: {
134
+ timestamp: Date.now(),
135
+ severity: "error",
136
+ message,
137
+ metadata,
138
+ },
139
+ })
140
+ .catch((err) =>
141
+ console.error(
142
+ "[Tracer] Failed to add error log to child span:",
143
+ err,
144
+ ),
145
+ );
146
+ },
147
+ updateMetadata: async (metadata: Record<string, any>) => {
148
+ await this.ctx
149
+ .runMutation(this.component.lib.updateSpanMetadata, {
150
+ spanId,
151
+ metadata,
152
+ })
153
+ .catch((err) =>
154
+ console.error("[Tracer] Failed to set child span metadata:", err),
155
+ );
156
+ },
157
+ withSpan: async <T>(
158
+ spanName: string,
159
+ fn: (span: SpanAPI) => Promise<T>,
160
+ ): Promise<T> => {
161
+ return await this.createAndRunSpan(spanId, spanName, fn);
162
+ },
163
+ };
164
+ }
165
+
166
+ private async createAndRunSpan<T>(
167
+ parentSpanId: string,
168
+ spanName: string,
169
+ fn: (span: SpanAPI) => Promise<T>,
170
+ ): Promise<T> {
171
+ let childSpanId: string;
172
+ try {
173
+ childSpanId = await this.ctx.runMutation(this.component.lib.createSpan, {
174
+ traceId: this.traceId,
175
+ span: {
176
+ parentSpanId,
177
+ spanName,
178
+ source: "backend",
179
+ startTime: Date.now(),
180
+ status: "pending",
181
+ },
182
+ });
183
+ } catch (err) {
184
+ console.error("[Tracer] Failed to create child span:", err);
185
+ return await fn(this.createNoOpSpanAPI());
186
+ }
187
+
188
+ const spanAPI = this.createSpanAPI(childSpanId);
189
+ const startTime = Date.now();
190
+
191
+ try {
192
+ const result = await fn(spanAPI);
193
+ await this.ctx
194
+ .runMutation(this.component.lib.completeSpan, {
195
+ spanId: childSpanId,
196
+ endTime: Date.now(),
197
+ duration: Date.now() - startTime,
198
+ status: "success",
199
+ })
200
+ .catch((err) =>
201
+ console.error("[Tracer] Failed to complete span:", err),
202
+ );
203
+ return result;
204
+ } catch (error) {
205
+ await this.ctx
206
+ .runMutation(this.component.lib.completeSpan, {
207
+ spanId: childSpanId,
208
+ endTime: Date.now(),
209
+ duration: Date.now() - startTime,
210
+ status: "error",
211
+ error: error instanceof Error ? error.message : String(error),
212
+ })
213
+ .catch((err) =>
214
+ console.error("[Tracer] Failed to complete span with error:", err),
215
+ );
216
+
217
+ if (this.config.preserveErrors) {
218
+ await this.preserve();
219
+ }
220
+ throw error;
221
+ }
222
+ }
223
+
224
+ private createNoOpSpanAPI(): SpanAPI {
225
+ return {
226
+ info: async () => {},
227
+ warn: async () => {},
228
+ error: async () => {},
229
+ updateMetadata: async () => {},
230
+ withSpan: async <T>(): Promise<T> => {
231
+ return undefined as any;
232
+ },
233
+ };
234
+ }
235
+ }
@@ -0,0 +1,168 @@
1
+ import { sourceValidator, statusValidator } from "../../component/schema";
2
+
3
+ export interface SpanAPI {
4
+ /**
5
+ * Adds an info log to the current span.
6
+ * @param {string} message - The message to log.
7
+ * @param {Record<string, any>} metadata - Optional metadata to include with the log.
8
+ * @returns {Promise<void>}
9
+ * @example
10
+ * ```ts
11
+ * ctx.tracer.info("User created", { userId: user._id });
12
+ * ```
13
+ */
14
+ info(message: string, metadata?: Record<string, any>): Promise<void>;
15
+
16
+ /**
17
+ * Adds a warning log to the current span.
18
+ * @param {string} message - The message to log.
19
+ * @param {Record<string, any>} metadata - Optional metadata to include with the log.
20
+ * @returns {Promise<void>}
21
+ * @example
22
+ * ```ts
23
+ * ctx.tracer.warn("User not found", { userId: user._id });
24
+ * ```
25
+ */
26
+ warn(message: string, metadata?: Record<string, any>): Promise<void>;
27
+
28
+ /**
29
+ * Adds an error log to the current span.
30
+ * @param {string} message - The message to log.
31
+ * @param {Record<string, any>} metadata - Optional metadata to include with the log.
32
+ * @returns {Promise<void>}
33
+ * @example
34
+ * ```ts
35
+ * ctx.tracer.error("User not found", { userId: user._id });
36
+ * ```
37
+ */
38
+ error(message: string, metadata?: Record<string, any>): Promise<void>;
39
+
40
+ /**
41
+ * Sets the metadata for the current span.
42
+ * @param {Record<string, any>} metadata - The metadata to set.
43
+ * @returns {Promise<void>}
44
+ * @example
45
+ * ```ts
46
+ * ctx.tracer.updateMetadata({ userId: user._id });
47
+ * ```
48
+ */
49
+ updateMetadata(metadata: Record<string, any>): Promise<void>;
50
+
51
+ /**
52
+ * Creates a new span within the current trace.
53
+ * @param {string} name - The name of the span.
54
+ * @param {(span: SpanAPI) => Promise<T>} fn - The function to run within the span.
55
+ * @returns {Promise<T>} The result of the function.
56
+ * @example
57
+ * ```ts
58
+ * const result = await span.withSpan("createPost", async (span) => {
59
+ * await span.info("Creating post");
60
+ * return await ctx.db.insert("posts", args);
61
+ * });
62
+ * ```
63
+ */
64
+ withSpan<T>(name: string, fn: (span: SpanAPI) => Promise<T>): Promise<T>;
65
+ }
66
+
67
+ export interface TraceAPI extends SpanAPI {
68
+ /**
69
+ * Preserves the current trace.
70
+ * This will prevent the trace from being discarded or sampled.
71
+ * @returns {Promise<void>}
72
+ * @example
73
+ * ```ts
74
+ * await ctx.tracer.preserve();
75
+ * ```
76
+ */
77
+ preserve(): Promise<void>;
78
+
79
+ /**
80
+ * Discards the current trace.
81
+ * This will prevent the trace from being preserved.
82
+ * @returns {Promise<void>}
83
+ * @example
84
+ * ```ts
85
+ * await ctx.tracer.discard();
86
+ * ```
87
+ */
88
+ discard(): Promise<void>;
89
+
90
+ /**
91
+ * Makes sure the current trace will get sampled.
92
+ * This will undo any preserve() or discard() calls.
93
+ * @param {number} sampleRate - The sample rate to use. (optional)
94
+ * @returns {Promise<void>}
95
+ * @example
96
+ * ```ts
97
+ * await ctx.tracer.sample();
98
+ * ```
99
+ */
100
+ sample(sampleRate?: number): Promise<void>;
101
+
102
+ /**
103
+ * Creates a new span within the current trace.
104
+ * @param {string} name - The name of the span.
105
+ * @param {(span: SpanAPI) => Promise<T>} fn - The function to run within the span.
106
+ * @returns {Promise<T>} The result of the function.
107
+ * @example
108
+ * ```ts
109
+ * const result = await ctx.tracer.withSpan("createPost", async (span) => {
110
+ * await span.info("Creating post");
111
+ * return await ctx.db.insert("posts", args);
112
+ * });
113
+ * ```
114
+ */
115
+ withSpan<T>(name: string, fn: (span: SpanAPI) => Promise<T>): Promise<T>;
116
+
117
+ /**
118
+ * The Trace ID of the current trace.
119
+ */
120
+ getTraceId(): string;
121
+
122
+ /**
123
+ * The Span ID of the current span.
124
+ */
125
+ getSpanId(): string;
126
+ }
127
+
128
+ export interface TracerAPI {
129
+ /**
130
+ * Creates a new trace in the database.
131
+ * @param {string} traceId - The ID of the trace to create.
132
+ * @param {"pending" | "success" | "error"} status - The status of the trace.
133
+ * @param {number} sampleRate - The sample rate for the trace.
134
+ * @param {any} metadata - The metadata for the trace.
135
+ * @param {typeof statusValidator.type} source - The source of the trace.
136
+ * @returns {Promise<string>} A promise that resolves to the ID of the created trace.
137
+ */
138
+ createTrace: (
139
+ traceId: string,
140
+ status: typeof statusValidator.type,
141
+ sampleRate: number,
142
+ metadata: any,
143
+ source: typeof sourceValidator.type,
144
+ ) => Promise<string>;
145
+
146
+ /**
147
+ * Updates the status of a trace.
148
+ * @param {string} traceId - The ID of the trace to update.
149
+ * @param {typeof statusValidator.type} status - The new status of the trace.
150
+ * @returns {Promise<void>} A promise that resolves when the trace is updated.
151
+ */
152
+ updateTraceStatus: (
153
+ traceId: string,
154
+ status: typeof statusValidator.type,
155
+ ) => Promise<void>;
156
+
157
+ /**
158
+ * Updates the preserve flag of a trace.
159
+ * @param {string} traceId - The ID of the trace to update.
160
+ * @param {boolean | undefined} preserve - The new preserve flag of the trace.
161
+ * @returns {Promise<void>} A promise that resolves when the trace is updated.
162
+ */
163
+ updateTracePreserve: (
164
+ traceId: string,
165
+ preserve: boolean | undefined,
166
+ ) => Promise<void>;
167
+ updateTraceMetadata: (traceId: string, metadata: any) => Promise<void>;
168
+ }
@@ -0,0 +1,257 @@
1
+ import type {
2
+ FunctionReference,
3
+ FunctionType,
4
+ GenericActionCtx,
5
+ GenericDatabaseReader,
6
+ GenericDataModel,
7
+ GenericMutationCtx,
8
+ GenericQueryCtx,
9
+ StorageReader,
10
+ } from "convex/server";
11
+ import type {
12
+ ObjectType,
13
+ OptionalProperty,
14
+ PropertyValidators,
15
+ Validator,
16
+ } from "convex/values";
17
+ import type { EmptyObject } from "../react/types";
18
+ import type { TraceAPI } from "./tracer-api/types";
19
+
20
+ export type AnyFunctionReference = FunctionReference<any, any>;
21
+
22
+ export type OptionalArgsObject<Args extends PropertyValidators> =
23
+ keyof Args extends never ? EmptyObject : ObjectType<Args>;
24
+
25
+ export type IfArgs<
26
+ Args extends PropertyValidators,
27
+ T,
28
+ F,
29
+ > = keyof Args extends never ? F : T;
30
+
31
+ export type ExtractOutput<T> = T extends (
32
+ ctx: any,
33
+ args: any,
34
+ ) => Promise<infer R>
35
+ ? R
36
+ : never;
37
+
38
+ export interface TraceContext extends Required<TracerConfig> {
39
+ traceId: string; // Id<"traces"> from component
40
+ spanId: string; // Id<"spans"> from component
41
+ }
42
+
43
+ export type ArgsWithTraceContext<Args> = Args & {
44
+ __traceContext?: TraceContext;
45
+ };
46
+
47
+ export interface TracerConfig {
48
+ /**
49
+ * The sample rate for the trace.
50
+ * This is used to determine whether to sample the trace or not.
51
+ * @default - 0.1
52
+ */
53
+ sampleRate?: number;
54
+
55
+ /**
56
+ * Whether to preserve errors.
57
+ * If true, the trace will be preserved on error.
58
+ * If false, the trace will get sampled.
59
+ * @default - true
60
+ */
61
+ preserveErrors?: boolean;
62
+
63
+ /**
64
+ * The amount of time to wait before sampling or deleting the trace.
65
+ * This is used to prevent tracing of long-running functions.
66
+ * @default - 120
67
+ */
68
+ retentionMinutes?: number;
69
+ }
70
+
71
+ export type LogArgs<Args extends PropertyValidators> = IfArgs<
72
+ Args,
73
+ boolean | Array<keyof ObjectType<Args>> | undefined,
74
+ EmptyObject
75
+ >;
76
+
77
+ export interface TracedFunctionOptions<
78
+ Ctx,
79
+ Args extends PropertyValidators,
80
+ Output,
81
+ > {
82
+ /**
83
+ * The name of the traced function.
84
+ * This is used to identify the function in the DB or UI.
85
+ * @default - anonymous_function
86
+ */
87
+ name?: string;
88
+
89
+ /**
90
+ * Whether to log the arguments of the function.
91
+ * This can be a boolean or an array of argument names to log.
92
+ * @default - false
93
+ * @example
94
+ * ```ts
95
+ * logArgs: true, // Logs all arguments
96
+ * logArgs: ["userId", "title"], // Logs only the userId and title arguments
97
+ * ```
98
+ */
99
+ logArgs?: LogArgs<Args>;
100
+
101
+ /**
102
+ * Whether to log the return value of the function.
103
+ * @default - false
104
+ */
105
+ logReturn?: boolean;
106
+
107
+ /**
108
+ * The sample rate for the trace.
109
+ * This is used to determine whether to sample the trace or not.
110
+ * If undefined, the Tracer config will be used
111
+ * @default - 0.1
112
+ */
113
+ sampleRate?: number;
114
+
115
+ /** The retention minutes for the trace.
116
+ * This is used to determine how long to keep the trace.
117
+ * If undefined, the Tracer config will be used
118
+ * @default - 120
119
+ */
120
+ retentionMinutes?: number;
121
+
122
+ /** Whether to preserve errors.
123
+ * If true, the trace will be preserved on error.
124
+ * If undefined, the Tracer config will be used
125
+ * @default - undefined
126
+ */
127
+ preserveErrors?: boolean;
128
+
129
+ /**
130
+ * A callback to run before the function starts.
131
+ * @param {any} ctx - The context object.
132
+ * @param {ObjectType<Args>} args - The arguments object.
133
+ * @returns {void | Promise<void>}
134
+ * @example
135
+ * ```ts
136
+ * onStart: async (ctx, args) => {
137
+ * // do something before the function starts
138
+ * await ctx.tracer.info("Starting Processing...");
139
+ * }
140
+ * ```
141
+ */
142
+ onStart?: (ctx: Ctx, args: OptionalArgsObject<Args>) => void | Promise<void>;
143
+
144
+ /**
145
+ * A callback to run after the function succeeds.
146
+ * @param {any} ctx - The context object.
147
+ * @param {ObjectType<Args>} args - The arguments object.
148
+ * @param {unknown} result - The result of the function.
149
+ * @returns {void | Promise<void>}
150
+ * @example
151
+ * ```ts
152
+ * onSuccess: async (ctx, args, result) => {
153
+ * // do something with the result
154
+ * await ctx.tracer.info("Successfully processed");
155
+ * }
156
+ * ```
157
+ */
158
+ onSuccess?: (
159
+ ctx: Ctx,
160
+ args: OptionalArgsObject<Args>,
161
+ result: Output,
162
+ ) => void | Promise<void>;
163
+
164
+ /**
165
+ * A callback to run after the function fails.
166
+ * @param {any} ctx - The context object.
167
+ * @param {ObjectType<Args>} args - The arguments object.
168
+ * @param {Error} error - The error that occurred.
169
+ * @returns {void | Promise<void>}
170
+ * @example
171
+ * ```ts
172
+ * onError: async (ctx, args, error) => {
173
+ * // do something to handle the error
174
+ * await ctx.tracer.error("Failed to process", { error: error.message });
175
+ * }
176
+ * ```
177
+ */
178
+ onError?: (
179
+ ctx: Ctx,
180
+ args: OptionalArgsObject<Args>,
181
+ error: Error,
182
+ ) => void | Promise<void>;
183
+ }
184
+
185
+ export type TracerHandler<Ctx, Args extends PropertyValidators> = (
186
+ ctx: Ctx,
187
+ args: OptionalArgsObject<Args>,
188
+ ) => Promise<any>;
189
+
190
+ export type TracedFunctionConfig<
191
+ Ctx,
192
+ Args extends PropertyValidators,
193
+ Handler extends TracerHandler<Ctx, Args>,
194
+ Output extends ExtractOutput<Handler>,
195
+ > = TracedFunctionOptions<Ctx, Args, Output> & {
196
+ args?: Args;
197
+ handler: Handler;
198
+ returns?: Validator<Output, OptionalProperty, any>;
199
+ };
200
+
201
+ export type TracerArgs<Args extends PropertyValidators> = ObjectType<
202
+ Args & { __traceContext?: TraceContext }
203
+ >;
204
+
205
+ export type TracedFunctionTypes = Exclude<FunctionType, "query">;
206
+
207
+ export type TracedFunction<Type extends TracedFunctionTypes> = <
208
+ FuncRef extends FunctionReference<Type, any, any, any>,
209
+ >(
210
+ funcRef: FuncRef,
211
+ args?: Omit<FuncRef["_args"], "__traceContext">,
212
+ ) => Promise<FuncRef["_returnType"]>;
213
+
214
+ type RestrictedQueryContext<DataModel extends GenericDataModel> = Omit<
215
+ GenericMutationCtx<DataModel>,
216
+ "runMutation" | "scheduler" | "db" | "storage"
217
+ > & {
218
+ db: GenericDatabaseReader<DataModel>;
219
+ storage: StorageReader;
220
+ };
221
+
222
+ export type QueryCtxWithTracer<DataModel extends GenericDataModel> =
223
+ RestrictedQueryContext<DataModel> & {
224
+ tracer: TraceAPI;
225
+ runTracedQuery: TracedFunction<"mutation">;
226
+ };
227
+
228
+ export type MutationCtxWithTracer<DataModel extends GenericDataModel> =
229
+ GenericMutationCtx<DataModel> & {
230
+ tracer: TraceAPI;
231
+ runTracedQuery: TracedFunction<"mutation">;
232
+ runTracedMutation: TracedFunction<"mutation">;
233
+ };
234
+
235
+ export type ActionCtxWithTracer<DataModel extends GenericDataModel> =
236
+ GenericActionCtx<DataModel> & {
237
+ tracer: TraceAPI;
238
+ runTracedQuery: TracedFunction<"mutation">;
239
+ runTracedMutation: TracedFunction<"mutation">;
240
+ runTracedAction: TracedFunction<"action">;
241
+ };
242
+
243
+ export type TracedFunctionContext<DataModel extends GenericDataModel> =
244
+ | QueryCtxWithTracer<DataModel>
245
+ | MutationCtxWithTracer<DataModel>
246
+ | ActionCtxWithTracer<DataModel>;
247
+
248
+ export type StrippedGenericFunctionContext<DataModel extends GenericDataModel> =
249
+ GenericMutationCtx<DataModel> | GenericActionCtx<DataModel>;
250
+
251
+ export type GenericFunctionContext<DataModel extends GenericDataModel> =
252
+ | GenericQueryCtx<DataModel>
253
+ | StrippedGenericFunctionContext<DataModel>;
254
+
255
+ export type TracedResult<Output> =
256
+ | { success: true; data: Output; error: undefined }
257
+ | { success: false; data: undefined; error: string };
@@ -0,0 +1,52 @@
1
+ /* eslint-disable */
2
+ /**
3
+ * Generated `api` utility.
4
+ *
5
+ * THIS CODE IS AUTOMATICALLY GENERATED.
6
+ *
7
+ * To regenerate, run `npx convex dev`.
8
+ * @module
9
+ */
10
+
11
+ import type * as lib from "../lib.js";
12
+ import type * as types from "../types.js";
13
+
14
+ import type {
15
+ ApiFromModules,
16
+ FilterApi,
17
+ FunctionReference,
18
+ } from "convex/server";
19
+ import { anyApi, componentsGeneric } from "convex/server";
20
+
21
+ const fullApi: ApiFromModules<{
22
+ lib: typeof lib;
23
+ types: typeof types;
24
+ }> = anyApi as any;
25
+
26
+ /**
27
+ * A utility for referencing Convex functions in your app's public API.
28
+ *
29
+ * Usage:
30
+ * ```js
31
+ * const myFunctionReference = api.myModule.myFunction;
32
+ * ```
33
+ */
34
+ export const api: FilterApi<
35
+ typeof fullApi,
36
+ FunctionReference<any, "public">
37
+ > = anyApi as any;
38
+
39
+ /**
40
+ * A utility for referencing Convex functions in your app's internal API.
41
+ *
42
+ * Usage:
43
+ * ```js
44
+ * const myFunctionReference = internal.myModule.myFunction;
45
+ * ```
46
+ */
47
+ export const internal: FilterApi<
48
+ typeof fullApi,
49
+ FunctionReference<any, "internal">
50
+ > = anyApi as any;
51
+
52
+ export const components = componentsGeneric() as unknown as {};