mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-07-01 01:19:38 +02:00
Use MutableHashMap for collection manager
This commit is contained in:
parent
069d901737
commit
7d77a5c1de
3 changed files with 85 additions and 12 deletions
|
|
@ -2234,6 +2234,26 @@ Notes:
|
|||
- `cd ts && bun run lint`
|
||||
- `git diff --check`
|
||||
|
||||
### 2026-06-04: Librarian Collection Manager MutableHashMap Slice
|
||||
|
||||
- Status: migrated and package-verified.
|
||||
- Completed:
|
||||
- `ts/packages/flow/src/librarian/collection-manager.ts` now stores
|
||||
in-memory collection entries in `MutableHashMap` instead of native `Map`.
|
||||
- Public `listCollections`, `getCollection`, `updateCollection`,
|
||||
`deleteCollection`, `ensureCollectionExists`, `toJSON`, and `loadFromJSON`
|
||||
behavior stays array/boolean/undefined based at the API and persistence
|
||||
boundaries.
|
||||
- New focused coverage verifies create/update/list/get/delete and JSON
|
||||
restore behavior through the migrated collection state.
|
||||
- Verification:
|
||||
- `cd ts/packages/flow && bunx --bun vitest run src/__tests__/collection-manager.test.ts src/__tests__/librarian-service.test.ts`
|
||||
- `cd ts && bun run check:tsgo`
|
||||
- `cd ts && bun run build`
|
||||
- `cd ts && bun run test`
|
||||
- `cd ts && bun run lint`
|
||||
- `git diff --check`
|
||||
|
||||
## Subagent Findings To Preserve
|
||||
|
||||
- MCP/workbench:
|
||||
|
|
@ -2420,9 +2440,9 @@ Notes:
|
|||
The workbench random id helper is complete; the remaining workbench
|
||||
`Effect.gen` match is a local one-shot command effect value.
|
||||
- Remaining real long-lived native collection targets include base processor
|
||||
registries, Librarian service / collection manager state, prompt template
|
||||
cache, and a workbench module cache. Local traversal sets and test fakes
|
||||
remain no-op boundaries.
|
||||
registries, Librarian service state, prompt template cache, and a workbench
|
||||
module cache. The standalone Librarian collection manager is complete.
|
||||
Local traversal sets and test fakes remain no-op boundaries.
|
||||
|
||||
## Ranked Findings
|
||||
|
||||
|
|
|
|||
44
ts/packages/flow/src/__tests__/collection-manager.test.ts
Normal file
44
ts/packages/flow/src/__tests__/collection-manager.test.ts
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
import { makeCollectionManager } from "../librarian/collection-manager.js";
|
||||
|
||||
describe("CollectionManager", () => {
|
||||
it("manages collection entries through Effect MutableHashMap state", () => {
|
||||
const manager = makeCollectionManager();
|
||||
|
||||
const created = manager.ensureCollectionExists("alice", "papers");
|
||||
expect(created).toEqual({
|
||||
user: "alice",
|
||||
collection: "papers",
|
||||
name: "papers",
|
||||
description: "",
|
||||
tags: [],
|
||||
});
|
||||
|
||||
const updated = manager.updateCollection(
|
||||
"alice",
|
||||
"papers",
|
||||
"Research Papers",
|
||||
"Curated PDFs",
|
||||
["research", "pdf"],
|
||||
);
|
||||
manager.updateCollection("bob", "notes", "Notes", "", []);
|
||||
|
||||
expect(manager.getCollection("alice", "papers")).toEqual(updated);
|
||||
expect(manager.listCollections("alice")).toEqual([updated]);
|
||||
expect(manager.toJSON()).toEqual([updated, {
|
||||
user: "bob",
|
||||
collection: "notes",
|
||||
name: "Notes",
|
||||
description: "",
|
||||
tags: [],
|
||||
}]);
|
||||
|
||||
expect(manager.deleteCollection("alice", "papers")).toBe(true);
|
||||
expect(manager.deleteCollection("alice", "papers")).toBe(false);
|
||||
expect(manager.getCollection("alice", "papers")).toBeUndefined();
|
||||
|
||||
manager.loadFromJSON([updated]);
|
||||
expect(manager.listCollections("alice")).toEqual([updated]);
|
||||
expect(manager.listCollections("bob")).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
|
@ -6,6 +6,9 @@
|
|||
* via the parent LibrarianService JSON snapshot).
|
||||
*/
|
||||
|
||||
import * as MutableHashMap from "effect/MutableHashMap";
|
||||
import * as O from "effect/Option";
|
||||
|
||||
export interface CollectionEntry {
|
||||
user: string;
|
||||
collection: string;
|
||||
|
|
@ -32,7 +35,7 @@ export interface CollectionManager {
|
|||
|
||||
export function makeCollectionManager(): CollectionManager {
|
||||
/** keyed by `${user}:${collection}` */
|
||||
const collections = new Map<string, CollectionEntry>();
|
||||
const collections = MutableHashMap.empty<string, CollectionEntry>();
|
||||
|
||||
const key = (user: string, collection: string): string => `${user}:${collection}`;
|
||||
|
||||
|
|
@ -44,35 +47,41 @@ export function makeCollectionManager(): CollectionManager {
|
|||
tags: string[],
|
||||
): CollectionEntry => {
|
||||
const entry: CollectionEntry = { user, collection, name, description, tags };
|
||||
collections.set(key(user, collection), entry);
|
||||
MutableHashMap.set(collections, key(user, collection), entry);
|
||||
return entry;
|
||||
};
|
||||
|
||||
return {
|
||||
listCollections: (user) => {
|
||||
const result: CollectionEntry[] = [];
|
||||
for (const entry of collections.values()) {
|
||||
for (const entry of MutableHashMap.values(collections)) {
|
||||
if (entry.user === user) {
|
||||
result.push(entry);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
getCollection: (user, collection) => collections.get(key(user, collection)),
|
||||
getCollection: (user, collection) =>
|
||||
O.getOrUndefined(MutableHashMap.get(collections, key(user, collection))),
|
||||
updateCollection,
|
||||
deleteCollection: (user, collection) => collections.delete(key(user, collection)),
|
||||
deleteCollection: (user, collection) => {
|
||||
const collectionKey = key(user, collection);
|
||||
const exists = MutableHashMap.has(collections, collectionKey);
|
||||
MutableHashMap.remove(collections, collectionKey);
|
||||
return exists;
|
||||
},
|
||||
ensureCollectionExists: (user, collection) => {
|
||||
const existing = collections.get(key(user, collection));
|
||||
const existing = O.getOrUndefined(MutableHashMap.get(collections, key(user, collection)));
|
||||
if (existing !== undefined) return existing;
|
||||
return updateCollection(user, collection, collection, "", []);
|
||||
},
|
||||
/** Serialize to a plain array for JSON persistence. */
|
||||
toJSON: () => [...collections.values()],
|
||||
toJSON: () => Array.from(MutableHashMap.values(collections)),
|
||||
/** Restore from a serialized array. */
|
||||
loadFromJSON: (entries) => {
|
||||
collections.clear();
|
||||
MutableHashMap.clear(collections);
|
||||
for (const entry of entries) {
|
||||
collections.set(key(entry.user, entry.collection), entry);
|
||||
MutableHashMap.set(collections, key(entry.user, entry.collection), entry);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue