@quantiya/codevibe-core 2.0.74 → 2.0.76
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/appsync/sync-operation-journal.d.ts +2 -1
- package/dist/index.js +435 -435
- package/dist/orchestration-shell/cli.js +33 -26
- package/package.json +1 -1
|
@@ -8605,15 +8605,9 @@ function parseCompanionSyncState(value, environment, now = Date.now()) {
|
|
|
8605
8605
|
let date = new Date(value.observedAtEpochMs), resetAt = Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + 1, 1);
|
|
8606
8606
|
(value.periodId !== date.toISOString().slice(0, 7) || value.resetAtEpochMs !== resetAt || value.validUntilEpochMs > resetAt) && invalid2(), count(value.usage.usageRevision);
|
|
8607
8607
|
let gap2 = count(value.usage.gapStartedAtEpochMs), periodStart = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), 1);
|
|
8608
|
-
gap2 !== 0n && (gap2 < BigInt(periodStart) || gap2 > BigInt(value.observedAtEpochMs)) && invalid2();
|
|
8609
|
-
let
|
|
8610
|
-
|
|
8611
|
-
let committed = count(value.usage[`${meter}Committed`]);
|
|
8612
|
-
count(value.usage[`${meter}Reserved`]);
|
|
8613
|
-
let limit = count(value.usage[`${meter}Limit`]), pausedAtLimit = count(value.usage[`${meter}PauseLimit`]);
|
|
8614
|
-
pausedAtLimit > 0n && gap2 === 0n && invalid2(), value.usage[`${meter}Limit`] !== value.limits[meter] && invalid2(), meter === "syncUnits" && (committed >= limit || pausedAtLimit >= limit) ? state = "PAUSED" : committed * 5n >= limit * 4n && state !== "PAUSED" && (state = "WARNING");
|
|
8615
|
-
}
|
|
8616
|
-
value.usage.syncState !== state && invalid2();
|
|
8608
|
+
gap2 !== 0n && (gap2 < BigInt(periodStart) || gap2 > BigInt(value.observedAtEpochMs)) && invalid2(), ["ACTIVE", "WARNING", "PAUSED"].includes(value.usage.syncState) || invalid2();
|
|
8609
|
+
for (let meter of METERS)
|
|
8610
|
+
count(value.usage[`${meter}Committed`]), count(value.usage[`${meter}Reserved`]), count(value.usage[`${meter}Limit`]), count(value.usage[`${meter}PauseLimit`]) > 0n && gap2 === 0n && invalid2(), value.usage[`${meter}Limit`] !== value.limits[meter] && invalid2();
|
|
8617
8611
|
} else (value.protocol === "SYNC_V2" && value.mode !== "SHADOW" || value.mode === "ROLLBACK_FREEZE" && value.protocol !== "FROZEN" || value.usage !== null || value.periodId !== null || value.resetAtEpochMs !== null) && invalid2();
|
|
8618
8612
|
if (value.accountingGeneration === null && (value.mode !== "LEGACY" || value.controlGeneration !== 0) && invalid2(), value.accountingGeneration !== null && value.controlGeneration < 1 && invalid2(), value.usage?.syncState === "PAUSED") {
|
|
8619
8613
|
let notice2 = value.quotaNotice;
|
|
@@ -10300,7 +10294,7 @@ var SyncJournalError = class extends Error {
|
|
|
10300
10294
|
this.code = code;
|
|
10301
10295
|
this.name = "SyncJournalError";
|
|
10302
10296
|
}
|
|
10303
|
-
}, UUID8 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i, MAX_RECORD_BYTES = 1024 * 1024, MAX_ENVELOPE_BYTES = 2 * MAX_RECORD_BYTES, MAX_FILES = 256, MAX_STORE_BYTES = 32 * 1024 * 1024, MAX_RETIREMENT_INTENTS = 16, MAX_RETIREMENT_BYTES = 32 * 1024, invalid7 = () => {
|
|
10297
|
+
}, UUID8 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i, MAX_RECORD_BYTES = 1024 * 1024, MAX_ENVELOPE_BYTES = 2 * MAX_RECORD_BYTES, MAX_FILES = 256, MAX_STORE_BYTES = 32 * 1024 * 1024, MAX_RETIREMENT_INTENTS = 16, MAX_RETIREMENT_BYTES = 32 * 1024, MAX_INVENTORY_FILES = MAX_FILES * 4 + MAX_RETIREMENT_INTENTS * 2 + 8, MAX_DIRECTORY_ENTRIES = MAX_INVENTORY_FILES * 4 + MAX_FILES + MAX_RETIREMENT_INTENTS * 2 + 8, invalid7 = () => {
|
|
10304
10298
|
throw new SyncJournalError("SYNC_JOURNAL_INVALID");
|
|
10305
10299
|
}, errorCode = (error) => error?.code;
|
|
10306
10300
|
function operationId(value) {
|
|
@@ -10493,7 +10487,7 @@ var sourceCursorId = (scope, stream) => stableUuid("codevibe-sync-source-cursor-
|
|
|
10493
10487
|
}) : (this.options.assertAccount(), []);
|
|
10494
10488
|
}
|
|
10495
10489
|
/** One encrypted intent/credential record per original desktop incarnation.
|
|
10496
|
-
*
|
|
10490
|
+
* Bookkeeping shares the 32-MiB bound, but not outbound-operation slots. */
|
|
10497
10491
|
desktopRegistration(register, now = Date.now) {
|
|
10498
10492
|
let scope = this.sessionScope;
|
|
10499
10493
|
if (!scope || typeof register != "function") return invalid7();
|
|
@@ -11129,6 +11123,14 @@ var sourceCursorId = (scope, stream) => stableUuid("codevibe-sync-source-cursor-
|
|
|
11129
11123
|
let plan = await this.withStore((key) => this.retiredSourcePlan(key, input.expectedSessionKeyGen));
|
|
11130
11124
|
if (!plan.sources.length) return { sourcesRemoved: 0, operationsRemoved: 0 };
|
|
11131
11125
|
parseSyncSessionRetirementReceipt(await confirm(input), input), this.options.assertAccount();
|
|
11126
|
+
let total = { sourcesRemoved: 0, operationsRemoved: 0 };
|
|
11127
|
+
for (let page = 0; page < MAX_INVENTORY_FILES; page++) {
|
|
11128
|
+
let removed = await this.removeRetiredSourceBatch(plan, input.expectedSessionKeyGen);
|
|
11129
|
+
if (total.sourcesRemoved += removed.sourcesRemoved, total.operationsRemoved += removed.operationsRemoved, plan = await this.withStore((key) => this.retiredSourcePlan(key, input.expectedSessionKeyGen)), !plan.sources.length) return total;
|
|
11130
|
+
}
|
|
11131
|
+
throw new SyncJournalError("SYNC_OPERATION_PENDING");
|
|
11132
|
+
}
|
|
11133
|
+
async removeRetiredSourceBatch(plan, expectedSessionKeyGen) {
|
|
11132
11134
|
let owners = [], fence = async () => {
|
|
11133
11135
|
this.options.assertAccount();
|
|
11134
11136
|
for (let owner of owners) if (!await owner.reassertOwnership()) throw new SyncJournalError("SYNC_JOURNAL_LOCK_LOST");
|
|
@@ -11143,7 +11145,7 @@ var sourceCursorId = (scope, stream) => stableUuid("codevibe-sync-source-cursor-
|
|
|
11143
11145
|
if (owners.push(owner), this.options.assertAccount(), !await owner.reassertOwnership()) throw new SyncJournalError("SYNC_JOURNAL_LOCK_LOST");
|
|
11144
11146
|
}
|
|
11145
11147
|
return await this.withStore(async (key, storeFence) => {
|
|
11146
|
-
let current = await this.retiredSourcePlan(key,
|
|
11148
|
+
let current = await this.retiredSourcePlan(key, expectedSessionKeyGen);
|
|
11147
11149
|
if (current.digest !== plan.digest) throw new SyncJournalError("SYNC_OPERATION_PENDING");
|
|
11148
11150
|
await fence();
|
|
11149
11151
|
for (let name of current.operations)
|
|
@@ -11202,15 +11204,20 @@ var sourceCursorId = (scope, stream) => stableUuid("codevibe-sync-source-cursor-
|
|
|
11202
11204
|
}
|
|
11203
11205
|
async retiredSourcePlan(key, expectedSessionKeyGen) {
|
|
11204
11206
|
if (!this.sessionScope) return invalid7();
|
|
11205
|
-
let sources = [], operations = [], images = [], linked = /* @__PURE__ */ new Set(), outer = /* @__PURE__ */ new Set(), inner = /* @__PURE__ */ new Set(), expectedInputs = /* @__PURE__ */ new Map(), bind = (value) => {
|
|
11207
|
+
let sources = [], operations = [], images = [], linked = /* @__PURE__ */ new Set(), outer = /* @__PURE__ */ new Set(), inner = /* @__PURE__ */ new Set(), selectedLinks = /* @__PURE__ */ new Set(), sourceCount = 0, linkedOperationCount = 0, expectedInputs = /* @__PURE__ */ new Map(), bind = (value) => {
|
|
11206
11208
|
let input = request2("CREATE_EVENT", value), digest2 = fingerprint("CREATE_EVENT", input), prior = expectedInputs.get(input.clientOperationId);
|
|
11207
11209
|
if (prior !== void 0 && prior !== digest2) return invalid7();
|
|
11208
11210
|
expectedInputs.set(input.clientOperationId, digest2);
|
|
11209
11211
|
}, add = (name, row3, links, locks, innerLocks = []) => {
|
|
11210
|
-
if (this.matchesScope(row3))
|
|
11211
|
-
|
|
11212
|
-
|
|
11213
|
-
|
|
11212
|
+
if (!this.matchesScope(row3)) return;
|
|
11213
|
+
sourceCount++, images.push([name, row3]);
|
|
11214
|
+
for (let id5 of links) linked.add(id5);
|
|
11215
|
+
if (sourceCount > MAX_INVENTORY_FILES || linked.size > MAX_INVENTORY_FILES * MAX_FILES)
|
|
11216
|
+
throw new SyncJournalError("SYNC_JOURNAL_FULL");
|
|
11217
|
+
let additionalLinks = links.filter((id5) => !selectedLinks.has(id5));
|
|
11218
|
+
if (!(sources.length >= MAX_FILES || selectedLinks.size + additionalLinks.length > MAX_FILES)) {
|
|
11219
|
+
sources.push(name);
|
|
11220
|
+
for (let id5 of links) selectedLinks.add(id5);
|
|
11214
11221
|
for (let lock of locks) outer.add(lock);
|
|
11215
11222
|
for (let lock of innerLocks) inner.add(lock);
|
|
11216
11223
|
}
|
|
@@ -11261,16 +11268,16 @@ var sourceCursorId = (scope, stream) => stableUuid("codevibe-sync-source-cursor-
|
|
|
11261
11268
|
let row3 = await this.read(id5, key);
|
|
11262
11269
|
if (row3) {
|
|
11263
11270
|
if (this.requireScope(row3), row3.action !== "CREATE_EVENT" || row3.state === "PENDING" && row3.input.expectedSessionKeyGen !== expectedSessionKeyGen || expectedInputs.has(id5) && expectedInputs.get(id5) !== row3.fingerprint) return invalid7();
|
|
11264
|
-
|
|
11271
|
+
linkedOperationCount++, images.push([id5 + ".json", row3]), selectedLinks.has(id5) && operations.push(id5 + ".json");
|
|
11265
11272
|
}
|
|
11266
11273
|
}
|
|
11267
|
-
if (
|
|
11274
|
+
if (linkedOperationCount > MAX_FILES) throw new SyncJournalError("SYNC_JOURNAL_FULL");
|
|
11268
11275
|
return {
|
|
11269
11276
|
sources: sources.sort(),
|
|
11270
11277
|
operations,
|
|
11271
11278
|
// Even a missing operation may retain its dead sender/GC lock after an
|
|
11272
11279
|
// interrupted unlink. The source's complete link set owns reclamation.
|
|
11273
|
-
locks: [...[...outer].sort(), ...[...inner].sort(), ...[...
|
|
11280
|
+
locks: [...[...outer].sort(), ...[...inner].sort(), ...[...selectedLinks].sort().map((id5) => `send-${id5}.lockdir`)],
|
|
11274
11281
|
digest: (0, import_node_crypto14.createHash)("sha256").update((0, import_json_freeze12.canonicalize)(images)).digest("hex")
|
|
11275
11282
|
};
|
|
11276
11283
|
}
|
|
@@ -11529,21 +11536,21 @@ var sourceCursorId = (scope, stream) => stableUuid("codevibe-sync-source-cursor-
|
|
|
11529
11536
|
async recordNames(suffix = ".json") {
|
|
11530
11537
|
let names = [], entries = 0, directory = await import_node_fs5.promises.opendir(this.directory);
|
|
11531
11538
|
for await (let entry5 of directory) {
|
|
11532
|
-
if (++entries >
|
|
11533
|
-
if (entry5.name.endsWith(suffix) && ((!entry5.isFile() || !UUID8.test(entry5.name.slice(0, -suffix.length))) && invalid7(), names.push(entry5.name), names.length > MAX_FILES))
|
|
11539
|
+
if (++entries > MAX_DIRECTORY_ENTRIES) throw new SyncJournalError("SYNC_JOURNAL_FULL");
|
|
11540
|
+
if (entry5.name.endsWith(suffix) && ((!entry5.isFile() || !UUID8.test(entry5.name.slice(0, -suffix.length))) && invalid7(), names.push(entry5.name), names.length > (suffix === ".json" ? MAX_FILES : MAX_INVENTORY_FILES)))
|
|
11534
11541
|
throw new SyncJournalError("SYNC_JOURNAL_FULL");
|
|
11535
11542
|
}
|
|
11536
11543
|
return names;
|
|
11537
11544
|
}
|
|
11538
11545
|
async checkCapacity(additionalBytes, replacedName, retirement = !1) {
|
|
11539
|
-
let
|
|
11546
|
+
let operations = 0, bookkeeping = 0, bytes = additionalBytes, entries = 0, retirements = 0, allocatesOperation = replacedName === void 0 || replacedName.endsWith(".json"), directory = await import_node_fs5.promises.opendir(this.directory);
|
|
11540
11547
|
for await (let entry5 of directory)
|
|
11541
|
-
if ((++entries >
|
|
11548
|
+
if ((++entries > MAX_DIRECTORY_ENTRIES || entry5.isSymbolicLink()) && invalid7(), entry5.isFile()) {
|
|
11542
11549
|
let stat13 = await import_node_fs5.promises.lstat(path18.join(this.directory, entry5.name));
|
|
11543
11550
|
if ((!stat13.isFile() || stat13.nlink !== 1) && invalid7(), entry5.name === replacedName) continue;
|
|
11544
|
-
entry5.name.endsWith(".retirement")
|
|
11551
|
+
bytes += stat13.size, entry5.name.endsWith(".json") ? operations++ : entry5.name.endsWith(".retirement") ? retirements++ : bookkeeping++;
|
|
11545
11552
|
}
|
|
11546
|
-
if (
|
|
11553
|
+
if (allocatesOperation && operations >= MAX_FILES || !allocatesOperation && !retirement && bookkeeping >= MAX_INVENTORY_FILES || bytes > MAX_STORE_BYTES + (retirement ? MAX_RETIREMENT_INTENTS * MAX_RETIREMENT_BYTES : 0) || retirement && retirements >= MAX_RETIREMENT_INTENTS) throw new SyncJournalError("SYNC_JOURNAL_FULL");
|
|
11547
11554
|
}
|
|
11548
11555
|
async ensureDirectory() {
|
|
11549
11556
|
let current = path18.parse(this.directory).root;
|
package/package.json
CHANGED