agentic-team-templates 0.9.2 → 0.10.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.
@@ -0,0 +1,203 @@
1
+ # JavaScript Performance
2
+
3
+ Expert-level performance patterns for JavaScript across browser and server environments.
4
+
5
+ ## Profiling First
6
+
7
+ Never optimize without data. Always profile before and after changes.
8
+
9
+ ```typescript
10
+ // Node.js profiling
11
+ // node --prof app.js
12
+ // node --prof-process isolate-*.log
13
+
14
+ // Browser: use Performance API
15
+ performance.mark('operation-start');
16
+ doExpensiveWork();
17
+ performance.mark('operation-end');
18
+ performance.measure('operation', 'operation-start', 'operation-end');
19
+ const duration = performance.getEntriesByName('operation')[0]!.duration;
20
+ ```
21
+
22
+ ## V8 Optimization Patterns
23
+
24
+ ### Monomorphic Functions
25
+
26
+ ```typescript
27
+ // Good: Consistent argument shapes (monomorphic — V8 optimizes)
28
+ function processItem(item: { id: string; value: number }) {
29
+ return item.id + item.value;
30
+ }
31
+
32
+ items.forEach(processItem); // All same shape — fast
33
+
34
+ // Bad: Polymorphic — different shapes deoptimize
35
+ function processAnything(item: any) {
36
+ return item.id + item.value;
37
+ }
38
+ // Called with { id, value }, { id, value, extra }, { id, value, other }
39
+ // V8 can't optimize — megamorphic IC
40
+ ```
41
+
42
+ ### Hidden Classes
43
+
44
+ ```typescript
45
+ // Good: Initialize all properties in the same order
46
+ class Point {
47
+ x: number;
48
+ y: number;
49
+ constructor(x: number, y: number) {
50
+ this.x = x; // Always x first
51
+ this.y = y; // Always y second
52
+ }
53
+ }
54
+
55
+ // Bad: Conditional property assignment
56
+ function createPoint(x: number, y: number, z?: number) {
57
+ const p: any = {};
58
+ p.x = x;
59
+ if (z) p.z = z; // Different hidden class!
60
+ p.y = y;
61
+ return p;
62
+ }
63
+ ```
64
+
65
+ ## Data Structures
66
+
67
+ ```typescript
68
+ // Map vs Object
69
+ // Use Map when: keys are dynamic, non-string keys, frequent add/delete
70
+ const cache = new Map<string, CacheEntry>();
71
+
72
+ // Use Object when: static shape, string keys, serialization needed
73
+ const config = { host: 'localhost', port: 3000 };
74
+
75
+ // Set vs Array for membership tests
76
+ // O(1) lookup vs O(n)
77
+ const allowedIds = new Set(['a', 'b', 'c']);
78
+ if (allowedIds.has(id)) { ... }
79
+
80
+ // TypedArrays for numeric data
81
+ const buffer = new Float64Array(1000);
82
+ // 8x more memory efficient than number[]
83
+ // Faster iteration for numeric operations
84
+ ```
85
+
86
+ ## Memory Management
87
+
88
+ ```typescript
89
+ // Avoid memory leaks in event listeners
90
+ class Component {
91
+ #controller = new AbortController();
92
+
93
+ mount() {
94
+ window.addEventListener('resize', this.#onResize, {
95
+ signal: this.#controller.signal,
96
+ });
97
+ }
98
+
99
+ unmount() {
100
+ this.#controller.abort(); // Removes all listeners at once
101
+ }
102
+
103
+ #onResize = () => { ... };
104
+ }
105
+
106
+ // WeakMap for metadata on objects without preventing GC
107
+ const metadata = new WeakMap<object, Metadata>();
108
+
109
+ function annotate(obj: object, data: Metadata) {
110
+ metadata.set(obj, data); // Won't prevent obj from being GC'd
111
+ }
112
+
113
+ // Avoid closures that capture large scopes
114
+ // Bad: Entire scope captured
115
+ function createHandler(largeData: BigObject[]) {
116
+ const id = largeData[0]!.id; // Only need id
117
+ return () => console.log(largeData); // Captures entire array!
118
+ }
119
+
120
+ // Good: Capture only what's needed
121
+ function createHandler(largeData: BigObject[]) {
122
+ const id = largeData[0]!.id;
123
+ return () => console.log(id); // Only captures id
124
+ }
125
+ ```
126
+
127
+ ## Async Performance
128
+
129
+ ```typescript
130
+ // Batch concurrent operations with limits
131
+ async function processInBatches<T, R>(
132
+ items: T[],
133
+ fn: (item: T) => Promise<R>,
134
+ batchSize: number,
135
+ ): Promise<R[]> {
136
+ const results: R[] = [];
137
+ for (let i = 0; i < items.length; i += batchSize) {
138
+ const batch = items.slice(i, i + batchSize);
139
+ const batchResults = await Promise.all(batch.map(fn));
140
+ results.push(...batchResults);
141
+ }
142
+ return results;
143
+ }
144
+
145
+ // Use streams for large data — don't load everything into memory
146
+ // See node-patterns.md for stream examples
147
+
148
+ // requestAnimationFrame for visual updates (browser)
149
+ function animateValue(element: HTMLElement, from: number, to: number) {
150
+ const start = performance.now();
151
+ const duration = 300;
152
+
153
+ const tick = (now: number) => {
154
+ const progress = Math.min((now - start) / duration, 1);
155
+ const value = from + (to - from) * progress;
156
+ element.textContent = String(Math.round(value));
157
+ if (progress < 1) requestAnimationFrame(tick);
158
+ };
159
+
160
+ requestAnimationFrame(tick);
161
+ }
162
+ ```
163
+
164
+ ## Bundle Size (Client-Side)
165
+
166
+ ```typescript
167
+ // Dynamic imports for code splitting
168
+ const AdminPanel = lazy(() => import('./AdminPanel.js'));
169
+
170
+ // Tree-shakeable exports (named, not default)
171
+ export { validateEmail } from './validators.js';
172
+
173
+ // Avoid barrel file re-exports for large packages
174
+ // Bad: import { Button } from './components'; // Pulls everything
175
+ // Good: import { Button } from './components/Button.js';
176
+
177
+ // Check bundle impact before adding dependencies
178
+ // npx bundlephobia <package-name>
179
+
180
+ // Prefer native APIs over libraries
181
+ // Use Intl.DateTimeFormat instead of moment/date-fns for formatting
182
+ // Use structuredClone instead of lodash.cloneDeep
183
+ // Use URL instead of query-string
184
+ // Use AbortController instead of custom cancellation
185
+ // Use crypto.randomUUID() instead of uuid
186
+ ```
187
+
188
+ ## Anti-Patterns
189
+
190
+ ```typescript
191
+ // Never: Premature optimization
192
+ // Measure first, optimize the bottleneck, measure again
193
+
194
+ // Never: Micro-optimizations that harm readability
195
+ // arr[arr.length - 1] vs arr.at(-1) — the difference is negligible
196
+
197
+ // Never: Caching without invalidation strategy
198
+ // Every cache needs a TTL, max size, or explicit invalidation
199
+
200
+ // Never: Synchronous operations blocking the event loop
201
+ // Use worker threads for CPU work
202
+ // Use async I/O for file/network operations
203
+ ```
@@ -0,0 +1,249 @@
1
+ # React Patterns
2
+
3
+ Expert-level React patterns for building production UI applications.
4
+
5
+ ## Component Design
6
+
7
+ ### Server Components First (React 19+)
8
+
9
+ ```tsx
10
+ // Default: Server Components — no 'use client' directive
11
+ // They run on the server, have zero client bundle cost
12
+ async function ProjectList() {
13
+ const projects = await db.projects.findMany();
14
+ return (
15
+ <ul>
16
+ {projects.map(p => <ProjectCard key={p.id} project={p} />)}
17
+ </ul>
18
+ );
19
+ }
20
+
21
+ // Only add 'use client' when you need:
22
+ // - useState, useEffect, useReducer
23
+ // - Browser APIs (window, document)
24
+ // - Event handlers (onClick, onChange)
25
+ // - Custom hooks that use client features
26
+ 'use client';
27
+ function SearchInput({ onSearch }: { onSearch: (q: string) => void }) {
28
+ const [query, setQuery] = useState('');
29
+ return <input value={query} onChange={e => setQuery(e.target.value)} />;
30
+ }
31
+ ```
32
+
33
+ ### Composition Patterns
34
+
35
+ ```tsx
36
+ // Compound components for related UI
37
+ function Tabs({ children }: { children: React.ReactNode }) {
38
+ const [active, setActive] = useState(0);
39
+ return (
40
+ <TabsContext.Provider value={{ active, setActive }}>
41
+ {children}
42
+ </TabsContext.Provider>
43
+ );
44
+ }
45
+
46
+ Tabs.List = function TabList({ children }: { children: React.ReactNode }) { ... };
47
+ Tabs.Panel = function TabPanel({ children, index }: { children: React.ReactNode; index: number }) { ... };
48
+
49
+ // Usage — clean, declarative API
50
+ <Tabs>
51
+ <Tabs.List>
52
+ <Tab>Overview</Tab>
53
+ <Tab>Details</Tab>
54
+ </Tabs.List>
55
+ <Tabs.Panel index={0}>Overview content</Tabs.Panel>
56
+ <Tabs.Panel index={1}>Details content</Tabs.Panel>
57
+ </Tabs>
58
+ ```
59
+
60
+ ### Render Props and Children as Function
61
+
62
+ ```tsx
63
+ // For maximum flexibility in rendering
64
+ interface DataLoaderProps<T> {
65
+ load: () => Promise<T>;
66
+ children: (data: T) => React.ReactNode;
67
+ fallback?: React.ReactNode;
68
+ }
69
+
70
+ function DataLoader<T>({ load, children, fallback }: DataLoaderProps<T>) {
71
+ const data = use(load());
72
+ return <>{children(data)}</>;
73
+ }
74
+
75
+ // Usage
76
+ <Suspense fallback={<Spinner />}>
77
+ <DataLoader load={fetchUsers}>
78
+ {users => <UserList users={users} />}
79
+ </DataLoader>
80
+ </Suspense>
81
+ ```
82
+
83
+ ## Hooks
84
+
85
+ ### Custom Hook Patterns
86
+
87
+ ```tsx
88
+ // Encapsulate complex state logic
89
+ function useOptimisticUpdate<T>(
90
+ current: T,
91
+ updateFn: (value: T) => Promise<void>,
92
+ ) {
93
+ const [optimistic, setOptimistic] = useState(current);
94
+ const [isPending, startTransition] = useTransition();
95
+
96
+ const update = (next: T) => {
97
+ setOptimistic(next);
98
+ startTransition(async () => {
99
+ try {
100
+ await updateFn(next);
101
+ } catch {
102
+ setOptimistic(current); // Rollback
103
+ }
104
+ });
105
+ };
106
+
107
+ return [optimistic, update, isPending] as const;
108
+ }
109
+
110
+ // Debounced value hook
111
+ function useDebouncedValue<T>(value: T, delayMs: number): T {
112
+ const [debounced, setDebounced] = useState(value);
113
+
114
+ useEffect(() => {
115
+ const timer = setTimeout(() => setDebounced(value), delayMs);
116
+ return () => clearTimeout(timer);
117
+ }, [value, delayMs]);
118
+
119
+ return debounced;
120
+ }
121
+ ```
122
+
123
+ ### Hook Rules (Enforced, Not Suggested)
124
+
125
+ - Only call hooks at the top level — never inside conditions, loops, or nested functions
126
+ - Only call hooks from React function components or custom hooks
127
+ - Custom hooks must start with `use`
128
+ - Always include correct dependencies in `useEffect`/`useMemo`/`useCallback`
129
+
130
+ ## State Management
131
+
132
+ ```tsx
133
+ // Rule: Use the simplest tool that works
134
+ // 1. useState — local state
135
+ // 2. useReducer — complex local state with actions
136
+ // 3. Context — low-frequency shared state (theme, auth, locale)
137
+ // 4. External store (Zustand, Jotai) — high-frequency shared state
138
+
139
+ // useReducer for complex state machines
140
+ type Action =
141
+ | { type: 'FETCH_START' }
142
+ | { type: 'FETCH_SUCCESS'; payload: User[] }
143
+ | { type: 'FETCH_ERROR'; error: Error };
144
+
145
+ interface State {
146
+ status: 'idle' | 'loading' | 'success' | 'error';
147
+ data: User[];
148
+ error: Error | null;
149
+ }
150
+
151
+ const reducer = (state: State, action: Action): State => {
152
+ switch (action.type) {
153
+ case 'FETCH_START':
154
+ return { ...state, status: 'loading', error: null };
155
+ case 'FETCH_SUCCESS':
156
+ return { status: 'success', data: action.payload, error: null };
157
+ case 'FETCH_ERROR':
158
+ return { ...state, status: 'error', error: action.error };
159
+ }
160
+ };
161
+ ```
162
+
163
+ ## Performance
164
+
165
+ ```tsx
166
+ // React Compiler (React 19+) handles most memoization automatically
167
+ // Only manually optimize when profiling shows a bottleneck
168
+
169
+ // Virtualize large lists
170
+ import { useVirtualizer } from '@tanstack/react-virtual';
171
+
172
+ function VirtualList({ items }: { items: Item[] }) {
173
+ const parentRef = useRef<HTMLDivElement>(null);
174
+ const virtualizer = useVirtualizer({
175
+ count: items.length,
176
+ getScrollElement: () => parentRef.current,
177
+ estimateSize: () => 50,
178
+ });
179
+
180
+ return (
181
+ <div ref={parentRef} style={{ overflow: 'auto', height: '500px' }}>
182
+ <div style={{ height: virtualizer.getTotalSize() }}>
183
+ {virtualizer.getVirtualItems().map(row => (
184
+ <div key={row.key} style={{
185
+ position: 'absolute',
186
+ top: row.start,
187
+ height: row.size,
188
+ }}>
189
+ <ItemRow item={items[row.index]!} />
190
+ </div>
191
+ ))}
192
+ </div>
193
+ </div>
194
+ );
195
+ }
196
+ ```
197
+
198
+ ## Error Boundaries
199
+
200
+ ```tsx
201
+ // Every route and major feature section needs an error boundary
202
+ 'use client';
203
+
204
+ interface ErrorBoundaryProps {
205
+ children: React.ReactNode;
206
+ fallback: (error: Error, reset: () => void) => React.ReactNode;
207
+ }
208
+
209
+ class ErrorBoundary extends React.Component<ErrorBoundaryProps, { error: Error | null }> {
210
+ state = { error: null as Error | null };
211
+
212
+ static getDerivedStateFromError(error: Error) {
213
+ return { error };
214
+ }
215
+
216
+ render() {
217
+ if (this.state.error) {
218
+ return this.props.fallback(this.state.error, () => this.setState({ error: null }));
219
+ }
220
+ return this.props.children;
221
+ }
222
+ }
223
+ ```
224
+
225
+ ## Anti-Patterns
226
+
227
+ ```tsx
228
+ // Never: useEffect for derived state
229
+ // Bad
230
+ const [fullName, setFullName] = useState('');
231
+ useEffect(() => {
232
+ setFullName(`${firstName} ${lastName}`);
233
+ }, [firstName, lastName]);
234
+ // Good
235
+ const fullName = `${firstName} ${lastName}`;
236
+
237
+ // Never: Object/array literals as default props (new reference every render)
238
+ // Bad
239
+ function List({ items = [] }) { ... }
240
+ // Good
241
+ const EMPTY: readonly Item[] = [];
242
+ function List({ items = EMPTY }: { items?: readonly Item[] }) { ... }
243
+
244
+ // Never: index as key for dynamic lists
245
+ // Bad
246
+ {items.map((item, i) => <Item key={i} item={item} />)}
247
+ // Good
248
+ {items.map(item => <Item key={item.id} item={item} />)}
249
+ ```