@noego/ioc 0.2.0 → 0.2.2

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.
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
  var TraceLogger_exports = {};
30
20
  __export(TraceLogger_exports, {
@@ -43,214 +33,125 @@ __export(TraceLogger_exports, {
43
33
  resetDatabase: () => resetDatabase
44
34
  });
45
35
  module.exports = __toCommonJS(TraceLogger_exports);
46
- var import_better_sqlite3 = __toESM(require("better-sqlite3"), 1);
47
- var import_json_stringify_safe = __toESM(require("json-stringify-safe"), 1);
48
- let _db = null;
49
- function initializeDatabase() {
50
- if (_db) {
51
- return _db;
52
- }
53
- const db = new import_better_sqlite3.default(":memory:");
54
- db.exec(`
55
- CREATE TABLE IF NOT EXISTS proxy_registry (
56
- proxy_id INTEGER PRIMARY KEY,
57
- class_name TEXT NOT NULL,
58
- parent_proxy_id INTEGER,
59
- created_at DATETIME DEFAULT CURRENT_TIMESTAMP
60
- )
61
- `);
62
- db.exec(`
63
- CREATE TABLE IF NOT EXISTS traces (
64
- id INTEGER PRIMARY KEY AUTOINCREMENT,
65
- timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
66
- proxy_id INTEGER NOT NULL,
67
- parent_proxy_id INTEGER,
68
- class_name TEXT NOT NULL,
69
- method_name TEXT NOT NULL,
70
- parameters TEXT,
71
- return_value TEXT,
72
- error TEXT,
73
- duration_ms REAL
74
- )
75
- `);
76
- db.exec(`CREATE INDEX IF NOT EXISTS idx_proxy_id ON traces(proxy_id)`);
77
- db.exec(`CREATE INDEX IF NOT EXISTS idx_parent_proxy_id ON traces(parent_proxy_id)`);
78
- db.exec(`CREATE INDEX IF NOT EXISTS idx_timestamp ON traces(timestamp)`);
79
- _db = db;
80
- return db;
36
+ let _proxyRegistry = [];
37
+ let _traces = [];
38
+ let _nextTraceId = 1;
39
+ function now() {
40
+ return (/* @__PURE__ */ new Date()).toISOString();
41
+ }
42
+ function safeStringify(value) {
43
+ const seen = /* @__PURE__ */ new WeakSet();
44
+ return JSON.stringify(value, (_key, val) => {
45
+ if (val !== null && typeof val === "object") {
46
+ if (seen.has(val)) return "[Circular]";
47
+ seen.add(val);
48
+ }
49
+ return val;
50
+ });
81
51
  }
82
- function getDatabase() {
83
- if (!_db) {
84
- initializeDatabase();
52
+ function serializeError(err) {
53
+ if (!err) return null;
54
+ if (err instanceof Error) {
55
+ return { name: err.name, message: err.message, stack: err.stack };
85
56
  }
86
- return _db;
57
+ return { value: String(err) };
87
58
  }
88
59
  function registerProxy(proxyId, className, parentProxyId) {
89
- const db = getDatabase();
90
- const stmt = db.prepare(
91
- `INSERT OR IGNORE INTO proxy_registry (proxy_id, class_name, parent_proxy_id)
92
- VALUES (?, ?, ?)`
93
- );
94
- stmt.run(proxyId, className, parentProxyId || null);
60
+ if (_proxyRegistry.some((e) => e.proxy_id === proxyId)) return;
61
+ _proxyRegistry.push({
62
+ proxy_id: proxyId,
63
+ class_name: className,
64
+ parent_proxy_id: parentProxyId,
65
+ created_at: now()
66
+ });
95
67
  }
96
68
  function logMethodCall(event) {
97
- const db = getDatabase();
98
- const parametersJson = (0, import_json_stringify_safe.default)(event.parameters);
99
- const returnValueJson = event.returnValue !== void 0 ? (0, import_json_stringify_safe.default)(event.returnValue) : null;
100
- const errorJson = event.error ? JSON.stringify(serializeError(event.error)) : null;
101
- const stmt = db.prepare(
102
- `INSERT INTO traces (
103
- proxy_id,
104
- parent_proxy_id,
105
- class_name,
106
- method_name,
107
- parameters,
108
- return_value,
109
- error,
110
- duration_ms
111
- )
112
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
113
- );
114
- stmt.run(
115
- event.proxyId,
116
- event.parentProxyId || null,
117
- event.className,
118
- event.methodName,
119
- parametersJson,
120
- returnValueJson,
121
- errorJson,
122
- event.duration_ms
123
- );
124
- }
125
- function serializeError(err) {
126
- if (!err) return null;
127
- if (err instanceof Error) {
128
- return {
129
- name: err.name,
130
- message: err.message,
131
- stack: err.stack
132
- };
133
- }
134
- return {
135
- value: String(err)
136
- };
69
+ _traces.push({
70
+ id: _nextTraceId++,
71
+ timestamp: now(),
72
+ proxy_id: event.proxyId,
73
+ parent_proxy_id: event.parentProxyId,
74
+ class_name: event.className,
75
+ method_name: event.methodName,
76
+ parameters: safeStringify(event.parameters),
77
+ return_value: event.returnValue !== void 0 ? safeStringify(event.returnValue) : void 0,
78
+ error: event.error ? JSON.stringify(serializeError(event.error)) : void 0,
79
+ duration_ms: event.duration_ms
80
+ });
137
81
  }
138
82
  function getTracesByProxyId(proxyId) {
139
- const db = getDatabase();
140
- const stmt = db.prepare(
141
- `SELECT * FROM traces WHERE proxy_id = ? ORDER BY timestamp`
142
- );
143
- return stmt.all(proxyId);
83
+ return _traces.filter((t) => t.proxy_id === proxyId).sort((a, b) => a.timestamp.localeCompare(b.timestamp));
144
84
  }
145
85
  function getRecentTraces(retentionMinutes = 5) {
146
- const db = getDatabase();
147
- const stmt = db.prepare(
148
- `SELECT * FROM traces
149
- WHERE timestamp > datetime('now', '-' || ? || ' minutes')
150
- ORDER BY timestamp DESC`
151
- );
152
- return stmt.all(retentionMinutes);
86
+ const cutoff = new Date(Date.now() - retentionMinutes * 6e4).toISOString();
87
+ return _traces.filter((t) => t.timestamp > cutoff).sort((a, b) => b.timestamp.localeCompare(a.timestamp));
153
88
  }
154
89
  function getAllTraces() {
155
- const db = getDatabase();
156
- const stmt = db.prepare(`SELECT * FROM traces ORDER BY timestamp DESC`);
157
- return stmt.all();
90
+ return [..._traces].sort((a, b) => b.timestamp.localeCompare(a.timestamp));
158
91
  }
159
92
  function getInjectionHierarchy(proxyId) {
160
- const db = getDatabase();
161
- const stmt = db.prepare(`
162
- WITH RECURSIVE chain AS (
163
- SELECT proxy_id, parent_proxy_id, class_name, created_at, 1 as level
164
- FROM proxy_registry WHERE proxy_id = ?
165
-
166
- UNION ALL
167
-
168
- SELECT p.proxy_id, p.parent_proxy_id, p.class_name, p.created_at, c.level + 1
169
- FROM proxy_registry p
170
- INNER JOIN chain c ON p.proxy_id = c.parent_proxy_id
171
- )
172
- SELECT proxy_id, class_name, parent_proxy_id, created_at FROM chain ORDER BY level DESC
173
- `);
174
- return stmt.all(proxyId);
93
+ const result = [];
94
+ let current = _proxyRegistry.find((e) => e.proxy_id === proxyId);
95
+ while (current) {
96
+ result.unshift(current);
97
+ if (current.parent_proxy_id == null) break;
98
+ current = _proxyRegistry.find((e) => e.proxy_id === current.parent_proxy_id);
99
+ }
100
+ return result;
175
101
  }
176
102
  function getDependencies(proxyId) {
177
- const db = getDatabase();
178
- const stmt = db.prepare(`
179
- WITH RECURSIVE children AS (
180
- SELECT proxy_id, parent_proxy_id, class_name, created_at
181
- FROM proxy_registry WHERE proxy_id = ?
182
-
183
- UNION ALL
184
-
185
- SELECT p.proxy_id, p.parent_proxy_id, p.class_name, p.created_at
186
- FROM proxy_registry p
187
- INNER JOIN children c ON p.parent_proxy_id = c.proxy_id
188
- )
189
- SELECT proxy_id, class_name, parent_proxy_id, created_at FROM children
190
- `);
191
- return stmt.all(proxyId);
103
+ const result = [];
104
+ const queue = [proxyId];
105
+ const visited = /* @__PURE__ */ new Set();
106
+ while (queue.length > 0) {
107
+ const id = queue.shift();
108
+ if (visited.has(id)) continue;
109
+ visited.add(id);
110
+ const entry = _proxyRegistry.find((e) => e.proxy_id === id);
111
+ if (entry) result.push(entry);
112
+ for (const child of _proxyRegistry) {
113
+ if (child.parent_proxy_id === id && !visited.has(child.proxy_id)) {
114
+ queue.push(child.proxy_id);
115
+ }
116
+ }
117
+ }
118
+ return result;
192
119
  }
193
120
  function clearOldTraces(retentionMinutes = 5) {
194
- const db = getDatabase();
195
- const stmt = db.prepare(
196
- `DELETE FROM traces
197
- WHERE timestamp <= datetime('now', '-' || ? || ' minutes')`
198
- );
199
- const info = stmt.run(retentionMinutes);
200
- return info.changes;
121
+ const cutoff = new Date(Date.now() - retentionMinutes * 6e4).toISOString();
122
+ const before = _traces.length;
123
+ _traces = _traces.filter((t) => t.timestamp > cutoff);
124
+ return before - _traces.length;
201
125
  }
202
126
  function clearAllTraces() {
203
- const db = getDatabase();
204
- db.exec("DELETE FROM traces");
127
+ _traces = [];
205
128
  }
206
129
  function clearProxyRegistry() {
207
- const db = getDatabase();
208
- db.exec("DELETE FROM proxy_registry");
130
+ _proxyRegistry = [];
209
131
  }
210
132
  function resetDatabase() {
211
- if (_db) {
212
- _db.close();
213
- _db = null;
214
- }
133
+ _proxyRegistry = [];
134
+ _traces = [];
135
+ _nextTraceId = 1;
215
136
  }
216
137
  function exportTracesToJson() {
217
- const db = getDatabase();
218
- const proxyStmt = db.prepare("SELECT * FROM proxy_registry");
219
- const proxyRegistry = proxyStmt.all();
220
- const traceStmt = db.prepare("SELECT * FROM traces ORDER BY timestamp DESC");
221
- const traces = traceStmt.all();
222
138
  return {
223
- proxyRegistry,
224
- traces
139
+ proxyRegistry: [..._proxyRegistry],
140
+ traces: [..._traces].sort((a, b) => b.timestamp.localeCompare(a.timestamp))
225
141
  };
226
142
  }
227
143
  function getTraceStatistics() {
228
- const db = getDatabase();
229
- const countStmt = db.prepare("SELECT COUNT(*) as count FROM traces");
230
- const countResult = countStmt.get();
231
- const totalTraces = countResult.count;
232
- const proxiesStmt = db.prepare("SELECT COUNT(*) as count FROM proxy_registry");
233
- const proxiesResult = proxiesStmt.get();
234
- const totalProxies = proxiesResult.count;
235
- const classByStmt = db.prepare(
236
- "SELECT class_name, COUNT(*) as count FROM proxy_registry GROUP BY class_name"
237
- );
238
- const classRows = classByStmt.all();
239
144
  const proxiesByClass = {};
240
- for (const row of classRows) {
241
- proxiesByClass[row.class_name] = row.count;
145
+ for (const entry of _proxyRegistry) {
146
+ proxiesByClass[entry.class_name] = (proxiesByClass[entry.class_name] || 0) + 1;
242
147
  }
243
- const methodStmt = db.prepare(
244
- "SELECT proxy_id, COUNT(*) as count FROM traces GROUP BY proxy_id"
245
- );
246
- const methodRows = methodStmt.all();
247
148
  const methodCallsByProxy = {};
248
- for (const row of methodRows) {
249
- methodCallsByProxy[row.proxy_id] = row.count;
149
+ for (const trace of _traces) {
150
+ methodCallsByProxy[trace.proxy_id] = (methodCallsByProxy[trace.proxy_id] || 0) + 1;
250
151
  }
251
152
  return {
252
- totalTraces,
253
- totalProxies,
153
+ totalTraces: _traces.length,
154
+ totalProxies: _proxyRegistry.length,
254
155
  proxiesByClass,
255
156
  methodCallsByProxy
256
157
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../framework/implementation/TraceLogger.ts"],"sourcesContent":["import Database from 'better-sqlite3';\nimport stringify from 'json-stringify-safe';\nimport { TraceLogEvent } from './ProxyFactory.cjs';\n\nlet _db: Database.Database | null = null;\n\nexport interface ProxyRegistryEntry {\n proxy_id: number;\n class_name: string;\n parent_proxy_id?: number;\n created_at: string;\n}\n\nexport interface TraceRecord {\n id?: number;\n timestamp: string;\n proxy_id: number;\n parent_proxy_id?: number;\n class_name: string;\n method_name: string;\n parameters: string;\n return_value?: string;\n error?: string;\n duration_ms: number;\n}\n\n/**\n * Initialize the trace database with better-sqlite3\n */\nfunction initializeDatabase(): Database.Database {\n if (_db) {\n return _db;\n }\n\n // Create in-memory SQLite database\n const db = new Database(':memory:');\n\n // Create proxy_registry table\n db.exec(`\n CREATE TABLE IF NOT EXISTS proxy_registry (\n proxy_id INTEGER PRIMARY KEY,\n class_name TEXT NOT NULL,\n parent_proxy_id INTEGER,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Create traces table\n db.exec(`\n CREATE TABLE IF NOT EXISTS traces (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,\n proxy_id INTEGER NOT NULL,\n parent_proxy_id INTEGER,\n class_name TEXT NOT NULL,\n method_name TEXT NOT NULL,\n parameters TEXT,\n return_value TEXT,\n error TEXT,\n duration_ms REAL\n )\n `);\n\n // Create indexes\n db.exec(`CREATE INDEX IF NOT EXISTS idx_proxy_id ON traces(proxy_id)`);\n db.exec(`CREATE INDEX IF NOT EXISTS idx_parent_proxy_id ON traces(parent_proxy_id)`);\n db.exec(`CREATE INDEX IF NOT EXISTS idx_timestamp ON traces(timestamp)`);\n\n _db = db;\n return db;\n}\n\n/**\n * Get or initialize the database\n */\nfunction getDatabase(): Database.Database {\n if (!_db) {\n initializeDatabase();\n }\n\n return _db!;\n}\n\n/**\n * Register a proxy in the registry\n */\nexport function registerProxy(\n proxyId: number,\n className: string,\n parentProxyId?: number\n): void {\n const db = getDatabase();\n const stmt = db.prepare(\n `INSERT OR IGNORE INTO proxy_registry (proxy_id, class_name, parent_proxy_id)\n VALUES (?, ?, ?)`\n );\n stmt.run(proxyId, className, parentProxyId || null);\n}\n\n/**\n * Log a method call event\n */\nexport function logMethodCall(event: TraceLogEvent): void {\n const db = getDatabase();\n\n const parametersJson = stringify(event.parameters);\n const returnValueJson = event.returnValue !== undefined ? stringify(event.returnValue) : null;\n const errorJson = event.error ? JSON.stringify(serializeError(event.error)) : null;\n\n const stmt = db.prepare(\n `INSERT INTO traces (\n proxy_id,\n parent_proxy_id,\n class_name,\n method_name,\n parameters,\n return_value,\n error,\n duration_ms\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`\n );\n\n stmt.run(\n event.proxyId,\n event.parentProxyId || null,\n event.className,\n event.methodName,\n parametersJson,\n returnValueJson,\n errorJson,\n event.duration_ms\n );\n}\n\n/**\n * Serialize an error to a JSON-friendly format\n */\nfunction serializeError(err: any): any {\n if (!err) return null;\n\n if (err instanceof Error) {\n return {\n name: err.name,\n message: err.message,\n stack: err.stack\n };\n }\n\n return {\n value: String(err)\n };\n}\n\n/**\n * Get all traces for a specific proxy\n */\nexport function getTracesByProxyId(proxyId: number): TraceRecord[] {\n const db = getDatabase();\n const stmt = db.prepare(\n `SELECT * FROM traces WHERE proxy_id = ? ORDER BY timestamp`\n );\n\n return stmt.all(proxyId) as TraceRecord[];\n}\n\n/**\n * Get all recent traces within the retention window\n */\nexport function getRecentTraces(retentionMinutes: number = 5): TraceRecord[] {\n const db = getDatabase();\n const stmt = db.prepare(\n `SELECT * FROM traces\n WHERE timestamp > datetime('now', '-' || ? || ' minutes')\n ORDER BY timestamp DESC`\n );\n\n return stmt.all(retentionMinutes) as TraceRecord[];\n}\n\n/**\n * Get all traces\n */\nexport function getAllTraces(): TraceRecord[] {\n const db = getDatabase();\n const stmt = db.prepare(`SELECT * FROM traces ORDER BY timestamp DESC`);\n\n return stmt.all() as TraceRecord[];\n}\n\n/**\n * Get the injection hierarchy (parents) for a proxy\n */\nexport function getInjectionHierarchy(proxyId: number): ProxyRegistryEntry[] {\n const db = getDatabase();\n const stmt = db.prepare(`\n WITH RECURSIVE chain AS (\n SELECT proxy_id, parent_proxy_id, class_name, created_at, 1 as level\n FROM proxy_registry WHERE proxy_id = ?\n\n UNION ALL\n\n SELECT p.proxy_id, p.parent_proxy_id, p.class_name, p.created_at, c.level + 1\n FROM proxy_registry p\n INNER JOIN chain c ON p.proxy_id = c.parent_proxy_id\n )\n SELECT proxy_id, class_name, parent_proxy_id, created_at FROM chain ORDER BY level DESC\n `);\n\n return stmt.all(proxyId) as ProxyRegistryEntry[];\n}\n\n/**\n * Get all dependencies of a proxy (its children in the hierarchy)\n */\nexport function getDependencies(proxyId: number): ProxyRegistryEntry[] {\n const db = getDatabase();\n const stmt = db.prepare(`\n WITH RECURSIVE children AS (\n SELECT proxy_id, parent_proxy_id, class_name, created_at\n FROM proxy_registry WHERE proxy_id = ?\n\n UNION ALL\n\n SELECT p.proxy_id, p.parent_proxy_id, p.class_name, p.created_at\n FROM proxy_registry p\n INNER JOIN children c ON p.parent_proxy_id = c.proxy_id\n )\n SELECT proxy_id, class_name, parent_proxy_id, created_at FROM children\n `);\n\n return stmt.all(proxyId) as ProxyRegistryEntry[];\n}\n\n/**\n * Clear traces older than the retention window\n */\nexport function clearOldTraces(retentionMinutes: number = 5): number {\n const db = getDatabase();\n const stmt = db.prepare(\n `DELETE FROM traces\n WHERE timestamp <= datetime('now', '-' || ? || ' minutes')`\n );\n const info = stmt.run(retentionMinutes);\n return info.changes;\n}\n\n/**\n * Clear all traces\n */\nexport function clearAllTraces(): void {\n const db = getDatabase();\n db.exec('DELETE FROM traces');\n}\n\n/**\n * Clear the proxy registry\n */\nexport function clearProxyRegistry(): void {\n const db = getDatabase();\n db.exec('DELETE FROM proxy_registry');\n}\n\n/**\n * Reset the database completely\n */\nexport function resetDatabase(): void {\n if (_db) {\n _db.close();\n _db = null;\n }\n}\n\n/**\n * Export traces to JSON\n */\nexport function exportTracesToJson(): {\n proxyRegistry: ProxyRegistryEntry[];\n traces: TraceRecord[];\n} {\n const db = getDatabase();\n\n const proxyStmt = db.prepare('SELECT * FROM proxy_registry');\n const proxyRegistry = proxyStmt.all() as ProxyRegistryEntry[];\n\n const traceStmt = db.prepare('SELECT * FROM traces ORDER BY timestamp DESC');\n const traces = traceStmt.all() as TraceRecord[];\n\n return {\n proxyRegistry,\n traces\n };\n}\n\n/**\n * Get statistics about traces\n */\nexport function getTraceStatistics(): {\n totalTraces: number;\n totalProxies: number;\n proxiesByClass: Record<string, number>;\n methodCallsByProxy: Record<number, number>;\n} {\n const db = getDatabase();\n\n const countStmt = db.prepare('SELECT COUNT(*) as count FROM traces');\n const countResult = countStmt.get() as any;\n const totalTraces = countResult.count as number;\n\n const proxiesStmt = db.prepare('SELECT COUNT(*) as count FROM proxy_registry');\n const proxiesResult = proxiesStmt.get() as any;\n const totalProxies = proxiesResult.count as number;\n\n const classByStmt = db.prepare(\n 'SELECT class_name, COUNT(*) as count FROM proxy_registry GROUP BY class_name'\n );\n const classRows = classByStmt.all() as any[];\n const proxiesByClass: Record<string, number> = {};\n for (const row of classRows) {\n proxiesByClass[row.class_name] = row.count;\n }\n\n const methodStmt = db.prepare(\n 'SELECT proxy_id, COUNT(*) as count FROM traces GROUP BY proxy_id'\n );\n const methodRows = methodStmt.all() as any[];\n const methodCallsByProxy: Record<number, number> = {};\n for (const row of methodRows) {\n methodCallsByProxy[row.proxy_id] = row.count;\n }\n\n return {\n totalTraces,\n totalProxies,\n proxiesByClass,\n methodCallsByProxy\n };\n}\n"],"mappings":"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","names":["Database","stringify"]}
1
+ {"version":3,"sources":["../../../framework/implementation/TraceLogger.ts"],"sourcesContent":["import { TraceLogEvent } from './ProxyFactory.cjs';\n\nexport interface ProxyRegistryEntry {\n proxy_id: number;\n class_name: string;\n parent_proxy_id?: number;\n created_at: string;\n}\n\nexport interface TraceRecord {\n id?: number;\n timestamp: string;\n proxy_id: number;\n parent_proxy_id?: number;\n class_name: string;\n method_name: string;\n parameters: string;\n return_value?: string;\n error?: string;\n duration_ms: number;\n}\n\nlet _proxyRegistry: ProxyRegistryEntry[] = [];\nlet _traces: TraceRecord[] = [];\nlet _nextTraceId = 1;\n\nfunction now(): string {\n return new Date().toISOString();\n}\n\nfunction safeStringify(value: any): string {\n const seen = new WeakSet();\n return JSON.stringify(value, (_key, val) => {\n if (val !== null && typeof val === 'object') {\n if (seen.has(val)) return '[Circular]';\n seen.add(val);\n }\n return val;\n });\n}\n\nfunction serializeError(err: any): any {\n if (!err) return null;\n if (err instanceof Error) {\n return { name: err.name, message: err.message, stack: err.stack };\n }\n return { value: String(err) };\n}\n\n/**\n * Register a proxy in the registry\n */\nexport function registerProxy(\n proxyId: number,\n className: string,\n parentProxyId?: number\n): void {\n if (_proxyRegistry.some((e) => e.proxy_id === proxyId)) return;\n _proxyRegistry.push({\n proxy_id: proxyId,\n class_name: className,\n parent_proxy_id: parentProxyId,\n created_at: now(),\n });\n}\n\n/**\n * Log a method call event\n */\nexport function logMethodCall(event: TraceLogEvent): void {\n _traces.push({\n id: _nextTraceId++,\n timestamp: now(),\n proxy_id: event.proxyId,\n parent_proxy_id: event.parentProxyId,\n class_name: event.className,\n method_name: event.methodName,\n parameters: safeStringify(event.parameters),\n return_value: event.returnValue !== undefined ? safeStringify(event.returnValue) : undefined,\n error: event.error ? JSON.stringify(serializeError(event.error)) : undefined,\n duration_ms: event.duration_ms,\n });\n}\n\n/**\n * Get all traces for a specific proxy\n */\nexport function getTracesByProxyId(proxyId: number): TraceRecord[] {\n return _traces\n .filter((t) => t.proxy_id === proxyId)\n .sort((a, b) => a.timestamp.localeCompare(b.timestamp));\n}\n\n/**\n * Get all recent traces within the retention window\n */\nexport function getRecentTraces(retentionMinutes: number = 5): TraceRecord[] {\n const cutoff = new Date(Date.now() - retentionMinutes * 60_000).toISOString();\n return _traces\n .filter((t) => t.timestamp > cutoff)\n .sort((a, b) => b.timestamp.localeCompare(a.timestamp));\n}\n\n/**\n * Get all traces\n */\nexport function getAllTraces(): TraceRecord[] {\n return [..._traces].sort((a, b) => b.timestamp.localeCompare(a.timestamp));\n}\n\n/**\n * Get the injection hierarchy (parents) for a proxy\n */\nexport function getInjectionHierarchy(proxyId: number): ProxyRegistryEntry[] {\n const result: ProxyRegistryEntry[] = [];\n let current = _proxyRegistry.find((e) => e.proxy_id === proxyId);\n while (current) {\n result.unshift(current);\n if (current.parent_proxy_id == null) break;\n current = _proxyRegistry.find((e) => e.proxy_id === current!.parent_proxy_id);\n }\n return result;\n}\n\n/**\n * Get all dependencies of a proxy (its children in the hierarchy)\n */\nexport function getDependencies(proxyId: number): ProxyRegistryEntry[] {\n const result: ProxyRegistryEntry[] = [];\n const queue = [proxyId];\n const visited = new Set<number>();\n while (queue.length > 0) {\n const id = queue.shift()!;\n if (visited.has(id)) continue;\n visited.add(id);\n const entry = _proxyRegistry.find((e) => e.proxy_id === id);\n if (entry) result.push(entry);\n for (const child of _proxyRegistry) {\n if (child.parent_proxy_id === id && !visited.has(child.proxy_id)) {\n queue.push(child.proxy_id);\n }\n }\n }\n return result;\n}\n\n/**\n * Clear traces older than the retention window\n */\nexport function clearOldTraces(retentionMinutes: number = 5): number {\n const cutoff = new Date(Date.now() - retentionMinutes * 60_000).toISOString();\n const before = _traces.length;\n _traces = _traces.filter((t) => t.timestamp > cutoff);\n return before - _traces.length;\n}\n\n/**\n * Clear all traces\n */\nexport function clearAllTraces(): void {\n _traces = [];\n}\n\n/**\n * Clear the proxy registry\n */\nexport function clearProxyRegistry(): void {\n _proxyRegistry = [];\n}\n\n/**\n * Reset the database completely\n */\nexport function resetDatabase(): void {\n _proxyRegistry = [];\n _traces = [];\n _nextTraceId = 1;\n}\n\n/**\n * Export traces to JSON\n */\nexport function exportTracesToJson(): {\n proxyRegistry: ProxyRegistryEntry[];\n traces: TraceRecord[];\n} {\n return {\n proxyRegistry: [..._proxyRegistry],\n traces: [..._traces].sort((a, b) => b.timestamp.localeCompare(a.timestamp)),\n };\n}\n\n/**\n * Get statistics about traces\n */\nexport function getTraceStatistics(): {\n totalTraces: number;\n totalProxies: number;\n proxiesByClass: Record<string, number>;\n methodCallsByProxy: Record<number, number>;\n} {\n const proxiesByClass: Record<string, number> = {};\n for (const entry of _proxyRegistry) {\n proxiesByClass[entry.class_name] = (proxiesByClass[entry.class_name] || 0) + 1;\n }\n\n const methodCallsByProxy: Record<number, number> = {};\n for (const trace of _traces) {\n methodCallsByProxy[trace.proxy_id] = (methodCallsByProxy[trace.proxy_id] || 0) + 1;\n }\n\n return {\n totalTraces: _traces.length,\n totalProxies: _proxyRegistry.length,\n proxiesByClass,\n methodCallsByProxy,\n };\n}\n"],"mappings":"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","names":[]}
@@ -1,211 +1,122 @@
1
- import Database from "better-sqlite3";
2
- import stringify from "json-stringify-safe";
3
- let _db = null;
4
- function initializeDatabase() {
5
- if (_db) {
6
- return _db;
7
- }
8
- const db = new Database(":memory:");
9
- db.exec(`
10
- CREATE TABLE IF NOT EXISTS proxy_registry (
11
- proxy_id INTEGER PRIMARY KEY,
12
- class_name TEXT NOT NULL,
13
- parent_proxy_id INTEGER,
14
- created_at DATETIME DEFAULT CURRENT_TIMESTAMP
15
- )
16
- `);
17
- db.exec(`
18
- CREATE TABLE IF NOT EXISTS traces (
19
- id INTEGER PRIMARY KEY AUTOINCREMENT,
20
- timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
21
- proxy_id INTEGER NOT NULL,
22
- parent_proxy_id INTEGER,
23
- class_name TEXT NOT NULL,
24
- method_name TEXT NOT NULL,
25
- parameters TEXT,
26
- return_value TEXT,
27
- error TEXT,
28
- duration_ms REAL
29
- )
30
- `);
31
- db.exec(`CREATE INDEX IF NOT EXISTS idx_proxy_id ON traces(proxy_id)`);
32
- db.exec(`CREATE INDEX IF NOT EXISTS idx_parent_proxy_id ON traces(parent_proxy_id)`);
33
- db.exec(`CREATE INDEX IF NOT EXISTS idx_timestamp ON traces(timestamp)`);
34
- _db = db;
35
- return db;
36
- }
37
- function getDatabase() {
38
- if (!_db) {
39
- initializeDatabase();
40
- }
41
- return _db;
42
- }
43
- function registerProxy(proxyId, className, parentProxyId) {
44
- const db = getDatabase();
45
- const stmt = db.prepare(
46
- `INSERT OR IGNORE INTO proxy_registry (proxy_id, class_name, parent_proxy_id)
47
- VALUES (?, ?, ?)`
48
- );
49
- stmt.run(proxyId, className, parentProxyId || null);
50
- }
51
- function logMethodCall(event) {
52
- const db = getDatabase();
53
- const parametersJson = stringify(event.parameters);
54
- const returnValueJson = event.returnValue !== void 0 ? stringify(event.returnValue) : null;
55
- const errorJson = event.error ? JSON.stringify(serializeError(event.error)) : null;
56
- const stmt = db.prepare(
57
- `INSERT INTO traces (
58
- proxy_id,
59
- parent_proxy_id,
60
- class_name,
61
- method_name,
62
- parameters,
63
- return_value,
64
- error,
65
- duration_ms
66
- )
67
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
68
- );
69
- stmt.run(
70
- event.proxyId,
71
- event.parentProxyId || null,
72
- event.className,
73
- event.methodName,
74
- parametersJson,
75
- returnValueJson,
76
- errorJson,
77
- event.duration_ms
78
- );
1
+ let _proxyRegistry = [];
2
+ let _traces = [];
3
+ let _nextTraceId = 1;
4
+ function now() {
5
+ return (/* @__PURE__ */ new Date()).toISOString();
6
+ }
7
+ function safeStringify(value) {
8
+ const seen = /* @__PURE__ */ new WeakSet();
9
+ return JSON.stringify(value, (_key, val) => {
10
+ if (val !== null && typeof val === "object") {
11
+ if (seen.has(val)) return "[Circular]";
12
+ seen.add(val);
13
+ }
14
+ return val;
15
+ });
79
16
  }
80
17
  function serializeError(err) {
81
18
  if (!err) return null;
82
19
  if (err instanceof Error) {
83
- return {
84
- name: err.name,
85
- message: err.message,
86
- stack: err.stack
87
- };
20
+ return { name: err.name, message: err.message, stack: err.stack };
88
21
  }
89
- return {
90
- value: String(err)
91
- };
22
+ return { value: String(err) };
23
+ }
24
+ function registerProxy(proxyId, className, parentProxyId) {
25
+ if (_proxyRegistry.some((e) => e.proxy_id === proxyId)) return;
26
+ _proxyRegistry.push({
27
+ proxy_id: proxyId,
28
+ class_name: className,
29
+ parent_proxy_id: parentProxyId,
30
+ created_at: now()
31
+ });
32
+ }
33
+ function logMethodCall(event) {
34
+ _traces.push({
35
+ id: _nextTraceId++,
36
+ timestamp: now(),
37
+ proxy_id: event.proxyId,
38
+ parent_proxy_id: event.parentProxyId,
39
+ class_name: event.className,
40
+ method_name: event.methodName,
41
+ parameters: safeStringify(event.parameters),
42
+ return_value: event.returnValue !== void 0 ? safeStringify(event.returnValue) : void 0,
43
+ error: event.error ? JSON.stringify(serializeError(event.error)) : void 0,
44
+ duration_ms: event.duration_ms
45
+ });
92
46
  }
93
47
  function getTracesByProxyId(proxyId) {
94
- const db = getDatabase();
95
- const stmt = db.prepare(
96
- `SELECT * FROM traces WHERE proxy_id = ? ORDER BY timestamp`
97
- );
98
- return stmt.all(proxyId);
48
+ return _traces.filter((t) => t.proxy_id === proxyId).sort((a, b) => a.timestamp.localeCompare(b.timestamp));
99
49
  }
100
50
  function getRecentTraces(retentionMinutes = 5) {
101
- const db = getDatabase();
102
- const stmt = db.prepare(
103
- `SELECT * FROM traces
104
- WHERE timestamp > datetime('now', '-' || ? || ' minutes')
105
- ORDER BY timestamp DESC`
106
- );
107
- return stmt.all(retentionMinutes);
51
+ const cutoff = new Date(Date.now() - retentionMinutes * 6e4).toISOString();
52
+ return _traces.filter((t) => t.timestamp > cutoff).sort((a, b) => b.timestamp.localeCompare(a.timestamp));
108
53
  }
109
54
  function getAllTraces() {
110
- const db = getDatabase();
111
- const stmt = db.prepare(`SELECT * FROM traces ORDER BY timestamp DESC`);
112
- return stmt.all();
55
+ return [..._traces].sort((a, b) => b.timestamp.localeCompare(a.timestamp));
113
56
  }
114
57
  function getInjectionHierarchy(proxyId) {
115
- const db = getDatabase();
116
- const stmt = db.prepare(`
117
- WITH RECURSIVE chain AS (
118
- SELECT proxy_id, parent_proxy_id, class_name, created_at, 1 as level
119
- FROM proxy_registry WHERE proxy_id = ?
120
-
121
- UNION ALL
122
-
123
- SELECT p.proxy_id, p.parent_proxy_id, p.class_name, p.created_at, c.level + 1
124
- FROM proxy_registry p
125
- INNER JOIN chain c ON p.proxy_id = c.parent_proxy_id
126
- )
127
- SELECT proxy_id, class_name, parent_proxy_id, created_at FROM chain ORDER BY level DESC
128
- `);
129
- return stmt.all(proxyId);
58
+ const result = [];
59
+ let current = _proxyRegistry.find((e) => e.proxy_id === proxyId);
60
+ while (current) {
61
+ result.unshift(current);
62
+ if (current.parent_proxy_id == null) break;
63
+ current = _proxyRegistry.find((e) => e.proxy_id === current.parent_proxy_id);
64
+ }
65
+ return result;
130
66
  }
131
67
  function getDependencies(proxyId) {
132
- const db = getDatabase();
133
- const stmt = db.prepare(`
134
- WITH RECURSIVE children AS (
135
- SELECT proxy_id, parent_proxy_id, class_name, created_at
136
- FROM proxy_registry WHERE proxy_id = ?
137
-
138
- UNION ALL
139
-
140
- SELECT p.proxy_id, p.parent_proxy_id, p.class_name, p.created_at
141
- FROM proxy_registry p
142
- INNER JOIN children c ON p.parent_proxy_id = c.proxy_id
143
- )
144
- SELECT proxy_id, class_name, parent_proxy_id, created_at FROM children
145
- `);
146
- return stmt.all(proxyId);
68
+ const result = [];
69
+ const queue = [proxyId];
70
+ const visited = /* @__PURE__ */ new Set();
71
+ while (queue.length > 0) {
72
+ const id = queue.shift();
73
+ if (visited.has(id)) continue;
74
+ visited.add(id);
75
+ const entry = _proxyRegistry.find((e) => e.proxy_id === id);
76
+ if (entry) result.push(entry);
77
+ for (const child of _proxyRegistry) {
78
+ if (child.parent_proxy_id === id && !visited.has(child.proxy_id)) {
79
+ queue.push(child.proxy_id);
80
+ }
81
+ }
82
+ }
83
+ return result;
147
84
  }
148
85
  function clearOldTraces(retentionMinutes = 5) {
149
- const db = getDatabase();
150
- const stmt = db.prepare(
151
- `DELETE FROM traces
152
- WHERE timestamp <= datetime('now', '-' || ? || ' minutes')`
153
- );
154
- const info = stmt.run(retentionMinutes);
155
- return info.changes;
86
+ const cutoff = new Date(Date.now() - retentionMinutes * 6e4).toISOString();
87
+ const before = _traces.length;
88
+ _traces = _traces.filter((t) => t.timestamp > cutoff);
89
+ return before - _traces.length;
156
90
  }
157
91
  function clearAllTraces() {
158
- const db = getDatabase();
159
- db.exec("DELETE FROM traces");
92
+ _traces = [];
160
93
  }
161
94
  function clearProxyRegistry() {
162
- const db = getDatabase();
163
- db.exec("DELETE FROM proxy_registry");
95
+ _proxyRegistry = [];
164
96
  }
165
97
  function resetDatabase() {
166
- if (_db) {
167
- _db.close();
168
- _db = null;
169
- }
98
+ _proxyRegistry = [];
99
+ _traces = [];
100
+ _nextTraceId = 1;
170
101
  }
171
102
  function exportTracesToJson() {
172
- const db = getDatabase();
173
- const proxyStmt = db.prepare("SELECT * FROM proxy_registry");
174
- const proxyRegistry = proxyStmt.all();
175
- const traceStmt = db.prepare("SELECT * FROM traces ORDER BY timestamp DESC");
176
- const traces = traceStmt.all();
177
103
  return {
178
- proxyRegistry,
179
- traces
104
+ proxyRegistry: [..._proxyRegistry],
105
+ traces: [..._traces].sort((a, b) => b.timestamp.localeCompare(a.timestamp))
180
106
  };
181
107
  }
182
108
  function getTraceStatistics() {
183
- const db = getDatabase();
184
- const countStmt = db.prepare("SELECT COUNT(*) as count FROM traces");
185
- const countResult = countStmt.get();
186
- const totalTraces = countResult.count;
187
- const proxiesStmt = db.prepare("SELECT COUNT(*) as count FROM proxy_registry");
188
- const proxiesResult = proxiesStmt.get();
189
- const totalProxies = proxiesResult.count;
190
- const classByStmt = db.prepare(
191
- "SELECT class_name, COUNT(*) as count FROM proxy_registry GROUP BY class_name"
192
- );
193
- const classRows = classByStmt.all();
194
109
  const proxiesByClass = {};
195
- for (const row of classRows) {
196
- proxiesByClass[row.class_name] = row.count;
110
+ for (const entry of _proxyRegistry) {
111
+ proxiesByClass[entry.class_name] = (proxiesByClass[entry.class_name] || 0) + 1;
197
112
  }
198
- const methodStmt = db.prepare(
199
- "SELECT proxy_id, COUNT(*) as count FROM traces GROUP BY proxy_id"
200
- );
201
- const methodRows = methodStmt.all();
202
113
  const methodCallsByProxy = {};
203
- for (const row of methodRows) {
204
- methodCallsByProxy[row.proxy_id] = row.count;
114
+ for (const trace of _traces) {
115
+ methodCallsByProxy[trace.proxy_id] = (methodCallsByProxy[trace.proxy_id] || 0) + 1;
205
116
  }
206
117
  return {
207
- totalTraces,
208
- totalProxies,
118
+ totalTraces: _traces.length,
119
+ totalProxies: _proxyRegistry.length,
209
120
  proxiesByClass,
210
121
  methodCallsByProxy
211
122
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../framework/implementation/TraceLogger.ts"],"sourcesContent":["import Database from 'better-sqlite3';\nimport stringify from 'json-stringify-safe';\nimport { TraceLogEvent } from './ProxyFactory.js';\n\nlet _db: Database.Database | null = null;\n\nexport interface ProxyRegistryEntry {\n proxy_id: number;\n class_name: string;\n parent_proxy_id?: number;\n created_at: string;\n}\n\nexport interface TraceRecord {\n id?: number;\n timestamp: string;\n proxy_id: number;\n parent_proxy_id?: number;\n class_name: string;\n method_name: string;\n parameters: string;\n return_value?: string;\n error?: string;\n duration_ms: number;\n}\n\n/**\n * Initialize the trace database with better-sqlite3\n */\nfunction initializeDatabase(): Database.Database {\n if (_db) {\n return _db;\n }\n\n // Create in-memory SQLite database\n const db = new Database(':memory:');\n\n // Create proxy_registry table\n db.exec(`\n CREATE TABLE IF NOT EXISTS proxy_registry (\n proxy_id INTEGER PRIMARY KEY,\n class_name TEXT NOT NULL,\n parent_proxy_id INTEGER,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Create traces table\n db.exec(`\n CREATE TABLE IF NOT EXISTS traces (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,\n proxy_id INTEGER NOT NULL,\n parent_proxy_id INTEGER,\n class_name TEXT NOT NULL,\n method_name TEXT NOT NULL,\n parameters TEXT,\n return_value TEXT,\n error TEXT,\n duration_ms REAL\n )\n `);\n\n // Create indexes\n db.exec(`CREATE INDEX IF NOT EXISTS idx_proxy_id ON traces(proxy_id)`);\n db.exec(`CREATE INDEX IF NOT EXISTS idx_parent_proxy_id ON traces(parent_proxy_id)`);\n db.exec(`CREATE INDEX IF NOT EXISTS idx_timestamp ON traces(timestamp)`);\n\n _db = db;\n return db;\n}\n\n/**\n * Get or initialize the database\n */\nfunction getDatabase(): Database.Database {\n if (!_db) {\n initializeDatabase();\n }\n\n return _db!;\n}\n\n/**\n * Register a proxy in the registry\n */\nexport function registerProxy(\n proxyId: number,\n className: string,\n parentProxyId?: number\n): void {\n const db = getDatabase();\n const stmt = db.prepare(\n `INSERT OR IGNORE INTO proxy_registry (proxy_id, class_name, parent_proxy_id)\n VALUES (?, ?, ?)`\n );\n stmt.run(proxyId, className, parentProxyId || null);\n}\n\n/**\n * Log a method call event\n */\nexport function logMethodCall(event: TraceLogEvent): void {\n const db = getDatabase();\n\n const parametersJson = stringify(event.parameters);\n const returnValueJson = event.returnValue !== undefined ? stringify(event.returnValue) : null;\n const errorJson = event.error ? JSON.stringify(serializeError(event.error)) : null;\n\n const stmt = db.prepare(\n `INSERT INTO traces (\n proxy_id,\n parent_proxy_id,\n class_name,\n method_name,\n parameters,\n return_value,\n error,\n duration_ms\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`\n );\n\n stmt.run(\n event.proxyId,\n event.parentProxyId || null,\n event.className,\n event.methodName,\n parametersJson,\n returnValueJson,\n errorJson,\n event.duration_ms\n );\n}\n\n/**\n * Serialize an error to a JSON-friendly format\n */\nfunction serializeError(err: any): any {\n if (!err) return null;\n\n if (err instanceof Error) {\n return {\n name: err.name,\n message: err.message,\n stack: err.stack\n };\n }\n\n return {\n value: String(err)\n };\n}\n\n/**\n * Get all traces for a specific proxy\n */\nexport function getTracesByProxyId(proxyId: number): TraceRecord[] {\n const db = getDatabase();\n const stmt = db.prepare(\n `SELECT * FROM traces WHERE proxy_id = ? ORDER BY timestamp`\n );\n\n return stmt.all(proxyId) as TraceRecord[];\n}\n\n/**\n * Get all recent traces within the retention window\n */\nexport function getRecentTraces(retentionMinutes: number = 5): TraceRecord[] {\n const db = getDatabase();\n const stmt = db.prepare(\n `SELECT * FROM traces\n WHERE timestamp > datetime('now', '-' || ? || ' minutes')\n ORDER BY timestamp DESC`\n );\n\n return stmt.all(retentionMinutes) as TraceRecord[];\n}\n\n/**\n * Get all traces\n */\nexport function getAllTraces(): TraceRecord[] {\n const db = getDatabase();\n const stmt = db.prepare(`SELECT * FROM traces ORDER BY timestamp DESC`);\n\n return stmt.all() as TraceRecord[];\n}\n\n/**\n * Get the injection hierarchy (parents) for a proxy\n */\nexport function getInjectionHierarchy(proxyId: number): ProxyRegistryEntry[] {\n const db = getDatabase();\n const stmt = db.prepare(`\n WITH RECURSIVE chain AS (\n SELECT proxy_id, parent_proxy_id, class_name, created_at, 1 as level\n FROM proxy_registry WHERE proxy_id = ?\n\n UNION ALL\n\n SELECT p.proxy_id, p.parent_proxy_id, p.class_name, p.created_at, c.level + 1\n FROM proxy_registry p\n INNER JOIN chain c ON p.proxy_id = c.parent_proxy_id\n )\n SELECT proxy_id, class_name, parent_proxy_id, created_at FROM chain ORDER BY level DESC\n `);\n\n return stmt.all(proxyId) as ProxyRegistryEntry[];\n}\n\n/**\n * Get all dependencies of a proxy (its children in the hierarchy)\n */\nexport function getDependencies(proxyId: number): ProxyRegistryEntry[] {\n const db = getDatabase();\n const stmt = db.prepare(`\n WITH RECURSIVE children AS (\n SELECT proxy_id, parent_proxy_id, class_name, created_at\n FROM proxy_registry WHERE proxy_id = ?\n\n UNION ALL\n\n SELECT p.proxy_id, p.parent_proxy_id, p.class_name, p.created_at\n FROM proxy_registry p\n INNER JOIN children c ON p.parent_proxy_id = c.proxy_id\n )\n SELECT proxy_id, class_name, parent_proxy_id, created_at FROM children\n `);\n\n return stmt.all(proxyId) as ProxyRegistryEntry[];\n}\n\n/**\n * Clear traces older than the retention window\n */\nexport function clearOldTraces(retentionMinutes: number = 5): number {\n const db = getDatabase();\n const stmt = db.prepare(\n `DELETE FROM traces\n WHERE timestamp <= datetime('now', '-' || ? || ' minutes')`\n );\n const info = stmt.run(retentionMinutes);\n return info.changes;\n}\n\n/**\n * Clear all traces\n */\nexport function clearAllTraces(): void {\n const db = getDatabase();\n db.exec('DELETE FROM traces');\n}\n\n/**\n * Clear the proxy registry\n */\nexport function clearProxyRegistry(): void {\n const db = getDatabase();\n db.exec('DELETE FROM proxy_registry');\n}\n\n/**\n * Reset the database completely\n */\nexport function resetDatabase(): void {\n if (_db) {\n _db.close();\n _db = null;\n }\n}\n\n/**\n * Export traces to JSON\n */\nexport function exportTracesToJson(): {\n proxyRegistry: ProxyRegistryEntry[];\n traces: TraceRecord[];\n} {\n const db = getDatabase();\n\n const proxyStmt = db.prepare('SELECT * FROM proxy_registry');\n const proxyRegistry = proxyStmt.all() as ProxyRegistryEntry[];\n\n const traceStmt = db.prepare('SELECT * FROM traces ORDER BY timestamp DESC');\n const traces = traceStmt.all() as TraceRecord[];\n\n return {\n proxyRegistry,\n traces\n };\n}\n\n/**\n * Get statistics about traces\n */\nexport function getTraceStatistics(): {\n totalTraces: number;\n totalProxies: number;\n proxiesByClass: Record<string, number>;\n methodCallsByProxy: Record<number, number>;\n} {\n const db = getDatabase();\n\n const countStmt = db.prepare('SELECT COUNT(*) as count FROM traces');\n const countResult = countStmt.get() as any;\n const totalTraces = countResult.count as number;\n\n const proxiesStmt = db.prepare('SELECT COUNT(*) as count FROM proxy_registry');\n const proxiesResult = proxiesStmt.get() as any;\n const totalProxies = proxiesResult.count as number;\n\n const classByStmt = db.prepare(\n 'SELECT class_name, COUNT(*) as count FROM proxy_registry GROUP BY class_name'\n );\n const classRows = classByStmt.all() as any[];\n const proxiesByClass: Record<string, number> = {};\n for (const row of classRows) {\n proxiesByClass[row.class_name] = row.count;\n }\n\n const methodStmt = db.prepare(\n 'SELECT proxy_id, COUNT(*) as count FROM traces GROUP BY proxy_id'\n );\n const methodRows = methodStmt.all() as any[];\n const methodCallsByProxy: Record<number, number> = {};\n for (const row of methodRows) {\n methodCallsByProxy[row.proxy_id] = row.count;\n }\n\n return {\n totalTraces,\n totalProxies,\n proxiesByClass,\n methodCallsByProxy\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../framework/implementation/TraceLogger.ts"],"sourcesContent":["import { TraceLogEvent } from './ProxyFactory.js';\n\nexport interface ProxyRegistryEntry {\n proxy_id: number;\n class_name: string;\n parent_proxy_id?: number;\n created_at: string;\n}\n\nexport interface TraceRecord {\n id?: number;\n timestamp: string;\n proxy_id: number;\n parent_proxy_id?: number;\n class_name: string;\n method_name: string;\n parameters: string;\n return_value?: string;\n error?: string;\n duration_ms: number;\n}\n\nlet _proxyRegistry: ProxyRegistryEntry[] = [];\nlet _traces: TraceRecord[] = [];\nlet _nextTraceId = 1;\n\nfunction now(): string {\n return new Date().toISOString();\n}\n\nfunction safeStringify(value: any): string {\n const seen = new WeakSet();\n return JSON.stringify(value, (_key, val) => {\n if (val !== null && typeof val === 'object') {\n if (seen.has(val)) return '[Circular]';\n seen.add(val);\n }\n return val;\n });\n}\n\nfunction serializeError(err: any): any {\n if (!err) return null;\n if (err instanceof Error) {\n return { name: err.name, message: err.message, stack: err.stack };\n }\n return { value: String(err) };\n}\n\n/**\n * Register a proxy in the registry\n */\nexport function registerProxy(\n proxyId: number,\n className: string,\n parentProxyId?: number\n): void {\n if (_proxyRegistry.some((e) => e.proxy_id === proxyId)) return;\n _proxyRegistry.push({\n proxy_id: proxyId,\n class_name: className,\n parent_proxy_id: parentProxyId,\n created_at: now(),\n });\n}\n\n/**\n * Log a method call event\n */\nexport function logMethodCall(event: TraceLogEvent): void {\n _traces.push({\n id: _nextTraceId++,\n timestamp: now(),\n proxy_id: event.proxyId,\n parent_proxy_id: event.parentProxyId,\n class_name: event.className,\n method_name: event.methodName,\n parameters: safeStringify(event.parameters),\n return_value: event.returnValue !== undefined ? safeStringify(event.returnValue) : undefined,\n error: event.error ? JSON.stringify(serializeError(event.error)) : undefined,\n duration_ms: event.duration_ms,\n });\n}\n\n/**\n * Get all traces for a specific proxy\n */\nexport function getTracesByProxyId(proxyId: number): TraceRecord[] {\n return _traces\n .filter((t) => t.proxy_id === proxyId)\n .sort((a, b) => a.timestamp.localeCompare(b.timestamp));\n}\n\n/**\n * Get all recent traces within the retention window\n */\nexport function getRecentTraces(retentionMinutes: number = 5): TraceRecord[] {\n const cutoff = new Date(Date.now() - retentionMinutes * 60_000).toISOString();\n return _traces\n .filter((t) => t.timestamp > cutoff)\n .sort((a, b) => b.timestamp.localeCompare(a.timestamp));\n}\n\n/**\n * Get all traces\n */\nexport function getAllTraces(): TraceRecord[] {\n return [..._traces].sort((a, b) => b.timestamp.localeCompare(a.timestamp));\n}\n\n/**\n * Get the injection hierarchy (parents) for a proxy\n */\nexport function getInjectionHierarchy(proxyId: number): ProxyRegistryEntry[] {\n const result: ProxyRegistryEntry[] = [];\n let current = _proxyRegistry.find((e) => e.proxy_id === proxyId);\n while (current) {\n result.unshift(current);\n if (current.parent_proxy_id == null) break;\n current = _proxyRegistry.find((e) => e.proxy_id === current!.parent_proxy_id);\n }\n return result;\n}\n\n/**\n * Get all dependencies of a proxy (its children in the hierarchy)\n */\nexport function getDependencies(proxyId: number): ProxyRegistryEntry[] {\n const result: ProxyRegistryEntry[] = [];\n const queue = [proxyId];\n const visited = new Set<number>();\n while (queue.length > 0) {\n const id = queue.shift()!;\n if (visited.has(id)) continue;\n visited.add(id);\n const entry = _proxyRegistry.find((e) => e.proxy_id === id);\n if (entry) result.push(entry);\n for (const child of _proxyRegistry) {\n if (child.parent_proxy_id === id && !visited.has(child.proxy_id)) {\n queue.push(child.proxy_id);\n }\n }\n }\n return result;\n}\n\n/**\n * Clear traces older than the retention window\n */\nexport function clearOldTraces(retentionMinutes: number = 5): number {\n const cutoff = new Date(Date.now() - retentionMinutes * 60_000).toISOString();\n const before = _traces.length;\n _traces = _traces.filter((t) => t.timestamp > cutoff);\n return before - _traces.length;\n}\n\n/**\n * Clear all traces\n */\nexport function clearAllTraces(): void {\n _traces = [];\n}\n\n/**\n * Clear the proxy registry\n */\nexport function clearProxyRegistry(): void {\n _proxyRegistry = [];\n}\n\n/**\n * Reset the database completely\n */\nexport function resetDatabase(): void {\n _proxyRegistry = [];\n _traces = [];\n _nextTraceId = 1;\n}\n\n/**\n * Export traces to JSON\n */\nexport function exportTracesToJson(): {\n proxyRegistry: ProxyRegistryEntry[];\n traces: TraceRecord[];\n} {\n return {\n proxyRegistry: [..._proxyRegistry],\n traces: [..._traces].sort((a, b) => b.timestamp.localeCompare(a.timestamp)),\n };\n}\n\n/**\n * Get statistics about traces\n */\nexport function getTraceStatistics(): {\n totalTraces: number;\n totalProxies: number;\n proxiesByClass: Record<string, number>;\n methodCallsByProxy: Record<number, number>;\n} {\n const proxiesByClass: Record<string, number> = {};\n for (const entry of _proxyRegistry) {\n proxiesByClass[entry.class_name] = (proxiesByClass[entry.class_name] || 0) + 1;\n }\n\n const methodCallsByProxy: Record<number, number> = {};\n for (const trace of _traces) {\n methodCallsByProxy[trace.proxy_id] = (methodCallsByProxy[trace.proxy_id] || 0) + 1;\n }\n\n return {\n totalTraces: _traces.length,\n totalProxies: _proxyRegistry.length,\n proxiesByClass,\n methodCallsByProxy,\n };\n}\n"],"mappings":"AAsBA,IAAI,iBAAuC,CAAC;AAC5C,IAAI,UAAyB,CAAC;AAC9B,IAAI,eAAe;AAEnB,SAAS,MAAc;AACrB,UAAO,oBAAI,KAAK,GAAE,YAAY;AAChC;AAEA,SAAS,cAAc,OAAoB;AACzC,QAAM,OAAO,oBAAI,QAAQ;AACzB,SAAO,KAAK,UAAU,OAAO,CAAC,MAAM,QAAQ;AAC1C,QAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU;AAC3C,UAAI,KAAK,IAAI,GAAG,EAAG,QAAO;AAC1B,WAAK,IAAI,GAAG;AAAA,IACd;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,eAAe,KAAe;AACrC,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI,eAAe,OAAO;AACxB,WAAO,EAAE,MAAM,IAAI,MAAM,SAAS,IAAI,SAAS,OAAO,IAAI,MAAM;AAAA,EAClE;AACA,SAAO,EAAE,OAAO,OAAO,GAAG,EAAE;AAC9B;AAKO,SAAS,cACd,SACA,WACA,eACM;AACN,MAAI,eAAe,KAAK,CAAC,MAAM,EAAE,aAAa,OAAO,EAAG;AACxD,iBAAe,KAAK;AAAA,IAClB,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,YAAY,IAAI;AAAA,EAClB,CAAC;AACH;AAKO,SAAS,cAAc,OAA4B;AACxD,UAAQ,KAAK;AAAA,IACX,IAAI;AAAA,IACJ,WAAW,IAAI;AAAA,IACf,UAAU,MAAM;AAAA,IAChB,iBAAiB,MAAM;AAAA,IACvB,YAAY,MAAM;AAAA,IAClB,aAAa,MAAM;AAAA,IACnB,YAAY,cAAc,MAAM,UAAU;AAAA,IAC1C,cAAc,MAAM,gBAAgB,SAAY,cAAc,MAAM,WAAW,IAAI;AAAA,IACnF,OAAO,MAAM,QAAQ,KAAK,UAAU,eAAe,MAAM,KAAK,CAAC,IAAI;AAAA,IACnE,aAAa,MAAM;AAAA,EACrB,CAAC;AACH;AAKO,SAAS,mBAAmB,SAAgC;AACjE,SAAO,QACJ,OAAO,CAAC,MAAM,EAAE,aAAa,OAAO,EACpC,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,cAAc,EAAE,SAAS,CAAC;AAC1D;AAKO,SAAS,gBAAgB,mBAA2B,GAAkB;AAC3E,QAAM,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,mBAAmB,GAAM,EAAE,YAAY;AAC5E,SAAO,QACJ,OAAO,CAAC,MAAM,EAAE,YAAY,MAAM,EAClC,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,cAAc,EAAE,SAAS,CAAC;AAC1D;AAKO,SAAS,eAA8B;AAC5C,SAAO,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,cAAc,EAAE,SAAS,CAAC;AAC3E;AAKO,SAAS,sBAAsB,SAAuC;AAC3E,QAAM,SAA+B,CAAC;AACtC,MAAI,UAAU,eAAe,KAAK,CAAC,MAAM,EAAE,aAAa,OAAO;AAC/D,SAAO,SAAS;AACd,WAAO,QAAQ,OAAO;AACtB,QAAI,QAAQ,mBAAmB,KAAM;AACrC,cAAU,eAAe,KAAK,CAAC,MAAM,EAAE,aAAa,QAAS,eAAe;AAAA,EAC9E;AACA,SAAO;AACT;AAKO,SAAS,gBAAgB,SAAuC;AACrE,QAAM,SAA+B,CAAC;AACtC,QAAM,QAAQ,CAAC,OAAO;AACtB,QAAM,UAAU,oBAAI,IAAY;AAChC,SAAO,MAAM,SAAS,GAAG;AACvB,UAAM,KAAK,MAAM,MAAM;AACvB,QAAI,QAAQ,IAAI,EAAE,EAAG;AACrB,YAAQ,IAAI,EAAE;AACd,UAAM,QAAQ,eAAe,KAAK,CAAC,MAAM,EAAE,aAAa,EAAE;AAC1D,QAAI,MAAO,QAAO,KAAK,KAAK;AAC5B,eAAW,SAAS,gBAAgB;AAClC,UAAI,MAAM,oBAAoB,MAAM,CAAC,QAAQ,IAAI,MAAM,QAAQ,GAAG;AAChE,cAAM,KAAK,MAAM,QAAQ;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAKO,SAAS,eAAe,mBAA2B,GAAW;AACnE,QAAM,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,mBAAmB,GAAM,EAAE,YAAY;AAC5E,QAAM,SAAS,QAAQ;AACvB,YAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,YAAY,MAAM;AACpD,SAAO,SAAS,QAAQ;AAC1B;AAKO,SAAS,iBAAuB;AACrC,YAAU,CAAC;AACb;AAKO,SAAS,qBAA2B;AACzC,mBAAiB,CAAC;AACpB;AAKO,SAAS,gBAAsB;AACpC,mBAAiB,CAAC;AAClB,YAAU,CAAC;AACX,iBAAe;AACjB;AAKO,SAAS,qBAGd;AACA,SAAO;AAAA,IACL,eAAe,CAAC,GAAG,cAAc;AAAA,IACjC,QAAQ,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,cAAc,EAAE,SAAS,CAAC;AAAA,EAC5E;AACF;AAKO,SAAS,qBAKd;AACA,QAAM,iBAAyC,CAAC;AAChD,aAAW,SAAS,gBAAgB;AAClC,mBAAe,MAAM,UAAU,KAAK,eAAe,MAAM,UAAU,KAAK,KAAK;AAAA,EAC/E;AAEA,QAAM,qBAA6C,CAAC;AACpD,aAAW,SAAS,SAAS;AAC3B,uBAAmB,MAAM,QAAQ,KAAK,mBAAmB,MAAM,QAAQ,KAAK,KAAK;AAAA,EACnF;AAEA,SAAO;AAAA,IACL,aAAa,QAAQ;AAAA,IACrB,cAAc,eAAe;AAAA,IAC7B;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noego/ioc",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "A self contained IoC container for Node.js",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -43,15 +43,11 @@
43
43
  "@types/node": "^20.10.4",
44
44
  "@types/randomstring": "^1.1.11",
45
45
  "@types/reflect-metadata": "^0.0.5",
46
- "better-sqlite3": "^9.6.0",
47
- "json-stringify-safe": "^5.0.1",
48
46
  "randomstring": "^1.3.0",
49
47
  "reflect-metadata": "^0.2.2"
50
48
  },
51
49
  "devDependencies": {
52
- "@types/better-sqlite3": "^7.6.13",
53
50
  "@types/jest": "^29.5.14",
54
- "@types/json-stringify-safe": "^5.0.3",
55
51
  "jest": "^29.7.0",
56
52
  "ts-jest": "^29.3.2",
57
53
  "ts-node": "^10.9.2",
File without changes