@tallyui/database 1.0.0
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/dist/index.d.ts +65 -0
- package/dist/index.js +80 -0
- package/package.json +33 -0
- package/src/create-db.ts +65 -0
- package/src/index.ts +7 -0
- package/src/replication.test.ts +97 -0
- package/src/replication.ts +50 -0
- package/src/storage.test.ts +19 -0
- package/src/storage.ts +33 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { RxDatabase, RxCollection, RxStorage } from 'rxdb';
|
|
2
|
+
import { TallyConnector, ReplicationAdapter, SyncContext } from '@tallyui/core';
|
|
3
|
+
import { RxReplicationState } from 'rxdb/plugins/replication';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The shape of a Tally database — keyed by collection name.
|
|
7
|
+
*/
|
|
8
|
+
type TallyDatabase = RxDatabase<{
|
|
9
|
+
[key: string]: RxCollection;
|
|
10
|
+
}>;
|
|
11
|
+
interface CreateDatabaseOptions {
|
|
12
|
+
/** The connector whose schemas define the collections */
|
|
13
|
+
connector: TallyConnector;
|
|
14
|
+
/** Database name (defaults to `tally_${connector.id}`) */
|
|
15
|
+
name?: string;
|
|
16
|
+
/** RxDB storage adapter (defaults to in-memory for dev/demo) */
|
|
17
|
+
storage?: any;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Create an RxDB database from a connector's schemas.
|
|
21
|
+
*
|
|
22
|
+
* This is the main entry point — give it a connector and it builds
|
|
23
|
+
* the database with the right collections and schemas.
|
|
24
|
+
*
|
|
25
|
+
* ```ts
|
|
26
|
+
* import { woocommerceConnector } from '@tallyui/connector-woocommerce';
|
|
27
|
+
* import { createTallyDatabase } from '@tallyui/database';
|
|
28
|
+
*
|
|
29
|
+
* const db = await createTallyDatabase({ connector: woocommerceConnector });
|
|
30
|
+
* const products = await db.products.find().exec();
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
declare function createTallyDatabase(options: CreateDatabaseOptions): Promise<TallyDatabase>;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Returns the appropriate RxDB storage adapter for the current platform.
|
|
37
|
+
*
|
|
38
|
+
* - Web browser: Dexie (IndexedDB)
|
|
39
|
+
* - React Native: throws with guidance to provide SQLite storage explicitly
|
|
40
|
+
* - Node/SSR/test: In-memory
|
|
41
|
+
*
|
|
42
|
+
* Override by passing a storage directly to createTallyDatabase().
|
|
43
|
+
*/
|
|
44
|
+
declare function getStorage(): RxStorage<any, any>;
|
|
45
|
+
|
|
46
|
+
interface StartReplicationOptions<RxDocType, CheckpointType = any> {
|
|
47
|
+
collection: RxCollection<RxDocType>;
|
|
48
|
+
adapter: ReplicationAdapter<RxDocType, CheckpointType>;
|
|
49
|
+
context: SyncContext;
|
|
50
|
+
/** Keep syncing after initial pull (default: true) */
|
|
51
|
+
live?: boolean;
|
|
52
|
+
/** Retry interval in ms on error (default: 5000) */
|
|
53
|
+
retryTime?: number;
|
|
54
|
+
/** Start immediately (default: true) */
|
|
55
|
+
autoStart?: boolean;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Start RxDB replication for a single collection using a ReplicationAdapter.
|
|
59
|
+
*
|
|
60
|
+
* Returns the RxReplicationState which exposes observables for monitoring
|
|
61
|
+
* and methods like cancel(), awaitInSync(), reSync().
|
|
62
|
+
*/
|
|
63
|
+
declare function startReplication<RxDocType, CheckpointType = any>({ collection, adapter, context, live, retryTime, autoStart, }: StartReplicationOptions<RxDocType, CheckpointType>): RxReplicationState<RxDocType, CheckpointType>;
|
|
64
|
+
|
|
65
|
+
export { type CreateDatabaseOptions, type StartReplicationOptions, type TallyDatabase, createTallyDatabase, getStorage, startReplication };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
// src/create-db.ts
|
|
9
|
+
import { createRxDatabase, addRxPlugin } from "rxdb";
|
|
10
|
+
import { RxDBDevModePlugin } from "rxdb/plugins/dev-mode";
|
|
11
|
+
import { getRxStorageMemory } from "rxdb/plugins/storage-memory";
|
|
12
|
+
if (process.env.NODE_ENV !== "production") {
|
|
13
|
+
addRxPlugin(RxDBDevModePlugin);
|
|
14
|
+
}
|
|
15
|
+
async function createTallyDatabase(options) {
|
|
16
|
+
const {
|
|
17
|
+
connector,
|
|
18
|
+
name = `tally_${connector.id}`,
|
|
19
|
+
storage = getRxStorageMemory()
|
|
20
|
+
} = options;
|
|
21
|
+
const db = await createRxDatabase({
|
|
22
|
+
name,
|
|
23
|
+
storage,
|
|
24
|
+
multiInstance: false,
|
|
25
|
+
ignoreDuplicate: true
|
|
26
|
+
});
|
|
27
|
+
const collectionConfigs = {};
|
|
28
|
+
for (const [collectionName, schema] of Object.entries(connector.schemas)) {
|
|
29
|
+
collectionConfigs[collectionName] = { schema };
|
|
30
|
+
}
|
|
31
|
+
await db.addCollections(collectionConfigs);
|
|
32
|
+
return db;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// src/storage.ts
|
|
36
|
+
import { getRxStorageMemory as getRxStorageMemory2 } from "rxdb/plugins/storage-memory";
|
|
37
|
+
function getStorage() {
|
|
38
|
+
if (typeof window === "undefined") {
|
|
39
|
+
return getRxStorageMemory2();
|
|
40
|
+
}
|
|
41
|
+
if (typeof navigator !== "undefined" && navigator.product === "ReactNative") {
|
|
42
|
+
throw new Error(
|
|
43
|
+
'React Native detected. Pass a storage adapter explicitly:\n import { getRxStorageSQLite } from "@tallyui/storage-sqlite";\n createTallyDatabase({ connector, storage: getRxStorageSQLite({ database }) })'
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
const { getRxStorageDexie } = __require("rxdb/plugins/storage-dexie");
|
|
47
|
+
return getRxStorageDexie();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// src/replication.ts
|
|
51
|
+
import { replicateRxCollection } from "rxdb/plugins/replication";
|
|
52
|
+
function startReplication({
|
|
53
|
+
collection,
|
|
54
|
+
adapter,
|
|
55
|
+
context,
|
|
56
|
+
live = true,
|
|
57
|
+
retryTime = 5e3,
|
|
58
|
+
autoStart = true
|
|
59
|
+
}) {
|
|
60
|
+
return replicateRxCollection({
|
|
61
|
+
collection,
|
|
62
|
+
replicationIdentifier: `${context.connectorId}-${collection.name}`,
|
|
63
|
+
pull: {
|
|
64
|
+
handler: (checkpoint, batchSize) => adapter.pull.handler(checkpoint, batchSize, context),
|
|
65
|
+
stream$: adapter.pull.stream$
|
|
66
|
+
},
|
|
67
|
+
push: adapter.push ? {
|
|
68
|
+
handler: (rows) => adapter.push.handler(rows, context),
|
|
69
|
+
batchSize: adapter.push.batchSize
|
|
70
|
+
} : void 0,
|
|
71
|
+
live,
|
|
72
|
+
retryTime,
|
|
73
|
+
autoStart
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
export {
|
|
77
|
+
createTallyDatabase,
|
|
78
|
+
getStorage,
|
|
79
|
+
startReplication
|
|
80
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tallyui/database",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "RxDB database factory for Tally UI — accepts pluggable connector schemas",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"source": "./src/index.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"source": "./src/index.ts"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"src"
|
|
19
|
+
],
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"rxdb": "16.21.1",
|
|
23
|
+
"rxjs": "7.8.2"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"@tallyui/core": "0.2.0"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsup",
|
|
30
|
+
"typecheck": "tsc --noEmit",
|
|
31
|
+
"test": "echo \"no tests yet\""
|
|
32
|
+
}
|
|
33
|
+
}
|
package/src/create-db.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { createRxDatabase, addRxPlugin, type RxDatabase, type RxCollection } from 'rxdb';
|
|
2
|
+
import { RxDBDevModePlugin } from 'rxdb/plugins/dev-mode';
|
|
3
|
+
import { getRxStorageMemory } from 'rxdb/plugins/storage-memory';
|
|
4
|
+
|
|
5
|
+
import type { TallyConnector } from '@tallyui/core';
|
|
6
|
+
|
|
7
|
+
// Enable dev mode in non-production
|
|
8
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
9
|
+
addRxPlugin(RxDBDevModePlugin);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The shape of a Tally database — keyed by collection name.
|
|
14
|
+
*/
|
|
15
|
+
export type TallyDatabase = RxDatabase<{
|
|
16
|
+
[key: string]: RxCollection;
|
|
17
|
+
}>;
|
|
18
|
+
|
|
19
|
+
export interface CreateDatabaseOptions {
|
|
20
|
+
/** The connector whose schemas define the collections */
|
|
21
|
+
connector: TallyConnector;
|
|
22
|
+
/** Database name (defaults to `tally_${connector.id}`) */
|
|
23
|
+
name?: string;
|
|
24
|
+
/** RxDB storage adapter (defaults to in-memory for dev/demo) */
|
|
25
|
+
storage?: any;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Create an RxDB database from a connector's schemas.
|
|
30
|
+
*
|
|
31
|
+
* This is the main entry point — give it a connector and it builds
|
|
32
|
+
* the database with the right collections and schemas.
|
|
33
|
+
*
|
|
34
|
+
* ```ts
|
|
35
|
+
* import { woocommerceConnector } from '@tallyui/connector-woocommerce';
|
|
36
|
+
* import { createTallyDatabase } from '@tallyui/database';
|
|
37
|
+
*
|
|
38
|
+
* const db = await createTallyDatabase({ connector: woocommerceConnector });
|
|
39
|
+
* const products = await db.products.find().exec();
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export async function createTallyDatabase(options: CreateDatabaseOptions): Promise<TallyDatabase> {
|
|
43
|
+
const {
|
|
44
|
+
connector,
|
|
45
|
+
name = `tally_${connector.id}`,
|
|
46
|
+
storage = getRxStorageMemory(),
|
|
47
|
+
} = options;
|
|
48
|
+
|
|
49
|
+
const db = await createRxDatabase({
|
|
50
|
+
name,
|
|
51
|
+
storage,
|
|
52
|
+
multiInstance: false,
|
|
53
|
+
ignoreDuplicate: true,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Build collection configs from connector schemas
|
|
57
|
+
const collectionConfigs: Record<string, { schema: any }> = {};
|
|
58
|
+
for (const [collectionName, schema] of Object.entries(connector.schemas)) {
|
|
59
|
+
collectionConfigs[collectionName] = { schema };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
await db.addCollections(collectionConfigs);
|
|
63
|
+
|
|
64
|
+
return db as TallyDatabase;
|
|
65
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { createTallyDatabase } from './create-db';
|
|
2
|
+
export type { TallyDatabase, CreateDatabaseOptions } from './create-db';
|
|
3
|
+
|
|
4
|
+
export { getStorage } from './storage';
|
|
5
|
+
|
|
6
|
+
export { startReplication } from './replication';
|
|
7
|
+
export type { StartReplicationOptions } from './replication';
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { createRxDatabase, addRxPlugin } from 'rxdb';
|
|
3
|
+
import { RxDBDevModePlugin } from 'rxdb/plugins/dev-mode';
|
|
4
|
+
import { getRxStorageMemory } from 'rxdb/plugins/storage-memory';
|
|
5
|
+
import { wrappedValidateAjvStorage } from 'rxdb/plugins/validate-ajv';
|
|
6
|
+
|
|
7
|
+
import { startReplication } from './replication';
|
|
8
|
+
import type { ReplicationAdapter, SyncContext } from '@tallyui/core';
|
|
9
|
+
|
|
10
|
+
addRxPlugin(RxDBDevModePlugin);
|
|
11
|
+
|
|
12
|
+
const storage = wrappedValidateAjvStorage({ storage: getRxStorageMemory() });
|
|
13
|
+
|
|
14
|
+
const testSchema = {
|
|
15
|
+
version: 0,
|
|
16
|
+
primaryKey: 'id',
|
|
17
|
+
type: 'object' as const,
|
|
18
|
+
properties: {
|
|
19
|
+
id: { type: 'string', maxLength: 100 },
|
|
20
|
+
name: { type: 'string' },
|
|
21
|
+
},
|
|
22
|
+
required: ['id', 'name'],
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const context: SyncContext = {
|
|
26
|
+
connectorId: 'test',
|
|
27
|
+
baseUrl: 'https://example.com',
|
|
28
|
+
headers: {},
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
describe('startReplication', () => {
|
|
32
|
+
let db: any;
|
|
33
|
+
|
|
34
|
+
beforeEach(async () => {
|
|
35
|
+
db = await createRxDatabase({
|
|
36
|
+
name: `test_${Date.now()}`,
|
|
37
|
+
storage,
|
|
38
|
+
multiInstance: false,
|
|
39
|
+
ignoreDuplicate: true,
|
|
40
|
+
});
|
|
41
|
+
await db.addCollections({ products: { schema: testSchema } });
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
afterEach(async () => {
|
|
45
|
+
await db?.close();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('starts replication and pulls documents', async () => {
|
|
49
|
+
const adapter: ReplicationAdapter<any, any> = {
|
|
50
|
+
pull: {
|
|
51
|
+
handler: vi.fn().mockResolvedValueOnce({
|
|
52
|
+
documents: [
|
|
53
|
+
{ id: '1', name: 'Widget', _deleted: false },
|
|
54
|
+
],
|
|
55
|
+
checkpoint: { id: '1' },
|
|
56
|
+
}).mockResolvedValue({
|
|
57
|
+
documents: [],
|
|
58
|
+
checkpoint: { id: '1' },
|
|
59
|
+
}),
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const state = startReplication({
|
|
64
|
+
collection: db.products,
|
|
65
|
+
adapter,
|
|
66
|
+
context,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
await state.awaitInSync();
|
|
70
|
+
|
|
71
|
+
const docs = await db.products.find().exec();
|
|
72
|
+
expect(docs).toHaveLength(1);
|
|
73
|
+
expect(docs[0].name).toBe('Widget');
|
|
74
|
+
|
|
75
|
+
await state.cancel();
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('returns RxReplicationState with observables', async () => {
|
|
79
|
+
const adapter: ReplicationAdapter<any, any> = {
|
|
80
|
+
pull: {
|
|
81
|
+
handler: vi.fn().mockResolvedValue({ documents: [], checkpoint: {} }),
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const state = startReplication({
|
|
86
|
+
collection: db.products,
|
|
87
|
+
adapter,
|
|
88
|
+
context,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
expect(state.error$).toBeDefined();
|
|
92
|
+
expect(state.active$).toBeDefined();
|
|
93
|
+
expect(state.received$).toBeDefined();
|
|
94
|
+
|
|
95
|
+
await state.cancel();
|
|
96
|
+
});
|
|
97
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { replicateRxCollection, type RxReplicationState } from 'rxdb/plugins/replication';
|
|
2
|
+
import type { RxCollection } from 'rxdb';
|
|
3
|
+
|
|
4
|
+
import type { ReplicationAdapter, SyncContext } from '@tallyui/core';
|
|
5
|
+
|
|
6
|
+
export interface StartReplicationOptions<RxDocType, CheckpointType = any> {
|
|
7
|
+
collection: RxCollection<RxDocType>;
|
|
8
|
+
adapter: ReplicationAdapter<RxDocType, CheckpointType>;
|
|
9
|
+
context: SyncContext;
|
|
10
|
+
/** Keep syncing after initial pull (default: true) */
|
|
11
|
+
live?: boolean;
|
|
12
|
+
/** Retry interval in ms on error (default: 5000) */
|
|
13
|
+
retryTime?: number;
|
|
14
|
+
/** Start immediately (default: true) */
|
|
15
|
+
autoStart?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Start RxDB replication for a single collection using a ReplicationAdapter.
|
|
20
|
+
*
|
|
21
|
+
* Returns the RxReplicationState which exposes observables for monitoring
|
|
22
|
+
* and methods like cancel(), awaitInSync(), reSync().
|
|
23
|
+
*/
|
|
24
|
+
export function startReplication<RxDocType, CheckpointType = any>({
|
|
25
|
+
collection,
|
|
26
|
+
adapter,
|
|
27
|
+
context,
|
|
28
|
+
live = true,
|
|
29
|
+
retryTime = 5000,
|
|
30
|
+
autoStart = true,
|
|
31
|
+
}: StartReplicationOptions<RxDocType, CheckpointType>): RxReplicationState<RxDocType, CheckpointType> {
|
|
32
|
+
return replicateRxCollection({
|
|
33
|
+
collection,
|
|
34
|
+
replicationIdentifier: `${context.connectorId}-${collection.name}`,
|
|
35
|
+
pull: {
|
|
36
|
+
handler: (checkpoint, batchSize) =>
|
|
37
|
+
adapter.pull.handler(checkpoint as CheckpointType | undefined, batchSize, context),
|
|
38
|
+
stream$: adapter.pull.stream$,
|
|
39
|
+
},
|
|
40
|
+
push: adapter.push
|
|
41
|
+
? {
|
|
42
|
+
handler: (rows) => adapter.push!.handler(rows, context),
|
|
43
|
+
batchSize: adapter.push.batchSize,
|
|
44
|
+
}
|
|
45
|
+
: undefined,
|
|
46
|
+
live,
|
|
47
|
+
retryTime,
|
|
48
|
+
autoStart,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// @vitest-environment node
|
|
2
|
+
import { describe, it, expect } from 'vitest';
|
|
3
|
+
|
|
4
|
+
import { getStorage } from './storage';
|
|
5
|
+
|
|
6
|
+
describe('getStorage', () => {
|
|
7
|
+
it('returns a storage object with a name property', () => {
|
|
8
|
+
const storage = getStorage();
|
|
9
|
+
expect(storage).toBeDefined();
|
|
10
|
+
expect(storage.name).toBeDefined();
|
|
11
|
+
expect(typeof storage.createStorageInstance).toBe('function');
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('returns memory storage in node/test environment', () => {
|
|
15
|
+
const storage = getStorage();
|
|
16
|
+
// In Node.js (test env), we expect memory storage
|
|
17
|
+
expect(storage.name).toBe('memory');
|
|
18
|
+
});
|
|
19
|
+
});
|
package/src/storage.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { RxStorage } from 'rxdb';
|
|
2
|
+
import { getRxStorageMemory } from 'rxdb/plugins/storage-memory';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Returns the appropriate RxDB storage adapter for the current platform.
|
|
6
|
+
*
|
|
7
|
+
* - Web browser: Dexie (IndexedDB)
|
|
8
|
+
* - React Native: throws with guidance to provide SQLite storage explicitly
|
|
9
|
+
* - Node/SSR/test: In-memory
|
|
10
|
+
*
|
|
11
|
+
* Override by passing a storage directly to createTallyDatabase().
|
|
12
|
+
*/
|
|
13
|
+
export function getStorage(): RxStorage<any, any> {
|
|
14
|
+
// Node.js / SSR / test — no persistent storage needed
|
|
15
|
+
if (typeof window === 'undefined') {
|
|
16
|
+
return getRxStorageMemory();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// React Native — no IndexedDB available.
|
|
20
|
+
// Users must provide SQLite storage explicitly via createTallyDatabase({ storage }).
|
|
21
|
+
if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {
|
|
22
|
+
throw new Error(
|
|
23
|
+
'React Native detected. Pass a storage adapter explicitly:\n' +
|
|
24
|
+
' import { getRxStorageSQLite } from "@tallyui/storage-sqlite";\n' +
|
|
25
|
+
' createTallyDatabase({ connector, storage: getRxStorageSQLite({ database }) })'
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Web browser — use Dexie (IndexedDB)
|
|
30
|
+
// Dynamic import avoided here; Dexie is bundled with rxdb.
|
|
31
|
+
const { getRxStorageDexie } = require('rxdb/plugins/storage-dexie');
|
|
32
|
+
return getRxStorageDexie();
|
|
33
|
+
}
|