@nexly/react-native 0.17.0 → 1.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.
package/README.md CHANGED
@@ -87,6 +87,10 @@ No scroll/click tracking (those are DOM-only); if you want tap analytics, send c
87
87
 
88
88
  `startEngagement()` is idempotent — calling it again stops the previous subscription first, so Fast Refresh or double-mounts cannot produce duplicate listeners.
89
89
 
90
+ ## Privacy mode (no device storage)
91
+
92
+ Pass `privacyMode` to the provider (or `Nexly.init({ privacyMode: true })`) and Nexly never reads or writes `AsyncStorage` for its visitor / session identifiers. Events go out without client-side IDs; the Nexly collector derives a daily-rotating visit fingerprint server-side instead. Cross-day returning-visitor metrics are not available in this mode.
93
+
90
94
  ## Dashboard setup
91
95
 
92
96
  Enable Mobile apps in your app's Ingest settings in the
@@ -2,6 +2,7 @@ import { type IngestCredentials, type NexlyClient } from '@nexly/core';
2
2
  type EngagementCreds = {
3
3
  collectUrl: string;
4
4
  client?: NexlyClient;
5
+ privacyMode?: boolean;
5
6
  } & IngestCredentials;
6
7
  type StopFn = () => void;
7
8
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"engagement.d.ts","sourceRoot":"","sources":["../src/engagement.ts"],"names":[],"mappings":"AACA,OAAO,EAAuB,KAAK,iBAAiB,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAA;AAQ3F,KAAK,eAAe,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,GAAG,iBAAiB,CAAA;AAqBvF,KAAK,MAAM,GAAG,MAAM,IAAI,CAAA;AAExB;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAyCtE"}
1
+ {"version":3,"file":"engagement.d.ts","sourceRoot":"","sources":["../src/engagement.ts"],"names":[],"mappings":"AACA,OAAO,EAAuB,KAAK,iBAAiB,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAA;AAQ3F,KAAK,eAAe,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,iBAAiB,CAAA;AAsB9G,KAAK,MAAM,GAAG,MAAM,IAAI,CAAA;AAExB;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAyCtE"}
@@ -9,6 +9,7 @@ function send(creds, eventName, eventType, data, sessionContext) {
9
9
  const payload = buildCollectPayload({
10
10
  credentials: { appId: creds.appId, apiToken: creds.apiToken },
11
11
  client: creds.client,
12
+ privacyMode: creds.privacyMode,
12
13
  eventName,
13
14
  eventType,
14
15
  context: collectEventMeta(),
@@ -48,7 +49,7 @@ export function startEngagementTracking(creds) {
48
49
  send(creds, 'session_ping', 'lifecycle', { active_seconds: activeSeconds });
49
50
  }
50
51
  }
51
- if (next === 'active') {
52
+ if (next === 'active' && !creds.privacyMode) {
52
53
  void touchSession();
53
54
  }
54
55
  });
@@ -13,13 +13,20 @@ export type NexlyProviderProps = {
13
13
  * Update it later with `client.setScreen(name)` or `client.screenview(name)`.
14
14
  */
15
15
  initialScreen?: string;
16
+ /**
17
+ * Privacy mode: never read or write `AsyncStorage` for visitor / session
18
+ * identifiers. The collector derives a daily-rotating visit fingerprint
19
+ * server-side instead.
20
+ * @default false
21
+ */
22
+ privacyMode?: boolean;
16
23
  children: ReactNode;
17
24
  };
18
25
  /**
19
26
  * Initializes the Nexly client asynchronously (AsyncStorage prewarm) and exposes it
20
27
  * via context. `useNexlyClient()` returns `null` until init completes or if credentials are missing.
21
28
  */
22
- export declare function NexlyProvider({ collectUrl, appId, ingestKey, autoEngagement, initialScreen, children, }: NexlyProviderProps): import("react/jsx-runtime").JSX.Element;
29
+ export declare function NexlyProvider({ collectUrl, appId, ingestKey, autoEngagement, initialScreen, privacyMode, children, }: NexlyProviderProps): import("react/jsx-runtime").JSX.Element;
23
30
  /** Returns the configured {@link Nexly} client, or `null` if not yet ready / credentials missing. */
24
31
  export declare function useNexlyClient(): Nexly | null;
25
32
  //# sourceMappingURL=nexly-provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"nexly-provider.d.ts","sourceRoot":"","sources":["../src/nexly-provider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAkD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AACtF,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAIlC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,8FAA8F;IAC9F,SAAS,EAAE,MAAM,CAAA;IACjB,4FAA4F;IAC5F,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,EAAE,SAAS,CAAA;CACpB,CAAA;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAC5B,UAAU,EACV,KAAK,EACL,SAAS,EACT,cAAsB,EACtB,aAAa,EACb,QAAQ,GACT,EAAE,kBAAkB,2CA6BpB;AAED,qGAAqG;AACrG,wBAAgB,cAAc,IAAI,KAAK,GAAG,IAAI,CAE7C"}
1
+ {"version":3,"file":"nexly-provider.d.ts","sourceRoot":"","sources":["../src/nexly-provider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAkD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AACtF,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAIlC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,8FAA8F;IAC9F,SAAS,EAAE,MAAM,CAAA;IACjB,4FAA4F;IAC5F,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,QAAQ,EAAE,SAAS,CAAA;CACpB,CAAA;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAC5B,UAAU,EACV,KAAK,EACL,SAAS,EACT,cAAsB,EACtB,aAAa,EACb,WAAmB,EACnB,QAAQ,GACT,EAAE,kBAAkB,2CA6BpB;AAED,qGAAqG;AACrG,wBAAgB,cAAc,IAAI,KAAK,GAAG,IAAI,CAE7C"}
@@ -6,7 +6,7 @@ const NexlyClientContext = createContext(null);
6
6
  * Initializes the Nexly client asynchronously (AsyncStorage prewarm) and exposes it
7
7
  * via context. `useNexlyClient()` returns `null` until init completes or if credentials are missing.
8
8
  */
9
- export function NexlyProvider({ collectUrl, appId, ingestKey, autoEngagement = false, initialScreen, children, }) {
9
+ export function NexlyProvider({ collectUrl, appId, ingestKey, autoEngagement = false, initialScreen, privacyMode = false, children, }) {
10
10
  const [client, setClient] = useState(null);
11
11
  useEffect(() => {
12
12
  const id = (appId ?? '').trim();
@@ -20,7 +20,7 @@ export function NexlyProvider({ collectUrl, appId, ingestKey, autoEngagement = f
20
20
  return;
21
21
  }
22
22
  let cancelled = false;
23
- Nexly.init({ collectUrl, appId: id, key: k }).then((instance) => {
23
+ Nexly.init({ collectUrl, appId: id, key: k, privacyMode }).then((instance) => {
24
24
  if (cancelled)
25
25
  return;
26
26
  if (initialScreen)
@@ -30,7 +30,7 @@ export function NexlyProvider({ collectUrl, appId, ingestKey, autoEngagement = f
30
30
  return () => {
31
31
  cancelled = true;
32
32
  };
33
- }, [collectUrl, appId, ingestKey, initialScreen]);
33
+ }, [collectUrl, appId, ingestKey, initialScreen, privacyMode]);
34
34
  useEffect(() => {
35
35
  if (!autoEngagement || !client)
36
36
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"nexly.d.ts","sourceRoot":"","sources":["../src/nexly.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAe,KAAK,SAAS,EAAE,MAAM,aAAa,CAAA;AAmBpE;;;;;;GAMG;AACH,qBAAa,KAAM,SAAQ,SAAS;IAClC,OAAO,CAAC,aAAa,CAAM;IAC3B,OAAO,CAAC,cAAc,CAA4B;IAElD;;;OAGG;WACU,IAAI,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC;IASrD,+DAA+D;IAC/D,MAAM,CAAC,WAAW,IAAI,KAAK,GAAG,IAAI;gBAItB,IAAI,EAAE,SAAS;IAI3B,yEAAyE;IACzE,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK7B,+DAA+D;IAC/D,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;cAKd,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO;cAIpD,mBAAmB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;cAI9C,qBAAqB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAI1D,cAAc,IAAI,MAAM;IAIjC;;;OAGG;IACH,eAAe,IAAI,MAAM,IAAI;CAe9B"}
1
+ {"version":3,"file":"nexly.d.ts","sourceRoot":"","sources":["../src/nexly.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAe,KAAK,SAAS,EAAE,MAAM,aAAa,CAAA;AAmBpE;;;;;;GAMG;AACH,qBAAa,KAAM,SAAQ,SAAS;IAClC,OAAO,CAAC,aAAa,CAAM;IAC3B,OAAO,CAAC,cAAc,CAA4B;IAElD;;;OAGG;WACU,IAAI,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC;IAYrD,+DAA+D;IAC/D,MAAM,CAAC,WAAW,IAAI,KAAK,GAAG,IAAI;gBAItB,IAAI,EAAE,SAAS;IAI3B,yEAAyE;IACzE,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK7B,+DAA+D;IAC/D,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;cAKd,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO;cAIpD,mBAAmB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;cAI9C,qBAAqB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAI1D,cAAc,IAAI,MAAM;IAIjC;;;OAGG;IACH,eAAe,IAAI,MAAM,IAAI;CAgB9B"}
package/dist/nexly.js CHANGED
@@ -32,7 +32,10 @@ export class Nexly extends NexlyBase {
32
32
  static async init(options) {
33
33
  const instance = new Nexly({ ...options, client: options.client ?? defaultClient() });
34
34
  Nexly.setInstance(instance);
35
- if (instance.appId && instance.key) {
35
+ // Privacy mode skips ID prewarming entirely: AsyncStorage is never read
36
+ // or written, events go out without IDs and the collector derives a
37
+ // daily visit fingerprint server-side (privacy_mode is on the wire).
38
+ if (instance.appId && instance.key && !instance.privacyMode) {
36
39
  await prewarmIds();
37
40
  }
38
41
  return instance;
@@ -79,6 +82,7 @@ export class Nexly extends NexlyBase {
79
82
  appId: this.appId,
80
83
  apiToken: this.key,
81
84
  client: this.client,
85
+ privacyMode: this.privacyMode,
82
86
  });
83
87
  this.engagementStop = stop;
84
88
  return () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexly/react-native",
3
- "version": "0.17.0",
3
+ "version": "1.0.0",
4
4
  "description": "React Native bindings for Nexly: fetch transport, AsyncStorage IDs, AppState engagement on top of @nexly/core",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -43,7 +43,7 @@
43
43
  "react-native": ">=0.72.0"
44
44
  },
45
45
  "dependencies": {
46
- "@nexly/core": "0.17.0"
46
+ "@nexly/core": "1.0.0"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@react-native-async-storage/async-storage": "^2.1.2",