Pinia Persistent Storage via AT Protocol for Open Web Desktop
1import { createPersistedStatePlugin } from 'pinia-plugin-persistedstate-2' 2import { deepEqual } from '@owdproject/core/runtime/utils/utilCommon' 3import { defineNuxtPlugin, useRuntimeConfig } from 'nuxt/app' 4import { toRaw } from 'vue' 5import { usePinia, useRouter, useAtproto, useAgent } from '#imports' 6 7import localforage from 'localforage/src/localforage.js' 8import { 9 putAtprotoApplicationState, 10 parseAtprotoStoreKey, 11 loadActorDesktopStateMap 12} from './utils/utilAtprotoApplicationStates' 13 14export default defineNuxtPlugin({ 15 name: 'owd-plugin-atproto-persistence', 16 dependsOn: ['owd-plugin-atproto'], 17 async setup() { 18 const pinia = usePinia() 19 const atproto = useAtproto() 20 const runtimeConfig = useRuntimeConfig() 21 const router = useRouter() 22 23 let states = {} 24 let actorDid = undefined 25 26 if (router.currentRoute.value.params.did) { 27 actorDid = router.currentRoute.value.params.did 28 } else { 29 if ( 30 runtimeConfig.public.atprotoPersistence && 31 runtimeConfig.public.atprotoPersistence.loadOwnerDesktopOnMounted 32 ) { 33 actorDid = runtimeConfig.public.atprotoDesktop.owner.did 34 } 35 } 36 37 if (actorDid) { 38 states = await loadActorDesktopStateMap(runtimeConfig.public.atprotoDesktop.owner.did) 39 } 40 41 pinia.use( 42 createPersistedStatePlugin({ 43 persist: false, 44 storage: { 45 getItem: async (piniaKey) => { 46 47 if (states.hasOwnProperty(piniaKey)) { 48 return JSON.stringify(states[piniaKey]) 49 } 50 51 return localforage.getItem(piniaKey) 52 }, 53 setItem: async (piniaKey, piniaValue) => { 54 const previousPiniaValue = await localforage.getItem(piniaKey) 55 await localforage.setItem(piniaKey, piniaValue) 56 57 const atprotoTargetRecord = parseAtprotoStoreKey(piniaKey) 58 59 if (!atprotoTargetRecord || !atproto.isLogged()) { 60 return piniaValue 61 } 62 63 const { collection, rkey } = atprotoTargetRecord 64 65 if (deepEqual(toRaw(piniaValue), toRaw(previousPiniaValue))) { 66 return piniaValue 67 } 68 69 const agent = useAgent('private') 70 71 return putAtprotoApplicationState( 72 agent, 73 agent.assertDid, 74 collection, 75 rkey, 76 JSON.parse(piniaValue), 77 ) 78 }, 79 removeItem: async (key) => { 80 await localforage.removeItem(key) 81 }, 82 }, 83 }), 84 ) 85 }, 86})