react-native-nitro-storage 0.5.7 → 0.5.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/lib/commonjs/index.js +119 -1599
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +83 -1550
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/commonjs/shared.js +102 -0
- package/lib/commonjs/shared.js.map +1 -0
- package/lib/commonjs/storage-core.js +1505 -0
- package/lib/commonjs/storage-core.js.map +1 -0
- package/lib/module/index.js +111 -1591
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +69 -1536
- package/lib/module/index.web.js.map +1 -1
- package/lib/module/shared.js +82 -0
- package/lib/module/shared.js.map +1 -0
- package/lib/module/storage-core.js +1501 -0
- package/lib/module/storage-core.js.map +1 -0
- package/lib/typescript/index.d.ts +30 -133
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/index.web.d.ts +30 -133
- package/lib/typescript/index.web.d.ts.map +1 -1
- package/lib/typescript/shared.d.ts +96 -0
- package/lib/typescript/shared.d.ts.map +1 -0
- package/lib/typescript/storage-core.d.ts +157 -0
- package/lib/typescript/storage-core.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/index.ts +260 -2519
- package/src/index.web.ts +132 -2331
- package/src/shared.ts +249 -0
- package/src/storage-core.ts +2349 -0
package/src/shared.ts
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { StorageScope, AccessControl, BiometricLevel } from "./Storage.types";
|
|
2
|
+
import {
|
|
3
|
+
serializeWithPrimitiveFastPath,
|
|
4
|
+
deserializeWithPrimitiveFastPath,
|
|
5
|
+
} from "./internal";
|
|
6
|
+
import {
|
|
7
|
+
getStorageErrorCode,
|
|
8
|
+
isLockedStorageErrorCode,
|
|
9
|
+
} from "./storage-runtime";
|
|
10
|
+
import type {
|
|
11
|
+
StorageChangeOperation,
|
|
12
|
+
StorageChangeSource,
|
|
13
|
+
StorageKeyChangeEvent,
|
|
14
|
+
} from "./storage-events";
|
|
15
|
+
|
|
16
|
+
export type Validator<T> = (value: unknown) => value is T;
|
|
17
|
+
|
|
18
|
+
export type ExpirationConfig = {
|
|
19
|
+
ttlMs: number;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export type StorageVersion = string;
|
|
23
|
+
|
|
24
|
+
export type VersionedValue<T> = {
|
|
25
|
+
value: T;
|
|
26
|
+
version: StorageVersion;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type StorageMetricsEvent = {
|
|
30
|
+
operation: string;
|
|
31
|
+
scope: StorageScope;
|
|
32
|
+
durationMs: number;
|
|
33
|
+
keysCount: number;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export type StorageMetricsObserver = (event: StorageMetricsEvent) => void;
|
|
37
|
+
|
|
38
|
+
export type StorageEventObserverOptions = {
|
|
39
|
+
redactSecureValues?: boolean;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export type StorageExportOptions = {
|
|
43
|
+
includeSecureValues?: boolean;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export type StorageMetricSummary = {
|
|
47
|
+
count: number;
|
|
48
|
+
totalDurationMs: number;
|
|
49
|
+
avgDurationMs: number;
|
|
50
|
+
maxDurationMs: number;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export type StorageSelectorListener<TSelected> = (
|
|
54
|
+
value: TSelected,
|
|
55
|
+
previousValue: TSelected,
|
|
56
|
+
) => void;
|
|
57
|
+
|
|
58
|
+
export type StorageSelectorSubscribeOptions<TSelected> = {
|
|
59
|
+
isEqual?: (previousValue: TSelected, nextValue: TSelected) => boolean;
|
|
60
|
+
fireImmediately?: boolean;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export type MigrationContext = {
|
|
64
|
+
scope: StorageScope;
|
|
65
|
+
getRaw: (key: string) => string | undefined;
|
|
66
|
+
setRaw: (key: string, value: string) => void;
|
|
67
|
+
removeRaw: (key: string) => void;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export type Migration = (context: MigrationContext) => void;
|
|
71
|
+
|
|
72
|
+
export type KeyListenerRegistry = Map<string, Set<() => void>>;
|
|
73
|
+
|
|
74
|
+
export type RawBatchPathItem = {
|
|
75
|
+
_hasValidation?: boolean;
|
|
76
|
+
_hasExpiration?: boolean;
|
|
77
|
+
_isBiometric?: boolean;
|
|
78
|
+
_biometricLevel?: BiometricLevel;
|
|
79
|
+
_secureAccessControl?: AccessControl;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export type RollbackRecord =
|
|
83
|
+
| {
|
|
84
|
+
kind: "memory";
|
|
85
|
+
value: unknown;
|
|
86
|
+
}
|
|
87
|
+
| {
|
|
88
|
+
kind: "raw";
|
|
89
|
+
value: string | undefined;
|
|
90
|
+
accessControl?: AccessControl;
|
|
91
|
+
}
|
|
92
|
+
| {
|
|
93
|
+
kind: "biometric";
|
|
94
|
+
value: string | undefined;
|
|
95
|
+
level: BiometricLevel;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export function isUpdater<T>(
|
|
99
|
+
valueOrFn: T | ((prev: T) => T),
|
|
100
|
+
): valueOrFn is (prev: T) => T {
|
|
101
|
+
return typeof valueOrFn === "function";
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function typedKeys<K extends string, V>(record: Record<K, V>): K[] {
|
|
105
|
+
return Object.keys(record) as K[];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function assertEnumInteger(
|
|
109
|
+
value: number,
|
|
110
|
+
min: number,
|
|
111
|
+
max: number,
|
|
112
|
+
label: string,
|
|
113
|
+
): void {
|
|
114
|
+
if (!Number.isFinite(value) || value < min || value > max) {
|
|
115
|
+
throw new Error(`NitroStorage: Invalid ${label}`);
|
|
116
|
+
}
|
|
117
|
+
if (value !== Math.trunc(value)) {
|
|
118
|
+
throw new Error(`NitroStorage: Invalid ${label}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function assertAccessControlLevel(level: number): void {
|
|
123
|
+
assertEnumInteger(level, 0, 4, "access control level");
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function assertBiometricLevel(level: number): void {
|
|
127
|
+
assertEnumInteger(level, 0, 2, "biometric level");
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export type NonMemoryScope = StorageScope.Disk | StorageScope.Secure;
|
|
131
|
+
|
|
132
|
+
export type PendingDiskWrite = {
|
|
133
|
+
key: string;
|
|
134
|
+
value: string | undefined;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export type PendingSecureWrite = {
|
|
138
|
+
key: string;
|
|
139
|
+
value: string | undefined;
|
|
140
|
+
accessControl?: AccessControl;
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
export const runMicrotask =
|
|
144
|
+
typeof queueMicrotask === "function"
|
|
145
|
+
? queueMicrotask
|
|
146
|
+
: (task: () => void) => {
|
|
147
|
+
Promise.resolve().then(task);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
export const now =
|
|
151
|
+
typeof performance !== "undefined" && typeof performance.now === "function"
|
|
152
|
+
? () => performance.now()
|
|
153
|
+
: () => Date.now();
|
|
154
|
+
|
|
155
|
+
export function notifyKeyListeners(
|
|
156
|
+
registry: KeyListenerRegistry,
|
|
157
|
+
key: string,
|
|
158
|
+
): void {
|
|
159
|
+
const listeners = registry.get(key);
|
|
160
|
+
if (listeners) {
|
|
161
|
+
for (const listener of listeners) {
|
|
162
|
+
listener();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export function notifyAllListeners(registry: KeyListenerRegistry): void {
|
|
168
|
+
for (const listeners of registry.values()) {
|
|
169
|
+
for (const listener of listeners) {
|
|
170
|
+
listener();
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export function createKeyChange(
|
|
176
|
+
scope: StorageScope,
|
|
177
|
+
key: string,
|
|
178
|
+
oldValue: string | undefined,
|
|
179
|
+
newValue: string | undefined,
|
|
180
|
+
operation: StorageChangeOperation,
|
|
181
|
+
source: StorageChangeSource,
|
|
182
|
+
): StorageKeyChangeEvent {
|
|
183
|
+
return {
|
|
184
|
+
type: "key",
|
|
185
|
+
scope,
|
|
186
|
+
key,
|
|
187
|
+
oldValue,
|
|
188
|
+
newValue,
|
|
189
|
+
operation,
|
|
190
|
+
source,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export const SECURE_EVENT_REDACTED_VALUE = "[secure]";
|
|
195
|
+
|
|
196
|
+
export function redactSecureKeyChange(
|
|
197
|
+
event: StorageKeyChangeEvent,
|
|
198
|
+
): StorageKeyChangeEvent {
|
|
199
|
+
if (event.scope !== StorageScope.Secure) {
|
|
200
|
+
return event;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return {
|
|
204
|
+
...event,
|
|
205
|
+
oldValue:
|
|
206
|
+
event.oldValue === undefined ? undefined : SECURE_EVENT_REDACTED_VALUE,
|
|
207
|
+
newValue:
|
|
208
|
+
event.newValue === undefined ? undefined : SECURE_EVENT_REDACTED_VALUE,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export function canUseRawBatchPath(item: RawBatchPathItem): boolean {
|
|
213
|
+
return (
|
|
214
|
+
item._hasExpiration === false &&
|
|
215
|
+
item._hasValidation === false &&
|
|
216
|
+
item._isBiometric !== true &&
|
|
217
|
+
item._secureAccessControl === undefined
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export function canUseSecureRawBatchPath(item: RawBatchPathItem): boolean {
|
|
222
|
+
return (
|
|
223
|
+
item._hasExpiration === false &&
|
|
224
|
+
item._hasValidation === false &&
|
|
225
|
+
item._isBiometric !== true
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export function defaultSerialize<T>(value: T): string {
|
|
230
|
+
return serializeWithPrimitiveFastPath(value);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export function defaultDeserialize<T>(value: string): T {
|
|
234
|
+
return deserializeWithPrimitiveFastPath(value);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export type SecureAuthStorageConfig<K extends string = string> = Record<
|
|
238
|
+
K,
|
|
239
|
+
{
|
|
240
|
+
ttlMs?: number;
|
|
241
|
+
biometric?: boolean;
|
|
242
|
+
biometricLevel?: BiometricLevel;
|
|
243
|
+
accessControl?: AccessControl;
|
|
244
|
+
}
|
|
245
|
+
>;
|
|
246
|
+
|
|
247
|
+
export function isKeychainLockedError(err: unknown): boolean {
|
|
248
|
+
return isLockedStorageErrorCode(getStorageErrorCode(err));
|
|
249
|
+
}
|