@cleocode/core 2026.10.5 → 2026.10.6
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/bootstrap.d.ts +13 -0
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +21 -32
- package/dist/bootstrap.js.map +1 -1
- package/dist/build-provenance.json +2 -2
- package/dist/cloud/nexus-cloud-status.d.ts.map +1 -1
- package/dist/cloud/nexus-cloud-status.js +3 -1
- package/dist/cloud/nexus-cloud-status.js.map +1 -1
- package/dist/cloud/nexus-device.d.ts +1 -1
- package/dist/cloud/nexus-presence-refresh.d.ts.map +1 -1
- package/dist/cloud/nexus-presence-refresh.js +20 -13
- package/dist/cloud/nexus-presence-refresh.js.map +1 -1
- package/dist/cloud/nexus-vault.d.ts.map +1 -1
- package/dist/cloud/nexus-vault.js +4 -1
- package/dist/cloud/nexus-vault.js.map +1 -1
- package/dist/docs/derive-links.d.ts +69 -0
- package/dist/docs/derive-links.d.ts.map +1 -0
- package/dist/docs/derive-links.js +85 -0
- package/dist/docs/derive-links.js.map +1 -0
- package/dist/docs/docs-generator.d.ts.map +1 -1
- package/dist/docs/docs-generator.js +2 -0
- package/dist/docs/docs-generator.js.map +1 -1
- package/dist/docs/docs-update.d.ts.map +1 -1
- package/dist/docs/docs-update.js +24 -4
- package/dist/docs/docs-update.js.map +1 -1
- package/dist/docs/fetch-result.d.ts +77 -0
- package/dist/docs/fetch-result.d.ts.map +1 -0
- package/dist/docs/fetch-result.js +132 -0
- package/dist/docs/fetch-result.js.map +1 -0
- package/dist/docs/supersede.d.ts.map +1 -1
- package/dist/docs/supersede.js +9 -0
- package/dist/docs/supersede.js.map +1 -1
- package/dist/doctor/db-substrate.d.ts.map +1 -1
- package/dist/doctor/db-substrate.js +64 -29
- package/dist/doctor/db-substrate.js.map +1 -1
- package/dist/doctor/row-identity-refill.d.ts.map +1 -1
- package/dist/doctor/row-identity-refill.js +25 -10
- package/dist/doctor/row-identity-refill.js.map +1 -1
- package/dist/doctor/row-identity.d.ts.map +1 -1
- package/dist/doctor/row-identity.js +8 -2
- package/dist/doctor/row-identity.js.map +1 -1
- package/dist/doctor/sync-repair.d.ts +5 -0
- package/dist/doctor/sync-repair.d.ts.map +1 -1
- package/dist/doctor/sync-repair.js +11 -0
- package/dist/doctor/sync-repair.js.map +1 -1
- package/dist/doctor/sync-triggers.d.ts.map +1 -1
- package/dist/doctor/sync-triggers.js +3 -17
- package/dist/doctor/sync-triggers.js.map +1 -1
- package/dist/hygiene/validate-spawn-readiness.d.ts +6 -1
- package/dist/hygiene/validate-spawn-readiness.d.ts.map +1 -1
- package/dist/hygiene/validate-spawn-readiness.js +11 -6
- package/dist/hygiene/validate-spawn-readiness.js.map +1 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +10 -1
- package/dist/init.js.map +1 -1
- package/dist/injection.d.ts +37 -12
- package/dist/injection.d.ts.map +1 -1
- package/dist/injection.js +152 -35
- package/dist/injection.js.map +1 -1
- package/dist/memory/brain-search.d.ts.map +1 -1
- package/dist/memory/brain-search.js +7 -32
- package/dist/memory/brain-search.js.map +1 -1
- package/dist/memory/pipeline-manifest-sqlite.d.ts +2 -0
- package/dist/memory/pipeline-manifest-sqlite.d.ts.map +1 -1
- package/dist/memory/pipeline-manifest-sqlite.js +51 -9
- package/dist/memory/pipeline-manifest-sqlite.js.map +1 -1
- package/dist/nexus/assessment-projection.d.ts +96 -1
- package/dist/nexus/assessment-projection.d.ts.map +1 -1
- package/dist/nexus/assessment-projection.js +135 -0
- package/dist/nexus/assessment-projection.js.map +1 -1
- package/dist/nexus/assessment-store.d.ts +54 -0
- package/dist/nexus/assessment-store.d.ts.map +1 -1
- package/dist/nexus/assessment-store.js +161 -2
- package/dist/nexus/assessment-store.js.map +1 -1
- package/dist/nexus/knowledge.d.ts +19 -0
- package/dist/nexus/knowledge.d.ts.map +1 -1
- package/dist/nexus/knowledge.js +56 -2
- package/dist/nexus/knowledge.js.map +1 -1
- package/dist/orchestrate/spawn-ops.d.ts.map +1 -1
- package/dist/orchestrate/spawn-ops.js +12 -1
- package/dist/orchestrate/spawn-ops.js.map +1 -1
- package/dist/release/commit-presence.d.ts +24 -0
- package/dist/release/commit-presence.d.ts.map +1 -1
- package/dist/release/commit-presence.js +31 -0
- package/dist/release/commit-presence.js.map +1 -1
- package/dist/release/plan.d.ts +8 -6
- package/dist/release/plan.d.ts.map +1 -1
- package/dist/release/plan.js +11 -6
- package/dist/release/plan.js.map +1 -1
- package/dist/release/reconcile.d.ts.map +1 -1
- package/dist/release/reconcile.js +10 -8
- package/dist/release/reconcile.js.map +1 -1
- package/dist/release/verify-provenance.d.ts.map +1 -1
- package/dist/release/verify-provenance.js +6 -8
- package/dist/release/verify-provenance.js.map +1 -1
- package/dist/resources/admission-ledger.d.ts +66 -0
- package/dist/resources/admission-ledger.d.ts.map +1 -1
- package/dist/resources/admission-ledger.js +145 -6
- package/dist/resources/admission-ledger.js.map +1 -1
- package/dist/resources/run-class.d.ts +71 -0
- package/dist/resources/run-class.d.ts.map +1 -1
- package/dist/resources/run-class.js +203 -0
- package/dist/resources/run-class.js.map +1 -1
- package/dist/resources/run-governed.d.ts +2 -0
- package/dist/resources/run-governed.d.ts.map +1 -1
- package/dist/resources/run-governed.js +1 -0
- package/dist/resources/run-governed.js.map +1 -1
- package/dist/scaffold/ensure-config.d.ts +20 -9
- package/dist/scaffold/ensure-config.d.ts.map +1 -1
- package/dist/scaffold/ensure-config.js +56 -23
- package/dist/scaffold/ensure-config.js.map +1 -1
- package/dist/scaffold/ensure-skills.d.ts +10 -0
- package/dist/scaffold/ensure-skills.d.ts.map +1 -1
- package/dist/scaffold/ensure-skills.js +47 -3
- package/dist/scaffold/ensure-skills.js.map +1 -1
- package/dist/scaffold/upgrade-file-journal.d.ts +79 -0
- package/dist/scaffold/upgrade-file-journal.d.ts.map +1 -0
- package/dist/scaffold/upgrade-file-journal.js +111 -0
- package/dist/scaffold/upgrade-file-journal.js.map +1 -0
- package/dist/session/engine-ops.d.ts.map +1 -1
- package/dist/session/engine-ops.js +10 -2
- package/dist/session/engine-ops.js.map +1 -1
- package/dist/sessions/index.d.ts.map +1 -1
- package/dist/sessions/index.js +3 -0
- package/dist/sessions/index.js.map +1 -1
- package/dist/spawn/worktree-lock-holder.d.ts +59 -1
- package/dist/spawn/worktree-lock-holder.d.ts.map +1 -1
- package/dist/spawn/worktree-lock-holder.js +114 -0
- package/dist/spawn/worktree-lock-holder.js.map +1 -1
- package/dist/store/attachment-store.d.ts.map +1 -1
- package/dist/store/attachment-store.js +38 -0
- package/dist/store/attachment-store.js.map +1 -1
- package/dist/store/backup-recover.d.ts +4 -4
- package/dist/store/backup-recover.d.ts.map +1 -1
- package/dist/store/backup-recover.js +11 -4
- package/dist/store/backup-recover.js.map +1 -1
- package/dist/store/backup-sidecar.d.ts +19 -1
- package/dist/store/backup-sidecar.d.ts.map +1 -1
- package/dist/store/backup-sidecar.js +57 -6
- package/dist/store/backup-sidecar.js.map +1 -1
- package/dist/store/db-helpers.js +1 -1
- package/dist/store/display-id-alias.js +1 -1
- package/dist/store/display-id-alias.js.map +1 -1
- package/dist/store/dual-scope-db.d.ts +2 -0
- package/dist/store/dual-scope-db.d.ts.map +1 -1
- package/dist/store/dual-scope-db.js +28 -16
- package/dist/store/dual-scope-db.js.map +1 -1
- package/dist/store/exodus/archive.d.ts +42 -2
- package/dist/store/exodus/archive.d.ts.map +1 -1
- package/dist/store/exodus/archive.js +81 -4
- package/dist/store/exodus/archive.js.map +1 -1
- package/dist/store/exodus/bare-family.d.ts +104 -0
- package/dist/store/exodus/bare-family.d.ts.map +1 -0
- package/dist/store/exodus/bare-family.js +470 -0
- package/dist/store/exodus/bare-family.js.map +1 -0
- package/dist/store/exodus/column-transforms.d.ts.map +1 -1
- package/dist/store/exodus/column-transforms.js +15 -8
- package/dist/store/exodus/column-transforms.js.map +1 -1
- package/dist/store/exodus/health.d.ts +2 -0
- package/dist/store/exodus/health.d.ts.map +1 -1
- package/dist/store/exodus/health.js +7 -1
- package/dist/store/exodus/health.js.map +1 -1
- package/dist/store/exodus/index.d.ts +2 -2
- package/dist/store/exodus/index.d.ts.map +1 -1
- package/dist/store/exodus/index.js +2 -2
- package/dist/store/exodus/index.js.map +1 -1
- package/dist/store/exodus/migrate.d.ts.map +1 -1
- package/dist/store/exodus/migrate.js +30 -1
- package/dist/store/exodus/migrate.js.map +1 -1
- package/dist/store/exodus/on-open.d.ts +11 -0
- package/dist/store/exodus/on-open.d.ts.map +1 -1
- package/dist/store/exodus/on-open.js +26 -1
- package/dist/store/exodus/on-open.js.map +1 -1
- package/dist/store/exodus/prior-recoveries.d.ts +3 -2
- package/dist/store/exodus/prior-recoveries.d.ts.map +1 -1
- package/dist/store/exodus/prior-recoveries.js +7 -3
- package/dist/store/exodus/prior-recoveries.js.map +1 -1
- package/dist/store/exodus/reconcile.d.ts +44 -6
- package/dist/store/exodus/reconcile.d.ts.map +1 -1
- package/dist/store/exodus/reconcile.js +246 -173
- package/dist/store/exodus/reconcile.js.map +1 -1
- package/dist/store/exodus/recovery.d.ts +48 -0
- package/dist/store/exodus/recovery.d.ts.map +1 -1
- package/dist/store/exodus/recovery.js +104 -6
- package/dist/store/exodus/recovery.js.map +1 -1
- package/dist/store/exodus/seal.d.ts.map +1 -1
- package/dist/store/exodus/seal.js +4 -2
- package/dist/store/exodus/seal.js.map +1 -1
- package/dist/store/exodus/table-order.d.ts +6 -0
- package/dist/store/exodus/table-order.d.ts.map +1 -1
- package/dist/store/exodus/table-order.js +15 -0
- package/dist/store/exodus/table-order.js.map +1 -1
- package/dist/store/exodus/types.d.ts +4 -0
- package/dist/store/exodus/types.d.ts.map +1 -1
- package/dist/store/exodus/types.js +4 -0
- package/dist/store/exodus/types.js.map +1 -1
- package/dist/store/exodus/verify-migration.d.ts.map +1 -1
- package/dist/store/exodus/verify-migration.js +22 -17
- package/dist/store/exodus/verify-migration.js.map +1 -1
- package/dist/store/identity-share.d.ts +14 -0
- package/dist/store/identity-share.d.ts.map +1 -1
- package/dist/store/identity-share.js +33 -0
- package/dist/store/identity-share.js.map +1 -1
- package/dist/store/lock.d.ts +33 -0
- package/dist/store/lock.d.ts.map +1 -1
- package/dist/store/lock.js +60 -0
- package/dist/store/lock.js.map +1 -1
- package/dist/store/portable-bundle-import.d.ts.map +1 -1
- package/dist/store/portable-bundle-import.js +7 -0
- package/dist/store/portable-bundle-import.js.map +1 -1
- package/dist/store/portable-bundle-scan.d.ts +3 -2
- package/dist/store/portable-bundle-scan.d.ts.map +1 -1
- package/dist/store/portable-bundle-scan.js +7 -5
- package/dist/store/portable-bundle-scan.js.map +1 -1
- package/dist/store/portable-bundle.d.ts +1 -1
- package/dist/store/portable-bundle.d.ts.map +1 -1
- package/dist/store/portable-bundle.js +9 -1
- package/dist/store/portable-bundle.js.map +1 -1
- package/dist/store/repair-malformed-dbs.d.ts.map +1 -1
- package/dist/store/repair-malformed-dbs.js +36 -6
- package/dist/store/repair-malformed-dbs.js.map +1 -1
- package/dist/store/restore-marker.d.ts +20 -2
- package/dist/store/restore-marker.d.ts.map +1 -1
- package/dist/store/restore-marker.js +41 -1
- package/dist/store/restore-marker.js.map +1 -1
- package/dist/store/row-identity-flag.d.ts +9 -6
- package/dist/store/row-identity-flag.d.ts.map +1 -1
- package/dist/store/row-identity-flag.js +10 -7
- package/dist/store/row-identity-flag.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 +132 -31
- package/dist/store/row-identity-registry.js.map +1 -1
- package/dist/store/row-identity.d.ts +81 -14
- package/dist/store/row-identity.d.ts.map +1 -1
- package/dist/store/row-identity.js +238 -32
- package/dist/store/row-identity.js.map +1 -1
- package/dist/store/schema/cleo-shared/brain.d.ts +368 -0
- package/dist/store/schema/cleo-shared/brain.d.ts.map +1 -1
- package/dist/store/schema/cleo-shared/brain.js +104 -2
- package/dist/store/schema/cleo-shared/brain.js.map +1 -1
- package/dist/store/sync/apply/applier.d.ts +5 -0
- package/dist/store/sync/apply/applier.d.ts.map +1 -1
- package/dist/store/sync/apply/applier.js +5 -1
- package/dist/store/sync/apply/applier.js.map +1 -1
- package/dist/store/sync/apply/parent-delete.d.ts.map +1 -1
- package/dist/store/sync/apply/parent-delete.js +4 -0
- package/dist/store/sync/apply/parent-delete.js.map +1 -1
- package/dist/store/sync/capture.d.ts +13 -1
- package/dist/store/sync/capture.d.ts.map +1 -1
- package/dist/store/sync/capture.js +31 -3
- package/dist/store/sync/capture.js.map +1 -1
- package/dist/store/sync/flags.d.ts +14 -5
- package/dist/store/sync/flags.d.ts.map +1 -1
- package/dist/store/sync/flags.js +20 -8
- package/dist/store/sync/flags.js.map +1 -1
- package/dist/store/sync/genesis.d.ts +130 -0
- package/dist/store/sync/genesis.d.ts.map +1 -0
- package/dist/store/sync/genesis.js +337 -0
- package/dist/store/sync/genesis.js.map +1 -0
- package/dist/store/sync/repair.d.ts +2 -2
- package/dist/store/sync/repair.d.ts.map +1 -1
- package/dist/store/sync/repair.js +55 -15
- package/dist/store/sync/repair.js.map +1 -1
- package/dist/store/sync/sealer.d.ts +14 -0
- package/dist/store/sync/sealer.d.ts.map +1 -1
- package/dist/store/sync/sealer.js +27 -6
- package/dist/store/sync/sealer.js.map +1 -1
- package/dist/store/sync/segments.d.ts +124 -0
- package/dist/store/sync/segments.d.ts.map +1 -0
- package/dist/store/sync/segments.js +267 -0
- package/dist/store/sync/segments.js.map +1 -0
- package/dist/store/sync/sequencing.d.ts +44 -1
- package/dist/store/sync/sequencing.d.ts.map +1 -1
- package/dist/store/sync/sequencing.js +59 -2
- package/dist/store/sync/sequencing.js.map +1 -1
- package/dist/store/sync/timestamp-canon.d.ts +6 -3
- package/dist/store/sync/timestamp-canon.d.ts.map +1 -1
- package/dist/store/sync/timestamp-canon.js +55 -4
- package/dist/store/sync/timestamp-canon.js.map +1 -1
- package/dist/store/sync/txn-signing.d.ts +69 -0
- package/dist/store/sync/txn-signing.d.ts.map +1 -0
- package/dist/store/sync/txn-signing.js +81 -0
- package/dist/store/sync/txn-signing.js.map +1 -0
- package/dist/store/table-classification.d.ts.map +1 -1
- package/dist/store/table-classification.js +30 -0
- 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 +65 -2
- package/dist/store/twin-collapse.js.map +1 -1
- package/dist/system/backup.d.ts +3 -2
- package/dist/system/backup.d.ts.map +1 -1
- package/dist/system/backup.js +43 -17
- package/dist/system/backup.js.map +1 -1
- package/dist/system/health.d.ts.map +1 -1
- package/dist/system/health.js +2 -1
- package/dist/system/health.js.map +1 -1
- package/dist/tasks/affected-packages.d.ts +26 -0
- package/dist/tasks/affected-packages.d.ts.map +1 -1
- package/dist/tasks/affected-packages.js +95 -28
- package/dist/tasks/affected-packages.js.map +1 -1
- package/dist/tasks/change-set.d.ts.map +1 -1
- package/dist/tasks/change-set.js +14 -4
- package/dist/tasks/change-set.js.map +1 -1
- package/dist/tasks/done-plan.d.ts.map +1 -1
- package/dist/tasks/done-plan.js +50 -4
- package/dist/tasks/done-plan.js.map +1 -1
- package/dist/tasks/test-run-binding.d.ts +14 -0
- package/dist/tasks/test-run-binding.d.ts.map +1 -1
- package/dist/tasks/test-run-binding.js +35 -4
- package/dist/tasks/test-run-binding.js.map +1 -1
- package/dist/upgrade.d.ts +6 -0
- package/dist/upgrade.d.ts.map +1 -1
- package/dist/upgrade.js +58 -11
- package/dist/upgrade.js.map +1 -1
- package/migrations/drizzle-cleo-global/20261010120000_t12894-brain-row-uids/migration.sql +88 -0
- package/migrations/drizzle-cleo-project/20261010120000_t12894-brain-row-uids/migration.sql +92 -0
- package/migrations/sync-journal/20261007120000_t12343-segment-outbox/migration.sql +38 -0
- package/package.json +13 -13
- package/templates/CLEO-INJECTION.md +1 -1
- package/templates/CLEO-REFERENCE.md +2 -2
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persist before push: the segment outbox (journal spec §2.8 "Building
|
|
3
|
+
* segments", "Persist before push"; T12343 O-1).
|
|
4
|
+
*
|
|
5
|
+
* Sealed local transactions are packed, in local commit order, into a
|
|
6
|
+
* segment of one stream: `deflate-raw(canonical JSON of LedgerTxn[])` with
|
|
7
|
+
* its plaintext metadata (op count, HLC range, per-table and per-transaction
|
|
8
|
+
* deltas, schema version). The caller's sealer encrypts it (the journal
|
|
9
|
+
* client's `sealSegment`, under the stream key), and ONE local transaction
|
|
10
|
+
* then:
|
|
11
|
+
* - first makes any pre-T13222 partial-group op whole (T13233, T13287), so
|
|
12
|
+
* no segment ever carries one;
|
|
13
|
+
* - inserts the `_sync_segment` row with the exact sealed bytes and their
|
|
14
|
+
* hash, at the next `replicaSeq` of (stream, replica), state `sealed`, and
|
|
15
|
+
* raises the store's persisted replicaSeq high-water mark;
|
|
16
|
+
* - maps every packed transaction to it (`_sync_segment_txn`) and marks it
|
|
17
|
+
* `segmented` (it stays unsequenced until its echo, §3.5);
|
|
18
|
+
* - sets `_sync_row_meta.sent` for every row it carries;
|
|
19
|
+
* - writes the `row_identity_synced` marker if absent (§3.4: uids are about
|
|
20
|
+
* to leave the device).
|
|
21
|
+
*
|
|
22
|
+
* A push sends the persisted bytes, never re-sealed: re-encrypting would
|
|
23
|
+
* change the hash and defeat the server's (replica, hash) idempotency, so a
|
|
24
|
+
* crash at any point resends the same segment or finds it stored.
|
|
25
|
+
*
|
|
26
|
+
* @task T12343
|
|
27
|
+
* @module store/sync/segments
|
|
28
|
+
*/
|
|
29
|
+
import type { DatabaseSync } from 'node:sqlite';
|
|
30
|
+
import type { TableScope } from '@cleocode/contracts';
|
|
31
|
+
import type { TxnDelta } from '@cleocode/contracts/cloud';
|
|
32
|
+
import { type LedgerTxn } from '@cleocode/contracts/ledger';
|
|
33
|
+
import type { SegmentMetaFields } from '../../cloud/signing.js';
|
|
34
|
+
/** Encrypts a segment for one stream (the journal client's `sealSegment`). */
|
|
35
|
+
export type SegmentSealer = (replicaSeq: number, plaintext: Uint8Array, meta: SegmentMetaFields) => Buffer;
|
|
36
|
+
/** What {@link buildSegment} needs. */
|
|
37
|
+
export interface BuildSegmentOptions {
|
|
38
|
+
/** The stream (`project:<id>` or `home:<userId>`). */
|
|
39
|
+
readonly stream: string;
|
|
40
|
+
/** This store's bound replica (the segment's author); only its own transactions are packed. */
|
|
41
|
+
readonly replica: string;
|
|
42
|
+
/** The store's scope (the legacy group pass reads its capture tables). */
|
|
43
|
+
readonly scope: TableScope;
|
|
44
|
+
/** The merge key's project, or null on a home stream. */
|
|
45
|
+
readonly project: string | null;
|
|
46
|
+
readonly sealer: SegmentSealer;
|
|
47
|
+
/** Signs each packed transaction for the stream (§2.8: `signTxn` of txn-signing.ts, with the device key). */
|
|
48
|
+
readonly signTxn: (stream: string, txn: LedgerTxn) => LedgerTxn;
|
|
49
|
+
readonly nowIso: string;
|
|
50
|
+
/** Stop packing once the canonical JSON passes this many bytes (one txn always goes in). */
|
|
51
|
+
readonly maxPlaintextBytes?: number;
|
|
52
|
+
}
|
|
53
|
+
/** A persisted segment, as push reads it. */
|
|
54
|
+
export interface PersistedSegment {
|
|
55
|
+
readonly stream: string;
|
|
56
|
+
readonly replica: string;
|
|
57
|
+
readonly replicaSeq: number;
|
|
58
|
+
readonly meta: SegmentMetaFields;
|
|
59
|
+
readonly sealed: Buffer;
|
|
60
|
+
readonly segmentHash: string;
|
|
61
|
+
readonly state: 'sealed' | 'pushed';
|
|
62
|
+
readonly serverSeq: number | null;
|
|
63
|
+
/** The transactions it carries, in order. */
|
|
64
|
+
readonly txns: readonly string[];
|
|
65
|
+
}
|
|
66
|
+
/** Default plaintext budget: comfortably under the 1 MiB inline ciphertext limit once deflated. */
|
|
67
|
+
export declare const SEGMENT_PLAINTEXT_BUDGET: number;
|
|
68
|
+
/**
|
|
69
|
+
* The segment metadata of `txns` (§2.8): op count, HLC range over every
|
|
70
|
+
* transaction and op, per-table deltas and per-transaction deltas
|
|
71
|
+
* (segment/v3), at this build's sync schema version.
|
|
72
|
+
*
|
|
73
|
+
* @param txns - The transactions, in segment order.
|
|
74
|
+
* @returns The metadata.
|
|
75
|
+
*/
|
|
76
|
+
export declare function segmentMetaOf(txns: readonly LedgerTxn[]): SegmentMetaFields & {
|
|
77
|
+
txnDeltas: TxnDelta[];
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* The plaintext of a segment: `deflate-raw` of the canonical JSON of its
|
|
81
|
+
* transactions (§2.8).
|
|
82
|
+
*
|
|
83
|
+
* @param txns - The transactions, in segment order.
|
|
84
|
+
* @returns The bytes the stream key encrypts.
|
|
85
|
+
*/
|
|
86
|
+
export declare function segmentPlaintext(txns: readonly LedgerTxn[]): Buffer;
|
|
87
|
+
/**
|
|
88
|
+
* Pack the next sealed transactions into one segment of `stream`, seal it,
|
|
89
|
+
* and persist it before any push (§2.8). Opens its own `BEGIN IMMEDIATE`, so
|
|
90
|
+
* it must run outside a transaction and outside any frame. Only `replica`'s
|
|
91
|
+
* own transactions are packed, and packing stops before a transaction that
|
|
92
|
+
* still carries a partial merge group. The caller advances the device
|
|
93
|
+
* registry's high-water mark after this commits.
|
|
94
|
+
*
|
|
95
|
+
* @param db - The store.
|
|
96
|
+
* @param o - Stream, replica, project, sealer and clock.
|
|
97
|
+
* @returns The persisted segment, or null when nothing is waiting.
|
|
98
|
+
*/
|
|
99
|
+
export declare function buildSegment(db: DatabaseSync, o: BuildSegmentOptions): PersistedSegment | null;
|
|
100
|
+
/**
|
|
101
|
+
* The persisted segments of `stream` not yet acknowledged by the server, in
|
|
102
|
+
* `replicaSeq` order (push sends the lowest first, one at a time).
|
|
103
|
+
*
|
|
104
|
+
* @param db - The store.
|
|
105
|
+
* @param stream - The stream.
|
|
106
|
+
* @param replica - This store's replica.
|
|
107
|
+
* @returns The unpushed segments.
|
|
108
|
+
*/
|
|
109
|
+
export declare function unpushedSegments(db: DatabaseSync, stream: string, replica: string): PersistedSegment[];
|
|
110
|
+
/**
|
|
111
|
+
* Record that the server stored a segment (a new append or a duplicate):
|
|
112
|
+
* its stream `seq`.
|
|
113
|
+
*
|
|
114
|
+
* @param db - The store.
|
|
115
|
+
* @param s - The segment and the server's seq.
|
|
116
|
+
*/
|
|
117
|
+
export declare function markSegmentPushed(db: DatabaseSync, s: {
|
|
118
|
+
readonly stream: string;
|
|
119
|
+
readonly replica: string;
|
|
120
|
+
readonly replicaSeq: number;
|
|
121
|
+
readonly serverSeq: number;
|
|
122
|
+
readonly nowIso: string;
|
|
123
|
+
}): void;
|
|
124
|
+
//# sourceMappingURL=segments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"segments.d.ts","sourceRoot":"","sources":["../../../src/store/sync/segments.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAe,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAyB,KAAK,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAEnF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAOhE,8EAA8E;AAC9E,MAAM,MAAM,aAAa,GAAG,CAC1B,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,UAAU,EACrB,IAAI,EAAE,iBAAiB,KACpB,MAAM,CAAC;AAEZ,uCAAuC;AACvC,MAAM,WAAW,mBAAmB;IAClC,sDAAsD;IACtD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+FAA+F;IAC/F,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,yDAAyD;IACzD,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,6GAA6G;IAC7G,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,KAAK,SAAS,CAAC;IAChE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,4FAA4F;IAC5F,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC;AAED,6CAA6C;AAC7C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,QAAQ,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAED,mGAAmG;AACnG,eAAO,MAAM,wBAAwB,QAAa,CAAC;AA8DnD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,SAAS,SAAS,EAAE,GACzB,iBAAiB,GAAG;IAAE,SAAS,EAAE,QAAQ,EAAE,CAAA;CAAE,CAW/C;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,GAAG,MAAM,CAEnE;AAiBD;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,YAAY,EAAE,CAAC,EAAE,mBAAmB,GAAG,gBAAgB,GAAG,IAAI,CAgF9F;AAkDD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,YAAY,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,gBAAgB,EAAE,CASpB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,YAAY,EAChB,CAAC,EAAE;IACD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,GACA,IAAI,CAKN"}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persist before push: the segment outbox (journal spec §2.8 "Building
|
|
3
|
+
* segments", "Persist before push"; T12343 O-1).
|
|
4
|
+
*
|
|
5
|
+
* Sealed local transactions are packed, in local commit order, into a
|
|
6
|
+
* segment of one stream: `deflate-raw(canonical JSON of LedgerTxn[])` with
|
|
7
|
+
* its plaintext metadata (op count, HLC range, per-table and per-transaction
|
|
8
|
+
* deltas, schema version). The caller's sealer encrypts it (the journal
|
|
9
|
+
* client's `sealSegment`, under the stream key), and ONE local transaction
|
|
10
|
+
* then:
|
|
11
|
+
* - first makes any pre-T13222 partial-group op whole (T13233, T13287), so
|
|
12
|
+
* no segment ever carries one;
|
|
13
|
+
* - inserts the `_sync_segment` row with the exact sealed bytes and their
|
|
14
|
+
* hash, at the next `replicaSeq` of (stream, replica), state `sealed`, and
|
|
15
|
+
* raises the store's persisted replicaSeq high-water mark;
|
|
16
|
+
* - maps every packed transaction to it (`_sync_segment_txn`) and marks it
|
|
17
|
+
* `segmented` (it stays unsequenced until its echo, §3.5);
|
|
18
|
+
* - sets `_sync_row_meta.sent` for every row it carries;
|
|
19
|
+
* - writes the `row_identity_synced` marker if absent (§3.4: uids are about
|
|
20
|
+
* to leave the device).
|
|
21
|
+
*
|
|
22
|
+
* A push sends the persisted bytes, never re-sealed: re-encrypting would
|
|
23
|
+
* change the hash and defeat the server's (replica, hash) idempotency, so a
|
|
24
|
+
* crash at any point resends the same segment or finds it stored.
|
|
25
|
+
*
|
|
26
|
+
* @task T12343
|
|
27
|
+
* @module store/sync/segments
|
|
28
|
+
*/
|
|
29
|
+
import { createHash } from 'node:crypto';
|
|
30
|
+
import { deflateRawSync } from 'node:zlib';
|
|
31
|
+
import { LedgerActor, LedgerOp } from '@cleocode/contracts/ledger';
|
|
32
|
+
import { SYNC_SCHEMA_VERSION } from '@cleocode/contracts/sync-schema.js';
|
|
33
|
+
import { ROW_IDENTITY_META_TABLE, ROW_IDENTITY_SYNCED_KEY } from '../row-identity.js';
|
|
34
|
+
import { persistStoreSeq, storeHwm } from './replica.js';
|
|
35
|
+
import { hasTable } from './schema.js';
|
|
36
|
+
import { completeLegacyGroupsBeforePack } from './sealer.js';
|
|
37
|
+
import { canonicalJson } from './sealer-values.js';
|
|
38
|
+
/** Default plaintext budget: comfortably under the 1 MiB inline ciphertext limit once deflated. */
|
|
39
|
+
export const SEGMENT_PLAINTEXT_BUDGET = 512 * 1024;
|
|
40
|
+
/** The server's cap on transactions per segment (`MAX_TXNS_PER_SEGMENT`). */
|
|
41
|
+
const MAX_TXNS_PER_SEGMENT = 10_000;
|
|
42
|
+
/** A sealed local transaction as the wire carries it, before {@link BuildSegmentOptions.signTxn} signs it. */
|
|
43
|
+
function ledgerTxnOf(db, row, project) {
|
|
44
|
+
let actor = null;
|
|
45
|
+
if (row.actor?.startsWith('{')) {
|
|
46
|
+
const parsed = LedgerActor.safeParse(JSON.parse(row.actor));
|
|
47
|
+
if (parsed.success)
|
|
48
|
+
actor = parsed.data;
|
|
49
|
+
}
|
|
50
|
+
const ops = db.prepare('SELECT body FROM _sync_op WHERE txn = ? ORDER BY idx').all(row.txn).map((o) => LedgerOp.parse(JSON.parse(o.body)));
|
|
51
|
+
return {
|
|
52
|
+
v: 1,
|
|
53
|
+
txn: row.txn,
|
|
54
|
+
hlc: row.hlc,
|
|
55
|
+
project,
|
|
56
|
+
scope: row.scope === 'global' ? 'global' : 'project',
|
|
57
|
+
via: row.via,
|
|
58
|
+
kind: row.kind,
|
|
59
|
+
actor,
|
|
60
|
+
ops,
|
|
61
|
+
sig: '',
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** Per-table created/deleted counts of ops (an I creates, a D deletes; U and K count as neither). */
|
|
65
|
+
function deltasOf(ops) {
|
|
66
|
+
const out = {};
|
|
67
|
+
for (const op of ops) {
|
|
68
|
+
if (op.o !== 'I' && op.o !== 'D')
|
|
69
|
+
continue;
|
|
70
|
+
const d = out[op.t] ?? { created: 0, deleted: 0 };
|
|
71
|
+
out[op.t] = d;
|
|
72
|
+
if (op.o === 'I')
|
|
73
|
+
d.created += 1;
|
|
74
|
+
else
|
|
75
|
+
d.deleted += 1;
|
|
76
|
+
}
|
|
77
|
+
return out;
|
|
78
|
+
}
|
|
79
|
+
/** Sum per-transaction deltas into the segment's deltas. */
|
|
80
|
+
function sumDeltas(parts) {
|
|
81
|
+
const out = {};
|
|
82
|
+
for (const p of parts) {
|
|
83
|
+
for (const [t, d] of Object.entries(p)) {
|
|
84
|
+
const s = out[t] ?? { created: 0, deleted: 0 };
|
|
85
|
+
out[t] = s;
|
|
86
|
+
s.created += d.created;
|
|
87
|
+
s.deleted += d.deleted;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return out;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* The segment metadata of `txns` (§2.8): op count, HLC range over every
|
|
94
|
+
* transaction and op, per-table deltas and per-transaction deltas
|
|
95
|
+
* (segment/v3), at this build's sync schema version.
|
|
96
|
+
*
|
|
97
|
+
* @param txns - The transactions, in segment order.
|
|
98
|
+
* @returns The metadata.
|
|
99
|
+
*/
|
|
100
|
+
export function segmentMetaOf(txns) {
|
|
101
|
+
const hlcs = txns.flatMap((t) => [t.hlc, ...t.ops.map((o) => o.h)]).sort();
|
|
102
|
+
const txnDeltas = txns.map((t, i) => ({ txn: i, deltas: deltasOf(t.ops) }));
|
|
103
|
+
return {
|
|
104
|
+
schemaVersion: SYNC_SCHEMA_VERSION,
|
|
105
|
+
opCount: txns.reduce((n, t) => n + t.ops.length, 0),
|
|
106
|
+
hlcMin: hlcs[0],
|
|
107
|
+
hlcMax: hlcs[hlcs.length - 1],
|
|
108
|
+
deltas: sumDeltas(txnDeltas.map((t) => t.deltas)),
|
|
109
|
+
txnDeltas,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* The plaintext of a segment: `deflate-raw` of the canonical JSON of its
|
|
114
|
+
* transactions (§2.8).
|
|
115
|
+
*
|
|
116
|
+
* @param txns - The transactions, in segment order.
|
|
117
|
+
* @returns The bytes the stream key encrypts.
|
|
118
|
+
*/
|
|
119
|
+
export function segmentPlaintext(txns) {
|
|
120
|
+
return deflateRawSync(Buffer.from(canonicalJson(txns), 'utf8'));
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* The next `replicaSeq` of (stream, replica): one past the persisted
|
|
124
|
+
* high-water mark ({@link storeHwm}), or past the newest outbox row if that
|
|
125
|
+
* is higher; 0 for the first. The mark outlives the outbox rows, so a seq is
|
|
126
|
+
* never handed out twice once its segment row is pruned (T13287).
|
|
127
|
+
*/
|
|
128
|
+
function nextReplicaSeq(db, stream, replica) {
|
|
129
|
+
const hwm = storeHwm(db, replica)[stream];
|
|
130
|
+
const row = db
|
|
131
|
+
.prepare('SELECT max(replica_seq) AS s FROM _sync_segment WHERE stream = ? AND replica_id = ?')
|
|
132
|
+
.get(stream, replica);
|
|
133
|
+
const last = Math.max(hwm ?? -1, row.s === null ? -1 : Number(row.s));
|
|
134
|
+
return last + 1;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Pack the next sealed transactions into one segment of `stream`, seal it,
|
|
138
|
+
* and persist it before any push (§2.8). Opens its own `BEGIN IMMEDIATE`, so
|
|
139
|
+
* it must run outside a transaction and outside any frame. Only `replica`'s
|
|
140
|
+
* own transactions are packed, and packing stops before a transaction that
|
|
141
|
+
* still carries a partial merge group. The caller advances the device
|
|
142
|
+
* registry's high-water mark after this commits.
|
|
143
|
+
*
|
|
144
|
+
* @param db - The store.
|
|
145
|
+
* @param o - Stream, replica, project, sealer and clock.
|
|
146
|
+
* @returns The persisted segment, or null when nothing is waiting.
|
|
147
|
+
*/
|
|
148
|
+
export function buildSegment(db, o) {
|
|
149
|
+
const budget = o.maxPlaintextBytes ?? SEGMENT_PLAINTEXT_BUDGET;
|
|
150
|
+
db.exec('BEGIN IMMEDIATE');
|
|
151
|
+
try {
|
|
152
|
+
// T13287: complete pre-T13222 partial groups before anything is packed.
|
|
153
|
+
const partial = completeLegacyGroupsBeforePack(db, o.scope, o.nowIso);
|
|
154
|
+
const rows = db
|
|
155
|
+
.prepare(`SELECT txn, hlc, scope, via, kind, actor FROM _sync_txn
|
|
156
|
+
WHERE state = 'sealed' AND replica = ? ORDER BY local_seq LIMIT ?`)
|
|
157
|
+
.all(o.replica, MAX_TXNS_PER_SEGMENT);
|
|
158
|
+
const txns = [];
|
|
159
|
+
let bytes = 0;
|
|
160
|
+
for (const r of rows) {
|
|
161
|
+
// Commit order is kept: nothing after a still-partial txn goes either.
|
|
162
|
+
if (partial.has(r.txn))
|
|
163
|
+
break;
|
|
164
|
+
const t = o.signTxn(o.stream, ledgerTxnOf(db, r, o.project));
|
|
165
|
+
const size = Buffer.byteLength(canonicalJson(t), 'utf8');
|
|
166
|
+
if (txns.length > 0 && bytes + size > budget)
|
|
167
|
+
break;
|
|
168
|
+
txns.push(t);
|
|
169
|
+
bytes += size;
|
|
170
|
+
}
|
|
171
|
+
if (txns.length === 0) {
|
|
172
|
+
db.exec('COMMIT');
|
|
173
|
+
const blocked = rows[0]?.txn;
|
|
174
|
+
if (blocked !== undefined && partial.has(blocked)) {
|
|
175
|
+
// @sync-invariant none:local-only a sealed op this build cannot make group-whole is never pushed partial
|
|
176
|
+
throw new Error(`sealed transaction ${blocked} carries a partial merge group that cannot be completed; it is not packed (T13287)`);
|
|
177
|
+
}
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
const replicaSeq = nextReplicaSeq(db, o.stream, o.replica);
|
|
181
|
+
const meta = segmentMetaOf(txns);
|
|
182
|
+
const sealed = o.sealer(replicaSeq, segmentPlaintext(txns), meta);
|
|
183
|
+
const segmentHash = createHash('sha256').update(sealed).digest('hex');
|
|
184
|
+
db.prepare(`INSERT INTO _sync_segment (stream, replica_id, replica_seq, meta_json, sealed, segment_hash, state, created_at)
|
|
185
|
+
VALUES (?, ?, ?, ?, ?, ?, 'sealed', ?)`).run(o.stream, o.replica, replicaSeq, canonicalJson(meta), sealed, segmentHash, o.nowIso);
|
|
186
|
+
const map = db.prepare('INSERT INTO _sync_segment_txn (stream, replica_id, replica_seq, idx, txn) VALUES (?, ?, ?, ?, ?)');
|
|
187
|
+
const mark = db.prepare("UPDATE _sync_txn SET state = 'segmented' WHERE txn = ?");
|
|
188
|
+
const sent = db.prepare('UPDATE _sync_row_meta SET sent = 1 WHERE tbl = ? AND uid = ?');
|
|
189
|
+
txns.forEach((t, i) => {
|
|
190
|
+
map.run(o.stream, o.replica, replicaSeq, i, t.txn);
|
|
191
|
+
mark.run(t.txn);
|
|
192
|
+
for (const op of t.ops) {
|
|
193
|
+
sent.run(op.t, op.u);
|
|
194
|
+
if (op.o === 'K' && op.nu)
|
|
195
|
+
sent.run(op.t, op.nu);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
markRowIdentitySynced(db, o.replica, o.stream, o.nowIso);
|
|
199
|
+
persistStoreSeq(db, o.replica, o.stream, replicaSeq, new Date(o.nowIso));
|
|
200
|
+
db.exec('COMMIT');
|
|
201
|
+
return {
|
|
202
|
+
stream: o.stream,
|
|
203
|
+
replica: o.replica,
|
|
204
|
+
replicaSeq,
|
|
205
|
+
meta,
|
|
206
|
+
sealed,
|
|
207
|
+
segmentHash,
|
|
208
|
+
state: 'sealed',
|
|
209
|
+
serverSeq: null,
|
|
210
|
+
txns: txns.map((t) => t.txn),
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
catch (err) {
|
|
214
|
+
if (db.isTransaction)
|
|
215
|
+
db.exec('ROLLBACK');
|
|
216
|
+
throw err;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/** Write `row_identity_synced` once, before the first uid leaves the device (§3.4). */
|
|
220
|
+
function markRowIdentitySynced(db, replica, stream, nowIso) {
|
|
221
|
+
if (!hasTable(db, ROW_IDENTITY_META_TABLE))
|
|
222
|
+
return;
|
|
223
|
+
db.prepare(`INSERT INTO main.${ROW_IDENTITY_META_TABLE} (key, value) VALUES (?, ?) ON CONFLICT (key) DO NOTHING`).run(ROW_IDENTITY_SYNCED_KEY, JSON.stringify({ at: nowIso, replicaId: replica, stream, reason: 'send' }));
|
|
224
|
+
}
|
|
225
|
+
function toSegment(db, r) {
|
|
226
|
+
const txns = db
|
|
227
|
+
.prepare('SELECT txn FROM _sync_segment_txn WHERE stream = ? AND replica_id = ? AND replica_seq = ? ORDER BY idx')
|
|
228
|
+
.all(r.stream, r.replica_id, r.replica_seq).map((t) => t.txn);
|
|
229
|
+
return {
|
|
230
|
+
stream: r.stream,
|
|
231
|
+
replica: r.replica_id,
|
|
232
|
+
replicaSeq: Number(r.replica_seq),
|
|
233
|
+
meta: JSON.parse(r.meta_json),
|
|
234
|
+
sealed: Buffer.from(r.sealed),
|
|
235
|
+
segmentHash: r.segment_hash,
|
|
236
|
+
state: r.state === 'pushed' ? 'pushed' : 'sealed',
|
|
237
|
+
serverSeq: r.server_seq === null ? null : Number(r.server_seq),
|
|
238
|
+
txns,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* The persisted segments of `stream` not yet acknowledged by the server, in
|
|
243
|
+
* `replicaSeq` order (push sends the lowest first, one at a time).
|
|
244
|
+
*
|
|
245
|
+
* @param db - The store.
|
|
246
|
+
* @param stream - The stream.
|
|
247
|
+
* @param replica - This store's replica.
|
|
248
|
+
* @returns The unpushed segments.
|
|
249
|
+
*/
|
|
250
|
+
export function unpushedSegments(db, stream, replica) {
|
|
251
|
+
return db
|
|
252
|
+
.prepare(`SELECT stream, replica_id, replica_seq, meta_json, sealed, segment_hash, state, server_seq
|
|
253
|
+
FROM _sync_segment WHERE stream = ? AND replica_id = ? AND state = 'sealed' ORDER BY replica_seq`)
|
|
254
|
+
.all(stream, replica).map((r) => toSegment(db, r));
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Record that the server stored a segment (a new append or a duplicate):
|
|
258
|
+
* its stream `seq`.
|
|
259
|
+
*
|
|
260
|
+
* @param db - The store.
|
|
261
|
+
* @param s - The segment and the server's seq.
|
|
262
|
+
*/
|
|
263
|
+
export function markSegmentPushed(db, s) {
|
|
264
|
+
db.prepare(`UPDATE _sync_segment SET state = 'pushed', server_seq = ?, pushed_at = ?
|
|
265
|
+
WHERE stream = ? AND replica_id = ? AND replica_seq = ?`).run(s.serverSeq, s.nowIso, s.stream, s.replica, s.replicaSeq);
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=segments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"segments.js","sourceRoot":"","sources":["../../../src/store/sync/segments.ts"],"names":[],"mappings":"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"}
|
|
@@ -66,7 +66,7 @@ export declare function capturePosition(db: DatabaseSync): number;
|
|
|
66
66
|
* undo seq. Joins through the `_sync_txn_frame` index (T13260), since it
|
|
67
67
|
* runs on every echo and foreign apply under the write lock.
|
|
68
68
|
*/
|
|
69
|
-
export declare const OLDEST_UNSEQUENCED_SQL = "SELECT min(u.seq) AS p FROM _sync_undo u JOIN _sync_txn t ON t.frame = u.txn_local\n WHERE t.state
|
|
69
|
+
export declare const OLDEST_UNSEQUENCED_SQL = "SELECT min(u.seq) AS p FROM _sync_undo u JOIN _sync_txn t ON t.frame = u.txn_local\n WHERE t.state IN ('sealed', 'segmented') AND NOT EXISTS (SELECT 1 FROM _sync_sequenced s WHERE s.txn = t.txn)";
|
|
70
70
|
/**
|
|
71
71
|
* Drop the undo of frames sealed into no transaction (netted away, or
|
|
72
72
|
* inherited/folded) that hold no live capture. Probes `_sync_txn` through
|
|
@@ -172,4 +172,47 @@ export declare function readRowUndo(db: DatabaseSync, txn: string, idx: number):
|
|
|
172
172
|
* @param values - The wire values the op is about to overwrite.
|
|
173
173
|
*/
|
|
174
174
|
export declare function resnapshotRowUndo(db: DatabaseSync, txn: string, idx: number, tbl: string, uid: string, values: Readonly<Record<string, LedgerWireValue>>): void;
|
|
175
|
+
/** Undo a store may hold before it warns and schedules a rebind (§3.5 Rule 2, C1). */
|
|
176
|
+
export declare const UNDO_BUDGET_BYTES: number;
|
|
177
|
+
/** The share of {@link UNDO_BUDGET_BYTES} at which `cleo doctor` and status warn. */
|
|
178
|
+
export declare const UNDO_BUDGET_WARN_RATIO = 0.8;
|
|
179
|
+
/**
|
|
180
|
+
* `_sync_meta` key set (to when) the first time undo reached its budget: the
|
|
181
|
+
* persistent `undo_budget_exceeded` warning, and the rebind it schedules for
|
|
182
|
+
* the next pull to head (D5). Only that rebind clears it.
|
|
183
|
+
*/
|
|
184
|
+
export declare const UNDO_BUDGET_EXCEEDED_KEY = "sync.undo_budget_exceeded";
|
|
185
|
+
/** How much undo a store holds against its budget (§3.5 Rule 2, D5). */
|
|
186
|
+
export interface UndoBudget {
|
|
187
|
+
/**
|
|
188
|
+
* Undo payload bytes (`_sync_undo` images plus `_sync_row_undo` snapshots),
|
|
189
|
+
* by `octet_length()`: the stored size, read without decoding the text.
|
|
190
|
+
*/
|
|
191
|
+
readonly bytes: number;
|
|
192
|
+
readonly budget: number;
|
|
193
|
+
/** `warn` from 80%; `exceeded` at 100% or once it has been (persistent). */
|
|
194
|
+
readonly state: 'ok' | 'warn' | 'exceeded';
|
|
195
|
+
/** When undo first reached the budget, or null. A rebind is scheduled from then. */
|
|
196
|
+
readonly exceededAt: string | null;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* The store's undo against its budget. Read-only (a snapshot is fine).
|
|
200
|
+
* Undo is never stopped: at 100% the replica keeps writing it, warns, and
|
|
201
|
+
* rebinds at the next pull to head (D5).
|
|
202
|
+
*
|
|
203
|
+
* @param db - The store.
|
|
204
|
+
* @param budget - The budget in bytes. @defaultValue UNDO_BUDGET_BYTES
|
|
205
|
+
* @returns The bytes held, the budget and the warning state.
|
|
206
|
+
*/
|
|
207
|
+
export declare function undoBudget(db: DatabaseSync, budget?: number): UndoBudget;
|
|
208
|
+
/**
|
|
209
|
+
* {@link undoBudget}, persisting the `undo_budget_exceeded` warning the first
|
|
210
|
+
* time undo reaches the budget (a pull's check; D5).
|
|
211
|
+
*
|
|
212
|
+
* @param db - The store, outside a transaction.
|
|
213
|
+
* @param nowIso - Now (ISO-8601).
|
|
214
|
+
* @param budget - The budget in bytes. @defaultValue UNDO_BUDGET_BYTES
|
|
215
|
+
* @returns The budget state after recording.
|
|
216
|
+
*/
|
|
217
|
+
export declare function recordUndoBudget(db: DatabaseSync, nowIso: string, budget?: number): UndoBudget;
|
|
175
218
|
//# sourceMappingURL=sequencing.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sequencing.d.ts","sourceRoot":"","sources":["../../../src/store/sync/sequencing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,4BAA4B,CAAC;AACzF,OAAO,EAEL,KAAK,kBAAkB,EAGxB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"sequencing.d.ts","sourceRoot":"","sources":["../../../src/store/sync/sequencing.ts"],"names":[],"mappings":"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"}
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
import { LedgerActor, LedgerOp } from '@cleocode/contracts/ledger';
|
|
33
33
|
import { actorOpOf, readFieldFrontiers, readFieldLeaves, } from './field-leave.js';
|
|
34
34
|
import { readRowMetaFull } from './row-meta.js';
|
|
35
|
+
import { hasTable } from './schema.js';
|
|
35
36
|
import { canonicalJson } from './sealer-values.js';
|
|
36
37
|
/** The foreign-touch index's bound (spec R7-6). */
|
|
37
38
|
export const FOREIGN_TOUCH_MAX = 200_000;
|
|
@@ -76,7 +77,7 @@ export function capturePosition(db) {
|
|
|
76
77
|
* runs on every echo and foreign apply under the write lock.
|
|
77
78
|
*/
|
|
78
79
|
export const OLDEST_UNSEQUENCED_SQL = `SELECT min(u.seq) AS p FROM _sync_undo u JOIN _sync_txn t ON t.frame = u.txn_local
|
|
79
|
-
WHERE t.state
|
|
80
|
+
WHERE t.state IN ('sealed', 'segmented') AND NOT EXISTS (SELECT 1 FROM _sync_sequenced s WHERE s.txn = t.txn)`;
|
|
80
81
|
/**
|
|
81
82
|
* Drop the undo of frames sealed into no transaction (netted away, or
|
|
82
83
|
* inherited/folded) that hold no live capture. Probes `_sync_txn` through
|
|
@@ -221,7 +222,7 @@ export function markSequenced(db, local, at) {
|
|
|
221
222
|
export function unsequencedLocalTxns(db) {
|
|
222
223
|
const txns = db
|
|
223
224
|
.prepare(`SELECT t.txn, t.frame, t.actor FROM _sync_txn t
|
|
224
|
-
WHERE t.state
|
|
225
|
+
WHERE t.state IN ('sealed', 'segmented') AND NOT EXISTS (SELECT 1 FROM _sync_sequenced s WHERE s.txn = t.txn)
|
|
225
226
|
ORDER BY t.local_seq`)
|
|
226
227
|
.all();
|
|
227
228
|
const ops = db.prepare('SELECT body FROM _sync_op WHERE txn = ? ORDER BY idx');
|
|
@@ -292,4 +293,60 @@ export function resnapshotRowUndo(db, txn, idx, tbl, uid, values) {
|
|
|
292
293
|
ON CONFLICT (txn, idx) DO UPDATE SET meta_json = excluded.meta_json,
|
|
293
294
|
leave_json = excluded.leave_json, values_json = excluded.values_json`).run(txn, idx, tbl, uid, meta ? canonicalJson(meta) : null, state, canonicalJson(values));
|
|
294
295
|
}
|
|
296
|
+
/** Undo a store may hold before it warns and schedules a rebind (§3.5 Rule 2, C1). */
|
|
297
|
+
export const UNDO_BUDGET_BYTES = 256 * 1024 * 1024;
|
|
298
|
+
/** The share of {@link UNDO_BUDGET_BYTES} at which `cleo doctor` and status warn. */
|
|
299
|
+
export const UNDO_BUDGET_WARN_RATIO = 0.8;
|
|
300
|
+
/**
|
|
301
|
+
* `_sync_meta` key set (to when) the first time undo reached its budget: the
|
|
302
|
+
* persistent `undo_budget_exceeded` warning, and the rebind it schedules for
|
|
303
|
+
* the next pull to head (D5). Only that rebind clears it.
|
|
304
|
+
*/
|
|
305
|
+
export const UNDO_BUDGET_EXCEEDED_KEY = 'sync.undo_budget_exceeded';
|
|
306
|
+
/**
|
|
307
|
+
* The store's undo against its budget. Read-only (a snapshot is fine).
|
|
308
|
+
* Undo is never stopped: at 100% the replica keeps writing it, warns, and
|
|
309
|
+
* rebinds at the next pull to head (D5).
|
|
310
|
+
*
|
|
311
|
+
* @param db - The store.
|
|
312
|
+
* @param budget - The budget in bytes. @defaultValue UNDO_BUDGET_BYTES
|
|
313
|
+
* @returns The bytes held, the budget and the warning state.
|
|
314
|
+
*/
|
|
315
|
+
export function undoBudget(db, budget = UNDO_BUDGET_BYTES) {
|
|
316
|
+
const sum = (sql) => Number(db.prepare(sql).get().n ?? 0);
|
|
317
|
+
const bytes = (hasTable(db, '_sync_undo')
|
|
318
|
+
? sum(`SELECT sum(octet_length(tbl) + octet_length(rk) + coalesce(octet_length(uid), 0)
|
|
319
|
+
+ coalesce(octet_length(before_full), 0) + coalesce(octet_length(after_full), 0)) AS n FROM _sync_undo`)
|
|
320
|
+
: 0) +
|
|
321
|
+
(hasTable(db, '_sync_row_undo')
|
|
322
|
+
? sum(`SELECT sum(octet_length(tbl) + octet_length(uid) + coalesce(octet_length(meta_json), 0)
|
|
323
|
+
+ coalesce(octet_length(leave_json), 0) + coalesce(octet_length(values_json), 0)
|
|
324
|
+
+ coalesce(octet_length(kept_json), 0)) AS n FROM _sync_row_undo`)
|
|
325
|
+
: 0);
|
|
326
|
+
const flagged = hasTable(db, '_sync_meta')
|
|
327
|
+
? (db.prepare('SELECT value FROM _sync_meta WHERE key = ?').get(UNDO_BUDGET_EXCEEDED_KEY)?.value ?? null)
|
|
328
|
+
: null;
|
|
329
|
+
const state = flagged !== null || bytes >= budget
|
|
330
|
+
? 'exceeded'
|
|
331
|
+
: bytes >= budget * UNDO_BUDGET_WARN_RATIO
|
|
332
|
+
? 'warn'
|
|
333
|
+
: 'ok';
|
|
334
|
+
return { bytes, budget, state, exceededAt: flagged };
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* {@link undoBudget}, persisting the `undo_budget_exceeded` warning the first
|
|
338
|
+
* time undo reaches the budget (a pull's check; D5).
|
|
339
|
+
*
|
|
340
|
+
* @param db - The store, outside a transaction.
|
|
341
|
+
* @param nowIso - Now (ISO-8601).
|
|
342
|
+
* @param budget - The budget in bytes. @defaultValue UNDO_BUDGET_BYTES
|
|
343
|
+
* @returns The budget state after recording.
|
|
344
|
+
*/
|
|
345
|
+
export function recordUndoBudget(db, nowIso, budget = UNDO_BUDGET_BYTES) {
|
|
346
|
+
const now = undoBudget(db, budget);
|
|
347
|
+
if (now.exceededAt !== null || now.bytes < budget)
|
|
348
|
+
return now;
|
|
349
|
+
db.prepare(`INSERT INTO _sync_meta (key, value, updated_at) VALUES (?, ?, ?) ON CONFLICT (key) DO NOTHING`).run(UNDO_BUDGET_EXCEEDED_KEY, nowIso, nowIso);
|
|
350
|
+
return { ...now, exceededAt: nowIso };
|
|
351
|
+
}
|
|
295
352
|
//# sourceMappingURL=sequencing.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sequencing.js","sourceRoot":"","sources":["../../../src/store/sync/sequencing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGH,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAwB,MAAM,4BAA4B,CAAC;AACzF,OAAO,EACL,SAAS,EAET,kBAAkB,EAClB,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAoB,eAAe,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,mDAAmD;AACnD,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC;AAEzC,+EAA+E;AAC/E,MAAM,CAAC,MAAM,4BAA4B,GAAG,+BAA+B,CAAC;AAQ5E,gFAAgF;AAChF,MAAM,UAAU,WAAW,CAAC,EAAgB;IAC1C,OAAO,EAAE,CAAC,OAAO,CAAC,qDAAqD,CAAC,CAAC,GAAG,EAAE,KAAK,SAAS,CAAC;AAC/F,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAC7B,EAAgB,EAChB,GAAW,EACX,GAAW,EACX,GAAW,EACX,GAAW;IAEX,MAAM,IAAI,GAAG,eAAe,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,eAAe,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,kBAAkB,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACnD,MAAM,KAAK,GACT,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC;QAC5D,CAAC,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QACtC,CAAC,CAAC,IAAI,CAAC;IACX,EAAE,CAAC,OAAO,CACR;uCACmC,CACpC,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACtE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,EAAgB;IAC9C,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,8DAA8D,CAAC,CAAC,GAAG,EAE7E,CAAC;IACd,OAAO,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;AAC/B,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;
|
|
1
|
+
{"version":3,"file":"sequencing.js","sourceRoot":"","sources":["../../../src/store/sync/sequencing.ts"],"names":[],"mappings":"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"}
|
|
@@ -28,10 +28,13 @@ import type { TableScope } from '@cleocode/contracts';
|
|
|
28
28
|
*/
|
|
29
29
|
export declare function canonicalStoreTimestamp(value: string): string | null;
|
|
30
30
|
/**
|
|
31
|
-
* Captured timestamp columns per sync-set table. The claim-lease columns
|
|
31
|
+
* Captured TEXT timestamp columns per sync-set table. The claim-lease columns
|
|
32
32
|
* (`claimed_at`, `lease_expires_at`) are local-only and are not captured, so
|
|
33
|
-
* they are not here.
|
|
34
|
-
*
|
|
33
|
+
* they are not here. INTEGER epoch-millisecond columns (`brain_attention`,
|
|
34
|
+
* `brain_decisions.validator_run_at`, `brain_session_narrative.last_updated_at`)
|
|
35
|
+
* are already canonical and are not here either. A test pins this map, plus
|
|
36
|
+
* an explicit list of those integer columns, against every captured `*_at`
|
|
37
|
+
* column of both sync sets.
|
|
35
38
|
*/
|
|
36
39
|
export declare const SYNC_TIMESTAMP_COLUMNS: Readonly<Record<TableScope, Readonly<Record<string, readonly string[]>>>>;
|
|
37
40
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timestamp-canon.d.ts","sourceRoot":"","sources":["../../../src/store/sync/timestamp-canon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AActD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA+BpE;AAMD
|
|
1
|
+
{"version":3,"file":"timestamp-canon.d.ts","sourceRoot":"","sources":["../../../src/store/sync/timestamp-canon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AActD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA+BpE;AAMD;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAC3C,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC,CA4DhE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAC3C,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC,CAIhE,CAAC;AAEF,0EAA0E;AAC1E,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAGtF"}
|