@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.
- 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 +109 -64
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -12
- package/dist/index.d.ts +38 -12
- package/dist/index.js +108 -64
- 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.cjs
CHANGED
|
@@ -43,6 +43,14 @@ var ErrorCodes = {
|
|
|
43
43
|
ABORTED: "ABORTED",
|
|
44
44
|
INVALID_INPUT: "INVALID_INPUT",
|
|
45
45
|
PERMISSION_DENIED: "PERMISSION_DENIED",
|
|
46
|
+
// Node retry signals (tinycloud-node #347). `meta.retryable` says whether a
|
|
47
|
+
// retry is safe; `meta.retryAfterMs` carries the node's Retry-After.
|
|
48
|
+
/** HTTP 503 `sql_busy:<stage>` / `unavailable_retryable`: nothing was applied; retry after `meta.retryAfterMs`. */
|
|
49
|
+
NODE_BUSY: "NODE_BUSY",
|
|
50
|
+
/** HTTP 503 `request_timeout`: the node's deadline passed before any write began; nothing was applied. */
|
|
51
|
+
REQUEST_TIMEOUT: "REQUEST_TIMEOUT",
|
|
52
|
+
/** HTTP 500 `outcome_unknown`: a write may have been applied; read back before retrying a non-idempotent operation. */
|
|
53
|
+
OUTCOME_UNKNOWN: "OUTCOME_UNKNOWN",
|
|
46
54
|
// KV-specific errors
|
|
47
55
|
KV_NOT_FOUND: "KV_NOT_FOUND",
|
|
48
56
|
KV_WRITE_FAILED: "KV_WRITE_FAILED",
|
|
@@ -97,6 +105,8 @@ var TelemetryEvents = {
|
|
|
97
105
|
REPLICATION_SYNC: "replication.sync",
|
|
98
106
|
REPLICATION_STATE: "replication.state",
|
|
99
107
|
REPLICATION_DIVERGENCE: "replication.divergence",
|
|
108
|
+
REPLICATION_GRANT: "replication.grant",
|
|
109
|
+
REPLICATION_LIFECYCLE: "replication.lifecycle",
|
|
100
110
|
/** Emitted once, on the first write rejected because storage is full. */
|
|
101
111
|
STORAGE_FULL: "storage.full"
|
|
102
112
|
};
|
|
@@ -116,6 +126,42 @@ function serviceError(code, message, service, options) {
|
|
|
116
126
|
};
|
|
117
127
|
}
|
|
118
128
|
|
|
129
|
+
// src/responseErrors.ts
|
|
130
|
+
function parseServiceErrorBody(errorText) {
|
|
131
|
+
try {
|
|
132
|
+
return JSON.parse(errorText);
|
|
133
|
+
} catch {
|
|
134
|
+
return {};
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function formatServiceResponseError(serviceLabel, operation, status, errorText, parsed) {
|
|
138
|
+
if (parsed.message) {
|
|
139
|
+
return compactMessage(parsed.message);
|
|
140
|
+
}
|
|
141
|
+
if (looksLikeHtml(errorText)) {
|
|
142
|
+
if (status === 524 || /524\s*[:-]/i.test(errorText) || /a timeout occurred/i.test(errorText)) {
|
|
143
|
+
return `${serviceLabel} ${operation} failed: upstream request timed out. Please retry.`;
|
|
144
|
+
}
|
|
145
|
+
return `${serviceLabel} ${operation} failed: upstream service returned an HTML error page (${status}).`;
|
|
146
|
+
}
|
|
147
|
+
return `${serviceLabel} ${operation} failed: ${status} - ${compactMessage(errorText)}`;
|
|
148
|
+
}
|
|
149
|
+
function responseErrorMeta(status, statusText, errorText) {
|
|
150
|
+
const meta = { status, statusText };
|
|
151
|
+
const snippet = compactMessage(errorText);
|
|
152
|
+
if (snippet) {
|
|
153
|
+
meta.responseSnippet = snippet.slice(0, 300);
|
|
154
|
+
}
|
|
155
|
+
return meta;
|
|
156
|
+
}
|
|
157
|
+
function looksLikeHtml(text) {
|
|
158
|
+
return /<!doctype html/i.test(text) || /<html[\s>]/i.test(text);
|
|
159
|
+
}
|
|
160
|
+
function compactMessage(message) {
|
|
161
|
+
const compact = message.replace(/\s+/g, " ").trim();
|
|
162
|
+
return compact.length > 500 ? `${compact.slice(0, 500)}...` : compact;
|
|
163
|
+
}
|
|
164
|
+
|
|
119
165
|
// src/errors.ts
|
|
120
166
|
var import_bootstrap = require("@tinycloud/bootstrap");
|
|
121
167
|
function authRequiredError(service) {
|
|
@@ -125,6 +171,30 @@ function authRequiredError(service) {
|
|
|
125
171
|
service
|
|
126
172
|
};
|
|
127
173
|
}
|
|
174
|
+
function nodeRetryError(service, message, response, errorText) {
|
|
175
|
+
const body = errorText.trim();
|
|
176
|
+
const [, token, stage] = /^([a-z_]+)(?::\s*([a-z_]+):)?/.exec(body) ?? [];
|
|
177
|
+
let code;
|
|
178
|
+
if (response.status === 503 && (token === "sql_busy" || token === "unavailable_retryable")) {
|
|
179
|
+
code = ErrorCodes.NODE_BUSY;
|
|
180
|
+
} else if (response.status === 503 && token === "request_timeout") {
|
|
181
|
+
code = ErrorCodes.REQUEST_TIMEOUT;
|
|
182
|
+
} else if (response.status === 500 && token === "outcome_unknown") {
|
|
183
|
+
code = ErrorCodes.OUTCOME_UNKNOWN;
|
|
184
|
+
} else {
|
|
185
|
+
return void 0;
|
|
186
|
+
}
|
|
187
|
+
const retryable = code !== ErrorCodes.OUTCOME_UNKNOWN;
|
|
188
|
+
const retryAfter = response.headers.get("retry-after")?.trim();
|
|
189
|
+
return serviceError(code, message, service, {
|
|
190
|
+
meta: {
|
|
191
|
+
...responseErrorMeta(response.status, response.statusText, errorText),
|
|
192
|
+
retryable,
|
|
193
|
+
...token === "sql_busy" && stage ? { stage } : {},
|
|
194
|
+
...retryable && retryAfter && /^\d{1,9}$/.test(retryAfter) ? { retryAfterMs: Number(retryAfter) * 1e3 } : {}
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
}
|
|
128
198
|
var RequestTimeoutError = class extends Error {
|
|
129
199
|
constructor(timeoutMs) {
|
|
130
200
|
super(`Request timed out after ${timeoutMs}ms.`);
|
|
@@ -532,42 +602,6 @@ var BaseService = class {
|
|
|
532
602
|
}
|
|
533
603
|
};
|
|
534
604
|
|
|
535
|
-
// src/responseErrors.ts
|
|
536
|
-
function parseServiceErrorBody(errorText) {
|
|
537
|
-
try {
|
|
538
|
-
return JSON.parse(errorText);
|
|
539
|
-
} catch {
|
|
540
|
-
return {};
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
function formatServiceResponseError(serviceLabel, operation, status, errorText, parsed) {
|
|
544
|
-
if (parsed.message) {
|
|
545
|
-
return compactMessage(parsed.message);
|
|
546
|
-
}
|
|
547
|
-
if (looksLikeHtml(errorText)) {
|
|
548
|
-
if (status === 524 || /524\s*[:-]/i.test(errorText) || /a timeout occurred/i.test(errorText)) {
|
|
549
|
-
return `${serviceLabel} ${operation} failed: upstream request timed out. Please retry.`;
|
|
550
|
-
}
|
|
551
|
-
return `${serviceLabel} ${operation} failed: upstream service returned an HTML error page (${status}).`;
|
|
552
|
-
}
|
|
553
|
-
return `${serviceLabel} ${operation} failed: ${status} - ${compactMessage(errorText)}`;
|
|
554
|
-
}
|
|
555
|
-
function responseErrorMeta(status, statusText, errorText) {
|
|
556
|
-
const meta = { status, statusText };
|
|
557
|
-
const snippet = compactMessage(errorText);
|
|
558
|
-
if (snippet) {
|
|
559
|
-
meta.responseSnippet = snippet.slice(0, 300);
|
|
560
|
-
}
|
|
561
|
-
return meta;
|
|
562
|
-
}
|
|
563
|
-
function looksLikeHtml(text) {
|
|
564
|
-
return /<!doctype html/i.test(text) || /<html[\s>]/i.test(text);
|
|
565
|
-
}
|
|
566
|
-
function compactMessage(message) {
|
|
567
|
-
const compact = message.replace(/\s+/g, " ").trim();
|
|
568
|
-
return compact.length > 500 ? `${compact.slice(0, 500)}...` : compact;
|
|
569
|
-
}
|
|
570
|
-
|
|
571
605
|
// src/sql/SQLMigrations.ts
|
|
572
606
|
var SQLMigrations = class {
|
|
573
607
|
constructor(service, dbName) {
|
|
@@ -983,6 +1017,8 @@ var SQLService = class extends BaseService {
|
|
|
983
1017
|
if (response.status === 413 && parseStorageRejection(errorText)) {
|
|
984
1018
|
return err(storageRejectionError("sql", 413, meta, errorText));
|
|
985
1019
|
}
|
|
1020
|
+
const retryError = nodeRetryError("sql", `SQL ${operation} failed: ${response.status} - ${errorText}`, response, errorText);
|
|
1021
|
+
if (retryError) return err(retryError);
|
|
986
1022
|
const errorBody = parseServiceErrorBody(errorText);
|
|
987
1023
|
const errorCode = this.mapHttpStatusToErrorCode(
|
|
988
1024
|
response.status,
|