effect-cf 0.7.0 → 0.8.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 +8 -0
- package/README.md +91 -0
- package/dist/Hyperdrive-By6DrSS_.d.mts +140 -0
- package/dist/Hyperdrive-LuQaVhXU.mjs +86 -0
- package/dist/HyperdrivePg.d.mts +14 -0
- package/dist/HyperdrivePg.mjs +13 -0
- package/dist/index.d.mts +257 -200
- package/dist/index.mjs +251 -190
- package/package.json +13 -1
- package/src/D1.ts +3 -59
- package/src/Hyperdrive.ts +82 -0
- package/src/HyperdrivePg.ts +27 -0
- package/src/Images.ts +332 -0
- package/src/Kv.ts +0 -62
- package/src/R2.ts +230 -0
- package/src/index.ts +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# effect-cf
|
|
2
2
|
|
|
3
|
+
## 0.8.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#22](https://github.com/danieljvdm/effect-cf/pull/22) [`24c27ee`](https://github.com/danieljvdm/effect-cf/commit/24c27ee2884aacc72ab51ab5a208b795e1fa9738) Thanks [@danieljvdm](https://github.com/danieljvdm)! - Add Effect-native R2 bucket, Hyperdrive, and Cloudflare Images binding tags, including optional hosted Images operations, ArrayBuffer image inputs, and an optional Hyperdrive Postgres SQL layer integration.
|
|
8
|
+
|
|
9
|
+
- [#22](https://github.com/danieljvdm/effect-cf/pull/22) [`24c27ee`](https://github.com/danieljvdm/effect-cf/commit/24c27ee2884aacc72ab51ab5a208b795e1fa9738) Thanks [@danieljvdm](https://github.com/danieljvdm)! - Remove non-canonical static operation helpers from existing KV and D1 resource bindings. Use yielded binding services for resource operations; D1 keeps `sqlLayer()`.
|
|
10
|
+
|
|
3
11
|
## 0.7.0
|
|
4
12
|
|
|
5
13
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -32,6 +32,9 @@ Runtime creation belongs at Cloudflare entrypoints, not inside binding helpers.
|
|
|
32
32
|
- `DurableObjectWebSocket` - WebSocket upgrade helpers for Durable Objects
|
|
33
33
|
- `Kv` - typed KV namespace helper
|
|
34
34
|
- `D1` - typed D1 database binding helper with an `@effect/sql-d1` backed SQL layer
|
|
35
|
+
- `R2` - typed R2 bucket binding helper with Effect-wrapped object and multipart operations
|
|
36
|
+
- `Hyperdrive` - typed Hyperdrive binding helper for connection strings and optional Postgres SQL integration
|
|
37
|
+
- `Images` - typed Cloudflare Images binding helper with transformation APIs and optional hosted image operations
|
|
35
38
|
- `Queue` - typed Queue producer/consumer tags plus client and error types
|
|
36
39
|
- `Workflow` - typed Workflow entrypoints, steps, starter clients, and instance types
|
|
37
40
|
- `Rpc` - Cloudflare RPC type helpers and scoped disposal utilities
|
|
@@ -115,6 +118,94 @@ Producers should usually use `const queue = yield* AvatarQueue` and then call `q
|
|
|
115
118
|
|
|
116
119
|
Queue handlers run inline failures through Cloudflare's normal retry path. If background work scheduled with `WorkerContext.waitUntil(...)` should also make the batch retry, use `WorkerContext.waitUntilPropagating(...)` or `waitUntil(..., { mode: "propagate" })`; the default `waitUntil` mode observes and logs failures without rejecting the native `waitUntil` promise.
|
|
117
120
|
|
|
121
|
+
## R2 Example
|
|
122
|
+
|
|
123
|
+
R2 bucket tags expose Cloudflare object operations as Effects and map nullable reads to `Option`.
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
import { Effect, Layer, Option } from "effect";
|
|
127
|
+
import { R2 } from "effect-cf";
|
|
128
|
+
|
|
129
|
+
class ArtifactBucket extends R2.Tag<ArtifactBucket>()("ArtifactBucket") {}
|
|
130
|
+
|
|
131
|
+
export const ArtifactBucketLayer = ArtifactBucket.layer({ binding: "ARTIFACT_BUCKET" });
|
|
132
|
+
|
|
133
|
+
export const writeArtifact = (key: string, body: string) =>
|
|
134
|
+
Effect.gen(function* () {
|
|
135
|
+
const bucket = yield* ArtifactBucket;
|
|
136
|
+
yield* bucket.put(key, body, {
|
|
137
|
+
httpMetadata: { contentType: "application/json" },
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
export const readArtifact = (key: string) =>
|
|
142
|
+
Effect.gen(function* () {
|
|
143
|
+
const bucket = yield* ArtifactBucket;
|
|
144
|
+
const object = yield* bucket.get(key);
|
|
145
|
+
return Option.isSome(object) ? yield* Effect.promise(() => object.value.text()) : undefined;
|
|
146
|
+
});
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Use `createMultipartUpload(...)` or `resumeMultipartUpload(...)` for large objects; returned upload handles wrap `uploadPart`, `complete`, and `abort` in Effect.
|
|
150
|
+
|
|
151
|
+
## Hyperdrive Example
|
|
152
|
+
|
|
153
|
+
Hyperdrive tags expose the binding `connectionString` directly on the yielded service.
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
import { Effect } from "effect";
|
|
157
|
+
import { Hyperdrive } from "effect-cf";
|
|
158
|
+
|
|
159
|
+
class AppDatabase extends Hyperdrive.Tag<AppDatabase>()("AppDatabase") {}
|
|
160
|
+
|
|
161
|
+
export const AppDatabaseLayer = AppDatabase.layer({ binding: "HYPERDRIVE" });
|
|
162
|
+
|
|
163
|
+
export const databaseUrl = Effect.gen(function* () {
|
|
164
|
+
const hyperdrive = yield* AppDatabase;
|
|
165
|
+
return hyperdrive.connectionString;
|
|
166
|
+
});
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
If your Worker uses Postgres via `@effect/sql-pg`, install that driver and use the optional subpath integration:
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
import { Hyperdrive } from "effect-cf";
|
|
173
|
+
import * as HyperdrivePg from "effect-cf/hyperdrive-pg";
|
|
174
|
+
|
|
175
|
+
class AppDatabase extends Hyperdrive.Tag<AppDatabase>()("AppDatabase") {}
|
|
176
|
+
|
|
177
|
+
export const SqlLive = HyperdrivePg.layer(AppDatabase, { binding: "HYPERDRIVE" });
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
The Postgres integration builds an Effect `PgClient` from Hyperdrive's generated connection string with `PgClient.makeClient`. It intentionally does not expose app-side pool options; Hyperdrive manages the underlying database pool.
|
|
181
|
+
|
|
182
|
+
## Images Example
|
|
183
|
+
|
|
184
|
+
Images tags expose `info`, `input`, optional hosted image operations, and composable transform/draw steps.
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
import { Effect } from "effect";
|
|
188
|
+
import { Images } from "effect-cf";
|
|
189
|
+
|
|
190
|
+
class AvatarImages extends Images.Tag<AvatarImages>()("AvatarImages") {}
|
|
191
|
+
|
|
192
|
+
export const AvatarImagesLayer = AvatarImages.layer({ binding: "IMAGES" });
|
|
193
|
+
|
|
194
|
+
export const resizeAvatar = (image: Images.ImageInputValue) =>
|
|
195
|
+
Effect.gen(function* () {
|
|
196
|
+
const images = yield* AvatarImages;
|
|
197
|
+
const result = yield* images.process(
|
|
198
|
+
Images.transform(Images.empty, { width: 256, height: 256 }),
|
|
199
|
+
{
|
|
200
|
+
stream: image,
|
|
201
|
+
outputOptions: { format: "image/webp" },
|
|
202
|
+
},
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
return yield* result.response;
|
|
206
|
+
});
|
|
207
|
+
```
|
|
208
|
+
|
|
118
209
|
## Workflow Example
|
|
119
210
|
|
|
120
211
|
Workflow definitions type the payload and result. Runtime handlers can access `Workflow.WorkflowEvent`, use durable `Workflow.step(...)`, and use normal binding services inside steps.
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { Config, ConfigProvider, Context, Effect, Layer } from "effect";
|
|
2
|
+
import * as _$effect_Types0 from "effect/Types";
|
|
3
|
+
import * as _$effect_Cause0 from "effect/Cause";
|
|
4
|
+
import * as _$effect_Redacted0 from "effect/Redacted";
|
|
5
|
+
import * as _$effect_Layer0 from "effect/Layer";
|
|
6
|
+
|
|
7
|
+
//#region src/Environment.d.ts
|
|
8
|
+
/** Cloudflare worker environment object (`env`). */
|
|
9
|
+
type WorkerEnv = Cloudflare.Env;
|
|
10
|
+
declare const WorkerEnvironment_base: Context.ServiceClass<WorkerEnvironment, "effect-cf/WorkerEnvironment", Cloudflare.Env>;
|
|
11
|
+
/**
|
|
12
|
+
* Context service for reading worker bindings from the current `env` object.
|
|
13
|
+
*/
|
|
14
|
+
declare class WorkerEnvironment extends WorkerEnvironment_base {}
|
|
15
|
+
type ScalarConfigValue = string | number | boolean;
|
|
16
|
+
type ScalarConfigKey = Extract<{ readonly [Key in keyof Cloudflare.Env]-?: NonNullable<Cloudflare.Env[Key]> extends ScalarConfigValue ? Key : never }[keyof Cloudflare.Env], string>;
|
|
17
|
+
/**
|
|
18
|
+
* Effect `Config` helpers for scalar Cloudflare vars and secrets declared on
|
|
19
|
+
* `Cloudflare.Env` / generated `worker-configuration.d.ts`.
|
|
20
|
+
*
|
|
21
|
+
* Users still author their app config explicitly with Effect `Config`:
|
|
22
|
+
*
|
|
23
|
+
* ```ts
|
|
24
|
+
* import { Config, Effect } from "effect";
|
|
25
|
+
* import { WorkerConfig } from "effect-cf";
|
|
26
|
+
*
|
|
27
|
+
* const AppConfig = Config.all({
|
|
28
|
+
* databaseUrl: WorkerConfig.redacted("DATABASE_URL"),
|
|
29
|
+
* port: WorkerConfig.integer("PORT").pipe(Config.withDefault(8787)),
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* const program = Effect.gen(function* () {
|
|
33
|
+
* const config = yield* AppConfig;
|
|
34
|
+
* // ...
|
|
35
|
+
* }).pipe(Effect.provide(WorkerConfig.layer));
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* Keys are constrained to scalar `Cloudflare.Env` properties (`string`,
|
|
39
|
+
* `number`, or `boolean`, including optional scalar properties). Binding
|
|
40
|
+
* objects such as `KVNamespace`, `DurableObjectNamespace`, and service
|
|
41
|
+
* bindings are intentionally excluded; keep using the package binding helpers
|
|
42
|
+
* for those live resources.
|
|
43
|
+
*/
|
|
44
|
+
declare namespace WorkerConfig {
|
|
45
|
+
/** Scalar env value types supported by the typed config key helpers. */
|
|
46
|
+
type Scalar = ScalarConfigValue;
|
|
47
|
+
/** Scalar keys available on the current consumer's `Cloudflare.Env`. */
|
|
48
|
+
type Key = ScalarConfigKey;
|
|
49
|
+
/** Read a scalar Cloudflare var or secret as a string. */
|
|
50
|
+
const string: <const Name extends Key>(name: Name) => Config.Config<string>;
|
|
51
|
+
/** Read a scalar Cloudflare secret as a redacted string. */
|
|
52
|
+
const redacted: <const Name extends Key>(name: Name) => Config.Config<_$effect_Redacted0.Redacted<string>>;
|
|
53
|
+
/** Read a scalar Cloudflare var or secret as a number. */
|
|
54
|
+
const number: <const Name extends Key>(name: Name) => Config.Config<number>;
|
|
55
|
+
/** Read a scalar Cloudflare var or secret as an integer. */
|
|
56
|
+
const integer: <const Name extends Key>(name: Name) => Config.Config<number>;
|
|
57
|
+
/** Read a scalar Cloudflare var or secret as a boolean. */
|
|
58
|
+
const boolean: <const Name extends Key>(name: Name) => Config.Config<boolean>;
|
|
59
|
+
/** Build a `ConfigProvider` from a Cloudflare worker `env` object. */
|
|
60
|
+
const providerFromEnv: (env: WorkerEnv) => ConfigProvider.ConfigProvider;
|
|
61
|
+
/**
|
|
62
|
+
* Build a `ConfigProvider` from the current `WorkerEnvironment` with a custom
|
|
63
|
+
* conversion function.
|
|
64
|
+
*/
|
|
65
|
+
const providerWith: (makeProvider: (env: WorkerEnv) => ConfigProvider.ConfigProvider) => Effect.Effect<ConfigProvider.ConfigProvider, never, WorkerEnvironment>;
|
|
66
|
+
/** Build a `ConfigProvider` from the current `WorkerEnvironment`. */
|
|
67
|
+
const provider: Effect.Effect<ConfigProvider.ConfigProvider, never, WorkerEnvironment>;
|
|
68
|
+
/**
|
|
69
|
+
* Replace the active Effect `ConfigProvider` with one backed by the current
|
|
70
|
+
* Cloudflare worker `env` object.
|
|
71
|
+
*/
|
|
72
|
+
const providerLayer: _$effect_Layer0.Layer<never, never, WorkerEnvironment>;
|
|
73
|
+
/** Alias for `providerLayer` for concise use in worker layers. */
|
|
74
|
+
const layer: _$effect_Layer0.Layer<never, never, WorkerEnvironment>;
|
|
75
|
+
/** Build a `ConfigProvider` layer with a custom `env` conversion function. */
|
|
76
|
+
const layerWith: (makeProvider: (env: WorkerEnv) => ConfigProvider.ConfigProvider) => _$effect_Layer0.Layer<never, never, WorkerEnvironment>;
|
|
77
|
+
}
|
|
78
|
+
declare namespace Binding_d_exports {
|
|
79
|
+
export { BindingNotFoundError, BindingService, BindingValidationError, Service, TypeId, layer$1 as layer };
|
|
80
|
+
}
|
|
81
|
+
/** Internal type id marker used by binding helper services. */
|
|
82
|
+
declare const TypeId: "effect-cf/Binding";
|
|
83
|
+
declare const BindingNotFoundError_base: new <A extends Record<string, any> = {}>(args: _$effect_Types0.VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => _$effect_Cause0.YieldableError & {
|
|
84
|
+
readonly _tag: "BindingNotFoundError";
|
|
85
|
+
} & Readonly<A>;
|
|
86
|
+
/** Error raised when a configured binding does not exist on `env`. */
|
|
87
|
+
declare class BindingNotFoundError extends BindingNotFoundError_base<{
|
|
88
|
+
readonly binding: string;
|
|
89
|
+
}> {}
|
|
90
|
+
declare const BindingValidationError_base: new <A extends Record<string, any> = {}>(args: _$effect_Types0.VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => _$effect_Cause0.YieldableError & {
|
|
91
|
+
readonly _tag: "BindingValidationError";
|
|
92
|
+
} & Readonly<A>;
|
|
93
|
+
/** Error raised when a binding exists but does not match the expected shape. */
|
|
94
|
+
declare class BindingValidationError extends BindingValidationError_base<{
|
|
95
|
+
readonly binding: string;
|
|
96
|
+
}> {}
|
|
97
|
+
/**
|
|
98
|
+
* Creates a Context tag + layer for reading and validating a Cloudflare binding.
|
|
99
|
+
*/
|
|
100
|
+
interface BindingService<Self, Id extends string, Service> extends Context.ServiceClass<Self, Id, Service> {
|
|
101
|
+
readonly [TypeId]: typeof TypeId;
|
|
102
|
+
readonly binding: string;
|
|
103
|
+
readonly layer: Layer.Layer<Self, BindingNotFoundError | BindingValidationError, WorkerEnvironment>;
|
|
104
|
+
}
|
|
105
|
+
declare const layer$1: <Self, Resource, Service = Resource>(tag: Context.Service<Self, Service>, binding: string, isResource: (value: unknown) => value is Resource, wrap?: (resource: Resource) => Service) => Layer.Layer<Self, BindingNotFoundError | BindingValidationError, WorkerEnvironment>;
|
|
106
|
+
declare const Service: <Self>() => <Id extends string, Resource, Service = Resource>(id: Id, binding: string, isResource: (value: unknown) => value is Resource, wrap?: (resource: Resource) => Service) => BindingService<Self, Id, Service>;
|
|
107
|
+
declare namespace Hyperdrive_d_exports {
|
|
108
|
+
export { HyperdriveClient, HyperdriveDefinition, HyperdriveService, LayerOptions, Tag, TagClass, isHyperdrive, layer, make, makeClient };
|
|
109
|
+
}
|
|
110
|
+
/** Typed Hyperdrive binding definition. */
|
|
111
|
+
interface HyperdriveDefinition {
|
|
112
|
+
/** Binding name as configured in `wrangler.jsonc`. */
|
|
113
|
+
readonly binding: string;
|
|
114
|
+
}
|
|
115
|
+
interface HyperdriveClient {
|
|
116
|
+
readonly connectionString: string;
|
|
117
|
+
readonly unsafeRaw: Effect.Effect<Hyperdrive>;
|
|
118
|
+
readonly definition: HyperdriveDefinition;
|
|
119
|
+
}
|
|
120
|
+
declare const HyperdriveServiceTypeId: unique symbol;
|
|
121
|
+
/** Nominal service marker for Hyperdrive services created with {@link make}. */
|
|
122
|
+
interface HyperdriveService<Id extends string> {
|
|
123
|
+
readonly [HyperdriveServiceTypeId]: {
|
|
124
|
+
readonly id: Id;
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
type LayerOptions = {
|
|
128
|
+
readonly binding: string;
|
|
129
|
+
};
|
|
130
|
+
interface TagClass<Self, Id extends string> extends Context.ServiceClass<Self, Id, HyperdriveClient> {
|
|
131
|
+
readonly id: Id;
|
|
132
|
+
readonly layer: (options: LayerOptions) => Layer.Layer<Self, BindingNotFoundError | BindingValidationError, WorkerEnvironment>;
|
|
133
|
+
}
|
|
134
|
+
declare const isHyperdrive: (value: unknown) => value is Hyperdrive;
|
|
135
|
+
declare const makeClient: (definition: HyperdriveDefinition) => (hyperdrive: Hyperdrive) => HyperdriveClient;
|
|
136
|
+
declare const layer: <Self>(tag: Context.Service<Self, HyperdriveClient>, definition: HyperdriveDefinition) => Layer.Layer<Self, BindingNotFoundError | BindingValidationError, WorkerEnvironment>;
|
|
137
|
+
declare const make: <Id extends string>(id: Id) => TagClass<HyperdriveService<Id>, Id>;
|
|
138
|
+
declare const Tag: <Self>() => <Id extends string>(id: Id) => TagClass<Self, Id>;
|
|
139
|
+
//#endregion
|
|
140
|
+
export { BindingService as a, WorkerConfig as c, BindingNotFoundError as i, WorkerEnv as l, LayerOptions as n, BindingValidationError as o, TagClass as r, Binding_d_exports as s, Hyperdrive_d_exports as t, WorkerEnvironment as u };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { t as __exportAll } from "./chunk-CfYAbeIz.mjs";
|
|
2
|
+
import { Config, ConfigProvider, Context, Data, Effect, Layer } from "effect";
|
|
3
|
+
//#region src/Environment.ts
|
|
4
|
+
/**
|
|
5
|
+
* Context service for reading worker bindings from the current `env` object.
|
|
6
|
+
*/
|
|
7
|
+
var WorkerEnvironment = class extends Context.Service()("effect-cf/WorkerEnvironment") {};
|
|
8
|
+
let WorkerConfig;
|
|
9
|
+
(function(_WorkerConfig) {
|
|
10
|
+
_WorkerConfig.string = (name) => Config.string(name);
|
|
11
|
+
_WorkerConfig.redacted = (name) => Config.redacted(name);
|
|
12
|
+
_WorkerConfig.number = (name) => Config.number(name);
|
|
13
|
+
_WorkerConfig.integer = (name) => Config.int(name);
|
|
14
|
+
_WorkerConfig.boolean = (name) => Config.boolean(name);
|
|
15
|
+
const providerFromEnv = _WorkerConfig.providerFromEnv = (env) => ConfigProvider.fromUnknown(env);
|
|
16
|
+
const providerWith = _WorkerConfig.providerWith = (makeProvider) => Effect.map(WorkerEnvironment.asEffect(), makeProvider);
|
|
17
|
+
const provider = _WorkerConfig.provider = providerWith(providerFromEnv);
|
|
18
|
+
_WorkerConfig.layer = _WorkerConfig.providerLayer = ConfigProvider.layer(provider);
|
|
19
|
+
_WorkerConfig.layerWith = (makeProvider) => ConfigProvider.layer(providerWith(makeProvider));
|
|
20
|
+
})(WorkerConfig || (WorkerConfig = {}));
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/Binding.ts
|
|
23
|
+
var Binding_exports = /* @__PURE__ */ __exportAll({
|
|
24
|
+
BindingNotFoundError: () => BindingNotFoundError,
|
|
25
|
+
BindingValidationError: () => BindingValidationError,
|
|
26
|
+
Service: () => Service,
|
|
27
|
+
TypeId: () => TypeId,
|
|
28
|
+
layer: () => layer$1
|
|
29
|
+
});
|
|
30
|
+
/** Internal type id marker used by binding helper services. */
|
|
31
|
+
const TypeId = "effect-cf/Binding";
|
|
32
|
+
/** Error raised when a configured binding does not exist on `env`. */
|
|
33
|
+
var BindingNotFoundError = class extends Data.TaggedError("BindingNotFoundError") {};
|
|
34
|
+
/** Error raised when a binding exists but does not match the expected shape. */
|
|
35
|
+
var BindingValidationError = class extends Data.TaggedError("BindingValidationError") {};
|
|
36
|
+
const isPropertyTarget = (value) => (typeof value === "object" || typeof value === "function") && value !== null;
|
|
37
|
+
const getBinding = (env, binding, isResource) => Effect.gen(function* () {
|
|
38
|
+
if (!isPropertyTarget(env)) return yield* Effect.fail(new BindingValidationError({ binding }));
|
|
39
|
+
const resource = Reflect.get(env, binding);
|
|
40
|
+
if (resource === void 0) return yield* Effect.fail(new BindingNotFoundError({ binding }));
|
|
41
|
+
if (!isResource(resource)) return yield* Effect.fail(new BindingValidationError({ binding }));
|
|
42
|
+
return resource;
|
|
43
|
+
});
|
|
44
|
+
const layer$1 = (tag, binding, isResource, wrap) => Layer.effect(tag, Effect.gen(function* () {
|
|
45
|
+
const resource = yield* getBinding(yield* WorkerEnvironment, binding, isResource);
|
|
46
|
+
return wrap === void 0 ? resource : wrap(resource);
|
|
47
|
+
}));
|
|
48
|
+
const Service = () => (id, binding, isResource, wrap) => {
|
|
49
|
+
const tag = Context.Service()(id);
|
|
50
|
+
const serviceLayer = layer$1(tag, binding, isResource, wrap);
|
|
51
|
+
return Object.assign(tag, {
|
|
52
|
+
[TypeId]: TypeId,
|
|
53
|
+
binding,
|
|
54
|
+
layer: serviceLayer
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/Hyperdrive.ts
|
|
59
|
+
var Hyperdrive_exports = /* @__PURE__ */ __exportAll({
|
|
60
|
+
Tag: () => Tag,
|
|
61
|
+
isHyperdrive: () => isHyperdrive,
|
|
62
|
+
layer: () => layer,
|
|
63
|
+
make: () => make,
|
|
64
|
+
makeClient: () => makeClient
|
|
65
|
+
});
|
|
66
|
+
const isHyperdrive = (value) => {
|
|
67
|
+
if (typeof value !== "object" || value === null) return false;
|
|
68
|
+
return typeof value.connectionString === "string";
|
|
69
|
+
};
|
|
70
|
+
const makeClient = (definition) => (hyperdrive) => ({
|
|
71
|
+
definition,
|
|
72
|
+
connectionString: hyperdrive.connectionString,
|
|
73
|
+
unsafeRaw: Effect.succeed(hyperdrive)
|
|
74
|
+
});
|
|
75
|
+
const layer = (tag, definition) => layer$1(tag, definition.binding, isHyperdrive, makeClient(definition));
|
|
76
|
+
const make = (id) => Tag()(id);
|
|
77
|
+
const Tag = () => (id) => {
|
|
78
|
+
const tag = Context.Service()(id);
|
|
79
|
+
const makeLayer = (definition) => layer(tag, definition);
|
|
80
|
+
return Object.assign(tag, {
|
|
81
|
+
id,
|
|
82
|
+
layer: makeLayer
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
//#endregion
|
|
86
|
+
export { WorkerConfig as a, layer$1 as i, Binding_exports as n, WorkerEnvironment as o, Service as r, Hyperdrive_exports as t };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { i as BindingNotFoundError, n as LayerOptions, o as BindingValidationError, r as TagClass, u as WorkerEnvironment } from "./Hyperdrive-By6DrSS_.mjs";
|
|
2
|
+
import { Layer } from "effect";
|
|
3
|
+
import { PgClient } from "@effect/sql-pg";
|
|
4
|
+
import * as _$effect_unstable_sql_SqlClient0 from "effect/unstable/sql/SqlClient";
|
|
5
|
+
import * as _$effect_unstable_sql_SqlError0 from "effect/unstable/sql/SqlError";
|
|
6
|
+
import * as _$effect_Scope0 from "effect/Scope";
|
|
7
|
+
|
|
8
|
+
//#region src/HyperdrivePg.d.ts
|
|
9
|
+
type PgLayerOptions = Omit<PgClient.PgClientConfig & {
|
|
10
|
+
readonly acquireForStream?: boolean;
|
|
11
|
+
}, "url" | "host" | "port" | "path" | "ssl" | "database" | "username" | "password" | "stream">;
|
|
12
|
+
declare const layer: <Self, Id extends string>(tag: TagClass<Self, Id>, binding: LayerOptions, options?: PgLayerOptions) => Layer.Layer<PgClient.PgClient | _$effect_unstable_sql_SqlClient0.SqlClient, BindingNotFoundError | BindingValidationError | _$effect_unstable_sql_SqlError0.SqlError, WorkerEnvironment | Exclude<Exclude<Self, _$effect_Scope0.Scope>, Self>>;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { PgLayerOptions, layer };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import "./Hyperdrive-LuQaVhXU.mjs";
|
|
2
|
+
import { Effect, Layer, Redacted } from "effect";
|
|
3
|
+
import { PgClient } from "@effect/sql-pg";
|
|
4
|
+
//#region src/HyperdrivePg.ts
|
|
5
|
+
const layer = (tag, binding, options) => Layer.unwrap(Effect.gen(function* () {
|
|
6
|
+
const hyperdrive = yield* tag;
|
|
7
|
+
return PgClient.layerFrom(PgClient.makeClient({
|
|
8
|
+
...options,
|
|
9
|
+
url: Redacted.make(hyperdrive.connectionString)
|
|
10
|
+
}));
|
|
11
|
+
})).pipe(Layer.provide(tag.layer(binding)));
|
|
12
|
+
//#endregion
|
|
13
|
+
export { layer };
|