mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-07-01 09:29: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`
|
- `cd ts && bun run lint`
|
||||||
- `git diff --check`
|
- `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
|
## Subagent Findings To Preserve
|
||||||
|
|
||||||
- MCP/workbench:
|
- MCP/workbench:
|
||||||
|
|
@ -2420,9 +2440,9 @@ Notes:
|
||||||
The workbench random id helper is complete; the remaining workbench
|
The workbench random id helper is complete; the remaining workbench
|
||||||
`Effect.gen` match is a local one-shot command effect value.
|
`Effect.gen` match is a local one-shot command effect value.
|
||||||
- Remaining real long-lived native collection targets include base processor
|
- Remaining real long-lived native collection targets include base processor
|
||||||
registries, Librarian service / collection manager state, prompt template
|
registries, Librarian service state, prompt template cache, and a workbench
|
||||||
cache, and a workbench module cache. Local traversal sets and test fakes
|
module cache. The standalone Librarian collection manager is complete.
|
||||||
remain no-op boundaries.
|
Local traversal sets and test fakes remain no-op boundaries.
|
||||||
|
|
||||||
## Ranked Findings
|
## 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).
|
* via the parent LibrarianService JSON snapshot).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import * as MutableHashMap from "effect/MutableHashMap";
|
||||||
|
import * as O from "effect/Option";
|
||||||
|
|
||||||
export interface CollectionEntry {
|
export interface CollectionEntry {
|
||||||
user: string;
|
user: string;
|
||||||
collection: string;
|
collection: string;
|
||||||
|
|
@ -32,7 +35,7 @@ export interface CollectionManager {
|
||||||
|
|
||||||
export function makeCollectionManager(): CollectionManager {
|
export function makeCollectionManager(): CollectionManager {
|
||||||
/** keyed by `${user}:${collection}` */
|
/** 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}`;
|
const key = (user: string, collection: string): string => `${user}:${collection}`;
|
||||||
|
|
||||||
|
|
@ -44,35 +47,41 @@ export function makeCollectionManager(): CollectionManager {
|
||||||
tags: string[],
|
tags: string[],
|
||||||
): CollectionEntry => {
|
): CollectionEntry => {
|
||||||
const entry: CollectionEntry = { user, collection, name, description, tags };
|
const entry: CollectionEntry = { user, collection, name, description, tags };
|
||||||
collections.set(key(user, collection), entry);
|
MutableHashMap.set(collections, key(user, collection), entry);
|
||||||
return entry;
|
return entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
listCollections: (user) => {
|
listCollections: (user) => {
|
||||||
const result: CollectionEntry[] = [];
|
const result: CollectionEntry[] = [];
|
||||||
for (const entry of collections.values()) {
|
for (const entry of MutableHashMap.values(collections)) {
|
||||||
if (entry.user === user) {
|
if (entry.user === user) {
|
||||||
result.push(entry);
|
result.push(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
getCollection: (user, collection) => collections.get(key(user, collection)),
|
getCollection: (user, collection) =>
|
||||||
|
O.getOrUndefined(MutableHashMap.get(collections, key(user, collection))),
|
||||||
updateCollection,
|
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) => {
|
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;
|
if (existing !== undefined) return existing;
|
||||||
return updateCollection(user, collection, collection, "", []);
|
return updateCollection(user, collection, collection, "", []);
|
||||||
},
|
},
|
||||||
/** Serialize to a plain array for JSON persistence. */
|
/** Serialize to a plain array for JSON persistence. */
|
||||||
toJSON: () => [...collections.values()],
|
toJSON: () => Array.from(MutableHashMap.values(collections)),
|
||||||
/** Restore from a serialized array. */
|
/** Restore from a serialized array. */
|
||||||
loadFromJSON: (entries) => {
|
loadFromJSON: (entries) => {
|
||||||
collections.clear();
|
MutableHashMap.clear(collections);
|
||||||
for (const entry of entries) {
|
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