@utaba/deep-memory 0.2.0 → 0.4.0

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/providers-builtin/conformance.ts"],"sourcesContent":["// Provider Conformance Test Suite\n// Any StorageProvider implementer can import and run these tests to verify conformance.\n//\n// Usage:\n// import { runStorageProviderConformanceTests } from '@utaba/deep-memory';\n// runStorageProviderConformanceTests(() => new MyStorageProvider());\n\nimport { describe, it, expect, beforeEach } from 'vitest';\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type { StoredEntity } from '../types/entities.js';\nimport type { StoredRelationship } from '../types/relationships.js';\nimport type { Provenance } from '../types/provenance.js';\n\nfunction makeProvenance(): Provenance {\n const now = new Date().toISOString();\n return {\n createdBy: 'conformance-test',\n createdByType: 'agent',\n createdAt: now,\n modifiedBy: 'conformance-test',\n modifiedByType: 'agent',\n modifiedAt: now,\n };\n}\n\nfunction makeEntity(id: string, type = 'test-type', label?: string): StoredEntity {\n return {\n id,\n slug: `${type}:${(label ?? id).toLowerCase().replace(/[^a-z0-9]+/g, '-')}`,\n entityType: type,\n label: label ?? id,\n summary: `Summary for ${id}`,\n properties: { key: 'value' },\n provenance: makeProvenance(),\n };\n}\n\nfunction makeRelationship(\n id: string,\n type: string,\n sourceId: string,\n targetId: string,\n bidirectional = false,\n): StoredRelationship {\n return {\n id,\n relationshipType: type,\n sourceEntityId: sourceId,\n targetEntityId: targetId,\n properties: {},\n bidirectional,\n provenance: makeProvenance(),\n };\n}\n\n/**\n * Run the full StorageProvider conformance test suite.\n *\n * @param factory - A function that creates a fresh, empty StorageProvider instance.\n * Called before each test to ensure isolation.\n */\nexport function runStorageProviderConformanceTests(\n factory: () => StorageProvider | Promise<StorageProvider>,\n): void {\n // Use a stable GUID so external cleanup scripts can target it\n const repoId = '40000000-0000-4000-a000-000000000001';\n\n let provider: StorageProvider;\n\n async function setup(): Promise<void> {\n provider = await factory();\n if (provider.initialise) await provider.initialise();\n\n await provider.createRepository({\n repositoryId: repoId,\n label: 'Conformance Test',\n governanceConfig: { mode: 'open' },\n createdAt: new Date().toISOString(),\n createdBy: 'conformance-test',\n });\n }\n\n describe('StorageProvider Conformance Tests', () => {\n beforeEach(async () => {\n await setup();\n });\n\n // ─── Repository ─────────────────────────────────────────\n\n describe('repository operations', () => {\n it('creates a repository', async () => {\n const repo = await provider.getRepository(repoId);\n expect(repo).not.toBeNull();\n expect(repo!.repositoryId).toBe(repoId);\n expect(repo!.label).toBe('Conformance Test');\n });\n\n it('returns null for non-existent repository', async () => {\n const repo = await provider.getRepository('ffffffff-ffff-4fff-afff-ffffffffffff');\n expect(repo).toBeNull();\n });\n\n it('lists repositories', async () => {\n const list = await provider.listRepositories();\n expect(list.items.length).toBeGreaterThanOrEqual(1);\n expect(list.items.some((r) => r.repositoryId === repoId)).toBe(true);\n });\n\n it('updates a repository', async () => {\n const updated = await provider.updateRepository(repoId, {\n label: 'Updated Label',\n description: 'Updated description',\n governanceConfig: { mode: 'open', defaultSimilarityThreshold: 0.4 },\n });\n expect(updated.label).toBe('Updated Label');\n expect(updated.description).toBe('Updated description');\n expect(updated.governanceConfig.defaultSimilarityThreshold).toBe(0.4);\n\n // Verify persistence\n const fetched = await provider.getRepository(repoId);\n expect(fetched!.label).toBe('Updated Label');\n expect(fetched!.governanceConfig.defaultSimilarityThreshold).toBe(0.4);\n });\n\n it('deletes a repository', async () => {\n await provider.deleteRepository(repoId);\n expect(await provider.getRepository(repoId)).toBeNull();\n });\n\n it('returns repository stats', async () => {\n const stats = await provider.getRepositoryStats(repoId);\n expect(stats.entityCount).toBe(0);\n expect(stats.relationshipCount).toBe(0);\n expect(typeof stats.vocabularyVersion).toBe('string');\n });\n });\n\n // ─── Vocabulary ─────────────────────────────────────────\n\n describe('vocabulary operations', () => {\n it('gets and saves vocabulary', async () => {\n const vocab = await provider.getVocabulary(repoId);\n expect(vocab).toBeDefined();\n expect(typeof vocab.version).toBe('string');\n\n const updated = { ...vocab, version: '1.0.0' };\n await provider.saveVocabulary(repoId, updated);\n\n const fetched = await provider.getVocabulary(repoId);\n expect(fetched.version).toBe('1.0.0');\n });\n\n it('returns vocabulary change log', async () => {\n const log = await provider.getVocabularyChangeLog(repoId);\n expect(Array.isArray(log.items)).toBe(true);\n });\n });\n\n // ─── Entities ───────────────────────────────────────────\n\n describe('entity operations', () => {\n it('creates and retrieves an entity', async () => {\n const entity = makeEntity('e1');\n await provider.createEntity(repoId, entity);\n\n const retrieved = await provider.getEntity(repoId, 'e1');\n expect(retrieved).not.toBeNull();\n expect(retrieved!.id).toBe('e1');\n expect(retrieved!.label).toBe('e1');\n });\n\n it('retrieves an entity by slug', async () => {\n const entity = makeEntity('e1', 'test-type', 'Alpha');\n await provider.createEntity(repoId, entity);\n\n const retrieved = await provider.getEntityBySlug(repoId, entity.slug);\n expect(retrieved).not.toBeNull();\n expect(retrieved!.id).toBe('e1');\n expect(retrieved!.slug).toBe(entity.slug);\n });\n\n it('returns null for non-existent entity', async () => {\n const result = await provider.getEntity(repoId, 'nonexistent');\n expect(result).toBeNull();\n });\n\n it('returns null for non-existent slug', async () => {\n const result = await provider.getEntityBySlug(repoId, 'nonexistent:slug');\n expect(result).toBeNull();\n });\n\n it('batch retrieves entities', async () => {\n await provider.createEntity(repoId, makeEntity('e1'));\n await provider.createEntity(repoId, makeEntity('e2'));\n\n const map = await provider.getEntities(repoId, ['e1', 'e2', 'missing']);\n expect(map.size).toBe(2);\n expect(map.has('e1')).toBe(true);\n expect(map.has('e2')).toBe(true);\n expect(map.has('missing')).toBe(false);\n });\n\n it('updates an entity', async () => {\n await provider.createEntity(repoId, makeEntity('e1'));\n const updated = await provider.updateEntity(repoId, 'e1', {\n label: 'Updated Label',\n provenance: makeProvenance(),\n });\n expect(updated.label).toBe('Updated Label');\n\n const fetched = await provider.getEntity(repoId, 'e1');\n expect(fetched!.label).toBe('Updated Label');\n });\n\n it('deletes an entity', async () => {\n await provider.createEntity(repoId, makeEntity('e1'));\n await provider.deleteEntity(repoId, 'e1');\n expect(await provider.getEntity(repoId, 'e1')).toBeNull();\n });\n\n it('finds entities by search term', async () => {\n await provider.createEntity(repoId, makeEntity('e1', 'test-type', 'Alpha'));\n await provider.createEntity(repoId, makeEntity('e2', 'test-type', 'Beta'));\n\n const result = await provider.findEntities(repoId, {\n searchTerm: 'alpha',\n limit: 10,\n offset: 0,\n });\n expect(result.items).toHaveLength(1);\n expect(result.items[0]!.label).toBe('Alpha');\n });\n\n it('finds entities by type filter', async () => {\n await provider.createEntity(repoId, makeEntity('e1', 'type-a', 'A'));\n await provider.createEntity(repoId, makeEntity('e2', 'type-b', 'B'));\n\n const result = await provider.findEntities(repoId, {\n entityTypes: ['type-a'],\n limit: 10,\n offset: 0,\n });\n expect(result.items).toHaveLength(1);\n expect(result.items[0]!.entityType).toBe('type-a');\n });\n\n it('paginates find results', async () => {\n await provider.createEntity(repoId, makeEntity('e1'));\n await provider.createEntity(repoId, makeEntity('e2'));\n await provider.createEntity(repoId, makeEntity('e3'));\n\n const page1 = await provider.findEntities(repoId, { limit: 2, offset: 0 });\n expect(page1.items).toHaveLength(2);\n expect(page1.hasMore).toBe(true);\n\n const page2 = await provider.findEntities(repoId, { limit: 2, offset: 2 });\n expect(page2.items).toHaveLength(1);\n expect(page2.hasMore).toBe(false);\n });\n });\n\n // ─── Relationships ──────────────────────────────────────\n\n describe('relationship operations', () => {\n beforeEach(async () => {\n await provider.createEntity(repoId, makeEntity('a'));\n await provider.createEntity(repoId, makeEntity('b'));\n await provider.createEntity(repoId, makeEntity('c'));\n });\n\n it('creates and retrieves a relationship', async () => {\n const rel = makeRelationship('r1', 'connects', 'a', 'b');\n await provider.createRelationship(repoId, rel);\n\n const retrieved = await provider.getRelationship(repoId, 'r1');\n expect(retrieved).not.toBeNull();\n expect(retrieved!.sourceEntityId).toBe('a');\n expect(retrieved!.targetEntityId).toBe('b');\n });\n\n it('returns null for non-existent relationship', async () => {\n expect(await provider.getRelationship(repoId, 'nonexistent')).toBeNull();\n });\n\n it('gets entity relationships', async () => {\n await provider.createRelationship(repoId, makeRelationship('r1', 'connects', 'a', 'b'));\n await provider.createRelationship(repoId, makeRelationship('r2', 'connects', 'c', 'a'));\n\n const result = await provider.getEntityRelationships(repoId, 'a');\n expect(result.items).toHaveLength(2);\n });\n\n it('filters relationships by direction', async () => {\n await provider.createRelationship(repoId, makeRelationship('r1', 'connects', 'a', 'b'));\n await provider.createRelationship(repoId, makeRelationship('r2', 'connects', 'c', 'a'));\n\n const outbound = await provider.getEntityRelationships(repoId, 'a', { direction: 'outbound' });\n expect(outbound.items).toHaveLength(1);\n expect(outbound.items[0]!.targetEntityId).toBe('b');\n\n const inbound = await provider.getEntityRelationships(repoId, 'a', { direction: 'inbound' });\n expect(inbound.items).toHaveLength(1);\n expect(inbound.items[0]!.sourceEntityId).toBe('c');\n });\n\n it('deletes a relationship', async () => {\n await provider.createRelationship(repoId, makeRelationship('r1', 'connects', 'a', 'b'));\n await provider.deleteRelationship(repoId, 'r1');\n expect(await provider.getRelationship(repoId, 'r1')).toBeNull();\n });\n });\n\n // ─── Graph Traversal ────────────────────────────────────\n\n describe('graph traversal', () => {\n beforeEach(async () => {\n await provider.createEntity(repoId, makeEntity('a', 'node', 'A'));\n await provider.createEntity(repoId, makeEntity('b', 'node', 'B'));\n await provider.createEntity(repoId, makeEntity('c', 'node', 'C'));\n await provider.createRelationship(repoId, makeRelationship('r1', 'links', 'a', 'b'));\n await provider.createRelationship(repoId, makeRelationship('r2', 'links', 'b', 'c'));\n });\n\n it('explores neighbourhood at depth 1', async () => {\n const result = await provider.exploreNeighbourhood(repoId, 'a', {\n depth: 1,\n direction: 'both',\n limitPerType: 10,\n offsetPerType: 0,\n });\n expect(result.centreId).toBe('a');\n expect(result.layers).toHaveLength(1);\n });\n\n it('finds paths between connected entities', async () => {\n const result = await provider.findPaths(repoId, 'a', 'c', {\n maxDepth: 3,\n limit: 5,\n offset: 0,\n });\n expect(result.paths.length).toBeGreaterThanOrEqual(1);\n const firstPath = result.paths[0]!;\n expect(firstPath.entityIds[0]).toBe('a');\n expect(firstPath.entityIds[firstPath.entityIds.length - 1]).toBe('c');\n });\n\n it('returns empty paths when no connection', async () => {\n await provider.createEntity(repoId, makeEntity('isolated', 'node', 'Isolated'));\n const result = await provider.findPaths(repoId, 'a', 'isolated', {\n maxDepth: 3,\n limit: 5,\n offset: 0,\n });\n expect(result.paths).toHaveLength(0);\n });\n\n it('finds paths through non-bidirectional inbound edges', async () => {\n // Graph: a → b ← d (both edges are non-bidirectional)\n // Path from a to d should traverse: a →(outbound) b ←(inbound) d\n await provider.createEntity(repoId, makeEntity('d', 'node', 'D'));\n await provider.createRelationship(repoId, makeRelationship('r3', 'links', 'd', 'b'));\n const result = await provider.findPaths(repoId, 'a', 'd', {\n maxDepth: 3,\n limit: 5,\n offset: 0,\n });\n expect(result.paths.length).toBeGreaterThanOrEqual(1);\n const firstPath = result.paths[0]!;\n expect(firstPath.entityIds[0]).toBe('a');\n expect(firstPath.entityIds[firstPath.entityIds.length - 1]).toBe('d');\n });\n });\n\n // ─── Timeline ───────────────────────────────────────────\n\n describe('timeline', () => {\n it('returns timeline events', async () => {\n await provider.createEntity(repoId, makeEntity('e1'));\n const result = await provider.getTimeline(repoId, 'e1', {\n limit: 10,\n offset: 0,\n });\n expect(result.events.length).toBeGreaterThanOrEqual(1);\n });\n });\n\n // ─── Bulk Operations ────────────────────────────────────\n\n describe('bulk operations', () => {\n it('exports data', async () => {\n await provider.createEntity(repoId, makeEntity('e1'));\n\n const chunks = [];\n for await (const chunk of provider.exportAll(repoId)) {\n chunks.push(chunk);\n }\n expect(chunks.length).toBeGreaterThanOrEqual(1);\n });\n\n it('imports data', async () => {\n const result = await provider.importBulk(repoId, [\n { entities: [makeEntity('imported-1'), makeEntity('imported-2')] },\n { relationships: [makeRelationship('ir1', 'links', 'imported-1', 'imported-2')] },\n ]);\n expect(result.entitiesImported).toBe(2);\n expect(result.relationshipsImported).toBe(1);\n\n // Verify imported data is accessible\n const e = await provider.getEntity(repoId, 'imported-1');\n expect(e).not.toBeNull();\n });\n });\n\n // ─── Stats after data ───────────────────────────────────\n\n describe('stats reflect data', () => {\n it('counts entities and relationships', async () => {\n await provider.createEntity(repoId, makeEntity('e1', 'alpha'));\n await provider.createEntity(repoId, makeEntity('e2', 'alpha'));\n await provider.createEntity(repoId, makeEntity('e3', 'beta'));\n await provider.createRelationship(repoId, makeRelationship('r1', 'links', 'e1', 'e2'));\n\n const stats = await provider.getRepositoryStats(repoId);\n expect(stats.entityCount).toBe(3);\n expect(stats.relationshipCount).toBe(1);\n expect(stats.entityTypeBreakdown['alpha']).toBe(2);\n expect(stats.entityTypeBreakdown['beta']).toBe(1);\n expect(stats.relationshipTypeBreakdown['links']).toBe(1);\n });\n });\n });\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/providers-builtin/conformance.ts"],"sourcesContent":["// Provider Conformance Test Suite\n// Any StorageProvider implementer can import and run these tests to verify conformance.\n//\n// Usage:\n// import { runStorageProviderConformanceTests } from '@utaba/deep-memory';\n// runStorageProviderConformanceTests(() => new MyStorageProvider());\n\nimport { describe, it, expect, beforeEach } from 'vitest';\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type { StoredEntity } from '../types/entities.js';\nimport type { StoredRelationship } from '../types/relationships.js';\nimport type { Provenance } from '../types/provenance.js';\n\nfunction makeProvenance(): Provenance {\n const now = new Date().toISOString();\n return {\n createdBy: 'conformance-test',\n createdByType: 'agent',\n createdAt: now,\n modifiedBy: 'conformance-test',\n modifiedByType: 'agent',\n modifiedAt: now,\n };\n}\n\nfunction makeEntity(id: string, type = 'test-type', label?: string): StoredEntity {\n return {\n id,\n slug: `${type}:${(label ?? id).toLowerCase().replace(/[^a-z0-9]+/g, '-')}`,\n entityType: type,\n label: label ?? id,\n summary: `Summary for ${id}`,\n properties: { key: 'value' },\n provenance: makeProvenance(),\n };\n}\n\nfunction makeRelationship(\n id: string,\n type: string,\n sourceId: string,\n targetId: string,\n bidirectional = false,\n): StoredRelationship {\n return {\n id,\n relationshipType: type,\n sourceEntityId: sourceId,\n targetEntityId: targetId,\n properties: {},\n bidirectional,\n provenance: makeProvenance(),\n };\n}\n\n/**\n * Run the full StorageProvider conformance test suite.\n *\n * @param factory - A function that creates a fresh, empty StorageProvider instance.\n * Called before each test to ensure isolation.\n */\nexport function runStorageProviderConformanceTests(\n factory: () => StorageProvider | Promise<StorageProvider>,\n): void {\n // Use a stable GUID so external cleanup scripts can target it\n const repoId = '40000000-0000-4000-a000-000000000001';\n\n let provider: StorageProvider;\n\n async function setup(): Promise<void> {\n provider = await factory();\n if (provider.initialize) await provider.initialize();\n\n await provider.createRepository({\n repositoryId: repoId,\n label: 'Conformance Test',\n governanceConfig: { mode: 'open' },\n createdAt: new Date().toISOString(),\n createdBy: 'conformance-test',\n });\n }\n\n describe('StorageProvider Conformance Tests', () => {\n beforeEach(async () => {\n await setup();\n });\n\n // ─── Repository ─────────────────────────────────────────\n\n describe('repository operations', () => {\n it('creates a repository', async () => {\n const repo = await provider.getRepository(repoId);\n expect(repo).not.toBeNull();\n expect(repo!.repositoryId).toBe(repoId);\n expect(repo!.label).toBe('Conformance Test');\n });\n\n it('returns null for non-existent repository', async () => {\n const repo = await provider.getRepository('ffffffff-ffff-4fff-afff-ffffffffffff');\n expect(repo).toBeNull();\n });\n\n it('lists repositories', async () => {\n const list = await provider.listRepositories();\n expect(list.items.length).toBeGreaterThanOrEqual(1);\n expect(list.items.some((r) => r.repositoryId === repoId)).toBe(true);\n });\n\n it('updates a repository', async () => {\n const updated = await provider.updateRepository(repoId, {\n label: 'Updated Label',\n description: 'Updated description',\n governanceConfig: { mode: 'open', defaultSimilarityThreshold: 0.4 },\n });\n expect(updated.label).toBe('Updated Label');\n expect(updated.description).toBe('Updated description');\n expect(updated.governanceConfig.defaultSimilarityThreshold).toBe(0.4);\n\n // Verify persistence\n const fetched = await provider.getRepository(repoId);\n expect(fetched!.label).toBe('Updated Label');\n expect(fetched!.governanceConfig.defaultSimilarityThreshold).toBe(0.4);\n });\n\n it('deletes a repository', async () => {\n await provider.deleteRepository(repoId);\n expect(await provider.getRepository(repoId)).toBeNull();\n });\n\n it('returns repository stats', async () => {\n const stats = await provider.getRepositoryStats(repoId);\n expect(stats.entityCount).toBe(0);\n expect(stats.relationshipCount).toBe(0);\n expect(typeof stats.vocabularyVersion).toBe('string');\n });\n });\n\n // ─── Vocabulary ─────────────────────────────────────────\n\n describe('vocabulary operations', () => {\n it('gets and saves vocabulary', async () => {\n const vocab = await provider.getVocabulary(repoId);\n expect(vocab).toBeDefined();\n expect(typeof vocab.version).toBe('string');\n\n const updated = { ...vocab, version: '1.0.0' };\n await provider.saveVocabulary(repoId, updated);\n\n const fetched = await provider.getVocabulary(repoId);\n expect(fetched.version).toBe('1.0.0');\n });\n\n it('returns vocabulary change log', async () => {\n const log = await provider.getVocabularyChangeLog(repoId);\n expect(Array.isArray(log.items)).toBe(true);\n });\n });\n\n // ─── Entities ───────────────────────────────────────────\n\n describe('entity operations', () => {\n it('creates and retrieves an entity', async () => {\n const entity = makeEntity('e1');\n await provider.createEntity(repoId, entity);\n\n const retrieved = await provider.getEntity(repoId, 'e1');\n expect(retrieved).not.toBeNull();\n expect(retrieved!.id).toBe('e1');\n expect(retrieved!.label).toBe('e1');\n });\n\n it('retrieves an entity by slug', async () => {\n const entity = makeEntity('e1', 'test-type', 'Alpha');\n await provider.createEntity(repoId, entity);\n\n const retrieved = await provider.getEntityBySlug(repoId, entity.slug);\n expect(retrieved).not.toBeNull();\n expect(retrieved!.id).toBe('e1');\n expect(retrieved!.slug).toBe(entity.slug);\n });\n\n it('returns null for non-existent entity', async () => {\n const result = await provider.getEntity(repoId, 'nonexistent');\n expect(result).toBeNull();\n });\n\n it('returns null for non-existent slug', async () => {\n const result = await provider.getEntityBySlug(repoId, 'nonexistent:slug');\n expect(result).toBeNull();\n });\n\n it('batch retrieves entities', async () => {\n await provider.createEntity(repoId, makeEntity('e1'));\n await provider.createEntity(repoId, makeEntity('e2'));\n\n const map = await provider.getEntities(repoId, ['e1', 'e2', 'missing']);\n expect(map.size).toBe(2);\n expect(map.has('e1')).toBe(true);\n expect(map.has('e2')).toBe(true);\n expect(map.has('missing')).toBe(false);\n });\n\n it('updates an entity', async () => {\n await provider.createEntity(repoId, makeEntity('e1'));\n const updated = await provider.updateEntity(repoId, 'e1', {\n label: 'Updated Label',\n provenance: makeProvenance(),\n });\n expect(updated.label).toBe('Updated Label');\n\n const fetched = await provider.getEntity(repoId, 'e1');\n expect(fetched!.label).toBe('Updated Label');\n });\n\n it('deletes an entity', async () => {\n await provider.createEntity(repoId, makeEntity('e1'));\n await provider.deleteEntity(repoId, 'e1');\n expect(await provider.getEntity(repoId, 'e1')).toBeNull();\n });\n\n it('finds entities by search term', async () => {\n await provider.createEntity(repoId, makeEntity('e1', 'test-type', 'Alpha'));\n await provider.createEntity(repoId, makeEntity('e2', 'test-type', 'Beta'));\n\n const result = await provider.findEntities(repoId, {\n searchTerm: 'alpha',\n limit: 10,\n offset: 0,\n });\n expect(result.items).toHaveLength(1);\n expect(result.items[0]!.label).toBe('Alpha');\n });\n\n it('finds entities by type filter', async () => {\n await provider.createEntity(repoId, makeEntity('e1', 'type-a', 'A'));\n await provider.createEntity(repoId, makeEntity('e2', 'type-b', 'B'));\n\n const result = await provider.findEntities(repoId, {\n entityTypes: ['type-a'],\n limit: 10,\n offset: 0,\n });\n expect(result.items).toHaveLength(1);\n expect(result.items[0]!.entityType).toBe('type-a');\n });\n\n it('paginates find results', async () => {\n await provider.createEntity(repoId, makeEntity('e1'));\n await provider.createEntity(repoId, makeEntity('e2'));\n await provider.createEntity(repoId, makeEntity('e3'));\n\n const page1 = await provider.findEntities(repoId, { limit: 2, offset: 0 });\n expect(page1.items).toHaveLength(2);\n expect(page1.hasMore).toBe(true);\n\n const page2 = await provider.findEntities(repoId, { limit: 2, offset: 2 });\n expect(page2.items).toHaveLength(1);\n expect(page2.hasMore).toBe(false);\n });\n });\n\n // ─── Relationships ──────────────────────────────────────\n\n describe('relationship operations', () => {\n beforeEach(async () => {\n await provider.createEntity(repoId, makeEntity('a'));\n await provider.createEntity(repoId, makeEntity('b'));\n await provider.createEntity(repoId, makeEntity('c'));\n });\n\n it('creates and retrieves a relationship', async () => {\n const rel = makeRelationship('r1', 'connects', 'a', 'b');\n await provider.createRelationship(repoId, rel);\n\n const retrieved = await provider.getRelationship(repoId, 'r1');\n expect(retrieved).not.toBeNull();\n expect(retrieved!.sourceEntityId).toBe('a');\n expect(retrieved!.targetEntityId).toBe('b');\n });\n\n it('returns null for non-existent relationship', async () => {\n expect(await provider.getRelationship(repoId, 'nonexistent')).toBeNull();\n });\n\n it('gets entity relationships', async () => {\n await provider.createRelationship(repoId, makeRelationship('r1', 'connects', 'a', 'b'));\n await provider.createRelationship(repoId, makeRelationship('r2', 'connects', 'c', 'a'));\n\n const result = await provider.getEntityRelationships(repoId, 'a');\n expect(result.items).toHaveLength(2);\n });\n\n it('filters relationships by direction', async () => {\n await provider.createRelationship(repoId, makeRelationship('r1', 'connects', 'a', 'b'));\n await provider.createRelationship(repoId, makeRelationship('r2', 'connects', 'c', 'a'));\n\n const outbound = await provider.getEntityRelationships(repoId, 'a', { direction: 'outbound' });\n expect(outbound.items).toHaveLength(1);\n expect(outbound.items[0]!.targetEntityId).toBe('b');\n\n const inbound = await provider.getEntityRelationships(repoId, 'a', { direction: 'inbound' });\n expect(inbound.items).toHaveLength(1);\n expect(inbound.items[0]!.sourceEntityId).toBe('c');\n });\n\n it('deletes a relationship', async () => {\n await provider.createRelationship(repoId, makeRelationship('r1', 'connects', 'a', 'b'));\n await provider.deleteRelationship(repoId, 'r1');\n expect(await provider.getRelationship(repoId, 'r1')).toBeNull();\n });\n });\n\n // ─── Graph Traversal ────────────────────────────────────\n\n describe('graph traversal', () => {\n beforeEach(async () => {\n await provider.createEntity(repoId, makeEntity('a', 'node', 'A'));\n await provider.createEntity(repoId, makeEntity('b', 'node', 'B'));\n await provider.createEntity(repoId, makeEntity('c', 'node', 'C'));\n await provider.createRelationship(repoId, makeRelationship('r1', 'links', 'a', 'b'));\n await provider.createRelationship(repoId, makeRelationship('r2', 'links', 'b', 'c'));\n });\n\n it('explores neighborhood at depth 1', async () => {\n const result = await provider.exploreNeighborhood(repoId, 'a', {\n depth: 1,\n direction: 'both',\n limitPerType: 10,\n offsetPerType: 0,\n });\n expect(result.centerId).toBe('a');\n expect(result.layers).toHaveLength(1);\n });\n\n it('finds paths between connected entities', async () => {\n const result = await provider.findPaths(repoId, 'a', 'c', {\n maxDepth: 3,\n limit: 5,\n offset: 0,\n });\n expect(result.paths.length).toBeGreaterThanOrEqual(1);\n const firstPath = result.paths[0]!;\n expect(firstPath.entityIds[0]).toBe('a');\n expect(firstPath.entityIds[firstPath.entityIds.length - 1]).toBe('c');\n });\n\n it('returns empty paths when no connection', async () => {\n await provider.createEntity(repoId, makeEntity('isolated', 'node', 'Isolated'));\n const result = await provider.findPaths(repoId, 'a', 'isolated', {\n maxDepth: 3,\n limit: 5,\n offset: 0,\n });\n expect(result.paths).toHaveLength(0);\n });\n\n it('finds paths through non-bidirectional inbound edges', async () => {\n // Graph: a → b ← d (both edges are non-bidirectional)\n // Path from a to d should traverse: a →(outbound) b ←(inbound) d\n await provider.createEntity(repoId, makeEntity('d', 'node', 'D'));\n await provider.createRelationship(repoId, makeRelationship('r3', 'links', 'd', 'b'));\n const result = await provider.findPaths(repoId, 'a', 'd', {\n maxDepth: 3,\n limit: 5,\n offset: 0,\n });\n expect(result.paths.length).toBeGreaterThanOrEqual(1);\n const firstPath = result.paths[0]!;\n expect(firstPath.entityIds[0]).toBe('a');\n expect(firstPath.entityIds[firstPath.entityIds.length - 1]).toBe('d');\n });\n });\n\n // ─── Timeline ───────────────────────────────────────────\n\n describe('timeline', () => {\n it('returns timeline events', async () => {\n await provider.createEntity(repoId, makeEntity('e1'));\n const result = await provider.getTimeline(repoId, 'e1', {\n limit: 10,\n offset: 0,\n });\n expect(result.events.length).toBeGreaterThanOrEqual(1);\n });\n });\n\n // ─── Bulk Operations ────────────────────────────────────\n\n describe('bulk operations', () => {\n it('exports data', async () => {\n await provider.createEntity(repoId, makeEntity('e1'));\n\n const chunks = [];\n for await (const chunk of provider.exportAll(repoId)) {\n chunks.push(chunk);\n }\n expect(chunks.length).toBeGreaterThanOrEqual(1);\n });\n\n it('imports data', async () => {\n const result = await provider.importBulk(repoId, [\n { entities: [makeEntity('imported-1'), makeEntity('imported-2')] },\n { relationships: [makeRelationship('ir1', 'links', 'imported-1', 'imported-2')] },\n ]);\n expect(result.entitiesImported).toBe(2);\n expect(result.relationshipsImported).toBe(1);\n\n // Verify imported data is accessible\n const e = await provider.getEntity(repoId, 'imported-1');\n expect(e).not.toBeNull();\n });\n });\n\n // ─── Delete All Contents ───────────────────────────────\n\n describe('deleteAllContents', () => {\n it('deletes all entities and relationships but preserves the repository', async () => {\n await provider.createEntity(repoId, makeEntity('e1', 'alpha'));\n await provider.createEntity(repoId, makeEntity('e2', 'beta'));\n await provider.createRelationship(repoId, makeRelationship('r1', 'links', 'e1', 'e2'));\n\n const result = await provider.deleteAllContents(repoId);\n expect(result.deletedEntities).toBe(2);\n expect(result.deletedRelationships).toBe(1);\n\n // Repository still exists\n const repo = await provider.getRepository(repoId);\n expect(repo).not.toBeNull();\n\n // Vocabulary still exists\n const vocab = await provider.getVocabulary(repoId);\n expect(vocab).toBeDefined();\n\n // Contents are gone\n const stats = await provider.getRepositoryStats(repoId);\n expect(stats.entityCount).toBe(0);\n expect(stats.relationshipCount).toBe(0);\n });\n\n it('returns zero counts on an empty repository', async () => {\n const result = await provider.deleteAllContents(repoId);\n expect(result.deletedEntities).toBe(0);\n expect(result.deletedRelationships).toBe(0);\n });\n });\n\n // ─── Stats after data ───────────────────────────────────\n\n describe('stats reflect data', () => {\n it('counts entities and relationships', async () => {\n await provider.createEntity(repoId, makeEntity('e1', 'alpha'));\n await provider.createEntity(repoId, makeEntity('e2', 'alpha'));\n await provider.createEntity(repoId, makeEntity('e3', 'beta'));\n await provider.createRelationship(repoId, makeRelationship('r1', 'links', 'e1', 'e2'));\n\n const stats = await provider.getRepositoryStats(repoId);\n expect(stats.entityCount).toBe(3);\n expect(stats.relationshipCount).toBe(1);\n expect(stats.entityTypeBreakdown['alpha']).toBe(2);\n expect(stats.entityTypeBreakdown['beta']).toBe(1);\n expect(stats.relationshipTypeBreakdown['links']).toBe(1);\n });\n });\n });\n}\n"],"mappings":";AAOA,SAAS,UAAU,IAAI,QAAQ,kBAAkB;AAMjD,SAAS,iBAA6B;AACpC,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,SAAO;AAAA,IACL,WAAW;AAAA,IACX,eAAe;AAAA,IACf,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,YAAY;AAAA,EACd;AACF;AAEA,SAAS,WAAW,IAAY,OAAO,aAAa,OAA8B;AAChF,SAAO;AAAA,IACL;AAAA,IACA,MAAM,GAAG,IAAI,KAAK,SAAS,IAAI,YAAY,EAAE,QAAQ,eAAe,GAAG,CAAC;AAAA,IACxE,YAAY;AAAA,IACZ,OAAO,SAAS;AAAA,IAChB,SAAS,eAAe,EAAE;AAAA,IAC1B,YAAY,EAAE,KAAK,QAAQ;AAAA,IAC3B,YAAY,eAAe;AAAA,EAC7B;AACF;AAEA,SAAS,iBACP,IACA,MACA,UACA,UACA,gBAAgB,OACI;AACpB,SAAO;AAAA,IACL;AAAA,IACA,kBAAkB;AAAA,IAClB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,YAAY,CAAC;AAAA,IACb;AAAA,IACA,YAAY,eAAe;AAAA,EAC7B;AACF;AAQO,SAAS,mCACd,SACM;AAEN,QAAM,SAAS;AAEf,MAAI;AAEJ,iBAAe,QAAuB;AACpC,eAAW,MAAM,QAAQ;AACzB,QAAI,SAAS,WAAY,OAAM,SAAS,WAAW;AAEnD,UAAM,SAAS,iBAAiB;AAAA,MAC9B,cAAc;AAAA,MACd,OAAO;AAAA,MACP,kBAAkB,EAAE,MAAM,OAAO;AAAA,MACjC,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,WAAS,qCAAqC,MAAM;AAClD,eAAW,YAAY;AACrB,YAAM,MAAM;AAAA,IACd,CAAC;AAID,aAAS,yBAAyB,MAAM;AACtC,SAAG,wBAAwB,YAAY;AACrC,cAAM,OAAO,MAAM,SAAS,cAAc,MAAM;AAChD,eAAO,IAAI,EAAE,IAAI,SAAS;AAC1B,eAAO,KAAM,YAAY,EAAE,KAAK,MAAM;AACtC,eAAO,KAAM,KAAK,EAAE,KAAK,kBAAkB;AAAA,MAC7C,CAAC;AAED,SAAG,4CAA4C,YAAY;AACzD,cAAM,OAAO,MAAM,SAAS,cAAc,sCAAsC;AAChF,eAAO,IAAI,EAAE,SAAS;AAAA,MACxB,CAAC;AAED,SAAG,sBAAsB,YAAY;AACnC,cAAM,OAAO,MAAM,SAAS,iBAAiB;AAC7C,eAAO,KAAK,MAAM,MAAM,EAAE,uBAAuB,CAAC;AAClD,eAAO,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,iBAAiB,MAAM,CAAC,EAAE,KAAK,IAAI;AAAA,MACrE,CAAC;AAED,SAAG,wBAAwB,YAAY;AACrC,cAAM,UAAU,MAAM,SAAS,iBAAiB,QAAQ;AAAA,UACtD,OAAO;AAAA,UACP,aAAa;AAAA,UACb,kBAAkB,EAAE,MAAM,QAAQ,4BAA4B,IAAI;AAAA,QACpE,CAAC;AACD,eAAO,QAAQ,KAAK,EAAE,KAAK,eAAe;AAC1C,eAAO,QAAQ,WAAW,EAAE,KAAK,qBAAqB;AACtD,eAAO,QAAQ,iBAAiB,0BAA0B,EAAE,KAAK,GAAG;AAGpE,cAAM,UAAU,MAAM,SAAS,cAAc,MAAM;AACnD,eAAO,QAAS,KAAK,EAAE,KAAK,eAAe;AAC3C,eAAO,QAAS,iBAAiB,0BAA0B,EAAE,KAAK,GAAG;AAAA,MACvE,CAAC;AAED,SAAG,wBAAwB,YAAY;AACrC,cAAM,SAAS,iBAAiB,MAAM;AACtC,eAAO,MAAM,SAAS,cAAc,MAAM,CAAC,EAAE,SAAS;AAAA,MACxD,CAAC;AAED,SAAG,4BAA4B,YAAY;AACzC,cAAM,QAAQ,MAAM,SAAS,mBAAmB,MAAM;AACtD,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC;AAChC,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC;AACtC,eAAO,OAAO,MAAM,iBAAiB,EAAE,KAAK,QAAQ;AAAA,MACtD,CAAC;AAAA,IACH,CAAC;AAID,aAAS,yBAAyB,MAAM;AACtC,SAAG,6BAA6B,YAAY;AAC1C,cAAM,QAAQ,MAAM,SAAS,cAAc,MAAM;AACjD,eAAO,KAAK,EAAE,YAAY;AAC1B,eAAO,OAAO,MAAM,OAAO,EAAE,KAAK,QAAQ;AAE1C,cAAM,UAAU,EAAE,GAAG,OAAO,SAAS,QAAQ;AAC7C,cAAM,SAAS,eAAe,QAAQ,OAAO;AAE7C,cAAM,UAAU,MAAM,SAAS,cAAc,MAAM;AACnD,eAAO,QAAQ,OAAO,EAAE,KAAK,OAAO;AAAA,MACtC,CAAC;AAED,SAAG,iCAAiC,YAAY;AAC9C,cAAM,MAAM,MAAM,SAAS,uBAAuB,MAAM;AACxD,eAAO,MAAM,QAAQ,IAAI,KAAK,CAAC,EAAE,KAAK,IAAI;AAAA,MAC5C,CAAC;AAAA,IACH,CAAC;AAID,aAAS,qBAAqB,MAAM;AAClC,SAAG,mCAAmC,YAAY;AAChD,cAAM,SAAS,WAAW,IAAI;AAC9B,cAAM,SAAS,aAAa,QAAQ,MAAM;AAE1C,cAAM,YAAY,MAAM,SAAS,UAAU,QAAQ,IAAI;AACvD,eAAO,SAAS,EAAE,IAAI,SAAS;AAC/B,eAAO,UAAW,EAAE,EAAE,KAAK,IAAI;AAC/B,eAAO,UAAW,KAAK,EAAE,KAAK,IAAI;AAAA,MACpC,CAAC;AAED,SAAG,+BAA+B,YAAY;AAC5C,cAAM,SAAS,WAAW,MAAM,aAAa,OAAO;AACpD,cAAM,SAAS,aAAa,QAAQ,MAAM;AAE1C,cAAM,YAAY,MAAM,SAAS,gBAAgB,QAAQ,OAAO,IAAI;AACpE,eAAO,SAAS,EAAE,IAAI,SAAS;AAC/B,eAAO,UAAW,EAAE,EAAE,KAAK,IAAI;AAC/B,eAAO,UAAW,IAAI,EAAE,KAAK,OAAO,IAAI;AAAA,MAC1C,CAAC;AAED,SAAG,wCAAwC,YAAY;AACrD,cAAM,SAAS,MAAM,SAAS,UAAU,QAAQ,aAAa;AAC7D,eAAO,MAAM,EAAE,SAAS;AAAA,MAC1B,CAAC;AAED,SAAG,sCAAsC,YAAY;AACnD,cAAM,SAAS,MAAM,SAAS,gBAAgB,QAAQ,kBAAkB;AACxE,eAAO,MAAM,EAAE,SAAS;AAAA,MAC1B,CAAC;AAED,SAAG,4BAA4B,YAAY;AACzC,cAAM,SAAS,aAAa,QAAQ,WAAW,IAAI,CAAC;AACpD,cAAM,SAAS,aAAa,QAAQ,WAAW,IAAI,CAAC;AAEpD,cAAM,MAAM,MAAM,SAAS,YAAY,QAAQ,CAAC,MAAM,MAAM,SAAS,CAAC;AACtE,eAAO,IAAI,IAAI,EAAE,KAAK,CAAC;AACvB,eAAO,IAAI,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI;AAC/B,eAAO,IAAI,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI;AAC/B,eAAO,IAAI,IAAI,SAAS,CAAC,EAAE,KAAK,KAAK;AAAA,MACvC,CAAC;AAED,SAAG,qBAAqB,YAAY;AAClC,cAAM,SAAS,aAAa,QAAQ,WAAW,IAAI,CAAC;AACpD,cAAM,UAAU,MAAM,SAAS,aAAa,QAAQ,MAAM;AAAA,UACxD,OAAO;AAAA,UACP,YAAY,eAAe;AAAA,QAC7B,CAAC;AACD,eAAO,QAAQ,KAAK,EAAE,KAAK,eAAe;AAE1C,cAAM,UAAU,MAAM,SAAS,UAAU,QAAQ,IAAI;AACrD,eAAO,QAAS,KAAK,EAAE,KAAK,eAAe;AAAA,MAC7C,CAAC;AAED,SAAG,qBAAqB,YAAY;AAClC,cAAM,SAAS,aAAa,QAAQ,WAAW,IAAI,CAAC;AACpD,cAAM,SAAS,aAAa,QAAQ,IAAI;AACxC,eAAO,MAAM,SAAS,UAAU,QAAQ,IAAI,CAAC,EAAE,SAAS;AAAA,MAC1D,CAAC;AAED,SAAG,iCAAiC,YAAY;AAC9C,cAAM,SAAS,aAAa,QAAQ,WAAW,MAAM,aAAa,OAAO,CAAC;AAC1E,cAAM,SAAS,aAAa,QAAQ,WAAW,MAAM,aAAa,MAAM,CAAC;AAEzE,cAAM,SAAS,MAAM,SAAS,aAAa,QAAQ;AAAA,UACjD,YAAY;AAAA,UACZ,OAAO;AAAA,UACP,QAAQ;AAAA,QACV,CAAC;AACD,eAAO,OAAO,KAAK,EAAE,aAAa,CAAC;AACnC,eAAO,OAAO,MAAM,CAAC,EAAG,KAAK,EAAE,KAAK,OAAO;AAAA,MAC7C,CAAC;AAED,SAAG,iCAAiC,YAAY;AAC9C,cAAM,SAAS,aAAa,QAAQ,WAAW,MAAM,UAAU,GAAG,CAAC;AACnE,cAAM,SAAS,aAAa,QAAQ,WAAW,MAAM,UAAU,GAAG,CAAC;AAEnE,cAAM,SAAS,MAAM,SAAS,aAAa,QAAQ;AAAA,UACjD,aAAa,CAAC,QAAQ;AAAA,UACtB,OAAO;AAAA,UACP,QAAQ;AAAA,QACV,CAAC;AACD,eAAO,OAAO,KAAK,EAAE,aAAa,CAAC;AACnC,eAAO,OAAO,MAAM,CAAC,EAAG,UAAU,EAAE,KAAK,QAAQ;AAAA,MACnD,CAAC;AAED,SAAG,0BAA0B,YAAY;AACvC,cAAM,SAAS,aAAa,QAAQ,WAAW,IAAI,CAAC;AACpD,cAAM,SAAS,aAAa,QAAQ,WAAW,IAAI,CAAC;AACpD,cAAM,SAAS,aAAa,QAAQ,WAAW,IAAI,CAAC;AAEpD,cAAM,QAAQ,MAAM,SAAS,aAAa,QAAQ,EAAE,OAAO,GAAG,QAAQ,EAAE,CAAC;AACzE,eAAO,MAAM,KAAK,EAAE,aAAa,CAAC;AAClC,eAAO,MAAM,OAAO,EAAE,KAAK,IAAI;AAE/B,cAAM,QAAQ,MAAM,SAAS,aAAa,QAAQ,EAAE,OAAO,GAAG,QAAQ,EAAE,CAAC;AACzE,eAAO,MAAM,KAAK,EAAE,aAAa,CAAC;AAClC,eAAO,MAAM,OAAO,EAAE,KAAK,KAAK;AAAA,MAClC,CAAC;AAAA,IACH,CAAC;AAID,aAAS,2BAA2B,MAAM;AACxC,iBAAW,YAAY;AACrB,cAAM,SAAS,aAAa,QAAQ,WAAW,GAAG,CAAC;AACnD,cAAM,SAAS,aAAa,QAAQ,WAAW,GAAG,CAAC;AACnD,cAAM,SAAS,aAAa,QAAQ,WAAW,GAAG,CAAC;AAAA,MACrD,CAAC;AAED,SAAG,wCAAwC,YAAY;AACrD,cAAM,MAAM,iBAAiB,MAAM,YAAY,KAAK,GAAG;AACvD,cAAM,SAAS,mBAAmB,QAAQ,GAAG;AAE7C,cAAM,YAAY,MAAM,SAAS,gBAAgB,QAAQ,IAAI;AAC7D,eAAO,SAAS,EAAE,IAAI,SAAS;AAC/B,eAAO,UAAW,cAAc,EAAE,KAAK,GAAG;AAC1C,eAAO,UAAW,cAAc,EAAE,KAAK,GAAG;AAAA,MAC5C,CAAC;AAED,SAAG,8CAA8C,YAAY;AAC3D,eAAO,MAAM,SAAS,gBAAgB,QAAQ,aAAa,CAAC,EAAE,SAAS;AAAA,MACzE,CAAC;AAED,SAAG,6BAA6B,YAAY;AAC1C,cAAM,SAAS,mBAAmB,QAAQ,iBAAiB,MAAM,YAAY,KAAK,GAAG,CAAC;AACtF,cAAM,SAAS,mBAAmB,QAAQ,iBAAiB,MAAM,YAAY,KAAK,GAAG,CAAC;AAEtF,cAAM,SAAS,MAAM,SAAS,uBAAuB,QAAQ,GAAG;AAChE,eAAO,OAAO,KAAK,EAAE,aAAa,CAAC;AAAA,MACrC,CAAC;AAED,SAAG,sCAAsC,YAAY;AACnD,cAAM,SAAS,mBAAmB,QAAQ,iBAAiB,MAAM,YAAY,KAAK,GAAG,CAAC;AACtF,cAAM,SAAS,mBAAmB,QAAQ,iBAAiB,MAAM,YAAY,KAAK,GAAG,CAAC;AAEtF,cAAM,WAAW,MAAM,SAAS,uBAAuB,QAAQ,KAAK,EAAE,WAAW,WAAW,CAAC;AAC7F,eAAO,SAAS,KAAK,EAAE,aAAa,CAAC;AACrC,eAAO,SAAS,MAAM,CAAC,EAAG,cAAc,EAAE,KAAK,GAAG;AAElD,cAAM,UAAU,MAAM,SAAS,uBAAuB,QAAQ,KAAK,EAAE,WAAW,UAAU,CAAC;AAC3F,eAAO,QAAQ,KAAK,EAAE,aAAa,CAAC;AACpC,eAAO,QAAQ,MAAM,CAAC,EAAG,cAAc,EAAE,KAAK,GAAG;AAAA,MACnD,CAAC;AAED,SAAG,0BAA0B,YAAY;AACvC,cAAM,SAAS,mBAAmB,QAAQ,iBAAiB,MAAM,YAAY,KAAK,GAAG,CAAC;AACtF,cAAM,SAAS,mBAAmB,QAAQ,IAAI;AAC9C,eAAO,MAAM,SAAS,gBAAgB,QAAQ,IAAI,CAAC,EAAE,SAAS;AAAA,MAChE,CAAC;AAAA,IACH,CAAC;AAID,aAAS,mBAAmB,MAAM;AAChC,iBAAW,YAAY;AACrB,cAAM,SAAS,aAAa,QAAQ,WAAW,KAAK,QAAQ,GAAG,CAAC;AAChE,cAAM,SAAS,aAAa,QAAQ,WAAW,KAAK,QAAQ,GAAG,CAAC;AAChE,cAAM,SAAS,aAAa,QAAQ,WAAW,KAAK,QAAQ,GAAG,CAAC;AAChE,cAAM,SAAS,mBAAmB,QAAQ,iBAAiB,MAAM,SAAS,KAAK,GAAG,CAAC;AACnF,cAAM,SAAS,mBAAmB,QAAQ,iBAAiB,MAAM,SAAS,KAAK,GAAG,CAAC;AAAA,MACrF,CAAC;AAED,SAAG,oCAAoC,YAAY;AACjD,cAAM,SAAS,MAAM,SAAS,oBAAoB,QAAQ,KAAK;AAAA,UAC7D,OAAO;AAAA,UACP,WAAW;AAAA,UACX,cAAc;AAAA,UACd,eAAe;AAAA,QACjB,CAAC;AACD,eAAO,OAAO,QAAQ,EAAE,KAAK,GAAG;AAChC,eAAO,OAAO,MAAM,EAAE,aAAa,CAAC;AAAA,MACtC,CAAC;AAED,SAAG,0CAA0C,YAAY;AACvD,cAAM,SAAS,MAAM,SAAS,UAAU,QAAQ,KAAK,KAAK;AAAA,UACxD,UAAU;AAAA,UACV,OAAO;AAAA,UACP,QAAQ;AAAA,QACV,CAAC;AACD,eAAO,OAAO,MAAM,MAAM,EAAE,uBAAuB,CAAC;AACpD,cAAM,YAAY,OAAO,MAAM,CAAC;AAChC,eAAO,UAAU,UAAU,CAAC,CAAC,EAAE,KAAK,GAAG;AACvC,eAAO,UAAU,UAAU,UAAU,UAAU,SAAS,CAAC,CAAC,EAAE,KAAK,GAAG;AAAA,MACtE,CAAC;AAED,SAAG,0CAA0C,YAAY;AACvD,cAAM,SAAS,aAAa,QAAQ,WAAW,YAAY,QAAQ,UAAU,CAAC;AAC9E,cAAM,SAAS,MAAM,SAAS,UAAU,QAAQ,KAAK,YAAY;AAAA,UAC/D,UAAU;AAAA,UACV,OAAO;AAAA,UACP,QAAQ;AAAA,QACV,CAAC;AACD,eAAO,OAAO,KAAK,EAAE,aAAa,CAAC;AAAA,MACrC,CAAC;AAED,SAAG,uDAAuD,YAAY;AAGpE,cAAM,SAAS,aAAa,QAAQ,WAAW,KAAK,QAAQ,GAAG,CAAC;AAChE,cAAM,SAAS,mBAAmB,QAAQ,iBAAiB,MAAM,SAAS,KAAK,GAAG,CAAC;AACnF,cAAM,SAAS,MAAM,SAAS,UAAU,QAAQ,KAAK,KAAK;AAAA,UACxD,UAAU;AAAA,UACV,OAAO;AAAA,UACP,QAAQ;AAAA,QACV,CAAC;AACD,eAAO,OAAO,MAAM,MAAM,EAAE,uBAAuB,CAAC;AACpD,cAAM,YAAY,OAAO,MAAM,CAAC;AAChC,eAAO,UAAU,UAAU,CAAC,CAAC,EAAE,KAAK,GAAG;AACvC,eAAO,UAAU,UAAU,UAAU,UAAU,SAAS,CAAC,CAAC,EAAE,KAAK,GAAG;AAAA,MACtE,CAAC;AAAA,IACH,CAAC;AAID,aAAS,YAAY,MAAM;AACzB,SAAG,2BAA2B,YAAY;AACxC,cAAM,SAAS,aAAa,QAAQ,WAAW,IAAI,CAAC;AACpD,cAAM,SAAS,MAAM,SAAS,YAAY,QAAQ,MAAM;AAAA,UACtD,OAAO;AAAA,UACP,QAAQ;AAAA,QACV,CAAC;AACD,eAAO,OAAO,OAAO,MAAM,EAAE,uBAAuB,CAAC;AAAA,MACvD,CAAC;AAAA,IACH,CAAC;AAID,aAAS,mBAAmB,MAAM;AAChC,SAAG,gBAAgB,YAAY;AAC7B,cAAM,SAAS,aAAa,QAAQ,WAAW,IAAI,CAAC;AAEpD,cAAM,SAAS,CAAC;AAChB,yBAAiB,SAAS,SAAS,UAAU,MAAM,GAAG;AACpD,iBAAO,KAAK,KAAK;AAAA,QACnB;AACA,eAAO,OAAO,MAAM,EAAE,uBAAuB,CAAC;AAAA,MAChD,CAAC;AAED,SAAG,gBAAgB,YAAY;AAC7B,cAAM,SAAS,MAAM,SAAS,WAAW,QAAQ;AAAA,UAC/C,EAAE,UAAU,CAAC,WAAW,YAAY,GAAG,WAAW,YAAY,CAAC,EAAE;AAAA,UACjE,EAAE,eAAe,CAAC,iBAAiB,OAAO,SAAS,cAAc,YAAY,CAAC,EAAE;AAAA,QAClF,CAAC;AACD,eAAO,OAAO,gBAAgB,EAAE,KAAK,CAAC;AACtC,eAAO,OAAO,qBAAqB,EAAE,KAAK,CAAC;AAG3C,cAAM,IAAI,MAAM,SAAS,UAAU,QAAQ,YAAY;AACvD,eAAO,CAAC,EAAE,IAAI,SAAS;AAAA,MACzB,CAAC;AAAA,IACH,CAAC;AAID,aAAS,qBAAqB,MAAM;AAClC,SAAG,uEAAuE,YAAY;AACpF,cAAM,SAAS,aAAa,QAAQ,WAAW,MAAM,OAAO,CAAC;AAC7D,cAAM,SAAS,aAAa,QAAQ,WAAW,MAAM,MAAM,CAAC;AAC5D,cAAM,SAAS,mBAAmB,QAAQ,iBAAiB,MAAM,SAAS,MAAM,IAAI,CAAC;AAErF,cAAM,SAAS,MAAM,SAAS,kBAAkB,MAAM;AACtD,eAAO,OAAO,eAAe,EAAE,KAAK,CAAC;AACrC,eAAO,OAAO,oBAAoB,EAAE,KAAK,CAAC;AAG1C,cAAM,OAAO,MAAM,SAAS,cAAc,MAAM;AAChD,eAAO,IAAI,EAAE,IAAI,SAAS;AAG1B,cAAM,QAAQ,MAAM,SAAS,cAAc,MAAM;AACjD,eAAO,KAAK,EAAE,YAAY;AAG1B,cAAM,QAAQ,MAAM,SAAS,mBAAmB,MAAM;AACtD,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC;AAChC,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC;AAAA,MACxC,CAAC;AAED,SAAG,8CAA8C,YAAY;AAC3D,cAAM,SAAS,MAAM,SAAS,kBAAkB,MAAM;AACtD,eAAO,OAAO,eAAe,EAAE,KAAK,CAAC;AACrC,eAAO,OAAO,oBAAoB,EAAE,KAAK,CAAC;AAAA,MAC5C,CAAC;AAAA,IACH,CAAC;AAID,aAAS,sBAAsB,MAAM;AACnC,SAAG,qCAAqC,YAAY;AAClD,cAAM,SAAS,aAAa,QAAQ,WAAW,MAAM,OAAO,CAAC;AAC7D,cAAM,SAAS,aAAa,QAAQ,WAAW,MAAM,OAAO,CAAC;AAC7D,cAAM,SAAS,aAAa,QAAQ,WAAW,MAAM,MAAM,CAAC;AAC5D,cAAM,SAAS,mBAAmB,QAAQ,iBAAiB,MAAM,SAAS,MAAM,IAAI,CAAC;AAErF,cAAM,QAAQ,MAAM,SAAS,mBAAmB,MAAM;AACtD,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC;AAChC,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC;AACtC,eAAO,MAAM,oBAAoB,OAAO,CAAC,EAAE,KAAK,CAAC;AACjD,eAAO,MAAM,oBAAoB,MAAM,CAAC,EAAE,KAAK,CAAC;AAChD,eAAO,MAAM,0BAA0B,OAAO,CAAC,EAAE,KAAK,CAAC;AAAA,MACzD,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AACH;","names":[]}
@@ -1,20 +1,46 @@
1
- import { P as PropertyFilter, D as DetailLevel, E as Entity, a as EntitySummary, b as EntityBrief } from './portability-DdjsCB07.js';
1
+ import { P as PropertyFilter, D as DetailLevel, E as Entity, a as EntitySummary, b as EntityBrief, R as RelationshipSummary } from './portability-B-8J4nQQ.js';
2
2
 
3
3
  /**
4
- * A structured traversal specification that can be compiled to
4
+ * An entity as returned inside a TraversalResult the projected entity plus
5
+ * an optional relationship summary when includeRelationshipSummary is set.
6
+ */
7
+ type TraversalEntity = (Entity | EntitySummary | EntityBrief) & {
8
+ relationshipSummary?: RelationshipSummary;
9
+ };
10
+ /**
11
+ * A structured graph query specification that can be compiled to
5
12
  * Gremlin, Cypher, or executed via application-level BFS.
6
13
  *
7
14
  * Designed to be expressible by AI agents without raw query
8
- * language knowledge, while covering the common multi-hop
9
- * traversal patterns needed for knowledge graph exploration.
15
+ * language knowledge. Covers both vertex-only queries (property
16
+ * aggregation, distinct values, filtered lookups) and multi-hop
17
+ * relationship traversals.
18
+ *
19
+ * When steps is empty or omitted, the query operates on the
20
+ * starting entities directly — no relationship hops needed.
10
21
  */
11
22
  interface TraversalSpec {
12
- /** Starting point for the traversal. */
23
+ /** Starting point which entities to query or start traversing from. */
13
24
  start: TraversalStart;
14
- /** Ordered sequence of traversal steps. */
15
- steps: TraversalStep[];
16
- /** What to return from the traversal. */
25
+ /**
26
+ * Ordered sequence of traversal steps (relationship hops).
27
+ * When empty or omitted, the query operates on the starting entities
28
+ * directly — useful for property aggregation, distinct value queries,
29
+ * and filtered entity lookups without relationship hops.
30
+ */
31
+ steps?: TraversalStep[];
32
+ /** What to return from the query. */
17
33
  returnMode: TraversalReturnMode;
34
+ /**
35
+ * Property projection — extract and aggregate property values from
36
+ * result entities. When present, returns projected values in the
37
+ * `aggregations` array. By default, the `entities` array is suppressed
38
+ * (projection replaces full entity output). Set `includeEntities: true`
39
+ * to return both.
40
+ *
41
+ * Works with both vertex-only queries and traversals.
42
+ */
43
+ projection?: TraversalProjection;
18
44
  /**
19
45
  * Maximum number of results to return.
20
46
  * Default: 50. Max: 200.
@@ -30,6 +56,54 @@ interface TraversalSpec {
30
56
  detailLevel?: DetailLevel;
31
57
  /** Whether to deduplicate entities in the result set. Default: true. */
32
58
  dedup?: boolean;
59
+ /**
60
+ * Whether to include a relationship summary (outbound/inbound counts by type)
61
+ * on each entity in the result. Default: false.
62
+ *
63
+ * Native GraphTraversalProviders (Gremlin, Cypher) can return this in a single
64
+ * query. The fallback executor fetches all relationship data in one batch call
65
+ * and computes summaries locally. Check GraphTraversalCapabilities.supportsRelationshipSummary
66
+ * to know whether the active provider handles this natively.
67
+ */
68
+ includeRelationshipSummary?: boolean;
69
+ /**
70
+ * Whether to include provenance data on entities. Default: false.
71
+ * Only has effect when detailLevel is 'full'.
72
+ */
73
+ includeProvenance?: boolean;
74
+ }
75
+ /**
76
+ * Property projection — extract and optionally aggregate property values
77
+ * from result entities. Like SQL SELECT or Gremlin valueMap(), projection
78
+ * returns the projected values, not the full objects.
79
+ *
80
+ * By default, when projection is present the entities array is suppressed
81
+ * (only aggregations are returned). Set includeEntities to also get the
82
+ * full entity objects back.
83
+ */
84
+ interface TraversalProjection {
85
+ /**
86
+ * Property names to extract from result entities.
87
+ */
88
+ properties: string[];
89
+ /**
90
+ * Return only distinct combinations of the projected properties.
91
+ * Default: false.
92
+ */
93
+ distinct?: boolean;
94
+ /**
95
+ * Aggregation mode for the projected properties.
96
+ * - 'values': return the raw property values (default)
97
+ * - 'count': count entities per distinct value combination
98
+ */
99
+ mode?: 'count' | 'values';
100
+ /**
101
+ * When true, also return the full entities array alongside the
102
+ * projected aggregations. By default, projection suppresses entities
103
+ * to keep responses lightweight.
104
+ * Default: false.
105
+ */
106
+ includeEntities?: boolean;
33
107
  }
34
108
  /** Where the traversal begins. */
35
109
  interface TraversalStart {
@@ -99,7 +173,7 @@ type TraversalReturnMode =
99
173
  */
100
174
  interface TraversalResult {
101
175
  /** Entities in the result set, projected to the requested detail level. */
102
- entities: Array<Entity | EntitySummary | EntityBrief>;
176
+ entities: TraversalEntity[];
103
177
  /**
104
178
  * Relationships in the result set.
105
179
  * Present when returnMode is 'path' or 'all'.
@@ -110,6 +184,12 @@ interface TraversalResult {
110
184
  * Present only when returnMode is 'path'.
111
185
  */
112
186
  paths?: TraversalPath[];
187
+ /**
188
+ * Aggregated property values.
189
+ * Present when select is specified in the query.
190
+ * Each entry is a distinct value combination with an optional count.
191
+ */
192
+ aggregations?: TraversalAggregation[];
113
193
  /** Total number of results matching the traversal (before limit/offset). */
114
194
  total: number;
115
195
  /** Number of results returned in this response. */
@@ -119,6 +199,13 @@ interface TraversalResult {
119
199
  /** Query execution metadata. */
120
200
  queryMetadata: QueryMetadata;
121
201
  }
202
+ /** A single aggregation row — a distinct property value combination with optional count. */
203
+ interface TraversalAggregation {
204
+ /** Property values for this combination. */
205
+ values: Record<string, unknown>;
206
+ /** Number of entities with this value combination. Present when mode is 'count'. */
207
+ count?: number;
208
+ }
122
209
  interface TraversalRelationship {
123
210
  id: string;
124
211
  type: string;
@@ -131,7 +218,7 @@ interface TraversalPath {
131
218
  /** Number of hops in this path. */
132
219
  length: number;
133
220
  /** Ordered sequence of entities from start to end. */
134
- entities: Array<Entity | EntitySummary | EntityBrief>;
221
+ entities: TraversalEntity[];
135
222
  /** Ordered sequence of relationships connecting the entities. */
136
223
  relationships: TraversalRelationship[];
137
224
  }
@@ -174,4 +261,4 @@ interface QueryMetadata {
174
261
  truncationReason?: 'result_limit' | 'timeout' | 'cost_limit' | 'depth_limit';
175
262
  }
176
263
 
177
- export type { QueryMetadata as Q, TraversalSpec as T, TraversalResult as a, TraversalPath as b, TraversalRelationship as c, TraversalReturnMode as d, TraversalStart as e, TraversalStep as f };
264
+ export type { QueryMetadata as Q, TraversalSpec as T, TraversalResult as a, TraversalAggregation as b, TraversalPath as c, TraversalProjection as d, TraversalRelationship as e, TraversalReturnMode as f, TraversalStart as g, TraversalStep as h };
@@ -1,20 +1,46 @@
1
- import { P as PropertyFilter, D as DetailLevel, E as Entity, a as EntitySummary, b as EntityBrief } from './portability-DdjsCB07.cjs';
1
+ import { P as PropertyFilter, D as DetailLevel, E as Entity, a as EntitySummary, b as EntityBrief, R as RelationshipSummary } from './portability-B-8J4nQQ.cjs';
2
2
 
3
3
  /**
4
- * A structured traversal specification that can be compiled to
4
+ * An entity as returned inside a TraversalResult the projected entity plus
5
+ * an optional relationship summary when includeRelationshipSummary is set.
6
+ */
7
+ type TraversalEntity = (Entity | EntitySummary | EntityBrief) & {
8
+ relationshipSummary?: RelationshipSummary;
9
+ };
10
+ /**
11
+ * A structured graph query specification that can be compiled to
5
12
  * Gremlin, Cypher, or executed via application-level BFS.
6
13
  *
7
14
  * Designed to be expressible by AI agents without raw query
8
- * language knowledge, while covering the common multi-hop
9
- * traversal patterns needed for knowledge graph exploration.
15
+ * language knowledge. Covers both vertex-only queries (property
16
+ * aggregation, distinct values, filtered lookups) and multi-hop
17
+ * relationship traversals.
18
+ *
19
+ * When steps is empty or omitted, the query operates on the
20
+ * starting entities directly — no relationship hops needed.
10
21
  */
11
22
  interface TraversalSpec {
12
- /** Starting point for the traversal. */
23
+ /** Starting point which entities to query or start traversing from. */
13
24
  start: TraversalStart;
14
- /** Ordered sequence of traversal steps. */
15
- steps: TraversalStep[];
16
- /** What to return from the traversal. */
25
+ /**
26
+ * Ordered sequence of traversal steps (relationship hops).
27
+ * When empty or omitted, the query operates on the starting entities
28
+ * directly — useful for property aggregation, distinct value queries,
29
+ * and filtered entity lookups without relationship hops.
30
+ */
31
+ steps?: TraversalStep[];
32
+ /** What to return from the query. */
17
33
  returnMode: TraversalReturnMode;
34
+ /**
35
+ * Property projection — extract and aggregate property values from
36
+ * result entities. When present, returns projected values in the
37
+ * `aggregations` array. By default, the `entities` array is suppressed
38
+ * (projection replaces full entity output). Set `includeEntities: true`
39
+ * to return both.
40
+ *
41
+ * Works with both vertex-only queries and traversals.
42
+ */
43
+ projection?: TraversalProjection;
18
44
  /**
19
45
  * Maximum number of results to return.
20
46
  * Default: 50. Max: 200.
@@ -30,6 +56,54 @@ interface TraversalSpec {
30
56
  detailLevel?: DetailLevel;
31
57
  /** Whether to deduplicate entities in the result set. Default: true. */
32
58
  dedup?: boolean;
59
+ /**
60
+ * Whether to include a relationship summary (outbound/inbound counts by type)
61
+ * on each entity in the result. Default: false.
62
+ *
63
+ * Native GraphTraversalProviders (Gremlin, Cypher) can return this in a single
64
+ * query. The fallback executor fetches all relationship data in one batch call
65
+ * and computes summaries locally. Check GraphTraversalCapabilities.supportsRelationshipSummary
66
+ * to know whether the active provider handles this natively.
67
+ */
68
+ includeRelationshipSummary?: boolean;
69
+ /**
70
+ * Whether to include provenance data on entities. Default: false.
71
+ * Only has effect when detailLevel is 'full'.
72
+ */
73
+ includeProvenance?: boolean;
74
+ }
75
+ /**
76
+ * Property projection — extract and optionally aggregate property values
77
+ * from result entities. Like SQL SELECT or Gremlin valueMap(), projection
78
+ * returns the projected values, not the full objects.
79
+ *
80
+ * By default, when projection is present the entities array is suppressed
81
+ * (only aggregations are returned). Set includeEntities to also get the
82
+ * full entity objects back.
83
+ */
84
+ interface TraversalProjection {
85
+ /**
86
+ * Property names to extract from result entities.
87
+ */
88
+ properties: string[];
89
+ /**
90
+ * Return only distinct combinations of the projected properties.
91
+ * Default: false.
92
+ */
93
+ distinct?: boolean;
94
+ /**
95
+ * Aggregation mode for the projected properties.
96
+ * - 'values': return the raw property values (default)
97
+ * - 'count': count entities per distinct value combination
98
+ */
99
+ mode?: 'count' | 'values';
100
+ /**
101
+ * When true, also return the full entities array alongside the
102
+ * projected aggregations. By default, projection suppresses entities
103
+ * to keep responses lightweight.
104
+ * Default: false.
105
+ */
106
+ includeEntities?: boolean;
33
107
  }
34
108
  /** Where the traversal begins. */
35
109
  interface TraversalStart {
@@ -99,7 +173,7 @@ type TraversalReturnMode =
99
173
  */
100
174
  interface TraversalResult {
101
175
  /** Entities in the result set, projected to the requested detail level. */
102
- entities: Array<Entity | EntitySummary | EntityBrief>;
176
+ entities: TraversalEntity[];
103
177
  /**
104
178
  * Relationships in the result set.
105
179
  * Present when returnMode is 'path' or 'all'.
@@ -110,6 +184,12 @@ interface TraversalResult {
110
184
  * Present only when returnMode is 'path'.
111
185
  */
112
186
  paths?: TraversalPath[];
187
+ /**
188
+ * Aggregated property values.
189
+ * Present when select is specified in the query.
190
+ * Each entry is a distinct value combination with an optional count.
191
+ */
192
+ aggregations?: TraversalAggregation[];
113
193
  /** Total number of results matching the traversal (before limit/offset). */
114
194
  total: number;
115
195
  /** Number of results returned in this response. */
@@ -119,6 +199,13 @@ interface TraversalResult {
119
199
  /** Query execution metadata. */
120
200
  queryMetadata: QueryMetadata;
121
201
  }
202
+ /** A single aggregation row — a distinct property value combination with optional count. */
203
+ interface TraversalAggregation {
204
+ /** Property values for this combination. */
205
+ values: Record<string, unknown>;
206
+ /** Number of entities with this value combination. Present when mode is 'count'. */
207
+ count?: number;
208
+ }
122
209
  interface TraversalRelationship {
123
210
  id: string;
124
211
  type: string;
@@ -131,7 +218,7 @@ interface TraversalPath {
131
218
  /** Number of hops in this path. */
132
219
  length: number;
133
220
  /** Ordered sequence of entities from start to end. */
134
- entities: Array<Entity | EntitySummary | EntityBrief>;
221
+ entities: TraversalEntity[];
135
222
  /** Ordered sequence of relationships connecting the entities. */
136
223
  relationships: TraversalRelationship[];
137
224
  }
@@ -174,4 +261,4 @@ interface QueryMetadata {
174
261
  truncationReason?: 'result_limit' | 'timeout' | 'cost_limit' | 'depth_limit';
175
262
  }
176
263
 
177
- export type { QueryMetadata as Q, TraversalSpec as T, TraversalResult as a, TraversalPath as b, TraversalRelationship as c, TraversalReturnMode as d, TraversalStart as e, TraversalStep as f };
264
+ export type { QueryMetadata as Q, TraversalSpec as T, TraversalResult as a, TraversalAggregation as b, TraversalPath as c, TraversalProjection as d, TraversalRelationship as e, TraversalReturnMode as f, TraversalStart as g, TraversalStep as h };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/index.ts"],"sourcesContent":["// Type re-exports — @utaba/deep-memory/types\n\nexport type {\n ProvenanceContext,\n Provenance,\n} from './provenance.js';\n\nexport type {\n PropertyType,\n PropertySchema,\n EntityTypeDefinition,\n RelationshipTypeDefinition,\n MemoryVocabulary,\n GovernanceMode,\n GovernanceConfig,\n VocabularyProposal,\n VocabularyProposalResult,\n VocabularyChangeRecord,\n ResolvedVocabulary,\n EntityTypeInput,\n RelationshipTypeInput,\n VocabularyInput,\n} from './vocabulary.js';\n\nexport type {\n DetailLevel,\n Entity,\n EntitySummary,\n EntityBrief,\n CreateEntityInput,\n UpdateEntityInput,\n StoredEntity,\n StoredEntityUpdate,\n GetEntityOptions,\n GetEntitiesOptions,\n} from './entities.js';\n\nexport type {\n RelationshipDirection,\n Relationship,\n EnrichedRelationship,\n CreateRelationshipInput,\n StoredRelationship,\n RelationshipQueryOptions,\n RelationshipSummary,\n} from './relationships.js';\n\nexport type {\n RepositoryConfig,\n RepositoryMetadata,\n RepositoryUpdate,\n RepositorySummary,\n RepositoryStats,\n StoredRepository,\n StoredRepositorySummary,\n RepositoryFilter,\n StorageRepositoryConfig,\n} from './repositories.js';\n\nexport type {\n PaginationOptions,\n FindEntitiesQuery,\n ExploreOptions,\n PathOptions,\n ConceptSearchOptions,\n TimelineOptions,\n StorageFindQuery,\n StorageExploreOptions,\n StoragePathOptions,\n StorageTimelineOptions,\n SearchOptions,\n PropertyFilter,\n ProvenanceFilter,\n} from './queries.js';\n\nexport type {\n PaginatedResult,\n NeighbourhoodCentre,\n NeighbourhoodGroup,\n NeighbourhoodLayer,\n Neighbourhood,\n Path,\n PathResult,\n ScoredEntity,\n TimelineEntityRef,\n TimelineRelationshipDetail,\n TimelineEvent,\n TimelineResult,\n GraphResult,\n EntityMap,\n StorageNeighbourhoodGroup,\n StorageNeighbourhoodLayer,\n StorageNeighbourhood,\n StoragePath,\n StoragePathResult,\n StorageTimelineEvent,\n StorageTimelineResult,\n SearchHit,\n BulkImportResult,\n ReembedResult,\n} from './results.js';\n\nexport type {\n DeepMemoryEventType,\n EventPayload,\n DeepMemoryEvent,\n EventHandler,\n Unsubscribe,\n HookResult,\n} from './events.js';\n\nexport type {\n TraversalSpec,\n TraversalStart,\n TraversalStep,\n TraversalReturnMode,\n TraversalResult,\n TraversalRelationship,\n TraversalPath,\n QueryMetadata,\n} from './traversal.js';\n\nexport type {\n ExportManifest,\n ExportLegalMetadata,\n ExportPipelineMetadata,\n ExportOptions,\n ExportArchive,\n ExportChunk,\n ExportStreamItem,\n ImportOptions,\n ImportChunk,\n ImportStreamHeader,\n ImportWarning,\n ImportResult,\n} from './portability.js';\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../../src/types/index.ts"],"sourcesContent":["// Type re-exports — @utaba/deep-memory/types\n\nexport type {\n ProvenanceContext,\n Provenance,\n} from './provenance.js';\n\nexport type {\n PropertyType,\n PropertySchema,\n EntityTypeDefinition,\n RelationshipTypeDefinition,\n MemoryVocabulary,\n GovernanceMode,\n GovernanceConfig,\n VocabularyProposal,\n VocabularyProposalResult,\n VocabularyChangeRecord,\n ResolvedVocabulary,\n EntityTypeInput,\n RelationshipTypeInput,\n VocabularyInput,\n} from './vocabulary.js';\n\nexport type {\n DetailLevel,\n Entity,\n EntitySummary,\n EntityBrief,\n CreateEntityInput,\n UpdateEntityInput,\n StoredEntity,\n StoredEntityUpdate,\n GetEntityOptions,\n GetEntitiesOptions,\n} from './entities.js';\n\nexport type {\n RelationshipDirection,\n Relationship,\n EnrichedRelationship,\n CreateRelationshipInput,\n StoredRelationship,\n RelationshipQueryOptions,\n RelationshipSummary,\n} from './relationships.js';\n\nexport type {\n RepositoryConfig,\n RepositoryMetadata,\n RepositoryUpdate,\n RepositorySummary,\n RepositoryStats,\n StoredRepository,\n StoredRepositorySummary,\n RepositoryFilter,\n StorageRepositoryConfig,\n} from './repositories.js';\n\nexport type {\n PaginationOptions,\n FindEntitiesQuery,\n ExploreOptions,\n PathOptions,\n ConceptSearchOptions,\n TimelineOptions,\n StorageFindQuery,\n StorageExploreOptions,\n StoragePathOptions,\n StorageTimelineOptions,\n SearchOptions,\n PropertyFilter,\n ProvenanceFilter,\n} from './queries.js';\n\nexport type {\n PaginatedResult,\n NeighborhoodCenter,\n NeighborhoodGroup,\n NeighborhoodLayer,\n Neighborhood,\n Path,\n PathResult,\n ScoredEntity,\n TimelineEntityRef,\n TimelineRelationshipDetail,\n TimelineEvent,\n TimelineResult,\n GraphResult,\n EntityMap,\n StorageNeighborhoodGroup,\n StorageNeighborhoodLayer,\n StorageNeighborhood,\n StoragePath,\n StoragePathResult,\n StorageTimelineEvent,\n StorageTimelineResult,\n SearchHit,\n BulkImportResult,\n ReembedResult,\n} from './results.js';\n\nexport type {\n DeepMemoryEventType,\n EventPayload,\n DeepMemoryEvent,\n EventHandler,\n Unsubscribe,\n HookResult,\n} from './events.js';\n\nexport type {\n TraversalSpec,\n TraversalStart,\n TraversalStep,\n TraversalProjection,\n TraversalReturnMode,\n TraversalResult,\n TraversalAggregation,\n TraversalRelationship,\n TraversalPath,\n QueryMetadata,\n} from './traversal.js';\n\nexport type {\n ExportManifest,\n ExportLegalMetadata,\n ExportPipelineMetadata,\n ExportOptions,\n ExportArchive,\n ExportChunk,\n ExportStreamItem,\n ImportOptions,\n ImportChunk,\n BulkImportOptions,\n DeleteProgressCallback,\n ImportStreamHeader,\n ImportWarning,\n ImportResult,\n} from './portability.js';\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -1,9 +1,9 @@
1
- import { z as ProvenanceContext, C as CreateEntityInput, E as Entity, U as UpdateEntityInput, v as CreateRelationshipInput, J as Relationship, V as VocabularyChangeRecord } from '../portability-DdjsCB07.cjs';
2
- export { B as BulkImportResult, W as ConceptSearchOptions, D as DetailLevel, a8 as EnrichedRelationship, b as EntityBrief, a9 as EntityMap, a as EntitySummary, w as EntityTypeDefinition, aa as EntityTypeInput, N as ExploreOptions, a1 as ExportArchive, t as ExportChunk, ab as ExportLegalMetadata, ac as ExportManifest, a0 as ExportOptions, ad as ExportPipelineMetadata, a4 as ExportStreamItem, F as FindEntitiesQuery, ae as GetEntitiesOptions, af as GetEntityOptions, G as GovernanceConfig, ag as GovernanceMode, L as GraphResult, I as ImportChunk, a2 as ImportOptions, a3 as ImportResult, a5 as ImportStreamHeader, ah as ImportWarning, M as MemoryVocabulary, O as Neighbourhood, ai as NeighbourhoodCentre, aj as NeighbourhoodGroup, ak as NeighbourhoodLayer, d as PaginatedResult, h as PaginationOptions, al as Path, Q as PathOptions, T as PathResult, P as PropertyFilter, am as PropertySchema, an as PropertyType, A as Provenance, ao as ProvenanceFilter, H as ReembedResult, ap as RelationshipDirection, m as RelationshipQueryOptions, K as RelationshipSummary, aq as RelationshipTypeDefinition, ar as RelationshipTypeInput, _ as RepositoryConfig, R as RepositoryFilter, as as RepositoryMetadata, g as RepositoryStats, $ as RepositorySummary, f as RepositoryUpdate, u as ResolvedVocabulary, X as ScoredEntity, a7 as SearchHit, a6 as SearchOptions, n as StorageExploreOptions, k as StorageFindQuery, o as StorageNeighbourhood, at as StorageNeighbourhoodGroup, au as StorageNeighbourhoodLayer, av as StoragePath, p as StoragePathOptions, q as StoragePathResult, S as StorageRepositoryConfig, aw as StorageTimelineEvent, r as StorageTimelineOptions, s as StorageTimelineResult, i as StoredEntity, j as StoredEntityUpdate, l as StoredRelationship, c as StoredRepository, e as StoredRepositorySummary, ax as TimelineEntityRef, ay as TimelineEvent, Y as TimelineOptions, az as TimelineRelationshipDetail, Z as TimelineResult, aA as VocabularyInput, x as VocabularyProposal, y as VocabularyProposalResult } from '../portability-DdjsCB07.cjs';
3
- export { Q as QueryMetadata, b as TraversalPath, c as TraversalRelationship, a as TraversalResult, d as TraversalReturnMode, T as TraversalSpec, e as TraversalStart, f as TraversalStep } from '../traversal-BB_yERbf.cjs';
1
+ import { H as ProvenanceContext, C as CreateEntityInput, E as Entity, U as UpdateEntityInput, y as CreateRelationshipInput, N as Relationship, V as VocabularyChangeRecord } from '../portability-B-8J4nQQ.cjs';
2
+ export { B as BulkImportOptions, w as BulkImportResult, Y as ConceptSearchOptions, h as DeleteProgressCallback, D as DetailLevel, aa as EnrichedRelationship, b as EntityBrief, ab as EntityMap, a as EntitySummary, z as EntityTypeDefinition, ac as EntityTypeInput, Q as ExploreOptions, a3 as ExportArchive, v as ExportChunk, ad as ExportLegalMetadata, ae as ExportManifest, a2 as ExportOptions, af as ExportPipelineMetadata, a6 as ExportStreamItem, K as FindEntitiesQuery, ag as GetEntitiesOptions, ah as GetEntityOptions, G as GovernanceConfig, ai as GovernanceMode, O as GraphResult, I as ImportChunk, a4 as ImportOptions, a5 as ImportResult, a7 as ImportStreamHeader, aj as ImportWarning, M as MemoryVocabulary, T as Neighborhood, ak as NeighborhoodCenter, al as NeighborhoodGroup, am as NeighborhoodLayer, e as PaginatedResult, j as PaginationOptions, an as Path, W as PathOptions, X as PathResult, P as PropertyFilter, ao as PropertySchema, ap as PropertyType, J as Provenance, aq as ProvenanceFilter, L as ReembedResult, ar as RelationshipDirection, o as RelationshipQueryOptions, R as RelationshipSummary, as as RelationshipTypeDefinition, at as RelationshipTypeInput, a0 as RepositoryConfig, d as RepositoryFilter, au as RepositoryMetadata, i as RepositoryStats, a1 as RepositorySummary, g as RepositoryUpdate, x as ResolvedVocabulary, Z as ScoredEntity, a9 as SearchHit, a8 as SearchOptions, p as StorageExploreOptions, m as StorageFindQuery, q as StorageNeighborhood, av as StorageNeighborhoodGroup, aw as StorageNeighborhoodLayer, ax as StoragePath, r as StoragePathOptions, s as StoragePathResult, S as StorageRepositoryConfig, ay as StorageTimelineEvent, t as StorageTimelineOptions, u as StorageTimelineResult, k as StoredEntity, l as StoredEntityUpdate, n as StoredRelationship, c as StoredRepository, f as StoredRepositorySummary, az as TimelineEntityRef, aA as TimelineEvent, _ as TimelineOptions, aB as TimelineRelationshipDetail, $ as TimelineResult, aC as VocabularyInput, A as VocabularyProposal, F as VocabularyProposalResult } from '../portability-B-8J4nQQ.cjs';
3
+ export { Q as QueryMetadata, b as TraversalAggregation, c as TraversalPath, d as TraversalProjection, e as TraversalRelationship, a as TraversalResult, f as TraversalReturnMode, T as TraversalSpec, g as TraversalStart, h as TraversalStep } from '../traversal-Llalk03r.cjs';
4
4
 
5
5
  /** All event types emitted by the Deep Memory engine */
6
- type DeepMemoryEventType = 'repository:created' | 'repository:opened' | 'repository:updated' | 'repository:deleted' | 'entity:creating' | 'entity:created' | 'entity:updating' | 'entity:updated' | 'entity:deleting' | 'entity:deleted' | 'relationship:creating' | 'relationship:created' | 'relationship:removing' | 'relationship:removed' | 'vocabulary:proposal' | 'vocabulary:approved' | 'vocabulary:rejected' | 'vocabulary:pending' | 'vocabulary:changed' | 'validation:failed' | 'search:executed' | 'reembed:started' | 'reembed:progress' | 'reembed:completed' | 'reembed:failed' | 'export:started' | 'export:progress' | 'export:completed' | 'import:started' | 'import:progress' | 'import:completed' | 'import:failed';
6
+ type DeepMemoryEventType = 'repository:created' | 'repository:opened' | 'repository:updated' | 'repository:deleted' | 'entity:creating' | 'entity:created' | 'entity:updating' | 'entity:updated' | 'entity:deleting' | 'entity:deleted' | 'relationship:creating' | 'relationship:created' | 'relationship:removing' | 'relationship:removed' | 'vocabulary:proposal' | 'vocabulary:approved' | 'vocabulary:rejected' | 'vocabulary:pending' | 'vocabulary:changed' | 'validation:failed' | 'search:executed' | 'reembed:started' | 'reembed:progress' | 'reembed:completed' | 'reembed:failed' | 'export:started' | 'export:progress' | 'export:completed' | 'import:started' | 'import:progress' | 'import:completed' | 'import:failed' | 'delete:started' | 'delete:progress' | 'delete:completed';
7
7
  /** Type-safe event payload mapping */
8
8
  type EventPayload<T extends DeepMemoryEventType> = T extends 'repository:created' ? {
9
9
  repositoryId: string;
@@ -76,10 +76,16 @@ type EventPayload<T extends DeepMemoryEventType> = T extends 'repository:created
76
76
  error: string;
77
77
  } : T extends 'export:started' ? {
78
78
  repositoryId: string;
79
+ totalEntities: number;
80
+ totalRelationships: number;
79
81
  } : T extends 'export:progress' ? {
80
82
  repositoryId: string;
81
83
  entitiesExported: number;
84
+ relationshipsExported: number;
82
85
  totalEntities: number;
86
+ totalRelationships: number;
87
+ chunksCompleted: number;
88
+ totalChunks: number;
83
89
  } : T extends 'export:completed' ? {
84
90
  repositoryId: string;
85
91
  entityCount: number;
@@ -89,7 +95,11 @@ type EventPayload<T extends DeepMemoryEventType> = T extends 'repository:created
89
95
  } : T extends 'import:progress' ? {
90
96
  repositoryId: string;
91
97
  entitiesImported: number;
98
+ relationshipsImported: number;
92
99
  totalEntities: number;
100
+ totalRelationships: number;
101
+ chunksCompleted: number;
102
+ totalChunks: number;
93
103
  } : T extends 'import:completed' ? {
94
104
  repositoryId: string;
95
105
  entitiesImported: number;
@@ -97,6 +107,20 @@ type EventPayload<T extends DeepMemoryEventType> = T extends 'repository:created
97
107
  } : T extends 'import:failed' ? {
98
108
  repositoryId: string;
99
109
  error: string;
110
+ } : T extends 'delete:started' ? {
111
+ repositoryId: string;
112
+ totalEntities: number;
113
+ totalRelationships: number;
114
+ } : T extends 'delete:progress' ? {
115
+ repositoryId: string;
116
+ entitiesDeleted: number;
117
+ relationshipsDeleted: number;
118
+ totalEntities: number;
119
+ totalRelationships: number;
120
+ } : T extends 'delete:completed' ? {
121
+ repositoryId: string;
122
+ entitiesDeleted: number;
123
+ relationshipsDeleted: number;
100
124
  } : Record<string, unknown>;
101
125
  /** A typed event emitted by the engine */
102
126
  interface DeepMemoryEvent<T extends DeepMemoryEventType> {
@@ -1,9 +1,9 @@
1
- import { z as ProvenanceContext, C as CreateEntityInput, E as Entity, U as UpdateEntityInput, v as CreateRelationshipInput, J as Relationship, V as VocabularyChangeRecord } from '../portability-DdjsCB07.js';
2
- export { B as BulkImportResult, W as ConceptSearchOptions, D as DetailLevel, a8 as EnrichedRelationship, b as EntityBrief, a9 as EntityMap, a as EntitySummary, w as EntityTypeDefinition, aa as EntityTypeInput, N as ExploreOptions, a1 as ExportArchive, t as ExportChunk, ab as ExportLegalMetadata, ac as ExportManifest, a0 as ExportOptions, ad as ExportPipelineMetadata, a4 as ExportStreamItem, F as FindEntitiesQuery, ae as GetEntitiesOptions, af as GetEntityOptions, G as GovernanceConfig, ag as GovernanceMode, L as GraphResult, I as ImportChunk, a2 as ImportOptions, a3 as ImportResult, a5 as ImportStreamHeader, ah as ImportWarning, M as MemoryVocabulary, O as Neighbourhood, ai as NeighbourhoodCentre, aj as NeighbourhoodGroup, ak as NeighbourhoodLayer, d as PaginatedResult, h as PaginationOptions, al as Path, Q as PathOptions, T as PathResult, P as PropertyFilter, am as PropertySchema, an as PropertyType, A as Provenance, ao as ProvenanceFilter, H as ReembedResult, ap as RelationshipDirection, m as RelationshipQueryOptions, K as RelationshipSummary, aq as RelationshipTypeDefinition, ar as RelationshipTypeInput, _ as RepositoryConfig, R as RepositoryFilter, as as RepositoryMetadata, g as RepositoryStats, $ as RepositorySummary, f as RepositoryUpdate, u as ResolvedVocabulary, X as ScoredEntity, a7 as SearchHit, a6 as SearchOptions, n as StorageExploreOptions, k as StorageFindQuery, o as StorageNeighbourhood, at as StorageNeighbourhoodGroup, au as StorageNeighbourhoodLayer, av as StoragePath, p as StoragePathOptions, q as StoragePathResult, S as StorageRepositoryConfig, aw as StorageTimelineEvent, r as StorageTimelineOptions, s as StorageTimelineResult, i as StoredEntity, j as StoredEntityUpdate, l as StoredRelationship, c as StoredRepository, e as StoredRepositorySummary, ax as TimelineEntityRef, ay as TimelineEvent, Y as TimelineOptions, az as TimelineRelationshipDetail, Z as TimelineResult, aA as VocabularyInput, x as VocabularyProposal, y as VocabularyProposalResult } from '../portability-DdjsCB07.js';
3
- export { Q as QueryMetadata, b as TraversalPath, c as TraversalRelationship, a as TraversalResult, d as TraversalReturnMode, T as TraversalSpec, e as TraversalStart, f as TraversalStep } from '../traversal-9JdiqjZ9.js';
1
+ import { H as ProvenanceContext, C as CreateEntityInput, E as Entity, U as UpdateEntityInput, y as CreateRelationshipInput, N as Relationship, V as VocabularyChangeRecord } from '../portability-B-8J4nQQ.js';
2
+ export { B as BulkImportOptions, w as BulkImportResult, Y as ConceptSearchOptions, h as DeleteProgressCallback, D as DetailLevel, aa as EnrichedRelationship, b as EntityBrief, ab as EntityMap, a as EntitySummary, z as EntityTypeDefinition, ac as EntityTypeInput, Q as ExploreOptions, a3 as ExportArchive, v as ExportChunk, ad as ExportLegalMetadata, ae as ExportManifest, a2 as ExportOptions, af as ExportPipelineMetadata, a6 as ExportStreamItem, K as FindEntitiesQuery, ag as GetEntitiesOptions, ah as GetEntityOptions, G as GovernanceConfig, ai as GovernanceMode, O as GraphResult, I as ImportChunk, a4 as ImportOptions, a5 as ImportResult, a7 as ImportStreamHeader, aj as ImportWarning, M as MemoryVocabulary, T as Neighborhood, ak as NeighborhoodCenter, al as NeighborhoodGroup, am as NeighborhoodLayer, e as PaginatedResult, j as PaginationOptions, an as Path, W as PathOptions, X as PathResult, P as PropertyFilter, ao as PropertySchema, ap as PropertyType, J as Provenance, aq as ProvenanceFilter, L as ReembedResult, ar as RelationshipDirection, o as RelationshipQueryOptions, R as RelationshipSummary, as as RelationshipTypeDefinition, at as RelationshipTypeInput, a0 as RepositoryConfig, d as RepositoryFilter, au as RepositoryMetadata, i as RepositoryStats, a1 as RepositorySummary, g as RepositoryUpdate, x as ResolvedVocabulary, Z as ScoredEntity, a9 as SearchHit, a8 as SearchOptions, p as StorageExploreOptions, m as StorageFindQuery, q as StorageNeighborhood, av as StorageNeighborhoodGroup, aw as StorageNeighborhoodLayer, ax as StoragePath, r as StoragePathOptions, s as StoragePathResult, S as StorageRepositoryConfig, ay as StorageTimelineEvent, t as StorageTimelineOptions, u as StorageTimelineResult, k as StoredEntity, l as StoredEntityUpdate, n as StoredRelationship, c as StoredRepository, f as StoredRepositorySummary, az as TimelineEntityRef, aA as TimelineEvent, _ as TimelineOptions, aB as TimelineRelationshipDetail, $ as TimelineResult, aC as VocabularyInput, A as VocabularyProposal, F as VocabularyProposalResult } from '../portability-B-8J4nQQ.js';
3
+ export { Q as QueryMetadata, b as TraversalAggregation, c as TraversalPath, d as TraversalProjection, e as TraversalRelationship, a as TraversalResult, f as TraversalReturnMode, T as TraversalSpec, g as TraversalStart, h as TraversalStep } from '../traversal-BdmDLMxV.js';
4
4
 
5
5
  /** All event types emitted by the Deep Memory engine */
6
- type DeepMemoryEventType = 'repository:created' | 'repository:opened' | 'repository:updated' | 'repository:deleted' | 'entity:creating' | 'entity:created' | 'entity:updating' | 'entity:updated' | 'entity:deleting' | 'entity:deleted' | 'relationship:creating' | 'relationship:created' | 'relationship:removing' | 'relationship:removed' | 'vocabulary:proposal' | 'vocabulary:approved' | 'vocabulary:rejected' | 'vocabulary:pending' | 'vocabulary:changed' | 'validation:failed' | 'search:executed' | 'reembed:started' | 'reembed:progress' | 'reembed:completed' | 'reembed:failed' | 'export:started' | 'export:progress' | 'export:completed' | 'import:started' | 'import:progress' | 'import:completed' | 'import:failed';
6
+ type DeepMemoryEventType = 'repository:created' | 'repository:opened' | 'repository:updated' | 'repository:deleted' | 'entity:creating' | 'entity:created' | 'entity:updating' | 'entity:updated' | 'entity:deleting' | 'entity:deleted' | 'relationship:creating' | 'relationship:created' | 'relationship:removing' | 'relationship:removed' | 'vocabulary:proposal' | 'vocabulary:approved' | 'vocabulary:rejected' | 'vocabulary:pending' | 'vocabulary:changed' | 'validation:failed' | 'search:executed' | 'reembed:started' | 'reembed:progress' | 'reembed:completed' | 'reembed:failed' | 'export:started' | 'export:progress' | 'export:completed' | 'import:started' | 'import:progress' | 'import:completed' | 'import:failed' | 'delete:started' | 'delete:progress' | 'delete:completed';
7
7
  /** Type-safe event payload mapping */
8
8
  type EventPayload<T extends DeepMemoryEventType> = T extends 'repository:created' ? {
9
9
  repositoryId: string;
@@ -76,10 +76,16 @@ type EventPayload<T extends DeepMemoryEventType> = T extends 'repository:created
76
76
  error: string;
77
77
  } : T extends 'export:started' ? {
78
78
  repositoryId: string;
79
+ totalEntities: number;
80
+ totalRelationships: number;
79
81
  } : T extends 'export:progress' ? {
80
82
  repositoryId: string;
81
83
  entitiesExported: number;
84
+ relationshipsExported: number;
82
85
  totalEntities: number;
86
+ totalRelationships: number;
87
+ chunksCompleted: number;
88
+ totalChunks: number;
83
89
  } : T extends 'export:completed' ? {
84
90
  repositoryId: string;
85
91
  entityCount: number;
@@ -89,7 +95,11 @@ type EventPayload<T extends DeepMemoryEventType> = T extends 'repository:created
89
95
  } : T extends 'import:progress' ? {
90
96
  repositoryId: string;
91
97
  entitiesImported: number;
98
+ relationshipsImported: number;
92
99
  totalEntities: number;
100
+ totalRelationships: number;
101
+ chunksCompleted: number;
102
+ totalChunks: number;
93
103
  } : T extends 'import:completed' ? {
94
104
  repositoryId: string;
95
105
  entitiesImported: number;
@@ -97,6 +107,20 @@ type EventPayload<T extends DeepMemoryEventType> = T extends 'repository:created
97
107
  } : T extends 'import:failed' ? {
98
108
  repositoryId: string;
99
109
  error: string;
110
+ } : T extends 'delete:started' ? {
111
+ repositoryId: string;
112
+ totalEntities: number;
113
+ totalRelationships: number;
114
+ } : T extends 'delete:progress' ? {
115
+ repositoryId: string;
116
+ entitiesDeleted: number;
117
+ relationshipsDeleted: number;
118
+ totalEntities: number;
119
+ totalRelationships: number;
120
+ } : T extends 'delete:completed' ? {
121
+ repositoryId: string;
122
+ entitiesDeleted: number;
123
+ relationshipsDeleted: number;
100
124
  } : Record<string, unknown>;
101
125
  /** A typed event emitted by the engine */
102
126
  interface DeepMemoryEvent<T extends DeepMemoryEventType> {