@confect/server 9.0.0-next.1 → 9.0.0-next.10

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 (190) hide show
  1. package/CHANGELOG.md +293 -4
  2. package/dist/ActionCtx.d.ts +4 -11
  3. package/dist/ActionCtx.d.ts.map +1 -1
  4. package/dist/ActionCtx.js +1 -1
  5. package/dist/ActionCtx.js.map +1 -1
  6. package/dist/ActionRunner.d.ts +8 -13
  7. package/dist/ActionRunner.d.ts.map +1 -1
  8. package/dist/ActionRunner.js +4 -3
  9. package/dist/ActionRunner.js.map +1 -1
  10. package/dist/Auth.d.ts +17 -23
  11. package/dist/Auth.d.ts.map +1 -1
  12. package/dist/Auth.js +5 -1
  13. package/dist/Auth.js.map +1 -1
  14. package/dist/BlobNotFoundError.d.ts +6 -12
  15. package/dist/BlobNotFoundError.d.ts.map +1 -1
  16. package/dist/BlobNotFoundError.js +1 -1
  17. package/dist/BlobNotFoundError.js.map +1 -1
  18. package/dist/ConvexConfigProvider.d.ts +2 -9
  19. package/dist/ConvexConfigProvider.d.ts.map +1 -1
  20. package/dist/ConvexConfigProvider.js +6 -1
  21. package/dist/ConvexConfigProvider.js.map +1 -1
  22. package/dist/CronJob.d.ts +12 -19
  23. package/dist/CronJob.d.ts.map +1 -1
  24. package/dist/CronJob.js +1 -1
  25. package/dist/CronJob.js.map +1 -1
  26. package/dist/CronJobs.d.ts +11 -18
  27. package/dist/CronJobs.d.ts.map +1 -1
  28. package/dist/CronJobs.js +11 -4
  29. package/dist/CronJobs.js.map +1 -1
  30. package/dist/DataModel.d.ts +24 -29
  31. package/dist/DataModel.d.ts.map +1 -1
  32. package/dist/DatabaseReader.d.ts +4323 -64
  33. package/dist/DatabaseReader.d.ts.map +1 -1
  34. package/dist/DatabaseReader.js +6 -6
  35. package/dist/DatabaseReader.js.map +1 -1
  36. package/dist/DatabaseSchema.d.ts +38 -130
  37. package/dist/DatabaseSchema.d.ts.map +1 -1
  38. package/dist/DatabaseSchema.js +20 -30
  39. package/dist/DatabaseSchema.js.map +1 -1
  40. package/dist/DatabaseWriter.d.ts +38 -42
  41. package/dist/DatabaseWriter.d.ts.map +1 -1
  42. package/dist/DatabaseWriter.js +8 -5
  43. package/dist/DatabaseWriter.js.map +1 -1
  44. package/dist/Document.d.ts +28 -37
  45. package/dist/Document.d.ts.map +1 -1
  46. package/dist/Document.js +5 -1
  47. package/dist/Document.js.map +1 -1
  48. package/dist/FunctionImpl.d.ts +30 -29
  49. package/dist/FunctionImpl.d.ts.map +1 -1
  50. package/dist/FunctionImpl.js +25 -14
  51. package/dist/FunctionImpl.js.map +1 -1
  52. package/dist/GroupImpl.d.ts +45 -41
  53. package/dist/GroupImpl.d.ts.map +1 -1
  54. package/dist/GroupImpl.js +42 -35
  55. package/dist/GroupImpl.js.map +1 -1
  56. package/dist/Handler.d.ts +34 -40
  57. package/dist/Handler.d.ts.map +1 -1
  58. package/dist/HttpApi.d.ts +21 -25
  59. package/dist/HttpApi.d.ts.map +1 -1
  60. package/dist/HttpApi.js +11 -6
  61. package/dist/HttpApi.js.map +1 -1
  62. package/dist/MutationCtx.d.ts +4 -11
  63. package/dist/MutationCtx.d.ts.map +1 -1
  64. package/dist/MutationCtx.js +1 -1
  65. package/dist/MutationCtx.js.map +1 -1
  66. package/dist/MutationRunner.d.ts +8 -13
  67. package/dist/MutationRunner.d.ts.map +1 -1
  68. package/dist/MutationRunner.js +4 -3
  69. package/dist/MutationRunner.js.map +1 -1
  70. package/dist/OrderedQuery.d.ts +16 -21
  71. package/dist/OrderedQuery.d.ts.map +1 -1
  72. package/dist/OrderedQuery.js +4 -1
  73. package/dist/OrderedQuery.js.map +1 -1
  74. package/dist/QueryCtx.d.ts +4 -11
  75. package/dist/QueryCtx.d.ts.map +1 -1
  76. package/dist/QueryCtx.js +1 -1
  77. package/dist/QueryCtx.js.map +1 -1
  78. package/dist/QueryInitializer.d.ts +34 -39
  79. package/dist/QueryInitializer.d.ts.map +1 -1
  80. package/dist/QueryInitializer.js +5 -1
  81. package/dist/QueryInitializer.js.map +1 -1
  82. package/dist/QueryRunner.d.ts +8 -13
  83. package/dist/QueryRunner.d.ts.map +1 -1
  84. package/dist/QueryRunner.js +4 -3
  85. package/dist/QueryRunner.js.map +1 -1
  86. package/dist/RegisteredConvexFunction.d.ts +1107 -60
  87. package/dist/RegisteredConvexFunction.d.ts.map +1 -1
  88. package/dist/RegisteredConvexFunction.js +14 -9
  89. package/dist/RegisteredConvexFunction.js.map +1 -1
  90. package/dist/RegisteredFunction.d.ts +48 -64
  91. package/dist/RegisteredFunction.d.ts.map +1 -1
  92. package/dist/RegisteredFunction.js +9 -5
  93. package/dist/RegisteredFunction.js.map +1 -1
  94. package/dist/RegisteredFunctions.d.ts +48 -26
  95. package/dist/RegisteredFunctions.d.ts.map +1 -1
  96. package/dist/RegisteredFunctions.js +22 -9
  97. package/dist/RegisteredFunctions.js.map +1 -1
  98. package/dist/RegisteredNodeFunction.d.ts +4 -14
  99. package/dist/RegisteredNodeFunction.d.ts.map +1 -1
  100. package/dist/RegisteredNodeFunction.js +5 -4
  101. package/dist/RegisteredNodeFunction.js.map +1 -1
  102. package/dist/RegistryItem.d.ts +17 -27
  103. package/dist/RegistryItem.d.ts.map +1 -1
  104. package/dist/RegistryItem.js +1 -1
  105. package/dist/RegistryItem.js.map +1 -1
  106. package/dist/Scheduler.d.ts +16 -20
  107. package/dist/Scheduler.d.ts.map +1 -1
  108. package/dist/Scheduler.js +10 -6
  109. package/dist/Scheduler.js.map +1 -1
  110. package/dist/SchemaToValidator.d.ts +71 -64
  111. package/dist/SchemaToValidator.d.ts.map +1 -1
  112. package/dist/SchemaToValidator.js +15 -3
  113. package/dist/SchemaToValidator.js.map +1 -1
  114. package/dist/StorageActionWriter.d.ts +21 -28
  115. package/dist/StorageActionWriter.d.ts.map +1 -1
  116. package/dist/StorageActionWriter.js +4 -1
  117. package/dist/StorageActionWriter.js.map +1 -1
  118. package/dist/StorageReader.d.ts +14 -21
  119. package/dist/StorageReader.d.ts.map +1 -1
  120. package/dist/StorageReader.js +5 -1
  121. package/dist/StorageReader.js.map +1 -1
  122. package/dist/StorageWriter.d.ts +16 -23
  123. package/dist/StorageWriter.d.ts.map +1 -1
  124. package/dist/StorageWriter.js +4 -1
  125. package/dist/StorageWriter.js.map +1 -1
  126. package/dist/Table.d.ts +204 -197
  127. package/dist/Table.d.ts.map +1 -1
  128. package/dist/Table.js +72 -62
  129. package/dist/Table.js.map +1 -1
  130. package/dist/TableInfo.d.ts +35 -41
  131. package/dist/TableInfo.d.ts.map +1 -1
  132. package/dist/VectorSearch.d.ts +30 -35
  133. package/dist/VectorSearch.d.ts.map +1 -1
  134. package/dist/VectorSearch.js +3 -1
  135. package/dist/VectorSearch.js.map +1 -1
  136. package/dist/index.d.ts +35 -36
  137. package/dist/index.d.ts.map +1 -0
  138. package/dist/index.js +4 -5
  139. package/dist/internal/utils.d.ts +9 -11
  140. package/dist/internal/utils.d.ts.map +1 -1
  141. package/dist/internal/utils.js +3 -1
  142. package/dist/internal/utils.js.map +1 -1
  143. package/dist/node.d.ts +2 -2
  144. package/dist/node.d.ts.map +1 -0
  145. package/dist/tsconfig.src.tsbuildinfo +1 -0
  146. package/package.json +50 -59
  147. package/src/ActionCtx.ts +1 -1
  148. package/src/ActionRunner.ts +2 -1
  149. package/src/Auth.ts +5 -1
  150. package/src/BlobNotFoundError.ts +1 -1
  151. package/src/ConvexConfigProvider.ts +6 -8
  152. package/src/CronJob.ts +1 -1
  153. package/src/CronJobs.ts +8 -10
  154. package/src/DatabaseReader.ts +18 -21
  155. package/src/DatabaseSchema.ts +38 -98
  156. package/src/DatabaseWriter.ts +13 -6
  157. package/src/Document.ts +5 -1
  158. package/src/FunctionImpl.ts +36 -44
  159. package/src/GroupImpl.ts +54 -81
  160. package/src/HttpApi.ts +8 -9
  161. package/src/MutationCtx.ts +1 -1
  162. package/src/MutationRunner.ts +2 -1
  163. package/src/OrderedQuery.ts +5 -1
  164. package/src/QueryCtx.ts +1 -1
  165. package/src/QueryInitializer.ts +15 -3
  166. package/src/QueryRunner.ts +2 -1
  167. package/src/RegisteredConvexFunction.ts +11 -7
  168. package/src/RegisteredFunction.ts +5 -1
  169. package/src/RegisteredFunctions.ts +69 -93
  170. package/src/RegisteredNodeFunction.ts +7 -6
  171. package/src/RegistryItem.ts +1 -1
  172. package/src/Scheduler.ts +5 -1
  173. package/src/SchemaToValidator.ts +14 -16
  174. package/src/StorageActionWriter.ts +4 -1
  175. package/src/StorageReader.ts +5 -1
  176. package/src/StorageWriter.ts +4 -1
  177. package/src/Table.ts +253 -132
  178. package/src/VectorSearch.ts +3 -1
  179. package/src/index.ts +0 -1
  180. package/src/internal/utils.ts +3 -1
  181. package/dist/Api.d.ts +0 -30
  182. package/dist/Api.d.ts.map +0 -1
  183. package/dist/Api.js +0 -26
  184. package/dist/Api.js.map +0 -1
  185. package/dist/GroupPath.d.ts +0 -8
  186. package/dist/GroupPath.d.ts.map +0 -1
  187. package/dist/GroupPath.js +0 -10
  188. package/dist/GroupPath.js.map +0 -1
  189. package/src/Api.ts +0 -75
  190. package/src/GroupPath.ts +0 -43
package/src/GroupImpl.ts CHANGED
@@ -1,20 +1,16 @@
1
1
  import type * as GroupSpec from "@confect/core/GroupSpec";
2
2
  import * as Registry from "@confect/core/Registry";
3
- import {
4
- Array,
5
- Context,
6
- Effect,
7
- Layer,
8
- Option,
9
- pipe,
10
- Predicate,
11
- Record,
12
- Ref,
13
- String,
14
- } from "effect";
15
- import type * as Api from "./Api";
3
+ import { pipe } from "effect/Function";
4
+ import * as Array from "effect/Array";
5
+ import * as Context from "effect/Context";
6
+ import * as Effect from "effect/Effect";
7
+ import * as Layer from "effect/Layer";
8
+ import * as Option from "effect/Option";
9
+ import * as Predicate from "effect/Predicate";
10
+ import * as Record from "effect/Record";
11
+ import * as Ref from "effect/Ref";
12
+ import type * as DatabaseSchema from "./DatabaseSchema";
16
13
  import type * as FunctionImpl from "./FunctionImpl";
17
- import { resolveGroupPathUnsafe } from "./GroupPath";
18
14
 
19
15
  export const TypeId = "@confect/server/GroupImpl";
20
16
  export type TypeId = typeof TypeId;
@@ -22,11 +18,9 @@ export type TypeId = typeof TypeId;
22
18
  export type FinalizationStatus = "Unfinalized" | "Finalized";
23
19
 
24
20
  export interface GroupImpl<
25
- GroupPath_ extends string,
26
21
  FinalizationStatus_ extends FinalizationStatus = "Unfinalized",
27
22
  > {
28
23
  readonly [TypeId]: TypeId;
29
- readonly groupPath: GroupPath_;
30
24
  readonly finalizationStatus: FinalizationStatus_;
31
25
  /**
32
26
  * Names of every function registered into this group's layer scope by
@@ -37,13 +31,13 @@ export interface GroupImpl<
37
31
  readonly registeredFunctionNames: ReadonlyArray<string>;
38
32
  }
39
33
 
40
- export interface Any extends GroupImpl<string, FinalizationStatus> {}
34
+ export interface Any extends GroupImpl<FinalizationStatus> {}
41
35
 
42
36
  export const isGroupImpl = (u: unknown): u is Any =>
43
37
  Predicate.hasProperty(u, TypeId);
44
38
 
45
- export interface AnyFinalized extends GroupImpl<string, "Finalized"> {}
46
- export interface AnyUnfinalized extends GroupImpl<string, "Unfinalized"> {}
39
+ export interface AnyFinalized extends GroupImpl<"Finalized"> {}
40
+ export interface AnyUnfinalized extends GroupImpl<"Unfinalized"> {}
47
41
 
48
42
  export const isFinalizedGroupImpl = (u: unknown): u is AnyFinalized =>
49
43
  isGroupImpl(u) && u.finalizationStatus === "Finalized";
@@ -55,83 +49,71 @@ export const isUnfinalizedGroupImpl = (u: unknown): u is AnyUnfinalized =>
55
49
  * Build the runtime tag for a `GroupImpl` service. The finalization status is
56
50
  * embedded in the tag string so that `Unfinalized` and `Finalized` are distinct
57
51
  * services at runtime; consumers of a finalized layer (the server's
58
- * `RegisteredFunctions.buildForGroup` and the CLI's `implValidation`) retrieve
52
+ * `RegisteredFunctions.buildForGroup` and the CLI's `validateImpl`) retrieve
59
53
  * the typed `Finalized` service directly rather than scanning the context.
54
+ *
55
+ * The tag is keyed only by finalization status — no group path — because each
56
+ * group's impl layer is built in its own isolated scope (`buildForGroup` /
57
+ * `validateImpl` each provide a fresh `Registry`), so at most one `GroupImpl`
58
+ * service of each status exists per build.
60
59
  */
61
- export const GroupImpl = <
62
- GroupPath_ extends string,
63
- FinalizationStatus_ extends FinalizationStatus,
64
- >({
65
- groupPath,
60
+ export const GroupImpl = <FinalizationStatus_ extends FinalizationStatus>({
66
61
  finalizationStatus,
67
62
  }: {
68
- groupPath: GroupPath_;
69
63
  finalizationStatus: FinalizationStatus_;
70
64
  }) =>
71
- Context.GenericTag<GroupImpl<GroupPath_, FinalizationStatus_>>(
72
- `@confect/server/GroupImpl/${finalizationStatus}/${groupPath}`,
65
+ Context.GenericTag<GroupImpl<FinalizationStatus_>>(
66
+ `@confect/server/GroupImpl/${finalizationStatus}`,
73
67
  );
74
68
 
69
+ /**
70
+ * Begin a group's impl layer. `databaseSchema` and `group` are retained only as
71
+ * type-level carriers (`group` drives the required `FunctionImpl` services via
72
+ * `FromGroupSpec<Group>`; `databaseSchema` keeps the impl's dependency on
73
+ * `_generated/schema` symmetric with `FunctionImpl.make`). Neither is read at
74
+ * runtime.
75
+ */
75
76
  export const make = <
76
- Api_ extends Api.AnyWithProps,
77
+ DatabaseSchema_ extends DatabaseSchema.AnyWithProps,
77
78
  Group extends GroupSpec.AnyWithProps,
78
79
  >(
79
- api: Api_,
80
- group: Group,
80
+ _databaseSchema: DatabaseSchema_,
81
+ _group: Group,
81
82
  ): Layer.Layer<
82
- GroupImpl<string, "Unfinalized">,
83
+ GroupImpl<"Unfinalized">,
83
84
  never,
84
85
  FunctionImpl.FromGroupSpec<Group>
85
- > => {
86
- const groupPath = resolveGroupPathUnsafe(api.spec, group);
87
-
88
- return Layer.succeed(
89
- GroupImpl<string, "Unfinalized">({
90
- groupPath,
91
- finalizationStatus: "Unfinalized",
92
- }),
86
+ > =>
87
+ Layer.succeed(
88
+ GroupImpl<"Unfinalized">({ finalizationStatus: "Unfinalized" }),
93
89
  {
94
90
  [TypeId]: TypeId,
95
- groupPath,
96
91
  finalizationStatus: "Unfinalized" as const,
97
92
  registeredFunctionNames: [],
98
93
  },
99
94
  ) as Layer.Layer<
100
- GroupImpl<string, "Unfinalized">,
95
+ GroupImpl<"Unfinalized">,
101
96
  never,
102
97
  FunctionImpl.FromGroupSpec<Group>
103
98
  >;
104
- };
105
99
 
106
100
  const isFunctionShaped = (value: unknown): boolean =>
107
101
  Predicate.isRecord(value) && "functionSpec" in value;
108
102
 
109
103
  /**
110
- * Walk a `RegistryItems` tree to the entries at `groupPath` and return the
111
- * names of the function-shaped leaves directly underneath.
104
+ * Return the names of the function-shaped entries in a group's (flat,
105
+ * isolated) registry. `FunctionImpl.make` registers each function under a
106
+ * single-segment key, so the registry built for one group contains exactly
107
+ * that group's functions at the top level.
112
108
  */
113
- const collectFunctionNamesAtPath = (
109
+ const collectFunctionNames = (
114
110
  items: Registry.RegistryItems,
115
- groupPath: string,
116
111
  ): ReadonlyArray<string> =>
117
112
  pipe(
118
- String.split(groupPath, "."),
119
- Array.reduce(Option.some<unknown>(items), (acc, segment) =>
120
- acc.pipe(
121
- Option.filter(Predicate.isRecord),
122
- Option.flatMap((node) =>
123
- segment in node ? Option.some(node[segment]) : Option.none(),
124
- ),
125
- ),
113
+ Record.toEntries(items),
114
+ Array.filterMap(([name, value]) =>
115
+ isFunctionShaped(value) ? Option.some(name) : Option.none(),
126
116
  ),
127
- Option.filter(Predicate.isRecord),
128
- Option.map(Record.toEntries),
129
- Option.map(
130
- Array.filterMap(([name, value]) =>
131
- isFunctionShaped(value) ? Option.some(name) : Option.none(),
132
- ),
133
- ),
134
- Option.getOrElse((): ReadonlyArray<string> => []),
135
117
  );
136
118
 
137
119
  const findUnfinalizedGroupImpl = <S>(
@@ -152,12 +134,12 @@ const findUnfinalizedGroupImpl = <S>(
152
134
  * impl completeness against a `GroupSpec`'s expected functions without
153
135
  * having to inspect the `Registry` themselves.
154
136
  */
155
- export const finalize = <GroupPath_ extends string>(
156
- group: Layer.Layer<GroupImpl<GroupPath_, "Unfinalized">>,
157
- ): Layer.Layer<GroupImpl<GroupPath_, "Finalized">> =>
137
+ export const finalize = (
138
+ group: Layer.Layer<GroupImpl<"Unfinalized">>,
139
+ ): Layer.Layer<GroupImpl<"Finalized">> =>
158
140
  Layer.flatMap(
159
141
  group,
160
- (context): Layer.Layer<GroupImpl<GroupPath_, "Finalized">> =>
142
+ (context): Layer.Layer<GroupImpl<"Finalized">> =>
161
143
  findUnfinalizedGroupImpl(context).pipe(
162
144
  Option.match({
163
145
  onNone: () =>
@@ -166,28 +148,19 @@ export const finalize = <GroupPath_ extends string>(
166
148
  "GroupImpl.finalize: no Unfinalized GroupImpl service was found in the layer's context.",
167
149
  ),
168
150
  ),
169
- onSome: (unfinalized) => {
170
- const groupPath = unfinalized.groupPath as GroupPath_;
171
- return Layer.effect(
172
- GroupImpl<GroupPath_, "Finalized">({
173
- groupPath,
174
- finalizationStatus: "Finalized",
175
- }),
151
+ onSome: () =>
152
+ Layer.effect(
153
+ GroupImpl<"Finalized">({ finalizationStatus: "Finalized" }),
176
154
  Effect.gen(function* () {
177
155
  const registry = yield* Registry.Registry;
178
156
  const items = yield* Ref.get(registry);
179
157
  return {
180
158
  [TypeId]: TypeId,
181
- groupPath,
182
159
  finalizationStatus: "Finalized" as const,
183
- registeredFunctionNames: collectFunctionNamesAtPath(
184
- items,
185
- groupPath,
186
- ),
160
+ registeredFunctionNames: collectFunctionNames(items),
187
161
  };
188
162
  }),
189
- );
190
- },
163
+ ),
191
164
  }),
192
165
  ),
193
166
  );
package/src/HttpApi.ts CHANGED
@@ -1,11 +1,7 @@
1
- import {
2
- type HttpApi,
3
- HttpApiBuilder,
4
- HttpApiScalar,
5
- type HttpApp,
6
- type HttpRouter,
7
- HttpServer,
8
- } from "@effect/platform";
1
+ import type { HttpApi, HttpApp, HttpRouter } from "@effect/platform";
2
+ import * as HttpApiBuilder from "@effect/platform/HttpApiBuilder";
3
+ import * as HttpApiScalar from "@effect/platform/HttpApiScalar";
4
+ import * as HttpServer from "@effect/platform/HttpServer";
9
5
  import {
10
6
  type HttpRouter as ConvexHttpRouter,
11
7
  type GenericActionCtx,
@@ -15,7 +11,10 @@ import {
15
11
  ROUTABLE_HTTP_METHODS,
16
12
  type RouteSpecWithPathPrefix,
17
13
  } from "convex/server";
18
- import { Array, Layer, pipe, Record } from "effect";
14
+ import { pipe } from "effect/Function";
15
+ import * as Array from "effect/Array";
16
+ import * as Layer from "effect/Layer";
17
+ import * as Record from "effect/Record";
19
18
  import * as ActionCtx from "./ActionCtx";
20
19
  import * as ActionRunner from "./ActionRunner";
21
20
  import * as Auth from "./Auth";
@@ -1,5 +1,5 @@
1
1
  import type { GenericDataModel, GenericMutationCtx } from "convex/server";
2
- import { Context } from "effect";
2
+ import * as Context from "effect/Context";
3
3
 
4
4
  export const MutationCtx = <DataModel extends GenericDataModel>() =>
5
5
  Context.GenericTag<GenericMutationCtx<DataModel>>(
@@ -1,7 +1,8 @@
1
1
  import * as Ref from "@confect/core/Ref";
2
2
  import { type GenericMutationCtx } from "convex/server";
3
3
  import type { ParseResult, Effect } from "effect";
4
- import { Context, Layer } from "effect";
4
+ import * as Context from "effect/Context";
5
+ import * as Layer from "effect/Layer";
5
6
 
6
7
  const make =
7
8
  (runMutation: GenericMutationCtx<any>["runMutation"]) =>
@@ -4,7 +4,11 @@ import type {
4
4
  OrderedQuery as ConvexOrderedQuery,
5
5
  PaginationResult,
6
6
  } from "convex/server";
7
- import { Chunk, Effect, identity, type Option, pipe, Stream } from "effect";
7
+ import { identity, pipe } from "effect/Function";
8
+ import type { Option } from "effect";
9
+ import * as Chunk from "effect/Chunk";
10
+ import * as Effect from "effect/Effect";
11
+ import * as Stream from "effect/Stream";
8
12
  import * as Document from "./Document";
9
13
  import type * as TableInfo from "./TableInfo";
10
14
 
package/src/QueryCtx.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { GenericDataModel, GenericQueryCtx } from "convex/server";
2
- import { Context } from "effect";
2
+ import * as Context from "effect/Context";
3
3
 
4
4
  export const QueryCtx = <DataModel extends GenericDataModel>() =>
5
5
  Context.GenericTag<GenericQueryCtx<DataModel>>("@confect/server/QueryCtx");
@@ -16,7 +16,11 @@ import type {
16
16
  SearchIndexes,
17
17
  } from "convex/server";
18
18
  import type { GenericId } from "convex/values";
19
- import { Array, Effect, Either, pipe, Schema } from "effect";
19
+ import { pipe } from "effect/Function";
20
+ import * as Array from "effect/Array";
21
+ import * as Effect from "effect/Effect";
22
+ import * as Either from "effect/Either";
23
+ import * as Schema from "effect/Schema";
20
24
  import type {
21
25
  BaseDatabaseReader,
22
26
  IndexFieldTypesForEq,
@@ -238,7 +242,13 @@ export const make = <
238
242
  return OrderedQuery.make<
239
243
  DataModel.TableInfoWithName_<DataModel_, TableName>,
240
244
  TableName
241
- >(orderedQuery, tableName, table.Fields);
245
+ >(
246
+ orderedQuery,
247
+ tableName,
248
+ table.Fields as TableInfo.TableSchema<
249
+ DataModel.TableInfoWithName_<DataModel_, TableName>
250
+ >,
251
+ );
242
252
  };
243
253
 
244
254
  const search: QueryInitializerFunction<"search"> = (
@@ -253,7 +263,9 @@ export const make = <
253
263
  .query(tableName)
254
264
  .withSearchIndex(indexName, searchFilter),
255
265
  tableName,
256
- table.Fields,
266
+ table.Fields as TableInfo.TableSchema<
267
+ DataModel.TableInfoWithName_<DataModel_, TableName>
268
+ >,
257
269
  );
258
270
 
259
271
  return {
@@ -1,7 +1,8 @@
1
1
  import * as Ref from "@confect/core/Ref";
2
2
  import { type GenericQueryCtx } from "convex/server";
3
3
  import type { ParseResult, Effect } from "effect";
4
- import { Context, Layer } from "effect";
4
+ import * as Context from "effect/Context";
5
+ import * as Layer from "effect/Layer";
5
6
 
6
7
  const make =
7
8
  (runQuery: GenericQueryCtx<any>["runQuery"]) =>
@@ -11,8 +11,12 @@ import {
11
11
  queryGeneric,
12
12
  } from "convex/server";
13
13
  import type { Value } from "convex/values";
14
- import { Clock, Effect, Layer, Match, pipe, Schema } from "effect";
15
- import type * as Api from "./Api";
14
+ import { pipe } from "effect/Function";
15
+ import * as Clock from "effect/Clock";
16
+ import * as Effect from "effect/Effect";
17
+ import * as Layer from "effect/Layer";
18
+ import * as Match from "effect/Match";
19
+ import * as Schema from "effect/Schema";
16
20
  import * as Auth from "./Auth";
17
21
  import * as ConvexConfigProvider from "./ConvexConfigProvider";
18
22
  import * as DatabaseReader from "./DatabaseReader";
@@ -31,8 +35,8 @@ import * as SchemaToValidator from "./SchemaToValidator";
31
35
  import { StorageReader } from "./StorageReader";
32
36
  import { StorageWriter } from "./StorageWriter";
33
37
 
34
- export const make = <Api_ extends Api.AnyWithPropsWithRuntime<"Convex">>(
35
- api: Api_,
38
+ export const make = (
39
+ databaseSchema: DatabaseSchema.AnyWithProps,
36
40
  { functionSpec, handler }: RegistryItem.AnyWithProps,
37
41
  ): RegisteredFunction.Any =>
38
42
  Match.value(functionSpec.functionProvenance).pipe(
@@ -51,7 +55,7 @@ export const make = <Api_ extends Api.AnyWithPropsWithRuntime<"Convex">>(
51
55
 
52
56
  return genericFunction(
53
57
  queryFunction({
54
- databaseSchema: api.databaseSchema,
58
+ databaseSchema,
55
59
  args: functionProvenance.args,
56
60
  returns: functionProvenance.returns,
57
61
  error: functionProvenance.error,
@@ -68,7 +72,7 @@ export const make = <Api_ extends Api.AnyWithPropsWithRuntime<"Convex">>(
68
72
 
69
73
  return genericFunction(
70
74
  mutationFunction({
71
- databaseSchema: api.databaseSchema,
75
+ databaseSchema,
72
76
  args: functionProvenance.args,
73
77
  returns: functionProvenance.returns,
74
78
  error: functionProvenance.error,
@@ -84,7 +88,7 @@ export const make = <Api_ extends Api.AnyWithPropsWithRuntime<"Convex">>(
84
88
  );
85
89
 
86
90
  return genericFunction(
87
- convexActionFunction(api.databaseSchema, {
91
+ convexActionFunction(databaseSchema, {
88
92
  args: functionProvenance.args,
89
93
  returns: functionProvenance.returns,
90
94
  error: functionProvenance.error,
@@ -10,7 +10,11 @@ import {
10
10
  } from "convex/server";
11
11
  import type { Value } from "convex/values";
12
12
  import { ConvexError } from "convex/values";
13
- import { Effect, Either, Layer, pipe, Schema } from "effect";
13
+ import { pipe } from "effect/Function";
14
+ import * as Effect from "effect/Effect";
15
+ import * as Either from "effect/Either";
16
+ import * as Layer from "effect/Layer";
17
+ import * as Schema from "effect/Schema";
14
18
  import * as ActionCtx from "./ActionCtx";
15
19
  import * as ActionRunner from "./ActionRunner";
16
20
  import * as Auth from "./Auth";
@@ -2,18 +2,10 @@ import type * as FunctionSpec from "@confect/core/FunctionSpec";
2
2
  import type * as GroupSpec from "@confect/core/GroupSpec";
3
3
  import * as Registry from "@confect/core/Registry";
4
4
  import type * as Spec from "@confect/core/Spec";
5
- import {
6
- Array,
7
- Effect,
8
- type Layer,
9
- Option,
10
- pipe,
11
- Predicate,
12
- Ref,
13
- String,
14
- type Types,
15
- } from "effect";
16
- import type * as Api from "./Api";
5
+ import type { Layer, Types } from "effect";
6
+ import * as Effect from "effect/Effect";
7
+ import * as Ref from "effect/Ref";
8
+ import type * as DatabaseSchema from "./DatabaseSchema";
17
9
  import type * as GroupImpl from "./GroupImpl";
18
10
  import { mapLeaves } from "./internal/utils";
19
11
  import type * as RegisteredFunction from "./RegisteredFunction";
@@ -27,106 +19,90 @@ type RegisteredFunctionsHelper<Groups extends GroupSpec.AnyWithProps> = {
27
19
  Groups,
28
20
  GroupName
29
21
  > extends infer Group extends GroupSpec.AnyWithProps
30
- ? GroupSpec.Groups<Group> extends infer SubGroups extends
31
- GroupSpec.AnyWithProps
32
- ? Types.Simplify<
33
- RegisteredFunctionsHelper<SubGroups> & {
34
- [FunctionName in FunctionSpec.Name<
35
- GroupSpec.Functions<Group>
36
- >]: FunctionSpec.WithName<
37
- GroupSpec.Functions<Group>,
38
- FunctionName
39
- > extends infer FunctionSpec_ extends FunctionSpec.AnyWithProps
40
- ? RegisteredFunction.RegisteredFunction<FunctionSpec_>
41
- : never;
42
- }
43
- >
44
- : {
45
- [FunctionName in FunctionSpec.Name<
46
- GroupSpec.Functions<Group>
47
- >]: FunctionSpec.WithName<
48
- GroupSpec.Functions<Group>,
49
- FunctionName
50
- > extends infer FunctionSpec_ extends FunctionSpec.AnyWithProps
51
- ? RegisteredFunction.RegisteredFunction<FunctionSpec_>
52
- : never;
53
- }
22
+ ? RegisteredFunctionsForGroupSpec<Group>
54
23
  : never;
55
24
  };
56
25
 
26
+ /** The `RegisteredFunction` record for a group's own declared functions. */
27
+ type RegisteredFunctionsOf<Group extends GroupSpec.AnyWithProps> = {
28
+ [FunctionName in FunctionSpec.Name<
29
+ GroupSpec.Functions<Group>
30
+ >]: FunctionSpec.WithName<
31
+ GroupSpec.Functions<Group>,
32
+ FunctionName
33
+ > extends infer FunctionSpec_ extends FunctionSpec.AnyWithProps
34
+ ? RegisteredFunction.RegisteredFunction<FunctionSpec_>
35
+ : never;
36
+ };
37
+
38
+ /**
39
+ * The registered-functions record for a single group, derived from the group's
40
+ * own `GroupSpec`: its declared functions, plus any nested subgroups it carries
41
+ * directly. This is the node that `buildForGroup` returns — computed from the
42
+ * leaf `GroupSpec` itself rather than by navigating the project-wide assembled
43
+ * `Spec` to a dot-path, so the per-group registry's type depends only on its
44
+ * own leaf. For the filesystem layout a leaf `GroupSpec` carries no subgroups
45
+ * (subdirectory children are assembled separately into `_generated/spec.ts`),
46
+ * so this resolves to just the leaf's functions.
47
+ */
48
+ export type RegisteredFunctionsForGroupSpec<
49
+ Group extends GroupSpec.AnyWithProps,
50
+ > =
51
+ GroupSpec.Groups<Group> extends infer SubGroups extends GroupSpec.AnyWithProps
52
+ ? Types.Simplify<
53
+ RegisteredFunctionsHelper<SubGroups> & RegisteredFunctionsOf<Group>
54
+ >
55
+ : RegisteredFunctionsOf<Group>;
56
+
57
57
  export interface AnyWithProps {
58
58
  readonly [key: string]: RegisteredFunction.Any | AnyWithProps;
59
59
  }
60
60
 
61
- type RegisteredFunctionsAtPath<
62
- Tree,
63
- Path extends string,
64
- > = Path extends `${infer Head}.${infer Tail}`
65
- ? Head extends keyof Tree
66
- ? Tree[Head] extends AnyWithProps
67
- ? RegisteredFunctionsAtPath<Tree[Head], Tail>
68
- : never
69
- : never
70
- : Path extends keyof Tree
71
- ? Tree[Path]
72
- : never;
73
-
74
- export type ForGroupPath<
75
- Spec_ extends Spec.AnyWithProps,
76
- Path extends string,
77
- > = RegisteredFunctionsAtPath<RegisteredFunctions<Spec_>, Path>;
78
-
79
61
  /**
80
62
  * Build the registered Convex functions for a single group from its finalized
81
63
  * `GroupImpl` layer.
82
64
  *
83
- * The `groupLayer` parameter requires `GroupImpl<string, "Finalized">`, so
84
- * impls that were never piped through `GroupImpl.finalize` (and impls with
85
- * unmet `FunctionImpl` requirements, which cannot be finalized) are rejected
86
- * at the codegen boundary, not just deep inside Convex at runtime.
65
+ * The `groupLayer` parameter requires `GroupImpl<"Finalized">`, so impls that
66
+ * were never piped through `GroupImpl.finalize` (and impls with unmet
67
+ * `FunctionImpl` requirements, which cannot be finalized) are rejected at the
68
+ * codegen boundary, not just deep inside Convex at runtime.
69
+ *
70
+ * The group layer is built with a fresh, isolated `Registry` (rather than the
71
+ * globally-cached default `Context.Reference`), so each `FunctionImpl.make`
72
+ * registers under its flat, single-segment function-name key without colliding
73
+ * with any other group built in the same process — the built registry holds
74
+ * exactly this group's functions at the top level.
75
+ *
76
+ * Only the runtime `databaseSchema` value is needed at runtime (it is forwarded
77
+ * to `makeRegisteredFunction` to build each function's ctx services); the
78
+ * group's `GroupSpec` is supplied purely as the `Group` type parameter to shape
79
+ * the returned record. The generated caller passes it explicitly and imports
80
+ * the leaf spec type-only (`typeof import("…/<group>.spec")["default"]`), so a
81
+ * function's bundle never imports a spec module at runtime.
87
82
  */
88
- export const buildForGroup = <
89
- Api_ extends Api.AnyWithProps,
90
- const GroupPath_ extends string,
91
- >(
92
- api: Api_,
93
- groupPath: GroupPath_,
94
- groupLayer: Layer.Layer<GroupImpl.GroupImpl<string, "Finalized">>,
83
+ export const buildForGroup = <Group extends GroupSpec.AnyWithProps>(
84
+ databaseSchema: DatabaseSchema.AnyWithProps,
85
+ groupLayer: Layer.Layer<GroupImpl.GroupImpl<"Finalized">>,
95
86
  makeRegisteredFunction: (
96
- api: Api_,
87
+ databaseSchema: DatabaseSchema.AnyWithProps,
97
88
  registryItem: RegistryItem.AnyWithProps,
98
89
  ) => RegisteredFunction.Any,
99
- ): ForGroupPath<Api_["spec"], GroupPath_> => {
90
+ ): RegisteredFunctionsForGroupSpec<Group> => {
100
91
  const registryItems = Effect.gen(function* () {
101
92
  const registry = yield* Registry.Registry;
102
93
  return yield* Ref.get(registry);
103
- }).pipe(Effect.provide(groupLayer), Effect.runSync);
94
+ }).pipe(
95
+ Effect.provide(groupLayer),
96
+ Effect.provideService(
97
+ Registry.Registry,
98
+ Ref.unsafeMake<Registry.RegistryItems>({}),
99
+ ),
100
+ Effect.runSync,
101
+ );
104
102
 
105
- const registeredFunctions = mapLeaves<
106
- RegistryItem.AnyWithProps,
107
- RegisteredFunction.Any
108
- >(
103
+ return mapLeaves<RegistryItem.AnyWithProps, RegisteredFunction.Any>(
109
104
  registryItems as { [key: string]: RegistryItem.AnyWithProps },
110
105
  RegistryItem.isRegistryItem,
111
- (registryItem) => makeRegisteredFunction(api, registryItem),
112
- );
113
-
114
- return pipe(
115
- String.split(groupPath, "."),
116
- Array.reduce(
117
- Option.some<unknown>(registeredFunctions),
118
- (currentNode, segment) =>
119
- currentNode.pipe(
120
- Option.filter(Predicate.isRecord),
121
- Option.flatMap((nodeRecord) =>
122
- segment in nodeRecord
123
- ? Option.some(nodeRecord[segment])
124
- : Option.none(),
125
- ),
126
- ),
127
- ),
128
- Option.getOrThrowWith(
129
- () => new Error(`No functions registered for group path "${groupPath}"`),
130
- ),
131
- ) as ForGroupPath<Api_["spec"], GroupPath_>;
106
+ (registryItem) => makeRegisteredFunction(databaseSchema, registryItem),
107
+ ) as RegisteredFunctionsForGroupSpec<Group>;
132
108
  };
@@ -1,20 +1,21 @@
1
1
  import type * as FunctionSpec from "@confect/core/FunctionSpec";
2
- import { NodeContext } from "@effect/platform-node";
2
+ import * as NodeContext from "@effect/platform-node/NodeContext";
3
3
  import {
4
4
  actionGeneric,
5
5
  type DefaultFunctionArgs,
6
6
  internalActionGeneric,
7
7
  } from "convex/server";
8
8
  import type { Effect } from "effect";
9
- import { Layer, Match, type Schema } from "effect";
10
- import type * as Api from "./Api";
9
+ import type { Schema } from "effect";
10
+ import * as Layer from "effect/Layer";
11
+ import * as Match from "effect/Match";
11
12
  import type * as DatabaseSchema from "./DatabaseSchema";
12
13
  import type * as Handler from "./Handler";
13
14
  import * as RegisteredFunction from "./RegisteredFunction";
14
15
  import type * as RegistryItem from "./RegistryItem";
15
16
 
16
- export const make = <Api_ extends Api.AnyWithPropsWithRuntime<"Node">>(
17
- api: Api_,
17
+ export const make = (
18
+ databaseSchema: DatabaseSchema.AnyWithProps,
18
19
  { functionSpec, handler }: RegistryItem.AnyWithProps,
19
20
  ): RegisteredFunction.Any =>
20
21
  Match.value(functionSpec.functionProvenance).pipe(
@@ -30,7 +31,7 @@ export const make = <Api_ extends Api.AnyWithPropsWithRuntime<"Node">>(
30
31
  );
31
32
 
32
33
  return genericFunction(
33
- nodeActionFunction(api.databaseSchema, {
34
+ nodeActionFunction(databaseSchema, {
34
35
  args: functionProvenance.args,
35
36
  returns: functionProvenance.returns,
36
37
  error: functionProvenance.error,
@@ -1,5 +1,5 @@
1
1
  import type * as FunctionSpec from "@confect/core/FunctionSpec";
2
- import { Predicate } from "effect";
2
+ import * as Predicate from "effect/Predicate";
3
3
  import type * as DatabaseSchema from "./DatabaseSchema";
4
4
  import type * as Handler from "./Handler";
5
5
 
package/src/Scheduler.ts CHANGED
@@ -1,6 +1,10 @@
1
1
  import { Ref } from "@confect/core";
2
2
  import type { Scheduler as ConvexScheduler } from "convex/server";
3
- import { Context, DateTime, Duration, Effect, Layer } from "effect";
3
+ import * as Context from "effect/Context";
4
+ import * as DateTime from "effect/DateTime";
5
+ import * as Duration from "effect/Duration";
6
+ import * as Effect from "effect/Effect";
7
+ import * as Layer from "effect/Layer";
4
8
 
5
9
  const make = (scheduler: ConvexScheduler) => ({
6
10
  runAfter: <Ref_ extends Ref.AnyMutation | Ref.AnyAction>(