@soulcraft/brainy 3.10.1 → 3.12.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.
@@ -40,10 +40,12 @@ export declare class PathResolver {
40
40
  private fullResolve;
41
41
  /**
42
42
  * Resolve a child entity by name within a parent directory
43
+ * Uses proper graph relationships instead of metadata queries
43
44
  */
44
45
  private resolveChild;
45
46
  /**
46
47
  * Get all children of a directory
48
+ * Uses proper graph relationships to traverse the tree
47
49
  */
48
50
  getChildren(dirId: string): Promise<VFSEntity[]>;
49
51
  /**
@@ -122,69 +122,56 @@ export class PathResolver {
122
122
  }
123
123
  /**
124
124
  * Resolve a child entity by name within a parent directory
125
+ * Uses proper graph relationships instead of metadata queries
125
126
  */
126
127
  async resolveChild(parentId, name) {
127
128
  // Check parent cache first
128
129
  const cachedChildren = this.parentCache.get(parentId);
129
130
  if (cachedChildren && cachedChildren.has(name)) {
130
- // We know this child exists, find it by path since parent queries don't work
131
- const parentEntity = await this.getEntity(parentId);
132
- const parentPath = parentEntity.metadata.path;
133
- const childPath = this.joinPath(parentPath, name);
134
- const pathResults = await this.brain.find({
135
- where: { path: childPath },
136
- limit: 1
137
- });
138
- if (pathResults.length > 0) {
139
- return pathResults[0].entity.id;
140
- }
131
+ // Use cached knowledge to quickly find the child
132
+ // Still need to verify it exists
141
133
  }
142
- // Since parent field queries don't work reliably, construct the expected path
143
- // and query by path instead
144
- const parentEntity = await this.getEntity(parentId);
145
- const parentPath = parentEntity.metadata.path;
146
- const childPath = this.joinPath(parentPath, name);
147
- const results = await this.brain.find({
148
- where: { path: childPath },
149
- limit: 1
134
+ // Use proper graph traversal to find children
135
+ // Get all relationships where parentId contains other entities
136
+ const relations = await this.brain.getRelations({
137
+ from: parentId,
138
+ type: VerbType.Contains
150
139
  });
151
- if (results.length > 0) {
152
- const childId = results[0].entity.id;
153
- // Update parent cache
154
- if (!this.parentCache.has(parentId)) {
155
- this.parentCache.set(parentId, new Set());
140
+ // Find the child with matching name
141
+ for (const relation of relations) {
142
+ const childEntity = await this.brain.get(relation.to);
143
+ if (childEntity && childEntity.metadata?.name === name) {
144
+ // Update parent cache
145
+ if (!this.parentCache.has(parentId)) {
146
+ this.parentCache.set(parentId, new Set());
147
+ }
148
+ this.parentCache.get(parentId).add(name);
149
+ return childEntity.id;
156
150
  }
157
- this.parentCache.get(parentId).add(name);
158
- return childId;
159
151
  }
160
152
  return null;
161
153
  }
162
154
  /**
163
155
  * Get all children of a directory
156
+ * Uses proper graph relationships to traverse the tree
164
157
  */
165
158
  async getChildren(dirId) {
166
- // Use Brainy's relationship query to find all children
167
- const results = await this.brain.find({
168
- connected: {
169
- from: dirId,
170
- via: VerbType.Contains
171
- },
172
- limit: 10000 // Large limit for directories
159
+ // Use proper graph API to get all Contains relationships from this directory
160
+ const relations = await this.brain.getRelations({
161
+ from: dirId,
162
+ type: VerbType.Contains
173
163
  });
174
- // Filter and process valid VFS entities only
175
164
  const validChildren = [];
176
165
  const childNames = new Set();
177
- for (const result of results) {
178
- const entity = result.entity;
179
- // Only include entities with proper VFS metadata and non-empty names
180
- if (entity.metadata?.vfsType &&
181
- entity.metadata?.name &&
182
- entity.metadata?.path &&
183
- entity.id !== dirId) { // Don't include the directory itself
166
+ // Fetch all child entities
167
+ for (const relation of relations) {
168
+ const entity = await this.brain.get(relation.to);
169
+ if (entity && entity.metadata?.vfsType && entity.metadata?.name) {
184
170
  validChildren.push(entity);
185
171
  childNames.add(entity.metadata.name);
186
172
  }
187
173
  }
174
+ // Update cache
188
175
  this.parentCache.set(dirId, childNames);
189
176
  return validChildren;
190
177
  }
@@ -1364,37 +1364,29 @@ export class VirtualFileSystem {
1364
1364
  await this.ensureInitialized();
1365
1365
  const entityId = await this.pathResolver.resolve(path);
1366
1366
  const results = [];
1367
- // Get all relationships involving this entity (both from and to)
1367
+ // Use proper Brainy relationship API to get all relationships
1368
1368
  const [fromRelations, toRelations] = await Promise.all([
1369
- this.brain.find({
1370
- connected: {
1371
- from: entityId
1372
- },
1373
- limit: 1000
1374
- }),
1375
- this.brain.find({
1376
- connected: {
1377
- to: entityId
1378
- },
1379
- limit: 1000
1380
- })
1369
+ this.brain.getRelations({ from: entityId }),
1370
+ this.brain.getRelations({ to: entityId })
1381
1371
  ]);
1382
1372
  // Add outgoing relationships
1383
1373
  for (const rel of fromRelations) {
1384
- if (rel.entity.metadata?.path) {
1374
+ const targetEntity = await this.brain.get(rel.to);
1375
+ if (targetEntity && targetEntity.metadata?.path) {
1385
1376
  results.push({
1386
- path: rel.entity.metadata.path,
1387
- relationship: 'related',
1377
+ path: targetEntity.metadata.path,
1378
+ relationship: rel.type || 'related',
1388
1379
  direction: 'from'
1389
1380
  });
1390
1381
  }
1391
1382
  }
1392
1383
  // Add incoming relationships
1393
1384
  for (const rel of toRelations) {
1394
- if (rel.entity.metadata?.path) {
1385
+ const sourceEntity = await this.brain.get(rel.from);
1386
+ if (sourceEntity && sourceEntity.metadata?.path) {
1395
1387
  results.push({
1396
- path: rel.entity.metadata.path,
1397
- relationship: 'related',
1388
+ path: sourceEntity.metadata.path,
1389
+ relationship: rel.type || 'related',
1398
1390
  direction: 'to'
1399
1391
  });
1400
1392
  }
@@ -1405,49 +1397,37 @@ export class VirtualFileSystem {
1405
1397
  await this.ensureInitialized();
1406
1398
  const entityId = await this.pathResolver.resolve(path);
1407
1399
  const relationships = [];
1408
- // Get all relationships involving this entity (both from and to)
1400
+ // Use proper Brainy relationship API
1409
1401
  const [fromRelations, toRelations] = await Promise.all([
1410
- this.brain.find({
1411
- connected: {
1412
- from: entityId
1413
- },
1414
- limit: 1000
1415
- }),
1416
- this.brain.find({
1417
- connected: {
1418
- to: entityId
1419
- },
1420
- limit: 1000
1421
- })
1402
+ this.brain.getRelations({ from: entityId }),
1403
+ this.brain.getRelations({ to: entityId })
1422
1404
  ]);
1423
- // Add outgoing relationships (exclude parent-child relationships)
1405
+ // Process outgoing relationships (excluding Contains for parent-child)
1424
1406
  for (const rel of fromRelations) {
1425
- if (rel.entity.metadata?.path && rel.entity.metadata?.vfsType) {
1426
- // Skip parent-child relationships to focus on user-defined relationships
1427
- const parentPath = this.getParentPath(rel.entity.metadata.path);
1428
- if (parentPath !== path) { // Not a direct child
1407
+ if (rel.type !== VerbType.Contains) { // Skip filesystem hierarchy
1408
+ const targetEntity = await this.brain.get(rel.to);
1409
+ if (targetEntity && targetEntity.metadata?.path) {
1429
1410
  relationships.push({
1430
- id: crypto.randomUUID(),
1431
- from: path,
1432
- to: rel.entity.metadata.path,
1433
- type: VerbType.References,
1434
- createdAt: Date.now()
1411
+ id: rel.id || crypto.randomUUID(),
1412
+ from: entityId,
1413
+ to: rel.to,
1414
+ type: rel.type,
1415
+ createdAt: rel.createdAt || Date.now()
1435
1416
  });
1436
1417
  }
1437
1418
  }
1438
1419
  }
1439
- // Add incoming relationships (exclude parent-child relationships)
1420
+ // Process incoming relationships (excluding Contains for parent-child)
1440
1421
  for (const rel of toRelations) {
1441
- if (rel.entity.metadata?.path && rel.entity.metadata?.vfsType) {
1442
- // Skip parent-child relationships to focus on user-defined relationships
1443
- const parentPath = this.getParentPath(path);
1444
- if (rel.entity.metadata.path !== parentPath) { // Not the parent
1422
+ if (rel.type !== VerbType.Contains) { // Skip filesystem hierarchy
1423
+ const sourceEntity = await this.brain.get(rel.from);
1424
+ if (sourceEntity && sourceEntity.metadata?.path) {
1445
1425
  relationships.push({
1446
- id: crypto.randomUUID(),
1447
- from: rel.entity.metadata.path,
1448
- to: path,
1449
- type: VerbType.References,
1450
- createdAt: Date.now()
1426
+ id: rel.id || crypto.randomUUID(),
1427
+ from: rel.from,
1428
+ to: entityId,
1429
+ type: rel.type,
1430
+ createdAt: rel.createdAt || Date.now()
1451
1431
  });
1452
1432
  }
1453
1433
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soulcraft/brainy",
3
- "version": "3.10.1",
3
+ "version": "3.12.0",
4
4
  "description": "Universal Knowledge Protocol™ - World's first Triple Intelligence database unifying vector, graph, and document search in one API. 31 nouns × 40 verbs for infinite expressiveness.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",