We use cookies to enhance your experience on the site
CodeWorlds

Plugins and Persistence

The NOVA LAB backup system ensures that critical data survives even a station restart. In Pinia, this role is fulfilled by plugins - extensions that add new capabilities to stores. The most important one is persistence - saving state to localStorage.

$subscribe - Listening for Changes

$subscribe
allows reacting to every state change:

1const store = useResourceStore()
2
3store.$subscribe((mutation, state) => {
4  console.log('Store changed:', mutation.storeId)
5  console.log('Type:', mutation.type) // 'direct' | '$patch'
6  console.log('New state:', state)
7
8  // Automatic save to localStorage
9  localStorage.setItem('resources', JSON.stringify(state))
10})

Subscribe options:

1store.$subscribe(
2  (mutation, state) => { /* ... */ },
3  { detached: true } // Survives component unmount
4)

$onAction - Observing Actions

1const store = useResourceStore()
2
3store.$onAction(({ name, args, after, onError }) => {
4  console.log(`Action started: ${name}`, args)
5
6  after((result) => {
7    console.log(`Action ${name} completed`, result)
8  })
9
10  onError((error) => {
11    console.error(`Action ${name} failed`, error)
12  })
13})

Persistence Plugin

The most popular plugin -

pinia-plugin-persistedstate
:

1npm install pinia-plugin-persistedstate

Configuration:

1// main.js
2import { createPinia } from 'pinia'
3import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
4
5const pinia = createPinia()
6pinia.use(piniaPluginPersistedstate)

Usage in a store:

1export const useSettingsStore = defineStore('settings', () => {
2  const theme = ref('dark')
3  const language = ref('en')
4
5  return { theme, language }
6}, {
7  persist: true // Entire state to localStorage
8})

Advanced Persist Configuration

1export const useAuthStore = defineStore('auth', () => {
2  const token = ref(null)
3  const user = ref(null)
4  const tempData = ref(null) // We don't want to save this
5
6  return { token, user, tempData }
7}, {
8  persist: {
9    // Only selected fields
10    paths: ['token'],
11
12    // Custom storage
13    storage: sessionStorage,
14
15    // Custom key
16    key: 'nova-lab-auth'
17  }
18})

Creating a Custom Plugin

A Pinia plugin is a function that receives a context with the store:

1// plugins/logger.js
2export function loggerPlugin({ store }) {
3  store.$subscribe((mutation, state) => {
4    console.log(`[${mutation.storeId}] ${mutation.type}`)
5  })
6
7  store.$onAction(({ name, store: s, args }) => {
8    console.log(`[${s.$id}] Action: ${name}`, args)
9  })
10}
11
12// main.js
13const pinia = createPinia()
14pinia.use(loggerPlugin)

Plugin Adding Properties

1function timestampPlugin({ store }) {
2  // Add lastUpdated to every store
3  store.lastUpdated = ref(null)
4
5  store.$subscribe(() => {
6    store.lastUpdated = new Date()
7  })
8}
Go to CodeWorlds