@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 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
- return this.writeObjectToPath(branchPath, data);
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.1",
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",