@cleocode/core 2026.10.8 → 2026.10.9-rc.ci.676
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/build-provenance.json +2 -2
- package/dist/cloud/auto-sync-command-entry.d.ts +13 -0
- package/dist/cloud/auto-sync-command-entry.d.ts.map +1 -0
- package/dist/cloud/auto-sync-command-entry.js +18 -0
- package/dist/cloud/auto-sync-command-entry.js.map +1 -0
- package/dist/cloud/auto-sync-command.d.ts +64 -0
- package/dist/cloud/auto-sync-command.d.ts.map +1 -0
- package/dist/cloud/auto-sync-command.js +109 -0
- package/dist/cloud/auto-sync-command.js.map +1 -0
- package/dist/cloud/auto-sync.d.ts +111 -0
- package/dist/cloud/auto-sync.d.ts.map +1 -0
- package/dist/cloud/auto-sync.js +275 -0
- package/dist/cloud/auto-sync.js.map +1 -0
- package/dist/cloud/nexus-cloud-device-overview.d.ts +52 -0
- package/dist/cloud/nexus-cloud-device-overview.d.ts.map +1 -0
- package/dist/cloud/nexus-cloud-device-overview.js +105 -0
- package/dist/cloud/nexus-cloud-device-overview.js.map +1 -0
- package/dist/cloud/nexus-cloud-journal-activity.d.ts +56 -0
- package/dist/cloud/nexus-cloud-journal-activity.d.ts.map +1 -0
- package/dist/cloud/nexus-cloud-journal-activity.js +98 -0
- package/dist/cloud/nexus-cloud-journal-activity.js.map +1 -0
- package/dist/cloud/nexus-cloud-status.d.ts.map +1 -1
- package/dist/cloud/nexus-cloud-status.js +88 -5
- package/dist/cloud/nexus-cloud-status.js.map +1 -1
- package/dist/cloud/nexus-vault.d.ts +19 -5
- package/dist/cloud/nexus-vault.d.ts.map +1 -1
- package/dist/cloud/nexus-vault.js +376 -71
- package/dist/cloud/nexus-vault.js.map +1 -1
- package/dist/cloud/replica-rebind.d.ts +14 -0
- package/dist/cloud/replica-rebind.d.ts.map +1 -1
- package/dist/cloud/replica-rebind.js +20 -1
- package/dist/cloud/replica-rebind.js.map +1 -1
- package/dist/config.d.ts +10 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +19 -0
- package/dist/config.js.map +1 -1
- package/dist/docs/docs-ops.d.ts +4 -2
- package/dist/docs/docs-ops.d.ts.map +1 -1
- package/dist/docs/docs-ops.js +107 -15
- package/dist/docs/docs-ops.js.map +1 -1
- package/dist/doctor/system-health.d.ts +76 -2
- package/dist/doctor/system-health.d.ts.map +1 -1
- package/dist/doctor/system-health.js +264 -41
- package/dist/doctor/system-health.js.map +1 -1
- package/dist/hooks/project-runner.d.ts +10 -0
- package/dist/hooks/project-runner.d.ts.map +1 -0
- package/dist/hooks/project-runner.js +328 -0
- package/dist/hooks/project-runner.js.map +1 -0
- package/dist/hooks/project-state.d.ts +41 -0
- package/dist/hooks/project-state.d.ts.map +1 -0
- package/dist/hooks/project-state.js +331 -0
- package/dist/hooks/project-state.js.map +1 -0
- package/dist/hooks/release-gate.d.ts +61 -0
- package/dist/hooks/release-gate.d.ts.map +1 -0
- package/dist/hooks/release-gate.js +70 -0
- package/dist/hooks/release-gate.js.map +1 -0
- package/dist/nexus/analyze-orchestrator.d.ts +2 -0
- package/dist/nexus/analyze-orchestrator.d.ts.map +1 -1
- package/dist/nexus/analyze-orchestrator.js +1 -0
- package/dist/nexus/analyze-orchestrator.js.map +1 -1
- package/dist/nexus/freshness.d.ts +67 -3
- package/dist/nexus/freshness.d.ts.map +1 -1
- package/dist/nexus/freshness.js +130 -9
- package/dist/nexus/freshness.js.map +1 -1
- package/dist/nexus/refresh-child.d.ts +14 -0
- package/dist/nexus/refresh-child.d.ts.map +1 -0
- package/dist/nexus/refresh-child.js +24 -0
- package/dist/nexus/refresh-child.js.map +1 -0
- package/dist/orchestrate/spawn-ops.d.ts +8 -1
- package/dist/orchestrate/spawn-ops.d.ts.map +1 -1
- package/dist/orchestrate/spawn-ops.js +42 -12
- package/dist/orchestrate/spawn-ops.js.map +1 -1
- package/dist/orchestration/spawn.d.ts +5 -0
- package/dist/orchestration/spawn.d.ts.map +1 -1
- package/dist/orchestration/spawn.js +4 -1
- package/dist/orchestration/spawn.js.map +1 -1
- package/dist/release/channel.d.ts.map +1 -1
- package/dist/release/channel.js +10 -0
- package/dist/release/channel.js.map +1 -1
- package/dist/release/github-pr.d.ts.map +1 -1
- package/dist/release/github-pr.js +1 -0
- package/dist/release/github-pr.js.map +1 -1
- package/dist/release/plan.d.ts +8 -3
- package/dist/release/plan.d.ts.map +1 -1
- package/dist/release/plan.js +72 -15
- package/dist/release/plan.js.map +1 -1
- package/dist/release/reconcile.d.ts.map +1 -1
- package/dist/release/reconcile.js +6 -15
- package/dist/release/reconcile.js.map +1 -1
- package/dist/sentient/daemon-entry.d.ts +6 -0
- package/dist/sentient/daemon-entry.d.ts.map +1 -1
- package/dist/sentient/daemon-entry.js +12 -0
- package/dist/sentient/daemon-entry.js.map +1 -1
- package/dist/sentient/worktree-dispatch.d.ts +7 -0
- package/dist/sentient/worktree-dispatch.d.ts.map +1 -1
- package/dist/sentient/worktree-dispatch.js +37 -1
- package/dist/sentient/worktree-dispatch.js.map +1 -1
- package/dist/sessions/session-end-snapshot-entry.d.ts +4 -1
- package/dist/sessions/session-end-snapshot-entry.d.ts.map +1 -1
- package/dist/sessions/session-end-snapshot-entry.js +9 -1
- package/dist/sessions/session-end-snapshot-entry.js.map +1 -1
- package/dist/spawn/agent-identity.d.ts.map +1 -1
- package/dist/spawn/agent-identity.js +96 -1
- package/dist/spawn/agent-identity.js.map +1 -1
- package/dist/spawn/branch-lock.d.ts +27 -8
- package/dist/spawn/branch-lock.d.ts.map +1 -1
- package/dist/spawn/branch-lock.js +57 -73
- package/dist/spawn/branch-lock.js.map +1 -1
- package/dist/store/agent-resolver.d.ts +6 -0
- package/dist/store/agent-resolver.d.ts.map +1 -1
- package/dist/store/agent-resolver.js +2 -0
- package/dist/store/agent-resolver.js.map +1 -1
- package/dist/store/dual-scope-db.d.ts +20 -0
- package/dist/store/dual-scope-db.d.ts.map +1 -1
- package/dist/store/dual-scope-db.js +81 -8
- package/dist/store/dual-scope-db.js.map +1 -1
- package/dist/store/exodus/bare-family.d.ts.map +1 -1
- package/dist/store/exodus/bare-family.js +4 -1
- package/dist/store/exodus/bare-family.js.map +1 -1
- package/dist/store/exodus/migrate.d.ts.map +1 -1
- package/dist/store/exodus/migrate.js +2 -0
- package/dist/store/exodus/migrate.js.map +1 -1
- package/dist/store/exodus/on-open.d.ts.map +1 -1
- package/dist/store/exodus/on-open.js +16 -4
- package/dist/store/exodus/on-open.js.map +1 -1
- package/dist/store/exodus/reconcile.d.ts.map +1 -1
- package/dist/store/exodus/reconcile.js +2 -0
- package/dist/store/exodus/reconcile.js.map +1 -1
- package/dist/store/portable-bundle-import.d.ts +17 -0
- package/dist/store/portable-bundle-import.d.ts.map +1 -1
- package/dist/store/portable-bundle-import.js +46 -31
- package/dist/store/portable-bundle-import.js.map +1 -1
- package/dist/store/portable-bundle-scan.d.ts.map +1 -1
- package/dist/store/portable-bundle-scan.js +5 -0
- package/dist/store/portable-bundle-scan.js.map +1 -1
- package/dist/store/row-identity-registry.d.ts +4 -3
- package/dist/store/row-identity-registry.d.ts.map +1 -1
- package/dist/store/row-identity-registry.js +37 -35
- package/dist/store/row-identity-registry.js.map +1 -1
- package/dist/store/row-identity.d.ts.map +1 -1
- package/dist/store/row-identity.js +6 -1
- package/dist/store/row-identity.js.map +1 -1
- package/dist/store/schema/cleo-global/agent-registry.d.ts +16 -0
- package/dist/store/schema/cleo-global/agent-registry.d.ts.map +1 -1
- package/dist/store/schema/cleo-global/agent-registry.js +4 -1
- package/dist/store/schema/cleo-global/agent-registry.js.map +1 -1
- package/dist/store/schema/cleo-project/provenance-orphans.d.ts +126 -1
- package/dist/store/schema/cleo-project/provenance-orphans.d.ts.map +1 -1
- package/dist/store/schema/cleo-project/provenance-orphans.js +41 -1
- package/dist/store/schema/cleo-project/provenance-orphans.js.map +1 -1
- package/dist/store/sqlite-data-accessor.d.ts +40 -0
- package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
- package/dist/store/sqlite-data-accessor.js +122 -0
- package/dist/store/sqlite-data-accessor.js.map +1 -1
- package/dist/store/sync/activity.d.ts +64 -0
- package/dist/store/sync/activity.d.ts.map +1 -0
- package/dist/store/sync/activity.js +220 -0
- package/dist/store/sync/activity.js.map +1 -0
- package/dist/store/sync/apply/applier.d.ts.map +1 -1
- package/dist/store/sync/apply/applier.js +58 -2
- package/dist/store/sync/apply/applier.js.map +1 -1
- package/dist/store/sync/apply/write-api.d.ts.map +1 -1
- package/dist/store/sync/apply/write-api.js +45 -3
- package/dist/store/sync/apply/write-api.js.map +1 -1
- package/dist/store/sync/capture.d.ts +6 -4
- package/dist/store/sync/capture.d.ts.map +1 -1
- package/dist/store/sync/capture.js +16 -4
- package/dist/store/sync/capture.js.map +1 -1
- package/dist/store/sync/collision-settle.d.ts +120 -0
- package/dist/store/sync/collision-settle.d.ts.map +1 -1
- package/dist/store/sync/collision-settle.js +342 -5
- package/dist/store/sync/collision-settle.js.map +1 -1
- package/dist/store/sync/flags.d.ts +34 -0
- package/dist/store/sync/flags.d.ts.map +1 -1
- package/dist/store/sync/flags.js +46 -0
- package/dist/store/sync/flags.js.map +1 -1
- package/dist/store/sync/genesis.d.ts +8 -0
- package/dist/store/sync/genesis.d.ts.map +1 -1
- package/dist/store/sync/genesis.js +18 -5
- package/dist/store/sync/genesis.js.map +1 -1
- package/dist/store/sync/push.d.ts +4 -2
- package/dist/store/sync/push.d.ts.map +1 -1
- package/dist/store/sync/push.js +10 -1
- package/dist/store/sync/push.js.map +1 -1
- package/dist/store/sync/rebind.d.ts +20 -0
- package/dist/store/sync/rebind.d.ts.map +1 -1
- package/dist/store/sync/rebind.js +86 -4
- package/dist/store/sync/rebind.js.map +1 -1
- package/dist/store/sync/reconcile-copy.d.ts +152 -0
- package/dist/store/sync/reconcile-copy.d.ts.map +1 -0
- package/dist/store/sync/reconcile-copy.js +428 -0
- package/dist/store/sync/reconcile-copy.js.map +1 -0
- package/dist/store/sync/reconcile.d.ts +80 -0
- package/dist/store/sync/reconcile.d.ts.map +1 -1
- package/dist/store/sync/reconcile.js +97 -5
- package/dist/store/sync/reconcile.js.map +1 -1
- package/dist/store/sync/repair.d.ts +11 -0
- package/dist/store/sync/repair.d.ts.map +1 -1
- package/dist/store/sync/repair.js +14 -3
- package/dist/store/sync/repair.js.map +1 -1
- package/dist/store/sync/replica.d.ts +74 -1
- package/dist/store/sync/replica.d.ts.map +1 -1
- package/dist/store/sync/replica.js +104 -6
- package/dist/store/sync/replica.js.map +1 -1
- package/dist/store/sync/row-meta.d.ts +4 -2
- package/dist/store/sync/row-meta.d.ts.map +1 -1
- package/dist/store/sync/row-meta.js +6 -4
- package/dist/store/sync/row-meta.js.map +1 -1
- package/dist/store/sync/sealer.d.ts +2 -0
- package/dist/store/sync/sealer.d.ts.map +1 -1
- package/dist/store/sync/sealer.js +33 -4
- package/dist/store/sync/sealer.js.map +1 -1
- package/dist/store/sync/structural.d.ts.map +1 -1
- package/dist/store/sync/structural.js +3 -1
- package/dist/store/sync/structural.js.map +1 -1
- package/dist/store/sync/timestamp-canon.d.ts.map +1 -1
- package/dist/store/sync/timestamp-canon.js +2 -0
- package/dist/store/sync/timestamp-canon.js.map +1 -1
- package/dist/store/table-classification.d.ts +29 -0
- package/dist/store/table-classification.d.ts.map +1 -1
- package/dist/store/table-classification.js +85 -19
- package/dist/store/table-classification.js.map +1 -1
- package/dist/store/twin-collapse.d.ts.map +1 -1
- package/dist/store/twin-collapse.js +28 -10
- package/dist/store/twin-collapse.js.map +1 -1
- package/dist/store/vault-manifest.d.ts +5 -0
- package/dist/store/vault-manifest.d.ts.map +1 -1
- package/dist/store/vault-manifest.js +14 -1
- package/dist/store/vault-manifest.js.map +1 -1
- package/dist/tasks/affected-packages.d.ts +15 -5
- package/dist/tasks/affected-packages.d.ts.map +1 -1
- package/dist/tasks/affected-packages.js +20 -8
- package/dist/tasks/affected-packages.js.map +1 -1
- package/dist/tasks/done-record.d.ts +14 -4
- package/dist/tasks/done-record.d.ts.map +1 -1
- package/dist/tasks/done-record.js +21 -9
- package/dist/tasks/done-record.js.map +1 -1
- package/dist/tasks/evidence.d.ts.map +1 -1
- package/dist/tasks/evidence.js +45 -4
- package/dist/tasks/evidence.js.map +1 -1
- package/dist/tasks/gate-runner.d.ts +5 -4
- package/dist/tasks/gate-runner.d.ts.map +1 -1
- package/dist/tasks/gate-runner.js +18 -11
- package/dist/tasks/gate-runner.js.map +1 -1
- package/dist/tasks/tool-cache.d.ts +27 -1
- package/dist/tasks/tool-cache.d.ts.map +1 -1
- package/dist/tasks/tool-cache.js +110 -6
- package/dist/tasks/tool-cache.js.map +1 -1
- package/dist/tools/fs.d.ts +3 -1
- package/dist/tools/fs.d.ts.map +1 -1
- package/dist/tools/fs.js +35 -2
- package/dist/tools/fs.js.map +1 -1
- package/dist/validation/engine-ops.d.ts +10 -3
- package/dist/validation/engine-ops.d.ts.map +1 -1
- package/dist/validation/engine-ops.js +17 -8
- package/dist/validation/engine-ops.js.map +1 -1
- package/migrations/drizzle-cleo-global/20261010180000_t12915-agent-registry-uids/migration.sql +18 -0
- package/migrations/drizzle-cleo-project/20261010170000_t12896b-brain-task-observations/migration.sql +37 -0
- package/migrations/sync-journal/20261009150000_t13335-capture-pin/migration.sql +13 -0
- package/package.json +18 -13
- package/schemas/config.schema.json +12 -0
- package/schemas/project-context.schema.json +5 -0
- package/templates/CLEO-INJECTION.md +2 -2
- package/templates/CLEO-REFERENCE.md +6 -4
- package/templates/git-hooks/pre-push +29 -1
- package/templates/workflows/release-prepare.yml.tmpl +1 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Journal activity: what each device changed and when, read from this
|
|
3
|
+
* store's journal inbox (T13369).
|
|
4
|
+
*
|
|
5
|
+
* Every transaction a pull stages is an `_sync_inbox` row carrying the
|
|
6
|
+
* writing replica, the Nexus device that signed its segment, the
|
|
7
|
+
* transaction's HLC (its write time) and the times this store staged and
|
|
8
|
+
* applied it. Own transactions come back through the same inbox as echoes,
|
|
9
|
+
* so the inbox shows every device on the stream, this one included.
|
|
10
|
+
*
|
|
11
|
+
* A transaction its replica wrote after a server-confirmed retire is marked
|
|
12
|
+
* `history` once applied (§1.5, T13366): the merge recorded no conflict for it.
|
|
13
|
+
*
|
|
14
|
+
* The inbox is the window: applied rows pruned after a verified checkpoint
|
|
15
|
+
* are no longer listed. Read-only: nothing is written.
|
|
16
|
+
*
|
|
17
|
+
* @task T13369
|
|
18
|
+
* @module store/sync/activity
|
|
19
|
+
*/
|
|
20
|
+
import { getStableDeviceId } from '../../llm/stable-device-id.js';
|
|
21
|
+
import { parseHlc } from './hlc.js';
|
|
22
|
+
import { isInheritedHistory } from './retire.js';
|
|
23
|
+
import { hasTable } from './schema.js';
|
|
24
|
+
/** Largest page {@link journalActivity} returns. */
|
|
25
|
+
export const JOURNAL_ACTIVITY_PAGE_MAX = 200;
|
|
26
|
+
/** Thrown for a `before` cursor this module did not issue. */
|
|
27
|
+
export class JournalActivityCursorError extends Error {
|
|
28
|
+
code = 'E_VALIDATION';
|
|
29
|
+
constructor(cursor) {
|
|
30
|
+
super(`not a journal activity cursor: ${cursor}`);
|
|
31
|
+
this.name = 'JournalActivityCursorError';
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function encodeCursor(c) {
|
|
35
|
+
return Buffer.from(JSON.stringify([c.hlc, c.stream, c.seq, c.txnIdx]), 'utf8').toString('base64url');
|
|
36
|
+
}
|
|
37
|
+
function decodeCursor(raw) {
|
|
38
|
+
try {
|
|
39
|
+
const v = JSON.parse(Buffer.from(raw, 'base64url').toString('utf8'));
|
|
40
|
+
if (Array.isArray(v) &&
|
|
41
|
+
v.length === 4 &&
|
|
42
|
+
typeof v[0] === 'string' &&
|
|
43
|
+
typeof v[1] === 'string' &&
|
|
44
|
+
Number.isSafeInteger(v[2]) &&
|
|
45
|
+
Number.isSafeInteger(v[3])) {
|
|
46
|
+
return { hlc: v[0], stream: v[1], seq: v[2], txnIdx: v[3] };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// Falls through to the refusal.
|
|
51
|
+
}
|
|
52
|
+
// @sync-invariant none:input-shape a read-only listing refuses a cursor it did not issue
|
|
53
|
+
throw new JournalActivityCursorError(raw);
|
|
54
|
+
}
|
|
55
|
+
/** The HLC's physical time as ISO-8601, or the raw HLC when it does not parse. */
|
|
56
|
+
function hlcTime(hlc) {
|
|
57
|
+
try {
|
|
58
|
+
return new Date(parseHlc(hlc).phys).toISOString();
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return hlc;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/** The replicas this machine bound in this store. */
|
|
65
|
+
function ownReplicas(db, localDeviceId) {
|
|
66
|
+
if (!hasTable(db, '_sync_replica'))
|
|
67
|
+
return new Set();
|
|
68
|
+
const rows = db
|
|
69
|
+
.prepare('SELECT replica_id FROM _sync_replica WHERE device_id = ?')
|
|
70
|
+
.all(localDeviceId);
|
|
71
|
+
return new Set(rows.map((r) => r.replica_id));
|
|
72
|
+
}
|
|
73
|
+
function summarise(txnJson) {
|
|
74
|
+
let t = {};
|
|
75
|
+
try {
|
|
76
|
+
const parsed = JSON.parse(txnJson);
|
|
77
|
+
if (parsed !== null && typeof parsed === 'object')
|
|
78
|
+
t = parsed;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// A row the stager accepted always parses; an unreadable one shows empty.
|
|
82
|
+
}
|
|
83
|
+
const tables = {};
|
|
84
|
+
const ops = Array.isArray(t.ops) ? t.ops : [];
|
|
85
|
+
for (const op of ops) {
|
|
86
|
+
if (op === null || typeof op !== 'object')
|
|
87
|
+
continue;
|
|
88
|
+
const { t: table, o } = op;
|
|
89
|
+
if (typeof table !== 'string' || (o !== 'I' && o !== 'U' && o !== 'D' && o !== 'K'))
|
|
90
|
+
continue;
|
|
91
|
+
tables[table] ??= { I: 0, U: 0, D: 0, K: 0 };
|
|
92
|
+
tables[table][o] += 1;
|
|
93
|
+
}
|
|
94
|
+
const actor = t.actor !== null && typeof t.actor === 'object'
|
|
95
|
+
? Object.fromEntries(Object.entries(t.actor).filter(([, v]) => typeof v === 'string'))
|
|
96
|
+
: null;
|
|
97
|
+
return {
|
|
98
|
+
txn: typeof t.txn === 'string' ? t.txn : '',
|
|
99
|
+
kind: typeof t.kind === 'string' ? t.kind : '',
|
|
100
|
+
via: typeof t.via === 'string' ? t.via : '',
|
|
101
|
+
actor,
|
|
102
|
+
project: typeof t.project === 'string' ? t.project : null,
|
|
103
|
+
ops: ops.length,
|
|
104
|
+
tables,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/** The WHERE clause and parameters of the filters (the cursor excluded). */
|
|
108
|
+
function filters(opts) {
|
|
109
|
+
const where = [];
|
|
110
|
+
const params = [];
|
|
111
|
+
if (opts.deviceId !== undefined) {
|
|
112
|
+
where.push('device_id = ?');
|
|
113
|
+
params.push(opts.deviceId);
|
|
114
|
+
}
|
|
115
|
+
if (opts.sinceMs !== undefined) {
|
|
116
|
+
// HLCs sort lexically by physical time; a bare 13-digit prefix sorts first.
|
|
117
|
+
where.push('hlc >= ?');
|
|
118
|
+
params.push(String(Math.max(0, Math.trunc(opts.sinceMs))).padStart(13, '0'));
|
|
119
|
+
}
|
|
120
|
+
if (opts.project !== undefined) {
|
|
121
|
+
where.push("json_extract(txn_json, '$.project') = ?");
|
|
122
|
+
params.push(opts.project);
|
|
123
|
+
}
|
|
124
|
+
return { where, params };
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* List the transactions this store's journal received, newest first (by
|
|
128
|
+
* HLC), with the device that wrote each one and a per-device summary.
|
|
129
|
+
*
|
|
130
|
+
* @param db - The store.
|
|
131
|
+
* @param opts - Paging and filters.
|
|
132
|
+
* @returns A page of transactions, the per-device summary and the next cursor.
|
|
133
|
+
* @throws {JournalActivityCursorError} When `before` is not a cursor this module issued.
|
|
134
|
+
*/
|
|
135
|
+
export function journalActivity(db, opts = {}) {
|
|
136
|
+
if (!hasTable(db, '_sync_inbox'))
|
|
137
|
+
return { items: [], devices: [], nextBefore: null };
|
|
138
|
+
const requested = opts.limit !== undefined && Number.isFinite(opts.limit) ? Math.trunc(opts.limit) : 50;
|
|
139
|
+
const limit = Math.min(Math.max(requested, 1), JOURNAL_ACTIVITY_PAGE_MAX);
|
|
140
|
+
const own = ownReplicas(db, opts.localDeviceId ?? getStableDeviceId());
|
|
141
|
+
const names = opts.deviceNames ?? new Map();
|
|
142
|
+
const { where, params } = filters(opts);
|
|
143
|
+
const devRows = db
|
|
144
|
+
.prepare(`SELECT device_id, replica_id, count(*) AS n, max(hlc) AS last
|
|
145
|
+
FROM _sync_inbox ${where.length ? `WHERE ${where.join(' AND ')}` : ''}
|
|
146
|
+
GROUP BY device_id, replica_id`)
|
|
147
|
+
.all(...params);
|
|
148
|
+
const byDevice = new Map();
|
|
149
|
+
for (const r of devRows) {
|
|
150
|
+
const d = byDevice.get(r.device_id) ?? { txns: 0, last: '', mine: false };
|
|
151
|
+
d.txns += Number(r.n);
|
|
152
|
+
if (r.last > d.last)
|
|
153
|
+
d.last = r.last;
|
|
154
|
+
if (own.has(r.replica_id))
|
|
155
|
+
d.mine = true;
|
|
156
|
+
byDevice.set(r.device_id, d);
|
|
157
|
+
}
|
|
158
|
+
const devices = [...byDevice.entries()]
|
|
159
|
+
.sort((a, b) => (a[1].last < b[1].last ? 1 : a[1].last > b[1].last ? -1 : 0))
|
|
160
|
+
.map(([deviceId, d]) => ({
|
|
161
|
+
deviceId,
|
|
162
|
+
deviceName: names.get(deviceId) ?? null,
|
|
163
|
+
thisDevice: d.mine,
|
|
164
|
+
txns: d.txns,
|
|
165
|
+
lastAt: hlcTime(d.last),
|
|
166
|
+
lastSeenAt: opts.deviceLastSeen?.get(deviceId) ?? null,
|
|
167
|
+
}));
|
|
168
|
+
const pageWhere = [...where];
|
|
169
|
+
const pageParams = [...params];
|
|
170
|
+
if (opts.before !== undefined) {
|
|
171
|
+
const c = decodeCursor(opts.before);
|
|
172
|
+
pageWhere.push('(hlc, stream, seq, txn_idx) < (?, ?, ?, ?)');
|
|
173
|
+
pageParams.push(c.hlc, c.stream, c.seq, c.txnIdx);
|
|
174
|
+
}
|
|
175
|
+
const rows = db
|
|
176
|
+
.prepare(`SELECT stream, seq, txn_idx, replica_id, device_id, txn_json, hlc, status, reason,
|
|
177
|
+
staged_at, applied_at
|
|
178
|
+
FROM _sync_inbox ${pageWhere.length ? `WHERE ${pageWhere.join(' AND ')}` : ''}
|
|
179
|
+
ORDER BY hlc DESC, stream DESC, seq DESC, txn_idx DESC
|
|
180
|
+
LIMIT ?`)
|
|
181
|
+
.all(...pageParams, limit + 1);
|
|
182
|
+
const page = rows.slice(0, limit);
|
|
183
|
+
const items = page.map((r) => {
|
|
184
|
+
const s = summarise(r.txn_json);
|
|
185
|
+
return {
|
|
186
|
+
txn: s.txn,
|
|
187
|
+
stream: r.stream,
|
|
188
|
+
seq: Number(r.seq),
|
|
189
|
+
txnIdx: Number(r.txn_idx),
|
|
190
|
+
replicaId: r.replica_id,
|
|
191
|
+
deviceId: r.device_id,
|
|
192
|
+
deviceName: names.get(r.device_id) ?? null,
|
|
193
|
+
thisDevice: own.has(r.replica_id),
|
|
194
|
+
hlc: r.hlc,
|
|
195
|
+
at: hlcTime(r.hlc),
|
|
196
|
+
stagedAt: r.staged_at,
|
|
197
|
+
appliedAt: r.applied_at,
|
|
198
|
+
status: r.status,
|
|
199
|
+
reason: r.reason,
|
|
200
|
+
history: r.status === 'applied' && isInheritedHistory(db, r.stream, r.replica_id, Number(r.seq)),
|
|
201
|
+
kind: s.kind,
|
|
202
|
+
via: s.via,
|
|
203
|
+
actor: s.actor,
|
|
204
|
+
project: s.project,
|
|
205
|
+
ops: s.ops,
|
|
206
|
+
tables: s.tables,
|
|
207
|
+
};
|
|
208
|
+
});
|
|
209
|
+
const last = page.at(-1);
|
|
210
|
+
const nextBefore = rows.length > limit && last !== undefined
|
|
211
|
+
? encodeCursor({
|
|
212
|
+
hlc: last.hlc,
|
|
213
|
+
stream: last.stream,
|
|
214
|
+
seq: Number(last.seq),
|
|
215
|
+
txnIdx: Number(last.txn_idx),
|
|
216
|
+
})
|
|
217
|
+
: null;
|
|
218
|
+
return { items, devices, nextBefore };
|
|
219
|
+
}
|
|
220
|
+
//# sourceMappingURL=activity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activity.js","sourceRoot":"","sources":["../../../src/store/sync/activity.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"applier.d.ts","sourceRoot":"","sources":["../../../../src/store/sync/apply/applier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"applier.d.ts","sourceRoot":"","sources":["../../../../src/store/sync/apply/applier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AA2CtD,OAAO,EAUL,KAAK,UAAU,EAIhB,MAAM,kBAAkB,CAAC;AAU1B,wCAAwC;AACxC,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,gDAAgD;IAChD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,+FAA+F;IAC/F,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,2EAA2E;IAC3E,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,2EAA2E;AAC3E,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,gCAAgC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,yFAAyF;IACzF,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,6FAA6F;IAC7F,QAAQ,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IACvC,qEAAqE;IACrE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AA4vCD,0FAA0F;AAC1F,eAAO,MAAM,eAAe,OAAQ,CAAC;AACrC,sEAAsE;AACtE,eAAO,MAAM,cAAc,KAAK,CAAC;AAgNjC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,kBAAkB,GAAG,WAAW,CA4KvF"}
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
*/
|
|
62
62
|
import { BIRTH_FP_COLUMN, UID_COLUMN } from '../../row-identity-registry.js';
|
|
63
63
|
import { captureTableDef } from '../capture.js';
|
|
64
|
-
import { announcePlacedRekeys, settleLostUidCollisions } from '../collision-settle.js';
|
|
64
|
+
import { announcePlacedRekeys, displayKeyColumn, displayKeyReferrers, foldDisplayRemints, followLocalTaskRefs, remintLostKeyCollisions, repointOwnDecisionText, settleLostUidCollisions, } from '../collision-settle.js';
|
|
65
65
|
import { recordConflictOnce, recordConflicts, resolveHeldConflicts } from '../conflicts.js';
|
|
66
66
|
import { clearFieldLeaves, readFieldFrontiers, readFieldLeaves, recordFieldLeaves, restoreFieldState, setFieldFrontiers, } from '../field-leave.js';
|
|
67
67
|
import { accountRebaseRows, heldOp, holdOp, txnHasHold, unholdOp } from '../held.js';
|
|
@@ -685,9 +685,13 @@ function applyOne(c, opIdx, op) {
|
|
|
685
685
|
});
|
|
686
686
|
}
|
|
687
687
|
}
|
|
688
|
+
const keyMove = displayKeyMove(def, before, out);
|
|
688
689
|
const sp = `apply_op_${opIdx}`;
|
|
689
690
|
c.db.exec(`SAVEPOINT ${sp}`);
|
|
690
691
|
try {
|
|
692
|
+
// A display key that moves leaves its referrers behind until they follow.
|
|
693
|
+
if (keyMove)
|
|
694
|
+
c.db.exec('PRAGMA defer_foreign_keys = ON');
|
|
691
695
|
// cascade-with-ops: the remaining children go first, with ops' tombstones.
|
|
692
696
|
const actor = c.st.txn.actor ? JSON.stringify(c.st.txn.actor) : null;
|
|
693
697
|
for (const x of live)
|
|
@@ -697,6 +701,8 @@ function applyOne(c, opIdx, op) {
|
|
|
697
701
|
: c.st;
|
|
698
702
|
const history = c.history === true && out.status !== 'void';
|
|
699
703
|
const recorded = effect(c.db, c.api, st, opIdx, { op, def, before, out, refKeys }, c.nowIso, c.replay !== undefined || history);
|
|
704
|
+
if (keyMove)
|
|
705
|
+
followDisplayKey(c, op.t, op.u, keyMove);
|
|
700
706
|
const n = history ? 0 : recorded;
|
|
701
707
|
c.db.exec(`RELEASE ${sp}`);
|
|
702
708
|
const result = out.status === 'applied' || out.status === 'partial'
|
|
@@ -724,6 +730,42 @@ function applyOne(c, opIdx, op) {
|
|
|
724
730
|
});
|
|
725
731
|
}
|
|
726
732
|
}
|
|
733
|
+
/** Decision key moves applied in the current apply call, by store (T13433). */
|
|
734
|
+
const decisionMoves = new WeakMap();
|
|
735
|
+
/** A counter display key an applied update moves (T13405), or null. */
|
|
736
|
+
function displayKeyMove(def, before, out) {
|
|
737
|
+
const column = displayKeyColumn(def.table);
|
|
738
|
+
if (!column || out.effect !== 'update' || !before.live)
|
|
739
|
+
return null;
|
|
740
|
+
const from = before.fields[column]?.value;
|
|
741
|
+
const to = out.next.fields[column]?.value;
|
|
742
|
+
return typeof from === 'string' && typeof to === 'string' && from !== to
|
|
743
|
+
? { column, from, to }
|
|
744
|
+
: null;
|
|
745
|
+
}
|
|
746
|
+
/**
|
|
747
|
+
* Point the local rows that reference a moved display key at the new key
|
|
748
|
+
* (T13405): a replica that had placed a re-minted loser keeps its own
|
|
749
|
+
* children on it, never on the winner that takes the old key. Writes go
|
|
750
|
+
* through the write API, so each is an apply intent, not a local change.
|
|
751
|
+
*/
|
|
752
|
+
function followDisplayKey(c, table, uid, move) {
|
|
753
|
+
// Its own text references re-point after the passes, in a local frame (T13433).
|
|
754
|
+
if (table === 'brain_decisions' && !c.replay) {
|
|
755
|
+
const moves = decisionMoves.get(c.db) ?? [];
|
|
756
|
+
moves.push({ uid, from: move.from, to: move.to });
|
|
757
|
+
decisionMoves.set(c.db, moves);
|
|
758
|
+
}
|
|
759
|
+
for (const ref of displayKeyReferrers(c.db, c.defs, table, move.column)) {
|
|
760
|
+
const rows = c.db
|
|
761
|
+
.prepare(`SELECT "${UID_COLUMN}" AS uid FROM main."${ref.table.replaceAll('"', '""')}" WHERE "${ref.column.replaceAll('"', '""')}" = ? AND "${UID_COLUMN}" IS NOT NULL`)
|
|
762
|
+
.all(move.from);
|
|
763
|
+
for (const r of rows)
|
|
764
|
+
c.api.writeFields(ref.table, r.uid, { [ref.column]: move.to });
|
|
765
|
+
}
|
|
766
|
+
if (table === 'tasks_tasks')
|
|
767
|
+
followLocalTaskRefs(c.db, c.defs, move.from, move.to);
|
|
768
|
+
}
|
|
727
769
|
/** The rows a transaction's ops write (a re-key's both uids). */
|
|
728
770
|
function touchedRows(ops) {
|
|
729
771
|
return ops.flatMap((o) => o.o === 'K' && o.nu && o.nu !== o.u
|
|
@@ -1330,7 +1372,8 @@ export function applyStagedTxns(db, opts) {
|
|
|
1330
1372
|
passes += 1;
|
|
1331
1373
|
const heldReplicas = new Set();
|
|
1332
1374
|
const held = new Set(); // rows written by a pending transaction
|
|
1333
|
-
|
|
1375
|
+
// An origin's display-key re-mint folds into the insert it held (T13405).
|
|
1376
|
+
const staged = foldDisplayRemints(db, stagedTxns(db, opts.stream).map((st) => followUidAliases(db, withoutLocalRowids(st, defs), defs)), defs);
|
|
1334
1377
|
// Each page is one frame and one scoped rebase (§3.5 Rule 3): rewind the
|
|
1335
1378
|
// page's scope once, apply its transactions in stream order, replay once.
|
|
1336
1379
|
for (let at = 0; at < staged.length;) {
|
|
@@ -1423,6 +1466,19 @@ export function applyStagedTxns(db, opts) {
|
|
|
1423
1466
|
opts.seal?.();
|
|
1424
1467
|
runPasses();
|
|
1425
1468
|
}
|
|
1469
|
+
// The origin of a row that lost a key collision re-mints its key, then the
|
|
1470
|
+
// held insert places (T13405). Driven by the open conflicts, so a failed
|
|
1471
|
+
// re-mint is retried by the next apply (T13431).
|
|
1472
|
+
if (remintLostKeyCollisions(db, opts).length > 0) {
|
|
1473
|
+
opts.seal?.();
|
|
1474
|
+
runPasses();
|
|
1475
|
+
}
|
|
1476
|
+
// Forget the moves only once their frames committed: a busy or failed frame
|
|
1477
|
+
// keeps them for the next apply on this handle (re-pointing is idempotent).
|
|
1478
|
+
const moves = decisionMoves.get(db) ?? [];
|
|
1479
|
+
if (repointOwnDecisionText(db, opts, moves) > 0)
|
|
1480
|
+
opts.seal?.();
|
|
1481
|
+
decisionMoves.delete(db);
|
|
1426
1482
|
// Every other replica that had placed a re-keyed loser announces the
|
|
1427
1483
|
// re-key, so its earlier references follow the loser too (T13399).
|
|
1428
1484
|
if (announcePlacedRekeys(db, opts, new Date(now()).toISOString()) > 0)
|