react-native-mosquito-transport 0.0.47 → 0.0.49

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 (97) hide show
  1. package/CONTRIBUTING.md +37 -19
  2. package/MosquitoTransport.podspec +20 -0
  3. package/android/build.gradle +32 -42
  4. package/android/src/main/AndroidManifest.xml +1 -3
  5. package/android/src/main/java/com/mosquitotransport/MosquitoTransportModule.kt +101 -0
  6. package/android/src/main/java/com/mosquitotransport/MosquitoTransportPackage.kt +31 -0
  7. package/android/src/main/java/com/mosquitotransport/utils/FileUploader.kt +106 -0
  8. package/android/src/main/java/com/mosquitotransport/utils/UploadCallback.kt +7 -0
  9. package/ios/MosquitoTransport-Bridging-Header.h +1 -0
  10. package/ios/MosquitoTransport.h +6 -0
  11. package/ios/MosquitoTransport.mm +81 -0
  12. package/ios/{Mosquitodb.swift → MosquitoTransport.swift} +39 -42
  13. package/package.json +11 -3
  14. package/src/NativeMosquitoTransport.js +24 -0
  15. package/src/helpers/fs_manager.js +1 -1
  16. package/src/helpers/utils.js +2 -4
  17. package/src/helpers/variables.js +2 -1
  18. package/src/index.d.ts +55 -24
  19. package/src/index.js +20 -12
  20. package/src/products/auth/accessor.js +119 -95
  21. package/src/products/auth/index.js +11 -9
  22. package/src/products/database/index.js +1 -0
  23. package/src/products/http_callable/index.js +6 -5
  24. package/src/products/storage/index.js +65 -60
  25. package/.jshintignore +0 -4
  26. package/.jshintrc +0 -16
  27. package/TODO +0 -27
  28. package/android/gradle.properties +0 -5
  29. package/android/src/main/java/com/mosquitodb/MosquitodbModule.java +0 -82
  30. package/android/src/main/java/com/mosquitodb/MosquitodbPackage.java +0 -28
  31. package/android/src/main/java/com/mosquitodb/utils/FileUploader.java +0 -101
  32. package/android/src/main/java/com/mosquitodb/utils/UploadCallback.java +0 -7
  33. package/example/.bundle/config +0 -2
  34. package/example/.node-version +0 -1
  35. package/example/.watchmanconfig +0 -1
  36. package/example/Gemfile +0 -6
  37. package/example/android/app/build.gradle +0 -170
  38. package/example/android/app/debug.keystore +0 -0
  39. package/example/android/app/proguard-rules.pro +0 -10
  40. package/example/android/app/src/debug/AndroidManifest.xml +0 -13
  41. package/example/android/app/src/debug/java/com/mosquitodbexample/ReactNativeFlipper.java +0 -75
  42. package/example/android/app/src/main/AndroidManifest.xml +0 -25
  43. package/example/android/app/src/main/java/com/mosquitodbexample/MainActivity.java +0 -35
  44. package/example/android/app/src/main/java/com/mosquitodbexample/MainApplication.java +0 -62
  45. package/example/android/app/src/main/res/drawable/rn_edit_text_material.xml +0 -36
  46. package/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  47. package/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
  48. package/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  49. package/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
  50. package/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  51. package/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
  52. package/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  53. package/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  54. package/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  55. package/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  56. package/example/android/app/src/main/res/values/strings.xml +0 -3
  57. package/example/android/app/src/main/res/values/styles.xml +0 -9
  58. package/example/android/app/src/release/java/com/mosquitodbexample/ReactNativeFlipper.java +0 -20
  59. package/example/android/build.gradle +0 -21
  60. package/example/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  61. package/example/android/gradle/wrapper/gradle-wrapper.properties +0 -5
  62. package/example/android/gradle.properties +0 -44
  63. package/example/android/gradlew +0 -234
  64. package/example/android/gradlew.bat +0 -89
  65. package/example/android/settings.gradle +0 -4
  66. package/example/app.json +0 -4
  67. package/example/babel.config.js +0 -17
  68. package/example/index.js +0 -5
  69. package/example/ios/.xcode.env +0 -11
  70. package/example/ios/File.swift +0 -6
  71. package/example/ios/MosquitodbExample/AppDelegate.h +0 -6
  72. package/example/ios/MosquitodbExample/AppDelegate.mm +0 -36
  73. package/example/ios/MosquitodbExample/Images.xcassets/AppIcon.appiconset/Contents.json +0 -53
  74. package/example/ios/MosquitodbExample/Images.xcassets/Contents.json +0 -6
  75. package/example/ios/MosquitodbExample/Info.plist +0 -55
  76. package/example/ios/MosquitodbExample/LaunchScreen.storyboard +0 -47
  77. package/example/ios/MosquitodbExample/main.m +0 -10
  78. package/example/ios/MosquitodbExample-Bridging-Header.h +0 -3
  79. package/example/ios/MosquitodbExample.xcodeproj/project.pbxproj +0 -703
  80. package/example/ios/MosquitodbExample.xcodeproj/xcshareddata/xcschemes/MosquitodbExample.xcscheme +0 -88
  81. package/example/ios/MosquitodbExample.xcworkspace/contents.xcworkspacedata +0 -10
  82. package/example/ios/MosquitodbExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
  83. package/example/ios/MosquitodbExample.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +0 -8
  84. package/example/ios/MosquitodbExample.xcworkspace/xcuserdata/anthony.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  85. package/example/ios/MosquitodbExample.xcworkspace/xcuserdata/anthony.xcuserdatad/WorkspaceSettings.xcsettings +0 -14
  86. package/example/ios/MosquitodbExampleTests/Info.plist +0 -24
  87. package/example/ios/MosquitodbExampleTests/MosquitodbExampleTests.m +0 -66
  88. package/example/ios/Podfile +0 -60
  89. package/example/metro.config.js +0 -40
  90. package/example/package.json +0 -22
  91. package/example/react-native.config.js +0 -10
  92. package/example/src/App.tsx +0 -31
  93. package/ios/Mosquitodb-Bridging-Header.h +0 -2
  94. package/ios/Mosquitodb.m +0 -22
  95. package/ios/Mosquitodb.xcodeproj/project.pbxproj +0 -283
  96. package/ios/Mosquitodb.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -4
  97. package/react-native-mosquitodb.podspec +0 -35
@@ -1,52 +1,34 @@
1
1
  import React
2
2
 
3
- @objc(Mosquitodb)
4
- class Mosquitodb: RCTEventEmitter, URLSessionDataDelegate {
3
+ @objc
4
+ public protocol NativeMosquitoTransportImplDelegate {
5
+ func sendEvent(name: String, body: Any)
6
+ }
7
+
8
+ @objc(NativeMosquitoTransportImpl)
9
+ public class NativeMosquitoTransportImpl: NSObject, URLSessionDataDelegate {
10
+ // Add property for the Objective-C bridge
11
+ @objc public weak var delegate: NativeMosquitoTransportImplDelegate? = nil
5
12
 
6
13
  public override init() {
7
14
  super.init()
8
15
  }
9
-
10
- override public static func requiresMainQueueSetup() -> Bool {
11
- return true;
12
- }
13
-
14
- @objc(supportedEvents)
15
- override public func supportedEvents() -> [String] {
16
- return [
17
- "mt-uploading-progress",
18
- "mt-uploading-status",
19
- "mt-download-progress",
20
- "mt-download-status"
21
- ]
16
+
17
+ private func emitNewEvent(name: String, body: Any? = nil) {
18
+ delegate?.sendEvent(name: name, body: body ?? [])
22
19
  }
23
20
 
24
- var uploadTask: [String: MosquitodbUploadTask] = [:]
25
- var downloadTask: [String: MosquitodbDownloadTask] = [:]
26
-
27
- @objc(downloadFile:)
28
- func downloadFile(options: [String: Any]) -> Void {
29
- let processID = options["processID"] as! String
30
- downloadTask[processID] = MosquitodbDownloadTask()
31
- downloadTask[processID]?.downloadFile(options: options, completion: { res in
32
- let status = res![0] as? String
33
-
34
- self.sendEvent(withName: status, body: res![1])
35
- if status == "mt-download-status" {
36
- self.downloadTask.removeValue(forKey: processID)
37
- }
38
- })
39
- }
21
+ var uploadTask: [String: MosquitoTransportUploadTask] = [:]
40
22
 
41
23
  @objc(uploadFile:)
42
- func uploadFile(options: [String: Any]) -> Void {
24
+ public func uploadFile(options: [String: Any]) -> Void {
43
25
  let processID = options["processID"] as! String
44
26
 
45
- uploadTask[processID] = MosquitodbUploadTask()
27
+ uploadTask[processID] = MosquitoTransportUploadTask()
46
28
  uploadTask[processID]?.uploadFile(options: options, completion: { res in
47
29
  let status = res![0] as? String
48
30
 
49
- self.sendEvent(withName: status, body: res![1])
31
+ self.emitNewEvent(name: status!, body: res![1])
50
32
  if status == "mt-uploading-status" {
51
33
  self.uploadTask.removeValue(forKey: processID)
52
34
  }
@@ -54,28 +36,43 @@ class Mosquitodb: RCTEventEmitter, URLSessionDataDelegate {
54
36
  }
55
37
 
56
38
  @objc(cancelUpload:)
57
- func cancelUpload (processID: String)-> Void {
39
+ public func cancelUpload (processID: String)-> Void {
58
40
  uploadTask[processID]?.cancelUpload()
59
41
  }
60
42
 
43
+ var downloadTask: [String: MosquitoTransportDownloadTask] = [:]
44
+
45
+ @objc(downloadFile:)
46
+ public func downloadFile(options: [String: Any]) -> Void {
47
+ let processID = options["processID"] as! String
48
+ downloadTask[processID] = MosquitoTransportDownloadTask()
49
+ downloadTask[processID]?.downloadFile(options: options, completion: { res in
50
+ let status = res![0] as? String
51
+
52
+ self.emitNewEvent(name: status!, body: res![1])
53
+ if status == "mt-download-status" {
54
+ self.downloadTask.removeValue(forKey: processID)
55
+ }
56
+ })
57
+ }
58
+
61
59
  @objc(cancelDownload:)
62
- func cancelDownload (processID: String)-> Void {
60
+ public func cancelDownload (processID: String)-> Void {
63
61
  downloadTask[processID]?.cancelDownload()
64
62
  }
65
63
 
66
64
  @objc(pauseDownload:)
67
- func pauseDownload (processID: String)-> Void {
65
+ public func pauseDownload (processID: String)-> Void {
68
66
  downloadTask[processID]?.pauseDownload()
69
67
  }
70
68
 
71
69
  @objc(resumeDownload:)
72
- func resumeDownload (processID: String)-> Void {
70
+ public func resumeDownload (processID: String)-> Void {
73
71
  downloadTask[processID]?.resumeDownload()
74
72
  }
75
73
  }
76
74
 
77
-
78
- class MosquitodbUploadTask: NSObject, URLSessionDataDelegate {
75
+ class MosquitoTransportUploadTask: NSObject, URLSessionDataDelegate {
79
76
 
80
77
  var mainProcessID: String = ""
81
78
  var mainTask : URLSessionUploadTask? = nil
@@ -177,7 +174,7 @@ class MosquitodbUploadTask: NSObject, URLSessionDataDelegate {
177
174
  }
178
175
 
179
176
 
180
- class MosquitodbDownloadTask: NSObject, URLSessionDownloadDelegate {
177
+ class MosquitoTransportDownloadTask: NSObject, URLSessionDownloadDelegate {
181
178
 
182
179
  var mainProcessID: String = ""
183
180
  var mainTask : URLSessionDownloadTask? = nil
@@ -208,7 +205,7 @@ class MosquitodbDownloadTask: NSObject, URLSessionDownloadDelegate {
208
205
  mainOptions = options
209
206
  trigger = completion
210
207
  task.resume()
211
- print("MosquitodbDownloadTask started:\(mainProcessID)")
208
+ print("MosquitoTransportDownloadTask started:\(mainProcessID)")
212
209
  }
213
210
 
214
211
  func cancelDownload ()-> Void {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-mosquito-transport",
3
- "version": "0.0.47",
3
+ "version": "0.0.49",
4
4
  "description": "React native javascript sdk for mosquito-transport (https://github.com/brainbehindx/mosquito-transport)",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -26,10 +26,18 @@
26
26
  "url": "https://github.com/brainbehindx/react-native-mosquito-transport/issues"
27
27
  },
28
28
  "homepage": "https://github.com/brainbehindx/react-native-mosquito-transport#readme",
29
+ "codegenConfig": {
30
+ "name": "MosquitoTransportSpec",
31
+ "type": "modules",
32
+ "jsSrcsDir": "src",
33
+ "android": {
34
+ "javaPackageName": "com.mosquitotransport"
35
+ }
36
+ },
29
37
  "dependencies": {
30
38
  "@turf/turf": "^7.2.0",
31
39
  "buffer": "^6.0.3",
32
- "entity-serializer": "^1.0.3",
40
+ "entity-serializer": "^1.0.4",
33
41
  "guard-object": "^1.1.4",
34
42
  "poke-object": "^1.0.1",
35
43
  "simplify-error": "^1.0.1",
@@ -43,4 +51,4 @@
43
51
  "react-native-get-random-values": "*",
44
52
  "react-native-sha256": "*"
45
53
  }
46
- }
54
+ }
@@ -0,0 +1,24 @@
1
+ // @flow
2
+ import type { TurboModule } from 'react-native';
3
+ import { type UnsafeObject } from 'react-native/Libraries/Types/CodegenTypes';
4
+ import { TurboModuleRegistry } from 'react-native';
5
+
6
+ export interface Spec extends TurboModule {
7
+ // storage
8
+ uploadFile(option: UnsafeObject): void;
9
+ cancelUpload(process_id: string): void;
10
+ downloadFile(option: UnsafeObject): void;
11
+ cancelDownload(process_id: string): void;
12
+ pauseDownload(process_id: string): void;
13
+ resumeDownload(process_id: string): void;
14
+
15
+ // utils
16
+ getSystemUptime(): Promise<number>;
17
+
18
+ // event listeners
19
+ // readonly onMessage?: EventEmitter<{ message: string }>;
20
+ addListener(eventName: string): void;
21
+ removeListeners(count: number): void;
22
+ }
23
+
24
+ export default TurboModuleRegistry.getEnforcing<Spec>('MosquitoTransport');
@@ -4,7 +4,7 @@ import { Platform } from "react-native";
4
4
  import { Dirs, FileSystem } from "react-native-file-access";
5
5
  import { Buffer } from "buffer";
6
6
 
7
- const PARENT_FOLDER = `${Platform.OS === 'android' ? Dirs.DocumentDir.split('/').slice(0, -1).join('/') : Dirs.MainBundleDir}/mosquito_base`;
7
+ const PARENT_FOLDER = `${Platform.OS === 'android' ? Dirs.DocumentDir.split('/').slice(0, -1).join('/') : Dirs.LibraryDir}/mosquito_base`;
8
8
 
9
9
  /**
10
10
  * this method linearize read/write for individual access_id on the file system ensuring consistency across concurrent operations
@@ -134,21 +134,19 @@ export const releaseCacheStore = async (builder) => {
134
134
  Scoped.AuthJWTToken[key] = value?.token;
135
135
  });
136
136
  Scoped.IsStoreReady = true;
137
- StoreReadyListener.dispatchPersist('_', 'ready');
137
+ StoreReadyListener.dispatchPersist('_', true);
138
138
  setTimeout(() => {
139
139
  if (tobePurged.length) updateCacheStore(tobePurged);
140
140
  }, 0);
141
141
  };
142
142
 
143
- export const getPrefferTime = () => Date.now() + (Scoped.serverTimeOffset || 0);
144
-
145
143
  export const awaitStore = () => new Promise(resolve => {
146
144
  if (Scoped.IsStoreReady) {
147
145
  resolve();
148
146
  return;
149
147
  }
150
148
  const l = StoreReadyListener.listenToPersist('_', t => {
151
- if (t === 'ready') {
149
+ if (t) {
152
150
  resolve();
153
151
  l();
154
152
  }
@@ -10,7 +10,8 @@ export const Scoped = {
10
10
  AuthJWTToken: {},
11
11
  IsStoreReady: false,
12
12
  TokenRefreshTimer: {},
13
- LastTokenRefreshRef: {},
13
+ TokenRefreshProcess: {},
14
+ TokenTimestamping: {},
14
15
  StorageProcessID: 0,
15
16
  InitiatedForcedToken: {},
16
17
  PendingFetchCollective: {},
package/src/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { BSON } from "./vendor/bson";
2
2
 
3
- interface RNMTConfig {
3
+ export interface RNMTConfig {
4
4
  dbName?: string;
5
5
  dbUrl?: string;
6
6
  projectUrl: string;
@@ -38,7 +38,7 @@ interface RNMTConfig {
38
38
  castBSON?: boolean;
39
39
  }
40
40
 
41
- interface GetDatabase {
41
+ export interface GetDatabase {
42
42
  collection: (path: string) => RNMTCollection;
43
43
  }
44
44
 
@@ -98,7 +98,7 @@ type auth_provider_id_values = auth_provider_id['GOOGLE'] |
98
98
  interface ReleaseCacheOption_IO {
99
99
  }
100
100
 
101
- interface ReleaseCacheOption {
101
+ export interface ReleaseCacheOption {
102
102
  /**
103
103
  * fs is used as the default caching mechanism
104
104
  *
@@ -137,7 +137,7 @@ interface ReleaseCacheOption {
137
137
  promoteCache?: boolean;
138
138
  }
139
139
 
140
- interface RNMTSocket {
140
+ export interface RNMTSocket {
141
141
  timeout: (timeout?: number) => ({
142
142
  emitWithAck: (...args: any) => Promise<any>;
143
143
  });
@@ -167,13 +167,18 @@ interface CountConfig {
167
167
  disableAuth?: boolean;
168
168
  }
169
169
 
170
- interface FetchHttpResponse extends Response {
170
+ export interface FetchHttpResponse extends Response {
171
171
  /**
172
172
  * true if this response was from local cache
173
173
  */
174
174
  fromCache?: boolean | undefined;
175
175
  }
176
176
 
177
+ interface CustomSocketOption extends OveridenProjectUrl {
178
+ disableAuth?: boolean;
179
+ authHandshake?: Object;
180
+ }
181
+
177
182
  export default class RNMT {
178
183
  constructor(config: RNMTConfig);
179
184
  static initializeCache(option?: ReleaseCacheOption): void;
@@ -183,12 +188,12 @@ export default class RNMT {
183
188
  storage(): RNMTStorage;
184
189
  fetchHttp(endpoint: string, init?: RequestInit, config?: FetchHttpConfig): Promise<FetchHttpResponse>;
185
190
  listenReachableServer(callback: (reachable: boolean) => void): () => void;
186
- getSocket(options: { disableAuth?: boolean; authHandshake?: Object }): RNMTSocket;
191
+ getSocket(options?: CustomSocketOption): RNMTSocket;
187
192
  onConnect: () => CollectionIO;
188
193
  batchWrite(map: BatchWriteValue[], config?: BatchWriteConfig): Promise<DocumentWriteResult[] | undefined>;
189
194
  }
190
195
 
191
- interface RNMTCollection {
196
+ export interface RNMTCollection {
192
197
  find: (find?: DocumentFind) => ({
193
198
  get: (config?: GetConfig) => Promise<DocumentResult[]>;
194
199
  listen: (callback: (snapshot?: DocumentResult[]) => void, onError?: (error?: DocumentError) => void, config?: GetConfig) => void;
@@ -258,7 +263,7 @@ interface RNMTCollection {
258
263
  deleteMany: (find?: DocumentFind, config?: WriteConfig) => Promise<DocumentWriteResult>;
259
264
  }
260
265
 
261
- interface CollectionTaskIO<T> {
266
+ export interface CollectionTaskIO<T> {
262
267
  batchWrite(map: BatchWriteValue[], config?: BatchWriteConfig): T;
263
268
  }
264
269
 
@@ -270,7 +275,7 @@ interface OnConnectChain extends StartStop {
270
275
  onDisconnect: () => CollectionTaskIO<StartStop>;
271
276
  }
272
277
 
273
- interface CollectionIO extends CollectionTaskIO<OnConnectChain> {
278
+ export interface CollectionIO extends CollectionTaskIO<OnConnectChain> {
274
279
  onDisconnect: () => CollectionTaskIO<StartStop>;
275
280
  }
276
281
 
@@ -282,7 +287,7 @@ interface DocumentError extends ErrorResponse {
282
287
 
283
288
  }
284
289
 
285
- interface FetchHttpConfig {
290
+ export interface FetchHttpConfig {
286
291
  retrieval?: GetConfig['retrieval'];
287
292
  /**
288
293
  * disable sending authentication token along with this request
@@ -342,7 +347,7 @@ interface GetConfig {
342
347
  retrieval?: Retrieval;
343
348
  /**
344
349
  * - 0: returns data that may have been internally updated locally with updateOne, updateMany, mergeOne, deleteOne, deleteMany, putOne, replaceOne
345
- * - 1: returns exact data which was cached in the last query process
350
+ * - 1: returns exact remote data which was cached in the last query process
346
351
  *
347
352
  * @defaults - 0
348
353
  *
@@ -429,7 +434,7 @@ interface DocumentWriteValue {
429
434
 
430
435
  }
431
436
 
432
- interface RNMTAuth {
437
+ export interface RNMTAuth {
433
438
  customSignin: (email: string, password: string) => Promise<SigninResult>;
434
439
  customSignup: (email: string, password: string, name?: string, metadata?: Object) => Promise<SignupResult>;
435
440
  /**
@@ -465,7 +470,7 @@ export interface SignupResult extends SigninResult {
465
470
  isNewUser: boolean;
466
471
  }
467
472
 
468
- interface AuthData {
473
+ export interface AuthData {
469
474
  email?: string;
470
475
  metadata: Object;
471
476
  signupMethod: auth_provider_id_values;
@@ -473,7 +478,8 @@ interface AuthData {
473
478
  joinedOn: number;
474
479
  uid: string;
475
480
  claims: Object;
476
- emailVerified: boolean;
481
+ authVerified: boolean;
482
+ passwordVerified?: boolean | undefined;
477
483
  tokenID: string;
478
484
  disabled: boolean;
479
485
  entityOf: string;
@@ -487,7 +493,7 @@ interface AuthData {
487
493
  sub: string;
488
494
  }
489
495
 
490
- interface RefreshTokenData {
496
+ export interface RefreshTokenData {
491
497
  uid: string;
492
498
  tokenID: string;
493
499
  isRefreshToken: true;
@@ -497,24 +503,37 @@ interface RefreshTokenData {
497
503
  sub: string;
498
504
  }
499
505
 
500
- interface TokenEventData extends AuthData {
506
+ export interface TokenEventData extends AuthData {
501
507
  tokenManager: TokenManager;
502
508
  }
503
509
 
504
- interface TokenManager {
510
+ export interface TokenManager {
505
511
  refreshToken: string;
506
512
  accessToken: string;
507
513
  }
508
514
 
509
- interface UploadOptions {
515
+ interface OveridenProjectUrl {
516
+ /**
517
+ * The server instance to send requests to. This overrides the parent `projectUrl`, but still relies on the parent `projectUrl` for authentication token resolution and verify server reachability.
518
+ */
519
+ projectUrl?: string;
520
+ }
521
+
522
+ interface UploadOptions extends OveridenProjectUrl {
510
523
  /**
511
524
  * optionally create hash for this upload to save disk space
512
525
  */
513
526
  createHash?: boolean;
527
+
514
528
  /**
515
529
  * wait for a reachable server before initiating the upload task
516
530
  */
517
531
  awaitServer?: boolean;
532
+
533
+ /**
534
+ * monitor upload progress stats
535
+ */
536
+ onProgress?: (stats: UploadProgressStats) => void;
518
537
  }
519
538
 
520
539
  interface DownloadOptions {
@@ -522,16 +541,28 @@ interface DownloadOptions {
522
541
  * wait for a reachable server before initiating the download task
523
542
  */
524
543
  awaitServer?: boolean;
544
+
545
+ /**
546
+ * monitor download progress stats
547
+ */
548
+ onProgress?: (stats: DownloadProgressStats) => void;
549
+ }
550
+
551
+ interface StorageTask extends Promise<string> {
552
+ /**
553
+ * abort the running task process
554
+ */
555
+ abort: () => void;
525
556
  }
526
557
 
527
- interface RNMTStorage {
528
- downloadFile: (link: string, onComplete?: (error?: ErrorResponse, filepath?: string) => void, destination?: string, onProgress?: (stats: DownloadProgressStats) => void, options?: DownloadOptions) => () => void;
529
- uploadFile: (file: string, destination: string, onComplete?: (error?: ErrorResponse, downloadUrl?: string) => void, onProgress?: (stats: UploadProgressStats) => void, options?: UploadOptions) => () => void;
530
- deleteFile: (path: string) => Promise<void>;
531
- deleteFolder: (folder: string) => Promise<void>;
558
+ export interface RNMTStorage {
559
+ downloadFile: (link: string, filepath?: string | undefined, options?: DownloadOptions | undefined) => StorageTask;
560
+ uploadFile: (filepath: string, destination: string, options?: UploadOptions | undefined) => StorageTask;
561
+ deleteFile: (path: string, options?: OveridenProjectUrl | undefined) => Promise<void>;
562
+ deleteFolder: (folder: string, options?: OveridenProjectUrl | undefined) => Promise<void>;
532
563
  }
533
564
 
534
- interface DownloadProgressStats {
565
+ export interface DownloadProgressStats {
535
566
  receivedBtyes: number;
536
567
  expectedBytes: number;
537
568
  isPaused: boolean;
package/src/index.js CHANGED
@@ -16,6 +16,7 @@ import { Buffer } from 'buffer';
16
16
  import MTAuth, { purgePendingToken } from './products/auth';
17
17
  import { BSON } from "./vendor/bson";
18
18
  import { basicClone } from './helpers/basic_clone';
19
+ import { AppState } from "react-native";
19
20
 
20
21
  const {
21
22
  _listenCollection,
@@ -59,11 +60,10 @@ class RNMT {
59
60
 
60
61
  if (!Scoped.InitializedProject[projectUrl]) {
61
62
  Scoped.InitializedProject[projectUrl] = basicClone(this.config);
62
- Scoped.LastTokenRefreshRef[projectUrl] = 0;
63
63
  triggerAuthToken(projectUrl);
64
- initTokenRefresher({ ...this.config }, true);
64
+ initTokenRefresher({ config: this.config, forceRefresh: true });
65
65
 
66
- let isConnected, recentToken;
66
+ let isConnected, recentToken, isVirtualMachineFocused = true;
67
67
 
68
68
  const socket = io(`${this.config.wsPrefix}://${this.config.baseUrl}`, {
69
69
  transports: ['websocket', 'polling', 'flashsocket'],
@@ -86,9 +86,9 @@ class RNMT {
86
86
  };
87
87
  const onDisconnect = () => {
88
88
  ++connectionIte;
89
- isConnected = false;
90
- Scoped.IS_CONNECTED[projectUrl] = false;
91
- ServerReachableListener.dispatchPersist(projectUrl, false);
89
+ isConnected = isVirtualMachineFocused ? false : null;
90
+ Scoped.IS_CONNECTED[projectUrl] = isConnected;
91
+ ServerReachableListener.dispatchPersist(projectUrl, isConnected);
92
92
  }
93
93
 
94
94
  const manualCheckConnection = () => {
@@ -112,6 +112,11 @@ class RNMT {
112
112
  manualCheckConnection();
113
113
  });
114
114
 
115
+ AppState.addEventListener('change', (s) => {
116
+ isVirtualMachineFocused = s === 'active';
117
+ manualCheckConnection();
118
+ });
119
+
115
120
  const updateMountedToken = () => {
116
121
  socket.emit('_update_mounted_user', recentToken || null);
117
122
  };
@@ -165,7 +170,7 @@ class RNMT {
165
170
  listenReachableServer = (callback) => listenReachableServer(callback, this.config.projectUrl);
166
171
 
167
172
  getSocket = (configOpts) => {
168
- const { disableAuth, authHandshake } = configOpts || {};
173
+ const { disableAuth, authHandshake, projectUrl: overidenUrl } = configOpts || {};
169
174
  const { projectUrl, uglify, serverE2E_PublicKey, wsPrefix, extraHeaders } = this.config;
170
175
 
171
176
  const restrictedRoute = [
@@ -278,7 +283,10 @@ class RNMT {
278
283
  const mtoken = disableAuth ? undefined : Scoped.AuthJWTToken[projectUrl];
279
284
  const [reqBuilder, [privateKey]] = uglify ? await serializeE2E({ a_extras: authHandshake }, mtoken, serverE2E_PublicKey) : [null, []];
280
285
 
281
- socket = io(`${wsPrefix}://${projectUrl.split('://')[1]}`, {
286
+ const getWsPrefix = url => url.startsWith('https') ? 'wss' : 'ws';
287
+ const wsUrl = overidenUrl ? `${getWsPrefix(overidenUrl)}://${overidenUrl.split('://')[1]}` : `${wsPrefix}://${projectUrl.split('://')[1]}`;
288
+
289
+ socket = io(wsUrl, {
282
290
  transports: ['websocket', 'polling', 'flashsocket'],
283
291
  extraHeaders,
284
292
  auth: uglify ? {
@@ -305,7 +313,7 @@ class RNMT {
305
313
  tokenListener = listenTokenReady(status => {
306
314
  if (lastTokenStatus === (status || false)) return;
307
315
 
308
- if (status === 'ready') {
316
+ if (status) {
309
317
  init();
310
318
  } else {
311
319
  socket?.close?.();
@@ -445,7 +453,7 @@ const ConfigValidator = {
445
453
  if (v.endsWith('/')) throw '"projectUrl" must not end with a trailing slash "/"';
446
454
  },
447
455
  disableCache: (v) => {
448
- if (typeof v !== 'boolean')
456
+ if (typeof v !== 'boolean' && v !== undefined)
449
457
  throw `Invalid value supplied to disableCache, value must be a boolean`;
450
458
  },
451
459
  maxRetries: (v) => {
@@ -453,7 +461,7 @@ const ConfigValidator = {
453
461
  throw `Invalid value supplied to maxRetries, value must be positive integer greater than zero`;
454
462
  },
455
463
  enableE2E_Encryption: (v) => {
456
- if (typeof v !== 'boolean')
464
+ if (typeof v !== 'boolean' && v !== undefined)
457
465
  throw `Invalid value supplied to enableE2E_Encryption, value must be a boolean`;
458
466
  },
459
467
  castBSON: v => {
@@ -465,7 +473,7 @@ const ConfigValidator = {
465
473
  throw `Expected "borrowToken" to be valid https or http link but got "${v}"`;
466
474
  },
467
475
  serverE2E_PublicKey: (v) => {
468
- if (typeof v !== 'string' || !v.trim())
476
+ if (v !== undefined && (typeof v !== 'string' || !v.trim()))
469
477
  throw `Invalid value supplied to serverETE_PublicKey, value must be a non-empty string`;
470
478
  },
471
479
  extraHeaders: v => {