@tinycloud/node-sdk 3.3.0-beta.28 → 3.3.0-beta.30
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/index.cjs +51 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +51 -4
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -29045,6 +29045,34 @@ assertSyncEffective_fn = async function() {
|
|
|
29045
29045
|
throw new ReplicaStorageError("GRANT_EXPIRED", "The replica grant's effective lifetime has expired.");
|
|
29046
29046
|
}
|
|
29047
29047
|
};
|
|
29048
|
+
async function listDir(dir) {
|
|
29049
|
+
try {
|
|
29050
|
+
return await readdir(dir);
|
|
29051
|
+
} catch (error) {
|
|
29052
|
+
if (error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR")) {
|
|
29053
|
+
return [];
|
|
29054
|
+
}
|
|
29055
|
+
throw error;
|
|
29056
|
+
}
|
|
29057
|
+
}
|
|
29058
|
+
async function collectProfileOrphans(root, collectOrphans) {
|
|
29059
|
+
for (const partition of await listDir(root)) {
|
|
29060
|
+
const replicasDir = join2(root, partition, "replicas");
|
|
29061
|
+
for (const replicaName of await listDir(replicasDir)) {
|
|
29062
|
+
await collectOrphans(join2(replicasDir, replicaName));
|
|
29063
|
+
}
|
|
29064
|
+
}
|
|
29065
|
+
}
|
|
29066
|
+
async function profileContentBytes(root, contentBytes) {
|
|
29067
|
+
let total = 0;
|
|
29068
|
+
for (const partition of await listDir(root)) {
|
|
29069
|
+
const replicasDir = join2(root, partition, "replicas");
|
|
29070
|
+
for (const replicaName of await listDir(replicasDir)) {
|
|
29071
|
+
total += await contentBytes(join2(replicasDir, replicaName));
|
|
29072
|
+
}
|
|
29073
|
+
}
|
|
29074
|
+
return total;
|
|
29075
|
+
}
|
|
29048
29076
|
function createSqliteReplicaStorage(options) {
|
|
29049
29077
|
const root = options.dir;
|
|
29050
29078
|
const profileDir = dirname2(options.gateFile ?? join2(dirname2(root), REPLICA_GATE_FILE));
|
|
@@ -30039,10 +30067,29 @@ function createSqliteReplicaStorage(options) {
|
|
|
30039
30067
|
const replicaHash = replicaHashOf(spec.prefix, device.did);
|
|
30040
30068
|
partitionId = `${identityKeyHash}:${replicaHash}`;
|
|
30041
30069
|
const replicaDir = join2(idDir, "replicas", replicaHash);
|
|
30042
|
-
const
|
|
30043
|
-
|
|
30044
|
-
|
|
30045
|
-
}
|
|
30070
|
+
const quota = spec.quota?.maxBytes ?? options.maxBytes;
|
|
30071
|
+
if (quota !== void 0 && (!Number.isSafeInteger(quota) || quota < 0)) {
|
|
30072
|
+
throw new TypeError(`maxBytes must be a non-negative safe integer, got ${quota}.`);
|
|
30073
|
+
}
|
|
30074
|
+
if (quota !== void 0) await collectProfileOrphans(root, sqlite.SqliteReplicaStore.collectOrphans);
|
|
30075
|
+
const store = await sqlite.SqliteReplicaStore.open(
|
|
30076
|
+
replicaDir,
|
|
30077
|
+
quota === void 0 ? { create: true, guard: storeGuard } : {
|
|
30078
|
+
create: true,
|
|
30079
|
+
guard: storeGuard,
|
|
30080
|
+
partitionId: basename(idDir),
|
|
30081
|
+
admit: async (page) => {
|
|
30082
|
+
await collectProfileOrphans(root, sqlite.SqliteReplicaStore.collectOrphans);
|
|
30083
|
+
const used = await profileContentBytes(root, sqlite.SqliteReplicaStore.contentBytes);
|
|
30084
|
+
if (page.blobBytes > 0 && used + page.blobBytes > quota) {
|
|
30085
|
+
throw new replica.ReplicaError(
|
|
30086
|
+
replica.ReplicaErrorCode.STORAGE_BUDGET,
|
|
30087
|
+
`Profile storage holds ${used} bytes; this page adds ${page.blobBytes} against a ${quota}-byte quota. Nothing was committed.`
|
|
30088
|
+
);
|
|
30089
|
+
}
|
|
30090
|
+
}
|
|
30091
|
+
}
|
|
30092
|
+
);
|
|
30046
30093
|
let generation;
|
|
30047
30094
|
try {
|
|
30048
30095
|
try {
|