@n-dx/web 0.1.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/LICENSE +96 -0
- package/README.md +5 -0
- package/build.js +243 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.js +50 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/landing/index.html +325 -0
- package/dist/landing/landing.d.ts +38 -0
- package/dist/landing/landing.js +299 -0
- package/dist/landing/landing.js.map +1 -0
- package/dist/public.d.ts +55 -0
- package/dist/public.js +51 -0
- package/dist/public.js.map +1 -0
- package/dist/schema/features.d.ts +28 -0
- package/dist/schema/features.js +9 -0
- package/dist/schema/features.js.map +1 -0
- package/dist/schema/v1.d.ts +317 -0
- package/dist/schema/v1.js +3 -0
- package/dist/schema/v1.js.map +1 -0
- package/dist/server/aggregation-cache.d.ts +105 -0
- package/dist/server/aggregation-cache.js +163 -0
- package/dist/server/aggregation-cache.js.map +1 -0
- package/dist/server/concurrent-execution-metrics.d.ts +103 -0
- package/dist/server/concurrent-execution-metrics.js +253 -0
- package/dist/server/concurrent-execution-metrics.js.map +1 -0
- package/dist/server/domain-gateway.d.ts +18 -0
- package/dist/server/domain-gateway.js +19 -0
- package/dist/server/domain-gateway.js.map +1 -0
- package/dist/server/incremental-task-usage.d.ts +92 -0
- package/dist/server/incremental-task-usage.js +251 -0
- package/dist/server/incremental-task-usage.js.map +1 -0
- package/dist/server/index.d.ts +39 -0
- package/dist/server/index.js +36 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/port.d.ts +96 -0
- package/dist/server/port.js +134 -0
- package/dist/server/port.js.map +1 -0
- package/dist/server/pr-markdown-refresh-diagnostics.d.ts +59 -0
- package/dist/server/pr-markdown-refresh-diagnostics.js +429 -0
- package/dist/server/pr-markdown-refresh-diagnostics.js.map +1 -0
- package/dist/server/prd-io.d.ts +40 -0
- package/dist/server/prd-io.js +66 -0
- package/dist/server/prd-io.js.map +1 -0
- package/dist/server/process-memory-tracker.d.ts +79 -0
- package/dist/server/process-memory-tracker.js +194 -0
- package/dist/server/process-memory-tracker.js.map +1 -0
- package/dist/server/register-scheduler.d.ts +53 -0
- package/dist/server/register-scheduler.js +36 -0
- package/dist/server/register-scheduler.js.map +1 -0
- package/dist/server/rex-gateway.d.ts +39 -0
- package/dist/server/rex-gateway.js +47 -0
- package/dist/server/rex-gateway.js.map +1 -0
- package/dist/server/routes-adaptive.d.ts +21 -0
- package/dist/server/routes-adaptive.js +659 -0
- package/dist/server/routes-adaptive.js.map +1 -0
- package/dist/server/routes-config.d.ts +47 -0
- package/dist/server/routes-config.js +222 -0
- package/dist/server/routes-config.js.map +1 -0
- package/dist/server/routes-data.d.ts +14 -0
- package/dist/server/routes-data.js +129 -0
- package/dist/server/routes-data.js.map +1 -0
- package/dist/server/routes-features.d.ts +14 -0
- package/dist/server/routes-features.js +245 -0
- package/dist/server/routes-features.js.map +1 -0
- package/dist/server/routes-hench.d.ts +116 -0
- package/dist/server/routes-hench.js +2016 -0
- package/dist/server/routes-hench.js.map +1 -0
- package/dist/server/routes-integrations.d.ts +23 -0
- package/dist/server/routes-integrations.js +277 -0
- package/dist/server/routes-integrations.js.map +1 -0
- package/dist/server/routes-mcp.d.ts +31 -0
- package/dist/server/routes-mcp.js +175 -0
- package/dist/server/routes-mcp.js.map +1 -0
- package/dist/server/routes-notion.d.ts +23 -0
- package/dist/server/routes-notion.js +723 -0
- package/dist/server/routes-notion.js.map +1 -0
- package/dist/server/routes-project.d.ts +47 -0
- package/dist/server/routes-project.js +128 -0
- package/dist/server/routes-project.js.map +1 -0
- package/dist/server/routes-rex/analysis.d.ts +11 -0
- package/dist/server/routes-rex/analysis.js +583 -0
- package/dist/server/routes-rex/analysis.js.map +1 -0
- package/dist/server/routes-rex/execution.d.ts +37 -0
- package/dist/server/routes-rex/execution.js +355 -0
- package/dist/server/routes-rex/execution.js.map +1 -0
- package/dist/server/routes-rex/health.d.ts +8 -0
- package/dist/server/routes-rex/health.js +136 -0
- package/dist/server/routes-rex/health.js.map +1 -0
- package/dist/server/routes-rex/index.d.ts +35 -0
- package/dist/server/routes-rex/index.js +72 -0
- package/dist/server/routes-rex/index.js.map +1 -0
- package/dist/server/routes-rex/items.d.ts +8 -0
- package/dist/server/routes-rex/items.js +359 -0
- package/dist/server/routes-rex/items.js.map +1 -0
- package/dist/server/routes-rex/prune.d.ts +11 -0
- package/dist/server/routes-rex/prune.js +379 -0
- package/dist/server/routes-rex/prune.js.map +1 -0
- package/dist/server/routes-rex/reads.d.ts +9 -0
- package/dist/server/routes-rex/reads.js +119 -0
- package/dist/server/routes-rex/reads.js.map +1 -0
- package/dist/server/routes-rex/requirements.d.ts +10 -0
- package/dist/server/routes-rex/requirements.js +408 -0
- package/dist/server/routes-rex/requirements.js.map +1 -0
- package/dist/server/routes-rex/shared.d.ts +37 -0
- package/dist/server/routes-rex/shared.js +73 -0
- package/dist/server/routes-rex/shared.js.map +1 -0
- package/dist/server/routes-search.d.ts +26 -0
- package/dist/server/routes-search.js +82 -0
- package/dist/server/routes-search.js.map +1 -0
- package/dist/server/routes-sourcevision.d.ts +18 -0
- package/dist/server/routes-sourcevision.js +444 -0
- package/dist/server/routes-sourcevision.js.map +1 -0
- package/dist/server/routes-static.d.ts +20 -0
- package/dist/server/routes-static.js +168 -0
- package/dist/server/routes-static.js.map +1 -0
- package/dist/server/routes-status.d.ts +58 -0
- package/dist/server/routes-status.js +191 -0
- package/dist/server/routes-status.js.map +1 -0
- package/dist/server/routes-token-usage.d.ts +63 -0
- package/dist/server/routes-token-usage.js +720 -0
- package/dist/server/routes-token-usage.js.map +1 -0
- package/dist/server/routes-validation.d.ts +10 -0
- package/dist/server/routes-validation.js +365 -0
- package/dist/server/routes-validation.js.map +1 -0
- package/dist/server/routes-workflow.d.ts +15 -0
- package/dist/server/routes-workflow.js +498 -0
- package/dist/server/routes-workflow.js.map +1 -0
- package/dist/server/search-index.d.ts +111 -0
- package/dist/server/search-index.js +348 -0
- package/dist/server/search-index.js.map +1 -0
- package/dist/server/shared-types.d.ts +65 -0
- package/dist/server/shared-types.js +31 -0
- package/dist/server/shared-types.js.map +1 -0
- package/dist/server/start.d.ts +68 -0
- package/dist/server/start.js +568 -0
- package/dist/server/start.js.map +1 -0
- package/dist/server/task-usage.d.ts +17 -0
- package/dist/server/task-usage.js +20 -0
- package/dist/server/task-usage.js.map +1 -0
- package/dist/server/types.d.ts +27 -0
- package/dist/server/types.js +26 -0
- package/dist/server/types.js.map +1 -0
- package/dist/server/usage-cleanup-scheduler.d.ts +107 -0
- package/dist/server/usage-cleanup-scheduler.js +232 -0
- package/dist/server/usage-cleanup-scheduler.js.map +1 -0
- package/dist/server/websocket.d.ts +131 -0
- package/dist/server/websocket.js +512 -0
- package/dist/server/websocket.js.map +1 -0
- package/dist/shared/data-files.d.ts +17 -0
- package/dist/shared/data-files.js +18 -0
- package/dist/shared/data-files.js.map +1 -0
- package/dist/shared/index.d.ts +9 -0
- package/dist/shared/index.js +9 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/view-id.d.ts +8 -0
- package/dist/shared/view-id.js +9 -0
- package/dist/shared/view-id.js.map +1 -0
- package/dist/viewer/Hench-F.png +0 -0
- package/dist/viewer/Rex-F.png +0 -0
- package/dist/viewer/SourceVision-F.png +0 -0
- package/dist/viewer/SourceVision.png +0 -0
- package/dist/viewer/api.d.ts +19 -0
- package/dist/viewer/api.js +17 -0
- package/dist/viewer/api.js.map +1 -0
- package/dist/viewer/bootstrap.d.ts +13 -0
- package/dist/viewer/bootstrap.js +40 -0
- package/dist/viewer/bootstrap.js.map +1 -0
- package/dist/viewer/components/active-tasks-panel.d.ts +36 -0
- package/dist/viewer/components/active-tasks-panel.js +183 -0
- package/dist/viewer/components/active-tasks-panel.js.map +1 -0
- package/dist/viewer/components/breadcrumb.d.ts +21 -0
- package/dist/viewer/components/breadcrumb.js +117 -0
- package/dist/viewer/components/breadcrumb.js.map +1 -0
- package/dist/viewer/components/concurrency-panel.d.ts +18 -0
- package/dist/viewer/components/concurrency-panel.js +175 -0
- package/dist/viewer/components/concurrency-panel.js.map +1 -0
- package/dist/viewer/components/config-footer.d.ts +11 -0
- package/dist/viewer/components/config-footer.js +132 -0
- package/dist/viewer/components/config-footer.js.map +1 -0
- package/dist/viewer/components/constants.d.ts +10 -0
- package/dist/viewer/components/constants.js +11 -0
- package/dist/viewer/components/constants.js.map +1 -0
- package/dist/viewer/components/copy-link-button.d.ts +30 -0
- package/dist/viewer/components/copy-link-button.js +74 -0
- package/dist/viewer/components/copy-link-button.js.map +1 -0
- package/dist/viewer/components/crash-recovery-banner.d.ts +28 -0
- package/dist/viewer/components/crash-recovery-banner.js +47 -0
- package/dist/viewer/components/crash-recovery-banner.js.map +1 -0
- package/dist/viewer/components/data-display/collapsible-section.d.ts +14 -0
- package/dist/viewer/components/data-display/collapsible-section.js +66 -0
- package/dist/viewer/components/data-display/collapsible-section.js.map +1 -0
- package/dist/viewer/components/data-display/findings-list.d.ts +13 -0
- package/dist/viewer/components/data-display/findings-list.js +136 -0
- package/dist/viewer/components/data-display/findings-list.js.map +1 -0
- package/dist/viewer/components/data-display/health-gauge.d.ts +37 -0
- package/dist/viewer/components/data-display/health-gauge.js +62 -0
- package/dist/viewer/components/data-display/health-gauge.js.map +1 -0
- package/dist/viewer/components/data-display/mini-charts.d.ts +36 -0
- package/dist/viewer/components/data-display/mini-charts.js +124 -0
- package/dist/viewer/components/data-display/mini-charts.js.map +1 -0
- package/dist/viewer/components/data-display/tree-view.d.ts +18 -0
- package/dist/viewer/components/data-display/tree-view.js +107 -0
- package/dist/viewer/components/data-display/tree-view.js.map +1 -0
- package/dist/viewer/components/data-display/zone-map.d.ts +28 -0
- package/dist/viewer/components/data-display/zone-map.js +197 -0
- package/dist/viewer/components/data-display/zone-map.js.map +1 -0
- package/dist/viewer/components/degradation-banner.d.ts +28 -0
- package/dist/viewer/components/degradation-banner.js +47 -0
- package/dist/viewer/components/degradation-banner.js.map +1 -0
- package/dist/viewer/components/detail-panel.d.ts +12 -0
- package/dist/viewer/components/detail-panel.js +166 -0
- package/dist/viewer/components/detail-panel.js.map +1 -0
- package/dist/viewer/components/elapsed-time.d.ts +38 -0
- package/dist/viewer/components/elapsed-time.js +35 -0
- package/dist/viewer/components/elapsed-time.js.map +1 -0
- package/dist/viewer/components/faq.d.ts +12 -0
- package/dist/viewer/components/faq.js +237 -0
- package/dist/viewer/components/faq.js.map +1 -0
- package/dist/viewer/components/favicon.d.ts +30 -0
- package/dist/viewer/components/favicon.js +90 -0
- package/dist/viewer/components/favicon.js.map +1 -0
- package/dist/viewer/components/guide.d.ts +5 -0
- package/dist/viewer/components/guide.js +116 -0
- package/dist/viewer/components/guide.js.map +1 -0
- package/dist/viewer/components/index.d.ts +37 -0
- package/dist/viewer/components/index.js +46 -0
- package/dist/viewer/components/index.js.map +1 -0
- package/dist/viewer/components/logos.d.ts +42 -0
- package/dist/viewer/components/logos.js +46 -0
- package/dist/viewer/components/logos.js.map +1 -0
- package/dist/viewer/components/memory-panel.d.ts +19 -0
- package/dist/viewer/components/memory-panel.js +181 -0
- package/dist/viewer/components/memory-panel.js.map +1 -0
- package/dist/viewer/components/memory-warning.d.ts +23 -0
- package/dist/viewer/components/memory-warning.js +42 -0
- package/dist/viewer/components/memory-warning.js.map +1 -0
- package/dist/viewer/components/notion-schema-wizard.d.ts +16 -0
- package/dist/viewer/components/notion-schema-wizard.js +263 -0
- package/dist/viewer/components/notion-schema-wizard.js.map +1 -0
- package/dist/viewer/components/polling-suspension-indicator.d.ts +24 -0
- package/dist/viewer/components/polling-suspension-indicator.js +31 -0
- package/dist/viewer/components/polling-suspension-indicator.js.map +1 -0
- package/dist/viewer/components/prd-tree/add-item-form.d.ts +31 -0
- package/dist/viewer/components/prd-tree/add-item-form.js +231 -0
- package/dist/viewer/components/prd-tree/add-item-form.js.map +1 -0
- package/dist/viewer/components/prd-tree/analyze-panel.d.ts +13 -0
- package/dist/viewer/components/prd-tree/analyze-panel.js +245 -0
- package/dist/viewer/components/prd-tree/analyze-panel.js.map +1 -0
- package/dist/viewer/components/prd-tree/batch-import-panel.d.ts +34 -0
- package/dist/viewer/components/prd-tree/batch-import-panel.js +415 -0
- package/dist/viewer/components/prd-tree/batch-import-panel.js.map +1 -0
- package/dist/viewer/components/prd-tree/bulk-actions.d.ts +19 -0
- package/dist/viewer/components/prd-tree/bulk-actions.js +90 -0
- package/dist/viewer/components/prd-tree/bulk-actions.js.map +1 -0
- package/dist/viewer/components/prd-tree/compute.d.ts +32 -0
- package/dist/viewer/components/prd-tree/compute.js +129 -0
- package/dist/viewer/components/prd-tree/compute.js.map +1 -0
- package/dist/viewer/components/prd-tree/delete-confirmation.d.ts +23 -0
- package/dist/viewer/components/prd-tree/delete-confirmation.js +83 -0
- package/dist/viewer/components/prd-tree/delete-confirmation.js.map +1 -0
- package/dist/viewer/components/prd-tree/execution-panel.d.ts +14 -0
- package/dist/viewer/components/prd-tree/execution-panel.js +291 -0
- package/dist/viewer/components/prd-tree/execution-panel.js.map +1 -0
- package/dist/viewer/components/prd-tree/facet-filter.d.ts +40 -0
- package/dist/viewer/components/prd-tree/facet-filter.js +188 -0
- package/dist/viewer/components/prd-tree/facet-filter.js.map +1 -0
- package/dist/viewer/components/prd-tree/index.d.ts +24 -0
- package/dist/viewer/components/prd-tree/index.js +16 -0
- package/dist/viewer/components/prd-tree/index.js.map +1 -0
- package/dist/viewer/components/prd-tree/inline-add-form.d.ts +32 -0
- package/dist/viewer/components/prd-tree/inline-add-form.js +175 -0
- package/dist/viewer/components/prd-tree/inline-add-form.js.map +1 -0
- package/dist/viewer/components/prd-tree/inline-status-picker.d.ts +31 -0
- package/dist/viewer/components/prd-tree/inline-status-picker.js +110 -0
- package/dist/viewer/components/prd-tree/inline-status-picker.js.map +1 -0
- package/dist/viewer/components/prd-tree/lazy-children.d.ts +40 -0
- package/dist/viewer/components/prd-tree/lazy-children.js +73 -0
- package/dist/viewer/components/prd-tree/lazy-children.js.map +1 -0
- package/dist/viewer/components/prd-tree/levels.d.ts +31 -0
- package/dist/viewer/components/prd-tree/levels.js +72 -0
- package/dist/viewer/components/prd-tree/levels.js.map +1 -0
- package/dist/viewer/components/prd-tree/listener-lifecycle.d.ts +105 -0
- package/dist/viewer/components/prd-tree/listener-lifecycle.js +173 -0
- package/dist/viewer/components/prd-tree/listener-lifecycle.js.map +1 -0
- package/dist/viewer/components/prd-tree/merge-preview.d.ts +25 -0
- package/dist/viewer/components/prd-tree/merge-preview.js +181 -0
- package/dist/viewer/components/prd-tree/merge-preview.js.map +1 -0
- package/dist/viewer/components/prd-tree/prd-tree.d.ts +91 -0
- package/dist/viewer/components/prd-tree/prd-tree.js +565 -0
- package/dist/viewer/components/prd-tree/prd-tree.js.map +1 -0
- package/dist/viewer/components/prd-tree/proposal-editor.d.ts +44 -0
- package/dist/viewer/components/prd-tree/proposal-editor.js +438 -0
- package/dist/viewer/components/prd-tree/proposal-editor.js.map +1 -0
- package/dist/viewer/components/prd-tree/prune-confirmation.d.ts +25 -0
- package/dist/viewer/components/prd-tree/prune-confirmation.js +336 -0
- package/dist/viewer/components/prd-tree/prune-confirmation.js.map +1 -0
- package/dist/viewer/components/prd-tree/prune-diff-tree.d.ts +39 -0
- package/dist/viewer/components/prd-tree/prune-diff-tree.js +319 -0
- package/dist/viewer/components/prd-tree/prune-diff-tree.js.map +1 -0
- package/dist/viewer/components/prd-tree/reorganize-panel.d.ts +16 -0
- package/dist/viewer/components/prd-tree/reorganize-panel.js +213 -0
- package/dist/viewer/components/prd-tree/reorganize-panel.js.map +1 -0
- package/dist/viewer/components/prd-tree/smart-add-input.d.ts +19 -0
- package/dist/viewer/components/prd-tree/smart-add-input.js +383 -0
- package/dist/viewer/components/prd-tree/smart-add-input.js.map +1 -0
- package/dist/viewer/components/prd-tree/status-filter.d.ts +40 -0
- package/dist/viewer/components/prd-tree/status-filter.js +131 -0
- package/dist/viewer/components/prd-tree/status-filter.js.map +1 -0
- package/dist/viewer/components/prd-tree/task-detail.d.ts +41 -0
- package/dist/viewer/components/prd-tree/task-detail.js +1205 -0
- package/dist/viewer/components/prd-tree/task-detail.js.map +1 -0
- package/dist/viewer/components/prd-tree/task-utilization.d.ts +7 -0
- package/dist/viewer/components/prd-tree/task-utilization.js +25 -0
- package/dist/viewer/components/prd-tree/task-utilization.js.map +1 -0
- package/dist/viewer/components/prd-tree/tree-differ.d.ts +59 -0
- package/dist/viewer/components/prd-tree/tree-differ.js +200 -0
- package/dist/viewer/components/prd-tree/tree-differ.js.map +1 -0
- package/dist/viewer/components/prd-tree/tree-event-delegate.d.ts +70 -0
- package/dist/viewer/components/prd-tree/tree-event-delegate.js +176 -0
- package/dist/viewer/components/prd-tree/tree-event-delegate.js.map +1 -0
- package/dist/viewer/components/prd-tree/tree-search.d.ts +65 -0
- package/dist/viewer/components/prd-tree/tree-search.js +178 -0
- package/dist/viewer/components/prd-tree/tree-search.js.map +1 -0
- package/dist/viewer/components/prd-tree/tree-utils.d.ts +38 -0
- package/dist/viewer/components/prd-tree/tree-utils.js +107 -0
- package/dist/viewer/components/prd-tree/tree-utils.js.map +1 -0
- package/dist/viewer/components/prd-tree/types.d.ts +93 -0
- package/dist/viewer/components/prd-tree/types.js +16 -0
- package/dist/viewer/components/prd-tree/types.js.map +1 -0
- package/dist/viewer/components/prd-tree/virtual-scroll.d.ts +119 -0
- package/dist/viewer/components/prd-tree/virtual-scroll.js +169 -0
- package/dist/viewer/components/prd-tree/virtual-scroll.js.map +1 -0
- package/dist/viewer/components/progressive-loader.d.ts +114 -0
- package/dist/viewer/components/progressive-loader.js +225 -0
- package/dist/viewer/components/progressive-loader.js.map +1 -0
- package/dist/viewer/components/refresh-queue-status.d.ts +20 -0
- package/dist/viewer/components/refresh-queue-status.js +65 -0
- package/dist/viewer/components/refresh-queue-status.js.map +1 -0
- package/dist/viewer/components/rex-task-link.d.ts +50 -0
- package/dist/viewer/components/rex-task-link.js +218 -0
- package/dist/viewer/components/rex-task-link.js.map +1 -0
- package/dist/viewer/components/search-filter.d.ts +20 -0
- package/dist/viewer/components/search-filter.js +28 -0
- package/dist/viewer/components/search-filter.js.map +1 -0
- package/dist/viewer/components/search-overlay.d.ts +31 -0
- package/dist/viewer/components/search-overlay.js +472 -0
- package/dist/viewer/components/search-overlay.js.map +1 -0
- package/dist/viewer/components/sidebar.d.ts +18 -0
- package/dist/viewer/components/sidebar.js +357 -0
- package/dist/viewer/components/sidebar.js.map +1 -0
- package/dist/viewer/components/status-indicators.d.ts +63 -0
- package/dist/viewer/components/status-indicators.js +136 -0
- package/dist/viewer/components/status-indicators.js.map +1 -0
- package/dist/viewer/components/theme-toggle.d.ts +8 -0
- package/dist/viewer/components/theme-toggle.js +28 -0
- package/dist/viewer/components/theme-toggle.js.map +1 -0
- package/dist/viewer/components/throttle-controls.d.ts +18 -0
- package/dist/viewer/components/throttle-controls.js +304 -0
- package/dist/viewer/components/throttle-controls.js.map +1 -0
- package/dist/viewer/components/ws-health-panel.d.ts +18 -0
- package/dist/viewer/components/ws-health-panel.js +250 -0
- package/dist/viewer/components/ws-health-panel.js.map +1 -0
- package/dist/viewer/components/zone-slideout.d.ts +17 -0
- package/dist/viewer/components/zone-slideout.js +162 -0
- package/dist/viewer/components/zone-slideout.js.map +1 -0
- package/dist/viewer/crash/crash-detector.d.ts +69 -0
- package/dist/viewer/crash/crash-detector.js +239 -0
- package/dist/viewer/crash/crash-detector.js.map +1 -0
- package/dist/viewer/crash/index.d.ts +7 -0
- package/dist/viewer/crash/index.js +8 -0
- package/dist/viewer/crash/index.js.map +1 -0
- package/dist/viewer/deployed-mode.d.ts +37 -0
- package/dist/viewer/deployed-mode.js +94 -0
- package/dist/viewer/deployed-mode.js.map +1 -0
- package/dist/viewer/external.d.ts +17 -0
- package/dist/viewer/external.js +17 -0
- package/dist/viewer/external.js.map +1 -0
- package/dist/viewer/graph/index.d.ts +9 -0
- package/dist/viewer/graph/index.js +12 -0
- package/dist/viewer/graph/index.js.map +1 -0
- package/dist/viewer/graph/physics.d.ts +96 -0
- package/dist/viewer/graph/physics.js +366 -0
- package/dist/viewer/graph/physics.js.map +1 -0
- package/dist/viewer/graph/renderer.d.ts +184 -0
- package/dist/viewer/graph/renderer.js +1438 -0
- package/dist/viewer/graph/renderer.js.map +1 -0
- package/dist/viewer/hooks/index.d.ts +27 -0
- package/dist/viewer/hooks/index.js +28 -0
- package/dist/viewer/hooks/index.js.map +1 -0
- package/dist/viewer/hooks/use-app-data.d.ts +31 -0
- package/dist/viewer/hooks/use-app-data.js +152 -0
- package/dist/viewer/hooks/use-app-data.js.map +1 -0
- package/dist/viewer/hooks/use-crash-recovery.d.ts +50 -0
- package/dist/viewer/hooks/use-crash-recovery.js +76 -0
- package/dist/viewer/hooks/use-crash-recovery.js.map +1 -0
- package/dist/viewer/hooks/use-delete-actions.d.ts +48 -0
- package/dist/viewer/hooks/use-delete-actions.js +103 -0
- package/dist/viewer/hooks/use-delete-actions.js.map +1 -0
- package/dist/viewer/hooks/use-dom-performance-monitor.d.ts +68 -0
- package/dist/viewer/hooks/use-dom-performance-monitor.js +71 -0
- package/dist/viewer/hooks/use-dom-performance-monitor.js.map +1 -0
- package/dist/viewer/hooks/use-facet-state.d.ts +32 -0
- package/dist/viewer/hooks/use-facet-state.js +119 -0
- package/dist/viewer/hooks/use-facet-state.js.map +1 -0
- package/dist/viewer/hooks/use-feature-toggle.d.ts +18 -0
- package/dist/viewer/hooks/use-feature-toggle.js +57 -0
- package/dist/viewer/hooks/use-feature-toggle.js.map +1 -0
- package/dist/viewer/hooks/use-file-edges.d.ts +23 -0
- package/dist/viewer/hooks/use-file-edges.js +221 -0
- package/dist/viewer/hooks/use-file-edges.js.map +1 -0
- package/dist/viewer/hooks/use-graceful-degradation.d.ts +30 -0
- package/dist/viewer/hooks/use-graceful-degradation.js +45 -0
- package/dist/viewer/hooks/use-graceful-degradation.js.map +1 -0
- package/dist/viewer/hooks/use-item-selection.d.ts +49 -0
- package/dist/viewer/hooks/use-item-selection.js +117 -0
- package/dist/viewer/hooks/use-item-selection.js.map +1 -0
- package/dist/viewer/hooks/use-memory-monitor.d.ts +39 -0
- package/dist/viewer/hooks/use-memory-monitor.js +73 -0
- package/dist/viewer/hooks/use-memory-monitor.js.map +1 -0
- package/dist/viewer/hooks/use-pan-zoom.d.ts +33 -0
- package/dist/viewer/hooks/use-pan-zoom.js +110 -0
- package/dist/viewer/hooks/use-pan-zoom.js.map +1 -0
- package/dist/viewer/hooks/use-persistent-filter.d.ts +24 -0
- package/dist/viewer/hooks/use-persistent-filter.js +37 -0
- package/dist/viewer/hooks/use-persistent-filter.js.map +1 -0
- package/dist/viewer/hooks/use-polling-suspension.d.ts +32 -0
- package/dist/viewer/hooks/use-polling-suspension.js +41 -0
- package/dist/viewer/hooks/use-polling-suspension.js.map +1 -0
- package/dist/viewer/hooks/use-polling.d.ts +39 -0
- package/dist/viewer/hooks/use-polling.js +55 -0
- package/dist/viewer/hooks/use-polling.js.map +1 -0
- package/dist/viewer/hooks/use-prd-actions.d.ts +126 -0
- package/dist/viewer/hooks/use-prd-actions.js +250 -0
- package/dist/viewer/hooks/use-prd-actions.js.map +1 -0
- package/dist/viewer/hooks/use-prd-data.d.ts +45 -0
- package/dist/viewer/hooks/use-prd-data.js +159 -0
- package/dist/viewer/hooks/use-prd-data.js.map +1 -0
- package/dist/viewer/hooks/use-prd-deep-link.d.ts +45 -0
- package/dist/viewer/hooks/use-prd-deep-link.js +60 -0
- package/dist/viewer/hooks/use-prd-deep-link.js.map +1 -0
- package/dist/viewer/hooks/use-prd-websocket.d.ts +47 -0
- package/dist/viewer/hooks/use-prd-websocket.js +139 -0
- package/dist/viewer/hooks/use-prd-websocket.js.map +1 -0
- package/dist/viewer/hooks/use-project-metadata.d.ts +25 -0
- package/dist/viewer/hooks/use-project-metadata.js +55 -0
- package/dist/viewer/hooks/use-project-metadata.js.map +1 -0
- package/dist/viewer/hooks/use-project-status.d.ts +60 -0
- package/dist/viewer/hooks/use-project-status.js +133 -0
- package/dist/viewer/hooks/use-project-status.js.map +1 -0
- package/dist/viewer/hooks/use-refresh-throttle.d.ts +45 -0
- package/dist/viewer/hooks/use-refresh-throttle.js +52 -0
- package/dist/viewer/hooks/use-refresh-throttle.js.map +1 -0
- package/dist/viewer/hooks/use-route-state.d.ts +18 -0
- package/dist/viewer/hooks/use-route-state.js +115 -0
- package/dist/viewer/hooks/use-route-state.js.map +1 -0
- package/dist/viewer/hooks/use-subzone-edges.d.ts +21 -0
- package/dist/viewer/hooks/use-subzone-edges.js +147 -0
- package/dist/viewer/hooks/use-subzone-edges.js.map +1 -0
- package/dist/viewer/hooks/use-tab-visibility.d.ts +31 -0
- package/dist/viewer/hooks/use-tab-visibility.js +43 -0
- package/dist/viewer/hooks/use-tab-visibility.js.map +1 -0
- package/dist/viewer/hooks/use-tick.d.ts +43 -0
- package/dist/viewer/hooks/use-tick.js +76 -0
- package/dist/viewer/hooks/use-tick.js.map +1 -0
- package/dist/viewer/hooks/use-toast.d.ts +24 -0
- package/dist/viewer/hooks/use-toast.js +26 -0
- package/dist/viewer/hooks/use-toast.js.map +1 -0
- package/dist/viewer/hooks/use-zone-drag.d.ts +30 -0
- package/dist/viewer/hooks/use-zone-drag.js +60 -0
- package/dist/viewer/hooks/use-zone-drag.js.map +1 -0
- package/dist/viewer/index.html +36 -0
- package/dist/viewer/loader.d.ts +33 -0
- package/dist/viewer/loader.js +195 -0
- package/dist/viewer/loader.js.map +1 -0
- package/dist/viewer/main.d.ts +1 -0
- package/dist/viewer/main.js +121 -0
- package/dist/viewer/main.js.map +1 -0
- package/dist/viewer/messaging/call-rate-limiter.d.ts +50 -0
- package/dist/viewer/messaging/call-rate-limiter.js +103 -0
- package/dist/viewer/messaging/call-rate-limiter.js.map +1 -0
- package/dist/viewer/messaging/fetch-pipeline.d.ts +58 -0
- package/dist/viewer/messaging/fetch-pipeline.js +58 -0
- package/dist/viewer/messaging/fetch-pipeline.js.map +1 -0
- package/dist/viewer/messaging/index.d.ts +43 -0
- package/dist/viewer/messaging/index.js +46 -0
- package/dist/viewer/messaging/index.js.map +1 -0
- package/dist/viewer/messaging/message-coalescer.d.ts +96 -0
- package/dist/viewer/messaging/message-coalescer.js +121 -0
- package/dist/viewer/messaging/message-coalescer.js.map +1 -0
- package/dist/viewer/messaging/message-throttle.d.ts +95 -0
- package/dist/viewer/messaging/message-throttle.js +147 -0
- package/dist/viewer/messaging/message-throttle.js.map +1 -0
- package/dist/viewer/messaging/request-dedup.d.ts +43 -0
- package/dist/viewer/messaging/request-dedup.js +55 -0
- package/dist/viewer/messaging/request-dedup.js.map +1 -0
- package/dist/viewer/messaging/ws-pipeline.d.ts +85 -0
- package/dist/viewer/messaging/ws-pipeline.js +68 -0
- package/dist/viewer/messaging/ws-pipeline.js.map +1 -0
- package/dist/viewer/n-dx.png +0 -0
- package/dist/viewer/performance/dom-performance-monitor.d.ts +157 -0
- package/dist/viewer/performance/dom-performance-monitor.js +341 -0
- package/dist/viewer/performance/dom-performance-monitor.js.map +1 -0
- package/dist/viewer/performance/dom-update-gate.d.ts +122 -0
- package/dist/viewer/performance/dom-update-gate.js +229 -0
- package/dist/viewer/performance/dom-update-gate.js.map +1 -0
- package/dist/viewer/performance/graceful-degradation.d.ts +73 -0
- package/dist/viewer/performance/graceful-degradation.js +152 -0
- package/dist/viewer/performance/graceful-degradation.js.map +1 -0
- package/dist/viewer/performance/index.d.ts +14 -0
- package/dist/viewer/performance/index.js +20 -0
- package/dist/viewer/performance/index.js.map +1 -0
- package/dist/viewer/performance/memory-monitor.d.ts +78 -0
- package/dist/viewer/performance/memory-monitor.js +218 -0
- package/dist/viewer/performance/memory-monitor.js.map +1 -0
- package/dist/viewer/performance/refresh-throttle.d.ts +90 -0
- package/dist/viewer/performance/refresh-throttle.js +266 -0
- package/dist/viewer/performance/refresh-throttle.js.map +1 -0
- package/dist/viewer/performance/response-buffer-gate.d.ts +108 -0
- package/dist/viewer/performance/response-buffer-gate.js +170 -0
- package/dist/viewer/performance/response-buffer-gate.js.map +1 -0
- package/dist/viewer/performance/update-batcher.d.ts +79 -0
- package/dist/viewer/performance/update-batcher.js +119 -0
- package/dist/viewer/performance/update-batcher.js.map +1 -0
- package/dist/viewer/polling/batched-tick-dispatcher.d.ts +83 -0
- package/dist/viewer/polling/batched-tick-dispatcher.js +183 -0
- package/dist/viewer/polling/batched-tick-dispatcher.js.map +1 -0
- package/dist/viewer/polling/index.d.ts +13 -0
- package/dist/viewer/polling/index.js +16 -0
- package/dist/viewer/polling/index.js.map +1 -0
- package/dist/viewer/polling/polling-manager.d.ts +82 -0
- package/dist/viewer/polling/polling-manager.js +254 -0
- package/dist/viewer/polling/polling-manager.js.map +1 -0
- package/dist/viewer/polling/polling-restart.d.ts +45 -0
- package/dist/viewer/polling/polling-restart.js +98 -0
- package/dist/viewer/polling/polling-restart.js.map +1 -0
- package/dist/viewer/polling/polling-state.d.ts +182 -0
- package/dist/viewer/polling/polling-state.js +306 -0
- package/dist/viewer/polling/polling-state.js.map +1 -0
- package/dist/viewer/polling/tab-visibility.d.ts +112 -0
- package/dist/viewer/polling/tab-visibility.js +276 -0
- package/dist/viewer/polling/tab-visibility.js.map +1 -0
- package/dist/viewer/polling/tick-timer.d.ts +70 -0
- package/dist/viewer/polling/tick-timer.js +168 -0
- package/dist/viewer/polling/tick-timer.js.map +1 -0
- package/dist/viewer/polling/tick-visibility-gate.d.ts +92 -0
- package/dist/viewer/polling/tick-visibility-gate.js +146 -0
- package/dist/viewer/polling/tick-visibility-gate.js.map +1 -0
- package/dist/viewer/route-state.d.ts +8 -0
- package/dist/viewer/route-state.js +77 -0
- package/dist/viewer/route-state.js.map +1 -0
- package/dist/viewer/schema-compat.d.ts +17 -0
- package/dist/viewer/schema-compat.js +49 -0
- package/dist/viewer/schema-compat.js.map +1 -0
- package/dist/viewer/types.d.ts +66 -0
- package/dist/viewer/types.js +2 -0
- package/dist/viewer/types.js.map +1 -0
- package/dist/viewer/usage/constants.d.ts +14 -0
- package/dist/viewer/usage/constants.js +14 -0
- package/dist/viewer/usage/constants.js.map +1 -0
- package/dist/viewer/usage/index.d.ts +7 -0
- package/dist/viewer/usage/index.js +8 -0
- package/dist/viewer/usage/index.js.map +1 -0
- package/dist/viewer/utils.d.ts +25 -0
- package/dist/viewer/utils.js +48 -0
- package/dist/viewer/utils.js.map +1 -0
- package/dist/viewer/validate.d.ts +23 -0
- package/dist/viewer/validate.js +275 -0
- package/dist/viewer/validate.js.map +1 -0
- package/dist/viewer/views/analysis.d.ts +10 -0
- package/dist/viewer/views/analysis.js +109 -0
- package/dist/viewer/views/analysis.js.map +1 -0
- package/dist/viewer/views/architecture.d.ts +10 -0
- package/dist/viewer/views/architecture.js +44 -0
- package/dist/viewer/views/architecture.js.map +1 -0
- package/dist/viewer/views/domain-hench.d.ts +13 -0
- package/dist/viewer/views/domain-hench.js +14 -0
- package/dist/viewer/views/domain-hench.js.map +1 -0
- package/dist/viewer/views/domain-rex.d.ts +17 -0
- package/dist/viewer/views/domain-rex.js +18 -0
- package/dist/viewer/views/domain-rex.js.map +1 -0
- package/dist/viewer/views/domain-settings.d.ts +12 -0
- package/dist/viewer/views/domain-settings.js +13 -0
- package/dist/viewer/views/domain-settings.js.map +1 -0
- package/dist/viewer/views/domain-sourcevision.d.ts +20 -0
- package/dist/viewer/views/domain-sourcevision.js +21 -0
- package/dist/viewer/views/domain-sourcevision.js.map +1 -0
- package/dist/viewer/views/enrichment-thresholds.d.ts +11 -0
- package/dist/viewer/views/enrichment-thresholds.js +12 -0
- package/dist/viewer/views/enrichment-thresholds.js.map +1 -0
- package/dist/viewer/views/feature-toggles.d.ts +13 -0
- package/dist/viewer/views/feature-toggles.js +185 -0
- package/dist/viewer/views/feature-toggles.js.map +1 -0
- package/dist/viewer/views/files.d.ts +13 -0
- package/dist/viewer/views/files.js +174 -0
- package/dist/viewer/views/files.js.map +1 -0
- package/dist/viewer/views/graph.d.ts +12 -0
- package/dist/viewer/views/graph.js +316 -0
- package/dist/viewer/views/graph.js.map +1 -0
- package/dist/viewer/views/hench-config.d.ts +39 -0
- package/dist/viewer/views/hench-config.js +473 -0
- package/dist/viewer/views/hench-config.js.map +1 -0
- package/dist/viewer/views/hench-runs.d.ts +19 -0
- package/dist/viewer/views/hench-runs.js +460 -0
- package/dist/viewer/views/hench-runs.js.map +1 -0
- package/dist/viewer/views/hench-templates.d.ts +17 -0
- package/dist/viewer/views/hench-templates.js +262 -0
- package/dist/viewer/views/hench-templates.js.map +1 -0
- package/dist/viewer/views/integration-config.d.ts +73 -0
- package/dist/viewer/views/integration-config.js +524 -0
- package/dist/viewer/views/integration-config.js.map +1 -0
- package/dist/viewer/views/notion-config.d.ts +16 -0
- package/dist/viewer/views/notion-config.js +357 -0
- package/dist/viewer/views/notion-config.js.map +1 -0
- package/dist/viewer/views/overview.d.ts +10 -0
- package/dist/viewer/views/overview.js +187 -0
- package/dist/viewer/views/overview.js.map +1 -0
- package/dist/viewer/views/pr-markdown.d.ts +3 -0
- package/dist/viewer/views/pr-markdown.js +350 -0
- package/dist/viewer/views/pr-markdown.js.map +1 -0
- package/dist/viewer/views/prd.d.ts +34 -0
- package/dist/viewer/views/prd.js +257 -0
- package/dist/viewer/views/prd.js.map +1 -0
- package/dist/viewer/views/problems.d.ts +8 -0
- package/dist/viewer/views/problems.js +50 -0
- package/dist/viewer/views/problems.js.map +1 -0
- package/dist/viewer/views/rex-dashboard.d.ts +14 -0
- package/dist/viewer/views/rex-dashboard.js +334 -0
- package/dist/viewer/views/rex-dashboard.js.map +1 -0
- package/dist/viewer/views/routes.d.ts +8 -0
- package/dist/viewer/views/routes.js +216 -0
- package/dist/viewer/views/routes.js.map +1 -0
- package/dist/viewer/views/sourcevision-tabs.d.ts +18 -0
- package/dist/viewer/views/sourcevision-tabs.js +14 -0
- package/dist/viewer/views/sourcevision-tabs.js.map +1 -0
- package/dist/viewer/views/suggestions.d.ts +8 -0
- package/dist/viewer/views/suggestions.js +36 -0
- package/dist/viewer/views/suggestions.js.map +1 -0
- package/dist/viewer/views/task-audit.d.ts +18 -0
- package/dist/viewer/views/task-audit.js +413 -0
- package/dist/viewer/views/task-audit.js.map +1 -0
- package/dist/viewer/views/token-usage.d.ts +10 -0
- package/dist/viewer/views/token-usage.js +410 -0
- package/dist/viewer/views/token-usage.js.map +1 -0
- package/dist/viewer/views/validation.d.ts +11 -0
- package/dist/viewer/views/validation.js +475 -0
- package/dist/viewer/views/validation.js.map +1 -0
- package/dist/viewer/views/view-registry.d.ts +27 -0
- package/dist/viewer/views/view-registry.js +70 -0
- package/dist/viewer/views/view-registry.js.map +1 -0
- package/dist/viewer/views/workflow-optimization.d.ts +12 -0
- package/dist/viewer/views/workflow-optimization.js +311 -0
- package/dist/viewer/views/workflow-optimization.js.map +1 -0
- package/dist/viewer/views/zone-types.d.ts +69 -0
- package/dist/viewer/views/zone-types.js +5 -0
- package/dist/viewer/views/zone-types.js.map +1 -0
- package/dist/viewer/views/zones.d.ts +50 -0
- package/dist/viewer/views/zones.js +1438 -0
- package/dist/viewer/views/zones.js.map +1 -0
- package/dist/viewer/visualization/colors.d.ts +16 -0
- package/dist/viewer/visualization/colors.js +31 -0
- package/dist/viewer/visualization/colors.js.map +1 -0
- package/dist/viewer/visualization/flow.d.ts +54 -0
- package/dist/viewer/visualization/flow.js +123 -0
- package/dist/viewer/visualization/flow.js.map +1 -0
- package/dist/viewer/visualization/index.d.ts +34 -0
- package/dist/viewer/visualization/index.js +40 -0
- package/dist/viewer/visualization/index.js.map +1 -0
- package/dist/viewer/visualization/metrics.d.ts +8 -0
- package/dist/viewer/visualization/metrics.js +16 -0
- package/dist/viewer/visualization/metrics.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data loader for sourcevision viewer.
|
|
3
|
+
* Fetches and validates .sourcevision/ JSON files.
|
|
4
|
+
* Supports both server mode (fetch from /data/) and file drop mode.
|
|
5
|
+
*
|
|
6
|
+
* Memory-efficient strategies:
|
|
7
|
+
* - loadModules(): lazy-load data files on demand in parallel
|
|
8
|
+
* - Selective refresh: only reload files whose mtime changed
|
|
9
|
+
*/
|
|
10
|
+
import type { LoadedData } from "./types.js";
|
|
11
|
+
type DataChangeHandler = (data: LoadedData) => void;
|
|
12
|
+
export declare function getData(): LoadedData;
|
|
13
|
+
export declare function onDataChange(handler: DataChangeHandler): void;
|
|
14
|
+
/** Remove the current data-change handler (for cleanup on unmount). */
|
|
15
|
+
export declare function clearOnChange(): void;
|
|
16
|
+
/**
|
|
17
|
+
* Lazy-load multiple modules in parallel. Only fetches modules that
|
|
18
|
+
* are not already loaded. Returns the current data state.
|
|
19
|
+
*/
|
|
20
|
+
export declare function loadModules(keys: Array<keyof LoadedData>): Promise<LoadedData>;
|
|
21
|
+
/** Load data from dropped files */
|
|
22
|
+
export declare function loadFromFiles(files: FileList): Promise<LoadedData>;
|
|
23
|
+
/** Check if we're running in server mode */
|
|
24
|
+
export declare function detectMode(): Promise<"server" | "static">;
|
|
25
|
+
/**
|
|
26
|
+
* Start polling for data changes (selective refresh — only changed files).
|
|
27
|
+
* Registers with the centralized polling manager for automatic
|
|
28
|
+
* suspend/resume based on tab visibility.
|
|
29
|
+
*/
|
|
30
|
+
export declare function startPolling(intervalMs?: number): void;
|
|
31
|
+
/** Stop polling for data changes */
|
|
32
|
+
export declare function stopPolling(): void;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data loader for sourcevision viewer.
|
|
3
|
+
* Fetches and validates .sourcevision/ JSON files.
|
|
4
|
+
* Supports both server mode (fetch from /data/) and file drop mode.
|
|
5
|
+
*
|
|
6
|
+
* Memory-efficient strategies:
|
|
7
|
+
* - loadModules(): lazy-load data files on demand in parallel
|
|
8
|
+
* - Selective refresh: only reload files whose mtime changed
|
|
9
|
+
*/
|
|
10
|
+
import { validateManifest, validateInventory, validateImports, validateZones, validateComponents, validateCallGraph, } from "./validate.js";
|
|
11
|
+
import { DATA_FILES } from "./external.js";
|
|
12
|
+
import { migrateData } from "./schema-compat.js";
|
|
13
|
+
import { registerPoller, unregisterPoller } from "./polling/polling-manager.js";
|
|
14
|
+
const MODULE_DEFS = [
|
|
15
|
+
{ key: "manifest", file: DATA_FILES.manifest, validate: validateManifest },
|
|
16
|
+
{ key: "inventory", file: DATA_FILES.inventory, validate: validateInventory },
|
|
17
|
+
{ key: "imports", file: DATA_FILES.imports, validate: validateImports },
|
|
18
|
+
{ key: "zones", file: DATA_FILES.zones, validate: validateZones },
|
|
19
|
+
{ key: "components", file: DATA_FILES.components, validate: validateComponents },
|
|
20
|
+
{ key: "callGraph", file: DATA_FILES.callGraph, validate: validateCallGraph },
|
|
21
|
+
];
|
|
22
|
+
/** Map from data filename to its module key, for selective refresh. */
|
|
23
|
+
const FILE_TO_KEY = {};
|
|
24
|
+
for (const mod of MODULE_DEFS) {
|
|
25
|
+
FILE_TO_KEY[mod.file] = mod.key;
|
|
26
|
+
}
|
|
27
|
+
let currentData = {
|
|
28
|
+
manifest: null,
|
|
29
|
+
inventory: null,
|
|
30
|
+
imports: null,
|
|
31
|
+
zones: null,
|
|
32
|
+
components: null,
|
|
33
|
+
callGraph: null,
|
|
34
|
+
};
|
|
35
|
+
let onChange = null;
|
|
36
|
+
let pollingActive = false;
|
|
37
|
+
let lastMtimes = {};
|
|
38
|
+
export function getData() {
|
|
39
|
+
return currentData;
|
|
40
|
+
}
|
|
41
|
+
export function onDataChange(handler) {
|
|
42
|
+
onChange = handler;
|
|
43
|
+
}
|
|
44
|
+
/** Remove the current data-change handler (for cleanup on unmount). */
|
|
45
|
+
export function clearOnChange() {
|
|
46
|
+
onChange = null;
|
|
47
|
+
}
|
|
48
|
+
function notifyChange() {
|
|
49
|
+
if (onChange)
|
|
50
|
+
onChange(currentData);
|
|
51
|
+
}
|
|
52
|
+
/** Fetch, validate, and store a single module. Returns true on success. */
|
|
53
|
+
async function fetchModule(mod) {
|
|
54
|
+
try {
|
|
55
|
+
const res = await fetch(`/data/${mod.file}`);
|
|
56
|
+
if (!res.ok)
|
|
57
|
+
return false;
|
|
58
|
+
const raw = await res.json();
|
|
59
|
+
const migrated = migrateData(mod.key, raw);
|
|
60
|
+
const result = mod.validate(migrated);
|
|
61
|
+
if (result.ok) {
|
|
62
|
+
currentData[mod.key] = result.data;
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
console.warn(`Validation failed for ${mod.file}:`, result);
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Lazy-load multiple modules in parallel. Only fetches modules that
|
|
74
|
+
* are not already loaded. Returns the current data state.
|
|
75
|
+
*/
|
|
76
|
+
export async function loadModules(keys) {
|
|
77
|
+
const toLoad = keys
|
|
78
|
+
.filter((key) => currentData[key] === null)
|
|
79
|
+
.map((key) => MODULE_DEFS.find((m) => m.key === key))
|
|
80
|
+
.filter((mod) => mod !== undefined);
|
|
81
|
+
if (toLoad.length > 0) {
|
|
82
|
+
await Promise.allSettled(toLoad.map((mod) => fetchModule(mod)));
|
|
83
|
+
notifyChange();
|
|
84
|
+
}
|
|
85
|
+
return currentData;
|
|
86
|
+
}
|
|
87
|
+
/** Load data from dropped files */
|
|
88
|
+
export async function loadFromFiles(files) {
|
|
89
|
+
const fileMap = new Map();
|
|
90
|
+
for (const f of files) {
|
|
91
|
+
fileMap.set(f.name, f);
|
|
92
|
+
}
|
|
93
|
+
for (const mod of MODULE_DEFS) {
|
|
94
|
+
const file = fileMap.get(mod.file);
|
|
95
|
+
if (!file)
|
|
96
|
+
continue;
|
|
97
|
+
try {
|
|
98
|
+
const text = await file.text();
|
|
99
|
+
const raw = JSON.parse(text);
|
|
100
|
+
const migrated = migrateData(mod.key, raw);
|
|
101
|
+
const result = mod.validate(migrated);
|
|
102
|
+
if (result.ok) {
|
|
103
|
+
currentData[mod.key] = result.data;
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
console.warn(`Validation failed for ${mod.file}:`, result);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
console.warn(`Failed to parse ${mod.file}:`, err);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
notifyChange();
|
|
114
|
+
return currentData;
|
|
115
|
+
}
|
|
116
|
+
/** Check if we're running in server mode */
|
|
117
|
+
export async function detectMode() {
|
|
118
|
+
try {
|
|
119
|
+
const res = await fetch("/data");
|
|
120
|
+
if (res.ok)
|
|
121
|
+
return "server";
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
// Not in server mode
|
|
125
|
+
}
|
|
126
|
+
return "static";
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Selectively reload only the data files whose mtime has changed.
|
|
130
|
+
* More memory-efficient than reloading all files on every change.
|
|
131
|
+
*/
|
|
132
|
+
async function refreshChangedModules(newMtimes) {
|
|
133
|
+
const changedKeys = [];
|
|
134
|
+
for (const [file, mtime] of Object.entries(newMtimes)) {
|
|
135
|
+
if (lastMtimes[file] !== mtime) {
|
|
136
|
+
const key = FILE_TO_KEY[file];
|
|
137
|
+
if (key) {
|
|
138
|
+
changedKeys.push(key);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (changedKeys.length === 0)
|
|
143
|
+
return;
|
|
144
|
+
lastMtimes = newMtimes;
|
|
145
|
+
// Only fetch the modules that actually changed
|
|
146
|
+
const toLoad = changedKeys
|
|
147
|
+
.map((key) => MODULE_DEFS.find((m) => m.key === key))
|
|
148
|
+
.filter((mod) => mod !== undefined);
|
|
149
|
+
if (toLoad.length > 0) {
|
|
150
|
+
await Promise.allSettled(toLoad.map((mod) => fetchModule(mod)));
|
|
151
|
+
notifyChange();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/** The polling callback, extracted for registration with the polling manager. */
|
|
155
|
+
async function pollForChanges() {
|
|
156
|
+
try {
|
|
157
|
+
const res = await fetch("/data/status");
|
|
158
|
+
if (!res.ok)
|
|
159
|
+
return;
|
|
160
|
+
const status = await res.json();
|
|
161
|
+
// Check if any file changed
|
|
162
|
+
let changed = false;
|
|
163
|
+
for (const [file, mtime] of Object.entries(status.mtimes)) {
|
|
164
|
+
if (lastMtimes[file] !== mtime) {
|
|
165
|
+
changed = true;
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (changed) {
|
|
170
|
+
await refreshChangedModules(status.mtimes);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
// Server may be down — ignore
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Start polling for data changes (selective refresh — only changed files).
|
|
179
|
+
* Registers with the centralized polling manager for automatic
|
|
180
|
+
* suspend/resume based on tab visibility.
|
|
181
|
+
*/
|
|
182
|
+
export function startPolling(intervalMs = 5000) {
|
|
183
|
+
if (pollingActive)
|
|
184
|
+
return;
|
|
185
|
+
pollingActive = true;
|
|
186
|
+
registerPoller("loader:data-status", pollForChanges, intervalMs);
|
|
187
|
+
}
|
|
188
|
+
/** Stop polling for data changes */
|
|
189
|
+
export function stopPolling() {
|
|
190
|
+
if (!pollingActive)
|
|
191
|
+
return;
|
|
192
|
+
pollingActive = false;
|
|
193
|
+
unregisterPoller("loader:data-status");
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/viewer/loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { h, render, Fragment } from "preact";
|
|
2
|
+
import { useState, useEffect, useMemo, useCallback } from "preact/hooks";
|
|
3
|
+
import { ALL_DATA_FILES } from "./external.js";
|
|
4
|
+
import { Sidebar, DetailPanel, Guide, Breadcrumb, updateFavicon, MemoryWarningBanner, CrashRecoveryBanner, DegradationBanner, RefreshQueueStatus, PollingSuspensionIndicator, SearchOverlay, useSearchOverlay, } from "./components/index.js";
|
|
5
|
+
import { useRouteState, useAppData, useMemoryMonitor, useCrashRecovery, useGracefulDegradation, useRefreshThrottle, usePollingSuspension, } from "./hooks/index.js";
|
|
6
|
+
import { bootstrap } from "./bootstrap.js";
|
|
7
|
+
import { renderActiveView, buildValidViews } from "./views/view-registry.js";
|
|
8
|
+
bootstrap();
|
|
9
|
+
/** Fetch viewer scope from the server config endpoint. */
|
|
10
|
+
async function fetchScope() {
|
|
11
|
+
try {
|
|
12
|
+
const res = await fetch("/api/config");
|
|
13
|
+
if (!res.ok)
|
|
14
|
+
return null;
|
|
15
|
+
const config = await res.json();
|
|
16
|
+
return config.scope ?? null;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const SIDEBAR_COLLAPSED_KEY = "sidebar-collapsed";
|
|
23
|
+
function getInitialSidebarCollapsed() {
|
|
24
|
+
try {
|
|
25
|
+
return localStorage.getItem(SIDEBAR_COLLAPSED_KEY) === "true";
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function App({ scope }) {
|
|
32
|
+
const validViews = useMemo(() => buildValidViews(scope), [scope]);
|
|
33
|
+
const { view, selectedFile, setSelectedFile, selectedZone, selectedRunId, selectedTaskId, navigateTo, handleSidebarNav, } = useRouteState(validViews);
|
|
34
|
+
const { snapshot: memorySnapshot, level: memoryLevel, showWarning: showMemoryWarning, dismiss: dismissMemoryWarning } = useMemoryMonitor();
|
|
35
|
+
const { tier: degradationTier, isDegraded, summary: degradationSummary, disabledFeatures, isDisabled: isFeatureDisabled, } = useGracefulDegradation();
|
|
36
|
+
const { state: refreshQueueState } = useRefreshThrottle();
|
|
37
|
+
const { isSuspended: pollingSuspended, suspendedCount: pollingSuspendedCount } = usePollingSuspension();
|
|
38
|
+
const [searchOpen, , closeSearch] = useSearchOverlay();
|
|
39
|
+
const { data, loading, refreshToast, showDrop } = useAppData({ pausePolling: isFeatureDisabled("autoRefresh") });
|
|
40
|
+
const { showRecovery, crashLoop, recentCrashCount, recoveredState, dismiss: dismissRecovery, restore: restoreCrashState, } = useCrashRecovery({ view, selectedFile, selectedZone, selectedRunId, selectedTaskId });
|
|
41
|
+
const [detail, setDetail] = useState(null);
|
|
42
|
+
const [degradationDismissed, setDegradationDismissed] = useState(false);
|
|
43
|
+
const [sidebarCollapsed, setSidebarCollapsed] = useState(getInitialSidebarCollapsed);
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
|
+
const [prdDetailContent, setPrdDetailContent] = useState(null);
|
|
46
|
+
const handleRestore = () => {
|
|
47
|
+
const state = restoreCrashState();
|
|
48
|
+
if (state) {
|
|
49
|
+
navigateTo(state.view, {
|
|
50
|
+
file: state.selectedFile ?? undefined,
|
|
51
|
+
zone: state.selectedZone ?? undefined,
|
|
52
|
+
runId: state.selectedRunId ?? undefined,
|
|
53
|
+
taskId: state.selectedTaskId ?? undefined,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const handleManualRefresh = useCallback(() => {
|
|
58
|
+
window.location.reload();
|
|
59
|
+
}, []);
|
|
60
|
+
const handleToggleSidebar = () => {
|
|
61
|
+
setSidebarCollapsed((prev) => {
|
|
62
|
+
const next = !prev;
|
|
63
|
+
try {
|
|
64
|
+
localStorage.setItem(SIDEBAR_COLLAPSED_KEY, String(next));
|
|
65
|
+
}
|
|
66
|
+
catch { /* noop */ }
|
|
67
|
+
return next;
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
// Re-show degradation banner when tier escalates
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (isDegraded)
|
|
73
|
+
setDegradationDismissed(false);
|
|
74
|
+
}, [degradationTier]);
|
|
75
|
+
// Toggle CSS animation suppression class when animations are degraded
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
const el = document.documentElement;
|
|
78
|
+
if (isFeatureDisabled("animations")) {
|
|
79
|
+
el.classList.add("degradation-no-animations");
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
el.classList.remove("degradation-no-animations");
|
|
83
|
+
}
|
|
84
|
+
return () => { el.classList.remove("degradation-no-animations"); };
|
|
85
|
+
}, [isFeatureDisabled]);
|
|
86
|
+
// Scroll to top on view change
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
document.getElementById("main-content")?.scrollTo(0, 0);
|
|
89
|
+
}, [view]);
|
|
90
|
+
// Update browser favicon to match the active product section
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
updateFavicon(view);
|
|
93
|
+
}, [view]);
|
|
94
|
+
const hasData = data.manifest || data.inventory || data.imports || data.zones;
|
|
95
|
+
// Show degradation banner when degraded and not already showing the memory warning (avoid stacking)
|
|
96
|
+
const showDegradationBanner = isDegraded && !degradationDismissed && !showMemoryWarning;
|
|
97
|
+
return h(Fragment, null, h(CrashRecoveryBanner, { visible: showRecovery, crashLoop, recentCrashCount, recoveredState, onDismiss: dismissRecovery, onRestore: handleRestore }), h(MemoryWarningBanner, { snapshot: memorySnapshot, level: memoryLevel, visible: showMemoryWarning, onDismiss: dismissMemoryWarning }), h(DegradationBanner, { tier: degradationTier, isDegraded, summary: degradationSummary, disabledFeatures, visible: showDegradationBanner, onDismiss: () => setDegradationDismissed(true) }), h("a", { href: "#main-content", class: "skip-link" }, "Skip to main content"), h(Sidebar, { view, onNavigate: handleSidebarNav, manifest: data.manifest, zones: data.zones, sidebarCollapsed, onToggleSidebar: handleToggleSidebar, scope }), h("main", {
|
|
98
|
+
id: "main-content",
|
|
99
|
+
class: "main",
|
|
100
|
+
role: "main",
|
|
101
|
+
"aria-label": "Main content",
|
|
102
|
+
},
|
|
103
|
+
// Page-context bar: breadcrumb navigation + help buttons
|
|
104
|
+
h("div", { class: "page-context-bar", role: "group", "aria-label": "Page navigation and help" }, h(Breadcrumb, { view, navigateTo, scope }), h("div", { class: "page-context-actions" }, h(Guide, { view }))), loading
|
|
105
|
+
? h("div", { class: "loading", role: "status", "aria-live": "polite" }, "Loading...")
|
|
106
|
+
: renderActiveView(view, { data, setDetail, setPrdDetailContent, selectedFile, setSelectedFile, selectedZone, selectedRunId, selectedTaskId, navigateTo, isFeatureDisabled })), !isFeatureDisabled("detailPanel")
|
|
107
|
+
? h(DetailPanel, { detail, data, navigateTo, onClose: () => { setDetail(null); setPrdDetailContent(null); }, prdDetailContent })
|
|
108
|
+
: null, (refreshToast && !isFeatureDisabled("autoRefresh"))
|
|
109
|
+
? h("div", { class: "refresh-toast", role: "status", "aria-live": "polite" }, "Data updated")
|
|
110
|
+
: null, h(RefreshQueueStatus, { state: refreshQueueState, visible: !isFeatureDisabled("autoRefresh") }), h(PollingSuspensionIndicator, { isSuspended: pollingSuspended, suspendedCount: pollingSuspendedCount, onRefresh: handleManualRefresh }), (showDrop && !hasData)
|
|
111
|
+
? h("div", { class: "drop-overlay", role: "dialog", "aria-label": "File drop zone" }, h("div", { class: "drop-box" }, h("h2", null, "Drop .sourcevision files"), h("p", null, `Drag and drop ${ALL_DATA_FILES.join(", ")}`)))
|
|
112
|
+
: null, h(SearchOverlay, { visible: searchOpen, onClose: closeSearch, navigateTo }));
|
|
113
|
+
}
|
|
114
|
+
const root = document.getElementById("app");
|
|
115
|
+
if (root) {
|
|
116
|
+
// Fetch scope before first render to avoid flash of unscoped content
|
|
117
|
+
fetchScope().then((scope) => {
|
|
118
|
+
render(h(App, { scope }), root);
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/viewer/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Call-level rate limiter with queue deduplication.
|
|
3
|
+
*
|
|
4
|
+
* Enforces a minimum interval between execution starts. Calls arriving
|
|
5
|
+
* within the cooldown window are queued (deduplicated: only one pending
|
|
6
|
+
* call exists at a time — subsequent callers share its promise).
|
|
7
|
+
*
|
|
8
|
+
* Designed to sit in front of `createRequestDedup`: the rate limiter
|
|
9
|
+
* controls *when* calls happen, while the dedup handles concurrent
|
|
10
|
+
* in-flight request sharing.
|
|
11
|
+
*
|
|
12
|
+
* Standalone module with zero framework dependencies.
|
|
13
|
+
* Preact integration lives in the consumer (views/prd.ts).
|
|
14
|
+
*/
|
|
15
|
+
export interface CallRateLimiterConfig {
|
|
16
|
+
/**
|
|
17
|
+
* Minimum milliseconds between execution starts.
|
|
18
|
+
* Default: 500 (allows max 2 calls per second).
|
|
19
|
+
*/
|
|
20
|
+
minIntervalMs?: number;
|
|
21
|
+
}
|
|
22
|
+
/** A rate-limited, queue-deduplicated wrapper around an async function. */
|
|
23
|
+
export interface CallRateLimiter<T = void> {
|
|
24
|
+
/**
|
|
25
|
+
* Schedule execution. If within the rate limit cooldown, the call is
|
|
26
|
+
* queued. Multiple callers hitting the queue share one promise (dedup).
|
|
27
|
+
*/
|
|
28
|
+
execute(): Promise<T>;
|
|
29
|
+
/** Whether the underlying function is currently executing. */
|
|
30
|
+
isExecuting(): boolean;
|
|
31
|
+
/** Whether a call is queued waiting for the rate limit cooldown. */
|
|
32
|
+
isPending(): boolean;
|
|
33
|
+
/** Clean up timers and pending state. Safe to call multiple times. */
|
|
34
|
+
dispose(): void;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Create a rate-limited, queue-deduplicated wrapper for an async function.
|
|
38
|
+
*
|
|
39
|
+
* Usage:
|
|
40
|
+
* ```ts
|
|
41
|
+
* const rateLimited = createCallRateLimiter(() => fetchData(), { minIntervalMs: 500 });
|
|
42
|
+
*
|
|
43
|
+
* rateLimited.execute(); // executes immediately (first call)
|
|
44
|
+
* rateLimited.execute(); // queued — shares the same pending promise
|
|
45
|
+
* rateLimited.execute(); // deduped to the already-queued call
|
|
46
|
+
*
|
|
47
|
+
* // After 500ms the queued call fires.
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function createCallRateLimiter<T = void>(fn: () => Promise<T>, config?: CallRateLimiterConfig): CallRateLimiter<T>;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Call-level rate limiter with queue deduplication.
|
|
3
|
+
*
|
|
4
|
+
* Enforces a minimum interval between execution starts. Calls arriving
|
|
5
|
+
* within the cooldown window are queued (deduplicated: only one pending
|
|
6
|
+
* call exists at a time — subsequent callers share its promise).
|
|
7
|
+
*
|
|
8
|
+
* Designed to sit in front of `createRequestDedup`: the rate limiter
|
|
9
|
+
* controls *when* calls happen, while the dedup handles concurrent
|
|
10
|
+
* in-flight request sharing.
|
|
11
|
+
*
|
|
12
|
+
* Standalone module with zero framework dependencies.
|
|
13
|
+
* Preact integration lives in the consumer (views/prd.ts).
|
|
14
|
+
*/
|
|
15
|
+
/** Default minimum interval — 500ms ≈ 2 calls/sec. */
|
|
16
|
+
const DEFAULT_MIN_INTERVAL_MS = 500;
|
|
17
|
+
// ─── Factory ─────────────────────────────────────────────────────────────────
|
|
18
|
+
/**
|
|
19
|
+
* Create a rate-limited, queue-deduplicated wrapper for an async function.
|
|
20
|
+
*
|
|
21
|
+
* Usage:
|
|
22
|
+
* ```ts
|
|
23
|
+
* const rateLimited = createCallRateLimiter(() => fetchData(), { minIntervalMs: 500 });
|
|
24
|
+
*
|
|
25
|
+
* rateLimited.execute(); // executes immediately (first call)
|
|
26
|
+
* rateLimited.execute(); // queued — shares the same pending promise
|
|
27
|
+
* rateLimited.execute(); // deduped to the already-queued call
|
|
28
|
+
*
|
|
29
|
+
* // After 500ms the queued call fires.
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export function createCallRateLimiter(fn, config) {
|
|
33
|
+
const minIntervalMs = config?.minIntervalMs ?? DEFAULT_MIN_INTERVAL_MS;
|
|
34
|
+
let lastExecutionStartMs = 0;
|
|
35
|
+
let executing = false;
|
|
36
|
+
let pendingTimer = null;
|
|
37
|
+
let pendingResolve = null;
|
|
38
|
+
let pendingReject = null;
|
|
39
|
+
let pendingPromise = null;
|
|
40
|
+
let disposed = false;
|
|
41
|
+
function executeNow() {
|
|
42
|
+
lastExecutionStartMs = Date.now();
|
|
43
|
+
executing = true;
|
|
44
|
+
return fn().then((value) => {
|
|
45
|
+
executing = false;
|
|
46
|
+
return value;
|
|
47
|
+
}, (err) => {
|
|
48
|
+
executing = false;
|
|
49
|
+
throw err;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function execute() {
|
|
53
|
+
if (disposed) {
|
|
54
|
+
return Promise.reject(new Error("CallRateLimiter has been disposed"));
|
|
55
|
+
}
|
|
56
|
+
const now = Date.now();
|
|
57
|
+
const elapsed = now - lastExecutionStartMs;
|
|
58
|
+
if (elapsed >= minIntervalMs) {
|
|
59
|
+
// Enough time since last execution start — fire immediately.
|
|
60
|
+
return executeNow();
|
|
61
|
+
}
|
|
62
|
+
// Within rate limit cooldown — queue (deduplicated).
|
|
63
|
+
if (pendingPromise !== null) {
|
|
64
|
+
// Already queued — return the existing promise (dedup).
|
|
65
|
+
return pendingPromise;
|
|
66
|
+
}
|
|
67
|
+
// Create a new queued execution.
|
|
68
|
+
pendingPromise = new Promise((resolve, reject) => {
|
|
69
|
+
pendingResolve = resolve;
|
|
70
|
+
pendingReject = reject;
|
|
71
|
+
});
|
|
72
|
+
const delay = minIntervalMs - elapsed;
|
|
73
|
+
pendingTimer = setTimeout(() => {
|
|
74
|
+
const resolve = pendingResolve;
|
|
75
|
+
const reject = pendingReject;
|
|
76
|
+
pendingTimer = null;
|
|
77
|
+
pendingResolve = null;
|
|
78
|
+
pendingReject = null;
|
|
79
|
+
pendingPromise = null;
|
|
80
|
+
executeNow().then(resolve, reject);
|
|
81
|
+
}, delay);
|
|
82
|
+
return pendingPromise;
|
|
83
|
+
}
|
|
84
|
+
function isExecuting() {
|
|
85
|
+
return executing;
|
|
86
|
+
}
|
|
87
|
+
function isPending() {
|
|
88
|
+
return pendingPromise !== null;
|
|
89
|
+
}
|
|
90
|
+
function dispose() {
|
|
91
|
+
disposed = true;
|
|
92
|
+
if (pendingTimer !== null) {
|
|
93
|
+
clearTimeout(pendingTimer);
|
|
94
|
+
pendingTimer = null;
|
|
95
|
+
}
|
|
96
|
+
pendingResolve = null;
|
|
97
|
+
pendingReject = null;
|
|
98
|
+
pendingPromise = null;
|
|
99
|
+
executing = false;
|
|
100
|
+
}
|
|
101
|
+
return { execute, isExecuting, isPending, dispose };
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=call-rate-limiter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call-rate-limiter.js","sourceRoot":"","sources":["../../../src/viewer/messaging/call-rate-limiter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA8BH,sDAAsD;AACtD,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAEpC,gFAAgF;AAEhF;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,qBAAqB,CACnC,EAAoB,EACpB,MAA8B;IAE9B,MAAM,aAAa,GAAG,MAAM,EAAE,aAAa,IAAI,uBAAuB,CAAC;IAEvE,IAAI,oBAAoB,GAAG,CAAC,CAAC;IAC7B,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,YAAY,GAAyC,IAAI,CAAC;IAC9D,IAAI,cAAc,GAAgC,IAAI,CAAC;IACvD,IAAI,aAAa,GAAuC,IAAI,CAAC;IAC7D,IAAI,cAAc,GAAsB,IAAI,CAAC;IAC7C,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,SAAS,UAAU;QACjB,oBAAoB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAClC,SAAS,GAAG,IAAI,CAAC;QACjB,OAAO,EAAE,EAAE,CAAC,IAAI,CACd,CAAC,KAAK,EAAE,EAAE;YACR,SAAS,GAAG,KAAK,CAAC;YAClB,OAAO,KAAK,CAAC;QACf,CAAC,EACD,CAAC,GAAG,EAAE,EAAE;YACN,SAAS,GAAG,KAAK,CAAC;YAClB,MAAM,GAAG,CAAC;QACZ,CAAC,CACF,CAAC;IACJ,CAAC;IAED,SAAS,OAAO;QACd,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC,CAAC;QACxE,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,GAAG,GAAG,oBAAoB,CAAC;QAE3C,IAAI,OAAO,IAAI,aAAa,EAAE,CAAC;YAC7B,6DAA6D;YAC7D,OAAO,UAAU,EAAE,CAAC;QACtB,CAAC;QAED,qDAAqD;QACrD,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;YAC5B,wDAAwD;YACxD,OAAO,cAAc,CAAC;QACxB,CAAC;QAED,iCAAiC;QACjC,cAAc,GAAG,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAClD,cAAc,GAAG,OAAO,CAAC;YACzB,aAAa,GAAG,MAAM,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG,aAAa,GAAG,OAAO,CAAC;QACtC,YAAY,GAAG,UAAU,CAAC,GAAG,EAAE;YAC7B,MAAM,OAAO,GAAG,cAAe,CAAC;YAChC,MAAM,MAAM,GAAG,aAAc,CAAC;YAC9B,YAAY,GAAG,IAAI,CAAC;YACpB,cAAc,GAAG,IAAI,CAAC;YACtB,aAAa,GAAG,IAAI,CAAC;YACrB,cAAc,GAAG,IAAI,CAAC;YAEtB,UAAU,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACrC,CAAC,EAAE,KAAK,CAAC,CAAC;QAEV,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,SAAS,WAAW;QAClB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,SAAS,SAAS;QAChB,OAAO,cAAc,KAAK,IAAI,CAAC;IACjC,CAAC;IAED,SAAS,OAAO;QACd,QAAQ,GAAG,IAAI,CAAC;QAChB,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;YAC1B,YAAY,CAAC,YAAY,CAAC,CAAC;YAC3B,YAAY,GAAG,IAAI,CAAC;QACtB,CAAC;QACD,cAAc,GAAG,IAAI,CAAC;QACtB,aAAa,GAAG,IAAI,CAAC;QACrB,cAAc,GAAG,IAAI,CAAC;QACtB,SAAS,GAAG,KAAK,CAAC;IACpB,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetch pipeline — composed request dedup + call rate limiter.
|
|
3
|
+
*
|
|
4
|
+
* Wraps an async function with two layers of protection:
|
|
5
|
+
* 1. **Rate limiter** — caps execution frequency (e.g. max 2 calls/sec).
|
|
6
|
+
* 2. **Request dedup** — concurrent callers share one in-flight request.
|
|
7
|
+
*
|
|
8
|
+
* This module captures the pattern used by `usePRDData` for both PRD and
|
|
9
|
+
* task-usage fetching, reducing the coupling surface from two individual
|
|
10
|
+
* messaging imports to one composed import.
|
|
11
|
+
*
|
|
12
|
+
* Standalone module with zero framework dependencies.
|
|
13
|
+
*/
|
|
14
|
+
/** Configuration for the fetch pipeline. */
|
|
15
|
+
export interface FetchPipelineConfig {
|
|
16
|
+
/**
|
|
17
|
+
* Minimum milliseconds between execution starts.
|
|
18
|
+
* Default: 500 (allows max 2 calls per second).
|
|
19
|
+
*/
|
|
20
|
+
minIntervalMs?: number;
|
|
21
|
+
}
|
|
22
|
+
/** A composed fetch pipeline (rate limiter + request dedup). */
|
|
23
|
+
export interface FetchPipeline<T = void> {
|
|
24
|
+
/**
|
|
25
|
+
* Execute the wrapped function. Rate-limited and deduplicated:
|
|
26
|
+
* - If within the rate limit cooldown, the call is queued.
|
|
27
|
+
* - If a request is already in-flight, returns the existing promise.
|
|
28
|
+
*/
|
|
29
|
+
execute(): Promise<T>;
|
|
30
|
+
/** Whether the underlying function is currently executing. */
|
|
31
|
+
isExecuting(): boolean;
|
|
32
|
+
/** Whether a call is queued waiting for the rate limit cooldown. */
|
|
33
|
+
isPending(): boolean;
|
|
34
|
+
/** Whether a request is currently in-flight (dedup layer). */
|
|
35
|
+
isInFlight(): boolean;
|
|
36
|
+
/** Clean up timers and pending state. Safe to call multiple times. */
|
|
37
|
+
dispose(): void;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Create a fetch pipeline that rate-limits and deduplicates an async function.
|
|
41
|
+
*
|
|
42
|
+
* Usage:
|
|
43
|
+
* ```ts
|
|
44
|
+
* const fetchPRD = createFetchPipeline(
|
|
45
|
+
* async () => {
|
|
46
|
+
* const res = await fetch("/data/prd.json");
|
|
47
|
+
* return res.json();
|
|
48
|
+
* },
|
|
49
|
+
* { minIntervalMs: 500 },
|
|
50
|
+
* );
|
|
51
|
+
*
|
|
52
|
+
* // All three calls resolve to the same result — one actual fetch:
|
|
53
|
+
* fetchPRD.execute();
|
|
54
|
+
* fetchPRD.execute();
|
|
55
|
+
* fetchPRD.execute();
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export declare function createFetchPipeline<T = void>(fn: () => Promise<T>, config?: FetchPipelineConfig): FetchPipeline<T>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetch pipeline — composed request dedup + call rate limiter.
|
|
3
|
+
*
|
|
4
|
+
* Wraps an async function with two layers of protection:
|
|
5
|
+
* 1. **Rate limiter** — caps execution frequency (e.g. max 2 calls/sec).
|
|
6
|
+
* 2. **Request dedup** — concurrent callers share one in-flight request.
|
|
7
|
+
*
|
|
8
|
+
* This module captures the pattern used by `usePRDData` for both PRD and
|
|
9
|
+
* task-usage fetching, reducing the coupling surface from two individual
|
|
10
|
+
* messaging imports to one composed import.
|
|
11
|
+
*
|
|
12
|
+
* Standalone module with zero framework dependencies.
|
|
13
|
+
*/
|
|
14
|
+
import { createCallRateLimiter } from "./call-rate-limiter.js";
|
|
15
|
+
import { createRequestDedup } from "./request-dedup.js";
|
|
16
|
+
// ─── Factory ─────────────────────────────────────────────────────────────────
|
|
17
|
+
/**
|
|
18
|
+
* Create a fetch pipeline that rate-limits and deduplicates an async function.
|
|
19
|
+
*
|
|
20
|
+
* Usage:
|
|
21
|
+
* ```ts
|
|
22
|
+
* const fetchPRD = createFetchPipeline(
|
|
23
|
+
* async () => {
|
|
24
|
+
* const res = await fetch("/data/prd.json");
|
|
25
|
+
* return res.json();
|
|
26
|
+
* },
|
|
27
|
+
* { minIntervalMs: 500 },
|
|
28
|
+
* );
|
|
29
|
+
*
|
|
30
|
+
* // All three calls resolve to the same result — one actual fetch:
|
|
31
|
+
* fetchPRD.execute();
|
|
32
|
+
* fetchPRD.execute();
|
|
33
|
+
* fetchPRD.execute();
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export function createFetchPipeline(fn, config) {
|
|
37
|
+
const dedup = createRequestDedup(fn);
|
|
38
|
+
const rateLimiter = createCallRateLimiter(() => dedup.execute(), { minIntervalMs: config?.minIntervalMs });
|
|
39
|
+
return {
|
|
40
|
+
execute() {
|
|
41
|
+
return rateLimiter.execute();
|
|
42
|
+
},
|
|
43
|
+
isExecuting() {
|
|
44
|
+
return rateLimiter.isExecuting();
|
|
45
|
+
},
|
|
46
|
+
isPending() {
|
|
47
|
+
return rateLimiter.isPending();
|
|
48
|
+
},
|
|
49
|
+
isInFlight() {
|
|
50
|
+
return dedup.isInFlight();
|
|
51
|
+
},
|
|
52
|
+
dispose() {
|
|
53
|
+
rateLimiter.dispose();
|
|
54
|
+
dedup.dispose();
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=fetch-pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-pipeline.js","sourceRoot":"","sources":["../../../src/viewer/messaging/fetch-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,qBAAqB,EAAoD,MAAM,wBAAwB,CAAC;AACjH,OAAO,EAAE,kBAAkB,EAAqB,MAAM,oBAAoB,CAAC;AAmC3E,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,mBAAmB,CACjC,EAAoB,EACpB,MAA4B;IAE5B,MAAM,KAAK,GAAoB,kBAAkB,CAAC,EAAE,CAAC,CAAC;IACtD,MAAM,WAAW,GAAuB,qBAAqB,CAC3D,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,EACrB,EAAE,aAAa,EAAE,MAAM,EAAE,aAAa,EAAkC,CACzE,CAAC;IAEF,OAAO;QACL,OAAO;YACL,OAAO,WAAW,CAAC,OAAO,EAAE,CAAC;QAC/B,CAAC;QAED,WAAW;YACT,OAAO,WAAW,CAAC,WAAW,EAAE,CAAC;QACnC,CAAC;QAED,SAAS;YACP,OAAO,WAAW,CAAC,SAAS,EAAE,CAAC;QACjC,CAAC;QAED,UAAU;YACR,OAAO,KAAK,CAAC,UAAU,EAAE,CAAC;QAC5B,CAAC;QAED,OAAO;YACL,WAAW,CAAC,OAAO,EAAE,CAAC;YACtB,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,CAAC;KACF,CAAC;AACJ,CAAC"}
|