ima-claude 2.9.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 (182) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +463 -0
  3. package/dist/cli.js +1064 -0
  4. package/package.json +49 -0
  5. package/platforms/claude/adapter.ts +115 -0
  6. package/platforms/junie/adapter.ts +254 -0
  7. package/platforms/junie/agents-template.md +113 -0
  8. package/platforms/junie/hook-translations.md +84 -0
  9. package/platforms/shared/detector.ts +27 -0
  10. package/platforms/shared/installer.ts +202 -0
  11. package/platforms/shared/types.ts +78 -0
  12. package/plugins/ima-claude/.claude-plugin/plugin.json +25 -0
  13. package/plugins/ima-claude/agents/explorer.md +30 -0
  14. package/plugins/ima-claude/agents/implementer.md +30 -0
  15. package/plugins/ima-claude/agents/memory.md +42 -0
  16. package/plugins/ima-claude/agents/reviewer.md +53 -0
  17. package/plugins/ima-claude/agents/tester.md +33 -0
  18. package/plugins/ima-claude/agents/wp-developer.md +46 -0
  19. package/plugins/ima-claude/hooks/README.md +145 -0
  20. package/plugins/ima-claude/hooks/atlassian_prereqs.py +112 -0
  21. package/plugins/ima-claude/hooks/block_sed_edits.py +59 -0
  22. package/plugins/ima-claude/hooks/bootstrap.sh +90 -0
  23. package/plugins/ima-claude/hooks/bootstrap_utility_check.py +94 -0
  24. package/plugins/ima-claude/hooks/composer_autoload_check.py +70 -0
  25. package/plugins/ima-claude/hooks/docs_organization.py +104 -0
  26. package/plugins/ima-claude/hooks/enforce_rg_over_grep.py +56 -0
  27. package/plugins/ima-claude/hooks/fp_utility_check.py +90 -0
  28. package/plugins/ima-claude/hooks/hook_logger.py +69 -0
  29. package/plugins/ima-claude/hooks/hooks.json +239 -0
  30. package/plugins/ima-claude/hooks/jira_issue_fetch.py +79 -0
  31. package/plugins/ima-claude/hooks/jquery_in_wordpress.py +92 -0
  32. package/plugins/ima-claude/hooks/memory_bootstrap.py +79 -0
  33. package/plugins/ima-claude/hooks/memory_store_reminder.py +75 -0
  34. package/plugins/ima-claude/hooks/prompt_coach.py +125 -0
  35. package/plugins/ima-claude/hooks/prompt_coach_digest.md +48 -0
  36. package/plugins/ima-claude/hooks/prompt_coach_system.md +30 -0
  37. package/plugins/ima-claude/hooks/sequential_thinking_check.py +81 -0
  38. package/plugins/ima-claude/hooks/serena_over_grep.py +96 -0
  39. package/plugins/ima-claude/hooks/serena_over_read.py +66 -0
  40. package/plugins/ima-claude/hooks/serena_project_check.py +133 -0
  41. package/plugins/ima-claude/hooks/sql_injection_check.py +73 -0
  42. package/plugins/ima-claude/hooks/task_master_after_plan.py +31 -0
  43. package/plugins/ima-claude/hooks/task_master_before_impl.py +93 -0
  44. package/plugins/ima-claude/hooks/tavily_extract_advanced.py +48 -0
  45. package/plugins/ima-claude/hooks/vestige_before_external.py +86 -0
  46. package/plugins/ima-claude/hooks/webfetch_to_tavily.py +42 -0
  47. package/plugins/ima-claude/hooks/websearch_to_tavily.py +41 -0
  48. package/plugins/ima-claude/hooks/wp_security_check.py +150 -0
  49. package/plugins/ima-claude/personalities/README.md +45 -0
  50. package/plugins/ima-claude/personalities/enable-40k.md +69 -0
  51. package/plugins/ima-claude/personalities/enable-templars.md +69 -0
  52. package/plugins/ima-claude/skills/.research-summary.md +340 -0
  53. package/plugins/ima-claude/skills/architect/SKILL.md +304 -0
  54. package/plugins/ima-claude/skills/compound-bridge/SKILL.md +200 -0
  55. package/plugins/ima-claude/skills/discourse/SKILL.md +440 -0
  56. package/plugins/ima-claude/skills/discourse-admin/SKILL.md +192 -0
  57. package/plugins/ima-claude/skills/discourse-admin/references/api-endpoints.md +441 -0
  58. package/plugins/ima-claude/skills/discourse-admin/references/gotchas.md +107 -0
  59. package/plugins/ima-claude/skills/discourse-admin/references/staging-defaults.md +98 -0
  60. package/plugins/ima-claude/skills/discourse-admin/scripts/discourse-admin.py +319 -0
  61. package/plugins/ima-claude/skills/docs-organize/SKILL.md +254 -0
  62. package/plugins/ima-claude/skills/docs-organize/templates/active-README.md +50 -0
  63. package/plugins/ima-claude/skills/docs-organize/templates/archive-README.md +57 -0
  64. package/plugins/ima-claude/skills/docs-organize/templates/docs-README.md +43 -0
  65. package/plugins/ima-claude/skills/docs-organize/templates/phase-archive-README.md +83 -0
  66. package/plugins/ima-claude/skills/docs-organize/templates/section-README.md +48 -0
  67. package/plugins/ima-claude/skills/docs-organize/templates/transient-README.md +79 -0
  68. package/plugins/ima-claude/skills/docs-organize/templates/transient-gitignore +9 -0
  69. package/plugins/ima-claude/skills/ember-discourse/SKILL.md +496 -0
  70. package/plugins/ima-claude/skills/functional-programmer/SKILL.md +258 -0
  71. package/plugins/ima-claude/skills/ima-bootstrap/SKILL.md +278 -0
  72. package/plugins/ima-claude/skills/ima-bootstrap/references/bootstrap-patterns.md +356 -0
  73. package/plugins/ima-claude/skills/ima-bootstrap/references/ima-brand.md +273 -0
  74. package/plugins/ima-claude/skills/ima-bootstrap/references/theme-integration.md +212 -0
  75. package/plugins/ima-claude/skills/ima-brand/SKILL.md +108 -0
  76. package/plugins/ima-claude/skills/ima-brand/references/brand-identity.md +140 -0
  77. package/plugins/ima-claude/skills/ima-brand/references/digital-standards.md +180 -0
  78. package/plugins/ima-claude/skills/ima-brand/references/visual-system.md +173 -0
  79. package/plugins/ima-claude/skills/ima-forms-expert/SKILL.md +175 -0
  80. package/plugins/ima-claude/skills/ima-forms-expert/references/container-components.md +154 -0
  81. package/plugins/ima-claude/skills/ima-forms-expert/references/examples.md +328 -0
  82. package/plugins/ima-claude/skills/ima-forms-expert/references/field-components.md +298 -0
  83. package/plugins/ima-claude/skills/ima-forms-expert/references/form-factory.md +193 -0
  84. package/plugins/ima-claude/skills/ima-forms-expert/references/quick-reference.md +153 -0
  85. package/plugins/ima-claude/skills/ima-forms-expert/references/validation-engine.md +336 -0
  86. package/plugins/ima-claude/skills/jira-checkpoint/SKILL.md +178 -0
  87. package/plugins/ima-claude/skills/jquery/SKILL.md +413 -0
  88. package/plugins/ima-claude/skills/js-fp/SKILL.md +463 -0
  89. package/plugins/ima-claude/skills/js-fp/core-principles.md +487 -0
  90. package/plugins/ima-claude/skills/js-fp/examples/pure-functions.js +260 -0
  91. package/plugins/ima-claude/skills/js-fp/examples/tests/pure-functions.test.js +262 -0
  92. package/plugins/ima-claude/skills/js-fp/references/anti-patterns.md +120 -0
  93. package/plugins/ima-claude/skills/js-fp/references/performance-patterns.md +116 -0
  94. package/plugins/ima-claude/skills/js-fp/references/testing-patterns.md +134 -0
  95. package/plugins/ima-claude/skills/js-fp-api/SKILL.md +280 -0
  96. package/plugins/ima-claude/skills/js-fp-api/examples/crud-endpoint.js +258 -0
  97. package/plugins/ima-claude/skills/js-fp-api/references/middleware-patterns.md +134 -0
  98. package/plugins/ima-claude/skills/js-fp-api/references/security-sql.md +110 -0
  99. package/plugins/ima-claude/skills/js-fp-api/references/validation-patterns.md +165 -0
  100. package/plugins/ima-claude/skills/js-fp-react/SKILL.md +447 -0
  101. package/plugins/ima-claude/skills/js-fp-react/examples/ProductCard.tsx +65 -0
  102. package/plugins/ima-claude/skills/js-fp-react/references/hooks-advanced.md +136 -0
  103. package/plugins/ima-claude/skills/js-fp-react/references/performance-patterns.md +175 -0
  104. package/plugins/ima-claude/skills/js-fp-vue/SKILL.md +322 -0
  105. package/plugins/ima-claude/skills/js-fp-vue/references/complete-examples.md +397 -0
  106. package/plugins/ima-claude/skills/js-fp-vue/references/composables-advanced.md +282 -0
  107. package/plugins/ima-claude/skills/js-fp-vue/references/reactivity-patterns.md +348 -0
  108. package/plugins/ima-claude/skills/js-fp-vue/references/testing.md +314 -0
  109. package/plugins/ima-claude/skills/js-fp-wordpress/SKILL.md +301 -0
  110. package/plugins/ima-claude/skills/js-fp-wordpress/references/ajax-patterns.md +192 -0
  111. package/plugins/ima-claude/skills/js-fp-wordpress/references/event-patterns.md +136 -0
  112. package/plugins/ima-claude/skills/js-fp-wordpress/references/wp-integration.md +248 -0
  113. package/plugins/ima-claude/skills/livecanvas/SKILL.md +209 -0
  114. package/plugins/ima-claude/skills/livecanvas/references/livecanvas-features.md +311 -0
  115. package/plugins/ima-claude/skills/livecanvas/references/loops-and-logic.md +730 -0
  116. package/plugins/ima-claude/skills/livecanvas/references/picostrap.md +227 -0
  117. package/plugins/ima-claude/skills/mcp-atlassian/SKILL.md +339 -0
  118. package/plugins/ima-claude/skills/mcp-context7/SKILL.md +109 -0
  119. package/plugins/ima-claude/skills/mcp-memory/SKILL.md +182 -0
  120. package/plugins/ima-claude/skills/mcp-qdrant/SKILL.md +233 -0
  121. package/plugins/ima-claude/skills/mcp-sequential/SKILL.md +149 -0
  122. package/plugins/ima-claude/skills/mcp-serena/SKILL.md +174 -0
  123. package/plugins/ima-claude/skills/mcp-tavily/SKILL.md +118 -0
  124. package/plugins/ima-claude/skills/mcp-vestige/SKILL.md +259 -0
  125. package/plugins/ima-claude/skills/php-authnet/SKILL.md +275 -0
  126. package/plugins/ima-claude/skills/php-authnet/references/api-reference.md +624 -0
  127. package/plugins/ima-claude/skills/php-authnet/references/sandbox-testing.md +424 -0
  128. package/plugins/ima-claude/skills/php-fp/SKILL.md +333 -0
  129. package/plugins/ima-claude/skills/php-fp/examples/pure-functions.php +403 -0
  130. package/plugins/ima-claude/skills/php-fp/examples/tests/PureFunctionsTest.php +515 -0
  131. package/plugins/ima-claude/skills/php-fp/references/core-principles.md +277 -0
  132. package/plugins/ima-claude/skills/php-fp/references/testing-patterns.md +374 -0
  133. package/plugins/ima-claude/skills/php-fp-wordpress/SKILL.md +216 -0
  134. package/plugins/ima-claude/skills/php-fp-wordpress/references/fp-patterns.md +275 -0
  135. package/plugins/ima-claude/skills/php-fp-wordpress/references/plugin-architecture.md +295 -0
  136. package/plugins/ima-claude/skills/php-fp-wordpress/references/security-examples.md +203 -0
  137. package/plugins/ima-claude/skills/php-fp-wordpress/references/testing-strategy.md +259 -0
  138. package/plugins/ima-claude/skills/phpunit-wp/SKILL.md +716 -0
  139. package/plugins/ima-claude/skills/playwright/SKILL.md +434 -0
  140. package/plugins/ima-claude/skills/playwright/references/accessibility-testing.md +153 -0
  141. package/plugins/ima-claude/skills/playwright/references/ci-cd.md +268 -0
  142. package/plugins/ima-claude/skills/playwright/references/network-mocking.md +270 -0
  143. package/plugins/ima-claude/skills/playwright/references/visual-regression.md +215 -0
  144. package/plugins/ima-claude/skills/py-fp/SKILL.md +663 -0
  145. package/plugins/ima-claude/skills/py-fp/examples/pure-functions.py +185 -0
  146. package/plugins/ima-claude/skills/py-fp/examples/tests/test_pure_functions.py +244 -0
  147. package/plugins/ima-claude/skills/py-fp/references/core-principles.md +381 -0
  148. package/plugins/ima-claude/skills/py-fp/references/testing-patterns.md +283 -0
  149. package/plugins/ima-claude/skills/quasar-fp/SKILL.md +327 -0
  150. package/plugins/ima-claude/skills/quasar-fp/metadata.json +85 -0
  151. package/plugins/ima-claude/skills/quasar-fp/references/component-patterns.md +257 -0
  152. package/plugins/ima-claude/skills/quasar-fp/references/theme-integration.md +233 -0
  153. package/plugins/ima-claude/skills/quasar-fp/references/utility-classes.md +237 -0
  154. package/plugins/ima-claude/skills/quickstart/SKILL.md +129 -0
  155. package/plugins/ima-claude/skills/rails/SKILL.md +359 -0
  156. package/plugins/ima-claude/skills/resume-session/SKILL.md +68 -0
  157. package/plugins/ima-claude/skills/rg/SKILL.md +205 -0
  158. package/plugins/ima-claude/skills/ruby-fp/SKILL.md +336 -0
  159. package/plugins/ima-claude/skills/save-session/SKILL.md +81 -0
  160. package/plugins/ima-claude/skills/scorecard/SKILL.md +96 -0
  161. package/plugins/ima-claude/skills/skill-analyzer/SKILL.md +127 -0
  162. package/plugins/ima-claude/skills/skill-analyzer/references/advanced-checklist.md +44 -0
  163. package/plugins/ima-claude/skills/skill-analyzer/references/core-checklist.md +60 -0
  164. package/plugins/ima-claude/skills/skill-analyzer/scripts/analyze_skill.py +418 -0
  165. package/plugins/ima-claude/skills/skill-creator/LICENSE.txt +202 -0
  166. package/plugins/ima-claude/skills/skill-creator/SKILL.md +343 -0
  167. package/plugins/ima-claude/skills/skill-creator/references/output-patterns.md +82 -0
  168. package/plugins/ima-claude/skills/skill-creator/references/workflows.md +28 -0
  169. package/plugins/ima-claude/skills/skill-creator/scripts/init_skill.py +303 -0
  170. package/plugins/ima-claude/skills/skill-creator/scripts/package_skill.py +110 -0
  171. package/plugins/ima-claude/skills/skill-creator/scripts/quick_validate.py +103 -0
  172. package/plugins/ima-claude/skills/task-master/SKILL.md +51 -0
  173. package/plugins/ima-claude/skills/task-planner/SKILL.md +228 -0
  174. package/plugins/ima-claude/skills/task-runner/SKILL.md +192 -0
  175. package/plugins/ima-claude/skills/unit-testing/SKILL.md +198 -0
  176. package/plugins/ima-claude/skills/unit-testing/references/mock-patterns.md +181 -0
  177. package/plugins/ima-claude/skills/unit-testing/references/tdd-workflow.md +177 -0
  178. package/plugins/ima-claude/skills/unit-testing/references/test-strategy.md +126 -0
  179. package/plugins/ima-claude/skills/wp-local/SKILL.md +246 -0
  180. package/plugins/ima-claude/skills/wp-local/references/configuration.md +198 -0
  181. package/plugins/ima-claude/skills/wp-local/references/wp-cli-reference.md +406 -0
  182. package/plugins/ima-claude/skills/wp-local/scripts/wp-local.sh +61 -0
@@ -0,0 +1,487 @@
1
+ # Core FP Principles - Deep Dive
2
+
3
+ Complete functional programming philosophy with detailed pattern explanations and cross-pattern comparisons.
4
+
5
+ ## Table of Contents
6
+
7
+ 1. [Philosophy and Mindset](#philosophy-and-mindset)
8
+ 2. [Purity Deep Dive](#purity-deep-dive)
9
+ 3. [Composition Strategies](#composition-strategies)
10
+ 4. [Dependency Injection Patterns](#dependency-injection-patterns)
11
+ 5. [Immutability Strategies](#immutability-strategies)
12
+ 6. [Error Handling Patterns](#error-handling-patterns)
13
+ 7. [State Management](#state-management)
14
+ 8. [Cross-Pattern Comparisons](#cross-pattern-comparisons)
15
+
16
+ ## Philosophy and Mindset
17
+
18
+ ### The FP Mental Model
19
+
20
+ Functional programming is about:
21
+ - **Functions as building blocks**: Small, composable, testable units
22
+ - **Data transformation**: Input → Processing → Output (no hidden state)
23
+ - **Explicit over implicit**: Dependencies and effects are visible
24
+ - **Simplicity over cleverness**: Native patterns over utilities
25
+
26
+ ### Why FP in JavaScript?
27
+
28
+ **JavaScript's FP strengths**:
29
+ - First-class functions (functions as values)
30
+ - Closures (lexical scoping for data encapsulation)
31
+ - Array methods (map, filter, reduce are FP primitives)
32
+ - Async/await (functional async composition)
33
+
34
+ **NOT about**:
35
+ - Creating Haskell in JavaScript
36
+ - Complex category theory
37
+ - Academic purity for its own sake
38
+ - FP utility libraries
39
+
40
+ ## Purity Deep Dive
41
+
42
+ ### What Makes a Function Pure?
43
+
44
+ ```javascript
45
+ // Pure: Same inputs → Same outputs, no side effects
46
+ const add = (a, b) => a + b
47
+ const multiply = (x) => (y) => x * y
48
+
49
+ // Impure: Depends on external state
50
+ let discount = 0.1
51
+ const calculatePrice = (price) => price * (1 - discount) // ❌
52
+
53
+ // Pure version: Explicit dependency
54
+ const calculatePrice = (price, discount) => price * (1 - discount) // ✅
55
+ ```
56
+
57
+ ### Benefits of Purity
58
+
59
+ **1. Testability**: 100% of logic is testable
60
+ ```javascript
61
+ // Pure function - test every data type easily
62
+ const safeDivide = (a, b) => b === 0 ? 0 : a / b
63
+
64
+ describe('safeDivide', () => {
65
+ const testCases = [
66
+ [10, 2, 5],
67
+ [10, 0, 0],
68
+ [0, 5, 0],
69
+ [-10, 2, -5]
70
+ ]
71
+
72
+ testCases.forEach(([a, b, expected]) => {
73
+ it(`${a} / ${b} = ${expected}`, () => {
74
+ expect(safeDivide(a, b)).toBe(expected)
75
+ })
76
+ })
77
+ })
78
+ ```
79
+
80
+ **2. Predictability**: No surprises from hidden state
81
+ ```javascript
82
+ // Impure: Can fail randomly based on network
83
+ const getUser = (id) => fetch(`/users/${id}`).then(r => r.json()) // ❌
84
+
85
+ // Pure: Explicit dependency injection
86
+ const getUser = (id, fetcher) => fetcher.get(`/users/${id}`) // ✅
87
+
88
+ // Test with mock
89
+ const mockFetcher = { get: jest.fn().mockResolvedValue({ id: 1, name: 'Test' }) }
90
+ await getUser(1, mockFetcher) // Fully controllable
91
+ ```
92
+
93
+ **3. Memoization**: Pure functions can be cached safely
94
+ ```javascript
95
+ const memoize = (fn) => {
96
+ const cache = new Map()
97
+ return (...args) => {
98
+ const key = JSON.stringify(args)
99
+ if (cache.has(key)) return cache.get(key)
100
+ const result = fn(...args)
101
+ cache.set(key, result)
102
+ return result
103
+ }
104
+ }
105
+
106
+ // Only works with pure functions
107
+ const expensiveCalculation = memoize((n) => {
108
+ // Complex computation
109
+ return n * n * n
110
+ })
111
+ ```
112
+
113
+ ### Side Effect Isolation
114
+
115
+ **Pattern**: Push effects to the edges
116
+ ```javascript
117
+ // ❌ Mixed concerns
118
+ const processAndSaveUser = async (userData) => {
119
+ const validated = validateUser(userData) // Pure
120
+ console.log('Validated:', validated) // Side effect
121
+ const enhanced = enhanceUser(validated) // Pure
122
+ await database.save(enhanced) // Side effect
123
+ console.log('Saved:', enhanced.id) // Side effect
124
+ return enhanced
125
+ }
126
+
127
+ // ✅ Separated concerns
128
+ // Pure business logic
129
+ const processUser = (userData) => {
130
+ const validated = validateUser(userData)
131
+ if (!validated.valid) return validated
132
+ return { valid: true, data: enhanceUser(validated.data) }
133
+ }
134
+
135
+ // Side effects at the edge
136
+ const saveUser = async (userData, logger, database) => {
137
+ const result = processUser(userData) // Pure
138
+
139
+ if (!result.valid) {
140
+ logger.error('Validation failed', result.errors)
141
+ return result
142
+ }
143
+
144
+ logger.info('Validated', result.data)
145
+ const saved = await database.save(result.data)
146
+ logger.info('Saved', saved.id)
147
+ return { valid: true, data: saved }
148
+ }
149
+ ```
150
+
151
+ ## Composition Strategies
152
+
153
+ ### Why Composition Over Inheritance?
154
+
155
+ **Problems with inheritance**:
156
+ - Tight coupling between parent and child
157
+ - Fragile base class problem
158
+ - Deep hierarchies are hard to understand
159
+ - Can't mix behaviors from multiple parents easily
160
+
161
+ **Composition benefits**:
162
+ - Loosely coupled functions
163
+ - Easy to understand each piece
164
+ - Mix and match behaviors freely
165
+ - Easy to test each function
166
+
167
+ ### Composition Patterns
168
+
169
+ **1. Sequential Composition (early returns)**
170
+ ```javascript
171
+ // Each step can short-circuit
172
+ const processOrder = (order) => {
173
+ const validated = validateOrder(order)
174
+ if (!validated.valid) return validated
175
+
176
+ const priced = calculatePrice(validated.data)
177
+ if (!priced.valid) return priced
178
+
179
+ const inventoryCheck = checkInventory(priced.data)
180
+ if (!inventoryCheck.valid) return inventoryCheck
181
+
182
+ return { valid: true, data: prepareShipment(inventoryCheck.data) }
183
+ }
184
+ ```
185
+
186
+ **2. Array Methods Composition**
187
+ ```javascript
188
+ // Native JavaScript composition
189
+ const processUsers = (users) =>
190
+ users
191
+ .filter(user => user.active)
192
+ .map(user => ({ ...user, displayName: `${user.firstName} ${user.lastName}` }))
193
+ .sort((a, b) => a.lastName.localeCompare(b.lastName))
194
+ .slice(0, 10)
195
+ ```
196
+
197
+ **3. Function Factories**
198
+ ```javascript
199
+ // Create specialized functions
200
+ const createTransformer = (config) => {
201
+ // Pre-compile configuration
202
+ const rules = compileRules(config.rules)
203
+ const filters = compileFilters(config.filters)
204
+
205
+ return (data) => {
206
+ const filtered = filters.reduce((d, filter) => filter(d), data)
207
+ return rules.reduce((d, rule) => rule(d), filtered)
208
+ }
209
+ }
210
+
211
+ // Use specialized function
212
+ const userTransformer = createTransformer(userConfig)
213
+ const results = users.map(userTransformer)
214
+ ```
215
+
216
+ ## Dependency Injection Patterns
217
+
218
+ ### Why DI in FP?
219
+
220
+ - Makes dependencies explicit
221
+ - Enables complete testing
222
+ - Reduces coupling
223
+ - Makes side effects visible
224
+
225
+ ### DI Pattern Levels
226
+
227
+ **Level 1: Direct Parameter Injection**
228
+ ```javascript
229
+ const saveUser = (user, hasher, database) => {
230
+ const hashed = hasher.hash(user.password)
231
+ return database.save({ ...user, password: hashed })
232
+ }
233
+
234
+ // Test with mocks
235
+ const mockHasher = { hash: (p) => `hashed_${p}` }
236
+ const mockDb = { save: jest.fn() }
237
+ saveUser(testUser, mockHasher, mockDb)
238
+ ```
239
+
240
+ **Level 2: Function Factory**
241
+ ```javascript
242
+ const createUserService = (hasher, database) => ({
243
+ save: (user) => saveUser(user, hasher, database),
244
+ find: (id) => database.findById(id),
245
+ update: (id, updates) => updateUser(id, updates, hasher, database)
246
+ })
247
+
248
+ // Create once with real deps
249
+ const userService = createUserService(bcrypt, postgresDb)
250
+
251
+ // Use without passing deps every time
252
+ await userService.save(userData)
253
+
254
+ // Test with mock deps
255
+ const testService = createUserService(mockHasher, mockDb)
256
+ ```
257
+
258
+ **Level 3: Higher-Order Functions**
259
+ ```javascript
260
+ const withLogging = (fn, logger) => async (...args) => {
261
+ logger.info('Starting', { fn: fn.name, args })
262
+ try {
263
+ const result = await fn(...args)
264
+ logger.info('Success', { fn: fn.name, result })
265
+ return result
266
+ } catch (error) {
267
+ logger.error('Failed', { fn: fn.name, error })
268
+ throw error
269
+ }
270
+ }
271
+
272
+ // Wrap any function with logging
273
+ const saveUserWithLogging = withLogging(saveUser, console)
274
+ ```
275
+
276
+ ## Immutability Strategies
277
+
278
+ ### Why Immutability?
279
+
280
+ - Prevents unexpected mutations
281
+ - Makes state changes explicit
282
+ - Enables time-travel debugging
283
+ - Safer concurrent operations
284
+
285
+ ### Immutable Operations
286
+
287
+ **Objects**:
288
+ ```javascript
289
+ // Add property
290
+ const addProp = (obj, key, value) => ({ ...obj, [key]: value })
291
+
292
+ // Remove property
293
+ const removeProp = (obj, key) => {
294
+ const { [key]: removed, ...rest } = obj
295
+ return rest
296
+ }
297
+
298
+ // Update nested property
299
+ const updateNested = (obj, path, value) => {
300
+ const [key, ...rest] = path
301
+ if (rest.length === 0) return { ...obj, [key]: value }
302
+ return { ...obj, [key]: updateNested(obj[key], rest, value) }
303
+ }
304
+ ```
305
+
306
+ **Arrays**:
307
+ ```javascript
308
+ // Add
309
+ const add = (arr, item) => [...arr, item]
310
+ const addAt = (arr, index, item) => [...arr.slice(0, index), item, ...arr.slice(index)]
311
+
312
+ // Remove
313
+ const remove = (arr, index) => [...arr.slice(0, index), ...arr.slice(index + 1)]
314
+ const removeBy = (arr, predicate) => arr.filter(item => !predicate(item))
315
+
316
+ // Update
317
+ const update = (arr, index, updater) =>
318
+ arr.map((item, i) => i === index ? updater(item) : item)
319
+ ```
320
+
321
+ ## Error Handling Patterns
322
+
323
+ ### Result Type Pattern
324
+
325
+ ```javascript
326
+ // Standard result shape
327
+ const createResult = (data, error = null) =>
328
+ error ? { success: false, error } : { success: true, data }
329
+
330
+ // Use in functions
331
+ const divide = (a, b) =>
332
+ b === 0
333
+ ? createResult(null, 'Division by zero')
334
+ : createResult(a / b)
335
+
336
+ // Chain results
337
+ const calculate = (a, b, c) => {
338
+ const result1 = divide(a, b)
339
+ if (!result1.success) return result1
340
+
341
+ const result2 = divide(result1.data, c)
342
+ return result2
343
+ }
344
+ ```
345
+
346
+ ### Try-Catch Wrapper
347
+
348
+ ```javascript
349
+ const tryCatch = (fn) => async (...args) => {
350
+ try {
351
+ const data = await fn(...args)
352
+ return { success: true, data }
353
+ } catch (error) {
354
+ return { success: false, error: error.message }
355
+ }
356
+ }
357
+
358
+ // Wrap async functions
359
+ const safeFetchUser = tryCatch(fetchUser)
360
+ const result = await safeFetchUser(userId)
361
+ ```
362
+
363
+ ## State Management
364
+
365
+ ### Local State with Closures
366
+
367
+ ```javascript
368
+ const createCounter = (initial = 0) => {
369
+ let count = initial
370
+
371
+ return {
372
+ get: () => count,
373
+ increment: () => ++count,
374
+ decrement: () => --count,
375
+ reset: () => count = initial
376
+ }
377
+ }
378
+
379
+ const counter = createCounter(10)
380
+ counter.increment() // 11
381
+ counter.get() // 11
382
+ ```
383
+
384
+ ### Immutable State Updates
385
+
386
+ ```javascript
387
+ const createStore = (initialState) => {
388
+ let state = initialState
389
+ const listeners = []
390
+
391
+ return {
392
+ getState: () => state,
393
+ setState: (updater) => {
394
+ state = updater(state)
395
+ listeners.forEach(listener => listener(state))
396
+ },
397
+ subscribe: (listener) => {
398
+ listeners.push(listener)
399
+ return () => {
400
+ const index = listeners.indexOf(listener)
401
+ if (index > -1) listeners.splice(index, 1)
402
+ }
403
+ }
404
+ }
405
+ }
406
+ ```
407
+
408
+ ## Cross-Pattern Comparisons
409
+
410
+ ### OOP vs FP Comparison
411
+
412
+ **OOP Approach**:
413
+ ```javascript
414
+ class UserService {
415
+ constructor(database, hasher) {
416
+ this.database = database
417
+ this.hasher = hasher
418
+ }
419
+
420
+ async saveUser(userData) {
421
+ const hashed = await this.hasher.hash(userData.password)
422
+ return this.database.save({ ...userData, password: hashed })
423
+ }
424
+ }
425
+ ```
426
+
427
+ **FP Approach**:
428
+ ```javascript
429
+ const createUserService = (database, hasher) => ({
430
+ saveUser: async (userData) => {
431
+ const hashed = await hasher.hash(userData.password)
432
+ return database.save({ ...userData, password: hashed })
433
+ }
434
+ })
435
+ ```
436
+
437
+ **Trade-offs**:
438
+ - FP: Simpler, more explicit, easier to test
439
+ - OOP: More familiar to some developers, encapsulation through privacy
440
+
441
+ ### Procedural vs FP
442
+
443
+ **Procedural**:
444
+ ```javascript
445
+ function processUsers(users) {
446
+ const result = []
447
+ for (let i = 0; i < users.length; i++) {
448
+ if (users[i].active) {
449
+ result.push({
450
+ ...users[i],
451
+ displayName: users[i].firstName + ' ' + users[i].lastName
452
+ })
453
+ }
454
+ }
455
+ return result
456
+ }
457
+ ```
458
+
459
+ **FP**:
460
+ ```javascript
461
+ const processUsers = (users) =>
462
+ users
463
+ .filter(user => user.active)
464
+ .map(user => ({
465
+ ...user,
466
+ displayName: `${user.firstName} ${user.lastName}`
467
+ }))
468
+ ```
469
+
470
+ **Trade-offs**:
471
+ - FP: More declarative, easier to understand intent
472
+ - Procedural: More control, potentially more performant for very large datasets
473
+
474
+ ## When to Break the Rules
475
+
476
+ FP is a tool, not a religion. Break rules when:
477
+
478
+ 1. **Performance**: Mutation is faster for large datasets (measure first!)
479
+ 2. **Simplicity**: Sometimes procedural code is clearer
480
+ 3. **Library Integration**: Some libraries require mutation
481
+ 4. **Team Familiarity**: Don't force FP on a team that hates it
482
+
483
+ Always prioritize:
484
+ 1. Correctness
485
+ 2. Simplicity
486
+ 3. Maintainability
487
+ 4. Performance (when needed with evidence)