@x12i/memorix-retrieval 1.5.0 → 1.6.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.
- package/README.md +1 -0
- package/dist/client/create-client.d.ts.map +1 -1
- package/dist/client/create-client.js +17 -12
- package/dist/client/create-client.js.map +1 -1
- package/dist/client/create-from-env.d.ts +4 -0
- package/dist/client/create-from-env.d.ts.map +1 -1
- package/dist/client/create-from-env.js +10 -3
- package/dist/client/create-from-env.js.map +1 -1
- package/dist/client/create-xronox-from-env.d.ts +16 -0
- package/dist/client/create-xronox-from-env.d.ts.map +1 -0
- package/dist/client/create-xronox-from-env.js +17 -0
- package/dist/client/create-xronox-from-env.js.map +1 -0
- package/dist/client/types.d.ts +7 -5
- package/dist/client/types.d.ts.map +1 -1
- package/dist/client/xronox-adapter.d.ts +14 -0
- package/dist/client/xronox-adapter.d.ts.map +1 -0
- package/dist/client/xronox-adapter.js +69 -0
- package/dist/client/xronox-adapter.js.map +1 -0
- package/dist/client/xronox-like.d.ts +24 -0
- package/dist/client/xronox-like.d.ts.map +1 -1
- package/dist/data/memorix-count.d.ts +11 -0
- package/dist/data/memorix-count.d.ts.map +1 -0
- package/dist/data/memorix-count.js +38 -0
- package/dist/data/memorix-count.js.map +1 -0
- package/dist/data/memorix-read.d.ts +1 -1
- package/dist/data/memorix-read.d.ts.map +1 -1
- package/dist/data/memorix-read.js +21 -16
- package/dist/data/memorix-read.js.map +1 -1
- package/dist/explorer/collection-inventory.d.ts +77 -0
- package/dist/explorer/collection-inventory.d.ts.map +1 -0
- package/dist/explorer/collection-inventory.js +302 -0
- package/dist/explorer/collection-inventory.js.map +1 -0
- package/dist/explorer/entity-graph.d.ts +35 -12
- package/dist/explorer/entity-graph.d.ts.map +1 -1
- package/dist/explorer/entity-graph.js +117 -55
- package/dist/explorer/entity-graph.js.map +1 -1
- package/dist/explorer/health.d.ts +1 -0
- package/dist/explorer/health.d.ts.map +1 -1
- package/dist/explorer/health.js +53 -0
- package/dist/explorer/health.js.map +1 -1
- package/dist/explorer/raw-reads.d.ts.map +1 -1
- package/dist/explorer/raw-reads.js +4 -12
- package/dist/explorer/raw-reads.js.map +1 -1
- package/dist/explorer/scoped-workspace.d.ts.map +1 -1
- package/dist/explorer/scoped-workspace.js +20 -58
- package/dist/explorer/scoped-workspace.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/retrieval/fetch-list.d.ts.map +1 -1
- package/dist/retrieval/fetch-list.js +5 -8
- package/dist/retrieval/fetch-list.js.map +1 -1
- package/dist/tests/collection-inventory.test.d.ts +2 -0
- package/dist/tests/collection-inventory.test.d.ts.map +1 -0
- package/dist/tests/collection-inventory.test.js +207 -0
- package/dist/tests/collection-inventory.test.js.map +1 -0
- package/dist/tests/entity-graph.test.d.ts +2 -0
- package/dist/tests/entity-graph.test.d.ts.map +1 -0
- package/dist/tests/entity-graph.test.js +148 -0
- package/dist/tests/entity-graph.test.js.map +1 -0
- package/dist/tests/fetch-list.test.js +1 -1
- package/dist/tests/fetch-list.test.js.map +1 -1
- package/dist/tests/package-json.test.d.ts +2 -0
- package/dist/tests/package-json.test.d.ts.map +1 -0
- package/dist/tests/package-json.test.js +14 -0
- package/dist/tests/package-json.test.js.map +1 -0
- package/docs/DATA-TIER-CONTRACT.md +16 -8
- package/docs/EXPLORER-HOST-APIS.md +16 -2
- package/docs/MEMORIX-CATALOX-CONTRACTS.md +8 -4
- package/docs/XRONOX-DATA-TIER-REQUIREMENTS.md +132 -0
- package/docs/fr/README.md +15 -0
- package/docs/fr/xronox-fr-list-collections.md +196 -0
- package/docs/fr/xronox-fr-memorix-env-preset.md +69 -0
- package/docs/fr/xronox-fr-per-role-selftest.md +60 -0
- package/package.json +3 -12
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import pkg from "../../package.json" with { type: "json" };
|
|
3
|
+
describe("package.json sanity", () => {
|
|
4
|
+
it("does not list @x12i/memorix-retrieval as its own dependency", () => {
|
|
5
|
+
const deps = pkg.dependencies;
|
|
6
|
+
const devDeps = pkg.devDependencies;
|
|
7
|
+
const peerDeps = pkg
|
|
8
|
+
.peerDependencies;
|
|
9
|
+
expect(deps?.["@x12i/memorix-retrieval"]).toBeUndefined();
|
|
10
|
+
expect(devDeps?.["@x12i/memorix-retrieval"]).toBeUndefined();
|
|
11
|
+
expect(peerDeps?.["@x12i/memorix-retrieval"]).toBeUndefined();
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
//# sourceMappingURL=package-json.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-json.test.js","sourceRoot":"","sources":["../../src/tests/package-json.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,GAAG,MAAM,oBAAoB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAE3D,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,MAAM,IAAI,GAAG,GAAG,CAAC,YAAkD,CAAC;QACpE,MAAM,OAAO,GAAG,GAAG,CAAC,eAAqD,CAAC;QAC1E,MAAM,QAAQ,GAAI,GAAqD;aACpE,gBAAgB,CAAC;QAEpB,MAAM,CAAC,IAAI,EAAE,CAAC,yBAAyB,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;QAC1D,MAAM,CAAC,OAAO,EAAE,CAAC,yBAAyB,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;QAC7D,MAAM,CAAC,QAAQ,EAAE,CAAC,yBAAyB,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAChE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -9,6 +9,8 @@ See also:
|
|
|
9
9
|
- [MEMORIX-CATALOX-CONTRACTS.md](./MEMORIX-CATALOX-CONTRACTS.md) — descriptor catalogs and JSON formats
|
|
10
10
|
- [MEMORIX-DATABASE-CONVENTIONS.md](./MEMORIX-DATABASE-CONVENTIONS.md) — Mongo layout and env vars
|
|
11
11
|
- [EXPLORER-HOST-APIS.md](./EXPLORER-HOST-APIS.md) — graph, raw reads, scoped workspace (Explorer-oriented)
|
|
12
|
+
- [XRONOX-DATA-TIER-REQUIREMENTS.md](./XRONOX-DATA-TIER-REQUIREMENTS.md) — what `@x12i/xronox` must provide as Memorix data tier
|
|
13
|
+
- [fr/README.md](./fr/README.md) — **open feature requests for `@x12i/xronox`** (implement there first)
|
|
12
14
|
|
|
13
15
|
---
|
|
14
16
|
|
|
@@ -16,13 +18,16 @@ See also:
|
|
|
16
18
|
|
|
17
19
|
| Export | Purpose |
|
|
18
20
|
|--------|---------|
|
|
19
|
-
| `createMemorixRetrieval(options)` | Build client with Catalox
|
|
20
|
-
| `createMemorixRetrievalFromEnv(options)` |
|
|
21
|
+
| `createMemorixRetrieval(options)` | Build client with Catalox + optional Xronox data tier |
|
|
22
|
+
| `createMemorixRetrievalFromEnv(options)` | Catalox + Xronox from env (default for hosts) |
|
|
23
|
+
| `createMemorixXronoxFromEnv(options?)` | Xronox zero-config bootstrap only |
|
|
21
24
|
| `createMemorixRetrievalStackFromEnv(options?)` | Catalox from env + adapter + retrieval client (recommended for hosts) |
|
|
22
25
|
| `createCataloxAdapterFromBound(bound)` | Wrap a bound Catalox client for descriptor loads |
|
|
23
26
|
| `resolveMemorixAppId(options?, processEnv?)` | Resolve app id: option → `CATALOX_APP_ID` → `MEMORIX_APP_ID` → `memorix` |
|
|
24
27
|
|
|
25
|
-
**Required env (
|
|
28
|
+
**Required env (default stack):** `MONGO_URI` (used by Xronox zero-config). Catalox credentials per `@x12i/catalox` when using the stack helper.
|
|
29
|
+
|
|
30
|
+
Data reads and counts go through **Xronox** (`role: memorix_entities` for entity descriptors, `role: memorix_events` for event descriptors). Direct Mongo is an advanced test-only escape hatch.
|
|
26
31
|
|
|
27
32
|
---
|
|
28
33
|
|
|
@@ -62,8 +67,10 @@ List descriptor `filters` with `operator` + `value` are **always applied**; requ
|
|
|
62
67
|
|
|
63
68
|
| Export | Purpose |
|
|
64
69
|
|--------|---------|
|
|
65
|
-
| `buildMemorixEntityGraph(client, options?)` | Discovery + counts + relation graph |
|
|
66
|
-
| `buildMemorixEntitySlices(client, entityName)` | Per–content-type counts for drill-down |
|
|
70
|
+
| `buildMemorixEntityGraph(client, options?)` | Discovery + counts + relation graph (per–content-type metadata, both DBs) |
|
|
71
|
+
| `buildMemorixEntitySlices(client, entityName)` | Per–content-type counts for drill-down (includes zero counts) |
|
|
72
|
+
| `buildMemorixCollectionInventory(client, options?)` | Reconcile Catalox-declared collections with Mongo in both databases via Xronox `listCollections` (≥ 3.9.0) |
|
|
73
|
+
| `orphanNodesFromInventory(entries)` | Group inventory orphans for entity graph canvas |
|
|
67
74
|
| `getMemorixRetrievalHealth(client)` | Mongo ping + discovery sample |
|
|
68
75
|
| `countMemorixEntityContentTypeDocuments` | Count by entity + content type (descriptor-resolved collection) |
|
|
69
76
|
| `listMemorixEntityContentTypeDocuments` | Paginated raw documents (descriptor-resolved) |
|
|
@@ -111,12 +118,13 @@ Scripts (not imported by hosts at runtime):
|
|
|
111
118
|
|
|
112
119
|
| Export | Purpose |
|
|
113
120
|
|--------|---------|
|
|
114
|
-
| `memorixRead` |
|
|
115
|
-
| `
|
|
121
|
+
| `memorixRead` | Routed read via Xronox (entity context + collection + role) |
|
|
122
|
+
| `memorixCount` | Routed count via Xronox (`countDocuments` on adapter) |
|
|
123
|
+
| `readMemorixCollection` / `countMemorixCollection` / `connectMemorixMongo` | **Test-only** — not used by production inventory or list/item paths |
|
|
116
124
|
| `resolveMemorixCollectionName` / `resolveMemorixDbNameForEntity` | Resolution utilities |
|
|
117
125
|
| Env helpers: `resolveMemorixDbName`, `resolveMongoUri`, `targetCollectionEnvKey` | Advanced overrides |
|
|
118
126
|
|
|
119
|
-
Pass `
|
|
127
|
+
Pass `mongo` to `createMemorixRetrieval` only for tests or legacy hosts. Production hosts should use `createMemorixRetrievalFromEnv` / `createMemorixRetrievalStackFromEnv` (Xronox data tier).
|
|
120
128
|
|
|
121
129
|
---
|
|
122
130
|
|
|
@@ -19,8 +19,22 @@ Uses `createCataloxFromEnv` + `createCataloxAdapterFromBound` + `createMemorixRe
|
|
|
19
19
|
## Entity discovery
|
|
20
20
|
|
|
21
21
|
- `discoverMemorixEntities(client)` — lists `memorix-entity-descriptors` via Catalox only (`source: "catalox" | "none"`). No env entity list fallback.
|
|
22
|
-
- `buildMemorixEntityGraph(client)` — discovery + per–content-type counts + **relations from entity descriptors**.
|
|
23
|
-
- `buildMemorixEntitySlices(client, entityName)` — slice counts for canvas drill-down.
|
|
22
|
+
- `buildMemorixEntityGraph(client)` — discovery + per–content-type counts + **relations from entity descriptors**. Each entity includes `target`, `memorixDatabase`, and `contentTypes[]` (collection, database, count, status). `discovery.memorixDatabases` names both entity and event stores.
|
|
23
|
+
- `buildMemorixEntitySlices(client, entityName)` — slice counts for canvas drill-down; includes **all** declared content types (zero counts use `status: "empty"`).
|
|
24
|
+
- `buildMemorixCollectionInventory(client, options?)` — bidirectional Mongo ↔ Catalox inventory across both databases (`matched`, `empty`, `orphan`, `unresolved`). Options: `includeExactCounts`, `scopedNamespace`.
|
|
25
|
+
- `orphanNodesFromInventory(entries)` — group orphan inventory rows into graph nodes for Explorer entities canvas.
|
|
26
|
+
|
|
27
|
+
## Collection inventory
|
|
28
|
+
|
|
29
|
+
Requires `@x12i/xronox` ≥ 3.9.0 (`listCollections`).
|
|
30
|
+
|
|
31
|
+
- Declared counts: `countMemorixEntityContentTypeDocuments` (Xronox)
|
|
32
|
+
- DB scan: `xronox.listCollections({ role })` for `memorix_entities` and `memorix_events`
|
|
33
|
+
- Orphan counts: `xronox.countDocuments({ estimated: true })`
|
|
34
|
+
|
|
35
|
+
Smoke: `npm run smoke:retrieval -- --inventory`
|
|
36
|
+
|
|
37
|
+
Response: `entries`, `summary.byTarget`, `discovery`.
|
|
24
38
|
|
|
25
39
|
## Raw collection reads (Explorer compatibility)
|
|
26
40
|
|
|
@@ -481,12 +481,16 @@ When `discovery.source` is `"none"`, returns empty rows with a hint — no env e
|
|
|
481
481
|
5. Resolve `includeRelations` and optional full content fetches.
|
|
482
482
|
6. Return `{ identity, sections, relations?, issues? }`.
|
|
483
483
|
|
|
484
|
-
### 5.6 Entity graph (Explorer)
|
|
484
|
+
### 5.6 Entity graph and collection inventory (Explorer)
|
|
485
485
|
|
|
486
|
-
|
|
486
|
+
Retrieval exports (see [EXPLORER-HOST-APIS.md](./EXPLORER-HOST-APIS.md)):
|
|
487
487
|
|
|
488
|
-
-
|
|
489
|
-
- `
|
|
488
|
+
- `buildMemorixEntityGraph` — discovery + entity descriptors; per entity: label, counts, **`contentTypes[]`**, **`relations` → connections**, default list/item ids, `target`, `memorixDatabase`.
|
|
489
|
+
- `buildMemorixEntitySlices` — all declared content types including zero counts.
|
|
490
|
+
- `buildMemorixCollectionInventory` — reconcile declared collections with Mongo in both databases.
|
|
491
|
+
- `orphanNodesFromInventory` — orphan groups for entities canvas.
|
|
492
|
+
|
|
493
|
+
`discovery.source` is `"catalox"` or `"none"` — never `"env"`. `discovery.memorixDatabases` names both entity and event stores.
|
|
490
494
|
|
|
491
495
|
---
|
|
492
496
|
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Xronox data tier requirements — `@x12i/memorix-retrieval`
|
|
2
|
+
|
|
3
|
+
**Audience:** `@x12i/xronox` maintainers
|
|
4
|
+
**Consumer:** `@x12i/memorix-retrieval` (v1.5+) and hosts (Memorix Explorer, APIs, tools)
|
|
5
|
+
**Status:** Active — open FRs in [`docs/fr/`](./fr/README.md). **No Mongo workarounds in production paths.**
|
|
6
|
+
|
|
7
|
+
Related docs:
|
|
8
|
+
|
|
9
|
+
- [DATA-TIER-CONTRACT.md](./DATA-TIER-CONTRACT.md) — public retrieval API
|
|
10
|
+
- [MEMORIX-DATABASE-CONVENTIONS.md](./MEMORIX-DATABASE-CONVENTIONS.md) — Mongo layout and env vars
|
|
11
|
+
- [MEMORIX-CATALOX-CONTRACTS.md](./MEMORIX-CATALOX-CONTRACTS.md) — descriptor metadata (Catalox, not Xronox)
|
|
12
|
+
- **[Feature requests for `@x12i/xronox`](./fr/README.md)** — implement here first; retrieval waits
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 1. Why Xronox is the Memorix data tier
|
|
17
|
+
|
|
18
|
+
Memorix separates **metadata** from **payload**:
|
|
19
|
+
|
|
20
|
+
| Layer | Package | Owns |
|
|
21
|
+
|-------|---------|------|
|
|
22
|
+
| Metadata | **Catalox** | Entity/list/item descriptors, discovery, column layout |
|
|
23
|
+
| Payload | **Xronox** | Routed Mongo reads/counts by role + collection |
|
|
24
|
+
| Composition | **memorix-retrieval** | Join descriptors + Xronox I/O → list/item rows |
|
|
25
|
+
|
|
26
|
+
Hosts must **not** connect to Mongo directly in production. Retrieval’s default bootstrap is:
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
createMemorixRetrievalFromEnv({ catalox })
|
|
30
|
+
→ createMemorixXronoxFromEnv()
|
|
31
|
+
→ createMemorixXronoxAdapter(createXronox())
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
All list/item/workspace reads and counts flow through Xronox routing.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 2. Integration contract (today)
|
|
39
|
+
|
|
40
|
+
### 2.1 Read routing key
|
|
41
|
+
|
|
42
|
+
Every Memorix Mongo read uses this Xronox routing shape:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
{
|
|
46
|
+
dataType: "metadata",
|
|
47
|
+
sourceType: "database",
|
|
48
|
+
subSourceType: "mongo",
|
|
49
|
+
role: "<xronox-role>",
|
|
50
|
+
source: "<collection-name>",
|
|
51
|
+
query?: Record<string, unknown>,
|
|
52
|
+
project?: string[],
|
|
53
|
+
sort?: string | string[] | Record<string, 1 | -1>,
|
|
54
|
+
limit?: number,
|
|
55
|
+
skip?: number,
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 2.2 Role mapping (Memorix target → Xronox role)
|
|
60
|
+
|
|
61
|
+
| Entity descriptor `target` | Memorix database (logical) | Default Xronox `role` (3.8+) |
|
|
62
|
+
|--------------------------|----------------------------|------------------------------|
|
|
63
|
+
| `"entity"` (default) | `memorix-entities` | `memorix_entities` |
|
|
64
|
+
| `"event"` | `memorix-events` | `memorix_events` |
|
|
65
|
+
|
|
66
|
+
Constants in retrieval: `DEFAULT_MEMORIX_XRONOX_ROLES` (`src/data/memorix-read.ts`).
|
|
67
|
+
|
|
68
|
+
### 2.3 Operations retrieval performs via Xronox
|
|
69
|
+
|
|
70
|
+
| Operation | Retrieval API | Xronox usage | Blocked? |
|
|
71
|
+
|-----------|---------------|--------------|----------|
|
|
72
|
+
| Paginated list | `fetchMemorixList` | `read` / `readArray` | — |
|
|
73
|
+
| List total | `fetchMemorixList` | `countDocuments` | — |
|
|
74
|
+
| Entity graph counts | `buildMemorixEntityGraph` | `countDocuments` per content type | — |
|
|
75
|
+
| **Collection inventory scan** | `buildMemorixCollectionInventory` | **`listCollections` + `countDocuments`** | — (3.9.0+) |
|
|
76
|
+
| Raw explorer reads | `listMemorixEntityContentTypeDocuments` | `read` + `countDocuments` | — |
|
|
77
|
+
| Health | `getMemorixRetrievalHealth` | `selfTest` | Partial — [FR](./fr/xronox-fr-per-role-selftest.md) |
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 3. Shipped in Xronox (retrieval uses today)
|
|
82
|
+
|
|
83
|
+
| Capability | Xronox API | Since |
|
|
84
|
+
|------------|------------|-------|
|
|
85
|
+
| Routed read | `read` / `readArray` | 3.8+ |
|
|
86
|
+
| Routed count | `countDocuments` (incl. `estimated: true`) | 3.8+ |
|
|
87
|
+
| Offset pagination | `skip` + `limit` | 3.8+ |
|
|
88
|
+
| Object sort | `sort: Record<string, 1 \| -1>` | 3.8+ |
|
|
89
|
+
| Role-based DB routing | `role` on params | 3.8+ |
|
|
90
|
+
| Database collection listing | `listCollections({ role, source: "_db" })` | **3.9+** |
|
|
91
|
+
| Connectivity | `selfTest({ testConnectivity })` | 3.8+ |
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## 4. Open — implement in Xronox (see FRs)
|
|
96
|
+
|
|
97
|
+
| Priority | FR | Blocks |
|
|
98
|
+
|----------|-----|--------|
|
|
99
|
+
| P1 | [Memorix env preset](./fr/xronox-fr-memorix-env-preset.md) | `MEMORIX_*_DB`-only zero-config |
|
|
100
|
+
| P2 | [Per-role selfTest](./fr/xronox-fr-per-role-selftest.md) | Health detail for both DBs |
|
|
101
|
+
|
|
102
|
+
~~P0 listCollections~~ — **shipped 3.9.0**. See [FR](./fr/xronox-fr-list-collections.md).
|
|
103
|
+
|
|
104
|
+
**Do not** implement these in retrieval with `connectMemorixMongo` or other driver bypasses.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## 5. Retrieval policy (no workarounds)
|
|
109
|
+
|
|
110
|
+
| Rule | Detail |
|
|
111
|
+
|------|--------|
|
|
112
|
+
| Production I/O | Xronox only |
|
|
113
|
+
| `buildMemorixCollectionInventory` | Uses Xronox `listCollections` + `countDocuments` (requires `@x12i/xronox` ≥ 3.9.0) |
|
|
114
|
+
| Tests | Mock `xronox.listCollections` / inject test `mongo` only in unit tests — not production bootstrap |
|
|
115
|
+
| Explorer host shims | Delete `memorix-explorer/server/collection-inventory.ts` after bumping to retrieval 1.6.1+ |
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## 6. Version alignment
|
|
120
|
+
|
|
121
|
+
| Package | Current | Notes |
|
|
122
|
+
|---------|---------|-------|
|
|
123
|
+
| `@x12i/memorix-retrieval` | 1.6.1 | Inventory via Xronox `listCollections` |
|
|
124
|
+
| `@x12i/xronox` | ^3.9.0 | `listCollections` required for inventory |
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 7. Out of scope for Xronox
|
|
129
|
+
|
|
130
|
+
Entity discovery, list columns, row composition, Catalox seed, orphan name parsing — stay in Catalox / memorix-retrieval.
|
|
131
|
+
|
|
132
|
+
Xronox remains a **database routing + I/O layer**, not Memorix-aware.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Feature requests — `@x12i/xronox` (Memorix data tier)
|
|
2
|
+
|
|
3
|
+
**Audience:** `@x12i/xronox` maintainers
|
|
4
|
+
**Consumer:** `@x12i/memorix-retrieval`, Memorix Explorer, APIs, tools
|
|
5
|
+
**Policy:** Retrieval and hosts **must not** bypass Xronox with direct Mongo for production paths. Open FRs block retrieval features until Xronox ships the generic API.
|
|
6
|
+
|
|
7
|
+
| FR | Status | Blocks |
|
|
8
|
+
|----|--------|--------|
|
|
9
|
+
| [xronox-fr-list-collections.md](./xronox-fr-list-collections.md) | **Shipped** (`@x12i/xronox` 3.9.0) | — |
|
|
10
|
+
| [xronox-fr-memorix-env-preset.md](./xronox-fr-memorix-env-preset.md) | **Open** | Zero-config with `MEMORIX_*_DB` only |
|
|
11
|
+
| [xronox-fr-per-role-selftest.md](./xronox-fr-per-role-selftest.md) | **Open** | Health reporting both entity + event DBs |
|
|
12
|
+
|
|
13
|
+
**Already in Xronox 3.8+ (no FR):** `countDocuments`, `skip`, `sort` as Mongo object, `countDocuments({ estimated: true })`.
|
|
14
|
+
|
|
15
|
+
See also: [XRONOX-DATA-TIER-REQUIREMENTS.md](../XRONOX-DATA-TIER-REQUIREMENTS.md) (integration index).
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# Feature request — routed `listCollections` (`@x12i/xronox`)
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-05-22
|
|
4
|
+
**Status:** **Shipped** — `@x12i/xronox@3.9.0`
|
|
5
|
+
**Consumer:** `@x12i/memorix-retrieval@1.6.1+`
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Summary
|
|
10
|
+
|
|
11
|
+
Memorix **collection inventory** lists all Mongo collections in **both** Memorix databases (`memorix-entities`, `memorix-events`) using the same **role → database** routing as `read` and `countDocuments`. Implemented in Xronox 3.9.0; retrieval uses it with **no direct Mongo bypass**.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Why this belongs in Xronox (not retrieval)
|
|
16
|
+
|
|
17
|
+
| Concern | Host/retrieval bypass problem |
|
|
18
|
+
|---------|-------------------------------|
|
|
19
|
+
| Role routing | Must use same `role` → DB resolution as reads (`memorix_entities`, `memorix_events`) |
|
|
20
|
+
| Multi-DB | Inventory scans **both** databases; routing must stay in Xronox |
|
|
21
|
+
| Contract | [DATA-TIER-CONTRACT.md](../DATA-TIER-CONTRACT.md): production I/O through Xronox only |
|
|
22
|
+
| Reuse | Any x12i app with role-based Mongo needs collection discovery, not only Memorix |
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Product requirement
|
|
27
|
+
|
|
28
|
+
Expose a routed API that returns collection names (and optional types) for the **database resolved from `role`**, without targeting a single collection in `source`.
|
|
29
|
+
|
|
30
|
+
Orphan scan flow (retrieval consumer):
|
|
31
|
+
|
|
32
|
+
1. `listCollections({ role: "memorix_entities" })` → all non-system collections in entity DB
|
|
33
|
+
2. `listCollections({ role: "memorix_events" })` → all non-system collections in event DB
|
|
34
|
+
3. For each collection not in Catalox descriptor map: `countDocuments({ role, source: collectionName, estimated: true })` (already in Xronox 3.8+)
|
|
35
|
+
|
|
36
|
+
Declared slot counts continue to use descriptor-routed `countDocuments` via `countMemorixEntityContentTypeDocuments` (retrieval).
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Proposed API
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
listCollections(params: ListCollectionsParams): Promise<ListCollectionsResult>;
|
|
44
|
+
|
|
45
|
+
export interface ListedCollection {
|
|
46
|
+
name: string;
|
|
47
|
+
type?: string; // "collection" | "view" | ...
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface ListCollectionsResult {
|
|
51
|
+
/** Resolved database name after role + tenancy (same as countDocuments/read) */
|
|
52
|
+
database: string;
|
|
53
|
+
collections: ListedCollection[];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface ListCollectionsParams extends RoutingKey {
|
|
57
|
+
subSourceType: "mongo";
|
|
58
|
+
/**
|
|
59
|
+
* Binding match token only — not a collection name.
|
|
60
|
+
* Zero-config bindings with no `match` accept any source (e.g. `"_db"`).
|
|
61
|
+
*/
|
|
62
|
+
source: string;
|
|
63
|
+
role?: string;
|
|
64
|
+
/** Forwarded to Mongo db.listCollections({ filter }) */
|
|
65
|
+
filter?: Record<string, unknown>;
|
|
66
|
+
/** Default true — omit names starting with `system.` */
|
|
67
|
+
excludeSystem?: boolean;
|
|
68
|
+
/** Default true — use driver nameOnly for lighter responses */
|
|
69
|
+
nameOnly?: boolean;
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Add to `Xronox` interface and `Engine` (nxMongo engine only; xronoxCore may omit like `countDocuments`).
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Algorithm (normative)
|
|
78
|
+
|
|
79
|
+
1. `resolveBinding(config, params)` — **same as `countDocuments` and `read`**.
|
|
80
|
+
2. Resolve `connection` → `SimpleMongoHelper`.
|
|
81
|
+
3. Resolve `db` from binding + `params.role` (role overrides binding default db).
|
|
82
|
+
4. `sanitizeDatabaseName(db)` — same as existing count path.
|
|
83
|
+
5. `mongoDb.listCollections(filter, { nameOnly })`.
|
|
84
|
+
6. If `excludeSystem !== false`, filter out `system.*` names.
|
|
85
|
+
7. Return `{ database: db, collections }`.
|
|
86
|
+
|
|
87
|
+
**Do not** use `params.source` as a collection name. `source` exists only for binding selection.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Example calls (Memorix)
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
// Entity store
|
|
95
|
+
const entityDb = await xronox.listCollections({
|
|
96
|
+
dataType: "metadata",
|
|
97
|
+
sourceType: "database",
|
|
98
|
+
subSourceType: "mongo",
|
|
99
|
+
source: "_db",
|
|
100
|
+
role: "memorix_entities",
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Event store
|
|
104
|
+
const eventDb = await xronox.listCollections({
|
|
105
|
+
dataType: "metadata",
|
|
106
|
+
sourceType: "database",
|
|
107
|
+
subSourceType: "mongo",
|
|
108
|
+
source: "_db",
|
|
109
|
+
role: "memorix_events",
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// Orphan count (existing API)
|
|
113
|
+
const count = await xronox.countDocuments({
|
|
114
|
+
dataType: "metadata",
|
|
115
|
+
sourceType: "database",
|
|
116
|
+
subSourceType: "mongo",
|
|
117
|
+
role: "memorix_entities",
|
|
118
|
+
source: "orphan-entity-records",
|
|
119
|
+
estimated: true,
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Implementation guidance (`@x12i/xronox`)
|
|
126
|
+
|
|
127
|
+
| Layer | Change |
|
|
128
|
+
|-------|--------|
|
|
129
|
+
| `src/types.ts` | `ListCollectionsParams`, `ListCollectionsResult`, `ListedCollection`; extend `Xronox` |
|
|
130
|
+
| `src/engines/interface.ts` | `listCollections?(params, resolved)` |
|
|
131
|
+
| `src/engines/nxMongoEngine.ts` | Implement via `getDatabase` / `listCollections` (same helper lookup as `countDocuments`) |
|
|
132
|
+
| `src/index.ts` | `XronoxImpl.listCollections` → `resolveBinding` → engine |
|
|
133
|
+
| `README.md` | Document next to `countDocuments` example |
|
|
134
|
+
| Tests | Routing unit test (no Mongo); optional integration test with fixture DB |
|
|
135
|
+
|
|
136
|
+
Mirror error codes from count path: `CONNECTION_NOT_FOUND`, `DATABASE_NOT_RESOLVED`, `ROUTING_NOT_FOUND`.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Retrieval integration (after Xronox ships)
|
|
141
|
+
|
|
142
|
+
| Step | Action |
|
|
143
|
+
|------|--------|
|
|
144
|
+
| 1 | Bump `@x12i/xronox` minimum (e.g. `^3.9.0`) |
|
|
145
|
+
| 2 | Extend `XronoxLike` + adapter to delegate `listCollections` |
|
|
146
|
+
| 3 | `buildMemorixCollectionInventory` calls Xronox only — **throws** if `listCollections` missing |
|
|
147
|
+
| 4 | Delete Explorer host shim `server/collection-inventory.ts` |
|
|
148
|
+
| 5 | `npm run smoke:retrieval -- --inventory` |
|
|
149
|
+
|
|
150
|
+
**No Mongo fallback in retrieval.** Tests may inject a mock `xronox` with `listCollections`; production requires real Xronox.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Acceptance criteria
|
|
155
|
+
|
|
156
|
+
### Xronox
|
|
157
|
+
|
|
158
|
+
- [ ] `listCollections({ role: "memorix_entities" })` returns collections from `MEMORIX_ENTITIES_DB` / role map default
|
|
159
|
+
- [ ] `listCollections({ role: "memorix_events" })` returns collections from events DB
|
|
160
|
+
- [ ] `excludeSystem: true` (default) omits `system.*`
|
|
161
|
+
- [ ] `database` in result matches DB used for `countDocuments` on same role + collection
|
|
162
|
+
- [ ] Wrong/missing role → typed routing error (not empty list)
|
|
163
|
+
- [ ] nxMongo engine only; clear error on xronoxCore
|
|
164
|
+
|
|
165
|
+
### Retrieval (downstream)
|
|
166
|
+
|
|
167
|
+
- [ ] `buildMemorixCollectionInventory` completes without `connectMemorixMongo`
|
|
168
|
+
- [ ] Inventory `summary.byTarget` matches entries filtered by `target`
|
|
169
|
+
- [ ] Vitest mocks `xronox.listCollections` only (no Mongo client for scan)
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Non-goals
|
|
174
|
+
|
|
175
|
+
| Item | Reason |
|
|
176
|
+
|------|--------|
|
|
177
|
+
| Catalox orphan → descriptor seeding | Ops / Catalox tooling |
|
|
178
|
+
| Memorix-specific parsing in Xronox | Stays in retrieval (`parseOrphanCollection`) |
|
|
179
|
+
| List documents across all collections | Use inventory + per-collection `read` |
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Version
|
|
184
|
+
|
|
185
|
+
| Package | Minimum after FR |
|
|
186
|
+
|---------|------------------|
|
|
187
|
+
| `@x12i/xronox` | `3.9.0` (proposed minor) |
|
|
188
|
+
| `@x12i/memorix-retrieval` | Requires published Xronox with this FR |
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## References
|
|
193
|
+
|
|
194
|
+
- Retrieval inventory: `src/explorer/collection-inventory.ts`
|
|
195
|
+
- Role constants: `src/data/memorix-read.ts` (`DEFAULT_MEMORIX_XRONOX_ROLES`)
|
|
196
|
+
- Explorer shim (delete after ship): `memorix-explorer/server/collection-inventory.ts`
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Feature request — Memorix deployment preset / env aliases (`@x12i/xronox`)
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-05-22
|
|
4
|
+
**Status:** **Open**
|
|
5
|
+
**Requested by:** `@x12i/memorix-retrieval`, Memorix Explorer smoke scripts
|
|
6
|
+
**Target package:** `@x12i/xronox`
|
|
7
|
+
**Priority:** P1 (ergonomics — not blocking inventory if roles + DB vars are set explicitly)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Summary
|
|
12
|
+
|
|
13
|
+
Memorix documents **`MEMORIX_ENTITIES_DB`** and **`MEMORIX_EVENTS_DB`**. Xronox zero-config resolves databases via **`MONGO_OPERATIONAL_DB`**, **`MONGO_LOGS_DB`**, and role maps (`memorix_entities`, `memorix_events`). Deployments must duplicate env vars today.
|
|
14
|
+
|
|
15
|
+
This FR aligns Xronox zero-config with Memorix conventions so smoke and Explorer work with **`MONGO_URI` + `MEMORIX_*_DB` only**.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Product requirement
|
|
20
|
+
|
|
21
|
+
When resolving Mongo database names for roles:
|
|
22
|
+
|
|
23
|
+
| Xronox role | Memorix target | Fallback chain should include |
|
|
24
|
+
|-------------|----------------|------------------------------|
|
|
25
|
+
| `memorix_entities` / `memory.entities` / `operational` | `entity` | `MEMORIX_ENTITIES_DB` → `memorix-entities` |
|
|
26
|
+
| `memorix_events` / `memory.events` / `logs` | `event` | `MEMORIX_EVENTS_DB` → `memorix-events` |
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Proposed options (pick one or both)
|
|
31
|
+
|
|
32
|
+
### Option A — Env aliases in role resolution
|
|
33
|
+
|
|
34
|
+
In `resolveDatabaseNameFromRole` / `MONGO_ROLE_MAP` fallback chains:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
memorix_entities.database ← MEMORIX_ENTITIES_DB ← MONGO_OPERATIONAL_DB ← MONGO_DB
|
|
38
|
+
memorix_events.database ← MEMORIX_EVENTS_DB ← MONGO_LOGS_DB ← MONGO_DB
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Option B — Zero-config preset
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
await xronox.init({ engine: "nxMongo", preset: "memorix", zeroConfig: true });
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Preset registers role map defaults and env aliases above. Document in Xronox README + `.env.example`.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Acceptance criteria
|
|
52
|
+
|
|
53
|
+
- [ ] `npm run smoke:retrieval` in memorix-retrieval succeeds with only `MONGO_URI`, `MEMORIX_ENTITIES_DB`, `MEMORIX_EVENTS_DB`, Catalox creds
|
|
54
|
+
- [ ] No requirement to set `MONGO_OPERATIONAL_DB` / `MONGO_LOGS_DB` for Memorix deployments
|
|
55
|
+
- [ ] Existing non-Memorix zero-config behavior unchanged when preset not used
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Retrieval integration (after ship)
|
|
60
|
+
|
|
61
|
+
- Optionally simplify `createMemorixXronoxFromEnv` to pass `preset: "memorix"`.
|
|
62
|
+
- Update [MEMORIX-DATABASE-CONVENTIONS.md](../MEMORIX-DATABASE-CONVENTIONS.md) with single env table.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Non-goals
|
|
67
|
+
|
|
68
|
+
- Catalox or descriptor env (stays in `@x12i/catalox`)
|
|
69
|
+
- Changing Memorix collection naming (retrieval + Catalox)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Feature request — per-role `selfTest` detail (`@x12i/xronox`)
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-05-22
|
|
4
|
+
**Status:** **Open**
|
|
5
|
+
**Requested by:** `@x12i/memorix-retrieval` (`getMemorixRetrievalHealth`)
|
|
6
|
+
**Target package:** `@x12i/xronox`
|
|
7
|
+
**Priority:** P2 (health UX — not blocking lists or inventory)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Summary
|
|
12
|
+
|
|
13
|
+
Memorix runs **two** Mongo databases (entity + event). Health checks should report connectivity **per role**, not a single anonymous ping. Retrieval already passes `selfTestRoles: ["memorix_entities", "memorix_events"]` to the adapter when Xronox supports it.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Product requirement
|
|
18
|
+
|
|
19
|
+
Extend `selfTest` result so hosts can show which Memorix store failed:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
type SelfTestResult = {
|
|
23
|
+
passed: boolean;
|
|
24
|
+
roles?: Array<{
|
|
25
|
+
role: string;
|
|
26
|
+
db: string;
|
|
27
|
+
ok: boolean;
|
|
28
|
+
latencyMs?: number;
|
|
29
|
+
error?: string;
|
|
30
|
+
}>;
|
|
31
|
+
};
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
await xronox.selfTest({
|
|
36
|
+
testConnectivity: true,
|
|
37
|
+
selfTestRoles: ["memorix_entities", "memorix_events"],
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Acceptance criteria
|
|
44
|
+
|
|
45
|
+
- [ ] Each role resolves DB name and attempts connectivity (e.g. listCollections or count on a lightweight op)
|
|
46
|
+
- [ ] `passed: false` if any requested role fails
|
|
47
|
+
- [ ] Works with Memorix env vars when [memorix-env-preset FR](./xronox-fr-memorix-env-preset.md) is also applied (or explicit DB vars)
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Retrieval integration (after ship)
|
|
52
|
+
|
|
53
|
+
- `getMemorixRetrievalHealth` surfaces per-role results in response (optional field)
|
|
54
|
+
- Remove direct Mongo ping fallback from health when Xronox reports both roles
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Non-goals
|
|
59
|
+
|
|
60
|
+
- Descriptor / Catalox health (retrieval discovers Catalox separately)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@x12i/memorix-retrieval",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.2",
|
|
4
4
|
"description": "Descriptor-driven Memorix retrieval layer for lists, items, and content objects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -30,18 +30,9 @@
|
|
|
30
30
|
"node": ">=18.0.0"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@x12i/catalox": "^
|
|
33
|
+
"@x12i/catalox": "^5.0.0",
|
|
34
34
|
"@x12i/helpers": "^1.7.0",
|
|
35
|
-
"@x12i/
|
|
36
|
-
"mongodb": "^6.21.0"
|
|
37
|
-
},
|
|
38
|
-
"peerDependencies": {
|
|
39
|
-
"@x12i/xronox": ">=3.7.0"
|
|
40
|
-
},
|
|
41
|
-
"peerDependenciesMeta": {
|
|
42
|
-
"@x12i/xronox": {
|
|
43
|
-
"optional": true
|
|
44
|
-
}
|
|
35
|
+
"@x12i/xronox": "^3.9.0"
|
|
45
36
|
},
|
|
46
37
|
"devDependencies": {
|
|
47
38
|
"@types/node": "^20.14.0",
|