bun-sqlite-for-rxdb 1.1.3 → 1.3.1

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,379 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.3.0] - 2026-02-26
4
+
5
+ ### Added
6
+ - **Bun-optimized stable-stringify for deterministic JSON**
7
+ - Custom implementation optimized for Bun's JavaScriptCore engine
8
+ - 25x faster than baseline (536K ops/sec average)
9
+ - 49x faster for Mango queries (1.04M ops/sec)
10
+ - Eliminates cache key collisions between undefined and null
11
+ - Safe toJSON error handling (returns "[Error: message]" instead of crashing)
12
+
13
+ ### Performance 🔥
14
+ - **stable-stringify optimizations: 10-65% faster**
15
+ - Small objects: +65% faster (691K → 1.1M ops/sec)
16
+ - Overall average: +10% faster (646K → 714K ops/sec)
17
+ - Optimized for common case (simple Mango queries with 5-20 keys)
18
+ - **SQL query optimizations**
19
+ - Push ORDER BY/LIMIT/OFFSET to SQL layer (eliminates in-memory sorting overhead)
20
+ - Batch INSERT operations for better throughput
21
+ - **Regex cache: O(1) FIFO eviction**
22
+ - Eliminates cache management overhead
23
+ - Constant-time eviction vs linear scan
24
+
25
+ ### Fixed 🔥
26
+ - **Query cache collision between undefined and null**
27
+ - Fixed cache key collision where `{ age: undefined }` and `{ age: null }` produced identical keys
28
+ - stable-stringify now omits undefined values (matches JSON.stringify behavior)
29
+ - Prevents cache pollution and wrong SQL being returned
30
+ - 30x faster performance (645K ops/sec)
31
+ - **toJSON error handling in stableStringify**
32
+ - Add callSafe helper to catch toJSON errors instead of crashing
33
+ - Returns "[Error: <message>]" format for failed toJSON calls
34
+ - Prevents application crashes from buggy toJSON implementations
35
+ - **$elemMatch operator fixes**
36
+ - Handle non-operator fields and nested operators correctly
37
+ - Added 6 missing operators: $exists, $size, $mod, $not, $and, $or
38
+ - Fixed 3 edge cases: multi-field objects, nested object values, dot notation paths
39
+ - **SQL operator precedence**
40
+ - Add proper parentheses for $or operator precedence (AND > OR in SQL)
41
+ - Fixed 3 test expectations that were checking for incorrect SQL
42
+ - **Input validation to prevent data corruption crashes**
43
+ - Validate at function boundaries (buildWhereClause, processSelector, operators)
44
+ - Prevents crashes on null/undefined/wrong types
45
+ - Fixed 17 data corruption test failures
46
+ - **Null checks in not-operators tests**
47
+ - Add proper null validation to prevent edge case failures
48
+
49
+ ### Changed
50
+ - **Removed Mingo dependency**
51
+ - Simplified query routing by using ourMemory regex matcher for all fallback cases
52
+ - Eliminates 519 lines from lockfile
53
+ - Reduces bundle size and dependency complexity
54
+ - All regex queries now use custom LRU-cached matcher
55
+ - **buildWhereClause now returns nullable**
56
+ - Returns null for untranslatable queries (cleaner API)
57
+ - Enables proper fallback to in-memory filtering
58
+ - Updated all unit tests for new signature
59
+
60
+ ### Technical Details
61
+ - All 346 tests passing (17 data corruption tests fixed)
62
+ - No regressions in query or write performance
63
+ - stable-stringify uses manual loops (no .map() overhead)
64
+ - Custom insertion sort for arrays <100 elements (threshold optimized)
65
+ - Proper type safety: no `any` types in stable-stringify implementation
66
+ - Query cache now properly handles undefined vs null distinction
67
+
68
+ ---
69
+
70
+ ## [1.2.8] - 2026-02-25
71
+
72
+ ### Performance 🔥
73
+ - **PRAGMA optimizations for read-heavy workloads**
74
+ - Added `PRAGMA mmap_size = 268435456` (256MB, configurable via `mmapSize` setting)
75
+ - Added `PRAGMA temp_store = MEMORY` (10-20% faster complex queries)
76
+ - Added `PRAGMA locking_mode = NORMAL` (multi-instance compatibility)
77
+ - 256MB mmap_size is industry standard (GrapheneOS, Android apps, desktop tools)
78
+ - Eliminates double-copy for reads, shares OS page cache directly
79
+
80
+ ### Added
81
+ - **Configurable mmap_size setting**
82
+ - New `mmapSize` option in `BunSQLiteStorageSettings`
83
+ - Default: 268435456 bytes (256MB) - industry standard
84
+ - Set to 0 to disable (recommended for iOS)
85
+ - Automatically skipped for in-memory databases
86
+ - **4 comprehensive behavior tests**
87
+ - Transaction queue prevents race conditions
88
+ - mmap_size improves read performance at scale
89
+ - temp_store MEMORY improves complex query performance
90
+ - mmapSize can be disabled without breaking functionality
91
+
92
+ ### Technical Details
93
+ - mmap_size default validated against production libraries:
94
+ - GrapheneOS AttestationServer: 256MB
95
+ - WechatExporter: 256MB
96
+ - Android ArchiveTune: 256MB
97
+ - better-sqlite3 tests: Fresh DB per test pattern
98
+ - temp_store = MEMORY: Keeps temporary tables/indexes in RAM
99
+ - locking_mode = NORMAL: Allows multiple connections (vs EXCLUSIVE)
100
+ - All 215 tests passing (211 + 4 behavior tests)
101
+ - No regressions in query or write performance
102
+
103
+ ---
104
+
105
+ ## [1.2.7] - 2026-02-25
106
+
107
+ ### Fixed 🔥
108
+ - **Transaction queue for bulkWrite: Prevents race conditions**
109
+ - Added `sqliteTransaction()` helper to serialize concurrent writes
110
+ - Wraps bulkWrite in transaction queue (BEGIN IMMEDIATE → COMMIT/ROLLBACK)
111
+ - Prevents data corruption from parallel bulkWrite calls
112
+ - SQLite doesn't support concurrent writes - queue ensures serialization
113
+
114
+ ### Added
115
+ - **7 comprehensive transaction queue tests**
116
+ - Tests for successful transactions, rollback on error
117
+ - Concurrent write serialization verification
118
+ - Race condition prevention tests
119
+ - Error preservation and handler result tests
120
+
121
+ ### Technical Details
122
+ - Transaction queue uses WeakMap to track per-database queues
123
+ - BEGIN IMMEDIATE ensures exclusive write lock
124
+ - Automatic ROLLBACK on errors
125
+ - All 211 tests passing (7 new transaction queue tests)
126
+ - No performance regression (transactions were already implicit)
127
+
128
+ ---
129
+
130
+ ## [1.2.6] - 2026-02-25
131
+
132
+ ### Performance 🔥
133
+ - **Statement caching in all() and get(): 35% variance reduction**
134
+ - Added LRU statement caching to all() and get() methods
135
+ - Previously only run() had caching, causing 22% query variance
136
+ - queryEq: 5.43ms → 3.52ms StdDev (35% reduction)
137
+ - queryRepeated: 4.25ms → 3.87ms StdDev (9% reduction)
138
+ - 6.8x faster for cached queries (performance test)
139
+
140
+ ### Added
141
+ - **Linus-style close() safety**
142
+ - close() now throws on use-after-close (prevents resource leaks)
143
+ - Matches industry standard (file handles, DB connections, streams)
144
+ - Prevents silent failures and memory leaks
145
+ - **20 comprehensive StatementManager tests**
146
+ - Cache hits/misses, LRU eviction, boundary conditions
147
+ - Multiple managers isolation, statement finalization
148
+ - Stress tests: 10k queries in 81ms (8.17µs per query)
149
+
150
+ ### Technical Details
151
+ - Statement cache uses same LRU pattern as run() method
152
+ - MAX_STATEMENTS = 500 with proper finalization on eviction
153
+ - close() sets flag and throws Error on subsequent use
154
+ - All 204 tests passing (20 new StatementManager tests)
155
+ - No regressions in query or write performance
156
+
157
+ ---
158
+
159
+ ## [1.2.5] - 2026-02-25
160
+
161
+ ### Performance 🔥
162
+ - **Bounded statement cache: Prevents memory leaks**
163
+ - Added MAX_STATEMENTS = 500 with LRU eviction
164
+ - Calls finalize() on evicted statements to free resources
165
+ - No performance regression - cache hit path unchanged
166
+ - **bulkWrite(100) optimization: 2.1x faster**
167
+ - 3.83ms → 1.82ms (Phase 1 PRAGMA optimizations showing impact at scale)
168
+
169
+ ### Changed
170
+ - **Document cache removed** (Phase 2 Iteration 5)
171
+ - Industry research: PouchDB, Dexie, LokiJS, WatermelonDB don't use document-level caching
172
+ - SQLite page cache (PRAGMA cache_size = -32000) is sufficient
173
+ - Simpler architecture, no cache invalidation complexity
174
+
175
+ ### Fixed
176
+ - **Timing test reliability on Windows**
177
+ - Switched from performance.now() to process.hrtime.bigint() for nanosecond precision
178
+ - Fixes flaky tests caused by ~1ms resolution on Windows
179
+ - Applied to "Production Scenario 3" and "Edge Case 13" tests
180
+
181
+ ### Added
182
+ - bulkWrite(100) benchmark test to measure Phase 2 impact at scale
183
+
184
+ ### Technical Details
185
+ - Statement cache bounded at 500 entries (prevents unbounded growth)
186
+ - LRU eviction: moves accessed statements to end, evicts oldest
187
+ - All 184 tests passing with reliable timing
188
+ - No regressions in query or write performance
189
+
190
+ ---
191
+
192
+ ## [1.2.4] - 2026-02-25
193
+
194
+ ### Performance 🔥
195
+ - **count() optimization: 4.5x faster at scale**
196
+ - Fixed to use `SELECT COUNT(*)` instead of fetching all documents
197
+ - 10k docs: 21.74ms → 5.03ms (4.32x faster)
198
+ - 100k docs: 219.44ms → 48.41ms (4.53x faster)
199
+ - **PRAGMA optimizations: 2x faster writes**
200
+ - Added `PRAGMA wal_autocheckpoint = 1000` (+12% write performance)
201
+ - Added `PRAGMA cache_size = -32000` (32MB cache for better query performance)
202
+ - Added `PRAGMA analysis_limit = 400` (faster query planning)
203
+ - bulkWrite: 0.36ms → 0.18ms (2x faster for single doc)
204
+ - **Query cache increase: 500 → 1000**
205
+ - Prevents cache thrashing in multi-collection apps
206
+ - Supports 5-10 collections × 10-20 queries each
207
+
208
+ ### Added
209
+ - Comprehensive Phase 1 benchmark suite (200 runs @ 10k docs, 100 runs @ 100k docs)
210
+ - Optimization journey documentation with baseline results and Phase 2-4 roadmap
211
+
212
+ ### Technical Details
213
+ - count() changed from O(n) to O(1) complexity
214
+ - All optimizations verified with 260/260 tests passing
215
+ - No regressions in query performance (1.01-1.03x, within margin of error)
216
+ - Low standard deviation confirms stable, reliable results
217
+
218
+ ---
219
+
220
+ ## [1.2.3] - 2026-02-25
221
+
222
+ ### Changed
223
+ - **Code Organization**
224
+ - Reorganized tests into unit/integration/benchmarks structure
225
+ - Added TypeScript path aliases ($app/* → src/*) for cleaner imports
226
+ - Updated all test imports to use path aliases
227
+ - Eliminated all `any` types from core modules (src/)
228
+ - Removed obsolete test files and old benchmark directory
229
+
230
+ ### Technical Details
231
+ - Zero `any` types in src/ (instance.ts, rxdb-helpers.ts, statement-manager.ts, builder.ts)
232
+ - Proper TypeScript types: `SQLQueryBindings[]`, `RxAttachmentData`, generic `all<T>()`
233
+ - Test structure: test/unit/, test/unit/operators/, test/integration/, test/benchmarks/
234
+ - Path aliases configured in tsconfig.json
235
+
236
+ ### Test Results
237
+ - 181/184 tests passing (3 pre-existing regex bugs)
238
+ - All type safety improvements verified
239
+
240
+ ---
241
+
242
+ ## [1.2.2] - 2026-02-24
243
+
244
+ ### Fixed
245
+ - **$type Operator** (SQL Translation)
246
+ - Fixed translateType() signature: now requires jsonColumn, fieldName, and type parameters
247
+ - Rewritten to use SQLite's json_type() for all 6 RxDB types (was using typeof() for only 3)
248
+ - All types now translate to SQL: null, boolean, number, string, array, object
249
+ - Removed redundant canTranslateToSQL check (all types now supported)
250
+ - Fixed TypeScript error: "Expected 3 arguments, but got 2"
251
+
252
+ ### Changed
253
+ - **Architecture Simplification**
254
+ - Removed redundant ternary in translateType() (both branches identical)
255
+ - Cleaner jsonPath construction: `$.${fieldName}`
256
+
257
+ ### Test Results
258
+ - 181/184 tests passing (3 pre-existing regex bugs unrelated to $type)
259
+ - All 6 $type operator tests passing
260
+
261
+ ---
262
+
263
+ ## [1.2.1] - 2026-02-24
264
+
265
+ ### Added
266
+ - **$elemMatch with $and/$or/$nor** (SQL Fast Path)
267
+ - Implemented nested logical operators inside $elemMatch queries
268
+ - Uses single EXISTS pattern with combined WHERE clause (SQLite best practice)
269
+ - Eliminates Mingo fallback for complex array matching
270
+ - 8 integration tests for $elemMatch with logical operators
271
+
272
+ ### Changed
273
+ - **Architecture Simplification**
274
+ - Removed redundant $and/$or/$nor validation from canTranslateToSQL()
275
+ - Simplified routing logic (processSelector handles all cases)
276
+
277
+ ### Performance
278
+ - $elemMatch with $and: ~24.44ms (SQL fast path)
279
+ - $elemMatch with $or: ~25.23ms (SQL fast path)
280
+ - $elemMatch with $nor: ~25.33ms (SQL fast path)
281
+
282
+ ### Test Results
283
+ - 8/8 new integration tests passing
284
+ - 180/183 total tests passing (3 pre-existing regex bugs)
285
+
286
+ ---
287
+
288
+ ## [1.2.0] - 2026-02-24
289
+
290
+ ### Added
291
+ - **$elemMatch Operator** (SQL Translation)
292
+ - Implemented with EXISTS + json_each() pattern
293
+ - Supports simple field matching inside arrays
294
+ - Foundation for nested logical operators
295
+ - **$type Array Operator**
296
+ - Added json_type check for 'array' type detection
297
+ - Completes $type operator support
298
+ - **ourMemory Regex Matcher**
299
+ - Custom LRU-cached regex matcher (100 entries, 53 lines)
300
+ - Replaces Mingo for simple case-insensitive $regex queries
301
+ - Expression index support: LOWER(field) parsing
302
+ - 6.1% performance improvement (37.41ms → 35.11ms)
303
+ - **Mingo Routing Architecture**
304
+ - Added canTranslateToSQL() for intelligent query routing
305
+ - SQL fast path for translatable queries
306
+ - Mingo fallback for complex patterns
307
+ - Schema-aware query builder
308
+
309
+ ### Changed
310
+ - **Query Builder Schema-Aware**
311
+ - translateRegex() now accepts schema and fieldName parameters
312
+ - Enables expression index detection
313
+ - Better optimization decisions
314
+
315
+ ### Fixed
316
+ - Disabled case-insensitive regex translation to SQL (correctness over performance)
317
+
318
+ ### Performance
319
+ - ourMemory regex matcher: 6.1% faster than Mingo (37.41ms → 35.11ms)
320
+ - $elemMatch: SQL fast path for simple queries
321
+
322
+ ### Test Results
323
+ - Comprehensive array edge case tests added
324
+ - All $type array tests passing
325
+
326
+ ---
327
+
328
+ ## [1.1.4] - 2026-02-24
329
+
330
+ ### Fixed
331
+ - **$nor Operator Bug** (Critical)
332
+ - Fixed $nor generating raw field names instead of json_extract() paths
333
+ - Was causing "no such column" SQLite errors
334
+ - Now schema-aware and handles JSONB storage correctly
335
+ - **Query Cache Collision** (Critical)
336
+ - Fixed cache collisions between different collections
337
+ - Cache key now includes collectionName: `v${version}_${collectionName}_${selector}`
338
+ - Prevents wrong SQL being used across collections with same schema
339
+
340
+ ### Changed
341
+ - **DRY Refactor: Unified $or/$nor Handling**
342
+ - Created `buildLogicalOperator()` helper for both operators
343
+ - Eliminated code duplication (15 lines of inline $or code)
344
+ - Both operators now use same schema-aware logic
345
+ - **buildWhereClause Signature**
346
+ - Added `collectionName` as 3rd parameter
347
+ - Ensures cache isolation between collections
348
+ - All unit tests updated for new signature
349
+
350
+ ### Added
351
+ - **DEBUG_QUERIES Logging**
352
+ - Added fallback error logging via `DEBUG_QUERIES=1` env var
353
+ - Helps debug which queries trigger fallback path
354
+ - **Comprehensive Integration Tests**
355
+ - 27 new integration tests for all SQL operators
356
+ - Covers: $eq, $ne, $gt, $gte, $lt, $lte, $in, $nin, $exists, $regex (simple), $and, $or, $not, $nor, $type (simple), $size, $mod
357
+ - Tests include edge cases and complex nested queries
358
+ - **TDD Tests for Complex Operators**
359
+ - 6 failing tests documenting fallback bug
360
+ - Tests for: complex $regex (character classes, flags), $elemMatch, $type (array/object)
361
+ - Will pass once Mingo fallback is implemented
362
+
363
+ ### Test Results
364
+ - **Local tests: 162/162 pass (100%)** ✅
365
+ - **Failing tests: 6/6 (expected - TDD tests for Mingo fallback)** ⏳
366
+ - All SQL operators working correctly
367
+ - $nor bug fixed and tested
368
+
369
+ ### Technical Details
370
+ - Removed broken `translateNor()` function
371
+ - Kept `processOperatorValue()` (used by `translateNot()`)
372
+ - Cache key now: `v${schema.version}_${collectionName}_${stringify(selector)}`
373
+ - RxDB integration verified: `this.collectionName` available and passed correctly
374
+
375
+ ---
376
+
3
377
  ## [1.1.0] - 2026-02-23
4
378
 
5
379
  ### Added