madapes

@aurora/codegen-zustand (0.3.3)

Published 2025-12-27 10:44:49 +00:00 by vlad

Installation

@aurora:registry=
npm install @aurora/codegen-zustand@0.3.3
"@aurora/codegen-zustand": "0.3.3"

About this package

@aurora/codegen-zustand

Zustand store generator for Aurora - generates type-safe stores from API schemas.

Overview

Generates Zustand stores for managing frontend state:

  • Type-safe state management
  • Async actions for API calls
  • Optimistic updates
  • DevTools integration

Installation

bun add zustand
bun add -D @aurora/codegen-zustand

Usage

Generated via @aurora/codegen:

aurora codegen

Generated Stores

Example Store

// generated/stores/OrderStore.ts
import { create } from "zustand";
import { AuroraClient } from "./client";

interface OrderState {
  orders: Record<string, Order>;
  loading: boolean;
  error: Error | null;
  
  // Actions
  fetchOrder: (orderId: string) => Promise<void>;
  createOrder: (order: CreateOrderInput) => Promise<void>;
  updateOrder: (orderId: string, updates: Partial<Order>) => Promise<void>;
  deleteOrder: (orderId: string) => Promise<void>;
  setError: (error: Error | null) => void;
}

export const useOrderStore = create<OrderState>((set, get) => ({
  orders: {},
  loading: false,
  error: null,

  fetchOrder: async (orderId: string) => {
    set({ loading: true, error: null });
    
    try {
      const client = new AuroraClient({
        baseUrl: import.meta.env.VITE_API_URL,
        token: localStorage.getItem("token") || "",
      });
      
      const order = await client.getOrder({ orderId });
      
      set(state => ({
        orders: { ...state.orders, [orderId]: order },
        loading: false,
      }));
    } catch (error) {
      set({ error: error as Error, loading: false });
      throw error;
    }
  },

  createOrder: async (order: CreateOrderInput) => {
    set({ loading: true, error: null });
    
    try {
      const client = new AuroraClient({
        baseUrl: import.meta.env.VITE_API_URL,
        token: localStorage.getItem("token") || "",
      });
      
      const result = await client.createOrder({}, order);
      
      set(state => ({
        orders: {
          ...state.orders,
          [result.orderId]: { ...order, orderId: result.orderId },
        },
        loading: false,
      }));
    } catch (error) {
      set({ error: error as Error, loading: false });
      throw error;
    }
  },

  updateOrder: async (orderId: string, updates: Partial<Order>) => {
    // Optimistic update
    const previousOrder = get().orders[orderId];
    set(state => ({
      orders: {
        ...state.orders,
        [orderId]: { ...state.orders[orderId], ...updates },
      },
    }));

    try {
      const client = new AuroraClient({
        baseUrl: import.meta.env.VITE_API_URL,
        token: localStorage.getItem("token") || "",
      });
      
      await client.updateOrder({ orderId }, updates);
    } catch (error) {
      // Revert on error
      set(state => ({
        orders: {
          ...state.orders,
          [orderId]: previousOrder,
        },
        error: error as Error,
      }));
      throw error;
    }
  },

  deleteOrder: async (orderId: string) => {
    // Optimistic update
    const previousOrders = get().orders;
    set(state => {
      const newOrders = { ...state.orders };
      delete newOrders[orderId];
      return { orders: newOrders };
    });

    try {
      const client = new AuroraClient({
        baseUrl: import.meta.env.VITE_API_URL,
        token: localStorage.getItem("token") || "",
      });
      
      await client.deleteOrder({ orderId });
    } catch (error) {
      // Revert on error
      set({ orders: previousOrders, error: error as Error });
      throw error;
    }
  },

  setError: (error: Error | null) => {
    set({ error });
  },
}));

Usage Examples

Reading State

import { useOrderStore } from "./generated/stores/OrderStore";

function OrderList() {
  const orders = useOrderStore(state => state.orders);
  const loading = useOrderStore(state => state.loading);
  const error = useOrderStore(state => state.error);

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <ul>
      {Object.values(orders).map(order => (
        <li key={order.orderId}>
          {order.status} - {order.amount}
        </li>
      ))}
    </ul>
  );
}

Calling Actions

import { useOrderStore } from "./generated/stores/OrderStore";

function CreateOrderForm() {
  const createOrder = useOrderStore(state => state.createOrder);
  const loading = useOrderStore(state => state.loading);

  const handleSubmit = async (e: FormEvent) => {
    e.preventDefault();
    const formData = new FormData(e.target as HTMLFormElement);
    
    await createOrder({
      userId: formData.get("userId") as string,
      amount: Number(formData.get("amount")),
      currency: formData.get("currency") as string,
    });
  };

  return (
    <form onSubmit={handleSubmit}>
      <input name="userId" placeholder="User ID" />
      <input name="amount" type="number" placeholder="Amount" />
      <button type="submit" disabled={loading}>
        {loading ? "Creating..." : "Create Order"}
      </button>
    </form>
  );
}

Selectors

import { useOrderStore } from "./generated/stores/OrderStore";

// Selector for filtered orders
const pendingOrders = useOrderStore(state =>
  Object.values(state.orders).filter(order => order.status === "pending")
);

// Selector with multiple states
const { loading, error } = useOrderStore(state => ({
  loading: state.loading,
  error: state.error,
}));

DevTools

import { devtools } from "zustand/middleware";

export const useOrderStore = create<OrderState>()(
  devtools((set, get) => ({
    // ...store implementation
  }), {
    name: "OrderStore",
  })
);

License

MIT

Dependencies

Dependencies

ID Version
@aurora/codegen 0.3.3
zustand ^4.5.0
Details
npm
2025-12-27 10:44:49 +00:00
13
latest
4.5 KiB
Assets (1)
Versions (3) View all
0.3.3 2025-12-27
0.3.2 2025-12-27
0.3.1 2025-12-27