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|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 }