@tinycloud/sdk-services 3.2.6-beta.4 → 3.3.0-beta.25

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.
Files changed (45) hide show
  1. package/dist/{BaseService-1Ug6y7DC.d.cts → BaseService-BhfKzKke.d.cts} +5 -1
  2. package/dist/{BaseService-Bn07Vudy.d.ts → BaseService-x4AFZiEa.d.ts} +5 -1
  3. package/dist/encryption/index.cjs +25 -4
  4. package/dist/encryption/index.cjs.map +1 -1
  5. package/dist/encryption/index.d.cts +2 -2
  6. package/dist/encryption/index.d.ts +2 -2
  7. package/dist/encryption/index.js +25 -4
  8. package/dist/encryption/index.js.map +1 -1
  9. package/dist/index.cjs +959 -808
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +114 -7
  12. package/dist/index.d.ts +114 -7
  13. package/dist/index.js +958 -808
  14. package/dist/index.js.map +1 -1
  15. package/dist/internal/decrypt-transport-response-error.d.cts +1 -1
  16. package/dist/internal/decrypt-transport-response-error.d.ts +1 -1
  17. package/dist/kv/index.cjs +136 -99
  18. package/dist/kv/index.cjs.map +1 -1
  19. package/dist/kv/index.d.cts +4 -5
  20. package/dist/kv/index.d.ts +4 -5
  21. package/dist/kv/index.js +136 -99
  22. package/dist/kv/index.js.map +1 -1
  23. package/dist/kv/replication/grantPolicy.cjs +82 -0
  24. package/dist/kv/replication/grantPolicy.cjs.map +1 -0
  25. package/dist/kv/replication/grantPolicy.d.cts +19 -0
  26. package/dist/kv/replication/grantPolicy.d.ts +19 -0
  27. package/dist/kv/replication/grantPolicy.js +50 -0
  28. package/dist/kv/replication/grantPolicy.js.map +1 -0
  29. package/dist/kv/replication/index.cjs +576 -132
  30. package/dist/kv/replication/index.cjs.map +1 -1
  31. package/dist/kv/replication/index.d.cts +3 -3
  32. package/dist/kv/replication/index.d.ts +3 -3
  33. package/dist/kv/replication/index.js +576 -132
  34. package/dist/kv/replication/index.js.map +1 -1
  35. package/dist/{scope-BnyVPZ5E.d.ts → scope-9U4gVNFN.d.ts} +312 -7
  36. package/dist/{scope-CQ5kmHlt.d.cts → scope-BzdcrOZG.d.cts} +312 -7
  37. package/dist/sql/index.cjs +98 -50
  38. package/dist/sql/index.cjs.map +1 -1
  39. package/dist/sql/index.d.cts +2 -2
  40. package/dist/sql/index.d.ts +2 -2
  41. package/dist/sql/index.js +98 -50
  42. package/dist/sql/index.js.map +1 -1
  43. package/dist/{types-gmdUiorz.d.cts → types-eVS1Whuf.d.cts} +29 -3
  44. package/dist/{types-gmdUiorz.d.ts → types-eVS1Whuf.d.ts} +29 -3
  45. package/package.json +16 -2
package/dist/index.d.cts CHANGED
@@ -1,11 +1,11 @@
1
- import { a as IServiceContext, c as InvokeFunction, d as InvokeAnyFunction, F as FetchFunction, S as ServiceSession, e as RetryPolicy, T as TelemetryConfig, I as IService, E as EventHandler, b as ServiceError, R as Result, P as PermissionHint, f as StorageQuotaInfo } from './types-gmdUiorz.cjs';
2
- export { g as ErrorCode, h as ErrorCodes, i as FetchRequestInit, j as FetchResponse, k as InvocationFact, l as InvocationFacts, m as InvokeAnyEntry, n as ServiceErrorEvent, o as ServiceHeaders, p as ServiceRequestEvent, q as ServiceResponseEvent, r as ServiceRetryEvent, s as TelemetryEventHandler, t as TelemetryEvents, u as TelemetrySpanEvent, v as defaultRetryPolicy, w as err, x as ok, y as serviceError } from './types-gmdUiorz.cjs';
1
+ import { a as IServiceContext, g as InvokeFunction, h as InvokeAnyFunction, f as FetchFunction, S as ServiceSession, i as RetryPolicy, T as TelemetryConfig, I as IService, E as EventHandler, F as FetchRequestInit, d as FetchResponse, b as ServiceError, R as Result, P as PermissionHint, j as StorageQuotaInfo } from './types-eVS1Whuf.cjs';
2
+ export { k as ErrorCode, l as ErrorCodes, m as InvocationFact, n as InvocationFacts, o as InvokeAnyEntry, e as RetryStats, p as ServiceErrorEvent, c as ServiceHeaders, q as ServiceRequestEvent, r as ServiceResponseEvent, s as ServiceRetryEvent, t as TelemetryEventHandler, u as TelemetryEvents, v as TelemetrySpanEvent, w as defaultRetryPolicy, x as err, y as ok, z as serviceError } from './types-eVS1Whuf.cjs';
3
3
  import { z } from 'zod';
4
- import { B as BaseService } from './BaseService-1Ug6y7DC.cjs';
5
- export { a as BaseServiceOptions, R as RequestSignal, S as ServiceConstructor, b as ServiceRegistration } from './BaseService-1Ug6y7DC.cjs';
4
+ import { B as BaseService } from './BaseService-BhfKzKke.cjs';
5
+ export { a as BaseServiceOptions, R as RequestSignal, S as ServiceConstructor, b as ServiceRegistration } from './BaseService-BhfKzKke.cjs';
6
6
  import { IKVService } from './kv/index.cjs';
7
7
  export { IPrefixedKVService, KVService, PrefixedKVService } from './kv/index.cjs';
8
- export { A as AuthorityRefusal, C as CLEAR_PENDING_WARNING, ah as DEFAULT_SIGNED_READ_URL_EXPIRY_MS, ai as KVAction, aj as KVActionType, ak as KVBatchPutItem, al as KVBatchPutOptions, am as KVBatchPutResponse, an as KVBatchReadResponse, ao as KVChange, ap as KVChangesAuthority, aq as KVChangesOptions, ar as KVChangesResponse, as as KVCreateSignedReadUrlOptions, at as KVDeleteOptions, au as KVGetOptions, av as KVHeadOptions, aw as KVListOptions, b as KVListPage, ax as KVListResponse, ay as KVPutOptions, c as KVReadThrough, d as KVReplicaHandle, e as KVReplicaSpec, f as KVReplicaStorage, a as KVReplicationController, K as KVReplicationDeps, az as KVResponse, aA as KVResponseHeaders, aB as KVServiceConfig, aC as KVSignedReadUrlResponse, L as LocalGetResult, g as LocalListResult, h as LocalReadMeta, i as LocalReplicaStatus, j as LocalSyncResult, k as PendingWriteRecord, l as PendingWriteState, P as PendingWriteStore, m as PinnedKey, n as PurgeTarget, o as ReplicaAccountGate, p as ReplicaAdmitHook, q as ReplicaAuthorityState, r as ReplicaBrowserGateAccess, s as ReplicaBrowserGateSnapshot, t as ReplicaBrowserGateTx, u as ReplicaBrowserPageAdmission, v as ReplicaClock, w as ReplicaCoverage, x as ReplicaDeliveryDecision, y as ReplicaDenyInput, z as ReplicaDenyOutcome, B as ReplicaDevice, D as ReplicaEraseReport, E as ReplicaGateAccess, F as ReplicaGateReason, G as ReplicaGateScope, H as ReplicaGateSnapshot, I as ReplicaGateTx, J as ReplicaGatedError, M as ReplicaGatedHandle, N as ReplicaGatedSpec, O as ReplicaGatedStorage, Q as ReplicaGrantInfo, S as ReplicaGuardedStore, T as ReplicaInspectedStatus, U as ReplicaLifecycleGate, V as ReplicaPageAdmission, W as ReplicaPartitionEraser, X as ReplicaPartitionIndexEntry, Y as ReplicaPeerCommit, Z as ReplicaPrivateGateHash, _ as ReplicaPurgeIntent, $ as ReplicaQuotaLedger, a0 as ReplicaQuotaSpec, a1 as ReplicaSessionStamp, a2 as ReplicaStampedReply, a3 as ReplicaState, a4 as ReplicaStatusEntry, a5 as ReplicationAuthority, a6 as ReplicationControl, a7 as ReplicationEvent, R as ReplicationIdentity, a8 as ReplicationOptions, a9 as ReplicationPurgeReport, aa as ReplicationReason, ab as ReplicationScheduler, ac as ResolvedReplicationOptions, ad as SaltedHash, ae as canonicalReplicationIdentity, af as replicationIdentityKey, ag as requiresSecretsOptIn } from './scope-CQ5kmHlt.cjs';
8
+ export { A as AuthorityRefusal, C as CLEAR_PENDING_WARNING, aq as DEFAULT_SIGNED_READ_URL_EXPIRY_MS, ar as KVAction, as as KVActionType, at as KVBatchPutItem, au as KVBatchPutOptions, av as KVBatchPutResponse, aw as KVBatchReadResponse, ax as KVChange, ay as KVChangesAuthority, az as KVChangesOptions, aA as KVChangesResponse, aB as KVCreateSignedReadUrlOptions, aC as KVDeleteOptions, aD as KVGetOptions, aE as KVHeadOptions, aF as KVListOptions, b as KVListPage, aG as KVListResponse, aH as KVPutOptions, c as KVReadThrough, d as KVReplicaHandle, e as KVReplicaSpec, f as KVReplicaStorage, a as KVReplicationController, K as KVReplicationDeps, aI as KVResponse, aJ as KVResponseHeaders, aK as KVServiceConfig, aL as KVSignedReadUrlResponse, L as LocalGetResult, g as LocalListResult, h as LocalReadMeta, i as LocalReplicaStatus, j as LocalSyncResult, k as PendingWriteRecord, l as PendingWriteState, P as PendingWriteStore, m as PinnedKey, w as PurgeTarget, x as ReplicaAccountGate, y as ReplicaAdmitHook, z as ReplicaAuthorityState, B as ReplicaBrowserGateAccess, D as ReplicaBrowserGateSnapshot, E as ReplicaBrowserGateTx, F as ReplicaBrowserPageAdmission, G as ReplicaClock, H as ReplicaCoverage, I as ReplicaDeliveryDecision, J as ReplicaDenyInput, M as ReplicaDenyOutcome, N as ReplicaDevice, O as ReplicaEraseReport, Q as ReplicaGateAccess, S as ReplicaGateReason, T as ReplicaGateScope, U as ReplicaGateSnapshot, V as ReplicaGateTx, W as ReplicaGatedError, X as ReplicaGatedHandle, Y as ReplicaGatedSpec, Z as ReplicaGatedStorage, _ as ReplicaGrantInfo, $ as ReplicaGuardedStore, a0 as ReplicaInspectedStatus, a1 as ReplicaLifecycleGate, a2 as ReplicaPageAdmission, a3 as ReplicaPartitionEraser, a4 as ReplicaPartitionIndexEntry, a5 as ReplicaPeerCommit, a6 as ReplicaPrivateGateHash, a7 as ReplicaPurgeIntent, a8 as ReplicaQuotaLedger, a9 as ReplicaQuotaSpec, aa as ReplicaSessionStamp, ab as ReplicaStampedReply, ac as ReplicaState, ad as ReplicaStatusEntry, ae as ReplicationAuthority, af as ReplicationControl, ag as ReplicationEvent, R as ReplicationIdentity, ah as ReplicationOptions, ai as ReplicationPurgeReport, aj as ReplicationReason, ak as ReplicationScheduler, al as ResolvedReplicationOptions, am as SaltedHash, an as canonicalReplicationIdentity, ao as replicationIdentityKey, ap as requiresSecretsOptIn } from './scope-BzdcrOZG.cjs';
9
9
  export { ClampConsentAnchor, ConsentDeadlineMs, EffectiveGrantExpiry, EffectiveGrantExpiryInput, MintRemainingMs, NeedsSilentRenewal, ReplicaConsentAnchor, ReplicaConsentSource, ReplicaGrantPolicy } from './kv/replication/grantPolicyTypes.cjs';
10
10
  export { BatchOptions, BatchResponse, DatabaseHandle, ExecuteOptions, ExecuteResponse, IDatabaseHandle, ISQLMigrations, ISQLService, QueryOptions, QueryResponse, SQLAction, SQLActionType, SQLMigrations, SQLService, SQLServiceConfig, SqlMigration, SqlMigrationApplyOptions, SqlMigrationApplyResponse, SqlStatement, SqlValue } from './sql/index.cjs';
11
11
  import { IEncryptionService, DecryptCapabilityProof } from './encryption/index.cjs';
@@ -717,18 +717,22 @@ declare const RetryPolicySchema: z.ZodObject<{
717
717
  maxDelayMs: z.ZodNumber;
718
718
  /** Error codes that should trigger a retry */
719
719
  retryableErrors: z.ZodArray<z.ZodString, "many">;
720
+ /** Total time budget for all attempts and waits, in milliseconds */
721
+ maxTotalMs: z.ZodOptional<z.ZodNumber>;
720
722
  }, "strip", z.ZodTypeAny, {
721
723
  maxAttempts: number;
722
724
  backoff: "none" | "linear" | "exponential";
723
725
  baseDelayMs: number;
724
726
  maxDelayMs: number;
725
727
  retryableErrors: string[];
728
+ maxTotalMs?: number | undefined;
726
729
  }, {
727
730
  maxAttempts: number;
728
731
  backoff: "none" | "linear" | "exponential";
729
732
  baseDelayMs: number;
730
733
  maxDelayMs: number;
731
734
  retryableErrors: string[];
735
+ maxTotalMs?: number | undefined;
732
736
  }>;
733
737
  type RetryPolicyType = z.infer<typeof RetryPolicySchema>;
734
738
  /**
@@ -1037,6 +1041,8 @@ declare class ServiceContext implements IServiceContext {
1037
1041
  private wrapInvoke;
1038
1042
  private assertActive;
1039
1043
  private wrapInvokeAny;
1044
+ /** Retry `NODE_BUSY` / `REQUEST_TIMEOUT`; `build` must re-sign per attempt (the node 409s a repeated invocation). */
1045
+ invokeWithRetry(url: string, build: () => FetchRequestInit | Promise<FetchRequestInit>): Promise<FetchResponse>;
1040
1046
  private wrapFetch;
1041
1047
  private combineSignals;
1042
1048
  }
@@ -1057,6 +1063,30 @@ declare function authExpiredError(service: string): ServiceError;
1057
1063
  * Create a service error for network issues.
1058
1064
  */
1059
1065
  declare function networkError(service: string, message: string, cause?: Error): ServiceError;
1066
+ /**
1067
+ * Classify a node retry signal (tinycloud-node #347, TC-1054). The node's
1068
+ * bodies are plain text led by a stable token:
1069
+ * - `503 sql_busy: <stage>: ...` and `503 unavailable_retryable: ...` (and
1070
+ * `read_audit_busy`) are `NODE_BUSY`: nothing was applied; retry after `meta.retryAfterMs`.
1071
+ * - `503 request_timeout: ...` is `REQUEST_TIMEOUT`: the deadline passed before
1072
+ * any write began, so nothing was applied.
1073
+ * - `500 outcome_unknown: ...` is `OUTCOME_UNKNOWN`: a write may have been
1074
+ * applied; read back before retrying a non-idempotent operation.
1075
+ *
1076
+ * `meta.retryable` is the safe-to-retry verdict and `meta.retryAfterMs` the
1077
+ * node's `Retry-After` (the node sends whole seconds; anything else is
1078
+ * ignored). `invokeWithRetry` retries `NODE_BUSY` and `REQUEST_TIMEOUT`;
1079
+ * `OUTCOME_UNKNOWN` is never retried. Returns `undefined` for any
1080
+ * other response, including the bodyless 503/500 of nodes before 1.21, which
1081
+ * callers keep classifying as they always did.
1082
+ */
1083
+ declare function nodeRetryError(service: string, message: string, response: {
1084
+ status: number;
1085
+ statusText: string;
1086
+ headers: {
1087
+ get(name: string): string | null;
1088
+ };
1089
+ }, errorText: string): ServiceError | undefined;
1060
1090
  /**
1061
1091
  * Create a service error for timeouts.
1062
1092
  *
@@ -1871,6 +1901,19 @@ interface VaultPutOptions {
1871
1901
  * fails with `ALREADY_EXISTS`; it is never overwritten.
1872
1902
  */
1873
1903
  ifNoneMatch?: "*";
1904
+ /**
1905
+ * Compare-and-swap: write only when the stored envelope still has this
1906
+ * strong ETag, passed exactly as {@link VaultEntry.etag} returned it
1907
+ * (including the quotes). Network-encrypted vaults only; cannot be combined
1908
+ * with `ifNoneMatch`.
1909
+ *
1910
+ * Failures are distinct codes: `ETAG_MISMATCH` (the value changed or was
1911
+ * deleted: re-read, re-apply, retry), `INVALID_ETAG` (malformed; never
1912
+ * retry), `OUTCOME_UNKNOWN` (the node may have applied the write, or a gateway
1913
+ * answered for it: read it back before retrying, with a freshly signed request) and `NODE_BUSY`
1914
+ * (nothing was written; retry).
1915
+ */
1916
+ ifMatch?: string;
1874
1917
  }
1875
1918
  /**
1876
1919
  * Options for vault get operations.
@@ -1880,8 +1923,25 @@ interface VaultGetOptions<T = unknown> {
1880
1923
  deserialize?: (data: Uint8Array) => T;
1881
1924
  /** Return raw decrypted bytes without deserialization */
1882
1925
  raw?: boolean;
1883
- /** Force the underlying KV read to bypass replica read-through. */
1926
+ /**
1927
+ * Force the underlying KV read to bypass replica read-through. Required for
1928
+ * a usable {@link VaultEntry.etag}: only network reads return one, because
1929
+ * a replica can serve a stale etag.
1930
+ */
1884
1931
  source?: "network";
1932
+ /**
1933
+ * Opt-in (default off): refuse an envelope whose AAD is not bound to this
1934
+ * vault's space and this key (`tinycloud.vault:<spaceId>:<key>`). The space
1935
+ * id is compared after normalizing the spelling of its EVM addresses
1936
+ * (checksummed and lowercase are the same space). An envelope with no AAD,
1937
+ * or with a different one, fails with `AAD_MISMATCH` (`aad_mismatch` from
1938
+ * `readNetworkEncrypted`) instead of decrypting. This stops a ciphertext
1939
+ * copied to another key from being accepted; it does not stop a freshly
1940
+ * encrypted forgery. A malformed stored value is a corrupt envelope, as without this
1941
+ * option. Network-encrypted vaults only: a master-key vault and `getShared` refuse it with
1942
+ * `STORAGE_ERROR` rather than skip the check.
1943
+ */
1944
+ expectAad?: boolean;
1885
1945
  /** Delegated KV service for reading from the grantor's space (used by getShared) */
1886
1946
  kv?: {
1887
1947
  get<V>(key: string, options?: {
@@ -1936,6 +1996,12 @@ interface VaultEntry<T> {
1936
1996
  metadata: Record<string, string>;
1937
1997
  /** Key ID used for encryption */
1938
1998
  keyId: string;
1999
+ /**
2000
+ * Strong ETag of the stored envelope, for {@link VaultPutOptions.ifMatch}.
2001
+ * Present only for network-encrypted reads made with `source: "network"`
2002
+ * (always for `readNetworkEncrypted`); never taken from a replica.
2003
+ */
2004
+ etag?: string;
1939
2005
  }
1940
2006
  /**
1941
2007
  * Safe classification for a network-encrypted vault read.
@@ -1962,6 +2028,10 @@ type VaultNetworkReadResult<T> = {
1962
2028
  status: "decrypt_failed";
1963
2029
  } | {
1964
2030
  status: "invalid_payload";
2031
+ }
2032
+ /** Only with `expectAad`: the envelope is not bound to this space and key. */
2033
+ | {
2034
+ status: "aad_mismatch";
1965
2035
  };
1966
2036
  /**
1967
2037
  * Structured error codes for vault operations.
@@ -2019,6 +2089,43 @@ type VaultErrorInput = {
2019
2089
  meta?: Record<string, unknown>;
2020
2090
  /** The typed KV error that refused the write (an `Error` carrying its `code`, `service` and `meta`). */
2021
2091
  cause: ServiceError & Error;
2092
+ } | {
2093
+ /** `expectAad` read: the envelope's AAD is missing or bound to another space/key. */
2094
+ code: "AAD_MISMATCH";
2095
+ key: string;
2096
+ message: string;
2097
+ } | {
2098
+ /** `ifMatch` write refused (HTTP 412): the value changed or no longer exists. Re-read and retry. */
2099
+ code: "ETAG_MISMATCH";
2100
+ key: string;
2101
+ message: string;
2102
+ meta?: Record<string, unknown>;
2103
+ cause: ServiceError & Error;
2104
+ } | {
2105
+ /** `ifMatch` is not a strong ETag (HTTP 400, or rejected before sending). Never retry. */
2106
+ code: "INVALID_ETAG";
2107
+ key: string;
2108
+ message: string;
2109
+ meta?: Record<string, unknown>;
2110
+ cause?: ServiceError & Error;
2111
+ } | {
2112
+ /**
2113
+ * `ifMatch` write that may have been applied: the node's `outcome_unknown` (500), a gateway
2114
+ * answer that can follow a commit (500, 502, 503 without the node's busy body, 504, 520,
2115
+ * 522, 524) or a connection that failed after the request was sent. Re-read before retrying.
2116
+ */
2117
+ code: "OUTCOME_UNKNOWN";
2118
+ key: string;
2119
+ message: string;
2120
+ meta?: Record<string, unknown>;
2121
+ cause: ServiceError & Error;
2122
+ } | {
2123
+ /** `ifMatch` write, the node's own busy/timeout answer (503 with its busy body): nothing was written. Safe to retry. */
2124
+ code: "NODE_BUSY";
2125
+ key: string;
2126
+ message: string;
2127
+ meta?: Record<string, unknown>;
2128
+ cause: ServiceError & Error;
2022
2129
  } | {
2023
2130
  code: "STORAGE_QUOTA_EXCEEDED" | "STORAGE_LIMIT_REACHED";
2024
2131
  message: string;
@@ -2584,4 +2691,4 @@ declare class SecretsService implements ISecretsService {
2584
2691
  listAll(): Promise<Result<SecretCatalogEntry[], SecretsError>>;
2585
2692
  }
2586
2693
 
2587
- export { type AuthorizationVerdict, BaseService, type ColumnInfo, type DataVaultConfig, DataVaultService, DecryptCapabilityProof, DuckDbAction, type DuckDbActionType, type DuckDbBatchOptions, type BatchResponse as DuckDbBatchResponse, DuckDbDatabaseHandle, type DuckDbExecuteOptions, type ExecuteResponse as DuckDbExecuteResponse, type DuckDbOptions, type DuckDbQueryOptions, type QueryResponse as DuckDbQueryResponse, DuckDbService, type DuckDbServiceConfig, type DuckDbStatement, type DuckDbValue, EventHandler, FetchFunction, GenericKVResponseSchema, type GenericKVResponseType, GenericResultSchema, type HookEvent, type HookServiceName, type HookStreamEvent, type HookStreamRetryConfig, type HookSubscription, type HookWebhookListOptions, type HookWebhookRecord, type HookWebhookRegistration, type HookWebhookScope, type HookWebhookUnregisterOptions, HooksService, type HooksServiceConfig, type IDataVaultService, type IDuckDbDatabaseHandle, type IDuckDbService, IEncryptionService, type IHooksService, IKVService, type ISecretsService, IService, IServiceContext, type IStorageService, InvokeAnyFunction, InvokeFunction, KVListResponseSchema, type KVListResponseType, KVListResultSchema, type KVListResultType, KVResponseHeadersSchema, type KVResponseHeadersType, MAX_SECRET_SCOPE_LENGTH, type ParsedSecretCatalogKey, PermissionHint, type QuotaConfig, type QuotaStatus, type ResolvedSecretPath, Result, RetryPolicy, RetryPolicySchema, type RetryPolicyType, SECRET_NAME_RE, SECRET_SCOPE_RE, STORAGE_FULL_MESSAGE, STORAGE_MANAGE_URL, STORAGE_NEARLY_FULL_RATIO, STORAGE_WRITE_TOO_LARGE_MESSAGE, type SchemaInfo, type SecretCatalogEntry, type SecretPayload, type SecretPutOptions, type SecretScopeOptions, type SecretsError, SecretsService, ServiceContext, type ServiceContextConfig, ServiceError, ServiceErrorEventSchema, type ServiceErrorEventType, ServiceErrorSchema, type ServiceErrorType, ServiceRequestEventSchema, type ServiceRequestEventType, ServiceResponseEventSchema, type ServiceResponseEventType, ServiceRetryEventSchema, type ServiceRetryEventType, ServiceSession, ServiceSessionSchema, type ServiceSessionType, type StorageAccountUsage, type StorageFullEvent, type StorageFullHandler, StorageFullMonitor, StorageQuotaInfo, type StorageRejectionDetails, type StorageStatus, type StorageStatusOptions, type StorageUsage, type StorageUsageState, type SubscribeOptions, TC832_RESERVED_SCOPES, type TableInfo, TelemetryConfig, TelemetrySpanEventSchema, type TelemetrySpanEventType, type TinyCloudDebugEnableOptions, type TinyCloudDebugEvent, type TinyCloudDebugLevel, TinyCloudDebugLogger, type TinyCloudDebugTimer, TinyCloudQuota, type ValidationError, type VaultCrypto, type VaultEntry, type VaultError, type VaultGetOptions, type VaultGrantOptions, VaultHeaders, type VaultListOptions, type VaultListPage, type VaultNetworkReadResult, VaultPublicSpaceKVActions, type VaultPutOptions, type ViewInfo, type WasmVaultFunctions, abortedError, appSecretScope, authExpiredError, authRequiredError, authUnauthorizedError, authorizationVerdictOf, canonicalizeSecretScope, clearTinyCloudDebugLogs, createKVResponseSchema, createResultSchema, createVaultCrypto, disableTinyCloudDebug, enableTinyCloudDebug, errorResult, getTinyCloudDebugLogs, installTinyCloudDebugGlobals, isStorageFullError, networkError, notFoundError, parseAuthError, parseCapabilityResource, parsePermissionHint, parsePermissionHintFromErrorText, parseSecretCatalogKey, parseStorageQuotaBytes, parseStorageRejection, parseStorageStatus, permissionDeniedError, resolveSecretListPrefix, resolveSecretPath, storageLimitReachedError, storageQuotaExceededError, storageRejectionError, storageUsageState, timeoutError, tinyCloudDebugLogger, validateKVListResponse, validateKVResponseHeaders, validateRetryPolicy, validateServiceError, validateServiceRequestEvent, validateServiceResponseEvent, validateServiceSession, validateTelemetrySpanEvent, validatedCapabilityOf, wrapError };
2694
+ export { type AuthorizationVerdict, BaseService, type ColumnInfo, type DataVaultConfig, DataVaultService, DecryptCapabilityProof, DuckDbAction, type DuckDbActionType, type DuckDbBatchOptions, type BatchResponse as DuckDbBatchResponse, DuckDbDatabaseHandle, type DuckDbExecuteOptions, type ExecuteResponse as DuckDbExecuteResponse, type DuckDbOptions, type DuckDbQueryOptions, type QueryResponse as DuckDbQueryResponse, DuckDbService, type DuckDbServiceConfig, type DuckDbStatement, type DuckDbValue, EventHandler, FetchFunction, FetchRequestInit, FetchResponse, GenericKVResponseSchema, type GenericKVResponseType, GenericResultSchema, type HookEvent, type HookServiceName, type HookStreamEvent, type HookStreamRetryConfig, type HookSubscription, type HookWebhookListOptions, type HookWebhookRecord, type HookWebhookRegistration, type HookWebhookScope, type HookWebhookUnregisterOptions, HooksService, type HooksServiceConfig, type IDataVaultService, type IDuckDbDatabaseHandle, type IDuckDbService, IEncryptionService, type IHooksService, IKVService, type ISecretsService, IService, IServiceContext, type IStorageService, InvokeAnyFunction, InvokeFunction, KVListResponseSchema, type KVListResponseType, KVListResultSchema, type KVListResultType, KVResponseHeadersSchema, type KVResponseHeadersType, MAX_SECRET_SCOPE_LENGTH, type ParsedSecretCatalogKey, PermissionHint, type QuotaConfig, type QuotaStatus, type ResolvedSecretPath, Result, RetryPolicy, RetryPolicySchema, type RetryPolicyType, SECRET_NAME_RE, SECRET_SCOPE_RE, STORAGE_FULL_MESSAGE, STORAGE_MANAGE_URL, STORAGE_NEARLY_FULL_RATIO, STORAGE_WRITE_TOO_LARGE_MESSAGE, type SchemaInfo, type SecretCatalogEntry, type SecretPayload, type SecretPutOptions, type SecretScopeOptions, type SecretsError, SecretsService, ServiceContext, type ServiceContextConfig, ServiceError, ServiceErrorEventSchema, type ServiceErrorEventType, ServiceErrorSchema, type ServiceErrorType, ServiceRequestEventSchema, type ServiceRequestEventType, ServiceResponseEventSchema, type ServiceResponseEventType, ServiceRetryEventSchema, type ServiceRetryEventType, ServiceSession, ServiceSessionSchema, type ServiceSessionType, type StorageAccountUsage, type StorageFullEvent, type StorageFullHandler, StorageFullMonitor, StorageQuotaInfo, type StorageRejectionDetails, type StorageStatus, type StorageStatusOptions, type StorageUsage, type StorageUsageState, type SubscribeOptions, TC832_RESERVED_SCOPES, type TableInfo, TelemetryConfig, TelemetrySpanEventSchema, type TelemetrySpanEventType, type TinyCloudDebugEnableOptions, type TinyCloudDebugEvent, type TinyCloudDebugLevel, TinyCloudDebugLogger, type TinyCloudDebugTimer, TinyCloudQuota, type ValidationError, type VaultCrypto, type VaultEntry, type VaultError, type VaultGetOptions, type VaultGrantOptions, VaultHeaders, type VaultListOptions, type VaultListPage, type VaultNetworkReadResult, VaultPublicSpaceKVActions, type VaultPutOptions, type ViewInfo, type WasmVaultFunctions, abortedError, appSecretScope, authExpiredError, authRequiredError, authUnauthorizedError, authorizationVerdictOf, canonicalizeSecretScope, clearTinyCloudDebugLogs, createKVResponseSchema, createResultSchema, createVaultCrypto, disableTinyCloudDebug, enableTinyCloudDebug, errorResult, getTinyCloudDebugLogs, installTinyCloudDebugGlobals, isStorageFullError, networkError, nodeRetryError, notFoundError, parseAuthError, parseCapabilityResource, parsePermissionHint, parsePermissionHintFromErrorText, parseSecretCatalogKey, parseStorageQuotaBytes, parseStorageRejection, parseStorageStatus, permissionDeniedError, resolveSecretListPrefix, resolveSecretPath, storageLimitReachedError, storageQuotaExceededError, storageRejectionError, storageUsageState, timeoutError, tinyCloudDebugLogger, validateKVListResponse, validateKVResponseHeaders, validateRetryPolicy, validateServiceError, validateServiceRequestEvent, validateServiceResponseEvent, validateServiceSession, validateTelemetrySpanEvent, validatedCapabilityOf, wrapError };
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- import { a as IServiceContext, c as InvokeFunction, d as InvokeAnyFunction, F as FetchFunction, S as ServiceSession, e as RetryPolicy, T as TelemetryConfig, I as IService, E as EventHandler, b as ServiceError, R as Result, P as PermissionHint, f as StorageQuotaInfo } from './types-gmdUiorz.js';
2
- export { g as ErrorCode, h as ErrorCodes, i as FetchRequestInit, j as FetchResponse, k as InvocationFact, l as InvocationFacts, m as InvokeAnyEntry, n as ServiceErrorEvent, o as ServiceHeaders, p as ServiceRequestEvent, q as ServiceResponseEvent, r as ServiceRetryEvent, s as TelemetryEventHandler, t as TelemetryEvents, u as TelemetrySpanEvent, v as defaultRetryPolicy, w as err, x as ok, y as serviceError } from './types-gmdUiorz.js';
1
+ import { a as IServiceContext, g as InvokeFunction, h as InvokeAnyFunction, f as FetchFunction, S as ServiceSession, i as RetryPolicy, T as TelemetryConfig, I as IService, E as EventHandler, F as FetchRequestInit, d as FetchResponse, b as ServiceError, R as Result, P as PermissionHint, j as StorageQuotaInfo } from './types-eVS1Whuf.js';
2
+ export { k as ErrorCode, l as ErrorCodes, m as InvocationFact, n as InvocationFacts, o as InvokeAnyEntry, e as RetryStats, p as ServiceErrorEvent, c as ServiceHeaders, q as ServiceRequestEvent, r as ServiceResponseEvent, s as ServiceRetryEvent, t as TelemetryEventHandler, u as TelemetryEvents, v as TelemetrySpanEvent, w as defaultRetryPolicy, x as err, y as ok, z as serviceError } from './types-eVS1Whuf.js';
3
3
  import { z } from 'zod';
4
- import { B as BaseService } from './BaseService-Bn07Vudy.js';
5
- export { a as BaseServiceOptions, R as RequestSignal, S as ServiceConstructor, b as ServiceRegistration } from './BaseService-Bn07Vudy.js';
4
+ import { B as BaseService } from './BaseService-x4AFZiEa.js';
5
+ export { a as BaseServiceOptions, R as RequestSignal, S as ServiceConstructor, b as ServiceRegistration } from './BaseService-x4AFZiEa.js';
6
6
  import { IKVService } from './kv/index.js';
7
7
  export { IPrefixedKVService, KVService, PrefixedKVService } from './kv/index.js';
8
- export { A as AuthorityRefusal, C as CLEAR_PENDING_WARNING, ah as DEFAULT_SIGNED_READ_URL_EXPIRY_MS, ai as KVAction, aj as KVActionType, ak as KVBatchPutItem, al as KVBatchPutOptions, am as KVBatchPutResponse, an as KVBatchReadResponse, ao as KVChange, ap as KVChangesAuthority, aq as KVChangesOptions, ar as KVChangesResponse, as as KVCreateSignedReadUrlOptions, at as KVDeleteOptions, au as KVGetOptions, av as KVHeadOptions, aw as KVListOptions, b as KVListPage, ax as KVListResponse, ay as KVPutOptions, c as KVReadThrough, d as KVReplicaHandle, e as KVReplicaSpec, f as KVReplicaStorage, a as KVReplicationController, K as KVReplicationDeps, az as KVResponse, aA as KVResponseHeaders, aB as KVServiceConfig, aC as KVSignedReadUrlResponse, L as LocalGetResult, g as LocalListResult, h as LocalReadMeta, i as LocalReplicaStatus, j as LocalSyncResult, k as PendingWriteRecord, l as PendingWriteState, P as PendingWriteStore, m as PinnedKey, n as PurgeTarget, o as ReplicaAccountGate, p as ReplicaAdmitHook, q as ReplicaAuthorityState, r as ReplicaBrowserGateAccess, s as ReplicaBrowserGateSnapshot, t as ReplicaBrowserGateTx, u as ReplicaBrowserPageAdmission, v as ReplicaClock, w as ReplicaCoverage, x as ReplicaDeliveryDecision, y as ReplicaDenyInput, z as ReplicaDenyOutcome, B as ReplicaDevice, D as ReplicaEraseReport, E as ReplicaGateAccess, F as ReplicaGateReason, G as ReplicaGateScope, H as ReplicaGateSnapshot, I as ReplicaGateTx, J as ReplicaGatedError, M as ReplicaGatedHandle, N as ReplicaGatedSpec, O as ReplicaGatedStorage, Q as ReplicaGrantInfo, S as ReplicaGuardedStore, T as ReplicaInspectedStatus, U as ReplicaLifecycleGate, V as ReplicaPageAdmission, W as ReplicaPartitionEraser, X as ReplicaPartitionIndexEntry, Y as ReplicaPeerCommit, Z as ReplicaPrivateGateHash, _ as ReplicaPurgeIntent, $ as ReplicaQuotaLedger, a0 as ReplicaQuotaSpec, a1 as ReplicaSessionStamp, a2 as ReplicaStampedReply, a3 as ReplicaState, a4 as ReplicaStatusEntry, a5 as ReplicationAuthority, a6 as ReplicationControl, a7 as ReplicationEvent, R as ReplicationIdentity, a8 as ReplicationOptions, a9 as ReplicationPurgeReport, aa as ReplicationReason, ab as ReplicationScheduler, ac as ResolvedReplicationOptions, ad as SaltedHash, ae as canonicalReplicationIdentity, af as replicationIdentityKey, ag as requiresSecretsOptIn } from './scope-BnyVPZ5E.js';
8
+ export { A as AuthorityRefusal, C as CLEAR_PENDING_WARNING, aq as DEFAULT_SIGNED_READ_URL_EXPIRY_MS, ar as KVAction, as as KVActionType, at as KVBatchPutItem, au as KVBatchPutOptions, av as KVBatchPutResponse, aw as KVBatchReadResponse, ax as KVChange, ay as KVChangesAuthority, az as KVChangesOptions, aA as KVChangesResponse, aB as KVCreateSignedReadUrlOptions, aC as KVDeleteOptions, aD as KVGetOptions, aE as KVHeadOptions, aF as KVListOptions, b as KVListPage, aG as KVListResponse, aH as KVPutOptions, c as KVReadThrough, d as KVReplicaHandle, e as KVReplicaSpec, f as KVReplicaStorage, a as KVReplicationController, K as KVReplicationDeps, aI as KVResponse, aJ as KVResponseHeaders, aK as KVServiceConfig, aL as KVSignedReadUrlResponse, L as LocalGetResult, g as LocalListResult, h as LocalReadMeta, i as LocalReplicaStatus, j as LocalSyncResult, k as PendingWriteRecord, l as PendingWriteState, P as PendingWriteStore, m as PinnedKey, w as PurgeTarget, x as ReplicaAccountGate, y as ReplicaAdmitHook, z as ReplicaAuthorityState, B as ReplicaBrowserGateAccess, D as ReplicaBrowserGateSnapshot, E as ReplicaBrowserGateTx, F as ReplicaBrowserPageAdmission, G as ReplicaClock, H as ReplicaCoverage, I as ReplicaDeliveryDecision, J as ReplicaDenyInput, M as ReplicaDenyOutcome, N as ReplicaDevice, O as ReplicaEraseReport, Q as ReplicaGateAccess, S as ReplicaGateReason, T as ReplicaGateScope, U as ReplicaGateSnapshot, V as ReplicaGateTx, W as ReplicaGatedError, X as ReplicaGatedHandle, Y as ReplicaGatedSpec, Z as ReplicaGatedStorage, _ as ReplicaGrantInfo, $ as ReplicaGuardedStore, a0 as ReplicaInspectedStatus, a1 as ReplicaLifecycleGate, a2 as ReplicaPageAdmission, a3 as ReplicaPartitionEraser, a4 as ReplicaPartitionIndexEntry, a5 as ReplicaPeerCommit, a6 as ReplicaPrivateGateHash, a7 as ReplicaPurgeIntent, a8 as ReplicaQuotaLedger, a9 as ReplicaQuotaSpec, aa as ReplicaSessionStamp, ab as ReplicaStampedReply, ac as ReplicaState, ad as ReplicaStatusEntry, ae as ReplicationAuthority, af as ReplicationControl, ag as ReplicationEvent, R as ReplicationIdentity, ah as ReplicationOptions, ai as ReplicationPurgeReport, aj as ReplicationReason, ak as ReplicationScheduler, al as ResolvedReplicationOptions, am as SaltedHash, an as canonicalReplicationIdentity, ao as replicationIdentityKey, ap as requiresSecretsOptIn } from './scope-9U4gVNFN.js';
9
9
  export { ClampConsentAnchor, ConsentDeadlineMs, EffectiveGrantExpiry, EffectiveGrantExpiryInput, MintRemainingMs, NeedsSilentRenewal, ReplicaConsentAnchor, ReplicaConsentSource, ReplicaGrantPolicy } from './kv/replication/grantPolicyTypes.js';
10
10
  export { BatchOptions, BatchResponse, DatabaseHandle, ExecuteOptions, ExecuteResponse, IDatabaseHandle, ISQLMigrations, ISQLService, QueryOptions, QueryResponse, SQLAction, SQLActionType, SQLMigrations, SQLService, SQLServiceConfig, SqlMigration, SqlMigrationApplyOptions, SqlMigrationApplyResponse, SqlStatement, SqlValue } from './sql/index.js';
11
11
  import { IEncryptionService, DecryptCapabilityProof } from './encryption/index.js';
@@ -717,18 +717,22 @@ declare const RetryPolicySchema: z.ZodObject<{
717
717
  maxDelayMs: z.ZodNumber;
718
718
  /** Error codes that should trigger a retry */
719
719
  retryableErrors: z.ZodArray<z.ZodString, "many">;
720
+ /** Total time budget for all attempts and waits, in milliseconds */
721
+ maxTotalMs: z.ZodOptional<z.ZodNumber>;
720
722
  }, "strip", z.ZodTypeAny, {
721
723
  maxAttempts: number;
722
724
  backoff: "none" | "linear" | "exponential";
723
725
  baseDelayMs: number;
724
726
  maxDelayMs: number;
725
727
  retryableErrors: string[];
728
+ maxTotalMs?: number | undefined;
726
729
  }, {
727
730
  maxAttempts: number;
728
731
  backoff: "none" | "linear" | "exponential";
729
732
  baseDelayMs: number;
730
733
  maxDelayMs: number;
731
734
  retryableErrors: string[];
735
+ maxTotalMs?: number | undefined;
732
736
  }>;
733
737
  type RetryPolicyType = z.infer<typeof RetryPolicySchema>;
734
738
  /**
@@ -1037,6 +1041,8 @@ declare class ServiceContext implements IServiceContext {
1037
1041
  private wrapInvoke;
1038
1042
  private assertActive;
1039
1043
  private wrapInvokeAny;
1044
+ /** Retry `NODE_BUSY` / `REQUEST_TIMEOUT`; `build` must re-sign per attempt (the node 409s a repeated invocation). */
1045
+ invokeWithRetry(url: string, build: () => FetchRequestInit | Promise<FetchRequestInit>): Promise<FetchResponse>;
1040
1046
  private wrapFetch;
1041
1047
  private combineSignals;
1042
1048
  }
@@ -1057,6 +1063,30 @@ declare function authExpiredError(service: string): ServiceError;
1057
1063
  * Create a service error for network issues.
1058
1064
  */
1059
1065
  declare function networkError(service: string, message: string, cause?: Error): ServiceError;
1066
+ /**
1067
+ * Classify a node retry signal (tinycloud-node #347, TC-1054). The node's
1068
+ * bodies are plain text led by a stable token:
1069
+ * - `503 sql_busy: <stage>: ...` and `503 unavailable_retryable: ...` (and
1070
+ * `read_audit_busy`) are `NODE_BUSY`: nothing was applied; retry after `meta.retryAfterMs`.
1071
+ * - `503 request_timeout: ...` is `REQUEST_TIMEOUT`: the deadline passed before
1072
+ * any write began, so nothing was applied.
1073
+ * - `500 outcome_unknown: ...` is `OUTCOME_UNKNOWN`: a write may have been
1074
+ * applied; read back before retrying a non-idempotent operation.
1075
+ *
1076
+ * `meta.retryable` is the safe-to-retry verdict and `meta.retryAfterMs` the
1077
+ * node's `Retry-After` (the node sends whole seconds; anything else is
1078
+ * ignored). `invokeWithRetry` retries `NODE_BUSY` and `REQUEST_TIMEOUT`;
1079
+ * `OUTCOME_UNKNOWN` is never retried. Returns `undefined` for any
1080
+ * other response, including the bodyless 503/500 of nodes before 1.21, which
1081
+ * callers keep classifying as they always did.
1082
+ */
1083
+ declare function nodeRetryError(service: string, message: string, response: {
1084
+ status: number;
1085
+ statusText: string;
1086
+ headers: {
1087
+ get(name: string): string | null;
1088
+ };
1089
+ }, errorText: string): ServiceError | undefined;
1060
1090
  /**
1061
1091
  * Create a service error for timeouts.
1062
1092
  *
@@ -1871,6 +1901,19 @@ interface VaultPutOptions {
1871
1901
  * fails with `ALREADY_EXISTS`; it is never overwritten.
1872
1902
  */
1873
1903
  ifNoneMatch?: "*";
1904
+ /**
1905
+ * Compare-and-swap: write only when the stored envelope still has this
1906
+ * strong ETag, passed exactly as {@link VaultEntry.etag} returned it
1907
+ * (including the quotes). Network-encrypted vaults only; cannot be combined
1908
+ * with `ifNoneMatch`.
1909
+ *
1910
+ * Failures are distinct codes: `ETAG_MISMATCH` (the value changed or was
1911
+ * deleted: re-read, re-apply, retry), `INVALID_ETAG` (malformed; never
1912
+ * retry), `OUTCOME_UNKNOWN` (the node may have applied the write, or a gateway
1913
+ * answered for it: read it back before retrying, with a freshly signed request) and `NODE_BUSY`
1914
+ * (nothing was written; retry).
1915
+ */
1916
+ ifMatch?: string;
1874
1917
  }
1875
1918
  /**
1876
1919
  * Options for vault get operations.
@@ -1880,8 +1923,25 @@ interface VaultGetOptions<T = unknown> {
1880
1923
  deserialize?: (data: Uint8Array) => T;
1881
1924
  /** Return raw decrypted bytes without deserialization */
1882
1925
  raw?: boolean;
1883
- /** Force the underlying KV read to bypass replica read-through. */
1926
+ /**
1927
+ * Force the underlying KV read to bypass replica read-through. Required for
1928
+ * a usable {@link VaultEntry.etag}: only network reads return one, because
1929
+ * a replica can serve a stale etag.
1930
+ */
1884
1931
  source?: "network";
1932
+ /**
1933
+ * Opt-in (default off): refuse an envelope whose AAD is not bound to this
1934
+ * vault's space and this key (`tinycloud.vault:<spaceId>:<key>`). The space
1935
+ * id is compared after normalizing the spelling of its EVM addresses
1936
+ * (checksummed and lowercase are the same space). An envelope with no AAD,
1937
+ * or with a different one, fails with `AAD_MISMATCH` (`aad_mismatch` from
1938
+ * `readNetworkEncrypted`) instead of decrypting. This stops a ciphertext
1939
+ * copied to another key from being accepted; it does not stop a freshly
1940
+ * encrypted forgery. A malformed stored value is a corrupt envelope, as without this
1941
+ * option. Network-encrypted vaults only: a master-key vault and `getShared` refuse it with
1942
+ * `STORAGE_ERROR` rather than skip the check.
1943
+ */
1944
+ expectAad?: boolean;
1885
1945
  /** Delegated KV service for reading from the grantor's space (used by getShared) */
1886
1946
  kv?: {
1887
1947
  get<V>(key: string, options?: {
@@ -1936,6 +1996,12 @@ interface VaultEntry<T> {
1936
1996
  metadata: Record<string, string>;
1937
1997
  /** Key ID used for encryption */
1938
1998
  keyId: string;
1999
+ /**
2000
+ * Strong ETag of the stored envelope, for {@link VaultPutOptions.ifMatch}.
2001
+ * Present only for network-encrypted reads made with `source: "network"`
2002
+ * (always for `readNetworkEncrypted`); never taken from a replica.
2003
+ */
2004
+ etag?: string;
1939
2005
  }
1940
2006
  /**
1941
2007
  * Safe classification for a network-encrypted vault read.
@@ -1962,6 +2028,10 @@ type VaultNetworkReadResult<T> = {
1962
2028
  status: "decrypt_failed";
1963
2029
  } | {
1964
2030
  status: "invalid_payload";
2031
+ }
2032
+ /** Only with `expectAad`: the envelope is not bound to this space and key. */
2033
+ | {
2034
+ status: "aad_mismatch";
1965
2035
  };
1966
2036
  /**
1967
2037
  * Structured error codes for vault operations.
@@ -2019,6 +2089,43 @@ type VaultErrorInput = {
2019
2089
  meta?: Record<string, unknown>;
2020
2090
  /** The typed KV error that refused the write (an `Error` carrying its `code`, `service` and `meta`). */
2021
2091
  cause: ServiceError & Error;
2092
+ } | {
2093
+ /** `expectAad` read: the envelope's AAD is missing or bound to another space/key. */
2094
+ code: "AAD_MISMATCH";
2095
+ key: string;
2096
+ message: string;
2097
+ } | {
2098
+ /** `ifMatch` write refused (HTTP 412): the value changed or no longer exists. Re-read and retry. */
2099
+ code: "ETAG_MISMATCH";
2100
+ key: string;
2101
+ message: string;
2102
+ meta?: Record<string, unknown>;
2103
+ cause: ServiceError & Error;
2104
+ } | {
2105
+ /** `ifMatch` is not a strong ETag (HTTP 400, or rejected before sending). Never retry. */
2106
+ code: "INVALID_ETAG";
2107
+ key: string;
2108
+ message: string;
2109
+ meta?: Record<string, unknown>;
2110
+ cause?: ServiceError & Error;
2111
+ } | {
2112
+ /**
2113
+ * `ifMatch` write that may have been applied: the node's `outcome_unknown` (500), a gateway
2114
+ * answer that can follow a commit (500, 502, 503 without the node's busy body, 504, 520,
2115
+ * 522, 524) or a connection that failed after the request was sent. Re-read before retrying.
2116
+ */
2117
+ code: "OUTCOME_UNKNOWN";
2118
+ key: string;
2119
+ message: string;
2120
+ meta?: Record<string, unknown>;
2121
+ cause: ServiceError & Error;
2122
+ } | {
2123
+ /** `ifMatch` write, the node's own busy/timeout answer (503 with its busy body): nothing was written. Safe to retry. */
2124
+ code: "NODE_BUSY";
2125
+ key: string;
2126
+ message: string;
2127
+ meta?: Record<string, unknown>;
2128
+ cause: ServiceError & Error;
2022
2129
  } | {
2023
2130
  code: "STORAGE_QUOTA_EXCEEDED" | "STORAGE_LIMIT_REACHED";
2024
2131
  message: string;
@@ -2584,4 +2691,4 @@ declare class SecretsService implements ISecretsService {
2584
2691
  listAll(): Promise<Result<SecretCatalogEntry[], SecretsError>>;
2585
2692
  }
2586
2693
 
2587
- export { type AuthorizationVerdict, BaseService, type ColumnInfo, type DataVaultConfig, DataVaultService, DecryptCapabilityProof, DuckDbAction, type DuckDbActionType, type DuckDbBatchOptions, type BatchResponse as DuckDbBatchResponse, DuckDbDatabaseHandle, type DuckDbExecuteOptions, type ExecuteResponse as DuckDbExecuteResponse, type DuckDbOptions, type DuckDbQueryOptions, type QueryResponse as DuckDbQueryResponse, DuckDbService, type DuckDbServiceConfig, type DuckDbStatement, type DuckDbValue, EventHandler, FetchFunction, GenericKVResponseSchema, type GenericKVResponseType, GenericResultSchema, type HookEvent, type HookServiceName, type HookStreamEvent, type HookStreamRetryConfig, type HookSubscription, type HookWebhookListOptions, type HookWebhookRecord, type HookWebhookRegistration, type HookWebhookScope, type HookWebhookUnregisterOptions, HooksService, type HooksServiceConfig, type IDataVaultService, type IDuckDbDatabaseHandle, type IDuckDbService, IEncryptionService, type IHooksService, IKVService, type ISecretsService, IService, IServiceContext, type IStorageService, InvokeAnyFunction, InvokeFunction, KVListResponseSchema, type KVListResponseType, KVListResultSchema, type KVListResultType, KVResponseHeadersSchema, type KVResponseHeadersType, MAX_SECRET_SCOPE_LENGTH, type ParsedSecretCatalogKey, PermissionHint, type QuotaConfig, type QuotaStatus, type ResolvedSecretPath, Result, RetryPolicy, RetryPolicySchema, type RetryPolicyType, SECRET_NAME_RE, SECRET_SCOPE_RE, STORAGE_FULL_MESSAGE, STORAGE_MANAGE_URL, STORAGE_NEARLY_FULL_RATIO, STORAGE_WRITE_TOO_LARGE_MESSAGE, type SchemaInfo, type SecretCatalogEntry, type SecretPayload, type SecretPutOptions, type SecretScopeOptions, type SecretsError, SecretsService, ServiceContext, type ServiceContextConfig, ServiceError, ServiceErrorEventSchema, type ServiceErrorEventType, ServiceErrorSchema, type ServiceErrorType, ServiceRequestEventSchema, type ServiceRequestEventType, ServiceResponseEventSchema, type ServiceResponseEventType, ServiceRetryEventSchema, type ServiceRetryEventType, ServiceSession, ServiceSessionSchema, type ServiceSessionType, type StorageAccountUsage, type StorageFullEvent, type StorageFullHandler, StorageFullMonitor, StorageQuotaInfo, type StorageRejectionDetails, type StorageStatus, type StorageStatusOptions, type StorageUsage, type StorageUsageState, type SubscribeOptions, TC832_RESERVED_SCOPES, type TableInfo, TelemetryConfig, TelemetrySpanEventSchema, type TelemetrySpanEventType, type TinyCloudDebugEnableOptions, type TinyCloudDebugEvent, type TinyCloudDebugLevel, TinyCloudDebugLogger, type TinyCloudDebugTimer, TinyCloudQuota, type ValidationError, type VaultCrypto, type VaultEntry, type VaultError, type VaultGetOptions, type VaultGrantOptions, VaultHeaders, type VaultListOptions, type VaultListPage, type VaultNetworkReadResult, VaultPublicSpaceKVActions, type VaultPutOptions, type ViewInfo, type WasmVaultFunctions, abortedError, appSecretScope, authExpiredError, authRequiredError, authUnauthorizedError, authorizationVerdictOf, canonicalizeSecretScope, clearTinyCloudDebugLogs, createKVResponseSchema, createResultSchema, createVaultCrypto, disableTinyCloudDebug, enableTinyCloudDebug, errorResult, getTinyCloudDebugLogs, installTinyCloudDebugGlobals, isStorageFullError, networkError, notFoundError, parseAuthError, parseCapabilityResource, parsePermissionHint, parsePermissionHintFromErrorText, parseSecretCatalogKey, parseStorageQuotaBytes, parseStorageRejection, parseStorageStatus, permissionDeniedError, resolveSecretListPrefix, resolveSecretPath, storageLimitReachedError, storageQuotaExceededError, storageRejectionError, storageUsageState, timeoutError, tinyCloudDebugLogger, validateKVListResponse, validateKVResponseHeaders, validateRetryPolicy, validateServiceError, validateServiceRequestEvent, validateServiceResponseEvent, validateServiceSession, validateTelemetrySpanEvent, validatedCapabilityOf, wrapError };
2694
+ export { type AuthorizationVerdict, BaseService, type ColumnInfo, type DataVaultConfig, DataVaultService, DecryptCapabilityProof, DuckDbAction, type DuckDbActionType, type DuckDbBatchOptions, type BatchResponse as DuckDbBatchResponse, DuckDbDatabaseHandle, type DuckDbExecuteOptions, type ExecuteResponse as DuckDbExecuteResponse, type DuckDbOptions, type DuckDbQueryOptions, type QueryResponse as DuckDbQueryResponse, DuckDbService, type DuckDbServiceConfig, type DuckDbStatement, type DuckDbValue, EventHandler, FetchFunction, FetchRequestInit, FetchResponse, GenericKVResponseSchema, type GenericKVResponseType, GenericResultSchema, type HookEvent, type HookServiceName, type HookStreamEvent, type HookStreamRetryConfig, type HookSubscription, type HookWebhookListOptions, type HookWebhookRecord, type HookWebhookRegistration, type HookWebhookScope, type HookWebhookUnregisterOptions, HooksService, type HooksServiceConfig, type IDataVaultService, type IDuckDbDatabaseHandle, type IDuckDbService, IEncryptionService, type IHooksService, IKVService, type ISecretsService, IService, IServiceContext, type IStorageService, InvokeAnyFunction, InvokeFunction, KVListResponseSchema, type KVListResponseType, KVListResultSchema, type KVListResultType, KVResponseHeadersSchema, type KVResponseHeadersType, MAX_SECRET_SCOPE_LENGTH, type ParsedSecretCatalogKey, PermissionHint, type QuotaConfig, type QuotaStatus, type ResolvedSecretPath, Result, RetryPolicy, RetryPolicySchema, type RetryPolicyType, SECRET_NAME_RE, SECRET_SCOPE_RE, STORAGE_FULL_MESSAGE, STORAGE_MANAGE_URL, STORAGE_NEARLY_FULL_RATIO, STORAGE_WRITE_TOO_LARGE_MESSAGE, type SchemaInfo, type SecretCatalogEntry, type SecretPayload, type SecretPutOptions, type SecretScopeOptions, type SecretsError, SecretsService, ServiceContext, type ServiceContextConfig, ServiceError, ServiceErrorEventSchema, type ServiceErrorEventType, ServiceErrorSchema, type ServiceErrorType, ServiceRequestEventSchema, type ServiceRequestEventType, ServiceResponseEventSchema, type ServiceResponseEventType, ServiceRetryEventSchema, type ServiceRetryEventType, ServiceSession, ServiceSessionSchema, type ServiceSessionType, type StorageAccountUsage, type StorageFullEvent, type StorageFullHandler, StorageFullMonitor, StorageQuotaInfo, type StorageRejectionDetails, type StorageStatus, type StorageStatusOptions, type StorageUsage, type StorageUsageState, type SubscribeOptions, TC832_RESERVED_SCOPES, type TableInfo, TelemetryConfig, TelemetrySpanEventSchema, type TelemetrySpanEventType, type TinyCloudDebugEnableOptions, type TinyCloudDebugEvent, type TinyCloudDebugLevel, TinyCloudDebugLogger, type TinyCloudDebugTimer, TinyCloudQuota, type ValidationError, type VaultCrypto, type VaultEntry, type VaultError, type VaultGetOptions, type VaultGrantOptions, VaultHeaders, type VaultListOptions, type VaultListPage, type VaultNetworkReadResult, VaultPublicSpaceKVActions, type VaultPutOptions, type ViewInfo, type WasmVaultFunctions, abortedError, appSecretScope, authExpiredError, authRequiredError, authUnauthorizedError, authorizationVerdictOf, canonicalizeSecretScope, clearTinyCloudDebugLogs, createKVResponseSchema, createResultSchema, createVaultCrypto, disableTinyCloudDebug, enableTinyCloudDebug, errorResult, getTinyCloudDebugLogs, installTinyCloudDebugGlobals, isStorageFullError, networkError, nodeRetryError, notFoundError, parseAuthError, parseCapabilityResource, parsePermissionHint, parsePermissionHintFromErrorText, parseSecretCatalogKey, parseStorageQuotaBytes, parseStorageRejection, parseStorageStatus, permissionDeniedError, resolveSecretListPrefix, resolveSecretPath, storageLimitReachedError, storageQuotaExceededError, storageRejectionError, storageUsageState, timeoutError, tinyCloudDebugLogger, validateKVListResponse, validateKVResponseHeaders, validateRetryPolicy, validateServiceError, validateServiceRequestEvent, validateServiceResponseEvent, validateServiceSession, validateTelemetrySpanEvent, validatedCapabilityOf, wrapError };