1import * as Effect from "effect/Effect";
2import * as Binding from "../Binding.ts";
3import type { RuntimeContext } from "../RuntimeContext.ts";
4import type { Object, ObjectDecodeError } from "./Object.ts";
5import type { WriteBucketClient } from "./WriteBucket.ts";
6import type { ReadBucketClient } from "./ReadBucket.ts";
7import type { StorageBindingOptions } from "./StorageBinding.ts";
8
9export interface WriteObjectClient<T> {
10 /** Serialize a typed JSON value, or upload exact bytes/text to a raw object. */
11 put(
12 value: [T] extends [never] ? string | Uint8Array : T,
13 ): Effect.Effect<
14 Effect.Success<ReturnType<WriteBucketClient["put"]>>,
15 | Effect.Error<ReturnType<WriteBucketClient["put"]>>
16 | Effect.Error<ReturnType<ReadBucketClient["head"]>>
17 | ObjectDecodeError,
18 RuntimeContext
19 >;
20}
21
22/**
23 * Bind an object's key and value type for writes. Declarative reconciliation
24 * restores the resource's declared value; use WriteBucket for application data.
25 * Managed writers request both storage:read and storage:write: write-only
26 * credentials currently fail S3 authorization. These scopes cover the branch
27 * lineage, not only this object's key.
28 *
29 * ### Typed Writes
30 * **Example:** Update settings without JSON.stringify
31 * ```typescript
32 * const settings = yield* Neon.WriteObject(settingsObject);
33 * yield* settings.put({ theme: "dark", pageSize: 50 });
34 * ```
35 *
36 * @binding
37 * @product Bucket
38 */
39export interface WriteObject extends Binding.Service<
40 WriteObject,
41 "Neon.WriteObject",
42 <T>(
43 object: Object<T>,
44 options?: StorageBindingOptions,
45 ) => Effect.Effect<WriteObjectClient<T>>
46> {
47 <T>(
48 object: Object<T>,
49 options?: StorageBindingOptions,
50 ): Effect.Effect<WriteObjectClient<T>, never, WriteObject>;
51}
52export const WriteObject = Binding.Service<WriteObject>("Neon.WriteObject");