effect-cf 0.5.0 → 0.6.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 +6 -0
- package/README.md +7 -1
- package/dist/index.d.mts +173 -345
- package/dist/index.mjs +210 -103
- package/package.json +1 -1
- package/src/Binding.ts +21 -5
- package/src/DurableObjectNamespace.ts +227 -32
- package/src/Kv.ts +133 -80
- package/src/QueueBinding.ts +51 -18
- package/src/ServiceBinding.ts +147 -84
package/dist/index.mjs
CHANGED
|
@@ -46,13 +46,11 @@ const getBinding = (env, binding, isResource) => Effect.gen(function* () {
|
|
|
46
46
|
if (!isResource(resource)) return yield* Effect.fail(new BindingValidationError({ binding }));
|
|
47
47
|
return resource;
|
|
48
48
|
});
|
|
49
|
-
|
|
50
|
-
* Creates a Context tag + layer for reading and validating a Cloudflare binding.
|
|
51
|
-
*/
|
|
52
|
-
const Service$6 = () => (id, binding, isResource) => {
|
|
49
|
+
const Service$6 = () => (id, binding, isResource, wrap) => {
|
|
53
50
|
const tag = Context.Service()(id);
|
|
54
51
|
const layer = Layer.effect(tag, Effect.gen(function* () {
|
|
55
|
-
|
|
52
|
+
const resource = yield* getBinding(yield* WorkerEnvironment, binding, isResource);
|
|
53
|
+
return wrap === void 0 ? resource : wrap(resource);
|
|
56
54
|
}));
|
|
57
55
|
return Object.assign(tag, {
|
|
58
56
|
[TypeId$6]: TypeId$6,
|
|
@@ -171,32 +169,43 @@ const make$10 = (id, definition) => Service$4()(id, definition);
|
|
|
171
169
|
* Builds an Effect service around a Cloudflare Queue producer binding.
|
|
172
170
|
*/
|
|
173
171
|
const Service$4 = () => (id, definition) => {
|
|
174
|
-
const tag = Service$6()(id, definition.binding, (value) => isQueue(value));
|
|
175
172
|
const encodeMessage = Schema.encodeEffect(definition.message);
|
|
173
|
+
const makeClient = (queue) => ({
|
|
174
|
+
send: Effect.fnUntraced(function* (message, options) {
|
|
175
|
+
const encoded = yield* encodeMessage(message);
|
|
176
|
+
yield* tryQueuePromise(definition.binding, "send", () => queue.send(encoded, options));
|
|
177
|
+
}),
|
|
178
|
+
sendBatch: Effect.fnUntraced(function* (messages, options) {
|
|
179
|
+
const encodedMessages = [];
|
|
180
|
+
for (const message of messages) encodedMessages.push({
|
|
181
|
+
...message,
|
|
182
|
+
body: yield* encodeMessage(message.body)
|
|
183
|
+
});
|
|
184
|
+
yield* tryQueuePromise(definition.binding, "sendBatch", () => queue.sendBatch(encodedMessages, options));
|
|
185
|
+
}),
|
|
186
|
+
metrics: () => tryQueuePromise(definition.binding, "metrics", () => queue.metrics()),
|
|
187
|
+
unsafeRaw: Effect.succeed(queue)
|
|
188
|
+
});
|
|
189
|
+
const tag = Service$6()(id, definition.binding, (value) => isQueue(value), makeClient);
|
|
176
190
|
const send = Effect.fnUntraced(function* (message, options) {
|
|
177
|
-
|
|
178
|
-
const encoded = yield* encodeMessage(message);
|
|
179
|
-
return yield* tryQueuePromise(definition.binding, "send", () => queue.send(encoded, options));
|
|
191
|
+
yield* (yield* tag).send(message, options);
|
|
180
192
|
});
|
|
181
193
|
const sendBatch = Effect.fnUntraced(function* (messages, options) {
|
|
182
|
-
|
|
183
|
-
const encodedMessages = [];
|
|
184
|
-
for (const message of messages) encodedMessages.push({
|
|
185
|
-
...message,
|
|
186
|
-
body: yield* encodeMessage(message.body)
|
|
187
|
-
});
|
|
188
|
-
return yield* tryQueuePromise(definition.binding, "sendBatch", () => queue.sendBatch(encodedMessages, options));
|
|
194
|
+
yield* (yield* tag).sendBatch(messages, options);
|
|
189
195
|
});
|
|
190
196
|
const metrics = Effect.fnUntraced(function* () {
|
|
191
|
-
|
|
192
|
-
|
|
197
|
+
return yield* (yield* tag).metrics();
|
|
198
|
+
});
|
|
199
|
+
const unsafeRaw = Effect.fnUntraced(function* () {
|
|
200
|
+
return yield* (yield* tag).unsafeRaw;
|
|
193
201
|
});
|
|
194
202
|
return Object.assign(tag, {
|
|
195
203
|
[TypeId$4]: TypeId$4,
|
|
196
204
|
binding: definition.binding,
|
|
197
205
|
send,
|
|
198
206
|
sendBatch,
|
|
199
|
-
metrics
|
|
207
|
+
metrics,
|
|
208
|
+
unsafeRaw
|
|
200
209
|
});
|
|
201
210
|
};
|
|
202
211
|
//#endregion
|
|
@@ -504,46 +513,63 @@ var ServiceBindingRpcError = class extends Data.TaggedError("ServiceBindingRpcEr
|
|
|
504
513
|
* ```
|
|
505
514
|
*/
|
|
506
515
|
const Service$3 = () => (id, definition) => {
|
|
507
|
-
const
|
|
508
|
-
|
|
509
|
-
const service = yield* tag;
|
|
510
|
-
return yield* Effect.tryPromise({
|
|
516
|
+
const makeClient = (service) => {
|
|
517
|
+
const fetch = (input, init) => Effect.tryPromise({
|
|
511
518
|
try: () => service.fetch(input, init),
|
|
512
519
|
catch: (cause) => new ServiceBindingFetchError({
|
|
513
520
|
binding: definition.binding,
|
|
514
521
|
cause
|
|
515
522
|
})
|
|
516
523
|
});
|
|
524
|
+
const rpc = (method, ...args) => Effect.gen(function* () {
|
|
525
|
+
const methodName = String(method);
|
|
526
|
+
return yield* invokeRpcMethod(service, method, definition.definition === void 0 ? args : yield* encodeArgs(definition.definition, methodName, args).pipe(Effect.mapError((cause) => new ServiceBindingRpcError({
|
|
527
|
+
binding: definition.binding,
|
|
528
|
+
method: methodName,
|
|
529
|
+
cause
|
|
530
|
+
}))), (cause) => new ServiceBindingRpcError({
|
|
531
|
+
binding: definition.binding,
|
|
532
|
+
method: methodName,
|
|
533
|
+
cause
|
|
534
|
+
}));
|
|
535
|
+
});
|
|
536
|
+
const call = (method, ...args) => Effect.gen(function* () {
|
|
537
|
+
const methodName = String(method);
|
|
538
|
+
const value = yield* resolve(yield* rpc(method, ...args)).pipe(Effect.mapError((cause) => new ServiceBindingRpcError({
|
|
539
|
+
binding: definition.binding,
|
|
540
|
+
method: methodName,
|
|
541
|
+
cause
|
|
542
|
+
})));
|
|
543
|
+
if (definition.definition === void 0) return value;
|
|
544
|
+
return yield* decodeSuccess(definition.definition, methodName, value).pipe(Effect.mapError((cause) => new ServiceBindingRpcError({
|
|
545
|
+
binding: definition.binding,
|
|
546
|
+
method: methodName,
|
|
547
|
+
cause
|
|
548
|
+
})));
|
|
549
|
+
});
|
|
550
|
+
const scopedCall = (method, ...args) => Effect.gen(function* () {
|
|
551
|
+
return yield* scoped(yield* rpc(method, ...args));
|
|
552
|
+
});
|
|
553
|
+
const directMethods = makeDirectMethods$1(definition.definition, call);
|
|
554
|
+
return Object.assign(directMethods, {
|
|
555
|
+
fetch,
|
|
556
|
+
rpc,
|
|
557
|
+
call,
|
|
558
|
+
scopedCall
|
|
559
|
+
});
|
|
560
|
+
};
|
|
561
|
+
const tag = Service$6()(id, definition.binding, (value) => typeof value === "object" && value !== null && "fetch" in value, makeClient);
|
|
562
|
+
const fetch = (input, init) => Effect.gen(function* () {
|
|
563
|
+
return yield* (yield* tag).fetch(input, init);
|
|
517
564
|
});
|
|
518
565
|
const rpc = (method, ...args) => Effect.gen(function* () {
|
|
519
|
-
|
|
520
|
-
const methodName = String(method);
|
|
521
|
-
return yield* invokeRpcMethod(service, method, definition.definition === void 0 ? args : yield* encodeArgs(definition.definition, methodName, args).pipe(Effect.mapError((cause) => new ServiceBindingRpcError({
|
|
522
|
-
binding: definition.binding,
|
|
523
|
-
method: methodName,
|
|
524
|
-
cause
|
|
525
|
-
}))), (cause) => new ServiceBindingRpcError({
|
|
526
|
-
binding: definition.binding,
|
|
527
|
-
method: methodName,
|
|
528
|
-
cause
|
|
529
|
-
}));
|
|
566
|
+
return yield* (yield* tag).rpc(method, ...args);
|
|
530
567
|
});
|
|
531
568
|
const call = (method, ...args) => Effect.gen(function* () {
|
|
532
|
-
|
|
533
|
-
const value = yield* resolve(yield* rpc(method, ...args)).pipe(Effect.mapError((cause) => new ServiceBindingRpcError({
|
|
534
|
-
binding: definition.binding,
|
|
535
|
-
method: methodName,
|
|
536
|
-
cause
|
|
537
|
-
})));
|
|
538
|
-
if (definition.definition === void 0) return value;
|
|
539
|
-
return yield* decodeSuccess(definition.definition, methodName, value).pipe(Effect.mapError((cause) => new ServiceBindingRpcError({
|
|
540
|
-
binding: definition.binding,
|
|
541
|
-
method: methodName,
|
|
542
|
-
cause
|
|
543
|
-
})));
|
|
569
|
+
return yield* (yield* tag).call(method, ...args);
|
|
544
570
|
});
|
|
545
571
|
const scopedCall = (method, ...args) => Effect.gen(function* () {
|
|
546
|
-
return yield*
|
|
572
|
+
return yield* (yield* tag).scopedCall(method, ...args);
|
|
547
573
|
});
|
|
548
574
|
const directMethods = makeDirectMethods$1(definition.definition, call);
|
|
549
575
|
return Object.assign(tag, directMethods, {
|
|
@@ -1089,24 +1115,87 @@ var DurableObjectFetchError = class extends Data.TaggedError("DurableObjectFetch
|
|
|
1089
1115
|
const Service$2 = () => (id, definition) => {
|
|
1090
1116
|
const hasFunction = (value, key) => typeof Reflect.get(value, key) === "function";
|
|
1091
1117
|
const isDurableObjectNamespaceClient = (value) => typeof value === "object" && value !== null && hasFunction(value, "getByName") && hasFunction(value, "get") && hasFunction(value, "idFromName") && hasFunction(value, "idFromString") && hasFunction(value, "newUniqueId") && hasFunction(value, "jurisdiction");
|
|
1092
|
-
const
|
|
1118
|
+
const makeClient = (namespace) => {
|
|
1119
|
+
const newUniqueId = (options) => Effect.sync(() => namespace.newUniqueId(options));
|
|
1120
|
+
const idFromName = (name) => Effect.sync(() => namespace.idFromName(name));
|
|
1121
|
+
const idFromString = (id) => Effect.sync(() => namespace.idFromString(id));
|
|
1122
|
+
const get = (id, options) => Effect.sync(() => namespace.get(id, options));
|
|
1123
|
+
const getByName = (name, options) => Effect.sync(() => namespace.getByName(name, options));
|
|
1124
|
+
const jurisdiction = (value) => Effect.sync(() => namespace.jurisdiction(value));
|
|
1125
|
+
const fetch = (stub, input, init) => Effect.tryPromise({
|
|
1126
|
+
try: () => stub.fetch(input, init),
|
|
1127
|
+
catch: (cause) => new DurableObjectFetchError({
|
|
1128
|
+
binding: definition.binding,
|
|
1129
|
+
cause
|
|
1130
|
+
})
|
|
1131
|
+
});
|
|
1132
|
+
const rpc = (stub, method, ...args) => Effect.gen(function* () {
|
|
1133
|
+
const methodName = String(method);
|
|
1134
|
+
return yield* invokeRpcMethod(stub, method, definition.definition === void 0 ? args : yield* encodeArgs(definition.definition, methodName, args).pipe(Effect.mapError((cause) => new DurableObjectRpcError({
|
|
1135
|
+
binding: definition.binding,
|
|
1136
|
+
method: methodName,
|
|
1137
|
+
cause
|
|
1138
|
+
}))), (cause) => new DurableObjectRpcError({
|
|
1139
|
+
binding: definition.binding,
|
|
1140
|
+
method: methodName,
|
|
1141
|
+
cause
|
|
1142
|
+
}));
|
|
1143
|
+
});
|
|
1144
|
+
const call = (stub, method, ...args) => Effect.gen(function* () {
|
|
1145
|
+
const methodName = String(method);
|
|
1146
|
+
const value = yield* resolve(yield* rpc(stub, method, ...args)).pipe(Effect.mapError((cause) => new DurableObjectRpcError({
|
|
1147
|
+
binding: definition.binding,
|
|
1148
|
+
method: methodName,
|
|
1149
|
+
cause
|
|
1150
|
+
})));
|
|
1151
|
+
if (definition.definition === void 0) return value;
|
|
1152
|
+
return yield* decodeSuccess(definition.definition, methodName, value).pipe(Effect.mapError((cause) => new DurableObjectRpcError({
|
|
1153
|
+
binding: definition.binding,
|
|
1154
|
+
method: methodName,
|
|
1155
|
+
cause
|
|
1156
|
+
})));
|
|
1157
|
+
});
|
|
1158
|
+
const scopedCall = (stub, method, ...args) => Effect.gen(function* () {
|
|
1159
|
+
return yield* scoped(yield* rpc(stub, method, ...args));
|
|
1160
|
+
});
|
|
1161
|
+
const directMethods = makeDirectMethods(definition.definition, {
|
|
1162
|
+
call,
|
|
1163
|
+
fetch,
|
|
1164
|
+
get,
|
|
1165
|
+
getByName
|
|
1166
|
+
});
|
|
1167
|
+
return Object.assign(directMethods, {
|
|
1168
|
+
newUniqueId,
|
|
1169
|
+
idFromName,
|
|
1170
|
+
idFromString,
|
|
1171
|
+
get,
|
|
1172
|
+
getByName,
|
|
1173
|
+
jurisdiction,
|
|
1174
|
+
fetch,
|
|
1175
|
+
rpc,
|
|
1176
|
+
call,
|
|
1177
|
+
scopedCall,
|
|
1178
|
+
unsafeRaw: Effect.succeed(namespace)
|
|
1179
|
+
});
|
|
1180
|
+
};
|
|
1181
|
+
const tag = Service$6()(id, definition.binding, (value) => isDurableObjectNamespaceClient(value), makeClient);
|
|
1093
1182
|
const newUniqueId = Effect.fnUntraced(function* (options) {
|
|
1094
|
-
return (yield* tag).newUniqueId(options);
|
|
1183
|
+
return yield* (yield* tag).newUniqueId(options);
|
|
1095
1184
|
});
|
|
1096
1185
|
const idFromName = Effect.fnUntraced(function* (name) {
|
|
1097
|
-
return (yield* tag).idFromName(name);
|
|
1186
|
+
return yield* (yield* tag).idFromName(name);
|
|
1098
1187
|
});
|
|
1099
1188
|
const idFromString = Effect.fnUntraced(function* (id) {
|
|
1100
|
-
return (yield* tag).idFromString(id);
|
|
1189
|
+
return yield* (yield* tag).idFromString(id);
|
|
1101
1190
|
});
|
|
1102
1191
|
const get = Effect.fnUntraced(function* (id, options) {
|
|
1103
|
-
return (yield* tag).get(id, options);
|
|
1192
|
+
return yield* (yield* tag).get(id, options);
|
|
1104
1193
|
});
|
|
1105
1194
|
const getByName = Effect.fnUntraced(function* (name, options) {
|
|
1106
|
-
return (yield* tag).getByName(name, options);
|
|
1195
|
+
return yield* (yield* tag).getByName(name, options);
|
|
1107
1196
|
});
|
|
1108
1197
|
const jurisdiction = Effect.fnUntraced(function* (value) {
|
|
1109
|
-
return (yield* tag).jurisdiction(value);
|
|
1198
|
+
return yield* (yield* tag).jurisdiction(value);
|
|
1110
1199
|
});
|
|
1111
1200
|
const fetch = (stub, input, init) => Effect.tryPromise({
|
|
1112
1201
|
try: () => stub.fetch(input, init),
|
|
@@ -1144,6 +1233,9 @@ const Service$2 = () => (id, definition) => {
|
|
|
1144
1233
|
const scopedCall = (stub, method, ...args) => Effect.gen(function* () {
|
|
1145
1234
|
return yield* scoped(yield* rpc(stub, method, ...args));
|
|
1146
1235
|
});
|
|
1236
|
+
const unsafeRaw = Effect.fnUntraced(function* () {
|
|
1237
|
+
return yield* (yield* tag).unsafeRaw;
|
|
1238
|
+
});
|
|
1147
1239
|
const directMethods = makeDirectMethods(definition.definition, {
|
|
1148
1240
|
call,
|
|
1149
1241
|
fetch,
|
|
@@ -1162,7 +1254,8 @@ const Service$2 = () => (id, definition) => {
|
|
|
1162
1254
|
fetch,
|
|
1163
1255
|
rpc,
|
|
1164
1256
|
call,
|
|
1165
|
-
scopedCall
|
|
1257
|
+
scopedCall,
|
|
1258
|
+
unsafeRaw
|
|
1166
1259
|
});
|
|
1167
1260
|
};
|
|
1168
1261
|
const makeDirectMethods = (rpcDefinition, helpers) => {
|
|
@@ -1853,69 +1946,83 @@ const Tag$2 = () => (id, definition) => {
|
|
|
1853
1946
|
* ```
|
|
1854
1947
|
*/
|
|
1855
1948
|
const Service$1 = () => (id, definition) => {
|
|
1856
|
-
const tag = Service$6()(id, definition.binding, (value) => {
|
|
1857
|
-
if (typeof value !== "object" || value === null) return false;
|
|
1858
|
-
const resource = value;
|
|
1859
|
-
return typeof resource.get === "function" && typeof resource.put === "function" && typeof resource.delete === "function" && typeof resource.getWithMetadata === "function" && typeof resource.list === "function";
|
|
1860
|
-
});
|
|
1861
1949
|
const encodeKey = Schema.encodeEffect(definition.key);
|
|
1862
1950
|
const decodeKey = Schema.decodeUnknownEffect(definition.key);
|
|
1863
1951
|
const encodeValue = Schema.encodeEffect(Schema.fromJsonString(Schema.toCodecJson(definition.value)));
|
|
1864
1952
|
const decodeValue = Schema.decodeUnknownEffect(Schema.fromJsonString(Schema.toCodecJson(definition.value)));
|
|
1953
|
+
const makeClient = (kv) => ({
|
|
1954
|
+
definition,
|
|
1955
|
+
put: Effect.fnUntraced(function* (key, value, options) {
|
|
1956
|
+
const keyEncoded = yield* encodeKey(key);
|
|
1957
|
+
const valueEncoded = yield* encodeValue(value);
|
|
1958
|
+
yield* tryKvPromise(definition.binding, "put", () => kv.put(keyEncoded, valueEncoded, options));
|
|
1959
|
+
}),
|
|
1960
|
+
get: Effect.fnUntraced(function* (key) {
|
|
1961
|
+
const keyEncoded = yield* encodeKey(key);
|
|
1962
|
+
const valueEncoded = yield* tryKvPromise(definition.binding, "get", () => kv.get(keyEncoded));
|
|
1963
|
+
if (valueEncoded === null) return Option.none();
|
|
1964
|
+
return yield* decodeValue(valueEncoded).pipe(Effect.map(Option.some));
|
|
1965
|
+
}),
|
|
1966
|
+
getWithMetadata: Effect.fnUntraced(function* (key, metadataSchema) {
|
|
1967
|
+
const keyEncoded = yield* encodeKey(key);
|
|
1968
|
+
const result = yield* tryKvPromise(definition.binding, "getWithMetadata", () => kv.getWithMetadata(keyEncoded));
|
|
1969
|
+
if (result.value === null) return Option.none();
|
|
1970
|
+
const value = yield* decodeValue(result.value);
|
|
1971
|
+
const metadata = result.metadata === null ? Option.none() : Option.some(yield* Schema.decodeUnknownEffect(metadataSchema)(result.metadata));
|
|
1972
|
+
return Option.some({
|
|
1973
|
+
value,
|
|
1974
|
+
metadata,
|
|
1975
|
+
cacheStatus: maybeString(result.cacheStatus)
|
|
1976
|
+
});
|
|
1977
|
+
}),
|
|
1978
|
+
list: Effect.fnUntraced(function* (options) {
|
|
1979
|
+
const { metadataSchema, ...kvOptions } = options ?? {};
|
|
1980
|
+
const result = yield* tryKvPromise(definition.binding, "list", () => kv.list(kvOptions));
|
|
1981
|
+
const keys = [];
|
|
1982
|
+
for (const key of result.keys) {
|
|
1983
|
+
const decodedName = yield* decodeKey(key.name);
|
|
1984
|
+
const decodedMetadata = key.metadata === void 0 ? Option.none() : metadataSchema === void 0 ? Option.some(key.metadata) : Option.some(yield* Schema.decodeUnknownEffect(metadataSchema)(key.metadata));
|
|
1985
|
+
keys.push({
|
|
1986
|
+
name: decodedName,
|
|
1987
|
+
expiration: maybeNumber(key.expiration),
|
|
1988
|
+
metadata: decodedMetadata
|
|
1989
|
+
});
|
|
1990
|
+
}
|
|
1991
|
+
return {
|
|
1992
|
+
keys,
|
|
1993
|
+
listComplete: result.list_complete,
|
|
1994
|
+
cursor: maybeString("cursor" in result ? result.cursor : void 0),
|
|
1995
|
+
cacheStatus: maybeString(result.cacheStatus)
|
|
1996
|
+
};
|
|
1997
|
+
}),
|
|
1998
|
+
remove: Effect.fnUntraced(function* (key) {
|
|
1999
|
+
const keyEncoded = yield* encodeKey(key);
|
|
2000
|
+
yield* tryKvPromise(definition.binding, "delete", () => kv.delete(keyEncoded));
|
|
2001
|
+
}),
|
|
2002
|
+
unsafeRaw: Effect.succeed(kv)
|
|
2003
|
+
});
|
|
2004
|
+
const tag = Service$6()(id, definition.binding, (value) => {
|
|
2005
|
+
if (typeof value !== "object" || value === null) return false;
|
|
2006
|
+
const resource = value;
|
|
2007
|
+
return typeof resource.get === "function" && typeof resource.put === "function" && typeof resource.delete === "function" && typeof resource.getWithMetadata === "function" && typeof resource.list === "function";
|
|
2008
|
+
}, makeClient);
|
|
1865
2009
|
const put = Effect.fnUntraced(function* (key, value, options) {
|
|
1866
|
-
|
|
1867
|
-
const keyEncoded = yield* encodeKey(key);
|
|
1868
|
-
const valueEncoded = yield* encodeValue(value);
|
|
1869
|
-
yield* tryKvPromise(definition.binding, "put", () => kv.put(keyEncoded, valueEncoded, options));
|
|
2010
|
+
yield* (yield* tag).put(key, value, options);
|
|
1870
2011
|
});
|
|
1871
2012
|
const get = Effect.fnUntraced(function* (key) {
|
|
1872
|
-
|
|
1873
|
-
const keyEncoded = yield* encodeKey(key);
|
|
1874
|
-
const valueEncoded = yield* tryKvPromise(definition.binding, "get", () => kv.get(keyEncoded));
|
|
1875
|
-
if (valueEncoded === null) return Option.none();
|
|
1876
|
-
return yield* decodeValue(valueEncoded).pipe(Effect.map(Option.some));
|
|
2013
|
+
return yield* (yield* tag).get(key);
|
|
1877
2014
|
});
|
|
1878
2015
|
const getWithMetadata = Effect.fnUntraced(function* (key, metadataSchema) {
|
|
1879
|
-
|
|
1880
|
-
const keyEncoded = yield* encodeKey(key);
|
|
1881
|
-
const result = yield* tryKvPromise(definition.binding, "getWithMetadata", () => kv.getWithMetadata(keyEncoded));
|
|
1882
|
-
if (result.value === null) return Option.none();
|
|
1883
|
-
const value = yield* decodeValue(result.value);
|
|
1884
|
-
const metadata = result.metadata === null ? Option.none() : Option.some(yield* Schema.decodeUnknownEffect(metadataSchema)(result.metadata));
|
|
1885
|
-
return Option.some({
|
|
1886
|
-
value,
|
|
1887
|
-
metadata,
|
|
1888
|
-
cacheStatus: maybeString(result.cacheStatus)
|
|
1889
|
-
});
|
|
2016
|
+
return yield* (yield* tag).getWithMetadata(key, metadataSchema);
|
|
1890
2017
|
});
|
|
1891
2018
|
const list = Effect.fnUntraced(function* (options) {
|
|
1892
|
-
|
|
1893
|
-
const { metadataSchema, ...kvOptions } = options ?? {};
|
|
1894
|
-
const result = yield* tryKvPromise(definition.binding, "list", () => kv.list(kvOptions));
|
|
1895
|
-
const keys = [];
|
|
1896
|
-
for (const key of result.keys) {
|
|
1897
|
-
const decodedName = yield* decodeKey(key.name);
|
|
1898
|
-
const decodedMetadata = key.metadata === void 0 ? Option.none() : metadataSchema === void 0 ? Option.some(key.metadata) : Option.some(yield* Schema.decodeUnknownEffect(metadataSchema)(key.metadata));
|
|
1899
|
-
keys.push({
|
|
1900
|
-
name: decodedName,
|
|
1901
|
-
expiration: maybeNumber(key.expiration),
|
|
1902
|
-
metadata: decodedMetadata
|
|
1903
|
-
});
|
|
1904
|
-
}
|
|
1905
|
-
return {
|
|
1906
|
-
keys,
|
|
1907
|
-
listComplete: result.list_complete,
|
|
1908
|
-
cursor: maybeString("cursor" in result ? result.cursor : void 0),
|
|
1909
|
-
cacheStatus: maybeString(result.cacheStatus)
|
|
1910
|
-
};
|
|
2019
|
+
return yield* (yield* tag).list(options);
|
|
1911
2020
|
});
|
|
1912
2021
|
const remove = Effect.fnUntraced(function* (key) {
|
|
1913
|
-
|
|
1914
|
-
const keyEncoded = yield* encodeKey(key);
|
|
1915
|
-
yield* tryKvPromise(definition.binding, "delete", () => kv.delete(keyEncoded));
|
|
2022
|
+
yield* (yield* tag).remove(key);
|
|
1916
2023
|
});
|
|
1917
2024
|
const unsafeRaw = Effect.fnUntraced(function* () {
|
|
1918
|
-
return yield* tag;
|
|
2025
|
+
return yield* (yield* tag).unsafeRaw;
|
|
1919
2026
|
});
|
|
1920
2027
|
return Object.assign(tag, {
|
|
1921
2028
|
[TypeId$1]: TypeId$1,
|
package/package.json
CHANGED
package/src/Binding.ts
CHANGED
|
@@ -45,20 +45,36 @@ const getBinding = <Resource>(
|
|
|
45
45
|
/**
|
|
46
46
|
* Creates a Context tag + layer for reading and validating a Cloudflare binding.
|
|
47
47
|
*/
|
|
48
|
+
export interface BindingService<Self, Id extends string, Service> extends Context.ServiceClass<
|
|
49
|
+
Self,
|
|
50
|
+
Id,
|
|
51
|
+
Service
|
|
52
|
+
> {
|
|
53
|
+
readonly [TypeId]: typeof TypeId;
|
|
54
|
+
readonly binding: string;
|
|
55
|
+
readonly layer: Layer.Layer<
|
|
56
|
+
Self,
|
|
57
|
+
BindingNotFoundError | BindingValidationError,
|
|
58
|
+
WorkerEnvironment
|
|
59
|
+
>;
|
|
60
|
+
}
|
|
61
|
+
|
|
48
62
|
export const Service =
|
|
49
63
|
<Self>() =>
|
|
50
|
-
<Id extends string, Resource>(
|
|
64
|
+
<Id extends string, Resource, Service = Resource>(
|
|
51
65
|
id: Id,
|
|
52
66
|
binding: string,
|
|
53
67
|
isResource: (value: unknown) => value is Resource,
|
|
54
|
-
|
|
55
|
-
|
|
68
|
+
wrap?: (resource: Resource) => Service,
|
|
69
|
+
): BindingService<Self, Id, Service> => {
|
|
70
|
+
const tag = Context.Service<Self, Service>()(id);
|
|
56
71
|
|
|
57
72
|
const layer = Layer.effect(
|
|
58
73
|
tag,
|
|
59
74
|
Effect.gen(function* () {
|
|
60
75
|
const env = yield* WorkerEnvironment;
|
|
61
|
-
|
|
76
|
+
const resource = yield* getBinding(env, binding, isResource);
|
|
77
|
+
return wrap === undefined ? (resource as unknown as Service) : wrap(resource);
|
|
62
78
|
}),
|
|
63
79
|
);
|
|
64
80
|
|
|
@@ -66,5 +82,5 @@ export const Service =
|
|
|
66
82
|
[TypeId]: TypeId,
|
|
67
83
|
binding,
|
|
68
84
|
layer,
|
|
69
|
-
})
|
|
85
|
+
}) as BindingService<Self, Id, Service>;
|
|
70
86
|
};
|