@soulcraft/brainy 5.7.1 → 5.7.2
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 +7 -0
- package/dist/storage/baseStorage.d.ts +1 -0
- package/dist/storage/baseStorage.js +34 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
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.2](https://github.com/soulcraftlabs/brainy/compare/v5.7.1...v5.7.2) (2025-11-12)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### 🐛 Bug Fixes
|
|
9
|
+
|
|
10
|
+
* resolve v5.7.x race condition with write-through cache (v5.7.2) ([732d23b](https://github.com/soulcraftlabs/brainy/commit/732d23bd2afb4ac9559a9beb7835e0f623065ff2))
|
|
11
|
+
|
|
5
12
|
### [5.7.1](https://github.com/soulcraftlabs/brainy/compare/v5.7.0...v5.7.1) (2025-11-11)
|
|
6
13
|
|
|
7
14
|
- fix: resolve v5.7.0 deadlock by restoring storage layer separation (v5.7.1) (eb9af45)
|
|
@@ -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,12 @@ 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
|
+
// Guarantees that immediately after writeObjectToBranch(), readWithInheritance() returns the data
|
|
79
|
+
// Cache key: resolved branchPath (includes branch scope for COW isolation)
|
|
80
|
+
// Cache lifetime: write start → write completion (microseconds to milliseconds)
|
|
81
|
+
// Memory footprint: Typically <10 items (only in-flight writes), <1KB total
|
|
82
|
+
this.writeCache = new Map();
|
|
77
83
|
this.currentBranch = 'main';
|
|
78
84
|
this.cowEnabled = false;
|
|
79
85
|
// Type-first indexing support (v5.4.0)
|
|
@@ -353,7 +359,17 @@ export class BaseStorage extends BaseStorageAdapter {
|
|
|
353
359
|
*/
|
|
354
360
|
async writeObjectToBranch(path, data, branch) {
|
|
355
361
|
const branchPath = this.resolveBranchPath(path, branch);
|
|
356
|
-
|
|
362
|
+
// v5.7.2: Add to write cache BEFORE async write (guarantees read-after-write consistency)
|
|
363
|
+
// This ensures readWithInheritance() returns data immediately, fixing "Source entity not found" bug
|
|
364
|
+
this.writeCache.set(branchPath, data);
|
|
365
|
+
try {
|
|
366
|
+
await this.writeObjectToPath(branchPath, data);
|
|
367
|
+
}
|
|
368
|
+
finally {
|
|
369
|
+
// v5.7.2: Remove from cache after write completes (success or failure)
|
|
370
|
+
// Small memory footprint: cache only holds in-flight writes (typically <10 items)
|
|
371
|
+
this.writeCache.delete(branchPath);
|
|
372
|
+
}
|
|
357
373
|
}
|
|
358
374
|
/**
|
|
359
375
|
* Read object with inheritance from parent branches (COW layer)
|
|
@@ -362,12 +378,24 @@ export class BaseStorage extends BaseStorageAdapter {
|
|
|
362
378
|
*/
|
|
363
379
|
async readWithInheritance(path, branch) {
|
|
364
380
|
if (!this.cowEnabled) {
|
|
365
|
-
// COW disabled, direct read
|
|
381
|
+
// COW disabled: check write cache, then direct read
|
|
382
|
+
// v5.7.2: Check cache first for read-after-write consistency
|
|
383
|
+
const cachedData = this.writeCache.get(path);
|
|
384
|
+
if (cachedData !== undefined) {
|
|
385
|
+
return cachedData;
|
|
386
|
+
}
|
|
366
387
|
return this.readObjectFromPath(path);
|
|
367
388
|
}
|
|
368
389
|
const targetBranch = branch || this.currentBranch || 'main';
|
|
369
|
-
// Try current branch first
|
|
370
390
|
const branchPath = this.resolveBranchPath(path, targetBranch);
|
|
391
|
+
// v5.7.2: Check write cache FIRST (synchronous, instant)
|
|
392
|
+
// This guarantees read-after-write consistency within the same process
|
|
393
|
+
// Fixes bug: brain.add() → brain.relate() → "Source entity not found"
|
|
394
|
+
const cachedData = this.writeCache.get(branchPath);
|
|
395
|
+
if (cachedData !== undefined) {
|
|
396
|
+
return cachedData;
|
|
397
|
+
}
|
|
398
|
+
// Try current branch first
|
|
371
399
|
let data = await this.readObjectFromPath(branchPath);
|
|
372
400
|
if (data !== null) {
|
|
373
401
|
return data; // Found in current branch
|
|
@@ -411,6 +439,9 @@ export class BaseStorage extends BaseStorageAdapter {
|
|
|
411
439
|
*/
|
|
412
440
|
async deleteObjectFromBranch(path, branch) {
|
|
413
441
|
const branchPath = this.resolveBranchPath(path, branch);
|
|
442
|
+
// v5.7.2: Remove from write cache immediately (before async delete)
|
|
443
|
+
// Ensures subsequent reads don't return stale cached data
|
|
444
|
+
this.writeCache.delete(branchPath);
|
|
414
445
|
return this.deleteObjectFromPath(branchPath);
|
|
415
446
|
}
|
|
416
447
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soulcraft/brainy",
|
|
3
|
-
"version": "5.7.
|
|
3
|
+
"version": "5.7.2",
|
|
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",
|