@omgbase/core 0.28.0 → 0.29.2

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 (74) hide show
  1. package/README.md +7 -5
  2. package/dist/src/core/read/document.d.ts +11 -10
  3. package/dist/src/core/read/document.js +12 -11
  4. package/dist/src/core/read/nodes.d.ts +10 -10
  5. package/dist/src/core/read/nodes.js +11 -11
  6. package/dist/src/core/read/reader.d.ts +37 -24
  7. package/dist/src/core/read/reader.js +44 -31
  8. package/dist/src/graph/history.d.ts +25 -22
  9. package/dist/src/graph/history.js +17 -17
  10. package/dist/src/graph/inbound-links.d.ts +7 -7
  11. package/dist/src/graph/inbound-links.js +7 -7
  12. package/dist/src/graph/link-health.d.ts +9 -9
  13. package/dist/src/graph/link-health.js +9 -9
  14. package/dist/src/graph/links.d.ts +3 -3
  15. package/dist/src/graph/links.js +4 -4
  16. package/dist/src/mcp/arguments.d.ts +10 -3
  17. package/dist/src/mcp/arguments.js +32 -9
  18. package/dist/src/mcp/errors.d.ts +1 -1
  19. package/dist/src/mcp/graph.d.ts +22 -22
  20. package/dist/src/mcp/graph.js +54 -47
  21. package/dist/src/mcp/reference.d.ts +29 -1
  22. package/dist/src/mcp/reference.js +398 -255
  23. package/dist/src/mcp/server.d.ts +9 -0
  24. package/dist/src/mcp/server.js +170 -108
  25. package/dist/src/mutate/apply.d.ts +6 -6
  26. package/dist/src/mutate/apply.js +1 -1
  27. package/dist/src/mutate/canonical.d.ts +1 -1
  28. package/dist/src/mutate/canonical.js +2 -2
  29. package/dist/src/mutate/commit.d.ts +3 -3
  30. package/dist/src/mutate/commit.js +4 -4
  31. package/dist/src/mutate/docs.d.ts +1 -1
  32. package/dist/src/mutate/docs.js +8 -8
  33. package/dist/src/mutate/effects.d.ts +17 -17
  34. package/dist/src/mutate/effects.js +113 -113
  35. package/dist/src/mutate/macros.d.ts +5 -5
  36. package/dist/src/mutate/macros.js +1 -1
  37. package/dist/src/mutate/materialize.js +2 -2
  38. package/dist/src/mutate/ops.js +2 -2
  39. package/dist/src/mutate/opset.d.ts +7 -7
  40. package/dist/src/mutate/plan-update.js +2 -2
  41. package/dist/src/mutate/plan.d.ts +8 -8
  42. package/dist/src/mutate/plan.js +25 -25
  43. package/dist/src/mutate/select.d.ts +4 -4
  44. package/dist/src/mutate/select.js +57 -56
  45. package/dist/src/mutate/sugar.d.ts +10 -10
  46. package/dist/src/mutate/sugar.js +21 -21
  47. package/dist/src/oqx-js/context.d.ts +8 -4
  48. package/dist/src/oqx-js/context.js +206 -189
  49. package/dist/src/oqx-js/names.d.ts +28 -17
  50. package/dist/src/oqx-js/names.js +115 -78
  51. package/dist/src/oqx-js/planner.d.ts +4 -8
  52. package/dist/src/oqx-js/planner.js +6 -10
  53. package/dist/src/oqx-js/root-row.d.ts +6 -5
  54. package/dist/src/oqx-js/root-row.js +15 -16
  55. package/dist/src/oqx-js/run.d.ts +18 -17
  56. package/dist/src/oqx-js/run.js +57 -54
  57. package/dist/src/oqx-js/sql/translate.d.ts +5 -5
  58. package/dist/src/oqx-js/sql/translate.js +162 -161
  59. package/dist/src/oqx-js/store-index.d.ts +1 -1
  60. package/dist/src/oqx-js/store-index.js +28 -30
  61. package/dist/src/search/external.d.ts +10 -0
  62. package/dist/src/search/external.js +20 -2
  63. package/dist/src/search/resolve.d.ts +2 -2
  64. package/dist/src/search/resolve.js +1 -1
  65. package/dist/src/search/rrf.js +2 -2
  66. package/dist/src/search/text.d.ts +5 -5
  67. package/dist/src/search/text.js +2 -2
  68. package/dist/src/spec-versions.d.ts +7 -7
  69. package/dist/src/spec-versions.js +6 -6
  70. package/dist/src/surface-paths.d.ts +18 -17
  71. package/dist/src/surface-paths.js +23 -21
  72. package/dist/src/sync/admin.d.ts +2 -2
  73. package/dist/src/sync/admin.js +1 -1
  74. package/package.json +2 -2
@@ -8,10 +8,10 @@ export interface Sugar {
8
8
  effects: Effect[];
9
9
  reason?: string;
10
10
  }
11
- /** A live document as the builders address it: its id and its storage-form path (the reasons spell the path). */
11
+ /** A live document as the builders address it: its row attributes `_id` and `_path` (the storage-form path; the reasons spell it). */
12
12
  export interface SugarDoc {
13
- id: string;
14
- path: string;
13
+ _id: string;
14
+ _path: string;
15
15
  }
16
16
  /** A caller's guard as an effect guard: absent stays absent, an empty object stays an empty guard (the planner then pins what it needs). */
17
17
  export declare function guardOf(e: {
@@ -40,21 +40,21 @@ export declare function moveDocEffects(doc: SugarDoc, toPath: string, retargetIn
40
40
  /** `docs_delete` / `omg rm --doc`: one `remove { target: document }`; reason `delete <path>`. */
41
41
  export declare function deleteDocEffects(doc: SugarDoc): Sugar;
42
42
  /**
43
- * `docs_set_meta` / `omg meta`: one `set`/`unset frontmatter.<k>` per key, `unset`
43
+ * `docs_set_meta` / `omg meta`: one `set`/`unset _frontmatter.<k>` per key, `unset`
44
44
  * winning a key named in both (the legacy merge spread `set` then deleted `unset`);
45
45
  * reason `set_meta <path>`. An empty patch yields no effect — the caller refuses
46
46
  * it (`filter_invalid` "pass `set` and/or `unset`", spec/surface §9).
47
47
  */
48
48
  export declare function setMetaEffects(doc: SugarDoc, set: Record<string, unknown> | undefined, unset: readonly string[] | undefined): Sugar;
49
49
  /** `docs_update` / `omg update <doc>`: one `set { document, content }`; the reason is the caller's. */
50
- export declare function updateContentEffects(doc: Pick<SugarDoc, "id">, content: string, reason?: string): Sugar;
50
+ export declare function updateContentEffects(doc: Pick<SugarDoc, "_id">, content: string, reason?: string): Sugar;
51
51
  /** `blocks_insert` / `omg insert`: `insert into <document|block> at …`; the caller's `expect` is the destination-parent CAS. */
52
52
  export declare function insertEffects(into: EffectTarget, at: EffectAt, markdown: string, expect?: {
53
53
  parent_children_hash?: string | undefined;
54
54
  }): Sugar;
55
55
  /**
56
56
  * `blocks_update` / `omg update <block>` / `omg edit`: `set markdown` and/or `set
57
- * attrs.checked`. The caller's `expect` guards the FIRST effect (the content CAS
57
+ * _attrs.checked`. The caller's `expect` guards the FIRST effect (the content CAS
58
58
  * is checked once, against the bytes the caller saw); a second effect is pinned
59
59
  * by the planner to the block as the first left it. Nothing to set → no effect
60
60
  * (the caller refuses it).
@@ -77,7 +77,7 @@ export declare function removeBlocksEffects(ids: readonly string[]): Sugar;
77
77
  export declare function splitEffects(id: string, at: readonly number[]): Sugar;
78
78
  /** `blocks_merge` / `omg merge`: one `merge { targets, separator? }`. */
79
79
  export declare function mergeEffects(ids: readonly string[], separator?: string): Sugar;
80
- /** `blocks_check` / `omg done`: N × `set attrs.checked` (a block named twice is one write — the planner drops the duplicate). */
80
+ /** `blocks_check` / `omg done`: N × `set _attrs.checked` (a block named twice is one write — the planner drops the duplicate). */
81
81
  export declare function checkEffects(ids: readonly string[], checked: boolean): Sugar;
82
82
  /** `nodes_set` / `omg node set`: one `set { node, field: prop, value }`. */
83
83
  export declare function nodeSetEffects(nodeId: string, prop: string, value: string): Sugar;
@@ -108,10 +108,10 @@ export declare function applySugar(store: Store, request: SugarRequest & {
108
108
  plan: Plan;
109
109
  receipt?: Receipt;
110
110
  };
111
- /** The document-operation result the `omg` document verbs and the fixture `docs` step record (`spec/mutate` §9): `{ id, path, committed }`, the path in the storage form. */
111
+ /** The document-operation result the `omg` document verbs and the fixture `docs` step record (`spec/mutate` §9): `{ _id, _path, committed }`, the path in the storage form. */
112
112
  export interface DocOpOutcome {
113
- id: string;
114
- path: string;
113
+ _id: string;
114
+ _path: string;
115
115
  committed: true;
116
116
  }
117
117
  /** `docs_create`'s document is the receipt's first revision (`new_ids["$new.0"]` is the same id); every other operation's is the one addressed. */
@@ -4,8 +4,8 @@ import { canonicalDocPath, planInboundRetarget } from "./docs.js";
4
4
  import { resolveDocStore } from "./doc-store.js";
5
5
  import { MutationError } from "./tree.js";
6
6
  import { applyEffectsDetailed, stripEffectIndex } from "./plan.js";
7
- const documentTarget = (id) => ({ kind: "document", id });
8
- const blockTarget = (id) => ({ kind: "block", id });
7
+ const documentTarget = (id) => ({ kind: "document", _id: id });
8
+ const blockTarget = (id) => ({ kind: "block", _id: id });
9
9
  /** A caller's guard as an effect guard: absent stays absent, an empty object stays an empty guard (the planner then pins what it needs). */
10
10
  export function guardOf(e) {
11
11
  if (!e)
@@ -41,30 +41,30 @@ export function createEffects(path, markdown, frontmatter) {
41
41
  /** `docs_move` / `omg mv`: one `move { target: document, to, retarget_inbound }`; reason `move <from> -> <to>`. */
42
42
  export function moveDocEffects(doc, toPath, retargetInbound = true) {
43
43
  const to = canonicalDocPath(toPath);
44
- return { effects: [{ op: "move", target: documentTarget(doc.id), to, ...(retargetInbound ? {} : { retarget_inbound: false }) }], reason: `move ${doc.path} -> ${to}` };
44
+ return { effects: [{ op: "move", target: documentTarget(doc._id), to, ...(retargetInbound ? {} : { retarget_inbound: false }) }], reason: `move ${doc._path} -> ${to}` };
45
45
  }
46
46
  /** `docs_delete` / `omg rm --doc`: one `remove { target: document }`; reason `delete <path>`. */
47
47
  export function deleteDocEffects(doc) {
48
- return { effects: [{ op: "remove", target: documentTarget(doc.id) }], reason: `delete ${doc.path}` };
48
+ return { effects: [{ op: "remove", target: documentTarget(doc._id) }], reason: `delete ${doc._path}` };
49
49
  }
50
50
  /**
51
- * `docs_set_meta` / `omg meta`: one `set`/`unset frontmatter.<k>` per key, `unset`
51
+ * `docs_set_meta` / `omg meta`: one `set`/`unset _frontmatter.<k>` per key, `unset`
52
52
  * winning a key named in both (the legacy merge spread `set` then deleted `unset`);
53
53
  * reason `set_meta <path>`. An empty patch yields no effect — the caller refuses
54
54
  * it (`filter_invalid` "pass `set` and/or `unset`", spec/surface §9).
55
55
  */
56
56
  export function setMetaEffects(doc, set, unset) {
57
57
  const gone = unset ?? [];
58
- const target = documentTarget(doc.id);
58
+ const target = documentTarget(doc._id);
59
59
  const effects = [
60
- ...Object.entries(set ?? {}).filter(([k]) => !gone.includes(k)).map(([k, value]) => ({ op: "set", target, field: `frontmatter.${k}`, value })),
61
- ...gone.map((k) => ({ op: "unset", target, field: `frontmatter.${k}` })),
60
+ ...Object.entries(set ?? {}).filter(([k]) => !gone.includes(k)).map(([k, value]) => ({ op: "set", target, field: `_frontmatter.${k}`, value })),
61
+ ...gone.map((k) => ({ op: "unset", target, field: `_frontmatter.${k}` })),
62
62
  ];
63
- return { effects, reason: `set_meta ${doc.path}` };
63
+ return { effects, reason: `set_meta ${doc._path}` };
64
64
  }
65
65
  /** `docs_update` / `omg update <doc>`: one `set { document, content }`; the reason is the caller's. */
66
66
  export function updateContentEffects(doc, content, reason) {
67
- return { effects: [{ op: "set", target: documentTarget(doc.id), field: "content", value: content }], ...(reason !== undefined ? { reason } : {}) };
67
+ return { effects: [{ op: "set", target: documentTarget(doc._id), field: "content", value: content }], ...(reason !== undefined ? { reason } : {}) };
68
68
  }
69
69
  // ---- the block-level tools (spec/surface §4) ----------------------------------------------
70
70
  /** `blocks_insert` / `omg insert`: `insert into <document|block> at …`; the caller's `expect` is the destination-parent CAS. */
@@ -73,7 +73,7 @@ export function insertEffects(into, at, markdown, expect) {
73
73
  }
74
74
  /**
75
75
  * `blocks_update` / `omg update <block>` / `omg edit`: `set markdown` and/or `set
76
- * attrs.checked`. The caller's `expect` guards the FIRST effect (the content CAS
76
+ * _attrs.checked`. The caller's `expect` guards the FIRST effect (the content CAS
77
77
  * is checked once, against the bytes the caller saw); a second effect is pinned
78
78
  * by the planner to the block as the first left it. Nothing to set → no effect
79
79
  * (the caller refuses it).
@@ -85,7 +85,7 @@ export function updateBlockEffects(id, patch) {
85
85
  if (patch.markdown !== undefined)
86
86
  effects.push({ op: "set", target, field: "markdown", value: patch.markdown, ...expect });
87
87
  if (patch.checked !== undefined)
88
- effects.push({ op: "set", target, field: "attrs.checked", value: patch.checked, ...(effects.length === 0 ? expect : {}) });
88
+ effects.push({ op: "set", target, field: "_attrs.checked", value: patch.checked, ...(effects.length === 0 ? expect : {}) });
89
89
  return { effects, reason: "blocks_update" };
90
90
  }
91
91
  /** `blocks_move` / `omg move`: one `move { targets, into, at, expect }`. */
@@ -104,13 +104,13 @@ export function splitEffects(id, at) {
104
104
  export function mergeEffects(ids, separator) {
105
105
  return { effects: [{ op: "merge", targets: ids.map(blockTarget), ...(separator !== undefined ? { separator } : {}) }], reason: "blocks_merge" };
106
106
  }
107
- /** `blocks_check` / `omg done`: N × `set attrs.checked` (a block named twice is one write — the planner drops the duplicate). */
107
+ /** `blocks_check` / `omg done`: N × `set _attrs.checked` (a block named twice is one write — the planner drops the duplicate). */
108
108
  export function checkEffects(ids, checked) {
109
- return { effects: ids.map((id) => ({ op: "set", target: blockTarget(id), field: "attrs.checked", value: checked })), reason: "blocks_check" };
109
+ return { effects: ids.map((id) => ({ op: "set", target: blockTarget(id), field: "_attrs.checked", value: checked })), reason: "blocks_check" };
110
110
  }
111
111
  /** `nodes_set` / `omg node set`: one `set { node, field: prop, value }`. */
112
112
  export function nodeSetEffects(nodeId, prop, value) {
113
- return { effects: [{ op: "set", target: { kind: "node", id: nodeId }, field: prop, value }], reason: "nodes_set" };
113
+ return { effects: [{ op: "set", target: { kind: "node", _id: nodeId }, field: prop, value }], reason: "nodes_set" };
114
114
  }
115
115
  /** `blocks_append` / `omg append`: `insert at end` into a heading's section or a container block (the caller decided which by the block's kind). */
116
116
  export function appendEffects(into, text) {
@@ -143,13 +143,13 @@ export function applySugar(store, request, sugar) {
143
143
  }
144
144
  /** `docs_create`'s document is the receipt's first revision (`new_ids["$new.0"]` is the same id); every other operation's is the one addressed. */
145
145
  export function createdDoc(receipt, path) {
146
- const id = receipt.new_ids["$new.0"] ?? receipt.revisions[0]?.id;
146
+ const id = receipt.new_ids["$new.0"] ?? receipt.revisions[0]?._id;
147
147
  if (id === undefined)
148
148
  throw new Error("createdDoc: the receipt names no created document");
149
- return { id, path, committed: true };
149
+ return { _id: id, _path: path, committed: true };
150
150
  }
151
- export function docOutcome(doc, path = doc.path) {
152
- return { id: doc.id, path, committed: true };
151
+ export function docOutcome(doc, path = doc._path) {
152
+ return { _id: doc._id, _path: path, committed: true };
153
153
  }
154
154
  /**
155
155
  * Who links to the document BY PATH as written, and what the move's retarget
@@ -158,10 +158,10 @@ export function docOutcome(doc, path = doc.path) {
158
158
  */
159
159
  export function moveLinks(store, repoId, doc, toPath, retargetInbound = true) {
160
160
  const to = canonicalDocPath(toPath);
161
- const inbound = inboundLinksTo(store, repoId, doc.id, doc.path);
161
+ const inbound = inboundLinksTo(store, repoId, doc._id, doc._path);
162
162
  if (!retargetInbound || inbound.length === 0)
163
163
  return { dangling: inbound, retargeted: null };
164
- const plan = planInboundRetarget(store, doc.id, doc.path, to, inbound);
164
+ const plan = planInboundRetarget(store, doc._id, doc._path, to, inbound);
165
165
  return { dangling: plan.dangling, retargeted: { blocks: plan.blocks, docs: plan.docs } };
166
166
  }
167
167
  //# sourceMappingURL=sugar.js.map
@@ -13,9 +13,13 @@ declare const TARGET: unique symbol;
13
13
  /** The engine attributes per kind (spec/surface §1.2 table). Exported so the
14
14
  * translator's tests pin the two against each other. */
15
15
  export declare const ATTRIBUTES: Readonly<Record<Kind, ReadonlySet<string>>>;
16
- /** The source handles of a document (§1.2): `data` is the merged authored view
16
+ /** The source handles of a document (§1.2): `_data` is the merged authored view
17
17
  * (frontmatter + inline), the other two one source each. */
18
18
  export declare const SOURCE_HANDLES: ReadonlySet<string>;
19
+ /** The `properties.source` a handle narrows a read to: `_data` → both authored sources (null). */
20
+ export declare function handleSource(handle: string): string | null;
21
+ /** The reach-through handles per kind (§1.2) — each a statically single row of another kind. */
22
+ export declare const REACH_THROUGHS: Readonly<Record<Kind, ReadonlySet<string>>>;
19
23
  /** The value of a statically SINGLE relation that has no row — `dst` on an
20
24
  * external or dangling link, `block` on a node without one (oqx 0.20, SEMANTICS
21
25
  * §3): an object the engine treats as one row with no rows, so `dst { title }`
@@ -41,7 +45,7 @@ export declare function makeStoreContext(store: Store, repoId: string, opts?: St
41
45
  export declare function tagRows(rows: Record<string, unknown>[], target: Kind): unknown[];
42
46
  /**
43
47
  * A store row surfacing as a VALUE in a result (spec/surface §1.4, rows as
44
- * values, 1.2) is rendered as `{ id, path }` (3.0) — its id column and its
48
+ * values, 1.2) is rendered as `{ _id, _path }` (5.0) — its id column and its
45
49
  * document's path in the reference form (`/a.md`, §1 "Paths"), the same two keys
46
50
  * every hit carries, spelled as the attributes that read them — never the store
47
51
  * row itself.
@@ -49,7 +53,7 @@ export declare function tagRows(rows: Record<string, unknown>[], target: Kind):
49
53
  * alone).
50
54
  */
51
55
  export declare function rowRef(value: unknown): {
52
- id: string;
53
- path: string;
56
+ _id: string;
57
+ _path: string;
54
58
  } | undefined;
55
59
  export { TARGET };