@confect/core 10.0.0-next.2 → 10.0.0-next.20

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 (94) hide show
  1. package/CHANGELOG.md +518 -0
  2. package/README.md +3 -1
  3. package/dist/FunctionProvenance.d.ts +155 -65
  4. package/dist/FunctionProvenance.d.ts.map +1 -1
  5. package/dist/FunctionProvenance.js +51 -10
  6. package/dist/FunctionProvenance.js.map +1 -1
  7. package/dist/FunctionSpec.d.ts +314 -138
  8. package/dist/FunctionSpec.d.ts.map +1 -1
  9. package/dist/FunctionSpec.js +50 -13
  10. package/dist/FunctionSpec.js.map +1 -1
  11. package/dist/GenericId.d.ts.map +1 -1
  12. package/dist/GenericId.js +1 -1
  13. package/dist/GroupPath.d.ts +1 -4
  14. package/dist/GroupPath.d.ts.map +1 -1
  15. package/dist/GroupPath.js.map +1 -1
  16. package/dist/GroupSpec.d.ts +16 -10
  17. package/dist/GroupSpec.d.ts.map +1 -1
  18. package/dist/GroupSpec.js +34 -11
  19. package/dist/GroupSpec.js.map +1 -1
  20. package/dist/Identifier.d.ts.map +1 -1
  21. package/dist/Lazy.d.ts +2 -3
  22. package/dist/Lazy.d.ts.map +1 -1
  23. package/dist/Lazy.js +2 -3
  24. package/dist/Lazy.js.map +1 -1
  25. package/dist/MiddlewareSpec.d.ts +184 -0
  26. package/dist/MiddlewareSpec.d.ts.map +1 -0
  27. package/dist/MiddlewareSpec.js +55 -0
  28. package/dist/MiddlewareSpec.js.map +1 -0
  29. package/dist/PaginationError.d.ts +14 -0
  30. package/dist/PaginationError.d.ts.map +1 -0
  31. package/dist/PaginationError.js +25 -0
  32. package/dist/PaginationError.js.map +1 -0
  33. package/dist/PaginationOptions.d.ts +23 -0
  34. package/dist/PaginationOptions.d.ts.map +1 -0
  35. package/dist/PaginationOptions.js +29 -0
  36. package/dist/PaginationOptions.js.map +1 -0
  37. package/dist/PaginationResult.d.ts +1 -0
  38. package/dist/PaginationResult.d.ts.map +1 -1
  39. package/dist/PaginationResult.js.map +1 -1
  40. package/dist/Ref.d.ts +120 -39
  41. package/dist/Ref.d.ts.map +1 -1
  42. package/dist/Ref.js +94 -38
  43. package/dist/Ref.js.map +1 -1
  44. package/dist/Refs.d.ts +9 -4
  45. package/dist/Refs.d.ts.map +1 -1
  46. package/dist/Refs.js +3 -3
  47. package/dist/Refs.js.map +1 -1
  48. package/dist/SchemaToValidator.d.ts +99 -0
  49. package/dist/SchemaToValidator.d.ts.map +1 -0
  50. package/dist/SchemaToValidator.js +156 -0
  51. package/dist/SchemaToValidator.js.map +1 -0
  52. package/dist/Spec.d.ts +3 -2
  53. package/dist/Spec.d.ts.map +1 -1
  54. package/dist/Spec.js +1 -1
  55. package/dist/Spec.js.map +1 -1
  56. package/dist/SystemFields.d.ts +1 -1
  57. package/dist/SystemFields.d.ts.map +1 -1
  58. package/dist/SystemFields.js +2 -2
  59. package/dist/SystemFields.js.map +1 -1
  60. package/dist/Table.d.ts +74 -0
  61. package/dist/Table.d.ts.map +1 -0
  62. package/dist/Table.js +77 -0
  63. package/dist/Table.js.map +1 -0
  64. package/dist/Types.d.ts +8 -2
  65. package/dist/Types.d.ts.map +1 -1
  66. package/dist/Types.js.map +1 -1
  67. package/dist/UserIdentity.d.ts.map +1 -1
  68. package/dist/index.d.ts +5 -1
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +7 -3
  71. package/package.json +14 -13
  72. package/src/FunctionProvenance.ts +187 -31
  73. package/src/FunctionSpec.ts +313 -85
  74. package/src/GroupPath.ts +1 -6
  75. package/src/GroupSpec.ts +125 -18
  76. package/src/Lazy.ts +2 -3
  77. package/src/MiddlewareSpec.ts +356 -0
  78. package/src/PaginationError.ts +72 -0
  79. package/src/PaginationOptions.ts +23 -0
  80. package/src/PaginationResult.ts +4 -0
  81. package/src/Ref.ts +429 -208
  82. package/src/Refs.ts +41 -16
  83. package/src/SchemaToValidator.ts +601 -0
  84. package/src/Spec.ts +4 -4
  85. package/src/SystemFields.ts +3 -6
  86. package/src/Table.ts +426 -0
  87. package/src/Types.ts +9 -3
  88. package/src/index.ts +5 -1
  89. package/dist/Registry.d.ts +0 -24
  90. package/dist/Registry.d.ts.map +0 -1
  91. package/dist/Registry.js +0 -19
  92. package/dist/Registry.js.map +0 -1
  93. package/dist/tsconfig.src.tsbuildinfo +0 -1
  94. package/src/Registry.ts +0 -30
package/src/Ref.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  import type {
2
+ DefaultFunctionArgs,
2
3
  FunctionReference as ConvexFunctionReference,
3
4
  FunctionVisibility,
5
+ PaginationOptions,
6
+ PaginationResult,
4
7
  } from "convex/server";
5
8
  import { makeFunctionReference } from "convex/server";
6
9
  import type { Value } from "convex/values";
@@ -9,175 +12,307 @@ import * as Effect from "effect/Effect";
9
12
  import * as Match from "effect/Match";
10
13
  import * as Option from "effect/Option";
11
14
  import * as Schema from "effect/Schema";
15
+ import type * as FunctionProvenance from "./FunctionProvenance";
12
16
  import type * as FunctionSpec from "./FunctionSpec";
17
+ import * as Lazy from "./Lazy";
18
+ import * as MiddlewareSpec from "./MiddlewareSpec";
13
19
  import type * as RuntimeAndFunctionType from "./RuntimeAndFunctionType";
14
20
 
15
- export interface Ref<
16
- _RuntimeAndFunctionType extends RuntimeAndFunctionType.RuntimeAndFunctionType,
17
- _FunctionVisibility extends FunctionVisibility,
18
- _Args,
19
- _Returns,
20
- _Error = never,
21
+ export interface Base<
22
+ RuntimeAndFunctionType_ extends RuntimeAndFunctionType.RuntimeAndFunctionType,
23
+ FunctionVisibility_ extends FunctionVisibility,
24
+ Args_ extends DefaultFunctionArgs,
25
+ Returns_,
26
+ Error_ = never,
21
27
  > {
22
- readonly _RuntimeAndFunctionType?: _RuntimeAndFunctionType;
23
- readonly _FunctionVisibility?: _FunctionVisibility;
24
- readonly _Args?: _Args;
25
- readonly _Returns?: _Returns;
26
- readonly _Error?: _Error;
27
- /** @internal */
28
- readonly functionSpec: FunctionSpec.AnyWithProps;
29
- /** @internal */
30
- readonly functionNamespace: string;
28
+ readonly "~RuntimeAndFunctionType": RuntimeAndFunctionType_;
29
+ readonly "~FunctionVisibility": FunctionVisibility_;
30
+ readonly "~Args": Args_;
31
+ readonly "~Returns": Returns_;
32
+ readonly "~Error": Error_;
33
+ readonly convexFunctionName: string;
31
34
  }
32
35
 
33
- export interface Any extends Ref<any, any, any, any, any> {}
36
+ /**
37
+ * A reference to a single Convex function, as callers see it: the wire name
38
+ * plus the data needed to encode args, decode returns, and decode typed
39
+ * errors. A ref is one of two shapes, keyed by the spec's provenance.
40
+ */
41
+ export type Ref<
42
+ RuntimeAndFunctionType_ extends RuntimeAndFunctionType.RuntimeAndFunctionType,
43
+ FunctionVisibility_ extends FunctionVisibility,
44
+ Args_ extends DefaultFunctionArgs,
45
+ Returns_,
46
+ Error_ = never,
47
+ > =
48
+ | ConfectRefWithTypes<
49
+ RuntimeAndFunctionType_,
50
+ FunctionVisibility_,
51
+ FunctionProvenance.ArgsFields,
52
+ Args_,
53
+ Returns_,
54
+ Error_
55
+ >
56
+ | ConvexRef<
57
+ RuntimeAndFunctionType_,
58
+ FunctionVisibility_,
59
+ Args_,
60
+ Returns_,
61
+ Error_
62
+ >;
63
+
64
+ export type ConfectRef<
65
+ RuntimeAndFunctionType_ extends RuntimeAndFunctionType.RuntimeAndFunctionType,
66
+ FunctionVisibility_ extends FunctionVisibility,
67
+ ArgsFields_ extends FunctionProvenance.ArgsFields,
68
+ ReturnsSchema_ extends Schema.Codec<any, any>,
69
+ ErrorSchema_ extends Schema.Codec<any, any> = never,
70
+ MiddlewareError_ = never,
71
+ > = ConfectRefWithTypes<
72
+ RuntimeAndFunctionType_,
73
+ FunctionVisibility_,
74
+ ArgsFields_,
75
+ Schema.Struct.Type<ArgsFields_>,
76
+ ReturnsSchema_["Type"],
77
+ ErrorSchema_["Type"] | MiddlewareError_
78
+ >;
79
+
80
+ /**
81
+ * Internal form used while mapping a spec to a ref. Supplying the already
82
+ * derived value types avoids repeatedly expanding `Schema.Struct` for every
83
+ * leaf in a generated ref tree; the public `ConfectRef` alias still derives
84
+ * the same values from its fields and schemas.
85
+ */
86
+ interface ConfectRefWithTypes<
87
+ RuntimeAndFunctionType_ extends RuntimeAndFunctionType.RuntimeAndFunctionType,
88
+ FunctionVisibility_ extends FunctionVisibility,
89
+ ArgsFields_ extends FunctionProvenance.ArgsFields,
90
+ Args_ extends DefaultFunctionArgs,
91
+ Returns_,
92
+ Error_,
93
+ > extends Base<
94
+ RuntimeAndFunctionType_,
95
+ FunctionVisibility_,
96
+ Args_,
97
+ Returns_,
98
+ Error_
99
+ > {
100
+ readonly _tag: "Confect";
101
+ readonly args: FunctionProvenance.ArgsSchema<ArgsFields_>;
102
+ readonly returns: Schema.Codec<any, any>;
103
+ readonly kind: FunctionProvenance.ConfectKind;
104
+ readonly middlewareSpecs: ReadonlyArray<MiddlewareSpec.AnyMiddlewareSpec>;
105
+ readonly error?: Schema.Codec<any, any>;
106
+ }
107
+
108
+ export interface ConvexRef<
109
+ RuntimeAndFunctionType_ extends RuntimeAndFunctionType.RuntimeAndFunctionType,
110
+ FunctionVisibility_ extends FunctionVisibility,
111
+ Args_ extends DefaultFunctionArgs,
112
+ Returns_,
113
+ Error_ = never,
114
+ > extends Base<
115
+ RuntimeAndFunctionType_,
116
+ FunctionVisibility_,
117
+ Args_,
118
+ Returns_,
119
+ Error_
120
+ > {
121
+ readonly _tag: "Convex";
122
+ }
34
123
 
35
- export interface AnyInternal extends Ref<any, "internal", any, any, any> {}
124
+ export type Any = Ref<any, any, any, any, any>;
36
125
 
37
- export interface AnyPublic extends Ref<any, "public", any, any, any> {}
126
+ /** Erased Confect-provenance ref used by provenance-specific APIs. */
127
+ export type AnyConfect = Extract<Any, { readonly _tag: "Confect" }>;
38
128
 
39
- export interface AnyQuery extends Ref<
129
+ export type AnyInternal = Ref<any, "internal", any, any, any>;
130
+
131
+ export type AnyPublic = Ref<any, "public", any, any, any>;
132
+
133
+ export type AnyQuery = Ref<
40
134
  RuntimeAndFunctionType.AnyQuery,
41
135
  FunctionVisibility,
42
136
  any,
43
137
  any,
44
138
  any
45
- > {}
139
+ >;
140
+
141
+ export type AnyPaginatedQuery = AnyQuery &
142
+ Base<
143
+ RuntimeAndFunctionType.AnyQuery,
144
+ FunctionVisibility,
145
+ {
146
+ [key: string]: any;
147
+ paginationOpts: PaginationOptions;
148
+ },
149
+ PaginationResult<any>,
150
+ any
151
+ >;
46
152
 
47
- export interface AnyMutation extends Ref<
153
+ export type AnyMutation = Ref<
48
154
  RuntimeAndFunctionType.AnyMutation,
49
155
  FunctionVisibility,
50
156
  any,
51
157
  any,
52
158
  any
53
- > {}
159
+ >;
54
160
 
55
- export interface AnyAction extends Ref<
161
+ export type AnyAction = Ref<
56
162
  RuntimeAndFunctionType.AnyAction,
57
163
  FunctionVisibility,
58
164
  any,
59
165
  any,
60
166
  any
61
- > {}
167
+ >;
62
168
 
63
- export interface AnyPublicQuery extends Ref<
169
+ export type AnyPublicQuery = Ref<
64
170
  RuntimeAndFunctionType.AnyQuery,
65
171
  "public",
66
172
  any,
67
173
  any,
68
174
  any
69
- > {}
175
+ >;
176
+
177
+ export type AnyConfectPublicQuery = Extract<AnyPublicQuery, AnyConfect>;
178
+
179
+ export type AnyPublicPaginatedQuery = AnyPublicQuery & AnyPaginatedQuery;
70
180
 
71
- export interface AnyPublicMutation extends Ref<
181
+ export type AnyConfectPublicPaginatedQuery = AnyConfectPublicQuery &
182
+ AnyPublicPaginatedQuery;
183
+
184
+ export type AnyPublicMutation = Ref<
72
185
  RuntimeAndFunctionType.AnyMutation,
73
186
  "public",
74
187
  any,
75
188
  any,
76
189
  any
77
- > {}
190
+ >;
191
+
192
+ export type AnyConfectPublicMutation = Extract<AnyPublicMutation, AnyConfect>;
78
193
 
79
- export interface AnyPublicAction extends Ref<
194
+ export type AnyPublicAction = Ref<
80
195
  RuntimeAndFunctionType.AnyAction,
81
196
  "public",
82
197
  any,
83
198
  any,
84
199
  any
85
- > {}
86
-
87
- export type GetRuntimeAndFunctionType<Ref_> =
88
- Ref_ extends Ref<
89
- infer RuntimeAndFunctionType_,
90
- infer _FunctionVisibility,
91
- infer _Args,
92
- infer _Returns,
93
- infer _Error
94
- >
95
- ? RuntimeAndFunctionType_
96
- : never;
97
-
98
- export type GetRuntime<Ref_> =
99
- Ref_ extends Ref<
100
- infer RuntimeAndFunctionType_,
101
- infer _FunctionVisibility,
102
- infer _Args,
103
- infer _Returns,
104
- infer _Error
105
- >
106
- ? RuntimeAndFunctionType.GetRuntime<RuntimeAndFunctionType_>
107
- : never;
108
-
109
- export type GetFunctionType<Ref_> =
110
- Ref_ extends Ref<
111
- infer RuntimeAndFunctionType_,
112
- infer _FunctionVisibility,
113
- infer _Args,
114
- infer _Returns,
115
- infer _Error
116
- >
117
- ? RuntimeAndFunctionType.GetFunctionType<RuntimeAndFunctionType_>
118
- : never;
119
-
120
- export type GetFunctionVisibility<Ref_> =
121
- Ref_ extends Ref<
122
- infer _RuntimeAndFunctionType,
123
- infer FunctionVisibility_,
124
- infer _Args,
125
- infer _Returns,
126
- infer _Error
127
- >
128
- ? FunctionVisibility_
129
- : never;
130
-
131
- export type Args<Ref_> =
132
- Ref_ extends Ref<
133
- infer _RuntimeAndFunctionType,
134
- infer _FunctionVisibility,
135
- infer Args_,
136
- infer _Returns,
137
- infer _Error
138
- >
139
- ? Args_
140
- : never;
200
+ >;
201
+
202
+ export type AnyConfectPublicAction = Extract<AnyPublicAction, AnyConfect>;
203
+
204
+ export type GetRuntimeAndFunctionType<Ref_> = Ref_ extends {
205
+ readonly "~RuntimeAndFunctionType": infer RuntimeAndFunctionType_ extends
206
+ RuntimeAndFunctionType.RuntimeAndFunctionType;
207
+ }
208
+ ? RuntimeAndFunctionType_
209
+ : never;
210
+
211
+ export type GetRuntime<Ref_> = RuntimeAndFunctionType.GetRuntime<
212
+ GetRuntimeAndFunctionType<Ref_>
213
+ >;
214
+
215
+ export type GetFunctionType<Ref_> = RuntimeAndFunctionType.GetFunctionType<
216
+ GetRuntimeAndFunctionType<Ref_>
217
+ >;
218
+
219
+ export type GetFunctionVisibility<Ref_> = Ref_ extends {
220
+ readonly "~FunctionVisibility": infer FunctionVisibility_;
221
+ }
222
+ ? FunctionVisibility_
223
+ : never;
224
+
225
+ export type Args<Ref_> = Ref_ extends { readonly "~Args": infer Args_ }
226
+ ? Args_
227
+ : never;
228
+
229
+ /** The field map captured by a Confect-provenance ref. */
230
+ export type ArgsFields<Ref_> = Ref_ extends {
231
+ readonly _tag: "Confect";
232
+ readonly args: {
233
+ readonly fields: infer ArgsFields_ extends FunctionProvenance.ArgsFields;
234
+ };
235
+ }
236
+ ? ArgsFields_
237
+ : never;
238
+
239
+ /** The assembled args schema carried by a Confect-provenance ref. */
240
+ export type ArgsSchema<Ref_> = Ref_ extends {
241
+ readonly _tag: "Confect";
242
+ readonly args: infer ArgsSchema_ extends FunctionProvenance.AnyArgsSchema;
243
+ }
244
+ ? ArgsSchema_
245
+ : never;
141
246
 
142
247
  export type OptionalArgs<Ref_ extends Any> = keyof Args<Ref_> extends never
143
248
  ? [args?: Args<Ref_>]
144
249
  : [args: Args<Ref_>];
145
250
 
146
- export type Returns<Ref_> =
147
- Ref_ extends Ref<
148
- infer _RuntimeAndFunctionType,
149
- infer _FunctionVisibility,
150
- infer _Args,
151
- infer Returns_,
152
- infer _Error
153
- >
154
- ? Returns_
155
- : never;
156
-
157
- export type Error<Ref_> =
158
- Ref_ extends Ref<
159
- infer _RuntimeAndFunctionType,
160
- infer _FunctionVisibility,
161
- infer _Args,
162
- infer _Returns,
163
- infer Error_
164
- >
165
- ? Error_
166
- : never;
251
+ export type Returns<Ref_> = Ref_ extends { readonly "~Returns": infer Returns_ }
252
+ ? Returns_
253
+ : never;
254
+
255
+ export type Error<Ref_> = Ref_ extends { readonly "~Error": infer Error_ }
256
+ ? Error_
257
+ : never;
167
258
 
168
259
  export type FunctionReference<Ref_ extends Any> = ConvexFunctionReference<
169
260
  GetFunctionType<Ref_>,
170
261
  GetFunctionVisibility<Ref_>
171
262
  >;
172
263
 
173
- export type FromFunctionSpec<FunctionSpec_ extends FunctionSpec.AnyWithProps> =
174
- Ref<
175
- FunctionSpec.GetRuntimeAndFunctionType<FunctionSpec_>,
176
- FunctionSpec.GetFunctionVisibility<FunctionSpec_>,
177
- FunctionSpec.Args<FunctionSpec_>,
178
- FunctionSpec.Returns<FunctionSpec_>,
179
- FunctionSpec.Error<FunctionSpec_>
180
- >;
264
+ export type FromFunctionSpec<
265
+ FunctionSpec_ extends FunctionSpec.AnyWithProps,
266
+ MiddlewareError = never,
267
+ > = FromFunctionSpecHelper<
268
+ FunctionSpec_,
269
+ FunctionSpec.GetRuntimeAndFunctionType<FunctionSpec_>,
270
+ FunctionSpec.GetFunctionVisibility<FunctionSpec_>,
271
+ FunctionSpec.ArgsFields<FunctionSpec_>,
272
+ FunctionSpec.Args<FunctionSpec_>,
273
+ FunctionSpec.Returns<FunctionSpec_>,
274
+ FunctionSpec.Error<FunctionSpec_> | MiddlewareError
275
+ >;
276
+
277
+ type FromFunctionSpecHelper<
278
+ FunctionSpec_ extends FunctionSpec.AnyWithProps,
279
+ RuntimeAndFunctionType_ extends RuntimeAndFunctionType.RuntimeAndFunctionType,
280
+ FunctionVisibility_ extends FunctionVisibility,
281
+ ArgsFields_ extends FunctionProvenance.ArgsFields,
282
+ Args_ extends DefaultFunctionArgs,
283
+ Returns_,
284
+ Error_,
285
+ > =
286
+ FunctionSpec_ extends FunctionSpec.WithFunctionProvenance<
287
+ FunctionSpec_,
288
+ FunctionProvenance.AnyConvex
289
+ >
290
+ ? ConvexRef<
291
+ RuntimeAndFunctionType_,
292
+ FunctionVisibility_,
293
+ Args_ extends DefaultFunctionArgs ? Args_ : never,
294
+ Returns_,
295
+ never
296
+ >
297
+ : FunctionSpec_ extends FunctionSpec.WithFunctionProvenance<
298
+ FunctionSpec_,
299
+ FunctionProvenance.AnyConfect
300
+ >
301
+ ? ConfectRefWithTypes<
302
+ RuntimeAndFunctionType_,
303
+ FunctionVisibility_,
304
+ ArgsFields_,
305
+ Args_,
306
+ Returns_,
307
+ Error_
308
+ >
309
+ : Ref<
310
+ RuntimeAndFunctionType_,
311
+ FunctionVisibility_,
312
+ Args_,
313
+ Returns_,
314
+ Error_
315
+ >;
181
316
 
182
317
  export const make = <FunctionSpec_ extends FunctionSpec.AnyWithProps>(
183
318
  /**
@@ -185,36 +320,74 @@ export const make = <FunctionSpec_ extends FunctionSpec.AnyWithProps>(
185
320
  * colon. For example, for `myGroupDir/myGroupMod:myFunc` this would be
186
321
  * `myGroupDir/myGroupMod`.
187
322
  */
188
- functionNamespace: string,
323
+ convexFunctionNamespace: string,
189
324
  functionSpec: FunctionSpec_,
190
- ): FromFunctionSpec<FunctionSpec_> => ({ functionSpec, functionNamespace });
325
+ groupMiddlewareSpecs: ReadonlyArray<MiddlewareSpec.AnyMiddlewareSpec> = [],
326
+ ): FromFunctionSpec<FunctionSpec_> => {
327
+ const convexFunctionName = `${convexFunctionNamespace}:${functionSpec.name}`;
328
+
329
+ return Match.value(functionSpec.functionProvenance).pipe(
330
+ Match.tag(
331
+ "Convex",
332
+ (): Any =>
333
+ ({
334
+ _tag: "Convex",
335
+ convexFunctionName,
336
+ }) as Any,
337
+ ),
338
+ Match.tag("Confect", (provenance): Any => {
339
+ const ref = {
340
+ _tag: "Confect" as const,
341
+ convexFunctionName,
342
+ kind: provenance.kind,
343
+ middlewareSpecs: [
344
+ ...groupMiddlewareSpecs,
345
+ ...functionSpec.middlewareSpecs,
346
+ ],
347
+ };
348
+
349
+ Lazy.defineProperty(ref, "args", () => provenance.args);
350
+ Lazy.defineProperty(ref, "returns", () => provenance.returns);
351
+ if ("error" in provenance) {
352
+ Lazy.defineProperty(ref, "error", () => provenance.error);
353
+ }
354
+
355
+ return ref as unknown as Any;
356
+ }),
357
+ Match.exhaustive,
358
+ ) as FromFunctionSpec<FunctionSpec_>;
359
+ };
191
360
 
192
361
  export const getConvexFunctionName = (ref: Any): string =>
193
- `${ref.functionNamespace}:${ref.functionSpec.name}`;
362
+ ref.convexFunctionName;
194
363
 
195
364
  const functionReferenceCache = new Map<string, FunctionReference<Any>>();
196
365
 
197
366
  export const getFunctionReference = <Ref_ extends Any>(
198
367
  ref: Ref_,
199
368
  ): FunctionReference<Ref_> => {
200
- const functionName = getConvexFunctionName(ref);
369
+ const convexFunctionName = getConvexFunctionName(ref);
201
370
 
202
- const cached = functionReferenceCache.get(functionName);
371
+ const cached = functionReferenceCache.get(convexFunctionName);
203
372
  if (cached !== undefined) {
204
373
  return cached as FunctionReference<Ref_>;
205
374
  }
206
375
 
207
- const functionReference = makeFunctionReference(functionName);
208
- functionReferenceCache.set(functionName, functionReference);
376
+ const functionReference = makeFunctionReference(convexFunctionName);
377
+ functionReferenceCache.set(convexFunctionName, functionReference);
209
378
 
210
379
  return functionReference as FunctionReference<Ref_>;
211
380
  };
212
381
 
213
382
  export const hasErrorSchema = (ref: Any): boolean =>
214
- Match.value(ref.functionSpec.functionProvenance).pipe(
383
+ Match.value(ref).pipe(
215
384
  Match.tag(
216
385
  "Confect",
217
- (confectFunctionProvenance) => "error" in confectFunctionProvenance,
386
+ (confectRef) =>
387
+ "error" in confectRef ||
388
+ confectRef.middlewareSpecs.some(
389
+ (middlewareSpec) => "error" in middlewareSpec,
390
+ ),
218
391
  ),
219
392
  Match.tag("Convex", () => false),
220
393
  Match.exhaustive,
@@ -224,9 +397,9 @@ export const encodeArgs = <Ref_ extends Any>(
224
397
  ref: Ref_,
225
398
  args: Args<Ref_>,
226
399
  ): Effect.Effect<unknown, Schema.SchemaError> =>
227
- Match.value(ref.functionSpec.functionProvenance).pipe(
228
- Match.tag("Confect", (confectFunctionProvenance) =>
229
- Schema.encodeEffect(confectFunctionProvenance.args)(args),
400
+ Match.value<Any>(ref).pipe(
401
+ Match.tag("Confect", (confectRef) =>
402
+ Schema.encodeEffect(confectRef.args)(args),
230
403
  ),
231
404
  Match.tag("Convex", () => Effect.succeed(args)),
232
405
  Match.exhaustive,
@@ -236,11 +409,11 @@ export const decodeReturns = <Ref_ extends Any>(
236
409
  ref: Ref_,
237
410
  returns: unknown,
238
411
  ): Effect.Effect<Returns<Ref_>, Schema.SchemaError> =>
239
- Match.value(ref.functionSpec.functionProvenance).pipe(
240
- Match.tag("Confect", (confectFunctionProvenance) =>
241
- Schema.decodeUnknownEffect(confectFunctionProvenance.returns)(returns),
412
+ Match.value<Any>(ref).pipe(
413
+ Match.tag("Confect", (confectRef) =>
414
+ Schema.decodeUnknownEffect(confectRef.returns)(returns),
242
415
  ),
243
- Match.tag("Convex", () => Effect.succeed(returns)),
416
+ Match.tag("Convex", () => Effect.succeed(returns as Returns<Ref_>)),
244
417
  Match.exhaustive,
245
418
  );
246
419
 
@@ -248,9 +421,9 @@ export const encodeArgsSync = <Ref_ extends Any>(
248
421
  ref: Ref_,
249
422
  args: Args<Ref_>,
250
423
  ): unknown =>
251
- Match.value(ref.functionSpec.functionProvenance).pipe(
252
- Match.tag("Confect", (confectFunctionProvenance) =>
253
- Schema.encodeSync(confectFunctionProvenance.args)(args),
424
+ Match.value<Any>(ref).pipe(
425
+ Match.tag("Confect", (confectRef) =>
426
+ Schema.encodeSync(confectRef.args)(args),
254
427
  ),
255
428
  Match.tag("Convex", () => args),
256
429
  Match.exhaustive,
@@ -260,9 +433,9 @@ export const decodeArgsSync = <Ref_ extends Any>(
260
433
  ref: Ref_,
261
434
  encodedArgs: unknown,
262
435
  ): Args<Ref_> =>
263
- Match.value(ref.functionSpec.functionProvenance).pipe(
264
- Match.tag("Confect", (confectFunctionProvenance) =>
265
- Schema.decodeUnknownSync(confectFunctionProvenance.args)(encodedArgs),
436
+ Match.value<Any>(ref).pipe(
437
+ Match.tag("Confect", (confectRef) =>
438
+ Schema.decodeUnknownSync(confectRef.args)(encodedArgs),
266
439
  ),
267
440
  Match.tag("Convex", () => encodedArgs),
268
441
  Match.exhaustive,
@@ -272,9 +445,9 @@ export const encodeReturnsSync = <Ref_ extends Any>(
272
445
  ref: Ref_,
273
446
  returns: Returns<Ref_>,
274
447
  ): unknown =>
275
- Match.value(ref.functionSpec.functionProvenance).pipe(
276
- Match.tag("Confect", (confectFunctionProvenance) =>
277
- Schema.encodeSync(confectFunctionProvenance.returns)(returns),
448
+ Match.value<Any>(ref).pipe(
449
+ Match.tag("Confect", (confectRef) =>
450
+ Schema.encodeSync(confectRef.returns)(returns),
278
451
  ),
279
452
  Match.tag("Convex", () => returns),
280
453
  Match.exhaustive,
@@ -284,11 +457,9 @@ export const decodeReturnsSync = <Ref_ extends Any>(
284
457
  ref: Ref_,
285
458
  encodedReturns: unknown,
286
459
  ): Returns<Ref_> =>
287
- Match.value(ref.functionSpec.functionProvenance).pipe(
288
- Match.tag("Confect", (confectFunctionProvenance) =>
289
- Schema.decodeUnknownSync(confectFunctionProvenance.returns)(
290
- encodedReturns,
291
- ),
460
+ Match.value<Any>(ref).pipe(
461
+ Match.tag("Confect", (confectRef) =>
462
+ Schema.decodeUnknownSync(confectRef.returns)(encodedReturns),
292
463
  ),
293
464
  Match.tag("Convex", () => encodedReturns),
294
465
  Match.exhaustive,
@@ -315,7 +486,7 @@ export const decodeErrorOrElse =
315
486
  <Ref_ extends Any, E>(ref: Ref_, mapUnknownError: (error: unknown) => E) =>
316
487
  (error: unknown): Error<Ref_> | E => {
317
488
  if (isConvexError(error)) {
318
- const decoded = decodeErrorSync(ref, error.data);
489
+ const decoded = decodeErrorOption(ref, error.data);
319
490
  if (Option.isSome(decoded)) {
320
491
  return decoded.value;
321
492
  }
@@ -323,10 +494,31 @@ export const decodeErrorOrElse =
323
494
  return mapUnknownError(error);
324
495
  };
325
496
 
497
+ const errorSchemaOf = (ref: Any): Option.Option<Schema.Codec<any, any>> =>
498
+ Match.value(ref).pipe(
499
+ Match.tag("Confect", (confectRef) => {
500
+ const schemas = [
501
+ ...("error" in confectRef && confectRef.error !== undefined
502
+ ? [confectRef.error]
503
+ : []),
504
+ ...MiddlewareSpec.errorSchemas(confectRef.middlewareSpecs),
505
+ ];
506
+ return schemas.length === 0
507
+ ? Option.none<Schema.Codec<any, any>>()
508
+ : Option.some(
509
+ schemas.length === 1 ? schemas[0]! : Schema.Union(schemas),
510
+ );
511
+ }),
512
+ Match.tag("Convex", () => Option.none<Schema.Codec<any, any>>()),
513
+ Match.exhaustive,
514
+ );
515
+
326
516
  /**
327
- * Decode `encodedError` against the ref's error schema. Returns `None` if the
328
- * ref doesn't declare a typed error (Confect ref without an `error` schema, or
329
- * a Convex-provenance ref)—by definition there's nothing to decode the value
517
+ * Decode `encodedError` against the ref's error schema — the function's
518
+ * declared `error` schema unioned with its covering middlewares' error
519
+ * schemas. Returns `None` if the ref declares no typed error at all (Confect
520
+ * ref without an `error` schema and without failing middleware, or a
521
+ * Convex-provenance ref)—by definition there's nothing to decode the value
330
522
  * into, and the caller is responsible for deciding what to do (typically:
331
523
  * surface the original value as a defect).
332
524
  */
@@ -334,60 +526,101 @@ export const decodeError = <Ref_ extends Any>(
334
526
  ref: Ref_,
335
527
  encodedError: unknown,
336
528
  ): Effect.Effect<Option.Option<Error<Ref_>>, Schema.SchemaError> =>
337
- Match.value(ref.functionSpec.functionProvenance).pipe(
338
- Match.tag("Confect", (confectFunctionProvenance) =>
339
- "error" in confectFunctionProvenance
340
- ? Effect.map(
341
- Schema.decodeUnknownEffect(confectFunctionProvenance.error)(
342
- encodedError,
343
- ),
344
- Option.some,
345
- )
346
- : Effect.succeed(Option.none<Error<Ref_>>()),
347
- ),
348
- Match.tag("Convex", () => Effect.succeed(Option.none<Error<Ref_>>())),
349
- Match.exhaustive,
350
- );
529
+ Option.match(errorSchemaOf(ref), {
530
+ onNone: () => Effect.succeed(Option.none<Error<Ref_>>()),
531
+ onSome: (schema) =>
532
+ Effect.map(
533
+ Schema.decodeUnknownEffect(schema)(encodedError),
534
+ Option.some,
535
+ ) as Effect.Effect<Option.Option<Error<Ref_>>, Schema.SchemaError>,
536
+ });
351
537
 
352
538
  /**
353
- * Synchronous counterpart to `decodeError`. Throws on schema decode failure;
354
- * returns `None` when the ref doesn't declare a typed error.
539
+ * Synchronous counterpart to `decodeError`. Returns `None` when the value is
540
+ * not this ref's typed error — either because the ref declares no `error`
541
+ * schema, or because `encodedError` doesn't match the one it declares.
542
+ *
543
+ * The second case is reachable in normal operation: Convex raises its own
544
+ * `ConvexError`s (an `InvalidCursor` pagination error, for instance), and
545
+ * those never match a user-declared error schema. Callers pair this with a
546
+ * fallback that surfaces the original error, so failing to decode must not
547
+ * throw — a `ParseError` here would replace the real error with an opaque one
548
+ * and lose the only useful diagnostic. Hence the `Option` suffix rather than
549
+ * `Sync`, matching `Schema.decodeUnknownOption`: the sibling `*Sync` helpers
550
+ * in this module all throw on a parse failure, and this one deliberately
551
+ * doesn't.
355
552
  */
356
- export const decodeErrorSync = <Ref_ extends Any>(
553
+ export const decodeErrorOption = <Ref_ extends Any>(
357
554
  ref: Ref_,
358
555
  encodedError: unknown,
359
556
  ): Option.Option<Error<Ref_>> =>
360
- Match.value(ref.functionSpec.functionProvenance).pipe(
361
- Match.tag("Confect", (confectFunctionProvenance) =>
362
- "error" in confectFunctionProvenance
363
- ? Option.some(
364
- Schema.decodeUnknownSync(confectFunctionProvenance.error)(
365
- encodedError,
366
- ) as Error<Ref_>,
367
- )
368
- : Option.none<Error<Ref_>>(),
369
- ),
370
- Match.tag("Convex", () => Option.none<Error<Ref_>>()),
557
+ Option.flatMap(
558
+ errorSchemaOf(ref),
559
+ (schema) =>
560
+ Schema.decodeUnknownOption(schema)(encodedError) as Option.Option<
561
+ Error<Ref_>
562
+ >,
563
+ );
564
+
565
+ const missingPaginatedProvenanceError = (ref: Any) =>
566
+ new globalThis.Error(
567
+ `Paginated query ref "${getConvexFunctionName(ref)}" was not built with ` +
568
+ "`FunctionSpec.publicPaginatedQuery` (or `FunctionSpec.internalPaginatedQuery`). " +
569
+ "Paginated encoding and decoding require the user-args and item schemas " +
570
+ "those constructors store. Define the function as, e.g.:\n\n" +
571
+ " FunctionSpec.publicPaginatedQuery({\n" +
572
+ ' name: "...",\n' +
573
+ " args: () => ({ ... }), // optional; without paginationOpts\n" +
574
+ " item: () => ItemSchema,\n" +
575
+ " })",
576
+ );
577
+
578
+ const paginatedKind = (ref: AnyConfect): FunctionProvenance.Paginated =>
579
+ Match.value(ref.kind).pipe(
580
+ Match.tag("Paginated", (kind) => kind),
581
+ Match.tag("Standard", () => {
582
+ throw missingPaginatedProvenanceError(ref);
583
+ }),
371
584
  Match.exhaustive,
372
585
  );
373
586
 
374
- export const maybeDecodeErrorSync = <Ref_ extends Any>(
587
+ /**
588
+ * Encode the args of a paginated query ref via its user-args schema —
589
+ * `paginationOpts` is excluded, since the pagination protocol fields are
590
+ * managed by the client (e.g. `usePaginatedQuery` from `convex/react`), not by
591
+ * the caller. Requires a ref built with `FunctionSpec.publicPaginatedQuery`
592
+ * (or `internalPaginatedQuery`).
593
+ */
594
+ export const encodePaginatedQueryArgsSync = <
595
+ Ref_ extends AnyPublicPaginatedQuery,
596
+ >(
375
597
  ref: Ref_,
376
- error: unknown,
598
+ args: Omit<Args<Ref_>, "paginationOpts">,
377
599
  ): unknown =>
378
- isConvexError(error)
379
- ? Match.value(ref.functionSpec.functionProvenance).pipe(
380
- Match.tag("Confect", (confectFunctionProvenance) =>
381
- "error" in confectFunctionProvenance
382
- ? Schema.decodeUnknownSync(confectFunctionProvenance.error)(
383
- error.data,
384
- )
385
- : error,
386
- ),
387
- Match.tag("Convex", () => error),
388
- Match.exhaustive,
389
- )
390
- : error;
600
+ Match.value<Any>(ref).pipe(
601
+ Match.tag("Confect", (confectRef) =>
602
+ Schema.encodeUnknownSync(paginatedKind(confectRef).userArgs)(args),
603
+ ),
604
+ Match.tag("Convex", () => args),
605
+ Match.exhaustive,
606
+ );
607
+
608
+ /**
609
+ * Decode a page of a paginated query's results via the ref's item schema.
610
+ * Requires a ref built with `FunctionSpec.publicPaginatedQuery` (or
611
+ * `internalPaginatedQuery`).
612
+ */
613
+ export const decodePaginationPageSync = <Ref_ extends AnyPublicPaginatedQuery>(
614
+ ref: Ref_,
615
+ encodedPage: unknown,
616
+ ): Returns<Ref_>["page"] =>
617
+ Match.value<Any>(ref).pipe(
618
+ Match.tag("Confect", (confectRef) =>
619
+ Schema.decodeUnknownSync(paginatedKind(confectRef).page)(encodedPage),
620
+ ),
621
+ Match.tag("Convex", () => encodedPage),
622
+ Match.exhaustive,
623
+ ) as Returns<Ref_>["page"];
391
624
 
392
625
  /**
393
626
  * Encode args via the ref's args schema, invoke `call`, decode returns via the
@@ -408,7 +641,6 @@ export const runWithCodec = <Ref_ extends Any, E = never>(
408
641
  ): Effect.Effect<Returns<Ref_>, E | Error<Ref_> | Schema.SchemaError> =>
409
642
  Effect.gen(function* () {
410
643
  const functionReference = getFunctionReference(ref);
411
- const functionProvenance = ref.functionSpec.functionProvenance;
412
644
  const invoke = (
413
645
  encodedArgs: unknown,
414
646
  ): Effect.Effect<unknown, Error<Ref_> | E> =>
@@ -416,7 +648,7 @@ export const runWithCodec = <Ref_ extends Any, E = never>(
416
648
  try: () => Promise.resolve(call(functionReference, encodedArgs)),
417
649
  catch: (error): Error<Ref_> | E => {
418
650
  if (isConvexError(error)) {
419
- const decoded = decodeErrorSync(ref, error.data);
651
+ const decoded = decodeErrorOption(ref, error.data);
420
652
  if (Option.isSome(decoded)) {
421
653
  return decoded.value;
422
654
  }
@@ -427,19 +659,8 @@ export const runWithCodec = <Ref_ extends Any, E = never>(
427
659
  throw error;
428
660
  },
429
661
  });
430
- return yield* Match.value(functionProvenance).pipe(
431
- Match.tag("Confect", (confectFunctionProvenance) =>
432
- Effect.gen(function* () {
433
- const encodedArgs = yield* Schema.encodeEffect(
434
- confectFunctionProvenance.args,
435
- )(args);
436
- const encodedReturns = yield* invoke(encodedArgs);
437
- return yield* Schema.decodeUnknownEffect(
438
- confectFunctionProvenance.returns,
439
- )(encodedReturns);
440
- }),
441
- ),
442
- Match.tag("Convex", () => invoke(args)),
443
- Match.exhaustive,
444
- );
662
+
663
+ const encodedArgs = yield* encodeArgs(ref, args);
664
+ const encodedReturns = yield* invoke(encodedArgs);
665
+ return yield* decodeReturns(ref, encodedReturns);
445
666
  });