@cloudbitmaps/gcs 0.21.0 → 0.23.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudbitmaps/gcs",
3
- "version": "0.21.0",
3
+ "version": "0.23.0",
4
4
  "description": "Google Cloud Storage for CloudBitmaps",
5
5
  "keywords": [
6
6
  "cloudbitmaps",
@@ -36,7 +36,8 @@
36
36
  ".": {
37
37
  "types": "./dist/index.d.ts",
38
38
  "default": "./dist/index.js"
39
- }
39
+ },
40
+ "./package.json": "./package.json"
40
41
  },
41
42
  "files": [
42
43
  "dist",
@@ -49,7 +50,7 @@
49
50
  },
50
51
  "dependencies": {
51
52
  "@google-cloud/storage": "^7 || ^8",
52
- "@cloudbitmaps/core": "^0.21.0"
53
+ "@cloudbitmaps/core": "0.23.0"
53
54
  },
54
55
  "devDependencies": {
55
56
  "@types/node": "^22.0.0",
@@ -1,37 +0,0 @@
1
- /**
2
- * Whether the bucket a driver names exists, asked when a request first answers 404.
3
- *
4
- * GCS answers a missing bucket and a missing object with the same status and reason (`404 notFound`), and a
5
- * GCS-compatible server may not even word them apart. Read as a missing object, a misnamed or deleted bucket would
6
- * answer every read as an empty segment. An object listing tells them apart: it names no object, so its 404 can only
7
- * be the bucket's.
8
- *
9
- * ```
10
- * a request answers 404 ──▶ confirm() ──▶ bucket seen before? ── yes ──▶ the 404 is an object's
11
- * │ no
12
- * ▼
13
- * list one object in the bucket
14
- * ├─ answered ──────────▶ remember the bucket; the 404 is an object's
15
- * ├─ 404 ───────────────▶ reject: ValidationError, the bucket does not exist
16
- * ├─ transient ─────────▶ reject: TransientError (asked again next time)
17
- * ├─ 403 ───────────────▶ remember it as unknowable; the 404 is an object's
18
- * └─ anything else ─────▶ the 404 is an object's (asked again next time)
19
- * ```
20
- *
21
- * A process pays one listing at most while its bucket exists, and concurrent 404s share it. An identity without
22
- * `storage.objects.list` is answered `403`, which says nothing about the bucket, so its 404s read as they always did.
23
- * Any other failure (a credential that could not be fetched, a 401) says nothing either, but may not last, so it is
24
- * not remembered. Once seen, the bucket is not asked about again: one deleted later in the process's life reads as an
25
- * empty store, as it did before this check, while every write to it fails.
26
- */
27
- import type { Storage } from '@google-cloud/storage';
28
- export declare class BucketPresence {
29
- private readonly storage;
30
- private readonly bucket;
31
- private settled;
32
- private asking;
33
- constructor(storage: Storage, bucket: string);
34
- /** Resolve when a 404 can be read as an object's; reject with `ValidationError` when the bucket does not exist, `TransientError` when the listing failed in transit. */
35
- confirm(): Promise<void>;
36
- private ask;
37
- }
package/dist/crc32c.d.ts DELETED
@@ -1,5 +0,0 @@
1
- /**
2
- * CRC32C (Castagnoli) of some bytes, in the form GCS takes in an object's `crc32c` metadata: the 4-byte big-endian
3
- * value, base64-encoded. Computed here rather than through the SDK so it is the same on every major the driver accepts.
4
- */
5
- export declare function crc32cBase64(bytes: Uint8Array): string;
package/dist/defined.d.ts DELETED
@@ -1,8 +0,0 @@
1
- /**
2
- * `values` without the entries that are `undefined`, typed as optional properties, so a constructor can pass on the
3
- * options it was given: `exactOptionalPropertyTypes` refuses `{ x: undefined }` for an optional `x`, and a sub-driver
4
- * must see an option the caller left out as absent.
5
- */
6
- export declare function defined<T extends Record<string, unknown>>(values: T): {
7
- [K in keyof T]?: Exclude<T[K], undefined>;
8
- };
@@ -1,8 +0,0 @@
1
- import { type Deadline } from './read-timeout.js';
2
- /** Under a deadline, a retry is not sent with less than this left of it. */
3
- export declare const MIN_RETRY_MS = 10;
4
- /**
5
- * Call `download`, and again after each retryable fault, up to {@link RETRIES} more times, within `deadline` when there
6
- * is one; rethrow the last error, or the deadline's once it has passed.
7
- */
8
- export declare function retryDownload<T>(download: () => Promise<T>, deadline?: Deadline): Promise<T>;
@@ -1,60 +0,0 @@
1
- /**
2
- * Pure helpers for classifying Google Cloud Storage SDK errors (the transient class mirrors S3's).
3
- *
4
- * SDK-free + side-effect-free — they only read structural shapes off the thrown value (`err.code`,
5
- * `err.response.status`, `err.name`), so the GCS-specific translation is unit-testable without a live GCS or
6
- * an emulator, and without importing `@google-cloud/storage`. GCS's `ApiError` carries the HTTP status on
7
- * `.code` (a number); dropped/timed-out sockets surface as a Node error with a string `.code` (`ECONNRESET`,
8
- * `ETIMEDOUT`, …).
9
- */
10
- import { ValidationError } from '@cloudbitmaps/core/driver-kit';
11
- /**
12
- * A conditional `ifGenerationMatch: 0` write lost the write-once race — the object already existed, so GCS
13
- * returns **412 Precondition Failed**. Maps to `WriteConflictError` (caller OCC), never a blind retry.
14
- */
15
- export declare function isPreconditionFailed(err: unknown): boolean;
16
- /**
17
- * GCS asked the client to slow down: `429` (`rateLimitExceeded`) or `503` (`backendError`), which the SDK raises as an
18
- * `ApiError` with the status as a numeric `code`. GCS does not document that a throttled request was not applied, so
19
- * an upload sent again after one must still tell a landed first send apart.
20
- */
21
- export declare function isThrottle(err: unknown): boolean;
22
- /** The object / generation does not exist (GCS returns 404), in a bucket that does. */
23
- export declare function isNotFound(err: unknown): boolean;
24
- /**
25
- * The bucket itself does not exist: a wiring fault, never an absent object. Read as one, a misnamed or deleted bucket
26
- * would answer every read as an empty segment. GCS gives both the same status and reason (`404 notFound`), so only its
27
- * message tells them apart: on a download the message is the response body as it came, JSON or text, and elsewhere
28
- * the message and each `errors[].message` are GCS's own. A wording this does not match reads as an absent object.
29
- */
30
- export declare function isMissingBucket(err: unknown): boolean;
31
- /**
32
- * The {@link ValidationError} a missing bucket is: it names the bucket and what to check, and carries the service's
33
- * error as its `cause`. A wiring fault is not an absent object, so it is not a `NotFoundError`: a read re-resolves on
34
- * that, and would treat a misnamed bucket as a miss it can heal.
35
- */
36
- export declare function missingBucketError(bucket: string, cause: unknown): ValidationError;
37
- /** `err`, or {@link missingBucketError} when `err` says the bucket does not exist. */
38
- export declare function asMissingBucket(err: unknown, bucket: string): unknown;
39
- /** A range request started past EOF (HTTP 416 Requested Range Not Satisfiable). */
40
- export declare function isInvalidRange(err: unknown): boolean;
41
- /** A download that failed in transit rather than with an HTTP status: a connection fault ({@link isConnectionFault}). */
42
- export declare function isTransportFault(err: unknown): boolean;
43
- /**
44
- * Whether the driver retries a failed download, which it does in the SDK's place: the statuses the SDK's predicate
45
- * retries (408, 429, 500, 502, 503 and 504, as a number or a string `code`), the connection faults it names in any
46
- * `errors[].reason`, and every {@link isTransportFault}, which the SDK retried before any response came. A 404, 412,
47
- * 416 or 403, a 501 or 505, a credentials or TLS failure, and every other answer reach the caller on the first attempt.
48
- */
49
- export declare function isDownloadRetryable(err: unknown): boolean;
50
- /**
51
- * A transient GCS fault that is safe to retry: throttling (429), a request timeout (408), any 5xx, or a dropped/timed-out socket.
52
- * Excludes the deterministic, caller-meaningful outcomes (412/404/416) — those must never be reclassified as
53
- * a blind transient (a retried doomed conditional write would just fail again, and mask an OCC conflict).
54
- */
55
- export declare function isTransient(err: unknown): boolean;
56
- /**
57
- * The message a transient GCS fault is handed on with: `transient GCS fault: <code>`, the HTTP status the SDK puts on
58
- * `code` or Node's connection code, else the error's name.
59
- */
60
- export declare function transientFaultMessage(err: unknown): string;
@@ -1,6 +0,0 @@
1
- import type { Storage } from '@google-cloud/storage';
2
- /**
3
- * A twin of `client` that sends each download once, or `client` itself when it is a test double whose retries are off.
4
- * `supplied`: the caller handed `client` in, rather than the backend building it.
5
- */
6
- export declare function downloadClient(client: Storage, supplied: boolean): Storage;
@@ -1,52 +0,0 @@
1
- /**
2
- * `readOnce` — read one object, or one range of it, in a single GET, with the response headers in hand.
3
- *
4
- * `file.download()` returns only the bytes. The headers carry what a caller needs alongside them — the object's
5
- * `generation` (the registry's version fence) and, on a ranged read, the object's total size in `Content-Range` — so
6
- * this reads through `createReadStream`, which announces the raw response before any data flows. Both come from the
7
- * same response as the bytes, so they describe one observation of the object.
8
- *
9
- * **Everything on the wire is untrusted.** The advertised `Content-Length` is checked against `maxBytes` before the
10
- * first byte is buffered, and the bytes are counted as they arrive, so a response that understates its length (or
11
- * omits it) still cannot make the caller hold more than `maxBytes`. The headers are returned as received; each caller
12
- * parses the ones it relies on strictly.
13
- *
14
- * **Every download stays off the SDK's shared connection pool.** When a download fails part-way — a body cut off, a
15
- * refused response, a timeout — the SDK destroys the HTTP agent the request went out on, to free its socket. By default
16
- * that is one keep-alive agent the whole process shares (teeny-request's, for every request with `forever: true`), so
17
- * every other request in flight on any client is reset with it, uploads included. {@link downloadFile} sets
18
- * `forever: false` on its own requests, through the SDK's request interceptors: they then go out on Node's global
19
- * agent, which the SDK never destroys, and on `@google-cloud/storage` 8.x a destroyed download closes its own socket
20
- * and nothing else. The cost: the global agent closes a connection idle for 5 seconds, where the SDK's pool keeps it,
21
- * so a read after a longer pause opens a new one; and it is shared with the process's other `http` and `https` code.
22
- */
23
- import type { Storage } from '@google-cloud/storage';
24
- import type { Deadline } from './read-timeout.js';
25
- type GcsFile = ReturnType<ReturnType<Storage['bucket']>['file']>;
26
- /** A handle on `name` for downloading: its requests stay off the SDK's shared agent. The client is not touched. */
27
- export declare function downloadFile(storage: Storage, bucket: string, name: string): GcsFile;
28
- export interface ObjectRead {
29
- /** The HTTP status of the response (200 for a whole object, 206 for a range). */
30
- readonly status: number;
31
- /** The response headers, lower-cased as Node delivers them. */
32
- readonly headers: Readonly<Record<string, string | string[] | undefined>>;
33
- /** The body, at most `maxBytes` long. */
34
- readonly bytes: Uint8Array;
35
- }
36
- /** The value of a header that must appear once, or `undefined` when it is absent, repeated or empty. */
37
- export declare function singleHeader(headers: ObjectRead['headers'], name: string): string | undefined;
38
- /**
39
- * GET `file` (with the SDK's `createReadStream` options), buffering at most `maxBytes`. `oversize` builds the error
40
- * thrown when the advertised or actual length passes the cap, so each caller reports it in its own vocabulary.
41
- * Transport and HTTP errors reject as the SDK raises them (a 404 carries `code: 404`).
42
- *
43
- * With a `deadline`, a read still unsettled when it passes rejects with its `ReadTimedOut`; one asked for after it has
44
- * passed is not sent. The deadline belongs to the whole driver read, so an attempt gets only what is left of it.
45
- */
46
- export declare function readOnce(file: GcsFile, options: {
47
- start?: number;
48
- end?: number;
49
- validation?: false;
50
- decompress?: false;
51
- }, maxBytes: number, oversize: (size: number | undefined) => Error, deadline?: Deadline): Promise<ObjectRead>;
52
- export {};
@@ -1,28 +0,0 @@
1
- /** Validate a caller's `readTimeoutMs`, defaulting it: an integer from 0 (no timeout) to {@link MAX_TIMER_MS}. */
2
- export declare function resolveReadTimeoutMs(value: unknown): number;
3
- /** A read the driver gave up on when its deadline passed. Coded `ETIMEDOUT`, as a timed-out connection is. */
4
- export declare class ReadTimedOut extends Error {
5
- readonly code = "ETIMEDOUT";
6
- constructor(read: string, ms: number, cause?: unknown);
7
- }
8
- /** One driver read's deadline: `ms` from when it is made. `read` names the read in the error, e.g. `tail read of s.3`. */
9
- export declare class Deadline {
10
- readonly ms: number;
11
- readonly read: string;
12
- private readonly endsAt;
13
- constructor(ms: number, read: string);
14
- /** What is left of it, in milliseconds: 0 once it has passed. */
15
- remaining(): number;
16
- /** The error a read fails with once this has passed; `cause` is the last attempt's own error, if one failed. */
17
- expired(cause?: unknown): ReadTimedOut;
18
- }
19
- /** The deadline a read made now runs under, or none when `ms` is 0 (no timeout). */
20
- export declare function startDeadline(ms: number, read: string): Deadline | undefined;
21
- /**
22
- * Make the request `send` starts, and settle with it, or with {@link ReadTimedOut} once `deadline` has passed; a
23
- * deadline already passed sends nothing. For a request the SDK cannot cancel: a metadata read is one callback-style
24
- * request that returns no handle to abort it, so at the deadline this stops waiting and the request runs on until it is
25
- * answered or its connection closes. The race keeps a handler on the request, so what it settles with then is dropped
26
- * rather than raised.
27
- */
28
- export declare function withDeadline<T>(send: () => Promise<T>, deadline: Deadline | undefined): Promise<T>;
@@ -1,90 +0,0 @@
1
- /**
2
- * `GcsRegistryDriver` — an {@link IRegistryDriver} over Google Cloud Storage.
3
- *
4
- * Lets a **GCS deployment run on one bucket alone** — storage `.crbm` generations and the registry in the same
5
- * place, with no second cloud involved.
6
- *
7
- * The protocol (an ABA-safe OCC token, the delete and its tombstone, the bounded retry, the key layout) lives once
8
- * in {@link ObjectStoreRegistry}; this file is only the I/O calls GCS makes. A delete removes a row for good, under
9
- * `ifGenerationMatch: <generation>`, when `conditionalDelete` is `true`. It is off by default, on the public endpoint too:
10
- * no run against real GCS has verified that the service applies the precondition to a delete, and fake-gcs-server
11
- * accepts it and ignores it, so CI cannot show it.
12
- *
13
- * **The atomic swap is offloaded to GCS's object preconditions.** `ifGenerationMatch: 0` is create-only
14
- * ("only if it does not exist") and `ifGenerationMatch: <generation>` is compare-and-swap — the same pair S3
15
- * spells `If-None-Match: *` / `If-Match: <etag>`. A lost race returns `412` → {@link WriteConflictError}. Each write
16
- * is one request sent once ({@link saveOnce}), so a `412` means another write got there first, never this one meeting
17
- * itself after a lost response. A transient failure reaches the caller as {@link TransientError}: the write may or may
18
- * not have landed, and the caller re-reads the row to learn where it stands.
19
- *
20
- * **The version fence is the object's `generation`, not its ETag**: GCS mutates the generation on every
21
- * overwrite and it is the value `ifGenerationMatch` compares, so it is the only correct fence here. (Note
22
- * the unrelated collision of vocabulary — a GCS *object generation* has nothing to do with a CloudBitmaps
23
- * `.crbm` *generation*.) Reads are strongly consistent, satisfying the registry's `strongRead` contract.
24
- *
25
- * **Deployment requirements** (a policy that violates these silently corrupts the registry):
26
- * - The principal needs `storage.objects.get`, `create`, `update`, `list` and, to remove rows, `delete` on the
27
- * bucket. Without `list`
28
- * the registry cannot enumerate, and a missing-object read may surface as `403` rather than `404`.
29
- * - **Do not apply an Object Lifecycle rule to the `registry/` prefix that deletes a live object** (one on
30
- * noncurrent versions only is safe), and do not enable a retention
31
- * policy that blocks overwrite or deletion; see {@link ObjectStoreRegistry}.
32
- * - Object versioning is neither required nor used; the driver always reads the live generation. A read is one
33
- * GET whose `x-goog-generation` header and body describe the same object, so a concurrent overwrite is simply
34
- * observed as the older or the newer row, never as a torn pair or a missing one.
35
- */
36
- import { ObjectStoreRegistry } from '@cloudbitmaps/core/driver-kit';
37
- import type { ObjectRegistryStore, ObjectRow } from '@cloudbitmaps/core/driver-kit';
38
- import type { Storage } from '@google-cloud/storage';
39
- interface GcsRegistryDriverOptions {
40
- /** A constructed `@google-cloud/storage` `Storage` client (point `apiEndpoint` at fake-gcs-server locally). */
41
- readonly storage: Storage;
42
- /** The client the downloads go through; `storage` when absent (see `GcsStorageDriverOptions.readStorage`). */
43
- readonly readStorage?: Storage;
44
- /** Target bucket (must already exist). */
45
- readonly bucket: string;
46
- /** Optional object-name prefix under which all registry objects live (e.g. `cloudbitmaps/`). */
47
- readonly prefix?: string;
48
- /** Injected clock for `createdAt`/`updatedAt`; defaults to `Date.now`. */
49
- readonly now?: () => number;
50
- /**
51
- * Cut off a read of a registry row once it has run this long, in milliseconds, every attempt included; `0` (the
52
- * default) sets no timeout. Timed as the storage driver's reads are (see `GcsStorageDriverOptions.readTimeoutMs`);
53
- * the writes and listings are not timed.
54
- */
55
- readonly readTimeoutMs?: number;
56
- /**
57
- * Whether a delete removes a row for good, by an object delete sent with `ifGenerationMatch: <the generation it
58
- * read>`, rather than leaving a tombstone. Defaults to `false`, on the public endpoint too: whether real GCS applies
59
- * `ifGenerationMatch` to a delete has not been verified by a run against the service, and fake-gcs-server accepts the
60
- * precondition and ignores it, so CI cannot show it. Set `true` to remove rows for good.
61
- */
62
- readonly conditionalDelete?: boolean;
63
- }
64
- /** The calls {@link ObjectStoreRegistry} needs, in GCS's dialect. Exported for the tests that drive one directly. */
65
- export declare class GcsRegistryStore implements ObjectRegistryStore {
66
- private readonly storage;
67
- private readonly readStorage;
68
- private readonly bucket;
69
- private readonly readTimeoutMs;
70
- readonly conditionalDelete: boolean;
71
- readonly label = "GCS";
72
- private readonly presence;
73
- constructor(storage: Storage, readStorage: Storage, bucket: string, readTimeoutMs: number, conditionalDelete: boolean);
74
- /** A handle on one registry object. */
75
- private file;
76
- /** The same file handle on the download client, off the SDK's shared agent ({@link downloadFile}). */
77
- private downloadable;
78
- read(key: string): Promise<ObjectRow | null>;
79
- write(key: string, body: Uint8Array, expect: 'absent' | {
80
- version: string;
81
- }): Promise<void>;
82
- delete(key: string, expect: {
83
- version: string;
84
- }): Promise<void>;
85
- listKeys(prefix: string): AsyncIterable<string>;
86
- }
87
- export declare class GcsRegistryDriver extends ObjectStoreRegistry {
88
- constructor(options: GcsRegistryDriverOptions);
89
- }
90
- export {};
@@ -1,18 +0,0 @@
1
- /**
2
- * Make an error the SDK raised safe to throw, or to keep as a `cause`: a copy of it with no credential and none of the
3
- * live transport.
4
- *
5
- * The SDK keeps the request it sent on the error (`response.request`, `config.headers`, the raw request line), and
6
- * through that request the HTTP agent it shares with every other call, whose sockets hold the raw text, bearer token
7
- * included, of requests still in flight. An application that logs the error or its cause chain would write a live
8
- * access token. The error is therefore replaced by a copy built from what it is: its prototype, name, message, stack,
9
- * code, status and other plain data; `response` reduced to its status; the request, agent, socket and config dropped.
10
- * Nothing live is ever changed, only read, and the copy is made from plain data alone, so no depth or size limit can
11
- * stop short of a secret. A credential header or header line in the plain data that is kept is redacted.
12
- */
13
- /**
14
- * `err` as it is safe to throw: a credential-free copy of an error that holds the SDK's request or response, and any
15
- * other value as it is (a timeout, a connection fault or an error of the driver's own holds no credential, and keeps
16
- * its identity).
17
- */
18
- export declare function scrubCredentials<T>(err: T): T;
@@ -1,5 +0,0 @@
1
- import type { CreateWriteStreamOptions, Storage } from '@google-cloud/storage';
2
- type GcsFile = ReturnType<ReturnType<Storage['bucket']>['file']>;
3
- /** Upload `body` to `file` in one request, sent once; resolves once GCS has stored it and its checksum matched. */
4
- export declare function saveOnce(file: GcsFile, body: Uint8Array, options: CreateWriteStreamOptions): Promise<void>;
5
- export {};
package/dist/storage.d.ts DELETED
@@ -1,109 +0,0 @@
1
- import type { BlobSink, GenKey, IStorageDriver, SegmentRef, StorageCaps, StorageDeleteOptions, TailRead } from '@cloudbitmaps/core/driver-kit';
2
- import type { Clock, Rng } from '@cloudbitmaps/core';
3
- import type { Storage } from '@google-cloud/storage';
4
- /** What the throttle backoff waits on. */
5
- type Sleeper = Pick<Clock, 'sleep'>;
6
- interface GcsStorageDriverOptions {
7
- /** A constructed `@google-cloud/storage` `Storage` client (point `apiEndpoint` at fake-gcs-server locally). */
8
- readonly storage: Storage;
9
- /**
10
- * The client the downloads go through; `storage` when absent. `GcsStorage` passes one built with the SDK's request
11
- * retries off (the read client built in its constructor), because a download the SDK retries can crash the process;
12
- * the driver retries a download itself instead.
13
- */
14
- readonly readStorage?: Storage;
15
- /** Target bucket (must already exist). */
16
- readonly bucket: string;
17
- /** Optional object-name prefix under which all objects live (e.g. `cloudbitmaps/`). */
18
- readonly prefix?: string;
19
- /** Largest object this driver will write/advertise (default = GCS's 5 TiB max). Must be a positive safe integer. */
20
- readonly maxObjectBytes?: number;
21
- /** Bytes at/under which a single non-resumable upload is used instead of a resumable stream (default 8 MiB).
22
- * Must be a positive safe integer. */
23
- readonly simpleUploadThresholdBytes?: number;
24
- /**
25
- * Cut off a read that has run this long, in milliseconds: a tail read (with the metadata read it falls back on for
26
- * an empty object) or a range read, every attempt and the backoff between them included. `0` (the default) sets no
27
- * timeout. The clock starts at the call into the driver, so a credential fetch counts, and runs until the body has
28
- * ended; when it passes the read throws `TransientError` and no further attempt starts. Uploads, deletes and
29
- * listings are not timed. A non-negative safe integer no larger than 2,147,483,647.
30
- */
31
- readonly readTimeoutMs?: number;
32
- /** What the backoff before re-sending a throttled upload waits on; real time when absent. */
33
- readonly clock?: Sleeper;
34
- /** Where the jitter of that backoff is drawn from; `Math.random` when absent. */
35
- readonly rng?: Rng;
36
- /**
37
- * Whether a delete given `ifVersion` is sent with `ifGenerationMatch`, so it removes the object only while it is the
38
- * one that generation names. Defaults to `false`, on the public endpoint too, as the registry's option does: whether
39
- * real GCS applies `ifGenerationMatch` to a delete has not been verified by a run against the service, and
40
- * fake-gcs-server accepts the precondition and ignores it. Set `true` once you have. Until it is set, a delete
41
- * decided from one read of an object removes whatever is under the name by then: on GCS the window in which an
42
- * erasure's stalled delete takes a generation a load put under the number since stays open.
43
- */
44
- readonly conditionalDelete?: boolean;
45
- }
46
- export declare class GcsStorageDriver implements IStorageDriver {
47
- private readonly storage;
48
- private readonly readStorage;
49
- private readonly bucket;
50
- private readonly prefix;
51
- private readonly maxObjectBytes;
52
- private readonly threshold;
53
- private readonly readTimeoutMs;
54
- private readonly clock;
55
- private readonly rng;
56
- private readonly presence;
57
- private readonly conditionalDelete;
58
- constructor(options: GcsStorageDriverOptions);
59
- capabilities(): StorageCaps;
60
- private file;
61
- /** The same object on the download client, off the SDK's shared agent ({@link downloadFile}). */
62
- private downloadable;
63
- /** The deadline a read of `key` made now runs under, every attempt included, named for its error; none when off. */
64
- private deadline;
65
- putImmutable(key: GenKey, write: (sink: BlobSink) => Promise<void>): Promise<{
66
- size: number;
67
- sha256: string;
68
- }>;
69
- getRange(key: GenKey, offset: number, length: number): Promise<Uint8Array>;
70
- /**
71
- * Refuse a range response unless it is exactly the bytes asked for. A 206 must name them in `Content-Range: bytes
72
- * a-b/total`, starting at `offset`, and hold that many; a 200 (a server that ignored the range) is the whole object,
73
- * which is the range only when the range starts at 0. A short read means the range ran past the end of the object:
74
- * out of bounds, never a partial result.
75
- */
76
- private checkRange;
77
- private badRange;
78
- getTail(key: GenKey, maxBytes: number): Promise<TailRead>;
79
- /**
80
- * The object's size from its metadata, validated, and its generation when the metadata names a usable one. Read on the
81
- * download client and retried as a download is, within the calling read's `deadline` ({@link withDeadline}), so
82
- * nothing but the one request in flight runs past it.
83
- */
84
- private metadataOf;
85
- /**
86
- * The object's total size from a tail response, refused unless every header agrees with the bytes received. A 206
87
- * must carry `Content-Range: bytes a-b/total` that names exactly the suffix asked for and exactly the bytes held;
88
- * a 200 (a server that ignored the range) is the whole object, and is accepted only when it fits in the request.
89
- */
90
- private tailSize;
91
- private badTail;
92
- delete(key: GenKey, options?: StorageDeleteOptions): Promise<void>;
93
- /** Whether an object is under the name, from its metadata. A read that fails in any other way throws. */
94
- private exists;
95
- list(ref: SegmentRef): AsyncIterable<GenKey>;
96
- /** A read's error, once a 404 is known to be the object's and not the bucket's ({@link BucketPresence}). */
97
- private readFailure;
98
- /** Map GCS read errors to the driver vocabulary; pass everything else through {@link mapError}. */
99
- private mapReadError;
100
- /**
101
- * Reclassify a transient GCS fault (throttle/5xx/dropped connection) as a retryable {@link TransientError}, so the
102
- * store's read retry can ride it out and a write's caller can tell it from a deterministic failure, and a missing
103
- * bucket as a `ValidationError` that names it; everything else propagates unchanged. The final fallback at every
104
- * client-call site: an HTTP status and a fault in transit arrive typed, and anything else (a checksum mismatch, a
105
- * credentials failure) as the SDK raised it.
106
- */
107
- private mapError;
108
- }
109
- export {};