Create src/worker.ts. A Worker is a special kind of Resource — it
has both an infrastructure definition and a runtime implementation
expressed as an Effect.
Now let’s bind the R2 Bucket from Part 1 to our new Worker. The
problem is that the Bucket is declared inside the Stack’s generator
in alchemy.run.ts — we can’t import it from there.
A common pattern in Alchemy is to give each resource its own file.
Create src/bucket.ts:
src/bucket.ts
import*as Cloudflare from"alchemy/Cloudflare";
exportconstBucket= Cloudflare.R2Bucket("Bucket");
Update alchemy.run.ts to import it instead of declaring it inline:
alchemy.run.ts
import*as Alchemy from"alchemy";
import*as Cloudflare from"alchemy/Cloudflare";
import*as Effect from"effect/Effect";
import { Bucket } from"./src/bucket.ts";
exportdefaultAlchemy.Stack(
"MyApp",
{
providers: Cloudflare.providers(),
},
Effect.gen(function* () {
constbucket=yield* Cloudflare.R2Bucket("Bucket");
constbucket=yield* Bucket;
return {
bucketName: bucket.bucketName,
};
}),
);
Now the Worker can import Bucket and bind it in the Init phase:
Provides a way to write effectful code using generator functions, simplifying
control flow and error handling.
When to Use
gen allows you to write code that looks and behaves like synchronous
code, but it can handle asynchronous tasks, errors, and complex control flow
(like loops and conditions). It helps make asynchronous code more readable
and easier to manage.
The generator functions work similarly to async/await but with more
explicit control over the execution of effects. You can yield* values from
effects and return the final result at the end.
Provides a way to write effectful code using generator functions, simplifying
control flow and error handling.
When to Use
gen allows you to write code that looks and behaves like synchronous
code, but it can handle asynchronous tasks, errors, and complex control flow
(like loops and conditions). It helps make asynchronous code more readable
and easier to manage.
The generator functions work similarly to async/await but with more
explicit control over the execution of effects. You can yield* values from
effects and return the final result at the end.
The previous step showed a type error — R2Bucket.bind requires the
R2BucketBinding service. Fix it by piping the outer Effect through
R2BucketBindingLive:
Provides a way to write effectful code using generator functions, simplifying
control flow and error handling.
When to Use
gen allows you to write code that looks and behaves like synchronous
code, but it can handle asynchronous tasks, errors, and complex control flow
(like loops and conditions). It helps make asynchronous code more readable
and easier to manage.
The generator functions work similarly to async/await but with more
explicit control over the execution of effects. You can yield* values from
effects and return the final result at the end.
Provides a way to write effectful code using generator functions, simplifying
control flow and error handling.
When to Use
gen allows you to write code that looks and behaves like synchronous
code, but it can handle asynchronous tasks, errors, and complex control flow
(like loops and conditions). It helps make asynchronous code more readable
and easier to manage.
The generator functions work similarly to async/await but with more
explicit control over the execution of effects. You can yield* values from
effects and return the final result at the end.
} |undefined) => <A, E, R>(self:Effect.Effect<A, E, R>) =>Effect.Effect<...> (+5overloads)
Provides dependencies to an effect using layers or a context. Use options.local
to build the layer every time; by default, layers are shared between provide
calls.
R2BucketBindingLive tells the Worker runtime how to look up the
underlying R2 binding from the Cloudflare environment. Without it,
bind wouldn’t know where to find the bucket at runtime.
Provides a way to write effectful code using generator functions, simplifying
control flow and error handling.
When to Use
gen allows you to write code that looks and behaves like synchronous
code, but it can handle asynchronous tasks, errors, and complex control flow
(like loops and conditions). It helps make asynchronous code more readable
and easier to manage.
The generator functions work similarly to async/await but with more
explicit control over the execution of effects. You can yield* values from
effects and return the final result at the end.
Provides a way to write effectful code using generator functions, simplifying
control flow and error handling.
When to Use
gen allows you to write code that looks and behaves like synchronous
code, but it can handle asynchronous tasks, errors, and complex control flow
(like loops and conditions). It helps make asynchronous code more readable
and easier to manage.
The generator functions work similarly to async/await but with more
explicit control over the execution of effects. You can yield* values from
effects and return the final result at the end.
Split a string into substrings using the specified separator and return them as an array.
@param ― separator A string that identifies character or characters to use in separating the string. If omitted, a single-element array containing the entire string is returned.
@param ― limit A value used to limit the number of elements returned in the array.
split("/").
Array<string>.pop(): string |undefined
Removes the last element from an array and returns it.
If the array is empty, undefined is returned and the array is not modified.
} |undefined) => <A, E, R>(self:Effect.Effect<A, E, R>) =>Effect.Effect<...> (+5overloads)
Provides dependencies to an effect using layers or a context. Use options.local
to build the layer every time; by default, layers are shared between provide
calls.
TypeScript flags a type error. The bucket.put call can fail with
R2Error, but a Worker’s fetch handler only allows
HttpServerError or HttpBodyError. Effect tracks this in the type
system — you can’t forget to handle it.
Catches and handles specific errors by their _tag field, which is used as a
discriminator.
When to Use
catchTag is useful when your errors are tagged with a readonly _tag field
that identifies the error type. You can use this function to handle specific
error types by matching the _tag value. This allows for precise error
handling, ensuring that only specific errors are caught and handled.
The error type must have a readonly _tag field to use catchTag. This
field is used to identify and match errors.
Effect.catchTag matches errors by their _tag field. If an R2
operation fails at runtime, the Worker returns a 500 instead of
crashing — and the type error disappears because R2Error is now
fully handled.
Provides a way to write effectful code using generator functions, simplifying
control flow and error handling.
When to Use
gen allows you to write code that looks and behaves like synchronous
code, but it can handle asynchronous tasks, errors, and complex control flow
(like loops and conditions). It helps make asynchronous code more readable
and easier to manage.
The generator functions work similarly to async/await but with more
explicit control over the execution of effects. You can yield* values from
effects and return the final result at the end.
Split a string into substrings using the specified separator and return them as an array.
@param ― separator A string that identifies character or characters to use in separating the string. If omitted, a single-element array containing the entire string is returned.
@param ― limit A value used to limit the number of elements returned in the array.
split("/").
Array<string>.pop(): string |undefined
Removes the last element from an array and returns it.
If the array is empty, undefined is returned and the array is not modified.
Catches and handles specific errors by their _tag field, which is used as a
discriminator.
When to Use
catchTag is useful when your errors are tagged with a readonly _tag field
that identifies the error type. You can use this function to handle specific
error types by matching the _tag value. This allows for precise error
handling, ensuring that only specific errors are caught and handled.
The error type must have a readonly _tag field to use catchTag. This
field is used to identify and match errors.