@tryvital/vital-core-react-native 5.2.3 → 5.3.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.
Files changed (41) hide show
  1. package/android/build.gradle +1 -1
  2. package/android/src/main/java/com/vitalcorereactnative/ReactNativeAuthenticateRequest.kt +19 -0
  3. package/android/src/main/java/com/vitalcorereactnative/VitalCoreReactNativeModule.kt +70 -0
  4. package/ios/VitalCoreReactNative.m +13 -0
  5. package/ios/VitalCoreReactNative.swift +96 -1
  6. package/lib/commonjs/index.js +76 -13
  7. package/lib/commonjs/index.js.map +1 -1
  8. package/lib/commonjs/models/AuthenticateRequest.js +2 -0
  9. package/lib/commonjs/models/AuthenticateRequest.js.map +1 -0
  10. package/lib/commonjs/models/BloodPressureSample.js.map +1 -1
  11. package/lib/commonjs/models/Provider.js.map +1 -1
  12. package/lib/commonjs/models/QuantitySample.js.map +1 -1
  13. package/lib/commonjs/models/TimeSeriesData.js.map +1 -1
  14. package/lib/commonjs/models/VitalCoreStatus.js.map +1 -1
  15. package/lib/module/index.js +75 -14
  16. package/lib/module/index.js.map +1 -1
  17. package/lib/module/models/AuthenticateRequest.js +2 -0
  18. package/lib/module/models/AuthenticateRequest.js.map +1 -0
  19. package/lib/module/models/BloodPressureSample.js +1 -1
  20. package/lib/module/models/BloodPressureSample.js.map +1 -1
  21. package/lib/module/models/Provider.js +0 -2
  22. package/lib/module/models/Provider.js.map +1 -1
  23. package/lib/module/models/QuantitySample.js +1 -1
  24. package/lib/module/models/QuantitySample.js.map +1 -1
  25. package/lib/module/models/TimeSeriesData.js +0 -2
  26. package/lib/module/models/TimeSeriesData.js.map +1 -1
  27. package/lib/module/models/VitalCoreStatus.js +1 -1
  28. package/lib/module/models/VitalCoreStatus.js.map +1 -1
  29. package/lib/typescript/index.d.ts +42 -0
  30. package/lib/typescript/index.d.ts.map +1 -1
  31. package/lib/typescript/models/AuthenticateRequest.d.ts +15 -0
  32. package/lib/typescript/models/AuthenticateRequest.d.ts.map +1 -0
  33. package/package.json +1 -1
  34. package/src/index.ts +86 -10
  35. package/src/models/AuthenticateRequest.ts +17 -0
  36. package/ios/VitalCoreReactNative.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
  37. package/ios/VitalCoreReactNative.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
  38. package/ios/VitalCoreReactNative.xcodeproj/project.xcworkspace/xcuserdata/anders.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  39. package/ios/VitalCoreReactNative.xcodeproj/xcuserdata/anders.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
  40. package/lib/commonjs/package.json +0 -1
  41. package/lib/module/package.json +0 -1
@@ -131,7 +131,7 @@ repositories {
131
131
  }
132
132
 
133
133
  def kotlin_version = getExtOrDefault('kotlinVersion')
134
- def vital_sdk_version = '4.0.2'
134
+ def vital_sdk_version = '4.1.0'
135
135
 
136
136
  dependencies {
137
137
  ksp "com.squareup.moshi:moshi-kotlin-codegen:1.13.0"
@@ -0,0 +1,19 @@
1
+ package com.vitalcorereactnative
2
+
3
+ import com.squareup.moshi.JsonClass
4
+ import com.squareup.moshi.adapters.PolymorphicJsonAdapterFactory
5
+
6
+ sealed class ReactNativeAuthenticateRequest {
7
+ @JsonClass(generateAdapter = true)
8
+ data class SignInToken(val type: String, val rawToken: String): ReactNativeAuthenticateRequest()
9
+
10
+ @JsonClass(generateAdapter = true)
11
+ data class APIKey(val type: String, val key: String, val userId: String, val region: String, val environment: String): ReactNativeAuthenticateRequest()
12
+
13
+ companion object {
14
+ val jsonAdapter = PolymorphicJsonAdapterFactory.of(ReactNativeAuthenticateRequest::class.java, "type")
15
+ .withSubtype(SignInToken::class.java, "signInToken")
16
+ .withSubtype(APIKey::class.java, "apiKey")
17
+ }
18
+ }
19
+
@@ -11,6 +11,7 @@ import com.facebook.react.module.annotations.ReactModule
11
11
  import com.facebook.react.modules.core.DeviceEventManagerModule
12
12
  import com.squareup.moshi.Moshi
13
13
  import com.squareup.moshi.adapter
14
+ import com.squareup.moshi.adapters.EnumJsonAdapter
14
15
  import com.squareup.moshi.adapters.Rfc3339DateJsonAdapter
15
16
  import io.tryvital.client.*
16
17
  import io.tryvital.client.services.data.DataStage
@@ -25,13 +26,18 @@ import kotlinx.coroutines.MainScope
25
26
  import kotlinx.coroutines.flow.collect
26
27
  import kotlinx.coroutines.flow.onEach
27
28
  import kotlinx.coroutines.launch
29
+ import kotlinx.coroutines.suspendCancellableCoroutine
28
30
  import java.time.ZoneId
29
31
  import java.util.*
32
+ import kotlin.coroutines.Continuation
33
+ import kotlin.coroutines.resume
30
34
 
31
35
  const val VITAL_CORE_ERROR = "VitalCoreError"
36
+ const val IDENTIFY_EXTERNAL_USER_REQUEST = "IdentifyExternalUserRequest"
32
37
 
33
38
  internal val moshi by lazy {
34
39
  Moshi.Builder()
40
+ .add(ReactNativeAuthenticateRequest.jsonAdapter)
35
41
  .add(Date::class.java, Rfc3339DateJsonAdapter())
36
42
  .build()
37
43
  }
@@ -45,6 +51,8 @@ class VitalCoreReactNativeModule(reactContext: ReactApplicationContext) :
45
51
  private var listenerCount = 0
46
52
  private var statusObserver: Job? = null
47
53
 
54
+ private val pendingIdentifyCalls = mutableMapOf<String, Continuation<String>>()
55
+
48
56
  override fun getName(): String {
49
57
  return NAME
50
58
  }
@@ -100,6 +108,68 @@ class VitalCoreReactNativeModule(reactContext: ReactApplicationContext) :
100
108
  promise.resolve(VitalClient.currentUserId)
101
109
  }
102
110
 
111
+ @ReactMethod
112
+ fun identifiedExternalUser(promise: Promise) {
113
+ // Ensure that the SDK is initialized.
114
+ VitalClient.getOrCreate(reactApplicationContext)
115
+
116
+ promise.resolve(VitalClient.identifiedExternalUser)
117
+ }
118
+
119
+ @ReactMethod
120
+ fun identifyExternalUser(externalUserId: String, callId: String, promise: Promise) {
121
+ mainScope.launch {
122
+ try {
123
+ VitalClient.identifyExternalUser(
124
+ reactApplicationContext,
125
+ externalUserId
126
+ ) { innerExternalUserId ->
127
+ val jsonPayload = suspendCancellableCoroutine<String> { continuation ->
128
+ synchronized(this) {
129
+ pendingIdentifyCalls[callId] = continuation
130
+ }
131
+ eventEmitter().emit(
132
+ IDENTIFY_EXTERNAL_USER_REQUEST,
133
+ WritableNativeArray().apply {
134
+ pushString(callId)
135
+ pushString(innerExternalUserId)
136
+ }
137
+ )
138
+ }
139
+
140
+ val request = moshi.adapter(ReactNativeAuthenticateRequest::class.java).fromJson(jsonPayload)
141
+ ?: throw RuntimeException("failed to deserialize ReactNativeAuthenticateRequest")
142
+
143
+ when (request) {
144
+ is ReactNativeAuthenticateRequest.SignInToken -> {
145
+ AuthenticateRequest.SignInToken(request.rawToken)
146
+ }
147
+ is ReactNativeAuthenticateRequest.APIKey -> {
148
+ AuthenticateRequest.APIKey(
149
+ request.key,
150
+ request.userId,
151
+ Environment.valueOf(request.environment.lowercase().replaceFirstChar { it.uppercase() }),
152
+ Region.valueOf(request.region.uppercase())
153
+ )
154
+ }
155
+ }
156
+ }
157
+
158
+ promise.resolve(null)
159
+
160
+ } catch (e: Throwable) {
161
+ promise.reject(VITAL_CORE_ERROR, e.message, e)
162
+ }
163
+ }
164
+ }
165
+
166
+ @ReactMethod
167
+ fun identifyExternalUserResponse(jsonPayload: String, callId: String, promise: Promise) {
168
+ val continuation = synchronized(this) { pendingIdentifyCalls.remove(callId) }
169
+ continuation?.resume(jsonPayload)
170
+ promise.resolve(null)
171
+ }
172
+
103
173
  @ReactMethod
104
174
  fun setUserId(userId: String, promise: Promise) {
105
175
  try {
@@ -8,6 +8,19 @@ RCT_EXTERN_METHOD(status:(RCTPromiseResolveBlock)resolve
8
8
  RCT_EXTERN_METHOD(currentUserId:(RCTPromiseResolveBlock)resolve
9
9
  rejecter:(RCTPromiseRejectBlock)reject)
10
10
 
11
+ RCT_EXTERN_METHOD(identifiedExternalUser:(RCTPromiseResolveBlock)resolve
12
+ rejecter:(RCTPromiseRejectBlock)reject)
13
+
14
+ RCT_EXTERN_METHOD(identifyExternalUser:(NSString *)externalUserId
15
+ callId:(NSString *)callId
16
+ resolver:(RCTPromiseResolveBlock)resolve
17
+ rejecter:(RCTPromiseRejectBlock)reject)
18
+
19
+ RCT_EXTERN_METHOD(identifyExternalUserResponse:(NSString *)payload
20
+ callId:(NSString *)callId
21
+ resolver:(RCTPromiseResolveBlock)resolve
22
+ rejecter:(RCTPromiseRejectBlock)reject)
23
+
11
24
  RCT_EXTERN_METHOD(signIn:(NSString *)token
12
25
  resolver:(RCTPromiseResolveBlock)resolve
13
26
  rejecter:(RCTPromiseRejectBlock)reject)
@@ -2,13 +2,17 @@ import VitalCore
2
2
 
3
3
  private let errorKey = "VitalCoreError"
4
4
  private let statusEventKey = "VitalClientStatus"
5
+ private let identifyExternalUserRequestKey = "IdentifyExternalUserRequest"
5
6
 
6
7
  @objc(VitalCoreReactNative)
7
8
  class VitalCoreReactNative: RCTEventEmitter {
8
9
  private var statusObservation: Task<Void, Never>?
9
10
 
11
+ private let lock = NSLock()
12
+ private var pendingIdentifyResponses: [String: CheckedContinuation<String, Never>] = [:]
13
+
10
14
  override func supportedEvents() -> [String]! {
11
- [statusEventKey]
15
+ [statusEventKey, identifyExternalUserRequestKey]
12
16
  }
13
17
 
14
18
  override func startObserving() {
@@ -33,6 +37,48 @@ class VitalCoreReactNative: RCTEventEmitter {
33
37
  func currentUserId(resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
34
38
  resolve(VitalClient.currentUserId)
35
39
  }
40
+ @objc(identifiedExternalUser:rejecter:)
41
+ func identifiedExternalUser(resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
42
+ resolve(VitalClient.identifiedExternalUser)
43
+ }
44
+
45
+ @objc(identifyExternalUser:callId:resolver:rejecter:)
46
+ func identifyExternalUser(_ externalUserId: String, callId: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
47
+ Task {
48
+ do {
49
+ try await VitalClient.identifyExternalUser(externalUserId) { @MainActor externalUserId in
50
+ // Setup a listener
51
+ let rawResponse: String = await withCheckedContinuation { continuation in
52
+
53
+ // Register the continuation
54
+ lock.withLock { self.pendingIdentifyResponses[callId] = continuation }
55
+
56
+ // Send the request to JS land, which should eventually invoke the continuation
57
+ // via `identifyExternalUserResponse(4)`.
58
+ self.sendEvent(withName: identifyExternalUserRequestKey, body: [callId, externalUserId])
59
+ }
60
+
61
+ let decoder = JSONDecoder()
62
+ switch try decoder.decode(ReactNativeAuthenticateRequest.self, from: rawResponse.data(using: .utf8)!) {
63
+ case let .apiKey(userId, key, environment):
64
+ return .apiKey(key: key, userId: userId, environment)
65
+ case let .signInToken(token):
66
+ return .signInToken(rawToken: token)
67
+ }
68
+ }
69
+ resolve(())
70
+ } catch let error {
71
+ reject("VitalCoreError", "\(error)", error)
72
+ }
73
+ }
74
+ }
75
+
76
+ @objc(identifyExternalUserResponse:callId:resolver:rejecter:)
77
+ func identifyExternalUserResponse(_ jsonPayload: String, _ callId: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
78
+ let continuation = lock.withLock { self.pendingIdentifyResponses.removeValue(forKey: callId) }
79
+ defer { resolve(()) }
80
+ continuation?.resume(returning: jsonPayload)
81
+ }
36
82
 
37
83
  @objc(signIn:resolver:rejecter:)
38
84
  func signIn(withToken token: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
@@ -260,3 +306,52 @@ extension VitalClient.Status {
260
306
  return strings
261
307
  }
262
308
  }
309
+
310
+ enum ReactNativeAuthenticateRequest: Decodable {
311
+ case signInToken(String)
312
+ case apiKey(userId: String, key: String, environment: Environment)
313
+
314
+ enum CodingKeys: CodingKey {
315
+ case type
316
+ case rawToken
317
+ case userId
318
+ case key
319
+ case environment
320
+ case region
321
+ }
322
+
323
+ init(from decoder: any Decoder) throws {
324
+ let container = try decoder.container(keyedBy: CodingKeys.self)
325
+
326
+ switch try container.decode(String.self, forKey: .type) {
327
+ case "signInToken":
328
+ self = .signInToken(try container.decode(String.self, forKey: .rawToken))
329
+ case "apiKey":
330
+
331
+ let env: Environment
332
+ let rawEnv = try container.decode(String.self, forKey: .environment)
333
+ let rawRegion = try container.decode(String.self, forKey: .region)
334
+
335
+ switch (rawEnv, rawRegion) {
336
+ case ("production", "us"):
337
+ env = .production(.us)
338
+ case ("production", "eu"):
339
+ env = .production(.eu)
340
+ case ("sandbox", "us"):
341
+ env = .sandbox(.us)
342
+ case ("sandbox", "eu"):
343
+ env = .sandbox(.eu)
344
+ default:
345
+ throw DecodingError.dataCorruptedError(forKey: .environment, in: container, debugDescription: "unsupported: \(rawEnv) \(rawRegion)")
346
+ }
347
+
348
+ self = .apiKey(
349
+ userId: try container.decode(String.self, forKey: .userId),
350
+ key: try container.decode(String.self, forKey: .key),
351
+ environment: env
352
+ )
353
+ case let value:
354
+ throw DecodingError.dataCorruptedError(forKey: .type, in: container, debugDescription: "unrecognized: \(value)")
355
+ }
356
+ }
357
+ }
@@ -52,7 +52,7 @@ Object.keys(_TimeSeriesData).forEach(function (key) {
52
52
  });
53
53
  });
54
54
  var _Provider = require("./models/Provider");
55
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
55
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
56
56
  const LINKING_ERROR = `The package 'vital-core-react-native' doesn't seem to be linked. Make sure: \n\n` + _reactNative.Platform.select({
57
57
  ios: "- You have run 'pod install'\n",
58
58
  default: ''
@@ -70,29 +70,92 @@ class VitalCore {
70
70
  static currentUserId() {
71
71
  return VitalCoreReactNative.currentUserId();
72
72
  }
73
+
74
+ /**
75
+ * The currently identified External User ID of the Mobile SDK.
76
+ * This has meaning only if you have migrated to [identifyExternalUser].
77
+ */
78
+ static identifiedExternalUser() {
79
+ return VitalCoreReactNative.identifiedExternalUser();
80
+ }
73
81
  static status() {
74
82
  return VitalCoreReactNative.status();
75
83
  }
84
+
85
+ /**
86
+ * Identify your user to the Vital Mobile SDK with an external user identifier from your system.
87
+ *
88
+ * This is _external_ with respect to the SDK. From your perspective, this would be your _internal_ user identifier.
89
+ *
90
+ * If the identified external user is not what the SDK has last seen, or has last successfully signed-in:
91
+ * 1. The SDK calls your supplied [authenticate] lambda.
92
+ * 2. Your lambda obtains a Vital Sign-In Token **from your backend service** and returns it.
93
+ * 3. The SDK performs the following actions:
94
+ *
95
+ * | SDK Signed-In User | The supplied Sign-In Token | Outcome |
96
+ * | ------ | ------ | ------ |
97
+ * | User A | User B | Sign out user A, then Sign in user B |
98
+ * | User A | User A | No-op |
99
+ * | None | User A | Sign In user A |
100
+ *
101
+ * Your [authenticate] lambda can throw CancellationError to abort the identify operation.
102
+ *
103
+ * You should identify at regular and significant moments in your app user lifecycle to ensure that it stays in sync with
104
+ * the Vital Mobile SDK user state. For example:
105
+ *
106
+ * 1. Identify your user after you signed in a new user.
107
+ * 2. Identify your user again after you have reloaded user state from persistent storage (e.g. [SharedPreferences]) post app launch.
108
+ *
109
+ * You can query the current identified user through [identifiedExternalUser].
110
+ *
111
+ * ## Notes on migrating from [signIn]
112
+ *
113
+ * [identifyExternalUser] does not perform any action or [VitalCore.signOut] when the Sign-In Token you supplied belongs
114
+ * to the already signed-in Vital User — regardless of whether the sign-in happened prior to or after the introduction of
115
+ * [identifyExternalUser].
116
+ *
117
+ * Because of this behaviour, you can migrate by simply replacing [signIn] with [identifyExternalUser].
118
+ * There is no precaution in SDK State — e.g., the Health SDK data sync state — being unintentionally reset.
119
+ */
120
+ static async identifyExternalUser(externalUserId, authenticate) {
121
+ const callId = new Date().getTime().toString();
122
+
123
+ // Android/iOS sends IdentifyExternalUserRequest when the SDK detects an external user ID change,
124
+ // and needs new credentials to sign-in the new user.
125
+ const listener = this.eventEmitter.addListener("IdentifyExternalUserRequest", args => {
126
+ const [eventCallId, eventExternalUserId] = args;
127
+ if (eventCallId !== callId) {
128
+ return;
129
+ }
130
+ authenticate(eventExternalUserId).then(request => {
131
+ VitalCoreReactNative.identifyExternalUserResponse(JSON.stringify(request), callId);
132
+ });
133
+ });
134
+ try {
135
+ await VitalCoreReactNative.identifyExternalUser(externalUserId, callId);
136
+ } finally {
137
+ listener.remove();
138
+ }
139
+ }
76
140
  static signIn(token) {
77
141
  return VitalCoreReactNative.signIn(token);
78
142
  }
79
143
  static observeStatusChange(listener) {
80
144
  var isCancelled = false;
81
- var subscription = {
82
- remove: () => {
83
- isCancelled = true;
145
+ const wrappedListener = status => {
146
+ if (isCancelled) {
147
+ return;
84
148
  }
149
+ listener(status);
85
150
  };
86
- this.status().then(initialStatus => {
87
- if (!isCancelled) {
88
- listener(initialStatus);
89
- let emitterSub = this.eventEmitter.addListener("VitalClientStatus", listener);
90
- subscription.remove = () => {
91
- emitterSub.remove();
92
- };
151
+ const subscription = this.eventEmitter.addListener("VitalClientStatus", wrappedListener);
152
+ this.status().then(wrappedListener);
153
+ return {
154
+ remove() {
155
+ isCancelled = true;
156
+ subscription.remove();
93
157
  }
94
- });
95
- return subscription;
158
+ };
96
159
  }
97
160
  static setUserId(userId) {
98
161
  return VitalCoreReactNative.setUserId(userId);
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","_VitalCoreStatus","_QuantitySample","_interopRequireDefault","_BloodPressureSample","_TimeSeriesData","Object","keys","forEach","key","prototype","hasOwnProperty","call","_exportNames","exports","defineProperty","enumerable","get","_Provider","e","__esModule","default","LINKING_ERROR","Platform","select","ios","VitalCoreReactNative","NativeModules","Proxy","Error","VitalCore","eventEmitter","NativeEventEmitter","setEventEmitter","emitter","currentUserId","status","signIn","token","observeStatusChange","listener","isCancelled","subscription","remove","then","initialStatus","emitterSub","addListener","setUserId","userId","configure","apiKey","environment","region","enableLogs","hasUserConnectedTo","provider","userConnections","deregisterProvider","getAccessToken","refreshToken","getVitalAPIHeaders","accessToken","sdkVersion","Promise","all","versionKey","OS","headers","signOut"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_reactNative","require","_VitalCoreStatus","_QuantitySample","_interopRequireDefault","_BloodPressureSample","_TimeSeriesData","Object","keys","forEach","key","prototype","hasOwnProperty","call","_exportNames","exports","defineProperty","enumerable","get","_Provider","obj","__esModule","default","LINKING_ERROR","Platform","select","ios","VitalCoreReactNative","NativeModules","Proxy","Error","VitalCore","eventEmitter","NativeEventEmitter","setEventEmitter","emitter","currentUserId","identifiedExternalUser","status","identifyExternalUser","externalUserId","authenticate","callId","Date","getTime","toString","listener","addListener","args","eventCallId","eventExternalUserId","then","request","identifyExternalUserResponse","JSON","stringify","remove","signIn","token","observeStatusChange","isCancelled","wrappedListener","subscription","setUserId","userId","configure","apiKey","environment","region","enableLogs","hasUserConnectedTo","provider","userConnections","deregisterProvider","getAccessToken","refreshToken","getVitalAPIHeaders","accessToken","sdkVersion","Promise","all","versionKey","OS","headers","signOut"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=AuthenticateRequest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"../../../src","sources":["models/AuthenticateRequest.ts"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sourceRoot":"../../../src","sources":["models/BloodPressureSample.ts"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sourceRoot":"../../../src","sources":["models/BloodPressureSample.ts"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"names":["ManualProviderSlug","exports","ProviderSlug"],"sourceRoot":"../../../src","sources":["models/Provider.ts"],"mappings":";;;;;;IAAYA,kBAAkB,GAAAC,OAAA,CAAAD,kBAAA,0BAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAA,OAAlBA,kBAAkB;AAAA;AAAA,IAWlBE,YAAY,GAAAD,OAAA,CAAAC,YAAA,0BAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAA,OAAZA,YAAY;AAAA","ignoreList":[]}
1
+ {"version":3,"names":["ManualProviderSlug","exports","ProviderSlug"],"sourceRoot":"../../../src","sources":["models/Provider.ts"],"mappings":";;;;;;IAAYA,kBAAkB,GAAAC,OAAA,CAAAD,kBAAA,0BAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAA,OAAlBA,kBAAkB;AAAA;AAAA,IAWlBE,YAAY,GAAAD,OAAA,CAAAC,YAAA,0BAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAA,OAAZA,YAAY;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sourceRoot":"../../../src","sources":["models/QuantitySample.ts"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sourceRoot":"../../../src","sources":["models/QuantitySample.ts"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sourceRoot":"../../../src","sources":["models/TimeSeriesData.ts"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sourceRoot":"../../../src","sources":["models/TimeSeriesData.ts"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sourceRoot":"../../../src","sources":["models/VitalCoreStatus.ts"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sourceRoot":"../../../src","sources":["models/VitalCoreStatus.ts"],"mappings":""}
@@ -1,5 +1,3 @@
1
- "use strict";
2
-
3
1
  import { NativeEventEmitter, NativeModules, Platform } from 'react-native';
4
2
  export { VitalCoreStatus } from './models/VitalCoreStatus';
5
3
  export { default as QuantitySample } from './models/QuantitySample';
@@ -23,29 +21,92 @@ export class VitalCore {
23
21
  static currentUserId() {
24
22
  return VitalCoreReactNative.currentUserId();
25
23
  }
24
+
25
+ /**
26
+ * The currently identified External User ID of the Mobile SDK.
27
+ * This has meaning only if you have migrated to [identifyExternalUser].
28
+ */
29
+ static identifiedExternalUser() {
30
+ return VitalCoreReactNative.identifiedExternalUser();
31
+ }
26
32
  static status() {
27
33
  return VitalCoreReactNative.status();
28
34
  }
35
+
36
+ /**
37
+ * Identify your user to the Vital Mobile SDK with an external user identifier from your system.
38
+ *
39
+ * This is _external_ with respect to the SDK. From your perspective, this would be your _internal_ user identifier.
40
+ *
41
+ * If the identified external user is not what the SDK has last seen, or has last successfully signed-in:
42
+ * 1. The SDK calls your supplied [authenticate] lambda.
43
+ * 2. Your lambda obtains a Vital Sign-In Token **from your backend service** and returns it.
44
+ * 3. The SDK performs the following actions:
45
+ *
46
+ * | SDK Signed-In User | The supplied Sign-In Token | Outcome |
47
+ * | ------ | ------ | ------ |
48
+ * | User A | User B | Sign out user A, then Sign in user B |
49
+ * | User A | User A | No-op |
50
+ * | None | User A | Sign In user A |
51
+ *
52
+ * Your [authenticate] lambda can throw CancellationError to abort the identify operation.
53
+ *
54
+ * You should identify at regular and significant moments in your app user lifecycle to ensure that it stays in sync with
55
+ * the Vital Mobile SDK user state. For example:
56
+ *
57
+ * 1. Identify your user after you signed in a new user.
58
+ * 2. Identify your user again after you have reloaded user state from persistent storage (e.g. [SharedPreferences]) post app launch.
59
+ *
60
+ * You can query the current identified user through [identifiedExternalUser].
61
+ *
62
+ * ## Notes on migrating from [signIn]
63
+ *
64
+ * [identifyExternalUser] does not perform any action or [VitalCore.signOut] when the Sign-In Token you supplied belongs
65
+ * to the already signed-in Vital User — regardless of whether the sign-in happened prior to or after the introduction of
66
+ * [identifyExternalUser].
67
+ *
68
+ * Because of this behaviour, you can migrate by simply replacing [signIn] with [identifyExternalUser].
69
+ * There is no precaution in SDK State — e.g., the Health SDK data sync state — being unintentionally reset.
70
+ */
71
+ static async identifyExternalUser(externalUserId, authenticate) {
72
+ const callId = new Date().getTime().toString();
73
+
74
+ // Android/iOS sends IdentifyExternalUserRequest when the SDK detects an external user ID change,
75
+ // and needs new credentials to sign-in the new user.
76
+ const listener = this.eventEmitter.addListener("IdentifyExternalUserRequest", args => {
77
+ const [eventCallId, eventExternalUserId] = args;
78
+ if (eventCallId !== callId) {
79
+ return;
80
+ }
81
+ authenticate(eventExternalUserId).then(request => {
82
+ VitalCoreReactNative.identifyExternalUserResponse(JSON.stringify(request), callId);
83
+ });
84
+ });
85
+ try {
86
+ await VitalCoreReactNative.identifyExternalUser(externalUserId, callId);
87
+ } finally {
88
+ listener.remove();
89
+ }
90
+ }
29
91
  static signIn(token) {
30
92
  return VitalCoreReactNative.signIn(token);
31
93
  }
32
94
  static observeStatusChange(listener) {
33
95
  var isCancelled = false;
34
- var subscription = {
35
- remove: () => {
36
- isCancelled = true;
96
+ const wrappedListener = status => {
97
+ if (isCancelled) {
98
+ return;
37
99
  }
100
+ listener(status);
38
101
  };
39
- this.status().then(initialStatus => {
40
- if (!isCancelled) {
41
- listener(initialStatus);
42
- let emitterSub = this.eventEmitter.addListener("VitalClientStatus", listener);
43
- subscription.remove = () => {
44
- emitterSub.remove();
45
- };
102
+ const subscription = this.eventEmitter.addListener("VitalClientStatus", wrappedListener);
103
+ this.status().then(wrappedListener);
104
+ return {
105
+ remove() {
106
+ isCancelled = true;
107
+ subscription.remove();
46
108
  }
47
- });
48
- return subscription;
109
+ };
49
110
  }
50
111
  static setUserId(userId) {
51
112
  return VitalCoreReactNative.setUserId(userId);
@@ -1 +1 @@
1
- {"version":3,"names":["NativeEventEmitter","NativeModules","Platform","VitalCoreStatus","default","QuantitySample","BloodPressureSample","ManualProviderSlug","LINKING_ERROR","select","ios","VitalCoreReactNative","Proxy","get","Error","VitalCore","eventEmitter","setEventEmitter","emitter","currentUserId","status","signIn","token","observeStatusChange","listener","isCancelled","subscription","remove","then","initialStatus","emitterSub","addListener","setUserId","userId","configure","apiKey","environment","region","enableLogs","hasUserConnectedTo","provider","userConnections","deregisterProvider","getAccessToken","refreshToken","getVitalAPIHeaders","accessToken","sdkVersion","Promise","all","versionKey","OS","headers","signOut"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["NativeEventEmitter","NativeModules","Platform","VitalCoreStatus","default","QuantitySample","BloodPressureSample","ManualProviderSlug","LINKING_ERROR","select","ios","VitalCoreReactNative","Proxy","get","Error","VitalCore","eventEmitter","setEventEmitter","emitter","currentUserId","identifiedExternalUser","status","identifyExternalUser","externalUserId","authenticate","callId","Date","getTime","toString","listener","addListener","args","eventCallId","eventExternalUserId","then","request","identifyExternalUserResponse","JSON","stringify","remove","signIn","token","observeStatusChange","isCancelled","wrappedListener","subscription","setUserId","userId","configure","apiKey","environment","region","enableLogs","hasUserConnectedTo","provider","userConnections","deregisterProvider","getAccessToken","refreshToken","getVitalAPIHeaders","accessToken","sdkVersion","Promise","all","versionKey","OS","headers","signOut"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+
2
+ //# sourceMappingURL=AuthenticateRequest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"../../../src","sources":["models/AuthenticateRequest.ts"],"mappings":""}
@@ -1,2 +1,2 @@
1
- "use strict";
1
+
2
2
  //# sourceMappingURL=BloodPressureSample.js.map
@@ -1 +1 @@
1
- {"version":3,"names":[],"sourceRoot":"../../../src","sources":["models/BloodPressureSample.ts"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sourceRoot":"../../../src","sources":["models/BloodPressureSample.ts"],"mappings":""}
@@ -1,5 +1,3 @@
1
- "use strict";
2
-
3
1
  export let ManualProviderSlug = /*#__PURE__*/function (ManualProviderSlug) {
4
2
  ManualProviderSlug["BeurerBLE"] = "beurer_ble";
5
3
  ManualProviderSlug["OmronBLE"] = "omron_ble";
@@ -1 +1 @@
1
- {"version":3,"names":["ManualProviderSlug","ProviderSlug"],"sourceRoot":"../../../src","sources":["models/Provider.ts"],"mappings":";;AAAA,WAAYA,kBAAkB,0BAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAA,OAAlBA,kBAAkB;AAAA;AAW9B,WAAYC,YAAY,0BAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAA,OAAZA,YAAY;AAAA","ignoreList":[]}
1
+ {"version":3,"names":["ManualProviderSlug","ProviderSlug"],"sourceRoot":"../../../src","sources":["models/Provider.ts"],"mappings":"AAAA,WAAYA,kBAAkB,0BAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAA,OAAlBA,kBAAkB;AAAA;AAW9B,WAAYC,YAAY,0BAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAA,OAAZA,YAAY;AAAA"}
@@ -1,2 +1,2 @@
1
- "use strict";
1
+
2
2
  //# sourceMappingURL=QuantitySample.js.map
@@ -1 +1 @@
1
- {"version":3,"names":[],"sourceRoot":"../../../src","sources":["models/QuantitySample.ts"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sourceRoot":"../../../src","sources":["models/QuantitySample.ts"],"mappings":""}
@@ -1,4 +1,2 @@
1
- "use strict";
2
-
3
1
  export {};
4
2
  //# sourceMappingURL=TimeSeriesData.js.map
@@ -1 +1 @@
1
- {"version":3,"names":[],"sourceRoot":"../../../src","sources":["models/TimeSeriesData.ts"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sourceRoot":"../../../src","sources":["models/TimeSeriesData.ts"],"mappings":""}
@@ -1,2 +1,2 @@
1
- "use strict";
1
+
2
2
  //# sourceMappingURL=VitalCoreStatus.js.map
@@ -1 +1 @@
1
- {"version":3,"names":[],"sourceRoot":"../../../src","sources":["models/VitalCoreStatus.ts"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sourceRoot":"../../../src","sources":["models/VitalCoreStatus.ts"],"mappings":""}
@@ -1,6 +1,7 @@
1
1
  import { NativeEventEmitter } from 'react-native';
2
2
  import type { ManualProviderSlug, ProviderSlug, UserConnection } from './models/Provider';
3
3
  import type { VitalCoreStatus } from './models/VitalCoreStatus';
4
+ import type { AuthenticateRequest } from './models/AuthenticateRequest';
4
5
  export { VitalCoreStatus } from './models/VitalCoreStatus';
5
6
  export { default as QuantitySample } from './models/QuantitySample';
6
7
  export { default as BloodPressureSample } from './models/BloodPressureSample';
@@ -13,7 +14,48 @@ export declare class VitalCore {
13
14
  private static eventEmitter;
14
15
  static setEventEmitter(emitter: NativeEventEmitter): void;
15
16
  static currentUserId(): Promise<string | null>;
17
+ /**
18
+ * The currently identified External User ID of the Mobile SDK.
19
+ * This has meaning only if you have migrated to [identifyExternalUser].
20
+ */
21
+ static identifiedExternalUser(): Promise<string | null>;
16
22
  static status(): Promise<VitalCoreStatus[]>;
23
+ /**
24
+ * Identify your user to the Vital Mobile SDK with an external user identifier from your system.
25
+ *
26
+ * This is _external_ with respect to the SDK. From your perspective, this would be your _internal_ user identifier.
27
+ *
28
+ * If the identified external user is not what the SDK has last seen, or has last successfully signed-in:
29
+ * 1. The SDK calls your supplied [authenticate] lambda.
30
+ * 2. Your lambda obtains a Vital Sign-In Token **from your backend service** and returns it.
31
+ * 3. The SDK performs the following actions:
32
+ *
33
+ * | SDK Signed-In User | The supplied Sign-In Token | Outcome |
34
+ * | ------ | ------ | ------ |
35
+ * | User A | User B | Sign out user A, then Sign in user B |
36
+ * | User A | User A | No-op |
37
+ * | None | User A | Sign In user A |
38
+ *
39
+ * Your [authenticate] lambda can throw CancellationError to abort the identify operation.
40
+ *
41
+ * You should identify at regular and significant moments in your app user lifecycle to ensure that it stays in sync with
42
+ * the Vital Mobile SDK user state. For example:
43
+ *
44
+ * 1. Identify your user after you signed in a new user.
45
+ * 2. Identify your user again after you have reloaded user state from persistent storage (e.g. [SharedPreferences]) post app launch.
46
+ *
47
+ * You can query the current identified user through [identifiedExternalUser].
48
+ *
49
+ * ## Notes on migrating from [signIn]
50
+ *
51
+ * [identifyExternalUser] does not perform any action or [VitalCore.signOut] when the Sign-In Token you supplied belongs
52
+ * to the already signed-in Vital User — regardless of whether the sign-in happened prior to or after the introduction of
53
+ * [identifyExternalUser].
54
+ *
55
+ * Because of this behaviour, you can migrate by simply replacing [signIn] with [identifyExternalUser].
56
+ * There is no precaution in SDK State — e.g., the Health SDK data sync state — being unintentionally reset.
57
+ */
58
+ static identifyExternalUser(externalUserId: string, authenticate: (externalUserId: string) => Promise<AuthenticateRequest>): Promise<void>;
17
59
  static signIn(token: string): Promise<void>;
18
60
  static observeStatusChange(listener: (status: VitalCoreStatus[]) => void): Subscription;
19
61
  static setUserId(userId: string): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA2B,MAAM,cAAc,CAAC;AAC3E,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC1F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAEhE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAC9E,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAmBvD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAC,YAAY,CAA8D;IAEzF,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,kBAAkB;IAIlD,MAAM,CAAC,aAAa,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAI9C,MAAM,CAAC,MAAM,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAI3C,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,IAAI,GAAG,YAAY;IAgBvF,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C,MAAM,CAAC,SAAS,CACd,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,OAAO,GAClB,OAAO,CAAC,IAAI,CAAC;IAShB,MAAM,CAAC,kBAAkB,CACvB,QAAQ,EAAE,kBAAkB,GAC3B,OAAO,CAAC,OAAO,CAAC;IAInB,MAAM,CAAC,eAAe,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAInD,MAAM,CAAC,kBAAkB,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhE,MAAM,CAAC,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAIxC,MAAM,CAAC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;WAIvB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAiBlE,MAAM,CAAC,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAIpC,MAAM,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAGhC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA2B,MAAM,cAAc,CAAC;AAC3E,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC1F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAExE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAC9E,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAmBvD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAC,YAAY,CAA8D;IAEzF,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,kBAAkB;IAIlD,MAAM,CAAC,aAAa,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAI9C;;;OAGG;IACH,MAAM,CAAC,sBAAsB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIvD,MAAM,CAAC,MAAM,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAI3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkCG;WACU,oBAAoB,CAAC,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC,mBAAmB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BhJ,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,IAAI,GAAG,YAAY;IAoBvF,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C,MAAM,CAAC,SAAS,CACd,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,OAAO,GAClB,OAAO,CAAC,IAAI,CAAC;IAShB,MAAM,CAAC,kBAAkB,CACvB,QAAQ,EAAE,kBAAkB,GAC3B,OAAO,CAAC,OAAO,CAAC;IAInB,MAAM,CAAC,eAAe,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAInD,MAAM,CAAC,kBAAkB,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhE,MAAM,CAAC,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAIxC,MAAM,CAAC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;WAIvB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAiBlE,MAAM,CAAC,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAIpC,MAAM,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAGhC"}
@@ -0,0 +1,15 @@
1
+ export type Environment = "dev" | "sandbox" | "production";
2
+ export type Region = "us" | "eu";
3
+ export interface AuthenticateRequestSignInToken {
4
+ type: "signInToken";
5
+ rawToken: string;
6
+ }
7
+ export interface AuthenticateRequestAPIKey {
8
+ type: "apiKey";
9
+ key: string;
10
+ environment: Environment;
11
+ region: Region;
12
+ userId: string;
13
+ }
14
+ export type AuthenticateRequest = AuthenticateRequestSignInToken | AuthenticateRequestAPIKey;
15
+ //# sourceMappingURL=AuthenticateRequest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthenticateRequest.d.ts","sourceRoot":"","sources":["../../../src/models/AuthenticateRequest.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,SAAS,GAAG,YAAY,CAAC;AAC3D,MAAM,MAAM,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;AAEjC,MAAM,WAAW,8BAA8B;IAC3C,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,yBAAyB;IACtC,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,WAAW,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,mBAAmB,GAAG,8BAA8B,GAAG,yBAAyB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tryvital/vital-core-react-native",
3
- "version": "5.2.3",
3
+ "version": "5.3.0",
4
4
  "description": "test",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
package/src/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { NativeEventEmitter, NativeModules, Platform } from 'react-native';
2
2
  import type { ManualProviderSlug, ProviderSlug, UserConnection } from './models/Provider';
3
3
  import type { VitalCoreStatus } from './models/VitalCoreStatus';
4
+ import type { AuthenticateRequest } from './models/AuthenticateRequest';
4
5
 
5
6
  export { VitalCoreStatus } from './models/VitalCoreStatus';
6
7
  export { default as QuantitySample } from './models/QuantitySample';
@@ -40,28 +41,103 @@ export class VitalCore {
40
41
  return VitalCoreReactNative.currentUserId();
41
42
  }
42
43
 
44
+ /**
45
+ * The currently identified External User ID of the Mobile SDK.
46
+ * This has meaning only if you have migrated to [identifyExternalUser].
47
+ */
48
+ static identifiedExternalUser(): Promise<string | null> {
49
+ return VitalCoreReactNative.identifiedExternalUser();
50
+ }
51
+
43
52
  static status(): Promise<VitalCoreStatus[]> {
44
53
  return VitalCoreReactNative.status();
45
54
  }
46
55
 
56
+ /**
57
+ * Identify your user to the Vital Mobile SDK with an external user identifier from your system.
58
+ *
59
+ * This is _external_ with respect to the SDK. From your perspective, this would be your _internal_ user identifier.
60
+ *
61
+ * If the identified external user is not what the SDK has last seen, or has last successfully signed-in:
62
+ * 1. The SDK calls your supplied [authenticate] lambda.
63
+ * 2. Your lambda obtains a Vital Sign-In Token **from your backend service** and returns it.
64
+ * 3. The SDK performs the following actions:
65
+ *
66
+ * | SDK Signed-In User | The supplied Sign-In Token | Outcome |
67
+ * | ------ | ------ | ------ |
68
+ * | User A | User B | Sign out user A, then Sign in user B |
69
+ * | User A | User A | No-op |
70
+ * | None | User A | Sign In user A |
71
+ *
72
+ * Your [authenticate] lambda can throw CancellationError to abort the identify operation.
73
+ *
74
+ * You should identify at regular and significant moments in your app user lifecycle to ensure that it stays in sync with
75
+ * the Vital Mobile SDK user state. For example:
76
+ *
77
+ * 1. Identify your user after you signed in a new user.
78
+ * 2. Identify your user again after you have reloaded user state from persistent storage (e.g. [SharedPreferences]) post app launch.
79
+ *
80
+ * You can query the current identified user through [identifiedExternalUser].
81
+ *
82
+ * ## Notes on migrating from [signIn]
83
+ *
84
+ * [identifyExternalUser] does not perform any action or [VitalCore.signOut] when the Sign-In Token you supplied belongs
85
+ * to the already signed-in Vital User — regardless of whether the sign-in happened prior to or after the introduction of
86
+ * [identifyExternalUser].
87
+ *
88
+ * Because of this behaviour, you can migrate by simply replacing [signIn] with [identifyExternalUser].
89
+ * There is no precaution in SDK State — e.g., the Health SDK data sync state — being unintentionally reset.
90
+ */
91
+ static async identifyExternalUser(externalUserId: string, authenticate: (externalUserId: string) => Promise<AuthenticateRequest>): Promise<void> {
92
+ const callId = (new Date().getTime()).toString();
93
+
94
+ // Android/iOS sends IdentifyExternalUserRequest when the SDK detects an external user ID change,
95
+ // and needs new credentials to sign-in the new user.
96
+ const listener = this.eventEmitter.addListener(
97
+ "IdentifyExternalUserRequest",
98
+ (args) => {
99
+ const [eventCallId, eventExternalUserId] = args;
100
+
101
+ if (eventCallId !== callId) {
102
+ return;
103
+ }
104
+
105
+ authenticate(eventExternalUserId).then((request) => {
106
+ VitalCoreReactNative.identifyExternalUserResponse(JSON.stringify(request), callId);
107
+ });
108
+ }
109
+ );
110
+
111
+ try {
112
+ await VitalCoreReactNative.identifyExternalUser(externalUserId, callId);
113
+
114
+ } finally {
115
+ listener.remove()
116
+ }
117
+ }
118
+
47
119
  static signIn(token: string): Promise<void> {
48
120
  return VitalCoreReactNative.signIn(token);
49
121
  }
50
122
 
51
123
  static observeStatusChange(listener: (status: VitalCoreStatus[]) => void): Subscription {
52
124
  var isCancelled = false
53
- var subscription = { remove: () => { isCancelled = true } };
54
125
 
55
- this.status().then((initialStatus) => {
56
- if (!isCancelled) {
57
- listener(initialStatus);
58
-
59
- let emitterSub = this.eventEmitter.addListener("VitalClientStatus", listener)
60
- subscription.remove = () => { emitterSub.remove() }
126
+ const wrappedListener = (status: VitalCoreStatus[]) => {
127
+ if (isCancelled) {
128
+ return;
61
129
  }
62
- });
63
-
64
- return subscription
130
+ listener(status);
131
+ }
132
+ const subscription = this.eventEmitter.addListener("VitalClientStatus", wrappedListener);
133
+ this.status().then(wrappedListener);
134
+
135
+ return {
136
+ remove() {
137
+ isCancelled = true;
138
+ subscription.remove();
139
+ },
140
+ };
65
141
  }
66
142
 
67
143
  static setUserId(userId: string): Promise<void> {
@@ -0,0 +1,17 @@
1
+ export type Environment = "dev" | "sandbox" | "production";
2
+ export type Region = "us" | "eu";
3
+
4
+ export interface AuthenticateRequestSignInToken {
5
+ type: "signInToken";
6
+ rawToken: string;
7
+ }
8
+
9
+ export interface AuthenticateRequestAPIKey {
10
+ type: "apiKey";
11
+ key: string;
12
+ environment: Environment;
13
+ region: Region;
14
+ userId: string;
15
+ }
16
+
17
+ export type AuthenticateRequest = AuthenticateRequestSignInToken | AuthenticateRequestAPIKey;
@@ -1,7 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <Workspace
3
- version = "1.0">
4
- <FileRef
5
- location = "self:">
6
- </FileRef>
7
- </Workspace>
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
- <plist version="1.0">
4
- <dict>
5
- <key>IDEDidComputeMac32BitWarning</key>
6
- <true/>
7
- </dict>
8
- </plist>
@@ -1,14 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
- <plist version="1.0">
4
- <dict>
5
- <key>SchemeUserState</key>
6
- <dict>
7
- <key>VitalCoreReactNative.xcscheme_^#shared#^_</key>
8
- <dict>
9
- <key>orderHint</key>
10
- <integer>0</integer>
11
- </dict>
12
- </dict>
13
- </dict>
14
- </plist>
@@ -1 +0,0 @@
1
- {"type":"commonjs"}
@@ -1 +0,0 @@
1
- {"type":"module"}