bun-sqlite-for-rxdb 1.0.1 → 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.
Files changed (92) hide show
  1. package/CHANGELOG.md +422 -0
  2. package/dist/connection-pool.d.ts +4 -0
  3. package/{src/index.ts → dist/index.d.ts} +1 -0
  4. package/dist/index.js +13560 -0
  5. package/dist/instance.d.ts +43 -0
  6. package/dist/query/builder.d.ts +7 -0
  7. package/dist/query/operators.d.ts +28 -0
  8. package/dist/query/regex-matcher.d.ts +2 -0
  9. package/dist/query/schema-mapper.d.ts +8 -0
  10. package/dist/query/smart-regex.d.ts +7 -0
  11. package/dist/rxdb-helpers.d.ts +28 -0
  12. package/dist/src/connection-pool.d.ts +4 -0
  13. package/dist/src/index.d.ts +3 -0
  14. package/dist/src/instance.d.ts +44 -0
  15. package/dist/src/query/builder.d.ts +6 -0
  16. package/dist/src/query/operators.d.ts +27 -0
  17. package/dist/src/query/regex-matcher.d.ts +2 -0
  18. package/dist/src/query/schema-mapper.d.ts +8 -0
  19. package/dist/src/query/smart-regex.d.ts +7 -0
  20. package/dist/src/rxdb-helpers.d.ts +28 -0
  21. package/dist/src/statement-manager.d.ts +20 -0
  22. package/dist/src/storage.d.ts +4 -0
  23. package/dist/src/transaction-queue.d.ts +3 -0
  24. package/dist/src/types.d.ts +20 -0
  25. package/dist/src/utils/stable-stringify.d.ts +16 -0
  26. package/dist/statement-manager.d.ts +15 -0
  27. package/dist/storage.d.ts +4 -0
  28. package/dist/types.d.ts +13 -0
  29. package/package.json +18 -9
  30. package/.serena/project.yml +0 -84
  31. package/ROADMAP.md +0 -532
  32. package/benchmarks/benchmark.ts +0 -145
  33. package/benchmarks/case-insensitive-10runs.ts +0 -156
  34. package/benchmarks/fts5-1m-scale.ts +0 -126
  35. package/benchmarks/fts5-before-after.ts +0 -104
  36. package/benchmarks/indexed-benchmark.ts +0 -141
  37. package/benchmarks/new-operators-benchmark.ts +0 -140
  38. package/benchmarks/query-builder-benchmark.ts +0 -88
  39. package/benchmarks/query-builder-consistency.ts +0 -109
  40. package/benchmarks/raw-better-sqlite3-10m.ts +0 -85
  41. package/benchmarks/raw-better-sqlite3.ts +0 -86
  42. package/benchmarks/raw-bun-sqlite-10m.ts +0 -85
  43. package/benchmarks/raw-bun-sqlite.ts +0 -86
  44. package/benchmarks/regex-10runs-all.ts +0 -216
  45. package/benchmarks/regex-comparison-benchmark.ts +0 -161
  46. package/benchmarks/regex-real-comparison.ts +0 -213
  47. package/benchmarks/run-10x.sh +0 -19
  48. package/benchmarks/smart-regex-benchmark.ts +0 -148
  49. package/benchmarks/sql-vs-mingo-benchmark.ts +0 -210
  50. package/benchmarks/sql-vs-mingo-comparison.ts +0 -175
  51. package/benchmarks/text-vs-jsonb.ts +0 -167
  52. package/benchmarks/wal-benchmark.ts +0 -112
  53. package/docs/architectural-patterns.md +0 -1336
  54. package/docs/id1-testsuite-journey.md +0 -839
  55. package/docs/official-test-suite-setup.md +0 -393
  56. package/nul +0 -0
  57. package/src/changestream.test.ts +0 -182
  58. package/src/cleanup.test.ts +0 -110
  59. package/src/collection-isolation.test.ts +0 -74
  60. package/src/connection-pool.test.ts +0 -102
  61. package/src/connection-pool.ts +0 -38
  62. package/src/findDocumentsById.test.ts +0 -122
  63. package/src/instance.ts +0 -382
  64. package/src/multi-instance-events.test.ts +0 -204
  65. package/src/query/and-operator.test.ts +0 -39
  66. package/src/query/builder.test.ts +0 -96
  67. package/src/query/builder.ts +0 -154
  68. package/src/query/elemMatch-operator.test.ts +0 -24
  69. package/src/query/exists-operator.test.ts +0 -28
  70. package/src/query/in-operators.test.ts +0 -54
  71. package/src/query/mod-operator.test.ts +0 -22
  72. package/src/query/nested-query.test.ts +0 -198
  73. package/src/query/not-operators.test.ts +0 -49
  74. package/src/query/operators.test.ts +0 -70
  75. package/src/query/operators.ts +0 -185
  76. package/src/query/or-operator.test.ts +0 -68
  77. package/src/query/regex-escaping-regression.test.ts +0 -43
  78. package/src/query/regex-operator.test.ts +0 -44
  79. package/src/query/schema-mapper.ts +0 -27
  80. package/src/query/size-operator.test.ts +0 -22
  81. package/src/query/smart-regex.ts +0 -52
  82. package/src/query/type-operator.test.ts +0 -37
  83. package/src/query-cache.test.ts +0 -286
  84. package/src/rxdb-helpers.test.ts +0 -348
  85. package/src/rxdb-helpers.ts +0 -262
  86. package/src/schema-version-isolation.test.ts +0 -126
  87. package/src/statement-manager.ts +0 -69
  88. package/src/storage.test.ts +0 -589
  89. package/src/storage.ts +0 -21
  90. package/src/types.ts +0 -14
  91. package/test/rxdb-test-suite.ts +0 -27
  92. package/tsconfig.json +0 -31
@@ -1,74 +0,0 @@
1
- import { describe, it, expect } from 'bun:test';
2
- import { createRxDatabase, addRxPlugin } from 'rxdb';
3
- import { RxDBDevModePlugin } from 'rxdb/plugins/dev-mode';
4
- import { wrappedValidateAjvStorage } from 'rxdb/plugins/validate-ajv';
5
- import { getRxStorageBunSQLite } from './index';
6
-
7
- addRxPlugin(RxDBDevModePlugin);
8
-
9
- describe('Collection Isolation', () => {
10
- it('should NOT leak events across different collections in same database', async () => {
11
- const dbName = 'test-collection-isolation-' + Date.now();
12
-
13
- const db = await createRxDatabase({
14
- name: dbName,
15
- storage: wrappedValidateAjvStorage({ storage: getRxStorageBunSQLite() }),
16
- multiInstance: true,
17
- ignoreDuplicate: true
18
- });
19
-
20
- await db.addCollections({
21
- users: {
22
- schema: {
23
- version: 0,
24
- primaryKey: 'id',
25
- type: 'object',
26
- properties: {
27
- id: { type: 'string', maxLength: 100 },
28
- name: { type: 'string' }
29
- },
30
- required: ['id', 'name']
31
- }
32
- },
33
- posts: {
34
- schema: {
35
- version: 0,
36
- primaryKey: 'id',
37
- type: 'object',
38
- properties: {
39
- id: { type: 'string', maxLength: 100 },
40
- title: { type: 'string' }
41
- },
42
- required: ['id', 'title']
43
- }
44
- }
45
- });
46
-
47
- let usersChangeCount = 0;
48
- let postsChangeCount = 0;
49
-
50
- const usersSub = db.users.find().$.subscribe(() => {
51
- usersChangeCount++;
52
- });
53
-
54
- const postsSub = db.posts.find().$.subscribe(() => {
55
- postsChangeCount++;
56
- });
57
-
58
- await new Promise(resolve => setTimeout(resolve, 100));
59
-
60
- const initialUsersCount = usersChangeCount;
61
- const initialPostsCount = postsChangeCount;
62
-
63
- await db.posts.insert({ id: 'post1', title: 'Hello World' });
64
-
65
- await new Promise(resolve => setTimeout(resolve, 100));
66
-
67
- expect(postsChangeCount).toBeGreaterThan(initialPostsCount);
68
- expect(usersChangeCount).toBe(initialUsersCount);
69
-
70
- usersSub.unsubscribe();
71
- postsSub.unsubscribe();
72
- await db.remove();
73
- });
74
- });
@@ -1,102 +0,0 @@
1
- import { describe, test, expect, afterEach } from 'bun:test';
2
- import { getDatabase, releaseDatabase } from './connection-pool';
3
-
4
- describe('Connection Pool', () => {
5
- afterEach(() => {
6
- // Clean up any leaked connections
7
- const leaked = ['testdb1', 'testdb2', 'testdb3'];
8
- leaked.forEach(name => {
9
- try { releaseDatabase(name); } catch {}
10
- });
11
- });
12
-
13
- test('should share Database object for same databaseName', () => {
14
- const db1 = getDatabase('testdb1', ':memory:');
15
- const db2 = getDatabase('testdb1', ':memory:');
16
-
17
- expect(db1).toBe(db2); // Same object reference
18
-
19
- releaseDatabase('testdb1');
20
- releaseDatabase('testdb1');
21
- });
22
-
23
- test('should create separate Database objects for different databaseNames', () => {
24
- const db1 = getDatabase('testdb1', ':memory:');
25
- const db2 = getDatabase('testdb2', ':memory:');
26
-
27
- expect(db1).not.toBe(db2); // Different objects
28
-
29
- releaseDatabase('testdb1');
30
- releaseDatabase('testdb2');
31
- });
32
-
33
- test('should throw error when same databaseName used with different filenames', () => {
34
- getDatabase('testdb1', ':memory:');
35
-
36
- expect(() => {
37
- getDatabase('testdb1', './different.db');
38
- }).toThrow("Database 'testdb1' already opened with different filename");
39
-
40
- releaseDatabase('testdb1');
41
- });
42
-
43
- test('should increment reference count on multiple getDatabase calls', () => {
44
- const db1 = getDatabase('testdb1', ':memory:');
45
- const db2 = getDatabase('testdb1', ':memory:');
46
- const db3 = getDatabase('testdb1', ':memory:');
47
-
48
- expect(db1).toBe(db2);
49
- expect(db2).toBe(db3);
50
-
51
- // Create a table to verify database stays open
52
- db1.run('CREATE TABLE test (id INTEGER)');
53
-
54
- // Release twice - should still be open
55
- releaseDatabase('testdb1');
56
- releaseDatabase('testdb1');
57
-
58
- // Database should still work
59
- expect(() => db1.run('INSERT INTO test VALUES (1)')).not.toThrow();
60
-
61
- // Final release - now it closes
62
- releaseDatabase('testdb1');
63
- });
64
-
65
- test('should close database when reference count reaches zero', () => {
66
- const db = getDatabase('testdb1', ':memory:');
67
- db.run('CREATE TABLE test (id INTEGER)');
68
-
69
- releaseDatabase('testdb1');
70
-
71
- // Database should be closed now
72
- expect(() => db.run('INSERT INTO test VALUES (1)')).toThrow();
73
- });
74
-
75
- test('should handle multiple databases independently', () => {
76
- const db1 = getDatabase('testdb1', ':memory:');
77
- const db2 = getDatabase('testdb2', ':memory:');
78
-
79
- db1.run('CREATE TABLE test1 (id INTEGER)');
80
- db2.run('CREATE TABLE test2 (id INTEGER)');
81
-
82
- // Close db1
83
- releaseDatabase('testdb1');
84
- expect(() => db1.run('INSERT INTO test1 VALUES (1)')).toThrow();
85
-
86
- // db2 should still work
87
- expect(() => db2.run('INSERT INTO test2 VALUES (1)')).not.toThrow();
88
-
89
- releaseDatabase('testdb2');
90
- });
91
-
92
- test('should allow reusing databaseName after full release', () => {
93
- const db1 = getDatabase('testdb1', ':memory:');
94
- releaseDatabase('testdb1');
95
-
96
- // Should be able to get a new database with same name
97
- const db2 = getDatabase('testdb1', ':memory:');
98
- expect(db2).not.toBe(db1); // Different instance (old one was closed)
99
-
100
- releaseDatabase('testdb1');
101
- });
102
- });
@@ -1,38 +0,0 @@
1
- import { Database } from 'bun:sqlite';
2
-
3
- type DatabaseState = {
4
- db: Database;
5
- filename: string;
6
- openConnections: number;
7
- };
8
-
9
- const DATABASE_POOL = new Map<string, DatabaseState>();
10
-
11
- export function getDatabase(databaseName: string, filename: string): Database {
12
- let state = DATABASE_POOL.get(databaseName);
13
- if (!state) {
14
- state = {
15
- db: new Database(filename),
16
- filename,
17
- openConnections: 1
18
- };
19
- DATABASE_POOL.set(databaseName, state);
20
- } else {
21
- if (state.filename !== filename) {
22
- throw new Error(`Database '${databaseName}' already opened with different filename: '${state.filename}' vs '${filename}'`);
23
- }
24
- state.openConnections++;
25
- }
26
- return state.db;
27
- }
28
-
29
- export function releaseDatabase(databaseName: string): void {
30
- const state = DATABASE_POOL.get(databaseName);
31
- if (state) {
32
- state.openConnections--;
33
- if (state.openConnections === 0) {
34
- state.db.close();
35
- DATABASE_POOL.delete(databaseName);
36
- }
37
- }
38
- }
@@ -1,122 +0,0 @@
1
- import { describe, expect, test } from 'bun:test';
2
- import { getRxStorageBunSQLite } from './storage';
3
- import type { RxDocumentData, RxJsonSchema } from 'rxdb';
4
-
5
- interface TestDoc {
6
- id: string;
7
- name: string;
8
- age: number;
9
- _deleted: boolean;
10
- _attachments: {};
11
- _rev: string;
12
- _meta: { lwt: number };
13
- }
14
-
15
- const testSchema: RxJsonSchema<RxDocumentData<TestDoc>> = {
16
- version: 0,
17
- primaryKey: 'id',
18
- type: 'object',
19
- properties: {
20
- id: { type: 'string', maxLength: 100 },
21
- name: { type: 'string' },
22
- age: { type: 'number' },
23
- _deleted: { type: 'boolean' },
24
- _attachments: { type: 'object' },
25
- _rev: { type: 'string' },
26
- _meta: {
27
- type: 'object',
28
- properties: {
29
- lwt: { type: 'number' }
30
- },
31
- required: ['lwt']
32
- }
33
- },
34
- required: ['id', '_deleted', '_rev', '_meta']
35
- };
36
-
37
- describe('findDocumentsById - withDeleted semantics', () => {
38
- test('withDeleted=false returns ONLY non-deleted docs', async () => {
39
- const storage = getRxStorageBunSQLite();
40
- const instance = await storage.createStorageInstance({
41
- databaseName: 'test-db',
42
- collectionName: 'test-collection',
43
- schema: testSchema,
44
- options: {},
45
- multiInstance: false,
46
- devMode: false,
47
- databaseInstanceToken: 'test-token'
48
- });
49
-
50
- const docs: RxDocumentData<TestDoc>[] = [
51
- { id: 'doc1', name: 'Active', age: 25, _deleted: false, _attachments: {}, _rev: '1-a', _meta: { lwt: Date.now() } },
52
- { id: 'doc2', name: 'Deleted', age: 30, _deleted: true, _attachments: {}, _rev: '1-b', _meta: { lwt: Date.now() } },
53
- { id: 'doc3', name: 'Active2', age: 35, _deleted: false, _attachments: {}, _rev: '1-c', _meta: { lwt: Date.now() } }
54
- ];
55
-
56
- await instance.bulkWrite(docs.map(doc => ({ document: doc })), 'test');
57
-
58
- const result = await instance.findDocumentsById(['doc1', 'doc2', 'doc3'], false);
59
-
60
- expect(result.length).toBe(2);
61
- expect(result.map(d => d.id).sort()).toEqual(['doc1', 'doc3']);
62
- expect(result.every(d => d._deleted === false)).toBe(true);
63
-
64
- await instance.remove();
65
- });
66
-
67
- test('withDeleted=true returns ALL docs (deleted + non-deleted)', async () => {
68
- const storage = getRxStorageBunSQLite();
69
- const instance = await storage.createStorageInstance({
70
- databaseName: 'test-db',
71
- collectionName: 'test-collection',
72
- schema: testSchema,
73
- options: {},
74
- multiInstance: false,
75
- devMode: false,
76
- databaseInstanceToken: 'test-token'
77
- });
78
-
79
- const docs: RxDocumentData<TestDoc>[] = [
80
- { id: 'doc1', name: 'Active', age: 25, _deleted: false, _attachments: {}, _rev: '1-a', _meta: { lwt: Date.now() } },
81
- { id: 'doc2', name: 'Deleted', age: 30, _deleted: true, _attachments: {}, _rev: '1-b', _meta: { lwt: Date.now() } },
82
- { id: 'doc3', name: 'Active2', age: 35, _deleted: false, _attachments: {}, _rev: '1-c', _meta: { lwt: Date.now() } }
83
- ];
84
-
85
- await instance.bulkWrite(docs.map(doc => ({ document: doc })), 'test');
86
-
87
- const result = await instance.findDocumentsById(['doc1', 'doc2', 'doc3'], true);
88
-
89
- expect(result.length).toBe(3);
90
- expect(result.map(d => d.id).sort()).toEqual(['doc1', 'doc2', 'doc3']);
91
- expect(result.filter(d => d._deleted).length).toBe(1);
92
- expect(result.filter(d => !d._deleted).length).toBe(2);
93
-
94
- await instance.remove();
95
- });
96
-
97
- test('withDeleted=false with only deleted docs returns empty array', async () => {
98
- const storage = getRxStorageBunSQLite();
99
- const instance = await storage.createStorageInstance({
100
- databaseName: 'test-db',
101
- collectionName: 'test-collection',
102
- schema: testSchema,
103
- options: {},
104
- multiInstance: false,
105
- devMode: false,
106
- databaseInstanceToken: 'test-token'
107
- });
108
-
109
- const docs: RxDocumentData<TestDoc>[] = [
110
- { id: 'doc1', name: 'Deleted1', age: 25, _deleted: true, _attachments: {}, _rev: '1-a', _meta: { lwt: Date.now() } },
111
- { id: 'doc2', name: 'Deleted2', age: 30, _deleted: true, _attachments: {}, _rev: '1-b', _meta: { lwt: Date.now() } }
112
- ];
113
-
114
- await instance.bulkWrite(docs.map(doc => ({ document: doc })), 'test');
115
-
116
- const result = await instance.findDocumentsById(['doc1', 'doc2'], false);
117
-
118
- expect(result.length).toBe(0);
119
-
120
- await instance.remove();
121
- });
122
- });