fix(performance-storage): make MikroORM integration work (#1701)
* fix(performance-storage): make MikroORM integration work
Fix MikroORM performance storage integration by addressing:
- Fork EntityManager per operation (prevents identity map accumulation)
- Pass entity class to em.upsert() (MikroORM v6 API)
- Add schema generation in open() (table creation)
- Fix entity: add tableName, JSON type for statisticsData
- Add connection validation before operations
- Use direct entity class import instead of fragile glob paths
- Ensure SQLite directory exists before ORM init
- Fix type-only import to value import (verbatimModuleSyntax)
- Swap setPerformanceStatistics/checkDBConnection call order to match
MongoDBStorage pattern (in-memory stats updated first so UI stays
current even when DB is down)
- Close ORM connection on schema updateSchema() failure to prevent
resource leak when init succeeds but schema generation fails
* test(performance-storage): add unit tests for MikroOrmStorage
Add 18 tests covering constructor, close, storePerformanceStatistics,
and error handling. Uses mock ORM to avoid sqlite3 native binding
dependency in CI (--ignore-scripts). Explicit decorator types on
PerformanceRecord for tsx/esbuild compatibility.
* refactor(tests): harmonize MikroOrmStorage tests with project conventions
Use TestableMikroOrmStorage subclass with Reflect.get/set (matches
UIHttpServer pattern). Replace toBeGreaterThan with exact toBe counts.
Use .mock.calls.length consistently. Remove constructor tests that
tested implementation details.
* refactor(performance-storage): migrate from @mikro-orm/sqlite to @mikro-orm/better-sqlite
The sqlite3 native bindings used by @mikro-orm/sqlite are broken on
Node v24 (no prebuilt binaries for ABI v137, node-gyp@8.4.1 cannot
compile with Python 3.13). Replace with better-sqlite3 which provides
an identical MikroORM API surface while using a more portable native
binding.
* test(performance-storage): add integration tests for MikroOrmStorage
Add 6 integration tests that exercise real SQLite database operations
(open, persist, upsert, JSON serialization, close/reopen, multi-record).
Tests detect better-sqlite3 availability at module load and skip
gracefully via { skip: SKIP_SQLITE } when the native binding is not
built (e.g. CI with --ignore-scripts).
* fix(performance-storage): use caret version for @mikro-orm/better-sqlite and fix test JSDoc order
Use ^6.6.8 (caret) consistently across all @mikro-orm/* packages to
prevent version skew when updating dependencies. MikroORM requires all
packages be on the same version.
Also move @file JSDoc block before all imports in the test file to
match project conventions.
* refactor(performance-storage): extract ensureDBDirectory into Storage base class and audit fixes
Move duplicated directory creation logic from JsonFileStorage and
MikroOrmStorage into a shared protected method in the abstract Storage
base class. Place the call inside the existing switch case instead of
a separate if block.
Also use ^6.6.8 (caret) consistently for @mikro-orm/better-sqlite and
fix test JSDoc ordering to match project conventions.
* refactor(performance-storage): factorize serialization into base class and fix MongoDBStorage
- Extract serializePerformanceStatistics() into Storage base class (DRY)
- Update MikroOrmStorage to use shared serialization method
- Fix MongoDBStorage: remove unnecessary optional client, use shared
serialization for CircularBuffer, remove eslint-disable comments,
rename connected to opened for lifecycle clarity
- Add 20 unit tests for MongoDBStorage mirroring MikroOrmStorage pattern
- Remove 2 eslint-disable comments in Storage.handleDBStorageError by
using nullish coalescing and proper string typing
- Simplify handleDBStorageError params default spread
- Refactor JsonFileStorage.checkPerformanceRecordsFile to return fd,
eliminating non-null assertion and eslint-disable
- Remove eslint-disable in StorageFactory by casting enum to string
- Fix StorageFactory.getStorage return type: Storage (not | undefined)
- Update None.ts copyright year to 2025 for consistency
* refactor(tests): extract buildTestStatistics into shared StorageTestHelpers
* fix(lint): remove unnecessary optional chain after StorageFactory return type fix