@sentiance-react-native/user-context 6.11.0-rc.1 → 6.11.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.
@@ -10,9 +10,9 @@ import com.sentiance.sdk.usercontext.api.UserContextUpdateCriteria;
10
10
 
11
11
  import java.util.List;
12
12
 
13
- class SentianceUserContextEmitter extends AbstractSentianceEmitter {
13
+ public class SentianceUserContextEmitter extends AbstractSentianceEmitter {
14
14
 
15
- private static final String USER_CONTEXT_EVENT = "SENTIANCE_USER_CONTEXT_UPDATE_EVENT";
15
+ static final String USER_CONTEXT_EVENT = "SENTIANCE_USER_CONTEXT_UPDATE_EVENT";
16
16
  private final SentianceUserContextConverter converter;
17
17
 
18
18
  public SentianceUserContextEmitter(Context context) {
@@ -1,15 +1,19 @@
1
1
  package com.sentiance.react.bridge.usercontext;
2
2
 
3
+ import static com.sentiance.react.bridge.usercontext.SentianceUserContextEmitter.USER_CONTEXT_EVENT;
4
+
3
5
  import androidx.annotation.NonNull;
4
6
  import androidx.annotation.Nullable;
5
7
 
6
8
  import com.facebook.react.bridge.Promise;
7
9
  import com.facebook.react.bridge.ReactApplicationContext;
8
10
  import com.facebook.react.bridge.ReactMethod;
11
+ import com.facebook.react.bridge.ReadableMap;
9
12
  import com.sentiance.react.bridge.core.common.SentianceSubscriptionsManager;
10
13
  import com.sentiance.react.bridge.core.common.base.AbstractSentianceModule;
11
14
  import com.sentiance.react.bridge.usercontext.utils.ErrorCodes;
12
15
  import com.sentiance.sdk.Sentiance;
16
+ import com.sentiance.sdk.pendingoperation.PendingOperation;
13
17
  import com.sentiance.sdk.usercontext.api.RequestUserContextError;
14
18
  import com.sentiance.sdk.usercontext.api.UserContext;
15
19
  import com.sentiance.sdk.usercontext.api.UserContextApi;
@@ -17,82 +21,97 @@ import com.sentiance.sdk.usercontext.api.UserContextUpdateListener;
17
21
 
18
22
  public class SentianceUserContextModule extends AbstractSentianceModule {
19
23
 
20
- private static final String NATIVE_MODULE_NAME = "SentianceUserContext";
21
-
22
- private final SentianceUserContextEmitter emitter;
23
- private final SentianceUserContextConverter converter;
24
- private @Nullable
25
- UserContextUpdateListener mUserContextUpdateListener;
26
-
27
- public SentianceUserContextModule(ReactApplicationContext reactContext) {
28
- super(reactContext, Sentiance.getInstance(reactContext), new SentianceSubscriptionsManager());
29
- emitter = new SentianceUserContextEmitter(reactContext);
30
- converter = new SentianceUserContextConverter();
31
- }
32
-
33
- @NonNull
34
- @Override
35
- public String getName() {
36
- return NATIVE_MODULE_NAME;
37
- }
38
-
39
- @ReactMethod
40
- @SuppressWarnings("unused")
41
- public void requestUserContext(final Promise promise) {
42
- if (rejectIfNotInitialized(promise)) {
43
- return;
24
+ private static final String NATIVE_MODULE_NAME = "SentianceUserContext";
25
+ static final String JS_PAYLOAD_KEY_INCLUDE_PROVISIONAL_EVENTS = "includeProvisionalEvents";
26
+
27
+ private final SentianceUserContextEmitter mEmitter;
28
+ private final SentianceUserContextConverter mConverter;
29
+ private final UserContextApi mUserContextApi;
30
+
31
+ public SentianceUserContextModule(ReactApplicationContext reactContext,
32
+ Sentiance sentiance,
33
+ SentianceSubscriptionsManager subscriptionsManager,
34
+ SentianceUserContextEmitter emitter,
35
+ SentianceUserContextConverter converter,
36
+ UserContextApi userContextApi) {
37
+ super(reactContext, sentiance, subscriptionsManager);
38
+ mEmitter = emitter;
39
+ mConverter = converter;
40
+ mUserContextApi = userContextApi;
44
41
  }
45
42
 
46
- UserContextApi.getInstance(mReactContext)
47
- .requestUserContext()
48
- .addOnCompleteListener(pendingOperation -> {
49
- if (pendingOperation.isSuccessful()) {
50
- UserContext userContext = pendingOperation.getResult();
51
- promise.resolve(converter.convertUserContext(userContext));
52
- } else {
53
- RequestUserContextError error = pendingOperation.getError();
54
- promise.reject(ErrorCodes.E_SDK_REQUEST_USER_CONTEXT_ERROR,
55
- converter.stringifyGetUserContextError(error));
56
- }
57
- });
58
- }
59
-
60
- @ReactMethod
61
- @SuppressWarnings("unused")
62
- public void listenUserContextUpdates(Promise promise) {
63
- if (rejectIfNotInitialized(promise)) {
64
- return;
43
+ @Override
44
+ protected void addSupportedEventSubscriptions(SentianceSubscriptionsManager subscriptionsManager) {
45
+ mSubscriptionsManager.addSupportedSubscription(
46
+ USER_CONTEXT_EVENT,
47
+ mUserContextApi::addProvisionalAwareUserContextUpdateListener,
48
+ mUserContextApi::removeUserContextUpdateListener,
49
+ SentianceSubscriptionsManager.SubscriptionType.MULTIPLE
50
+ );
65
51
  }
66
52
 
67
- UserContextApi userContextApi = UserContextApi.getInstance(mReactContext);
68
-
69
- if (mUserContextUpdateListener != null) {
70
- userContextApi.removeUserContextUpdateListener(mUserContextUpdateListener);
53
+ @NonNull
54
+ @Override
55
+ public String getName() {
56
+ return NATIVE_MODULE_NAME;
71
57
  }
72
58
 
73
- mUserContextUpdateListener = emitter::sendUserContext;
59
+ @ReactMethod
60
+ @SuppressWarnings("unused")
61
+ public void requestUserContext(final boolean includeProvisionalEvents, final Promise promise) {
62
+ if (rejectIfNotInitialized(promise)) {
63
+ return;
64
+ }
74
65
 
75
- userContextApi.addUserContextUpdateListener(mUserContextUpdateListener);
76
- promise.resolve(true);
77
- }
66
+ PendingOperation<UserContext, RequestUserContextError> userContextRequest =
67
+ includeProvisionalEvents ? mUserContextApi.requestUserContextIncludingProvisionalEvents()
68
+ : mUserContextApi.requestUserContext();
69
+
70
+ userContextRequest.addOnCompleteListener(pendingOperation -> {
71
+ if (pendingOperation.isSuccessful()) {
72
+ UserContext userContext = pendingOperation.getResult();
73
+ promise.resolve(mConverter.convertUserContext(userContext));
74
+ } else {
75
+ RequestUserContextError error = pendingOperation.getError();
76
+ promise.reject(ErrorCodes.E_SDK_REQUEST_USER_CONTEXT_ERROR,
77
+ mConverter.stringifyGetUserContextError(error));
78
+ }
79
+ });
80
+ }
78
81
 
79
- @Override
80
- @ReactMethod
81
- protected void addNativeListener(String eventName, int subscriptionId, Promise promise) {
82
+ @Override
83
+ @ReactMethod
84
+ protected void addNativeListener(String eventName, int subscriptionId, @Nullable ReadableMap payload, Promise promise) {
85
+ if (rejectIfNotInitialized(promise)) {
86
+ return;
87
+ }
82
88
 
83
- }
89
+ switch (eventName) {
90
+ case USER_CONTEXT_EVENT:
91
+ mSubscriptionsManager.addSubscription(eventName, subscriptionId, (UserContextUpdateListener) mEmitter::sendUserContext);
92
+ break;
93
+ }
94
+ promise.resolve(null);
95
+ }
84
96
 
85
- @Override
86
- @ReactMethod
87
- protected void removeNativeListener(String eventName, int subscriptionId, Promise promise) {
97
+ @Override
98
+ @ReactMethod
99
+ protected void removeNativeListener(String eventName, int subscriptionId, Promise promise) {
100
+ if (rejectIfNotInitialized(promise)) {
101
+ return;
102
+ }
88
103
 
89
- }
104
+ mSubscriptionsManager.removeSubscription(subscriptionId, eventName);
105
+ promise.resolve(null);
106
+ }
90
107
 
91
- @Override
92
- @ReactMethod
93
- protected void addListener(String eventName) {}
108
+ @Override
109
+ @ReactMethod
110
+ protected void addListener(String eventName) {
111
+ }
94
112
 
95
- @Override
96
- @ReactMethod
97
- public void removeListeners(Integer count) {}
113
+ @Override
114
+ @ReactMethod
115
+ public void removeListeners(Integer count) {
116
+ }
98
117
  }
@@ -6,6 +6,9 @@ import com.facebook.react.ReactPackage;
6
6
  import com.facebook.react.bridge.NativeModule;
7
7
  import com.facebook.react.bridge.ReactApplicationContext;
8
8
  import com.facebook.react.uimanager.ViewManager;
9
+ import com.sentiance.react.bridge.core.common.SentianceSubscriptionsManager;
10
+ import com.sentiance.sdk.Sentiance;
11
+ import com.sentiance.sdk.usercontext.api.UserContextApi;
9
12
 
10
13
  import java.util.ArrayList;
11
14
  import java.util.Collections;
@@ -13,18 +16,25 @@ import java.util.List;
13
16
 
14
17
  public class SentianceUserContextPackage implements ReactPackage {
15
18
 
16
- @NonNull
17
- @Override
18
- public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
19
- List<NativeModule> modules = new ArrayList<>();
20
- SentianceUserContextModule module = new SentianceUserContextModule(reactContext);
21
- modules.add(module);
22
- return modules;
23
- }
19
+ @NonNull
20
+ @Override
21
+ public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
22
+ List<NativeModule> modules = new ArrayList<>();
23
+ SentianceUserContextModule module = new SentianceUserContextModule(
24
+ reactContext,
25
+ Sentiance.getInstance(reactContext),
26
+ new SentianceSubscriptionsManager(),
27
+ new SentianceUserContextEmitter(reactContext),
28
+ new SentianceUserContextConverter(),
29
+ UserContextApi.getInstance(reactContext)
30
+ );
31
+ modules.add(module);
32
+ return modules;
33
+ }
24
34
 
25
- @NonNull
26
- @Override
27
- public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
28
- return Collections.emptyList();
29
- }
35
+ @NonNull
36
+ @Override
37
+ public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
38
+ return Collections.emptyList();
39
+ }
30
40
  }
package/lib/index.d.ts CHANGED
@@ -193,6 +193,22 @@ declare module "@sentiance-react-native/user-context" {
193
193
  endTimeEpoch: number | null; // in milliseconds
194
194
  durationInSeconds: number | null;
195
195
  type: string;
196
+ /**
197
+ * Indicates whether the event is provisional.
198
+ *
199
+ * <p>A provisional event is identified based on real-time detections, but may change in the near future
200
+ * as more data is collected and processed, to filter out unwanted artifacts.
201
+ * For example, a provisional car transport may get identified, followed by a provisional bus transport.
202
+ * After the full trip is complete, these provisional events may get merged into a single final car event.</p>
203
+ *
204
+ * <p>Final events are generated independently of the provisional events, and have unique event IDs. They are
205
+ * not linked to the provisional events they may resemble, replace, or overlap with.</p>
206
+ *
207
+ * <p>Currently, provisional events apply only to 'transport' types, as the SDK tries to determine the mode of
208
+ * transport in (near) real time. When the full trip is complete (e.g. the user becomes stationary),
209
+ * the collected data is reprocessed to produce a more accurate and cleaned up list of transport events.</p>
210
+ */
211
+ isProvisional: boolean;
196
212
  // stationary event fields
197
213
  location: GeoLocation | null;
198
214
  venue: Venue | null;
@@ -260,10 +276,11 @@ declare module "@sentiance-react-native/user-context" {
260
276
  }
261
277
 
262
278
  export interface SentianceUserContext {
263
- requestUserContext(): Promise<UserContext>;
279
+ requestUserContext(includeProvisionalEvents?: boolean): Promise<UserContext>;
264
280
 
265
281
  addUserContextUpdateListener(
266
- onUserContextUpdated: (userContextUpdate: UserContextUpdate) => void
282
+ onUserContextUpdated: (userContextUpdate: UserContextUpdate) => void,
283
+ includeProvisionalEvents?: boolean
267
284
  ): Promise<EmitterSubscription>;
268
285
  }
269
286
 
package/lib/index.js CHANGED
@@ -1,9 +1,16 @@
1
- const userContext = require('./user-context');
1
+ const userContext = require("./user-context");
2
2
 
3
- const requestUserContext = () => userContext.requestUserContext();
4
- const addUserContextUpdateListener = userContext._addUserContextUpdateListener;
3
+ const requestUserContext = (includeProvisionalEvents) => {
4
+ // See: https://github.com/facebook/react-native/issues/24250
5
+ return userContext.requestUserContext(!!includeProvisionalEvents);
6
+ };
7
+ const addUserContextUpdateListener = (listener, includeProvisionalEvents) =>
8
+ userContext._addUserContextUpdateListener(listener, !!includeProvisionalEvents);
5
9
 
6
10
  module.exports = {
7
11
  requestUserContext,
8
12
  addUserContextUpdateListener
9
13
  };
14
+ module.exports.events = {
15
+ USER_CONTEXT_UPDATE_EVENT: userContext.events.USER_CONTEXT_UPDATE_EVENT
16
+ };
@@ -1,40 +1,61 @@
1
- const {NativeModules, NativeEventEmitter, Platform} = require("react-native");
2
- const {varToString} = require("@sentiance-react-native/core/lib/utils")
3
- const {SentianceUserContext, SentianceCore} = NativeModules;
1
+ const { NativeModules, Platform } = require("react-native");
2
+ const { varToString } = require("@sentiance-react-native/core/lib/generated/utils");
3
+ const SentianceEventEmitter = require("@sentiance-react-native/core/lib/generated/sentiance-event-emitter").default;
4
+ const { SentianceUserContext, SentianceCore } = NativeModules;
4
5
 
6
+ const allUserContextCriteria = ["CURRENT_EVENT", "ACTIVE_SEGMENTS", "VISITED_VENUES"];
5
7
  const SDK_USER_CONTEXT_UPDATE_EVENT = "SENTIANCE_USER_CONTEXT_UPDATE_EVENT";
6
8
 
7
9
  let didLocateNativeModule = true;
8
10
  let userContextModule = {};
9
- if (Platform.OS === 'android') {
11
+ if (Platform.OS === "android") {
10
12
  if (!SentianceUserContext) {
11
13
  didLocateNativeModule = false;
12
- const nativeModuleName = varToString({SentianceUserContext});
14
+ const nativeModuleName = varToString({ SentianceUserContext });
13
15
  console.error(`Could not locate the native ${nativeModuleName} module.
14
16
  Make sure that your native code is properly linked, and that the module name you specified is correct.`);
15
17
  } else {
16
- userContextModule = SentianceUserContext
18
+ userContextModule = SentianceUserContext;
17
19
  }
18
20
  } else {
19
21
  if (!SentianceCore) {
20
22
  didLocateNativeModule = false;
21
- const nativeModuleName = varToString({SentianceCore});
23
+ const nativeModuleName = varToString({ SentianceCore });
22
24
  console.error(`Could not locate the native ${nativeModuleName} module.
23
25
  Make sure that your native code is properly linked, and that the module name you specified is correct.`);
24
26
  } else {
25
- userContextModule = SentianceCore
27
+ userContextModule = SentianceCore;
26
28
  }
27
29
  }
28
30
 
29
31
  if (didLocateNativeModule) {
30
- const SENTIANCE_EMITTER = new NativeEventEmitter(userContextModule);
32
+ const emitter = new SentianceEventEmitter(userContextModule);
31
33
 
32
- userContextModule._addUserContextUpdateListener = async (onUserContextUpdated) => {
33
- await userContextModule.listenUserContextUpdates();
34
- return SENTIANCE_EMITTER.addListener(SDK_USER_CONTEXT_UPDATE_EVENT, (data) => {
35
- onUserContextUpdated(data);
36
- });
34
+ userContextModule._addUserContextUpdateListener = async (onUserContextUpdated, includeProvisionalEvents) => {
35
+ const payload = {
36
+ includeProvisionalEvents: true
37
+ };
38
+ return emitter.addListener(
39
+ SDK_USER_CONTEXT_UPDATE_EVENT,
40
+ async function(update) {
41
+ if (includeProvisionalEvents) {
42
+ // If the JS listener is interested in provisional events, we deliver the update as is
43
+ onUserContextUpdated(update);
44
+ } else {
45
+ // Otherwise, we query for a fresh user context without provisional events
46
+ const userContext = await userContextModule.requestUserContext(false);
47
+ onUserContextUpdated({
48
+ userContext,
49
+ criteria: allUserContextCriteria
50
+ });
51
+ }
52
+ },
53
+ payload
54
+ );
37
55
  };
38
56
  }
39
57
 
40
58
  module.exports = userContextModule;
59
+ module.exports.events = {
60
+ USER_CONTEXT_UPDATE_EVENT: SDK_USER_CONTEXT_UPDATE_EVENT
61
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentiance-react-native/user-context",
3
- "version": "6.11.0-rc.1",
3
+ "version": "6.11.0",
4
4
  "description": "The Sentiance User Context library",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
@@ -14,7 +14,7 @@
14
14
  "sentiance"
15
15
  ],
16
16
  "peerDependencies": {
17
- "@sentiance-react-native/core": "6.11.0-rc.1"
17
+ "@sentiance-react-native/core": "6.11.0"
18
18
  },
19
19
  "author": "",
20
20
  "license": "",