@soulcraft/brainy 5.7.1 β 5.7.3
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/CHANGELOG.md +14 -0
- package/dist/brainy.js +24 -1
- package/dist/import/ImportCoordinator.js +4 -0
- package/dist/storage/baseStorage.d.ts +1 -0
- package/dist/storage/baseStorage.js +32 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [5.7.3](https://github.com/soulcraftlabs/brainy/compare/v5.7.2...v5.7.3) (2025-11-12)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### π Bug Fixes
|
|
9
|
+
|
|
10
|
+
* resolve REAL v5.7.x race condition - type cache layer (v5.7.3) ([ee17565](https://github.com/soulcraftlabs/brainy/commit/ee1756565ca01666e2aa3b31a80b62c6aa8046e8))
|
|
11
|
+
|
|
12
|
+
### [5.7.2](https://github.com/soulcraftlabs/brainy/compare/v5.7.1...v5.7.2) (2025-11-12)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### π Bug Fixes
|
|
16
|
+
|
|
17
|
+
* resolve v5.7.x race condition with write-through cache (v5.7.2) ([732d23b](https://github.com/soulcraftlabs/brainy/commit/732d23bd2afb4ac9559a9beb7835e0f623065ff2))
|
|
18
|
+
|
|
5
19
|
### [5.7.1](https://github.com/soulcraftlabs/brainy/compare/v5.7.0...v5.7.1) (2025-11-11)
|
|
6
20
|
|
|
7
21
|
- fix: resolve v5.7.0 deadlock by restoring storage layer separation (v5.7.1) (eb9af45)
|
package/dist/brainy.js
CHANGED
|
@@ -1613,6 +1613,21 @@ export class Brainy {
|
|
|
1613
1613
|
lastBatchTime = Date.now();
|
|
1614
1614
|
}
|
|
1615
1615
|
}
|
|
1616
|
+
// v5.7.3: Ensure nounTypeCache is populated for all successful entities
|
|
1617
|
+
// This prevents cache misses that trigger expensive 42-type searches
|
|
1618
|
+
// when entities are immediately queried (e.g., during brain.relate())
|
|
1619
|
+
const cacheWarmingNeeded = result.successful.filter(id => !this.storage.nounTypeCache?.has(id));
|
|
1620
|
+
if (cacheWarmingNeeded.length > 0) {
|
|
1621
|
+
// Warm the cache by fetching metadata for entities not in cache
|
|
1622
|
+
await Promise.all(cacheWarmingNeeded.map(async (id) => {
|
|
1623
|
+
try {
|
|
1624
|
+
await this.storage.getNounMetadata(id);
|
|
1625
|
+
}
|
|
1626
|
+
catch (error) {
|
|
1627
|
+
// Ignore errors during cache warming (entity may be invalid)
|
|
1628
|
+
}
|
|
1629
|
+
}));
|
|
1630
|
+
}
|
|
1616
1631
|
result.duration = Date.now() - startTime;
|
|
1617
1632
|
return result;
|
|
1618
1633
|
}
|
|
@@ -3079,7 +3094,15 @@ export class Brainy {
|
|
|
3079
3094
|
// 3. Flush graph adjacency index (relationship cache)
|
|
3080
3095
|
// Note: Graph structure is already persisted via storage.saveVerb() calls
|
|
3081
3096
|
// This just flushes the in-memory cache for performance
|
|
3082
|
-
this.graphIndex.flush()
|
|
3097
|
+
this.graphIndex.flush(),
|
|
3098
|
+
// 4. v5.7.3: Clear write-through cache after flush
|
|
3099
|
+
// Cache persists during batch operations for read-after-write consistency
|
|
3100
|
+
// Cleared here after all writes are guaranteed flushed to disk
|
|
3101
|
+
(async () => {
|
|
3102
|
+
if (this.storage && typeof this.storage.writeCache !== 'undefined') {
|
|
3103
|
+
this.storage.writeCache.clear();
|
|
3104
|
+
}
|
|
3105
|
+
})()
|
|
3083
3106
|
]);
|
|
3084
3107
|
const elapsed = Date.now() - startTime;
|
|
3085
3108
|
console.log(`β
All indexes flushed to disk in ${elapsed}ms`);
|
|
@@ -643,6 +643,10 @@ export class ImportCoordinator {
|
|
|
643
643
|
if (addResult.failed.length > 0) {
|
|
644
644
|
console.warn(`β οΈ ${addResult.failed.length} entities failed to create`);
|
|
645
645
|
}
|
|
646
|
+
// v5.7.3: Ensure all writes are flushed before creating relationships
|
|
647
|
+
// Fixes "Source entity not found" error in v5.7.0/v5.7.1/v5.7.2
|
|
648
|
+
// Guarantees entities are fully persisted and queryable before brain.relate() is called
|
|
649
|
+
await this.brain.flush();
|
|
646
650
|
// Create provenance links in batch
|
|
647
651
|
if (documentEntityId && options.createProvenanceLinks !== false && entities.length > 0) {
|
|
648
652
|
const provenanceParams = entities.map((entity, idx) => {
|
|
@@ -53,6 +53,7 @@ export declare abstract class BaseStorage extends BaseStorageAdapter {
|
|
|
53
53
|
protected graphIndex?: GraphAdjacencyIndex;
|
|
54
54
|
protected graphIndexPromise?: Promise<GraphAdjacencyIndex>;
|
|
55
55
|
protected readOnly: boolean;
|
|
56
|
+
private writeCache;
|
|
56
57
|
refManager?: RefManager;
|
|
57
58
|
blobStorage?: BlobStorage;
|
|
58
59
|
commitLog?: CommitLog;
|
|
@@ -74,6 +74,13 @@ export class BaseStorage extends BaseStorageAdapter {
|
|
|
74
74
|
super(...arguments);
|
|
75
75
|
this.isInitialized = false;
|
|
76
76
|
this.readOnly = false;
|
|
77
|
+
// v5.7.2: Write-through cache for read-after-write consistency
|
|
78
|
+
// v5.7.3: Extended lifetime - persists until explicit flush() call
|
|
79
|
+
// Guarantees that immediately after writeObjectToBranch(), readWithInheritance() returns the data
|
|
80
|
+
// Cache key: resolved branchPath (includes branch scope for COW isolation)
|
|
81
|
+
// Cache lifetime: write start β flush() call (provides safety net for batch operations)
|
|
82
|
+
// Memory footprint: Bounded by batch size (typically <1000 items during imports)
|
|
83
|
+
this.writeCache = new Map();
|
|
77
84
|
this.currentBranch = 'main';
|
|
78
85
|
this.cowEnabled = false;
|
|
79
86
|
// Type-first indexing support (v5.4.0)
|
|
@@ -353,7 +360,14 @@ export class BaseStorage extends BaseStorageAdapter {
|
|
|
353
360
|
*/
|
|
354
361
|
async writeObjectToBranch(path, data, branch) {
|
|
355
362
|
const branchPath = this.resolveBranchPath(path, branch);
|
|
356
|
-
|
|
363
|
+
// v5.7.2: Add to write cache BEFORE async write (guarantees read-after-write consistency)
|
|
364
|
+
// v5.7.3: Cache persists until flush() is called (extended lifetime for batch operations)
|
|
365
|
+
// This ensures readWithInheritance() returns data immediately, fixing "Source entity not found" bug
|
|
366
|
+
this.writeCache.set(branchPath, data);
|
|
367
|
+
// Write to storage (async)
|
|
368
|
+
await this.writeObjectToPath(branchPath, data);
|
|
369
|
+
// v5.7.3: Cache is NOT cleared here anymore - persists until flush()
|
|
370
|
+
// This provides a safety net for immediate queries after batch writes
|
|
357
371
|
}
|
|
358
372
|
/**
|
|
359
373
|
* Read object with inheritance from parent branches (COW layer)
|
|
@@ -362,12 +376,24 @@ export class BaseStorage extends BaseStorageAdapter {
|
|
|
362
376
|
*/
|
|
363
377
|
async readWithInheritance(path, branch) {
|
|
364
378
|
if (!this.cowEnabled) {
|
|
365
|
-
// COW disabled, direct read
|
|
379
|
+
// COW disabled: check write cache, then direct read
|
|
380
|
+
// v5.7.2: Check cache first for read-after-write consistency
|
|
381
|
+
const cachedData = this.writeCache.get(path);
|
|
382
|
+
if (cachedData !== undefined) {
|
|
383
|
+
return cachedData;
|
|
384
|
+
}
|
|
366
385
|
return this.readObjectFromPath(path);
|
|
367
386
|
}
|
|
368
387
|
const targetBranch = branch || this.currentBranch || 'main';
|
|
369
|
-
// Try current branch first
|
|
370
388
|
const branchPath = this.resolveBranchPath(path, targetBranch);
|
|
389
|
+
// v5.7.2: Check write cache FIRST (synchronous, instant)
|
|
390
|
+
// This guarantees read-after-write consistency within the same process
|
|
391
|
+
// Fixes bug: brain.add() β brain.relate() β "Source entity not found"
|
|
392
|
+
const cachedData = this.writeCache.get(branchPath);
|
|
393
|
+
if (cachedData !== undefined) {
|
|
394
|
+
return cachedData;
|
|
395
|
+
}
|
|
396
|
+
// Try current branch first
|
|
371
397
|
let data = await this.readObjectFromPath(branchPath);
|
|
372
398
|
if (data !== null) {
|
|
373
399
|
return data; // Found in current branch
|
|
@@ -411,6 +437,9 @@ export class BaseStorage extends BaseStorageAdapter {
|
|
|
411
437
|
*/
|
|
412
438
|
async deleteObjectFromBranch(path, branch) {
|
|
413
439
|
const branchPath = this.resolveBranchPath(path, branch);
|
|
440
|
+
// v5.7.2: Remove from write cache immediately (before async delete)
|
|
441
|
+
// Ensures subsequent reads don't return stale cached data
|
|
442
|
+
this.writeCache.delete(branchPath);
|
|
414
443
|
return this.deleteObjectFromPath(branchPath);
|
|
415
444
|
}
|
|
416
445
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soulcraft/brainy",
|
|
3
|
-
"version": "5.7.
|
|
3
|
+
"version": "5.7.3",
|
|
4
4
|
"description": "Universal Knowledge Protocolβ’ - World's first Triple Intelligence database unifying vector, graph, and document search in one API. Stage 3 CANONICAL: 42 nouns Γ 127 verbs covering 96-97% of all human knowledge.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|