@soulcraft/brainy 3.0.1 → 3.1.1

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
@@ -11,11 +11,11 @@
11
11
 
12
12
  **🧠 Brainy 3.0 - Universal Knowledge Protocol™**
13
13
 
14
- **World's first Triple Intelligence™ database** unifying vector similarity, graph relationships, and document filtering in one magical API. Model ANY data from ANY domain using 31 standardized noun types × 40 verb types.
14
+ **World's first Triple Intelligence™ database** unifying vector similarity, graph relationships, and document filtering in one magical API. **Framework-friendly design** works seamlessly with Next.js, React, Vue, Angular, and any modern JavaScript framework.
15
15
 
16
16
  **Why Brainy Leads**: We're the first to solve the impossible—combining three different database paradigms (vector, graph, document) into one unified query interface. This breakthrough enables us to be the Universal Knowledge Protocol where all tools, augmentations, and AI models speak the same language.
17
17
 
18
- **Build once, integrate everywhere.** O(log n) performance, <10ms search latency, production-ready.
18
+ **Framework-first design.** Built for modern web development with zero configuration and automatic framework compatibility. O(log n) performance, <10ms search latency, production-ready.
19
19
 
20
20
  ## 🎉 What's New in 3.0
21
21
 
@@ -98,6 +98,73 @@ const filtered = await brain.find({
98
98
  })
99
99
  ```
100
100
 
101
+ ## 🌐 Framework Integration
102
+
103
+ **Brainy 3.0 is framework-first!** Works seamlessly with any modern JavaScript framework:
104
+
105
+ ### ⚛️ **React & Next.js**
106
+ ```javascript
107
+ import { Brainy } from '@soulcraft/brainy'
108
+
109
+ function SearchComponent() {
110
+ const [brain] = useState(() => new Brainy())
111
+
112
+ useEffect(() => {
113
+ brain.init()
114
+ }, [])
115
+
116
+ const handleSearch = async (query) => {
117
+ const results = await brain.find(query)
118
+ setResults(results)
119
+ }
120
+ }
121
+ ```
122
+
123
+ ### 🟢 **Vue.js & Nuxt.js**
124
+ ```javascript
125
+ import { Brainy } from '@soulcraft/brainy'
126
+
127
+ export default {
128
+ async mounted() {
129
+ this.brain = new Brainy()
130
+ await this.brain.init()
131
+ },
132
+ methods: {
133
+ async search(query) {
134
+ return await this.brain.find(query)
135
+ }
136
+ }
137
+ }
138
+ ```
139
+
140
+ ### 🅰️ **Angular**
141
+ ```typescript
142
+ import { Injectable } from '@angular/core'
143
+ import { Brainy } from '@soulcraft/brainy'
144
+
145
+ @Injectable({ providedIn: 'root' })
146
+ export class BrainyService {
147
+ private brain = new Brainy()
148
+
149
+ async init() {
150
+ await this.brain.init()
151
+ }
152
+
153
+ async search(query: string) {
154
+ return await this.brain.find(query)
155
+ }
156
+ }
157
+ ```
158
+
159
+ ### 🔥 **Other Frameworks**
160
+ Brainy works with **any** framework that supports ES6 imports: Svelte, Solid.js, Qwik, Fresh, and more!
161
+
162
+ **Framework Compatibility:**
163
+ - ✅ All modern bundlers (Webpack, Vite, Rollup, Parcel)
164
+ - ✅ SSR/SSG (Next.js, Nuxt, SvelteKit, Astro)
165
+ - ✅ Edge runtimes (Vercel Edge, Cloudflare Workers)
166
+ - ✅ Browser and Node.js environments
167
+
101
168
  ## 📋 System Requirements
102
169
 
103
170
  **Node.js Version:** 22 LTS or later (recommended)
@@ -436,9 +503,9 @@ const brain = new Brainy({
436
503
  }
437
504
  })
438
505
 
439
- // Browser Storage (OPFS)
506
+ // Browser Storage (OPFS) - Works with frameworks
440
507
  const brain = new Brainy({
441
- storage: {type: 'opfs'}
508
+ storage: {type: 'opfs'} // Framework handles browser polyfills
442
509
  })
443
510
 
444
511
  // S3 Compatible (Production)
@@ -629,6 +696,12 @@ We welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
629
696
 
630
697
  ## 📖 Documentation
631
698
 
699
+ ### Framework Integration
700
+ - [Framework Integration Guide](docs/guides/framework-integration.md) - **NEW!** Complete framework setup guide
701
+ - [Next.js Integration](docs/guides/nextjs-integration.md) - **NEW!** React and Next.js examples
702
+ - [Vue.js Integration](docs/guides/vue-integration.md) - **NEW!** Vue and Nuxt examples
703
+
704
+ ### Core Documentation
632
705
  - [Getting Started Guide](docs/guides/getting-started.md)
633
706
  - [API Reference](docs/api/README.md)
634
707
  - [Architecture Overview](docs/architecture/overview.md)
package/dist/brainy.d.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  import { ImprovedNeuralAPI } from './neural/improvedNeuralAPI.js';
8
8
  import { NaturalLanguageProcessor } from './neural/naturalLanguageProcessor.js';
9
9
  import { TripleIntelligenceSystem } from './triple/TripleIntelligenceSystem.js';
10
- import { Entity, Relation, Result, AddParams, UpdateParams, RelateParams, FindParams, SimilarParams, GetRelationsParams, AddManyParams, DeleteManyParams, BatchResult, BrainyConfig } from './types/brainy.types.js';
10
+ import { Entity, Relation, Result, AddParams, UpdateParams, RelateParams, FindParams, SimilarParams, GetRelationsParams, AddManyParams, DeleteManyParams, RelateManyParams, BatchResult, BrainyConfig } from './types/brainy.types.js';
11
11
  import { NounType } from './types/graphTypes.js';
12
12
  /**
13
13
  * The main Brainy class - Clean, Beautiful, Powerful
@@ -98,6 +98,10 @@ export declare class Brainy<T = any> {
98
98
  continueOnError?: boolean;
99
99
  onProgress?: (completed: number, total: number) => void;
100
100
  }): Promise<BatchResult<string>>;
101
+ /**
102
+ * Create multiple relationships with batch processing
103
+ */
104
+ relateMany(params: RelateManyParams<T>): Promise<string[]>;
101
105
  /**
102
106
  * Clear all data from the database
103
107
  */
package/dist/brainy.js CHANGED
@@ -16,6 +16,7 @@ import { NaturalLanguageProcessor } from './neural/naturalLanguageProcessor.js';
16
16
  import { TripleIntelligenceSystem } from './triple/TripleIntelligenceSystem.js';
17
17
  import { MetadataIndexManager } from './utils/metadataIndex.js';
18
18
  import { GraphAdjacencyIndex } from './graph/graphAdjacencyIndex.js';
19
+ import { configureLogger, LogLevel } from './utils/logger.js';
19
20
  import { NounType } from './types/graphTypes.js';
20
21
  /**
21
22
  * The main Brainy class - Clean, Beautiful, Powerful
@@ -50,13 +51,22 @@ export class Brainy {
50
51
  storage: { ...this.config.storage, ...configOverrides.storage },
51
52
  model: { ...this.config.model, ...configOverrides.model },
52
53
  index: { ...this.config.index, ...configOverrides.index },
53
- augmentations: { ...this.config.augmentations, ...configOverrides.augmentations }
54
+ augmentations: { ...this.config.augmentations, ...configOverrides.augmentations },
55
+ verbose: configOverrides.verbose ?? this.config.verbose,
56
+ silent: configOverrides.silent ?? this.config.silent
54
57
  };
55
58
  // Set dimensions if provided
56
59
  if (dimensions) {
57
60
  this.dimensions = dimensions;
58
61
  }
59
62
  }
63
+ // Configure logging based on config options
64
+ if (this.config.silent) {
65
+ configureLogger({ level: -1 }); // Suppress all logs
66
+ }
67
+ else if (this.config.verbose) {
68
+ configureLogger({ level: LogLevel.DEBUG }); // Enable verbose logging
69
+ }
60
70
  try {
61
71
  // Setup and initialize storage
62
72
  this.storage = await this.setupStorage();
@@ -663,6 +673,66 @@ export class Brainy {
663
673
  result.duration = Date.now() - startTime;
664
674
  return result;
665
675
  }
676
+ /**
677
+ * Create multiple relationships with batch processing
678
+ */
679
+ async relateMany(params) {
680
+ await this.ensureInitialized();
681
+ const result = {
682
+ successful: [],
683
+ failed: [],
684
+ total: params.items.length,
685
+ duration: 0
686
+ };
687
+ const startTime = Date.now();
688
+ const chunkSize = params.chunkSize || 100;
689
+ for (let i = 0; i < params.items.length; i += chunkSize) {
690
+ const chunk = params.items.slice(i, i + chunkSize);
691
+ if (params.parallel) {
692
+ // Process chunk in parallel
693
+ const promises = chunk.map(async (item) => {
694
+ try {
695
+ const relationId = await this.relate(item);
696
+ result.successful.push(relationId);
697
+ }
698
+ catch (error) {
699
+ result.failed.push({
700
+ item,
701
+ error: error.message || 'Unknown error'
702
+ });
703
+ if (!params.continueOnError) {
704
+ throw error;
705
+ }
706
+ }
707
+ });
708
+ await Promise.all(promises);
709
+ }
710
+ else {
711
+ // Process chunk sequentially
712
+ for (const item of chunk) {
713
+ try {
714
+ const relationId = await this.relate(item);
715
+ result.successful.push(relationId);
716
+ }
717
+ catch (error) {
718
+ result.failed.push({
719
+ item,
720
+ error: error.message || 'Unknown error'
721
+ });
722
+ if (!params.continueOnError) {
723
+ throw error;
724
+ }
725
+ }
726
+ }
727
+ }
728
+ // Report progress
729
+ if (params.onProgress) {
730
+ params.onProgress(result.successful.length + result.failed.length, result.total);
731
+ }
732
+ }
733
+ result.duration = Date.now() - startTime;
734
+ return result.successful;
735
+ }
666
736
  /**
667
737
  * Clear all data from the database
668
738
  */
@@ -1130,7 +1200,9 @@ export class Brainy {
1130
1200
  warmup: config?.warmup ?? false,
1131
1201
  realtime: config?.realtime ?? false,
1132
1202
  multiTenancy: config?.multiTenancy ?? false,
1133
- telemetry: config?.telemetry ?? false
1203
+ telemetry: config?.telemetry ?? false,
1204
+ verbose: config?.verbose ?? false,
1205
+ silent: config?.silent ?? false
1134
1206
  };
1135
1207
  }
1136
1208
  /**
@@ -4040,5 +4040,7 @@ export const PATTERNS_METADATA = {
4040
4040
  total: 403493
4041
4041
  }
4042
4042
  };
4043
- console.log(`🧠 Brainy Pattern Library loaded: ${EMBEDDED_PATTERNS.length} patterns, ${(PATTERNS_METADATA.sizeBytes.total / 1024).toFixed(1)}KB total`);
4043
+ // Only log if not suppressed - controlled by logging configuration
4044
+ import { prodLog } from '../utils/logger.js';
4045
+ prodLog.info(`🧠 Brainy Pattern Library loaded: ${EMBEDDED_PATTERNS.length} patterns, ${(PATTERNS_METADATA.sizeBytes.total / 1024).toFixed(1)}KB total`);
4044
4046
  //# sourceMappingURL=embeddedPatterns.js.map
@@ -503,8 +503,23 @@ export class FileSystemStorage extends BaseStorage {
503
503
  }
504
504
  // Get page of files
505
505
  const pageFiles = nounFiles.slice(startIndex, startIndex + limit);
506
- // Load nouns
506
+ // Load nouns - count actual successfully loaded items
507
507
  const items = [];
508
+ let successfullyLoaded = 0;
509
+ let totalValidFiles = 0;
510
+ // First pass: count total valid files (for accurate totalCount)
511
+ // This is necessary to fix the pagination bug
512
+ for (const file of nounFiles) {
513
+ try {
514
+ // Just check if file exists and is readable
515
+ await fs.promises.access(path.join(this.nounsDir, file), fs.constants.R_OK);
516
+ totalValidFiles++;
517
+ }
518
+ catch {
519
+ // File not readable, skip
520
+ }
521
+ }
522
+ // Second pass: load the current page
508
523
  for (const file of pageFiles) {
509
524
  try {
510
525
  const data = await fs.promises.readFile(path.join(this.nounsDir, file), 'utf-8');
@@ -523,18 +538,21 @@ export class FileSystemStorage extends BaseStorage {
523
538
  continue;
524
539
  }
525
540
  items.push(noun);
541
+ successfullyLoaded++;
526
542
  }
527
543
  catch (error) {
528
544
  console.warn(`Failed to read noun file ${file}:`, error);
529
545
  }
530
546
  }
531
- const hasMore = startIndex + limit < nounFiles.length;
547
+ // CRITICAL FIX: hasMore should be based on actual valid files, not just file count
548
+ // Also check if we actually loaded any items from this page
549
+ const hasMore = (startIndex + limit < totalValidFiles) && (successfullyLoaded > 0 || startIndex === 0);
532
550
  const nextCursor = hasMore && pageFiles.length > 0
533
551
  ? pageFiles[pageFiles.length - 1].replace('.json', '')
534
552
  : undefined;
535
553
  return {
536
554
  items,
537
- totalCount: nounFiles.length,
555
+ totalCount: totalValidFiles, // Use actual valid file count, not all files
538
556
  hasMore,
539
557
  nextCursor
540
558
  };
@@ -345,10 +345,14 @@ export class BaseStorage extends BaseStorageAdapter {
345
345
  });
346
346
  // Apply offset if needed (some adapters might not support offset)
347
347
  const items = result.items.slice(offset);
348
+ // CRITICAL SAFETY CHECK: Prevent infinite loops
349
+ // If we have no items but hasMore is true, force hasMore to false
350
+ // This prevents pagination bugs from causing infinite loops
351
+ const safeHasMore = items.length > 0 ? result.hasMore : false;
348
352
  return {
349
353
  items,
350
354
  totalCount: result.totalCount || totalCount,
351
- hasMore: result.hasMore,
355
+ hasMore: safeHasMore,
352
356
  nextCursor: result.nextCursor
353
357
  };
354
358
  }
@@ -490,10 +494,14 @@ export class BaseStorage extends BaseStorageAdapter {
490
494
  });
491
495
  // Apply offset if needed (some adapters might not support offset)
492
496
  const items = result.items.slice(offset);
497
+ // CRITICAL SAFETY CHECK: Prevent infinite loops
498
+ // If we have no items but hasMore is true, force hasMore to false
499
+ // This prevents pagination bugs from causing infinite loops
500
+ const safeHasMore = items.length > 0 ? result.hasMore : false;
493
501
  return {
494
502
  items,
495
503
  totalCount: result.totalCount || totalCount,
496
- hasMore: result.hasMore,
504
+ hasMore: safeHasMore,
497
505
  nextCursor: result.nextCursor
498
506
  };
499
507
  }
@@ -273,6 +273,8 @@ export interface BrainyConfig {
273
273
  realtime?: boolean;
274
274
  multiTenancy?: boolean;
275
275
  telemetry?: boolean;
276
+ verbose?: boolean;
277
+ silent?: boolean;
276
278
  }
277
279
  /**
278
280
  * Neural similarity parameters
@@ -1,17 +1,21 @@
1
1
  /**
2
2
  * Universal Crypto implementation
3
- * Works in all environments: Browser, Node.js, Serverless
3
+ * Framework-friendly: Trusts that frameworks provide crypto polyfills
4
+ * Works in all environments: Browser (via framework), Node.js, Serverless
4
5
  */
5
6
  /**
6
7
  * Generate random bytes
8
+ * Framework-friendly: Assumes crypto API is available via framework polyfills
7
9
  */
8
10
  export declare function randomBytes(size: number): Uint8Array;
9
11
  /**
10
12
  * Generate random UUID
13
+ * Framework-friendly: Assumes crypto.randomUUID is available via framework polyfills
11
14
  */
12
15
  export declare function randomUUID(): string;
13
16
  /**
14
17
  * Create hash (simplified interface)
18
+ * Framework-friendly: Relies on Node.js crypto or framework-provided implementations
15
19
  */
16
20
  export declare function createHash(algorithm: string): {
17
21
  update: (data: string | Uint8Array) => any;
@@ -19,6 +23,7 @@ export declare function createHash(algorithm: string): {
19
23
  };
20
24
  /**
21
25
  * Create HMAC
26
+ * Framework-friendly: Relies on Node.js crypto or framework-provided implementations
22
27
  */
23
28
  export declare function createHmac(algorithm: string, key: string | Uint8Array): {
24
29
  update: (data: string | Uint8Array) => any;
@@ -26,14 +31,17 @@ export declare function createHmac(algorithm: string, key: string | Uint8Array):
26
31
  };
27
32
  /**
28
33
  * PBKDF2 synchronous
34
+ * Framework-friendly: Relies on Node.js crypto or framework-provided implementations
29
35
  */
30
36
  export declare function pbkdf2Sync(password: string | Uint8Array, salt: string | Uint8Array, iterations: number, keylen: number, digest: string): Uint8Array;
31
37
  /**
32
38
  * Scrypt synchronous
39
+ * Framework-friendly: Relies on Node.js crypto or framework-provided implementations
33
40
  */
34
41
  export declare function scryptSync(password: string | Uint8Array, salt: string | Uint8Array, keylen: number, options?: any): Uint8Array;
35
42
  /**
36
43
  * Create cipher
44
+ * Framework-friendly: Relies on Node.js crypto or framework-provided implementations
37
45
  */
38
46
  export declare function createCipheriv(algorithm: string, key: Uint8Array, iv: Uint8Array): {
39
47
  update: (data: string, inputEncoding?: string, outputEncoding?: string) => string;
@@ -41,6 +49,7 @@ export declare function createCipheriv(algorithm: string, key: Uint8Array, iv: U
41
49
  };
42
50
  /**
43
51
  * Create decipher
52
+ * Framework-friendly: Relies on Node.js crypto or framework-provided implementations
44
53
  */
45
54
  export declare function createDecipheriv(algorithm: string, key: Uint8Array, iv: Uint8Array): {
46
55
  update: (data: string, inputEncoding?: string, outputEncoding?: string) => string;
@@ -48,6 +57,7 @@ export declare function createDecipheriv(algorithm: string, key: Uint8Array, iv:
48
57
  };
49
58
  /**
50
59
  * Timing safe equal
60
+ * Framework-friendly: Relies on Node.js crypto or framework-provided implementations
51
61
  */
52
62
  export declare function timingSafeEqual(a: Uint8Array, b: Uint8Array): boolean;
53
63
  declare const _default: {
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * Universal Crypto implementation
3
- * Works in all environments: Browser, Node.js, Serverless
3
+ * Framework-friendly: Trusts that frameworks provide crypto polyfills
4
+ * Works in all environments: Browser (via framework), Node.js, Serverless
4
5
  */
5
- import { isBrowser, isNode } from '../utils/environment.js';
6
+ import { isNode } from '../utils/environment.js';
6
7
  let nodeCrypto = null;
7
8
  // Dynamic import for Node.js crypto (only in Node.js environment)
8
9
  if (isNode()) {
@@ -15,29 +16,26 @@ if (isNode()) {
15
16
  }
16
17
  /**
17
18
  * Generate random bytes
19
+ * Framework-friendly: Assumes crypto API is available via framework polyfills
18
20
  */
19
21
  export function randomBytes(size) {
20
- if (isBrowser() || typeof crypto !== 'undefined') {
21
- // Use Web Crypto API (available in browsers and modern Node.js)
22
+ if (typeof crypto !== 'undefined') {
23
+ // Use Web Crypto API (available in browsers via framework polyfills and modern Node.js)
22
24
  const array = new Uint8Array(size);
23
25
  crypto.getRandomValues(array);
24
26
  return array;
25
27
  }
26
28
  else if (nodeCrypto) {
27
- // Use Node.js crypto as fallback
29
+ // Use Node.js crypto
28
30
  return new Uint8Array(nodeCrypto.randomBytes(size));
29
31
  }
30
32
  else {
31
- // Fallback for environments without crypto
32
- const array = new Uint8Array(size);
33
- for (let i = 0; i < size; i++) {
34
- array[i] = Math.floor(Math.random() * 256);
35
- }
36
- return array;
33
+ throw new Error('Crypto API not available. Framework bundlers should provide crypto polyfills.');
37
34
  }
38
35
  }
39
36
  /**
40
37
  * Generate random UUID
38
+ * Framework-friendly: Assumes crypto.randomUUID is available via framework polyfills
41
39
  */
42
40
  export function randomUUID() {
43
41
  if (typeof crypto !== 'undefined' && crypto.randomUUID) {
@@ -47,158 +45,91 @@ export function randomUUID() {
47
45
  return nodeCrypto.randomUUID();
48
46
  }
49
47
  else {
50
- // Fallback UUID generation
51
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
52
- const r = Math.random() * 16 | 0;
53
- const v = c === 'x' ? r : (r & 0x3 | 0x8);
54
- return v.toString(16);
55
- });
48
+ throw new Error('crypto.randomUUID not available. Framework bundlers should provide crypto polyfills.');
56
49
  }
57
50
  }
58
51
  /**
59
52
  * Create hash (simplified interface)
53
+ * Framework-friendly: Relies on Node.js crypto or framework-provided implementations
60
54
  */
61
55
  export function createHash(algorithm) {
62
56
  if (nodeCrypto && nodeCrypto.createHash) {
63
57
  return nodeCrypto.createHash(algorithm);
64
58
  }
65
59
  else {
66
- // Simple fallback hash for browsers (not cryptographically secure)
67
- let hash = 0;
68
- const hashObj = {
69
- update: (data) => {
70
- const text = typeof data === 'string' ? data : new TextDecoder().decode(data);
71
- for (let i = 0; i < text.length; i++) {
72
- const char = text.charCodeAt(i);
73
- hash = ((hash << 5) - hash) + char;
74
- hash = hash & hash; // Convert to 32-bit integer
75
- }
76
- return hashObj;
77
- },
78
- digest: (encoding) => {
79
- return Math.abs(hash).toString(16);
80
- }
81
- };
82
- return hashObj;
60
+ throw new Error(`createHash not available. For browser environments, frameworks should provide crypto polyfills or use Web Crypto API directly.`);
83
61
  }
84
62
  }
85
63
  /**
86
64
  * Create HMAC
65
+ * Framework-friendly: Relies on Node.js crypto or framework-provided implementations
87
66
  */
88
67
  export function createHmac(algorithm, key) {
89
68
  if (nodeCrypto && nodeCrypto.createHmac) {
90
69
  return nodeCrypto.createHmac(algorithm, key);
91
70
  }
92
71
  else {
93
- // Fallback HMAC implementation (simplified)
94
- return createHash(algorithm);
72
+ throw new Error(`createHmac not available. For browser environments, frameworks should provide crypto polyfills or use Web Crypto API directly.`);
95
73
  }
96
74
  }
97
75
  /**
98
76
  * PBKDF2 synchronous
77
+ * Framework-friendly: Relies on Node.js crypto or framework-provided implementations
99
78
  */
100
79
  export function pbkdf2Sync(password, salt, iterations, keylen, digest) {
101
80
  if (nodeCrypto && nodeCrypto.pbkdf2Sync) {
102
81
  return new Uint8Array(nodeCrypto.pbkdf2Sync(password, salt, iterations, keylen, digest));
103
82
  }
104
83
  else {
105
- // Simplified fallback (not cryptographically secure)
106
- const result = new Uint8Array(keylen);
107
- const passwordStr = typeof password === 'string' ? password : new TextDecoder().decode(password);
108
- const saltStr = typeof salt === 'string' ? salt : new TextDecoder().decode(salt);
109
- let hash = 0;
110
- const combined = passwordStr + saltStr;
111
- for (let i = 0; i < combined.length; i++) {
112
- hash = ((hash << 5) - hash) + combined.charCodeAt(i);
113
- hash = hash & hash;
114
- }
115
- for (let i = 0; i < keylen; i++) {
116
- result[i] = (Math.abs(hash + i) % 256);
117
- }
118
- return result;
84
+ throw new Error(`pbkdf2Sync not available. For browser environments, frameworks should provide crypto polyfills or use Web Crypto API directly.`);
119
85
  }
120
86
  }
121
87
  /**
122
88
  * Scrypt synchronous
89
+ * Framework-friendly: Relies on Node.js crypto or framework-provided implementations
123
90
  */
124
91
  export function scryptSync(password, salt, keylen, options) {
125
92
  if (nodeCrypto && nodeCrypto.scryptSync) {
126
93
  return new Uint8Array(nodeCrypto.scryptSync(password, salt, keylen, options));
127
94
  }
128
95
  else {
129
- // Fallback to pbkdf2Sync
130
- return pbkdf2Sync(password, salt, 10000, keylen, 'sha256');
96
+ throw new Error(`scryptSync not available. For browser environments, frameworks should provide crypto polyfills or use Web Crypto API directly.`);
131
97
  }
132
98
  }
133
99
  /**
134
100
  * Create cipher
101
+ * Framework-friendly: Relies on Node.js crypto or framework-provided implementations
135
102
  */
136
103
  export function createCipheriv(algorithm, key, iv) {
137
104
  if (nodeCrypto && nodeCrypto.createCipheriv) {
138
105
  return nodeCrypto.createCipheriv(algorithm, key, iv);
139
106
  }
140
107
  else {
141
- // Fallback encryption (XOR-based, not secure)
142
- let encrypted = '';
143
- return {
144
- update: (data, inputEncoding, outputEncoding) => {
145
- for (let i = 0; i < data.length; i++) {
146
- const char = data.charCodeAt(i);
147
- const keyByte = key[i % key.length];
148
- const ivByte = iv[i % iv.length];
149
- encrypted += String.fromCharCode(char ^ keyByte ^ ivByte);
150
- }
151
- return outputEncoding === 'hex' ? Buffer.from(encrypted, 'binary').toString('hex') : encrypted;
152
- },
153
- final: (outputEncoding) => {
154
- return outputEncoding === 'hex' ? '' : '';
155
- }
156
- };
108
+ throw new Error(`createCipheriv not available. For browser environments, frameworks should provide crypto polyfills or use Web Crypto API directly.`);
157
109
  }
158
110
  }
159
111
  /**
160
112
  * Create decipher
113
+ * Framework-friendly: Relies on Node.js crypto or framework-provided implementations
161
114
  */
162
115
  export function createDecipheriv(algorithm, key, iv) {
163
116
  if (nodeCrypto && nodeCrypto.createDecipheriv) {
164
117
  return nodeCrypto.createDecipheriv(algorithm, key, iv);
165
118
  }
166
119
  else {
167
- // Fallback decryption (XOR-based, matches createCipheriv)
168
- let decrypted = '';
169
- return {
170
- update: (data, inputEncoding, outputEncoding) => {
171
- const input = inputEncoding === 'hex' ? Buffer.from(data, 'hex').toString('binary') : data;
172
- for (let i = 0; i < input.length; i++) {
173
- const char = input.charCodeAt(i);
174
- const keyByte = key[i % key.length];
175
- const ivByte = iv[i % iv.length];
176
- decrypted += String.fromCharCode(char ^ keyByte ^ ivByte);
177
- }
178
- return decrypted;
179
- },
180
- final: (outputEncoding) => {
181
- return '';
182
- }
183
- };
120
+ throw new Error(`createDecipheriv not available. For browser environments, frameworks should provide crypto polyfills or use Web Crypto API directly.`);
184
121
  }
185
122
  }
186
123
  /**
187
124
  * Timing safe equal
125
+ * Framework-friendly: Relies on Node.js crypto or framework-provided implementations
188
126
  */
189
127
  export function timingSafeEqual(a, b) {
190
128
  if (nodeCrypto && nodeCrypto.timingSafeEqual) {
191
129
  return nodeCrypto.timingSafeEqual(a, b);
192
130
  }
193
131
  else {
194
- // Fallback implementation
195
- if (a.length !== b.length)
196
- return false;
197
- let result = 0;
198
- for (let i = 0; i < a.length; i++) {
199
- result |= a[i] ^ b[i];
200
- }
201
- return result === 0;
132
+ throw new Error(`timingSafeEqual not available. For browser environments, frameworks should provide crypto polyfills or use Web Crypto API directly.`);
202
133
  }
203
134
  }
204
135
  export default {
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Universal Events implementation
3
- * Browser: Uses EventTarget API
4
- * Node.js: Uses built-in events module
3
+ * Framework-friendly: Trusts that frameworks provide events polyfills
4
+ * Works in all environments: Browser (via framework), Node.js, Serverless
5
5
  */
6
6
  /**
7
7
  * Universal EventEmitter interface
@@ -16,6 +16,7 @@ export interface UniversalEventEmitter {
16
16
  }
17
17
  /**
18
18
  * Universal EventEmitter class
19
+ * Framework-friendly: Assumes events API is available via framework polyfills
19
20
  */
20
21
  export declare class EventEmitter implements UniversalEventEmitter {
21
22
  private emitter;