@confect/server 1.0.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/LICENSE +7 -0
  3. package/dist/ActionCtx.d.ts +12 -0
  4. package/dist/ActionCtx.d.ts.map +1 -0
  5. package/dist/ActionCtx.js +10 -0
  6. package/dist/ActionCtx.js.map +1 -0
  7. package/dist/ActionRunner.d.ts +15 -0
  8. package/dist/ActionRunner.d.ts.map +1 -0
  9. package/dist/ActionRunner.js +23 -0
  10. package/dist/ActionRunner.js.map +1 -0
  11. package/dist/Api.d.ts +27 -0
  12. package/dist/Api.d.ts.map +1 -0
  13. package/dist/Api.js +26 -0
  14. package/dist/Api.js.map +1 -0
  15. package/dist/Auth.d.ts +30 -0
  16. package/dist/Auth.d.ts.map +1 -0
  17. package/dist/Auth.js +24 -0
  18. package/dist/Auth.js.map +1 -0
  19. package/dist/DataModel.d.ts +33 -0
  20. package/dist/DataModel.d.ts.map +1 -0
  21. package/dist/DataModel.js +6 -0
  22. package/dist/DataModel.js.map +1 -0
  23. package/dist/DatabaseReader.d.ts +73 -0
  24. package/dist/DatabaseReader.d.ts.map +1 -0
  25. package/dist/DatabaseReader.js +32 -0
  26. package/dist/DatabaseReader.js.map +1 -0
  27. package/dist/DatabaseSchema.d.ts +139 -0
  28. package/dist/DatabaseSchema.d.ts.map +1 -0
  29. package/dist/DatabaseSchema.js +45 -0
  30. package/dist/DatabaseSchema.js.map +1 -0
  31. package/dist/DatabaseWriter.d.ts +39 -0
  32. package/dist/DatabaseWriter.d.ts.map +1 -0
  33. package/dist/DatabaseWriter.js +43 -0
  34. package/dist/DatabaseWriter.js.map +1 -0
  35. package/dist/Document.d.ts +47 -0
  36. package/dist/Document.d.ts.map +1 -0
  37. package/dist/Document.js +66 -0
  38. package/dist/Document.js.map +1 -0
  39. package/dist/FunctionImpl.d.ts +34 -0
  40. package/dist/FunctionImpl.d.ts.map +1 -0
  41. package/dist/FunctionImpl.js +35 -0
  42. package/dist/FunctionImpl.js.map +1 -0
  43. package/dist/GroupImpl.d.ts +24 -0
  44. package/dist/GroupImpl.d.ts.map +1 -0
  45. package/dist/GroupImpl.js +14 -0
  46. package/dist/GroupImpl.js.map +1 -0
  47. package/dist/Handler.d.ts +31 -0
  48. package/dist/Handler.d.ts.map +1 -0
  49. package/dist/Handler.js +6 -0
  50. package/dist/Handler.js.map +1 -0
  51. package/dist/HttpApi.d.ts +26 -0
  52. package/dist/HttpApi.d.ts.map +1 -0
  53. package/dist/HttpApi.js +74 -0
  54. package/dist/HttpApi.js.map +1 -0
  55. package/dist/Impl.d.ts +24 -0
  56. package/dist/Impl.d.ts.map +1 -0
  57. package/dist/Impl.js +28 -0
  58. package/dist/Impl.js.map +1 -0
  59. package/dist/MutationCtx.d.ts +12 -0
  60. package/dist/MutationCtx.d.ts.map +1 -0
  61. package/dist/MutationCtx.js +10 -0
  62. package/dist/MutationCtx.js.map +1 -0
  63. package/dist/MutationRunner.d.ts +24 -0
  64. package/dist/MutationRunner.d.ts.map +1 -0
  65. package/dist/MutationRunner.js +33 -0
  66. package/dist/MutationRunner.js.map +1 -0
  67. package/dist/OrderedQuery.d.ts +23 -0
  68. package/dist/OrderedQuery.d.ts.map +1 -0
  69. package/dist/OrderedQuery.js +34 -0
  70. package/dist/OrderedQuery.js.map +1 -0
  71. package/dist/QueryCtx.d.ts +12 -0
  72. package/dist/QueryCtx.d.ts.map +1 -0
  73. package/dist/QueryCtx.js +10 -0
  74. package/dist/QueryCtx.js.map +1 -0
  75. package/dist/QueryInitializer.d.ts +49 -0
  76. package/dist/QueryInitializer.d.ts.map +1 -0
  77. package/dist/QueryInitializer.js +83 -0
  78. package/dist/QueryInitializer.js.map +1 -0
  79. package/dist/QueryRunner.d.ts +14 -0
  80. package/dist/QueryRunner.d.ts.map +1 -0
  81. package/dist/QueryRunner.js +23 -0
  82. package/dist/QueryRunner.js.map +1 -0
  83. package/dist/RegisteredFunctions.d.ts +66 -0
  84. package/dist/RegisteredFunctions.d.ts.map +1 -0
  85. package/dist/RegisteredFunctions.js +71 -0
  86. package/dist/RegisteredFunctions.js.map +1 -0
  87. package/dist/Registry.d.ts +15 -0
  88. package/dist/Registry.d.ts.map +1 -0
  89. package/dist/Registry.js +10 -0
  90. package/dist/Registry.js.map +1 -0
  91. package/dist/RegistryItem.d.ts +31 -0
  92. package/dist/RegistryItem.d.ts.map +1 -0
  93. package/dist/RegistryItem.js +20 -0
  94. package/dist/RegistryItem.js.map +1 -0
  95. package/dist/Scheduler.d.ts +23 -0
  96. package/dist/Scheduler.d.ts.map +1 -0
  97. package/dist/Scheduler.js +24 -0
  98. package/dist/Scheduler.js.map +1 -0
  99. package/dist/SchemaToValidator.d.ts +88 -0
  100. package/dist/SchemaToValidator.d.ts.map +1 -0
  101. package/dist/SchemaToValidator.js +155 -0
  102. package/dist/SchemaToValidator.js.map +1 -0
  103. package/dist/Storage.d.ts +69 -0
  104. package/dist/Storage.d.ts.map +1 -0
  105. package/dist/Storage.js +46 -0
  106. package/dist/Storage.js.map +1 -0
  107. package/dist/Table.d.ts +247 -0
  108. package/dist/Table.d.ts.map +1 -0
  109. package/dist/Table.js +97 -0
  110. package/dist/Table.js.map +1 -0
  111. package/dist/TableInfo.d.ts +48 -0
  112. package/dist/TableInfo.d.ts.map +1 -0
  113. package/dist/TableInfo.js +6 -0
  114. package/dist/TableInfo.js.map +1 -0
  115. package/dist/VectorSearch.d.ts +42 -0
  116. package/dist/VectorSearch.d.ts.map +1 -0
  117. package/dist/VectorSearch.js +16 -0
  118. package/dist/VectorSearch.js.map +1 -0
  119. package/dist/_virtual/rolldown_runtime.js +13 -0
  120. package/dist/index.d.ts +30 -0
  121. package/dist/index.js +31 -0
  122. package/dist/internal/utils.d.ts +15 -0
  123. package/dist/internal/utils.d.ts.map +1 -0
  124. package/dist/internal/utils.js +49 -0
  125. package/dist/internal/utils.js.map +1 -0
  126. package/package.json +90 -0
  127. package/src/ActionCtx.ts +9 -0
  128. package/src/ActionRunner.ts +28 -0
  129. package/src/Api.ts +63 -0
  130. package/src/Auth.ts +31 -0
  131. package/src/DataModel.ts +69 -0
  132. package/src/DatabaseReader.ts +75 -0
  133. package/src/DatabaseSchema.ts +134 -0
  134. package/src/DatabaseWriter.ts +166 -0
  135. package/src/Document.ts +200 -0
  136. package/src/FunctionImpl.ts +112 -0
  137. package/src/GroupImpl.ts +60 -0
  138. package/src/Handler.ts +105 -0
  139. package/src/HttpApi.ts +232 -0
  140. package/src/Impl.ts +57 -0
  141. package/src/MutationCtx.ts +11 -0
  142. package/src/MutationRunner.ts +41 -0
  143. package/src/OrderedQuery.ts +109 -0
  144. package/src/QueryCtx.ts +9 -0
  145. package/src/QueryInitializer.ts +308 -0
  146. package/src/QueryRunner.ts +29 -0
  147. package/src/RegisteredFunctions.ts +381 -0
  148. package/src/Registry.ts +13 -0
  149. package/src/RegistryItem.ts +44 -0
  150. package/src/Scheduler.ts +39 -0
  151. package/src/SchemaToValidator.ts +619 -0
  152. package/src/Storage.ts +86 -0
  153. package/src/Table.ts +439 -0
  154. package/src/TableInfo.ts +91 -0
  155. package/src/VectorSearch.ts +46 -0
  156. package/src/index.ts +29 -0
  157. package/src/internal/utils.ts +87 -0
@@ -0,0 +1,381 @@
1
+ import type * as FunctionSpec from "@confect/core/FunctionSpec";
2
+ import type * as GroupSpec from "@confect/core/GroupSpec";
3
+ import type * as Spec from "@confect/core/Spec";
4
+ import {
5
+ actionGeneric,
6
+ type DefaultFunctionArgs,
7
+ type FunctionVisibility,
8
+ type GenericActionCtx,
9
+ type GenericMutationCtx,
10
+ type GenericQueryCtx,
11
+ internalActionGeneric,
12
+ internalMutationGeneric,
13
+ internalQueryGeneric,
14
+ mutationGeneric,
15
+ queryGeneric,
16
+ type RegisteredAction,
17
+ type RegisteredMutation,
18
+ type RegisteredQuery,
19
+ } from "convex/server";
20
+ import {
21
+ Effect,
22
+ Layer,
23
+ Match,
24
+ pipe,
25
+ Ref,
26
+ Schema,
27
+ type Types,
28
+ } from "effect";
29
+ import * as ActionCtx from "./ActionCtx";
30
+ import * as ActionRunner from "./ActionRunner";
31
+ import type * as Api from "./Api";
32
+ import * as Auth from "./Auth";
33
+ import * as DatabaseReader from "./DatabaseReader";
34
+ import type * as DatabaseSchema from "./DatabaseSchema";
35
+ import * as DatabaseWriter from "./DatabaseWriter";
36
+ import type * as DataModel from "./DataModel";
37
+ import * as Impl from "./Impl";
38
+ import { mapLeaves } from "./internal/utils";
39
+ import * as MutationCtx from "./MutationCtx";
40
+ import * as MutationRunner from "./MutationRunner";
41
+ import * as QueryCtx from "./QueryCtx";
42
+ import * as QueryRunner from "./QueryRunner";
43
+ import * as Registry from "./Registry";
44
+ import * as RegistryItem from "./RegistryItem";
45
+ import * as Scheduler from "./Scheduler";
46
+ import * as SchemaToValidator from "./SchemaToValidator";
47
+ import { StorageActionWriter, StorageReader, StorageWriter } from "./Storage";
48
+ import * as VectorSearch from "./VectorSearch";
49
+
50
+ export type RegisteredFunction =
51
+ | RegisteredQuery<FunctionVisibility, DefaultFunctionArgs, any>
52
+ | RegisteredMutation<FunctionVisibility, DefaultFunctionArgs, any>
53
+ | RegisteredAction<FunctionVisibility, DefaultFunctionArgs, any>;
54
+
55
+ export type RegisteredFunctions<Spec_ extends Spec.AnyWithProps> =
56
+ Types.Simplify<RegisteredFunctionsHelper<Spec.Groups<Spec_>>>;
57
+
58
+ type RegisteredFunctionsHelper<Groups extends GroupSpec.AnyWithProps> = {
59
+ [GroupName in GroupSpec.Name<Groups>]: GroupSpec.WithName<
60
+ Groups,
61
+ GroupName
62
+ > extends infer Group extends GroupSpec.AnyWithProps
63
+ ? GroupSpec.Groups<Group> extends infer SubGroups extends
64
+ GroupSpec.AnyWithProps
65
+ ? Types.Simplify<
66
+ RegisteredFunctionsHelper<SubGroups> & {
67
+ [FunctionName in FunctionSpec.Name<
68
+ GroupSpec.Functions<Group>
69
+ >]: FunctionSpec.WithName<
70
+ GroupSpec.Functions<Group>,
71
+ FunctionName
72
+ > extends infer Function extends FunctionSpec.AnyWithProps
73
+ ? FunctionSpec.RegisteredFunction<Function>
74
+ : never;
75
+ }
76
+ >
77
+ : {
78
+ [FunctionName in FunctionSpec.Name<
79
+ GroupSpec.Functions<Group>
80
+ >]: FunctionSpec.WithName<
81
+ GroupSpec.Functions<Group>,
82
+ FunctionName
83
+ > extends infer Function extends FunctionSpec.AnyWithProps
84
+ ? FunctionSpec.RegisteredFunction<Function>
85
+ : never;
86
+ }
87
+ : never;
88
+ };
89
+
90
+ export interface AnyWithProps {
91
+ readonly [key: string]: RegisteredFunction | AnyWithProps;
92
+ }
93
+
94
+ export const make = <Api_ extends Api.AnyWithProps>(
95
+ impl: Layer.Layer<Impl.Impl<Api_, "Finalized">>,
96
+ ) =>
97
+ Effect.gen(function* () {
98
+ const registry = yield* Registry.Registry;
99
+ const functionImplItems = yield* Ref.get(registry);
100
+ const { api, finalizationStatus } = yield* Impl.Impl<Api_, "Finalized">();
101
+
102
+ return yield* Match.value(
103
+ finalizationStatus as Impl.FinalizationStatus,
104
+ ).pipe(
105
+ Match.withReturnType<Effect.Effect<RegisteredFunctions<Api_["spec"]>>>(),
106
+ Match.when("Unfinalized", () =>
107
+ Effect.dieMessage("Impl is not finalized"),
108
+ ),
109
+ Match.when("Finalized", () =>
110
+ Effect.succeed(
111
+ mapLeaves<RegistryItem.AnyWithProps, RegisteredFunction>(
112
+ functionImplItems,
113
+ RegistryItem.isRegistryItem,
114
+ (registryItem) => makeRegisteredFunction(api, registryItem),
115
+ ) as RegisteredFunctions<Api_["spec"]>,
116
+ ),
117
+ ),
118
+ Match.exhaustive,
119
+ );
120
+ }).pipe(Effect.provide(impl), Effect.runSync);
121
+
122
+ const makeRegisteredFunction = <Api_ extends Api.AnyWithProps>(
123
+ api: Api_,
124
+ { function_, handler }: RegistryItem.AnyWithProps,
125
+ ): RegisteredFunction =>
126
+ Match.value(function_.functionType).pipe(
127
+ Match.when("query", () => {
128
+ const genericFunction = Match.value(function_.functionVisibility).pipe(
129
+ Match.when("public", () => queryGeneric),
130
+ Match.when("internal", () => internalQueryGeneric),
131
+ Match.exhaustive,
132
+ );
133
+
134
+ return genericFunction(
135
+ queryFunction(api.databaseSchema, {
136
+ args: function_.args,
137
+ returns: function_.returns,
138
+ handler,
139
+ }),
140
+ );
141
+ }),
142
+ Match.when("mutation", () => {
143
+ const genericFunction = Match.value(function_.functionVisibility).pipe(
144
+ Match.when("public", () => mutationGeneric),
145
+ Match.when("internal", () => internalMutationGeneric),
146
+ Match.exhaustive,
147
+ );
148
+
149
+ return genericFunction(
150
+ mutationFunction(api.databaseSchema, {
151
+ args: function_.args,
152
+ returns: function_.returns,
153
+ handler,
154
+ }),
155
+ );
156
+ }),
157
+ Match.when("action", () => {
158
+ const genericFunction = Match.value(function_.functionVisibility).pipe(
159
+ Match.when("public", () => actionGeneric),
160
+ Match.when("internal", () => internalActionGeneric),
161
+ Match.exhaustive,
162
+ );
163
+
164
+ return genericFunction(
165
+ actionFunction({
166
+ args: function_.args,
167
+ returns: function_.returns,
168
+ handler,
169
+ }),
170
+ );
171
+ }),
172
+ Match.exhaustive,
173
+ );
174
+
175
+ const queryFunction = <
176
+ Schema extends DatabaseSchema.AnyWithProps,
177
+ Args,
178
+ ConvexArgs extends DefaultFunctionArgs,
179
+ Returns,
180
+ ConvexReturns,
181
+ E,
182
+ >(
183
+ schema: Schema,
184
+ {
185
+ args,
186
+ returns,
187
+ handler,
188
+ }: {
189
+ args: Schema.Schema<Args, ConvexArgs>;
190
+ returns: Schema.Schema<Returns, ConvexReturns>;
191
+ handler: (
192
+ a: Args,
193
+ ) => Effect.Effect<
194
+ Returns,
195
+ E,
196
+ | DatabaseReader.DatabaseReader<Schema>
197
+ | Auth.Auth
198
+ | StorageReader
199
+ | QueryRunner.QueryRunner
200
+ | QueryCtx.QueryCtx<DataModel.ToConvex<DataModel.FromSchema<Schema>>>
201
+ >;
202
+ },
203
+ ) => ({
204
+ args: SchemaToValidator.compileArgsSchema(args),
205
+ returns: SchemaToValidator.compileReturnsSchema(returns),
206
+ handler: (
207
+ ctx: GenericQueryCtx<DataModel.ToConvex<DataModel.FromSchema<Schema>>>,
208
+ actualArgs: ConvexArgs,
209
+ ): Promise<ConvexReturns> =>
210
+ pipe(
211
+ actualArgs,
212
+ Schema.decode(args),
213
+ Effect.orDie,
214
+ Effect.andThen((decodedArgs) =>
215
+ pipe(
216
+ handler(decodedArgs),
217
+ Effect.provide(
218
+ Layer.mergeAll(
219
+ DatabaseReader.layer(schema, ctx.db),
220
+ Auth.layer(ctx.auth),
221
+ StorageReader.layer(ctx.storage),
222
+ QueryRunner.layer(ctx.runQuery),
223
+ Layer.succeed(
224
+ QueryCtx.QueryCtx<
225
+ DataModel.ToConvex<DataModel.FromSchema<Schema>>
226
+ >(),
227
+ ctx,
228
+ ),
229
+ ),
230
+ ),
231
+ ),
232
+ ),
233
+ Effect.andThen((convexReturns) =>
234
+ Schema.encodeUnknown(returns)(convexReturns),
235
+ ),
236
+ Effect.runPromise,
237
+ ),
238
+ });
239
+
240
+ export const mutationLayer = <Schema extends DatabaseSchema.AnyWithProps>(
241
+ schema: Schema,
242
+ ctx: GenericMutationCtx<DataModel.ToConvex<DataModel.FromSchema<Schema>>>,
243
+ ) =>
244
+ Layer.mergeAll(
245
+ DatabaseReader.layer(schema, ctx.db),
246
+ DatabaseWriter.layer(schema, ctx.db),
247
+ Auth.layer(ctx.auth),
248
+ Scheduler.layer(ctx.scheduler),
249
+ StorageReader.layer(ctx.storage),
250
+ StorageWriter.layer(ctx.storage),
251
+ QueryRunner.layer(ctx.runQuery),
252
+ MutationRunner.layer(ctx.runMutation),
253
+ Layer.succeed(
254
+ MutationCtx.MutationCtx<
255
+ DataModel.ToConvex<DataModel.FromSchema<Schema>>
256
+ >(),
257
+ ctx,
258
+ ),
259
+ );
260
+
261
+ export type MutationServices<Schema extends DatabaseSchema.AnyWithProps> =
262
+ | DatabaseReader.DatabaseReader<Schema>
263
+ | DatabaseWriter.DatabaseWriter<Schema>
264
+ | Auth.Auth
265
+ | Scheduler.Scheduler
266
+ | StorageReader
267
+ | StorageWriter
268
+ | QueryRunner.QueryRunner
269
+ | MutationRunner.MutationRunner
270
+ | MutationCtx.MutationCtx<DataModel.ToConvex<DataModel.FromSchema<Schema>>>;
271
+
272
+ const mutationFunction = <
273
+ Schema extends DatabaseSchema.AnyWithProps,
274
+ Args,
275
+ ConvexArgs extends DefaultFunctionArgs,
276
+ Returns,
277
+ ConvexReturns,
278
+ E,
279
+ >(
280
+ schema: Schema,
281
+ {
282
+ args,
283
+ returns,
284
+ handler,
285
+ }: {
286
+ args: Schema.Schema<Args, ConvexArgs>;
287
+ returns: Schema.Schema<Returns, ConvexReturns>;
288
+ handler: (a: Args) => Effect.Effect<Returns, E, MutationServices<Schema>>;
289
+ },
290
+ ) => ({
291
+ args: SchemaToValidator.compileArgsSchema(args),
292
+ returns: SchemaToValidator.compileReturnsSchema(returns),
293
+ handler: (
294
+ ctx: GenericMutationCtx<DataModel.ToConvex<DataModel.FromSchema<Schema>>>,
295
+ actualArgs: ConvexArgs,
296
+ ): Promise<ConvexReturns> =>
297
+ pipe(
298
+ actualArgs,
299
+ Schema.decode(args),
300
+ Effect.orDie,
301
+ Effect.andThen((decodedArgs) =>
302
+ handler(decodedArgs).pipe(Effect.provide(mutationLayer(schema, ctx))),
303
+ ),
304
+ Effect.andThen((convexReturns) =>
305
+ Schema.encodeUnknown(returns)(convexReturns),
306
+ ),
307
+ Effect.runPromise,
308
+ ),
309
+ });
310
+
311
+ const actionFunction = <
312
+ Schema extends DatabaseSchema.AnyWithProps,
313
+ Args,
314
+ ConvexArgs extends DefaultFunctionArgs,
315
+ Returns,
316
+ ConvexReturns,
317
+ E,
318
+ >({
319
+ args,
320
+ returns,
321
+ handler,
322
+ }: {
323
+ args: Schema.Schema<Args, ConvexArgs>;
324
+ returns: Schema.Schema<Returns, ConvexReturns>;
325
+ handler: (
326
+ a: Args,
327
+ ) => Effect.Effect<
328
+ Returns,
329
+ E,
330
+ | Scheduler.Scheduler
331
+ | Auth.Auth
332
+ | StorageReader
333
+ | StorageWriter
334
+ | StorageActionWriter
335
+ | QueryRunner.QueryRunner
336
+ | MutationRunner.MutationRunner
337
+ | ActionRunner.ActionRunner
338
+ | VectorSearch.VectorSearch<DataModel.FromSchema<Schema>>
339
+ | ActionCtx.ActionCtx<DataModel.ToConvex<DataModel.FromSchema<Schema>>>
340
+ >;
341
+ }) => ({
342
+ args: SchemaToValidator.compileArgsSchema(args),
343
+ returns: SchemaToValidator.compileReturnsSchema(returns),
344
+ handler: (
345
+ ctx: GenericActionCtx<DataModel.ToConvex<DataModel.FromSchema<Schema>>>,
346
+ actualArgs: ConvexArgs,
347
+ ): Promise<ConvexReturns> =>
348
+ pipe(
349
+ actualArgs,
350
+ Schema.decode(args),
351
+ Effect.orDie,
352
+ Effect.andThen((decodedArgs) =>
353
+ pipe(
354
+ handler(decodedArgs),
355
+ Effect.provide(
356
+ Layer.mergeAll(
357
+ Scheduler.layer(ctx.scheduler),
358
+ Auth.layer(ctx.auth),
359
+ StorageReader.layer(ctx.storage),
360
+ StorageWriter.layer(ctx.storage),
361
+ StorageActionWriter.layer(ctx.storage),
362
+ QueryRunner.layer(ctx.runQuery),
363
+ MutationRunner.layer(ctx.runMutation),
364
+ ActionRunner.layer(ctx.runAction),
365
+ VectorSearch.layer(ctx.vectorSearch),
366
+ Layer.succeed(
367
+ ActionCtx.ActionCtx<
368
+ DataModel.ToConvex<DataModel.FromSchema<Schema>>
369
+ >(),
370
+ ctx,
371
+ ),
372
+ ),
373
+ ),
374
+ ),
375
+ ),
376
+ Effect.andThen((convexReturns) =>
377
+ Schema.encodeUnknown(returns)(convexReturns),
378
+ ),
379
+ Effect.runPromise,
380
+ ),
381
+ });
@@ -0,0 +1,13 @@
1
+ import { Context, Ref } from "effect";
2
+ import type * as RegistryItem from "./RegistryItem";
3
+
4
+ export interface RegistryItems {
5
+ readonly [key: string]: RegistryItem.AnyWithProps | RegistryItems;
6
+ }
7
+
8
+ export class Registry extends Context.Reference<Registry>()(
9
+ "@confect/server/Registry",
10
+ {
11
+ defaultValue: () => Ref.unsafeMake<RegistryItems>({}),
12
+ },
13
+ ) {}
@@ -0,0 +1,44 @@
1
+ import type * as FunctionSpec from "@confect/core/FunctionSpec";
2
+ import { Predicate } from "effect";
3
+ import type * as DatabaseSchema from "./DatabaseSchema";
4
+ import type * as Handler from "./Handler";
5
+
6
+ export const TypeId = "@confect/server/RegistryItem";
7
+ export type TypeId = typeof TypeId;
8
+
9
+ export const isRegistryItem = (value: unknown): value is AnyWithProps =>
10
+ Predicate.hasProperty(value, TypeId);
11
+
12
+ const RegistryItemProto = {
13
+ [TypeId]: TypeId,
14
+ };
15
+
16
+ export interface RegistryItem<
17
+ DatabaseSchema_ extends DatabaseSchema.AnyWithProps,
18
+ FunctionSpec_ extends FunctionSpec.AnyWithProps,
19
+ > {
20
+ readonly [TypeId]: TypeId;
21
+ readonly function_: FunctionSpec_;
22
+ readonly handler: Handler.Handler<DatabaseSchema_, FunctionSpec_>;
23
+ }
24
+
25
+ export interface AnyWithProps {
26
+ readonly [TypeId]: TypeId;
27
+ readonly function_: FunctionSpec.AnyWithProps;
28
+ readonly handler: Handler.AnyWithProps;
29
+ }
30
+
31
+ export const make = <
32
+ DatabaseSchema_ extends DatabaseSchema.AnyWithProps,
33
+ FunctionSpec_ extends FunctionSpec.AnyWithProps,
34
+ >({
35
+ function_,
36
+ handler,
37
+ }: {
38
+ function_: FunctionSpec_;
39
+ handler: Handler.Handler<DatabaseSchema_, FunctionSpec_>;
40
+ }): RegistryItem<DatabaseSchema_, FunctionSpec_> =>
41
+ Object.assign(Object.create(RegistryItemProto), {
42
+ function_,
43
+ handler,
44
+ });
@@ -0,0 +1,39 @@
1
+ import type {
2
+ OptionalRestArgs,
3
+ SchedulableFunctionReference,
4
+ Scheduler as ConvexScheduler,
5
+ } from "convex/server";
6
+ import { Context, DateTime, Duration, Effect, Layer } from "effect";
7
+
8
+ const make = (scheduler: ConvexScheduler) => ({
9
+ runAfter: <FuncRef extends SchedulableFunctionReference>(
10
+ delay: Duration.Duration,
11
+ functionReference: FuncRef,
12
+ ...args: OptionalRestArgs<FuncRef>
13
+ ) => {
14
+ const delayMs = Duration.toMillis(delay);
15
+
16
+ return Effect.promise(() =>
17
+ scheduler.runAfter(delayMs, functionReference, ...args),
18
+ );
19
+ },
20
+ runAt: <FuncRef extends SchedulableFunctionReference>(
21
+ dateTime: DateTime.DateTime,
22
+ functionReference: FuncRef,
23
+ ...args: OptionalRestArgs<FuncRef>
24
+ ) => {
25
+ const timestamp = DateTime.toEpochMillis(dateTime);
26
+
27
+ return Effect.promise(() =>
28
+ scheduler.runAt(timestamp, functionReference, ...args),
29
+ );
30
+ },
31
+ });
32
+
33
+ export const Scheduler = Context.GenericTag<ReturnType<typeof make>>(
34
+ "@confect/server/Scheduler",
35
+ );
36
+ export type Scheduler = typeof Scheduler.Identifier;
37
+
38
+ export const layer = (scheduler: ConvexScheduler) =>
39
+ Layer.succeed(Scheduler, make(scheduler));