Skip to content

Instantly share code, notes, and snippets.

@wilcorrea
Last active November 11, 2024 22:58
Show Gist options
  • Save wilcorrea/f361dd6ca3b0d32091e4c5c574632569 to your computer and use it in GitHub Desktop.
Save wilcorrea/f361dd6ca3b0d32091e4c5c574632569 to your computer and use it in GitHub Desktop.
/* eslint-disable @typescript-eslint/no-explicit-any */
import { reactive } from 'vue'
type StoreMutation<StoreState> = (state: StoreState, ...args: any[]) => void
type StoreMutations<StoreState> = Record<string, StoreMutation<StoreState>>
type Store<StoreState> = {
state: StoreState
commit (mutation: string, ...args: any[]): void
}
export enum StoreStorageType {
SESSION = 'session',
FOREVER = 'forever'
}
/**
* @param {string} name
* @param {string} type
*/
const recover = (name: string, type: StoreStorageType) => {
if (type === StoreStorageType.FOREVER) {
return JSON.parse(window.localStorage.getItem(name) ?? '{}')
}
return JSON.parse(window.sessionStorage.getItem(name) ?? '{}')
}
/**
* @param {string} name
* @param {*} state
* @param {string} type
*/
const persist = (name: string, state: unknown, type: StoreStorageType) => {
if (type === StoreStorageType.FOREVER) {
window.localStorage.setItem(name, JSON.stringify(state))
return
}
window.sessionStorage.setItem(name, JSON.stringify(state))
}
/**
* Helper to create dynamic stores
* Useful to reduce boilerplate.. simple and functional
* Besides the store is standalone and works fine in a lot of places
* @param name
* @param {StoreState} states
* @param {Record<string, StoreMutation<StoreState>>} mutations
* @param {StoreStorageType} type
*/
export function createStore<StoreState extends object> (
name: string,
states: StoreState,
mutations: StoreMutations<StoreState>,
type: StoreStorageType = StoreStorageType.SESSION
): Store<StoreState> {
const state = reactive<StoreState>(states) as StoreState
const previous = recover(name, type)
Object.assign(state, previous)
return {
state,
commit (mutation: string, ...args: any[]) {
const handler = mutations[mutation]
if (!handler) {
throw new Error(`Invalid mutation '${mutation}'`)
}
handler(state, ...args)
persist(name, state, type)
}
}
}
import { createStore, StoreStorageType } from '@store'
import { AuthSession as Session } from 'whatever'
const store = createStore<Session>('AuthStore', states, mutations, StoreStorageType.FOREVER)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment