@soulcraft/brainy 3.34.0 → 3.35.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.
@@ -1471,5 +1471,106 @@ export class OPFSStorage extends BaseStorage {
1471
1471
  console.error('Error persisting counts to OPFS:', error);
1472
1472
  }
1473
1473
  }
1474
+ // HNSW Index Persistence (v3.35.0+)
1475
+ /**
1476
+ * Get a noun's vector for HNSW rebuild
1477
+ */
1478
+ async getNounVector(id) {
1479
+ await this.ensureInitialized();
1480
+ const noun = await this.getNoun_internal(id);
1481
+ return noun ? noun.vector : null;
1482
+ }
1483
+ /**
1484
+ * Save HNSW graph data for a noun
1485
+ * Storage path: nouns/hnsw/{shard}/{id}.json
1486
+ */
1487
+ async saveHNSWData(nounId, hnswData) {
1488
+ await this.ensureInitialized();
1489
+ try {
1490
+ // Get or create the hnsw directory under nouns
1491
+ const hnswDir = await this.nounsDir.getDirectoryHandle('hnsw', { create: true });
1492
+ // Use sharded path for HNSW data
1493
+ const shard = getShardIdFromUuid(nounId);
1494
+ const shardDir = await hnswDir.getDirectoryHandle(shard, { create: true });
1495
+ // Create or get the file in the shard directory
1496
+ const fileHandle = await shardDir.getFileHandle(`${nounId}.json`, { create: true });
1497
+ // Write the HNSW data to the file
1498
+ const writable = await fileHandle.createWritable();
1499
+ await writable.write(JSON.stringify(hnswData, null, 2));
1500
+ await writable.close();
1501
+ }
1502
+ catch (error) {
1503
+ console.error(`Failed to save HNSW data for ${nounId}:`, error);
1504
+ throw new Error(`Failed to save HNSW data for ${nounId}: ${error}`);
1505
+ }
1506
+ }
1507
+ /**
1508
+ * Get HNSW graph data for a noun
1509
+ * Storage path: nouns/hnsw/{shard}/{id}.json
1510
+ */
1511
+ async getHNSWData(nounId) {
1512
+ await this.ensureInitialized();
1513
+ try {
1514
+ // Get the hnsw directory under nouns
1515
+ const hnswDir = await this.nounsDir.getDirectoryHandle('hnsw');
1516
+ // Use sharded path for HNSW data
1517
+ const shard = getShardIdFromUuid(nounId);
1518
+ const shardDir = await hnswDir.getDirectoryHandle(shard);
1519
+ // Get the file handle from the shard directory
1520
+ const fileHandle = await shardDir.getFileHandle(`${nounId}.json`);
1521
+ // Read the HNSW data from the file
1522
+ const file = await fileHandle.getFile();
1523
+ const text = await file.text();
1524
+ return JSON.parse(text);
1525
+ }
1526
+ catch (error) {
1527
+ if (error.name === 'NotFoundError') {
1528
+ return null;
1529
+ }
1530
+ console.error(`Failed to get HNSW data for ${nounId}:`, error);
1531
+ throw new Error(`Failed to get HNSW data for ${nounId}: ${error}`);
1532
+ }
1533
+ }
1534
+ /**
1535
+ * Save HNSW system data (entry point, max level)
1536
+ * Storage path: index/hnsw-system.json
1537
+ */
1538
+ async saveHNSWSystem(systemData) {
1539
+ await this.ensureInitialized();
1540
+ try {
1541
+ // Create or get the file in the index directory
1542
+ const fileHandle = await this.indexDir.getFileHandle('hnsw-system.json', { create: true });
1543
+ // Write the system data to the file
1544
+ const writable = await fileHandle.createWritable();
1545
+ await writable.write(JSON.stringify(systemData, null, 2));
1546
+ await writable.close();
1547
+ }
1548
+ catch (error) {
1549
+ console.error('Failed to save HNSW system data:', error);
1550
+ throw new Error(`Failed to save HNSW system data: ${error}`);
1551
+ }
1552
+ }
1553
+ /**
1554
+ * Get HNSW system data (entry point, max level)
1555
+ * Storage path: index/hnsw-system.json
1556
+ */
1557
+ async getHNSWSystem() {
1558
+ await this.ensureInitialized();
1559
+ try {
1560
+ // Get the file handle from the index directory
1561
+ const fileHandle = await this.indexDir.getFileHandle('hnsw-system.json');
1562
+ // Read the system data from the file
1563
+ const file = await fileHandle.getFile();
1564
+ const text = await file.text();
1565
+ return JSON.parse(text);
1566
+ }
1567
+ catch (error) {
1568
+ if (error.name === 'NotFoundError') {
1569
+ return null;
1570
+ }
1571
+ console.error('Failed to get HNSW system data:', error);
1572
+ throw new Error(`Failed to get HNSW system data: ${error}`);
1573
+ }
1574
+ }
1474
1575
  }
1475
1576
  //# sourceMappingURL=opfsStorage.js.map
@@ -572,4 +572,40 @@ export declare class S3CompatibleStorage extends BaseStorage {
572
572
  * @returns true (S3 is cloud storage)
573
573
  */
574
574
  protected isCloudStorage(): boolean;
575
+ /**
576
+ * Get a noun's vector for HNSW rebuild
577
+ */
578
+ getNounVector(id: string): Promise<number[] | null>;
579
+ /**
580
+ * Save HNSW graph data for a noun
581
+ * Storage path: entities/nouns/hnsw/{shard}/{id}.json
582
+ */
583
+ saveHNSWData(nounId: string, hnswData: {
584
+ level: number;
585
+ connections: Record<string, string[]>;
586
+ }): Promise<void>;
587
+ /**
588
+ * Get HNSW graph data for a noun
589
+ * Storage path: entities/nouns/hnsw/{shard}/{id}.json
590
+ */
591
+ getHNSWData(nounId: string): Promise<{
592
+ level: number;
593
+ connections: Record<string, string[]>;
594
+ } | null>;
595
+ /**
596
+ * Save HNSW system data (entry point, max level)
597
+ * Storage path: system/hnsw-system.json
598
+ */
599
+ saveHNSWSystem(systemData: {
600
+ entryPointId: string | null;
601
+ maxLevel: number;
602
+ }): Promise<void>;
603
+ /**
604
+ * Get HNSW system data (entry point, max level)
605
+ * Storage path: system/hnsw-system.json
606
+ */
607
+ getHNSWSystem(): Promise<{
608
+ entryPointId: string | null;
609
+ maxLevel: number;
610
+ } | null>;
575
611
  }
@@ -2765,5 +2765,117 @@ export class S3CompatibleStorage extends BaseStorage {
2765
2765
  isCloudStorage() {
2766
2766
  return true; // S3 benefits from batching
2767
2767
  }
2768
+ // HNSW Index Persistence (v3.35.0+)
2769
+ /**
2770
+ * Get a noun's vector for HNSW rebuild
2771
+ */
2772
+ async getNounVector(id) {
2773
+ await this.ensureInitialized();
2774
+ const noun = await this.getNode(id);
2775
+ return noun ? noun.vector : null;
2776
+ }
2777
+ /**
2778
+ * Save HNSW graph data for a noun
2779
+ * Storage path: entities/nouns/hnsw/{shard}/{id}.json
2780
+ */
2781
+ async saveHNSWData(nounId, hnswData) {
2782
+ await this.ensureInitialized();
2783
+ try {
2784
+ const { PutObjectCommand } = await import('@aws-sdk/client-s3');
2785
+ // Use sharded path for HNSW data
2786
+ const shard = getShardIdFromUuid(nounId);
2787
+ const key = `entities/nouns/hnsw/${shard}/${nounId}.json`;
2788
+ await this.s3Client.send(new PutObjectCommand({
2789
+ Bucket: this.bucketName,
2790
+ Key: key,
2791
+ Body: JSON.stringify(hnswData, null, 2),
2792
+ ContentType: 'application/json'
2793
+ }));
2794
+ }
2795
+ catch (error) {
2796
+ this.logger.error(`Failed to save HNSW data for ${nounId}:`, error);
2797
+ throw new Error(`Failed to save HNSW data for ${nounId}: ${error}`);
2798
+ }
2799
+ }
2800
+ /**
2801
+ * Get HNSW graph data for a noun
2802
+ * Storage path: entities/nouns/hnsw/{shard}/{id}.json
2803
+ */
2804
+ async getHNSWData(nounId) {
2805
+ await this.ensureInitialized();
2806
+ try {
2807
+ const { GetObjectCommand } = await import('@aws-sdk/client-s3');
2808
+ const shard = getShardIdFromUuid(nounId);
2809
+ const key = `entities/nouns/hnsw/${shard}/${nounId}.json`;
2810
+ const response = await this.s3Client.send(new GetObjectCommand({
2811
+ Bucket: this.bucketName,
2812
+ Key: key
2813
+ }));
2814
+ if (!response || !response.Body) {
2815
+ return null;
2816
+ }
2817
+ const bodyContents = await response.Body.transformToString();
2818
+ return JSON.parse(bodyContents);
2819
+ }
2820
+ catch (error) {
2821
+ if (error.name === 'NoSuchKey' ||
2822
+ error.message?.includes('NoSuchKey') ||
2823
+ error.message?.includes('not found')) {
2824
+ return null;
2825
+ }
2826
+ this.logger.error(`Failed to get HNSW data for ${nounId}:`, error);
2827
+ throw new Error(`Failed to get HNSW data for ${nounId}: ${error}`);
2828
+ }
2829
+ }
2830
+ /**
2831
+ * Save HNSW system data (entry point, max level)
2832
+ * Storage path: system/hnsw-system.json
2833
+ */
2834
+ async saveHNSWSystem(systemData) {
2835
+ await this.ensureInitialized();
2836
+ try {
2837
+ const { PutObjectCommand } = await import('@aws-sdk/client-s3');
2838
+ const key = `${this.systemPrefix}hnsw-system.json`;
2839
+ await this.s3Client.send(new PutObjectCommand({
2840
+ Bucket: this.bucketName,
2841
+ Key: key,
2842
+ Body: JSON.stringify(systemData, null, 2),
2843
+ ContentType: 'application/json'
2844
+ }));
2845
+ }
2846
+ catch (error) {
2847
+ this.logger.error('Failed to save HNSW system data:', error);
2848
+ throw new Error(`Failed to save HNSW system data: ${error}`);
2849
+ }
2850
+ }
2851
+ /**
2852
+ * Get HNSW system data (entry point, max level)
2853
+ * Storage path: system/hnsw-system.json
2854
+ */
2855
+ async getHNSWSystem() {
2856
+ await this.ensureInitialized();
2857
+ try {
2858
+ const { GetObjectCommand } = await import('@aws-sdk/client-s3');
2859
+ const key = `${this.systemPrefix}hnsw-system.json`;
2860
+ const response = await this.s3Client.send(new GetObjectCommand({
2861
+ Bucket: this.bucketName,
2862
+ Key: key
2863
+ }));
2864
+ if (!response || !response.Body) {
2865
+ return null;
2866
+ }
2867
+ const bodyContents = await response.Body.transformToString();
2868
+ return JSON.parse(bodyContents);
2869
+ }
2870
+ catch (error) {
2871
+ if (error.name === 'NoSuchKey' ||
2872
+ error.message?.includes('NoSuchKey') ||
2873
+ error.message?.includes('not found')) {
2874
+ return null;
2875
+ }
2876
+ this.logger.error('Failed to get HNSW system data:', error);
2877
+ throw new Error(`Failed to get HNSW system data: ${error}`);
2878
+ }
2879
+ }
2768
2880
  }
2769
2881
  //# sourceMappingURL=s3CompatibleStorage.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soulcraft/brainy",
3
- "version": "3.34.0",
3
+ "version": "3.35.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",