Hone logo
Hone
Problems

Vue Store Reset with Pinia

This challenge focuses on implementing a robust reset functionality for your Vue application's state management using Pinia. A store reset is crucial for scenarios like user logout, clearing temporary data, or debugging, ensuring a clean slate for your application's data.

Problem Description

Your task is to create a reusable mechanism in Vue using Pinia to reset a specific store to its initial state. This means that after calling the reset function, the store should revert to the values it had when it was first initialized.

Key Requirements:

  • Initial State Capture: The mechanism must be able to capture the initial state of a Pinia store.
  • Reset Functionality: A function should be available to trigger the reset of a store to its captured initial state.
  • Reusability: The solution should be general enough to be applied to any Pinia store without significant modification.
  • TypeScript Support: The solution must be implemented in TypeScript, leveraging type safety.

Expected Behavior:

When a store reset is triggered, all state properties of that store should revert to their original values as defined when the store was first created. Actions and getters should remain functional after the reset.

Edge Cases to Consider:

  • Stores with complex nested objects or arrays in their state.
  • Stores that might be initialized with asynchronous data. (While the direct reset might not re-fetch async data, it should revert to the state before any potential async operations modified it, or to a defined "empty" initial state).

Examples

Let's consider a simple UserStore with a name and age.

Example 1: Basic Reset

Input:

Imagine a UserStore defined as:

import { defineStore } from 'pinia';

interface UserState {
  name: string | null;
  age: number | null;
}

export const useUserStore = defineStore('user', {
  state: (): UserState => ({
    name: 'Alice',
    age: 30,
  }),
  actions: {
    setName(newName: string) {
      this.name = newName;
    },
    setAge(newAge: number) {
      this.age = newAge;
    },
  },
  getters: {
    displayName: (state) => state.name ? `User: ${state.name}` : 'No user logged in',
  },
});

Scenario:

  1. Initialize the store: const userStore = useUserStore();
  2. Modify the state: userStore.setName('Bob'); userStore.setAge(35);
  3. Trigger the reset: resetStore(userStore);

Output (after reset):

The userStore state will be:

{
  name: 'Alice',
  age: 30,
}

The displayName getter will reflect the reset state.

Explanation:

The reset function successfully reverted the name and age properties back to their initial values ('Alice' and 30).

Example 2: Reset with Null/Undefined Initial State

Input:

Consider a SettingsStore initialized with potentially null values:

import { defineStore } from 'pinia';

interface SettingsState {
  theme: string | null;
  fontSize: number | null;
}

export const useSettingsStore = defineStore('settings', {
  state: (): SettingsState => ({
    theme: null,
    fontSize: null,
  }),
  actions: {
    setTheme(newTheme: string | null) {
      this.theme = newTheme;
    },
    setFontSize(newSize: number | null) {
      this.fontSize = newSize;
    },
  },
});

Scenario:

  1. Initialize the store: const settingsStore = useSettingsStore();
  2. Modify the state: settingsStore.setTheme('dark'); settingsStore.setFontSize(16);
  3. Trigger the reset: resetStore(settingsStore);

Output (after reset):

The settingsStore state will be:

{
  theme: null,
  fontSize: null,
}

Explanation:

The reset correctly restored the theme and fontSize to their initial null values.

Constraints

  • The solution should be compatible with Pinia v2.
  • The solution should not require external libraries beyond Pinia and Vue.
  • The reset mechanism should be performant and not introduce significant overhead for typical store sizes.
  • The solution must be implemented using TypeScript.

Notes

  • Think about how you can generically capture the initial state of any Pinia store.
  • Consider the immutability of state when storing the initial state.
  • The reset function will likely need to be a standalone function or a utility that can accept a Pinia store instance.
  • How would you handle state properties that are objects or arrays? Ensure a deep copy is made if necessary to avoid unintended mutations.
Loading editor...
typescript