1import * as Cloudflare from "@/Cloudflare/index.ts";
2import * as Stripe from "@/Stripe/index.ts";
3import * as Effect from "effect/Effect";
4import { HttpServerRequest } from "effect/http/HttpServerRequest";
5import * as HttpServerResponse from "effect/http/HttpServerResponse";
6
7export default class StripeEventSourceWorker extends Cloudflare.Worker<StripeEventSourceWorker>()(
8 "StripeEventSourceWorker",
9 {
10 main: import.meta.url,
11 },
12 Effect.gen(function* () {
13 const log = yield* Cloudflare.KV.Namespace("EventLog");
14 const kv = yield* Cloudflare.KV.ReadWriteNamespace(log);
15 const createCustomer = yield* Stripe.CreateCustomer();
16
17 yield* Stripe.consumeEvents(
18 "Events",
19 { events: [Stripe.CustomerCreated] },
20 Effect.fn(function* (event) {
21 yield* kv.put(event.object.id, "1").pipe(Effect.orDie);
22 yield* kv.put("lastCustomerId", event.object.id).pipe(Effect.orDie);
23 }),
24 ).pipe(Effect.orDie);
25
26 return {
27 fetch: Effect.gen(function* () {
28 const request = yield* HttpServerRequest;
29 if (request.url.startsWith("/last/")) {
30 const id = request.url.slice("/last/".length).split("?")[0];
31 const seen = yield* kv.get(id).pipe(Effect.orDie);
32 return yield* HttpServerResponse.json({
33 id: seen === "1" ? id : null,
34 });
35 }
36 if (request.url.startsWith("/last")) {
37 const id = yield* kv.get("lastCustomerId").pipe(Effect.orDie);
38 return yield* HttpServerResponse.json({ id: id ?? null });
39 }
40 if (request.method === "POST" && request.url.startsWith("/customers")) {
41 const customer = yield* createCustomer({
42 email: "event-source@example.com",
43 }).pipe(Effect.orDie);
44 return yield* HttpServerResponse.json(
45 { id: customer.id },
46 { status: 201 },
47 );
48 }
49 return HttpServerResponse.text("ok");
50 }),
51 };
52 }).pipe(
53 Effect.provide([
54 Cloudflare.KV.ReadWriteNamespaceBinding,
55 Stripe.CreateCustomerHttp,
56 Stripe.ConsumeEventsLive,
57 ]),
58 ),
59) {}