@opentrace/components 0.1.1-rc.112 → 0.1.1-rc.120
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/pipeline.cjs +533 -2
- package/dist/pipeline.cjs.map +1 -1
- package/dist/pipeline.js +533 -2
- package/dist/pipeline.js.map +1 -1
- package/dist/src/pipeline/__tests__/concurrent.test.d.ts +2 -0
- package/dist/src/pipeline/__tests__/concurrent.test.d.ts.map +1 -0
- package/dist/src/pipeline/concurrent/debug.d.ts +38 -0
- package/dist/src/pipeline/concurrent/debug.d.ts.map +1 -0
- package/dist/src/pipeline/concurrent/index.d.ts +8 -0
- package/dist/src/pipeline/concurrent/index.d.ts.map +1 -0
- package/dist/src/pipeline/concurrent/scheduler.d.ts +13 -0
- package/dist/src/pipeline/concurrent/scheduler.d.ts.map +1 -0
- package/dist/src/pipeline/concurrent/stages.d.ts +156 -0
- package/dist/src/pipeline/concurrent/stages.d.ts.map +1 -0
- package/dist/src/pipeline/concurrent/types.d.ts +52 -0
- package/dist/src/pipeline/concurrent/types.d.ts.map +1 -0
- package/dist/src/pipeline/index.d.ts +8 -0
- package/dist/src/pipeline/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/pipeline.cjs
CHANGED
|
@@ -3315,14 +3315,14 @@ class TemplateSummarizer {
|
|
|
3315
3315
|
async dispose() {
|
|
3316
3316
|
}
|
|
3317
3317
|
}
|
|
3318
|
-
const TYPE_TO_KIND = {
|
|
3318
|
+
const TYPE_TO_KIND$1 = {
|
|
3319
3319
|
Function: "function",
|
|
3320
3320
|
Class: "class",
|
|
3321
3321
|
File: "file",
|
|
3322
3322
|
Directory: "directory"
|
|
3323
3323
|
};
|
|
3324
3324
|
function summarizeNode(node) {
|
|
3325
|
-
const kind = TYPE_TO_KIND[node.type];
|
|
3325
|
+
const kind = TYPE_TO_KIND$1[node.type];
|
|
3326
3326
|
if (!kind) {
|
|
3327
3327
|
return `${node.type} ${node.name}`;
|
|
3328
3328
|
}
|
|
@@ -3431,8 +3431,537 @@ const DEFAULT_SUMMARIZER_CONFIG = {
|
|
|
3431
3431
|
maxInputLength: 480,
|
|
3432
3432
|
minLines: 5
|
|
3433
3433
|
};
|
|
3434
|
+
function pushAll(dst, src) {
|
|
3435
|
+
for (let j = 0; j < src.length; j++) {
|
|
3436
|
+
dst.push(src[j]);
|
|
3437
|
+
}
|
|
3438
|
+
}
|
|
3439
|
+
function* runNodePipeline(opts) {
|
|
3440
|
+
const { ctx, stages, seeds } = opts;
|
|
3441
|
+
const stageCount = stages.length;
|
|
3442
|
+
const queues = Array.from({ length: stageCount }, () => []);
|
|
3443
|
+
pushAll(queues[0], seeds);
|
|
3444
|
+
let totalNodes = seeds.length;
|
|
3445
|
+
let totalRelationships = 0;
|
|
3446
|
+
const hasWork = () => queues.some((q) => q.length > 0);
|
|
3447
|
+
while (hasWork()) {
|
|
3448
|
+
if (ctx.cancelled) {
|
|
3449
|
+
yield { kind: "pipeline_error", error: "cancelled" };
|
|
3450
|
+
return;
|
|
3451
|
+
}
|
|
3452
|
+
let processed = false;
|
|
3453
|
+
for (let i = stageCount - 1; i >= 0; i--) {
|
|
3454
|
+
if (queues[i].length === 0) continue;
|
|
3455
|
+
const node = queues[i].shift();
|
|
3456
|
+
const stage = stages[i];
|
|
3457
|
+
yield { stage: stage.name(), node: node.id, action: "start" };
|
|
3458
|
+
let mutation;
|
|
3459
|
+
try {
|
|
3460
|
+
mutation = stage.process(node);
|
|
3461
|
+
} catch (err) {
|
|
3462
|
+
yield {
|
|
3463
|
+
kind: "item_error",
|
|
3464
|
+
stage: stage.name(),
|
|
3465
|
+
node: node.id,
|
|
3466
|
+
error: err instanceof Error ? err.message : String(err)
|
|
3467
|
+
};
|
|
3468
|
+
processed = true;
|
|
3469
|
+
break;
|
|
3470
|
+
}
|
|
3471
|
+
yield { stage: stage.name(), node: node.id, action: "end", mutation };
|
|
3472
|
+
totalRelationships += mutation.relationships.length;
|
|
3473
|
+
if (mutation.nodes.length > 0) {
|
|
3474
|
+
totalNodes += mutation.nodes.length;
|
|
3475
|
+
if (i < stageCount - 1) {
|
|
3476
|
+
pushAll(queues[i + 1], mutation.nodes);
|
|
3477
|
+
}
|
|
3478
|
+
}
|
|
3479
|
+
processed = true;
|
|
3480
|
+
break;
|
|
3481
|
+
}
|
|
3482
|
+
if (!processed) break;
|
|
3483
|
+
}
|
|
3484
|
+
for (const stage of stages) {
|
|
3485
|
+
if (ctx.cancelled) {
|
|
3486
|
+
yield { kind: "pipeline_error", error: "cancelled" };
|
|
3487
|
+
return;
|
|
3488
|
+
}
|
|
3489
|
+
yield { kind: "flush_start", stage: stage.name() };
|
|
3490
|
+
let mutation;
|
|
3491
|
+
try {
|
|
3492
|
+
mutation = stage.flush();
|
|
3493
|
+
} catch (err) {
|
|
3494
|
+
yield {
|
|
3495
|
+
kind: "pipeline_error",
|
|
3496
|
+
error: `flush error in ${stage.name()}: ${err instanceof Error ? err.message : String(err)}`
|
|
3497
|
+
};
|
|
3498
|
+
return;
|
|
3499
|
+
}
|
|
3500
|
+
totalNodes += mutation.nodes.length;
|
|
3501
|
+
totalRelationships += mutation.relationships.length;
|
|
3502
|
+
yield {
|
|
3503
|
+
kind: "flush_end",
|
|
3504
|
+
stage: stage.name(),
|
|
3505
|
+
mutation: mutation.nodes.length > 0 || mutation.relationships.length > 0 ? mutation : void 0
|
|
3506
|
+
};
|
|
3507
|
+
}
|
|
3508
|
+
yield {
|
|
3509
|
+
kind: "pipeline_done",
|
|
3510
|
+
totalNodes,
|
|
3511
|
+
totalRelationships
|
|
3512
|
+
};
|
|
3513
|
+
}
|
|
3514
|
+
const EMPTY_MUTATION = Object.freeze({
|
|
3515
|
+
nodes: [],
|
|
3516
|
+
relationships: []
|
|
3517
|
+
});
|
|
3518
|
+
const DEFAULT_CACHE_LIMIT = 500 * 1024 * 1024;
|
|
3519
|
+
class FileCacheStage {
|
|
3520
|
+
cache = /* @__PURE__ */ new Map();
|
|
3521
|
+
bytesUsed = 0;
|
|
3522
|
+
byteLimit;
|
|
3523
|
+
full = false;
|
|
3524
|
+
cachedCount = 0;
|
|
3525
|
+
skippedCount = 0;
|
|
3526
|
+
constructor(config) {
|
|
3527
|
+
this.byteLimit = config.byteLimit ?? DEFAULT_CACHE_LIMIT;
|
|
3528
|
+
for (const [fileId, content] of config.fileContentMap) {
|
|
3529
|
+
const byteSize = content.length * 2;
|
|
3530
|
+
if (this.bytesUsed + byteSize <= this.byteLimit) {
|
|
3531
|
+
this.cache.set(fileId, content);
|
|
3532
|
+
this.bytesUsed += byteSize;
|
|
3533
|
+
this.cachedCount++;
|
|
3534
|
+
} else {
|
|
3535
|
+
this.full = true;
|
|
3536
|
+
this.skippedCount++;
|
|
3537
|
+
}
|
|
3538
|
+
}
|
|
3539
|
+
}
|
|
3540
|
+
name() {
|
|
3541
|
+
return "cache";
|
|
3542
|
+
}
|
|
3543
|
+
process(node) {
|
|
3544
|
+
return { nodes: [node], relationships: [] };
|
|
3545
|
+
}
|
|
3546
|
+
flush() {
|
|
3547
|
+
return { nodes: [], relationships: [] };
|
|
3548
|
+
}
|
|
3549
|
+
/** Read cached content for a file. Returns undefined if not cached. */
|
|
3550
|
+
getContent(fileId) {
|
|
3551
|
+
return this.cache.get(fileId);
|
|
3552
|
+
}
|
|
3553
|
+
/**
|
|
3554
|
+
* Remove a file from the raw cache (e.g. after extraction is done).
|
|
3555
|
+
* Frees the JS string so GC can reclaim the memory.
|
|
3556
|
+
*/
|
|
3557
|
+
evict(fileId) {
|
|
3558
|
+
const content = this.cache.get(fileId);
|
|
3559
|
+
if (content) {
|
|
3560
|
+
this.bytesUsed -= content.length * 2;
|
|
3561
|
+
this.cache.delete(fileId);
|
|
3562
|
+
}
|
|
3563
|
+
}
|
|
3564
|
+
/** Current bytes used by the cache. */
|
|
3565
|
+
getBytesUsed() {
|
|
3566
|
+
return this.bytesUsed;
|
|
3567
|
+
}
|
|
3568
|
+
/** Whether the cache limit has been reached. */
|
|
3569
|
+
isFull() {
|
|
3570
|
+
return this.full;
|
|
3571
|
+
}
|
|
3572
|
+
/** Number of files cached vs skipped. */
|
|
3573
|
+
stats() {
|
|
3574
|
+
return {
|
|
3575
|
+
cached: this.cachedCount,
|
|
3576
|
+
skipped: this.skippedCount,
|
|
3577
|
+
bytesUsed: this.bytesUsed,
|
|
3578
|
+
byteLimit: this.byteLimit
|
|
3579
|
+
};
|
|
3580
|
+
}
|
|
3581
|
+
}
|
|
3582
|
+
class ExtractStage {
|
|
3583
|
+
registries = {
|
|
3584
|
+
nameRegistry: /* @__PURE__ */ new Map(),
|
|
3585
|
+
fileRegistry: /* @__PURE__ */ new Map(),
|
|
3586
|
+
classRegistry: /* @__PURE__ */ new Map(),
|
|
3587
|
+
importRegistry: /* @__PURE__ */ new Map()
|
|
3588
|
+
};
|
|
3589
|
+
allCallInfo = [];
|
|
3590
|
+
knownPaths;
|
|
3591
|
+
pathToFileId;
|
|
3592
|
+
goModulePath;
|
|
3593
|
+
getContent;
|
|
3594
|
+
packageNodes;
|
|
3595
|
+
emittedNodeIds = /* @__PURE__ */ new Set();
|
|
3596
|
+
pendingPackageNodes = [];
|
|
3597
|
+
constructor(config) {
|
|
3598
|
+
const { scanResult, getContent } = config;
|
|
3599
|
+
this.knownPaths = scanResult.knownPaths;
|
|
3600
|
+
this.pathToFileId = scanResult.pathToFileId;
|
|
3601
|
+
this.goModulePath = scanResult.goModulePath;
|
|
3602
|
+
this.getContent = getContent;
|
|
3603
|
+
this.packageNodes = new Map(scanResult.packageNodes);
|
|
3604
|
+
}
|
|
3605
|
+
name() {
|
|
3606
|
+
return "extract";
|
|
3607
|
+
}
|
|
3608
|
+
process(node) {
|
|
3609
|
+
if (node.type !== "File") {
|
|
3610
|
+
return { nodes: [node], relationships: [] };
|
|
3611
|
+
}
|
|
3612
|
+
const filePath = node.properties?.path;
|
|
3613
|
+
if (!filePath) {
|
|
3614
|
+
return { nodes: [node], relationships: [] };
|
|
3615
|
+
}
|
|
3616
|
+
const ext = getExtension(filePath);
|
|
3617
|
+
const language = detectLanguage(ext);
|
|
3618
|
+
if (!language) {
|
|
3619
|
+
return { nodes: [node], relationships: [] };
|
|
3620
|
+
}
|
|
3621
|
+
const parser = getParserForLanguage(language, ext);
|
|
3622
|
+
const extractor = getExtractor(language);
|
|
3623
|
+
if (!parser || !extractor) {
|
|
3624
|
+
return { nodes: [node], relationships: [] };
|
|
3625
|
+
}
|
|
3626
|
+
const fileId = node.id;
|
|
3627
|
+
const content = this.getContent(fileId);
|
|
3628
|
+
if (content === void 0) {
|
|
3629
|
+
return { nodes: [node], relationships: [] };
|
|
3630
|
+
}
|
|
3631
|
+
const nodes = [node];
|
|
3632
|
+
const rels = [];
|
|
3633
|
+
try {
|
|
3634
|
+
const tree = parser.parse(content);
|
|
3635
|
+
if (!tree) {
|
|
3636
|
+
return { nodes: [node], relationships: [] };
|
|
3637
|
+
}
|
|
3638
|
+
const extraction = extractor(tree.rootNode);
|
|
3639
|
+
this.registries.fileRegistry.set(fileId, /* @__PURE__ */ new Map());
|
|
3640
|
+
for (const sym of extraction.symbols) {
|
|
3641
|
+
processSymbol(
|
|
3642
|
+
sym,
|
|
3643
|
+
fileId,
|
|
3644
|
+
language,
|
|
3645
|
+
this.registries,
|
|
3646
|
+
this.allCallInfo,
|
|
3647
|
+
nodes,
|
|
3648
|
+
rels,
|
|
3649
|
+
this.emittedNodeIds
|
|
3650
|
+
);
|
|
3651
|
+
}
|
|
3652
|
+
const rootNode = extraction.rootNode;
|
|
3653
|
+
if (rootNode) {
|
|
3654
|
+
const importResult = analyzeImports(
|
|
3655
|
+
rootNode,
|
|
3656
|
+
language,
|
|
3657
|
+
filePath,
|
|
3658
|
+
this.knownPaths,
|
|
3659
|
+
this.goModulePath
|
|
3660
|
+
);
|
|
3661
|
+
const fileImports = {};
|
|
3662
|
+
const seenTargetFiles = /* @__PURE__ */ new Set();
|
|
3663
|
+
for (const [alias, targetPath] of Object.entries(
|
|
3664
|
+
importResult.internal
|
|
3665
|
+
)) {
|
|
3666
|
+
const targetFileId = this.pathToFileId.get(targetPath);
|
|
3667
|
+
if (targetFileId) {
|
|
3668
|
+
fileImports[alias] = targetFileId;
|
|
3669
|
+
if (!seenTargetFiles.has(targetFileId)) {
|
|
3670
|
+
seenTargetFiles.add(targetFileId);
|
|
3671
|
+
rels.push({
|
|
3672
|
+
id: `${fileId}->IMPORTS->${targetFileId}`,
|
|
3673
|
+
type: "IMPORTS",
|
|
3674
|
+
source_id: fileId,
|
|
3675
|
+
target_id: targetFileId
|
|
3676
|
+
});
|
|
3677
|
+
}
|
|
3678
|
+
}
|
|
3679
|
+
}
|
|
3680
|
+
this.registries.importRegistry.set(fileId, fileImports);
|
|
3681
|
+
for (const [pkgName, pkgId] of Object.entries(
|
|
3682
|
+
importResult.external
|
|
3683
|
+
)) {
|
|
3684
|
+
if (!this.packageNodes.has(pkgId)) {
|
|
3685
|
+
const pkgNode = {
|
|
3686
|
+
id: pkgId,
|
|
3687
|
+
type: "Package",
|
|
3688
|
+
name: pkgName,
|
|
3689
|
+
properties: { registry: pkgId.split(":")[1] }
|
|
3690
|
+
};
|
|
3691
|
+
this.packageNodes.set(pkgId, pkgNode);
|
|
3692
|
+
this.pendingPackageNodes.push(pkgNode);
|
|
3693
|
+
}
|
|
3694
|
+
rels.push({
|
|
3695
|
+
id: `${fileId}->IMPORTS->${pkgId}`,
|
|
3696
|
+
type: "IMPORTS",
|
|
3697
|
+
source_id: fileId,
|
|
3698
|
+
target_id: pkgId
|
|
3699
|
+
});
|
|
3700
|
+
}
|
|
3701
|
+
}
|
|
3702
|
+
} catch {
|
|
3703
|
+
return { nodes: [node], relationships: [] };
|
|
3704
|
+
}
|
|
3705
|
+
return { nodes, relationships: rels };
|
|
3706
|
+
}
|
|
3707
|
+
flush() {
|
|
3708
|
+
const nodes = this.pendingPackageNodes.splice(0);
|
|
3709
|
+
return { nodes, relationships: [] };
|
|
3710
|
+
}
|
|
3711
|
+
}
|
|
3712
|
+
class ResolveStage {
|
|
3713
|
+
extractStage;
|
|
3714
|
+
constructor(extractStage) {
|
|
3715
|
+
this.extractStage = extractStage;
|
|
3716
|
+
}
|
|
3717
|
+
name() {
|
|
3718
|
+
return "resolve";
|
|
3719
|
+
}
|
|
3720
|
+
process(node) {
|
|
3721
|
+
return { nodes: [node], relationships: [] };
|
|
3722
|
+
}
|
|
3723
|
+
flush() {
|
|
3724
|
+
const { registries, allCallInfo } = this.extractStage;
|
|
3725
|
+
const resolvedCalls = resolveCalls(allCallInfo, registries);
|
|
3726
|
+
const callRels = resolvedCallsToRelationships(resolvedCalls);
|
|
3727
|
+
return { nodes: [], relationships: callRels };
|
|
3728
|
+
}
|
|
3729
|
+
}
|
|
3730
|
+
const TYPE_TO_KIND = {
|
|
3731
|
+
Function: "function",
|
|
3732
|
+
Class: "class",
|
|
3733
|
+
File: "file",
|
|
3734
|
+
Directory: "directory"
|
|
3735
|
+
};
|
|
3736
|
+
class SummarizeStage {
|
|
3737
|
+
name() {
|
|
3738
|
+
return "summarize";
|
|
3739
|
+
}
|
|
3740
|
+
process(node) {
|
|
3741
|
+
if (!node.properties?.summary) {
|
|
3742
|
+
const summary = this.summarizeNode(node);
|
|
3743
|
+
if (summary) {
|
|
3744
|
+
node.properties = { ...node.properties, summary };
|
|
3745
|
+
}
|
|
3746
|
+
}
|
|
3747
|
+
return { nodes: [node], relationships: [] };
|
|
3748
|
+
}
|
|
3749
|
+
flush() {
|
|
3750
|
+
return { nodes: [], relationships: [] };
|
|
3751
|
+
}
|
|
3752
|
+
summarizeNode(node) {
|
|
3753
|
+
const kind = TYPE_TO_KIND[node.type];
|
|
3754
|
+
if (!kind) {
|
|
3755
|
+
return `${node.type} ${node.name}`;
|
|
3756
|
+
}
|
|
3757
|
+
const props = node.properties ?? {};
|
|
3758
|
+
return summarizeFromMetadata({
|
|
3759
|
+
name: node.name,
|
|
3760
|
+
kind,
|
|
3761
|
+
signature: props.signature,
|
|
3762
|
+
language: props.language,
|
|
3763
|
+
lineCount: typeof props.start_line === "number" && typeof props.end_line === "number" ? props.end_line - props.start_line + 1 : void 0,
|
|
3764
|
+
receiverType: props.receiver_type,
|
|
3765
|
+
fileName: kind === "file" ? props.path ?? node.name : void 0,
|
|
3766
|
+
childNames: props.childNames,
|
|
3767
|
+
docs: props.docs
|
|
3768
|
+
});
|
|
3769
|
+
}
|
|
3770
|
+
}
|
|
3771
|
+
const DEFAULT_DRAIN_THRESHOLD = 500;
|
|
3772
|
+
class StoreStage {
|
|
3773
|
+
bufferedNodes = [];
|
|
3774
|
+
bufferedRelationships = [];
|
|
3775
|
+
totalNodes = 0;
|
|
3776
|
+
totalRelationships = 0;
|
|
3777
|
+
drainThreshold;
|
|
3778
|
+
constructor(drainThreshold = DEFAULT_DRAIN_THRESHOLD) {
|
|
3779
|
+
this.drainThreshold = drainThreshold;
|
|
3780
|
+
}
|
|
3781
|
+
name() {
|
|
3782
|
+
return "store";
|
|
3783
|
+
}
|
|
3784
|
+
process(node) {
|
|
3785
|
+
this.bufferedNodes.push(node);
|
|
3786
|
+
this.totalNodes++;
|
|
3787
|
+
return { nodes: [], relationships: [] };
|
|
3788
|
+
}
|
|
3789
|
+
/**
|
|
3790
|
+
* Feed relationships from upstream stage mutations.
|
|
3791
|
+
* Call this from the event loop when processing StageEvent 'end' mutations.
|
|
3792
|
+
*/
|
|
3793
|
+
addRelationships(rels) {
|
|
3794
|
+
for (let i = 0; i < rels.length; i++) {
|
|
3795
|
+
this.bufferedRelationships.push(rels[i]);
|
|
3796
|
+
this.totalRelationships++;
|
|
3797
|
+
}
|
|
3798
|
+
}
|
|
3799
|
+
/** True when the node buffer has reached the drain threshold. */
|
|
3800
|
+
needsDrain() {
|
|
3801
|
+
return this.bufferedNodes.length >= this.drainThreshold;
|
|
3802
|
+
}
|
|
3803
|
+
/**
|
|
3804
|
+
* Return and clear buffered nodes. The caller should persist these
|
|
3805
|
+
* to the store (importBatch + flush). Called periodically from the
|
|
3806
|
+
* event loop, not just at the end.
|
|
3807
|
+
*/
|
|
3808
|
+
drainNodes() {
|
|
3809
|
+
const nodes = this.bufferedNodes;
|
|
3810
|
+
this.bufferedNodes = [];
|
|
3811
|
+
return nodes;
|
|
3812
|
+
}
|
|
3813
|
+
/**
|
|
3814
|
+
* Return and clear buffered relationships. Called once at the end
|
|
3815
|
+
* after all nodes have been persisted.
|
|
3816
|
+
*/
|
|
3817
|
+
drainRelationships() {
|
|
3818
|
+
const rels = this.bufferedRelationships;
|
|
3819
|
+
this.bufferedRelationships = [];
|
|
3820
|
+
return rels;
|
|
3821
|
+
}
|
|
3822
|
+
flush() {
|
|
3823
|
+
return {
|
|
3824
|
+
nodes: this.bufferedNodes,
|
|
3825
|
+
relationships: this.bufferedRelationships
|
|
3826
|
+
};
|
|
3827
|
+
}
|
|
3828
|
+
/** Cumulative counts (including already-drained items). */
|
|
3829
|
+
stats() {
|
|
3830
|
+
return {
|
|
3831
|
+
nodes: this.totalNodes,
|
|
3832
|
+
relationships: this.totalRelationships
|
|
3833
|
+
};
|
|
3834
|
+
}
|
|
3835
|
+
}
|
|
3836
|
+
class PipelineDebugLog {
|
|
3837
|
+
entries = [];
|
|
3838
|
+
startTime = 0;
|
|
3839
|
+
maxEntries;
|
|
3840
|
+
_enabled;
|
|
3841
|
+
constructor(opts = {}) {
|
|
3842
|
+
this.maxEntries = opts.maxEntries ?? 2e3;
|
|
3843
|
+
this._enabled = opts.enabled ?? true;
|
|
3844
|
+
}
|
|
3845
|
+
get enabled() {
|
|
3846
|
+
return this._enabled;
|
|
3847
|
+
}
|
|
3848
|
+
start() {
|
|
3849
|
+
this.entries = [];
|
|
3850
|
+
this.startTime = performance.now();
|
|
3851
|
+
this.log("pipeline", "started");
|
|
3852
|
+
}
|
|
3853
|
+
log(label, detail) {
|
|
3854
|
+
if (!this._enabled) return;
|
|
3855
|
+
const now = performance.now();
|
|
3856
|
+
const entry = {
|
|
3857
|
+
ts: now,
|
|
3858
|
+
elapsed: now - this.startTime,
|
|
3859
|
+
label,
|
|
3860
|
+
detail
|
|
3861
|
+
};
|
|
3862
|
+
this.entries.push(entry);
|
|
3863
|
+
if (this.entries.length > this.maxEntries) {
|
|
3864
|
+
this.entries.shift();
|
|
3865
|
+
}
|
|
3866
|
+
}
|
|
3867
|
+
logEvent(event) {
|
|
3868
|
+
if (!this._enabled) return;
|
|
3869
|
+
if ("action" in event) {
|
|
3870
|
+
const mutInfo = event.mutation ? ` nodes=${event.mutation.nodes.length} rels=${event.mutation.relationships.length}` : "";
|
|
3871
|
+
this.log(
|
|
3872
|
+
`stage:${event.stage}`,
|
|
3873
|
+
`${event.action} ${event.node}${mutInfo}`
|
|
3874
|
+
);
|
|
3875
|
+
} else if ("kind" in event) {
|
|
3876
|
+
switch (event.kind) {
|
|
3877
|
+
case "pipeline_done":
|
|
3878
|
+
this.log(
|
|
3879
|
+
"pipeline",
|
|
3880
|
+
`done nodes=${event.totalNodes} rels=${event.totalRelationships}`
|
|
3881
|
+
);
|
|
3882
|
+
break;
|
|
3883
|
+
case "pipeline_error":
|
|
3884
|
+
this.log("pipeline", `error: ${event.error}`);
|
|
3885
|
+
break;
|
|
3886
|
+
case "item_error":
|
|
3887
|
+
this.log(
|
|
3888
|
+
`stage:${event.stage}`,
|
|
3889
|
+
`item_error ${event.node}: ${event.error}`
|
|
3890
|
+
);
|
|
3891
|
+
break;
|
|
3892
|
+
case "flush_start":
|
|
3893
|
+
this.log(`stage:${event.stage}`, "flush_start");
|
|
3894
|
+
break;
|
|
3895
|
+
case "flush_end": {
|
|
3896
|
+
const mutInfo = event.mutation ? ` nodes=${event.mutation.nodes.length} rels=${event.mutation.relationships.length}` : "";
|
|
3897
|
+
this.log(`stage:${event.stage}`, `flush_end${mutInfo}`);
|
|
3898
|
+
break;
|
|
3899
|
+
}
|
|
3900
|
+
}
|
|
3901
|
+
}
|
|
3902
|
+
}
|
|
3903
|
+
/** Return all entries (most recent last). */
|
|
3904
|
+
getEntries() {
|
|
3905
|
+
return this.entries;
|
|
3906
|
+
}
|
|
3907
|
+
/** Summarize stage durations and counts. */
|
|
3908
|
+
summary() {
|
|
3909
|
+
const stages = {};
|
|
3910
|
+
for (const entry of this.entries) {
|
|
3911
|
+
if (!entry.label.startsWith("stage:")) continue;
|
|
3912
|
+
const stage = entry.label;
|
|
3913
|
+
if (!stages[stage]) {
|
|
3914
|
+
stages[stage] = { count: 0, totalMs: 0, lastStart: 0 };
|
|
3915
|
+
}
|
|
3916
|
+
if (entry.detail?.startsWith("start ")) {
|
|
3917
|
+
stages[stage].lastStart = entry.ts;
|
|
3918
|
+
} else if (entry.detail?.startsWith("end ")) {
|
|
3919
|
+
if (stages[stage].lastStart > 0) {
|
|
3920
|
+
stages[stage].totalMs += entry.ts - stages[stage].lastStart;
|
|
3921
|
+
stages[stage].count++;
|
|
3922
|
+
stages[stage].lastStart = 0;
|
|
3923
|
+
}
|
|
3924
|
+
}
|
|
3925
|
+
}
|
|
3926
|
+
const result = {};
|
|
3927
|
+
for (const [k, v] of Object.entries(stages)) {
|
|
3928
|
+
result[k] = { count: v.count, totalMs: Math.round(v.totalMs * 100) / 100 };
|
|
3929
|
+
}
|
|
3930
|
+
return result;
|
|
3931
|
+
}
|
|
3932
|
+
/** Dump to console in a readable format. */
|
|
3933
|
+
dump() {
|
|
3934
|
+
console.group("[PipelineDebug] Event log");
|
|
3935
|
+
for (const e of this.entries) {
|
|
3936
|
+
console.log(
|
|
3937
|
+
`%c+${e.elapsed.toFixed(1)}ms%c ${e.label} %c${e.detail ?? ""}`,
|
|
3938
|
+
"color: gray",
|
|
3939
|
+
"color: white; font-weight: bold",
|
|
3940
|
+
"color: cyan"
|
|
3941
|
+
);
|
|
3942
|
+
}
|
|
3943
|
+
console.groupEnd();
|
|
3944
|
+
const s = this.summary();
|
|
3945
|
+
if (Object.keys(s).length > 0) {
|
|
3946
|
+
console.group("[PipelineDebug] Stage summary");
|
|
3947
|
+
for (const [stage, info] of Object.entries(s)) {
|
|
3948
|
+
console.log(
|
|
3949
|
+
`${stage}: ${info.count} items in ${info.totalMs.toFixed(1)}ms (avg ${(info.totalMs / Math.max(info.count, 1)).toFixed(1)}ms)`
|
|
3950
|
+
);
|
|
3951
|
+
}
|
|
3952
|
+
console.groupEnd();
|
|
3953
|
+
}
|
|
3954
|
+
}
|
|
3955
|
+
}
|
|
3434
3956
|
exports.DEFAULT_SUMMARIZER_CONFIG = DEFAULT_SUMMARIZER_CONFIG;
|
|
3957
|
+
exports.EMPTY_MUTATION = EMPTY_MUTATION;
|
|
3958
|
+
exports.ExtractStage = ExtractStage;
|
|
3959
|
+
exports.FileCacheStage = FileCacheStage;
|
|
3435
3960
|
exports.MemoryStore = MemoryStore;
|
|
3961
|
+
exports.PipelineDebugLog = PipelineDebugLog;
|
|
3962
|
+
exports.ResolveStage = ResolveStage;
|
|
3963
|
+
exports.StoreStage = StoreStage;
|
|
3964
|
+
exports.SummarizeStage = SummarizeStage;
|
|
3436
3965
|
exports.TemplateSummarizer = TemplateSummarizer;
|
|
3437
3966
|
exports.addToRegistry = addToRegistry;
|
|
3438
3967
|
exports.analyzeGoImports = analyzeGoImports;
|
|
@@ -3445,6 +3974,7 @@ exports.collectPipeline = collectPipeline;
|
|
|
3445
3974
|
exports.countSymbols = countSymbols;
|
|
3446
3975
|
exports.detectLanguage = detectLanguage;
|
|
3447
3976
|
exports.ensureDirChain = ensureDirChain;
|
|
3977
|
+
exports.executeScanning = execute$3;
|
|
3448
3978
|
exports.extractGeneric = extractGeneric;
|
|
3449
3979
|
exports.extractGo = extractGo;
|
|
3450
3980
|
exports.extractKeywords = extractKeywords;
|
|
@@ -3471,6 +4001,7 @@ exports.processSymbol = processSymbol;
|
|
|
3471
4001
|
exports.resetDirIndexCache = resetDirIndexCache;
|
|
3472
4002
|
exports.resolveCalls = resolveCalls;
|
|
3473
4003
|
exports.resolvedCallsToRelationships = resolvedCallsToRelationships;
|
|
4004
|
+
exports.runNodePipeline = runNodePipeline;
|
|
3474
4005
|
exports.runPipeline = runPipeline;
|
|
3475
4006
|
exports.splitIdentifier = splitIdentifier;
|
|
3476
4007
|
exports.summarizeClass = summarizeClass;
|