jazz-react-native 0.8.7 → 0.8.11
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +15 -0
- package/README.md +229 -6
- package/dist/auth/DemoAuthMethod.d.ts +1 -1
- package/dist/auth/DemoAuthMethod.js +25 -25
- package/dist/auth/DemoAuthMethod.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/provider.d.ts +4 -4
- package/dist/provider.js +7 -3
- package/dist/provider.js.map +1 -1
- package/dist/storage/expo-secure-store-adapter.d.ts +7 -0
- package/dist/storage/expo-secure-store-adapter.js +25 -0
- package/dist/storage/expo-secure-store-adapter.js.map +1 -0
- package/dist/storage/kv-store-context.d.ts +15 -0
- package/dist/{native-storage.js → storage/kv-store-context.js} +8 -8
- package/dist/storage/kv-store-context.js.map +1 -0
- package/package.json +8 -8
- package/src/auth/DemoAuthMethod.ts +23 -23
- package/src/index.ts +5 -6
- package/src/provider.tsx +9 -8
- package/src/storage/expo-secure-store-adapter.ts +29 -0
- package/src/storage/kv-store-context.ts +35 -0
- package/.turbo/turbo-build.log +0 -8
- package/dist/native-storage.d.ts +0 -15
- package/dist/native-storage.js.map +0 -1
- package/src/native-storage.ts +0 -35
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,20 @@
|
|
1
1
|
# jazz-browser
|
2
2
|
|
3
|
+
## 0.8.11
|
4
|
+
|
5
|
+
### Patch Changes
|
6
|
+
|
7
|
+
- Updated dependencies [1ed4ab5]
|
8
|
+
- cojson@0.8.11
|
9
|
+
- cojson-transport-ws@0.8.11
|
10
|
+
- jazz-tools@0.8.11
|
11
|
+
|
12
|
+
## 0.8.8
|
13
|
+
|
14
|
+
### Patch Changes
|
15
|
+
|
16
|
+
- b7639cf: feat(react-native): replaced react-native-mmkv with expo-secure-store and initialize it by default as kvStore in createJazzRNApp() (BREAKING)
|
17
|
+
|
3
18
|
## 0.8.7
|
4
19
|
|
5
20
|
### Patch Changes
|
package/README.md
CHANGED
@@ -1,10 +1,233 @@
|
|
1
|
-
#
|
1
|
+
# 🎷 Jazz + React Native
|
2
2
|
|
3
|
-
|
3
|
+
Jazz requires an [Expo development build](https://docs.expo.dev/develop/development-builds/introduction/) using [Expo Prebuild](https://docs.expo.dev/workflow/prebuild/) for native code. It is **not compatible** with Expo Go. Jazz also supports the [New Architecture](https://docs.expo.dev/guides/new-architecture/).
|
4
4
|
|
5
|
-
|
6
|
-
or to build your framework bindings for Jazz.
|
5
|
+
Tested with:
|
7
6
|
|
8
|
-
|
7
|
+
```json
|
8
|
+
"expo": "~51.0.0",
|
9
|
+
"react-native": "~0.74.5",
|
10
|
+
"react": "^18.2.0",
|
11
|
+
```
|
9
12
|
|
10
|
-
|
13
|
+
## 🚀 Setup
|
14
|
+
|
15
|
+
### Create a New Project
|
16
|
+
|
17
|
+
(skip this step if you already have one)
|
18
|
+
|
19
|
+
```bash
|
20
|
+
npx create-expo-app -e with-router-tailwind my-jazz-app
|
21
|
+
cd my-jazz-app
|
22
|
+
npx expo prebuild
|
23
|
+
```
|
24
|
+
|
25
|
+
### Install dependencies
|
26
|
+
|
27
|
+
```bash
|
28
|
+
npx expo install expo-linking expo-secure-store expo-file-system @react-native-community/netinfo @bam.tech/react-native-image-resizer
|
29
|
+
|
30
|
+
npm i -S react-native-polyfill-globals react-native-url-polyfill web-streams-polyfill base-64 text-encoding react-native-fetch-api react-native-get-random-values buffer
|
31
|
+
|
32
|
+
npm i -D @babel/plugin-transform-class-static-block
|
33
|
+
|
34
|
+
npm i -S jazz-tools jazz-react-native jazz-react-native-media-images
|
35
|
+
|
36
|
+
```
|
37
|
+
|
38
|
+
### Fix Incompatible Dependencies
|
39
|
+
|
40
|
+
```bash
|
41
|
+
npx expo install --fix
|
42
|
+
```
|
43
|
+
|
44
|
+
### Install Pods
|
45
|
+
|
46
|
+
```bash
|
47
|
+
npx pod-install
|
48
|
+
```
|
49
|
+
|
50
|
+
### Configure Metro
|
51
|
+
|
52
|
+
#### Regular Repositories
|
53
|
+
|
54
|
+
If you are not working within a monorepo, create a new file metro.config.js in the root of your project with the following content:
|
55
|
+
|
56
|
+
```js
|
57
|
+
const { getDefaultConfig } = require("expo/metro-config");
|
58
|
+
const path = require("path");
|
59
|
+
const workspaceRoot = path.resolve(__dirname);
|
60
|
+
const config = getDefaultConfig(projectRoot);
|
61
|
+
config.resolver.unstable_enablePackageExports = true; // important setting
|
62
|
+
config.resolver.sourceExts = ["mjs", "js", "json", "ts", "tsx"];
|
63
|
+
config.resolver.requireCycleIgnorePatterns = [/(^|\/|\\)node_modules($|\/|\\)/];
|
64
|
+
module.exports = config;
|
65
|
+
```
|
66
|
+
|
67
|
+
If you created the project using the command npx create-expo-app -e with-router-tailwind my-jazz-app, then metro.config.js is already present. In that case, simply add this setting to the existing file:
|
68
|
+
|
69
|
+
```js
|
70
|
+
config.resolver.unstable_enablePackageExports = true
|
71
|
+
```
|
72
|
+
|
73
|
+
#### Monorepos
|
74
|
+
|
75
|
+
For monorepos, use the following metro.config.js:
|
76
|
+
|
77
|
+
```js
|
78
|
+
const { getDefaultConfig } = require("expo/metro-config");
|
79
|
+
const { FileStore } = require("metro-cache");
|
80
|
+
const path = require("path");
|
81
|
+
|
82
|
+
// eslint-disable-next-line no-undef
|
83
|
+
const projectRoot = __dirname;
|
84
|
+
const workspaceRoot = path.resolve(projectRoot, "../..");
|
85
|
+
|
86
|
+
const config = getDefaultConfig(projectRoot);
|
87
|
+
|
88
|
+
config.watchFolders = [workspaceRoot];
|
89
|
+
config.resolver.nodeModulesPaths = [
|
90
|
+
path.resolve(projectRoot, "node_modules"),
|
91
|
+
path.resolve(workspaceRoot, "node_modules"),
|
92
|
+
];
|
93
|
+
config.resolver.sourceExts = ["mjs", "js", "json", "ts", "tsx"];
|
94
|
+
config.resolver.unstable_enablePackageExports = true;
|
95
|
+
config.resolver.requireCycleIgnorePatterns = [/(^|\/|\\)node_modules($|\/|\\)/];
|
96
|
+
config.cacheStores = [
|
97
|
+
new FileStore({
|
98
|
+
root: path.join(projectRoot, "node_modules", ".cache", "metro"),
|
99
|
+
}),
|
100
|
+
];
|
101
|
+
|
102
|
+
module.exports = config;
|
103
|
+
```
|
104
|
+
|
105
|
+
### Additional Monorepo Configuration (for pnpm users)
|
106
|
+
|
107
|
+
- Add node-linker=hoisted to the root .npmrc (create this file if it doesn’t exist).
|
108
|
+
- Add the following to the root package.json:
|
109
|
+
|
110
|
+
```json
|
111
|
+
"pnpm": {
|
112
|
+
"peerDependencyRules": {
|
113
|
+
"ignoreMissing": [
|
114
|
+
"@babel/*",
|
115
|
+
"expo-modules-*",
|
116
|
+
"typescript"
|
117
|
+
]
|
118
|
+
}
|
119
|
+
}
|
120
|
+
```
|
121
|
+
|
122
|
+
For more information, refer to [this](https://github.com/byCedric/expo-monorepo-example#pnpm-workarounds) Expo monorepo example.
|
123
|
+
|
124
|
+
### Configure Babel
|
125
|
+
|
126
|
+
Add `@babel/plugin-transform-class-static-block` to the array of Babel plugins inside `babel.config.js`:
|
127
|
+
|
128
|
+
```js
|
129
|
+
module.exports = function (api) {
|
130
|
+
api.cache(true);
|
131
|
+
return {
|
132
|
+
presets: ["babel-preset-expo"],
|
133
|
+
plugins: [
|
134
|
+
"nativewind/babel",
|
135
|
+
"@babel/plugin-transform-class-static-block",
|
136
|
+
],
|
137
|
+
};
|
138
|
+
};
|
139
|
+
```
|
140
|
+
|
141
|
+
### Add Polyfills
|
142
|
+
|
143
|
+
Create a file `polyfills.js` at the project root with the following content:
|
144
|
+
|
145
|
+
```js
|
146
|
+
import "react-native-polyfill-globals/auto";
|
147
|
+
import "@azure/core-asynciterator-polyfill";
|
148
|
+
import { ReadableStream } from "web-streams-polyfill/ponyfill/es6";
|
149
|
+
import { polyfillGlobal } from "react-native/Libraries/Utilities/PolyfillFunctions";
|
150
|
+
import { Buffer } from "buffer";
|
151
|
+
|
152
|
+
polyfillGlobal("Buffer", () => Buffer);
|
153
|
+
polyfillGlobal("ReadableStream", () => ReadableStream);
|
154
|
+
```
|
155
|
+
|
156
|
+
Update `index.js` based on whether you are using expo-router or not:
|
157
|
+
|
158
|
+
#### If using `expo-router`
|
159
|
+
|
160
|
+
```js
|
161
|
+
import "./polyfills";
|
162
|
+
import "expo-router/entry";
|
163
|
+
```
|
164
|
+
|
165
|
+
#### Without `expo-router`
|
166
|
+
|
167
|
+
```js
|
168
|
+
import "./polyfills";
|
169
|
+
import { registerRootComponent } from "expo";
|
170
|
+
import App from "./src/App";
|
171
|
+
registerRootComponent(App);
|
172
|
+
```
|
173
|
+
|
174
|
+
Lastly, ensure that the `"main"` field in your `package.json` points to `index.js`:
|
175
|
+
|
176
|
+
```js
|
177
|
+
"main": "index.js",
|
178
|
+
```
|
179
|
+
|
180
|
+
## 🎉 How to Use Jazz
|
181
|
+
|
182
|
+
### `createJazzRNApp()`
|
183
|
+
|
184
|
+
Create a file `jazz.tsx` with the following contents:
|
185
|
+
|
186
|
+
```js
|
187
|
+
import { createJazzRNApp } from "jazz-react-native";
|
188
|
+
|
189
|
+
export const Jazz = createJazzRNApp();
|
190
|
+
export const { useAccount, useCoState, useAcceptInvite } = Jazz;
|
191
|
+
```
|
192
|
+
|
193
|
+
You can optionally pass a custom `kvStore` and `AccountSchema` to `createJazzRNApp()`, otherwise, it defaults to `ExpoSecureStoreAdapter` and `Account`.
|
194
|
+
|
195
|
+
### Choosing an Auth Method
|
196
|
+
|
197
|
+
Refer to the Jazz + React Native demo projects for implementing authentication:
|
198
|
+
|
199
|
+
- [DemoAuth Example](https://github.com/gardencmp/jazz/tree/main/examples/chat-rn)
|
200
|
+
- [ClerkAuth Example](https://github.com/gardencmp/jazz/tree/main/examples/chat-rn-clerk)
|
201
|
+
|
202
|
+
In the demos, you'll find details on:
|
203
|
+
|
204
|
+
- Using Jazz.Provider with your chosen authentication method
|
205
|
+
- Defining a Jazz schema
|
206
|
+
- Creating and subscribing to covalues
|
207
|
+
- Handling invites
|
208
|
+
|
209
|
+
### 🖼️ Working with Images
|
210
|
+
|
211
|
+
To work with images in Jazz, import the `createImage` function from [`jazz-react-native-media-images`](https://github.com/gardencmp/jazz/tree/main/packages/jazz-react-native-media-images).
|
212
|
+
|
213
|
+
```js
|
214
|
+
import { createImage } from "jazz-react-native-media-images";
|
215
|
+
|
216
|
+
const base64ImageDataURI = "data:image/png;base64,...";
|
217
|
+
|
218
|
+
const image = await createImage(base64ImageDataURI, {
|
219
|
+
owner: newPetPost._owner,
|
220
|
+
maxSize: 2048, // optional: specify maximum image size
|
221
|
+
});
|
222
|
+
|
223
|
+
someCovalue.image = image;
|
224
|
+
```
|
225
|
+
|
226
|
+
For a complete implementation, please refer to [this](https://github.com/gardencmp/jazz/blob/main/examples/pets/src/3_NewPetPostForm.tsx) demo.
|
227
|
+
|
228
|
+
### 📱 Running Your App
|
229
|
+
|
230
|
+
```bash
|
231
|
+
npx expo run:ios
|
232
|
+
npx expo run:android
|
233
|
+
```
|
@@ -16,7 +16,7 @@ export declare namespace RNDemoAuth {
|
|
16
16
|
}
|
17
17
|
export declare class RNDemoAuth implements AuthMethod {
|
18
18
|
private driver;
|
19
|
-
private
|
19
|
+
private kvStore;
|
20
20
|
private constructor();
|
21
21
|
static init(driver: RNDemoAuth.Driver, seedAccounts?: {
|
22
22
|
[name: string]: {
|
@@ -1,33 +1,33 @@
|
|
1
|
-
import
|
1
|
+
import { KvStoreContext } from "../storage/kv-store-context.js";
|
2
2
|
const localStorageKey = "demo-auth-logged-in-secret";
|
3
3
|
export class RNDemoAuth {
|
4
4
|
driver;
|
5
|
-
|
6
|
-
constructor(driver,
|
5
|
+
kvStore;
|
6
|
+
constructor(driver, kvStore) {
|
7
7
|
this.driver = driver;
|
8
|
-
this.
|
8
|
+
this.kvStore = kvStore;
|
9
9
|
}
|
10
10
|
static async init(driver, seedAccounts) {
|
11
|
-
const
|
11
|
+
const kvStore = KvStoreContext.getInstance().getStorage();
|
12
12
|
for (const [name, credentials] of Object.entries(seedAccounts || {})) {
|
13
13
|
const storageData = JSON.stringify(credentials);
|
14
|
-
if (!(await
|
15
|
-
const existingUsers = await
|
14
|
+
if (!(await kvStore.get("demo-auth-existing-users"))?.split(",")?.includes(name)) {
|
15
|
+
const existingUsers = await kvStore.get("demo-auth-existing-users");
|
16
16
|
if (existingUsers) {
|
17
|
-
await
|
17
|
+
await kvStore.set("demo-auth-existing-users", existingUsers + "," + name);
|
18
18
|
}
|
19
19
|
else {
|
20
|
-
await
|
20
|
+
await kvStore.set("demo-auth-existing-users", name);
|
21
21
|
}
|
22
22
|
}
|
23
|
-
await
|
23
|
+
await kvStore.set("demo-auth-existing-users-" + name, storageData);
|
24
24
|
}
|
25
|
-
return new RNDemoAuth(driver,
|
25
|
+
return new RNDemoAuth(driver, kvStore);
|
26
26
|
}
|
27
27
|
async start() {
|
28
28
|
try {
|
29
|
-
if (await this.
|
30
|
-
const localStorageData = JSON.parse((await this.
|
29
|
+
if (await this.kvStore.get(localStorageKey)) {
|
30
|
+
const localStorageData = JSON.parse((await this.kvStore.get(localStorageKey)) ?? "{}");
|
31
31
|
const accountID = localStorageData.accountID;
|
32
32
|
const secret = localStorageData.accountSecret;
|
33
33
|
return {
|
@@ -40,7 +40,7 @@ export class RNDemoAuth {
|
|
40
40
|
this.driver.onError(error);
|
41
41
|
},
|
42
42
|
logOut: async () => {
|
43
|
-
void (await this.
|
43
|
+
void (await this.kvStore.delete(localStorageKey));
|
44
44
|
},
|
45
45
|
};
|
46
46
|
}
|
@@ -58,7 +58,7 @@ export class RNDemoAuth {
|
|
58
58
|
accountSecret: credentials.secret,
|
59
59
|
});
|
60
60
|
// Retrieve the list of existing users
|
61
|
-
const existingUsers = await this.
|
61
|
+
const existingUsers = await this.kvStore.get("demo-auth-existing-users");
|
62
62
|
const existingUsernames = existingUsers
|
63
63
|
? existingUsers.split(",")
|
64
64
|
: [];
|
@@ -70,14 +70,14 @@ export class RNDemoAuth {
|
|
70
70
|
uniqueUsername = `${username}-${counter}`;
|
71
71
|
}
|
72
72
|
// Save credentials using the unique username
|
73
|
-
await this.
|
74
|
-
await this.
|
73
|
+
await this.kvStore.set(localStorageKey, storageData);
|
74
|
+
await this.kvStore.set("demo-auth-existing-users-" +
|
75
75
|
uniqueUsername, storageData);
|
76
76
|
// Update the list of existing users
|
77
77
|
const updatedUsers = existingUsers
|
78
78
|
? `${existingUsers},${uniqueUsername}`
|
79
79
|
: uniqueUsername;
|
80
|
-
await this.
|
80
|
+
await this.kvStore.set("demo-auth-existing-users", updatedUsers);
|
81
81
|
},
|
82
82
|
onSuccess: () => {
|
83
83
|
this.driver.onSignedIn({ logOut });
|
@@ -88,16 +88,16 @@ export class RNDemoAuth {
|
|
88
88
|
this.driver.onError(error);
|
89
89
|
},
|
90
90
|
logOut: async () => {
|
91
|
-
void (await this.
|
91
|
+
void (await this.kvStore.delete(localStorageKey));
|
92
92
|
},
|
93
93
|
});
|
94
94
|
},
|
95
95
|
getExistingUsers: async () => {
|
96
|
-
return ((await this.
|
96
|
+
return ((await this.kvStore.get("demo-auth-existing-users"))?.split(",") ?? []);
|
97
97
|
},
|
98
98
|
logInAs: async (existingUser) => {
|
99
|
-
const storageData = JSON.parse((await this.
|
100
|
-
await this.
|
99
|
+
const storageData = JSON.parse((await this.kvStore.get("demo-auth-existing-users-" + existingUser)) ?? "{}");
|
100
|
+
await this.kvStore.set(localStorageKey, JSON.stringify(storageData));
|
101
101
|
resolve({
|
102
102
|
type: "existing",
|
103
103
|
credentials: {
|
@@ -111,7 +111,7 @@ export class RNDemoAuth {
|
|
111
111
|
this.driver.onError(error);
|
112
112
|
},
|
113
113
|
logOut: async () => {
|
114
|
-
void (await this.
|
114
|
+
void (await this.kvStore.delete(localStorageKey));
|
115
115
|
},
|
116
116
|
});
|
117
117
|
},
|
@@ -126,7 +126,7 @@ export class RNDemoAuth {
|
|
126
126
|
}
|
127
127
|
}
|
128
128
|
async function logOut() {
|
129
|
-
const
|
130
|
-
void (await
|
129
|
+
const kvStore = KvStoreContext.getInstance().getStorage();
|
130
|
+
void (await kvStore.delete(localStorageKey));
|
131
131
|
}
|
132
132
|
//# sourceMappingURL=DemoAuthMethod.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"DemoAuthMethod.js","sourceRoot":"","sources":["../../src/auth/DemoAuthMethod.ts"],"names":[],"mappings":"AAEA,OAAO,
|
1
|
+
{"version":3,"file":"DemoAuthMethod.js","sourceRoot":"","sources":["../../src/auth/DemoAuthMethod.ts"],"names":[],"mappings":"AAEA,OAAO,EAAW,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAqBzE,MAAM,eAAe,GAAG,4BAA4B,CAAC;AAErD,MAAM,OAAO,UAAU;IAEP;IACA;IAFZ,YACY,MAAyB,EACzB,OAAgB;QADhB,WAAM,GAAN,MAAM,CAAmB;QACzB,YAAO,GAAP,OAAO,CAAS;IACzB,CAAC;IAEG,MAAM,CAAC,KAAK,CAAC,IAAI,CACpB,MAAyB,EACzB,YAKC;QAED,MAAM,OAAO,GAAG,cAAc,CAAC,WAAW,EAAE,CAAC,UAAU,EAAE,CAAC;QAC1D,KAAK,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC,EAAE,CAAC;YACnE,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAC9B,WAAiC,CACpC,CAAC;YACF,IACI,CACI,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC,EAAE,KAAK,CAClD,GAAG,CAEV,EAAE,QAAQ,CAAC,IAAI,CAAC,EACnB,CAAC;gBACC,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,GAAG,CACnC,0BAA0B,CAC7B,CAAC;gBACF,IAAI,aAAa,EAAE,CAAC;oBAChB,MAAM,OAAO,CAAC,GAAG,CACb,0BAA0B,EAC1B,aAAa,GAAG,GAAG,GAAG,IAAI,CAC7B,CAAC;gBACN,CAAC;qBAAM,CAAC;oBACJ,MAAM,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,IAAI,CAAC,CAAC;gBACxD,CAAC;YACL,CAAC;YACD,MAAM,OAAO,CAAC,GAAG,CAAC,2BAA2B,GAAG,IAAI,EAAE,WAAW,CAAC,CAAC;QACvE,CAAC;QACD,OAAO,IAAI,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,KAAK;QACP,IAAI,CAAC;YACD,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC;gBAC1C,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAC/B,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,IAAI,IAAI,CACrC,CAAC;gBAEjB,MAAM,SAAS,GAAG,gBAAgB,CAAC,SAAwB,CAAC;gBAC5D,MAAM,MAAM,GAAG,gBAAgB,CAAC,aAAa,CAAC;gBAE9C,OAAO;oBACH,IAAI,EAAE,UAAU;oBAChB,WAAW,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE;oBAClC,SAAS,EAAE,GAAG,EAAE;wBACZ,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;oBACvC,CAAC;oBACD,OAAO,EAAE,CAAC,KAAqB,EAAE,EAAE;wBAC/B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;oBAC/B,CAAC;oBACD,MAAM,EAAE,KAAK,IAAI,EAAE;wBACf,KAAK,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC;oBACtD,CAAC;iBACiB,CAAC;YAC3B,CAAC;iBAAM,CAAC;gBACJ,OAAO,IAAI,OAAO,CAAa,CAAC,OAAO,EAAE,EAAE;oBACvC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;wBAChB,uBAAuB;wBACvB,MAAM,EAAE,CAAC,QAAgB,EAAE,EAAE;4BACzB,OAAO,CAAC;gCACJ,IAAI,EAAE,KAAK;gCACX,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gCACjC,eAAe,EAAE,KAAK,EAAE,WAGvB,EAAE,EAAE;oCACD,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC;wCAC/B,SAAS,EAAE,WAAW,CAAC,SAAS;wCAChC,aAAa,EAAE,WAAW,CAAC,MAAM;qCACd,CAAC,CAAC;oCAEzB,sCAAsC;oCACtC,MAAM,aAAa,GACf,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAClB,0BAA0B,CAC7B,CAAC;oCACN,MAAM,iBAAiB,GAAG,aAAa;wCACnC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC;wCAC1B,CAAC,CAAC,EAAE,CAAC;oCAET,0EAA0E;oCAC1E,IAAI,cAAc,GAAG,QAAQ,CAAC;oCAC9B,IAAI,OAAO,GAAG,CAAC,CAAC;oCAChB,OACI,iBAAiB,CAAC,QAAQ,CACtB,cAAc,CACjB,EACH,CAAC;wCACC,OAAO,EAAE,CAAC;wCACV,cAAc,GAAG,GAAG,QAAQ,IAAI,OAAO,EAAE,CAAC;oCAC9C,CAAC;oCAED,6CAA6C;oCAC7C,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAClB,eAAe,EACf,WAAW,CACd,CAAC;oCACF,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAClB,2BAA2B;wCACvB,cAAc,EAClB,WAAW,CACd,CAAC;oCAEF,oCAAoC;oCACpC,MAAM,YAAY,GAAG,aAAa;wCAC9B,CAAC,CAAC,GAAG,aAAa,IAAI,cAAc,EAAE;wCACtC,CAAC,CAAC,cAAc,CAAC;oCACrB,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAClB,0BAA0B,EAC1B,YAAY,CACf,CAAC;gCACN,CAAC;gCACD,SAAS,EAAE,GAAG,EAAE;oCACZ,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;gCACvC,CAAC;gCACD,OAAO,EAAE,CAAC,KAAqB,EAAE,EAAE;oCAC/B,uBAAuB;oCACvB,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;oCACtC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gCAC/B,CAAC;gCACD,MAAM,EAAE,KAAK,IAAI,EAAE;oCACf,KAAK,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAC3B,eAAe,CAClB,CAAC,CAAC;gCACP,CAAC;6BACJ,CAAC,CAAC;wBACP,CAAC;wBACD,gBAAgB,EAAE,KAAK,IAAI,EAAE;4BACzB,OAAO,CACH,CACI,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAClB,0BAA0B,CAC7B,CACJ,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CACtB,CAAC;wBACN,CAAC;wBACD,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE;4BAC5B,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAC1B,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CACnB,2BAA2B,GAAG,YAAY,CAC7C,CAAC,IAAI,IAAI,CACE,CAAC;4BAEjB,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAClB,eAAe,EACf,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAC9B,CAAC;4BAEF,OAAO,CAAC;gCACJ,IAAI,EAAE,UAAU;gCAChB,WAAW,EAAE;oCACT,SAAS,EAAE,WAAW,CAAC,SAAS;oCAChC,MAAM,EAAE,WAAW,CAAC,aAAa;iCACpC;gCACD,SAAS,EAAE,GAAG,EAAE;oCACZ,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;gCACvC,CAAC;gCACD,OAAO,EAAE,CAAC,KAAqB,EAAE,EAAE;oCAC/B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gCAC/B,CAAC;gCACD,MAAM,EAAE,KAAK,IAAI,EAAE;oCACf,KAAK,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAC3B,eAAe,CAClB,CAAC,CAAC;gCACP,CAAC;6BACJ,CAAC,CAAC;wBACP,CAAC;qBACJ,CAAC,CAAC;gBACP,CAAC,CAAC,CAAC;YACP,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAC9B,MAAM,KAAK,CAAC;QAChB,CAAC;IACL,CAAC;CACJ;AAED,KAAK,UAAU,MAAM;IACjB,MAAM,OAAO,GAAG,cAAc,CAAC,WAAW,EAAE,CAAC,UAAU,EAAE,CAAC;IAC1D,KAAK,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC;AACjD,CAAC"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
@@ -6,7 +6,7 @@ import { createWebSocketPeer } from "cojson-transport-ws";
|
|
6
6
|
import NetInfo from "@react-native-community/netinfo";
|
7
7
|
import * as Linking from "expo-linking";
|
8
8
|
export { RNDemoAuth } from "./auth/DemoAuthMethod.js";
|
9
|
-
import {
|
9
|
+
import { KvStoreContext } from "./storage/kv-store-context.js";
|
10
10
|
export async function createJazzRNContext(options) {
|
11
11
|
const firstWsPeer = createWebSocketPeer({
|
12
12
|
websocket: new WebSocket(options.peer),
|
@@ -91,10 +91,10 @@ export async function createJazzRNContext(options) {
|
|
91
91
|
}
|
92
92
|
export async function provideLockSession(accountID, crypto) {
|
93
93
|
const sessionDone = () => { };
|
94
|
-
const
|
95
|
-
const sessionID = (await
|
94
|
+
const kvStore = KvStoreContext.getInstance().getStorage();
|
95
|
+
const sessionID = (await kvStore.get(accountID)) ||
|
96
96
|
crypto.newRandomSessionID(accountID);
|
97
|
-
await
|
97
|
+
await kvStore.set(accountID, sessionID);
|
98
98
|
return Promise.resolve({
|
99
99
|
sessionID,
|
100
100
|
sessionDone,
|
@@ -149,5 +149,5 @@ export function parseInviteLink(inviteURL) {
|
|
149
149
|
/////////
|
150
150
|
export * from "./provider.js";
|
151
151
|
export * from "./auth/auth.js";
|
152
|
-
export * from "./
|
152
|
+
export * from "./storage/kv-store-context.js";
|
153
153
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,sDAAsD;AACtD,OAAO,EAKH,eAAe,EAMf,iBAAiB,GAEpB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/provider.d.ts
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
import React from "react";
|
2
2
|
import { Account, AccountClass, AnonymousJazzAgent, AuthMethod, CoValue, CoValueClass, DeeplyLoaded, DepthsIn, ID } from "jazz-tools";
|
3
|
-
import {
|
3
|
+
import { ExpoSecureStoreAdapter } from "./storage/expo-secure-store-adapter.js";
|
4
4
|
/** @category Context & Hooks */
|
5
|
-
export declare function createJazzRNApp<Acc extends Account>({
|
6
|
-
|
7
|
-
AccountSchema?: AccountClass<Acc
|
5
|
+
export declare function createJazzRNApp<Acc extends Account>({ kvStore, AccountSchema, }?: {
|
6
|
+
kvStore?: ExpoSecureStoreAdapter | undefined;
|
7
|
+
AccountSchema?: AccountClass<Acc> | undefined;
|
8
8
|
}): JazzReactApp<Acc>;
|
9
9
|
/** @category Context & Hooks */
|
10
10
|
export interface JazzReactApp<Acc extends Account> {
|
package/dist/provider.js
CHANGED
@@ -1,11 +1,15 @@
|
|
1
1
|
import React, { useEffect, useState } from "react";
|
2
2
|
import { Account, subscribeToCoValue, } from "jazz-tools";
|
3
|
-
import { createJazzRNContext,
|
3
|
+
import { createJazzRNContext, KvStoreContext, parseInviteLink, } from "./index.js";
|
4
4
|
import { Linking } from "react-native";
|
5
|
+
import { ExpoSecureStoreAdapter } from "./storage/expo-secure-store-adapter.js";
|
5
6
|
/** @category Context & Hooks */
|
6
|
-
export function createJazzRNApp({
|
7
|
+
export function createJazzRNApp({ kvStore = new ExpoSecureStoreAdapter(), AccountSchema = Account, } = {}) {
|
7
8
|
const JazzContext = React.createContext(undefined);
|
8
|
-
|
9
|
+
if (!kvStore) {
|
10
|
+
throw new Error("kvStore is required");
|
11
|
+
}
|
12
|
+
KvStoreContext.getInstance().initialize(kvStore);
|
9
13
|
function Provider({ children, auth, peer, storage, }) {
|
10
14
|
const [ctx, setCtx] = useState();
|
11
15
|
const [sessionCount, setSessionCount] = useState(0);
|
package/dist/provider.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,EACH,OAAO,EASP,kBAAkB,GACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EAGH,mBAAmB,EACnB,
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,7 @@
|
|
1
|
+
import type { KvStore } from "./kv-store-context.js";
|
2
|
+
export declare class ExpoSecureStoreAdapter implements KvStore {
|
3
|
+
get(key: string): Promise<string | null>;
|
4
|
+
set(key: string, value: string): Promise<void>;
|
5
|
+
delete(key: string): Promise<void>;
|
6
|
+
clearAll(): Promise<void>;
|
7
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import * as SecureStore from "expo-secure-store";
|
2
|
+
export class ExpoSecureStoreAdapter {
|
3
|
+
get(key) {
|
4
|
+
return SecureStore.getItemAsync(key, {
|
5
|
+
requireAuthentication: SecureStore.canUseBiometricAuthentication(),
|
6
|
+
keychainAccessible: SecureStore.AFTER_FIRST_UNLOCK,
|
7
|
+
});
|
8
|
+
}
|
9
|
+
async set(key, value) {
|
10
|
+
return SecureStore.setItemAsync(key, value, {
|
11
|
+
requireAuthentication: SecureStore.canUseBiometricAuthentication(),
|
12
|
+
keychainAccessible: SecureStore.AFTER_FIRST_UNLOCK,
|
13
|
+
});
|
14
|
+
}
|
15
|
+
async delete(key) {
|
16
|
+
return SecureStore.deleteItemAsync(key, {
|
17
|
+
requireAuthentication: SecureStore.canUseBiometricAuthentication(),
|
18
|
+
keychainAccessible: SecureStore.AFTER_FIRST_UNLOCK,
|
19
|
+
});
|
20
|
+
}
|
21
|
+
async clearAll() {
|
22
|
+
throw new Error("Not implemented");
|
23
|
+
}
|
24
|
+
}
|
25
|
+
//# sourceMappingURL=expo-secure-store-adapter.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"expo-secure-store-adapter.js","sourceRoot":"","sources":["../../src/storage/expo-secure-store-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAC;AAGjD,MAAM,OAAO,sBAAsB;IAC/B,GAAG,CAAC,GAAW;QACX,OAAO,WAAW,CAAC,YAAY,CAAC,GAAG,EAAE;YACjC,qBAAqB,EAAE,WAAW,CAAC,6BAA6B,EAAE;YAClE,kBAAkB,EAAE,WAAW,CAAC,kBAAkB;SACrD,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAa;QAChC,OAAO,WAAW,CAAC,YAAY,CAAC,GAAG,EAAE,KAAK,EAAE;YACxC,qBAAqB,EAAE,WAAW,CAAC,6BAA6B,EAAE;YAClE,kBAAkB,EAAE,WAAW,CAAC,kBAAkB;SACrD,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACpB,OAAO,WAAW,CAAC,eAAe,CAAC,GAAG,EAAE;YACpC,qBAAqB,EAAE,WAAW,CAAC,6BAA6B,EAAE;YAClE,kBAAkB,EAAE,WAAW,CAAC,kBAAkB;SACrD,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,QAAQ;QACV,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACvC,CAAC;CACJ"}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
export interface KvStore {
|
2
|
+
get(key: string): Promise<string | null>;
|
3
|
+
set(key: string, value: string): Promise<void>;
|
4
|
+
delete(key: string): Promise<void>;
|
5
|
+
clearAll(): Promise<void>;
|
6
|
+
}
|
7
|
+
export declare class KvStoreContext {
|
8
|
+
private static instance;
|
9
|
+
private storageInstance;
|
10
|
+
private constructor();
|
11
|
+
static getInstance(): KvStoreContext;
|
12
|
+
initialize(store: KvStore): void;
|
13
|
+
getStorage(): KvStore;
|
14
|
+
}
|
15
|
+
export default KvStoreContext;
|
@@ -1,16 +1,16 @@
|
|
1
|
-
export class
|
1
|
+
export class KvStoreContext {
|
2
2
|
static instance;
|
3
3
|
storageInstance = null;
|
4
4
|
constructor() { }
|
5
5
|
static getInstance() {
|
6
|
-
if (!
|
7
|
-
|
6
|
+
if (!KvStoreContext.instance) {
|
7
|
+
KvStoreContext.instance = new KvStoreContext();
|
8
8
|
}
|
9
|
-
return
|
9
|
+
return KvStoreContext.instance;
|
10
10
|
}
|
11
|
-
initialize(
|
11
|
+
initialize(store) {
|
12
12
|
if (!this.storageInstance) {
|
13
|
-
this.storageInstance =
|
13
|
+
this.storageInstance = store;
|
14
14
|
}
|
15
15
|
}
|
16
16
|
getStorage() {
|
@@ -20,5 +20,5 @@ export class NativeStorageContext {
|
|
20
20
|
return this.storageInstance;
|
21
21
|
}
|
22
22
|
}
|
23
|
-
export default
|
24
|
-
//# sourceMappingURL=
|
23
|
+
export default KvStoreContext;
|
24
|
+
//# sourceMappingURL=kv-store-context.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"kv-store-context.js","sourceRoot":"","sources":["../../src/storage/kv-store-context.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,cAAc;IACf,MAAM,CAAC,QAAQ,CAAiB;IAChC,eAAe,GAAmB,IAAI,CAAC;IAE/C,gBAAuB,CAAC;IAEjB,MAAM,CAAC,WAAW;QACrB,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC;YAC3B,cAAc,CAAC,QAAQ,GAAG,IAAI,cAAc,EAAE,CAAC;QACnD,CAAC;QACD,OAAO,cAAc,CAAC,QAAQ,CAAC;IACnC,CAAC;IAEM,UAAU,CAAC,KAAc;QAC5B,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YACxB,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;QACjC,CAAC;IACL,CAAC;IAEM,UAAU;QACb,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,IAAI,CAAC,eAAe,CAAC;IAChC,CAAC;CACJ;AAED,eAAe,cAAc,CAAC"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "jazz-react-native",
|
3
|
-
"version": "0.8.
|
3
|
+
"version": "0.8.11",
|
4
4
|
"type": "module",
|
5
5
|
"main": "./dist/index.js",
|
6
6
|
"module": "./dist/index.js",
|
@@ -17,21 +17,21 @@
|
|
17
17
|
"dependencies": {
|
18
18
|
"@scure/bip39": "^1.3.0",
|
19
19
|
"typescript": "^5.3.3",
|
20
|
-
"cojson": "0.8.
|
21
|
-
"cojson-transport-ws": "0.8.
|
22
|
-
"jazz-tools": "0.8.
|
20
|
+
"cojson": "0.8.11",
|
21
|
+
"cojson-transport-ws": "0.8.11",
|
22
|
+
"jazz-tools": "0.8.11"
|
23
23
|
},
|
24
24
|
"peerDependencies": {
|
25
25
|
"@react-native-community/netinfo": "*",
|
26
26
|
"expo-linking": "*",
|
27
|
-
"
|
28
|
-
"react-native
|
27
|
+
"expo-secure-store": "*",
|
28
|
+
"react-native": "*"
|
29
29
|
},
|
30
30
|
"devDependencies": {
|
31
31
|
"@react-native-community/netinfo": "^11.3.1",
|
32
32
|
"expo-linking": "~6.3.1",
|
33
|
-
"
|
34
|
-
"react-native
|
33
|
+
"expo-secure-store": "~13.0.2",
|
34
|
+
"react-native": "~0.74.5"
|
35
35
|
},
|
36
36
|
"lint-staged": {
|
37
37
|
"*.{ts,tsx}": "eslint --fix",
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { AgentSecret } from "cojson";
|
2
2
|
import { Account, AuthMethod, AuthResult, ID } from "jazz-tools";
|
3
|
-
import
|
3
|
+
import { KvStore, KvStoreContext } from "../storage/kv-store-context.js";
|
4
4
|
|
5
5
|
type StorageData = {
|
6
6
|
accountID: ID<Account>;
|
@@ -26,7 +26,7 @@ const localStorageKey = "demo-auth-logged-in-secret";
|
|
26
26
|
export class RNDemoAuth implements AuthMethod {
|
27
27
|
private constructor(
|
28
28
|
private driver: RNDemoAuth.Driver,
|
29
|
-
private
|
29
|
+
private kvStore: KvStore,
|
30
30
|
) {}
|
31
31
|
|
32
32
|
public static async init(
|
@@ -38,40 +38,40 @@ export class RNDemoAuth implements AuthMethod {
|
|
38
38
|
};
|
39
39
|
},
|
40
40
|
) {
|
41
|
-
const
|
41
|
+
const kvStore = KvStoreContext.getInstance().getStorage();
|
42
42
|
for (const [name, credentials] of Object.entries(seedAccounts || {})) {
|
43
43
|
const storageData = JSON.stringify(
|
44
44
|
credentials satisfies StorageData,
|
45
45
|
);
|
46
46
|
if (
|
47
47
|
!(
|
48
|
-
(await
|
48
|
+
(await kvStore.get("demo-auth-existing-users"))?.split(
|
49
49
|
",",
|
50
50
|
) as string[] | undefined
|
51
51
|
)?.includes(name)
|
52
52
|
) {
|
53
|
-
const existingUsers = await
|
53
|
+
const existingUsers = await kvStore.get(
|
54
54
|
"demo-auth-existing-users",
|
55
55
|
);
|
56
56
|
if (existingUsers) {
|
57
|
-
await
|
57
|
+
await kvStore.set(
|
58
58
|
"demo-auth-existing-users",
|
59
59
|
existingUsers + "," + name,
|
60
60
|
);
|
61
61
|
} else {
|
62
|
-
await
|
62
|
+
await kvStore.set("demo-auth-existing-users", name);
|
63
63
|
}
|
64
64
|
}
|
65
|
-
await
|
65
|
+
await kvStore.set("demo-auth-existing-users-" + name, storageData);
|
66
66
|
}
|
67
|
-
return new RNDemoAuth(driver,
|
67
|
+
return new RNDemoAuth(driver, kvStore);
|
68
68
|
}
|
69
69
|
|
70
70
|
async start() {
|
71
71
|
try {
|
72
|
-
if (await this.
|
72
|
+
if (await this.kvStore.get(localStorageKey)) {
|
73
73
|
const localStorageData = JSON.parse(
|
74
|
-
(await this.
|
74
|
+
(await this.kvStore.get(localStorageKey)) ?? "{}",
|
75
75
|
) as StorageData;
|
76
76
|
|
77
77
|
const accountID = localStorageData.accountID as ID<Account>;
|
@@ -87,7 +87,7 @@ export class RNDemoAuth implements AuthMethod {
|
|
87
87
|
this.driver.onError(error);
|
88
88
|
},
|
89
89
|
logOut: async () => {
|
90
|
-
void (await this.
|
90
|
+
void (await this.kvStore.delete(localStorageKey));
|
91
91
|
},
|
92
92
|
} satisfies AuthResult;
|
93
93
|
} else {
|
@@ -109,7 +109,7 @@ export class RNDemoAuth implements AuthMethod {
|
|
109
109
|
|
110
110
|
// Retrieve the list of existing users
|
111
111
|
const existingUsers =
|
112
|
-
await this.
|
112
|
+
await this.kvStore.get(
|
113
113
|
"demo-auth-existing-users",
|
114
114
|
);
|
115
115
|
const existingUsernames = existingUsers
|
@@ -129,11 +129,11 @@ export class RNDemoAuth implements AuthMethod {
|
|
129
129
|
}
|
130
130
|
|
131
131
|
// Save credentials using the unique username
|
132
|
-
await this.
|
132
|
+
await this.kvStore.set(
|
133
133
|
localStorageKey,
|
134
134
|
storageData,
|
135
135
|
);
|
136
|
-
await this.
|
136
|
+
await this.kvStore.set(
|
137
137
|
"demo-auth-existing-users-" +
|
138
138
|
uniqueUsername,
|
139
139
|
storageData,
|
@@ -143,7 +143,7 @@ export class RNDemoAuth implements AuthMethod {
|
|
143
143
|
const updatedUsers = existingUsers
|
144
144
|
? `${existingUsers},${uniqueUsername}`
|
145
145
|
: uniqueUsername;
|
146
|
-
await this.
|
146
|
+
await this.kvStore.set(
|
147
147
|
"demo-auth-existing-users",
|
148
148
|
updatedUsers,
|
149
149
|
);
|
@@ -157,7 +157,7 @@ export class RNDemoAuth implements AuthMethod {
|
|
157
157
|
this.driver.onError(error);
|
158
158
|
},
|
159
159
|
logOut: async () => {
|
160
|
-
void (await this.
|
160
|
+
void (await this.kvStore.delete(
|
161
161
|
localStorageKey,
|
162
162
|
));
|
163
163
|
},
|
@@ -166,7 +166,7 @@ export class RNDemoAuth implements AuthMethod {
|
|
166
166
|
getExistingUsers: async () => {
|
167
167
|
return (
|
168
168
|
(
|
169
|
-
await this.
|
169
|
+
await this.kvStore.get(
|
170
170
|
"demo-auth-existing-users",
|
171
171
|
)
|
172
172
|
)?.split(",") ?? []
|
@@ -174,12 +174,12 @@ export class RNDemoAuth implements AuthMethod {
|
|
174
174
|
},
|
175
175
|
logInAs: async (existingUser) => {
|
176
176
|
const storageData = JSON.parse(
|
177
|
-
(await this.
|
177
|
+
(await this.kvStore.get(
|
178
178
|
"demo-auth-existing-users-" + existingUser,
|
179
179
|
)) ?? "{}",
|
180
180
|
) as StorageData;
|
181
181
|
|
182
|
-
await this.
|
182
|
+
await this.kvStore.set(
|
183
183
|
localStorageKey,
|
184
184
|
JSON.stringify(storageData),
|
185
185
|
);
|
@@ -197,7 +197,7 @@ export class RNDemoAuth implements AuthMethod {
|
|
197
197
|
this.driver.onError(error);
|
198
198
|
},
|
199
199
|
logOut: async () => {
|
200
|
-
void (await this.
|
200
|
+
void (await this.kvStore.delete(
|
201
201
|
localStorageKey,
|
202
202
|
));
|
203
203
|
},
|
@@ -214,6 +214,6 @@ export class RNDemoAuth implements AuthMethod {
|
|
214
214
|
}
|
215
215
|
|
216
216
|
async function logOut() {
|
217
|
-
const
|
218
|
-
void (await
|
217
|
+
const kvStore = KvStoreContext.getInstance().getStorage();
|
218
|
+
void (await kvStore.delete(localStorageKey));
|
219
219
|
}
|
package/src/index.ts
CHANGED
@@ -18,13 +18,12 @@ import {
|
|
18
18
|
import { PureJSCrypto } from "jazz-tools/native";
|
19
19
|
import { RawAccountID } from "cojson";
|
20
20
|
import { createWebSocketPeer } from "cojson-transport-ws";
|
21
|
-
import { MMKV } from "react-native-mmkv";
|
22
21
|
import NetInfo from "@react-native-community/netinfo";
|
23
22
|
import * as Linking from "expo-linking";
|
24
23
|
|
25
24
|
export { RNDemoAuth } from "./auth/DemoAuthMethod.js";
|
26
25
|
|
27
|
-
import {
|
26
|
+
import { KvStoreContext } from "./storage/kv-store-context.js";
|
28
27
|
|
29
28
|
/** @category Context Creation */
|
30
29
|
export type BrowserContext<Acc extends Account> = {
|
@@ -182,12 +181,12 @@ export async function provideLockSession(
|
|
182
181
|
) {
|
183
182
|
const sessionDone = () => {};
|
184
183
|
|
185
|
-
const
|
184
|
+
const kvStore = KvStoreContext.getInstance().getStorage();
|
186
185
|
|
187
186
|
const sessionID =
|
188
|
-
((await
|
187
|
+
((await kvStore.get(accountID)) as SessionID) ||
|
189
188
|
crypto.newRandomSessionID(accountID as RawAccountID | AgentID);
|
190
|
-
await
|
189
|
+
await kvStore.set(accountID, sessionID);
|
191
190
|
|
192
191
|
return Promise.resolve({
|
193
192
|
sessionID,
|
@@ -272,4 +271,4 @@ export function parseInviteLink<C extends CoValue>(
|
|
272
271
|
|
273
272
|
export * from "./provider.js";
|
274
273
|
export * from "./auth/auth.js";
|
275
|
-
export * from "./
|
274
|
+
export * from "./storage/kv-store-context.js";
|
package/src/provider.tsx
CHANGED
@@ -16,25 +16,26 @@ import {
|
|
16
16
|
BrowserContext,
|
17
17
|
BrowserGuestContext,
|
18
18
|
createJazzRNContext,
|
19
|
-
|
20
|
-
NativeStorage,
|
19
|
+
KvStoreContext,
|
21
20
|
parseInviteLink,
|
22
21
|
} from "./index.js";
|
23
22
|
import { Linking } from "react-native";
|
23
|
+
import { ExpoSecureStoreAdapter } from "./storage/expo-secure-store-adapter.js";
|
24
24
|
|
25
25
|
/** @category Context & Hooks */
|
26
26
|
export function createJazzRNApp<Acc extends Account>({
|
27
|
-
|
27
|
+
kvStore = new ExpoSecureStoreAdapter(),
|
28
28
|
AccountSchema = Account as unknown as AccountClass<Acc>,
|
29
|
-
}: {
|
30
|
-
nativeStorage: NativeStorage;
|
31
|
-
AccountSchema?: AccountClass<Acc>;
|
32
|
-
}): JazzReactApp<Acc> {
|
29
|
+
} = {}): JazzReactApp<Acc> {
|
33
30
|
const JazzContext = React.createContext<
|
34
31
|
BrowserContext<Acc> | BrowserGuestContext | undefined
|
35
32
|
>(undefined);
|
36
33
|
|
37
|
-
|
34
|
+
if (!kvStore) {
|
35
|
+
throw new Error("kvStore is required");
|
36
|
+
}
|
37
|
+
|
38
|
+
KvStoreContext.getInstance().initialize(kvStore);
|
38
39
|
|
39
40
|
function Provider({
|
40
41
|
children,
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import * as SecureStore from "expo-secure-store";
|
2
|
+
import type { KvStore } from "./kv-store-context.js";
|
3
|
+
|
4
|
+
export class ExpoSecureStoreAdapter implements KvStore {
|
5
|
+
get(key: string): Promise<string | null> {
|
6
|
+
return SecureStore.getItemAsync(key, {
|
7
|
+
requireAuthentication: SecureStore.canUseBiometricAuthentication(),
|
8
|
+
keychainAccessible: SecureStore.AFTER_FIRST_UNLOCK,
|
9
|
+
});
|
10
|
+
}
|
11
|
+
|
12
|
+
async set(key: string, value: string): Promise<void> {
|
13
|
+
return SecureStore.setItemAsync(key, value, {
|
14
|
+
requireAuthentication: SecureStore.canUseBiometricAuthentication(),
|
15
|
+
keychainAccessible: SecureStore.AFTER_FIRST_UNLOCK,
|
16
|
+
});
|
17
|
+
}
|
18
|
+
|
19
|
+
async delete(key: string): Promise<void> {
|
20
|
+
return SecureStore.deleteItemAsync(key, {
|
21
|
+
requireAuthentication: SecureStore.canUseBiometricAuthentication(),
|
22
|
+
keychainAccessible: SecureStore.AFTER_FIRST_UNLOCK,
|
23
|
+
});
|
24
|
+
}
|
25
|
+
|
26
|
+
async clearAll(): Promise<void> {
|
27
|
+
throw new Error("Not implemented");
|
28
|
+
}
|
29
|
+
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
export interface KvStore {
|
2
|
+
get(key: string): Promise<string | null>;
|
3
|
+
set(key: string, value: string): Promise<void>;
|
4
|
+
delete(key: string): Promise<void>;
|
5
|
+
clearAll(): Promise<void>;
|
6
|
+
}
|
7
|
+
|
8
|
+
export class KvStoreContext {
|
9
|
+
private static instance: KvStoreContext;
|
10
|
+
private storageInstance: KvStore | null = null;
|
11
|
+
|
12
|
+
private constructor() {}
|
13
|
+
|
14
|
+
public static getInstance(): KvStoreContext {
|
15
|
+
if (!KvStoreContext.instance) {
|
16
|
+
KvStoreContext.instance = new KvStoreContext();
|
17
|
+
}
|
18
|
+
return KvStoreContext.instance;
|
19
|
+
}
|
20
|
+
|
21
|
+
public initialize(store: KvStore): void {
|
22
|
+
if (!this.storageInstance) {
|
23
|
+
this.storageInstance = store;
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
public getStorage(): KvStore {
|
28
|
+
if (!this.storageInstance) {
|
29
|
+
throw new Error("Storage instance is not initialized.");
|
30
|
+
}
|
31
|
+
return this.storageInstance;
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
export default KvStoreContext;
|
package/.turbo/turbo-build.log
DELETED
package/dist/native-storage.d.ts
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
export interface NativeStorage {
|
2
|
-
get(key: string): Promise<string | undefined>;
|
3
|
-
set(key: string, value: string): Promise<void>;
|
4
|
-
delete(key: string): Promise<void>;
|
5
|
-
clearAll(): Promise<void>;
|
6
|
-
}
|
7
|
-
export declare class NativeStorageContext {
|
8
|
-
private static instance;
|
9
|
-
private storageInstance;
|
10
|
-
private constructor();
|
11
|
-
static getInstance(): NativeStorageContext;
|
12
|
-
initialize(db: NativeStorage): void;
|
13
|
-
getStorage(): NativeStorage;
|
14
|
-
}
|
15
|
-
export default NativeStorageContext;
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"native-storage.js","sourceRoot":"","sources":["../src/native-storage.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,oBAAoB;IACrB,MAAM,CAAC,QAAQ,CAAuB;IACtC,eAAe,GAAyB,IAAI,CAAC;IAErD,gBAAuB,CAAC;IAEjB,MAAM,CAAC,WAAW;QACrB,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,CAAC;YACjC,oBAAoB,CAAC,QAAQ,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC/D,CAAC;QACD,OAAO,oBAAoB,CAAC,QAAQ,CAAC;IACzC,CAAC;IAEM,UAAU,CAAC,EAAiB;QAC/B,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YACxB,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;QAC9B,CAAC;IACL,CAAC;IAEM,UAAU;QACb,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,IAAI,CAAC,eAAe,CAAC;IAChC,CAAC;CACJ;AAED,eAAe,oBAAoB,CAAC"}
|
package/src/native-storage.ts
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
export interface NativeStorage {
|
2
|
-
get(key: string): Promise<string | undefined>;
|
3
|
-
set(key: string, value: string): Promise<void>;
|
4
|
-
delete(key: string): Promise<void>;
|
5
|
-
clearAll(): Promise<void>;
|
6
|
-
}
|
7
|
-
|
8
|
-
export class NativeStorageContext {
|
9
|
-
private static instance: NativeStorageContext;
|
10
|
-
private storageInstance: NativeStorage | null = null;
|
11
|
-
|
12
|
-
private constructor() {}
|
13
|
-
|
14
|
-
public static getInstance(): NativeStorageContext {
|
15
|
-
if (!NativeStorageContext.instance) {
|
16
|
-
NativeStorageContext.instance = new NativeStorageContext();
|
17
|
-
}
|
18
|
-
return NativeStorageContext.instance;
|
19
|
-
}
|
20
|
-
|
21
|
-
public initialize(db: NativeStorage): void {
|
22
|
-
if (!this.storageInstance) {
|
23
|
-
this.storageInstance = db;
|
24
|
-
}
|
25
|
-
}
|
26
|
-
|
27
|
-
public getStorage(): NativeStorage {
|
28
|
-
if (!this.storageInstance) {
|
29
|
-
throw new Error("Storage instance is not initialized.");
|
30
|
-
}
|
31
|
-
return this.storageInstance;
|
32
|
-
}
|
33
|
-
}
|
34
|
-
|
35
|
-
export default NativeStorageContext;
|