@gaganref/confect-server 0.0.0-stage → 10.3.1-fork.2
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.
- package/CHANGELOG.md +2119 -0
- package/LICENSE +7 -0
- package/README.md +16 -2
- package/dist/ActionCtx.d.ts +10 -0
- package/dist/ActionCtx.d.ts.map +1 -0
- package/dist/ActionCtx.js +18 -0
- package/dist/ActionCtx.js.map +1 -0
- package/dist/ActionRunner.d.ts +16 -0
- package/dist/ActionRunner.d.ts.map +1 -0
- package/dist/ActionRunner.js +18 -0
- package/dist/ActionRunner.js.map +1 -0
- package/dist/AiGatewayDecisionClient.d.ts +20 -0
- package/dist/AiGatewayDecisionClient.d.ts.map +1 -0
- package/dist/AiGatewayDecisionClient.js +31 -0
- package/dist/AiGatewayDecisionClient.js.map +1 -0
- package/dist/AiGatewayDecisionModel.d.ts +24 -0
- package/dist/AiGatewayDecisionModel.d.ts.map +1 -0
- package/dist/AiGatewayDecisionModel.js +27 -0
- package/dist/AiGatewayDecisionModel.js.map +1 -0
- package/dist/AiGatewayLanguageClient.d.ts +21 -0
- package/dist/AiGatewayLanguageClient.d.ts.map +1 -0
- package/dist/AiGatewayLanguageClient.js +32 -0
- package/dist/AiGatewayLanguageClient.js.map +1 -0
- package/dist/AiGatewayLanguageModel.d.ts +95 -0
- package/dist/AiGatewayLanguageModel.d.ts.map +1 -0
- package/dist/AiGatewayLanguageModel.js +42 -0
- package/dist/AiGatewayLanguageModel.js.map +1 -0
- package/dist/Auth.d.ts +20 -0
- package/dist/Auth.d.ts.map +1 -0
- package/dist/Auth.js +31 -0
- package/dist/Auth.js.map +1 -0
- package/dist/BlobNotFoundError.d.ts +9 -0
- package/dist/BlobNotFoundError.d.ts.map +1 -0
- package/dist/BlobNotFoundError.js +13 -0
- package/dist/BlobNotFoundError.js.map +1 -0
- package/dist/Callback.d.ts +31 -0
- package/dist/Callback.d.ts.map +1 -0
- package/dist/Callback.js +182 -0
- package/dist/Callback.js.map +1 -0
- package/dist/ComponentCtx.d.ts +71 -0
- package/dist/ComponentCtx.d.ts.map +1 -0
- package/dist/ComponentCtx.js +0 -0
- package/dist/ConvexConfigProvider.d.ts +21 -0
- package/dist/ConvexConfigProvider.d.ts.map +1 -0
- package/dist/ConvexConfigProvider.js +36 -0
- package/dist/ConvexConfigProvider.js.map +1 -0
- package/dist/ConvexFunctionDefinitions.d.ts +25 -0
- package/dist/ConvexFunctionDefinitions.d.ts.map +1 -0
- package/dist/ConvexFunctionDefinitions.js +25 -0
- package/dist/ConvexFunctionDefinitions.js.map +1 -0
- package/dist/ConvexLogger.d.ts +17 -0
- package/dist/ConvexLogger.d.ts.map +1 -0
- package/dist/ConvexLogger.js +33 -0
- package/dist/ConvexLogger.js.map +1 -0
- package/dist/CronJob.d.ts +14 -0
- package/dist/CronJob.d.ts.map +1 -0
- package/dist/CronJob.js +22 -0
- package/dist/CronJob.js.map +1 -0
- package/dist/CronJobs.d.ts +22 -0
- package/dist/CronJobs.d.ts.map +1 -0
- package/dist/CronJobs.js +83 -0
- package/dist/CronJobs.js.map +1 -0
- package/dist/DataModel.d.ts +28 -0
- package/dist/DataModel.d.ts.map +1 -0
- package/dist/DataModel.js +7 -0
- package/dist/DataModel.js.map +1 -0
- package/dist/DatabaseReader.d.ts +26 -0
- package/dist/DatabaseReader.d.ts.map +1 -0
- package/dist/DatabaseReader.js +33 -0
- package/dist/DatabaseReader.js.map +1 -0
- package/dist/DatabaseSchema.d.ts +67 -0
- package/dist/DatabaseSchema.d.ts.map +1 -0
- package/dist/DatabaseSchema.js +61 -0
- package/dist/DatabaseSchema.js.map +1 -0
- package/dist/DatabaseWriter.d.ts +44 -0
- package/dist/DatabaseWriter.d.ts.map +1 -0
- package/dist/DatabaseWriter.js +47 -0
- package/dist/DatabaseWriter.js.map +1 -0
- package/dist/Document.d.ts +37 -0
- package/dist/Document.d.ts.map +1 -0
- package/dist/Document.js +54 -0
- package/dist/Document.js.map +1 -0
- package/dist/ExecutionMetadata.d.ts +13 -0
- package/dist/ExecutionMetadata.d.ts.map +1 -0
- package/dist/ExecutionMetadata.js +19 -0
- package/dist/ExecutionMetadata.js.map +1 -0
- package/dist/FunctionImpl.d.ts +39 -0
- package/dist/FunctionImpl.d.ts.map +1 -0
- package/dist/FunctionImpl.js +46 -0
- package/dist/FunctionImpl.js.map +1 -0
- package/dist/FunctionRegistryItem.d.ts +36 -0
- package/dist/FunctionRegistryItem.d.ts.map +1 -0
- package/dist/FunctionRegistryItem.js +34 -0
- package/dist/FunctionRegistryItem.js.map +1 -0
- package/dist/GroupImpl.d.ts +77 -0
- package/dist/GroupImpl.d.ts.map +1 -0
- package/dist/GroupImpl.js +81 -0
- package/dist/GroupImpl.js.map +1 -0
- package/dist/GroupRegistry.d.ts +8 -0
- package/dist/GroupRegistry.d.ts.map +1 -0
- package/dist/GroupRegistry.js +26 -0
- package/dist/GroupRegistry.js.map +1 -0
- package/dist/Handler.d.ts +47 -0
- package/dist/Handler.d.ts.map +1 -0
- package/dist/Handler.js +7 -0
- package/dist/Handler.js.map +1 -0
- package/dist/HttpRouter.d.ts +80 -0
- package/dist/HttpRouter.d.ts.map +1 -0
- package/dist/HttpRouter.js +195 -0
- package/dist/HttpRouter.js.map +1 -0
- package/dist/MiddlewareImpl.d.ts +79 -0
- package/dist/MiddlewareImpl.d.ts.map +1 -0
- package/dist/MiddlewareImpl.js +58 -0
- package/dist/MiddlewareImpl.js.map +1 -0
- package/dist/MiddlewareRegistryItem.d.ts +12 -0
- package/dist/MiddlewareRegistryItem.d.ts.map +1 -0
- package/dist/MiddlewareRegistryItem.js +15 -0
- package/dist/MiddlewareRegistryItem.js.map +1 -0
- package/dist/MutationCtx.d.ts +10 -0
- package/dist/MutationCtx.d.ts.map +1 -0
- package/dist/MutationCtx.js +18 -0
- package/dist/MutationCtx.js.map +1 -0
- package/dist/MutationRunner.d.ts +27 -0
- package/dist/MutationRunner.d.ts.map +1 -0
- package/dist/MutationRunner.js +28 -0
- package/dist/MutationRunner.js.map +1 -0
- package/dist/MutationTransactionContext.d.ts +17 -0
- package/dist/MutationTransactionContext.d.ts.map +1 -0
- package/dist/MutationTransactionContext.js +20 -0
- package/dist/MutationTransactionContext.js.map +1 -0
- package/dist/OrderedQuery.d.ts +32 -0
- package/dist/OrderedQuery.d.ts.map +1 -0
- package/dist/OrderedQuery.js +36 -0
- package/dist/OrderedQuery.js.map +1 -0
- package/dist/QueryCtx.d.ts +10 -0
- package/dist/QueryCtx.d.ts.map +1 -0
- package/dist/QueryCtx.js +18 -0
- package/dist/QueryCtx.js.map +1 -0
- package/dist/QueryInitializer.d.ts +75 -0
- package/dist/QueryInitializer.d.ts.map +1 -0
- package/dist/QueryInitializer.js +105 -0
- package/dist/QueryInitializer.js.map +1 -0
- package/dist/QueryRunner.d.ts +46 -0
- package/dist/QueryRunner.d.ts.map +1 -0
- package/dist/QueryRunner.js +30 -0
- package/dist/QueryRunner.js.map +1 -0
- package/dist/QueryStream.d.ts +678 -0
- package/dist/QueryStream.d.ts.map +1 -0
- package/dist/QueryStream.js +943 -0
- package/dist/QueryStream.js.map +1 -0
- package/dist/QueryStreamCursor.d.ts +39 -0
- package/dist/QueryStreamCursor.d.ts.map +1 -0
- package/dist/QueryStreamCursor.js +52 -0
- package/dist/QueryStreamCursor.js.map +1 -0
- package/dist/QueryStreamIndexPrefix.d.ts +48 -0
- package/dist/QueryStreamIndexPrefix.d.ts.map +1 -0
- package/dist/QueryStreamIndexPrefix.js +38 -0
- package/dist/QueryStreamIndexPrefix.js.map +1 -0
- package/dist/QueryStreamIndexRange.d.ts +193 -0
- package/dist/QueryStreamIndexRange.d.ts.map +1 -0
- package/dist/QueryStreamIndexRange.js +241 -0
- package/dist/QueryStreamIndexRange.js.map +1 -0
- package/dist/QueryStreamKey.d.ts +64 -0
- package/dist/QueryStreamKey.d.ts.map +1 -0
- package/dist/QueryStreamKey.js +69 -0
- package/dist/QueryStreamKey.js.map +1 -0
- package/dist/QueryStreamKeyBounds.d.ts +136 -0
- package/dist/QueryStreamKeyBounds.d.ts.map +1 -0
- package/dist/QueryStreamKeyBounds.js +208 -0
- package/dist/QueryStreamKeyBounds.js.map +1 -0
- package/dist/QueryStreamKeyLabels.d.ts +27 -0
- package/dist/QueryStreamKeyLabels.d.ts.map +1 -0
- package/dist/QueryStreamKeyLabels.js +22 -0
- package/dist/QueryStreamKeyLabels.js.map +1 -0
- package/dist/QueryStreamKeyLayout.d.ts +179 -0
- package/dist/QueryStreamKeyLayout.d.ts.map +1 -0
- package/dist/QueryStreamKeyLayout.js +167 -0
- package/dist/QueryStreamKeyLayout.js.map +1 -0
- package/dist/QueryStreamKeyValues.d.ts +40 -0
- package/dist/QueryStreamKeyValues.d.ts.map +1 -0
- package/dist/QueryStreamKeyValues.js +57 -0
- package/dist/QueryStreamKeyValues.js.map +1 -0
- package/dist/QueryStreamOrderDirection.d.ts +24 -0
- package/dist/QueryStreamOrderDirection.d.ts.map +1 -0
- package/dist/QueryStreamOrderDirection.js +11 -0
- package/dist/QueryStreamOrderDirection.js.map +1 -0
- package/dist/QueryStreamPagination.d.ts +264 -0
- package/dist/QueryStreamPagination.d.ts.map +1 -0
- package/dist/QueryStreamPagination.js +172 -0
- package/dist/QueryStreamPagination.js.map +1 -0
- package/dist/QueryStreamReadBudget.d.ts +63 -0
- package/dist/QueryStreamReadBudget.d.ts.map +1 -0
- package/dist/QueryStreamReadBudget.js +81 -0
- package/dist/QueryStreamReadBudget.js.map +1 -0
- package/dist/QueryTransactionContext.d.ts +16 -0
- package/dist/QueryTransactionContext.d.ts.map +1 -0
- package/dist/QueryTransactionContext.js +17 -0
- package/dist/QueryTransactionContext.js.map +1 -0
- package/dist/RegisteredConvexFunction.d.ts +359 -0
- package/dist/RegisteredConvexFunction.d.ts.map +1 -0
- package/dist/RegisteredConvexFunction.js +154 -0
- package/dist/RegisteredConvexFunction.js.map +1 -0
- package/dist/RegisteredFunction.d.ts +143 -0
- package/dist/RegisteredFunction.d.ts.map +1 -0
- package/dist/RegisteredFunction.js +125 -0
- package/dist/RegisteredFunction.js.map +1 -0
- package/dist/RegisteredFunctions.d.ts +57 -0
- package/dist/RegisteredFunctions.d.ts.map +1 -0
- package/dist/RegisteredFunctions.js +32 -0
- package/dist/RegisteredFunctions.js.map +1 -0
- package/dist/RegisteredNodeFunction.d.ts +11 -0
- package/dist/RegisteredNodeFunction.d.ts.map +1 -0
- package/dist/RegisteredNodeFunction.js +45 -0
- package/dist/RegisteredNodeFunction.js.map +1 -0
- package/dist/Registry.d.ts +12 -0
- package/dist/Registry.d.ts.map +1 -0
- package/dist/Registry.js +17 -0
- package/dist/Registry.js.map +1 -0
- package/dist/RegistryItems.d.ts +21 -0
- package/dist/RegistryItems.d.ts.map +1 -0
- package/dist/RegistryItems.js +27 -0
- package/dist/RegistryItems.js.map +1 -0
- package/dist/RequestMetadata.d.ts +12 -0
- package/dist/RequestMetadata.d.ts.map +1 -0
- package/dist/RequestMetadata.js +16 -0
- package/dist/RequestMetadata.js.map +1 -0
- package/dist/ResolvedMiddleware.d.ts +24 -0
- package/dist/ResolvedMiddleware.d.ts.map +1 -0
- package/dist/ResolvedMiddleware.js +34 -0
- package/dist/ResolvedMiddleware.js.map +1 -0
- package/dist/Scheduler.d.ts +31 -0
- package/dist/Scheduler.d.ts.map +1 -0
- package/dist/Scheduler.js +35 -0
- package/dist/Scheduler.js.map +1 -0
- package/dist/Storage.d.ts +22 -0
- package/dist/Storage.d.ts.map +1 -0
- package/dist/Storage.js +27 -0
- package/dist/Storage.js.map +1 -0
- package/dist/StorageActionWriter.d.ts +35 -0
- package/dist/StorageActionWriter.d.ts.map +1 -0
- package/dist/StorageActionWriter.js +24 -0
- package/dist/StorageActionWriter.js.map +1 -0
- package/dist/StorageReader.d.ts +26 -0
- package/dist/StorageReader.d.ts.map +1 -0
- package/dist/StorageReader.js +22 -0
- package/dist/StorageReader.js.map +1 -0
- package/dist/StorageWriter.d.ts +29 -0
- package/dist/StorageWriter.d.ts.map +1 -0
- package/dist/StorageWriter.js +24 -0
- package/dist/StorageWriter.js.map +1 -0
- package/dist/Table.d.ts +274 -0
- package/dist/Table.d.ts.map +1 -0
- package/dist/Table.js +70 -0
- package/dist/Table.js.map +1 -0
- package/dist/TableInfo.d.ts +44 -0
- package/dist/TableInfo.d.ts.map +1 -0
- package/dist/TableInfo.js +7 -0
- package/dist/TableInfo.js.map +1 -0
- package/dist/TransactionMetadata.d.ts +12 -0
- package/dist/TransactionMetadata.d.ts.map +1 -0
- package/dist/TransactionMetadata.js +16 -0
- package/dist/TransactionMetadata.js.map +1 -0
- package/dist/VectorSearch.d.ts +23 -0
- package/dist/VectorSearch.d.ts.map +1 -0
- package/dist/VectorSearch.js +17 -0
- package/dist/VectorSearch.js.map +1 -0
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/index.d.ts +88 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +61 -0
- package/dist/internal/AiGatewayDecisionClient.d.ts +7 -0
- package/dist/internal/AiGatewayDecisionClient.d.ts.map +1 -0
- package/dist/internal/AiGatewayDecisionClient.js +19 -0
- package/dist/internal/AiGatewayDecisionClient.js.map +1 -0
- package/dist/internal/AiGatewayLanguageClient.d.ts +7 -0
- package/dist/internal/AiGatewayLanguageClient.d.ts.map +1 -0
- package/dist/internal/AiGatewayLanguageClient.js +19 -0
- package/dist/internal/AiGatewayLanguageClient.js.map +1 -0
- package/dist/internal/AiGatewayServiceToken.d.ts +46 -0
- package/dist/internal/AiGatewayServiceToken.d.ts.map +1 -0
- package/dist/internal/AiGatewayServiceToken.js +62 -0
- package/dist/internal/AiGatewayServiceToken.js.map +1 -0
- package/dist/internal/constants.d.ts +2 -0
- package/dist/internal/constants.d.ts.map +1 -0
- package/dist/internal/constants.js +6 -0
- package/dist/internal/constants.js.map +1 -0
- package/dist/internal/utils.d.ts +13 -0
- package/dist/internal/utils.d.ts.map +1 -0
- package/dist/internal/utils.js +50 -0
- package/dist/internal/utils.js.map +1 -0
- package/dist/node.d.ts +2 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +1 -0
- package/package.json +68 -3
- package/src/ActionCtx.ts +45 -0
- package/src/ActionRunner.ts +36 -0
- package/src/AiGatewayDecisionClient.ts +40 -0
- package/src/AiGatewayDecisionModel.ts +46 -0
- package/src/AiGatewayLanguageClient.ts +41 -0
- package/src/AiGatewayLanguageModel.ts +61 -0
- package/src/Auth.ts +51 -0
- package/src/BlobNotFoundError.ts +12 -0
- package/src/Callback.ts +313 -0
- package/src/ComponentCtx.ts +192 -0
- package/src/ConvexConfigProvider.ts +39 -0
- package/src/ConvexFunctionDefinitions.ts +91 -0
- package/src/ConvexLogger.ts +43 -0
- package/src/CronJob.ts +42 -0
- package/src/CronJobs.ts +165 -0
- package/src/DataModel.ts +81 -0
- package/src/DatabaseReader.ts +118 -0
- package/src/DatabaseSchema.ts +139 -0
- package/src/DatabaseWriter.ts +232 -0
- package/src/Document.ts +146 -0
- package/src/ExecutionMetadata.ts +26 -0
- package/src/FunctionImpl.ts +96 -0
- package/src/FunctionRegistryItem.ts +85 -0
- package/src/GroupImpl.ts +167 -0
- package/src/GroupRegistry.ts +41 -0
- package/src/Handler.ts +191 -0
- package/src/HttpRouter.ts +388 -0
- package/src/MiddlewareImpl.ts +247 -0
- package/src/MiddlewareRegistryItem.ts +21 -0
- package/src/MutationCtx.ts +45 -0
- package/src/MutationRunner.ts +66 -0
- package/src/MutationTransactionContext.ts +48 -0
- package/src/OrderedQuery.ts +136 -0
- package/src/QueryCtx.ts +45 -0
- package/src/QueryInitializer.ts +537 -0
- package/src/QueryRunner.ts +91 -0
- package/src/QueryStream.ts +2476 -0
- package/src/QueryStreamCursor.ts +99 -0
- package/src/QueryStreamIndexPrefix.ts +79 -0
- package/src/QueryStreamIndexRange.ts +489 -0
- package/src/QueryStreamKey.ts +118 -0
- package/src/QueryStreamKeyBounds.ts +395 -0
- package/src/QueryStreamKeyLabels.ts +56 -0
- package/src/QueryStreamKeyLayout.ts +382 -0
- package/src/QueryStreamKeyValues.ts +112 -0
- package/src/QueryStreamOrderDirection.ts +29 -0
- package/src/QueryStreamPagination.ts +357 -0
- package/src/QueryStreamReadBudget.ts +167 -0
- package/src/QueryTransactionContext.ts +37 -0
- package/src/RegisteredConvexFunction.ts +415 -0
- package/src/RegisteredFunction.ts +391 -0
- package/src/RegisteredFunctions.ts +88 -0
- package/src/RegisteredNodeFunction.ts +120 -0
- package/src/Registry.ts +17 -0
- package/src/RegistryItems.ts +40 -0
- package/src/RequestMetadata.ts +20 -0
- package/src/ResolvedMiddleware.ts +70 -0
- package/src/Scheduler.ts +85 -0
- package/src/Storage.ts +37 -0
- package/src/StorageActionWriter.ts +59 -0
- package/src/StorageReader.ts +59 -0
- package/src/StorageWriter.ts +58 -0
- package/src/Table.ts +156 -0
- package/src/TableInfo.ts +106 -0
- package/src/TransactionMetadata.ts +20 -0
- package/src/VectorSearch.ts +75 -0
- package/src/index.ts +87 -0
- package/src/internal/AiGatewayDecisionClient.ts +16 -0
- package/src/internal/AiGatewayLanguageClient.ts +16 -0
- package/src/internal/AiGatewayServiceToken.ts +129 -0
- package/src/internal/constants.ts +1 -0
- package/src/internal/utils.ts +89 -0
- package/src/node.ts +1 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import type { GenericDatabaseReader } from "convex/server";
|
|
2
|
+
import * as Context from "effect/Context";
|
|
3
|
+
import * as Layer from "effect/Layer";
|
|
4
|
+
import type { BaseDatabaseReader } from "@confect/core/Types";
|
|
5
|
+
import * as DatabaseSchema from "./DatabaseSchema";
|
|
6
|
+
import type * as DataModel from "./DataModel";
|
|
7
|
+
import * as QueryInitializer from "./QueryInitializer";
|
|
8
|
+
import * as Table from "./Table";
|
|
9
|
+
|
|
10
|
+
type IncludedTables<DatabaseSchema_ extends DatabaseSchema.AnyWithProps> =
|
|
11
|
+
| DatabaseSchema.Tables<DatabaseSchema_>
|
|
12
|
+
| Table.SystemTables<DatabaseSchema.Scope<DatabaseSchema_>>;
|
|
13
|
+
|
|
14
|
+
type IncludedDataModel<DatabaseSchema_ extends DatabaseSchema.AnyWithProps> =
|
|
15
|
+
DataModel.FromTables<IncludedTables<DatabaseSchema_>>;
|
|
16
|
+
|
|
17
|
+
export interface DatabaseReaderService<
|
|
18
|
+
DatabaseSchema_ extends DatabaseSchema.AnyWithProps,
|
|
19
|
+
Docs = {},
|
|
20
|
+
> {
|
|
21
|
+
readonly table: <
|
|
22
|
+
const TableName extends Table.Name<IncludedTables<DatabaseSchema_>>,
|
|
23
|
+
>(
|
|
24
|
+
tableName: TableName,
|
|
25
|
+
) => QueryInitializer.QueryInitializer<
|
|
26
|
+
IncludedDataModel<DatabaseSchema_>,
|
|
27
|
+
TableName,
|
|
28
|
+
TableName extends keyof Docs
|
|
29
|
+
? Docs[TableName]
|
|
30
|
+
: DataModel.DocumentWithName<
|
|
31
|
+
IncludedDataModel<DatabaseSchema_>,
|
|
32
|
+
TableName
|
|
33
|
+
>,
|
|
34
|
+
DatabaseSchema_["target"]["kind"]
|
|
35
|
+
>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const make = <DatabaseSchema_ extends DatabaseSchema.AnyWithProps>(
|
|
39
|
+
databaseSchema: DatabaseSchema_,
|
|
40
|
+
convexDatabaseReader: GenericDatabaseReader<
|
|
41
|
+
DataModel.ToConvex<DataModel.FromSchema<DatabaseSchema_>>
|
|
42
|
+
>,
|
|
43
|
+
): DatabaseReaderService<DatabaseSchema_> => {
|
|
44
|
+
const systemTables = Table.systemTablesForScope(databaseSchema.target.scope);
|
|
45
|
+
return {
|
|
46
|
+
table: <
|
|
47
|
+
const TableName extends Table.Name<IncludedTables<DatabaseSchema_>>,
|
|
48
|
+
>(
|
|
49
|
+
tableName: TableName,
|
|
50
|
+
) => {
|
|
51
|
+
const isSystem = Object.hasOwn(systemTables, tableName);
|
|
52
|
+
|
|
53
|
+
const baseDatabaseReader: BaseDatabaseReader<any> = isSystem
|
|
54
|
+
? {
|
|
55
|
+
get: convexDatabaseReader.system.get.bind(
|
|
56
|
+
convexDatabaseReader.system,
|
|
57
|
+
),
|
|
58
|
+
query: convexDatabaseReader.system.query.bind(
|
|
59
|
+
convexDatabaseReader.system,
|
|
60
|
+
),
|
|
61
|
+
}
|
|
62
|
+
: {
|
|
63
|
+
get: convexDatabaseReader.get.bind(convexDatabaseReader),
|
|
64
|
+
query: convexDatabaseReader.query.bind(convexDatabaseReader),
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const table = (
|
|
68
|
+
isSystem
|
|
69
|
+
? (systemTables as Record<string, Table.AnyWithProps>)[tableName]
|
|
70
|
+
: DatabaseSchema.tables(databaseSchema)[tableName]
|
|
71
|
+
) as Table.WithName<IncludedTables<DatabaseSchema_>, TableName>;
|
|
72
|
+
|
|
73
|
+
return QueryInitializer.make<IncludedTables<DatabaseSchema_>, TableName>(
|
|
74
|
+
baseDatabaseReader,
|
|
75
|
+
table,
|
|
76
|
+
);
|
|
77
|
+
},
|
|
78
|
+
} as DatabaseReaderService<DatabaseSchema_>;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The tag's _Identifier_ (the Effect requirements-channel type) is
|
|
83
|
+
* `Docs`-independent so a helper's `R` channel is the same whether or not a
|
|
84
|
+
* codegen document registry is supplied—this keeps it identical to what
|
|
85
|
+
* `Handler`/runtime provisioning provide. The tag's _Service_ (what `yield*`
|
|
86
|
+
* produces) carries `Docs`, so queries resolve to the named doc interfaces.
|
|
87
|
+
*/
|
|
88
|
+
export type DatabaseReaderTag<
|
|
89
|
+
DatabaseSchema_ extends DatabaseSchema.AnyWithProps,
|
|
90
|
+
Docs = {},
|
|
91
|
+
> = Context.Service<
|
|
92
|
+
DatabaseReaderService<DatabaseSchema_>,
|
|
93
|
+
DatabaseReaderService<DatabaseSchema_, Docs>
|
|
94
|
+
>;
|
|
95
|
+
|
|
96
|
+
export const DatabaseReader = <
|
|
97
|
+
DatabaseSchema_ extends DatabaseSchema.AnyWithProps,
|
|
98
|
+
Docs = {},
|
|
99
|
+
>(): DatabaseReaderTag<DatabaseSchema_, Docs> =>
|
|
100
|
+
Context.Service<
|
|
101
|
+
DatabaseReaderService<DatabaseSchema_>,
|
|
102
|
+
DatabaseReaderService<DatabaseSchema_, Docs>
|
|
103
|
+
>("@confect/server/DatabaseReader");
|
|
104
|
+
|
|
105
|
+
export type DatabaseReader<
|
|
106
|
+
DatabaseSchema_ extends DatabaseSchema.AnyWithProps,
|
|
107
|
+
> = DatabaseReaderService<DatabaseSchema_>;
|
|
108
|
+
|
|
109
|
+
export const layer = <DatabaseSchema_ extends DatabaseSchema.AnyWithProps>(
|
|
110
|
+
databaseSchema: DatabaseSchema_,
|
|
111
|
+
convexDatabaseReader: GenericDatabaseReader<
|
|
112
|
+
DataModel.ToConvex<DataModel.FromSchema<DatabaseSchema_>>
|
|
113
|
+
>,
|
|
114
|
+
) =>
|
|
115
|
+
Layer.succeed(
|
|
116
|
+
DatabaseReader<DatabaseSchema_>(),
|
|
117
|
+
make(databaseSchema, convexDatabaseReader),
|
|
118
|
+
);
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import * as IdScope from "@confect/core/IdScope";
|
|
2
|
+
import * as Data from "effect/Data";
|
|
3
|
+
import * as Result from "effect/Result";
|
|
4
|
+
import * as Predicate from "effect/Predicate";
|
|
5
|
+
import * as Record from "effect/Record";
|
|
6
|
+
import type * as Table from "./Table";
|
|
7
|
+
|
|
8
|
+
export class EmptyDatabaseScopeError extends Data.TaggedError(
|
|
9
|
+
"EmptyDatabaseScopeError",
|
|
10
|
+
)<{
|
|
11
|
+
readonly databaseScope: IdScope.IdScope;
|
|
12
|
+
}> {
|
|
13
|
+
override get message(): string {
|
|
14
|
+
return "A component database schema requires a nonempty ID scope.";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class TableBindingMismatchError extends Data.TaggedError(
|
|
19
|
+
"TableBindingMismatchError",
|
|
20
|
+
)<{
|
|
21
|
+
readonly bindingName: string;
|
|
22
|
+
readonly tableName: string;
|
|
23
|
+
readonly tableScope: IdScope.IdScope;
|
|
24
|
+
readonly databaseScope: IdScope.IdScope;
|
|
25
|
+
}> {
|
|
26
|
+
override get message(): string {
|
|
27
|
+
return `Table '${this.bindingName}' must be bound to its database schema's name and ID scope.`;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const TypeId = "~@confect/server/DatabaseSchema";
|
|
32
|
+
export type TypeId = typeof TypeId;
|
|
33
|
+
|
|
34
|
+
export interface AppTarget {
|
|
35
|
+
readonly kind: "app";
|
|
36
|
+
readonly scope: IdScope.App;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface ComponentTarget<
|
|
40
|
+
Scope_ extends IdScope.IdScope = IdScope.IdScope,
|
|
41
|
+
> {
|
|
42
|
+
readonly kind: "component";
|
|
43
|
+
readonly scope: Scope_;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type Target = AppTarget | ComponentTarget;
|
|
47
|
+
|
|
48
|
+
export interface Any {
|
|
49
|
+
readonly [TypeId]: unknown;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const isDatabaseSchema = (u: unknown): u is Any =>
|
|
53
|
+
Predicate.hasProperty(u, TypeId);
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* A schema definition holding a record of bound `Table`s keyed by table name.
|
|
57
|
+
* Codegen emits a single static `DatabaseSchema.make({ ... })` call; laziness
|
|
58
|
+
* lives entirely on each `Table` (its `Fields` and `Doc` are lazy memoised
|
|
59
|
+
* getters), so this layer is a plain record indirection with no module-loading
|
|
60
|
+
* or async machinery.
|
|
61
|
+
*/
|
|
62
|
+
export interface DatabaseSchema<
|
|
63
|
+
Tables_ extends Readonly<Record<string, Table.AnyWithProps>> = {},
|
|
64
|
+
Target_ extends Target = AppTarget,
|
|
65
|
+
> {
|
|
66
|
+
readonly [TypeId]: Readonly<Tables_>;
|
|
67
|
+
readonly target: Target_;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface AnyWithProps extends DatabaseSchema<
|
|
71
|
+
Readonly<Record<string, Table.AnyWithProps>>,
|
|
72
|
+
Target
|
|
73
|
+
> {}
|
|
74
|
+
|
|
75
|
+
export type Scope<Schema extends AnyWithProps> = Schema["target"]["scope"];
|
|
76
|
+
|
|
77
|
+
export type Tables<DatabaseSchema_ extends AnyWithProps> =
|
|
78
|
+
DatabaseSchema_[TypeId][keyof DatabaseSchema_[TypeId]];
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The bound table record, without evaluating any table schemas.
|
|
82
|
+
*/
|
|
83
|
+
export const tables = <Schema extends AnyWithProps>(
|
|
84
|
+
self: Schema,
|
|
85
|
+
): Schema[TypeId] => self[TypeId];
|
|
86
|
+
|
|
87
|
+
export type TableNames<DatabaseSchema_ extends AnyWithProps> = Table.Name<
|
|
88
|
+
Tables<DatabaseSchema_>
|
|
89
|
+
> &
|
|
90
|
+
string;
|
|
91
|
+
|
|
92
|
+
export type TableWithName<
|
|
93
|
+
DatabaseSchema_ extends AnyWithProps,
|
|
94
|
+
TableName extends TableNames<DatabaseSchema_>,
|
|
95
|
+
> = Extract<Tables<DatabaseSchema_>, { readonly tableName: TableName }>;
|
|
96
|
+
|
|
97
|
+
const validateBindings = (
|
|
98
|
+
tableRecord: Readonly<Record<string, Table.AnyWithProps>>,
|
|
99
|
+
target: Target,
|
|
100
|
+
): Result.Result<void, EmptyDatabaseScopeError | TableBindingMismatchError> => {
|
|
101
|
+
if (target.kind === "component" && target.scope === "") {
|
|
102
|
+
return Result.fail(
|
|
103
|
+
new EmptyDatabaseScopeError({ databaseScope: target.scope }),
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
for (const [name, table] of Record.toEntries(tableRecord)) {
|
|
107
|
+
if (name !== table.tableName || table.scope !== target.scope) {
|
|
108
|
+
return Result.fail(
|
|
109
|
+
new TableBindingMismatchError({
|
|
110
|
+
bindingName: name,
|
|
111
|
+
tableName: table.tableName,
|
|
112
|
+
tableScope: table.scope,
|
|
113
|
+
databaseScope: target.scope,
|
|
114
|
+
}),
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return Result.succeed(undefined);
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Construct a database schema from its bound table record. The record's keys
|
|
123
|
+
* must match their tables' names. Table schemas remain lazy; construction only
|
|
124
|
+
* stores the record. The empty case is `make({})`.
|
|
125
|
+
*/
|
|
126
|
+
export const make = <
|
|
127
|
+
const TablesRecord extends Readonly<Record<string, Table.AnyWithProps>>,
|
|
128
|
+
const Target_ extends Target = AppTarget,
|
|
129
|
+
>(
|
|
130
|
+
tableRecord: TablesRecord,
|
|
131
|
+
target?: Target_,
|
|
132
|
+
): DatabaseSchema<TablesRecord, Target_> => {
|
|
133
|
+
const resolvedTarget = target ?? { kind: "app", scope: IdScope.app };
|
|
134
|
+
Result.getOrThrow(validateBindings(tableRecord, resolvedTarget));
|
|
135
|
+
return {
|
|
136
|
+
[TypeId]: tableRecord,
|
|
137
|
+
target: resolvedTarget,
|
|
138
|
+
} as DatabaseSchema<TablesRecord, Target_>;
|
|
139
|
+
};
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
BetterOmit,
|
|
3
|
+
DocumentByName,
|
|
4
|
+
Expand,
|
|
5
|
+
GenericDatabaseWriter,
|
|
6
|
+
WithoutSystemFields,
|
|
7
|
+
} from "convex/server";
|
|
8
|
+
import type { GenericId } from "convex/values";
|
|
9
|
+
import { pipe } from "effect/Function";
|
|
10
|
+
import * as Context from "effect/Context";
|
|
11
|
+
import * as Effect from "effect/Effect";
|
|
12
|
+
import * as Layer from "effect/Layer";
|
|
13
|
+
import * as Record from "effect/Record";
|
|
14
|
+
import * as DatabaseSchema from "./DatabaseSchema";
|
|
15
|
+
import type * as DataModel from "./DataModel";
|
|
16
|
+
import type { DocumentByName as DocumentByName_ } from "./DataModel";
|
|
17
|
+
import * as Document from "./Document";
|
|
18
|
+
import * as QueryInitializer from "./QueryInitializer";
|
|
19
|
+
import type * as Table from "./Table";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The argument accepted by `patch`: like `Partial<Doc>` without system fields,
|
|
23
|
+
* but the fields that are already optional also accept `undefined`, since
|
|
24
|
+
* setting a field to `undefined` unsets it.
|
|
25
|
+
*/
|
|
26
|
+
export type PatchValue<Doc> = {
|
|
27
|
+
[
|
|
28
|
+
K in keyof Doc as K extends "_id" | "_creationTime" ? never : K
|
|
29
|
+
]?: undefined extends Doc[K] ? Doc[K] | undefined : Doc[K];
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export interface DatabaseWriterTableAccessor<
|
|
33
|
+
DataModel_ extends DataModel.AnyWithProps,
|
|
34
|
+
TableName extends DataModel.TableNames<DataModel_>,
|
|
35
|
+
Doc = DocumentByName_<DataModel_, TableName>,
|
|
36
|
+
> {
|
|
37
|
+
readonly insert: (
|
|
38
|
+
document: Document.WithoutSystemFields<Doc>,
|
|
39
|
+
) => Effect.Effect<
|
|
40
|
+
DataModel.Id<DataModel_, TableName>,
|
|
41
|
+
Document.DocumentEncodeError
|
|
42
|
+
>;
|
|
43
|
+
readonly patch: (
|
|
44
|
+
id: DataModel.Id<DataModel_, TableName>,
|
|
45
|
+
patchedValues: PatchValue<Doc>,
|
|
46
|
+
) => Effect.Effect<
|
|
47
|
+
void,
|
|
48
|
+
| QueryInitializer.GetByIdFailure
|
|
49
|
+
| Document.DocumentDecodeError
|
|
50
|
+
| Document.DocumentEncodeError
|
|
51
|
+
>;
|
|
52
|
+
readonly replace: (
|
|
53
|
+
id: DataModel.Id<DataModel_, TableName>,
|
|
54
|
+
value: Document.WithoutSystemFields<Doc>,
|
|
55
|
+
) => Effect.Effect<void, Document.DocumentEncodeError>;
|
|
56
|
+
readonly delete: (
|
|
57
|
+
id: DataModel.Id<DataModel_, TableName>,
|
|
58
|
+
) => Effect.Effect<void>;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The service shape backing the `DatabaseWriter` tag. Named (rather than an
|
|
63
|
+
* inferred anonymous object) so declaration emit prints
|
|
64
|
+
* `DatabaseWriterService<…>` by reference instead of expanding the data model.
|
|
65
|
+
* `Docs` is the optional named document registry (see
|
|
66
|
+
* `DatabaseReaderService`).
|
|
67
|
+
*/
|
|
68
|
+
export interface DatabaseWriterService<
|
|
69
|
+
DatabaseSchema_ extends DatabaseSchema.AnyWithProps,
|
|
70
|
+
Docs = {},
|
|
71
|
+
> {
|
|
72
|
+
readonly table: <
|
|
73
|
+
const TableName extends DataModel.TableNames<
|
|
74
|
+
DataModel.FromSchema<DatabaseSchema_>
|
|
75
|
+
>,
|
|
76
|
+
>(
|
|
77
|
+
tableName: TableName,
|
|
78
|
+
) => DatabaseWriterTableAccessor<
|
|
79
|
+
DataModel.FromSchema<DatabaseSchema_>,
|
|
80
|
+
TableName,
|
|
81
|
+
TableName extends keyof Docs
|
|
82
|
+
? Docs[TableName]
|
|
83
|
+
: DocumentByName_<DataModel.FromSchema<DatabaseSchema_>, TableName>
|
|
84
|
+
>;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* The tag's _Identifier_ is `Docs`-independent (see `DatabaseReaderTag`); only
|
|
89
|
+
* the _Service_ carries `Docs` so writer inputs print the named doc
|
|
90
|
+
* interfaces.
|
|
91
|
+
*/
|
|
92
|
+
export type DatabaseWriterTag<
|
|
93
|
+
DatabaseSchema_ extends DatabaseSchema.AnyWithProps,
|
|
94
|
+
Docs = {},
|
|
95
|
+
> = Context.Service<
|
|
96
|
+
DatabaseWriterService<DatabaseSchema_>,
|
|
97
|
+
DatabaseWriterService<DatabaseSchema_, Docs>
|
|
98
|
+
>;
|
|
99
|
+
|
|
100
|
+
export const make = <DatabaseSchema_ extends DatabaseSchema.AnyWithProps>(
|
|
101
|
+
databaseSchema: DatabaseSchema_,
|
|
102
|
+
convexDatabaseWriter: GenericDatabaseWriter<
|
|
103
|
+
DataModel.ToConvex<DataModel.FromSchema<DatabaseSchema_>>
|
|
104
|
+
>,
|
|
105
|
+
): DatabaseWriterService<DatabaseSchema_> => {
|
|
106
|
+
type DataModel_ = DataModel.FromSchema<DatabaseSchema_>;
|
|
107
|
+
|
|
108
|
+
const table = <const TableName extends DataModel.TableNames<DataModel_>>(
|
|
109
|
+
tableName: TableName,
|
|
110
|
+
) => {
|
|
111
|
+
const tableDef = DatabaseSchema.tables(databaseSchema)[tableName];
|
|
112
|
+
|
|
113
|
+
const insert = Effect.fn("DatabaseWriter.insert")(function* (
|
|
114
|
+
document: Document.WithoutSystemFields<
|
|
115
|
+
DocumentByName_<DataModel_, TableName>
|
|
116
|
+
>,
|
|
117
|
+
) {
|
|
118
|
+
const encodedDocument = yield* Document.encode(document, tableDef);
|
|
119
|
+
|
|
120
|
+
const id = yield* Effect.promise(() =>
|
|
121
|
+
convexDatabaseWriter.insert(
|
|
122
|
+
tableName,
|
|
123
|
+
encodedDocument as WithoutSystemFields<
|
|
124
|
+
DocumentByName<DataModel.ToConvex<DataModel_>, TableName>
|
|
125
|
+
>,
|
|
126
|
+
),
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
// The database supplies the ID in this table's execution scope. Its
|
|
130
|
+
// scope brand is erased at the Convex syscall boundary.
|
|
131
|
+
return id as unknown as DataModel.Id<DataModel_, TableName>;
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
const patch = Effect.fn("DatabaseWriter.patch")(function* (
|
|
135
|
+
id: DataModel.Id<DataModel_, TableName>,
|
|
136
|
+
patchedValues: PatchValue<
|
|
137
|
+
Document.WithoutSystemFields<DocumentByName_<DataModel_, TableName>>
|
|
138
|
+
>,
|
|
139
|
+
) {
|
|
140
|
+
const originalDecodedDoc = yield* QueryInitializer.getById<
|
|
141
|
+
Table.AnyWithProps,
|
|
142
|
+
TableName
|
|
143
|
+
>(
|
|
144
|
+
convexDatabaseWriter as any,
|
|
145
|
+
tableDef,
|
|
146
|
+
)(id as unknown as GenericId<TableName>);
|
|
147
|
+
|
|
148
|
+
const updatedEncodedDoc = yield* pipe(
|
|
149
|
+
patchedValues,
|
|
150
|
+
Record.reduce(originalDecodedDoc, (acc, value, key) =>
|
|
151
|
+
value === undefined
|
|
152
|
+
? Record.remove(acc, key)
|
|
153
|
+
: Record.set(acc, key, value),
|
|
154
|
+
),
|
|
155
|
+
Document.encode(tableDef),
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
yield* Effect.promise(() =>
|
|
159
|
+
convexDatabaseWriter.replace(
|
|
160
|
+
id as unknown as GenericId<TableName>,
|
|
161
|
+
updatedEncodedDoc as Expand<
|
|
162
|
+
BetterOmit<
|
|
163
|
+
DocumentByName<DataModel.ToConvex<DataModel_>, TableName>,
|
|
164
|
+
"_creationTime" | "_id"
|
|
165
|
+
>
|
|
166
|
+
>,
|
|
167
|
+
),
|
|
168
|
+
);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
const replace = Effect.fn("DatabaseWriter.replace")(function* (
|
|
172
|
+
id: DataModel.Id<DataModel_, TableName>,
|
|
173
|
+
value: Document.WithoutSystemFields<
|
|
174
|
+
DocumentByName_<DataModel_, TableName>
|
|
175
|
+
>,
|
|
176
|
+
) {
|
|
177
|
+
const updatedEncodedDoc = yield* Document.encode(value, tableDef);
|
|
178
|
+
|
|
179
|
+
yield* Effect.promise(() =>
|
|
180
|
+
convexDatabaseWriter.replace(
|
|
181
|
+
id as unknown as GenericId<TableName>,
|
|
182
|
+
updatedEncodedDoc as Expand<
|
|
183
|
+
BetterOmit<
|
|
184
|
+
DocumentByName<DataModel.ToConvex<DataModel_>, TableName>,
|
|
185
|
+
"_creationTime" | "_id"
|
|
186
|
+
>
|
|
187
|
+
>,
|
|
188
|
+
),
|
|
189
|
+
);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
const delete_ = (id: DataModel.Id<DataModel_, TableName>) =>
|
|
193
|
+
Effect.promise(() =>
|
|
194
|
+
convexDatabaseWriter.delete(id as unknown as GenericId<TableName>),
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
return {
|
|
198
|
+
insert,
|
|
199
|
+
patch,
|
|
200
|
+
replace,
|
|
201
|
+
delete: delete_,
|
|
202
|
+
};
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
return {
|
|
206
|
+
table,
|
|
207
|
+
} as DatabaseWriterService<DatabaseSchema_>;
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
export const DatabaseWriter = <
|
|
211
|
+
DatabaseSchema_ extends DatabaseSchema.AnyWithProps,
|
|
212
|
+
Docs = {},
|
|
213
|
+
>(): DatabaseWriterTag<DatabaseSchema_, Docs> =>
|
|
214
|
+
Context.Service<
|
|
215
|
+
DatabaseWriterService<DatabaseSchema_>,
|
|
216
|
+
DatabaseWriterService<DatabaseSchema_, Docs>
|
|
217
|
+
>("@confect/server/DatabaseWriter");
|
|
218
|
+
|
|
219
|
+
export type DatabaseWriter<
|
|
220
|
+
DatabaseSchema_ extends DatabaseSchema.AnyWithProps,
|
|
221
|
+
> = DatabaseWriterService<DatabaseSchema_>;
|
|
222
|
+
|
|
223
|
+
export const layer = <DatabaseSchema_ extends DatabaseSchema.AnyWithProps>(
|
|
224
|
+
databaseSchema: DatabaseSchema_,
|
|
225
|
+
convexDatabaseWriter: GenericDatabaseWriter<
|
|
226
|
+
DataModel.ToConvex<DataModel.FromSchema<DatabaseSchema_>>
|
|
227
|
+
>,
|
|
228
|
+
) =>
|
|
229
|
+
Layer.succeed(
|
|
230
|
+
DatabaseWriter<DatabaseSchema_>(),
|
|
231
|
+
make(databaseSchema, convexDatabaseWriter),
|
|
232
|
+
);
|
package/src/Document.ts
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import type { ReadonlyValue } from "@confect/core/SchemaToValidator";
|
|
2
|
+
import { pipe } from "effect/Function";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
import * as Function from "effect/Function";
|
|
5
|
+
import * as Schema from "effect/Schema";
|
|
6
|
+
import type { ReadonlyRecord } from "effect/Record";
|
|
7
|
+
import type * as DatabaseSchema from "./DatabaseSchema";
|
|
8
|
+
import type * as DataModel from "./DataModel";
|
|
9
|
+
import type * as TableInfo from "./TableInfo";
|
|
10
|
+
import type * as Table from "./Table";
|
|
11
|
+
|
|
12
|
+
export type Document<
|
|
13
|
+
Schema_ extends DatabaseSchema.AnyWithProps,
|
|
14
|
+
TableName extends DatabaseSchema.TableNames<Schema_>,
|
|
15
|
+
> = DataModel.DocumentByName<DataModel.FromSchema<Schema_>, TableName>;
|
|
16
|
+
|
|
17
|
+
export type WithoutSystemFields<Doc> = Doc extends unknown
|
|
18
|
+
? Omit<Doc, "_creationTime" | "_id">
|
|
19
|
+
: never;
|
|
20
|
+
|
|
21
|
+
export type Any = any;
|
|
22
|
+
export type AnyEncoded = ReadonlyRecord<string, ReadonlyValue>;
|
|
23
|
+
|
|
24
|
+
export const decode = Function.dual<
|
|
25
|
+
<Table_ extends Table.AnyWithProps>(
|
|
26
|
+
table: Table_,
|
|
27
|
+
) => (
|
|
28
|
+
self: TableInfo.TableInfo<Table_>["convexDocument"],
|
|
29
|
+
) => Effect.Effect<
|
|
30
|
+
TableInfo.TableInfo<Table_>["document"],
|
|
31
|
+
DocumentDecodeError
|
|
32
|
+
>,
|
|
33
|
+
<Table_ extends Table.AnyWithProps>(
|
|
34
|
+
self: TableInfo.TableInfo<Table_>["convexDocument"],
|
|
35
|
+
table: Table_,
|
|
36
|
+
) => Effect.Effect<
|
|
37
|
+
TableInfo.TableInfo<Table_>["document"],
|
|
38
|
+
DocumentDecodeError
|
|
39
|
+
>
|
|
40
|
+
>(
|
|
41
|
+
2,
|
|
42
|
+
<Table_ extends Table.AnyWithProps>(
|
|
43
|
+
self: TableInfo.TableInfo<Table_>["convexDocument"],
|
|
44
|
+
table: Table_,
|
|
45
|
+
): Effect.Effect<
|
|
46
|
+
TableInfo.TableInfo<Table_>["document"],
|
|
47
|
+
DocumentDecodeError
|
|
48
|
+
> =>
|
|
49
|
+
pipe(
|
|
50
|
+
self,
|
|
51
|
+
Schema.decodeUnknownEffect(table.Doc),
|
|
52
|
+
Effect.catchIf(Schema.isSchemaError, (schemaError) =>
|
|
53
|
+
Effect.fail(
|
|
54
|
+
new DocumentDecodeError({
|
|
55
|
+
tableName: table.tableName,
|
|
56
|
+
id: self._id,
|
|
57
|
+
parseError: schemaError.message,
|
|
58
|
+
}),
|
|
59
|
+
),
|
|
60
|
+
),
|
|
61
|
+
),
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
export const encode = Function.dual<
|
|
65
|
+
<Table_ extends Table.AnyWithProps>(
|
|
66
|
+
table: Table_,
|
|
67
|
+
) => (
|
|
68
|
+
self: Schema.Schema.Type<Table.Fields<Table_>>,
|
|
69
|
+
) => Effect.Effect<
|
|
70
|
+
Schema.Codec.Encoded<Table.Fields<Table_>>,
|
|
71
|
+
DocumentEncodeError
|
|
72
|
+
>,
|
|
73
|
+
<Table_ extends Table.AnyWithProps>(
|
|
74
|
+
self: Schema.Schema.Type<Table.Fields<Table_>>,
|
|
75
|
+
table: Table_,
|
|
76
|
+
) => Effect.Effect<
|
|
77
|
+
Schema.Codec.Encoded<Table.Fields<Table_>>,
|
|
78
|
+
DocumentEncodeError
|
|
79
|
+
>
|
|
80
|
+
>(
|
|
81
|
+
2,
|
|
82
|
+
<Table_ extends Table.AnyWithProps>(
|
|
83
|
+
self: Schema.Schema.Type<Table.Fields<Table_>>,
|
|
84
|
+
table: Table_,
|
|
85
|
+
): Effect.Effect<
|
|
86
|
+
Schema.Codec.Encoded<Table.Fields<Table_>>,
|
|
87
|
+
DocumentEncodeError
|
|
88
|
+
> =>
|
|
89
|
+
pipe(
|
|
90
|
+
self,
|
|
91
|
+
Schema.encodeEffect(table.Fields),
|
|
92
|
+
Effect.catchIf(Schema.isSchemaError, (schemaError) =>
|
|
93
|
+
Effect.fail(
|
|
94
|
+
new DocumentEncodeError({
|
|
95
|
+
tableName: table.tableName,
|
|
96
|
+
id: self._id,
|
|
97
|
+
parseError: schemaError.message,
|
|
98
|
+
}),
|
|
99
|
+
),
|
|
100
|
+
),
|
|
101
|
+
),
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
export class DocumentDecodeError extends Schema.TaggedError<DocumentDecodeError>()(
|
|
105
|
+
"DocumentDecodeError",
|
|
106
|
+
{
|
|
107
|
+
tableName: Schema.String,
|
|
108
|
+
id: Schema.String,
|
|
109
|
+
parseError: Schema.String,
|
|
110
|
+
},
|
|
111
|
+
) {
|
|
112
|
+
override get message(): string {
|
|
113
|
+
return documentErrorMessage({
|
|
114
|
+
id: this.id,
|
|
115
|
+
tableName: this.tableName,
|
|
116
|
+
message: `could not be decoded:\n\n${this.parseError}`,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export class DocumentEncodeError extends Schema.TaggedError<DocumentEncodeError>()(
|
|
122
|
+
"DocumentEncodeError",
|
|
123
|
+
{
|
|
124
|
+
tableName: Schema.String,
|
|
125
|
+
id: Schema.String,
|
|
126
|
+
parseError: Schema.String,
|
|
127
|
+
},
|
|
128
|
+
) {
|
|
129
|
+
override get message(): string {
|
|
130
|
+
return documentErrorMessage({
|
|
131
|
+
id: this.id,
|
|
132
|
+
tableName: this.tableName,
|
|
133
|
+
message: `could not be encoded:\n\n${this.parseError}`,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export const documentErrorMessage = ({
|
|
139
|
+
id,
|
|
140
|
+
tableName,
|
|
141
|
+
message,
|
|
142
|
+
}: {
|
|
143
|
+
id: string;
|
|
144
|
+
tableName: string;
|
|
145
|
+
message: string;
|
|
146
|
+
}) => `Document with ID '${id}' in table '${tableName}' ${message}`;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { QueryMeta } from "convex/server";
|
|
2
|
+
import * as Context from "effect/Context";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
import * as Layer from "effect/Layer";
|
|
5
|
+
|
|
6
|
+
export type { DeploymentMetadata, FunctionMetadata } from "convex/server";
|
|
7
|
+
|
|
8
|
+
const make = (
|
|
9
|
+
meta: Pick<QueryMeta, "getFunctionMetadata" | "getDeploymentMetadata">,
|
|
10
|
+
) => ({
|
|
11
|
+
getFunction: Effect.fn("ExecutionMetadata.getFunction")(() =>
|
|
12
|
+
Effect.promise(() => meta.getFunctionMetadata()),
|
|
13
|
+
),
|
|
14
|
+
getDeployment: Effect.fn("ExecutionMetadata.getDeployment")(() =>
|
|
15
|
+
Effect.promise(() => meta.getDeploymentMetadata()),
|
|
16
|
+
),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export class ExecutionMetadata extends Context.Service<
|
|
20
|
+
ExecutionMetadata,
|
|
21
|
+
ReturnType<typeof make>
|
|
22
|
+
>()("@confect/server/ExecutionMetadata") {}
|
|
23
|
+
|
|
24
|
+
export const layer = (
|
|
25
|
+
meta: Pick<QueryMeta, "getFunctionMetadata" | "getDeploymentMetadata">,
|
|
26
|
+
) => Layer.succeed(ExecutionMetadata, make(meta));
|