@soulcraft/brainy 6.2.0 → 6.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/augmentations/KnowledgeAugmentation.d.ts +40 -0
- package/dist/augmentations/KnowledgeAugmentation.js +251 -0
- package/dist/brainy.d.ts +17 -13
- package/dist/brainy.js +70 -5
- package/dist/importManager.d.ts +78 -0
- package/dist/importManager.js +267 -0
- package/dist/query/typeInference.d.ts +158 -0
- package/dist/query/typeInference.js +760 -0
- package/dist/storage/adapters/typeAwareStorageAdapter.d.ts +252 -0
- package/dist/storage/adapters/typeAwareStorageAdapter.js +814 -0
- package/dist/types/brainyDataInterface.d.ts +52 -0
- package/dist/types/brainyDataInterface.js +10 -0
- package/dist/utils/metadataIndex.d.ts +17 -0
- package/dist/utils/metadataIndex.js +63 -0
- package/dist/vfs/ConceptSystem.d.ts +203 -0
- package/dist/vfs/ConceptSystem.js +545 -0
- package/dist/vfs/EntityManager.d.ts +75 -0
- package/dist/vfs/EntityManager.js +216 -0
- package/dist/vfs/EventRecorder.d.ts +84 -0
- package/dist/vfs/EventRecorder.js +269 -0
- package/dist/vfs/GitBridge.d.ts +167 -0
- package/dist/vfs/GitBridge.js +537 -0
- package/dist/vfs/KnowledgeLayer.d.ts +35 -0
- package/dist/vfs/KnowledgeLayer.js +443 -0
- package/dist/vfs/PersistentEntitySystem.d.ts +165 -0
- package/dist/vfs/PersistentEntitySystem.js +503 -0
- package/dist/vfs/SemanticVersioning.d.ts +105 -0
- package/dist/vfs/SemanticVersioning.js +309 -0
- package/package.json +1 -1
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge Layer Augmentation for VFS
|
|
3
|
+
*
|
|
4
|
+
* Adds intelligent features to VFS without modifying core functionality:
|
|
5
|
+
* - Event recording for all operations
|
|
6
|
+
* - Semantic versioning based on content changes
|
|
7
|
+
* - Entity and concept extraction
|
|
8
|
+
* - Git bridge for import/export
|
|
9
|
+
*
|
|
10
|
+
* This is a TRUE augmentation - VFS works perfectly without it
|
|
11
|
+
*/
|
|
12
|
+
import { Brainy } from '../brainy.js';
|
|
13
|
+
import { BaseAugmentation } from './brainyAugmentation.js';
|
|
14
|
+
export declare class KnowledgeAugmentation extends BaseAugmentation {
|
|
15
|
+
name: string;
|
|
16
|
+
timing: 'after';
|
|
17
|
+
metadata: 'none';
|
|
18
|
+
operations: any;
|
|
19
|
+
priority: number;
|
|
20
|
+
constructor(config?: any);
|
|
21
|
+
execute<T = any>(operation: string, params: any, next: () => Promise<T>): Promise<T>;
|
|
22
|
+
private eventRecorder?;
|
|
23
|
+
private semanticVersioning?;
|
|
24
|
+
private entitySystem?;
|
|
25
|
+
private conceptSystem?;
|
|
26
|
+
private gitBridge?;
|
|
27
|
+
private originalMethods;
|
|
28
|
+
initialize(context: any): Promise<void>;
|
|
29
|
+
augment(brain: Brainy): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Wrap a VFS method to add Knowledge Layer functionality
|
|
32
|
+
*/
|
|
33
|
+
private wrapMethod;
|
|
34
|
+
/**
|
|
35
|
+
* Add Knowledge Layer methods to VFS
|
|
36
|
+
*/
|
|
37
|
+
private addKnowledgeMethods;
|
|
38
|
+
private isSemanticChange;
|
|
39
|
+
cleanup(brain: Brainy): Promise<void>;
|
|
40
|
+
}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge Layer Augmentation for VFS
|
|
3
|
+
*
|
|
4
|
+
* Adds intelligent features to VFS without modifying core functionality:
|
|
5
|
+
* - Event recording for all operations
|
|
6
|
+
* - Semantic versioning based on content changes
|
|
7
|
+
* - Entity and concept extraction
|
|
8
|
+
* - Git bridge for import/export
|
|
9
|
+
*
|
|
10
|
+
* This is a TRUE augmentation - VFS works perfectly without it
|
|
11
|
+
*/
|
|
12
|
+
import { BaseAugmentation } from './brainyAugmentation.js';
|
|
13
|
+
import { EventRecorder } from '../vfs/EventRecorder.js';
|
|
14
|
+
import { SemanticVersioning } from '../vfs/SemanticVersioning.js';
|
|
15
|
+
import { PersistentEntitySystem } from '../vfs/PersistentEntitySystem.js';
|
|
16
|
+
import { ConceptSystem } from '../vfs/ConceptSystem.js';
|
|
17
|
+
import { GitBridge } from '../vfs/GitBridge.js';
|
|
18
|
+
export class KnowledgeAugmentation extends BaseAugmentation {
|
|
19
|
+
constructor(config = {}) {
|
|
20
|
+
super(config);
|
|
21
|
+
this.name = 'knowledge';
|
|
22
|
+
this.timing = 'after'; // Process after VFS operations
|
|
23
|
+
this.metadata = 'none'; // No metadata access needed
|
|
24
|
+
this.operations = []; // VFS-specific augmentation, no operation interception
|
|
25
|
+
this.priority = 100; // Run last
|
|
26
|
+
this.originalMethods = new Map();
|
|
27
|
+
}
|
|
28
|
+
async execute(operation, params, next) {
|
|
29
|
+
// Pass through - this augmentation works at VFS level, not operation level
|
|
30
|
+
return await next();
|
|
31
|
+
}
|
|
32
|
+
async initialize(context) {
|
|
33
|
+
await this.augment(context.brain);
|
|
34
|
+
}
|
|
35
|
+
async augment(brain) {
|
|
36
|
+
// Only augment if VFS exists
|
|
37
|
+
const vfs = brain.vfs?.();
|
|
38
|
+
if (!vfs) {
|
|
39
|
+
console.warn('KnowledgeAugmentation: VFS not found, skipping');
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
// Initialize Knowledge Layer components
|
|
43
|
+
this.eventRecorder = new EventRecorder(brain);
|
|
44
|
+
this.semanticVersioning = new SemanticVersioning(brain);
|
|
45
|
+
this.entitySystem = new PersistentEntitySystem(brain);
|
|
46
|
+
this.conceptSystem = new ConceptSystem(brain);
|
|
47
|
+
this.gitBridge = new GitBridge(vfs, brain);
|
|
48
|
+
// Wrap VFS methods to add intelligence WITHOUT slowing them down
|
|
49
|
+
this.wrapMethod(vfs, 'writeFile', async (original, path, data, options) => {
|
|
50
|
+
// Call original first (stays fast)
|
|
51
|
+
const result = await original.call(vfs, path, data, options);
|
|
52
|
+
// Knowledge processing in background (non-blocking)
|
|
53
|
+
setImmediate(async () => {
|
|
54
|
+
try {
|
|
55
|
+
// Record event
|
|
56
|
+
if (this.eventRecorder) {
|
|
57
|
+
await this.eventRecorder.recordEvent({
|
|
58
|
+
type: 'write',
|
|
59
|
+
path,
|
|
60
|
+
content: data,
|
|
61
|
+
size: data.length,
|
|
62
|
+
author: options?.author || 'system'
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
// Check for semantic versioning
|
|
66
|
+
if (this.semanticVersioning) {
|
|
67
|
+
const existingContent = await vfs.readFile(path).catch(() => null);
|
|
68
|
+
const shouldVersion = existingContent && this.isSemanticChange(existingContent, data);
|
|
69
|
+
if (shouldVersion) {
|
|
70
|
+
await this.semanticVersioning.createVersion(path, data, {
|
|
71
|
+
message: 'Automatic semantic version'
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Extract concepts
|
|
76
|
+
if (this.conceptSystem && options?.extractConcepts !== false) {
|
|
77
|
+
await this.conceptSystem.extractAndLinkConcepts(path, data);
|
|
78
|
+
}
|
|
79
|
+
// Extract entities
|
|
80
|
+
if (this.entitySystem && options?.extractEntities !== false) {
|
|
81
|
+
await this.entitySystem.extractEntities(data.toString('utf8'), data);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
// Knowledge Layer errors should not affect VFS operations
|
|
86
|
+
console.debug('KnowledgeLayer background processing error:', error);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
return result;
|
|
90
|
+
});
|
|
91
|
+
this.wrapMethod(vfs, 'unlink', async (original, path) => {
|
|
92
|
+
const result = await original.call(vfs, path);
|
|
93
|
+
// Record deletion event
|
|
94
|
+
setImmediate(async () => {
|
|
95
|
+
if (this.eventRecorder) {
|
|
96
|
+
await this.eventRecorder.recordEvent({
|
|
97
|
+
type: 'delete',
|
|
98
|
+
path,
|
|
99
|
+
author: 'system'
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
return result;
|
|
104
|
+
});
|
|
105
|
+
this.wrapMethod(vfs, 'rename', async (original, oldPath, newPath) => {
|
|
106
|
+
const result = await original.call(vfs, oldPath, newPath);
|
|
107
|
+
// Record rename event
|
|
108
|
+
setImmediate(async () => {
|
|
109
|
+
if (this.eventRecorder) {
|
|
110
|
+
await this.eventRecorder.recordEvent({
|
|
111
|
+
type: 'rename',
|
|
112
|
+
path: oldPath,
|
|
113
|
+
metadata: { newPath },
|
|
114
|
+
author: 'system'
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
return result;
|
|
119
|
+
});
|
|
120
|
+
// Add Knowledge Layer methods to VFS
|
|
121
|
+
this.addKnowledgeMethods(vfs);
|
|
122
|
+
console.log('✨ Knowledge Layer augmentation enabled');
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Wrap a VFS method to add Knowledge Layer functionality
|
|
126
|
+
*/
|
|
127
|
+
wrapMethod(vfs, methodName, wrapper) {
|
|
128
|
+
const original = vfs[methodName];
|
|
129
|
+
if (!original)
|
|
130
|
+
return;
|
|
131
|
+
// Store original for cleanup
|
|
132
|
+
this.originalMethods.set(methodName, original);
|
|
133
|
+
// Replace with wrapped version
|
|
134
|
+
vfs[methodName] = async (...args) => {
|
|
135
|
+
return await wrapper(original, ...args);
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Add Knowledge Layer methods to VFS
|
|
140
|
+
*/
|
|
141
|
+
addKnowledgeMethods(vfs) {
|
|
142
|
+
// Event history
|
|
143
|
+
vfs.getHistory = async (path, options) => {
|
|
144
|
+
if (!this.eventRecorder)
|
|
145
|
+
throw new Error('Knowledge Layer not initialized');
|
|
146
|
+
return await this.eventRecorder.getHistory(path, options);
|
|
147
|
+
};
|
|
148
|
+
vfs.reconstructAtTime = async (path, timestamp) => {
|
|
149
|
+
if (!this.eventRecorder)
|
|
150
|
+
throw new Error('Knowledge Layer not initialized');
|
|
151
|
+
return await this.eventRecorder.reconstructFileAtTime(path, timestamp);
|
|
152
|
+
};
|
|
153
|
+
// Semantic versioning
|
|
154
|
+
vfs.getVersions = async (path) => {
|
|
155
|
+
if (!this.semanticVersioning)
|
|
156
|
+
throw new Error('Knowledge Layer not initialized');
|
|
157
|
+
return await this.semanticVersioning.getVersions(path);
|
|
158
|
+
};
|
|
159
|
+
vfs.restoreVersion = async (path, versionId) => {
|
|
160
|
+
if (!this.semanticVersioning)
|
|
161
|
+
throw new Error('Knowledge Layer not initialized');
|
|
162
|
+
const version = await this.semanticVersioning.getVersion(path, versionId);
|
|
163
|
+
if (version) {
|
|
164
|
+
await vfs.writeFile(path, version);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
// Entities
|
|
168
|
+
vfs.findEntity = async (query) => {
|
|
169
|
+
if (!this.entitySystem)
|
|
170
|
+
throw new Error('Knowledge Layer not initialized');
|
|
171
|
+
return await this.entitySystem.findEntity(query);
|
|
172
|
+
};
|
|
173
|
+
vfs.getEntityAppearances = async (entityId) => {
|
|
174
|
+
if (!this.entitySystem)
|
|
175
|
+
throw new Error('Knowledge Layer not initialized');
|
|
176
|
+
return await this.entitySystem.getEvolution(entityId);
|
|
177
|
+
};
|
|
178
|
+
// Concepts
|
|
179
|
+
vfs.getConcepts = async (path) => {
|
|
180
|
+
if (!this.conceptSystem)
|
|
181
|
+
throw new Error('Knowledge Layer not initialized');
|
|
182
|
+
const concepts = await this.conceptSystem.findConcepts({ manifestedIn: path });
|
|
183
|
+
return concepts;
|
|
184
|
+
};
|
|
185
|
+
vfs.getConceptGraph = async (options) => {
|
|
186
|
+
if (!this.conceptSystem)
|
|
187
|
+
throw new Error('Knowledge Layer not initialized');
|
|
188
|
+
return await this.conceptSystem.getConceptGraph(options);
|
|
189
|
+
};
|
|
190
|
+
// Git bridge
|
|
191
|
+
vfs.exportToGit = async (vfsPath, gitPath) => {
|
|
192
|
+
if (!this.gitBridge)
|
|
193
|
+
throw new Error('Knowledge Layer not initialized');
|
|
194
|
+
return await this.gitBridge.exportToGit(vfsPath, gitPath);
|
|
195
|
+
};
|
|
196
|
+
vfs.importFromGit = async (gitPath, vfsPath) => {
|
|
197
|
+
if (!this.gitBridge)
|
|
198
|
+
throw new Error('Knowledge Layer not initialized');
|
|
199
|
+
return await this.gitBridge.importFromGit(gitPath, vfsPath);
|
|
200
|
+
};
|
|
201
|
+
// Temporal coupling
|
|
202
|
+
vfs.findTemporalCoupling = async (path, windowMs) => {
|
|
203
|
+
if (!this.eventRecorder)
|
|
204
|
+
throw new Error('Knowledge Layer not initialized');
|
|
205
|
+
return await this.eventRecorder.findTemporalCoupling(path, windowMs);
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
isSemanticChange(oldContent, newContent) {
|
|
209
|
+
// Simple heuristic - significant size change or different content
|
|
210
|
+
const oldStr = oldContent.toString('utf8');
|
|
211
|
+
const newStr = newContent.toString('utf8');
|
|
212
|
+
// Check for significant size change (>10%)
|
|
213
|
+
const sizeDiff = Math.abs(oldStr.length - newStr.length) / oldStr.length;
|
|
214
|
+
if (sizeDiff > 0.1)
|
|
215
|
+
return true;
|
|
216
|
+
// Check for structural changes (simplified)
|
|
217
|
+
const oldLines = oldStr.split('\n').filter(l => l.trim());
|
|
218
|
+
const newLines = newStr.split('\n').filter(l => l.trim());
|
|
219
|
+
// Different number of non-empty lines
|
|
220
|
+
return Math.abs(oldLines.length - newLines.length) > 5;
|
|
221
|
+
}
|
|
222
|
+
async cleanup(brain) {
|
|
223
|
+
const vfs = brain.vfs?.();
|
|
224
|
+
if (!vfs)
|
|
225
|
+
return;
|
|
226
|
+
// Restore original methods
|
|
227
|
+
for (const [methodName, original] of this.originalMethods) {
|
|
228
|
+
vfs[methodName] = original;
|
|
229
|
+
}
|
|
230
|
+
// Remove added methods
|
|
231
|
+
delete vfs.getHistory;
|
|
232
|
+
delete vfs.reconstructAtTime;
|
|
233
|
+
delete vfs.getVersions;
|
|
234
|
+
delete vfs.restoreVersion;
|
|
235
|
+
delete vfs.findEntity;
|
|
236
|
+
delete vfs.getEntityAppearances;
|
|
237
|
+
delete vfs.getConcepts;
|
|
238
|
+
delete vfs.getConceptGraph;
|
|
239
|
+
delete vfs.exportToGit;
|
|
240
|
+
delete vfs.importFromGit;
|
|
241
|
+
delete vfs.findTemporalCoupling;
|
|
242
|
+
// Clean up components
|
|
243
|
+
this.eventRecorder = undefined;
|
|
244
|
+
this.semanticVersioning = undefined;
|
|
245
|
+
this.entitySystem = undefined;
|
|
246
|
+
this.conceptSystem = undefined;
|
|
247
|
+
this.gitBridge = undefined;
|
|
248
|
+
console.log('Knowledge Layer augmentation removed');
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=KnowledgeAugmentation.js.map
|
package/dist/brainy.d.ts
CHANGED
|
@@ -1566,9 +1566,11 @@ export declare class Brainy<T = any> implements BrainyInterface<T> {
|
|
|
1566
1566
|
get counts(): {
|
|
1567
1567
|
entities: () => number;
|
|
1568
1568
|
relationships: () => number;
|
|
1569
|
-
byType: (
|
|
1570
|
-
|
|
1571
|
-
}
|
|
1569
|
+
byType: (typeOrOptions?: string | {
|
|
1570
|
+
excludeVFS?: boolean;
|
|
1571
|
+
}, options?: {
|
|
1572
|
+
excludeVFS?: boolean;
|
|
1573
|
+
}) => Promise<number | Record<string, number>>;
|
|
1572
1574
|
byTypeEnum: (type: NounType) => number;
|
|
1573
1575
|
topTypes: (n?: number) => NounType[];
|
|
1574
1576
|
topVerbTypes: (n?: number) => VerbType[];
|
|
@@ -1579,12 +1581,12 @@ export declare class Brainy<T = any> implements BrainyInterface<T> {
|
|
|
1579
1581
|
};
|
|
1580
1582
|
byCriteria: (field: string, value: any) => Promise<number>;
|
|
1581
1583
|
getAllTypeCounts: () => Map<string, number>;
|
|
1582
|
-
getStats: (
|
|
1584
|
+
getStats: (options?: {
|
|
1585
|
+
excludeVFS?: boolean;
|
|
1586
|
+
}) => Promise<{
|
|
1583
1587
|
entities: {
|
|
1584
1588
|
total: number;
|
|
1585
|
-
byType:
|
|
1586
|
-
[k: string]: number;
|
|
1587
|
-
};
|
|
1589
|
+
byType: Record<string, number>;
|
|
1588
1590
|
};
|
|
1589
1591
|
relationships: {
|
|
1590
1592
|
totalRelationships: number;
|
|
@@ -1594,7 +1596,7 @@ export declare class Brainy<T = any> implements BrainyInterface<T> {
|
|
|
1594
1596
|
totalNodes: number;
|
|
1595
1597
|
};
|
|
1596
1598
|
density: number;
|
|
1597
|
-
}
|
|
1599
|
+
}>;
|
|
1598
1600
|
};
|
|
1599
1601
|
/**
|
|
1600
1602
|
* Augmentations API - Clean and simple
|
|
@@ -1607,14 +1609,16 @@ export declare class Brainy<T = any> implements BrainyInterface<T> {
|
|
|
1607
1609
|
/**
|
|
1608
1610
|
* Get complete statistics - convenience method
|
|
1609
1611
|
* For more granular counting, use brain.counts API
|
|
1612
|
+
* v6.2.1: Added optional excludeVFS using Roaring bitmap intersection
|
|
1613
|
+
* @param options Optional settings - excludeVFS: filter out VFS entities
|
|
1610
1614
|
* @returns Complete statistics including entities, relationships, and density
|
|
1611
1615
|
*/
|
|
1612
|
-
getStats(
|
|
1616
|
+
getStats(options?: {
|
|
1617
|
+
excludeVFS?: boolean;
|
|
1618
|
+
}): Promise<{
|
|
1613
1619
|
entities: {
|
|
1614
1620
|
total: number;
|
|
1615
|
-
byType:
|
|
1616
|
-
[k: string]: number;
|
|
1617
|
-
};
|
|
1621
|
+
byType: Record<string, number>;
|
|
1618
1622
|
};
|
|
1619
1623
|
relationships: {
|
|
1620
1624
|
totalRelationships: number;
|
|
@@ -1624,7 +1628,7 @@ export declare class Brainy<T = any> implements BrainyInterface<T> {
|
|
|
1624
1628
|
totalNodes: number;
|
|
1625
1629
|
};
|
|
1626
1630
|
density: number;
|
|
1627
|
-
}
|
|
1631
|
+
}>;
|
|
1628
1632
|
/**
|
|
1629
1633
|
* Parse natural language query using advanced NLP with 220+ patterns
|
|
1630
1634
|
* The embedding model is always available as it's core to Brainy's functionality
|
package/dist/brainy.js
CHANGED
|
@@ -768,7 +768,13 @@ export class Brainy {
|
|
|
768
768
|
}
|
|
769
769
|
}
|
|
770
770
|
// Operation 5-6: Update metadata index (remove old, add new)
|
|
771
|
-
|
|
771
|
+
// v6.2.1: Fix - Include type in removal metadata so noun index is properly updated
|
|
772
|
+
// existing.metadata only contains custom fields, not 'type' which maps to 'noun'
|
|
773
|
+
const removalMetadata = {
|
|
774
|
+
...existing.metadata,
|
|
775
|
+
type: existing.type // Include type so it maps to 'noun' during removal
|
|
776
|
+
};
|
|
777
|
+
tx.addOperation(new RemoveFromMetadataIndexOperation(this.metadataIndex, params.id, removalMetadata));
|
|
772
778
|
tx.addOperation(new AddToMetadataIndexOperation(this.metadataIndex, params.id, entityForIndexing));
|
|
773
779
|
});
|
|
774
780
|
});
|
|
@@ -3405,7 +3411,39 @@ export class Brainy {
|
|
|
3405
3411
|
// O(1) total relationship count
|
|
3406
3412
|
relationships: () => this.graphIndex.getTotalRelationshipCount(),
|
|
3407
3413
|
// O(1) count by type (string-based, backward compatible)
|
|
3408
|
-
|
|
3414
|
+
// v6.2.1: Added optional excludeVFS using Roaring bitmap intersection
|
|
3415
|
+
byType: async (typeOrOptions, options) => {
|
|
3416
|
+
// Handle overloaded signature: byType(type), byType({ excludeVFS }), byType(type, { excludeVFS })
|
|
3417
|
+
let type;
|
|
3418
|
+
let excludeVFS = false;
|
|
3419
|
+
if (typeof typeOrOptions === 'string') {
|
|
3420
|
+
type = typeOrOptions;
|
|
3421
|
+
excludeVFS = options?.excludeVFS ?? false;
|
|
3422
|
+
}
|
|
3423
|
+
else if (typeOrOptions && typeof typeOrOptions === 'object') {
|
|
3424
|
+
excludeVFS = typeOrOptions.excludeVFS ?? false;
|
|
3425
|
+
}
|
|
3426
|
+
if (excludeVFS) {
|
|
3427
|
+
const allCounts = this.metadataIndex.getAllEntityCounts();
|
|
3428
|
+
// Uses Roaring bitmap intersection - hardware accelerated
|
|
3429
|
+
const vfsCounts = await this.metadataIndex.getAllVFSEntityCounts();
|
|
3430
|
+
if (type) {
|
|
3431
|
+
const total = allCounts.get(type) || 0;
|
|
3432
|
+
const vfs = vfsCounts.get(type) || 0;
|
|
3433
|
+
return total - vfs;
|
|
3434
|
+
}
|
|
3435
|
+
// Return all counts with VFS subtracted
|
|
3436
|
+
const result = {};
|
|
3437
|
+
for (const [t, total] of allCounts) {
|
|
3438
|
+
const vfs = vfsCounts.get(t) || 0;
|
|
3439
|
+
const nonVfs = total - vfs;
|
|
3440
|
+
if (nonVfs > 0) {
|
|
3441
|
+
result[t] = nonVfs;
|
|
3442
|
+
}
|
|
3443
|
+
}
|
|
3444
|
+
return result;
|
|
3445
|
+
}
|
|
3446
|
+
// Default path (unchanged) - synchronous for backward compatibility
|
|
3409
3447
|
if (type) {
|
|
3410
3448
|
return this.metadataIndex.getEntityCountByType(type);
|
|
3411
3449
|
}
|
|
@@ -3447,7 +3485,32 @@ export class Brainy {
|
|
|
3447
3485
|
// Get all type counts as Map for performance-critical operations
|
|
3448
3486
|
getAllTypeCounts: () => this.metadataIndex.getAllEntityCounts(),
|
|
3449
3487
|
// Get complete statistics
|
|
3450
|
-
|
|
3488
|
+
// v6.2.1: Added optional excludeVFS using Roaring bitmap intersection
|
|
3489
|
+
getStats: async (options) => {
|
|
3490
|
+
if (options?.excludeVFS) {
|
|
3491
|
+
const allCounts = this.metadataIndex.getAllEntityCounts();
|
|
3492
|
+
// Uses Roaring bitmap intersection - hardware accelerated
|
|
3493
|
+
const vfsCounts = await this.metadataIndex.getAllVFSEntityCounts();
|
|
3494
|
+
// Compute non-VFS counts via subtraction
|
|
3495
|
+
const byType = {};
|
|
3496
|
+
let total = 0;
|
|
3497
|
+
for (const [type, count] of allCounts) {
|
|
3498
|
+
const vfs = vfsCounts.get(type) || 0;
|
|
3499
|
+
const nonVfs = count - vfs;
|
|
3500
|
+
if (nonVfs > 0) {
|
|
3501
|
+
byType[type] = nonVfs;
|
|
3502
|
+
total += nonVfs;
|
|
3503
|
+
}
|
|
3504
|
+
}
|
|
3505
|
+
const entityStats = { total, byType };
|
|
3506
|
+
const relationshipStats = this.graphIndex.getRelationshipStats();
|
|
3507
|
+
return {
|
|
3508
|
+
entities: entityStats,
|
|
3509
|
+
relationships: relationshipStats,
|
|
3510
|
+
density: total > 0 ? relationshipStats.totalRelationships / total : 0
|
|
3511
|
+
};
|
|
3512
|
+
}
|
|
3513
|
+
// Default path (unchanged) - synchronous for backward compatibility
|
|
3451
3514
|
const entityStats = {
|
|
3452
3515
|
total: this.metadataIndex.getTotalEntityCount(),
|
|
3453
3516
|
byType: Object.fromEntries(this.metadataIndex.getAllEntityCounts())
|
|
@@ -3474,10 +3537,12 @@ export class Brainy {
|
|
|
3474
3537
|
/**
|
|
3475
3538
|
* Get complete statistics - convenience method
|
|
3476
3539
|
* For more granular counting, use brain.counts API
|
|
3540
|
+
* v6.2.1: Added optional excludeVFS using Roaring bitmap intersection
|
|
3541
|
+
* @param options Optional settings - excludeVFS: filter out VFS entities
|
|
3477
3542
|
* @returns Complete statistics including entities, relationships, and density
|
|
3478
3543
|
*/
|
|
3479
|
-
getStats() {
|
|
3480
|
-
return this.counts.getStats();
|
|
3544
|
+
async getStats(options) {
|
|
3545
|
+
return this.counts.getStats(options);
|
|
3481
3546
|
}
|
|
3482
3547
|
// ============= HELPER METHODS =============
|
|
3483
3548
|
/**
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Import Manager - Comprehensive data import with intelligent type detection
|
|
3
|
+
*
|
|
4
|
+
* Handles multiple data sources:
|
|
5
|
+
* - Direct data (objects, arrays)
|
|
6
|
+
* - Files (JSON, CSV, text)
|
|
7
|
+
* - URLs (fetch and parse)
|
|
8
|
+
* - Streams (for large files)
|
|
9
|
+
*
|
|
10
|
+
* Uses NeuralImportAugmentation for intelligent processing
|
|
11
|
+
*/
|
|
12
|
+
import { NounType } from './types/graphTypes.js';
|
|
13
|
+
export interface ImportOptions {
|
|
14
|
+
source?: 'data' | 'file' | 'url' | 'auto';
|
|
15
|
+
format?: 'json' | 'csv' | 'text' | 'yaml' | 'auto';
|
|
16
|
+
batchSize?: number;
|
|
17
|
+
autoDetect?: boolean;
|
|
18
|
+
typeHint?: NounType;
|
|
19
|
+
extractRelationships?: boolean;
|
|
20
|
+
csvDelimiter?: string;
|
|
21
|
+
csvHeaders?: boolean;
|
|
22
|
+
parallel?: boolean;
|
|
23
|
+
maxConcurrency?: number;
|
|
24
|
+
}
|
|
25
|
+
export interface ImportResult {
|
|
26
|
+
success: boolean;
|
|
27
|
+
nouns: string[];
|
|
28
|
+
verbs: string[];
|
|
29
|
+
errors: string[];
|
|
30
|
+
stats: {
|
|
31
|
+
total: number;
|
|
32
|
+
imported: number;
|
|
33
|
+
failed: number;
|
|
34
|
+
relationships: number;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export declare class ImportManager {
|
|
38
|
+
private neuralImport;
|
|
39
|
+
private typeMatcher;
|
|
40
|
+
private brain;
|
|
41
|
+
constructor(brain: any);
|
|
42
|
+
/**
|
|
43
|
+
* Initialize the import manager
|
|
44
|
+
*/
|
|
45
|
+
init(): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Main import method - handles all sources
|
|
48
|
+
*/
|
|
49
|
+
import(source: string | Buffer | any[] | any, options?: ImportOptions): Promise<ImportResult>;
|
|
50
|
+
/**
|
|
51
|
+
* Import from file
|
|
52
|
+
*/
|
|
53
|
+
importFile(filePath: string, options?: ImportOptions): Promise<ImportResult>;
|
|
54
|
+
/**
|
|
55
|
+
* Import from URL
|
|
56
|
+
*/
|
|
57
|
+
importUrl(url: string, options?: ImportOptions): Promise<ImportResult>;
|
|
58
|
+
/**
|
|
59
|
+
* Detect source type
|
|
60
|
+
*/
|
|
61
|
+
private detectSourceType;
|
|
62
|
+
/**
|
|
63
|
+
* Detect format from file path
|
|
64
|
+
*/
|
|
65
|
+
private detectFormatFromPath;
|
|
66
|
+
/**
|
|
67
|
+
* Read file
|
|
68
|
+
*/
|
|
69
|
+
private readFile;
|
|
70
|
+
/**
|
|
71
|
+
* Fetch from URL
|
|
72
|
+
*/
|
|
73
|
+
private fetchFromUrl;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Create an import manager instance
|
|
77
|
+
*/
|
|
78
|
+
export declare function createImportManager(brain: any): ImportManager;
|