@tinycloud/sdk-services 3.1.0-beta.7 → 3.1.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.
@@ -1,5 +1,5 @@
1
- import { B as BaseService } from '../BaseService-C8zRy0ww.cjs';
2
- import { R as Result, I as IService } from '../types-qwMmB7qB.cjs';
1
+ import { B as BaseService } from '../BaseService-DWbPbov7.cjs';
2
+ import { R as Result, I as IService } from '../types-CVwwxqXF.cjs';
3
3
 
4
4
  /**
5
5
  * KV Service Types
@@ -333,6 +333,102 @@ interface KVListResponse {
333
333
  /** Opaque cursor for the next page, when the node returned one. */
334
334
  nextCursor?: string;
335
335
  }
336
+ /**
337
+ * Options for {@link IKVService.changes}, the `tinycloud.kv/sync` change feed.
338
+ */
339
+ interface KVChangesOptions {
340
+ /**
341
+ * The space-relative KV prefix to follow, sent as the invocation path. It
342
+ * is not joined with the service's configured prefix, and must be non-empty.
343
+ * Prefixes match whole path segments: `notes` covers `notes` and
344
+ * `notes/a`, while `notes/` covers everything under `notes/` but not
345
+ * `notes` itself. The session must hold `tinycloud.kv/sync` on it by name.
346
+ *
347
+ * Returned `changes[].key` values are full paths in the space, like this
348
+ * prefix. On a service with a configured prefix (for example
349
+ * `DelegatedAccess.kv`, whose prefix is the delegation path), `get` joins
350
+ * that prefix again, so strip it from the key first, or follow the feed
351
+ * with `kv.withPrefix(...).changes()`, which returns relative keys.
352
+ */
353
+ prefix: string;
354
+ /**
355
+ * The `cursor` from the previous page. Omit it to bootstrap from the start
356
+ * of the prefix. Opaque; never parse or build one.
357
+ */
358
+ cursor?: string;
359
+ /**
360
+ * Page size, 1 through 1000 (node default 500). A page never splits one
361
+ * invocation's changes, so it can hold more than `limit` changes.
362
+ */
363
+ limit?: number;
364
+ /**
365
+ * CID of a never-invoked delegation carrying `tinycloud.kv/retain` on the
366
+ * prefix. When valid, the node attests `authority.retainUntil`.
367
+ */
368
+ retentionGrant?: string;
369
+ /**
370
+ * Custom timeout for this operation in milliseconds. Overrides
371
+ * `KVServiceConfig.timeout`; `0` disables a configured timeout.
372
+ */
373
+ timeout?: number;
374
+ /**
375
+ * Custom abort signal for this operation.
376
+ */
377
+ signal?: AbortSignal;
378
+ }
379
+ /**
380
+ * One key's latest state in a change feed page. Content is not included:
381
+ * read it with `get`/`batchGet` and check it against `etag`.
382
+ */
383
+ type KVChange = {
384
+ key: string;
385
+ deleted: false;
386
+ /** The strong ETag `get` returns for this state. */
387
+ etag: string;
388
+ metadata: Record<string, string>;
389
+ } | {
390
+ key: string;
391
+ deleted: true;
392
+ };
393
+ /**
394
+ * The node-attested window in which the caller's authority holds. Values are
395
+ * RFC 3339 timestamps, or `null` when nothing in the chain sets one.
396
+ */
397
+ interface KVChangesAuthority {
398
+ /** The latest `nbf` across the invocation's whole delegation chain. */
399
+ notBefore: string | null;
400
+ /** The earliest `exp` across the invocation's whole delegation chain. */
401
+ expiresAt: string | null;
402
+ /**
403
+ * The earliest `exp` across a valid retention grant's own chain. `null`
404
+ * means no retention: none was presented, or its chain sets no expiry.
405
+ */
406
+ retainUntil: string | null;
407
+ }
408
+ /**
409
+ * One page of the `tinycloud.kv/sync` change feed.
410
+ */
411
+ interface KVChangesResponse {
412
+ /** Each changed key's latest state, in commit order. */
413
+ changes: KVChange[];
414
+ /**
415
+ * More changes are available now. A page may be empty with `more: true`;
416
+ * keep paging with the returned cursor.
417
+ */
418
+ more: boolean;
419
+ /**
420
+ * The cursor for the next request. An empty poll returns the request's
421
+ * cursor unchanged.
422
+ */
423
+ cursor: string;
424
+ /** The node, space and prefix that served the page. */
425
+ source: {
426
+ nodeDid: string;
427
+ space: string;
428
+ prefix: string;
429
+ };
430
+ authority: KVChangesAuthority;
431
+ }
336
432
  /**
337
433
  * Response from signed KV read URL creation.
338
434
  */
@@ -363,6 +459,10 @@ declare const KVAction: {
363
459
  readonly LIST: "tinycloud.kv/list";
364
460
  readonly DELETE: "tinycloud.kv/del";
365
461
  readonly HEAD: "tinycloud.kv/metadata";
462
+ /** The change feed; never implied by `*` or `tinycloud.kv/*`. */
463
+ readonly SYNC: "tinycloud.kv/sync";
464
+ /** Retention attestation; presented through `retentionGrant`, never invoked or implied. */
465
+ readonly RETAIN: "tinycloud.kv/retain";
366
466
  };
367
467
  type KVActionType = (typeof KVAction)[keyof typeof KVAction];
368
468
 
@@ -466,6 +566,20 @@ interface IPrefixedKVService {
466
566
  * ```
467
567
  */
468
568
  list(options?: Omit<KVListOptions, 'prefix'>): Promise<Result<KVListResponse>>;
569
+ /**
570
+ * Read one page of the change feed for everything under this prefix
571
+ * (`tinycloud.kv/sync` on `<prefix>/`). Keys are returned relative to the
572
+ * prefix, like `list`; `source.prefix` stays the node's full prefix.
573
+ * See `IKVService.changes` for paging and errors.
574
+ *
575
+ * @example
576
+ * ```typescript
577
+ * const notes = kv.withPrefix('notes');
578
+ * const page = await notes.changes({ limit: 100 });
579
+ * // -> Feed of: notes/*, keys like 'a.md'
580
+ * ```
581
+ */
582
+ changes(options?: Omit<KVChangesOptions, 'prefix'>): Promise<Result<KVChangesResponse>>;
469
583
  /**
470
584
  * Delete a key.
471
585
  *
@@ -540,6 +654,7 @@ interface IKVServiceLike {
540
654
  put(key: string, value: unknown, options?: KVPutOptions): Promise<Result<KVResponse<void>>>;
541
655
  batchPut(items: KVBatchPutItem[], options?: KVBatchPutOptions): Promise<Result<KVBatchPutResponse>>;
542
656
  list(options?: KVListOptions): Promise<Result<KVListResponse>>;
657
+ changes(options: KVChangesOptions): Promise<Result<KVChangesResponse>>;
543
658
  delete(key: string, options?: KVDeleteOptions): Promise<Result<KVResponse<void>>>;
544
659
  head(key: string, options?: KVHeadOptions): Promise<Result<KVResponse<void>>>;
545
660
  batchHead(keys: string[], options?: KVHeadOptions): Promise<Result<KVBatchReadResponse<void>>>;
@@ -621,6 +736,12 @@ declare class PrefixedKVService implements IPrefixedKVService {
621
736
  * List keys within this prefix.
622
737
  */
623
738
  list(options?: Omit<KVListOptions, 'prefix'>): Promise<Result<KVListResponse>>;
739
+ /**
740
+ * Read the change feed for everything under this prefix. A view with an
741
+ * empty prefix (`""` or `"/"`) is refused: the node does not serve a
742
+ * whole-space feed.
743
+ */
744
+ changes(options?: Omit<KVChangesOptions, 'prefix'>): Promise<Result<KVChangesResponse>>;
624
745
  /**
625
746
  * Delete a key.
626
747
  */
@@ -769,6 +890,41 @@ interface IKVService extends IService {
769
890
  */
770
891
  head(key: string, options?: KVHeadOptions): Promise<Result<KVResponse<void>>>;
771
892
  batchHead(keys: string[], options?: KVHeadOptions): Promise<Result<KVBatchReadResponse<void>>>;
893
+ /**
894
+ * Read one page of the ordered, delete-aware change feed for a KV prefix
895
+ * (`tinycloud.kv/sync`). Each change is a key's latest state; read content
896
+ * with `get`/`batchGet` and check it against the change's `etag`.
897
+ *
898
+ * `options.prefix` and every returned `key` are full paths in the space;
899
+ * the service's configured prefix is not applied to either. On a prefixed
900
+ * service (for example `DelegatedAccess.kv`), `get(change.key)` would join
901
+ * that prefix twice: strip the prefix from the key, or use
902
+ * `withPrefix(...).changes()`, which returns keys relative to the view.
903
+ *
904
+ * The session must hold `tinycloud.kv/sync` on `options.prefix` by name: no
905
+ * wildcard grants it. Page with the returned `cursor` while `more` is true;
906
+ * a page can exceed `limit`, or be empty with `more: true`.
907
+ *
908
+ * Errors: `KV_SYNC_RESET_REQUIRED` (410, `meta.reason`) means discard sync
909
+ * state and restart without a cursor. `AUTH_DELEGATION_REVOKED` and
910
+ * `AUTH_DELEGATION_ANCESTOR_REVOKED` mean the grant is revoked.
911
+ * `KV_RETENTION_GRANT_REFUSED` (403, `meta.reason`) rejects `retentionGrant`.
912
+ *
913
+ * Requires a node that advertises the `kv-sync-v1` feature in `/info`.
914
+ *
915
+ * @example
916
+ * ```typescript
917
+ * let cursor: string | undefined;
918
+ * do {
919
+ * const page = await kv.changes({ prefix: 'notes/', cursor });
920
+ * if (!page.ok) throw new Error(page.error.message);
921
+ * for (const change of page.data.changes) apply(change);
922
+ * cursor = page.data.cursor;
923
+ * if (!page.data.more) break;
924
+ * } while (true);
925
+ * ```
926
+ */
927
+ changes(options: KVChangesOptions): Promise<Result<KVChangesResponse>>;
772
928
  /**
773
929
  * Create a short-lived signed URL for reading a KV object.
774
930
  *
@@ -917,6 +1073,16 @@ declare class KVService extends BaseService implements IKVService {
917
1073
  private createResponseHeaders;
918
1074
  private createBatchResponseHeaders;
919
1075
  private parseBatchValue;
1076
+ /**
1077
+ * Validate a batch read response and return its items in the caller's
1078
+ * request order. The node flattens invocation abilities from a `BTreeMap`,
1079
+ * so results arrive sorted by UTF-8 byte order of the path, not in request
1080
+ * order. Items that carry their path in `key` are matched by path; if no
1081
+ * item carries a key, items are assumed to be in the node's byte-sorted
1082
+ * order and the request is aligned the same way. Any mix of keyed and
1083
+ * keyless items, a missing requested path, an unrequested path, or a
1084
+ * malformed item fails closed (returns undefined).
1085
+ */
920
1086
  private normalizeBatchReadResponse;
921
1087
  private batchRead;
922
1088
  /**
@@ -958,6 +1124,19 @@ declare class KVService extends BaseService implements IKVService {
958
1124
  * List keys with optional prefix filtering.
959
1125
  */
960
1126
  list(options?: KVListOptions): Promise<Result<KVListResponse>>;
1127
+ /**
1128
+ * Read one page of the `tinycloud.kv/sync` change feed for a prefix.
1129
+ */
1130
+ changes(options: KVChangesOptions): Promise<Result<KVChangesResponse>>;
1131
+ /**
1132
+ * Map a failed `kv/sync` response. 410 and the retention 403 carry
1133
+ * `{"error":{"code","reason"}}`; a revoked grant is a 401 whose whole body
1134
+ * is the node's revocation error (see REVOKED_BODY). A body read that
1135
+ * fails because the request was cancelled or timed out rethrows, so the
1136
+ * caller sees `ABORTED`/`TIMEOUT` rather than a mapped status.
1137
+ */
1138
+ private changesFailure;
1139
+ private normalizeChangesResponse;
961
1140
  /**
962
1141
  * Delete a key.
963
1142
  */
@@ -1016,4 +1195,4 @@ declare class KVService extends BaseService implements IKVService {
1016
1195
  withPrefix(prefix: string): IPrefixedKVService;
1017
1196
  }
1018
1197
 
1019
- export { DEFAULT_SIGNED_READ_URL_EXPIRY_MS, type IKVService, type IPrefixedKVService, KVAction, type KVActionType, type KVBatchPutItem, type KVBatchPutOptions, type KVBatchPutResponse, type KVBatchReadResponse, type KVCreateSignedReadUrlOptions, type KVDeleteOptions, type KVGetOptions, type KVHeadOptions, type KVListOptions, type KVListResponse, type KVPutOptions, type KVResponse, type KVResponseHeaders, KVService, type KVServiceConfig, type KVSignedReadUrlResponse, PrefixedKVService };
1198
+ export { DEFAULT_SIGNED_READ_URL_EXPIRY_MS, type IKVService, type IPrefixedKVService, KVAction, type KVActionType, type KVBatchPutItem, type KVBatchPutOptions, type KVBatchPutResponse, type KVBatchReadResponse, type KVChange, type KVChangesAuthority, type KVChangesOptions, type KVChangesResponse, type KVCreateSignedReadUrlOptions, type KVDeleteOptions, type KVGetOptions, type KVHeadOptions, type KVListOptions, type KVListResponse, type KVPutOptions, type KVResponse, type KVResponseHeaders, KVService, type KVServiceConfig, type KVSignedReadUrlResponse, PrefixedKVService };
@@ -1,5 +1,5 @@
1
- import { B as BaseService } from '../BaseService-DU-lE-Qx.js';
2
- import { R as Result, I as IService } from '../types-qwMmB7qB.js';
1
+ import { B as BaseService } from '../BaseService-B_UKhVht.js';
2
+ import { R as Result, I as IService } from '../types-CVwwxqXF.js';
3
3
 
4
4
  /**
5
5
  * KV Service Types
@@ -333,6 +333,102 @@ interface KVListResponse {
333
333
  /** Opaque cursor for the next page, when the node returned one. */
334
334
  nextCursor?: string;
335
335
  }
336
+ /**
337
+ * Options for {@link IKVService.changes}, the `tinycloud.kv/sync` change feed.
338
+ */
339
+ interface KVChangesOptions {
340
+ /**
341
+ * The space-relative KV prefix to follow, sent as the invocation path. It
342
+ * is not joined with the service's configured prefix, and must be non-empty.
343
+ * Prefixes match whole path segments: `notes` covers `notes` and
344
+ * `notes/a`, while `notes/` covers everything under `notes/` but not
345
+ * `notes` itself. The session must hold `tinycloud.kv/sync` on it by name.
346
+ *
347
+ * Returned `changes[].key` values are full paths in the space, like this
348
+ * prefix. On a service with a configured prefix (for example
349
+ * `DelegatedAccess.kv`, whose prefix is the delegation path), `get` joins
350
+ * that prefix again, so strip it from the key first, or follow the feed
351
+ * with `kv.withPrefix(...).changes()`, which returns relative keys.
352
+ */
353
+ prefix: string;
354
+ /**
355
+ * The `cursor` from the previous page. Omit it to bootstrap from the start
356
+ * of the prefix. Opaque; never parse or build one.
357
+ */
358
+ cursor?: string;
359
+ /**
360
+ * Page size, 1 through 1000 (node default 500). A page never splits one
361
+ * invocation's changes, so it can hold more than `limit` changes.
362
+ */
363
+ limit?: number;
364
+ /**
365
+ * CID of a never-invoked delegation carrying `tinycloud.kv/retain` on the
366
+ * prefix. When valid, the node attests `authority.retainUntil`.
367
+ */
368
+ retentionGrant?: string;
369
+ /**
370
+ * Custom timeout for this operation in milliseconds. Overrides
371
+ * `KVServiceConfig.timeout`; `0` disables a configured timeout.
372
+ */
373
+ timeout?: number;
374
+ /**
375
+ * Custom abort signal for this operation.
376
+ */
377
+ signal?: AbortSignal;
378
+ }
379
+ /**
380
+ * One key's latest state in a change feed page. Content is not included:
381
+ * read it with `get`/`batchGet` and check it against `etag`.
382
+ */
383
+ type KVChange = {
384
+ key: string;
385
+ deleted: false;
386
+ /** The strong ETag `get` returns for this state. */
387
+ etag: string;
388
+ metadata: Record<string, string>;
389
+ } | {
390
+ key: string;
391
+ deleted: true;
392
+ };
393
+ /**
394
+ * The node-attested window in which the caller's authority holds. Values are
395
+ * RFC 3339 timestamps, or `null` when nothing in the chain sets one.
396
+ */
397
+ interface KVChangesAuthority {
398
+ /** The latest `nbf` across the invocation's whole delegation chain. */
399
+ notBefore: string | null;
400
+ /** The earliest `exp` across the invocation's whole delegation chain. */
401
+ expiresAt: string | null;
402
+ /**
403
+ * The earliest `exp` across a valid retention grant's own chain. `null`
404
+ * means no retention: none was presented, or its chain sets no expiry.
405
+ */
406
+ retainUntil: string | null;
407
+ }
408
+ /**
409
+ * One page of the `tinycloud.kv/sync` change feed.
410
+ */
411
+ interface KVChangesResponse {
412
+ /** Each changed key's latest state, in commit order. */
413
+ changes: KVChange[];
414
+ /**
415
+ * More changes are available now. A page may be empty with `more: true`;
416
+ * keep paging with the returned cursor.
417
+ */
418
+ more: boolean;
419
+ /**
420
+ * The cursor for the next request. An empty poll returns the request's
421
+ * cursor unchanged.
422
+ */
423
+ cursor: string;
424
+ /** The node, space and prefix that served the page. */
425
+ source: {
426
+ nodeDid: string;
427
+ space: string;
428
+ prefix: string;
429
+ };
430
+ authority: KVChangesAuthority;
431
+ }
336
432
  /**
337
433
  * Response from signed KV read URL creation.
338
434
  */
@@ -363,6 +459,10 @@ declare const KVAction: {
363
459
  readonly LIST: "tinycloud.kv/list";
364
460
  readonly DELETE: "tinycloud.kv/del";
365
461
  readonly HEAD: "tinycloud.kv/metadata";
462
+ /** The change feed; never implied by `*` or `tinycloud.kv/*`. */
463
+ readonly SYNC: "tinycloud.kv/sync";
464
+ /** Retention attestation; presented through `retentionGrant`, never invoked or implied. */
465
+ readonly RETAIN: "tinycloud.kv/retain";
366
466
  };
367
467
  type KVActionType = (typeof KVAction)[keyof typeof KVAction];
368
468
 
@@ -466,6 +566,20 @@ interface IPrefixedKVService {
466
566
  * ```
467
567
  */
468
568
  list(options?: Omit<KVListOptions, 'prefix'>): Promise<Result<KVListResponse>>;
569
+ /**
570
+ * Read one page of the change feed for everything under this prefix
571
+ * (`tinycloud.kv/sync` on `<prefix>/`). Keys are returned relative to the
572
+ * prefix, like `list`; `source.prefix` stays the node's full prefix.
573
+ * See `IKVService.changes` for paging and errors.
574
+ *
575
+ * @example
576
+ * ```typescript
577
+ * const notes = kv.withPrefix('notes');
578
+ * const page = await notes.changes({ limit: 100 });
579
+ * // -> Feed of: notes/*, keys like 'a.md'
580
+ * ```
581
+ */
582
+ changes(options?: Omit<KVChangesOptions, 'prefix'>): Promise<Result<KVChangesResponse>>;
469
583
  /**
470
584
  * Delete a key.
471
585
  *
@@ -540,6 +654,7 @@ interface IKVServiceLike {
540
654
  put(key: string, value: unknown, options?: KVPutOptions): Promise<Result<KVResponse<void>>>;
541
655
  batchPut(items: KVBatchPutItem[], options?: KVBatchPutOptions): Promise<Result<KVBatchPutResponse>>;
542
656
  list(options?: KVListOptions): Promise<Result<KVListResponse>>;
657
+ changes(options: KVChangesOptions): Promise<Result<KVChangesResponse>>;
543
658
  delete(key: string, options?: KVDeleteOptions): Promise<Result<KVResponse<void>>>;
544
659
  head(key: string, options?: KVHeadOptions): Promise<Result<KVResponse<void>>>;
545
660
  batchHead(keys: string[], options?: KVHeadOptions): Promise<Result<KVBatchReadResponse<void>>>;
@@ -621,6 +736,12 @@ declare class PrefixedKVService implements IPrefixedKVService {
621
736
  * List keys within this prefix.
622
737
  */
623
738
  list(options?: Omit<KVListOptions, 'prefix'>): Promise<Result<KVListResponse>>;
739
+ /**
740
+ * Read the change feed for everything under this prefix. A view with an
741
+ * empty prefix (`""` or `"/"`) is refused: the node does not serve a
742
+ * whole-space feed.
743
+ */
744
+ changes(options?: Omit<KVChangesOptions, 'prefix'>): Promise<Result<KVChangesResponse>>;
624
745
  /**
625
746
  * Delete a key.
626
747
  */
@@ -769,6 +890,41 @@ interface IKVService extends IService {
769
890
  */
770
891
  head(key: string, options?: KVHeadOptions): Promise<Result<KVResponse<void>>>;
771
892
  batchHead(keys: string[], options?: KVHeadOptions): Promise<Result<KVBatchReadResponse<void>>>;
893
+ /**
894
+ * Read one page of the ordered, delete-aware change feed for a KV prefix
895
+ * (`tinycloud.kv/sync`). Each change is a key's latest state; read content
896
+ * with `get`/`batchGet` and check it against the change's `etag`.
897
+ *
898
+ * `options.prefix` and every returned `key` are full paths in the space;
899
+ * the service's configured prefix is not applied to either. On a prefixed
900
+ * service (for example `DelegatedAccess.kv`), `get(change.key)` would join
901
+ * that prefix twice: strip the prefix from the key, or use
902
+ * `withPrefix(...).changes()`, which returns keys relative to the view.
903
+ *
904
+ * The session must hold `tinycloud.kv/sync` on `options.prefix` by name: no
905
+ * wildcard grants it. Page with the returned `cursor` while `more` is true;
906
+ * a page can exceed `limit`, or be empty with `more: true`.
907
+ *
908
+ * Errors: `KV_SYNC_RESET_REQUIRED` (410, `meta.reason`) means discard sync
909
+ * state and restart without a cursor. `AUTH_DELEGATION_REVOKED` and
910
+ * `AUTH_DELEGATION_ANCESTOR_REVOKED` mean the grant is revoked.
911
+ * `KV_RETENTION_GRANT_REFUSED` (403, `meta.reason`) rejects `retentionGrant`.
912
+ *
913
+ * Requires a node that advertises the `kv-sync-v1` feature in `/info`.
914
+ *
915
+ * @example
916
+ * ```typescript
917
+ * let cursor: string | undefined;
918
+ * do {
919
+ * const page = await kv.changes({ prefix: 'notes/', cursor });
920
+ * if (!page.ok) throw new Error(page.error.message);
921
+ * for (const change of page.data.changes) apply(change);
922
+ * cursor = page.data.cursor;
923
+ * if (!page.data.more) break;
924
+ * } while (true);
925
+ * ```
926
+ */
927
+ changes(options: KVChangesOptions): Promise<Result<KVChangesResponse>>;
772
928
  /**
773
929
  * Create a short-lived signed URL for reading a KV object.
774
930
  *
@@ -917,6 +1073,16 @@ declare class KVService extends BaseService implements IKVService {
917
1073
  private createResponseHeaders;
918
1074
  private createBatchResponseHeaders;
919
1075
  private parseBatchValue;
1076
+ /**
1077
+ * Validate a batch read response and return its items in the caller's
1078
+ * request order. The node flattens invocation abilities from a `BTreeMap`,
1079
+ * so results arrive sorted by UTF-8 byte order of the path, not in request
1080
+ * order. Items that carry their path in `key` are matched by path; if no
1081
+ * item carries a key, items are assumed to be in the node's byte-sorted
1082
+ * order and the request is aligned the same way. Any mix of keyed and
1083
+ * keyless items, a missing requested path, an unrequested path, or a
1084
+ * malformed item fails closed (returns undefined).
1085
+ */
920
1086
  private normalizeBatchReadResponse;
921
1087
  private batchRead;
922
1088
  /**
@@ -958,6 +1124,19 @@ declare class KVService extends BaseService implements IKVService {
958
1124
  * List keys with optional prefix filtering.
959
1125
  */
960
1126
  list(options?: KVListOptions): Promise<Result<KVListResponse>>;
1127
+ /**
1128
+ * Read one page of the `tinycloud.kv/sync` change feed for a prefix.
1129
+ */
1130
+ changes(options: KVChangesOptions): Promise<Result<KVChangesResponse>>;
1131
+ /**
1132
+ * Map a failed `kv/sync` response. 410 and the retention 403 carry
1133
+ * `{"error":{"code","reason"}}`; a revoked grant is a 401 whose whole body
1134
+ * is the node's revocation error (see REVOKED_BODY). A body read that
1135
+ * fails because the request was cancelled or timed out rethrows, so the
1136
+ * caller sees `ABORTED`/`TIMEOUT` rather than a mapped status.
1137
+ */
1138
+ private changesFailure;
1139
+ private normalizeChangesResponse;
961
1140
  /**
962
1141
  * Delete a key.
963
1142
  */
@@ -1016,4 +1195,4 @@ declare class KVService extends BaseService implements IKVService {
1016
1195
  withPrefix(prefix: string): IPrefixedKVService;
1017
1196
  }
1018
1197
 
1019
- export { DEFAULT_SIGNED_READ_URL_EXPIRY_MS, type IKVService, type IPrefixedKVService, KVAction, type KVActionType, type KVBatchPutItem, type KVBatchPutOptions, type KVBatchPutResponse, type KVBatchReadResponse, type KVCreateSignedReadUrlOptions, type KVDeleteOptions, type KVGetOptions, type KVHeadOptions, type KVListOptions, type KVListResponse, type KVPutOptions, type KVResponse, type KVResponseHeaders, KVService, type KVServiceConfig, type KVSignedReadUrlResponse, PrefixedKVService };
1198
+ export { DEFAULT_SIGNED_READ_URL_EXPIRY_MS, type IKVService, type IPrefixedKVService, KVAction, type KVActionType, type KVBatchPutItem, type KVBatchPutOptions, type KVBatchPutResponse, type KVBatchReadResponse, type KVChange, type KVChangesAuthority, type KVChangesOptions, type KVChangesResponse, type KVCreateSignedReadUrlOptions, type KVDeleteOptions, type KVGetOptions, type KVHeadOptions, type KVListOptions, type KVListResponse, type KVPutOptions, type KVResponse, type KVResponseHeaders, KVService, type KVServiceConfig, type KVSignedReadUrlResponse, PrefixedKVService };