@omgbase/core 0.19.0 → 0.23.0

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.
Files changed (55) hide show
  1. package/dist/src/core/ids.d.ts +1 -1
  2. package/dist/src/core/ingest.d.ts +2 -0
  3. package/dist/src/core/ingest.js +13 -0
  4. package/dist/src/core/read/document.d.ts +13 -9
  5. package/dist/src/core/read/document.js +18 -8
  6. package/dist/src/core/store/archive.d.ts +196 -0
  7. package/dist/src/core/store/archive.js +606 -0
  8. package/dist/src/core/store/gc.d.ts +37 -4
  9. package/dist/src/core/store/gc.js +62 -28
  10. package/dist/src/core/store/rebuild.d.ts +2 -0
  11. package/dist/src/core/store/rebuild.js +8 -2
  12. package/dist/src/core/store/retention.d.ts +138 -0
  13. package/dist/src/core/store/retention.js +409 -0
  14. package/dist/src/core/store/schema.d.ts +3 -2
  15. package/dist/src/core/store/schema.js +30 -4
  16. package/dist/src/core/store/size.d.ts +24 -2
  17. package/dist/src/core/store/size.js +33 -3
  18. package/dist/src/core/store/store.d.ts +1 -0
  19. package/dist/src/core/store/store.js +53 -1
  20. package/dist/src/graph/history.d.ts +2 -0
  21. package/dist/src/graph/history.js +8 -4
  22. package/dist/src/index.d.ts +3 -1
  23. package/dist/src/index.js +3 -0
  24. package/dist/src/mcp/arguments.d.ts +10 -2
  25. package/dist/src/mcp/arguments.js +37 -3
  26. package/dist/src/mcp/errors.d.ts +1 -1
  27. package/dist/src/mcp/errors.js +4 -0
  28. package/dist/src/mcp/reference.d.ts +1 -1
  29. package/dist/src/mcp/reference.js +58 -8
  30. package/dist/src/mcp/server.js +51 -24
  31. package/dist/src/mutate/effects.d.ts +23 -5
  32. package/dist/src/mutate/effects.js +111 -22
  33. package/dist/src/mutate/known-ids.d.ts +19 -0
  34. package/dist/src/mutate/known-ids.js +47 -7
  35. package/dist/src/mutate/ops.d.ts +1 -0
  36. package/dist/src/mutate/ops.js +20 -1
  37. package/dist/src/mutate/select.d.ts +0 -11
  38. package/dist/src/mutate/select.js +33 -9
  39. package/dist/src/oqx-js/context.d.ts +9 -2
  40. package/dist/src/oqx-js/context.js +92 -30
  41. package/dist/src/oqx-js/dates.d.ts +105 -0
  42. package/dist/src/oqx-js/dates.js +427 -0
  43. package/dist/src/oqx-js/names.d.ts +40 -0
  44. package/dist/src/oqx-js/names.js +358 -0
  45. package/dist/src/oqx-js/planner.d.ts +3 -3
  46. package/dist/src/oqx-js/planner.js +30 -11
  47. package/dist/src/oqx-js/root-row.d.ts +15 -4
  48. package/dist/src/oqx-js/root-row.js +18 -10
  49. package/dist/src/oqx-js/run.d.ts +19 -1
  50. package/dist/src/oqx-js/run.js +97 -13
  51. package/dist/src/oqx-js/sql/translate.js +1 -1
  52. package/dist/src/spec-versions.d.ts +5 -5
  53. package/dist/src/spec-versions.js +4 -4
  54. package/dist/src/sync/observe.js +9 -3
  55. package/package.json +2 -2
@@ -1,4 +1,4 @@
1
- export type IdPrefix = "d" | "b" | "c" | "r" | "x" | "col" | "cp" | "e" | "rp" | "v" | "src";
1
+ export type IdPrefix = "d" | "b" | "c" | "r" | "x" | "col" | "cp" | "e" | "rp" | "v" | "src" | "s";
2
2
  export declare function randomSuffix(len?: number): string;
3
3
  /** A replacement id generator (spec/store §2.2): given a prefix, return the whole id. */
4
4
  export type IdMinter = (prefix: IdPrefix) => string;
@@ -10,6 +10,8 @@ export interface DispositionRow {
10
10
  matcherV: string | null;
11
11
  detail: Record<string, unknown>;
12
12
  }
13
+ /** spec/store §5.4 step 10 (14.2): which verdicts the store persists — every kind but `same`. */
14
+ export declare function persistsDisposition(kind: string): boolean;
13
15
  export interface ResolvedEdgeRow {
14
16
  srcDoc: string;
15
17
  srcBlock: string | null;
@@ -13,6 +13,10 @@ import { flattenFrontmatter, flattenComputed, writeDocProperties } from "./store
13
13
  import { maintainEdges, adoptPhantoms } from "./store/edges.js";
14
14
  import { parse as parseYaml } from "yaml";
15
15
  import { adapterForPath } from "../format/index.js";
16
+ /** spec/store §5.4 step 10 (14.2): which verdicts the store persists — every kind but `same`. */
17
+ export function persistsDisposition(kind) {
18
+ return kind !== "same";
19
+ }
16
20
  /** The parse step of ingest, exported so a batch caller can parse + reconcile
17
21
  * every document of a checkpoint BEFORE committing any (the cross-document
18
22
  * phase needs all per-doc results first) and hand the tree back via
@@ -279,10 +283,19 @@ export function ingestInto(db, repoId, path, content, opts) {
279
283
  const dispositions = resolved.dispositions.length > 0 || opts.resolveIds
280
284
  ? resolved.dispositions
281
285
  : rows.map((r) => ({ blockId: r.blockId, kind: "inserted", confidence: null, reason: null, matcherV: null, detail: {} }));
286
+ // spec/store §5.4 step 10 (14.2): a `same` verdict is not persisted. The
287
+ // matcher (and the known-id resolver) still produce one per untouched block
288
+ // — the outcome counts them — but the table records what CHANGED, so a
289
+ // block's `updated_at` (MAX commit ts over its `block_changes`) and its
290
+ // `blocks_history` are the block's own changes, not its siblings'. Every
291
+ // other kind — the first revision's `inserted` rows the mint oracle (§2.1)
292
+ // depends on included — is written as before.
282
293
  const insDisp = db.prepare(`INSERT OR IGNORE INTO dispositions (commit_id, block_id, kind, confidence, reason, matcher_v, detail)
283
294
  VALUES (?, ?, ?, ?, ?, ?, ?)`);
284
295
  const bc = db.prepare("INSERT OR IGNORE INTO block_changes (block_id, commit_id, kind) VALUES (?, ?, ?)");
285
296
  for (const d of dispositions) {
297
+ if (!persistsDisposition(d.kind))
298
+ continue;
286
299
  insDisp.run(commitId, d.blockId, d.kind, d.confidence, d.reason, d.matcherV, JSON.stringify(d.detail));
287
300
  bc.run(d.blockId, commitId, d.kind);
288
301
  }
@@ -76,6 +76,15 @@ export declare function docsReadMany(store: Store, repoId: string, refs: string[
76
76
  includeIds?: boolean;
77
77
  budgetTokens?: number;
78
78
  }): DocsReadManyResult;
79
+ /**
80
+ * `docs_read { at }` / `docs_read_at` (spec/surface §2, 4.7): the document AS
81
+ * OF a revision. No `properties`: the properties table is current-state only
82
+ * (`spec/properties`), and recomputing the bag from the reconstructed bytes is
83
+ * not yet a one-call affair of the format layer (the inline fields come out of
84
+ * the ingest's node projection) — so the time-travel read carries the bytes
85
+ * and nothing it would have to guess at (through 4.6 `docs_read_at` returned
86
+ * the CURRENT bag flagged `propertiesAreCurrent: true`).
87
+ */
79
88
  export interface DocsReadAtResult {
80
89
  id: string;
81
90
  /** The path as of that revision, in the reference form. */
@@ -88,14 +97,6 @@ export interface DocsReadAtResult {
88
97
  * rendered_hash — a byte-faithful round-trip. False flags the fidelity gap
89
98
  * described below (doc-level trivia may differ for an old revision). */
90
99
  renderedHashMatch: boolean;
91
- /**
92
- * Properties as they are CURRENTLY (not at `rev`): the properties table is
93
- * current-state only (properties-table), so historical property values are
94
- * not recoverable. Included as best-effort context, flagged by
95
- * `propertiesAreCurrent: true`.
96
- */
97
- properties: Record<string, Record<string, unknown>>;
98
- propertiesAreCurrent: true;
99
100
  }
100
101
  /**
101
102
  * Whole-document TIME-TRAVEL read: reconstruct a document's full file bytes AS
@@ -105,7 +106,10 @@ export interface DocsReadAtResult {
105
106
  * IN ORDER — but sourced from the revision's Merkle `root_tree` instead of the
106
107
  * live `blocks` table. Returns null when the doc is missing, or when `revId`
107
108
  * does not name a revision of this document (so the caller can raise a clean
108
- * not-found error).
109
+ * not-found error). An ARCHIVED revision (spec/store §7 "Retention", 15.0)
110
+ * reads through its segment, attached on demand; when the segment is not
111
+ * recorded or not on disk this throws `RevisionArchived` (the surface's
112
+ * `revision_archived`).
109
113
  *
110
114
  * FIDELITY CAVEAT: `leading_trivia` and `frontmatter_trivia` are stored ONLY on
111
115
  * the current `docs` row, NOT per-revision (see schema.ts — the `docs` row is
@@ -2,6 +2,7 @@ import { findDoc, findDocByRef, loadDocBlocks } from "./reader.js";
2
2
  import { docPropertiesGrouped } from "../store/properties.js";
3
3
  import { sha256 } from "../hash.js";
4
4
  import { referencePath } from "../paths.js";
5
+ import { revisionBody } from "../store/archive.js";
5
6
  function blob(db, hash) {
6
7
  const row = db.prepare("SELECT bytes FROM blobs WHERE hash = ?").get(hash);
7
8
  return row ? row.bytes.toString("utf8") : "";
@@ -154,7 +155,10 @@ export function docsReadMany(store, repoId, refs, opts = {}) {
154
155
  * IN ORDER — but sourced from the revision's Merkle `root_tree` instead of the
155
156
  * live `blocks` table. Returns null when the doc is missing, or when `revId`
156
157
  * does not name a revision of this document (so the caller can raise a clean
157
- * not-found error).
158
+ * not-found error). An ARCHIVED revision (spec/store §7 "Retention", 15.0)
159
+ * reads through its segment, attached on demand; when the segment is not
160
+ * recorded or not on disk this throws `RevisionArchived` (the surface's
161
+ * `revision_archived`).
158
162
  *
159
163
  * FIDELITY CAVEAT: `leading_trivia` and `frontmatter_trivia` are stored ONLY on
160
164
  * the current `docs` row, NOT per-revision (see schema.ts — the `docs` row is
@@ -174,25 +178,33 @@ export function readDocumentAtRevision(store, docId, revId) {
174
178
  .get(docId);
175
179
  if (!doc)
176
180
  return null;
177
- const rev = db.prepare("SELECT root_tree, frontmatter_blob, rendered_hash, path FROM revisions WHERE rev_id = ? AND doc_id = ?").get(revId, docId);
181
+ // The revision's bodies: the store's for a live revision, its segment's for
182
+ // an archived one (spec/store §6.2 "through a segment", 15.0 — `prefix` is
183
+ // the attached alias; an unavailable segment throws RevisionArchived).
184
+ const rev = revisionBody(store, revId, docId);
178
185
  if (!rev)
179
186
  return null;
187
+ const at = (table) => `${rev.prefix}${table}`;
188
+ const blobAt = (hash) => {
189
+ const row = db.prepare(`SELECT bytes FROM ${at("blobs")} WHERE hash = ?`).get(hash);
190
+ return row ? row.bytes.toString("utf8") : "";
191
+ };
180
192
  const out = [doc.leading_trivia];
181
193
  // Frontmatter blob for THIS revision (per-revision), then the doc-level
182
194
  // separator (best-effort — see fidelity caveat).
183
195
  if (rev.frontmatter_blob)
184
- out.push(blob(db, rev.frontmatter_blob) + (doc.frontmatter_trivia ?? ""));
196
+ out.push(blobAt(rev.frontmatter_blob) + (doc.frontmatter_trivia ?? ""));
185
197
  // Top-level blocks in tree order, from THIS revision's Merkle root tree node.
186
198
  // A container's raw already holds its children verbatim, so we deliberately do
187
199
  // NOT recurse into childTreeHashHex (mirrors reconstructContent's
188
200
  // parent_block IS NULL walk). An absent tree node yields empty body bytes.
189
- const node = db.prepare("SELECT entries FROM tree_nodes WHERE hash = ?").get(rev.root_tree);
201
+ const node = db.prepare(`SELECT entries FROM ${at("tree_nodes")} WHERE hash = ?`).get(rev.root_tree);
190
202
  if (node) {
191
203
  const entries = JSON.parse(node.entries);
192
204
  for (const [, rawHashHex, , , , triviaHashHex] of entries) {
193
- out.push(blob(db, Buffer.from(rawHashHex, "hex")));
205
+ out.push(blobAt(Buffer.from(rawHashHex, "hex")));
194
206
  if (triviaHashHex)
195
- out.push(blob(db, Buffer.from(triviaHashHex, "hex")));
207
+ out.push(blobAt(Buffer.from(triviaHashHex, "hex")));
196
208
  }
197
209
  }
198
210
  const content = out.join("");
@@ -204,8 +216,6 @@ export function readDocumentAtRevision(store, docId, revId) {
204
216
  rev: revId,
205
217
  raw: content,
206
218
  renderedHashMatch,
207
- properties: surfaceProperties(docPropertiesGrouped(db, docId)),
208
- propertiesAreCurrent: true,
209
219
  };
210
220
  }
211
221
  //# sourceMappingURL=document.js.map
@@ -0,0 +1,196 @@
1
+ import type { Store } from "./store.js";
2
+ import { type EvaluateOptions, type RetentionPlan, type RetentionPolicy } from "./retention.js";
3
+ /** spec/store/archive.sql, verbatim — the segment's DDL. */
4
+ export declare const ARCHIVE_DDL = "-- ---- an archive segment (spec/store \u00A77 \"Retention\", 15.0) --------------------\n-- One file per `history export`, never appended: the bodies of the revisions\n-- the retention policy squashed, self-contained (every blob and tree node\n-- reachable from them), plus copies of their revision, commit, disposition and\n-- block-change rows, and one manifest row. The same DDL subset as schema.sql\n-- minus the foreign keys (a segment holds no repos or docs rows).\nCREATE TABLE IF NOT EXISTS manifest (\n segment_id TEXT PRIMARY KEY,\n repo_id TEXT NOT NULL,\n created_at TEXT NOT NULL,\n policy TEXT NOT NULL,\n seq_lo INTEGER NOT NULL,\n seq_hi INTEGER NOT NULL,\n revision_count INTEGER NOT NULL,\n previous_segment TEXT,\n schema_user_version INTEGER NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS revisions (\n rev_id TEXT PRIMARY KEY,\n doc_id TEXT NOT NULL,\n seq INTEGER NOT NULL,\n root_tree BLOB NOT NULL,\n frontmatter_blob BLOB,\n rendered_hash BLOB NOT NULL,\n path TEXT NOT NULL,\n commit_id TEXT NOT NULL,\n UNIQUE (doc_id, seq)\n);\n\nCREATE TABLE IF NOT EXISTS commits (\n commit_id TEXT PRIMARY KEY,\n repo_id TEXT NOT NULL,\n seq INTEGER NOT NULL,\n ts TEXT NOT NULL,\n origin TEXT NOT NULL CHECK (origin IN ('api','observed','import','projection')),\n actor TEXT,\n reason TEXT,\n checkpoint_id TEXT,\n ops TEXT\n);\n\nCREATE TABLE IF NOT EXISTS blobs (\n hash BLOB PRIMARY KEY,\n bytes BLOB NOT NULL,\n size INTEGER NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS tree_nodes (\n hash BLOB PRIMARY KEY,\n entries TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS dispositions (\n commit_id TEXT NOT NULL,\n block_id TEXT NOT NULL,\n kind TEXT NOT NULL CHECK (kind IN\n ('same','edited','moved','edited_moved','inserted','deleted',\n 'split_from','merged_into','copied_from','resurrected','bulk_rewrite')),\n confidence REAL,\n reason TEXT,\n matcher_v TEXT,\n detail TEXT NOT NULL DEFAULT '{}',\n PRIMARY KEY (commit_id, block_id, kind)\n);\n\nCREATE TABLE IF NOT EXISTS block_changes (\n block_id TEXT NOT NULL,\n commit_id TEXT NOT NULL,\n kind TEXT NOT NULL,\n PRIMARY KEY (block_id, commit_id, kind)\n);\n";
5
+ /** The file suffix every segment carries. */
6
+ export declare const ARCHIVE_SUFFIX = ".omgarchive.db";
7
+ /** The default directory under `.omgbase/`. */
8
+ export declare const ARCHIVE_DIR = "archives";
9
+ /** `<repo_id>-<seq_lo>-<seq_hi>-<segment_id>.omgarchive.db` */
10
+ export declare function segmentFileName(repoId: string, seqLo: number, seqHi: number, segmentId: string): string;
11
+ /** The parts a segment file name carries, or null when the name is not one. */
12
+ export declare function parseSegmentFileName(name: string): {
13
+ repoId: string;
14
+ seqLo: number;
15
+ seqHi: number;
16
+ segmentId: string;
17
+ } | null;
18
+ export interface Manifest {
19
+ segment_id: string;
20
+ repo_id: string;
21
+ created_at: string;
22
+ policy: RetentionPolicy;
23
+ seq_lo: number;
24
+ seq_hi: number;
25
+ revision_count: number;
26
+ previous_segment: string | null;
27
+ schema_user_version: number;
28
+ }
29
+ /** A read of an archived revision whose segment is not recorded, or recorded but not on disk (spec/surface: `revision_archived`). */
30
+ export declare class RevisionArchived extends Error {
31
+ readonly rev: string;
32
+ readonly archive: string;
33
+ readonly path: string | null;
34
+ constructor(rev: string, archive: string, path: string | null);
35
+ }
36
+ /** Not an archive segment, or one of another repository. */
37
+ export declare class NotASegment extends Error {
38
+ readonly path: string;
39
+ constructor(path: string, detail: string);
40
+ }
41
+ /** Open a segment read-only and return its manifest; `NotASegment` when the file is not one. */
42
+ export declare function readManifest(path: string): Manifest;
43
+ export interface ArchiveRow {
44
+ segment_id: string;
45
+ repo_id: string;
46
+ path: string;
47
+ seq_lo: number;
48
+ seq_hi: number;
49
+ created_at: string;
50
+ revision_count: number;
51
+ bytes: number;
52
+ }
53
+ export interface AttachedSegment {
54
+ segment_id: string;
55
+ path: string;
56
+ seq_lo: number;
57
+ seq_hi: number;
58
+ revision_count: number;
59
+ bytes: number;
60
+ }
61
+ export interface AttachResult {
62
+ attached: AttachedSegment[];
63
+ /** Files in a directory that are not this repository's segments. */
64
+ skipped: number;
65
+ }
66
+ /**
67
+ * `omg history attach <file|dir>`: record a segment (idempotent — a known
68
+ * segment's path is re-recorded) or every `.omgarchive.db` of a directory
69
+ * whose manifest `repo_id` is this repository's. A single file of another
70
+ * repository or a non-segment is `NotASegment`; in a directory they are skipped.
71
+ */
72
+ export declare function attachArchive(store: Store, repoId: string, target: string): AttachResult;
73
+ /**
74
+ * `omg history detach <segment_id|path>`: forget a segment. The revisions it
75
+ * holds keep their `archive` pointer; reading one is `revision_archived` until
76
+ * the segment is attached again. Returns the id, or null when nothing matched.
77
+ */
78
+ export declare function detachArchive(store: Store, repoId: string, ref: string): string | null;
79
+ /**
80
+ * A segment's state (spec/store §7 "Retention"): recorded and on disk
81
+ * (`attached`), recorded but not on disk (`missing`); or unrecorded under the
82
+ * archives directory — `pending` (complete, its revisions still live: the
83
+ * crash rule finishes it on the next `export --prune`), `detached` (complete
84
+ * and squashed: `attach` brings it back), `stale` (some of its revisions live,
85
+ * some not: it belongs to another store or predates a different squash).
86
+ */
87
+ export type ArchiveState = "attached" | "missing" | "pending" | "detached" | "stale";
88
+ export interface ArchiveListing extends AttachedSegment {
89
+ created_at: string;
90
+ state: ArchiveState;
91
+ }
92
+ /**
93
+ * `omg history list`: the repository's recorded segments by `seq_lo` then id,
94
+ * followed by the unrecorded complete segments found in `dest`, by file name.
95
+ */
96
+ export declare function listArchives(store: Store, repoId: string, opts?: {
97
+ dest?: string;
98
+ }): ArchiveListing[];
99
+ export interface UnrecordedSegment {
100
+ path: string;
101
+ state: "pending" | "detached" | "stale";
102
+ }
103
+ /**
104
+ * The complete segments of this repository under `dest` that no `archives`
105
+ * row records, by file name, each classified by its revisions: all live →
106
+ * `pending` (the crash rule's input), all archived → `detached`, else `stale`.
107
+ */
108
+ export declare function unrecordedSegments(store: Store, repoId: string, dest: string): UnrecordedSegment[];
109
+ export declare function archiveAlias(segmentId: string): string;
110
+ /**
111
+ * The table prefix a revision's bodies are read under: `""` for a live
112
+ * revision, `"<alias>."` for an archived one whose segment is attached on
113
+ * demand (and verified to be the segment it claims). `RevisionArchived` when
114
+ * the segment is not recorded or not on disk.
115
+ */
116
+ export declare function archivePrefix(store: Store, rev: {
117
+ rev_id: string;
118
+ archive: string | null;
119
+ }): string;
120
+ export interface RevisionBody {
121
+ rev_id: string;
122
+ doc_id: string;
123
+ path: string;
124
+ rendered_hash: Buffer;
125
+ root_tree: Buffer;
126
+ frontmatter_blob: Buffer | null;
127
+ /** `""` or `"<alias>."` — where `tree_nodes` and `blobs` for this revision live. */
128
+ prefix: string;
129
+ archived: boolean;
130
+ }
131
+ /**
132
+ * A revision's row with its bodies resolved: a live revision's from the store,
133
+ * an archived one's from its segment (attached on demand). `undefined` when
134
+ * `revId` is not a revision (of `docId`, when given); `RevisionArchived` when
135
+ * its segment is unavailable.
136
+ */
137
+ export declare function revisionBody(store: Store, revId: string, docId?: string): RevisionBody | undefined;
138
+ export interface SegmentInfo {
139
+ id: string;
140
+ path: string;
141
+ seq_lo: number;
142
+ seq_hi: number;
143
+ created_at: string;
144
+ revision_count: number;
145
+ /** The file's size on disk. */
146
+ bytes: number;
147
+ previous_segment: string | null;
148
+ }
149
+ export interface SquashResult {
150
+ revisions: number;
151
+ /** Commits every revision of which is archived: their dispositions and block changes moved. */
152
+ commits: number;
153
+ dispositions: number;
154
+ block_changes: number;
155
+ }
156
+ export interface ExportResult {
157
+ plan: RetentionPlan;
158
+ /** null when nothing was to archive (no file written). */
159
+ segment: SegmentInfo | null;
160
+ /** An unrecorded complete segment was finished instead of writing a new one (the crash rule). */
161
+ reused: boolean;
162
+ /** null without `prune`. */
163
+ squashed: SquashResult | null;
164
+ /** null without `prune`. */
165
+ gc: {
166
+ blobs: number;
167
+ tree_nodes: number;
168
+ } | null;
169
+ }
170
+ export interface ExportOptions extends EvaluateOptions {
171
+ /** The directory the segment is written to (created when missing). */
172
+ dest: string;
173
+ /** Squash the store after the segment is durable. */
174
+ prune: boolean;
175
+ }
176
+ /** An unrecorded segment under `dest` names both live and non-live revisions (it predates another squash, or belongs elsewhere). */
177
+ export declare class StaleSegment extends Error {
178
+ readonly path: string;
179
+ readonly rev: string;
180
+ constructor(path: string, rev: string);
181
+ }
182
+ /**
183
+ * `omg history export [--prune]`: evaluate the policy, write ONE new segment
184
+ * for the revisions to archive (or finish an unrecorded one — the crash
185
+ * rule), and with `prune` squash the store. Nothing to archive → no file,
186
+ * `segment: null`.
187
+ */
188
+ export declare function exportHistory(store: Store, repoId: string, opts: ExportOptions): ExportResult;
189
+ /** The archived-history figures the size report carries (spec/store §7 "Size", 15.0). */
190
+ export declare function archivedSummary(store: Store): {
191
+ revisions: number;
192
+ segments: number;
193
+ bytes: number;
194
+ };
195
+ /** The file name of a segment path, for messages and fixtures. */
196
+ export declare function segmentBasename(path: string): string;