@kodexa-ai/document-wasm-ts 8.0.0-develop-20957644908 → 8.0.0-develop-20981803950

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.
@@ -32,6 +32,155 @@ var KodexaBridge = (() => {
32
32
  var databases = /* @__PURE__ */ new Map();
33
33
  var nextHandle = 1;
34
34
  var sqlInstance = null;
35
+ var SqlPerformanceTracer = class {
36
+ constructor() {
37
+ this.enabled = false;
38
+ this.stats = /* @__PURE__ */ new Map();
39
+ this.recentTraces = [];
40
+ this.maxRecentTraces = 100;
41
+ this.sessionStart = 0;
42
+ this.logQueries = false;
43
+ this.slowQueryThreshold = 10;
44
+ }
45
+ // ms
46
+ enable(options) {
47
+ this.enabled = true;
48
+ this.sessionStart = performance.now();
49
+ this.logQueries = options?.logQueries ?? false;
50
+ this.slowQueryThreshold = options?.slowQueryThreshold ?? 10;
51
+ this.reset();
52
+ console.log("[sql.js PERF] Performance tracing ENABLED", {
53
+ logQueries: this.logQueries,
54
+ slowQueryThreshold: this.slowQueryThreshold + "ms"
55
+ });
56
+ }
57
+ disable() {
58
+ this.enabled = false;
59
+ console.log("[sql.js PERF] Performance tracing DISABLED");
60
+ }
61
+ isEnabled() {
62
+ return this.enabled;
63
+ }
64
+ reset() {
65
+ this.stats.clear();
66
+ this.recentTraces = [];
67
+ this.sessionStart = performance.now();
68
+ }
69
+ extractQueryType(sql) {
70
+ const trimmed = sql.trim().toUpperCase();
71
+ if (trimmed.startsWith("SELECT")) {
72
+ const match = sql.match(/FROM\s+["']?(\w+)["']?/i);
73
+ return match ? `SELECT:${match[1]}` : "SELECT";
74
+ }
75
+ if (trimmed.startsWith("INSERT")) {
76
+ const match = sql.match(/INTO\s+["']?(\w+)["']?/i);
77
+ return match ? `INSERT:${match[1]}` : "INSERT";
78
+ }
79
+ if (trimmed.startsWith("UPDATE")) {
80
+ const match = sql.match(/UPDATE\s+["']?(\w+)["']?/i);
81
+ return match ? `UPDATE:${match[1]}` : "UPDATE";
82
+ }
83
+ if (trimmed.startsWith("DELETE")) {
84
+ const match = sql.match(/FROM\s+["']?(\w+)["']?/i);
85
+ return match ? `DELETE:${match[1]}` : "DELETE";
86
+ }
87
+ if (trimmed.startsWith("BEGIN")) return "BEGIN";
88
+ if (trimmed.startsWith("COMMIT")) return "COMMIT";
89
+ if (trimmed.startsWith("ROLLBACK")) return "ROLLBACK";
90
+ if (trimmed.startsWith("PRAGMA")) return "PRAGMA";
91
+ if (trimmed.startsWith("CREATE")) return "CREATE";
92
+ return "OTHER";
93
+ }
94
+ recordQuery(sql, paramsJson, startTime, endTime, rowCount, error) {
95
+ if (!this.enabled) return;
96
+ const duration = endTime - startTime;
97
+ const queryType = this.extractQueryType(sql);
98
+ let stat = this.stats.get(queryType);
99
+ if (!stat) {
100
+ stat = { count: 0, totalMs: 0, minMs: Infinity, maxMs: 0, errors: 0 };
101
+ this.stats.set(queryType, stat);
102
+ }
103
+ stat.count++;
104
+ stat.totalMs += duration;
105
+ stat.minMs = Math.min(stat.minMs, duration);
106
+ stat.maxMs = Math.max(stat.maxMs, duration);
107
+ if (error) stat.errors++;
108
+ const trace = { sql, paramsJson, startTime, endTime, duration, rowCount, error };
109
+ this.recentTraces.push(trace);
110
+ if (this.recentTraces.length > this.maxRecentTraces) {
111
+ this.recentTraces.shift();
112
+ }
113
+ if (duration >= this.slowQueryThreshold) {
114
+ console.warn(`[sql.js PERF] SLOW QUERY (${duration.toFixed(2)}ms): ${queryType}`, {
115
+ sql: sql.substring(0, 200),
116
+ rowCount,
117
+ duration: duration.toFixed(2) + "ms"
118
+ });
119
+ } else if (this.logQueries) {
120
+ console.log(`[sql.js PERF] ${queryType} (${duration.toFixed(2)}ms, ${rowCount} rows)`);
121
+ }
122
+ }
123
+ getStats() {
124
+ const result = {};
125
+ for (const [queryType, stat] of this.stats) {
126
+ result[queryType] = {
127
+ ...stat,
128
+ avgMs: stat.count > 0 ? stat.totalMs / stat.count : 0
129
+ };
130
+ }
131
+ return result;
132
+ }
133
+ getSummary() {
134
+ const stats = this.getStats();
135
+ let totalQueries = 0;
136
+ let totalTimeMs = 0;
137
+ let slowQueries = 0;
138
+ let errors = 0;
139
+ const entries = [];
140
+ for (const [type, stat] of Object.entries(stats)) {
141
+ totalQueries += stat.count;
142
+ totalTimeMs += stat.totalMs;
143
+ slowQueries += this.recentTraces.filter(
144
+ (t) => this.extractQueryType(t.sql) === type && t.duration >= this.slowQueryThreshold
145
+ ).length;
146
+ errors += stat.errors;
147
+ entries.push({ type, count: stat.count, totalMs: stat.totalMs, avgMs: stat.avgMs });
148
+ }
149
+ return {
150
+ sessionDuration: performance.now() - this.sessionStart,
151
+ totalQueries,
152
+ totalTimeMs,
153
+ avgQueryMs: totalQueries > 0 ? totalTimeMs / totalQueries : 0,
154
+ slowQueries,
155
+ errors,
156
+ topByCount: [...entries].sort((a, b) => b.count - a.count).slice(0, 10),
157
+ topByTime: [...entries].sort((a, b) => b.totalMs - a.totalMs).slice(0, 10)
158
+ };
159
+ }
160
+ getRecentTraces(count = 20) {
161
+ return this.recentTraces.slice(-count);
162
+ }
163
+ printReport() {
164
+ const summary = this.getSummary();
165
+ console.log("\n========== SQL.JS PERFORMANCE REPORT ==========");
166
+ console.log(`Session Duration: ${(summary.sessionDuration / 1e3).toFixed(2)}s`);
167
+ console.log(`Total Queries: ${summary.totalQueries}`);
168
+ console.log(`Total SQL Time: ${summary.totalTimeMs.toFixed(2)}ms`);
169
+ console.log(`Avg Query Time: ${summary.avgQueryMs.toFixed(3)}ms`);
170
+ console.log(`Slow Queries (>${this.slowQueryThreshold}ms): ${summary.slowQueries}`);
171
+ console.log(`Errors: ${summary.errors}`);
172
+ console.log("\n--- Top by Count ---");
173
+ for (const entry of summary.topByCount) {
174
+ console.log(` ${entry.type}: ${entry.count} calls, ${entry.totalMs.toFixed(2)}ms total, ${entry.avgMs.toFixed(3)}ms avg`);
175
+ }
176
+ console.log("\n--- Top by Total Time ---");
177
+ for (const entry of summary.topByTime) {
178
+ console.log(` ${entry.type}: ${entry.totalMs.toFixed(2)}ms total, ${entry.count} calls, ${entry.avgMs.toFixed(3)}ms avg`);
179
+ }
180
+ console.log("================================================\n");
181
+ }
182
+ };
183
+ var perfTracer = new SqlPerformanceTracer();
35
184
  function uint8ArrayToBase64(bytes) {
36
185
  if (bytes.length < 32768) {
37
186
  let binary2 = "";
@@ -88,12 +237,17 @@ var KodexaBridge = (() => {
88
237
  console.error(`[sql.js] Invalid database handle: ${handle}`);
89
238
  return 0;
90
239
  }
240
+ const startTime = performance.now();
241
+ let error;
91
242
  try {
92
243
  db.run(sql);
93
244
  return 1;
94
- } catch (error) {
95
- console.error("[sql.js] Exec failed:", error);
245
+ } catch (err) {
246
+ error = String(err);
247
+ console.error("[sql.js] Exec failed:", err);
96
248
  return 0;
249
+ } finally {
250
+ perfTracer.recordQuery(sql, "[]", startTime, performance.now(), 0, error);
97
251
  }
98
252
  }
99
253
  function queryOp(handle, sql, paramsJson) {
@@ -102,6 +256,9 @@ var KodexaBridge = (() => {
102
256
  console.error(`[sql.js] Invalid database handle: ${handle}`);
103
257
  return "[]";
104
258
  }
259
+ const startTime = performance.now();
260
+ let error;
261
+ let rowCount = 0;
105
262
  try {
106
263
  let params = [];
107
264
  if (paramsJson && paramsJson !== "[]" && paramsJson !== "null") {
@@ -116,10 +273,14 @@ var KodexaBridge = (() => {
116
273
  results.push(processRowForJson(stmt.getAsObject()));
117
274
  }
118
275
  stmt.free();
276
+ rowCount = results.length;
119
277
  return JSON.stringify(results);
120
- } catch (error) {
121
- console.error("[sql.js] Query failed:", sql, error);
278
+ } catch (err) {
279
+ error = String(err);
280
+ console.error("[sql.js] Query failed:", sql, err);
122
281
  return "[]";
282
+ } finally {
283
+ perfTracer.recordQuery(sql, paramsJson, startTime, performance.now(), rowCount, error);
123
284
  }
124
285
  }
125
286
  function insertOp(handle, sql, paramsJson) {
@@ -128,6 +289,8 @@ var KodexaBridge = (() => {
128
289
  console.error(`[sql.js] Invalid database handle: ${handle}`);
129
290
  return 0;
130
291
  }
292
+ const startTime = performance.now();
293
+ let error;
131
294
  try {
132
295
  let params = [];
133
296
  if (paramsJson && paramsJson !== "[]" && paramsJson !== "null") {
@@ -143,9 +306,12 @@ var KodexaBridge = (() => {
143
306
  return result[0].values[0][0];
144
307
  }
145
308
  return 0;
146
- } catch (error) {
147
- console.error("[sql.js] Insert failed:", sql, error);
309
+ } catch (err) {
310
+ error = String(err);
311
+ console.error("[sql.js] Insert failed:", sql, err);
148
312
  return 0;
313
+ } finally {
314
+ perfTracer.recordQuery(sql, paramsJson, startTime, performance.now(), 1, error);
149
315
  }
150
316
  }
151
317
  function execParamsOp(handle, sql, paramsJson) {
@@ -154,6 +320,9 @@ var KodexaBridge = (() => {
154
320
  console.error(`[sql.js] Invalid database handle: ${handle}`);
155
321
  return -1;
156
322
  }
323
+ const startTime = performance.now();
324
+ let error;
325
+ let rowsAffected = 0;
157
326
  try {
158
327
  let params = [];
159
328
  if (paramsJson && paramsJson !== "[]" && paramsJson !== "null") {
@@ -166,12 +335,16 @@ var KodexaBridge = (() => {
166
335
  }
167
336
  const result = db.exec("SELECT changes() as count");
168
337
  if (result.length > 0 && result[0].values.length > 0) {
169
- return result[0].values[0][0];
338
+ rowsAffected = result[0].values[0][0];
339
+ return rowsAffected;
170
340
  }
171
341
  return 0;
172
- } catch (error) {
173
- console.error("[sql.js] ExecParams failed:", sql, error);
342
+ } catch (err) {
343
+ error = String(err);
344
+ console.error("[sql.js] ExecParams failed:", sql, err);
174
345
  return -1;
346
+ } finally {
347
+ perfTracer.recordQuery(sql, paramsJson, startTime, performance.now(), rowsAffected, error);
175
348
  }
176
349
  }
177
350
  function exportOp(handle) {
@@ -266,7 +439,31 @@ var KodexaBridge = (() => {
266
439
  g.sqljsGetError = getErrorOp;
267
440
  g.sqljsLoadDirect = loadDirectOp;
268
441
  g.sqljsDatabases = databases;
442
+ g.sqljsPerf = {
443
+ /**
444
+ * Enable SQL performance tracing
445
+ * @param options.logQueries - Log all queries (default: false, only slow queries are logged)
446
+ * @param options.slowQueryThreshold - Threshold in ms for slow query warnings (default: 10)
447
+ * @example sqljsPerf.enable({ logQueries: true, slowQueryThreshold: 5 })
448
+ */
449
+ enable: (options) => perfTracer.enable(options),
450
+ /** Disable SQL performance tracing */
451
+ disable: () => perfTracer.disable(),
452
+ /** Check if tracing is enabled */
453
+ isEnabled: () => perfTracer.isEnabled(),
454
+ /** Reset all statistics and traces */
455
+ reset: () => perfTracer.reset(),
456
+ /** Get detailed statistics by query type */
457
+ getStats: () => perfTracer.getStats(),
458
+ /** Get summary with top queries by count and time */
459
+ getSummary: () => perfTracer.getSummary(),
460
+ /** Get recent query traces (default: last 20) */
461
+ getRecentTraces: (count) => perfTracer.getRecentTraces(count),
462
+ /** Print formatted performance report to console */
463
+ printReport: () => perfTracer.printReport()
464
+ };
269
465
  console.log("[sql.js] Bridge functions exposed to globalThis");
466
+ console.log("[sql.js] Performance tracing available via sqljsPerf.enable()");
270
467
  }
271
468
  function getDatabase(handle) {
272
469
  return databases.get(handle);
@@ -7,6 +7,22 @@
7
7
  * The SQL instance is passed in from the wrapper modules, allowing them to
8
8
  * load sql.js in different ways (npm import vs CDN global).
9
9
  */
10
+ interface SqlStats {
11
+ count: number;
12
+ totalMs: number;
13
+ minMs: number;
14
+ maxMs: number;
15
+ errors: number;
16
+ }
17
+ interface QueryTrace {
18
+ sql: string;
19
+ paramsJson: string;
20
+ startTime: number;
21
+ endTime: number;
22
+ duration: number;
23
+ rowCount: number;
24
+ error?: string;
25
+ }
10
26
  /**
11
27
  * Create a new in-memory database
12
28
  * @returns Database handle (positive integer) or 0 on error
@@ -89,4 +105,47 @@ export declare function exposeBridgeFunctions(): void;
89
105
  * Get a database by handle (for debugging from console)
90
106
  */
91
107
  export declare function getDatabase(handle: number): any;
108
+ /**
109
+ * Enable SQL performance tracing
110
+ * @param options.logQueries - Log all queries (default: false, only slow queries are logged)
111
+ * @param options.slowQueryThreshold - Threshold in ms for slow query warnings (default: 10)
112
+ */
113
+ export declare function enableSqlPerformanceTracing(options?: {
114
+ logQueries?: boolean;
115
+ slowQueryThreshold?: number;
116
+ }): void;
117
+ /** Disable SQL performance tracing */
118
+ export declare function disableSqlPerformanceTracing(): void;
119
+ /** Get SQL performance statistics */
120
+ export declare function getSqlPerformanceStats(): Record<string, SqlStats & {
121
+ avgMs: number;
122
+ }>;
123
+ /** Get SQL performance summary */
124
+ export declare function getSqlPerformanceSummary(): {
125
+ sessionDuration: number;
126
+ totalQueries: number;
127
+ totalTimeMs: number;
128
+ avgQueryMs: number;
129
+ slowQueries: number;
130
+ errors: number;
131
+ topByCount: Array<{
132
+ type: string;
133
+ count: number;
134
+ totalMs: number;
135
+ avgMs: number;
136
+ }>;
137
+ topByTime: Array<{
138
+ type: string;
139
+ count: number;
140
+ totalMs: number;
141
+ avgMs: number;
142
+ }>;
143
+ };
144
+ /** Print SQL performance report to console */
145
+ export declare function printSqlPerformanceReport(): void;
146
+ /** Get recent SQL query traces */
147
+ export declare function getRecentSqlTraces(count?: number): QueryTrace[];
148
+ /** Reset SQL performance statistics */
149
+ export declare function resetSqlPerformanceStats(): void;
150
+ export {};
92
151
  //# sourceMappingURL=sqljs-core.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sqljs-core.d.ts","sourceRoot":"","sources":["../../src/wasm/sqljs-core.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAiEH;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAgBzC;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAc1D;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAgC/E;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CA+BhF;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CA+BpF;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAe/C;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAuBnD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAetD;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAW5C;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAIlD;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,IAAI,CAWhC;AAMD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAE7C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAkB5C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAE/C"}
1
+ {"version":3,"file":"sqljs-core.d.ts","sourceRoot":"","sources":["../../src/wasm/sqljs-core.ts"],"names":[],"mappings":"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"}