Rewrote sync_microsoft_skills.py (v4) to use each SKILL.md's frontmatter 'name' field as the flat directory name under skills/, replacing the nested skills/official/microsoft/<lang>/<category>/<service>/ hierarchy. This fixes CI failures caused by the indexing, validation, and catalog scripts expecting skills/<id>/SKILL.md (depth 1). Changes: - Rewrite scripts/sync_microsoft_skills.py for flat output with collision detection - Update scripts/tests/inspect_microsoft_repo.py for flat name mapping - Update scripts/tests/test_comprehensive_coverage.py for name uniqueness checks - Delete skills/official/ nested directory - Add 129 Microsoft skills as flat directories (e.g. skills/azure-mgmt-botservice-dotnet/) - Move attribution files to docs/ (LICENSE-MICROSOFT, microsoft-skills-attribution.json) - Rebuild skills_index.json, CATALOG.md, README.md (845 total skills)
69 lines
1.7 KiB
Markdown
69 lines
1.7 KiB
Markdown
---
|
|
name: zustand-store-ts
|
|
description: Create Zustand stores with TypeScript, subscribeWithSelector middleware, and proper state/action separation. Use when building React state management, creating global stores, or implementing reactive state patterns with Zustand.
|
|
---
|
|
|
|
# Zustand Store
|
|
|
|
Create Zustand stores following established patterns with proper TypeScript types and middleware.
|
|
|
|
## Quick Start
|
|
|
|
Copy the template from [assets/template.ts](assets/template.ts) and replace placeholders:
|
|
- `{{StoreName}}` → PascalCase store name (e.g., `Project`)
|
|
- `{{description}}` → Brief description for JSDoc
|
|
|
|
## Always Use subscribeWithSelector
|
|
|
|
```typescript
|
|
import { create } from 'zustand';
|
|
import { subscribeWithSelector } from 'zustand/middleware';
|
|
|
|
export const useMyStore = create<MyStore>()(
|
|
subscribeWithSelector((set, get) => ({
|
|
// state and actions
|
|
}))
|
|
);
|
|
```
|
|
|
|
## Separate State and Actions
|
|
|
|
```typescript
|
|
export interface MyState {
|
|
items: Item[];
|
|
isLoading: boolean;
|
|
}
|
|
|
|
export interface MyActions {
|
|
addItem: (item: Item) => void;
|
|
loadItems: () => Promise<void>;
|
|
}
|
|
|
|
export type MyStore = MyState & MyActions;
|
|
```
|
|
|
|
## Use Individual Selectors
|
|
|
|
```typescript
|
|
// Good - only re-renders when `items` changes
|
|
const items = useMyStore((state) => state.items);
|
|
|
|
// Avoid - re-renders on any state change
|
|
const { items, isLoading } = useMyStore();
|
|
```
|
|
|
|
## Subscribe Outside React
|
|
|
|
```typescript
|
|
useMyStore.subscribe(
|
|
(state) => state.selectedId,
|
|
(selectedId) => console.log('Selected:', selectedId)
|
|
);
|
|
```
|
|
|
|
## Integration Steps
|
|
|
|
1. Create store in `src/frontend/src/store/`
|
|
2. Export from `src/frontend/src/store/index.ts`
|
|
3. Add tests in `src/frontend/src/store/*.test.ts`
|