@flanksource/clicky-ui 0.3.54 → 0.3.56
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/NOTICE.md +6 -0
- package/dist/ai.cjs +6 -0
- package/dist/ai.js +3 -1
- package/dist/chat.cjs +2 -0
- package/dist/chat.d.ts +1 -0
- package/dist/chat.d.ts.map +1 -1
- package/dist/chat.js +2 -1
- package/dist/comments/CommentCard.cjs +37 -7
- package/dist/comments/CommentCard.cjs.map +1 -1
- package/dist/comments/CommentCard.d.ts +11 -1
- package/dist/comments/CommentCard.d.ts.map +1 -1
- package/dist/comments/CommentCard.js +37 -7
- package/dist/comments/CommentCard.js.map +1 -1
- package/dist/comments/CommentCardParts.cjs +9 -4
- package/dist/comments/CommentCardParts.cjs.map +1 -1
- package/dist/comments/CommentCardParts.d.ts.map +1 -1
- package/dist/comments/CommentCardParts.js +9 -4
- package/dist/comments/CommentCardParts.js.map +1 -1
- package/dist/comments/CommentComposer.cjs +8 -8
- package/dist/comments/CommentComposer.cjs.map +1 -1
- package/dist/comments/CommentComposer.d.ts.map +1 -1
- package/dist/comments/CommentComposer.js +8 -8
- package/dist/comments/CommentComposer.js.map +1 -1
- package/dist/comments/CommentProvider.cjs +5 -1
- package/dist/comments/CommentProvider.cjs.map +1 -1
- package/dist/comments/CommentProvider.d.ts +1 -1
- package/dist/comments/CommentProvider.d.ts.map +1 -1
- package/dist/comments/CommentProvider.js +5 -1
- package/dist/comments/CommentProvider.js.map +1 -1
- package/dist/comments/CommentSidePanel.cjs +17 -11
- package/dist/comments/CommentSidePanel.cjs.map +1 -1
- package/dist/comments/CommentSidePanel.d.ts +6 -0
- package/dist/comments/CommentSidePanel.d.ts.map +1 -1
- package/dist/comments/CommentSidePanel.js +17 -11
- package/dist/comments/CommentSidePanel.js.map +1 -1
- package/dist/comments/CommentThread.cjs +4 -1
- package/dist/comments/CommentThread.cjs.map +1 -1
- package/dist/comments/CommentThread.d.ts +4 -1
- package/dist/comments/CommentThread.d.ts.map +1 -1
- package/dist/comments/CommentThread.js +4 -1
- package/dist/comments/CommentThread.js.map +1 -1
- package/dist/comments/CommentThreadList.cjs +6 -3
- package/dist/comments/CommentThreadList.cjs.map +1 -1
- package/dist/comments/CommentThreadList.d.ts +7 -2
- package/dist/comments/CommentThreadList.d.ts.map +1 -1
- package/dist/comments/CommentThreadList.js +6 -3
- package/dist/comments/CommentThreadList.js.map +1 -1
- package/dist/comments/MentionTextarea.cjs +1 -1
- package/dist/comments/MentionTextarea.cjs.map +1 -1
- package/dist/comments/MentionTextarea.d.ts.map +1 -1
- package/dist/comments/MentionTextarea.js +1 -1
- package/dist/comments/MentionTextarea.js.map +1 -1
- package/dist/comments/comment-assign.cjs +68 -0
- package/dist/comments/comment-assign.cjs.map +1 -0
- package/dist/comments/comment-assign.d.ts +31 -0
- package/dist/comments/comment-assign.d.ts.map +1 -0
- package/dist/comments/comment-assign.js +67 -0
- package/dist/comments/comment-assign.js.map +1 -0
- package/dist/comments/comment-types.cjs.map +1 -1
- package/dist/comments/comment-types.d.ts +39 -0
- package/dist/comments/comment-types.d.ts.map +1 -1
- package/dist/comments/comment-types.js.map +1 -1
- package/dist/comments/comment-utils.cjs +2 -0
- package/dist/comments/comment-utils.cjs.map +1 -1
- package/dist/comments/comment-utils.d.ts +2 -0
- package/dist/comments/comment-utils.d.ts.map +1 -1
- package/dist/comments/comment-utils.js +2 -0
- package/dist/comments/comment-utils.js.map +1 -1
- package/dist/comments.cjs +3 -0
- package/dist/comments.d.ts +1 -0
- package/dist/comments.d.ts.map +1 -1
- package/dist/comments.js +2 -1
- package/dist/components/ComboboxMenu.cjs +23 -13
- package/dist/components/ComboboxMenu.cjs.map +1 -1
- package/dist/components/ComboboxMenu.d.ts.map +1 -1
- package/dist/components/ComboboxMenu.js +23 -13
- package/dist/components/ComboboxMenu.js.map +1 -1
- package/dist/components/FilterBar.cjs +29 -6
- package/dist/components/FilterBar.cjs.map +1 -1
- package/dist/components/FilterBar.d.ts +3 -1
- package/dist/components/FilterBar.d.ts.map +1 -1
- package/dist/components/FilterBar.js +29 -6
- package/dist/components/FilterBar.js.map +1 -1
- package/dist/components/ItemActions.cjs +1 -1
- package/dist/components/ItemActions.cjs.map +1 -1
- package/dist/components/ItemActions.js +1 -1
- package/dist/components/ItemActions.js.map +1 -1
- package/dist/components/ListMenu.cjs +33 -3
- package/dist/components/ListMenu.cjs.map +1 -1
- package/dist/components/ListMenu.d.ts +4 -1
- package/dist/components/ListMenu.d.ts.map +1 -1
- package/dist/components/ListMenu.js +33 -3
- package/dist/components/ListMenu.js.map +1 -1
- package/dist/components/ListMenuItems.cjs +80 -0
- package/dist/components/ListMenuItems.cjs.map +1 -0
- package/dist/components/ListMenuItems.d.ts +8 -0
- package/dist/components/ListMenuItems.d.ts.map +1 -0
- package/dist/components/ListMenuItems.js +80 -0
- package/dist/components/ListMenuItems.js.map +1 -0
- package/dist/components/LocalPathPicker.cjs +182 -0
- package/dist/components/LocalPathPicker.cjs.map +1 -0
- package/dist/components/LocalPathPicker.d.ts +11 -0
- package/dist/components/LocalPathPicker.d.ts.map +1 -0
- package/dist/components/LocalPathPicker.js +182 -0
- package/dist/components/LocalPathPicker.js.map +1 -0
- package/dist/components/LocalPathTree.cjs +89 -0
- package/dist/components/LocalPathTree.cjs.map +1 -0
- package/dist/components/LocalPathTree.d.ts +9 -0
- package/dist/components/LocalPathTree.d.ts.map +1 -0
- package/dist/components/LocalPathTree.js +89 -0
- package/dist/components/LocalPathTree.js.map +1 -0
- package/dist/components/RangeSlider.cjs +10 -30
- package/dist/components/RangeSlider.cjs.map +1 -1
- package/dist/components/RangeSlider.d.ts.map +1 -1
- package/dist/components/RangeSlider.js +4 -24
- package/dist/components/RangeSlider.js.map +1 -1
- package/dist/components/Slider.cjs +79 -0
- package/dist/components/Slider.cjs.map +1 -0
- package/dist/components/Slider.d.ts +23 -0
- package/dist/components/Slider.d.ts.map +1 -0
- package/dist/components/Slider.js +79 -0
- package/dist/components/Slider.js.map +1 -0
- package/dist/components/combobox-types.d.ts +4 -1
- package/dist/components/combobox-types.d.ts.map +1 -1
- package/dist/components/filter-bar-field-utils.cjs +3 -5
- package/dist/components/filter-bar-field-utils.cjs.map +1 -1
- package/dist/components/filter-bar-field-utils.d.ts.map +1 -1
- package/dist/components/filter-bar-field-utils.js +3 -5
- package/dist/components/filter-bar-field-utils.js.map +1 -1
- package/dist/components/filter-bar-tree-model.cjs +22 -0
- package/dist/components/filter-bar-tree-model.cjs.map +1 -0
- package/dist/components/filter-bar-tree-model.d.ts +33 -0
- package/dist/components/filter-bar-tree-model.d.ts.map +1 -0
- package/dist/components/filter-bar-tree-model.js +21 -0
- package/dist/components/filter-bar-tree-model.js.map +1 -0
- package/dist/components/filter-bar-tree.cjs +84 -0
- package/dist/components/filter-bar-tree.cjs.map +1 -0
- package/dist/components/filter-bar-tree.d.ts +7 -0
- package/dist/components/filter-bar-tree.d.ts.map +1 -0
- package/dist/components/filter-bar-tree.js +84 -0
- package/dist/components/filter-bar-tree.js.map +1 -0
- package/dist/components/json-schema-form-debug-glyph-map.cjs +2 -0
- package/dist/components/json-schema-form-debug-glyph-map.cjs.map +1 -1
- package/dist/components/json-schema-form-debug-glyph-map.d.ts.map +1 -1
- package/dist/components/json-schema-form-debug-glyph-map.js +2 -0
- package/dist/components/json-schema-form-debug-glyph-map.js.map +1 -1
- package/dist/components/json-schema-form-help-links.cjs +18 -0
- package/dist/components/json-schema-form-help-links.cjs.map +1 -0
- package/dist/components/json-schema-form-help-links.d.ts +5 -0
- package/dist/components/json-schema-form-help-links.d.ts.map +1 -0
- package/dist/components/json-schema-form-help-links.js +18 -0
- package/dist/components/json-schema-form-help-links.js.map +1 -0
- package/dist/components/json-schema-form-help-model.cjs +7 -0
- package/dist/components/json-schema-form-help-model.cjs.map +1 -0
- package/dist/components/json-schema-form-help-model.d.ts +3 -0
- package/dist/components/json-schema-form-help-model.d.ts.map +1 -0
- package/dist/components/json-schema-form-help-model.js +7 -0
- package/dist/components/json-schema-form-help-model.js.map +1 -0
- package/dist/components/json-schema-form-json.cjs +48 -0
- package/dist/components/json-schema-form-json.cjs.map +1 -0
- package/dist/components/json-schema-form-json.d.ts +7 -0
- package/dist/components/json-schema-form-json.d.ts.map +1 -0
- package/dist/components/json-schema-form-json.js +48 -0
- package/dist/components/json-schema-form-json.js.map +1 -0
- package/dist/components/json-schema-form-layout.cjs +7 -5
- package/dist/components/json-schema-form-layout.cjs.map +1 -1
- package/dist/components/json-schema-form-layout.d.ts +2 -2
- package/dist/components/json-schema-form-layout.d.ts.map +1 -1
- package/dist/components/json-schema-form-layout.js +7 -5
- package/dist/components/json-schema-form-layout.js.map +1 -1
- package/dist/components/json-schema-form-object.cjs +2 -13
- package/dist/components/json-schema-form-object.cjs.map +1 -1
- package/dist/components/json-schema-form-object.d.ts.map +1 -1
- package/dist/components/json-schema-form-object.js +2 -13
- package/dist/components/json-schema-form-object.js.map +1 -1
- package/dist/components/json-schema-form-refs.cjs +1 -1
- package/dist/components/json-schema-form-refs.cjs.map +1 -1
- package/dist/components/json-schema-form-refs.d.ts.map +1 -1
- package/dist/components/json-schema-form-refs.js +1 -1
- package/dist/components/json-schema-form-refs.js.map +1 -1
- package/dist/components/json-schema-form-render.cjs +20 -6
- package/dist/components/json-schema-form-render.cjs.map +1 -1
- package/dist/components/json-schema-form-render.d.ts.map +1 -1
- package/dist/components/json-schema-form-render.js +20 -6
- package/dist/components/json-schema-form-render.js.map +1 -1
- package/dist/components/json-schema-form-resolve.cjs +22 -2
- package/dist/components/json-schema-form-resolve.cjs.map +1 -1
- package/dist/components/json-schema-form-resolve.d.ts.map +1 -1
- package/dist/components/json-schema-form-resolve.js +22 -2
- package/dist/components/json-schema-form-resolve.js.map +1 -1
- package/dist/components/json-schema-form-types.d.ts +5 -1
- package/dist/components/json-schema-form-types.d.ts.map +1 -1
- package/dist/components/json-schema-form-union-model.cjs +46 -0
- package/dist/components/json-schema-form-union-model.cjs.map +1 -0
- package/dist/components/json-schema-form-union-model.d.ts +6 -0
- package/dist/components/json-schema-form-union-model.d.ts.map +1 -0
- package/dist/components/json-schema-form-union-model.js +43 -0
- package/dist/components/json-schema-form-union-model.js.map +1 -0
- package/dist/components/json-schema-form-union.cjs +52 -0
- package/dist/components/json-schema-form-union.cjs.map +1 -0
- package/dist/components/json-schema-form-union.d.ts +7 -0
- package/dist/components/json-schema-form-union.d.ts.map +1 -0
- package/dist/components/json-schema-form-union.js +52 -0
- package/dist/components/json-schema-form-union.js.map +1 -0
- package/dist/components/list-menu-virtual.cjs +5 -0
- package/dist/components/list-menu-virtual.cjs.map +1 -0
- package/dist/components/list-menu-virtual.d.ts +12 -0
- package/dist/components/list-menu-virtual.d.ts.map +1 -0
- package/dist/components/list-menu-virtual.js +6 -0
- package/dist/components/list-menu-virtual.js.map +1 -0
- package/dist/components/local-path.cjs +12 -0
- package/dist/components/local-path.cjs.map +1 -0
- package/dist/components/local-path.d.ts +14 -0
- package/dist/components/local-path.d.ts.map +1 -0
- package/dist/components/local-path.js +12 -0
- package/dist/components/local-path.js.map +1 -0
- package/dist/components/slider-shared.cjs +32 -0
- package/dist/components/slider-shared.cjs.map +1 -0
- package/dist/components/slider-shared.d.ts +18 -0
- package/dist/components/slider-shared.d.ts.map +1 -0
- package/dist/components/slider-shared.js +27 -0
- package/dist/components/slider-shared.js.map +1 -0
- package/dist/components.cjs +8 -0
- package/dist/components.d.ts +6 -1
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +5 -1
- package/dist/connections/ConnectionsPage.cjs +51 -19
- package/dist/connections/ConnectionsPage.cjs.map +1 -1
- package/dist/connections/ConnectionsPage.d.ts +9 -1
- package/dist/connections/ConnectionsPage.d.ts.map +1 -1
- package/dist/connections/ConnectionsPage.js +52 -20
- package/dist/connections/ConnectionsPage.js.map +1 -1
- package/dist/connections/connectionDashboard.cjs +13 -8
- package/dist/connections/connectionDashboard.cjs.map +1 -1
- package/dist/connections/connectionDashboard.d.ts +8 -3
- package/dist/connections/connectionDashboard.d.ts.map +1 -1
- package/dist/connections/connectionDashboard.js +14 -9
- package/dist/connections/connectionDashboard.js.map +1 -1
- package/dist/connections/connectionDashboardModel.cjs.map +1 -1
- package/dist/connections/connectionDashboardModel.d.ts +4 -0
- package/dist/connections/connectionDashboardModel.d.ts.map +1 -1
- package/dist/connections/connectionDashboardModel.js.map +1 -1
- package/dist/connections/connectionDashboardRow.cjs +75 -55
- package/dist/connections/connectionDashboardRow.cjs.map +1 -1
- package/dist/connections/connectionDashboardRow.d.ts +3 -2
- package/dist/connections/connectionDashboardRow.d.ts.map +1 -1
- package/dist/connections/connectionDashboardRow.js +75 -55
- package/dist/connections/connectionDashboardRow.js.map +1 -1
- package/dist/connections/connectionNamespaceField.cjs +17 -0
- package/dist/connections/connectionNamespaceField.cjs.map +1 -0
- package/dist/connections/connectionNamespaceField.d.ts +10 -0
- package/dist/connections/connectionNamespaceField.d.ts.map +1 -0
- package/dist/connections/connectionNamespaceField.js +17 -0
- package/dist/connections/connectionNamespaceField.js.map +1 -0
- package/dist/connections/connectionSchemaFormExtensions.cjs +98 -0
- package/dist/connections/connectionSchemaFormExtensions.cjs.map +1 -0
- package/dist/connections/connectionSchemaFormExtensions.d.ts +41 -0
- package/dist/connections/connectionSchemaFormExtensions.d.ts.map +1 -0
- package/dist/connections/connectionSchemaFormExtensions.js +96 -0
- package/dist/connections/connectionSchemaFormExtensions.js.map +1 -0
- package/dist/connections/connectionsPageModel.cjs +11 -0
- package/dist/connections/connectionsPageModel.cjs.map +1 -1
- package/dist/connections/connectionsPageModel.d.ts +5 -0
- package/dist/connections/connectionsPageModel.d.ts.map +1 -1
- package/dist/connections/connectionsPageModel.js +11 -1
- package/dist/connections/connectionsPageModel.js.map +1 -1
- package/dist/connections.cjs +5 -0
- package/dist/connections.d.ts +2 -1
- package/dist/connections.d.ts.map +1 -1
- package/dist/connections.js +3 -2
- package/dist/data/AvatarBadge.cjs +3 -3
- package/dist/data/AvatarBadge.cjs.map +1 -1
- package/dist/data/AvatarBadge.js +3 -3
- package/dist/data/AvatarBadge.js.map +1 -1
- package/dist/data/CodeDiff.cjs +2 -0
- package/dist/data/CodeDiff.cjs.map +1 -1
- package/dist/data/CodeDiff.js +2 -0
- package/dist/data/CodeDiff.js.map +1 -1
- package/dist/data/DataTable.cjs +3 -2
- package/dist/data/DataTable.cjs.map +1 -1
- package/dist/data/DataTable.d.ts.map +1 -1
- package/dist/data/DataTable.js +3 -2
- package/dist/data/DataTable.js.map +1 -1
- package/dist/data/Gauge.cjs +1 -1
- package/dist/data/Gauge.cjs.map +1 -1
- package/dist/data/Gauge.js +1 -1
- package/dist/data/Gauge.js.map +1 -1
- package/dist/data/HighlightedTokens.cjs +2 -10
- package/dist/data/HighlightedTokens.cjs.map +1 -1
- package/dist/data/HighlightedTokens.d.ts.map +1 -1
- package/dist/data/HighlightedTokens.js +1 -9
- package/dist/data/HighlightedTokens.js.map +1 -1
- package/dist/data/Markdown.cjs +38 -11
- package/dist/data/Markdown.cjs.map +1 -1
- package/dist/data/Markdown.d.ts +9 -1
- package/dist/data/Markdown.d.ts.map +1 -1
- package/dist/data/Markdown.js +39 -12
- package/dist/data/Markdown.js.map +1 -1
- package/dist/data/MultiGaugeBar.cjs +157 -0
- package/dist/data/MultiGaugeBar.cjs.map +1 -0
- package/dist/data/MultiGaugeBar.d.ts +29 -0
- package/dist/data/MultiGaugeBar.d.ts.map +1 -0
- package/dist/data/MultiGaugeBar.js +157 -0
- package/dist/data/MultiGaugeBar.js.map +1 -0
- package/dist/data/OpenInFilesLink.cjs +27 -0
- package/dist/data/OpenInFilesLink.cjs.map +1 -0
- package/dist/data/OpenInFilesLink.d.ts +15 -0
- package/dist/data/OpenInFilesLink.d.ts.map +1 -0
- package/dist/data/OpenInFilesLink.js +27 -0
- package/dist/data/OpenInFilesLink.js.map +1 -0
- package/dist/data/ProgressBar.cjs +5 -3
- package/dist/data/ProgressBar.cjs.map +1 -1
- package/dist/data/ProgressBar.d.ts +5 -1
- package/dist/data/ProgressBar.d.ts.map +1 -1
- package/dist/data/ProgressBar.js +5 -3
- package/dist/data/ProgressBar.js.map +1 -1
- package/dist/data/ProgressBars.cjs +13 -5
- package/dist/data/ProgressBars.cjs.map +1 -1
- package/dist/data/ProgressBars.d.ts +6 -1
- package/dist/data/ProgressBars.d.ts.map +1 -1
- package/dist/data/ProgressBars.js +13 -5
- package/dist/data/ProgressBars.js.map +1 -1
- package/dist/data/Properties.cjs +3 -3
- package/dist/data/Properties.cjs.map +1 -1
- package/dist/data/Properties.js +3 -3
- package/dist/data/Properties.js.map +1 -1
- package/dist/data/TaskProgress.cjs +14 -6
- package/dist/data/TaskProgress.cjs.map +1 -1
- package/dist/data/TaskProgress.d.ts +3 -1
- package/dist/data/TaskProgress.d.ts.map +1 -1
- package/dist/data/TaskProgress.js +14 -6
- package/dist/data/TaskProgress.js.map +1 -1
- package/dist/data/TaskPrompts.cjs +96 -0
- package/dist/data/TaskPrompts.cjs.map +1 -0
- package/dist/data/TaskPrompts.d.ts +6 -0
- package/dist/data/TaskPrompts.d.ts.map +1 -0
- package/dist/data/TaskPrompts.js +96 -0
- package/dist/data/TaskPrompts.js.map +1 -0
- package/dist/data/TaskSnapshot.cjs.map +1 -1
- package/dist/data/TaskSnapshot.d.ts +3 -0
- package/dist/data/TaskSnapshot.d.ts.map +1 -1
- package/dist/data/TaskSnapshot.js.map +1 -1
- package/dist/data/TimeseriesCoreBars.cjs +7 -3
- package/dist/data/TimeseriesCoreBars.cjs.map +1 -1
- package/dist/data/TimeseriesCoreBars.d.ts.map +1 -1
- package/dist/data/TimeseriesCoreBars.js +8 -4
- package/dist/data/TimeseriesCoreBars.js.map +1 -1
- package/dist/data/TimeseriesGauge.cjs +12 -5
- package/dist/data/TimeseriesGauge.cjs.map +1 -1
- package/dist/data/TimeseriesGauge.d.ts.map +1 -1
- package/dist/data/TimeseriesGauge.js +13 -6
- package/dist/data/TimeseriesGauge.js.map +1 -1
- package/dist/data/TimeseriesPanel.cjs +10 -9
- package/dist/data/TimeseriesPanel.cjs.map +1 -1
- package/dist/data/TimeseriesPanel.d.ts +1 -1
- package/dist/data/TimeseriesPanel.d.ts.map +1 -1
- package/dist/data/TimeseriesPanel.js +11 -10
- package/dist/data/TimeseriesPanel.js.map +1 -1
- package/dist/data/TimeseriesPanel.model.cjs +62 -10
- package/dist/data/TimeseriesPanel.model.cjs.map +1 -1
- package/dist/data/TimeseriesPanel.model.d.ts +40 -1
- package/dist/data/TimeseriesPanel.model.d.ts.map +1 -1
- package/dist/data/TimeseriesPanel.model.js +62 -11
- package/dist/data/TimeseriesPanel.model.js.map +1 -1
- package/dist/data/WorkloadCard.cjs +7 -3
- package/dist/data/WorkloadCard.cjs.map +1 -1
- package/dist/data/WorkloadCard.d.ts +3 -1
- package/dist/data/WorkloadCard.d.ts.map +1 -1
- package/dist/data/WorkloadCard.js +7 -3
- package/dist/data/WorkloadCard.js.map +1 -1
- package/dist/data/WorkloadCard.model.cjs.map +1 -1
- package/dist/data/WorkloadCard.model.d.ts +2 -0
- package/dist/data/WorkloadCard.model.d.ts.map +1 -1
- package/dist/data/WorkloadCard.model.js.map +1 -1
- package/dist/data/ai/ChatWindow.placement.cjs +2 -1
- package/dist/data/ai/ChatWindow.placement.cjs.map +1 -1
- package/dist/data/ai/ChatWindow.placement.d.ts +1 -1
- package/dist/data/ai/ChatWindow.placement.d.ts.map +1 -1
- package/dist/data/ai/ChatWindow.placement.js +2 -1
- package/dist/data/ai/ChatWindow.placement.js.map +1 -1
- package/dist/data/ai/SpecRuntimeBar.cjs +2 -2
- package/dist/data/ai/SpecRuntimeBar.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeBar.d.ts +4 -1
- package/dist/data/ai/SpecRuntimeBar.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeBar.js +2 -2
- package/dist/data/ai/SpecRuntimeBar.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/PromptSection.cjs +1 -1
- package/dist/data/ai/SpecRuntimeEditor/PromptSection.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/PromptSection.js +1 -1
- package/dist/data/ai/SpecRuntimeEditor/PromptSection.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor.model.cjs +2 -2
- package/dist/data/ai/SpecRuntimeEditor.model.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor.model.d.ts +2 -2
- package/dist/data/ai/SpecRuntimeEditor.model.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor.model.js +2 -2
- package/dist/data/ai/SpecRuntimeEditor.model.js.map +1 -1
- package/dist/data/ai/ThreadPicker.cjs +2 -2
- package/dist/data/ai/ThreadPicker.cjs.map +1 -1
- package/dist/data/ai/ThreadPicker.js +2 -2
- package/dist/data/ai/ThreadPicker.js.map +1 -1
- package/dist/data/ai/index.d.ts +2 -0
- package/dist/data/ai/index.d.ts.map +1 -1
- package/dist/data/ai/use-prompt-run-stream.cjs +126 -0
- package/dist/data/ai/use-prompt-run-stream.cjs.map +1 -0
- package/dist/data/ai/use-prompt-run-stream.d.ts +52 -0
- package/dist/data/ai/use-prompt-run-stream.d.ts.map +1 -0
- package/dist/data/ai/use-prompt-run-stream.js +126 -0
- package/dist/data/ai/use-prompt-run-stream.js.map +1 -0
- package/dist/data/cache-browser/CacheBrowser.cjs +1 -0
- package/dist/data/cache-browser/CacheBrowser.cjs.map +1 -1
- package/dist/data/cache-browser/CacheBrowser.d.ts.map +1 -1
- package/dist/data/cache-browser/CacheBrowser.js +1 -0
- package/dist/data/cache-browser/CacheBrowser.js.map +1 -1
- package/dist/data/charts/BarChart.cjs +194 -0
- package/dist/data/charts/BarChart.cjs.map +1 -0
- package/dist/data/charts/BarChart.d.ts +19 -0
- package/dist/data/charts/BarChart.d.ts.map +1 -0
- package/dist/data/charts/BarChart.js +194 -0
- package/dist/data/charts/BarChart.js.map +1 -0
- package/dist/data/charts/ChartLegend.cjs +54 -0
- package/dist/data/charts/ChartLegend.cjs.map +1 -0
- package/dist/data/charts/ChartLegend.d.ts +17 -0
- package/dist/data/charts/ChartLegend.d.ts.map +1 -0
- package/dist/data/charts/ChartLegend.js +54 -0
- package/dist/data/charts/ChartLegend.js.map +1 -0
- package/dist/data/charts/Sparkline.cjs +56 -0
- package/dist/data/charts/Sparkline.cjs.map +1 -0
- package/dist/data/charts/Sparkline.d.ts +15 -0
- package/dist/data/charts/Sparkline.d.ts.map +1 -0
- package/dist/data/charts/Sparkline.js +56 -0
- package/dist/data/charts/Sparkline.js.map +1 -0
- package/dist/data/charts/StackedBarChart.cjs +241 -0
- package/dist/data/charts/StackedBarChart.cjs.map +1 -0
- package/dist/data/charts/StackedBarChart.d.ts +20 -0
- package/dist/data/charts/StackedBarChart.d.ts.map +1 -0
- package/dist/data/charts/StackedBarChart.js +241 -0
- package/dist/data/charts/StackedBarChart.js.map +1 -0
- package/dist/data/charts/TrendChart.cjs +157 -0
- package/dist/data/charts/TrendChart.cjs.map +1 -0
- package/dist/data/charts/TrendChart.d.ts +20 -0
- package/dist/data/charts/TrendChart.d.ts.map +1 -0
- package/dist/data/charts/TrendChart.js +157 -0
- package/dist/data/charts/TrendChart.js.map +1 -0
- package/dist/data/charts/chart-marks.cjs +115 -0
- package/dist/data/charts/chart-marks.cjs.map +1 -0
- package/dist/data/charts/chart-marks.d.ts +39 -0
- package/dist/data/charts/chart-marks.d.ts.map +1 -0
- package/dist/data/charts/chart-marks.js +112 -0
- package/dist/data/charts/chart-marks.js.map +1 -0
- package/dist/data/charts/chart-palette.cjs +74 -0
- package/dist/data/charts/chart-palette.cjs.map +1 -0
- package/dist/data/charts/chart-palette.d.ts +58 -0
- package/dist/data/charts/chart-palette.d.ts.map +1 -0
- package/dist/data/charts/chart-palette.js +72 -0
- package/dist/data/charts/chart-palette.js.map +1 -0
- package/dist/data/charts/chart-scale.cjs +115 -0
- package/dist/data/charts/chart-scale.cjs.map +1 -0
- package/dist/data/charts/chart-scale.d.ts +41 -0
- package/dist/data/charts/chart-scale.d.ts.map +1 -0
- package/dist/data/charts/chart-scale.js +104 -0
- package/dist/data/charts/chart-scale.js.map +1 -0
- package/dist/data/charts/chart.test-utils.d.ts +7 -0
- package/dist/data/charts/chart.test-utils.d.ts.map +1 -0
- package/dist/data/charts/index.d.ts +7 -0
- package/dist/data/charts/index.d.ts.map +1 -0
- package/dist/data/chat/MessageActions.cjs +1 -1
- package/dist/data/chat/MessageActions.cjs.map +1 -1
- package/dist/data/chat/MessageActions.js +1 -1
- package/dist/data/chat/MessageActions.js.map +1 -1
- package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs +1 -1
- package/dist/data/diagnostics/DiagnosticsDetailPanel.js +1 -1
- package/dist/data/diagnostics/DiagnosticsTree.cjs +1 -1
- package/dist/data/diagnostics/DiagnosticsTree.cjs.map +1 -1
- package/dist/data/diagnostics/DiagnosticsTree.js +1 -1
- package/dist/data/diagnostics/DiagnosticsTree.js.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.cjs +9 -2
- package/dist/data/diagnostics/FrameSourceWindow.cjs.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.d.ts +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.d.ts.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.js +9 -2
- package/dist/data/diagnostics/FrameSourceWindow.js.map +1 -1
- package/dist/data/diagnostics/ProblemActions.cjs +37 -0
- package/dist/data/diagnostics/ProblemActions.cjs.map +1 -0
- package/dist/data/diagnostics/ProblemActions.d.ts +6 -0
- package/dist/data/diagnostics/ProblemActions.d.ts.map +1 -0
- package/dist/data/diagnostics/ProblemActions.js +37 -0
- package/dist/data/diagnostics/ProblemActions.js.map +1 -0
- package/dist/data/diagnostics/ProblemFacet.cjs +33 -0
- package/dist/data/diagnostics/ProblemFacet.cjs.map +1 -0
- package/dist/data/diagnostics/ProblemFacet.d.ts +9 -0
- package/dist/data/diagnostics/ProblemFacet.d.ts.map +1 -0
- package/dist/data/diagnostics/ProblemFacet.js +33 -0
- package/dist/data/diagnostics/ProblemFacet.js.map +1 -0
- package/dist/data/diagnostics/ProblemRow.cjs +62 -0
- package/dist/data/diagnostics/ProblemRow.cjs.map +1 -0
- package/dist/data/diagnostics/ProblemRow.d.ts +14 -0
- package/dist/data/diagnostics/ProblemRow.d.ts.map +1 -0
- package/dist/data/diagnostics/ProblemRow.js +62 -0
- package/dist/data/diagnostics/ProblemRow.js.map +1 -0
- package/dist/data/diagnostics/ProblemViewOptions.cjs +18 -0
- package/dist/data/diagnostics/ProblemViewOptions.cjs.map +1 -0
- package/dist/data/diagnostics/ProblemViewOptions.d.ts +6 -0
- package/dist/data/diagnostics/ProblemViewOptions.d.ts.map +1 -0
- package/dist/data/diagnostics/ProblemViewOptions.js +18 -0
- package/dist/data/diagnostics/ProblemViewOptions.js.map +1 -0
- package/dist/data/diagnostics/StackFrameRow.cjs +1 -1
- package/dist/data/diagnostics/StackFrameRow.cjs.map +1 -1
- package/dist/data/diagnostics/StackFrameRow.js +1 -1
- package/dist/data/diagnostics/StackFrameRow.js.map +1 -1
- package/dist/data/diagnostics/diagnostic-identity.cjs +14 -0
- package/dist/data/diagnostics/diagnostic-identity.cjs.map +1 -0
- package/dist/data/diagnostics/diagnostic-identity.d.ts +3 -0
- package/dist/data/diagnostics/diagnostic-identity.d.ts.map +1 -0
- package/dist/data/diagnostics/diagnostic-identity.js +14 -0
- package/dist/data/diagnostics/diagnostic-identity.js.map +1 -0
- package/dist/data/diagnostics/use-problem-expansion.cjs +16 -0
- package/dist/data/diagnostics/use-problem-expansion.cjs.map +1 -0
- package/dist/data/diagnostics/use-problem-expansion.d.ts +3 -0
- package/dist/data/diagnostics/use-problem-expansion.d.ts.map +1 -0
- package/dist/data/diagnostics/use-problem-expansion.js +16 -0
- package/dist/data/diagnostics/use-problem-expansion.js.map +1 -0
- package/dist/data/git/GitChangeList.cjs +9 -6
- package/dist/data/git/GitChangeList.cjs.map +1 -1
- package/dist/data/git/GitChangeList.d.ts +6 -0
- package/dist/data/git/GitChangeList.d.ts.map +1 -1
- package/dist/data/git/GitChangeList.js +9 -6
- package/dist/data/git/GitChangeList.js.map +1 -1
- package/dist/data/git/pickers/GitPickersDemo.d.ts.map +1 -1
- package/dist/data/git/pickers/ReferencePicker.cjs +1 -0
- package/dist/data/git/pickers/ReferencePicker.cjs.map +1 -1
- package/dist/data/git/pickers/ReferencePicker.js +1 -0
- package/dist/data/git/pickers/ReferencePicker.js.map +1 -1
- package/dist/data/lint/LintDetail.cjs +230 -189
- package/dist/data/lint/LintDetail.cjs.map +1 -1
- package/dist/data/lint/LintDetail.d.ts +25 -3
- package/dist/data/lint/LintDetail.d.ts.map +1 -1
- package/dist/data/lint/LintDetail.js +231 -192
- package/dist/data/lint/LintDetail.js.map +1 -1
- package/dist/data/lint/LintFilterBar.cjs +78 -83
- package/dist/data/lint/LintFilterBar.cjs.map +1 -1
- package/dist/data/lint/LintFilterBar.d.ts +23 -6
- package/dist/data/lint/LintFilterBar.d.ts.map +1 -1
- package/dist/data/lint/LintFilterBar.js +78 -85
- package/dist/data/lint/LintFilterBar.js.map +1 -1
- package/dist/data/lint/LintIgnoreMenu.cjs +59 -0
- package/dist/data/lint/LintIgnoreMenu.cjs.map +1 -0
- package/dist/data/lint/LintIgnoreMenu.d.ts +20 -0
- package/dist/data/lint/LintIgnoreMenu.d.ts.map +1 -0
- package/dist/data/lint/LintIgnoreMenu.js +58 -0
- package/dist/data/lint/LintIgnoreMenu.js.map +1 -0
- package/dist/data/lint/LintResults.cjs +59 -14
- package/dist/data/lint/LintResults.cjs.map +1 -1
- package/dist/data/lint/LintResults.d.ts +25 -1
- package/dist/data/lint/LintResults.d.ts.map +1 -1
- package/dist/data/lint/LintResults.fixtures.d.ts +19 -0
- package/dist/data/lint/LintResults.fixtures.d.ts.map +1 -1
- package/dist/data/lint/LintResults.js +60 -15
- package/dist/data/lint/LintResults.js.map +1 -1
- package/dist/data/lint/LintTable.cjs +156 -0
- package/dist/data/lint/LintTable.cjs.map +1 -0
- package/dist/data/lint/LintTable.d.ts +13 -0
- package/dist/data/lint/LintTable.d.ts.map +1 -0
- package/dist/data/lint/LintTable.js +156 -0
- package/dist/data/lint/LintTable.js.map +1 -0
- package/dist/data/lint/LintTreeNode.cjs +42 -19
- package/dist/data/lint/LintTreeNode.cjs.map +1 -1
- package/dist/data/lint/LintTreeNode.d.ts +7 -2
- package/dist/data/lint/LintTreeNode.d.ts.map +1 -1
- package/dist/data/lint/LintTreeNode.js +44 -21
- package/dist/data/lint/LintTreeNode.js.map +1 -1
- package/dist/data/lint/ViolationSnippet.cjs +113 -0
- package/dist/data/lint/ViolationSnippet.cjs.map +1 -0
- package/dist/data/lint/ViolationSnippet.d.ts +20 -0
- package/dist/data/lint/ViolationSnippet.d.ts.map +1 -0
- package/dist/data/lint/ViolationSnippet.js +112 -0
- package/dist/data/lint/ViolationSnippet.js.map +1 -0
- package/dist/data/lint/actions.cjs +44 -16
- package/dist/data/lint/actions.cjs.map +1 -1
- package/dist/data/lint/actions.d.ts +7 -3
- package/dist/data/lint/actions.d.ts.map +1 -1
- package/dist/data/lint/actions.js +44 -16
- package/dist/data/lint/actions.js.map +1 -1
- package/dist/data/lint/grouping.cjs +105 -8
- package/dist/data/lint/grouping.cjs.map +1 -1
- package/dist/data/lint/grouping.d.ts +21 -1
- package/dist/data/lint/grouping.d.ts.map +1 -1
- package/dist/data/lint/grouping.js +105 -10
- package/dist/data/lint/grouping.js.map +1 -1
- package/dist/data/lint/ignore-menu-items.cjs +18 -0
- package/dist/data/lint/ignore-menu-items.cjs.map +1 -0
- package/dist/data/lint/ignore-menu-items.d.ts +6 -0
- package/dist/data/lint/ignore-menu-items.d.ts.map +1 -0
- package/dist/data/lint/ignore-menu-items.js +17 -0
- package/dist/data/lint/ignore-menu-items.js.map +1 -0
- package/dist/data/lint/index.d.ts +7 -5
- package/dist/data/lint/index.d.ts.map +1 -1
- package/dist/data/lint/stats.cjs +19 -4
- package/dist/data/lint/stats.cjs.map +1 -1
- package/dist/data/lint/stats.d.ts +13 -3
- package/dist/data/lint/stats.d.ts.map +1 -1
- package/dist/data/lint/stats.js +17 -5
- package/dist/data/lint/stats.js.map +1 -1
- package/dist/data/lint/types.cjs +8 -0
- package/dist/data/lint/types.cjs.map +1 -1
- package/dist/data/lint/types.d.ts +47 -0
- package/dist/data/lint/types.d.ts.map +1 -1
- package/dist/data/lint/types.js +8 -1
- package/dist/data/lint/types.js.map +1 -1
- package/dist/data/lint/violation-menu-items.cjs +31 -0
- package/dist/data/lint/violation-menu-items.cjs.map +1 -0
- package/dist/data/lint/violation-menu-items.d.ts +12 -0
- package/dist/data/lint/violation-menu-items.d.ts.map +1 -0
- package/dist/data/lint/violation-menu-items.js +31 -0
- package/dist/data/lint/violation-menu-items.js.map +1 -0
- package/dist/data/markdown-source-blocks.cjs +38 -0
- package/dist/data/markdown-source-blocks.cjs.map +1 -0
- package/dist/data/markdown-source-blocks.d.ts +32 -0
- package/dist/data/markdown-source-blocks.d.ts.map +1 -0
- package/dist/data/markdown-source-blocks.js +35 -0
- package/dist/data/markdown-source-blocks.js.map +1 -0
- package/dist/data/test-runner/FilterFacet.cjs +52 -0
- package/dist/data/test-runner/FilterFacet.cjs.map +1 -0
- package/dist/data/test-runner/FilterFacet.d.ts +13 -0
- package/dist/data/test-runner/FilterFacet.d.ts.map +1 -0
- package/dist/data/test-runner/FilterFacet.js +52 -0
- package/dist/data/test-runner/FilterFacet.js.map +1 -0
- package/dist/data/test-runner/MatrixMarks.cjs +42 -40
- package/dist/data/test-runner/MatrixMarks.cjs.map +1 -1
- package/dist/data/test-runner/MatrixMarks.d.ts +20 -4
- package/dist/data/test-runner/MatrixMarks.d.ts.map +1 -1
- package/dist/data/test-runner/MatrixMarks.js +43 -42
- package/dist/data/test-runner/MatrixMarks.js.map +1 -1
- package/dist/data/test-runner/TestAttemptDetail.cjs +1 -1
- package/dist/data/test-runner/TestAttemptDetail.js +1 -1
- package/dist/data/test-runner/TestDetailPanel.cjs +11 -0
- package/dist/data/test-runner/TestDetailPanel.cjs.map +1 -1
- package/dist/data/test-runner/TestDetailPanel.d.ts.map +1 -1
- package/dist/data/test-runner/TestDetailPanel.js +11 -0
- package/dist/data/test-runner/TestDetailPanel.js.map +1 -1
- package/dist/data/test-runner/TestFilterBar.cjs +3 -44
- package/dist/data/test-runner/TestFilterBar.cjs.map +1 -1
- package/dist/data/test-runner/TestFilterBar.d.ts.map +1 -1
- package/dist/data/test-runner/TestFilterBar.js +3 -44
- package/dist/data/test-runner/TestFilterBar.js.map +1 -1
- package/dist/data/test-runner/TestRunner.cjs +3 -1
- package/dist/data/test-runner/TestRunner.cjs.map +1 -1
- package/dist/data/test-runner/TestRunner.d.ts +7 -1
- package/dist/data/test-runner/TestRunner.d.ts.map +1 -1
- package/dist/data/test-runner/TestRunner.js +3 -1
- package/dist/data/test-runner/TestRunner.js.map +1 -1
- package/dist/data/test-runner/context.cjs.map +1 -1
- package/dist/data/test-runner/context.d.ts +3 -0
- package/dist/data/test-runner/context.d.ts.map +1 -1
- package/dist/data/test-runner/context.js.map +1 -1
- package/dist/data/test-runner/index.d.ts +2 -2
- package/dist/data/test-runner/index.d.ts.map +1 -1
- package/dist/data/test-runner/matrix-marks.cjs +2 -11
- package/dist/data/test-runner/matrix-marks.cjs.map +1 -1
- package/dist/data/test-runner/matrix-marks.d.ts +2 -4
- package/dist/data/test-runner/matrix-marks.d.ts.map +1 -1
- package/dist/data/test-runner/matrix-marks.js +3 -11
- package/dist/data/test-runner/matrix-marks.js.map +1 -1
- package/dist/data/test-runner/types.d.ts +2 -0
- package/dist/data/test-runner/types.d.ts.map +1 -1
- package/dist/data/timeseries-query.cjs +98 -2
- package/dist/data/timeseries-query.cjs.map +1 -1
- package/dist/data/timeseries-query.d.ts +31 -5
- package/dist/data/timeseries-query.d.ts.map +1 -1
- package/dist/data/timeseries-query.js +98 -3
- package/dist/data/timeseries-query.js.map +1 -1
- package/dist/data/timeseries-stream-provider.cjs +38 -0
- package/dist/data/timeseries-stream-provider.cjs.map +1 -0
- package/dist/data/timeseries-stream-provider.d.ts +26 -0
- package/dist/data/timeseries-stream-provider.d.ts.map +1 -0
- package/dist/data/timeseries-stream-provider.js +38 -0
- package/dist/data/timeseries-stream-provider.js.map +1 -0
- package/dist/data/timeseries-stream.cjs +304 -0
- package/dist/data/timeseries-stream.cjs.map +1 -0
- package/dist/data/timeseries-stream.d.ts +81 -0
- package/dist/data/timeseries-stream.d.ts.map +1 -0
- package/dist/data/timeseries-stream.fixtures.d.ts +36 -0
- package/dist/data/timeseries-stream.fixtures.d.ts.map +1 -0
- package/dist/data/timeseries-stream.js +296 -0
- package/dist/data/timeseries-stream.js.map +1 -0
- package/dist/data/token-style.cjs +13 -0
- package/dist/data/token-style.cjs.map +1 -0
- package/dist/data/token-style.d.ts +4 -0
- package/dist/data/token-style.d.ts.map +1 -0
- package/dist/data/token-style.js +13 -0
- package/dist/data/token-style.js.map +1 -0
- package/dist/data/traces/ProcessTraceDetail.cjs +1 -1
- package/dist/data/traces/ProcessTraceDetail.js +1 -1
- package/dist/data/traces/index.d.ts +1 -1
- package/dist/data/traces/index.d.ts.map +1 -1
- package/dist/data/use-data-table-virtual.d.ts +1 -1
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data/workload-panel/MemoryStack.cjs +49 -0
- package/dist/data/workload-panel/MemoryStack.cjs.map +1 -0
- package/dist/data/workload-panel/MemoryStack.d.ts +11 -0
- package/dist/data/workload-panel/MemoryStack.d.ts.map +1 -0
- package/dist/data/workload-panel/MemoryStack.js +48 -0
- package/dist/data/workload-panel/MemoryStack.js.map +1 -0
- package/dist/data/workload-panel/Metrics.cjs +197 -0
- package/dist/data/workload-panel/Metrics.cjs.map +1 -0
- package/dist/data/workload-panel/Metrics.d.ts +11 -0
- package/dist/data/workload-panel/Metrics.d.ts.map +1 -0
- package/dist/data/workload-panel/Metrics.js +196 -0
- package/dist/data/workload-panel/Metrics.js.map +1 -0
- package/dist/data/workload-panel/WorkloadPanel.cjs +66 -0
- package/dist/data/workload-panel/WorkloadPanel.cjs.map +1 -0
- package/dist/data/workload-panel/WorkloadPanel.d.ts +3 -0
- package/dist/data/workload-panel/WorkloadPanel.d.ts.map +1 -0
- package/dist/data/workload-panel/WorkloadPanel.js +66 -0
- package/dist/data/workload-panel/WorkloadPanel.js.map +1 -0
- package/dist/data/workload-panel/fixtures.d.ts +60 -0
- package/dist/data/workload-panel/fixtures.d.ts.map +1 -0
- package/dist/data/workload-panel/model.cjs +137 -0
- package/dist/data/workload-panel/model.cjs.map +1 -0
- package/dist/data/workload-panel/model.d.ts +53 -0
- package/dist/data/workload-panel/model.d.ts.map +1 -0
- package/dist/data/workload-panel/model.js +133 -0
- package/dist/data/workload-panel/model.js.map +1 -0
- package/dist/data/workload-panel/types.d.ts +56 -0
- package/dist/data/workload-panel/types.d.ts.map +1 -0
- package/dist/data.cjs +58 -7
- package/dist/data.d.ts +9 -1
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +29 -12
- package/dist/file-findings/AnnotatedCode.cjs +243 -0
- package/dist/file-findings/AnnotatedCode.cjs.map +1 -0
- package/dist/file-findings/AnnotatedCode.d.ts +30 -0
- package/dist/file-findings/AnnotatedCode.d.ts.map +1 -0
- package/dist/file-findings/AnnotatedCode.js +243 -0
- package/dist/file-findings/AnnotatedCode.js.map +1 -0
- package/dist/file-findings/FileFindingsView.cjs +213 -0
- package/dist/file-findings/FileFindingsView.cjs.map +1 -0
- package/dist/file-findings/FileFindingsView.d.ts +35 -0
- package/dist/file-findings/FileFindingsView.d.ts.map +1 -0
- package/dist/file-findings/FileFindingsView.js +213 -0
- package/dist/file-findings/FileFindingsView.js.map +1 -0
- package/dist/file-findings/LazyAnnotatedCode.cjs +22 -0
- package/dist/file-findings/LazyAnnotatedCode.cjs.map +1 -0
- package/dist/file-findings/LazyAnnotatedCode.d.ts +5 -0
- package/dist/file-findings/LazyAnnotatedCode.d.ts.map +1 -0
- package/dist/file-findings/LazyAnnotatedCode.js +22 -0
- package/dist/file-findings/LazyAnnotatedCode.js.map +1 -0
- package/dist/file-findings/adapters.cjs +155 -0
- package/dist/file-findings/adapters.cjs.map +1 -0
- package/dist/file-findings/adapters.d.ts +24 -0
- package/dist/file-findings/adapters.d.ts.map +1 -0
- package/dist/file-findings/adapters.js +153 -0
- package/dist/file-findings/adapters.js.map +1 -0
- package/dist/file-findings/file-review/CommentDraft.cjs +97 -0
- package/dist/file-findings/file-review/CommentDraft.cjs.map +1 -0
- package/dist/file-findings/file-review/CommentDraft.d.ts +25 -0
- package/dist/file-findings/file-review/CommentDraft.d.ts.map +1 -0
- package/dist/file-findings/file-review/CommentDraft.js +97 -0
- package/dist/file-findings/file-review/CommentDraft.js.map +1 -0
- package/dist/file-findings/file-review/FileReview.cjs +863 -0
- package/dist/file-findings/file-review/FileReview.cjs.map +1 -0
- package/dist/file-findings/file-review/FileReview.d.ts +79 -0
- package/dist/file-findings/file-review/FileReview.d.ts.map +1 -0
- package/dist/file-findings/file-review/FileReview.fixtures.d.ts +25 -0
- package/dist/file-findings/file-review/FileReview.fixtures.d.ts.map +1 -0
- package/dist/file-findings/file-review/FileReview.js +863 -0
- package/dist/file-findings/file-review/FileReview.js.map +1 -0
- package/dist/file-findings/file-review/InlineAuthors.cjs +77 -0
- package/dist/file-findings/file-review/InlineAuthors.cjs.map +1 -0
- package/dist/file-findings/file-review/InlineAuthors.d.ts +9 -0
- package/dist/file-findings/file-review/InlineAuthors.d.ts.map +1 -0
- package/dist/file-findings/file-review/InlineAuthors.js +77 -0
- package/dist/file-findings/file-review/InlineAuthors.js.map +1 -0
- package/dist/file-findings/file-review/InlineThread.cjs +77 -0
- package/dist/file-findings/file-review/InlineThread.cjs.map +1 -0
- package/dist/file-findings/file-review/InlineThread.d.ts +27 -0
- package/dist/file-findings/file-review/InlineThread.d.ts.map +1 -0
- package/dist/file-findings/file-review/InlineThread.js +77 -0
- package/dist/file-findings/file-review/InlineThread.js.map +1 -0
- package/dist/file-findings/file-review/ProblemsList.cjs +164 -0
- package/dist/file-findings/file-review/ProblemsList.cjs.map +1 -0
- package/dist/file-findings/file-review/ProblemsList.d.ts +15 -0
- package/dist/file-findings/file-review/ProblemsList.d.ts.map +1 -0
- package/dist/file-findings/file-review/ProblemsList.js +164 -0
- package/dist/file-findings/file-review/ProblemsList.js.map +1 -0
- package/dist/file-findings/file-review/SourceView.cjs +179 -0
- package/dist/file-findings/file-review/SourceView.cjs.map +1 -0
- package/dist/file-findings/file-review/SourceView.d.ts +29 -0
- package/dist/file-findings/file-review/SourceView.d.ts.map +1 -0
- package/dist/file-findings/file-review/SourceView.js +179 -0
- package/dist/file-findings/file-review/SourceView.js.map +1 -0
- package/dist/file-findings/file-review/blame.cjs +35 -0
- package/dist/file-findings/file-review/blame.cjs.map +1 -0
- package/dist/file-findings/file-review/blame.d.ts +28 -0
- package/dist/file-findings/file-review/blame.d.ts.map +1 -0
- package/dist/file-findings/file-review/blame.js +33 -0
- package/dist/file-findings/file-review/blame.js.map +1 -0
- package/dist/file-findings/file-review/geometry.cjs +101 -0
- package/dist/file-findings/file-review/geometry.cjs.map +1 -0
- package/dist/file-findings/file-review/geometry.d.ts +45 -0
- package/dist/file-findings/file-review/geometry.d.ts.map +1 -0
- package/dist/file-findings/file-review/geometry.js +98 -0
- package/dist/file-findings/file-review/geometry.js.map +1 -0
- package/dist/file-findings/file-review/hooks.cjs +101 -0
- package/dist/file-findings/file-review/hooks.cjs.map +1 -0
- package/dist/file-findings/file-review/hooks.d.ts +22 -0
- package/dist/file-findings/file-review/hooks.d.ts.map +1 -0
- package/dist/file-findings/file-review/hooks.js +99 -0
- package/dist/file-findings/file-review/hooks.js.map +1 -0
- package/dist/file-findings/file-review/marks.cjs +52 -0
- package/dist/file-findings/file-review/marks.cjs.map +1 -0
- package/dist/file-findings/file-review/marks.d.ts +23 -0
- package/dist/file-findings/file-review/marks.d.ts.map +1 -0
- package/dist/file-findings/file-review/marks.js +47 -0
- package/dist/file-findings/file-review/marks.js.map +1 -0
- package/dist/file-findings/file-review/problem-filters.cjs +14 -0
- package/dist/file-findings/file-review/problem-filters.cjs.map +1 -0
- package/dist/file-findings/file-review/problem-filters.d.ts +10 -0
- package/dist/file-findings/file-review/problem-filters.d.ts.map +1 -0
- package/dist/file-findings/file-review/problem-filters.js +13 -0
- package/dist/file-findings/file-review/problem-filters.js.map +1 -0
- package/dist/file-findings/file-review/quote-anchor.cjs +234 -0
- package/dist/file-findings/file-review/quote-anchor.cjs.map +1 -0
- package/dist/file-findings/file-review/quote-anchor.d.ts +54 -0
- package/dist/file-findings/file-review/quote-anchor.d.ts.map +1 -0
- package/dist/file-findings/file-review/quote-anchor.js +226 -0
- package/dist/file-findings/file-review/quote-anchor.js.map +1 -0
- package/dist/file-findings/file-review/source-anchor.cjs +104 -0
- package/dist/file-findings/file-review/source-anchor.cjs.map +1 -0
- package/dist/file-findings/file-review/source-anchor.d.ts +27 -0
- package/dist/file-findings/file-review/source-anchor.d.ts.map +1 -0
- package/dist/file-findings/file-review/source-anchor.js +99 -0
- package/dist/file-findings/file-review/source-anchor.js.map +1 -0
- package/dist/file-findings/file-review/source-marks.cjs +71 -0
- package/dist/file-findings/file-review/source-marks.cjs.map +1 -0
- package/dist/file-findings/file-review/source-marks.d.ts +27 -0
- package/dist/file-findings/file-review/source-marks.d.ts.map +1 -0
- package/dist/file-findings/file-review/source-marks.js +68 -0
- package/dist/file-findings/file-review/source-marks.js.map +1 -0
- package/dist/file-findings/findings-comments.cjs +136 -0
- package/dist/file-findings/findings-comments.cjs.map +1 -0
- package/dist/file-findings/findings-comments.d.ts +28 -0
- package/dist/file-findings/findings-comments.d.ts.map +1 -0
- package/dist/file-findings/findings-comments.js +131 -0
- package/dist/file-findings/findings-comments.js.map +1 -0
- package/dist/file-findings/findings-languages.cjs +53 -0
- package/dist/file-findings/findings-languages.cjs.map +1 -0
- package/dist/file-findings/findings-languages.d.ts +11 -0
- package/dist/file-findings/findings-languages.d.ts.map +1 -0
- package/dist/file-findings/findings-languages.js +53 -0
- package/dist/file-findings/findings-languages.js.map +1 -0
- package/dist/file-findings/mdx-source.cjs +48 -0
- package/dist/file-findings/mdx-source.cjs.map +1 -0
- package/dist/file-findings/mdx-source.d.ts +7 -0
- package/dist/file-findings/mdx-source.d.ts.map +1 -0
- package/dist/file-findings/mdx-source.js +48 -0
- package/dist/file-findings/mdx-source.js.map +1 -0
- package/dist/file-findings/monaco-language.cjs +73 -0
- package/dist/file-findings/monaco-language.cjs.map +1 -0
- package/dist/file-findings/monaco-language.d.ts +11 -0
- package/dist/file-findings/monaco-language.d.ts.map +1 -0
- package/dist/file-findings/monaco-language.js +72 -0
- package/dist/file-findings/monaco-language.js.map +1 -0
- package/dist/file-findings/severity-counts.cjs +20 -0
- package/dist/file-findings/severity-counts.cjs.map +1 -0
- package/dist/file-findings/severity-counts.d.ts +5 -0
- package/dist/file-findings/severity-counts.d.ts.map +1 -0
- package/dist/file-findings/severity-counts.js +19 -0
- package/dist/file-findings/severity-counts.js.map +1 -0
- package/dist/file-findings/types.cjs +12 -0
- package/dist/file-findings/types.cjs.map +1 -0
- package/dist/file-findings/types.d.ts +43 -0
- package/dist/file-findings/types.d.ts.map +1 -0
- package/dist/file-findings/types.js +11 -0
- package/dist/file-findings/types.js.map +1 -0
- package/dist/file-findings.cjs +47 -0
- package/dist/file-findings.d.ts +15 -0
- package/dist/file-findings.d.ts.map +1 -0
- package/dist/file-findings.js +15 -0
- package/dist/hooks/event-hub.cjs +22 -8
- package/dist/hooks/event-hub.cjs.map +1 -1
- package/dist/hooks/event-hub.d.ts.map +1 -1
- package/dist/hooks/event-hub.js +22 -8
- package/dist/hooks/event-hub.js.map +1 -1
- package/dist/icons/components/UiBrowser.cjs +51 -0
- package/dist/icons/components/UiBrowser.cjs.map +1 -0
- package/dist/icons/components/UiBrowser.d.ts +15 -0
- package/dist/icons/components/UiBrowser.d.ts.map +1 -0
- package/dist/icons/components/UiBrowser.js +48 -0
- package/dist/icons/components/UiBrowser.js.map +1 -0
- package/dist/icons/components/UiCreditCard.cjs +51 -0
- package/dist/icons/components/UiCreditCard.cjs.map +1 -0
- package/dist/icons/components/UiCreditCard.d.ts +15 -0
- package/dist/icons/components/UiCreditCard.d.ts.map +1 -0
- package/dist/icons/components/UiCreditCard.js +48 -0
- package/dist/icons/components/UiCreditCard.js.map +1 -0
- package/dist/icons/components/UiShoppingCart.cjs +51 -0
- package/dist/icons/components/UiShoppingCart.cjs.map +1 -0
- package/dist/icons/components/UiShoppingCart.d.ts +15 -0
- package/dist/icons/components/UiShoppingCart.d.ts.map +1 -0
- package/dist/icons/components/UiShoppingCart.js +48 -0
- package/dist/icons/components/UiShoppingCart.js.map +1 -0
- package/dist/icons/index.d.ts +6 -0
- package/dist/icons/index.d.ts.map +1 -1
- package/dist/icons/registry.cjs +6 -0
- package/dist/icons/registry.cjs.map +1 -1
- package/dist/icons/registry.d.ts.map +1 -1
- package/dist/icons/registry.js +6 -0
- package/dist/icons/registry.js.map +1 -1
- package/dist/icons.cjs +9 -0
- package/dist/icons.js +4 -1
- package/dist/index.cjs +76 -8
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -14
- package/dist/layout/AppShell.cjs +37 -21
- package/dist/layout/AppShell.cjs.map +1 -1
- package/dist/layout/AppShell.d.ts +13 -2
- package/dist/layout/AppShell.d.ts.map +1 -1
- package/dist/layout/AppShell.js +37 -21
- package/dist/layout/AppShell.js.map +1 -1
- package/dist/layout/AppShell.nav.cjs +7 -6
- package/dist/layout/AppShell.nav.cjs.map +1 -1
- package/dist/layout/AppShell.nav.d.ts.map +1 -1
- package/dist/layout/AppShell.nav.js +7 -6
- package/dist/layout/AppShell.nav.js.map +1 -1
- package/dist/layout/SplitPane.cjs +16 -6
- package/dist/layout/SplitPane.cjs.map +1 -1
- package/dist/layout/SplitPane.d.ts +12 -2
- package/dist/layout/SplitPane.d.ts.map +1 -1
- package/dist/layout/SplitPane.js +16 -6
- package/dist/layout/SplitPane.js.map +1 -1
- package/dist/layout/Workspace.cjs +37 -33
- package/dist/layout/Workspace.cjs.map +1 -1
- package/dist/layout/Workspace.d.ts.map +1 -1
- package/dist/layout/Workspace.js +37 -33
- package/dist/layout/Workspace.js.map +1 -1
- package/dist/layout/Workspace.regions.cjs +3 -3
- package/dist/layout/Workspace.regions.cjs.map +1 -1
- package/dist/layout/Workspace.regions.js +3 -3
- package/dist/layout/Workspace.regions.js.map +1 -1
- package/dist/lib/breakpoints.cjs +102 -0
- package/dist/lib/breakpoints.cjs.map +1 -0
- package/dist/lib/breakpoints.d.ts +36 -0
- package/dist/lib/breakpoints.d.ts.map +1 -0
- package/dist/lib/breakpoints.js +99 -0
- package/dist/lib/breakpoints.js.map +1 -0
- package/dist/lib/combobox.cjs +2 -1
- package/dist/lib/combobox.cjs.map +1 -1
- package/dist/lib/combobox.d.ts +1 -1
- package/dist/lib/combobox.d.ts.map +1 -1
- package/dist/lib/combobox.js +2 -1
- package/dist/lib/combobox.js.map +1 -1
- package/dist/lib/path-tree.cjs +21 -0
- package/dist/lib/path-tree.cjs.map +1 -1
- package/dist/lib/path-tree.d.ts +15 -0
- package/dist/lib/path-tree.d.ts.map +1 -1
- package/dist/lib/path-tree.js +21 -1
- package/dist/lib/path-tree.js.map +1 -1
- package/dist/overlay/Modal.cjs +2 -1
- package/dist/overlay/Modal.cjs.map +1 -1
- package/dist/overlay/Modal.d.ts.map +1 -1
- package/dist/overlay/Modal.js +2 -1
- package/dist/overlay/Modal.js.map +1 -1
- package/dist/overlay/dropdownMenuContext.d.ts +1 -1
- package/dist/profiles/editor/profileEditor.cjs +1 -1
- package/dist/profiles/editor/profileEditor.cjs.map +1 -1
- package/dist/profiles/editor/profileEditor.js +1 -1
- package/dist/profiles/editor/profileEditor.js.map +1 -1
- package/dist/profiles/editor/profileEditorSections.cjs +2 -2
- package/dist/profiles/editor/profileEditorSections.cjs.map +1 -1
- package/dist/profiles/editor/profileEditorSections.js +2 -2
- package/dist/profiles/editor/profileEditorSections.js.map +1 -1
- package/dist/profiles/query/prometheusResults.cjs +24 -36
- package/dist/profiles/query/prometheusResults.cjs.map +1 -1
- package/dist/profiles/query/prometheusResults.d.ts.map +1 -1
- package/dist/profiles/query/prometheusResults.js +24 -36
- package/dist/profiles/query/prometheusResults.js.map +1 -1
- package/dist/rpc/CommandForm.cjs +1 -1
- package/dist/rpc/CommandForm.cjs.map +1 -1
- package/dist/rpc/CommandForm.js +1 -1
- package/dist/rpc/CommandForm.js.map +1 -1
- package/dist/rpc/classify.cjs +1 -1
- package/dist/rpc/classify.cjs.map +1 -1
- package/dist/rpc/classify.d.ts.map +1 -1
- package/dist/rpc/classify.js +1 -1
- package/dist/rpc/classify.js.map +1 -1
- package/dist/rpc/useOperations.d.ts +24 -24
- package/dist/rpc.cjs +0 -2
- package/dist/rpc.d.ts +0 -1
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +1 -2
- package/dist/styles.css +1 -1
- package/dist/utils.cjs +6 -0
- package/dist/utils.d.ts +2 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +3 -2
- package/package.json +9 -3
- package/schemas/json-schema-form.schema.json +9 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// src/file-findings/severity-counts.ts
|
|
2
|
+
/** Severities worst first, the order counts are shown in. */
|
|
3
|
+
var FINDING_SEVERITIES = [
|
|
4
|
+
"error",
|
|
5
|
+
"warning",
|
|
6
|
+
"info"
|
|
7
|
+
];
|
|
8
|
+
function countFindingsBySeverity(findings) {
|
|
9
|
+
const counts = {
|
|
10
|
+
error: 0,
|
|
11
|
+
warning: 0,
|
|
12
|
+
info: 0
|
|
13
|
+
};
|
|
14
|
+
for (const finding of findings) counts[finding.severity] += 1;
|
|
15
|
+
return counts;
|
|
16
|
+
}
|
|
17
|
+
export { FINDING_SEVERITIES, countFindingsBySeverity };
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=severity-counts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"severity-counts.js","names":[],"sources":["../../src/file-findings/severity-counts.ts"],"sourcesContent":["import type { FileFinding, LintSeverity } from \"./types\";\n\n/** Severities worst first, the order counts are shown in. */\nexport const FINDING_SEVERITIES: readonly LintSeverity[] = [\"error\", \"warning\", \"info\"];\n\nexport function countFindingsBySeverity(findings: readonly FileFinding[]): Record<LintSeverity, number> {\n const counts: Record<LintSeverity, number> = { error: 0, warning: 0, info: 0 };\n for (const finding of findings) counts[finding.severity] += 1;\n return counts;\n}\n"],"mappings":";;AAGA,IAAa,qBAA8C;CAAC;CAAS;CAAW;AAAM;AAEtF,SAAgB,wBAAwB,UAAgE;CACtG,MAAM,SAAuC;EAAE,OAAO;EAAG,SAAS;EAAG,MAAM;CAAE;CAC7E,KAAK,MAAM,WAAW,UAAU,OAAO,QAAQ,aAAa;CAC5D,OAAO;AACT"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// src/file-findings/types.ts
|
|
2
|
+
function fileRefKey(ref) {
|
|
3
|
+
return `${ref.workDir ?? ""}\u0000${ref.file}`;
|
|
4
|
+
}
|
|
5
|
+
function sameFileRef(a, b) {
|
|
6
|
+
if (!a || !b) return a === b;
|
|
7
|
+
return a.file === b.file && (a.workDir ?? "") === (b.workDir ?? "");
|
|
8
|
+
}
|
|
9
|
+
exports.fileRefKey = fileRefKey;
|
|
10
|
+
exports.sameFileRef = sameFileRef;
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=types.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.cjs","names":[],"sources":["../../src/file-findings/types.ts"],"sourcesContent":["// One finding against one line of one file, whichever tool raised it. Lint\n// violations and failed tests both project onto this shape so a single view\n// can overlay them on the file's source.\n\nimport type { LintSeverity } from \"../data/lint/types\";\n\nexport type { LintSeverity };\n\nexport type FindingKind = \"lint\" | \"test\";\n\nexport type FileFinding = {\n /** Path relative to `workDir` when it lives under it, otherwise as the tool reported it. */\n file: string;\n /** Root `file` is relative to; absent when the tool reported none. */\n workDir?: string | undefined;\n /** 1-based first line of the finding. */\n line: number;\n /** 1-based first column. */\n column?: number | undefined;\n /** 1-based last line of the finding's range. */\n endLine?: number | undefined;\n /** 1-based column just past the range on `endLine`. */\n endColumn?: number | undefined;\n severity: LintSeverity;\n message: string;\n /** The linter or test framework that raised it. */\n source: string;\n /** Rule id for lint findings; the test name for test findings. */\n rule?: string | undefined;\n kind: FindingKind;\n};\n\n/** Identifies a file within a findings set: the same relative path can exist under several work dirs. */\nexport type FileRef = {\n workDir?: string | undefined;\n file: string;\n};\n\nexport type FileTreeNode = {\n /** Stable, unique key (folders collapsed into a child keep the child's key). */\n key: string;\n name: string;\n kind: \"folder\" | \"file\";\n children?: FileTreeNode[] | undefined;\n /** Set on `file` nodes. */\n ref?: FileRef | undefined;\n /** Findings in this file, or beneath this folder. */\n findings: FileFinding[];\n};\n\nexport function fileRefKey(ref: FileRef): string {\n return `${ref.workDir ?? \"\"}\\u0000${ref.file}`;\n}\n\nexport function sameFileRef(a: FileRef | null, b: FileRef | null): boolean {\n if (!a || !b) return a === b;\n return a.file === b.file && (a.workDir ?? \"\") === (b.workDir ?? \"\");\n}\n"],"mappings":";AAkDA,SAAgB,WAAW,KAAsB;CAC/C,OAAO,GAAG,IAAI,WAAW,GAAG,QAAQ,IAAI;AAC1C;AAEA,SAAgB,YAAY,GAAmB,GAA4B;CACzE,IAAI,CAAC,KAAK,CAAC,GAAG,OAAO,MAAM;CAC3B,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,SAAS,EAAE,WAAW;AAClE"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { LintSeverity } from '../data/lint/types.js';
|
|
2
|
+
export type { LintSeverity };
|
|
3
|
+
export type FindingKind = "lint" | "test";
|
|
4
|
+
export type FileFinding = {
|
|
5
|
+
/** Path relative to `workDir` when it lives under it, otherwise as the tool reported it. */
|
|
6
|
+
file: string;
|
|
7
|
+
/** Root `file` is relative to; absent when the tool reported none. */
|
|
8
|
+
workDir?: string | undefined;
|
|
9
|
+
/** 1-based first line of the finding. */
|
|
10
|
+
line: number;
|
|
11
|
+
/** 1-based first column. */
|
|
12
|
+
column?: number | undefined;
|
|
13
|
+
/** 1-based last line of the finding's range. */
|
|
14
|
+
endLine?: number | undefined;
|
|
15
|
+
/** 1-based column just past the range on `endLine`. */
|
|
16
|
+
endColumn?: number | undefined;
|
|
17
|
+
severity: LintSeverity;
|
|
18
|
+
message: string;
|
|
19
|
+
/** The linter or test framework that raised it. */
|
|
20
|
+
source: string;
|
|
21
|
+
/** Rule id for lint findings; the test name for test findings. */
|
|
22
|
+
rule?: string | undefined;
|
|
23
|
+
kind: FindingKind;
|
|
24
|
+
};
|
|
25
|
+
/** Identifies a file within a findings set: the same relative path can exist under several work dirs. */
|
|
26
|
+
export type FileRef = {
|
|
27
|
+
workDir?: string | undefined;
|
|
28
|
+
file: string;
|
|
29
|
+
};
|
|
30
|
+
export type FileTreeNode = {
|
|
31
|
+
/** Stable, unique key (folders collapsed into a child keep the child's key). */
|
|
32
|
+
key: string;
|
|
33
|
+
name: string;
|
|
34
|
+
kind: "folder" | "file";
|
|
35
|
+
children?: FileTreeNode[] | undefined;
|
|
36
|
+
/** Set on `file` nodes. */
|
|
37
|
+
ref?: FileRef | undefined;
|
|
38
|
+
/** Findings in this file, or beneath this folder. */
|
|
39
|
+
findings: FileFinding[];
|
|
40
|
+
};
|
|
41
|
+
export declare function fileRefKey(ref: FileRef): string;
|
|
42
|
+
export declare function sameFileRef(a: FileRef | null, b: FileRef | null): boolean;
|
|
43
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/file-findings/types.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,YAAY,EAAE,YAAY,EAAE,CAAC;AAE7B,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC;AAE1C,MAAM,MAAM,WAAW,GAAG;IACxB,4FAA4F;IAC5F,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,QAAQ,EAAE,YAAY,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,IAAI,EAAE,WAAW,CAAC;CACnB,CAAC;AAEF,yGAAyG;AACzG,MAAM,MAAM,OAAO,GAAG;IACpB,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,gFAAgF;IAChF,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,YAAY,EAAE,GAAG,SAAS,CAAC;IACtC,2BAA2B;IAC3B,GAAG,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1B,qDAAqD;IACrD,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB,CAAC;AAEF,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAE/C;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,EAAE,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,CAGzE"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// src/file-findings/types.ts
|
|
2
|
+
function fileRefKey(ref) {
|
|
3
|
+
return `${ref.workDir ?? ""}\u0000${ref.file}`;
|
|
4
|
+
}
|
|
5
|
+
function sameFileRef(a, b) {
|
|
6
|
+
if (!a || !b) return a === b;
|
|
7
|
+
return a.file === b.file && (a.workDir ?? "") === (b.workDir ?? "");
|
|
8
|
+
}
|
|
9
|
+
export { fileRefKey, sameFileRef };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../../src/file-findings/types.ts"],"sourcesContent":["// One finding against one line of one file, whichever tool raised it. Lint\n// violations and failed tests both project onto this shape so a single view\n// can overlay them on the file's source.\n\nimport type { LintSeverity } from \"../data/lint/types\";\n\nexport type { LintSeverity };\n\nexport type FindingKind = \"lint\" | \"test\";\n\nexport type FileFinding = {\n /** Path relative to `workDir` when it lives under it, otherwise as the tool reported it. */\n file: string;\n /** Root `file` is relative to; absent when the tool reported none. */\n workDir?: string | undefined;\n /** 1-based first line of the finding. */\n line: number;\n /** 1-based first column. */\n column?: number | undefined;\n /** 1-based last line of the finding's range. */\n endLine?: number | undefined;\n /** 1-based column just past the range on `endLine`. */\n endColumn?: number | undefined;\n severity: LintSeverity;\n message: string;\n /** The linter or test framework that raised it. */\n source: string;\n /** Rule id for lint findings; the test name for test findings. */\n rule?: string | undefined;\n kind: FindingKind;\n};\n\n/** Identifies a file within a findings set: the same relative path can exist under several work dirs. */\nexport type FileRef = {\n workDir?: string | undefined;\n file: string;\n};\n\nexport type FileTreeNode = {\n /** Stable, unique key (folders collapsed into a child keep the child's key). */\n key: string;\n name: string;\n kind: \"folder\" | \"file\";\n children?: FileTreeNode[] | undefined;\n /** Set on `file` nodes. */\n ref?: FileRef | undefined;\n /** Findings in this file, or beneath this folder. */\n findings: FileFinding[];\n};\n\nexport function fileRefKey(ref: FileRef): string {\n return `${ref.workDir ?? \"\"}\\u0000${ref.file}`;\n}\n\nexport function sameFileRef(a: FileRef | null, b: FileRef | null): boolean {\n if (!a || !b) return a === b;\n return a.file === b.file && (a.workDir ?? \"\") === (b.workDir ?? \"\");\n}\n"],"mappings":";AAkDA,SAAgB,WAAW,KAAsB;CAC/C,OAAO,GAAG,IAAI,WAAW,GAAG,QAAQ,IAAI;AAC1C;AAEA,SAAgB,YAAY,GAAmB,GAA4B;CACzE,IAAI,CAAC,KAAK,CAAC,GAAG,OAAO,MAAM;CAC3B,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,SAAS,EAAE,WAAW;AAClE"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_types = require("./file-findings/types.cjs");
|
|
3
|
+
const require_adapters = require("./file-findings/adapters.cjs");
|
|
4
|
+
const require_findings_comments = require("./file-findings/findings-comments.cjs");
|
|
5
|
+
const require_LazyAnnotatedCode = require("./file-findings/LazyAnnotatedCode.cjs");
|
|
6
|
+
const require_mdx_source = require("./file-findings/mdx-source.cjs");
|
|
7
|
+
const require_quote_anchor = require("./file-findings/file-review/quote-anchor.cjs");
|
|
8
|
+
const require_geometry = require("./file-findings/file-review/geometry.cjs");
|
|
9
|
+
const require_severity_counts = require("./file-findings/severity-counts.cjs");
|
|
10
|
+
const require_problem_filters = require("./file-findings/file-review/problem-filters.cjs");
|
|
11
|
+
const require_blame = require("./file-findings/file-review/blame.cjs");
|
|
12
|
+
const require_source_anchor = require("./file-findings/file-review/source-anchor.cjs");
|
|
13
|
+
const require_FileReview = require("./file-findings/file-review/FileReview.cjs");
|
|
14
|
+
const require_FileFindingsView = require("./file-findings/FileFindingsView.cjs");
|
|
15
|
+
const require_monaco_language = require("./file-findings/monaco-language.cjs");
|
|
16
|
+
exports.AnnotatedCode = require_LazyAnnotatedCode.AnnotatedCode;
|
|
17
|
+
exports.FINDINGS_COMMENT_CONFIG = require_findings_comments.FINDINGS_COMMENT_CONFIG;
|
|
18
|
+
exports.FileFindingsView = require_FileFindingsView.FileFindingsView;
|
|
19
|
+
exports.FileReview = require_FileReview.FileReview;
|
|
20
|
+
exports.QUOTE_PREFIX = require_quote_anchor.QUOTE_PREFIX;
|
|
21
|
+
exports.SOURCE_PREFIX = require_source_anchor.SOURCE_PREFIX;
|
|
22
|
+
exports.blameAge = require_blame.blameAge;
|
|
23
|
+
exports.blankMdxPreamble = require_mdx_source.blankMdxPreamble;
|
|
24
|
+
exports.blockAnchor = require_findings_comments.blockAnchor;
|
|
25
|
+
exports.countFindingsBySeverity = require_severity_counts.countFindingsBySeverity;
|
|
26
|
+
exports.describeQuote = require_quote_anchor.describeQuote;
|
|
27
|
+
exports.describeSource = require_source_anchor.describeSource;
|
|
28
|
+
exports.emptyProblemFilters = require_problem_filters.emptyProblemFilters;
|
|
29
|
+
exports.fileRefKey = require_types.fileRefKey;
|
|
30
|
+
exports.findingsToComments = require_findings_comments.findingsToComments;
|
|
31
|
+
exports.groupFindingsByFile = require_adapters.groupFindingsByFile;
|
|
32
|
+
exports.isUncommitted = require_blame.isUncommitted;
|
|
33
|
+
exports.lineAnchor = require_findings_comments.lineAnchor;
|
|
34
|
+
exports.lineRangeAnchorResolver = require_findings_comments.lineRangeAnchorResolver;
|
|
35
|
+
exports.lintFindings = require_adapters.lintFindings;
|
|
36
|
+
exports.markdownOutline = require_quote_anchor.markdownOutline;
|
|
37
|
+
exports.monacoLanguageForPath = require_monaco_language.monacoLanguageForPath;
|
|
38
|
+
exports.parseQuoteAnchor = require_quote_anchor.parseQuoteAnchor;
|
|
39
|
+
exports.parseSourceAnchor = require_source_anchor.parseSourceAnchor;
|
|
40
|
+
exports.problemType = require_problem_filters.problemType;
|
|
41
|
+
exports.quoteAnchor = require_quote_anchor.quoteAnchor;
|
|
42
|
+
exports.resolveQuote = require_quote_anchor.resolveQuote;
|
|
43
|
+
exports.resolveSource = require_source_anchor.resolveSource;
|
|
44
|
+
exports.sameFileRef = require_types.sameFileRef;
|
|
45
|
+
exports.sourceAnchor = require_source_anchor.sourceAnchor;
|
|
46
|
+
exports.sourceBlockOf = require_geometry.sourceBlockOf;
|
|
47
|
+
exports.testFindings = require_adapters.testFindings;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { FileFindingsView, type FileFindingsViewProps } from './file-findings/FileFindingsView.js';
|
|
2
|
+
export { AnnotatedCode, type AnnotatedCodeProps } from './file-findings/LazyAnnotatedCode.js';
|
|
3
|
+
export { FileReview, type FileReviewComments, type FileReviewLayout, type FileReviewProps, type FileReviewView, } from './file-findings/file-review/FileReview.js';
|
|
4
|
+
export { emptyProblemFilters, problemType, type ProblemFilters } from './file-findings/file-review/problem-filters.js';
|
|
5
|
+
export { QUOTE_PREFIX, describeQuote, markdownOutline, parseQuoteAnchor, quoteAnchor, resolveQuote, type OutlineEntry, type QuoteLocator, } from './file-findings/file-review/quote-anchor.js';
|
|
6
|
+
export { SOURCE_PREFIX, describeSource, parseSourceAnchor, resolveSource, sourceAnchor, type SourceLocator, } from './file-findings/file-review/source-anchor.js';
|
|
7
|
+
export { blameAge, isUncommitted, type BlameCommit, type BlameRange } from './file-findings/file-review/blame.js';
|
|
8
|
+
export { sourceBlockOf, type AnchorMode } from './file-findings/file-review/geometry.js';
|
|
9
|
+
export { countFindingsBySeverity } from './file-findings/severity-counts.js';
|
|
10
|
+
export { groupFindingsByFile, lintFindings, testFindings } from './file-findings/adapters.js';
|
|
11
|
+
export { FINDINGS_COMMENT_CONFIG, blockAnchor, findingsToComments, lineAnchor, lineRangeAnchorResolver, } from './file-findings/findings-comments.js';
|
|
12
|
+
export { blankMdxPreamble } from './file-findings/mdx-source.js';
|
|
13
|
+
export { monacoLanguageForPath } from './file-findings/monaco-language.js';
|
|
14
|
+
export { fileRefKey, sameFileRef, type FileFinding, type FileRef, type FileTreeNode, type FindingKind, type LintSeverity, } from './file-findings/types.js';
|
|
15
|
+
//# sourceMappingURL=file-findings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-findings.d.ts","sourceRoot":"","sources":["../src/file-findings.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAChG,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAC3F,OAAO,EACL,UAAU,EACV,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,cAAc,GACpB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,6CAA6C,CAAC;AACpH,OAAO,EACL,YAAY,EACZ,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,KAAK,YAAY,EACjB,KAAK,YAAY,GAClB,MAAM,0CAA0C,CAAC;AAClD,OAAO,EACL,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,KAAK,aAAa,GACnB,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAC/G,OAAO,EAAE,aAAa,EAAE,KAAK,UAAU,EAAE,MAAM,sCAAsC,CAAC;AACtF,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC3F,OAAO,EACL,uBAAuB,EACvB,WAAW,EACX,kBAAkB,EAClB,UAAU,EACV,uBAAuB,GACxB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EACL,UAAU,EACV,WAAW,EACX,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,YAAY,GAClB,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { fileRefKey, sameFileRef } from "./file-findings/types.js";
|
|
2
|
+
import { groupFindingsByFile, lintFindings, testFindings } from "./file-findings/adapters.js";
|
|
3
|
+
import { FINDINGS_COMMENT_CONFIG, blockAnchor, findingsToComments, lineAnchor, lineRangeAnchorResolver } from "./file-findings/findings-comments.js";
|
|
4
|
+
import { AnnotatedCode } from "./file-findings/LazyAnnotatedCode.js";
|
|
5
|
+
import { blankMdxPreamble } from "./file-findings/mdx-source.js";
|
|
6
|
+
import { QUOTE_PREFIX, describeQuote, markdownOutline, parseQuoteAnchor, quoteAnchor, resolveQuote } from "./file-findings/file-review/quote-anchor.js";
|
|
7
|
+
import { sourceBlockOf } from "./file-findings/file-review/geometry.js";
|
|
8
|
+
import { countFindingsBySeverity } from "./file-findings/severity-counts.js";
|
|
9
|
+
import { emptyProblemFilters, problemType } from "./file-findings/file-review/problem-filters.js";
|
|
10
|
+
import { blameAge, isUncommitted } from "./file-findings/file-review/blame.js";
|
|
11
|
+
import { SOURCE_PREFIX, describeSource, parseSourceAnchor, resolveSource, sourceAnchor } from "./file-findings/file-review/source-anchor.js";
|
|
12
|
+
import { FileReview } from "./file-findings/file-review/FileReview.js";
|
|
13
|
+
import { FileFindingsView } from "./file-findings/FileFindingsView.js";
|
|
14
|
+
import { monacoLanguageForPath } from "./file-findings/monaco-language.js";
|
|
15
|
+
export { AnnotatedCode, FINDINGS_COMMENT_CONFIG, FileFindingsView, FileReview, QUOTE_PREFIX, SOURCE_PREFIX, blameAge, blankMdxPreamble, blockAnchor, countFindingsBySeverity, describeQuote, describeSource, emptyProblemFilters, fileRefKey, findingsToComments, groupFindingsByFile, isUncommitted, lineAnchor, lineRangeAnchorResolver, lintFindings, markdownOutline, monacoLanguageForPath, parseQuoteAnchor, parseSourceAnchor, problemType, quoteAnchor, resolveQuote, resolveSource, sameFileRef, sourceAnchor, sourceBlockOf, testFindings };
|
package/dist/hooks/event-hub.cjs
CHANGED
|
@@ -73,11 +73,22 @@ function createEventHub(options = {}) {
|
|
|
73
73
|
reloadedForBuildMismatch = true;
|
|
74
74
|
onBuildMismatch();
|
|
75
75
|
}
|
|
76
|
-
function failSub(sub, message,
|
|
76
|
+
function failSub(sub, message, context = {}) {
|
|
77
77
|
sub.readyState = READY_STATE_CLOSED;
|
|
78
|
-
dispatch(sub, "error", new
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
dispatch(sub, "error", new ErrorEvent("error", { message }));
|
|
79
|
+
const status = context.status === void 0 ? "" : ` (status ${context.status})`;
|
|
80
|
+
const line = `[event-hub] ${sub.url} failed${status}: ${message}`;
|
|
81
|
+
if (context.cause !== void 0) console.error(line, context.cause);
|
|
82
|
+
else console.error(line);
|
|
83
|
+
}
|
|
84
|
+
async function refusedSubscribeMessage(res) {
|
|
85
|
+
const body = (await res.text()).trim();
|
|
86
|
+
if (body === "") return `subscribe failed with status ${res.status} and no error message`;
|
|
87
|
+
let error;
|
|
88
|
+
try {
|
|
89
|
+
error = JSON.parse(body).error;
|
|
90
|
+
} catch {}
|
|
91
|
+
return typeof error === "string" && error !== "" ? error : `subscribe failed with status ${res.status}: ${body}`;
|
|
81
92
|
}
|
|
82
93
|
async function postSub(sub) {
|
|
83
94
|
const conn = connId;
|
|
@@ -99,10 +110,12 @@ function createEventHub(options = {}) {
|
|
|
99
110
|
return;
|
|
100
111
|
}
|
|
101
112
|
if (res.status === 404) return;
|
|
102
|
-
|
|
113
|
+
const message = await refusedSubscribeMessage(res);
|
|
114
|
+
if (stale()) return;
|
|
115
|
+
failSub(sub, message, { status: res.status });
|
|
103
116
|
} catch (err) {
|
|
104
117
|
if (stale()) return;
|
|
105
|
-
failSub(sub,
|
|
118
|
+
failSub(sub, `subscribe request failed: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
|
|
106
119
|
}
|
|
107
120
|
}
|
|
108
121
|
function onHello(event) {
|
|
@@ -173,7 +186,7 @@ function createEventHub(options = {}) {
|
|
|
173
186
|
try {
|
|
174
187
|
payload = JSON.parse(event.data);
|
|
175
188
|
} catch (err) {
|
|
176
|
-
failSub(sub,
|
|
189
|
+
failSub(sub, `sub closed with a malformed __closed frame: ${String(event.data)}`, { cause: err });
|
|
177
190
|
return;
|
|
178
191
|
}
|
|
179
192
|
if (payload.status >= 200 && payload.status < 300) {
|
|
@@ -185,7 +198,8 @@ function createEventHub(options = {}) {
|
|
|
185
198
|
}, RESUBSCRIBE_DELAY_MS);
|
|
186
199
|
return;
|
|
187
200
|
}
|
|
188
|
-
|
|
201
|
+
const error = payload.error?.trimEnd() ?? "";
|
|
202
|
+
failSub(sub, error !== "" ? error : `sub closed with status ${payload.status} and no error message`, { status: payload.status });
|
|
189
203
|
}
|
|
190
204
|
function routeClosed(sub) {
|
|
191
205
|
const eventName = eventNameFor(sub, "__closed");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-hub.cjs","names":[],"sources":["../../src/hooks/event-hub.ts"],"sourcesContent":["import type { EventSourceFactory, EventSourceLike } from \"./event-source\";\n\n// Browsers allow only six HTTP/1.1 connections per host, shared across every\n// tab. An app that opens one native EventSource per topic (list view, status\n// badge, detail pane, activity feed, ...) lets a second tab or a reload starve\n// ordinary fetches behind a queue that never drains.\n//\n// An event hub multiplexes every topic a tab opens onto a single real\n// connection to the server's events endpoint (`/api/events` by default): one\n// native EventSource, with each logical stream registered as a \"sub\"\n// (POST {url}/{conn}/subs, DELETE {url}/{conn}/subs/{id}) whose frames arrive\n// prefixed `<subId>/<name>`. Callers never see any of this — the factory\n// returned by createEventHub() hands back an EventSourceLike that behaves like\n// `new EventSource(url)` from their point of view, so it plugs straight into\n// `<EventSourceProvider value={...}>`.\n\nexport interface EventHubOptions {\n /** Server endpoint of the multiplexed stream. Defaults to `/api/events`. */\n url?: string;\n /**\n * The build id this page was served with. When the server's hello frame\n * reports a different build, `onBuildMismatch` fires once. `null`/absent\n * (tests, Storybook, a bare dev server with no backend in front of it)\n * means the hub never reloads.\n */\n buildId?: string | null;\n /** Called once on a build mismatch. Defaults to `window.location.reload()`. */\n onBuildMismatch?: () => void;\n}\n\nconst DEFAULT_URL = \"/api/events\";\n\n// How long an idle hub (no subs left) keeps the real connection open before\n// tearing it down — long enough to survive React StrictMode's mount → unmount\n// → mount churn and a component swap that closes one stream and immediately\n// opens its replacement.\nconst TEARDOWN_GRACE_MS = 1000;\n\n// Delay before re-subscribing after a sub's handler ends with a 2xx status\n// (server-side stream completed normally and can be re-opened), mirroring\n// native EventSource's own reconnect delay.\nconst RESUBSCRIBE_DELAY_MS = 1000;\n\nconst READY_STATE_CONNECTING = 0;\nconst READY_STATE_OPEN = 1;\nconst READY_STATE_CLOSED = 2;\n\ntype DomListener = EventListenerOrEventListenerObject;\n\nfunction invokeListener(listener: DomListener, event: Event): void {\n if (typeof listener === \"function\") listener(event);\n else listener.handleEvent(event);\n}\n\n// Sub is both the internal bookkeeping for one logical stream and the public\n// EventSourceLike handed back to the caller — there is no separate wrapper\n// object, so `readyState`/`url` always reflect live state.\nclass Sub implements EventSourceLike {\n readyState = READY_STATE_CONNECTING;\n onopen: ((ev: Event) => unknown) | null = null;\n onmessage: ((ev: MessageEvent) => unknown) | null = null;\n onerror: ((ev: Event) => unknown) | null = null;\n\n readonly listeners = new Map<string, Set<DomListener>>();\n // Real-connection listeners this sub has registered, keyed by the prefixed\n // event name (`${id}/${name}`), so close() can remove exactly what it added.\n readonly routedHandlers = new Map<string, (ev: Event) => void>();\n resubscribeTimer: ReturnType<typeof setTimeout> | null = null;\n disposed = false;\n\n constructor(\n readonly id: string,\n readonly url: string,\n private readonly hooks: { route(sub: Sub, name: string): void; close(sub: Sub): void },\n ) {}\n\n addEventListener(type: string, listener: DomListener): void {\n let set = this.listeners.get(type);\n if (!set) {\n set = new Set();\n this.listeners.set(type, set);\n }\n set.add(listener);\n this.hooks.route(this, type);\n }\n\n removeEventListener(type: string, listener: DomListener): void {\n this.listeners.get(type)?.delete(listener);\n }\n\n close(): void {\n this.hooks.close(this);\n }\n}\n\nfunction dispatch(sub: Sub, name: string, event: Event): void {\n // Snapshot the set so a listener that (un)registers listeners mid-dispatch\n // doesn't change who receives this frame.\n for (const listener of Array.from(sub.listeners.get(name) ?? [])) invokeListener(listener, event);\n // onmessage/onerror/onopen mirror native EventSource: each is just the\n // single-slot form of addEventListener('message'|'error'|'open', ...), so a\n // frame named \"error\" (server-sent) reaches both a registered\n // addEventListener('error', ...) and .onerror, exactly like the browser.\n if (name === \"message\") sub.onmessage?.(event as MessageEvent);\n if (name === \"error\") sub.onerror?.(event);\n if (name === \"open\") sub.onopen?.(event);\n}\n\n/**\n * Creates an `EventSourceFactory` that multiplexes every stream it opens over\n * one real connection to `options.url`. Each returned stream behaves like\n * `new EventSource(url)` to the caller: CONNECTING until the subscription is\n * live, dispatches 'open'/'message'/'error' (and any server-named event), and\n * auto-reconnects the way native EventSource does.\n *\n * All state (real connection, connection id, sub registry, teardown timer,\n * reload guard) is per hub, so two hubs never share a connection.\n */\nexport function createEventHub(options: EventHubOptions = {}): EventSourceFactory {\n const { url: hubUrl = DEFAULT_URL, buildId = null, onBuildMismatch = () => window.location.reload() } = options;\n\n let real: EventSourceLike | null = null;\n let connId: string | null = null;\n let subCounter = 0;\n const subs = new Map<string, Sub>();\n let teardownTimer: ReturnType<typeof setTimeout> | null = null;\n // Guards against a reload loop within one page load: once triggered, further\n // __hello frames (e.g. after the reload's own new connection reconnects\n // mid-flight) never trigger a second one.\n let reloadedForBuildMismatch = false;\n\n // A stale tab still serving an old bundle would otherwise keep working\n // against a server that has moved on — including racing the six-connection\n // cap this hub exists to close, since an old bundle may hold raw\n // EventSources of its own. When the server's hello reports a different build\n // than the one this page was served with, reload once to pick up the\n // current bundle.\n function maybeReloadForBuildMismatch(helloBuildId: string | undefined): void {\n if (reloadedForBuildMismatch) return;\n if (!helloBuildId || !buildId) return;\n if (helloBuildId === buildId) return;\n reloadedForBuildMismatch = true;\n onBuildMismatch();\n }\n\n function failSub(sub: Sub, message: string, cause?: unknown): void {\n sub.readyState = READY_STATE_CLOSED;\n dispatch(sub, \"error\", new Event(\"error\"));\n if (cause !== undefined) console.error(`[event-hub] ${message} for ${sub.url}:`, cause);\n else console.error(`[event-hub] ${message} for ${sub.url}`);\n }\n\n async function postSub(sub: Sub): Promise<void> {\n const conn = connId;\n if (!conn || sub.disposed || sub.readyState === READY_STATE_CLOSED) return;\n // A response for a connection that has since dropped (or a sub that has\n // since failed) is stale: the next __hello re-subscribes on the live one.\n const stale = () => sub.disposed || conn !== connId || sub.readyState === READY_STATE_CLOSED;\n try {\n const res = await fetch(`${hubUrl}/${conn}/subs`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ id: sub.id, path: sub.url }),\n });\n if (stale()) return;\n if (res.status === 204) {\n sub.readyState = READY_STATE_OPEN;\n dispatch(sub, \"open\", new Event(\"open\"));\n return;\n }\n if (res.status === 404) return; // stale conn id; the next __hello retries\n failSub(sub, `subscribe failed: ${res.status}`);\n } catch (err) {\n if (stale()) return;\n failSub(sub, \"subscribe request failed\", err);\n }\n }\n\n function onHello(event: MessageEvent): void {\n const payload = JSON.parse(event.data) as { conn: string; build?: string };\n connId = payload.conn;\n maybeReloadForBuildMismatch(payload.build);\n // A hello means every currently-active sub needs a fresh subscription: the\n // first hello of a brand-new connection, or a reconnect hello after a\n // drop, both start from a server side with no subs registered yet.\n for (const sub of subs.values()) {\n if (!sub.disposed) void postSub(sub);\n }\n }\n\n function onRealError(es: EventSourceLike): void {\n connId = null;\n for (const sub of subs.values()) {\n if (sub.disposed || sub.readyState === READY_STATE_CLOSED) continue;\n sub.readyState = READY_STATE_CONNECTING;\n dispatch(sub, \"error\", new Event(\"error\"));\n }\n // Native EventSource reconnects on its own after a transient error; the\n // next __hello re-subscribes everything and dispatches 'open' again. A\n // CLOSED source (non-200 or wrong Content-Type) never reconnects, so drop\n // it and open a replacement after a delay.\n if (es.readyState !== READY_STATE_CLOSED || real !== es) return;\n for (const sub of subs.values()) {\n for (const [eventName, handler] of sub.routedHandlers) es.removeEventListener(eventName, handler);\n sub.routedHandlers.clear();\n }\n es.onerror = null;\n real = null;\n setTimeout(() => {\n if (!real && subs.size > 0) ensureRealOpen();\n }, RESUBSCRIBE_DELAY_MS);\n }\n\n function ensureRealOpen(): EventSourceLike {\n if (real) {\n if (teardownTimer) {\n clearTimeout(teardownTimer);\n teardownTimer = null;\n }\n return real;\n }\n connId = null;\n const es = new EventSource(hubUrl);\n es.addEventListener(\"__hello\", (event) => onHello(event as MessageEvent));\n es.onerror = () => onRealError(es);\n real = es;\n routeActiveSubs();\n return es;\n }\n\n // routeActiveSubs binds every live sub's routing onto a freshly created real\n // connection (a replacement after a terminal error has none yet).\n function routeActiveSubs(): void {\n for (const sub of subs.values()) {\n if (sub.disposed) continue;\n routeName(sub, \"message\");\n for (const name of sub.listeners.keys()) routeName(sub, name);\n routeClosed(sub);\n }\n }\n\n const eventNameFor = (sub: Sub, name: string) => `${sub.id}/${name}`;\n\n // routeName registers, at most once per sub+name, a real-connection listener\n // that re-dispatches `${sub.id}/${name}` frames to this sub's own listeners.\n // \"open\" is synthetic (dispatched locally on subscribe/reconnect) and never\n // arrives on the wire, so it is never routed. A closed sub has no routing to\n // register: its real connection may already be torn down, and no frame for\n // it can arrive. With no real connection (awaiting a replacement after a\n // terminal error) routing is deferred to routeActiveSubs.\n function routeName(sub: Sub, name: string): void {\n const eventName = eventNameFor(sub, name);\n if (!real || name === \"open\" || sub.disposed || sub.routedHandlers.has(eventName)) return;\n const handler = (event: Event) => {\n const message = event as MessageEvent;\n dispatch(sub, name, new MessageEvent(name, { data: message.data, lastEventId: message.lastEventId }));\n };\n real.addEventListener(eventName, handler);\n sub.routedHandlers.set(eventName, handler);\n }\n\n function onSubClosed(sub: Sub, event: MessageEvent): void {\n if (sub.disposed) return;\n let payload: { status: number; error?: string };\n try {\n payload = JSON.parse(event.data) as { status: number; error?: string };\n } catch (err) {\n failSub(sub, \"closed frame was malformed\", err);\n return;\n }\n if (payload.status >= 200 && payload.status < 300) {\n // The server-side handler ended on its own with a success status — the\n // same shape as a native stream simply reconnecting.\n sub.readyState = READY_STATE_CONNECTING;\n dispatch(sub, \"error\", new Event(\"error\"));\n sub.resubscribeTimer = setTimeout(() => {\n sub.resubscribeTimer = null;\n if (!sub.disposed) void postSub(sub);\n }, RESUBSCRIBE_DELAY_MS);\n return;\n }\n failSub(sub, `sub closed with status ${payload.status}`, payload.error);\n }\n\n // routeClosed wires the sub's terminal frame: unlike every other name, its\n // payload drives re-subscription rather than being handed to consumers.\n function routeClosed(sub: Sub): void {\n const eventName = eventNameFor(sub, \"__closed\");\n if (!real || sub.routedHandlers.has(eventName)) return;\n const handler = (event: Event) => onSubClosed(sub, event as MessageEvent);\n real.addEventListener(eventName, handler);\n sub.routedHandlers.set(eventName, handler);\n }\n\n function scheduleTeardownIfIdle(): void {\n if (subs.size > 0 || teardownTimer) return;\n teardownTimer = setTimeout(() => {\n teardownTimer = null;\n if (subs.size > 0) return; // something re-subscribed during the grace window\n real?.close();\n real = null;\n connId = null;\n }, TEARDOWN_GRACE_MS);\n }\n\n function closeSub(sub: Sub): void {\n if (sub.disposed) return;\n sub.disposed = true;\n sub.readyState = READY_STATE_CLOSED;\n if (sub.resubscribeTimer) {\n clearTimeout(sub.resubscribeTimer);\n sub.resubscribeTimer = null;\n }\n for (const [eventName, handler] of sub.routedHandlers) real?.removeEventListener(eventName, handler);\n sub.routedHandlers.clear();\n subs.delete(sub.id);\n\n const conn = connId;\n if (conn) {\n fetch(`${hubUrl}/${conn}/subs/${sub.id}`, { method: \"DELETE\" })\n .then((res) => {\n if (!res.ok && res.status !== 404) console.error(`[event-hub] unsubscribe failed for ${sub.url}: ${res.status}`);\n })\n .catch((err) => console.error(`[event-hub] unsubscribe request failed for ${sub.url}:`, err));\n }\n scheduleTeardownIfIdle();\n }\n\n const hooks = { route: routeName, close: closeSub };\n\n return (url) => {\n const sub = new Sub(`s${++subCounter}`, url, hooks);\n subs.set(sub.id, sub);\n ensureRealOpen();\n // Routing must be registered before the subscribe POST is sent: frames can\n // start arriving on the real connection as soon as the server accepts the\n // subscription, which can race the POST's own response.\n routeName(sub, \"message\");\n routeClosed(sub);\n if (connId) void postSub(sub);\n return sub;\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"event-hub.cjs","names":[],"sources":["../../src/hooks/event-hub.ts"],"sourcesContent":["import type { EventSourceFactory, EventSourceLike } from \"./event-source\";\n\n// Browsers allow only six HTTP/1.1 connections per host, shared across every\n// tab. An app that opens one native EventSource per topic (list view, status\n// badge, detail pane, activity feed, ...) lets a second tab or a reload starve\n// ordinary fetches behind a queue that never drains.\n//\n// An event hub multiplexes every topic a tab opens onto a single real\n// connection to the server's events endpoint (`/api/events` by default): one\n// native EventSource, with each logical stream registered as a \"sub\"\n// (POST {url}/{conn}/subs, DELETE {url}/{conn}/subs/{id}) whose frames arrive\n// prefixed `<subId>/<name>`. Callers never see any of this — the factory\n// returned by createEventHub() hands back an EventSourceLike that behaves like\n// `new EventSource(url)` from their point of view, so it plugs straight into\n// `<EventSourceProvider value={...}>`.\n\nexport interface EventHubOptions {\n /** Server endpoint of the multiplexed stream. Defaults to `/api/events`. */\n url?: string;\n /**\n * The build id this page was served with. When the server's hello frame\n * reports a different build, `onBuildMismatch` fires once. `null`/absent\n * (tests, Storybook, a bare dev server with no backend in front of it)\n * means the hub never reloads.\n */\n buildId?: string | null;\n /** Called once on a build mismatch. Defaults to `window.location.reload()`. */\n onBuildMismatch?: () => void;\n}\n\nconst DEFAULT_URL = \"/api/events\";\n\n// How long an idle hub (no subs left) keeps the real connection open before\n// tearing it down — long enough to survive React StrictMode's mount → unmount\n// → mount churn and a component swap that closes one stream and immediately\n// opens its replacement.\nconst TEARDOWN_GRACE_MS = 1000;\n\n// Delay before re-subscribing after a sub's handler ends with a 2xx status\n// (server-side stream completed normally and can be re-opened), mirroring\n// native EventSource's own reconnect delay.\nconst RESUBSCRIBE_DELAY_MS = 1000;\n\nconst READY_STATE_CONNECTING = 0;\nconst READY_STATE_OPEN = 1;\nconst READY_STATE_CLOSED = 2;\n\ntype DomListener = EventListenerOrEventListenerObject;\n\nfunction invokeListener(listener: DomListener, event: Event): void {\n if (typeof listener === \"function\") listener(event);\n else listener.handleEvent(event);\n}\n\n// Sub is both the internal bookkeeping for one logical stream and the public\n// EventSourceLike handed back to the caller — there is no separate wrapper\n// object, so `readyState`/`url` always reflect live state.\nclass Sub implements EventSourceLike {\n readyState = READY_STATE_CONNECTING;\n onopen: ((ev: Event) => unknown) | null = null;\n onmessage: ((ev: MessageEvent) => unknown) | null = null;\n onerror: ((ev: Event) => unknown) | null = null;\n\n readonly listeners = new Map<string, Set<DomListener>>();\n // Real-connection listeners this sub has registered, keyed by the prefixed\n // event name (`${id}/${name}`), so close() can remove exactly what it added.\n readonly routedHandlers = new Map<string, (ev: Event) => void>();\n resubscribeTimer: ReturnType<typeof setTimeout> | null = null;\n disposed = false;\n\n constructor(\n readonly id: string,\n readonly url: string,\n private readonly hooks: { route(sub: Sub, name: string): void; close(sub: Sub): void },\n ) {}\n\n addEventListener(type: string, listener: DomListener): void {\n let set = this.listeners.get(type);\n if (!set) {\n set = new Set();\n this.listeners.set(type, set);\n }\n set.add(listener);\n this.hooks.route(this, type);\n }\n\n removeEventListener(type: string, listener: DomListener): void {\n this.listeners.get(type)?.delete(listener);\n }\n\n close(): void {\n this.hooks.close(this);\n }\n}\n\nfunction dispatch(sub: Sub, name: string, event: Event): void {\n // Snapshot the set so a listener that (un)registers listeners mid-dispatch\n // doesn't change who receives this frame.\n for (const listener of Array.from(sub.listeners.get(name) ?? [])) invokeListener(listener, event);\n // onmessage/onerror/onopen mirror native EventSource: each is just the\n // single-slot form of addEventListener('message'|'error'|'open', ...), so a\n // frame named \"error\" (server-sent) reaches both a registered\n // addEventListener('error', ...) and .onerror, exactly like the browser.\n if (name === \"message\") sub.onmessage?.(event as MessageEvent);\n if (name === \"error\") sub.onerror?.(event);\n if (name === \"open\") sub.onopen?.(event);\n}\n\n/**\n * Creates an `EventSourceFactory` that multiplexes every stream it opens over\n * one real connection to `options.url`. Each returned stream behaves like\n * `new EventSource(url)` to the caller: CONNECTING until the subscription is\n * live, dispatches 'open'/'message'/'error' (and any server-named event), and\n * auto-reconnects the way native EventSource does.\n *\n * All state (real connection, connection id, sub registry, teardown timer,\n * reload guard) is per hub, so two hubs never share a connection.\n */\nexport function createEventHub(options: EventHubOptions = {}): EventSourceFactory {\n const { url: hubUrl = DEFAULT_URL, buildId = null, onBuildMismatch = () => window.location.reload() } = options;\n\n let real: EventSourceLike | null = null;\n let connId: string | null = null;\n let subCounter = 0;\n const subs = new Map<string, Sub>();\n let teardownTimer: ReturnType<typeof setTimeout> | null = null;\n // Guards against a reload loop within one page load: once triggered, further\n // __hello frames (e.g. after the reload's own new connection reconnects\n // mid-flight) never trigger a second one.\n let reloadedForBuildMismatch = false;\n\n // A stale tab still serving an old bundle would otherwise keep working\n // against a server that has moved on — including racing the six-connection\n // cap this hub exists to close, since an old bundle may hold raw\n // EventSources of its own. When the server's hello reports a different build\n // than the one this page was served with, reload once to pick up the\n // current bundle.\n function maybeReloadForBuildMismatch(helloBuildId: string | undefined): void {\n if (reloadedForBuildMismatch) return;\n if (!helloBuildId || !buildId) return;\n if (helloBuildId === buildId) return;\n reloadedForBuildMismatch = true;\n onBuildMismatch();\n }\n\n // failSub ends a sub for good. Its error event is an ErrorEvent whose\n // `message` is what the server said (a __closed frame's `error`, or a refused\n // subscribe's `{\"error\"}` body), so a consumer can show the real reason; a\n // transport-style drop stays a bare Event, as native EventSource sends.\n function failSub(sub: Sub, message: string, context: { status?: number; cause?: unknown } = {}): void {\n sub.readyState = READY_STATE_CLOSED;\n dispatch(sub, \"error\", new ErrorEvent(\"error\", { message }));\n const status = context.status === undefined ? \"\" : ` (status ${context.status})`;\n const line = `[event-hub] ${sub.url} failed${status}: ${message}`;\n if (context.cause !== undefined) console.error(line, context.cause);\n else console.error(line);\n }\n\n async function refusedSubscribeMessage(res: Response): Promise<string> {\n const body = (await res.text()).trim();\n if (body === \"\") return `subscribe failed with status ${res.status} and no error message`;\n let error: unknown;\n try {\n error = (JSON.parse(body) as { error?: unknown }).error;\n } catch {\n // Not the hub's JSON error shape (e.g. a proxy's HTML/text page): show it verbatim.\n }\n return typeof error === \"string\" && error !== \"\" ? error : `subscribe failed with status ${res.status}: ${body}`;\n }\n\n async function postSub(sub: Sub): Promise<void> {\n const conn = connId;\n if (!conn || sub.disposed || sub.readyState === READY_STATE_CLOSED) return;\n // A response for a connection that has since dropped (or a sub that has\n // since failed) is stale: the next __hello re-subscribes on the live one.\n const stale = () => sub.disposed || conn !== connId || sub.readyState === READY_STATE_CLOSED;\n try {\n const res = await fetch(`${hubUrl}/${conn}/subs`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ id: sub.id, path: sub.url }),\n });\n if (stale()) return;\n if (res.status === 204) {\n sub.readyState = READY_STATE_OPEN;\n dispatch(sub, \"open\", new Event(\"open\"));\n return;\n }\n if (res.status === 404) return; // stale conn id; the next __hello retries\n const message = await refusedSubscribeMessage(res);\n if (stale()) return;\n failSub(sub, message, { status: res.status });\n } catch (err) {\n if (stale()) return;\n failSub(sub, `subscribe request failed: ${err instanceof Error ? err.message : String(err)}`, { cause: err });\n }\n }\n\n function onHello(event: MessageEvent): void {\n const payload = JSON.parse(event.data) as { conn: string; build?: string };\n connId = payload.conn;\n maybeReloadForBuildMismatch(payload.build);\n // A hello means every currently-active sub needs a fresh subscription: the\n // first hello of a brand-new connection, or a reconnect hello after a\n // drop, both start from a server side with no subs registered yet.\n for (const sub of subs.values()) {\n if (!sub.disposed) void postSub(sub);\n }\n }\n\n function onRealError(es: EventSourceLike): void {\n connId = null;\n for (const sub of subs.values()) {\n if (sub.disposed || sub.readyState === READY_STATE_CLOSED) continue;\n sub.readyState = READY_STATE_CONNECTING;\n dispatch(sub, \"error\", new Event(\"error\"));\n }\n // Native EventSource reconnects on its own after a transient error; the\n // next __hello re-subscribes everything and dispatches 'open' again. A\n // CLOSED source (non-200 or wrong Content-Type) never reconnects, so drop\n // it and open a replacement after a delay.\n if (es.readyState !== READY_STATE_CLOSED || real !== es) return;\n for (const sub of subs.values()) {\n for (const [eventName, handler] of sub.routedHandlers) es.removeEventListener(eventName, handler);\n sub.routedHandlers.clear();\n }\n es.onerror = null;\n real = null;\n setTimeout(() => {\n if (!real && subs.size > 0) ensureRealOpen();\n }, RESUBSCRIBE_DELAY_MS);\n }\n\n function ensureRealOpen(): EventSourceLike {\n if (real) {\n if (teardownTimer) {\n clearTimeout(teardownTimer);\n teardownTimer = null;\n }\n return real;\n }\n connId = null;\n const es = new EventSource(hubUrl);\n es.addEventListener(\"__hello\", (event) => onHello(event as MessageEvent));\n es.onerror = () => onRealError(es);\n real = es;\n routeActiveSubs();\n return es;\n }\n\n // routeActiveSubs binds every live sub's routing onto a freshly created real\n // connection (a replacement after a terminal error has none yet).\n function routeActiveSubs(): void {\n for (const sub of subs.values()) {\n if (sub.disposed) continue;\n routeName(sub, \"message\");\n for (const name of sub.listeners.keys()) routeName(sub, name);\n routeClosed(sub);\n }\n }\n\n const eventNameFor = (sub: Sub, name: string) => `${sub.id}/${name}`;\n\n // routeName registers, at most once per sub+name, a real-connection listener\n // that re-dispatches `${sub.id}/${name}` frames to this sub's own listeners.\n // \"open\" is synthetic (dispatched locally on subscribe/reconnect) and never\n // arrives on the wire, so it is never routed. A closed sub has no routing to\n // register: its real connection may already be torn down, and no frame for\n // it can arrive. With no real connection (awaiting a replacement after a\n // terminal error) routing is deferred to routeActiveSubs.\n function routeName(sub: Sub, name: string): void {\n const eventName = eventNameFor(sub, name);\n if (!real || name === \"open\" || sub.disposed || sub.routedHandlers.has(eventName)) return;\n const handler = (event: Event) => {\n const message = event as MessageEvent;\n dispatch(sub, name, new MessageEvent(name, { data: message.data, lastEventId: message.lastEventId }));\n };\n real.addEventListener(eventName, handler);\n sub.routedHandlers.set(eventName, handler);\n }\n\n // A sub's __closed frame is clicky sse hubClosed: {\"status\": int,\n // \"error\"?: string}, `error` being the handler's (≤500 byte) response body.\n function onSubClosed(sub: Sub, event: MessageEvent): void {\n if (sub.disposed) return;\n let payload: { status: number; error?: string };\n try {\n payload = JSON.parse(event.data) as { status: number; error?: string };\n } catch (err) {\n failSub(sub, `sub closed with a malformed __closed frame: ${String(event.data)}`, { cause: err });\n return;\n }\n if (payload.status >= 200 && payload.status < 300) {\n // The server-side handler ended on its own with a success status — the\n // same shape as a native stream simply reconnecting.\n sub.readyState = READY_STATE_CONNECTING;\n dispatch(sub, \"error\", new Event(\"error\"));\n sub.resubscribeTimer = setTimeout(() => {\n sub.resubscribeTimer = null;\n if (!sub.disposed) void postSub(sub);\n }, RESUBSCRIBE_DELAY_MS);\n return;\n }\n // http.Error bodies end in a newline; only trailing whitespace is dropped.\n const error = payload.error?.trimEnd() ?? \"\";\n failSub(sub, error !== \"\" ? error : `sub closed with status ${payload.status} and no error message`, {\n status: payload.status,\n });\n }\n\n // routeClosed wires the sub's terminal frame: unlike every other name, its\n // payload drives re-subscription rather than being handed to consumers.\n function routeClosed(sub: Sub): void {\n const eventName = eventNameFor(sub, \"__closed\");\n if (!real || sub.routedHandlers.has(eventName)) return;\n const handler = (event: Event) => onSubClosed(sub, event as MessageEvent);\n real.addEventListener(eventName, handler);\n sub.routedHandlers.set(eventName, handler);\n }\n\n function scheduleTeardownIfIdle(): void {\n if (subs.size > 0 || teardownTimer) return;\n teardownTimer = setTimeout(() => {\n teardownTimer = null;\n if (subs.size > 0) return; // something re-subscribed during the grace window\n real?.close();\n real = null;\n connId = null;\n }, TEARDOWN_GRACE_MS);\n }\n\n function closeSub(sub: Sub): void {\n if (sub.disposed) return;\n sub.disposed = true;\n sub.readyState = READY_STATE_CLOSED;\n if (sub.resubscribeTimer) {\n clearTimeout(sub.resubscribeTimer);\n sub.resubscribeTimer = null;\n }\n for (const [eventName, handler] of sub.routedHandlers) real?.removeEventListener(eventName, handler);\n sub.routedHandlers.clear();\n subs.delete(sub.id);\n\n const conn = connId;\n if (conn) {\n fetch(`${hubUrl}/${conn}/subs/${sub.id}`, { method: \"DELETE\" })\n .then((res) => {\n if (!res.ok && res.status !== 404) console.error(`[event-hub] unsubscribe failed for ${sub.url}: ${res.status}`);\n })\n .catch((err) => console.error(`[event-hub] unsubscribe request failed for ${sub.url}:`, err));\n }\n scheduleTeardownIfIdle();\n }\n\n const hooks = { route: routeName, close: closeSub };\n\n return (url) => {\n const sub = new Sub(`s${++subCounter}`, url, hooks);\n subs.set(sub.id, sub);\n ensureRealOpen();\n // Routing must be registered before the subscribe POST is sent: frames can\n // start arriving on the real connection as soon as the server accepts the\n // subscription, which can race the POST's own response.\n routeName(sub, \"message\");\n routeClosed(sub);\n if (connId) void postSub(sub);\n return sub;\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-hub.d.ts","sourceRoot":"","sources":["../../src/hooks/event-hub.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAmB,MAAM,gBAAgB,CAAC;AAgB1E,MAAM,WAAW,eAAe;IAC9B,4EAA4E;IAC5E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,+EAA+E;IAC/E,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;CAC9B;AAgFD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,eAAoB,GAAG,kBAAkB,
|
|
1
|
+
{"version":3,"file":"event-hub.d.ts","sourceRoot":"","sources":["../../src/hooks/event-hub.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAmB,MAAM,gBAAgB,CAAC;AAgB1E,MAAM,WAAW,eAAe;IAC9B,4EAA4E;IAC5E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,+EAA+E;IAC/E,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;CAC9B;AAgFD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,eAAoB,GAAG,kBAAkB,CA0PhF"}
|
package/dist/hooks/event-hub.js
CHANGED
|
@@ -73,11 +73,22 @@ function createEventHub(options = {}) {
|
|
|
73
73
|
reloadedForBuildMismatch = true;
|
|
74
74
|
onBuildMismatch();
|
|
75
75
|
}
|
|
76
|
-
function failSub(sub, message,
|
|
76
|
+
function failSub(sub, message, context = {}) {
|
|
77
77
|
sub.readyState = READY_STATE_CLOSED;
|
|
78
|
-
dispatch(sub, "error", new
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
dispatch(sub, "error", new ErrorEvent("error", { message }));
|
|
79
|
+
const status = context.status === void 0 ? "" : ` (status ${context.status})`;
|
|
80
|
+
const line = `[event-hub] ${sub.url} failed${status}: ${message}`;
|
|
81
|
+
if (context.cause !== void 0) console.error(line, context.cause);
|
|
82
|
+
else console.error(line);
|
|
83
|
+
}
|
|
84
|
+
async function refusedSubscribeMessage(res) {
|
|
85
|
+
const body = (await res.text()).trim();
|
|
86
|
+
if (body === "") return `subscribe failed with status ${res.status} and no error message`;
|
|
87
|
+
let error;
|
|
88
|
+
try {
|
|
89
|
+
error = JSON.parse(body).error;
|
|
90
|
+
} catch {}
|
|
91
|
+
return typeof error === "string" && error !== "" ? error : `subscribe failed with status ${res.status}: ${body}`;
|
|
81
92
|
}
|
|
82
93
|
async function postSub(sub) {
|
|
83
94
|
const conn = connId;
|
|
@@ -99,10 +110,12 @@ function createEventHub(options = {}) {
|
|
|
99
110
|
return;
|
|
100
111
|
}
|
|
101
112
|
if (res.status === 404) return;
|
|
102
|
-
|
|
113
|
+
const message = await refusedSubscribeMessage(res);
|
|
114
|
+
if (stale()) return;
|
|
115
|
+
failSub(sub, message, { status: res.status });
|
|
103
116
|
} catch (err) {
|
|
104
117
|
if (stale()) return;
|
|
105
|
-
failSub(sub,
|
|
118
|
+
failSub(sub, `subscribe request failed: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
|
|
106
119
|
}
|
|
107
120
|
}
|
|
108
121
|
function onHello(event) {
|
|
@@ -173,7 +186,7 @@ function createEventHub(options = {}) {
|
|
|
173
186
|
try {
|
|
174
187
|
payload = JSON.parse(event.data);
|
|
175
188
|
} catch (err) {
|
|
176
|
-
failSub(sub,
|
|
189
|
+
failSub(sub, `sub closed with a malformed __closed frame: ${String(event.data)}`, { cause: err });
|
|
177
190
|
return;
|
|
178
191
|
}
|
|
179
192
|
if (payload.status >= 200 && payload.status < 300) {
|
|
@@ -185,7 +198,8 @@ function createEventHub(options = {}) {
|
|
|
185
198
|
}, RESUBSCRIBE_DELAY_MS);
|
|
186
199
|
return;
|
|
187
200
|
}
|
|
188
|
-
|
|
201
|
+
const error = payload.error?.trimEnd() ?? "";
|
|
202
|
+
failSub(sub, error !== "" ? error : `sub closed with status ${payload.status} and no error message`, { status: payload.status });
|
|
189
203
|
}
|
|
190
204
|
function routeClosed(sub) {
|
|
191
205
|
const eventName = eventNameFor(sub, "__closed");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-hub.js","names":[],"sources":["../../src/hooks/event-hub.ts"],"sourcesContent":["import type { EventSourceFactory, EventSourceLike } from \"./event-source\";\n\n// Browsers allow only six HTTP/1.1 connections per host, shared across every\n// tab. An app that opens one native EventSource per topic (list view, status\n// badge, detail pane, activity feed, ...) lets a second tab or a reload starve\n// ordinary fetches behind a queue that never drains.\n//\n// An event hub multiplexes every topic a tab opens onto a single real\n// connection to the server's events endpoint (`/api/events` by default): one\n// native EventSource, with each logical stream registered as a \"sub\"\n// (POST {url}/{conn}/subs, DELETE {url}/{conn}/subs/{id}) whose frames arrive\n// prefixed `<subId>/<name>`. Callers never see any of this — the factory\n// returned by createEventHub() hands back an EventSourceLike that behaves like\n// `new EventSource(url)` from their point of view, so it plugs straight into\n// `<EventSourceProvider value={...}>`.\n\nexport interface EventHubOptions {\n /** Server endpoint of the multiplexed stream. Defaults to `/api/events`. */\n url?: string;\n /**\n * The build id this page was served with. When the server's hello frame\n * reports a different build, `onBuildMismatch` fires once. `null`/absent\n * (tests, Storybook, a bare dev server with no backend in front of it)\n * means the hub never reloads.\n */\n buildId?: string | null;\n /** Called once on a build mismatch. Defaults to `window.location.reload()`. */\n onBuildMismatch?: () => void;\n}\n\nconst DEFAULT_URL = \"/api/events\";\n\n// How long an idle hub (no subs left) keeps the real connection open before\n// tearing it down — long enough to survive React StrictMode's mount → unmount\n// → mount churn and a component swap that closes one stream and immediately\n// opens its replacement.\nconst TEARDOWN_GRACE_MS = 1000;\n\n// Delay before re-subscribing after a sub's handler ends with a 2xx status\n// (server-side stream completed normally and can be re-opened), mirroring\n// native EventSource's own reconnect delay.\nconst RESUBSCRIBE_DELAY_MS = 1000;\n\nconst READY_STATE_CONNECTING = 0;\nconst READY_STATE_OPEN = 1;\nconst READY_STATE_CLOSED = 2;\n\ntype DomListener = EventListenerOrEventListenerObject;\n\nfunction invokeListener(listener: DomListener, event: Event): void {\n if (typeof listener === \"function\") listener(event);\n else listener.handleEvent(event);\n}\n\n// Sub is both the internal bookkeeping for one logical stream and the public\n// EventSourceLike handed back to the caller — there is no separate wrapper\n// object, so `readyState`/`url` always reflect live state.\nclass Sub implements EventSourceLike {\n readyState = READY_STATE_CONNECTING;\n onopen: ((ev: Event) => unknown) | null = null;\n onmessage: ((ev: MessageEvent) => unknown) | null = null;\n onerror: ((ev: Event) => unknown) | null = null;\n\n readonly listeners = new Map<string, Set<DomListener>>();\n // Real-connection listeners this sub has registered, keyed by the prefixed\n // event name (`${id}/${name}`), so close() can remove exactly what it added.\n readonly routedHandlers = new Map<string, (ev: Event) => void>();\n resubscribeTimer: ReturnType<typeof setTimeout> | null = null;\n disposed = false;\n\n constructor(\n readonly id: string,\n readonly url: string,\n private readonly hooks: { route(sub: Sub, name: string): void; close(sub: Sub): void },\n ) {}\n\n addEventListener(type: string, listener: DomListener): void {\n let set = this.listeners.get(type);\n if (!set) {\n set = new Set();\n this.listeners.set(type, set);\n }\n set.add(listener);\n this.hooks.route(this, type);\n }\n\n removeEventListener(type: string, listener: DomListener): void {\n this.listeners.get(type)?.delete(listener);\n }\n\n close(): void {\n this.hooks.close(this);\n }\n}\n\nfunction dispatch(sub: Sub, name: string, event: Event): void {\n // Snapshot the set so a listener that (un)registers listeners mid-dispatch\n // doesn't change who receives this frame.\n for (const listener of Array.from(sub.listeners.get(name) ?? [])) invokeListener(listener, event);\n // onmessage/onerror/onopen mirror native EventSource: each is just the\n // single-slot form of addEventListener('message'|'error'|'open', ...), so a\n // frame named \"error\" (server-sent) reaches both a registered\n // addEventListener('error', ...) and .onerror, exactly like the browser.\n if (name === \"message\") sub.onmessage?.(event as MessageEvent);\n if (name === \"error\") sub.onerror?.(event);\n if (name === \"open\") sub.onopen?.(event);\n}\n\n/**\n * Creates an `EventSourceFactory` that multiplexes every stream it opens over\n * one real connection to `options.url`. Each returned stream behaves like\n * `new EventSource(url)` to the caller: CONNECTING until the subscription is\n * live, dispatches 'open'/'message'/'error' (and any server-named event), and\n * auto-reconnects the way native EventSource does.\n *\n * All state (real connection, connection id, sub registry, teardown timer,\n * reload guard) is per hub, so two hubs never share a connection.\n */\nexport function createEventHub(options: EventHubOptions = {}): EventSourceFactory {\n const { url: hubUrl = DEFAULT_URL, buildId = null, onBuildMismatch = () => window.location.reload() } = options;\n\n let real: EventSourceLike | null = null;\n let connId: string | null = null;\n let subCounter = 0;\n const subs = new Map<string, Sub>();\n let teardownTimer: ReturnType<typeof setTimeout> | null = null;\n // Guards against a reload loop within one page load: once triggered, further\n // __hello frames (e.g. after the reload's own new connection reconnects\n // mid-flight) never trigger a second one.\n let reloadedForBuildMismatch = false;\n\n // A stale tab still serving an old bundle would otherwise keep working\n // against a server that has moved on — including racing the six-connection\n // cap this hub exists to close, since an old bundle may hold raw\n // EventSources of its own. When the server's hello reports a different build\n // than the one this page was served with, reload once to pick up the\n // current bundle.\n function maybeReloadForBuildMismatch(helloBuildId: string | undefined): void {\n if (reloadedForBuildMismatch) return;\n if (!helloBuildId || !buildId) return;\n if (helloBuildId === buildId) return;\n reloadedForBuildMismatch = true;\n onBuildMismatch();\n }\n\n function failSub(sub: Sub, message: string, cause?: unknown): void {\n sub.readyState = READY_STATE_CLOSED;\n dispatch(sub, \"error\", new Event(\"error\"));\n if (cause !== undefined) console.error(`[event-hub] ${message} for ${sub.url}:`, cause);\n else console.error(`[event-hub] ${message} for ${sub.url}`);\n }\n\n async function postSub(sub: Sub): Promise<void> {\n const conn = connId;\n if (!conn || sub.disposed || sub.readyState === READY_STATE_CLOSED) return;\n // A response for a connection that has since dropped (or a sub that has\n // since failed) is stale: the next __hello re-subscribes on the live one.\n const stale = () => sub.disposed || conn !== connId || sub.readyState === READY_STATE_CLOSED;\n try {\n const res = await fetch(`${hubUrl}/${conn}/subs`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ id: sub.id, path: sub.url }),\n });\n if (stale()) return;\n if (res.status === 204) {\n sub.readyState = READY_STATE_OPEN;\n dispatch(sub, \"open\", new Event(\"open\"));\n return;\n }\n if (res.status === 404) return; // stale conn id; the next __hello retries\n failSub(sub, `subscribe failed: ${res.status}`);\n } catch (err) {\n if (stale()) return;\n failSub(sub, \"subscribe request failed\", err);\n }\n }\n\n function onHello(event: MessageEvent): void {\n const payload = JSON.parse(event.data) as { conn: string; build?: string };\n connId = payload.conn;\n maybeReloadForBuildMismatch(payload.build);\n // A hello means every currently-active sub needs a fresh subscription: the\n // first hello of a brand-new connection, or a reconnect hello after a\n // drop, both start from a server side with no subs registered yet.\n for (const sub of subs.values()) {\n if (!sub.disposed) void postSub(sub);\n }\n }\n\n function onRealError(es: EventSourceLike): void {\n connId = null;\n for (const sub of subs.values()) {\n if (sub.disposed || sub.readyState === READY_STATE_CLOSED) continue;\n sub.readyState = READY_STATE_CONNECTING;\n dispatch(sub, \"error\", new Event(\"error\"));\n }\n // Native EventSource reconnects on its own after a transient error; the\n // next __hello re-subscribes everything and dispatches 'open' again. A\n // CLOSED source (non-200 or wrong Content-Type) never reconnects, so drop\n // it and open a replacement after a delay.\n if (es.readyState !== READY_STATE_CLOSED || real !== es) return;\n for (const sub of subs.values()) {\n for (const [eventName, handler] of sub.routedHandlers) es.removeEventListener(eventName, handler);\n sub.routedHandlers.clear();\n }\n es.onerror = null;\n real = null;\n setTimeout(() => {\n if (!real && subs.size > 0) ensureRealOpen();\n }, RESUBSCRIBE_DELAY_MS);\n }\n\n function ensureRealOpen(): EventSourceLike {\n if (real) {\n if (teardownTimer) {\n clearTimeout(teardownTimer);\n teardownTimer = null;\n }\n return real;\n }\n connId = null;\n const es = new EventSource(hubUrl);\n es.addEventListener(\"__hello\", (event) => onHello(event as MessageEvent));\n es.onerror = () => onRealError(es);\n real = es;\n routeActiveSubs();\n return es;\n }\n\n // routeActiveSubs binds every live sub's routing onto a freshly created real\n // connection (a replacement after a terminal error has none yet).\n function routeActiveSubs(): void {\n for (const sub of subs.values()) {\n if (sub.disposed) continue;\n routeName(sub, \"message\");\n for (const name of sub.listeners.keys()) routeName(sub, name);\n routeClosed(sub);\n }\n }\n\n const eventNameFor = (sub: Sub, name: string) => `${sub.id}/${name}`;\n\n // routeName registers, at most once per sub+name, a real-connection listener\n // that re-dispatches `${sub.id}/${name}` frames to this sub's own listeners.\n // \"open\" is synthetic (dispatched locally on subscribe/reconnect) and never\n // arrives on the wire, so it is never routed. A closed sub has no routing to\n // register: its real connection may already be torn down, and no frame for\n // it can arrive. With no real connection (awaiting a replacement after a\n // terminal error) routing is deferred to routeActiveSubs.\n function routeName(sub: Sub, name: string): void {\n const eventName = eventNameFor(sub, name);\n if (!real || name === \"open\" || sub.disposed || sub.routedHandlers.has(eventName)) return;\n const handler = (event: Event) => {\n const message = event as MessageEvent;\n dispatch(sub, name, new MessageEvent(name, { data: message.data, lastEventId: message.lastEventId }));\n };\n real.addEventListener(eventName, handler);\n sub.routedHandlers.set(eventName, handler);\n }\n\n function onSubClosed(sub: Sub, event: MessageEvent): void {\n if (sub.disposed) return;\n let payload: { status: number; error?: string };\n try {\n payload = JSON.parse(event.data) as { status: number; error?: string };\n } catch (err) {\n failSub(sub, \"closed frame was malformed\", err);\n return;\n }\n if (payload.status >= 200 && payload.status < 300) {\n // The server-side handler ended on its own with a success status — the\n // same shape as a native stream simply reconnecting.\n sub.readyState = READY_STATE_CONNECTING;\n dispatch(sub, \"error\", new Event(\"error\"));\n sub.resubscribeTimer = setTimeout(() => {\n sub.resubscribeTimer = null;\n if (!sub.disposed) void postSub(sub);\n }, RESUBSCRIBE_DELAY_MS);\n return;\n }\n failSub(sub, `sub closed with status ${payload.status}`, payload.error);\n }\n\n // routeClosed wires the sub's terminal frame: unlike every other name, its\n // payload drives re-subscription rather than being handed to consumers.\n function routeClosed(sub: Sub): void {\n const eventName = eventNameFor(sub, \"__closed\");\n if (!real || sub.routedHandlers.has(eventName)) return;\n const handler = (event: Event) => onSubClosed(sub, event as MessageEvent);\n real.addEventListener(eventName, handler);\n sub.routedHandlers.set(eventName, handler);\n }\n\n function scheduleTeardownIfIdle(): void {\n if (subs.size > 0 || teardownTimer) return;\n teardownTimer = setTimeout(() => {\n teardownTimer = null;\n if (subs.size > 0) return; // something re-subscribed during the grace window\n real?.close();\n real = null;\n connId = null;\n }, TEARDOWN_GRACE_MS);\n }\n\n function closeSub(sub: Sub): void {\n if (sub.disposed) return;\n sub.disposed = true;\n sub.readyState = READY_STATE_CLOSED;\n if (sub.resubscribeTimer) {\n clearTimeout(sub.resubscribeTimer);\n sub.resubscribeTimer = null;\n }\n for (const [eventName, handler] of sub.routedHandlers) real?.removeEventListener(eventName, handler);\n sub.routedHandlers.clear();\n subs.delete(sub.id);\n\n const conn = connId;\n if (conn) {\n fetch(`${hubUrl}/${conn}/subs/${sub.id}`, { method: \"DELETE\" })\n .then((res) => {\n if (!res.ok && res.status !== 404) console.error(`[event-hub] unsubscribe failed for ${sub.url}: ${res.status}`);\n })\n .catch((err) => console.error(`[event-hub] unsubscribe request failed for ${sub.url}:`, err));\n }\n scheduleTeardownIfIdle();\n }\n\n const hooks = { route: routeName, close: closeSub };\n\n return (url) => {\n const sub = new Sub(`s${++subCounter}`, url, hooks);\n subs.set(sub.id, sub);\n ensureRealOpen();\n // Routing must be registered before the subscribe POST is sent: frames can\n // start arriving on the real connection as soon as the server accepts the\n // subscription, which can race the POST's own response.\n routeName(sub, \"message\");\n routeClosed(sub);\n if (connId) void postSub(sub);\n return sub;\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"event-hub.js","names":[],"sources":["../../src/hooks/event-hub.ts"],"sourcesContent":["import type { EventSourceFactory, EventSourceLike } from \"./event-source\";\n\n// Browsers allow only six HTTP/1.1 connections per host, shared across every\n// tab. An app that opens one native EventSource per topic (list view, status\n// badge, detail pane, activity feed, ...) lets a second tab or a reload starve\n// ordinary fetches behind a queue that never drains.\n//\n// An event hub multiplexes every topic a tab opens onto a single real\n// connection to the server's events endpoint (`/api/events` by default): one\n// native EventSource, with each logical stream registered as a \"sub\"\n// (POST {url}/{conn}/subs, DELETE {url}/{conn}/subs/{id}) whose frames arrive\n// prefixed `<subId>/<name>`. Callers never see any of this — the factory\n// returned by createEventHub() hands back an EventSourceLike that behaves like\n// `new EventSource(url)` from their point of view, so it plugs straight into\n// `<EventSourceProvider value={...}>`.\n\nexport interface EventHubOptions {\n /** Server endpoint of the multiplexed stream. Defaults to `/api/events`. */\n url?: string;\n /**\n * The build id this page was served with. When the server's hello frame\n * reports a different build, `onBuildMismatch` fires once. `null`/absent\n * (tests, Storybook, a bare dev server with no backend in front of it)\n * means the hub never reloads.\n */\n buildId?: string | null;\n /** Called once on a build mismatch. Defaults to `window.location.reload()`. */\n onBuildMismatch?: () => void;\n}\n\nconst DEFAULT_URL = \"/api/events\";\n\n// How long an idle hub (no subs left) keeps the real connection open before\n// tearing it down — long enough to survive React StrictMode's mount → unmount\n// → mount churn and a component swap that closes one stream and immediately\n// opens its replacement.\nconst TEARDOWN_GRACE_MS = 1000;\n\n// Delay before re-subscribing after a sub's handler ends with a 2xx status\n// (server-side stream completed normally and can be re-opened), mirroring\n// native EventSource's own reconnect delay.\nconst RESUBSCRIBE_DELAY_MS = 1000;\n\nconst READY_STATE_CONNECTING = 0;\nconst READY_STATE_OPEN = 1;\nconst READY_STATE_CLOSED = 2;\n\ntype DomListener = EventListenerOrEventListenerObject;\n\nfunction invokeListener(listener: DomListener, event: Event): void {\n if (typeof listener === \"function\") listener(event);\n else listener.handleEvent(event);\n}\n\n// Sub is both the internal bookkeeping for one logical stream and the public\n// EventSourceLike handed back to the caller — there is no separate wrapper\n// object, so `readyState`/`url` always reflect live state.\nclass Sub implements EventSourceLike {\n readyState = READY_STATE_CONNECTING;\n onopen: ((ev: Event) => unknown) | null = null;\n onmessage: ((ev: MessageEvent) => unknown) | null = null;\n onerror: ((ev: Event) => unknown) | null = null;\n\n readonly listeners = new Map<string, Set<DomListener>>();\n // Real-connection listeners this sub has registered, keyed by the prefixed\n // event name (`${id}/${name}`), so close() can remove exactly what it added.\n readonly routedHandlers = new Map<string, (ev: Event) => void>();\n resubscribeTimer: ReturnType<typeof setTimeout> | null = null;\n disposed = false;\n\n constructor(\n readonly id: string,\n readonly url: string,\n private readonly hooks: { route(sub: Sub, name: string): void; close(sub: Sub): void },\n ) {}\n\n addEventListener(type: string, listener: DomListener): void {\n let set = this.listeners.get(type);\n if (!set) {\n set = new Set();\n this.listeners.set(type, set);\n }\n set.add(listener);\n this.hooks.route(this, type);\n }\n\n removeEventListener(type: string, listener: DomListener): void {\n this.listeners.get(type)?.delete(listener);\n }\n\n close(): void {\n this.hooks.close(this);\n }\n}\n\nfunction dispatch(sub: Sub, name: string, event: Event): void {\n // Snapshot the set so a listener that (un)registers listeners mid-dispatch\n // doesn't change who receives this frame.\n for (const listener of Array.from(sub.listeners.get(name) ?? [])) invokeListener(listener, event);\n // onmessage/onerror/onopen mirror native EventSource: each is just the\n // single-slot form of addEventListener('message'|'error'|'open', ...), so a\n // frame named \"error\" (server-sent) reaches both a registered\n // addEventListener('error', ...) and .onerror, exactly like the browser.\n if (name === \"message\") sub.onmessage?.(event as MessageEvent);\n if (name === \"error\") sub.onerror?.(event);\n if (name === \"open\") sub.onopen?.(event);\n}\n\n/**\n * Creates an `EventSourceFactory` that multiplexes every stream it opens over\n * one real connection to `options.url`. Each returned stream behaves like\n * `new EventSource(url)` to the caller: CONNECTING until the subscription is\n * live, dispatches 'open'/'message'/'error' (and any server-named event), and\n * auto-reconnects the way native EventSource does.\n *\n * All state (real connection, connection id, sub registry, teardown timer,\n * reload guard) is per hub, so two hubs never share a connection.\n */\nexport function createEventHub(options: EventHubOptions = {}): EventSourceFactory {\n const { url: hubUrl = DEFAULT_URL, buildId = null, onBuildMismatch = () => window.location.reload() } = options;\n\n let real: EventSourceLike | null = null;\n let connId: string | null = null;\n let subCounter = 0;\n const subs = new Map<string, Sub>();\n let teardownTimer: ReturnType<typeof setTimeout> | null = null;\n // Guards against a reload loop within one page load: once triggered, further\n // __hello frames (e.g. after the reload's own new connection reconnects\n // mid-flight) never trigger a second one.\n let reloadedForBuildMismatch = false;\n\n // A stale tab still serving an old bundle would otherwise keep working\n // against a server that has moved on — including racing the six-connection\n // cap this hub exists to close, since an old bundle may hold raw\n // EventSources of its own. When the server's hello reports a different build\n // than the one this page was served with, reload once to pick up the\n // current bundle.\n function maybeReloadForBuildMismatch(helloBuildId: string | undefined): void {\n if (reloadedForBuildMismatch) return;\n if (!helloBuildId || !buildId) return;\n if (helloBuildId === buildId) return;\n reloadedForBuildMismatch = true;\n onBuildMismatch();\n }\n\n // failSub ends a sub for good. Its error event is an ErrorEvent whose\n // `message` is what the server said (a __closed frame's `error`, or a refused\n // subscribe's `{\"error\"}` body), so a consumer can show the real reason; a\n // transport-style drop stays a bare Event, as native EventSource sends.\n function failSub(sub: Sub, message: string, context: { status?: number; cause?: unknown } = {}): void {\n sub.readyState = READY_STATE_CLOSED;\n dispatch(sub, \"error\", new ErrorEvent(\"error\", { message }));\n const status = context.status === undefined ? \"\" : ` (status ${context.status})`;\n const line = `[event-hub] ${sub.url} failed${status}: ${message}`;\n if (context.cause !== undefined) console.error(line, context.cause);\n else console.error(line);\n }\n\n async function refusedSubscribeMessage(res: Response): Promise<string> {\n const body = (await res.text()).trim();\n if (body === \"\") return `subscribe failed with status ${res.status} and no error message`;\n let error: unknown;\n try {\n error = (JSON.parse(body) as { error?: unknown }).error;\n } catch {\n // Not the hub's JSON error shape (e.g. a proxy's HTML/text page): show it verbatim.\n }\n return typeof error === \"string\" && error !== \"\" ? error : `subscribe failed with status ${res.status}: ${body}`;\n }\n\n async function postSub(sub: Sub): Promise<void> {\n const conn = connId;\n if (!conn || sub.disposed || sub.readyState === READY_STATE_CLOSED) return;\n // A response for a connection that has since dropped (or a sub that has\n // since failed) is stale: the next __hello re-subscribes on the live one.\n const stale = () => sub.disposed || conn !== connId || sub.readyState === READY_STATE_CLOSED;\n try {\n const res = await fetch(`${hubUrl}/${conn}/subs`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ id: sub.id, path: sub.url }),\n });\n if (stale()) return;\n if (res.status === 204) {\n sub.readyState = READY_STATE_OPEN;\n dispatch(sub, \"open\", new Event(\"open\"));\n return;\n }\n if (res.status === 404) return; // stale conn id; the next __hello retries\n const message = await refusedSubscribeMessage(res);\n if (stale()) return;\n failSub(sub, message, { status: res.status });\n } catch (err) {\n if (stale()) return;\n failSub(sub, `subscribe request failed: ${err instanceof Error ? err.message : String(err)}`, { cause: err });\n }\n }\n\n function onHello(event: MessageEvent): void {\n const payload = JSON.parse(event.data) as { conn: string; build?: string };\n connId = payload.conn;\n maybeReloadForBuildMismatch(payload.build);\n // A hello means every currently-active sub needs a fresh subscription: the\n // first hello of a brand-new connection, or a reconnect hello after a\n // drop, both start from a server side with no subs registered yet.\n for (const sub of subs.values()) {\n if (!sub.disposed) void postSub(sub);\n }\n }\n\n function onRealError(es: EventSourceLike): void {\n connId = null;\n for (const sub of subs.values()) {\n if (sub.disposed || sub.readyState === READY_STATE_CLOSED) continue;\n sub.readyState = READY_STATE_CONNECTING;\n dispatch(sub, \"error\", new Event(\"error\"));\n }\n // Native EventSource reconnects on its own after a transient error; the\n // next __hello re-subscribes everything and dispatches 'open' again. A\n // CLOSED source (non-200 or wrong Content-Type) never reconnects, so drop\n // it and open a replacement after a delay.\n if (es.readyState !== READY_STATE_CLOSED || real !== es) return;\n for (const sub of subs.values()) {\n for (const [eventName, handler] of sub.routedHandlers) es.removeEventListener(eventName, handler);\n sub.routedHandlers.clear();\n }\n es.onerror = null;\n real = null;\n setTimeout(() => {\n if (!real && subs.size > 0) ensureRealOpen();\n }, RESUBSCRIBE_DELAY_MS);\n }\n\n function ensureRealOpen(): EventSourceLike {\n if (real) {\n if (teardownTimer) {\n clearTimeout(teardownTimer);\n teardownTimer = null;\n }\n return real;\n }\n connId = null;\n const es = new EventSource(hubUrl);\n es.addEventListener(\"__hello\", (event) => onHello(event as MessageEvent));\n es.onerror = () => onRealError(es);\n real = es;\n routeActiveSubs();\n return es;\n }\n\n // routeActiveSubs binds every live sub's routing onto a freshly created real\n // connection (a replacement after a terminal error has none yet).\n function routeActiveSubs(): void {\n for (const sub of subs.values()) {\n if (sub.disposed) continue;\n routeName(sub, \"message\");\n for (const name of sub.listeners.keys()) routeName(sub, name);\n routeClosed(sub);\n }\n }\n\n const eventNameFor = (sub: Sub, name: string) => `${sub.id}/${name}`;\n\n // routeName registers, at most once per sub+name, a real-connection listener\n // that re-dispatches `${sub.id}/${name}` frames to this sub's own listeners.\n // \"open\" is synthetic (dispatched locally on subscribe/reconnect) and never\n // arrives on the wire, so it is never routed. A closed sub has no routing to\n // register: its real connection may already be torn down, and no frame for\n // it can arrive. With no real connection (awaiting a replacement after a\n // terminal error) routing is deferred to routeActiveSubs.\n function routeName(sub: Sub, name: string): void {\n const eventName = eventNameFor(sub, name);\n if (!real || name === \"open\" || sub.disposed || sub.routedHandlers.has(eventName)) return;\n const handler = (event: Event) => {\n const message = event as MessageEvent;\n dispatch(sub, name, new MessageEvent(name, { data: message.data, lastEventId: message.lastEventId }));\n };\n real.addEventListener(eventName, handler);\n sub.routedHandlers.set(eventName, handler);\n }\n\n // A sub's __closed frame is clicky sse hubClosed: {\"status\": int,\n // \"error\"?: string}, `error` being the handler's (≤500 byte) response body.\n function onSubClosed(sub: Sub, event: MessageEvent): void {\n if (sub.disposed) return;\n let payload: { status: number; error?: string };\n try {\n payload = JSON.parse(event.data) as { status: number; error?: string };\n } catch (err) {\n failSub(sub, `sub closed with a malformed __closed frame: ${String(event.data)}`, { cause: err });\n return;\n }\n if (payload.status >= 200 && payload.status < 300) {\n // The server-side handler ended on its own with a success status — the\n // same shape as a native stream simply reconnecting.\n sub.readyState = READY_STATE_CONNECTING;\n dispatch(sub, \"error\", new Event(\"error\"));\n sub.resubscribeTimer = setTimeout(() => {\n sub.resubscribeTimer = null;\n if (!sub.disposed) void postSub(sub);\n }, RESUBSCRIBE_DELAY_MS);\n return;\n }\n // http.Error bodies end in a newline; only trailing whitespace is dropped.\n const error = payload.error?.trimEnd() ?? \"\";\n failSub(sub, error !== \"\" ? error : `sub closed with status ${payload.status} and no error message`, {\n status: payload.status,\n });\n }\n\n // routeClosed wires the sub's terminal frame: unlike every other name, its\n // payload drives re-subscription rather than being handed to consumers.\n function routeClosed(sub: Sub): void {\n const eventName = eventNameFor(sub, \"__closed\");\n if (!real || sub.routedHandlers.has(eventName)) return;\n const handler = (event: Event) => onSubClosed(sub, event as MessageEvent);\n real.addEventListener(eventName, handler);\n sub.routedHandlers.set(eventName, handler);\n }\n\n function scheduleTeardownIfIdle(): void {\n if (subs.size > 0 || teardownTimer) return;\n teardownTimer = setTimeout(() => {\n teardownTimer = null;\n if (subs.size > 0) return; // something re-subscribed during the grace window\n real?.close();\n real = null;\n connId = null;\n }, TEARDOWN_GRACE_MS);\n }\n\n function closeSub(sub: Sub): void {\n if (sub.disposed) return;\n sub.disposed = true;\n sub.readyState = READY_STATE_CLOSED;\n if (sub.resubscribeTimer) {\n clearTimeout(sub.resubscribeTimer);\n sub.resubscribeTimer = null;\n }\n for (const [eventName, handler] of sub.routedHandlers) real?.removeEventListener(eventName, handler);\n sub.routedHandlers.clear();\n subs.delete(sub.id);\n\n const conn = connId;\n if (conn) {\n fetch(`${hubUrl}/${conn}/subs/${sub.id}`, { method: \"DELETE\" })\n .then((res) => {\n if (!res.ok && res.status !== 404) console.error(`[event-hub] unsubscribe failed for ${sub.url}: ${res.status}`);\n })\n .catch((err) => console.error(`[event-hub] unsubscribe request failed for ${sub.url}:`, err));\n }\n scheduleTeardownIfIdle();\n }\n\n const hooks = { route: routeName, close: closeSub };\n\n return (url) => {\n const sub = new Sub(`s${++subCounter}`, url, hooks);\n subs.set(sub.id, sub);\n ensureRealOpen();\n // Routing must be registered before the subscribe POST is sent: frames can\n // start arriving on the real connection as soon as the server accepts the\n // subscription, which can race the POST's own response.\n routeName(sub, \"message\");\n routeClosed(sub);\n if (connId) void postSub(sub);\n return sub;\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const require_runtime = require("../../_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
let react = require("react");
|
|
3
|
+
react = require_runtime.__toESM(react, 1);
|
|
4
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
5
|
+
// src/icons/components/UiBrowser.tsx
|
|
6
|
+
var UiBrowser = Object.assign(({ size = "1em", className, title, ...props }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
7
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
8
|
+
width: size,
|
|
9
|
+
height: size,
|
|
10
|
+
viewBox: "0 0 256 256",
|
|
11
|
+
role: title ? "img" : "presentation",
|
|
12
|
+
"aria-label": title,
|
|
13
|
+
"aria-hidden": title ? void 0 : true,
|
|
14
|
+
className,
|
|
15
|
+
...props,
|
|
16
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
17
|
+
fill: "currentColor",
|
|
18
|
+
d: "M216 42H40a14 14 0 0 0-14 14v144a14 14 0 0 0 14 14h176a14 14 0 0 0 14-14V56a14 14 0 0 0-14-14M40 54h176a2 2 0 0 1 2 2v34H38V56a2 2 0 0 1 2-2m176 148H40a2 2 0 0 1-2-2v-98h180v98a2 2 0 0 1-2 2"
|
|
19
|
+
})
|
|
20
|
+
}), {
|
|
21
|
+
__source: "ph:browser-light",
|
|
22
|
+
__viewBox: "0 0 256 256",
|
|
23
|
+
__group: "infrastructure",
|
|
24
|
+
__consumerName: "browser",
|
|
25
|
+
displayName: "UiBrowser"
|
|
26
|
+
});
|
|
27
|
+
var UiBrowserFilled = Object.assign(({ size = "1em", className, title, ...props }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
28
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
29
|
+
width: size,
|
|
30
|
+
height: size,
|
|
31
|
+
viewBox: "0 0 256 256",
|
|
32
|
+
role: title ? "img" : "presentation",
|
|
33
|
+
"aria-label": title,
|
|
34
|
+
"aria-hidden": title ? void 0 : true,
|
|
35
|
+
className,
|
|
36
|
+
...props,
|
|
37
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
38
|
+
fill: "currentColor",
|
|
39
|
+
d: "M216 40H40a16 16 0 0 0-16 16v144a16 16 0 0 0 16 16h176a16 16 0 0 0 16-16V56a16 16 0 0 0-16-16m0 16v32H40V56Z"
|
|
40
|
+
})
|
|
41
|
+
}), {
|
|
42
|
+
__source: "ph:browser-fill",
|
|
43
|
+
__viewBox: "0 0 256 256",
|
|
44
|
+
__group: "infrastructure",
|
|
45
|
+
__consumerName: "browser",
|
|
46
|
+
displayName: "UiBrowserFilled"
|
|
47
|
+
});
|
|
48
|
+
exports.UiBrowser = UiBrowser;
|
|
49
|
+
exports.UiBrowserFilled = UiBrowserFilled;
|
|
50
|
+
|
|
51
|
+
//# sourceMappingURL=UiBrowser.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UiBrowser.cjs","names":[],"sources":["../../../src/icons/components/UiBrowser.tsx"],"sourcesContent":["import * as React from \"react\";\nimport type { IconProps } from \"../types\";\n\n// source: ph:browser-light\nexport const UiBrowser: React.FC<IconProps> & { __source: string; __viewBox: string; __group: string; __consumerName: string } = Object.assign(\n ({ size = \"1em\", className, title, ...props }: IconProps) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width={size} height={size} viewBox=\"0 0 256 256\" role={title ? \"img\" : \"presentation\"} aria-label={title} aria-hidden={title ? undefined : true} className={className} {...props}>\n <path fill=\"currentColor\" d=\"M216 42H40a14 14 0 0 0-14 14v144a14 14 0 0 0 14 14h176a14 14 0 0 0 14-14V56a14 14 0 0 0-14-14M40 54h176a2 2 0 0 1 2 2v34H38V56a2 2 0 0 1 2-2m176 148H40a2 2 0 0 1-2-2v-98h180v98a2 2 0 0 1-2 2\"/>\n </svg>\n ),\n { __source: \"ph:browser-light\", __viewBox: \"0 0 256 256\", __group: \"infrastructure\", __consumerName: \"browser\", displayName: \"UiBrowser\" },\n);\n\n// source: ph:browser-fill\nexport const UiBrowserFilled: React.FC<IconProps> & { __source: string; __viewBox: string; __group: string; __consumerName: string } = Object.assign(\n ({ size = \"1em\", className, title, ...props }: IconProps) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width={size} height={size} viewBox=\"0 0 256 256\" role={title ? \"img\" : \"presentation\"} aria-label={title} aria-hidden={title ? undefined : true} className={className} {...props}>\n <path fill=\"currentColor\" d=\"M216 40H40a16 16 0 0 0-16 16v144a16 16 0 0 0 16 16h176a16 16 0 0 0 16-16V56a16 16 0 0 0-16-16m0 16v32H40V56Z\"/>\n </svg>\n ),\n { __source: \"ph:browser-fill\", __viewBox: \"0 0 256 256\", __group: \"infrastructure\", __consumerName: \"browser\", displayName: \"UiBrowserFilled\" },\n);\n"],"mappings":";;;;;AAIA,IAAa,YAAoH,OAAO,QACrI,EAAE,OAAO,OAAO,WAAW,OAAO,GAAG,YACpC,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;CAAK,OAAM;CAA6B,OAAO;CAAM,QAAQ;CAAM,SAAQ;CAAc,MAAM,QAAQ,QAAQ;CAAgB,cAAY;CAAO,eAAa,QAAQ,KAAA,IAAY;CAAiB;CAAW,GAAI;CACjN,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;EAAM,MAAK;EAAe,GAAE;CAAiM,CAAA;AAC1N,CAAA,GAEP;CAAE,UAAU;CAAoB,WAAW;CAAe,SAAS;CAAkB,gBAAgB;CAAW,aAAa;AAAY,CAC3I;AAGA,IAAa,kBAA0H,OAAO,QAC3I,EAAE,OAAO,OAAO,WAAW,OAAO,GAAG,YACpC,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;CAAK,OAAM;CAA6B,OAAO;CAAM,QAAQ;CAAM,SAAQ;CAAc,MAAM,QAAQ,QAAQ;CAAgB,cAAY;CAAO,eAAa,QAAQ,KAAA,IAAY;CAAiB;CAAW,GAAI;CACjN,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;EAAM,MAAK;EAAe,GAAE;CAA+G,CAAA;AACxI,CAAA,GAEP;CAAE,UAAU;CAAmB,WAAW;CAAe,SAAS;CAAkB,gBAAgB;CAAW,aAAa;AAAkB,CAChJ"}
|