@tinycloud/sdk-services 3.2.6-beta.2 → 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 (65) hide show
  1. package/dist/{BaseService-4wwJq1Gn.d.cts → BaseService-Cc6Ueicm.d.cts} +1 -1
  2. package/dist/{BaseService-BGr2slUz.d.ts → BaseService-DOdXd7sr.d.ts} +1 -1
  3. package/dist/encryption/index.cjs +10 -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 +10 -0
  8. package/dist/encryption/index.js.map +1 -1
  9. package/dist/index.cjs +109 -64
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +38 -12
  12. package/dist/index.d.ts +38 -12
  13. package/dist/index.js +108 -64
  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 +68 -21
  18. package/dist/kv/index.cjs.map +1 -1
  19. package/dist/kv/index.d.cts +7 -4
  20. package/dist/kv/index.d.ts +7 -4
  21. package/dist/kv/index.js +68 -21
  22. package/dist/kv/index.js.map +1 -1
  23. package/dist/kv/replication/contractConstants.cjs +115 -0
  24. package/dist/kv/replication/contractConstants.cjs.map +1 -0
  25. package/dist/kv/replication/contractConstants.d.cts +77 -0
  26. package/dist/kv/replication/contractConstants.d.ts +77 -0
  27. package/dist/kv/replication/contractConstants.js +75 -0
  28. package/dist/kv/replication/contractConstants.js.map +1 -0
  29. package/dist/kv/replication/grantPolicy.cjs +82 -0
  30. package/dist/kv/replication/grantPolicy.cjs.map +1 -0
  31. package/dist/kv/replication/grantPolicy.d.cts +19 -0
  32. package/dist/kv/replication/grantPolicy.d.ts +19 -0
  33. package/dist/kv/replication/grantPolicy.js +50 -0
  34. package/dist/kv/replication/grantPolicy.js.map +1 -0
  35. package/dist/kv/replication/grantPolicyConstants.cjs +42 -0
  36. package/dist/kv/replication/grantPolicyConstants.cjs.map +1 -0
  37. package/dist/kv/replication/grantPolicyConstants.d.cts +10 -0
  38. package/dist/kv/replication/grantPolicyConstants.d.ts +10 -0
  39. package/dist/kv/replication/grantPolicyConstants.js +14 -0
  40. package/dist/kv/replication/grantPolicyConstants.js.map +1 -0
  41. package/dist/kv/replication/grantPolicyTypes.cjs +19 -0
  42. package/dist/kv/replication/grantPolicyTypes.cjs.map +1 -0
  43. package/dist/kv/replication/grantPolicyTypes.d.cts +87 -0
  44. package/dist/kv/replication/grantPolicyTypes.d.ts +87 -0
  45. package/dist/kv/replication/grantPolicyTypes.js +1 -0
  46. package/dist/kv/replication/grantPolicyTypes.js.map +1 -0
  47. package/dist/kv/replication/index.cjs +575 -131
  48. package/dist/kv/replication/index.cjs.map +1 -1
  49. package/dist/kv/replication/index.d.cts +6 -3
  50. package/dist/kv/replication/index.d.ts +6 -3
  51. package/dist/kv/replication/index.js +575 -131
  52. package/dist/kv/replication/index.js.map +1 -1
  53. package/dist/scope-B-m6cKH-.d.ts +1962 -0
  54. package/dist/scope-B7oeKdLM.d.cts +1962 -0
  55. package/dist/sql/index.cjs +72 -36
  56. package/dist/sql/index.cjs.map +1 -1
  57. package/dist/sql/index.d.cts +2 -2
  58. package/dist/sql/index.d.ts +2 -2
  59. package/dist/sql/index.js +72 -36
  60. package/dist/sql/index.js.map +1 -1
  61. package/dist/{types-D-9A3Sut.d.cts → types-BjH0ZtGy.d.cts} +8 -0
  62. package/dist/{types-D-9A3Sut.d.ts → types-BjH0ZtGy.d.ts} +8 -0
  63. package/package.json +55 -2
  64. package/dist/scope-CoKKmMiI.d.ts +0 -957
  65. package/dist/scope-D7wmjbMH.d.cts +0 -957
@@ -1,8 +1,11 @@
1
- import { B as BaseService } from '../BaseService-4wwJq1Gn.cjs';
2
- import { R as Result, I as IService } from '../types-D-9A3Sut.cjs';
3
- import { Y as KVGetOptions, a1 as KVResponse, Q as KVBatchReadResponse, a0 as KVPutOptions, M as KVBatchPutItem, N as KVBatchPutOptions, O as KVBatchPutResponse, _ as KVListOptions, $ as KVListResponse, U as KVChangesOptions, V as KVChangesResponse, X as KVDeleteOptions, Z as KVHeadOptions, W as KVCreateSignedReadUrlOptions, a4 as KVSignedReadUrlResponse, a3 as KVServiceConfig, c as KVReadThrough } from '../scope-D7wmjbMH.cjs';
4
- export { A as AuthorityRefusal, C as CLEAR_PENDING_WARNING, H as DEFAULT_SIGNED_READ_URL_EXPIRY_MS, I as KVAction, J as KVActionType, S as KVChange, T as KVChangesAuthority, b as KVListPage, d as KVReplicaHandle, e as KVReplicaSpec, f as KVReplicaStorage, a as KVReplicationController, K as KVReplicationDeps, a2 as KVResponseHeaders, 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 ReplicaAuthorityState, p as ReplicaCoverage, q as ReplicaDevice, r as ReplicaGrantInfo, s as ReplicaState, t as ReplicaStatusEntry, u as ReplicationAuthority, v as ReplicationControl, w as ReplicationEvent, R as ReplicationIdentity, x as ReplicationOptions, y as ReplicationPurgeReport, z as ReplicationReason, B as ReplicationScheduler, D as ResolvedReplicationOptions, E as canonicalReplicationIdentity, F as replicationIdentityKey, G as requiresSecretsOptIn } from '../scope-D7wmjbMH.cjs';
1
+ import { B as BaseService } from '../BaseService-Cc6Ueicm.cjs';
2
+ import { R as Result, I as IService } from '../types-BjH0ZtGy.cjs';
3
+ import { aD as KVGetOptions, aI as KVResponse, aw as KVBatchReadResponse, aH as KVPutOptions, at as KVBatchPutItem, au as KVBatchPutOptions, av as KVBatchPutResponse, aF as KVListOptions, aG as KVListResponse, az as KVChangesOptions, aA as KVChangesResponse, aC as KVDeleteOptions, aE as KVHeadOptions, aB as KVCreateSignedReadUrlOptions, aL as KVSignedReadUrlResponse, aK as KVServiceConfig, c as KVReadThrough } from '../scope-B7oeKdLM.cjs';
4
+ export { A as AuthorityRefusal, C as CLEAR_PENDING_WARNING, aq as DEFAULT_SIGNED_READ_URL_EXPIRY_MS, ar as KVAction, as as KVActionType, ax as KVChange, ay as KVChangesAuthority, b as KVListPage, d as KVReplicaHandle, e as KVReplicaSpec, f as KVReplicaStorage, a as KVReplicationController, K as KVReplicationDeps, aJ as KVResponseHeaders, 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, z as ReplicaAuthorityState, H as ReplicaCoverage, N as ReplicaDevice, X as ReplicaGatedHandle, _ as ReplicaGrantInfo, a0 as ReplicaInspectedStatus, 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, an as canonicalReplicationIdentity, ao as replicationIdentityKey, ap as requiresSecretsOptIn } from '../scope-B7oeKdLM.cjs';
5
5
  export { kvPrefixCovers } from './replication/prefix.cjs';
6
+ import './replication/contractConstants.cjs';
7
+ import './replication/grantPolicyConstants.cjs';
8
+ import './replication/grantPolicyTypes.cjs';
6
9
 
7
10
  /**
8
11
  * PrefixedKVService - A prefix-scoped view of KVService.
@@ -1,8 +1,11 @@
1
- import { B as BaseService } from '../BaseService-BGr2slUz.js';
2
- import { R as Result, I as IService } from '../types-D-9A3Sut.js';
3
- import { Y as KVGetOptions, a1 as KVResponse, Q as KVBatchReadResponse, a0 as KVPutOptions, M as KVBatchPutItem, N as KVBatchPutOptions, O as KVBatchPutResponse, _ as KVListOptions, $ as KVListResponse, U as KVChangesOptions, V as KVChangesResponse, X as KVDeleteOptions, Z as KVHeadOptions, W as KVCreateSignedReadUrlOptions, a4 as KVSignedReadUrlResponse, a3 as KVServiceConfig, c as KVReadThrough } from '../scope-CoKKmMiI.js';
4
- export { A as AuthorityRefusal, C as CLEAR_PENDING_WARNING, H as DEFAULT_SIGNED_READ_URL_EXPIRY_MS, I as KVAction, J as KVActionType, S as KVChange, T as KVChangesAuthority, b as KVListPage, d as KVReplicaHandle, e as KVReplicaSpec, f as KVReplicaStorage, a as KVReplicationController, K as KVReplicationDeps, a2 as KVResponseHeaders, 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 ReplicaAuthorityState, p as ReplicaCoverage, q as ReplicaDevice, r as ReplicaGrantInfo, s as ReplicaState, t as ReplicaStatusEntry, u as ReplicationAuthority, v as ReplicationControl, w as ReplicationEvent, R as ReplicationIdentity, x as ReplicationOptions, y as ReplicationPurgeReport, z as ReplicationReason, B as ReplicationScheduler, D as ResolvedReplicationOptions, E as canonicalReplicationIdentity, F as replicationIdentityKey, G as requiresSecretsOptIn } from '../scope-CoKKmMiI.js';
1
+ import { B as BaseService } from '../BaseService-DOdXd7sr.js';
2
+ import { R as Result, I as IService } from '../types-BjH0ZtGy.js';
3
+ import { aD as KVGetOptions, aI as KVResponse, aw as KVBatchReadResponse, aH as KVPutOptions, at as KVBatchPutItem, au as KVBatchPutOptions, av as KVBatchPutResponse, aF as KVListOptions, aG as KVListResponse, az as KVChangesOptions, aA as KVChangesResponse, aC as KVDeleteOptions, aE as KVHeadOptions, aB as KVCreateSignedReadUrlOptions, aL as KVSignedReadUrlResponse, aK as KVServiceConfig, c as KVReadThrough } from '../scope-B-m6cKH-.js';
4
+ export { A as AuthorityRefusal, C as CLEAR_PENDING_WARNING, aq as DEFAULT_SIGNED_READ_URL_EXPIRY_MS, ar as KVAction, as as KVActionType, ax as KVChange, ay as KVChangesAuthority, b as KVListPage, d as KVReplicaHandle, e as KVReplicaSpec, f as KVReplicaStorage, a as KVReplicationController, K as KVReplicationDeps, aJ as KVResponseHeaders, 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, z as ReplicaAuthorityState, H as ReplicaCoverage, N as ReplicaDevice, X as ReplicaGatedHandle, _ as ReplicaGrantInfo, a0 as ReplicaInspectedStatus, 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, an as canonicalReplicationIdentity, ao as replicationIdentityKey, ap as requiresSecretsOptIn } from '../scope-B-m6cKH-.js';
5
5
  export { kvPrefixCovers } from './replication/prefix.js';
6
+ import './replication/contractConstants.js';
7
+ import './replication/grantPolicyConstants.js';
8
+ import './replication/grantPolicyTypes.js';
6
9
 
7
10
  /**
8
11
  * PrefixedKVService - A prefix-scoped view of KVService.
package/dist/kv/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",
@@ -68,6 +76,8 @@ var TelemetryEvents = {
68
76
  REPLICATION_SYNC: "replication.sync",
69
77
  REPLICATION_STATE: "replication.state",
70
78
  REPLICATION_DIVERGENCE: "replication.divergence",
79
+ REPLICATION_GRANT: "replication.grant",
80
+ REPLICATION_LIFECYCLE: "replication.lifecycle",
71
81
  /** Emitted once, on the first write rejected because storage is full. */
72
82
  STORAGE_FULL: "storage.full"
73
83
  };
@@ -87,6 +97,20 @@ function serviceError(code, message, service, options) {
87
97
  };
88
98
  }
89
99
 
100
+ // src/responseErrors.ts
101
+ function responseErrorMeta(status, statusText, errorText) {
102
+ const meta = { status, statusText };
103
+ const snippet = compactMessage(errorText);
104
+ if (snippet) {
105
+ meta.responseSnippet = snippet.slice(0, 300);
106
+ }
107
+ return meta;
108
+ }
109
+ function compactMessage(message) {
110
+ const compact = message.replace(/\s+/g, " ").trim();
111
+ return compact.length > 500 ? `${compact.slice(0, 500)}...` : compact;
112
+ }
113
+
90
114
  // src/errors.ts
91
115
  import { CAPABILITY_REGISTRY } from "@tinycloud/bootstrap";
92
116
 
@@ -180,6 +204,30 @@ function authRequiredError(service) {
180
204
  service
181
205
  };
182
206
  }
207
+ function nodeRetryError(service, message, response, errorText) {
208
+ const body = errorText.trim();
209
+ const [, token, stage] = /^([a-z_]+)(?::\s*([a-z_]+):)?/.exec(body) ?? [];
210
+ let code;
211
+ if (response.status === 503 && (token === "sql_busy" || token === "unavailable_retryable")) {
212
+ code = ErrorCodes.NODE_BUSY;
213
+ } else if (response.status === 503 && token === "request_timeout") {
214
+ code = ErrorCodes.REQUEST_TIMEOUT;
215
+ } else if (response.status === 500 && token === "outcome_unknown") {
216
+ code = ErrorCodes.OUTCOME_UNKNOWN;
217
+ } else {
218
+ return void 0;
219
+ }
220
+ const retryable = code !== ErrorCodes.OUTCOME_UNKNOWN;
221
+ const retryAfter = response.headers.get("retry-after")?.trim();
222
+ return serviceError(code, message, service, {
223
+ meta: {
224
+ ...responseErrorMeta(response.status, response.statusText, errorText),
225
+ retryable,
226
+ ...token === "sql_busy" && stage ? { stage } : {},
227
+ ...retryable && retryAfter && /^\d{1,9}$/.test(retryAfter) ? { retryAfterMs: Number(retryAfter) * 1e3 } : {}
228
+ }
229
+ });
230
+ }
183
231
  var RequestTimeoutError = class extends Error {
184
232
  constructor(timeoutMs) {
185
233
  super(`Request timed out after ${timeoutMs}ms.`);
@@ -1498,9 +1546,12 @@ var KVService = class extends BaseService {
1498
1546
  { meta: { status: response.status, statusText: response.statusText } }
1499
1547
  ));
1500
1548
  }
1549
+ const message = `Failed to get key ${JSON.stringify(key)}: ${response.status} - ${errorText}`;
1550
+ const retryError = nodeRetryError("kv", message, response, errorText);
1551
+ if (retryError) return err(retryError);
1501
1552
  return err(serviceError(
1502
1553
  ErrorCodes.NETWORK_ERROR,
1503
- `Failed to get key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,
1554
+ message,
1504
1555
  "kv",
1505
1556
  { meta: { status: response.status, statusText: response.statusText } }
1506
1557
  ));
@@ -1582,19 +1633,14 @@ var KVService = class extends BaseService {
1582
1633
  { meta: { status: response.status, statusText: response.statusText } }
1583
1634
  ));
1584
1635
  }
1585
- if (response.status === 503 && (options?.ifMatch !== void 0 || options?.ifNoneMatch !== void 0)) {
1586
- return err(serviceError(
1587
- ErrorCodes.KV_CONFLICT,
1588
- `Concurrent KV update conflicted for key ${JSON.stringify(key)}`,
1589
- "kv",
1590
- { meta: { status: response.status, statusText: response.statusText } }
1591
- ));
1592
- }
1636
+ const message = `Failed to put key ${JSON.stringify(key)}: ${response.status} - ${errorText}`;
1637
+ const retryError = nodeRetryError("kv", message, response, errorText);
1638
+ if (retryError) return err(retryError);
1593
1639
  const quotaError = this.handleQuotaErrorResponse(response, errorText, key);
1594
1640
  if (quotaError) return quotaError;
1595
1641
  return err(serviceError(
1596
1642
  ErrorCodes.KV_WRITE_FAILED,
1597
- `Failed to put key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,
1643
+ message,
1598
1644
  "kv",
1599
1645
  { meta: { status: response.status, statusText: response.statusText } }
1600
1646
  ));
@@ -1894,9 +1940,12 @@ var KVService = class extends BaseService {
1894
1940
  );
1895
1941
  }
1896
1942
  const errorText = await response.text();
1943
+ const message = `Failed to list keys: ${response.status} - ${errorText}`;
1944
+ const retryError = nodeRetryError("kv", message, response, errorText);
1945
+ if (retryError) return err(retryError);
1897
1946
  return err(serviceError(
1898
1947
  ErrorCodes.NETWORK_ERROR,
1899
- `Failed to list keys: ${response.status} - ${errorText}`,
1948
+ message,
1900
1949
  "kv",
1901
1950
  { meta: { status: response.status, statusText: response.statusText } }
1902
1951
  ));
@@ -2147,17 +2196,12 @@ var KVService = class extends BaseService {
2147
2196
  { meta: { status: response.status, statusText: response.statusText } }
2148
2197
  ));
2149
2198
  }
2150
- if (response.status === 503 && options?.ifMatch !== void 0) {
2151
- return err(serviceError(
2152
- ErrorCodes.KV_CONFLICT,
2153
- `Concurrent KV delete conflicted for key ${JSON.stringify(key)}`,
2154
- "kv",
2155
- { meta: { status: response.status, statusText: response.statusText } }
2156
- ));
2157
- }
2199
+ const message = `Failed to delete key ${JSON.stringify(key)}: ${response.status} - ${errorText}`;
2200
+ const retryError = nodeRetryError("kv", message, response, errorText);
2201
+ if (retryError) return err(retryError);
2158
2202
  return err(serviceError(
2159
2203
  ErrorCodes.NETWORK_ERROR,
2160
- `Failed to delete key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,
2204
+ message,
2161
2205
  "kv",
2162
2206
  { meta: { status: response.status, statusText: response.statusText } }
2163
2207
  ));
@@ -2198,10 +2242,13 @@ var KVService = class extends BaseService {
2198
2242
  return await this.classifyNotFound(response, key);
2199
2243
  }
2200
2244
  const errorText = await response.text();
2245
+ const message = `Failed to get metadata for key ${JSON.stringify(key)}: ${response.status} - ${errorText}`;
2246
+ const retryError = nodeRetryError("kv", message, response, errorText);
2247
+ if (retryError) return err(retryError);
2201
2248
  return err(
2202
2249
  serviceError(
2203
2250
  ErrorCodes.NETWORK_ERROR,
2204
- `Failed to get metadata for key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,
2251
+ message,
2205
2252
  "kv",
2206
2253
  { meta: { status: response.status, statusText: response.statusText } }
2207
2254
  )