@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,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response buffer gate — suspends message pipeline during tab inactivity.
|
|
3
|
+
*
|
|
4
|
+
* Sits at the front of the WebSocket message pipeline to prevent memory
|
|
5
|
+
* buildup from accumulating response data while the browser tab is hidden.
|
|
6
|
+
* When the tab becomes inactive:
|
|
7
|
+
*
|
|
8
|
+
* 1. Flushes all pending data from downstream buffers (throttle, coalescer,
|
|
9
|
+
* batcher) so they release references immediately.
|
|
10
|
+
* 2. Drops all subsequent incoming messages silently — no accumulation.
|
|
11
|
+
* 3. Tracks that messages were dropped during suspension.
|
|
12
|
+
*
|
|
13
|
+
* When the tab becomes visible again:
|
|
14
|
+
*
|
|
15
|
+
* 1. Opens the gate to accept new messages normally.
|
|
16
|
+
* 2. If any messages were dropped, calls `onResume` so the consumer can
|
|
17
|
+
* trigger a single full reconciliation (e.g. fetchPRDData + fetchTaskUsage)
|
|
18
|
+
* to restore data integrity.
|
|
19
|
+
*
|
|
20
|
+
* This module complements the polling-manager (which suspends fetch intervals)
|
|
21
|
+
* by also stopping the *response processing* side. Without this, WebSocket
|
|
22
|
+
* messages arriving during a background tab would still accumulate in the
|
|
23
|
+
* message-throttle pending arrays, coalescer batch, and update-batcher queue.
|
|
24
|
+
*
|
|
25
|
+
* Pipeline position:
|
|
26
|
+
*
|
|
27
|
+
* raw WebSocket → **response-buffer-gate** → throttle → coalescer → batcher → render
|
|
28
|
+
*
|
|
29
|
+
* Designed as a standalone module with zero framework dependencies.
|
|
30
|
+
* The Preact integration lives in the consumer (views/prd.ts etc.).
|
|
31
|
+
*/
|
|
32
|
+
/** Flush callback for a downstream buffer (throttle, coalescer, or batcher). */
|
|
33
|
+
export type BufferFlushFn = () => void;
|
|
34
|
+
/** Configuration for the response buffer gate. */
|
|
35
|
+
export interface ResponseBufferGateConfig {
|
|
36
|
+
/**
|
|
37
|
+
* Downstream buffer flush functions. Called in order when the gate
|
|
38
|
+
* closes (tab goes hidden) to release buffered data from memory.
|
|
39
|
+
*
|
|
40
|
+
* Typical order: throttle.flush → coalescer.flush → batcher.flush
|
|
41
|
+
*/
|
|
42
|
+
flushDownstream: readonly BufferFlushFn[];
|
|
43
|
+
/**
|
|
44
|
+
* Called when the gate re-opens after suspension, but only if messages
|
|
45
|
+
* were dropped while the gate was closed. Use this to trigger a single
|
|
46
|
+
* reconciliation fetch that restores data integrity.
|
|
47
|
+
*/
|
|
48
|
+
onResume: () => void;
|
|
49
|
+
/**
|
|
50
|
+
* Debounce delay in milliseconds before re-opening the gate after the
|
|
51
|
+
* tab becomes visible. Prevents thrashing on rapid tab switches.
|
|
52
|
+
* Default: 100ms (matches polling-manager's resume debounce).
|
|
53
|
+
*/
|
|
54
|
+
resumeDebounceMs?: number | undefined;
|
|
55
|
+
}
|
|
56
|
+
/** Read-only snapshot of the gate's current state. */
|
|
57
|
+
export interface BufferGateSnapshot {
|
|
58
|
+
/** Whether the gate is currently open (accepting messages). */
|
|
59
|
+
readonly isOpen: boolean;
|
|
60
|
+
/** Number of messages dropped during the current or most recent suspension. */
|
|
61
|
+
readonly droppedCount: number;
|
|
62
|
+
/** Total messages dropped across all suspensions since creation. */
|
|
63
|
+
readonly totalDropped: number;
|
|
64
|
+
/** Number of times the gate has been suspended. */
|
|
65
|
+
readonly suspensionCount: number;
|
|
66
|
+
}
|
|
67
|
+
/** A response buffer gate instance. */
|
|
68
|
+
export interface ResponseBufferGate {
|
|
69
|
+
/**
|
|
70
|
+
* Check whether a message should be processed.
|
|
71
|
+
* Returns `true` if the gate is open (message should be forwarded).
|
|
72
|
+
* Returns `false` if the gate is closed (message is dropped).
|
|
73
|
+
*
|
|
74
|
+
* Increments the drop counter on each rejection.
|
|
75
|
+
*/
|
|
76
|
+
accept(): boolean;
|
|
77
|
+
/** Whether the gate is currently open. */
|
|
78
|
+
isOpen(): boolean;
|
|
79
|
+
/** Get a snapshot of the gate's current state. */
|
|
80
|
+
getSnapshot(): BufferGateSnapshot;
|
|
81
|
+
/** Dispose: unsubscribe from visibility events, clear timers. */
|
|
82
|
+
dispose(): void;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Create a new response buffer gate.
|
|
86
|
+
*
|
|
87
|
+
* Usage:
|
|
88
|
+
* ```ts
|
|
89
|
+
* const gate = createResponseBufferGate({
|
|
90
|
+
* flushDownstream: [
|
|
91
|
+
* () => throttle.flush(),
|
|
92
|
+
* () => coalescer.flush(),
|
|
93
|
+
* () => batcher.flush(),
|
|
94
|
+
* ],
|
|
95
|
+
* onResume: () => {
|
|
96
|
+
* fetchPRDData();
|
|
97
|
+
* fetchTaskUsage();
|
|
98
|
+
* },
|
|
99
|
+
* });
|
|
100
|
+
*
|
|
101
|
+
* ws.onmessage = (event) => {
|
|
102
|
+
* const msg = JSON.parse(event.data);
|
|
103
|
+
* if (!gate.accept()) return; // Dropped — tab is hidden
|
|
104
|
+
* throttle.push(msg);
|
|
105
|
+
* };
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
export declare function createResponseBufferGate(config: ResponseBufferGateConfig): ResponseBufferGate;
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response buffer gate — suspends message pipeline during tab inactivity.
|
|
3
|
+
*
|
|
4
|
+
* Sits at the front of the WebSocket message pipeline to prevent memory
|
|
5
|
+
* buildup from accumulating response data while the browser tab is hidden.
|
|
6
|
+
* When the tab becomes inactive:
|
|
7
|
+
*
|
|
8
|
+
* 1. Flushes all pending data from downstream buffers (throttle, coalescer,
|
|
9
|
+
* batcher) so they release references immediately.
|
|
10
|
+
* 2. Drops all subsequent incoming messages silently — no accumulation.
|
|
11
|
+
* 3. Tracks that messages were dropped during suspension.
|
|
12
|
+
*
|
|
13
|
+
* When the tab becomes visible again:
|
|
14
|
+
*
|
|
15
|
+
* 1. Opens the gate to accept new messages normally.
|
|
16
|
+
* 2. If any messages were dropped, calls `onResume` so the consumer can
|
|
17
|
+
* trigger a single full reconciliation (e.g. fetchPRDData + fetchTaskUsage)
|
|
18
|
+
* to restore data integrity.
|
|
19
|
+
*
|
|
20
|
+
* This module complements the polling-manager (which suspends fetch intervals)
|
|
21
|
+
* by also stopping the *response processing* side. Without this, WebSocket
|
|
22
|
+
* messages arriving during a background tab would still accumulate in the
|
|
23
|
+
* message-throttle pending arrays, coalescer batch, and update-batcher queue.
|
|
24
|
+
*
|
|
25
|
+
* Pipeline position:
|
|
26
|
+
*
|
|
27
|
+
* raw WebSocket → **response-buffer-gate** → throttle → coalescer → batcher → render
|
|
28
|
+
*
|
|
29
|
+
* Designed as a standalone module with zero framework dependencies.
|
|
30
|
+
* The Preact integration lives in the consumer (views/prd.ts etc.).
|
|
31
|
+
*/
|
|
32
|
+
import { onVisibilityChange, isTabVisible, } from "../polling/index.js";
|
|
33
|
+
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
34
|
+
const DEFAULT_RESUME_DEBOUNCE_MS = 100;
|
|
35
|
+
// ─── Factory ─────────────────────────────────────────────────────────────────
|
|
36
|
+
/**
|
|
37
|
+
* Create a new response buffer gate.
|
|
38
|
+
*
|
|
39
|
+
* Usage:
|
|
40
|
+
* ```ts
|
|
41
|
+
* const gate = createResponseBufferGate({
|
|
42
|
+
* flushDownstream: [
|
|
43
|
+
* () => throttle.flush(),
|
|
44
|
+
* () => coalescer.flush(),
|
|
45
|
+
* () => batcher.flush(),
|
|
46
|
+
* ],
|
|
47
|
+
* onResume: () => {
|
|
48
|
+
* fetchPRDData();
|
|
49
|
+
* fetchTaskUsage();
|
|
50
|
+
* },
|
|
51
|
+
* });
|
|
52
|
+
*
|
|
53
|
+
* ws.onmessage = (event) => {
|
|
54
|
+
* const msg = JSON.parse(event.data);
|
|
55
|
+
* if (!gate.accept()) return; // Dropped — tab is hidden
|
|
56
|
+
* throttle.push(msg);
|
|
57
|
+
* };
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export function createResponseBufferGate(config) {
|
|
61
|
+
const flushDownstream = config.flushDownstream;
|
|
62
|
+
const onResume = config.onResume;
|
|
63
|
+
const resumeDebounceMs = config.resumeDebounceMs ?? DEFAULT_RESUME_DEBOUNCE_MS;
|
|
64
|
+
// Start as visible; the initial-state check below may immediately suspend.
|
|
65
|
+
let open = true;
|
|
66
|
+
let droppedCount = 0;
|
|
67
|
+
let totalDropped = 0;
|
|
68
|
+
let suspensionCount = 0;
|
|
69
|
+
let resumeTimer = null;
|
|
70
|
+
let disposed = false;
|
|
71
|
+
function clearResumeTimer() {
|
|
72
|
+
if (resumeTimer !== null) {
|
|
73
|
+
clearTimeout(resumeTimer);
|
|
74
|
+
resumeTimer = null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/** Flush all downstream buffers to release buffered data from memory. */
|
|
78
|
+
function flushAllDownstream() {
|
|
79
|
+
for (const flush of flushDownstream) {
|
|
80
|
+
try {
|
|
81
|
+
flush();
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// Swallow errors from individual flushes.
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/** Close the gate: flush downstream buffers and start dropping. */
|
|
89
|
+
function suspend() {
|
|
90
|
+
if (!open)
|
|
91
|
+
return;
|
|
92
|
+
open = false;
|
|
93
|
+
droppedCount = 0;
|
|
94
|
+
suspensionCount++;
|
|
95
|
+
// Flush downstream buffers to release buffered data from memory.
|
|
96
|
+
// This ensures the throttle's pending arrays, the coalescer's batch,
|
|
97
|
+
// and the batcher's queue are all cleared immediately.
|
|
98
|
+
flushAllDownstream();
|
|
99
|
+
}
|
|
100
|
+
/** Re-open the gate and trigger reconciliation if data was dropped. */
|
|
101
|
+
function resume() {
|
|
102
|
+
if (open)
|
|
103
|
+
return;
|
|
104
|
+
const hadDrops = droppedCount > 0;
|
|
105
|
+
open = true;
|
|
106
|
+
// Trigger reconciliation if any messages were lost during suspension.
|
|
107
|
+
// This ensures the UI shows the latest state from the server.
|
|
108
|
+
if (hadDrops) {
|
|
109
|
+
try {
|
|
110
|
+
onResume();
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
// Swallow errors from the resume callback.
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function handleVisibilityChange(snapshot) {
|
|
118
|
+
if (disposed)
|
|
119
|
+
return;
|
|
120
|
+
if (snapshot.isVisible) {
|
|
121
|
+
// Tab became visible — resume with debounce to prevent thrash.
|
|
122
|
+
clearResumeTimer();
|
|
123
|
+
resumeTimer = setTimeout(() => {
|
|
124
|
+
resumeTimer = null;
|
|
125
|
+
resume();
|
|
126
|
+
}, resumeDebounceMs);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
// Tab became hidden — suspend immediately.
|
|
130
|
+
clearResumeTimer();
|
|
131
|
+
suspend();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// Subscribe to tab visibility changes.
|
|
135
|
+
const unsubVisibility = onVisibilityChange(handleVisibilityChange);
|
|
136
|
+
// If the tab is currently hidden, suspend immediately. This runs the
|
|
137
|
+
// full suspend path (flush + mark closed) even on initial creation.
|
|
138
|
+
if (!isTabVisible()) {
|
|
139
|
+
suspend();
|
|
140
|
+
}
|
|
141
|
+
// ─── Public methods ─────────────────────────────────────────────────
|
|
142
|
+
function accept() {
|
|
143
|
+
if (disposed)
|
|
144
|
+
return false;
|
|
145
|
+
if (!open) {
|
|
146
|
+
droppedCount++;
|
|
147
|
+
totalDropped++;
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
function isOpenFn() {
|
|
153
|
+
return open;
|
|
154
|
+
}
|
|
155
|
+
function getSnapshot() {
|
|
156
|
+
return {
|
|
157
|
+
isOpen: open,
|
|
158
|
+
droppedCount,
|
|
159
|
+
totalDropped,
|
|
160
|
+
suspensionCount,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function dispose() {
|
|
164
|
+
disposed = true;
|
|
165
|
+
clearResumeTimer();
|
|
166
|
+
unsubVisibility();
|
|
167
|
+
}
|
|
168
|
+
return { accept, isOpen: isOpenFn, getSnapshot, dispose };
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=response-buffer-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-buffer-gate.js","sourceRoot":"","sources":["../../../src/viewer/performance/response-buffer-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,EACL,kBAAkB,EAClB,YAAY,GAEb,MAAM,qBAAqB,CAAC;AAiE7B,gFAAgF;AAEhF,MAAM,0BAA0B,GAAG,GAAG,CAAC;AAEvC,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,wBAAwB,CACtC,MAAgC;IAEhC,MAAM,eAAe,GAAG,MAAM,CAAC,eAAe,CAAC;IAC/C,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IACjC,MAAM,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,IAAI,0BAA0B,CAAC;IAE/E,2EAA2E;IAC3E,IAAI,IAAI,GAAG,IAAI,CAAC;IAChB,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,IAAI,WAAW,GAAyC,IAAI,CAAC;IAC7D,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,SAAS,gBAAgB;QACvB,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;YACzB,YAAY,CAAC,WAAW,CAAC,CAAC;YAC1B,WAAW,GAAG,IAAI,CAAC;QACrB,CAAC;IACH,CAAC;IAED,yEAAyE;IACzE,SAAS,kBAAkB;QACzB,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;YACpC,IAAI,CAAC;gBACH,KAAK,EAAE,CAAC;YACV,CAAC;YAAC,MAAM,CAAC;gBACP,0CAA0C;YAC5C,CAAC;QACH,CAAC;IACH,CAAC;IAED,mEAAmE;IACnE,SAAS,OAAO;QACd,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,IAAI,GAAG,KAAK,CAAC;QACb,YAAY,GAAG,CAAC,CAAC;QACjB,eAAe,EAAE,CAAC;QAElB,iEAAiE;QACjE,qEAAqE;QACrE,uDAAuD;QACvD,kBAAkB,EAAE,CAAC;IACvB,CAAC;IAED,uEAAuE;IACvE,SAAS,MAAM;QACb,IAAI,IAAI;YAAE,OAAO;QAEjB,MAAM,QAAQ,GAAG,YAAY,GAAG,CAAC,CAAC;QAElC,IAAI,GAAG,IAAI,CAAC;QAEZ,sEAAsE;QACtE,8DAA8D;QAC9D,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC;gBACH,QAAQ,EAAE,CAAC;YACb,CAAC;YAAC,MAAM,CAAC;gBACP,2CAA2C;YAC7C,CAAC;QACH,CAAC;IACH,CAAC;IAED,SAAS,sBAAsB,CAAC,QAA+B;QAC7D,IAAI,QAAQ;YAAE,OAAO;QAErB,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;YACvB,+DAA+D;YAC/D,gBAAgB,EAAE,CAAC;YACnB,WAAW,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,WAAW,GAAG,IAAI,CAAC;gBACnB,MAAM,EAAE,CAAC;YACX,CAAC,EAAE,gBAAgB,CAAC,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,2CAA2C;YAC3C,gBAAgB,EAAE,CAAC;YACnB,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,uCAAuC;IACvC,MAAM,eAAe,GAAG,kBAAkB,CAAC,sBAAsB,CAAC,CAAC;IAEnE,qEAAqE;IACrE,oEAAoE;IACpE,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;QACpB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,uEAAuE;IAEvE,SAAS,MAAM;QACb,IAAI,QAAQ;YAAE,OAAO,KAAK,CAAC;QAE3B,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,YAAY,EAAE,CAAC;YACf,YAAY,EAAE,CAAC;YACf,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,SAAS,QAAQ;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IAED,SAAS,WAAW;QAClB,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,YAAY;YACZ,YAAY;YACZ,eAAe;SAChB,CAAC;IACJ,CAAC;IAED,SAAS,OAAO;QACd,QAAQ,GAAG,IAAI,CAAC;QAChB,gBAAgB,EAAE,CAAC;QACnB,eAAe,EAAE,CAAC;IACpB,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;AAC5D,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* requestAnimationFrame-based update batching for rapid UI state changes.
|
|
3
|
+
*
|
|
4
|
+
* When multiple WebSocket messages trigger state updates in quick succession,
|
|
5
|
+
* this module batches them into a single animation frame to prevent unnecessary
|
|
6
|
+
* intermediate renders. All queued updaters are composed per-setter and applied
|
|
7
|
+
* once within one RAF callback, preserving final state consistency.
|
|
8
|
+
*
|
|
9
|
+
* Two operating modes:
|
|
10
|
+
*
|
|
11
|
+
* **Enabled (default)** — updaters are queued and applied in the next RAF.
|
|
12
|
+
* Multiple `schedule()` calls for the same setter are composed in arrival
|
|
13
|
+
* order so the setter is invoked exactly once per frame. Different setters
|
|
14
|
+
* are invoked independently within the same frame.
|
|
15
|
+
*
|
|
16
|
+
* **Disabled** — updaters are applied synchronously on each `schedule()`
|
|
17
|
+
* call, bypassing RAF entirely. Useful for debugging and testing where
|
|
18
|
+
* immediate state visibility is needed.
|
|
19
|
+
*
|
|
20
|
+
* Pipeline position:
|
|
21
|
+
*
|
|
22
|
+
* ... → coalescer.onMessage → updateBatcher.schedule(setter, updater) → RAF → render
|
|
23
|
+
*
|
|
24
|
+
* Designed as a standalone module with zero framework dependencies.
|
|
25
|
+
* The Preact integration lives in the consumer (views/prd.ts etc.).
|
|
26
|
+
*/
|
|
27
|
+
/** Configuration for the update batcher. */
|
|
28
|
+
export interface UpdateBatcherConfig {
|
|
29
|
+
/**
|
|
30
|
+
* When true, bypasses RAF batching and applies updates synchronously.
|
|
31
|
+
* Useful for debugging and testing.
|
|
32
|
+
* Default: false.
|
|
33
|
+
*/
|
|
34
|
+
disabled?: boolean | undefined;
|
|
35
|
+
}
|
|
36
|
+
/** An update batcher instance. */
|
|
37
|
+
export interface UpdateBatcher {
|
|
38
|
+
/**
|
|
39
|
+
* Schedule a state update to be applied in the next animation frame.
|
|
40
|
+
*
|
|
41
|
+
* Multiple updates for the same setter are composed in order: each updater
|
|
42
|
+
* receives the result of the previous, and the setter is called once with
|
|
43
|
+
* the final composed value — identical to sequential application.
|
|
44
|
+
*
|
|
45
|
+
* When batching is disabled, the setter is called immediately.
|
|
46
|
+
*/
|
|
47
|
+
schedule<T>(setter: (updater: (prev: T) => T) => void, updater: (prev: T) => T): void;
|
|
48
|
+
/**
|
|
49
|
+
* Force-flush all pending updates synchronously. Cancels any pending RAF.
|
|
50
|
+
* No-op if no updates are pending.
|
|
51
|
+
*/
|
|
52
|
+
flush(): void;
|
|
53
|
+
/** Whether updates are currently pending in the batch queue. */
|
|
54
|
+
hasPending(): boolean;
|
|
55
|
+
/** Dispose: cancel pending RAF, clear queue, ignore future schedules. */
|
|
56
|
+
dispose(): void;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Create a new update batcher.
|
|
60
|
+
*
|
|
61
|
+
* Usage:
|
|
62
|
+
* ```ts
|
|
63
|
+
* const batcher = createUpdateBatcher();
|
|
64
|
+
*
|
|
65
|
+
* // In a WebSocket message handler:
|
|
66
|
+
* coalescer.onMessage = (msg) => {
|
|
67
|
+
* if (msg.type === "rex:item-updated") {
|
|
68
|
+
* batcher.schedule(setData, (prev) => {
|
|
69
|
+
* const newItems = applyItemUpdate(prev.items, msg.itemId, msg.updates);
|
|
70
|
+
* return newItems === prev.items ? prev : { ...prev, items: newItems };
|
|
71
|
+
* });
|
|
72
|
+
* }
|
|
73
|
+
* };
|
|
74
|
+
*
|
|
75
|
+
* // On component unmount:
|
|
76
|
+
* batcher.dispose();
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export declare function createUpdateBatcher(config?: UpdateBatcherConfig): UpdateBatcher;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* requestAnimationFrame-based update batching for rapid UI state changes.
|
|
3
|
+
*
|
|
4
|
+
* When multiple WebSocket messages trigger state updates in quick succession,
|
|
5
|
+
* this module batches them into a single animation frame to prevent unnecessary
|
|
6
|
+
* intermediate renders. All queued updaters are composed per-setter and applied
|
|
7
|
+
* once within one RAF callback, preserving final state consistency.
|
|
8
|
+
*
|
|
9
|
+
* Two operating modes:
|
|
10
|
+
*
|
|
11
|
+
* **Enabled (default)** — updaters are queued and applied in the next RAF.
|
|
12
|
+
* Multiple `schedule()` calls for the same setter are composed in arrival
|
|
13
|
+
* order so the setter is invoked exactly once per frame. Different setters
|
|
14
|
+
* are invoked independently within the same frame.
|
|
15
|
+
*
|
|
16
|
+
* **Disabled** — updaters are applied synchronously on each `schedule()`
|
|
17
|
+
* call, bypassing RAF entirely. Useful for debugging and testing where
|
|
18
|
+
* immediate state visibility is needed.
|
|
19
|
+
*
|
|
20
|
+
* Pipeline position:
|
|
21
|
+
*
|
|
22
|
+
* ... → coalescer.onMessage → updateBatcher.schedule(setter, updater) → RAF → render
|
|
23
|
+
*
|
|
24
|
+
* Designed as a standalone module with zero framework dependencies.
|
|
25
|
+
* The Preact integration lives in the consumer (views/prd.ts etc.).
|
|
26
|
+
*/
|
|
27
|
+
// ─── Factory ─────────────────────────────────────────────────────────────────
|
|
28
|
+
/**
|
|
29
|
+
* Create a new update batcher.
|
|
30
|
+
*
|
|
31
|
+
* Usage:
|
|
32
|
+
* ```ts
|
|
33
|
+
* const batcher = createUpdateBatcher();
|
|
34
|
+
*
|
|
35
|
+
* // In a WebSocket message handler:
|
|
36
|
+
* coalescer.onMessage = (msg) => {
|
|
37
|
+
* if (msg.type === "rex:item-updated") {
|
|
38
|
+
* batcher.schedule(setData, (prev) => {
|
|
39
|
+
* const newItems = applyItemUpdate(prev.items, msg.itemId, msg.updates);
|
|
40
|
+
* return newItems === prev.items ? prev : { ...prev, items: newItems };
|
|
41
|
+
* });
|
|
42
|
+
* }
|
|
43
|
+
* };
|
|
44
|
+
*
|
|
45
|
+
* // On component unmount:
|
|
46
|
+
* batcher.dispose();
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export function createUpdateBatcher(config) {
|
|
50
|
+
const disabled = config?.disabled ?? false;
|
|
51
|
+
// Map from setter reference → array of updater functions.
|
|
52
|
+
// Using a Map preserves insertion order for deterministic flush ordering.
|
|
53
|
+
let queue = new Map();
|
|
54
|
+
let rafId = null;
|
|
55
|
+
let disposed = false;
|
|
56
|
+
function applyAll() {
|
|
57
|
+
const entries = queue;
|
|
58
|
+
queue = new Map();
|
|
59
|
+
rafId = null;
|
|
60
|
+
for (const entry of entries.values()) {
|
|
61
|
+
// Compose all updaters into a single function call.
|
|
62
|
+
// Each updater receives the output of the previous one.
|
|
63
|
+
const composed = (prev) => {
|
|
64
|
+
let current = prev;
|
|
65
|
+
for (const updater of entry.updaters) {
|
|
66
|
+
current = updater(current);
|
|
67
|
+
}
|
|
68
|
+
return current;
|
|
69
|
+
};
|
|
70
|
+
entry.setter(composed);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function scheduleRAF() {
|
|
74
|
+
if (rafId !== null)
|
|
75
|
+
return; // Already scheduled
|
|
76
|
+
rafId = requestAnimationFrame(applyAll);
|
|
77
|
+
}
|
|
78
|
+
function cancelRAF() {
|
|
79
|
+
if (rafId !== null) {
|
|
80
|
+
cancelAnimationFrame(rafId);
|
|
81
|
+
rafId = null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function schedule(setter, updater) {
|
|
85
|
+
if (disposed)
|
|
86
|
+
return;
|
|
87
|
+
// Disabled mode: apply immediately, no batching.
|
|
88
|
+
if (disabled) {
|
|
89
|
+
setter(updater);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const key = setter;
|
|
93
|
+
let entry = queue.get(key);
|
|
94
|
+
if (!entry) {
|
|
95
|
+
entry = { setter: key, updaters: [] };
|
|
96
|
+
queue.set(key, entry);
|
|
97
|
+
}
|
|
98
|
+
entry.updaters.push(updater);
|
|
99
|
+
scheduleRAF();
|
|
100
|
+
}
|
|
101
|
+
function flush() {
|
|
102
|
+
if (disposed)
|
|
103
|
+
return;
|
|
104
|
+
if (queue.size === 0)
|
|
105
|
+
return;
|
|
106
|
+
cancelRAF();
|
|
107
|
+
applyAll();
|
|
108
|
+
}
|
|
109
|
+
function hasPending() {
|
|
110
|
+
return queue.size > 0;
|
|
111
|
+
}
|
|
112
|
+
function dispose() {
|
|
113
|
+
disposed = true;
|
|
114
|
+
cancelRAF();
|
|
115
|
+
queue = new Map();
|
|
116
|
+
}
|
|
117
|
+
return { schedule, flush, hasPending, dispose };
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=update-batcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-batcher.js","sourceRoot":"","sources":["../../../src/viewer/performance/update-batcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAwDH,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAA4B;IAC9D,MAAM,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,CAAC;IAE3C,0DAA0D;IAC1D,0EAA0E;IAC1E,IAAI,KAAK,GAAG,IAAI,GAAG,EAA0B,CAAC;IAC9C,IAAI,KAAK,GAAkB,IAAI,CAAC;IAChC,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,SAAS,QAAQ;QACf,MAAM,OAAO,GAAG,KAAK,CAAC;QACtB,KAAK,GAAG,IAAI,GAAG,EAAE,CAAC;QAClB,KAAK,GAAG,IAAI,CAAC;QAEb,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YACrC,oDAAoD;YACpD,wDAAwD;YACxD,MAAM,QAAQ,GAAe,CAAC,IAAI,EAAE,EAAE;gBACpC,IAAI,OAAO,GAAG,IAAI,CAAC;gBACnB,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;oBACrC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;gBAC7B,CAAC;gBACD,OAAO,OAAO,CAAC;YACjB,CAAC,CAAC;YAEF,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED,SAAS,WAAW;QAClB,IAAI,KAAK,KAAK,IAAI;YAAE,OAAO,CAAC,oBAAoB;QAChD,KAAK,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;IAED,SAAS,SAAS;QAChB,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,oBAAoB,CAAC,KAAK,CAAC,CAAC;YAC5B,KAAK,GAAG,IAAI,CAAC;QACf,CAAC;IACH,CAAC;IAED,SAAS,QAAQ,CACf,MAAyC,EACzC,OAAuB;QAEvB,IAAI,QAAQ;YAAE,OAAO;QAErB,iDAAiD;QACjD,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,CAAC,OAAO,CAAC,CAAC;YAChB,OAAO;QACT,CAAC;QAED,MAAM,GAAG,GAAG,MAAmB,CAAC;QAChC,IAAI,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;YACtC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACxB,CAAC;QACD,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAqB,CAAC,CAAC;QAE3C,WAAW,EAAE,CAAC;IAChB,CAAC;IAED,SAAS,KAAK;QACZ,IAAI,QAAQ;YAAE,OAAO;QACrB,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO;QAE7B,SAAS,EAAE,CAAC;QACZ,QAAQ,EAAE,CAAC;IACb,CAAC;IAED,SAAS,UAAU;QACjB,OAAO,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;IACxB,CAAC;IAED,SAAS,OAAO;QACd,QAAQ,GAAG,IAAI,CAAC;QAChB,SAAS,EAAE,CAAC;QACZ,KAAK,GAAG,IAAI,GAAG,EAAE,CAAC;IACpB,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Batched tick dispatcher for elapsed time state updates.
|
|
3
|
+
*
|
|
4
|
+
* Sits between the shared tick timer and individual `useTick` hook instances.
|
|
5
|
+
* Instead of N separate `onTick` listeners each calling `setState` independently,
|
|
6
|
+
* this dispatcher:
|
|
7
|
+
*
|
|
8
|
+
* 1. Subscribes to the tick timer **once** (regardless of how many components
|
|
9
|
+
* display elapsed time).
|
|
10
|
+
* 2. On each tick, computes all new values synchronously (read-only phase).
|
|
11
|
+
* 3. Filters out unchanged values via equality check (skip phase).
|
|
12
|
+
* 4. Schedules a single `requestAnimationFrame` to apply all state updates
|
|
13
|
+
* in one synchronous block (write phase).
|
|
14
|
+
*
|
|
15
|
+
* This two-phase (compute → RAF write) approach ensures:
|
|
16
|
+
*
|
|
17
|
+
* - All `setState` calls occur within the same synchronous execution context
|
|
18
|
+
* inside the RAF callback, allowing Preact to batch them into a single
|
|
19
|
+
* reconciliation pass.
|
|
20
|
+
* - State updates are aligned with the browser's paint cycle, eliminating
|
|
21
|
+
* wasted intermediate renders.
|
|
22
|
+
* - With 20+ visible task cards, the re-render count drops from N individual
|
|
23
|
+
* renders to one batched reconciliation per tick.
|
|
24
|
+
*
|
|
25
|
+
* Auto-lifecycle: subscribes to the tick timer when the first component
|
|
26
|
+
* registers, unsubscribes when the last one unregisters. Zero overhead
|
|
27
|
+
* when no elapsed time displays are mounted.
|
|
28
|
+
*
|
|
29
|
+
* Designed as a standalone module with zero framework dependencies —
|
|
30
|
+
* the Preact integration lives in the `useTick` hook.
|
|
31
|
+
*/
|
|
32
|
+
/** Function that computes the current formatted elapsed time string. */
|
|
33
|
+
type ComputeFn = () => string;
|
|
34
|
+
/** Preact state setter for the display value. */
|
|
35
|
+
type SetDisplayFn = (value: string) => void;
|
|
36
|
+
/** Mutable ref object (matches Preact's useRef shape). */
|
|
37
|
+
interface MutableRef<T> {
|
|
38
|
+
current: T;
|
|
39
|
+
}
|
|
40
|
+
/** Read-only snapshot of the dispatcher's current state (for testing/monitoring). */
|
|
41
|
+
export interface BatchedTickDispatcherState {
|
|
42
|
+
/** Number of active registrations. */
|
|
43
|
+
readonly registrationCount: number;
|
|
44
|
+
/** Whether a RAF callback is currently pending. */
|
|
45
|
+
readonly hasPendingRAF: boolean;
|
|
46
|
+
/** Number of state updates queued for the next RAF. */
|
|
47
|
+
readonly pendingUpdateCount: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Register an elapsed time updater with the batched dispatcher.
|
|
51
|
+
*
|
|
52
|
+
* The dispatcher will call `compute()` on each tick, compare the result
|
|
53
|
+
* against `lastValueRef.current`, and — if changed — schedule a batched
|
|
54
|
+
* RAF update that calls `setDisplay(newValue)`.
|
|
55
|
+
*
|
|
56
|
+
* The `lastValueRef` is shared with the calling hook so that both the
|
|
57
|
+
* dispatcher and the hook's immediate-update effect (for `startedAt`
|
|
58
|
+
* prop changes) stay in sync.
|
|
59
|
+
*
|
|
60
|
+
* Returns an unregister function. When the last registration is removed,
|
|
61
|
+
* the dispatcher unsubscribes from the tick timer automatically.
|
|
62
|
+
*
|
|
63
|
+
* @param compute - Pure function returning the current formatted string.
|
|
64
|
+
* @param setDisplay - Preact state setter for the display value.
|
|
65
|
+
* @param lastValueRef - Mutable ref tracking the last emitted value.
|
|
66
|
+
* @returns Unregister function (safe to call multiple times).
|
|
67
|
+
*/
|
|
68
|
+
export declare function registerTickUpdater(compute: ComputeFn, setDisplay: SetDisplayFn, lastValueRef: MutableRef<string>): () => void;
|
|
69
|
+
/**
|
|
70
|
+
* Get the current state of the batched tick dispatcher (for testing/monitoring).
|
|
71
|
+
*/
|
|
72
|
+
export declare function getBatchedTickDispatcherState(): BatchedTickDispatcherState;
|
|
73
|
+
/**
|
|
74
|
+
* Force-flush all pending RAF updates synchronously.
|
|
75
|
+
* Cancels any pending RAF. No-op if nothing is pending.
|
|
76
|
+
*/
|
|
77
|
+
export declare function flushBatchedTicks(): void;
|
|
78
|
+
/**
|
|
79
|
+
* Reset all dispatcher state (for testing). Unsubscribes from the tick
|
|
80
|
+
* timer, cancels pending RAF, and clears all registrations.
|
|
81
|
+
*/
|
|
82
|
+
export declare function resetBatchedTickDispatcher(): void;
|
|
83
|
+
export {};
|