@adhdev/daemon-core 0.9.82-rc.274 → 0.9.82-rc.275
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.js +100 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +100 -15
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-events-coordinator.d.ts +1 -0
- package/dist/mesh/mesh-events-pending.d.ts +14 -2
- package/dist/mesh/mesh-runtime-store.d.ts +13 -1
- package/package.json +2 -2
- package/src/mesh/mesh-events-coordinator.ts +1 -1
- package/src/mesh/mesh-events-pending.ts +84 -6
- package/src/mesh/mesh-reconcile-loop.ts +34 -14
- package/src/mesh/mesh-runtime-store.ts +33 -8
package/dist/index.mjs
CHANGED
|
@@ -270,10 +270,10 @@ function readInjected(value) {
|
|
|
270
270
|
}
|
|
271
271
|
function getDaemonBuildInfo() {
|
|
272
272
|
if (cached) return cached;
|
|
273
|
-
const commit = readInjected(true ? "
|
|
274
|
-
const commitShort = readInjected(true ? "
|
|
275
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
276
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
273
|
+
const commit = readInjected(true ? "080b607ef221e44126942d9d52eaf547b4e92550" : void 0) ?? "unknown";
|
|
274
|
+
const commitShort = readInjected(true ? "080b607e" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
275
|
+
const version = readInjected(true ? "0.9.82-rc.275" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
276
|
+
const builtAt = readInjected(true ? "2026-06-15T08:24:26.468Z" : void 0);
|
|
277
277
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
278
278
|
return cached;
|
|
279
279
|
}
|
|
@@ -4258,12 +4258,33 @@ var init_mesh_runtime_store = __esm({
|
|
|
4258
4258
|
this.maybeCheckpointWal();
|
|
4259
4259
|
return result.changes > 0;
|
|
4260
4260
|
}
|
|
4261
|
-
|
|
4261
|
+
/**
|
|
4262
|
+
* Drain undrained pending events for a mesh, atomically marking them drained.
|
|
4263
|
+
* When `opts.onlyEvents` is supplied, ONLY rows whose `event` is in that set are
|
|
4264
|
+
* drained — the rest stay queued (drained=0) for a later drain. This is how the
|
|
4265
|
+
* reconcile loop force-drains terminal/force-inject events into a *generating*
|
|
4266
|
+
* coordinator while leaving non-force progress events for the coordinator's next
|
|
4267
|
+
* idle transition. Filtering happens inside the same transaction as the
|
|
4268
|
+
* drained=1 marking, so force-drain + a concurrent full drain can never both
|
|
4269
|
+
* consume the same row.
|
|
4270
|
+
*/
|
|
4271
|
+
drainPendingEvents(meshId, coordinatorDaemonId, opts) {
|
|
4262
4272
|
return this.transaction(() => {
|
|
4263
|
-
const
|
|
4264
|
-
|
|
4273
|
+
const onlyEvents = opts?.onlyEvents;
|
|
4274
|
+
if (onlyEvents && onlyEvents.size === 0) return [];
|
|
4275
|
+
const eventList = onlyEvents ? [...onlyEvents] : [];
|
|
4276
|
+
const clauses = ["mesh_id = ?", "drained = 0"];
|
|
4277
|
+
const params = [meshId];
|
|
4278
|
+
if (coordinatorDaemonId) {
|
|
4279
|
+
clauses.push("(coordinator_daemon_id IS NULL OR coordinator_daemon_id = ?)");
|
|
4280
|
+
params.push(coordinatorDaemonId);
|
|
4281
|
+
}
|
|
4282
|
+
if (eventList.length > 0) {
|
|
4283
|
+
clauses.push(`event IN (${eventList.map(() => "?").join(",")})`);
|
|
4284
|
+
params.push(...eventList);
|
|
4285
|
+
}
|
|
4265
4286
|
const rows = this.db.prepare(
|
|
4266
|
-
`SELECT id, event, payload FROM mesh_pending_events ${
|
|
4287
|
+
`SELECT id, event, payload FROM mesh_pending_events WHERE ${clauses.join(" AND ")} ORDER BY queued_at ASC LIMIT 100`
|
|
4267
4288
|
).all(...params);
|
|
4268
4289
|
if (rows.length === 0) return [];
|
|
4269
4290
|
const ids = rows.map((r) => r.id);
|
|
@@ -6526,8 +6547,57 @@ function atomicDrainFile(path39) {
|
|
|
6526
6547
|
return null;
|
|
6527
6548
|
}
|
|
6528
6549
|
}
|
|
6529
|
-
function
|
|
6550
|
+
function selectiveDrainFile(path39, predicate) {
|
|
6551
|
+
const tmpPath = `${path39}.draining`;
|
|
6552
|
+
try {
|
|
6553
|
+
renameSync4(path39, tmpPath);
|
|
6554
|
+
} catch {
|
|
6555
|
+
return [];
|
|
6556
|
+
}
|
|
6557
|
+
let content;
|
|
6558
|
+
try {
|
|
6559
|
+
content = readFileSync10(tmpPath, "utf-8");
|
|
6560
|
+
} catch {
|
|
6561
|
+
try {
|
|
6562
|
+
unlinkSync2(tmpPath);
|
|
6563
|
+
} catch {
|
|
6564
|
+
}
|
|
6565
|
+
return [];
|
|
6566
|
+
}
|
|
6567
|
+
const consumed = [];
|
|
6568
|
+
const keptLines = [];
|
|
6569
|
+
for (const line of content.split("\n")) {
|
|
6570
|
+
if (!line) continue;
|
|
6571
|
+
let parsed;
|
|
6572
|
+
try {
|
|
6573
|
+
parsed = JSON.parse(line);
|
|
6574
|
+
} catch {
|
|
6575
|
+
parsed = void 0;
|
|
6576
|
+
}
|
|
6577
|
+
if (parsed && predicate(parsed)) {
|
|
6578
|
+
consumed.push(parsed);
|
|
6579
|
+
} else {
|
|
6580
|
+
keptLines.push(line);
|
|
6581
|
+
}
|
|
6582
|
+
}
|
|
6583
|
+
try {
|
|
6584
|
+
if (keptLines.length > 0) {
|
|
6585
|
+
writeFileSync6(path39, keptLines.join("\n") + "\n", "utf-8");
|
|
6586
|
+
}
|
|
6587
|
+
unlinkSync2(tmpPath);
|
|
6588
|
+
} catch {
|
|
6589
|
+
try {
|
|
6590
|
+
if (existsSync12(tmpPath) && !existsSync12(path39)) renameSync4(tmpPath, path39);
|
|
6591
|
+
} catch {
|
|
6592
|
+
}
|
|
6593
|
+
return [];
|
|
6594
|
+
}
|
|
6595
|
+
return consumed;
|
|
6596
|
+
}
|
|
6597
|
+
function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId, opts) {
|
|
6530
6598
|
if (!meshId) return [];
|
|
6599
|
+
const onlyEvents = opts?.onlyEvents;
|
|
6600
|
+
const matchesFilter = (eventName) => !onlyEvents || onlyEvents.has(eventName);
|
|
6531
6601
|
const merged = [];
|
|
6532
6602
|
const seenFingerprints = /* @__PURE__ */ new Set();
|
|
6533
6603
|
const pushUnique = (event) => {
|
|
@@ -6541,7 +6611,7 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
6541
6611
|
try {
|
|
6542
6612
|
const store = MeshRuntimeStore.getInstance();
|
|
6543
6613
|
if (store.pendingEventCount(meshId) > 0) {
|
|
6544
|
-
for (const row of store.drainPendingEvents(meshId, coordinatorDaemonId)) {
|
|
6614
|
+
for (const row of store.drainPendingEvents(meshId, coordinatorDaemonId, onlyEvents ? { onlyEvents } : void 0)) {
|
|
6545
6615
|
const event = row.payload;
|
|
6546
6616
|
if (event) pushUnique(event);
|
|
6547
6617
|
}
|
|
@@ -6550,6 +6620,14 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
6550
6620
|
}
|
|
6551
6621
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
6552
6622
|
for (const path39 of paths) {
|
|
6623
|
+
const isSharedFile = coordinatorDaemonId && path39 === getPendingEventsPath(meshId);
|
|
6624
|
+
const targets = (e) => !isSharedFile || !e.targetCoordinatorDaemonId || e.targetCoordinatorDaemonId === coordinatorDaemonId;
|
|
6625
|
+
if (onlyEvents) {
|
|
6626
|
+
for (const event of selectiveDrainFile(path39, (e) => targets(e) && matchesFilter(e.event))) {
|
|
6627
|
+
pushUnique(event);
|
|
6628
|
+
}
|
|
6629
|
+
continue;
|
|
6630
|
+
}
|
|
6553
6631
|
const content = atomicDrainFile(path39);
|
|
6554
6632
|
if (!content) continue;
|
|
6555
6633
|
const parsed = content.split("\n").filter(Boolean).flatMap((line) => {
|
|
@@ -6559,7 +6637,7 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
6559
6637
|
return [];
|
|
6560
6638
|
}
|
|
6561
6639
|
});
|
|
6562
|
-
const filtered =
|
|
6640
|
+
const filtered = isSharedFile ? parsed.filter(targets) : parsed;
|
|
6563
6641
|
for (const event of filtered) pushUnique(event);
|
|
6564
6642
|
}
|
|
6565
6643
|
if (merged.length === 0) return [];
|
|
@@ -8575,7 +8653,9 @@ async function runMeshReconcileTick(components) {
|
|
|
8575
8653
|
}
|
|
8576
8654
|
}
|
|
8577
8655
|
const idleCoordinators = meshCoordinators.filter((c) => c.idle);
|
|
8578
|
-
|
|
8656
|
+
const generatingCoordinators = meshCoordinators.filter((c) => !c.idle);
|
|
8657
|
+
const targetCoordinators = idleCoordinators.length > 0 ? idleCoordinators : generatingCoordinators;
|
|
8658
|
+
const forceOnly = idleCoordinators.length === 0;
|
|
8579
8659
|
if (store) {
|
|
8580
8660
|
try {
|
|
8581
8661
|
if (store.pendingEventCount(meshId) === 0) continue;
|
|
@@ -8584,15 +8664,20 @@ async function runMeshReconcileTick(components) {
|
|
|
8584
8664
|
}
|
|
8585
8665
|
let pendingEvents = [];
|
|
8586
8666
|
try {
|
|
8587
|
-
pendingEvents = drainPendingMeshCoordinatorEvents(
|
|
8667
|
+
pendingEvents = drainPendingMeshCoordinatorEvents(
|
|
8668
|
+
meshId,
|
|
8669
|
+
localDaemonId,
|
|
8670
|
+
forceOnly ? { onlyEvents: MESH_FORCE_INJECT_EVENTS } : void 0
|
|
8671
|
+
);
|
|
8588
8672
|
} catch (e) {
|
|
8589
8673
|
LOG.warn("MeshReconcile", `Drain failed for mesh ${meshId}: ${e?.message || e}`);
|
|
8590
8674
|
continue;
|
|
8591
8675
|
}
|
|
8592
8676
|
if (pendingEvents.length === 0) continue;
|
|
8593
|
-
|
|
8677
|
+
const mode = forceOnly ? "force-drain \u2192 generating" : "inject \u2192 idle";
|
|
8678
|
+
LOG.info("MeshReconcile", `Reconcile ${mode}: ${pendingEvents.length} pending event(s) \u2192 ${targetCoordinators.length} coordinator(s) for mesh ${meshId}`);
|
|
8594
8679
|
for (const pending of pendingEvents) {
|
|
8595
|
-
for (const c of
|
|
8680
|
+
for (const c of targetCoordinators) {
|
|
8596
8681
|
injectPendingIntoCoordinator(c.instance, pending);
|
|
8597
8682
|
}
|
|
8598
8683
|
}
|