1import * as Fly from "@/Fly";
2import * as Effect from "effect/Effect";
3import * as Stream from "effect/Stream";
4import { HttpServerRequest } from "effect/http/HttpServerRequest";
5import * as HttpServerResponse from "effect/http/HttpServerResponse";
6
7export const USERS = [
8 { id: "u1", name: "Ada" },
9 { id: "u2", name: "Grace" },
10];
11
12/**
13 * Private Service on the stack network. It serves methods to bound callers,
14 * plain HTTP routes, and an admin port (9000) for `Fly.bindEndpoint`.
15 */
16export default class RpcUsers extends Fly.Service<RpcUsers>()(
17 "RpcUsers",
18 Effect.gen(function* () {
19 return {
20 main: import.meta.url,
21 region: "iad",
22 public: false,
23 network: yield* Fly.stackNetwork,
24 guest: { cpuKind: "shared" as const, cpus: 1, memoryMb: 256 },
25 services: [
26 {
27 protocol: "tcp",
28 internalPort: 3000,
29 autostop: "off" as const,
30 ports: [{ port: 80, handlers: ["http"] }],
31 },
32 {
33 protocol: "tcp",
34 internalPort: 3000,
35 autostop: "off" as const,
36 ports: [{ port: 9000, handlers: ["http"] }],
37 },
38 ],
39 };
40 }),
41 Effect.gen(function* () {
42 return {
43 listUsers: () => Effect.succeed(USERS),
44 getUser: (id: string) =>
45 Effect.succeed(USERS.find((user) => user.id === id)),
46 streamUsers: () => Stream.fromIterable(USERS),
47 fetch: Effect.gen(function* () {
48 const request = yield* HttpServerRequest;
49 return HttpServerResponse.text(
50 `users-http ${request.headers["fly-forwarded-port"] ?? ""} ${request.url}`,
51 );
52 }),
53 };
54 }),
55) {}