@omgbase/core 0.4.0 → 0.5.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.
- package/dist/src/core/ids.d.ts +34 -3
- package/dist/src/core/ids.js +79 -6
- package/dist/src/core/store/fts.d.ts +9 -0
- package/dist/src/core/store/fts.js +13 -0
- package/dist/src/core/store/store.d.ts +4 -0
- package/dist/src/core/store/store.js +40 -1
- package/dist/src/format/index.d.ts +12 -1
- package/dist/src/format/index.js +14 -1
- package/dist/src/format/markdown.d.ts +7 -0
- package/dist/src/format/markdown.js +7 -0
- package/dist/src/graph/history.d.ts +21 -0
- package/dist/src/graph/history.js +48 -6
- package/dist/src/graph/links.d.ts +2 -0
- package/dist/src/graph/links.js +22 -11
- package/dist/src/index.d.ts +8 -5
- package/dist/src/index.js +8 -5
- package/dist/src/mcp/errors.d.ts +8 -0
- package/dist/src/mcp/errors.js +17 -3
- package/dist/src/mcp/server.d.ts +8 -0
- package/dist/src/mcp/server.js +47 -50
- package/dist/src/mutate/apply.js +12 -4
- package/dist/src/mutate/doc-store.js +4 -1
- package/dist/src/mutate/docs.d.ts +19 -0
- package/dist/src/mutate/docs.js +64 -16
- package/dist/src/mutate/ops.js +25 -13
- package/dist/src/oqx-js/sql/translate.d.ts +36 -13
- package/dist/src/oqx-js/sql/translate.js +122 -33
- package/dist/src/search/tasks.d.ts +9 -0
- package/dist/src/search/tasks.js +23 -1
- package/dist/src/spec-versions.d.ts +14 -0
- package/dist/src/spec-versions.js +25 -0
- package/dist/src/sync/admin.d.ts +13 -0
- package/dist/src/sync/admin.js +11 -0
- package/dist/src/version.d.ts +39 -0
- package/dist/src/version.js +103 -0
- package/package.json +1 -1
package/dist/src/core/ids.d.ts
CHANGED
|
@@ -2,17 +2,48 @@ export type IdPrefix = "d" | "b" | "c" | "r" | "x" | "col" | "cp" | "e" | "rp" |
|
|
|
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;
|
|
5
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* An in-use oracle (spec/store §2.1): does `id` name a row of the prefix's
|
|
7
|
+
* table(s)? A `Store` registers one when it opens and unregisters it on close.
|
|
8
|
+
* `col`/`v` have no table; an oracle answers false for them.
|
|
9
|
+
*/
|
|
10
|
+
export type IdOracle = (prefix: IdPrefix, id: string) => boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Consecutive rejections after which a mint gives up. The CSPRNG cannot hit
|
|
13
|
+
* this (32⁷ candidates against at most millions in use); only a minter that
|
|
14
|
+
* can never produce a fresh id — a broken fixture minter — does, and it must
|
|
15
|
+
* fail loudly rather than spin forever.
|
|
16
|
+
*/
|
|
17
|
+
export declare const MINT_GIVE_UP_AFTER = 1000;
|
|
18
|
+
/** Install a replacement minter (null restores the CSPRNG default). Starts a fresh issued set. */
|
|
6
19
|
export declare function setIdMinter(minter: IdMinter | null): void;
|
|
7
|
-
/** Run `body` with `minter` installed, restoring the previous minter afterwards (also on throw). */
|
|
20
|
+
/** Run `body` with `minter` installed, restoring the previous minter (and its issued set) afterwards (also on throw). */
|
|
8
21
|
export declare function withIdMinter<T>(minter: IdMinter, body: () => T): T;
|
|
22
|
+
/**
|
|
23
|
+
* Register an in-use oracle (spec/store §2.1); returns the unregister handle.
|
|
24
|
+
* Every open `Store` holds one, so a mint is checked against every database
|
|
25
|
+
* this process has open — a false "in use" from another store costs one redraw.
|
|
26
|
+
*/
|
|
27
|
+
export declare function registerIdOracle(oracle: IdOracle): () => void;
|
|
9
28
|
/**
|
|
10
29
|
* The fixture minter (spec/store §2.2): a sequential per-prefix counter —
|
|
11
30
|
* `d_0, d_1, …`, `b_0, …`, each prefix counting from 0 independently. A fresh
|
|
12
31
|
* instance per case resets every counter.
|
|
13
32
|
*/
|
|
14
33
|
export declare function sequentialMinter(): IdMinter;
|
|
15
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* The repeating fixture minter (spec/store §9.4, `"minter": "repeat"`): the
|
|
36
|
+
* sequential counter whose every id is offered twice — `rp_0, rp_0, b_0, b_0,
|
|
37
|
+
* b_1, b_1, …`. The store rejects the second offering as in use and asks
|
|
38
|
+
* again, so a case run under it projects exactly as under `sequentialMinter`.
|
|
39
|
+
*/
|
|
40
|
+
export declare function repeatingMinter(): IdMinter;
|
|
41
|
+
/**
|
|
42
|
+
* Mint an id with the given prefix (spec/store §2.1 "Uniqueness at mint"):
|
|
43
|
+
* draw a candidate — from the installed minter, else the CSPRNG — and redraw
|
|
44
|
+
* while it is in use (issued in this process, or present in a registered
|
|
45
|
+
* store). Gives up after `MINT_GIVE_UP_AFTER` consecutive rejections.
|
|
46
|
+
*/
|
|
16
47
|
export declare function mintId(prefix: IdPrefix): string;
|
|
17
48
|
export declare function isValidId(id: string, prefix?: IdPrefix): boolean;
|
|
18
49
|
export declare function prefixOf(id: string): string | null;
|
package/dist/src/core/ids.js
CHANGED
|
@@ -8,6 +8,13 @@ export function randomSuffix(len = ID_LEN) {
|
|
|
8
8
|
s += ALPHABET[randomInt(ALPHABET.length)];
|
|
9
9
|
return s;
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* Consecutive rejections after which a mint gives up. The CSPRNG cannot hit
|
|
13
|
+
* this (32⁷ candidates against at most millions in use); only a minter that
|
|
14
|
+
* can never produce a fresh id — a broken fixture minter — does, and it must
|
|
15
|
+
* fail loudly rather than spin forever.
|
|
16
|
+
*/
|
|
17
|
+
export const MINT_GIVE_UP_AFTER = 1_000;
|
|
11
18
|
// The installed minter, or null for production (CSPRNG). spec/store §2.2: the
|
|
12
19
|
// store's tree hashes contain block ids, so a fixture runner installs a
|
|
13
20
|
// deterministic per-prefix counter here to make ids comparable across
|
|
@@ -15,21 +22,47 @@ export function randomSuffix(len = ID_LEN) {
|
|
|
15
22
|
// the reconcile module's phase 7 mints), commits, revisions, repos, sources —
|
|
16
23
|
// goes through `mintId`, so one seam covers them all.
|
|
17
24
|
let installed = null;
|
|
18
|
-
|
|
25
|
+
// Ids issued by the production minter in this process: a candidate already
|
|
26
|
+
// here is redrawn without asking any oracle. Bounded by the number of ids the
|
|
27
|
+
// process mints (a 360k-block ingest is a few tens of MB at most).
|
|
28
|
+
const productionIssued = new Set();
|
|
29
|
+
// Ids issued while a replacement minter is installed. A *fresh* set per
|
|
30
|
+
// install: a fixture case runs on a fresh database, so what the previous case
|
|
31
|
+
// minted must not reject this one's `d_0` — sequential ids stay byte-identical
|
|
32
|
+
// across cases. The repeating minter's second offering of an id is caught
|
|
33
|
+
// here (the row may not be written yet, so the oracle alone would miss it).
|
|
34
|
+
let installedIssued = new Set();
|
|
35
|
+
const oracles = new Set();
|
|
36
|
+
/** Install a replacement minter (null restores the CSPRNG default). Starts a fresh issued set. */
|
|
19
37
|
export function setIdMinter(minter) {
|
|
20
38
|
installed = minter;
|
|
39
|
+
installedIssued = new Set();
|
|
21
40
|
}
|
|
22
|
-
/** Run `body` with `minter` installed, restoring the previous minter afterwards (also on throw). */
|
|
41
|
+
/** Run `body` with `minter` installed, restoring the previous minter (and its issued set) afterwards (also on throw). */
|
|
23
42
|
export function withIdMinter(minter, body) {
|
|
24
43
|
const previous = installed;
|
|
44
|
+
const previousIssued = installedIssued;
|
|
25
45
|
installed = minter;
|
|
46
|
+
installedIssued = new Set();
|
|
26
47
|
try {
|
|
27
48
|
return body();
|
|
28
49
|
}
|
|
29
50
|
finally {
|
|
30
51
|
installed = previous;
|
|
52
|
+
installedIssued = previousIssued;
|
|
31
53
|
}
|
|
32
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Register an in-use oracle (spec/store §2.1); returns the unregister handle.
|
|
57
|
+
* Every open `Store` holds one, so a mint is checked against every database
|
|
58
|
+
* this process has open — a false "in use" from another store costs one redraw.
|
|
59
|
+
*/
|
|
60
|
+
export function registerIdOracle(oracle) {
|
|
61
|
+
oracles.add(oracle);
|
|
62
|
+
return () => {
|
|
63
|
+
oracles.delete(oracle);
|
|
64
|
+
};
|
|
65
|
+
}
|
|
33
66
|
/**
|
|
34
67
|
* The fixture minter (spec/store §2.2): a sequential per-prefix counter —
|
|
35
68
|
* `d_0, d_1, …`, `b_0, …`, each prefix counting from 0 independently. A fresh
|
|
@@ -43,11 +76,51 @@ export function sequentialMinter() {
|
|
|
43
76
|
return `${prefix}_${n}`;
|
|
44
77
|
};
|
|
45
78
|
}
|
|
46
|
-
/**
|
|
79
|
+
/**
|
|
80
|
+
* The repeating fixture minter (spec/store §9.4, `"minter": "repeat"`): the
|
|
81
|
+
* sequential counter whose every id is offered twice — `rp_0, rp_0, b_0, b_0,
|
|
82
|
+
* b_1, b_1, …`. The store rejects the second offering as in use and asks
|
|
83
|
+
* again, so a case run under it projects exactly as under `sequentialMinter`.
|
|
84
|
+
*/
|
|
85
|
+
export function repeatingMinter() {
|
|
86
|
+
const next = sequentialMinter();
|
|
87
|
+
const pending = new Map();
|
|
88
|
+
return (prefix) => {
|
|
89
|
+
const again = pending.get(prefix);
|
|
90
|
+
if (again !== undefined) {
|
|
91
|
+
pending.delete(prefix);
|
|
92
|
+
return again;
|
|
93
|
+
}
|
|
94
|
+
const id = next(prefix);
|
|
95
|
+
pending.set(prefix, id);
|
|
96
|
+
return id;
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function inUse(prefix, id, issued) {
|
|
100
|
+
if (issued.has(id))
|
|
101
|
+
return true;
|
|
102
|
+
for (const oracle of oracles)
|
|
103
|
+
if (oracle(prefix, id))
|
|
104
|
+
return true;
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Mint an id with the given prefix (spec/store §2.1 "Uniqueness at mint"):
|
|
109
|
+
* draw a candidate — from the installed minter, else the CSPRNG — and redraw
|
|
110
|
+
* while it is in use (issued in this process, or present in a registered
|
|
111
|
+
* store). Gives up after `MINT_GIVE_UP_AFTER` consecutive rejections.
|
|
112
|
+
*/
|
|
47
113
|
export function mintId(prefix) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
114
|
+
const minter = installed;
|
|
115
|
+
const issued = minter ? installedIssued : productionIssued;
|
|
116
|
+
for (let rejected = 0; rejected < MINT_GIVE_UP_AFTER; rejected++) {
|
|
117
|
+
const candidate = minter ? minter(prefix) : `${prefix}_${randomSuffix()}`;
|
|
118
|
+
if (inUse(prefix, candidate, issued))
|
|
119
|
+
continue;
|
|
120
|
+
issued.add(candidate);
|
|
121
|
+
return candidate;
|
|
122
|
+
}
|
|
123
|
+
throw new Error(`mintId(${prefix}): ${MINT_GIVE_UP_AFTER} consecutive candidates were already in use — the ${minter ? "installed" : "production"} minter cannot produce a fresh id`);
|
|
51
124
|
}
|
|
52
125
|
// Production ids carry exactly ID_LEN suffix characters; the fixture minter
|
|
53
126
|
// (spec/store §2.2) mints `d_0`, `b_12`, … — one to seven alphabet characters.
|
|
@@ -5,6 +5,15 @@ import type { Database } from "better-sqlite3";
|
|
|
5
5
|
* it never changes the answer).
|
|
6
6
|
*/
|
|
7
7
|
export declare const LIVE_LEAF_SQL = "b.deleted_commit IS NULL AND NOT EXISTS (SELECT 1 FROM blocks c WHERE c.doc_id = b.doc_id AND c.parent_block = b.block_id AND c.deleted_commit IS NULL)";
|
|
8
|
+
/**
|
|
9
|
+
* How many rows the FTS index actually holds. `SELECT count(*) FROM blocks_fts`
|
|
10
|
+
* is answered from the external-content table (`blocks`, tombstones included),
|
|
11
|
+
* so the count comes from the index's own `_docsize` shadow table — one row per
|
|
12
|
+
* indexed row. `doctor` compares it to the live leaf count (spec/search §1.1).
|
|
13
|
+
*/
|
|
14
|
+
export declare function ftsIndexedRowCount(db: Database): number;
|
|
15
|
+
/** The number of live leaf blocks — the rows the FTS index must hold (spec/search §1.1). */
|
|
16
|
+
export declare function liveLeafCount(db: Database): number;
|
|
8
17
|
/** Remove a document's live leaf rows from the FTS index (call before deleting
|
|
9
18
|
* or tombstoning blocks). Only live leaves are indexed (see ftsIndexDoc), so the
|
|
10
19
|
* delete must target the SAME set: an already-tombstoned block or a container has
|
|
@@ -4,6 +4,19 @@
|
|
|
4
4
|
* it never changes the answer).
|
|
5
5
|
*/
|
|
6
6
|
export const LIVE_LEAF_SQL = "b.deleted_commit IS NULL AND NOT EXISTS (SELECT 1 FROM blocks c WHERE c.doc_id = b.doc_id AND c.parent_block = b.block_id AND c.deleted_commit IS NULL)";
|
|
7
|
+
/**
|
|
8
|
+
* How many rows the FTS index actually holds. `SELECT count(*) FROM blocks_fts`
|
|
9
|
+
* is answered from the external-content table (`blocks`, tombstones included),
|
|
10
|
+
* so the count comes from the index's own `_docsize` shadow table — one row per
|
|
11
|
+
* indexed row. `doctor` compares it to the live leaf count (spec/search §1.1).
|
|
12
|
+
*/
|
|
13
|
+
export function ftsIndexedRowCount(db) {
|
|
14
|
+
return db.prepare("SELECT count(*) c FROM blocks_fts_docsize").get().c;
|
|
15
|
+
}
|
|
16
|
+
/** The number of live leaf blocks — the rows the FTS index must hold (spec/search §1.1). */
|
|
17
|
+
export function liveLeafCount(db) {
|
|
18
|
+
return db.prepare(`SELECT count(*) c FROM blocks b WHERE ${LIVE_LEAF_SQL}`).get().c;
|
|
19
|
+
}
|
|
7
20
|
/** Remove a document's live leaf rows from the FTS index (call before deleting
|
|
8
21
|
* or tombstoning blocks). Only live leaves are indexed (see ftsIndexDoc), so the
|
|
9
22
|
* delete must target the SAME set: an already-tombstoned block or a container has
|
|
@@ -5,7 +5,11 @@ export interface StoreOptions {
|
|
|
5
5
|
}
|
|
6
6
|
export declare class Store {
|
|
7
7
|
readonly db: Database.Database;
|
|
8
|
+
private readonly unregisterOracle;
|
|
9
|
+
private readonly inUseStmts;
|
|
8
10
|
constructor(opts: StoreOptions);
|
|
11
|
+
/** spec/store §2.1: does `id` name a row of the prefix's table(s)? */
|
|
12
|
+
private idInUse;
|
|
9
13
|
private migrate;
|
|
10
14
|
private migrateV3;
|
|
11
15
|
private migrateV4;
|
|
@@ -3,9 +3,28 @@ import { mkdirSync } from "node:fs";
|
|
|
3
3
|
import { dirname } from "node:path";
|
|
4
4
|
import { DDL, SCHEMA_VERSION, MIGRATIONS, SYNC_DDL } from "./schema.js";
|
|
5
5
|
import { cosineBytes } from "../vec.js";
|
|
6
|
-
import { mintId } from "../ids.js";
|
|
6
|
+
import { mintId, registerIdOracle } from "../ids.js";
|
|
7
|
+
// spec/store §2.1 "Uniqueness at mint": the table(s) and id column a minted
|
|
8
|
+
// id of each prefix must not already name a row of. A block id lives on in
|
|
9
|
+
// history after its `blocks` row is gone, hence `block_changes` and
|
|
10
|
+
// `resurrection_pool`. `col` and `v` have no table and no check.
|
|
11
|
+
const ID_TABLES = {
|
|
12
|
+
d: [["docs", "doc_id"]],
|
|
13
|
+
b: [["blocks", "block_id"], ["block_changes", "block_id"], ["resurrection_pool", "block_id"]],
|
|
14
|
+
c: [["commits", "commit_id"]],
|
|
15
|
+
r: [["revisions", "rev_id"]],
|
|
16
|
+
x: [["external_nodes", "node_id"]],
|
|
17
|
+
e: [["edges", "edge_id"]],
|
|
18
|
+
cp: [["checkpoints", "id"]],
|
|
19
|
+
rp: [["repos", "repo_id"]],
|
|
20
|
+
src: [["sources", "source_id"]],
|
|
21
|
+
};
|
|
7
22
|
export class Store {
|
|
8
23
|
db;
|
|
24
|
+
// The in-use oracle this store registered with `mintId` (spec/store §2.1);
|
|
25
|
+
// `close()` calls it to unregister. Prepared statements cached per prefix.
|
|
26
|
+
unregisterOracle;
|
|
27
|
+
inUseStmts = new Map();
|
|
9
28
|
constructor(opts) {
|
|
10
29
|
if (opts.path !== ":memory:")
|
|
11
30
|
mkdirSync(dirname(opts.path), { recursive: true });
|
|
@@ -17,6 +36,24 @@ export class Store {
|
|
|
17
36
|
// scalar. Deterministic (same inputs → same score) so SQLite may cache it.
|
|
18
37
|
this.db.function("cosine", { deterministic: true }, (a, b) => cosineBytes(a, b));
|
|
19
38
|
this.migrate();
|
|
39
|
+
// Registered after the migration so every table the oracle reads exists.
|
|
40
|
+
// (A migration's own mints — v13's `src_` per repo — are checked only
|
|
41
|
+
// against the process's issued set; they land in tables that were empty.)
|
|
42
|
+
this.unregisterOracle = registerIdOracle((prefix, id) => this.idInUse(prefix, id));
|
|
43
|
+
}
|
|
44
|
+
/** spec/store §2.1: does `id` name a row of the prefix's table(s)? */
|
|
45
|
+
idInUse(prefix, id) {
|
|
46
|
+
if (!this.db.open)
|
|
47
|
+
return false;
|
|
48
|
+
let stmts = this.inUseStmts.get(prefix);
|
|
49
|
+
if (!stmts) {
|
|
50
|
+
stmts = (ID_TABLES[prefix] ?? []).map(([table, column]) => this.db.prepare(`SELECT 1 FROM ${table} WHERE ${column} = ? LIMIT 1`));
|
|
51
|
+
this.inUseStmts.set(prefix, stmts);
|
|
52
|
+
}
|
|
53
|
+
for (const stmt of stmts)
|
|
54
|
+
if (stmt.get(id) !== undefined)
|
|
55
|
+
return true;
|
|
56
|
+
return false;
|
|
20
57
|
}
|
|
21
58
|
migrate() {
|
|
22
59
|
const current = this.db.pragma("user_version", { simple: true });
|
|
@@ -158,6 +195,8 @@ export class Store {
|
|
|
158
195
|
return this.db.pragma(name, { simple: true });
|
|
159
196
|
}
|
|
160
197
|
close() {
|
|
198
|
+
this.unregisterOracle();
|
|
199
|
+
this.inUseStmts.clear();
|
|
161
200
|
this.db.close();
|
|
162
201
|
}
|
|
163
202
|
}
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
export type { FormatAdapter, AdapterEdge, ProjectedNode, EmbeddingChunk, ReconcileHints, } from "./adapter.js";
|
|
2
2
|
export { AdapterCapability } from "./adapter.js";
|
|
3
3
|
export { registerAdapter, adapterForFormat, adapterForPath, registeredFormats, detectFormat, } from "./registry.js";
|
|
4
|
-
export { markdownAdapter, MARKDOWN_FORMAT } from "./markdown.js";
|
|
4
|
+
export { markdownAdapter, MARKDOWN_FORMAT, MARKDOWN_CONTAINER_KINDS } from "./markdown.js";
|
|
5
5
|
export { yamlAdapter, YAML_FORMAT } from "./yaml.js";
|
|
6
6
|
export { jsonAdapter, JSON_FORMAT } from "./json.js";
|
|
7
|
+
/**
|
|
8
|
+
* May this block take children (spec/mutate §1.1)? Markdown decides by kind —
|
|
9
|
+
* the parser only ever nests under `list`, `list_item`, `task`, `blockquote`
|
|
10
|
+
* and `table`, so an empty `children` on a heading or paragraph is structural,
|
|
11
|
+
* not "an empty container". The other formats have no kind table for this yet:
|
|
12
|
+
* a block that has children is a container, a childless one a leaf.
|
|
13
|
+
*/
|
|
14
|
+
export declare function isContainerBlock(format: string, block: {
|
|
15
|
+
type: string;
|
|
16
|
+
children: readonly unknown[];
|
|
17
|
+
}): boolean;
|
package/dist/src/format/index.js
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
// Format adapter system. Importing this module registers the built-in adapters.
|
|
2
2
|
export { AdapterCapability } from "./adapter.js";
|
|
3
3
|
export { registerAdapter, adapterForFormat, adapterForPath, registeredFormats, detectFormat, } from "./registry.js";
|
|
4
|
-
export { markdownAdapter, MARKDOWN_FORMAT } from "./markdown.js";
|
|
4
|
+
export { markdownAdapter, MARKDOWN_FORMAT, MARKDOWN_CONTAINER_KINDS } from "./markdown.js";
|
|
5
5
|
export { yamlAdapter, YAML_FORMAT } from "./yaml.js";
|
|
6
6
|
export { jsonAdapter, JSON_FORMAT } from "./json.js";
|
|
7
|
+
import { MARKDOWN_FORMAT, MARKDOWN_CONTAINER_KINDS } from "./markdown.js";
|
|
8
|
+
/**
|
|
9
|
+
* May this block take children (spec/mutate §1.1)? Markdown decides by kind —
|
|
10
|
+
* the parser only ever nests under `list`, `list_item`, `task`, `blockquote`
|
|
11
|
+
* and `table`, so an empty `children` on a heading or paragraph is structural,
|
|
12
|
+
* not "an empty container". The other formats have no kind table for this yet:
|
|
13
|
+
* a block that has children is a container, a childless one a leaf.
|
|
14
|
+
*/
|
|
15
|
+
export function isContainerBlock(format, block) {
|
|
16
|
+
if (format === MARKDOWN_FORMAT)
|
|
17
|
+
return MARKDOWN_CONTAINER_KINDS.has(block.type);
|
|
18
|
+
return block.children.length > 0;
|
|
19
|
+
}
|
|
7
20
|
// Register built-in adapters.
|
|
8
21
|
import { registerAdapter } from "./registry.js";
|
|
9
22
|
import { markdownAdapter } from "./markdown.js";
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { type FormatAdapter } from "./adapter.js";
|
|
2
2
|
import { assertFullCoverage } from "../core/parse/tree.js";
|
|
3
3
|
export declare const MARKDOWN_FORMAT = "markdown";
|
|
4
|
+
/**
|
|
5
|
+
* The Markdown block kinds whose `children` the parser produces (spec/format;
|
|
6
|
+
* `core/parse/parse.ts` CONTAINER_TYPES on the mdast side: list → list_item /
|
|
7
|
+
* task, blockquote, table → table_row). Every other kind is a leaf: its raw IS
|
|
8
|
+
* its whole content, so nothing may be placed inside it (spec/mutate §1.1).
|
|
9
|
+
*/
|
|
10
|
+
export declare const MARKDOWN_CONTAINER_KINDS: ReadonlySet<string>;
|
|
4
11
|
export declare const markdownAdapter: FormatAdapter;
|
|
5
12
|
export { assertFullCoverage };
|
|
@@ -4,6 +4,13 @@ import { parseTree, assertFullCoverage } from "../core/parse/tree.js";
|
|
|
4
4
|
import { render } from "../core/parse/render.js";
|
|
5
5
|
import { extractFromBlock, extractFromFrontmatter, ownText, scanText, INLINE_FIELD_BRACKETED, INLINE_FIELD_LINE } from "../graph/extract.js";
|
|
6
6
|
export const MARKDOWN_FORMAT = "markdown";
|
|
7
|
+
/**
|
|
8
|
+
* The Markdown block kinds whose `children` the parser produces (spec/format;
|
|
9
|
+
* `core/parse/parse.ts` CONTAINER_TYPES on the mdast side: list → list_item /
|
|
10
|
+
* task, blockquote, table → table_row). Every other kind is a leaf: its raw IS
|
|
11
|
+
* its whole content, so nothing may be placed inside it (spec/mutate §1.1).
|
|
12
|
+
*/
|
|
13
|
+
export const MARKDOWN_CONTAINER_KINDS = new Set(["list", "list_item", "task", "blockquote", "table"]);
|
|
7
14
|
function toAdapterEdge(e) {
|
|
8
15
|
return {
|
|
9
16
|
srcBlock: e.srcBlock,
|
|
@@ -28,6 +28,27 @@ export declare function diffBlocks(store: Store, docId: string, fromRev: string,
|
|
|
28
28
|
/** `diff_unified` (spec/surface §3): a unified diff of two revisions' rendered
|
|
29
29
|
* texts — each revision's live raws joined by `\n` — via {@link unifiedDiff}. */
|
|
30
30
|
export declare function diffUnified(store: Store, docId: string, fromRev: string, toRev: string): string;
|
|
31
|
+
/** The `diff_unified` tool's result (spec/surface §3): the resolved revision pair and the diff. */
|
|
32
|
+
export interface DocDiffUnified {
|
|
33
|
+
doc: string;
|
|
34
|
+
path: string;
|
|
35
|
+
from: string;
|
|
36
|
+
to: string;
|
|
37
|
+
diff: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* `diff_unified` over a resolved document: `to` defaults to the current revision,
|
|
41
|
+
* `from` to the one before it (or the current one again when there is only one:
|
|
42
|
+
* an empty diff). Shared by the MCP tool and `omg diff` so the shape cannot
|
|
43
|
+
* drift. `label` is how the caller named the document, for the error message.
|
|
44
|
+
* A document with no revision at all is `target_missing`; an unknown `rev` is
|
|
45
|
+
* `RevisionNotFound` (→ `target_missing` through `errorBody`).
|
|
46
|
+
*/
|
|
47
|
+
export declare function docDiffUnified(store: Store, docId: string, opts?: {
|
|
48
|
+
fromRev?: string;
|
|
49
|
+
toRev?: string;
|
|
50
|
+
label?: string;
|
|
51
|
+
}): DocDiffUnified;
|
|
31
52
|
/** How each text becomes lines: `split("\n")` exactly — no trimming, no
|
|
32
53
|
* dropping of a trailing empty element (a raw ending in `\n` yields one) — with
|
|
33
54
|
* a single special case: the empty text has *no* lines (an empty file is zero
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { findDocByRef } from "../core/read/reader.js";
|
|
2
2
|
import { isValidId } from "../core/ids.js";
|
|
3
|
+
import { EngineError } from "../mcp/errors.js";
|
|
3
4
|
/** history_node: a block's biography from block_changes + commits (06 §3). */
|
|
4
5
|
export function historyNode(store, blockId, opts = {}) {
|
|
5
6
|
const limit = opts.limit ?? 100;
|
|
@@ -78,6 +79,25 @@ export function diffUnified(store, docId, fromRev, toRev) {
|
|
|
78
79
|
const rendered = (rev) => [...blocksAtRevision(store, docId, rev).values()].join("\n");
|
|
79
80
|
return unifiedDiff(rendered(fromRev), rendered(toRev));
|
|
80
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* `diff_unified` over a resolved document: `to` defaults to the current revision,
|
|
84
|
+
* `from` to the one before it (or the current one again when there is only one:
|
|
85
|
+
* an empty diff). Shared by the MCP tool and `omg diff` so the shape cannot
|
|
86
|
+
* drift. `label` is how the caller named the document, for the error message.
|
|
87
|
+
* A document with no revision at all is `target_missing`; an unknown `rev` is
|
|
88
|
+
* `RevisionNotFound` (→ `target_missing` through `errorBody`).
|
|
89
|
+
*/
|
|
90
|
+
export function docDiffUnified(store, docId, opts = {}) {
|
|
91
|
+
const revs = store.db
|
|
92
|
+
.prepare("SELECT rev_id FROM revisions WHERE doc_id = ? ORDER BY seq DESC LIMIT 2")
|
|
93
|
+
.all(docId);
|
|
94
|
+
const to = opts.toRev ?? revs[0]?.rev_id;
|
|
95
|
+
const from = opts.fromRev ?? revs[1]?.rev_id ?? revs[0]?.rev_id;
|
|
96
|
+
if (!to || !from)
|
|
97
|
+
throw new EngineError("target_missing", `no revisions to diff for ${opts.label ?? docId}`);
|
|
98
|
+
const path = store.db.prepare("SELECT path FROM docs WHERE doc_id = ?").get(docId)?.path ?? "";
|
|
99
|
+
return { doc: docId, path, from, to, diff: diffUnified(store, docId, from, to) };
|
|
100
|
+
}
|
|
81
101
|
// ---- unified diff (spec/surface §3) ------------------------------------------
|
|
82
102
|
// A line-grain unified diff with a deterministic Myers script, so both engines
|
|
83
103
|
// (this reference and crates/omgbase-surface/src/history.rs) produce the same
|
|
@@ -232,14 +252,19 @@ export function changesSince(store, repoId, opts = {}) {
|
|
|
232
252
|
params.push(opts.origin);
|
|
233
253
|
params.push(limit + 1);
|
|
234
254
|
const commits = store.db
|
|
235
|
-
.prepare(`SELECT commit_id, seq, ts, origin, actor FROM commits WHERE repo_id = ? AND seq > ? ${originClause} ORDER BY seq LIMIT ?`)
|
|
255
|
+
.prepare(`SELECT commit_id, seq, ts, origin, actor, reason FROM commits WHERE repo_id = ? AND seq > ? ${originClause} ORDER BY seq LIMIT ?`)
|
|
236
256
|
.all(...params);
|
|
237
257
|
const truncated = commits.length > limit;
|
|
238
258
|
const page = commits.slice(0, limit);
|
|
239
259
|
const digests = page.map((c) => {
|
|
240
260
|
const revs = store.db.prepare("SELECT r.doc_id AS doc, r.path AS path, r.rendered_hash AS rendered_hash FROM revisions r WHERE r.commit_id = ?").all(c.commit_id).map((r) => ({ doc: r.doc, path: r.path, contentHash: r.rendered_hash.toString("hex") }));
|
|
241
261
|
const dispCounts = store.db.prepare("SELECT kind, count(*) n FROM dispositions WHERE commit_id = ? GROUP BY kind").all(c.commit_id);
|
|
242
|
-
|
|
262
|
+
// A deletion or a move writes no revision: the tombstone names the commit
|
|
263
|
+
// (`docs.deleted_commit`), a move only its reason (`move <from> -> <to>`).
|
|
264
|
+
const deleted = revs.length === 0
|
|
265
|
+
? store.db.prepare("SELECT path FROM docs WHERE deleted_commit = ? ORDER BY path").all(c.commit_id).map((r) => r.path)
|
|
266
|
+
: [];
|
|
267
|
+
const summary = renderSummary(c.origin, c.actor, revs, dispCounts, { deleted, moved: revs.length === 0 ? parseMove(c.reason) : null });
|
|
243
268
|
return { commit: c.commit_id, seq: c.seq, ts: c.ts, origin: c.origin, actor: c.actor, summary, revisions: revs };
|
|
244
269
|
});
|
|
245
270
|
const nextCursor = page.length > 0 ? page[page.length - 1].seq : cursor;
|
|
@@ -333,12 +358,29 @@ function resolveDocRow(store, repoId, ref, includeDeleted) {
|
|
|
333
358
|
: store.db.prepare("SELECT doc_id, path, current_rev, deleted_commit FROM docs WHERE repo_id = ? AND path = ?");
|
|
334
359
|
return (asId ? stmt.get(ref) : stmt.get(repoId, ref));
|
|
335
360
|
}
|
|
336
|
-
|
|
337
|
-
|
|
361
|
+
/** The `reason` a document move records (`mutate/docs.ts`): `move <from> -> <to>`. */
|
|
362
|
+
function parseMove(reason) {
|
|
363
|
+
const m = reason === null ? null : /^move (.+) -> (.+)$/.exec(reason);
|
|
364
|
+
return m ? { from: m[1], to: m[2] } : null;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* One line per commit: `<origin>[(<actor>)]: <paths> — <n> <kind>, …`. A
|
|
368
|
+
* commit that touched no revision — a document deletion (observed or api) or a
|
|
369
|
+
* move — says so instead: `deleted <path>` / `moved <from> → <to>`
|
|
370
|
+
* (spec/cli §6 `log`; the summary is unpinned by spec/surface).
|
|
371
|
+
*/
|
|
372
|
+
function renderSummary(origin, actor, revs, disp, extra = { deleted: [], moved: null }) {
|
|
373
|
+
let subject = revs.map((r) => r.path).join(", ");
|
|
374
|
+
if (revs.length === 0) {
|
|
375
|
+
if (extra.deleted.length > 0)
|
|
376
|
+
subject = `deleted ${extra.deleted.join(", ")}`;
|
|
377
|
+
else if (extra.moved)
|
|
378
|
+
subject = `moved ${extra.moved.from} → ${extra.moved.to}`;
|
|
379
|
+
}
|
|
338
380
|
const parts = disp.filter((d) => d.kind !== "same").map((d) => `${d.n} ${d.kind}`);
|
|
339
381
|
const detail = parts.length > 0 ? ` — ${parts.join(", ")}` : "";
|
|
340
382
|
if (origin === "api" || origin === "import")
|
|
341
|
-
return `${origin}(${actor ?? "?"}): ${
|
|
342
|
-
return `observed: ${
|
|
383
|
+
return `${origin}(${actor ?? "?"}): ${subject}${detail}`;
|
|
384
|
+
return `observed: ${subject}${detail}`;
|
|
343
385
|
}
|
|
344
386
|
//# sourceMappingURL=history.js.map
|
|
@@ -8,6 +8,8 @@ export interface LinkEdge {
|
|
|
8
8
|
count: number;
|
|
9
9
|
/** sample source block ids (out-edges only) */
|
|
10
10
|
samples?: string[];
|
|
11
|
+
/** block-grain (`blocks: true`): the source block of this edge (null for a frontmatter edge) */
|
|
12
|
+
block?: string | null;
|
|
11
13
|
}
|
|
12
14
|
export interface LinksResult {
|
|
13
15
|
out: LinkEdge[];
|
package/dist/src/graph/links.js
CHANGED
|
@@ -8,12 +8,12 @@ export function docLinks(store, docId, opts = {}) {
|
|
|
8
8
|
if (dir === "out" || dir === "both") {
|
|
9
9
|
if (opts.blocks) {
|
|
10
10
|
const rows = store.db
|
|
11
|
-
.prepare(`SELECT predicate, dst_node, dst_kind FROM edges
|
|
12
|
-
WHERE src_doc = ? AND to_commit IS NULL ORDER BY predicate, dst_node`)
|
|
11
|
+
.prepare(`SELECT predicate, dst_node, dst_kind, src_block FROM edges
|
|
12
|
+
WHERE src_doc = ? AND to_commit IS NULL ORDER BY predicate, dst_node, src_block`)
|
|
13
13
|
.all(docId);
|
|
14
14
|
for (const r of rows)
|
|
15
15
|
if (inPred(r.predicate))
|
|
16
|
-
out.push({ predicate: r.predicate, node: r.dst_node, kind: r.dst_kind, count: 1 });
|
|
16
|
+
out.push({ predicate: r.predicate, node: r.dst_node, kind: r.dst_kind, count: 1, block: r.src_block });
|
|
17
17
|
}
|
|
18
18
|
else {
|
|
19
19
|
const rows = store.db
|
|
@@ -28,14 +28,25 @@ export function docLinks(store, docId, opts = {}) {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
if (dir === "in" || dir === "both") {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
if (opts.blocks) {
|
|
32
|
+
const rows = store.db
|
|
33
|
+
.prepare(`SELECT predicate, src_doc, src_block FROM edges
|
|
34
|
+
WHERE dst_node = ? AND to_commit IS NULL ORDER BY predicate, src_doc, src_block`)
|
|
35
|
+
.all(docId);
|
|
36
|
+
for (const r of rows)
|
|
37
|
+
if (inPred(r.predicate))
|
|
38
|
+
inbound.push({ predicate: r.predicate, node: r.src_doc, kind: "document", count: 1, block: r.src_block });
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
const rows = store.db
|
|
42
|
+
.prepare(`SELECT predicate, src_doc, count(*) AS cnt FROM edges
|
|
43
|
+
WHERE dst_node = ? AND to_commit IS NULL
|
|
44
|
+
GROUP BY predicate, src_doc ORDER BY predicate, src_doc`)
|
|
45
|
+
.all(docId);
|
|
46
|
+
for (const r of rows)
|
|
47
|
+
if (inPred(r.predicate))
|
|
48
|
+
inbound.push({ predicate: r.predicate, node: r.src_doc, kind: "document", count: r.cnt });
|
|
49
|
+
}
|
|
39
50
|
}
|
|
40
51
|
return { out, in: inbound };
|
|
41
52
|
}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { VERSION } from "./core/index.js";
|
|
2
|
+
export { versionInfo, coreVersion, nearestPackageVersion, COMPONENT_PACKAGES, type VersionInfo, type HostInfo } from "./version.js";
|
|
3
|
+
export { SPEC_VERSIONS, type SpecName } from "./spec-versions.js";
|
|
2
4
|
export type { FormatAdapter, AdapterEdge, ProjectedNode, EmbeddingChunk, ReconcileHints } from "./format/adapter.js";
|
|
3
5
|
export { AdapterCapability } from "./format/adapter.js";
|
|
4
6
|
export { registerAdapter, adapterForFormat, adapterForPath, registeredFormats, detectFormat } from "./format/registry.js";
|
|
@@ -28,7 +30,7 @@ export { observeFile, observeMany, observeOne, observeDelete, observeBatch, type
|
|
|
28
30
|
export { buildServer, type ServerContext } from "./mcp/server.js";
|
|
29
31
|
export { serveStdio, type ServeStdioHandle } from "./mcp/stdio.js";
|
|
30
32
|
export { processCheckpoint, type CheckpointResult } from "./sync/checkpoint.js";
|
|
31
|
-
export { reposStatus, syncStatus, type RepoStatus, type SyncStatus, type DiskStatus } from "./sync/admin.js";
|
|
33
|
+
export { reposStatus, syncStatus, reposList, type RepoStatus, type SyncStatus, type DiskStatus, type ReposList } from "./sync/admin.js";
|
|
32
34
|
export { docsOutline, type OutlineResult, type OutlineOptions } from "./core/read/outline.js";
|
|
33
35
|
export { docsRead, reconstructContent, type DocsReadResult, type DocsReadOptions } from "./core/read/document.js";
|
|
34
36
|
export { nodesGet, nodesGetMany, type GetNode, type Resolution } from "./core/read/nodes.js";
|
|
@@ -38,18 +40,18 @@ export { resolveRef, type ResolvedRef } from "./core/read/refs.js";
|
|
|
38
40
|
export { resolve, type ResolveHit, type ResolveInput } from "./search/resolve.js";
|
|
39
41
|
export { oqxRun, oqxRunAsync, collectSemanticPhrases, parseOqx, type OqxResult, type OqxHit, type OqxOptions, type EmbedQuery } from "./oqx/run.js";
|
|
40
42
|
export { EmbeddingWorker, SemanticUnavailable, contextPrefix, shouldEmbed, estimateTokens, type EmbeddingProvider, type EmbedTask, type DocEmbedTask, type DocEmbedBlockRef, type DocEmbedMethod, type DocVectorRow, } from "./search/embeddings.js";
|
|
41
|
-
export { buildEmbedTasks, buildDocEmbedTasks } from "./search/tasks.js";
|
|
43
|
+
export { buildEmbedTasks, buildDocEmbedTasks, staleEmbedCount } from "./search/tasks.js";
|
|
42
44
|
export { EmbedDrainer, type DrainerOptions } from "./search/drain.js";
|
|
43
45
|
export { embeddingSettings, type EmbeddingSettings } from "./search/provider.js";
|
|
44
46
|
export { createExternalProvider, type ExternalProvider } from "./search/external.js";
|
|
45
47
|
export { hybridSearch, type HybridHit, type HybridInput } from "./search/rrf.js";
|
|
46
48
|
export { vectorSearch, docVectorSearch, type VectorHit, type DocVectorHit } from "./search/vector.js";
|
|
47
|
-
export { historyNode, diffUnified, unifiedDiff, changesSince, type NodeChange, type CommitDigest } from "./graph/history.js";
|
|
49
|
+
export { historyNode, diffUnified, docDiffUnified, diffBlocks, unifiedDiff, changesSince, RevisionNotFound, type NodeChange, type CommitDigest, type DocDiffUnified, type DiffEntry } from "./graph/history.js";
|
|
48
50
|
export { docLinks, type LinksResult, type LinkEdge, type LinksOptions } from "./graph/links.js";
|
|
49
51
|
export { FilterInvalid } from "./search/cel/parser.js";
|
|
50
|
-
export { EngineError, type ErrorCode } from "./mcp/errors.js";
|
|
52
|
+
export { EngineError, errorBody, type ErrorCode, type ErrorBody } from "./mcp/errors.js";
|
|
51
53
|
export { MutationError } from "./mutate/tree.js";
|
|
52
|
-
export { isValidId, prefixOf, mintId, setIdMinter, withIdMinter, sequentialMinter, type IdMinter, type IdPrefix } from "./core/ids.js";
|
|
54
|
+
export { isValidId, prefixOf, mintId, setIdMinter, withIdMinter, sequentialMinter, repeatingMinter, registerIdOracle, type IdMinter, type IdOracle, type IdPrefix } from "./core/ids.js";
|
|
53
55
|
export { pinClock, withClock } from "./core/clock.js";
|
|
54
56
|
export { sha256 } from "./core/hash.js";
|
|
55
57
|
export { ingestFile, type IngestResult } from "./core/ingest.js";
|
|
@@ -63,3 +65,4 @@ export { planUpdate, applyOpset, docsUpdate, type PlanUpdateOptions, type ApplyO
|
|
|
63
65
|
export { opsetKernelOps, renderOpsetPlan, serializeOpset, parseOpset, type Opset, type PlanOp, type OpsetSummary, type OpsetPrecondition, type PlanDisposition, } from "./mutate/opset.js";
|
|
64
66
|
export { rebuildIndex, type RebuildTarget } from "./core/store/rebuild.js";
|
|
65
67
|
export { runGc, type GcResult } from "./core/store/gc.js";
|
|
68
|
+
export { LIVE_LEAF_SQL, ftsIndexedRowCount, liveLeafCount } from "./core/store/fts.js";
|
package/dist/src/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { VERSION } from "./core/index.js";
|
|
2
|
+
export { versionInfo, coreVersion, nearestPackageVersion, COMPONENT_PACKAGES } from "./version.js";
|
|
3
|
+
export { SPEC_VERSIONS } from "./spec-versions.js";
|
|
2
4
|
export { AdapterCapability } from "./format/adapter.js";
|
|
3
5
|
export { registerAdapter, adapterForFormat, adapterForPath, registeredFormats, detectFormat } from "./format/registry.js";
|
|
4
6
|
export { markdownAdapter, MARKDOWN_FORMAT } from "./format/markdown.js";
|
|
@@ -28,7 +30,7 @@ export { observeFile, observeMany, observeOne, observeDelete, observeBatch } fro
|
|
|
28
30
|
export { buildServer } from "./mcp/server.js";
|
|
29
31
|
export { serveStdio } from "./mcp/stdio.js";
|
|
30
32
|
export { processCheckpoint } from "./sync/checkpoint.js";
|
|
31
|
-
export { reposStatus, syncStatus } from "./sync/admin.js";
|
|
33
|
+
export { reposStatus, syncStatus, reposList } from "./sync/admin.js";
|
|
32
34
|
// Read surface consumed by CLI read commands (11 §5.2–5.5).
|
|
33
35
|
export { docsOutline } from "./core/read/outline.js";
|
|
34
36
|
export { docsRead, reconstructContent } from "./core/read/document.js";
|
|
@@ -43,18 +45,18 @@ export { oqxRun, oqxRunAsync, collectSemanticPhrases, parseOqx } from "./oqx/run
|
|
|
43
45
|
// Embeddings + semantic retrieval (05 §5–6). The provider is a plugin loaded by
|
|
44
46
|
// package name; core carries no ML dependency.
|
|
45
47
|
export { EmbeddingWorker, SemanticUnavailable, contextPrefix, shouldEmbed, estimateTokens, } from "./search/embeddings.js";
|
|
46
|
-
export { buildEmbedTasks, buildDocEmbedTasks } from "./search/tasks.js";
|
|
48
|
+
export { buildEmbedTasks, buildDocEmbedTasks, staleEmbedCount } from "./search/tasks.js";
|
|
47
49
|
export { EmbedDrainer } from "./search/drain.js";
|
|
48
50
|
export { embeddingSettings } from "./search/provider.js";
|
|
49
51
|
export { createExternalProvider } from "./search/external.js";
|
|
50
52
|
export { hybridSearch } from "./search/rrf.js";
|
|
51
53
|
export { vectorSearch, docVectorSearch } from "./search/vector.js";
|
|
52
|
-
export { historyNode, diffUnified, unifiedDiff, changesSince } from "./graph/history.js";
|
|
54
|
+
export { historyNode, diffUnified, docDiffUnified, diffBlocks, unifiedDiff, changesSince, RevisionNotFound } from "./graph/history.js";
|
|
53
55
|
export { docLinks } from "./graph/links.js";
|
|
54
56
|
export { FilterInvalid } from "./search/cel/parser.js";
|
|
55
|
-
export { EngineError } from "./mcp/errors.js";
|
|
57
|
+
export { EngineError, errorBody } from "./mcp/errors.js";
|
|
56
58
|
export { MutationError } from "./mutate/tree.js";
|
|
57
|
-
export { isValidId, prefixOf, mintId, setIdMinter, withIdMinter, sequentialMinter } from "./core/ids.js";
|
|
59
|
+
export { isValidId, prefixOf, mintId, setIdMinter, withIdMinter, sequentialMinter, repeatingMinter, registerIdOracle } from "./core/ids.js";
|
|
58
60
|
// The clock seam (spec/surface §7.1): `omg mcp` pins the process clock under OMGBASE_SPEC_CLOCK.
|
|
59
61
|
export { pinClock, withClock } from "./core/clock.js";
|
|
60
62
|
export { sha256 } from "./core/hash.js";
|
|
@@ -73,4 +75,5 @@ export { planUpdate, applyOpset, docsUpdate, } from "./mutate/plan-update.js";
|
|
|
73
75
|
export { opsetKernelOps, renderOpsetPlan, serializeOpset, parseOpset, } from "./mutate/opset.js";
|
|
74
76
|
export { rebuildIndex } from "./core/store/rebuild.js";
|
|
75
77
|
export { runGc } from "./core/store/gc.js";
|
|
78
|
+
export { LIVE_LEAF_SQL, ftsIndexedRowCount, liveLeafCount } from "./core/store/fts.js";
|
|
76
79
|
//# sourceMappingURL=index.js.map
|
package/dist/src/mcp/errors.d.ts
CHANGED
|
@@ -15,3 +15,11 @@ export declare class EngineError extends Error {
|
|
|
15
15
|
});
|
|
16
16
|
body(): EngineErrorBody;
|
|
17
17
|
}
|
|
18
|
+
/** The rendered body of any thrown error (`error` is the code). */
|
|
19
|
+
export interface ErrorBody {
|
|
20
|
+
error: string;
|
|
21
|
+
message: string;
|
|
22
|
+
data?: unknown;
|
|
23
|
+
retriable: boolean;
|
|
24
|
+
}
|
|
25
|
+
export declare function errorBody(err: unknown): ErrorBody;
|