zerobucket 0.1.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -63,6 +63,22 @@ interface Queryable {
63
63
  rowCount: number | null;
64
64
  }>;
65
65
  }
66
+ /**
67
+ * The slice of a `better-sqlite3` Database that ZeroBucket's SQLite backend uses. Pass your own
68
+ * Database handle as `connection` to make a call part of YOUR SQLite transaction.
69
+ */
70
+ interface SqliteDatabaseLike {
71
+ prepare(sql: string): {
72
+ all(...params: unknown[]): any[];
73
+ get(...params: unknown[]): any;
74
+ run(...params: unknown[]): {
75
+ changes: number;
76
+ };
77
+ };
78
+ exec(sql: string): unknown;
79
+ }
80
+ /** What `connection` accepts: a `pg` client for the Postgres backend, a `better-sqlite3` Database for SQLite. */
81
+ type Connection = Queryable | SqliteDatabaseLike;
66
82
  /** The row shape a storage backend persists (after validation and checksumming). */
67
83
  interface PreparedRow {
68
84
  data: Buffer;
@@ -99,7 +115,7 @@ interface StoredRecord {
99
115
  }
100
116
  type StoredRecordMetadata = Omit<StoredRecord, "data">;
101
117
  interface CallOptions {
102
- connection?: Queryable;
118
+ connection?: Connection;
103
119
  }
104
120
  interface StreamOptions$1 extends CallOptions {
105
121
  chunkSize: number;
@@ -109,6 +125,50 @@ interface StreamOptions$1 extends CallOptions {
109
125
  end: number;
110
126
  };
111
127
  }
128
+ /** Filters for maintenance listings (CLI `verify` / `tier`). All optional; combined with AND. */
129
+ interface ImageListOptions {
130
+ /** Return a random sample of this many images instead of all of them. */
131
+ sample?: number;
132
+ limit?: number;
133
+ /** Only images with size_bytes >= this. */
134
+ minSize?: number;
135
+ /** Only images created at least this many days ago. */
136
+ olderThanDays?: number;
137
+ /** Only images whose bytes are still in the database (not tiered). */
138
+ onlyUntiered?: boolean;
139
+ }
140
+ interface ImageListEntry {
141
+ id: string;
142
+ /** Bytes live in object storage, not in the database. */
143
+ tiered: boolean;
144
+ }
145
+ /** Storage statistics for `zerobucket info`. */
146
+ interface StorageInfo {
147
+ mode: "classic" | "dedup";
148
+ /** Number of images (references, in dedup mode). */
149
+ count: number;
150
+ /** Sum of every image's size_bytes as recorded by the application (logical size). */
151
+ totalBytes: number;
152
+ oldest: string | null;
153
+ newest: string | null;
154
+ /** Human-readable on-disk size, if the database can tell. */
155
+ onDisk: string | null;
156
+ byFormat: {
157
+ mimeType: string;
158
+ count: number;
159
+ bytes: number;
160
+ }[];
161
+ /** Classic mode: images currently living in object storage. */
162
+ tiered?: {
163
+ count: number;
164
+ bytes: number;
165
+ };
166
+ /** Dedup mode: distinct stored blobs and the bytes they physically occupy. */
167
+ dedup?: {
168
+ blobs: number;
169
+ storedBytes: number;
170
+ };
171
+ }
112
172
  interface StorageBackend {
113
173
  /** Resolve once the backend is connected and migrated. Safe to call repeatedly. */
114
174
  ready(): Promise<void>;
@@ -128,9 +188,69 @@ interface StorageBackend {
128
188
  /** Returns the ids that were actually deleted. */
129
189
  deleteMany(ids: string[], opts?: CallOptions): Promise<string[]>;
130
190
  exists(id: string, opts?: CallOptions): Promise<boolean>;
191
+ /** null = no such image, false = already tiered (no-op), true = tiered now. Needs object storage configured. */
192
+ tierToObjectStorage(id: string, opts?: CallOptions): Promise<boolean | null>;
193
+ /** Dedup-mode instances only: copy the classic table into the dedup tables (non-destructive). */
194
+ migrateClassicToDedup?(): Promise<{
195
+ imagesMigrated: number;
196
+ distinctBlobsCreated: number;
197
+ duplicateReferencesFound: number;
198
+ alreadyMigrated: number;
199
+ }>;
200
+ /** Maintenance: storage statistics, or null if the tables do not exist yet. */
201
+ getInfo?(): Promise<StorageInfo | null>;
202
+ /** Maintenance: list ids matching the filters (oldest first, or random when sampling). */
203
+ listImages?(opts?: ImageListOptions): Promise<ImageListEntry[]>;
131
204
  close(): Promise<void>;
132
205
  }
133
206
 
207
+ /** The surface the Postgres adapter needs. Implement this to plug in a non-S3 store (or a test double). */
208
+ interface ObjectStorageLike {
209
+ readonly bucket: string;
210
+ upload(key: string, data: Buffer, opts: {
211
+ mimeType: string;
212
+ }): Promise<void>;
213
+ download(key: string): Promise<Buffer>;
214
+ /** Inclusive byte range, fetched with a real HTTP Range request. */
215
+ downloadRange(key: string, start: number, endInclusive: number): Promise<Buffer>;
216
+ /** Idempotent: deleting a missing key is not an error. */
217
+ delete(key: string): Promise<void>;
218
+ exists(key: string): Promise<boolean>;
219
+ }
220
+ interface ObjectStorageOptions {
221
+ /** Must already exist. */
222
+ bucket: string;
223
+ /** Set for anything that is not AWS S3 itself (MinIO, R2, B2, Spaces, ...). */
224
+ endpoint?: string;
225
+ /** Default: AWS_REGION / AWS_DEFAULT_REGION, else "us-east-1". Many S3-compatible services ignore it but the SDK requires one. */
226
+ region?: string;
227
+ /** Default: the SDK's standard chain (env vars, shared config, IAM role, ...). */
228
+ credentials?: {
229
+ accessKeyId: string;
230
+ secretAccessKey: string;
231
+ sessionToken?: string;
232
+ };
233
+ /** Path-style addressing (`endpoint/bucket/key`). Default: true when `endpoint` is set, else false. */
234
+ forcePathStyle?: boolean;
235
+ /** Bring your own configured S3Client (advanced). */
236
+ client?: unknown;
237
+ }
238
+ declare class ObjectStorage implements ObjectStorageLike {
239
+ private readonly opts;
240
+ readonly bucket: string;
241
+ private clientPromise;
242
+ constructor(opts: ObjectStorageOptions);
243
+ private connection;
244
+ upload(key: string, data: Buffer, { mimeType }: {
245
+ mimeType: string;
246
+ }): Promise<void>;
247
+ download(key: string): Promise<Buffer>;
248
+ downloadRange(key: string, start: number, endInclusive: number): Promise<Buffer>;
249
+ private get;
250
+ delete(key: string): Promise<void>;
251
+ exists(key: string): Promise<boolean>;
252
+ }
253
+
134
254
  interface OptimizeOptions {
135
255
  /** Downscale (aspect ratio preserved, Lanczos) if wider than this. Never upscales. */
136
256
  maxWidth?: number;
@@ -188,7 +308,13 @@ interface ZeroBucketOptions<C = unknown> {
188
308
  connectionString?: string;
189
309
  /** Bring your own pg.Pool. It is NOT closed by close(). */
190
310
  pool?: Pool;
191
- /** Advanced: inject a custom StorageBackend instead of building a PostgresBackend. */
311
+ /**
312
+ * Use SQLite instead of PostgreSQL: a database file path (or ":memory:"). Needs `npm install better-sqlite3`.
313
+ * `dedup`, `objectStorage`, `autoMigrate` and `onOperation` apply to it too. Same file format as the Python
314
+ * package's SQLiteBackend, so both can share one `.db` file.
315
+ */
316
+ sqlite?: string;
317
+ /** Advanced: inject a custom StorageBackend instead of building one from `connectionString` / `pool` / `sqlite`. */
192
318
  backend?: StorageBackend;
193
319
  /** Max accepted size in bytes. Default 8 MiB. */
194
320
  maxBytes?: number;
@@ -204,6 +330,19 @@ interface ZeroBucketOptions<C = unknown> {
204
330
  poolTimeoutMs?: number;
205
331
  /** Fire-and-forget observability. Exceptions thrown inside it are swallowed. */
206
332
  onOperation?: (event: OperationEvent) => void;
333
+ /**
334
+ * S3-compatible object storage, enabling `tierToObjectStorage()` and transparent
335
+ * reads of images the Python or Node package tiered. Configure it with the same
336
+ * bucket and credentials used to tier. Without it, reading a tiered image throws
337
+ * a clear StorageError.
338
+ */
339
+ objectStorage?: ObjectStorageLike;
340
+ /**
341
+ * Content-addressed mode: identical bytes are stored once and shared by reference, each image
342
+ * keeping its own id and filename. Cannot be combined with `objectStorage`. Uses separate tables
343
+ * (zerobucket_blobs / zerobucket_image_refs); see `migrateClassicToDedup()` for existing data.
344
+ */
345
+ dedup?: boolean;
207
346
  /**
208
347
  * Authorization hook for get / getMany (per id) / getStream / streamTo / metadata.
209
348
  * Return false to deny. A hook that THROWS fails closed: the exception
@@ -222,7 +361,7 @@ interface PutBase<C> {
222
361
  /** Store non-image content through the same machinery. Incompatible with `optimize`. */
223
362
  validator?: ContentValidator;
224
363
  /** Join your own transaction. ZeroBucket then does not commit, roll back or retry. */
225
- connection?: Queryable;
364
+ connection?: Connection;
226
365
  /** Passed to beforePut. */
227
366
  context?: C;
228
367
  }
@@ -232,7 +371,7 @@ interface PutManyOptions<C = unknown> extends Omit<PutBase<C>, "filename"> {
232
371
  filenames?: (string | null | undefined)[];
233
372
  }
234
373
  interface GetOptions<C = unknown> {
235
- connection?: Queryable;
374
+ connection?: Connection;
236
375
  context?: C;
237
376
  }
238
377
  interface StreamOptions<C = unknown> extends GetOptions<C> {
@@ -302,6 +441,21 @@ declare class ZeroBucket<C = unknown> {
302
441
  delete(imageId: string, options?: Pick<CallOptions, "connection">): Promise<boolean>;
303
442
  /** Delete many in one query. Results are in input order; a missing id is `deleted: false`, not an error. */
304
443
  deleteMany(imageIds: string[], options?: Pick<CallOptions, "connection">): Promise<BatchDeleteResult[]>;
444
+ /**
445
+ * Move an image's bytes from Postgres into object storage; reads, streams and
446
+ * deletes keep working transparently. Returns true if tiered now, false if it was
447
+ * already tiered (safe to re-run in a backfill). Throws ImageNotFoundError if missing.
448
+ *
449
+ * The upload runs inside the database transaction: if it fails, the row is left
450
+ * completely untouched. Explicit and opt-in: put() never tiers automatically.
451
+ * Not gated by beforeGet/beforePut (it is a maintenance operation, as in the Python package).
452
+ */
453
+ tierToObjectStorage(imageId: string, options?: Pick<CallOptions, "connection">): Promise<boolean>;
454
+ /**
455
+ * One-time, non-destructive copy of classic-mode images into a dedup instance's tables, keeping every
456
+ * id. Call it on an instance created with `dedup: true`. Safe to re-run. See PostgresBackend for details.
457
+ */
458
+ migrateClassicToDedup(): ReturnType<NonNullable<StorageBackend["migrateClassicToDedup"]>>;
305
459
  /** Release the pool (if ZeroBucket created it). */
306
460
  close(): Promise<void>;
307
461
  }
@@ -316,4 +470,4 @@ declare function readInput(image: ImageInput, filename: string | undefined, maxB
316
470
  filename: string | undefined;
317
471
  }>;
318
472
 
319
- export { type BatchDeleteResult as B, type CallOptions as C, DEFAULT_MAX_BYTES as D, type GetOptions as G, type Image as I, type OperationEvent as O, type PreparedRow as P, type Queryable as Q, type StorageBackend as S, type ValidatedContent as V, type WritableLike as W, ZeroBucket as Z, type StoredRecord as a, type StoredRecordMetadata as b, type StreamOptions$1 as c, type ContentValidator as d, type BatchGetResult as e, type BatchPutResult as f, type BeforeGetHook as g, type BeforePutHook as h, type ImageInput as i, type ImageMetadata as j, type OptimizationResult as k, type OptimizeOptions as l, type PutManyOptions as m, type PutOptions as n, type StreamOptions as o, type ZeroBucketOptions as p, optimizeImage as q, readInput as r };
473
+ export { type BatchDeleteResult as B, type CallOptions as C, DEFAULT_MAX_BYTES as D, type GetOptions as G, type ImageListOptions as I, type OperationEvent as O, type PreparedRow as P, type Queryable as Q, type StorageBackend as S, type ValidatedContent as V, type WritableLike as W, ZeroBucket as Z, type ObjectStorageLike as a, type StoredRecord as b, type StoredRecordMetadata as c, type StreamOptions$1 as d, type StorageInfo as e, type ImageListEntry as f, type ContentValidator as g, type BatchGetResult as h, type BatchPutResult as i, type BeforeGetHook as j, type BeforePutHook as k, type Connection as l, type Image as m, type ImageInput as n, type ImageMetadata as o, ObjectStorage as p, type ObjectStorageOptions as q, type OptimizationResult as r, type OptimizeOptions as s, type PutManyOptions as t, type PutOptions as u, type SqliteDatabaseLike as v, type StreamOptions as w, type ZeroBucketOptions as x, optimizeImage as y, readInput as z };
@@ -63,6 +63,22 @@ interface Queryable {
63
63
  rowCount: number | null;
64
64
  }>;
65
65
  }
66
+ /**
67
+ * The slice of a `better-sqlite3` Database that ZeroBucket's SQLite backend uses. Pass your own
68
+ * Database handle as `connection` to make a call part of YOUR SQLite transaction.
69
+ */
70
+ interface SqliteDatabaseLike {
71
+ prepare(sql: string): {
72
+ all(...params: unknown[]): any[];
73
+ get(...params: unknown[]): any;
74
+ run(...params: unknown[]): {
75
+ changes: number;
76
+ };
77
+ };
78
+ exec(sql: string): unknown;
79
+ }
80
+ /** What `connection` accepts: a `pg` client for the Postgres backend, a `better-sqlite3` Database for SQLite. */
81
+ type Connection = Queryable | SqliteDatabaseLike;
66
82
  /** The row shape a storage backend persists (after validation and checksumming). */
67
83
  interface PreparedRow {
68
84
  data: Buffer;
@@ -99,7 +115,7 @@ interface StoredRecord {
99
115
  }
100
116
  type StoredRecordMetadata = Omit<StoredRecord, "data">;
101
117
  interface CallOptions {
102
- connection?: Queryable;
118
+ connection?: Connection;
103
119
  }
104
120
  interface StreamOptions$1 extends CallOptions {
105
121
  chunkSize: number;
@@ -109,6 +125,50 @@ interface StreamOptions$1 extends CallOptions {
109
125
  end: number;
110
126
  };
111
127
  }
128
+ /** Filters for maintenance listings (CLI `verify` / `tier`). All optional; combined with AND. */
129
+ interface ImageListOptions {
130
+ /** Return a random sample of this many images instead of all of them. */
131
+ sample?: number;
132
+ limit?: number;
133
+ /** Only images with size_bytes >= this. */
134
+ minSize?: number;
135
+ /** Only images created at least this many days ago. */
136
+ olderThanDays?: number;
137
+ /** Only images whose bytes are still in the database (not tiered). */
138
+ onlyUntiered?: boolean;
139
+ }
140
+ interface ImageListEntry {
141
+ id: string;
142
+ /** Bytes live in object storage, not in the database. */
143
+ tiered: boolean;
144
+ }
145
+ /** Storage statistics for `zerobucket info`. */
146
+ interface StorageInfo {
147
+ mode: "classic" | "dedup";
148
+ /** Number of images (references, in dedup mode). */
149
+ count: number;
150
+ /** Sum of every image's size_bytes as recorded by the application (logical size). */
151
+ totalBytes: number;
152
+ oldest: string | null;
153
+ newest: string | null;
154
+ /** Human-readable on-disk size, if the database can tell. */
155
+ onDisk: string | null;
156
+ byFormat: {
157
+ mimeType: string;
158
+ count: number;
159
+ bytes: number;
160
+ }[];
161
+ /** Classic mode: images currently living in object storage. */
162
+ tiered?: {
163
+ count: number;
164
+ bytes: number;
165
+ };
166
+ /** Dedup mode: distinct stored blobs and the bytes they physically occupy. */
167
+ dedup?: {
168
+ blobs: number;
169
+ storedBytes: number;
170
+ };
171
+ }
112
172
  interface StorageBackend {
113
173
  /** Resolve once the backend is connected and migrated. Safe to call repeatedly. */
114
174
  ready(): Promise<void>;
@@ -128,9 +188,69 @@ interface StorageBackend {
128
188
  /** Returns the ids that were actually deleted. */
129
189
  deleteMany(ids: string[], opts?: CallOptions): Promise<string[]>;
130
190
  exists(id: string, opts?: CallOptions): Promise<boolean>;
191
+ /** null = no such image, false = already tiered (no-op), true = tiered now. Needs object storage configured. */
192
+ tierToObjectStorage(id: string, opts?: CallOptions): Promise<boolean | null>;
193
+ /** Dedup-mode instances only: copy the classic table into the dedup tables (non-destructive). */
194
+ migrateClassicToDedup?(): Promise<{
195
+ imagesMigrated: number;
196
+ distinctBlobsCreated: number;
197
+ duplicateReferencesFound: number;
198
+ alreadyMigrated: number;
199
+ }>;
200
+ /** Maintenance: storage statistics, or null if the tables do not exist yet. */
201
+ getInfo?(): Promise<StorageInfo | null>;
202
+ /** Maintenance: list ids matching the filters (oldest first, or random when sampling). */
203
+ listImages?(opts?: ImageListOptions): Promise<ImageListEntry[]>;
131
204
  close(): Promise<void>;
132
205
  }
133
206
 
207
+ /** The surface the Postgres adapter needs. Implement this to plug in a non-S3 store (or a test double). */
208
+ interface ObjectStorageLike {
209
+ readonly bucket: string;
210
+ upload(key: string, data: Buffer, opts: {
211
+ mimeType: string;
212
+ }): Promise<void>;
213
+ download(key: string): Promise<Buffer>;
214
+ /** Inclusive byte range, fetched with a real HTTP Range request. */
215
+ downloadRange(key: string, start: number, endInclusive: number): Promise<Buffer>;
216
+ /** Idempotent: deleting a missing key is not an error. */
217
+ delete(key: string): Promise<void>;
218
+ exists(key: string): Promise<boolean>;
219
+ }
220
+ interface ObjectStorageOptions {
221
+ /** Must already exist. */
222
+ bucket: string;
223
+ /** Set for anything that is not AWS S3 itself (MinIO, R2, B2, Spaces, ...). */
224
+ endpoint?: string;
225
+ /** Default: AWS_REGION / AWS_DEFAULT_REGION, else "us-east-1". Many S3-compatible services ignore it but the SDK requires one. */
226
+ region?: string;
227
+ /** Default: the SDK's standard chain (env vars, shared config, IAM role, ...). */
228
+ credentials?: {
229
+ accessKeyId: string;
230
+ secretAccessKey: string;
231
+ sessionToken?: string;
232
+ };
233
+ /** Path-style addressing (`endpoint/bucket/key`). Default: true when `endpoint` is set, else false. */
234
+ forcePathStyle?: boolean;
235
+ /** Bring your own configured S3Client (advanced). */
236
+ client?: unknown;
237
+ }
238
+ declare class ObjectStorage implements ObjectStorageLike {
239
+ private readonly opts;
240
+ readonly bucket: string;
241
+ private clientPromise;
242
+ constructor(opts: ObjectStorageOptions);
243
+ private connection;
244
+ upload(key: string, data: Buffer, { mimeType }: {
245
+ mimeType: string;
246
+ }): Promise<void>;
247
+ download(key: string): Promise<Buffer>;
248
+ downloadRange(key: string, start: number, endInclusive: number): Promise<Buffer>;
249
+ private get;
250
+ delete(key: string): Promise<void>;
251
+ exists(key: string): Promise<boolean>;
252
+ }
253
+
134
254
  interface OptimizeOptions {
135
255
  /** Downscale (aspect ratio preserved, Lanczos) if wider than this. Never upscales. */
136
256
  maxWidth?: number;
@@ -188,7 +308,13 @@ interface ZeroBucketOptions<C = unknown> {
188
308
  connectionString?: string;
189
309
  /** Bring your own pg.Pool. It is NOT closed by close(). */
190
310
  pool?: Pool;
191
- /** Advanced: inject a custom StorageBackend instead of building a PostgresBackend. */
311
+ /**
312
+ * Use SQLite instead of PostgreSQL: a database file path (or ":memory:"). Needs `npm install better-sqlite3`.
313
+ * `dedup`, `objectStorage`, `autoMigrate` and `onOperation` apply to it too. Same file format as the Python
314
+ * package's SQLiteBackend, so both can share one `.db` file.
315
+ */
316
+ sqlite?: string;
317
+ /** Advanced: inject a custom StorageBackend instead of building one from `connectionString` / `pool` / `sqlite`. */
192
318
  backend?: StorageBackend;
193
319
  /** Max accepted size in bytes. Default 8 MiB. */
194
320
  maxBytes?: number;
@@ -204,6 +330,19 @@ interface ZeroBucketOptions<C = unknown> {
204
330
  poolTimeoutMs?: number;
205
331
  /** Fire-and-forget observability. Exceptions thrown inside it are swallowed. */
206
332
  onOperation?: (event: OperationEvent) => void;
333
+ /**
334
+ * S3-compatible object storage, enabling `tierToObjectStorage()` and transparent
335
+ * reads of images the Python or Node package tiered. Configure it with the same
336
+ * bucket and credentials used to tier. Without it, reading a tiered image throws
337
+ * a clear StorageError.
338
+ */
339
+ objectStorage?: ObjectStorageLike;
340
+ /**
341
+ * Content-addressed mode: identical bytes are stored once and shared by reference, each image
342
+ * keeping its own id and filename. Cannot be combined with `objectStorage`. Uses separate tables
343
+ * (zerobucket_blobs / zerobucket_image_refs); see `migrateClassicToDedup()` for existing data.
344
+ */
345
+ dedup?: boolean;
207
346
  /**
208
347
  * Authorization hook for get / getMany (per id) / getStream / streamTo / metadata.
209
348
  * Return false to deny. A hook that THROWS fails closed: the exception
@@ -222,7 +361,7 @@ interface PutBase<C> {
222
361
  /** Store non-image content through the same machinery. Incompatible with `optimize`. */
223
362
  validator?: ContentValidator;
224
363
  /** Join your own transaction. ZeroBucket then does not commit, roll back or retry. */
225
- connection?: Queryable;
364
+ connection?: Connection;
226
365
  /** Passed to beforePut. */
227
366
  context?: C;
228
367
  }
@@ -232,7 +371,7 @@ interface PutManyOptions<C = unknown> extends Omit<PutBase<C>, "filename"> {
232
371
  filenames?: (string | null | undefined)[];
233
372
  }
234
373
  interface GetOptions<C = unknown> {
235
- connection?: Queryable;
374
+ connection?: Connection;
236
375
  context?: C;
237
376
  }
238
377
  interface StreamOptions<C = unknown> extends GetOptions<C> {
@@ -302,6 +441,21 @@ declare class ZeroBucket<C = unknown> {
302
441
  delete(imageId: string, options?: Pick<CallOptions, "connection">): Promise<boolean>;
303
442
  /** Delete many in one query. Results are in input order; a missing id is `deleted: false`, not an error. */
304
443
  deleteMany(imageIds: string[], options?: Pick<CallOptions, "connection">): Promise<BatchDeleteResult[]>;
444
+ /**
445
+ * Move an image's bytes from Postgres into object storage; reads, streams and
446
+ * deletes keep working transparently. Returns true if tiered now, false if it was
447
+ * already tiered (safe to re-run in a backfill). Throws ImageNotFoundError if missing.
448
+ *
449
+ * The upload runs inside the database transaction: if it fails, the row is left
450
+ * completely untouched. Explicit and opt-in: put() never tiers automatically.
451
+ * Not gated by beforeGet/beforePut (it is a maintenance operation, as in the Python package).
452
+ */
453
+ tierToObjectStorage(imageId: string, options?: Pick<CallOptions, "connection">): Promise<boolean>;
454
+ /**
455
+ * One-time, non-destructive copy of classic-mode images into a dedup instance's tables, keeping every
456
+ * id. Call it on an instance created with `dedup: true`. Safe to re-run. See PostgresBackend for details.
457
+ */
458
+ migrateClassicToDedup(): ReturnType<NonNullable<StorageBackend["migrateClassicToDedup"]>>;
305
459
  /** Release the pool (if ZeroBucket created it). */
306
460
  close(): Promise<void>;
307
461
  }
@@ -316,4 +470,4 @@ declare function readInput(image: ImageInput, filename: string | undefined, maxB
316
470
  filename: string | undefined;
317
471
  }>;
318
472
 
319
- export { type BatchDeleteResult as B, type CallOptions as C, DEFAULT_MAX_BYTES as D, type GetOptions as G, type Image as I, type OperationEvent as O, type PreparedRow as P, type Queryable as Q, type StorageBackend as S, type ValidatedContent as V, type WritableLike as W, ZeroBucket as Z, type StoredRecord as a, type StoredRecordMetadata as b, type StreamOptions$1 as c, type ContentValidator as d, type BatchGetResult as e, type BatchPutResult as f, type BeforeGetHook as g, type BeforePutHook as h, type ImageInput as i, type ImageMetadata as j, type OptimizationResult as k, type OptimizeOptions as l, type PutManyOptions as m, type PutOptions as n, type StreamOptions as o, type ZeroBucketOptions as p, optimizeImage as q, readInput as r };
473
+ export { type BatchDeleteResult as B, type CallOptions as C, DEFAULT_MAX_BYTES as D, type GetOptions as G, type ImageListOptions as I, type OperationEvent as O, type PreparedRow as P, type Queryable as Q, type StorageBackend as S, type ValidatedContent as V, type WritableLike as W, ZeroBucket as Z, type ObjectStorageLike as a, type StoredRecord as b, type StoredRecordMetadata as c, type StreamOptions$1 as d, type StorageInfo as e, type ImageListEntry as f, type ContentValidator as g, type BatchGetResult as h, type BatchPutResult as i, type BeforeGetHook as j, type BeforePutHook as k, type Connection as l, type Image as m, type ImageInput as n, type ImageMetadata as o, ObjectStorage as p, type ObjectStorageOptions as q, type OptimizationResult as r, type OptimizeOptions as s, type PutManyOptions as t, type PutOptions as u, type SqliteDatabaseLike as v, type StreamOptions as w, type ZeroBucketOptions as x, optimizeImage as y, readInput as z };
package/dist/http.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { IncomingMessage, ServerResponse } from 'node:http';
2
- import { Z as ZeroBucket } from './client-C_W0t8My.cjs';
2
+ import { Z as ZeroBucket } from './client-C7xs1dlr.cjs';
3
3
  import 'pg';
4
4
 
5
5
  /**
package/dist/http.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { IncomingMessage, ServerResponse } from 'node:http';
2
- import { Z as ZeroBucket } from './client-C_W0t8My.js';
2
+ import { Z as ZeroBucket } from './client-C7xs1dlr.js';
3
3
  import 'pg';
4
4
 
5
5
  /**