react-wire-persisted 2.1.0 → 3.1.0
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 +121 -28
- package/dist/index.d.ts +276 -0
- package/dist/index.js +238 -339
- package/dist/react-wire-persisted.js +238 -339
- package/dist/react-wire-persisted.js.map +1 -0
- package/dist/react-wire-persisted.umd.cjs +2 -1
- package/dist/react-wire-persisted.umd.cjs.map +1 -0
- package/package.json +32 -23
- package/src/components/{HydrationProvider.jsx → HydrationProvider.tsx} +12 -2
- package/src/components/index.tsx +1 -0
- package/src/global.d.ts +16 -0
- package/src/hooks/{useHydration.js → useHydration.ts} +8 -3
- package/src/{index.js → index.ts} +4 -1
- package/src/providers/{LocalStorageProvider.js → LocalStorageProvider.ts} +35 -34
- package/src/providers/MemoryStorageProvider.ts +14 -0
- package/src/providers/{StorageProvider.js → RWPStorageProvider.ts} +30 -19
- package/src/{react-wire-persisted.js → react-wire-persisted.ts} +43 -47
- package/src/types.ts +19 -0
- package/src/utils/fakeLocalStorage.ts +17 -0
- package/src/utils/{index.js → index.ts} +4 -4
- package/src/utils/{isomorphic.js → isomorphic.ts} +8 -8
- package/src/utils/keys.ts +49 -0
- package/src/components/HydrationProvider.js +0 -45
- package/src/components/index.js +0 -1
- package/src/providers/MemoryStorageProvider.js +0 -14
- package/src/utils/fakeLocalStorage.js +0 -15
- package/src/utils/keys.js +0 -46
package/README.md
CHANGED
|
@@ -5,23 +5,13 @@
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
7
|
```shell
|
|
8
|
-
$ pnpm add
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Building
|
|
12
|
-
|
|
13
|
-
```shell
|
|
14
|
-
$ pnpm build
|
|
15
|
-
$ npm version patch # patch, minor, major
|
|
16
|
-
$ git push
|
|
17
|
-
$ git push --tags
|
|
18
|
-
$ npm publish
|
|
8
|
+
$ pnpm add @forminator/react-wire react-wire-persisted
|
|
19
9
|
```
|
|
20
10
|
|
|
21
11
|
## Usage
|
|
22
12
|
|
|
23
|
-
```
|
|
24
|
-
// constants.
|
|
13
|
+
```typescript
|
|
14
|
+
// constants.ts
|
|
25
15
|
import { key, getPrefixedKeys } from 'react-wire-persisted/lib/utils'
|
|
26
16
|
|
|
27
17
|
export const NS = 'myapp'
|
|
@@ -33,36 +23,48 @@ const prefixedKeys = getPrefixedKeys(NS)
|
|
|
33
23
|
export { prefixedKeys as keys }
|
|
34
24
|
```
|
|
35
25
|
|
|
36
|
-
```
|
|
37
|
-
// index.
|
|
26
|
+
```tsx
|
|
27
|
+
// index.tsx
|
|
38
28
|
import { NS } from './constants'
|
|
39
|
-
import * as
|
|
29
|
+
import * as rwp from 'react-wire-persisted'
|
|
30
|
+
|
|
31
|
+
rwp.setNamespace(NS)
|
|
40
32
|
|
|
41
|
-
|
|
33
|
+
rwp.setOptions({
|
|
34
|
+
logging: {
|
|
35
|
+
enabled: true,
|
|
36
|
+
},
|
|
37
|
+
storageProvider: rwp.MemoryStorageProvider,
|
|
38
|
+
})
|
|
42
39
|
|
|
43
40
|
// Normal React init code
|
|
44
41
|
```
|
|
45
42
|
|
|
46
|
-
```
|
|
47
|
-
// store.
|
|
43
|
+
```typescript
|
|
44
|
+
// store.ts
|
|
48
45
|
import { createPersistedWire } from 'react-wire-persisted'
|
|
49
46
|
import { keys } from './constants'
|
|
50
47
|
|
|
51
|
-
|
|
48
|
+
type User = {
|
|
49
|
+
id: number
|
|
50
|
+
email: string
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export const user = createPersistedWire<User | null>(keys.foo, null)
|
|
52
54
|
```
|
|
53
55
|
|
|
54
|
-
```
|
|
55
|
-
// SomeComponent.
|
|
56
|
+
```tsx
|
|
57
|
+
// SomeComponent.tsx
|
|
56
58
|
import { useWireState } from '@forminator/react-wire'
|
|
57
59
|
import * as store from './store'
|
|
58
60
|
|
|
59
61
|
const SomeComponent = () => {
|
|
60
|
-
const [
|
|
62
|
+
const [user, setUser] = useWireState(store.user)
|
|
61
63
|
return (
|
|
62
64
|
<div>
|
|
63
|
-
<p>
|
|
64
|
-
<button onClick={() =>
|
|
65
|
-
|
|
65
|
+
<p>User: {user?.email}</p>
|
|
66
|
+
<button onClick={() => setUser({ ...user, email: 'example@gmail.com'})}>
|
|
67
|
+
Change Email
|
|
66
68
|
</button>
|
|
67
69
|
</div>
|
|
68
70
|
)
|
|
@@ -75,9 +77,100 @@ See the [demo](demo) folder for a more complete example.
|
|
|
75
77
|
|
|
76
78
|
## Storage Providers
|
|
77
79
|
|
|
78
|
-
|
|
80
|
+
By default, this library uses `localStorage` via `LocalStorageProvider` in browser environments. However, you can customize the storage behavior using `setOptions`:
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { setOptions, createPersistedWire } from 'react-wire-persisted'
|
|
84
|
+
import { MemoryStorageProvider } from 'react-wire-persisted'
|
|
85
|
+
|
|
86
|
+
// Use in-memory storage (useful for testing or SSR)
|
|
87
|
+
setOptions({
|
|
88
|
+
storageProvider: MemoryStorageProvider,
|
|
89
|
+
})
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
This is useful for:
|
|
93
|
+
- **Testing**: Avoid localStorage in unit tests
|
|
94
|
+
- **SSR**: Use in-memory storage during server-side rendering
|
|
95
|
+
- **Custom storage**: Implement your own provider by extending `RWPStorageProvider`
|
|
96
|
+
|
|
97
|
+
See [LocalStorageProvider](src/providers/LocalStorageProvider.ts) and [MemoryStorageProvider](src/providers/MemoryStorageProvider.ts) for implementation examples.
|
|
98
|
+
|
|
99
|
+
## API
|
|
100
|
+
|
|
101
|
+
### `createPersistedWire<T = null>(key: string, value?: T): PersistedWire<T>`
|
|
102
|
+
|
|
103
|
+
Creates a persisted Wire that automatically syncs with the configured storage provider.
|
|
104
|
+
|
|
105
|
+
### `setNamespace(namespace: string): void`
|
|
106
|
+
|
|
107
|
+
Sets the namespace for storage keys. This prefixes all keys to avoid collisions.
|
|
108
|
+
|
|
109
|
+
### `setOptions(options: Partial<RWPOptions>): void`
|
|
110
|
+
|
|
111
|
+
Configure library options:
|
|
112
|
+
- `logging.enabled`: Enable/disable logging (default: `false`)
|
|
113
|
+
- `storageProvider`: Custom storage provider class
|
|
114
|
+
|
|
115
|
+
### `getOptions(): RWPOptions`
|
|
116
|
+
|
|
117
|
+
Get current options.
|
|
79
118
|
|
|
80
|
-
|
|
119
|
+
### `getNamespace(): string | null`
|
|
120
|
+
|
|
121
|
+
Get current namespace.
|
|
122
|
+
|
|
123
|
+
### `getStorage(): RWPStorageProvider`
|
|
124
|
+
|
|
125
|
+
Get the current storage provider instance.
|
|
126
|
+
|
|
127
|
+
### `upgradeStorage(): boolean`
|
|
128
|
+
|
|
129
|
+
Attempts to upgrade from fake storage (used during SSR) to real localStorage. Returns `true` if upgrade was successful. Call this after hydration in client-side code.
|
|
130
|
+
|
|
131
|
+
## Building
|
|
132
|
+
|
|
133
|
+
```shell
|
|
134
|
+
$ pnpm build
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Contributing
|
|
138
|
+
|
|
139
|
+
Contributions are welcome. Please feel free to submit a [GitHub Issue](https://github.com/forminator/react-wire-persisted/issues) or pull request.
|
|
140
|
+
|
|
141
|
+
### Development
|
|
142
|
+
|
|
143
|
+
```shell
|
|
144
|
+
# Install dependencies
|
|
145
|
+
pnpm install
|
|
146
|
+
|
|
147
|
+
# Run tests
|
|
148
|
+
pnpm test
|
|
149
|
+
|
|
150
|
+
# Run linter
|
|
151
|
+
pnpm lint
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Publishing
|
|
155
|
+
|
|
156
|
+
To publish a new version to npm:
|
|
157
|
+
|
|
158
|
+
```shell
|
|
159
|
+
# Build the project
|
|
160
|
+
pnpm build
|
|
161
|
+
|
|
162
|
+
# Bump version (choose one)
|
|
163
|
+
npm version patch # bug fixes (e.g., 2.1.0 -> 2.1.1)
|
|
164
|
+
npm version minor # new features (e.g., 2.1.0 -> 2.2.0)
|
|
165
|
+
npm version major # breaking changes (e.g., 2.1.0 -> 3.0.0)
|
|
166
|
+
|
|
167
|
+
# Push changes and tags
|
|
168
|
+
git push
|
|
169
|
+
git push --tags
|
|
170
|
+
|
|
171
|
+
# Publish to npm
|
|
172
|
+
npm publish
|
|
173
|
+
```
|
|
81
174
|
|
|
82
175
|
## Miscellaneous
|
|
83
176
|
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { Wire } from '@forminator/react-wire';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Adds a key to the keys map
|
|
6
|
+
*
|
|
7
|
+
* @param {String} value Key name
|
|
8
|
+
*/
|
|
9
|
+
declare const addKey: (value: string) => void;
|
|
10
|
+
|
|
11
|
+
declare type AnyStorage = InternalStorage | Storage;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Creates a persisted Wire using the `RWPStorageProvider` that is currently set
|
|
15
|
+
* Defaults to `localStorage` via `LocalStorageProvider`
|
|
16
|
+
*
|
|
17
|
+
* @param {String} key Unique key for storing this value
|
|
18
|
+
* @param {*} value Initial value of this Wire
|
|
19
|
+
* @returns A new Wire decorated with localStorage functionality
|
|
20
|
+
*/
|
|
21
|
+
export declare const createPersistedWire: <T = null>(key: string, value?: T) => PersistedWire<T>;
|
|
22
|
+
|
|
23
|
+
export declare const defaultOptions: RWPOptions;
|
|
24
|
+
|
|
25
|
+
declare const fakeLocalStorage: InternalStorage;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Check if the client has finished hydrating
|
|
29
|
+
*/
|
|
30
|
+
declare const getHasHydrated: () => boolean;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Check if storage has been hydrated (safe to read from real localStorage)
|
|
34
|
+
*/
|
|
35
|
+
declare const getHasHydratedStorage: () => boolean;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Check if we're running in a browser environment
|
|
39
|
+
*/
|
|
40
|
+
declare const getIsClient: () => boolean;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Convenience method to get internally managed storage keys
|
|
44
|
+
*
|
|
45
|
+
* @returns {Object} InternalStorage keys map
|
|
46
|
+
*/
|
|
47
|
+
declare const getKeys: () => Record<string, string>;
|
|
48
|
+
|
|
49
|
+
export declare const getNamespace: () => string | null;
|
|
50
|
+
|
|
51
|
+
export declare const getOptions: () => RWPOptions;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Helper utility to prefix all keys in a map to use a namespace
|
|
55
|
+
*
|
|
56
|
+
* @param {String} namespace InternalStorage namespace prefix
|
|
57
|
+
* @param {Object} keys (Optional) InternalStorage key/values. Defaults to the internally managed keys map
|
|
58
|
+
*/
|
|
59
|
+
declare const getPrefixedKeys: (namespace: string, keys?: Record<string, string> | null) => Record<string, string>;
|
|
60
|
+
|
|
61
|
+
export declare const getStorage: () => RWPStorageProvider;
|
|
62
|
+
|
|
63
|
+
export declare const HydrationProvider: ({ children, onUpgrade, autoUpgrade }: HydrationProviderProps) => ReactNode;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* A Next.js App Router compatible component that handles automatic storage upgrade
|
|
67
|
+
* after hydration. Use this in your root layout.
|
|
68
|
+
*
|
|
69
|
+
* @param {Object} props Component props
|
|
70
|
+
* @param {React.ReactNode} props.children Child components to render
|
|
71
|
+
* @param {Function} props.onUpgrade Callback called when storage is upgraded
|
|
72
|
+
* @param {Boolean} props.autoUpgrade Whether to automatically upgrade storage (default: true)
|
|
73
|
+
*/
|
|
74
|
+
declare type HydrationProviderProps = {
|
|
75
|
+
children: ReactNode;
|
|
76
|
+
onUpgrade?: () => void;
|
|
77
|
+
autoUpgrade?: boolean;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
declare interface InternalStorage {
|
|
81
|
+
getItem: (key: string) => string | null;
|
|
82
|
+
setItem: (key: string, value: string) => void;
|
|
83
|
+
removeItem: (key: string) => void;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Check if localStorage is available and safe to use
|
|
88
|
+
*/
|
|
89
|
+
declare const isLocalStorageAvailable: () => boolean;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Checks if a value is a primitive type
|
|
93
|
+
*
|
|
94
|
+
* @param {*} val Value to check
|
|
95
|
+
* @returns {Boolean} True if value is a primitive type
|
|
96
|
+
*/
|
|
97
|
+
declare const isPrimitive: (val: unknown) => boolean;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Adds a key to the keys map
|
|
101
|
+
* (Alias for `addKey`)
|
|
102
|
+
*
|
|
103
|
+
* @param {String} value Key name
|
|
104
|
+
*/
|
|
105
|
+
declare const key: (value: string) => void;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* A storage provider for `localStorage`
|
|
109
|
+
* @see `RWPStorageProvider.ts` for documentation
|
|
110
|
+
*/
|
|
111
|
+
export declare class LocalStorageProvider extends RWPStorageProvider {
|
|
112
|
+
storage: AnyStorage;
|
|
113
|
+
private _isUsingFakeStorage;
|
|
114
|
+
constructor(namespace: string, registry?: Record<string, unknown>);
|
|
115
|
+
getStorage(): AnyStorage;
|
|
116
|
+
setNamespace(namespace: string): void;
|
|
117
|
+
getItem(key: string): any;
|
|
118
|
+
setItem(key: string, value: unknown): void;
|
|
119
|
+
removeItem(key: string, fromRegistry?: boolean): void;
|
|
120
|
+
getAll(): Record<string, unknown>;
|
|
121
|
+
_resetAll(useInitialValues?: boolean, excludedKeys?: string[], clearRegistry?: boolean): void;
|
|
122
|
+
resetAll(excludedKeys?: string[], clearRegistry?: boolean): void;
|
|
123
|
+
removeAll(excludedKeys?: string[], clearRegistry?: boolean): void;
|
|
124
|
+
/**
|
|
125
|
+
* Attempt to upgrade from fake storage to real localStorage
|
|
126
|
+
* This is useful for hydration scenarios
|
|
127
|
+
*/
|
|
128
|
+
upgradeToRealStorage(): boolean;
|
|
129
|
+
/**
|
|
130
|
+
* Check if currently using fake storage
|
|
131
|
+
*/
|
|
132
|
+
isUsingFakeStorage(): boolean;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Mark storage as hydrated (called after upgradeStorage)
|
|
137
|
+
*/
|
|
138
|
+
declare const markStorageAsHydrated: () => void;
|
|
139
|
+
|
|
140
|
+
export declare class MemoryStorageProvider extends LocalStorageProvider {
|
|
141
|
+
constructor(namespace: string, registry?: Record<string, unknown>);
|
|
142
|
+
getStorage(): InternalStorage;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
declare type PersistedWire<T> = Wire<T>;
|
|
146
|
+
|
|
147
|
+
declare type RWPOptions = {
|
|
148
|
+
logging: {
|
|
149
|
+
enabled: boolean;
|
|
150
|
+
};
|
|
151
|
+
storageProvider?: typeof RWPStorageProvider;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Base class to allow storage access
|
|
156
|
+
* @see `LocalStorageProvider.ts` for an example implementation
|
|
157
|
+
*/
|
|
158
|
+
/** biome-ignore-all lint/correctness/noUnusedFunctionParameters: WIP next PR will switch to TypeScript */
|
|
159
|
+
export declare abstract class RWPStorageProvider {
|
|
160
|
+
namespace: string | null;
|
|
161
|
+
registry: Record<string, unknown>;
|
|
162
|
+
/**
|
|
163
|
+
* Initializes the class
|
|
164
|
+
* @param {String} namespace Namespace to prefix all keys with. Mostly used for the logging and reset functions
|
|
165
|
+
* @param {Object} registry (Optional) Initialize the storage provider with an existing registry
|
|
166
|
+
*/
|
|
167
|
+
protected constructor(namespace: string, registry: Record<string, unknown>);
|
|
168
|
+
/**
|
|
169
|
+
* Sets the namespace for this storage provider, and migrates
|
|
170
|
+
* all stored values to the new namespace
|
|
171
|
+
* @param {String} namespace New namespace for this storage provider
|
|
172
|
+
*/
|
|
173
|
+
abstract setNamespace(namespace: string | null): void;
|
|
174
|
+
/**
|
|
175
|
+
* Registers an item with its initial value. This is used for logging, resetting, etc.
|
|
176
|
+
* @param {String} key InternalStorage item's key
|
|
177
|
+
* @param {*} initialValue InternalStorage item's initial value
|
|
178
|
+
*/
|
|
179
|
+
register<T>(key: string, initialValue: T | null): void;
|
|
180
|
+
/**
|
|
181
|
+
* Reads an item from storage
|
|
182
|
+
* @param {String} key Key for the item to retrieve
|
|
183
|
+
*/
|
|
184
|
+
abstract getItem<T>(key: string): T | null;
|
|
185
|
+
/**
|
|
186
|
+
* Stores a value
|
|
187
|
+
* @param {String} key Item's storage key
|
|
188
|
+
* @param {String} value Item's value to store
|
|
189
|
+
*/
|
|
190
|
+
abstract setItem<T>(key: string, value: T | null): void;
|
|
191
|
+
/**
|
|
192
|
+
* Removes an item from storage
|
|
193
|
+
* @param {String} key Item's storage key
|
|
194
|
+
* @param {Boolean} fromRegistry (Optional) If the item should also be removed from the registry
|
|
195
|
+
*/
|
|
196
|
+
abstract removeItem(key: string, fromRegistry: boolean): void;
|
|
197
|
+
/**
|
|
198
|
+
* Gets all stored keys and values
|
|
199
|
+
* If a `namespace` was set, only keys prefixed with the namespace will be returned
|
|
200
|
+
*/
|
|
201
|
+
abstract getAll(): Record<string, unknown>;
|
|
202
|
+
/**
|
|
203
|
+
*
|
|
204
|
+
* @param {Boolean} useInitialValues If values should be replaced with their initial values. If false, keys are removed
|
|
205
|
+
* @param {String[]} excludedKeys (Optional) List of keys to exclude
|
|
206
|
+
* @param {Boolean} clearRegistry (Optional) If the registry should also be cleared
|
|
207
|
+
*/
|
|
208
|
+
abstract _resetAll(useInitialValues: boolean, excludedKeys: string[], clearRegistry: boolean): void;
|
|
209
|
+
/**
|
|
210
|
+
* Resets all values to their initial values
|
|
211
|
+
* If a `namespace` is set, only keys prefixed with the namespace will be reset
|
|
212
|
+
* @param {String[]} excludedKeys (Optional) List of keys to exclude
|
|
213
|
+
*/
|
|
214
|
+
abstract resetAll(excludedKeys: string[]): void;
|
|
215
|
+
/**
|
|
216
|
+
* Removes all items from local storage.
|
|
217
|
+
* If a `namespace` is set, only keys prefixed with the namespace will be removed
|
|
218
|
+
* @param {String[]} excludedKeys (Optional) List of keys to exclude
|
|
219
|
+
*/
|
|
220
|
+
abstract removeAll(excludedKeys: string[]): void;
|
|
221
|
+
upgradeToRealStorage(): boolean;
|
|
222
|
+
isUsingFakeStorage(): boolean;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Sets the namespace for the storage provider
|
|
227
|
+
*
|
|
228
|
+
* @param {String} namespace The namespace for the storage provider
|
|
229
|
+
*/
|
|
230
|
+
export declare const setNamespace: (namespace: string) => void;
|
|
231
|
+
|
|
232
|
+
export declare const setOptions: (value: Partial<RWPOptions>) => void;
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Attempts to upgrade the storage provider from fake storage to real localStorage
|
|
236
|
+
* This should be called on the client side after hydration
|
|
237
|
+
*
|
|
238
|
+
* @returns true if upgrade was successful
|
|
239
|
+
*/
|
|
240
|
+
export declare const upgradeStorage: () => boolean;
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* React hook that handles automatic storage upgrade after hydration
|
|
244
|
+
* This should be used in the root component of your application
|
|
245
|
+
*
|
|
246
|
+
* @param {Object} options Configuration options
|
|
247
|
+
* @param {Boolean} options.autoUpgrade Whether to automatically upgrade storage (default: true)
|
|
248
|
+
* @param {Function} options.onUpgrade Callback called when storage is upgraded
|
|
249
|
+
*/
|
|
250
|
+
export declare const useHydration: (options?: UseHydrationOptions) => {
|
|
251
|
+
hasUpgraded: boolean;
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
export declare type UseHydrationOptions = {
|
|
255
|
+
autoUpgrade?: boolean;
|
|
256
|
+
onUpgrade?: () => void;
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
declare namespace utils {
|
|
260
|
+
export {
|
|
261
|
+
isPrimitive,
|
|
262
|
+
fakeLocalStorage,
|
|
263
|
+
getIsClient,
|
|
264
|
+
getHasHydrated,
|
|
265
|
+
getHasHydratedStorage,
|
|
266
|
+
markStorageAsHydrated,
|
|
267
|
+
isLocalStorageAvailable,
|
|
268
|
+
addKey,
|
|
269
|
+
key,
|
|
270
|
+
getKeys,
|
|
271
|
+
getPrefixedKeys
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
export { utils }
|
|
275
|
+
|
|
276
|
+
export { }
|