claude-flow-novice 2.15.3 → 2.15.5
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/.claude/cfn-extras/skills/advanced-features/cfn-agent-swap/recommend-swap.sh +59 -59
- package/.claude/cfn-extras/skills/analytics/cfn-improvement-recommender/recommend-improvements.sh +91 -91
- package/.claude/cfn-extras/skills/analytics/cfn-pattern-extraction/extract-patterns.sh +79 -79
- package/.claude/cfn-extras/skills/analytics/cfn-retrospective-report/generate-report.sh +100 -100
- package/.claude/cfn-extras/skills/analytics/cfn-telemetry/start-telemetry.sh +110 -110
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/add-bullet.sh +145 -145
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/log-merge.sh +67 -67
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/monitor-injection-performance.sh +137 -137
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/optimize-injection-pipeline.sh +168 -168
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/query-reflections.sh +35 -35
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/store-reflection.sh +45 -45
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/track-ab-test.sh +41 -41
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/update-reflection.sh +41 -41
- package/.claude/cfn-extras/skills/deprecated/cfn-cli-setup/validate-cli-environment.sh +191 -191
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/create-campaign.sh +231 -231
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/get-campaign-performance.sh +190 -190
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/pause-campaign.sh +142 -142
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/set-budget.sh +181 -181
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/update-bid-strategy.sh +133 -133
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/get-conversation-history.sh +121 -121
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/qualify-lead.sh +156 -156
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/schedule-demo.sh +181 -181
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/send-message.sh +137 -137
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/transfer-to-human.sh +179 -179
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/create-campaign.sh +183 -183
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/get-delivery-status.sh +139 -139
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/opt-out.sh +150 -150
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/schedule-campaign.sh +187 -187
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/send-sms.sh +181 -181
- package/.claude/cfn-extras/skills/ui-portal/cfn-web-portal/test-web-portal-skill.sh +50 -50
- package/.claude/cfn-extras/skills/ui-portal/cfn-web-portal/validate-deployment.sh +84 -84
- package/.claude/cfn-extras/skills/utility/cfn-environment-sanitization/sanitize-environment.sh +243 -243
- package/.claude/commands/cfn-loop-cli.md +29 -6
- package/.claude/commands/switch-api.md +31 -10
- package/.claude/hooks/cfn-lint-sql-injection.sh +61 -0
- package/.claude/hooks/cfn-post-edit-cfn-retrospective.sh +33 -2
- package/.claude/hooks/cfn-pre-edit-security-warning.sh +40 -0
- package/.claude/skills/cfn-agent-spawning/spawn-agent.sh +22 -24
- package/.claude/skills/cfn-docker-agent-spawning/SKILL.md +28 -4
- package/.claude/skills/cfn-docker-agent-spawning/spawn-agent.sh +3 -1
- package/.claude/skills/cfn-docker-loop-orchestration/orchestrate.sh +224 -20
- package/.claude/skills/cfn-loop-orchestration/helpers/gate-check.sh +550 -46
- package/.claude/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +277 -0
- package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +238 -29
- package/.claude/skills/cfn-loop-orchestration/security_utils.sh +24 -0
- package/.claude/skills/cfn-loop-orchestration/test-iteration-context-injection.sh +366 -0
- package/.claude/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +319 -0
- package/.claude/skills/cfn-redis-coordination/agent-log.sh +4 -0
- package/.claude/skills/cfn-redis-coordination/agent-log.sh.bak +124 -0
- package/.claude/skills/cfn-redis-coordination/agent-recovery.sh +2 -2
- package/.claude/skills/cfn-redis-coordination/collect-confidence-scores.sh +30 -0
- package/.claude/skills/cfn-redis-coordination/get-context.sh +33 -0
- package/.claude/skills/cfn-redis-coordination/get-success-criteria.sh +54 -0
- package/.claude/skills/cfn-redis-coordination/invoke-waiting-mode.sh +6 -2
- package/.claude/skills/cfn-redis-coordination/redis-cli-wrapper.sh +24 -3
- package/.claude/skills/cfn-redis-coordination/redis-functions.sh +34 -0
- package/.claude/skills/cfn-redis-coordination/report-completion.sh +24 -31
- package/.claude/skills/cfn-redis-coordination/store-context.sh +4 -0
- package/.claude/skills/cfn-redis-coordination/store-success-criteria.sh +85 -0
- package/.claude/skills/cfn-redis-coordination/update-all-scripts.sh +67 -0
- package/.claude/skills/cfn-sqlite-memory/ttl-cleanup.sh +17 -25
- package/.claude/skills/cfn-transparency-middleware/test-e2e.sh +15 -0
- package/.claude/skills/cfn-transparency-middleware/tests/input-validation.sh +15 -0
- package/README.md +116 -475
- package/claude-assets/agents/cfn-dev-team/README.md +103 -0
- package/claude-assets/agents/cfn-dev-team/architecture/goal-planner.md +1 -1
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-frontend-coordinator.md +77 -15
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +355 -6
- package/claude-assets/agents/cfn-dev-team/coordinators/consensus-builder.md +82 -1
- package/claude-assets/agents/cfn-dev-team/coordinators/handoff-coordinator.md +82 -1
- package/claude-assets/agents/cfn-dev-team/coordinators/multi-sprint-coordinator.md +77 -15
- package/claude-assets/agents/cfn-dev-team/dev-ops/docker-specialist.md +99 -12
- package/claude-assets/agents/cfn-dev-team/dev-ops/github-commit-agent.md +1 -1
- package/claude-assets/agents/cfn-dev-team/dev-ops/kubernetes-specialist.md +97 -0
- package/claude-assets/agents/cfn-dev-team/dev-ops/monitoring-specialist.md +20 -1
- package/claude-assets/agents/cfn-dev-team/developers/api-gateway-specialist.md +97 -0
- package/claude-assets/agents/cfn-dev-team/developers/backend-developer.md +110 -13
- package/claude-assets/agents/cfn-dev-team/developers/data/data-engineer.md +106 -15
- package/claude-assets/agents/cfn-dev-team/developers/database/database-architect.md +115 -11
- package/claude-assets/agents/cfn-dev-team/developers/frontend/mobile-dev.md +94 -7
- package/claude-assets/agents/cfn-dev-team/developers/frontend/react-frontend-engineer.md +87 -9
- package/claude-assets/agents/cfn-dev-team/developers/frontend/typescript-specialist.md +85 -7
- package/claude-assets/agents/cfn-dev-team/developers/frontend/ui-designer.md +160 -28
- package/claude-assets/agents/cfn-dev-team/developers/graphql-specialist.md +101 -19
- package/claude-assets/agents/cfn-dev-team/developers/rust-developer.md +108 -14
- package/claude-assets/agents/cfn-dev-team/reviewers/{reviewer.md → code-reviewer.md} +95 -8
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/code-quality-validator.md +107 -7
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/perf-analyzer.md +98 -7
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/performance-benchmarker.md +95 -7
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/security-specialist.md +136 -9
- package/claude-assets/agents/cfn-dev-team/testers/api-testing-specialist.md +108 -1
- package/claude-assets/agents/cfn-dev-team/testers/chaos-engineering-specialist.md +107 -13
- package/claude-assets/agents/cfn-dev-team/testers/contract-tester.md +737 -0
- package/claude-assets/agents/cfn-dev-team/testers/e2e/playwright-tester.md +1 -1
- package/claude-assets/agents/cfn-dev-team/testers/integration-tester.md +828 -0
- package/claude-assets/agents/cfn-dev-team/testers/interaction-tester.md +106 -7
- package/claude-assets/agents/cfn-dev-team/testers/load-testing-specialist.md +77 -0
- package/claude-assets/agents/cfn-dev-team/testers/mutation-testing-specialist.md +684 -0
- package/claude-assets/agents/cfn-dev-team/testers/playwright-tester.md +110 -1
- package/claude-assets/agents/cfn-dev-team/testers/tester.md +94 -7
- package/claude-assets/agents/cfn-dev-team/utility/code-booster.md +1 -3
- package/claude-assets/agents/cfn-dev-team/utility/epic-creator.md +87 -13
- package/claude-assets/agents/cfn-dev-team/utility/memory-leak-specialist.md +103 -7
- package/claude-assets/agents/cfn-dev-team/utility/researcher.md +1 -3
- package/claude-assets/agents/cfn-dev-team/utility/z-ai-specialist.md +94 -7
- package/claude-assets/agents/docker-coordinators/cfn-docker-v3-coordinator.md +46 -0
- package/claude-assets/agents/project-only-agents/npm-package-specialist.md +1 -1
- package/claude-assets/cfn-extras/skills/advanced-features/cfn-agent-swap/recommend-swap.sh +59 -59
- package/claude-assets/cfn-extras/skills/analytics/cfn-improvement-recommender/recommend-improvements.sh +91 -91
- package/claude-assets/cfn-extras/skills/analytics/cfn-pattern-extraction/extract-patterns.sh +79 -79
- package/claude-assets/cfn-extras/skills/analytics/cfn-retrospective-report/generate-report.sh +100 -100
- package/claude-assets/cfn-extras/skills/analytics/cfn-telemetry/start-telemetry.sh +110 -110
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/add-bullet.sh +145 -145
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/log-merge.sh +67 -67
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/monitor-injection-performance.sh +137 -137
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/optimize-injection-pipeline.sh +168 -168
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/query-reflections.sh +35 -35
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/store-reflection.sh +45 -45
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/track-ab-test.sh +41 -41
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/update-reflection.sh +41 -41
- package/claude-assets/cfn-extras/skills/deprecated/cfn-cli-setup/validate-cli-environment.sh +191 -191
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/create-campaign.sh +231 -231
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/get-campaign-performance.sh +190 -190
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/pause-campaign.sh +142 -142
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/set-budget.sh +181 -181
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/update-bid-strategy.sh +133 -133
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/get-conversation-history.sh +121 -121
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/qualify-lead.sh +156 -156
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/schedule-demo.sh +181 -181
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/send-message.sh +137 -137
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/transfer-to-human.sh +179 -179
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/create-campaign.sh +183 -183
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/get-delivery-status.sh +139 -139
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/opt-out.sh +150 -150
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/schedule-campaign.sh +187 -187
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/send-sms.sh +181 -181
- package/claude-assets/cfn-extras/skills/ui-portal/cfn-web-portal/test-web-portal-skill.sh +50 -50
- package/claude-assets/cfn-extras/skills/ui-portal/cfn-web-portal/validate-deployment.sh +84 -84
- package/claude-assets/cfn-extras/skills/utility/cfn-environment-sanitization/sanitize-environment.sh +243 -243
- package/claude-assets/commands/cfn-loop-cli.md +29 -6
- package/claude-assets/commands/switch-api.md +31 -10
- package/claude-assets/hooks/cfn-lint-sql-injection.sh +61 -0
- package/claude-assets/hooks/cfn-post-edit-cfn-retrospective.sh +33 -2
- package/claude-assets/hooks/cfn-pre-edit-security-warning.sh +40 -0
- package/claude-assets/hooks/detect-hardcoded-credentials.sh +212 -0
- package/claude-assets/skills/SKILL_TEMPLATE.md +774 -0
- package/claude-assets/skills/agent-lifecycle/execute-lifecycle-hook.sh +84 -113
- package/claude-assets/skills/agent-lifecycle/simple-audit.sh +33 -6
- package/claude-assets/skills/agent-template-generator/SKILL.md +440 -0
- package/claude-assets/skills/agent-template-generator/generate-agent.sh +405 -0
- package/claude-assets/skills/agent-validation-linter/SKILL.md +589 -0
- package/claude-assets/skills/agent-validation-linter/lint-agents.sh +271 -0
- package/claude-assets/skills/bootstrap/bash-fundamentals.md +786 -0
- package/claude-assets/skills/bootstrap/database-connection.md +464 -0
- package/claude-assets/skills/bootstrap/error-handling.md +580 -0
- package/claude-assets/skills/bootstrap/file-operations.md +699 -0
- package/claude-assets/skills/bootstrap/skill-loader.md +616 -0
- package/claude-assets/skills/bootstrap/sqlite-params.sh +287 -0
- package/claude-assets/skills/cfn-agent-spawning/spawn-agent.sh +22 -24
- package/claude-assets/skills/cfn-automatic-memory-persistence/test-memory-persistence.sh +17 -16
- package/claude-assets/skills/cfn-deployment/SKILL.md +293 -0
- package/claude-assets/skills/cfn-deployment/execute.sh +21 -0
- package/claude-assets/skills/cfn-docker-agent-spawning/SKILL.md +28 -4
- package/claude-assets/skills/cfn-docker-agent-spawning/spawn-agent.sh +3 -1
- package/claude-assets/skills/cfn-docker-loop-orchestration/orchestrate.sh +224 -20
- package/claude-assets/skills/cfn-environment-sanitization/sanitize-environment.sh +38 -0
- package/claude-assets/skills/cfn-error-batching-strategy/lib/core-functions.sh +47 -47
- package/claude-assets/skills/cfn-file-operations/SKILL.md +290 -0
- package/claude-assets/skills/cfn-file-operations/execute.sh +129 -0
- package/claude-assets/skills/cfn-file-operations/lib/atomic-write.sh +294 -0
- package/claude-assets/skills/cfn-file-operations/lib/lock.sh +361 -0
- package/claude-assets/skills/cfn-file-operations/test.sh +369 -0
- package/claude-assets/skills/cfn-log-operations/SKILL.md +308 -0
- package/claude-assets/skills/cfn-log-operations/execute.sh +420 -0
- package/claude-assets/skills/cfn-log-operations/lib/rotate.sh +406 -0
- package/claude-assets/skills/cfn-log-operations/lib/search.sh +448 -0
- package/claude-assets/skills/cfn-log-operations/test.sh +394 -0
- package/claude-assets/skills/cfn-loop-orchestration/helpers/gate-check.sh +550 -46
- package/claude-assets/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +277 -0
- package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh +238 -29
- package/claude-assets/skills/cfn-loop-orchestration/security_utils.sh +24 -0
- package/claude-assets/skills/cfn-loop-orchestration/test-iteration-context-injection.sh +366 -0
- package/claude-assets/skills/cfn-parameterized-queries/SKILL.md +339 -0
- package/claude-assets/skills/cfn-playbook/query-playbook.sh +19 -15
- package/claude-assets/skills/cfn-playbook/update-playbook.sh +25 -14
- package/claude-assets/skills/cfn-process-instrumentation/instrument-process.sh +44 -0
- package/claude-assets/skills/cfn-promotion/SKILL.md +305 -0
- package/claude-assets/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +319 -0
- package/claude-assets/skills/cfn-redis-coordination/agent-log.sh +4 -0
- package/claude-assets/skills/cfn-redis-coordination/agent-log.sh.bak +124 -0
- package/claude-assets/skills/cfn-redis-coordination/agent-recovery.sh +2 -2
- package/claude-assets/skills/cfn-redis-coordination/collect-confidence-scores.sh +30 -0
- package/claude-assets/skills/cfn-redis-coordination/get-context.sh +33 -0
- package/claude-assets/skills/cfn-redis-coordination/get-success-criteria.sh +54 -0
- package/claude-assets/skills/cfn-redis-coordination/invoke-waiting-mode.sh +6 -2
- package/claude-assets/skills/cfn-redis-coordination/redis-cli-wrapper.sh +24 -3
- package/claude-assets/skills/cfn-redis-coordination/redis-functions.sh +34 -0
- package/claude-assets/skills/cfn-redis-coordination/report-completion.sh +24 -31
- package/claude-assets/skills/cfn-redis-coordination/store-context.sh +4 -0
- package/claude-assets/skills/cfn-redis-coordination/store-success-criteria.sh +85 -0
- package/claude-assets/skills/cfn-redis-coordination/update-all-scripts.sh +67 -0
- package/claude-assets/skills/cfn-skill-loader/SKILL.md +466 -0
- package/claude-assets/skills/cfn-skill-loader/execute.sh +344 -0
- package/claude-assets/skills/cfn-sqlite-memory/ttl-cleanup.sh +17 -25
- package/claude-assets/skills/cfn-task-audit/get-audit-data.sh +42 -21
- package/claude-assets/skills/cfn-task-audit/store-task-audit.sh +17 -10
- package/claude-assets/skills/cfn-test-runner/detect-regressions.sh +17 -14
- package/claude-assets/skills/cfn-test-runner/detect-regressions.sh.backup-1763392821 +55 -0
- package/claude-assets/skills/cfn-test-runner/store-benchmarks.sh +17 -19
- package/claude-assets/skills/cfn-transparency-middleware/test-e2e.sh +15 -0
- package/claude-assets/skills/cfn-transparency-middleware/tests/input-validation.sh +15 -0
- package/claude-assets/skills/cfn-utilities/SKILL.md +237 -0
- package/claude-assets/skills/cfn-utilities/execute.sh +32 -0
- package/claude-assets/skills/cfn-utilities/lib/errors.sh +56 -0
- package/claude-assets/skills/cfn-utilities/lib/file-ops.sh +164 -0
- package/claude-assets/skills/cfn-utilities/lib/logging.sh +77 -0
- package/claude-assets/skills/cfn-utilities/lib/retry.sh +127 -0
- package/claude-assets/skills/cfn-utilities/test.sh +317 -0
- package/claude-assets/skills/integration/agent-handoff.sh +62 -64
- package/claude-assets/skills/json-validation/SKILL.md +431 -0
- package/claude-assets/skills/json-validation/test-validate-success-criteria.sh +421 -0
- package/claude-assets/skills/json-validation/validate-success-criteria.sh +197 -0
- package/claude-assets/skills/redis-coordination/validate-parameters.sh +34 -0
- package/claude-assets/skills/workflow-codification/DEPLOY_QUICK_REFERENCE.md +106 -0
- package/claude-assets/skills/workflow-codification/PROPAGATE_UPDATE_QUICK_REFERENCE.md +366 -0
- package/claude-assets/skills/workflow-codification/deploy-approved-skill.sh +481 -0
- package/claude-assets/skills/workflow-codification/deploy-approved-skill.sh.backup-1763392820 +512 -0
- package/claude-assets/skills/workflow-codification/lib/security-utils.sh +204 -0
- package/claude-assets/skills/workflow-codification/propagate-skill-update.sh +648 -0
- package/claude-assets/skills/workflow-codification/propagate-skill-update.sh.backup-1763392820 +664 -0
- package/claude-assets/skills/workflow-codification/test-integration.sh +15 -0
- package/claude-assets/skills/workflow-codification/test-metadata-update.sh +350 -0
- package/claude-assets/skills/workflow-codification/track-cost-savings.sh +55 -14
- package/claude-assets/skills/workflow-codification/track-cost-savings.sh.backup-1763392821 +445 -0
- package/claude-assets/skills/workflow-codification/track-edge-case.sh +27 -60
- package/claude-assets/skills/workflow-codification/workflow-codification.db +0 -0
- package/dist/ace/ace-curator.js +10 -2
- package/dist/ace/ace-curator.js.map +1 -1
- package/dist/ace/ace-generator.js +4 -0
- package/dist/ace/ace-generator.js.map +1 -1
- package/dist/ace/ace-reflector.js +1 -1
- package/dist/ace/ace-reflector.js.map +1 -1
- package/dist/ace/context-injection.js +24 -2
- package/dist/ace/context-injection.js.map +1 -1
- package/dist/agents/task-agent-integration.js +1 -1
- package/dist/agents/task-agent-integration.js.map +1 -1
- package/dist/api/health-endpoints.js +390 -0
- package/dist/api/health-endpoints.js.map +1 -0
- package/dist/cli/agent-executor.js +4 -1
- package/dist/cli/agent-executor.js.map +1 -1
- package/dist/cli/agent-prompt-builder.js +89 -1
- package/dist/cli/agent-prompt-builder.js.map +1 -1
- package/dist/cli/agent-spawn.js +130 -37
- package/dist/cli/agent-spawn.js.map +1 -1
- package/dist/cli/config-manager.js +109 -91
- package/dist/cli/config-manager.js.map +1 -1
- package/dist/cli/conversation-fork-cleanup.js +201 -0
- package/dist/cli/conversation-fork-cleanup.js.map +1 -0
- package/dist/cli/conversation-fork.js +16 -3
- package/dist/cli/conversation-fork.js.map +1 -1
- package/dist/cli/skill-cache-validator.js +412 -0
- package/dist/cli/skill-cache-validator.js.map +1 -0
- package/dist/cli/skill-cli.js +991 -0
- package/dist/cli/skill-cli.js.map +1 -0
- package/dist/cli/skill-execution-logger.js +284 -0
- package/dist/cli/skill-execution-logger.js.map +1 -0
- package/dist/cli/skill-loader.js +457 -0
- package/dist/cli/skill-loader.js.map +1 -0
- package/dist/coordination/event-bus.js +2 -2
- package/dist/coordination/event-bus.js.map +1 -1
- package/dist/coordination/fleet-manager.js +1 -1
- package/dist/coordination/fleet-manager.js.map +1 -1
- package/dist/coordination/index.js +23 -9
- package/dist/coordination/index.js.map +1 -1
- package/dist/coordination/types/fleet-manager.types.js.map +1 -1
- package/dist/db/migration-manager.js +483 -0
- package/dist/db/migration-manager.js.map +1 -0
- package/dist/db/skills-query.js +535 -0
- package/dist/db/skills-query.js.map +1 -0
- package/dist/integration/DatabaseHandoff.js +1 -1
- package/dist/integration/DatabaseHandoff.js.map +1 -1
- package/dist/jobs/edge-case-analyzer.js +367 -0
- package/dist/jobs/edge-case-analyzer.js.map +1 -0
- package/dist/jobs/promotion-sla-enforcer.js +288 -0
- package/dist/jobs/promotion-sla-enforcer.js.map +1 -0
- package/dist/lib/agent-output-parser.js.map +1 -1
- package/dist/lib/agent-output-validator.js.map +1 -1
- package/dist/lib/agent-workspace.js +281 -0
- package/dist/lib/agent-workspace.js.map +1 -0
- package/dist/lib/atomic-file-writer.js +377 -0
- package/dist/lib/atomic-file-writer.js.map +1 -0
- package/dist/lib/backup-manager.js +779 -0
- package/dist/lib/backup-manager.js.map +1 -0
- package/dist/lib/checkpoint-manager.js +837 -0
- package/dist/lib/checkpoint-manager.js.map +1 -0
- package/dist/lib/circuit-breaker.js +340 -0
- package/dist/lib/circuit-breaker.js.map +1 -0
- package/dist/lib/completion-signal-handler.js +243 -0
- package/dist/lib/completion-signal-handler.js.map +1 -0
- package/dist/lib/config-manager.js +312 -0
- package/dist/lib/config-manager.js.map +1 -0
- package/dist/lib/config-migrator.js +386 -0
- package/dist/lib/config-migrator.js.map +1 -0
- package/dist/lib/config-validator.js.map +1 -1
- package/dist/lib/correlation-cache.js +311 -0
- package/dist/lib/correlation-cache.js.map +1 -0
- package/dist/lib/correlation.js +263 -0
- package/dist/lib/correlation.js.map +1 -0
- package/dist/lib/database-service/connection-pool-manager.js +520 -0
- package/dist/lib/database-service/connection-pool-manager.js.map +1 -0
- package/dist/lib/database-service/correlation.js +329 -0
- package/dist/lib/database-service/correlation.js.map +1 -0
- package/dist/lib/database-service/errors.js +120 -0
- package/dist/lib/database-service/errors.js.map +1 -0
- package/dist/lib/database-service/index.js +168 -0
- package/dist/lib/database-service/index.js.map +1 -0
- package/dist/lib/database-service/postgres-adapter.js +526 -0
- package/dist/lib/database-service/postgres-adapter.js.map +1 -0
- package/dist/lib/database-service/redis-adapter.js +360 -0
- package/dist/lib/database-service/redis-adapter.js.map +1 -0
- package/dist/lib/database-service/sqlite-adapter.js +544 -0
- package/dist/lib/database-service/sqlite-adapter.js.map +1 -0
- package/dist/lib/database-service/transaction-manager.js +773 -0
- package/dist/lib/database-service/transaction-manager.js.map +1 -0
- package/dist/lib/database-service/types.js +23 -0
- package/dist/lib/database-service/types.js.map +1 -0
- package/dist/lib/deadlock-resolver.js +292 -0
- package/dist/lib/deadlock-resolver.js.map +1 -0
- package/dist/lib/distributed-lock.js +451 -0
- package/dist/lib/distributed-lock.js.map +1 -0
- package/dist/lib/edge-case-deduplicator.js +227 -0
- package/dist/lib/edge-case-deduplicator.js.map +1 -0
- package/dist/lib/encryption-manager.js +322 -0
- package/dist/lib/encryption-manager.js.map +1 -0
- package/dist/lib/error-aggregator.js +234 -0
- package/dist/lib/error-aggregator.js.map +1 -0
- package/dist/lib/errors.js +287 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/file-lock-manager.js +578 -0
- package/dist/lib/file-lock-manager.js.map +1 -0
- package/dist/lib/file-operations.js +367 -0
- package/dist/lib/file-operations.js.map +1 -0
- package/dist/lib/idempotent-write.js +237 -0
- package/dist/lib/idempotent-write.js.map +1 -0
- package/dist/lib/integration-schema-validator.js +522 -0
- package/dist/lib/integration-schema-validator.js.map +1 -0
- package/dist/lib/lock-health-monitor.js +298 -0
- package/dist/lib/lock-health-monitor.js.map +1 -0
- package/dist/lib/log-shipper.js +422 -0
- package/dist/lib/log-shipper.js.map +1 -0
- package/dist/lib/logging.js +146 -0
- package/dist/lib/logging.js.map +1 -0
- package/dist/lib/message-deduplicator.js +439 -0
- package/dist/lib/message-deduplicator.js.map +1 -0
- package/dist/lib/multi-system-query.js +604 -0
- package/dist/lib/multi-system-query.js.map +1 -0
- package/dist/lib/orphan-detector.js +332 -0
- package/dist/lib/orphan-detector.js.map +1 -0
- package/dist/lib/password-generator.js +166 -0
- package/dist/lib/password-generator.js.map +1 -0
- package/dist/lib/path-validator.js +429 -0
- package/dist/lib/path-validator.js.map +1 -0
- package/dist/lib/query-translator.js +905 -0
- package/dist/lib/query-translator.js.map +1 -0
- package/dist/lib/queue-recovery.js +469 -0
- package/dist/lib/queue-recovery.js.map +1 -0
- package/dist/lib/redis-queue-manager.js +512 -0
- package/dist/lib/redis-queue-manager.js.map +1 -0
- package/dist/lib/reflection-archiver.js +272 -0
- package/dist/lib/reflection-archiver.js.map +1 -0
- package/dist/lib/retry-manager.js +453 -0
- package/dist/lib/retry-manager.js.map +1 -0
- package/dist/lib/retry.js +262 -0
- package/dist/lib/retry.js.map +1 -0
- package/dist/lib/schema-transform.js +695 -0
- package/dist/lib/schema-transform.js.map +1 -0
- package/dist/lib/schema-validator.js +491 -0
- package/dist/lib/schema-validator.js.map +1 -0
- package/dist/lib/skill-cache.js +297 -0
- package/dist/lib/skill-cache.js.map +1 -0
- package/dist/lib/skill-content-manager.js +337 -0
- package/dist/lib/skill-content-manager.js.map +1 -0
- package/dist/lib/skill-frontmatter-parser.js +237 -0
- package/dist/lib/skill-frontmatter-parser.js.map +1 -0
- package/dist/lib/skill-git-integration.js +275 -0
- package/dist/lib/skill-git-integration.js.map +1 -0
- package/dist/lib/skill-markdown-validator.js +396 -0
- package/dist/lib/skill-markdown-validator.js.map +1 -0
- package/dist/lib/skill-output-parser.js +312 -0
- package/dist/lib/skill-output-parser.js.map +1 -0
- package/dist/lib/unified-query-api.js +467 -0
- package/dist/lib/unified-query-api.js.map +1 -0
- package/dist/middleware/auth-middleware.js +350 -0
- package/dist/middleware/auth-middleware.js.map +1 -0
- package/dist/middleware/schema-validation.js +347 -0
- package/dist/middleware/schema-validation.js.map +1 -0
- package/dist/providers/anthropic-provider.js +1 -1
- package/dist/providers/anthropic-provider.js.map +1 -1
- package/dist/providers/provider-factory.js +2 -2
- package/dist/providers/provider-factory.js.map +1 -1
- package/dist/services/edge-case-analyzer.js +321 -0
- package/dist/services/edge-case-analyzer.js.map +1 -0
- package/dist/services/edge-case-deduplicator.js +266 -0
- package/dist/services/edge-case-deduplicator.js.map +1 -0
- package/dist/services/edge-case-detector.js +337 -0
- package/dist/services/edge-case-detector.js.map +1 -0
- package/dist/services/edge-case-tracker.js +547 -0
- package/dist/services/edge-case-tracker.js.map +1 -0
- package/dist/services/health-check-system.js +586 -0
- package/dist/services/health-check-system.js.map +1 -0
- package/dist/services/metrics-logger.js +412 -0
- package/dist/services/metrics-logger.js.map +1 -0
- package/dist/services/patch-generator.js +378 -0
- package/dist/services/patch-generator.js.map +1 -0
- package/dist/services/patch-validator.js +337 -0
- package/dist/services/patch-validator.js.map +1 -0
- package/dist/services/performance-monitor.js +811 -0
- package/dist/services/performance-monitor.js.map +1 -0
- package/dist/services/promotion-pipeline.js +918 -0
- package/dist/services/promotion-pipeline.js.map +1 -0
- package/dist/services/promotion-validator.js +394 -0
- package/dist/services/promotion-validator.js.map +1 -0
- package/dist/services/reflection-logger.js +388 -0
- package/dist/services/reflection-logger.js.map +1 -0
- package/dist/services/skill-deployment.js +472 -0
- package/dist/services/skill-deployment.js.map +1 -0
- package/dist/services/skill-loader.js +427 -0
- package/dist/services/skill-loader.js.map +1 -0
- package/dist/services/skill-promotion.js +372 -0
- package/dist/services/skill-promotion.js.map +1 -0
- package/dist/services/skill-validator.js +454 -0
- package/dist/services/skill-validator.js.map +1 -0
- package/dist/services/skill-versioning.js +244 -0
- package/dist/services/skill-versioning.js.map +1 -0
- package/dist/services/workspace-supervisor.js +597 -0
- package/dist/services/workspace-supervisor.js.map +1 -0
- package/dist/types/edge-case.js +45 -0
- package/dist/types/edge-case.js.map +1 -0
- package/docs/BUG_19_MEMORY_LEAK_TASK_MODE.md +405 -0
- package/docs/MEMORY_CLEANUP_GUIDE.md +358 -0
- package/docs/MEMORY_LEAK_FIX_SUMMARY.md +322 -0
- package/docs/REDIS_CLEANUP_EXECUTIVE_SUMMARY.md +319 -0
- package/docs/REDIS_CLEANUP_VERIFICATION_REPORT.md +574 -0
- package/package.json +35 -4
- package/readme/README.md +53 -5
- package/scripts/backup-cleanup.sh +627 -0
- package/scripts/cleanup-workspaces.sh +412 -0
- package/scripts/cleanup-yaml-configs.sh +141 -0
- package/scripts/deploy-approved-skills.sh +263 -0
- package/scripts/health-check.sh +447 -0
- package/scripts/log-aggregator.sh +554 -0
- package/scripts/log-monitor.sh +629 -0
- package/scripts/manage-agent-workspaces.sh +434 -0
- package/scripts/migrate-schema.sh +533 -0
- package/scripts/promote-staged-skills.sh +423 -0
- package/scripts/verify-no-secrets.sh +88 -35
- package/scripts/verify-redis-cleanup.sh +173 -0
- package/tests/README.md +84 -0
- package/tests/test-memory-leak-task-mode.sh +435 -0
- package/.claude/cfn-extras/agents/deprecated-coordinators/adaptive-coordinator.md.backup +0 -161
- package/.claude/cfn-extras/agents/deprecated-coordinators/blocking-coordinator-example.md.backup +0 -728
- package/.claude/cfn-extras/agents/deprecated-coordinators/mesh-coordinator.md.backup +0 -131
- package/.claude/skills/agent-lifecycle/SKILL.md +0 -60
- package/.claude/skills/agent-lifecycle/execute-lifecycle-hook.sh +0 -573
- package/.claude/skills/agent-lifecycle/simple-audit.sh +0 -31
- package/.claude/skills/cfn-agent-spawning/spawn-agent.sh.backup +0 -273
- package/.claude/skills/cfn-loop-orchestration/orchestrate.sh.backup +0 -949
- package/README.md.backup_before_replace +0 -781
- package/claude-assets/cfn-extras/agents/deprecated-coordinators/adaptive-coordinator.md.backup +0 -161
- package/claude-assets/cfn-extras/agents/deprecated-coordinators/blocking-coordinator-example.md.backup +0 -728
- package/claude-assets/cfn-extras/agents/deprecated-coordinators/mesh-coordinator.md.backup +0 -131
- package/claude-assets/skills/cfn-agent-spawning/spawn-agent.sh.backup +0 -273
- package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh.backup +0 -949
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Connection Pool Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages connection pools for database adapters with:
|
|
5
|
+
* - Automatic initialization on service startup
|
|
6
|
+
* - Connection health checks (ping every 30s)
|
|
7
|
+
* - Automatic reconnection with exponential backoff
|
|
8
|
+
* - Connection metrics (active, idle, pending)
|
|
9
|
+
* - Graceful degradation on connection failures
|
|
10
|
+
*
|
|
11
|
+
* Part of Bug Fix: Connection Pool Initialization
|
|
12
|
+
*/ import sqlite3 from 'sqlite3';
|
|
13
|
+
import { open } from 'sqlite';
|
|
14
|
+
import { createClient } from 'redis';
|
|
15
|
+
import { Pool } from 'pg';
|
|
16
|
+
import { DatabaseErrorCode } from './types.js';
|
|
17
|
+
import { createDatabaseError } from './errors.js';
|
|
18
|
+
/**
|
|
19
|
+
* Connection Pool Manager
|
|
20
|
+
*
|
|
21
|
+
* Manages connection lifecycle, health checks, and automatic recovery
|
|
22
|
+
*/ export class ConnectionPoolManager {
|
|
23
|
+
config;
|
|
24
|
+
options;
|
|
25
|
+
pool = null;
|
|
26
|
+
connections = new Set();
|
|
27
|
+
activeConnections = new Set();
|
|
28
|
+
pendingRequests = [];
|
|
29
|
+
healthCheckInterval;
|
|
30
|
+
lastHealthCheck;
|
|
31
|
+
healthCheckActive = false;
|
|
32
|
+
reconnectAttempts = 0;
|
|
33
|
+
maxReconnectAttempts = 10;
|
|
34
|
+
failedAttempts = 0;
|
|
35
|
+
startTime;
|
|
36
|
+
isShuttingDown = false;
|
|
37
|
+
cacheFallbackEnabled = false;
|
|
38
|
+
cache = new Map();
|
|
39
|
+
constructor(config, options = {}){
|
|
40
|
+
this.config = config;
|
|
41
|
+
this.options = {
|
|
42
|
+
minConnections: options.minConnections ?? 2,
|
|
43
|
+
maxConnections: options.maxConnections ?? config.poolSize ?? 10,
|
|
44
|
+
acquireTimeout: options.acquireTimeout ?? config.timeout ?? 5000,
|
|
45
|
+
idleTimeout: options.idleTimeout ?? 30000,
|
|
46
|
+
healthCheckInterval: options.healthCheckInterval ?? 30000,
|
|
47
|
+
maxReconnectAttempts: options.maxReconnectAttempts ?? 10,
|
|
48
|
+
reconnectBaseDelay: options.reconnectBaseDelay ?? 1000
|
|
49
|
+
};
|
|
50
|
+
this.maxReconnectAttempts = this.options.maxReconnectAttempts;
|
|
51
|
+
this.startTime = new Date();
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Initialize connection pool
|
|
55
|
+
*/ async initialize() {
|
|
56
|
+
try {
|
|
57
|
+
switch(this.config.type){
|
|
58
|
+
case 'sqlite':
|
|
59
|
+
await this.initializeSQLitePool();
|
|
60
|
+
break;
|
|
61
|
+
case 'redis':
|
|
62
|
+
await this.initializeRedisPool();
|
|
63
|
+
break;
|
|
64
|
+
case 'postgres':
|
|
65
|
+
await this.initializePostgresPool();
|
|
66
|
+
break;
|
|
67
|
+
default:
|
|
68
|
+
throw new Error(`Unsupported database type: ${this.config.type}`);
|
|
69
|
+
}
|
|
70
|
+
// Initialize minimum connections
|
|
71
|
+
await this.warmUpPool();
|
|
72
|
+
} catch (err) {
|
|
73
|
+
this.failedAttempts++;
|
|
74
|
+
throw createDatabaseError(DatabaseErrorCode.CONNECTION_FAILED, `Failed to initialize ${this.config.type} connection pool`, err instanceof Error ? err : new Error(String(err)), {
|
|
75
|
+
config: this.config
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Initialize SQLite connection pool
|
|
81
|
+
*/ async initializeSQLitePool() {
|
|
82
|
+
const dbPath = this.config.database || this.config.connectionString || ':memory:';
|
|
83
|
+
if (!dbPath || dbPath === '') {
|
|
84
|
+
throw new Error('SQLite database path is required');
|
|
85
|
+
}
|
|
86
|
+
// Create connection pool for SQLite
|
|
87
|
+
for(let i = 0; i < this.options.minConnections; i++){
|
|
88
|
+
const db = await open({
|
|
89
|
+
filename: dbPath,
|
|
90
|
+
driver: sqlite3.Database
|
|
91
|
+
});
|
|
92
|
+
await db.run('PRAGMA foreign_keys = ON');
|
|
93
|
+
await db.run(`PRAGMA busy_timeout = ${this.config.timeout || 5000}`);
|
|
94
|
+
this.connections.add(db);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Initialize Redis connection pool
|
|
99
|
+
*/ async initializeRedisPool() {
|
|
100
|
+
let url = this.config.connectionString;
|
|
101
|
+
if (!url) {
|
|
102
|
+
// Build connection string with optional authentication
|
|
103
|
+
const host = this.config.host || 'localhost';
|
|
104
|
+
const port = this.config.port || 6379;
|
|
105
|
+
if (this.config.password) {
|
|
106
|
+
// Include password in connection string: redis://:password@host:port
|
|
107
|
+
url = `redis://:${encodeURIComponent(this.config.password)}@${host}:${port}`;
|
|
108
|
+
} else {
|
|
109
|
+
url = `redis://${host}:${port}`;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
this.pool = createClient({
|
|
113
|
+
url,
|
|
114
|
+
socket: {
|
|
115
|
+
connectTimeout: this.config.timeout || 5000,
|
|
116
|
+
reconnectStrategy: (retries)=>{
|
|
117
|
+
if (retries > this.maxReconnectAttempts) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
// Exponential backoff
|
|
121
|
+
return Math.min(this.options.reconnectBaseDelay * Math.pow(2, retries), 30000);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
// Set up event handlers
|
|
126
|
+
this.pool.on('error', (err)=>{
|
|
127
|
+
console.error('Redis connection error:', err);
|
|
128
|
+
this.failedAttempts++;
|
|
129
|
+
});
|
|
130
|
+
this.pool.on('reconnecting', ()=>{
|
|
131
|
+
this.reconnectAttempts++;
|
|
132
|
+
});
|
|
133
|
+
await this.pool.connect();
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Initialize PostgreSQL connection pool
|
|
137
|
+
*/ async initializePostgresPool() {
|
|
138
|
+
const connectionString = this.config.connectionString || `postgresql://${this.config.username}:${this.config.password}@${this.config.host}:${this.config.port}/${this.config.database}`;
|
|
139
|
+
this.pool = new Pool({
|
|
140
|
+
connectionString,
|
|
141
|
+
min: this.options.minConnections,
|
|
142
|
+
max: this.options.maxConnections,
|
|
143
|
+
idleTimeoutMillis: this.options.idleTimeout,
|
|
144
|
+
connectionTimeoutMillis: this.options.acquireTimeout
|
|
145
|
+
});
|
|
146
|
+
// Test connection
|
|
147
|
+
const client = await this.pool.connect();
|
|
148
|
+
await client.query('SELECT 1');
|
|
149
|
+
client.release();
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Warm up pool by creating minimum connections
|
|
153
|
+
*/ async warmUpPool() {
|
|
154
|
+
if (this.config.type === 'sqlite') {
|
|
155
|
+
// SQLite connections already created in initializeSQLitePool
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
// For Redis and Postgres, connections are managed by their libraries
|
|
159
|
+
// We just need to verify connectivity
|
|
160
|
+
if (this.config.type === 'redis') {
|
|
161
|
+
await this.pool.ping();
|
|
162
|
+
} else if (this.config.type === 'postgres') {
|
|
163
|
+
const client = await this.pool.connect();
|
|
164
|
+
await client.query('SELECT 1');
|
|
165
|
+
client.release();
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Acquire connection from pool
|
|
170
|
+
*/ async acquire() {
|
|
171
|
+
if (this.isShuttingDown) {
|
|
172
|
+
throw createDatabaseError(DatabaseErrorCode.CONNECTION_FAILED, 'Connection pool is shutting down', undefined, {
|
|
173
|
+
type: this.config.type
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
const startTime = Date.now();
|
|
177
|
+
try {
|
|
178
|
+
switch(this.config.type){
|
|
179
|
+
case 'sqlite':
|
|
180
|
+
return await this.acquireSQLiteConnection(startTime);
|
|
181
|
+
case 'redis':
|
|
182
|
+
return this.pool;
|
|
183
|
+
case 'postgres':
|
|
184
|
+
return await this.pool.connect();
|
|
185
|
+
default:
|
|
186
|
+
throw new Error(`Unsupported database type: ${this.config.type}`);
|
|
187
|
+
}
|
|
188
|
+
} catch (err) {
|
|
189
|
+
throw createDatabaseError(DatabaseErrorCode.CONNECTION_FAILED, 'Failed to acquire connection', err instanceof Error ? err : new Error(String(err)), {
|
|
190
|
+
type: this.config.type
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Acquire SQLite connection from pool
|
|
196
|
+
*/ async acquireSQLiteConnection(startTime) {
|
|
197
|
+
// Check for available connection
|
|
198
|
+
const availableConnection = Array.from(this.connections).find((conn)=>!this.activeConnections.has(conn));
|
|
199
|
+
if (availableConnection) {
|
|
200
|
+
this.activeConnections.add(availableConnection);
|
|
201
|
+
return availableConnection;
|
|
202
|
+
}
|
|
203
|
+
// Check if we can create more connections
|
|
204
|
+
if (this.connections.size < this.options.maxConnections) {
|
|
205
|
+
const newConnection = await this.createSQLiteConnection();
|
|
206
|
+
this.connections.add(newConnection);
|
|
207
|
+
this.activeConnections.add(newConnection);
|
|
208
|
+
return newConnection;
|
|
209
|
+
}
|
|
210
|
+
// Queue request
|
|
211
|
+
return new Promise((resolve, reject)=>{
|
|
212
|
+
const timeoutId = setTimeout(()=>{
|
|
213
|
+
const index = this.pendingRequests.findIndex((req)=>req.resolve === resolve);
|
|
214
|
+
if (index !== -1) {
|
|
215
|
+
this.pendingRequests.splice(index, 1);
|
|
216
|
+
}
|
|
217
|
+
reject(createDatabaseError(DatabaseErrorCode.TIMEOUT, 'Connection acquisition timeout', undefined, {
|
|
218
|
+
timeout: this.options.acquireTimeout
|
|
219
|
+
}));
|
|
220
|
+
}, this.options.acquireTimeout);
|
|
221
|
+
this.pendingRequests.push({
|
|
222
|
+
resolve: (conn)=>{
|
|
223
|
+
clearTimeout(timeoutId);
|
|
224
|
+
resolve(conn);
|
|
225
|
+
},
|
|
226
|
+
reject: (err)=>{
|
|
227
|
+
clearTimeout(timeoutId);
|
|
228
|
+
reject(err);
|
|
229
|
+
},
|
|
230
|
+
timestamp: startTime
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Create new SQLite connection
|
|
236
|
+
*/ async createSQLiteConnection() {
|
|
237
|
+
const dbPath = this.config.database || this.config.connectionString || ':memory:';
|
|
238
|
+
const db = await open({
|
|
239
|
+
filename: dbPath,
|
|
240
|
+
driver: sqlite3.Database
|
|
241
|
+
});
|
|
242
|
+
await db.run('PRAGMA foreign_keys = ON');
|
|
243
|
+
await db.run(`PRAGMA busy_timeout = ${this.config.timeout || 5000}`);
|
|
244
|
+
return db;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Release connection back to pool
|
|
248
|
+
*/ async release(connection) {
|
|
249
|
+
if (!connection) {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
try {
|
|
253
|
+
switch(this.config.type){
|
|
254
|
+
case 'sqlite':
|
|
255
|
+
this.releaseSQLiteConnection(connection);
|
|
256
|
+
break;
|
|
257
|
+
case 'redis':
|
|
258
|
+
break;
|
|
259
|
+
case 'postgres':
|
|
260
|
+
if (connection && typeof connection.release === 'function') {
|
|
261
|
+
connection.release();
|
|
262
|
+
}
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
265
|
+
} catch (err) {
|
|
266
|
+
console.error('Failed to release connection:', err);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Release SQLite connection
|
|
271
|
+
*/ releaseSQLiteConnection(connection) {
|
|
272
|
+
this.activeConnections.delete(connection);
|
|
273
|
+
// Process pending requests
|
|
274
|
+
if (this.pendingRequests.length > 0) {
|
|
275
|
+
const pending = this.pendingRequests.shift();
|
|
276
|
+
if (pending) {
|
|
277
|
+
this.activeConnections.add(connection);
|
|
278
|
+
pending.resolve(connection);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Start periodic health checks
|
|
284
|
+
*/ startHealthChecks() {
|
|
285
|
+
if (this.healthCheckActive) {
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
this.healthCheckActive = true;
|
|
289
|
+
this.healthCheckInterval = setInterval(async ()=>{
|
|
290
|
+
try {
|
|
291
|
+
const healthy = await this.performHealthCheck();
|
|
292
|
+
this.lastHealthCheck = new Date();
|
|
293
|
+
if (!healthy) {
|
|
294
|
+
console.warn(`Health check failed for ${this.config.type} pool`);
|
|
295
|
+
await this.attemptReconnection();
|
|
296
|
+
}
|
|
297
|
+
} catch (err) {
|
|
298
|
+
console.error('Health check error:', err);
|
|
299
|
+
}
|
|
300
|
+
}, this.options.healthCheckInterval);
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Stop health checks
|
|
304
|
+
*/ stopHealthChecks() {
|
|
305
|
+
if (this.healthCheckInterval) {
|
|
306
|
+
clearInterval(this.healthCheckInterval);
|
|
307
|
+
this.healthCheckInterval = undefined;
|
|
308
|
+
}
|
|
309
|
+
this.healthCheckActive = false;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Perform health check
|
|
313
|
+
*/ async performHealthCheck() {
|
|
314
|
+
try {
|
|
315
|
+
switch(this.config.type){
|
|
316
|
+
case 'sqlite':
|
|
317
|
+
{
|
|
318
|
+
const connection = Array.from(this.connections)[0];
|
|
319
|
+
if (connection) {
|
|
320
|
+
await connection.get('SELECT 1');
|
|
321
|
+
return true;
|
|
322
|
+
}
|
|
323
|
+
return false;
|
|
324
|
+
}
|
|
325
|
+
case 'redis':
|
|
326
|
+
if (this.pool) {
|
|
327
|
+
await this.pool.ping();
|
|
328
|
+
return true;
|
|
329
|
+
}
|
|
330
|
+
return false;
|
|
331
|
+
case 'postgres':
|
|
332
|
+
if (this.pool) {
|
|
333
|
+
const client = await this.pool.connect();
|
|
334
|
+
await client.query('SELECT 1');
|
|
335
|
+
client.release();
|
|
336
|
+
return true;
|
|
337
|
+
}
|
|
338
|
+
return false;
|
|
339
|
+
default:
|
|
340
|
+
return false;
|
|
341
|
+
}
|
|
342
|
+
} catch (err) {
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Check if pool is healthy (exposed for testing)
|
|
348
|
+
*/ async isHealthy() {
|
|
349
|
+
return this.performHealthCheck();
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Attempt reconnection with exponential backoff
|
|
353
|
+
*/ async attemptReconnection() {
|
|
354
|
+
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
|
|
355
|
+
console.error(`Max reconnection attempts (${this.maxReconnectAttempts}) reached for ${this.config.type}`);
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
const delay = Math.min(this.options.reconnectBaseDelay * Math.pow(2, this.reconnectAttempts), 30000);
|
|
359
|
+
this.reconnectAttempts++;
|
|
360
|
+
await new Promise((resolve)=>setTimeout(resolve, delay));
|
|
361
|
+
try {
|
|
362
|
+
await this.initialize();
|
|
363
|
+
console.log(`Reconnection successful for ${this.config.type}`);
|
|
364
|
+
this.reconnectAttempts = 0;
|
|
365
|
+
} catch (err) {
|
|
366
|
+
console.error(`Reconnection failed for ${this.config.type}:`, err);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Get reconnection delays for testing
|
|
371
|
+
*/ getReconnectDelays() {
|
|
372
|
+
const delays = [];
|
|
373
|
+
for(let i = 0; i < 5; i++){
|
|
374
|
+
delays.push(Math.min(this.options.reconnectBaseDelay * Math.pow(2, i), 30000));
|
|
375
|
+
}
|
|
376
|
+
return delays;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Simulate disconnection (for testing)
|
|
380
|
+
*/ simulateDisconnection() {
|
|
381
|
+
if (this.config.type === 'redis' && this.pool) {
|
|
382
|
+
this.pool.disconnect();
|
|
383
|
+
} else if (this.config.type === 'postgres' && this.pool) {
|
|
384
|
+
this.pool.end();
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Remove unhealthy connections (for testing)
|
|
389
|
+
*/ removeUnhealthyConnections(count) {
|
|
390
|
+
if (this.config.type === 'sqlite') {
|
|
391
|
+
const connectionsToRemove = Array.from(this.connections).slice(0, count);
|
|
392
|
+
connectionsToRemove.forEach((conn)=>{
|
|
393
|
+
this.connections.delete(conn);
|
|
394
|
+
this.activeConnections.delete(conn);
|
|
395
|
+
conn.close();
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Enable cache fallback for graceful degradation
|
|
401
|
+
*/ enableCacheFallback(enabled) {
|
|
402
|
+
this.cacheFallbackEnabled = enabled;
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Get data with cache fallback
|
|
406
|
+
*/ async getWithFallback(key) {
|
|
407
|
+
try {
|
|
408
|
+
const connection = await this.acquire();
|
|
409
|
+
// Actual data retrieval would happen here
|
|
410
|
+
await this.release(connection);
|
|
411
|
+
return null;
|
|
412
|
+
} catch (err) {
|
|
413
|
+
if (this.cacheFallbackEnabled && this.cache.has(key)) {
|
|
414
|
+
console.warn(`Using cached data for key: ${key}`);
|
|
415
|
+
return this.cache.get(key);
|
|
416
|
+
}
|
|
417
|
+
throw err;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Get connection pool statistics
|
|
422
|
+
*/ getStats() {
|
|
423
|
+
const now = Date.now();
|
|
424
|
+
const uptime = now - this.startTime.getTime();
|
|
425
|
+
switch(this.config.type){
|
|
426
|
+
case 'sqlite':
|
|
427
|
+
return {
|
|
428
|
+
type: 'sqlite',
|
|
429
|
+
total: this.connections.size,
|
|
430
|
+
active: this.activeConnections.size,
|
|
431
|
+
idle: this.connections.size - this.activeConnections.size,
|
|
432
|
+
pending: this.pendingRequests.length,
|
|
433
|
+
maxConnections: this.options.maxConnections,
|
|
434
|
+
available: this.connections.size - this.activeConnections.size,
|
|
435
|
+
healthy: this.connections.size > 0,
|
|
436
|
+
lastHealthCheck: this.lastHealthCheck,
|
|
437
|
+
healthCheckActive: this.healthCheckActive,
|
|
438
|
+
reconnectAttempts: this.reconnectAttempts,
|
|
439
|
+
failedAttempts: this.failedAttempts,
|
|
440
|
+
uptime
|
|
441
|
+
};
|
|
442
|
+
case 'redis':
|
|
443
|
+
return {
|
|
444
|
+
type: 'redis',
|
|
445
|
+
total: this.pool ? 1 : 0,
|
|
446
|
+
active: this.pool?.isOpen ? 1 : 0,
|
|
447
|
+
idle: 0,
|
|
448
|
+
pending: 0,
|
|
449
|
+
maxConnections: 1,
|
|
450
|
+
available: this.pool?.isOpen ? 1 : 0,
|
|
451
|
+
healthy: this.pool?.isOpen ?? false,
|
|
452
|
+
lastHealthCheck: this.lastHealthCheck,
|
|
453
|
+
healthCheckActive: this.healthCheckActive,
|
|
454
|
+
reconnectAttempts: this.reconnectAttempts,
|
|
455
|
+
failedAttempts: this.failedAttempts,
|
|
456
|
+
uptime
|
|
457
|
+
};
|
|
458
|
+
case 'postgres':
|
|
459
|
+
return {
|
|
460
|
+
type: 'postgres',
|
|
461
|
+
total: this.pool?.totalCount ?? 0,
|
|
462
|
+
active: (this.pool?.totalCount ?? 0) - (this.pool?.idleCount ?? 0),
|
|
463
|
+
idle: this.pool?.idleCount ?? 0,
|
|
464
|
+
pending: this.pool?.waitingCount ?? 0,
|
|
465
|
+
maxConnections: this.options.maxConnections,
|
|
466
|
+
available: this.pool?.idleCount ?? 0,
|
|
467
|
+
healthy: this.pool !== null,
|
|
468
|
+
lastHealthCheck: this.lastHealthCheck,
|
|
469
|
+
healthCheckActive: this.healthCheckActive,
|
|
470
|
+
reconnectAttempts: this.reconnectAttempts,
|
|
471
|
+
failedAttempts: this.failedAttempts,
|
|
472
|
+
uptime
|
|
473
|
+
};
|
|
474
|
+
default:
|
|
475
|
+
throw new Error(`Unsupported database type: ${this.config.type}`);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Shutdown connection pool
|
|
480
|
+
*/ async shutdown() {
|
|
481
|
+
if (this.isShuttingDown) {
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
this.isShuttingDown = true;
|
|
485
|
+
this.stopHealthChecks();
|
|
486
|
+
// Reject all pending requests
|
|
487
|
+
this.pendingRequests.forEach((req)=>{
|
|
488
|
+
req.reject(createDatabaseError(DatabaseErrorCode.CONNECTION_FAILED, 'Connection pool is shutting down', undefined, {
|
|
489
|
+
type: this.config.type
|
|
490
|
+
}));
|
|
491
|
+
});
|
|
492
|
+
this.pendingRequests = [];
|
|
493
|
+
// Close all connections
|
|
494
|
+
try {
|
|
495
|
+
switch(this.config.type){
|
|
496
|
+
case 'sqlite':
|
|
497
|
+
await Promise.all(Array.from(this.connections).map((conn)=>conn.close()));
|
|
498
|
+
this.connections.clear();
|
|
499
|
+
this.activeConnections.clear();
|
|
500
|
+
break;
|
|
501
|
+
case 'redis':
|
|
502
|
+
if (this.pool) {
|
|
503
|
+
await this.pool.quit();
|
|
504
|
+
this.pool = null;
|
|
505
|
+
}
|
|
506
|
+
break;
|
|
507
|
+
case 'postgres':
|
|
508
|
+
if (this.pool) {
|
|
509
|
+
await this.pool.end();
|
|
510
|
+
this.pool = null;
|
|
511
|
+
}
|
|
512
|
+
break;
|
|
513
|
+
}
|
|
514
|
+
} catch (err) {
|
|
515
|
+
console.error('Error during shutdown:', err);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
//# sourceMappingURL=connection-pool-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/database-service/connection-pool-manager.ts"],"sourcesContent":["/**\r\n * Connection Pool Manager\r\n *\r\n * Manages connection pools for database adapters with:\r\n * - Automatic initialization on service startup\r\n * - Connection health checks (ping every 30s)\r\n * - Automatic reconnection with exponential backoff\r\n * - Connection metrics (active, idle, pending)\r\n * - Graceful degradation on connection failures\r\n *\r\n * Part of Bug Fix: Connection Pool Initialization\r\n */\r\n\r\nimport sqlite3 from 'sqlite3';\r\nimport { open, Database } from 'sqlite';\r\nimport { createClient, RedisClientType } from 'redis';\r\nimport { Pool, PoolClient } from 'pg';\r\nimport {\r\n DatabaseConfig,\r\n DatabaseErrorCode,\r\n} from './types.js';\r\nimport { createDatabaseError } from './errors.js';\r\n\r\nexport interface ConnectionPoolStats {\r\n type: 'redis' | 'sqlite' | 'postgres';\r\n total: number;\r\n active: number;\r\n idle: number;\r\n pending: number;\r\n maxConnections: number;\r\n available: number;\r\n healthy: boolean;\r\n lastHealthCheck?: Date;\r\n healthCheckActive: boolean;\r\n reconnectAttempts: number;\r\n failedAttempts: number;\r\n uptime: number;\r\n}\r\n\r\nexport interface PoolOptions {\r\n minConnections?: number;\r\n maxConnections?: number;\r\n acquireTimeout?: number;\r\n idleTimeout?: number;\r\n healthCheckInterval?: number;\r\n maxReconnectAttempts?: number;\r\n reconnectBaseDelay?: number;\r\n}\r\n\r\n/**\r\n * Connection Pool Manager\r\n *\r\n * Manages connection lifecycle, health checks, and automatic recovery\r\n */\r\nexport class ConnectionPoolManager {\r\n private config: DatabaseConfig;\r\n private options: Required<PoolOptions>;\r\n private pool: any = null;\r\n private connections: Set<any> = new Set();\r\n private activeConnections: Set<any> = new Set();\r\n private pendingRequests: Array<{\r\n resolve: (connection: any) => void;\r\n reject: (error: Error) => void;\r\n timestamp: number;\r\n }> = [];\r\n private healthCheckInterval?: NodeJS.Timeout;\r\n private lastHealthCheck?: Date;\r\n private healthCheckActive: boolean = false;\r\n private reconnectAttempts: number = 0;\r\n private maxReconnectAttempts: number = 10;\r\n private failedAttempts: number = 0;\r\n private startTime: Date;\r\n private isShuttingDown: boolean = false;\r\n private cacheFallbackEnabled: boolean = false;\r\n private cache: Map<string, any> = new Map();\r\n\r\n constructor(config: DatabaseConfig, options: PoolOptions = {}) {\r\n this.config = config;\r\n this.options = {\r\n minConnections: options.minConnections ?? 2,\r\n maxConnections: options.maxConnections ?? config.poolSize ?? 10,\r\n acquireTimeout: options.acquireTimeout ?? config.timeout ?? 5000,\r\n idleTimeout: options.idleTimeout ?? 30000,\r\n healthCheckInterval: options.healthCheckInterval ?? 30000,\r\n maxReconnectAttempts: options.maxReconnectAttempts ?? 10,\r\n reconnectBaseDelay: options.reconnectBaseDelay ?? 1000,\r\n };\r\n this.maxReconnectAttempts = this.options.maxReconnectAttempts;\r\n this.startTime = new Date();\r\n }\r\n\r\n /**\r\n * Initialize connection pool\r\n */\r\n async initialize(): Promise<void> {\r\n try {\r\n switch (this.config.type) {\r\n case 'sqlite':\r\n await this.initializeSQLitePool();\r\n break;\r\n case 'redis':\r\n await this.initializeRedisPool();\r\n break;\r\n case 'postgres':\r\n await this.initializePostgresPool();\r\n break;\r\n default:\r\n throw new Error(`Unsupported database type: ${this.config.type}`);\r\n }\r\n\r\n // Initialize minimum connections\r\n await this.warmUpPool();\r\n } catch (err) {\r\n this.failedAttempts++;\r\n throw createDatabaseError(\r\n DatabaseErrorCode.CONNECTION_FAILED,\r\n `Failed to initialize ${this.config.type} connection pool`,\r\n err instanceof Error ? err : new Error(String(err)),\r\n { config: this.config }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Initialize SQLite connection pool\r\n */\r\n private async initializeSQLitePool(): Promise<void> {\r\n const dbPath = this.config.database || this.config.connectionString || ':memory:';\r\n\r\n if (!dbPath || dbPath === '') {\r\n throw new Error('SQLite database path is required');\r\n }\r\n\r\n // Create connection pool for SQLite\r\n for (let i = 0; i < this.options.minConnections; i++) {\r\n const db = await open({\r\n filename: dbPath,\r\n driver: sqlite3.Database,\r\n });\r\n\r\n await db.run('PRAGMA foreign_keys = ON');\r\n await db.run(`PRAGMA busy_timeout = ${this.config.timeout || 5000}`);\r\n\r\n this.connections.add(db);\r\n }\r\n }\r\n\r\n /**\r\n * Initialize Redis connection pool\r\n */\r\n private async initializeRedisPool(): Promise<void> {\r\n let url = this.config.connectionString;\r\n\r\n if (!url) {\r\n // Build connection string with optional authentication\r\n const host = this.config.host || 'localhost';\r\n const port = this.config.port || 6379;\r\n\r\n if (this.config.password) {\r\n // Include password in connection string: redis://:password@host:port\r\n url = `redis://:${encodeURIComponent(this.config.password)}@${host}:${port}`;\r\n } else {\r\n url = `redis://${host}:${port}`;\r\n }\r\n }\r\n\r\n this.pool = createClient({\r\n url,\r\n socket: {\r\n connectTimeout: this.config.timeout || 5000,\r\n reconnectStrategy: (retries) => {\r\n if (retries > this.maxReconnectAttempts) {\r\n return false;\r\n }\r\n // Exponential backoff\r\n return Math.min(this.options.reconnectBaseDelay * Math.pow(2, retries), 30000);\r\n },\r\n },\r\n });\r\n\r\n // Set up event handlers\r\n this.pool.on('error', (err: Error) => {\r\n console.error('Redis connection error:', err);\r\n this.failedAttempts++;\r\n });\r\n\r\n this.pool.on('reconnecting', () => {\r\n this.reconnectAttempts++;\r\n });\r\n\r\n await this.pool.connect();\r\n }\r\n\r\n /**\r\n * Initialize PostgreSQL connection pool\r\n */\r\n private async initializePostgresPool(): Promise<void> {\r\n const connectionString = this.config.connectionString ||\r\n `postgresql://${this.config.username}:${this.config.password}@${this.config.host}:${this.config.port}/${this.config.database}`;\r\n\r\n this.pool = new Pool({\r\n connectionString,\r\n min: this.options.minConnections,\r\n max: this.options.maxConnections,\r\n idleTimeoutMillis: this.options.idleTimeout,\r\n connectionTimeoutMillis: this.options.acquireTimeout,\r\n });\r\n\r\n // Test connection\r\n const client = await this.pool.connect();\r\n await client.query('SELECT 1');\r\n client.release();\r\n }\r\n\r\n /**\r\n * Warm up pool by creating minimum connections\r\n */\r\n private async warmUpPool(): Promise<void> {\r\n if (this.config.type === 'sqlite') {\r\n // SQLite connections already created in initializeSQLitePool\r\n return;\r\n }\r\n\r\n // For Redis and Postgres, connections are managed by their libraries\r\n // We just need to verify connectivity\r\n if (this.config.type === 'redis') {\r\n await this.pool.ping();\r\n } else if (this.config.type === 'postgres') {\r\n const client = await this.pool.connect();\r\n await client.query('SELECT 1');\r\n client.release();\r\n }\r\n }\r\n\r\n /**\r\n * Acquire connection from pool\r\n */\r\n async acquire(): Promise<any> {\r\n if (this.isShuttingDown) {\r\n throw createDatabaseError(\r\n DatabaseErrorCode.CONNECTION_FAILED,\r\n 'Connection pool is shutting down',\r\n undefined,\r\n { type: this.config.type }\r\n );\r\n }\r\n\r\n const startTime = Date.now();\r\n\r\n try {\r\n switch (this.config.type) {\r\n case 'sqlite':\r\n return await this.acquireSQLiteConnection(startTime);\r\n case 'redis':\r\n return this.pool;\r\n case 'postgres':\r\n return await this.pool.connect();\r\n default:\r\n throw new Error(`Unsupported database type: ${this.config.type}`);\r\n }\r\n } catch (err) {\r\n throw createDatabaseError(\r\n DatabaseErrorCode.CONNECTION_FAILED,\r\n 'Failed to acquire connection',\r\n err instanceof Error ? err : new Error(String(err)),\r\n { type: this.config.type }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Acquire SQLite connection from pool\r\n */\r\n private async acquireSQLiteConnection(startTime: number): Promise<Database> {\r\n // Check for available connection\r\n const availableConnection = Array.from(this.connections).find(\r\n conn => !this.activeConnections.has(conn)\r\n );\r\n\r\n if (availableConnection) {\r\n this.activeConnections.add(availableConnection);\r\n return availableConnection as Database;\r\n }\r\n\r\n // Check if we can create more connections\r\n if (this.connections.size < this.options.maxConnections) {\r\n const newConnection = await this.createSQLiteConnection();\r\n this.connections.add(newConnection);\r\n this.activeConnections.add(newConnection);\r\n return newConnection;\r\n }\r\n\r\n // Queue request\r\n return new Promise((resolve, reject) => {\r\n const timeoutId = setTimeout(() => {\r\n const index = this.pendingRequests.findIndex(req => req.resolve === resolve);\r\n if (index !== -1) {\r\n this.pendingRequests.splice(index, 1);\r\n }\r\n reject(createDatabaseError(\r\n DatabaseErrorCode.TIMEOUT,\r\n 'Connection acquisition timeout',\r\n undefined,\r\n { timeout: this.options.acquireTimeout }\r\n ));\r\n }, this.options.acquireTimeout);\r\n\r\n this.pendingRequests.push({\r\n resolve: (conn) => {\r\n clearTimeout(timeoutId);\r\n resolve(conn);\r\n },\r\n reject: (err) => {\r\n clearTimeout(timeoutId);\r\n reject(err);\r\n },\r\n timestamp: startTime,\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Create new SQLite connection\r\n */\r\n private async createSQLiteConnection(): Promise<Database> {\r\n const dbPath = this.config.database || this.config.connectionString || ':memory:';\r\n\r\n const db = await open({\r\n filename: dbPath,\r\n driver: sqlite3.Database,\r\n });\r\n\r\n await db.run('PRAGMA foreign_keys = ON');\r\n await db.run(`PRAGMA busy_timeout = ${this.config.timeout || 5000}`);\r\n\r\n return db;\r\n }\r\n\r\n /**\r\n * Release connection back to pool\r\n */\r\n async release(connection: any): Promise<void> {\r\n if (!connection) {\r\n return;\r\n }\r\n\r\n try {\r\n switch (this.config.type) {\r\n case 'sqlite':\r\n this.releaseSQLiteConnection(connection);\r\n break;\r\n case 'redis':\r\n // Redis client is shared, no release needed\r\n break;\r\n case 'postgres':\r\n if (connection && typeof connection.release === 'function') {\r\n connection.release();\r\n }\r\n break;\r\n }\r\n } catch (err) {\r\n console.error('Failed to release connection:', err);\r\n }\r\n }\r\n\r\n /**\r\n * Release SQLite connection\r\n */\r\n private releaseSQLiteConnection(connection: Database): void {\r\n this.activeConnections.delete(connection);\r\n\r\n // Process pending requests\r\n if (this.pendingRequests.length > 0) {\r\n const pending = this.pendingRequests.shift();\r\n if (pending) {\r\n this.activeConnections.add(connection);\r\n pending.resolve(connection);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Start periodic health checks\r\n */\r\n startHealthChecks(): void {\r\n if (this.healthCheckActive) {\r\n return;\r\n }\r\n\r\n this.healthCheckActive = true;\r\n this.healthCheckInterval = setInterval(async () => {\r\n try {\r\n const healthy = await this.performHealthCheck();\r\n this.lastHealthCheck = new Date();\r\n\r\n if (!healthy) {\r\n console.warn(`Health check failed for ${this.config.type} pool`);\r\n await this.attemptReconnection();\r\n }\r\n } catch (err) {\r\n console.error('Health check error:', err);\r\n }\r\n }, this.options.healthCheckInterval);\r\n }\r\n\r\n /**\r\n * Stop health checks\r\n */\r\n stopHealthChecks(): void {\r\n if (this.healthCheckInterval) {\r\n clearInterval(this.healthCheckInterval);\r\n this.healthCheckInterval = undefined;\r\n }\r\n this.healthCheckActive = false;\r\n }\r\n\r\n /**\r\n * Perform health check\r\n */\r\n private async performHealthCheck(): Promise<boolean> {\r\n try {\r\n switch (this.config.type) {\r\n case 'sqlite': {\r\n const connection = Array.from(this.connections)[0];\r\n if (connection) {\r\n await (connection as Database).get('SELECT 1');\r\n return true;\r\n }\r\n return false;\r\n }\r\n case 'redis':\r\n if (this.pool) {\r\n await this.pool.ping();\r\n return true;\r\n }\r\n return false;\r\n case 'postgres':\r\n if (this.pool) {\r\n const client = await this.pool.connect();\r\n await client.query('SELECT 1');\r\n client.release();\r\n return true;\r\n }\r\n return false;\r\n default:\r\n return false;\r\n }\r\n } catch (err) {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Check if pool is healthy (exposed for testing)\r\n */\r\n private async isHealthy(): Promise<boolean> {\r\n return this.performHealthCheck();\r\n }\r\n\r\n /**\r\n * Attempt reconnection with exponential backoff\r\n */\r\n private async attemptReconnection(): Promise<void> {\r\n if (this.reconnectAttempts >= this.maxReconnectAttempts) {\r\n console.error(`Max reconnection attempts (${this.maxReconnectAttempts}) reached for ${this.config.type}`);\r\n return;\r\n }\r\n\r\n const delay = Math.min(\r\n this.options.reconnectBaseDelay * Math.pow(2, this.reconnectAttempts),\r\n 30000\r\n );\r\n\r\n this.reconnectAttempts++;\r\n\r\n await new Promise(resolve => setTimeout(resolve, delay));\r\n\r\n try {\r\n await this.initialize();\r\n console.log(`Reconnection successful for ${this.config.type}`);\r\n this.reconnectAttempts = 0;\r\n } catch (err) {\r\n console.error(`Reconnection failed for ${this.config.type}:`, err);\r\n }\r\n }\r\n\r\n /**\r\n * Get reconnection delays for testing\r\n */\r\n private getReconnectDelays(): number[] {\r\n const delays: number[] = [];\r\n for (let i = 0; i < 5; i++) {\r\n delays.push(\r\n Math.min(this.options.reconnectBaseDelay * Math.pow(2, i), 30000)\r\n );\r\n }\r\n return delays;\r\n }\r\n\r\n /**\r\n * Simulate disconnection (for testing)\r\n */\r\n private simulateDisconnection(): void {\r\n if (this.config.type === 'redis' && this.pool) {\r\n this.pool.disconnect();\r\n } else if (this.config.type === 'postgres' && this.pool) {\r\n this.pool.end();\r\n }\r\n }\r\n\r\n /**\r\n * Remove unhealthy connections (for testing)\r\n */\r\n private removeUnhealthyConnections(count: number): void {\r\n if (this.config.type === 'sqlite') {\r\n const connectionsToRemove = Array.from(this.connections).slice(0, count);\r\n connectionsToRemove.forEach(conn => {\r\n this.connections.delete(conn);\r\n this.activeConnections.delete(conn);\r\n (conn as Database).close();\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Enable cache fallback for graceful degradation\r\n */\r\n enableCacheFallback(enabled: boolean): void {\r\n this.cacheFallbackEnabled = enabled;\r\n }\r\n\r\n /**\r\n * Get data with cache fallback\r\n */\r\n async getWithFallback(key: string): Promise<any> {\r\n try {\r\n const connection = await this.acquire();\r\n // Actual data retrieval would happen here\r\n await this.release(connection);\r\n return null;\r\n } catch (err) {\r\n if (this.cacheFallbackEnabled && this.cache.has(key)) {\r\n console.warn(`Using cached data for key: ${key}`);\r\n return this.cache.get(key);\r\n }\r\n throw err;\r\n }\r\n }\r\n\r\n /**\r\n * Get connection pool statistics\r\n */\r\n getStats(): ConnectionPoolStats {\r\n const now = Date.now();\r\n const uptime = now - this.startTime.getTime();\r\n\r\n switch (this.config.type) {\r\n case 'sqlite':\r\n return {\r\n type: 'sqlite',\r\n total: this.connections.size,\r\n active: this.activeConnections.size,\r\n idle: this.connections.size - this.activeConnections.size,\r\n pending: this.pendingRequests.length,\r\n maxConnections: this.options.maxConnections,\r\n available: this.connections.size - this.activeConnections.size,\r\n healthy: this.connections.size > 0,\r\n lastHealthCheck: this.lastHealthCheck,\r\n healthCheckActive: this.healthCheckActive,\r\n reconnectAttempts: this.reconnectAttempts,\r\n failedAttempts: this.failedAttempts,\r\n uptime,\r\n };\r\n\r\n case 'redis':\r\n return {\r\n type: 'redis',\r\n total: this.pool ? 1 : 0,\r\n active: this.pool?.isOpen ? 1 : 0,\r\n idle: 0,\r\n pending: 0,\r\n maxConnections: 1,\r\n available: this.pool?.isOpen ? 1 : 0,\r\n healthy: this.pool?.isOpen ?? false,\r\n lastHealthCheck: this.lastHealthCheck,\r\n healthCheckActive: this.healthCheckActive,\r\n reconnectAttempts: this.reconnectAttempts,\r\n failedAttempts: this.failedAttempts,\r\n uptime,\r\n };\r\n\r\n case 'postgres':\r\n return {\r\n type: 'postgres',\r\n total: this.pool?.totalCount ?? 0,\r\n active: (this.pool?.totalCount ?? 0) - (this.pool?.idleCount ?? 0),\r\n idle: this.pool?.idleCount ?? 0,\r\n pending: this.pool?.waitingCount ?? 0,\r\n maxConnections: this.options.maxConnections,\r\n available: this.pool?.idleCount ?? 0,\r\n healthy: this.pool !== null,\r\n lastHealthCheck: this.lastHealthCheck,\r\n healthCheckActive: this.healthCheckActive,\r\n reconnectAttempts: this.reconnectAttempts,\r\n failedAttempts: this.failedAttempts,\r\n uptime,\r\n };\r\n\r\n default:\r\n throw new Error(`Unsupported database type: ${this.config.type}`);\r\n }\r\n }\r\n\r\n /**\r\n * Shutdown connection pool\r\n */\r\n async shutdown(): Promise<void> {\r\n if (this.isShuttingDown) {\r\n return;\r\n }\r\n\r\n this.isShuttingDown = true;\r\n this.stopHealthChecks();\r\n\r\n // Reject all pending requests\r\n this.pendingRequests.forEach(req => {\r\n req.reject(createDatabaseError(\r\n DatabaseErrorCode.CONNECTION_FAILED,\r\n 'Connection pool is shutting down',\r\n undefined,\r\n { type: this.config.type }\r\n ));\r\n });\r\n this.pendingRequests = [];\r\n\r\n // Close all connections\r\n try {\r\n switch (this.config.type) {\r\n case 'sqlite':\r\n await Promise.all(\r\n Array.from(this.connections).map(conn => (conn as Database).close())\r\n );\r\n this.connections.clear();\r\n this.activeConnections.clear();\r\n break;\r\n\r\n case 'redis':\r\n if (this.pool) {\r\n await this.pool.quit();\r\n this.pool = null;\r\n }\r\n break;\r\n\r\n case 'postgres':\r\n if (this.pool) {\r\n await this.pool.end();\r\n this.pool = null;\r\n }\r\n break;\r\n }\r\n } catch (err) {\r\n console.error('Error during shutdown:', err);\r\n }\r\n }\r\n}\r\n"],"names":["sqlite3","open","createClient","Pool","DatabaseErrorCode","createDatabaseError","ConnectionPoolManager","config","options","pool","connections","Set","activeConnections","pendingRequests","healthCheckInterval","lastHealthCheck","healthCheckActive","reconnectAttempts","maxReconnectAttempts","failedAttempts","startTime","isShuttingDown","cacheFallbackEnabled","cache","Map","minConnections","maxConnections","poolSize","acquireTimeout","timeout","idleTimeout","reconnectBaseDelay","Date","initialize","type","initializeSQLitePool","initializeRedisPool","initializePostgresPool","Error","warmUpPool","err","CONNECTION_FAILED","String","dbPath","database","connectionString","i","db","filename","driver","Database","run","add","url","host","port","password","encodeURIComponent","socket","connectTimeout","reconnectStrategy","retries","Math","min","pow","on","console","error","connect","username","max","idleTimeoutMillis","connectionTimeoutMillis","client","query","release","ping","acquire","undefined","now","acquireSQLiteConnection","availableConnection","Array","from","find","conn","has","size","newConnection","createSQLiteConnection","Promise","resolve","reject","timeoutId","setTimeout","index","findIndex","req","splice","TIMEOUT","push","clearTimeout","timestamp","connection","releaseSQLiteConnection","delete","length","pending","shift","startHealthChecks","setInterval","healthy","performHealthCheck","warn","attemptReconnection","stopHealthChecks","clearInterval","get","isHealthy","delay","log","getReconnectDelays","delays","simulateDisconnection","disconnect","end","removeUnhealthyConnections","count","connectionsToRemove","slice","forEach","close","enableCacheFallback","enabled","getWithFallback","key","getStats","uptime","getTime","total","active","idle","available","isOpen","totalCount","idleCount","waitingCount","shutdown","all","map","clear","quit"],"mappings":"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"}
|