@soulcraft/brainy 0.26.0 → 0.27.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/dist/unified.js CHANGED
@@ -9916,40 +9916,251 @@ async function createStorage(options = {}) {
9916
9916
  return new MemoryStorage();
9917
9917
  }
9918
9918
 
9919
+ /**
9920
+ * Graph Types - Standardized Noun and Verb Type System
9921
+ *
9922
+ * This module defines a comprehensive, standardized set of noun and verb types
9923
+ * that can be used to model any kind of graph, semantic network, or data model.
9924
+ *
9925
+ * ## Purpose and Design Philosophy
9926
+ *
9927
+ * The type system is designed to be:
9928
+ * - **Universal**: Capable of representing any domain or use case
9929
+ * - **Hierarchical**: Organized into logical categories for easy navigation
9930
+ * - **Extensible**: Additional metadata can be attached to any entity or relationship
9931
+ * - **Semantic**: Types carry meaning that can be used for reasoning and inference
9932
+ *
9933
+ * ## Noun Types (Entities)
9934
+ *
9935
+ * Noun types represent entities in the graph and are organized into categories:
9936
+ *
9937
+ * ### Core Entity Types
9938
+ * - **Person**: Human entities and individuals
9939
+ * - **Organization**: Formal organizations, companies, institutions
9940
+ * - **Location**: Geographic locations, places, addresses
9941
+ * - **Thing**: Physical objects and tangible items
9942
+ * - **Concept**: Abstract ideas, concepts, and intangible entities
9943
+ * - **Event**: Occurrences with time and place dimensions
9944
+ *
9945
+ * ### Digital/Content Types
9946
+ * - **Document**: Text-based files and documents
9947
+ * - **Media**: Non-text media files (images, videos, audio)
9948
+ * - **File**: Generic digital files
9949
+ * - **Message**: Communication content
9950
+ * - **Content**: Generic content that doesn't fit other categories
9951
+ *
9952
+ * ### Collection Types
9953
+ * - **Collection**: Generic groupings of items
9954
+ * - **Dataset**: Structured collections of data
9955
+ *
9956
+ * ### Business/Application Types
9957
+ * - **Product**: Commercial products and offerings
9958
+ * - **Service**: Services and offerings
9959
+ * - **User**: User accounts and profiles
9960
+ * - **Task**: Actions, todos, and workflow items
9961
+ * - **Project**: Organized initiatives with goals and timelines
9962
+ *
9963
+ * ### Descriptive Types
9964
+ * - **Process**: Workflows, procedures, and sequences
9965
+ * - **State**: States, conditions, or statuses
9966
+ * - **Role**: Roles, positions, or responsibilities
9967
+ * - **Topic**: Subjects or themes
9968
+ * - **Language**: Languages or linguistic entities
9969
+ * - **Currency**: Currencies and monetary units
9970
+ * - **Measurement**: Measurements, metrics, or quantities
9971
+ *
9972
+ * ## Verb Types (Relationships)
9973
+ *
9974
+ * Verb types represent relationships between entities and are organized into categories:
9975
+ *
9976
+ * ### Core Relationship Types
9977
+ * - **RelatedTo**: Generic relationship (default fallback)
9978
+ * - **Contains**: Containment relationship
9979
+ * - **PartOf**: Part-whole relationship
9980
+ * - **LocatedAt**: Spatial relationship
9981
+ * - **References**: Reference or citation relationship
9982
+ *
9983
+ * ### Temporal/Causal Types
9984
+ * - **Precedes/Succeeds**: Temporal sequence relationships
9985
+ * - **Causes**: Causal relationships
9986
+ * - **DependsOn**: Dependency relationships
9987
+ * - **Requires**: Necessity relationships
9988
+ *
9989
+ * ### Creation/Transformation Types
9990
+ * - **Creates**: Creation relationships
9991
+ * - **Transforms**: Transformation relationships
9992
+ * - **Becomes**: State change relationships
9993
+ * - **Modifies**: Modification relationships
9994
+ * - **Consumes**: Consumption relationships
9995
+ *
9996
+ * ### Ownership/Attribution Types
9997
+ * - **Owns**: Ownership relationships
9998
+ * - **AttributedTo**: Attribution or authorship
9999
+ * - **CreatedBy**: Creation attribution
10000
+ * - **BelongsTo**: Belonging relationships
10001
+ *
10002
+ * ### Social/Organizational Types
10003
+ * - **MemberOf**: Membership or affiliation
10004
+ * - **WorksWith**: Professional relationships
10005
+ * - **FriendOf**: Friendship relationships
10006
+ * - **Follows**: Following relationships
10007
+ * - **Likes**: Liking relationships
10008
+ * - **ReportsTo**: Reporting relationships
10009
+ * - **Supervises**: Supervisory relationships
10010
+ * - **Mentors**: Mentorship relationships
10011
+ * - **Communicates**: Communication relationships
10012
+ *
10013
+ * ### Descriptive/Functional Types
10014
+ * - **Describes**: Descriptive relationships
10015
+ * - **Defines**: Definition relationships
10016
+ * - **Categorizes**: Categorization relationships
10017
+ * - **Measures**: Measurement relationships
10018
+ * - **Evaluates**: Evaluation or assessment relationships
10019
+ * - **Uses**: Utilization relationships
10020
+ * - **Implements**: Implementation relationships
10021
+ * - **Extends**: Extension relationships
10022
+ *
10023
+ * ## Usage with Additional Metadata
10024
+ *
10025
+ * While the type system provides a standardized vocabulary, additional metadata
10026
+ * can be attached to any entity or relationship to capture domain-specific
10027
+ * information:
10028
+ *
10029
+ * ```typescript
10030
+ * const person: GraphNoun = {
10031
+ * id: 'person-123',
10032
+ * noun: NounType.Person,
10033
+ * data: {
10034
+ * name: 'John Doe',
10035
+ * age: 30,
10036
+ * profession: 'Engineer'
10037
+ * }
10038
+ * }
10039
+ *
10040
+ * const worksFor: GraphVerb = {
10041
+ * id: 'verb-456',
10042
+ * source: 'person-123',
10043
+ * target: 'org-789',
10044
+ * verb: VerbType.MemberOf,
10045
+ * data: {
10046
+ * role: 'Senior Engineer',
10047
+ * startDate: '2020-01-01',
10048
+ * department: 'Engineering'
10049
+ * }
10050
+ * }
10051
+ * ```
10052
+ *
10053
+ * ## Modeling Different Graph Types
10054
+ *
10055
+ * This type system can model various graph structures:
10056
+ *
10057
+ * ### Knowledge Graphs
10058
+ * Use Person, Organization, Location, Concept entities with semantic relationships
10059
+ * like AttributedTo, LocatedAt, RelatedTo
10060
+ *
10061
+ * ### Social Networks
10062
+ * Use Person, User entities with social relationships like FriendOf, Follows,
10063
+ * WorksWith, Communicates
10064
+ *
10065
+ * ### Content Networks
10066
+ * Use Document, Media, Content entities with relationships like References,
10067
+ * CreatedBy, Contains, Categorizes
10068
+ *
10069
+ * ### Business Process Models
10070
+ * Use Task, Process, Role entities with relationships like Precedes, Requires,
10071
+ * DependsOn, Transforms
10072
+ *
10073
+ * ### Organizational Charts
10074
+ * Use Person, Role, Organization entities with relationships like ReportsTo,
10075
+ * Supervises, MemberOf
10076
+ *
10077
+ * The flexibility of this system allows it to represent any domain while
10078
+ * maintaining semantic consistency and enabling powerful graph operations
10079
+ * and reasoning capabilities.
10080
+ */
9919
10081
  /**
9920
10082
  * Defines valid noun types for graph entities
9921
10083
  * Used for categorizing different types of nodes
9922
10084
  */
9923
10085
  const NounType = {
9924
- Person: 'person', // Person entities
9925
- Place: 'place', // Physical locations
9926
- Thing: 'thing', // Physical or virtual objects
9927
- Event: 'event', // Events or occurrences
9928
- Concept: 'concept', // Abstract concepts or ideas
9929
- Content: 'content', // Content items
9930
- Group: 'group', // Groups of related entities
9931
- List: 'list', // Ordered collections of entities
9932
- Category: 'category' // Categories for content items including tags
10086
+ // Core Entity Types
10087
+ Person: 'person', // Human entities
10088
+ Organization: 'organization', // Formal organizations (companies, institutions, etc.)
10089
+ Location: 'location', // Geographic locations (merges previous Place and Location)
10090
+ Thing: 'thing', // Physical objects
10091
+ Concept: 'concept', // Abstract ideas, concepts, and intangible entities
10092
+ Event: 'event', // Occurrences with time and place
10093
+ // Digital/Content Types
10094
+ Document: 'document', // Text-based files and documents (reports, articles, etc.)
10095
+ Media: 'media', // Non-text media files (images, videos, audio)
10096
+ File: 'file', // Generic digital files (merges aspects of Digital with file-specific focus)
10097
+ Message: 'message', // Communication content (emails, chat messages, posts)
10098
+ Content: 'content', // Generic content that doesn't fit other categories
10099
+ // Collection Types
10100
+ Collection: 'collection', // Generic grouping of items (merges Group, List, and Category)
10101
+ Dataset: 'dataset', // Structured collections of data
10102
+ // Business/Application Types
10103
+ Product: 'product', // Commercial products and offerings
10104
+ Service: 'service', // Services and offerings
10105
+ User: 'user', // User accounts and profiles
10106
+ Task: 'task', // Actions, todos, and workflow items
10107
+ Project: 'project', // Organized initiatives with goals and timelines
10108
+ // Descriptive Types
10109
+ Process: 'process', // Workflows, procedures, and sequences
10110
+ State: 'state', // States, conditions, or statuses
10111
+ Role: 'role', // Roles, positions, or responsibilities
10112
+ Topic: 'topic', // Subjects or themes
10113
+ Language: 'language', // Languages or linguistic entities
10114
+ Currency: 'currency', // Currencies and monetary units
10115
+ Measurement: 'measurement' // Measurements, metrics, or quantities
9933
10116
  };
9934
10117
  /**
9935
10118
  * Defines valid verb types for relationships
9936
10119
  * Used for categorizing different types of connections
9937
10120
  */
9938
10121
  const VerbType = {
9939
- AttributedTo: 'attributedTo', // Indicates attribution or authorship
9940
- Controls: 'controls', // Indicates control or ownership
9941
- Created: 'created', // Indicates creation or authorship
9942
- Earned: 'earned', // Indicates achievement or acquisition
9943
- Owns: 'owns', // Indicates ownership
9944
- MemberOf: 'memberOf', // Indicates membership or affiliation
9945
- RelatedTo: 'relatedTo', // Indicates family relationship
9946
- WorksWith: 'worksWith', // Indicates professional relationship
9947
- FriendOf: 'friendOf', // Indicates friendship
9948
- ReportsTo: 'reportsTo', // Indicates reporting relationship
9949
- Supervises: 'supervises', // Indicates supervisory relationship
9950
- Mentors: 'mentors', // Indicates mentorship relationship
9951
- Follows: 'follows', // Indicates the following relationship
9952
- Likes: 'likes' // Indicates liking relationship
10122
+ // Core Relationship Types
10123
+ RelatedTo: 'relatedTo', // Generic relationship (default fallback)
10124
+ Contains: 'contains', // Containment relationship (parent contains child)
10125
+ PartOf: 'partOf', // Part-whole relationship (child is part of parent)
10126
+ LocatedAt: 'locatedAt', // Spatial relationship
10127
+ References: 'references', // Reference or citation relationship
10128
+ // Temporal/Causal Types
10129
+ Precedes: 'precedes', // Temporal sequence (comes before)
10130
+ Succeeds: 'succeeds', // Temporal sequence (comes after)
10131
+ Causes: 'causes', // Causal relationship (merges Influences and Causes)
10132
+ DependsOn: 'dependsOn', // Dependency relationship
10133
+ Requires: 'requires', // Necessity relationship (new)
10134
+ // Creation/Transformation Types
10135
+ Creates: 'creates', // Creation relationship (merges Created and Produces)
10136
+ Transforms: 'transforms', // Transformation relationship
10137
+ Becomes: 'becomes', // State change relationship
10138
+ Modifies: 'modifies', // Modification relationship
10139
+ Consumes: 'consumes', // Consumption relationship
10140
+ // Ownership/Attribution Types
10141
+ Owns: 'owns', // Ownership relationship (merges Controls and Owns)
10142
+ AttributedTo: 'attributedTo', // Attribution or authorship
10143
+ CreatedBy: 'createdBy', // Creation attribution (new, distinct from Creates)
10144
+ BelongsTo: 'belongsTo', // Belonging relationship (new)
10145
+ // Social/Organizational Types
10146
+ MemberOf: 'memberOf', // Membership or affiliation
10147
+ WorksWith: 'worksWith', // Professional relationship
10148
+ FriendOf: 'friendOf', // Friendship relationship
10149
+ Follows: 'follows', // Following relationship
10150
+ Likes: 'likes', // Liking relationship
10151
+ ReportsTo: 'reportsTo', // Reporting relationship
10152
+ Supervises: 'supervises', // Supervisory relationship
10153
+ Mentors: 'mentors', // Mentorship relationship
10154
+ Communicates: 'communicates', // Communication relationship (merges Communicates and Collaborates)
10155
+ // Descriptive/Functional Types
10156
+ Describes: 'describes', // Descriptive relationship
10157
+ Defines: 'defines', // Definition relationship
10158
+ Categorizes: 'categorizes', // Categorization relationship
10159
+ Measures: 'measures', // Measurement relationship
10160
+ Evaluates: 'evaluates', // Evaluation or assessment relationship
10161
+ Uses: 'uses', // Utilization relationship (new)
10162
+ Implements: 'implements', // Implementation relationship
10163
+ Extends: 'extends' // Extension relationship (merges Extends and Inherits)
9953
10164
  };
9954
10165
 
9955
10166
  /** Common types for the augmentation system */
@@ -12202,6 +12413,12 @@ class BrainyData {
12202
12413
  config.storage?.requestPersistentStorage || false;
12203
12414
  // Set read-only flag
12204
12415
  this.readOnly = config.readOnly || false;
12416
+ // Set write-only flag
12417
+ this.writeOnly = config.writeOnly || false;
12418
+ // Validate that readOnly and writeOnly are not both true
12419
+ if (this.readOnly && this.writeOnly) {
12420
+ throw new Error('Database cannot be both read-only and write-only');
12421
+ }
12205
12422
  // Store storage configuration for later use in init()
12206
12423
  this.storageConfig = config.storage || {};
12207
12424
  // Store timeout and retry configuration
@@ -12228,6 +12445,15 @@ class BrainyData {
12228
12445
  throw new Error('Cannot perform write operation: database is in read-only mode');
12229
12446
  }
12230
12447
  }
12448
+ /**
12449
+ * Check if the database is in write-only mode and throw an error if it is
12450
+ * @throws Error if the database is in write-only mode
12451
+ */
12452
+ checkWriteOnly() {
12453
+ if (this.writeOnly) {
12454
+ throw new Error('Cannot perform search operation: database is in write-only mode');
12455
+ }
12456
+ }
12231
12457
  /**
12232
12458
  * Start real-time updates if enabled in the configuration
12233
12459
  * This will periodically check for new data in storage and update the in-memory index and statistics
@@ -12242,14 +12468,16 @@ class BrainyData {
12242
12468
  return;
12243
12469
  }
12244
12470
  // Set the initial last known noun count
12245
- this.getNounCount().then(count => {
12471
+ this.getNounCount()
12472
+ .then((count) => {
12246
12473
  this.lastKnownNounCount = count;
12247
- }).catch(error => {
12474
+ })
12475
+ .catch((error) => {
12248
12476
  console.warn('Failed to get initial noun count for real-time updates:', error);
12249
12477
  });
12250
12478
  // Start the update timer
12251
12479
  this.updateTimerId = setInterval(() => {
12252
- this.checkForUpdates().catch(error => {
12480
+ this.checkForUpdates().catch((error) => {
12253
12481
  console.warn('Error during real-time update check:', error);
12254
12482
  });
12255
12483
  }, this.realtimeUpdateConfig.interval);
@@ -12415,7 +12643,8 @@ class BrainyData {
12415
12643
  // Continue with other changes
12416
12644
  }
12417
12645
  }
12418
- if (this.loggingConfig?.verbose && (addedCount > 0 || updatedCount > 0 || deletedCount > 0)) {
12646
+ if (this.loggingConfig?.verbose &&
12647
+ (addedCount > 0 || updatedCount > 0 || deletedCount > 0)) {
12419
12648
  console.log(`Real-time update: Added ${addedCount}, updated ${updatedCount}, deleted ${deletedCount} nouns using change log`);
12420
12649
  }
12421
12650
  // Update the last known noun count
@@ -12442,7 +12671,7 @@ class BrainyData {
12442
12671
  const indexNouns = this.index.getNouns();
12443
12672
  const indexNounIds = new Set(indexNouns.keys());
12444
12673
  // Find nouns that are in storage but not in the index
12445
- const newNouns = nouns.filter(noun => !indexNounIds.has(noun.id));
12674
+ const newNouns = nouns.filter((noun) => !indexNounIds.has(noun.id));
12446
12675
  // Add new nouns to the index
12447
12676
  for (const noun of newNouns) {
12448
12677
  // Check if the vector dimensions match the expected dimensions
@@ -12574,23 +12803,31 @@ class BrainyData {
12574
12803
  if (this.useOptimizedIndex && this.index instanceof HNSWIndexOptimized) {
12575
12804
  this.index.setStorage(this.storage);
12576
12805
  }
12577
- // Load all nouns from storage
12578
- const nouns = await this.storage.getAllNouns();
12579
- // Clear the index and add all nouns
12580
- this.index.clear();
12581
- for (const noun of nouns) {
12582
- // Check if the vector dimensions match the expected dimensions
12583
- if (noun.vector.length !== this._dimensions) {
12584
- console.warn(`Deleting noun ${noun.id} due to dimension mismatch: expected ${this._dimensions}, got ${noun.vector.length}`);
12585
- // Delete the mismatched noun from storage to prevent future issues
12586
- await this.storage.deleteNoun(noun.id);
12587
- continue;
12806
+ // In write-only mode, skip loading the index into memory
12807
+ if (this.writeOnly) {
12808
+ if (this.loggingConfig?.verbose) {
12809
+ console.log('Database is in write-only mode, skipping index loading');
12810
+ }
12811
+ }
12812
+ else {
12813
+ // Load all nouns from storage
12814
+ const nouns = await this.storage.getAllNouns();
12815
+ // Clear the index and add all nouns
12816
+ this.index.clear();
12817
+ for (const noun of nouns) {
12818
+ // Check if the vector dimensions match the expected dimensions
12819
+ if (noun.vector.length !== this._dimensions) {
12820
+ console.warn(`Deleting noun ${noun.id} due to dimension mismatch: expected ${this._dimensions}, got ${noun.vector.length}`);
12821
+ // Delete the mismatched noun from storage to prevent future issues
12822
+ await this.storage.deleteNoun(noun.id);
12823
+ continue;
12824
+ }
12825
+ // Add to index
12826
+ await this.index.addItem({
12827
+ id: noun.id,
12828
+ vector: noun.vector
12829
+ });
12588
12830
  }
12589
- // Add to index
12590
- await this.index.addItem({
12591
- id: noun.id,
12592
- vector: noun.vector
12593
- });
12594
12831
  }
12595
12832
  // Connect to remote server if configured with autoConnect
12596
12833
  if (this.remoteServerConfig && this.remoteServerConfig.autoConnect) {
@@ -12664,8 +12901,7 @@ class BrainyData {
12664
12901
  }
12665
12902
  }
12666
12903
  // Check if input is already a vector
12667
- if (Array.isArray(vectorOrData) &&
12668
- !options.forceEmbed) {
12904
+ if (Array.isArray(vectorOrData) && !options.forceEmbed) {
12669
12905
  // Input is already a vector (and we've validated it contains only numbers)
12670
12906
  vector = vectorOrData;
12671
12907
  }
@@ -12706,7 +12942,9 @@ class BrainyData {
12706
12942
  // Save metadata if provided and not empty
12707
12943
  if (metadata !== undefined) {
12708
12944
  // Skip saving if metadata is an empty object
12709
- if (metadata && typeof metadata === 'object' && Object.keys(metadata).length === 0) {
12945
+ if (metadata &&
12946
+ typeof metadata === 'object' &&
12947
+ Object.keys(metadata).length === 0) {
12710
12948
  // Don't save empty metadata
12711
12949
  // Explicitly save null to ensure no metadata is stored
12712
12950
  await this.storage.saveMetadata(id, null);
@@ -12938,7 +13176,7 @@ class BrainyData {
12938
13176
  filterResultsByService(results, service) {
12939
13177
  if (!service)
12940
13178
  return results;
12941
- return results.filter(result => {
13179
+ return results.filter((result) => {
12942
13180
  if (!result.metadata || typeof result.metadata !== 'object')
12943
13181
  return false;
12944
13182
  if (!('createdBy' in result.metadata))
@@ -12961,6 +13199,8 @@ class BrainyData {
12961
13199
  if (!this.isInitialized) {
12962
13200
  throw new Error('BrainyData must be initialized before searching. Call init() first.');
12963
13201
  }
13202
+ // Check if database is in write-only mode
13203
+ this.checkWriteOnly();
12964
13204
  try {
12965
13205
  let queryVector;
12966
13206
  // Check if input is already a vector
@@ -13087,6 +13327,8 @@ class BrainyData {
13087
13327
  if (!this.isInitialized) {
13088
13328
  throw new Error('BrainyData must be initialized before searching. Call init() first.');
13089
13329
  }
13330
+ // Check if database is in write-only mode
13331
+ this.checkWriteOnly();
13090
13332
  // If searching for verbs directly
13091
13333
  if (options.searchVerbs) {
13092
13334
  const verbResults = await this.searchVerbs(queryVectorOrData, k, {
@@ -13138,6 +13380,8 @@ class BrainyData {
13138
13380
  if (!this.isInitialized) {
13139
13381
  throw new Error('BrainyData must be initialized before searching. Call init() first.');
13140
13382
  }
13383
+ // Check if database is in write-only mode
13384
+ this.checkWriteOnly();
13141
13385
  // If input is a string and not a vector, automatically vectorize it
13142
13386
  let queryToUse = queryVectorOrData;
13143
13387
  if (typeof queryVectorOrData === 'string' && !options.forceEmbed) {
@@ -13202,9 +13446,9 @@ class BrainyData {
13202
13446
  // Get all verbs (relationships) from the source entity
13203
13447
  const outgoingVerbs = await this.storage.getVerbsBySource(id);
13204
13448
  // Filter to only include verbs of the specified type
13205
- const verbsOfType = outgoingVerbs.filter(verb => verb.type === options.relationType);
13449
+ const verbsOfType = outgoingVerbs.filter((verb) => verb.type === options.relationType);
13206
13450
  // Get the target IDs
13207
- const targetIds = verbsOfType.map(verb => verb.target);
13451
+ const targetIds = verbsOfType.map((verb) => verb.target);
13208
13452
  // Get the actual entities for these IDs
13209
13453
  const results = [];
13210
13454
  for (const targetId of targetIds) {
@@ -13382,7 +13626,7 @@ class BrainyData {
13382
13626
  const service = options.service || this.getCurrentAugmentation();
13383
13627
  const graphNoun = metadata;
13384
13628
  // Preserve existing createdBy and createdAt if they exist
13385
- const existingMetadata = await this.storage.getMetadata(id);
13629
+ const existingMetadata = (await this.storage.getMetadata(id));
13386
13630
  if (existingMetadata &&
13387
13631
  typeof existingMetadata === 'object' &&
13388
13632
  'createdBy' in existingMetadata) {
@@ -13791,7 +14035,7 @@ class BrainyData {
13791
14035
  // Get all verbs from storage
13792
14036
  const allVerbs = await this.storage.getAllVerbs();
13793
14037
  // Create a set of verb IDs for faster lookup
13794
- const verbIds = new Set(allVerbs.map(verb => verb.id));
14038
+ const verbIds = new Set(allVerbs.map((verb) => verb.id));
13795
14039
  // Get all nouns from the index
13796
14040
  const nouns = this.index.getNouns();
13797
14041
  // Count nouns that are not verbs
@@ -13853,8 +14097,14 @@ class BrainyData {
13853
14097
  };
13854
14098
  // Filter by service if specified
13855
14099
  const services = options.service
13856
- ? (Array.isArray(options.service) ? options.service : [options.service])
13857
- : Object.keys({ ...stats.nounCount, ...stats.verbCount, ...stats.metadataCount });
14100
+ ? Array.isArray(options.service)
14101
+ ? options.service
14102
+ : [options.service]
14103
+ : Object.keys({
14104
+ ...stats.nounCount,
14105
+ ...stats.verbCount,
14106
+ ...stats.metadataCount
14107
+ });
13858
14108
  // Calculate totals and service breakdown
13859
14109
  for (const service of services) {
13860
14110
  const nounCount = stats.nounCount[service] || 0;
@@ -13959,6 +14209,28 @@ class BrainyData {
13959
14209
  */
13960
14210
  setReadOnly(readOnly) {
13961
14211
  this.readOnly = readOnly;
14212
+ // Ensure readOnly and writeOnly are not both true
14213
+ if (readOnly && this.writeOnly) {
14214
+ this.writeOnly = false;
14215
+ }
14216
+ }
14217
+ /**
14218
+ * Check if the database is in write-only mode
14219
+ * @returns True if the database is in write-only mode, false otherwise
14220
+ */
14221
+ isWriteOnly() {
14222
+ return this.writeOnly;
14223
+ }
14224
+ /**
14225
+ * Set the database to write-only mode
14226
+ * @param writeOnly True to set the database to write-only mode, false to allow searches
14227
+ */
14228
+ setWriteOnly(writeOnly) {
14229
+ this.writeOnly = writeOnly;
14230
+ // Ensure readOnly and writeOnly are not both true
14231
+ if (writeOnly && this.readOnly) {
14232
+ this.readOnly = false;
14233
+ }
13962
14234
  }
13963
14235
  /**
13964
14236
  * Embed text or data into a vector using the same embedding function used by this instance
@@ -13986,6 +14258,8 @@ class BrainyData {
13986
14258
  */
13987
14259
  async searchVerbs(queryVectorOrData, k = 10, options = {}) {
13988
14260
  await this.ensureInitialized();
14261
+ // Check if database is in write-only mode
14262
+ this.checkWriteOnly();
13989
14263
  try {
13990
14264
  let queryVector;
13991
14265
  // Check if input is already a vector
@@ -14052,9 +14326,11 @@ class BrainyData {
14052
14326
  verbs = allVerbs;
14053
14327
  }
14054
14328
  // Calculate similarity for each verb not already in results
14055
- const existingIds = new Set(verbResults.map(v => v.id));
14329
+ const existingIds = new Set(verbResults.map((v) => v.id));
14056
14330
  for (const verb of verbs) {
14057
- if (!existingIds.has(verb.id) && verb.vector && verb.vector.length > 0) {
14331
+ if (!existingIds.has(verb.id) &&
14332
+ verb.vector &&
14333
+ verb.vector.length > 0) {
14058
14334
  const distance = this.index.getDistanceFunction()(queryVector, verb.vector);
14059
14335
  verbResults.push({
14060
14336
  ...verb,
@@ -14082,6 +14358,8 @@ class BrainyData {
14082
14358
  */
14083
14359
  async searchNounsByVerbs(queryVectorOrData, k = 10, options = {}) {
14084
14360
  await this.ensureInitialized();
14361
+ // Check if database is in write-only mode
14362
+ this.checkWriteOnly();
14085
14363
  try {
14086
14364
  // First, search for nouns
14087
14365
  const nounResults = await this.searchByNounTypes(queryVectorOrData, k * 2, // Get more results initially to account for filtering
@@ -14171,6 +14449,8 @@ class BrainyData {
14171
14449
  */
14172
14450
  async searchText(query, k = 10, options = {}) {
14173
14451
  await this.ensureInitialized();
14452
+ // Check if database is in write-only mode
14453
+ this.checkWriteOnly();
14174
14454
  try {
14175
14455
  // Embed the query text
14176
14456
  const queryVector = await this.embed(query);
@@ -14195,6 +14475,8 @@ class BrainyData {
14195
14475
  */
14196
14476
  async searchRemote(queryVectorOrData, k = 10, options = {}) {
14197
14477
  await this.ensureInitialized();
14478
+ // Check if database is in write-only mode
14479
+ this.checkWriteOnly();
14198
14480
  // Check if connected to a remote server
14199
14481
  if (!this.isConnectedToRemoteServer()) {
14200
14482
  throw new Error('Not connected to a remote server. Call connectToRemoteServer() first.');
@@ -14234,6 +14516,8 @@ class BrainyData {
14234
14516
  */
14235
14517
  async searchCombined(queryVectorOrData, k = 10, options = {}) {
14236
14518
  await this.ensureInitialized();
14519
+ // Check if database is in write-only mode
14520
+ this.checkWriteOnly();
14237
14521
  // Check if connected to a remote server
14238
14522
  if (!this.isConnectedToRemoteServer()) {
14239
14523
  // If not connected to a remote server, just search locally
@@ -14669,14 +14953,14 @@ class BrainyData {
14669
14953
  const nounIds = [];
14670
14954
  const nounDescriptions = {
14671
14955
  [NounType.Person]: 'A person with unique characteristics',
14672
- [NounType.Place]: 'A location with specific attributes',
14956
+ [NounType.Location]: 'A location with specific attributes',
14673
14957
  [NounType.Thing]: 'An object with distinct properties',
14674
14958
  [NounType.Event]: 'An occurrence with temporal aspects',
14675
14959
  [NounType.Concept]: 'An abstract idea or notion',
14676
14960
  [NounType.Content]: 'A piece of content or information',
14677
- [NounType.Group]: 'A collection of related entities',
14678
- [NounType.List]: 'An ordered sequence of items',
14679
- [NounType.Category]: 'A classification or grouping'
14961
+ [NounType.Collection]: 'A collection of related entities',
14962
+ [NounType.Organization]: 'An organization or institution',
14963
+ [NounType.Document]: 'A document or text-based file'
14680
14964
  };
14681
14965
  for (let i = 0; i < nounCount; i++) {
14682
14966
  // Select a random noun type
@@ -14702,10 +14986,10 @@ class BrainyData {
14702
14986
  const verbIds = [];
14703
14987
  const verbDescriptions = {
14704
14988
  [VerbType.AttributedTo]: 'Attribution relationship',
14705
- [VerbType.Controls]: 'Control relationship',
14706
- [VerbType.Created]: 'Creation relationship',
14707
- [VerbType.Earned]: 'Achievement relationship',
14708
14989
  [VerbType.Owns]: 'Ownership relationship',
14990
+ [VerbType.Creates]: 'Creation relationship',
14991
+ [VerbType.Uses]: 'Utilization relationship',
14992
+ [VerbType.BelongsTo]: 'Belonging relationship',
14709
14993
  [VerbType.MemberOf]: 'Membership relationship',
14710
14994
  [VerbType.RelatedTo]: 'General relationship',
14711
14995
  [VerbType.WorksWith]: 'Collaboration relationship',