@omgbase/core 0.19.0 → 0.21.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/ingest.d.ts +2 -0
- package/dist/src/core/ingest.js +13 -0
- package/dist/src/core/read/document.d.ts +9 -8
- package/dist/src/core/read/document.js +0 -2
- package/dist/src/core/store/gc.d.ts +13 -1
- package/dist/src/core/store/gc.js +24 -5
- package/dist/src/core/store/size.d.ts +4 -1
- package/dist/src/core/store/size.js +11 -2
- package/dist/src/mcp/arguments.d.ts +10 -2
- package/dist/src/mcp/arguments.js +37 -3
- package/dist/src/mcp/reference.d.ts +1 -1
- package/dist/src/mcp/reference.js +36 -4
- package/dist/src/mcp/server.js +50 -23
- package/dist/src/mutate/effects.d.ts +23 -5
- package/dist/src/mutate/effects.js +111 -22
- package/dist/src/mutate/known-ids.d.ts +19 -0
- package/dist/src/mutate/known-ids.js +47 -7
- package/dist/src/mutate/ops.d.ts +1 -0
- package/dist/src/mutate/ops.js +20 -1
- package/dist/src/mutate/select.d.ts +0 -11
- package/dist/src/mutate/select.js +33 -9
- package/dist/src/oqx-js/context.d.ts +9 -2
- package/dist/src/oqx-js/context.js +74 -28
- package/dist/src/oqx-js/names.d.ts +40 -0
- package/dist/src/oqx-js/names.js +347 -0
- package/dist/src/oqx-js/planner.d.ts +3 -3
- package/dist/src/oqx-js/planner.js +13 -9
- package/dist/src/oqx-js/root-row.d.ts +15 -4
- package/dist/src/oqx-js/root-row.js +18 -10
- package/dist/src/oqx-js/run.d.ts +18 -1
- package/dist/src/oqx-js/run.js +31 -12
- package/dist/src/oqx-js/sql/translate.js +1 -1
- package/dist/src/spec-versions.d.ts +5 -5
- package/dist/src/spec-versions.js +4 -4
- package/dist/src/sync/observe.js +9 -3
- package/package.json +2 -2
package/dist/src/oqx-js/run.js
CHANGED
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
// in-tree compiler, so every caller and the corpus are unchanged.
|
|
7
7
|
import { parse, PlannedEngine, InMemoryEngine, OqxError, resolveAliases, transform, visit, build, semantics } from "@omgbase/oqx";
|
|
8
8
|
import { makeStoreContext, rowRef } from "./context.js";
|
|
9
|
-
import { SQLiteQueryPlanner
|
|
10
|
-
import { REPO_REMOVED_MESSAGE,
|
|
9
|
+
import { SQLiteQueryPlanner } from "./planner.js";
|
|
10
|
+
import { REPO_REMOVED_MESSAGE, ROOTS, bareTargetMessage, pastRootMessage, unknownTargetMessage } from "./root-row.js";
|
|
11
|
+
import { checkNames } from "./names.js";
|
|
11
12
|
import { FilterInvalid } from "../search/cel/parser.js";
|
|
12
13
|
import { float32ToBlob } from "../core/vec.js";
|
|
13
14
|
import { encodeCursor as encodeKeyset, decodePathCursor } from "../core/cursor.js";
|
|
@@ -72,8 +73,8 @@ export function rootPathLiterals(e) {
|
|
|
72
73
|
export function checkRootSpellings(q) {
|
|
73
74
|
// A top-level `from <name>` that is no collection (`from edges`, the links
|
|
74
75
|
// target's name before 3.0) would scan an absent root and come back empty:
|
|
75
|
-
// refused, naming the
|
|
76
|
-
if (q.source.kind === "ident" && !
|
|
76
|
+
// refused, naming the five collections (root-row.ts).
|
|
77
|
+
if (q.source.kind === "ident" && !ROOTS.has(q.source.name))
|
|
77
78
|
throw new FilterInvalid(unknownTargetMessage(q.source.name), "OQX");
|
|
78
79
|
visit(q, {
|
|
79
80
|
enter(node, ctx) {
|
|
@@ -84,7 +85,7 @@ export function checkRootSpellings(q) {
|
|
|
84
85
|
if (node.kind === "ident" && ctx.depth >= 1 && (node.name === "docs" || node.name === "links")) {
|
|
85
86
|
throw new FilterInvalid(bareTargetMessage(node.name, ctx.depth), "OQX");
|
|
86
87
|
}
|
|
87
|
-
if (node.kind === "outer" &&
|
|
88
|
+
if (node.kind === "outer" && ROOTS.has(node.name) && node.levels > ctx.depth) {
|
|
88
89
|
throw new FilterInvalid(pastRootMessage(node.name, node.levels), "OQX");
|
|
89
90
|
}
|
|
90
91
|
},
|
|
@@ -165,8 +166,9 @@ function envelopeCollision(items) {
|
|
|
165
166
|
return null;
|
|
166
167
|
}
|
|
167
168
|
// A hit is a store row (spec/surface §1.4, 1.5). The engine's top-level rows
|
|
168
|
-
// are store rows by construction when the source is a bare root scan
|
|
169
|
-
//
|
|
169
|
+
// are store rows by construction when the source is a bare root scan (one of
|
|
170
|
+
// the five collections, `revisions` included — the planner's `rootTarget` is
|
|
171
|
+
// narrower: the four it can plan) and nothing re-projects them; a `follow` destination (`follow before` over a
|
|
170
172
|
// frontmatter list of paths), a `from E` re-projection or any other source can
|
|
171
173
|
// reach a scalar, which the injected `id`/`path` reads would render as the
|
|
172
174
|
// junk hit `{ id: "undefined", path: "" }`. For those queries the row itself is
|
|
@@ -177,7 +179,7 @@ function envelopeCollision(items) {
|
|
|
177
179
|
const SELF_KEY = "__oqx_self";
|
|
178
180
|
const SELF_ITEM = build.field(SELF_KEY, build.ident("$it"));
|
|
179
181
|
function mayReachNonRows(q) {
|
|
180
|
-
return q.follow !== null || q.from.length > 0 ||
|
|
182
|
+
return q.follow !== null || q.from.length > 0 || !(q.source.kind === "ident" && ROOTS.has(q.source.name));
|
|
181
183
|
}
|
|
182
184
|
function describeValue(v) {
|
|
183
185
|
if (v === null || v === undefined)
|
|
@@ -195,7 +197,7 @@ function describeValue(v) {
|
|
|
195
197
|
return "an object";
|
|
196
198
|
}
|
|
197
199
|
function notAStoreRow(v) {
|
|
198
|
-
return new FilterInvalid(`a hit must be a document, block, node or
|
|
200
|
+
return new FilterInvalid(`a hit must be a document, block, node, link or revision row — the query reached ${describeValue(v)}; to follow document references held in a property use refs(<field>)`, "OQX");
|
|
199
201
|
}
|
|
200
202
|
// The reserved key a top-level `values` projection's single item is renamed to,
|
|
201
203
|
// so it rides through id/path injection, keyset paging, and distinct as an
|
|
@@ -294,19 +296,36 @@ function oqxRunInner(store, repoId, source, opts) {
|
|
|
294
296
|
const reserved = reservedAlias(raw.select);
|
|
295
297
|
if (reserved)
|
|
296
298
|
throw reserved;
|
|
297
|
-
|
|
299
|
+
// The source entry is every read: a tier-3 name on an open kind is a hint.
|
|
300
|
+
return oqxRunQuery(store, repoId, raw, { unknownNames: "hint", ...opts });
|
|
298
301
|
}
|
|
299
302
|
/**
|
|
300
303
|
* The AST entry (4.1): run an already parsed query — the source path above
|
|
301
304
|
* after `parse`, and the selector compiler (`mutate/select.ts`), which appends
|
|
302
305
|
* its slot items to the RAW tree so a user alias a template reads is inlined
|
|
303
306
|
* by the alias resolution here. Errors are the library's own (`OqxError`);
|
|
304
|
-
* `oqxRun` normalizes them, a caller of this entry does the same.
|
|
307
|
+
* `oqxRun` normalizes them, a caller of this entry does the same. Unknown
|
|
308
|
+
* names (4.6) default to `"refuse"` here: this entry's caller is the write
|
|
309
|
+
* selector, where a name no row carries would select every row; the source
|
|
310
|
+
* entry passes `"hint"`.
|
|
305
311
|
*/
|
|
306
312
|
export function oqxRunQuery(store, repoId, raw, opts = {}) {
|
|
313
|
+
checkRootSpellings(raw);
|
|
314
|
+
// Unknown names (spec/surface §1.5): judged over the RAW tree — before alias
|
|
315
|
+
// resolution and the runner's own items — so an alias is never mistaken for
|
|
316
|
+
// a row property and the verdict never depends on the rows. The selector
|
|
317
|
+
// compiler's slot items (`__omg_sel_*`, the templates' expressions) are not
|
|
318
|
+
// the selector: an expression reading an absent property there is
|
|
319
|
+
// spec/mutate's `target_missing` / absent value, not an unknown name.
|
|
320
|
+
const own = { ...raw, select: raw.select.filter((it) => !RESERVED_ALIAS_PREFIXES.some((p) => it.name.startsWith(p))) };
|
|
321
|
+
const hints = checkNames(store, repoId, own, opts.unknownNames ?? "refuse");
|
|
322
|
+
const result = runResolved(store, repoId, raw, opts);
|
|
323
|
+
// `hints` is the last member, present only when there is something to say.
|
|
324
|
+
return hints.length === 0 ? result : { ...result, hints };
|
|
325
|
+
}
|
|
326
|
+
function runResolved(store, repoId, raw, opts) {
|
|
307
327
|
// The query's `select` aliases are resolved HERE, once, before the runner
|
|
308
328
|
// renames/injects items (an engine evaluates the query it is given).
|
|
309
|
-
checkRootSpellings(raw);
|
|
310
329
|
const parsed = rewriteQuery(resolveAliases(raw));
|
|
311
330
|
const consumer = parsed.consumer;
|
|
312
331
|
const ctxOpts = opts.semanticVectors ? { semanticVectors: opts.semanticVectors } : {};
|
|
@@ -53,7 +53,7 @@ import { TARGETS } from "../root-row.js";
|
|
|
53
53
|
* `translate.test.ts` asserts this set against the store context.
|
|
54
54
|
*/
|
|
55
55
|
export const NON_PROPERTY_NAMES = {
|
|
56
|
-
docs: new Set(["doc", "nodes", "blocks", "out_links", "in_links", "data", "frontmatter", "inline"]),
|
|
56
|
+
docs: new Set(["doc", "nodes", "blocks", "out_links", "in_links", "revisions", "data", "frontmatter", "inline"]),
|
|
57
57
|
blocks: new Set(["block", "doc", "children", "nodes", "out_links", "section", "attrs"]),
|
|
58
58
|
nodes: new Set(["section", "doc", "block", "blocks", "subsections", "children", "attrs"]),
|
|
59
59
|
links: new Set(["doc", "dst"]),
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
export declare const SPEC_VERSIONS: {
|
|
2
|
-
readonly oqx: "0.
|
|
2
|
+
readonly oqx: "0.23";
|
|
3
3
|
readonly format: "0.2";
|
|
4
4
|
readonly reconcile: "2.3";
|
|
5
|
-
readonly store: "14.
|
|
5
|
+
readonly store: "14.2";
|
|
6
6
|
readonly properties: "1.1";
|
|
7
7
|
readonly graph: "1.1";
|
|
8
8
|
readonly search: "2.0";
|
|
9
|
-
readonly mutate: "3.
|
|
9
|
+
readonly mutate: "3.5";
|
|
10
10
|
readonly sync: "2.2";
|
|
11
|
-
readonly surface: "4.
|
|
12
|
-
readonly cli: "4.
|
|
11
|
+
readonly surface: "4.7";
|
|
12
|
+
readonly cli: "4.5";
|
|
13
13
|
};
|
|
14
14
|
export type SpecName = keyof typeof SPEC_VERSIONS;
|
|
@@ -13,13 +13,13 @@ export const SPEC_VERSIONS = {
|
|
|
13
13
|
oqx: LANGUAGE_VERSION,
|
|
14
14
|
format: "0.2",
|
|
15
15
|
reconcile: "2.3",
|
|
16
|
-
store: "14.
|
|
16
|
+
store: "14.2",
|
|
17
17
|
properties: "1.1",
|
|
18
18
|
graph: "1.1",
|
|
19
19
|
search: "2.0",
|
|
20
|
-
mutate: "3.
|
|
20
|
+
mutate: "3.5",
|
|
21
21
|
sync: "2.2",
|
|
22
|
-
surface: "4.
|
|
23
|
-
cli: "4.
|
|
22
|
+
surface: "4.7",
|
|
23
|
+
cli: "4.5",
|
|
24
24
|
};
|
|
25
25
|
//# sourceMappingURL=spec-versions.js.map
|
package/dist/src/sync/observe.js
CHANGED
|
@@ -189,9 +189,15 @@ function commitPrepared(store, repoId, prepared, ts, oldHashHex, newHashHex) {
|
|
|
189
189
|
const conflicted = hasConflictMarkers(content);
|
|
190
190
|
const resolveIds = makeReconcilingResolver(store, repoId, { ts, path, prepared });
|
|
191
191
|
const res = ingestFile(store, repoId, path, content, { ts, origin: "observed", resolveIds, parsed: prepared.tree, conflicted });
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
192
|
+
// The outcome counts every verdict the matcher produced, `same` included —
|
|
193
|
+
// it describes what the matcher saw; the `dispositions` table describes
|
|
194
|
+
// what changed (spec/store §5.4 step 10, 14.2: `same` is not persisted), so
|
|
195
|
+
// the counts come from the in-memory result, not the table. Kinds in
|
|
196
|
+
// bytewise order, as the table query listed them through 14.1.
|
|
197
|
+
const counts = new Map();
|
|
198
|
+
for (const d of prepared.result.dispositions)
|
|
199
|
+
counts.set(d.kind, (counts.get(d.kind) ?? 0) + 1);
|
|
200
|
+
const rows = [...counts].map(([kind, n]) => ({ kind, n })).sort((a, b) => (a.kind < b.kind ? -1 : a.kind > b.kind ? 1 : 0));
|
|
195
201
|
return {
|
|
196
202
|
docId: res.docId,
|
|
197
203
|
path,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@omgbase/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "Open Markdown Graph Base — embedded engine",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
58
|
-
"@omgbase/oqx": "^0.
|
|
58
|
+
"@omgbase/oqx": "^0.23.0",
|
|
59
59
|
"better-sqlite3": "^13.0.3",
|
|
60
60
|
"mdast-util-from-markdown": "^2.0.2",
|
|
61
61
|
"mdast-util-frontmatter": "^2.0.1",
|