import type stream from 'node:stream'; import { type S3ClientConfig } from '@aws-sdk/client-s3'; import type { CID } from 'multiformats/cid'; import { type BlobStore } from '@atproto/repo'; export type S3Config = { bucket: string; /** * The maximum time any single HTTP request to S3 can remain idle (socket * idle timeout), in milliseconds. This acts as a stall detector: a stalled * or dead connection is reaped after this delay and the request is retried * by the SDK. It should be kept short, independently of * {@link S3Config.uploadTimeoutMs}, because blob bytes are buffered in * memory before each S3 request is dispatched (uploads to S3 are never * client-paced). * * @note Do not set this below 6 seconds. For values >= 6s, the SDK's socket * idle timeout is only armed if the response headers take more than 3s to * arrive, so blob *downloads* streamed to slow (client-paced) consumers are * unaffected. Below 6s, the timeout is armed immediately and stays armed * while the response body is streamed, causing slow-but-legitimate * downloads to be reaped mid-transfer (see "downloads" tests in * s3.test.ts). * * @note Maintenance context: the 6s threshold and 3s deferral are * *undocumented internals* of `@smithy/node-http-handler` (the AWS SDK's * node request handler; see `setSocketTimeout` in its `set-socket-timeout` * module, `DEFER_EVENT_LISTENER_TIME`). They are not part of any public API * contract and could change in a future SDK release. The "downloads" tests * in s3.test.ts characterize this behavior and will fail if it drifts — if * they break after a dependency bump, re-read the handler source and * re-evaluate the 6s floor below. * * Defaults to `min(uploadTimeoutMs, 15_000)`, clamped to a minimum of * `6_000`. */ requestTimeoutMs?: number; /** * The maximum time establishing a connection to S3 can take, in * milliseconds. * * Defaults to 5_000. */ connectionTimeoutMs?: number; /** * The maximum total time a blob upload can take, in milliseconds. Since * uploaded bytes are streamed from the client, this timeout should be large * enough to accommodate slow clients uploading large blobs. */ uploadTimeoutMs?: number; } & Omit; export declare class S3BlobStore implements BlobStore { did: string; private client; private bucket; private uploadTimeoutMs; constructor(did: string, cfg: S3Config); static creator(cfg: S3Config): (did: string) => S3BlobStore; private genKey; private getTmpPath; private getStoredPath; private getQuarantinedPath; private uploadBytes; putTemp(bytes: Uint8Array | stream.Readable): Promise; makePermanent(key: string, cid: CID): Promise; putPermanent(cid: CID, bytes: Uint8Array | stream.Readable): Promise; quarantine(cid: CID): Promise; unquarantine(cid: CID): Promise; private getObject; getBytes(cid: CID): Promise; getStream(cid: CID): Promise; delete(cid: CID): Promise; deleteMany(cids: CID[]): Promise; hasStored(cid: CID): Promise; hasTemp(key: string): Promise; private hasKey; private deleteKey; private deleteManyKeys; private move; } export default S3BlobStore; //# sourceMappingURL=s3.d.ts.map