@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,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Messaging integration layer — stable public interface for flow control.
|
|
3
|
+
*
|
|
4
|
+
* ## Responsibility boundary
|
|
5
|
+
*
|
|
6
|
+
* This barrel is the **only sanctioned import path** for viewer-to-server
|
|
7
|
+
* messaging utilities. It isolates consumers (hooks, components) from the
|
|
8
|
+
* internal module structure of the messaging zone. If an internal file is
|
|
9
|
+
* renamed, split, or merged, consumers are unaffected as long as this
|
|
10
|
+
* barrel's exports remain stable.
|
|
11
|
+
*
|
|
12
|
+
* ## Import rules
|
|
13
|
+
*
|
|
14
|
+
* - **Consumers** (hooks, components, views) → import from this barrel.
|
|
15
|
+
* - **Messaging internals** (pipeline files) → may import siblings directly.
|
|
16
|
+
* - **Type-only imports** are exempt (erased at compile time).
|
|
17
|
+
*
|
|
18
|
+
* ## Exports
|
|
19
|
+
*
|
|
20
|
+
* **Composed pipelines (preferred for new consumers):**
|
|
21
|
+
* - **WSPipeline** — throttle → coalescer chain for WebSocket messages.
|
|
22
|
+
* - **FetchPipeline** — rate limiter → dedup chain for API fetch calls.
|
|
23
|
+
*
|
|
24
|
+
* **Primitives (for custom composition only):**
|
|
25
|
+
* - **MessageCoalescer** — batches rapid sequential WebSocket messages
|
|
26
|
+
* into a single flush to avoid redundant fetch calls.
|
|
27
|
+
* - **MessageThrottle** — per-type trailing-edge debounce with independent
|
|
28
|
+
* timers, so different message types throttle at different rates.
|
|
29
|
+
* - **CallRateLimiter** — caps outbound API call frequency with automatic
|
|
30
|
+
* queue draining.
|
|
31
|
+
* - **RequestDedup** — deduplicates in-flight requests by key, returning
|
|
32
|
+
* the same promise to all concurrent callers.
|
|
33
|
+
*
|
|
34
|
+
* New consumers should prefer the composed pipelines unless they need
|
|
35
|
+
* custom composition. All consumers should import from this barrel rather
|
|
36
|
+
* than individual implementation files.
|
|
37
|
+
*/
|
|
38
|
+
export { createWSPipeline, type WSPipeline, type WSPipelineConfig, } from "./ws-pipeline.js";
|
|
39
|
+
export { createFetchPipeline, type FetchPipeline, type FetchPipelineConfig, } from "./fetch-pipeline.js";
|
|
40
|
+
export { createCallRateLimiter, type CallRateLimiter, type CallRateLimiterConfig, } from "./call-rate-limiter.js";
|
|
41
|
+
export { createMessageCoalescer, type MessageCoalescer, type MessageCoalescerConfig, type ParsedWSMessage, type CoalescedBatch, } from "./message-coalescer.js";
|
|
42
|
+
export { createMessageThrottle, type MessageThrottle, type ThrottledHandlerConfig, } from "./message-throttle.js";
|
|
43
|
+
export { createRequestDedup, type RequestDedup, } from "./request-dedup.js";
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Messaging integration layer — stable public interface for flow control.
|
|
3
|
+
*
|
|
4
|
+
* ## Responsibility boundary
|
|
5
|
+
*
|
|
6
|
+
* This barrel is the **only sanctioned import path** for viewer-to-server
|
|
7
|
+
* messaging utilities. It isolates consumers (hooks, components) from the
|
|
8
|
+
* internal module structure of the messaging zone. If an internal file is
|
|
9
|
+
* renamed, split, or merged, consumers are unaffected as long as this
|
|
10
|
+
* barrel's exports remain stable.
|
|
11
|
+
*
|
|
12
|
+
* ## Import rules
|
|
13
|
+
*
|
|
14
|
+
* - **Consumers** (hooks, components, views) → import from this barrel.
|
|
15
|
+
* - **Messaging internals** (pipeline files) → may import siblings directly.
|
|
16
|
+
* - **Type-only imports** are exempt (erased at compile time).
|
|
17
|
+
*
|
|
18
|
+
* ## Exports
|
|
19
|
+
*
|
|
20
|
+
* **Composed pipelines (preferred for new consumers):**
|
|
21
|
+
* - **WSPipeline** — throttle → coalescer chain for WebSocket messages.
|
|
22
|
+
* - **FetchPipeline** — rate limiter → dedup chain for API fetch calls.
|
|
23
|
+
*
|
|
24
|
+
* **Primitives (for custom composition only):**
|
|
25
|
+
* - **MessageCoalescer** — batches rapid sequential WebSocket messages
|
|
26
|
+
* into a single flush to avoid redundant fetch calls.
|
|
27
|
+
* - **MessageThrottle** — per-type trailing-edge debounce with independent
|
|
28
|
+
* timers, so different message types throttle at different rates.
|
|
29
|
+
* - **CallRateLimiter** — caps outbound API call frequency with automatic
|
|
30
|
+
* queue draining.
|
|
31
|
+
* - **RequestDedup** — deduplicates in-flight requests by key, returning
|
|
32
|
+
* the same promise to all concurrent callers.
|
|
33
|
+
*
|
|
34
|
+
* New consumers should prefer the composed pipelines unless they need
|
|
35
|
+
* custom composition. All consumers should import from this barrel rather
|
|
36
|
+
* than individual implementation files.
|
|
37
|
+
*/
|
|
38
|
+
// ── Composed pipelines (prefer these for new consumers) ──────────
|
|
39
|
+
export { createWSPipeline, } from "./ws-pipeline.js";
|
|
40
|
+
export { createFetchPipeline, } from "./fetch-pipeline.js";
|
|
41
|
+
// ── Primitives (for custom composition) ──────────────────────────
|
|
42
|
+
export { createCallRateLimiter, } from "./call-rate-limiter.js";
|
|
43
|
+
export { createMessageCoalescer, } from "./message-coalescer.js";
|
|
44
|
+
export { createMessageThrottle, } from "./message-throttle.js";
|
|
45
|
+
export { createRequestDedup, } from "./request-dedup.js";
|
|
46
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/viewer/messaging/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,oEAAoE;AAEpE,OAAO,EACL,gBAAgB,GAGjB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,mBAAmB,GAGpB,MAAM,qBAAqB,CAAC;AAE7B,oEAAoE;AAEpE,OAAO,EACL,qBAAqB,GAGtB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,sBAAsB,GAKvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,qBAAqB,GAGtB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,kBAAkB,GAEnB,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket message coalescing for rapid sequential updates.
|
|
3
|
+
*
|
|
4
|
+
* When multiple WebSocket messages arrive in quick succession (e.g. a batch
|
|
5
|
+
* of rex:item-updated events during a bulk operation), this module batches
|
|
6
|
+
* them into a single flush to avoid redundant fetch calls.
|
|
7
|
+
*
|
|
8
|
+
* Two-callback design:
|
|
9
|
+
*
|
|
10
|
+
* onMessage(msg) — fires immediately for each message, enabling optimistic
|
|
11
|
+
* UI updates with no delay.
|
|
12
|
+
* onFlush(batch) — fires once per throttle window (trailing edge), after
|
|
13
|
+
* messages stop arriving. The batch includes all message
|
|
14
|
+
* types seen, counts per type, and the full ordered list.
|
|
15
|
+
* Consumers use this to trigger a single reconciliation
|
|
16
|
+
* (e.g. fetchPRDData + fetchTaskUsage) instead of N calls.
|
|
17
|
+
*
|
|
18
|
+
* Designed as a standalone module with zero framework dependencies.
|
|
19
|
+
* The Preact integration lives in the consumer (views/prd.ts etc.).
|
|
20
|
+
*/
|
|
21
|
+
/** A parsed WebSocket message. Minimum requirement: a `type` string. */
|
|
22
|
+
export interface ParsedWSMessage {
|
|
23
|
+
readonly type: string;
|
|
24
|
+
readonly [key: string]: unknown;
|
|
25
|
+
}
|
|
26
|
+
/** The coalesced batch delivered to onFlush. */
|
|
27
|
+
export interface CoalescedBatch {
|
|
28
|
+
/** Deduplicated set of message types in this batch. */
|
|
29
|
+
readonly types: Set<string>;
|
|
30
|
+
/** Per-type count of messages in this batch. */
|
|
31
|
+
readonly countByType: Map<string, number>;
|
|
32
|
+
/** All messages in arrival order — no data loss. */
|
|
33
|
+
readonly messages: readonly ParsedWSMessage[];
|
|
34
|
+
/** Total number of messages. Convenience alias for messages.length. */
|
|
35
|
+
readonly size: number;
|
|
36
|
+
}
|
|
37
|
+
/** Configuration for the message coalescer. */
|
|
38
|
+
export interface MessageCoalescerConfig {
|
|
39
|
+
/**
|
|
40
|
+
* Called once per throttle window with the coalesced batch.
|
|
41
|
+
* Use this to trigger reconciliation fetches.
|
|
42
|
+
*/
|
|
43
|
+
onFlush: (batch: CoalescedBatch) => void;
|
|
44
|
+
/**
|
|
45
|
+
* Called immediately for each incoming message (before batching).
|
|
46
|
+
* Use this for optimistic local state updates that should not be delayed.
|
|
47
|
+
*/
|
|
48
|
+
onMessage?: ((msg: ParsedWSMessage) => void) | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Trailing-edge debounce window in milliseconds.
|
|
51
|
+
* Messages arriving within this window are coalesced into one flush.
|
|
52
|
+
* Default: 150ms.
|
|
53
|
+
*/
|
|
54
|
+
windowMs?: number | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Maximum number of messages to accumulate before forcing a flush.
|
|
57
|
+
* Prevents unbounded memory growth during sustained bursts.
|
|
58
|
+
* Default: 50.
|
|
59
|
+
*/
|
|
60
|
+
maxBatchSize?: number | undefined;
|
|
61
|
+
}
|
|
62
|
+
/** A message coalescer instance. */
|
|
63
|
+
export interface MessageCoalescer {
|
|
64
|
+
/** Push a new message into the coalescer. */
|
|
65
|
+
push(msg: ParsedWSMessage): void;
|
|
66
|
+
/** Force-flush the current batch immediately. No-op if empty. */
|
|
67
|
+
flush(): void;
|
|
68
|
+
/** Dispose: cancel timers, clear batch, ignore future pushes. */
|
|
69
|
+
dispose(): void;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Create a new message coalescer.
|
|
73
|
+
*
|
|
74
|
+
* Usage:
|
|
75
|
+
* ```ts
|
|
76
|
+
* const coalescer = createMessageCoalescer({
|
|
77
|
+
* onMessage: (msg) => {
|
|
78
|
+
* // Immediate optimistic update
|
|
79
|
+
* if (msg.type === "rex:item-updated") applyItemUpdate(msg);
|
|
80
|
+
* },
|
|
81
|
+
* onFlush: (batch) => {
|
|
82
|
+
* // Coalesced reconciliation — runs once per window
|
|
83
|
+
* if (batch.types.has("rex:item-updated") || batch.types.has("rex:prd-changed")) {
|
|
84
|
+
* fetchPRDData();
|
|
85
|
+
* fetchTaskUsage();
|
|
86
|
+
* }
|
|
87
|
+
* },
|
|
88
|
+
* });
|
|
89
|
+
*
|
|
90
|
+
* ws.onmessage = (event) => {
|
|
91
|
+
* const msg = JSON.parse(event.data);
|
|
92
|
+
* coalescer.push(msg);
|
|
93
|
+
* };
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export declare function createMessageCoalescer(config: MessageCoalescerConfig): MessageCoalescer;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket message coalescing for rapid sequential updates.
|
|
3
|
+
*
|
|
4
|
+
* When multiple WebSocket messages arrive in quick succession (e.g. a batch
|
|
5
|
+
* of rex:item-updated events during a bulk operation), this module batches
|
|
6
|
+
* them into a single flush to avoid redundant fetch calls.
|
|
7
|
+
*
|
|
8
|
+
* Two-callback design:
|
|
9
|
+
*
|
|
10
|
+
* onMessage(msg) — fires immediately for each message, enabling optimistic
|
|
11
|
+
* UI updates with no delay.
|
|
12
|
+
* onFlush(batch) — fires once per throttle window (trailing edge), after
|
|
13
|
+
* messages stop arriving. The batch includes all message
|
|
14
|
+
* types seen, counts per type, and the full ordered list.
|
|
15
|
+
* Consumers use this to trigger a single reconciliation
|
|
16
|
+
* (e.g. fetchPRDData + fetchTaskUsage) instead of N calls.
|
|
17
|
+
*
|
|
18
|
+
* Designed as a standalone module with zero framework dependencies.
|
|
19
|
+
* The Preact integration lives in the consumer (views/prd.ts etc.).
|
|
20
|
+
*/
|
|
21
|
+
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
22
|
+
const DEFAULT_WINDOW_MS = 150;
|
|
23
|
+
const DEFAULT_MAX_BATCH_SIZE = 50;
|
|
24
|
+
// ─── Factory ─────────────────────────────────────────────────────────────────
|
|
25
|
+
/**
|
|
26
|
+
* Create a new message coalescer.
|
|
27
|
+
*
|
|
28
|
+
* Usage:
|
|
29
|
+
* ```ts
|
|
30
|
+
* const coalescer = createMessageCoalescer({
|
|
31
|
+
* onMessage: (msg) => {
|
|
32
|
+
* // Immediate optimistic update
|
|
33
|
+
* if (msg.type === "rex:item-updated") applyItemUpdate(msg);
|
|
34
|
+
* },
|
|
35
|
+
* onFlush: (batch) => {
|
|
36
|
+
* // Coalesced reconciliation — runs once per window
|
|
37
|
+
* if (batch.types.has("rex:item-updated") || batch.types.has("rex:prd-changed")) {
|
|
38
|
+
* fetchPRDData();
|
|
39
|
+
* fetchTaskUsage();
|
|
40
|
+
* }
|
|
41
|
+
* },
|
|
42
|
+
* });
|
|
43
|
+
*
|
|
44
|
+
* ws.onmessage = (event) => {
|
|
45
|
+
* const msg = JSON.parse(event.data);
|
|
46
|
+
* coalescer.push(msg);
|
|
47
|
+
* };
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export function createMessageCoalescer(config) {
|
|
51
|
+
const windowMs = config.windowMs ?? DEFAULT_WINDOW_MS;
|
|
52
|
+
const maxBatchSize = config.maxBatchSize ?? DEFAULT_MAX_BATCH_SIZE;
|
|
53
|
+
const onFlush = config.onFlush;
|
|
54
|
+
const onMessage = config.onMessage ?? null;
|
|
55
|
+
let messages = [];
|
|
56
|
+
let types = new Set();
|
|
57
|
+
let countByType = new Map();
|
|
58
|
+
let timer = null;
|
|
59
|
+
let disposed = false;
|
|
60
|
+
function clearTimer() {
|
|
61
|
+
if (timer !== null) {
|
|
62
|
+
clearTimeout(timer);
|
|
63
|
+
timer = null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function buildBatch() {
|
|
67
|
+
return {
|
|
68
|
+
types,
|
|
69
|
+
countByType,
|
|
70
|
+
messages,
|
|
71
|
+
size: messages.length,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function resetBatch() {
|
|
75
|
+
messages = [];
|
|
76
|
+
types = new Set();
|
|
77
|
+
countByType = new Map();
|
|
78
|
+
}
|
|
79
|
+
function doFlush() {
|
|
80
|
+
clearTimer();
|
|
81
|
+
if (messages.length === 0)
|
|
82
|
+
return;
|
|
83
|
+
const batch = buildBatch();
|
|
84
|
+
resetBatch();
|
|
85
|
+
onFlush(batch);
|
|
86
|
+
}
|
|
87
|
+
function scheduleFlush() {
|
|
88
|
+
clearTimer();
|
|
89
|
+
timer = setTimeout(doFlush, windowMs);
|
|
90
|
+
}
|
|
91
|
+
function push(msg) {
|
|
92
|
+
if (disposed)
|
|
93
|
+
return;
|
|
94
|
+
// Immediate per-message callback (for optimistic updates)
|
|
95
|
+
if (onMessage)
|
|
96
|
+
onMessage(msg);
|
|
97
|
+
// Accumulate into the current batch
|
|
98
|
+
messages.push(msg);
|
|
99
|
+
types.add(msg.type);
|
|
100
|
+
countByType.set(msg.type, (countByType.get(msg.type) ?? 0) + 1);
|
|
101
|
+
// Force flush if batch size limit reached
|
|
102
|
+
if (messages.length >= maxBatchSize) {
|
|
103
|
+
doFlush();
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
// Reset the trailing-edge debounce timer
|
|
107
|
+
scheduleFlush();
|
|
108
|
+
}
|
|
109
|
+
function flush() {
|
|
110
|
+
if (disposed)
|
|
111
|
+
return;
|
|
112
|
+
doFlush();
|
|
113
|
+
}
|
|
114
|
+
function dispose() {
|
|
115
|
+
disposed = true;
|
|
116
|
+
clearTimer();
|
|
117
|
+
resetBatch();
|
|
118
|
+
}
|
|
119
|
+
return { push, flush, dispose };
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=message-coalescer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-coalescer.js","sourceRoot":"","sources":["../../../src/viewer/messaging/message-coalescer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AA6DH,gFAAgF;AAEhF,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAC9B,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAElC,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAA8B;IACnE,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,iBAAiB,CAAC;IACtD,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,IAAI,sBAAsB,CAAC;IACnE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IAC/B,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC;IAE3C,IAAI,QAAQ,GAAsB,EAAE,CAAC;IACrC,IAAI,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,IAAI,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC5C,IAAI,KAAK,GAAyC,IAAI,CAAC;IACvD,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,SAAS,UAAU;QACjB,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,KAAK,GAAG,IAAI,CAAC;QACf,CAAC;IACH,CAAC;IAED,SAAS,UAAU;QACjB,OAAO;YACL,KAAK;YACL,WAAW;YACX,QAAQ;YACR,IAAI,EAAE,QAAQ,CAAC,MAAM;SACtB,CAAC;IACJ,CAAC;IAED,SAAS,UAAU;QACjB,QAAQ,GAAG,EAAE,CAAC;QACd,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;QAC1B,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,CAAC;IAED,SAAS,OAAO;QACd,UAAU,EAAE,CAAC;QACb,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAElC,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;QAC3B,UAAU,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,CAAC;IACjB,CAAC;IAED,SAAS,aAAa;QACpB,UAAU,EAAE,CAAC;QACb,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED,SAAS,IAAI,CAAC,GAAoB;QAChC,IAAI,QAAQ;YAAE,OAAO;QAErB,0DAA0D;QAC1D,IAAI,SAAS;YAAE,SAAS,CAAC,GAAG,CAAC,CAAC;QAE9B,oCAAoC;QACpC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpB,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAEhE,0CAA0C;QAC1C,IAAI,QAAQ,CAAC,MAAM,IAAI,YAAY,EAAE,CAAC;YACpC,OAAO,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QAED,yCAAyC;QACzC,aAAa,EAAE,CAAC;IAClB,CAAC;IAED,SAAS,KAAK;QACZ,IAAI,QAAQ;YAAE,OAAO;QACrB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,SAAS,OAAO;QACd,QAAQ,GAAG,IAAI,CAAC;QAChB,UAAU,EAAE,CAAC;QACb,UAAU,EAAE,CAAC;IACf,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-type WebSocket message throttle with configurable debounce.
|
|
3
|
+
*
|
|
4
|
+
* Sits between the raw WebSocket and downstream handlers (e.g. the message
|
|
5
|
+
* coalescer) to provide per-message-type trailing-edge debouncing. Each
|
|
6
|
+
* configured type gets its own independent timer and delay, so different
|
|
7
|
+
* message types can be throttled at different rates.
|
|
8
|
+
*
|
|
9
|
+
* Design decisions:
|
|
10
|
+
*
|
|
11
|
+
* - **Trailing-edge debounce** — messages accumulate during the delay
|
|
12
|
+
* window and are forwarded once the timer fires. New messages of the
|
|
13
|
+
* same type reset the timer (like the coalescer, but per-type).
|
|
14
|
+
*
|
|
15
|
+
* - **Per-type isolation** — timers are fully independent. A burst of
|
|
16
|
+
* rex:item-updated messages doesn't delay rex:prd-changed.
|
|
17
|
+
*
|
|
18
|
+
* - **Bounded memory** — maxPendingPerType caps how many messages can
|
|
19
|
+
* accumulate per type before a force-flush, preventing unbounded growth
|
|
20
|
+
* during sustained bursts.
|
|
21
|
+
*
|
|
22
|
+
* - **Pass-through** — message types not in the throttledTypes set are
|
|
23
|
+
* forwarded immediately with zero delay, preserving low-latency for
|
|
24
|
+
* types that don't need throttling.
|
|
25
|
+
*
|
|
26
|
+
* Standalone module with zero framework dependencies.
|
|
27
|
+
* The Preact integration lives in the consumer (views/prd.ts etc.).
|
|
28
|
+
*/
|
|
29
|
+
import type { ParsedWSMessage } from "./message-coalescer.js";
|
|
30
|
+
/** Configuration for the throttled message handler. */
|
|
31
|
+
export interface ThrottledHandlerConfig {
|
|
32
|
+
/**
|
|
33
|
+
* Called for each message after its type's debounce window expires.
|
|
34
|
+
* For unthrottled types, called immediately.
|
|
35
|
+
*/
|
|
36
|
+
onMessage: (msg: ParsedWSMessage) => void;
|
|
37
|
+
/**
|
|
38
|
+
* Default debounce delay in milliseconds for throttled types
|
|
39
|
+
* that don't have an explicit entry in `delays`.
|
|
40
|
+
* Default: 250ms.
|
|
41
|
+
*/
|
|
42
|
+
defaultDelayMs?: number | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* Per-message-type delay overrides. Keys are message type strings,
|
|
45
|
+
* values are delay in milliseconds. Types not listed here fall back
|
|
46
|
+
* to `defaultDelayMs`.
|
|
47
|
+
*/
|
|
48
|
+
delays?: Partial<Record<string, number>> | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Message types to throttle. Types not in this set pass through
|
|
51
|
+
* immediately to `onMessage`.
|
|
52
|
+
*
|
|
53
|
+
* If undefined (not provided), ALL types are throttled.
|
|
54
|
+
* If an empty array/set, NO types are throttled (all pass through).
|
|
55
|
+
*/
|
|
56
|
+
throttledTypes?: ReadonlySet<string> | readonly string[] | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* Maximum pending messages per type before force-flushing.
|
|
59
|
+
* Prevents unbounded memory growth during sustained bursts.
|
|
60
|
+
* Default: 20.
|
|
61
|
+
*/
|
|
62
|
+
maxPendingPerType?: number | undefined;
|
|
63
|
+
}
|
|
64
|
+
/** A throttled message handler instance. */
|
|
65
|
+
export interface MessageThrottle {
|
|
66
|
+
/** Push a message through the throttle. */
|
|
67
|
+
push(msg: ParsedWSMessage): void;
|
|
68
|
+
/** Force-flush all pending messages across all types immediately. */
|
|
69
|
+
flush(): void;
|
|
70
|
+
/** Dispose: cancel all timers, clear all pending, ignore future pushes. */
|
|
71
|
+
dispose(): void;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Create a new per-type message throttle.
|
|
75
|
+
*
|
|
76
|
+
* Usage:
|
|
77
|
+
* ```ts
|
|
78
|
+
* const throttle = createMessageThrottle({
|
|
79
|
+
* onMessage: (msg) => coalescer.push(msg),
|
|
80
|
+
* defaultDelayMs: 250,
|
|
81
|
+
* delays: {
|
|
82
|
+
* "rex:prd-changed": 500, // slow — heavy reconciliation
|
|
83
|
+
* "rex:item-updated": 150, // fast — targeted updates
|
|
84
|
+
* },
|
|
85
|
+
* throttledTypes: ["rex:prd-changed", "rex:item-updated", "rex:item-deleted"],
|
|
86
|
+
* maxPendingPerType: 20,
|
|
87
|
+
* });
|
|
88
|
+
*
|
|
89
|
+
* ws.onmessage = (event) => {
|
|
90
|
+
* const msg = JSON.parse(event.data);
|
|
91
|
+
* throttle.push(msg);
|
|
92
|
+
* };
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
export declare function createMessageThrottle(config: ThrottledHandlerConfig): MessageThrottle;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-type WebSocket message throttle with configurable debounce.
|
|
3
|
+
*
|
|
4
|
+
* Sits between the raw WebSocket and downstream handlers (e.g. the message
|
|
5
|
+
* coalescer) to provide per-message-type trailing-edge debouncing. Each
|
|
6
|
+
* configured type gets its own independent timer and delay, so different
|
|
7
|
+
* message types can be throttled at different rates.
|
|
8
|
+
*
|
|
9
|
+
* Design decisions:
|
|
10
|
+
*
|
|
11
|
+
* - **Trailing-edge debounce** — messages accumulate during the delay
|
|
12
|
+
* window and are forwarded once the timer fires. New messages of the
|
|
13
|
+
* same type reset the timer (like the coalescer, but per-type).
|
|
14
|
+
*
|
|
15
|
+
* - **Per-type isolation** — timers are fully independent. A burst of
|
|
16
|
+
* rex:item-updated messages doesn't delay rex:prd-changed.
|
|
17
|
+
*
|
|
18
|
+
* - **Bounded memory** — maxPendingPerType caps how many messages can
|
|
19
|
+
* accumulate per type before a force-flush, preventing unbounded growth
|
|
20
|
+
* during sustained bursts.
|
|
21
|
+
*
|
|
22
|
+
* - **Pass-through** — message types not in the throttledTypes set are
|
|
23
|
+
* forwarded immediately with zero delay, preserving low-latency for
|
|
24
|
+
* types that don't need throttling.
|
|
25
|
+
*
|
|
26
|
+
* Standalone module with zero framework dependencies.
|
|
27
|
+
* The Preact integration lives in the consumer (views/prd.ts etc.).
|
|
28
|
+
*/
|
|
29
|
+
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
30
|
+
const DEFAULT_DELAY_MS = 250;
|
|
31
|
+
const DEFAULT_MAX_PENDING_PER_TYPE = 20;
|
|
32
|
+
// ─── Factory ─────────────────────────────────────────────────────────────────
|
|
33
|
+
/**
|
|
34
|
+
* Create a new per-type message throttle.
|
|
35
|
+
*
|
|
36
|
+
* Usage:
|
|
37
|
+
* ```ts
|
|
38
|
+
* const throttle = createMessageThrottle({
|
|
39
|
+
* onMessage: (msg) => coalescer.push(msg),
|
|
40
|
+
* defaultDelayMs: 250,
|
|
41
|
+
* delays: {
|
|
42
|
+
* "rex:prd-changed": 500, // slow — heavy reconciliation
|
|
43
|
+
* "rex:item-updated": 150, // fast — targeted updates
|
|
44
|
+
* },
|
|
45
|
+
* throttledTypes: ["rex:prd-changed", "rex:item-updated", "rex:item-deleted"],
|
|
46
|
+
* maxPendingPerType: 20,
|
|
47
|
+
* });
|
|
48
|
+
*
|
|
49
|
+
* ws.onmessage = (event) => {
|
|
50
|
+
* const msg = JSON.parse(event.data);
|
|
51
|
+
* throttle.push(msg);
|
|
52
|
+
* };
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export function createMessageThrottle(config) {
|
|
56
|
+
const onMessage = config.onMessage;
|
|
57
|
+
const defaultDelayMs = config.defaultDelayMs ?? DEFAULT_DELAY_MS;
|
|
58
|
+
const delays = config.delays ?? {};
|
|
59
|
+
const maxPending = config.maxPendingPerType ?? DEFAULT_MAX_PENDING_PER_TYPE;
|
|
60
|
+
// Normalize throttledTypes into a Set, or null to mean "all types throttled"
|
|
61
|
+
const throttledTypes = config.throttledTypes === undefined
|
|
62
|
+
? null // all types throttled
|
|
63
|
+
: config.throttledTypes instanceof Set
|
|
64
|
+
? config.throttledTypes
|
|
65
|
+
: new Set(config.throttledTypes);
|
|
66
|
+
// Per-type state map
|
|
67
|
+
const stateByType = new Map();
|
|
68
|
+
let disposed = false;
|
|
69
|
+
function isThrottled(type) {
|
|
70
|
+
if (throttledTypes === null)
|
|
71
|
+
return true; // all throttled
|
|
72
|
+
return throttledTypes.has(type);
|
|
73
|
+
}
|
|
74
|
+
function getDelay(type) {
|
|
75
|
+
return delays[type] ?? defaultDelayMs;
|
|
76
|
+
}
|
|
77
|
+
function getOrCreateState(type) {
|
|
78
|
+
let state = stateByType.get(type);
|
|
79
|
+
if (!state) {
|
|
80
|
+
state = { pending: [], timer: null };
|
|
81
|
+
stateByType.set(type, state);
|
|
82
|
+
}
|
|
83
|
+
return state;
|
|
84
|
+
}
|
|
85
|
+
function clearTypeTimer(state) {
|
|
86
|
+
if (state.timer !== null) {
|
|
87
|
+
clearTimeout(state.timer);
|
|
88
|
+
state.timer = null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function flushType(type) {
|
|
92
|
+
const state = stateByType.get(type);
|
|
93
|
+
if (!state || state.pending.length === 0)
|
|
94
|
+
return;
|
|
95
|
+
clearTypeTimer(state);
|
|
96
|
+
// Forward all pending messages for this type
|
|
97
|
+
const messages = state.pending;
|
|
98
|
+
state.pending = [];
|
|
99
|
+
for (const msg of messages) {
|
|
100
|
+
onMessage(msg);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function scheduleFlush(type, state) {
|
|
104
|
+
clearTypeTimer(state);
|
|
105
|
+
state.timer = setTimeout(() => {
|
|
106
|
+
state.timer = null;
|
|
107
|
+
flushType(type);
|
|
108
|
+
}, getDelay(type));
|
|
109
|
+
}
|
|
110
|
+
function push(msg) {
|
|
111
|
+
if (disposed)
|
|
112
|
+
return;
|
|
113
|
+
const type = msg.type;
|
|
114
|
+
// Pass-through for unthrottled types
|
|
115
|
+
if (!isThrottled(type)) {
|
|
116
|
+
onMessage(msg);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
// Accumulate into the type's pending queue
|
|
120
|
+
const state = getOrCreateState(type);
|
|
121
|
+
state.pending.push(msg);
|
|
122
|
+
// Force-flush if pending count exceeds the limit
|
|
123
|
+
if (state.pending.length >= maxPending) {
|
|
124
|
+
flushType(type);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
// Reset the trailing-edge debounce timer for this type
|
|
128
|
+
scheduleFlush(type, state);
|
|
129
|
+
}
|
|
130
|
+
function flush() {
|
|
131
|
+
if (disposed)
|
|
132
|
+
return;
|
|
133
|
+
for (const type of stateByType.keys()) {
|
|
134
|
+
flushType(type);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function dispose() {
|
|
138
|
+
disposed = true;
|
|
139
|
+
for (const state of stateByType.values()) {
|
|
140
|
+
clearTypeTimer(state);
|
|
141
|
+
state.pending = [];
|
|
142
|
+
}
|
|
143
|
+
stateByType.clear();
|
|
144
|
+
}
|
|
145
|
+
return { push, flush, dispose };
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=message-throttle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-throttle.js","sourceRoot":"","sources":["../../../src/viewer/messaging/message-throttle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAuDH,gFAAgF;AAEhF,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAC7B,MAAM,4BAA4B,GAAG,EAAE,CAAC;AASxC,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAA8B;IAClE,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;IACnC,MAAM,cAAc,GAAG,MAAM,CAAC,cAAc,IAAI,gBAAgB,CAAC;IACjE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;IACnC,MAAM,UAAU,GAAG,MAAM,CAAC,iBAAiB,IAAI,4BAA4B,CAAC;IAE5E,6EAA6E;IAC7E,MAAM,cAAc,GAClB,MAAM,CAAC,cAAc,KAAK,SAAS;QACjC,CAAC,CAAC,IAAI,CAAC,sBAAsB;QAC7B,CAAC,CAAC,MAAM,CAAC,cAAc,YAAY,GAAG;YACpC,CAAC,CAAC,MAAM,CAAC,cAA6B;YACtC,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAEvC,qBAAqB;IACrB,MAAM,WAAW,GAAG,IAAI,GAAG,EAAqB,CAAC;IAEjD,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,SAAS,WAAW,CAAC,IAAY;QAC/B,IAAI,cAAc,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC,CAAC,gBAAgB;QAC1D,OAAO,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAED,SAAS,QAAQ,CAAC,IAAY;QAC5B,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC;IACxC,CAAC;IAED,SAAS,gBAAgB,CAAC,IAAY;QACpC,IAAI,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;YACrC,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC/B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,SAAS,cAAc,CAAC,KAAgB;QACtC,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YACzB,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1B,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;QACrB,CAAC;IACH,CAAC;IAED,SAAS,SAAS,CAAC,IAAY;QAC7B,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAEjD,cAAc,CAAC,KAAK,CAAC,CAAC;QAEtB,6CAA6C;QAC7C,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC;QAC/B,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC;QAEnB,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,SAAS,CAAC,GAAG,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IAED,SAAS,aAAa,CAAC,IAAY,EAAE,KAAgB;QACnD,cAAc,CAAC,KAAK,CAAC,CAAC;QACtB,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;YACnB,SAAS,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IACrB,CAAC;IAED,SAAS,IAAI,CAAC,GAAoB;QAChC,IAAI,QAAQ;YAAE,OAAO;QAErB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QAEtB,qCAAqC;QACrC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,SAAS,CAAC,GAAG,CAAC,CAAC;YACf,OAAO;QACT,CAAC;QAED,2CAA2C;QAC3C,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACrC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAExB,iDAAiD;QACjD,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,IAAI,UAAU,EAAE,CAAC;YACvC,SAAS,CAAC,IAAI,CAAC,CAAC;YAChB,OAAO;QACT,CAAC;QAED,uDAAuD;QACvD,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED,SAAS,KAAK;QACZ,IAAI,QAAQ;YAAE,OAAO;QAErB,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;YACtC,SAAS,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,SAAS,OAAO;QACd,QAAQ,GAAG,IAAI,CAAC;QAEhB,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;YACzC,cAAc,CAAC,KAAK,CAAC,CAAC;YACtB,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC;QACrB,CAAC;QACD,WAAW,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-flight request deduplication.
|
|
3
|
+
*
|
|
4
|
+
* Wraps an async function so that concurrent callers share a single in-flight
|
|
5
|
+
* promise instead of triggering duplicate API calls. When the underlying
|
|
6
|
+
* request completes (success or failure), tracking is cleared and the next
|
|
7
|
+
* call starts a fresh request.
|
|
8
|
+
*
|
|
9
|
+
* Typical use: prevent duplicate `fetchPRDData` calls when a WebSocket
|
|
10
|
+
* message arrives while a polling request is already in progress.
|
|
11
|
+
*
|
|
12
|
+
* Designed as a standalone module with zero framework dependencies.
|
|
13
|
+
* The Preact integration lives in the consumer (views/prd.ts etc.).
|
|
14
|
+
*/
|
|
15
|
+
/** A deduplicating wrapper around an async function. */
|
|
16
|
+
export interface RequestDedup<T = void> {
|
|
17
|
+
/**
|
|
18
|
+
* Execute the wrapped function. If a request is already in-flight,
|
|
19
|
+
* returns the existing promise instead of starting a new one.
|
|
20
|
+
*/
|
|
21
|
+
execute(): Promise<T>;
|
|
22
|
+
/** Whether a request is currently in-flight. */
|
|
23
|
+
isInFlight(): boolean;
|
|
24
|
+
/** Clear in-flight tracking state. Safe to call multiple times. */
|
|
25
|
+
dispose(): void;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Create a deduplicating wrapper for an async function.
|
|
29
|
+
*
|
|
30
|
+
* Usage:
|
|
31
|
+
* ```ts
|
|
32
|
+
* const dedupedFetch = createRequestDedup(() => fetch("/data/prd.json").then(r => r.json()));
|
|
33
|
+
*
|
|
34
|
+
* // These two calls share one underlying fetch:
|
|
35
|
+
* dedupedFetch.execute(); // starts the request
|
|
36
|
+
* dedupedFetch.execute(); // returns the same promise
|
|
37
|
+
*
|
|
38
|
+
* // After the request settles, the next call starts fresh:
|
|
39
|
+
* await dedupedFetch.execute();
|
|
40
|
+
* dedupedFetch.execute(); // new request
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export declare function createRequestDedup<T = void>(fn: () => Promise<T>): RequestDedup<T>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-flight request deduplication.
|
|
3
|
+
*
|
|
4
|
+
* Wraps an async function so that concurrent callers share a single in-flight
|
|
5
|
+
* promise instead of triggering duplicate API calls. When the underlying
|
|
6
|
+
* request completes (success or failure), tracking is cleared and the next
|
|
7
|
+
* call starts a fresh request.
|
|
8
|
+
*
|
|
9
|
+
* Typical use: prevent duplicate `fetchPRDData` calls when a WebSocket
|
|
10
|
+
* message arrives while a polling request is already in progress.
|
|
11
|
+
*
|
|
12
|
+
* Designed as a standalone module with zero framework dependencies.
|
|
13
|
+
* The Preact integration lives in the consumer (views/prd.ts etc.).
|
|
14
|
+
*/
|
|
15
|
+
// ─── Factory ─────────────────────────────────────────────────────────────────
|
|
16
|
+
/**
|
|
17
|
+
* Create a deduplicating wrapper for an async function.
|
|
18
|
+
*
|
|
19
|
+
* Usage:
|
|
20
|
+
* ```ts
|
|
21
|
+
* const dedupedFetch = createRequestDedup(() => fetch("/data/prd.json").then(r => r.json()));
|
|
22
|
+
*
|
|
23
|
+
* // These two calls share one underlying fetch:
|
|
24
|
+
* dedupedFetch.execute(); // starts the request
|
|
25
|
+
* dedupedFetch.execute(); // returns the same promise
|
|
26
|
+
*
|
|
27
|
+
* // After the request settles, the next call starts fresh:
|
|
28
|
+
* await dedupedFetch.execute();
|
|
29
|
+
* dedupedFetch.execute(); // new request
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export function createRequestDedup(fn) {
|
|
33
|
+
let inflight = null;
|
|
34
|
+
function execute() {
|
|
35
|
+
if (inflight !== null) {
|
|
36
|
+
return inflight;
|
|
37
|
+
}
|
|
38
|
+
inflight = fn().then((value) => {
|
|
39
|
+
inflight = null;
|
|
40
|
+
return value;
|
|
41
|
+
}, (err) => {
|
|
42
|
+
inflight = null;
|
|
43
|
+
throw err;
|
|
44
|
+
});
|
|
45
|
+
return inflight;
|
|
46
|
+
}
|
|
47
|
+
function isInFlight() {
|
|
48
|
+
return inflight !== null;
|
|
49
|
+
}
|
|
50
|
+
function dispose() {
|
|
51
|
+
inflight = null;
|
|
52
|
+
}
|
|
53
|
+
return { execute, isInFlight, dispose };
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=request-dedup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-dedup.js","sourceRoot":"","sources":["../../../src/viewer/messaging/request-dedup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAmBH,gFAAgF;AAEhF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,kBAAkB,CAChC,EAAoB;IAEpB,IAAI,QAAQ,GAAsB,IAAI,CAAC;IAEvC,SAAS,OAAO;QACd,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACtB,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,QAAQ,GAAG,EAAE,EAAE,CAAC,IAAI,CAClB,CAAC,KAAK,EAAE,EAAE;YACR,QAAQ,GAAG,IAAI,CAAC;YAChB,OAAO,KAAK,CAAC;QACf,CAAC,EACD,CAAC,GAAG,EAAE,EAAE;YACN,QAAQ,GAAG,IAAI,CAAC;YAChB,MAAM,GAAG,CAAC;QACZ,CAAC,CACF,CAAC;QAEF,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,SAAS,UAAU;QACjB,OAAO,QAAQ,KAAK,IAAI,CAAC;IAC3B,CAAC;IAED,SAAS,OAAO;QACd,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;AAC1C,CAAC"}
|