react-wire-persisted 2.0.1 → 3.0.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.
@@ -1,194 +0,0 @@
1
- import StorageProvider from './StorageProvider'
2
- import { fakeLocalStorage, isPrimitive, isLocalStorageAvailable } from '../utils'
3
-
4
- /**
5
- * A storage provider for `localStorage`
6
- * @see `StorageProvider.js` for documentation
7
- */
8
- class LocalStorageProvider extends StorageProvider {
9
-
10
- constructor(namespace = null, registry = {}) {
11
-
12
- super(namespace, registry)
13
-
14
- this.storage = this.getStorage()
15
- this._isUsingFakeStorage = !isLocalStorageAvailable()
16
-
17
- }
18
-
19
- getStorage() {
20
-
21
- // Use the isomorphic utility to check localStorage availability
22
- if (isLocalStorageAvailable()) {
23
- return window.localStorage
24
- }
25
-
26
- // Fallback to fake localStorage for SSR or when localStorage is disabled
27
- return fakeLocalStorage
28
-
29
- }
30
-
31
- setNamespace(namespace) {
32
-
33
- if (!this.namespace) {
34
- this.namespace = namespace
35
- return
36
- }
37
-
38
- if (this.namespace === namespace)
39
- return
40
-
41
- const items = JSON.parse(JSON.stringify(this.getAll()))
42
-
43
- this.removeAll()
44
-
45
- for (const [key, value] of Object.entries(items)) {
46
- const newKey = key.replace(this.namespace, namespace)
47
- this.setItem(newKey, value)
48
- }
49
-
50
- this.namespace = namespace
51
-
52
- }
53
-
54
- getItem(key) {
55
-
56
- const val = this.storage.getItem(key)
57
-
58
- if (val === undefined || val === null)
59
- return null
60
-
61
- try {
62
- return JSON.parse(val)
63
- } catch (e) {
64
- return val
65
- }
66
-
67
- }
68
-
69
- setItem(key, value) {
70
-
71
- let val = value
72
-
73
- // Don't allow "null" & similar values to be stringified
74
- if (val !== undefined && val !== null)
75
- val = isPrimitive(value) ? value : JSON.stringify(value)
76
-
77
- return this.storage.setItem(key, val)
78
-
79
- }
80
-
81
- removeItem(key, fromRegistry = false) {
82
-
83
- if (fromRegistry)
84
- delete this.registry[key]
85
-
86
- return this.storage.removeItem(key)
87
-
88
- }
89
-
90
- getAll() {
91
-
92
- const prefixNs = `${this.namespace}.`
93
-
94
- return Object.keys(this.storage).reduce((acc, it) => {
95
-
96
- if (this.namespace ? it.startsWith(prefixNs) : true)
97
- acc[it] = this.storage.getItem(it)
98
-
99
- return acc
100
-
101
- }, {})
102
-
103
- }
104
-
105
- _resetAll(
106
- useInitialValues = true,
107
- excludedKeys = [],
108
- clearRegistry = false
109
- ) {
110
-
111
- const prefixNs = `${this.namespace}.`
112
-
113
- Object.keys(this.storage).forEach(it => {
114
-
115
- const isAppKey = this.namespace ? it.startsWith(prefixNs) : true
116
- const isExcluded = excludedKeys?.includes(it) || false
117
-
118
- if (!isAppKey || isExcluded) return
119
-
120
- if (useInitialValues) {
121
-
122
- const isRegistered = Object.prototype.hasOwnProperty.call(this.registry, it)
123
-
124
- if (isRegistered)
125
- this.storage.setItem(it, this.registry[it])
126
- else
127
- this.storage.removeItem(it)
128
-
129
- } else {
130
-
131
- this.storage.removeItem(it)
132
-
133
- if (clearRegistry)
134
- delete this.registry[it]
135
-
136
- }
137
-
138
- })
139
-
140
- }
141
-
142
- resetAll(excludedKeys = [], clearRegistry = false) {
143
- this._resetAll(true, excludedKeys || [], clearRegistry)
144
- }
145
-
146
- removeAll(excludedKeys = [], clearRegistry = false) {
147
- this._resetAll(false, excludedKeys || [], clearRegistry)
148
- }
149
-
150
- /**
151
- * Attempt to upgrade from fake storage to real localStorage
152
- * This is useful for hydration scenarios
153
- */
154
- upgradeToRealStorage() {
155
-
156
- if (!this._isUsingFakeStorage) {
157
- return false // Already using real storage
158
- }
159
-
160
- if (!isLocalStorageAvailable()) {
161
- return false // Real storage still not available
162
- }
163
-
164
- const fakeData = { ...this.storage }
165
- this.storage = window.localStorage
166
- this._isUsingFakeStorage = false
167
-
168
- // Migrate data from fake storage to real storage
169
- Object.keys(fakeData).forEach(key => {
170
- if (key !== '__IS_FAKE_LOCAL_STORAGE__' && fakeData[key] != null) {
171
- try {
172
- this.storage.setItem(key, fakeData[key])
173
- } catch (e) {
174
- // If we can't write to localStorage, revert to fake storage
175
- this.storage = fakeLocalStorage
176
- this._isUsingFakeStorage = true
177
- return false
178
- }
179
- }
180
- })
181
-
182
- return true
183
- }
184
-
185
- /**
186
- * Check if currently using fake storage
187
- */
188
- isUsingFakeStorage() {
189
- return this._isUsingFakeStorage
190
- }
191
-
192
- }
193
-
194
- export default LocalStorageProvider
@@ -1,20 +0,0 @@
1
- import LocalStorageProvider from './LocalStorageProvider'
2
- import { fakeLocalStorage } from '../utils'
3
-
4
- class MemoryStorageProvider extends LocalStorageProvider {
5
-
6
- constructor(namespace = null, registry = {}) {
7
-
8
- super(namespace, registry)
9
-
10
- }
11
-
12
- getStorage() {
13
-
14
- return fakeLocalStorage
15
-
16
- }
17
-
18
- }
19
-
20
- export default MemoryStorageProvider
@@ -1,136 +0,0 @@
1
- import { createWire } from '@forminator/react-wire'
2
- import LocalStorageProvider from './providers/LocalStorageProvider'
3
- import { getIsClient, getHasHydrated } from './utils'
4
-
5
- export const defaultOptions = {
6
- logging: {
7
- enabled: false,
8
- },
9
- }
10
-
11
- let Provider = LocalStorageProvider
12
- let storage = new Provider()
13
- let options = { ...defaultOptions }
14
- let pendingLogs = []
15
-
16
- /**
17
- * Gets the namespace of the storage provider
18
- *
19
- * @returns {String}
20
- */
21
- export const getNamespace = () => storage.namespace
22
-
23
- /**
24
- * Gets the current storage provider class instance
25
- *
26
- * @returns {StorageProvider}
27
- */
28
- export const getStorage = () => storage
29
-
30
- export const getOptions = () => options
31
-
32
- /**
33
- * Sets the namespace for the storage provider
34
- *
35
- * @param {String} namespace The namespace for the storage provider
36
- */
37
- export const setNamespace = namespace => {
38
- storage.setNamespace(namespace)
39
- storage = new Provider(namespace || getNamespace())
40
- }
41
-
42
- export const setOptions = value => {
43
- options = {
44
- ...options,
45
- ...value,
46
- }
47
- /* istanbul ignore next */
48
- if (options.logging.enabled) {
49
- console.info('Flushing', pendingLogs.length, 'pending logs')
50
- while (pendingLogs.length)
51
- /* istanbul ignore next */
52
- console.log(...pendingLogs.shift())
53
- }
54
- }
55
-
56
- /**
57
- * Attempts to upgrade the storage provider from fake storage to real localStorage
58
- * This should be called on the client side after hydration
59
- *
60
- * @returns {Boolean} True if upgrade was successful
61
- */
62
- export const upgradeStorage = () => {
63
- if (!getIsClient()) {
64
- return false
65
- }
66
-
67
- const upgraded = storage.upgradeToRealStorage()
68
-
69
- if (upgraded) {
70
- log('react-wire-persisted: Upgraded to real localStorage after hydration')
71
- }
72
-
73
- return upgraded
74
- }
75
-
76
- const log = (...args) => {
77
- /* istanbul ignore next */
78
- if (options.logging.enabled)
79
- /* istanbul ignore next */
80
- console.log(...args)
81
- else
82
- pendingLogs.push(args)
83
- }
84
-
85
- /**
86
- * Creates a persisted Wire using the `StorageProvider` that is currently set
87
- * Defaults to `localStorage` via `LocalStorageProvider`
88
- *
89
- * @param {String} key Unique key for storing this value
90
- * @param {*} value Initial value of this Wire
91
- * @returns A new Wire decorated with localStorage functionality
92
- */
93
- export const createPersistedWire = (key, value = null) => {
94
-
95
- // This check helps ensure no accidental key typos occur
96
- if (!key && (typeof key) !== 'number') throw new Error(
97
- `createPersistedWire: Key cannot be a falsey value (${key}}`
98
- )
99
-
100
- // Track this writable entry so we can easily clear all
101
- storage.register(key, value)
102
-
103
- // The actual Wire backing object
104
- const wire = createWire(value)
105
-
106
- const getValue = () => wire.getValue()
107
-
108
- const setValue = newValue => {
109
- storage.setItem(key, newValue)
110
- return wire.setValue(newValue)
111
- }
112
-
113
- const subscribe = fn => {
114
- wire.subscribe(fn)
115
- }
116
-
117
- const storedValue = storage.getItem(key)
118
- const initialValue = storedValue === null ? value : storedValue
119
-
120
- log('react-wire-persisted: create', key, {
121
- value,
122
- storedValue,
123
- initialValue,
124
- })
125
-
126
- if (initialValue !== value)
127
- setValue(initialValue)
128
-
129
- return {
130
- ...wire,
131
- getValue,
132
- setValue,
133
- subscribe,
134
- }
135
-
136
- }
@@ -1,16 +0,0 @@
1
-
2
- const storage = {
3
- __IS_FAKE_LOCAL_STORAGE__: true,
4
- }
5
-
6
- export const fakeLocalStorage = {
7
- getItem: key => storage[key],
8
- setItem: (key, value) => {
9
- storage[key] = value
10
- },
11
- removeItem: key => {
12
- delete storage[key]
13
- },
14
- // Make Object.keys() work properly for _resetAll method
15
- ...storage
16
- }
package/src/utils/keys.js DELETED
@@ -1,49 +0,0 @@
1
-
2
- /**
3
- * Convenience map of keys
4
- */
5
- const storageKeys = {}
6
-
7
- /**
8
- * Adds a key to the keys map
9
- *
10
- * @param {String} value Key name
11
- */
12
- export const addKey = value => {
13
- storageKeys[value] = value
14
- }
15
-
16
- /**
17
- * Adds a key to the keys map
18
- * (Alias for `addKey`)
19
- *
20
- * @param {String} value Key name
21
- */
22
- export const key = value => addKey(value)
23
-
24
- /**
25
- * Convenience method to get internally managed storage keys
26
- *
27
- * @returns {Object} Storage keys map
28
- */
29
- export const getKeys = () => storageKeys
30
-
31
- /**
32
- * Helper utility to prefix all keys in a map to use a namespace
33
- *
34
- * @param {String} namespace Storage namespace prefix
35
- * @param {Object} keys (Optional) Storage key/values. Defaults to the internally managed keys map
36
- */
37
- export const getPrefixedKeys = (namespace, keys = null) => {
38
-
39
- const items = keys || storageKeys
40
-
41
- if (!namespace)
42
- return items
43
-
44
- return Object.keys(items).reduce((acc, it) => ({
45
- ...acc,
46
- [it]: `${namespace}.${items[it]}`,
47
- }), {})
48
-
49
- }