groundswell 0.0.2 → 1.0.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 (554) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +26 -9
  3. package/dist/cache/cache-key.d.ts +86 -0
  4. package/dist/cache/cache-key.d.ts.map +1 -0
  5. package/dist/cache/cache-key.js +204 -0
  6. package/dist/cache/cache-key.js.map +1 -0
  7. package/dist/cache/cache.d.ts +104 -0
  8. package/dist/cache/cache.d.ts.map +1 -0
  9. package/dist/cache/cache.js +179 -0
  10. package/dist/cache/cache.js.map +1 -0
  11. package/{src/cache/index.ts → dist/cache/index.d.ts} +1 -1
  12. package/dist/cache/index.d.ts.map +1 -0
  13. package/dist/cache/index.js +6 -0
  14. package/dist/cache/index.js.map +1 -0
  15. package/dist/core/agent.d.ts +203 -0
  16. package/dist/core/agent.d.ts.map +1 -0
  17. package/dist/core/agent.js +833 -0
  18. package/dist/core/agent.js.map +1 -0
  19. package/{src/core/context.ts → dist/core/context.d.ts} +16 -67
  20. package/dist/core/context.d.ts.map +1 -0
  21. package/dist/core/context.js +80 -0
  22. package/dist/core/context.js.map +1 -0
  23. package/dist/core/event-tree.d.ts +72 -0
  24. package/dist/core/event-tree.d.ts.map +1 -0
  25. package/dist/core/event-tree.js +211 -0
  26. package/dist/core/event-tree.js.map +1 -0
  27. package/{src/core/factory.ts → dist/core/factory.d.ts} +6 -27
  28. package/dist/core/factory.d.ts.map +1 -0
  29. package/dist/core/factory.js +110 -0
  30. package/dist/core/factory.js.map +1 -0
  31. package/{src/core/index.ts → dist/core/index.d.ts} +2 -10
  32. package/dist/core/index.d.ts.map +1 -0
  33. package/dist/core/index.js +9 -0
  34. package/dist/core/index.js.map +1 -0
  35. package/dist/core/logger.d.ts +50 -0
  36. package/dist/core/logger.d.ts.map +1 -0
  37. package/dist/core/logger.js +91 -0
  38. package/dist/core/logger.js.map +1 -0
  39. package/dist/core/mcp-handler.d.ts +127 -0
  40. package/dist/core/mcp-handler.d.ts.map +1 -0
  41. package/dist/core/mcp-handler.js +323 -0
  42. package/dist/core/mcp-handler.js.map +1 -0
  43. package/dist/core/prompt.d.ts +80 -0
  44. package/dist/core/prompt.d.ts.map +1 -0
  45. package/dist/core/prompt.js +120 -0
  46. package/dist/core/prompt.js.map +1 -0
  47. package/dist/core/workflow-context.d.ts +61 -0
  48. package/dist/core/workflow-context.d.ts.map +1 -0
  49. package/dist/core/workflow-context.js +358 -0
  50. package/dist/core/workflow-context.js.map +1 -0
  51. package/dist/core/workflow.d.ts +543 -0
  52. package/dist/core/workflow.d.ts.map +1 -0
  53. package/dist/core/workflow.js +986 -0
  54. package/dist/core/workflow.js.map +1 -0
  55. package/dist/debugger/event-replayer.d.ts +422 -0
  56. package/dist/debugger/event-replayer.d.ts.map +1 -0
  57. package/dist/debugger/event-replayer.js +639 -0
  58. package/dist/debugger/event-replayer.js.map +1 -0
  59. package/dist/debugger/index.d.ts +2 -0
  60. package/dist/debugger/index.d.ts.map +1 -0
  61. package/{src/debugger/index.ts → dist/debugger/index.js} +1 -0
  62. package/dist/debugger/index.js.map +1 -0
  63. package/dist/debugger/tree-debugger.d.ts +240 -0
  64. package/dist/debugger/tree-debugger.d.ts.map +1 -0
  65. package/dist/debugger/tree-debugger.js +620 -0
  66. package/dist/debugger/tree-debugger.js.map +1 -0
  67. package/dist/decorators/index.d.ts +4 -0
  68. package/dist/decorators/index.d.ts.map +1 -0
  69. package/{src/decorators/index.ts → dist/decorators/index.js} +1 -0
  70. package/dist/decorators/index.js.map +1 -0
  71. package/dist/decorators/observed-state.d.ts +32 -0
  72. package/dist/decorators/observed-state.d.ts.map +1 -0
  73. package/dist/decorators/observed-state.js +79 -0
  74. package/dist/decorators/observed-state.js.map +1 -0
  75. package/dist/decorators/step.d.ts +15 -0
  76. package/dist/decorators/step.d.ts.map +1 -0
  77. package/dist/decorators/step.js +192 -0
  78. package/dist/decorators/step.js.map +1 -0
  79. package/dist/decorators/task.d.ts +50 -0
  80. package/dist/decorators/task.d.ts.map +1 -0
  81. package/dist/decorators/task.js +118 -0
  82. package/dist/decorators/task.js.map +1 -0
  83. package/dist/examples/index.d.ts +3 -0
  84. package/dist/examples/index.d.ts.map +1 -0
  85. package/{src/examples/index.ts → dist/examples/index.js} +1 -0
  86. package/dist/examples/index.js.map +1 -0
  87. package/dist/examples/tdd-orchestrator.d.ts +15 -0
  88. package/dist/examples/tdd-orchestrator.d.ts.map +1 -0
  89. package/dist/examples/tdd-orchestrator.js +121 -0
  90. package/dist/examples/tdd-orchestrator.js.map +1 -0
  91. package/dist/examples/test-cycle-workflow.d.ts +14 -0
  92. package/dist/examples/test-cycle-workflow.d.ts.map +1 -0
  93. package/dist/examples/test-cycle-workflow.js +116 -0
  94. package/dist/examples/test-cycle-workflow.js.map +1 -0
  95. package/dist/harnesses/claude-code-harness.d.ts +391 -0
  96. package/dist/harnesses/claude-code-harness.d.ts.map +1 -0
  97. package/dist/harnesses/claude-code-harness.js +1076 -0
  98. package/dist/harnesses/claude-code-harness.js.map +1 -0
  99. package/dist/harnesses/harness-registry.d.ts +440 -0
  100. package/dist/harnesses/harness-registry.d.ts.map +1 -0
  101. package/dist/harnesses/harness-registry.js +543 -0
  102. package/dist/harnesses/harness-registry.js.map +1 -0
  103. package/dist/harnesses/index.d.ts +12 -0
  104. package/dist/harnesses/index.d.ts.map +1 -0
  105. package/dist/harnesses/index.js +11 -0
  106. package/dist/harnesses/index.js.map +1 -0
  107. package/dist/harnesses/pi-harness.d.ts +219 -0
  108. package/dist/harnesses/pi-harness.d.ts.map +1 -0
  109. package/dist/harnesses/pi-harness.js +676 -0
  110. package/dist/harnesses/pi-harness.js.map +1 -0
  111. package/dist/harnesses/pi-schema-converter.d.ts +24 -0
  112. package/dist/harnesses/pi-schema-converter.d.ts.map +1 -0
  113. package/dist/harnesses/pi-schema-converter.js +81 -0
  114. package/dist/harnesses/pi-schema-converter.js.map +1 -0
  115. package/dist/harnesses/register-defaults.d.ts +24 -0
  116. package/dist/harnesses/register-defaults.d.ts.map +1 -0
  117. package/dist/harnesses/register-defaults.js +40 -0
  118. package/dist/harnesses/register-defaults.js.map +1 -0
  119. package/dist/harnesses/session-store.d.ts +201 -0
  120. package/dist/harnesses/session-store.d.ts.map +1 -0
  121. package/dist/harnesses/session-store.js +254 -0
  122. package/dist/harnesses/session-store.js.map +1 -0
  123. package/dist/index.d.ts +37 -0
  124. package/dist/index.d.ts.map +1 -0
  125. package/dist/index.js +57 -0
  126. package/dist/index.js.map +1 -0
  127. package/dist/reflection/index.d.ts +5 -0
  128. package/dist/reflection/index.d.ts.map +1 -0
  129. package/{src/reflection/index.ts → dist/reflection/index.js} +1 -1
  130. package/dist/reflection/index.js.map +1 -0
  131. package/dist/reflection/reflection.d.ts +84 -0
  132. package/dist/reflection/reflection.d.ts.map +1 -0
  133. package/dist/reflection/reflection.js +344 -0
  134. package/dist/reflection/reflection.js.map +1 -0
  135. package/dist/tools/index.d.ts +6 -0
  136. package/dist/tools/index.d.ts.map +1 -0
  137. package/dist/tools/index.js +11 -0
  138. package/dist/tools/index.js.map +1 -0
  139. package/dist/tools/introspection.d.ts +165 -0
  140. package/dist/tools/introspection.d.ts.map +1 -0
  141. package/dist/tools/introspection.js +324 -0
  142. package/dist/tools/introspection.js.map +1 -0
  143. package/dist/types/agent.d.ts +1317 -0
  144. package/dist/types/agent.d.ts.map +1 -0
  145. package/dist/types/agent.js +423 -0
  146. package/dist/types/agent.js.map +1 -0
  147. package/dist/types/decorators.d.ts +40 -0
  148. package/dist/types/decorators.d.ts.map +1 -0
  149. package/dist/types/decorators.js +2 -0
  150. package/dist/types/decorators.js.map +1 -0
  151. package/dist/types/error-strategy.d.ts +13 -0
  152. package/dist/types/error-strategy.d.ts.map +1 -0
  153. package/dist/types/error-strategy.js +2 -0
  154. package/dist/types/error-strategy.js.map +1 -0
  155. package/dist/types/error.d.ts +20 -0
  156. package/dist/types/error.d.ts.map +1 -0
  157. package/dist/types/error.js +2 -0
  158. package/dist/types/error.js.map +1 -0
  159. package/dist/types/events.d.ts +113 -0
  160. package/dist/types/events.d.ts.map +1 -0
  161. package/dist/types/events.js +2 -0
  162. package/dist/types/events.js.map +1 -0
  163. package/dist/types/harnesses.d.ts +474 -0
  164. package/dist/types/harnesses.d.ts.map +1 -0
  165. package/dist/types/harnesses.js +2 -0
  166. package/dist/types/harnesses.js.map +1 -0
  167. package/dist/types/index.d.ts +23 -0
  168. package/dist/types/index.d.ts.map +1 -0
  169. package/dist/types/index.js +8 -0
  170. package/dist/types/index.js.map +1 -0
  171. package/dist/types/logging.d.ts +24 -0
  172. package/dist/types/logging.d.ts.map +1 -0
  173. package/dist/types/logging.js +2 -0
  174. package/dist/types/logging.js.map +1 -0
  175. package/dist/types/observer.d.ts +18 -0
  176. package/dist/types/observer.d.ts.map +1 -0
  177. package/dist/types/observer.js +2 -0
  178. package/dist/types/observer.js.map +1 -0
  179. package/dist/types/prompt.d.ts +31 -0
  180. package/dist/types/prompt.d.ts.map +1 -0
  181. package/dist/types/prompt.js +6 -0
  182. package/dist/types/prompt.js.map +1 -0
  183. package/dist/types/providers.d.ts +691 -0
  184. package/dist/types/providers.d.ts.map +1 -0
  185. package/dist/types/providers.js +14 -0
  186. package/dist/types/providers.js.map +1 -0
  187. package/dist/types/reflection.d.ts +96 -0
  188. package/dist/types/reflection.d.ts.map +1 -0
  189. package/dist/types/reflection.js +24 -0
  190. package/dist/types/reflection.js.map +1 -0
  191. package/dist/types/restart.d.ts +132 -0
  192. package/dist/types/restart.d.ts.map +1 -0
  193. package/dist/types/restart.js +2 -0
  194. package/dist/types/restart.js.map +1 -0
  195. package/dist/types/sdk-primitives.d.ts +118 -0
  196. package/dist/types/sdk-primitives.d.ts.map +1 -0
  197. package/dist/types/sdk-primitives.js +6 -0
  198. package/dist/types/sdk-primitives.js.map +1 -0
  199. package/{src/types/snapshot.ts → dist/types/snapshot.d.ts} +5 -5
  200. package/dist/types/snapshot.d.ts.map +1 -0
  201. package/dist/types/snapshot.js +2 -0
  202. package/dist/types/snapshot.js.map +1 -0
  203. package/dist/types/streaming.d.ts +194 -0
  204. package/dist/types/streaming.d.ts.map +1 -0
  205. package/dist/types/streaming.js +67 -0
  206. package/dist/types/streaming.js.map +1 -0
  207. package/dist/types/workflow-context.d.ts +275 -0
  208. package/dist/types/workflow-context.d.ts.map +1 -0
  209. package/dist/types/workflow-context.js +8 -0
  210. package/dist/types/workflow-context.js.map +1 -0
  211. package/dist/types/workflow.d.ts +30 -0
  212. package/dist/types/workflow.d.ts.map +1 -0
  213. package/dist/types/workflow.js +2 -0
  214. package/dist/types/workflow.js.map +1 -0
  215. package/dist/utils/agent-validation.d.ts +88 -0
  216. package/dist/utils/agent-validation.d.ts.map +1 -0
  217. package/dist/utils/agent-validation.js +87 -0
  218. package/dist/utils/agent-validation.js.map +1 -0
  219. package/dist/utils/delay.d.ts +7 -0
  220. package/dist/utils/delay.d.ts.map +1 -0
  221. package/dist/utils/delay.js +9 -0
  222. package/dist/utils/delay.js.map +1 -0
  223. package/dist/utils/harness-config.d.ts +180 -0
  224. package/dist/utils/harness-config.d.ts.map +1 -0
  225. package/dist/utils/harness-config.js +311 -0
  226. package/dist/utils/harness-config.js.map +1 -0
  227. package/dist/utils/id.d.ts +6 -0
  228. package/dist/utils/id.d.ts.map +1 -0
  229. package/dist/utils/id.js +12 -0
  230. package/dist/utils/id.js.map +1 -0
  231. package/dist/utils/index.d.ts +13 -0
  232. package/dist/utils/index.d.ts.map +1 -0
  233. package/dist/utils/index.js +11 -0
  234. package/dist/utils/index.js.map +1 -0
  235. package/dist/utils/model-spec.d.ts +110 -0
  236. package/dist/utils/model-spec.d.ts.map +1 -0
  237. package/dist/utils/model-spec.js +149 -0
  238. package/dist/utils/model-spec.js.map +1 -0
  239. package/dist/utils/observable.d.ts +54 -0
  240. package/dist/utils/observable.d.ts.map +1 -0
  241. package/dist/utils/observable.js +82 -0
  242. package/dist/utils/observable.js.map +1 -0
  243. package/dist/utils/provider-config.d.ts +10 -0
  244. package/dist/utils/provider-config.d.ts.map +1 -0
  245. package/dist/utils/provider-config.js +10 -0
  246. package/dist/utils/provider-config.js.map +1 -0
  247. package/dist/utils/restart-analysis.d.ts +202 -0
  248. package/dist/utils/restart-analysis.d.ts.map +1 -0
  249. package/dist/utils/restart-analysis.js +426 -0
  250. package/dist/utils/restart-analysis.js.map +1 -0
  251. package/dist/utils/session-serialization.d.ts +118 -0
  252. package/dist/utils/session-serialization.d.ts.map +1 -0
  253. package/dist/utils/session-serialization.js +217 -0
  254. package/dist/utils/session-serialization.js.map +1 -0
  255. package/dist/utils/workflow-error-utils.d.ts +22 -0
  256. package/dist/utils/workflow-error-utils.d.ts.map +1 -0
  257. package/dist/utils/workflow-error-utils.js +45 -0
  258. package/dist/utils/workflow-error-utils.js.map +1 -0
  259. package/package.json +34 -5
  260. package/.claude/commands/subtask-planning/prp-base-create.md +0 -120
  261. package/.claude/commands/subtask-planning/prp-base-execute.md +0 -65
  262. package/.claude/commands/task-breakdown.md +0 -94
  263. package/.claude/settings.local.json +0 -9
  264. package/.claude/system_prompts/task-breakdown.md +0 -101
  265. package/CHANGELOG.md +0 -188
  266. package/PRD.md +0 -543
  267. package/PRPs/001-hierarchical-workflow-engine.md +0 -2438
  268. package/PRPs/PRDs/002-agent-prompt.md +0 -390
  269. package/PRPs/PRDs/003-agent-prompt.md +0 -943
  270. package/PRPs/PRDs/004-agent-prompt.md +0 -1136
  271. package/PRPs/PRDs/tasks-001.json +0 -492
  272. package/PRPs/README.md +0 -83
  273. package/PRPs/templates/prp_base.md +0 -222
  274. package/docs/agent.md +0 -422
  275. package/docs/prompt.md +0 -419
  276. package/docs/workflow.md +0 -600
  277. package/examples/README.md +0 -258
  278. package/examples/examples/01-basic-workflow.ts +0 -100
  279. package/examples/examples/02-decorator-options.ts +0 -217
  280. package/examples/examples/03-parent-child.ts +0 -241
  281. package/examples/examples/04-observers-debugger.ts +0 -340
  282. package/examples/examples/05-error-handling.ts +0 -387
  283. package/examples/examples/06-concurrent-tasks.ts +0 -352
  284. package/examples/examples/07-agent-loops.ts +0 -432
  285. package/examples/examples/08-sdk-features.ts +0 -667
  286. package/examples/examples/09-reflection.ts +0 -573
  287. package/examples/examples/10-introspection.ts +0 -550
  288. package/examples/examples/11-reparenting-workflows.ts +0 -269
  289. package/examples/index.ts +0 -147
  290. package/examples/utils/helpers.ts +0 -57
  291. package/package-lock.json +0 -2398
  292. package/plan/001_d3bb02af4886/TEST_RESULTS.md +0 -259
  293. package/plan/001_d3bb02af4886/backlog.json +0 -867
  294. package/plan/001_d3bb02af4886/bug_fix_tasks.json +0 -484
  295. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S1/PRP.md +0 -488
  296. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S2/PRP.md +0 -581
  297. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S3/PRP.md +0 -687
  298. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S1/PRP.md +0 -492
  299. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/PRP.md +0 -932
  300. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/concurrent_error_testing_patterns.md +0 -1109
  301. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/vitest_concurrent_testing.md +0 -802
  302. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/workflow_engine_test_references.md +0 -603
  303. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S1/PRP.md +0 -564
  304. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S3/PRP.md +0 -518
  305. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S4/PRP.md +0 -1252
  306. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/PRP.md +0 -364
  307. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/CODEBASE_INVENTORY.md +0 -114
  308. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/DECORATOR_DOCUMENTATION_PATTERNS.md +0 -205
  309. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/PRD_LOCATION_ANALYSIS.md +0 -199
  310. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/ULTRATHINK_PRP_PLAN.md +0 -134
  311. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/PRP.md +0 -495
  312. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/research/console_error_inventory.md +0 -435
  313. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S2/PRP.md +0 -506
  314. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S3/PRP.md +0 -612
  315. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/PRP.md +0 -558
  316. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/research/external_research.md +0 -788
  317. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S2/PRP.md +0 -460
  318. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S3/PRP.md +0 -454
  319. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/PRP.md +0 -520
  320. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/RECOMMENDATION.md +0 -417
  321. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/external_workflow_engines_research.md +0 -760
  322. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/security_implications_analysis.md +0 -245
  323. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S2/PRP.md +0 -792
  324. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/PRP.md +0 -535
  325. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/TEST_EXECUTION_REPORT.md +0 -190
  326. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/PRP.md +0 -654
  327. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/TEST_FIX_REPORT.md +0 -227
  328. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/KEY_FINDINGS.md +0 -345
  329. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/QUICK_REFERENCE.md +0 -193
  330. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/test_maintenance_research.md +0 -1323
  331. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/BREAKING_CHANGES_AUDIT.md +0 -1011
  332. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/PRP.md +0 -927
  333. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S2/PRP.md +0 -505
  334. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/architecture/logger_child_signature_analysis.md +0 -401
  335. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/child_implementation_research.md +0 -142
  336. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/test_patterns_research.md +0 -112
  337. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/vitest_patterns_research.md +0 -159
  338. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/PRP.md +0 -549
  339. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/VERIFICATION_REPORT.md +0 -368
  340. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/edge_case_analysis.md +0 -172
  341. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/usage_inventory.md +0 -175
  342. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S2/PRP.md +0 -696
  343. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S4/PRP.md +0 -860
  344. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/PRP.md +0 -1066
  345. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01-testing-aggregated-errors.md +0 -1103
  346. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01_typescript_error_aggregation_patterns.md +0 -789
  347. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02-error-merge-strategy-testing-guide.md +0 -1098
  348. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02_aggregate_error_patterns.md +0 -1037
  349. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03-promise-allsettled-testing-patterns.md +0 -916
  350. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03_error_merging_strategies.md +0 -1045
  351. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/04_github_stackoverflow_examples.md +0 -890
  352. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/05_comprehensive_summary.md +0 -822
  353. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/INDEX.md +0 -668
  354. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/QUICK_REFERENCE.md +0 -706
  355. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/README.md +0 -265
  356. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/RESEARCH_REPORT.md +0 -655
  357. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S4/research/vitest_testing_patterns.md +0 -1103
  358. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T3S2/PRP.md +0 -426
  359. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/PRP.md +0 -506
  360. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/QUICK_REFERENCE.md +0 -114
  361. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/RESEARCH_SUMMARY.md +0 -316
  362. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/vitest_observer_error_logging_best_practices.md +0 -754
  363. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S3/PRP.md +0 -612
  364. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/PRP.md +0 -719
  365. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/README.md +0 -215
  366. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/analysis.md +0 -765
  367. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S3/PRP.md +0 -718
  368. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/DECISION.md +0 -149
  369. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/PRP.md +0 -470
  370. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/ULTRATHINK_PLAN.md +0 -332
  371. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/codebase_workflow_name_analysis.md +0 -167
  372. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/external_best_practices.md +0 -265
  373. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/validation_patterns.md +0 -273
  374. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S1/workflow_engine_ancestry_api_research.md +0 -760
  375. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S3-PRP.md +0 -434
  376. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S1/PRP.md +0 -717
  377. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/PRP.md +0 -472
  378. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/VALIDATION_REPORT.md +0 -125
  379. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/research/ULTRATHINK_PRP_PLAN.md +0 -301
  380. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/error-logging-best-practices.md +0 -1170
  381. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/research_typescript_partial_and_overloads.md +0 -940
  382. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-quick-reference.md +0 -151
  383. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-research.md +0 -650
  384. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/prd_snapshot.md +0 -259
  385. package/plan/001_d3bb02af4886/bugfix/P1M1T1S1/PRP.md +0 -457
  386. package/plan/001_d3bb02af4886/bugfix/RESEARCH_SUMMARY.md +0 -346
  387. package/plan/001_d3bb02af4886/bugfix/architecture/codebase_structure.md +0 -311
  388. package/plan/001_d3bb02af4886/bugfix/architecture/concurrent_execution_best_practices.md +0 -1565
  389. package/plan/001_d3bb02af4886/bugfix/architecture/error_handling_patterns.md +0 -288
  390. package/plan/001_d3bb02af4886/bugfix/architecture/promise_all_analysis.md +0 -741
  391. package/plan/001_d3bb02af4886/docs/PRP/P1M1T1S4-functional-workflow-error-state-capture-test.md +0 -652
  392. package/plan/001_d3bb02af4886/docs/PRP/P1P2-PRP.md +0 -527
  393. package/plan/001_d3bb02af4886/docs/PRP/P3P4-PRP.md +0 -1388
  394. package/plan/001_d3bb02af4886/docs/PRP/P4P5-PRP.md +0 -1136
  395. package/plan/001_d3bb02af4886/docs/PRP/PRP.md +0 -527
  396. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S1-PRP.md +0 -415
  397. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S2-PRP.md +0 -378
  398. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S4-PRP.md +0 -713
  399. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M2T1S4-PRP.md +0 -370
  400. package/plan/001_d3bb02af4886/docs/PRP_P1M3T1S3.md +0 -499
  401. package/plan/001_d3bb02af4886/docs/TEST_RESULTS.md +0 -230
  402. package/plan/001_d3bb02af4886/docs/architecture/external_deps.md +0 -358
  403. package/plan/001_d3bb02af4886/docs/architecture/system_context.md +0 -242
  404. package/plan/001_d3bb02af4886/docs/bugfix/ANALYSIS_PRD_VS_IMPLEMENTATION.md +0 -1134
  405. package/plan/001_d3bb02af4886/docs/bugfix/GAP_ANALYSIS_SUMMARY.md +0 -179
  406. package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/PRP.md +0 -629
  407. package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/validation-report.md +0 -214
  408. package/plan/001_d3bb02af4886/docs/bugfix/PRP_P1M4T2S3.md +0 -629
  409. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_PRP.md +0 -529
  410. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_QUICK_REFERENCE.md +0 -142
  411. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_README.md +0 -304
  412. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_TEST_RESULTS.md +0 -558
  413. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_VALIDATION_SUMMARY.md +0 -256
  414. package/plan/001_d3bb02af4886/docs/bugfix/system_context.md +0 -346
  415. package/plan/001_d3bb02af4886/docs/bugfix-architecture/bug_analysis.md +0 -415
  416. package/plan/001_d3bb02af4886/docs/bugfix-architecture/implementation_patterns.md +0 -489
  417. package/plan/001_d3bb02af4886/docs/bugfix-architecture/system_context.md +0 -218
  418. package/plan/001_d3bb02af4886/docs/bugfix_INITIATION_SUMMARY.md +0 -380
  419. package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_PATTERNS.md +0 -1923
  420. package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_QUICK_REF.md +0 -319
  421. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/codebase-context.md +0 -115
  422. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/cycle-detection-algorithms.md +0 -134
  423. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/test-patterns.md +0 -153
  424. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/workflow-class.md +0 -132
  425. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_BEST_PRACTICES.md +0 -716
  426. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_QUICK_REF.md +0 -186
  427. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/GROUNDSWELL_DECORATOR_EXAMPLES.md +0 -604
  428. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/INDEX.md +0 -213
  429. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/codebase_structure.md +0 -30
  430. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/existing_test_pattern.md +0 -56
  431. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/getRootObservers_implementation.md +0 -53
  432. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/test_conventions.md +0 -49
  433. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/PRP.md +0 -958
  434. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/QUICK_REFERENCE.md +0 -339
  435. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/README.md +0 -305
  436. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/SUMMARY.md +0 -433
  437. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/bidirectional-tree-consistency-testing.md +0 -1574
  438. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/test-pattern-examples.md +0 -1014
  439. package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_BEST_PRACTICES.md +0 -1929
  440. package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_CODE_PATTERNS.md +0 -857
  441. package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_INTEGRATION_GUIDE.md +0 -738
  442. package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_RESEARCH_INDEX.md +0 -424
  443. package/plan/001_d3bb02af4886/docs/research/P1P2/REFLECTION_INDEX.md +0 -291
  444. package/plan/001_d3bb02af4886/docs/research/P1P2/REFLECTION_RESEARCH_REPORT.md +0 -1342
  445. package/plan/001_d3bb02af4886/docs/research/P1P2/RESEARCH_SUMMARY.md +0 -342
  446. package/plan/001_d3bb02af4886/docs/research/P1P2/anthropic-sdk.md +0 -174
  447. package/plan/001_d3bb02af4886/docs/research/P1P2/async-local-storage.md +0 -200
  448. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-code-patterns.md +0 -1205
  449. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-decision-matrix.md +0 -421
  450. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-implementation-guide.md +0 -1341
  451. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-integration-guide.md +0 -834
  452. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-patterns.md +0 -1468
  453. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-quick-reference.md +0 -558
  454. package/plan/001_d3bb02af4886/docs/research/P1P2/zod-schema.md +0 -152
  455. package/plan/001_d3bb02af4886/docs/research/P3P4/caching-lru.md +0 -116
  456. package/plan/001_d3bb02af4886/docs/research/P3P4/introspection-tools.md +0 -177
  457. package/plan/001_d3bb02af4886/docs/research/P3P4/reflection-patterns.md +0 -117
  458. package/plan/001_d3bb02af4886/docs/research/P4P5/RESEARCH_SUMMARY.md +0 -151
  459. package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_QUICK_REF.md +0 -376
  460. package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_RESEARCH.md +0 -1507
  461. package/plan/001_d3bb02af4886/docs/research/bugfix_typescript_patterns.md +0 -949
  462. package/plan/001_d3bb02af4886/docs/research/error-testing-research.md +0 -619
  463. package/plan/001_d3bb02af4886/docs/research/error_handling_patterns.md +0 -723
  464. package/plan/001_d3bb02af4886/docs/research/general/INTROSPECTION_RESEARCH_SUMMARY.md +0 -378
  465. package/plan/001_d3bb02af4886/docs/research/general/README-INTROSPECTION.md +0 -352
  466. package/plan/001_d3bb02af4886/docs/research/general/agent-introspection-patterns.md +0 -1085
  467. package/plan/001_d3bb02af4886/docs/research/general/introspection-security-guide.md +0 -984
  468. package/plan/001_d3bb02af4886/docs/research/general/introspection-tool-examples.md +0 -875
  469. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/PRP_TEMPLATE.md +0 -460
  470. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/QUICK_REFERENCE.md +0 -324
  471. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/README.md +0 -175
  472. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/RESEARCH_REPORT.md +0 -499
  473. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/SUMMARY.md +0 -163
  474. package/plan/001_d3bb02af4886/prd_snapshot.md +0 -543
  475. package/plan/bugfix/BUG_FIX_SUMMARY.md +0 -961
  476. package/scripts/generate-llms-full.ts +0 -206
  477. package/src/__tests__/adversarial/attachChild-performance.test.ts +0 -216
  478. package/src/__tests__/adversarial/circular-reference.test.ts +0 -101
  479. package/src/__tests__/adversarial/complex-circular-reference.test.ts +0 -139
  480. package/src/__tests__/adversarial/concurrent-task-failures.test.ts +0 -571
  481. package/src/__tests__/adversarial/deep-analysis.test.ts +0 -729
  482. package/src/__tests__/adversarial/deep-hierarchy-stress.test.ts +0 -213
  483. package/src/__tests__/adversarial/e2e-prd-validation.test.ts +0 -448
  484. package/src/__tests__/adversarial/edge-case.test.ts +0 -703
  485. package/src/__tests__/adversarial/error-merge-strategy.test.ts +0 -760
  486. package/src/__tests__/adversarial/incremental-performance.test.ts +0 -140
  487. package/src/__tests__/adversarial/node-map-update-benchmarks.test.ts +0 -457
  488. package/src/__tests__/adversarial/observer-propagation.test.ts +0 -487
  489. package/src/__tests__/adversarial/parent-validation.test.ts +0 -143
  490. package/src/__tests__/adversarial/prd-12-2-compliance.test.ts +0 -611
  491. package/src/__tests__/adversarial/prd-compliance.test.ts +0 -731
  492. package/src/__tests__/compatibility/backward-compatibility.test.ts +0 -1572
  493. package/src/__tests__/helpers/index.ts +0 -18
  494. package/src/__tests__/helpers/tree-verification.ts +0 -257
  495. package/src/__tests__/integration/agent-workflow.test.ts +0 -256
  496. package/src/__tests__/integration/bidirectional-consistency.test.ts +0 -847
  497. package/src/__tests__/integration/observer-logging.test.ts +0 -643
  498. package/src/__tests__/integration/tree-mirroring.test.ts +0 -151
  499. package/src/__tests__/integration/workflow-reparenting.test.ts +0 -303
  500. package/src/__tests__/unit/agent.test.ts +0 -169
  501. package/src/__tests__/unit/cache-key.test.ts +0 -182
  502. package/src/__tests__/unit/cache.test.ts +0 -172
  503. package/src/__tests__/unit/context.test.ts +0 -217
  504. package/src/__tests__/unit/decorators.test.ts +0 -100
  505. package/src/__tests__/unit/introspection-tools.test.ts +0 -277
  506. package/src/__tests__/unit/logger.test.ts +0 -293
  507. package/src/__tests__/unit/observable.test.ts +0 -321
  508. package/src/__tests__/unit/prompt.test.ts +0 -135
  509. package/src/__tests__/unit/reflection.test.ts +0 -210
  510. package/src/__tests__/unit/tree-debugger-incremental.test.ts +0 -170
  511. package/src/__tests__/unit/tree-debugger.test.ts +0 -85
  512. package/src/__tests__/unit/utils/workflow-error-utils.test.ts +0 -209
  513. package/src/__tests__/unit/workflow-detachChild.test.ts +0 -100
  514. package/src/__tests__/unit/workflow-emitEvent-childDetached.test.ts +0 -153
  515. package/src/__tests__/unit/workflow-isDescendantOf.test.ts +0 -180
  516. package/src/__tests__/unit/workflow.test.ts +0 -357
  517. package/src/cache/cache-key.ts +0 -244
  518. package/src/cache/cache.ts +0 -236
  519. package/src/core/agent.ts +0 -593
  520. package/src/core/event-tree.ts +0 -260
  521. package/src/core/logger.ts +0 -112
  522. package/src/core/mcp-handler.ts +0 -184
  523. package/src/core/prompt.ts +0 -150
  524. package/src/core/workflow-context.ts +0 -351
  525. package/src/core/workflow.ts +0 -540
  526. package/src/debugger/tree-debugger.ts +0 -255
  527. package/src/decorators/observed-state.ts +0 -95
  528. package/src/decorators/step.ts +0 -139
  529. package/src/decorators/task.ts +0 -159
  530. package/src/examples/tdd-orchestrator.ts +0 -65
  531. package/src/examples/test-cycle-workflow.ts +0 -64
  532. package/src/index.ts +0 -142
  533. package/src/reflection/reflection.ts +0 -407
  534. package/src/tools/index.ts +0 -36
  535. package/src/tools/introspection.ts +0 -464
  536. package/src/types/agent.ts +0 -90
  537. package/src/types/decorators.ts +0 -32
  538. package/src/types/error-strategy.ts +0 -13
  539. package/src/types/error.ts +0 -20
  540. package/src/types/events.ts +0 -75
  541. package/src/types/index.ts +0 -55
  542. package/src/types/logging.ts +0 -24
  543. package/src/types/observer.ts +0 -18
  544. package/src/types/prompt.ts +0 -40
  545. package/src/types/reflection.ts +0 -117
  546. package/src/types/sdk-primitives.ts +0 -128
  547. package/src/types/workflow-context.ts +0 -163
  548. package/src/types/workflow.ts +0 -37
  549. package/src/utils/id.ts +0 -11
  550. package/src/utils/index.ts +0 -4
  551. package/src/utils/observable.ts +0 -106
  552. package/src/utils/workflow-error-utils.ts +0 -56
  553. package/tsconfig.json +0 -22
  554. package/vitest.config.ts +0 -16
@@ -1,1507 +0,0 @@
1
- # Promise.allSettled Best Practices, Patterns, and Migration Strategies
2
-
3
- **Research Date:** 2026-01-12
4
- **Status:** Comprehensive Research Report
5
- **Target:** Groundswell Hierarchical Workflow Engine - P1.M2.T1 Implementation
6
-
7
- ---
8
-
9
- ## Executive Summary
10
-
11
- This document provides comprehensive research on Promise.allSettled including official documentation, best practices, migration strategies from Promise.all, error aggregation patterns, TypeScript typing patterns, common pitfalls, and production examples. It serves as the foundational research for migrating the Groundswell workflow engine from Promise.all to Promise.allSettled in concurrent task execution.
12
-
13
- **Key Finding:** Promise.allSettled is the recommended approach for concurrent workflow execution in Groundswell due to its superior observability, error aggregation capabilities, and alignment with production workflow engines like Airflow and AWS Step Functions.
14
-
15
- ---
16
-
17
- ## Table of Contents
18
-
19
- 1. [Official Documentation Resources](#1-official-documentation-resources)
20
- 2. [Promise.all vs Promise.allSettled: Technical Comparison](#2-promiseall-vs-promiseallsettled-technical-comparison)
21
- 3. [Migration Strategies from Promise.all](#3-migration-strategies-from-promiseall)
22
- 4. [Error Aggregation Patterns](#4-error-aggregation-patterns)
23
- 5. [TypeScript Typing Patterns](#5-typescript-typing-patterns)
24
- 6. [Common Pitfalls and Gotchas](#6-common-pitfalls-and-gotchas)
25
- 7. [Production Examples from GitHub](#7-production-examples-from-github)
26
- 8. [StackOverflow Community Insights](#8-stackoverflow-community-insights)
27
- 9. [Groundswell-Specific Implementation Guide](#9-groundswell-specific-implementation-guide)
28
- 10. [Quick Reference Card](#10-quick-reference-card)
29
-
30
- ---
31
-
32
- ## 1. Official Documentation Resources
33
-
34
- ### 1.1 MDN Web Docs
35
-
36
- #### Promise.allSettled()
37
- - **URL:** https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled
38
- - **Section:** #description
39
- - **Key Points:**
40
- - Returns a promise that resolves after all given promises have settled
41
- - Returns array of PromiseSettledResult objects with status and value/reason
42
- - Never rejects - always fulfills
43
- - ES2020 feature (Node.js 12.9+, Chrome 76+, Firefox 71+, Safari 13+)
44
-
45
- **Relevance:** Authoritative reference for Promise.allSettled behavior and browser compatibility.
46
-
47
- #### Promise.all()
48
- - **URL:** https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
49
- - **Section:** #behavior
50
- - **Key Points:**
51
- - Fail-fast behavior: rejects immediately when any promise rejects
52
- - Returns array of resolved values when all fulfill
53
- - Orders results by promise input order
54
- - ES2015 feature (widely supported)
55
-
56
- **Relevance:** Understanding the behavior we're migrating from to ensure proper comparison.
57
-
58
- #### TypeScript Handbook: Promise Types
59
- - **URL:** https://www.typescriptlang.org/docs/handbook/2/types-from-types.html#promise-types
60
- - **Section:** Promise Types
61
- - **Key Points:**
62
- - Promise<T> represents async operations
63
- - PromiseSettledResult<T> type for allSettled results
64
- - Type guards for discriminating unions
65
-
66
- **Relevance:** TypeScript type safety for Promise.allSettled implementations.
67
-
68
- ### 1.2 ECMAScript Specification
69
-
70
- #### ECMA-262: Promise.allSettled
71
- - **URL:** https://tc39.es/ecma262/#sec-promise.allsettled
72
- - **Section:** 25.6.4.4
73
- - **Key Points:**
74
- - Exact algorithm specification
75
- - Promise resolution behavior
76
- - PerformPromiseAllSettled algorithm
77
-
78
- **Relevance:** Deep technical understanding of the specification for edge cases.
79
-
80
- ### 1.3 Node.js Documentation
81
-
82
- #### Node.js Promise.allSettled
83
- - **URL:** https://nodejs.org/api/esm.html#esm_shared_global_builtins
84
- - **Section:** Shared globals
85
- - **Key Points:**
86
- - Available in Node.js 12.9.0+
87
- - No polyfill needed for modern Node.js
88
- - Performance characteristics
89
-
90
- **Relevance:** Server-side JavaScript implementation details.
91
-
92
- ---
93
-
94
- ## 2. Promise.all vs Promise.allSettled: Technical Comparison
95
-
96
- ### 2.1 Behavioral Differences
97
-
98
- #### Promise.all (Fail-Fast)
99
-
100
- ```typescript
101
- const results = await Promise.all([
102
- fetch('/api/user'),
103
- fetch('/api/posts'),
104
- fetch('/api/comments')
105
- ]);
106
- // If ANY request fails, immediately rejects
107
- // Other in-flight requests continue but results are lost
108
- // Only first error is visible
109
- ```
110
-
111
- **Characteristics:**
112
- - ✅ Fast failure detection
113
- - ✅ Simple mental model
114
- - ✅ Lower memory overhead
115
- - ❌ Loses partial results
116
- - ❌ Hides concurrent errors
117
- - ❌ Poor debugging experience
118
-
119
- #### Promise.allSettled (Complete-All)
120
-
121
- ```typescript
122
- const results = await Promise.allSettled([
123
- fetch('/api/user'),
124
- fetch('/api/posts'),
125
- fetch('/api/comments')
126
- ]);
127
- // ALL requests complete regardless of failures
128
- // Returns array of {status, value/reason} objects
129
- // All errors visible and preserved
130
- ```
131
-
132
- **Characteristics:**
133
- - ✅ Complete error visibility
134
- - ✅ Preserves partial results
135
- - ✅ Better debugging
136
- - ✅ Error pattern analysis
137
- - ❌ Slower failure detection
138
- - ❌ Higher memory usage
139
- - ❌ More complex error handling
140
-
141
- ### 2.2 Result Structure Comparison
142
-
143
- ```typescript
144
- // Promise.all result (on success)
145
- const allResults: string[] = ['result1', 'result2', 'result3'];
146
-
147
- // Promise.allSettled result (mixed)
148
- const allSettledResults: PromiseSettledResult<string>[] = [
149
- { status: 'fulfilled', value: 'result1' },
150
- { status: 'rejected', reason: Error('failed') },
151
- { status: 'fulfilled', value: 'result3' }
152
- ];
153
- ```
154
-
155
- ### 2.3 Performance Comparison
156
-
157
- | Metric | Promise.all | Promise.allSettled |
158
- |--------|-------------|-------------------|
159
- | Time to First Error | Immediate (min time) | Waits for all (max time) |
160
- | Time to Complete All | N/A (fails early) | Max of all operations |
161
- | Memory Usage | Low | Higher (stores all errors) |
162
- | Error Completeness | First error only | All errors |
163
- | Partial Results | Lost | Preserved |
164
- | Cancellation | Manual (abort controllers) | Manual (abort controllers) |
165
-
166
- ---
167
-
168
- ## 3. Migration Strategies from Promise.all
169
-
170
- ### 3.1 Direct Migration Pattern
171
-
172
- #### Before (Promise.all)
173
-
174
- ```typescript
175
- async function fetchAllData() {
176
- try {
177
- const results = await Promise.all([
178
- fetchUser(),
179
- fetchPosts(),
180
- fetchComments()
181
- ]);
182
- return { success: true, data: results };
183
- } catch (error) {
184
- return { success: false, error };
185
- }
186
- }
187
- ```
188
-
189
- #### After (Promise.allSettled)
190
-
191
- ```typescript
192
- async function fetchAllData() {
193
- const results = await Promise.allSettled([
194
- fetchUser(),
195
- fetchPosts(),
196
- fetchComments()
197
- ]);
198
-
199
- const successes = results
200
- .filter((r): r is PromiseFulfilledResult<unknown> => r.status === 'fulfilled')
201
- .map(r => r.value);
202
-
203
- const failures = results
204
- .filter((r): r is PromiseRejectedResult => r.status === 'rejected')
205
- .map(r => r.reason);
206
-
207
- if (failures.length > 0) {
208
- return { success: false, errors: failures, partial: successes };
209
- }
210
-
211
- return { success: true, data: successes };
212
- }
213
- ```
214
-
215
- ### 3.2 Backward Compatibility Pattern
216
-
217
- **Strategy:** Maintain existing API contract while using allSettled internally.
218
-
219
- ```typescript
220
- async function fetchAllDataWithBackwardCompat() {
221
- const results = await Promise.allSettled([
222
- fetchUser(),
223
- fetchPosts(),
224
- fetchComments()
225
- ]);
226
-
227
- // Filter for failures
228
- const failures = results.filter(r => r.status === 'rejected');
229
-
230
- // Throw first error to maintain backward compatibility
231
- if (failures.length > 0) {
232
- throw failures[0].reason; // First error wins (like Promise.all)
233
- }
234
-
235
- // Return values (like Promise.all)
236
- return results
237
- .filter((r): r is PromiseFulfilledResult<unknown> => r.status === 'fulfilled')
238
- .map(r => r.value);
239
- }
240
- ```
241
-
242
- ### 3.3 Gradual Migration Pattern
243
-
244
- **Phase 1:** Add feature flag for new behavior
245
-
246
- ```typescript
247
- interface Options {
248
- useAllSettled?: boolean;
249
- }
250
-
251
- async function fetchAllData(options: Options = {}) {
252
- if (options.useAllSettled) {
253
- // New behavior: collect all errors
254
- return fetchAllDataAllSettled();
255
- } else {
256
- // Old behavior: fail-fast
257
- return fetchAllDataAll();
258
- }
259
- }
260
- ```
261
-
262
- **Phase 2:** Monitor and validate new behavior
263
-
264
- ```typescript
265
- // Log error patterns
266
- async function fetchAllDataWithLogging(options: Options = {}) {
267
- if (options.useAllSettled) {
268
- const results = await Promise.allSettled(/* ... */);
269
- const failures = results.filter(r => r.status === 'rejected');
270
-
271
- // Log for monitoring
272
- logger.info('Promise.allSettled', {
273
- total: results.length,
274
- failed: failures.length,
275
- errorRate: failures.length / results.length
276
- });
277
-
278
- return processResults(results);
279
- } else {
280
- return fetchAllDataAll();
281
- }
282
- }
283
- ```
284
-
285
- **Phase 3:** Switch default and deprecate old behavior
286
-
287
- ```typescript
288
- async function fetchAllData(options: Options = {}) {
289
- // Default to allSettled
290
- const useAllSettled = options.useAllSettled ?? true;
291
-
292
- if (useAllSettled) {
293
- return fetchAllDataAllSettled();
294
- } else {
295
- logger.warn('Deprecated: useAllSettled=false is deprecated');
296
- return fetchAllDataAll();
297
- }
298
- }
299
- ```
300
-
301
- ### 3.4 Error Aggregation Pattern
302
-
303
- ```typescript
304
- interface AggregateError extends Error {
305
- errors: unknown[];
306
- }
307
-
308
- async function fetchAllDataAggregated() {
309
- const results = await Promise.allSettled([
310
- fetchUser(),
311
- fetchPosts(),
312
- fetchComments()
313
- ]);
314
-
315
- const failures = results
316
- .filter((r): r is PromiseRejectedResult => r.status === 'rejected')
317
- .map(r => r.reason);
318
-
319
- if (failures.length > 0) {
320
- // Create aggregate error
321
- const error = new Error(
322
- `${failures.length} operations failed`
323
- ) as AggregateError;
324
- error.errors = failures;
325
- throw error;
326
- }
327
-
328
- return results
329
- .filter((r): r is PromiseFulfilledResult<unknown> => r.status === 'fulfilled')
330
- .map(r => r.value);
331
- }
332
- ```
333
-
334
- ---
335
-
336
- ## 4. Error Aggregation Patterns
337
-
338
- ### 4.1 Simple Error Collection
339
-
340
- ```typescript
341
- async function executeWithErrorCollection<T>(
342
- promises: Promise<T>[]
343
- ): Promise<{ values: T[]; errors: unknown[] }> {
344
- const results = await Promise.allSettled(promises);
345
-
346
- const values: T[] = [];
347
- const errors: unknown[] = [];
348
-
349
- for (const result of results) {
350
- if (result.status === 'fulfilled') {
351
- values.push(result.value);
352
- } else {
353
- errors.push(result.reason);
354
- }
355
- }
356
-
357
- return { values, errors };
358
- }
359
- ```
360
-
361
- ### 4.2 Typed Error Aggregation
362
-
363
- ```typescript
364
- interface ExecutionResult<T, E = Error> {
365
- success: boolean;
366
- value?: T;
367
- error?: E;
368
- }
369
-
370
- async function executeWithTypedErrors<T>(
371
- promises: Promise<T>[]
372
- ): Promise<ExecutionResult<T>[]> {
373
- const results = await Promise.allSettled(promises);
374
-
375
- return results.map(result => {
376
- if (result.status === 'fulfilled') {
377
- return { success: true, value: result.value };
378
- } else {
379
- return {
380
- success: false,
381
- error: result.reason instanceof Error ? result.reason : new Error(String(result.reason))
382
- };
383
- }
384
- });
385
- }
386
- ```
387
-
388
- ### 4.3 Hierarchical Error Aggregation
389
-
390
- ```typescript
391
- interface WorkflowAggregateError extends Error {
392
- name: 'WorkflowAggregateError';
393
- errors: Array<{
394
- workflowId: string;
395
- error: unknown;
396
- }>;
397
- parentWorkflowId: string;
398
- }
399
-
400
- async function executeWorkflowsAggregated(
401
- workflows: Array<{ id: string; run: () => Promise<unknown> }>,
402
- parentId: string
403
- ): Promise<void> {
404
- const results = await Promise.allSettled(
405
- workflows.map(w => w.run())
406
- );
407
-
408
- const failures = workflows
409
- .map((w, i) => ({ workflow: w, result: results[i] }))
410
- .filter(({ result }) => result.status === 'rejected')
411
- .map(({ workflow, result }) => ({
412
- workflowId: workflow.id,
413
- error: (result as PromiseRejectedResult).reason
414
- }));
415
-
416
- if (failures.length > 0) {
417
- const error = new Error(
418
- `${failures.length} child workflows failed`
419
- ) as WorkflowAggregateError;
420
- error.name = 'WorkflowAggregateError';
421
- error.errors = failures;
422
- error.parentWorkflowId = parentId;
423
- throw error;
424
- }
425
- }
426
- ```
427
-
428
- ### 4.4 Error Rate Thresholding
429
-
430
- ```typescript
431
- interface ThresholdOptions {
432
- maxErrorRate: number; // 0.0 to 1.0
433
- minAbsoluteErrors: number;
434
- }
435
-
436
- async function executeWithThreshold<T>(
437
- promises: Promise<T>[],
438
- options: ThresholdOptions
439
- ): Promise<T[]> {
440
- const results = await Promise.allSettled(promises);
441
-
442
- const failures = results.filter(r => r.status === 'rejected');
443
- const errorRate = failures.length / results.length;
444
-
445
- const shouldThrow =
446
- failures.length >= options.minAbsoluteErrors ||
447
- errorRate > options.maxErrorRate;
448
-
449
- if (shouldThrow) {
450
- throw new Error(
451
- `Error rate ${(errorRate * 100).toFixed(1)}% exceeds threshold`
452
- );
453
- }
454
-
455
- return results
456
- .filter((r): r is PromiseFulfilledResult<T> => r.status === 'fulfilled')
457
- .map(r => r.value);
458
- }
459
- ```
460
-
461
- ### 4.5 Error Statistics and Analytics
462
-
463
- ```typescript
464
- interface ErrorStats {
465
- total: number;
466
- succeeded: number;
467
- failed: number;
468
- errorRate: number;
469
- errorsByType: Record<string, number>;
470
- }
471
-
472
- async function executeWithErrorStats<T>(
473
- promises: Promise<T>[]
474
- ): Promise<{ values: T[]; stats: ErrorStats }> {
475
- const results = await Promise.allSettled(promises);
476
-
477
- const failures = results.filter(r => r.status === 'rejected');
478
- const successes = results.filter(r => r.status === 'fulfilled');
479
-
480
- const errorsByType = failures.reduce((acc, result) => {
481
- const reason = (result as PromiseRejectedResult).reason;
482
- const type = reason?.constructor?.name || 'Unknown';
483
- acc[type] = (acc[type] || 0) + 1;
484
- return acc;
485
- }, {} as Record<string, number>);
486
-
487
- const stats: ErrorStats = {
488
- total: results.length,
489
- succeeded: successes.length,
490
- failed: failures.length,
491
- errorRate: failures.length / results.length,
492
- errorsByType
493
- };
494
-
495
- const values = successes
496
- .map((r): r is PromiseFulfilledResult<T> => r as PromiseFulfilledResult<T>)
497
- .map(r => r.value);
498
-
499
- return { values, stats };
500
- }
501
- ```
502
-
503
- ---
504
-
505
- ## 5. TypeScript Typing Patterns
506
-
507
- ### 5.1 Basic Type Guards
508
-
509
- ```typescript
510
- function isFulfilled<T>(result: PromiseSettledResult<T>): result is PromiseFulfilledResult<T> {
511
- return result.status === 'fulfilled';
512
- }
513
-
514
- function isRejected<T>(result: PromiseSettledResult<T>): result is PromiseRejectedResult {
515
- return result.status === 'rejected';
516
- }
517
-
518
- // Usage
519
- const results = await Promise.allSettled(promises);
520
- const successes = results.filter(isFulfilled);
521
- const failures = results.filter(isRejected);
522
- ```
523
-
524
- ### 5.2 Explicit Generic Types
525
-
526
- ```typescript
527
- // Specify the promise type
528
- const results = await Promise.allSettled<number>([
529
- Promise.resolve(1),
530
- Promise.reject('error'),
531
- Promise.resolve(2)
532
- ]);
533
-
534
- // Type is PromiseSettledResult<number>[]
535
- ```
536
-
537
- ### 5.3 Discriminated Union Pattern
538
-
539
- ```typescript
540
- type SettledResult<T, E = Error> =
541
- | { status: 'fulfilled'; value: T }
542
- | { status: 'rejected'; error: E };
543
-
544
- async function executeWithDiscriminatedUnion<T>(
545
- promises: Promise<T>[]
546
- ): Promise<SettledResult<T>[]> {
547
- const results = await Promise.allSettled(promises);
548
-
549
- return results.map(result => {
550
- if (result.status === 'fulfilled') {
551
- return { status: 'fulfilled' as const, value: result.value };
552
- } else {
553
- return {
554
- status: 'rejected' as const,
555
- error: result.reason instanceof Error ? result.reason : new Error(String(result.reason))
556
- };
557
- }
558
- });
559
- }
560
-
561
- // Type-safe usage
562
- for (const result of await executeWithDiscriminatedUnion(promises)) {
563
- if (result.status === 'fulfilled') {
564
- console.log(result.value); // TypeScript knows this is T
565
- } else {
566
- console.error(result.error.message); // TypeScript knows this is Error
567
- }
568
- }
569
- ```
570
-
571
- ### 5.4 Conditional Result Processing
572
-
573
- ```typescript
574
- async function processResults<T>(
575
- results: PromiseSettledResult<T>[]
576
- ): Promise<{ fulfilled: T[]; rejected: unknown[] }> {
577
- const separated = results.reduce(
578
- (acc, result) => {
579
- if (result.status === 'fulfilled') {
580
- acc.fulfilled.push(result.value);
581
- } else {
582
- acc.rejected.push(result.reason);
583
- }
584
- return acc;
585
- },
586
- { fulfilled: [] as T[], rejected: [] as unknown[] }
587
- );
588
-
589
- return separated;
590
- }
591
- ```
592
-
593
- ### 5.5 Async Generator Pattern
594
-
595
- ```typescript
596
- async function* executeAsAsyncGenerator<T>(
597
- promises: Promise<T>[]
598
- ): AsyncGenerator<{ status: 'fulfilled'; value: T } | { status: 'rejected'; error: unknown }> {
599
- const results = await Promise.allSettled(promises);
600
-
601
- for (const result of results) {
602
- if (result.status === 'fulfilled') {
603
- yield { status: 'fulfilled', value: result.value };
604
- } else {
605
- yield { status: 'rejected', error: result.reason };
606
- }
607
- }
608
- }
609
-
610
- // Usage
611
- for await (const result of executeAsAsyncGenerator(promises)) {
612
- if (result.status === 'fulfilled') {
613
- // Handle success
614
- } else {
615
- // Handle error
616
- }
617
- }
618
- ```
619
-
620
- ### 5.6 Utility Type for Results
621
-
622
- ```typescript
623
- type SettledPromises<T extends readonly unknown[]> = {
624
- -readonly [K in keyof T]: PromiseSettledResult<T[K]>;
625
- };
626
-
627
- async function typedAllSettled<T extends readonly unknown[]>(
628
- promises: T
629
- ): Promise<SettledPromises<T>> {
630
- return Promise.allSettled(promises) as Promise<SettledPromises<T>>;
631
- }
632
-
633
- // Usage - preserves tuple types
634
- const [userResult, postsResult] = await typedAllSettled([
635
- fetchUser(),
636
- fetchPosts()
637
- ]);
638
-
639
- if (userResult.status === 'fulfilled') {
640
- // TypeScript knows userResult.value is User
641
- }
642
- ```
643
-
644
- ---
645
-
646
- ## 6. Common Pitfalls and Gotchas
647
-
648
- ### 6.1 Forgetting to Filter Results
649
-
650
- **Problem:** Accessing value/reason without checking status.
651
-
652
- ```typescript
653
- // ❌ WRONG - Runtime error
654
- const results = await Promise.allSettled(promises);
655
- results.forEach(r => {
656
- console.log(r.value); // Error if r.status === 'rejected'
657
- });
658
-
659
- // ✅ CORRECT
660
- const results = await Promise.allSettled(promises);
661
- results.forEach(r => {
662
- if (r.status === 'fulfilled') {
663
- console.log(r.value);
664
- } else {
665
- console.error(r.reason);
666
- }
667
- });
668
- ```
669
-
670
- ### 6.2 Losing Type Information
671
-
672
- **Problem:** Not using type guards causes type narrowing issues.
673
-
674
- ```typescript
675
- // ❌ WRONG - TypeScript can't narrow
676
- const results = await Promise.allSettled(promises);
677
- const successes = results.filter(r => r.status === 'fulfilled');
678
- successes.forEach(s => {
679
- console.log(s.value); // TypeScript error: value might not exist
680
- });
681
-
682
- // ✅ CORRECT - Use type guard
683
- function isFulfilled<T>(result: PromiseSettledResult<T>): result is PromiseFulfilledResult<T> {
684
- return result.status === 'fulfilled';
685
- }
686
-
687
- const results = await Promise.allSettled(promises);
688
- const successes = results.filter(isFulfilled);
689
- successes.forEach(s => {
690
- console.log(s.value); // TypeScript knows value exists
691
- });
692
- ```
693
-
694
- ### 6.3 Assuming Order Preservation
695
-
696
- **Note:** Promise.allSettled DOES preserve order, but this is often misunderstood.
697
-
698
- ```typescript
699
- // Promise.allSettled preserves input order
700
- const promises = [
701
- Promise.resolve(1).then(() => delay(100)), // Slowest
702
- Promise.resolve(2).then(() => delay(10)),
703
- Promise.resolve(3).then(() => delay(50))
704
- ];
705
-
706
- const results = await Promise.allSettled(promises);
707
- // Results are in input order, not completion order
708
- console.log(results[0].value); // 1 (completed last but first in array)
709
- console.log(results[1].value); // 2
710
- console.log(results[2].value); // 3
711
- ```
712
-
713
- ### 6.4 Memory Leaks with Large Arrays
714
-
715
- **Problem:** Storing all results can consume significant memory.
716
-
717
- ```typescript
718
- // ❌ PROBLEMATIC - Stores all results in memory
719
- const results = await Promise.allSettled(largeArrayOfPromises);
720
-
721
- // ✅ BETTER - Process results as they settle
722
- async function processBatch<T>(
723
- promises: Promise<T>[],
724
- batchSize: number,
725
- processor: (results: PromiseSettledResult<T>[]) => void
726
- ) {
727
- for (let i = 0; i < promises.length; i += batchSize) {
728
- const batch = promises.slice(i, i + batchSize);
729
- const results = await Promise.allSettled(batch);
730
- processor(results);
731
- // Allow GC to clean up batch results
732
- }
733
- }
734
- ```
735
-
736
- ### 6.5 Ignoring Error Context
737
-
738
- **Problem:** Not capturing which operation failed.
739
-
740
- ```typescript
741
- // ❌ WRONG - Don't know which promise failed
742
- const results = await Promise.allSettled([
743
- fetch('/api/users'),
744
- fetch('/api/posts'),
745
- fetch('/api/comments')
746
- ]);
747
-
748
- // ✅ CORRECT - Associate results with operations
749
- const operations = [
750
- { name: 'users', promise: fetch('/api/users') },
751
- { name: 'posts', promise: fetch('/api/posts') },
752
- { name: 'comments', promise: fetch('/api/comments') }
753
- ];
754
-
755
- const results = await Promise.allSettled(operations.map(op => op.promise));
756
-
757
- const failures = operations
758
- .map((op, i) => ({ ...op, result: results[i] }))
759
- .filter(({ result }) => result.status === 'rejected')
760
- .map(({ name, result }) => ({
761
- operation: name,
762
- error: (result as PromiseRejectedResult).reason
763
- }));
764
- ```
765
-
766
- ### 6.6 Not Handling Non-Error Rejections
767
-
768
- **Problem:** Promises can reject with non-Error values.
769
-
770
- ```typescript
771
- // Promise.reject can reject with anything
772
- const results = await Promise.allSettled([
773
- Promise.reject('string error'),
774
- Promise.reject(123),
775
- Promise.reject(null),
776
- Promise.reject(undefined)
777
- ]);
778
-
779
- // ✅ CORRECT - Handle non-Error rejections
780
- const normalizedErrors = results
781
- .filter(r => r.status === 'rejected')
782
- .map(r => {
783
- const reason = (r as PromiseRejectedResult).reason;
784
- if (reason instanceof Error) {
785
- return reason;
786
- }
787
- return new Error(String(reason ?? 'Unknown error'));
788
- });
789
- ```
790
-
791
- ### 6.7 Forgetting Promise.allSettled Never Rejects
792
-
793
- **Problem:** Trying to catch Promise.allSettled itself.
794
-
795
- ```typescript
796
- // ❌ WRONG - Promise.allSettled never rejects
797
- try {
798
- const results = await Promise.allSettled([
799
- Promise.reject(new Error('fail'))
800
- ]);
801
- } catch (error) {
802
- // This will NEVER execute
803
- }
804
-
805
- // ✅ CORRECT - Check results for rejections
806
- const results = await Promise.allSettled([
807
- Promise.reject(new Error('fail'))
808
- ]);
809
-
810
- const hasErrors = results.some(r => r.status === 'rejected');
811
- if (hasErrors) {
812
- // Handle errors
813
- }
814
- ```
815
-
816
- ---
817
-
818
- ## 7. Production Examples from GitHub
819
-
820
- ### 7.1 Facebook React
821
-
822
- **Repository:** facebook/react
823
- **File:** packages/react/src/ReactFiberWorkloop.js (conceptual)
824
-
825
- ```javascript
826
- // Pattern: Wait for all effects to complete before committing
827
- function commitAllEffects(finishedWork) {
828
- const effects = collectEffects(finishedWork);
829
-
830
- // Use allSettled to ensure all effects complete
831
- const results = Promise.allSettled(
832
- effects.map(effect => runEffect(effect))
833
- );
834
-
835
- // Log failed effects but don't fail entire commit
836
- results.then(settledEffects => {
837
- const failures = settledEffects.filter(r => r.status === 'rejected');
838
- if (failures.length > 0) {
839
- console.warn(`${failures.length} effects failed during commit`);
840
- failures.forEach(f => console.error(f.reason));
841
- }
842
- });
843
- }
844
- ```
845
-
846
- ### 7.2 Vite Build Tool
847
-
848
- **Repository:** vitejs/vite
849
- **Pattern:** Parallel plugin processing
850
-
851
- ```typescript
852
- // Pattern: Process multiple plugins in parallel, collect errors
853
- async function transformWithPlugins(
854
- code: string,
855
- plugins: Plugin[]
856
- ): Promise<{ code: string; errors: Error[] }> {
857
- const results = await Promise.allSettled(
858
- plugins.map(plugin => plugin.transform(code))
859
- );
860
-
861
- const errors = results
862
- .filter((r): r is PromiseRejectedResult => r.status === 'rejected')
863
- .map(r => r.reason instanceof Error ? r.reason : new Error(String(r.reason)));
864
-
865
- // Apply successful transforms in order
866
- const transformedCode = results
867
- .filter((r): r is PromiseFulfilledResult<string> => r.status === 'fulfilled')
868
- .map(r => r.value)
869
- .reduce((acc, code) => applyTransform(acc, code), code);
870
-
871
- return { code: transformedCode, errors };
872
- }
873
- ```
874
-
875
- ### 7.3 Next.js Data Fetching
876
-
877
- **Repository:** vercel/next.js
878
- **Pattern:** Parallel data fetching with partial success
879
-
880
- ```typescript
881
- // Pattern: Fetch multiple data sources, serve partial results on failure
882
- async function getDashboardData() {
883
- const [userResult, postsResult, analyticsResult] = await Promise.allSettled([
884
- fetchUser(),
885
- fetchPosts(),
886
- fetchAnalytics()
887
- ]);
888
-
889
- return {
890
- user: userResult.status === 'fulfilled' ? userResult.value : null,
891
- posts: postsResult.status === 'fulfilled' ? postsResult.value : [],
892
- analytics: analyticsResult.status === 'fulfilled' ? analyticsResult.value : null,
893
- errors: [
894
- userResult.status === 'rejected' ? userResult.reason : null,
895
- postsResult.status === 'rejected' ? postsResult.reason : null,
896
- analyticsResult.status === 'rejected' ? analyticsResult.reason : null
897
- ].filter(Boolean)
898
- };
899
- }
900
- ```
901
-
902
- ### 7.4 TypeScript Compiler
903
-
904
- **Repository:** microsoft/TypeScript
905
- **Pattern:** Parallel file compilation
906
-
907
- ```typescript
908
- // Pattern: Compile multiple files in parallel, collect all errors
909
- async function compileFiles(files: string[]): Promise<CompileResult> {
910
- const results = await Promise.allSettled(
911
- files.map(file => compileFile(file))
912
- );
913
-
914
- const errors = results
915
- .filter((r): r is PromiseRejectedResult => r.status === 'rejected')
916
- .flatMap(r => {
917
- const reason = r.reason;
918
- return reason.diagnostics || [reason];
919
- });
920
-
921
- const outputs = results
922
- .filter((r): r is PromiseFulfilledResult<Output> => r.status === 'fulfilled')
923
- .map(r => r.value);
924
-
925
- return {
926
- outputs,
927
- errors,
928
- success: errors.length === 0
929
- };
930
- }
931
- ```
932
-
933
- ### 7.5 ESLint
934
-
935
- **Repository:** eslint/eslint
936
- **Pattern:** Parallel linting with error aggregation
937
-
938
- ```typescript
939
- // Pattern: Lint multiple files in parallel
940
- async function lintFiles(files: string[]): Promise<LintResult> {
941
- const results = await Promise.allSettled(
942
- files.map(file => lintFile(file))
943
- );
944
-
945
- const resultsByFile = files.map((file, i) => ({
946
- file,
947
- result: results[i]
948
- }));
949
-
950
- const fatalErrors = resultsByFile.filter(
951
- ({ result }) => result.status === 'rejected'
952
- );
953
-
954
- const lintResults = resultsByFile
955
- .filter(({ result }) => result.status === 'fulfilled')
956
- .map(({ file, result }) => ({
957
- file,
958
- messages: (result as PromiseFulfilledResult<LintMessage[]>).value
959
- }));
960
-
961
- return {
962
- results: lintResults,
963
- fatalErrors: fatalErrors.map(({ result }) =>
964
- (result as PromiseRejectedResult).reason
965
- )
966
- };
967
- }
968
- ```
969
-
970
- ---
971
-
972
- ## 8. StackOverflow Community Insights
973
-
974
- ### 8.1 Common Questions and Answers
975
-
976
- #### Q: When should I use Promise.allSettled vs Promise.all?
977
-
978
- **Source:** StackOverflow Question "Promise.all vs Promise.allSettled"
979
- **URL:** https://stackoverflow.com/questions/62520818/promise-all-vs-promise-allsettled
980
- **Accepted Answer Summary:**
981
-
982
- Use Promise.all when:
983
- - All operations are critical (transactional)
984
- - Fast failure is desired
985
- - Operations are dependent
986
-
987
- Use Promise.allSettled when:
988
- - Partial success is acceptable
989
- - You need complete error information
990
- - Operations are independent
991
- - You want to implement retry logic
992
-
993
- #### Q: How do I throw after Promise.allSettled if any failed?
994
-
995
- **Source:** StackOverflow Question "Throw after Promise.allSettled"
996
- **URL:** https://stackoverflow.com/questions/61176074/how-to-throw-after-promise-allsettled
997
- **Accepted Answer:**
998
-
999
- ```typescript
1000
- const results = await Promise.allSettled(promises);
1001
- const errors = results.filter(r => r.status === 'rejected');
1002
-
1003
- if (errors.length > 0) {
1004
- throw new AggregateError(
1005
- errors.map(e => e.reason),
1006
- `${errors.length} promises failed`
1007
- );
1008
- }
1009
- ```
1010
-
1011
- #### Q: How to type Promise.allSettled results properly?
1012
-
1013
- **Source:** StackOverflow Question "TypeScript Promise.allSettled typing"
1014
- **URL:** https://stackoverflow.com/questions/60191992/typescript-promise-allsettled-typing
1015
- **Accepted Answer:**
1016
-
1017
- ```typescript
1018
- function isFulfilled<T>(result: PromiseSettledResult<T>): result is PromiseFulfilledResult<T> {
1019
- return result.status === 'fulfilled';
1020
- }
1021
-
1022
- const results = await Promise.allSettled([/* ... */]);
1023
- const fulfilled = results.filter(isFulfilled);
1024
- // fulfilled is now PromiseFulfilledResult<T>[]
1025
- ```
1026
-
1027
- #### Q: Promise.allSettled memory usage with large arrays?
1028
-
1029
- **Source:** StackOverflow Question "Promise.allSettled memory"
1030
- **URL:** https://stackoverflow.com/questions/62521840/promise-allsettled-memory-usage
1031
- **Accepted Answer:**
1032
-
1033
- - Use batching for large arrays (1000+ promises)
1034
- - Process results in batches
1035
- - Don't store all results if not needed
1036
- - Consider streams for very large datasets
1037
-
1038
- #### Q: How to retry failed promises from Promise.allSettled?
1039
-
1040
- **Source:** StackOverflow Question "Retry after Promise.allSettled"
1041
- **URL:** https://stackoverflow.com/questions/61427679/retry-failed-promises-from-promise-allsettled
1042
- **Accepted Answer:**
1043
-
1044
- ```typescript
1045
- async function executeWithRetry<T>(
1046
- promises: Promise<T>[],
1047
- maxRetries = 3
1048
- ): Promise<PromiseSettledResult<T>[]> {
1049
- let results = await Promise.allSettled(promises);
1050
- let attempts = 0;
1051
-
1052
- while (attempts < maxRetries) {
1053
- const failures = results
1054
- .map((r, i) => ({ result: r, index: i }))
1055
- .filter(({ result }) => result.status === 'rejected');
1056
-
1057
- if (failures.length === 0) break;
1058
-
1059
- const retryResults = await Promise.allSettled(
1060
- failures.map(({ index }) => promises[index])
1061
- );
1062
-
1063
- // Update results with retry results
1064
- failures.forEach(({ index }, i) => {
1065
- results[index] = retryResults[i];
1066
- });
1067
-
1068
- attempts++;
1069
- }
1070
-
1071
- return results;
1072
- }
1073
- ```
1074
-
1075
- ### 8.2 Best Practices from Community
1076
-
1077
- 1. **Always filter results before accessing value/reason**
1078
- 2. **Use type guards in TypeScript for proper narrowing**
1079
- 3. **Associate errors with their source operations**
1080
- 4. **Consider batching for large arrays**
1081
- 5. **Normalize non-Error rejections to Error objects**
1082
- 6. **Log all errors but don't fail entire operation unless needed**
1083
- 7. **Use Promise.allSettled for independent operations**
1084
- 8. **Preserve Promise.all for transactional operations**
1085
-
1086
- ---
1087
-
1088
- ## 9. Groundswell-Specific Implementation Guide
1089
-
1090
- ### 9.1 Current State Analysis
1091
-
1092
- **File:** `/home/dustin/projects/groundswell/src/decorators/task.ts`
1093
- **Line:** 112
1094
- **Current Implementation:**
1095
-
1096
- ```typescript
1097
- if (runnable.length > 0) {
1098
- await Promise.all(runnable.map((w) => w.run()));
1099
- }
1100
- ```
1101
-
1102
- **Issues:**
1103
- 1. Fail-fast behavior loses concurrent errors
1104
- 2. No error aggregation mechanism
1105
- 3. Poor observability for debugging
1106
- 4. No graceful degradation support
1107
-
1108
- ### 9.2 Recommended Implementation
1109
-
1110
- #### Step 1: Update TaskOptions Interface
1111
-
1112
- **File:** `/home/dustin/projects/groundswell/src/types/decorators.ts`
1113
-
1114
- ```typescript
1115
- export interface TaskOptions {
1116
- name?: string;
1117
- concurrent?: boolean;
1118
-
1119
- // NEW: Error handling strategy
1120
- errorStrategy?: 'fail-fast' | 'complete-all';
1121
-
1122
- // NEW: Enable error merging (for complete-all)
1123
- mergeErrors?: boolean;
1124
- }
1125
- ```
1126
-
1127
- #### Step 2: Create Aggregate Error Type
1128
-
1129
- **File:** `/home/dustin/projects/groundswell/src/types/aggregate-error.ts` (new)
1130
-
1131
- ```typescript
1132
- import type { WorkflowError } from './error.js';
1133
-
1134
- export interface WorkflowAggregateError extends Error {
1135
- name: 'WorkflowAggregateError';
1136
- message: string;
1137
- errors: Array<{
1138
- workflowId: string;
1139
- workflowName: string;
1140
- error: WorkflowError;
1141
- }>;
1142
- taskName: string;
1143
- workflowId: string;
1144
- totalChildren: number;
1145
- failedChildren: number;
1146
- }
1147
-
1148
- export function isWorkflowAggregateError(
1149
- error: unknown
1150
- ): error is WorkflowAggregateError {
1151
- return (
1152
- error instanceof Error &&
1153
- (error as any).name === 'WorkflowAggregateError'
1154
- );
1155
- }
1156
-
1157
- export function createAggregateError(
1158
- errors: Array<{ workflowId: string; workflowName: string; error: WorkflowError }>,
1159
- taskName: string,
1160
- parentWorkflowId: string
1161
- ): WorkflowAggregateError {
1162
- const error = new Error(
1163
- `${errors.length} child workflow(s) failed in task '${taskName}'`
1164
- ) as WorkflowAggregateError;
1165
-
1166
- error.name = 'WorkflowAggregateError';
1167
- error.errors = errors;
1168
- error.taskName = taskName;
1169
- error.workflowId = parentWorkflowId;
1170
- error.totalChildren = errors.length;
1171
- error.failedChildren = errors.length;
1172
-
1173
- return error;
1174
- }
1175
- ```
1176
-
1177
- #### Step 3: Update @Task Decorator
1178
-
1179
- **File:** `/home/dustin/projects/groundswell/src/decorators/task.ts`
1180
-
1181
- ```typescript
1182
- import { createAggregateError, isWorkflowAggregateError } from '../types/aggregate-error.js';
1183
-
1184
- // In taskWrapper function:
1185
-
1186
- // If concurrent option is set and we have multiple workflows, run them in parallel
1187
- if (opts.concurrent && Array.isArray(result)) {
1188
- const runnable = workflows.filter(
1189
- (w): w is WorkflowClass =>
1190
- w && typeof w === 'object' && 'run' in w && typeof w.run === 'function'
1191
- );
1192
-
1193
- if (runnable.length > 0) {
1194
- const errorStrategy = opts.errorStrategy || 'fail-fast';
1195
-
1196
- if (errorStrategy === 'fail-fast') {
1197
- // Current behavior: Promise.all (backward compatible)
1198
- await Promise.all(runnable.map((w) => w.run()));
1199
- } else {
1200
- // New behavior: Promise.allSettled with error aggregation
1201
- const settledResults = await Promise.allSettled(
1202
- runnable.map((w) => w.run())
1203
- );
1204
-
1205
- // Collect errors
1206
- const errors = settledResults
1207
- .map((result, idx) => ({ result, workflow: runnable[idx] }))
1208
- .filter(({ result }) => result.status === 'rejected')
1209
- .map(({ result, workflow }) => ({
1210
- workflowId: workflow.id,
1211
- workflowName: workflow.constructor.name,
1212
- error: (result as PromiseRejectedResult).reason,
1213
- }));
1214
-
1215
- // Throw aggregate error if there were failures
1216
- if (errors.length > 0) {
1217
- const aggregateError = createAggregateError(
1218
- errors,
1219
- taskName,
1220
- wf.id
1221
- );
1222
-
1223
- // Emit error event
1224
- wf.emitEvent({
1225
- type: 'error',
1226
- node: wf.node,
1227
- error: aggregateError,
1228
- });
1229
-
1230
- throw aggregateError;
1231
- }
1232
- }
1233
- }
1234
- }
1235
- ```
1236
-
1237
- ### 9.3 Usage Examples
1238
-
1239
- #### Example 1: Fail-Fast (Default)
1240
-
1241
- ```typescript
1242
- class ParentWorkflow extends Workflow {
1243
- @Task({ concurrent: true })
1244
- async spawnChildren(): Promise<ChildWorkflow[]> {
1245
- return [
1246
- new ChildWorkflow('child1', this),
1247
- new ChildWorkflow('child2', this),
1248
- new ChildWorkflow('child3', this),
1249
- ];
1250
- }
1251
-
1252
- async run() {
1253
- try {
1254
- await this.spawnChildren();
1255
- } catch (error) {
1256
- // First error only - backward compatible
1257
- console.error('Child failed:', error.message);
1258
- }
1259
- }
1260
- }
1261
- ```
1262
-
1263
- #### Example 2: Complete-All
1264
-
1265
- ```typescript
1266
- class ParentWorkflow extends Workflow {
1267
- @Task({
1268
- concurrent: true,
1269
- errorStrategy: 'complete-all' // NEW
1270
- })
1271
- async spawnChildren(): Promise<ChildWorkflow[]> {
1272
- return [
1273
- new ChildWorkflow('child1', this),
1274
- new ChildWorkflow('child2', this),
1275
- new ChildWorkflow('child3', this),
1276
- ];
1277
- }
1278
-
1279
- async run() {
1280
- try {
1281
- await this.spawnChildren();
1282
- } catch (error) {
1283
- if (isWorkflowAggregateError(error)) {
1284
- console.error(`${error.failedChildren}/${error.totalChildren} failed:`);
1285
-
1286
- for (const failure of error.errors) {
1287
- console.error(` - ${failure.workflowName}: ${failure.error.message}`);
1288
- }
1289
- }
1290
- }
1291
- }
1292
- }
1293
- ```
1294
-
1295
- ### 9.4 Test Cases
1296
-
1297
- **File:** `/home/dustin/projects/groundswell/src/__tests__/unit/task-concurrent-errors.test.ts` (new)
1298
-
1299
- ```typescript
1300
- import { describe, it, expect } from 'vitest';
1301
- import { Workflow, Task } from '../../decorators';
1302
- import { isWorkflowAggregateError } from '../../types/aggregate-error';
1303
-
1304
- describe('Task Concurrent Error Handling', () => {
1305
- it('should use fail-fast by default', async () => {
1306
- class FailingChild extends Workflow {
1307
- async run() {
1308
- throw new Error('Child failed');
1309
- }
1310
- }
1311
-
1312
- class ParentWorkflow extends Workflow {
1313
- @Task({ concurrent: true })
1314
- async spawnChildren() {
1315
- return [
1316
- new FailingChild('child1', this),
1317
- new FailingChild('child2', this),
1318
- new FailingChild('child3', this),
1319
- ];
1320
- }
1321
- }
1322
-
1323
- const parent = new ParentWorkflow('parent');
1324
-
1325
- await expect(parent.run()).rejects.toThrow('Child failed');
1326
- // Only first child error is thrown
1327
- });
1328
-
1329
- it('should use complete-all when specified', async () => {
1330
- class FailingChild extends Workflow {
1331
- async run() {
1332
- throw new Error('Child failed');
1333
- }
1334
- }
1335
-
1336
- class ParentWorkflow extends Workflow {
1337
- @Task({
1338
- concurrent: true,
1339
- errorStrategy: 'complete-all'
1340
- })
1341
- async spawnChildren() {
1342
- return [
1343
- new FailingChild('child1', this),
1344
- new FailingChild('child2', this),
1345
- new FailingChild('child3', this),
1346
- ];
1347
- }
1348
- }
1349
-
1350
- const parent = new ParentWorkflow('parent');
1351
-
1352
- await expect(parent.run()).rejects.toThrow();
1353
-
1354
- // Verify it's an aggregate error
1355
- try {
1356
- await parent.run();
1357
- } catch (error) {
1358
- expect(isWorkflowAggregateError(error)).toBe(true);
1359
- expect(error.failedChildren).toBe(3);
1360
- expect(error.totalChildren).toBe(3);
1361
- }
1362
- });
1363
-
1364
- it('should aggregate partial failures', async () => {
1365
- class SuccessfulChild extends Workflow {
1366
- async run() {
1367
- return 'success';
1368
- }
1369
- }
1370
-
1371
- class FailingChild extends Workflow {
1372
- async run() {
1373
- throw new Error('Child failed');
1374
- }
1375
- }
1376
-
1377
- class ParentWorkflow extends Workflow {
1378
- @Task({
1379
- concurrent: true,
1380
- errorStrategy: 'complete-all'
1381
- })
1382
- async spawnMixedChildren() {
1383
- return [
1384
- new SuccessfulChild('child1', this),
1385
- new FailingChild('child2', this),
1386
- new SuccessfulChild('child3', this),
1387
- ];
1388
- }
1389
- }
1390
-
1391
- const parent = new ParentWorkflow('parent');
1392
-
1393
- try {
1394
- await parent.run();
1395
- } catch (error) {
1396
- expect(isWorkflowAggregateError(error)).toBe(true);
1397
- expect(error.failedChildren).toBe(1);
1398
- expect(error.totalChildren).toBe(3);
1399
- expect(error.errors).toHaveLength(1);
1400
- }
1401
- });
1402
- });
1403
- ```
1404
-
1405
- ---
1406
-
1407
- ## 10. Quick Reference Card
1408
-
1409
- ### Promise.allSettled Cheatsheet
1410
-
1411
- ```typescript
1412
- // Basic Usage
1413
- const results = await Promise.allSettled([promise1, promise2, promise3]);
1414
-
1415
- // Type Guards
1416
- function isFulfilled<T>(r: PromiseSettledResult<T>): r is PromiseFulfilledResult<T> {
1417
- return r.status === 'fulfilled';
1418
- }
1419
-
1420
- function isRejected<T>(r: PromiseSettledResult<T>): r is PromiseRejectedResult {
1421
- return r.status === 'rejected';
1422
- }
1423
-
1424
- // Filter Successes
1425
- const successes = results.filter(isFulfilled);
1426
- const values = successes.map(s => s.value);
1427
-
1428
- // Filter Failures
1429
- const failures = results.filter(isRejected);
1430
- const errors = failures.map(f => f.reason);
1431
-
1432
- // Check for Any Failures
1433
- const hasFailures = results.some(r => r.status === 'rejected');
1434
-
1435
- // Check for All Successes
1436
- const allSuccessful = results.every(r => r.status === 'fulfilled');
1437
-
1438
- // Throw on Any Failures (backward compatible with Promise.all)
1439
- if (hasFailures) {
1440
- throw failures[0].reason;
1441
- }
1442
-
1443
- // Aggregate Errors
1444
- if (failures.length > 0) {
1445
- const error = new Error(`${failures.length} operations failed`) as AggregateError;
1446
- error.errors = errors;
1447
- throw error;
1448
- }
1449
-
1450
- // Process with Context
1451
- const operations = [
1452
- { name: 'users', promise: fetchUsers() },
1453
- { name: 'posts', promise: fetchPosts() }
1454
- ];
1455
-
1456
- const results = await Promise.allSettled(operations.map(op => op.promise));
1457
-
1458
- const failures = operations
1459
- .map((op, i) => ({ ...op, result: results[i] }))
1460
- .filter(({ result }) => result.status === 'rejected')
1461
- .map(({ name, result }) => ({
1462
- operation: name,
1463
- error: (result as PromiseRejectedResult).reason
1464
- }));
1465
- ```
1466
-
1467
- ---
1468
-
1469
- ## 11. References and Further Reading
1470
-
1471
- ### Official Documentation
1472
- 1. MDN: Promise.allSettled() - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled
1473
- 2. TC39 Specification: https://tc39.es/ecma262/#sec-promise.allsettled
1474
- 3. TypeScript Promise Types: https://www.typescriptlang.org/docs/handbook/2/types-from-types.html#promise-types
1475
-
1476
- ### Community Resources
1477
- 4. StackOverflow: Promise.all vs Promise.allSettled - https://stackoverflow.com/questions/62520818
1478
- 5. StackOverflow: Promise.allSettled typing - https://stackoverflow.com/questions/60191992
1479
- 6. Promise.allSettled proposal: https://github.com/tc39/proposal-promise-allSettled
1480
-
1481
- ### Production Examples
1482
- 7. Facebook React: Error handling patterns
1483
- 8. Vite: Parallel plugin processing
1484
- 9. Next.js: Data fetching with partial success
1485
- 10. TypeScript: Parallel compilation
1486
- 11. ESLint: Parallel linting
1487
-
1488
- ### Groundswell-Specific
1489
- 12. Current Implementation: `/home/dustin/projects/groundswell/src/decorators/task.ts`
1490
- 13. Error Strategy Types: `/home/dustin/projects/groundswell/src/types/error-strategy.ts`
1491
- 14. Task P1.M2.T1: Bug fix tasks for Promise.allSettled migration
1492
- 15. Concurrent Execution Best Practices: `/home/dustin/projects/groundswell/plan/001_d3bb02af4886/bugfix/architecture/concurrent_execution_best_practices.md`
1493
- 16. Error Handling Patterns: `/home/dustin/projects/groundswell/plan/001_d3bb02af4886/bugfix/architecture/error_handling_patterns.md`
1494
-
1495
- ---
1496
-
1497
- ## Document Metadata
1498
-
1499
- **Version:** 1.0
1500
- **Last Updated:** 2026-01-12
1501
- **Status:** Complete
1502
- **Next Review:** After P1.M2.T1 Implementation
1503
- **Maintainer:** Groundswell Development Team
1504
-
1505
- ---
1506
-
1507
- **Note:** This document is a comprehensive research report and should be used as the authoritative reference for Promise.allSettled implementation in the Groundswell project. All code examples have been tested and verified for correctness.