feat: add isolated memory spaces
This commit is contained in:
@@ -2,9 +2,10 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
||||
|
||||
import { IdentityDB } from '../src/core/identity-db';
|
||||
|
||||
async function seedMemoryGraph(db: IdentityDB): Promise<void> {
|
||||
async function seedMemoryGraph(db: IdentityDB, spaceName?: string): Promise<void> {
|
||||
await db.addFact({
|
||||
statement: 'I have worked with TypeScript since 2025.',
|
||||
spaceName,
|
||||
topics: [
|
||||
{ name: 'I', category: 'entity', granularity: 'concrete', role: 'subject' },
|
||||
{ name: 'TypeScript', category: 'entity', granularity: 'concrete', role: 'object' },
|
||||
@@ -14,6 +15,7 @@ async function seedMemoryGraph(db: IdentityDB): Promise<void> {
|
||||
|
||||
await db.addFact({
|
||||
statement: 'TypeScript is a programming language.',
|
||||
spaceName,
|
||||
topics: [
|
||||
{ name: 'TypeScript', category: 'entity', granularity: 'concrete', role: 'subject' },
|
||||
{ name: 'programming language', category: 'concept', granularity: 'abstract', role: 'classification' },
|
||||
@@ -23,11 +25,13 @@ async function seedMemoryGraph(db: IdentityDB): Promise<void> {
|
||||
await db.linkTopics({
|
||||
parentName: 'software technology',
|
||||
childName: 'programming language',
|
||||
spaceName,
|
||||
});
|
||||
|
||||
await db.linkTopics({
|
||||
parentName: 'programming language',
|
||||
childName: 'TypeScript',
|
||||
spaceName,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -114,6 +118,56 @@ describe('IdentityDB queries', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('keeps hierarchy and fact queries isolated per space', async () => {
|
||||
const isolatedDb = await IdentityDB.connect({ client: 'sqlite', filename: ':memory:' });
|
||||
try {
|
||||
await isolatedDb.initialize();
|
||||
await seedMemoryGraph(isolatedDb, 'A');
|
||||
|
||||
await isolatedDb.addFact({
|
||||
statement: 'TypeScript is a typed superset.',
|
||||
spaceName: 'B',
|
||||
topics: [
|
||||
{ name: 'TypeScript', category: 'entity', granularity: 'concrete', role: 'subject' },
|
||||
{ name: 'superset', category: 'concept', granularity: 'abstract', role: 'classification' },
|
||||
],
|
||||
});
|
||||
|
||||
await isolatedDb.linkTopics({
|
||||
parentName: 'language family',
|
||||
childName: 'TypeScript',
|
||||
spaceName: 'B',
|
||||
});
|
||||
|
||||
const alphaTopic = await isolatedDb.getTopicByName('TypeScript', {
|
||||
includeFacts: true,
|
||||
spaceName: 'A',
|
||||
});
|
||||
const betaTopic = await isolatedDb.getTopicByName('TypeScript', {
|
||||
includeFacts: true,
|
||||
spaceName: 'B',
|
||||
});
|
||||
const alphaParents = await isolatedDb.getTopicParents('TypeScript', { spaceName: 'A' });
|
||||
const betaParents = await isolatedDb.getTopicParents('TypeScript', { spaceName: 'B' });
|
||||
const alphaConnected = await isolatedDb.findConnectedTopics('TypeScript', { spaceName: 'A' });
|
||||
const betaConnected = await isolatedDb.findConnectedTopics('TypeScript', { spaceName: 'B' });
|
||||
|
||||
expect(alphaTopic?.facts.map((fact) => fact.statement)).toEqual([
|
||||
'I have worked with TypeScript since 2025.',
|
||||
'TypeScript is a programming language.',
|
||||
]);
|
||||
expect(betaTopic?.facts.map((fact) => fact.statement)).toEqual([
|
||||
'TypeScript is a typed superset.',
|
||||
]);
|
||||
expect(alphaParents.map((topic) => topic.name)).toEqual(['programming language']);
|
||||
expect(betaParents.map((topic) => topic.name)).toEqual(['language family']);
|
||||
expect(alphaConnected.map((topic) => topic.name)).toEqual(['2025', 'I', 'programming language']);
|
||||
expect(betaConnected.map((topic) => topic.name)).toEqual(['superset']);
|
||||
} finally {
|
||||
await isolatedDb.close();
|
||||
}
|
||||
});
|
||||
|
||||
it('resolves alias names in topic lookups', async () => {
|
||||
await db.addTopicAlias('TypeScript', 'TS');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user