@gaganref/confect-server 10.3.1-fork.3 → 10.3.1-fork.30

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 (273) hide show
  1. package/dist/ActionCall.d.ts +30 -0
  2. package/dist/ActionCall.d.ts.map +1 -0
  3. package/dist/ActionCall.js +41 -0
  4. package/dist/ActionCall.js.map +1 -0
  5. package/dist/ActionCtx.d.ts +1 -1
  6. package/dist/ActionCtx.d.ts.map +1 -1
  7. package/dist/ActionCtx.js.map +1 -1
  8. package/dist/ActionRunner.js +2 -2
  9. package/dist/AiGatewayDecisionClient.d.ts +2 -2
  10. package/dist/AiGatewayDecisionClient.d.ts.map +1 -1
  11. package/dist/AiGatewayDecisionClient.js +1 -1
  12. package/dist/AiGatewayDecisionClient.js.map +1 -1
  13. package/dist/AiGatewayLanguageClient.d.ts +2 -2
  14. package/dist/AiGatewayLanguageClient.d.ts.map +1 -1
  15. package/dist/AiGatewayLanguageClient.js +1 -1
  16. package/dist/AiGatewayLanguageClient.js.map +1 -1
  17. package/dist/Auth.d.ts +1 -1
  18. package/dist/Auth.d.ts.map +1 -1
  19. package/dist/Auth.js +1 -1
  20. package/dist/Auth.js.map +1 -1
  21. package/dist/Callback.js +3 -3
  22. package/dist/ComponentCtx.d.ts +1 -1
  23. package/dist/ComponentCtx.d.ts.map +1 -1
  24. package/dist/ConvexConfigProvider.js +2 -2
  25. package/dist/ConvexFunctionDefinitions.d.ts +4 -4
  26. package/dist/ConvexFunctionDefinitions.d.ts.map +1 -1
  27. package/dist/ConvexFunctionDefinitions.js +2 -2
  28. package/dist/ConvexFunctionDefinitions.js.map +1 -1
  29. package/dist/ConvexLogger.js +1 -1
  30. package/dist/CronJobs.d.ts +1 -1
  31. package/dist/CronJobs.d.ts.map +1 -1
  32. package/dist/CronJobs.js +6 -6
  33. package/dist/CronJobs.js.map +1 -1
  34. package/dist/DataModel.d.ts +3 -3
  35. package/dist/DataModel.d.ts.map +1 -1
  36. package/dist/DataModel.js.map +1 -1
  37. package/dist/DatabaseReader.d.ts +4 -4
  38. package/dist/DatabaseReader.d.ts.map +1 -1
  39. package/dist/DatabaseReader.js.map +1 -1
  40. package/dist/DatabaseSchema.d.ts +1 -1
  41. package/dist/DatabaseSchema.d.ts.map +1 -1
  42. package/dist/DatabaseSchema.js +2 -2
  43. package/dist/DatabaseSchema.js.map +1 -1
  44. package/dist/DatabaseWriter.d.ts +41 -7
  45. package/dist/DatabaseWriter.d.ts.map +1 -1
  46. package/dist/DatabaseWriter.js +55 -8
  47. package/dist/DatabaseWriter.js.map +1 -1
  48. package/dist/Document.d.ts +4 -4
  49. package/dist/Document.d.ts.map +1 -1
  50. package/dist/Document.js.map +1 -1
  51. package/dist/ExecutionMetadata.js +1 -1
  52. package/dist/FunctionImpl.d.ts +2 -2
  53. package/dist/FunctionImpl.d.ts.map +1 -1
  54. package/dist/FunctionImpl.js +2 -2
  55. package/dist/FunctionImpl.js.map +1 -1
  56. package/dist/FunctionRegistryItem.d.ts +1 -1
  57. package/dist/FunctionRegistryItem.d.ts.map +1 -1
  58. package/dist/FunctionRegistryItem.js +1 -1
  59. package/dist/FunctionRegistryItem.js.map +1 -1
  60. package/dist/GroupImpl.d.ts +24 -5
  61. package/dist/GroupImpl.d.ts.map +1 -1
  62. package/dist/GroupImpl.js +21 -22
  63. package/dist/GroupImpl.js.map +1 -1
  64. package/dist/GroupRegistry.d.ts +2 -2
  65. package/dist/GroupRegistry.d.ts.map +1 -1
  66. package/dist/GroupRegistry.js.map +1 -1
  67. package/dist/Handler.d.ts +30 -26
  68. package/dist/Handler.d.ts.map +1 -1
  69. package/dist/Handler.js.map +1 -1
  70. package/dist/HttpRouter.d.ts +13 -13
  71. package/dist/HttpRouter.d.ts.map +1 -1
  72. package/dist/HttpRouter.js +2 -2
  73. package/dist/HttpRouter.js.map +1 -1
  74. package/dist/MiddlewareImpl.d.ts +14 -14
  75. package/dist/MiddlewareImpl.d.ts.map +1 -1
  76. package/dist/MiddlewareImpl.js +1 -1
  77. package/dist/MiddlewareImpl.js.map +1 -1
  78. package/dist/MutationCtx.d.ts +1 -1
  79. package/dist/MutationCtx.d.ts.map +1 -1
  80. package/dist/MutationCtx.js.map +1 -1
  81. package/dist/MutationRunner.d.ts +1 -1
  82. package/dist/MutationRunner.d.ts.map +1 -1
  83. package/dist/MutationRunner.js +2 -2
  84. package/dist/MutationRunner.js.map +1 -1
  85. package/dist/MutationTransactionContext.d.ts +2 -2
  86. package/dist/MutationTransactionContext.d.ts.map +1 -1
  87. package/dist/MutationTransactionContext.js +2 -2
  88. package/dist/MutationTransactionContext.js.map +1 -1
  89. package/dist/OfficialComponent.d.ts +50 -0
  90. package/dist/OfficialComponent.d.ts.map +1 -0
  91. package/dist/OfficialComponent.js +70 -0
  92. package/dist/OfficialComponent.js.map +1 -0
  93. package/dist/OrderedQuery.d.ts +4 -4
  94. package/dist/OrderedQuery.d.ts.map +1 -1
  95. package/dist/OrderedQuery.js.map +1 -1
  96. package/dist/QueryCtx.d.ts +1 -1
  97. package/dist/QueryCtx.d.ts.map +1 -1
  98. package/dist/QueryCtx.js.map +1 -1
  99. package/dist/QueryInitializer.d.ts +10 -10
  100. package/dist/QueryInitializer.d.ts.map +1 -1
  101. package/dist/QueryInitializer.js +2 -2
  102. package/dist/QueryInitializer.js.map +1 -1
  103. package/dist/QueryRunner.d.ts +2 -2
  104. package/dist/QueryRunner.d.ts.map +1 -1
  105. package/dist/QueryRunner.js +2 -2
  106. package/dist/QueryRunner.js.map +1 -1
  107. package/dist/QueryStream.d.ts +86 -13
  108. package/dist/QueryStream.d.ts.map +1 -1
  109. package/dist/QueryStream.js +81 -8
  110. package/dist/QueryStream.js.map +1 -1
  111. package/dist/QueryStreamCursor.d.ts +2 -2
  112. package/dist/QueryStreamCursor.d.ts.map +1 -1
  113. package/dist/QueryStreamCursor.js +1 -1
  114. package/dist/QueryStreamCursor.js.map +1 -1
  115. package/dist/QueryStreamIndexPrefix.d.ts +2 -2
  116. package/dist/QueryStreamIndexPrefix.d.ts.map +1 -1
  117. package/dist/QueryStreamIndexPrefix.js +1 -1
  118. package/dist/QueryStreamIndexPrefix.js.map +1 -1
  119. package/dist/QueryStreamIndexRange.d.ts +4 -4
  120. package/dist/QueryStreamIndexRange.d.ts.map +1 -1
  121. package/dist/QueryStreamIndexRange.js +2 -2
  122. package/dist/QueryStreamIndexRange.js.map +1 -1
  123. package/dist/QueryStreamKey.d.ts +2 -2
  124. package/dist/QueryStreamKey.d.ts.map +1 -1
  125. package/dist/QueryStreamKey.js +1 -1
  126. package/dist/QueryStreamKey.js.map +1 -1
  127. package/dist/QueryStreamKeyBounds.d.ts +3 -3
  128. package/dist/QueryStreamKeyBounds.d.ts.map +1 -1
  129. package/dist/QueryStreamKeyBounds.js +2 -2
  130. package/dist/QueryStreamKeyBounds.js.map +1 -1
  131. package/dist/QueryStreamKeyLayout.d.ts +1 -1
  132. package/dist/QueryStreamKeyLayout.d.ts.map +1 -1
  133. package/dist/QueryStreamKeyLayout.js +2 -2
  134. package/dist/QueryStreamKeyLayout.js.map +1 -1
  135. package/dist/QueryStreamKeyValues.d.ts +1 -1
  136. package/dist/QueryStreamKeyValues.d.ts.map +1 -1
  137. package/dist/QueryStreamKeyValues.js +1 -1
  138. package/dist/QueryStreamKeyValues.js.map +1 -1
  139. package/dist/QueryStreamPagination.d.ts +1 -1
  140. package/dist/QueryStreamPagination.d.ts.map +1 -1
  141. package/dist/QueryStreamPagination.js +1 -1
  142. package/dist/QueryStreamPagination.js.map +1 -1
  143. package/dist/QueryStreamReadBudget.d.ts +3 -2
  144. package/dist/QueryStreamReadBudget.d.ts.map +1 -1
  145. package/dist/QueryStreamReadBudget.js +6 -3
  146. package/dist/QueryStreamReadBudget.js.map +1 -1
  147. package/dist/QueryTransactionContext.js +2 -2
  148. package/dist/RegisteredConvexFunction.d.ts +20 -20
  149. package/dist/RegisteredConvexFunction.d.ts.map +1 -1
  150. package/dist/RegisteredConvexFunction.js +19 -19
  151. package/dist/RegisteredConvexFunction.js.map +1 -1
  152. package/dist/RegisteredFunction.d.ts +26 -26
  153. package/dist/RegisteredFunction.d.ts.map +1 -1
  154. package/dist/RegisteredFunction.js +55 -13
  155. package/dist/RegisteredFunction.js.map +1 -1
  156. package/dist/RegisteredFunctions.d.ts +3 -3
  157. package/dist/RegisteredFunctions.d.ts.map +1 -1
  158. package/dist/RegisteredFunctions.js.map +1 -1
  159. package/dist/RegisteredNodeFunction.d.ts +6 -6
  160. package/dist/RegisteredNodeFunction.d.ts.map +1 -1
  161. package/dist/RegisteredNodeFunction.js +1 -1
  162. package/dist/RegisteredNodeFunction.js.map +1 -1
  163. package/dist/Registry.d.ts +1 -1
  164. package/dist/Registry.d.ts.map +1 -1
  165. package/dist/Registry.js.map +1 -1
  166. package/dist/RegistryItems.d.ts +7 -0
  167. package/dist/RegistryItems.d.ts.map +1 -1
  168. package/dist/RegistryItems.js +8 -3
  169. package/dist/RegistryItems.js.map +1 -1
  170. package/dist/RequestMetadata.js +1 -1
  171. package/dist/ResolvedMiddleware.d.ts +2 -2
  172. package/dist/ResolvedMiddleware.d.ts.map +1 -1
  173. package/dist/ResolvedMiddleware.js.map +1 -1
  174. package/dist/Scheduler.js +2 -2
  175. package/dist/Storage.d.ts +6 -6
  176. package/dist/Storage.d.ts.map +1 -1
  177. package/dist/Storage.js +1 -1
  178. package/dist/Storage.js.map +1 -1
  179. package/dist/StorageActionWriter.d.ts +1 -1
  180. package/dist/StorageActionWriter.d.ts.map +1 -1
  181. package/dist/StorageActionWriter.js +1 -1
  182. package/dist/StorageActionWriter.js.map +1 -1
  183. package/dist/StorageReader.d.ts +1 -1
  184. package/dist/StorageReader.d.ts.map +1 -1
  185. package/dist/StorageReader.js +1 -1
  186. package/dist/StorageReader.js.map +1 -1
  187. package/dist/StorageWriter.d.ts +1 -1
  188. package/dist/StorageWriter.d.ts.map +1 -1
  189. package/dist/StorageWriter.js +1 -1
  190. package/dist/StorageWriter.js.map +1 -1
  191. package/dist/TableInfo.d.ts +2 -2
  192. package/dist/TableInfo.d.ts.map +1 -1
  193. package/dist/TableInfo.js.map +1 -1
  194. package/dist/TransactionMetadata.js +1 -1
  195. package/dist/VectorSearch.d.ts +1 -1
  196. package/dist/VectorSearch.d.ts.map +1 -1
  197. package/dist/VectorSearch.js +1 -1
  198. package/dist/VectorSearch.js.map +1 -1
  199. package/dist/index.d.ts +62 -60
  200. package/dist/index.d.ts.map +1 -1
  201. package/dist/index.js +11 -9
  202. package/dist/internal/AiGatewayDecisionClient.d.ts +1 -1
  203. package/dist/internal/AiGatewayDecisionClient.d.ts.map +1 -1
  204. package/dist/internal/AiGatewayDecisionClient.js +1 -1
  205. package/dist/internal/AiGatewayDecisionClient.js.map +1 -1
  206. package/dist/internal/AiGatewayLanguageClient.d.ts +1 -1
  207. package/dist/internal/AiGatewayLanguageClient.d.ts.map +1 -1
  208. package/dist/internal/AiGatewayLanguageClient.js +1 -1
  209. package/dist/internal/AiGatewayLanguageClient.js.map +1 -1
  210. package/dist/internal/AiGatewayServiceToken.js +1 -1
  211. package/dist/internal/DocumentPatch.d.ts +16 -0
  212. package/dist/internal/DocumentPatch.d.ts.map +1 -0
  213. package/dist/internal/DocumentPatch.js +36 -0
  214. package/dist/internal/DocumentPatch.js.map +1 -0
  215. package/dist/node.d.ts +1 -1
  216. package/dist/node.d.ts.map +1 -1
  217. package/package.json +2 -2
  218. package/src/ActionCall.ts +82 -0
  219. package/src/ActionCtx.ts +1 -1
  220. package/src/AiGatewayDecisionClient.ts +3 -3
  221. package/src/AiGatewayLanguageClient.ts +3 -3
  222. package/src/Auth.ts +1 -1
  223. package/src/ComponentCtx.ts +1 -1
  224. package/src/ConvexFunctionDefinitions.ts +8 -8
  225. package/src/CronJobs.ts +1 -1
  226. package/src/DataModel.ts +3 -3
  227. package/src/DatabaseReader.ts +4 -4
  228. package/src/DatabaseSchema.ts +1 -1
  229. package/src/DatabaseWriter.ts +189 -31
  230. package/src/Document.ts +4 -4
  231. package/src/FunctionImpl.ts +5 -5
  232. package/src/FunctionRegistryItem.ts +1 -1
  233. package/src/GroupImpl.ts +66 -13
  234. package/src/GroupRegistry.ts +4 -4
  235. package/src/Handler.ts +43 -28
  236. package/src/HttpRouter.ts +17 -17
  237. package/src/MiddlewareImpl.ts +17 -17
  238. package/src/MutationCtx.ts +1 -1
  239. package/src/MutationRunner.ts +1 -1
  240. package/src/MutationTransactionContext.ts +2 -2
  241. package/src/OfficialComponent.ts +151 -0
  242. package/src/OrderedQuery.ts +4 -4
  243. package/src/QueryCtx.ts +1 -1
  244. package/src/QueryInitializer.ts +9 -9
  245. package/src/QueryRunner.ts +2 -2
  246. package/src/QueryStream.ts +212 -20
  247. package/src/QueryStreamCursor.ts +3 -3
  248. package/src/QueryStreamIndexPrefix.ts +2 -2
  249. package/src/QueryStreamIndexRange.ts +4 -4
  250. package/src/QueryStreamKey.ts +2 -2
  251. package/src/QueryStreamKeyBounds.ts +3 -3
  252. package/src/QueryStreamKeyLayout.ts +1 -1
  253. package/src/QueryStreamKeyValues.ts +1 -1
  254. package/src/QueryStreamPagination.ts +2 -2
  255. package/src/QueryStreamReadBudget.ts +19 -6
  256. package/src/RegisteredConvexFunction.ts +21 -21
  257. package/src/RegisteredFunction.ts +72 -19
  258. package/src/RegisteredFunctions.ts +4 -4
  259. package/src/RegisteredNodeFunction.ts +8 -8
  260. package/src/Registry.ts +1 -1
  261. package/src/RegistryItems.ts +33 -2
  262. package/src/ResolvedMiddleware.ts +2 -2
  263. package/src/Storage.ts +3 -3
  264. package/src/StorageActionWriter.ts +1 -1
  265. package/src/StorageReader.ts +1 -1
  266. package/src/StorageWriter.ts +1 -1
  267. package/src/TableInfo.ts +2 -2
  268. package/src/VectorSearch.ts +1 -1
  269. package/src/index.ts +62 -60
  270. package/src/internal/AiGatewayDecisionClient.ts +2 -2
  271. package/src/internal/AiGatewayLanguageClient.ts +2 -2
  272. package/src/internal/DocumentPatch.ts +87 -0
  273. package/src/node.ts +1 -1
@@ -1,7 +1,7 @@
1
1
  import type * as IdScope from "@confect/core/IdScope";
2
2
  import type { GenericDataModel, GenericMutationCtx } from "convex/server";
3
3
  import * as Context from "effect/Context";
4
- import type * as ComponentCtx from "./ComponentCtx";
4
+ import type * as ComponentCtx from "./ComponentCtx.js";
5
5
  import * as Layer from "effect/Layer";
6
6
 
7
7
  export type MutationCtxTag<
@@ -4,7 +4,7 @@ import * as Context from "effect/Context";
4
4
  import * as Effect from "effect/Effect";
5
5
  import * as Layer from "effect/Layer";
6
6
  import type * as Schema from "effect/Schema";
7
- import * as MutationTransactionContext from "./MutationTransactionContext";
7
+ import * as MutationTransactionContext from "./MutationTransactionContext.js";
8
8
 
9
9
  export type Options = MutationTransactionContext.MutationOptions;
10
10
 
@@ -7,10 +7,10 @@ import type {
7
7
  import * as Context from "effect/Context";
8
8
  import * as Effect from "effect/Effect";
9
9
  import * as Layer from "effect/Layer";
10
- import type { Options as MutationOptions } from "./QueryTransactionContext";
10
+ import type { Options as MutationOptions } from "./QueryTransactionContext.js";
11
11
 
12
12
  export type { TransactionLimits } from "convex/server";
13
- export type { Options as MutationOptions } from "./QueryTransactionContext";
13
+ export type { Options as MutationOptions } from "./QueryTransactionContext.js";
14
14
  export type QueryOptions = AdvancedRunQueryOptions;
15
15
 
16
16
  const make = (
@@ -0,0 +1,151 @@
1
+ import * as Ref from "@confect/core/Ref";
2
+ import type {
3
+ DefaultFunctionArgs,
4
+ GenericActionCtx,
5
+ GenericDataModel,
6
+ GenericMutationCtx,
7
+ GenericQueryCtx,
8
+ } from "convex/server";
9
+ import * as Effect from "effect/Effect";
10
+ import * as Option from "effect/Option";
11
+ import * as Schema from "effect/Schema";
12
+ import * as ActionCtx from "./ActionCtx.js";
13
+ import type * as ActionRunner from "./ActionRunner.js";
14
+ import * as MutationCtx from "./MutationCtx.js";
15
+ import type * as MutationRunner from "./MutationRunner.js";
16
+ import * as QueryCtx from "./QueryCtx.js";
17
+ import type * as QueryRunner from "./QueryRunner.js";
18
+
19
+ /**
20
+ * An official component's method rejected. `cause` is the rejection as thrown.
21
+ */
22
+ export class ComponentCallFailed extends Schema.TaggedError<ComponentCallFailed>()(
23
+ "ComponentCallFailed",
24
+ { component: Schema.String, method: Schema.String, cause: Schema.Defect() },
25
+ ) {}
26
+
27
+ declare const unsupported: unique symbol;
28
+ type Unsupported = typeof unsupported;
29
+ type Needs<Param> = [GenericActionCtx<GenericDataModel>] extends [Param]
30
+ ? [GenericMutationCtx<GenericDataModel>] extends [Param]
31
+ ? [GenericQueryCtx<GenericDataModel>] extends [Param]
32
+ ? QueryRunner.QueryRunner
33
+ : MutationRunner.MutationRunner
34
+ : [GenericQueryCtx<GenericDataModel>] extends [Param]
35
+ ? Unsupported
36
+ : ActionRunner.ActionRunner
37
+ : Unsupported;
38
+
39
+ type Method<Official> = {
40
+ [K in keyof Official & string]: Official[K] extends (
41
+ ctx: infer Ctx,
42
+ ...args: infer _Args
43
+ ) => Promise<unknown>
44
+ ? Needs<Ctx> extends Unsupported
45
+ ? never
46
+ : K
47
+ : never;
48
+ }[keyof Official & string];
49
+
50
+ type Call<F> = F extends (
51
+ ctx: infer Ctx,
52
+ ...args: infer Args
53
+ ) => Promise<infer A>
54
+ ? (...args: Args) => Effect.Effect<A, never, Needs<Ctx>>
55
+ : never;
56
+
57
+ type Lifted<Official> = <M extends Method<Official>>(
58
+ method: M,
59
+ ...args: Parameters<Call<Official[M]>>
60
+ ) => ReturnType<Call<Official[M]>>;
61
+
62
+ /**
63
+ * Lift official promise methods, deriving each capability from its ctx
64
+ * parameter. A rejection is caller misuse, a limit or a platform fault rather
65
+ * than a domain fact, so it dies.
66
+ */
67
+ export const make = <Official extends object>(
68
+ component: string,
69
+ official: Official,
70
+ ): Lifted<Official> => {
71
+ const context = Effect.gen(function* () {
72
+ const action = yield* Effect.serviceOption(
73
+ ActionCtx.ActionCtx<GenericDataModel>(),
74
+ );
75
+ if (Option.isSome(action)) return action.value;
76
+ const mutation = yield* Effect.serviceOption(
77
+ MutationCtx.MutationCtx<GenericDataModel>(),
78
+ );
79
+ if (Option.isSome(mutation)) return mutation.value;
80
+ const query = yield* Effect.serviceOption(
81
+ QueryCtx.QueryCtx<GenericDataModel>(),
82
+ );
83
+ if (Option.isSome(query)) return query.value;
84
+ return yield* Effect.die(
85
+ new Error(`${component} called outside a Confect handler`),
86
+ );
87
+ });
88
+ const call = Effect.fn(`${component}.call`)(function* (
89
+ method: Method<Official>,
90
+ ...args: unknown[]
91
+ ) {
92
+ const ctx = yield* context;
93
+ // Method selects promise methods whose first argument accepts a native handler context.
94
+ const invoke = official[method] as (
95
+ native: typeof ctx,
96
+ ...args: unknown[]
97
+ ) => Promise<unknown>;
98
+ return yield* Effect.tryPromise({
99
+ try: () => invoke.call(official, ctx, ...args),
100
+ catch: (cause) => ComponentCallFailed.make({ component, method, cause }),
101
+ }).pipe(Effect.orDie);
102
+ });
103
+ // Confect installs the native ctx with the runner capability inferred by Needs.
104
+ return call as unknown as Lifted<Official>;
105
+ };
106
+
107
+ /**
108
+ * A function reference with its encoded arguments, ready for an official method
109
+ * that takes both.
110
+ */
111
+ export interface Fn<R extends Ref.Any> {
112
+ readonly reference: Ref.FunctionReference<R>;
113
+ readonly args: DefaultFunctionArgs;
114
+ }
115
+
116
+ /**
117
+ * Encode a ref's arguments through its codecs to the wire record an official
118
+ * method expects.
119
+ */
120
+ export const encodeCall = <R extends Ref.Any>(
121
+ ref: R,
122
+ args: NoInfer<Ref.Args<R>>,
123
+ ): Effect.Effect<Fn<R>> =>
124
+ Ref.encodeArgs(ref, args).pipe(
125
+ Effect.flatMap(
126
+ Schema.decodeUnknownEffect(Schema.Record(Schema.String, Schema.Unknown)),
127
+ ),
128
+ Effect.map((encoded) => ({
129
+ reference: Ref.getFunctionReference(ref),
130
+ args: encoded,
131
+ })),
132
+ Effect.orDie,
133
+ );
134
+
135
+ /**
136
+ * Encode a callback's real field without fabricating the rest of its arguments.
137
+ */
138
+ export const encodeField = <
139
+ R extends Ref.AnyConfect,
140
+ K extends keyof Ref.Args<R> & keyof Ref.ArgsFields<R>,
141
+ >(
142
+ ref: R,
143
+ key: K,
144
+ value: NoInfer<Ref.Args<R>[K]>,
145
+ ): Effect.Effect<unknown> => {
146
+ const fields = ref.args.fields as Record<
147
+ keyof Ref.ArgsFields<R>,
148
+ Schema.Codec<unknown, unknown>
149
+ >;
150
+ return Schema.encodeUnknownEffect(fields[key])(value).pipe(Effect.orDie);
151
+ };
@@ -10,10 +10,10 @@ import { identity, pipe } from "effect/Function";
10
10
  import type { Option } from "effect";
11
11
  import * as Effect from "effect/Effect";
12
12
  import * as Stream from "effect/Stream";
13
- import type * as DatabaseSchema from "./DatabaseSchema";
14
- import * as Document from "./Document";
15
- import type * as TableInfo from "./TableInfo";
16
- import type * as Table from "./Table";
13
+ import type * as DatabaseSchema from "./DatabaseSchema.js";
14
+ import * as Document from "./Document.js";
15
+ import type * as TableInfo from "./TableInfo.js";
16
+ import type * as Table from "./Table.js";
17
17
 
18
18
  type NativePaginate<TableInfo_ extends TableInfo.AnyWithProps, Doc> = (
19
19
  options: PaginationOptions,
package/src/QueryCtx.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type * as IdScope from "@confect/core/IdScope";
2
2
  import type { GenericDataModel, GenericQueryCtx } from "convex/server";
3
3
  import * as Context from "effect/Context";
4
- import type * as ComponentCtx from "./ComponentCtx";
4
+ import type * as ComponentCtx from "./ComponentCtx.js";
5
5
  import * as Layer from "effect/Layer";
6
6
 
7
7
  export type QueryCtxTag<
@@ -28,15 +28,15 @@ import type {
28
28
  BaseDatabaseReader,
29
29
  IndexFieldTypesForEq,
30
30
  } from "@confect/core/Types";
31
- import type * as DataModel from "./DataModel";
32
- import type * as DatabaseSchema from "./DatabaseSchema";
33
- import * as Document from "./Document";
34
- import * as OrderedQuery from "./OrderedQuery";
35
- import * as QueryStream from "./QueryStream";
36
- import type * as QueryStreamKeyLabels from "./QueryStreamKeyLabels";
37
- import * as QueryStreamIndexRange from "./QueryStreamIndexRange";
38
- import type { QueryStreamOrderDirection as OrderDirection } from "./QueryStreamOrderDirection";
39
- import type * as Table from "./Table";
31
+ import type * as DataModel from "./DataModel.js";
32
+ import type * as DatabaseSchema from "./DatabaseSchema.js";
33
+ import * as Document from "./Document.js";
34
+ import * as OrderedQuery from "./OrderedQuery.js";
35
+ import * as QueryStream from "./QueryStream.js";
36
+ import type * as QueryStreamKeyLabels from "./QueryStreamKeyLabels.js";
37
+ import * as QueryStreamIndexRange from "./QueryStreamIndexRange.js";
38
+ import type { QueryStreamOrderDirection as OrderDirection } from "./QueryStreamOrderDirection.js";
39
+ import type * as Table from "./Table.js";
40
40
 
41
41
  type ConvexTableInfoFor<
42
42
  DataModel_ extends DataModel.AnyWithProps,
@@ -4,8 +4,8 @@ import * as Context from "effect/Context";
4
4
  import * as Effect from "effect/Effect";
5
5
  import * as Layer from "effect/Layer";
6
6
  import type * as Schema from "effect/Schema";
7
- import * as MutationTransactionContext from "./MutationTransactionContext";
8
- import * as QueryTransactionContext from "./QueryTransactionContext";
7
+ import * as MutationTransactionContext from "./MutationTransactionContext.js";
8
+ import * as QueryTransactionContext from "./QueryTransactionContext.js";
9
9
 
10
10
  export type Options = MutationTransactionContext.QueryOptions;
11
11
 
@@ -55,22 +55,31 @@ import * as String from "effect/String";
55
55
  import * as Result from "effect/Result";
56
56
  import * as Tuple from "effect/Tuple";
57
57
  import type * as Types from "effect/Types";
58
- import * as Document from "./Document";
59
- import type * as Table from "./Table";
60
- import * as QueryStreamCursor from "./QueryStreamCursor";
61
- import * as QueryStreamKeyLabels from "./QueryStreamKeyLabels";
62
- import * as QueryStreamKeyLayout from "./QueryStreamKeyLayout";
63
- import * as QueryStreamOrderDirection from "./QueryStreamOrderDirection";
64
- import * as QueryStreamKeyValues from "./QueryStreamKeyValues";
65
- import * as QueryStreamIndexPrefix from "./QueryStreamIndexPrefix";
66
- import * as QueryStreamKey from "./QueryStreamKey";
67
- import * as QueryStreamKeyBounds from "./QueryStreamKeyBounds";
68
- import * as QueryStreamIndexRange from "./QueryStreamIndexRange";
69
- import * as QueryStreamPagination from "./QueryStreamPagination";
70
- import * as QueryStreamReadBudget from "./QueryStreamReadBudget";
58
+ import * as Document from "./Document.js";
59
+ import type * as Table from "./Table.js";
60
+ import * as QueryStreamCursor from "./QueryStreamCursor.js";
61
+ import * as QueryStreamKeyLabels from "./QueryStreamKeyLabels.js";
62
+ import * as QueryStreamKeyLayout from "./QueryStreamKeyLayout.js";
63
+ import * as QueryStreamOrderDirection from "./QueryStreamOrderDirection.js";
64
+ import * as QueryStreamKeyValues from "./QueryStreamKeyValues.js";
65
+ import * as QueryStreamIndexPrefix from "./QueryStreamIndexPrefix.js";
66
+ import * as QueryStreamKey from "./QueryStreamKey.js";
67
+ import * as QueryStreamKeyBounds from "./QueryStreamKeyBounds.js";
68
+ import * as QueryStreamIndexRange from "./QueryStreamIndexRange.js";
69
+ import * as QueryStreamPagination from "./QueryStreamPagination.js";
70
+ import * as QueryStreamReadBudget from "./QueryStreamReadBudget.js";
71
71
 
72
72
  /**
73
- * A page exhausted its read budget without a safe logical continuation.
73
+ * Default physical row budget for `paginate` and `collect`. Supply an explicit
74
+ * `maximumRowsRead` to override it. Plain Effect Stream consumers use their
75
+ * enclosing budget and remain unlimited when none is provided.
76
+ *
77
+ * @experimental
78
+ */
79
+ export const DEFAULT_MAXIMUM_ROWS_READ = 2_000;
80
+
81
+ /**
82
+ * A query stream exhausted its read budget before its consumer could finish.
74
83
  *
75
84
  * @experimental
76
85
  */
@@ -79,7 +88,7 @@ export class ReadBudgetExceededError extends Schema.TaggedError<ReadBudgetExceed
79
88
  { rowsRead: Schema.Natural, bytesRead: Schema.Natural },
80
89
  ) {
81
90
  override get message() {
82
- return "The read budget was exhausted before a safe page boundary; increase the budget or simplify the query";
91
+ return "The read budget was exhausted before the query stream completed; increase the budget or simplify the query";
83
92
  }
84
93
  }
85
94
 
@@ -165,14 +174,14 @@ export class MissingReversalRecipeError extends Data.TaggedError(
165
174
  export {
166
175
  EmptyInitialPageError,
167
176
  InvalidPageSizeError,
168
- } from "./QueryStreamPagination";
177
+ } from "./QueryStreamPagination.js";
169
178
 
170
179
  /**
171
180
  * Invalid numeric read limits.
172
181
  *
173
182
  * @experimental
174
183
  */
175
- export { InvalidReadLimitError } from "./QueryStreamReadBudget";
184
+ export { InvalidReadLimitError } from "./QueryStreamReadBudget.js";
176
185
 
177
186
  /**
178
187
  * Runtime identifier used to distinguish query streams from plain streams.
@@ -441,6 +450,89 @@ export const empty =
441
450
  return make(orderDirection);
442
451
  };
443
452
 
453
+ /**
454
+ * A deferred stream's resolved direction or layout differs from its
455
+ * declaration. The check runs on consumption, before the resolved source is
456
+ * pulled.
457
+ *
458
+ * @experimental
459
+ */
460
+ export class DeferredStreamMismatchError extends Data.TaggedError(
461
+ "DeferredStreamMismatchError",
462
+ )<{
463
+ readonly expectedOrderDirection: QueryStreamOrderDirection.QueryStreamOrderDirection;
464
+ readonly actualOrderDirection: QueryStreamOrderDirection.QueryStreamOrderDirection;
465
+ readonly expectedKeyLayout: QueryStreamKeyLayout.QueryStreamKeyLayout;
466
+ readonly actualKeyLayout: QueryStreamKeyLayout.QueryStreamKeyLayout;
467
+ }> {}
468
+
469
+ /**
470
+ * Defer an effect that checks access or constructs a query stream until it is
471
+ * pulled. Supply its layout and direction without reading documents. This lets
472
+ * `flatMap` build and narrow an inner stream before running its checks.
473
+ *
474
+ * The effect runs afresh on each consumption, seek, or reversal. Failures and
475
+ * service requirements are preserved. Its stream must match the declared layout
476
+ * and direction, or consumption dies with `DeferredStreamMismatchError`.
477
+ *
478
+ * @experimental
479
+ */
480
+ export const defer = <
481
+ Doc,
482
+ KeyLabels extends QueryStreamKeyLabels.QueryStreamKeyLabels,
483
+ OrderDirection extends QueryStreamOrderDirection.QueryStreamOrderDirection,
484
+ E = never,
485
+ R = never,
486
+ E2 = never,
487
+ R2 = never,
488
+ >(
489
+ options: {
490
+ readonly keyLayout: QueryStreamKeyLayout.QueryStreamKeyLayout<KeyLabels>;
491
+ readonly orderDirection: OrderDirection;
492
+ },
493
+ make: Effect.Effect<
494
+ QueryStream<Doc, KeyLabels, NoInfer<OrderDirection>, E, R>,
495
+ E2,
496
+ R2
497
+ >,
498
+ ): QueryStream<Doc, KeyLabels, OrderDirection, E | E2, R | R2> => {
499
+ const checked = Effect.map(make, (stream) => {
500
+ if (
501
+ stream.orderDirection !== options.orderDirection ||
502
+ !QueryStreamKeyLayout.Equivalence(stream.keyLayout, options.keyLayout)
503
+ ) {
504
+ throw new DeferredStreamMismatchError({
505
+ expectedOrderDirection: options.orderDirection,
506
+ actualOrderDirection: stream.orderDirection,
507
+ expectedKeyLayout: options.keyLayout,
508
+ actualKeyLayout: stream.keyLayout,
509
+ });
510
+ }
511
+ return stream;
512
+ });
513
+ return new QueryStream(
514
+ options.orderDirection,
515
+ options.keyLayout,
516
+ Stream.unwrap(Effect.map(checked, (stream) => stream.annotated)),
517
+ undefined,
518
+ (bounds) =>
519
+ defer(
520
+ options,
521
+ Effect.map(checked, (stream) => narrowByParsedBounds(stream, bounds)),
522
+ ),
523
+ () =>
524
+ defer(
525
+ {
526
+ ...options,
527
+ orderDirection: QueryStreamOrderDirection.flip(
528
+ options.orderDirection,
529
+ ),
530
+ },
531
+ Effect.map(checked, reverse),
532
+ ),
533
+ );
534
+ };
535
+
444
536
  // -----------------------------------------------------------------------------
445
537
  // Constructors
446
538
  // -----------------------------------------------------------------------------
@@ -2140,6 +2232,98 @@ const narrowInMemory = <
2140
2232
  // Sinks
2141
2233
  // -----------------------------------------------------------------------------
2142
2234
 
2235
+ /**
2236
+ * Read limits for `collect`. These count underlying index reads, including
2237
+ * filtered rows and join inputs, rather than just emitted values. At either
2238
+ * limit, one extra row may be read to distinguish completion from an overrun;
2239
+ * it counts toward reported reads but is never emitted. This also applies at
2240
+ * zero, so an empty stream completes under a zero budget.
2241
+ *
2242
+ * @experimental
2243
+ */
2244
+ export interface CollectOptions {
2245
+ readonly maximumRowsRead?: number;
2246
+ readonly maximumBytesRead?: number;
2247
+ }
2248
+
2249
+ /**
2250
+ * Collect the whole query stream or fail with `ReadBudgetExceededError` when a
2251
+ * read budget stops it. No partial array reaches the caller. Arbitrary I/O in
2252
+ * callbacks is not counted. Use `paginate` for data that can grow without
2253
+ * bound.
2254
+ *
2255
+ * With explicit options, each run gets a fresh budget. Without options, use the
2256
+ * enclosing budget if present, or the default row budget.
2257
+ *
2258
+ * @experimental
2259
+ */
2260
+ export const collect: {
2261
+ (
2262
+ options?: CollectOptions,
2263
+ ): <Doc, KeyLabels extends QueryStreamKeyLabels.QueryStreamKeyLabels, E, R>(
2264
+ self: QueryStream<
2265
+ Doc,
2266
+ KeyLabels,
2267
+ QueryStreamOrderDirection.QueryStreamOrderDirection,
2268
+ E,
2269
+ R
2270
+ >,
2271
+ ) => Effect.Effect<Array<Doc>, E | ReadBudgetExceededError, R>;
2272
+ <Doc, KeyLabels extends QueryStreamKeyLabels.QueryStreamKeyLabels, E, R>(
2273
+ self: QueryStream<
2274
+ Doc,
2275
+ KeyLabels,
2276
+ QueryStreamOrderDirection.QueryStreamOrderDirection,
2277
+ E,
2278
+ R
2279
+ >,
2280
+ options?: CollectOptions,
2281
+ ): Effect.Effect<Array<Doc>, E | ReadBudgetExceededError, R>;
2282
+ } = dual(
2283
+ (args) => isQueryStream(args[0]),
2284
+ Effect.fn("QueryStream.collect")(function* <
2285
+ Doc,
2286
+ KeyLabels extends QueryStreamKeyLabels.QueryStreamKeyLabels,
2287
+ E,
2288
+ R,
2289
+ >(
2290
+ self: QueryStream<
2291
+ Doc,
2292
+ KeyLabels,
2293
+ QueryStreamOrderDirection.QueryStreamOrderDirection,
2294
+ E,
2295
+ R
2296
+ >,
2297
+ options?: CollectOptions,
2298
+ ) {
2299
+ const makeBudget = Schema.decodeEffect(QueryStreamReadBudget.Limits)({
2300
+ maximumRowsRead: DEFAULT_MAXIMUM_ROWS_READ,
2301
+ ...options,
2302
+ }).pipe(
2303
+ Effect.catchTag("SchemaError", (cause) =>
2304
+ Effect.die(new QueryStreamReadBudget.InvalidReadLimitError({ cause })),
2305
+ ),
2306
+ Effect.flatMap(QueryStreamReadBudget.make),
2307
+ );
2308
+ const budget = yield* options === undefined
2309
+ ? Effect.serviceOption(QueryStreamReadBudget.QueryStreamReadBudget).pipe(
2310
+ Effect.flatMap(
2311
+ Option.match({ onNone: () => makeBudget, onSome: Effect.succeed }),
2312
+ ),
2313
+ )
2314
+ : makeBudget;
2315
+ const rows = yield* Stream.runCollect(self.toStream()).pipe(
2316
+ Effect.provideService(
2317
+ QueryStreamReadBudget.QueryStreamReadBudget,
2318
+ budget,
2319
+ ),
2320
+ );
2321
+ if (yield* budget.isStopped)
2322
+ return yield* new ReadBudgetExceededError(yield* budget.getReadCounts);
2323
+ return rows;
2324
+ }),
2325
+ );
2326
+
2143
2327
  /**
2144
2328
  * `unique` found at least two emitted values. Narrow the query if at most one
2145
2329
  * value was expected, or use another consumer to handle multiple results.
@@ -2200,11 +2384,16 @@ export const unique = Effect.fn("QueryStream.unique")(
2200
2384
  * - `endCursor`: optional inclusive boundary returned by a previous page. Pins
2201
2385
  * the page to a key range regardless of how many values it holds.
2202
2386
  * - `maximumRowsRead`: optional budget for physical document reads from
2203
- * underlying query-stream indexes, including filtered documents.
2387
+ * underlying query-stream indexes, including filtered documents. Defaults to
2388
+ * 2,000; an explicit limit overrides the default.
2204
2389
  * - `maximumBytesRead`: optional budget charging estimated document size on every
2205
2390
  * read, not Convex's exact billed bytes. The final document can take the
2206
2391
  * total over the limit because its size is known only after reading it.
2207
2392
  *
2393
+ * At either read limit, including zero, one extra row may be read to
2394
+ * distinguish completion from an overrun. It is counted but never emitted. An
2395
+ * empty stream completes under a zero budget.
2396
+ *
2208
2397
  * With `numItems: 0`, an existing cursor is returned unchanged with an empty
2209
2398
  * page and `isDone: false`; a null cursor dies with `EmptyInitialPageError`.
2210
2399
  *
@@ -2396,7 +2585,7 @@ export const paginate: {
2396
2585
  () => QueryStreamPagination.initial<Doc>(),
2397
2586
  (state) => state._tag === "Reading",
2398
2587
  (state, { doc, keyValues }: Element<Doc>) =>
2399
- Effect.map(readBudget.isExhausted, (hitLimit) =>
2588
+ Effect.map(readBudget.isStopped, (hitLimit) =>
2400
2589
  QueryStreamPagination.record(
2401
2590
  request,
2402
2591
  state,
@@ -2463,7 +2652,10 @@ export const paginate: {
2463
2652
  Effect.provideServiceEffect(
2464
2653
  effect,
2465
2654
  QueryStreamReadBudget.QueryStreamReadBudget,
2466
- Schema.decodeEffect(QueryStreamReadBudget.Limits)(options).pipe(
2655
+ Schema.decodeEffect(QueryStreamReadBudget.Limits)({
2656
+ maximumRowsRead: DEFAULT_MAXIMUM_ROWS_READ,
2657
+ ...options,
2658
+ }).pipe(
2467
2659
  Effect.catchTag("SchemaError", (cause) =>
2468
2660
  Effect.die(
2469
2661
  new QueryStreamReadBudget.InvalidReadLimitError({ cause }),
@@ -1,12 +1,12 @@
1
1
  import * as Array from "effect/Array";
2
2
  import * as Effect from "effect/Effect";
3
- import * as QueryStreamKey from "./QueryStreamKey";
3
+ import * as QueryStreamKey from "./QueryStreamKey.js";
4
4
  import * as SchemaIssue from "effect/SchemaIssue";
5
5
  import * as Match from "effect/Match";
6
6
  import * as Schema from "effect/Schema";
7
7
  import * as SchemaGetter from "effect/SchemaGetter";
8
- import * as QueryStreamKeyLayout from "./QueryStreamKeyLayout";
9
- import * as QueryStreamKeyValues from "./QueryStreamKeyValues";
8
+ import * as QueryStreamKeyLayout from "./QueryStreamKeyLayout.js";
9
+ import * as QueryStreamKeyValues from "./QueryStreamKeyValues.js";
10
10
 
11
11
  // Serialized labels are a cursor boundary representation. They include every
12
12
  // runtime position but do not preserve implicitness.
@@ -1,8 +1,8 @@
1
1
  import * as Array from "effect/Array";
2
2
  import * as Data from "effect/Data";
3
3
  import * as Result from "effect/Result";
4
- import type * as QueryStreamKey from "./QueryStreamKey";
5
- import type * as QueryStreamKeyValues from "./QueryStreamKeyValues";
4
+ import type * as QueryStreamKey from "./QueryStreamKey.js";
5
+ import type * as QueryStreamKeyValues from "./QueryStreamKeyValues.js";
6
6
 
7
7
  const TypeId = "~@confect/server/QueryStreamIndexPrefix";
8
8
 
@@ -11,10 +11,10 @@ import * as Match from "effect/Match";
11
11
  import * as Option from "effect/Option";
12
12
  import * as Result from "effect/Result";
13
13
  import type * as Types from "effect/Types";
14
- import * as QueryStreamIndexPrefix from "./QueryStreamIndexPrefix";
15
- import * as QueryStreamKeyBounds from "./QueryStreamKeyBounds";
16
- import * as QueryStreamKeyValues from "./QueryStreamKeyValues";
17
- import type * as QueryStreamOrderDirection from "./QueryStreamOrderDirection";
14
+ import * as QueryStreamIndexPrefix from "./QueryStreamIndexPrefix.js";
15
+ import * as QueryStreamKeyBounds from "./QueryStreamKeyBounds.js";
16
+ import * as QueryStreamKeyValues from "./QueryStreamKeyValues.js";
17
+ import type * as QueryStreamOrderDirection from "./QueryStreamOrderDirection.js";
18
18
 
19
19
  type Head<FieldPaths extends ReadonlyArray<string>> =
20
20
  FieldPaths extends readonly [infer H extends string, ...ReadonlyArray<string>]
@@ -1,8 +1,8 @@
1
1
  import * as Data from "effect/Data";
2
2
  import * as Predicate from "effect/Predicate";
3
3
  import * as Result from "effect/Result";
4
- import * as QueryStreamKeyLayout from "./QueryStreamKeyLayout";
5
- import type * as QueryStreamKeyValues from "./QueryStreamKeyValues";
4
+ import * as QueryStreamKeyLayout from "./QueryStreamKeyLayout.js";
5
+ import type * as QueryStreamKeyValues from "./QueryStreamKeyValues.js";
6
6
 
7
7
  const TypeId = "~@confect/server/QueryStreamKey";
8
8
 
@@ -3,9 +3,9 @@ import * as Data from "effect/Data";
3
3
  import * as Option from "effect/Option";
4
4
  import * as Order from "effect/Order";
5
5
  import * as Result from "effect/Result";
6
- import * as QueryStreamKey from "./QueryStreamKey";
7
- import * as QueryStreamKeyLayout from "./QueryStreamKeyLayout";
8
- import * as QueryStreamKeyValues from "./QueryStreamKeyValues";
6
+ import * as QueryStreamKey from "./QueryStreamKey.js";
7
+ import * as QueryStreamKeyLayout from "./QueryStreamKeyLayout.js";
8
+ import * as QueryStreamKeyValues from "./QueryStreamKeyValues.js";
9
9
 
10
10
  // A bound's key may be a *prefix* of the full key: bounding by `["a"]` means
11
11
  // bounding by the whole family of keys that start with `"a"`. To compare
@@ -6,7 +6,7 @@ import * as Option from "effect/Option";
6
6
  import * as Result from "effect/Result";
7
7
  import type * as Types from "effect/Types";
8
8
 
9
- import * as QueryStreamKeyLabels from "./QueryStreamKeyLabels";
9
+ import * as QueryStreamKeyLabels from "./QueryStreamKeyLabels.js";
10
10
 
11
11
  /**
12
12
  * One runtime position of a stream key. Explicit IDs and their aliases are
@@ -12,7 +12,7 @@ import * as Result from "effect/Result";
12
12
  import * as Schema from "effect/Schema";
13
13
  import * as SchemaGetter from "effect/SchemaGetter";
14
14
  import * as SchemaIssue from "effect/SchemaIssue";
15
- import type * as QueryStreamOrderDirection from "./QueryStreamOrderDirection";
15
+ import type * as QueryStreamOrderDirection from "./QueryStreamOrderDirection.js";
16
16
 
17
17
  const UNDEFINED_SENTINEL = { $undefined: true } as const;
18
18
  const KeyValue = Schema.Json.pipe(
@@ -4,8 +4,8 @@ import * as Match from "effect/Match";
4
4
  import * as Option from "effect/Option";
5
5
  import * as Result from "effect/Result";
6
6
  import * as Schema from "effect/Schema";
7
- import type * as QueryStreamKey from "./QueryStreamKey";
8
- import * as QueryStreamKeyValues from "./QueryStreamKeyValues";
7
+ import type * as QueryStreamKey from "./QueryStreamKey.js";
8
+ import * as QueryStreamKeyValues from "./QueryStreamKeyValues.js";
9
9
 
10
10
  const PageSize = Schema.Natural.pipe(
11
11
  Schema.brand("~@confect/server/QueryStreamPagination/PageSize"),