@onekeyfe/react-native-async-storage 1.1.55
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/AsyncStorage.podspec +19 -0
- package/ios/AsyncStorage.h +27 -0
- package/ios/AsyncStorage.mm +714 -0
- package/lib/module/NativeAsyncStorage.js +5 -0
- package/lib/module/NativeAsyncStorage.js.map +1 -0
- package/lib/module/index.js +5 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/NativeAsyncStorage.d.ts +12 -0
- package/lib/typescript/src/NativeAsyncStorage.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +4 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/package.json +155 -0
- package/src/NativeAsyncStorage.ts +13 -0
- package/src/index.tsx +4 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = "AsyncStorage"
|
|
7
|
+
s.version = package["version"]
|
|
8
|
+
s.summary = package["description"]
|
|
9
|
+
s.homepage = package["homepage"]
|
|
10
|
+
s.license = package["license"]
|
|
11
|
+
s.authors = package["author"]
|
|
12
|
+
|
|
13
|
+
s.platforms = { :ios => min_ios_version_supported }
|
|
14
|
+
s.source = { :git => "https://github.com/OneKeyHQ/app-modules/react-native-async-storage.git", :tag => "#{s.version}" }
|
|
15
|
+
|
|
16
|
+
s.source_files = "ios/**/*.{h,m,mm}"
|
|
17
|
+
|
|
18
|
+
install_modules_dependencies(s)
|
|
19
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#import <AsyncStorageSpec/AsyncStorageSpec.h>
|
|
2
|
+
|
|
3
|
+
@interface AsyncStorage : NativeRNCAsyncStorageSpecBase <NativeRNCAsyncStorageSpec>
|
|
4
|
+
|
|
5
|
+
- (void)multiGet:(NSArray<NSString *> *)keys
|
|
6
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
7
|
+
reject:(RCTPromiseRejectBlock)reject;
|
|
8
|
+
|
|
9
|
+
- (void)multiSet:(NSArray<NSArray<NSString *> *> *)keyValuePairs
|
|
10
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
11
|
+
reject:(RCTPromiseRejectBlock)reject;
|
|
12
|
+
|
|
13
|
+
- (void)multiRemove:(NSArray<NSString *> *)keys
|
|
14
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
15
|
+
reject:(RCTPromiseRejectBlock)reject;
|
|
16
|
+
|
|
17
|
+
- (void)multiMerge:(NSArray<NSArray<NSString *> *> *)keyValuePairs
|
|
18
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
19
|
+
reject:(RCTPromiseRejectBlock)reject;
|
|
20
|
+
|
|
21
|
+
- (void)getAllKeys:(RCTPromiseResolveBlock)resolve
|
|
22
|
+
reject:(RCTPromiseRejectBlock)reject;
|
|
23
|
+
|
|
24
|
+
- (void)clear:(RCTPromiseResolveBlock)resolve
|
|
25
|
+
reject:(RCTPromiseRejectBlock)reject;
|
|
26
|
+
|
|
27
|
+
@end
|
|
@@ -0,0 +1,714 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* Adapted to a proper TurboModule (no RCT_EXPORT_MODULE / RCT_EXPORT_METHOD)
|
|
8
|
+
* so it works in both the main and background Hermes runtimes.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#import "AsyncStorage.h"
|
|
12
|
+
|
|
13
|
+
#import <React/RCTConvert.h>
|
|
14
|
+
#import <React/RCTLog.h>
|
|
15
|
+
#import <React/RCTUtils.h>
|
|
16
|
+
|
|
17
|
+
static NSString *const RCTStorageDirectory = @"RCTAsyncLocalStorage_V1";
|
|
18
|
+
static NSString *const RCTOldStorageDirectory = @"RNCAsyncLocalStorage_V1";
|
|
19
|
+
static NSString *const RCTExpoStorageDirectory = @"RCTAsyncLocalStorage";
|
|
20
|
+
static NSString *const RCTManifestFileName = @"manifest.json";
|
|
21
|
+
static const NSUInteger RCTInlineValueThreshold = 1024;
|
|
22
|
+
|
|
23
|
+
#pragma mark - Static helper functions
|
|
24
|
+
|
|
25
|
+
static NSDictionary *RCTErrorForKey(NSString *key)
|
|
26
|
+
{
|
|
27
|
+
if (![key isKindOfClass:[NSString class]]) {
|
|
28
|
+
return RCTMakeAndLogError(@"Invalid key - must be a string. Key: ", key, @{@"key": key});
|
|
29
|
+
} else if (key.length < 1) {
|
|
30
|
+
return RCTMakeAndLogError(
|
|
31
|
+
@"Invalid key - must be at least one character. Key: ", key, @{@"key": key});
|
|
32
|
+
} else {
|
|
33
|
+
return nil;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
static BOOL RCTAsyncStorageSetExcludedFromBackup(NSString *path, NSNumber *isExcluded)
|
|
38
|
+
{
|
|
39
|
+
NSFileManager *fileManager = [[NSFileManager alloc] init];
|
|
40
|
+
|
|
41
|
+
BOOL isDir;
|
|
42
|
+
BOOL exists = [fileManager fileExistsAtPath:path isDirectory:&isDir];
|
|
43
|
+
BOOL success = false;
|
|
44
|
+
|
|
45
|
+
if (isDir && exists) {
|
|
46
|
+
NSURL *pathUrl = [NSURL fileURLWithPath:path];
|
|
47
|
+
NSError *error = nil;
|
|
48
|
+
success = [pathUrl setResourceValue:isExcluded
|
|
49
|
+
forKey:NSURLIsExcludedFromBackupKey
|
|
50
|
+
error:&error];
|
|
51
|
+
|
|
52
|
+
if (!success) {
|
|
53
|
+
NSLog(@"Could not exclude AsyncStorage dir from backup %@", error);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return success;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static void RCTAppendError(NSDictionary *error, NSMutableArray<NSDictionary *> **errors)
|
|
60
|
+
{
|
|
61
|
+
if (error && errors) {
|
|
62
|
+
if (!*errors) {
|
|
63
|
+
*errors = [NSMutableArray new];
|
|
64
|
+
}
|
|
65
|
+
[*errors addObject:error];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
static NSString *RCTReadFile(NSString *filePath, NSString *key, NSDictionary **errorOut)
|
|
70
|
+
{
|
|
71
|
+
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
|
|
72
|
+
NSError *error;
|
|
73
|
+
NSStringEncoding encoding;
|
|
74
|
+
NSString *entryString = [NSString stringWithContentsOfFile:filePath
|
|
75
|
+
usedEncoding:&encoding
|
|
76
|
+
error:&error];
|
|
77
|
+
NSDictionary *extraData = @{@"key": RCTNullIfNil(key)};
|
|
78
|
+
|
|
79
|
+
if (error) {
|
|
80
|
+
if (errorOut) {
|
|
81
|
+
*errorOut = RCTMakeError(@"Failed to read storage file.", error, extraData);
|
|
82
|
+
}
|
|
83
|
+
return nil;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (encoding != NSUTF8StringEncoding) {
|
|
87
|
+
if (errorOut) {
|
|
88
|
+
*errorOut =
|
|
89
|
+
RCTMakeError(@"Incorrect encoding of storage file: ", @(encoding), extraData);
|
|
90
|
+
}
|
|
91
|
+
return nil;
|
|
92
|
+
}
|
|
93
|
+
return entryString;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return nil;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
static NSString *RCTCreateStorageDirectoryPath_deprecated(NSString *storageDir)
|
|
100
|
+
{
|
|
101
|
+
NSString *storageDirectoryPath;
|
|
102
|
+
#if TARGET_OS_TV
|
|
103
|
+
storageDirectoryPath =
|
|
104
|
+
NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
|
|
105
|
+
#else
|
|
106
|
+
storageDirectoryPath =
|
|
107
|
+
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
|
|
108
|
+
#endif
|
|
109
|
+
storageDirectoryPath = [storageDirectoryPath stringByAppendingPathComponent:storageDir];
|
|
110
|
+
return storageDirectoryPath;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
static NSString *RCTCreateStorageDirectoryPath(NSString *storageDir)
|
|
114
|
+
{
|
|
115
|
+
NSString *storageDirectoryPath = @"";
|
|
116
|
+
|
|
117
|
+
#if TARGET_OS_TV
|
|
118
|
+
storageDirectoryPath =
|
|
119
|
+
NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
|
|
120
|
+
#else
|
|
121
|
+
storageDirectoryPath =
|
|
122
|
+
NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES)
|
|
123
|
+
.firstObject;
|
|
124
|
+
storageDirectoryPath = [storageDirectoryPath
|
|
125
|
+
stringByAppendingPathComponent:[[NSBundle mainBundle] bundleIdentifier]];
|
|
126
|
+
#endif
|
|
127
|
+
|
|
128
|
+
storageDirectoryPath = [storageDirectoryPath stringByAppendingPathComponent:storageDir];
|
|
129
|
+
|
|
130
|
+
return storageDirectoryPath;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
static NSString *RCTGetStorageDirectory()
|
|
134
|
+
{
|
|
135
|
+
static NSString *storageDirectory = nil;
|
|
136
|
+
static dispatch_once_t onceToken;
|
|
137
|
+
dispatch_once(&onceToken, ^{
|
|
138
|
+
#if TARGET_OS_TV
|
|
139
|
+
RCTLogWarn(
|
|
140
|
+
@"Persistent storage is not supported on tvOS, your data may be removed at any point.");
|
|
141
|
+
#endif
|
|
142
|
+
storageDirectory = RCTCreateStorageDirectoryPath(RCTStorageDirectory);
|
|
143
|
+
});
|
|
144
|
+
return storageDirectory;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
static NSString *RCTCreateManifestFilePath(NSString *storageDirectory)
|
|
148
|
+
{
|
|
149
|
+
return [storageDirectory stringByAppendingPathComponent:RCTManifestFileName];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
static NSString *RCTGetManifestFilePath()
|
|
153
|
+
{
|
|
154
|
+
static NSString *manifestFilePath = nil;
|
|
155
|
+
static dispatch_once_t onceToken;
|
|
156
|
+
dispatch_once(&onceToken, ^{
|
|
157
|
+
manifestFilePath = RCTCreateManifestFilePath(RCTStorageDirectory);
|
|
158
|
+
});
|
|
159
|
+
return manifestFilePath;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Only merges objects - all other types are just clobbered (including arrays)
|
|
163
|
+
static BOOL RCTMergeRecursive(NSMutableDictionary *destination, NSDictionary *source)
|
|
164
|
+
{
|
|
165
|
+
BOOL modified = NO;
|
|
166
|
+
for (NSString *key in source) {
|
|
167
|
+
id sourceValue = source[key];
|
|
168
|
+
id destinationValue = destination[key];
|
|
169
|
+
if ([sourceValue isKindOfClass:[NSDictionary class]]) {
|
|
170
|
+
if ([destinationValue isKindOfClass:[NSDictionary class]]) {
|
|
171
|
+
if ([destinationValue classForCoder] != [NSMutableDictionary class]) {
|
|
172
|
+
destinationValue = [destinationValue mutableCopy];
|
|
173
|
+
}
|
|
174
|
+
if (RCTMergeRecursive(destinationValue, sourceValue)) {
|
|
175
|
+
destination[key] = destinationValue;
|
|
176
|
+
modified = YES;
|
|
177
|
+
}
|
|
178
|
+
} else {
|
|
179
|
+
destination[key] = [sourceValue copy];
|
|
180
|
+
modified = YES;
|
|
181
|
+
}
|
|
182
|
+
} else if (![source isEqual:destinationValue]) {
|
|
183
|
+
destination[key] = [sourceValue copy];
|
|
184
|
+
modified = YES;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return modified;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
static dispatch_queue_t RCTGetMethodQueue()
|
|
191
|
+
{
|
|
192
|
+
// We want all instances to share the same queue since they will be reading/writing the same
|
|
193
|
+
// files.
|
|
194
|
+
static dispatch_queue_t queue;
|
|
195
|
+
static dispatch_once_t onceToken;
|
|
196
|
+
dispatch_once(&onceToken, ^{
|
|
197
|
+
queue =
|
|
198
|
+
dispatch_queue_create("com.facebook.react.AsyncLocalStorageQueue", DISPATCH_QUEUE_SERIAL);
|
|
199
|
+
});
|
|
200
|
+
return queue;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
static NSCache *RCTGetCache()
|
|
204
|
+
{
|
|
205
|
+
// We want all instances to share the same cache since they will be reading/writing the same
|
|
206
|
+
// files.
|
|
207
|
+
static NSCache *cache;
|
|
208
|
+
static dispatch_once_t onceToken;
|
|
209
|
+
dispatch_once(&onceToken, ^{
|
|
210
|
+
cache = [NSCache new];
|
|
211
|
+
cache.totalCostLimit = 2 * 1024 * 1024; // 2MB
|
|
212
|
+
|
|
213
|
+
#if !TARGET_OS_OSX
|
|
214
|
+
// Clear cache in the event of a memory warning
|
|
215
|
+
[[NSNotificationCenter defaultCenter]
|
|
216
|
+
addObserverForName:UIApplicationDidReceiveMemoryWarningNotification
|
|
217
|
+
object:nil
|
|
218
|
+
queue:nil
|
|
219
|
+
usingBlock:^(__unused NSNotification *note) {
|
|
220
|
+
[cache removeAllObjects];
|
|
221
|
+
}];
|
|
222
|
+
#endif // !TARGET_OS_OSX
|
|
223
|
+
});
|
|
224
|
+
return cache;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
static BOOL RCTHasCreatedStorageDirectory = NO;
|
|
228
|
+
|
|
229
|
+
static NSDictionary *RCTDeleteStorageDirectory()
|
|
230
|
+
{
|
|
231
|
+
NSError *error;
|
|
232
|
+
[[NSFileManager defaultManager] removeItemAtPath:RCTGetStorageDirectory() error:&error];
|
|
233
|
+
RCTHasCreatedStorageDirectory = NO;
|
|
234
|
+
if (error && error.code != NSFileNoSuchFileError) {
|
|
235
|
+
return RCTMakeError(@"Failed to delete storage directory.", error, nil);
|
|
236
|
+
}
|
|
237
|
+
return nil;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
static NSDate *RCTManifestModificationDate(NSString *manifestFilePath)
|
|
241
|
+
{
|
|
242
|
+
NSDictionary *attributes =
|
|
243
|
+
[[NSFileManager defaultManager] attributesOfItemAtPath:manifestFilePath error:nil];
|
|
244
|
+
return [attributes fileModificationDate];
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
static void RCTStorageDirectoryMigrationLogError(NSString *reason, NSError *error)
|
|
248
|
+
{
|
|
249
|
+
RCTLogWarn(@"%@: %@", reason, error ? error.description : @"");
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
static void RCTStorageDirectoryCleanupOld(NSString *oldDirectoryPath)
|
|
253
|
+
{
|
|
254
|
+
NSError *error;
|
|
255
|
+
if (![[NSFileManager defaultManager] removeItemAtPath:oldDirectoryPath error:&error]) {
|
|
256
|
+
RCTStorageDirectoryMigrationLogError(
|
|
257
|
+
@"Failed to remove old storage directory during migration", error);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
static void _createStorageDirectory(NSString *storageDirectory, NSError **error)
|
|
262
|
+
{
|
|
263
|
+
[[NSFileManager defaultManager] createDirectoryAtPath:storageDirectory
|
|
264
|
+
withIntermediateDirectories:YES
|
|
265
|
+
attributes:nil
|
|
266
|
+
error:error];
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
static void RCTStorageDirectoryMigrate(NSString *oldDirectoryPath,
|
|
270
|
+
NSString *newDirectoryPath,
|
|
271
|
+
BOOL shouldCleanupOldDirectory)
|
|
272
|
+
{
|
|
273
|
+
NSError *error;
|
|
274
|
+
if (![[NSFileManager defaultManager] copyItemAtPath:oldDirectoryPath
|
|
275
|
+
toPath:newDirectoryPath
|
|
276
|
+
error:&error]) {
|
|
277
|
+
if (error != nil && error.code == 4 &&
|
|
278
|
+
[newDirectoryPath isEqualToString:RCTGetStorageDirectory()]) {
|
|
279
|
+
error = nil;
|
|
280
|
+
_createStorageDirectory(RCTCreateStorageDirectoryPath(@""), &error);
|
|
281
|
+
if (error == nil) {
|
|
282
|
+
RCTStorageDirectoryMigrate(
|
|
283
|
+
oldDirectoryPath, newDirectoryPath, shouldCleanupOldDirectory);
|
|
284
|
+
} else {
|
|
285
|
+
RCTStorageDirectoryMigrationLogError(
|
|
286
|
+
@"Failed to create storage directory during migration.", error);
|
|
287
|
+
}
|
|
288
|
+
} else {
|
|
289
|
+
RCTStorageDirectoryMigrationLogError(
|
|
290
|
+
@"Failed to copy old storage directory to new storage directory location during "
|
|
291
|
+
@"migration",
|
|
292
|
+
error);
|
|
293
|
+
}
|
|
294
|
+
} else if (shouldCleanupOldDirectory) {
|
|
295
|
+
RCTStorageDirectoryCleanupOld(oldDirectoryPath);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
static NSString *RCTGetStoragePathForMigration()
|
|
300
|
+
{
|
|
301
|
+
BOOL isDir;
|
|
302
|
+
NSString *oldStoragePath = RCTCreateStorageDirectoryPath_deprecated(RCTOldStorageDirectory);
|
|
303
|
+
NSString *expoStoragePath = RCTCreateStorageDirectoryPath_deprecated(RCTExpoStorageDirectory);
|
|
304
|
+
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
305
|
+
BOOL oldStorageDirectoryExists =
|
|
306
|
+
[fileManager fileExistsAtPath:oldStoragePath isDirectory:&isDir] && isDir;
|
|
307
|
+
BOOL expoStorageDirectoryExists =
|
|
308
|
+
[fileManager fileExistsAtPath:expoStoragePath isDirectory:&isDir] && isDir;
|
|
309
|
+
|
|
310
|
+
if (oldStorageDirectoryExists && expoStorageDirectoryExists) {
|
|
311
|
+
if ([RCTManifestModificationDate(RCTCreateManifestFilePath(oldStoragePath))
|
|
312
|
+
compare:RCTManifestModificationDate(RCTCreateManifestFilePath(expoStoragePath))] ==
|
|
313
|
+
NSOrderedDescending) {
|
|
314
|
+
RCTStorageDirectoryCleanupOld(expoStoragePath);
|
|
315
|
+
return oldStoragePath;
|
|
316
|
+
} else {
|
|
317
|
+
RCTStorageDirectoryCleanupOld(oldStoragePath);
|
|
318
|
+
return expoStoragePath;
|
|
319
|
+
}
|
|
320
|
+
} else if (oldStorageDirectoryExists) {
|
|
321
|
+
return oldStoragePath;
|
|
322
|
+
} else if (expoStorageDirectoryExists) {
|
|
323
|
+
return expoStoragePath;
|
|
324
|
+
} else {
|
|
325
|
+
return nil;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
static void RCTStorageDirectoryMigrationCheck(NSString *fromStorageDirectory,
|
|
330
|
+
NSString *toStorageDirectory,
|
|
331
|
+
BOOL shouldCleanupOldDirectoryAndOverwriteNewDirectory)
|
|
332
|
+
{
|
|
333
|
+
NSError *error;
|
|
334
|
+
BOOL isDir;
|
|
335
|
+
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
336
|
+
if ([fileManager fileExistsAtPath:fromStorageDirectory isDirectory:&isDir] && isDir) {
|
|
337
|
+
if ([fileManager fileExistsAtPath:toStorageDirectory]) {
|
|
338
|
+
if ([RCTManifestModificationDate(RCTCreateManifestFilePath(toStorageDirectory))
|
|
339
|
+
compare:RCTManifestModificationDate(
|
|
340
|
+
RCTCreateManifestFilePath(fromStorageDirectory))] == 1) {
|
|
341
|
+
if (shouldCleanupOldDirectoryAndOverwriteNewDirectory) {
|
|
342
|
+
RCTStorageDirectoryCleanupOld(fromStorageDirectory);
|
|
343
|
+
}
|
|
344
|
+
} else if (shouldCleanupOldDirectoryAndOverwriteNewDirectory) {
|
|
345
|
+
if (![fileManager removeItemAtPath:toStorageDirectory error:&error]) {
|
|
346
|
+
RCTStorageDirectoryMigrationLogError(
|
|
347
|
+
@"Failed to remove new storage directory during migration", error);
|
|
348
|
+
} else {
|
|
349
|
+
RCTStorageDirectoryMigrate(fromStorageDirectory,
|
|
350
|
+
toStorageDirectory,
|
|
351
|
+
shouldCleanupOldDirectoryAndOverwriteNewDirectory);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
} else {
|
|
355
|
+
RCTStorageDirectoryMigrate(fromStorageDirectory,
|
|
356
|
+
toStorageDirectory,
|
|
357
|
+
shouldCleanupOldDirectoryAndOverwriteNewDirectory);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
#pragma mark - AsyncStorage
|
|
363
|
+
|
|
364
|
+
@implementation AsyncStorage {
|
|
365
|
+
BOOL _haveSetup;
|
|
366
|
+
// The manifest is a dictionary of all keys with small values inlined. Null values indicate
|
|
367
|
+
// values that are stored in separate files (as opposed to nil values which don't exist). The
|
|
368
|
+
// manifest is read off disk at startup, and written to disk after all mutations.
|
|
369
|
+
NSMutableDictionary<NSString *, NSString *> *_manifest;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
+ (NSString *)moduleName
|
|
373
|
+
{
|
|
374
|
+
return @"RNCAsyncStorage";
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
+ (BOOL)requiresMainQueueSetup
|
|
378
|
+
{
|
|
379
|
+
return NO;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
383
|
+
(const facebook::react::ObjCTurboModule::InitParams &)params
|
|
384
|
+
{
|
|
385
|
+
return std::make_shared<facebook::react::NativeRNCAsyncStorageSpecJSI>(params);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
- (instancetype)init
|
|
389
|
+
{
|
|
390
|
+
if (!(self = [super init])) {
|
|
391
|
+
return nil;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
NSString *oldStoragePath = RCTGetStoragePathForMigration();
|
|
395
|
+
if (oldStoragePath != nil) {
|
|
396
|
+
RCTStorageDirectoryMigrationCheck(
|
|
397
|
+
oldStoragePath, RCTCreateStorageDirectoryPath_deprecated(RCTStorageDirectory), YES);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
RCTStorageDirectoryMigrationCheck(RCTCreateStorageDirectoryPath_deprecated(RCTStorageDirectory),
|
|
401
|
+
RCTCreateStorageDirectoryPath(RCTStorageDirectory),
|
|
402
|
+
NO);
|
|
403
|
+
|
|
404
|
+
return self;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
- (NSString *)_filePathForKey:(NSString *)key
|
|
408
|
+
{
|
|
409
|
+
NSString *safeFileName = RCTMD5Hash(key);
|
|
410
|
+
return [RCTGetStorageDirectory() stringByAppendingPathComponent:safeFileName];
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
- (NSDictionary *)_ensureSetup
|
|
414
|
+
{
|
|
415
|
+
NSError *error = nil;
|
|
416
|
+
if (!RCTHasCreatedStorageDirectory) {
|
|
417
|
+
_createStorageDirectory(RCTGetStorageDirectory(), &error);
|
|
418
|
+
if (error) {
|
|
419
|
+
return RCTMakeError(@"Failed to create storage directory.", error, nil);
|
|
420
|
+
}
|
|
421
|
+
RCTHasCreatedStorageDirectory = YES;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
if (!_haveSetup) {
|
|
425
|
+
NSNumber *isExcludedFromBackup =
|
|
426
|
+
[[NSBundle mainBundle] objectForInfoDictionaryKey:@"RCTAsyncStorageExcludeFromBackup"];
|
|
427
|
+
if (isExcludedFromBackup == nil) {
|
|
428
|
+
isExcludedFromBackup = @YES;
|
|
429
|
+
}
|
|
430
|
+
RCTAsyncStorageSetExcludedFromBackup(RCTCreateStorageDirectoryPath(RCTStorageDirectory),
|
|
431
|
+
isExcludedFromBackup);
|
|
432
|
+
|
|
433
|
+
NSDictionary *errorOut = nil;
|
|
434
|
+
NSString *serialized = RCTReadFile(RCTCreateStorageDirectoryPath(RCTGetManifestFilePath()),
|
|
435
|
+
RCTManifestFileName,
|
|
436
|
+
&errorOut);
|
|
437
|
+
if (!serialized) {
|
|
438
|
+
if (errorOut) {
|
|
439
|
+
RCTLogError(
|
|
440
|
+
@"Could not open the existing manifest, perhaps data protection is "
|
|
441
|
+
@"enabled?\n\n%@",
|
|
442
|
+
errorOut);
|
|
443
|
+
return errorOut;
|
|
444
|
+
} else {
|
|
445
|
+
_manifest = [NSMutableDictionary new];
|
|
446
|
+
}
|
|
447
|
+
} else {
|
|
448
|
+
_manifest = RCTJSONParseMutable(serialized, &error);
|
|
449
|
+
if (!_manifest) {
|
|
450
|
+
RCTLogError(@"Failed to parse manifest - creating a new one.\n\n%@", error);
|
|
451
|
+
_manifest = [NSMutableDictionary new];
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
_haveSetup = YES;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
return nil;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
- (NSDictionary *)_writeManifest:(NSMutableArray<NSDictionary *> *__autoreleasing *)errors
|
|
461
|
+
{
|
|
462
|
+
NSError *error;
|
|
463
|
+
NSString *serialized = RCTJSONStringify(_manifest, &error);
|
|
464
|
+
[serialized writeToFile:RCTCreateStorageDirectoryPath(RCTGetManifestFilePath())
|
|
465
|
+
atomically:YES
|
|
466
|
+
encoding:NSUTF8StringEncoding
|
|
467
|
+
error:&error];
|
|
468
|
+
NSDictionary *errorOut;
|
|
469
|
+
if (error) {
|
|
470
|
+
errorOut = RCTMakeError(@"Failed to write manifest file.", error, nil);
|
|
471
|
+
RCTAppendError(errorOut, errors);
|
|
472
|
+
}
|
|
473
|
+
return errorOut;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
- (NSString *)_getValueForKey:(NSString *)key errorOut:(NSDictionary *__autoreleasing *)errorOut
|
|
477
|
+
{
|
|
478
|
+
NSString *value = _manifest[key];
|
|
479
|
+
if (value == (id)kCFNull) {
|
|
480
|
+
value = [RCTGetCache() objectForKey:key];
|
|
481
|
+
if (!value) {
|
|
482
|
+
NSString *filePath = [self _filePathForKey:key];
|
|
483
|
+
value = RCTReadFile(filePath, key, errorOut);
|
|
484
|
+
if (value) {
|
|
485
|
+
[RCTGetCache() setObject:value forKey:key cost:value.length];
|
|
486
|
+
} else {
|
|
487
|
+
[_manifest removeObjectForKey:key];
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
return value;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
- (NSDictionary *)_writeEntry:(NSArray<NSString *> *)entry changedManifest:(BOOL *)changedManifest
|
|
495
|
+
{
|
|
496
|
+
if (entry.count != 2) {
|
|
497
|
+
return RCTMakeAndLogError(
|
|
498
|
+
@"Entries must be arrays of the form [key: string, value: string], got: ", entry, nil);
|
|
499
|
+
}
|
|
500
|
+
NSString *key = entry[0];
|
|
501
|
+
NSDictionary *errorOut = RCTErrorForKey(key);
|
|
502
|
+
if (errorOut) {
|
|
503
|
+
return errorOut;
|
|
504
|
+
}
|
|
505
|
+
NSString *value = entry[1];
|
|
506
|
+
NSString *filePath = [self _filePathForKey:key];
|
|
507
|
+
NSError *error;
|
|
508
|
+
if (value.length <= RCTInlineValueThreshold) {
|
|
509
|
+
if (_manifest[key] == (id)kCFNull) {
|
|
510
|
+
[[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
|
|
511
|
+
[RCTGetCache() removeObjectForKey:key];
|
|
512
|
+
}
|
|
513
|
+
*changedManifest = YES;
|
|
514
|
+
_manifest[key] = value;
|
|
515
|
+
return nil;
|
|
516
|
+
}
|
|
517
|
+
[value writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error];
|
|
518
|
+
[RCTGetCache() setObject:value forKey:key cost:value.length];
|
|
519
|
+
if (error) {
|
|
520
|
+
errorOut = RCTMakeError(@"Failed to write value.", error, @{@"key": key});
|
|
521
|
+
} else if (_manifest[key] != (id)kCFNull) {
|
|
522
|
+
*changedManifest = YES;
|
|
523
|
+
_manifest[key] = (id)kCFNull;
|
|
524
|
+
}
|
|
525
|
+
return errorOut;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
#pragma mark - TurboModule methods
|
|
529
|
+
|
|
530
|
+
- (void)multiGet:(NSArray<NSString *> *)keys
|
|
531
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
532
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
533
|
+
{
|
|
534
|
+
dispatch_async(RCTGetMethodQueue(), ^{
|
|
535
|
+
NSDictionary *ensureSetupError = [self _ensureSetup];
|
|
536
|
+
if (ensureSetupError) {
|
|
537
|
+
reject(@"ASYNC_STORAGE_ERROR",
|
|
538
|
+
ensureSetupError[@"message"] ?: @"Storage setup failed",
|
|
539
|
+
nil);
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
NSMutableArray<NSArray *> *result = [NSMutableArray arrayWithCapacity:keys.count];
|
|
544
|
+
for (NSString *key in keys) {
|
|
545
|
+
NSDictionary *keyError = RCTErrorForKey(key);
|
|
546
|
+
if (keyError) {
|
|
547
|
+
[result addObject:@[RCTNullIfNil(key), (id)kCFNull]];
|
|
548
|
+
} else {
|
|
549
|
+
NSDictionary *errorOut = nil;
|
|
550
|
+
NSString *value = [self _getValueForKey:key errorOut:&errorOut];
|
|
551
|
+
[result addObject:@[key, RCTNullIfNil(value)]];
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
resolve(result);
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
- (void)multiSet:(NSArray<NSArray<NSString *> *> *)keyValuePairs
|
|
559
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
560
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
561
|
+
{
|
|
562
|
+
dispatch_async(RCTGetMethodQueue(), ^{
|
|
563
|
+
NSDictionary *ensureSetupError = [self _ensureSetup];
|
|
564
|
+
if (ensureSetupError) {
|
|
565
|
+
reject(@"ASYNC_STORAGE_ERROR",
|
|
566
|
+
ensureSetupError[@"message"] ?: @"Storage setup failed",
|
|
567
|
+
nil);
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
BOOL changedManifest = NO;
|
|
572
|
+
NSMutableArray<NSDictionary *> *errors;
|
|
573
|
+
for (NSArray<NSString *> *entry in keyValuePairs) {
|
|
574
|
+
NSDictionary *keyError = [self _writeEntry:entry changedManifest:&changedManifest];
|
|
575
|
+
RCTAppendError(keyError, &errors);
|
|
576
|
+
}
|
|
577
|
+
if (changedManifest) {
|
|
578
|
+
[self _writeManifest:&errors];
|
|
579
|
+
}
|
|
580
|
+
if (errors.count > 0) {
|
|
581
|
+
reject(@"ASYNC_STORAGE_ERROR",
|
|
582
|
+
@"One or more keys failed to set",
|
|
583
|
+
nil);
|
|
584
|
+
} else {
|
|
585
|
+
resolve(nil);
|
|
586
|
+
}
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
- (void)multiRemove:(NSArray<NSString *> *)keys
|
|
591
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
592
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
593
|
+
{
|
|
594
|
+
dispatch_async(RCTGetMethodQueue(), ^{
|
|
595
|
+
NSDictionary *ensureSetupError = [self _ensureSetup];
|
|
596
|
+
if (ensureSetupError) {
|
|
597
|
+
reject(@"ASYNC_STORAGE_ERROR",
|
|
598
|
+
ensureSetupError[@"message"] ?: @"Storage setup failed",
|
|
599
|
+
nil);
|
|
600
|
+
return;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
NSMutableArray<NSDictionary *> *errors;
|
|
604
|
+
BOOL changedManifest = NO;
|
|
605
|
+
for (NSString *key in keys) {
|
|
606
|
+
NSDictionary *keyError = RCTErrorForKey(key);
|
|
607
|
+
if (!keyError) {
|
|
608
|
+
if (self->_manifest[key] == (id)kCFNull) {
|
|
609
|
+
NSString *filePath = [self _filePathForKey:key];
|
|
610
|
+
[[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
|
|
611
|
+
[RCTGetCache() removeObjectForKey:key];
|
|
612
|
+
}
|
|
613
|
+
if (self->_manifest[key]) {
|
|
614
|
+
changedManifest = YES;
|
|
615
|
+
[self->_manifest removeObjectForKey:key];
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
RCTAppendError(keyError, &errors);
|
|
619
|
+
}
|
|
620
|
+
if (changedManifest) {
|
|
621
|
+
[self _writeManifest:&errors];
|
|
622
|
+
}
|
|
623
|
+
if (errors.count > 0) {
|
|
624
|
+
reject(@"ASYNC_STORAGE_ERROR",
|
|
625
|
+
@"One or more keys failed to remove",
|
|
626
|
+
nil);
|
|
627
|
+
} else {
|
|
628
|
+
resolve(nil);
|
|
629
|
+
}
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
- (void)multiMerge:(NSArray<NSArray<NSString *> *> *)keyValuePairs
|
|
634
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
635
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
636
|
+
{
|
|
637
|
+
dispatch_async(RCTGetMethodQueue(), ^{
|
|
638
|
+
NSDictionary *ensureSetupError = [self _ensureSetup];
|
|
639
|
+
if (ensureSetupError) {
|
|
640
|
+
reject(@"ASYNC_STORAGE_ERROR",
|
|
641
|
+
ensureSetupError[@"message"] ?: @"Storage setup failed",
|
|
642
|
+
nil);
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
BOOL changedManifest = NO;
|
|
647
|
+
NSMutableArray<NSDictionary *> *errors;
|
|
648
|
+
for (__strong NSArray<NSString *> *entry in keyValuePairs) {
|
|
649
|
+
NSDictionary *keyError;
|
|
650
|
+
NSString *value = [self _getValueForKey:entry[0] errorOut:&keyError];
|
|
651
|
+
if (!keyError) {
|
|
652
|
+
if (value) {
|
|
653
|
+
NSError *jsonError;
|
|
654
|
+
NSMutableDictionary *mergedVal = RCTJSONParseMutable(value, &jsonError);
|
|
655
|
+
NSDictionary *mergingValue = RCTJSONParse(entry[1], &jsonError);
|
|
656
|
+
if (!mergingValue.count || RCTMergeRecursive(mergedVal, mergingValue)) {
|
|
657
|
+
entry = @[entry[0], RCTNullIfNil(RCTJSONStringify(mergedVal, NULL))];
|
|
658
|
+
}
|
|
659
|
+
if (jsonError) {
|
|
660
|
+
keyError = RCTJSErrorFromNSError(jsonError);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
if (!keyError) {
|
|
664
|
+
keyError = [self _writeEntry:entry changedManifest:&changedManifest];
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
RCTAppendError(keyError, &errors);
|
|
668
|
+
}
|
|
669
|
+
if (changedManifest) {
|
|
670
|
+
[self _writeManifest:&errors];
|
|
671
|
+
}
|
|
672
|
+
if (errors.count > 0) {
|
|
673
|
+
reject(@"ASYNC_STORAGE_ERROR",
|
|
674
|
+
@"One or more keys failed to merge",
|
|
675
|
+
nil);
|
|
676
|
+
} else {
|
|
677
|
+
resolve(nil);
|
|
678
|
+
}
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
- (void)getAllKeys:(RCTPromiseResolveBlock)resolve
|
|
683
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
684
|
+
{
|
|
685
|
+
dispatch_async(RCTGetMethodQueue(), ^{
|
|
686
|
+
NSDictionary *ensureSetupError = [self _ensureSetup];
|
|
687
|
+
if (ensureSetupError) {
|
|
688
|
+
reject(@"ASYNC_STORAGE_ERROR",
|
|
689
|
+
ensureSetupError[@"message"] ?: @"Storage setup failed",
|
|
690
|
+
nil);
|
|
691
|
+
return;
|
|
692
|
+
}
|
|
693
|
+
resolve(self->_manifest.allKeys);
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
- (void)clear:(RCTPromiseResolveBlock)resolve
|
|
698
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
699
|
+
{
|
|
700
|
+
dispatch_async(RCTGetMethodQueue(), ^{
|
|
701
|
+
[self->_manifest removeAllObjects];
|
|
702
|
+
[RCTGetCache() removeAllObjects];
|
|
703
|
+
NSDictionary *error = RCTDeleteStorageDirectory();
|
|
704
|
+
if (error) {
|
|
705
|
+
reject(@"ASYNC_STORAGE_ERROR",
|
|
706
|
+
error[@"message"] ?: @"Failed to clear storage",
|
|
707
|
+
nil);
|
|
708
|
+
} else {
|
|
709
|
+
resolve(nil);
|
|
710
|
+
}
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
@end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeAsyncStorage.ts"],"mappings":";;AAAA,SAASA,mBAAmB,QAAQ,cAAc;AAYlD,eAAeA,mBAAmB,CAACC,YAAY,CAAO,iBAAiB,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["NativeAsyncStorage"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAOA,kBAAkB,MAAM,yBAAsB;AAErD,eAAeA,kBAAkB","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { TurboModule } from 'react-native';
|
|
2
|
+
export interface Spec extends TurboModule {
|
|
3
|
+
multiGet(keys: string[]): Promise<[string, string | null][]>;
|
|
4
|
+
multiSet(keyValuePairs: [string, string][]): Promise<void>;
|
|
5
|
+
multiRemove(keys: string[]): Promise<void>;
|
|
6
|
+
multiMerge(keyValuePairs: [string, string][]): Promise<void>;
|
|
7
|
+
getAllKeys(): Promise<string[]>;
|
|
8
|
+
clear(): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
declare const _default: Spec;
|
|
11
|
+
export default _default;
|
|
12
|
+
//# sourceMappingURL=NativeAsyncStorage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NativeAsyncStorage.d.ts","sourceRoot":"","sources":["../../../src/NativeAsyncStorage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7D,QAAQ,CAAC,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,UAAU,CAAC,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAChC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;;AAED,wBAAyE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AAEtD,eAAe,kBAAkB,CAAC;AAClC,YAAY,EAAE,IAAI,IAAI,gBAAgB,EAAE,MAAM,sBAAsB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@onekeyfe/react-native-async-storage",
|
|
3
|
+
"version": "1.1.55",
|
|
4
|
+
"description": "react-native-async-storage",
|
|
5
|
+
"main": "./lib/module/index.js",
|
|
6
|
+
"types": "./lib/typescript/src/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"source": "./src/index.tsx",
|
|
10
|
+
"types": "./lib/typescript/src/index.d.ts",
|
|
11
|
+
"default": "./lib/module/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./package.json": "./package.json"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"src",
|
|
17
|
+
"lib",
|
|
18
|
+
"ios",
|
|
19
|
+
"*.podspec",
|
|
20
|
+
"!ios/build",
|
|
21
|
+
"!**/__tests__",
|
|
22
|
+
"!**/__fixtures__",
|
|
23
|
+
"!**/__mocks__",
|
|
24
|
+
"!**/.*"
|
|
25
|
+
],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"clean": "del-cli ios/build lib",
|
|
28
|
+
"prepare": "bob build",
|
|
29
|
+
"typecheck": "tsc",
|
|
30
|
+
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
31
|
+
"test": "jest",
|
|
32
|
+
"release": "yarn prepare && npm whoami && npm publish --access public"
|
|
33
|
+
},
|
|
34
|
+
"keywords": [
|
|
35
|
+
"react-native",
|
|
36
|
+
"ios",
|
|
37
|
+
"async-storage"
|
|
38
|
+
],
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "git+https://github.com/OneKeyHQ/app-modules/react-native-async-storage.git"
|
|
42
|
+
},
|
|
43
|
+
"author": "@onekeyhq <huanming@onekey.so> (https://github.com/OneKeyHQ/app-modules)",
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"bugs": {
|
|
46
|
+
"url": "https://github.com/OneKeyHQ/app-modules/react-native-async-storage/issues"
|
|
47
|
+
},
|
|
48
|
+
"homepage": "https://github.com/OneKeyHQ/app-modules/react-native-async-storage#readme",
|
|
49
|
+
"publishConfig": {
|
|
50
|
+
"registry": "https://registry.npmjs.org/"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@commitlint/config-conventional": "^19.8.1",
|
|
54
|
+
"@eslint/compat": "^1.3.2",
|
|
55
|
+
"@eslint/eslintrc": "^3.3.1",
|
|
56
|
+
"@eslint/js": "^9.35.0",
|
|
57
|
+
"@react-native/babel-preset": "0.83.0",
|
|
58
|
+
"@react-native/eslint-config": "0.83.0",
|
|
59
|
+
"@release-it/conventional-changelog": "^10.0.1",
|
|
60
|
+
"@types/jest": "^29.5.14",
|
|
61
|
+
"@types/react": "^19.2.0",
|
|
62
|
+
"commitlint": "^19.8.1",
|
|
63
|
+
"del-cli": "^6.0.0",
|
|
64
|
+
"eslint": "^9.35.0",
|
|
65
|
+
"eslint-config-prettier": "^10.1.8",
|
|
66
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
67
|
+
"jest": "^29.7.0",
|
|
68
|
+
"lefthook": "^2.0.3",
|
|
69
|
+
"prettier": "^2.8.8",
|
|
70
|
+
"react": "19.2.0",
|
|
71
|
+
"react-native": "patch:react-native@npm%3A0.83.0#~/.yarn/patches/react-native-npm-0.83.0-577d0f2d83.patch",
|
|
72
|
+
"react-native-builder-bob": "^0.40.17",
|
|
73
|
+
"release-it": "^19.0.4",
|
|
74
|
+
"turbo": "^2.5.6",
|
|
75
|
+
"typescript": "^5.9.2"
|
|
76
|
+
},
|
|
77
|
+
"peerDependencies": {
|
|
78
|
+
"react": "*",
|
|
79
|
+
"react-native": "*"
|
|
80
|
+
},
|
|
81
|
+
"react-native-builder-bob": {
|
|
82
|
+
"source": "src",
|
|
83
|
+
"output": "lib",
|
|
84
|
+
"targets": [
|
|
85
|
+
[
|
|
86
|
+
"module",
|
|
87
|
+
{
|
|
88
|
+
"esm": true
|
|
89
|
+
}
|
|
90
|
+
],
|
|
91
|
+
[
|
|
92
|
+
"typescript",
|
|
93
|
+
{
|
|
94
|
+
"project": "tsconfig.build.json"
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
]
|
|
98
|
+
},
|
|
99
|
+
"codegenConfig": {
|
|
100
|
+
"name": "AsyncStorageSpec",
|
|
101
|
+
"type": "modules",
|
|
102
|
+
"jsSrcsDir": "src",
|
|
103
|
+
"android": {
|
|
104
|
+
"javaPackageName": "com.asyncstorage"
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
"prettier": {
|
|
108
|
+
"quoteProps": "consistent",
|
|
109
|
+
"singleQuote": true,
|
|
110
|
+
"tabWidth": 2,
|
|
111
|
+
"trailingComma": "es5",
|
|
112
|
+
"useTabs": false
|
|
113
|
+
},
|
|
114
|
+
"jest": {
|
|
115
|
+
"preset": "react-native",
|
|
116
|
+
"modulePathIgnorePatterns": [
|
|
117
|
+
"<rootDir>/lib/"
|
|
118
|
+
]
|
|
119
|
+
},
|
|
120
|
+
"commitlint": {
|
|
121
|
+
"extends": [
|
|
122
|
+
"@commitlint/config-conventional"
|
|
123
|
+
]
|
|
124
|
+
},
|
|
125
|
+
"release-it": {
|
|
126
|
+
"git": {
|
|
127
|
+
"commitMessage": "chore: release ${version}",
|
|
128
|
+
"tagName": "v${version}"
|
|
129
|
+
},
|
|
130
|
+
"npm": {
|
|
131
|
+
"publish": true
|
|
132
|
+
},
|
|
133
|
+
"github": {
|
|
134
|
+
"release": true
|
|
135
|
+
},
|
|
136
|
+
"plugins": {
|
|
137
|
+
"@release-it/conventional-changelog": {
|
|
138
|
+
"preset": {
|
|
139
|
+
"name": "angular"
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
"create-react-native-library": {
|
|
145
|
+
"type": "turbo-module",
|
|
146
|
+
"languages": "kotlin-objc",
|
|
147
|
+
"tools": [
|
|
148
|
+
"eslint",
|
|
149
|
+
"jest",
|
|
150
|
+
"lefthook",
|
|
151
|
+
"release-it"
|
|
152
|
+
],
|
|
153
|
+
"version": "0.56.0"
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { TurboModuleRegistry } from 'react-native';
|
|
2
|
+
import type { TurboModule } from 'react-native';
|
|
3
|
+
|
|
4
|
+
export interface Spec extends TurboModule {
|
|
5
|
+
multiGet(keys: string[]): Promise<[string, string | null][]>;
|
|
6
|
+
multiSet(keyValuePairs: [string, string][]): Promise<void>;
|
|
7
|
+
multiRemove(keys: string[]): Promise<void>;
|
|
8
|
+
multiMerge(keyValuePairs: [string, string][]): Promise<void>;
|
|
9
|
+
getAllKeys(): Promise<string[]>;
|
|
10
|
+
clear(): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default TurboModuleRegistry.getEnforcing<Spec>('RNCAsyncStorage');
|
package/src/index.tsx
ADDED