@tinycloud/sdk-services 3.2.0-beta.3 → 3.2.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-BDQXjWMx.d.cts → BaseService-4wwJq1Gn.d.cts} +1 -1
- package/dist/{BaseService-Di_hVfUV.d.ts → BaseService-BGr2slUz.d.ts} +1 -1
- package/dist/encryption/index.cjs +5 -1
- 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 +5 -1
- package/dist/encryption/index.js.map +1 -1
- package/dist/index.cjs +190 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +157 -6
- package/dist/index.d.ts +157 -6
- package/dist/index.js +184 -11
- 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 +56 -11
- package/dist/kv/index.cjs.map +1 -1
- package/dist/kv/index.d.cts +5 -4
- package/dist/kv/index.d.ts +5 -4
- package/dist/kv/index.js +56 -11
- package/dist/kv/index.js.map +1 -1
- package/dist/kv/replication/index.cjs +44 -19
- package/dist/kv/replication/index.cjs.map +1 -1
- package/dist/kv/replication/index.d.cts +4 -3
- package/dist/kv/replication/index.d.ts +4 -3
- package/dist/kv/replication/index.js +44 -19
- package/dist/kv/replication/index.js.map +1 -1
- package/dist/kv/replication/prefix.cjs +43 -0
- package/dist/kv/replication/prefix.cjs.map +1 -0
- package/dist/kv/replication/prefix.d.cts +6 -0
- package/dist/kv/replication/prefix.d.ts +6 -0
- package/dist/kv/replication/prefix.js +17 -0
- package/dist/kv/replication/prefix.js.map +1 -0
- package/dist/{scope-BmLxwyl-.d.ts → scope-CoKKmMiI.d.ts} +5 -5
- package/dist/{scope-D855kRDx.d.cts → scope-D7wmjbMH.d.cts} +5 -5
- package/dist/sql/index.cjs +44 -2
- 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 +44 -2
- package/dist/sql/index.js.map +1 -1
- package/dist/{types-7A5rHWRY.d.cts → types-D-9A3Sut.d.cts} +6 -0
- package/dist/{types-7A5rHWRY.d.ts → types-D-9A3Sut.d.ts} +6 -0
- package/package.json +14 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { K as KVReplicationDeps, a as KVReplicationController, R as ReplicationIdentity, P as PendingWriteStore } from '../../scope-
|
|
2
|
-
export { A as AuthorityRefusal, C as CLEAR_PENDING_WARNING, b as KVListPage, c as KVReadThrough, d as KVReplicaHandle, e as KVReplicaSpec, f as KVReplicaStorage, L as LocalGetResult, g as LocalListResult, h as LocalReadMeta, i as LocalReplicaStatus, j as LocalSyncResult, k as PendingWriteRecord, l as PendingWriteState, 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, x as ReplicationOptions, y as ReplicationPurgeReport, z as ReplicationReason, B as ReplicationScheduler, D as ResolvedReplicationOptions, E as canonicalReplicationIdentity, F as
|
|
3
|
-
|
|
1
|
+
import { K as KVReplicationDeps, a as KVReplicationController, R as ReplicationIdentity, P as PendingWriteStore } from '../../scope-D7wmjbMH.cjs';
|
|
2
|
+
export { A as AuthorityRefusal, C as CLEAR_PENDING_WARNING, b as KVListPage, c as KVReadThrough, d as KVReplicaHandle, e as KVReplicaSpec, f as KVReplicaStorage, L as LocalGetResult, g as LocalListResult, h as LocalReadMeta, i as LocalReplicaStatus, j as LocalSyncResult, k as PendingWriteRecord, l as PendingWriteState, 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, 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';
|
|
3
|
+
export { kvPrefixCovers } from './prefix.cjs';
|
|
4
|
+
import '../../types-D-9A3Sut.cjs';
|
|
4
5
|
|
|
5
6
|
declare function createKVReplication(deps: KVReplicationDeps): KVReplicationController;
|
|
6
7
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { K as KVReplicationDeps, a as KVReplicationController, R as ReplicationIdentity, P as PendingWriteStore } from '../../scope-
|
|
2
|
-
export { A as AuthorityRefusal, C as CLEAR_PENDING_WARNING, b as KVListPage, c as KVReadThrough, d as KVReplicaHandle, e as KVReplicaSpec, f as KVReplicaStorage, L as LocalGetResult, g as LocalListResult, h as LocalReadMeta, i as LocalReplicaStatus, j as LocalSyncResult, k as PendingWriteRecord, l as PendingWriteState, 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, x as ReplicationOptions, y as ReplicationPurgeReport, z as ReplicationReason, B as ReplicationScheduler, D as ResolvedReplicationOptions, E as canonicalReplicationIdentity, F as
|
|
3
|
-
|
|
1
|
+
import { K as KVReplicationDeps, a as KVReplicationController, R as ReplicationIdentity, P as PendingWriteStore } from '../../scope-CoKKmMiI.js';
|
|
2
|
+
export { A as AuthorityRefusal, C as CLEAR_PENDING_WARNING, b as KVListPage, c as KVReadThrough, d as KVReplicaHandle, e as KVReplicaSpec, f as KVReplicaStorage, L as LocalGetResult, g as LocalListResult, h as LocalReadMeta, i as LocalReplicaStatus, j as LocalSyncResult, k as PendingWriteRecord, l as PendingWriteState, 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, 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';
|
|
3
|
+
export { kvPrefixCovers } from './prefix.js';
|
|
4
|
+
import '../../types-D-9A3Sut.js';
|
|
4
5
|
|
|
5
6
|
declare function createKVReplication(deps: KVReplicationDeps): KVReplicationController;
|
|
6
7
|
|
|
@@ -45,16 +45,17 @@ ${canonical.space}
|
|
|
45
45
|
${canonical.principal}`;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
// src/kv/replication/
|
|
48
|
+
// src/kv/replication/prefix.ts
|
|
49
49
|
function kvPrefixCovers(prefix, key) {
|
|
50
|
-
|
|
51
|
-
if (prefix.endsWith("/")) return key.startsWith(prefix);
|
|
52
|
-
return key === prefix || key.startsWith(`${prefix}/`);
|
|
50
|
+
return prefix === "/" || key.startsWith(prefix);
|
|
53
51
|
}
|
|
52
|
+
|
|
53
|
+
// src/kv/replication/scope.ts
|
|
54
54
|
function listRangeCovers(path, key) {
|
|
55
|
-
return key === path || key.startsWith(path.endsWith("/") ? path : `${path}/`);
|
|
55
|
+
return path === "" || key === path || key.startsWith(path.endsWith("/") ? path : `${path}/`);
|
|
56
56
|
}
|
|
57
57
|
function requiresSecretsOptIn(space, prefix) {
|
|
58
|
+
if (prefix === "/") return true;
|
|
58
59
|
if (space === "secrets" || space.endsWith(":secrets")) return true;
|
|
59
60
|
return prefix.split("/", 1)[0] === "vault";
|
|
60
61
|
}
|
|
@@ -100,6 +101,8 @@ var ErrorCodes = {
|
|
|
100
101
|
// Storage quota errors
|
|
101
102
|
STORAGE_QUOTA_EXCEEDED: "STORAGE_QUOTA_EXCEEDED",
|
|
102
103
|
STORAGE_LIMIT_REACHED: "STORAGE_LIMIT_REACHED",
|
|
104
|
+
/** The node answered the usage read without usage numbers (it predates the read). */
|
|
105
|
+
STORAGE_STATUS_UNAVAILABLE: "STORAGE_STATUS_UNAVAILABLE",
|
|
103
106
|
// DuckDB-specific errors
|
|
104
107
|
DUCKDB_ERROR: "DUCKDB_ERROR",
|
|
105
108
|
DUCKDB_PERMISSION_DENIED: "DUCKDB_PERMISSION_DENIED",
|
|
@@ -339,9 +342,9 @@ function cursorRestart() {
|
|
|
339
342
|
}
|
|
340
343
|
function localList(handle, space, path, limit, cursor, validateMeta) {
|
|
341
344
|
const after = cursor ? decodeTcr1(cursor)?.last : void 0;
|
|
342
|
-
const exact = !path.endsWith("/") && (after === void 0 || utf8Compare(path, after) > 0) ? awaitExact(handle, path, after, validateMeta) : Promise.resolve(false);
|
|
345
|
+
const exact = path !== "" && !path.endsWith("/") && (after === void 0 || utf8Compare(path, after) > 0) ? awaitExact(handle, path, after, validateMeta) : Promise.resolve(false);
|
|
343
346
|
return exact.then(async (hasExact) => {
|
|
344
|
-
const child = path.endsWith("/") ? path : `${path}/`;
|
|
347
|
+
const child = path === "" ? "" : path.endsWith("/") ? path : `${path}/`;
|
|
345
348
|
const want = limit === void 0 ? void 0 : limit + 1 - (hasExact ? 1 : 0);
|
|
346
349
|
const children = await handle.list({ prefix: child, after, limit: want });
|
|
347
350
|
validateMeta(children.meta);
|
|
@@ -358,9 +361,7 @@ async function awaitExact(handle, path, after, validateMeta) {
|
|
|
358
361
|
return result.keys[0] === path;
|
|
359
362
|
}
|
|
360
363
|
function listPathCovered(prefixes, path) {
|
|
361
|
-
|
|
362
|
-
const covering = prefixes.filter((prefix) => kvPrefixCovers(prefix, path) && kvPrefixCovers(prefix, descendant));
|
|
363
|
-
return covering.length === 1 ? covering[0] : void 0;
|
|
364
|
+
return prefixes.find((prefix) => kvPrefixCovers(prefix, path));
|
|
364
365
|
}
|
|
365
366
|
|
|
366
367
|
// src/kv/replication/events.ts
|
|
@@ -389,6 +390,7 @@ function raceSignal(job, signal) {
|
|
|
389
390
|
}
|
|
390
391
|
function createKVReplication(deps) {
|
|
391
392
|
const { options, mode, storage, identity, session, authority, pending, scheduler } = deps;
|
|
393
|
+
const emit = (event) => emitEvent(deps.emit, scheduler, event);
|
|
392
394
|
const replicas = /* @__PURE__ */ new Map();
|
|
393
395
|
const statusInspections = /* @__PURE__ */ new Set();
|
|
394
396
|
let isClosed = false;
|
|
@@ -397,7 +399,6 @@ function createKVReplication(deps) {
|
|
|
397
399
|
let previous = deps.previous;
|
|
398
400
|
let pinnedStateReported = false;
|
|
399
401
|
const inProcessProof = /* @__PURE__ */ new Set();
|
|
400
|
-
const emit = (event) => emitEvent(deps.emit, scheduler, event);
|
|
401
402
|
const configuredPrefix = (path) => options.prefixes.find((prefix) => kvPrefixCovers(prefix, path));
|
|
402
403
|
function recordRevocation(prefix, error) {
|
|
403
404
|
if (errorCode(error) !== "GRANT_REVOKED") return;
|
|
@@ -407,6 +408,20 @@ function createKVReplication(deps) {
|
|
|
407
408
|
state.lastError = "GRANT_REVOKED";
|
|
408
409
|
replicas.set(prefix, state);
|
|
409
410
|
}
|
|
411
|
+
function markRootUnsupported(prefix) {
|
|
412
|
+
const state = replicas.get(prefix) ?? {};
|
|
413
|
+
const firstRefusal = state.lastError !== "REPLICATION_ROOT_UNSUPPORTED";
|
|
414
|
+
state.reason = "replica_unavailable";
|
|
415
|
+
state.lastError = "REPLICATION_ROOT_UNSUPPORTED";
|
|
416
|
+
replicas.set(prefix, state);
|
|
417
|
+
if (firstRefusal) {
|
|
418
|
+
emit({ type: "replication.state", space: session.space, replica: prefix, state: "unavailable", code: "REPLICATION_ROOT_UNSUPPORTED" });
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
function unsupportedRoot(prefix) {
|
|
422
|
+
markRootUnsupported(prefix);
|
|
423
|
+
return Object.assign(new Error("This node doesn't support whole-space sync yet."), { code: "REPLICATION_ROOT_UNSUPPORTED" });
|
|
424
|
+
}
|
|
410
425
|
async function open(prefix) {
|
|
411
426
|
if (isClosed || purgeStarted) throw Object.assign(new Error("Replication controller is closed"), { code: "REPLICA_CLOSED" });
|
|
412
427
|
let state = replicas.get(prefix);
|
|
@@ -440,6 +455,9 @@ function createKVReplication(deps) {
|
|
|
440
455
|
state.strategy = "session";
|
|
441
456
|
}
|
|
442
457
|
const spec = { identity, space: session.space, prefix, allowSecrets: options.allowSecrets, ...device ? { device } : {}, ...deps.fetch ? { fetch: deps.fetch } : {} };
|
|
458
|
+
if (prefix === "/" && deps.nodeFeatures !== void 0 && !deps.nodeFeatures.includes("kv-sync-root")) {
|
|
459
|
+
throw unsupportedRoot(prefix);
|
|
460
|
+
}
|
|
443
461
|
const handle = await storage.open(spec);
|
|
444
462
|
state.handle = handle;
|
|
445
463
|
emit({ type: "replication.state", space: session.space, replica: prefix, state: "opened" });
|
|
@@ -489,7 +507,7 @@ function createKVReplication(deps) {
|
|
|
489
507
|
state.lastError = code;
|
|
490
508
|
state.failures = (state.failures ?? 0) + 1;
|
|
491
509
|
if (code === "RUNTIME_UNSUPPORTED") state.unsupported = true;
|
|
492
|
-
else if (code !== "REPLICA_CLOSED") state.retryAt = scheduler.now() + Math.min(3e5, 5e3 * 2 ** Math.min(state.failures - 1, 6));
|
|
510
|
+
else if (code !== "REPLICA_CLOSED" && code !== "REPLICATION_ROOT_UNSUPPORTED") state.retryAt = scheduler.now() + Math.min(3e5, 5e3 * 2 ** Math.min(state.failures - 1, 6));
|
|
493
511
|
state.handle?.close().catch(() => void 0);
|
|
494
512
|
state.handle = void 0;
|
|
495
513
|
throw error;
|
|
@@ -506,6 +524,9 @@ function createKVReplication(deps) {
|
|
|
506
524
|
}, options.syncIntervalMs);
|
|
507
525
|
}
|
|
508
526
|
async function syncPrefix(prefix, trigger, signal, context) {
|
|
527
|
+
if (prefix === "/" && deps.nodeFeatures !== void 0 && !deps.nodeFeatures.includes("kv-sync-root")) {
|
|
528
|
+
throw unsupportedRoot(prefix);
|
|
529
|
+
}
|
|
509
530
|
const handle = await open(prefix);
|
|
510
531
|
const state = replicas.get(prefix);
|
|
511
532
|
if (state.sync) return state.sync;
|
|
@@ -807,7 +828,7 @@ function createKVReplication(deps) {
|
|
|
807
828
|
observeNetworkRequested({ op: "get", space: r.space, path: r.path, reason: "NETWORK_REQUESTED", outcome, latencyMs: scheduler.now() - started });
|
|
808
829
|
}
|
|
809
830
|
}
|
|
810
|
-
if (
|
|
831
|
+
if (prefix === void 0) {
|
|
811
832
|
const value = await r.network();
|
|
812
833
|
readEvent("get", r.path, null, "network", "not_covered", value.ok ? "found" : value.error.code === ErrorCodes.KV_NOT_FOUND ? "not_found" : "error", started);
|
|
813
834
|
return value;
|
|
@@ -958,10 +979,10 @@ function createKVReplication(deps) {
|
|
|
958
979
|
return cursorRestart();
|
|
959
980
|
};
|
|
960
981
|
if (cursor && decoded && (decoded.space !== r.space || decoded.path !== r.listPath)) return restart();
|
|
961
|
-
if (
|
|
982
|
+
if (prefix === void 0 || r.options?.raw) {
|
|
962
983
|
if (cursor && decoded) return restart();
|
|
963
984
|
const result = await r.network();
|
|
964
|
-
readEvent("list", r.listPath, prefix ?? null, "network", prefix ? "unsupported_option" : "not_covered", result.ok ? "found" : "error", started);
|
|
985
|
+
readEvent("list", r.listPath, prefix ?? null, "network", prefix !== void 0 ? "unsupported_option" : "not_covered", result.ok ? "found" : "error", started);
|
|
965
986
|
return result;
|
|
966
987
|
}
|
|
967
988
|
let handle;
|
|
@@ -1056,7 +1077,7 @@ function createKVReplication(deps) {
|
|
|
1056
1077
|
async function write(r) {
|
|
1057
1078
|
const covered = r.entries.flatMap((entry) => {
|
|
1058
1079
|
const prefix = configuredPrefix(entry.path);
|
|
1059
|
-
return prefix ? [{ key: entry.path, op: r.op === "delete" ? "delete" : "put" }] : [];
|
|
1080
|
+
return prefix !== void 0 ? [{ key: entry.path, op: r.op === "delete" ? "delete" : "put" }] : [];
|
|
1060
1081
|
});
|
|
1061
1082
|
if (covered.length === 0) return r.network();
|
|
1062
1083
|
await reportExistingPins();
|
|
@@ -1132,6 +1153,9 @@ function createKVReplication(deps) {
|
|
|
1132
1153
|
const persistedSnapshot = pending.readExisting ? await pending.readExisting() : await pending.read();
|
|
1133
1154
|
const snapshot = persistedSnapshot ?? emptyPendingState(identity);
|
|
1134
1155
|
const entries = await Promise.all(options.prefixes.map(async (prefix) => {
|
|
1156
|
+
if (prefix === "/" && deps.nodeFeatures !== void 0 && !deps.nodeFeatures.includes("kv-sync-root")) {
|
|
1157
|
+
markRootUnsupported(prefix);
|
|
1158
|
+
}
|
|
1135
1159
|
const records = snapshot.records.filter((r) => kvPrefixCovers(prefix, r.key));
|
|
1136
1160
|
const opened = replicas.get(prefix);
|
|
1137
1161
|
let local;
|
|
@@ -1146,12 +1170,13 @@ function createKVReplication(deps) {
|
|
|
1146
1170
|
local ?? (local = inspected.local);
|
|
1147
1171
|
if (inspected.missing && !opened?.reason && !opened?.authorityRevoked && !opened?.opening && !isClosed) return void 0;
|
|
1148
1172
|
const revoked = opened?.authorityRevoked === true || local?.authority.state === "revoked";
|
|
1149
|
-
const
|
|
1173
|
+
const rootUnsupported = opened?.lastError === "REPLICATION_ROOT_UNSUPPORTED";
|
|
1174
|
+
const state = isClosed ? "closed" : revoked ? "revoked" : rootUnsupported ? "unavailable" : opened?.reason === "grant_missing" ? "grant_missing" : local?.coverage === "complete" && local.authority.state === "valid" ? "ready" : opened?.reason || inspected.errorCode ? "unavailable" : "idle";
|
|
1150
1175
|
return {
|
|
1151
1176
|
prefix,
|
|
1152
1177
|
state,
|
|
1153
1178
|
...opened?.reason ? { reason: opened.reason } : inspected.errorCode ? { reason: "replica_unavailable" } : {},
|
|
1154
|
-
...inspected.errorCode ? { errorCode: inspected.errorCode } : {},
|
|
1179
|
+
...inspected.errorCode ?? opened?.lastError ? { errorCode: inspected.errorCode ?? opened?.lastError } : {},
|
|
1155
1180
|
...local ?? {},
|
|
1156
1181
|
...revoked ? { authority: { state: "revoked", expiresAt: local?.authority.expiresAt ?? null } } : {},
|
|
1157
1182
|
pending: {
|
|
@@ -1166,7 +1191,7 @@ function createKVReplication(deps) {
|
|
|
1166
1191
|
return entries.filter((entry) => entry !== void 0);
|
|
1167
1192
|
}
|
|
1168
1193
|
async function sync(o) {
|
|
1169
|
-
const prefixes = o?.prefix ? options.prefixes.filter((p) => p === o.prefix) : options.prefixes;
|
|
1194
|
+
const prefixes = o?.prefix !== void 0 ? options.prefixes.filter((p) => p === o.prefix) : options.prefixes;
|
|
1170
1195
|
await Promise.all(prefixes.map((prefix) => syncPrefix(prefix, "manual", o?.signal).then(() => void 0)));
|
|
1171
1196
|
}
|
|
1172
1197
|
async function clearPending2() {
|