@confect/server 3.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.
Files changed (67) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/BlobNotFoundError.d.ts +17 -0
  3. package/dist/BlobNotFoundError.d.ts.map +1 -0
  4. package/dist/BlobNotFoundError.js +14 -0
  5. package/dist/BlobNotFoundError.js.map +1 -0
  6. package/dist/CronJob.d.ts +22 -0
  7. package/dist/CronJob.d.ts.map +1 -0
  8. package/dist/CronJob.js +23 -0
  9. package/dist/CronJob.js.map +1 -0
  10. package/dist/CronJobs.d.ts +28 -0
  11. package/dist/CronJobs.d.ts.map +1 -0
  12. package/dist/CronJobs.js +75 -0
  13. package/dist/CronJobs.js.map +1 -0
  14. package/dist/DatabaseWriter.d.ts +4 -4
  15. package/dist/Handler.d.ts +4 -2
  16. package/dist/Handler.d.ts.map +1 -1
  17. package/dist/Handler.js.map +1 -1
  18. package/dist/HttpApi.d.ts +3 -1
  19. package/dist/HttpApi.d.ts.map +1 -1
  20. package/dist/HttpApi.js +3 -1
  21. package/dist/HttpApi.js.map +1 -1
  22. package/dist/OrderedQuery.d.ts +2 -2
  23. package/dist/OrderedQuery.d.ts.map +1 -1
  24. package/dist/OrderedQuery.js +3 -2
  25. package/dist/OrderedQuery.js.map +1 -1
  26. package/dist/QueryInitializer.d.ts +1 -1
  27. package/dist/QueryInitializer.d.ts.map +1 -1
  28. package/dist/RegisteredConvexFunction.d.ts +8 -7
  29. package/dist/RegisteredConvexFunction.d.ts.map +1 -1
  30. package/dist/RegisteredConvexFunction.js +2 -1
  31. package/dist/RegisteredConvexFunction.js.map +1 -1
  32. package/dist/RegisteredFunction.d.ts +7 -5
  33. package/dist/RegisteredFunction.d.ts.map +1 -1
  34. package/dist/RegisteredFunction.js +3 -1
  35. package/dist/RegisteredFunction.js.map +1 -1
  36. package/dist/StorageActionWriter.d.ts +35 -0
  37. package/dist/StorageActionWriter.d.ts.map +1 -0
  38. package/dist/StorageActionWriter.js +20 -0
  39. package/dist/StorageActionWriter.js.map +1 -0
  40. package/dist/StorageReader.d.ts +26 -0
  41. package/dist/StorageReader.d.ts.map +1 -0
  42. package/dist/StorageReader.js +17 -0
  43. package/dist/StorageReader.js.map +1 -0
  44. package/dist/StorageWriter.d.ts +29 -0
  45. package/dist/StorageWriter.d.ts.map +1 -0
  46. package/dist/StorageWriter.js +20 -0
  47. package/dist/StorageWriter.js.map +1 -0
  48. package/dist/index.d.ts +7 -2
  49. package/dist/index.js +7 -2
  50. package/package.json +4 -4
  51. package/src/BlobNotFoundError.ts +12 -0
  52. package/src/CronJob.ts +45 -0
  53. package/src/CronJobs.ts +161 -0
  54. package/src/Handler.ts +3 -5
  55. package/src/HttpApi.ts +3 -1
  56. package/src/OrderedQuery.ts +15 -6
  57. package/src/RegisteredConvexFunction.ts +2 -1
  58. package/src/RegisteredFunction.ts +3 -1
  59. package/src/StorageActionWriter.ts +28 -0
  60. package/src/StorageReader.ts +27 -0
  61. package/src/StorageWriter.ts +26 -0
  62. package/src/index.ts +6 -1
  63. package/dist/Storage.d.ts +0 -69
  64. package/dist/Storage.d.ts.map +0 -1
  65. package/dist/Storage.js +0 -46
  66. package/dist/Storage.js.map +0 -1
  67. package/src/Storage.ts +0 -87
@@ -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/Handler.ts CHANGED
@@ -15,11 +15,9 @@ import type * as QueryCtx from "./QueryCtx";
15
15
  import type * as QueryRunner from "./QueryRunner";
16
16
  import type * as RegisteredFunction from "./RegisteredFunction";
17
17
  import type * as Scheduler from "./Scheduler";
18
- import type {
19
- StorageActionWriter,
20
- StorageReader,
21
- StorageWriter,
22
- } from "./Storage";
18
+ import type { StorageActionWriter } from "./StorageActionWriter";
19
+ import type { StorageReader } from "./StorageReader";
20
+ import type { StorageWriter } from "./StorageWriter";
23
21
  import type * as VectorSearch from "./VectorSearch";
24
22
 
25
23
  export type Handler<
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, StorageReader, StorageWriter } from "./Storage";
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,
@@ -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: (options: {
32
- cursor: string | null;
33
- numItems: number;
34
- }) => Effect.Effect<
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
- query.paginate(options),
88
+ filteredQuery.paginate(options),
80
89
  );
81
90
 
82
91
  const parsedPage = yield* Effect.forEach(
@@ -27,7 +27,8 @@ import * as RegisteredFunction from "./RegisteredFunction";
27
27
  import type * as RegistryItem from "./RegistryItem";
28
28
  import * as Scheduler from "./Scheduler";
29
29
  import * as SchemaToValidator from "./SchemaToValidator";
30
- import { StorageReader, StorageWriter } from "./Storage";
30
+ import { StorageReader } from "./StorageReader";
31
+ import { StorageWriter } from "./StorageWriter";
31
32
 
32
33
  export const make = <Api_ extends Api.AnyWithPropsWithRuntime<"Convex">>(
33
34
  api: Api_,
@@ -18,7 +18,9 @@ import * as MutationRunner from "./MutationRunner";
18
18
  import * as QueryRunner from "./QueryRunner";
19
19
  import * as Scheduler from "./Scheduler";
20
20
  import * as SchemaToValidator from "./SchemaToValidator";
21
- import { StorageActionWriter, StorageReader, StorageWriter } from "./Storage";
21
+ import { StorageActionWriter } from "./StorageActionWriter";
22
+ import { StorageReader } from "./StorageReader";
23
+ import { StorageWriter } from "./StorageWriter";
22
24
  import * as VectorSearch from "./VectorSearch";
23
25
 
24
26
  export type Any =
@@ -0,0 +1,28 @@
1
+ import type { StorageActionWriter as ConvexStorageActionWriter } from "convex/server";
2
+ import type { GenericId } from "convex/values";
3
+ import { Effect, flow, Layer, Option } from "effect";
4
+ import { BlobNotFoundError } from "./BlobNotFoundError";
5
+
6
+ const make = (storageActionWriter: ConvexStorageActionWriter) => ({
7
+ get: (storageId: GenericId<"_storage">) =>
8
+ Effect.promise(() => storageActionWriter.get(storageId)).pipe(
9
+ Effect.andThen(
10
+ flow(
11
+ Option.fromNullable,
12
+ Option.match({
13
+ onNone: () => Effect.fail(new BlobNotFoundError({ id: storageId })),
14
+ onSome: Effect.succeed,
15
+ }),
16
+ ),
17
+ ),
18
+ ),
19
+ store: (blob: Blob, options?: { sha256?: string }) =>
20
+ Effect.promise(() => storageActionWriter.store(blob, options)),
21
+ });
22
+
23
+ export class StorageActionWriter extends Effect.Tag(
24
+ "@confect/server/StorageActionWriter",
25
+ )<StorageActionWriter, ReturnType<typeof make>>() {
26
+ static readonly layer = (storageActionWriter: ConvexStorageActionWriter) =>
27
+ Layer.succeed(this, make(storageActionWriter));
28
+ }
@@ -0,0 +1,27 @@
1
+ import type { StorageReader as ConvexStorageReader } from "convex/server";
2
+ import type { GenericId } from "convex/values";
3
+ import { Effect, flow, Layer, Option, pipe, Schema } from "effect";
4
+ import { BlobNotFoundError } from "./BlobNotFoundError";
5
+
6
+ const make = (storageReader: ConvexStorageReader) => ({
7
+ getUrl: (storageId: GenericId<"_storage">) =>
8
+ Effect.promise(() => storageReader.getUrl(storageId)).pipe(
9
+ Effect.andThen(
10
+ flow(
11
+ Option.fromNullable,
12
+ Option.match({
13
+ onNone: () => Effect.fail(new BlobNotFoundError({ id: storageId })),
14
+ onSome: (doc) => pipe(doc, Schema.decode(Schema.URL), Effect.orDie),
15
+ }),
16
+ ),
17
+ ),
18
+ ),
19
+ });
20
+
21
+ export class StorageReader extends Effect.Tag("@confect/server/StorageReader")<
22
+ StorageReader,
23
+ ReturnType<typeof make>
24
+ >() {
25
+ static readonly layer = (storageReader: ConvexStorageReader) =>
26
+ Layer.succeed(this, make(storageReader));
27
+ }
@@ -0,0 +1,26 @@
1
+ import type { StorageWriter as ConvexStorageWriter } from "convex/server";
2
+ import type { GenericId } from "convex/values";
3
+ import { Effect, Layer, pipe, Schema } from "effect";
4
+ import { BlobNotFoundError } from "./BlobNotFoundError";
5
+
6
+ const make = (storageWriter: ConvexStorageWriter) => ({
7
+ generateUploadUrl: () =>
8
+ Effect.promise(() => storageWriter.generateUploadUrl()).pipe(
9
+ Effect.andThen((url) =>
10
+ pipe(url, Schema.decode(Schema.URL), Effect.orDie),
11
+ ),
12
+ ),
13
+ delete: (storageId: GenericId<"_storage">) =>
14
+ Effect.tryPromise({
15
+ try: () => storageWriter.delete(storageId),
16
+ catch: () => new BlobNotFoundError({ id: storageId }),
17
+ }),
18
+ });
19
+
20
+ export class StorageWriter extends Effect.Tag("@confect/server/StorageWriter")<
21
+ StorageWriter,
22
+ ReturnType<typeof make>
23
+ >() {
24
+ static readonly layer = (storageWriter: ConvexStorageWriter) =>
25
+ Layer.succeed(this, make(storageWriter));
26
+ }
package/src/index.ts CHANGED
@@ -2,7 +2,10 @@ export * as ActionCtx from "./ActionCtx";
2
2
  export * as ActionRunner from "./ActionRunner";
3
3
  export * as Api from "./Api";
4
4
  export * as Auth from "./Auth";
5
+ export * as BlobNotFoundError from "./BlobNotFoundError";
5
6
  export * as ConvexConfigProvider from "./ConvexConfigProvider";
7
+ export * as CronJob from "./CronJob";
8
+ export * as CronJobs from "./CronJobs";
6
9
  export * as DatabaseReader from "./DatabaseReader";
7
10
  export * as DatabaseSchema from "./DatabaseSchema";
8
11
  export * as DatabaseWriter from "./DatabaseWriter";
@@ -26,7 +29,9 @@ export * as Registry from "./Registry";
26
29
  export * as RegistryItem from "./RegistryItem";
27
30
  export * as Scheduler from "./Scheduler";
28
31
  export * as SchemaToValidator from "./SchemaToValidator";
29
- export * as Storage from "./Storage";
32
+ export * as StorageActionWriter from "./StorageActionWriter";
33
+ export * as StorageReader from "./StorageReader";
34
+ export * as StorageWriter from "./StorageWriter";
30
35
  export * as Table from "./Table";
31
36
  export * as TableInfo from "./TableInfo";
32
37
  export * as VectorSearch from "./VectorSearch";
package/dist/Storage.d.ts DELETED
@@ -1,69 +0,0 @@
1
- import { Effect, Layer, Schema } from "effect";
2
- import { StorageActionWriter as StorageActionWriter$1, StorageReader as StorageReader$1, StorageWriter as StorageWriter$1 } from "convex/server";
3
- import { GenericId } from "convex/values";
4
- import * as effect_Context0 from "effect/Context";
5
- import * as effect_Cause0 from "effect/Cause";
6
-
7
- //#region src/Storage.d.ts
8
- declare namespace Storage_d_exports {
9
- export { BlobNotFoundError, StorageActionWriter, StorageReader, StorageWriter };
10
- }
11
- declare const StorageReader_base: effect_Context0.TagClass<StorageReader, "@confect/server/Storage/StorageReader", {
12
- getUrl: (storageId: GenericId<"_storage">) => Effect.Effect<URL, BlobNotFoundError, never>;
13
- }> & Effect.Tag.Proxy<StorageReader, {
14
- getUrl: (storageId: GenericId<"_storage">) => Effect.Effect<URL, BlobNotFoundError, never>;
15
- }> & {
16
- use: <X>(body: (_: {
17
- getUrl: (storageId: GenericId<"_storage">) => Effect.Effect<URL, BlobNotFoundError, never>;
18
- }) => X) => [X] extends [Effect.Effect<infer A, infer E, infer R>] ? Effect.Effect<A, E, R | StorageReader> : [X] extends [PromiseLike<infer A_1>] ? Effect.Effect<A_1, effect_Cause0.UnknownException, StorageReader> : Effect.Effect<X, never, StorageReader>;
19
- };
20
- declare class StorageReader extends StorageReader_base {
21
- static readonly layer: (storageReader: StorageReader$1) => Layer.Layer<StorageReader, never, never>;
22
- }
23
- declare const StorageWriter_base: effect_Context0.TagClass<StorageWriter, "@confect/server/Storage/StorageWriter", {
24
- generateUploadUrl: () => Effect.Effect<URL, never, never>;
25
- delete: (storageId: GenericId<"_storage">) => Effect.Effect<void, BlobNotFoundError, never>;
26
- }> & Effect.Tag.Proxy<StorageWriter, {
27
- generateUploadUrl: () => Effect.Effect<URL, never, never>;
28
- delete: (storageId: GenericId<"_storage">) => Effect.Effect<void, BlobNotFoundError, never>;
29
- }> & {
30
- use: <X>(body: (_: {
31
- generateUploadUrl: () => Effect.Effect<URL, never, never>;
32
- delete: (storageId: GenericId<"_storage">) => Effect.Effect<void, BlobNotFoundError, never>;
33
- }) => X) => [X] extends [Effect.Effect<infer A, infer E, infer R>] ? Effect.Effect<A, E, R | StorageWriter> : [X] extends [PromiseLike<infer A_1>] ? Effect.Effect<A_1, effect_Cause0.UnknownException, StorageWriter> : Effect.Effect<X, never, StorageWriter>;
34
- };
35
- declare class StorageWriter extends StorageWriter_base {
36
- static readonly layer: (storageWriter: StorageWriter$1) => Layer.Layer<StorageWriter, never, never>;
37
- }
38
- declare const StorageActionWriter_base: effect_Context0.TagClass<StorageActionWriter, "@confect/server/Storage/StorageActionWriter", {
39
- get: (storageId: GenericId<"_storage">) => Effect.Effect<Blob, BlobNotFoundError, never>;
40
- store: (blob: Blob, options?: {
41
- sha256?: string;
42
- }) => Effect.Effect<GenericId<"_storage">, never, never>;
43
- }> & Effect.Tag.Proxy<StorageActionWriter, {
44
- get: (storageId: GenericId<"_storage">) => Effect.Effect<Blob, BlobNotFoundError, never>;
45
- store: (blob: Blob, options?: {
46
- sha256?: string;
47
- }) => Effect.Effect<GenericId<"_storage">, never, never>;
48
- }> & {
49
- use: <X>(body: (_: {
50
- get: (storageId: GenericId<"_storage">) => Effect.Effect<Blob, BlobNotFoundError, never>;
51
- store: (blob: Blob, options?: {
52
- sha256?: string;
53
- }) => Effect.Effect<GenericId<"_storage">, never, never>;
54
- }) => X) => [X] extends [Effect.Effect<infer A, infer E, infer R>] ? Effect.Effect<A, E, R | StorageActionWriter> : [X] extends [PromiseLike<infer A_1>] ? Effect.Effect<A_1, effect_Cause0.UnknownException, StorageActionWriter> : Effect.Effect<X, never, StorageActionWriter>;
55
- };
56
- declare class StorageActionWriter extends StorageActionWriter_base {
57
- static readonly layer: (storageActionWriter: StorageActionWriter$1) => Layer.Layer<StorageActionWriter, never, never>;
58
- }
59
- declare const BlobNotFoundError_base: Schema.TaggedErrorClass<BlobNotFoundError, "BlobNotFoundError", {
60
- readonly _tag: Schema.tag<"BlobNotFoundError">;
61
- } & {
62
- id: typeof Schema.String;
63
- }>;
64
- declare class BlobNotFoundError extends BlobNotFoundError_base {
65
- get message(): string;
66
- }
67
- //#endregion
68
- export { BlobNotFoundError, StorageActionWriter, StorageReader, StorageWriter, Storage_d_exports };
69
- //# sourceMappingURL=Storage.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Storage.d.ts","names":[],"sources":["../src/Storage.ts"],"mappings":";;;;;;;;;;cAMmE,kBAAA,EAGxB,eAAA,CAAA,QAAA;sBAArB,SAAA,iBAAqB,MAAA,CAAA,MAAA,CAAA,GAAA,EAAA,iBAAA;AAAA;sBAArB,SAAA,iBAAqB,MAAA,CAAA,MAAA,CAAA,GAAA,EAAA,iBAAA;AAAA;;wBAArB,SAAA,iBAAqB,MAAA,CAAA,MAAA,CAAA,GAAA,EAAA,iBAAA;EAAA;;cA+C9B,aAAA,SAAsB,kBAAA;EAAA,gBAGjB,KAAA,GAAS,aAAA,EAAe,eAAA,KAAmB,KAAA,CAAA,KAAA,CAAA,aAAA;AAAA;AAAA,cAE5D,kBAAA,EA/B0C,eAAA,CAAA,QAAA;;sBAArB,SAAA,iBAAqB,MAAA,CAAA,MAAA,OAAA,iBAAA;AAAA;;sBAArB,SAAA,iBAAqB,MAAA,CAAA,MAAA,OAAA,iBAAA;AAAA;;;wBAArB,SAAA,iBAAqB,MAAA,CAAA,MAAA,OAAA,iBAAA;EAAA;;cAiC9B,aAAA,SAAsB,kBAAA;EAAA,gBAGjB,KAAA,GAAS,aAAA,EAAe,eAAA,KAAmB,KAAA,CAAA,KAAA,CAAA,aAAA;AAAA;AAAA,cAE5D,wBAAA,EAhBkD,eAAA,CAAA,QAAA;mBAZhC,SAAA,iBAAqB,MAAA,CAAA,MAAA,CAAA,IAAA,EAAA,iBAAA;gBAYxB,IAAA,EAAI,OAAA;IAAc,MAAA;EAAA,MAAiB,MAAA,CAAA,MAAA,CAAA,SAAA;AAAA;mBAZhC,SAAA,iBAAqB,MAAA,CAAA,MAAA,CAAA,IAAA,EAAA,iBAAA;gBAYxB,IAAA,EAAI,OAAA;IAAc,MAAA;EAAA,MAAiB,MAAA,CAAA,MAAA,CAAA,SAAA;AAAA;;qBAZhC,SAAA,iBAAqB,MAAA,CAAA,MAAA,CAAA,IAAA,EAAA,iBAAA;kBAYxB,IAAA,EAAI,OAAA;MAAc,MAAA;IAAA,MAAiB,MAAA,CAAA,MAAA,CAAA,SAAA;EAAA;;cAkBtC,mBAAA,SAA4B,wBAAA;EAAA,gBAGvB,KAAA,GAAS,mBAAA,EAAqB,qBAAA,KAAyB,KAAA,CAAA,KAAA,CAAA,mBAAA;AAAA;AAAA,cAExE,sBAAA;;;;;cAEY,iBAAA,SAA0B,sBAAA;EAAA,IAMxB,OAAA,CAAA;AAAA"}
package/dist/Storage.js DELETED
@@ -1,46 +0,0 @@
1
- import { __exportAll } from "./_virtual/_rolldown/runtime.js";
2
- import { Effect, Layer, Option, Schema, flow, pipe } from "effect";
3
-
4
- //#region src/Storage.ts
5
- var Storage_exports = /* @__PURE__ */ __exportAll({
6
- BlobNotFoundError: () => BlobNotFoundError,
7
- StorageActionWriter: () => StorageActionWriter,
8
- StorageReader: () => StorageReader,
9
- StorageWriter: () => StorageWriter
10
- });
11
- const makeStorageReader = (storageReader) => ({ getUrl: (storageId) => Effect.promise(() => storageReader.getUrl(storageId)).pipe(Effect.andThen(flow(Option.fromNullable, Option.match({
12
- onNone: () => Effect.fail(new BlobNotFoundError({ id: storageId })),
13
- onSome: (doc) => pipe(doc, Schema.decode(Schema.URL), Effect.orDie)
14
- })))) });
15
- const makeStorageWriter = (storageWriter) => ({
16
- generateUploadUrl: () => Effect.promise(() => storageWriter.generateUploadUrl()).pipe(Effect.andThen((url) => pipe(url, Schema.decode(Schema.URL), Effect.orDie))),
17
- delete: (storageId) => Effect.tryPromise({
18
- try: () => storageWriter.delete(storageId),
19
- catch: () => new BlobNotFoundError({ id: storageId })
20
- })
21
- });
22
- const makeStorageActionWriter = (storageActionWriter) => ({
23
- get: (storageId) => Effect.promise(() => storageActionWriter.get(storageId)).pipe(Effect.andThen(flow(Option.fromNullable, Option.match({
24
- onNone: () => Effect.fail(new BlobNotFoundError({ id: storageId })),
25
- onSome: Effect.succeed
26
- })))),
27
- store: (blob, options) => Effect.promise(() => storageActionWriter.store(blob, options))
28
- });
29
- var StorageReader = class extends Effect.Tag("@confect/server/Storage/StorageReader")() {
30
- static layer = (storageReader) => Layer.succeed(this, makeStorageReader(storageReader));
31
- };
32
- var StorageWriter = class extends Effect.Tag("@confect/server/Storage/StorageWriter")() {
33
- static layer = (storageWriter) => Layer.succeed(this, makeStorageWriter(storageWriter));
34
- };
35
- var StorageActionWriter = class extends Effect.Tag("@confect/server/Storage/StorageActionWriter")() {
36
- static layer = (storageActionWriter) => Layer.succeed(this, makeStorageActionWriter(storageActionWriter));
37
- };
38
- var BlobNotFoundError = class extends Schema.TaggedError()("BlobNotFoundError", { id: Schema.String }) {
39
- get message() {
40
- return `File with ID '${this.id}' not found`;
41
- }
42
- };
43
-
44
- //#endregion
45
- export { BlobNotFoundError, StorageActionWriter, StorageReader, StorageWriter, Storage_exports };
46
- //# sourceMappingURL=Storage.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Storage.js","names":[],"sources":["../src/Storage.ts"],"sourcesContent":["import type {\n StorageActionWriter as ConvexStorageActionWriter,\n StorageReader as ConvexStorageReader,\n StorageWriter as ConvexStorageWriter,\n} from \"convex/server\";\nimport type { GenericId } from \"convex/values\";\nimport { Effect, flow, Layer, Option, pipe, Schema } from \"effect\";\n\nconst makeStorageReader = (storageReader: ConvexStorageReader) => ({\n getUrl: (storageId: GenericId<\"_storage\">) =>\n Effect.promise(() => storageReader.getUrl(storageId)).pipe(\n Effect.andThen(\n flow(\n Option.fromNullable,\n Option.match({\n onNone: () => Effect.fail(new BlobNotFoundError({ id: storageId })),\n onSome: (doc) => pipe(doc, Schema.decode(Schema.URL), Effect.orDie),\n }),\n ),\n ),\n ),\n});\n\nconst makeStorageWriter = (storageWriter: ConvexStorageWriter) => ({\n generateUploadUrl: () =>\n Effect.promise(() => storageWriter.generateUploadUrl()).pipe(\n Effect.andThen((url) =>\n pipe(url, Schema.decode(Schema.URL), Effect.orDie),\n ),\n ),\n delete: (storageId: GenericId<\"_storage\">) =>\n Effect.tryPromise({\n try: () => storageWriter.delete(storageId),\n catch: () => new BlobNotFoundError({ id: storageId }),\n }),\n});\n\nconst makeStorageActionWriter = (\n storageActionWriter: ConvexStorageActionWriter,\n) => ({\n get: (storageId: GenericId<\"_storage\">) =>\n Effect.promise(() => storageActionWriter.get(storageId)).pipe(\n Effect.andThen(\n flow(\n Option.fromNullable,\n Option.match({\n onNone: () => Effect.fail(new BlobNotFoundError({ id: storageId })),\n onSome: Effect.succeed,\n }),\n ),\n ),\n ),\n store: (blob: Blob, options?: { sha256?: string }) =>\n Effect.promise(() => storageActionWriter.store(blob, options)),\n});\n\nexport class StorageReader extends Effect.Tag(\n \"@confect/server/Storage/StorageReader\",\n)<StorageReader, ReturnType<typeof makeStorageReader>>() {\n static readonly layer = (storageReader: ConvexStorageReader) =>\n Layer.succeed(this, makeStorageReader(storageReader));\n}\n\nexport class StorageWriter extends Effect.Tag(\n \"@confect/server/Storage/StorageWriter\",\n)<StorageWriter, ReturnType<typeof makeStorageWriter>>() {\n static readonly layer = (storageWriter: ConvexStorageWriter) =>\n Layer.succeed(this, makeStorageWriter(storageWriter));\n}\n\nexport class StorageActionWriter extends Effect.Tag(\n \"@confect/server/Storage/StorageActionWriter\",\n)<StorageActionWriter, ReturnType<typeof makeStorageActionWriter>>() {\n static readonly layer = (storageActionWriter: ConvexStorageActionWriter) =>\n Layer.succeed(this, makeStorageActionWriter(storageActionWriter));\n}\n\nexport class BlobNotFoundError extends Schema.TaggedError<BlobNotFoundError>()(\n \"BlobNotFoundError\",\n {\n id: Schema.String,\n },\n) {\n override get message(): string {\n return `File with ID '${this.id}' not found`;\n }\n}\n"],"mappings":";;;;;;;;;;AAQA,MAAM,qBAAqB,mBAAwC,EACjE,SAAS,cACP,OAAO,cAAc,cAAc,OAAO,UAAU,CAAC,CAAC,KACpD,OAAO,QACL,KACE,OAAO,cACP,OAAO,MAAM;CACX,cAAc,OAAO,KAAK,IAAI,kBAAkB,EAAE,IAAI,WAAW,CAAC,CAAC;CACnE,SAAS,QAAQ,KAAK,KAAK,OAAO,OAAO,OAAO,IAAI,EAAE,OAAO,MAAM;CACpE,CAAC,CACH,CACF,CACF,EACJ;AAED,MAAM,qBAAqB,mBAAwC;CACjE,yBACE,OAAO,cAAc,cAAc,mBAAmB,CAAC,CAAC,KACtD,OAAO,SAAS,QACd,KAAK,KAAK,OAAO,OAAO,OAAO,IAAI,EAAE,OAAO,MAAM,CACnD,CACF;CACH,SAAS,cACP,OAAO,WAAW;EAChB,WAAW,cAAc,OAAO,UAAU;EAC1C,aAAa,IAAI,kBAAkB,EAAE,IAAI,WAAW,CAAC;EACtD,CAAC;CACL;AAED,MAAM,2BACJ,yBACI;CACJ,MAAM,cACJ,OAAO,cAAc,oBAAoB,IAAI,UAAU,CAAC,CAAC,KACvD,OAAO,QACL,KACE,OAAO,cACP,OAAO,MAAM;EACX,cAAc,OAAO,KAAK,IAAI,kBAAkB,EAAE,IAAI,WAAW,CAAC,CAAC;EACnE,QAAQ,OAAO;EAChB,CAAC,CACH,CACF,CACF;CACH,QAAQ,MAAY,YAClB,OAAO,cAAc,oBAAoB,MAAM,MAAM,QAAQ,CAAC;CACjE;AAED,IAAa,gBAAb,cAAmC,OAAO,IACxC,wCACD,EAAuD,CAAC;CACvD,OAAgB,SAAS,kBACvB,MAAM,QAAQ,MAAM,kBAAkB,cAAc,CAAC;;AAGzD,IAAa,gBAAb,cAAmC,OAAO,IACxC,wCACD,EAAuD,CAAC;CACvD,OAAgB,SAAS,kBACvB,MAAM,QAAQ,MAAM,kBAAkB,cAAc,CAAC;;AAGzD,IAAa,sBAAb,cAAyC,OAAO,IAC9C,8CACD,EAAmE,CAAC;CACnE,OAAgB,SAAS,wBACvB,MAAM,QAAQ,MAAM,wBAAwB,oBAAoB,CAAC;;AAGrE,IAAa,oBAAb,cAAuC,OAAO,aAAgC,CAC5E,qBACA,EACE,IAAI,OAAO,QACZ,CACF,CAAC;CACA,IAAa,UAAkB;AAC7B,SAAO,iBAAiB,KAAK,GAAG"}
package/src/Storage.ts DELETED
@@ -1,87 +0,0 @@
1
- import type {
2
- StorageActionWriter as ConvexStorageActionWriter,
3
- StorageReader as ConvexStorageReader,
4
- StorageWriter as ConvexStorageWriter,
5
- } from "convex/server";
6
- import type { GenericId } from "convex/values";
7
- import { Effect, flow, Layer, Option, pipe, Schema } from "effect";
8
-
9
- const makeStorageReader = (storageReader: ConvexStorageReader) => ({
10
- getUrl: (storageId: GenericId<"_storage">) =>
11
- Effect.promise(() => storageReader.getUrl(storageId)).pipe(
12
- Effect.andThen(
13
- flow(
14
- Option.fromNullable,
15
- Option.match({
16
- onNone: () => Effect.fail(new BlobNotFoundError({ id: storageId })),
17
- onSome: (doc) => pipe(doc, Schema.decode(Schema.URL), Effect.orDie),
18
- }),
19
- ),
20
- ),
21
- ),
22
- });
23
-
24
- const makeStorageWriter = (storageWriter: ConvexStorageWriter) => ({
25
- generateUploadUrl: () =>
26
- Effect.promise(() => storageWriter.generateUploadUrl()).pipe(
27
- Effect.andThen((url) =>
28
- pipe(url, Schema.decode(Schema.URL), Effect.orDie),
29
- ),
30
- ),
31
- delete: (storageId: GenericId<"_storage">) =>
32
- Effect.tryPromise({
33
- try: () => storageWriter.delete(storageId),
34
- catch: () => new BlobNotFoundError({ id: storageId }),
35
- }),
36
- });
37
-
38
- const makeStorageActionWriter = (
39
- storageActionWriter: ConvexStorageActionWriter,
40
- ) => ({
41
- get: (storageId: GenericId<"_storage">) =>
42
- Effect.promise(() => storageActionWriter.get(storageId)).pipe(
43
- Effect.andThen(
44
- flow(
45
- Option.fromNullable,
46
- Option.match({
47
- onNone: () => Effect.fail(new BlobNotFoundError({ id: storageId })),
48
- onSome: Effect.succeed,
49
- }),
50
- ),
51
- ),
52
- ),
53
- store: (blob: Blob, options?: { sha256?: string }) =>
54
- Effect.promise(() => storageActionWriter.store(blob, options)),
55
- });
56
-
57
- export class StorageReader extends Effect.Tag(
58
- "@confect/server/Storage/StorageReader",
59
- )<StorageReader, ReturnType<typeof makeStorageReader>>() {
60
- static readonly layer = (storageReader: ConvexStorageReader) =>
61
- Layer.succeed(this, makeStorageReader(storageReader));
62
- }
63
-
64
- export class StorageWriter extends Effect.Tag(
65
- "@confect/server/Storage/StorageWriter",
66
- )<StorageWriter, ReturnType<typeof makeStorageWriter>>() {
67
- static readonly layer = (storageWriter: ConvexStorageWriter) =>
68
- Layer.succeed(this, makeStorageWriter(storageWriter));
69
- }
70
-
71
- export class StorageActionWriter extends Effect.Tag(
72
- "@confect/server/Storage/StorageActionWriter",
73
- )<StorageActionWriter, ReturnType<typeof makeStorageActionWriter>>() {
74
- static readonly layer = (storageActionWriter: ConvexStorageActionWriter) =>
75
- Layer.succeed(this, makeStorageActionWriter(storageActionWriter));
76
- }
77
-
78
- export class BlobNotFoundError extends Schema.TaggedError<BlobNotFoundError>()(
79
- "BlobNotFoundError",
80
- {
81
- id: Schema.String,
82
- },
83
- ) {
84
- override get message(): string {
85
- return `File with ID '${this.id}' not found`;
86
- }
87
- }