@safercity/sdk-react-native 0.1.0 → 0.1.1

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.
Files changed (2) hide show
  1. package/README.md +87 -9
  2. package/package.json +1 -6
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @safercity/sdk-react-native
2
2
 
3
- React Native adapter for SaferCity SDK with expo-fetch streaming support.
3
+ React Native adapter for SaferCity SDK with expo-fetch streaming support and secure token storage.
4
4
 
5
5
  ## Installation
6
6
 
@@ -19,10 +19,9 @@ bun add @safercity/sdk-react-native @safercity/sdk-react @tanstack/react-query
19
19
  ## Quick Start
20
20
 
21
21
  ```tsx
22
- import { createReactNativeClient, isStreamingSupported } from '@safercity/sdk-react-native';
22
+ import { createReactNativeClient } from '@safercity/sdk-react-native';
23
23
  import { SaferCityProvider } from '@safercity/sdk-react';
24
24
 
25
- // Create client with React Native optimizations
26
25
  const client = createReactNativeClient({
27
26
  baseUrl: 'https://api.safercity.com',
28
27
  token: userToken,
@@ -38,6 +37,76 @@ function App() {
38
37
  }
39
38
  ```
40
39
 
40
+ ## Authentication Modes
41
+
42
+ On mobile, **direct mode** is the most common pattern. Your app authenticates users with an external auth provider and passes the token to SaferCity:
43
+
44
+ ```tsx
45
+ import { SaferCityProvider } from '@safercity/sdk-react';
46
+
47
+ function App() {
48
+ return (
49
+ <SaferCityProvider
50
+ mode="direct"
51
+ baseUrl="https://api.safercity.com"
52
+ tenantId="tenant-123"
53
+ getAccessToken={() => getTokenFromAuthProvider()}
54
+ >
55
+ <Navigation />
56
+ </SaferCityProvider>
57
+ );
58
+ }
59
+ ```
60
+
61
+ **Proxy mode** also works if your mobile app communicates through a backend-for-frontend (BFF). Cookie mode is not typical for mobile apps.
62
+
63
+ ## Secure Token Storage
64
+
65
+ For server-side OAuth flows on mobile (e.g., background token management), the SDK provides secure storage that auto-detects the best available option:
66
+
67
+ ```typescript
68
+ import { createSecureTokenStorage, getStorageType } from '@safercity/sdk-react-native';
69
+ import { TokenManager } from '@safercity/sdk';
70
+
71
+ // Auto-detects: expo-secure-store > AsyncStorage > in-memory
72
+ const storage = createSecureTokenStorage();
73
+
74
+ const tokenManager = new TokenManager({
75
+ credentials: {
76
+ clientId: 'your-client-id',
77
+ clientSecret: 'your-client-secret',
78
+ },
79
+ storage,
80
+ });
81
+
82
+ // Get token (auto-refreshes if expired)
83
+ const token = await tokenManager.getToken();
84
+
85
+ // Check what storage is being used
86
+ const type = getStorageType(); // 'secure-store' | 'async-storage' | 'memory'
87
+ ```
88
+
89
+ ### Storage Priority
90
+
91
+ | Storage | Package | Security | Persistence |
92
+ |---------|---------|----------|-------------|
93
+ | `SecureStoreTokenStorage` | `expo-secure-store` | Encrypted (device keychain/keystore) | Yes |
94
+ | `AsyncStorageTokenStorage` | `@react-native-async-storage/async-storage` | Unencrypted | Yes |
95
+ | `InMemoryTokenStorage` | Built-in | N/A | No |
96
+
97
+ You can also use a specific storage class directly:
98
+
99
+ ```typescript
100
+ import {
101
+ SecureStoreTokenStorage,
102
+ AsyncStorageTokenStorage,
103
+ InMemoryTokenStorage,
104
+ } from '@safercity/sdk-react-native';
105
+
106
+ const storage = new SecureStoreTokenStorage();
107
+ await storage.waitForInit(); // wait for initial load from device storage
108
+ ```
109
+
41
110
  ## Streaming Support
42
111
 
43
112
  This package automatically uses `expo-fetch` for streaming when available (Expo SDK 52+).
@@ -45,7 +114,6 @@ This package automatically uses `expo-fetch` for streaming when available (Expo
45
114
  ```tsx
46
115
  import { isStreamingSupported } from '@safercity/sdk-react-native';
47
116
 
48
- // Check if streaming is supported
49
117
  if (isStreamingSupported()) {
50
118
  console.log('SSE streaming is available');
51
119
  } else {
@@ -57,6 +125,7 @@ if (isStreamingSupported()) {
57
125
 
58
126
  ```tsx
59
127
  import { usePanicStream } from '@safercity/sdk-react';
128
+ import { isStreamingSupported } from '@safercity/sdk-react-native';
60
129
 
61
130
  function PanicTracker({ panicId }: { panicId: string }) {
62
131
  const { data, isConnected, error } = usePanicStream(panicId, {
@@ -66,7 +135,6 @@ function PanicTracker({ panicId }: { panicId: string }) {
66
135
  });
67
136
 
68
137
  if (!isStreamingSupported()) {
69
- // Fallback to polling
70
138
  return <PollingPanicTracker panicId={panicId} />;
71
139
  }
72
140
 
@@ -81,13 +149,11 @@ function PanicTracker({ panicId }: { panicId: string }) {
81
149
 
82
150
  ## Without Expo
83
151
 
84
- For bare React Native projects without Expo, streaming will fall back to standard fetch.
85
- SSE may have limited support depending on your React Native version.
152
+ For bare React Native projects without Expo, streaming will fall back to standard fetch. SSE may have limited support depending on your React Native version.
86
153
 
87
154
  ```tsx
88
155
  import { createReactNativeClient } from '@safercity/sdk-react-native';
89
156
 
90
- // You can provide a custom fetch implementation
91
157
  const client = createReactNativeClient({
92
158
  baseUrl: 'https://api.safercity.com',
93
159
  token: userToken,
@@ -141,7 +207,19 @@ Returns `true` if expo-fetch is available and streaming is supported.
141
207
 
142
208
  ### getReactNativeFetch(customFetch?)
143
209
 
144
- Returns the best available fetch implementation for the current environment.
210
+ Returns the best available fetch implementation for the current environment. Priority: expo-fetch > custom > global fetch.
211
+
212
+ ### createReactNativeStreamAdapter(customFetch?)
213
+
214
+ Creates a `FetchStreamAdapter` using the best available fetch for the environment.
215
+
216
+ ### createSecureTokenStorage()
217
+
218
+ Auto-detects and returns the best available token storage. Priority: expo-secure-store > AsyncStorage > in-memory.
219
+
220
+ ### getStorageType()
221
+
222
+ Returns `'secure-store'` | `'async-storage'` | `'memory'` indicating what storage is available.
145
223
 
146
224
  ## Troubleshooting
147
225
 
package/package.json CHANGED
@@ -1,16 +1,11 @@
1
1
  {
2
2
  "name": "@safercity/sdk-react-native",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "React Native adapter for SaferCity SDK with expo-fetch streaming support",
5
5
  "license": "MIT",
6
6
  "author": {
7
7
  "name": "SaferCity"
8
8
  },
9
- "repository": {
10
- "type": "git",
11
- "url": "https://github.com/safercity/safercity-v2.git",
12
- "directory": "packages/sdk/react-native"
13
- },
14
9
  "keywords": ["safercity", "sdk", "react-native", "expo", "streaming"],
15
10
  "sideEffects": false,
16
11
  "type": "module",