effect-cf 0.13.0 → 0.14.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/src/Images.ts CHANGED
@@ -1,3 +1,21 @@
1
+ import type {
2
+ HostedImagesBinding as CloudflareHostedImagesBinding,
3
+ ImageDrawOptions as CloudflareImageDrawOptions,
4
+ ImageHandle as CloudflareImageHandle,
5
+ ImageInfoResponse as CloudflareImageInfoResponse,
6
+ ImageInputOptions as CloudflareImageInputOptions,
7
+ ImageList as CloudflareImageList,
8
+ ImageListOptions as CloudflareImageListOptions,
9
+ ImageMetadata as CloudflareImageMetadata,
10
+ ImageOutputOptions as CloudflareImageOutputOptions,
11
+ ImageTransform as CloudflareImageTransform,
12
+ ImageTransformationOutputOptions as CloudflareImageTransformationOutputOptions,
13
+ ImageTransformationResult as CloudflareImageTransformationResult,
14
+ ImageTransformer as CloudflareImageTransformer,
15
+ ImageUpdateOptions as CloudflareImageUpdateOptions,
16
+ ImageUploadOptions as CloudflareImageUploadOptions,
17
+ Response as CloudflareResponse,
18
+ } from "@cloudflare/workers-types";
1
19
  import { Context, Data, Effect, Option, type Layer } from "effect";
2
20
 
3
21
  import * as Binding from "./Binding";
@@ -19,23 +37,23 @@ export interface ImagesDefinition {
19
37
  readonly binding: string;
20
38
  }
21
39
 
22
- export type ImageInfoResponse = globalThis.ImageInfoResponse;
23
- export type ImageTransform = globalThis.ImageTransform;
24
- export type ImageDrawOptions = globalThis.ImageDrawOptions;
25
- export type ImageInputOptions = globalThis.ImageInputOptions;
26
- export type ImageOutputOptions = globalThis.ImageOutputOptions;
27
- export type ImageTransformationOutputOptions = globalThis.ImageTransformationOutputOptions;
28
- export type ImageTransformationResult = globalThis.ImageTransformationResult;
29
- export type ImageUploadOptions = globalThis.ImageUploadOptions;
30
- export type ImageUpdateOptions = globalThis.ImageUpdateOptions;
31
- export type ImageListOptions = globalThis.ImageListOptions;
32
- export type ImageList = globalThis.ImageList;
33
- export type ImageMetadata = globalThis.ImageMetadata;
40
+ export type ImageInfoResponse = CloudflareImageInfoResponse;
41
+ export type ImageTransform = CloudflareImageTransform;
42
+ export type ImageDrawOptions = CloudflareImageDrawOptions;
43
+ export type ImageInputOptions = CloudflareImageInputOptions;
44
+ export type ImageOutputOptions = CloudflareImageOutputOptions;
45
+ export type ImageTransformationOutputOptions = CloudflareImageTransformationOutputOptions;
46
+ export type ImageTransformationResult = CloudflareImageTransformationResult;
47
+ export type ImageUploadOptions = CloudflareImageUploadOptions;
48
+ export type ImageUpdateOptions = CloudflareImageUpdateOptions;
49
+ export type ImageListOptions = CloudflareImageListOptions;
50
+ export type ImageList = CloudflareImageList;
51
+ export type ImageMetadata = CloudflareImageMetadata;
34
52
  export type ImageInputValue = ReadableStream<Uint8Array> | ArrayBuffer;
35
53
  export type ImageUploadValue = ReadableStream<Uint8Array> | ArrayBuffer;
36
54
 
37
55
  export interface DrawStepOptions {
38
- readonly image: ReadableStream<Uint8Array> | globalThis.ImageTransformer;
56
+ readonly image: ReadableStream<Uint8Array> | CloudflareImageTransformer;
39
57
  readonly options?: ImageDrawOptions;
40
58
  }
41
59
 
@@ -58,8 +76,8 @@ export interface ProcessOptions {
58
76
  }
59
77
 
60
78
  export interface ImagesTransformationResultClient {
61
- readonly raw: globalThis.ImageTransformationResult;
62
- readonly response: Effect.Effect<globalThis.Response, ImagesOperationError>;
79
+ readonly raw: CloudflareImageTransformationResult;
80
+ readonly response: Effect.Effect<CloudflareResponse, ImagesOperationError>;
63
81
  readonly contentType: Effect.Effect<string, ImagesOperationError>;
64
82
  readonly image: (
65
83
  options?: ImageTransformationOutputOptions,
@@ -67,7 +85,7 @@ export interface ImagesTransformationResultClient {
67
85
  }
68
86
 
69
87
  export interface ImageHandleClient {
70
- readonly raw: globalThis.ImageHandle;
88
+ readonly raw: CloudflareImageHandle;
71
89
  readonly details: Effect.Effect<Option.Option<ImageMetadata>, ImagesOperationError>;
72
90
  readonly bytes: Effect.Effect<Option.Option<ReadableStream<Uint8Array>>, ImagesOperationError>;
73
91
  readonly update: (
@@ -83,7 +101,7 @@ export interface HostedImagesClient {
83
101
  options?: ImageUploadOptions,
84
102
  ) => Effect.Effect<ImageMetadata, ImagesOperationError>;
85
103
  readonly list: (options?: ImageListOptions) => Effect.Effect<ImageList, ImagesOperationError>;
86
- readonly unsafeRaw: Effect.Effect<globalThis.HostedImagesBinding>;
104
+ readonly unsafeRaw: Effect.Effect<CloudflareHostedImagesBinding>;
87
105
  }
88
106
 
89
107
  export interface ImagesRuntimeBinding {
@@ -94,8 +112,8 @@ export interface ImagesRuntimeBinding {
94
112
  readonly input: (
95
113
  image: ImageInputValue,
96
114
  options?: ImageInputOptions,
97
- ) => globalThis.ImageTransformer;
98
- readonly hosted?: globalThis.HostedImagesBinding;
115
+ ) => CloudflareImageTransformer;
116
+ readonly hosted?: CloudflareHostedImagesBinding;
99
117
  }
100
118
 
101
119
  export interface ImagesClient {
@@ -106,7 +124,7 @@ export interface ImagesClient {
106
124
  readonly input: (
107
125
  image: ImageInputValue,
108
126
  options?: ImageInputOptions,
109
- ) => Effect.Effect<globalThis.ImageTransformer, ImagesOperationError>;
127
+ ) => Effect.Effect<CloudflareImageTransformer, ImagesOperationError>;
110
128
  readonly process: (
111
129
  steps: Steps,
112
130
  options: ProcessOptions,
@@ -223,7 +241,7 @@ const maybe = <A>(value: A | null): Option.Option<A> =>
223
241
  const hasFunction = (value: object, key: string): boolean =>
224
242
  typeof Reflect.get(value, key) === "function";
225
243
 
226
- const isHostedImagesBinding = (value: unknown): value is globalThis.HostedImagesBinding =>
244
+ const isHostedImagesBinding = (value: unknown): value is CloudflareHostedImagesBinding =>
227
245
  typeof value === "object" &&
228
246
  value !== null &&
229
247
  hasFunction(value, "image") &&
@@ -238,7 +256,7 @@ export const isImagesBinding = (value: unknown): value is ImagesRuntimeBinding =
238
256
 
239
257
  const wrapResult = (
240
258
  binding: string,
241
- result: globalThis.ImageTransformationResult,
259
+ result: CloudflareImageTransformationResult,
242
260
  ): ImagesTransformationResultClient => ({
243
261
  raw: result,
244
262
  response: tryImagesSync(binding, "response", () => result.response()),
@@ -246,7 +264,7 @@ const wrapResult = (
246
264
  image: (options) => tryImagesSync(binding, "image", () => result.image(options)),
247
265
  });
248
266
 
249
- const wrapHandle = (binding: string, handle: globalThis.ImageHandle): ImageHandleClient => ({
267
+ const wrapHandle = (binding: string, handle: CloudflareImageHandle): ImageHandleClient => ({
250
268
  raw: handle,
251
269
  details: tryImagesPromise(binding, "details", () => handle.details()).pipe(Effect.map(maybe)),
252
270
  bytes: tryImagesPromise(binding, "bytes", () => handle.bytes()).pipe(Effect.map(maybe)),
@@ -256,7 +274,7 @@ const wrapHandle = (binding: string, handle: globalThis.ImageHandle): ImageHandl
256
274
 
257
275
  const wrapHosted = (
258
276
  binding: string,
259
- hosted: globalThis.HostedImagesBinding,
277
+ hosted: CloudflareHostedImagesBinding,
260
278
  ): HostedImagesClient => ({
261
279
  image: (imageId) => wrapHandle(binding, hosted.image(imageId)),
262
280
  upload: (image, options) =>
package/src/Kv.ts CHANGED
@@ -1,3 +1,7 @@
1
+ import type {
2
+ KVNamespaceListOptions as CloudflareKVNamespaceListOptions,
3
+ KVNamespacePutOptions as CloudflareKVNamespacePutOptions,
4
+ } from "@cloudflare/workers-types";
1
5
  import { Context, Data, Effect, Option, Schema as S, type Layer } from "effect";
2
6
 
3
7
  import * as Binding from "./Binding";
@@ -14,9 +18,9 @@ export class KvOperationError extends Data.TaggedError("KvOperationError")<{
14
18
  }> {}
15
19
 
16
20
  /** `KVNamespace.put` options. */
17
- export type KvPutOptions = globalThis.KVNamespacePutOptions;
21
+ export type KvPutOptions = CloudflareKVNamespacePutOptions;
18
22
  /** `KVNamespace.list` options with optional metadata decoding schema. */
19
- export type KvListOptions<Metadata = unknown> = globalThis.KVNamespaceListOptions & {
23
+ export type KvListOptions<Metadata = unknown> = CloudflareKVNamespaceListOptions & {
20
24
  readonly metadataSchema?: S.Codec<Metadata, unknown>;
21
25
  };
22
26
 
@@ -1,17 +1,26 @@
1
+ import type {
2
+ MessageSendRequest as CloudflareMessageSendRequest,
3
+ Queue as CloudflareQueue,
4
+ QueueMetrics as CloudflareQueueMetrics,
5
+ QueueSendBatchOptions as CloudflareQueueSendBatchOptions,
6
+ QueueSendBatchResponse as CloudflareQueueSendBatchResponse,
7
+ QueueSendOptions as CloudflareQueueSendOptions,
8
+ QueueSendResponse as CloudflareQueueSendResponse,
9
+ } from "@cloudflare/workers-types";
1
10
  import { Context, Data, Effect, Schema as S } from "effect";
2
11
 
3
12
  import * as Binding from "./Binding";
4
13
  import type * as RpcDefinition from "./RpcDefinition";
5
14
 
6
- export type QueueSendOptions = globalThis.QueueSendOptions;
7
- export type QueueSendResponse = globalThis.QueueSendResponse;
8
- export type QueueSendBatchOptions = globalThis.QueueSendBatchOptions;
9
- export type QueueSendBatchResponse = globalThis.QueueSendBatchResponse;
10
- export type QueueMetrics = globalThis.QueueMetrics;
11
- export type MessageSendRequest<Body> = globalThis.MessageSendRequest<Body>;
15
+ export type QueueSendOptions = CloudflareQueueSendOptions;
16
+ export type QueueSendResponse = CloudflareQueueSendResponse;
17
+ export type QueueSendBatchOptions = CloudflareQueueSendBatchOptions;
18
+ export type QueueSendBatchResponse = CloudflareQueueSendBatchResponse;
19
+ export type QueueMetrics = CloudflareQueueMetrics;
20
+ export type MessageSendRequest<Body> = CloudflareMessageSendRequest<Body>;
12
21
 
13
- export type QueueProducer<Body> = Pick<globalThis.Queue<Body>, "send"> &
14
- Partial<Pick<globalThis.Queue<Body>, "sendBatch" | "metrics">>;
22
+ export type QueueProducer<Body> = Pick<CloudflareQueue<Body>, "send"> &
23
+ Partial<Pick<CloudflareQueue<Body>, "sendBatch" | "metrics">>;
15
24
 
16
25
  const expectedQueueProducer = "Queue producer binding with send(); optional sendBatch()/metrics()";
17
26
 
@@ -32,7 +41,7 @@ export interface QueueBindingClient<Message extends RpcDefinition.ServiceFreeSch
32
41
  options?: QueueSendBatchOptions,
33
42
  ) => Effect.Effect<void, QueueOperationError | S.SchemaError>;
34
43
  readonly metrics: () => Effect.Effect<QueueMetrics, QueueOperationError>;
35
- readonly unsafeRaw: Effect.Effect<globalThis.Queue<S.Codec.Encoded<Message>>>;
44
+ readonly unsafeRaw: Effect.Effect<CloudflareQueue<S.Codec.Encoded<Message>>>;
36
45
  }
37
46
 
38
47
  export class QueueOperationError extends Data.TaggedError("QueueOperationError")<{
@@ -129,7 +138,7 @@ export const makeClient = <Message extends RpcDefinition.ServiceFreeSchema>(
129
138
 
130
139
  return tryQueuePromise(definition.binding, "metrics", () => metrics.call(queue));
131
140
  },
132
- unsafeRaw: Effect.succeed(queue as globalThis.Queue<EncodedBody>),
141
+ unsafeRaw: Effect.succeed(queue as CloudflareQueue<EncodedBody>),
133
142
  });
134
143
  };
135
144
 
package/src/R2.ts CHANGED
@@ -1,3 +1,17 @@
1
+ import type {
2
+ R2Bucket as CloudflareR2Bucket,
3
+ R2Conditional as CloudflareR2Conditional,
4
+ R2GetOptions as CloudflareR2GetOptions,
5
+ R2ListOptions as CloudflareR2ListOptions,
6
+ R2MultipartOptions as CloudflareR2MultipartOptions,
7
+ R2MultipartUpload as CloudflareR2MultipartUpload,
8
+ R2Object as CloudflareR2Object,
9
+ R2ObjectBody as CloudflareR2ObjectBody,
10
+ R2Objects as CloudflareR2Objects,
11
+ R2PutOptions as CloudflareR2PutOptions,
12
+ R2UploadPartOptions as CloudflareR2UploadPartOptions,
13
+ R2UploadedPart as CloudflareR2UploadedPart,
14
+ } from "@cloudflare/workers-types";
1
15
  import { Context, Data, Effect, Option, type Layer } from "effect";
2
16
 
3
17
  import * as Binding from "./Binding";
@@ -19,19 +33,19 @@ export interface R2Definition {
19
33
  readonly binding: string;
20
34
  }
21
35
 
22
- export type R2GetOptions = globalThis.R2GetOptions;
23
- export type R2PutOptions = globalThis.R2PutOptions;
24
- export type R2ListOptions = globalThis.R2ListOptions;
25
- export type R2MultipartOptions = globalThis.R2MultipartOptions;
26
- export type R2UploadPartOptions = globalThis.R2UploadPartOptions;
36
+ export type R2GetOptions = CloudflareR2GetOptions;
37
+ export type R2PutOptions = CloudflareR2PutOptions;
38
+ export type R2ListOptions = CloudflareR2ListOptions;
39
+ export type R2MultipartOptions = CloudflareR2MultipartOptions;
40
+ export type R2UploadPartOptions = CloudflareR2UploadPartOptions;
27
41
  export type R2PutValue = ReadableStream | ArrayBuffer | ArrayBufferView | string | null | Blob;
28
42
  export type R2UploadPartValue = ReadableStream | ArrayBuffer | ArrayBufferView | string | Blob;
29
43
 
30
44
  export interface R2ObjectBodyClient extends Omit<
31
- globalThis.R2ObjectBody,
45
+ CloudflareR2ObjectBody,
32
46
  "arrayBuffer" | "blob" | "bytes" | "json" | "text"
33
47
  > {
34
- readonly raw: globalThis.R2ObjectBody;
48
+ readonly raw: CloudflareR2ObjectBody;
35
49
  readonly arrayBuffer: Effect.Effect<ArrayBuffer, R2OperationError>;
36
50
  readonly bytes: Effect.Effect<Uint8Array, R2OperationError>;
37
51
  readonly text: Effect.Effect<string, R2OperationError>;
@@ -40,29 +54,29 @@ export interface R2ObjectBodyClient extends Omit<
40
54
  }
41
55
 
42
56
  export interface R2MultipartUploadClient {
43
- readonly raw: globalThis.R2MultipartUpload;
57
+ readonly raw: CloudflareR2MultipartUpload;
44
58
  readonly key: string;
45
59
  readonly uploadId: string;
46
60
  readonly uploadPart: (
47
61
  partNumber: number,
48
62
  value: R2UploadPartValue,
49
63
  options?: R2UploadPartOptions,
50
- ) => Effect.Effect<globalThis.R2UploadedPart, R2OperationError>;
64
+ ) => Effect.Effect<CloudflareR2UploadedPart, R2OperationError>;
51
65
  readonly abort: Effect.Effect<void, R2OperationError>;
52
66
  readonly complete: (
53
- uploadedParts: ReadonlyArray<globalThis.R2UploadedPart>,
54
- ) => Effect.Effect<globalThis.R2Object, R2OperationError>;
67
+ uploadedParts: ReadonlyArray<CloudflareR2UploadedPart>,
68
+ ) => Effect.Effect<CloudflareR2Object, R2OperationError>;
55
69
  }
56
70
 
57
71
  export interface R2Client {
58
72
  readonly head: (
59
73
  key: string,
60
- ) => Effect.Effect<Option.Option<globalThis.R2Object>, R2OperationError>;
74
+ ) => Effect.Effect<Option.Option<CloudflareR2Object>, R2OperationError>;
61
75
  readonly get: {
62
76
  (
63
77
  key: string,
64
- options: R2GetOptions & { readonly onlyIf: globalThis.R2Conditional | Headers },
65
- ): Effect.Effect<Option.Option<R2ObjectBodyClient | globalThis.R2Object>, R2OperationError>;
78
+ options: R2GetOptions & { readonly onlyIf: CloudflareR2Conditional | Headers },
79
+ ): Effect.Effect<Option.Option<R2ObjectBodyClient | CloudflareR2Object>, R2OperationError>;
66
80
  (
67
81
  key: string,
68
82
  options?: R2GetOptions,
@@ -72,13 +86,13 @@ export interface R2Client {
72
86
  (
73
87
  key: string,
74
88
  value: R2PutValue,
75
- options: R2PutOptions & { readonly onlyIf: globalThis.R2Conditional | Headers },
76
- ): Effect.Effect<Option.Option<globalThis.R2Object>, R2OperationError>;
89
+ options: R2PutOptions & { readonly onlyIf: CloudflareR2Conditional | Headers },
90
+ ): Effect.Effect<Option.Option<CloudflareR2Object>, R2OperationError>;
77
91
  (
78
92
  key: string,
79
93
  value: R2PutValue,
80
94
  options?: R2PutOptions,
81
- ): Effect.Effect<globalThis.R2Object, R2OperationError>;
95
+ ): Effect.Effect<CloudflareR2Object, R2OperationError>;
82
96
  };
83
97
  readonly createMultipartUpload: (
84
98
  key: string,
@@ -89,8 +103,8 @@ export interface R2Client {
89
103
  uploadId: string,
90
104
  ) => Effect.Effect<R2MultipartUploadClient, R2OperationError>;
91
105
  readonly delete: (keys: string | ReadonlyArray<string>) => Effect.Effect<void, R2OperationError>;
92
- readonly list: (options?: R2ListOptions) => Effect.Effect<globalThis.R2Objects, R2OperationError>;
93
- readonly unsafeRaw: Effect.Effect<globalThis.R2Bucket>;
106
+ readonly list: (options?: R2ListOptions) => Effect.Effect<CloudflareR2Objects, R2OperationError>;
107
+ readonly unsafeRaw: Effect.Effect<CloudflareR2Bucket>;
94
108
  readonly definition: R2Definition;
95
109
  }
96
110
 
@@ -149,16 +163,16 @@ const maybe = <A>(value: A | null): Option.Option<A> =>
149
163
  value === null ? Option.none() : Option.some(value);
150
164
 
151
165
  const isR2ObjectBody = (
152
- value: globalThis.R2ObjectBody | globalThis.R2Object,
153
- ): value is globalThis.R2ObjectBody =>
166
+ value: CloudflareR2ObjectBody | CloudflareR2Object,
167
+ ): value is CloudflareR2ObjectBody =>
154
168
  "body" in value &&
155
- typeof (value as globalThis.R2ObjectBody).arrayBuffer === "function" &&
156
- typeof (value as globalThis.R2ObjectBody).bytes === "function" &&
157
- typeof (value as globalThis.R2ObjectBody).text === "function" &&
158
- typeof (value as globalThis.R2ObjectBody).json === "function" &&
159
- typeof (value as globalThis.R2ObjectBody).blob === "function";
169
+ typeof (value as CloudflareR2ObjectBody).arrayBuffer === "function" &&
170
+ typeof (value as CloudflareR2ObjectBody).bytes === "function" &&
171
+ typeof (value as CloudflareR2ObjectBody).text === "function" &&
172
+ typeof (value as CloudflareR2ObjectBody).json === "function" &&
173
+ typeof (value as CloudflareR2ObjectBody).blob === "function";
160
174
 
161
- const wrapObjectBody = (binding: string, object: globalThis.R2ObjectBody): R2ObjectBodyClient => ({
175
+ const wrapObjectBody = (binding: string, object: CloudflareR2ObjectBody): R2ObjectBodyClient => ({
162
176
  key: object.key,
163
177
  version: object.version,
164
178
  size: object.size,
@@ -186,8 +200,8 @@ const wrapObjectBody = (binding: string, object: globalThis.R2ObjectBody): R2Obj
186
200
 
187
201
  const wrapGetResult = (
188
202
  binding: string,
189
- object: globalThis.R2ObjectBody | globalThis.R2Object | null,
190
- ): R2ObjectBodyClient | globalThis.R2Object | null => {
203
+ object: CloudflareR2ObjectBody | CloudflareR2Object | null,
204
+ ): R2ObjectBodyClient | CloudflareR2Object | null => {
191
205
  if (object === null || !isR2ObjectBody(object)) {
192
206
  return object;
193
207
  }
@@ -195,7 +209,7 @@ const wrapGetResult = (
195
209
  return wrapObjectBody(binding, object);
196
210
  };
197
211
 
198
- export const isR2Bucket = (value: unknown): value is globalThis.R2Bucket => {
212
+ export const isR2Bucket = (value: unknown): value is CloudflareR2Bucket => {
199
213
  if (typeof value !== "object" || value === null) {
200
214
  return false;
201
215
  }
@@ -215,8 +229,8 @@ export const isR2Bucket = (value: unknown): value is globalThis.R2Bucket => {
215
229
 
216
230
  export const makeClient = (
217
231
  definition: R2Definition,
218
- ): ((bucket: globalThis.R2Bucket) => R2Client) => {
219
- const wrapUpload = (upload: globalThis.R2MultipartUpload): R2MultipartUploadClient => ({
232
+ ): ((bucket: CloudflareR2Bucket) => R2Client) => {
233
+ const wrapUpload = (upload: CloudflareR2MultipartUpload): R2MultipartUploadClient => ({
220
234
  raw: upload,
221
235
  key: upload.key,
222
236
  uploadId: upload.uploadId,
@@ -246,7 +260,7 @@ export const makeClient = (
246
260
  tryR2Promise(definition.binding, "put", () => bucket.put(key, value, options)).pipe(
247
261
  Effect.map((object) => {
248
262
  if (object === null) {
249
- return Option.none<globalThis.R2Object>();
263
+ return Option.none<CloudflareR2Object>();
250
264
  }
251
265
 
252
266
  if (options !== undefined && "onlyIf" in options) {
@@ -0,0 +1,213 @@
1
+ import { Context, Data, Effect, type Layer } from "effect";
2
+ import type {
3
+ Vectorize as CloudflareVectorize,
4
+ VectorizeAsyncMutation as CloudflareVectorizeAsyncMutation,
5
+ VectorizeIndex as CloudflareVectorizeIndex,
6
+ VectorizeIndexDetails as CloudflareVectorizeIndexDetails,
7
+ VectorizeIndexInfo as CloudflareVectorizeIndexInfo,
8
+ VectorizeMatch as CloudflareVectorizeMatch,
9
+ VectorizeMatches as CloudflareVectorizeMatches,
10
+ VectorizeQueryOptions as CloudflareVectorizeQueryOptions,
11
+ VectorizeVector as CloudflareVectorizeVector,
12
+ VectorizeVectorMetadata as CloudflareVectorizeVectorMetadata,
13
+ VectorizeVectorMetadataFilter as CloudflareVectorizeVectorMetadataFilter,
14
+ VectorizeVectorMetadataValue as CloudflareVectorizeVectorMetadataValue,
15
+ VectorizeVectorMutation as CloudflareVectorizeVectorMutation,
16
+ } from "@cloudflare/workers-types";
17
+
18
+ import * as Binding from "./Binding";
19
+ import type { WorkerEnvironment } from "./Environment";
20
+
21
+ const expectedVectorizeBinding =
22
+ "Vectorize index binding with describe(), query(), insert(), upsert(), deleteByIds(), and getByIds()";
23
+
24
+ /** Error raised when a Vectorize operation fails. */
25
+ export class VectorizeOperationError extends Data.TaggedError("VectorizeOperationError")<{
26
+ readonly binding: string;
27
+ readonly operation: string;
28
+ readonly cause: unknown;
29
+ }> {}
30
+
31
+ /** Typed Vectorize binding definition. */
32
+ export interface VectorizeDefinition {
33
+ /** Binding name as configured in `wrangler.jsonc`. */
34
+ readonly binding: string;
35
+ }
36
+
37
+ export type VectorizeBinding = CloudflareVectorize | CloudflareVectorizeIndex;
38
+ export type VectorizeVector = CloudflareVectorizeVector;
39
+ export type VectorizeVectorMetadata = CloudflareVectorizeVectorMetadata;
40
+ export type VectorizeVectorMetadataValue = CloudflareVectorizeVectorMetadataValue;
41
+ export type VectorizeVectorMetadataFilter = CloudflareVectorizeVectorMetadataFilter;
42
+ export type VectorizeQueryOptions = CloudflareVectorizeQueryOptions;
43
+ export type VectorizeMatches = CloudflareVectorizeMatches;
44
+ export type VectorizeMatch = CloudflareVectorizeMatch;
45
+ export type VectorizeIndexInfo = CloudflareVectorizeIndexInfo;
46
+ export type VectorizeIndexDetails = CloudflareVectorizeIndexDetails;
47
+ export type VectorizeMutation =
48
+ | CloudflareVectorizeAsyncMutation
49
+ | CloudflareVectorizeVectorMutation;
50
+ export type VectorizeValues = Float32Array | Float64Array | ReadonlyArray<number>;
51
+
52
+ interface VectorizeRuntimeBinding {
53
+ readonly describe: () => Promise<VectorizeIndexInfo | VectorizeIndexDetails>;
54
+ readonly query: (
55
+ vector: Float32Array | Float64Array | number[],
56
+ options?: VectorizeQueryOptions,
57
+ ) => Promise<VectorizeMatches>;
58
+ readonly queryById?: (
59
+ vectorId: string,
60
+ options?: VectorizeQueryOptions,
61
+ ) => Promise<VectorizeMatches>;
62
+ readonly insert: (vectors: Array<VectorizeVector>) => Promise<VectorizeMutation>;
63
+ readonly upsert: (vectors: Array<VectorizeVector>) => Promise<VectorizeMutation>;
64
+ readonly deleteByIds: (ids: Array<string>) => Promise<VectorizeMutation>;
65
+ readonly getByIds: (ids: Array<string>) => Promise<Array<VectorizeVector>>;
66
+ }
67
+
68
+ export interface VectorizeClient {
69
+ readonly describe: Effect.Effect<
70
+ VectorizeIndexInfo | VectorizeIndexDetails,
71
+ VectorizeOperationError
72
+ >;
73
+ readonly query: (
74
+ vector: VectorizeValues,
75
+ options?: VectorizeQueryOptions,
76
+ ) => Effect.Effect<VectorizeMatches, VectorizeOperationError>;
77
+ readonly queryById: (
78
+ vectorId: string,
79
+ options?: VectorizeQueryOptions,
80
+ ) => Effect.Effect<VectorizeMatches, VectorizeOperationError>;
81
+ readonly insert: (
82
+ vectors: ReadonlyArray<VectorizeVector>,
83
+ ) => Effect.Effect<VectorizeMutation, VectorizeOperationError>;
84
+ readonly upsert: (
85
+ vectors: ReadonlyArray<VectorizeVector>,
86
+ ) => Effect.Effect<VectorizeMutation, VectorizeOperationError>;
87
+ readonly deleteByIds: (
88
+ ids: ReadonlyArray<string>,
89
+ ) => Effect.Effect<VectorizeMutation, VectorizeOperationError>;
90
+ readonly delete: (
91
+ ids: ReadonlyArray<string>,
92
+ ) => Effect.Effect<VectorizeMutation, VectorizeOperationError>;
93
+ readonly getByIds: (
94
+ ids: ReadonlyArray<string>,
95
+ ) => Effect.Effect<ReadonlyArray<VectorizeVector>, VectorizeOperationError>;
96
+ readonly unsafeRaw: Effect.Effect<VectorizeBinding>;
97
+ readonly definition: VectorizeDefinition;
98
+ }
99
+
100
+ declare const VectorizeServiceTypeId: unique symbol;
101
+
102
+ /** Nominal service marker for Vectorize services created with {@link make}. */
103
+ export interface VectorizeService<Id extends string> {
104
+ readonly [VectorizeServiceTypeId]: {
105
+ readonly id: Id;
106
+ };
107
+ }
108
+
109
+ export type LayerOptions = {
110
+ readonly binding: string;
111
+ };
112
+
113
+ export interface TagClass<Self, Id extends string> extends Context.ServiceClass<
114
+ Self,
115
+ Id,
116
+ VectorizeClient
117
+ > {
118
+ readonly id: Id;
119
+ readonly layer: (
120
+ options: LayerOptions,
121
+ ) => Layer.Layer<
122
+ Self,
123
+ Binding.BindingNotFoundError | Binding.BindingValidationError,
124
+ WorkerEnvironment
125
+ >;
126
+ }
127
+
128
+ const vectorizeError = (binding: string, operation: string, cause: unknown) =>
129
+ new VectorizeOperationError({ binding, operation, cause });
130
+
131
+ const tryVectorizePromise = <A>(
132
+ binding: string,
133
+ operation: string,
134
+ evaluate: () => Promise<A>,
135
+ ): Effect.Effect<A, VectorizeOperationError> =>
136
+ Effect.tryPromise({
137
+ try: evaluate,
138
+ catch: (cause) => vectorizeError(binding, operation, cause),
139
+ });
140
+
141
+ const hasFunction = (value: object, key: string): boolean =>
142
+ typeof Reflect.get(value, key) === "function";
143
+
144
+ export const isVectorizeBinding = (value: unknown): value is VectorizeBinding =>
145
+ typeof value === "object" &&
146
+ value !== null &&
147
+ hasFunction(value, "describe") &&
148
+ hasFunction(value, "query") &&
149
+ hasFunction(value, "insert") &&
150
+ hasFunction(value, "upsert") &&
151
+ hasFunction(value, "deleteByIds") &&
152
+ hasFunction(value, "getByIds");
153
+
154
+ export const makeClient =
155
+ (definition: VectorizeDefinition) =>
156
+ (index: VectorizeBinding): VectorizeClient => {
157
+ const runtime = index as VectorizeRuntimeBinding;
158
+ const deleteByIds = (ids: ReadonlyArray<string>) =>
159
+ tryVectorizePromise(definition.binding, "deleteByIds", () => runtime.deleteByIds([...ids]));
160
+
161
+ return {
162
+ definition,
163
+ describe: tryVectorizePromise(definition.binding, "describe", () => runtime.describe()),
164
+ query: (vector, options) =>
165
+ tryVectorizePromise(definition.binding, "query", () =>
166
+ runtime.query(vector as Float32Array | Float64Array | number[], options),
167
+ ),
168
+ queryById: (vectorId, options) =>
169
+ runtime.queryById !== undefined
170
+ ? tryVectorizePromise(definition.binding, "queryById", () =>
171
+ runtime.queryById!(vectorId, options),
172
+ )
173
+ : Effect.fail(
174
+ vectorizeError(
175
+ definition.binding,
176
+ "queryById",
177
+ new TypeError("Vectorize binding does not expose queryById()"),
178
+ ),
179
+ ),
180
+ insert: (vectors) =>
181
+ tryVectorizePromise(definition.binding, "insert", () => runtime.insert([...vectors])),
182
+ upsert: (vectors) =>
183
+ tryVectorizePromise(definition.binding, "upsert", () => runtime.upsert([...vectors])),
184
+ deleteByIds,
185
+ delete: deleteByIds,
186
+ getByIds: (ids) =>
187
+ tryVectorizePromise(definition.binding, "getByIds", () => runtime.getByIds([...ids])),
188
+ unsafeRaw: Effect.succeed(index),
189
+ };
190
+ };
191
+
192
+ export const layer = <Self>(
193
+ tag: Context.Service<Self, VectorizeClient>,
194
+ definition: VectorizeDefinition,
195
+ ) =>
196
+ Binding.layer(tag, definition.binding, isVectorizeBinding, makeClient(definition), {
197
+ expected: expectedVectorizeBinding,
198
+ });
199
+
200
+ export const make = <Id extends string>(id: Id) => Tag<VectorizeService<Id>>()<Id>(id);
201
+
202
+ export const Tag =
203
+ <Self>() =>
204
+ <Id extends string>(id: Id) => {
205
+ const tag = Context.Service<Self, VectorizeClient>()(id);
206
+
207
+ const makeLayer = (definition: LayerOptions) => layer(tag, definition);
208
+
209
+ return Object.assign(tag, {
210
+ id,
211
+ layer: makeLayer,
212
+ }) as TagClass<Self, Id>;
213
+ };
package/src/Worker.ts CHANGED
@@ -10,6 +10,7 @@ import type * as Rpc from "./Rpc";
10
10
  import type * as RpcDefinition from "./RpcDefinition";
11
11
  import type * as ServiceBinding from "./ServiceBinding";
12
12
  import * as WorkerDefinition from "./WorkerDefinition";
13
+ import * as CloudflareClock from "./internal/Clock";
13
14
  import * as Entrypoint from "./internal/Entrypoint";
14
15
  import { fromExecutionContext, type RunWaitUntilEffect } from "./internal/WorkerContext";
15
16
 
@@ -241,6 +242,7 @@ export function make<
241
242
  Promise.reject(new Error("WorkerContext runtime is not initialized"));
242
243
 
243
244
  const services = Layer.mergeAll(
245
+ CloudflareClock.layer,
244
246
  Layer.succeed(ExecutionContext, ctx),
245
247
  ConfigProvider.layer(Effect.succeed(WorkerConfig.providerFromEnv(env))),
246
248
  Layer.succeed(