@mr.dj2u/knowledge 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/content/checklists/ship-test-loop.md +16 -0
  2. package/dist/content/checklists/unified-agent-bundle-validation.md +8 -0
  3. package/dist/content/examples/ship-test-loop.md +13 -0
  4. package/dist/content/examples/unified-agent-bundle-bootstrap.md +8 -0
  5. package/dist/content/guides/animation-performance.md +30 -0
  6. package/dist/content/guides/post-create-onboarding.md +113 -0
  7. package/dist/content/patterns/api/api-routes.md +314 -0
  8. package/dist/content/patterns/api/error-handling.md +311 -0
  9. package/dist/content/patterns/database/drizzle-schema.md +280 -0
  10. package/dist/content/patterns/database/migrations.md +365 -0
  11. package/dist/content/patterns/database/query-organization.md +537 -0
  12. package/dist/content/patterns/database/relations.md +450 -0
  13. package/dist/content/patterns/deployment/build-configuration.md +452 -0
  14. package/dist/content/patterns/deployment/ci-cd-patterns.md +448 -0
  15. package/dist/content/patterns/deployment/environment-config.md +380 -0
  16. package/dist/content/patterns/deployment/hosting-setup.md +425 -0
  17. package/dist/content/patterns/project/configuration-patterns.md +459 -0
  18. package/dist/content/patterns/project/documentation-org.md +506 -0
  19. package/dist/content/patterns/project/folder-structure.md +398 -0
  20. package/dist/content/patterns/project/library-exports.md +465 -0
  21. package/dist/content/patterns/project/monorepo-structure.md +500 -0
  22. package/dist/content/patterns/routing/dynamic-routes.md +221 -0
  23. package/dist/content/patterns/routing/file-based-routing.md +186 -0
  24. package/dist/content/patterns/routing/route-groups.md +429 -0
  25. package/dist/content/patterns/state/persistence-middleware.md +521 -0
  26. package/dist/content/patterns/state/selector-hooks.md +538 -0
  27. package/dist/content/patterns/state/store-organization.md +539 -0
  28. package/dist/content/patterns/state/zustand-patterns.md +348 -0
  29. package/dist/content/patterns/styling/component-styling.md +468 -0
  30. package/dist/content/patterns/styling/responsive-patterns.md +398 -0
  31. package/dist/content/patterns/styling/theme-configuration.md +426 -0
  32. package/dist/content/patterns/styling/uniwind-setup.md +412 -0
  33. package/dist/content/prompts/continue-development.md +27 -0
  34. package/dist/content/prompts/create-expo-super-stack.md +29 -0
  35. package/dist/content/prompts/fix-seo.md +29 -0
  36. package/dist/content/prompts/onboard-new-expo-app.md +11 -0
  37. package/dist/content/prompts/prepare-deploy.md +29 -0
  38. package/dist/content/prompts/project-research-plan.md +29 -0
  39. package/dist/content/prompts/review-expo-project.md +29 -0
  40. package/dist/content/prompts/run-doctor.md +30 -0
  41. package/dist/content/prompts/ship-test-loop.md +24 -0
  42. package/dist/content/reference/create-expo-stack-uniwind.md +29 -0
  43. package/dist/content/reference/doctor-dogfood.md +42 -0
  44. package/dist/content/reference/mcp-sdk-transport.md +30 -0
  45. package/dist/content/reference/package-ci-patterns.md +24 -0
  46. package/dist/content/reference/reference-repo-evacuation.md +31 -0
  47. package/dist/content/resource-index.json +67 -0
  48. package/dist/content/rules/app-folder-architecture.md +13 -0
  49. package/dist/content/rules/env-hygiene.md +9 -0
  50. package/dist/content/rules/seo-metadata.md +7 -0
  51. package/dist/content/rules/ssr-safety.md +9 -0
  52. package/dist/content/skills/api-routes.md +33 -0
  53. package/dist/content/skills/continue-development.md +31 -0
  54. package/dist/content/skills/debugging.md +31 -0
  55. package/dist/content/skills/deployment.md +32 -0
  56. package/dist/content/skills/dev-server-management.md +31 -0
  57. package/dist/content/skills/env-vars.md +32 -0
  58. package/dist/content/skills/expo-router-architecture.md +33 -0
  59. package/dist/content/skills/expo-ssr-safety.md +32 -0
  60. package/dist/content/skills/plugin-creation.md +41 -0
  61. package/dist/content/skills/production-server-patterns.md +31 -0
  62. package/dist/content/skills/project-onboarding.md +31 -0
  63. package/dist/content/skills/research-plan-intake.md +31 -0
  64. package/dist/content/skills/seo-metadata.md +31 -0
  65. package/dist/content/skills/super-stack-startup.md +31 -0
  66. package/dist/content/skills/uniwind-theming.md +32 -0
  67. package/dist/index.d.ts +46 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +369 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/patterns/index.d.ts +78 -0
  72. package/dist/patterns/index.d.ts.map +1 -0
  73. package/dist/patterns/index.js +264 -0
  74. package/dist/patterns/index.js.map +1 -0
  75. package/dist/prompts/index.d.ts +35 -0
  76. package/dist/prompts/index.d.ts.map +1 -0
  77. package/dist/prompts/index.js +270 -0
  78. package/dist/prompts/index.js.map +1 -0
  79. package/dist/skills/index.d.ts +3 -0
  80. package/dist/skills/index.d.ts.map +1 -0
  81. package/dist/skills/index.js +2 -0
  82. package/dist/skills/index.js.map +1 -0
  83. package/package.json +50 -0
@@ -0,0 +1,348 @@
1
+ # Zustand State Management
2
+
3
+ ## Description
4
+
5
+ Zustand provides lightweight atomic state management with TypeScript type inference, optional persistence middleware, and selector hooks for optimal re-renders. Stores are created without providers, maintaining flat structure with computed properties derived from state, and AsyncStorage/localStorage integration for cross-platform persistence.
6
+
7
+ ## When to Use
8
+
9
+ **Use Zustand** for:
10
+ - ✅ Global application state (auth, user, settings)
11
+ - ✅ Feature-level state with persistence needs
12
+ - ✅ State requiring type-safe selectors
13
+ - ✅ Atomic updates without action dispatchers
14
+
15
+ ## Code Example
16
+
17
+ ### Basic Store with Persistence
18
+
19
+ ```typescript
20
+ // File: src/store/authStore.ts
21
+ import { create } from 'zustand';
22
+ import { persist, createJSONStorage } from 'zustand/middleware';
23
+ import AsyncStorage from '@react-native-async-storage/async-storage';
24
+
25
+ export interface AuthState {
26
+ // State
27
+ user: User | null;
28
+ profile: Profile | null;
29
+ session: Session | null;
30
+ isLoggedIn: boolean;
31
+ loading: boolean;
32
+
33
+ // Computed properties (derived state)
34
+ get isAdult(): boolean;
35
+ get canUseSocialFeatures(): boolean;
36
+ get isVip(): boolean;
37
+
38
+ // Actions
39
+ setUser: (user: User | null) => void;
40
+ setProfile: (profile: Profile | null) => void;
41
+ signOut: () => Promise<void>;
42
+ initializeAuth: () => Promise<void>;
43
+ }
44
+
45
+ export const useAuthStore = create<AuthState>()(
46
+ persist(
47
+ (set, get) => ({
48
+ // Initial state
49
+ user: null,
50
+ profile: null,
51
+ session: null,
52
+ isLoggedIn: false,
53
+ loading: true,
54
+
55
+ // Computed properties
56
+ get isAdult(): boolean {
57
+ const profile = get().profile;
58
+ if (!profile?.dateOfBirth) return false;
59
+ const age = calculateAge(profile.dateOfBirth);
60
+ return age >= 18;
61
+ },
62
+
63
+ get canUseSocialFeatures(): boolean {
64
+ return get().isLoggedIn && get().isAdult;
65
+ },
66
+
67
+ get isVip(): boolean {
68
+ return get().profile?.vipStatus === true;
69
+ },
70
+
71
+ // Actions
72
+ setUser: (user) => set({ user, isLoggedIn: !!user }),
73
+
74
+ setProfile: (profile) => set({ profile }),
75
+
76
+ signOut: async () => {
77
+ await supabase.auth.signOut();
78
+ set({
79
+ user: null,
80
+ profile: null,
81
+ session: null,
82
+ isLoggedIn: false,
83
+ });
84
+ },
85
+
86
+ initializeAuth: async () => {
87
+ set({ loading: true });
88
+ try {
89
+ const { data } = await supabase.auth.getSession();
90
+ if (data.session?.user) {
91
+ const profile = await fetchProfile(data.session.user.id);
92
+ set({
93
+ user: data.session.user,
94
+ profile,
95
+ session: data.session,
96
+ isLoggedIn: true,
97
+ loading: false,
98
+ });
99
+ } else {
100
+ set({ loading: false });
101
+ }
102
+ } catch (error) {
103
+ console.error('Auth init error:', error);
104
+ set({ loading: false });
105
+ }
106
+ },
107
+ }),
108
+ {
109
+ name: 'auth-storage',
110
+ storage: createJSONStorage(() => AsyncStorage),
111
+ // Only persist specific fields
112
+ partialize: (state) => ({
113
+ user: state.user,
114
+ profile: state.profile,
115
+ session: state.session,
116
+ }),
117
+ }
118
+ )
119
+ );
120
+ ```
121
+
122
+ **From:** PokePages/src/store/authStore.ts, core-monorepo pattern
123
+
124
+ ### Selector Hooks for Performance
125
+
126
+ ```typescript
127
+ // ✅ GOOD - Custom selector hooks prevent unnecessary re-renders
128
+
129
+ // Only re-renders when user email changes
130
+ export const useUserEmail = () =>
131
+ useAuthStore((state) => state.user?.email);
132
+
133
+ // Only re-renders when isAdult computed property changes
134
+ export const useIsAdult = () =>
135
+ useAuthStore((state) => state.isAdult);
136
+
137
+ // Multi-selector in single hook
138
+ export const useUserWithProfile = () =>
139
+ useAuthStore((state) => ({
140
+ user: state.user,
141
+ profile: state.profile,
142
+ isLoggedIn: state.isLoggedIn,
143
+ }));
144
+
145
+ // Usage in component
146
+ function UserCard() {
147
+ const email = useUserEmail();
148
+ const { profile } = useUserWithProfile();
149
+
150
+ // Only re-renders when email or profile object reference changes
151
+ return <Text>{email}</Text>;
152
+ }
153
+ ```
154
+
155
+ ### Store for Favorites with Toggle
156
+
157
+ ```typescript
158
+ // File: src/store/favoriteFeaturesStore.ts
159
+ import { create } from 'zustand';
160
+ import { persist, createJSONStorage } from 'zustand/middleware';
161
+ import AsyncStorage from '@react-native-async-storage/async-storage';
162
+
163
+ export interface FavoritesState {
164
+ favorites: Record<string, boolean>;
165
+ toggleFavorite: (key: string) => void;
166
+ isFavorite: (key: string) => boolean;
167
+ }
168
+
169
+ export const useFavoritesStore = create<FavoritesState>()(
170
+ persist(
171
+ (set, get) => ({
172
+ favorites: {},
173
+
174
+ toggleFavorite: (key) =>
175
+ set((state) => ({
176
+ favorites: {
177
+ ...state.favorites,
178
+ [key]: !state.favorites[key],
179
+ },
180
+ })),
181
+
182
+ isFavorite: (key) => !!get().favorites[key],
183
+ }),
184
+ {
185
+ name: 'favorites-storage',
186
+ storage: createJSONStorage(() => AsyncStorage),
187
+ }
188
+ )
189
+ );
190
+
191
+ // Selector hooks
192
+ export const useIsFavorite = (key: string) =>
193
+ useFavoritesStore((state) => state.isFavorite(key));
194
+
195
+ export const useToggleFavorite = () =>
196
+ useFavoritesStore((state) => state.toggleFavorite);
197
+
198
+ // Component usage
199
+ function FavoriteButton({ pageKey }: { pageKey: string }) {
200
+ const isFavorite = useIsFavorite(pageKey);
201
+ const toggle = useToggleFavorite();
202
+
203
+ return (
204
+ <Pressable onPress={() => toggle(pageKey)}>
205
+ <Text>{isFavorite ? '⭐' : '☆'}</Text>
206
+ </Pressable>
207
+ );
208
+ }
209
+ ```
210
+
211
+ **From:** PokePages/src/store/favoriteFeaturesStore.ts
212
+
213
+ ## Configuration
214
+
215
+ ### Cross-Platform Storage Setup
216
+
217
+ ```typescript
218
+ // File: src/utils/createCrossPlatformStorage.ts
219
+ import { Platform } from 'react-native';
220
+ import AsyncStorage from '@react-native-async-storage/async-storage';
221
+ import { createJSONStorage } from 'zustand/middleware';
222
+
223
+ export function createCrossPlatformStorage() {
224
+ if (Platform.OS === 'web') {
225
+ return createJSONStorage(() => ({
226
+ getItem: (key) => localStorage.getItem(key),
227
+ setItem: (key, value) => localStorage.setItem(key, value),
228
+ removeItem: (key) => localStorage.removeItem(key),
229
+ }));
230
+ }
231
+
232
+ return createJSONStorage(() => AsyncStorage);
233
+ }
234
+
235
+ // Use in stores
236
+ export const useStore = create<State>()(
237
+ persist(
238
+ (set) => ({ /* state */ }),
239
+ {
240
+ storage: createCrossPlatformStorage(),
241
+ }
242
+ )
243
+ );
244
+ ```
245
+
246
+ ## Best Practices
247
+
248
+ ### ✅ DO
249
+
250
+ 1. **Use selector hooks** to prevent unnecessary re-renders
251
+ ```typescript
252
+ // ✅ GOOD - only subscribes to email
253
+ const email = useAuthStore((state) => state.user?.email);
254
+
255
+ // ❌ BAD - subscribes to entire store
256
+ const { user, profile, session, ... } = useAuthStore();
257
+ ```
258
+
259
+ 2. **Keep stores flat** — avoid nested objects
260
+ ```typescript
261
+ // ✅ GOOD - flat structure
262
+ userId: '123'
263
+ userName: 'alice'
264
+ userEmail: 'alice@example.com'
265
+
266
+ // ❌ BAD - nested (causes unnecessary re-renders)
267
+ user: { id: '123', name: 'alice', email: '...' }
268
+ ```
269
+
270
+ 3. **Use computed properties (getters)** for derived state
271
+ ```typescript
272
+ get isAdult(): boolean {
273
+ return calculateAge(get().profile?.dateOfBirth) >= 18;
274
+ }
275
+ ```
276
+
277
+ 4. **Partial persistence** — only persist necessary fields
278
+ ```typescript
279
+ partialize: (state) => ({
280
+ user: state.user,
281
+ theme: state.theme,
282
+ // Don't persist: loading, errors, temporary UI state
283
+ })
284
+ ```
285
+
286
+ 5. **Split stores** by domain/feature
287
+ ```typescript
288
+ useAuthStore() // auth + user
289
+ useThemeStore() // app theme
290
+ useFavoritesStore() // favorites
291
+ ```
292
+
293
+ ### ❌ DON'T
294
+
295
+ 1. **Don't use context** for everything
296
+ ```typescript
297
+ // ❌ AVOID - causes re-renders of all consumers
298
+ <UserContext.Provider value={{ user, setUser, ... }}>
299
+
300
+ // ✅ USE - only subscribed components re-render
301
+ const user = useUserStore((state) => state.user);
302
+ ```
303
+
304
+ 2. **Don't persist state that changes frequently**
305
+ ```typescript
306
+ // ❌ BAD - persists on every keystroke
307
+ persist((set) => ({
308
+ searchQuery: '',
309
+ setSearchQuery: (q) => set({ searchQuery: q })
310
+ }))
311
+
312
+ // ✅ GOOD - only persist final state
313
+ onChangeText={(q) => dispatch(setSearchQuery(q))} // local only
314
+ ```
315
+
316
+ 3. **Don't store derived data** that can be computed
317
+ ```typescript
318
+ // ❌ BAD - will get out of sync
319
+ user: { id: '1', name: 'alice', email: 'alice@ex.com' }
320
+ userDisplayName: 'alice' // Duplicate!
321
+
322
+ // ✅ GOOD - compute on demand
323
+ get userDisplayName() {
324
+ return get().user?.name;
325
+ }
326
+ ```
327
+
328
+ 4. **Don't forget to handle undefined** from selectors
329
+ ```typescript
330
+ // ❌ RISKY
331
+ const email = useAuthStore((state) => state.user?.email);
332
+ return <Text>{email}</Text>; // Could be undefined
333
+
334
+ // ✅ SAFE
335
+ const email = useAuthStore((state) => state.user?.email);
336
+ return <Text>{email || 'No email'}</Text>;
337
+ ```
338
+
339
+ ## Related Patterns
340
+
341
+ - [Store Organization](./store-organization.md) — Multi-store patterns
342
+ - [Persistence Middleware](./persistence-middleware.md) — AsyncStorage integration
343
+ - [Selector Hooks](./selector-hooks.md) — Performance optimization
344
+
345
+ ---
346
+
347
+ *Pattern extracted from production repositories: PokePages, core-monorepo, time2pay*
348
+ *Files: PokePages/src\store\authStore.ts, favoriteFeaturesStore.ts*