11// ./create-storage.ts
22
33import { Accessor , createEffect , createSignal , onCleanup , onMount } from 'solid-js' ;
4-
5- export type StorageType = 'localStorage' | 'sessionStorage' ;
6-
7- export interface StorageProperties < T > {
8- /** Storage key */
9- key : string ;
10-
11- /** Default value that will be set if value is not found in storage */
12- defaultValue ?: T ;
13-
14- /** If set to true, value will be updated in createEffect after mount. Default value is true. */
15- getInitialValueInEffect ?: boolean ;
16-
17- /** Function to serialize value into string to be save in storage */
18- serialize ?: ( value : T ) => string ;
19-
20- /** Function to deserialize string value from storage to value */
21- deserialize ?: ( value : string | undefined ) => T ;
22- }
23-
24- function serializeJSON < T > ( value : T , hookName : string = 'use-local-storage' ) {
25- try {
26- return JSON . stringify ( value ) ;
27- } catch ( error ) {
28- throw new Error ( `bagon-hooks ${ hookName } : Failed to serialize the value` ) ;
29- }
30- }
31-
32- function deserializeJSON ( value : string | undefined ) {
33- try {
34- return value && JSON . parse ( value ) ;
35- } catch {
36- return value ;
37- }
38- }
39-
40- function createStorageHandler ( type : StorageType ) {
41- const getItem = ( key : string ) => {
42- try {
43- return window [ type ] . getItem ( key ) ;
44- } catch ( error ) {
45- console . warn ( 'use-local-storage: Failed to get value from storage, localStorage is blocked' ) ;
46- return null ;
47- }
48- } ;
49-
50- const setItem = ( key : string , value : string ) => {
51- try {
52- window [ type ] . setItem ( key , value ) ;
53- } catch ( error ) {
54- console . warn ( 'use-local-storage: Failed to set value to storage, localStorage is blocked' ) ;
55- }
56- } ;
57-
58- const removeItem = ( key : string ) => {
59- try {
60- window [ type ] . removeItem ( key ) ;
61- } catch ( error ) {
62- console . warn (
63- 'use-local-storage: Failed to remove value from storage, localStorage is blocked' ,
64- ) ;
65- }
66- } ;
67-
68- return { getItem, setItem, removeItem } ;
69- }
4+ import {
5+ _createStorageHandler ,
6+ _deserializeJSON ,
7+ _serializeJSON ,
8+ readLocalStorageValue ,
9+ readValue ,
10+ StorageProperties ,
11+ StorageType ,
12+ } from './utils' ;
13+
14+ export { readLocalStorageValue , readValue } ;
15+ export type { StorageProperties , StorageType } ;
7016
7117export function createStorage < T > ( type : StorageType , hookName : string ) {
7218 const eventName = type === 'localStorage' ? 'bagon-local-storage' : 'bagon-session-storage' ;
73- const { getItem, setItem, removeItem } = createStorageHandler ( type ) ;
19+ const { getItem, setItem, removeItem } = _createStorageHandler ( type ) ;
7420
7521 return function useStorage ( {
7622 key,
7723 defaultValue,
7824 getInitialValueInEffect = true ,
79- deserialize = deserializeJSON ,
80- serialize = ( value : T ) => serializeJSON ( value , hookName ) ,
25+ deserialize = _deserializeJSON ,
26+ serialize = ( value : T ) => _serializeJSON ( value , hookName ) ,
8127 } : StorageProperties < T > ) {
8228 const readStorageValue = ( skipStorage ?: boolean ) : T => {
8329 let storageBlockedOrSkipped ;
@@ -149,10 +95,10 @@ export function createStorage<T>(type: StorageType, hookName: string) {
14995 } ) ;
15096
15197 createEffect ( ( ) => {
152- if ( defaultValue !== undefined && value === undefined ) {
98+ if ( defaultValue !== undefined && value ( ) === undefined ) {
15399 setStorageValue ( defaultValue ) ;
154100 }
155- } , [ defaultValue , value , setStorageValue ] ) ;
101+ } ) ;
156102
157103 onMount ( ( ) => {
158104 const val = readStorageValue ( ) ;
@@ -167,32 +113,6 @@ export function createStorage<T>(type: StorageType, hookName: string) {
167113 } ;
168114}
169115
170- export function readValue ( type : StorageType ) {
171- const { getItem } = createStorageHandler ( type ) ;
172-
173- return function read < T > ( {
174- key,
175- defaultValue,
176- deserialize = deserializeJSON ,
177- } : StorageProperties < T > ) {
178- let storageBlockedOrSkipped ;
179-
180- try {
181- storageBlockedOrSkipped =
182- typeof window === 'undefined' || ! ( type in window ) || window [ type ] === null ;
183- } catch ( _e ) {
184- storageBlockedOrSkipped = true ;
185- }
186-
187- if ( storageBlockedOrSkipped ) {
188- return defaultValue as T ;
189- }
190-
191- const storageValue = getItem ( key ) ;
192- return storageValue !== null ? deserialize ( storageValue ) : ( defaultValue as T ) ;
193- } ;
194- }
195-
196116// ./use-local-storage.ts
197117
198118/**
@@ -201,8 +121,6 @@ export function readValue(type: StorageType) {
201121 *
202122 * It's also reactive across different pages.
203123 */
204- export function useLocalStorage < T = string > ( props : StorageProperties < T > ) {
124+ export function useLocalStorage < T > ( props : StorageProperties < T > ) {
205125 return createStorage < T > ( 'localStorage' , 'use-local-storage' ) ( props ) ;
206126}
207-
208- export const readLocalStorageValue = readValue ( 'localStorage' ) ;
0 commit comments