@soulcraft/brainy 0.9.22 → 0.9.25

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 CHANGED
@@ -3,10 +3,10 @@
3
3
  <br/><br/>
4
4
 
5
5
  [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
6
- [![Node.js](https://img.shields.io/badge/node-%3E%3D24.0.0-brightgreen.svg)](https://nodejs.org/)
6
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D23.0.0-brightgreen.svg)](https://nodejs.org/)
7
7
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.1.6-blue.svg)](https://www.typescriptlang.org/)
8
8
  [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md)
9
- [![npm](https://img.shields.io/badge/npm-v0.9.22-blue.svg)](https://www.npmjs.com/package/@soulcraft/brainy)
9
+ [![npm](https://img.shields.io/badge/npm-v0.9.25-blue.svg)](https://www.npmjs.com/package/@soulcraft/brainy)
10
10
 
11
11
  [//]: # ([![Cartographer]&#40;https://img.shields.io/badge/Cartographer-Official%20Standard-brightgreen&#41;]&#40;https://github.com/sodal-project/cartographer&#41;)
12
12
 
@@ -280,43 +280,6 @@ Brainy's pipeline is designed to handle streaming data efficiently:
280
280
  - Automatic thread management based on environment capabilities
281
281
  - Example: `executeTypedPipeline(augmentations, method, args, { mode: ExecutionMode.THREADED })`
282
282
 
283
- ### Build System
284
-
285
- Brainy uses a modern build system that optimizes for both Node.js and browser environments:
286
-
287
- 1. **ES Modules**
288
- - Built as ES modules for maximum compatibility
289
- - Works in modern browsers and Node.js environments
290
- - Separate optimized builds for browser and Node.js
291
-
292
- 2. **Environment-Specific Builds**
293
- - **Node.js Build**: Optimized for server environments with full functionality
294
- - **Browser Build**: Optimized for browser environments with reduced bundle size
295
- - **CLI Build**: Separate build for command-line interface functionality
296
- - Conditional exports in package.json for automatic environment detection
297
-
298
- 3. **Modular Architecture**
299
- - Core functionality and CLI are built separately
300
- - CLI (4MB) is only included when explicitly imported or used from command line
301
- - Reduced bundle size for browser and Node.js applications
302
-
303
- 4. **Environment Detection**
304
- - Automatically detects whether it's running in a browser or Node.js
305
- - Loads appropriate dependencies and functionality based on the environment
306
- - Provides consistent API across all environments
307
-
308
- 5. **TypeScript**
309
- - Written in TypeScript for type safety and better developer experience
310
- - Generates type definitions for TypeScript users
311
- - Compiled to ES2020 for modern JavaScript environments
312
-
313
- 6. **Build Scripts**
314
- - `npm run build`: Builds the core library without CLI
315
- - `npm run build:browser`: Builds the browser-optimized version
316
- - `npm run build:cli`: Builds the CLI version (only needed for CLI usage)
317
- - `npm run prepare:cli`: Builds the CLI for command-line usage
318
- - `npm run demo`: Builds both core library and browser versions and starts a demo server
319
- - GitHub Actions workflow: Automatically deploys the demo directory to GitHub Pages when pushing to the main branch
320
283
 
321
284
  ### Running the Pipeline
322
285
 
@@ -453,10 +416,6 @@ brainy visualize
453
416
  brainy visualize --root <id> --depth 3
454
417
  ```
455
418
 
456
- ### Publishing the CLI Package
457
-
458
- If you need to publish the CLI package to npm, please refer to the [CLI Publishing Guide](docs/publishing-cli.md) for
459
- detailed instructions.
460
419
 
461
420
  ### Using the CLI in Your Code
462
421
 
@@ -473,15 +432,6 @@ import '@soulcraft/brainy/cli'
473
432
  This will only build and load the CLI when you explicitly import it, keeping your bundle size small when you don't need
474
433
  the CLI.
475
434
 
476
- ### Development Usage
477
-
478
- ```bash
479
- # Run the CLI directly from the source
480
- npm run cli help
481
-
482
- # Generate a random graph for testing
483
- npm run cli generate-random-graph --noun-count 20 --verb-count 40
484
- ```
485
435
 
486
436
  ### Available Commands
487
437
 
@@ -1303,74 +1253,14 @@ comprehensive [Scaling Strategy](scalingStrategy.md) document.
1303
1253
 
1304
1254
  - Node.js >= 24.0.0
1305
1255
 
1306
- ### Node.js 24 Optimizations
1307
-
1308
- Brainy takes advantage of several optimizations available in Node.js 24:
1309
-
1310
- 1. **Improved Worker Threads Performance**: The multithreading system has been completely rewritten to leverage Node.js
1311
- 24's enhanced Worker Threads API, resulting in better performance for compute-intensive operations like embedding
1312
- generation and vector similarity calculations.
1313
-
1314
- 2. **Worker Pool Management**: A sophisticated worker pool system reuses worker threads to minimize the overhead of
1315
- creating and destroying threads, leading to more efficient resource utilization.
1316
-
1317
- 3. **Dynamic Module Imports**: Uses the new `node:` protocol prefix for importing core modules, which provides better
1318
- performance and more reliable module resolution.
1319
-
1320
- 4. **ES Modules Optimizations**: Takes advantage of Node.js 24's improved ESM implementation for faster module loading
1321
- and execution.
1322
-
1323
- 5. **Enhanced Error Handling**: Implements more robust error handling patterns available in Node.js 24 for better
1324
- stability and debugging.
1325
-
1326
- These optimizations are particularly beneficial for:
1327
-
1328
- - Large-scale vector operations
1329
- - Batch processing of embeddings
1330
- - Real-time data processing pipelines
1331
- - High-throughput search operations
1332
1256
 
1333
1257
  ## Contributing
1334
1258
 
1335
1259
  For detailed contribution guidelines, please see [CONTRIBUTING.md](CONTRIBUTING.md).
1336
1260
 
1337
- We have a [Code of Conduct](CODE_OF_CONDUCT.md) that all contributors are expected to follow.
1338
-
1339
- ### Reporting Issues
1340
-
1341
- We use GitHub issues to track bugs and feature requests. Please use the provided issue templates when creating a new
1342
- issue:
1343
-
1344
- - [Bug Report Template](.github/ISSUE_TEMPLATE/bug_report.md)
1345
- - [Feature Request Template](.github/ISSUE_TEMPLATE/feature_request.md)
1346
-
1347
- ### Code Style Guidelines
1261
+ For developer documentation, including building, testing, and publishing instructions, please see [DEVELOPERS.md](DEVELOPERS.md).
1348
1262
 
1349
- Brainy follows a specific code style to maintain consistency throughout the codebase:
1350
-
1351
- 1. **No Semicolons**: All code in the project should avoid using semicolons wherever possible
1352
- 2. **Formatting**: The project uses Prettier for code formatting
1353
- 3. **Linting**: ESLint is configured with specific rules for the project
1354
- 4. **TypeScript Configuration**: Strict type checking enabled with ES2020 target
1355
- 5. **Commit Messages**: Use the imperative mood and keep the first line concise
1356
-
1357
- ### Development Workflow
1358
-
1359
- 1. Fork the repository
1360
- 2. Create a feature branch
1361
- 3. Make your changes
1362
- 4. Submit a pull request
1363
-
1364
- ### Badge Maintenance
1365
-
1366
- The README badges are automatically updated during the build process:
1367
-
1368
- 1. **npm Version Badge**: The npm version badge is automatically updated to match the version in package.json when:
1369
- - Running `npm run build` (via the prebuild script)
1370
- - Running `npm version` commands (patch, minor, major)
1371
- - Manually running `node scripts/generate-version.js`
1372
-
1373
- This ensures that the badge always reflects the current version in package.json, even before publishing to npm.
1263
+ We have a [Code of Conduct](CODE_OF_CONDUCT.md) that all contributors are expected to follow.
1374
1264
 
1375
1265
  ## License
1376
1266
 
package/dist/brainy.js CHANGED
@@ -2900,6 +2900,19 @@ let UniversalSentenceEncoder$1 = class UniversalSentenceEncoder {
2900
2900
  this.use = null;
2901
2901
  this.backend = 'cpu'; // Default to CPU
2902
2902
  }
2903
+ /**
2904
+ * Add polyfills and patches for TensorFlow.js compatibility
2905
+ * This addresses issues with TensorFlow.js in Node.js environments
2906
+ */
2907
+ addNodeCompatibilityPolyfills() {
2908
+ // Only apply in Node.js environment
2909
+ if (typeof process === 'undefined' ||
2910
+ !process.versions ||
2911
+ !process.versions.node) {
2912
+ return;
2913
+ }
2914
+ // No compatibility patches needed - TensorFlow.js now works correctly with Node.js 24+
2915
+ }
2903
2916
  /**
2904
2917
  * Initialize the embedding model
2905
2918
  */
@@ -2916,6 +2929,8 @@ let UniversalSentenceEncoder$1 = class UniversalSentenceEncoder {
2916
2929
  }
2917
2930
  originalWarn(message, ...optionalParams);
2918
2931
  };
2932
+ // Add polyfills for TensorFlow.js compatibility
2933
+ this.addNodeCompatibilityPolyfills();
2919
2934
  // TensorFlow.js will use its default EPSILON value
2920
2935
  // Dynamically import TensorFlow.js core module and backends
2921
2936
  // Use type assertions to tell TypeScript these modules exist
@@ -9312,9 +9327,42 @@ class BrainyData {
9312
9327
  }
9313
9328
  }
9314
9329
 
9315
- // We'll dynamically import Node.js built-in modules
9330
+ // Import Node.js built-in modules
9331
+ // Using require for compatibility with Node.js
9316
9332
  let fs;
9317
9333
  let path;
9334
+ // Initialize these modules immediately if in Node.js environment
9335
+ if (typeof process !== 'undefined' &&
9336
+ process.versions &&
9337
+ process.versions.node) {
9338
+ try {
9339
+ // Use require for Node.js built-in modules
9340
+ fs = require('fs');
9341
+ path = require('path');
9342
+ // Verify that path has the required methods
9343
+ if (!path || typeof path.resolve !== 'function') {
9344
+ throw new Error('path module is missing required methods');
9345
+ }
9346
+ }
9347
+ catch (e) {
9348
+ console.warn('Failed to load Node.js modules with require:', e);
9349
+ // Try using dynamic import as a fallback
9350
+ try {
9351
+ // Use a synchronous approach to ensure modules are loaded before continuing
9352
+ const pathModule = require('node:path');
9353
+ const fsModule = require('node:fs');
9354
+ path = pathModule;
9355
+ fs = fsModule;
9356
+ // Verify that path has the required methods
9357
+ if (!path || typeof path.resolve !== 'function') {
9358
+ throw new Error('path module from node:path is missing required methods');
9359
+ }
9360
+ }
9361
+ catch (nodeImportError) {
9362
+ console.warn('Failed to load Node.js modules with node: prefix:', nodeImportError);
9363
+ }
9364
+ }
9365
+ }
9318
9366
  // Constants for directory and file names
9319
9367
  const ROOT_DIR = 'brainy-data';
9320
9368
  const NOUNS_DIR = 'nouns';
@@ -9355,32 +9403,91 @@ class FileSystemStorage {
9355
9403
  return;
9356
9404
  }
9357
9405
  try {
9358
- // Dynamically import Node.js built-in modules
9359
- try {
9360
- // Import the modules
9361
- const fsModule = await Promise.resolve().then(function () { return _fsShim$1; });
9362
- const pathModule = await Promise.resolve().then(function () { return _pathShim$1; });
9363
- // Assign to our module-level variables
9364
- fs = fsModule.default || fsModule;
9365
- path = pathModule.default || pathModule;
9366
- // Now set up the directory paths
9367
- const rootDir = this.rootDir || process.cwd();
9368
- this.rootDir = path.resolve(rootDir, ROOT_DIR);
9369
- this.nounsDir = path.join(this.rootDir, NOUNS_DIR);
9370
- this.verbsDir = path.join(this.rootDir, VERBS_DIR);
9371
- this.metadataDir = path.join(this.rootDir, METADATA_DIR);
9372
- // Set up noun type directory paths
9373
- this.personDir = path.join(this.nounsDir, PERSON_DIR);
9374
- this.placeDir = path.join(this.nounsDir, PLACE_DIR);
9375
- this.thingDir = path.join(this.nounsDir, THING_DIR);
9376
- this.eventDir = path.join(this.nounsDir, EVENT_DIR);
9377
- this.conceptDir = path.join(this.nounsDir, CONCEPT_DIR);
9378
- this.contentDir = path.join(this.nounsDir, CONTENT_DIR);
9379
- this.defaultDir = path.join(this.nounsDir, DEFAULT_DIR);
9380
- }
9381
- catch (importError) {
9382
- throw new Error(`Failed to import Node.js modules: ${importError}. This adapter requires a Node.js environment.`);
9406
+ // Check if fs and path modules are available and have required methods
9407
+ if (!fs || !path || typeof path.resolve !== 'function') {
9408
+ console.log('Node.js modules not properly loaded, attempting to load them now');
9409
+ // Try multiple approaches to load the modules
9410
+ const loadAttempts = [
9411
+ // Attempt 1: Use require
9412
+ async () => {
9413
+ console.log('Attempting to load Node.js modules with require()');
9414
+ const fsModule = require('fs');
9415
+ const pathModule = require('path');
9416
+ if (!pathModule || typeof pathModule.resolve !== 'function') {
9417
+ throw new Error('path.resolve is not a function after require()');
9418
+ }
9419
+ return { fs: fsModule, path: pathModule };
9420
+ },
9421
+ // Attempt 2: Use require with node: prefix
9422
+ async () => {
9423
+ console.log('Attempting to load Node.js modules with require("node:...")');
9424
+ const fsModule = require('node:fs');
9425
+ const pathModule = require('node:path');
9426
+ if (!pathModule || typeof pathModule.resolve !== 'function') {
9427
+ throw new Error('path.resolve is not a function after require("node:path")');
9428
+ }
9429
+ return { fs: fsModule, path: pathModule };
9430
+ },
9431
+ // Attempt 3: Use dynamic import
9432
+ async () => {
9433
+ console.log('Attempting to load Node.js modules with dynamic import');
9434
+ const fsModule = await Promise.resolve().then(function () { return _fsShim$1; });
9435
+ const pathModule = await Promise.resolve().then(function () { return _pathShim$1; });
9436
+ const fsResolved = fsModule.default || fsModule;
9437
+ const pathResolved = pathModule.default || pathModule;
9438
+ if (!pathResolved || typeof pathResolved.resolve !== 'function') {
9439
+ throw new Error('path.resolve is not a function after dynamic import');
9440
+ }
9441
+ return { fs: fsResolved, path: pathResolved };
9442
+ },
9443
+ // Attempt 4: Use dynamic import with node: prefix
9444
+ async () => {
9445
+ console.log('Attempting to load Node.js modules with dynamic import("node:...")');
9446
+ const fsModule = await import('node:fs');
9447
+ const pathModule = await import('node:path');
9448
+ const fsResolved = fsModule.default || fsModule;
9449
+ const pathResolved = pathModule.default || pathModule;
9450
+ if (!pathResolved || typeof pathResolved.resolve !== 'function') {
9451
+ throw new Error('path.resolve is not a function after dynamic import("node:path")');
9452
+ }
9453
+ return { fs: fsResolved, path: pathResolved };
9454
+ }
9455
+ ];
9456
+ // Try each loading method until one succeeds
9457
+ let lastError = null;
9458
+ for (const loadAttempt of loadAttempts) {
9459
+ try {
9460
+ const modules = await loadAttempt();
9461
+ fs = modules.fs;
9462
+ path = modules.path;
9463
+ console.log('Successfully loaded Node.js modules');
9464
+ break;
9465
+ }
9466
+ catch (error) {
9467
+ lastError = error;
9468
+ console.warn(`Module loading attempt failed:`, error);
9469
+ // Continue to the next attempt
9470
+ }
9471
+ }
9472
+ // If all attempts failed, throw an error
9473
+ if (!fs || !path || typeof path.resolve !== 'function') {
9474
+ throw new Error(`Failed to import Node.js modules after multiple attempts: ${lastError}. This adapter requires a Node.js environment.`);
9475
+ }
9383
9476
  }
9477
+ // Now set up the directory paths
9478
+ const rootDir = this.rootDir || process.cwd();
9479
+ this.rootDir = path.resolve(rootDir, ROOT_DIR);
9480
+ this.nounsDir = path.join(this.rootDir, NOUNS_DIR);
9481
+ this.verbsDir = path.join(this.rootDir, VERBS_DIR);
9482
+ this.metadataDir = path.join(this.rootDir, METADATA_DIR);
9483
+ // Set up noun type directory paths
9484
+ this.personDir = path.join(this.nounsDir, PERSON_DIR);
9485
+ this.placeDir = path.join(this.nounsDir, PLACE_DIR);
9486
+ this.thingDir = path.join(this.nounsDir, THING_DIR);
9487
+ this.eventDir = path.join(this.nounsDir, EVENT_DIR);
9488
+ this.conceptDir = path.join(this.nounsDir, CONCEPT_DIR);
9489
+ this.contentDir = path.join(this.nounsDir, CONTENT_DIR);
9490
+ this.defaultDir = path.join(this.nounsDir, DEFAULT_DIR);
9384
9491
  // Create directories if they don't exist
9385
9492
  await this.ensureDirectoryExists(this.rootDir);
9386
9493
  await this.ensureDirectoryExists(this.nounsDir);