@tinycloud/sdk-services 3.2.6-beta.2 → 3.3.0-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{BaseService-4wwJq1Gn.d.cts → BaseService-Cc6Ueicm.d.cts} +1 -1
- package/dist/{BaseService-BGr2slUz.d.ts → BaseService-DOdXd7sr.d.ts} +1 -1
- package/dist/encryption/index.cjs +10 -0
- package/dist/encryption/index.cjs.map +1 -1
- package/dist/encryption/index.d.cts +2 -2
- package/dist/encryption/index.d.ts +2 -2
- package/dist/encryption/index.js +10 -0
- package/dist/encryption/index.js.map +1 -1
- package/dist/index.cjs +360 -210
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +116 -13
- package/dist/index.d.ts +116 -13
- package/dist/index.js +359 -210
- package/dist/index.js.map +1 -1
- package/dist/internal/decrypt-transport-response-error.d.cts +1 -1
- package/dist/internal/decrypt-transport-response-error.d.ts +1 -1
- package/dist/kv/index.cjs +68 -21
- package/dist/kv/index.cjs.map +1 -1
- package/dist/kv/index.d.cts +7 -4
- package/dist/kv/index.d.ts +7 -4
- package/dist/kv/index.js +68 -21
- package/dist/kv/index.js.map +1 -1
- package/dist/kv/replication/contractConstants.cjs +115 -0
- package/dist/kv/replication/contractConstants.cjs.map +1 -0
- package/dist/kv/replication/contractConstants.d.cts +77 -0
- package/dist/kv/replication/contractConstants.d.ts +77 -0
- package/dist/kv/replication/contractConstants.js +75 -0
- package/dist/kv/replication/contractConstants.js.map +1 -0
- package/dist/kv/replication/grantPolicy.cjs +82 -0
- package/dist/kv/replication/grantPolicy.cjs.map +1 -0
- package/dist/kv/replication/grantPolicy.d.cts +19 -0
- package/dist/kv/replication/grantPolicy.d.ts +19 -0
- package/dist/kv/replication/grantPolicy.js +50 -0
- package/dist/kv/replication/grantPolicy.js.map +1 -0
- package/dist/kv/replication/grantPolicyConstants.cjs +42 -0
- package/dist/kv/replication/grantPolicyConstants.cjs.map +1 -0
- package/dist/kv/replication/grantPolicyConstants.d.cts +10 -0
- package/dist/kv/replication/grantPolicyConstants.d.ts +10 -0
- package/dist/kv/replication/grantPolicyConstants.js +14 -0
- package/dist/kv/replication/grantPolicyConstants.js.map +1 -0
- package/dist/kv/replication/grantPolicyTypes.cjs +19 -0
- package/dist/kv/replication/grantPolicyTypes.cjs.map +1 -0
- package/dist/kv/replication/grantPolicyTypes.d.cts +87 -0
- package/dist/kv/replication/grantPolicyTypes.d.ts +87 -0
- package/dist/kv/replication/grantPolicyTypes.js +1 -0
- package/dist/kv/replication/grantPolicyTypes.js.map +1 -0
- package/dist/kv/replication/index.cjs +575 -131
- package/dist/kv/replication/index.cjs.map +1 -1
- package/dist/kv/replication/index.d.cts +6 -3
- package/dist/kv/replication/index.d.ts +6 -3
- package/dist/kv/replication/index.js +575 -131
- package/dist/kv/replication/index.js.map +1 -1
- package/dist/scope-B-m6cKH-.d.ts +1962 -0
- package/dist/scope-B7oeKdLM.d.cts +1962 -0
- package/dist/sql/index.cjs +72 -36
- package/dist/sql/index.cjs.map +1 -1
- package/dist/sql/index.d.cts +2 -2
- package/dist/sql/index.d.ts +2 -2
- package/dist/sql/index.js +72 -36
- package/dist/sql/index.js.map +1 -1
- package/dist/{types-D-9A3Sut.d.cts → types-BjH0ZtGy.d.cts} +8 -0
- package/dist/{types-D-9A3Sut.d.ts → types-BjH0ZtGy.d.ts} +8 -0
- package/package.json +55 -2
- package/dist/scope-CoKKmMiI.d.ts +0 -957
- package/dist/scope-D7wmjbMH.d.cts +0 -957
package/dist/sql/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,42 @@ function serviceError(code, message, service, options) {
|
|
|
87
97
|
};
|
|
88
98
|
}
|
|
89
99
|
|
|
100
|
+
// src/responseErrors.ts
|
|
101
|
+
function parseServiceErrorBody(errorText) {
|
|
102
|
+
try {
|
|
103
|
+
return JSON.parse(errorText);
|
|
104
|
+
} catch {
|
|
105
|
+
return {};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function formatServiceResponseError(serviceLabel, operation, status, errorText, parsed) {
|
|
109
|
+
if (parsed.message) {
|
|
110
|
+
return compactMessage(parsed.message);
|
|
111
|
+
}
|
|
112
|
+
if (looksLikeHtml(errorText)) {
|
|
113
|
+
if (status === 524 || /524\s*[:-]/i.test(errorText) || /a timeout occurred/i.test(errorText)) {
|
|
114
|
+
return `${serviceLabel} ${operation} failed: upstream request timed out. Please retry.`;
|
|
115
|
+
}
|
|
116
|
+
return `${serviceLabel} ${operation} failed: upstream service returned an HTML error page (${status}).`;
|
|
117
|
+
}
|
|
118
|
+
return `${serviceLabel} ${operation} failed: ${status} - ${compactMessage(errorText)}`;
|
|
119
|
+
}
|
|
120
|
+
function responseErrorMeta(status, statusText, errorText) {
|
|
121
|
+
const meta = { status, statusText };
|
|
122
|
+
const snippet = compactMessage(errorText);
|
|
123
|
+
if (snippet) {
|
|
124
|
+
meta.responseSnippet = snippet.slice(0, 300);
|
|
125
|
+
}
|
|
126
|
+
return meta;
|
|
127
|
+
}
|
|
128
|
+
function looksLikeHtml(text) {
|
|
129
|
+
return /<!doctype html/i.test(text) || /<html[\s>]/i.test(text);
|
|
130
|
+
}
|
|
131
|
+
function compactMessage(message) {
|
|
132
|
+
const compact = message.replace(/\s+/g, " ").trim();
|
|
133
|
+
return compact.length > 500 ? `${compact.slice(0, 500)}...` : compact;
|
|
134
|
+
}
|
|
135
|
+
|
|
90
136
|
// src/errors.ts
|
|
91
137
|
import { CAPABILITY_REGISTRY } from "@tinycloud/bootstrap";
|
|
92
138
|
function authRequiredError(service) {
|
|
@@ -96,6 +142,30 @@ function authRequiredError(service) {
|
|
|
96
142
|
service
|
|
97
143
|
};
|
|
98
144
|
}
|
|
145
|
+
function nodeRetryError(service, message, response, errorText) {
|
|
146
|
+
const body = errorText.trim();
|
|
147
|
+
const [, token, stage] = /^([a-z_]+)(?::\s*([a-z_]+):)?/.exec(body) ?? [];
|
|
148
|
+
let code;
|
|
149
|
+
if (response.status === 503 && (token === "sql_busy" || token === "unavailable_retryable")) {
|
|
150
|
+
code = ErrorCodes.NODE_BUSY;
|
|
151
|
+
} else if (response.status === 503 && token === "request_timeout") {
|
|
152
|
+
code = ErrorCodes.REQUEST_TIMEOUT;
|
|
153
|
+
} else if (response.status === 500 && token === "outcome_unknown") {
|
|
154
|
+
code = ErrorCodes.OUTCOME_UNKNOWN;
|
|
155
|
+
} else {
|
|
156
|
+
return void 0;
|
|
157
|
+
}
|
|
158
|
+
const retryable = code !== ErrorCodes.OUTCOME_UNKNOWN;
|
|
159
|
+
const retryAfter = response.headers.get("retry-after")?.trim();
|
|
160
|
+
return serviceError(code, message, service, {
|
|
161
|
+
meta: {
|
|
162
|
+
...responseErrorMeta(response.status, response.statusText, errorText),
|
|
163
|
+
retryable,
|
|
164
|
+
...token === "sql_busy" && stage ? { stage } : {},
|
|
165
|
+
...retryable && retryAfter && /^\d{1,9}$/.test(retryAfter) ? { retryAfterMs: Number(retryAfter) * 1e3 } : {}
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
}
|
|
99
169
|
var RequestTimeoutError = class extends Error {
|
|
100
170
|
constructor(timeoutMs) {
|
|
101
171
|
super(`Request timed out after ${timeoutMs}ms.`);
|
|
@@ -503,42 +573,6 @@ var BaseService = class {
|
|
|
503
573
|
}
|
|
504
574
|
};
|
|
505
575
|
|
|
506
|
-
// src/responseErrors.ts
|
|
507
|
-
function parseServiceErrorBody(errorText) {
|
|
508
|
-
try {
|
|
509
|
-
return JSON.parse(errorText);
|
|
510
|
-
} catch {
|
|
511
|
-
return {};
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
function formatServiceResponseError(serviceLabel, operation, status, errorText, parsed) {
|
|
515
|
-
if (parsed.message) {
|
|
516
|
-
return compactMessage(parsed.message);
|
|
517
|
-
}
|
|
518
|
-
if (looksLikeHtml(errorText)) {
|
|
519
|
-
if (status === 524 || /524\s*[:-]/i.test(errorText) || /a timeout occurred/i.test(errorText)) {
|
|
520
|
-
return `${serviceLabel} ${operation} failed: upstream request timed out. Please retry.`;
|
|
521
|
-
}
|
|
522
|
-
return `${serviceLabel} ${operation} failed: upstream service returned an HTML error page (${status}).`;
|
|
523
|
-
}
|
|
524
|
-
return `${serviceLabel} ${operation} failed: ${status} - ${compactMessage(errorText)}`;
|
|
525
|
-
}
|
|
526
|
-
function responseErrorMeta(status, statusText, errorText) {
|
|
527
|
-
const meta = { status, statusText };
|
|
528
|
-
const snippet = compactMessage(errorText);
|
|
529
|
-
if (snippet) {
|
|
530
|
-
meta.responseSnippet = snippet.slice(0, 300);
|
|
531
|
-
}
|
|
532
|
-
return meta;
|
|
533
|
-
}
|
|
534
|
-
function looksLikeHtml(text) {
|
|
535
|
-
return /<!doctype html/i.test(text) || /<html[\s>]/i.test(text);
|
|
536
|
-
}
|
|
537
|
-
function compactMessage(message) {
|
|
538
|
-
const compact = message.replace(/\s+/g, " ").trim();
|
|
539
|
-
return compact.length > 500 ? `${compact.slice(0, 500)}...` : compact;
|
|
540
|
-
}
|
|
541
|
-
|
|
542
576
|
// src/sql/SQLMigrations.ts
|
|
543
577
|
var SQLMigrations = class {
|
|
544
578
|
constructor(service, dbName) {
|
|
@@ -954,6 +988,8 @@ var SQLService = class extends BaseService {
|
|
|
954
988
|
if (response.status === 413 && parseStorageRejection(errorText)) {
|
|
955
989
|
return err(storageRejectionError("sql", 413, meta, errorText));
|
|
956
990
|
}
|
|
991
|
+
const retryError = nodeRetryError("sql", `SQL ${operation} failed: ${response.status} - ${errorText}`, response, errorText);
|
|
992
|
+
if (retryError) return err(retryError);
|
|
957
993
|
const errorBody = parseServiceErrorBody(errorText);
|
|
958
994
|
const errorCode = this.mapHttpStatusToErrorCode(
|
|
959
995
|
response.status,
|