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,111 @@
1
+ "use strict";
2
+ // ─────────────────────────────────────────────────────────────
3
+ // flow-debugger — MongoDB/Mongoose Auto-Instrument
4
+ // Patches Mongoose to automatically trace all DB queries
5
+ // ─────────────────────────────────────────────────────────────
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.mongoTracer = mongoTracer;
8
+ exports.removeMongoTracer = removeMongoTracer;
9
+ const types_1 = require("../core/types");
10
+ const Classifier_1 = require("../core/Classifier");
11
+ /**
12
+ * Auto-instrument Mongoose to trace all queries.
13
+ *
14
+ * Usage:
15
+ * mongoTracer(mongoose, { getTracer: () => currentTracer })
16
+ *
17
+ * Output:
18
+ * Mongo users.findOne → 22ms ✔
19
+ * Mongo payments.insertMany → error ❌
20
+ */
21
+ function mongoTracer(mongoose, options) {
22
+ try {
23
+ const config = { ...types_1.DEFAULT_CONFIG, ...options?.config };
24
+ const queryProto = mongoose.Query?.prototype;
25
+ if (!queryProto || queryProto.__flowDebuggerPatched)
26
+ return;
27
+ queryProto.__flowDebuggerPatched = true;
28
+ const originalExec = queryProto.exec;
29
+ queryProto.exec = async function (...args) {
30
+ const tracer = options?.getTracer?.();
31
+ if (!tracer) {
32
+ return originalExec.apply(this, args);
33
+ }
34
+ const op = this.op || 'query';
35
+ const collection = this.mongooseCollection?.name || this.model?.collection?.name || 'unknown';
36
+ const stepName = `Mongo ${collection}.${op}`;
37
+ const startTime = performance.now();
38
+ let status = 'success';
39
+ let error;
40
+ let stackTrace;
41
+ let result;
42
+ try {
43
+ result = await originalExec.apply(this, args);
44
+ }
45
+ catch (err) {
46
+ status = 'error';
47
+ const e = err instanceof Error ? err : new Error(String(err));
48
+ error = e.message;
49
+ stackTrace = e.stack;
50
+ // Record step before re-throwing
51
+ const endTime = performance.now();
52
+ const duration = endTime - startTime;
53
+ const classification = (0, Classifier_1.classifyQuery)(duration, status, config);
54
+ const step = {
55
+ name: stepName,
56
+ service: 'mongo',
57
+ status,
58
+ classification,
59
+ startTime: startTime,
60
+ endTime,
61
+ duration,
62
+ error,
63
+ stackTrace,
64
+ metadata: { operation: op, collection },
65
+ };
66
+ tracer.addStep(step);
67
+ throw err;
68
+ }
69
+ const endTime = performance.now();
70
+ const duration = endTime - startTime;
71
+ const classification = (0, Classifier_1.classifyQuery)(duration, status, config);
72
+ const step = {
73
+ name: stepName,
74
+ service: 'mongo',
75
+ status,
76
+ classification,
77
+ startTime: startTime,
78
+ endTime,
79
+ duration,
80
+ error,
81
+ stackTrace,
82
+ metadata: { operation: op, collection },
83
+ };
84
+ tracer.addStep(step);
85
+ // Log slow query warning
86
+ if (duration > (config.slowQueryThreshold ?? 300)) {
87
+ try {
88
+ (config.logger || console.log)(`\x1b[33m⚠ Slow MongoDB query: ${stepName} (${Math.round(duration)}ms)\x1b[0m`);
89
+ }
90
+ catch (_) { }
91
+ }
92
+ return result;
93
+ };
94
+ }
95
+ catch (_) {
96
+ // Production-safe: never crash the app
97
+ }
98
+ }
99
+ /**
100
+ * Remove the monkey-patch from Mongoose (for testing/cleanup).
101
+ */
102
+ function removeMongoTracer(mongoose) {
103
+ try {
104
+ const queryProto = mongoose.Query?.prototype;
105
+ if (queryProto) {
106
+ delete queryProto.__flowDebuggerPatched;
107
+ }
108
+ }
109
+ catch (_) { }
110
+ }
111
+ //# sourceMappingURL=mongo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mongo.js","sourceRoot":"","sources":["../../../src/integrations/mongo.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,212 @@
1
+ "use strict";
2
+ // ─────────────────────────────────────────────────────────────
3
+ // flow-debugger — MySQL Auto-Instrument (mysql2)
4
+ // Patches mysql2 pool to trace all queries
5
+ // ─────────────────────────────────────────────────────────────
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.mysqlTracer = mysqlTracer;
8
+ const types_1 = require("../core/types");
9
+ const Classifier_1 = require("../core/Classifier");
10
+ /**
11
+ * Auto-instrument mysql2 pool to trace all queries.
12
+ *
13
+ * Usage:
14
+ * mysqlTracer(pool, { getTracer: () => currentTracer })
15
+ *
16
+ * Output:
17
+ * MySQL SELECT users → 12ms ✔
18
+ * MySQL INSERT payments → error ❌
19
+ */
20
+ function mysqlTracer(pool, options) {
21
+ try {
22
+ if (pool.__flowDebuggerPatched)
23
+ return;
24
+ pool.__flowDebuggerPatched = true;
25
+ const config = { ...types_1.DEFAULT_CONFIG, ...options?.config };
26
+ // Patch pool.query
27
+ const originalQuery = pool.query.bind(pool);
28
+ pool.query = function tracedQuery(...args) {
29
+ const tracer = options?.getTracer?.();
30
+ if (!tracer) {
31
+ return originalQuery(...args);
32
+ }
33
+ const sql = typeof args[0] === 'string' ? args[0] : args[0]?.sql || 'unknown';
34
+ const operation = extractSqlOperation(sql);
35
+ const stepName = `MySQL ${operation}`;
36
+ const startTime = performance.now();
37
+ // Check if using callback or promise style
38
+ const lastArg = args[args.length - 1];
39
+ if (typeof lastArg === 'function') {
40
+ // Callback style
41
+ const callback = lastArg;
42
+ args[args.length - 1] = function (err, results, fields) {
43
+ const endTime = performance.now();
44
+ const duration = endTime - startTime;
45
+ const status = err ? 'error' : 'success';
46
+ const classification = (0, Classifier_1.classifyQuery)(duration, status, config);
47
+ const step = {
48
+ name: stepName,
49
+ service: 'mysql',
50
+ status,
51
+ classification,
52
+ startTime,
53
+ endTime,
54
+ duration,
55
+ error: err?.message,
56
+ stackTrace: err?.stack,
57
+ metadata: { sql: sql.substring(0, 200), operation },
58
+ };
59
+ tracer.addStep(step);
60
+ if (duration > (config.slowQueryThreshold ?? 300)) {
61
+ try {
62
+ (config.logger || console.log)(`\x1b[33m⚠ Slow MySQL query: ${stepName} (${Math.round(duration)}ms)\n ${sql.substring(0, 100)}\x1b[0m`);
63
+ }
64
+ catch (_) { }
65
+ }
66
+ callback(err, results, fields);
67
+ };
68
+ return originalQuery(...args);
69
+ }
70
+ else {
71
+ // Promise style
72
+ const promise = originalQuery(...args);
73
+ if (promise && typeof promise.then === 'function') {
74
+ return promise.then((result) => {
75
+ const endTime = performance.now();
76
+ const duration = endTime - startTime;
77
+ const classification = (0, Classifier_1.classifyQuery)(duration, 'success', config);
78
+ const step = {
79
+ name: stepName,
80
+ service: 'mysql',
81
+ status: 'success',
82
+ classification,
83
+ startTime,
84
+ endTime,
85
+ duration,
86
+ metadata: { sql: sql.substring(0, 200), operation },
87
+ };
88
+ tracer.addStep(step);
89
+ if (duration > (config.slowQueryThreshold ?? 300)) {
90
+ try {
91
+ (config.logger || console.log)(`\x1b[33m⚠ Slow MySQL query: ${stepName} (${Math.round(duration)}ms)\n ${sql.substring(0, 100)}\x1b[0m`);
92
+ }
93
+ catch (_) { }
94
+ }
95
+ return result;
96
+ }, (err) => {
97
+ const endTime = performance.now();
98
+ const duration = endTime - startTime;
99
+ const classification = (0, Classifier_1.classifyQuery)(duration, 'error', config);
100
+ const step = {
101
+ name: stepName,
102
+ service: 'mysql',
103
+ status: 'error',
104
+ classification,
105
+ startTime,
106
+ endTime,
107
+ duration,
108
+ error: err?.message,
109
+ stackTrace: err?.stack,
110
+ metadata: { sql: sql.substring(0, 200), operation },
111
+ };
112
+ tracer.addStep(step);
113
+ throw err;
114
+ });
115
+ }
116
+ return promise;
117
+ }
118
+ };
119
+ // Patch pool.execute (mysql2 specific)
120
+ if (pool.execute) {
121
+ const originalExecute = pool.execute.bind(pool);
122
+ pool.execute = function tracedExecute(...args) {
123
+ const tracer = options?.getTracer?.();
124
+ if (!tracer) {
125
+ return originalExecute(...args);
126
+ }
127
+ const sql = typeof args[0] === 'string' ? args[0] : args[0]?.sql || 'unknown';
128
+ const operation = extractSqlOperation(sql);
129
+ const stepName = `MySQL ${operation}`;
130
+ const startTime = performance.now();
131
+ const lastArg = args[args.length - 1];
132
+ if (typeof lastArg === 'function') {
133
+ const callback = lastArg;
134
+ args[args.length - 1] = function (err, results, fields) {
135
+ const endTime = performance.now();
136
+ const duration = endTime - startTime;
137
+ const status = err ? 'error' : 'success';
138
+ const classification = (0, Classifier_1.classifyQuery)(duration, status, config);
139
+ tracer.addStep({
140
+ name: stepName,
141
+ service: 'mysql',
142
+ status,
143
+ classification,
144
+ startTime,
145
+ endTime,
146
+ duration,
147
+ error: err?.message,
148
+ stackTrace: err?.stack,
149
+ metadata: { sql: sql.substring(0, 200), operation },
150
+ });
151
+ callback(err, results, fields);
152
+ };
153
+ return originalExecute(...args);
154
+ }
155
+ else {
156
+ const promise = originalExecute(...args);
157
+ if (promise && typeof promise.then === 'function') {
158
+ return promise.then((result) => {
159
+ const endTime = performance.now();
160
+ const duration = endTime - startTime;
161
+ tracer.addStep({
162
+ name: stepName,
163
+ service: 'mysql',
164
+ status: 'success',
165
+ classification: (0, Classifier_1.classifyQuery)(duration, 'success', config),
166
+ startTime,
167
+ endTime,
168
+ duration,
169
+ metadata: { sql: sql.substring(0, 200), operation },
170
+ });
171
+ return result;
172
+ }, (err) => {
173
+ const endTime = performance.now();
174
+ const duration = endTime - startTime;
175
+ tracer.addStep({
176
+ name: stepName,
177
+ service: 'mysql',
178
+ status: 'error',
179
+ classification: (0, Classifier_1.classifyQuery)(duration, 'error', config),
180
+ startTime,
181
+ endTime,
182
+ duration,
183
+ error: err?.message,
184
+ stackTrace: err?.stack,
185
+ metadata: { sql: sql.substring(0, 200), operation },
186
+ });
187
+ throw err;
188
+ });
189
+ }
190
+ return promise;
191
+ }
192
+ };
193
+ }
194
+ }
195
+ catch (_) {
196
+ // Production-safe: never crash
197
+ }
198
+ }
199
+ /** Extract the SQL operation type from a query string */
200
+ function extractSqlOperation(sql) {
201
+ const trimmed = sql.trim().toUpperCase();
202
+ const match = trimmed.match(/^(SELECT|INSERT|UPDATE|DELETE|CREATE|ALTER|DROP|TRUNCATE|REPLACE|CALL)\b/);
203
+ if (match) {
204
+ const op = match[1];
205
+ // Try to extract table name
206
+ const tableMatch = sql.match(/(?:FROM|INTO|UPDATE|TABLE|JOIN)\s+[`"]?(\w+)[`"]?/i);
207
+ const table = tableMatch ? tableMatch[1] : '';
208
+ return table ? `${op} ${table}` : op;
209
+ }
210
+ return sql.substring(0, 30);
211
+ }
212
+ //# sourceMappingURL=mysql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mysql.js","sourceRoot":"","sources":["../../../src/integrations/mysql.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,182 @@
1
+ "use strict";
2
+ // ─────────────────────────────────────────────────────────────
3
+ // flow-debugger — PostgreSQL Auto-Instrument (pg)
4
+ // Patches pg Pool/Client to trace all queries
5
+ // ─────────────────────────────────────────────────────────────
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.pgTracer = pgTracer;
8
+ const types_1 = require("../core/types");
9
+ const Classifier_1 = require("../core/Classifier");
10
+ /**
11
+ * Auto-instrument pg Pool/Client to trace all queries.
12
+ *
13
+ * Usage:
14
+ * pgTracer(pool, { getTracer: () => currentTracer })
15
+ *
16
+ * Output:
17
+ * Postgres SELECT orders → 18ms ✔
18
+ * Postgres UPDATE invoice → timeout ❌
19
+ */
20
+ function pgTracer(pool, options) {
21
+ try {
22
+ if (pool.__flowDebuggerPatched)
23
+ return;
24
+ pool.__flowDebuggerPatched = true;
25
+ const config = { ...types_1.DEFAULT_CONFIG, ...options?.config };
26
+ const originalQuery = pool.query.bind(pool);
27
+ pool.query = function tracedQuery(...args) {
28
+ const tracer = options?.getTracer?.();
29
+ if (!tracer) {
30
+ return originalQuery(...args);
31
+ }
32
+ const sql = extractSql(args);
33
+ const operation = extractPgOperation(sql);
34
+ const stepName = `Postgres ${operation}`;
35
+ const startTime = performance.now();
36
+ // Detect if callback is provided
37
+ const lastArg = args[args.length - 1];
38
+ if (typeof lastArg === 'function') {
39
+ // Callback style
40
+ const callback = lastArg;
41
+ args[args.length - 1] = function (err, result) {
42
+ recordStep(tracer, stepName, startTime, err, sql, operation, config);
43
+ callback(err, result);
44
+ };
45
+ return originalQuery(...args);
46
+ }
47
+ // Promise style
48
+ const promise = originalQuery(...args);
49
+ if (promise && typeof promise.then === 'function') {
50
+ return promise.then((result) => {
51
+ recordStep(tracer, stepName, startTime, null, sql, operation, config);
52
+ return result;
53
+ }, (err) => {
54
+ recordStep(tracer, stepName, startTime, err, sql, operation, config);
55
+ throw err;
56
+ });
57
+ }
58
+ return promise;
59
+ };
60
+ // Also patch connect() to instrument clients from the pool
61
+ if (pool.connect && !pool.__connectPatched) {
62
+ pool.__connectPatched = true;
63
+ const originalConnect = pool.connect.bind(pool);
64
+ pool.connect = function tracedConnect(...connectArgs) {
65
+ const lastArg = connectArgs[connectArgs.length - 1];
66
+ if (typeof lastArg === 'function') {
67
+ // Callback style: connect((err, client, done) => { ... })
68
+ const callback = lastArg;
69
+ connectArgs[connectArgs.length - 1] = function (err, client, done) {
70
+ if (client && !client.__flowDebuggerPatched) {
71
+ patchClient(client, options, config);
72
+ }
73
+ callback(err, client, done);
74
+ };
75
+ return originalConnect(...connectArgs);
76
+ }
77
+ // Promise style
78
+ const promise = originalConnect(...connectArgs);
79
+ if (promise && typeof promise.then === 'function') {
80
+ return promise.then((client) => {
81
+ if (client && !client.__flowDebuggerPatched) {
82
+ patchClient(client, options, config);
83
+ }
84
+ return client;
85
+ });
86
+ }
87
+ return promise;
88
+ };
89
+ }
90
+ }
91
+ catch (_) {
92
+ // Production-safe: never crash
93
+ }
94
+ }
95
+ /** Patch an individual pg Client's query method */
96
+ function patchClient(client, options, config) {
97
+ try {
98
+ client.__flowDebuggerPatched = true;
99
+ const originalClientQuery = client.query.bind(client);
100
+ client.query = function tracedClientQuery(...args) {
101
+ const tracer = options?.getTracer?.();
102
+ if (!tracer) {
103
+ return originalClientQuery(...args);
104
+ }
105
+ const sql = extractSql(args);
106
+ const operation = extractPgOperation(sql);
107
+ const stepName = `Postgres ${operation}`;
108
+ const startTime = performance.now();
109
+ const lastArg = args[args.length - 1];
110
+ if (typeof lastArg === 'function') {
111
+ const callback = lastArg;
112
+ args[args.length - 1] = function (err, result) {
113
+ recordStep(tracer, stepName, startTime, err, sql, operation, config);
114
+ callback(err, result);
115
+ };
116
+ return originalClientQuery(...args);
117
+ }
118
+ const promise = originalClientQuery(...args);
119
+ if (promise && typeof promise.then === 'function') {
120
+ return promise.then((result) => {
121
+ recordStep(tracer, stepName, startTime, null, sql, operation, config);
122
+ return result;
123
+ }, (err) => {
124
+ recordStep(tracer, stepName, startTime, err, sql, operation, config);
125
+ throw err;
126
+ });
127
+ }
128
+ return promise;
129
+ };
130
+ }
131
+ catch (_) { }
132
+ }
133
+ /** Record a step from query execution */
134
+ function recordStep(tracer, stepName, startTime, err, sql, operation, config) {
135
+ try {
136
+ const endTime = performance.now();
137
+ const duration = endTime - startTime;
138
+ const status = err ? 'error' : 'success';
139
+ const classification = (0, Classifier_1.classifyQuery)(duration, status, config);
140
+ const step = {
141
+ name: stepName,
142
+ service: 'postgres',
143
+ status,
144
+ classification,
145
+ startTime,
146
+ endTime,
147
+ duration,
148
+ error: err?.message,
149
+ stackTrace: err?.stack,
150
+ metadata: { sql: sql.substring(0, 200), operation },
151
+ };
152
+ tracer.addStep(step);
153
+ if (duration > (config.slowQueryThreshold ?? 300)) {
154
+ try {
155
+ (config.logger || console.log)(`\x1b[33m⚠ Slow PostgreSQL query: ${stepName} (${Math.round(duration)}ms)\n ${sql.substring(0, 100)}\x1b[0m`);
156
+ }
157
+ catch (_) { }
158
+ }
159
+ }
160
+ catch (_) { }
161
+ }
162
+ /** Extract SQL string from query arguments */
163
+ function extractSql(args) {
164
+ if (typeof args[0] === 'string')
165
+ return args[0];
166
+ if (args[0] && typeof args[0] === 'object' && args[0].text)
167
+ return args[0].text;
168
+ return 'unknown';
169
+ }
170
+ /** Extract the SQL operation type from a query string */
171
+ function extractPgOperation(sql) {
172
+ const trimmed = sql.trim().toUpperCase();
173
+ const match = trimmed.match(/^(SELECT|INSERT|UPDATE|DELETE|CREATE|ALTER|DROP|TRUNCATE|WITH)\b/);
174
+ if (match) {
175
+ const op = match[1];
176
+ const tableMatch = sql.match(/(?:FROM|INTO|UPDATE|TABLE|JOIN)\s+"?(\w+)"?/i);
177
+ const table = tableMatch ? tableMatch[1] : '';
178
+ return table ? `${op} ${table}` : op;
179
+ }
180
+ return sql.substring(0, 30);
181
+ }
182
+ //# sourceMappingURL=postgres.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../../src/integrations/postgres.ts"],"names":[],"mappings":";AAAA,gEAAgE;AAChE,kDAAkD;AAClD,8CAA8C;AAC9C,gEAAgE;;AAuBhE,4BAoFC;AAxGD,yCAAsF;AACtF,mDAAmD;AASnD;;;;;;;;;GASG;AACH,SAAgB,QAAQ,CAAC,IAAa,EAAE,OAAyB;IAC7D,IAAI,CAAC;QACD,IAAI,IAAI,CAAC,qBAAqB;YAAE,OAAO;QACvC,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;QAElC,MAAM,MAAM,GAAG,EAAE,GAAG,sBAAc,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,CAAC;QACzD,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE5C,IAAI,CAAC,KAAK,GAAG,SAAS,WAAW,CAAC,GAAG,IAAW;YAC5C,MAAM,MAAM,GAAG,OAAO,EAAE,SAAS,EAAE,EAAE,CAAC;YACtC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACV,OAAO,aAAa,CAAC,GAAG,IAAI,CAAC,CAAC;YAClC,CAAC;YAED,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;YAC7B,MAAM,SAAS,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;YAC1C,MAAM,QAAQ,GAAG,YAAY,SAAS,EAAE,CAAC;YACzC,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAEpC,iCAAiC;YACjC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACtC,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;gBAChC,iBAAiB;gBACjB,MAAM,QAAQ,GAAG,OAAO,CAAC;gBACzB,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,UAAU,GAAQ,EAAE,MAAW;oBACnD,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;oBACrE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;gBAC1B,CAAC,CAAC;gBACF,OAAO,aAAa,CAAC,GAAG,IAAI,CAAC,CAAC;YAClC,CAAC;YAED,gBAAgB;YAChB,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,IAAI,CAAC,CAAC;YACvC,IAAI,OAAO,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAChD,OAAO,OAAO,CAAC,IAAI,CACf,CAAC,MAAW,EAAE,EAAE;oBACZ,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;oBACtE,OAAO,MAAM,CAAC;gBAClB,CAAC,EACD,CAAC,GAAQ,EAAE,EAAE;oBACT,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;oBACrE,MAAM,GAAG,CAAC;gBACd,CAAC,CACJ,CAAC;YACN,CAAC;YACD,OAAO,OAAO,CAAC;QACnB,CAAC,CAAC;QAEF,2DAA2D;QAC3D,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACzC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAC7B,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEhD,IAAI,CAAC,OAAO,GAAG,SAAS,aAAa,CAAC,GAAG,WAAkB;gBACvD,MAAM,OAAO,GAAG,WAAW,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAEpD,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;oBAChC,0DAA0D;oBAC1D,MAAM,QAAQ,GAAG,OAAO,CAAC;oBACzB,WAAW,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,UAAU,GAAQ,EAAE,MAAW,EAAE,IAAS;wBAC5E,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC;4BAC1C,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;wBACzC,CAAC;wBACD,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;oBAChC,CAAC,CAAC;oBACF,OAAO,eAAe,CAAC,GAAG,WAAW,CAAC,CAAC;gBAC3C,CAAC;gBAED,gBAAgB;gBAChB,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,WAAW,CAAC,CAAC;gBAChD,IAAI,OAAO,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;oBAChD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,MAAW,EAAE,EAAE;wBAChC,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC;4BAC1C,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;wBACzC,CAAC;wBACD,OAAO,MAAM,CAAC;oBAClB,CAAC,CAAC,CAAC;gBACP,CAAC;gBACD,OAAO,OAAO,CAAC;YACnB,CAAC,CAAC;QACN,CAAC;IACL,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACT,+BAA+B;IACnC,CAAC;AACL,CAAC;AAED,mDAAmD;AACnD,SAAS,WAAW,CAAC,MAAW,EAAE,OAAoC,EAAE,MAAgC;IACpG,IAAI,CAAC;QACD,MAAM,CAAC,qBAAqB,GAAG,IAAI,CAAC;QACpC,MAAM,mBAAmB,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAEtD,MAAM,CAAC,KAAK,GAAG,SAAS,iBAAiB,CAAC,GAAG,IAAW;YACpD,MAAM,MAAM,GAAG,OAAO,EAAE,SAAS,EAAE,EAAE,CAAC;YACtC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACV,OAAO,mBAAmB,CAAC,GAAG,IAAI,CAAC,CAAC;YACxC,CAAC;YAED,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;YAC7B,MAAM,SAAS,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;YAC1C,MAAM,QAAQ,GAAG,YAAY,SAAS,EAAE,CAAC;YACzC,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAEpC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACtC,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;gBAChC,MAAM,QAAQ,GAAG,OAAO,CAAC;gBACzB,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,UAAU,GAAQ,EAAE,MAAW;oBACnD,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;oBACrE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;gBAC1B,CAAC,CAAC;gBACF,OAAO,mBAAmB,CAAC,GAAG,IAAI,CAAC,CAAC;YACxC,CAAC;YAED,MAAM,OAAO,GAAG,mBAAmB,CAAC,GAAG,IAAI,CAAC,CAAC;YAC7C,IAAI,OAAO,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAChD,OAAO,OAAO,CAAC,IAAI,CACf,CAAC,MAAW,EAAE,EAAE;oBACZ,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;oBACtE,OAAO,MAAM,CAAC;gBAClB,CAAC,EACD,CAAC,GAAQ,EAAE,EAAE;oBACT,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;oBACrE,MAAM,GAAG,CAAC;gBACd,CAAC,CACJ,CAAC;YACN,CAAC;YACD,OAAO,OAAO,CAAC;QACnB,CAAC,CAAC;IACN,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;AACnB,CAAC;AAED,yCAAyC;AACzC,SAAS,UAAU,CACf,MAAqB,EACrB,QAAgB,EAChB,SAAiB,EACjB,GAAQ,EACR,GAAW,EACX,SAAiB,EACjB,MAAgC;IAEhC,IAAI,CAAC;QACD,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;QACrC,MAAM,MAAM,GAAe,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;QACrD,MAAM,cAAc,GAAG,IAAA,0BAAa,EAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAE/D,MAAM,IAAI,GAAc;YACpB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,UAAU;YACnB,MAAM;YACN,cAAc;YACd,SAAS;YACT,OAAO;YACP,QAAQ;YACR,KAAK,EAAE,GAAG,EAAE,OAAO;YACnB,UAAU,EAAE,GAAG,EAAE,KAAK;YACtB,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE;SACtD,CAAC;QAEF,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAErB,IAAI,QAAQ,GAAG,CAAC,MAAM,CAAC,kBAAkB,IAAI,GAAG,CAAC,EAAE,CAAC;YAChD,IAAI,CAAC;gBACD,CAAC,MAAM,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,CAC1B,oCAAoC,QAAQ,KAAK,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAChH,CAAC;YACN,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QACnB,CAAC;IACL,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;AACnB,CAAC;AAED,8CAA8C;AAC9C,SAAS,UAAU,CAAC,IAAW;IAC3B,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;IAChD,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAChF,OAAO,SAAS,CAAC;AACrB,CAAC;AAED,yDAAyD;AACzD,SAAS,kBAAkB,CAAC,GAAW;IACnC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,kEAAkE,CAAC,CAAC;IAChG,IAAI,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACpB,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAC7E,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9C,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACzC,CAAC;IACD,OAAO,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ // ─────────────────────────────────────────────────────────────
3
+ // flow-debugger — Redis Auto-Instrument
4
+ // Wraps Redis client commands to trace all operations
5
+ // ─────────────────────────────────────────────────────────────
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.redisTracer = redisTracer;
8
+ const types_1 = require("../core/types");
9
+ const Classifier_1 = require("../core/Classifier");
10
+ /** Commands to trace */
11
+ const TRACED_COMMANDS = [
12
+ 'get', 'set', 'del', 'exists', 'expire', 'ttl',
13
+ 'hget', 'hset', 'hdel', 'hgetall', 'hmset', 'hmget',
14
+ 'lpush', 'rpush', 'lpop', 'rpop', 'lrange', 'llen',
15
+ 'sadd', 'srem', 'smembers', 'sismember',
16
+ 'zadd', 'zrem', 'zrange', 'zrank', 'zscore',
17
+ 'incr', 'decr', 'incrby', 'decrby',
18
+ 'setex', 'setnx', 'mget', 'mset',
19
+ 'publish', 'subscribe',
20
+ 'eval', 'evalsha',
21
+ ];
22
+ /**
23
+ * Auto-instrument a Redis client (ioredis or node-redis v4).
24
+ *
25
+ * Usage:
26
+ * redisTracer(redisClient, { getTracer: () => currentTracer })
27
+ *
28
+ * Output:
29
+ * Redis SET session → 3ms ✔
30
+ * Redis GET cache → timeout ❌
31
+ */
32
+ function redisTracer(client, options) {
33
+ try {
34
+ if (client.__flowDebuggerPatched)
35
+ return;
36
+ client.__flowDebuggerPatched = true;
37
+ const config = { ...types_1.DEFAULT_CONFIG, ...options?.config };
38
+ for (const command of TRACED_COMMANDS) {
39
+ if (typeof client[command] !== 'function')
40
+ continue;
41
+ const original = client[command].bind(client);
42
+ client[command] = async function tracedCommand(...args) {
43
+ const tracer = options?.getTracer?.();
44
+ if (!tracer) {
45
+ return original(...args);
46
+ }
47
+ const key = args[0] !== undefined ? String(args[0]).substring(0, 50) : '';
48
+ const stepName = `Redis ${command.toUpperCase()} ${key}`;
49
+ const startTime = performance.now();
50
+ let status = 'success';
51
+ let error;
52
+ let stackTrace;
53
+ try {
54
+ const result = await original(...args);
55
+ const endTime = performance.now();
56
+ const duration = endTime - startTime;
57
+ const classification = (0, Classifier_1.classifyQuery)(duration, status, config);
58
+ tracer.addStep({
59
+ name: stepName,
60
+ service: 'redis',
61
+ status,
62
+ classification,
63
+ startTime,
64
+ endTime,
65
+ duration,
66
+ metadata: { command: command.toUpperCase(), key },
67
+ });
68
+ return result;
69
+ }
70
+ catch (err) {
71
+ const e = err instanceof Error ? err : new Error(String(err));
72
+ error = e.message;
73
+ stackTrace = e.stack;
74
+ // Detect connection errors as CRITICAL
75
+ const isConnectionError = error.includes('ECONNREFUSED') ||
76
+ error.includes('ECONNRESET') ||
77
+ error.includes('ETIMEDOUT') ||
78
+ error.includes('connection') ||
79
+ error.includes('Connection');
80
+ status = isConnectionError ? 'timeout' : 'error';
81
+ const endTime = performance.now();
82
+ const duration = endTime - startTime;
83
+ const classification = (0, Classifier_1.classifyQuery)(duration, status, config);
84
+ tracer.addStep({
85
+ name: stepName,
86
+ service: 'redis',
87
+ status,
88
+ classification,
89
+ startTime,
90
+ endTime,
91
+ duration,
92
+ error,
93
+ stackTrace,
94
+ metadata: { command: command.toUpperCase(), key },
95
+ });
96
+ throw err;
97
+ }
98
+ };
99
+ }
100
+ }
101
+ catch (_) {
102
+ // Production-safe: never crash
103
+ }
104
+ }
105
+ //# sourceMappingURL=redis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis.js","sourceRoot":"","sources":["../../../src/integrations/redis.ts"],"names":[],"mappings":"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"}