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