bun-sqlite-for-rxdb 1.0.1 → 1.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.
Files changed (88) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/connection-pool.d.ts +4 -0
  3. package/dist/connection-pool.d.ts.map +1 -0
  4. package/{src/index.ts → dist/index.d.ts} +1 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +13220 -0
  7. package/dist/instance.d.ts +42 -0
  8. package/dist/instance.d.ts.map +1 -0
  9. package/dist/query/builder.d.ts +6 -0
  10. package/dist/query/builder.d.ts.map +1 -0
  11. package/dist/query/operators.d.ts +21 -0
  12. package/dist/query/operators.d.ts.map +1 -0
  13. package/dist/query/schema-mapper.d.ts +8 -0
  14. package/dist/query/schema-mapper.d.ts.map +1 -0
  15. package/dist/query/smart-regex.d.ts +6 -0
  16. package/dist/query/smart-regex.d.ts.map +1 -0
  17. package/dist/rxdb-helpers.d.ts +28 -0
  18. package/dist/rxdb-helpers.d.ts.map +1 -0
  19. package/dist/statement-manager.d.ts +15 -0
  20. package/dist/statement-manager.d.ts.map +1 -0
  21. package/dist/storage.d.ts +4 -0
  22. package/dist/storage.d.ts.map +1 -0
  23. package/dist/types.d.ts +13 -0
  24. package/dist/types.d.ts.map +1 -0
  25. package/package.json +11 -3
  26. package/.serena/project.yml +0 -84
  27. package/ROADMAP.md +0 -532
  28. package/benchmarks/benchmark.ts +0 -145
  29. package/benchmarks/case-insensitive-10runs.ts +0 -156
  30. package/benchmarks/fts5-1m-scale.ts +0 -126
  31. package/benchmarks/fts5-before-after.ts +0 -104
  32. package/benchmarks/indexed-benchmark.ts +0 -141
  33. package/benchmarks/new-operators-benchmark.ts +0 -140
  34. package/benchmarks/query-builder-benchmark.ts +0 -88
  35. package/benchmarks/query-builder-consistency.ts +0 -109
  36. package/benchmarks/raw-better-sqlite3-10m.ts +0 -85
  37. package/benchmarks/raw-better-sqlite3.ts +0 -86
  38. package/benchmarks/raw-bun-sqlite-10m.ts +0 -85
  39. package/benchmarks/raw-bun-sqlite.ts +0 -86
  40. package/benchmarks/regex-10runs-all.ts +0 -216
  41. package/benchmarks/regex-comparison-benchmark.ts +0 -161
  42. package/benchmarks/regex-real-comparison.ts +0 -213
  43. package/benchmarks/run-10x.sh +0 -19
  44. package/benchmarks/smart-regex-benchmark.ts +0 -148
  45. package/benchmarks/sql-vs-mingo-benchmark.ts +0 -210
  46. package/benchmarks/sql-vs-mingo-comparison.ts +0 -175
  47. package/benchmarks/text-vs-jsonb.ts +0 -167
  48. package/benchmarks/wal-benchmark.ts +0 -112
  49. package/docs/architectural-patterns.md +0 -1336
  50. package/docs/id1-testsuite-journey.md +0 -839
  51. package/docs/official-test-suite-setup.md +0 -393
  52. package/nul +0 -0
  53. package/src/changestream.test.ts +0 -182
  54. package/src/cleanup.test.ts +0 -110
  55. package/src/collection-isolation.test.ts +0 -74
  56. package/src/connection-pool.test.ts +0 -102
  57. package/src/connection-pool.ts +0 -38
  58. package/src/findDocumentsById.test.ts +0 -122
  59. package/src/instance.ts +0 -382
  60. package/src/multi-instance-events.test.ts +0 -204
  61. package/src/query/and-operator.test.ts +0 -39
  62. package/src/query/builder.test.ts +0 -96
  63. package/src/query/builder.ts +0 -154
  64. package/src/query/elemMatch-operator.test.ts +0 -24
  65. package/src/query/exists-operator.test.ts +0 -28
  66. package/src/query/in-operators.test.ts +0 -54
  67. package/src/query/mod-operator.test.ts +0 -22
  68. package/src/query/nested-query.test.ts +0 -198
  69. package/src/query/not-operators.test.ts +0 -49
  70. package/src/query/operators.test.ts +0 -70
  71. package/src/query/operators.ts +0 -185
  72. package/src/query/or-operator.test.ts +0 -68
  73. package/src/query/regex-escaping-regression.test.ts +0 -43
  74. package/src/query/regex-operator.test.ts +0 -44
  75. package/src/query/schema-mapper.ts +0 -27
  76. package/src/query/size-operator.test.ts +0 -22
  77. package/src/query/smart-regex.ts +0 -52
  78. package/src/query/type-operator.test.ts +0 -37
  79. package/src/query-cache.test.ts +0 -286
  80. package/src/rxdb-helpers.test.ts +0 -348
  81. package/src/rxdb-helpers.ts +0 -262
  82. package/src/schema-version-isolation.test.ts +0 -126
  83. package/src/statement-manager.ts +0 -69
  84. package/src/storage.test.ts +0 -589
  85. package/src/storage.ts +0 -21
  86. package/src/types.ts +0 -14
  87. package/test/rxdb-test-suite.ts +0 -27
  88. 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
- });