1import * as Context from "effect/Context";
2import * as Effect from "effect/Effect";
3import * as Schema from "effect/Schema";
4
5import type { HeldHook } from "./HookInboxStore.ts";
6
7export class HookInboxError extends Schema.TaggedError<HookInboxError>()("HookInboxError", {
8 operation: Schema.Literals(["hold", "wake", "clear"]),
9 endpointKey: Schema.String,
10 cause: Schema.Defect(),
11}) {
12 override get message(): string {
13 return `Hook inbox '${this.operation}' failed for endpoint '${this.endpointKey}'`;
14 }
15}
16
17/**
18 * Webhook requests held for environments that opted in, while they are
19 * offline. Each managed endpoint's requests live in its own `HookInboxObject`,
20 * named by endpoint key, which delivers them itself once the environment is back.
21 */
22export class HookInbox extends Context.Service<
23 HookInbox,
24 {
25 /** False when the environment's inbox is full and nothing was stored. */
26 readonly hold: (input: {
27 readonly endpointKey: string;
28 readonly baseUrl: string;
29 readonly hook: HeldHook;
30 }) => Effect.Effect<boolean, HookInboxError>;
31 /** Delivers what is waiting now; true when anything was waiting. */
32 readonly wake: (input: {
33 readonly endpointKey: string;
34 readonly baseUrl: string;
35 }) => Effect.Effect<boolean, HookInboxError>;
36 readonly clear: (input: {
37 readonly endpointKey: string;
38 }) => Effect.Effect<void, HookInboxError>;
39 }
40>()("t3code-relay/hooks/HookInbox") {}