@confect/server 2.0.0 → 4.0.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.
- package/CHANGELOG.md +33 -0
- package/dist/ActionRunner.d.ts +2 -2
- package/dist/ActionRunner.d.ts.map +1 -1
- package/dist/ActionRunner.js +9 -7
- package/dist/ActionRunner.js.map +1 -1
- package/dist/BlobNotFoundError.d.ts +17 -0
- package/dist/BlobNotFoundError.d.ts.map +1 -0
- package/dist/BlobNotFoundError.js +14 -0
- package/dist/BlobNotFoundError.js.map +1 -0
- package/dist/CronJob.d.ts +22 -0
- package/dist/CronJob.d.ts.map +1 -0
- package/dist/CronJob.js +23 -0
- package/dist/CronJob.js.map +1 -0
- package/dist/CronJobs.d.ts +28 -0
- package/dist/CronJobs.d.ts.map +1 -0
- package/dist/CronJobs.js +75 -0
- package/dist/CronJobs.js.map +1 -0
- package/dist/DatabaseWriter.d.ts +4 -4
- package/dist/FunctionImpl.js +2 -2
- package/dist/FunctionImpl.js.map +1 -1
- package/dist/Handler.d.ts +22 -14
- package/dist/Handler.d.ts.map +1 -1
- package/dist/Handler.js.map +1 -1
- package/dist/HttpApi.d.ts +3 -1
- package/dist/HttpApi.d.ts.map +1 -1
- package/dist/HttpApi.js +3 -1
- package/dist/HttpApi.js.map +1 -1
- package/dist/MutationRunner.d.ts +2 -2
- package/dist/MutationRunner.d.ts.map +1 -1
- package/dist/MutationRunner.js +9 -7
- package/dist/MutationRunner.js.map +1 -1
- package/dist/OrderedQuery.d.ts +2 -2
- package/dist/OrderedQuery.d.ts.map +1 -1
- package/dist/OrderedQuery.js +3 -2
- package/dist/OrderedQuery.js.map +1 -1
- package/dist/QueryInitializer.d.ts +1 -1
- package/dist/QueryInitializer.d.ts.map +1 -1
- package/dist/QueryRunner.d.ts +2 -2
- package/dist/QueryRunner.d.ts.map +1 -1
- package/dist/QueryRunner.js +7 -5
- package/dist/QueryRunner.js.map +1 -1
- package/dist/RegisteredConvexFunction.d.ts +11 -10
- package/dist/RegisteredConvexFunction.d.ts.map +1 -1
- package/dist/RegisteredConvexFunction.js +23 -19
- package/dist/RegisteredConvexFunction.js.map +1 -1
- package/dist/RegisteredFunction.d.ts +20 -7
- package/dist/RegisteredFunction.d.ts.map +1 -1
- package/dist/RegisteredFunction.js +3 -1
- package/dist/RegisteredFunction.js.map +1 -1
- package/dist/RegisteredFunctions.d.ts +4 -4
- package/dist/RegisteredFunctions.d.ts.map +1 -1
- package/dist/RegisteredFunctions.js.map +1 -1
- package/dist/RegisteredNodeFunction.d.ts +3 -3
- package/dist/RegisteredNodeFunction.d.ts.map +1 -1
- package/dist/RegisteredNodeFunction.js +6 -5
- package/dist/RegisteredNodeFunction.js.map +1 -1
- package/dist/RegistryItem.d.ts +9 -9
- package/dist/RegistryItem.d.ts.map +1 -1
- package/dist/RegistryItem.js +2 -2
- package/dist/RegistryItem.js.map +1 -1
- package/dist/StorageActionWriter.d.ts +35 -0
- package/dist/StorageActionWriter.d.ts.map +1 -0
- package/dist/StorageActionWriter.js +20 -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 +17 -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 +20 -0
- package/dist/StorageWriter.js.map +1 -0
- package/dist/index.d.ts +8 -3
- package/dist/index.js +7 -2
- package/package.json +4 -4
- package/src/ActionRunner.ts +27 -13
- package/src/BlobNotFoundError.ts +12 -0
- package/src/CronJob.ts +45 -0
- package/src/CronJobs.ts +161 -0
- package/src/FunctionImpl.ts +3 -3
- package/src/Handler.ts +42 -19
- package/src/HttpApi.ts +3 -1
- package/src/MutationRunner.ts +27 -13
- package/src/OrderedQuery.ts +15 -6
- package/src/QueryRunner.ts +22 -8
- package/src/RegisteredConvexFunction.ts +54 -42
- package/src/RegisteredFunction.ts +89 -2
- package/src/RegisteredFunctions.ts +10 -11
- package/src/RegisteredNodeFunction.ts +23 -13
- package/src/RegistryItem.ts +9 -12
- package/src/StorageActionWriter.ts +28 -0
- package/src/StorageReader.ts +27 -0
- package/src/StorageWriter.ts +26 -0
- package/src/index.ts +7 -2
- package/dist/Storage.d.ts +0 -69
- package/dist/Storage.d.ts.map +0 -1
- package/dist/Storage.js +0 -46
- package/dist/Storage.js.map +0 -1
- package/src/Storage.ts +0 -87
package/src/CronJobs.ts
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { Ref } from "@confect/core";
|
|
2
|
+
import type {
|
|
3
|
+
CronJob as ConvexCronJob,
|
|
4
|
+
SchedulableFunctionReference,
|
|
5
|
+
} from "convex/server";
|
|
6
|
+
import { cronJobs as makeConvexCrons, type Crons } from "convex/server";
|
|
7
|
+
import {
|
|
8
|
+
Array,
|
|
9
|
+
Cron,
|
|
10
|
+
Duration,
|
|
11
|
+
Match,
|
|
12
|
+
Order,
|
|
13
|
+
pipe,
|
|
14
|
+
Predicate,
|
|
15
|
+
Record,
|
|
16
|
+
Schema,
|
|
17
|
+
} from "effect";
|
|
18
|
+
import type * as CronJob from "./CronJob";
|
|
19
|
+
|
|
20
|
+
export const TypeId = "@confect/server/CronJobs";
|
|
21
|
+
export type TypeId = typeof TypeId;
|
|
22
|
+
|
|
23
|
+
export interface CronJobs {
|
|
24
|
+
readonly [TypeId]: TypeId;
|
|
25
|
+
readonly cronJobs: Record<string, CronJob.CronJob>;
|
|
26
|
+
readonly convexCronJobs: Crons;
|
|
27
|
+
|
|
28
|
+
add(cron: CronJob.CronJob): CronJobs;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const isCronJobs = (u: unknown): u is CronJobs =>
|
|
32
|
+
Predicate.hasProperty(u, TypeId);
|
|
33
|
+
|
|
34
|
+
const Proto = {
|
|
35
|
+
[TypeId]: TypeId,
|
|
36
|
+
|
|
37
|
+
add(this: CronJobs, cronJob: CronJob.CronJob) {
|
|
38
|
+
const newConvexCrons = Object.assign(makeConvexCrons(), {
|
|
39
|
+
crons: { ...this.convexCronJobs.crons },
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const schedulableFunctionReference = Ref.getConvexFunctionName(
|
|
43
|
+
cronJob.ref,
|
|
44
|
+
) as unknown as SchedulableFunctionReference;
|
|
45
|
+
|
|
46
|
+
const functionSpec = Ref.getFunctionSpec(cronJob.ref);
|
|
47
|
+
const encodedArgs = Match.value(functionSpec.functionProvenance).pipe(
|
|
48
|
+
Match.tag("Confect", (confect) =>
|
|
49
|
+
Schema.encodeSync(confect.args)(cronJob.args),
|
|
50
|
+
),
|
|
51
|
+
Match.tag("Convex", () => cronJob.args),
|
|
52
|
+
Match.exhaustive,
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
Match.value(cronJob.schedule).pipe(
|
|
56
|
+
Match.when(Cron.isCron, (cron) => {
|
|
57
|
+
newConvexCrons.cron(
|
|
58
|
+
cronJob.identifier,
|
|
59
|
+
cronToConvexCronString(cron),
|
|
60
|
+
schedulableFunctionReference,
|
|
61
|
+
encodedArgs,
|
|
62
|
+
);
|
|
63
|
+
}),
|
|
64
|
+
Match.when(Duration.isDuration, (duration) => {
|
|
65
|
+
newConvexCrons.interval(
|
|
66
|
+
cronJob.identifier,
|
|
67
|
+
durationToConvexIntervalSchedule(duration),
|
|
68
|
+
schedulableFunctionReference,
|
|
69
|
+
encodedArgs,
|
|
70
|
+
);
|
|
71
|
+
}),
|
|
72
|
+
Match.exhaustive,
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
return makeProto(
|
|
76
|
+
Record.set(this.cronJobs, cronJob.identifier, cronJob),
|
|
77
|
+
newConvexCrons,
|
|
78
|
+
);
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const makeProto = (
|
|
83
|
+
cronJobs: Record<string, CronJob.CronJob>,
|
|
84
|
+
convexCronJobs: Crons,
|
|
85
|
+
): CronJobs =>
|
|
86
|
+
Object.assign(Object.create(Proto), {
|
|
87
|
+
cronJobs,
|
|
88
|
+
convexCronJobs,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
export const make = (): CronJobs => makeProto({}, makeConvexCrons());
|
|
92
|
+
|
|
93
|
+
/** @internal */
|
|
94
|
+
export const cronToConvexCronString = (cron: Cron.Cron): string => {
|
|
95
|
+
const hasNonDefaultSeconds = cron.seconds.size !== 1 || !cron.seconds.has(0);
|
|
96
|
+
if (hasNonDefaultSeconds) {
|
|
97
|
+
throw new Error(
|
|
98
|
+
"Convex cron expressions do not support a seconds field. " +
|
|
99
|
+
"The seconds field must be the default {0}. " +
|
|
100
|
+
"Sub-minute scheduling is supported only by interval schedules defined using a Duration.",
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return Array.join(
|
|
105
|
+
[
|
|
106
|
+
setToField(cron.minutes),
|
|
107
|
+
setToField(cron.hours),
|
|
108
|
+
setToField(cron.days),
|
|
109
|
+
setToField(cron.months),
|
|
110
|
+
setToField(cron.weekdays),
|
|
111
|
+
],
|
|
112
|
+
" ",
|
|
113
|
+
);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const setToField = (set: ReadonlySet<number>): string => {
|
|
117
|
+
if (set.size === 0) return "*";
|
|
118
|
+
return pipe(
|
|
119
|
+
set,
|
|
120
|
+
Array.sort(Order.number),
|
|
121
|
+
Array.map((n) => n.toString()),
|
|
122
|
+
Array.join(","),
|
|
123
|
+
);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
/** @internal */
|
|
127
|
+
export const durationToConvexIntervalSchedule = (
|
|
128
|
+
duration: Duration.Duration,
|
|
129
|
+
): IntervalSchedule => {
|
|
130
|
+
const millis = Duration.toMillis(duration);
|
|
131
|
+
if (millis <= 0) {
|
|
132
|
+
throw new Error("Interval must be a positive duration.");
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const oneHourInMillis = Duration.hours(1).pipe(Duration.toMillis);
|
|
136
|
+
const hours = millis / oneHourInMillis;
|
|
137
|
+
if (Number.isInteger(hours)) {
|
|
138
|
+
return { type: "interval", hours };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const oneMinuteInMillis = Duration.minutes(1).pipe(Duration.toMillis);
|
|
142
|
+
const minutes = millis / oneMinuteInMillis;
|
|
143
|
+
if (Number.isInteger(minutes)) {
|
|
144
|
+
return { type: "interval", minutes };
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const oneSecondInMillis = Duration.seconds(1).pipe(Duration.toMillis);
|
|
148
|
+
const seconds = millis / oneSecondInMillis;
|
|
149
|
+
if (Number.isInteger(seconds)) {
|
|
150
|
+
return { type: "interval", seconds };
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
throw new Error(
|
|
154
|
+
"Interval must be a whole number of seconds, minutes, or hours.",
|
|
155
|
+
);
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
type IntervalSchedule = Extract<
|
|
159
|
+
ConvexCronJob["schedule"],
|
|
160
|
+
{ type: "interval" }
|
|
161
|
+
>;
|
package/src/FunctionImpl.ts
CHANGED
|
@@ -56,7 +56,7 @@ export const make = <
|
|
|
56
56
|
currentGroup.groups[groupPathPart],
|
|
57
57
|
);
|
|
58
58
|
|
|
59
|
-
const
|
|
59
|
+
const functionSpec = group_.functions[functionName]!;
|
|
60
60
|
|
|
61
61
|
return Layer.effect(
|
|
62
62
|
FunctionImpl<GroupPath_, FunctionName>({
|
|
@@ -71,8 +71,8 @@ export const make = <
|
|
|
71
71
|
registryItems,
|
|
72
72
|
[...groupPathParts, functionName],
|
|
73
73
|
RegistryItem.make({
|
|
74
|
-
|
|
75
|
-
handler
|
|
74
|
+
functionSpec,
|
|
75
|
+
handler,
|
|
76
76
|
}),
|
|
77
77
|
),
|
|
78
78
|
);
|
package/src/Handler.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { FunctionSpec, RuntimeAndFunctionType } from "@confect/core";
|
|
2
|
+
import type * as FunctionProvenance from "@confect/core/FunctionProvenance";
|
|
2
3
|
import type { NodeContext } from "@effect/platform-node";
|
|
3
4
|
import type { Effect } from "effect";
|
|
4
5
|
import type * as ActionCtx from "./ActionCtx";
|
|
@@ -12,38 +13,59 @@ import type * as MutationCtx from "./MutationCtx";
|
|
|
12
13
|
import type * as MutationRunner from "./MutationRunner";
|
|
13
14
|
import type * as QueryCtx from "./QueryCtx";
|
|
14
15
|
import type * as QueryRunner from "./QueryRunner";
|
|
16
|
+
import type * as RegisteredFunction from "./RegisteredFunction";
|
|
15
17
|
import type * as Scheduler from "./Scheduler";
|
|
16
|
-
import type {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
StorageWriter,
|
|
20
|
-
} from "./Storage";
|
|
18
|
+
import type { StorageActionWriter } from "./StorageActionWriter";
|
|
19
|
+
import type { StorageReader } from "./StorageReader";
|
|
20
|
+
import type { StorageWriter } from "./StorageWriter";
|
|
21
21
|
import type * as VectorSearch from "./VectorSearch";
|
|
22
22
|
|
|
23
23
|
export type Handler<
|
|
24
24
|
DatabaseSchema_ extends DatabaseSchema.AnyWithProps,
|
|
25
25
|
FunctionSpec_ extends FunctionSpec.AnyWithProps,
|
|
26
|
+
> =
|
|
27
|
+
FunctionSpec_ extends FunctionSpec.WithFunctionProvenance<
|
|
28
|
+
FunctionSpec_,
|
|
29
|
+
FunctionProvenance.AnyConvex
|
|
30
|
+
>
|
|
31
|
+
? ConvexProvenanceHandler<FunctionSpec_>
|
|
32
|
+
: FunctionSpec_ extends FunctionSpec.WithFunctionProvenance<
|
|
33
|
+
FunctionSpec_,
|
|
34
|
+
FunctionProvenance.AnyConfect
|
|
35
|
+
>
|
|
36
|
+
? ConfectProvenanceHandler<DatabaseSchema_, FunctionSpec_>
|
|
37
|
+
: never;
|
|
38
|
+
|
|
39
|
+
type ConvexProvenanceHandler<
|
|
40
|
+
FunctionSpec_ extends
|
|
41
|
+
FunctionSpec.AnyWithPropsWithFunctionProvenance<FunctionProvenance.AnyConvex>,
|
|
42
|
+
> = RegisteredFunction.ConvexRegisteredFunction<FunctionSpec_>;
|
|
43
|
+
|
|
44
|
+
type ConfectProvenanceHandler<
|
|
45
|
+
DatabaseSchema_ extends DatabaseSchema.AnyWithProps,
|
|
46
|
+
FunctionSpec_ extends
|
|
47
|
+
FunctionSpec.AnyWithPropsWithFunctionProvenance<FunctionProvenance.AnyConfect>,
|
|
26
48
|
> =
|
|
27
49
|
FunctionSpec_ extends FunctionSpec.WithFunctionType<FunctionSpec_, "query">
|
|
28
|
-
?
|
|
50
|
+
? ConfectProvenanceQuery<DatabaseSchema_, FunctionSpec_>
|
|
29
51
|
: FunctionSpec_ extends FunctionSpec.WithFunctionType<
|
|
30
52
|
FunctionSpec_,
|
|
31
53
|
"mutation"
|
|
32
54
|
>
|
|
33
|
-
?
|
|
55
|
+
? ConfectProvenanceMutation<DatabaseSchema_, FunctionSpec_>
|
|
34
56
|
: FunctionSpec_ extends FunctionSpec.WithRuntimeAndFunctionType<
|
|
35
57
|
FunctionSpec_,
|
|
36
58
|
RuntimeAndFunctionType.ConvexAction
|
|
37
59
|
>
|
|
38
|
-
?
|
|
60
|
+
? ConvexRuntimeAction<DatabaseSchema_, FunctionSpec_>
|
|
39
61
|
: FunctionSpec_ extends FunctionSpec.WithRuntimeAndFunctionType<
|
|
40
62
|
FunctionSpec_,
|
|
41
63
|
RuntimeAndFunctionType.NodeAction
|
|
42
64
|
>
|
|
43
|
-
?
|
|
65
|
+
? NodeRuntimeAction<DatabaseSchema_, FunctionSpec_>
|
|
44
66
|
: never;
|
|
45
67
|
|
|
46
|
-
export type
|
|
68
|
+
export type ConfectProvenanceQuery<
|
|
47
69
|
DatabaseSchema_ extends DatabaseSchema.AnyWithProps,
|
|
48
70
|
FunctionSpec_ extends
|
|
49
71
|
FunctionSpec.AnyWithPropsWithFunctionType<RuntimeAndFunctionType.AnyQuery>,
|
|
@@ -56,7 +78,7 @@ export type Query<
|
|
|
56
78
|
| QueryCtx.QueryCtx<DataModel.ToConvex<DataModel.FromSchema<DatabaseSchema_>>>
|
|
57
79
|
>;
|
|
58
80
|
|
|
59
|
-
export type
|
|
81
|
+
export type ConfectProvenanceMutation<
|
|
60
82
|
DatabaseSchema_ extends DatabaseSchema.AnyWithProps,
|
|
61
83
|
FunctionSpec_ extends
|
|
62
84
|
FunctionSpec.AnyWithPropsWithFunctionType<RuntimeAndFunctionType.AnyMutation>,
|
|
@@ -89,13 +111,13 @@ type ActionServices<DatabaseSchema_ extends DatabaseSchema.AnyWithProps> =
|
|
|
89
111
|
DataModel.ToConvex<DataModel.FromSchema<DatabaseSchema_>>
|
|
90
112
|
>;
|
|
91
113
|
|
|
92
|
-
export type
|
|
114
|
+
export type ConvexRuntimeAction<
|
|
93
115
|
DatabaseSchema_ extends DatabaseSchema.AnyWithProps,
|
|
94
116
|
FunctionSpec_ extends
|
|
95
117
|
FunctionSpec.AnyWithPropsWithFunctionType<RuntimeAndFunctionType.AnyAction>,
|
|
96
118
|
> = Base<FunctionSpec_, ActionServices<DatabaseSchema_>>;
|
|
97
119
|
|
|
98
|
-
export type
|
|
120
|
+
export type NodeRuntimeAction<
|
|
99
121
|
DatabaseSchema_ extends DatabaseSchema.AnyWithProps,
|
|
100
122
|
FunctionSpec_ extends
|
|
101
123
|
FunctionSpec.AnyWithPropsWithFunctionType<RuntimeAndFunctionType.NodeAction>,
|
|
@@ -105,13 +127,14 @@ export type NodeAction<
|
|
|
105
127
|
>;
|
|
106
128
|
|
|
107
129
|
type Base<FunctionSpec_ extends FunctionSpec.AnyWithProps, R> = (
|
|
108
|
-
args: FunctionSpec.Args<FunctionSpec_
|
|
109
|
-
) => Effect.Effect<FunctionSpec.Returns<FunctionSpec_
|
|
130
|
+
args: FunctionSpec.Args<FunctionSpec_>,
|
|
131
|
+
) => Effect.Effect<FunctionSpec.Returns<FunctionSpec_>, never, R>;
|
|
110
132
|
|
|
111
|
-
export type
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
133
|
+
export type Any = AnyConfectProvenance | AnyConvexProvenance;
|
|
134
|
+
|
|
135
|
+
export type AnyConfectProvenance = Base<FunctionSpec.AnyConfect, any>;
|
|
136
|
+
|
|
137
|
+
export type AnyConvexProvenance = RegisteredFunction.Any;
|
|
115
138
|
|
|
116
139
|
export type WithName<
|
|
117
140
|
DatabaseSchema_ extends DatabaseSchema.AnyWithProps,
|
package/src/HttpApi.ts
CHANGED
|
@@ -23,7 +23,9 @@ import * as ConvexConfigProvider from "./ConvexConfigProvider";
|
|
|
23
23
|
import * as MutationRunner from "./MutationRunner";
|
|
24
24
|
import * as QueryRunner from "./QueryRunner";
|
|
25
25
|
import * as Scheduler from "./Scheduler";
|
|
26
|
-
import { StorageActionWriter
|
|
26
|
+
import { StorageActionWriter } from "./StorageActionWriter";
|
|
27
|
+
import { StorageReader } from "./StorageReader";
|
|
28
|
+
import { StorageWriter } from "./StorageWriter";
|
|
27
29
|
|
|
28
30
|
type Middleware = (
|
|
29
31
|
httpApp: HttpApp.Default,
|
package/src/MutationRunner.ts
CHANGED
|
@@ -1,32 +1,46 @@
|
|
|
1
1
|
import * as Ref from "@confect/core/Ref";
|
|
2
2
|
import { type GenericMutationCtx } from "convex/server";
|
|
3
3
|
import type { ParseResult } from "effect";
|
|
4
|
-
import { Context, Effect, Layer, Schema } from "effect";
|
|
4
|
+
import { Context, Effect, Layer, Match, Schema } from "effect";
|
|
5
5
|
|
|
6
|
-
const
|
|
6
|
+
const make =
|
|
7
7
|
(runMutation: GenericMutationCtx<any>["runMutation"]) =>
|
|
8
8
|
<Mutation extends Ref.AnyMutation>(
|
|
9
9
|
mutation: Mutation,
|
|
10
|
-
args: Ref.Args<Mutation
|
|
11
|
-
): Effect.Effect<Ref.Returns<Mutation
|
|
10
|
+
args: Ref.Args<Mutation>,
|
|
11
|
+
): Effect.Effect<Ref.Returns<Mutation>, ParseResult.ParseError> =>
|
|
12
12
|
Effect.gen(function* () {
|
|
13
|
-
const
|
|
13
|
+
const functionSpec = Ref.getFunctionSpec(mutation);
|
|
14
14
|
const functionName = Ref.getConvexFunctionName(mutation);
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
return yield* Match.value(functionSpec.functionProvenance).pipe(
|
|
17
|
+
Match.tag("Confect", (confectFunctionSpec) =>
|
|
18
|
+
Effect.gen(function* () {
|
|
19
|
+
const encodedArgs = yield* Schema.encode(confectFunctionSpec.args)(
|
|
20
|
+
args,
|
|
21
|
+
);
|
|
22
|
+
const encodedReturns = yield* Effect.promise(() =>
|
|
23
|
+
runMutation(functionName as any, encodedArgs),
|
|
24
|
+
);
|
|
25
|
+
return yield* Schema.decode(confectFunctionSpec.returns)(
|
|
26
|
+
encodedReturns,
|
|
27
|
+
);
|
|
28
|
+
}),
|
|
29
|
+
),
|
|
30
|
+
Match.tag("Convex", () =>
|
|
31
|
+
Effect.promise(() => runMutation(functionName as any, args as any)),
|
|
32
|
+
),
|
|
33
|
+
Match.exhaustive,
|
|
19
34
|
);
|
|
20
|
-
return yield* Schema.decode(function_.returns)(encodedReturns);
|
|
21
35
|
});
|
|
22
36
|
|
|
23
|
-
export const MutationRunner = Context.GenericTag<
|
|
24
|
-
|
|
25
|
-
|
|
37
|
+
export const MutationRunner = Context.GenericTag<ReturnType<typeof make>>(
|
|
38
|
+
"@confect/server/MutationRunner",
|
|
39
|
+
);
|
|
26
40
|
export type MutationRunner = typeof MutationRunner.Identifier;
|
|
27
41
|
|
|
28
42
|
export const layer = (runMutation: GenericMutationCtx<any>["runMutation"]) =>
|
|
29
|
-
Layer.succeed(MutationRunner,
|
|
43
|
+
Layer.succeed(MutationRunner, make(runMutation));
|
|
30
44
|
|
|
31
45
|
export class MutationRollback extends Schema.TaggedError<MutationRollback>()(
|
|
32
46
|
"MutationRollback",
|
package/src/OrderedQuery.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
ExpressionOrValue,
|
|
3
|
+
FilterBuilder,
|
|
2
4
|
OrderedQuery as ConvexOrderedQuery,
|
|
3
5
|
PaginationResult,
|
|
4
6
|
} from "convex/server";
|
|
@@ -28,10 +30,15 @@ export type OrderedQuery<
|
|
|
28
30
|
TableInfo_["document"],
|
|
29
31
|
Document.DocumentDecodeError
|
|
30
32
|
>;
|
|
31
|
-
readonly paginate: (
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
readonly paginate: (
|
|
34
|
+
options: {
|
|
35
|
+
cursor: string | null;
|
|
36
|
+
numItems: number;
|
|
37
|
+
},
|
|
38
|
+
filter?: (
|
|
39
|
+
q: FilterBuilder<TableInfo.ConvexTableInfo<TableInfo_>>,
|
|
40
|
+
) => ExpressionOrValue<boolean>,
|
|
41
|
+
) => Effect.Effect<
|
|
35
42
|
PaginationResult<TableInfo_["document"]>,
|
|
36
43
|
Document.DocumentDecodeError
|
|
37
44
|
>;
|
|
@@ -73,10 +80,12 @@ export const make = <
|
|
|
73
80
|
const collect: OrderedQueryFunction<"collect"> = () =>
|
|
74
81
|
pipe(stream(), Stream.runCollect, Effect.map(Chunk.toReadonlyArray));
|
|
75
82
|
|
|
76
|
-
const paginate: OrderedQueryFunction<"paginate"> = (options) =>
|
|
83
|
+
const paginate: OrderedQueryFunction<"paginate"> = (options, filter) =>
|
|
77
84
|
Effect.gen(function* () {
|
|
85
|
+
const filteredQuery = filter !== undefined ? query.filter(filter) : query;
|
|
86
|
+
|
|
78
87
|
const paginationResult = yield* Effect.promise(() =>
|
|
79
|
-
|
|
88
|
+
filteredQuery.paginate(options),
|
|
80
89
|
);
|
|
81
90
|
|
|
82
91
|
const parsedPage = yield* Effect.forEach(
|
package/src/QueryRunner.ts
CHANGED
|
@@ -1,23 +1,37 @@
|
|
|
1
1
|
import * as Ref from "@confect/core/Ref";
|
|
2
2
|
import { type GenericQueryCtx } from "convex/server";
|
|
3
3
|
import type { ParseResult } from "effect";
|
|
4
|
-
import { Context, Effect, Layer, Schema } from "effect";
|
|
4
|
+
import { Context, Effect, Layer, Match, Schema } from "effect";
|
|
5
5
|
|
|
6
6
|
const make =
|
|
7
7
|
(runQuery: GenericQueryCtx<any>["runQuery"]) =>
|
|
8
8
|
<Query extends Ref.AnyQuery>(
|
|
9
9
|
query: Query,
|
|
10
|
-
args: Ref.Args<Query
|
|
11
|
-
): Effect.Effect<Ref.Returns<Query
|
|
10
|
+
args: Ref.Args<Query>,
|
|
11
|
+
): Effect.Effect<Ref.Returns<Query>, ParseResult.ParseError> =>
|
|
12
12
|
Effect.gen(function* () {
|
|
13
|
-
const
|
|
13
|
+
const functionSpec = Ref.getFunctionSpec(query);
|
|
14
14
|
const functionName = Ref.getConvexFunctionName(query);
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
return yield* Match.value(functionSpec.functionProvenance).pipe(
|
|
17
|
+
Match.tag("Confect", (confectFunctionSpec) =>
|
|
18
|
+
Effect.gen(function* () {
|
|
19
|
+
const encodedArgs = yield* Schema.encode(confectFunctionSpec.args)(
|
|
20
|
+
args,
|
|
21
|
+
);
|
|
22
|
+
const encodedReturns = yield* Effect.promise(() =>
|
|
23
|
+
runQuery(functionName as any, encodedArgs),
|
|
24
|
+
);
|
|
25
|
+
return yield* Schema.decode(confectFunctionSpec.returns)(
|
|
26
|
+
encodedReturns,
|
|
27
|
+
);
|
|
28
|
+
}),
|
|
29
|
+
),
|
|
30
|
+
Match.tag("Convex", () =>
|
|
31
|
+
Effect.promise(() => runQuery(functionName as any, args as any)),
|
|
32
|
+
),
|
|
33
|
+
Match.exhaustive,
|
|
19
34
|
);
|
|
20
|
-
return yield* Schema.decode(function_.returns)(encodedReturns);
|
|
21
35
|
});
|
|
22
36
|
|
|
23
37
|
export const QueryRunner = Context.GenericTag<ReturnType<typeof make>>(
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type * as FunctionSpec from "@confect/core/FunctionSpec";
|
|
1
2
|
import {
|
|
2
3
|
actionGeneric,
|
|
3
4
|
type DefaultFunctionArgs,
|
|
@@ -12,10 +13,12 @@ import {
|
|
|
12
13
|
import { Effect, Layer, Match, pipe, Schema } from "effect";
|
|
13
14
|
import type * as Api from "./Api";
|
|
14
15
|
import * as Auth from "./Auth";
|
|
16
|
+
import * as ConvexConfigProvider from "./ConvexConfigProvider";
|
|
15
17
|
import * as DatabaseReader from "./DatabaseReader";
|
|
16
18
|
import type * as DatabaseSchema from "./DatabaseSchema";
|
|
17
19
|
import * as DatabaseWriter from "./DatabaseWriter";
|
|
18
20
|
import type * as DataModel from "./DataModel";
|
|
21
|
+
import type * as Handler from "./Handler";
|
|
19
22
|
import * as MutationCtx from "./MutationCtx";
|
|
20
23
|
import * as MutationRunner from "./MutationRunner";
|
|
21
24
|
import * as QueryCtx from "./QueryCtx";
|
|
@@ -24,57 +27,66 @@ import * as RegisteredFunction from "./RegisteredFunction";
|
|
|
24
27
|
import type * as RegistryItem from "./RegistryItem";
|
|
25
28
|
import * as Scheduler from "./Scheduler";
|
|
26
29
|
import * as SchemaToValidator from "./SchemaToValidator";
|
|
27
|
-
import
|
|
28
|
-
import {
|
|
30
|
+
import { StorageReader } from "./StorageReader";
|
|
31
|
+
import { StorageWriter } from "./StorageWriter";
|
|
29
32
|
|
|
30
33
|
export const make = <Api_ extends Api.AnyWithPropsWithRuntime<"Convex">>(
|
|
31
34
|
api: Api_,
|
|
32
|
-
{
|
|
33
|
-
): RegisteredFunction.
|
|
34
|
-
Match.value(
|
|
35
|
-
Match.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
Match.exhaustive,
|
|
40
|
-
);
|
|
35
|
+
{ functionSpec, handler }: RegistryItem.AnyWithProps,
|
|
36
|
+
): RegisteredFunction.Any =>
|
|
37
|
+
Match.value(functionSpec.functionProvenance).pipe(
|
|
38
|
+
Match.tag("Convex", () => handler as RegisteredFunction.Any),
|
|
39
|
+
Match.tag("Confect", () => {
|
|
40
|
+
const { functionVisibility, functionProvenance } =
|
|
41
|
+
functionSpec as FunctionSpec.AnyConfect;
|
|
41
42
|
|
|
42
|
-
return
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
return Match.value(functionSpec.runtimeAndFunctionType.functionType).pipe(
|
|
44
|
+
Match.when("query", () => {
|
|
45
|
+
const genericFunction = Match.value(functionVisibility).pipe(
|
|
46
|
+
Match.when("public", () => queryGeneric),
|
|
47
|
+
Match.when("internal", () => internalQueryGeneric),
|
|
48
|
+
Match.exhaustive,
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
return genericFunction(
|
|
52
|
+
queryFunction(api.databaseSchema, {
|
|
53
|
+
args: functionProvenance.args,
|
|
54
|
+
returns: functionProvenance.returns,
|
|
55
|
+
handler: handler as Handler.AnyConfectProvenance,
|
|
56
|
+
}),
|
|
57
|
+
);
|
|
47
58
|
}),
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
Match.exhaustive,
|
|
55
|
-
);
|
|
59
|
+
Match.when("mutation", () => {
|
|
60
|
+
const genericFunction = Match.value(functionVisibility).pipe(
|
|
61
|
+
Match.when("public", () => mutationGeneric),
|
|
62
|
+
Match.when("internal", () => internalMutationGeneric),
|
|
63
|
+
Match.exhaustive,
|
|
64
|
+
);
|
|
56
65
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
66
|
+
return genericFunction(
|
|
67
|
+
mutationFunction(api.databaseSchema, {
|
|
68
|
+
args: functionProvenance.args,
|
|
69
|
+
returns: functionProvenance.returns,
|
|
70
|
+
handler: handler as Handler.AnyConfectProvenance,
|
|
71
|
+
}),
|
|
72
|
+
);
|
|
62
73
|
}),
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
Match.exhaustive,
|
|
70
|
-
);
|
|
74
|
+
Match.when("action", () => {
|
|
75
|
+
const genericFunction = Match.value(functionVisibility).pipe(
|
|
76
|
+
Match.when("public", () => actionGeneric),
|
|
77
|
+
Match.when("internal", () => internalActionGeneric),
|
|
78
|
+
Match.exhaustive,
|
|
79
|
+
);
|
|
71
80
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
81
|
+
return genericFunction(
|
|
82
|
+
convexActionFunction(api.databaseSchema, {
|
|
83
|
+
args: functionProvenance.args,
|
|
84
|
+
returns: functionProvenance.returns,
|
|
85
|
+
handler: handler as Handler.AnyConfectProvenance,
|
|
86
|
+
}),
|
|
87
|
+
);
|
|
77
88
|
}),
|
|
89
|
+
Match.exhaustive,
|
|
78
90
|
);
|
|
79
91
|
}),
|
|
80
92
|
Match.exhaustive,
|