export function persistStore< T extends object = {}, R extends ActionReturn = {}>(
name: string,
options: StoreOption<T, R>,
): [provider: ParentComponent, useStore: () => BaseStore<T, R>] {
const { action, state, persist: persistOption } = options
const initalState = typeof state === 'function' ? state() : state
const [store, setStore] = createStore<T>(initalState, { name })
const ctxData = { store, ...action(setStore) }
const ctx = createContext(ctxData, { name: `ctx_${name}` })
const option = normalizePersistOption(name, persistOption)
onMount(() => {
if (!option) {
return
}
const { debug, key, serializer: { deserialize, serialize }, storage } = option
const stored = storage.getItem(key)
try {
if (stored) {
setStore(deserialize(stored))
debug && console.log(`[$store - ${key}]: read from persisted, value: ${stored}`)
} else {
storage.setItem(option.key, serialize(store))
debug && console.log(`[$store - ${key}]: no persisted data, initialize`)
}
} catch (e) {
debug && console.error(`[$store - ${key}]: ${e}`)
}
createEffect(on(() => deepTrack(store), () => {
debug && console.log(`[$store - ${key}]: update to ${JSON.stringify(store)}`)
storage.setItem(option.key, serialize(unwrap(store)))
}))
})
return [
(props: ParentProps): JSX.Element =>
createComponent(ctx.Provider, {
value: ctxData,
get children() {
return props.children
},
}),
() => useContext(ctx),
]
}
export function persistStore< T extends object = {}, R extends ActionReturn = {}>(
name: string,
options: StoreOption<T, R>,
): [provider: ParentComponent, useStore: () => BaseStore<T, R>] {
const { action, state, persist: persistOption } = options
const initalState = typeof state === 'function' ? state() : state
const [store, setStore] = createStore<T>(initalState, { name })
const ctxData = { store, ...action(setStore) }
const ctx = createContext(ctxData, { name: `ctx_${name}` })
const option = normalizePersistOption(name, persistOption)
onMount(() => {
if (!option) {
return
}
const { debug, key, serializer: { deserialize, serialize }, storage } = option
const stored = storage.getItem(key)
try {
if (stored) {
setStore(deserialize(stored))
debug && console.log(`[$store - ${key}]: read from persisted, value: ${stored}`)
} else {
storage.setItem(option.key, serialize(store))
debug && console.log(`[$store - ${key}]: no persisted data, initialize`)
}
} catch (e) {
debug && console.error(`[$store - ${key}]: ${e}`)
}
createEffect(on(() => deepTrack(store), () => {
debug && console.log(`[$store - ${key}]: update to ${JSON.stringify(store)}`)
storage.setItem(option.key, serialize(unwrap(store)))
}))
})
return [
(props: ParentProps): JSX.Element =>
createComponent(ctx.Provider, {
value: ctxData,
get children() {
return props.children
},
}),
() => useContext(ctx),
]
}