@powersync/react-native 1.26.0 → 1.26.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/dist/index.js +20450 -3
- package/dist/index.js.map +1 -0
- package/lib/db/PowerSyncDatabase.js +1 -0
- package/lib/db/PowerSyncDatabase.js.map +1 -0
- package/lib/db/adapters/react-native-quick-sqlite/RNQSDBAdapter.js +1 -0
- package/lib/db/adapters/react-native-quick-sqlite/RNQSDBAdapter.js.map +1 -0
- package/lib/db/adapters/react-native-quick-sqlite/RNQSDBOpenFactory.js +1 -0
- package/lib/db/adapters/react-native-quick-sqlite/RNQSDBOpenFactory.js.map +1 -0
- package/lib/db/adapters/react-native-quick-sqlite/ReactNativeQuickSQLiteOpenFactory.js +1 -0
- package/lib/db/adapters/react-native-quick-sqlite/ReactNativeQuickSQLiteOpenFactory.js.map +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -0
- package/lib/sync/bucket/ReactNativeBucketStorageAdapter.js +1 -0
- package/lib/sync/bucket/ReactNativeBucketStorageAdapter.js.map +1 -0
- package/lib/sync/stream/ReactNativeRemote.d.ts +2 -0
- package/lib/sync/stream/ReactNativeRemote.js +5 -0
- package/lib/sync/stream/ReactNativeRemote.js.map +1 -0
- package/lib/sync/stream/ReactNativeStreamingSyncImplementation.d.ts +2 -2
- package/lib/sync/stream/ReactNativeStreamingSyncImplementation.js +5 -4
- package/lib/sync/stream/ReactNativeStreamingSyncImplementation.js.map +1 -0
- package/package.json +9 -9
- package/src/db/PowerSyncDatabase.ts +63 -0
- package/src/db/adapters/react-native-quick-sqlite/RNQSDBAdapter.ts +156 -0
- package/src/db/adapters/react-native-quick-sqlite/RNQSDBOpenFactory.ts +44 -0
- package/src/db/adapters/react-native-quick-sqlite/ReactNativeQuickSQLiteOpenFactory.ts +43 -0
- package/src/index.ts +10 -0
- package/src/sync/bucket/ReactNativeBucketStorageAdapter.ts +24 -0
- package/src/sync/stream/ReactNativeRemote.ts +98 -0
- package/src/sync/stream/ReactNativeStreamingSyncImplementation.ts +55 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { ILogger } from 'js-logger';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
AbstractRemote,
|
|
5
|
+
AbstractRemoteOptions,
|
|
6
|
+
BSONImplementation,
|
|
7
|
+
DEFAULT_REMOTE_LOGGER,
|
|
8
|
+
DataStream,
|
|
9
|
+
FetchImplementation,
|
|
10
|
+
FetchImplementationProvider,
|
|
11
|
+
RemoteConnector,
|
|
12
|
+
SyncStreamOptions
|
|
13
|
+
} from '@powersync/common';
|
|
14
|
+
import { Platform } from 'react-native';
|
|
15
|
+
// Note docs for React Native https://github.com/mongodb/js-bson?tab=readme-ov-file#react-native
|
|
16
|
+
import { BSON } from 'bson';
|
|
17
|
+
import { TextDecoder } from 'text-encoding';
|
|
18
|
+
|
|
19
|
+
import { fetch } from 'react-native-fetch-api';
|
|
20
|
+
|
|
21
|
+
export const STREAMING_POST_TIMEOUT_MS = 30_000;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Directly imports fetch implementation from react-native-fetch-api.
|
|
25
|
+
* This removes the requirement for the global `fetch` to be overridden by
|
|
26
|
+
* a polyfill.
|
|
27
|
+
*/
|
|
28
|
+
class ReactNativeFetchProvider extends FetchImplementationProvider {
|
|
29
|
+
getFetch(): FetchImplementation {
|
|
30
|
+
return fetch.bind(globalThis);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export class ReactNativeRemote extends AbstractRemote {
|
|
35
|
+
constructor(
|
|
36
|
+
protected connector: RemoteConnector,
|
|
37
|
+
protected logger: ILogger = DEFAULT_REMOTE_LOGGER,
|
|
38
|
+
options?: Partial<AbstractRemoteOptions>
|
|
39
|
+
) {
|
|
40
|
+
super(connector, logger, {
|
|
41
|
+
...(options ?? {}),
|
|
42
|
+
fetchImplementation: options?.fetchImplementation ?? new ReactNativeFetchProvider()
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
getUserAgent(): string {
|
|
47
|
+
return [
|
|
48
|
+
super.getUserAgent(),
|
|
49
|
+
`powersync-react-native`,
|
|
50
|
+
`react-native/${Platform.constants.reactNativeVersion.major}.${Platform.constants.reactNativeVersion.minor}`,
|
|
51
|
+
`${Platform.OS}/${Platform.Version}`
|
|
52
|
+
].join(' ');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async getBSON(): Promise<BSONImplementation> {
|
|
56
|
+
return BSON;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
protected createTextDecoder(): TextDecoder {
|
|
60
|
+
return new TextDecoder();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async postStreamRaw<T>(options: SyncStreamOptions, mapLine: (line: string) => T): Promise<DataStream<T>> {
|
|
64
|
+
const timeout =
|
|
65
|
+
Platform.OS == 'android'
|
|
66
|
+
? setTimeout(() => {
|
|
67
|
+
this.logger.warn(
|
|
68
|
+
`HTTP Streaming POST is taking longer than ${Math.ceil(
|
|
69
|
+
STREAMING_POST_TIMEOUT_MS / 1000
|
|
70
|
+
)} seconds to resolve. If using a debug build, please ensure Flipper Network plugin is disabled.`
|
|
71
|
+
);
|
|
72
|
+
}, STREAMING_POST_TIMEOUT_MS)
|
|
73
|
+
: null;
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
return await super.postStreamRaw(
|
|
77
|
+
{
|
|
78
|
+
...options,
|
|
79
|
+
fetchOptions: {
|
|
80
|
+
...options.fetchOptions,
|
|
81
|
+
/**
|
|
82
|
+
* The `react-native-fetch-api` polyfill provides streaming support via
|
|
83
|
+
* this non-standard flag
|
|
84
|
+
* https://github.com/react-native-community/fetch#enable-text-streaming
|
|
85
|
+
*/
|
|
86
|
+
// @ts-expect-error https://github.com/react-native-community/fetch#enable-text-streaming
|
|
87
|
+
reactNative: { textStreaming: true }
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
mapLine
|
|
91
|
+
);
|
|
92
|
+
} finally {
|
|
93
|
+
if (timeout) {
|
|
94
|
+
clearTimeout(timeout);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AbstractStreamingSyncImplementation,
|
|
3
|
+
AbstractStreamingSyncImplementationOptions,
|
|
4
|
+
LockOptions,
|
|
5
|
+
LockType
|
|
6
|
+
} from '@powersync/common';
|
|
7
|
+
import { Mutex } from 'async-mutex';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Global locks which prevent multiple instances from syncing
|
|
11
|
+
* concurrently.
|
|
12
|
+
*/
|
|
13
|
+
const LOCKS = new Map<string, Map<LockType, Mutex>>();
|
|
14
|
+
|
|
15
|
+
export class ReactNativeStreamingSyncImplementation extends AbstractStreamingSyncImplementation {
|
|
16
|
+
locks: Map<LockType, Mutex>;
|
|
17
|
+
|
|
18
|
+
constructor(options: AbstractStreamingSyncImplementationOptions) {
|
|
19
|
+
super(options);
|
|
20
|
+
this.initLocks();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Configures global locks on sync process
|
|
25
|
+
*/
|
|
26
|
+
initLocks() {
|
|
27
|
+
const { identifier } = this.options;
|
|
28
|
+
if (identifier && LOCKS.has(identifier)) {
|
|
29
|
+
this.locks = LOCKS.get(identifier)!;
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
this.locks = new Map<LockType, Mutex>();
|
|
34
|
+
this.locks.set(LockType.CRUD, new Mutex());
|
|
35
|
+
this.locks.set(LockType.SYNC, new Mutex());
|
|
36
|
+
|
|
37
|
+
if (identifier) {
|
|
38
|
+
LOCKS.set(identifier, this.locks);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
obtainLock<T>(lockOptions: LockOptions<T>): Promise<T> {
|
|
43
|
+
const lock = this.locks.get(lockOptions.type);
|
|
44
|
+
if (!lock) {
|
|
45
|
+
throw new Error(`Lock type ${lockOptions.type} not found`);
|
|
46
|
+
}
|
|
47
|
+
return lock.runExclusive(async () => {
|
|
48
|
+
if (lockOptions.signal?.aborted) {
|
|
49
|
+
throw new Error('Aborted');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return lockOptions.callback();
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|