@confect/core 10.0.0-next.17 → 10.0.0-next.19

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 (68) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/dist/FunctionProvenance.d.ts +81 -60
  3. package/dist/FunctionProvenance.d.ts.map +1 -1
  4. package/dist/FunctionProvenance.js +9 -9
  5. package/dist/FunctionProvenance.js.map +1 -1
  6. package/dist/FunctionSpec.d.ts +256 -144
  7. package/dist/FunctionSpec.d.ts.map +1 -1
  8. package/dist/FunctionSpec.js +25 -20
  9. package/dist/FunctionSpec.js.map +1 -1
  10. package/dist/GroupPath.d.ts +1 -4
  11. package/dist/GroupPath.d.ts.map +1 -1
  12. package/dist/GroupPath.js.map +1 -1
  13. package/dist/GroupSpec.d.ts +5 -3
  14. package/dist/GroupSpec.d.ts.map +1 -1
  15. package/dist/GroupSpec.js +1 -1
  16. package/dist/GroupSpec.js.map +1 -1
  17. package/dist/Lazy.d.ts +2 -3
  18. package/dist/Lazy.d.ts.map +1 -1
  19. package/dist/Lazy.js +2 -3
  20. package/dist/Lazy.js.map +1 -1
  21. package/dist/MiddlewareSpec.d.ts +2 -2
  22. package/dist/MiddlewareSpec.d.ts.map +1 -1
  23. package/dist/MiddlewareSpec.js +1 -1
  24. package/dist/MiddlewareSpec.js.map +1 -1
  25. package/dist/PaginationError.d.ts +14 -0
  26. package/dist/PaginationError.d.ts.map +1 -0
  27. package/dist/PaginationError.js +25 -0
  28. package/dist/PaginationError.js.map +1 -0
  29. package/dist/Ref.d.ts +66 -20
  30. package/dist/Ref.d.ts.map +1 -1
  31. package/dist/Ref.js +3 -3
  32. package/dist/Ref.js.map +1 -1
  33. package/dist/Refs.d.ts +1 -1
  34. package/dist/Refs.d.ts.map +1 -1
  35. package/dist/Refs.js.map +1 -1
  36. package/dist/SchemaToValidator.d.ts +99 -0
  37. package/dist/SchemaToValidator.d.ts.map +1 -0
  38. package/dist/SchemaToValidator.js +156 -0
  39. package/dist/SchemaToValidator.js.map +1 -0
  40. package/dist/Spec.d.ts +3 -2
  41. package/dist/Spec.d.ts.map +1 -1
  42. package/dist/Spec.js +1 -1
  43. package/dist/Spec.js.map +1 -1
  44. package/dist/Table.d.ts +74 -0
  45. package/dist/Table.d.ts.map +1 -0
  46. package/dist/Table.js +77 -0
  47. package/dist/Table.js.map +1 -0
  48. package/dist/Types.d.ts +8 -2
  49. package/dist/Types.d.ts.map +1 -1
  50. package/dist/Types.js.map +1 -1
  51. package/dist/index.d.ts +3 -0
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +4 -1
  54. package/package.json +4 -4
  55. package/src/FunctionProvenance.ts +84 -71
  56. package/src/FunctionSpec.ts +193 -110
  57. package/src/GroupPath.ts +1 -6
  58. package/src/GroupSpec.ts +6 -6
  59. package/src/Lazy.ts +2 -3
  60. package/src/MiddlewareSpec.ts +2 -2
  61. package/src/PaginationError.ts +72 -0
  62. package/src/Ref.ts +164 -153
  63. package/src/Refs.ts +1 -0
  64. package/src/SchemaToValidator.ts +601 -0
  65. package/src/Spec.ts +4 -4
  66. package/src/Table.ts +426 -0
  67. package/src/Types.ts +9 -3
  68. package/src/index.ts +3 -0
@@ -1,18 +1,19 @@
1
1
  import type {
2
+ DefaultFunctionArgs,
2
3
  FunctionType,
3
4
  FunctionVisibility,
4
5
  RegisteredAction,
5
6
  RegisteredMutation,
6
7
  RegisteredQuery,
7
8
  } from "convex/server";
8
- import * as Schema from "effect/Schema";
9
+ import type * as Schema from "effect/Schema";
9
10
  import * as Predicate from "effect/Predicate";
10
11
  import * as FunctionProvenance from "./FunctionProvenance";
11
12
  import { validateConfectFunctionIdentifier } from "./Identifier";
12
13
  import type * as MiddlewareSpec from "./MiddlewareSpec";
13
14
  import * as RuntimeAndFunctionType from "./RuntimeAndFunctionType";
14
15
 
15
- export const TypeId = "@confect/core/FunctionSpec";
16
+ export const TypeId = "~@confect/core/FunctionSpec";
16
17
  export type TypeId = typeof TypeId;
17
18
 
18
19
  export const isFunctionSpec = (u: unknown): u is AnyWithProps =>
@@ -127,86 +128,122 @@ export type GetRuntimeAndFunctionType<FunctionSpec_ extends AnyWithProps> =
127
128
  export type GetFunctionVisibility<FunctionSpec_ extends AnyWithProps> =
128
129
  FunctionSpec_["functionVisibility"];
129
130
 
131
+ export type GetFunctionProvenance<FunctionSpec_ extends AnyWithProps> =
132
+ FunctionSpec_["functionProvenance"];
133
+
130
134
  export type Name<FunctionSpec_ extends AnyWithProps> = FunctionSpec_["name"];
131
135
 
132
136
  export type MiddlewareSpecs<FunctionSpec_ extends AnyWithProps> =
133
137
  FunctionSpec_["middlewareSpecs"][number];
134
138
 
139
+ /** The field map declared by a Confect-provenance spec. */
140
+ export type ArgsFields<FunctionSpec_ extends AnyWithProps> =
141
+ FunctionSpec_ extends {
142
+ readonly functionProvenance: {
143
+ readonly _tag: "Confect";
144
+ readonly "~ArgsFields": infer ArgsFields_ extends
145
+ FunctionProvenance.ArgsFields;
146
+ };
147
+ }
148
+ ? ArgsFields_
149
+ : FunctionSpec_ extends {
150
+ readonly functionProvenance: { readonly _tag: "Confect" };
151
+ }
152
+ ? FunctionProvenance.ArgsFields
153
+ : never;
154
+
155
+ /** The args schema assembled from a Confect-provenance spec's field map. */
156
+ export type ArgsSchema<FunctionSpec_ extends AnyWithProps> =
157
+ FunctionSpec_ extends {
158
+ readonly functionProvenance: {
159
+ readonly _tag: "Confect";
160
+ readonly "~ArgsFields": infer ArgsFields_ extends
161
+ FunctionProvenance.ArgsFields;
162
+ };
163
+ }
164
+ ? Schema.Struct<ArgsFields_>
165
+ : FunctionSpec_ extends {
166
+ readonly functionProvenance: {
167
+ readonly _tag: "Confect";
168
+ readonly args: infer ArgsSchema_ extends
169
+ FunctionProvenance.AnyArgsSchema;
170
+ };
171
+ }
172
+ ? ArgsSchema_
173
+ : never;
174
+
175
+ export type ReturnsSchema<FunctionSpec_ extends AnyWithProps> =
176
+ FunctionSpec_ extends {
177
+ readonly functionProvenance: {
178
+ readonly _tag: "Confect";
179
+ readonly returns: infer ReturnsSchema_ extends Schema.Codec<any, any>;
180
+ };
181
+ }
182
+ ? ReturnsSchema_
183
+ : never;
184
+
185
+ export type ErrorSchema<FunctionSpec_ extends AnyWithProps> =
186
+ FunctionSpec_ extends {
187
+ readonly functionProvenance: {
188
+ readonly _tag: "Confect";
189
+ readonly error?: infer ErrorSchema_ extends Schema.Codec<any, any>;
190
+ };
191
+ }
192
+ ? ErrorSchema_
193
+ : never;
194
+
135
195
  export type Args<FunctionSpec_ extends AnyWithProps> = FunctionSpec_ extends {
136
- functionProvenance: {
137
- _tag: "Confect";
138
- args: infer ArgsSchema_ extends Schema.Codec<any, any>;
139
- };
196
+ readonly functionProvenance: { readonly _tag: "Confect" };
140
197
  }
141
- ? ArgsSchema_["Type"]
142
- : FunctionSpec_ extends {
143
- functionProvenance: { _tag: "Convex"; _args: infer Args_ };
144
- }
198
+ ? ArgsSchema<FunctionSpec_>["Type"]
199
+ : GetFunctionProvenance<FunctionSpec_> extends FunctionProvenance.Convex<
200
+ infer Args_,
201
+ any
202
+ >
145
203
  ? Args_
146
204
  : never;
147
205
 
148
206
  export type Returns<FunctionSpec_ extends AnyWithProps> =
149
207
  FunctionSpec_ extends {
150
- functionProvenance: {
151
- _tag: "Confect";
152
- returns: infer ReturnsSchema_ extends Schema.Codec<any, any>;
153
- };
208
+ readonly functionProvenance: { readonly _tag: "Confect" };
154
209
  }
155
- ? ReturnsSchema_["Type"]
156
- : FunctionSpec_ extends {
157
- functionProvenance: { _tag: "Convex"; _returns: infer Returns_ };
158
- }
210
+ ? ReturnsSchema<FunctionSpec_>["Type"]
211
+ : GetFunctionProvenance<FunctionSpec_> extends FunctionProvenance.Convex<
212
+ any,
213
+ infer Returns_
214
+ >
159
215
  ? Awaited<Returns_>
160
216
  : never;
161
217
 
162
218
  export type EncodedArgs<FunctionSpec_ extends AnyWithProps> =
163
219
  FunctionSpec_ extends {
164
- functionProvenance: {
165
- _tag: "Confect";
166
- args: infer ArgsSchema_ extends Schema.Codec<any, any>;
167
- };
220
+ readonly functionProvenance: { readonly _tag: "Confect" };
168
221
  }
169
- ? ArgsSchema_["Encoded"]
170
- : FunctionSpec_ extends {
171
- functionProvenance: { _tag: "Convex"; _args: infer Args_ };
172
- }
222
+ ? ArgsSchema<FunctionSpec_>["Encoded"]
223
+ : GetFunctionProvenance<FunctionSpec_> extends FunctionProvenance.Convex<
224
+ infer Args_,
225
+ any
226
+ >
173
227
  ? Args_
174
228
  : never;
175
229
 
176
230
  export type EncodedReturns<FunctionSpec_ extends AnyWithProps> =
177
231
  FunctionSpec_ extends {
178
- functionProvenance: {
179
- _tag: "Confect";
180
- returns: infer ReturnsSchema_ extends Schema.Codec<any, any>;
181
- };
232
+ readonly functionProvenance: { readonly _tag: "Confect" };
182
233
  }
183
- ? ReturnsSchema_["Encoded"]
184
- : FunctionSpec_ extends {
185
- functionProvenance: { _tag: "Convex"; _returns: infer Returns_ };
186
- }
234
+ ? ReturnsSchema<FunctionSpec_>["Encoded"]
235
+ : GetFunctionProvenance<FunctionSpec_> extends FunctionProvenance.Convex<
236
+ any,
237
+ infer Returns_
238
+ >
187
239
  ? Returns_
188
240
  : never;
189
241
 
190
- export type Error<FunctionSpec_ extends AnyWithProps> = FunctionSpec_ extends {
191
- functionProvenance: FunctionProvenance.Confect<
192
- any,
193
- any,
194
- infer ErrorSchema_ extends Schema.Codec<any, any>
195
- >;
196
- }
197
- ? ErrorSchema_["Type"]
198
- : never;
242
+ export type Error<FunctionSpec_ extends AnyWithProps> =
243
+ ErrorSchema<FunctionSpec_>["Type"];
199
244
 
200
245
  export type EncodedError<FunctionSpec_ extends AnyWithProps> =
201
- FunctionSpec_ extends {
202
- functionProvenance: FunctionProvenance.Confect<
203
- any,
204
- any,
205
- infer ErrorSchema_ extends Schema.Codec<any, any>
206
- >;
207
- }
208
- ? ErrorSchema_["Encoded"]
209
- : never;
246
+ ErrorSchema<FunctionSpec_>["Encoded"];
210
247
 
211
248
  export type WithName<
212
249
  FunctionSpec_ extends AnyWithProps,
@@ -280,46 +317,68 @@ const Proto = {
280
317
  },
281
318
  };
282
319
 
283
- const make =
284
- <
285
- RuntimeAndFunctionType_ extends
286
- RuntimeAndFunctionType.RuntimeAndFunctionType,
287
- FunctionVisibility_ extends FunctionVisibility,
288
- >(
289
- runtimeAndFunctionType: RuntimeAndFunctionType_,
290
- functionVisibility: FunctionVisibility_,
291
- ) =>
292
- <
320
+ interface Options {
321
+ readonly name: string;
322
+ readonly args?: () => FunctionProvenance.ArgsFields;
323
+ readonly returns: () => Schema.Codec<any, any>;
324
+ readonly error?: () => Schema.Codec<any, any>;
325
+ }
326
+
327
+ const make = <
328
+ RuntimeAndFunctionType_ extends RuntimeAndFunctionType.RuntimeAndFunctionType,
329
+ FunctionVisibility_ extends FunctionVisibility,
330
+ >(
331
+ runtimeAndFunctionType: RuntimeAndFunctionType_,
332
+ functionVisibility: FunctionVisibility_,
333
+ ) => {
334
+ function makeSpec<
293
335
  const Name_ extends string,
294
- Args_ extends Schema.Codec<any, any>,
336
+ const ArgsFields_ extends FunctionProvenance.ArgsFields,
295
337
  Returns_ extends Schema.Codec<any, any>,
296
338
  Error_ extends Schema.Codec<any, any> = never,
297
- >({
298
- name,
299
- args,
300
- returns,
301
- error,
302
- }: {
339
+ >(options: {
303
340
  name: Name_;
304
- args: () => Args_;
341
+ args: () => ArgsFields_;
305
342
  returns: () => Returns_;
306
343
  error?: () => Error_;
307
344
  }): Builder<
308
345
  RuntimeAndFunctionType_,
309
346
  FunctionVisibility_,
310
347
  Name_,
311
- FunctionProvenance.Confect<Args_, Returns_, Error_>
312
- > => {
348
+ FunctionProvenance.Confect<ArgsFields_, Returns_, Error_>
349
+ >;
350
+ function makeSpec<
351
+ const Name_ extends string,
352
+ Returns_ extends Schema.Codec<any, any>,
353
+ Error_ extends Schema.Codec<any, any> = never,
354
+ >(options: {
355
+ name: Name_;
356
+ args?: never;
357
+ returns: () => Returns_;
358
+ error?: () => Error_;
359
+ }): Builder<
360
+ RuntimeAndFunctionType_,
361
+ FunctionVisibility_,
362
+ Name_,
363
+ FunctionProvenance.Confect<{}, Returns_, Error_>
364
+ >;
365
+ function makeSpec({ name, args, returns, error }: Options) {
313
366
  validateConfectFunctionIdentifier(name);
314
367
 
315
368
  return Object.assign(Object.create(Proto), {
316
369
  runtimeAndFunctionType,
317
370
  functionVisibility,
318
371
  name,
319
- functionProvenance: FunctionProvenance.Confect(args, returns, error),
372
+ functionProvenance:
373
+ args === undefined
374
+ ? FunctionProvenance.Confect(() => ({}), returns, error)
375
+ : FunctionProvenance.Confect(args, returns, error),
320
376
  middlewareSpecs: [],
321
377
  });
322
- };
378
+ }
379
+
380
+ return makeSpec;
381
+ };
323
382
 
324
383
  /**
325
384
  * `Schema.Struct` fields that must not declare `paginationOpts`. Used to
@@ -327,58 +386,74 @@ const make =
327
386
  * constructors add themselves; the check reports at the `args` thunk with an
328
387
  * unsatisfiable type when violated.
329
388
  */
330
- type ForbidPaginationOpts<UserArgs extends FunctionProvenance.AnyUserArgs> =
331
- "paginationOpts" extends keyof UserArgs["fields"]
332
- ? { readonly fields: { readonly paginationOpts: never } }
333
- : unknown;
389
+ type ForbidPaginationOpts<
390
+ UserArgsFields extends FunctionProvenance.ArgsFields,
391
+ > = "paginationOpts" extends keyof UserArgsFields
392
+ ? { readonly paginationOpts: never }
393
+ : unknown;
394
+
395
+ interface PaginatedOptions {
396
+ readonly name: string;
397
+ readonly args?: () => FunctionProvenance.ArgsFields;
398
+ readonly item: () => Schema.Codec<any, any>;
399
+ readonly error?: () => Schema.Codec<any, any>;
400
+ }
334
401
 
335
- const makePaginated =
336
- <
337
- RuntimeAndFunctionType_ extends
338
- RuntimeAndFunctionType.RuntimeAndFunctionType,
339
- FunctionVisibility_ extends FunctionVisibility,
340
- >(
341
- runtimeAndFunctionType: RuntimeAndFunctionType_,
342
- functionVisibility: FunctionVisibility_,
343
- ) =>
344
- <
402
+ const makePaginated = <
403
+ RuntimeAndFunctionType_ extends RuntimeAndFunctionType.RuntimeAndFunctionType,
404
+ FunctionVisibility_ extends FunctionVisibility,
405
+ >(
406
+ runtimeAndFunctionType: RuntimeAndFunctionType_,
407
+ functionVisibility: FunctionVisibility_,
408
+ ) => {
409
+ function makeSpec<
345
410
  const Name_ extends string,
411
+ const UserArgsFields_ extends FunctionProvenance.ArgsFields,
346
412
  Item_ extends Schema.Codec<any, any>,
347
- UserArgs_ extends FunctionProvenance.AnyUserArgs = Schema.Struct<{}>,
348
413
  Error_ extends Schema.Codec<any, any> = never,
349
- >({
350
- name,
351
- args,
352
- item,
353
- error,
354
- }: {
414
+ >(options: {
355
415
  name: Name_;
356
- /** User-declared args, without `paginationOpts` — it is added automatically. */
357
- args?: (() => UserArgs_) & ForbidPaginationOpts<UserArgs_>;
358
- /** The page element schema. */
416
+ args: () => UserArgsFields_ & ForbidPaginationOpts<UserArgsFields_>;
359
417
  item: () => Item_;
360
418
  error?: () => Error_;
361
419
  }): Builder<
362
420
  RuntimeAndFunctionType_,
363
421
  FunctionVisibility_,
364
422
  Name_,
365
- FunctionProvenance.ConfectPaginated<UserArgs_, Item_, Error_>
366
- > => {
423
+ FunctionProvenance.ConfectPaginated<UserArgsFields_, Item_, Error_>
424
+ >;
425
+ function makeSpec<
426
+ const Name_ extends string,
427
+ Item_ extends Schema.Codec<any, any>,
428
+ Error_ extends Schema.Codec<any, any> = never,
429
+ >(options: {
430
+ name: Name_;
431
+ args?: never;
432
+ item: () => Item_;
433
+ error?: () => Error_;
434
+ }): Builder<
435
+ RuntimeAndFunctionType_,
436
+ FunctionVisibility_,
437
+ Name_,
438
+ FunctionProvenance.ConfectPaginated<{}, Item_, Error_>
439
+ >;
440
+ function makeSpec({ name, args, item, error }: PaginatedOptions) {
367
441
  validateConfectFunctionIdentifier(name);
368
442
 
369
443
  return Object.assign(Object.create(Proto), {
370
444
  runtimeAndFunctionType,
371
445
  functionVisibility,
372
446
  name,
373
- functionProvenance: FunctionProvenance.ConfectPaginated(
374
- // When `args` is omitted, `UserArgs_` is its `Schema.Struct<{}>` default.
375
- args ?? ((() => Schema.Struct({})) as unknown as () => UserArgs_),
376
- item,
377
- error,
378
- ),
447
+ functionProvenance:
448
+ args === undefined
449
+ ? FunctionProvenance.ConfectPaginated(() => ({}), item, error)
450
+ : FunctionProvenance.ConfectPaginated(args, item, error),
379
451
  middlewareSpecs: [],
380
452
  });
381
- };
453
+ }
454
+
455
+ return makeSpec;
456
+ };
382
457
 
383
458
  export const publicQuery = make(RuntimeAndFunctionType.ConvexQuery, "public");
384
459
  export const internalQuery = make(
@@ -429,11 +504,19 @@ type MatchingRegisteredFunction<
429
504
  : never;
430
505
 
431
506
  type ExtractArgs<F> =
432
- F extends RegisteredQuery<any, infer A, any>
507
+ F extends RegisteredQuery<any, infer A extends DefaultFunctionArgs, any>
433
508
  ? A
434
- : F extends RegisteredMutation<any, infer A, any>
509
+ : F extends RegisteredMutation<
510
+ any,
511
+ infer A extends DefaultFunctionArgs,
512
+ any
513
+ >
435
514
  ? A
436
- : F extends RegisteredAction<any, infer A, any>
515
+ : F extends RegisteredAction<
516
+ any,
517
+ infer A extends DefaultFunctionArgs,
518
+ any
519
+ >
437
520
  ? A
438
521
  : never;
439
522
 
package/src/GroupPath.ts CHANGED
@@ -1,4 +1,3 @@
1
- import type { Record } from "effect";
2
1
  import type * as GroupSpec from "./GroupSpec";
3
2
 
4
3
  /**
@@ -41,11 +40,7 @@ export type GroupAt<
41
40
  > = Group extends GroupSpec.AnyWithProps
42
41
  ? Path extends `${infer Head}.${infer Tail}`
43
42
  ? Group extends { readonly name: Head }
44
- ? Group extends {
45
- readonly groups: Record.ReadonlyRecord<string, infer SubGroup>;
46
- }
47
- ? GroupAt<SubGroup, Tail>
48
- : never
43
+ ? GroupAt<GroupSpec.Groups<Group>, Tail>
49
44
  : never
50
45
  : GroupSpec.WithName<Group, Path>
51
46
  : never;
package/src/GroupSpec.ts CHANGED
@@ -5,7 +5,7 @@ import type * as MiddlewareSpec from "./MiddlewareSpec";
5
5
  import type * as RuntimeAndFunctionType from "./RuntimeAndFunctionType";
6
6
  import { validateConfectFunctionIdentifier } from "./Identifier";
7
7
 
8
- export const TypeId = "@confect/core/GroupSpec";
8
+ export const TypeId = "~@confect/core/GroupSpec";
9
9
  export type TypeId = typeof TypeId;
10
10
 
11
11
  export const isGroupSpec = (u: unknown): u is AnyWithProps =>
@@ -36,6 +36,8 @@ export interface GroupSpec<
36
36
  [GroupName in Name<Groups_>]: WithName<Groups_, GroupName>;
37
37
  };
38
38
  readonly middlewareSpecs: ReadonlyArray<MiddlewareSpecs_>;
39
+ readonly "~Functions": Functions_;
40
+ readonly "~Groups": Groups_;
39
41
 
40
42
  addFunction<Function extends FunctionSpec.AnyWithPropsWithRuntime<Runtime>>(
41
43
  function_: Function &
@@ -103,11 +105,9 @@ export interface AnyWithPropsWithRuntime<
103
105
 
104
106
  export type Name<Group extends AnyWithProps> = Group["name"];
105
107
 
106
- export type Functions<Group extends AnyWithProps> =
107
- Group["functions"][keyof Group["functions"]];
108
+ export type Functions<Group extends AnyWithProps> = Group["~Functions"];
108
109
 
109
- export type Groups<Group extends AnyWithProps> =
110
- Group["groups"][keyof Group["groups"]];
110
+ export type Groups<Group extends AnyWithProps> = Group["~Groups"];
111
111
 
112
112
  export type MiddlewareSpecs<Group extends AnyWithProps> =
113
113
  Group["middlewareSpecs"][number];
@@ -271,7 +271,7 @@ const makeProto = <
271
271
  functions,
272
272
  groups,
273
273
  middlewareSpecs,
274
- });
274
+ }) as GroupSpec<Runtime, Name_, Functions_, Groups_, MiddlewareSpecs_>;
275
275
 
276
276
  export const make = (): GroupSpec<"Convex", ""> =>
277
277
  makeProto({
package/src/Lazy.ts CHANGED
@@ -14,9 +14,8 @@
14
14
  * forcing the computation.
15
15
  *
16
16
  * This is the single shared implementation consumed across packages (e.g.
17
- * `@confect/core`'s lazy `FunctionSpec` schemas and `@confect/server`'s lazy
18
- * `Table` `Fields` / `Doc` / `tableDefinition`), so there is no chance of the
19
- * two drifting apart.
17
+ * `@confect/core`'s lazy `FunctionSpec` schemas and lazy `Table` `Fields` /
18
+ * `Doc`), so there is no chance of the two drifting apart.
20
19
  */
21
20
  export const defineProperty = <T extends object, K extends PropertyKey>(
22
21
  target: T,
@@ -8,7 +8,7 @@ import type * as FunctionSpec from "./FunctionSpec";
8
8
  import * as Lazy from "./Lazy";
9
9
  import type * as RuntimeAndFunctionType from "./RuntimeAndFunctionType";
10
10
 
11
- export const TypeId = "@confect/core/MiddlewareSpec";
11
+ export const TypeId = "~@confect/core/MiddlewareSpec";
12
12
  export type TypeId = typeof TypeId;
13
13
 
14
14
  export const isMiddlewareSpec = (u: unknown): u is AnyMiddlewareSpec =>
@@ -228,7 +228,7 @@ export const errorSchemas = (
228
228
  * problem at the `.middleware()` / `.addFunction()` call site.
229
229
  */
230
230
  export interface AttachmentError<Message extends string> {
231
- readonly "~confect/MiddlewareSpec/AttachmentError": Message;
231
+ readonly "~@confect/core/MiddlewareSpec/AttachmentError": Message;
232
232
  }
233
233
 
234
234
  type FunctionTypeOf<FunctionSpec_ extends FunctionSpec.AnyWithProps> =
@@ -0,0 +1,72 @@
1
+ import { ConvexError } from "convex/values";
2
+ import type { Value } from "convex/values";
3
+ import * as Match from "effect/Match";
4
+ import * as Option from "effect/Option";
5
+ import * as Schema from "effect/Schema";
6
+
7
+ /** A Convex pagination cursor that no longer describes the current query. */
8
+ export class InvalidCursor extends Schema.TaggedError<InvalidCursor>()(
9
+ "InvalidCursor",
10
+ {
11
+ cause: Schema.Defect(),
12
+ },
13
+ ) {}
14
+
15
+ interface InvalidCursorData {
16
+ readonly isConvexSystemError: true;
17
+ readonly paginationError: "InvalidCursor";
18
+ }
19
+
20
+ const ConvexErrorIdentifier = Symbol.for("ConvexError");
21
+
22
+ const isConvexError = (error: unknown): error is ConvexError<Value> =>
23
+ error instanceof ConvexError ||
24
+ (typeof error === "object" &&
25
+ error !== null &&
26
+ ConvexErrorIdentifier in error);
27
+
28
+ const isInvalidCursorData = (value: unknown): value is InvalidCursorData =>
29
+ typeof value === "object" &&
30
+ value !== null &&
31
+ "isConvexSystemError" in value &&
32
+ value.isConvexSystemError === true &&
33
+ "paginationError" in value &&
34
+ value.paginationError === "InvalidCursor";
35
+
36
+ const fromErrorMessage = (
37
+ error: globalThis.Error,
38
+ ): Option.Option<InvalidCursor> =>
39
+ error.message.includes("InvalidCursor")
40
+ ? Option.some(new InvalidCursor({ cause: error }))
41
+ : Option.none();
42
+
43
+ /** Recognizes an invalid-cursor error emitted by a Convex query. */
44
+ export const fromConvexQueryError = (
45
+ error: unknown,
46
+ ): Option.Option<InvalidCursor> =>
47
+ Match.value(error).pipe(
48
+ Match.when(isConvexError, (convexError) =>
49
+ Match.value(isInvalidCursorData(convexError.data)).pipe(
50
+ Match.when(true, () =>
51
+ Option.some(new InvalidCursor({ cause: error })),
52
+ ),
53
+ Match.when(false, () => fromErrorMessage(convexError)),
54
+ Match.exhaustive,
55
+ ),
56
+ ),
57
+ Match.when(Match.instanceOf(globalThis.Error), fromErrorMessage),
58
+ Match.when(Match.any, () => Option.none<InvalidCursor>()),
59
+ Match.exhaustive,
60
+ );
61
+
62
+ /** Recognizes the error data attached to Convex's invalid-cursor error. */
63
+ export const fromConvexErrorData = (
64
+ errorData: unknown,
65
+ ): Option.Option<InvalidCursor> =>
66
+ Match.value(errorData).pipe(
67
+ Match.when(isInvalidCursorData, (cause) =>
68
+ Option.some(new InvalidCursor({ cause })),
69
+ ),
70
+ Match.when(Match.any, () => Option.none<InvalidCursor>()),
71
+ Match.exhaustive,
72
+ );