@teardown/react-native 2.0.2 → 2.0.9

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
@@ -2,49 +2,90 @@
2
2
 
3
3
  Comprehensive SDK for managing device identity, force updates, logging, and analytics in React Native and Expo applications.
4
4
 
5
+ **[Documentation](https://teardown.dev/docs)** | **[Dashboard](https://dash.teardown.dev)**
6
+
5
7
  ## Features
6
8
 
7
- - 🔐 **Device & User Identity** - Unique device fingerprinting and user session management
8
- - 🔄 **Force Updates** - Automatic version checking with optional or required update flows
9
- - 📱 **Device Information** - Comprehensive device, OS, and app information collection
10
- - 💾 **Storage** - Namespaced persistent storage with platform adapters
11
- - 📝 **Logging** - Structured logging system with debug modes
12
- - **Performance** - Optimized with caching, throttling, and efficient state management
13
- - 🎯 **Type Safety** - Full TypeScript support with runtime validation
9
+ - **Device & User Identity** - Unique device fingerprinting and user session management
10
+ - **Force Updates** - Automatic version checking with optional or required update flows
11
+ - **Device Information** - Comprehensive device, OS, and app information collection
12
+ - **Storage** - Namespaced persistent storage with platform adapters
13
+ - **Logging** - Structured logging system with debug modes
14
+ - **Performance** - Optimized with caching, throttling, and efficient state management
15
+ - **Type Safety** - Full TypeScript support with runtime validation
14
16
 
15
17
  ## Installation
16
18
 
17
19
  ```bash
20
+ npm install @teardown/react-native
21
+ # or
22
+ yarn add @teardown/react-native
23
+ # or
18
24
  bun add @teardown/react-native
19
25
  ```
20
26
 
21
27
  ### Peer Dependencies
22
28
 
29
+ Choose adapters based on your project setup:
30
+
31
+ **Expo projects:**
32
+ ```bash
33
+ npx expo install expo-device expo-application
34
+ ```
35
+
36
+ **Bare React Native projects:**
23
37
  ```bash
24
- bun add react react-native zod
25
- bun add expo-application expo-device expo-updates
26
- bun add react-native-device-info
38
+ npm install react-native-device-info
27
39
  ```
28
40
 
41
+ **Storage (choose one):**
42
+ ```bash
43
+ # MMKV (recommended - faster)
44
+ npm install react-native-mmkv
45
+
46
+ # or AsyncStorage
47
+ npm install @react-native-async-storage/async-storage
48
+ ```
49
+
50
+ ## Getting Your Credentials
51
+
52
+ 1. Sign up or log in at [dash.teardown.dev](https://dash.teardown.dev)
53
+ 2. Create or select a project
54
+ 3. Copy your `org_id`, `project_id`, and `api_key` from project settings
55
+
29
56
  ## Quick Start
30
57
 
31
58
  ### 1. Initialize the SDK
32
59
 
60
+ Create a file (e.g., `lib/teardown.ts`):
61
+
62
+ **Expo Setup:**
33
63
  ```tsx
34
64
  import { TeardownCore } from '@teardown/react-native';
35
- import { ExpoDeviceAdapter } from '@teardown/react-native/expo';
36
- import { createMMKVStorageFactory } from '@teardown/react-native/mmkv';
65
+ import { ExpoDeviceAdapter } from '@teardown/react-native/adapters/expo';
66
+ import { MMKVStorageAdapter } from '@teardown/react-native/adapters/mmkv';
37
67
 
38
68
  export const teardown = new TeardownCore({
39
69
  org_id: 'your-org-id',
40
70
  project_id: 'your-project-id',
41
71
  api_key: 'your-api-key',
42
- storageFactory: createMMKVStorageFactory(),
72
+ storageAdapter: new MMKVStorageAdapter(),
43
73
  deviceAdapter: new ExpoDeviceAdapter(),
44
- forceUpdate: {
45
- throttleMs: 30_000, // 30 seconds
46
- checkCooldownMs: 10_000, // 10 seconds
47
- },
74
+ });
75
+ ```
76
+
77
+ **Bare React Native Setup:**
78
+ ```tsx
79
+ import { TeardownCore } from '@teardown/react-native';
80
+ import { DeviceInfoAdapter } from '@teardown/react-native/adapters/device-info';
81
+ import { AsyncStorageAdapter } from '@teardown/react-native/adapters/async-storage';
82
+
83
+ export const teardown = new TeardownCore({
84
+ org_id: 'your-org-id',
85
+ project_id: 'your-project-id',
86
+ api_key: 'your-api-key',
87
+ storageAdapter: new AsyncStorageAdapter(),
88
+ deviceAdapter: new DeviceInfoAdapter(),
48
89
  });
49
90
  ```
50
91
 
@@ -54,7 +95,7 @@ export const teardown = new TeardownCore({
54
95
  import { TeardownProvider } from '@teardown/react-native';
55
96
  import { teardown } from './lib/teardown';
56
97
 
57
- export default function RootLayout() {
98
+ export default function App() {
58
99
  return (
59
100
  <TeardownProvider core={teardown}>
60
101
  <YourApp />
@@ -66,36 +107,65 @@ export default function RootLayout() {
66
107
  ### 3. Use in components
67
108
 
68
109
  ```tsx
69
- import { useTeardown } from '@teardown/react-native';
110
+ import { useTeardown, useForceUpdate, useSession } from '@teardown/react-native';
70
111
 
71
112
  function YourComponent() {
72
113
  const { core } = useTeardown();
73
-
114
+ const session = useSession();
115
+ const { status, isUpdateRequired } = useForceUpdate();
116
+
74
117
  const handleLogin = async () => {
75
118
  await core.identity.identify({
76
119
  user_id: 'user-123',
77
120
  email: 'user@example.com',
78
121
  });
79
122
  };
80
-
81
- return <Button onPress={handleLogin} />;
123
+
124
+ return <Button onPress={handleLogin} title="Login" />;
82
125
  }
83
126
  ```
84
127
 
128
+ ## Configuration Options
129
+
130
+ ```tsx
131
+ new TeardownCore({
132
+ org_id: string, // Your organization ID
133
+ project_id: string, // Your project ID
134
+ api_key: string, // Your API key
135
+ storageAdapter: adapter, // Storage implementation
136
+ deviceAdapter: adapter, // Device info source
137
+ forceUpdate: {
138
+ throttleMs: 30_000, // Min time between checks (default: 30s)
139
+ checkCooldownMs: 10_000 // Cooldown after check (default: 10s)
140
+ },
141
+ });
142
+ ```
143
+
144
+ ## Available Adapters
145
+
146
+ | Adapter | Import Path | Use Case |
147
+ |---------|-------------|----------|
148
+ | `ExpoDeviceAdapter` | `@teardown/react-native/adapters/expo` | Expo projects |
149
+ | `DeviceInfoAdapter` | `@teardown/react-native/adapters/device-info` | Bare RN projects |
150
+ | `MMKVStorageAdapter` | `@teardown/react-native/adapters/mmkv` | Fast sync storage |
151
+ | `AsyncStorageAdapter` | `@teardown/react-native/adapters/async-storage` | Standard async storage |
152
+
85
153
  ## Documentation
86
154
 
87
- Complete documentation is available in the [docs](./docs) folder:
88
-
89
- - [Getting Started](./docs/01-getting-started.mdx) - Installation and setup
90
- - [Core Concepts](./docs/02-core-concepts.mdx) - Architecture overview
91
- - [Identity & Authentication](./docs/03-identity.mdx) - User session management
92
- - [Force Updates](./docs/04-force-updates.mdx) - Version management
93
- - [Device Information](./docs/05-device-info.mdx) - Device data collection
94
- - [Storage](./docs/06-storage.mdx) - Persistent storage
95
- - [Logging](./docs/07-logging.mdx) - Structured logging
96
- - [API Reference](./docs/08-api-reference.mdx) - Complete API docs
97
- - [Hooks Reference](./docs/09-hooks-reference.mdx) - React hooks
98
- - [Advanced Usage](./docs/10-advanced.mdx) - Advanced patterns
155
+ For detailed guides, visit **[teardown.dev/docs](https://teardown.dev/docs)**
156
+
157
+ Local documentation is also available in the [docs](./docs) folder:
158
+
159
+ - [Getting Started](./docs/01-getting-started.mdx)
160
+ - [Core Concepts](./docs/02-core-concepts.mdx)
161
+ - [Identity & Authentication](./docs/03-identity.mdx)
162
+ - [Force Updates](./docs/04-force-updates.mdx)
163
+ - [Device Information](./docs/05-device-info.mdx)
164
+ - [Storage](./docs/06-storage.mdx)
165
+ - [Logging](./docs/07-logging.mdx)
166
+ - [API Reference](./docs/08-api-reference.mdx)
167
+ - [Hooks Reference](./docs/09-hooks-reference.mdx)
168
+ - [Advanced Usage](./docs/10-advanced.mdx)
99
169
 
100
170
  ## License
101
171
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teardown/react-native",
3
- "version": "2.0.2",
3
+ "version": "2.0.9",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -32,6 +32,11 @@
32
32
  "types": "./src/exports/adapters/async-storage.ts",
33
33
  "import": "./src/exports/adapters/async-storage.ts",
34
34
  "default": "./src/exports/adapters/async-storage.ts"
35
+ },
36
+ "./adapters/device-info": {
37
+ "types": "./src/exports/adapters/device-info.ts",
38
+ "import": "./src/exports/adapters/device-info.ts",
39
+ "default": "./src/exports/adapters/device-info.ts"
35
40
  }
36
41
  },
37
42
  "scripts": {
@@ -62,20 +67,24 @@
62
67
  "expo-updates": "^29.0.12"
63
68
  },
64
69
  "peerDependencies": {
65
- "@react-native-async-storage/async-storage": "^1.21.0 || ^2.0.0",
66
- "react": "*",
67
- "react-native": "*",
68
- "typescript": "*",
70
+ "@react-native-async-storage/async-storage": "^1.21 || ^2.0",
69
71
  "expo-application": "*",
70
72
  "expo-device": "*",
71
73
  "expo-notifications": "*",
72
74
  "expo-secure-store": "*",
73
- "react-native-mmkv": "*"
75
+ "react": "*",
76
+ "react-native": "*",
77
+ "react-native-device-info": "^15",
78
+ "react-native-mmkv": "^4.0.0",
79
+ "typescript": "*"
74
80
  },
75
81
  "peerDependenciesMeta": {
76
82
  "@react-native-async-storage/async-storage": {
77
83
  "optional": true
78
84
  },
85
+ "react-native-device-info": {
86
+ "optional": true
87
+ },
79
88
  "react-native-mmkv": {
80
89
  "optional": true
81
90
  },
@@ -8,8 +8,8 @@ import * as Application from "expo-application";
8
8
  import * as Device from "expo-device";
9
9
  import { Platform } from "react-native";
10
10
 
11
- import { DeviceInfoAdapter } from "./device.adpater-interface";
12
11
  import { DevicePlatformEnum, NotificationPlatformEnum } from "../device.client";
12
+ import { DeviceInfoAdapter } from "./device.adpater-interface";
13
13
 
14
14
  /**
15
15
  * Maps expo-device DeviceType to a string representation
@@ -0,0 +1,36 @@
1
+ import type {
2
+ ApplicationInfo,
3
+ HardwareInfo,
4
+ OSInfo
5
+ } from "@teardown/schemas";
6
+ import { Platform } from "react-native";
7
+ import DeviceInfo from "react-native-device-info";
8
+ import { DeviceInfoAdapter as BaseInfoAdapterInterface } from "./device.adpater-interface";
9
+
10
+ export class DeviceInfoAdapter extends BaseInfoAdapterInterface {
11
+ get applicationInfo(): ApplicationInfo {
12
+ return {
13
+ version: DeviceInfo.getVersion() ?? "0.0.0",
14
+ build_number: Number.parseInt(
15
+ DeviceInfo.getBuildNumber() ?? "0",
16
+ 10
17
+ ),
18
+ };
19
+ }
20
+
21
+ get hardwareInfo(): HardwareInfo {
22
+ return {
23
+ device_name: DeviceInfo.getDeviceNameSync() ?? "Unknown Device",
24
+ device_brand: DeviceInfo.getBrand() ?? "Unknown Brand",
25
+ device_type: DeviceInfo.getDeviceType?.() ?? "unknown",
26
+ };
27
+ }
28
+
29
+ get osInfo(): OSInfo {
30
+ return {
31
+ platform: this.mapPlatform(Platform.OS),
32
+ name: DeviceInfo.getSystemName() ?? Platform.OS,
33
+ version: DeviceInfo.getSystemVersion() ?? "0.0.0",
34
+ };
35
+ }
36
+ }
@@ -2,9 +2,10 @@ import type {
2
2
  ApplicationInfo,
3
3
  DeviceInfo,
4
4
  HardwareInfo,
5
- NotificationsInfo,
6
5
  OSInfo
7
6
  } from "@teardown/schemas";
7
+ import type { Platform } from "react-native";
8
+ import { DevicePlatformEnum } from "../device.client";
8
9
 
9
10
  /**
10
11
  * An interface for a device adapter.
@@ -16,32 +17,18 @@ import type {
16
17
  *
17
18
  */
18
19
  export abstract class DeviceInfoAdapter {
19
- // -- Application Information --
20
20
  /**
21
21
  * The information about the application running.
22
22
  */
23
23
  abstract get applicationInfo(): ApplicationInfo;
24
- // -- Updates Information --
25
- /**
26
- * The information about the update running.
27
- */
28
- // abstract get updateInfo(): UpdateInfo | null;
29
- // -- Hardware Information --
30
24
  /**
31
25
  * The information about the hardware of the device.
32
26
  */
33
27
  abstract get hardwareInfo(): HardwareInfo;
34
- // -- OS Information --
35
28
  /**
36
29
  * The information about the operating system of the device.
37
30
  */
38
31
  abstract get osInfo(): OSInfo;
39
-
40
- /**
41
- * The information about the notifications of the device.
42
- */
43
- abstract get notificationsInfo(): NotificationsInfo;
44
-
45
32
  /**
46
33
  * The information about the device.
47
34
  */
@@ -54,4 +41,25 @@ export abstract class DeviceInfoAdapter {
54
41
  update: null,
55
42
  });
56
43
  }
44
+
45
+ /**
46
+ * Maps React Native Platform.OS to DevicePlatformEnum
47
+ */
48
+ mapPlatform(platform: typeof Platform.OS): DevicePlatformEnum {
49
+ switch (platform) {
50
+ case "ios":
51
+ return DevicePlatformEnum.IOS;
52
+ case "android":
53
+ return DevicePlatformEnum.ANDROID;
54
+ case "web":
55
+ return DevicePlatformEnum.WEB;
56
+ case "macos":
57
+ return DevicePlatformEnum.MACOS;
58
+ case "windows":
59
+ return DevicePlatformEnum.WINDOWS;
60
+ default:
61
+ return DevicePlatformEnum.UNKNOWN;
62
+ }
63
+ }
64
+
57
65
  }
@@ -1,15 +1,13 @@
1
1
  import type {
2
2
  ApplicationInfo,
3
3
  HardwareInfo,
4
- NotificationsInfo,
5
- OSInfo,
4
+ OSInfo
6
5
  } from "@teardown/schemas";
7
6
  import * as Application from "expo-application";
8
7
  import * as Device from "expo-device";
9
8
  import { Platform } from "react-native";
10
9
 
11
10
  import { DeviceInfoAdapter } from "./device.adpater-interface";
12
- import { DevicePlatformEnum, NotificationPlatformEnum } from "../device.client";
13
11
 
14
12
  /**
15
13
  * Maps expo-device DeviceType to a string representation
@@ -29,26 +27,6 @@ function mapDeviceType(deviceType: Device.DeviceType | null): string {
29
27
  }
30
28
  }
31
29
 
32
- /**
33
- * Maps React Native Platform.OS to DevicePlatformEnum
34
- */
35
- function mapPlatform(platform: typeof Platform.OS): DevicePlatformEnum {
36
- switch (platform) {
37
- case "ios":
38
- return DevicePlatformEnum.IOS;
39
- case "android":
40
- return DevicePlatformEnum.ANDROID;
41
- case "web":
42
- return DevicePlatformEnum.WEB;
43
- case "macos":
44
- return DevicePlatformEnum.MACOS;
45
- case "windows":
46
- return DevicePlatformEnum.WINDOWS;
47
- default:
48
- return DevicePlatformEnum.UNKNOWN;
49
- }
50
- }
51
-
52
30
  export class ExpoDeviceAdapter extends DeviceInfoAdapter {
53
31
  get applicationInfo(): ApplicationInfo {
54
32
  return {
@@ -70,21 +48,9 @@ export class ExpoDeviceAdapter extends DeviceInfoAdapter {
70
48
 
71
49
  get osInfo(): OSInfo {
72
50
  return {
73
- platform: mapPlatform(Platform.OS),
51
+ platform: this.mapPlatform(Platform.OS),
74
52
  name: Device.osName ?? Platform.OS,
75
53
  version: Device.osVersion ?? "0.0.0",
76
54
  };
77
55
  }
78
-
79
- get notificationsInfo(): NotificationsInfo {
80
- return {
81
- push: {
82
- enabled: false,
83
- granted: false,
84
- token: null,
85
- platform: NotificationPlatformEnum.EXPO,
86
- },
87
- };
88
- }
89
-
90
56
  }
@@ -69,12 +69,31 @@ export type VersionStatusChangeEvents = {
69
69
  };
70
70
 
71
71
  export type ForceUpdateClientOptions = {
72
- /** Min ms between foreground checks (default: 30000) */
72
+ /**
73
+ * Minimum time (ms) between foreground transitions to prevent rapid-fire checks.
74
+ * Measured from the last time the app came to foreground.
75
+ * Prevents checking when user quickly switches apps back and forth.
76
+ * Default: 30000 (30 seconds)
77
+ *
78
+ * Special values:
79
+ * - -1: Disable throttling, check on every foreground (respects checkCooldownMs)
80
+ *
81
+ * Example: If throttleMs is 30s and user backgrounds then foregrounds the app
82
+ * twice within 20s, only the first transition triggers a check.
83
+ */
73
84
  throttleMs?: number;
74
85
  /**
75
- * Min ms since last successful check before re-checking (default: 300000 = 5min)
76
- * Set this to 0 to disable cooldown and check immediately on every foreground transition.
77
- * Set to -1 disable checking entirely.
86
+ * Minimum time (ms) since the last successful version check before checking again.
87
+ * Measured from when the last check completed successfully (not when it started).
88
+ * Prevents unnecessary API calls after we already have fresh version data.
89
+ * Default: 300000 (5 minutes)
90
+ *
91
+ * Special values:
92
+ * - 0: Disable cooldown, check on every foreground (respects throttleMs)
93
+ * - -1: Disable all automatic version checking
94
+ *
95
+ * Example: If checkCooldownMs is 5min and a check completes at 12:00pm,
96
+ * no new checks occur until 12:05pm, even if user foregrounds the app multiple times.
78
97
  */
79
98
  checkCooldownMs?: number;
80
99
  };
@@ -84,7 +103,7 @@ const DEFAULT_OPTIONS: Required<ForceUpdateClientOptions> = {
84
103
  checkCooldownMs: 300_000, // 5 minutes
85
104
  };
86
105
 
87
- export const VERSION_STATUS_STORAGE_KEY = "VERSION_STATUS";
106
+ export const VERSION_STATUS_STORAGE_KEY = "version_status";
88
107
 
89
108
  export class ForceUpdateClient {
90
109
  private emitter = new EventEmitter<VersionStatusChangeEvents>();
@@ -220,7 +239,12 @@ export class ForceUpdateClient {
220
239
  }
221
240
 
222
241
  const now = Date.now();
223
- const throttleOk = !this.lastForegroundTime || now - this.lastForegroundTime >= this.options.throttleMs;
242
+
243
+ // If throttleMs is -1, disable throttling (always pass)
244
+ // Otherwise, check if enough time has passed since last foreground
245
+ const throttleOk = this.options.throttleMs === -1
246
+ || !this.lastForegroundTime
247
+ || now - this.lastForegroundTime >= this.options.throttleMs;
224
248
 
225
249
  // If checkCooldownMs is 0, always allow check (no cooldown)
226
250
  // Otherwise, check if enough time has passed since last successful check
@@ -27,7 +27,7 @@ function createMockLoggingClient() {
27
27
  debug: (message: string, ...args: unknown[]) => logs.push({ level: "debug", message, args }),
28
28
  }),
29
29
  getLogs: () => logs,
30
- clearLogs: () => logs.length = 0,
30
+ clearLogs: () => { logs.length = 0; },
31
31
  };
32
32
  }
33
33
 
@@ -605,7 +605,7 @@ describe("IdentityClient", () => {
605
605
 
606
606
  // Should have debug log about state already being 'identifying' (first setIdentifyState call)
607
607
  // Then transitions to identified
608
- const debugLogs = mockLogging.getLogs().filter(l => l.level === "debug");
608
+ const debugLogs = mockLogging.getLogs().filter((l) => l.level === "debug");
609
609
  // The "identifying" to "identifying" won't happen since we start from "identified"
610
610
  // But we can check that state changes are logged properly
611
611
  expect(mockLogging.getLogs().some(l => l.level === "info")).toBe(true);
@@ -0,0 +1 @@
1
+ export * from "../../clients/device/adapters/device-info.adapter";
@@ -1,147 +0,0 @@
1
- # Getting Started
2
-
3
- This guide will walk you through installing and setting up the Teardown SDK in your React Native or Expo application.
4
-
5
- ## Installation
6
-
7
- Install the core package:
8
-
9
- ```bash
10
- bun add @teardown/react-native
11
- ```
12
-
13
- ### Peer Dependencies
14
-
15
- Install required peer dependencies:
16
-
17
- ```bash
18
- bun add react react-native zod
19
- ```
20
-
21
- ### Platform Adapters
22
-
23
- #### For Expo Projects
24
-
25
- ```bash
26
- bun add expo-application expo-device expo-updates
27
- ```
28
-
29
- #### For React Native CLI Projects
30
-
31
- ```bash
32
- bun add react-native-device-info
33
- ```
34
-
35
- ### Storage Adapter
36
-
37
- Install MMKV for fast, encrypted storage:
38
-
39
- ```bash
40
- bun add react-native-mmkv
41
- ```
42
-
43
- ## Initial Setup
44
-
45
- ### 1. Create SDK Configuration
46
-
47
- Create a file to initialize the Teardown SDK (e.g., `lib/teardown.ts`):
48
-
49
- ```typescript
50
- import { TeardownCore } from '@teardown/react-native';
51
- import { ExpoDeviceAdapter } from '@teardown/react-native/expo';
52
- import { createMMKVStorageFactory } from '@teardown/react-native/mmkv';
53
-
54
- export const teardown = new TeardownCore({
55
- org_id: 'your-org-id',
56
- project_id: 'your-project-id',
57
- api_key: 'your-api-key',
58
- storageFactory: createMMKVStorageFactory(),
59
- deviceAdapter: new ExpoDeviceAdapter(),
60
- forceUpdate: {
61
- throttleMs: 30_000, // Check every 30 seconds when app returns to foreground
62
- checkCooldownMs: 300_000, // Wait 5 minutes between checks
63
- },
64
- });
65
- ```
66
-
67
- ### 2. Wrap Your App with TeardownProvider
68
-
69
- In your root layout file (e.g., `app/_layout.tsx` for Expo Router):
70
-
71
- ```typescript
72
- import { TeardownProvider } from '@teardown/react-native';
73
- import { teardown } from '../lib/teardown';
74
-
75
- export default function RootLayout() {
76
- return (
77
- <TeardownProvider core={teardown}>
78
- <YourApp />
79
- </TeardownProvider>
80
- );
81
- }
82
- ```
83
-
84
- For traditional React Native:
85
-
86
- ```typescript
87
- import { TeardownProvider } from '@teardown/react-native';
88
- import { teardown } from './lib/teardown';
89
-
90
- export default function App() {
91
- return (
92
- <TeardownProvider core={teardown}>
93
- <YourNavigationStack />
94
- </TeardownProvider>
95
- );
96
- }
97
- ```
98
-
99
- ### 3. Use the SDK in Your Components
100
-
101
- ```typescript
102
- import { useTeardown } from '@teardown/react-native';
103
-
104
- function MyComponent() {
105
- const { core } = useTeardown();
106
-
107
- const handleLogin = async () => {
108
- const result = await core.identity.identify({
109
- user_id: 'user-123',
110
- email: 'user@example.com',
111
- name: 'John Doe',
112
- });
113
-
114
- if (result.success) {
115
- console.log('User identified:', result.data);
116
- }
117
- };
118
-
119
- return <Button onPress={handleLogin} title="Login" />;
120
- }
121
- ```
122
-
123
- ## Configuration Options
124
-
125
- ### TeardownCore Options
126
-
127
- | Option | Type | Required | Description |
128
- |--------|------|----------|-------------|
129
- | `org_id` | string | Yes | Your organization ID from Teardown dashboard |
130
- | `project_id` | string | Yes | Your project ID from Teardown dashboard |
131
- | `api_key` | string | Yes | Your API key from Teardown dashboard |
132
- | `storageFactory` | function | Yes | Storage adapter factory (e.g., MMKV) |
133
- | `deviceAdapter` | object | Yes | Device info adapter (Expo or RN) |
134
- | `forceUpdate` | object | No | Force update configuration |
135
-
136
- ### Force Update Options
137
-
138
- | Option | Type | Default | Description |
139
- |--------|------|---------|-------------|
140
- | `throttleMs` | number | 30000 | Minimum time between foreground checks (ms) |
141
- | `checkCooldownMs` | number | 300000 | Minimum time since last successful check (ms) |
142
-
143
- ## Next Steps
144
-
145
- - [Core Concepts](./02-core-concepts.mdx) - Understand the architecture
146
- - [Identity & Authentication](./03-identity.mdx) - Manage user sessions
147
- - [Force Updates](./04-force-updates.mdx) - Handle version management