@soulcraft/brainy 0.9.37 → 0.11.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.
- package/README.demo.md +1 -1
- package/README.md +2 -6
- package/dist/augmentations/huggingfaceActivation.d.ts +57 -0
- package/dist/augmentations/huggingfaceActivation.d.ts.map +1 -0
- package/dist/augmentations/huggingfaceActivationRegistration.d.ts +6 -0
- package/dist/augmentations/huggingfaceActivationRegistration.d.ts.map +1 -0
- package/dist/brainy.js +564 -815
- package/dist/brainy.min.js +748 -749
- package/dist/index.d.ts +3 -2
- package/dist/setup.d.ts +1 -0
- package/dist/storage/fileSystemStorage.d.ts +27 -69
- package/dist/storage/fileSystemStorage.d.ts.map +1 -1
- package/dist/types/tensorflowTypes.d.ts +10 -2
- package/dist/types/tensorflowTypes.d.ts.map +1 -1
- package/dist/unified.js +565 -816
- package/dist/unified.min.js +748 -749
- package/dist/utils/embedding.d.ts.map +1 -1
- package/dist/utils/huggingfaceEmbedding.d.ts +53 -0
- package/dist/utils/huggingfaceEmbedding.d.ts.map +1 -0
- package/dist/utils/tensorflowBridge.d.ts +14 -0
- package/dist/utils/tensorflowBridge.d.ts.map +1 -0
- package/dist/utils/tensorflowUtils.d.ts.map +1 -1
- package/dist/utils/textEncoding.d.ts +6 -51
- package/dist/utils/textEncoding.d.ts.map +1 -1
- package/dist/utils/universalDebug.d.ts +21 -0
- package/dist/utils/universalDebug.d.ts.map +1 -0
- package/dist/utils/universalUuid.d.ts +26 -0
- package/dist/utils/universalUuid.d.ts.map +1 -0
- package/dist/utils/version.d.ts +1 -1
- package/dist/utils/workerUtils.d.ts.map +1 -1
- package/package.json +17 -8
- package/CHANGELOG.md +0 -20
package/dist/unified.js
CHANGED
|
@@ -2398,133 +2398,84 @@ ieee754.write = function (buffer, value, offset, isLE, mLen, nBytes) {
|
|
|
2398
2398
|
* Unified Text Encoding Utilities
|
|
2399
2399
|
*
|
|
2400
2400
|
* This module provides a consistent way to handle text encoding/decoding across all environments
|
|
2401
|
-
*
|
|
2401
|
+
* using the native TextEncoder/TextDecoder APIs.
|
|
2402
2402
|
*/
|
|
2403
|
-
/**
|
|
2404
|
-
* A simple text encoder that works in all environments
|
|
2405
|
-
* This avoids the need for TextEncoder polyfills and patches
|
|
2406
|
-
*/
|
|
2407
|
-
class SimpleTextEncoder {
|
|
2408
|
-
/**
|
|
2409
|
-
* Encode a string to a Uint8Array
|
|
2410
|
-
* @param input - The string to encode
|
|
2411
|
-
* @returns A Uint8Array containing the encoded string
|
|
2412
|
-
*/
|
|
2413
|
-
encode(input) {
|
|
2414
|
-
// Simple UTF-8 encoding implementation that works everywhere
|
|
2415
|
-
return new Uint8Array([...input].map((c) => c.charCodeAt(0)));
|
|
2416
|
-
}
|
|
2417
|
-
}
|
|
2418
|
-
/**
|
|
2419
|
-
* A simple text decoder that works in all environments
|
|
2420
|
-
* This avoids the need for TextDecoder polyfills and patches
|
|
2421
|
-
*/
|
|
2422
|
-
class SimpleTextDecoder {
|
|
2423
|
-
/**
|
|
2424
|
-
* Decode a Uint8Array to a string
|
|
2425
|
-
* @param input - The Uint8Array to decode
|
|
2426
|
-
* @returns The decoded string
|
|
2427
|
-
*/
|
|
2428
|
-
decode(input) {
|
|
2429
|
-
// Simple UTF-8 decoding implementation that works everywhere
|
|
2430
|
-
return String.fromCharCode.apply(null, [...input]);
|
|
2431
|
-
}
|
|
2432
|
-
}
|
|
2433
|
-
/**
|
|
2434
|
-
* A constructor function for TextEncoder that works in all environments
|
|
2435
|
-
*/
|
|
2436
|
-
function UniversalTextEncoder() {
|
|
2437
|
-
if (!(this instanceof UniversalTextEncoder)) {
|
|
2438
|
-
return new UniversalTextEncoder();
|
|
2439
|
-
}
|
|
2440
|
-
try {
|
|
2441
|
-
// Try to use the native TextEncoder if available
|
|
2442
|
-
const nativeEncoder = new TextEncoder();
|
|
2443
|
-
this.encode = nativeEncoder.encode.bind(nativeEncoder);
|
|
2444
|
-
}
|
|
2445
|
-
catch (e) {
|
|
2446
|
-
// Fall back to our simple implementation
|
|
2447
|
-
const simpleEncoder = new SimpleTextEncoder();
|
|
2448
|
-
this.encode = simpleEncoder.encode.bind(simpleEncoder);
|
|
2449
|
-
}
|
|
2450
|
-
}
|
|
2451
|
-
/**
|
|
2452
|
-
* A constructor function for TextDecoder that works in all environments
|
|
2453
|
-
*/
|
|
2454
|
-
function UniversalTextDecoder() {
|
|
2455
|
-
if (!(this instanceof UniversalTextDecoder)) {
|
|
2456
|
-
return new UniversalTextDecoder();
|
|
2457
|
-
}
|
|
2458
|
-
try {
|
|
2459
|
-
// Try to use the native TextDecoder if available
|
|
2460
|
-
const nativeDecoder = new TextDecoder();
|
|
2461
|
-
this.decode = nativeDecoder.decode.bind(nativeDecoder);
|
|
2462
|
-
}
|
|
2463
|
-
catch (e) {
|
|
2464
|
-
// Fall back to our simple implementation
|
|
2465
|
-
const simpleDecoder = new SimpleTextDecoder();
|
|
2466
|
-
this.decode = simpleDecoder.decode.bind(simpleDecoder);
|
|
2467
|
-
}
|
|
2468
|
-
}
|
|
2469
2403
|
/**
|
|
2470
2404
|
* Get a text encoder that works in the current environment
|
|
2471
|
-
* @returns A
|
|
2405
|
+
* @returns A TextEncoder instance
|
|
2472
2406
|
*/
|
|
2473
|
-
function getTextEncoder() {
|
|
2474
|
-
return new UniversalTextEncoder();
|
|
2475
|
-
}
|
|
2476
|
-
/**
|
|
2477
|
-
* Get a text decoder that works in the current environment
|
|
2478
|
-
* @returns A text decoder object with a decode method
|
|
2479
|
-
*/
|
|
2480
|
-
function getTextDecoder() {
|
|
2481
|
-
return new UniversalTextDecoder();
|
|
2482
|
-
}
|
|
2483
2407
|
/**
|
|
2484
2408
|
* Apply the TensorFlow.js platform patch if needed
|
|
2485
2409
|
* This function patches the global object to provide a PlatformNode class
|
|
2486
|
-
* that uses
|
|
2410
|
+
* that uses native TextEncoder/TextDecoder
|
|
2487
2411
|
*/
|
|
2488
2412
|
function applyTensorFlowPatch() {
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2413
|
+
try {
|
|
2414
|
+
// Define a custom Platform class that works in both Node.js and browser environments
|
|
2415
|
+
class Platform {
|
|
2416
|
+
constructor() {
|
|
2417
|
+
// Create a util object with necessary methods and constructors
|
|
2418
|
+
this.util = {
|
|
2419
|
+
// Use native TextEncoder and TextDecoder
|
|
2420
|
+
TextEncoder: globalThis.TextEncoder || TextEncoder,
|
|
2421
|
+
TextDecoder: globalThis.TextDecoder || TextDecoder
|
|
2422
|
+
};
|
|
2423
|
+
// Initialize using native constructors directly
|
|
2424
|
+
this.textEncoder = new (globalThis.TextEncoder || TextEncoder)();
|
|
2425
|
+
this.textDecoder = new (globalThis.TextDecoder || TextDecoder)();
|
|
2426
|
+
}
|
|
2427
|
+
// Define isFloat32Array directly on the instance
|
|
2428
|
+
isFloat32Array(arr) {
|
|
2429
|
+
return !!(arr instanceof Float32Array ||
|
|
2430
|
+
(arr &&
|
|
2431
|
+
Object.prototype.toString.call(arr) === '[object Float32Array]'));
|
|
2432
|
+
}
|
|
2433
|
+
// Define isTypedArray directly on the instance
|
|
2434
|
+
isTypedArray(arr) {
|
|
2435
|
+
return !!(ArrayBuffer.isView(arr) && !(arr instanceof DataView));
|
|
2436
|
+
}
|
|
2437
|
+
}
|
|
2438
|
+
// Get the global object in a way that works in both Node.js and browser
|
|
2439
|
+
const globalObj = typeof global !== 'undefined'
|
|
2440
|
+
? global
|
|
2441
|
+
: typeof window !== 'undefined'
|
|
2442
|
+
? window
|
|
2443
|
+
: typeof self !== 'undefined'
|
|
2444
|
+
? self
|
|
2445
|
+
: {};
|
|
2446
|
+
// Only apply in Node.js environment
|
|
2447
|
+
if (typeof process !== 'undefined' &&
|
|
2448
|
+
process.versions &&
|
|
2449
|
+
process.versions.node) {
|
|
2450
|
+
// Assign the Platform class to the global object as PlatformNode for Node.js
|
|
2518
2451
|
;
|
|
2519
|
-
|
|
2520
|
-
|
|
2452
|
+
globalObj.PlatformNode = Platform;
|
|
2453
|
+
globalObj.platformNode = new Platform();
|
|
2521
2454
|
}
|
|
2522
|
-
|
|
2523
|
-
|
|
2455
|
+
else if (typeof window !== 'undefined' || typeof self !== 'undefined') {
|
|
2456
|
+
// In browser environments, we might need to provide similar functionality
|
|
2457
|
+
// but we'll use a different name to avoid conflicts
|
|
2458
|
+
;
|
|
2459
|
+
globalObj.PlatformBrowser = Platform;
|
|
2460
|
+
globalObj.platformBrowser = new Platform();
|
|
2524
2461
|
}
|
|
2525
2462
|
}
|
|
2463
|
+
catch (error) {
|
|
2464
|
+
console.warn('Failed to apply TensorFlow.js platform patch:', error);
|
|
2465
|
+
}
|
|
2526
2466
|
}
|
|
2527
2467
|
|
|
2468
|
+
/**
|
|
2469
|
+
* This file is imported for its side effects to patch the environment
|
|
2470
|
+
* for TensorFlow.js before any other library code runs.
|
|
2471
|
+
*
|
|
2472
|
+
* It ensures that by the time TensorFlow.js is imported by any other
|
|
2473
|
+
* module, the necessary compatibility fixes for the current Node.js
|
|
2474
|
+
* environment are already in place.
|
|
2475
|
+
*/
|
|
2476
|
+
// Apply the TensorFlow.js platform patch if needed
|
|
2477
|
+
applyTensorFlowPatch();
|
|
2478
|
+
|
|
2528
2479
|
// Unique ID creation requires a high quality random # generator. In the browser we therefore
|
|
2529
2480
|
// require the crypto API and do not support built-in fallback to lower quality random number
|
|
2530
2481
|
// generators (like Math.random()).
|
|
@@ -2853,7 +2804,7 @@ async function areWorkerThreadsAvailable() {
|
|
|
2853
2804
|
function areWorkerThreadsAvailableSync() {
|
|
2854
2805
|
if (!isNode())
|
|
2855
2806
|
return false;
|
|
2856
|
-
// In Node.js 24.
|
|
2807
|
+
// In Node.js 24.4.0+, worker_threads is always available
|
|
2857
2808
|
return parseInt(process.versions.node.split('.')[0]) >= 24;
|
|
2858
2809
|
}
|
|
2859
2810
|
/**
|
|
@@ -2913,9 +2864,16 @@ function executeInThread(fnString, args) {
|
|
|
2913
2864
|
fn = new Function(fnString)();
|
|
2914
2865
|
}
|
|
2915
2866
|
catch (directError) {
|
|
2916
|
-
console.
|
|
2917
|
-
|
|
2918
|
-
|
|
2867
|
+
console.warn('Fallback: Direct approach failed, trying with function wrapper', directError);
|
|
2868
|
+
try {
|
|
2869
|
+
// Try wrapping in a function that returns the function expression
|
|
2870
|
+
fn = new Function('return function(args) { return (' + fnString + ')(args); }')();
|
|
2871
|
+
}
|
|
2872
|
+
catch (wrapperError) {
|
|
2873
|
+
console.error('Fallback: All approaches to create function failed', wrapperError);
|
|
2874
|
+
throw new Error('Failed to create function from string: ' +
|
|
2875
|
+
functionError.message);
|
|
2876
|
+
}
|
|
2919
2877
|
}
|
|
2920
2878
|
}
|
|
2921
2879
|
}
|
|
@@ -2950,6 +2908,82 @@ function executeInNodeWorker(fnString, args) {
|
|
|
2950
2908
|
// Create a new worker
|
|
2951
2909
|
worker = new Worker(`
|
|
2952
2910
|
import { parentPort, workerData } from 'node:worker_threads';
|
|
2911
|
+
|
|
2912
|
+
// Add TensorFlow.js platform patch for Node.js
|
|
2913
|
+
if (typeof global !== 'undefined') {
|
|
2914
|
+
try {
|
|
2915
|
+
// Define a custom PlatformNode class
|
|
2916
|
+
class PlatformNode {
|
|
2917
|
+
constructor() {
|
|
2918
|
+
// Create a util object with necessary methods
|
|
2919
|
+
this.util = {
|
|
2920
|
+
// Add isFloat32Array and isTypedArray directly to util
|
|
2921
|
+
isFloat32Array: (arr) => {
|
|
2922
|
+
return !!(
|
|
2923
|
+
arr instanceof Float32Array ||
|
|
2924
|
+
(arr &&
|
|
2925
|
+
Object.prototype.toString.call(arr) === '[object Float32Array]')
|
|
2926
|
+
);
|
|
2927
|
+
},
|
|
2928
|
+
isTypedArray: (arr) => {
|
|
2929
|
+
return !!(ArrayBuffer.isView(arr) && !(arr instanceof DataView));
|
|
2930
|
+
},
|
|
2931
|
+
// Use native TextEncoder and TextDecoder
|
|
2932
|
+
TextEncoder: TextEncoder,
|
|
2933
|
+
TextDecoder: TextDecoder
|
|
2934
|
+
};
|
|
2935
|
+
|
|
2936
|
+
// Initialize encoders using native constructors
|
|
2937
|
+
this.textEncoder = new TextEncoder();
|
|
2938
|
+
this.textDecoder = new TextDecoder();
|
|
2939
|
+
}
|
|
2940
|
+
|
|
2941
|
+
// Define isFloat32Array directly on the instance
|
|
2942
|
+
isFloat32Array(arr) {
|
|
2943
|
+
return !!(
|
|
2944
|
+
arr instanceof Float32Array ||
|
|
2945
|
+
(arr && Object.prototype.toString.call(arr) === '[object Float32Array]')
|
|
2946
|
+
);
|
|
2947
|
+
}
|
|
2948
|
+
|
|
2949
|
+
// Define isTypedArray directly on the instance
|
|
2950
|
+
isTypedArray(arr) {
|
|
2951
|
+
return !!(ArrayBuffer.isView(arr) && !(arr instanceof DataView));
|
|
2952
|
+
}
|
|
2953
|
+
}
|
|
2954
|
+
|
|
2955
|
+
// Assign the PlatformNode class to the global object
|
|
2956
|
+
global.PlatformNode = PlatformNode;
|
|
2957
|
+
|
|
2958
|
+
// Also create an instance and assign it to global.platformNode
|
|
2959
|
+
global.platformNode = new PlatformNode();
|
|
2960
|
+
|
|
2961
|
+
// Ensure global.util exists and has the necessary methods
|
|
2962
|
+
if (!global.util) {
|
|
2963
|
+
global.util = {};
|
|
2964
|
+
}
|
|
2965
|
+
|
|
2966
|
+
// Add isFloat32Array method if it doesn't exist
|
|
2967
|
+
if (!global.util.isFloat32Array) {
|
|
2968
|
+
global.util.isFloat32Array = (arr) => {
|
|
2969
|
+
return !!(
|
|
2970
|
+
arr instanceof Float32Array ||
|
|
2971
|
+
(arr && Object.prototype.toString.call(arr) === '[object Float32Array]')
|
|
2972
|
+
);
|
|
2973
|
+
};
|
|
2974
|
+
}
|
|
2975
|
+
|
|
2976
|
+
// Add isTypedArray method if it doesn't exist
|
|
2977
|
+
if (!global.util.isTypedArray) {
|
|
2978
|
+
global.util.isTypedArray = (arr) => {
|
|
2979
|
+
return !!(ArrayBuffer.isView(arr) && !(arr instanceof DataView));
|
|
2980
|
+
};
|
|
2981
|
+
}
|
|
2982
|
+
} catch (error) {
|
|
2983
|
+
console.warn('Failed to apply TensorFlow.js platform patch:', error);
|
|
2984
|
+
}
|
|
2985
|
+
}
|
|
2986
|
+
|
|
2953
2987
|
const fn = new Function('return ' + workerData.fnString)();
|
|
2954
2988
|
const result = fn(workerData.args);
|
|
2955
2989
|
parentPort.postMessage({ result });
|
|
@@ -2969,6 +3003,71 @@ function executeInNodeWorker(fnString, args) {
|
|
|
2969
3003
|
worker.terminate();
|
|
2970
3004
|
worker = new Worker(`
|
|
2971
3005
|
import { parentPort, workerData } from 'node:worker_threads';
|
|
3006
|
+
|
|
3007
|
+
// Add TensorFlow.js platform patch for Node.js
|
|
3008
|
+
if (typeof global !== 'undefined') {
|
|
3009
|
+
try {
|
|
3010
|
+
// Define a custom PlatformNode class
|
|
3011
|
+
class PlatformNode {
|
|
3012
|
+
constructor() {
|
|
3013
|
+
// Create a util object with necessary methods
|
|
3014
|
+
this.util = {
|
|
3015
|
+
// Use native TextEncoder and TextDecoder
|
|
3016
|
+
TextEncoder: TextEncoder,
|
|
3017
|
+
TextDecoder: TextDecoder
|
|
3018
|
+
};
|
|
3019
|
+
|
|
3020
|
+
// Initialize encoders using native constructors
|
|
3021
|
+
this.textEncoder = new TextEncoder();
|
|
3022
|
+
this.textDecoder = new TextDecoder();
|
|
3023
|
+
}
|
|
3024
|
+
|
|
3025
|
+
// Define isFloat32Array directly on the instance
|
|
3026
|
+
isFloat32Array(arr) {
|
|
3027
|
+
return !!(
|
|
3028
|
+
arr instanceof Float32Array ||
|
|
3029
|
+
(arr && Object.prototype.toString.call(arr) === '[object Float32Array]')
|
|
3030
|
+
);
|
|
3031
|
+
}
|
|
3032
|
+
|
|
3033
|
+
// Define isTypedArray directly on the instance
|
|
3034
|
+
isTypedArray(arr) {
|
|
3035
|
+
return !!(ArrayBuffer.isView(arr) && !(arr instanceof DataView));
|
|
3036
|
+
}
|
|
3037
|
+
}
|
|
3038
|
+
|
|
3039
|
+
// Assign the PlatformNode class to the global object
|
|
3040
|
+
global.PlatformNode = PlatformNode;
|
|
3041
|
+
|
|
3042
|
+
// Also create an instance and assign it to global.platformNode
|
|
3043
|
+
global.platformNode = new PlatformNode();
|
|
3044
|
+
|
|
3045
|
+
// Ensure global.util exists and has the necessary methods
|
|
3046
|
+
if (!global.util) {
|
|
3047
|
+
global.util = {};
|
|
3048
|
+
}
|
|
3049
|
+
|
|
3050
|
+
// Add isFloat32Array method if it doesn't exist
|
|
3051
|
+
if (!global.util.isFloat32Array) {
|
|
3052
|
+
global.util.isFloat32Array = (arr) => {
|
|
3053
|
+
return !!(
|
|
3054
|
+
arr instanceof Float32Array ||
|
|
3055
|
+
(arr && Object.prototype.toString.call(arr) === '[object Float32Array]')
|
|
3056
|
+
);
|
|
3057
|
+
};
|
|
3058
|
+
}
|
|
3059
|
+
|
|
3060
|
+
// Add isTypedArray method if it doesn't exist
|
|
3061
|
+
if (!global.util.isTypedArray) {
|
|
3062
|
+
global.util.isTypedArray = (arr) => {
|
|
3063
|
+
return !!(ArrayBuffer.isView(arr) && !(arr instanceof DataView));
|
|
3064
|
+
};
|
|
3065
|
+
}
|
|
3066
|
+
} catch (error) {
|
|
3067
|
+
console.warn('Failed to apply TensorFlow.js platform patch:', error);
|
|
3068
|
+
}
|
|
3069
|
+
}
|
|
3070
|
+
|
|
2972
3071
|
const fn = new Function('return ' + workerData.fnString)();
|
|
2973
3072
|
const result = fn(workerData.args);
|
|
2974
3073
|
parentPort.postMessage({ result });
|
|
@@ -3209,7 +3308,71 @@ let UniversalSentenceEncoder$1 = class UniversalSentenceEncoder {
|
|
|
3209
3308
|
!process.versions.node) {
|
|
3210
3309
|
return;
|
|
3211
3310
|
}
|
|
3212
|
-
//
|
|
3311
|
+
// Add polyfill for isFloat32Array in Node.js 24.4.0
|
|
3312
|
+
// This fixes the "Cannot read properties of undefined (reading 'isFloat32Array')" error
|
|
3313
|
+
if (typeof global !== 'undefined') {
|
|
3314
|
+
try {
|
|
3315
|
+
// Define a custom PlatformNode class
|
|
3316
|
+
class PlatformNode {
|
|
3317
|
+
constructor() {
|
|
3318
|
+
// Create a util object with necessary methods
|
|
3319
|
+
this.util = {
|
|
3320
|
+
// Add isFloat32Array and isTypedArray directly to util
|
|
3321
|
+
isFloat32Array: (arr) => {
|
|
3322
|
+
return !!(arr instanceof Float32Array ||
|
|
3323
|
+
(arr &&
|
|
3324
|
+
Object.prototype.toString.call(arr) ===
|
|
3325
|
+
'[object Float32Array]'));
|
|
3326
|
+
},
|
|
3327
|
+
isTypedArray: (arr) => {
|
|
3328
|
+
return !!(ArrayBuffer.isView(arr) && !(arr instanceof DataView));
|
|
3329
|
+
},
|
|
3330
|
+
// Use native TextEncoder and TextDecoder
|
|
3331
|
+
TextEncoder: TextEncoder,
|
|
3332
|
+
TextDecoder: TextDecoder
|
|
3333
|
+
};
|
|
3334
|
+
// Initialize encoders using native constructors
|
|
3335
|
+
this.textEncoder = new TextEncoder();
|
|
3336
|
+
this.textDecoder = new TextDecoder();
|
|
3337
|
+
}
|
|
3338
|
+
// Define isFloat32Array directly on the instance
|
|
3339
|
+
isFloat32Array(arr) {
|
|
3340
|
+
return !!(arr instanceof Float32Array ||
|
|
3341
|
+
(arr &&
|
|
3342
|
+
Object.prototype.toString.call(arr) === '[object Float32Array]'));
|
|
3343
|
+
}
|
|
3344
|
+
// Define isTypedArray directly on the instance
|
|
3345
|
+
isTypedArray(arr) {
|
|
3346
|
+
return !!(ArrayBuffer.isView(arr) && !(arr instanceof DataView));
|
|
3347
|
+
}
|
|
3348
|
+
}
|
|
3349
|
+
// Assign the PlatformNode class to the global object
|
|
3350
|
+
;
|
|
3351
|
+
global.PlatformNode = PlatformNode;
|
|
3352
|
+
global.platformNode = new PlatformNode();
|
|
3353
|
+
}
|
|
3354
|
+
catch (error) {
|
|
3355
|
+
console.warn('Failed to define global PlatformNode class:', error);
|
|
3356
|
+
}
|
|
3357
|
+
// Ensure the util object exists
|
|
3358
|
+
if (!global.util) {
|
|
3359
|
+
global.util = {};
|
|
3360
|
+
}
|
|
3361
|
+
// Add isFloat32Array method if it doesn't exist
|
|
3362
|
+
if (!global.util.isFloat32Array) {
|
|
3363
|
+
global.util.isFloat32Array = (obj) => {
|
|
3364
|
+
return !!(obj instanceof Float32Array ||
|
|
3365
|
+
(obj &&
|
|
3366
|
+
Object.prototype.toString.call(obj) === '[object Float32Array]'));
|
|
3367
|
+
};
|
|
3368
|
+
}
|
|
3369
|
+
// Add isTypedArray method if it doesn't exist
|
|
3370
|
+
if (!global.util.isTypedArray) {
|
|
3371
|
+
global.util.isTypedArray = (obj) => {
|
|
3372
|
+
return !!(ArrayBuffer.isView(obj) && !(obj instanceof DataView));
|
|
3373
|
+
};
|
|
3374
|
+
}
|
|
3375
|
+
}
|
|
3213
3376
|
}
|
|
3214
3377
|
/**
|
|
3215
3378
|
* Initialize the embedding model
|
|
@@ -9625,12 +9788,40 @@ class BrainyData {
|
|
|
9625
9788
|
}
|
|
9626
9789
|
}
|
|
9627
9790
|
|
|
9628
|
-
//
|
|
9629
|
-
//
|
|
9791
|
+
// Dynamically and asynchronously load Node.js modules at the top level.
|
|
9792
|
+
// This ensures they are available as soon as this module is imported,
|
|
9793
|
+
// preventing race conditions with dependencies like TensorFlow.js.
|
|
9630
9794
|
let fs;
|
|
9631
9795
|
let path;
|
|
9632
|
-
|
|
9633
|
-
//
|
|
9796
|
+
const nodeModulesPromise = (async () => {
|
|
9797
|
+
// A reliable check for a Node.js environment.
|
|
9798
|
+
const isNode = typeof process !== 'undefined' &&
|
|
9799
|
+
process.versions != null &&
|
|
9800
|
+
process.versions.node != null;
|
|
9801
|
+
if (!isNode) {
|
|
9802
|
+
return { fs: null, path: null };
|
|
9803
|
+
}
|
|
9804
|
+
try {
|
|
9805
|
+
// Use the 'node:' prefix for unambiguous importing of built-in modules.
|
|
9806
|
+
const fsModule = await import('node:fs');
|
|
9807
|
+
const pathModule = await import('node:path');
|
|
9808
|
+
// Return the modules, preferring the default export if it exists.
|
|
9809
|
+
return {
|
|
9810
|
+
fs: fsModule.default || fsModule,
|
|
9811
|
+
path: pathModule.default || pathModule
|
|
9812
|
+
};
|
|
9813
|
+
}
|
|
9814
|
+
catch (error) {
|
|
9815
|
+
console.error('FileSystemStorage: Failed to load Node.js modules. This adapter is not supported in this environment.', error);
|
|
9816
|
+
return { fs: null, path: null };
|
|
9817
|
+
}
|
|
9818
|
+
})();
|
|
9819
|
+
// Immediately assign the modules once the promise resolves.
|
|
9820
|
+
nodeModulesPromise.then((modules) => {
|
|
9821
|
+
fs = modules.fs;
|
|
9822
|
+
path = modules.path;
|
|
9823
|
+
});
|
|
9824
|
+
// --- End of Refactored Code ---
|
|
9634
9825
|
// Constants for directory and file names
|
|
9635
9826
|
const ROOT_DIR = 'brainy-data';
|
|
9636
9827
|
const NOUNS_DIR = 'nouns';
|
|
@@ -9670,58 +9861,13 @@ class FileSystemStorage {
|
|
|
9670
9861
|
if (this.isInitialized) {
|
|
9671
9862
|
return;
|
|
9672
9863
|
}
|
|
9864
|
+
// Wait for the top-level module loading to complete.
|
|
9865
|
+
await nodeModulesPromise;
|
|
9866
|
+
// Check if the modules were loaded successfully.
|
|
9867
|
+
if (!fs || !path) {
|
|
9868
|
+
throw new Error('FileSystemStorage requires a Node.js environment, but `fs` and `path` modules could not be loaded.');
|
|
9869
|
+
}
|
|
9673
9870
|
try {
|
|
9674
|
-
// Check if fs and path modules are available and have required methods
|
|
9675
|
-
if (!fs || !path || typeof path.resolve !== 'function') {
|
|
9676
|
-
console.log('Node.js modules not properly loaded, attempting to load them now');
|
|
9677
|
-
// Try multiple approaches to load the modules
|
|
9678
|
-
const loadAttempts = [
|
|
9679
|
-
// Attempt 1: Use dynamic import
|
|
9680
|
-
async () => {
|
|
9681
|
-
console.log('Attempting to load Node.js modules with dynamic import');
|
|
9682
|
-
const fsModule = await import('fs');
|
|
9683
|
-
const pathModule = await import('path');
|
|
9684
|
-
const fsResolved = fsModule.default || fsModule;
|
|
9685
|
-
const pathResolved = pathModule.default || pathModule;
|
|
9686
|
-
if (!pathResolved || typeof pathResolved.resolve !== 'function') {
|
|
9687
|
-
throw new Error('path.resolve is not a function after dynamic import');
|
|
9688
|
-
}
|
|
9689
|
-
return { fs: fsResolved, path: pathResolved };
|
|
9690
|
-
},
|
|
9691
|
-
// Attempt 2: Use dynamic import with node: prefix
|
|
9692
|
-
async () => {
|
|
9693
|
-
console.log('Attempting to load Node.js modules with dynamic import("node:...")');
|
|
9694
|
-
const fsModule = await import('node:fs');
|
|
9695
|
-
const pathModule = await import('node:path');
|
|
9696
|
-
const fsResolved = fsModule.default || fsModule;
|
|
9697
|
-
const pathResolved = pathModule.default || pathModule;
|
|
9698
|
-
if (!pathResolved || typeof pathResolved.resolve !== 'function') {
|
|
9699
|
-
throw new Error('path.resolve is not a function after dynamic import("node:path")');
|
|
9700
|
-
}
|
|
9701
|
-
return { fs: fsResolved, path: pathResolved };
|
|
9702
|
-
}
|
|
9703
|
-
];
|
|
9704
|
-
// Try each loading method until one succeeds
|
|
9705
|
-
let lastError = null;
|
|
9706
|
-
for (const loadAttempt of loadAttempts) {
|
|
9707
|
-
try {
|
|
9708
|
-
const modules = await loadAttempt();
|
|
9709
|
-
fs = modules.fs;
|
|
9710
|
-
path = modules.path;
|
|
9711
|
-
console.log('Successfully loaded Node.js modules');
|
|
9712
|
-
break;
|
|
9713
|
-
}
|
|
9714
|
-
catch (error) {
|
|
9715
|
-
lastError = error;
|
|
9716
|
-
console.warn(`Module loading attempt failed:`, error);
|
|
9717
|
-
// Continue to the next attempt
|
|
9718
|
-
}
|
|
9719
|
-
}
|
|
9720
|
-
// If all attempts failed, throw an error
|
|
9721
|
-
if (!fs || !path || typeof path.resolve !== 'function') {
|
|
9722
|
-
throw new Error(`Failed to import Node.js modules after multiple attempts: ${lastError}. This adapter requires a Node.js environment.`);
|
|
9723
|
-
}
|
|
9724
|
-
}
|
|
9725
9871
|
// Now set up the directory paths
|
|
9726
9872
|
const rootDir = this.rootDir || process.cwd();
|
|
9727
9873
|
this.rootDir = path.resolve(rootDir, ROOT_DIR);
|
|
@@ -9741,7 +9887,6 @@ class FileSystemStorage {
|
|
|
9741
9887
|
await this.ensureDirectoryExists(this.nounsDir);
|
|
9742
9888
|
await this.ensureDirectoryExists(this.verbsDir);
|
|
9743
9889
|
await this.ensureDirectoryExists(this.metadataDir);
|
|
9744
|
-
// Create noun type directories
|
|
9745
9890
|
await this.ensureDirectoryExists(this.personDir);
|
|
9746
9891
|
await this.ensureDirectoryExists(this.placeDir);
|
|
9747
9892
|
await this.ensureDirectoryExists(this.thingDir);
|
|
@@ -9752,736 +9897,349 @@ class FileSystemStorage {
|
|
|
9752
9897
|
this.isInitialized = true;
|
|
9753
9898
|
}
|
|
9754
9899
|
catch (error) {
|
|
9755
|
-
console.error('
|
|
9756
|
-
throw
|
|
9900
|
+
console.error('Error initializing FileSystemStorage:', error);
|
|
9901
|
+
throw error;
|
|
9757
9902
|
}
|
|
9758
9903
|
}
|
|
9759
|
-
|
|
9760
|
-
* Save a node to storage
|
|
9761
|
-
*/
|
|
9762
|
-
async saveNoun(noun) {
|
|
9763
|
-
await this.ensureInitialized();
|
|
9904
|
+
async ensureDirectoryExists(dirPath) {
|
|
9764
9905
|
try {
|
|
9765
|
-
|
|
9766
|
-
const serializableNode = {
|
|
9767
|
-
...noun,
|
|
9768
|
-
connections: this.mapToObject(noun.connections, (set) => Array.from(set))
|
|
9769
|
-
};
|
|
9770
|
-
// Get the appropriate directory based on the node's metadata
|
|
9771
|
-
const nodeDir = await this.getNodeDirectory(noun.id);
|
|
9772
|
-
const filePath = path.join(nodeDir, `${noun.id}.json`);
|
|
9773
|
-
await fs.promises.writeFile(filePath, JSON.stringify(serializableNode, null, 2), 'utf8');
|
|
9906
|
+
await fs.promises.mkdir(dirPath, { recursive: true });
|
|
9774
9907
|
}
|
|
9775
9908
|
catch (error) {
|
|
9776
|
-
|
|
9777
|
-
|
|
9778
|
-
|
|
9779
|
-
}
|
|
9780
|
-
/**
|
|
9781
|
-
* Get a node from storage
|
|
9782
|
-
*/
|
|
9783
|
-
async getNoun(id) {
|
|
9784
|
-
await this.ensureInitialized();
|
|
9785
|
-
try {
|
|
9786
|
-
// Get the appropriate directory based on the node's metadata
|
|
9787
|
-
const nodeDir = await this.getNodeDirectory(id);
|
|
9788
|
-
const filePath = path.join(nodeDir, `${id}.json`);
|
|
9789
|
-
// Check if a file exists
|
|
9790
|
-
try {
|
|
9791
|
-
await fs.promises.access(filePath);
|
|
9792
|
-
}
|
|
9793
|
-
catch {
|
|
9794
|
-
// If the file doesn't exist in the expected directory, try the default directory
|
|
9795
|
-
if (nodeDir !== this.defaultDir) {
|
|
9796
|
-
const defaultFilePath = path.join(this.defaultDir, `${id}.json`);
|
|
9797
|
-
try {
|
|
9798
|
-
await fs.promises.access(defaultFilePath);
|
|
9799
|
-
// If found in default directory, use that path
|
|
9800
|
-
const data = await fs.promises.readFile(defaultFilePath, 'utf8');
|
|
9801
|
-
const parsedNode = JSON.parse(data);
|
|
9802
|
-
// Convert serialized connections back to Map<number, Set<string>>
|
|
9803
|
-
const connections = new Map();
|
|
9804
|
-
for (const [level, nodeIds] of Object.entries(parsedNode.connections)) {
|
|
9805
|
-
connections.set(Number(level), new Set(nodeIds));
|
|
9806
|
-
}
|
|
9807
|
-
return {
|
|
9808
|
-
id: parsedNode.id,
|
|
9809
|
-
vector: parsedNode.vector,
|
|
9810
|
-
connections
|
|
9811
|
-
};
|
|
9812
|
-
}
|
|
9813
|
-
catch {
|
|
9814
|
-
// If not found in default directory either, try all noun type directories
|
|
9815
|
-
const directories = [
|
|
9816
|
-
this.personDir,
|
|
9817
|
-
this.placeDir,
|
|
9818
|
-
this.thingDir,
|
|
9819
|
-
this.eventDir,
|
|
9820
|
-
this.conceptDir,
|
|
9821
|
-
this.contentDir
|
|
9822
|
-
];
|
|
9823
|
-
for (const dir of directories) {
|
|
9824
|
-
if (dir === nodeDir)
|
|
9825
|
-
continue; // Skip the already checked directory
|
|
9826
|
-
const dirFilePath = path.join(dir, `${id}.json`);
|
|
9827
|
-
try {
|
|
9828
|
-
await fs.promises.access(dirFilePath);
|
|
9829
|
-
// If found in this directory, use that path
|
|
9830
|
-
const data = await fs.promises.readFile(dirFilePath, 'utf8');
|
|
9831
|
-
const parsedNode = JSON.parse(data);
|
|
9832
|
-
// Convert serialized connections back to Map<number, Set<string>>
|
|
9833
|
-
const connections = new Map();
|
|
9834
|
-
for (const [level, nodeIds] of Object.entries(parsedNode.connections)) {
|
|
9835
|
-
connections.set(Number(level), new Set(nodeIds));
|
|
9836
|
-
}
|
|
9837
|
-
return {
|
|
9838
|
-
id: parsedNode.id,
|
|
9839
|
-
vector: parsedNode.vector,
|
|
9840
|
-
connections
|
|
9841
|
-
};
|
|
9842
|
-
}
|
|
9843
|
-
catch {
|
|
9844
|
-
// Continue to the next directory
|
|
9845
|
-
}
|
|
9846
|
-
}
|
|
9847
|
-
return null; // File doesn't exist in any directory
|
|
9848
|
-
}
|
|
9849
|
-
}
|
|
9850
|
-
return null; // File doesn't exist
|
|
9851
|
-
}
|
|
9852
|
-
const data = await fs.promises.readFile(filePath, 'utf8');
|
|
9853
|
-
const parsedNode = JSON.parse(data);
|
|
9854
|
-
// Convert serialized connections back to Map<number, Set<string>>
|
|
9855
|
-
const connections = new Map();
|
|
9856
|
-
for (const [level, nodeIds] of Object.entries(parsedNode.connections)) {
|
|
9857
|
-
connections.set(Number(level), new Set(nodeIds));
|
|
9909
|
+
// Ignore EEXIST error, which means the directory already exists
|
|
9910
|
+
if (error.code !== 'EEXIST') {
|
|
9911
|
+
throw error;
|
|
9858
9912
|
}
|
|
9859
|
-
return {
|
|
9860
|
-
id: parsedNode.id,
|
|
9861
|
-
vector: parsedNode.vector,
|
|
9862
|
-
connections
|
|
9863
|
-
};
|
|
9864
|
-
}
|
|
9865
|
-
catch (error) {
|
|
9866
|
-
console.error(`Failed to get node ${id}:`, error);
|
|
9867
|
-
return null;
|
|
9868
9913
|
}
|
|
9869
9914
|
}
|
|
9870
|
-
|
|
9871
|
-
|
|
9872
|
-
|
|
9873
|
-
|
|
9874
|
-
*/
|
|
9875
|
-
async getNounsByNounType(nounType) {
|
|
9876
|
-
await this.ensureInitialized();
|
|
9877
|
-
try {
|
|
9878
|
-
// Determine the directory based on the noun type
|
|
9879
|
-
let dir;
|
|
9880
|
-
switch (nounType) {
|
|
9915
|
+
getNounPath(id, nounType) {
|
|
9916
|
+
let typeDir = this.defaultDir;
|
|
9917
|
+
if (nounType) {
|
|
9918
|
+
switch (nounType.toLowerCase()) {
|
|
9881
9919
|
case 'person':
|
|
9882
|
-
|
|
9920
|
+
typeDir = this.personDir;
|
|
9883
9921
|
break;
|
|
9884
9922
|
case 'place':
|
|
9885
|
-
|
|
9923
|
+
typeDir = this.placeDir;
|
|
9886
9924
|
break;
|
|
9887
9925
|
case 'thing':
|
|
9888
|
-
|
|
9926
|
+
typeDir = this.thingDir;
|
|
9889
9927
|
break;
|
|
9890
9928
|
case 'event':
|
|
9891
|
-
|
|
9929
|
+
typeDir = this.eventDir;
|
|
9892
9930
|
break;
|
|
9893
9931
|
case 'concept':
|
|
9894
|
-
|
|
9932
|
+
typeDir = this.conceptDir;
|
|
9895
9933
|
break;
|
|
9896
9934
|
case 'content':
|
|
9897
|
-
|
|
9935
|
+
typeDir = this.contentDir;
|
|
9898
9936
|
break;
|
|
9899
9937
|
default:
|
|
9900
|
-
|
|
9938
|
+
typeDir = this.defaultDir;
|
|
9901
9939
|
}
|
|
9902
|
-
const nodes = [];
|
|
9903
|
-
try {
|
|
9904
|
-
const files = await fs.promises.readdir(dir);
|
|
9905
|
-
const nodePromises = files
|
|
9906
|
-
.filter((file) => file.endsWith('.json'))
|
|
9907
|
-
.map((file) => {
|
|
9908
|
-
// Use the file path directly instead of getNode to avoid redundant searches
|
|
9909
|
-
return this.readNodeFromFile(path.join(dir, file));
|
|
9910
|
-
});
|
|
9911
|
-
const dirNodes = await Promise.all(nodePromises);
|
|
9912
|
-
nodes.push(...dirNodes.filter((node) => node !== null));
|
|
9913
|
-
}
|
|
9914
|
-
catch (dirError) {
|
|
9915
|
-
// If directory doesn't exist or can't be read, log a warning
|
|
9916
|
-
console.warn(`Could not read directory for noun type ${nounType}:`, dirError);
|
|
9917
|
-
}
|
|
9918
|
-
return nodes;
|
|
9919
|
-
}
|
|
9920
|
-
catch (error) {
|
|
9921
|
-
console.error(`Failed to get nodes for noun type ${nounType}:`, error);
|
|
9922
|
-
throw new Error(`Failed to get nodes for noun type ${nounType}: ${error}`);
|
|
9923
9940
|
}
|
|
9941
|
+
return path.join(typeDir, `${id}.json`);
|
|
9924
9942
|
}
|
|
9925
|
-
|
|
9926
|
-
|
|
9927
|
-
|
|
9928
|
-
|
|
9929
|
-
|
|
9930
|
-
|
|
9931
|
-
|
|
9932
|
-
const nounTypes = [
|
|
9933
|
-
'person',
|
|
9934
|
-
'place',
|
|
9935
|
-
'thing',
|
|
9936
|
-
'event',
|
|
9937
|
-
'concept',
|
|
9938
|
-
'content',
|
|
9939
|
-
'default'
|
|
9940
|
-
];
|
|
9941
|
-
// Run searches in parallel for all noun types
|
|
9942
|
-
const nodePromises = nounTypes.map((nounType) => this.getNounsByNounType(nounType));
|
|
9943
|
-
const nodeArrays = await Promise.all(nodePromises);
|
|
9944
|
-
// Combine all results
|
|
9945
|
-
const allNodes = [];
|
|
9946
|
-
for (const nodes of nodeArrays) {
|
|
9947
|
-
allNodes.push(...nodes);
|
|
9948
|
-
}
|
|
9949
|
-
return allNodes;
|
|
9950
|
-
}
|
|
9951
|
-
catch (error) {
|
|
9952
|
-
console.error('Failed to get all nodes:', error);
|
|
9953
|
-
throw new Error(`Failed to get all nodes: ${error}`);
|
|
9954
|
-
}
|
|
9943
|
+
async saveNoun(noun) {
|
|
9944
|
+
if (!this.isInitialized)
|
|
9945
|
+
await this.init();
|
|
9946
|
+
const nounType = noun.metadata?.noun;
|
|
9947
|
+
const filePath = this.getNounPath(noun.id, nounType);
|
|
9948
|
+
await this.ensureDirectoryExists(path.dirname(filePath));
|
|
9949
|
+
await fs.promises.writeFile(filePath, JSON.stringify(noun, null, 2));
|
|
9955
9950
|
}
|
|
9956
|
-
|
|
9957
|
-
|
|
9958
|
-
|
|
9959
|
-
|
|
9960
|
-
|
|
9961
|
-
|
|
9962
|
-
|
|
9963
|
-
|
|
9964
|
-
|
|
9965
|
-
|
|
9966
|
-
|
|
9951
|
+
async getNoun(id) {
|
|
9952
|
+
if (!this.isInitialized)
|
|
9953
|
+
await this.init();
|
|
9954
|
+
const nounDirs = [
|
|
9955
|
+
this.personDir,
|
|
9956
|
+
this.placeDir,
|
|
9957
|
+
this.thingDir,
|
|
9958
|
+
this.eventDir,
|
|
9959
|
+
this.conceptDir,
|
|
9960
|
+
this.contentDir,
|
|
9961
|
+
this.defaultDir
|
|
9962
|
+
];
|
|
9963
|
+
for (const dir of nounDirs) {
|
|
9964
|
+
const filePath = path.join(dir, `${id}.json`);
|
|
9965
|
+
try {
|
|
9966
|
+
const data = await fs.promises.readFile(filePath, 'utf-8');
|
|
9967
|
+
return JSON.parse(data);
|
|
9968
|
+
}
|
|
9969
|
+
catch (error) {
|
|
9970
|
+
if (error.code !== 'ENOENT') {
|
|
9971
|
+
console.error(`Error reading noun ${id}:`, error);
|
|
9972
|
+
}
|
|
9967
9973
|
}
|
|
9968
|
-
return {
|
|
9969
|
-
id: parsedNode.id,
|
|
9970
|
-
vector: parsedNode.vector,
|
|
9971
|
-
connections
|
|
9972
|
-
};
|
|
9973
|
-
}
|
|
9974
|
-
catch (error) {
|
|
9975
|
-
console.error(`Failed to read node from file ${filePath}:`, error);
|
|
9976
|
-
return null;
|
|
9977
9974
|
}
|
|
9975
|
+
return null;
|
|
9978
9976
|
}
|
|
9979
|
-
/**
|
|
9980
|
-
* Delete a node from storage
|
|
9981
|
-
*/
|
|
9982
9977
|
async deleteNoun(id) {
|
|
9983
|
-
|
|
9984
|
-
|
|
9985
|
-
|
|
9986
|
-
|
|
9987
|
-
const
|
|
9988
|
-
|
|
9978
|
+
if (!this.isInitialized)
|
|
9979
|
+
await this.init();
|
|
9980
|
+
const noun = await this.getNoun(id);
|
|
9981
|
+
if (noun) {
|
|
9982
|
+
const nounType = noun.metadata?.noun;
|
|
9983
|
+
const filePath = this.getNounPath(id, nounType);
|
|
9989
9984
|
try {
|
|
9990
|
-
await fs.promises.access(filePath);
|
|
9991
9985
|
await fs.promises.unlink(filePath);
|
|
9992
|
-
return; // File found and deleted
|
|
9993
9986
|
}
|
|
9994
|
-
catch {
|
|
9995
|
-
|
|
9996
|
-
|
|
9997
|
-
|
|
9998
|
-
try {
|
|
9999
|
-
await fs.promises.access(defaultFilePath);
|
|
10000
|
-
await fs.promises.unlink(defaultFilePath);
|
|
10001
|
-
return; // File found and deleted
|
|
10002
|
-
}
|
|
10003
|
-
catch {
|
|
10004
|
-
// If not found in default directory either, try all noun type directories
|
|
10005
|
-
const directories = [
|
|
10006
|
-
this.personDir,
|
|
10007
|
-
this.placeDir,
|
|
10008
|
-
this.thingDir,
|
|
10009
|
-
this.eventDir,
|
|
10010
|
-
this.conceptDir,
|
|
10011
|
-
this.contentDir
|
|
10012
|
-
];
|
|
10013
|
-
for (const dir of directories) {
|
|
10014
|
-
if (dir === nodeDir)
|
|
10015
|
-
continue; // Skip the already checked directory
|
|
10016
|
-
const dirFilePath = path.join(dir, `${id}.json`);
|
|
10017
|
-
try {
|
|
10018
|
-
await fs.promises.access(dirFilePath);
|
|
10019
|
-
await fs.promises.unlink(dirFilePath);
|
|
10020
|
-
return; // File found and deleted
|
|
10021
|
-
}
|
|
10022
|
-
catch {
|
|
10023
|
-
// Continue to the next directory
|
|
10024
|
-
}
|
|
10025
|
-
}
|
|
10026
|
-
return; // File doesn't exist in any directory, nothing to delete
|
|
10027
|
-
}
|
|
9987
|
+
catch (error) {
|
|
9988
|
+
if (error.code !== 'ENOENT') {
|
|
9989
|
+
console.error(`Error deleting noun file ${filePath}:`, error);
|
|
9990
|
+
throw error;
|
|
10028
9991
|
}
|
|
10029
|
-
return; // File doesn't exist, nothing to delete
|
|
10030
9992
|
}
|
|
10031
9993
|
}
|
|
10032
|
-
catch (error) {
|
|
10033
|
-
console.error(`Failed to delete node ${id}:`, error);
|
|
10034
|
-
throw new Error(`Failed to delete node ${id}: ${error}`);
|
|
10035
|
-
}
|
|
10036
|
-
}
|
|
10037
|
-
/**
|
|
10038
|
-
* Save an edge to storage
|
|
10039
|
-
*/
|
|
10040
|
-
async saveVerb(verb) {
|
|
10041
|
-
await this.ensureInitialized();
|
|
10042
|
-
try {
|
|
10043
|
-
// Convert connections Map to a serializable format
|
|
10044
|
-
const serializableEdge = {
|
|
10045
|
-
...verb,
|
|
10046
|
-
connections: this.mapToObject(verb.connections, (set) => Array.from(set))
|
|
10047
|
-
};
|
|
10048
|
-
const filePath = path.join(this.verbsDir, `${verb.id}.json`);
|
|
10049
|
-
await fs.promises.writeFile(filePath, JSON.stringify(serializableEdge, null, 2), 'utf8');
|
|
10050
|
-
}
|
|
10051
|
-
catch (error) {
|
|
10052
|
-
console.error(`Failed to save edge ${verb.id}:`, error);
|
|
10053
|
-
throw new Error(`Failed to save edge ${verb.id}: ${error}`);
|
|
10054
|
-
}
|
|
10055
9994
|
}
|
|
10056
|
-
|
|
10057
|
-
|
|
10058
|
-
|
|
10059
|
-
|
|
10060
|
-
|
|
10061
|
-
|
|
10062
|
-
|
|
10063
|
-
|
|
9995
|
+
async getAllNouns() {
|
|
9996
|
+
if (!this.isInitialized)
|
|
9997
|
+
await this.init();
|
|
9998
|
+
const allNouns = [];
|
|
9999
|
+
const nounDirs = [
|
|
10000
|
+
this.personDir,
|
|
10001
|
+
this.placeDir,
|
|
10002
|
+
this.thingDir,
|
|
10003
|
+
this.eventDir,
|
|
10004
|
+
this.conceptDir,
|
|
10005
|
+
this.contentDir,
|
|
10006
|
+
this.defaultDir
|
|
10007
|
+
];
|
|
10008
|
+
for (const dir of nounDirs) {
|
|
10064
10009
|
try {
|
|
10065
|
-
await fs.promises.
|
|
10066
|
-
|
|
10067
|
-
|
|
10068
|
-
|
|
10010
|
+
const files = await fs.promises.readdir(dir);
|
|
10011
|
+
for (const file of files) {
|
|
10012
|
+
if (file.endsWith('.json')) {
|
|
10013
|
+
const filePath = path.join(dir, file);
|
|
10014
|
+
const data = await fs.promises.readFile(filePath, 'utf-8');
|
|
10015
|
+
allNouns.push(JSON.parse(data));
|
|
10016
|
+
}
|
|
10017
|
+
}
|
|
10069
10018
|
}
|
|
10070
|
-
|
|
10071
|
-
|
|
10072
|
-
|
|
10073
|
-
|
|
10074
|
-
for (const [level, nodeIds] of Object.entries(parsedEdge.connections)) {
|
|
10075
|
-
connections.set(Number(level), new Set(nodeIds));
|
|
10019
|
+
catch (error) {
|
|
10020
|
+
if (error.code !== 'ENOENT') {
|
|
10021
|
+
console.error(`Error reading directory ${dir}:`, error);
|
|
10022
|
+
}
|
|
10076
10023
|
}
|
|
10077
|
-
return {
|
|
10078
|
-
id: parsedEdge.id,
|
|
10079
|
-
vector: parsedEdge.vector,
|
|
10080
|
-
connections,
|
|
10081
|
-
sourceId: parsedEdge.sourceId,
|
|
10082
|
-
targetId: parsedEdge.targetId,
|
|
10083
|
-
type: parsedEdge.type,
|
|
10084
|
-
weight: parsedEdge.weight,
|
|
10085
|
-
metadata: parsedEdge.metadata
|
|
10086
|
-
};
|
|
10087
|
-
}
|
|
10088
|
-
catch (error) {
|
|
10089
|
-
console.error(`Failed to get edge ${id}:`, error);
|
|
10090
|
-
return null;
|
|
10091
|
-
}
|
|
10092
|
-
}
|
|
10093
|
-
/**
|
|
10094
|
-
* Get all edges from storage
|
|
10095
|
-
*/
|
|
10096
|
-
async getAllVerbs() {
|
|
10097
|
-
await this.ensureInitialized();
|
|
10098
|
-
try {
|
|
10099
|
-
const files = await fs.promises.readdir(this.verbsDir);
|
|
10100
|
-
const edgePromises = files
|
|
10101
|
-
.filter((file) => file.endsWith('.json'))
|
|
10102
|
-
.map((file) => {
|
|
10103
|
-
const id = path.basename(file, '.json');
|
|
10104
|
-
return this.getVerb(id);
|
|
10105
|
-
});
|
|
10106
|
-
const edges = await Promise.all(edgePromises);
|
|
10107
|
-
return edges.filter((edge) => edge !== null);
|
|
10108
|
-
}
|
|
10109
|
-
catch (error) {
|
|
10110
|
-
console.error('Failed to get all edges:', error);
|
|
10111
|
-
throw new Error(`Failed to get all edges: ${error}`);
|
|
10112
|
-
}
|
|
10113
|
-
}
|
|
10114
|
-
/**
|
|
10115
|
-
* Get edges by source node ID
|
|
10116
|
-
*/
|
|
10117
|
-
async getVerbsBySource(sourceId) {
|
|
10118
|
-
await this.ensureInitialized();
|
|
10119
|
-
try {
|
|
10120
|
-
const allEdges = await this.getAllVerbs();
|
|
10121
|
-
return allEdges.filter((edge) => edge.sourceId === sourceId);
|
|
10122
|
-
}
|
|
10123
|
-
catch (error) {
|
|
10124
|
-
console.error(`Failed to get edges by source ${sourceId}:`, error);
|
|
10125
|
-
throw new Error(`Failed to get edges by source ${sourceId}: ${error}`);
|
|
10126
|
-
}
|
|
10127
|
-
}
|
|
10128
|
-
/**
|
|
10129
|
-
* Get edges by target node ID
|
|
10130
|
-
*/
|
|
10131
|
-
async getVerbsByTarget(targetId) {
|
|
10132
|
-
await this.ensureInitialized();
|
|
10133
|
-
try {
|
|
10134
|
-
const allEdges = await this.getAllVerbs();
|
|
10135
|
-
return allEdges.filter((edge) => edge.targetId === targetId);
|
|
10136
|
-
}
|
|
10137
|
-
catch (error) {
|
|
10138
|
-
console.error(`Failed to get edges by target ${targetId}:`, error);
|
|
10139
|
-
throw new Error(`Failed to get edges by target ${targetId}: ${error}`);
|
|
10140
10024
|
}
|
|
10025
|
+
return allNouns;
|
|
10141
10026
|
}
|
|
10142
10027
|
/**
|
|
10143
|
-
* Get
|
|
10028
|
+
* Get nouns by noun type
|
|
10029
|
+
* @param nounType The noun type to filter by
|
|
10030
|
+
* @returns Promise that resolves to an array of nouns of the specified noun type
|
|
10144
10031
|
*/
|
|
10145
|
-
async
|
|
10146
|
-
|
|
10147
|
-
|
|
10148
|
-
|
|
10149
|
-
|
|
10150
|
-
|
|
10151
|
-
|
|
10152
|
-
|
|
10153
|
-
|
|
10032
|
+
async getNounsByNounType(nounType) {
|
|
10033
|
+
if (!this.isInitialized)
|
|
10034
|
+
await this.init();
|
|
10035
|
+
let typeDir;
|
|
10036
|
+
switch (nounType.toLowerCase()) {
|
|
10037
|
+
case 'person':
|
|
10038
|
+
typeDir = this.personDir;
|
|
10039
|
+
break;
|
|
10040
|
+
case 'place':
|
|
10041
|
+
typeDir = this.placeDir;
|
|
10042
|
+
break;
|
|
10043
|
+
case 'thing':
|
|
10044
|
+
typeDir = this.thingDir;
|
|
10045
|
+
break;
|
|
10046
|
+
case 'event':
|
|
10047
|
+
typeDir = this.eventDir;
|
|
10048
|
+
break;
|
|
10049
|
+
case 'concept':
|
|
10050
|
+
typeDir = this.conceptDir;
|
|
10051
|
+
break;
|
|
10052
|
+
case 'content':
|
|
10053
|
+
typeDir = this.contentDir;
|
|
10054
|
+
break;
|
|
10055
|
+
default:
|
|
10056
|
+
typeDir = this.defaultDir;
|
|
10154
10057
|
}
|
|
10155
|
-
|
|
10156
|
-
/**
|
|
10157
|
-
* Delete an edge from storage
|
|
10158
|
-
*/
|
|
10159
|
-
async deleteVerb(id) {
|
|
10160
|
-
await this.ensureInitialized();
|
|
10058
|
+
const nouns = [];
|
|
10161
10059
|
try {
|
|
10162
|
-
const
|
|
10163
|
-
|
|
10164
|
-
|
|
10165
|
-
|
|
10166
|
-
|
|
10167
|
-
|
|
10168
|
-
|
|
10060
|
+
const files = await fs.promises.readdir(typeDir);
|
|
10061
|
+
for (const file of files) {
|
|
10062
|
+
if (file.endsWith('.json')) {
|
|
10063
|
+
const filePath = path.join(typeDir, file);
|
|
10064
|
+
const data = await fs.promises.readFile(filePath, 'utf-8');
|
|
10065
|
+
nouns.push(JSON.parse(data));
|
|
10066
|
+
}
|
|
10169
10067
|
}
|
|
10170
|
-
await fs.promises.unlink(filePath);
|
|
10171
10068
|
}
|
|
10172
10069
|
catch (error) {
|
|
10173
|
-
|
|
10174
|
-
|
|
10070
|
+
if (error.code !== 'ENOENT') {
|
|
10071
|
+
console.error(`Error reading directory ${typeDir}:`, error);
|
|
10072
|
+
}
|
|
10175
10073
|
}
|
|
10074
|
+
return nouns;
|
|
10176
10075
|
}
|
|
10177
|
-
|
|
10178
|
-
|
|
10179
|
-
|
|
10180
|
-
|
|
10181
|
-
await
|
|
10182
|
-
try {
|
|
10183
|
-
const filePath = path.join(this.metadataDir, `${id}.json`);
|
|
10184
|
-
await fs.promises.writeFile(filePath, JSON.stringify(metadata, null, 2), 'utf8');
|
|
10185
|
-
}
|
|
10186
|
-
catch (error) {
|
|
10187
|
-
console.error(`Failed to save metadata for ${id}:`, error);
|
|
10188
|
-
throw new Error(`Failed to save metadata for ${id}: ${error}`);
|
|
10189
|
-
}
|
|
10076
|
+
async saveVerb(verb) {
|
|
10077
|
+
if (!this.isInitialized)
|
|
10078
|
+
await this.init();
|
|
10079
|
+
const filePath = path.join(this.verbsDir, `${verb.id}.json`);
|
|
10080
|
+
await fs.promises.writeFile(filePath, JSON.stringify(verb, null, 2));
|
|
10190
10081
|
}
|
|
10191
10082
|
/**
|
|
10192
|
-
* Get
|
|
10083
|
+
* Get a verb by its ID
|
|
10084
|
+
* @param id The ID of the verb to retrieve
|
|
10085
|
+
* @returns Promise that resolves to the verb or null if not found
|
|
10193
10086
|
*/
|
|
10194
|
-
async
|
|
10195
|
-
|
|
10087
|
+
async getVerb(id) {
|
|
10088
|
+
if (!this.isInitialized)
|
|
10089
|
+
await this.init();
|
|
10090
|
+
const filePath = path.join(this.verbsDir, `${id}.json`);
|
|
10196
10091
|
try {
|
|
10197
|
-
const
|
|
10198
|
-
// Check if a file exists
|
|
10199
|
-
try {
|
|
10200
|
-
await fs.promises.access(filePath);
|
|
10201
|
-
}
|
|
10202
|
-
catch {
|
|
10203
|
-
return null; // File doesn't exist
|
|
10204
|
-
}
|
|
10205
|
-
const data = await fs.promises.readFile(filePath, 'utf8');
|
|
10092
|
+
const data = await fs.promises.readFile(filePath, 'utf-8');
|
|
10206
10093
|
return JSON.parse(data);
|
|
10207
10094
|
}
|
|
10208
10095
|
catch (error) {
|
|
10209
|
-
|
|
10096
|
+
if (error.code !== 'ENOENT') {
|
|
10097
|
+
console.error(`Error reading verb ${id}:`, error);
|
|
10098
|
+
}
|
|
10210
10099
|
return null;
|
|
10211
10100
|
}
|
|
10212
10101
|
}
|
|
10213
|
-
|
|
10214
|
-
|
|
10215
|
-
|
|
10216
|
-
|
|
10217
|
-
|
|
10218
|
-
try {
|
|
10219
|
-
// Delete and recreate the nodes, edges, and metadata directories
|
|
10220
|
-
await this.deleteDirectory(this.nounsDir);
|
|
10221
|
-
await this.deleteDirectory(this.verbsDir);
|
|
10222
|
-
await this.deleteDirectory(this.metadataDir);
|
|
10223
|
-
await this.ensureDirectoryExists(this.nounsDir);
|
|
10224
|
-
await this.ensureDirectoryExists(this.verbsDir);
|
|
10225
|
-
await this.ensureDirectoryExists(this.metadataDir);
|
|
10226
|
-
// Create noun type directories
|
|
10227
|
-
await this.ensureDirectoryExists(this.personDir);
|
|
10228
|
-
await this.ensureDirectoryExists(this.placeDir);
|
|
10229
|
-
await this.ensureDirectoryExists(this.thingDir);
|
|
10230
|
-
await this.ensureDirectoryExists(this.eventDir);
|
|
10231
|
-
await this.ensureDirectoryExists(this.conceptDir);
|
|
10232
|
-
await this.ensureDirectoryExists(this.contentDir);
|
|
10233
|
-
await this.ensureDirectoryExists(this.defaultDir);
|
|
10234
|
-
}
|
|
10235
|
-
catch (error) {
|
|
10236
|
-
console.error('Failed to clear storage:', error);
|
|
10237
|
-
throw new Error(`Failed to clear storage: ${error}`);
|
|
10238
|
-
}
|
|
10102
|
+
async getVerbsBySource(sourceId) {
|
|
10103
|
+
if (!this.isInitialized)
|
|
10104
|
+
await this.init();
|
|
10105
|
+
const allVerbs = await this.getAllVerbs();
|
|
10106
|
+
return allVerbs.filter((verb) => verb.sourceId === sourceId);
|
|
10239
10107
|
}
|
|
10240
10108
|
/**
|
|
10241
|
-
*
|
|
10109
|
+
* Get verbs by target ID
|
|
10110
|
+
* @param targetId The target ID to filter by
|
|
10111
|
+
* @returns Promise that resolves to an array of verbs with the specified target ID
|
|
10242
10112
|
*/
|
|
10243
|
-
async
|
|
10244
|
-
if (!this.isInitialized)
|
|
10113
|
+
async getVerbsByTarget(targetId) {
|
|
10114
|
+
if (!this.isInitialized)
|
|
10245
10115
|
await this.init();
|
|
10246
|
-
|
|
10116
|
+
const allVerbs = await this.getAllVerbs();
|
|
10117
|
+
return allVerbs.filter((verb) => verb.targetId === targetId);
|
|
10247
10118
|
}
|
|
10248
10119
|
/**
|
|
10249
|
-
*
|
|
10120
|
+
* Get verbs by type
|
|
10121
|
+
* @param type The verb type to filter by
|
|
10122
|
+
* @returns Promise that resolves to an array of verbs of the specified type
|
|
10250
10123
|
*/
|
|
10251
|
-
async
|
|
10252
|
-
|
|
10253
|
-
await
|
|
10254
|
-
|
|
10255
|
-
|
|
10256
|
-
// Directory doesn't exist, create it
|
|
10257
|
-
await fs.promises.mkdir(dirPath, { recursive: true });
|
|
10258
|
-
}
|
|
10124
|
+
async getVerbsByType(type) {
|
|
10125
|
+
if (!this.isInitialized)
|
|
10126
|
+
await this.init();
|
|
10127
|
+
const allVerbs = await this.getAllVerbs();
|
|
10128
|
+
return allVerbs.filter((verb) => verb.type === type);
|
|
10259
10129
|
}
|
|
10260
|
-
|
|
10261
|
-
|
|
10262
|
-
|
|
10263
|
-
|
|
10130
|
+
async getAllVerbs() {
|
|
10131
|
+
if (!this.isInitialized)
|
|
10132
|
+
await this.init();
|
|
10133
|
+
const allVerbs = [];
|
|
10264
10134
|
try {
|
|
10265
|
-
const files = await fs.promises.readdir(
|
|
10135
|
+
const files = await fs.promises.readdir(this.verbsDir);
|
|
10266
10136
|
for (const file of files) {
|
|
10267
|
-
|
|
10268
|
-
|
|
10269
|
-
|
|
10270
|
-
|
|
10271
|
-
await this.deleteDirectory(filePath);
|
|
10272
|
-
}
|
|
10273
|
-
else {
|
|
10274
|
-
// Delete files
|
|
10275
|
-
await fs.promises.unlink(filePath);
|
|
10137
|
+
if (file.endsWith('.json')) {
|
|
10138
|
+
const filePath = path.join(this.verbsDir, file);
|
|
10139
|
+
const data = await fs.promises.readFile(filePath, 'utf-8');
|
|
10140
|
+
allVerbs.push(JSON.parse(data));
|
|
10276
10141
|
}
|
|
10277
10142
|
}
|
|
10278
|
-
// After all contents are deleted, remove the directory itself
|
|
10279
|
-
await fs.promises.rmdir(dirPath);
|
|
10280
10143
|
}
|
|
10281
10144
|
catch (error) {
|
|
10282
|
-
// If the directory doesn't exist, that's fine
|
|
10283
10145
|
if (error.code !== 'ENOENT') {
|
|
10284
|
-
|
|
10146
|
+
console.error(`Error reading verbs directory ${this.verbsDir}:`, error);
|
|
10285
10147
|
}
|
|
10286
10148
|
}
|
|
10149
|
+
return allVerbs;
|
|
10287
10150
|
}
|
|
10288
|
-
|
|
10289
|
-
|
|
10290
|
-
|
|
10291
|
-
|
|
10151
|
+
async deleteVerb(id) {
|
|
10152
|
+
if (!this.isInitialized)
|
|
10153
|
+
await this.init();
|
|
10154
|
+
const filePath = path.join(this.verbsDir, `${id}.json`);
|
|
10292
10155
|
try {
|
|
10293
|
-
|
|
10294
|
-
return files.filter((file) => file.endsWith('.json')).length;
|
|
10156
|
+
await fs.promises.unlink(filePath);
|
|
10295
10157
|
}
|
|
10296
10158
|
catch (error) {
|
|
10297
|
-
|
|
10298
|
-
|
|
10299
|
-
|
|
10159
|
+
if (error.code !== 'ENOENT') {
|
|
10160
|
+
console.error(`Error deleting verb file ${filePath}:`, error);
|
|
10161
|
+
throw error;
|
|
10300
10162
|
}
|
|
10301
|
-
throw error;
|
|
10302
10163
|
}
|
|
10303
10164
|
}
|
|
10304
10165
|
/**
|
|
10305
|
-
*
|
|
10166
|
+
* Save metadata for an entity
|
|
10167
|
+
* @param id The ID of the entity
|
|
10168
|
+
* @param metadata The metadata to save
|
|
10306
10169
|
*/
|
|
10307
|
-
|
|
10308
|
-
|
|
10309
|
-
|
|
10310
|
-
|
|
10311
|
-
|
|
10312
|
-
return obj;
|
|
10170
|
+
async saveMetadata(id, metadata) {
|
|
10171
|
+
if (!this.isInitialized)
|
|
10172
|
+
await this.init();
|
|
10173
|
+
const filePath = path.join(this.metadataDir, `${id}.json`);
|
|
10174
|
+
await fs.promises.writeFile(filePath, JSON.stringify(metadata, null, 2));
|
|
10313
10175
|
}
|
|
10314
10176
|
/**
|
|
10315
|
-
* Get
|
|
10177
|
+
* Get metadata for an entity
|
|
10178
|
+
* @param id The ID of the entity
|
|
10179
|
+
* @returns Promise that resolves to the metadata or null if not found
|
|
10316
10180
|
*/
|
|
10317
|
-
async
|
|
10181
|
+
async getMetadata(id) {
|
|
10182
|
+
if (!this.isInitialized)
|
|
10183
|
+
await this.init();
|
|
10184
|
+
const filePath = path.join(this.metadataDir, `${id}.json`);
|
|
10318
10185
|
try {
|
|
10319
|
-
|
|
10320
|
-
|
|
10321
|
-
// If metadata exists and has a noun field, use the corresponding directory
|
|
10322
|
-
if (metadata && metadata.noun) {
|
|
10323
|
-
switch (metadata.noun) {
|
|
10324
|
-
case 'person':
|
|
10325
|
-
return this.personDir;
|
|
10326
|
-
case 'place':
|
|
10327
|
-
return this.placeDir;
|
|
10328
|
-
case 'thing':
|
|
10329
|
-
return this.thingDir;
|
|
10330
|
-
case 'event':
|
|
10331
|
-
return this.eventDir;
|
|
10332
|
-
case 'concept':
|
|
10333
|
-
return this.conceptDir;
|
|
10334
|
-
case 'content':
|
|
10335
|
-
return this.contentDir;
|
|
10336
|
-
default:
|
|
10337
|
-
return this.defaultDir;
|
|
10338
|
-
}
|
|
10339
|
-
}
|
|
10340
|
-
// If no metadata or no noun field, use the default directory
|
|
10341
|
-
return this.defaultDir;
|
|
10186
|
+
const data = await fs.promises.readFile(filePath, 'utf-8');
|
|
10187
|
+
return JSON.parse(data);
|
|
10342
10188
|
}
|
|
10343
10189
|
catch (error) {
|
|
10344
|
-
|
|
10345
|
-
|
|
10190
|
+
if (error.code !== 'ENOENT') {
|
|
10191
|
+
console.error(`Error reading metadata for ${id}:`, error);
|
|
10192
|
+
}
|
|
10193
|
+
return null;
|
|
10346
10194
|
}
|
|
10347
10195
|
}
|
|
10348
|
-
|
|
10349
|
-
|
|
10350
|
-
|
|
10196
|
+
async clear() {
|
|
10197
|
+
if (!this.isInitialized)
|
|
10198
|
+
await this.init();
|
|
10199
|
+
await fs.promises.rm(this.rootDir, { recursive: true, force: true });
|
|
10200
|
+
this.isInitialized = false; // Reset state
|
|
10201
|
+
await this.init(); // Re-create directories
|
|
10202
|
+
}
|
|
10351
10203
|
async getStorageStatus() {
|
|
10352
|
-
|
|
10353
|
-
|
|
10354
|
-
|
|
10355
|
-
let
|
|
10356
|
-
|
|
10357
|
-
|
|
10358
|
-
|
|
10359
|
-
|
|
10360
|
-
|
|
10361
|
-
|
|
10362
|
-
|
|
10363
|
-
|
|
10364
|
-
if (stats.isDirectory()) {
|
|
10365
|
-
size += await calculateDirSize(filePath);
|
|
10366
|
-
}
|
|
10367
|
-
else {
|
|
10368
|
-
size += stats.size;
|
|
10369
|
-
}
|
|
10204
|
+
if (!this.isInitialized)
|
|
10205
|
+
await this.init();
|
|
10206
|
+
const calculateSize = async (dirPath) => {
|
|
10207
|
+
let size = 0;
|
|
10208
|
+
try {
|
|
10209
|
+
const files = await fs.promises.readdir(dirPath, {
|
|
10210
|
+
withFileTypes: true
|
|
10211
|
+
});
|
|
10212
|
+
for (const file of files) {
|
|
10213
|
+
const fullPath = path.join(dirPath, file.name);
|
|
10214
|
+
if (file.isDirectory()) {
|
|
10215
|
+
size += await calculateSize(fullPath);
|
|
10370
10216
|
}
|
|
10371
|
-
|
|
10372
|
-
|
|
10373
|
-
|
|
10374
|
-
}
|
|
10375
|
-
return size;
|
|
10376
|
-
};
|
|
10377
|
-
// Calculate size for each directory
|
|
10378
|
-
const nodesDirSize = await calculateDirSize(this.nounsDir);
|
|
10379
|
-
const edgesDirSize = await calculateDirSize(this.verbsDir);
|
|
10380
|
-
const metadataDirSize = await calculateDirSize(this.metadataDir);
|
|
10381
|
-
// Calculate sizes of noun type directories
|
|
10382
|
-
const personDirSize = await calculateDirSize(this.personDir);
|
|
10383
|
-
const placeDirSize = await calculateDirSize(this.placeDir);
|
|
10384
|
-
const thingDirSize = await calculateDirSize(this.thingDir);
|
|
10385
|
-
const eventDirSize = await calculateDirSize(this.eventDir);
|
|
10386
|
-
const conceptDirSize = await calculateDirSize(this.conceptDir);
|
|
10387
|
-
const contentDirSize = await calculateDirSize(this.contentDir);
|
|
10388
|
-
const defaultDirSize = await calculateDirSize(this.defaultDir);
|
|
10389
|
-
// Note: The noun type directories are subdirectories of the nodes directory,
|
|
10390
|
-
// so their sizes are already included in nodesDirSize.
|
|
10391
|
-
// We don't need to add them again to avoid double counting.
|
|
10392
|
-
totalSize = nodesDirSize + edgesDirSize + metadataDirSize;
|
|
10393
|
-
// Get filesystem information
|
|
10394
|
-
let quota = null;
|
|
10395
|
-
let details = {
|
|
10396
|
-
nounTypes: {
|
|
10397
|
-
person: {
|
|
10398
|
-
size: personDirSize,
|
|
10399
|
-
count: await this.countFilesInDirectory(this.personDir)
|
|
10400
|
-
},
|
|
10401
|
-
place: {
|
|
10402
|
-
size: placeDirSize,
|
|
10403
|
-
count: await this.countFilesInDirectory(this.placeDir)
|
|
10404
|
-
},
|
|
10405
|
-
thing: {
|
|
10406
|
-
size: thingDirSize,
|
|
10407
|
-
count: await this.countFilesInDirectory(this.thingDir)
|
|
10408
|
-
},
|
|
10409
|
-
event: {
|
|
10410
|
-
size: eventDirSize,
|
|
10411
|
-
count: await this.countFilesInDirectory(this.eventDir)
|
|
10412
|
-
},
|
|
10413
|
-
concept: {
|
|
10414
|
-
size: conceptDirSize,
|
|
10415
|
-
count: await this.countFilesInDirectory(this.conceptDir)
|
|
10416
|
-
},
|
|
10417
|
-
content: {
|
|
10418
|
-
size: contentDirSize,
|
|
10419
|
-
count: await this.countFilesInDirectory(this.contentDir)
|
|
10420
|
-
},
|
|
10421
|
-
default: {
|
|
10422
|
-
size: defaultDirSize,
|
|
10423
|
-
count: await this.countFilesInDirectory(this.defaultDir)
|
|
10217
|
+
else {
|
|
10218
|
+
const stats = await fs.promises.stat(fullPath);
|
|
10219
|
+
size += stats.size;
|
|
10424
10220
|
}
|
|
10425
10221
|
}
|
|
10426
|
-
};
|
|
10427
|
-
try {
|
|
10428
|
-
// Try to get disk space information
|
|
10429
|
-
const stats = await fs.promises.statfs(this.rootDir);
|
|
10430
|
-
if (stats) {
|
|
10431
|
-
const availableSpace = stats.bavail * stats.bsize;
|
|
10432
|
-
const totalSpace = stats.blocks * stats.bsize;
|
|
10433
|
-
quota = totalSpace;
|
|
10434
|
-
details = {
|
|
10435
|
-
availableSpace,
|
|
10436
|
-
totalSpace,
|
|
10437
|
-
freePercentage: (availableSpace / totalSpace) * 100
|
|
10438
|
-
};
|
|
10439
|
-
}
|
|
10440
10222
|
}
|
|
10441
10223
|
catch (error) {
|
|
10442
|
-
|
|
10443
|
-
|
|
10444
|
-
try {
|
|
10445
|
-
const { exec } = await Promise.resolve().then(function () { return _child_processShim; });
|
|
10446
|
-
const util = await Promise.resolve().then(function () { return _utilShim$1; });
|
|
10447
|
-
const execPromise = util.promisify(exec);
|
|
10448
|
-
const { stdout } = await execPromise(`df -k "${this.rootDir}"`);
|
|
10449
|
-
const lines = stdout.trim().split('\n');
|
|
10450
|
-
if (lines.length > 1) {
|
|
10451
|
-
const parts = lines[1].split(/\s+/);
|
|
10452
|
-
if (parts.length >= 4) {
|
|
10453
|
-
const totalKB = parseInt(parts[1], 10);
|
|
10454
|
-
const usedKB = parseInt(parts[2], 10);
|
|
10455
|
-
const availableKB = parseInt(parts[3], 10);
|
|
10456
|
-
quota = totalKB * 1024;
|
|
10457
|
-
details = {
|
|
10458
|
-
availableSpace: availableKB * 1024,
|
|
10459
|
-
totalSpace: totalKB * 1024,
|
|
10460
|
-
freePercentage: (availableKB / totalKB) * 100
|
|
10461
|
-
};
|
|
10462
|
-
}
|
|
10463
|
-
}
|
|
10464
|
-
}
|
|
10465
|
-
catch (dfError) {
|
|
10466
|
-
console.warn('Unable to get disk space using df command:', dfError);
|
|
10224
|
+
if (error.code !== 'ENOENT') {
|
|
10225
|
+
console.error(`Could not calculate size for ${dirPath}:`, error);
|
|
10467
10226
|
}
|
|
10468
10227
|
}
|
|
10469
|
-
return
|
|
10470
|
-
|
|
10471
|
-
|
|
10472
|
-
|
|
10473
|
-
|
|
10474
|
-
|
|
10475
|
-
|
|
10476
|
-
|
|
10477
|
-
|
|
10478
|
-
|
|
10479
|
-
|
|
10480
|
-
|
|
10481
|
-
|
|
10482
|
-
|
|
10483
|
-
|
|
10484
|
-
}
|
|
10228
|
+
return size;
|
|
10229
|
+
};
|
|
10230
|
+
const totalSize = await calculateSize(this.rootDir);
|
|
10231
|
+
const nouns = await this.getAllNouns();
|
|
10232
|
+
const verbs = await this.getAllVerbs();
|
|
10233
|
+
return {
|
|
10234
|
+
type: 'FileSystem',
|
|
10235
|
+
used: totalSize,
|
|
10236
|
+
quota: null, // File system quota is not easily available from Node.js
|
|
10237
|
+
details: {
|
|
10238
|
+
rootDir: this.rootDir,
|
|
10239
|
+
nounCount: nouns.length,
|
|
10240
|
+
verbCount: verbs.length
|
|
10241
|
+
}
|
|
10242
|
+
};
|
|
10485
10243
|
}
|
|
10486
10244
|
}
|
|
10487
10245
|
|
|
@@ -14193,20 +13951,15 @@ class BrainyMCPService {
|
|
|
14193
13951
|
}
|
|
14194
13952
|
}
|
|
14195
13953
|
|
|
14196
|
-
/**
|
|
14197
|
-
* OPFS BrainyData
|
|
14198
|
-
* A vector database using HNSW indexing with Origin Private File System storage
|
|
14199
|
-
*/
|
|
14200
|
-
// Import unified text encoding utilities first to ensure they're available
|
|
14201
|
-
// Apply the TensorFlow.js platform patch if needed
|
|
14202
|
-
applyTensorFlowPatch();
|
|
14203
|
-
|
|
14204
13954
|
// Make Buffer available globally
|
|
14205
13955
|
if (typeof window !== 'undefined' && typeof globalThis.Buffer === 'undefined') {
|
|
14206
13956
|
globalThis.Buffer = buffer$1.Buffer;
|
|
14207
13957
|
}
|
|
14208
|
-
|
|
14209
|
-
|
|
13958
|
+
/**
|
|
13959
|
+
* Unified entry point for Brainy
|
|
13960
|
+
* This file exports everything from index.ts
|
|
13961
|
+
* Environment detection is handled here and made available to all components
|
|
13962
|
+
*/
|
|
14210
13963
|
// Export environment information
|
|
14211
13964
|
const environment = {
|
|
14212
13965
|
isBrowser: typeof window !== 'undefined',
|
|
@@ -22312,7 +22065,7 @@ class PlatformNode {
|
|
|
22312
22065
|
this.util = require$$1;
|
|
22313
22066
|
// According to the spec, the built-in encoder can do only UTF-8 encoding.
|
|
22314
22067
|
// https://developer.mozilla.org/en-US/docs/Web/API/TextEncoder/TextEncoder
|
|
22315
|
-
this.textEncoder = new TextEncoder();
|
|
22068
|
+
this.textEncoder = new this.util.TextEncoder();
|
|
22316
22069
|
}
|
|
22317
22070
|
fetch(path, requestInits) {
|
|
22318
22071
|
if (env().global.fetch != null) {
|
|
@@ -87531,9 +87284,5 @@ var universalSentenceEncoder_esm = /*#__PURE__*/Object.freeze({
|
|
|
87531
87284
|
version: version
|
|
87532
87285
|
});
|
|
87533
87286
|
|
|
87534
|
-
var _child_processShim = /*#__PURE__*/Object.freeze({
|
|
87535
|
-
__proto__: null
|
|
87536
|
-
});
|
|
87537
|
-
|
|
87538
87287
|
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, areWebWorkersAvailable, areWorkerThreadsAvailable, areWorkerThreadsAvailableSync, 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, isBrowser$1 as isBrowser, isNode, isThreadingAvailable, isThreadingAvailableAsync, isWebWorker, loadAugmentationModule, loadAugmentationsFromModules, manhattanDistance, pipeline, processStaticData, processStreamingData, registerAugmentation, sequentialPipeline, setAugmentationEnabled };
|
|
87539
87288
|
//# sourceMappingURL=unified.js.map
|