agentic-qe 3.2.3 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/v3/qe-accessibility-auditor.md +90 -0
- package/README.md +43 -5
- package/package.json +3 -2
- package/scripts/cloud-db-config.json +37 -0
- package/scripts/cloud-db-connect.sh +37 -0
- package/scripts/cloud-db-tunnel.sh +23 -0
- package/v3/CHANGELOG.md +165 -0
- package/v3/README.md +59 -1
- package/v3/assets/agents/v3/qe-accessibility-auditor.md +90 -0
- package/v3/dist/adapters/claude-flow/index.d.ts +54 -0
- package/v3/dist/adapters/claude-flow/index.d.ts.map +1 -0
- package/v3/dist/adapters/claude-flow/index.js +79 -0
- package/v3/dist/adapters/claude-flow/index.js.map +1 -0
- package/v3/dist/adapters/claude-flow/model-router-bridge.d.ts +70 -0
- package/v3/dist/adapters/claude-flow/model-router-bridge.d.ts.map +1 -0
- package/v3/dist/adapters/claude-flow/model-router-bridge.js +203 -0
- package/v3/dist/adapters/claude-flow/model-router-bridge.js.map +1 -0
- package/v3/dist/adapters/claude-flow/pretrain-bridge.d.ts +73 -0
- package/v3/dist/adapters/claude-flow/pretrain-bridge.d.ts.map +1 -0
- package/v3/dist/adapters/claude-flow/pretrain-bridge.js +276 -0
- package/v3/dist/adapters/claude-flow/pretrain-bridge.js.map +1 -0
- package/v3/dist/adapters/claude-flow/trajectory-bridge.d.ts +70 -0
- package/v3/dist/adapters/claude-flow/trajectory-bridge.d.ts.map +1 -0
- package/v3/dist/adapters/claude-flow/trajectory-bridge.js +205 -0
- package/v3/dist/adapters/claude-flow/trajectory-bridge.js.map +1 -0
- package/v3/dist/adapters/claude-flow/types.d.ts +99 -0
- package/v3/dist/adapters/claude-flow/types.d.ts.map +1 -0
- package/v3/dist/adapters/claude-flow/types.js +6 -0
- package/v3/dist/adapters/claude-flow/types.js.map +1 -0
- package/v3/dist/causal-discovery/causal-graph.d.ts +80 -1
- package/v3/dist/causal-discovery/causal-graph.d.ts.map +1 -1
- package/v3/dist/causal-discovery/causal-graph.js +111 -1
- package/v3/dist/causal-discovery/causal-graph.js.map +1 -1
- package/v3/dist/cli/bundle.js +11612 -4929
- package/v3/dist/cli/commands/claude-flow-setup.d.ts +82 -0
- package/v3/dist/cli/commands/claude-flow-setup.d.ts.map +1 -0
- package/v3/dist/cli/commands/claude-flow-setup.js +334 -0
- package/v3/dist/cli/commands/claude-flow-setup.js.map +1 -0
- package/v3/dist/cli/commands/hooks.d.ts +2 -0
- package/v3/dist/cli/commands/hooks.d.ts.map +1 -1
- package/v3/dist/cli/commands/hooks.js +13 -2
- package/v3/dist/cli/commands/hooks.js.map +1 -1
- package/v3/dist/cli/commands/init.d.ts +19 -0
- package/v3/dist/cli/commands/init.d.ts.map +1 -0
- package/v3/dist/cli/commands/init.js +345 -0
- package/v3/dist/cli/commands/init.js.map +1 -0
- package/v3/dist/cli/index.js +110 -2
- package/v3/dist/cli/index.js.map +1 -1
- package/v3/dist/coordination/mincut/interfaces.d.ts +8 -2
- package/v3/dist/coordination/mincut/interfaces.d.ts.map +1 -1
- package/v3/dist/coordination/mincut/interfaces.js.map +1 -1
- package/v3/dist/coordination/mincut/mincut-health-monitor.d.ts +5 -0
- package/v3/dist/coordination/mincut/mincut-health-monitor.d.ts.map +1 -1
- package/v3/dist/coordination/mincut/mincut-health-monitor.js +22 -4
- package/v3/dist/coordination/mincut/mincut-health-monitor.js.map +1 -1
- package/v3/dist/coordination/mincut/queen-integration.d.ts +4 -0
- package/v3/dist/coordination/mincut/queen-integration.d.ts.map +1 -1
- package/v3/dist/coordination/mincut/queen-integration.js +14 -1
- package/v3/dist/coordination/mincut/queen-integration.js.map +1 -1
- package/v3/dist/coordination/queen-coordinator.d.ts +5 -0
- package/v3/dist/coordination/queen-coordinator.d.ts.map +1 -1
- package/v3/dist/coordination/queen-coordinator.js +45 -7
- package/v3/dist/coordination/queen-coordinator.js.map +1 -1
- package/v3/dist/domains/learning-optimization/coordinator.d.ts +5 -0
- package/v3/dist/domains/learning-optimization/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/learning-optimization/coordinator.js +79 -0
- package/v3/dist/domains/learning-optimization/coordinator.js.map +1 -1
- package/v3/dist/domains/test-generation/coherence-gate.d.ts +245 -0
- package/v3/dist/domains/test-generation/coherence-gate.d.ts.map +1 -0
- package/v3/dist/domains/test-generation/coherence-gate.js +454 -0
- package/v3/dist/domains/test-generation/coherence-gate.js.map +1 -0
- package/v3/dist/domains/test-generation/coordinator.d.ts +32 -1
- package/v3/dist/domains/test-generation/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/test-generation/coordinator.js +70 -1
- package/v3/dist/domains/test-generation/coordinator.js.map +1 -1
- package/v3/dist/domains/test-generation/index.d.ts +1 -0
- package/v3/dist/domains/test-generation/index.d.ts.map +1 -1
- package/v3/dist/domains/test-generation/index.js +4 -0
- package/v3/dist/domains/test-generation/index.js.map +1 -1
- package/v3/dist/domains/test-generation/services/index.d.ts +1 -0
- package/v3/dist/domains/test-generation/services/index.d.ts.map +1 -1
- package/v3/dist/domains/test-generation/services/index.js +2 -0
- package/v3/dist/domains/test-generation/services/index.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/index.d.ts +2 -1
- package/v3/dist/domains/visual-accessibility/index.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/index.js +1 -0
- package/v3/dist/domains/visual-accessibility/index.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/interfaces.d.ts +131 -0
- package/v3/dist/domains/visual-accessibility/interfaces.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/plugin.d.ts +26 -0
- package/v3/dist/domains/visual-accessibility/plugin.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/plugin.js +151 -0
- package/v3/dist/domains/visual-accessibility/plugin.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/accessibility-tester.d.ts +42 -1
- package/v3/dist/domains/visual-accessibility/services/accessibility-tester.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/accessibility-tester.js +69 -0
- package/v3/dist/domains/visual-accessibility/services/accessibility-tester.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/eu-compliance.d.ts +138 -0
- package/v3/dist/domains/visual-accessibility/services/eu-compliance.d.ts.map +1 -0
- package/v3/dist/domains/visual-accessibility/services/eu-compliance.js +830 -0
- package/v3/dist/domains/visual-accessibility/services/eu-compliance.js.map +1 -0
- package/v3/dist/domains/visual-accessibility/services/index.d.ts +1 -0
- package/v3/dist/domains/visual-accessibility/services/index.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/index.js +1 -0
- package/v3/dist/domains/visual-accessibility/services/index.js.map +1 -1
- package/v3/dist/init/enhancements/claude-flow-adapter.d.ts +84 -0
- package/v3/dist/init/enhancements/claude-flow-adapter.d.ts.map +1 -0
- package/v3/dist/init/enhancements/claude-flow-adapter.js +250 -0
- package/v3/dist/init/enhancements/claude-flow-adapter.js.map +1 -0
- package/v3/dist/init/enhancements/detector.d.ts +10 -0
- package/v3/dist/init/enhancements/detector.d.ts.map +1 -0
- package/v3/dist/init/enhancements/detector.js +87 -0
- package/v3/dist/init/enhancements/detector.js.map +1 -0
- package/v3/dist/init/enhancements/index.d.ts +13 -0
- package/v3/dist/init/enhancements/index.d.ts.map +1 -0
- package/v3/dist/init/enhancements/index.js +25 -0
- package/v3/dist/init/enhancements/index.js.map +1 -0
- package/v3/dist/init/enhancements/types.d.ts +93 -0
- package/v3/dist/init/enhancements/types.d.ts.map +1 -0
- package/v3/dist/init/enhancements/types.js +6 -0
- package/v3/dist/init/enhancements/types.js.map +1 -0
- package/v3/dist/init/index.d.ts +8 -0
- package/v3/dist/init/index.d.ts.map +1 -1
- package/v3/dist/init/index.js +4 -0
- package/v3/dist/init/index.js.map +1 -1
- package/v3/dist/init/migration/config-migrator.d.ts +31 -0
- package/v3/dist/init/migration/config-migrator.d.ts.map +1 -0
- package/v3/dist/init/migration/config-migrator.js +133 -0
- package/v3/dist/init/migration/config-migrator.js.map +1 -0
- package/v3/dist/init/migration/data-migrator.d.ts +72 -0
- package/v3/dist/init/migration/data-migrator.d.ts.map +1 -0
- package/v3/dist/init/migration/data-migrator.js +233 -0
- package/v3/dist/init/migration/data-migrator.js.map +1 -0
- package/v3/dist/init/migration/detector.d.ts +44 -0
- package/v3/dist/init/migration/detector.d.ts.map +1 -0
- package/v3/dist/init/migration/detector.js +106 -0
- package/v3/dist/init/migration/detector.js.map +1 -0
- package/v3/dist/init/migration/index.d.ts +8 -0
- package/v3/dist/init/migration/index.d.ts.map +1 -0
- package/v3/dist/init/migration/index.js +8 -0
- package/v3/dist/init/migration/index.js.map +1 -0
- package/v3/dist/init/orchestrator.d.ts +68 -0
- package/v3/dist/init/orchestrator.d.ts.map +1 -0
- package/v3/dist/init/orchestrator.js +239 -0
- package/v3/dist/init/orchestrator.js.map +1 -0
- package/v3/dist/init/phases/01-detection.d.ts +30 -0
- package/v3/dist/init/phases/01-detection.d.ts.map +1 -0
- package/v3/dist/init/phases/01-detection.js +143 -0
- package/v3/dist/init/phases/01-detection.js.map +1 -0
- package/v3/dist/init/phases/02-analysis.d.ts +18 -0
- package/v3/dist/init/phases/02-analysis.d.ts.map +1 -0
- package/v3/dist/init/phases/02-analysis.js +28 -0
- package/v3/dist/init/phases/02-analysis.js.map +1 -0
- package/v3/dist/init/phases/03-configuration.d.ts +26 -0
- package/v3/dist/init/phases/03-configuration.d.ts.map +1 -0
- package/v3/dist/init/phases/03-configuration.js +98 -0
- package/v3/dist/init/phases/03-configuration.js.map +1 -0
- package/v3/dist/init/phases/04-database.d.ts +22 -0
- package/v3/dist/init/phases/04-database.d.ts.map +1 -0
- package/v3/dist/init/phases/04-database.js +88 -0
- package/v3/dist/init/phases/04-database.js.map +1 -0
- package/v3/dist/init/phases/05-learning.d.ts +28 -0
- package/v3/dist/init/phases/05-learning.d.ts.map +1 -0
- package/v3/dist/init/phases/05-learning.js +98 -0
- package/v3/dist/init/phases/05-learning.js.map +1 -0
- package/v3/dist/init/phases/06-code-intelligence.d.ts +33 -0
- package/v3/dist/init/phases/06-code-intelligence.d.ts.map +1 -0
- package/v3/dist/init/phases/06-code-intelligence.js +115 -0
- package/v3/dist/init/phases/06-code-intelligence.js.map +1 -0
- package/v3/dist/init/phases/07-hooks.d.ts +27 -0
- package/v3/dist/init/phases/07-hooks.d.ts.map +1 -0
- package/v3/dist/init/phases/07-hooks.js +209 -0
- package/v3/dist/init/phases/07-hooks.js.map +1 -0
- package/v3/dist/init/phases/08-mcp.d.ts +22 -0
- package/v3/dist/init/phases/08-mcp.d.ts.map +1 -0
- package/v3/dist/init/phases/08-mcp.js +62 -0
- package/v3/dist/init/phases/08-mcp.js.map +1 -0
- package/v3/dist/init/phases/09-assets.d.ts +23 -0
- package/v3/dist/init/phases/09-assets.d.ts.map +1 -0
- package/v3/dist/init/phases/09-assets.js +82 -0
- package/v3/dist/init/phases/09-assets.js.map +1 -0
- package/v3/dist/init/phases/10-workers.d.ts +23 -0
- package/v3/dist/init/phases/10-workers.d.ts.map +1 -0
- package/v3/dist/init/phases/10-workers.js +111 -0
- package/v3/dist/init/phases/10-workers.js.map +1 -0
- package/v3/dist/init/phases/11-claude-md.d.ts +26 -0
- package/v3/dist/init/phases/11-claude-md.d.ts.map +1 -0
- package/v3/dist/init/phases/11-claude-md.js +121 -0
- package/v3/dist/init/phases/11-claude-md.js.map +1 -0
- package/v3/dist/init/phases/12-verification.d.ts +38 -0
- package/v3/dist/init/phases/12-verification.d.ts.map +1 -0
- package/v3/dist/init/phases/12-verification.js +187 -0
- package/v3/dist/init/phases/12-verification.js.map +1 -0
- package/v3/dist/init/phases/index.d.ts +46 -0
- package/v3/dist/init/phases/index.d.ts.map +1 -0
- package/v3/dist/init/phases/index.js +64 -0
- package/v3/dist/init/phases/index.js.map +1 -0
- package/v3/dist/init/phases/phase-interface.d.ts +193 -0
- package/v3/dist/init/phases/phase-interface.d.ts.map +1 -0
- package/v3/dist/init/phases/phase-interface.js +119 -0
- package/v3/dist/init/phases/phase-interface.js.map +1 -0
- package/v3/dist/integrations/coherence/coherence-service.d.ts +323 -0
- package/v3/dist/integrations/coherence/coherence-service.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/coherence-service.js +799 -0
- package/v3/dist/integrations/coherence/coherence-service.js.map +1 -0
- package/v3/dist/integrations/coherence/engines/category-adapter.d.ts +170 -0
- package/v3/dist/integrations/coherence/engines/category-adapter.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/engines/category-adapter.js +403 -0
- package/v3/dist/integrations/coherence/engines/category-adapter.js.map +1 -0
- package/v3/dist/integrations/coherence/engines/causal-adapter.d.ts +159 -0
- package/v3/dist/integrations/coherence/engines/causal-adapter.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/engines/causal-adapter.js +348 -0
- package/v3/dist/integrations/coherence/engines/causal-adapter.js.map +1 -0
- package/v3/dist/integrations/coherence/engines/cohomology-adapter.d.ts +174 -0
- package/v3/dist/integrations/coherence/engines/cohomology-adapter.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/engines/cohomology-adapter.js +401 -0
- package/v3/dist/integrations/coherence/engines/cohomology-adapter.js.map +1 -0
- package/v3/dist/integrations/coherence/engines/homotopy-adapter.d.ts +201 -0
- package/v3/dist/integrations/coherence/engines/homotopy-adapter.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/engines/homotopy-adapter.js +324 -0
- package/v3/dist/integrations/coherence/engines/homotopy-adapter.js.map +1 -0
- package/v3/dist/integrations/coherence/engines/index.d.ts +20 -0
- package/v3/dist/integrations/coherence/engines/index.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/engines/index.js +26 -0
- package/v3/dist/integrations/coherence/engines/index.js.map +1 -0
- package/v3/dist/integrations/coherence/engines/spectral-adapter.d.ts +193 -0
- package/v3/dist/integrations/coherence/engines/spectral-adapter.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/engines/spectral-adapter.js +476 -0
- package/v3/dist/integrations/coherence/engines/spectral-adapter.js.map +1 -0
- package/v3/dist/integrations/coherence/engines/witness-adapter.d.ts +175 -0
- package/v3/dist/integrations/coherence/engines/witness-adapter.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/engines/witness-adapter.js +377 -0
- package/v3/dist/integrations/coherence/engines/witness-adapter.js.map +1 -0
- package/v3/dist/integrations/coherence/index.d.ts +84 -0
- package/v3/dist/integrations/coherence/index.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/index.js +114 -0
- package/v3/dist/integrations/coherence/index.js.map +1 -0
- package/v3/dist/integrations/coherence/threshold-tuner.d.ts +396 -0
- package/v3/dist/integrations/coherence/threshold-tuner.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/threshold-tuner.js +538 -0
- package/v3/dist/integrations/coherence/threshold-tuner.js.map +1 -0
- package/v3/dist/integrations/coherence/types.d.ts +879 -0
- package/v3/dist/integrations/coherence/types.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/types.js +134 -0
- package/v3/dist/integrations/coherence/types.js.map +1 -0
- package/v3/dist/integrations/coherence/wasm-loader.d.ts +351 -0
- package/v3/dist/integrations/coherence/wasm-loader.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/wasm-loader.js +842 -0
- package/v3/dist/integrations/coherence/wasm-loader.js.map +1 -0
- package/v3/dist/integrations/embeddings/index/HNSWIndex.d.ts.map +1 -1
- package/v3/dist/integrations/embeddings/index/HNSWIndex.js +4 -1
- package/v3/dist/integrations/embeddings/index/HNSWIndex.js.map +1 -1
- package/v3/dist/kernel/interfaces.d.ts +8 -1
- package/v3/dist/kernel/interfaces.d.ts.map +1 -1
- package/v3/dist/learning/aqe-learning-engine.d.ts +272 -0
- package/v3/dist/learning/aqe-learning-engine.d.ts.map +1 -0
- package/v3/dist/learning/aqe-learning-engine.js +708 -0
- package/v3/dist/learning/aqe-learning-engine.js.map +1 -0
- package/v3/dist/learning/causal-verifier.d.ts +244 -0
- package/v3/dist/learning/causal-verifier.d.ts.map +1 -0
- package/v3/dist/learning/causal-verifier.js +300 -0
- package/v3/dist/learning/causal-verifier.js.map +1 -0
- package/v3/dist/learning/experience-capture.d.ts +266 -0
- package/v3/dist/learning/experience-capture.d.ts.map +1 -0
- package/v3/dist/learning/experience-capture.js +647 -0
- package/v3/dist/learning/experience-capture.js.map +1 -0
- package/v3/dist/learning/index.d.ts +8 -0
- package/v3/dist/learning/index.d.ts.map +1 -1
- package/v3/dist/learning/index.js +16 -0
- package/v3/dist/learning/index.js.map +1 -1
- package/v3/dist/learning/memory-auditor.d.ts +235 -0
- package/v3/dist/learning/memory-auditor.d.ts.map +1 -0
- package/v3/dist/learning/memory-auditor.js +478 -0
- package/v3/dist/learning/memory-auditor.js.map +1 -0
- package/v3/dist/learning/pattern-store.d.ts.map +1 -1
- package/v3/dist/learning/pattern-store.js +27 -6
- package/v3/dist/learning/pattern-store.js.map +1 -1
- package/v3/dist/learning/qe-patterns.d.ts +15 -1
- package/v3/dist/learning/qe-patterns.d.ts.map +1 -1
- package/v3/dist/learning/qe-patterns.js +26 -5
- package/v3/dist/learning/qe-patterns.js.map +1 -1
- package/v3/dist/learning/qe-reasoning-bank.d.ts +38 -2
- package/v3/dist/learning/qe-reasoning-bank.d.ts.map +1 -1
- package/v3/dist/learning/qe-reasoning-bank.js +86 -4
- package/v3/dist/learning/qe-reasoning-bank.js.map +1 -1
- package/v3/dist/learning/real-qe-reasoning-bank.d.ts +32 -2
- package/v3/dist/learning/real-qe-reasoning-bank.d.ts.map +1 -1
- package/v3/dist/learning/real-qe-reasoning-bank.js +61 -6
- package/v3/dist/learning/real-qe-reasoning-bank.js.map +1 -1
- package/v3/dist/mcp/bundle.js +6303 -266
- package/v3/dist/mcp/tools/coherence/audit.d.ts +107 -0
- package/v3/dist/mcp/tools/coherence/audit.d.ts.map +1 -0
- package/v3/dist/mcp/tools/coherence/audit.js +236 -0
- package/v3/dist/mcp/tools/coherence/audit.js.map +1 -0
- package/v3/dist/mcp/tools/coherence/check.d.ts +106 -0
- package/v3/dist/mcp/tools/coherence/check.d.ts.map +1 -0
- package/v3/dist/mcp/tools/coherence/check.js +205 -0
- package/v3/dist/mcp/tools/coherence/check.js.map +1 -0
- package/v3/dist/mcp/tools/coherence/collapse.d.ts +123 -0
- package/v3/dist/mcp/tools/coherence/collapse.d.ts.map +1 -0
- package/v3/dist/mcp/tools/coherence/collapse.js +279 -0
- package/v3/dist/mcp/tools/coherence/collapse.js.map +1 -0
- package/v3/dist/mcp/tools/coherence/consensus.d.ts +100 -0
- package/v3/dist/mcp/tools/coherence/consensus.d.ts.map +1 -0
- package/v3/dist/mcp/tools/coherence/consensus.js +201 -0
- package/v3/dist/mcp/tools/coherence/consensus.js.map +1 -0
- package/v3/dist/mcp/tools/coherence/index.d.ts +31 -0
- package/v3/dist/mcp/tools/coherence/index.d.ts.map +1 -0
- package/v3/dist/mcp/tools/coherence/index.js +42 -0
- package/v3/dist/mcp/tools/coherence/index.js.map +1 -0
- package/v3/dist/mcp/tools/index.d.ts +6 -1
- package/v3/dist/mcp/tools/index.d.ts.map +1 -1
- package/v3/dist/mcp/tools/index.js +9 -1
- package/v3/dist/mcp/tools/index.js.map +1 -1
- package/v3/dist/mcp/tools/mincut/index.d.ts +1 -1
- package/v3/dist/mcp/tools/mincut/index.d.ts.map +1 -1
- package/v3/dist/mcp/tools/mincut/index.js.map +1 -1
- package/v3/dist/mcp/tools/registry.d.ts +4 -0
- package/v3/dist/mcp/tools/registry.d.ts.map +1 -1
- package/v3/dist/mcp/tools/registry.js +5 -0
- package/v3/dist/mcp/tools/registry.js.map +1 -1
- package/v3/dist/mcp/types.d.ts +1 -1
- package/v3/dist/mcp/types.d.ts.map +1 -1
- package/v3/dist/strange-loop/belief-reconciler.d.ts +357 -0
- package/v3/dist/strange-loop/belief-reconciler.d.ts.map +1 -0
- package/v3/dist/strange-loop/belief-reconciler.js +696 -0
- package/v3/dist/strange-loop/belief-reconciler.js.map +1 -0
- package/v3/dist/strange-loop/index.d.ts +1 -0
- package/v3/dist/strange-loop/index.d.ts.map +1 -1
- package/v3/dist/strange-loop/index.js +2 -0
- package/v3/dist/strange-loop/index.js.map +1 -1
- package/v3/dist/strange-loop/strange-loop.d.ts +177 -5
- package/v3/dist/strange-loop/strange-loop.d.ts.map +1 -1
- package/v3/dist/strange-loop/strange-loop.js +452 -9
- package/v3/dist/strange-loop/strange-loop.js.map +1 -1
- package/v3/dist/strange-loop/types.d.ts +205 -1
- package/v3/dist/strange-loop/types.d.ts.map +1 -1
- package/v3/dist/strange-loop/types.js +5 -0
- package/v3/dist/strange-loop/types.js.map +1 -1
- package/v3/package.json +5 -1
|
@@ -0,0 +1,842 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WASM Loader for Prime-Radiant Coherence Engines
|
|
3
|
+
*
|
|
4
|
+
* Provides lazy loading of the prime-radiant-advanced-wasm module with:
|
|
5
|
+
* - Retry logic with exponential backoff (3 attempts by default)
|
|
6
|
+
* - Event emission for monitoring load status
|
|
7
|
+
* - Graceful error handling
|
|
8
|
+
* - Node.js 18+ compatibility
|
|
9
|
+
*
|
|
10
|
+
* @module integrations/coherence/wasm-loader
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { wasmLoader } from './wasm-loader';
|
|
15
|
+
*
|
|
16
|
+
* // Add event listeners
|
|
17
|
+
* wasmLoader.on('loaded', ({ version, loadTimeMs }) => {
|
|
18
|
+
* console.log(`WASM loaded v${version} in ${loadTimeMs}ms`);
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* wasmLoader.on('retry', ({ attempt, maxAttempts, delayMs }) => {
|
|
22
|
+
* console.log(`Retry ${attempt}/${maxAttempts} in ${delayMs}ms`);
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* // Load and use engines
|
|
26
|
+
* const engines = await wasmLoader.getEngines();
|
|
27
|
+
* const energy = engines.cohomology.consistencyEnergy(graph);
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
import { createRequire } from 'node:module';
|
|
31
|
+
import { fileURLToPath } from 'node:url';
|
|
32
|
+
import { dirname, join } from 'node:path';
|
|
33
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
34
|
+
import { DEFAULT_WASM_LOADER_CONFIG, WasmLoadError, WasmNotLoadedError, } from './types.js';
|
|
35
|
+
/**
|
|
36
|
+
* ADR-052 A4.3: Exponential backoff delays for retry logic
|
|
37
|
+
* Default: 1s, 2s, 4s (3 retries)
|
|
38
|
+
*/
|
|
39
|
+
const FALLBACK_RETRY_DELAYS_MS = [1000, 2000, 4000];
|
|
40
|
+
/**
|
|
41
|
+
* WASM Loader for Prime-Radiant coherence engines.
|
|
42
|
+
*
|
|
43
|
+
* Provides lazy loading with retry logic and event emission.
|
|
44
|
+
* Uses the Singleton pattern to ensure only one loader instance.
|
|
45
|
+
* Implements IWasmLoader interface for CoherenceService compatibility.
|
|
46
|
+
*
|
|
47
|
+
* ADR-052 A4.3 Enhancements:
|
|
48
|
+
* - Full graceful degradation with fallback results
|
|
49
|
+
* - Emits 'degraded_mode' event via internal EventBus
|
|
50
|
+
* - Exponential backoff retry (1s, 2s, 4s)
|
|
51
|
+
* - Never blocks execution due to WASM failure
|
|
52
|
+
*/
|
|
53
|
+
export class WasmLoader {
|
|
54
|
+
state = 'unloaded';
|
|
55
|
+
wasmModule = null;
|
|
56
|
+
engines = null;
|
|
57
|
+
loadPromise = null;
|
|
58
|
+
lastError = null;
|
|
59
|
+
config;
|
|
60
|
+
version = '';
|
|
61
|
+
// ADR-052 A4.3: Fallback state tracking
|
|
62
|
+
fallbackState = {
|
|
63
|
+
mode: 'wasm',
|
|
64
|
+
consecutiveFailures: 0,
|
|
65
|
+
totalActivations: 0,
|
|
66
|
+
nextRetryAt: undefined,
|
|
67
|
+
lastSuccessfulLoad: undefined,
|
|
68
|
+
};
|
|
69
|
+
// ADR-052 A4.3: Background retry timer
|
|
70
|
+
retryTimer = null;
|
|
71
|
+
degradedModeStartTime = null;
|
|
72
|
+
eventListeners;
|
|
73
|
+
/**
|
|
74
|
+
* Create a new WASM loader instance.
|
|
75
|
+
*
|
|
76
|
+
* @param config - Loader configuration (optional)
|
|
77
|
+
*/
|
|
78
|
+
constructor(config = {}) {
|
|
79
|
+
this.config = { ...DEFAULT_WASM_LOADER_CONFIG, ...config };
|
|
80
|
+
// Initialize event listener maps (ADR-052 A4.3: added degraded_mode and recovered)
|
|
81
|
+
this.eventListeners = new Map();
|
|
82
|
+
this.eventListeners.set('loaded', new Set());
|
|
83
|
+
this.eventListeners.set('error', new Set());
|
|
84
|
+
this.eventListeners.set('retry', new Set());
|
|
85
|
+
this.eventListeners.set('degraded_mode', new Set());
|
|
86
|
+
this.eventListeners.set('recovered', new Set());
|
|
87
|
+
}
|
|
88
|
+
// ===========================================================================
|
|
89
|
+
// Public API
|
|
90
|
+
// ===========================================================================
|
|
91
|
+
/**
|
|
92
|
+
* Check if the WASM module is loaded and ready.
|
|
93
|
+
*
|
|
94
|
+
* @returns True if the module is loaded and engines are available
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* if (wasmLoader.isLoaded()) {
|
|
99
|
+
* const engines = wasmLoader.getEnginesSync();
|
|
100
|
+
* }
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
isLoaded() {
|
|
104
|
+
return this.state === 'loaded' && this.engines !== null;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Get the current loader state.
|
|
108
|
+
*
|
|
109
|
+
* @returns Current state: 'unloaded', 'loading', 'loaded', or 'failed'
|
|
110
|
+
*/
|
|
111
|
+
getState() {
|
|
112
|
+
return this.state;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Get the loaded WASM version (empty string if not loaded).
|
|
116
|
+
*
|
|
117
|
+
* @returns Version string from the WASM module
|
|
118
|
+
*/
|
|
119
|
+
getVersion() {
|
|
120
|
+
return this.version;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Get the last error that occurred during loading (if any).
|
|
124
|
+
*
|
|
125
|
+
* @returns The last error or null if no error
|
|
126
|
+
*/
|
|
127
|
+
getLastError() {
|
|
128
|
+
return this.lastError;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* ADR-052 A4.3: Check if currently operating in fallback/degraded mode.
|
|
132
|
+
*
|
|
133
|
+
* @returns True if WASM is unavailable and fallback is active
|
|
134
|
+
*/
|
|
135
|
+
isInDegradedMode() {
|
|
136
|
+
return this.state === 'degraded' || this.fallbackState.mode === 'fallback';
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* ADR-052 A4.3: Get the current fallback state.
|
|
140
|
+
*
|
|
141
|
+
* @returns Current fallback state with retry information
|
|
142
|
+
*/
|
|
143
|
+
getFallbackState() {
|
|
144
|
+
return { ...this.fallbackState };
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* ADR-052 A4.3: Get a fallback result when WASM is unavailable.
|
|
148
|
+
* Returns a "coherent" result with low confidence (0.5) and usedFallback: true.
|
|
149
|
+
* NEVER blocks execution.
|
|
150
|
+
*
|
|
151
|
+
* @returns FallbackResult with usedFallback: true and confidence: 0.5
|
|
152
|
+
*/
|
|
153
|
+
getFallbackResult() {
|
|
154
|
+
return {
|
|
155
|
+
usedFallback: true,
|
|
156
|
+
confidence: 0.5,
|
|
157
|
+
retryCount: this.fallbackState.consecutiveFailures,
|
|
158
|
+
lastError: this.lastError?.message,
|
|
159
|
+
activatedAt: this.degradedModeStartTime ?? new Date(),
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Load the WASM module and initialize all engines.
|
|
164
|
+
*
|
|
165
|
+
* This method is idempotent - calling it multiple times will return
|
|
166
|
+
* the same promise if loading is in progress, or the cached engines
|
|
167
|
+
* if already loaded.
|
|
168
|
+
*
|
|
169
|
+
* @returns Promise resolving to all coherence engines
|
|
170
|
+
* @throws {WasmLoadError} If loading fails after all retry attempts
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```typescript
|
|
174
|
+
* try {
|
|
175
|
+
* const engines = await wasmLoader.getEngines();
|
|
176
|
+
* const energy = engines.cohomology.consistencyEnergy(graph);
|
|
177
|
+
* } catch (error) {
|
|
178
|
+
* if (error instanceof WasmLoadError) {
|
|
179
|
+
* console.error(`Failed after ${error.attempts} attempts`);
|
|
180
|
+
* }
|
|
181
|
+
* }
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
async getEngines() {
|
|
185
|
+
// Return cached engines if already loaded
|
|
186
|
+
if (this.state === 'loaded' && this.engines) {
|
|
187
|
+
return this.engines;
|
|
188
|
+
}
|
|
189
|
+
// Return existing load promise if loading is in progress
|
|
190
|
+
if (this.state === 'loading' && this.loadPromise) {
|
|
191
|
+
return this.loadPromise;
|
|
192
|
+
}
|
|
193
|
+
// Start new load
|
|
194
|
+
this.state = 'loading';
|
|
195
|
+
this.loadPromise = this.loadWithRetry();
|
|
196
|
+
try {
|
|
197
|
+
this.engines = await this.loadPromise;
|
|
198
|
+
this.state = 'loaded';
|
|
199
|
+
// ADR-052 A4.3: Track successful load and emit recovery event if coming from degraded
|
|
200
|
+
if (this.fallbackState.mode === 'fallback' || this.fallbackState.mode === 'recovering') {
|
|
201
|
+
this.emitRecoveryEvent();
|
|
202
|
+
}
|
|
203
|
+
this.fallbackState.mode = 'wasm';
|
|
204
|
+
this.fallbackState.consecutiveFailures = 0;
|
|
205
|
+
this.fallbackState.lastSuccessfulLoad = new Date();
|
|
206
|
+
return this.engines;
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
this.state = 'failed';
|
|
210
|
+
this.lastError = error instanceof Error ? error : new Error(String(error));
|
|
211
|
+
// ADR-052 A4.3: Enter degraded mode and schedule retry
|
|
212
|
+
this.enterDegradedMode(this.lastError);
|
|
213
|
+
throw error;
|
|
214
|
+
}
|
|
215
|
+
finally {
|
|
216
|
+
this.loadPromise = null;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* ADR-052 A4.3: Get engines with graceful fallback - NEVER throws.
|
|
221
|
+
*
|
|
222
|
+
* This method attempts to load WASM but returns null with a FallbackResult
|
|
223
|
+
* instead of throwing. Use this when you want to handle degraded mode gracefully.
|
|
224
|
+
*
|
|
225
|
+
* @returns Object with engines (or null) and fallback information
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
* ```typescript
|
|
229
|
+
* const { engines, fallback } = await wasmLoader.getEnginesWithFallback();
|
|
230
|
+
*
|
|
231
|
+
* if (fallback.usedFallback) {
|
|
232
|
+
* console.warn('Operating in degraded mode:', fallback.lastError);
|
|
233
|
+
* // Use TypeScript fallback implementation
|
|
234
|
+
* } else {
|
|
235
|
+
* // Use WASM engines
|
|
236
|
+
* const energy = engines!.cohomology.consistencyEnergy(graph);
|
|
237
|
+
* }
|
|
238
|
+
* ```
|
|
239
|
+
*/
|
|
240
|
+
async getEnginesWithFallback() {
|
|
241
|
+
// Return cached engines if already loaded
|
|
242
|
+
if (this.state === 'loaded' && this.engines) {
|
|
243
|
+
return {
|
|
244
|
+
engines: this.engines,
|
|
245
|
+
fallback: {
|
|
246
|
+
usedFallback: false,
|
|
247
|
+
confidence: 1.0,
|
|
248
|
+
retryCount: 0,
|
|
249
|
+
},
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
// If already in degraded mode, return fallback immediately (don't block)
|
|
253
|
+
if (this.state === 'degraded') {
|
|
254
|
+
return {
|
|
255
|
+
engines: null,
|
|
256
|
+
fallback: this.getFallbackResult(),
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
try {
|
|
260
|
+
const engines = await this.getEngines();
|
|
261
|
+
return {
|
|
262
|
+
engines,
|
|
263
|
+
fallback: {
|
|
264
|
+
usedFallback: false,
|
|
265
|
+
confidence: 1.0,
|
|
266
|
+
retryCount: 0,
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
catch {
|
|
271
|
+
// ADR-052 A4.3: Never throw - return fallback result
|
|
272
|
+
return {
|
|
273
|
+
engines: null,
|
|
274
|
+
fallback: this.getFallbackResult(),
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Get engines synchronously if already loaded.
|
|
280
|
+
*
|
|
281
|
+
* @returns Coherence engines
|
|
282
|
+
* @throws {WasmNotLoadedError} If WASM is not loaded
|
|
283
|
+
*
|
|
284
|
+
* @example
|
|
285
|
+
* ```typescript
|
|
286
|
+
* if (wasmLoader.isLoaded()) {
|
|
287
|
+
* const engines = wasmLoader.getEnginesSync();
|
|
288
|
+
* }
|
|
289
|
+
* ```
|
|
290
|
+
*/
|
|
291
|
+
getEnginesSync() {
|
|
292
|
+
if (!this.engines) {
|
|
293
|
+
throw new WasmNotLoadedError('WASM module is not loaded. Call getEngines() first.');
|
|
294
|
+
}
|
|
295
|
+
return this.engines;
|
|
296
|
+
}
|
|
297
|
+
// ===========================================================================
|
|
298
|
+
// IWasmLoader Interface Implementation
|
|
299
|
+
// ===========================================================================
|
|
300
|
+
/**
|
|
301
|
+
* Check if WASM module is available for loading.
|
|
302
|
+
* Required by IWasmLoader interface.
|
|
303
|
+
*
|
|
304
|
+
* @returns Promise resolving to true if WASM can be loaded
|
|
305
|
+
*/
|
|
306
|
+
async isAvailable() {
|
|
307
|
+
// If already loaded, it's available
|
|
308
|
+
if (this.state === 'loaded' && this.wasmModule) {
|
|
309
|
+
return true;
|
|
310
|
+
}
|
|
311
|
+
// If failed, it's not available
|
|
312
|
+
if (this.state === 'failed') {
|
|
313
|
+
return false;
|
|
314
|
+
}
|
|
315
|
+
// Try to detect if WASM file exists
|
|
316
|
+
try {
|
|
317
|
+
const require = createRequire(import.meta.url);
|
|
318
|
+
const wasmPaths = [
|
|
319
|
+
(() => {
|
|
320
|
+
try {
|
|
321
|
+
const modulePath = require.resolve('prime-radiant-advanced-wasm');
|
|
322
|
+
return join(dirname(modulePath), 'prime_radiant_advanced_wasm_bg.wasm');
|
|
323
|
+
}
|
|
324
|
+
catch {
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
})(),
|
|
328
|
+
join(process.cwd(), 'node_modules/prime-radiant-advanced-wasm/prime_radiant_advanced_wasm_bg.wasm'),
|
|
329
|
+
].filter((p) => p !== null);
|
|
330
|
+
for (const path of wasmPaths) {
|
|
331
|
+
if (existsSync(path)) {
|
|
332
|
+
return true;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
catch {
|
|
338
|
+
return false;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Load the WASM module.
|
|
343
|
+
* Required by IWasmLoader interface.
|
|
344
|
+
*
|
|
345
|
+
* @returns Promise resolving to the loaded WasmModule
|
|
346
|
+
*/
|
|
347
|
+
async load() {
|
|
348
|
+
// Ensure engines are loaded (this also loads the module)
|
|
349
|
+
await this.getEngines();
|
|
350
|
+
if (!this.wasmModule) {
|
|
351
|
+
throw new WasmNotLoadedError('WASM module failed to load');
|
|
352
|
+
}
|
|
353
|
+
// Return the module cast to WasmModule (they have the same structure)
|
|
354
|
+
return this.wasmModule;
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Get the loaded WASM module synchronously.
|
|
358
|
+
* Required by IWasmLoader interface.
|
|
359
|
+
*
|
|
360
|
+
* @returns The loaded WasmModule
|
|
361
|
+
* @throws {WasmNotLoadedError} If the module is not loaded
|
|
362
|
+
*/
|
|
363
|
+
getModule() {
|
|
364
|
+
if (!this.wasmModule) {
|
|
365
|
+
throw new WasmNotLoadedError('WASM module is not loaded. Call load() first.');
|
|
366
|
+
}
|
|
367
|
+
return this.wasmModule;
|
|
368
|
+
}
|
|
369
|
+
// ===========================================================================
|
|
370
|
+
// Event Handling
|
|
371
|
+
// ===========================================================================
|
|
372
|
+
/**
|
|
373
|
+
* Subscribe to loader events.
|
|
374
|
+
*
|
|
375
|
+
* @param event - Event name: 'loaded', 'error', or 'retry'
|
|
376
|
+
* @param listener - Callback function
|
|
377
|
+
* @returns Unsubscribe function
|
|
378
|
+
*
|
|
379
|
+
* @example
|
|
380
|
+
* ```typescript
|
|
381
|
+
* const unsubscribe = wasmLoader.on('loaded', ({ version }) => {
|
|
382
|
+
* console.log(`Loaded version ${version}`);
|
|
383
|
+
* });
|
|
384
|
+
*
|
|
385
|
+
* // Later, to unsubscribe:
|
|
386
|
+
* unsubscribe();
|
|
387
|
+
* ```
|
|
388
|
+
*/
|
|
389
|
+
on(event, listener) {
|
|
390
|
+
const listeners = this.eventListeners.get(event);
|
|
391
|
+
if (listeners) {
|
|
392
|
+
listeners.add(listener);
|
|
393
|
+
}
|
|
394
|
+
// Return unsubscribe function
|
|
395
|
+
return () => {
|
|
396
|
+
listeners?.delete(listener);
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Unsubscribe from loader events.
|
|
401
|
+
*
|
|
402
|
+
* @param event - Event name
|
|
403
|
+
* @param listener - Callback function to remove
|
|
404
|
+
*/
|
|
405
|
+
off(event, listener) {
|
|
406
|
+
const listeners = this.eventListeners.get(event);
|
|
407
|
+
if (listeners) {
|
|
408
|
+
listeners.delete(listener);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Reset the loader state to allow reloading.
|
|
413
|
+
*
|
|
414
|
+
* This frees any loaded engines and resets the state to 'unloaded'.
|
|
415
|
+
* Useful for testing or recovery scenarios.
|
|
416
|
+
*/
|
|
417
|
+
reset() {
|
|
418
|
+
// Cancel any pending retry timer
|
|
419
|
+
if (this.retryTimer) {
|
|
420
|
+
clearTimeout(this.retryTimer);
|
|
421
|
+
this.retryTimer = null;
|
|
422
|
+
}
|
|
423
|
+
// Free any loaded engines
|
|
424
|
+
if (this.engines) {
|
|
425
|
+
try {
|
|
426
|
+
this.engines.cohomology.free();
|
|
427
|
+
this.engines.spectral.free();
|
|
428
|
+
this.engines.causal.free();
|
|
429
|
+
this.engines.category.free();
|
|
430
|
+
this.engines.hott.free();
|
|
431
|
+
this.engines.quantum.free();
|
|
432
|
+
}
|
|
433
|
+
catch {
|
|
434
|
+
// Ignore errors during cleanup
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
this.state = 'unloaded';
|
|
438
|
+
this.wasmModule = null;
|
|
439
|
+
this.engines = null;
|
|
440
|
+
this.loadPromise = null;
|
|
441
|
+
this.lastError = null;
|
|
442
|
+
this.version = '';
|
|
443
|
+
// ADR-052 A4.3: Reset fallback state
|
|
444
|
+
this.fallbackState = {
|
|
445
|
+
mode: 'wasm',
|
|
446
|
+
consecutiveFailures: 0,
|
|
447
|
+
totalActivations: 0,
|
|
448
|
+
nextRetryAt: undefined,
|
|
449
|
+
lastSuccessfulLoad: undefined,
|
|
450
|
+
};
|
|
451
|
+
this.degradedModeStartTime = null;
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* ADR-052 A4.3: Force a retry of WASM loading.
|
|
455
|
+
* Can be called manually to trigger an immediate retry attempt.
|
|
456
|
+
*
|
|
457
|
+
* @returns Promise resolving to true if WASM was loaded, false otherwise
|
|
458
|
+
*/
|
|
459
|
+
async forceRetry() {
|
|
460
|
+
// Cancel any pending retry
|
|
461
|
+
if (this.retryTimer) {
|
|
462
|
+
clearTimeout(this.retryTimer);
|
|
463
|
+
this.retryTimer = null;
|
|
464
|
+
}
|
|
465
|
+
// Clear failed state to allow retry
|
|
466
|
+
if (this.state === 'failed' || this.state === 'degraded') {
|
|
467
|
+
this.state = 'unloaded';
|
|
468
|
+
this.fallbackState.mode = 'recovering';
|
|
469
|
+
}
|
|
470
|
+
try {
|
|
471
|
+
await this.getEngines();
|
|
472
|
+
return true;
|
|
473
|
+
}
|
|
474
|
+
catch {
|
|
475
|
+
return false;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
// ===========================================================================
|
|
479
|
+
// Private Methods
|
|
480
|
+
// ===========================================================================
|
|
481
|
+
/**
|
|
482
|
+
* Load the WASM module with retry logic and exponential backoff.
|
|
483
|
+
*/
|
|
484
|
+
async loadWithRetry() {
|
|
485
|
+
const { maxAttempts, baseDelayMs, maxDelayMs } = this.config;
|
|
486
|
+
let lastError = new Error('Unknown error');
|
|
487
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
488
|
+
try {
|
|
489
|
+
const startTime = performance.now();
|
|
490
|
+
const engines = await this.attemptLoad();
|
|
491
|
+
const loadTimeMs = performance.now() - startTime;
|
|
492
|
+
// Emit success event
|
|
493
|
+
this.emit('loaded', {
|
|
494
|
+
version: this.version,
|
|
495
|
+
loadTimeMs: Math.round(loadTimeMs * 100) / 100,
|
|
496
|
+
});
|
|
497
|
+
return engines;
|
|
498
|
+
}
|
|
499
|
+
catch (error) {
|
|
500
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
501
|
+
// Emit error event
|
|
502
|
+
this.emit('error', {
|
|
503
|
+
error: lastError,
|
|
504
|
+
fatal: attempt >= maxAttempts,
|
|
505
|
+
attempt,
|
|
506
|
+
});
|
|
507
|
+
if (attempt < maxAttempts) {
|
|
508
|
+
// Calculate delay with exponential backoff
|
|
509
|
+
const delayMs = Math.min(baseDelayMs * Math.pow(2, attempt - 1), maxDelayMs);
|
|
510
|
+
// Emit retry event
|
|
511
|
+
this.emit('retry', {
|
|
512
|
+
attempt: attempt + 1,
|
|
513
|
+
maxAttempts,
|
|
514
|
+
delayMs,
|
|
515
|
+
previousError: lastError,
|
|
516
|
+
});
|
|
517
|
+
// Wait before retry
|
|
518
|
+
await this.sleep(delayMs);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
// All retries exhausted
|
|
523
|
+
throw new WasmLoadError(`Failed to load WASM module after ${maxAttempts} attempts: ${lastError.message}`, maxAttempts, lastError);
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Attempt to load the WASM module once.
|
|
527
|
+
*
|
|
528
|
+
* This method handles both Node.js and browser environments:
|
|
529
|
+
* - Node.js: Uses initSync() with WASM bytes read from filesystem
|
|
530
|
+
* - Browser: Uses default() async init with fetch
|
|
531
|
+
*/
|
|
532
|
+
async attemptLoad() {
|
|
533
|
+
// Create require for ESM/CommonJS compatibility
|
|
534
|
+
// Note: import.meta.url is available in ESM contexts (Node.js 18+)
|
|
535
|
+
let require;
|
|
536
|
+
try {
|
|
537
|
+
// ESM context
|
|
538
|
+
require = createRequire(import.meta.url);
|
|
539
|
+
}
|
|
540
|
+
catch {
|
|
541
|
+
// CommonJS fallback - use global require
|
|
542
|
+
require = globalThis.require || (await import('module')).createRequire(__filename);
|
|
543
|
+
}
|
|
544
|
+
// Import the WASM module
|
|
545
|
+
let wasmModule;
|
|
546
|
+
try {
|
|
547
|
+
// Dynamic import for the WASM module
|
|
548
|
+
wasmModule = await import('prime-radiant-advanced-wasm');
|
|
549
|
+
}
|
|
550
|
+
catch (importError) {
|
|
551
|
+
// Fallback to require for CommonJS environments
|
|
552
|
+
try {
|
|
553
|
+
wasmModule = require('prime-radiant-advanced-wasm');
|
|
554
|
+
}
|
|
555
|
+
catch (requireError) {
|
|
556
|
+
throw new Error(`Failed to import prime-radiant-advanced-wasm: ${importError instanceof Error ? importError.message : String(importError)}`);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
// Determine if we're in Node.js environment
|
|
560
|
+
const isNodeJs = typeof process !== 'undefined' &&
|
|
561
|
+
process.versions != null &&
|
|
562
|
+
process.versions.node != null;
|
|
563
|
+
if (isNodeJs) {
|
|
564
|
+
// Node.js: Use initSync with WASM bytes from filesystem
|
|
565
|
+
await this.initializeForNodeJs(wasmModule, require);
|
|
566
|
+
}
|
|
567
|
+
else {
|
|
568
|
+
// Browser: Use async default init with fetch
|
|
569
|
+
if (wasmModule.default && typeof wasmModule.default === 'function') {
|
|
570
|
+
await wasmModule.default();
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
// Initialize the module internals if needed
|
|
574
|
+
if (wasmModule.initModule && typeof wasmModule.initModule === 'function') {
|
|
575
|
+
try {
|
|
576
|
+
wasmModule.initModule();
|
|
577
|
+
}
|
|
578
|
+
catch {
|
|
579
|
+
// initModule might throw if already initialized, which is fine
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
// Get version
|
|
583
|
+
if (wasmModule.getVersion && typeof wasmModule.getVersion === 'function') {
|
|
584
|
+
this.version = wasmModule.getVersion();
|
|
585
|
+
}
|
|
586
|
+
this.wasmModule = wasmModule;
|
|
587
|
+
// Create engine instances
|
|
588
|
+
const engines = {
|
|
589
|
+
cohomology: new wasmModule.CohomologyEngine(),
|
|
590
|
+
spectral: new wasmModule.SpectralEngine(),
|
|
591
|
+
causal: new wasmModule.CausalEngine(),
|
|
592
|
+
category: new wasmModule.CategoryEngine(),
|
|
593
|
+
hott: new wasmModule.HoTTEngine(),
|
|
594
|
+
quantum: new wasmModule.QuantumEngine(),
|
|
595
|
+
};
|
|
596
|
+
return engines;
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* Initialize WASM module for Node.js environment.
|
|
600
|
+
*
|
|
601
|
+
* In Node.js, the default async init uses fetch() which isn't available.
|
|
602
|
+
* Instead, we read the WASM binary from disk and use initSync().
|
|
603
|
+
*/
|
|
604
|
+
async initializeForNodeJs(wasmModule, require) {
|
|
605
|
+
// Find the WASM file path
|
|
606
|
+
const wasmPaths = [
|
|
607
|
+
// Resolve from require - most reliable
|
|
608
|
+
(() => {
|
|
609
|
+
try {
|
|
610
|
+
const modulePath = require.resolve('prime-radiant-advanced-wasm');
|
|
611
|
+
return join(dirname(modulePath), 'prime_radiant_advanced_wasm_bg.wasm');
|
|
612
|
+
}
|
|
613
|
+
catch {
|
|
614
|
+
return null;
|
|
615
|
+
}
|
|
616
|
+
})(),
|
|
617
|
+
// Direct node_modules path from current file
|
|
618
|
+
join(dirname(fileURLToPath(import.meta.url)), '../../../../node_modules/prime-radiant-advanced-wasm/prime_radiant_advanced_wasm_bg.wasm'),
|
|
619
|
+
// Workspace root
|
|
620
|
+
join(process.cwd(), 'node_modules/prime-radiant-advanced-wasm/prime_radiant_advanced_wasm_bg.wasm'),
|
|
621
|
+
].filter((p) => p !== null);
|
|
622
|
+
let wasmPath = null;
|
|
623
|
+
for (const path of wasmPaths) {
|
|
624
|
+
if (existsSync(path)) {
|
|
625
|
+
wasmPath = path;
|
|
626
|
+
break;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
if (!wasmPath) {
|
|
630
|
+
throw new Error(`Could not find WASM binary. Searched paths:\n${wasmPaths.join('\n')}\n` +
|
|
631
|
+
'Ensure prime-radiant-advanced-wasm is installed.');
|
|
632
|
+
}
|
|
633
|
+
// Read WASM bytes from disk
|
|
634
|
+
const wasmBytes = readFileSync(wasmPath);
|
|
635
|
+
// Use initSync to initialize the module with raw bytes
|
|
636
|
+
// Pass as object format to avoid deprecation warning
|
|
637
|
+
if (wasmModule.initSync && typeof wasmModule.initSync === 'function') {
|
|
638
|
+
wasmModule.initSync({ module: wasmBytes });
|
|
639
|
+
}
|
|
640
|
+
else {
|
|
641
|
+
throw new Error('WASM module does not export initSync function');
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* Emit an event to all registered listeners.
|
|
646
|
+
*/
|
|
647
|
+
emit(event, data) {
|
|
648
|
+
const listeners = this.eventListeners.get(event);
|
|
649
|
+
if (listeners) {
|
|
650
|
+
// Use Array.from for ES5 compatibility
|
|
651
|
+
const listenerArray = Array.from(listeners);
|
|
652
|
+
for (let i = 0; i < listenerArray.length; i++) {
|
|
653
|
+
try {
|
|
654
|
+
listenerArray[i](data);
|
|
655
|
+
}
|
|
656
|
+
catch {
|
|
657
|
+
// Don't let listener errors affect the loader
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Sleep for a specified duration.
|
|
664
|
+
*/
|
|
665
|
+
sleep(ms) {
|
|
666
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
667
|
+
}
|
|
668
|
+
// ===========================================================================
|
|
669
|
+
// ADR-052 A4.3: Fallback Mode Management
|
|
670
|
+
// ===========================================================================
|
|
671
|
+
/**
|
|
672
|
+
* ADR-052 A4.3: Enter degraded/fallback mode after WASM load failure.
|
|
673
|
+
* Logs warning, emits degraded_mode event, and schedules retry with exponential backoff.
|
|
674
|
+
*/
|
|
675
|
+
enterDegradedMode(error) {
|
|
676
|
+
// Update state
|
|
677
|
+
this.state = 'degraded';
|
|
678
|
+
this.fallbackState.mode = 'fallback';
|
|
679
|
+
this.fallbackState.consecutiveFailures++;
|
|
680
|
+
this.fallbackState.totalActivations++;
|
|
681
|
+
// Track when we entered degraded mode
|
|
682
|
+
if (!this.degradedModeStartTime) {
|
|
683
|
+
this.degradedModeStartTime = new Date();
|
|
684
|
+
}
|
|
685
|
+
// Calculate next retry time with exponential backoff (1s, 2s, 4s)
|
|
686
|
+
const retryIndex = Math.min(this.fallbackState.consecutiveFailures - 1, FALLBACK_RETRY_DELAYS_MS.length - 1);
|
|
687
|
+
const retryDelayMs = FALLBACK_RETRY_DELAYS_MS[retryIndex];
|
|
688
|
+
const nextRetryAt = new Date(Date.now() + retryDelayMs);
|
|
689
|
+
this.fallbackState.nextRetryAt = nextRetryAt;
|
|
690
|
+
// Log warning (ADR-052 A4.3 requirement 1)
|
|
691
|
+
console.warn(`[WasmLoader] WASM load failed, entering degraded mode. ` +
|
|
692
|
+
`Retry ${this.fallbackState.consecutiveFailures}/3 in ${retryDelayMs}ms. ` +
|
|
693
|
+
`Error: ${error.message}`);
|
|
694
|
+
// Emit degraded_mode event (ADR-052 A4.3 requirement 3)
|
|
695
|
+
this.emit('degraded_mode', {
|
|
696
|
+
reason: 'WASM load failed after retries',
|
|
697
|
+
retryCount: this.fallbackState.consecutiveFailures,
|
|
698
|
+
lastError: error.message,
|
|
699
|
+
activatedAt: this.degradedModeStartTime,
|
|
700
|
+
nextRetryAt,
|
|
701
|
+
});
|
|
702
|
+
// Schedule background retry with exponential backoff (ADR-052 A4.3 requirement 4)
|
|
703
|
+
// Only schedule if we haven't exceeded max retries
|
|
704
|
+
if (this.fallbackState.consecutiveFailures < FALLBACK_RETRY_DELAYS_MS.length) {
|
|
705
|
+
this.scheduleBackgroundRetry(retryDelayMs);
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
/**
|
|
709
|
+
* ADR-052 A4.3: Schedule a background retry of WASM loading.
|
|
710
|
+
* Never blocks execution (requirement 5).
|
|
711
|
+
*/
|
|
712
|
+
scheduleBackgroundRetry(delayMs) {
|
|
713
|
+
// Clear any existing retry timer
|
|
714
|
+
if (this.retryTimer) {
|
|
715
|
+
clearTimeout(this.retryTimer);
|
|
716
|
+
}
|
|
717
|
+
// Schedule the retry (non-blocking)
|
|
718
|
+
this.retryTimer = setTimeout(() => {
|
|
719
|
+
this.retryTimer = null;
|
|
720
|
+
this.fallbackState.mode = 'recovering';
|
|
721
|
+
// Attempt to reload WASM in background
|
|
722
|
+
this.attemptBackgroundRecovery();
|
|
723
|
+
}, delayMs);
|
|
724
|
+
}
|
|
725
|
+
/**
|
|
726
|
+
* ADR-052 A4.3: Attempt to recover WASM in the background.
|
|
727
|
+
* Called by the scheduled retry timer.
|
|
728
|
+
*/
|
|
729
|
+
async attemptBackgroundRecovery() {
|
|
730
|
+
// Reset state to allow reload attempt
|
|
731
|
+
this.state = 'unloaded';
|
|
732
|
+
this.loadPromise = null;
|
|
733
|
+
try {
|
|
734
|
+
await this.getEngines();
|
|
735
|
+
// Success! emitRecoveryEvent is called in getEngines()
|
|
736
|
+
}
|
|
737
|
+
catch {
|
|
738
|
+
// Still failing - enterDegradedMode will be called by getEngines()
|
|
739
|
+
// which will schedule the next retry if retries remain
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
/**
|
|
743
|
+
* ADR-052 A4.3: Emit recovery event when WASM is restored after degraded mode.
|
|
744
|
+
*/
|
|
745
|
+
emitRecoveryEvent() {
|
|
746
|
+
if (!this.degradedModeStartTime)
|
|
747
|
+
return;
|
|
748
|
+
const degradedDurationMs = Date.now() - this.degradedModeStartTime.getTime();
|
|
749
|
+
console.info(`[WasmLoader] WASM recovered after ${degradedDurationMs}ms in degraded mode. ` +
|
|
750
|
+
`Retry count: ${this.fallbackState.consecutiveFailures}`);
|
|
751
|
+
this.emit('recovered', {
|
|
752
|
+
degradedDurationMs,
|
|
753
|
+
retryCount: this.fallbackState.consecutiveFailures,
|
|
754
|
+
version: this.version,
|
|
755
|
+
});
|
|
756
|
+
// Reset degraded mode tracking
|
|
757
|
+
this.degradedModeStartTime = null;
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
// =============================================================================
|
|
761
|
+
// Singleton Instance
|
|
762
|
+
// =============================================================================
|
|
763
|
+
/**
|
|
764
|
+
* Default WASM loader instance (singleton).
|
|
765
|
+
*
|
|
766
|
+
* Use this for most cases. Create a new WasmLoader instance only if you
|
|
767
|
+
* need custom configuration or isolated state.
|
|
768
|
+
*
|
|
769
|
+
* @example
|
|
770
|
+
* ```typescript
|
|
771
|
+
* import { wasmLoader } from './wasm-loader';
|
|
772
|
+
*
|
|
773
|
+
* const engines = await wasmLoader.getEngines();
|
|
774
|
+
* ```
|
|
775
|
+
*/
|
|
776
|
+
export const wasmLoader = new WasmLoader();
|
|
777
|
+
// =============================================================================
|
|
778
|
+
// Convenience Exports
|
|
779
|
+
// =============================================================================
|
|
780
|
+
/**
|
|
781
|
+
* Check if WASM is loaded (convenience function).
|
|
782
|
+
*
|
|
783
|
+
* @returns True if the default loader has loaded the WASM module
|
|
784
|
+
*/
|
|
785
|
+
export function isLoaded() {
|
|
786
|
+
return wasmLoader.isLoaded();
|
|
787
|
+
}
|
|
788
|
+
/**
|
|
789
|
+
* Get engines from the default loader (convenience function).
|
|
790
|
+
*
|
|
791
|
+
* @returns Promise resolving to coherence engines
|
|
792
|
+
*/
|
|
793
|
+
export async function getEngines() {
|
|
794
|
+
return wasmLoader.getEngines();
|
|
795
|
+
}
|
|
796
|
+
/**
|
|
797
|
+
* Create a custom loader with specific configuration.
|
|
798
|
+
*
|
|
799
|
+
* @param config - Loader configuration
|
|
800
|
+
* @returns New WasmLoader instance
|
|
801
|
+
*
|
|
802
|
+
* @example
|
|
803
|
+
* ```typescript
|
|
804
|
+
* const customLoader = createLoader({
|
|
805
|
+
* maxAttempts: 5,
|
|
806
|
+
* baseDelayMs: 200,
|
|
807
|
+
* });
|
|
808
|
+
* ```
|
|
809
|
+
*/
|
|
810
|
+
export function createLoader(config) {
|
|
811
|
+
return new WasmLoader(config);
|
|
812
|
+
}
|
|
813
|
+
// =============================================================================
|
|
814
|
+
// ADR-052 A4.3: Fallback Convenience Exports
|
|
815
|
+
// =============================================================================
|
|
816
|
+
/**
|
|
817
|
+
* Check if the default loader is in degraded mode (convenience function).
|
|
818
|
+
*
|
|
819
|
+
* @returns True if operating with fallback logic
|
|
820
|
+
*/
|
|
821
|
+
export function isInDegradedMode() {
|
|
822
|
+
return wasmLoader.isInDegradedMode();
|
|
823
|
+
}
|
|
824
|
+
/**
|
|
825
|
+
* Get the fallback state from the default loader (convenience function).
|
|
826
|
+
*
|
|
827
|
+
* @returns Current fallback state
|
|
828
|
+
*/
|
|
829
|
+
export function getFallbackState() {
|
|
830
|
+
return wasmLoader.getFallbackState();
|
|
831
|
+
}
|
|
832
|
+
/**
|
|
833
|
+
* Get engines with fallback from the default loader (convenience function).
|
|
834
|
+
* NEVER throws - returns fallback result on failure.
|
|
835
|
+
*
|
|
836
|
+
* @returns Object with engines (or null) and fallback information
|
|
837
|
+
*/
|
|
838
|
+
export async function getEnginesWithFallback() {
|
|
839
|
+
return wasmLoader.getEnginesWithFallback();
|
|
840
|
+
}
|
|
841
|
+
export default wasmLoader;
|
|
842
|
+
//# sourceMappingURL=wasm-loader.js.map
|