flow-debugger 1.0.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.
Files changed (131) hide show
  1. package/PORTFOLIO_README_SECTION.md +177 -0
  2. package/README.md +251 -0
  3. package/dashboard/app.js +339 -0
  4. package/dashboard/index.html +168 -0
  5. package/dashboard/style.css +846 -0
  6. package/dist/cjs/core/Analytics.js +174 -0
  7. package/dist/cjs/core/Analytics.js.map +1 -0
  8. package/dist/cjs/core/Classifier.js +66 -0
  9. package/dist/cjs/core/Classifier.js.map +1 -0
  10. package/dist/cjs/core/HealthMonitor.js +79 -0
  11. package/dist/cjs/core/HealthMonitor.js.map +1 -0
  12. package/dist/cjs/core/RootCause.js +89 -0
  13. package/dist/cjs/core/RootCause.js.map +1 -0
  14. package/dist/cjs/core/Sampler.js +34 -0
  15. package/dist/cjs/core/Sampler.js.map +1 -0
  16. package/dist/cjs/core/Timeline.js +90 -0
  17. package/dist/cjs/core/Timeline.js.map +1 -0
  18. package/dist/cjs/core/TraceEngine.js +222 -0
  19. package/dist/cjs/core/TraceEngine.js.map +1 -0
  20. package/dist/cjs/core/types.js +21 -0
  21. package/dist/cjs/core/types.js.map +1 -0
  22. package/dist/cjs/index.js +46 -0
  23. package/dist/cjs/index.js.map +1 -0
  24. package/dist/cjs/integrations/axios.js +136 -0
  25. package/dist/cjs/integrations/axios.js.map +1 -0
  26. package/dist/cjs/integrations/fetch.js +153 -0
  27. package/dist/cjs/integrations/fetch.js.map +1 -0
  28. package/dist/cjs/integrations/mongo.js +111 -0
  29. package/dist/cjs/integrations/mongo.js.map +1 -0
  30. package/dist/cjs/integrations/mysql.js +212 -0
  31. package/dist/cjs/integrations/mysql.js.map +1 -0
  32. package/dist/cjs/integrations/postgres.js +182 -0
  33. package/dist/cjs/integrations/postgres.js.map +1 -0
  34. package/dist/cjs/integrations/redis.js +105 -0
  35. package/dist/cjs/integrations/redis.js.map +1 -0
  36. package/dist/cjs/middleware/express.js +255 -0
  37. package/dist/cjs/middleware/express.js.map +1 -0
  38. package/dist/esm/core/Analytics.js +170 -0
  39. package/dist/esm/core/Analytics.js.map +1 -0
  40. package/dist/esm/core/Classifier.js +61 -0
  41. package/dist/esm/core/Classifier.js.map +1 -0
  42. package/dist/esm/core/HealthMonitor.js +75 -0
  43. package/dist/esm/core/HealthMonitor.js.map +1 -0
  44. package/dist/esm/core/RootCause.js +86 -0
  45. package/dist/esm/core/RootCause.js.map +1 -0
  46. package/dist/esm/core/Sampler.js +30 -0
  47. package/dist/esm/core/Sampler.js.map +1 -0
  48. package/dist/esm/core/Timeline.js +86 -0
  49. package/dist/esm/core/Timeline.js.map +1 -0
  50. package/dist/esm/core/TraceEngine.js +217 -0
  51. package/dist/esm/core/TraceEngine.js.map +1 -0
  52. package/dist/esm/core/types.js +18 -0
  53. package/dist/esm/core/types.js.map +1 -0
  54. package/dist/esm/index.js +22 -0
  55. package/dist/esm/index.js.map +1 -0
  56. package/dist/esm/integrations/axios.js +133 -0
  57. package/dist/esm/integrations/axios.js.map +1 -0
  58. package/dist/esm/integrations/fetch.js +149 -0
  59. package/dist/esm/integrations/fetch.js.map +1 -0
  60. package/dist/esm/integrations/mongo.js +107 -0
  61. package/dist/esm/integrations/mongo.js.map +1 -0
  62. package/dist/esm/integrations/mysql.js +209 -0
  63. package/dist/esm/integrations/mysql.js.map +1 -0
  64. package/dist/esm/integrations/postgres.js +179 -0
  65. package/dist/esm/integrations/postgres.js.map +1 -0
  66. package/dist/esm/integrations/redis.js +102 -0
  67. package/dist/esm/integrations/redis.js.map +1 -0
  68. package/dist/esm/middleware/express.js +219 -0
  69. package/dist/esm/middleware/express.js.map +1 -0
  70. package/dist/types/core/Analytics.d.ts +35 -0
  71. package/dist/types/core/Analytics.d.ts.map +1 -0
  72. package/dist/types/core/Classifier.d.ts +21 -0
  73. package/dist/types/core/Classifier.d.ts.map +1 -0
  74. package/dist/types/core/HealthMonitor.d.ts +14 -0
  75. package/dist/types/core/HealthMonitor.d.ts.map +1 -0
  76. package/dist/types/core/RootCause.d.ts +12 -0
  77. package/dist/types/core/RootCause.d.ts.map +1 -0
  78. package/dist/types/core/Sampler.d.ts +13 -0
  79. package/dist/types/core/Sampler.d.ts.map +1 -0
  80. package/dist/types/core/Timeline.d.ts +22 -0
  81. package/dist/types/core/Timeline.d.ts.map +1 -0
  82. package/dist/types/core/TraceEngine.d.ts +47 -0
  83. package/dist/types/core/TraceEngine.d.ts.map +1 -0
  84. package/dist/types/core/types.d.ts +118 -0
  85. package/dist/types/core/types.d.ts.map +1 -0
  86. package/dist/types/index.d.ts +18 -0
  87. package/dist/types/index.d.ts.map +1 -0
  88. package/dist/types/integrations/axios.d.ts +22 -0
  89. package/dist/types/integrations/axios.d.ts.map +1 -0
  90. package/dist/types/integrations/fetch.d.ts +25 -0
  91. package/dist/types/integrations/fetch.d.ts.map +1 -0
  92. package/dist/types/integrations/mongo.d.ts +26 -0
  93. package/dist/types/integrations/mongo.d.ts.map +1 -0
  94. package/dist/types/integrations/mysql.d.ts +20 -0
  95. package/dist/types/integrations/mysql.d.ts.map +1 -0
  96. package/dist/types/integrations/postgres.d.ts +20 -0
  97. package/dist/types/integrations/postgres.d.ts.map +1 -0
  98. package/dist/types/integrations/redis.d.ts +20 -0
  99. package/dist/types/integrations/redis.d.ts.map +1 -0
  100. package/dist/types/middleware/express.d.ts +39 -0
  101. package/dist/types/middleware/express.d.ts.map +1 -0
  102. package/example/server.ts +234 -0
  103. package/jest.config.js +8 -0
  104. package/package.json +110 -0
  105. package/portfolio-repo/APIRESPONSE DASH.png +0 -0
  106. package/portfolio-repo/PAYLOAD.png +0 -0
  107. package/portfolio-repo/README.md +182 -0
  108. package/src/core/Analytics.ts +209 -0
  109. package/src/core/Classifier.ts +82 -0
  110. package/src/core/HealthMonitor.ts +92 -0
  111. package/src/core/RootCause.ts +105 -0
  112. package/src/core/Sampler.ts +35 -0
  113. package/src/core/Timeline.ts +108 -0
  114. package/src/core/TraceEngine.ts +266 -0
  115. package/src/core/types.ts +170 -0
  116. package/src/index.ts +42 -0
  117. package/src/integrations/axios.ts +164 -0
  118. package/src/integrations/fetch.ts +172 -0
  119. package/src/integrations/mongo.ts +130 -0
  120. package/src/integrations/mysql.ts +239 -0
  121. package/src/integrations/postgres.ts +217 -0
  122. package/src/integrations/redis.ts +122 -0
  123. package/src/middleware/express.ts +264 -0
  124. package/tests/Analytics.test.ts +136 -0
  125. package/tests/Classifier.test.ts +57 -0
  126. package/tests/RootCause.test.ts +69 -0
  127. package/tests/TraceEngine.test.ts +110 -0
  128. package/tsconfig.cjs.json +9 -0
  129. package/tsconfig.esm.json +9 -0
  130. package/tsconfig.json +31 -0
  131. package/tsconfig.types.json +8 -0
@@ -0,0 +1,86 @@
1
+ // ─────────────────────────────────────────────────────────────
2
+ // flow-debugger — Root Cause Detection
3
+ // Analyzes trace steps to identify the most likely failure origin
4
+ // ─────────────────────────────────────────────────────────────
5
+ /**
6
+ * Detect the root cause of a trace failure or slowness.
7
+ *
8
+ * Algorithm:
9
+ * 1. If response is 500 and a step failed → root cause = first failed step
10
+ * 2. If a step timed out → root cause = timeout step (CRITICAL)
11
+ * 3. If DB/Redis slow and total latency high → root cause = slow dependency
12
+ * 4. If no failures but overall slow → root cause = slowest step
13
+ */
14
+ export function detectRootCause(steps, statusCode, config) {
15
+ if (steps.length === 0)
16
+ return null;
17
+ const slowThreshold = config.slowThreshold ?? 300;
18
+ // 1. Look for timed-out steps (highest priority)
19
+ const timedOut = steps.find(s => s.status === 'timeout');
20
+ if (timedOut) {
21
+ return {
22
+ cause: `${timedOut.name} timed out`,
23
+ step: timedOut.name,
24
+ service: timedOut.service,
25
+ confidence: 'high',
26
+ };
27
+ }
28
+ // 2. Look for failed steps when response is 5xx
29
+ if (statusCode && statusCode >= 500) {
30
+ const failedSteps = steps.filter(s => s.status === 'error');
31
+ if (failedSteps.length > 0) {
32
+ // First failure is most likely root cause
33
+ const first = failedSteps[0];
34
+ return {
35
+ cause: `${first.name} failed: ${first.error || 'unknown error'}`,
36
+ step: first.name,
37
+ service: first.service,
38
+ confidence: 'high',
39
+ };
40
+ }
41
+ }
42
+ // 3. Look for any failed step (even if response isn't 500)
43
+ const failedStep = steps.find(s => s.status === 'error');
44
+ if (failedStep) {
45
+ return {
46
+ cause: `${failedStep.name} failed: ${failedStep.error || 'unknown error'}`,
47
+ step: failedStep.name,
48
+ service: failedStep.service,
49
+ confidence: statusCode && statusCode >= 400 ? 'high' : 'medium',
50
+ };
51
+ }
52
+ // 4. Look for slow steps
53
+ const slowSteps = steps.filter(s => s.duration > slowThreshold);
54
+ if (slowSteps.length > 0) {
55
+ // Slowest step is the most likely bottleneck
56
+ const slowest = slowSteps.reduce((a, b) => (a.duration > b.duration ? a : b));
57
+ const totalDuration = steps.reduce((sum, s) => sum + s.duration, 0);
58
+ const ratio = slowest.duration / totalDuration;
59
+ return {
60
+ cause: `Slow ${getServiceLabel(slowest.service)} query: ${slowest.name} (${Math.round(slowest.duration)}ms)`,
61
+ step: slowest.name,
62
+ service: slowest.service,
63
+ confidence: ratio > 0.5 ? 'high' : 'medium',
64
+ };
65
+ }
66
+ return null;
67
+ }
68
+ function getServiceLabel(service) {
69
+ const labels = {
70
+ mongo: 'MongoDB',
71
+ mysql: 'MySQL',
72
+ postgres: 'PostgreSQL',
73
+ redis: 'Redis',
74
+ axios: 'HTTP',
75
+ fetch: 'HTTP',
76
+ stripe: 'Stripe',
77
+ razorpay: 'Razorpay',
78
+ sendgrid: 'SendGrid',
79
+ twilio: 'Twilio',
80
+ external: 'External',
81
+ internal: 'Internal',
82
+ unknown: 'Unknown',
83
+ };
84
+ return labels[service] || service;
85
+ }
86
+ //# sourceMappingURL=RootCause.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RootCause.js","sourceRoot":"","sources":["../../../src/core/RootCause.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ // ─────────────────────────────────────────────────────────────
2
+ // flow-debugger — Sampler
3
+ // Probabilistic sampling for high-traffic environments
4
+ // ─────────────────────────────────────────────────────────────
5
+ export class Sampler {
6
+ constructor(rate = 1, alwaysSampleErrors = true) {
7
+ this.rate = Math.max(0, Math.min(1, rate));
8
+ this.alwaysSampleErrors = alwaysSampleErrors;
9
+ }
10
+ /** Should this request be sampled? */
11
+ shouldSample() {
12
+ if (this.rate >= 1)
13
+ return true;
14
+ if (this.rate <= 0)
15
+ return false;
16
+ return Math.random() < this.rate;
17
+ }
18
+ /** Force sample if it's an error (if alwaysSampleErrors is true) */
19
+ shouldSampleError() {
20
+ return this.alwaysSampleErrors;
21
+ }
22
+ /** Update sampling rate at runtime */
23
+ setRate(rate) {
24
+ this.rate = Math.max(0, Math.min(1, rate));
25
+ }
26
+ getRate() {
27
+ return this.rate;
28
+ }
29
+ }
30
+ //# sourceMappingURL=Sampler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Sampler.js","sourceRoot":"","sources":["../../../src/core/Sampler.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,0BAA0B;AAC1B,uDAAuD;AACvD,gEAAgE;AAEhE,MAAM,OAAO,OAAO;IAIhB,YAAY,IAAI,GAAG,CAAC,EAAE,kBAAkB,GAAG,IAAI;QAC3C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;QAC3C,IAAI,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;IACjD,CAAC;IAED,sCAAsC;IACtC,YAAY;QACR,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAChC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QACjC,OAAO,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC;IACrC,CAAC;IAED,oEAAoE;IACpE,iBAAiB;QACb,OAAO,IAAI,CAAC,kBAAkB,CAAC;IACnC,CAAC;IAED,sCAAsC;IACtC,OAAO,CAAC,IAAY;QAChB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO;QACH,OAAO,IAAI,CAAC,IAAI,CAAC;IACrB,CAAC;CACJ"}
@@ -0,0 +1,86 @@
1
+ // ─────────────────────────────────────────────────────────────
2
+ // flow-debugger — Timeline Renderer
3
+ // Prints a visual timeline of a trace to the console
4
+ // ─────────────────────────────────────────────────────────────
5
+ const ICONS = {
6
+ success: '✔',
7
+ error: '❌',
8
+ timeout: '⏱ TIMEOUT',
9
+ };
10
+ const LEVEL_COLORS = {
11
+ INFO: '\x1b[32m', // green
12
+ WARN: '\x1b[33m', // yellow
13
+ ERROR: '\x1b[31m', // red
14
+ CRITICAL: '\x1b[35m', // magenta
15
+ };
16
+ const RESET = '\x1b[0m';
17
+ const DIM = '\x1b[2m';
18
+ const BOLD = '\x1b[1m';
19
+ const CYAN = '\x1b[36m';
20
+ /**
21
+ * Render a trace timeline to the console.
22
+ *
23
+ * Output example:
24
+ * ┌─── flow-debugger ── req_abc123 ── POST /login ───
25
+ * │ [0ms] Request start
26
+ * │ [2ms] DB find user ✔ (14ms) [mongo]
27
+ * │ [16ms] Redis cache ❌ (3ms) [redis]
28
+ * │ [20ms] Response 200
29
+ * │
30
+ * │ ⚠ Root cause: Redis cache failed: connection refused
31
+ * │ Classification: ERROR
32
+ * │ Total: 20ms
33
+ * └────────────────────────────────────────────────────
34
+ */
35
+ export function renderTimeline(trace, logger = console.log) {
36
+ const lines = [];
37
+ const divider = '─'.repeat(50);
38
+ lines.push('');
39
+ lines.push(`${CYAN}┌─── flow-debugger ── ${trace.traceId} ── ${trace.method} ${trace.endpoint} ───${RESET}`);
40
+ lines.push(`${DIM}│ [0ms] Request start${RESET}`);
41
+ for (const step of trace.steps) {
42
+ const offset = Math.round(step.startTime);
43
+ const dur = Math.round(step.duration);
44
+ const icon = ICONS[step.status] || '?';
45
+ const levelColor = LEVEL_COLORS[step.classification] || '';
46
+ const serviceTag = step.service !== 'internal' ? ` ${DIM}[${step.service}]${RESET}` : '';
47
+ const line = `│ [${offset}ms]${' '.repeat(Math.max(1, 5 - String(offset).length))}` +
48
+ `${levelColor}${step.name} ${icon} (${dur}ms)${RESET}${serviceTag}`;
49
+ lines.push(line);
50
+ if (step.error) {
51
+ lines.push(`│ ${DIM}└─ ${step.error}${RESET}`);
52
+ }
53
+ // Slow query warning
54
+ if (step.classification === 'WARN' && step.duration > 300) {
55
+ lines.push(`│ ${LEVEL_COLORS.WARN}⚠ Slow ${step.service} query detected (${dur}ms)${RESET}`);
56
+ }
57
+ }
58
+ // Response line
59
+ lines.push(`${DIM}│ [${Math.round(trace.totalDuration)}ms]${' '.repeat(Math.max(1, 5 - String(Math.round(trace.totalDuration)).length))}Response ${trace.statusCode || '—'}${RESET}`);
60
+ lines.push('│');
61
+ // Root cause
62
+ if (trace.rootCause) {
63
+ const rcColor = LEVEL_COLORS.ERROR;
64
+ lines.push(`${rcColor}│ 🔍 Root cause: ${trace.rootCause.cause}${RESET}`);
65
+ lines.push(`${DIM}│ Service: ${trace.rootCause.service} | Confidence: ${trace.rootCause.confidence}${RESET}`);
66
+ }
67
+ // Classification
68
+ const clsColor = LEVEL_COLORS[trace.classification];
69
+ lines.push(`${clsColor}│ Classification: ${trace.classification}${RESET}`);
70
+ lines.push(`${DIM}│ Total: ${Math.round(trace.totalDuration)}ms${RESET}`);
71
+ lines.push(`${CYAN}└${divider}${RESET}`);
72
+ lines.push('');
73
+ logger(lines.join('\n'));
74
+ }
75
+ /**
76
+ * Render a compact one-line summary for high-traffic mode.
77
+ */
78
+ export function renderCompact(trace, logger = console.log) {
79
+ const icon = trace.classification === 'INFO' ? '✔' :
80
+ trace.classification === 'WARN' ? '⚠' :
81
+ trace.classification === 'ERROR' ? '❌' :
82
+ '🔴';
83
+ const rc = trace.rootCause ? ` → ${trace.rootCause.cause}` : '';
84
+ logger(`${icon} ${trace.method} ${trace.endpoint} ${Math.round(trace.totalDuration)}ms [${trace.classification}]${rc}`);
85
+ }
86
+ //# sourceMappingURL=Timeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Timeline.js","sourceRoot":"","sources":["../../../src/core/Timeline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,217 @@
1
+ // ─────────────────────────────────────────────────────────────
2
+ // flow-debugger — Trace Engine
3
+ // Manages trace lifecycle: create → add steps → end
4
+ // ─────────────────────────────────────────────────────────────
5
+ import { EventEmitter } from 'events';
6
+ import { DEFAULT_CONFIG, } from './types';
7
+ import { classify, classifyTrace } from './Classifier';
8
+ import { detectRootCause } from './RootCause';
9
+ import { renderTimeline } from './Timeline';
10
+ let idCounter = 0;
11
+ /** Generate a unique trace ID */
12
+ function generateTraceId() {
13
+ const ts = Date.now().toString(36);
14
+ const rand = Math.random().toString(36).substring(2, 8);
15
+ idCounter++;
16
+ return `req_${ts}_${rand}_${idCounter}`;
17
+ }
18
+ /**
19
+ * Extract file and line number from stack trace for dashboard preview.
20
+ * Example: "at Object.<anonymous> (d:\\project\\auth.service.ts:42:15)"
21
+ * Returns: { file: "auth.service.ts", line: 42 }
22
+ */
23
+ function extractErrorLocation(stackTrace) {
24
+ if (!stackTrace)
25
+ return {};
26
+ try {
27
+ // Match patterns like:
28
+ // at functionName (file.ts:42:15)
29
+ // at file.ts:42:15
30
+ const match = stackTrace.match(/\(([^)]+):(\d+):\d+\)/) || stackTrace.match(/at\s+([^:]+):(\d+):\d+/);
31
+ if (match) {
32
+ const fullPath = match[1];
33
+ const lineNum = parseInt(match[2], 10);
34
+ // Extract just the filename from full path
35
+ const fileName = fullPath.split(/[/\\]/).pop() || fullPath;
36
+ return { file: fileName, line: lineNum };
37
+ }
38
+ }
39
+ catch (_) {
40
+ // ignore parse errors
41
+ }
42
+ return {};
43
+ }
44
+ /**
45
+ * TraceEngine — manages the lifecycle of a single request trace.
46
+ *
47
+ * Usage:
48
+ * const engine = new TraceEngine(config);
49
+ * const tracer = engine.startTrace('/login', 'POST');
50
+ * await tracer.step('DB find user', async () => User.findOne(), { service: 'mongo' });
51
+ * tracer.end(200);
52
+ */
53
+ export class TraceEngine extends EventEmitter {
54
+ constructor(config) {
55
+ super();
56
+ this.config = { ...DEFAULT_CONFIG, ...config };
57
+ }
58
+ /** Update config at runtime */
59
+ updateConfig(patch) {
60
+ Object.assign(this.config, patch);
61
+ }
62
+ getConfig() {
63
+ return { ...this.config };
64
+ }
65
+ /** Start a new request trace */
66
+ startTrace(endpoint, method) {
67
+ const tracer = new RequestTracer(endpoint, method, this.config, this);
68
+ this.safeEmit('trace:start', { traceId: tracer.getTraceId(), endpoint, method });
69
+ return tracer;
70
+ }
71
+ /** Safe emit — never throws */
72
+ safeEmit(event, data) {
73
+ try {
74
+ this.emit(event, data);
75
+ }
76
+ catch (_) {
77
+ // debugger never crashes the app
78
+ }
79
+ }
80
+ }
81
+ /**
82
+ * RequestTracer — the object attached to a single request.
83
+ * Provides `step()` for manual instrumentation and `addStep()` for auto-instrumentation.
84
+ */
85
+ export class RequestTracer {
86
+ constructor(endpoint, method, config, engine) {
87
+ this.steps = [];
88
+ this.ended = false;
89
+ this.traceId = generateTraceId();
90
+ this.endpoint = endpoint;
91
+ this.method = method;
92
+ this.startTime = performance.now();
93
+ this.config = config;
94
+ this.engine = engine;
95
+ }
96
+ getTraceId() {
97
+ return this.traceId;
98
+ }
99
+ getSteps() {
100
+ return [...this.steps];
101
+ }
102
+ /** Manually run & trace an async step */
103
+ async step(name, fn, options) {
104
+ const service = options?.service ?? 'internal';
105
+ const timeout = options?.timeout ?? this.config.defaultTimeout;
106
+ const stepStart = performance.now();
107
+ let status = 'success';
108
+ let error;
109
+ let stackTrace;
110
+ let result;
111
+ try {
112
+ // Race the function against a timeout
113
+ result = await Promise.race([
114
+ Promise.resolve(fn()),
115
+ new Promise((_, reject) => setTimeout(() => reject(new Error(`Step "${name}" timed out after ${timeout}ms`)), timeout)),
116
+ ]);
117
+ }
118
+ catch (err) {
119
+ const e = err instanceof Error ? err : new Error(String(err));
120
+ if (e.message.includes('timed out')) {
121
+ status = 'timeout';
122
+ }
123
+ else {
124
+ status = 'error';
125
+ }
126
+ error = e.message;
127
+ stackTrace = e.stack;
128
+ const { file: errorFile, line: errorLine } = extractErrorLocation(stackTrace);
129
+ // Re-throw so the caller can handle the error
130
+ const stepEnd = performance.now();
131
+ const duration = stepEnd - stepStart;
132
+ const classification = classify(duration, status, this.config);
133
+ this.steps.push({
134
+ name,
135
+ service,
136
+ status,
137
+ classification,
138
+ startTime: stepStart - this.startTime,
139
+ endTime: stepEnd - this.startTime,
140
+ duration,
141
+ error,
142
+ stackTrace,
143
+ errorFile,
144
+ errorLine,
145
+ metadata: options?.metadata,
146
+ });
147
+ throw err;
148
+ }
149
+ const stepEnd = performance.now();
150
+ const duration = stepEnd - stepStart;
151
+ const classification = classify(duration, status, this.config);
152
+ const { file: errorFile, line: errorLine } = error ? extractErrorLocation(stackTrace) : {};
153
+ this.steps.push({
154
+ name,
155
+ service,
156
+ status,
157
+ classification,
158
+ startTime: stepStart - this.startTime,
159
+ endTime: stepEnd - this.startTime,
160
+ duration,
161
+ error,
162
+ stackTrace,
163
+ errorFile,
164
+ errorLine,
165
+ metadata: options?.metadata,
166
+ });
167
+ return result;
168
+ }
169
+ /** Add a pre-recorded step (used by auto-integrations) */
170
+ addStep(step) {
171
+ try {
172
+ this.steps.push(step);
173
+ }
174
+ catch (_) {
175
+ // never crash
176
+ }
177
+ }
178
+ /** End the trace and produce the final result */
179
+ end(statusCode) {
180
+ if (this.ended) {
181
+ return this.buildTrace(statusCode);
182
+ }
183
+ this.ended = true;
184
+ const trace = this.buildTrace(statusCode);
185
+ // Render timeline to console
186
+ if (this.config.enableTimeline) {
187
+ try {
188
+ renderTimeline(trace, this.config.logger);
189
+ }
190
+ catch (_) {
191
+ // never crash
192
+ }
193
+ }
194
+ this.engine.safeEmit('trace:end', trace);
195
+ return trace;
196
+ }
197
+ buildTrace(statusCode) {
198
+ const endTime = performance.now();
199
+ const totalDuration = endTime - this.startTime;
200
+ const traceClassification = classifyTrace(this.steps, totalDuration, this.config);
201
+ const rootCause = detectRootCause(this.steps, statusCode, this.config);
202
+ return {
203
+ traceId: this.traceId,
204
+ endpoint: this.endpoint,
205
+ method: this.method,
206
+ statusCode,
207
+ steps: [...this.steps],
208
+ totalDuration,
209
+ classification: traceClassification,
210
+ rootCause,
211
+ startTime: 0,
212
+ endTime: totalDuration,
213
+ timestamp: new Date(),
214
+ };
215
+ }
216
+ }
217
+ //# sourceMappingURL=TraceEngine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TraceEngine.js","sourceRoot":"","sources":["../../../src/core/TraceEngine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ // ─────────────────────────────────────────────────────────────
2
+ // flow-debugger — Core Type Definitions
3
+ // ─────────────────────────────────────────────────────────────
4
+ export const DEFAULT_CONFIG = {
5
+ enabled: true,
6
+ environment: process.env.NODE_ENV || 'development',
7
+ slowThreshold: 300,
8
+ slowQueryThreshold: 300,
9
+ defaultTimeout: 30000,
10
+ samplingRate: 1,
11
+ alwaysSampleErrors: true,
12
+ maxTraces: 1000,
13
+ enableTimeline: true,
14
+ enableDashboard: true,
15
+ largePayloadThreshold: 1024 * 1024, // 1MB
16
+ logger: console.log,
17
+ };
18
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/types.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,wCAAwC;AACxC,gEAAgE;AA0JhE,MAAM,CAAC,MAAM,cAAc,GAA6B;IACpD,OAAO,EAAE,IAAI;IACb,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa;IAClD,aAAa,EAAE,GAAG;IAClB,kBAAkB,EAAE,GAAG;IACvB,cAAc,EAAE,KAAK;IACrB,YAAY,EAAE,CAAC;IACf,kBAAkB,EAAE,IAAI;IACxB,SAAS,EAAE,IAAI;IACf,cAAc,EAAE,IAAI;IACpB,eAAe,EAAE,IAAI;IACrB,qBAAqB,EAAE,IAAI,GAAG,IAAI,EAAE,MAAM;IAC1C,MAAM,EAAE,OAAO,CAAC,GAAG;CACtB,CAAC"}
@@ -0,0 +1,22 @@
1
+ // ─────────────────────────────────────────────────────────────
2
+ // flow-debugger — Main Entry Point
3
+ // ─────────────────────────────────────────────────────────────
4
+ // Core
5
+ export { TraceEngine, RequestTracer } from './core/TraceEngine';
6
+ export { classify, classifyTrace, classifyQuery } from './core/Classifier';
7
+ export { detectRootCause } from './core/RootCause';
8
+ export { Analytics } from './core/Analytics';
9
+ export { HealthMonitor } from './core/HealthMonitor';
10
+ export { Sampler } from './core/Sampler';
11
+ export { renderTimeline, renderCompact } from './core/Timeline';
12
+ export { DEFAULT_CONFIG } from './core/types';
13
+ // Integrations
14
+ export { mongoTracer, removeMongoTracer } from './integrations/mongo';
15
+ export { mysqlTracer } from './integrations/mysql';
16
+ export { pgTracer } from './integrations/postgres';
17
+ export { redisTracer } from './integrations/redis';
18
+ export { fetchTracer, removeFetchTracer } from './integrations/fetch';
19
+ export { axiosTracer } from './integrations/axios';
20
+ // Middleware
21
+ export { flowDebugger } from './middleware/express';
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,mCAAmC;AACnC,gEAAgE;AAEhE,OAAO;AACP,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAkBhE,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,aAAa;AACb,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,133 @@
1
+ // ─────────────────────────────────────────────────────────────
2
+ // flow-debugger — Axios Auto-Instrument
3
+ // Uses interceptors to trace all Axios requests
4
+ // ─────────────────────────────────────────────────────────────
5
+ import { DEFAULT_CONFIG } from '../core/types';
6
+ import { classifyQuery } from '../core/Classifier';
7
+ const DEFAULT_SERVICE_MAP = {
8
+ 'stripe.com': 'stripe',
9
+ 'api.stripe.com': 'stripe',
10
+ 'razorpay.com': 'razorpay',
11
+ 'api.razorpay.com': 'razorpay',
12
+ 'sendgrid.com': 'sendgrid',
13
+ 'api.sendgrid.com': 'sendgrid',
14
+ 'twilio.com': 'twilio',
15
+ 'api.twilio.com': 'twilio',
16
+ };
17
+ /**
18
+ * Auto-instrument Axios instance to trace all HTTP requests.
19
+ *
20
+ * Usage:
21
+ * axiosTracer(axios, { getTracer: () => currentTracer })
22
+ *
23
+ * Output:
24
+ * Axios POST https://api.stripe.com/v1/charges → 234ms ✔ [stripe]
25
+ * Axios GET https://api.razorpay.com/orders → 502 error ❌ [razorpay]
26
+ */
27
+ export function axiosTracer(axiosInstance, options) {
28
+ try {
29
+ if (axiosInstance.__flowDebuggerPatched)
30
+ return;
31
+ axiosInstance.__flowDebuggerPatched = true;
32
+ const config = { ...DEFAULT_CONFIG, ...options?.config };
33
+ const serviceMap = { ...DEFAULT_SERVICE_MAP, ...options?.serviceMap };
34
+ // Request interceptor — attach start time
35
+ axiosInstance.interceptors.request.use((reqConfig) => {
36
+ reqConfig.__flowDebuggerStartTime = performance.now();
37
+ return reqConfig;
38
+ }, (error) => Promise.reject(error));
39
+ // Response interceptor — record success
40
+ axiosInstance.interceptors.response.use((response) => {
41
+ const tracer = options?.getTracer?.();
42
+ if (!tracer)
43
+ return response;
44
+ const reqConfig = response.config;
45
+ const startTime = reqConfig.__flowDebuggerStartTime || performance.now();
46
+ const endTime = performance.now();
47
+ const duration = endTime - startTime;
48
+ const url = reqConfig.url || 'unknown';
49
+ const method = (reqConfig.method || 'GET').toUpperCase();
50
+ const service = getServiceFromUrl(url, serviceMap);
51
+ const stepName = `Axios ${method} ${getDomain(url)}`;
52
+ const classification = classifyQuery(duration, 'success', config);
53
+ tracer.addStep({
54
+ name: stepName,
55
+ service,
56
+ status: 'success',
57
+ classification,
58
+ startTime,
59
+ endTime,
60
+ duration,
61
+ metadata: { url, method, statusCode: response.status },
62
+ });
63
+ return response;
64
+ }, (error) => {
65
+ const tracer = options?.getTracer?.();
66
+ if (!tracer)
67
+ return Promise.reject(error);
68
+ const reqConfig = error.config || {};
69
+ const startTime = reqConfig.__flowDebuggerStartTime || performance.now();
70
+ const endTime = performance.now();
71
+ const duration = endTime - startTime;
72
+ const url = reqConfig.url || 'unknown';
73
+ const method = (reqConfig.method || 'GET').toUpperCase();
74
+ const service = getServiceFromUrl(url, serviceMap);
75
+ const stepName = `Axios ${method} ${getDomain(url)}`;
76
+ let status = 'error';
77
+ let errorMsg = error.message || 'Request failed';
78
+ // Detect timeouts
79
+ if (error.code === 'ECONNABORTED' || error.code === 'ETIMEDOUT' || errorMsg.includes('timeout')) {
80
+ status = 'timeout';
81
+ }
82
+ // HTTP error status
83
+ if (error.response) {
84
+ errorMsg = `HTTP ${error.response.status} ${error.response.statusText || ''}`;
85
+ }
86
+ const classification = classifyQuery(duration, status, config);
87
+ tracer.addStep({
88
+ name: stepName,
89
+ service,
90
+ status,
91
+ classification,
92
+ startTime,
93
+ endTime,
94
+ duration,
95
+ error: errorMsg,
96
+ stackTrace: error.stack,
97
+ metadata: { url, method, statusCode: error.response?.status },
98
+ });
99
+ return Promise.reject(error);
100
+ });
101
+ }
102
+ catch (_) {
103
+ // Production-safe: never crash
104
+ }
105
+ }
106
+ /** Extract service tag from URL */
107
+ function getServiceFromUrl(url, serviceMap) {
108
+ try {
109
+ const urlObj = new URL(url);
110
+ const hostname = urlObj.hostname;
111
+ if (serviceMap[hostname])
112
+ return serviceMap[hostname];
113
+ for (const [pattern, service] of Object.entries(serviceMap)) {
114
+ if (hostname.includes(pattern))
115
+ return service;
116
+ }
117
+ return 'axios';
118
+ }
119
+ catch {
120
+ return 'axios';
121
+ }
122
+ }
123
+ /** Extract domain from URL for display */
124
+ function getDomain(url) {
125
+ try {
126
+ const urlObj = new URL(url);
127
+ return urlObj.hostname + urlObj.pathname.substring(0, 30);
128
+ }
129
+ catch {
130
+ return url.substring(0, 50);
131
+ }
132
+ }
133
+ //# sourceMappingURL=axios.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"axios.js","sourceRoot":"","sources":["../../../src/integrations/axios.ts"],"names":[],"mappings":"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"}