Hone logo
Hone
Problems

Global State Management with Vue and TypeScript

Managing application state effectively is crucial for complex Vue.js applications. This challenge focuses on implementing a simple global state management solution using Vue's reactivity system and TypeScript for type safety. You'll create a reusable GlobalState class that allows components to access and modify shared state across the application.

Problem Description

You are tasked with creating a GlobalState class in TypeScript that acts as a central repository for application-wide state. This class should:

  1. Hold State: Maintain a set of properties representing the global state. These properties should be reactive, meaning changes to them trigger updates in components that depend on them.
  2. Provide Accessors & Mutators: Offer methods to access and modify the state. Accessors should return the current value of a state property, and mutators should update the state property while ensuring reactivity.
  3. Be Reusable: The class should be designed to be easily instantiated with different initial state configurations.
  4. Type Safety: Utilize TypeScript to ensure type safety for the state properties and methods.

Expected Behavior:

  • Components should be able to access the global state through the GlobalState instance.
  • Modifying the state through the mutator methods should trigger updates in all components that are observing the state.
  • The GlobalState class should be flexible enough to handle different types of state properties (numbers, strings, booleans, objects, arrays).

Edge Cases to Consider:

  • Handling initial state values correctly.
  • Ensuring that state updates are reactive and trigger component re-renders.
  • Preventing direct modification of the state properties to maintain control and reactivity.

Examples

Example 1:

Input:
GlobalState initialized with: { count: 0, message: "Hello" }

Component A: Displays count and message.
Component B: Displays count and message.

Component A calls: globalState.incrementCount()

Output:
Component A and Component B both update to display: count: 1, message: "Hello"
Explanation:
The `incrementCount()` method updates the `count` property in the `GlobalState` instance.  Vue's reactivity system detects this change and re-renders both components that are observing the `count` property.

Example 2:

Input:
GlobalState initialized with: { user: { name: "Guest", loggedIn: false } }

Component A: Displays user.name and user.loggedIn.

Component B: Calls globalState.login("Alice")

Output:
Component A updates to display: user.name: "Alice", user.loggedIn: true
Explanation:
The `login()` method updates the `user` object within the `GlobalState`. Vue's reactivity system detects changes within nested objects and re-renders Component A.

Example 3:

Input:
GlobalState initialized with: { items: [] }

Component A: Calls globalState.addItem("Apple")

Output:
GlobalState.items becomes: ["Apple"]
Explanation:
The `addItem()` method adds a new item to the `items` array within the `GlobalState`. Vue's reactivity system detects changes to arrays and re-renders any components observing the `items` array.

Constraints

  • Language: TypeScript
  • Framework: Vue.js (using the reactivity system - no external state management libraries like Vuex or Pinia)
  • Performance: The solution should be reasonably performant. Avoid unnecessary re-renders.
  • State Size: Assume the global state will contain a moderate number of properties (less than 20).
  • Mutability: Directly modifying the state properties (e.g., globalState.count = 5;) should not trigger reactivity. Use the provided mutator methods.

Notes

  • Consider using Vue's reactive() or ref() functions to create reactive state properties within the GlobalState class.
  • Think about how to design the mutator methods to ensure they trigger reactivity when updating the state.
  • Focus on creating a clean, reusable, and type-safe solution.
  • You don't need to create a full-fledged Vue application. Just focus on the GlobalState class itself and demonstrate its usage with simple examples. You can use console.log to simulate component updates for demonstration purposes.
Loading editor...
typescript