@soulcraft/brainy 5.7.10 → 5.7.11
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.11](https://github.com/soulcraftlabs/brainy/compare/v5.7.10...v5.7.11) (2025-11-13)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### 🐛 Bug Fixes
|
|
9
|
+
|
|
10
|
+
* resolve critical 378x pagination infinite loop bug (v5.7.11) ([e86f765](https://github.com/soulcraftlabs/brainy/commit/e86f765f3d30be41707e2ef7d07bb5c92d4ca3da))
|
|
11
|
+
|
|
5
12
|
### [5.7.9](https://github.com/soulcraftlabs/brainy/compare/v5.7.8...v5.7.9) (2025-11-13)
|
|
6
13
|
|
|
7
14
|
- fix: implement exists: false and missing operators in MetadataIndexManager (b0f72ef)
|
package/dist/hnsw/hnswIndex.js
CHANGED
|
@@ -858,12 +858,12 @@ export class HNSWIndex {
|
|
|
858
858
|
// Cloud storage: Use pagination with native cloud APIs
|
|
859
859
|
prodLog.info(`HNSW: Using cloud pagination strategy (${storageType})`);
|
|
860
860
|
let hasMore = true;
|
|
861
|
-
let
|
|
861
|
+
let offset = 0; // v5.7.11: Use offset-based pagination instead of cursor (bug fix for infinite loop)
|
|
862
862
|
while (hasMore) {
|
|
863
863
|
// Fetch batch of nouns from storage (cast needed as method is not in base interface)
|
|
864
864
|
const result = await this.storage.getNounsWithPagination({
|
|
865
865
|
limit: batchSize,
|
|
866
|
-
cursor
|
|
866
|
+
offset // v5.7.11: Pass offset for proper pagination (previously passed cursor which was ignored)
|
|
867
867
|
});
|
|
868
868
|
// Set total count on first batch
|
|
869
869
|
if (totalCount === undefined && result.totalCount !== undefined) {
|
|
@@ -912,7 +912,7 @@ export class HNSWIndex {
|
|
|
912
912
|
}
|
|
913
913
|
// Check for more data
|
|
914
914
|
hasMore = result.hasMore;
|
|
915
|
-
|
|
915
|
+
offset += batchSize; // v5.7.11: Increment offset for next page
|
|
916
916
|
}
|
|
917
917
|
}
|
|
918
918
|
const cacheInfo = shouldPreload
|
|
@@ -342,14 +342,14 @@ export class TypeAwareHNSWIndex {
|
|
|
342
342
|
}
|
|
343
343
|
// Load ALL nouns ONCE and route to correct type indexes
|
|
344
344
|
// This is O(N) instead of O(42*N) from the previous parallel approach
|
|
345
|
-
let
|
|
345
|
+
let offset = 0; // v5.7.11: Use offset-based pagination instead of cursor (bug fix for infinite loop)
|
|
346
346
|
let hasMore = true;
|
|
347
347
|
let totalLoaded = 0;
|
|
348
348
|
const loadedByType = new Map();
|
|
349
349
|
while (hasMore) {
|
|
350
350
|
const result = await this.storage.getNounsWithPagination({
|
|
351
351
|
limit: batchSize,
|
|
352
|
-
cursor
|
|
352
|
+
offset // v5.7.11: Pass offset for proper pagination (previously passed cursor which was ignored)
|
|
353
353
|
});
|
|
354
354
|
// Route each noun to its type index
|
|
355
355
|
for (const nounData of result.items) {
|
|
@@ -407,7 +407,7 @@ export class TypeAwareHNSWIndex {
|
|
|
407
407
|
}
|
|
408
408
|
}
|
|
409
409
|
hasMore = result.hasMore;
|
|
410
|
-
|
|
410
|
+
offset += batchSize; // v5.7.11: Increment offset for next page
|
|
411
411
|
// Progress logging
|
|
412
412
|
if (totalLoaded % 1000 === 0) {
|
|
413
413
|
prodLog.info(`Progress: ${totalLoaded.toLocaleString()} entities loaded...`);
|
|
@@ -48,7 +48,7 @@ export class OptimizedS3Search {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
// Determine if there are more items
|
|
51
|
-
const hasMore = listResult.hasMore || nouns.length
|
|
51
|
+
const hasMore = listResult.hasMore || nouns.length > limit; // v5.7.11: Fixed >= to > (was causing infinite loop)
|
|
52
52
|
// Set next cursor
|
|
53
53
|
let nextCursor;
|
|
54
54
|
if (hasMore && nouns.length > 0) {
|
|
@@ -114,7 +114,7 @@ export class OptimizedS3Search {
|
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
// Determine if there are more items
|
|
117
|
-
const hasMore = listResult.hasMore || verbs.length
|
|
117
|
+
const hasMore = listResult.hasMore || verbs.length > limit; // v5.7.11: Fixed >= to > (was causing infinite loop)
|
|
118
118
|
// Set next cursor
|
|
119
119
|
let nextCursor;
|
|
120
120
|
if (hasMore && verbs.length > 0) {
|
|
@@ -879,7 +879,7 @@ export class BaseStorage extends BaseStorageAdapter {
|
|
|
879
879
|
*/
|
|
880
880
|
async getNounsWithPagination(options) {
|
|
881
881
|
await this.ensureInitialized();
|
|
882
|
-
const { limit, offset = 0, filter } = options;
|
|
882
|
+
const { limit, offset = 0, filter } = options; // cursor intentionally not extracted (not yet implemented)
|
|
883
883
|
const collectedNouns = [];
|
|
884
884
|
const targetCount = offset + limit; // Early termination target
|
|
885
885
|
// v5.5.0 BUG FIX: Only use optimization if counts are reliable
|
|
@@ -960,7 +960,7 @@ export class BaseStorage extends BaseStorageAdapter {
|
|
|
960
960
|
}
|
|
961
961
|
// Apply pagination (v5.5.0: Efficient slicing after early termination)
|
|
962
962
|
const paginatedNouns = collectedNouns.slice(offset, offset + limit);
|
|
963
|
-
const hasMore = collectedNouns.length
|
|
963
|
+
const hasMore = collectedNouns.length > targetCount; // v5.7.11: Fixed >= to > (was causing infinite loop)
|
|
964
964
|
return {
|
|
965
965
|
items: paginatedNouns,
|
|
966
966
|
totalCount: collectedNouns.length, // Accurate count of collected results
|
|
@@ -987,7 +987,7 @@ export class BaseStorage extends BaseStorageAdapter {
|
|
|
987
987
|
*/
|
|
988
988
|
async getVerbsWithPagination(options) {
|
|
989
989
|
await this.ensureInitialized();
|
|
990
|
-
const { limit, offset = 0, filter } = options;
|
|
990
|
+
const { limit, offset = 0, filter } = options; // cursor intentionally not extracted (not yet implemented)
|
|
991
991
|
const collectedVerbs = [];
|
|
992
992
|
const targetCount = offset + limit; // Early termination target
|
|
993
993
|
// v5.5.0 BUG FIX: Only use optimization if counts are reliable
|
|
@@ -1046,7 +1046,7 @@ export class BaseStorage extends BaseStorageAdapter {
|
|
|
1046
1046
|
}
|
|
1047
1047
|
// Apply pagination (v5.5.0: Efficient slicing after early termination)
|
|
1048
1048
|
const paginatedVerbs = collectedVerbs.slice(offset, offset + limit);
|
|
1049
|
-
const hasMore = collectedVerbs.length
|
|
1049
|
+
const hasMore = collectedVerbs.length > targetCount; // v5.7.11: Fixed >= to > (was causing infinite loop)
|
|
1050
1050
|
return {
|
|
1051
1051
|
items: paginatedVerbs,
|
|
1052
1052
|
totalCount: collectedVerbs.length, // Accurate count of collected results
|
|
@@ -1301,7 +1301,7 @@ export class BaseStorage extends BaseStorageAdapter {
|
|
|
1301
1301
|
}
|
|
1302
1302
|
// Apply pagination (slice for offset)
|
|
1303
1303
|
const paginatedVerbs = collectedVerbs.slice(offset, offset + limit);
|
|
1304
|
-
const hasMore = collectedVerbs.length
|
|
1304
|
+
const hasMore = collectedVerbs.length > targetCount; // v5.7.11: Fixed >= to > (was causing infinite loop)
|
|
1305
1305
|
return {
|
|
1306
1306
|
items: paginatedVerbs,
|
|
1307
1307
|
totalCount: collectedVerbs.length, // Accurate count of filtered results
|
|
@@ -39,9 +39,12 @@ export async function rebuildCounts(storage) {
|
|
|
39
39
|
throw new Error('Storage adapter does not support getNounsWithPagination');
|
|
40
40
|
}
|
|
41
41
|
let hasMore = true;
|
|
42
|
-
let cursor
|
|
42
|
+
let offset = 0; // v5.7.11: Use offset-based pagination instead of cursor (bug fix for infinite loop)
|
|
43
43
|
while (hasMore) {
|
|
44
|
-
const result = await storageWithPagination.getNounsWithPagination({
|
|
44
|
+
const result = await storageWithPagination.getNounsWithPagination({
|
|
45
|
+
limit: 100,
|
|
46
|
+
offset // v5.7.11: Pass offset for proper pagination (previously passed cursor which was ignored)
|
|
47
|
+
});
|
|
45
48
|
for (const noun of result.items) {
|
|
46
49
|
const metadata = await storage.getNounMetadata(noun.id);
|
|
47
50
|
if (metadata?.noun) {
|
|
@@ -51,7 +54,7 @@ export async function rebuildCounts(storage) {
|
|
|
51
54
|
}
|
|
52
55
|
}
|
|
53
56
|
hasMore = result.hasMore;
|
|
54
|
-
|
|
57
|
+
offset += 100; // v5.7.11: Increment offset for next page
|
|
55
58
|
}
|
|
56
59
|
console.log(` Found ${totalNouns} entities across ${entityCounts.size} types`);
|
|
57
60
|
// Scan all verbs using pagination
|
|
@@ -60,9 +63,12 @@ export async function rebuildCounts(storage) {
|
|
|
60
63
|
throw new Error('Storage adapter does not support getVerbsWithPagination');
|
|
61
64
|
}
|
|
62
65
|
hasMore = true;
|
|
63
|
-
|
|
66
|
+
offset = 0; // v5.7.11: Reset offset for verbs pagination
|
|
64
67
|
while (hasMore) {
|
|
65
|
-
const result = await storageWithPagination.getVerbsWithPagination({
|
|
68
|
+
const result = await storageWithPagination.getVerbsWithPagination({
|
|
69
|
+
limit: 100,
|
|
70
|
+
offset // v5.7.11: Pass offset for proper pagination (previously passed cursor which was ignored)
|
|
71
|
+
});
|
|
66
72
|
for (const verb of result.items) {
|
|
67
73
|
if (verb.verb) {
|
|
68
74
|
const verbType = verb.verb;
|
|
@@ -71,7 +77,7 @@ export async function rebuildCounts(storage) {
|
|
|
71
77
|
}
|
|
72
78
|
}
|
|
73
79
|
hasMore = result.hasMore;
|
|
74
|
-
|
|
80
|
+
offset += 100; // v5.7.11: Increment offset for next page
|
|
75
81
|
}
|
|
76
82
|
console.log(` Found ${totalVerbs} relationships across ${verbCounts.size} types`);
|
|
77
83
|
// Update storage adapter's in-memory counts FIRST
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soulcraft/brainy",
|
|
3
|
-
"version": "5.7.
|
|
3
|
+
"version": "5.7.11",
|
|
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",
|