npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@dbs-portal/core-store

v1.0.0

Published

Global state management with Zustand for DBS Portal

Readme

@dbs-portal/core-store

Enhanced global state management with Zustand for DBS Portal, featuring immutable updates with Immer, runtime validation with Zod, and comprehensive middleware support.

Features

🔧 Core Capabilities

  • Zustand-based state management with TypeScript support
  • Immer integration for immutable state updates
  • Zod validation for runtime type checking and data integrity
  • Persistence middleware with customizable storage options
  • DevTools integration for development debugging
  • Backward compatibility with existing store implementations

🎯 Enhanced Features

  • State validation with custom error handling
  • Async action utilities with automatic loading states
  • Computed values (derived state) with memoization
  • Selector utilities for optimized component subscriptions
  • Middleware composition for extensible functionality

Installation

This package is part of the DBS Portal monorepo and includes all necessary dependencies:

# Dependencies are automatically managed
yarn install

Quick Start

Basic Enhanced Store

import { createEnhancedStore } from '@dbs-portal/core-store'
import { z } from 'zod'

// Define validation schema
const CounterSchema = z.object({
  count: z.number(),
  step: z.number().positive()
})

type CounterState = z.infer<typeof CounterSchema> & {
  increment: () => void
  decrement: () => void
  setStep: (step: number) => void
  reset: () => void
}

// Create enhanced store
export const useCounterStore = createEnhancedStore<CounterState>(
  (set) => ({
    count: 0,
    step: 1,
    
    // Immer allows direct mutations
    increment: () => set((state) => {
      state.count += state.step
    }),
    
    decrement: () => set((state) => {
      state.count -= state.step
    }),
    
    setStep: (step: number) => set((state) => {
      state.step = step
    }),
    
    reset: () => set((state) => {
      state.count = 0
      state.step = 1
    })
  }),
  {
    name: 'Counter Store',
    immer: true,
    validation: {
      schema: CounterSchema,
      enabled: process.env.NODE_ENV === 'development'
    },
    persist: {
      key: 'counter-store',
      options: {
        partialize: (state) => ({ count: state.count })
      }
    }
  }
)

Using the Enhanced Root Store

import { useEnhancedStore } from '@dbs-portal/core-store'

function MyComponent() {
  const { 
    theme, 
    setTheme, 
    notifications, 
    success,
    isLoading 
  } = useEnhancedStore()

  const handleThemeChange = () => {
    setTheme(theme === 'light' ? 'dark' : 'light')
  }

  const showNotification = () => {
    success('Success!', 'Operation completed successfully')
  }

  return (
    <div>
      <button onClick={handleThemeChange}>
        Current theme: {theme}
      </button>
      <button onClick={showNotification}>
        Show Notification
      </button>
      {isLoading && <div>Loading...</div>}
    </div>
  )
}

Advanced Usage

State Validation

import { createEnhancedStore } from '@dbs-portal/core-store'
import { z } from 'zod'

const UserSchema = z.object({
  id: z.string(),
  name: z.string().min(1),
  email: z.string().email(),
  role: z.enum(['admin', 'user', 'guest'])
})

const store = createEnhancedStore(
  (set) => ({
    users: [],
    addUser: (user) => set((state) => {
      state.users.push(user)
    })
  }),
  {
    validation: {
      schema: z.object({
        users: z.array(UserSchema)
      }),
      enabled: true,
      onError: (error) => {
        console.error('Validation failed:', error)
        // Handle validation errors
      }
    }
  }
)

Async Actions with Loading States

import { createAsyncAction } from '@dbs-portal/core-store'

const useAsyncActions = {
  fetchData: createAsyncAction(useMyStore, 'fetchData')
}

// Usage
const handleFetch = async () => {
  await useAsyncActions.fetchData(async () => {
    const response = await fetch('/api/data')
    const data = await response.json()
    
    useMyStore.getState().setData(data)
  })
}

Computed Values

import { createComputed } from '@dbs-portal/core-store'

const useDoubledCount = createComputed(
  useCounterStore,
  (state) => state.count * 2
)

const useFilteredUsers = createComputed(
  useUserStore,
  (state) => state.users.filter(user => user.isActive),
  (a, b) => a.length === b.length // Custom equality function
)

Custom Middleware

import { createStoreWithMiddleware } from '@dbs-portal/core-store'

const store = createStoreWithMiddleware(
  (set, get) => ({
    // Your state and actions
  }),
  {
    immer: true,
    persist: {
      key: 'my-store',
      options: {
        version: 1,
        migrate: (persistedState, version) => {
          // Handle migrations
          return persistedState
        }
      }
    },
    devtools: {
      name: 'My Store',
      enabled: process.env.NODE_ENV === 'development'
    },
    validation: {
      schema: MySchema,
      enabled: true
    }
  }
)

API Reference

Core Functions

createEnhancedStore<T>(initializer, options)

Creates an enhanced store with middleware support.

Parameters:

  • initializer: Store state and actions initializer function
  • options: Configuration options for middleware

Options:

  • name: Store name for debugging
  • immer: Enable immer middleware (default: true)
  • persist: Persistence configuration
  • devtools: DevTools configuration
  • validation: State validation configuration
  • middleware: Custom middleware array

createStoreWithMiddleware<T>(initializer, middlewareConfig)

Alternative API for creating stores with middleware configuration.

createEnhancedRootStore(config)

Creates the enhanced root store with all application state.

Utility Functions

createSelectors(useStore)

Creates typed selectors for store properties.

createActions(useStore)

Extracts action functions from store.

createComputed(useStore, selector, equalityFn?)

Creates computed/derived values with memoization.

createAsyncAction(useStore, key)

Creates async action wrapper with loading state management.

Migration Guide

From Legacy Store

The enhanced store is fully backward compatible. You can gradually migrate:

// Legacy usage (still works)
import { useStore } from '@dbs-portal/core-store'

// Enhanced usage (new features)
import { useEnhancedStore } from '@dbs-portal/core-store'

Adding Validation

// Before
const store = createStore(initializer)

// After
const store = createEnhancedStore(initializer, {
  validation: {
    schema: MySchema,
    enabled: process.env.NODE_ENV === 'development'
  }
})

Best Practices

  1. Use Immer for Complex Updates: Leverage immer's draft mutations for cleaner code
  2. Validate in Development: Enable validation during development for better DX
  3. Partition Persistence: Only persist necessary state to reduce storage usage
  4. Use Computed Values: Create derived state with createComputed for performance
  5. Handle Async Actions: Use createAsyncAction for consistent loading states

TypeScript Support

Full TypeScript support with:

  • Type-safe state and actions
  • Inferred types from Zod schemas
  • Generic store creation
  • Typed selectors and computed values

Performance

  • Tree-shaking: Only bundle used middleware
  • Selective subscriptions: Use selectors to prevent unnecessary re-renders
  • Memoized computations: Computed values are automatically memoized
  • Optimized persistence: Configurable state partitioning

License

MIT - Part of the DBS Portal monorepo.