@plq/use-persisted-state 1.3.0 → 1.4.1

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.
Files changed (101) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +179 -50
  3. package/esm/index.d.mts +13 -0
  4. package/esm/index.mjs +10 -0
  5. package/esm/storages/browser-storage.d.mts +1 -0
  6. package/esm/storages/browser-storage.mjs +5 -0
  7. package/esm/storages/chrome-storage.d.mts +1 -0
  8. package/esm/storages/chrome-storage.mjs +5 -0
  9. package/esm/storages/local-storage.d.mts +1 -0
  10. package/esm/storages/local-storage.mjs +3 -0
  11. package/esm/storages/session-storage.d.mts +1 -0
  12. package/esm/storages/session-storage.mjs +3 -0
  13. package/lib/@types/storage.d.ts.map +1 -1
  14. package/lib/create-async-persisted-state.d.ts +2 -2
  15. package/lib/create-async-persisted-state.d.ts.map +1 -1
  16. package/lib/create-async-persisted-state.js +136 -17
  17. package/lib/create-async-persisted-state.js.map +1 -1
  18. package/lib/create-persisted-state.d.ts +2 -2
  19. package/lib/create-persisted-state.d.ts.map +1 -1
  20. package/lib/create-persisted-state.js +76 -15
  21. package/lib/create-persisted-state.js.map +1 -1
  22. package/lib/index.d.ts +6 -5
  23. package/lib/index.d.ts.map +1 -1
  24. package/lib/index.js +4 -2
  25. package/lib/index.js.map +1 -1
  26. package/lib/storages/browser-storage.d.ts +2 -2
  27. package/lib/storages/browser-storage.d.ts.map +1 -1
  28. package/lib/storages/browser-storage.js +6 -26
  29. package/lib/storages/browser-storage.js.map +1 -1
  30. package/lib/storages/chrome-storage.d.ts +2 -2
  31. package/lib/storages/chrome-storage.d.ts.map +1 -1
  32. package/lib/storages/chrome-storage.js +10 -27
  33. package/lib/storages/chrome-storage.js.map +1 -1
  34. package/lib/storages/local-storage.d.ts +1 -1
  35. package/lib/storages/local-storage.d.ts.map +1 -1
  36. package/lib/storages/local-storage.js +3 -1
  37. package/lib/storages/local-storage.js.map +1 -1
  38. package/lib/storages/session-storage.d.ts +1 -1
  39. package/lib/storages/session-storage.d.ts.map +1 -1
  40. package/lib/storages/session-storage.js +3 -1
  41. package/lib/storages/session-storage.js.map +1 -1
  42. package/lib/utils/change-notifier.d.ts +18 -0
  43. package/lib/utils/change-notifier.d.ts.map +1 -0
  44. package/lib/utils/change-notifier.js +38 -0
  45. package/lib/utils/change-notifier.js.map +1 -0
  46. package/lib/utils/create-web-storage.d.ts +10 -2
  47. package/lib/utils/create-web-storage.d.ts.map +1 -1
  48. package/lib/utils/create-web-storage.js +72 -75
  49. package/lib/utils/create-web-storage.js.map +1 -1
  50. package/lib/utils/extension-storage.d.ts +38 -0
  51. package/lib/utils/extension-storage.d.ts.map +1 -0
  52. package/lib/utils/extension-storage.js +66 -0
  53. package/lib/utils/extension-storage.js.map +1 -0
  54. package/lib/utils/get-new-item.d.ts +13 -1
  55. package/lib/utils/get-new-item.d.ts.map +1 -1
  56. package/lib/utils/get-new-item.js +27 -7
  57. package/lib/utils/get-new-item.js.map +1 -1
  58. package/lib/utils/get-new-value.d.ts +1 -1
  59. package/lib/utils/get-new-value.d.ts.map +1 -1
  60. package/lib/utils/get-persisted-value.d.ts +8 -1
  61. package/lib/utils/get-persisted-value.d.ts.map +1 -1
  62. package/lib/utils/get-persisted-value.js +19 -5
  63. package/lib/utils/get-persisted-value.js.map +1 -1
  64. package/lib/utils/is-async-storage.d.ts +7 -0
  65. package/lib/utils/is-async-storage.d.ts.map +1 -1
  66. package/lib/utils/is-async-storage.js +51 -20
  67. package/lib/utils/is-async-storage.js.map +1 -1
  68. package/lib/utils/storage-event-router.d.ts +17 -0
  69. package/lib/utils/storage-event-router.d.ts.map +1 -0
  70. package/lib/utils/storage-event-router.js +54 -0
  71. package/lib/utils/storage-event-router.js.map +1 -0
  72. package/lib/utils/use-storage-handler.d.ts +14 -3
  73. package/lib/utils/use-storage-handler.d.ts.map +1 -1
  74. package/lib/utils/use-storage-handler.js +109 -26
  75. package/lib/utils/use-storage-handler.js.map +1 -1
  76. package/package.json +97 -41
  77. package/src/@types/storage.ts +13 -13
  78. package/src/create-async-persisted-state.ts +125 -20
  79. package/src/create-persisted-state.ts +59 -23
  80. package/src/index.ts +12 -7
  81. package/src/storages/browser-storage.ts +8 -36
  82. package/src/storages/chrome-storage.ts +24 -46
  83. package/src/storages/local-storage.ts +3 -1
  84. package/src/storages/session-storage.ts +3 -1
  85. package/src/utils/change-notifier.ts +43 -0
  86. package/src/utils/create-web-storage.ts +74 -77
  87. package/src/utils/extension-storage.ts +79 -0
  88. package/src/utils/get-new-item.ts +32 -9
  89. package/src/utils/get-new-value.ts +1 -1
  90. package/src/utils/get-persisted-value.ts +22 -7
  91. package/src/utils/is-async-storage.ts +72 -27
  92. package/src/utils/storage-event-router.ts +67 -0
  93. package/src/utils/use-storage-handler.ts +144 -36
  94. package/storages/browser-storage.d.ts +1 -0
  95. package/storages/browser-storage.js +11 -0
  96. package/storages/chrome-storage.d.ts +1 -0
  97. package/storages/chrome-storage.js +11 -0
  98. package/storages/local-storage.d.ts +1 -0
  99. package/storages/local-storage.js +9 -0
  100. package/storages/session-storage.d.ts +1 -0
  101. package/storages/session-storage.js +9 -0
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2017 Uploadcare
3
+ Copyright (c) 2019 Alexander Kurganov
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,21 +1,37 @@
1
1
  # usePersistedState
2
+
2
3
  [![npm version](https://badge.fury.io/js/@plq%2Fuse-persisted-state.svg)](https://www.npmjs.com/package/@plq/use-persisted-state)
3
- [![Tests](https://github.com/Akurganow/use-persisted-state/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/Akurganow/use-persisted-state/actions/workflows/main.yml)
4
+ [![Tests](https://github.com/Akurganow/use-persisted-state/actions/workflows/main.yml/badge.svg?branch=main)](https://github.com/Akurganow/use-persisted-state/actions/workflows/main.yml)
5
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
6
+ [![Ko-fi](https://img.shields.io/badge/Ko--fi-support-FF5E5B?logo=ko-fi&logoColor=white)](https://ko-fi.com/akurganow)
4
7
 
5
- Persists the state to localStorage, sessionStorage or any custom storage
8
+ A React `useState` that persists to `localStorage`, `sessionStorage`, extension storage (`browser.storage` / `chrome.storage`), or any custom backend.
6
9
 
7
10
  ## Features
8
11
 
9
- - Persist the state to `localStorage`, `sessionStorage` or almost anything else implements [storage API](https://github.com/Akurganow/use-persisted-state/blob/master/docs/storage-api.md)
10
- - The state factory takes as many keys as needed, so you don't have to call the factory for each variable
11
- - Written with the TypeScript, the definitions go with the library
12
- - No third-party dependencies
12
+ - Persist state to `localStorage`, `sessionStorage`, extension storage, or almost anything else that implements the [storage API](https://github.com/Akurganow/use-persisted-state/blob/main/docs/storage-api.md)
13
+ - One state factory serves as many keys as needed, so you don't have to call the factory for each variable
14
+ - Supports both synchronous and asynchronous storage backends
15
+ - Components using the same key stay in sync; with the `localStorage` adapter, changes also propagate across browser tabs
16
+ - Written in TypeScript — type definitions ship with the package
17
+ - A single tiny runtime dependency: [`@plq/is`](https://www.npmjs.com/package/@plq/is)
18
+
19
+ ## Requirements
20
+
21
+ To use `@plq/use-persisted-state`, you must use `react@16.8.0` or greater, which includes Hooks.
22
+ The library is tested against React 19. The peer range allows React 16.8 and above, though only 19 is exercised in CI.
13
23
 
14
- ## Example
24
+ ## Install
25
+
26
+ ```sh
27
+ npm install @plq/use-persisted-state
28
+ ```
29
+
30
+ ## Quick start
15
31
 
16
32
  ```jsx
17
33
  import createPersistedState from '@plq/use-persisted-state'
18
- import storage from '@plq/use-persisted-state/lib/storages/local-storage'
34
+ import storage from '@plq/use-persisted-state/storages/local-storage'
19
35
 
20
36
  const [usePersistedState] = createPersistedState('example', storage)
21
37
 
@@ -32,25 +48,64 @@ export default function App() {
32
48
  }
33
49
  ```
34
50
 
35
- [![Edit @plq/use-persisted-state](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/plquse-persisted-state-ob2od?fontsize=14)
51
+ This example uses the bundled `localStorage` adapter; [Storage adapters](#storage-adapters) lists the rest and what each one is for.
52
+
53
+ To try it locally, run the demo app from a repository checkout: `npm ci && npm run demo`.
54
+
55
+ ## API
56
+
57
+ ### `createPersistedState(name, storage)` — default export
58
+
59
+ ```ts
60
+ const [usePersistedState, clear] = createPersistedState(name, storage)
61
+ ```
62
+
63
+ - `name` — a namespace for this factory. All keys created by the returned hook are stored together in a single storage entry named `persisted_state_hook:<name>`.
64
+ - `storage` — a synchronous or asynchronous storage backend implementing the [storage API](https://github.com/Akurganow/use-persisted-state/blob/main/docs/storage-api.md).
65
+
66
+ Returns a `[usePersistedState, clear]` tuple. The default export detects whether the backend is asynchronous from the shape of its methods wherever it can — a `get` declared `async` settles the question without a call. Only when that does not hold does it call `get('')` once, as a method of your storage, to see whether the result is a `Promise`; `set` and `remove` are never invoked, so detection cannot write to your storage. All three members must be functions. If even a read during setup is undesirable, import one of the named factories below instead — they skip detection entirely.
67
+
68
+ ### Named factories
69
+
70
+ ```ts
71
+ import { createPersistedState, createAsyncPersistedState } from '@plq/use-persisted-state'
72
+ ```
73
+
74
+ - `createPersistedState(name, storage)` — for synchronous backends only (`localStorage`, `sessionStorage`).
75
+ - `createAsyncPersistedState(name, storage)` — for asynchronous backends only (`browser.storage`, `chrome.storage`, custom promise-based backends).
76
+
77
+ ### `usePersistedState(key, initialValue)`
78
+
79
+ ```ts
80
+ const [state, setState] = usePersistedState(key, initialValue)
81
+ ```
82
+
83
+ Works like `useState`: returns the current state and a setter that accepts either a value or an updater function (`prev => next`). In addition, every update is written to the storage backend, and external changes to the stored value update the state.
84
+
85
+ - Values are serialized with `JSON.stringify`, so they must be JSON-serializable (no functions, class instances, `Map`, `Set`, etc.). A few values serialize into something else rather than failing outright — see [Values JSON cannot carry](#values-json-cannot-carry).
86
+ - With an asynchronous backend, the hook renders `initialValue` first and updates once the stored value has loaded.
87
+
88
+ ### `clear()`
36
89
 
37
- ## Requirement
38
- To use `@plq/use-persisted-state`, you must use `react@16.8.0` or greater which includes Hooks.
39
- The library is fully compatible with React 18 and React 19.
90
+ Removes the factory's whole storage entry. Hooks created by that factory fall back to their initial values. Returns `void` for synchronous backends and `Promise<void>` for asynchronous ones.
91
+
92
+ ### TypeScript
93
+
94
+ The package ships its own type definitions. The storage contract and the hook's own types are exported from the entry point:
95
+
96
+ ```ts
97
+ import type { Storage, AsyncStorage, StorageChange, StorageChangeListener } from '@plq/use-persisted-state'
98
+ ```
40
99
 
41
- ## React 19 Compatibility
100
+ `Storage` and `AsyncStorage` are the two backend contracts. `StorageChange`, `StorageChangeListener` and `StorageChangeEvent` describe the `onChanged` event an adapter provides. `PersistedState` and `UsePersistedState` type the hook and the tuple it returns.
42
101
 
43
- This library is fully compatible with React 19 and supports all new features:
44
- - Works seamlessly with `useTransition` for performance optimization
45
- - Compatible with `useActionState` for form handling
46
- - Supports `useOptimistic` for optimistic updates
102
+ The longer `@plq/use-persisted-state/lib/@types/storage` path that earlier versions documented continues to work and resolves to the same types. Prefer the entry point: `lib/` is kept open for compatibility only.
47
103
 
48
- Check out our [React 19 examples](./demo/src/examples/) to see these features in action!
104
+ ## Clear storage
49
105
 
50
- ## Clear Storage
51
106
  ```jsx
52
107
  import createPersistedState from '@plq/use-persisted-state'
53
- import storage from '@plq/use-persisted-state/lib/storages/local-storage'
108
+ import storage from '@plq/use-persisted-state/storages/local-storage'
54
109
 
55
110
  const [usePersistedState, clear] = createPersistedState('example', storage)
56
111
 
@@ -67,44 +122,36 @@ export default function App() {
67
122
  )
68
123
  }
69
124
  ```
125
+
70
126
  ## Use sessionStorage
127
+
71
128
  ```jsx
72
129
  import createPersistedState from '@plq/use-persisted-state'
73
- import storage from '@plq/use-persisted-state/lib/storages/session-storage'
130
+ import storage from '@plq/use-persisted-state/storages/session-storage'
74
131
 
75
132
  const [usePersistedState, clear] = createPersistedState('example', storage)
76
133
  ```
134
+
77
135
  ## Use async storage
136
+
78
137
  ```jsx
79
138
  import createPersistedState from '@plq/use-persisted-state'
80
- // or
139
+ // or, to skip async detection:
81
140
  import { createAsyncPersistedState } from '@plq/use-persisted-state'
82
- import { local } from '@plq/use-persisted-state/lib/storages/browser-storage'
141
+ import { local } from '@plq/use-persisted-state/storages/browser-storage'
83
142
 
84
143
  const [usePersistedState, clear] = createPersistedState('example', local)
85
144
  ```
145
+
86
146
  ## Use custom storage
87
147
 
88
- The [storage API](https://github.com/Akurganow/use-persisted-state/blob/master/docs/storage-api.md) is similar to the browser.storage but with a few differences
148
+ The [storage API](https://github.com/Akurganow/use-persisted-state/blob/main/docs/storage-api.md) is similar to the WebExtensions `browser.storage` API, with a few differences. Any object implementing it works:
89
149
 
90
150
  ```jsx
91
151
  import createPersistedState from '@plq/use-persisted-state'
92
152
 
93
153
  const storageListeners = new Set()
94
154
 
95
- onChangeSomeStorage(event => {
96
- const changes = {
97
- [event.key]: {
98
- newValue: event.newValue,
99
- oldValue: event.oldValue,
100
- },
101
- }
102
-
103
- listeners.forEach(listener => {
104
- listener(changes)
105
- })
106
- })
107
-
108
155
  const myStorage = {
109
156
  get: keys => getItemsFromSomeStorage(keys),
110
157
  set: items => setItemsToSomeStorage(items),
@@ -113,21 +160,103 @@ const myStorage = {
113
160
  addListener: listener => storageListeners.add(listener),
114
161
  removeListener: listener => storageListeners.delete(listener),
115
162
  hasListener: listener => storageListeners.has(listener),
116
- }
163
+ },
117
164
  }
118
165
 
119
166
  const [usePersistedState, clear] = createPersistedState('example', myStorage)
120
167
  ```
168
+
169
+ Your adapter owns that listener set and calls every listener when the backing store changes, which is what keeps components on the same key in sync. The [storage API](https://github.com/Akurganow/use-persisted-state/blob/main/docs/storage-api.md) documents the change payload and carries the complete example, including how to forward a backend's own events to the listeners.
170
+
121
171
  ## Storage adapters
122
- ### [localStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage) `@plq/use-persisted-state/lib/storages/local-storage`
123
- - Useful for average web application
124
- ### [sessionStorage](https://developer.mozilla.org/docs/Web/API/Window/sessionStorage) `@plq/use-persisted-state/lib/storages/session-storage`
125
- - Useful for average web application
126
- ### [browser.storage](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/storage) `@plq/use-persisted-state/lib/storages/browser-storage`
127
- - Only for web extensions.
128
- - Don't forget to set up [polyfill](https://github.com/mozilla/webextension-polyfill) if you want to run extension in Chrome browser.
129
- - To use this storage you need to include the "storage" [permission](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions) in your `manifest.json` file
130
- ### [chrome.storage](https://developer.chrome.com/apps/storage) `@plq/use-persisted-state/lib/storages/chrome-storage`
131
- - Only for Chrome-based web extensions.
132
- - If you develop extension that will be run only in Chrome browser you can use this storage without [polyfill](https://github.com/mozilla/webextension-polyfill).
133
- - You must declare the "storage" permission in the [extension manifest](https://developer.chrome.com/apps/manifest) to use this storage.
172
+
173
+ The longer `@plq/use-persisted-state/lib/storages/…` paths that earlier versions documented continue
174
+ to work. Prefer the shorter ones below: imported from ES module code, the `lib` path hands back the
175
+ CommonJS exports object rather than the adapter, so it needs an extra `.default` that the shorter
176
+ path does not.
177
+
178
+ ### [localStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage) `@plq/use-persisted-state/storages/local-storage`
179
+
180
+ - Useful for the average web application.
181
+ - Synchronous. Changes made in other browser tabs are picked up through the [`storage` event](https://developer.mozilla.org/docs/Web/API/Window/storage_event).
182
+
183
+ ### [sessionStorage](https://developer.mozilla.org/docs/Web/API/Window/sessionStorage) `@plq/use-persisted-state/storages/session-storage`
184
+
185
+ - Useful for state that should not outlive the browser session.
186
+ - Synchronous.
187
+
188
+ ### [browser.storage](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/storage) `@plq/use-persisted-state/storages/browser-storage`
189
+
190
+ - Only for web extensions. Asynchronous.
191
+ - Named exports for each storage area: `local`, `sync` and `managed` (note that the [managed area](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/storage/managed) is read-only for the extension).
192
+ - Don't forget to set up the [polyfill](https://github.com/mozilla/webextension-polyfill) if you want to run the extension in a Chromium-based browser.
193
+ - You need to declare the "storage" [permission](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions) in your `manifest.json` file.
194
+
195
+ ### [chrome.storage](https://developer.chrome.com/docs/extensions/reference/api/storage) `@plq/use-persisted-state/storages/chrome-storage`
196
+
197
+ - Only for Chromium-based web extensions. Asynchronous.
198
+ - Named exports for each storage area: `local`, `sync` and `managed` (the managed area is read-only for the extension).
199
+ - If your extension runs only in Chromium-based browsers, you can use this adapter without the polyfill.
200
+ - You must declare the "storage" permission in the [extension manifest](https://developer.chrome.com/docs/extensions/reference/manifest) to use this adapter.
201
+
202
+ ```jsx
203
+ import createPersistedState from '@plq/use-persisted-state'
204
+ import { local } from '@plq/use-persisted-state/storages/chrome-storage'
205
+
206
+ const [usePersistedState, clear] = createPersistedState('example', local)
207
+ ```
208
+
209
+ ## Server-side rendering
210
+
211
+ This library targets browser environments. Two things matter when rendering on a server:
212
+
213
+ - The bundled `local-storage` and `session-storage` adapters can be imported without `localStorage` / `sessionStorage`. Where the global is missing the adapter reads back nothing and discards every write, so the hook keeps its initial value rather than throwing.
214
+ - The synchronous hook reads from storage during render.
215
+
216
+ When using an SSR framework (Next.js, Remix, etc.), make sure the components using the hook run only on the client — for example, in client-only components or behind a dynamic import that is disabled during SSR.
217
+
218
+ ## How values are stored
219
+
220
+ Each factory keeps all of its keys in a single storage entry named `persisted_state_hook:<name>`, holding a JSON object with one property per key:
221
+
222
+ ```
223
+ persisted_state_hook:example → {"count":0}
224
+ ```
225
+
226
+ Storage backends only ever see serialized strings. Anything you persist ends up unencrypted in the underlying storage — do not store secrets or sensitive data (see [SECURITY.md](https://github.com/Akurganow/use-persisted-state/blob/main/SECURITY.md)).
227
+
228
+ ### An entry the library cannot read
229
+
230
+ A write replaces the factory's whole entry, so there is nothing safe to store when the entry already
231
+ there is a string that will not parse, or parses to something that is not an object — another
232
+ library writing under the same key, or a write cut short. The setter reports the failure on
233
+ `console.error`, keeps the value you set in memory and writes nothing, leaving every other hook's
234
+ key exactly where it is. The factory's `clear` removes the entry and lets writing resume.
235
+
236
+ This reaches as far as the adapter reports. Web storage holds only strings, so anything under the
237
+ key comes back and is checked. Extension storage holds arbitrary JSON, and the bundled adapters
238
+ report a non-string value as absent — the library then reads the entry as empty and its next write
239
+ **replaces that value**. Storing your own data under a `persisted_state_hook:` key in extension
240
+ storage is not safe, whatever its type.
241
+
242
+ ### Values JSON cannot carry
243
+
244
+ A few values do not survive `JSON.stringify`. This follows from the format rather than from a choice
245
+ the library makes, and no adapter can repair it: once a value has been written, nothing in storage
246
+ tells a `null` you stored apart from a `null` that JSON produced.
247
+
248
+ - **`undefined`** — the key is dropped, so nothing reaches storage at all. The component that set it
249
+ keeps `undefined` in memory, as `useState` would, and other components already mounted on that key
250
+ see no change and keep the value they hold. After a remount or a reload the key is absent, so the
251
+ initial value comes back.
252
+ - **`NaN`, `Infinity`, `-Infinity`** — these are written as `null`. The component that set the value
253
+ keeps it until it remounts; every other component on that key reads back `null`, as does any
254
+ reader after a reload.
255
+
256
+ ## Contributing
257
+
258
+ Contributions are welcome — see [CONTRIBUTING.md](https://github.com/Akurganow/use-persisted-state/blob/main/CONTRIBUTING.md) for setup, testing and the commit convention, and [CODE_OF_CONDUCT.md](https://github.com/Akurganow/use-persisted-state/blob/main/CODE_OF_CONDUCT.md) for community standards.
259
+
260
+ ## License
261
+
262
+ [MIT](LICENSE)
@@ -0,0 +1,13 @@
1
+ // Type-level aliases of the build output rather than restated signatures: a
2
+ // copy keeps compiling after src changes and hands ESM consumers stale types
3
+ // while CJS consumers get the current ones.
4
+ export { default, createPersistedState, createAsyncPersistedState } from '../lib/index.js'
5
+ export type {
6
+ AsyncStorage,
7
+ PersistedState,
8
+ Storage,
9
+ StorageChange,
10
+ StorageChangeEvent,
11
+ StorageChangeListener,
12
+ UsePersistedState,
13
+ } from '../lib/index.js'
package/esm/index.mjs ADDED
@@ -0,0 +1,10 @@
1
+ // Hand-written ES module wrapper over the single CJS build. A second compiled
2
+ // ESM copy would duplicate the module-level listener registries, so hooks
3
+ // loaded through one module system would stop seeing writes made through the
4
+ // other. Values are re-exported through property access because Node's named
5
+ // export detection for CJS is heuristic.
6
+ import cjs from '../lib/index.js'
7
+
8
+ export default cjs.default
9
+ export const createPersistedState = cjs.createPersistedState
10
+ export const createAsyncPersistedState = cjs.createAsyncPersistedState
@@ -0,0 +1 @@
1
+ export { local, sync, managed } from '../../lib/storages/browser-storage.js'
@@ -0,0 +1,5 @@
1
+ import cjs from '../../lib/storages/browser-storage.js'
2
+
3
+ export const local = cjs.local
4
+ export const sync = cjs.sync
5
+ export const managed = cjs.managed
@@ -0,0 +1 @@
1
+ export { local, sync, managed } from '../../lib/storages/chrome-storage.js'
@@ -0,0 +1,5 @@
1
+ import cjs from '../../lib/storages/chrome-storage.js'
2
+
3
+ export const local = cjs.local
4
+ export const sync = cjs.sync
5
+ export const managed = cjs.managed
@@ -0,0 +1 @@
1
+ export { default } from '../../lib/storages/local-storage.js'
@@ -0,0 +1,3 @@
1
+ import cjs from '../../lib/storages/local-storage.js'
2
+
3
+ export default cjs.default
@@ -0,0 +1 @@
1
+ export { default } from '../../lib/storages/session-storage.js'
@@ -0,0 +1,3 @@
1
+ import cjs from '../../lib/storages/session-storage.js'
2
+
3
+ export default cjs.default
@@ -1 +1 @@
1
- {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/@types/storage.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAAA;CAAE,KAAK,IAAI,CAAA;AAEvF,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,QAAQ,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACnD,cAAc,CAAC,QAAQ,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACtD,WAAW,CAAC,QAAQ,EAAE,qBAAqB,GAAG,OAAO,CAAC;CACvD;AAED,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAC5D,GAAG,EAAE,CAAC,KAAK,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAChD,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,IAAI,CAAC;IAC1C,SAAS,EAAE,kBAAkB,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,OAAO,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC,CAAC;IACrE,GAAG,EAAE,CAAC,KAAK,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,SAAS,EAAE,kBAAkB,CAAC;CAC/B"}
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/@types/storage.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACzB;AAED,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAAA;CAAE,KAAK,IAAI,CAAA;AAEvF,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,QAAQ,EAAE,qBAAqB,GAAG,IAAI,CAAA;IAClD,cAAc,CAAC,QAAQ,EAAE,qBAAqB,GAAG,IAAI,CAAA;IACrD,WAAW,CAAC,QAAQ,EAAE,qBAAqB,GAAG,OAAO,CAAA;CACtD;AAED,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IAC3D,GAAG,EAAE,CAAC,KAAK,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;IAC/C,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,IAAI,CAAA;IACzC,SAAS,EAAE,kBAAkB,CAAA;CAC9B;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,OAAO,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC,CAAA;IACpE,GAAG,EAAE,CAAC,KAAK,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACxD,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAClD,SAAS,EAAE,kBAAkB,CAAA;CAC9B"}
@@ -1,4 +1,4 @@
1
- import { AsyncStorage } from './@types/storage';
2
- import { PersistedState } from './@types/hook';
1
+ import type { AsyncStorage } from './@types/storage';
2
+ import type { PersistedState } from './@types/hook';
3
3
  export default function createAsyncPersistedState<S extends AsyncStorage>(storageKey: string, storage: S): [PersistedState, () => Promise<void>];
4
4
  //# sourceMappingURL=create-async-persisted-state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-async-persisted-state.d.ts","sourceRoot":"","sources":["../src/create-async-persisted-state.ts"],"names":[],"mappings":"AAOA,OAAO,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAC,cAAc,EAAoB,MAAM,eAAe,CAAA;AAE/D,MAAM,CAAC,OAAO,UAAU,yBAAyB,CAAC,CAAC,SAAS,YAAY,EACtE,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,CAAC,GACT,CAAC,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAuCvC"}
1
+ {"version":3,"file":"create-async-persisted-state.d.ts","sourceRoot":"","sources":["../src/create-async-persisted-state.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,KAAK,EAAE,cAAc,EAAqB,MAAM,eAAe,CAAA;AAEtE,MAAM,CAAC,OAAO,UAAU,yBAAyB,CAAC,CAAC,SAAS,YAAY,EACtE,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,CAAC,GACT,CAAC,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CA+IvC"}
@@ -1,38 +1,157 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
37
  };
5
38
  Object.defineProperty(exports, "__esModule", { value: true });
6
39
  exports.default = createAsyncPersistedState;
7
40
  const react_1 = require("react");
8
- const use_storage_handler_1 = __importDefault(require("./utils/use-storage-handler"));
41
+ const use_storage_handler_1 = __importStar(require("./utils/use-storage-handler"));
9
42
  const get_new_value_1 = __importDefault(require("./utils/get-new-value"));
10
43
  const get_new_item_1 = __importDefault(require("./utils/get-new-item"));
11
44
  const get_persisted_value_1 = __importDefault(require("./utils/get-persisted-value"));
12
45
  function createAsyncPersistedState(storageKey, storage) {
13
46
  const safeStorageKey = `persisted_state_hook:${storageKey}`;
47
+ // Every hook this factory makes lives in one entry, and storing a value means
48
+ // reading that entry, merging one key into it and writing all of it back, with
49
+ // a suspension point on either side of the merge. Left to overlap, a second
50
+ // writer merges into a snapshot taken before the first one landed and stores
51
+ // it: the first writer's key is gone from storage while its value is still on
52
+ // screen, and nothing reports the disagreement. It is the entry, not the hook,
53
+ // that has to be taken one at a time, so the chain belongs to the factory.
54
+ let entryWrites = Promise.resolve();
14
55
  const clear = () => {
15
- return storage.remove(safeStorageKey);
56
+ // Removing the entry changes it as much as storing does, so it takes its turn
57
+ // in the same chain. Outside it, a write already queued lands after the
58
+ // removal and brings back what was cleared - and "clear this data" is the one
59
+ // request that cannot be allowed to half happen.
60
+ const removal = entryWrites.then(() => storage.remove(safeStorageKey));
61
+ entryWrites = removal.catch(() => undefined);
62
+ return removal;
16
63
  };
17
- const usePersistedState = (key, initialValue) => {
18
- const [state, setState] = (0, react_1.useState)(initialValue);
19
- const setPersistedState = async (newState) => {
20
- const newValue = (0, get_new_value_1.default)(newState, state);
21
- setState(newValue);
64
+ const commitEntry = (key, newValue, pendingOwnWrites) => {
65
+ const write = entryWrites.then(async () => {
22
66
  const persistedItem = await storage.get(safeStorageKey);
23
- const newItem = (0, get_new_item_1.default)(key, persistedItem[safeStorageKey], newValue);
67
+ let newItem;
68
+ try {
69
+ newItem = (0, get_new_item_1.default)(key, persistedItem[safeStorageKey], newValue);
70
+ }
71
+ catch {
72
+ // Refused, and reported where it was refused. A write replaces the whole
73
+ // entry, so an entry that cannot be read is one no write can be built on
74
+ // without dropping every other hook's key; skipping leaves the bytes for
75
+ // a repair to reach. The caller keeps what it set, unpersisted.
76
+ return;
77
+ }
78
+ // Recorded before the write, because the backend may report it before the
79
+ // promise settles.
80
+ (0, use_storage_handler_1.recordOwnWrite)(pendingOwnWrites, newItem);
24
81
  await storage.set({ [safeStorageKey]: newItem });
25
- };
82
+ });
83
+ // The chain has to outlive a failed write, or one backend rejection stops
84
+ // every later write on this entry. The rejection itself is not swallowed: it
85
+ // stays on the promise handed back to the caller that asked for the write.
86
+ entryWrites = write.catch(() => undefined);
87
+ return write;
88
+ };
89
+ const usePersistedState = (key, initialValue) => {
90
+ const [state, setState] = (0, react_1.useState)(initialValue);
91
+ // The setter must resolve updater functions against the last value applied,
92
+ // not against the one captured by the render that created it. Reading the
93
+ // render closure collapses updates batched into a single event.
94
+ const latestValue = (0, react_1.useRef)(state);
95
+ // Whether anything has already put a value in place. A load that settles after
96
+ // the caller set one must not revert it, and no signal local to the load can
97
+ // answer this: the write it loses to happens outside the load entirely.
98
+ const hasAppliedValue = (0, react_1.useRef)(false);
99
+ const applyValue = (0, react_1.useCallback)((value) => {
100
+ latestValue.current = value;
101
+ hasAppliedValue.current = true;
102
+ setState(value);
103
+ }, []);
104
+ // The entries this hook has written and not yet seen reported back.
105
+ const pendingOwnWrites = (0, react_1.useRef)([]);
106
+ const setPersistedState = (0, react_1.useCallback)(async (newState) => {
107
+ const newValue = (0, get_new_value_1.default)(newState, latestValue.current);
108
+ // Applied before the write is even queued: the caller sees its value at
109
+ // once, and only the trip to storage waits its turn.
110
+ applyValue(newValue);
111
+ await commitEntry(key, newValue, pendingOwnWrites);
112
+ }, [key, applyValue]);
113
+ // As in `useState`, the value the load falls back to is the one given on the
114
+ // first render. Later identities of an inline object must not reload, or the
115
+ // effect re-runs on every render and never settles.
116
+ const mountInitialValue = (0, react_1.useRef)(initialValue);
117
+ // Subscribed before the load below, and the order is load-bearing: React runs
118
+ // effects in declaration order, so reading first would leave an interval
119
+ // between the read and the subscription in which a write belongs to neither
120
+ // and is lost. Reading last covers everything written before the subscription
121
+ // began, and the listener covers everything after.
122
+ (0, use_storage_handler_1.default)(key, safeStorageKey, applyValue, storage, initialValue, pendingOwnWrites);
26
123
  (0, react_1.useEffect)(() => {
27
- const setInitialValue = async () => {
28
- const persist = await storage.get(safeStorageKey);
29
- const persistedState = persist[safeStorageKey];
30
- const initialOrPersistedValue = (0, get_persisted_value_1.default)(key, initialValue, persistedState);
31
- setState(initialOrPersistedValue);
124
+ // Two separate questions, and one cell cannot hold both: whether this load
125
+ // is still the current one, which only the closure it belongs to can answer,
126
+ // and whether a value has been applied meanwhile, which outlives it. A load
127
+ // abandoned by a key change would otherwise read the flag its successor had
128
+ // just set, apply the previous key's value and shut the successor out. The
129
+ // second question is also what makes subscribing first safe: a value the
130
+ // listener delivers while the load is in flight is not overwritten by it.
131
+ let isCancelled = false;
132
+ hasAppliedValue.current = false;
133
+ const loadPersistedValue = async () => {
134
+ try {
135
+ const persist = await storage.get(safeStorageKey);
136
+ if (isCancelled || hasAppliedValue.current)
137
+ return;
138
+ applyValue((0, get_persisted_value_1.default)(key, mountInitialValue.current, persist[safeStorageKey]));
139
+ }
140
+ catch (err) {
141
+ // An extension backend rejects on a quota error or an invalidated
142
+ // extension context. Nothing awaits this load, so an unclaimed
143
+ // rejection terminates the process on Node 15+ and surfaces as an
144
+ // uncaught error in the browser. The initial value is already in
145
+ // state, so the mount stands on it and the failure is reported rather
146
+ // than swallowed, as the synchronous path reports its own.
147
+ console.error("use-persisted-state: Can't read value from storage", err);
148
+ }
149
+ };
150
+ loadPersistedValue();
151
+ return () => {
152
+ isCancelled = true;
32
153
  };
33
- setInitialValue();
34
- }, [initialValue, key]);
35
- (0, use_storage_handler_1.default)(key, safeStorageKey, setState, storage, initialValue);
154
+ }, [key, applyValue]);
36
155
  return [state, setPersistedState];
37
156
  };
38
157
  return [usePersistedState, clear];
@@ -1 +1 @@
1
- {"version":3,"file":"create-async-persisted-state.js","sourceRoot":"","sources":["../src/create-async-persisted-state.ts"],"names":[],"mappings":";;;;;AAUA,4CA0CC;AApDD,iCAAgD;AAEhD,sFAA2D;AAC3D,0EAA+C;AAC/C,wEAA6C;AAC7C,sFAA2D;AAK3D,SAAwB,yBAAyB,CAC/C,UAAkB,EAClB,OAAU;IAEV,MAAM,cAAc,GAAG,wBAAwB,UAAU,EAAE,CAAA;IAE3D,MAAM,KAAK,GAAG,GAAkB,EAAE;QAChC,OAAO,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;IACvC,CAAC,CAAA;IAED,MAAM,iBAAiB,GAAG,CAAI,GAAW,EAAE,YAA2B,EAAwB,EAAE;QAC9F,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,IAAA,gBAAQ,EAAI,YAAY,CAAC,CAAA;QAEnD,MAAM,iBAAiB,GAAG,KAAK,EAAE,QAAiC,EAAiB,EAAE;YACnF,MAAM,QAAQ,GAAG,IAAA,uBAAW,EAAI,QAAQ,EAAE,KAAK,CAAC,CAAA;YAEhD,QAAQ,CAAC,QAAQ,CAAC,CAAA;YAElB,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;YACvD,MAAM,OAAO,GAAG,IAAA,sBAAU,EAAI,GAAG,EAAE,aAAa,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,CAAA;YAE3E,MAAM,OAAO,CAAC,GAAG,CAAC,EAAC,CAAC,cAAc,CAAC,EAAE,OAAO,EAAC,CAAC,CAAA;QAChD,CAAC,CAAA;QAED,IAAA,iBAAS,EAAC,GAAG,EAAE;YACb,MAAM,eAAe,GAAG,KAAK,IAAI,EAAE;gBACjC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;gBACjD,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;gBAC9C,MAAM,uBAAuB,GAAG,IAAA,6BAAiB,EAAI,GAAG,EAAE,YAAY,EAAE,cAAc,CAAC,CAAA;gBAEvF,QAAQ,CAAC,uBAAuB,CAAC,CAAA;YACnC,CAAC,CAAA;YAED,eAAe,EAAE,CAAA;QACnB,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC,CAAA;QAEvB,IAAA,6BAAiB,EAAI,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,CAAC,CAAA;QAE1E,OAAO,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAA;IACnC,CAAC,CAAA;IAED,OAAO,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAA;AACnC,CAAC"}
1
+ {"version":3,"file":"create-async-persisted-state.js","sourceRoot":"","sources":["../src/create-async-persisted-state.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { Storage } from './@types/storage';
2
- import { PersistedState } from './@types/hook';
1
+ import type { Storage } from './@types/storage';
2
+ import type { PersistedState } from './@types/hook';
3
3
  export default function createPersistedState(storageKey: string, storage: Storage): [PersistedState, () => void];
4
4
  //# sourceMappingURL=create-persisted-state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-persisted-state.d.ts","sourceRoot":"","sources":["../src/create-persisted-state.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,OAAO,EAAC,MAAM,kBAAkB,CAAA;AACxC,OAAO,EAAC,cAAc,EAAoB,MAAM,eAAe,CAAA;AAO/D,MAAM,CAAC,OAAO,UAAU,oBAAoB,CAC1C,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,GACf,CAAC,cAAc,EAAE,MAAM,IAAI,CAAC,CAoC9B"}
1
+ {"version":3,"file":"create-persisted-state.d.ts","sourceRoot":"","sources":["../src/create-persisted-state.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAqB,MAAM,eAAe,CAAA;AAOtE,MAAM,CAAC,OAAO,UAAU,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,CAAC,cAAc,EAAE,MAAM,IAAI,CAAC,CA0E/G"}