1import * as Effect from "effect/Effect";
2import type { Scope } from "effect/Scope";
3import * as Binding from "../Binding.ts";
4import type { RuntimeContext } from "../RuntimeContext.ts";
5import type { Bucket } from "./Bucket.ts";
6import type { BucketEvent } from "./FunctionTriggerEvent.ts";
7
8export interface BucketEventSourceProps {
9 /** Unique trigger and route name. */ name: string;
10 /** Byte-exact object-key prefix. */ prefix?: string;
11 /** Enable future delivery. @default true */ enabled?: boolean;
12}
13export type BucketEventSourceService = <R = never>(
14 bucket: Bucket,
15 props: BucketEventSourceProps,
16 handler: (event: BucketEvent) => Effect.Effect<void, unknown, R>,
17) => Effect.Effect<void, never, Exclude<R, RuntimeContext | Scope>>;
18/**
19 * Subscribe a Neon Function to successful uploads in a same-branch bucket.
20 * Registers the handler route and creates a tracked FunctionTrigger automatically.
21 * Provide BucketEventSourceHttp on the Function initialization Effect. The trigger
22 * is deleted before its Function/bucket. Use invocationId for application idempotency.
23 * Delivery is HTTP POST, not a queue: no acknowledgement, retry or exactly-once
24 * policy is added. Local development does not generate cloud upload events.
25 *
26 * ### Process Uploads
27 * **Example:** Register an upload handler
28 * ```typescript
29 * yield* Neon.BucketEventSource(uploads, { name: "Uploads", prefix: "incoming/" }, event => Effect.log(event.objectKey));
30 * ```
31 *
32 * @binding
33 * @product Bucket
34 */
35export interface BucketEventSource extends Binding.Service<
36 BucketEventSource,
37 "Neon.BucketEventSource",
38 BucketEventSourceService
39> {
40 <R = never>(
41 bucket: Bucket,
42 props: BucketEventSourceProps,
43 handler: (event: BucketEvent) => Effect.Effect<void, unknown, R>,
44 ): Effect.Effect<
45 void,
46 never,
47 BucketEventSource | Exclude<R, RuntimeContext | Scope>
48 >;
49}
50export const BucketEventSource = Binding.Service<BucketEventSource>(
51 "Neon.BucketEventSource",
52);