@sylix/coworker 2.0.11 → 2.0.12

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 (169) hide show
  1. package/dist/commands/slash/config.d.ts.map +1 -1
  2. package/dist/commands/slash/config.js +22 -4
  3. package/dist/commands/slash/config.js.map +1 -1
  4. package/dist/core/CoWorkerAgent.d.ts.map +1 -1
  5. package/dist/core/CoWorkerAgent.js +6 -3
  6. package/dist/core/CoWorkerAgent.js.map +1 -1
  7. package/dist/skills/defaults/accessibility/screen-reader-testing.md +545 -0
  8. package/dist/skills/defaults/accessibility/wcag-audit-patterns.md +555 -0
  9. package/dist/skills/defaults/ai-ml/rag.md +276 -0
  10. package/dist/skills/defaults/backend-development/api-design-principles.md +528 -0
  11. package/dist/skills/defaults/backend-development/api-design.md +285 -0
  12. package/dist/skills/defaults/backend-development/architecture-patterns.md +494 -0
  13. package/dist/skills/defaults/backend-development/async-python.md +237 -0
  14. package/dist/skills/defaults/backend-development/auth-implementation-patterns.md +638 -0
  15. package/dist/skills/defaults/backend-development/bazel-build-optimization.md +387 -0
  16. package/dist/skills/defaults/backend-development/billing-automation/SKILL.md +566 -0
  17. package/dist/skills/defaults/backend-development/code-review-excellence.md +538 -0
  18. package/dist/skills/defaults/backend-development/cqrs-implementation.md +554 -0
  19. package/dist/skills/defaults/backend-development/database-design.md +305 -0
  20. package/dist/skills/defaults/backend-development/debugging-strategies.md +536 -0
  21. package/dist/skills/defaults/backend-development/e2e-testing-patterns.md +544 -0
  22. package/dist/skills/defaults/backend-development/error-handling-patterns.md +641 -0
  23. package/dist/skills/defaults/backend-development/fastapi-templates.md +559 -0
  24. package/dist/skills/defaults/backend-development/fastapi.md +309 -0
  25. package/dist/skills/defaults/backend-development/git-advanced-workflows.md +405 -0
  26. package/dist/skills/defaults/backend-development/microservices-patterns.md +595 -0
  27. package/dist/skills/defaults/backend-development/microservices.md +284 -0
  28. package/dist/skills/defaults/backend-development/monorepo-management.md +623 -0
  29. package/dist/skills/defaults/backend-development/nodejs-backend-patterns.md +1048 -0
  30. package/dist/skills/defaults/backend-development/nx-workspace-patterns.md +457 -0
  31. package/dist/skills/defaults/backend-development/paypal-integration/SKILL.md +478 -0
  32. package/dist/skills/defaults/backend-development/pci-compliance/SKILL.md +480 -0
  33. package/dist/skills/defaults/backend-development/python-anti-patterns.md +349 -0
  34. package/dist/skills/defaults/backend-development/python-background-jobs.md +364 -0
  35. package/dist/skills/defaults/backend-development/python-code-style.md +360 -0
  36. package/dist/skills/defaults/backend-development/python-configuration.md +368 -0
  37. package/dist/skills/defaults/backend-development/python-design-patterns.md +296 -0
  38. package/dist/skills/defaults/backend-development/python-error-handling.md +323 -0
  39. package/dist/skills/defaults/backend-development/python-packaging.md +887 -0
  40. package/dist/skills/defaults/backend-development/python-performance-optimization.md +874 -0
  41. package/dist/skills/defaults/backend-development/python-project-structure.md +252 -0
  42. package/dist/skills/defaults/backend-development/python-resilience.md +376 -0
  43. package/dist/skills/defaults/backend-development/python-resource-management.md +421 -0
  44. package/dist/skills/defaults/backend-development/python-type-safety.md +428 -0
  45. package/dist/skills/defaults/backend-development/sql-optimization-patterns.md +509 -0
  46. package/dist/skills/defaults/backend-development/stripe-integration/SKILL.md +522 -0
  47. package/dist/skills/defaults/backend-development/turborepo-caching.md +376 -0
  48. package/dist/skills/defaults/blockchain/defi-protocol-templates.md +430 -0
  49. package/dist/skills/defaults/blockchain/nft-standards.md +364 -0
  50. package/dist/skills/defaults/blockchain/solidity-security.md +514 -0
  51. package/dist/skills/defaults/blockchain/web3-testing.md +360 -0
  52. package/dist/skills/defaults/business/competitive-landscape/SKILL.md +527 -0
  53. package/dist/skills/defaults/business/market-sizing-analysis/SKILL.md +451 -0
  54. package/dist/skills/defaults/business/startup-financial-modeling/SKILL.md +494 -0
  55. package/dist/skills/defaults/business/startup-metrics-framework/SKILL.md +564 -0
  56. package/dist/skills/defaults/business/team-composition-analysis.md +437 -0
  57. package/dist/skills/defaults/compliance/employment-contract-templates/SKILL.md +527 -0
  58. package/dist/skills/defaults/compliance/gdpr-data-handling/SKILL.md +630 -0
  59. package/dist/skills/defaults/data-engineering/airflow-dag-patterns.md +436 -0
  60. package/dist/skills/defaults/data-engineering/airflow.md +519 -0
  61. package/dist/skills/defaults/data-engineering/data-quality.md +583 -0
  62. package/dist/skills/defaults/data-engineering/dbt-transformation-patterns.md +482 -0
  63. package/dist/skills/defaults/data-engineering/dbt.md +556 -0
  64. package/dist/skills/defaults/data-engineering/ml-pipeline-workflow/SKILL.md +247 -0
  65. package/dist/skills/defaults/data-engineering/spark-optimization.md +348 -0
  66. package/dist/skills/defaults/data-engineering/spark.md +411 -0
  67. package/dist/skills/defaults/database/postgresql.md +202 -0
  68. package/dist/skills/defaults/debugging/systematic-debugging.md +249 -0
  69. package/dist/skills/defaults/devops/architecture-decision-records.md +448 -0
  70. package/dist/skills/defaults/devops/changelog-automation.md +580 -0
  71. package/dist/skills/defaults/devops/cicd.md +314 -0
  72. package/dist/skills/defaults/devops/cloud.md +263 -0
  73. package/dist/skills/defaults/devops/code-review-excellence.md +299 -0
  74. package/dist/skills/defaults/devops/cost-optimization.md +295 -0
  75. package/dist/skills/defaults/devops/deployment-pipeline-design.md +356 -0
  76. package/dist/skills/defaults/devops/docker.md +281 -0
  77. package/dist/skills/defaults/devops/git-workflows.md +205 -0
  78. package/dist/skills/defaults/devops/github-actions.md +311 -0
  79. package/dist/skills/defaults/devops/gitlab-ci-patterns.md +266 -0
  80. package/dist/skills/defaults/devops/hybrid-cloud-networking.md +241 -0
  81. package/dist/skills/defaults/devops/istio-traffic-management.md +327 -0
  82. package/dist/skills/defaults/devops/kubernetes.md +339 -0
  83. package/dist/skills/defaults/devops/linkerd-patterns.md +311 -0
  84. package/dist/skills/defaults/devops/multi-cloud-architecture.md +181 -0
  85. package/dist/skills/defaults/devops/observability.md +243 -0
  86. package/dist/skills/defaults/devops/openapi-spec-generation.md +1024 -0
  87. package/dist/skills/defaults/devops/postmortem-writing.md +396 -0
  88. package/dist/skills/defaults/devops/prometheus-configuration.md +265 -0
  89. package/dist/skills/defaults/devops/secrets-management.md +341 -0
  90. package/dist/skills/defaults/devops/service-mesh-observability.md +385 -0
  91. package/dist/skills/defaults/devops/terraform-module-library.md +244 -0
  92. package/dist/skills/defaults/finance/backtesting-frameworks/SKILL.md +663 -0
  93. package/dist/skills/defaults/finance/risk-metrics-calculation/SKILL.md +557 -0
  94. package/dist/skills/defaults/frontend/accessibility-compliance.md +420 -0
  95. package/dist/skills/defaults/frontend/design-system-patterns.md +337 -0
  96. package/dist/skills/defaults/frontend/interaction-design.md +327 -0
  97. package/dist/skills/defaults/frontend/javascript.md +311 -0
  98. package/dist/skills/defaults/frontend/modern-javascript-patterns.md +927 -0
  99. package/dist/skills/defaults/frontend/react-native-design.md +440 -0
  100. package/dist/skills/defaults/frontend/react.md +345 -0
  101. package/dist/skills/defaults/frontend/responsive-design.md +472 -0
  102. package/dist/skills/defaults/frontend/tailwind-design-system.md +337 -0
  103. package/dist/skills/defaults/frontend/typescript-advanced-types.md +724 -0
  104. package/dist/skills/defaults/frontend/typescript.md +334 -0
  105. package/dist/skills/defaults/frontend/visual-design-foundations.md +326 -0
  106. package/dist/skills/defaults/frontend/web-component-design.md +279 -0
  107. package/dist/skills/defaults/game-development/godot-gdscript-patterns.md +188 -0
  108. package/dist/skills/defaults/game-development/unity-ecs-patterns.md +594 -0
  109. package/dist/skills/defaults/kubernetes/gitops-workflow.md +285 -0
  110. package/dist/skills/defaults/kubernetes/gitops.md +280 -0
  111. package/dist/skills/defaults/kubernetes/helm-chart-scaffolding.md +553 -0
  112. package/dist/skills/defaults/kubernetes/helm.md +343 -0
  113. package/dist/skills/defaults/kubernetes/k8s-manifest-generator.md +501 -0
  114. package/dist/skills/defaults/kubernetes/k8s-security-policies.md +342 -0
  115. package/dist/skills/defaults/kubernetes/manifests.md +330 -0
  116. package/dist/skills/defaults/kubernetes/security.md +337 -0
  117. package/dist/skills/defaults/llm-application/embedding-strategies.md +608 -0
  118. package/dist/skills/defaults/llm-application/hybrid-search-implementation.md +570 -0
  119. package/dist/skills/defaults/llm-application/hybrid-search.md +570 -0
  120. package/dist/skills/defaults/llm-application/langchain-architecture.md +666 -0
  121. package/dist/skills/defaults/llm-application/langchain.md +259 -0
  122. package/dist/skills/defaults/llm-application/llm-evaluation.md +695 -0
  123. package/dist/skills/defaults/llm-application/prompt-engineering-patterns.md +449 -0
  124. package/dist/skills/defaults/llm-application/prompt-engineering.md +219 -0
  125. package/dist/skills/defaults/llm-application/rag-implementation.md +434 -0
  126. package/dist/skills/defaults/llm-application/similarity-search-patterns.md +560 -0
  127. package/dist/skills/defaults/llm-application/similarity-search.md +560 -0
  128. package/dist/skills/defaults/llm-application/vector-index-tuning.md +523 -0
  129. package/dist/skills/defaults/mobile/mobile-android-design.md +440 -0
  130. package/dist/skills/defaults/mobile/mobile-ios-design.md +266 -0
  131. package/dist/skills/defaults/monitoring/distributed-tracing.md +436 -0
  132. package/dist/skills/defaults/monitoring/grafana-dashboards.md +370 -0
  133. package/dist/skills/defaults/monitoring/prometheus-configuration.md +379 -0
  134. package/dist/skills/defaults/monitoring/slo-implementation.md +323 -0
  135. package/dist/skills/defaults/refactoring/code-refactoring.md +349 -0
  136. package/dist/skills/defaults/security/anti-reversing-techniques/SKILL.md +559 -0
  137. package/dist/skills/defaults/security/auditor.md +168 -0
  138. package/dist/skills/defaults/security/binary-analysis-patterns/SKILL.md +438 -0
  139. package/dist/skills/defaults/security/memory-forensics/SKILL.md +483 -0
  140. package/dist/skills/defaults/security/mtls-configuration.md +349 -0
  141. package/dist/skills/defaults/security/protocol-reverse-engineering/SKILL.md +520 -0
  142. package/dist/skills/defaults/security/sast-configuration.md +182 -0
  143. package/dist/skills/defaults/security/security.md +313 -0
  144. package/dist/skills/defaults/security/stride-analysis.md +273 -0
  145. package/dist/skills/defaults/security/threat-mitigation-mapping.md +290 -0
  146. package/dist/skills/defaults/systems/bash-defensive-patterns/SKILL.md +539 -0
  147. package/dist/skills/defaults/systems/bats-testing-patterns/SKILL.md +631 -0
  148. package/dist/skills/defaults/systems/go-concurrency-patterns.md +657 -0
  149. package/dist/skills/defaults/systems/memory-safety-patterns.md +605 -0
  150. package/dist/skills/defaults/systems/rust-async-patterns.md +519 -0
  151. package/dist/skills/defaults/systems/shellcheck-configuration/SKILL.md +456 -0
  152. package/dist/skills/defaults/team-collaboration/multi-reviewer-patterns.md +126 -0
  153. package/dist/skills/defaults/team-collaboration/parallel-feature-development.md +151 -0
  154. package/dist/skills/defaults/testing/javascript-testing-patterns.md +1021 -0
  155. package/dist/skills/defaults/testing/python-testing-patterns.md +351 -0
  156. package/dist/skills/defaults/testing/testing.md +332 -0
  157. package/dist/skills/defaults/workflows/context-driven-development.md +384 -0
  158. package/dist/skills/defaults/workflows/track-management.md +592 -0
  159. package/dist/skills/defaults/workflows/workflow-patterns.md +622 -0
  160. package/dist/skills/index.d.ts +11 -0
  161. package/dist/skills/index.d.ts.map +1 -0
  162. package/dist/skills/index.js +129 -0
  163. package/dist/skills/index.js.map +1 -0
  164. package/dist/utils/character.js +4 -4
  165. package/dist/utils/character.js.map +1 -1
  166. package/dist/utils/inputbar.d.ts.map +1 -1
  167. package/dist/utils/inputbar.js +7 -0
  168. package/dist/utils/inputbar.js.map +1 -1
  169. package/package.json +1 -1
@@ -0,0 +1,345 @@
1
+ ---
2
+ name: react-patterns
3
+ description: Build scalable React applications with modern patterns, hooks, and best practices.
4
+ ---
5
+
6
+ # React Patterns — CoWorker Edition
7
+
8
+ Build maintainable React applications.
9
+
10
+ ## When to Use This Skill
11
+
12
+ - Building new React components
13
+ - Managing state
14
+ - Performance optimization
15
+ - Code organization
16
+
17
+ ## Core Concepts
18
+
19
+ ### 1. Component Patterns
20
+
21
+ ```typescript
22
+ // Function component with types
23
+ interface ButtonProps {
24
+ children: React.ReactNode;
25
+ onClick?: () => void;
26
+ variant?: 'primary' | 'secondary';
27
+ disabled?: boolean;
28
+ className?: string;
29
+ }
30
+
31
+ function Button({
32
+ children,
33
+ onClick,
34
+ variant = 'primary',
35
+ disabled = false,
36
+ className = ''
37
+ }: ButtonProps) {
38
+ return (
39
+ <button
40
+ className={`btn btn-${variant} ${className}`}
41
+ onClick={onClick}
42
+ disabled={disabled}
43
+ >
44
+ {children}
45
+ </button>
46
+ );
47
+ }
48
+
49
+ // Compound components
50
+ interface TabsProps {
51
+ children: React.ReactNode;
52
+ defaultIndex?: number;
53
+ }
54
+
55
+ function Tabs({ children, defaultIndex = 0 }: TabsProps) {
56
+ const [activeIndex, setActiveIndex] = useState(defaultIndex);
57
+
58
+ return (
59
+ <TabsContext.Provider value={{ activeIndex, setActiveIndex }}>
60
+ {children}
61
+ </TabsContext.Provider>
62
+ );
63
+ }
64
+
65
+ Tabs.List = function TabsList({ children }: { children: React.ReactNode }) {
66
+ return <div className="tabs-list">{children}</div>;
67
+ };
68
+
69
+ Tabs.Tab = function Tab({ index, label }: { index: number; label: string }) {
70
+ const { activeIndex, setActiveIndex } = useContext(TabsContext);
71
+ return (
72
+ <button
73
+ className={activeIndex === index ? 'active' : ''}
74
+ onClick={() => setActiveIndex(index)}
75
+ >
76
+ {label}
77
+ </button>
78
+ );
79
+ };
80
+
81
+ Tabs.Panel = function TabPanel({ index, children }: { index: number; children: React.ReactNode }) {
82
+ const { activeIndex } = useContext(TabsContext);
83
+ return activeIndex === index ? <div>{children}</div> : null;
84
+ };
85
+
86
+ // Usage
87
+ <Tabs defaultIndex={0}>
88
+ <Tabs.List>
89
+ <Tabs.Tab index={0} label="Profile" />
90
+ <Tabs.Tab index={1} label="Settings" />
91
+ </Tabs.List>
92
+ <Tabs.Panel index={0}>Profile content</Tabs.Panel>
93
+ <Tabs.Panel index={1}>Settings content</Tabs.Panel>
94
+ </Tabs>
95
+ ```
96
+
97
+ ### 2. Custom Hooks
98
+
99
+ ```typescript
100
+ // Data fetching hook
101
+ function useFetch<T>(url: string) {
102
+ const [data, setData] = useState<T | null>(null);
103
+ const [loading, setLoading] = useState(true);
104
+ const [error, setError] = useState<Error | null>(null);
105
+
106
+ useEffect(() => {
107
+ let cancelled = false;
108
+
109
+ async function fetchData() {
110
+ try {
111
+ setLoading(true);
112
+ const response = await fetch(url);
113
+ const json = await response.json();
114
+
115
+ if (!cancelled) {
116
+ setData(json);
117
+ setError(null);
118
+ }
119
+ } catch (e) {
120
+ if (!cancelled) {
121
+ setError(e as Error);
122
+ }
123
+ } finally {
124
+ if (!cancelled) {
125
+ setLoading(false);
126
+ }
127
+ }
128
+ }
129
+
130
+ fetchData();
131
+
132
+ return () => {
133
+ cancelled = true;
134
+ };
135
+ }, [url]);
136
+
137
+ return { data, loading, error };
138
+ }
139
+
140
+ // Local storage hook
141
+ function useLocalStorage<T>(key: string, initialValue: T) {
142
+ const [storedValue, setStoredValue] = useState<T>(() => {
143
+ try {
144
+ const item = window.localStorage.getItem(key);
145
+ return item ? JSON.parse(item) : initialValue;
146
+ } catch (error) {
147
+ return initialValue;
148
+ }
149
+ });
150
+
151
+ const setValue = (value: T | ((val: T) => T)) => {
152
+ try {
153
+ const valueToStore = value instanceof Function
154
+ ? value(storedValue)
155
+ : value;
156
+ setStoredValue(valueToStore);
157
+ window.localStorage.setItem(key, JSON.stringify(valueToStore));
158
+ } catch (error) {
159
+ console.error(error);
160
+ }
161
+ };
162
+
163
+ return [storedValue, setValue] as const;
164
+ }
165
+
166
+ // Debounced search
167
+ function useDebounce<T>(value: T, delay: number): T {
168
+ const [debouncedValue, setDebouncedValue] = useState(value);
169
+
170
+ useEffect(() => {
171
+ const handler = setTimeout(() => {
172
+ setDebouncedValue(value);
173
+ }, delay);
174
+
175
+ return () => {
176
+ clearTimeout(handler);
177
+ };
178
+ }, [value, delay]);
179
+
180
+ return debouncedValue;
181
+ }
182
+ ```
183
+
184
+ ### 3. State Management
185
+
186
+ ```typescript
187
+ // Context for global state
188
+ interface AuthState {
189
+ user: User | null;
190
+ isAuthenticated: boolean;
191
+ }
192
+
193
+ function AuthProvider({ children }: { children: React.ReactNode }) {
194
+ const [state, setState] = useState<AuthState>({
195
+ user: null,
196
+ isAuthenticated: false
197
+ });
198
+
199
+ const login = async (email: string, password: string) => {
200
+ const user = await api.login(email, password);
201
+ setState({ user, isAuthenticated: true });
202
+ };
203
+
204
+ const logout = () => {
205
+ setState({ user: null, isAuthenticated: false });
206
+ };
207
+
208
+ return (
209
+ <AuthContext.Provider value={{ ...state, login, logout }}>
210
+ {children}
211
+ </AuthContext.Provider>
212
+ );
213
+ }
214
+
215
+ // Reducer for complex state
216
+ type Action =
217
+ | { type: 'SET_DATA'; payload: Data[] }
218
+ | { type: 'ADD_ITEM'; payload: Data }
219
+ | { type: 'REMOVE_ITEM'; payload: string }
220
+ | { type: 'UPDATE_ITEM'; payload: Data };
221
+
222
+ function reducer(state: State, action: Action): State {
223
+ switch (action.type) {
224
+ case 'SET_DATA':
225
+ return { ...state, data: action.payload, loading: false };
226
+ case 'ADD_ITEM':
227
+ return { ...state, data: [...state.data, action.payload] };
228
+ case 'REMOVE_ITEM':
229
+ return { ...state, data: state.data.filter(d => d.id !== action.payload) };
230
+ case 'UPDATE_ITEM':
231
+ return {
232
+ ...state,
233
+ data: state.data.map(d => d.id === action.payload.id ? action.payload : d)
234
+ };
235
+ default:
236
+ return state;
237
+ }
238
+ }
239
+ ```
240
+
241
+ ### 4. Performance Optimization
242
+
243
+ ```typescript
244
+ // Memoization
245
+ const MemoizedComponent = React.memo(function Component({ data }) {
246
+ return <div>{data.name}</div>;
247
+ });
248
+
249
+ // with custom comparison
250
+ const MemoizedWithCompare = React.memo(
251
+ function Component({ data }) {
252
+ return <div>{data.name}</div>;
253
+ },
254
+ (prevProps, nextProps) => {
255
+ return prevProps.data.id === nextProps.data.id;
256
+ }
257
+ );
258
+
259
+ // useMemo for expensive calculations
260
+ function ExpensiveComponent({ items, filter }) {
261
+ const filteredItems = useMemo(() => {
262
+ return items.filter(item =>
263
+ item.name.toLowerCase().includes(filter.toLowerCase())
264
+ );
265
+ }, [items, filter]);
266
+
267
+ return (
268
+ <ul>
269
+ {filteredItems.map(item => (
270
+ <li key={item.id}>{item.name}</li>
271
+ ))}
272
+ </ul>
273
+ );
274
+ }
275
+
276
+ // useCallback for callbacks
277
+ function Parent() {
278
+ const [count, setCount] = useState(0);
279
+
280
+ const handleClick = useCallback(() => {
281
+ console.log('clicked');
282
+ }, []); // Empty deps = stable function
283
+
284
+ return <Child onClick={handleClick} />;
285
+ }
286
+ ```
287
+
288
+ ### 5. Error Boundaries
289
+
290
+ ```typescript
291
+ interface ErrorBoundaryProps {
292
+ children: React.ReactNode;
293
+ fallback?: React.ReactNode;
294
+ onError?: (error: Error, errorInfo: React.ErrorInfo) => void;
295
+ }
296
+
297
+ interface ErrorBoundaryState {
298
+ hasError: boolean;
299
+ error?: Error;
300
+ }
301
+
302
+ class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {
303
+ state: ErrorBoundaryState = { hasError: false };
304
+
305
+ static getDerivedStateFromError(error: Error): ErrorBoundaryState {
306
+ return { hasError: true, error };
307
+ }
308
+
309
+ componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
310
+ this.props.onError?.(error, errorInfo);
311
+ console.error('Error:', error, errorInfo);
312
+ }
313
+
314
+ render() {
315
+ if (this.state.hasError) {
316
+ return this.props.fallback || <DefaultError />;
317
+ }
318
+
319
+ return this.props.children;
320
+ }
321
+ }
322
+
323
+ // Usage
324
+ <ErrorBoundary fallback={<ErrorFallback />}>
325
+ <MyComponent />
326
+ </ErrorBoundary>
327
+ ```
328
+
329
+ ## Best Practices
330
+
331
+ 1. **Small components** - Single responsibility
332
+ 2. **Custom hooks** - Reusable logic
333
+ 3. **Prop types** - TypeScript or PropTypes
334
+ 4. **Memoization** - Optimize when needed
335
+ 5. **Error boundaries** - Graceful failures
336
+ 6. **Composition** - Over inheritance
337
+
338
+ ## Common Mistakes
339
+
340
+ - Over-memoization
341
+ - Not cleaning up effects
342
+ - Prop drilling
343
+ - Not handling loading/error
344
+ - Large components
345
+ - Not using TypeScript types