groundswell 0.0.2 → 0.0.3
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.
- package/dist/__tests__/adversarial/attachChild-performance.test.d.ts +16 -0
- package/dist/__tests__/adversarial/attachChild-performance.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/attachChild-performance.test.js +187 -0
- package/dist/__tests__/adversarial/attachChild-performance.test.js.map +1 -0
- package/dist/__tests__/adversarial/circular-reference.test.d.ts +13 -0
- package/dist/__tests__/adversarial/circular-reference.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/circular-reference.test.js +92 -0
- package/dist/__tests__/adversarial/circular-reference.test.js.map +1 -0
- package/dist/__tests__/adversarial/complex-circular-reference.test.d.ts +16 -0
- package/dist/__tests__/adversarial/complex-circular-reference.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/complex-circular-reference.test.js +127 -0
- package/dist/__tests__/adversarial/complex-circular-reference.test.js.map +1 -0
- package/dist/__tests__/adversarial/concurrent-task-failures.test.d.ts +21 -0
- package/dist/__tests__/adversarial/concurrent-task-failures.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/concurrent-task-failures.test.js +667 -0
- package/dist/__tests__/adversarial/concurrent-task-failures.test.js.map +1 -0
- package/dist/__tests__/adversarial/deep-analysis.test.d.ts +6 -0
- package/dist/__tests__/adversarial/deep-analysis.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/deep-analysis.test.js +877 -0
- package/dist/__tests__/adversarial/deep-analysis.test.js.map +1 -0
- package/dist/__tests__/adversarial/deep-hierarchy-stress.test.d.ts +13 -0
- package/dist/__tests__/adversarial/deep-hierarchy-stress.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/deep-hierarchy-stress.test.js +186 -0
- package/dist/__tests__/adversarial/deep-hierarchy-stress.test.js.map +1 -0
- package/dist/__tests__/adversarial/e2e-prd-validation.test.d.ts +6 -0
- package/dist/__tests__/adversarial/e2e-prd-validation.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/e2e-prd-validation.test.js +626 -0
- package/dist/__tests__/adversarial/e2e-prd-validation.test.js.map +1 -0
- package/dist/__tests__/adversarial/edge-case.test.d.ts +6 -0
- package/dist/__tests__/adversarial/edge-case.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/edge-case.test.js +857 -0
- package/dist/__tests__/adversarial/edge-case.test.js.map +1 -0
- package/dist/__tests__/adversarial/error-merge-strategy.test.d.ts +20 -0
- package/dist/__tests__/adversarial/error-merge-strategy.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/error-merge-strategy.test.js +907 -0
- package/dist/__tests__/adversarial/error-merge-strategy.test.js.map +1 -0
- package/dist/__tests__/adversarial/incremental-performance.test.d.ts +2 -0
- package/dist/__tests__/adversarial/incremental-performance.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/incremental-performance.test.js +113 -0
- package/dist/__tests__/adversarial/incremental-performance.test.js.map +1 -0
- package/dist/__tests__/adversarial/node-map-update-benchmarks.test.d.ts +22 -0
- package/dist/__tests__/adversarial/node-map-update-benchmarks.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/node-map-update-benchmarks.test.js +383 -0
- package/dist/__tests__/adversarial/node-map-update-benchmarks.test.js.map +1 -0
- package/dist/__tests__/adversarial/observer-propagation.test.d.ts +21 -0
- package/dist/__tests__/adversarial/observer-propagation.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/observer-propagation.test.js +404 -0
- package/dist/__tests__/adversarial/observer-propagation.test.js.map +1 -0
- package/dist/__tests__/adversarial/parent-validation.test.d.ts +13 -0
- package/dist/__tests__/adversarial/parent-validation.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/parent-validation.test.js +128 -0
- package/dist/__tests__/adversarial/parent-validation.test.js.map +1 -0
- package/dist/__tests__/adversarial/prd-12-2-compliance.test.d.ts +20 -0
- package/dist/__tests__/adversarial/prd-12-2-compliance.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/prd-12-2-compliance.test.js +482 -0
- package/dist/__tests__/adversarial/prd-12-2-compliance.test.js.map +1 -0
- package/dist/__tests__/adversarial/prd-compliance.test.d.ts +6 -0
- package/dist/__tests__/adversarial/prd-compliance.test.d.ts.map +1 -0
- package/dist/__tests__/adversarial/prd-compliance.test.js +886 -0
- package/dist/__tests__/adversarial/prd-compliance.test.js.map +1 -0
- package/dist/__tests__/compatibility/backward-compatibility.test.d.ts +22 -0
- package/dist/__tests__/compatibility/backward-compatibility.test.d.ts.map +1 -0
- package/dist/__tests__/compatibility/backward-compatibility.test.js +1843 -0
- package/dist/__tests__/compatibility/backward-compatibility.test.js.map +1 -0
- package/dist/__tests__/helpers/index.d.ts +10 -0
- package/dist/__tests__/helpers/index.d.ts.map +1 -0
- package/{src/__tests__/helpers/index.ts → dist/__tests__/helpers/index.js} +2 -10
- package/dist/__tests__/helpers/index.js.map +1 -0
- package/dist/__tests__/helpers/tree-verification.d.ts +90 -0
- package/dist/__tests__/helpers/tree-verification.d.ts.map +1 -0
- package/dist/__tests__/helpers/tree-verification.js +202 -0
- package/dist/__tests__/helpers/tree-verification.js.map +1 -0
- package/dist/__tests__/integration/agent-workflow.test.d.ts +2 -0
- package/dist/__tests__/integration/agent-workflow.test.d.ts.map +1 -0
- package/dist/__tests__/integration/agent-workflow.test.js +256 -0
- package/dist/__tests__/integration/agent-workflow.test.js.map +1 -0
- package/dist/__tests__/integration/bidirectional-consistency.test.d.ts +14 -0
- package/dist/__tests__/integration/bidirectional-consistency.test.d.ts.map +1 -0
- package/dist/__tests__/integration/bidirectional-consistency.test.js +668 -0
- package/dist/__tests__/integration/bidirectional-consistency.test.js.map +1 -0
- package/dist/__tests__/integration/observer-logging.test.d.ts +2 -0
- package/dist/__tests__/integration/observer-logging.test.d.ts.map +1 -0
- package/dist/__tests__/integration/observer-logging.test.js +517 -0
- package/dist/__tests__/integration/observer-logging.test.js.map +1 -0
- package/dist/__tests__/integration/tree-mirroring.test.d.ts +2 -0
- package/dist/__tests__/integration/tree-mirroring.test.d.ts.map +1 -0
- package/dist/__tests__/integration/tree-mirroring.test.js +117 -0
- package/dist/__tests__/integration/tree-mirroring.test.js.map +1 -0
- package/dist/__tests__/integration/workflow-reparenting.test.d.ts +12 -0
- package/dist/__tests__/integration/workflow-reparenting.test.d.ts.map +1 -0
- package/dist/__tests__/integration/workflow-reparenting.test.js +239 -0
- package/dist/__tests__/integration/workflow-reparenting.test.js.map +1 -0
- package/dist/__tests__/unit/agent.test.d.ts +2 -0
- package/dist/__tests__/unit/agent.test.d.ts.map +1 -0
- package/dist/__tests__/unit/agent.test.js +143 -0
- package/dist/__tests__/unit/agent.test.js.map +1 -0
- package/dist/__tests__/unit/cache-key.test.d.ts +5 -0
- package/dist/__tests__/unit/cache-key.test.d.ts.map +1 -0
- package/dist/__tests__/unit/cache-key.test.js +145 -0
- package/dist/__tests__/unit/cache-key.test.js.map +1 -0
- package/dist/__tests__/unit/cache.test.d.ts +5 -0
- package/dist/__tests__/unit/cache.test.d.ts.map +1 -0
- package/dist/__tests__/unit/cache.test.js +132 -0
- package/dist/__tests__/unit/cache.test.js.map +1 -0
- package/dist/__tests__/unit/context.test.d.ts +2 -0
- package/dist/__tests__/unit/context.test.d.ts.map +1 -0
- package/dist/__tests__/unit/context.test.js +220 -0
- package/dist/__tests__/unit/context.test.js.map +1 -0
- package/dist/__tests__/unit/decorators.test.d.ts +2 -0
- package/dist/__tests__/unit/decorators.test.d.ts.map +1 -0
- package/dist/__tests__/unit/decorators.test.js +162 -0
- package/dist/__tests__/unit/decorators.test.js.map +1 -0
- package/dist/__tests__/unit/introspection-tools.test.d.ts +5 -0
- package/dist/__tests__/unit/introspection-tools.test.d.ts.map +1 -0
- package/dist/__tests__/unit/introspection-tools.test.js +191 -0
- package/dist/__tests__/unit/introspection-tools.test.js.map +1 -0
- package/dist/__tests__/unit/logger.test.d.ts +2 -0
- package/dist/__tests__/unit/logger.test.d.ts.map +1 -0
- package/dist/__tests__/unit/logger.test.js +241 -0
- package/dist/__tests__/unit/logger.test.js.map +1 -0
- package/dist/__tests__/unit/observable.test.d.ts +2 -0
- package/dist/__tests__/unit/observable.test.d.ts.map +1 -0
- package/dist/__tests__/unit/observable.test.js +251 -0
- package/dist/__tests__/unit/observable.test.js.map +1 -0
- package/dist/__tests__/unit/prompt.test.d.ts +2 -0
- package/dist/__tests__/unit/prompt.test.d.ts.map +1 -0
- package/dist/__tests__/unit/prompt.test.js +113 -0
- package/dist/__tests__/unit/prompt.test.js.map +1 -0
- package/dist/__tests__/unit/reflection.test.d.ts +5 -0
- package/dist/__tests__/unit/reflection.test.d.ts.map +1 -0
- package/dist/__tests__/unit/reflection.test.js +160 -0
- package/dist/__tests__/unit/reflection.test.js.map +1 -0
- package/dist/__tests__/unit/tree-debugger-incremental.test.d.ts +2 -0
- package/dist/__tests__/unit/tree-debugger-incremental.test.d.ts.map +1 -0
- package/dist/__tests__/unit/tree-debugger-incremental.test.js +136 -0
- package/dist/__tests__/unit/tree-debugger-incremental.test.js.map +1 -0
- package/dist/__tests__/unit/tree-debugger.test.d.ts +2 -0
- package/dist/__tests__/unit/tree-debugger.test.d.ts.map +1 -0
- package/dist/__tests__/unit/tree-debugger.test.js +69 -0
- package/dist/__tests__/unit/tree-debugger.test.js.map +1 -0
- package/dist/__tests__/unit/utils/workflow-error-utils.test.d.ts +2 -0
- package/dist/__tests__/unit/utils/workflow-error-utils.test.d.ts.map +1 -0
- package/dist/__tests__/unit/utils/workflow-error-utils.test.js +154 -0
- package/dist/__tests__/unit/utils/workflow-error-utils.test.js.map +1 -0
- package/dist/__tests__/unit/workflow-detachChild.test.d.ts +2 -0
- package/dist/__tests__/unit/workflow-detachChild.test.d.ts.map +1 -0
- package/dist/__tests__/unit/workflow-detachChild.test.js +76 -0
- package/dist/__tests__/unit/workflow-detachChild.test.js.map +1 -0
- package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.d.ts +2 -0
- package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.d.ts.map +1 -0
- package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.js +122 -0
- package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.js.map +1 -0
- package/dist/__tests__/unit/workflow-isDescendantOf.test.d.ts +2 -0
- package/dist/__tests__/unit/workflow-isDescendantOf.test.d.ts.map +1 -0
- package/dist/__tests__/unit/workflow-isDescendantOf.test.js +140 -0
- package/dist/__tests__/unit/workflow-isDescendantOf.test.js.map +1 -0
- package/dist/__tests__/unit/workflow.test.d.ts +2 -0
- package/dist/__tests__/unit/workflow.test.d.ts.map +1 -0
- package/dist/__tests__/unit/workflow.test.js +330 -0
- package/dist/__tests__/unit/workflow.test.js.map +1 -0
- package/dist/cache/cache-key.d.ts +66 -0
- package/dist/cache/cache-key.d.ts.map +1 -0
- package/dist/cache/cache-key.js +195 -0
- package/dist/cache/cache-key.js.map +1 -0
- package/dist/cache/cache.d.ts +104 -0
- package/dist/cache/cache.d.ts.map +1 -0
- package/dist/cache/cache.js +179 -0
- package/dist/cache/cache.js.map +1 -0
- package/{src/cache/index.ts → dist/cache/index.d.ts} +1 -1
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +6 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/core/agent.d.ts +112 -0
- package/dist/core/agent.d.ts.map +1 -0
- package/dist/core/agent.js +426 -0
- package/dist/core/agent.js.map +1 -0
- package/{src/core/context.ts → dist/core/context.d.ts} +16 -67
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +80 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/event-tree.d.ts +72 -0
- package/dist/core/event-tree.d.ts.map +1 -0
- package/dist/core/event-tree.js +211 -0
- package/dist/core/event-tree.js.map +1 -0
- package/{src/core/factory.ts → dist/core/factory.d.ts} +6 -27
- package/dist/core/factory.d.ts.map +1 -0
- package/dist/core/factory.js +110 -0
- package/dist/core/factory.js.map +1 -0
- package/{src/core/index.ts → dist/core/index.d.ts} +2 -10
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +9 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/logger.d.ts +50 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +91 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/mcp-handler.d.ts +69 -0
- package/dist/core/mcp-handler.d.ts.map +1 -0
- package/dist/core/mcp-handler.js +143 -0
- package/dist/core/mcp-handler.js.map +1 -0
- package/dist/core/prompt.d.ts +80 -0
- package/dist/core/prompt.d.ts.map +1 -0
- package/dist/core/prompt.js +120 -0
- package/dist/core/prompt.js.map +1 -0
- package/dist/core/workflow-context.d.ts +57 -0
- package/dist/core/workflow-context.d.ts.map +1 -0
- package/dist/core/workflow-context.js +263 -0
- package/dist/core/workflow-context.js.map +1 -0
- package/dist/core/workflow.d.ts +241 -0
- package/dist/core/workflow.d.ts.map +1 -0
- package/dist/core/workflow.js +464 -0
- package/dist/core/workflow.js.map +1 -0
- package/dist/debugger/index.d.ts +2 -0
- package/dist/debugger/index.d.ts.map +1 -0
- package/{src/debugger/index.ts → dist/debugger/index.js} +1 -0
- package/dist/debugger/index.js.map +1 -0
- package/dist/debugger/tree-debugger.d.ts +71 -0
- package/dist/debugger/tree-debugger.d.ts.map +1 -0
- package/dist/debugger/tree-debugger.js +198 -0
- package/dist/debugger/tree-debugger.js.map +1 -0
- package/dist/decorators/index.d.ts +4 -0
- package/dist/decorators/index.d.ts.map +1 -0
- package/{src/decorators/index.ts → dist/decorators/index.js} +1 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/decorators/observed-state.d.ts +32 -0
- package/dist/decorators/observed-state.d.ts.map +1 -0
- package/dist/decorators/observed-state.js +79 -0
- package/dist/decorators/observed-state.js.map +1 -0
- package/dist/decorators/step.d.ts +15 -0
- package/dist/decorators/step.d.ts.map +1 -0
- package/dist/decorators/step.js +110 -0
- package/dist/decorators/step.js.map +1 -0
- package/dist/decorators/task.d.ts +50 -0
- package/dist/decorators/task.d.ts.map +1 -0
- package/dist/decorators/task.js +118 -0
- package/dist/decorators/task.js.map +1 -0
- package/dist/examples/index.d.ts +3 -0
- package/dist/examples/index.d.ts.map +1 -0
- package/{src/examples/index.ts → dist/examples/index.js} +1 -0
- package/dist/examples/index.js.map +1 -0
- package/dist/examples/tdd-orchestrator.d.ts +15 -0
- package/dist/examples/tdd-orchestrator.d.ts.map +1 -0
- package/dist/examples/tdd-orchestrator.js +121 -0
- package/dist/examples/tdd-orchestrator.js.map +1 -0
- package/dist/examples/test-cycle-workflow.d.ts +14 -0
- package/dist/examples/test-cycle-workflow.d.ts.map +1 -0
- package/dist/examples/test-cycle-workflow.js +116 -0
- package/dist/examples/test-cycle-workflow.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/reflection/index.d.ts +5 -0
- package/dist/reflection/index.d.ts.map +1 -0
- package/{src/reflection/index.ts → dist/reflection/index.js} +1 -1
- package/dist/reflection/index.js.map +1 -0
- package/dist/reflection/reflection.d.ts +84 -0
- package/dist/reflection/reflection.d.ts.map +1 -0
- package/dist/reflection/reflection.js +329 -0
- package/dist/reflection/reflection.js.map +1 -0
- package/dist/tools/index.d.ts +6 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +11 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/introspection.d.ts +165 -0
- package/dist/tools/introspection.d.ts.map +1 -0
- package/dist/tools/introspection.js +324 -0
- package/dist/tools/introspection.js.map +1 -0
- package/dist/types/agent.d.ts +66 -0
- package/dist/types/agent.d.ts.map +1 -0
- package/dist/types/agent.js +6 -0
- package/dist/types/agent.js.map +1 -0
- package/dist/types/decorators.d.ts +31 -0
- package/dist/types/decorators.d.ts.map +1 -0
- package/dist/types/decorators.js +2 -0
- package/dist/types/decorators.js.map +1 -0
- package/dist/types/error-strategy.d.ts +13 -0
- package/dist/types/error-strategy.d.ts.map +1 -0
- package/dist/types/error-strategy.js +2 -0
- package/dist/types/error-strategy.js.map +1 -0
- package/dist/types/error.d.ts +20 -0
- package/dist/types/error.d.ts.map +1 -0
- package/dist/types/error.js +2 -0
- package/dist/types/error.js.map +1 -0
- package/dist/types/events.d.ts +87 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +2 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/index.d.ts +15 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/logging.d.ts +24 -0
- package/dist/types/logging.d.ts.map +1 -0
- package/dist/types/logging.js +2 -0
- package/dist/types/logging.js.map +1 -0
- package/dist/types/observer.d.ts +18 -0
- package/dist/types/observer.d.ts.map +1 -0
- package/dist/types/observer.js +2 -0
- package/dist/types/observer.js.map +1 -0
- package/dist/types/prompt.d.ts +31 -0
- package/dist/types/prompt.d.ts.map +1 -0
- package/dist/types/prompt.js +6 -0
- package/dist/types/prompt.js.map +1 -0
- package/dist/types/reflection.d.ts +96 -0
- package/dist/types/reflection.d.ts.map +1 -0
- package/dist/types/reflection.js +24 -0
- package/dist/types/reflection.js.map +1 -0
- package/dist/types/sdk-primitives.d.ts +118 -0
- package/dist/types/sdk-primitives.d.ts.map +1 -0
- package/dist/types/sdk-primitives.js +6 -0
- package/dist/types/sdk-primitives.js.map +1 -0
- package/{src/types/snapshot.ts → dist/types/snapshot.d.ts} +5 -5
- package/dist/types/snapshot.d.ts.map +1 -0
- package/dist/types/snapshot.js +2 -0
- package/dist/types/snapshot.js.map +1 -0
- package/dist/types/workflow-context.d.ts +139 -0
- package/dist/types/workflow-context.d.ts.map +1 -0
- package/dist/types/workflow-context.js +8 -0
- package/dist/types/workflow-context.js.map +1 -0
- package/dist/types/workflow.d.ts +30 -0
- package/dist/types/workflow.d.ts.map +1 -0
- package/dist/types/workflow.js +2 -0
- package/dist/types/workflow.js.map +1 -0
- package/dist/utils/id.d.ts +6 -0
- package/dist/utils/id.d.ts.map +1 -0
- package/dist/utils/id.js +12 -0
- package/dist/utils/id.js.map +1 -0
- package/{src/utils/index.ts → dist/utils/index.d.ts} +1 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/observable.d.ts +54 -0
- package/dist/utils/observable.d.ts.map +1 -0
- package/dist/utils/observable.js +82 -0
- package/dist/utils/observable.js.map +1 -0
- package/dist/utils/workflow-error-utils.d.ts +22 -0
- package/dist/utils/workflow-error-utils.d.ts.map +1 -0
- package/dist/utils/workflow-error-utils.js +45 -0
- package/dist/utils/workflow-error-utils.js.map +1 -0
- package/package.json +5 -2
- package/.claude/commands/subtask-planning/prp-base-create.md +0 -120
- package/.claude/commands/subtask-planning/prp-base-execute.md +0 -65
- package/.claude/commands/task-breakdown.md +0 -94
- package/.claude/settings.local.json +0 -9
- package/.claude/system_prompts/task-breakdown.md +0 -101
- package/PRD.md +0 -543
- package/PRPs/001-hierarchical-workflow-engine.md +0 -2438
- package/PRPs/PRDs/002-agent-prompt.md +0 -390
- package/PRPs/PRDs/003-agent-prompt.md +0 -943
- package/PRPs/PRDs/004-agent-prompt.md +0 -1136
- package/PRPs/PRDs/tasks-001.json +0 -492
- package/PRPs/README.md +0 -83
- package/PRPs/templates/prp_base.md +0 -222
- package/docs/agent.md +0 -422
- package/docs/prompt.md +0 -419
- package/docs/workflow.md +0 -600
- package/examples/README.md +0 -258
- package/examples/examples/01-basic-workflow.ts +0 -100
- package/examples/examples/02-decorator-options.ts +0 -217
- package/examples/examples/03-parent-child.ts +0 -241
- package/examples/examples/04-observers-debugger.ts +0 -340
- package/examples/examples/05-error-handling.ts +0 -387
- package/examples/examples/06-concurrent-tasks.ts +0 -352
- package/examples/examples/07-agent-loops.ts +0 -432
- package/examples/examples/08-sdk-features.ts +0 -667
- package/examples/examples/09-reflection.ts +0 -573
- package/examples/examples/10-introspection.ts +0 -550
- package/examples/examples/11-reparenting-workflows.ts +0 -269
- package/examples/index.ts +0 -147
- package/examples/utils/helpers.ts +0 -57
- package/package-lock.json +0 -2398
- package/plan/001_d3bb02af4886/TEST_RESULTS.md +0 -259
- package/plan/001_d3bb02af4886/backlog.json +0 -867
- package/plan/001_d3bb02af4886/bug_fix_tasks.json +0 -484
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S1/PRP.md +0 -488
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S2/PRP.md +0 -581
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S3/PRP.md +0 -687
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S1/PRP.md +0 -492
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/PRP.md +0 -932
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/concurrent_error_testing_patterns.md +0 -1109
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/vitest_concurrent_testing.md +0 -802
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/workflow_engine_test_references.md +0 -603
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S1/PRP.md +0 -564
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S3/PRP.md +0 -518
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S4/PRP.md +0 -1252
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/PRP.md +0 -364
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/CODEBASE_INVENTORY.md +0 -114
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/DECORATOR_DOCUMENTATION_PATTERNS.md +0 -205
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/PRD_LOCATION_ANALYSIS.md +0 -199
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/ULTRATHINK_PRP_PLAN.md +0 -134
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/PRP.md +0 -495
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/research/console_error_inventory.md +0 -435
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S2/PRP.md +0 -506
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S3/PRP.md +0 -612
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/PRP.md +0 -558
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/research/external_research.md +0 -788
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S2/PRP.md +0 -460
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S3/PRP.md +0 -454
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/PRP.md +0 -520
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/RECOMMENDATION.md +0 -417
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/external_workflow_engines_research.md +0 -760
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/security_implications_analysis.md +0 -245
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S2/PRP.md +0 -792
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/PRP.md +0 -535
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/TEST_EXECUTION_REPORT.md +0 -190
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/PRP.md +0 -654
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/TEST_FIX_REPORT.md +0 -227
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/KEY_FINDINGS.md +0 -345
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/QUICK_REFERENCE.md +0 -193
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/test_maintenance_research.md +0 -1323
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/BREAKING_CHANGES_AUDIT.md +0 -1011
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/PRP.md +0 -927
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S2/PRP.md +0 -505
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/architecture/logger_child_signature_analysis.md +0 -401
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/child_implementation_research.md +0 -142
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/test_patterns_research.md +0 -112
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/vitest_patterns_research.md +0 -159
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/PRP.md +0 -549
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/VERIFICATION_REPORT.md +0 -368
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/edge_case_analysis.md +0 -172
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/usage_inventory.md +0 -175
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S2/PRP.md +0 -696
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S4/PRP.md +0 -860
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/PRP.md +0 -1066
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01-testing-aggregated-errors.md +0 -1103
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01_typescript_error_aggregation_patterns.md +0 -789
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02-error-merge-strategy-testing-guide.md +0 -1098
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02_aggregate_error_patterns.md +0 -1037
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03-promise-allsettled-testing-patterns.md +0 -916
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03_error_merging_strategies.md +0 -1045
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/04_github_stackoverflow_examples.md +0 -890
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/05_comprehensive_summary.md +0 -822
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/INDEX.md +0 -668
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/QUICK_REFERENCE.md +0 -706
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/README.md +0 -265
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/RESEARCH_REPORT.md +0 -655
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S4/research/vitest_testing_patterns.md +0 -1103
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T3S2/PRP.md +0 -426
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/PRP.md +0 -506
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/QUICK_REFERENCE.md +0 -114
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/RESEARCH_SUMMARY.md +0 -316
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/vitest_observer_error_logging_best_practices.md +0 -754
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S3/PRP.md +0 -612
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/PRP.md +0 -719
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/README.md +0 -215
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/analysis.md +0 -765
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S3/PRP.md +0 -718
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/DECISION.md +0 -149
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/PRP.md +0 -470
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/ULTRATHINK_PLAN.md +0 -332
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/codebase_workflow_name_analysis.md +0 -167
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/external_best_practices.md +0 -265
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/validation_patterns.md +0 -273
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S1/workflow_engine_ancestry_api_research.md +0 -760
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S3-PRP.md +0 -434
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S1/PRP.md +0 -717
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/PRP.md +0 -472
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/VALIDATION_REPORT.md +0 -125
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/research/ULTRATHINK_PRP_PLAN.md +0 -301
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/error-logging-best-practices.md +0 -1170
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/research_typescript_partial_and_overloads.md +0 -940
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-quick-reference.md +0 -151
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-research.md +0 -650
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/prd_snapshot.md +0 -259
- package/plan/001_d3bb02af4886/bugfix/P1M1T1S1/PRP.md +0 -457
- package/plan/001_d3bb02af4886/bugfix/RESEARCH_SUMMARY.md +0 -346
- package/plan/001_d3bb02af4886/bugfix/architecture/codebase_structure.md +0 -311
- package/plan/001_d3bb02af4886/bugfix/architecture/concurrent_execution_best_practices.md +0 -1565
- package/plan/001_d3bb02af4886/bugfix/architecture/error_handling_patterns.md +0 -288
- package/plan/001_d3bb02af4886/bugfix/architecture/promise_all_analysis.md +0 -741
- package/plan/001_d3bb02af4886/docs/PRP/P1M1T1S4-functional-workflow-error-state-capture-test.md +0 -652
- package/plan/001_d3bb02af4886/docs/PRP/P1P2-PRP.md +0 -527
- package/plan/001_d3bb02af4886/docs/PRP/P3P4-PRP.md +0 -1388
- package/plan/001_d3bb02af4886/docs/PRP/P4P5-PRP.md +0 -1136
- package/plan/001_d3bb02af4886/docs/PRP/PRP.md +0 -527
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S1-PRP.md +0 -415
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S2-PRP.md +0 -378
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S4-PRP.md +0 -713
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M2T1S4-PRP.md +0 -370
- package/plan/001_d3bb02af4886/docs/PRP_P1M3T1S3.md +0 -499
- package/plan/001_d3bb02af4886/docs/TEST_RESULTS.md +0 -230
- package/plan/001_d3bb02af4886/docs/architecture/external_deps.md +0 -358
- package/plan/001_d3bb02af4886/docs/architecture/system_context.md +0 -242
- package/plan/001_d3bb02af4886/docs/bugfix/ANALYSIS_PRD_VS_IMPLEMENTATION.md +0 -1134
- package/plan/001_d3bb02af4886/docs/bugfix/GAP_ANALYSIS_SUMMARY.md +0 -179
- package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/PRP.md +0 -629
- package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/validation-report.md +0 -214
- package/plan/001_d3bb02af4886/docs/bugfix/PRP_P1M4T2S3.md +0 -629
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_PRP.md +0 -529
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_QUICK_REFERENCE.md +0 -142
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_README.md +0 -304
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_TEST_RESULTS.md +0 -558
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_VALIDATION_SUMMARY.md +0 -256
- package/plan/001_d3bb02af4886/docs/bugfix/system_context.md +0 -346
- package/plan/001_d3bb02af4886/docs/bugfix-architecture/bug_analysis.md +0 -415
- package/plan/001_d3bb02af4886/docs/bugfix-architecture/implementation_patterns.md +0 -489
- package/plan/001_d3bb02af4886/docs/bugfix-architecture/system_context.md +0 -218
- package/plan/001_d3bb02af4886/docs/bugfix_INITIATION_SUMMARY.md +0 -380
- package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_PATTERNS.md +0 -1923
- package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_QUICK_REF.md +0 -319
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/codebase-context.md +0 -115
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/cycle-detection-algorithms.md +0 -134
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/test-patterns.md +0 -153
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/workflow-class.md +0 -132
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_BEST_PRACTICES.md +0 -716
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_QUICK_REF.md +0 -186
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/GROUNDSWELL_DECORATOR_EXAMPLES.md +0 -604
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/INDEX.md +0 -213
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/codebase_structure.md +0 -30
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/existing_test_pattern.md +0 -56
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/getRootObservers_implementation.md +0 -53
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/test_conventions.md +0 -49
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/PRP.md +0 -958
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/QUICK_REFERENCE.md +0 -339
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/README.md +0 -305
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/SUMMARY.md +0 -433
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/bidirectional-tree-consistency-testing.md +0 -1574
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/test-pattern-examples.md +0 -1014
- package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_BEST_PRACTICES.md +0 -1929
- package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_CODE_PATTERNS.md +0 -857
- package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_INTEGRATION_GUIDE.md +0 -738
- package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_RESEARCH_INDEX.md +0 -424
- package/plan/001_d3bb02af4886/docs/research/P1P2/REFLECTION_INDEX.md +0 -291
- package/plan/001_d3bb02af4886/docs/research/P1P2/REFLECTION_RESEARCH_REPORT.md +0 -1342
- package/plan/001_d3bb02af4886/docs/research/P1P2/RESEARCH_SUMMARY.md +0 -342
- package/plan/001_d3bb02af4886/docs/research/P1P2/anthropic-sdk.md +0 -174
- package/plan/001_d3bb02af4886/docs/research/P1P2/async-local-storage.md +0 -200
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-code-patterns.md +0 -1205
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-decision-matrix.md +0 -421
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-implementation-guide.md +0 -1341
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-integration-guide.md +0 -834
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-patterns.md +0 -1468
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-quick-reference.md +0 -558
- package/plan/001_d3bb02af4886/docs/research/P1P2/zod-schema.md +0 -152
- package/plan/001_d3bb02af4886/docs/research/P3P4/caching-lru.md +0 -116
- package/plan/001_d3bb02af4886/docs/research/P3P4/introspection-tools.md +0 -177
- package/plan/001_d3bb02af4886/docs/research/P3P4/reflection-patterns.md +0 -117
- package/plan/001_d3bb02af4886/docs/research/P4P5/RESEARCH_SUMMARY.md +0 -151
- package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_QUICK_REF.md +0 -376
- package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_RESEARCH.md +0 -1507
- package/plan/001_d3bb02af4886/docs/research/bugfix_typescript_patterns.md +0 -949
- package/plan/001_d3bb02af4886/docs/research/error-testing-research.md +0 -619
- package/plan/001_d3bb02af4886/docs/research/error_handling_patterns.md +0 -723
- package/plan/001_d3bb02af4886/docs/research/general/INTROSPECTION_RESEARCH_SUMMARY.md +0 -378
- package/plan/001_d3bb02af4886/docs/research/general/README-INTROSPECTION.md +0 -352
- package/plan/001_d3bb02af4886/docs/research/general/agent-introspection-patterns.md +0 -1085
- package/plan/001_d3bb02af4886/docs/research/general/introspection-security-guide.md +0 -984
- package/plan/001_d3bb02af4886/docs/research/general/introspection-tool-examples.md +0 -875
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/PRP_TEMPLATE.md +0 -460
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/QUICK_REFERENCE.md +0 -324
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/README.md +0 -175
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/RESEARCH_REPORT.md +0 -499
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/SUMMARY.md +0 -163
- package/plan/001_d3bb02af4886/prd_snapshot.md +0 -543
- package/plan/bugfix/BUG_FIX_SUMMARY.md +0 -961
- package/scripts/generate-llms-full.ts +0 -206
- package/src/__tests__/adversarial/attachChild-performance.test.ts +0 -216
- package/src/__tests__/adversarial/circular-reference.test.ts +0 -101
- package/src/__tests__/adversarial/complex-circular-reference.test.ts +0 -139
- package/src/__tests__/adversarial/concurrent-task-failures.test.ts +0 -571
- package/src/__tests__/adversarial/deep-analysis.test.ts +0 -729
- package/src/__tests__/adversarial/deep-hierarchy-stress.test.ts +0 -213
- package/src/__tests__/adversarial/e2e-prd-validation.test.ts +0 -448
- package/src/__tests__/adversarial/edge-case.test.ts +0 -703
- package/src/__tests__/adversarial/error-merge-strategy.test.ts +0 -760
- package/src/__tests__/adversarial/incremental-performance.test.ts +0 -140
- package/src/__tests__/adversarial/node-map-update-benchmarks.test.ts +0 -457
- package/src/__tests__/adversarial/observer-propagation.test.ts +0 -487
- package/src/__tests__/adversarial/parent-validation.test.ts +0 -143
- package/src/__tests__/adversarial/prd-12-2-compliance.test.ts +0 -611
- package/src/__tests__/adversarial/prd-compliance.test.ts +0 -731
- package/src/__tests__/compatibility/backward-compatibility.test.ts +0 -1572
- package/src/__tests__/helpers/tree-verification.ts +0 -257
- package/src/__tests__/integration/agent-workflow.test.ts +0 -256
- package/src/__tests__/integration/bidirectional-consistency.test.ts +0 -847
- package/src/__tests__/integration/observer-logging.test.ts +0 -643
- package/src/__tests__/integration/tree-mirroring.test.ts +0 -151
- package/src/__tests__/integration/workflow-reparenting.test.ts +0 -303
- package/src/__tests__/unit/agent.test.ts +0 -169
- package/src/__tests__/unit/cache-key.test.ts +0 -182
- package/src/__tests__/unit/cache.test.ts +0 -172
- package/src/__tests__/unit/context.test.ts +0 -217
- package/src/__tests__/unit/decorators.test.ts +0 -100
- package/src/__tests__/unit/introspection-tools.test.ts +0 -277
- package/src/__tests__/unit/logger.test.ts +0 -293
- package/src/__tests__/unit/observable.test.ts +0 -321
- package/src/__tests__/unit/prompt.test.ts +0 -135
- package/src/__tests__/unit/reflection.test.ts +0 -210
- package/src/__tests__/unit/tree-debugger-incremental.test.ts +0 -170
- package/src/__tests__/unit/tree-debugger.test.ts +0 -85
- package/src/__tests__/unit/utils/workflow-error-utils.test.ts +0 -209
- package/src/__tests__/unit/workflow-detachChild.test.ts +0 -100
- package/src/__tests__/unit/workflow-emitEvent-childDetached.test.ts +0 -153
- package/src/__tests__/unit/workflow-isDescendantOf.test.ts +0 -180
- package/src/__tests__/unit/workflow.test.ts +0 -357
- package/src/cache/cache-key.ts +0 -244
- package/src/cache/cache.ts +0 -236
- package/src/core/agent.ts +0 -593
- package/src/core/event-tree.ts +0 -260
- package/src/core/logger.ts +0 -112
- package/src/core/mcp-handler.ts +0 -184
- package/src/core/prompt.ts +0 -150
- package/src/core/workflow-context.ts +0 -351
- package/src/core/workflow.ts +0 -540
- package/src/debugger/tree-debugger.ts +0 -255
- package/src/decorators/observed-state.ts +0 -95
- package/src/decorators/step.ts +0 -139
- package/src/decorators/task.ts +0 -159
- package/src/examples/tdd-orchestrator.ts +0 -65
- package/src/examples/test-cycle-workflow.ts +0 -64
- package/src/index.ts +0 -142
- package/src/reflection/reflection.ts +0 -407
- package/src/tools/index.ts +0 -36
- package/src/tools/introspection.ts +0 -464
- package/src/types/agent.ts +0 -90
- package/src/types/decorators.ts +0 -32
- package/src/types/error-strategy.ts +0 -13
- package/src/types/error.ts +0 -20
- package/src/types/events.ts +0 -75
- package/src/types/index.ts +0 -55
- package/src/types/logging.ts +0 -24
- package/src/types/observer.ts +0 -18
- package/src/types/prompt.ts +0 -40
- package/src/types/reflection.ts +0 -117
- package/src/types/sdk-primitives.ts +0 -128
- package/src/types/workflow-context.ts +0 -163
- package/src/types/workflow.ts +0 -37
- package/src/utils/id.ts +0 -11
- package/src/utils/observable.ts +0 -106
- package/src/utils/workflow-error-utils.ts +0 -56
- package/tsconfig.json +0 -22
- package/vitest.config.ts +0 -16
|
@@ -1,1170 +0,0 @@
|
|
|
1
|
-
# Error Logging Best Practices for TypeScript/JavaScript Applications
|
|
2
|
-
|
|
3
|
-
**Research Date:** 2026-01-12
|
|
4
|
-
**Focus Areas:** Observer pattern error handling, logger context propagation, structured logging patterns, TypeScript-specific considerations
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Table of Contents
|
|
9
|
-
|
|
10
|
-
1. [Observer Pattern Error Handling Best Practices](#1-observer-pattern-error-handling-best-practices)
|
|
11
|
-
2. [Logger Context Propagation Through Callback Chains](#2-logger-context-propagation-through-callback-chains)
|
|
12
|
-
3. [Replacing console.error with Structured Logging](#3-replacing-consoleerror-with-structured-logging)
|
|
13
|
-
4. [TypeScript-Specific Considerations](#4-typescript-specific-considerations)
|
|
14
|
-
5. [Recommended Libraries and Tools](#5-recommended-libraries-and-tools)
|
|
15
|
-
6. [Implementation Examples](#6-implementation-examples)
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## 1. Observer Pattern Error Handling Best Practices
|
|
20
|
-
|
|
21
|
-
### 1.1 Core Principles
|
|
22
|
-
|
|
23
|
-
**Error Isolation**
|
|
24
|
-
- Errors in one observer should not prevent other observers from receiving notifications
|
|
25
|
-
- Each observer callback should be wrapped in a try-catch block
|
|
26
|
-
- Failed observers should be logged but should not break the notification chain
|
|
27
|
-
|
|
28
|
-
**Fail-Safe Notification**
|
|
29
|
-
```typescript
|
|
30
|
-
interface Observer<T> {
|
|
31
|
-
next(value: T): void | Promise<void>;
|
|
32
|
-
error(err: Error): void | Promise<void>;
|
|
33
|
-
complete(): void | Promise<void>;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
class SafeObservable<T> {
|
|
37
|
-
private observers: Set<Observer<T>> = new Set();
|
|
38
|
-
|
|
39
|
-
subscribe(observer: Observer<T>): () => void {
|
|
40
|
-
this.observers.add(observer);
|
|
41
|
-
return () => this.observers.delete(observer);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
notify(value: T): void {
|
|
45
|
-
this.observers.forEach(observer => {
|
|
46
|
-
try {
|
|
47
|
-
const result = observer.next(value);
|
|
48
|
-
|
|
49
|
-
// Handle async observers
|
|
50
|
-
if (result instanceof Promise) {
|
|
51
|
-
result.catch(err => {
|
|
52
|
-
this.handleObserverError(observer, err, value);
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
} catch (err) {
|
|
56
|
-
this.handleObserverError(observer, err, value);
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
private handleObserverError(
|
|
62
|
-
observer: Observer<T>,
|
|
63
|
-
err: unknown,
|
|
64
|
-
value: T
|
|
65
|
-
): void {
|
|
66
|
-
const error = err instanceof Error ? err : new Error(String(err));
|
|
67
|
-
|
|
68
|
-
// Try to notify observer of error
|
|
69
|
-
try {
|
|
70
|
-
observer.error(error);
|
|
71
|
-
} catch (handlerError) {
|
|
72
|
-
// Last resort: log to fallback logger
|
|
73
|
-
console.error('Error in observer error handler:', handlerError);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### 1.2 Error Handling Patterns
|
|
80
|
-
|
|
81
|
-
**Pattern 1: Safe Notification with Error Callback**
|
|
82
|
-
```typescript
|
|
83
|
-
type SafeObserverCallback<T> = (value: T) => void | Promise<void>;
|
|
84
|
-
type ErrorHandler = (error: Error, observer: SafeObserverCallback<any>) => void;
|
|
85
|
-
|
|
86
|
-
class ErrorSafeObservable<T> {
|
|
87
|
-
private observers: Map<SafeObserverCallback<T>, ErrorHandler> = new Map();
|
|
88
|
-
|
|
89
|
-
subscribe(
|
|
90
|
-
onNext: SafeObserverCallback<T>,
|
|
91
|
-
onError?: ErrorHandler
|
|
92
|
-
): () => void {
|
|
93
|
-
this.observers.set(onNext, onError || this.defaultErrorHandler);
|
|
94
|
-
return () => this.observers.delete(onNext);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
notify(value: T): void {
|
|
98
|
-
this.observers.forEach((errorHandler, observer) => {
|
|
99
|
-
try {
|
|
100
|
-
const result = observer(value);
|
|
101
|
-
if (result instanceof Promise) {
|
|
102
|
-
result.catch(err => errorHandler(err, observer));
|
|
103
|
-
}
|
|
104
|
-
} catch (err) {
|
|
105
|
-
errorHandler(err, observer);
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
private defaultErrorHandler: ErrorHandler = (error, observer) => {
|
|
111
|
-
console.error('Observer callback error:', error);
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
**Pattern 2: Error Aggregation**
|
|
117
|
-
```typescript
|
|
118
|
-
interface ObserverError {
|
|
119
|
-
observer: string;
|
|
120
|
-
error: Error;
|
|
121
|
-
timestamp: Date;
|
|
122
|
-
value?: any;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
class ObservableWithErrorAggregation<T> {
|
|
126
|
-
private observers: Set<Observer<T>> = new Set();
|
|
127
|
-
private errors: ObserverError[] = [];
|
|
128
|
-
|
|
129
|
-
notify(value: T): ObserverError[] {
|
|
130
|
-
this.errors = [];
|
|
131
|
-
|
|
132
|
-
this.observers.forEach(observer => {
|
|
133
|
-
try {
|
|
134
|
-
observer.next(value);
|
|
135
|
-
} catch (err) {
|
|
136
|
-
this.errors.push({
|
|
137
|
-
observer: observer.constructor.name || 'Anonymous',
|
|
138
|
-
error: err instanceof Error ? err : new Error(String(err)),
|
|
139
|
-
timestamp: new Date(),
|
|
140
|
-
value
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
return this.errors;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
getErrors(): ObserverError[] {
|
|
149
|
-
return [...this.errors];
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
### 1.3 Best Practices for Observer Error Handling
|
|
155
|
-
|
|
156
|
-
1. **Always wrap observer callbacks in try-catch**
|
|
157
|
-
- Prevents cascading failures
|
|
158
|
-
- Allows other observers to execute
|
|
159
|
-
|
|
160
|
-
2. **Provide error feedback to observers**
|
|
161
|
-
- Implement the `error()` method on observers
|
|
162
|
-
- Pass errors back to the observer for handling
|
|
163
|
-
|
|
164
|
-
3. **Log all observer errors**
|
|
165
|
-
- Use structured logging with context
|
|
166
|
-
- Include observer identity and value that caused error
|
|
167
|
-
|
|
168
|
-
4. **Consider unsubscribing failed observers**
|
|
169
|
-
- Optional: Auto-unsubscribe after N errors
|
|
170
|
-
- Prevents repeated failures from same observer
|
|
171
|
-
|
|
172
|
-
5. **Handle both sync and async observers**
|
|
173
|
-
- Check for Promise return values
|
|
174
|
-
- Attach catch handlers to async callbacks
|
|
175
|
-
|
|
176
|
-
---
|
|
177
|
-
|
|
178
|
-
## 2. Logger Context Propagation Through Callback Chains
|
|
179
|
-
|
|
180
|
-
### 2.1 Context Propagation Patterns
|
|
181
|
-
|
|
182
|
-
**Pattern 1: AsyncLocalStorage (Node.js)**
|
|
183
|
-
```typescript
|
|
184
|
-
import { AsyncLocalStorage } from 'async_hooks';
|
|
185
|
-
|
|
186
|
-
interface LogContext {
|
|
187
|
-
correlationId: string;
|
|
188
|
-
userId?: string;
|
|
189
|
-
requestId?: string;
|
|
190
|
-
operation?: string;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
const contextStorage = new AsyncLocalStorage<LogContext>();
|
|
194
|
-
|
|
195
|
-
class ContextualLogger {
|
|
196
|
-
error(message: string, error?: Error): void {
|
|
197
|
-
const context = contextStorage.getStore();
|
|
198
|
-
console.error({
|
|
199
|
-
timestamp: new Date().toISOString(),
|
|
200
|
-
message,
|
|
201
|
-
error: error ? {
|
|
202
|
-
name: error.name,
|
|
203
|
-
message: error.message,
|
|
204
|
-
stack: error.stack
|
|
205
|
-
} : undefined,
|
|
206
|
-
...context
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
info(message: string, metadata?: Record<string, any>): void {
|
|
211
|
-
const context = contextStorage.getStore();
|
|
212
|
-
console.info({
|
|
213
|
-
timestamp: new Date().toISOString(),
|
|
214
|
-
message,
|
|
215
|
-
...metadata,
|
|
216
|
-
...context
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// Usage
|
|
222
|
-
const logger = new ContextualLogger();
|
|
223
|
-
|
|
224
|
-
async function withContext<T>(
|
|
225
|
-
context: LogContext,
|
|
226
|
-
fn: () => Promise<T>
|
|
227
|
-
): Promise<T> {
|
|
228
|
-
return contextStorage.run(context, fn);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// Example: Context propagates through callback chain
|
|
232
|
-
async function processUser(userId: string) {
|
|
233
|
-
return withContext(
|
|
234
|
-
{ correlationId: generateId(), userId, operation: 'processUser' },
|
|
235
|
-
async () => {
|
|
236
|
-
logger.info('Starting user processing');
|
|
237
|
-
|
|
238
|
-
// Context is preserved through all async operations
|
|
239
|
-
await processData();
|
|
240
|
-
await validateData();
|
|
241
|
-
|
|
242
|
-
logger.info('Completed user processing');
|
|
243
|
-
}
|
|
244
|
-
);
|
|
245
|
-
}
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
**Pattern 2: Explicit Context Passing**
|
|
249
|
-
```typescript
|
|
250
|
-
interface LoggerContext {
|
|
251
|
-
traceId: string;
|
|
252
|
-
component: string;
|
|
253
|
-
userId?: string;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
type ContextualCallback<T> = (context: LoggerContext, data: T) => void;
|
|
257
|
-
|
|
258
|
-
class ContextAwareObservable<T> {
|
|
259
|
-
private baseContext: LoggerContext;
|
|
260
|
-
private observers: Set<ContextualCallback<T>> = new Set();
|
|
261
|
-
|
|
262
|
-
constructor(baseContext: LoggerContext) {
|
|
263
|
-
this.baseContext = baseContext;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
subscribe(callback: ContextualCallback<T>): () => void {
|
|
267
|
-
this.observers.add(callback);
|
|
268
|
-
return () => this.observers.delete(callback);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
notify(data: T): void {
|
|
272
|
-
const context = {
|
|
273
|
-
...this.baseContext,
|
|
274
|
-
timestamp: new Date().toISOString()
|
|
275
|
-
};
|
|
276
|
-
|
|
277
|
-
this.observers.forEach(callback => {
|
|
278
|
-
try {
|
|
279
|
-
callback(context, data);
|
|
280
|
-
} catch (err) {
|
|
281
|
-
console.error('Observer error:', {
|
|
282
|
-
error: err instanceof Error ? err.message : String(err),
|
|
283
|
-
context
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
// Usage
|
|
291
|
-
const observable = new ContextAwareObservable({
|
|
292
|
-
traceId: 'trace-123',
|
|
293
|
-
component: 'UserService'
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
observable.subscribe((context, data) => {
|
|
297
|
-
console.log('Received data:', { context, data });
|
|
298
|
-
});
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
**Pattern 3: Logger Factory Pattern**
|
|
302
|
-
```typescript
|
|
303
|
-
class LoggerFactory {
|
|
304
|
-
private static baseContext: Record<string, any> = {};
|
|
305
|
-
|
|
306
|
-
static setBaseContext(context: Record<string, any>): void {
|
|
307
|
-
this.baseContext = { ...this.baseContext, ...context };
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
static createLogger(component: string): Logger {
|
|
311
|
-
return new Logger({
|
|
312
|
-
...this.baseContext,
|
|
313
|
-
component
|
|
314
|
-
});
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
static withContext<T>(
|
|
318
|
-
context: Record<string, any>,
|
|
319
|
-
fn: () => T
|
|
320
|
-
): T {
|
|
321
|
-
const originalContext = { ...this.baseContext };
|
|
322
|
-
this.baseContext = { ...this.baseContext, ...context };
|
|
323
|
-
|
|
324
|
-
try {
|
|
325
|
-
return fn();
|
|
326
|
-
} finally {
|
|
327
|
-
this.baseContext = originalContext;
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
class Logger {
|
|
333
|
-
constructor(private context: Record<string, any>) {}
|
|
334
|
-
|
|
335
|
-
error(message: string, error?: Error): void {
|
|
336
|
-
console.error({
|
|
337
|
-
timestamp: new Date().toISOString(),
|
|
338
|
-
level: 'error',
|
|
339
|
-
message,
|
|
340
|
-
...(error && {
|
|
341
|
-
error: {
|
|
342
|
-
name: error.name,
|
|
343
|
-
message: error.message,
|
|
344
|
-
stack: error.stack
|
|
345
|
-
}
|
|
346
|
-
}),
|
|
347
|
-
...this.context
|
|
348
|
-
});
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
### 2.2 Best Practices for Context Propagation
|
|
354
|
-
|
|
355
|
-
1. **Use AsyncLocalStorage in Node.js**
|
|
356
|
-
- Automatic propagation through async boundaries
|
|
357
|
-
- No need to manually pass context
|
|
358
|
-
- Zero overhead for synchronous code
|
|
359
|
-
|
|
360
|
-
2. **Include correlation/trace IDs**
|
|
361
|
-
- Track requests across service boundaries
|
|
362
|
-
- Enable distributed tracing
|
|
363
|
-
- Use UUIDs or similar unique identifiers
|
|
364
|
-
|
|
365
|
-
3. **Make context immutable**
|
|
366
|
-
- Prevent accidental modifications
|
|
367
|
-
- Use Readonly types in TypeScript
|
|
368
|
-
- Create new context objects instead of mutating
|
|
369
|
-
|
|
370
|
-
4. **Set context at entry points**
|
|
371
|
-
- HTTP request handlers
|
|
372
|
-
- Message queue consumers
|
|
373
|
-
- Scheduled job entry points
|
|
374
|
-
|
|
375
|
-
5. **Beware of context loss**
|
|
376
|
-
- Some async operations lose context
|
|
377
|
-
- Be careful with setTimeout/setInterval
|
|
378
|
-
- Test context propagation thoroughly
|
|
379
|
-
|
|
380
|
-
---
|
|
381
|
-
|
|
382
|
-
## 3. Replacing console.error with Structured Logging
|
|
383
|
-
|
|
384
|
-
### 3.1 Why Replace console.error?
|
|
385
|
-
|
|
386
|
-
**Limitations of console.error:**
|
|
387
|
-
- Inconsistent format across browsers/environments
|
|
388
|
-
- Difficult to parse and search in production
|
|
389
|
-
- No built-in log levels or filtering
|
|
390
|
-
- Lacks metadata/context attachment
|
|
391
|
-
- Not suitable for centralized logging
|
|
392
|
-
|
|
393
|
-
**Benefits of Structured Logging:**
|
|
394
|
-
- JSON format for easy parsing
|
|
395
|
-
- Searchable and queryable
|
|
396
|
-
- Consistent schema across application
|
|
397
|
-
- Support for log levels and filtering
|
|
398
|
-
- Integration with log aggregation tools
|
|
399
|
-
- Better debugging in production
|
|
400
|
-
|
|
401
|
-
### 3.2 Structured Logging Libraries
|
|
402
|
-
|
|
403
|
-
**Winston (Industry Standard)**
|
|
404
|
-
```typescript
|
|
405
|
-
import winston from 'winston';
|
|
406
|
-
|
|
407
|
-
const logger = winston.createLogger({
|
|
408
|
-
level: process.env.LOG_LEVEL || 'info',
|
|
409
|
-
format: winston.format.combine(
|
|
410
|
-
winston.format.timestamp({
|
|
411
|
-
format: 'YYYY-MM-DD HH:mm:ss'
|
|
412
|
-
}),
|
|
413
|
-
winston.format.errors({ stack: true }),
|
|
414
|
-
winston.format.json()
|
|
415
|
-
),
|
|
416
|
-
defaultMeta: {
|
|
417
|
-
service: 'user-service',
|
|
418
|
-
environment: process.env.NODE_ENV
|
|
419
|
-
},
|
|
420
|
-
transports: [
|
|
421
|
-
new winston.transports.Console({
|
|
422
|
-
format: winston.format.combine(
|
|
423
|
-
winston.format.colorize(),
|
|
424
|
-
winston.format.simple()
|
|
425
|
-
)
|
|
426
|
-
}),
|
|
427
|
-
new winston.transports.File({
|
|
428
|
-
filename: 'error.log',
|
|
429
|
-
level: 'error'
|
|
430
|
-
}),
|
|
431
|
-
new winston.transports.File({
|
|
432
|
-
filename: 'combined.log'
|
|
433
|
-
})
|
|
434
|
-
]
|
|
435
|
-
});
|
|
436
|
-
|
|
437
|
-
// Usage
|
|
438
|
-
logger.error('Failed to process user', {
|
|
439
|
-
userId: '12345',
|
|
440
|
-
error: error.message,
|
|
441
|
-
stack: error.stack,
|
|
442
|
-
operation: 'processUser'
|
|
443
|
-
});
|
|
444
|
-
```
|
|
445
|
-
|
|
446
|
-
**Pino (High Performance)**
|
|
447
|
-
```typescript
|
|
448
|
-
import pino from 'pino';
|
|
449
|
-
|
|
450
|
-
const logger = pino({
|
|
451
|
-
level: process.env.LOG_LEVEL || 'info',
|
|
452
|
-
formatters: {
|
|
453
|
-
level: (label) => {
|
|
454
|
-
return { level: label };
|
|
455
|
-
}
|
|
456
|
-
},
|
|
457
|
-
redact: ['password', 'token', 'secret'],
|
|
458
|
-
timestamp: pino.stdTimeFunctions.isoTime
|
|
459
|
-
});
|
|
460
|
-
|
|
461
|
-
// Usage
|
|
462
|
-
logger.error({
|
|
463
|
-
userId: '12345',
|
|
464
|
-
err: {
|
|
465
|
-
type: error.name,
|
|
466
|
-
message: error.message,
|
|
467
|
-
stack: error.stack
|
|
468
|
-
},
|
|
469
|
-
operation: 'processUser'
|
|
470
|
-
}, 'Failed to process user');
|
|
471
|
-
```
|
|
472
|
-
|
|
473
|
-
**Roarr (Minimalist)**
|
|
474
|
-
```typescript
|
|
475
|
-
import Logger from 'roarr';
|
|
476
|
-
|
|
477
|
-
const logger = new Logger();
|
|
478
|
-
|
|
479
|
-
logger.error({
|
|
480
|
-
userId: '12345',
|
|
481
|
-
error: {
|
|
482
|
-
message: error.message,
|
|
483
|
-
stack: error.stack
|
|
484
|
-
}
|
|
485
|
-
}, 'Failed to process user');
|
|
486
|
-
```
|
|
487
|
-
|
|
488
|
-
### 3.3 Migration Strategy
|
|
489
|
-
|
|
490
|
-
**Phase 1: Create Logging Abstraction**
|
|
491
|
-
```typescript
|
|
492
|
-
interface ILogger {
|
|
493
|
-
error(message: string, error?: Error, context?: Record<string, any>): void;
|
|
494
|
-
warn(message: string, context?: Record<string, any>): void;
|
|
495
|
-
info(message: string, context?: Record<string, any>): void;
|
|
496
|
-
debug(message: string, context?: Record<string, any>): void;
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
// Create adapter for your chosen library
|
|
500
|
-
class LoggerAdapter implements ILogger {
|
|
501
|
-
constructor(private winston: winston.Logger) {}
|
|
502
|
-
|
|
503
|
-
error(message: string, error?: Error, context?: Record<string, any>): void {
|
|
504
|
-
this.winston.error(message, {
|
|
505
|
-
...(error && {
|
|
506
|
-
error: {
|
|
507
|
-
name: error.name,
|
|
508
|
-
message: error.message,
|
|
509
|
-
stack: error.stack
|
|
510
|
-
}
|
|
511
|
-
}),
|
|
512
|
-
...context
|
|
513
|
-
});
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
// ... other methods
|
|
517
|
-
}
|
|
518
|
-
```
|
|
519
|
-
|
|
520
|
-
**Phase 2: Gradual Replacement**
|
|
521
|
-
```typescript
|
|
522
|
-
// Before
|
|
523
|
-
console.error('Observer error:', error);
|
|
524
|
-
|
|
525
|
-
// After
|
|
526
|
-
logger.error('Observer error', error, {
|
|
527
|
-
component: 'Observable',
|
|
528
|
-
observer: observerName
|
|
529
|
-
});
|
|
530
|
-
```
|
|
531
|
-
|
|
532
|
-
**Phase 3: Replace All Instances**
|
|
533
|
-
```bash
|
|
534
|
-
# Find all console.error calls
|
|
535
|
-
grep -r "console\.error" src/
|
|
536
|
-
|
|
537
|
-
# Replace systematically
|
|
538
|
-
```
|
|
539
|
-
|
|
540
|
-
### 3.4 Structured Logging Best Practices
|
|
541
|
-
|
|
542
|
-
1. **Use consistent field names**
|
|
543
|
-
- `timestamp` (ISO 8601 format)
|
|
544
|
-
- `level` (error, warn, info, debug)
|
|
545
|
-
- `message` (human-readable description)
|
|
546
|
-
- `error` (error details)
|
|
547
|
-
- `context` (additional metadata)
|
|
548
|
-
|
|
549
|
-
2. **Include correlation IDs**
|
|
550
|
-
- Link related log entries
|
|
551
|
-
- Track requests across boundaries
|
|
552
|
-
- Enable distributed tracing
|
|
553
|
-
|
|
554
|
-
3. **Sanitize sensitive data**
|
|
555
|
-
- Passwords, tokens, API keys
|
|
556
|
-
- Personal information (PII)
|
|
557
|
-
- Use redaction in logger configuration
|
|
558
|
-
|
|
559
|
-
4. **Use appropriate log levels**
|
|
560
|
-
- `error`: Application errors requiring attention
|
|
561
|
-
- `warn`: Warning conditions not stopping execution
|
|
562
|
-
- `info`: General informational messages
|
|
563
|
-
- `debug`: Detailed diagnostic information
|
|
564
|
-
|
|
565
|
-
5. **Structure error objects consistently**
|
|
566
|
-
```typescript
|
|
567
|
-
{
|
|
568
|
-
error: {
|
|
569
|
-
type: 'DatabaseError',
|
|
570
|
-
message: 'Connection failed',
|
|
571
|
-
code: 'DB_CONN_001',
|
|
572
|
-
stack: '...',
|
|
573
|
-
context: {
|
|
574
|
-
host: 'localhost',
|
|
575
|
-
port: 5432
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
```
|
|
580
|
-
|
|
581
|
-
---
|
|
582
|
-
|
|
583
|
-
## 4. TypeScript-Specific Considerations
|
|
584
|
-
|
|
585
|
-
### 4.1 Type-Safe Error Handling
|
|
586
|
-
|
|
587
|
-
**Typed Error Classes**
|
|
588
|
-
```typescript
|
|
589
|
-
abstract class AppError extends Error {
|
|
590
|
-
abstract readonly code: string;
|
|
591
|
-
abstract readonly statusCode: number;
|
|
592
|
-
|
|
593
|
-
constructor(
|
|
594
|
-
message: string,
|
|
595
|
-
public readonly context?: Record<string, any>
|
|
596
|
-
) {
|
|
597
|
-
super(message);
|
|
598
|
-
this.name = this.constructor.name;
|
|
599
|
-
Error.captureStackTrace(this, this.constructor);
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
class ValidationError extends AppError {
|
|
604
|
-
readonly code = 'VALIDATION_ERROR';
|
|
605
|
-
readonly statusCode = 400;
|
|
606
|
-
|
|
607
|
-
constructor(
|
|
608
|
-
message: string,
|
|
609
|
-
public readonly validationErrors: Record<string, string[]>
|
|
610
|
-
) {
|
|
611
|
-
super(message);
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
class DatabaseError extends AppError {
|
|
616
|
-
readonly code = 'DATABASE_ERROR';
|
|
617
|
-
readonly statusCode = 500;
|
|
618
|
-
|
|
619
|
-
constructor(
|
|
620
|
-
message: string,
|
|
621
|
-
public readonly originalError?: Error
|
|
622
|
-
) {
|
|
623
|
-
super(message);
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
```
|
|
627
|
-
|
|
628
|
-
**Type-Safe Observer Pattern**
|
|
629
|
-
```typescript
|
|
630
|
-
type SafeObserverCallback<T, E extends Error = Error> = (
|
|
631
|
-
value: T
|
|
632
|
-
) => void | Promise<void>;
|
|
633
|
-
|
|
634
|
-
type ErrorHandler<E extends Error = Error> = (
|
|
635
|
-
error: E
|
|
636
|
-
) => void | Promise<void>;
|
|
637
|
-
|
|
638
|
-
interface StrictObserver<T, E extends Error = Error> {
|
|
639
|
-
next(value: T): void | Promise<void>;
|
|
640
|
-
error(error: E): void | Promise<void>;
|
|
641
|
-
complete(): void | Promise<void>;
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
class TypedObservable<T, E extends Error = Error> {
|
|
645
|
-
private observers: Set<StrictObserver<T, E>> = new Set();
|
|
646
|
-
|
|
647
|
-
subscribe(observer: StrictObserver<T, E>): () => void {
|
|
648
|
-
this.observers.add(observer);
|
|
649
|
-
return () => this.observers.delete(observer);
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
notify(value: T): void;
|
|
653
|
-
notify(error: E): void;
|
|
654
|
-
notify(value: T | E): void {
|
|
655
|
-
this.observers.forEach(observer => {
|
|
656
|
-
try {
|
|
657
|
-
if (value instanceof Error) {
|
|
658
|
-
observer.error(value as E);
|
|
659
|
-
} else {
|
|
660
|
-
observer.next(value);
|
|
661
|
-
}
|
|
662
|
-
} catch (err) {
|
|
663
|
-
console.error('Observer error:', err);
|
|
664
|
-
}
|
|
665
|
-
});
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
```
|
|
669
|
-
|
|
670
|
-
### 4.2 Type-Safe Logger
|
|
671
|
-
|
|
672
|
-
```typescript
|
|
673
|
-
type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
674
|
-
|
|
675
|
-
interface LogMetadata {
|
|
676
|
-
[key: string]: any;
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
interface LogEntry {
|
|
680
|
-
timestamp: string;
|
|
681
|
-
level: LogLevel;
|
|
682
|
-
message: string;
|
|
683
|
-
error?: {
|
|
684
|
-
name: string;
|
|
685
|
-
message: string;
|
|
686
|
-
stack?: string;
|
|
687
|
-
code?: string;
|
|
688
|
-
};
|
|
689
|
-
metadata?: LogMetadata;
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
class TypedLogger {
|
|
693
|
-
constructor(
|
|
694
|
-
private component: string,
|
|
695
|
-
private baseContext: LogMetadata = {}
|
|
696
|
-
) {}
|
|
697
|
-
|
|
698
|
-
private log(level: LogLevel, message: string, entry: Partial<LogEntry> = {}): void {
|
|
699
|
-
const logEntry: LogEntry = {
|
|
700
|
-
timestamp: new Date().toISOString(),
|
|
701
|
-
level,
|
|
702
|
-
message,
|
|
703
|
-
...entry,
|
|
704
|
-
metadata: {
|
|
705
|
-
component: this.component,
|
|
706
|
-
...this.baseContext,
|
|
707
|
-
...entry.metadata
|
|
708
|
-
}
|
|
709
|
-
};
|
|
710
|
-
|
|
711
|
-
console[level](JSON.stringify(logEntry));
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
error(message: string, error?: Error, metadata?: LogMetadata): void {
|
|
715
|
-
this.log('error', message, {
|
|
716
|
-
...(error && {
|
|
717
|
-
error: {
|
|
718
|
-
name: error.name,
|
|
719
|
-
message: error.message,
|
|
720
|
-
stack: error.stack,
|
|
721
|
-
code: (error as any).code
|
|
722
|
-
}
|
|
723
|
-
}),
|
|
724
|
-
metadata
|
|
725
|
-
});
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
warn(message: string, metadata?: LogMetadata): void {
|
|
729
|
-
this.log('warn', message, { metadata });
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
info(message: string, metadata?: LogMetadata): void {
|
|
733
|
-
this.log('info', message, { metadata });
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
debug(message: string, metadata?: LogMetadata): void {
|
|
737
|
-
this.log('debug', message, { metadata });
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
withContext(context: LogMetadata): TypedLogger {
|
|
741
|
-
return new TypedLogger(this.component, {
|
|
742
|
-
...this.baseContext,
|
|
743
|
-
...context
|
|
744
|
-
});
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
// Usage
|
|
749
|
-
const logger = new TypedLogger('UserService');
|
|
750
|
-
|
|
751
|
-
logger.error('Failed to create user', error, {
|
|
752
|
-
userId: '12345',
|
|
753
|
-
email: 'user@example.com'
|
|
754
|
-
});
|
|
755
|
-
|
|
756
|
-
const userScopedLogger = logger.withContext({ userId: '12345' });
|
|
757
|
-
userScopedLogger.info('User profile updated');
|
|
758
|
-
```
|
|
759
|
-
|
|
760
|
-
### 4.3 Type Guards for Error Handling
|
|
761
|
-
|
|
762
|
-
```typescript
|
|
763
|
-
function isError(error: unknown): error is Error {
|
|
764
|
-
return (
|
|
765
|
-
error instanceof Error ||
|
|
766
|
-
(typeof error === 'object' &&
|
|
767
|
-
error !== null &&
|
|
768
|
-
'message' in error &&
|
|
769
|
-
typeof error.message === 'string')
|
|
770
|
-
);
|
|
771
|
-
}
|
|
772
|
-
|
|
773
|
-
function isAppError(error: unknown): error is AppError {
|
|
774
|
-
return isError(error) && error instanceof AppError;
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
function handleUnknownError(error: unknown): void {
|
|
778
|
-
if (isAppError(error)) {
|
|
779
|
-
logger.error('Application error', error, {
|
|
780
|
-
code: error.code,
|
|
781
|
-
context: error.context
|
|
782
|
-
});
|
|
783
|
-
} else if (isError(error)) {
|
|
784
|
-
logger.error('Unexpected error', error);
|
|
785
|
-
} else {
|
|
786
|
-
logger.error('Unknown error type', undefined, {
|
|
787
|
-
error: String(error)
|
|
788
|
-
});
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
```
|
|
792
|
-
|
|
793
|
-
### 4.4 TypeScript Best Practices
|
|
794
|
-
|
|
795
|
-
1. **Use discriminated unions for error types**
|
|
796
|
-
```typescript
|
|
797
|
-
type Result<T, E extends Error = Error> =
|
|
798
|
-
| { success: true; data: T }
|
|
799
|
-
| { success: false; error: E };
|
|
800
|
-
```
|
|
801
|
-
|
|
802
|
-
2. **Leverage utility types**
|
|
803
|
-
```typescript
|
|
804
|
-
type ErrorContext<T extends Error> = {
|
|
805
|
-
[K in keyof T]?: T[K];
|
|
806
|
-
};
|
|
807
|
-
```
|
|
808
|
-
|
|
809
|
-
3. **Use readonly for context**
|
|
810
|
-
```typescript
|
|
811
|
-
interface LogContext {
|
|
812
|
-
readonly correlationId: string;
|
|
813
|
-
readonly userId?: string;
|
|
814
|
-
}
|
|
815
|
-
```
|
|
816
|
-
|
|
817
|
-
4. **Enable strict error checking**
|
|
818
|
-
```typescript
|
|
819
|
-
// tsconfig.json
|
|
820
|
-
{
|
|
821
|
-
"compilerOptions": {
|
|
822
|
-
"strictNullChecks": true,
|
|
823
|
-
"strictPropertyInitialization": true,
|
|
824
|
-
"noImplicitAny": true,
|
|
825
|
-
"useUnknownInCatchVariables": true
|
|
826
|
-
}
|
|
827
|
-
}
|
|
828
|
-
```
|
|
829
|
-
|
|
830
|
-
5. **Type-safe logger factories**
|
|
831
|
-
```typescript
|
|
832
|
-
function createLogger(component: string): Logger {
|
|
833
|
-
return new TypedLogger(component);
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
// Ensure component names are valid
|
|
837
|
-
type ValidComponent =
|
|
838
|
-
| 'UserService'
|
|
839
|
-
| 'AuthService'
|
|
840
|
-
| 'DatabaseService';
|
|
841
|
-
|
|
842
|
-
function createComponentLogger(
|
|
843
|
-
component: ValidComponent
|
|
844
|
-
): Logger {
|
|
845
|
-
return createLogger(component);
|
|
846
|
-
}
|
|
847
|
-
```
|
|
848
|
-
|
|
849
|
-
---
|
|
850
|
-
|
|
851
|
-
## 5. Recommended Libraries and Tools
|
|
852
|
-
|
|
853
|
-
### 5.1 Logging Libraries
|
|
854
|
-
|
|
855
|
-
| Library | Performance | Features | Best For |
|
|
856
|
-
|---------|-------------|----------|----------|
|
|
857
|
-
| **Winston** | Medium | Rich features, multiple transports | General-purpose applications |
|
|
858
|
-
| **Pino** | Very Fast | Minimal, high performance | High-throughput applications |
|
|
859
|
-
| **Bunyan** | Fast | JSON-first, extensible | Node.js applications |
|
|
860
|
-
| **log4js** | Medium | Flexible, multiple categories | Applications needing categories |
|
|
861
|
-
| **Roarr** | Fast | Minimalist, structured | Modern Node.js applications |
|
|
862
|
-
|
|
863
|
-
### 5.2 Error Handling Libraries
|
|
864
|
-
|
|
865
|
-
| Library | Purpose | TypeScript Support |
|
|
866
|
-
|---------|---------|-------------------|
|
|
867
|
-
| **fp-ts** | Functional error handling | Excellent |
|
|
868
|
-
| **neverthrow** | Result type for error handling | Excellent |
|
|
869
|
-
| **ts-results** | Result/Option types | Excellent |
|
|
870
|
-
| **Vest** | Validation framework | Good |
|
|
871
|
-
|
|
872
|
-
### 5.3 Observable/RxJS Libraries
|
|
873
|
-
|
|
874
|
-
| Library | Error Handling | TypeScript Support |
|
|
875
|
-
|---------|---------------|-------------------|
|
|
876
|
-
| **RxJS** | Comprehensive error operators | Excellent |
|
|
877
|
-
| **Zen-observable** | Basic observer pattern | Good |
|
|
878
|
-
| **Observable-Flyd** | Lightweight streams | Basic |
|
|
879
|
-
|
|
880
|
-
---
|
|
881
|
-
|
|
882
|
-
## 6. Implementation Examples
|
|
883
|
-
|
|
884
|
-
### 6.1 Complete Observer with Structured Logging
|
|
885
|
-
|
|
886
|
-
```typescript
|
|
887
|
-
import winston from 'winston';
|
|
888
|
-
|
|
889
|
-
// Setup logger
|
|
890
|
-
const logger = winston.createLogger({
|
|
891
|
-
level: 'info',
|
|
892
|
-
format: winston.format.combine(
|
|
893
|
-
winston.format.timestamp(),
|
|
894
|
-
winston.format.json()
|
|
895
|
-
),
|
|
896
|
-
transports: [new winston.transports.Console()]
|
|
897
|
-
});
|
|
898
|
-
|
|
899
|
-
// Error types
|
|
900
|
-
class ObserverError extends Error {
|
|
901
|
-
constructor(
|
|
902
|
-
message: string,
|
|
903
|
-
public readonly observerName: string,
|
|
904
|
-
public readonly value?: any
|
|
905
|
-
) {
|
|
906
|
-
super(message);
|
|
907
|
-
this.name = 'ObserverError';
|
|
908
|
-
}
|
|
909
|
-
}
|
|
910
|
-
|
|
911
|
-
// Observer interface with error handling
|
|
912
|
-
interface Observer<T> {
|
|
913
|
-
next(value: T): void | Promise<void>;
|
|
914
|
-
error(error: Error): void | Promise<void>;
|
|
915
|
-
complete(): void | Promise<void>;
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
// Observable with comprehensive error handling
|
|
919
|
-
class Observable<T> {
|
|
920
|
-
private observers: Map<string, Observer<T>> = new Map();
|
|
921
|
-
private errors: ObserverError[] = [];
|
|
922
|
-
|
|
923
|
-
subscribe(observer: Observer<T>, name: string): () => void {
|
|
924
|
-
this.observers.set(name, observer);
|
|
925
|
-
return () => this.observers.delete(name);
|
|
926
|
-
}
|
|
927
|
-
|
|
928
|
-
notify(value: T): void {
|
|
929
|
-
this.errors = [];
|
|
930
|
-
|
|
931
|
-
this.observers.forEach((observer, name) => {
|
|
932
|
-
try {
|
|
933
|
-
const result = observer.next(value);
|
|
934
|
-
|
|
935
|
-
if (result instanceof Promise) {
|
|
936
|
-
result.catch(err => {
|
|
937
|
-
this.handleError(name, err, value);
|
|
938
|
-
});
|
|
939
|
-
}
|
|
940
|
-
} catch (err) {
|
|
941
|
-
this.handleError(name, err, value);
|
|
942
|
-
}
|
|
943
|
-
});
|
|
944
|
-
|
|
945
|
-
// Log all errors
|
|
946
|
-
this.errors.forEach(err => {
|
|
947
|
-
logger.error('Observer callback failed', err, {
|
|
948
|
-
component: 'Observable',
|
|
949
|
-
observer: err.observerName,
|
|
950
|
-
value: err.value
|
|
951
|
-
});
|
|
952
|
-
});
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
private handleError(
|
|
956
|
-
observerName: string,
|
|
957
|
-
err: unknown,
|
|
958
|
-
value: T
|
|
959
|
-
): void {
|
|
960
|
-
const error = err instanceof Error
|
|
961
|
-
? err
|
|
962
|
-
: new Error(String(err));
|
|
963
|
-
|
|
964
|
-
const observerError = new ObserverError(
|
|
965
|
-
error.message,
|
|
966
|
-
observerName,
|
|
967
|
-
value
|
|
968
|
-
);
|
|
969
|
-
|
|
970
|
-
this.errors.push(observerError);
|
|
971
|
-
|
|
972
|
-
// Try to notify observer
|
|
973
|
-
const observer = this.observers.get(observerName);
|
|
974
|
-
if (observer) {
|
|
975
|
-
try {
|
|
976
|
-
observer.error(observerError);
|
|
977
|
-
} catch (handlerError) {
|
|
978
|
-
logger.error('Observer error handler failed', handlerError instanceof Error ? handlerError : undefined, {
|
|
979
|
-
component: 'Observable',
|
|
980
|
-
observer: observerName,
|
|
981
|
-
originalError: error.message
|
|
982
|
-
});
|
|
983
|
-
}
|
|
984
|
-
}
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
|
-
|
|
988
|
-
// Usage
|
|
989
|
-
const observable = new Observable<number>();
|
|
990
|
-
|
|
991
|
-
observable.subscribe(
|
|
992
|
-
{
|
|
993
|
-
next: (value) => {
|
|
994
|
-
console.log('Received:', value);
|
|
995
|
-
},
|
|
996
|
-
error: (error) => {
|
|
997
|
-
console.error('Error:', error.message);
|
|
998
|
-
},
|
|
999
|
-
complete: () => {
|
|
1000
|
-
console.log('Complete');
|
|
1001
|
-
}
|
|
1002
|
-
},
|
|
1003
|
-
'ConsoleObserver'
|
|
1004
|
-
);
|
|
1005
|
-
|
|
1006
|
-
observable.notify(42);
|
|
1007
|
-
```
|
|
1008
|
-
|
|
1009
|
-
### 6.2 Logger with Context Propagation
|
|
1010
|
-
|
|
1011
|
-
```typescript
|
|
1012
|
-
import { AsyncLocalStorage } from 'async_hooks';
|
|
1013
|
-
import winston from 'winston';
|
|
1014
|
-
|
|
1015
|
-
interface LogContext {
|
|
1016
|
-
traceId: string;
|
|
1017
|
-
userId?: string;
|
|
1018
|
-
operation?: string;
|
|
1019
|
-
}
|
|
1020
|
-
|
|
1021
|
-
class ContextualLogger {
|
|
1022
|
-
private static storage = new AsyncLocalStorage<LogContext>();
|
|
1023
|
-
private static baseLogger = winston.createLogger({
|
|
1024
|
-
level: 'info',
|
|
1025
|
-
format: winston.format.combine(
|
|
1026
|
-
winston.format.timestamp(),
|
|
1027
|
-
winston.format.json()
|
|
1028
|
-
),
|
|
1029
|
-
transports: [new winston.transports.Console()]
|
|
1030
|
-
});
|
|
1031
|
-
|
|
1032
|
-
static runWithContext<T>(
|
|
1033
|
-
context: LogContext,
|
|
1034
|
-
fn: () => Promise<T>
|
|
1035
|
-
): Promise<T> {
|
|
1036
|
-
return this.storage.run(context, fn);
|
|
1037
|
-
}
|
|
1038
|
-
|
|
1039
|
-
private static getContext(): LogContext {
|
|
1040
|
-
return this.storage.getStore() || { traceId: 'unknown' };
|
|
1041
|
-
}
|
|
1042
|
-
|
|
1043
|
-
static error(message: string, error?: Error): void {
|
|
1044
|
-
const context = this.getContext();
|
|
1045
|
-
this.baseLogger.error(message, {
|
|
1046
|
-
...context,
|
|
1047
|
-
...(error && {
|
|
1048
|
-
error: {
|
|
1049
|
-
name: error.name,
|
|
1050
|
-
message: error.message,
|
|
1051
|
-
stack: error.stack
|
|
1052
|
-
}
|
|
1053
|
-
})
|
|
1054
|
-
});
|
|
1055
|
-
}
|
|
1056
|
-
|
|
1057
|
-
static info(message: string, metadata?: Record<string, any>): void {
|
|
1058
|
-
const context = this.getContext();
|
|
1059
|
-
this.baseLogger.info(message, {
|
|
1060
|
-
...context,
|
|
1061
|
-
...metadata
|
|
1062
|
-
});
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1065
|
-
|
|
1066
|
-
// Usage with observer pattern
|
|
1067
|
-
async function processWithObserver(data: any[]) {
|
|
1068
|
-
return ContextualLogger.runWithContext(
|
|
1069
|
-
{ traceId: generateId(), operation: 'processData' },
|
|
1070
|
-
async () => {
|
|
1071
|
-
const observable = new Observable<any>();
|
|
1072
|
-
|
|
1073
|
-
observable.subscribe(
|
|
1074
|
-
{
|
|
1075
|
-
next: (value) => {
|
|
1076
|
-
ContextualLogger.info('Processing item', { itemId: value.id });
|
|
1077
|
-
// Process value
|
|
1078
|
-
},
|
|
1079
|
-
error: (error) => {
|
|
1080
|
-
ContextualLogger.error('Observer error', error);
|
|
1081
|
-
},
|
|
1082
|
-
complete: () => {
|
|
1083
|
-
ContextualLogger.info('Processing complete');
|
|
1084
|
-
}
|
|
1085
|
-
},
|
|
1086
|
-
'ItemProcessor'
|
|
1087
|
-
);
|
|
1088
|
-
|
|
1089
|
-
for (const item of data) {
|
|
1090
|
-
observable.notify(item);
|
|
1091
|
-
}
|
|
1092
|
-
}
|
|
1093
|
-
);
|
|
1094
|
-
}
|
|
1095
|
-
```
|
|
1096
|
-
|
|
1097
|
-
---
|
|
1098
|
-
|
|
1099
|
-
## Summary and Recommendations
|
|
1100
|
-
|
|
1101
|
-
### Key Takeaways
|
|
1102
|
-
|
|
1103
|
-
1. **Observer Pattern Error Handling**
|
|
1104
|
-
- Always wrap observer callbacks in try-catch
|
|
1105
|
-
- Isolate errors to prevent cascading failures
|
|
1106
|
-
- Provide error feedback through error() method
|
|
1107
|
-
- Support both sync and async observers
|
|
1108
|
-
|
|
1109
|
-
2. **Context Propagation**
|
|
1110
|
-
- Use AsyncLocalStorage in Node.js for automatic propagation
|
|
1111
|
-
- Include correlation/trace IDs for distributed tracing
|
|
1112
|
-
- Make context immutable
|
|
1113
|
-
- Set context at application entry points
|
|
1114
|
-
|
|
1115
|
-
3. **Structured Logging**
|
|
1116
|
-
- Replace console.error with a structured logging library
|
|
1117
|
-
- Use consistent field names and schemas
|
|
1118
|
-
- Include correlation IDs and metadata
|
|
1119
|
-
- Sanitize sensitive data
|
|
1120
|
-
|
|
1121
|
-
4. **TypeScript-Specific Considerations**
|
|
1122
|
-
- Create typed error classes
|
|
1123
|
-
- Use type guards for error handling
|
|
1124
|
-
- Leverage utility types
|
|
1125
|
-
- Enable strict error checking in tsconfig
|
|
1126
|
-
|
|
1127
|
-
### Implementation Roadmap
|
|
1128
|
-
|
|
1129
|
-
1. **Phase 1: Setup Infrastructure**
|
|
1130
|
-
- Choose and install logging library (Winston or Pino recommended)
|
|
1131
|
-
- Create logger abstraction layer
|
|
1132
|
-
- Setup AsyncLocalStorage for context propagation
|
|
1133
|
-
|
|
1134
|
-
2. **Phase 2: Create Error Types**
|
|
1135
|
-
- Define application error hierarchy
|
|
1136
|
-
- Create type-safe error classes
|
|
1137
|
-
- Implement error type guards
|
|
1138
|
-
|
|
1139
|
-
3. **Phase 3: Migrate Observer Pattern**
|
|
1140
|
-
- Update observer interface with error handling
|
|
1141
|
-
- Implement safe notification with try-catch
|
|
1142
|
-
- Add structured logging to error handlers
|
|
1143
|
-
|
|
1144
|
-
4. **Phase 4: Replace console.error**
|
|
1145
|
-
- Systematically find and replace console.error calls
|
|
1146
|
-
- Ensure all errors are logged with context
|
|
1147
|
-
- Add correlation IDs throughout application
|
|
1148
|
-
|
|
1149
|
-
5. **Phase 5: Testing and Validation**
|
|
1150
|
-
- Test error isolation in observers
|
|
1151
|
-
- Verify context propagation
|
|
1152
|
-
- Validate log output structure
|
|
1153
|
-
- Performance testing
|
|
1154
|
-
|
|
1155
|
-
### Additional Resources
|
|
1156
|
-
|
|
1157
|
-
**Documentation**
|
|
1158
|
-
- Winston: https://github.com/winstonjs/winston
|
|
1159
|
-
- Pino: https://getpino.io/
|
|
1160
|
-
- AsyncLocalStorage: https://nodejs.org/api/async_context.html
|
|
1161
|
-
- RxJS Error Handling: https://rxjs.dev/guide/error-handling
|
|
1162
|
-
|
|
1163
|
-
**Articles**
|
|
1164
|
-
- "The Twelve-Factor App - Logging": https://12factor.net/logs
|
|
1165
|
-
- "Structured Logging Best Practices": Various Medium/dev.to articles
|
|
1166
|
-
- "Observer Pattern in TypeScript": TypeScript documentation and patterns
|
|
1167
|
-
|
|
1168
|
-
---
|
|
1169
|
-
|
|
1170
|
-
**Note:** Due to web search quota limitations (resets February 1, 2026), this research is based on established best practices and patterns. For the most current information and specific library documentation, please refer to the official documentation linked above.
|