1import * as Cloudflare from "@/Cloudflare";
2import * as Effect from "effect/Effect";
3import * as Layer from "effect/Layer";
4import * as HttpClientRequest from "effect/http/HttpClientRequest";
5import { MyContainer } from "./container.ts";
6import { Storage } from "./storage.ts";
7
8export class Object extends Cloudflare.DurableObject<Object>()(
9 "Object",
10 Effect.gen(function* () {
11 // plan time
12 const bucket = yield* Cloudflare.R2.ReadWriteBucket(Storage);
13 const state = yield* Cloudflare.DurableObjectState;
14 const container = yield* MyContainer;
15
16 return Effect.gen(function* () {
17 // runtime
18 yield* state.storage.sql.exec(
19 "CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY, name TEXT)",
20 );
21
22 const conn = yield* container.getTcpPort(3000);
23
24 return {
25 // Seed R2 through the DO's NATIVE binding so the container (which reads
26 // over its HTTP token) sees a value written by a different binding.
27 put: (key: string, value: string) =>
28 bucket.put(key, value).pipe(Effect.asVoid),
29 get: (key: string) => bucket.get(key),
30 ping: () => container.ping(),
31 // The env var a `Binding.Service` injected into the container.
32 boundEnv: () => container.boundEnv(),
33 // Read the object from inside the container over RPC.
34 readObjectRpc: (key: string) => container.readObject(key),
35 // Read the object from inside the container over its TCP port (fetch).
36 readObjectFetch: (key: string) =>
37 Effect.gen(function* () {
38 const response = yield* conn.fetch(
39 HttpClientRequest.get(
40 `http://container/object?key=${encodeURIComponent(key)}`,
41 ),
42 );
43 return (yield* response.json) as { value: string | null };
44 }).pipe(Effect.orDie),
45 hello: () =>
46 Effect.gen(function* () {
47 const response = yield* conn.fetch(
48 HttpClientRequest.get("http://container/"),
49 );
50 return yield* response.text;
51 }).pipe(Effect.orDie),
52 };
53 });
54 }).pipe(
55 Effect.provide(
56 Layer.mergeAll(
57 Cloudflare.R2.ReadWriteBucketBinding,
58 Cloudflare.Containers.layer(MyContainer, {
59 enableInternet: true,
60 }),
61 ),
62 ),
63 ),
64) {}