@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.
- package/dist/augmentations/intelligentImport/handlers/csvHandler.js +33 -1
- package/dist/augmentations/intelligentImport/handlers/excelHandler.js +48 -2
- package/dist/augmentations/intelligentImport/handlers/pdfHandler.js +37 -0
- package/dist/augmentations/intelligentImport/types.d.ts +33 -0
- package/dist/brainy.d.ts +22 -3
- package/dist/brainy.js +28 -2
- package/dist/cli/commands/core.d.ts +3 -0
- package/dist/cli/commands/core.js +21 -3
- package/dist/cli/commands/import.js +69 -34
- package/dist/importers/SmartCSVImporter.js +35 -1
- package/dist/importers/SmartDOCXImporter.js +12 -0
- package/dist/importers/SmartExcelImporter.js +37 -1
- package/dist/importers/SmartJSONImporter.js +18 -0
- package/dist/importers/SmartMarkdownImporter.js +25 -2
- package/dist/importers/SmartPDFImporter.js +37 -1
- package/dist/importers/SmartYAMLImporter.js +12 -0
- package/dist/types/brainy.types.d.ts +106 -0
- package/dist/utils/import-progress-tracker.d.ts +140 -0
- package/dist/utils/import-progress-tracker.js +444 -0
- package/dist/vfs/PathResolver.js +4 -2
- package/dist/vfs/VirtualFileSystem.js +22 -7
- package/package.json +1 -1
|
@@ -61,7 +61,43 @@ export class SmartExcelImporter {
|
|
|
61
61
|
...options
|
|
62
62
|
};
|
|
63
63
|
// Parse Excel using existing handler
|
|
64
|
-
|
|
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:
|
|
75
|
-
relationshipsInferred:
|
|
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
|
-
|
|
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
|
+
}
|