@tinycloud/sdk-services 3.3.0-beta.7 → 3.3.0
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-Cc6Ueicm.d.cts → BaseService-BhfKzKke.d.cts} +5 -1
- package/dist/{BaseService-DOdXd7sr.d.ts → BaseService-x4AFZiEa.d.ts} +5 -1
- package/dist/encryption/index.cjs +18 -5
- 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 +18 -5
- package/dist/encryption/index.js.map +1 -1
- package/dist/index.cjs +911 -797
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +95 -11
- package/dist/index.d.ts +95 -11
- package/dist/index.js +911 -797
- 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 +72 -80
- package/dist/kv/index.cjs.map +1 -1
- package/dist/kv/index.d.cts +4 -5
- package/dist/kv/index.d.ts +4 -5
- package/dist/kv/index.js +72 -80
- package/dist/kv/index.js.map +1 -1
- package/dist/kv/replication/index.cjs +6 -5
- package/dist/kv/replication/index.cjs.map +1 -1
- package/dist/kv/replication/index.d.cts +3 -3
- package/dist/kv/replication/index.d.ts +3 -3
- package/dist/kv/replication/index.js +6 -5
- package/dist/kv/replication/index.js.map +1 -1
- package/dist/{scope-B-m6cKH-.d.ts → scope-BHTkk5Yk.d.ts} +13 -2
- package/dist/{scope-B7oeKdLM.d.cts → scope-DMhalRFn.d.cts} +13 -2
- package/dist/sql/index.cjs +30 -16
- 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 +30 -16
- package/dist/sql/index.js.map +1 -1
- package/dist/{types-BjH0ZtGy.d.cts → types-eVS1Whuf.d.cts} +24 -4
- package/dist/{types-BjH0ZtGy.d.ts → types-eVS1Whuf.d.ts} +24 -4
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { R as Result,
|
|
1
|
+
import { e as RetryStats, R as Result, f as FetchFunction } from './types-eVS1Whuf.js';
|
|
2
2
|
import { REPLICA_KV_STORES } from './kv/replication/contractConstants.js';
|
|
3
3
|
import { ReplicaConsentAnchor, ReplicaGrantPolicy } from './kv/replication/grantPolicyTypes.js';
|
|
4
4
|
|
|
@@ -334,6 +334,8 @@ interface KVResponse<T = unknown> {
|
|
|
334
334
|
* Response headers with metadata.
|
|
335
335
|
*/
|
|
336
336
|
headers: KVResponseHeaders;
|
|
337
|
+
/** Attempts and total backoff for the request behind this response; see `RetryPolicy`. */
|
|
338
|
+
retry?: RetryStats;
|
|
337
339
|
}
|
|
338
340
|
/**
|
|
339
341
|
* Response from KV list operations.
|
|
@@ -1172,7 +1174,12 @@ interface ReplicaQuotaSpec {
|
|
|
1172
1174
|
/** Node/CLI page admission keeps its existing blob/entry interpretation. */
|
|
1173
1175
|
interface ReplicaPageAdmission {
|
|
1174
1176
|
partitionId: string;
|
|
1175
|
-
/**
|
|
1177
|
+
/**
|
|
1178
|
+
* Node/CLI: the page's NET blob bytes, only blob content counted (not the database, WAL, rows or
|
|
1179
|
+
* pending store): new blobs not already stored, minus blobs only replaced or deleted entries
|
|
1180
|
+
* referenced. Negative when the page frees more than it adds; a page with `blobBytes <= 0` is
|
|
1181
|
+
* always admitted. Browser hosts keep their own ledger metric.
|
|
1182
|
+
*/
|
|
1176
1183
|
blobBytes: number;
|
|
1177
1184
|
/** Number of entry writes; not the browser ciphertext-row accounting metric. */
|
|
1178
1185
|
entries: number;
|
|
@@ -1779,6 +1786,10 @@ interface ReplicationOptions {
|
|
|
1779
1786
|
/**
|
|
1780
1787
|
* Replica byte budget; absent means unbounded. Browser: origin-wide across every partition.
|
|
1781
1788
|
* Node/CLI: per profile (per storage dir). Forwarded to storage via `KVReplicaSpec.quota`.
|
|
1789
|
+
* Node/CLI bounds the COMMITTED replica blob content only; the database, WAL, rows and the
|
|
1790
|
+
* pending store are not counted. During a page commit the previous blobs of replaced entries
|
|
1791
|
+
* stay until the commit completes, so on-disk bytes can transiently reach `maxBytes` plus the
|
|
1792
|
+
* bytes that page replaces. Orphaned blobs left by a crash are counted until collected on open.
|
|
1782
1793
|
*/
|
|
1783
1794
|
maxBytes?: number;
|
|
1784
1795
|
/** Browser free-space floor; default DEFAULT_MIN_FREE_BYTES (64 MiB). Ignored on node/CLI. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { R as Result,
|
|
1
|
+
import { e as RetryStats, R as Result, f as FetchFunction } from './types-eVS1Whuf.cjs';
|
|
2
2
|
import { REPLICA_KV_STORES } from './kv/replication/contractConstants.cjs';
|
|
3
3
|
import { ReplicaConsentAnchor, ReplicaGrantPolicy } from './kv/replication/grantPolicyTypes.cjs';
|
|
4
4
|
|
|
@@ -334,6 +334,8 @@ interface KVResponse<T = unknown> {
|
|
|
334
334
|
* Response headers with metadata.
|
|
335
335
|
*/
|
|
336
336
|
headers: KVResponseHeaders;
|
|
337
|
+
/** Attempts and total backoff for the request behind this response; see `RetryPolicy`. */
|
|
338
|
+
retry?: RetryStats;
|
|
337
339
|
}
|
|
338
340
|
/**
|
|
339
341
|
* Response from KV list operations.
|
|
@@ -1172,7 +1174,12 @@ interface ReplicaQuotaSpec {
|
|
|
1172
1174
|
/** Node/CLI page admission keeps its existing blob/entry interpretation. */
|
|
1173
1175
|
interface ReplicaPageAdmission {
|
|
1174
1176
|
partitionId: string;
|
|
1175
|
-
/**
|
|
1177
|
+
/**
|
|
1178
|
+
* Node/CLI: the page's NET blob bytes, only blob content counted (not the database, WAL, rows or
|
|
1179
|
+
* pending store): new blobs not already stored, minus blobs only replaced or deleted entries
|
|
1180
|
+
* referenced. Negative when the page frees more than it adds; a page with `blobBytes <= 0` is
|
|
1181
|
+
* always admitted. Browser hosts keep their own ledger metric.
|
|
1182
|
+
*/
|
|
1176
1183
|
blobBytes: number;
|
|
1177
1184
|
/** Number of entry writes; not the browser ciphertext-row accounting metric. */
|
|
1178
1185
|
entries: number;
|
|
@@ -1779,6 +1786,10 @@ interface ReplicationOptions {
|
|
|
1779
1786
|
/**
|
|
1780
1787
|
* Replica byte budget; absent means unbounded. Browser: origin-wide across every partition.
|
|
1781
1788
|
* Node/CLI: per profile (per storage dir). Forwarded to storage via `KVReplicaSpec.quota`.
|
|
1789
|
+
* Node/CLI bounds the COMMITTED replica blob content only; the database, WAL, rows and the
|
|
1790
|
+
* pending store are not counted. During a page commit the previous blobs of replaced entries
|
|
1791
|
+
* stay until the commit completes, so on-disk bytes can transiently reach `maxBytes` plus the
|
|
1792
|
+
* bytes that page replaces. Orphaned blobs left by a crash are counted until collected on open.
|
|
1782
1793
|
*/
|
|
1783
1794
|
maxBytes?: number;
|
|
1784
1795
|
/** Browser free-space floor; default DEFAULT_MIN_FREE_BYTES (64 MiB). Ignored on node/CLI. */
|
package/dist/sql/index.cjs
CHANGED
|
@@ -45,7 +45,7 @@ var ErrorCodes = {
|
|
|
45
45
|
PERMISSION_DENIED: "PERMISSION_DENIED",
|
|
46
46
|
// Node retry signals (tinycloud-node #347). `meta.retryable` says whether a
|
|
47
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`. */
|
|
48
|
+
/** HTTP 503 `sql_busy:<stage>` / `unavailable_retryable`/`read_audit_busy`: nothing was applied; retry after `meta.retryAfterMs`. */
|
|
49
49
|
NODE_BUSY: "NODE_BUSY",
|
|
50
50
|
/** HTTP 503 `request_timeout`: the node's deadline passed before any write began; nothing was applied. */
|
|
51
51
|
REQUEST_TIMEOUT: "REQUEST_TIMEOUT",
|
|
@@ -86,11 +86,12 @@ var ErrorCodes = {
|
|
|
86
86
|
DUCKDB_READONLY_VIOLATION: "DUCKDB_READONLY_VIOLATION"
|
|
87
87
|
};
|
|
88
88
|
var defaultRetryPolicy = {
|
|
89
|
-
maxAttempts:
|
|
89
|
+
maxAttempts: 4,
|
|
90
90
|
backoff: "exponential",
|
|
91
|
-
baseDelayMs:
|
|
92
|
-
maxDelayMs:
|
|
93
|
-
retryableErrors: [ErrorCodes.
|
|
91
|
+
baseDelayMs: 250,
|
|
92
|
+
maxDelayMs: 4e3,
|
|
93
|
+
retryableErrors: [ErrorCodes.NODE_BUSY, ErrorCodes.REQUEST_TIMEOUT],
|
|
94
|
+
maxTotalMs: 12e3
|
|
94
95
|
};
|
|
95
96
|
var TelemetryEvents = {
|
|
96
97
|
SPAN: "telemetry.span",
|
|
@@ -175,7 +176,7 @@ function nodeRetryError(service, message, response, errorText) {
|
|
|
175
176
|
const body = errorText.trim();
|
|
176
177
|
const [, token, stage] = /^([a-z_]+)(?::\s*([a-z_]+):)?/.exec(body) ?? [];
|
|
177
178
|
let code;
|
|
178
|
-
if (response.status === 503 && (token === "sql_busy" || token === "unavailable_retryable")) {
|
|
179
|
+
if (response.status === 503 && (token === "sql_busy" || token === "unavailable_retryable" || token === "read_audit_busy")) {
|
|
179
180
|
code = ErrorCodes.NODE_BUSY;
|
|
180
181
|
} else if (response.status === 503 && token === "request_timeout") {
|
|
181
182
|
code = ErrorCodes.REQUEST_TIMEOUT;
|
|
@@ -514,6 +515,18 @@ var BaseService = class {
|
|
|
514
515
|
}
|
|
515
516
|
return controller.signal;
|
|
516
517
|
}
|
|
518
|
+
/** POST a signed invocation with retry; `mint` re-signs per attempt, `init.headers` add to the signed ones. */
|
|
519
|
+
invokeWithRetry(url, mint, { headers: extra, ...init } = {}) {
|
|
520
|
+
const build = () => {
|
|
521
|
+
const signed = mint();
|
|
522
|
+
return {
|
|
523
|
+
method: "POST",
|
|
524
|
+
...init,
|
|
525
|
+
headers: Array.isArray(signed) ? [...signed, ...Object.entries(extra ?? {})] : { ...signed, ...extra }
|
|
526
|
+
};
|
|
527
|
+
};
|
|
528
|
+
return this.context.invokeWithRetry ? this.context.invokeWithRetry(url, build) : this.context.fetch(url, build());
|
|
529
|
+
}
|
|
517
530
|
/**
|
|
518
531
|
* Create the abort signal for one request, bounded by the request timeout.
|
|
519
532
|
*
|
|
@@ -965,18 +978,19 @@ var SQLService = class extends BaseService {
|
|
|
965
978
|
}
|
|
966
979
|
// === Private helpers ===
|
|
967
980
|
async invokeSQL(dbName, actions, body, signal) {
|
|
968
|
-
const session = this.context.session;
|
|
969
981
|
const actionList = Array.isArray(actions) ? actions : [actions];
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
"Content-Type": "application/json"
|
|
982
|
+
return this.invokeWithRetry(
|
|
983
|
+
`${this.host}/invoke`,
|
|
984
|
+
() => {
|
|
985
|
+
const session = this.context.session;
|
|
986
|
+
return actionList.length === 1 ? this.context.invoke(session, "sql", dbName, actionList[0]) : this.invokeSQLAny(session, dbName, actionList);
|
|
976
987
|
},
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
988
|
+
{
|
|
989
|
+
headers: { "Content-Type": "application/json" },
|
|
990
|
+
body: JSON.stringify(body),
|
|
991
|
+
signal
|
|
992
|
+
}
|
|
993
|
+
);
|
|
980
994
|
}
|
|
981
995
|
actionForSql(sql, fallback) {
|
|
982
996
|
const token = firstSqlToken(sql);
|