@sendoracloud/sdk-react-native 1.8.1 → 1.9.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.
- package/dist/index.cjs +52 -27
- package/dist/index.d.cts +36 -18
- package/dist/index.d.ts +36 -18
- package/dist/index.js +52 -27
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -43,6 +43,7 @@ __export(index_exports, {
|
|
|
43
43
|
});
|
|
44
44
|
module.exports = __toCommonJS(index_exports);
|
|
45
45
|
var import_react_native_get_random_values = require("react-native-get-random-values");
|
|
46
|
+
var import_react_native4 = require("react-native");
|
|
46
47
|
|
|
47
48
|
// src/storage.ts
|
|
48
49
|
var PREFIX = "sendora_";
|
|
@@ -222,7 +223,7 @@ async function request(opts, method, path, body, extraHeaders, reqOpts) {
|
|
|
222
223
|
// package.json
|
|
223
224
|
var package_default = {
|
|
224
225
|
name: "@sendoracloud/sdk-react-native",
|
|
225
|
-
version: "1.
|
|
226
|
+
version: "1.9.0",
|
|
226
227
|
description: "Sendora Cloud React Native + Expo SDK \u2014 analytics, identity, push-token registration, auth, deep links (Branch / Firebase Dynamic Links parity). Auth + analytics + deep links work in Expo Go; push token registration requires a Dev Client (EAS Build or `npx expo prebuild`).",
|
|
227
228
|
type: "module",
|
|
228
229
|
main: "./dist/index.cjs",
|
|
@@ -465,38 +466,44 @@ var Auth = class {
|
|
|
465
466
|
}
|
|
466
467
|
}
|
|
467
468
|
/**
|
|
468
|
-
* Returns
|
|
469
|
+
* Returns a VALID (non-expired) access token, or null.
|
|
469
470
|
*
|
|
470
|
-
*
|
|
471
|
-
*
|
|
472
|
-
*
|
|
473
|
-
*
|
|
474
|
-
*
|
|
475
|
-
*
|
|
476
|
-
*
|
|
477
|
-
*
|
|
478
|
-
* NSURLSession cold-launch contention) every caller hung too.
|
|
479
|
-
* 3. Expired + no inflight + refresh available + not in cooldown →
|
|
480
|
-
* fire refresh, await it.
|
|
481
|
-
* 4. Expired + in cooldown → return stale cached. Caller's RPC
|
|
482
|
-
* either succeeds against grace or fails fast on 401, which is
|
|
483
|
-
* a better UX than blocking the whole bridge waiting on a
|
|
484
|
-
* network that we already know is stalled.
|
|
471
|
+
* Hard contract (matches sdk-ios / sdk-android, and the industry
|
|
472
|
+
* token-client pattern — Supabase `_callRefreshToken`, Auth0
|
|
473
|
+
* `getTokenSilently`, Firebase `getIdToken`): this method NEVER
|
|
474
|
+
* returns a token past its `exp`. Callers attach the result as a
|
|
475
|
+
* Bearer to arbitrary resource servers — including third-party
|
|
476
|
+
* backends (PostgREST/Supabase) that have NO knowledge of Sendora's
|
|
477
|
+
* own refresh grace window — so a token must be either fresh or
|
|
478
|
+
* absent. A token expired by hours is useless and yields a 401.
|
|
485
479
|
*
|
|
486
|
-
*
|
|
487
|
-
*
|
|
480
|
+
* Resolution order:
|
|
481
|
+
* 1. Cached token with comfortable life left (>= REFRESH_SAFETY_MS
|
|
482
|
+
* skew before exp) → return it. Fast path, no I/O.
|
|
483
|
+
* 2. No cached token AND no refresh token in storage → genuinely
|
|
484
|
+
* signed out → null.
|
|
485
|
+
* 3. Expired/near-expiry but a refresh chain exists:
|
|
486
|
+
* a. A refresh is already inflight → AWAIT it and return the
|
|
487
|
+
* fresh token. Concurrent callers coalesce onto the single
|
|
488
|
+
* in-flight `/token/refresh` (single-flight) — nobody is
|
|
489
|
+
* handed a stale token. The inflight fetch is
|
|
490
|
+
* AbortController-bounded (http.ts caps `/auth-service/*` at
|
|
491
|
+
* 10s), so awaiting can NEVER hang the JS bridge. That
|
|
492
|
+
* bounded-fetch guarantee — NOT the old stale-token return —
|
|
493
|
+
* is what actually fixed the Wave-62 cold-launch hang.
|
|
494
|
+
* b. A recent refresh failed and we're in backoff cooldown →
|
|
495
|
+
* null. Honest "no usable token right now" rather than a
|
|
496
|
+
* provably-expired one; the AppState foreground hook clears
|
|
497
|
+
* the cooldown for an immediate retry on resume.
|
|
498
|
+
* c. Otherwise → fire the refresh and await it.
|
|
488
499
|
*/
|
|
489
500
|
async getAccessToken() {
|
|
490
|
-
if (
|
|
491
|
-
if (this.accessExpiresAt && Date.now() < this.accessExpiresAt - REFRESH_SAFETY_MS) {
|
|
492
|
-
return this.accessToken;
|
|
493
|
-
}
|
|
494
|
-
if (this.refreshInflight) {
|
|
495
|
-
return this.accessToken;
|
|
496
|
-
}
|
|
497
|
-
if (Date.now() < this.refreshCooldownUntil) {
|
|
501
|
+
if (this.accessToken && this.accessExpiresAt && Date.now() < this.accessExpiresAt - REFRESH_SAFETY_MS) {
|
|
498
502
|
return this.accessToken;
|
|
499
503
|
}
|
|
504
|
+
if (!this.hooks.storage.get(REFRESH_KEY)) return null;
|
|
505
|
+
if (this.refreshInflight) return this.refreshInflight;
|
|
506
|
+
if (Date.now() < this.refreshCooldownUntil) return null;
|
|
500
507
|
return this.refreshAccessToken();
|
|
501
508
|
}
|
|
502
509
|
/** Sync read — returns whatever's cached even if expired. Prefer the async variant. */
|
|
@@ -2029,6 +2036,22 @@ function byteLength(s) {
|
|
|
2029
2036
|
return s.length * 4;
|
|
2030
2037
|
}
|
|
2031
2038
|
}
|
|
2039
|
+
function buildDeviceContext(appVersion) {
|
|
2040
|
+
try {
|
|
2041
|
+
const os = import_react_native4.Platform?.OS;
|
|
2042
|
+
if (os !== "ios" && os !== "android") return void 0;
|
|
2043
|
+
const isPad = os === "ios" && import_react_native4.Platform.isPad === true;
|
|
2044
|
+
return {
|
|
2045
|
+
type: isPad ? "tablet" : "mobile",
|
|
2046
|
+
os: os === "ios" ? "iOS" : "Android",
|
|
2047
|
+
osVersion: String(import_react_native4.Platform.Version ?? ""),
|
|
2048
|
+
model: "",
|
|
2049
|
+
appVersion: appVersion ?? ""
|
|
2050
|
+
};
|
|
2051
|
+
} catch {
|
|
2052
|
+
return void 0;
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2032
2055
|
var SendoraSDK = class {
|
|
2033
2056
|
constructor() {
|
|
2034
2057
|
this.config = null;
|
|
@@ -2831,6 +2854,7 @@ var SendoraSDK = class {
|
|
|
2831
2854
|
async sendEvent(kind, payload) {
|
|
2832
2855
|
if (!this.config) return;
|
|
2833
2856
|
if (!this.consentGranted) return;
|
|
2857
|
+
const device = buildDeviceContext(this.config.appVersion);
|
|
2834
2858
|
await post(
|
|
2835
2859
|
{ apiUrl: this.config.apiUrl, publicKey: this.config.publicKey, debug: this.debug },
|
|
2836
2860
|
"/api/v1/events",
|
|
@@ -2845,6 +2869,7 @@ var SendoraSDK = class {
|
|
|
2845
2869
|
context: {
|
|
2846
2870
|
platform: "react-native",
|
|
2847
2871
|
sdk: { name: "@sendoracloud/sdk-react-native", version: SDK_VERSION },
|
|
2872
|
+
...device ? { device } : {},
|
|
2848
2873
|
...this.config.environment ? { environment: this.config.environment } : {},
|
|
2849
2874
|
...kind === "identify" ? { traits: payload.traits } : {}
|
|
2850
2875
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -210,26 +210,36 @@ declare class Auth {
|
|
|
210
210
|
/** Internal — fan out to subscribers + cache the latest. */
|
|
211
211
|
private fireDeviceTakeover;
|
|
212
212
|
/**
|
|
213
|
-
* Returns
|
|
213
|
+
* Returns a VALID (non-expired) access token, or null.
|
|
214
214
|
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
* NSURLSession cold-launch contention) every caller hung too.
|
|
224
|
-
* 3. Expired + no inflight + refresh available + not in cooldown →
|
|
225
|
-
* fire refresh, await it.
|
|
226
|
-
* 4. Expired + in cooldown → return stale cached. Caller's RPC
|
|
227
|
-
* either succeeds against grace or fails fast on 401, which is
|
|
228
|
-
* a better UX than blocking the whole bridge waiting on a
|
|
229
|
-
* network that we already know is stalled.
|
|
215
|
+
* Hard contract (matches sdk-ios / sdk-android, and the industry
|
|
216
|
+
* token-client pattern — Supabase `_callRefreshToken`, Auth0
|
|
217
|
+
* `getTokenSilently`, Firebase `getIdToken`): this method NEVER
|
|
218
|
+
* returns a token past its `exp`. Callers attach the result as a
|
|
219
|
+
* Bearer to arbitrary resource servers — including third-party
|
|
220
|
+
* backends (PostgREST/Supabase) that have NO knowledge of Sendora's
|
|
221
|
+
* own refresh grace window — so a token must be either fresh or
|
|
222
|
+
* absent. A token expired by hours is useless and yields a 401.
|
|
230
223
|
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
224
|
+
* Resolution order:
|
|
225
|
+
* 1. Cached token with comfortable life left (>= REFRESH_SAFETY_MS
|
|
226
|
+
* skew before exp) → return it. Fast path, no I/O.
|
|
227
|
+
* 2. No cached token AND no refresh token in storage → genuinely
|
|
228
|
+
* signed out → null.
|
|
229
|
+
* 3. Expired/near-expiry but a refresh chain exists:
|
|
230
|
+
* a. A refresh is already inflight → AWAIT it and return the
|
|
231
|
+
* fresh token. Concurrent callers coalesce onto the single
|
|
232
|
+
* in-flight `/token/refresh` (single-flight) — nobody is
|
|
233
|
+
* handed a stale token. The inflight fetch is
|
|
234
|
+
* AbortController-bounded (http.ts caps `/auth-service/*` at
|
|
235
|
+
* 10s), so awaiting can NEVER hang the JS bridge. That
|
|
236
|
+
* bounded-fetch guarantee — NOT the old stale-token return —
|
|
237
|
+
* is what actually fixed the Wave-62 cold-launch hang.
|
|
238
|
+
* b. A recent refresh failed and we're in backoff cooldown →
|
|
239
|
+
* null. Honest "no usable token right now" rather than a
|
|
240
|
+
* provably-expired one; the AppState foreground hook clears
|
|
241
|
+
* the cooldown for an immediate retry on resume.
|
|
242
|
+
* c. Otherwise → fire the refresh and await it.
|
|
233
243
|
*/
|
|
234
244
|
getAccessToken(): Promise<string | null>;
|
|
235
245
|
/** Sync read — returns whatever's cached even if expired. Prefer the async variant. */
|
|
@@ -806,6 +816,14 @@ interface SendoraConfig {
|
|
|
806
816
|
* Added 0.16.0.
|
|
807
817
|
*/
|
|
808
818
|
linkDomain?: string;
|
|
819
|
+
/**
|
|
820
|
+
* Your app's version (e.g. "2.4.0"). Attached to every event's
|
|
821
|
+
* `context.device.appVersion` so the dashboard can break analytics down by
|
|
822
|
+
* release (ADR-022). Optional — RN has no zero-dep way to auto-read the
|
|
823
|
+
* host app version, so supply it (e.g. from `expo-constants` /
|
|
824
|
+
* `react-native-device-info`) if you want app-version analytics.
|
|
825
|
+
*/
|
|
826
|
+
appVersion?: string;
|
|
809
827
|
}
|
|
810
828
|
type TraitValue = string | number | boolean | null | undefined;
|
|
811
829
|
interface IdentifyTraits {
|
package/dist/index.d.ts
CHANGED
|
@@ -210,26 +210,36 @@ declare class Auth {
|
|
|
210
210
|
/** Internal — fan out to subscribers + cache the latest. */
|
|
211
211
|
private fireDeviceTakeover;
|
|
212
212
|
/**
|
|
213
|
-
* Returns
|
|
213
|
+
* Returns a VALID (non-expired) access token, or null.
|
|
214
214
|
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
* NSURLSession cold-launch contention) every caller hung too.
|
|
224
|
-
* 3. Expired + no inflight + refresh available + not in cooldown →
|
|
225
|
-
* fire refresh, await it.
|
|
226
|
-
* 4. Expired + in cooldown → return stale cached. Caller's RPC
|
|
227
|
-
* either succeeds against grace or fails fast on 401, which is
|
|
228
|
-
* a better UX than blocking the whole bridge waiting on a
|
|
229
|
-
* network that we already know is stalled.
|
|
215
|
+
* Hard contract (matches sdk-ios / sdk-android, and the industry
|
|
216
|
+
* token-client pattern — Supabase `_callRefreshToken`, Auth0
|
|
217
|
+
* `getTokenSilently`, Firebase `getIdToken`): this method NEVER
|
|
218
|
+
* returns a token past its `exp`. Callers attach the result as a
|
|
219
|
+
* Bearer to arbitrary resource servers — including third-party
|
|
220
|
+
* backends (PostgREST/Supabase) that have NO knowledge of Sendora's
|
|
221
|
+
* own refresh grace window — so a token must be either fresh or
|
|
222
|
+
* absent. A token expired by hours is useless and yields a 401.
|
|
230
223
|
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
224
|
+
* Resolution order:
|
|
225
|
+
* 1. Cached token with comfortable life left (>= REFRESH_SAFETY_MS
|
|
226
|
+
* skew before exp) → return it. Fast path, no I/O.
|
|
227
|
+
* 2. No cached token AND no refresh token in storage → genuinely
|
|
228
|
+
* signed out → null.
|
|
229
|
+
* 3. Expired/near-expiry but a refresh chain exists:
|
|
230
|
+
* a. A refresh is already inflight → AWAIT it and return the
|
|
231
|
+
* fresh token. Concurrent callers coalesce onto the single
|
|
232
|
+
* in-flight `/token/refresh` (single-flight) — nobody is
|
|
233
|
+
* handed a stale token. The inflight fetch is
|
|
234
|
+
* AbortController-bounded (http.ts caps `/auth-service/*` at
|
|
235
|
+
* 10s), so awaiting can NEVER hang the JS bridge. That
|
|
236
|
+
* bounded-fetch guarantee — NOT the old stale-token return —
|
|
237
|
+
* is what actually fixed the Wave-62 cold-launch hang.
|
|
238
|
+
* b. A recent refresh failed and we're in backoff cooldown →
|
|
239
|
+
* null. Honest "no usable token right now" rather than a
|
|
240
|
+
* provably-expired one; the AppState foreground hook clears
|
|
241
|
+
* the cooldown for an immediate retry on resume.
|
|
242
|
+
* c. Otherwise → fire the refresh and await it.
|
|
233
243
|
*/
|
|
234
244
|
getAccessToken(): Promise<string | null>;
|
|
235
245
|
/** Sync read — returns whatever's cached even if expired. Prefer the async variant. */
|
|
@@ -806,6 +816,14 @@ interface SendoraConfig {
|
|
|
806
816
|
* Added 0.16.0.
|
|
807
817
|
*/
|
|
808
818
|
linkDomain?: string;
|
|
819
|
+
/**
|
|
820
|
+
* Your app's version (e.g. "2.4.0"). Attached to every event's
|
|
821
|
+
* `context.device.appVersion` so the dashboard can break analytics down by
|
|
822
|
+
* release (ADR-022). Optional — RN has no zero-dep way to auto-read the
|
|
823
|
+
* host app version, so supply it (e.g. from `expo-constants` /
|
|
824
|
+
* `react-native-device-info`) if you want app-version analytics.
|
|
825
|
+
*/
|
|
826
|
+
appVersion?: string;
|
|
809
827
|
}
|
|
810
828
|
type TraitValue = string | number | boolean | null | undefined;
|
|
811
829
|
interface IdentifyTraits {
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import "react-native-get-random-values";
|
|
3
|
+
import { Platform } from "react-native";
|
|
3
4
|
|
|
4
5
|
// src/storage.ts
|
|
5
6
|
var PREFIX = "sendora_";
|
|
@@ -179,7 +180,7 @@ async function request(opts, method, path, body, extraHeaders, reqOpts) {
|
|
|
179
180
|
// package.json
|
|
180
181
|
var package_default = {
|
|
181
182
|
name: "@sendoracloud/sdk-react-native",
|
|
182
|
-
version: "1.
|
|
183
|
+
version: "1.9.0",
|
|
183
184
|
description: "Sendora Cloud React Native + Expo SDK \u2014 analytics, identity, push-token registration, auth, deep links (Branch / Firebase Dynamic Links parity). Auth + analytics + deep links work in Expo Go; push token registration requires a Dev Client (EAS Build or `npx expo prebuild`).",
|
|
184
185
|
type: "module",
|
|
185
186
|
main: "./dist/index.cjs",
|
|
@@ -422,38 +423,44 @@ var Auth = class {
|
|
|
422
423
|
}
|
|
423
424
|
}
|
|
424
425
|
/**
|
|
425
|
-
* Returns
|
|
426
|
+
* Returns a VALID (non-expired) access token, or null.
|
|
426
427
|
*
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
*
|
|
431
|
-
*
|
|
432
|
-
*
|
|
433
|
-
*
|
|
434
|
-
*
|
|
435
|
-
* NSURLSession cold-launch contention) every caller hung too.
|
|
436
|
-
* 3. Expired + no inflight + refresh available + not in cooldown →
|
|
437
|
-
* fire refresh, await it.
|
|
438
|
-
* 4. Expired + in cooldown → return stale cached. Caller's RPC
|
|
439
|
-
* either succeeds against grace or fails fast on 401, which is
|
|
440
|
-
* a better UX than blocking the whole bridge waiting on a
|
|
441
|
-
* network that we already know is stalled.
|
|
428
|
+
* Hard contract (matches sdk-ios / sdk-android, and the industry
|
|
429
|
+
* token-client pattern — Supabase `_callRefreshToken`, Auth0
|
|
430
|
+
* `getTokenSilently`, Firebase `getIdToken`): this method NEVER
|
|
431
|
+
* returns a token past its `exp`. Callers attach the result as a
|
|
432
|
+
* Bearer to arbitrary resource servers — including third-party
|
|
433
|
+
* backends (PostgREST/Supabase) that have NO knowledge of Sendora's
|
|
434
|
+
* own refresh grace window — so a token must be either fresh or
|
|
435
|
+
* absent. A token expired by hours is useless and yields a 401.
|
|
442
436
|
*
|
|
443
|
-
*
|
|
444
|
-
*
|
|
437
|
+
* Resolution order:
|
|
438
|
+
* 1. Cached token with comfortable life left (>= REFRESH_SAFETY_MS
|
|
439
|
+
* skew before exp) → return it. Fast path, no I/O.
|
|
440
|
+
* 2. No cached token AND no refresh token in storage → genuinely
|
|
441
|
+
* signed out → null.
|
|
442
|
+
* 3. Expired/near-expiry but a refresh chain exists:
|
|
443
|
+
* a. A refresh is already inflight → AWAIT it and return the
|
|
444
|
+
* fresh token. Concurrent callers coalesce onto the single
|
|
445
|
+
* in-flight `/token/refresh` (single-flight) — nobody is
|
|
446
|
+
* handed a stale token. The inflight fetch is
|
|
447
|
+
* AbortController-bounded (http.ts caps `/auth-service/*` at
|
|
448
|
+
* 10s), so awaiting can NEVER hang the JS bridge. That
|
|
449
|
+
* bounded-fetch guarantee — NOT the old stale-token return —
|
|
450
|
+
* is what actually fixed the Wave-62 cold-launch hang.
|
|
451
|
+
* b. A recent refresh failed and we're in backoff cooldown →
|
|
452
|
+
* null. Honest "no usable token right now" rather than a
|
|
453
|
+
* provably-expired one; the AppState foreground hook clears
|
|
454
|
+
* the cooldown for an immediate retry on resume.
|
|
455
|
+
* c. Otherwise → fire the refresh and await it.
|
|
445
456
|
*/
|
|
446
457
|
async getAccessToken() {
|
|
447
|
-
if (
|
|
448
|
-
if (this.accessExpiresAt && Date.now() < this.accessExpiresAt - REFRESH_SAFETY_MS) {
|
|
449
|
-
return this.accessToken;
|
|
450
|
-
}
|
|
451
|
-
if (this.refreshInflight) {
|
|
452
|
-
return this.accessToken;
|
|
453
|
-
}
|
|
454
|
-
if (Date.now() < this.refreshCooldownUntil) {
|
|
458
|
+
if (this.accessToken && this.accessExpiresAt && Date.now() < this.accessExpiresAt - REFRESH_SAFETY_MS) {
|
|
455
459
|
return this.accessToken;
|
|
456
460
|
}
|
|
461
|
+
if (!this.hooks.storage.get(REFRESH_KEY)) return null;
|
|
462
|
+
if (this.refreshInflight) return this.refreshInflight;
|
|
463
|
+
if (Date.now() < this.refreshCooldownUntil) return null;
|
|
457
464
|
return this.refreshAccessToken();
|
|
458
465
|
}
|
|
459
466
|
/** Sync read — returns whatever's cached even if expired. Prefer the async variant. */
|
|
@@ -1991,6 +1998,22 @@ function byteLength(s) {
|
|
|
1991
1998
|
return s.length * 4;
|
|
1992
1999
|
}
|
|
1993
2000
|
}
|
|
2001
|
+
function buildDeviceContext(appVersion) {
|
|
2002
|
+
try {
|
|
2003
|
+
const os = Platform?.OS;
|
|
2004
|
+
if (os !== "ios" && os !== "android") return void 0;
|
|
2005
|
+
const isPad = os === "ios" && Platform.isPad === true;
|
|
2006
|
+
return {
|
|
2007
|
+
type: isPad ? "tablet" : "mobile",
|
|
2008
|
+
os: os === "ios" ? "iOS" : "Android",
|
|
2009
|
+
osVersion: String(Platform.Version ?? ""),
|
|
2010
|
+
model: "",
|
|
2011
|
+
appVersion: appVersion ?? ""
|
|
2012
|
+
};
|
|
2013
|
+
} catch {
|
|
2014
|
+
return void 0;
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
1994
2017
|
var SendoraSDK = class {
|
|
1995
2018
|
constructor() {
|
|
1996
2019
|
this.config = null;
|
|
@@ -2793,6 +2816,7 @@ var SendoraSDK = class {
|
|
|
2793
2816
|
async sendEvent(kind, payload) {
|
|
2794
2817
|
if (!this.config) return;
|
|
2795
2818
|
if (!this.consentGranted) return;
|
|
2819
|
+
const device = buildDeviceContext(this.config.appVersion);
|
|
2796
2820
|
await post(
|
|
2797
2821
|
{ apiUrl: this.config.apiUrl, publicKey: this.config.publicKey, debug: this.debug },
|
|
2798
2822
|
"/api/v1/events",
|
|
@@ -2807,6 +2831,7 @@ var SendoraSDK = class {
|
|
|
2807
2831
|
context: {
|
|
2808
2832
|
platform: "react-native",
|
|
2809
2833
|
sdk: { name: "@sendoracloud/sdk-react-native", version: SDK_VERSION },
|
|
2834
|
+
...device ? { device } : {},
|
|
2810
2835
|
...this.config.environment ? { environment: this.config.environment } : {},
|
|
2811
2836
|
...kind === "identify" ? { traits: payload.traits } : {}
|
|
2812
2837
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sendoracloud/sdk-react-native",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "Sendora Cloud React Native + Expo SDK — analytics, identity, push-token registration, auth, deep links (Branch / Firebase Dynamic Links parity). Auth + analytics + deep links work in Expo Go; push token registration requires a Dev Client (EAS Build or `npx expo prebuild`).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|