@powersync/react-native 0.0.0-dev-20260311081226 → 0.0.0-dev-20260414110516
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.js +35 -92
- package/dist/index.js.map +1 -1
- package/lib/db/adapters/react-native-quick-sqlite/RNQSDBAdapter.d.ts +41 -27
- package/lib/db/adapters/react-native-quick-sqlite/RNQSDBAdapter.js +26 -83
- package/lib/db/adapters/react-native-quick-sqlite/RNQSDBAdapter.js.map +1 -1
- package/lib/sync/stream/ReactNativeRemote.d.ts +7 -3
- package/lib/sync/stream/ReactNativeRemote.js +7 -3
- package/lib/sync/stream/ReactNativeRemote.js.map +1 -1
- package/lib/sync/stream/ReactNativeStreamingSyncImplementation.d.ts +1 -2
- package/lib/sync/stream/ReactNativeStreamingSyncImplementation.js +2 -6
- package/lib/sync/stream/ReactNativeStreamingSyncImplementation.js.map +1 -1
- package/package.json +5 -6
- package/src/db/adapters/react-native-quick-sqlite/RNQSDBAdapter.ts +30 -101
- package/src/sync/stream/ReactNativeRemote.ts +20 -19
- package/src/sync/stream/ReactNativeStreamingSyncImplementation.ts +3 -7
|
@@ -1,41 +1,55 @@
|
|
|
1
|
-
import { BaseObserver, DBAdapter, DBAdapterListener, LockContext as PowerSyncLockContext,
|
|
1
|
+
import { BaseObserver, DBAdapter, DBAdapterListener, LockContext as PowerSyncLockContext, DBLockOptions, ConnectionPool, LockContext, Transaction } from '@powersync/common';
|
|
2
2
|
import type { QuickSQLiteConnection, LockContext as RNQSLockContext } from '@journeyapps/react-native-quick-sqlite';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*/
|
|
6
|
-
export declare class RNQSDBAdapter extends BaseObserver<DBAdapterListener> implements DBAdapter {
|
|
3
|
+
import { QueryResult, SqlExecutor } from '@powersync/common/dist/index.cjs';
|
|
4
|
+
declare class RNQSConnectionPool extends BaseObserver<DBAdapterListener> implements ConnectionPool {
|
|
7
5
|
protected baseDB: QuickSQLiteConnection;
|
|
8
6
|
name: string;
|
|
9
|
-
getAll: <T>(sql: string, parameters?: any[]) => Promise<T[]>;
|
|
10
|
-
getOptional: <T>(sql: string, parameters?: any[]) => Promise<T | null>;
|
|
11
|
-
get: <T>(sql: string, parameters?: any[]) => Promise<T>;
|
|
12
7
|
constructor(baseDB: QuickSQLiteConnection, name: string);
|
|
13
8
|
close(): void;
|
|
14
9
|
readLock<T>(fn: (tx: PowerSyncLockContext) => Promise<T>, options?: DBLockOptions): Promise<T>;
|
|
15
|
-
readTransaction<T>(fn: (tx: PowerSyncTransaction) => Promise<T>, options?: DBLockOptions): Promise<T>;
|
|
16
10
|
writeLock<T>(fn: (tx: PowerSyncLockContext) => Promise<T>, options?: DBLockOptions): Promise<T>;
|
|
17
|
-
|
|
11
|
+
generateContext<T extends RNQSLockContext>(ctx: T): QuickSqliteContext;
|
|
12
|
+
refreshSchema(): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
declare class QuickSqliteExecutor implements Omit<SqlExecutor, 'executeBatch'> {
|
|
15
|
+
readonly context: RNQSLockContext;
|
|
16
|
+
constructor(context: RNQSLockContext);
|
|
18
17
|
execute(query: string, params?: any[]): Promise<import("@journeyapps/react-native-quick-sqlite").QueryResult>;
|
|
19
18
|
/**
|
|
20
19
|
* 'executeRaw' is not implemented in RNQS, this falls back to 'execute'.
|
|
21
20
|
*/
|
|
22
21
|
executeRaw(query: string, params?: any[]): Promise<any[][]>;
|
|
22
|
+
}
|
|
23
|
+
declare const QuickSqliteContext_base: (new (...args: any[]) => {
|
|
24
|
+
getAll<T>(sql: string, parameters?: any[]): Promise<T[]>;
|
|
25
|
+
getOptional<T>(sql: string, parameters?: any[]): Promise<T | null>;
|
|
26
|
+
get<T>(sql: string, parameters?: any[]): Promise<T>;
|
|
27
|
+
executeBatch(query: string, params?: any[][]): Promise<import("@powersync/common").QueryResult>;
|
|
28
|
+
execute: (query: string, params?: any[] | undefined) => Promise<import("@powersync/common").QueryResult>;
|
|
29
|
+
executeRaw: (query: string, params?: any[] | undefined) => Promise<any[][]>;
|
|
30
|
+
}) & typeof QuickSqliteExecutor;
|
|
31
|
+
declare class QuickSqliteContext extends QuickSqliteContext_base implements LockContext {
|
|
32
|
+
}
|
|
33
|
+
declare const RNQSDBAdapter_base: (new (...args: any[]) => {
|
|
34
|
+
readTransaction<T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions): Promise<T>;
|
|
35
|
+
writeTransaction<T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions): Promise<T>;
|
|
36
|
+
getAll<T>(sql: string, parameters?: any[]): Promise<T[]>;
|
|
37
|
+
getOptional<T>(sql: string, parameters?: any[]): Promise<T | null>;
|
|
38
|
+
get<T>(sql: string, parameters?: any[]): Promise<T>;
|
|
39
|
+
execute(query: string, params?: any[]): Promise<import("@powersync/common").QueryResult>;
|
|
40
|
+
executeRaw(query: string, params?: any[]): Promise<any[][]>;
|
|
41
|
+
executeBatch(query: string, params?: any[][]): Promise<import("@powersync/common").QueryResult>;
|
|
42
|
+
name: string;
|
|
43
|
+
close: () => void | Promise<void>;
|
|
44
|
+
readLock: <T>(fn: (tx: LockContext) => Promise<T>, options?: DBLockOptions) => Promise<T>;
|
|
45
|
+
writeLock: <T>(fn: (tx: LockContext) => Promise<T>, options?: DBLockOptions) => Promise<T>;
|
|
46
|
+
refreshSchema: () => Promise<void>;
|
|
47
|
+
registerListener(listener: Partial<DBAdapterListener>): () => void;
|
|
48
|
+
}) & typeof RNQSConnectionPool;
|
|
49
|
+
/**
|
|
50
|
+
* Adapter for React Native Quick SQLite
|
|
51
|
+
*/
|
|
52
|
+
export declare class RNQSDBAdapter extends RNQSDBAdapter_base implements DBAdapter {
|
|
23
53
|
executeBatch(query: string, params?: any[][]): Promise<QueryResult>;
|
|
24
|
-
generateContext<T extends RNQSLockContext>(ctx: T): T & {
|
|
25
|
-
executeRaw: (sql: string, params?: any[]) => Promise<unknown[][]>;
|
|
26
|
-
};
|
|
27
|
-
/**
|
|
28
|
-
* This provides a top-level read only execute method which is executed inside a read-lock.
|
|
29
|
-
* This is necessary since the high level `execute` method uses a write-lock under
|
|
30
|
-
* the hood. Helper methods such as `get`, `getAll` and `getOptional` are read only,
|
|
31
|
-
* and should use this method.
|
|
32
|
-
*/
|
|
33
|
-
private readOnlyExecute;
|
|
34
|
-
/**
|
|
35
|
-
* Adds DB get utils to lock contexts and transaction contexts
|
|
36
|
-
* @param tx
|
|
37
|
-
* @returns
|
|
38
|
-
*/
|
|
39
|
-
private generateDBHelpers;
|
|
40
|
-
refreshSchema(): Promise<void>;
|
|
41
54
|
}
|
|
55
|
+
export {};
|
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
import { BaseObserver } from '@powersync/common';
|
|
2
|
-
|
|
3
|
-
* Adapter for React Native Quick SQLite
|
|
4
|
-
*/
|
|
5
|
-
export class RNQSDBAdapter extends BaseObserver {
|
|
1
|
+
import { BaseObserver, DBGetUtilsDefaultMixin, DBAdapterDefaultMixin } from '@powersync/common';
|
|
2
|
+
class RNQSConnectionPool extends BaseObserver {
|
|
6
3
|
baseDB;
|
|
7
4
|
name;
|
|
8
|
-
getAll;
|
|
9
|
-
getOptional;
|
|
10
|
-
get;
|
|
11
5
|
constructor(baseDB, name) {
|
|
12
6
|
super();
|
|
13
7
|
this.baseDB = baseDB;
|
|
@@ -16,41 +10,48 @@ export class RNQSDBAdapter extends BaseObserver {
|
|
|
16
10
|
baseDB.registerTablesChangedHook((update) => {
|
|
17
11
|
this.iterateListeners((cb) => cb.tablesUpdated?.(update));
|
|
18
12
|
});
|
|
19
|
-
const topLevelUtils = this.generateDBHelpers({
|
|
20
|
-
// Arrow function binds `this` for use in readOnlyExecute
|
|
21
|
-
execute: (sql, params) => this.readOnlyExecute(sql, params)
|
|
22
|
-
});
|
|
23
|
-
// Only assigning get helpers
|
|
24
|
-
this.getAll = topLevelUtils.getAll;
|
|
25
|
-
this.getOptional = topLevelUtils.getOptional;
|
|
26
|
-
this.get = topLevelUtils.get;
|
|
27
13
|
}
|
|
28
14
|
close() {
|
|
29
15
|
return this.baseDB.close();
|
|
30
16
|
}
|
|
31
17
|
readLock(fn, options) {
|
|
32
|
-
return this.baseDB.readLock((dbTx) => fn(this.
|
|
33
|
-
}
|
|
34
|
-
readTransaction(fn, options) {
|
|
35
|
-
return this.baseDB.readTransaction((dbTx) => fn(this.generateDBHelpers(this.generateContext(dbTx))), options);
|
|
18
|
+
return this.baseDB.readLock((dbTx) => fn(this.generateContext(dbTx)), options);
|
|
36
19
|
}
|
|
37
20
|
writeLock(fn, options) {
|
|
38
|
-
return this.baseDB.writeLock((dbTx) => fn(this.
|
|
21
|
+
return this.baseDB.writeLock((dbTx) => fn(this.generateContext(dbTx)), options);
|
|
22
|
+
}
|
|
23
|
+
generateContext(ctx) {
|
|
24
|
+
return new QuickSqliteContext(ctx);
|
|
25
|
+
}
|
|
26
|
+
async refreshSchema() {
|
|
27
|
+
await this.baseDB.refreshSchema();
|
|
39
28
|
}
|
|
40
|
-
|
|
41
|
-
|
|
29
|
+
}
|
|
30
|
+
class QuickSqliteExecutor {
|
|
31
|
+
context;
|
|
32
|
+
constructor(context) {
|
|
33
|
+
this.context = context;
|
|
42
34
|
}
|
|
43
35
|
execute(query, params) {
|
|
44
|
-
return this.
|
|
36
|
+
return this.context.execute(query, params);
|
|
45
37
|
}
|
|
46
38
|
/**
|
|
47
39
|
* 'executeRaw' is not implemented in RNQS, this falls back to 'execute'.
|
|
48
40
|
*/
|
|
49
41
|
async executeRaw(query, params) {
|
|
50
|
-
const result = await this.
|
|
42
|
+
const result = await this.context.execute(query, params);
|
|
51
43
|
const rows = result.rows?._array ?? [];
|
|
52
44
|
return rows.map((row) => Object.values(row));
|
|
53
45
|
}
|
|
46
|
+
}
|
|
47
|
+
class QuickSqliteContext extends DBGetUtilsDefaultMixin(QuickSqliteExecutor) {
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Adapter for React Native Quick SQLite
|
|
51
|
+
*/
|
|
52
|
+
export class RNQSDBAdapter extends DBAdapterDefaultMixin(RNQSConnectionPool) {
|
|
53
|
+
// We don't want the default implementation here, RNQS does not support executeBatch for lock contexts so that would
|
|
54
|
+
// be less efficient.
|
|
54
55
|
async executeBatch(query, params = []) {
|
|
55
56
|
const commands = [];
|
|
56
57
|
for (let i = 0; i < params.length; i++) {
|
|
@@ -61,63 +62,5 @@ export class RNQSDBAdapter extends BaseObserver {
|
|
|
61
62
|
rowsAffected: result.rowsAffected ? result.rowsAffected : 0
|
|
62
63
|
};
|
|
63
64
|
}
|
|
64
|
-
generateContext(ctx) {
|
|
65
|
-
return {
|
|
66
|
-
...ctx,
|
|
67
|
-
// 'executeRaw' is not implemented in RNQS, this falls back to 'execute'.
|
|
68
|
-
executeRaw: async (sql, params) => {
|
|
69
|
-
const result = await ctx.execute(sql, params);
|
|
70
|
-
const rows = result.rows?._array ?? [];
|
|
71
|
-
return rows.map((row) => Object.values(row));
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* This provides a top-level read only execute method which is executed inside a read-lock.
|
|
77
|
-
* This is necessary since the high level `execute` method uses a write-lock under
|
|
78
|
-
* the hood. Helper methods such as `get`, `getAll` and `getOptional` are read only,
|
|
79
|
-
* and should use this method.
|
|
80
|
-
*/
|
|
81
|
-
readOnlyExecute(sql, params) {
|
|
82
|
-
return this.baseDB.readLock((ctx) => ctx.execute(sql, params));
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Adds DB get utils to lock contexts and transaction contexts
|
|
86
|
-
* @param tx
|
|
87
|
-
* @returns
|
|
88
|
-
*/
|
|
89
|
-
generateDBHelpers(tx) {
|
|
90
|
-
return {
|
|
91
|
-
...tx,
|
|
92
|
-
/**
|
|
93
|
-
* Execute a read-only query and return results
|
|
94
|
-
*/
|
|
95
|
-
getAll: async (sql, parameters) => {
|
|
96
|
-
const res = await tx.execute(sql, parameters);
|
|
97
|
-
return res.rows?._array ?? [];
|
|
98
|
-
},
|
|
99
|
-
/**
|
|
100
|
-
* Execute a read-only query and return the first result, or null if the ResultSet is empty.
|
|
101
|
-
*/
|
|
102
|
-
getOptional: async (sql, parameters) => {
|
|
103
|
-
const res = await tx.execute(sql, parameters);
|
|
104
|
-
return res.rows?.item(0) ?? null;
|
|
105
|
-
},
|
|
106
|
-
/**
|
|
107
|
-
* Execute a read-only query and return the first result, error if the ResultSet is empty.
|
|
108
|
-
*/
|
|
109
|
-
get: async (sql, parameters) => {
|
|
110
|
-
const res = await tx.execute(sql, parameters);
|
|
111
|
-
const first = res.rows?.item(0);
|
|
112
|
-
if (!first) {
|
|
113
|
-
throw new Error('Result set is empty');
|
|
114
|
-
}
|
|
115
|
-
return first;
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
async refreshSchema() {
|
|
120
|
-
await this.baseDB.refreshSchema();
|
|
121
|
-
}
|
|
122
65
|
}
|
|
123
66
|
//# sourceMappingURL=RNQSDBAdapter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RNQSDBAdapter.js","sourceRoot":"","sources":["../../../../src/db/adapters/react-native-quick-sqlite/RNQSDBAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,
|
|
1
|
+
{"version":3,"file":"RNQSDBAdapter.js","sourceRoot":"","sources":["../../../../src/db/adapters/react-native-quick-sqlite/RNQSDBAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AbstractRemote, AbstractRemoteOptions, BSONImplementation,
|
|
1
|
+
import { AbstractRemote, AbstractRemoteOptions, BSONImplementation, ILogger, RemoteConnector, SyncStreamOptions } from '@powersync/common';
|
|
2
2
|
import { TextDecoder } from 'text-encoding';
|
|
3
3
|
export declare const STREAMING_POST_TIMEOUT_MS = 30000;
|
|
4
4
|
export declare class ReactNativeRemote extends AbstractRemote {
|
|
@@ -7,6 +7,10 @@ export declare class ReactNativeRemote extends AbstractRemote {
|
|
|
7
7
|
constructor(connector: RemoteConnector, logger?: ILogger, options?: Partial<AbstractRemoteOptions>);
|
|
8
8
|
getUserAgent(): string;
|
|
9
9
|
getBSON(): Promise<BSONImplementation>;
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
createTextDecoder(): TextDecoder;
|
|
11
|
+
protected get supportsStreamingBinaryResponses(): boolean;
|
|
12
|
+
protected fetchStreamRaw(options: SyncStreamOptions): Promise<{
|
|
13
|
+
isBson: boolean;
|
|
14
|
+
stream: import("@powersync/common").SimpleAsyncIterator<Uint8Array>;
|
|
15
|
+
}>;
|
|
12
16
|
}
|
|
@@ -40,14 +40,18 @@ export class ReactNativeRemote extends AbstractRemote {
|
|
|
40
40
|
createTextDecoder() {
|
|
41
41
|
return new TextDecoder();
|
|
42
42
|
}
|
|
43
|
-
|
|
43
|
+
get supportsStreamingBinaryResponses() {
|
|
44
|
+
// We have to pass textStreaming: true to get streamed responses at all, and those don't support binary data.
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
async fetchStreamRaw(options) {
|
|
44
48
|
const timeout = Platform.OS == 'android'
|
|
45
49
|
? setTimeout(() => {
|
|
46
50
|
this.logger.warn(`HTTP Streaming POST is taking longer than ${Math.ceil(STREAMING_POST_TIMEOUT_MS / 1000)} seconds to resolve. If using a debug build, please ensure Flipper Network plugin is disabled.`);
|
|
47
51
|
}, STREAMING_POST_TIMEOUT_MS)
|
|
48
52
|
: null;
|
|
49
53
|
try {
|
|
50
|
-
return await super.
|
|
54
|
+
return await super.fetchStreamRaw({
|
|
51
55
|
...options,
|
|
52
56
|
fetchOptions: {
|
|
53
57
|
...options.fetchOptions,
|
|
@@ -59,7 +63,7 @@ export class ReactNativeRemote extends AbstractRemote {
|
|
|
59
63
|
// @ts-expect-error https://github.com/react-native-community/fetch#enable-text-streaming
|
|
60
64
|
reactNative: { textStreaming: true }
|
|
61
65
|
}
|
|
62
|
-
}
|
|
66
|
+
});
|
|
63
67
|
}
|
|
64
68
|
finally {
|
|
65
69
|
if (timeout) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReactNativeRemote.js","sourceRoot":"","sources":["../../../src/sync/stream/ReactNativeRemote.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EAGd,qBAAqB,
|
|
1
|
+
{"version":3,"file":"ReactNativeRemote.js","sourceRoot":"","sources":["../../../src/sync/stream/ReactNativeRemote.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EAGd,qBAAqB,EAErB,2BAA2B,EAI5B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,gGAAgG;AAChG,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAE/C,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC;AAEhD;;;;GAIG;AACH,MAAM,wBAAyB,SAAQ,2BAA2B;IAChE,QAAQ;QACN,OAAO,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAChC,CAAC;CACF;AAED,MAAM,OAAO,iBAAkB,SAAQ,cAAc;IAEvC;IACA;IAFZ,YACY,SAA0B,EAC1B,SAAkB,qBAAqB,EACjD,OAAwC;QAExC,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE;YACvB,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC;YAClB,mBAAmB,EAAE,OAAO,EAAE,mBAAmB,IAAI,IAAI,wBAAwB,EAAE;SACpF,CAAC,CAAC;QAPO,cAAS,GAAT,SAAS,CAAiB;QAC1B,WAAM,GAAN,MAAM,CAAiC;IAOnD,CAAC;IAED,YAAY;QACV,OAAO;YACL,KAAK,CAAC,YAAY,EAAE;YACpB,wBAAwB;YACxB,gBAAgB,QAAQ,CAAC,SAAS,CAAC,kBAAkB,CAAC,KAAK,IAAI,QAAQ,CAAC,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE;YAC5G,GAAG,QAAQ,CAAC,EAAE,IAAI,QAAQ,CAAC,OAAO,EAAE;SACrC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACd,CAAC;IAED,KAAK,CAAC,OAAO;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,WAAW,EAAE,CAAC;IAC3B,CAAC;IAED,IAAc,gCAAgC;QAC5C,6GAA6G;QAC7G,OAAO,KAAK,CAAC;IACf,CAAC;IAES,KAAK,CAAC,cAAc,CAAC,OAA0B;QACvD,MAAM,OAAO,GACX,QAAQ,CAAC,EAAE,IAAI,SAAS;YACtB,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE;gBACd,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,6CAA6C,IAAI,CAAC,IAAI,CACpD,yBAAyB,GAAG,IAAI,CACjC,gGAAgG,CAClG,CAAC;YACJ,CAAC,EAAE,yBAAyB,CAAC;YAC/B,CAAC,CAAC,IAAI,CAAC;QAEX,IAAI,CAAC;YACH,OAAO,MAAM,KAAK,CAAC,cAAc,CAAC;gBAChC,GAAG,OAAO;gBACV,YAAY,EAAE;oBACZ,GAAG,OAAO,CAAC,YAAY;oBACvB;;;;uBAIG;oBACH,yFAAyF;oBACzF,WAAW,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE;iBACrC;aACF,CAAC,CAAC;QACL,CAAC;gBAAS,CAAC;YACT,IAAI,OAAO,EAAE,CAAC;gBACZ,YAAY,CAAC,OAAO,CAAC,CAAC;YACxB,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { AbstractStreamingSyncImplementation, AbstractStreamingSyncImplementationOptions, LockOptions, LockType } from '@powersync/common';
|
|
2
|
-
import { Mutex } from 'async-mutex';
|
|
1
|
+
import { AbstractStreamingSyncImplementation, AbstractStreamingSyncImplementationOptions, LockOptions, LockType, Mutex } from '@powersync/common';
|
|
3
2
|
export declare class ReactNativeStreamingSyncImplementation extends AbstractStreamingSyncImplementation {
|
|
4
3
|
locks: Map<LockType, Mutex>;
|
|
5
4
|
constructor(options: AbstractStreamingSyncImplementationOptions);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { AbstractStreamingSyncImplementation, LockType } from '@powersync/common';
|
|
2
|
-
import { Mutex } from 'async-mutex';
|
|
1
|
+
import { AbstractStreamingSyncImplementation, LockType, Mutex } from '@powersync/common';
|
|
3
2
|
/**
|
|
4
3
|
* Global locks which prevent multiple instances from syncing
|
|
5
4
|
* concurrently.
|
|
@@ -33,11 +32,8 @@ export class ReactNativeStreamingSyncImplementation extends AbstractStreamingSyn
|
|
|
33
32
|
throw new Error(`Lock type ${lockOptions.type} not found`);
|
|
34
33
|
}
|
|
35
34
|
return lock.runExclusive(async () => {
|
|
36
|
-
if (lockOptions.signal?.aborted) {
|
|
37
|
-
throw new Error('Aborted');
|
|
38
|
-
}
|
|
39
35
|
return lockOptions.callback();
|
|
40
|
-
});
|
|
36
|
+
}, lockOptions.signal);
|
|
41
37
|
}
|
|
42
38
|
}
|
|
43
39
|
//# sourceMappingURL=ReactNativeStreamingSyncImplementation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReactNativeStreamingSyncImplementation.js","sourceRoot":"","sources":["../../../src/sync/stream/ReactNativeStreamingSyncImplementation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mCAAmC,EAGnC,QAAQ,
|
|
1
|
+
{"version":3,"file":"ReactNativeStreamingSyncImplementation.js","sourceRoot":"","sources":["../../../src/sync/stream/ReactNativeStreamingSyncImplementation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mCAAmC,EAGnC,QAAQ,EACR,KAAK,EACN,MAAM,mBAAmB,CAAC;AAE3B;;;GAGG;AACH,MAAM,KAAK,GAAG,IAAI,GAAG,EAAgC,CAAC;AAEtD,MAAM,OAAO,sCAAuC,SAAQ,mCAAmC;IAC7F,KAAK,CAAuB;IAE5B,YAAY,OAAmD;QAC7D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,SAAS,EAAE,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,SAAS;QACP,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QACpC,IAAI,UAAU,IAAI,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAE,CAAC;YACpC,OAAO;QACT,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,IAAI,GAAG,EAAmB,CAAC;QACxC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,KAAK,EAAE,CAAC,CAAC;QAC3C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,KAAK,EAAE,CAAC,CAAC;QAE3C,IAAI,UAAU,EAAE,CAAC;YACf,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,UAAU,CAAI,WAA2B;QACvC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,aAAa,WAAW,CAAC,IAAI,YAAY,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YAClC,OAAO,WAAW,CAAC,QAAQ,EAAE,CAAC;QAChC,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@powersync/react-native",
|
|
3
|
-
"version": "0.0.0-dev-
|
|
3
|
+
"version": "0.0.0-dev-20260414110516",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"registry": "https://registry.npmjs.org/",
|
|
6
6
|
"access": "public"
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"type": "git",
|
|
19
19
|
"url": "git+https://github.com/powersync-ja/powersync-js.git"
|
|
20
20
|
},
|
|
21
|
-
"author": "
|
|
21
|
+
"author": "PowerSync",
|
|
22
22
|
"license": "Apache-2.0",
|
|
23
23
|
"bugs": {
|
|
24
24
|
"url": "https://github.com/powersync-ja/powersync-js/issues"
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"homepage": "https://docs.powersync.com/",
|
|
27
27
|
"peerDependencies": {
|
|
28
28
|
"@journeyapps/react-native-quick-sqlite": "^2.5.1",
|
|
29
|
-
"@powersync/common": "0.0.0-dev-
|
|
29
|
+
"@powersync/common": "0.0.0-dev-20260414110516",
|
|
30
30
|
"react": "*",
|
|
31
31
|
"react-native": "*"
|
|
32
32
|
},
|
|
@@ -36,9 +36,8 @@
|
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"
|
|
40
|
-
"@powersync/
|
|
41
|
-
"@powersync/react": "1.9.0"
|
|
39
|
+
"@powersync/common": "0.0.0-dev-20260414110516",
|
|
40
|
+
"@powersync/react": "1.10.0"
|
|
42
41
|
},
|
|
43
42
|
"devDependencies": {
|
|
44
43
|
"@craftzdog/react-native-buffer": "^6.0.5",
|
|
@@ -3,25 +3,17 @@ import {
|
|
|
3
3
|
DBAdapter,
|
|
4
4
|
DBAdapterListener,
|
|
5
5
|
LockContext as PowerSyncLockContext,
|
|
6
|
-
Transaction as PowerSyncTransaction,
|
|
7
6
|
DBLockOptions,
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
ConnectionPool,
|
|
8
|
+
DBGetUtilsDefaultMixin,
|
|
9
|
+
LockContext,
|
|
10
|
+
DBAdapterDefaultMixin,
|
|
11
|
+
Transaction
|
|
10
12
|
} from '@powersync/common';
|
|
11
|
-
import type {
|
|
12
|
-
|
|
13
|
-
LockContext as RNQSLockContext,
|
|
14
|
-
TransactionContext as RNQSTransactionContext
|
|
15
|
-
} from '@journeyapps/react-native-quick-sqlite';
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Adapter for React Native Quick SQLite
|
|
19
|
-
*/
|
|
20
|
-
export class RNQSDBAdapter extends BaseObserver<DBAdapterListener> implements DBAdapter {
|
|
21
|
-
getAll: <T>(sql: string, parameters?: any[]) => Promise<T[]>;
|
|
22
|
-
getOptional: <T>(sql: string, parameters?: any[]) => Promise<T | null>;
|
|
23
|
-
get: <T>(sql: string, parameters?: any[]) => Promise<T>;
|
|
13
|
+
import type { QuickSQLiteConnection, LockContext as RNQSLockContext } from '@journeyapps/react-native-quick-sqlite';
|
|
14
|
+
import { QueryResult, SqlExecutor } from '@powersync/common/dist/index.cjs';
|
|
24
15
|
|
|
16
|
+
class RNQSConnectionPool extends BaseObserver<DBAdapterListener> implements ConnectionPool {
|
|
25
17
|
constructor(
|
|
26
18
|
protected baseDB: QuickSQLiteConnection,
|
|
27
19
|
public name: string
|
|
@@ -31,15 +23,6 @@ export class RNQSDBAdapter extends BaseObserver<DBAdapterListener> implements DB
|
|
|
31
23
|
baseDB.registerTablesChangedHook((update) => {
|
|
32
24
|
this.iterateListeners((cb) => cb.tablesUpdated?.(update));
|
|
33
25
|
});
|
|
34
|
-
|
|
35
|
-
const topLevelUtils = this.generateDBHelpers({
|
|
36
|
-
// Arrow function binds `this` for use in readOnlyExecute
|
|
37
|
-
execute: (sql: string, params?: any[]) => this.readOnlyExecute(sql, params)
|
|
38
|
-
});
|
|
39
|
-
// Only assigning get helpers
|
|
40
|
-
this.getAll = topLevelUtils.getAll;
|
|
41
|
-
this.getOptional = topLevelUtils.getOptional;
|
|
42
|
-
this.get = topLevelUtils.get;
|
|
43
26
|
}
|
|
44
27
|
|
|
45
28
|
close() {
|
|
@@ -47,34 +30,46 @@ export class RNQSDBAdapter extends BaseObserver<DBAdapterListener> implements DB
|
|
|
47
30
|
}
|
|
48
31
|
|
|
49
32
|
readLock<T>(fn: (tx: PowerSyncLockContext) => Promise<T>, options?: DBLockOptions): Promise<T> {
|
|
50
|
-
return this.baseDB.readLock((dbTx) => fn(this.
|
|
33
|
+
return this.baseDB.readLock((dbTx) => fn(this.generateContext(dbTx)), options);
|
|
51
34
|
}
|
|
52
35
|
|
|
53
|
-
|
|
54
|
-
return this.baseDB.
|
|
36
|
+
writeLock<T>(fn: (tx: PowerSyncLockContext) => Promise<T>, options?: DBLockOptions): Promise<T> {
|
|
37
|
+
return this.baseDB.writeLock((dbTx) => fn(this.generateContext(dbTx)), options);
|
|
55
38
|
}
|
|
56
39
|
|
|
57
|
-
|
|
58
|
-
return
|
|
40
|
+
generateContext<T extends RNQSLockContext>(ctx: T) {
|
|
41
|
+
return new QuickSqliteContext(ctx);
|
|
59
42
|
}
|
|
60
43
|
|
|
61
|
-
|
|
62
|
-
|
|
44
|
+
async refreshSchema() {
|
|
45
|
+
await this.baseDB.refreshSchema();
|
|
63
46
|
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
class QuickSqliteExecutor implements Omit<SqlExecutor, 'executeBatch'> {
|
|
50
|
+
constructor(readonly context: RNQSLockContext) {}
|
|
64
51
|
|
|
65
52
|
execute(query: string, params?: any[]) {
|
|
66
|
-
return this.
|
|
53
|
+
return this.context.execute(query, params);
|
|
67
54
|
}
|
|
68
|
-
|
|
69
55
|
/**
|
|
70
56
|
* 'executeRaw' is not implemented in RNQS, this falls back to 'execute'.
|
|
71
57
|
*/
|
|
72
58
|
async executeRaw(query: string, params?: any[]): Promise<any[][]> {
|
|
73
|
-
const result = await this.
|
|
59
|
+
const result = await this.context.execute(query, params);
|
|
74
60
|
const rows = result.rows?._array ?? [];
|
|
75
61
|
return rows.map((row) => Object.values(row));
|
|
76
62
|
}
|
|
63
|
+
}
|
|
77
64
|
|
|
65
|
+
class QuickSqliteContext extends DBGetUtilsDefaultMixin(QuickSqliteExecutor) implements LockContext {}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Adapter for React Native Quick SQLite
|
|
69
|
+
*/
|
|
70
|
+
export class RNQSDBAdapter extends DBAdapterDefaultMixin(RNQSConnectionPool) implements DBAdapter {
|
|
71
|
+
// We don't want the default implementation here, RNQS does not support executeBatch for lock contexts so that would
|
|
72
|
+
// be less efficient.
|
|
78
73
|
async executeBatch(query: string, params: any[][] = []): Promise<QueryResult> {
|
|
79
74
|
const commands: any[] = [];
|
|
80
75
|
|
|
@@ -87,70 +82,4 @@ export class RNQSDBAdapter extends BaseObserver<DBAdapterListener> implements DB
|
|
|
87
82
|
rowsAffected: result.rowsAffected ? result.rowsAffected : 0
|
|
88
83
|
};
|
|
89
84
|
}
|
|
90
|
-
|
|
91
|
-
generateContext<T extends RNQSLockContext>(ctx: T) {
|
|
92
|
-
return {
|
|
93
|
-
...ctx,
|
|
94
|
-
// 'executeRaw' is not implemented in RNQS, this falls back to 'execute'.
|
|
95
|
-
executeRaw: async (sql: string, params?: any[]) => {
|
|
96
|
-
const result = await ctx.execute(sql, params);
|
|
97
|
-
const rows = result.rows?._array ?? [];
|
|
98
|
-
return rows.map((row) => Object.values(row));
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* This provides a top-level read only execute method which is executed inside a read-lock.
|
|
105
|
-
* This is necessary since the high level `execute` method uses a write-lock under
|
|
106
|
-
* the hood. Helper methods such as `get`, `getAll` and `getOptional` are read only,
|
|
107
|
-
* and should use this method.
|
|
108
|
-
*/
|
|
109
|
-
private readOnlyExecute(sql: string, params?: any[]) {
|
|
110
|
-
return this.baseDB.readLock((ctx) => ctx.execute(sql, params));
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Adds DB get utils to lock contexts and transaction contexts
|
|
115
|
-
* @param tx
|
|
116
|
-
* @returns
|
|
117
|
-
*/
|
|
118
|
-
private generateDBHelpers<T extends { execute: (sql: string, params?: any[]) => Promise<QueryResult> }>(
|
|
119
|
-
tx: T
|
|
120
|
-
): T & DBGetUtils {
|
|
121
|
-
return {
|
|
122
|
-
...tx,
|
|
123
|
-
/**
|
|
124
|
-
* Execute a read-only query and return results
|
|
125
|
-
*/
|
|
126
|
-
getAll: async <T>(sql: string, parameters?: any[]): Promise<T[]> => {
|
|
127
|
-
const res = await tx.execute(sql, parameters);
|
|
128
|
-
return res.rows?._array ?? [];
|
|
129
|
-
},
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Execute a read-only query and return the first result, or null if the ResultSet is empty.
|
|
133
|
-
*/
|
|
134
|
-
getOptional: async <T>(sql: string, parameters?: any[]): Promise<T | null> => {
|
|
135
|
-
const res = await tx.execute(sql, parameters);
|
|
136
|
-
return res.rows?.item(0) ?? null;
|
|
137
|
-
},
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Execute a read-only query and return the first result, error if the ResultSet is empty.
|
|
141
|
-
*/
|
|
142
|
-
get: async <T>(sql: string, parameters?: any[]): Promise<T> => {
|
|
143
|
-
const res = await tx.execute(sql, parameters);
|
|
144
|
-
const first = res.rows?.item(0);
|
|
145
|
-
if (!first) {
|
|
146
|
-
throw new Error('Result set is empty');
|
|
147
|
-
}
|
|
148
|
-
return first;
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
async refreshSchema() {
|
|
154
|
-
await this.baseDB.refreshSchema();
|
|
155
|
-
}
|
|
156
85
|
}
|
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
AbstractRemoteOptions,
|
|
4
4
|
BSONImplementation,
|
|
5
5
|
DEFAULT_REMOTE_LOGGER,
|
|
6
|
-
DataStream,
|
|
7
6
|
FetchImplementation,
|
|
8
7
|
FetchImplementationProvider,
|
|
9
8
|
ILogger,
|
|
@@ -55,11 +54,16 @@ export class ReactNativeRemote extends AbstractRemote {
|
|
|
55
54
|
return BSON;
|
|
56
55
|
}
|
|
57
56
|
|
|
58
|
-
|
|
57
|
+
createTextDecoder(): TextDecoder {
|
|
59
58
|
return new TextDecoder();
|
|
60
59
|
}
|
|
61
60
|
|
|
62
|
-
|
|
61
|
+
protected get supportsStreamingBinaryResponses(): boolean {
|
|
62
|
+
// We have to pass textStreaming: true to get streamed responses at all, and those don't support binary data.
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
protected async fetchStreamRaw(options: SyncStreamOptions) {
|
|
63
67
|
const timeout =
|
|
64
68
|
Platform.OS == 'android'
|
|
65
69
|
? setTimeout(() => {
|
|
@@ -72,22 +76,19 @@ export class ReactNativeRemote extends AbstractRemote {
|
|
|
72
76
|
: null;
|
|
73
77
|
|
|
74
78
|
try {
|
|
75
|
-
return await super.
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
fetchOptions
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
},
|
|
89
|
-
mapLine
|
|
90
|
-
);
|
|
79
|
+
return await super.fetchStreamRaw({
|
|
80
|
+
...options,
|
|
81
|
+
fetchOptions: {
|
|
82
|
+
...options.fetchOptions,
|
|
83
|
+
/**
|
|
84
|
+
* The `react-native-fetch-api` polyfill provides streaming support via
|
|
85
|
+
* this non-standard flag
|
|
86
|
+
* https://github.com/react-native-community/fetch#enable-text-streaming
|
|
87
|
+
*/
|
|
88
|
+
// @ts-expect-error https://github.com/react-native-community/fetch#enable-text-streaming
|
|
89
|
+
reactNative: { textStreaming: true }
|
|
90
|
+
}
|
|
91
|
+
});
|
|
91
92
|
} finally {
|
|
92
93
|
if (timeout) {
|
|
93
94
|
clearTimeout(timeout);
|
|
@@ -2,9 +2,9 @@ import {
|
|
|
2
2
|
AbstractStreamingSyncImplementation,
|
|
3
3
|
AbstractStreamingSyncImplementationOptions,
|
|
4
4
|
LockOptions,
|
|
5
|
-
LockType
|
|
5
|
+
LockType,
|
|
6
|
+
Mutex
|
|
6
7
|
} from '@powersync/common';
|
|
7
|
-
import { Mutex } from 'async-mutex';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Global locks which prevent multiple instances from syncing
|
|
@@ -45,11 +45,7 @@ export class ReactNativeStreamingSyncImplementation extends AbstractStreamingSyn
|
|
|
45
45
|
throw new Error(`Lock type ${lockOptions.type} not found`);
|
|
46
46
|
}
|
|
47
47
|
return lock.runExclusive(async () => {
|
|
48
|
-
if (lockOptions.signal?.aborted) {
|
|
49
|
-
throw new Error('Aborted');
|
|
50
|
-
}
|
|
51
|
-
|
|
52
48
|
return lockOptions.callback();
|
|
53
|
-
});
|
|
49
|
+
}, lockOptions.signal);
|
|
54
50
|
}
|
|
55
51
|
}
|