init
This commit is contained in:
5
stores/index.js
Normal file
5
stores/index.js
Normal file
@@ -0,0 +1,5 @@
|
||||
const { sessionStore } = require('./modules/session')
|
||||
|
||||
module.exports = {
|
||||
sessionStore
|
||||
}
|
||||
128
stores/modules/session.js
Normal file
128
stores/modules/session.js
Normal file
@@ -0,0 +1,128 @@
|
||||
const { STORAGE_KEYS } = require('../../config/constants')
|
||||
|
||||
const EMPTY_STATE = Object.freeze({
|
||||
isLoggedIn: false,
|
||||
token: '',
|
||||
userInfo: null,
|
||||
permissions: []
|
||||
})
|
||||
|
||||
function cloneSessionState(state) {
|
||||
return {
|
||||
isLoggedIn: Boolean(state.token),
|
||||
token: state.token || '',
|
||||
userInfo: state.userInfo ? { ...state.userInfo } : null,
|
||||
permissions: Array.isArray(state.permissions) ? [...state.permissions] : []
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeSession(payload = {}) {
|
||||
return cloneSessionState({
|
||||
...EMPTY_STATE,
|
||||
...payload
|
||||
})
|
||||
}
|
||||
|
||||
function createStorageAdapter() {
|
||||
return {
|
||||
get(key) {
|
||||
if (typeof wx === 'undefined' || typeof wx.getStorageSync !== 'function') {
|
||||
return undefined
|
||||
}
|
||||
|
||||
try {
|
||||
return wx.getStorageSync(key)
|
||||
} catch (error) {
|
||||
return undefined
|
||||
}
|
||||
},
|
||||
set(key, value) {
|
||||
if (typeof wx === 'undefined' || typeof wx.setStorageSync !== 'function') {
|
||||
return
|
||||
}
|
||||
|
||||
wx.setStorageSync(key, value)
|
||||
},
|
||||
remove(key) {
|
||||
if (typeof wx === 'undefined' || typeof wx.removeStorageSync !== 'function') {
|
||||
return
|
||||
}
|
||||
|
||||
wx.removeStorageSync(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} SessionPayload
|
||||
* @property {string} token
|
||||
* @property {Record<string, any>|null} userInfo
|
||||
* @property {string[]} permissions
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {{
|
||||
* storage?: {get(key: string): any, set(key: string, value: any): void, remove(key: string): void},
|
||||
* storageKey?: string
|
||||
* }} [options]
|
||||
*/
|
||||
function createSessionStore(options = {}) {
|
||||
const storage = options.storage || createStorageAdapter()
|
||||
const storageKey = options.storageKey || STORAGE_KEYS.session
|
||||
const listeners = new Set()
|
||||
let state = normalizeSession()
|
||||
|
||||
function emitChange() {
|
||||
const snapshot = cloneSessionState(state)
|
||||
listeners.forEach(listener => listener(snapshot))
|
||||
}
|
||||
|
||||
return {
|
||||
getState() {
|
||||
return cloneSessionState(state)
|
||||
},
|
||||
hydrate() {
|
||||
const cachedSession = storage.get(storageKey)
|
||||
|
||||
if (cachedSession) {
|
||||
state = normalizeSession(cachedSession)
|
||||
emitChange()
|
||||
}
|
||||
|
||||
return this.getState()
|
||||
},
|
||||
/**
|
||||
* @param {SessionPayload} payload
|
||||
*/
|
||||
setSession(payload) {
|
||||
state = normalizeSession(payload)
|
||||
storage.set(storageKey, {
|
||||
token: state.token,
|
||||
userInfo: state.userInfo,
|
||||
permissions: state.permissions
|
||||
})
|
||||
emitChange()
|
||||
return this.getState()
|
||||
},
|
||||
clearSession() {
|
||||
state = normalizeSession()
|
||||
storage.remove(storageKey)
|
||||
emitChange()
|
||||
return this.getState()
|
||||
},
|
||||
subscribe(listener) {
|
||||
listeners.add(listener)
|
||||
|
||||
return () => {
|
||||
listeners.delete(listener)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const sessionStore = createSessionStore()
|
||||
|
||||
module.exports = {
|
||||
createSessionStore,
|
||||
sessionStore
|
||||
}
|
||||
Reference in New Issue
Block a user