react-native-usesense 1.0.0 → 2.0.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.
@@ -5,173 +5,194 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = exports.UseSense = void 0;
7
7
  var _reactNative = require("react-native");
8
- const {
9
- UseSenseModule
10
- } = _reactNative.NativeModules;
8
+ const LINKING_ERROR = `react-native-usesense: the native module could not be found.\n\n` + _reactNative.Platform.select({
9
+ ios: `iOS: run \`cd ios && pod install\` and rebuild the app.`,
10
+ android: `Android: rebuild the app after installing the package.`,
11
+ default: ''
12
+ }) + `\n\nIf you're using Expo, the plugin must be consumed through a development build; it does not support Expo Go because it wraps a native camera SDK.`;
13
+ const UseSenseModule = _reactNative.NativeModules.UseSenseModule;
11
14
  if (!UseSenseModule) {
12
- throw new Error('react-native-usesense: NativeModule not found. Make sure you have linked the library correctly.\n' + 'iOS: Run `cd ios && pod install`\n' + 'Android: Rebuild the app after installing the package.');
15
+ throw new Error(LINKING_ERROR);
13
16
  }
14
17
 
15
- // ─── Types ───────────────────────────────────────────────────────────
18
+ // ─── Types ───────────────────────────────────────────────────────────────
16
19
 
17
- /** Environment for the UseSense API. */
20
+ /**
21
+ * Target environment for the UseSense API. `auto` asks the native SDK
22
+ * to detect from the API key prefix (`sk_sandbox_*` → sandbox,
23
+ * `sk_prod_*` → production).
24
+ */
18
25
 
19
- /** Session type for verification. */
26
+ /** Type of verification session. */
20
27
 
21
- /** Challenge policy controlling verification difficulty. */
28
+ /**
29
+ * Decision returned by the native SDK.
30
+ *
31
+ * These values come straight from the server's verdict and are
32
+ * exposed to the integrator for UI feedback only. The definitive
33
+ * verdict arrives at your backend via an HMAC-signed webhook; never
34
+ * trust the client-side decision for access-control.
35
+ */
22
36
 
23
- /** Decision returned by the verification engine. */
37
+ /**
38
+ * Branding overrides applied to the native camera UI.
39
+ *
40
+ * - `logoUrl`, `primaryColor`, `buttonRadius`, `fontFamily` are
41
+ * honoured on both iOS and Android.
42
+ * - `displayName`, `redirectUrl` are Android-only fields. They're
43
+ * accepted on iOS for cross-platform API parity but ignored.
44
+ */
24
45
 
25
- /** Processing stage during server-side analysis. */
46
+ /**
47
+ * Configuration for `UseSense.initialize`. The minimum required
48
+ * field is the API key; every other field has a sensible default.
49
+ */
26
50
 
27
51
  /**
28
- * Configuration for initializing the UseSense plugin.
29
- *
30
- * @example
31
- * ```ts
32
- * await UseSense.initialize({
33
- * apiKey: 'your_api_key',
34
- * environment: 'sandbox',
35
- * });
36
- * ```
52
+ * Request to start a verification session.
37
53
  */
38
54
 
39
55
  /**
40
- * Result returned when a verification session completes.
56
+ * Redacted decision object returned when a session completes.
41
57
  *
42
- * **Important:** This result is for UI feedback only.
43
- * The definitive verdict arrives at your backend via HMAC-signed webhook.
58
+ * This is the ONLY shape the plugin exposes to React Native. Pillar
59
+ * scores (channel trust, liveness, matchsense risk) are intentionally
60
+ * not included — the native SDKs strip those fields before returning
61
+ * across the bridge to prevent reverse-engineering of the server-side
62
+ * scoring logic. If you need full scoring details, consume the signed
63
+ * webhook delivered to your backend.
44
64
  */
45
65
 
46
66
  /**
47
- * Error returned when a verification session fails.
67
+ * Error thrown when a verification session fails.
68
+ *
69
+ * Matches the native SDKs' error shape: machine-readable code,
70
+ * human-readable message, retry hint.
48
71
  */
49
72
 
50
73
  /**
51
- * Events emitted during the verification session lifecycle.
74
+ * Lifecycle event types emitted by the native SDK during a
75
+ * verification session.
52
76
  */
53
77
 
54
- /** Options for starting a verification session. */
55
-
56
- /** Status of a verification session. */
78
+ /** Single event emitted during a session. */
57
79
 
58
- /** Subscription handle returned by {@link UseSense.addListener}. */
80
+ /** Handle returned by `UseSense.addListener`. */
59
81
 
60
- // ─── Implementation ──────────────────────────────────────────────────
82
+ // ─── Implementation ──────────────────────────────────────────────────────
61
83
 
62
84
  const eventEmitter = new _reactNative.NativeEventEmitter(UseSenseModule);
63
85
 
64
86
  /**
65
87
  * UseSense React Native plugin.
66
88
  *
67
- * Provides human presence verification by wrapping the native UseSense
68
- * iOS and Android SDKs into a single cross-platform API.
89
+ * Human presence verification wrapping the native iOS and Android
90
+ * UseSense SDKs. Every session runs inside a full-screen native
91
+ * camera activity; the plugin is a thin bridge that forwards
92
+ * initialization, verification requests, and lifecycle events to
93
+ * the platform SDK and returns a redacted decision object.
69
94
  *
70
95
  * @example
71
96
  * ```ts
72
97
  * import { UseSense } from 'react-native-usesense';
73
98
  *
74
- * await UseSense.initialize({ apiKey: 'your_key', environment: 'sandbox' });
75
- * const result = await UseSense.startSession({ sessionType: 'enrollment' });
76
- * console.log(result.decision);
99
+ * await UseSense.initialize({
100
+ * apiKey: 'sk_sandbox_...',
101
+ * environment: 'sandbox',
102
+ * });
103
+ *
104
+ * const unsubscribe = UseSense.addListener((event) => {
105
+ * console.log(event.type, event.data);
106
+ * });
107
+ *
108
+ * try {
109
+ * const result = await UseSense.startVerification({
110
+ * sessionType: 'enrollment',
111
+ * });
112
+ * console.log(result.decision); // 'APPROVE' | 'REJECT' | 'MANUAL_REVIEW'
113
+ * } finally {
114
+ * unsubscribe.remove();
115
+ * }
77
116
  * ```
78
117
  */
79
118
  class UseSense {
80
119
  /**
81
- * Initialize the UseSense plugin. Must be called once before any other method.
120
+ * Initialize the UseSense plugin. Must be called before any other
121
+ * method. Calling again with a different API key or environment
122
+ * replaces the previous configuration.
82
123
  *
83
- * @param config - Plugin configuration including API key and environment.
84
- * @throws {UseSenseError} If the API key is invalid or configuration is malformed.
124
+ * @throws {UseSenseError} If the API key is empty or initialization
125
+ * fails on the native side.
85
126
  */
86
127
  static async initialize(config) {
87
128
  if (!config.apiKey) {
88
- throw {
129
+ const err = {
89
130
  code: 'invalid_config',
90
- message: 'apiKey is required'
131
+ message: 'apiKey is required',
132
+ isRetryable: false
91
133
  };
134
+ throw err;
92
135
  }
93
136
  return UseSenseModule.initialize({
94
137
  apiKey: config.apiKey,
95
- environment: config.environment ?? 'sandbox',
96
- organizationId: config.organizationId,
97
- sessionType: config.sessionType ?? 'enrollment',
98
- identityId: config.identityId,
99
- challengePolicy: config.challengePolicy ?? 'standard',
100
- enableAudio: config.enableAudio ?? false,
101
- timeout: config.timeout ?? 60000,
102
- metadata: config.metadata
138
+ environment: config.environment ?? 'auto',
139
+ apiEndpoint: config.apiEndpoint,
140
+ branding: config.branding
103
141
  });
104
142
  }
105
143
 
106
144
  /**
107
- * Start a verification session. Presents a full-screen native camera UI.
108
- *
109
- * The returned promise resolves when the session completes and the modal
110
- * dismisses, or rejects if an error occurs.
111
- *
112
- * @param options - Optional overrides for session type and identity ID.
113
- * @returns The verification result (for UI feedback only).
114
- * @throws {UseSenseError} On failure or cancellation.
145
+ * Start a verification session. Presents a full-screen native
146
+ * camera activity. The returned promise resolves when the session
147
+ * completes or rejects with a `UseSenseError` (including the
148
+ * `USER_CANCELLED` / `session_cancelled` cases when the user
149
+ * dismisses the camera screen).
115
150
  */
116
- static async startSession(options) {
117
- return UseSenseModule.startSession(options ?? {});
118
- }
119
-
120
- /**
121
- * Cancel an in-progress verification session.
122
- *
123
- * The camera UI is dismissed and the `startSession` promise rejects
124
- * with a `session_cancelled` error.
125
- */
126
- static async cancelSession() {
127
- return UseSenseModule.cancelSession();
151
+ static async startVerification(request) {
152
+ return UseSenseModule.startVerification({
153
+ sessionType: request.sessionType,
154
+ externalUserId: request.externalUserId,
155
+ identityId: request.identityId,
156
+ metadata: request.metadata
157
+ });
128
158
  }
129
159
 
130
160
  /**
131
- * Get the status of a verification session by ID.
161
+ * Subscribe to real-time lifecycle events emitted by the native
162
+ * SDK during a verification session. Call this **before**
163
+ * `startVerification` so the subscription captures the earliest
164
+ * events (`SESSION_CREATED`, `PERMISSIONS_REQUESTED`).
132
165
  *
133
- * @param sessionId - The session ID to query.
134
- * @returns The current status and optional result.
166
+ * Returns a subscription handle; call `.remove()` to stop
167
+ * receiving events.
135
168
  */
136
- static async getSessionStatus(sessionId) {
137
- return UseSenseModule.getSessionStatus(sessionId);
169
+ static addListener(callback) {
170
+ const subscription = eventEmitter.addListener('UseSenseEvent', raw => {
171
+ callback(raw);
172
+ });
173
+ return {
174
+ remove: () => subscription.remove()
175
+ };
138
176
  }
139
177
 
140
178
  /**
141
- * Subscribe to real-time events during the verification lifecycle.
142
- *
143
- * Call this before `startSession()` to receive all events.
144
- *
145
- * @param callback - Function invoked for each event.
146
- * @returns A subscription handle with a `remove()` method.
147
- *
148
- * @example
149
- * ```ts
150
- * const listener = UseSense.addListener((event) => {
151
- * console.log(event.type);
152
- * });
153
- * // Later:
154
- * listener.remove();
155
- * ```
179
+ * Clear all event listeners and release native resources. Does not
180
+ * need to be called explicitly during normal usage; the plugin
181
+ * cleans up on process teardown. Useful when you want to re-
182
+ * initialize against a different API key or during test teardown.
156
183
  */
157
- static addListener(callback) {
158
- UseSenseModule.subscribeToEvents();
159
- const subscription = eventEmitter.addListener('UseSenseEvent', callback);
160
- return {
161
- remove: () => {
162
- subscription.remove();
163
- UseSenseModule.unsubscribeFromEvents();
164
- }
165
- };
184
+ static async reset() {
185
+ return UseSenseModule.reset();
166
186
  }
167
187
 
168
188
  /**
169
- * Get the native SDK version string.
170
- *
171
- * @returns Version string in semver format (e.g. `"1.0.0"`).
189
+ * Whether the native plugin has an active `UseSense` client. Set
190
+ * to `true` after a successful `initialize` and `false` after
191
+ * `reset`. Useful for feature-flagging UI that should only show
192
+ * when the SDK is ready.
172
193
  */
173
- static getSdkVersion() {
174
- return UseSenseModule.getSdkVersion();
194
+ static async isInitialized() {
195
+ return UseSenseModule.isInitialized();
175
196
  }
176
197
  }
177
198
  exports.UseSense = UseSense;
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","UseSenseModule","NativeModules","Error","eventEmitter","NativeEventEmitter","UseSense","initialize","config","apiKey","code","message","environment","organizationId","sessionType","identityId","challengePolicy","enableAudio","timeout","metadata","startSession","options","cancelSession","getSessionStatus","sessionId","addListener","callback","subscribeToEvents","subscription","remove","unsubscribeFromEvents","getSdkVersion","exports","_default","default"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAEA,MAAM;EAAEC;AAAe,CAAC,GAAGC,0BAAa;AAExC,IAAI,CAACD,cAAc,EAAE;EACnB,MAAM,IAAIE,KAAK,CACb,mGAAmG,GACjG,oCAAoC,GACpC,wDACJ,CAAC;AACH;;AAEA;;AAEA;;AAGA;;AAGA;;AAGA;;AAGA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAsBA;AACA;AACA;AACA;AACA;AACA;;AAwBA;AACA;AACA;;AAUA;AACA;AACA;;AASA;;AAQA;;AAQA;;AAMA;;AAEA,MAAMC,YAAY,GAAG,IAAIC,+BAAkB,CAACJ,cAAc,CAAC;;AAE3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMK,QAAQ,CAAC;EACpB;AACF;AACA;AACA;AACA;AACA;EACE,aAAaC,UAAUA,CAACC,MAAsB,EAAiB;IAC7D,IAAI,CAACA,MAAM,CAACC,MAAM,EAAE;MAClB,MAAM;QAAEC,IAAI,EAAE,gBAAgB;QAAEC,OAAO,EAAE;MAAqB,CAAC;IACjE;IACA,OAAOV,cAAc,CAACM,UAAU,CAAC;MAC/BE,MAAM,EAAED,MAAM,CAACC,MAAM;MACrBG,WAAW,EAAEJ,MAAM,CAACI,WAAW,IAAI,SAAS;MAC5CC,cAAc,EAAEL,MAAM,CAACK,cAAc;MACrCC,WAAW,EAAEN,MAAM,CAACM,WAAW,IAAI,YAAY;MAC/CC,UAAU,EAAEP,MAAM,CAACO,UAAU;MAC7BC,eAAe,EAAER,MAAM,CAACQ,eAAe,IAAI,UAAU;MACrDC,WAAW,EAAET,MAAM,CAACS,WAAW,IAAI,KAAK;MACxCC,OAAO,EAAEV,MAAM,CAACU,OAAO,IAAI,KAAK;MAChCC,QAAQ,EAAEX,MAAM,CAACW;IACnB,CAAC,CAAC;EACJ;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACE,aAAaC,YAAYA,CAACC,OAA6B,EAA2B;IAChF,OAAOpB,cAAc,CAACmB,YAAY,CAACC,OAAO,IAAI,CAAC,CAAC,CAAC;EACnD;;EAEA;AACF;AACA;AACA;AACA;AACA;EACE,aAAaC,aAAaA,CAAA,EAAkB;IAC1C,OAAOrB,cAAc,CAACqB,aAAa,CAAC,CAAC;EACvC;;EAEA;AACF;AACA;AACA;AACA;AACA;EACE,aAAaC,gBAAgBA,CAACC,SAAiB,EAA0B;IACvE,OAAOvB,cAAc,CAACsB,gBAAgB,CAACC,SAAS,CAAC;EACnD;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACE,OAAOC,WAAWA,CAACC,QAAwC,EAAwB;IACjFzB,cAAc,CAAC0B,iBAAiB,CAAC,CAAC;IAClC,MAAMC,YAAY,GAAGxB,YAAY,CAACqB,WAAW,CAAC,eAAe,EAAEC,QAAQ,CAAC;IACxE,OAAO;MACLG,MAAM,EAAEA,CAAA,KAAM;QACZD,YAAY,CAACC,MAAM,CAAC,CAAC;QACrB5B,cAAc,CAAC6B,qBAAqB,CAAC,CAAC;MACxC;IACF,CAAC;EACH;;EAEA;AACF;AACA;AACA;AACA;EACE,OAAOC,aAAaA,CAAA,EAAW;IAC7B,OAAO9B,cAAc,CAAC8B,aAAa,CAAC,CAAC;EACvC;AACF;AAACC,OAAA,CAAA1B,QAAA,GAAAA,QAAA;AAAA,IAAA2B,QAAA,GAAAD,OAAA,CAAAE,OAAA,GAEc5B,QAAQ","ignoreList":[]}
1
+ {"version":3,"names":["_reactNative","require","LINKING_ERROR","Platform","select","ios","android","default","UseSenseModule","NativeModules","Error","eventEmitter","NativeEventEmitter","UseSense","initialize","config","apiKey","err","code","message","isRetryable","environment","apiEndpoint","branding","startVerification","request","sessionType","externalUserId","identityId","metadata","addListener","callback","subscription","raw","remove","reset","isInitialized","exports","_default"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"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","ignoreList":[]}
@@ -1,171 +1,192 @@
1
- import { NativeModules, NativeEventEmitter } from 'react-native';
2
- const {
3
- UseSenseModule
4
- } = NativeModules;
1
+ import { NativeModules, NativeEventEmitter, Platform } from 'react-native';
2
+ const LINKING_ERROR = `react-native-usesense: the native module could not be found.\n\n` + Platform.select({
3
+ ios: `iOS: run \`cd ios && pod install\` and rebuild the app.`,
4
+ android: `Android: rebuild the app after installing the package.`,
5
+ default: ''
6
+ }) + `\n\nIf you're using Expo, the plugin must be consumed through a development build; it does not support Expo Go because it wraps a native camera SDK.`;
7
+ const UseSenseModule = NativeModules.UseSenseModule;
5
8
  if (!UseSenseModule) {
6
- throw new Error('react-native-usesense: NativeModule not found. Make sure you have linked the library correctly.\n' + 'iOS: Run `cd ios && pod install`\n' + 'Android: Rebuild the app after installing the package.');
9
+ throw new Error(LINKING_ERROR);
7
10
  }
8
11
 
9
- // ─── Types ───────────────────────────────────────────────────────────
12
+ // ─── Types ───────────────────────────────────────────────────────────────
10
13
 
11
- /** Environment for the UseSense API. */
14
+ /**
15
+ * Target environment for the UseSense API. `auto` asks the native SDK
16
+ * to detect from the API key prefix (`sk_sandbox_*` → sandbox,
17
+ * `sk_prod_*` → production).
18
+ */
12
19
 
13
- /** Session type for verification. */
20
+ /** Type of verification session. */
14
21
 
15
- /** Challenge policy controlling verification difficulty. */
22
+ /**
23
+ * Decision returned by the native SDK.
24
+ *
25
+ * These values come straight from the server's verdict and are
26
+ * exposed to the integrator for UI feedback only. The definitive
27
+ * verdict arrives at your backend via an HMAC-signed webhook; never
28
+ * trust the client-side decision for access-control.
29
+ */
16
30
 
17
- /** Decision returned by the verification engine. */
31
+ /**
32
+ * Branding overrides applied to the native camera UI.
33
+ *
34
+ * - `logoUrl`, `primaryColor`, `buttonRadius`, `fontFamily` are
35
+ * honoured on both iOS and Android.
36
+ * - `displayName`, `redirectUrl` are Android-only fields. They're
37
+ * accepted on iOS for cross-platform API parity but ignored.
38
+ */
18
39
 
19
- /** Processing stage during server-side analysis. */
40
+ /**
41
+ * Configuration for `UseSense.initialize`. The minimum required
42
+ * field is the API key; every other field has a sensible default.
43
+ */
20
44
 
21
45
  /**
22
- * Configuration for initializing the UseSense plugin.
23
- *
24
- * @example
25
- * ```ts
26
- * await UseSense.initialize({
27
- * apiKey: 'your_api_key',
28
- * environment: 'sandbox',
29
- * });
30
- * ```
46
+ * Request to start a verification session.
31
47
  */
32
48
 
33
49
  /**
34
- * Result returned when a verification session completes.
50
+ * Redacted decision object returned when a session completes.
35
51
  *
36
- * **Important:** This result is for UI feedback only.
37
- * The definitive verdict arrives at your backend via HMAC-signed webhook.
52
+ * This is the ONLY shape the plugin exposes to React Native. Pillar
53
+ * scores (channel trust, liveness, matchsense risk) are intentionally
54
+ * not included — the native SDKs strip those fields before returning
55
+ * across the bridge to prevent reverse-engineering of the server-side
56
+ * scoring logic. If you need full scoring details, consume the signed
57
+ * webhook delivered to your backend.
38
58
  */
39
59
 
40
60
  /**
41
- * Error returned when a verification session fails.
61
+ * Error thrown when a verification session fails.
62
+ *
63
+ * Matches the native SDKs' error shape: machine-readable code,
64
+ * human-readable message, retry hint.
42
65
  */
43
66
 
44
67
  /**
45
- * Events emitted during the verification session lifecycle.
68
+ * Lifecycle event types emitted by the native SDK during a
69
+ * verification session.
46
70
  */
47
71
 
48
- /** Options for starting a verification session. */
49
-
50
- /** Status of a verification session. */
72
+ /** Single event emitted during a session. */
51
73
 
52
- /** Subscription handle returned by {@link UseSense.addListener}. */
74
+ /** Handle returned by `UseSense.addListener`. */
53
75
 
54
- // ─── Implementation ──────────────────────────────────────────────────
76
+ // ─── Implementation ──────────────────────────────────────────────────────
55
77
 
56
78
  const eventEmitter = new NativeEventEmitter(UseSenseModule);
57
79
 
58
80
  /**
59
81
  * UseSense React Native plugin.
60
82
  *
61
- * Provides human presence verification by wrapping the native UseSense
62
- * iOS and Android SDKs into a single cross-platform API.
83
+ * Human presence verification wrapping the native iOS and Android
84
+ * UseSense SDKs. Every session runs inside a full-screen native
85
+ * camera activity; the plugin is a thin bridge that forwards
86
+ * initialization, verification requests, and lifecycle events to
87
+ * the platform SDK and returns a redacted decision object.
63
88
  *
64
89
  * @example
65
90
  * ```ts
66
91
  * import { UseSense } from 'react-native-usesense';
67
92
  *
68
- * await UseSense.initialize({ apiKey: 'your_key', environment: 'sandbox' });
69
- * const result = await UseSense.startSession({ sessionType: 'enrollment' });
70
- * console.log(result.decision);
93
+ * await UseSense.initialize({
94
+ * apiKey: 'sk_sandbox_...',
95
+ * environment: 'sandbox',
96
+ * });
97
+ *
98
+ * const unsubscribe = UseSense.addListener((event) => {
99
+ * console.log(event.type, event.data);
100
+ * });
101
+ *
102
+ * try {
103
+ * const result = await UseSense.startVerification({
104
+ * sessionType: 'enrollment',
105
+ * });
106
+ * console.log(result.decision); // 'APPROVE' | 'REJECT' | 'MANUAL_REVIEW'
107
+ * } finally {
108
+ * unsubscribe.remove();
109
+ * }
71
110
  * ```
72
111
  */
73
112
  export class UseSense {
74
113
  /**
75
- * Initialize the UseSense plugin. Must be called once before any other method.
114
+ * Initialize the UseSense plugin. Must be called before any other
115
+ * method. Calling again with a different API key or environment
116
+ * replaces the previous configuration.
76
117
  *
77
- * @param config - Plugin configuration including API key and environment.
78
- * @throws {UseSenseError} If the API key is invalid or configuration is malformed.
118
+ * @throws {UseSenseError} If the API key is empty or initialization
119
+ * fails on the native side.
79
120
  */
80
121
  static async initialize(config) {
81
122
  if (!config.apiKey) {
82
- throw {
123
+ const err = {
83
124
  code: 'invalid_config',
84
- message: 'apiKey is required'
125
+ message: 'apiKey is required',
126
+ isRetryable: false
85
127
  };
128
+ throw err;
86
129
  }
87
130
  return UseSenseModule.initialize({
88
131
  apiKey: config.apiKey,
89
- environment: config.environment ?? 'sandbox',
90
- organizationId: config.organizationId,
91
- sessionType: config.sessionType ?? 'enrollment',
92
- identityId: config.identityId,
93
- challengePolicy: config.challengePolicy ?? 'standard',
94
- enableAudio: config.enableAudio ?? false,
95
- timeout: config.timeout ?? 60000,
96
- metadata: config.metadata
132
+ environment: config.environment ?? 'auto',
133
+ apiEndpoint: config.apiEndpoint,
134
+ branding: config.branding
97
135
  });
98
136
  }
99
137
 
100
138
  /**
101
- * Start a verification session. Presents a full-screen native camera UI.
102
- *
103
- * The returned promise resolves when the session completes and the modal
104
- * dismisses, or rejects if an error occurs.
105
- *
106
- * @param options - Optional overrides for session type and identity ID.
107
- * @returns The verification result (for UI feedback only).
108
- * @throws {UseSenseError} On failure or cancellation.
139
+ * Start a verification session. Presents a full-screen native
140
+ * camera activity. The returned promise resolves when the session
141
+ * completes or rejects with a `UseSenseError` (including the
142
+ * `USER_CANCELLED` / `session_cancelled` cases when the user
143
+ * dismisses the camera screen).
109
144
  */
110
- static async startSession(options) {
111
- return UseSenseModule.startSession(options ?? {});
112
- }
113
-
114
- /**
115
- * Cancel an in-progress verification session.
116
- *
117
- * The camera UI is dismissed and the `startSession` promise rejects
118
- * with a `session_cancelled` error.
119
- */
120
- static async cancelSession() {
121
- return UseSenseModule.cancelSession();
145
+ static async startVerification(request) {
146
+ return UseSenseModule.startVerification({
147
+ sessionType: request.sessionType,
148
+ externalUserId: request.externalUserId,
149
+ identityId: request.identityId,
150
+ metadata: request.metadata
151
+ });
122
152
  }
123
153
 
124
154
  /**
125
- * Get the status of a verification session by ID.
155
+ * Subscribe to real-time lifecycle events emitted by the native
156
+ * SDK during a verification session. Call this **before**
157
+ * `startVerification` so the subscription captures the earliest
158
+ * events (`SESSION_CREATED`, `PERMISSIONS_REQUESTED`).
126
159
  *
127
- * @param sessionId - The session ID to query.
128
- * @returns The current status and optional result.
160
+ * Returns a subscription handle; call `.remove()` to stop
161
+ * receiving events.
129
162
  */
130
- static async getSessionStatus(sessionId) {
131
- return UseSenseModule.getSessionStatus(sessionId);
163
+ static addListener(callback) {
164
+ const subscription = eventEmitter.addListener('UseSenseEvent', raw => {
165
+ callback(raw);
166
+ });
167
+ return {
168
+ remove: () => subscription.remove()
169
+ };
132
170
  }
133
171
 
134
172
  /**
135
- * Subscribe to real-time events during the verification lifecycle.
136
- *
137
- * Call this before `startSession()` to receive all events.
138
- *
139
- * @param callback - Function invoked for each event.
140
- * @returns A subscription handle with a `remove()` method.
141
- *
142
- * @example
143
- * ```ts
144
- * const listener = UseSense.addListener((event) => {
145
- * console.log(event.type);
146
- * });
147
- * // Later:
148
- * listener.remove();
149
- * ```
173
+ * Clear all event listeners and release native resources. Does not
174
+ * need to be called explicitly during normal usage; the plugin
175
+ * cleans up on process teardown. Useful when you want to re-
176
+ * initialize against a different API key or during test teardown.
150
177
  */
151
- static addListener(callback) {
152
- UseSenseModule.subscribeToEvents();
153
- const subscription = eventEmitter.addListener('UseSenseEvent', callback);
154
- return {
155
- remove: () => {
156
- subscription.remove();
157
- UseSenseModule.unsubscribeFromEvents();
158
- }
159
- };
178
+ static async reset() {
179
+ return UseSenseModule.reset();
160
180
  }
161
181
 
162
182
  /**
163
- * Get the native SDK version string.
164
- *
165
- * @returns Version string in semver format (e.g. `"1.0.0"`).
183
+ * Whether the native plugin has an active `UseSense` client. Set
184
+ * to `true` after a successful `initialize` and `false` after
185
+ * `reset`. Useful for feature-flagging UI that should only show
186
+ * when the SDK is ready.
166
187
  */
167
- static getSdkVersion() {
168
- return UseSenseModule.getSdkVersion();
188
+ static async isInitialized() {
189
+ return UseSenseModule.isInitialized();
169
190
  }
170
191
  }
171
192
  export default UseSense;
@@ -1 +1 @@
1
- {"version":3,"names":["NativeModules","NativeEventEmitter","UseSenseModule","Error","eventEmitter","UseSense","initialize","config","apiKey","code","message","environment","organizationId","sessionType","identityId","challengePolicy","enableAudio","timeout","metadata","startSession","options","cancelSession","getSessionStatus","sessionId","addListener","callback","subscribeToEvents","subscription","remove","unsubscribeFromEvents","getSdkVersion"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"AAAA,SAASA,aAAa,EAAEC,kBAAkB,QAAQ,cAAc;AAEhE,MAAM;EAAEC;AAAe,CAAC,GAAGF,aAAa;AAExC,IAAI,CAACE,cAAc,EAAE;EACnB,MAAM,IAAIC,KAAK,CACb,mGAAmG,GACjG,oCAAoC,GACpC,wDACJ,CAAC;AACH;;AAEA;;AAEA;;AAGA;;AAGA;;AAGA;;AAGA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAsBA;AACA;AACA;AACA;AACA;AACA;;AAwBA;AACA;AACA;;AAUA;AACA;AACA;;AASA;;AAQA;;AAQA;;AAMA;;AAEA,MAAMC,YAAY,GAAG,IAAIH,kBAAkB,CAACC,cAAc,CAAC;;AAE3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMG,QAAQ,CAAC;EACpB;AACF;AACA;AACA;AACA;AACA;EACE,aAAaC,UAAUA,CAACC,MAAsB,EAAiB;IAC7D,IAAI,CAACA,MAAM,CAACC,MAAM,EAAE;MAClB,MAAM;QAAEC,IAAI,EAAE,gBAAgB;QAAEC,OAAO,EAAE;MAAqB,CAAC;IACjE;IACA,OAAOR,cAAc,CAACI,UAAU,CAAC;MAC/BE,MAAM,EAAED,MAAM,CAACC,MAAM;MACrBG,WAAW,EAAEJ,MAAM,CAACI,WAAW,IAAI,SAAS;MAC5CC,cAAc,EAAEL,MAAM,CAACK,cAAc;MACrCC,WAAW,EAAEN,MAAM,CAACM,WAAW,IAAI,YAAY;MAC/CC,UAAU,EAAEP,MAAM,CAACO,UAAU;MAC7BC,eAAe,EAAER,MAAM,CAACQ,eAAe,IAAI,UAAU;MACrDC,WAAW,EAAET,MAAM,CAACS,WAAW,IAAI,KAAK;MACxCC,OAAO,EAAEV,MAAM,CAACU,OAAO,IAAI,KAAK;MAChCC,QAAQ,EAAEX,MAAM,CAACW;IACnB,CAAC,CAAC;EACJ;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACE,aAAaC,YAAYA,CAACC,OAA6B,EAA2B;IAChF,OAAOlB,cAAc,CAACiB,YAAY,CAACC,OAAO,IAAI,CAAC,CAAC,CAAC;EACnD;;EAEA;AACF;AACA;AACA;AACA;AACA;EACE,aAAaC,aAAaA,CAAA,EAAkB;IAC1C,OAAOnB,cAAc,CAACmB,aAAa,CAAC,CAAC;EACvC;;EAEA;AACF;AACA;AACA;AACA;AACA;EACE,aAAaC,gBAAgBA,CAACC,SAAiB,EAA0B;IACvE,OAAOrB,cAAc,CAACoB,gBAAgB,CAACC,SAAS,CAAC;EACnD;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACE,OAAOC,WAAWA,CAACC,QAAwC,EAAwB;IACjFvB,cAAc,CAACwB,iBAAiB,CAAC,CAAC;IAClC,MAAMC,YAAY,GAAGvB,YAAY,CAACoB,WAAW,CAAC,eAAe,EAAEC,QAAQ,CAAC;IACxE,OAAO;MACLG,MAAM,EAAEA,CAAA,KAAM;QACZD,YAAY,CAACC,MAAM,CAAC,CAAC;QACrB1B,cAAc,CAAC2B,qBAAqB,CAAC,CAAC;MACxC;IACF,CAAC;EACH;;EAEA;AACF;AACA;AACA;AACA;EACE,OAAOC,aAAaA,CAAA,EAAW;IAC7B,OAAO5B,cAAc,CAAC4B,aAAa,CAAC,CAAC;EACvC;AACF;AAEA,eAAezB,QAAQ","ignoreList":[]}
1
+ {"version":3,"names":["NativeModules","NativeEventEmitter","Platform","LINKING_ERROR","select","ios","android","default","UseSenseModule","Error","eventEmitter","UseSense","initialize","config","apiKey","err","code","message","isRetryable","environment","apiEndpoint","branding","startVerification","request","sessionType","externalUserId","identityId","metadata","addListener","callback","subscription","raw","remove","reset","isInitialized"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"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","ignoreList":[]}