@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.
- package/dist/{BaseService-DU-lE-Qx.d.ts → BaseService-B_UKhVht.d.ts} +1 -1
- package/dist/{BaseService-C8zRy0ww.d.cts → BaseService-DWbPbov7.d.cts} +1 -1
- package/dist/encryption/index.cjs +8 -0
- package/dist/encryption/index.cjs.map +1 -1
- package/dist/encryption/index.d.cts +2 -2
- package/dist/encryption/index.d.ts +2 -2
- package/dist/encryption/index.js +8 -0
- package/dist/encryption/index.js.map +1 -1
- package/dist/index.cjs +760 -169
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +108 -17
- package/dist/index.d.ts +108 -17
- package/dist/index.js +760 -169
- package/dist/index.js.map +1 -1
- package/dist/internal/decrypt-transport-response-error.d.cts +1 -1
- package/dist/internal/decrypt-transport-response-error.d.ts +1 -1
- package/dist/kv/index.cjs +256 -9
- package/dist/kv/index.cjs.map +1 -1
- package/dist/kv/index.d.cts +182 -3
- package/dist/kv/index.d.ts +182 -3
- package/dist/kv/index.js +256 -9
- package/dist/kv/index.js.map +1 -1
- package/dist/sql/index.cjs +8 -0
- package/dist/sql/index.cjs.map +1 -1
- package/dist/sql/index.d.cts +2 -2
- package/dist/sql/index.d.ts +2 -2
- package/dist/sql/index.js +8 -0
- package/dist/sql/index.js.map +1 -1
- package/dist/{types-qwMmB7qB.d.cts → types-CVwwxqXF.d.cts} +8 -0
- package/dist/{types-qwMmB7qB.d.ts → types-CVwwxqXF.d.ts} +8 -0
- package/package.json +3 -3
package/dist/kv/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as BaseService } from '../BaseService-
|
|
2
|
-
import { R as Result, I as IService } from '../types-
|
|
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 };
|
package/dist/kv/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as BaseService } from '../BaseService-
|
|
2
|
-
import { R as Result, I as IService } from '../types-
|
|
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 };
|