@soulcraft/brainy 0.9.12 → 0.9.14
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/README.md +23 -3
- package/dist/brainy.js +194 -39
- package/dist/brainy.min.js +746 -746
- package/dist/index.d.ts +2 -1
- package/dist/unified.js +194 -39
- package/dist/unified.min.js +746 -746
- package/dist/utils/environment.d.ts +1 -1
- package/dist/utils/version.d.ts +1 -1
- package/dist/utils/workerUtils.d.ts +5 -5
- package/package.json +9 -5
package/README.md
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
<br/><br/>
|
|
4
4
|
|
|
5
5
|
[](LICENSE)
|
|
6
|
-
[](https://nodejs.org/)
|
|
7
7
|
[](https://www.typescriptlang.org/)
|
|
8
8
|
[](CONTRIBUTING.md)
|
|
9
|
-
[](https://www.npmjs.com/package/@soulcraft/brainy)
|
|
10
10
|
|
|
11
11
|
[//]: # ([](https://github.com/sodal-project/cartographer))
|
|
12
12
|
|
|
@@ -1264,7 +1264,27 @@ comprehensive [Scaling Strategy](scalingStrategy.md) document.
|
|
|
1264
1264
|
|
|
1265
1265
|
## Requirements
|
|
1266
1266
|
|
|
1267
|
-
- Node.js >=
|
|
1267
|
+
- Node.js >= 24.0.0
|
|
1268
|
+
|
|
1269
|
+
### Node.js 24 Optimizations
|
|
1270
|
+
|
|
1271
|
+
Brainy takes advantage of several optimizations available in Node.js 24:
|
|
1272
|
+
|
|
1273
|
+
1. **Improved Worker Threads Performance**: The multithreading system has been completely rewritten to leverage Node.js 24's enhanced Worker Threads API, resulting in better performance for compute-intensive operations like embedding generation and vector similarity calculations.
|
|
1274
|
+
|
|
1275
|
+
2. **Worker Pool Management**: A sophisticated worker pool system reuses worker threads to minimize the overhead of creating and destroying threads, leading to more efficient resource utilization.
|
|
1276
|
+
|
|
1277
|
+
3. **Dynamic Module Imports**: Uses the new `node:` protocol prefix for importing core modules, which provides better performance and more reliable module resolution.
|
|
1278
|
+
|
|
1279
|
+
4. **ES Modules Optimizations**: Takes advantage of Node.js 24's improved ESM implementation for faster module loading and execution.
|
|
1280
|
+
|
|
1281
|
+
5. **Enhanced Error Handling**: Implements more robust error handling patterns available in Node.js 24 for better stability and debugging.
|
|
1282
|
+
|
|
1283
|
+
These optimizations are particularly beneficial for:
|
|
1284
|
+
- Large-scale vector operations
|
|
1285
|
+
- Batch processing of embeddings
|
|
1286
|
+
- Real-time data processing pipelines
|
|
1287
|
+
- High-throughput search operations
|
|
1268
1288
|
|
|
1269
1289
|
## Contributing
|
|
1270
1290
|
|
package/dist/brainy.js
CHANGED
|
@@ -2672,33 +2672,213 @@ async function calculateDistancesBatch(queryVector, vectors, distanceFunction =
|
|
|
2672
2672
|
}
|
|
2673
2673
|
|
|
2674
2674
|
/**
|
|
2675
|
-
* Utility functions for
|
|
2676
|
-
|
|
2675
|
+
* Utility functions for environment detection
|
|
2676
|
+
*/
|
|
2677
|
+
/**
|
|
2678
|
+
* Check if code is running in a browser environment
|
|
2679
|
+
*/
|
|
2680
|
+
function isBrowser$1() {
|
|
2681
|
+
return typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
2682
|
+
}
|
|
2683
|
+
/**
|
|
2684
|
+
* Check if code is running in a Node.js environment
|
|
2685
|
+
*/
|
|
2686
|
+
function isNode() {
|
|
2687
|
+
return typeof process !== 'undefined' &&
|
|
2688
|
+
process.versions != null &&
|
|
2689
|
+
process.versions.node != null;
|
|
2690
|
+
}
|
|
2691
|
+
/**
|
|
2692
|
+
* Check if Web Workers are available in the current environment
|
|
2693
|
+
*/
|
|
2694
|
+
function areWebWorkersAvailable() {
|
|
2695
|
+
return isBrowser$1() && typeof Worker !== 'undefined';
|
|
2696
|
+
}
|
|
2697
|
+
/**
|
|
2698
|
+
* Check if Worker Threads are available in the current environment (Node.js)
|
|
2699
|
+
*/
|
|
2700
|
+
function areWorkerThreadsAvailable() {
|
|
2701
|
+
if (!isNode())
|
|
2702
|
+
return false;
|
|
2703
|
+
try {
|
|
2704
|
+
// Dynamic import to avoid errors in browser environments
|
|
2705
|
+
require('worker_threads');
|
|
2706
|
+
return true;
|
|
2707
|
+
}
|
|
2708
|
+
catch (e) {
|
|
2709
|
+
return false;
|
|
2710
|
+
}
|
|
2711
|
+
}
|
|
2712
|
+
/**
|
|
2713
|
+
* Determine if threading is available in the current environment
|
|
2714
|
+
* Returns true if either Web Workers (browser) or Worker Threads (Node.js) are available
|
|
2715
|
+
*/
|
|
2716
|
+
function isThreadingAvailable() {
|
|
2717
|
+
return areWebWorkersAvailable() || areWorkerThreadsAvailable();
|
|
2718
|
+
}
|
|
2719
|
+
|
|
2720
|
+
/**
|
|
2721
|
+
* Utility functions for executing functions in Worker Threads (Node.js) or Web Workers (Browser)
|
|
2722
|
+
* This implementation leverages Node.js 24's improved Worker Threads API for better performance
|
|
2677
2723
|
*/
|
|
2724
|
+
// Worker pool to reuse workers
|
|
2725
|
+
const workerPool = new Map();
|
|
2726
|
+
const MAX_POOL_SIZE = 4; // Adjust based on system capabilities
|
|
2678
2727
|
/**
|
|
2679
|
-
* Execute a function
|
|
2728
|
+
* Execute a function in a separate thread
|
|
2680
2729
|
*
|
|
2681
2730
|
* @param fnString The function to execute as a string
|
|
2682
2731
|
* @param args The arguments to pass to the function
|
|
2683
2732
|
* @returns A promise that resolves with the result of the function
|
|
2684
2733
|
*/
|
|
2685
2734
|
function executeInThread(fnString, args) {
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
const fn = new Function('return ' + fnString)();
|
|
2689
|
-
return Promise.resolve(fn(args));
|
|
2735
|
+
if (isNode()) {
|
|
2736
|
+
return executeInNodeWorker(fnString, args);
|
|
2690
2737
|
}
|
|
2691
|
-
|
|
2692
|
-
return
|
|
2738
|
+
else if (isBrowser$1() && typeof window !== 'undefined' && window.Worker) {
|
|
2739
|
+
return executeInWebWorker(fnString, args);
|
|
2693
2740
|
}
|
|
2741
|
+
else {
|
|
2742
|
+
// Fallback to main thread execution
|
|
2743
|
+
try {
|
|
2744
|
+
const fn = new Function('return ' + fnString)();
|
|
2745
|
+
return Promise.resolve(fn(args));
|
|
2746
|
+
}
|
|
2747
|
+
catch (error) {
|
|
2748
|
+
return Promise.reject(error);
|
|
2749
|
+
}
|
|
2750
|
+
}
|
|
2751
|
+
}
|
|
2752
|
+
/**
|
|
2753
|
+
* Execute a function in a Node.js Worker Thread
|
|
2754
|
+
* Optimized for Node.js 24 with improved Worker Threads performance
|
|
2755
|
+
*/
|
|
2756
|
+
function executeInNodeWorker(fnString, args) {
|
|
2757
|
+
return new Promise((resolve, reject) => {
|
|
2758
|
+
try {
|
|
2759
|
+
// Dynamically import worker_threads (Node.js only)
|
|
2760
|
+
import('node:worker_threads').then(({ Worker, isMainThread, parentPort, workerData }) => {
|
|
2761
|
+
if (!isMainThread && parentPort) {
|
|
2762
|
+
// We're inside a worker, execute the function
|
|
2763
|
+
const fn = new Function('return ' + workerData.fnString)();
|
|
2764
|
+
const result = fn(workerData.args);
|
|
2765
|
+
parentPort.postMessage({ result });
|
|
2766
|
+
return;
|
|
2767
|
+
}
|
|
2768
|
+
// Get a worker from the pool or create a new one
|
|
2769
|
+
const workerId = `worker-${Math.random().toString(36).substring(2, 9)}`;
|
|
2770
|
+
let worker;
|
|
2771
|
+
if (workerPool.size < MAX_POOL_SIZE) {
|
|
2772
|
+
// Create a new worker
|
|
2773
|
+
worker = new Worker(`
|
|
2774
|
+
import { parentPort, workerData } from 'node:worker_threads';
|
|
2775
|
+
const fn = new Function('return ' + workerData.fnString)();
|
|
2776
|
+
const result = fn(workerData.args);
|
|
2777
|
+
parentPort.postMessage({ result });
|
|
2778
|
+
`, {
|
|
2779
|
+
eval: true,
|
|
2780
|
+
workerData: { fnString, args }
|
|
2781
|
+
});
|
|
2782
|
+
workerPool.set(workerId, worker);
|
|
2783
|
+
}
|
|
2784
|
+
else {
|
|
2785
|
+
// Reuse an existing worker
|
|
2786
|
+
const poolKeys = Array.from(workerPool.keys());
|
|
2787
|
+
const randomKey = poolKeys[Math.floor(Math.random() * poolKeys.length)];
|
|
2788
|
+
worker = workerPool.get(randomKey);
|
|
2789
|
+
// Terminate and recreate if the worker is busy
|
|
2790
|
+
if (worker._busy) {
|
|
2791
|
+
worker.terminate();
|
|
2792
|
+
worker = new Worker(`
|
|
2793
|
+
import { parentPort, workerData } from 'node:worker_threads';
|
|
2794
|
+
const fn = new Function('return ' + workerData.fnString)();
|
|
2795
|
+
const result = fn(workerData.args);
|
|
2796
|
+
parentPort.postMessage({ result });
|
|
2797
|
+
`, {
|
|
2798
|
+
eval: true,
|
|
2799
|
+
workerData: { fnString, args }
|
|
2800
|
+
});
|
|
2801
|
+
workerPool.set(randomKey, worker);
|
|
2802
|
+
}
|
|
2803
|
+
worker._busy = true;
|
|
2804
|
+
}
|
|
2805
|
+
worker.on('message', (message) => {
|
|
2806
|
+
worker._busy = false;
|
|
2807
|
+
resolve(message.result);
|
|
2808
|
+
});
|
|
2809
|
+
worker.on('error', (err) => {
|
|
2810
|
+
worker._busy = false;
|
|
2811
|
+
reject(err);
|
|
2812
|
+
});
|
|
2813
|
+
worker.on('exit', (code) => {
|
|
2814
|
+
if (code !== 0) {
|
|
2815
|
+
worker._busy = false;
|
|
2816
|
+
reject(new Error(`Worker stopped with exit code ${code}`));
|
|
2817
|
+
}
|
|
2818
|
+
});
|
|
2819
|
+
}).catch(reject);
|
|
2820
|
+
}
|
|
2821
|
+
catch (error) {
|
|
2822
|
+
reject(error);
|
|
2823
|
+
}
|
|
2824
|
+
});
|
|
2825
|
+
}
|
|
2826
|
+
/**
|
|
2827
|
+
* Execute a function in a Web Worker (Browser environment)
|
|
2828
|
+
*/
|
|
2829
|
+
function executeInWebWorker(fnString, args) {
|
|
2830
|
+
return new Promise((resolve, reject) => {
|
|
2831
|
+
try {
|
|
2832
|
+
const workerCode = `
|
|
2833
|
+
self.onmessage = function(e) {
|
|
2834
|
+
try {
|
|
2835
|
+
const fn = new Function('return ' + e.data.fnString)();
|
|
2836
|
+
const result = fn(e.data.args);
|
|
2837
|
+
self.postMessage({ result: result });
|
|
2838
|
+
} catch (error) {
|
|
2839
|
+
self.postMessage({ error: error.message });
|
|
2840
|
+
}
|
|
2841
|
+
};
|
|
2842
|
+
`;
|
|
2843
|
+
const blob = new Blob([workerCode], { type: 'application/javascript' });
|
|
2844
|
+
const url = URL.createObjectURL(blob);
|
|
2845
|
+
const worker = new Worker(url);
|
|
2846
|
+
worker.onmessage = function (e) {
|
|
2847
|
+
if (e.data.error) {
|
|
2848
|
+
reject(new Error(e.data.error));
|
|
2849
|
+
}
|
|
2850
|
+
else {
|
|
2851
|
+
resolve(e.data.result);
|
|
2852
|
+
}
|
|
2853
|
+
worker.terminate();
|
|
2854
|
+
URL.revokeObjectURL(url);
|
|
2855
|
+
};
|
|
2856
|
+
worker.onerror = function (e) {
|
|
2857
|
+
reject(new Error(`Worker error: ${e.message}`));
|
|
2858
|
+
worker.terminate();
|
|
2859
|
+
URL.revokeObjectURL(url);
|
|
2860
|
+
};
|
|
2861
|
+
worker.postMessage({ fnString, args });
|
|
2862
|
+
}
|
|
2863
|
+
catch (error) {
|
|
2864
|
+
reject(error);
|
|
2865
|
+
}
|
|
2866
|
+
});
|
|
2694
2867
|
}
|
|
2695
2868
|
/**
|
|
2696
|
-
*
|
|
2697
|
-
* This
|
|
2869
|
+
* Clean up all worker pools
|
|
2870
|
+
* This should be called when the application is shutting down
|
|
2698
2871
|
*/
|
|
2699
2872
|
function cleanupWorkerPools() {
|
|
2700
|
-
|
|
2701
|
-
|
|
2873
|
+
if (isNode()) {
|
|
2874
|
+
import('node:worker_threads').then(({ Worker }) => {
|
|
2875
|
+
for (const worker of workerPool.values()) {
|
|
2876
|
+
worker.terminate();
|
|
2877
|
+
}
|
|
2878
|
+
workerPool.clear();
|
|
2879
|
+
console.log('Worker pools cleaned up');
|
|
2880
|
+
}).catch(console.error);
|
|
2881
|
+
}
|
|
2702
2882
|
}
|
|
2703
2883
|
|
|
2704
2884
|
/**
|
|
@@ -10856,31 +11036,6 @@ var s3CompatibleStorage = /*#__PURE__*/Object.freeze({
|
|
|
10856
11036
|
S3CompatibleStorage: S3CompatibleStorage
|
|
10857
11037
|
});
|
|
10858
11038
|
|
|
10859
|
-
/**
|
|
10860
|
-
* Utility functions for environment detection
|
|
10861
|
-
*/
|
|
10862
|
-
/**
|
|
10863
|
-
* Check if code is running in a browser environment
|
|
10864
|
-
*/
|
|
10865
|
-
function isBrowser$1() {
|
|
10866
|
-
return typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
10867
|
-
}
|
|
10868
|
-
/**
|
|
10869
|
-
* Check if code is running in a Node.js environment
|
|
10870
|
-
*/
|
|
10871
|
-
function isNode() {
|
|
10872
|
-
return typeof process !== 'undefined' &&
|
|
10873
|
-
process.versions != null &&
|
|
10874
|
-
process.versions.node != null;
|
|
10875
|
-
}
|
|
10876
|
-
/**
|
|
10877
|
-
* Determine if threading is available in the current environment
|
|
10878
|
-
* Always returns false since multithreading has been removed
|
|
10879
|
-
*/
|
|
10880
|
-
function isThreadingAvailable() {
|
|
10881
|
-
return false;
|
|
10882
|
-
}
|
|
10883
|
-
|
|
10884
11039
|
/**
|
|
10885
11040
|
* Augmentation Registry
|
|
10886
11041
|
*
|
|
@@ -87036,5 +87191,5 @@ var _child_processShim = /*#__PURE__*/Object.freeze({
|
|
|
87036
87191
|
__proto__: null
|
|
87037
87192
|
});
|
|
87038
87193
|
|
|
87039
|
-
export { AugmentationType, BrainyData, BrainyMCPAdapter, BrainyMCPService, ExecutionMode$1 as ExecutionMode, FileSystemStorage, FileSystemStorageAugmentation, HNSWIndex, HNSWIndexOptimized, MCPAugmentationToolset, MCPRequestType, MCP_VERSION, MemoryStorage, MemoryStorageAugmentation, NounType, OPFSStorage, OPFSStorageAugmentation, Pipeline, S3CompatibleStorage as R2Storage, S3CompatibleStorage, SequentialPipeline, ServerSearchActivationAugmentation, ServerSearchConduitAugmentation, StreamlinedExecutionMode, UniversalSentenceEncoder$1 as UniversalSentenceEncoder, VerbType, WebRTCConduitAugmentation, WebSocketConduitAugmentation, addWebSocketSupport, augmentationPipeline$1 as augmentationPipeline, availableAugmentations, cosineDistance$1 as cosineDistance, createAugmentationRegistryPlugin, createAugmentationRegistryRollupPlugin, createConduitAugmentation, createEmbeddingFunction, createMemoryAugmentation, createPipeline, createSenseAugmentation, createServerSearchAugmentations, createStorage, createStreamingPipeline, createTensorFlowEmbeddingFunction, createThreadedEmbeddingFunction, defaultEmbeddingFunction, dotProductDistance, environment, euclideanDistance, executeAugmentation, executeByType, executeSingle, executeStreamlined, getAugmentationsByType, initializeAugmentationPipeline, loadAugmentationModule, loadAugmentationsFromModules, manhattanDistance, pipeline, processStaticData, processStreamingData, registerAugmentation, sequentialPipeline, setAugmentationEnabled };
|
|
87194
|
+
export { AugmentationType, BrainyData, BrainyMCPAdapter, BrainyMCPService, ExecutionMode$1 as ExecutionMode, FileSystemStorage, FileSystemStorageAugmentation, HNSWIndex, HNSWIndexOptimized, MCPAugmentationToolset, MCPRequestType, MCP_VERSION, MemoryStorage, MemoryStorageAugmentation, NounType, OPFSStorage, OPFSStorageAugmentation, Pipeline, S3CompatibleStorage as R2Storage, S3CompatibleStorage, SequentialPipeline, ServerSearchActivationAugmentation, ServerSearchConduitAugmentation, StreamlinedExecutionMode, UniversalSentenceEncoder$1 as UniversalSentenceEncoder, VerbType, WebRTCConduitAugmentation, WebSocketConduitAugmentation, addWebSocketSupport, augmentationPipeline$1 as augmentationPipeline, availableAugmentations, cleanupWorkerPools, cosineDistance$1 as cosineDistance, createAugmentationRegistryPlugin, createAugmentationRegistryRollupPlugin, createConduitAugmentation, createEmbeddingFunction, createMemoryAugmentation, createPipeline, createSenseAugmentation, createServerSearchAugmentations, createStorage, createStreamingPipeline, createTensorFlowEmbeddingFunction, createThreadedEmbeddingFunction, defaultEmbeddingFunction, dotProductDistance, environment, euclideanDistance, executeAugmentation, executeByType, executeInThread, executeSingle, executeStreamlined, getAugmentationsByType, initializeAugmentationPipeline, loadAugmentationModule, loadAugmentationsFromModules, manhattanDistance, pipeline, processStaticData, processStreamingData, registerAugmentation, sequentialPipeline, setAugmentationEnabled };
|
|
87040
87195
|
//# sourceMappingURL=brainy.js.map
|