@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.
Files changed (29) hide show
  1. package/dist/index.js +20450 -3
  2. package/dist/index.js.map +1 -0
  3. package/lib/db/PowerSyncDatabase.js +1 -0
  4. package/lib/db/PowerSyncDatabase.js.map +1 -0
  5. package/lib/db/adapters/react-native-quick-sqlite/RNQSDBAdapter.js +1 -0
  6. package/lib/db/adapters/react-native-quick-sqlite/RNQSDBAdapter.js.map +1 -0
  7. package/lib/db/adapters/react-native-quick-sqlite/RNQSDBOpenFactory.js +1 -0
  8. package/lib/db/adapters/react-native-quick-sqlite/RNQSDBOpenFactory.js.map +1 -0
  9. package/lib/db/adapters/react-native-quick-sqlite/ReactNativeQuickSQLiteOpenFactory.js +1 -0
  10. package/lib/db/adapters/react-native-quick-sqlite/ReactNativeQuickSQLiteOpenFactory.js.map +1 -0
  11. package/lib/index.js +1 -0
  12. package/lib/index.js.map +1 -0
  13. package/lib/sync/bucket/ReactNativeBucketStorageAdapter.js +1 -0
  14. package/lib/sync/bucket/ReactNativeBucketStorageAdapter.js.map +1 -0
  15. package/lib/sync/stream/ReactNativeRemote.d.ts +2 -0
  16. package/lib/sync/stream/ReactNativeRemote.js +5 -0
  17. package/lib/sync/stream/ReactNativeRemote.js.map +1 -0
  18. package/lib/sync/stream/ReactNativeStreamingSyncImplementation.d.ts +2 -2
  19. package/lib/sync/stream/ReactNativeStreamingSyncImplementation.js +5 -4
  20. package/lib/sync/stream/ReactNativeStreamingSyncImplementation.js.map +1 -0
  21. package/package.json +9 -9
  22. package/src/db/PowerSyncDatabase.ts +63 -0
  23. package/src/db/adapters/react-native-quick-sqlite/RNQSDBAdapter.ts +156 -0
  24. package/src/db/adapters/react-native-quick-sqlite/RNQSDBOpenFactory.ts +44 -0
  25. package/src/db/adapters/react-native-quick-sqlite/ReactNativeQuickSQLiteOpenFactory.ts +43 -0
  26. package/src/index.ts +10 -0
  27. package/src/sync/bucket/ReactNativeBucketStorageAdapter.ts +24 -0
  28. package/src/sync/stream/ReactNativeRemote.ts +98 -0
  29. 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
+ }