@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
package/src/Table.ts ADDED
@@ -0,0 +1,439 @@
1
+ import * as SystemFields from "@confect/core/SystemFields";
2
+ import {
3
+ defineTable,
4
+ type SystemFields as ConvexSystemFields,
5
+ type Expand,
6
+ type GenericTableIndexes,
7
+ type GenericTableSearchIndexes,
8
+ type GenericTableVectorIndexes,
9
+ type IndexTiebreakerField,
10
+ type SearchIndexConfig,
11
+ type TableDefinition,
12
+ type VectorIndexConfig,
13
+ } from "convex/server";
14
+ import type { GenericValidator, Validator } from "convex/values";
15
+ import { Predicate, Schema } from "effect";
16
+ import {
17
+ compileTableSchema,
18
+ type TableSchemaToTableValidator,
19
+ } from "./SchemaToValidator";
20
+
21
+ export const TypeId = "@confect/server/Table";
22
+ export type TypeId = typeof TypeId;
23
+
24
+ export const isTable = (u: unknown): u is Any =>
25
+ Predicate.hasProperty(u, TypeId);
26
+
27
+ export interface Table<
28
+ Name_ extends string,
29
+ TableSchema_ extends Schema.Schema.AnyNoContext,
30
+ TableValidator_ extends
31
+ GenericValidator = TableSchemaToTableValidator<TableSchema_>,
32
+ Indexes_ extends GenericTableIndexes = {},
33
+ SearchIndexes_ extends GenericTableSearchIndexes = {},
34
+ VectorIndexes_ extends GenericTableVectorIndexes = {},
35
+ > {
36
+ readonly [TypeId]: TypeId;
37
+ readonly tableDefinition: TableDefinition<
38
+ TableValidator_,
39
+ Indexes_,
40
+ SearchIndexes_,
41
+ VectorIndexes_
42
+ >;
43
+
44
+ readonly name: Name_;
45
+
46
+ readonly Fields: TableSchema_;
47
+ readonly Doc: SystemFields.ExtendWithSystemFields<Name_, TableSchema_>;
48
+
49
+ readonly indexes: Indexes_;
50
+
51
+ index<
52
+ IndexName extends string,
53
+ FirstFieldPath extends ExtractFieldPaths<TableValidator_>,
54
+ RestFieldPaths extends ExtractFieldPaths<TableValidator_>[],
55
+ >(
56
+ name: IndexName,
57
+ fields: [FirstFieldPath, ...RestFieldPaths],
58
+ ): Table<
59
+ Name_,
60
+ TableSchema_,
61
+ TableValidator_,
62
+ Expand<
63
+ Indexes_ &
64
+ Record<
65
+ IndexName,
66
+ [FirstFieldPath, ...RestFieldPaths, IndexTiebreakerField]
67
+ >
68
+ >,
69
+ SearchIndexes_,
70
+ VectorIndexes_
71
+ >;
72
+
73
+ searchIndex<
74
+ IndexName extends string,
75
+ SearchField extends ExtractFieldPaths<TableValidator_>,
76
+ FilterFields extends ExtractFieldPaths<TableValidator_> = never,
77
+ >(
78
+ name: IndexName,
79
+ indexConfig: Expand<SearchIndexConfig<SearchField, FilterFields>>,
80
+ ): Table<
81
+ Name_,
82
+ TableSchema_,
83
+ TableValidator_,
84
+ Indexes_,
85
+ Expand<
86
+ SearchIndexes_ &
87
+ Record<
88
+ IndexName,
89
+ {
90
+ searchField: SearchField;
91
+ filterFields: FilterFields;
92
+ }
93
+ >
94
+ >,
95
+ VectorIndexes_
96
+ >;
97
+
98
+ vectorIndex<
99
+ IndexName extends string,
100
+ VectorField extends ExtractFieldPaths<TableValidator_>,
101
+ FilterFields extends ExtractFieldPaths<TableValidator_> = never,
102
+ >(
103
+ name: IndexName,
104
+ indexConfig: Expand<VectorIndexConfig<VectorField, FilterFields>>,
105
+ ): Table<
106
+ Name_,
107
+ TableSchema_,
108
+ TableValidator_,
109
+ Indexes_,
110
+ SearchIndexes_,
111
+ Expand<
112
+ VectorIndexes_ &
113
+ Record<
114
+ IndexName,
115
+ {
116
+ vectorField: VectorField;
117
+ dimensions: number;
118
+ filterFields: FilterFields;
119
+ }
120
+ >
121
+ >
122
+ >;
123
+ }
124
+
125
+ export interface Any {
126
+ readonly [TypeId]: TypeId;
127
+ }
128
+
129
+ export type AnyWithProps = Table<
130
+ any,
131
+ Schema.Schema.AnyNoContext,
132
+ GenericValidator,
133
+ GenericTableIndexes,
134
+ GenericTableSearchIndexes,
135
+ GenericTableVectorIndexes
136
+ >;
137
+
138
+ export type Name<TableDef extends AnyWithProps> =
139
+ TableDef extends Table<
140
+ infer TableName,
141
+ infer _TableSchema,
142
+ infer _TableValidator,
143
+ infer _Indexes,
144
+ infer _SearchIndexes,
145
+ infer _VectorIndexes
146
+ >
147
+ ? TableName & string
148
+ : never;
149
+
150
+ export type TableSchema<TableDef extends AnyWithProps> =
151
+ TableDef extends Table<
152
+ infer _TableName,
153
+ infer TableSchema_,
154
+ infer _TableValidator,
155
+ infer _Indexes,
156
+ infer _SearchIndexes,
157
+ infer _VectorIndexes
158
+ >
159
+ ? TableSchema_
160
+ : never;
161
+
162
+ export type TableValidator<TableDef extends AnyWithProps> =
163
+ TableDef extends Table<
164
+ infer _TableName,
165
+ infer _TableSchema,
166
+ infer TableValidator_,
167
+ infer _Indexes,
168
+ infer _SearchIndexes,
169
+ infer _VectorIndexes
170
+ >
171
+ ? TableValidator_
172
+ : never;
173
+
174
+ export type Indexes<TableDef extends AnyWithProps> =
175
+ TableDef extends Table<
176
+ infer _TableName,
177
+ infer _TableSchema,
178
+ infer _TableValidator,
179
+ infer Indexes_,
180
+ infer _SearchIndexes,
181
+ infer _VectorIndexes
182
+ >
183
+ ? Indexes_
184
+ : never;
185
+
186
+ export type SearchIndexes<TableDef extends AnyWithProps> =
187
+ TableDef extends Table<
188
+ infer _TableName,
189
+ infer _TableSchema,
190
+ infer _TableValidator,
191
+ infer _Indexes,
192
+ infer SearchIndexes_,
193
+ infer _VectorIndexes
194
+ >
195
+ ? SearchIndexes_
196
+ : never;
197
+
198
+ export type VectorIndexes<TableDef extends AnyWithProps> =
199
+ TableDef extends Table<
200
+ infer _TableName,
201
+ infer _TableSchema,
202
+ infer _TableValidator,
203
+ infer _Indexes,
204
+ infer _SearchIndexes,
205
+ infer VectorIndexes_
206
+ >
207
+ ? VectorIndexes_
208
+ : never;
209
+
210
+ export type Doc<TableDef extends AnyWithProps> =
211
+ TableDef extends Table<
212
+ infer TableName,
213
+ infer TableSchema_,
214
+ infer _TableValidator,
215
+ infer _Indexes,
216
+ infer _SearchIndexes,
217
+ infer _VectorIndexes
218
+ >
219
+ ? SystemFields.ExtendWithSystemFields<TableName, TableSchema_>
220
+ : never;
221
+
222
+ export type Fields<TableDef extends AnyWithProps> =
223
+ TableDef extends Table<
224
+ infer _TableName,
225
+ infer TableSchema_,
226
+ infer _TableValidator,
227
+ infer _Indexes,
228
+ infer _SearchIndexes,
229
+ infer _VectorIndexes
230
+ >
231
+ ? TableSchema_
232
+ : never;
233
+
234
+ export type WithName<
235
+ TableDef extends AnyWithProps,
236
+ Name_ extends string,
237
+ > = TableDef extends { readonly name: Name_ } ? TableDef : never;
238
+
239
+ export type TablesRecord<Tables extends AnyWithProps> = {
240
+ readonly [TableName_ in Name<Tables>]: WithName<Tables, TableName_>;
241
+ };
242
+
243
+ const Proto = {
244
+ [TypeId]: TypeId,
245
+
246
+ index<
247
+ IndexName extends string,
248
+ FirstFieldPath extends string,
249
+ RestFieldPaths extends string[],
250
+ >(
251
+ this: AnyWithProps,
252
+ name: IndexName,
253
+ fields: [FirstFieldPath, ...RestFieldPaths],
254
+ ) {
255
+ return makeProto({
256
+ name: this.name,
257
+ Fields: this.Fields,
258
+ Doc: this.Doc,
259
+ tableDefinition: this.tableDefinition.index(name, fields as any),
260
+ indexes: {
261
+ ...this.indexes,
262
+ [name]: fields,
263
+ },
264
+ });
265
+ },
266
+
267
+ searchIndex<IndexName extends string, SearchField extends string>(
268
+ this: AnyWithProps,
269
+ name: IndexName,
270
+ indexConfig: SearchIndexConfig<SearchField, any>,
271
+ ) {
272
+ return makeProto({
273
+ name: this.name,
274
+ Fields: this.Fields,
275
+ Doc: this.Doc,
276
+ tableDefinition: this.tableDefinition.searchIndex(name, indexConfig),
277
+ indexes: this.indexes,
278
+ });
279
+ },
280
+
281
+ vectorIndex<IndexName extends string, VectorField extends string>(
282
+ this: AnyWithProps,
283
+ name: IndexName,
284
+ indexConfig: {
285
+ vectorField: VectorField;
286
+ dimensions: number;
287
+ filterFields?: string[] | undefined;
288
+ },
289
+ ) {
290
+ return makeProto({
291
+ name: this.name,
292
+ Fields: this.Fields,
293
+ Doc: this.Doc,
294
+ tableDefinition: this.tableDefinition.vectorIndex(name, {
295
+ vectorField: indexConfig.vectorField,
296
+ dimensions: indexConfig.dimensions,
297
+ ...(indexConfig.filterFields
298
+ ? { filterFields: indexConfig.filterFields }
299
+ : {}),
300
+ }),
301
+ indexes: this.indexes,
302
+ });
303
+ },
304
+ };
305
+
306
+ const makeProto = <
307
+ Name_ extends string,
308
+ TableSchema_ extends Schema.Schema.AnyNoContext,
309
+ TableValidator_ extends Validator<any, any, any>,
310
+ Indexes_ extends GenericTableIndexes,
311
+ SearchIndexes_ extends GenericTableSearchIndexes,
312
+ VectorIndexes_ extends GenericTableVectorIndexes,
313
+ >({
314
+ name,
315
+ Fields,
316
+ Doc,
317
+ tableDefinition,
318
+ indexes,
319
+ }: {
320
+ name: Name_;
321
+ Fields: TableSchema_;
322
+ Doc: SystemFields.ExtendWithSystemFields<Name_, TableSchema_>;
323
+ tableDefinition: TableDefinition<
324
+ TableValidator_,
325
+ Indexes_,
326
+ SearchIndexes_,
327
+ VectorIndexes_
328
+ >;
329
+ indexes: Indexes_;
330
+ }): Table<
331
+ Name_,
332
+ TableSchema_,
333
+ TableValidator_,
334
+ Indexes_,
335
+ SearchIndexes_,
336
+ VectorIndexes_
337
+ > =>
338
+ Object.assign(Object.create(Proto), {
339
+ name,
340
+ Fields,
341
+ Doc,
342
+ tableDefinition,
343
+ indexes,
344
+ });
345
+
346
+ /**
347
+ * Create a table.
348
+ */
349
+ export const make = <
350
+ const Name_ extends string,
351
+ TableSchema_ extends Schema.Schema.AnyNoContext,
352
+ TableValidator_ extends
353
+ GenericValidator = TableSchemaToTableValidator<TableSchema_>,
354
+ Indexes_ extends GenericTableIndexes = {},
355
+ SearchIndexes_ extends GenericTableSearchIndexes = {},
356
+ VectorIndexes_ extends GenericTableVectorIndexes = {},
357
+ >(
358
+ name: Name_,
359
+ fields: TableSchema_,
360
+ ): Table<
361
+ Name_,
362
+ TableSchema_,
363
+ TableValidator_,
364
+ Indexes_,
365
+ SearchIndexes_,
366
+ VectorIndexes_
367
+ > => {
368
+ const tableValidator = compileTableSchema(fields) as any;
369
+ const tableDefinition = defineTable(tableValidator) as any;
370
+
371
+ return makeProto<
372
+ Name_,
373
+ TableSchema_,
374
+ TableValidator_,
375
+ Indexes_,
376
+ SearchIndexes_,
377
+ VectorIndexes_
378
+ >({
379
+ name,
380
+ Fields: fields,
381
+ Doc: SystemFields.extendWithSystemFields(name, fields),
382
+ tableDefinition,
383
+ indexes: {} as Indexes_,
384
+ });
385
+ };
386
+
387
+ // -----------------------------------------------------------------------------
388
+ // System tables
389
+ // -----------------------------------------------------------------------------
390
+
391
+ export const scheduledFunctionsTable = make(
392
+ "_scheduled_functions",
393
+ Schema.Struct({
394
+ name: Schema.String,
395
+ args: Schema.Array(Schema.Any),
396
+ scheduledTime: Schema.Number,
397
+ completedTime: Schema.optionalWith(Schema.Number, { exact: true }),
398
+ state: Schema.Union(
399
+ Schema.Struct({ kind: Schema.Literal("pending") }),
400
+ Schema.Struct({ kind: Schema.Literal("inProgress") }),
401
+ Schema.Struct({ kind: Schema.Literal("success") }),
402
+ Schema.Struct({
403
+ kind: Schema.Literal("failed"),
404
+ error: Schema.String,
405
+ }),
406
+ Schema.Struct({ kind: Schema.Literal("canceled") }),
407
+ ),
408
+ }),
409
+ );
410
+
411
+ export const storageTable = make(
412
+ "_storage",
413
+ Schema.Struct({
414
+ sha256: Schema.String,
415
+ size: Schema.Number,
416
+ contentType: Schema.optionalWith(Schema.String, { exact: true }),
417
+ }),
418
+ );
419
+
420
+ export const systemTables = {
421
+ _scheduled_functions: scheduledFunctionsTable,
422
+ _storage: storageTable,
423
+ } as const;
424
+
425
+ export type SystemTables = typeof scheduledFunctionsTable | typeof storageTable;
426
+
427
+ // Vendored types from convex-js, partially modified. Ideally we could use these directly. See https://github.com/get-convex/convex-js/pull/14
428
+
429
+ /**
430
+ * Extract all of the index field paths within a {@link Validator}.
431
+ *
432
+ * This is used within {@link defineTable}.
433
+ * @public
434
+ */
435
+ type ExtractFieldPaths<T extends Validator<any, any, any>> =
436
+ // Add in the system fields available in index definitions.
437
+ // This should be everything except for `_id` because thats added to indexes
438
+ // automatically.
439
+ T["fieldPaths"] | keyof ConvexSystemFields;
@@ -0,0 +1,91 @@
1
+ import type {
2
+ Expand,
3
+ GenericDocument,
4
+ GenericFieldPaths,
5
+ GenericTableIndexes,
6
+ GenericTableSearchIndexes,
7
+ GenericTableVectorIndexes,
8
+ IdField,
9
+ SystemFields,
10
+ SystemIndexes,
11
+ } from "convex/server";
12
+ import type { GenericValidator } from "convex/values";
13
+ import type { Schema, Types } from "effect";
14
+ import type * as Document_ from "./Document";
15
+ import type * as Table from "./Table";
16
+
17
+ export declare const TypeId: "@confect/server/TableInfo";
18
+ export type TypeId = typeof TypeId;
19
+
20
+ export type TableInfo<Table_ extends Table.AnyWithProps> =
21
+ Table_ extends Table.Table<
22
+ infer TableName,
23
+ infer _TableSchema,
24
+ infer TableValidator,
25
+ infer Indexes,
26
+ infer SearchIndexes,
27
+ infer VectorIndexes
28
+ >
29
+ ? {
30
+ readonly [TypeId]: TypeId;
31
+ readonly document: Table_["Doc"]["Type"];
32
+ readonly encodedDocument: Table_["Doc"]["Encoded"];
33
+ // TODO: Can we exclude this and derive the convex document type from the encoded document?
34
+ readonly convexDocument: ExtractConvexDocument<
35
+ TableName,
36
+ TableValidator
37
+ >;
38
+ readonly fieldPaths:
39
+ | keyof IdField<TableName>
40
+ | ExtractFieldPaths<TableValidator>;
41
+ readonly indexes: Types.Simplify<Indexes & SystemIndexes>;
42
+ readonly searchIndexes: SearchIndexes;
43
+ readonly vectorIndexes: VectorIndexes;
44
+ }
45
+ : never;
46
+
47
+ export interface Any {
48
+ readonly [TypeId]: TypeId;
49
+ }
50
+
51
+ export interface AnyWithProps extends Any {
52
+ readonly document: Document_.Any;
53
+ readonly encodedDocument: Document_.AnyEncoded;
54
+ readonly convexDocument: GenericDocument;
55
+ readonly fieldPaths: GenericFieldPaths;
56
+ readonly indexes: GenericTableIndexes;
57
+ readonly searchIndexes: GenericTableSearchIndexes;
58
+ readonly vectorIndexes: GenericTableVectorIndexes;
59
+ }
60
+
61
+ export type ConvexTableInfo<TableInfo_ extends AnyWithProps> = {
62
+ document: TableInfo_["convexDocument"];
63
+ fieldPaths: TableInfo_["fieldPaths"];
64
+ indexes: TableInfo_["indexes"];
65
+ searchIndexes: TableInfo_["searchIndexes"];
66
+ vectorIndexes: TableInfo_["vectorIndexes"];
67
+ };
68
+
69
+ export type TableSchema<TableInfo_ extends AnyWithProps> = Schema.Schema<
70
+ TableInfo_["document"],
71
+ TableInfo_["encodedDocument"]
72
+ >;
73
+
74
+ export type Document<TableInfo_ extends AnyWithProps> = TableInfo_["document"];
75
+
76
+ // Vendored types from convex-js, partially modified.
77
+ // See https://github.com/get-convex/convex-js/pull/14
78
+
79
+ type ExtractFieldPaths<T extends GenericValidator> =
80
+ | T["fieldPaths"]
81
+ | keyof SystemFields;
82
+
83
+ type ExtractConvexDocument<
84
+ TableName extends string,
85
+ T extends GenericValidator,
86
+ > =
87
+ Expand<IdField<TableName> & SystemFields & T["type"]> extends GenericDocument
88
+ ? Expand<IdField<TableName> & SystemFields & T["type"]>
89
+ : never;
90
+
91
+ // End of vendored types from convex-js, partially modified.
@@ -0,0 +1,46 @@
1
+ import type {
2
+ Expand,
3
+ GenericActionCtx,
4
+ NamedTableInfo,
5
+ VectorIndexNames,
6
+ VectorSearchQuery,
7
+ } from "convex/server";
8
+ import type { GenericId } from "convex/values";
9
+ import { Context, Effect, Layer } from "effect";
10
+ import type * as DataModel from "./DataModel";
11
+
12
+ type ConvexVectorSearch<DataModel_ extends DataModel.AnyWithProps> =
13
+ GenericActionCtx<DataModel.ToConvex<DataModel_>>["vectorSearch"];
14
+
15
+ export const make =
16
+ <DataModel_ extends DataModel.AnyWithProps>(
17
+ vectorSearch: ConvexVectorSearch<DataModel_>,
18
+ ) =>
19
+ <
20
+ TableName extends DataModel.TableNames<DataModel_>,
21
+ IndexName extends VectorIndexNames<
22
+ NamedTableInfo<DataModel.ToConvex<DataModel_>, TableName>
23
+ >,
24
+ >(
25
+ tableName: TableName,
26
+ indexName: IndexName,
27
+ query: Expand<
28
+ VectorSearchQuery<
29
+ NamedTableInfo<DataModel.ToConvex<DataModel_>, TableName>,
30
+ IndexName
31
+ >
32
+ >,
33
+ ): Effect.Effect<Array<{ _id: GenericId<TableName>; _score: number }>> =>
34
+ Effect.promise(() => vectorSearch(tableName, indexName, query));
35
+
36
+ export const VectorSearch = <DataModel_ extends DataModel.AnyWithProps>() =>
37
+ Context.GenericTag<ReturnType<typeof make<DataModel_>>>(
38
+ "@confect/server/VectorSearch",
39
+ );
40
+
41
+ export type VectorSearch<DataModel_ extends DataModel.AnyWithProps> =
42
+ ReturnType<typeof VectorSearch<DataModel_>>["Identifier"];
43
+
44
+ export const layer = <DataModel_ extends DataModel.AnyWithProps>(
45
+ vectorSearch: ConvexVectorSearch<DataModel_>,
46
+ ) => Layer.succeed(VectorSearch<DataModel_>(), make(vectorSearch));
package/src/index.ts ADDED
@@ -0,0 +1,29 @@
1
+ export * as ActionCtx from "./ActionCtx";
2
+ export * as ActionRunner from "./ActionRunner";
3
+ export * as Api from "./Api";
4
+ export * as Auth from "./Auth";
5
+ export * as DatabaseReader from "./DatabaseReader";
6
+ export * as DatabaseSchema from "./DatabaseSchema";
7
+ export * as DatabaseWriter from "./DatabaseWriter";
8
+ export * as DataModel from "./DataModel";
9
+ export * as Document from "./Document";
10
+ export * as FunctionImpl from "./FunctionImpl";
11
+ export * as GroupImpl from "./GroupImpl";
12
+ export * as Handler from "./Handler";
13
+ export * as HttpApi from "./HttpApi";
14
+ export * as Impl from "./Impl";
15
+ export * as MutationCtx from "./MutationCtx";
16
+ export * as MutationRunner from "./MutationRunner";
17
+ export * as OrderedQuery from "./OrderedQuery";
18
+ export * as QueryCtx from "./QueryCtx";
19
+ export * as QueryInitializer from "./QueryInitializer";
20
+ export * as QueryRunner from "./QueryRunner";
21
+ export * as RegisteredFunctions from "./RegisteredFunctions";
22
+ export * as Registry from "./Registry";
23
+ export * as RegistryItem from "./RegistryItem";
24
+ export * as Scheduler from "./Scheduler";
25
+ export * as SchemaToValidator from "./SchemaToValidator";
26
+ export * as Storage from "./Storage";
27
+ export * as Table from "./Table";
28
+ export * as TableInfo from "./TableInfo";
29
+ export * as VectorSearch from "./VectorSearch";
@@ -0,0 +1,87 @@
1
+ import type { Predicate } from "effect";
2
+ import { Array, Effect, Record } from "effect";
3
+
4
+ type NestedObject<T> = {
5
+ [key: string]: T | NestedObject<T>;
6
+ };
7
+
8
+ export const mapLeaves = <T, U>(
9
+ obj: NestedObject<T>,
10
+ leafRefinement: Predicate.Refinement<unknown, T>,
11
+ f: (value: T) => U,
12
+ ): NestedObject<U> => {
13
+ const result: any = {};
14
+
15
+ for (const key in obj) {
16
+ const value = obj[key];
17
+
18
+ if (leafRefinement(value)) {
19
+ result[key] = f(value as T);
20
+ } else {
21
+ result[key] = mapLeaves(value as NestedObject<T>, leafRefinement, f);
22
+ }
23
+ }
24
+
25
+ return result;
26
+ };
27
+
28
+ const collectBranchLeaves = <T>(
29
+ obj: NestedObject<T>,
30
+ leafRefinement: Predicate.Refinement<unknown, T>,
31
+ path: string[] = [],
32
+ ): { path: string[]; values: Record<string, T> }[] => {
33
+ const leaves = Record.filter(obj, leafRefinement) as Record<string, T>;
34
+ const hasLeaves = Record.keys(leaves).length > 0;
35
+
36
+ const currentBranch = hasLeaves ? [{ path, values: leaves }] : [];
37
+
38
+ const nestedBranches = Array.flatMap(Record.keys(obj), (key) => {
39
+ const value = obj[key];
40
+
41
+ if (!leafRefinement(value) && typeof value === "object") {
42
+ return collectBranchLeaves(value as NestedObject<T>, leafRefinement, [
43
+ ...path,
44
+ key,
45
+ ]);
46
+ }
47
+ return [];
48
+ });
49
+
50
+ return [...currentBranch, ...nestedBranches];
51
+ };
52
+
53
+ export const forEachBranchLeaves = <T, A, E, R>(
54
+ obj: NestedObject<T>,
55
+ leafRefinement: Predicate.Refinement<unknown, T>,
56
+ f: (branchLeaves: {
57
+ path: string[];
58
+ values: Record<string, T>;
59
+ }) => Effect.Effect<A, E, R>,
60
+ ): Effect.Effect<void, E, R> => {
61
+ const branchLeaves = collectBranchLeaves(obj, leafRefinement);
62
+ return Effect.forEach(branchLeaves, f, {
63
+ discard: true,
64
+ });
65
+ };
66
+
67
+ export const setNestedProperty = <T extends object>(
68
+ obj: T,
69
+ path: PropertyKey[],
70
+ value: any,
71
+ ): T => {
72
+ if (path.length === 0) {
73
+ return obj;
74
+ }
75
+
76
+ if (path.length === 1) {
77
+ const key = path[0] as keyof T;
78
+ return { ...obj, [key]: value };
79
+ }
80
+
81
+ const [head, ...tail] = path;
82
+ const key = head as keyof T;
83
+ return {
84
+ ...obj,
85
+ [key]: setNestedProperty((obj as any)[key] ?? {}, tail, value),
86
+ };
87
+ };