@soulcraft/brainy 4.4.0 → 4.5.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.
@@ -61,7 +61,43 @@ export class SmartExcelImporter {
61
61
  ...options
62
62
  };
63
63
  // Parse Excel using existing handler
64
- const processedData = await this.excelHandler.process(buffer, options);
64
+ // v4.5.0: Pass progress hooks to handler for file parsing progress
65
+ const processedData = await this.excelHandler.process(buffer, {
66
+ ...options,
67
+ totalBytes: buffer.length,
68
+ progressHooks: {
69
+ onBytesProcessed: (bytes) => {
70
+ // Handler reports bytes processed during parsing
71
+ opts.onProgress?.({
72
+ processed: 0,
73
+ total: 0,
74
+ entities: 0,
75
+ relationships: 0,
76
+ phase: `Parsing Excel (${Math.round((bytes / buffer.length) * 100)}%)`
77
+ });
78
+ },
79
+ onCurrentItem: (message) => {
80
+ // Handler reports current processing step (e.g., "Reading sheet: Sales (1/3)")
81
+ opts.onProgress?.({
82
+ processed: 0,
83
+ total: 0,
84
+ entities: 0,
85
+ relationships: 0,
86
+ phase: message
87
+ });
88
+ },
89
+ onDataExtracted: (count, total) => {
90
+ // Handler reports rows extracted
91
+ opts.onProgress?.({
92
+ processed: 0,
93
+ total: total || count,
94
+ entities: 0,
95
+ relationships: 0,
96
+ phase: `Extracted ${count} rows from Excel`
97
+ });
98
+ }
99
+ }
100
+ });
65
101
  const rows = processedData.data;
66
102
  if (rows.length === 0) {
67
103
  return this.emptyResult(startTime);
@@ -48,6 +48,12 @@ export class SmartJSONImporter {
48
48
  onProgress: () => { },
49
49
  ...options
50
50
  };
51
+ // v4.5.0: Report parsing start
52
+ opts.onProgress({
53
+ processed: 0,
54
+ entities: 0,
55
+ relationships: 0
56
+ });
51
57
  // Parse JSON if string
52
58
  let jsonData;
53
59
  if (typeof data === 'string') {
@@ -61,6 +67,12 @@ export class SmartJSONImporter {
61
67
  else {
62
68
  jsonData = data;
63
69
  }
70
+ // v4.5.0: Report parsing complete, starting traversal
71
+ opts.onProgress({
72
+ processed: 0,
73
+ entities: 0,
74
+ relationships: 0
75
+ });
64
76
  // Traverse and extract
65
77
  const entities = [];
66
78
  const relationships = [];
@@ -82,6 +94,12 @@ export class SmartJSONImporter {
82
94
  });
83
95
  }
84
96
  });
97
+ // v4.5.0: Report completion
98
+ opts.onProgress({
99
+ processed: nodesProcessed,
100
+ entities: entities.length,
101
+ relationships: relationships.length
102
+ });
85
103
  return {
86
104
  nodesProcessed,
87
105
  entitiesExtracted: entities.length,
@@ -46,8 +46,22 @@ export class SmartMarkdownImporter {
46
46
  onProgress: () => { },
47
47
  ...options
48
48
  };
49
+ // v4.5.0: Report parsing start
50
+ opts.onProgress({
51
+ processed: 0,
52
+ total: 0,
53
+ entities: 0,
54
+ relationships: 0
55
+ });
49
56
  // Parse markdown into sections
50
57
  const parsedSections = this.parseMarkdown(markdown, opts);
58
+ // v4.5.0: Report parsing complete
59
+ opts.onProgress({
60
+ processed: 0,
61
+ total: parsedSections.length,
62
+ entities: 0,
63
+ relationships: 0
64
+ });
51
65
  // Process each section
52
66
  const sections = [];
53
67
  const entityMap = new Map();
@@ -69,10 +83,19 @@ export class SmartMarkdownImporter {
69
83
  relationships: sections.reduce((sum, s) => sum + s.relationships.length, 0)
70
84
  });
71
85
  }
86
+ // v4.5.0: Report completion
87
+ const totalEntities = sections.reduce((sum, s) => sum + s.entities.length, 0);
88
+ const totalRelationships = sections.reduce((sum, s) => sum + s.relationships.length, 0);
89
+ opts.onProgress({
90
+ processed: sections.length,
91
+ total: sections.length,
92
+ entities: totalEntities,
93
+ relationships: totalRelationships
94
+ });
72
95
  return {
73
96
  sectionsProcessed: sections.length,
74
- entitiesExtracted: sections.reduce((sum, s) => sum + s.entities.length, 0),
75
- relationshipsInferred: sections.reduce((sum, s) => sum + s.relationships.length, 0),
97
+ entitiesExtracted: totalEntities,
98
+ relationshipsInferred: totalRelationships,
76
99
  sections,
77
100
  entityMap,
78
101
  processingTime: Date.now() - startTime,
@@ -49,7 +49,43 @@ export class SmartPDFImporter {
49
49
  ...options
50
50
  };
51
51
  // Parse PDF using existing handler
52
- const processedData = await this.pdfHandler.process(buffer, options);
52
+ // v4.5.0: Pass progress hooks to handler for file parsing progress
53
+ const processedData = await this.pdfHandler.process(buffer, {
54
+ ...options,
55
+ totalBytes: buffer.length,
56
+ progressHooks: {
57
+ onBytesProcessed: (bytes) => {
58
+ // Handler reports bytes processed during parsing
59
+ opts.onProgress?.({
60
+ processed: 0,
61
+ total: 0,
62
+ entities: 0,
63
+ relationships: 0,
64
+ phase: `Parsing PDF (${Math.round((bytes / buffer.length) * 100)}%)`
65
+ });
66
+ },
67
+ onCurrentItem: (message) => {
68
+ // Handler reports current processing step (e.g., "Processing page 5 of 23")
69
+ opts.onProgress?.({
70
+ processed: 0,
71
+ total: 0,
72
+ entities: 0,
73
+ relationships: 0,
74
+ phase: message
75
+ });
76
+ },
77
+ onDataExtracted: (count, total) => {
78
+ // Handler reports items extracted (paragraphs + tables)
79
+ opts.onProgress?.({
80
+ processed: 0,
81
+ total: total || count,
82
+ entities: 0,
83
+ relationships: 0,
84
+ phase: `Extracted ${count} items from PDF`
85
+ });
86
+ }
87
+ }
88
+ });
53
89
  const data = processedData.data;
54
90
  const pdfMetadata = processedData.metadata.additionalInfo?.pdfMetadata || {};
55
91
  if (data.length === 0) {
@@ -37,6 +37,12 @@ export class SmartYAMLImporter {
37
37
  */
38
38
  async extract(yamlContent, options = {}) {
39
39
  const startTime = Date.now();
40
+ // v4.5.0: Report parsing start
41
+ options.onProgress?.({
42
+ processed: 0,
43
+ entities: 0,
44
+ relationships: 0
45
+ });
40
46
  // Parse YAML to JavaScript object
41
47
  const yamlString = typeof yamlContent === 'string'
42
48
  ? yamlContent
@@ -48,6 +54,12 @@ export class SmartYAMLImporter {
48
54
  catch (error) {
49
55
  throw new Error(`Failed to parse YAML: ${error.message}`);
50
56
  }
57
+ // v4.5.0: Report parsing complete
58
+ options.onProgress?.({
59
+ processed: 0,
60
+ entities: 0,
61
+ relationships: 0
62
+ });
51
63
  // Process as JSON-like structure
52
64
  const result = await this.extractFromData(data, options);
53
65
  result.processingTime = Date.now() - startTime;
@@ -266,6 +266,16 @@ export interface GetRelationsParams {
266
266
  * Only return relationships belonging to this service.
267
267
  */
268
268
  service?: string;
269
+ /**
270
+ * Include VFS relationships (v4.5.1)
271
+ *
272
+ * By default, getRelations() excludes VFS relationships (since v4.4.0).
273
+ * Set this to true when you need to traverse VFS structure.
274
+ *
275
+ * @default false
276
+ * @since v4.5.1
277
+ */
278
+ includeVFS?: boolean;
269
279
  }
270
280
  /**
271
281
  * Batch add parameters
@@ -319,6 +329,102 @@ export interface BatchResult<T = any> {
319
329
  total: number;
320
330
  duration: number;
321
331
  }
332
+ /**
333
+ * Import stage enumeration
334
+ */
335
+ export type ImportStage = 'detecting' | 'reading' | 'parsing' | 'extracting' | 'indexing' | 'completing';
336
+ /**
337
+ * Overall import status
338
+ */
339
+ export type ImportStatus = 'starting' | 'processing' | 'completing' | 'done';
340
+ /**
341
+ * Comprehensive import progress information
342
+ *
343
+ * Provides multi-dimensional progress tracking:
344
+ * - Bytes processed (always deterministic)
345
+ * - Entities extracted and indexed
346
+ * - Stage-specific progress
347
+ * - Time estimates
348
+ * - Performance metrics
349
+ *
350
+ * @since v4.5.0
351
+ */
352
+ export interface ImportProgress {
353
+ overall_progress: number;
354
+ overall_status: ImportStatus;
355
+ stage: ImportStage;
356
+ stage_progress: number;
357
+ stage_message: string;
358
+ bytes_processed: number;
359
+ total_bytes: number;
360
+ bytes_percentage: number;
361
+ bytes_per_second?: number;
362
+ entities_extracted: number;
363
+ entities_indexed: number;
364
+ entities_per_second?: number;
365
+ estimated_total_entities?: number;
366
+ estimation_confidence?: number;
367
+ elapsed_ms: number;
368
+ estimated_remaining_ms?: number;
369
+ estimated_total_ms?: number;
370
+ current_item?: string;
371
+ current_file?: string;
372
+ file_number?: number;
373
+ total_files?: number;
374
+ metrics?: {
375
+ parsing_rate_mbps?: number;
376
+ extraction_rate_entities_per_sec?: number;
377
+ indexing_rate_entities_per_sec?: number;
378
+ memory_usage_mb?: number;
379
+ peak_memory_mb?: number;
380
+ };
381
+ current: number;
382
+ total: number;
383
+ }
384
+ /**
385
+ * Import progress callback - backwards compatible
386
+ *
387
+ * Supports both legacy (current, total) and new (ImportProgress object) signatures
388
+ */
389
+ export type ImportProgressCallback = ((progress: ImportProgress) => void) | ((current: number, total: number) => void);
390
+ /**
391
+ * Stage weight configuration for overall progress calculation
392
+ *
393
+ * These weights reflect the typical time distribution across stages.
394
+ * Extraction is typically the slowest stage (60% of time).
395
+ */
396
+ export interface StageWeights {
397
+ detecting: number;
398
+ reading: number;
399
+ parsing: number;
400
+ extracting: number;
401
+ indexing: number;
402
+ completing: number;
403
+ }
404
+ /**
405
+ * Import result statistics
406
+ */
407
+ export interface ImportStats {
408
+ graphNodesCreated: number;
409
+ graphEdgesCreated: number;
410
+ vfsFilesCreated: number;
411
+ duration: number;
412
+ bytesProcessed: number;
413
+ averageRate: number;
414
+ peakMemoryMB?: number;
415
+ }
416
+ /**
417
+ * Import operation result
418
+ */
419
+ export interface ImportResult {
420
+ success: boolean;
421
+ stats: ImportStats;
422
+ errors?: Array<{
423
+ stage: ImportStage;
424
+ message: string;
425
+ error?: any;
426
+ }>;
427
+ }
322
428
  /**
323
429
  * Graph traversal parameters
324
430
  */
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Import Progress Tracker (v4.5.0)
3
+ *
4
+ * Comprehensive progress tracking for imports with:
5
+ * - Multi-dimensional progress (bytes, entities, stages, timing)
6
+ * - Smart estimation (entity count, time remaining)
7
+ * - Stage-specific metrics (bytes/sec vs entities/sec)
8
+ * - Throttled callbacks (avoid spam)
9
+ * - Weighted overall progress
10
+ *
11
+ * @since v4.5.0
12
+ */
13
+ import { ImportProgress, ImportStage, StageWeights, ImportProgressCallback } from '../types/brainy.types.js';
14
+ /**
15
+ * Progress tracker for imports
16
+ */
17
+ export declare class ImportProgressTracker {
18
+ private readonly stageWeights;
19
+ private readonly throttleMs;
20
+ private readonly callback?;
21
+ private startTime;
22
+ private lastEmitTime;
23
+ private currentStage;
24
+ private completedStages;
25
+ private totalBytes;
26
+ private bytesProcessed;
27
+ private entitiesExtracted;
28
+ private entitiesIndexed;
29
+ private parseStartTime?;
30
+ private extractStartTime?;
31
+ private indexStartTime?;
32
+ private lastBytesCheckpoint;
33
+ private lastBytesCheckpointTime;
34
+ private lastEntitiesCheckpoint;
35
+ private lastEntitiesCheckpointTime;
36
+ private currentItem?;
37
+ private currentFile?;
38
+ private fileNumber?;
39
+ private totalFiles?;
40
+ private peakMemoryMB;
41
+ constructor(options?: {
42
+ totalBytes?: number;
43
+ stageWeights?: Partial<StageWeights>;
44
+ throttleMs?: number;
45
+ callback?: ImportProgressCallback;
46
+ });
47
+ /**
48
+ * Set total file size (if known later)
49
+ */
50
+ setTotalBytes(bytes: number): void;
51
+ /**
52
+ * Update current stage
53
+ */
54
+ setStage(stage: ImportStage, message?: string): void;
55
+ /**
56
+ * Update bytes processed
57
+ */
58
+ updateBytes(bytes: number): void;
59
+ /**
60
+ * Increment bytes processed
61
+ */
62
+ addBytes(bytes: number): void;
63
+ /**
64
+ * Update entities extracted
65
+ */
66
+ updateEntitiesExtracted(count: number): void;
67
+ /**
68
+ * Increment entities extracted
69
+ */
70
+ addEntitiesExtracted(count: number): void;
71
+ /**
72
+ * Update entities indexed
73
+ */
74
+ updateEntitiesIndexed(count: number): void;
75
+ /**
76
+ * Increment entities indexed
77
+ */
78
+ addEntitiesIndexed(count: number): void;
79
+ /**
80
+ * Set context information
81
+ */
82
+ setContext(context: {
83
+ currentItem?: string;
84
+ currentFile?: string;
85
+ fileNumber?: number;
86
+ totalFiles?: number;
87
+ }): void;
88
+ /**
89
+ * Set stage message
90
+ */
91
+ private setStageMessage;
92
+ /**
93
+ * Calculate stage progress (0-100 within current stage)
94
+ */
95
+ private calculateStageProgress;
96
+ /**
97
+ * Calculate overall progress (0-100 weighted across all stages)
98
+ */
99
+ private calculateOverallProgress;
100
+ /**
101
+ * Calculate bytes per second
102
+ */
103
+ private calculateBytesPerSecond;
104
+ /**
105
+ * Calculate entities per second
106
+ */
107
+ private calculateEntitiesPerSecond;
108
+ /**
109
+ * Estimate total entities
110
+ */
111
+ private estimateTotalEntities;
112
+ /**
113
+ * Estimate remaining time
114
+ */
115
+ private estimateRemainingTime;
116
+ /**
117
+ * Get current memory usage
118
+ */
119
+ private getCurrentMemoryMB;
120
+ /**
121
+ * Build complete progress object
122
+ */
123
+ private buildProgress;
124
+ /**
125
+ * Emit progress (throttled)
126
+ */
127
+ private emit;
128
+ /**
129
+ * Force emit (for completion or critical updates)
130
+ */
131
+ forceEmit(): void;
132
+ /**
133
+ * Get current progress (without emitting)
134
+ */
135
+ getProgress(): ImportProgress;
136
+ /**
137
+ * Mark import as complete
138
+ */
139
+ complete(): ImportProgress;
140
+ }