effect-cf 0.28.1 → 0.30.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.
@@ -1,5 +1,5 @@
1
1
  import { c as WorkerEnvironment, n as BindingService, r as BindingValidationError, s as WorkerEnv, t as BindingNotFoundError } from "./Binding-xJJJPmiD.mjs";
2
- import { Cause, Context, Effect, Layer, Option, Predicate, Schema, Scope } from "effect";
2
+ import { Cause, Context, Duration, Effect, Layer, Option, Predicate, Schema, Scope } from "effect";
3
3
  import { HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
4
4
  import { RpcStub, RpcTarget, WorkerEntrypoint } from "cloudflare:workers";
5
5
  declare namespace DurableObjectStorage_d_exports {
@@ -84,6 +84,8 @@ interface DurableObjectTransaction {
84
84
  rollback(): StorageEffect<void>;
85
85
  getAlarm(options?: globalThis.DurableObjectGetAlarmOptions): StorageEffect<number | null>;
86
86
  setAlarm(scheduledTime: number | Date, options?: globalThis.DurableObjectSetAlarmOptions): StorageEffect<void>;
87
+ /** Schedules the alarm after a delay measured by the Effect clock. */
88
+ setAlarmAfter(delay: Duration.Input, options?: globalThis.DurableObjectSetAlarmOptions): StorageEffect<void>;
87
89
  deleteAlarm(options?: globalThis.DurableObjectSetAlarmOptions): StorageEffect<void>;
88
90
  }
89
91
  /**
@@ -110,6 +112,8 @@ interface DurableObjectStorage {
110
112
  deleteAll(options?: globalThis.DurableObjectPutOptions): StorageEffect<void>;
111
113
  getAlarm(options?: globalThis.DurableObjectGetAlarmOptions): StorageEffect<number | null>;
112
114
  setAlarm(scheduledTime: number | Date, options?: globalThis.DurableObjectSetAlarmOptions): StorageEffect<void>;
115
+ /** Schedules the alarm after a delay measured by the Effect clock. */
116
+ setAlarmAfter(delay: Duration.Input, options?: globalThis.DurableObjectSetAlarmOptions): StorageEffect<void>;
113
117
  deleteAlarm(options?: globalThis.DurableObjectSetAlarmOptions): StorageEffect<void>;
114
118
  /**
115
119
  * SQLite-backed Durable Object storage only.
@@ -0,0 +1,222 @@
1
+ import { c as WorkerEnvironment, r as BindingValidationError, t as BindingNotFoundError } from "./Binding-xJJJPmiD.mjs";
2
+ import { n as ContainerStartOptions, r as ContainerStopSignal } from "./ContainerNamespace-CFjiLw8b.mjs";
3
+ import { Context, Effect, Layer, Option, Stream } from "effect";
4
+ import { BackupOptions, BackupOptions as BackupOptions$1, CheckChangesOptions, CheckChangesOptions as CheckChangesOptions$1, CheckChangesResult, CheckChangesResult as CheckChangesResult$1, CreateTerminalOptions, CreateTerminalOptions as CreateTerminalOptions$1, DirectoryBackup, DirectoryBackup as DirectoryBackup$1, ExecOptions, ExecOptions as ExecOptions$1, FileWatchSSEEvent, FileWatchSSEEvent as FileWatchSSEEvent$1, ISandbox, ISandbox as ISandbox$1, ListFilesOptions, ListFilesOptions as ListFilesOptions$1, MountBucketOptions, MountBucketOptions as MountBucketOptions$1, ProcessExit, ProcessExit as ProcessExit$1, ProcessLogEvent, ProcessLogEvent as ProcessLogEvent$1, ProcessLogsOptions, ProcessLogsOptions as ProcessLogsOptions$1, ProcessOutput, ProcessOutput as ProcessOutput$1, ProcessOutputOptions, ProcessOutputOptions as ProcessOutputOptions$1, ProcessStatus, ProcessStatus as ProcessStatus$1, RestoreBackupResult, RestoreBackupResult as RestoreBackupResult$1, SandboxCommand, SandboxCommand as SandboxCommand$1, SandboxOptions, SandboxOptions as SandboxOptions$1, SandboxProcess, SandboxProcess as SandboxProcess$1, Terminal, Terminal as Terminal$1, TerminalOutputCursor, TerminalOutputCursor as TerminalOutputCursor$1, TerminalOutputEvent, TerminalOutputEvent as TerminalOutputEvent$1, TerminalOutputOptions, TerminalOutputOptions as TerminalOutputOptions$1, TerminalSnapshot, TerminalSnapshot as TerminalSnapshot$1, TunnelInfo, TunnelInfo as TunnelInfo$1, TunnelOptions, TunnelOptions as TunnelOptions$1, WaitForExitOptions, WaitForExitOptions as WaitForExitOptions$1, WaitForLogOptions, WaitForLogOptions as WaitForLogOptions$1, WaitForLogResult, WaitForLogResult as WaitForLogResult$1, WaitForPortOptions, WaitForPortOptions as WaitForPortOptions$1, WatchOptions, WatchOptions as WatchOptions$1 } from "@cloudflare/sandbox";
5
+ //#region src/Sandbox.d.ts
6
+ /** Sandbox namespace binding metadata. */
7
+ interface SandboxDefinition {
8
+ /** Binding name as configured in `wrangler.jsonc`. */
9
+ readonly binding: string;
10
+ }
11
+ declare const SandboxOperationError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
12
+ readonly _tag: "SandboxOperationError";
13
+ } & Readonly<A>;
14
+ /** Failure raised when invoking a sandbox operation. */
15
+ declare class SandboxOperationError extends SandboxOperationError_base<{
16
+ readonly binding: string;
17
+ readonly instance: string;
18
+ readonly operation: string;
19
+ readonly cause: unknown;
20
+ }> {
21
+ get message(): string;
22
+ }
23
+ /**
24
+ * Structural Durable Object namespace shape required by `getSandbox()`.
25
+ *
26
+ * This is structural so importing this module does not require
27
+ * `@cloudflare/sandbox` at runtime; the package is loaded lazily when a
28
+ * sandbox instance is first requested.
29
+ */
30
+ interface SandboxNamespaceResource {
31
+ idFromName(name: string): globalThis.DurableObjectId;
32
+ get(id: globalThis.DurableObjectId, options?: globalThis.DurableObjectNamespaceGetDurableObjectOptions): globalThis.DurableObjectStub;
33
+ }
34
+ /** Result of `writeFile` as reported by the sandbox client. */
35
+ type WriteFileResult = Awaited<ReturnType<ISandbox$1["writeFile"]>>;
36
+ /** Result of `readFile` as reported by the sandbox client. */
37
+ type ReadFileResult = Awaited<ReturnType<ISandbox$1["readFile"]>>;
38
+ /** Result of `mkdir` as reported by the sandbox client. */
39
+ type MkdirResult = Awaited<ReturnType<ISandbox$1["mkdir"]>>;
40
+ /** Result of `deleteFile` as reported by the sandbox client. */
41
+ type DeleteFileResult = Awaited<ReturnType<ISandbox$1["deleteFile"]>>;
42
+ /** Result of `renameFile` as reported by the sandbox client. */
43
+ type RenameFileResult = Awaited<ReturnType<ISandbox$1["renameFile"]>>;
44
+ /** Result of `moveFile` as reported by the sandbox client. */
45
+ type MoveFileResult = Awaited<ReturnType<ISandbox$1["moveFile"]>>;
46
+ /** Result of `listFiles` as reported by the sandbox client. */
47
+ type ListFilesResult = Awaited<ReturnType<ISandbox$1["listFiles"]>>;
48
+ /** Result of `exists` as reported by the sandbox client. */
49
+ type FileExistsResult = Awaited<ReturnType<ISandbox$1["exists"]>>;
50
+ /** Text encodings accepted by `readFile`. */
51
+ type ReadFileEncoding = "utf-8" | "utf8" | "base64";
52
+ /** Options accepted by `exposePort`. */
53
+ interface ExposePortOptions {
54
+ readonly name?: string;
55
+ readonly hostname: string;
56
+ readonly token?: string;
57
+ }
58
+ /** Preview URL information returned by `exposePort`. */
59
+ interface ExposedPort {
60
+ readonly url: string;
61
+ readonly port: number;
62
+ readonly name?: string;
63
+ }
64
+ /** Currently forwardable preview URL returned by `getExposedPorts`. */
65
+ interface ExposedPortStatus {
66
+ readonly url: string;
67
+ readonly port: number;
68
+ readonly status: "active";
69
+ }
70
+ /** Structural tunnel API surface exposed by a sandbox client. */
71
+ interface SandboxTunnelsResource {
72
+ get(port: number, options?: TunnelOptions$1): Promise<TunnelInfo$1>;
73
+ list(): Promise<Array<TunnelInfo$1>>;
74
+ destroy(portOrInfo: number | TunnelInfo$1): Promise<void>;
75
+ }
76
+ /**
77
+ * Structural surface of the client returned by `getSandbox()` that this
78
+ * module wraps: the `ISandbox` RPC contract plus the lifecycle, port, and
79
+ * tunnel methods the client proxy forwards to the Sandbox Durable Object.
80
+ */
81
+ interface SandboxClientResource extends ISandbox$1 {
82
+ start(options?: ContainerStartOptions): Promise<void>;
83
+ stop(signal?: ContainerStopSignal): Promise<void>;
84
+ destroy(): Promise<void>;
85
+ containerFetch(requestOrUrl: Request | string | URL, port?: number): Promise<Response>;
86
+ exposePort(port: number, options: ExposePortOptions): Promise<ExposedPort>;
87
+ unexposePort(port: number): Promise<void>;
88
+ getExposedPorts(hostname: string): Promise<Array<ExposedPortStatus>>;
89
+ isPortExposed(port: number): Promise<boolean>;
90
+ validatePortToken(port: number, token: string): Promise<boolean>;
91
+ readonly tunnels: SandboxTunnelsResource;
92
+ }
93
+ /** Effect-wrapped handle for one process started inside a sandbox. */
94
+ interface SandboxProcessHandle {
95
+ readonly id: string;
96
+ readonly pid: number;
97
+ readonly rawUnsafe: Effect.Effect<SandboxProcess$1>;
98
+ readonly status: Effect.Effect<ProcessStatus$1, SandboxOperationError>;
99
+ readonly exitCode: Effect.Effect<number, SandboxOperationError>;
100
+ readonly logs: (options?: Omit<ProcessLogsOptions$1, "signal">) => Stream.Stream<ProcessLogEvent$1, SandboxOperationError>;
101
+ readonly waitForLog: (pattern: string | RegExp, options?: Omit<WaitForLogOptions$1, "signal">) => Effect.Effect<WaitForLogResult$1, SandboxOperationError>;
102
+ readonly waitForExit: (options?: Omit<WaitForExitOptions$1, "signal">) => Effect.Effect<ProcessExit$1, SandboxOperationError>;
103
+ readonly output: (options?: Omit<ProcessOutputOptions$1, "signal">) => Effect.Effect<ProcessOutput$1<Uint8Array>, SandboxOperationError>;
104
+ readonly outputText: (options?: Omit<ProcessOutputOptions$1, "signal">) => Effect.Effect<ProcessOutput$1<string>, SandboxOperationError>;
105
+ readonly waitForPort: (port: number, options?: Omit<WaitForPortOptions$1, "signal">) => Effect.Effect<void, SandboxOperationError>;
106
+ readonly kill: (signal?: number) => Effect.Effect<void, SandboxOperationError>;
107
+ }
108
+ /** Effect-wrapped handle for one interactive terminal inside a sandbox. */
109
+ interface SandboxTerminalHandle {
110
+ readonly id: string;
111
+ readonly rawUnsafe: Effect.Effect<Terminal$1>;
112
+ readonly snapshot: Effect.Effect<TerminalSnapshot$1, SandboxOperationError>;
113
+ readonly write: (data: Uint8Array) => Effect.Effect<void, SandboxOperationError>;
114
+ readonly resize: (cols: number, rows: number) => Effect.Effect<void, SandboxOperationError>;
115
+ readonly output: (options?: Omit<TerminalOutputOptions$1, "signal">) => Stream.Stream<TerminalOutputEvent$1, SandboxOperationError>;
116
+ readonly waitForExit: (options?: Omit<WaitForExitOptions$1, "signal">) => Effect.Effect<ProcessExit$1, SandboxOperationError>;
117
+ readonly interrupt: Effect.Effect<void, SandboxOperationError>;
118
+ readonly terminate: Effect.Effect<void, SandboxOperationError>;
119
+ readonly connect: (request: Request, options?: {
120
+ readonly cursor?: TerminalOutputCursor$1;
121
+ readonly cols?: number;
122
+ readonly rows?: number;
123
+ }) => Effect.Effect<Response, SandboxOperationError>;
124
+ }
125
+ /** Effect-wrapped tunnel operations for one sandbox instance. */
126
+ interface SandboxTunnelsClient {
127
+ readonly get: (port: number, options?: TunnelOptions$1) => Effect.Effect<TunnelInfo$1, SandboxOperationError>;
128
+ readonly list: Effect.Effect<Array<TunnelInfo$1>, SandboxOperationError>;
129
+ readonly destroy: (portOrInfo: number | TunnelInfo$1) => Effect.Effect<void, SandboxOperationError>;
130
+ }
131
+ /** Effect-wrapped client for one named sandbox instance. */
132
+ interface SandboxInstanceClient {
133
+ readonly rawUnsafe: Effect.Effect<SandboxClientResource>;
134
+ readonly exec: (command: SandboxCommand$1, options?: ExecOptions$1) => Effect.Effect<SandboxProcessHandle, SandboxOperationError>;
135
+ readonly getProcess: (id: string) => Effect.Effect<Option.Option<SandboxProcessHandle>, SandboxOperationError>;
136
+ readonly listProcesses: Effect.Effect<Array<ProcessStatus$1>, SandboxOperationError>;
137
+ readonly writeFile: (path: string, content: string | ReadableStream<Uint8Array>, options?: {
138
+ readonly encoding?: string;
139
+ }) => Effect.Effect<WriteFileResult, SandboxOperationError>;
140
+ readonly readFile: (path: string, options?: {
141
+ readonly encoding?: ReadFileEncoding;
142
+ }) => Effect.Effect<ReadFileResult, SandboxOperationError>;
143
+ readonly readFileStream: (path: string) => Stream.Stream<Uint8Array, SandboxOperationError>;
144
+ readonly mkdir: (path: string, options?: {
145
+ readonly recursive?: boolean;
146
+ }) => Effect.Effect<MkdirResult, SandboxOperationError>;
147
+ readonly deleteFile: (path: string) => Effect.Effect<DeleteFileResult, SandboxOperationError>;
148
+ readonly renameFile: (oldPath: string, newPath: string) => Effect.Effect<RenameFileResult, SandboxOperationError>;
149
+ readonly moveFile: (sourcePath: string, destinationPath: string) => Effect.Effect<MoveFileResult, SandboxOperationError>;
150
+ readonly listFiles: (path: string, options?: ListFilesOptions$1) => Effect.Effect<ListFilesResult, SandboxOperationError>;
151
+ readonly exists: (path: string) => Effect.Effect<FileExistsResult, SandboxOperationError>;
152
+ readonly watch: (path: string, options?: WatchOptions$1) => Stream.Stream<FileWatchSSEEvent$1, SandboxOperationError>;
153
+ readonly checkChanges: (path: string, options?: CheckChangesOptions$1) => Effect.Effect<CheckChangesResult$1, SandboxOperationError>;
154
+ readonly setEnvVars: (envVars: Record<string, string | undefined>) => Effect.Effect<void, SandboxOperationError>;
155
+ readonly exposePort: (port: number, options: ExposePortOptions) => Effect.Effect<ExposedPort, SandboxOperationError>;
156
+ readonly unexposePort: (port: number) => Effect.Effect<void, SandboxOperationError>;
157
+ readonly getExposedPorts: (hostname: string) => Effect.Effect<Array<ExposedPortStatus>, SandboxOperationError>;
158
+ readonly isPortExposed: (port: number) => Effect.Effect<boolean, SandboxOperationError>;
159
+ readonly validatePortToken: (port: number, token: string) => Effect.Effect<boolean, SandboxOperationError>;
160
+ readonly containerFetch: (requestOrUrl: Request | string | URL, port?: number) => Effect.Effect<Response, SandboxOperationError>;
161
+ readonly wsConnect: (request: Request, port: number) => Effect.Effect<Response, SandboxOperationError>;
162
+ readonly mountBucket: (bucket: string, mountPath: string, options: MountBucketOptions$1) => Effect.Effect<void, SandboxOperationError>;
163
+ readonly unmountBucket: (mountPath: string) => Effect.Effect<void, SandboxOperationError>;
164
+ readonly createBackup: (options: BackupOptions$1) => Effect.Effect<DirectoryBackup$1, SandboxOperationError>;
165
+ readonly restoreBackup: (backup: DirectoryBackup$1) => Effect.Effect<RestoreBackupResult$1, SandboxOperationError>;
166
+ readonly createTerminal: (options: CreateTerminalOptions$1) => Effect.Effect<SandboxTerminalHandle, SandboxOperationError>;
167
+ readonly getTerminal: (id: string) => Effect.Effect<Option.Option<SandboxTerminalHandle>, SandboxOperationError>;
168
+ readonly listTerminals: Effect.Effect<Array<SandboxTerminalHandle>, SandboxOperationError>;
169
+ readonly tunnels: SandboxTunnelsClient;
170
+ readonly start: (options?: ContainerStartOptions) => Effect.Effect<void, SandboxOperationError>;
171
+ readonly stop: (signal?: ContainerStopSignal) => Effect.Effect<void, SandboxOperationError>;
172
+ readonly destroy: Effect.Effect<void, SandboxOperationError>;
173
+ }
174
+ /** Effect client for a Sandbox Durable Object namespace binding. */
175
+ interface SandboxNamespaceClient<Namespace extends SandboxNamespaceResource = SandboxNamespaceResource> {
176
+ readonly definition: SandboxDefinition;
177
+ readonly get: (name: string, options?: SandboxOptions$1) => Effect.Effect<SandboxInstanceClient, SandboxOperationError>;
178
+ readonly rawUnsafe: Effect.Effect<Namespace>;
179
+ }
180
+ type LayerOptions = {
181
+ readonly binding: string;
182
+ };
183
+ interface TagClass<Self, Id extends string, Namespace extends SandboxNamespaceResource = SandboxNamespaceResource> extends Context.ServiceClass<Self, `effect-cf/Sandbox/${Id}`, SandboxNamespaceClient<Namespace>> {
184
+ readonly id: Id;
185
+ readonly layer: (options: LayerOptions) => Layer.Layer<Self, BindingNotFoundError | BindingValidationError, WorkerEnvironment>;
186
+ readonly get: (name: string, options?: SandboxOptions$1) => Effect.Effect<SandboxInstanceClient, SandboxOperationError, Self>;
187
+ readonly rawUnsafe: Effect.Effect<Namespace, never, Self>;
188
+ }
189
+ /**
190
+ * Wraps an already-created sandbox client (the value returned by
191
+ * `getSandbox()` from `@cloudflare/sandbox`) into an Effect client.
192
+ *
193
+ * Prefer {@link Tag}/{@link make} with a layer for application code; this
194
+ * entry point exists for advanced composition and testing.
195
+ */
196
+ declare const fromSandboxClient: (client: SandboxClientResource, definition: SandboxDefinition, instance: string) => SandboxInstanceClient;
197
+ declare const isSandboxNamespaceResource: <Candidate>(value: Candidate) => value is Candidate & SandboxNamespaceResource;
198
+ declare const makeClient: (definition: SandboxDefinition) => <Namespace extends SandboxNamespaceResource>(namespace: Namespace) => SandboxNamespaceClient<Namespace>;
199
+ declare const layer: <Self, Namespace extends SandboxNamespaceResource>(tag: Context.Service<Self, SandboxNamespaceClient<Namespace>>, definition: SandboxDefinition) => Layer.Layer<Self, BindingNotFoundError | BindingValidationError, WorkerEnvironment>;
200
+ declare const make: <Id extends string>(id: Id) => TagClass<SandboxNamespaceService<Id>, Id, SandboxNamespaceResource>;
201
+ declare const SandboxNamespaceServiceTypeId: unique symbol;
202
+ /** Nominal service marker for Sandbox namespaces created with {@link make}. */
203
+ interface SandboxNamespaceService<Id extends string> {
204
+ readonly [SandboxNamespaceServiceTypeId]: {
205
+ readonly id: Id;
206
+ };
207
+ }
208
+ /** Creates a typed Effect service for a Cloudflare Sandbox namespace. */
209
+ declare const Tag: <Self, Namespace extends SandboxNamespaceResource = SandboxNamespaceResource>() => <Id extends string>(id: Id) => TagClass<Self, Id, Namespace>;
210
+ declare const Sandbox: typeof Tag;
211
+ /**
212
+ * Routes sandbox preview-URL requests (`https://<port>-<sandbox-id>-<token>.<host>`)
213
+ * to the owning sandbox, mirroring `proxyToSandbox` from `@cloudflare/sandbox`.
214
+ *
215
+ * Call this before any other routing in a Worker `fetch` handler; it resolves
216
+ * to `Option.none()` for requests that are not preview-URL traffic.
217
+ */
218
+ declare const proxyToSandbox: (request: Request<unknown, CfProperties<unknown>>, options?: {
219
+ readonly binding?: string;
220
+ } | undefined) => Effect.Effect<Option.Option<Response>, SandboxOperationError, WorkerEnvironment>;
221
+ //#endregion
222
+ export { type BackupOptions, type CheckChangesOptions, type CheckChangesResult, type CreateTerminalOptions, DeleteFileResult, type DirectoryBackup, type ExecOptions, ExposePortOptions, ExposedPort, ExposedPortStatus, FileExistsResult, type FileWatchSSEEvent, type ISandbox, LayerOptions, type ListFilesOptions, ListFilesResult, MkdirResult, type MountBucketOptions, MoveFileResult, type ProcessExit, type ProcessLogEvent, type ProcessLogsOptions, type ProcessOutput, type ProcessOutputOptions, type ProcessStatus, ReadFileEncoding, ReadFileResult, RenameFileResult, type RestoreBackupResult, Sandbox, SandboxClientResource, type SandboxCommand, SandboxDefinition, SandboxInstanceClient, SandboxNamespaceClient, SandboxNamespaceResource, SandboxNamespaceService, SandboxOperationError, type SandboxOptions, type SandboxProcess, SandboxProcessHandle, SandboxTerminalHandle, SandboxTunnelsClient, SandboxTunnelsResource, Tag, TagClass, type Terminal, type TerminalOutputCursor, type TerminalOutputEvent, type TerminalOutputOptions, type TerminalSnapshot, type TunnelInfo, type TunnelOptions, type WaitForExitOptions, type WaitForLogOptions, type WaitForLogResult, type WaitForPortOptions, type WatchOptions, WriteFileResult, fromSandboxClient, isSandboxNamespaceResource, layer, make, makeClient, proxyToSandbox };
@@ -0,0 +1,361 @@
1
+ import { a as WorkerEnvironment, t as causeMessage } from "./ErrorMessage-BM0K-Nik.mjs";
2
+ import { r as layer$1 } from "./Binding-pfilNJmP.mjs";
3
+ import { Context, Data, Effect, Option, Predicate, Stream } from "effect";
4
+ //#region src/Sandbox.ts
5
+ const expectedSandboxNamespace = "Sandbox Durable Object namespace binding with idFromName() and get()";
6
+ /** Failure raised when invoking a sandbox operation. */
7
+ var SandboxOperationError = class extends Data.TaggedError("SandboxOperationError") {
8
+ get message() {
9
+ return `Sandbox ${this.operation} failed for binding "${this.binding}" instance "${this.instance}": ${causeMessage(this.cause)}`;
10
+ }
11
+ };
12
+ const trySandboxPromise = (definition, instance, operation, evaluate) => Effect.tryPromise({
13
+ try: evaluate,
14
+ catch: (cause) => new SandboxOperationError({
15
+ binding: definition.binding,
16
+ instance,
17
+ operation,
18
+ cause
19
+ })
20
+ });
21
+ const sandboxStream = (definition, instance, operation, acquire) => Stream.unwrap(Effect.map(trySandboxPromise(definition, instance, operation, acquire), (readable) => Stream.fromReadableStream({
22
+ evaluate: () => readable,
23
+ onError: (cause) => new SandboxOperationError({
24
+ binding: definition.binding,
25
+ instance,
26
+ operation,
27
+ cause
28
+ })
29
+ })));
30
+ const decodeSseData = (payload) => {
31
+ if (payload === "[DONE]" || payload.trim() === "") return [];
32
+ try {
33
+ return [JSON.parse(payload)];
34
+ } catch {
35
+ return [];
36
+ }
37
+ };
38
+ /**
39
+ * Decodes the sandbox runtime's `data:`-framed Server-Sent Events byte stream
40
+ * into JSON event values, mirroring `parseSSEStream` from
41
+ * `@cloudflare/sandbox` without requiring the package at runtime.
42
+ */
43
+ const decodeSseEvents = (bytes) => bytes.pipe(Stream.decodeText(), Stream.splitLines, Stream.mapAccum(() => [], (pending, line) => {
44
+ if (line === "") return pending.length > 0 ? [[], decodeSseData(pending.join("\n"))] : [pending, []];
45
+ if (line.startsWith("data:")) {
46
+ const value = line.startsWith("data: ") ? line.slice(6) : line.slice(5);
47
+ return [[...pending, value], []];
48
+ }
49
+ return [pending, []];
50
+ }, { onHalt: (pending) => pending.length > 0 ? decodeSseData(pending.join("\n")) : [] }));
51
+ const makeProcessHandle = (definition, instance, process) => {
52
+ const spanOptions = (operation) => ({ attributes: {
53
+ binding: definition.binding,
54
+ instance,
55
+ processId: process.id,
56
+ operation
57
+ } });
58
+ return {
59
+ id: process.id,
60
+ pid: process.pid,
61
+ rawUnsafe: Effect.succeed(process),
62
+ status: trySandboxPromise(definition, instance, "process.status", () => process.status()).pipe(Effect.withSpan("Sandbox.process.status", spanOptions("process.status"))),
63
+ exitCode: trySandboxPromise(definition, instance, "process.exitCode", () => process.exitCode).pipe(Effect.withSpan("Sandbox.process.exitCode", spanOptions("process.exitCode"))),
64
+ logs: (options) => sandboxStream(definition, instance, "process.logs", (signal) => process.logs({
65
+ ...options,
66
+ signal
67
+ })),
68
+ waitForLog: Effect.fn("Sandbox.process.waitForLog", spanOptions("process.waitForLog"))(function* (pattern, options) {
69
+ return yield* trySandboxPromise(definition, instance, "process.waitForLog", (signal) => process.waitForLog(pattern, {
70
+ ...options,
71
+ signal
72
+ }));
73
+ }),
74
+ waitForExit: Effect.fn("Sandbox.process.waitForExit", spanOptions("process.waitForExit"))(function* (options) {
75
+ return yield* trySandboxPromise(definition, instance, "process.waitForExit", (signal) => process.waitForExit({
76
+ ...options,
77
+ signal
78
+ }));
79
+ }),
80
+ output: Effect.fn("Sandbox.process.output", spanOptions("process.output"))(function* (options) {
81
+ return yield* trySandboxPromise(definition, instance, "process.output", (signal) => process.output({
82
+ ...options,
83
+ signal
84
+ }));
85
+ }),
86
+ outputText: Effect.fn("Sandbox.process.outputText", spanOptions("process.outputText"))(function* (options) {
87
+ return yield* trySandboxPromise(definition, instance, "process.outputText", (signal) => process.output({
88
+ ...options,
89
+ encoding: "utf8",
90
+ signal
91
+ }));
92
+ }),
93
+ waitForPort: Effect.fn("Sandbox.process.waitForPort", spanOptions("process.waitForPort"))(function* (port, options) {
94
+ return yield* trySandboxPromise(definition, instance, "process.waitForPort", (signal) => process.waitForPort(port, {
95
+ ...options,
96
+ signal
97
+ }));
98
+ }),
99
+ kill: Effect.fn("Sandbox.process.kill", spanOptions("process.kill"))(function* (signal) {
100
+ return yield* trySandboxPromise(definition, instance, "process.kill", () => process.kill(signal));
101
+ })
102
+ };
103
+ };
104
+ const makeTerminalHandle = (definition, instance, terminal) => {
105
+ const spanOptions = (operation) => ({ attributes: {
106
+ binding: definition.binding,
107
+ instance,
108
+ terminalId: terminal.id,
109
+ operation
110
+ } });
111
+ return {
112
+ id: terminal.id,
113
+ rawUnsafe: Effect.succeed(terminal),
114
+ snapshot: trySandboxPromise(definition, instance, "terminal.snapshot", () => terminal.getSnapshot()).pipe(Effect.withSpan("Sandbox.terminal.snapshot", spanOptions("terminal.snapshot"))),
115
+ write: Effect.fn("Sandbox.terminal.write", spanOptions("terminal.write"))(function* (data) {
116
+ return yield* trySandboxPromise(definition, instance, "terminal.write", () => terminal.write(data));
117
+ }),
118
+ resize: Effect.fn("Sandbox.terminal.resize", spanOptions("terminal.resize"))(function* (cols, rows) {
119
+ return yield* trySandboxPromise(definition, instance, "terminal.resize", () => terminal.resize(cols, rows));
120
+ }),
121
+ output: (options) => sandboxStream(definition, instance, "terminal.output", (signal) => terminal.output({
122
+ ...options,
123
+ signal
124
+ })),
125
+ waitForExit: Effect.fn("Sandbox.terminal.waitForExit", spanOptions("terminal.waitForExit"))(function* (options) {
126
+ return yield* trySandboxPromise(definition, instance, "terminal.waitForExit", (signal) => terminal.waitForExit({
127
+ ...options,
128
+ signal
129
+ }));
130
+ }),
131
+ interrupt: trySandboxPromise(definition, instance, "terminal.interrupt", () => terminal.interrupt()).pipe(Effect.withSpan("Sandbox.terminal.interrupt", spanOptions("terminal.interrupt"))),
132
+ terminate: trySandboxPromise(definition, instance, "terminal.terminate", () => terminal.terminate()).pipe(Effect.withSpan("Sandbox.terminal.terminate", spanOptions("terminal.terminate"))),
133
+ connect: Effect.fn("Sandbox.terminal.connect", spanOptions("terminal.connect"))(function* (request, options) {
134
+ return yield* trySandboxPromise(definition, instance, "terminal.connect", () => terminal.connect(request, options));
135
+ })
136
+ };
137
+ };
138
+ /**
139
+ * Wraps an already-created sandbox client (the value returned by
140
+ * `getSandbox()` from `@cloudflare/sandbox`) into an Effect client.
141
+ *
142
+ * Prefer {@link Tag}/{@link make} with a layer for application code; this
143
+ * entry point exists for advanced composition and testing.
144
+ */
145
+ const fromSandboxClient = (client, definition, instance) => {
146
+ const spanOptions = (operation) => ({ attributes: {
147
+ binding: definition.binding,
148
+ instance,
149
+ operation
150
+ } });
151
+ return {
152
+ rawUnsafe: Effect.succeed(client),
153
+ exec: Effect.fn("Sandbox.exec", spanOptions("exec"))(function* (command, options) {
154
+ const process = yield* trySandboxPromise(definition, instance, "exec", () => client.exec(command, options));
155
+ return makeProcessHandle(definition, instance, process);
156
+ }),
157
+ getProcess: Effect.fn("Sandbox.getProcess", spanOptions("getProcess"))(function* (id) {
158
+ const process = yield* trySandboxPromise(definition, instance, "getProcess", () => client.getProcess(id));
159
+ return Option.map(Option.fromNullishOr(process), (found) => makeProcessHandle(definition, instance, found));
160
+ }),
161
+ listProcesses: trySandboxPromise(definition, instance, "listProcesses", () => client.listProcesses()).pipe(Effect.withSpan("Sandbox.listProcesses", spanOptions("listProcesses"))),
162
+ writeFile: Effect.fn("Sandbox.writeFile", spanOptions("writeFile"))(function* (path, content, options) {
163
+ yield* Effect.annotateCurrentSpan("path", path);
164
+ return yield* trySandboxPromise(definition, instance, "writeFile", () => client.writeFile(path, content, options));
165
+ }),
166
+ readFile: Effect.fn("Sandbox.readFile", spanOptions("readFile"))(function* (path, options) {
167
+ yield* Effect.annotateCurrentSpan("path", path);
168
+ return yield* trySandboxPromise(definition, instance, "readFile", () => client.readFile(path, options));
169
+ }),
170
+ readFileStream: (path) => sandboxStream(definition, instance, "readFileStream", () => client.readFileStream(path)),
171
+ mkdir: Effect.fn("Sandbox.mkdir", spanOptions("mkdir"))(function* (path, options) {
172
+ yield* Effect.annotateCurrentSpan("path", path);
173
+ return yield* trySandboxPromise(definition, instance, "mkdir", () => client.mkdir(path, options));
174
+ }),
175
+ deleteFile: Effect.fn("Sandbox.deleteFile", spanOptions("deleteFile"))(function* (path) {
176
+ yield* Effect.annotateCurrentSpan("path", path);
177
+ return yield* trySandboxPromise(definition, instance, "deleteFile", () => client.deleteFile(path));
178
+ }),
179
+ renameFile: Effect.fn("Sandbox.renameFile", spanOptions("renameFile"))(function* (oldPath, newPath) {
180
+ yield* Effect.annotateCurrentSpan({
181
+ oldPath,
182
+ newPath
183
+ });
184
+ return yield* trySandboxPromise(definition, instance, "renameFile", () => client.renameFile(oldPath, newPath));
185
+ }),
186
+ moveFile: Effect.fn("Sandbox.moveFile", spanOptions("moveFile"))(function* (sourcePath, destinationPath) {
187
+ yield* Effect.annotateCurrentSpan({
188
+ sourcePath,
189
+ destinationPath
190
+ });
191
+ return yield* trySandboxPromise(definition, instance, "moveFile", () => client.moveFile(sourcePath, destinationPath));
192
+ }),
193
+ listFiles: Effect.fn("Sandbox.listFiles", spanOptions("listFiles"))(function* (path, options) {
194
+ yield* Effect.annotateCurrentSpan("path", path);
195
+ return yield* trySandboxPromise(definition, instance, "listFiles", () => client.listFiles(path, options));
196
+ }),
197
+ exists: Effect.fn("Sandbox.exists", spanOptions("exists"))(function* (path) {
198
+ yield* Effect.annotateCurrentSpan("path", path);
199
+ return yield* trySandboxPromise(definition, instance, "exists", () => client.exists(path));
200
+ }),
201
+ watch: (path, options) => decodeSseEvents(sandboxStream(definition, instance, "watch", () => client.watch(path, options))),
202
+ checkChanges: Effect.fn("Sandbox.checkChanges", spanOptions("checkChanges"))(function* (path, options) {
203
+ yield* Effect.annotateCurrentSpan("path", path);
204
+ return yield* trySandboxPromise(definition, instance, "checkChanges", () => client.checkChanges(path, options));
205
+ }),
206
+ setEnvVars: Effect.fn("Sandbox.setEnvVars", spanOptions("setEnvVars"))(function* (envVars) {
207
+ return yield* trySandboxPromise(definition, instance, "setEnvVars", () => client.setEnvVars(envVars));
208
+ }),
209
+ exposePort: Effect.fn("Sandbox.exposePort", spanOptions("exposePort"))(function* (port, options) {
210
+ yield* Effect.annotateCurrentSpan("port", port);
211
+ return yield* trySandboxPromise(definition, instance, "exposePort", () => client.exposePort(port, options));
212
+ }),
213
+ unexposePort: Effect.fn("Sandbox.unexposePort", spanOptions("unexposePort"))(function* (port) {
214
+ yield* Effect.annotateCurrentSpan("port", port);
215
+ return yield* trySandboxPromise(definition, instance, "unexposePort", () => client.unexposePort(port));
216
+ }),
217
+ getExposedPorts: Effect.fn("Sandbox.getExposedPorts", spanOptions("getExposedPorts"))(function* (hostname) {
218
+ return yield* trySandboxPromise(definition, instance, "getExposedPorts", () => client.getExposedPorts(hostname));
219
+ }),
220
+ isPortExposed: Effect.fn("Sandbox.isPortExposed", spanOptions("isPortExposed"))(function* (port) {
221
+ yield* Effect.annotateCurrentSpan("port", port);
222
+ return yield* trySandboxPromise(definition, instance, "isPortExposed", () => client.isPortExposed(port));
223
+ }),
224
+ validatePortToken: Effect.fn("Sandbox.validatePortToken", spanOptions("validatePortToken"))(function* (port, token) {
225
+ yield* Effect.annotateCurrentSpan("port", port);
226
+ return yield* trySandboxPromise(definition, instance, "validatePortToken", () => client.validatePortToken(port, token));
227
+ }),
228
+ containerFetch: Effect.fn("Sandbox.containerFetch", spanOptions("containerFetch"))(function* (requestOrUrl, port) {
229
+ return yield* trySandboxPromise(definition, instance, "containerFetch", () => client.containerFetch(requestOrUrl, port));
230
+ }),
231
+ wsConnect: Effect.fn("Sandbox.wsConnect", spanOptions("wsConnect"))(function* (request, port) {
232
+ yield* Effect.annotateCurrentSpan("port", port);
233
+ return yield* trySandboxPromise(definition, instance, "wsConnect", () => client.wsConnect(request, port));
234
+ }),
235
+ mountBucket: Effect.fn("Sandbox.mountBucket", spanOptions("mountBucket"))(function* (bucket, mountPath, options) {
236
+ yield* Effect.annotateCurrentSpan({
237
+ bucket,
238
+ mountPath
239
+ });
240
+ return yield* trySandboxPromise(definition, instance, "mountBucket", () => client.mountBucket(bucket, mountPath, options));
241
+ }),
242
+ unmountBucket: Effect.fn("Sandbox.unmountBucket", spanOptions("unmountBucket"))(function* (mountPath) {
243
+ yield* Effect.annotateCurrentSpan("mountPath", mountPath);
244
+ return yield* trySandboxPromise(definition, instance, "unmountBucket", () => client.unmountBucket(mountPath));
245
+ }),
246
+ createBackup: Effect.fn("Sandbox.createBackup", spanOptions("createBackup"))(function* (options) {
247
+ yield* Effect.annotateCurrentSpan("dir", options.dir);
248
+ return yield* trySandboxPromise(definition, instance, "createBackup", () => client.createBackup(options));
249
+ }),
250
+ restoreBackup: Effect.fn("Sandbox.restoreBackup", spanOptions("restoreBackup"))(function* (backup) {
251
+ yield* Effect.annotateCurrentSpan({
252
+ backupId: backup.id,
253
+ dir: backup.dir
254
+ });
255
+ return yield* trySandboxPromise(definition, instance, "restoreBackup", () => client.restoreBackup(backup));
256
+ }),
257
+ createTerminal: Effect.fn("Sandbox.createTerminal", spanOptions("createTerminal"))(function* (options) {
258
+ const terminal = yield* trySandboxPromise(definition, instance, "createTerminal", () => client.createTerminal(options));
259
+ return makeTerminalHandle(definition, instance, terminal);
260
+ }),
261
+ getTerminal: Effect.fn("Sandbox.getTerminal", spanOptions("getTerminal"))(function* (id) {
262
+ const terminal = yield* trySandboxPromise(definition, instance, "getTerminal", () => client.getTerminal(id));
263
+ return Option.map(Option.fromNullishOr(terminal), (found) => makeTerminalHandle(definition, instance, found));
264
+ }),
265
+ listTerminals: trySandboxPromise(definition, instance, "listTerminals", () => client.listTerminals()).pipe(Effect.map((terminals) => terminals.map((terminal) => makeTerminalHandle(definition, instance, terminal))), Effect.withSpan("Sandbox.listTerminals", spanOptions("listTerminals"))),
266
+ tunnels: {
267
+ get: Effect.fn("Sandbox.tunnels.get", spanOptions("tunnels.get"))(function* (port, options) {
268
+ yield* Effect.annotateCurrentSpan("port", port);
269
+ return yield* trySandboxPromise(definition, instance, "tunnels.get", () => client.tunnels.get(port, options));
270
+ }),
271
+ list: trySandboxPromise(definition, instance, "tunnels.list", () => client.tunnels.list()).pipe(Effect.withSpan("Sandbox.tunnels.list", spanOptions("tunnels.list"))),
272
+ destroy: Effect.fn("Sandbox.tunnels.destroy", spanOptions("tunnels.destroy"))(function* (portOrInfo) {
273
+ return yield* trySandboxPromise(definition, instance, "tunnels.destroy", () => client.tunnels.destroy(portOrInfo));
274
+ })
275
+ },
276
+ start: Effect.fn("Sandbox.start", spanOptions("start"))(function* (options) {
277
+ return yield* trySandboxPromise(definition, instance, "start", () => client.start(options));
278
+ }),
279
+ stop: Effect.fn("Sandbox.stop", spanOptions("stop"))(function* (signal) {
280
+ return yield* trySandboxPromise(definition, instance, "stop", () => client.stop(signal));
281
+ }),
282
+ destroy: trySandboxPromise(definition, instance, "destroy", () => client.destroy()).pipe(Effect.withSpan("Sandbox.destroy", spanOptions("destroy")))
283
+ };
284
+ };
285
+ /**
286
+ * Lazily imports `@cloudflare/sandbox`.
287
+ *
288
+ * The package is an optional peer dependency: loading it on first use keeps
289
+ * this module importable (and the rest of `effect-cf` bundleable) in
290
+ * applications that never touch sandboxes.
291
+ */
292
+ const importSandboxModule = (definition, instance) => Effect.tryPromise({
293
+ try: () => import("@cloudflare/sandbox"),
294
+ catch: (cause) => new SandboxOperationError({
295
+ binding: definition.binding,
296
+ instance,
297
+ operation: "import",
298
+ cause
299
+ })
300
+ });
301
+ const isSandboxNamespaceResource = (value) => Predicate.hasProperty(value, "idFromName") && Predicate.isFunction(value.idFromName) && Predicate.hasProperty(value, "get") && Predicate.isFunction(value.get);
302
+ const makeClient = (definition) => (namespace) => {
303
+ return {
304
+ definition,
305
+ get: Effect.fn("Sandbox.get", { attributes: {
306
+ binding: definition.binding,
307
+ operation: "get"
308
+ } })(function* (name, options) {
309
+ yield* Effect.annotateCurrentSpan("instance", name);
310
+ const sandboxModule = yield* importSandboxModule(definition, name);
311
+ const nativeNamespace = namespace;
312
+ const client = yield* Effect.try({
313
+ try: () => sandboxModule.getSandbox(nativeNamespace, name, options),
314
+ catch: (cause) => new SandboxOperationError({
315
+ binding: definition.binding,
316
+ instance: name,
317
+ operation: "get",
318
+ cause
319
+ })
320
+ });
321
+ return fromSandboxClient(client, definition, name);
322
+ }),
323
+ rawUnsafe: Effect.succeed(namespace)
324
+ };
325
+ };
326
+ const layer = (tag, definition) => layer$1(tag, definition.binding, (value) => isSandboxNamespaceResource(value), makeClient(definition), { expected: expectedSandboxNamespace });
327
+ const make = (id) => Tag()(id);
328
+ /** Creates a typed Effect service for a Cloudflare Sandbox namespace. */
329
+ const Tag = () => (id) => {
330
+ const tag = Context.Service()(`effect-cf/Sandbox/${id}`);
331
+ const makeLayer = (definition) => layer(tag, definition);
332
+ const get = Effect.fnUntraced(function* (name, options) {
333
+ return yield* (yield* tag).get(name, options);
334
+ });
335
+ const rawUnsafe = Effect.flatMap(tag, (namespace) => namespace.rawUnsafe);
336
+ return Object.assign(tag, {
337
+ id,
338
+ layer: makeLayer,
339
+ get,
340
+ rawUnsafe
341
+ });
342
+ };
343
+ const Sandbox = Tag;
344
+ /**
345
+ * Routes sandbox preview-URL requests (`https://<port>-<sandbox-id>-<token>.<host>`)
346
+ * to the owning sandbox, mirroring `proxyToSandbox` from `@cloudflare/sandbox`.
347
+ *
348
+ * Call this before any other routing in a Worker `fetch` handler; it resolves
349
+ * to `Option.none()` for requests that are not preview-URL traffic.
350
+ */
351
+ const proxyToSandbox = Effect.fn("Sandbox.proxyToSandbox")(function* (request, options) {
352
+ const binding = options?.binding ?? "Sandbox";
353
+ const definition = { binding };
354
+ const env = yield* WorkerEnvironment;
355
+ const resource = Predicate.hasProperty(env, binding) ? env[binding] : void 0;
356
+ const sandboxModule = yield* importSandboxModule(definition, "preview");
357
+ const response = yield* trySandboxPromise(definition, "preview", "proxyToSandbox", () => sandboxModule.proxyToSandbox(request, { Sandbox: resource }));
358
+ return Option.fromNullishOr(response);
359
+ });
360
+ //#endregion
361
+ export { Sandbox, SandboxOperationError, Tag, fromSandboxClient, isSandboxNamespaceResource, layer, make, makeClient, proxyToSandbox };
package/dist/Vitest.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { c as WorkerEnvironment, s as WorkerEnv } from "./Binding-xJJJPmiD.mjs";
2
- import { n as DurableObjectStateService, t as DurableObjectState } from "./DurableObjectState-OupNMMUl.mjs";
3
- import { o as WorkflowInstanceStatusName } from "./WorkflowBinding-DUZtKCVM.mjs";
2
+ import { n as DurableObjectStateService, t as DurableObjectState } from "./DurableObjectState-D3k-WRnd.mjs";
3
+ import { o as WorkflowInstanceStatusName } from "./WorkflowBinding-CtrmxfdT.mjs";
4
4
  import { Effect, Layer, Schema } from "effect";
5
5
  import { DurableObject } from "cloudflare:workers";
6
6
  import { adminSecretsStore as adminSecretsStore$1, getQueueResult, introspectWorkflow as introspectWorkflow$1, introspectWorkflowInstance as introspectWorkflowInstance$1 } from "cloudflare:test";
package/dist/Vitest.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { a as WorkerEnvironment, i as WorkerConfig } from "./ErrorMessage-BM0K-Nik.mjs";
2
- import { r as fromDurableObjectState, t as DurableObjectState } from "./DurableObjectState-BjkK2kwH.mjs";
2
+ import { r as fromDurableObjectState, t as DurableObjectState } from "./DurableObjectState-CepagPkX.mjs";
3
3
  import { ConfigProvider, Effect, Exit, Layer } from "effect";
4
4
  import { env } from "cloudflare:workers";
5
5
  import { abortAllDurableObjects as abortAllDurableObjects$1, adminSecretsStore as adminSecretsStore$1, applyD1Migrations as applyD1Migrations$1, createExecutionContext, createMessageBatch, createPagesEventContext, createScheduledController, evictAllDurableObjects as evictAllDurableObjects$1, evictDurableObject as evictDurableObject$1, getQueueResult, introspectWorkflow as introspectWorkflow$1, introspectWorkflowInstance as introspectWorkflowInstance$1, listDurableObjectIds as listDurableObjectIds$1, reset as reset$1, runDurableObjectAlarm as runDurableObjectAlarm$1, runInDurableObject as runInDurableObject$1, waitOnExecutionContext } from "cloudflare:test";
@@ -1,5 +1,5 @@
1
1
  import { c as WorkerEnvironment, r as BindingValidationError, t as BindingNotFoundError } from "./Binding-xJJJPmiD.mjs";
2
- import { x as ServiceFreeSchema } from "./DurableObjectState-OupNMMUl.mjs";
2
+ import { x as ServiceFreeSchema } from "./DurableObjectState-D3k-WRnd.mjs";
3
3
  import { Context, Effect, Option, Schema } from "effect";
4
4
  declare namespace WorkflowBinding_d_exports {
5
5
  export { WorkflowBindingClient, WorkflowBindingDefinition, WorkflowInstance, WorkflowInstanceCreateBatchOptions, WorkflowInstanceCreateOptions, WorkflowInstanceEvent, WorkflowInstanceRestartOptions, WorkflowInstanceStatus, WorkflowInstanceStatusName, WorkflowOperationError, WorkflowResultDecodeError, isWorkflow, layer, makeClient };