@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
@@ -1,4 +1,4 @@
1
- import { P as PermissionHint } from '../types-gmdUiorz.cjs';
1
+ import { P as PermissionHint } from '../types-BjH0ZtGy.cjs';
2
2
 
3
3
  /** A reachable node returned an HTTP failure for a decrypt request. */
4
4
  declare class DecryptTransportResponseError extends Error {
@@ -1,4 +1,4 @@
1
- import { P as PermissionHint } from '../types-gmdUiorz.js';
1
+ import { P as PermissionHint } from '../types-BjH0ZtGy.js';
2
2
 
3
3
  /** A reachable node returned an HTTP failure for a decrypt request. */
4
4
  declare class DecryptTransportResponseError extends Error {
package/dist/kv/index.cjs CHANGED
@@ -48,6 +48,14 @@ var ErrorCodes = {
48
48
  ABORTED: "ABORTED",
49
49
  INVALID_INPUT: "INVALID_INPUT",
50
50
  PERMISSION_DENIED: "PERMISSION_DENIED",
51
+ // Node retry signals (tinycloud-node #347). `meta.retryable` says whether a
52
+ // retry is safe; `meta.retryAfterMs` carries the node's Retry-After.
53
+ /** HTTP 503 `sql_busy:<stage>` / `unavailable_retryable`: nothing was applied; retry after `meta.retryAfterMs`. */
54
+ NODE_BUSY: "NODE_BUSY",
55
+ /** HTTP 503 `request_timeout`: the node's deadline passed before any write began; nothing was applied. */
56
+ REQUEST_TIMEOUT: "REQUEST_TIMEOUT",
57
+ /** HTTP 500 `outcome_unknown`: a write may have been applied; read back before retrying a non-idempotent operation. */
58
+ OUTCOME_UNKNOWN: "OUTCOME_UNKNOWN",
51
59
  // KV-specific errors
52
60
  KV_NOT_FOUND: "KV_NOT_FOUND",
53
61
  KV_WRITE_FAILED: "KV_WRITE_FAILED",
@@ -123,6 +131,20 @@ function serviceError(code, message, service, options) {
123
131
  };
124
132
  }
125
133
 
134
+ // src/responseErrors.ts
135
+ function responseErrorMeta(status, statusText, errorText) {
136
+ const meta = { status, statusText };
137
+ const snippet = compactMessage(errorText);
138
+ if (snippet) {
139
+ meta.responseSnippet = snippet.slice(0, 300);
140
+ }
141
+ return meta;
142
+ }
143
+ function compactMessage(message) {
144
+ const compact = message.replace(/\s+/g, " ").trim();
145
+ return compact.length > 500 ? `${compact.slice(0, 500)}...` : compact;
146
+ }
147
+
126
148
  // src/errors.ts
127
149
  var import_bootstrap = require("@tinycloud/bootstrap");
128
150
 
@@ -216,6 +238,30 @@ function authRequiredError(service) {
216
238
  service
217
239
  };
218
240
  }
241
+ function nodeRetryError(service, message, response, errorText) {
242
+ const body = errorText.trim();
243
+ const [, token, stage] = /^([a-z_]+)(?::\s*([a-z_]+):)?/.exec(body) ?? [];
244
+ let code;
245
+ if (response.status === 503 && (token === "sql_busy" || token === "unavailable_retryable")) {
246
+ code = ErrorCodes.NODE_BUSY;
247
+ } else if (response.status === 503 && token === "request_timeout") {
248
+ code = ErrorCodes.REQUEST_TIMEOUT;
249
+ } else if (response.status === 500 && token === "outcome_unknown") {
250
+ code = ErrorCodes.OUTCOME_UNKNOWN;
251
+ } else {
252
+ return void 0;
253
+ }
254
+ const retryable = code !== ErrorCodes.OUTCOME_UNKNOWN;
255
+ const retryAfter = response.headers.get("retry-after")?.trim();
256
+ return serviceError(code, message, service, {
257
+ meta: {
258
+ ...responseErrorMeta(response.status, response.statusText, errorText),
259
+ retryable,
260
+ ...token === "sql_busy" && stage ? { stage } : {},
261
+ ...retryable && retryAfter && /^\d{1,9}$/.test(retryAfter) ? { retryAfterMs: Number(retryAfter) * 1e3 } : {}
262
+ }
263
+ });
264
+ }
219
265
  var RequestTimeoutError = class extends Error {
220
266
  constructor(timeoutMs) {
221
267
  super(`Request timed out after ${timeoutMs}ms.`);
@@ -1534,9 +1580,12 @@ var KVService = class extends BaseService {
1534
1580
  { meta: { status: response.status, statusText: response.statusText } }
1535
1581
  ));
1536
1582
  }
1583
+ const message = `Failed to get key ${JSON.stringify(key)}: ${response.status} - ${errorText}`;
1584
+ const retryError = nodeRetryError("kv", message, response, errorText);
1585
+ if (retryError) return err(retryError);
1537
1586
  return err(serviceError(
1538
1587
  ErrorCodes.NETWORK_ERROR,
1539
- `Failed to get key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,
1588
+ message,
1540
1589
  "kv",
1541
1590
  { meta: { status: response.status, statusText: response.statusText } }
1542
1591
  ));
@@ -1618,19 +1667,14 @@ var KVService = class extends BaseService {
1618
1667
  { meta: { status: response.status, statusText: response.statusText } }
1619
1668
  ));
1620
1669
  }
1621
- if (response.status === 503 && (options?.ifMatch !== void 0 || options?.ifNoneMatch !== void 0)) {
1622
- return err(serviceError(
1623
- ErrorCodes.KV_CONFLICT,
1624
- `Concurrent KV update conflicted for key ${JSON.stringify(key)}`,
1625
- "kv",
1626
- { meta: { status: response.status, statusText: response.statusText } }
1627
- ));
1628
- }
1670
+ const message = `Failed to put key ${JSON.stringify(key)}: ${response.status} - ${errorText}`;
1671
+ const retryError = nodeRetryError("kv", message, response, errorText);
1672
+ if (retryError) return err(retryError);
1629
1673
  const quotaError = this.handleQuotaErrorResponse(response, errorText, key);
1630
1674
  if (quotaError) return quotaError;
1631
1675
  return err(serviceError(
1632
1676
  ErrorCodes.KV_WRITE_FAILED,
1633
- `Failed to put key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,
1677
+ message,
1634
1678
  "kv",
1635
1679
  { meta: { status: response.status, statusText: response.statusText } }
1636
1680
  ));
@@ -1930,9 +1974,12 @@ var KVService = class extends BaseService {
1930
1974
  );
1931
1975
  }
1932
1976
  const errorText = await response.text();
1977
+ const message = `Failed to list keys: ${response.status} - ${errorText}`;
1978
+ const retryError = nodeRetryError("kv", message, response, errorText);
1979
+ if (retryError) return err(retryError);
1933
1980
  return err(serviceError(
1934
1981
  ErrorCodes.NETWORK_ERROR,
1935
- `Failed to list keys: ${response.status} - ${errorText}`,
1982
+ message,
1936
1983
  "kv",
1937
1984
  { meta: { status: response.status, statusText: response.statusText } }
1938
1985
  ));
@@ -2183,17 +2230,12 @@ var KVService = class extends BaseService {
2183
2230
  { meta: { status: response.status, statusText: response.statusText } }
2184
2231
  ));
2185
2232
  }
2186
- if (response.status === 503 && options?.ifMatch !== void 0) {
2187
- return err(serviceError(
2188
- ErrorCodes.KV_CONFLICT,
2189
- `Concurrent KV delete conflicted for key ${JSON.stringify(key)}`,
2190
- "kv",
2191
- { meta: { status: response.status, statusText: response.statusText } }
2192
- ));
2193
- }
2233
+ const message = `Failed to delete key ${JSON.stringify(key)}: ${response.status} - ${errorText}`;
2234
+ const retryError = nodeRetryError("kv", message, response, errorText);
2235
+ if (retryError) return err(retryError);
2194
2236
  return err(serviceError(
2195
2237
  ErrorCodes.NETWORK_ERROR,
2196
- `Failed to delete key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,
2238
+ message,
2197
2239
  "kv",
2198
2240
  { meta: { status: response.status, statusText: response.statusText } }
2199
2241
  ));
@@ -2234,10 +2276,13 @@ var KVService = class extends BaseService {
2234
2276
  return await this.classifyNotFound(response, key);
2235
2277
  }
2236
2278
  const errorText = await response.text();
2279
+ const message = `Failed to get metadata for key ${JSON.stringify(key)}: ${response.status} - ${errorText}`;
2280
+ const retryError = nodeRetryError("kv", message, response, errorText);
2281
+ if (retryError) return err(retryError);
2237
2282
  return err(
2238
2283
  serviceError(
2239
2284
  ErrorCodes.NETWORK_ERROR,
2240
- `Failed to get metadata for key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,
2285
+ message,
2241
2286
  "kv",
2242
2287
  { meta: { status: response.status, statusText: response.statusText } }
2243
2288
  )