Skip to content

Commit be2473b

Browse files
committed
async-storage(windows): start with windows implementation
1 parent 1e96464 commit be2473b

File tree

7 files changed

+157
-8
lines changed

7 files changed

+157
-8
lines changed

examples/example-react-native/app.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,6 @@
2020
"dist/assets",
2121
"dist/main.macos.jsbundle"
2222
],
23-
"visionos": [
24-
"dist/assets",
25-
"dist/main.visionos.jsbundle"
26-
],
2723
"windows": [
2824
"dist/assets",
2925
"dist/main.windows.bundle"

examples/example-react-native/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
"scripts": {
66
"android": "react-native run-android",
77
"ios": "react-native run-ios",
8-
"windows": "react-native run-windows",
8+
"windows": "install-windows-test-app && react-native run-windows",
9+
"macos": "react-native run-macos",
910
"build:android": "yarn mkdist && react-native bundle --entry-file index.js --platform android --dev true --bundle-output dist/main.android.jsbundle --assets-dest dist/res",
1011
"build:ios": "yarn mkdist && react-native bundle --entry-file index.js --platform ios --dev true --bundle-output dist/main.ios.jsbundle --assets-dest dist",
1112
"build:windows": "yarn mkdist && react-native bundle --entry-file index.js --platform windows --dev true --bundle-output dist/main.windows.bundle --assets-dest dist",
13+
"build:macos": "yarn mkdist && react-native bundle --entry-file index.js --platform macos --dev true --bundle-output dist/main.macos.bundle --assets-dest dist",
1214
"test:lint": "eslint .",
1315
"test:ts": "tsc --noEmit",
1416
"mkdist": "node -e \"require('node:fs').mkdirSync('dist', { recursive: true, mode: 0o755 })\"",

examples/example-react-native/react-native.config.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@ const project = (() => {
88
ios: {
99
sourceDir: "ios",
1010
},
11+
macos: {
12+
sourceDir: "macos",
13+
},
1114
windows: {
1215
sourceDir: "windows",
13-
solutionFile: "windows/Example.sln",
16+
solutionFile: "Example.sln",
1417
},
1518
});
1619
} catch (_) {

packages/async-storage/src/AsyncStorageError.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ enum AsyncStorageErrorType {
1818

1919
/**
2020
* Other errors related to Native Shared Storage or Legacy Storage exception.
21-
* ex. Storage could not be initialized
21+
* ex. Storage could not be initialized or wrongly formatted output is generated
2222
*/
2323
OtherStorageError = "OtherStorageError",
2424

packages/async-storage/src/createAsyncStorage.native.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ class LegacyAsyncStorageImpl implements AsyncStorage {
114114
const mod = NativeAsyncStorage;
115115
if (!mod) {
116116
throw AsyncStorageError.jsError(
117-
`Native module is null, access legacy storage`,
117+
`Native module is null, cannot access legacy storage`,
118118
AsyncStorageError.Type.NativeModuleError
119119
);
120120
}
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
import type { AsyncStorage } from "./AsyncStorage";
2+
import { AsyncStorageError } from "./AsyncStorageError";
3+
import { TurboModuleRegistry, type TurboModule } from "react-native";
4+
5+
/**
6+
* Because of missing support for Windows native target by Room KMP,
7+
* Windows target uses v2 implementation of AsyncStorage.
8+
*/
9+
export function createAsyncStorage(_: string): AsyncStorage {
10+
return getLegacyStorage();
11+
}
12+
13+
export function getLegacyStorage(): AsyncStorage {
14+
return LegacyAsyncStorageImpl.instance;
15+
}
16+
17+
class LegacyAsyncStorageImpl implements AsyncStorage {
18+
private constructor() {}
19+
20+
static instance = new LegacyAsyncStorageImpl();
21+
22+
private get db(): NativeAsyncStorageSpec {
23+
const mod = RNCAsyncStorage;
24+
if (!mod) {
25+
throw AsyncStorageError.jsError(
26+
`Native module is null, cannot access storage.`,
27+
AsyncStorageError.Type.NativeModuleError
28+
);
29+
}
30+
return mod;
31+
}
32+
33+
getItem = async (key: string): Promise<string | null> => {
34+
try {
35+
return await new Promise((resolve, reject) => {
36+
this.db.multiGet([key], (errors, result) => {
37+
if (errors?.length) {
38+
const error = errors[0]!;
39+
reject(
40+
AsyncStorageError.jsError(
41+
error.message,
42+
AsyncStorageError.Type.OtherStorageError
43+
)
44+
);
45+
} else {
46+
resolve(result?.[0]?.[1] ?? null);
47+
}
48+
});
49+
});
50+
} catch (e) {
51+
throw AsyncStorageError.nativeError(e);
52+
}
53+
};
54+
55+
setItem = async (key: string, value: string): Promise<void> => {
56+
try {
57+
throw new Error("todo");
58+
} catch (e) {
59+
throw AsyncStorageError.nativeError(e);
60+
}
61+
};
62+
63+
removeItem = async (key: string): Promise<void> => {
64+
try {
65+
throw new Error("todo");
66+
} catch (e) {
67+
throw AsyncStorageError.nativeError(e);
68+
}
69+
};
70+
71+
getMany = async (keys: string[]): Promise<Record<string, string | null>> => {
72+
try {
73+
throw new Error("todo");
74+
} catch (e) {
75+
throw AsyncStorageError.nativeError(e);
76+
}
77+
};
78+
79+
setMany = async (entries: Record<string, string>): Promise<void> => {
80+
try {
81+
throw new Error("todo");
82+
} catch (e) {
83+
throw AsyncStorageError.nativeError(e);
84+
}
85+
};
86+
87+
removeMany = async (keys: string[]): Promise<void> => {
88+
try {
89+
throw new Error("todo");
90+
} catch (e) {
91+
throw AsyncStorageError.nativeError(e);
92+
}
93+
};
94+
95+
getAllKeys = async (): Promise<string[]> => {
96+
try {
97+
throw new Error("todo");
98+
} catch (e) {
99+
throw AsyncStorageError.nativeError(e);
100+
}
101+
};
102+
103+
clear = async (): Promise<void> => {
104+
try {
105+
throw new Error("todo");
106+
} catch (e) {
107+
throw AsyncStorageError.nativeError(e);
108+
}
109+
};
110+
}
111+
112+
/**
113+
*
114+
* This is a backward compatibility layer, to support Windows target in v3.
115+
* Room KMP does not support Windows native target currently, so shared-storage cannot be used.
116+
* https://issuetracker.google.com/issues/363195546
117+
*/
118+
const RNCAsyncStorage =
119+
TurboModuleRegistry.get<NativeAsyncStorageSpec>("RNCAsyncStorage");
120+
121+
type ErrorLike = {
122+
message: string;
123+
key?: string;
124+
};
125+
126+
interface NativeAsyncStorageSpec extends TurboModule {
127+
multiGet: (
128+
keys: string[],
129+
callback: (error?: ErrorLike[], result?: [string, string][]) => void
130+
) => void;
131+
multiSet: (
132+
kvPairs: [string, string][],
133+
callback: (error?: ErrorLike[]) => void
134+
) => void;
135+
multiRemove: (
136+
keys: readonly string[],
137+
callback: (error?: ErrorLike[]) => void
138+
) => void;
139+
multiMerge: (
140+
kvPairs: [string, string][],
141+
callback: (error?: ErrorLike[]) => void
142+
) => void;
143+
getAllKeys: (
144+
callback: (error?: ErrorLike[], result?: [string, string][]) => void
145+
) => void;
146+
clear: (callback: (error?: ErrorLike[]) => void) => void;
147+
}

packages/async-storage/windows/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,4 @@ Ankh.NoLoad
3939

4040
#Files generated by the VS build
4141
**/Generated Files/**
42+
ReactNativeAsyncStorage/packages.json.lock

0 commit comments

Comments
 (0)