@smoothbricks/lmao 0.1.1 → 0.1.3

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.
Binary file
@@ -0,0 +1,4 @@
1
+ export declare function isCleanupDebugEnabled(): boolean;
2
+ export declare function cleanupDebug(label: string, details?: Record<string, unknown>): void;
3
+ export declare function cleanupDebugActiveHandles(label: string): void;
4
+ //# sourceMappingURL=cleanupDiagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cleanupDiagnostics.d.ts","sourceRoot":"","sources":["../../src/lib/cleanupDiagnostics.ts"],"names":[],"mappings":"AAMA,wBAAgB,qBAAqB,IAAI,OAAO,CAO/C;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAOnF;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CA2B7D"}
@@ -0,0 +1,42 @@
1
+ /// <reference types="bun" />
2
+ function isTruthyEnvFlag(value) {
3
+ return value === true || value === '1' || value === 'true';
4
+ }
5
+ export function isCleanupDebugEnabled() {
6
+ const globalDebug = Reflect.get(globalThis, '__LMAO_TEST_CLEANUP_DEBUG__');
7
+ if (isTruthyEnvFlag(globalDebug)) {
8
+ return true;
9
+ }
10
+ return isTruthyEnvFlag(process.env.LMAO_TEST_CLEANUP_DEBUG);
11
+ }
12
+ export function cleanupDebug(label, details) {
13
+ if (!isCleanupDebugEnabled()) {
14
+ return;
15
+ }
16
+ const suffix = details ? ` ${JSON.stringify(details)}` : '';
17
+ console.error(`[lmao/cleanup] ${label}${suffix}`);
18
+ }
19
+ export function cleanupDebugActiveHandles(label) {
20
+ if (!isCleanupDebugEnabled()) {
21
+ return;
22
+ }
23
+ const getActiveHandles = Reflect.get(process, '_getActiveHandles');
24
+ if (typeof getActiveHandles !== 'function') {
25
+ cleanupDebug(label, { activeHandles: 'unavailable' });
26
+ return;
27
+ }
28
+ const handles = getActiveHandles.call(process);
29
+ if (!Array.isArray(handles)) {
30
+ cleanupDebug(label, { activeHandles: 'unavailable' });
31
+ return;
32
+ }
33
+ const names = handles.map((handle) => {
34
+ if (typeof handle !== 'object' || handle === null) {
35
+ return typeof handle;
36
+ }
37
+ const constructor = Reflect.get(handle, 'constructor');
38
+ const name = typeof constructor === 'function' ? Reflect.get(constructor, 'name') : undefined;
39
+ return typeof name === 'string' && name.length > 0 ? name : 'Object';
40
+ });
41
+ cleanupDebug(label, { activeHandleCount: handles.length, activeHandles: names });
42
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"flushScheduler.d.ts","sourceRoot":"","sources":["../../src/lib/flushScheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAU,KAAK,KAAK,EAAoB,MAAM,mBAAmB,CAAC;AAIzE,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,YAAY,CAAC;AAiC5D;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAE3F;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;IAChE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAElC;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AAED;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,OAAO,CAAe;IAE9B,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,aAAa,CAAc;IACnC,OAAO,CAAC,gBAAgB,CAAc;IACtC,OAAO,CAAC,UAAU,CAAC,CAAiB;IACpC,OAAO,CAAC,SAAS,CAAC,CAAiB;IACnC,OAAO,CAAC,WAAW,CAAC,CAAiB;IACrC,OAAO,CAAC,SAAS,CAAS;IAE1B,wDAAwD;IACxD,OAAO,CAAC,WAAW,CAAK;IAExB;;;;OAIG;IACH,OAAO,CAAC,+BAA+B,CAAgD;gBAE3E,OAAO,EAAE,YAAY,EAAE,MAAM,GAAE,oBAAyB;IAepE;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAUrC;;OAEG;IACH,KAAK,IAAI,IAAI;IA2Bb;;OAEG;IACH,IAAI,IAAI,IAAI;IAqBZ;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAiB5B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAU7B;;OAEG;IACH,OAAO,CAAC,cAAc;IAatB;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAe3B;;OAEG;YACW,OAAO;IA+IrB;;OAEG;IACH,cAAc,IAAI,IAAI;CAGvB;AAQD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,oBAAoB,GAAG,cAAc,CAK5G;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAKhD;AAED;;;GAGG;AACH,eAAO,MAAM,uBAAuB;IAClC;;OAEG;6BACsB,cAAc,GAAG,MAAM,CAAC,OAAO,GAAG,SAAS;IAKpE;;OAEG;6BACsB,cAAc,SAAS,MAAM,CAAC,OAAO,GAAG,SAAS,GAAG,IAAI;IAIjF;;OAEG;mCAC4B,cAAc,GAAG,MAAM,GAAG,SAAS;IAKlE;;OAEG;mCAC4B,cAAc,QAAQ,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI;CAGtF,CAAC"}
1
+ {"version":3,"file":"flushScheduler.d.ts","sourceRoot":"","sources":["../../src/lib/flushScheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAU,KAAK,KAAK,EAAoB,MAAM,mBAAmB,CAAC;AAKzE,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,YAAY,CAAC;AAuC5D;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAE3F;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;IAChE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAElC;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AAED;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,OAAO,CAAe;IAE9B,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,aAAa,CAAc;IACnC,OAAO,CAAC,gBAAgB,CAAc;IACtC,OAAO,CAAC,UAAU,CAAC,CAAiB;IACpC,OAAO,CAAC,SAAS,CAAC,CAAiB;IACnC,OAAO,CAAC,WAAW,CAAC,CAAiB;IACrC,OAAO,CAAC,SAAS,CAAS;IAE1B,wDAAwD;IACxD,OAAO,CAAC,WAAW,CAAK;IAExB;;;;OAIG;IACH,OAAO,CAAC,+BAA+B,CAAgD;gBAE3E,OAAO,EAAE,YAAY,EAAE,MAAM,GAAE,oBAAyB;IAepE;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAUrC;;OAEG;IACH,KAAK,IAAI,IAAI;IA+Bb;;OAEG;IACH,IAAI,IAAI,IAAI;IAuBZ;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAiB5B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAU7B;;OAEG;IACH,OAAO,CAAC,cAAc;IAatB;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAe3B;;OAEG;YACW,OAAO;IAqJrB;;OAEG;IACH,cAAc,IAAI,IAAI;CAGvB;AAQD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,oBAAoB,GAAG,cAAc,CAK5G;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAKhD;AAED;;;GAGG;AACH,eAAO,MAAM,uBAAuB;IAClC;;OAEG;6BACsB,cAAc,GAAG,MAAM,CAAC,OAAO,GAAG,SAAS;IAKpE;;OAEG;6BACsB,cAAc,SAAS,MAAM,CAAC,OAAO,GAAG,SAAS,GAAG,IAAI;IAIjF;;OAEG;mCAC4B,cAAc,GAAG,MAAM,GAAG,SAAS;IAKlE;;OAEG;mCAC4B,cAAc,QAAQ,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI;CAGtF,CAAC"}
@@ -7,6 +7,7 @@
7
7
  * - Background processing (cold path)
8
8
  */
9
9
  import { Column, tableFromColumns } from '@uwdata/flechette';
10
+ import { cleanupDebug } from './cleanupDiagnostics.js';
10
11
  import { convertSpanTreeToArrowTable } from './convertToArrow.js';
11
12
  /**
12
13
  * Number of flushes before logging capacity stats.
@@ -19,6 +20,11 @@ function isSpanBufferConstructor(value) {
19
20
  function isNodeTimer(value) {
20
21
  return typeof value === 'object' && value !== null && typeof Reflect.get(value, 'hasRef') === 'function';
21
22
  }
23
+ function unrefTimer(timer) {
24
+ if (isNodeTimer(timer)) {
25
+ timer.unref();
26
+ }
27
+ }
22
28
  function mergeTables(first, rest) {
23
29
  if (rest.length === 0)
24
30
  return first;
@@ -90,21 +96,25 @@ export class FlushScheduler {
90
96
  this.isRunning = true;
91
97
  this.lastFlushTime = Date.now();
92
98
  this.lastActivityTime = Date.now();
99
+ cleanupDebug('flushScheduler.start', this.config);
93
100
  // Set up periodic flush timer
94
101
  this.flushTimer = setInterval(() => {
95
102
  this.checkFlushConditions();
96
103
  }, 1000); // Check every second
104
+ unrefTimer(this.flushTimer);
97
105
  // Set up idle detection timer
98
106
  if (this.config.idleDetection) {
99
107
  this.idleTimer = setInterval(() => {
100
108
  this.checkIdleFlush();
101
109
  }, this.config.idleTimeout);
110
+ unrefTimer(this.idleTimer);
102
111
  }
103
112
  // Set up memory pressure timer (Node.js only)
104
113
  if (this.config.memoryPressureDetection && typeof process !== 'undefined') {
105
114
  this.memoryTimer = setInterval(() => {
106
115
  this.checkMemoryPressure();
107
116
  }, 2000); // Check every 2 seconds
117
+ unrefTimer(this.memoryTimer);
108
118
  }
109
119
  }
110
120
  /**
@@ -113,6 +123,7 @@ export class FlushScheduler {
113
123
  stop() {
114
124
  if (!this.isRunning)
115
125
  return;
126
+ cleanupDebug('flushScheduler.stop:start', { pendingBuffers: this.buffers.size });
116
127
  this.isRunning = false;
117
128
  if (this.flushTimer) {
118
129
  clearInterval(this.flushTimer);
@@ -126,6 +137,7 @@ export class FlushScheduler {
126
137
  clearInterval(this.memoryTimer);
127
138
  this.memoryTimer = undefined;
128
139
  }
140
+ cleanupDebug('flushScheduler.stop:end', { pendingBuffers: this.buffers.size });
129
141
  }
130
142
  /**
131
143
  * Manually trigger a flush
@@ -321,6 +333,12 @@ export class FlushScheduler {
321
333
  }
322
334
  catch (error) {
323
335
  console.error('Error in flush handler:', error);
336
+ cleanupDebug('flushScheduler.doFlush:error', {
337
+ reason,
338
+ totalRows,
339
+ totalBuffers,
340
+ pendingBuffers: this.buffers.size,
341
+ });
324
342
  // Do NOT reset buffers on failure to avoid data loss
325
343
  }
326
344
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite-async-writer.d.ts","sourceRoot":"","sources":["../../../src/lib/sqlite/sqlite-async-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAejD,OAAO,KAAK,EAAE,mBAAmB,EAAwB,MAAM,gBAAgB,CAAC;AAEhF,qBAAa,sBAAsB;IAKrB,OAAO,CAAC,EAAE;IAJtB,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,eAAe,CAA2C;IAClE,OAAO,CAAC,WAAW,CAAS;gBAER,EAAE,EAAE,mBAAmB;YAE7B,IAAI;YAYJ,mBAAmB;YAUnB,aAAa;IAe3B,OAAO,CAAC,kBAAkB;IAYpB,KAAK,CAAC,UAAU,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAc/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
1
+ {"version":3,"file":"sqlite-async-writer.d.ts","sourceRoot":"","sources":["../../../src/lib/sqlite/sqlite-async-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAejD,OAAO,KAAK,EAAE,mBAAmB,EAAwB,MAAM,gBAAgB,CAAC;AAEhF,qBAAa,sBAAsB;IAKrB,OAAO,CAAC,EAAE;IAJtB,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,eAAe,CAA2C;IAClE,OAAO,CAAC,WAAW,CAAS;gBAER,EAAE,EAAE,mBAAmB;YAE7B,IAAI;YAYJ,mBAAmB;YAUnB,aAAa;IAe3B,OAAO,CAAC,kBAAkB;IAYpB,KAAK,CAAC,UAAU,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAK7B"}
@@ -1,3 +1,12 @@
1
+ /**
2
+ * SQLiteAsyncTraceWriter - Async SQLite persistence for span buffer trees.
3
+ *
4
+ * Works with async SQLite drivers (for example Cloudflare D1 adapters) while
5
+ * preserving the same `spans` table shape as the sync SQLiteTraceWriter.
6
+ *
7
+ * @module sqlite-async-writer
8
+ */
9
+ import { cleanupDebug } from '../cleanupDiagnostics.js';
1
10
  import { buildAddColumnSql, buildInsertParams, buildInsertSql, extractSqliteColumnsFromTableInfo, getActiveUserFields, getInsertStatementCacheKey, getMissingSchemaColumns, isSqliteDuplicateColumnError, parseSqliteTableInfoRows, SPANS_TABLE_INFO_SQL, SPANS_TABLE_INIT_SQL, walkSpanSegments, } from './sqlite-common.js';
2
11
  export class SQLiteAsyncTraceWriter {
3
12
  db;
@@ -49,6 +58,10 @@ export class SQLiteAsyncTraceWriter {
49
58
  return stmt;
50
59
  }
51
60
  async flush(rootBuffer) {
61
+ cleanupDebug('sqliteAsyncWriter.flush:start', {
62
+ initialized: this.initialized,
63
+ statementCacheSize: this.insertStmtCache.size,
64
+ });
52
65
  await this.init();
53
66
  for (const segment of walkSpanSegments(rootBuffer)) {
54
67
  await this.ensureColumns(segment.buffer._logSchema);
@@ -58,8 +71,11 @@ export class SQLiteAsyncTraceWriter {
58
71
  await insertStmt.run(...buildInsertParams(segment, row, activeUserFields));
59
72
  }
60
73
  }
74
+ cleanupDebug('sqliteAsyncWriter.flush:end', { statementCacheSize: this.insertStmtCache.size });
61
75
  }
62
76
  async close() {
77
+ cleanupDebug('sqliteAsyncWriter.close:start', { statementCacheSize: this.insertStmtCache.size });
63
78
  await this.db.close();
79
+ cleanupDebug('sqliteAsyncWriter.close:end');
64
80
  }
65
81
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite-writer.d.ts","sourceRoot":"","sources":["../../../src/lib/sqlite/sqlite-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAgBjD,OAAO,KAAK,EAAE,kBAAkB,EAAuB,MAAM,gBAAgB,CAAC;AAE9E,MAAM,WAAW,kBAAkB;IACjC,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,iBAAiB;IAIhB,OAAO,CAAC,EAAE;IAHtB,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,eAAe,CAA0C;gBAE7C,EAAE,EAAE,kBAAkB;IAI1C,OAAO,CAAC,IAAI;IAQZ,OAAO,CAAC,mBAAmB;IAU3B,kEAAkE;IAClE,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,gBAAgB;IAWxB,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,kBAAkB;IAY1B,mDAAmD;IACnD,KAAK,CAAC,UAAU,EAAE,aAAa,GAAG,IAAI;IAWtC,KAAK,IAAI,IAAI;CAGd"}
1
+ {"version":3,"file":"sqlite-writer.d.ts","sourceRoot":"","sources":["../../../src/lib/sqlite/sqlite-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAgBjD,OAAO,KAAK,EAAE,kBAAkB,EAAuB,MAAM,gBAAgB,CAAC;AAE9E,MAAM,WAAW,kBAAkB;IACjC,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,iBAAiB;IAIhB,OAAO,CAAC,EAAE;IAHtB,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,eAAe,CAA0C;gBAE7C,EAAE,EAAE,kBAAkB;IAI1C,OAAO,CAAC,IAAI;IAQZ,OAAO,CAAC,mBAAmB;IAU3B,kEAAkE;IAClE,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,gBAAgB;IAWxB,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,kBAAkB;IAY1B,mDAAmD;IACnD,KAAK,CAAC,UAAU,EAAE,aAAa,GAAG,IAAI;IActC,KAAK,IAAI,IAAI;CAKd"}
@@ -1,3 +1,20 @@
1
+ /**
2
+ * SQLiteTraceWriter - General-purpose writer that persists span buffer trees to SQLite.
3
+ *
4
+ * Accepts a SyncSQLiteDatabase instance (from bun:sqlite or better-sqlite3)
5
+ * and persists the full span tree as a flat `spans` table with dynamic column
6
+ * evolution based on the LogSchema fields found at flush time.
7
+ *
8
+ * Architecture:
9
+ * - Single `spans` table — no runs/log_entries decomposition
10
+ * - trace_id IS the run identifier (one root span per trace)
11
+ * - Tree structure via span_id / parent_span_id (no depth column)
12
+ * - User schema columns added dynamically via ALTER TABLE
13
+ * - Per-buffer ensureColumns for cross-library schema merging
14
+ *
15
+ * @module sqlite-writer
16
+ */
17
+ import { cleanupDebug } from '../cleanupDiagnostics.js';
1
18
  import { buildAddColumnSql, buildInsertParams, buildInsertSql, extractSqliteColumnsFromTableInfo, getActiveUserFields, getInsertStatementCacheKey, getMissingSchemaColumns, isSqliteDuplicateColumnError, parseSqliteTableInfoRows, SPANS_TABLE_INFO_SQL, SPANS_TABLE_INIT_SQL, walkSpanSegments, } from './sqlite-common.js';
2
19
  export class SQLiteTraceWriter {
3
20
  db;
@@ -62,17 +79,22 @@ export class SQLiteTraceWriter {
62
79
  }
63
80
  /** Write a root SpanBuffer tree to the database */
64
81
  flush(rootBuffer) {
82
+ cleanupDebug('sqliteWriter.flush:start', { statementCacheSize: this.insertStmtCache.size });
65
83
  this.db.exec('BEGIN IMMEDIATE');
66
84
  try {
67
85
  this.flushAllSegments(rootBuffer);
68
86
  this.db.exec('COMMIT');
87
+ cleanupDebug('sqliteWriter.flush:end', { statementCacheSize: this.insertStmtCache.size });
69
88
  }
70
89
  catch (error) {
71
90
  this.db.exec('ROLLBACK');
91
+ cleanupDebug('sqliteWriter.flush:error', { statementCacheSize: this.insertStmtCache.size });
72
92
  throw error;
73
93
  }
74
94
  }
75
95
  close() {
96
+ cleanupDebug('sqliteWriter.close:start', { statementCacheSize: this.insertStmtCache.size });
76
97
  this.db.close();
98
+ cleanupDebug('sqliteWriter.close:end');
77
99
  }
78
100
  }
@@ -1 +1 @@
1
- {"version":3,"file":"bun-harness.d.ts","sourceRoot":"","sources":["../../../src/lib/testing/bun-harness.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bun-harness.d.ts","sourceRoot":"","sources":["../../../src/lib/testing/bun-harness.ts"],"names":[],"mappings":"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"}
@@ -43,6 +43,7 @@ import { Database } from 'bun:sqlite';
43
43
  import * as bunTest from 'bun:test';
44
44
  import { afterAll as _afterAll, afterEach as _afterEach, beforeAll as _beforeAll, beforeEach as _beforeEach, describe as _describe, expect as _expect, it as _it, mock, } from 'bun:test';
45
45
  import { AsyncLocalStorage } from 'node:async_hooks';
46
+ import { cleanupDebug, cleanupDebugActiveHandles } from '../cleanupDiagnostics.js';
46
47
  import { defineOpContext } from '../defineOpContext.js';
47
48
  import { JsBufferStrategy } from '../JsBufferStrategy.js';
48
49
  import { S } from '../schema/builder.js';
@@ -162,7 +163,9 @@ function createRootTracer({ binding, sqlite, verbose, }) {
162
163
  async function closeTracer(tracer) {
163
164
  const close = Reflect.get(tracer, 'close');
164
165
  if (typeof close === 'function') {
166
+ cleanupDebug('tracer.close:start', { tracer: tracer.constructor.name });
165
167
  await close.call(tracer);
168
+ cleanupDebug('tracer.close:end', { tracer: tracer.constructor.name });
166
169
  }
167
170
  }
168
171
  let _activeSuiteTracer = null;
@@ -335,17 +338,24 @@ function createTestTracerInstance(binding, options) {
335
338
  });
336
339
  });
337
340
  _afterAll(async () => {
341
+ cleanupDebug('instance.afterAll:start');
342
+ cleanupDebugActiveHandles('instance.afterAll:handles:start');
338
343
  if (resolveTestRun) {
344
+ cleanupDebug('instance.rootTrace:resolve');
339
345
  resolveTestRun();
340
346
  resolveTestRun = null;
341
347
  }
342
348
  if (rootTracePromise) {
349
+ cleanupDebug('instance.rootTrace:await:start');
343
350
  await rootTracePromise;
351
+ cleanupDebug('instance.rootTrace:await:end');
344
352
  rootTracePromise = null;
345
353
  }
346
354
  if (tracer) {
347
355
  try {
356
+ cleanupDebug('instance.tracer.flush:start', { tracer: tracer.constructor.name });
348
357
  await tracer.flush();
358
+ cleanupDebug('instance.tracer.flush:end', { tracer: tracer.constructor.name });
349
359
  if (options?.sqlite && rootCtx) {
350
360
  const traceId = rootCtx.buffer.trace_id;
351
361
  const dbPath = options.sqlite.dbPath ?? '.trace-results.db';
@@ -357,6 +367,8 @@ function createTestTracerInstance(binding, options) {
357
367
  }
358
368
  finally {
359
369
  await closeTracer(tracer);
370
+ cleanupDebugActiveHandles('instance.afterAll:handles:end');
371
+ cleanupDebug('instance.afterAll:end');
360
372
  }
361
373
  }
362
374
  });
@@ -424,19 +436,26 @@ export function initTraceTestRun(opContext, options) {
424
436
  });
425
437
  // Register global teardown — resolve root, wait for span-end, then flush tracer outputs
426
438
  _afterAll(async () => {
439
+ cleanupDebug('global.afterAll:start');
440
+ cleanupDebugActiveHandles('global.afterAll:handles:start');
427
441
  // Resolve the root promise — triggers span-end write via _executeWithContext .then()
428
442
  if (_resolveTestRun) {
443
+ cleanupDebug('global.rootTrace:resolve');
429
444
  _resolveTestRun();
430
445
  _resolveTestRun = null;
431
446
  }
432
447
  // Await the trace promise so span-end is written to the buffer before flushing
433
448
  if (_rootTracePromise) {
449
+ cleanupDebug('global.rootTrace:await:start');
434
450
  await _rootTracePromise;
451
+ cleanupDebug('global.rootTrace:await:end');
435
452
  _rootTracePromise = null;
436
453
  }
437
454
  if (_tracer) {
438
455
  try {
456
+ cleanupDebug('global.tracer.flush:start', { tracer: _tracer.constructor.name });
439
457
  await _tracer.flush();
458
+ cleanupDebug('global.tracer.flush:end', { tracer: _tracer.constructor.name });
440
459
  if (options?.sqlite && _rootCtx) {
441
460
  const traceId = _rootCtx.buffer.trace_id;
442
461
  const dbPath = options.sqlite.dbPath ?? '.trace-results.db';
@@ -448,6 +467,8 @@ export function initTraceTestRun(opContext, options) {
448
467
  }
449
468
  finally {
450
469
  await closeTracer(_tracer);
470
+ cleanupDebugActiveHandles('global.afterAll:handles:end');
471
+ cleanupDebug('global.afterAll:end');
451
472
  }
452
473
  }
453
474
  });
@@ -1 +1 @@
1
- {"version":3,"file":"CompositeTracer.d.ts","sourceRoot":"","sources":["../../../src/lib/tracers/CompositeTracer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAQ9C,MAAM,WAAW,sBAAsB,CAAC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,CACnF,SAAQ,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC;IACnD,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;CACxB;AAED;;;;;GAKG;AACH,qBAAa,eAAe,CAAC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,CAAE,SAAQ,MAAM,CAAC,CAAC,CAAC;IAC3F,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;gBAE5B,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,sBAAsB,CAAC,CAAC,CAAC;IAK1D,YAAY,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI;IAMxE,UAAU,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI;IAMtE,WAAW,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI;IAMxE,SAAS,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI;IAMtE,mBAAmB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI;IAM5D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAM/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAU7B"}
1
+ {"version":3,"file":"CompositeTracer.d.ts","sourceRoot":"","sources":["../../../src/lib/tracers/CompositeTracer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAQ9C,MAAM,WAAW,sBAAsB,CAAC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,CACnF,SAAQ,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC;IACnD,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;CACxB;AAED;;;;;GAKG;AACH,qBAAa,eAAe,CAAC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,CAAE,SAAQ,MAAM,CAAC,CAAC,CAAC;IAC3F,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;gBAE5B,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,sBAAsB,CAAC,CAAC,CAAC;IAK1D,YAAY,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI;IAMxE,UAAU,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI;IAMtE,WAAW,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI;IAMxE,SAAS,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI;IAMtE,mBAAmB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI;IAM5D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAY7B"}
@@ -1,3 +1,4 @@
1
+ import { cleanupDebug } from '../cleanupDiagnostics.js';
1
2
  import { Tracer } from '../tracer.js';
2
3
  function hasClose(value) {
3
4
  return typeof value === 'object' && value !== null && typeof Reflect.get(value, 'close') === 'function';
@@ -41,7 +42,9 @@ export class CompositeTracer extends Tracer {
41
42
  }
42
43
  async flush() {
43
44
  for (const tracer of this.delegates) {
45
+ cleanupDebug('compositeTracer.flush:delegate:start', { tracer: tracer.constructor.name });
44
46
  await tracer.flush();
47
+ cleanupDebug('compositeTracer.flush:delegate:end', { tracer: tracer.constructor.name });
45
48
  }
46
49
  }
47
50
  async close() {
@@ -49,7 +52,9 @@ export class CompositeTracer extends Tracer {
49
52
  if (hasClose(tracer)) {
50
53
  const { close } = tracer;
51
54
  if (close) {
55
+ cleanupDebug('compositeTracer.close:delegate:start', { tracer: tracer.constructor.name });
52
56
  await close.call(tracer);
57
+ cleanupDebug('compositeTracer.close:delegate:end', { tracer: tracer.constructor.name });
53
58
  }
54
59
  }
55
60
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SQLiteTracer.d.ts","sourceRoot":"","sources":["../../../src/lib/tracers/SQLiteTracer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEtF,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,WAAW,mBAAmB,CAClC,CAAC,SAAS,OAAO,wBAAwB,EAAE,SAAS,GAAG,OAAO,wBAAwB,EAAE,SAAS,CACjG,SAAQ,aAAa,CAAC,CAAC,CAAC;IACxB,EAAE,EAAE,kBAAkB,CAAC;CACxB;AAED,MAAM,WAAW,wBAAwB,CACvC,CAAC,SAAS,OAAO,wBAAwB,EAAE,SAAS,GAAG,OAAO,wBAAwB,EAAE,SAAS,CACjG,SAAQ,aAAa,CAAC,CAAC,CAAC;IACxB,EAAE,EAAE,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACxD;AAED;;GAEG;AACH,qBAAa,YAAY,CAAC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,CAAE,SAAQ,MAAM,CAAC,CAAC,CAAC;IACxF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;gBAE/B,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC;IAKlF,YAAY,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI;IAIzE,UAAU,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI;IAItE,WAAW,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI;IAIzE,SAAS,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI;IAIvE,mBAAmB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI;IAItE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B;AAED;;;;GAIG;AACH,qBAAa,iBAAiB,CAAC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,CAAE,SAAQ,MAAM,CAAC,CAAC,CAAC;IAC7F,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkC;IAChE,OAAO,CAAC,aAAa,CAAoC;IACzD,OAAO,CAAC,aAAa,CAAiB;gBAE1B,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,wBAAwB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC;IAKvF,YAAY,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI;IAIzE,UAAU,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI;IAWtE,WAAW,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI;IAIzE,SAAS,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI;IAIvE,mBAAmB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI;IAI7D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAY/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAK7B"}
1
+ {"version":3,"file":"SQLiteTracer.d.ts","sourceRoot":"","sources":["../../../src/lib/tracers/SQLiteTracer.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { cleanupDebug } from '../cleanupDiagnostics.js';
1
2
  import { SQLiteAsyncTraceWriter } from '../sqlite/sqlite-async-writer.js';
2
3
  import { SQLiteTraceWriter } from '../sqlite/sqlite-writer.js';
3
4
  import { Tracer } from '../tracer.js';
@@ -14,7 +15,9 @@ export class SQLiteTracer extends Tracer {
14
15
  // No-op
15
16
  }
16
17
  onTraceEnd(rootBuffer) {
18
+ cleanupDebug('sqliteTracer.onTraceEnd:flush:start', { rows: rootBuffer._writeIndex });
17
19
  this.writer.flush(rootBuffer);
20
+ cleanupDebug('sqliteTracer.onTraceEnd:flush:end');
18
21
  }
19
22
  onSpanStart(_childBuffer) {
20
23
  // No-op
@@ -26,7 +29,9 @@ export class SQLiteTracer extends Tracer {
26
29
  // No-op
27
30
  }
28
31
  async close() {
32
+ cleanupDebug('sqliteTracer.close:start');
29
33
  this.writer.close();
34
+ cleanupDebug('sqliteTracer.close:end');
30
35
  }
31
36
  }
32
37
  /**
@@ -66,6 +71,7 @@ export class SQLiteAsyncTracer extends Tracer {
66
71
  // No-op
67
72
  }
68
73
  async flush() {
74
+ cleanupDebug('sqliteAsyncTracer.flush:start');
69
75
  await this.pendingWrites;
70
76
  if (this.pendingErrors.length > 0) {
71
77
  const errors = this.pendingErrors;
@@ -75,10 +81,13 @@ export class SQLiteAsyncTracer extends Tracer {
75
81
  }
76
82
  throw new AggregateError(errors, `SQLiteAsyncTracer flush failed for ${errors.length} trace writes`);
77
83
  }
84
+ cleanupDebug('sqliteAsyncTracer.flush:end');
78
85
  }
79
86
  async close() {
87
+ cleanupDebug('sqliteAsyncTracer.close:start');
80
88
  await this.flush();
81
89
  const writer = await this.writerPromise;
82
90
  await writer.close();
91
+ cleanupDebug('sqliteAsyncTracer.close:end');
83
92
  }
84
93
  }
@@ -88,9 +88,9 @@ export declare enum SizeClass {
88
88
  Identity = 4
89
89
  }
90
90
  export interface WasmAllocatorOptions {
91
- /** Initial memory pages (64KB each). Default: 17 (~1MB) */
91
+ /** Initial memory pages (64KB each). Values below the module minimum are clamped. */
92
92
  initialPages?: number;
93
- /** Maximum memory pages. Default: 16384 (1GB) */
93
+ /** Maximum memory pages. Values below the effective initial page count are clamped. */
94
94
  maxPages?: number;
95
95
  /** Default capacity (rows per span buffer). Default: 64 */
96
96
  capacity?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"wasmAllocator.d.ts","sourceRoot":"","sources":["../../../src/lib/wasm/wasmAllocator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC;IAEpC,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE;QAChB,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;QAC9F,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;QAC9F,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;QAC7F,eAAe,EAAE,CACf,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,KACb,MAAM,CAAC;KACb,CAAC;IAEF,sFAAsF;IACtF,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC;IAE3B,+CAA+C;IAC/C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,8CAA8C;IAC9C,IAAI,IAAI,IAAI,CAAC;IAEb,qDAAqD;IACrD,KAAK,IAAI,IAAI,CAAC;IAGd,eAAe,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3C,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACnC,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACnC,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAGnC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxD,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChD,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChD,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGhD,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjG,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5E,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7E,8DAA8D;IAC9D,aAAa,CACX,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAAC;IAGV,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzF,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzF,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAGxF,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAG1C,UAAU,IAAI,MAAM,CAAC;IACrB,aAAa,IAAI,MAAM,CAAC;IACxB,YAAY,IAAI,MAAM,CAAC;IACvB,iBAAiB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7C,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxC,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxC,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAGxC,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACzD,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5E,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5C,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzE,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IAG1D,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C,eAAe,IAAI,MAAM,CAAC;IAC1B,cAAc,IAAI,MAAM,CAAC;IACzB,aAAa,IAAI,MAAM,CAAC;IACxB,gBAAgB,IAAI,MAAM,CAAC;IAG3B,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;IACxD,kBAAkB,IAAI,MAAM,CAAC;IAC7B,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAChD,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IACpD,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAGnD,cAAc,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAChE,qBAAqB,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvE,qBAAqB,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvE,qBAAqB,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACxE;AAED;;GAEG;AACH,oBAAY,SAAS;IACnB,UAAU,IAAI;IACd,KAAK,IAAI;IACT,KAAK,IAAI;IACT,KAAK,IAAI;IACT,QAAQ,IAAI;CACb;AAED,MAAM,WAAW,oBAAoB;IACnC,2DAA2D;IAC3D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iDAAiD;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA0RD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,aAAa,CAAC,CAmBhG;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,aAAa,CAgBrH"}
1
+ {"version":3,"file":"wasmAllocator.d.ts","sourceRoot":"","sources":["../../../src/lib/wasm/wasmAllocator.ts"],"names":[],"mappings":"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"}
@@ -18,7 +18,7 @@ function isWasmExports(value) {
18
18
  // =============================================================================
19
19
  // Implementation
20
20
  // =============================================================================
21
- const DEFAULT_INITIAL_PAGES = 17; // ~1MB - matches WASM module minimum
21
+ const MIN_INITIAL_PAGES = 17; // ~1MB - matches WASM module minimum
22
22
  const DEFAULT_MAX_PAGES = 16384; // 1GB max (can grow up to this)
23
23
  const DEFAULT_CAPACITY = 64;
24
24
  /**
@@ -193,8 +193,8 @@ async function getWasmModule() {
193
193
  * Buddy allocation enables efficient memory management across different capacities.
194
194
  */
195
195
  export async function createWasmAllocator(options) {
196
- const initialPages = options?.initialPages ?? DEFAULT_INITIAL_PAGES;
197
- const maxPages = options?.maxPages ?? DEFAULT_MAX_PAGES;
196
+ const initialPages = Math.max(options?.initialPages ?? MIN_INITIAL_PAGES, MIN_INITIAL_PAGES);
197
+ const maxPages = Math.max(options?.maxPages ?? DEFAULT_MAX_PAGES, initialPages);
198
198
  const capacity = options?.capacity ?? DEFAULT_CAPACITY;
199
199
  // Create memory
200
200
  const memory = new WebAssembly.Memory({
@@ -212,8 +212,8 @@ export async function createWasmAllocator(options) {
212
212
  * Synchronous version for when WASM is pre-loaded.
213
213
  */
214
214
  export function createWasmAllocatorSync(wasmModule, options) {
215
- const initialPages = options?.initialPages ?? DEFAULT_INITIAL_PAGES;
216
- const maxPages = options?.maxPages ?? DEFAULT_MAX_PAGES;
215
+ const initialPages = Math.max(options?.initialPages ?? MIN_INITIAL_PAGES, MIN_INITIAL_PAGES);
216
+ const maxPages = Math.max(options?.maxPages ?? DEFAULT_MAX_PAGES, initialPages);
217
217
  const capacity = options?.capacity ?? DEFAULT_CAPACITY;
218
218
  // Create memory
219
219
  const memory = new WebAssembly.Memory({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smoothbricks/lmao",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -126,7 +126,8 @@
126
126
  "scripts": {
127
127
  "bench": "bun run benchmarks/*.bench.ts",
128
128
  "bench:wasm": "bun run benchmarks/js-vs-wasm.bench.ts",
129
- "build:wasm": "zig build -Doptimize=ReleaseSmall"
129
+ "build:wasm": "zig build -Doptimize=ReleaseSmall",
130
+ "test": "nx run lmao:test --tui=false --outputStyle=stream"
130
131
  },
131
132
  "nx": {
132
133
  "sourceRoot": "packages/lmao/src",
@@ -139,35 +140,20 @@
139
140
  "^typecheck"
140
141
  ]
141
142
  },
142
- "build:wasm": {
143
- "inputs": [
144
- "{projectRoot}/src/**/*.zig",
145
- "{projectRoot}/build.zig",
146
- "{projectRoot}/build.zig.zon"
147
- ],
148
- "executor": "nx:run-commands",
149
- "options": {
150
- "command": "zig build -Doptimize=ReleaseSmall",
151
- "cwd": "packages/lmao"
152
- }
153
- },
154
- "build": {
155
- "dependsOn": [
156
- "^build",
157
- "build:wasm"
158
- ]
159
- },
160
143
  "test": {
161
- "executor": "nx:run-commands",
144
+ "executor": "@smoothbricks/nx-plugin:bounded-exec",
162
145
  "options": {
163
146
  "command": "bun test",
164
- "cwd": "packages/lmao"
147
+ "cwd": "{projectRoot}",
148
+ "timeoutMs": 120000,
149
+ "killAfterMs": 1e4
165
150
  }
166
151
  }
167
152
  },
168
153
  "tags": [
169
154
  "npm:public"
170
- ]
155
+ ],
156
+ "name": "lmao"
171
157
  },
172
158
  "devDependencies": {
173
159
  "fast-check": "^4.4.0",
@@ -191,13 +191,20 @@ describe('FlushScheduler', () => {
191
191
  describe('failure cases', () => {
192
192
  it('should not throw if timers fail to clear', () => {
193
193
  scheduler.start();
194
+ const originalFlushTimer = FlushSchedulerTestUtils.getFlushTimer(scheduler);
194
195
 
195
196
  // Force internal state corruption - accessing private property for testing
196
197
  FlushSchedulerTestUtils.setFlushTimer(scheduler, undefined);
197
198
 
198
- expect(() => {
199
- scheduler.stop();
200
- }).not.toThrow();
199
+ try {
200
+ expect(() => {
201
+ scheduler.stop();
202
+ }).not.toThrow();
203
+ } finally {
204
+ if (originalFlushTimer) {
205
+ clearInterval(originalFlushTimer);
206
+ }
207
+ }
201
208
  });
202
209
  });
203
210
  });
@@ -0,0 +1,52 @@
1
+ /// <reference types="bun" />
2
+
3
+ function isTruthyEnvFlag(value: unknown): boolean {
4
+ return value === true || value === '1' || value === 'true';
5
+ }
6
+
7
+ export function isCleanupDebugEnabled(): boolean {
8
+ const globalDebug = Reflect.get(globalThis, '__LMAO_TEST_CLEANUP_DEBUG__');
9
+ if (isTruthyEnvFlag(globalDebug)) {
10
+ return true;
11
+ }
12
+
13
+ return isTruthyEnvFlag(process.env.LMAO_TEST_CLEANUP_DEBUG);
14
+ }
15
+
16
+ export function cleanupDebug(label: string, details?: Record<string, unknown>): void {
17
+ if (!isCleanupDebugEnabled()) {
18
+ return;
19
+ }
20
+
21
+ const suffix = details ? ` ${JSON.stringify(details)}` : '';
22
+ console.error(`[lmao/cleanup] ${label}${suffix}`);
23
+ }
24
+
25
+ export function cleanupDebugActiveHandles(label: string): void {
26
+ if (!isCleanupDebugEnabled()) {
27
+ return;
28
+ }
29
+
30
+ const getActiveHandles = Reflect.get(process, '_getActiveHandles');
31
+ if (typeof getActiveHandles !== 'function') {
32
+ cleanupDebug(label, { activeHandles: 'unavailable' });
33
+ return;
34
+ }
35
+
36
+ const handles = getActiveHandles.call(process);
37
+ if (!Array.isArray(handles)) {
38
+ cleanupDebug(label, { activeHandles: 'unavailable' });
39
+ return;
40
+ }
41
+
42
+ const names = handles.map((handle) => {
43
+ if (typeof handle !== 'object' || handle === null) {
44
+ return typeof handle;
45
+ }
46
+ const constructor = Reflect.get(handle, 'constructor');
47
+ const name = typeof constructor === 'function' ? Reflect.get(constructor, 'name') : undefined;
48
+ return typeof name === 'string' && name.length > 0 ? name : 'Object';
49
+ });
50
+
51
+ cleanupDebug(label, { activeHandleCount: handles.length, activeHandles: names });
52
+ }
@@ -9,6 +9,7 @@
9
9
 
10
10
  import { Column, type Table, tableFromColumns } from '@uwdata/flechette';
11
11
  import type { CapacityStatsEntry } from './arrow/capacityStats.js';
12
+ import { cleanupDebug } from './cleanupDiagnostics.js';
12
13
  import { convertSpanTreeToArrowTable } from './convertToArrow.js';
13
14
  import type { SpanBufferConstructor } from './spanBuffer.js';
14
15
  import type { AnySpanBuffer, OpMetadata } from './types.js';
@@ -27,6 +28,12 @@ function isNodeTimer(value: unknown): value is NodeJS.Timeout {
27
28
  return typeof value === 'object' && value !== null && typeof Reflect.get(value, 'hasRef') === 'function';
28
29
  }
29
30
 
31
+ function unrefTimer(timer: unknown): void {
32
+ if (isNodeTimer(timer)) {
33
+ timer.unref();
34
+ }
35
+ }
36
+
30
37
  function mergeTables(first: Table, rest: Table[]): Table {
31
38
  if (rest.length === 0) return first;
32
39
 
@@ -172,17 +179,20 @@ export class FlushScheduler {
172
179
  this.isRunning = true;
173
180
  this.lastFlushTime = Date.now();
174
181
  this.lastActivityTime = Date.now();
182
+ cleanupDebug('flushScheduler.start', this.config);
175
183
 
176
184
  // Set up periodic flush timer
177
185
  this.flushTimer = setInterval(() => {
178
186
  this.checkFlushConditions();
179
187
  }, 1000); // Check every second
188
+ unrefTimer(this.flushTimer);
180
189
 
181
190
  // Set up idle detection timer
182
191
  if (this.config.idleDetection) {
183
192
  this.idleTimer = setInterval(() => {
184
193
  this.checkIdleFlush();
185
194
  }, this.config.idleTimeout);
195
+ unrefTimer(this.idleTimer);
186
196
  }
187
197
 
188
198
  // Set up memory pressure timer (Node.js only)
@@ -190,6 +200,7 @@ export class FlushScheduler {
190
200
  this.memoryTimer = setInterval(() => {
191
201
  this.checkMemoryPressure();
192
202
  }, 2000); // Check every 2 seconds
203
+ unrefTimer(this.memoryTimer);
193
204
  }
194
205
  }
195
206
 
@@ -199,6 +210,7 @@ export class FlushScheduler {
199
210
  stop(): void {
200
211
  if (!this.isRunning) return;
201
212
 
213
+ cleanupDebug('flushScheduler.stop:start', { pendingBuffers: this.buffers.size });
202
214
  this.isRunning = false;
203
215
 
204
216
  if (this.flushTimer) {
@@ -215,6 +227,7 @@ export class FlushScheduler {
215
227
  clearInterval(this.memoryTimer);
216
228
  this.memoryTimer = undefined;
217
229
  }
230
+ cleanupDebug('flushScheduler.stop:end', { pendingBuffers: this.buffers.size });
218
231
  }
219
232
 
220
233
  /**
@@ -434,6 +447,12 @@ export class FlushScheduler {
434
447
  }
435
448
  } catch (error) {
436
449
  console.error('Error in flush handler:', error);
450
+ cleanupDebug('flushScheduler.doFlush:error', {
451
+ reason,
452
+ totalRows,
453
+ totalBuffers,
454
+ pendingBuffers: this.buffers.size,
455
+ });
437
456
  // Do NOT reset buffers on failure to avoid data loss
438
457
  }
439
458
  }
@@ -7,6 +7,7 @@
7
7
  * @module sqlite-async-writer
8
8
  */
9
9
 
10
+ import { cleanupDebug } from '../cleanupDiagnostics.js';
10
11
  import type { LogSchema } from '../schema/LogSchema.js';
11
12
  import type { AnySpanBuffer } from '../types.js';
12
13
  import {
@@ -82,6 +83,10 @@ export class SQLiteAsyncTraceWriter {
82
83
  }
83
84
 
84
85
  async flush(rootBuffer: AnySpanBuffer): Promise<void> {
86
+ cleanupDebug('sqliteAsyncWriter.flush:start', {
87
+ initialized: this.initialized,
88
+ statementCacheSize: this.insertStmtCache.size,
89
+ });
85
90
  await this.init();
86
91
  for (const segment of walkSpanSegments(rootBuffer)) {
87
92
  await this.ensureColumns(segment.buffer._logSchema);
@@ -93,9 +98,12 @@ export class SQLiteAsyncTraceWriter {
93
98
  await insertStmt.run(...buildInsertParams(segment, row, activeUserFields));
94
99
  }
95
100
  }
101
+ cleanupDebug('sqliteAsyncWriter.flush:end', { statementCacheSize: this.insertStmtCache.size });
96
102
  }
97
103
 
98
104
  async close(): Promise<void> {
105
+ cleanupDebug('sqliteAsyncWriter.close:start', { statementCacheSize: this.insertStmtCache.size });
99
106
  await this.db.close();
107
+ cleanupDebug('sqliteAsyncWriter.close:end');
100
108
  }
101
109
  }
@@ -15,6 +15,7 @@
15
15
  * @module sqlite-writer
16
16
  */
17
17
 
18
+ import { cleanupDebug } from '../cleanupDiagnostics.js';
18
19
  import type { LogSchema } from '../schema/LogSchema.js';
19
20
  import type { AnySpanBuffer } from '../types.js';
20
21
  import {
@@ -112,17 +113,22 @@ export class SQLiteTraceWriter {
112
113
 
113
114
  /** Write a root SpanBuffer tree to the database */
114
115
  flush(rootBuffer: AnySpanBuffer): void {
116
+ cleanupDebug('sqliteWriter.flush:start', { statementCacheSize: this.insertStmtCache.size });
115
117
  this.db.exec('BEGIN IMMEDIATE');
116
118
  try {
117
119
  this.flushAllSegments(rootBuffer);
118
120
  this.db.exec('COMMIT');
121
+ cleanupDebug('sqliteWriter.flush:end', { statementCacheSize: this.insertStmtCache.size });
119
122
  } catch (error) {
120
123
  this.db.exec('ROLLBACK');
124
+ cleanupDebug('sqliteWriter.flush:error', { statementCacheSize: this.insertStmtCache.size });
121
125
  throw error;
122
126
  }
123
127
  }
124
128
 
125
129
  close(): void {
130
+ cleanupDebug('sqliteWriter.close:start', { statementCacheSize: this.insertStmtCache.size });
126
131
  this.db.close();
132
+ cleanupDebug('sqliteWriter.close:end');
127
133
  }
128
134
  }
@@ -54,6 +54,7 @@ import {
54
54
  mock,
55
55
  } from 'bun:test';
56
56
  import { AsyncLocalStorage } from 'node:async_hooks';
57
+ import { cleanupDebug, cleanupDebugActiveHandles } from '../cleanupDiagnostics.js';
57
58
  import { defineOpContext } from '../defineOpContext.js';
58
59
  import { JsBufferStrategy } from '../JsBufferStrategy.js';
59
60
  import type { SpanContext } from '../opContext/spanContextTypes.js';
@@ -270,7 +271,9 @@ function createRootTracer<B extends OpContextBinding>({
270
271
  async function closeTracer<B extends OpContextBinding>(tracer: Tracer<B>): Promise<void> {
271
272
  const close = Reflect.get(tracer, 'close');
272
273
  if (typeof close === 'function') {
274
+ cleanupDebug('tracer.close:start', { tracer: tracer.constructor.name });
273
275
  await close.call(tracer);
276
+ cleanupDebug('tracer.close:end', { tracer: tracer.constructor.name });
274
277
  }
275
278
  }
276
279
 
@@ -531,19 +534,26 @@ function createTestTracerInstance<B extends OpContextBinding, TExt extends Schem
531
534
  });
532
535
 
533
536
  _afterAll(async () => {
537
+ cleanupDebug('instance.afterAll:start');
538
+ cleanupDebugActiveHandles('instance.afterAll:handles:start');
534
539
  if (resolveTestRun) {
540
+ cleanupDebug('instance.rootTrace:resolve');
535
541
  resolveTestRun();
536
542
  resolveTestRun = null;
537
543
  }
538
544
 
539
545
  if (rootTracePromise) {
546
+ cleanupDebug('instance.rootTrace:await:start');
540
547
  await rootTracePromise;
548
+ cleanupDebug('instance.rootTrace:await:end');
541
549
  rootTracePromise = null;
542
550
  }
543
551
 
544
552
  if (tracer) {
545
553
  try {
554
+ cleanupDebug('instance.tracer.flush:start', { tracer: tracer.constructor.name });
546
555
  await tracer.flush();
556
+ cleanupDebug('instance.tracer.flush:end', { tracer: tracer.constructor.name });
547
557
  if (options?.sqlite && rootCtx) {
548
558
  const traceId = rootCtx.buffer.trace_id;
549
559
  const dbPath = options.sqlite.dbPath ?? '.trace-results.db';
@@ -553,6 +563,8 @@ function createTestTracerInstance<B extends OpContextBinding, TExt extends Schem
553
563
  console.error('[lmao/testing] SQLite flush error:', e);
554
564
  } finally {
555
565
  await closeTracer(tracer);
566
+ cleanupDebugActiveHandles('instance.afterAll:handles:end');
567
+ cleanupDebug('instance.afterAll:end');
556
568
  }
557
569
  }
558
570
  });
@@ -635,20 +647,27 @@ export function initTraceTestRun<B extends OpContextBinding>(opContext: B, optio
635
647
 
636
648
  // Register global teardown — resolve root, wait for span-end, then flush tracer outputs
637
649
  _afterAll(async () => {
650
+ cleanupDebug('global.afterAll:start');
651
+ cleanupDebugActiveHandles('global.afterAll:handles:start');
638
652
  // Resolve the root promise — triggers span-end write via _executeWithContext .then()
639
653
  if (_resolveTestRun) {
654
+ cleanupDebug('global.rootTrace:resolve');
640
655
  _resolveTestRun();
641
656
  _resolveTestRun = null;
642
657
  }
643
658
  // Await the trace promise so span-end is written to the buffer before flushing
644
659
  if (_rootTracePromise) {
660
+ cleanupDebug('global.rootTrace:await:start');
645
661
  await _rootTracePromise;
662
+ cleanupDebug('global.rootTrace:await:end');
646
663
  _rootTracePromise = null;
647
664
  }
648
665
 
649
666
  if (_tracer) {
650
667
  try {
668
+ cleanupDebug('global.tracer.flush:start', { tracer: _tracer.constructor.name });
651
669
  await _tracer.flush();
670
+ cleanupDebug('global.tracer.flush:end', { tracer: _tracer.constructor.name });
652
671
  if (options?.sqlite && _rootCtx) {
653
672
  const traceId = _rootCtx.buffer.trace_id;
654
673
  const dbPath = options.sqlite.dbPath ?? '.trace-results.db';
@@ -658,6 +677,8 @@ export function initTraceTestRun<B extends OpContextBinding>(opContext: B, optio
658
677
  console.error('[lmao/testing] SQLite flush error:', e);
659
678
  } finally {
660
679
  await closeTracer(_tracer);
680
+ cleanupDebugActiveHandles('global.afterAll:handles:end');
681
+ cleanupDebug('global.afterAll:end');
661
682
  }
662
683
  }
663
684
  });
@@ -1,3 +1,4 @@
1
+ import { cleanupDebug } from '../cleanupDiagnostics.js';
1
2
  import type { OpContextBinding } from '../opContext/types.js';
2
3
  import { Tracer, type TracerOptions } from '../tracer.js';
3
4
  import type { SpanBuffer } from '../types.js';
@@ -59,7 +60,9 @@ export class CompositeTracer<B extends OpContextBinding = OpContextBinding> exte
59
60
 
60
61
  override async flush(): Promise<void> {
61
62
  for (const tracer of this.delegates) {
63
+ cleanupDebug('compositeTracer.flush:delegate:start', { tracer: tracer.constructor.name });
62
64
  await tracer.flush();
65
+ cleanupDebug('compositeTracer.flush:delegate:end', { tracer: tracer.constructor.name });
63
66
  }
64
67
  }
65
68
 
@@ -68,7 +71,9 @@ export class CompositeTracer<B extends OpContextBinding = OpContextBinding> exte
68
71
  if (hasClose(tracer)) {
69
72
  const { close } = tracer;
70
73
  if (close) {
74
+ cleanupDebug('compositeTracer.close:delegate:start', { tracer: tracer.constructor.name });
71
75
  await close.call(tracer);
76
+ cleanupDebug('compositeTracer.close:delegate:end', { tracer: tracer.constructor.name });
72
77
  }
73
78
  }
74
79
  }
@@ -1,3 +1,4 @@
1
+ import { cleanupDebug } from '../cleanupDiagnostics.js';
1
2
  import type { OpContextBinding } from '../opContext/types.js';
2
3
  import { SQLiteAsyncTraceWriter } from '../sqlite/sqlite-async-writer.js';
3
4
  import type { AsyncSQLiteDatabase, SyncSQLiteDatabase } from '../sqlite/sqlite-db.js';
@@ -33,7 +34,9 @@ export class SQLiteTracer<B extends OpContextBinding = OpContextBinding> extends
33
34
  }
34
35
 
35
36
  onTraceEnd(rootBuffer: SpanBuffer<B['logBinding']['logSchema']>): void {
37
+ cleanupDebug('sqliteTracer.onTraceEnd:flush:start', { rows: rootBuffer._writeIndex });
36
38
  this.writer.flush(rootBuffer);
39
+ cleanupDebug('sqliteTracer.onTraceEnd:flush:end');
37
40
  }
38
41
 
39
42
  onSpanStart(_childBuffer: SpanBuffer<B['logBinding']['logSchema']>): void {
@@ -49,7 +52,9 @@ export class SQLiteTracer<B extends OpContextBinding = OpContextBinding> extends
49
52
  }
50
53
 
51
54
  async close(): Promise<void> {
55
+ cleanupDebug('sqliteTracer.close:start');
52
56
  this.writer.close();
57
+ cleanupDebug('sqliteTracer.close:end');
53
58
  }
54
59
  }
55
60
 
@@ -96,6 +101,7 @@ export class SQLiteAsyncTracer<B extends OpContextBinding = OpContextBinding> ex
96
101
  }
97
102
 
98
103
  override async flush(): Promise<void> {
104
+ cleanupDebug('sqliteAsyncTracer.flush:start');
99
105
  await this.pendingWrites;
100
106
  if (this.pendingErrors.length > 0) {
101
107
  const errors = this.pendingErrors;
@@ -105,11 +111,14 @@ export class SQLiteAsyncTracer<B extends OpContextBinding = OpContextBinding> ex
105
111
  }
106
112
  throw new AggregateError(errors, `SQLiteAsyncTracer flush failed for ${errors.length} trace writes`);
107
113
  }
114
+ cleanupDebug('sqliteAsyncTracer.flush:end');
108
115
  }
109
116
 
110
117
  async close(): Promise<void> {
118
+ cleanupDebug('sqliteAsyncTracer.close:start');
111
119
  await this.flush();
112
120
  const writer = await this.writerPromise;
113
121
  await writer.close();
122
+ cleanupDebug('sqliteAsyncTracer.close:end');
114
123
  }
115
124
  }
@@ -132,9 +132,9 @@ export enum SizeClass {
132
132
  }
133
133
 
134
134
  export interface WasmAllocatorOptions {
135
- /** Initial memory pages (64KB each). Default: 17 (~1MB) */
135
+ /** Initial memory pages (64KB each). Values below the module minimum are clamped. */
136
136
  initialPages?: number;
137
- /** Maximum memory pages. Default: 16384 (1GB) */
137
+ /** Maximum memory pages. Values below the effective initial page count are clamped. */
138
138
  maxPages?: number;
139
139
  /** Default capacity (rows per span buffer). Default: 64 */
140
140
  capacity?: number;
@@ -225,7 +225,7 @@ function isWasmExports(value: unknown): value is WasmExports {
225
225
  // Implementation
226
226
  // =============================================================================
227
227
 
228
- const DEFAULT_INITIAL_PAGES = 17; // ~1MB - matches WASM module minimum
228
+ const MIN_INITIAL_PAGES = 17; // ~1MB - matches WASM module minimum
229
229
  const DEFAULT_MAX_PAGES = 16384; // 1GB max (can grow up to this)
230
230
  const DEFAULT_CAPACITY = 64;
231
231
 
@@ -427,8 +427,8 @@ async function getWasmModule(): Promise<WebAssembly.Module> {
427
427
  * Buddy allocation enables efficient memory management across different capacities.
428
428
  */
429
429
  export async function createWasmAllocator(options?: WasmAllocatorOptions): Promise<WasmAllocator> {
430
- const initialPages = options?.initialPages ?? DEFAULT_INITIAL_PAGES;
431
- const maxPages = options?.maxPages ?? DEFAULT_MAX_PAGES;
430
+ const initialPages = Math.max(options?.initialPages ?? MIN_INITIAL_PAGES, MIN_INITIAL_PAGES);
431
+ const maxPages = Math.max(options?.maxPages ?? DEFAULT_MAX_PAGES, initialPages);
432
432
  const capacity = options?.capacity ?? DEFAULT_CAPACITY;
433
433
 
434
434
  // Create memory
@@ -451,8 +451,8 @@ export async function createWasmAllocator(options?: WasmAllocatorOptions): Promi
451
451
  * Synchronous version for when WASM is pre-loaded.
452
452
  */
453
453
  export function createWasmAllocatorSync(wasmModule: WebAssembly.Module, options?: WasmAllocatorOptions): WasmAllocator {
454
- const initialPages = options?.initialPages ?? DEFAULT_INITIAL_PAGES;
455
- const maxPages = options?.maxPages ?? DEFAULT_MAX_PAGES;
454
+ const initialPages = Math.max(options?.initialPages ?? MIN_INITIAL_PAGES, MIN_INITIAL_PAGES);
455
+ const maxPages = Math.max(options?.maxPages ?? DEFAULT_MAX_PAGES, initialPages);
456
456
  const capacity = options?.capacity ?? DEFAULT_CAPACITY;
457
457
 
458
458
  // Create memory