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

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-Cc6Ueicm.d.cts} +1 -1
  2. package/dist/{BaseService-Bn07Vudy.d.ts → BaseService-DOdXd7sr.d.ts} +1 -1
  3. package/dist/encryption/index.cjs +8 -0
  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 +8 -0
  8. package/dist/encryption/index.js.map +1 -1
  9. package/dist/index.cjs +94 -57
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +29 -6
  12. package/dist/index.d.ts +29 -6
  13. package/dist/index.js +93 -57
  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 +66 -21
  18. package/dist/kv/index.cjs.map +1 -1
  19. package/dist/kv/index.d.cts +4 -4
  20. package/dist/kv/index.d.ts +4 -4
  21. package/dist/kv/index.js +66 -21
  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 +571 -128
  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 +571 -128
  34. package/dist/kv/replication/index.js.map +1 -1
  35. package/dist/{scope-BnyVPZ5E.d.ts → scope-B-m6cKH-.d.ts} +310 -7
  36. package/dist/{scope-CQ5kmHlt.d.cts → scope-B7oeKdLM.d.cts} +310 -7
  37. package/dist/sql/index.cjs +70 -36
  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 +70 -36
  42. package/dist/sql/index.js.map +1 -1
  43. package/dist/{types-gmdUiorz.d.cts → types-BjH0ZtGy.d.cts} +6 -0
  44. package/dist/{types-gmdUiorz.d.ts → types-BjH0ZtGy.d.ts} +6 -0
  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, 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-BjH0ZtGy.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-BjH0ZtGy.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-Cc6Ueicm.cjs';
5
+ export { a as BaseServiceOptions, R as RequestSignal, S as ServiceConstructor, b as ServiceRegistration } from './BaseService-Cc6Ueicm.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-B7oeKdLM.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';
@@ -1057,6 +1057,29 @@ declare function authExpiredError(service: string): ServiceError;
1057
1057
  * Create a service error for network issues.
1058
1058
  */
1059
1059
  declare function networkError(service: string, message: string, cause?: Error): ServiceError;
1060
+ /**
1061
+ * Classify a node retry signal (tinycloud-node #347, TC-1054). The node's
1062
+ * bodies are plain text led by a stable token:
1063
+ * - `503 sql_busy: <stage>: ...` and `503 unavailable_retryable: ...` are
1064
+ * `NODE_BUSY`: nothing was applied; retry after `meta.retryAfterMs`.
1065
+ * - `503 request_timeout: ...` is `REQUEST_TIMEOUT`: the deadline passed before
1066
+ * any write began, so nothing was applied.
1067
+ * - `500 outcome_unknown: ...` is `OUTCOME_UNKNOWN`: a write may have been
1068
+ * applied; read back before retrying a non-idempotent operation.
1069
+ *
1070
+ * `meta.retryable` is the safe-to-retry verdict and `meta.retryAfterMs` the
1071
+ * node's `Retry-After` (the node sends whole seconds; anything else is
1072
+ * ignored). The SDK never retries on its own. Returns `undefined` for any
1073
+ * other response, including the bodyless 503/500 of nodes before 1.21, which
1074
+ * callers keep classifying as they always did.
1075
+ */
1076
+ declare function nodeRetryError(service: string, message: string, response: {
1077
+ status: number;
1078
+ statusText: string;
1079
+ headers: {
1080
+ get(name: string): string | null;
1081
+ };
1082
+ }, errorText: string): ServiceError | undefined;
1060
1083
  /**
1061
1084
  * Create a service error for timeouts.
1062
1085
  *
@@ -2584,4 +2607,4 @@ declare class SecretsService implements ISecretsService {
2584
2607
  listAll(): Promise<Result<SecretCatalogEntry[], SecretsError>>;
2585
2608
  }
2586
2609
 
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 };
2610
+ 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, 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, 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-BjH0ZtGy.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-BjH0ZtGy.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-DOdXd7sr.js';
5
+ export { a as BaseServiceOptions, R as RequestSignal, S as ServiceConstructor, b as ServiceRegistration } from './BaseService-DOdXd7sr.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-B-m6cKH-.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';
@@ -1057,6 +1057,29 @@ declare function authExpiredError(service: string): ServiceError;
1057
1057
  * Create a service error for network issues.
1058
1058
  */
1059
1059
  declare function networkError(service: string, message: string, cause?: Error): ServiceError;
1060
+ /**
1061
+ * Classify a node retry signal (tinycloud-node #347, TC-1054). The node's
1062
+ * bodies are plain text led by a stable token:
1063
+ * - `503 sql_busy: <stage>: ...` and `503 unavailable_retryable: ...` are
1064
+ * `NODE_BUSY`: nothing was applied; retry after `meta.retryAfterMs`.
1065
+ * - `503 request_timeout: ...` is `REQUEST_TIMEOUT`: the deadline passed before
1066
+ * any write began, so nothing was applied.
1067
+ * - `500 outcome_unknown: ...` is `OUTCOME_UNKNOWN`: a write may have been
1068
+ * applied; read back before retrying a non-idempotent operation.
1069
+ *
1070
+ * `meta.retryable` is the safe-to-retry verdict and `meta.retryAfterMs` the
1071
+ * node's `Retry-After` (the node sends whole seconds; anything else is
1072
+ * ignored). The SDK never retries on its own. Returns `undefined` for any
1073
+ * other response, including the bodyless 503/500 of nodes before 1.21, which
1074
+ * callers keep classifying as they always did.
1075
+ */
1076
+ declare function nodeRetryError(service: string, message: string, response: {
1077
+ status: number;
1078
+ statusText: string;
1079
+ headers: {
1080
+ get(name: string): string | null;
1081
+ };
1082
+ }, errorText: string): ServiceError | undefined;
1060
1083
  /**
1061
1084
  * Create a service error for timeouts.
1062
1085
  *
@@ -2584,4 +2607,4 @@ declare class SecretsService implements ISecretsService {
2584
2607
  listAll(): Promise<Result<SecretCatalogEntry[], SecretsError>>;
2585
2608
  }
2586
2609
 
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 };
2610
+ 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, 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.js CHANGED
@@ -14,6 +14,14 @@ var ErrorCodes = {
14
14
  ABORTED: "ABORTED",
15
15
  INVALID_INPUT: "INVALID_INPUT",
16
16
  PERMISSION_DENIED: "PERMISSION_DENIED",
17
+ // Node retry signals (tinycloud-node #347). `meta.retryable` says whether a
18
+ // retry is safe; `meta.retryAfterMs` carries the node's Retry-After.
19
+ /** HTTP 503 `sql_busy:<stage>` / `unavailable_retryable`: nothing was applied; retry after `meta.retryAfterMs`. */
20
+ NODE_BUSY: "NODE_BUSY",
21
+ /** HTTP 503 `request_timeout`: the node's deadline passed before any write began; nothing was applied. */
22
+ REQUEST_TIMEOUT: "REQUEST_TIMEOUT",
23
+ /** HTTP 500 `outcome_unknown`: a write may have been applied; read back before retrying a non-idempotent operation. */
24
+ OUTCOME_UNKNOWN: "OUTCOME_UNKNOWN",
17
25
  // KV-specific errors
18
26
  KV_NOT_FOUND: "KV_NOT_FOUND",
19
27
  KV_WRITE_FAILED: "KV_WRITE_FAILED",
@@ -958,6 +966,42 @@ var ServiceContext = class {
958
966
  }
959
967
  };
960
968
 
969
+ // src/responseErrors.ts
970
+ function parseServiceErrorBody(errorText) {
971
+ try {
972
+ return JSON.parse(errorText);
973
+ } catch {
974
+ return {};
975
+ }
976
+ }
977
+ function formatServiceResponseError(serviceLabel, operation, status, errorText, parsed) {
978
+ if (parsed.message) {
979
+ return compactMessage(parsed.message);
980
+ }
981
+ if (looksLikeHtml(errorText)) {
982
+ if (status === 524 || /524\s*[:-]/i.test(errorText) || /a timeout occurred/i.test(errorText)) {
983
+ return `${serviceLabel} ${operation} failed: upstream request timed out. Please retry.`;
984
+ }
985
+ return `${serviceLabel} ${operation} failed: upstream service returned an HTML error page (${status}).`;
986
+ }
987
+ return `${serviceLabel} ${operation} failed: ${status} - ${compactMessage(errorText)}`;
988
+ }
989
+ function responseErrorMeta(status, statusText, errorText) {
990
+ const meta = { status, statusText };
991
+ const snippet = compactMessage(errorText);
992
+ if (snippet) {
993
+ meta.responseSnippet = snippet.slice(0, 300);
994
+ }
995
+ return meta;
996
+ }
997
+ function looksLikeHtml(text) {
998
+ return /<!doctype html/i.test(text) || /<html[\s>]/i.test(text);
999
+ }
1000
+ function compactMessage(message) {
1001
+ const compact = message.replace(/\s+/g, " ").trim();
1002
+ return compact.length > 500 ? `${compact.slice(0, 500)}...` : compact;
1003
+ }
1004
+
961
1005
  // src/errors.ts
962
1006
  import { CAPABILITY_REGISTRY } from "@tinycloud/bootstrap";
963
1007
 
@@ -1117,6 +1161,30 @@ function networkError(service, message, cause) {
1117
1161
  cause
1118
1162
  };
1119
1163
  }
1164
+ function nodeRetryError(service, message, response, errorText) {
1165
+ const body = errorText.trim();
1166
+ const [, token, stage] = /^([a-z_]+)(?::\s*([a-z_]+):)?/.exec(body) ?? [];
1167
+ let code;
1168
+ if (response.status === 503 && (token === "sql_busy" || token === "unavailable_retryable")) {
1169
+ code = ErrorCodes.NODE_BUSY;
1170
+ } else if (response.status === 503 && token === "request_timeout") {
1171
+ code = ErrorCodes.REQUEST_TIMEOUT;
1172
+ } else if (response.status === 500 && token === "outcome_unknown") {
1173
+ code = ErrorCodes.OUTCOME_UNKNOWN;
1174
+ } else {
1175
+ return void 0;
1176
+ }
1177
+ const retryable = code !== ErrorCodes.OUTCOME_UNKNOWN;
1178
+ const retryAfter = response.headers.get("retry-after")?.trim();
1179
+ return serviceError(code, message, service, {
1180
+ meta: {
1181
+ ...responseErrorMeta(response.status, response.statusText, errorText),
1182
+ retryable,
1183
+ ...token === "sql_busy" && stage ? { stage } : {},
1184
+ ...retryable && retryAfter && /^\d{1,9}$/.test(retryAfter) ? { retryAfterMs: Number(retryAfter) * 1e3 } : {}
1185
+ }
1186
+ });
1187
+ }
1120
1188
  var RequestTimeoutError = class extends Error {
1121
1189
  constructor(timeoutMs) {
1122
1190
  super(`Request timed out after ${timeoutMs}ms.`);
@@ -2455,9 +2523,12 @@ var KVService = class extends BaseService {
2455
2523
  { meta: { status: response.status, statusText: response.statusText } }
2456
2524
  ));
2457
2525
  }
2526
+ const message = `Failed to get key ${JSON.stringify(key)}: ${response.status} - ${errorText}`;
2527
+ const retryError = nodeRetryError("kv", message, response, errorText);
2528
+ if (retryError) return err(retryError);
2458
2529
  return err(serviceError(
2459
2530
  ErrorCodes.NETWORK_ERROR,
2460
- `Failed to get key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,
2531
+ message,
2461
2532
  "kv",
2462
2533
  { meta: { status: response.status, statusText: response.statusText } }
2463
2534
  ));
@@ -2539,19 +2610,14 @@ var KVService = class extends BaseService {
2539
2610
  { meta: { status: response.status, statusText: response.statusText } }
2540
2611
  ));
2541
2612
  }
2542
- if (response.status === 503 && (options?.ifMatch !== void 0 || options?.ifNoneMatch !== void 0)) {
2543
- return err(serviceError(
2544
- ErrorCodes.KV_CONFLICT,
2545
- `Concurrent KV update conflicted for key ${JSON.stringify(key)}`,
2546
- "kv",
2547
- { meta: { status: response.status, statusText: response.statusText } }
2548
- ));
2549
- }
2613
+ const message = `Failed to put key ${JSON.stringify(key)}: ${response.status} - ${errorText}`;
2614
+ const retryError = nodeRetryError("kv", message, response, errorText);
2615
+ if (retryError) return err(retryError);
2550
2616
  const quotaError = this.handleQuotaErrorResponse(response, errorText, key);
2551
2617
  if (quotaError) return quotaError;
2552
2618
  return err(serviceError(
2553
2619
  ErrorCodes.KV_WRITE_FAILED,
2554
- `Failed to put key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,
2620
+ message,
2555
2621
  "kv",
2556
2622
  { meta: { status: response.status, statusText: response.statusText } }
2557
2623
  ));
@@ -2851,9 +2917,12 @@ var KVService = class extends BaseService {
2851
2917
  );
2852
2918
  }
2853
2919
  const errorText = await response.text();
2920
+ const message = `Failed to list keys: ${response.status} - ${errorText}`;
2921
+ const retryError = nodeRetryError("kv", message, response, errorText);
2922
+ if (retryError) return err(retryError);
2854
2923
  return err(serviceError(
2855
2924
  ErrorCodes.NETWORK_ERROR,
2856
- `Failed to list keys: ${response.status} - ${errorText}`,
2925
+ message,
2857
2926
  "kv",
2858
2927
  { meta: { status: response.status, statusText: response.statusText } }
2859
2928
  ));
@@ -3104,17 +3173,12 @@ var KVService = class extends BaseService {
3104
3173
  { meta: { status: response.status, statusText: response.statusText } }
3105
3174
  ));
3106
3175
  }
3107
- if (response.status === 503 && options?.ifMatch !== void 0) {
3108
- return err(serviceError(
3109
- ErrorCodes.KV_CONFLICT,
3110
- `Concurrent KV delete conflicted for key ${JSON.stringify(key)}`,
3111
- "kv",
3112
- { meta: { status: response.status, statusText: response.statusText } }
3113
- ));
3114
- }
3176
+ const message = `Failed to delete key ${JSON.stringify(key)}: ${response.status} - ${errorText}`;
3177
+ const retryError = nodeRetryError("kv", message, response, errorText);
3178
+ if (retryError) return err(retryError);
3115
3179
  return err(serviceError(
3116
3180
  ErrorCodes.NETWORK_ERROR,
3117
- `Failed to delete key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,
3181
+ message,
3118
3182
  "kv",
3119
3183
  { meta: { status: response.status, statusText: response.statusText } }
3120
3184
  ));
@@ -3155,10 +3219,13 @@ var KVService = class extends BaseService {
3155
3219
  return await this.classifyNotFound(response, key);
3156
3220
  }
3157
3221
  const errorText = await response.text();
3222
+ const message = `Failed to get metadata for key ${JSON.stringify(key)}: ${response.status} - ${errorText}`;
3223
+ const retryError = nodeRetryError("kv", message, response, errorText);
3224
+ if (retryError) return err(retryError);
3158
3225
  return err(
3159
3226
  serviceError(
3160
3227
  ErrorCodes.NETWORK_ERROR,
3161
- `Failed to get metadata for key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,
3228
+ message,
3162
3229
  "kv",
3163
3230
  { meta: { status: response.status, statusText: response.statusText } }
3164
3231
  )
@@ -3350,42 +3417,6 @@ function requiresSecretsOptIn(space, prefix) {
3350
3417
  return prefix.split("/", 1)[0] === "vault";
3351
3418
  }
3352
3419
 
3353
- // src/responseErrors.ts
3354
- function parseServiceErrorBody(errorText) {
3355
- try {
3356
- return JSON.parse(errorText);
3357
- } catch {
3358
- return {};
3359
- }
3360
- }
3361
- function formatServiceResponseError(serviceLabel, operation, status, errorText, parsed) {
3362
- if (parsed.message) {
3363
- return compactMessage(parsed.message);
3364
- }
3365
- if (looksLikeHtml(errorText)) {
3366
- if (status === 524 || /524\s*[:-]/i.test(errorText) || /a timeout occurred/i.test(errorText)) {
3367
- return `${serviceLabel} ${operation} failed: upstream request timed out. Please retry.`;
3368
- }
3369
- return `${serviceLabel} ${operation} failed: upstream service returned an HTML error page (${status}).`;
3370
- }
3371
- return `${serviceLabel} ${operation} failed: ${status} - ${compactMessage(errorText)}`;
3372
- }
3373
- function responseErrorMeta(status, statusText, errorText) {
3374
- const meta = { status, statusText };
3375
- const snippet = compactMessage(errorText);
3376
- if (snippet) {
3377
- meta.responseSnippet = snippet.slice(0, 300);
3378
- }
3379
- return meta;
3380
- }
3381
- function looksLikeHtml(text) {
3382
- return /<!doctype html/i.test(text) || /<html[\s>]/i.test(text);
3383
- }
3384
- function compactMessage(message) {
3385
- const compact = message.replace(/\s+/g, " ").trim();
3386
- return compact.length > 500 ? `${compact.slice(0, 500)}...` : compact;
3387
- }
3388
-
3389
3420
  // src/sql/SQLMigrations.ts
3390
3421
  var SQLMigrations = class {
3391
3422
  constructor(service, dbName) {
@@ -3801,6 +3832,8 @@ var SQLService = class extends BaseService {
3801
3832
  if (response.status === 413 && parseStorageRejection(errorText)) {
3802
3833
  return err(storageRejectionError("sql", 413, meta, errorText));
3803
3834
  }
3835
+ const retryError = nodeRetryError("sql", `SQL ${operation} failed: ${response.status} - ${errorText}`, response, errorText);
3836
+ if (retryError) return err(retryError);
3804
3837
  const errorBody = parseServiceErrorBody(errorText);
3805
3838
  const errorCode = this.mapHttpStatusToErrorCode(
3806
3839
  response.status,
@@ -4270,6 +4303,8 @@ var DuckDbService = class extends BaseService {
4270
4303
  if (response.status === 413 && parseStorageRejection(errorText)) {
4271
4304
  return err(storageRejectionError("duckdb", 413, meta, errorText));
4272
4305
  }
4306
+ const retryError = nodeRetryError("duckdb", `DuckDB ${operation} failed: ${response.status} - ${errorText}`, response, errorText);
4307
+ if (retryError) return err(retryError);
4273
4308
  const errorBody = parseServiceErrorBody(errorText);
4274
4309
  const errorCode = this.mapHttpStatusToErrorCode(
4275
4310
  response.status,
@@ -8310,6 +8345,7 @@ export {
8310
8345
  kvPrefixCovers,
8311
8346
  networkDiscoveryKey,
8312
8347
  networkError,
8348
+ nodeRetryError,
8313
8349
  notFoundError,
8314
8350
  ok,
8315
8351
  openWrappedKey,