@flanksource/clicky-ui 0.3.17 → 0.3.18
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/dist/ai.cjs +12 -6
- package/dist/ai.cjs.map +1 -1
- package/dist/ai.js +10 -4
- package/dist/ai.js.map +1 -1
- package/dist/chat.cjs +36 -0
- package/dist/chat.cjs.map +1 -1
- package/dist/chat.js +37 -1
- package/dist/chat.js.map +1 -1
- package/dist/components/Combobox.cjs +122 -153
- package/dist/components/Combobox.cjs.map +1 -1
- package/dist/components/Combobox.d.ts.map +1 -1
- package/dist/components/Combobox.js +124 -155
- package/dist/components/Combobox.js.map +1 -1
- package/dist/components/ComboboxControl.cjs +145 -0
- package/dist/components/ComboboxControl.cjs.map +1 -0
- package/dist/components/ComboboxControl.d.ts +37 -0
- package/dist/components/ComboboxControl.d.ts.map +1 -0
- package/dist/components/ComboboxControl.js +145 -0
- package/dist/components/ComboboxControl.js.map +1 -0
- package/dist/components/ComboboxMenu.cjs +31 -14
- package/dist/components/ComboboxMenu.cjs.map +1 -1
- package/dist/components/ComboboxMenu.d.ts.map +1 -1
- package/dist/components/ComboboxMenu.js +31 -14
- package/dist/components/ComboboxMenu.js.map +1 -1
- package/dist/components/ComboboxTags.cjs +40 -0
- package/dist/components/ComboboxTags.cjs.map +1 -0
- package/dist/components/ComboboxTags.d.ts +8 -0
- package/dist/components/ComboboxTags.d.ts.map +1 -0
- package/dist/components/ComboboxTags.js +40 -0
- package/dist/components/ComboboxTags.js.map +1 -0
- package/dist/components/ErrorWrapper.cjs +168 -0
- package/dist/components/ErrorWrapper.cjs.map +1 -0
- package/dist/components/ErrorWrapper.d.ts +19 -0
- package/dist/components/ErrorWrapper.d.ts.map +1 -0
- package/dist/components/ErrorWrapper.js +168 -0
- package/dist/components/ErrorWrapper.js.map +1 -0
- package/dist/components/FilterBar.cjs +64 -2
- package/dist/components/FilterBar.cjs.map +1 -1
- package/dist/components/FilterBar.d.ts +18 -1
- package/dist/components/FilterBar.d.ts.map +1 -1
- package/dist/components/FilterBar.js +64 -2
- package/dist/components/FilterBar.js.map +1 -1
- package/dist/components/JSONPathField.cjs +91 -0
- package/dist/components/JSONPathField.cjs.map +1 -0
- package/dist/components/JSONPathField.d.ts +19 -0
- package/dist/components/JSONPathField.d.ts.map +1 -0
- package/dist/components/JSONPathField.js +91 -0
- package/dist/components/JSONPathField.js.map +1 -0
- package/dist/components/JsonSchemaForm.cjs +8 -4
- package/dist/components/JsonSchemaForm.cjs.map +1 -1
- package/dist/components/JsonSchemaForm.d.ts.map +1 -1
- package/dist/components/JsonSchemaForm.js +8 -4
- package/dist/components/JsonSchemaForm.js.map +1 -1
- package/dist/components/TreePickerField.cjs +22 -4
- package/dist/components/TreePickerField.cjs.map +1 -1
- package/dist/components/TreePickerField.d.ts +22 -2
- package/dist/components/TreePickerField.d.ts.map +1 -1
- package/dist/components/TreePickerField.js +22 -4
- package/dist/components/TreePickerField.js.map +1 -1
- package/dist/components/TriStateToggle.cjs +53 -0
- package/dist/components/TriStateToggle.cjs.map +1 -0
- package/dist/components/TriStateToggle.d.ts +27 -0
- package/dist/components/TriStateToggle.d.ts.map +1 -0
- package/dist/components/TriStateToggle.js +53 -0
- package/dist/components/TriStateToggle.js.map +1 -0
- package/dist/components/combobox-types.d.ts +16 -1
- package/dist/components/combobox-types.d.ts.map +1 -1
- package/dist/components/combobox-utils.cjs +26 -0
- package/dist/components/combobox-utils.cjs.map +1 -1
- package/dist/components/combobox-utils.d.ts +10 -0
- package/dist/components/combobox-utils.d.ts.map +1 -1
- package/dist/components/combobox-utils.js +26 -0
- package/dist/components/combobox-utils.js.map +1 -1
- package/dist/components/filter-bar-utils.cjs +5 -0
- package/dist/components/filter-bar-utils.cjs.map +1 -1
- package/dist/components/filter-bar-utils.d.ts.map +1 -1
- package/dist/components/filter-bar-utils.js +5 -0
- package/dist/components/filter-bar-utils.js.map +1 -1
- package/dist/components/json-schema-form-accordion-array.cjs +290 -0
- package/dist/components/json-schema-form-accordion-array.cjs.map +1 -0
- package/dist/components/json-schema-form-accordion-array.d.ts +7 -0
- package/dist/components/json-schema-form-accordion-array.d.ts.map +1 -0
- package/dist/components/json-schema-form-accordion-array.js +290 -0
- package/dist/components/json-schema-form-accordion-array.js.map +1 -0
- package/dist/components/json-schema-form-array.cjs +99 -110
- package/dist/components/json-schema-form-array.cjs.map +1 -1
- package/dist/components/json-schema-form-array.d.ts +1 -1
- package/dist/components/json-schema-form-array.d.ts.map +1 -1
- package/dist/components/json-schema-form-array.js +98 -109
- package/dist/components/json-schema-form-array.js.map +1 -1
- package/dist/components/json-schema-form-error-display.cjs +4 -2
- package/dist/components/json-schema-form-error-display.cjs.map +1 -1
- package/dist/components/json-schema-form-error-display.d.ts +4 -2
- package/dist/components/json-schema-form-error-display.d.ts.map +1 -1
- package/dist/components/json-schema-form-error-display.js +4 -2
- package/dist/components/json-schema-form-error-display.js.map +1 -1
- package/dist/components/json-schema-form-extensions.cjs +10 -0
- package/dist/components/json-schema-form-extensions.cjs.map +1 -0
- package/dist/components/json-schema-form-extensions.d.ts +8 -0
- package/dist/components/json-schema-form-extensions.d.ts.map +1 -0
- package/dist/components/json-schema-form-extensions.js +10 -0
- package/dist/components/json-schema-form-extensions.js.map +1 -0
- package/dist/components/json-schema-form-fields.cjs +25 -101
- package/dist/components/json-schema-form-fields.cjs.map +1 -1
- package/dist/components/json-schema-form-fields.d.ts +1 -32
- package/dist/components/json-schema-form-fields.d.ts.map +1 -1
- package/dist/components/json-schema-form-fields.js +28 -104
- package/dist/components/json-schema-form-fields.js.map +1 -1
- package/dist/components/json-schema-form-item-summary.cjs +131 -0
- package/dist/components/json-schema-form-item-summary.cjs.map +1 -0
- package/dist/components/json-schema-form-item-summary.d.ts +13 -0
- package/dist/components/json-schema-form-item-summary.d.ts.map +1 -0
- package/dist/components/json-schema-form-item-summary.js +131 -0
- package/dist/components/json-schema-form-item-summary.js.map +1 -0
- package/dist/components/json-schema-form-layout.cjs +156 -0
- package/dist/components/json-schema-form-layout.cjs.map +1 -0
- package/dist/components/json-schema-form-layout.d.ts +43 -0
- package/dist/components/json-schema-form-layout.d.ts.map +1 -0
- package/dist/components/json-schema-form-layout.js +156 -0
- package/dist/components/json-schema-form-layout.js.map +1 -0
- package/dist/components/json-schema-form-lookup-tree.cjs +149 -0
- package/dist/components/json-schema-form-lookup-tree.cjs.map +1 -0
- package/dist/components/json-schema-form-lookup-tree.d.ts +22 -0
- package/dist/components/json-schema-form-lookup-tree.d.ts.map +1 -0
- package/dist/components/json-schema-form-lookup-tree.js +149 -0
- package/dist/components/json-schema-form-lookup-tree.js.map +1 -0
- package/dist/components/json-schema-form-object.cjs +11 -4
- 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 +11 -4
- package/dist/components/json-schema-form-object.js.map +1 -1
- package/dist/components/json-schema-form-render.cjs +51 -28
- 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 +51 -28
- package/dist/components/json-schema-form-render.js.map +1 -1
- package/dist/components/json-schema-form-resolve.cjs +62 -13
- package/dist/components/json-schema-form-resolve.cjs.map +1 -1
- package/dist/components/json-schema-form-resolve.d.ts +1 -0
- package/dist/components/json-schema-form-resolve.d.ts.map +1 -1
- package/dist/components/json-schema-form-resolve.js +62 -13
- package/dist/components/json-schema-form-resolve.js.map +1 -1
- package/dist/components/json-schema-form-table-array.cjs +123 -0
- package/dist/components/json-schema-form-table-array.cjs.map +1 -0
- package/dist/components/json-schema-form-table-array.d.ts +7 -0
- package/dist/components/json-schema-form-table-array.d.ts.map +1 -0
- package/dist/components/json-schema-form-table-array.js +123 -0
- package/dist/components/json-schema-form-table-array.js.map +1 -0
- package/dist/components/json-schema-form-tone.cjs +34 -0
- package/dist/components/json-schema-form-tone.cjs.map +1 -0
- package/dist/components/json-schema-form-tone.d.ts +8 -0
- package/dist/components/json-schema-form-tone.d.ts.map +1 -0
- package/dist/components/json-schema-form-tone.js +34 -0
- package/dist/components/json-schema-form-tone.js.map +1 -0
- package/dist/components/json-schema-form-types.d.ts +79 -10
- package/dist/components/json-schema-form-types.d.ts.map +1 -1
- package/dist/components/json-schema-form-utils.cjs +47 -4
- package/dist/components/json-schema-form-utils.cjs.map +1 -1
- package/dist/components/json-schema-form-utils.d.ts +19 -4
- package/dist/components/json-schema-form-utils.d.ts.map +1 -1
- package/dist/components/json-schema-form-utils.js +47 -4
- package/dist/components/json-schema-form-utils.js.map +1 -1
- package/dist/components/tri-state.cjs +8 -0
- package/dist/components/tri-state.cjs.map +1 -0
- package/dist/components/tri-state.d.ts +5 -0
- package/dist/components/tri-state.d.ts.map +1 -0
- package/dist/components/tri-state.js +8 -0
- package/dist/components/tri-state.js.map +1 -0
- package/dist/components/useComboboxLayout.cjs +59 -0
- package/dist/components/useComboboxLayout.cjs.map +1 -0
- package/dist/components/useComboboxLayout.d.ts +5 -0
- package/dist/components/useComboboxLayout.d.ts.map +1 -0
- package/dist/components/useComboboxLayout.js +59 -0
- package/dist/components/useComboboxLayout.js.map +1 -0
- package/dist/components.cjs +21 -0
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.ts +14 -4
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +22 -1
- package/dist/components.js.map +1 -1
- package/dist/data/Clicky.cjs +51 -2
- package/dist/data/Clicky.cjs.map +1 -1
- package/dist/data/Clicky.d.ts +10 -1
- package/dist/data/Clicky.d.ts.map +1 -1
- package/dist/data/Clicky.js +51 -2
- package/dist/data/Clicky.js.map +1 -1
- package/dist/data/DataTable.cjs +185 -53
- package/dist/data/DataTable.cjs.map +1 -1
- package/dist/data/DataTable.d.ts +63 -3
- package/dist/data/DataTable.d.ts.map +1 -1
- package/dist/data/DataTable.js +185 -53
- package/dist/data/DataTable.js.map +1 -1
- package/dist/data/LogsTable.cjs +10 -1
- package/dist/data/LogsTable.cjs.map +1 -1
- package/dist/data/LogsTable.d.ts +3 -1
- package/dist/data/LogsTable.d.ts.map +1 -1
- package/dist/data/LogsTable.js +10 -1
- package/dist/data/LogsTable.js.map +1 -1
- package/dist/data/TaskManager.cjs +99 -14
- package/dist/data/TaskManager.cjs.map +1 -1
- package/dist/data/TaskManager.d.ts.map +1 -1
- package/dist/data/TaskManager.js +100 -15
- package/dist/data/TaskManager.js.map +1 -1
- package/dist/data/TaskProgress.cjs +50 -11
- package/dist/data/TaskProgress.cjs.map +1 -1
- package/dist/data/TaskProgress.d.ts +2 -1
- package/dist/data/TaskProgress.d.ts.map +1 -1
- package/dist/data/TaskProgress.js +50 -11
- package/dist/data/TaskProgress.js.map +1 -1
- package/dist/data/ai/AdvancedChatConfig.cjs +289 -0
- package/dist/data/ai/AdvancedChatConfig.cjs.map +1 -0
- package/dist/data/ai/AdvancedChatConfig.d.ts +21 -0
- package/dist/data/ai/AdvancedChatConfig.d.ts.map +1 -0
- package/dist/data/ai/AdvancedChatConfig.js +289 -0
- package/dist/data/ai/AdvancedChatConfig.js.map +1 -0
- package/dist/data/ai/AdvancedCostsPanel.cjs +120 -0
- package/dist/data/ai/AdvancedCostsPanel.cjs.map +1 -0
- package/dist/data/ai/AdvancedCostsPanel.d.ts +16 -0
- package/dist/data/ai/AdvancedCostsPanel.d.ts.map +1 -0
- package/dist/data/ai/AdvancedCostsPanel.js +120 -0
- package/dist/data/ai/AdvancedCostsPanel.js.map +1 -0
- package/dist/data/ai/ChatWindow.catalogs.cjs +74 -0
- package/dist/data/ai/ChatWindow.catalogs.cjs.map +1 -0
- package/dist/data/ai/ChatWindow.catalogs.d.ts +16 -0
- package/dist/data/ai/ChatWindow.catalogs.d.ts.map +1 -0
- package/dist/data/ai/ChatWindow.catalogs.js +74 -0
- package/dist/data/ai/ChatWindow.catalogs.js.map +1 -0
- package/dist/data/ai/ChatWindow.cjs +78 -100
- package/dist/data/ai/ChatWindow.cjs.map +1 -1
- package/dist/data/ai/ChatWindow.d.ts +1 -1
- package/dist/data/ai/ChatWindow.d.ts.map +1 -1
- package/dist/data/ai/ChatWindow.js +80 -102
- package/dist/data/ai/ChatWindow.js.map +1 -1
- package/dist/data/ai/ChatWindow.preferences.cjs.map +1 -1
- package/dist/data/ai/ChatWindow.preferences.d.ts +2 -4
- package/dist/data/ai/ChatWindow.preferences.d.ts.map +1 -1
- package/dist/data/ai/ChatWindow.preferences.js.map +1 -1
- package/dist/data/ai/ChatWindow.runtime.cjs +120 -0
- package/dist/data/ai/ChatWindow.runtime.cjs.map +1 -0
- package/dist/data/ai/ChatWindow.runtime.d.ts +20 -0
- package/dist/data/ai/ChatWindow.runtime.d.ts.map +1 -0
- package/dist/data/ai/ChatWindow.runtime.js +120 -0
- package/dist/data/ai/ChatWindow.runtime.js.map +1 -0
- package/dist/data/ai/ChatWindow.thread.cjs +1 -1
- package/dist/data/ai/ChatWindow.thread.cjs.map +1 -1
- package/dist/data/ai/ChatWindow.thread.js +1 -1
- package/dist/data/ai/ChatWindow.thread.js.map +1 -1
- package/dist/data/ai/ChatWindow.tool-catalog.cjs +20 -0
- package/dist/data/ai/ChatWindow.tool-catalog.cjs.map +1 -1
- package/dist/data/ai/ChatWindow.tool-catalog.d.ts +17 -1
- package/dist/data/ai/ChatWindow.tool-catalog.d.ts.map +1 -1
- package/dist/data/ai/ChatWindow.tool-catalog.js +20 -0
- package/dist/data/ai/ChatWindow.tool-catalog.js.map +1 -1
- package/dist/data/ai/ChatWindow.types.d.ts +13 -5
- package/dist/data/ai/ChatWindow.types.d.ts.map +1 -1
- package/dist/data/ai/ChatWindowManager.cjs +3 -1
- package/dist/data/ai/ChatWindowManager.cjs.map +1 -1
- package/dist/data/ai/ChatWindowManager.d.ts.map +1 -1
- package/dist/data/ai/ChatWindowManager.js +3 -1
- package/dist/data/ai/ChatWindowManager.js.map +1 -1
- package/dist/data/ai/PromptPicker/PromptPicker.cjs +1 -1
- package/dist/data/ai/PromptPicker/PromptPicker.cjs.map +1 -1
- package/dist/data/ai/PromptPicker/PromptPicker.d.ts +1 -1
- package/dist/data/ai/PromptPicker/PromptPicker.d.ts.map +1 -1
- package/dist/data/ai/PromptPicker/PromptPicker.js +1 -1
- package/dist/data/ai/PromptPicker/PromptPicker.js.map +1 -1
- package/dist/data/ai/PromptRunEditor/index.cjs +2 -2
- package/dist/data/ai/PromptRunEditor/index.cjs.map +1 -1
- package/dist/data/ai/PromptRunEditor/index.d.ts +1 -1
- package/dist/data/ai/PromptRunEditor/index.d.ts.map +1 -1
- package/dist/data/ai/PromptRunEditor/index.js +2 -2
- package/dist/data/ai/PromptRunEditor/index.js.map +1 -1
- package/dist/data/ai/RuntimeModePicker.cjs +1 -1
- package/dist/data/ai/RuntimeModePicker.cjs.map +1 -1
- package/dist/data/ai/RuntimeModePicker.d.ts +1 -1
- package/dist/data/ai/RuntimeModePicker.d.ts.map +1 -1
- package/dist/data/ai/RuntimeModePicker.js +1 -1
- package/dist/data/ai/RuntimeModePicker.js.map +1 -1
- package/dist/data/ai/SessionInspector.files.cjs +26 -43
- package/dist/data/ai/SessionInspector.files.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.files.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.files.js +26 -43
- package/dist/data/ai/SessionInspector.files.js.map +1 -1
- package/dist/data/ai/SessionInspector.hierarchy.cjs +1 -1
- package/dist/data/ai/SessionInspector.hierarchy.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.hierarchy.js +1 -1
- package/dist/data/ai/SessionInspector.hierarchy.js.map +1 -1
- package/dist/data/ai/SessionInspector.model.cjs +1 -1
- package/dist/data/ai/SessionInspector.model.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.model.js +1 -1
- package/dist/data/ai/SessionInspector.model.js.map +1 -1
- package/dist/data/ai/SessionViewer.rows.cjs +4 -16
- package/dist/data/ai/SessionViewer.rows.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.rows.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.rows.js +4 -16
- package/dist/data/ai/SessionViewer.rows.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/ModelSection.cjs +12 -3
- package/dist/data/ai/SpecRuntimeEditor/ModelSection.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/ModelSection.d.ts +1 -1
- package/dist/data/ai/SpecRuntimeEditor/ModelSection.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/ModelSection.js +12 -3
- package/dist/data/ai/SpecRuntimeEditor/ModelSection.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/VerifySection.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/VerifySection.d.ts +1 -1
- package/dist/data/ai/SpecRuntimeEditor/VerifySection.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/VerifySection.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/fields.js +1 -1
- package/dist/data/ai/SpecRuntimeEditor/index.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/index.d.ts +2 -2
- package/dist/data/ai/SpecRuntimeEditor/index.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/index.js.map +1 -1
- package/dist/data/ai/ThreadPicker.cjs +65 -3
- package/dist/data/ai/ThreadPicker.cjs.map +1 -1
- package/dist/data/ai/ThreadPicker.d.ts +11 -5
- package/dist/data/ai/ThreadPicker.d.ts.map +1 -1
- package/dist/data/ai/ThreadPicker.js +65 -3
- package/dist/data/ai/ThreadPicker.js.map +1 -1
- package/dist/data/ai/ToolPreferences.cjs +65 -685
- package/dist/data/ai/ToolPreferences.cjs.map +1 -1
- package/dist/data/ai/ToolPreferences.d.ts +15 -17
- package/dist/data/ai/ToolPreferences.d.ts.map +1 -1
- package/dist/data/ai/ToolPreferences.js +64 -683
- package/dist/data/ai/ToolPreferences.js.map +1 -1
- package/dist/data/ai/ToolPreferences.model.cjs +148 -0
- package/dist/data/ai/ToolPreferences.model.cjs.map +1 -0
- package/dist/data/ai/ToolPreferences.model.d.ts +31 -0
- package/dist/data/ai/ToolPreferences.model.d.ts.map +1 -0
- package/dist/data/ai/ToolPreferences.model.js +148 -0
- package/dist/data/ai/ToolPreferences.model.js.map +1 -0
- package/dist/data/ai/ToolPreferencesList.cjs +270 -0
- package/dist/data/ai/ToolPreferencesList.cjs.map +1 -0
- package/dist/data/ai/ToolPreferencesList.d.ts +18 -0
- package/dist/data/ai/ToolPreferencesList.d.ts.map +1 -0
- package/dist/data/ai/ToolPreferencesList.js +270 -0
- package/dist/data/ai/ToolPreferencesList.js.map +1 -0
- package/dist/data/ai/agent-action-icons.cjs.map +1 -1
- package/dist/data/ai/agent-action-icons.js.map +1 -1
- package/dist/data/ai/chat-window-context.cjs +4 -1
- package/dist/data/ai/chat-window-context.cjs.map +1 -1
- package/dist/data/ai/chat-window-context.d.ts +7 -0
- package/dist/data/ai/chat-window-context.d.ts.map +1 -1
- package/dist/data/ai/chat-window-context.js +4 -1
- package/dist/data/ai/chat-window-context.js.map +1 -1
- package/dist/data/ai/index.d.ts +6 -3
- package/dist/data/ai/index.d.ts.map +1 -1
- package/dist/data/ai/session-tones.cjs +67 -0
- package/dist/data/ai/session-tones.cjs.map +1 -0
- package/dist/data/ai/session-tones.d.ts +34 -0
- package/dist/data/ai/session-tones.d.ts.map +1 -0
- package/dist/data/ai/session-tones.js +67 -0
- package/dist/data/ai/session-tones.js.map +1 -0
- package/dist/data/ai/thread-costs.cjs +39 -0
- package/dist/data/ai/thread-costs.cjs.map +1 -0
- package/dist/data/ai/thread-costs.d.ts +62 -0
- package/dist/data/ai/thread-costs.d.ts.map +1 -0
- package/dist/data/ai/thread-costs.js +39 -0
- package/dist/data/ai/thread-costs.js.map +1 -0
- package/dist/data/cells/CellFilterActions.cjs +68 -0
- package/dist/data/cells/CellFilterActions.cjs.map +1 -0
- package/dist/data/cells/CellFilterActions.d.ts +15 -0
- package/dist/data/cells/CellFilterActions.d.ts.map +1 -0
- package/dist/data/cells/CellFilterActions.js +68 -0
- package/dist/data/cells/CellFilterActions.js.map +1 -0
- package/dist/data/chat/Chat.cjs +156 -113
- package/dist/data/chat/Chat.cjs.map +1 -1
- package/dist/data/chat/Chat.d.ts +24 -7
- package/dist/data/chat/Chat.d.ts.map +1 -1
- package/dist/data/chat/Chat.fixtures.cjs +48 -3
- package/dist/data/chat/Chat.fixtures.cjs.map +1 -1
- package/dist/data/chat/Chat.fixtures.d.ts +1 -1
- package/dist/data/chat/Chat.fixtures.d.ts.map +1 -1
- package/dist/data/chat/Chat.fixtures.js +48 -3
- package/dist/data/chat/Chat.fixtures.js.map +1 -1
- package/dist/data/chat/Chat.js +160 -117
- package/dist/data/chat/Chat.js.map +1 -1
- package/dist/data/chat/Chat.runtime.cjs +63 -0
- package/dist/data/chat/Chat.runtime.cjs.map +1 -0
- package/dist/data/chat/Chat.runtime.d.ts +16 -0
- package/dist/data/chat/Chat.runtime.d.ts.map +1 -0
- package/dist/data/chat/Chat.runtime.js +63 -0
- package/dist/data/chat/Chat.runtime.js.map +1 -0
- package/dist/data/chat/ChatRuntimeToolbar.cjs +62 -0
- package/dist/data/chat/ChatRuntimeToolbar.cjs.map +1 -0
- package/dist/data/chat/ChatRuntimeToolbar.d.ts +14 -0
- package/dist/data/chat/ChatRuntimeToolbar.d.ts.map +1 -0
- package/dist/data/chat/ChatRuntimeToolbar.js +62 -0
- package/dist/data/chat/ChatRuntimeToolbar.js.map +1 -0
- package/dist/data/chat/ToolCall.cjs +86 -24
- package/dist/data/chat/ToolCall.cjs.map +1 -1
- package/dist/data/chat/ToolCall.d.ts +12 -5
- package/dist/data/chat/ToolCall.d.ts.map +1 -1
- package/dist/data/chat/ToolCall.js +86 -24
- package/dist/data/chat/ToolCall.js.map +1 -1
- package/dist/data/chat/approval.cjs +49 -6
- package/dist/data/chat/approval.cjs.map +1 -1
- package/dist/data/chat/approval.d.ts +11 -4
- package/dist/data/chat/approval.d.ts.map +1 -1
- package/dist/data/chat/approval.js +49 -6
- package/dist/data/chat/approval.js.map +1 -1
- package/dist/data/chat/index.d.ts +5 -3
- package/dist/data/chat/index.d.ts.map +1 -1
- package/dist/data/chat/tool-render/ToolArgs.cjs +50 -0
- package/dist/data/chat/tool-render/ToolArgs.cjs.map +1 -0
- package/dist/data/chat/tool-render/ToolArgs.d.ts +7 -0
- package/dist/data/chat/tool-render/ToolArgs.d.ts.map +1 -0
- package/dist/data/chat/tool-render/ToolArgs.js +50 -0
- package/dist/data/chat/tool-render/ToolArgs.js.map +1 -0
- package/dist/data/chat/tool-render/ToolParams.cjs +155 -0
- package/dist/data/chat/tool-render/ToolParams.cjs.map +1 -0
- package/dist/data/chat/tool-render/ToolParams.d.ts +20 -0
- package/dist/data/chat/tool-render/ToolParams.d.ts.map +1 -0
- package/dist/data/chat/tool-render/ToolParams.js +155 -0
- package/dist/data/chat/tool-render/ToolParams.js.map +1 -0
- package/dist/data/chat/tool-render/ToolValue.cjs +140 -0
- package/dist/data/chat/tool-render/ToolValue.cjs.map +1 -0
- package/dist/data/chat/tool-render/ToolValue.d.ts +16 -0
- package/dist/data/chat/tool-render/ToolValue.d.ts.map +1 -0
- package/dist/data/chat/tool-render/ToolValue.js +140 -0
- package/dist/data/chat/tool-render/ToolValue.js.map +1 -0
- package/dist/data/chat/tool-render/adapter.cjs +48 -0
- package/dist/data/chat/tool-render/adapter.cjs.map +1 -0
- package/dist/data/chat/tool-render/adapter.d.ts +57 -0
- package/dist/data/chat/tool-render/adapter.d.ts.map +1 -0
- package/dist/data/chat/tool-render/adapter.js +48 -0
- package/dist/data/chat/tool-render/adapter.js.map +1 -0
- package/dist/data/chat/tool-render/context.cjs +16 -0
- package/dist/data/chat/tool-render/context.cjs.map +1 -0
- package/dist/data/chat/tool-render/context.d.ts +6 -0
- package/dist/data/chat/tool-render/context.d.ts.map +1 -0
- package/dist/data/chat/tool-render/context.js +16 -0
- package/dist/data/chat/tool-render/context.js.map +1 -0
- package/dist/data/chat/tool-render/defaults.cjs +45 -0
- package/dist/data/chat/tool-render/defaults.cjs.map +1 -0
- package/dist/data/chat/tool-render/defaults.d.ts +11 -0
- package/dist/data/chat/tool-render/defaults.d.ts.map +1 -0
- package/dist/data/chat/tool-render/defaults.js +45 -0
- package/dist/data/chat/tool-render/defaults.js.map +1 -0
- package/dist/data/chat/tool-render/index.d.ts +13 -0
- package/dist/data/chat/tool-render/index.d.ts.map +1 -0
- package/dist/data/chat/tool-render/known-tool-views.cjs +208 -0
- package/dist/data/chat/tool-render/known-tool-views.cjs.map +1 -0
- package/dist/data/chat/tool-render/known-tool-views.d.ts +10 -0
- package/dist/data/chat/tool-render/known-tool-views.d.ts.map +1 -0
- package/dist/data/chat/tool-render/known-tool-views.js +208 -0
- package/dist/data/chat/tool-render/known-tool-views.js.map +1 -0
- package/dist/data/chat/tool-render/known-tools.cjs +58 -0
- package/dist/data/chat/tool-render/known-tools.cjs.map +1 -0
- package/dist/data/chat/tool-render/known-tools.d.ts +4 -0
- package/dist/data/chat/tool-render/known-tools.d.ts.map +1 -0
- package/dist/data/chat/tool-render/known-tools.js +58 -0
- package/dist/data/chat/tool-render/known-tools.js.map +1 -0
- package/dist/data/chat/tool-render/normalize.cjs +42 -0
- package/dist/data/chat/tool-render/normalize.cjs.map +1 -0
- package/dist/data/chat/tool-render/normalize.d.ts +13 -0
- package/dist/data/chat/tool-render/normalize.d.ts.map +1 -0
- package/dist/data/chat/tool-render/normalize.js +42 -0
- package/dist/data/chat/tool-render/normalize.js.map +1 -0
- package/dist/data/chat/tool-render/registry.cjs +14 -0
- package/dist/data/chat/tool-render/registry.cjs.map +1 -0
- package/dist/data/chat/tool-render/registry.d.ts +7 -0
- package/dist/data/chat/tool-render/registry.d.ts.map +1 -0
- package/dist/data/chat/tool-render/registry.js +14 -0
- package/dist/data/chat/tool-render/registry.js.map +1 -0
- package/dist/data/chat/tool-render/schema.cjs +57 -0
- package/dist/data/chat/tool-render/schema.cjs.map +1 -0
- package/dist/data/chat/tool-render/schema.d.ts +28 -0
- package/dist/data/chat/tool-render/schema.d.ts.map +1 -0
- package/dist/data/chat/tool-render/schema.js +57 -0
- package/dist/data/chat/tool-render/schema.js.map +1 -0
- package/dist/data/chat/tool-render/shape.cjs +94 -0
- package/dist/data/chat/tool-render/shape.cjs.map +1 -0
- package/dist/data/chat/tool-render/shape.d.ts +39 -0
- package/dist/data/chat/tool-render/shape.d.ts.map +1 -0
- package/dist/data/chat/tool-render/shape.js +94 -0
- package/dist/data/chat/tool-render/shape.js.map +1 -0
- package/dist/data/chat/tool-render/summary.cjs +34 -0
- package/dist/data/chat/tool-render/summary.cjs.map +1 -0
- package/dist/data/chat/tool-render/summary.d.ts +8 -0
- package/dist/data/chat/tool-render/summary.d.ts.map +1 -0
- package/dist/data/chat/tool-render/summary.js +34 -0
- package/dist/data/chat/tool-render/summary.js.map +1 -0
- package/dist/data/chat/types.cjs.map +1 -1
- package/dist/data/chat/types.d.ts +7 -0
- package/dist/data/chat/types.d.ts.map +1 -1
- package/dist/data/chat/types.js.map +1 -1
- package/dist/data/chat/usage-snapshot.cjs +17 -0
- package/dist/data/chat/usage-snapshot.cjs.map +1 -0
- package/dist/data/chat/usage-snapshot.d.ts +21 -0
- package/dist/data/chat/usage-snapshot.d.ts.map +1 -0
- package/dist/data/chat/usage-snapshot.js +17 -0
- package/dist/data/chat/usage-snapshot.js.map +1 -0
- package/dist/data/data-table-filter-values.cjs +83 -0
- package/dist/data/data-table-filter-values.cjs.map +1 -0
- package/dist/data/data-table-filter-values.d.ts +18 -0
- package/dist/data/data-table-filter-values.d.ts.map +1 -0
- package/dist/data/data-table-filter-values.js +83 -0
- package/dist/data/data-table-filter-values.js.map +1 -0
- package/dist/data/data-table-server-filters.cjs +171 -0
- package/dist/data/data-table-server-filters.cjs.map +1 -0
- package/dist/data/data-table-server-filters.d.ts +128 -0
- package/dist/data/data-table-server-filters.d.ts.map +1 -0
- package/dist/data/data-table-server-filters.js +171 -0
- package/dist/data/data-table-server-filters.js.map +1 -0
- package/dist/data/query-browser/QueryBrowser.cjs +96 -19
- package/dist/data/query-browser/QueryBrowser.cjs.map +1 -1
- package/dist/data/query-browser/QueryBrowser.d.ts +37 -6
- package/dist/data/query-browser/QueryBrowser.d.ts.map +1 -1
- package/dist/data/query-browser/QueryBrowser.js +96 -19
- package/dist/data/query-browser/QueryBrowser.js.map +1 -1
- package/dist/data/query-browser/index.d.ts +1 -1
- package/dist/data/query-browser/index.d.ts.map +1 -1
- package/dist/data/runtime/ProviderStatusPanel.cjs +187 -0
- package/dist/data/runtime/ProviderStatusPanel.cjs.map +1 -0
- package/dist/data/runtime/ProviderStatusPanel.d.ts +10 -0
- package/dist/data/runtime/ProviderStatusPanel.d.ts.map +1 -0
- package/dist/data/runtime/ProviderStatusPanel.js +187 -0
- package/dist/data/runtime/ProviderStatusPanel.js.map +1 -0
- package/dist/data/runtime/RuntimeBar.cjs +147 -0
- package/dist/data/runtime/RuntimeBar.cjs.map +1 -0
- package/dist/data/{ai → runtime}/RuntimeBar.d.ts +8 -6
- package/dist/data/runtime/RuntimeBar.d.ts.map +1 -0
- package/dist/data/runtime/RuntimeBar.js +147 -0
- package/dist/data/runtime/RuntimeBar.js.map +1 -0
- package/dist/data/runtime/RuntimeBar.model.cjs.map +1 -0
- package/dist/data/{ai → runtime}/RuntimeBar.model.d.ts +2 -2
- package/dist/data/runtime/RuntimeBar.model.d.ts.map +1 -0
- package/dist/data/runtime/RuntimeBar.model.js.map +1 -0
- package/dist/data/{ai → runtime}/RuntimeBarCombo.cjs +25 -30
- package/dist/data/runtime/RuntimeBarCombo.cjs.map +1 -0
- package/dist/data/{ai → runtime}/RuntimeBarCombo.d.ts +4 -3
- package/dist/data/runtime/RuntimeBarCombo.d.ts.map +1 -0
- package/dist/data/{ai → runtime}/RuntimeBarCombo.js +25 -30
- package/dist/data/runtime/RuntimeBarCombo.js.map +1 -0
- package/dist/data/{ai/RuntimeBar.cjs → runtime/RuntimeBarSegments.cjs} +54 -120
- package/dist/data/runtime/RuntimeBarSegments.cjs.map +1 -0
- package/dist/data/runtime/RuntimeBarSegments.d.ts +25 -0
- package/dist/data/runtime/RuntimeBarSegments.d.ts.map +1 -0
- package/dist/data/{ai/RuntimeBar.js → runtime/RuntimeBarSegments.js} +58 -124
- package/dist/data/runtime/RuntimeBarSegments.js.map +1 -0
- package/dist/data/runtime/availability.cjs +11 -0
- package/dist/data/runtime/availability.cjs.map +1 -0
- package/dist/data/runtime/availability.d.ts +6 -0
- package/dist/data/runtime/availability.d.ts.map +1 -0
- package/dist/data/runtime/availability.js +11 -0
- package/dist/data/runtime/availability.js.map +1 -0
- package/dist/data/runtime/model-capabilities.cjs.map +1 -0
- package/dist/data/runtime/model-capabilities.d.ts.map +1 -0
- package/dist/data/runtime/model-capabilities.js.map +1 -0
- package/dist/data/runtime/provider-status.cjs +106 -0
- package/dist/data/runtime/provider-status.cjs.map +1 -0
- package/dist/data/runtime/provider-status.d.ts +24 -0
- package/dist/data/runtime/provider-status.d.ts.map +1 -0
- package/dist/data/runtime/provider-status.js +106 -0
- package/dist/data/runtime/provider-status.js.map +1 -0
- package/dist/data/{ai → runtime}/runtime-mode.cjs +119 -27
- package/dist/data/runtime/runtime-mode.cjs.map +1 -0
- package/dist/data/{ai → runtime}/runtime-mode.d.ts +7 -1
- package/dist/data/runtime/runtime-mode.d.ts.map +1 -0
- package/dist/data/{ai → runtime}/runtime-mode.js +120 -28
- package/dist/data/runtime/runtime-mode.js.map +1 -0
- package/dist/data/task-query-keys.cjs +26 -0
- package/dist/data/task-query-keys.cjs.map +1 -0
- package/dist/data/task-query-keys.d.ts +27 -0
- package/dist/data/task-query-keys.d.ts.map +1 -0
- package/dist/data/task-query-keys.js +26 -0
- package/dist/data/task-query-keys.js.map +1 -0
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data.cjs +16 -0
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +6 -2
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +16 -0
- package/dist/data.js.map +1 -1
- package/dist/hooks/use-hotkey.cjs +6 -1
- package/dist/hooks/use-hotkey.cjs.map +1 -1
- package/dist/hooks/use-hotkey.d.ts.map +1 -1
- package/dist/hooks/use-hotkey.js +6 -1
- package/dist/hooks/use-hotkey.js.map +1 -1
- package/dist/hooks/use-task-run.cjs +7 -4
- package/dist/hooks/use-task-run.cjs.map +1 -1
- package/dist/hooks/use-task-run.d.ts +12 -0
- package/dist/hooks/use-task-run.d.ts.map +1 -1
- package/dist/hooks/use-task-run.js +7 -4
- package/dist/hooks/use-task-run.js.map +1 -1
- package/dist/icons/index.d.ts +1 -0
- package/dist/icons/index.d.ts.map +1 -1
- package/dist/icons/registry.cjs +692 -0
- package/dist/icons/registry.cjs.map +1 -0
- package/dist/icons/registry.d.ts +21 -0
- package/dist/icons/registry.d.ts.map +1 -0
- package/dist/icons/registry.js +692 -0
- package/dist/icons/registry.js.map +1 -0
- package/dist/icons.cjs +3 -0
- package/dist/icons.cjs.map +1 -1
- package/dist/icons.js +4 -1
- package/dist/icons.js.map +1 -1
- package/dist/index.cjs +47 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +49 -2
- package/dist/index.js.map +1 -1
- package/dist/layout/AppShell.cjs +92 -56
- package/dist/layout/AppShell.cjs.map +1 -1
- package/dist/layout/AppShell.d.ts +49 -1
- package/dist/layout/AppShell.d.ts.map +1 -1
- package/dist/layout/AppShell.js +92 -56
- package/dist/layout/AppShell.js.map +1 -1
- package/dist/layout/AppShell.nav.cjs +144 -19
- package/dist/layout/AppShell.nav.cjs.map +1 -1
- package/dist/layout/AppShell.nav.d.ts +6 -1
- package/dist/layout/AppShell.nav.d.ts.map +1 -1
- package/dist/layout/AppShell.nav.js +144 -19
- package/dist/layout/AppShell.nav.js.map +1 -1
- package/dist/layout/SplitPane.cjs +23 -7
- package/dist/layout/SplitPane.cjs.map +1 -1
- package/dist/layout/SplitPane.d.ts +3 -1
- package/dist/layout/SplitPane.d.ts.map +1 -1
- package/dist/layout/SplitPane.js +23 -7
- package/dist/layout/SplitPane.js.map +1 -1
- package/dist/lib/format.cjs +86 -4
- package/dist/lib/format.cjs.map +1 -1
- package/dist/lib/format.d.ts +69 -0
- package/dist/lib/format.d.ts.map +1 -1
- package/dist/lib/format.js +86 -4
- package/dist/lib/format.js.map +1 -1
- package/dist/lib/path-tree.cjs +69 -0
- package/dist/lib/path-tree.cjs.map +1 -0
- package/dist/lib/path-tree.d.ts +54 -0
- package/dist/lib/path-tree.d.ts.map +1 -0
- package/dist/lib/path-tree.js +69 -0
- package/dist/lib/path-tree.js.map +1 -0
- package/dist/monaco.d.ts +1 -0
- package/dist/monaco.d.ts.map +1 -1
- package/dist/overlay/DropdownMenuSubmenu.cjs +13 -7
- package/dist/overlay/DropdownMenuSubmenu.cjs.map +1 -1
- package/dist/overlay/DropdownMenuSubmenu.d.ts.map +1 -1
- package/dist/overlay/DropdownMenuSubmenu.js +13 -7
- package/dist/overlay/DropdownMenuSubmenu.js.map +1 -1
- package/dist/overlay/Tour.cjs +173 -0
- package/dist/overlay/Tour.cjs.map +1 -0
- package/dist/overlay/Tour.d.ts +61 -0
- package/dist/overlay/Tour.d.ts.map +1 -0
- package/dist/overlay/Tour.js +173 -0
- package/dist/overlay/Tour.js.map +1 -0
- package/dist/overlay/TourCard.cjs +108 -0
- package/dist/overlay/TourCard.cjs.map +1 -0
- package/dist/overlay/TourCard.d.ts +23 -0
- package/dist/overlay/TourCard.d.ts.map +1 -0
- package/dist/overlay/TourCard.js +108 -0
- package/dist/overlay/TourCard.js.map +1 -0
- package/dist/overlay/TourProvider.cjs +160 -0
- package/dist/overlay/TourProvider.cjs.map +1 -0
- package/dist/overlay/TourProvider.d.ts +31 -0
- package/dist/overlay/TourProvider.d.ts.map +1 -0
- package/dist/overlay/TourProvider.js +160 -0
- package/dist/overlay/TourProvider.js.map +1 -0
- package/dist/overlay/TourSpotlight.cjs +47 -0
- package/dist/overlay/TourSpotlight.cjs.map +1 -0
- package/dist/overlay/TourSpotlight.d.ts +12 -0
- package/dist/overlay/TourSpotlight.d.ts.map +1 -0
- package/dist/overlay/TourSpotlight.js +47 -0
- package/dist/overlay/TourSpotlight.js.map +1 -0
- package/dist/overlay/modalStack.cjs +18 -4
- package/dist/overlay/modalStack.cjs.map +1 -1
- package/dist/overlay/modalStack.d.ts +10 -2
- package/dist/overlay/modalStack.d.ts.map +1 -1
- package/dist/overlay/modalStack.js +19 -5
- package/dist/overlay/modalStack.js.map +1 -1
- package/dist/overlay/tour-anchor.cjs +114 -0
- package/dist/overlay/tour-anchor.cjs.map +1 -0
- package/dist/overlay/tour-anchor.d.ts +30 -0
- package/dist/overlay/tour-anchor.d.ts.map +1 -0
- package/dist/overlay/tour-anchor.js +114 -0
- package/dist/overlay/tour-anchor.js.map +1 -0
- package/dist/overlay/tour-context.cjs +12 -0
- package/dist/overlay/tour-context.cjs.map +1 -0
- package/dist/overlay/tour-context.d.ts +40 -0
- package/dist/overlay/tour-context.d.ts.map +1 -0
- package/dist/overlay/tour-context.js +12 -0
- package/dist/overlay/tour-context.js.map +1 -0
- package/dist/overlay/tour-geometry.cjs +65 -0
- package/dist/overlay/tour-geometry.cjs.map +1 -0
- package/dist/overlay/tour-geometry.d.ts +47 -0
- package/dist/overlay/tour-geometry.d.ts.map +1 -0
- package/dist/overlay/tour-geometry.js +65 -0
- package/dist/overlay/tour-geometry.js.map +1 -0
- package/dist/overlay/tour-model.cjs +79 -0
- package/dist/overlay/tour-model.cjs.map +1 -0
- package/dist/overlay/tour-model.d.ts +29 -0
- package/dist/overlay/tour-model.d.ts.map +1 -0
- package/dist/overlay/tour-model.js +79 -0
- package/dist/overlay/tour-model.js.map +1 -0
- package/dist/overlay/tour-progress.cjs +54 -0
- package/dist/overlay/tour-progress.cjs.map +1 -0
- package/dist/overlay/tour-progress.d.ts +40 -0
- package/dist/overlay/tour-progress.d.ts.map +1 -0
- package/dist/overlay/tour-progress.js +54 -0
- package/dist/overlay/tour-progress.js.map +1 -0
- package/dist/overlay/tour-types.d.ts +144 -0
- package/dist/overlay/tour-types.d.ts.map +1 -0
- package/dist/overlay/use-tour-anchor.cjs +43 -0
- package/dist/overlay/use-tour-anchor.cjs.map +1 -0
- package/dist/overlay/use-tour-anchor.d.ts +23 -0
- package/dist/overlay/use-tour-anchor.d.ts.map +1 -0
- package/dist/overlay/use-tour-anchor.js +43 -0
- package/dist/overlay/use-tour-anchor.js.map +1 -0
- package/dist/overlay/use-tour-rect.cjs +33 -0
- package/dist/overlay/use-tour-rect.cjs.map +1 -0
- package/dist/overlay/use-tour-rect.d.ts +12 -0
- package/dist/overlay/use-tour-rect.d.ts.map +1 -0
- package/dist/overlay/use-tour-rect.js +33 -0
- package/dist/overlay/use-tour-rect.js.map +1 -0
- package/dist/overlay/use-tour-step.cjs +66 -0
- package/dist/overlay/use-tour-step.cjs.map +1 -0
- package/dist/overlay/use-tour-step.d.ts +45 -0
- package/dist/overlay/use-tour-step.d.ts.map +1 -0
- package/dist/overlay/use-tour-step.js +66 -0
- package/dist/overlay/use-tour-step.js.map +1 -0
- package/dist/overlay/zIndex.cjs +8 -0
- package/dist/overlay/zIndex.cjs.map +1 -1
- package/dist/overlay/zIndex.d.ts +8 -0
- package/dist/overlay/zIndex.d.ts.map +1 -1
- package/dist/overlay/zIndex.js +8 -0
- package/dist/overlay/zIndex.js.map +1 -1
- package/dist/rpc/CommandOutput.cjs +8 -0
- package/dist/rpc/CommandOutput.cjs.map +1 -1
- package/dist/rpc/CommandOutput.d.ts +4 -1
- package/dist/rpc/CommandOutput.d.ts.map +1 -1
- package/dist/rpc/CommandOutput.js +8 -0
- package/dist/rpc/CommandOutput.js.map +1 -1
- package/dist/rpc/EntityExplorerApp.cjs +10 -16
- package/dist/rpc/EntityExplorerApp.cjs.map +1 -1
- package/dist/rpc/EntityExplorerApp.d.ts.map +1 -1
- package/dist/rpc/EntityExplorerApp.js +10 -16
- package/dist/rpc/EntityExplorerApp.js.map +1 -1
- package/dist/rpc/OperationActionBar.cjs +1 -1
- package/dist/rpc/OperationActionBar.cjs.map +1 -1
- package/dist/rpc/OperationActionBar.js +1 -1
- package/dist/rpc/OperationActionBar.js.map +1 -1
- package/dist/rpc/OperationCatalog.cjs +83 -7
- package/dist/rpc/OperationCatalog.cjs.map +1 -1
- package/dist/rpc/OperationCatalog.d.ts.map +1 -1
- package/dist/rpc/OperationCatalog.js +84 -8
- package/dist/rpc/OperationCatalog.js.map +1 -1
- package/dist/rpc/OperationResultView.cjs +2 -0
- package/dist/rpc/OperationResultView.cjs.map +1 -1
- package/dist/rpc/OperationResultView.d.ts +6 -0
- package/dist/rpc/OperationResultView.d.ts.map +1 -1
- package/dist/rpc/OperationResultView.js +2 -0
- package/dist/rpc/OperationResultView.js.map +1 -1
- package/dist/rpc/SchemaActionForm.cjs +2 -21
- package/dist/rpc/SchemaActionForm.cjs.map +1 -1
- package/dist/rpc/SchemaActionForm.d.ts.map +1 -1
- package/dist/rpc/SchemaActionForm.js +3 -22
- package/dist/rpc/SchemaActionForm.js.map +1 -1
- package/dist/rpc/apiClient.cjs +16 -2
- package/dist/rpc/apiClient.cjs.map +1 -1
- package/dist/rpc/apiClient.d.ts.map +1 -1
- package/dist/rpc/apiClient.js +16 -2
- package/dist/rpc/apiClient.js.map +1 -1
- package/dist/rpc/formMetadata.cjs +89 -49
- package/dist/rpc/formMetadata.cjs.map +1 -1
- package/dist/rpc/formMetadata.d.ts +14 -6
- package/dist/rpc/formMetadata.d.ts.map +1 -1
- package/dist/rpc/formMetadata.js +87 -47
- package/dist/rpc/formMetadata.js.map +1 -1
- package/dist/rpc/operationFilterSearch.cjs +23 -0
- package/dist/rpc/operationFilterSearch.cjs.map +1 -0
- package/dist/rpc/operationFilterSearch.d.ts +22 -0
- package/dist/rpc/operationFilterSearch.d.ts.map +1 -0
- package/dist/rpc/operationFilterSearch.js +23 -0
- package/dist/rpc/operationFilterSearch.js.map +1 -0
- package/dist/rpc/operationLookupFetcher.cjs +28 -0
- package/dist/rpc/operationLookupFetcher.cjs.map +1 -0
- package/dist/rpc/operationLookupFetcher.d.ts +17 -0
- package/dist/rpc/operationLookupFetcher.d.ts.map +1 -0
- package/dist/rpc/operationLookupFetcher.js +28 -0
- package/dist/rpc/operationLookupFetcher.js.map +1 -0
- package/dist/rpc/surfaceNav.cjs +77 -0
- package/dist/rpc/surfaceNav.cjs.map +1 -0
- package/dist/rpc/surfaceNav.d.ts +19 -0
- package/dist/rpc/surfaceNav.d.ts.map +1 -0
- package/dist/rpc/surfaceNav.js +77 -0
- package/dist/rpc/surfaceNav.js.map +1 -0
- package/dist/rpc/types.cjs.map +1 -1
- package/dist/rpc/types.d.ts +12 -1
- package/dist/rpc/types.d.ts.map +1 -1
- package/dist/rpc/types.js.map +1 -1
- package/dist/rpc.cjs +2 -0
- package/dist/rpc.cjs.map +1 -1
- package/dist/rpc.d.ts +1 -0
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +2 -0
- package/dist/rpc.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/utils.cjs +8 -0
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.ts +2 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +10 -2
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
- package/dist/data/ai/RuntimeBar.cjs.map +0 -1
- package/dist/data/ai/RuntimeBar.d.ts.map +0 -1
- package/dist/data/ai/RuntimeBar.js.map +0 -1
- package/dist/data/ai/RuntimeBar.model.cjs.map +0 -1
- package/dist/data/ai/RuntimeBar.model.d.ts.map +0 -1
- package/dist/data/ai/RuntimeBar.model.js.map +0 -1
- package/dist/data/ai/RuntimeBarCombo.cjs.map +0 -1
- package/dist/data/ai/RuntimeBarCombo.d.ts.map +0 -1
- package/dist/data/ai/RuntimeBarCombo.js.map +0 -1
- package/dist/data/ai/model-capabilities.cjs.map +0 -1
- package/dist/data/ai/model-capabilities.d.ts.map +0 -1
- package/dist/data/ai/model-capabilities.js.map +0 -1
- package/dist/data/ai/runtime-mode.cjs.map +0 -1
- package/dist/data/ai/runtime-mode.d.ts.map +0 -1
- package/dist/data/ai/runtime-mode.js.map +0 -1
- /package/dist/data/{ai → runtime}/RuntimeBar.model.cjs +0 -0
- /package/dist/data/{ai → runtime}/RuntimeBar.model.js +0 -0
- /package/dist/data/{ai → runtime}/model-capabilities.cjs +0 -0
- /package/dist/data/{ai → runtime}/model-capabilities.d.ts +0 -0
- /package/dist/data/{ai → runtime}/model-capabilities.js +0 -0
package/dist/data.js
CHANGED
|
@@ -7,6 +7,8 @@ import { CodeBlock } from "./data/CodeBlock.js";
|
|
|
7
7
|
import { CodeDiff } from "./data/CodeDiff.js";
|
|
8
8
|
import { computeLineDiff, parseUnifiedDiff } from "./data/code-diff.js";
|
|
9
9
|
import { inferColumns } from "./data/data-table-utils.js";
|
|
10
|
+
import { parseMultiFilterValue, serializeMultiFilterValue, splitCommaValues, updateFilterSelection } from "./data/data-table-filter-values.js";
|
|
11
|
+
import { DATA_TABLE_FILTER_LOOKUP_LIMIT, serverColumnsToDataTableColumns, serverFiltersToFilterBar } from "./data/data-table-server-filters.js";
|
|
10
12
|
import { DataTable } from "./data/DataTable.js";
|
|
11
13
|
import { groupRecords, isGroupCollapsedByDefault } from "./data/DataTable.grouping.js";
|
|
12
14
|
import { StatStrip } from "./data/StatStrip.js";
|
|
@@ -14,6 +16,7 @@ import { EntityCell } from "./data/cells/EntityCell.js";
|
|
|
14
16
|
import { Timestamp } from "./data/cells/Timestamp.js";
|
|
15
17
|
import { chooseTimestampFormat, formatDateTimeRelative, formatRelativeTime, formatTimestamp, modeToFormat, parseTimestamp } from "./data/cells/timestamp-format.js";
|
|
16
18
|
import { TagActionsProvider, TagList } from "./data/cells/TagList.js";
|
|
19
|
+
import { CellFilterActions } from "./data/cells/CellFilterActions.js";
|
|
17
20
|
import { normalizeTags, splitTagToken, tagActionsFromRecord, tagFilterTokens, useTagActions, useTagActionsValue } from "./data/cells/tag-utils.js";
|
|
18
21
|
import { StatusDot } from "./data/cells/StatusDot.js";
|
|
19
22
|
import { STATUS_TOKEN_GROUPS, normalizeStatus } from "./data/cells/status-mapping.js";
|
|
@@ -69,6 +72,7 @@ import { allGroupsTerminal, isTerminalStatus } from "./data/TaskSnapshot.js";
|
|
|
69
72
|
import { bucketTasks, logLevelColor, taskSegments, taskStatusBg, taskStatusColor, taskStatusIcon } from "./data/task-status.js";
|
|
70
73
|
import { TaskProgress } from "./data/TaskProgress.js";
|
|
71
74
|
import { TaskManager } from "./data/TaskManager.js";
|
|
75
|
+
import { taskQueryKeys } from "./data/task-query-keys.js";
|
|
72
76
|
import { TaskManagerButton } from "./data/TaskManagerButton.js";
|
|
73
77
|
import { PromptDialog } from "./data/PromptDialog.js";
|
|
74
78
|
import { PromptBanner } from "./data/PromptBanner.js";
|
|
@@ -425,6 +429,7 @@ import { annotateRoutePaths, findNodeByRoutePath, slugify } from "./data/test-ru
|
|
|
425
429
|
import { applyFixtureFrontmatterRaw, applyFixtureFrontmatterState, fixtureFrontmatterState, parseFixtureFrontmatter } from "./data/FixtureEditor/fixture-frontmatter.js";
|
|
426
430
|
import { cacheQueryKeys, createCacheClient } from "./data/cache-browser/api.js";
|
|
427
431
|
import { changeIconAliases, getChangeIcon } from "./icons/changeIconAliases.js";
|
|
432
|
+
import { clickyIconProvider, iconsByConsumerName } from "./icons/registry.js";
|
|
428
433
|
import { createChecklistMarkdown, createFenceMarkdown, fixtureFenceKind, fixtureFenceSchemaAliases, fixtureFenceSnippetInfo, parseFixtureYaml, resolveFixtureFenceSchema, schemaKeys, stringifyFixtureYaml } from "./data/FixtureEditor/fixture-blocks.js";
|
|
429
434
|
import { cycleFilterState, decodeFilterState, emptyTestFilters, encodeFilterState, filterStateToRecord, matchesFilterState, recordToFilterState } from "./data/test-runner/filterState.js";
|
|
430
435
|
import { formatGitCommitDateHeader } from "./data/git/git-dates.js";
|
|
@@ -442,9 +447,11 @@ export {
|
|
|
442
447
|
CacheStatsOverview,
|
|
443
448
|
CacheTree,
|
|
444
449
|
CacheValue,
|
|
450
|
+
CellFilterActions,
|
|
445
451
|
CodeBlock,
|
|
446
452
|
CodeDiff,
|
|
447
453
|
CopyBadge,
|
|
454
|
+
DATA_TABLE_FILTER_LOOKUP_LIMIT,
|
|
448
455
|
DataTable,
|
|
449
456
|
DiagnosticsDetailPanel,
|
|
450
457
|
DiagnosticsTree,
|
|
@@ -1132,6 +1139,7 @@ export {
|
|
|
1132
1139
|
changeIconAliases,
|
|
1133
1140
|
chooseTimestampFormat,
|
|
1134
1141
|
clickyFormatForMarkdownPreview,
|
|
1142
|
+
clickyIconProvider,
|
|
1135
1143
|
collapseSingleChildChains,
|
|
1136
1144
|
collectFrameworks,
|
|
1137
1145
|
compactStackPath,
|
|
@@ -1177,6 +1185,7 @@ export {
|
|
|
1177
1185
|
hasHoverMeta,
|
|
1178
1186
|
hasPending,
|
|
1179
1187
|
humanizeName,
|
|
1188
|
+
iconsByConsumerName,
|
|
1180
1189
|
inferColumns,
|
|
1181
1190
|
isApplicationStackFrame,
|
|
1182
1191
|
isGroupCollapsedByDefault,
|
|
@@ -1200,6 +1209,7 @@ export {
|
|
|
1200
1209
|
parseInlineJsonContextValue,
|
|
1201
1210
|
parseJavaStackTrace,
|
|
1202
1211
|
parseJvmThreadDump,
|
|
1212
|
+
parseMultiFilterValue,
|
|
1203
1213
|
parseServerTiming,
|
|
1204
1214
|
parseStackDump,
|
|
1205
1215
|
parseTimestamp,
|
|
@@ -1214,11 +1224,15 @@ export {
|
|
|
1214
1224
|
resolveSeries,
|
|
1215
1225
|
schemaKeys,
|
|
1216
1226
|
segment,
|
|
1227
|
+
serializeMultiFilterValue,
|
|
1217
1228
|
seriesStats,
|
|
1229
|
+
serverColumnsToDataTableColumns,
|
|
1230
|
+
serverFiltersToFilterBar,
|
|
1218
1231
|
serverTimingCounterSummary,
|
|
1219
1232
|
serverTimingMetricLabel,
|
|
1220
1233
|
setFallbackIconProvider,
|
|
1221
1234
|
slugify,
|
|
1235
|
+
splitCommaValues,
|
|
1222
1236
|
splitTagToken,
|
|
1223
1237
|
statusIconFor,
|
|
1224
1238
|
statusToneFor,
|
|
@@ -1227,12 +1241,14 @@ export {
|
|
|
1227
1241
|
sumNonTaskTests,
|
|
1228
1242
|
tagActionsFromRecord,
|
|
1229
1243
|
tagFilterTokens,
|
|
1244
|
+
taskQueryKeys,
|
|
1230
1245
|
taskSegments,
|
|
1231
1246
|
taskStatusBg,
|
|
1232
1247
|
taskStatusColor,
|
|
1233
1248
|
taskStatusIcon,
|
|
1234
1249
|
testStatus,
|
|
1235
1250
|
totalDuration,
|
|
1251
|
+
updateFilterSelection,
|
|
1236
1252
|
usePrompts,
|
|
1237
1253
|
useTagActions,
|
|
1238
1254
|
useTagActionsValue,
|
package/dist/data.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"data.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -48,12 +48,17 @@ function isFormElement(target) {
|
|
|
48
48
|
if (target.isContentEditable) return true;
|
|
49
49
|
return ["INPUT", "TEXTAREA", "SELECT"].includes(target.tagName);
|
|
50
50
|
}
|
|
51
|
+
function eventOrigin(event) {
|
|
52
|
+
var _a;
|
|
53
|
+
return ((_a = event.composedPath) == null ? void 0 : _a.call(event)[0]) ?? event.target;
|
|
54
|
+
}
|
|
51
55
|
function onKeyDown(event) {
|
|
52
56
|
if (event.defaultPrevented || event.isComposing) return;
|
|
57
|
+
const origin = eventOrigin(event);
|
|
53
58
|
let winner;
|
|
54
59
|
for (const registration of registrations) {
|
|
55
60
|
if (!matches(event, registration.combo)) continue;
|
|
56
|
-
if (!registration.enableOnFormElements && isFormElement(
|
|
61
|
+
if (!registration.enableOnFormElements && isFormElement(origin)) continue;
|
|
57
62
|
if (!winner || registration.priority >= winner.priority) winner = registration;
|
|
58
63
|
}
|
|
59
64
|
if (!winner) return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-hotkey.cjs","sources":["../../src/hooks/use-hotkey.ts"],"sourcesContent":["import { useEffect, useId, useRef } from \"react\";\n\n// A process-wide registry of global keyboard shortcuts, modeled on the escape\n// layer in ../overlay/modalStack. Bindings mount independently (no shared\n// provider), so the registry lives at module scope. Exactly ONE binding wins a\n// given key combo — the highest `priority`, breaking ties toward the most\n// recently mounted. Without that discipline every mounted component that binds\n// the same combo fires on one keypress, which is how two ⌘K search fields end\n// up racing to focus themselves.\n//\n// The listener is attached to `document`, matching modalStack, so hotkeys and\n// escape layers agree on event target and ordering.\n\ntype Registration = {\n id: string;\n combo: ParsedHotkey;\n priority: number;\n enableOnFormElements: boolean;\n run: (event: KeyboardEvent) => void;\n};\n\nconst registrations: Registration[] = [];\nlet boundDocument: Document | null = null;\n\nexport type ParsedHotkey = {\n /** Bare key, lower-cased (e.g. \"k\"). */\n key: string;\n /** Requires cmd on macOS / ctrl elsewhere. */\n mod: boolean;\n shift: boolean;\n alt: boolean;\n};\n\nfunction isMacPlatform(): boolean {\n if (typeof navigator === \"undefined\") return false;\n return /mac|iphone|ipad|ipod/i.test(navigator.platform || navigator.userAgent);\n}\n\n/**\n * Parses a combo string such as `\"mod+k\"` or `\"mod+shift+p\"`. `mod` means ⌘ on\n * macOS and Ctrl elsewhere. The last segment is the key; order is irrelevant.\n */\nexport function parseHotkey(combo: string): ParsedHotkey {\n const parts = combo\n .split(\"+\")\n .map((part) => part.trim().toLowerCase())\n .filter(Boolean);\n const key = parts[parts.length - 1];\n if (!key) throw new Error(`useHotkey: empty combo \"${combo}\"`);\n return {\n key,\n mod: parts.includes(\"mod\") || parts.includes(\"cmd\") || parts.includes(\"ctrl\"),\n shift: parts.includes(\"shift\"),\n alt: parts.includes(\"alt\") || parts.includes(\"option\"),\n };\n}\n\n/**\n * Renders a combo for display — `\"mod+k\"` becomes `\"⌘K\"` on macOS and `\"Ctrl+K\"`\n * elsewhere. Deriving the label from the combo (rather than hand-authoring the\n * label and reverse-engineering the key from it) keeps the two in sync.\n */\nexport function formatHotkey(combo: string, platform?: \"mac\" | \"other\"): string {\n const parsed = parseHotkey(combo);\n const mac = platform ? platform === \"mac\" : isMacPlatform();\n const key = parsed.key.length === 1 ? parsed.key.toUpperCase() : titleCase(parsed.key);\n if (mac) {\n return `${parsed.mod ? \"⌘\" : \"\"}${parsed.alt ? \"⌥\" : \"\"}${parsed.shift ? \"⇧\" : \"\"}${key}`;\n }\n const segments = [\n ...(parsed.mod ? [\"Ctrl\"] : []),\n ...(parsed.alt ? [\"Alt\"] : []),\n ...(parsed.shift ? [\"Shift\"] : []),\n key,\n ];\n return segments.join(\"+\");\n}\n\nfunction titleCase(value: string): string {\n return value.charAt(0).toUpperCase() + value.slice(1);\n}\n\nfunction matches(event: KeyboardEvent, combo: ParsedHotkey): boolean {\n if (event.key.toLowerCase() !== combo.key) return false;\n if (combo.mod !== (event.metaKey || event.ctrlKey)) return false;\n if (combo.shift !== event.shiftKey) return false;\n if (combo.alt !== event.altKey) return false;\n return true;\n}\n\nfunction isFormElement(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n if (target.isContentEditable) return true;\n return [\"INPUT\", \"TEXTAREA\", \"SELECT\"].includes(target.tagName);\n}\n\nfunction onKeyDown(event: KeyboardEvent) {\n if (event.defaultPrevented || event.isComposing) return;\n\n // Highest priority wins; ties go to the most recently registered, so a\n // transient surface layered over the page takes precedence over the chrome.\n let winner: Registration | undefined;\n for (const registration of registrations) {\n if (!matches(event, registration.combo)) continue;\n if (!registration.enableOnFormElements && isFormElement(
|
|
1
|
+
{"version":3,"file":"use-hotkey.cjs","sources":["../../src/hooks/use-hotkey.ts"],"sourcesContent":["import { useEffect, useId, useRef } from \"react\";\n\n// A process-wide registry of global keyboard shortcuts, modeled on the escape\n// layer in ../overlay/modalStack. Bindings mount independently (no shared\n// provider), so the registry lives at module scope. Exactly ONE binding wins a\n// given key combo — the highest `priority`, breaking ties toward the most\n// recently mounted. Without that discipline every mounted component that binds\n// the same combo fires on one keypress, which is how two ⌘K search fields end\n// up racing to focus themselves.\n//\n// The listener is attached to `document`, matching modalStack, so hotkeys and\n// escape layers agree on event target and ordering.\n\ntype Registration = {\n id: string;\n combo: ParsedHotkey;\n priority: number;\n enableOnFormElements: boolean;\n run: (event: KeyboardEvent) => void;\n};\n\nconst registrations: Registration[] = [];\nlet boundDocument: Document | null = null;\n\nexport type ParsedHotkey = {\n /** Bare key, lower-cased (e.g. \"k\"). */\n key: string;\n /** Requires cmd on macOS / ctrl elsewhere. */\n mod: boolean;\n shift: boolean;\n alt: boolean;\n};\n\nfunction isMacPlatform(): boolean {\n if (typeof navigator === \"undefined\") return false;\n return /mac|iphone|ipad|ipod/i.test(navigator.platform || navigator.userAgent);\n}\n\n/**\n * Parses a combo string such as `\"mod+k\"` or `\"mod+shift+p\"`. `mod` means ⌘ on\n * macOS and Ctrl elsewhere. The last segment is the key; order is irrelevant.\n */\nexport function parseHotkey(combo: string): ParsedHotkey {\n const parts = combo\n .split(\"+\")\n .map((part) => part.trim().toLowerCase())\n .filter(Boolean);\n const key = parts[parts.length - 1];\n if (!key) throw new Error(`useHotkey: empty combo \"${combo}\"`);\n return {\n key,\n mod: parts.includes(\"mod\") || parts.includes(\"cmd\") || parts.includes(\"ctrl\"),\n shift: parts.includes(\"shift\"),\n alt: parts.includes(\"alt\") || parts.includes(\"option\"),\n };\n}\n\n/**\n * Renders a combo for display — `\"mod+k\"` becomes `\"⌘K\"` on macOS and `\"Ctrl+K\"`\n * elsewhere. Deriving the label from the combo (rather than hand-authoring the\n * label and reverse-engineering the key from it) keeps the two in sync.\n */\nexport function formatHotkey(combo: string, platform?: \"mac\" | \"other\"): string {\n const parsed = parseHotkey(combo);\n const mac = platform ? platform === \"mac\" : isMacPlatform();\n const key = parsed.key.length === 1 ? parsed.key.toUpperCase() : titleCase(parsed.key);\n if (mac) {\n return `${parsed.mod ? \"⌘\" : \"\"}${parsed.alt ? \"⌥\" : \"\"}${parsed.shift ? \"⇧\" : \"\"}${key}`;\n }\n const segments = [\n ...(parsed.mod ? [\"Ctrl\"] : []),\n ...(parsed.alt ? [\"Alt\"] : []),\n ...(parsed.shift ? [\"Shift\"] : []),\n key,\n ];\n return segments.join(\"+\");\n}\n\nfunction titleCase(value: string): string {\n return value.charAt(0).toUpperCase() + value.slice(1);\n}\n\nfunction matches(event: KeyboardEvent, combo: ParsedHotkey): boolean {\n if (event.key.toLowerCase() !== combo.key) return false;\n if (combo.mod !== (event.metaKey || event.ctrlKey)) return false;\n if (combo.shift !== event.shiftKey) return false;\n if (combo.alt !== event.altKey) return false;\n return true;\n}\n\nfunction isFormElement(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n if (target.isContentEditable) return true;\n return [\"INPUT\", \"TEXTAREA\", \"SELECT\"].includes(target.tagName);\n}\n\n// Across a shadow boundary `event.target` is retargeted to the shadow HOST, so a\n// key typed into an input inside a shadow root looks like a bare keypress on a\n// <div> and would fire hotkeys that must not fire while typing. The composed\n// path's first entry is the true origin.\nfunction eventOrigin(event: KeyboardEvent): EventTarget | null {\n return event.composedPath?.()[0] ?? event.target;\n}\n\nfunction onKeyDown(event: KeyboardEvent) {\n if (event.defaultPrevented || event.isComposing) return;\n\n // Highest priority wins; ties go to the most recently registered, so a\n // transient surface layered over the page takes precedence over the chrome.\n const origin = eventOrigin(event);\n let winner: Registration | undefined;\n for (const registration of registrations) {\n if (!matches(event, registration.combo)) continue;\n if (!registration.enableOnFormElements && isFormElement(origin)) continue;\n if (!winner || registration.priority >= winner.priority) winner = registration;\n }\n if (!winner) return;\n\n event.preventDefault();\n winner.run(event);\n}\n\nfunction ensureListener() {\n if (boundDocument || typeof document === \"undefined\") return;\n boundDocument = document;\n boundDocument.addEventListener(\"keydown\", onKeyDown);\n}\n\nfunction unregister(id: string) {\n const index = registrations.findIndex((entry) => entry.id === id);\n if (index !== -1) registrations.splice(index, 1);\n\n if (registrations.length === 0 && boundDocument) {\n boundDocument.removeEventListener(\"keydown\", onKeyDown);\n boundDocument = null;\n }\n}\n\nexport type UseHotkeyOptions = {\n /** Register the binding. Defaults to `true`. */\n enabled?: boolean | undefined;\n /**\n * Ordering among bindings for the same combo. Higher wins; ties break toward\n * the most recently mounted. Defaults to `0`.\n */\n priority?: number | undefined;\n /**\n * Fire while focus sits in an input, textarea, select, or contenteditable.\n * Defaults to `true` for combos carrying a modifier (⌘K should work while\n * typing) and `false` for bare keys (which would swallow ordinary typing).\n */\n enableOnFormElements?: boolean | undefined;\n};\n\n/**\n * Binds a global keyboard shortcut for as long as the component is mounted and\n * `enabled`. Pass `null`/`undefined` as the combo to bind nothing. Only the\n * winning registration for a combo runs, so overlapping bindings cannot both\n * fire on a single keypress.\n */\nexport function useHotkey(\n combo: string | null | undefined,\n handler: (event: KeyboardEvent) => void,\n options: UseHotkeyOptions = {},\n): void {\n const id = useId();\n const handlerRef = useRef(handler);\n handlerRef.current = handler;\n\n const { enabled = true, priority = 0, enableOnFormElements } = options;\n\n useEffect(() => {\n if (!combo || !enabled) return;\n const parsed = parseHotkey(combo);\n\n ensureListener();\n registrations.push({\n id,\n combo: parsed,\n priority,\n enableOnFormElements: enableOnFormElements ?? parsed.mod,\n run: (event) => handlerRef.current(event),\n });\n\n return () => unregister(id);\n }, [combo, enabled, priority, enableOnFormElements, id]);\n}\n"],"names":["useId","useRef","useEffect"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-hotkey.d.ts","sourceRoot":"","sources":["../../src/hooks/use-hotkey.ts"],"names":[],"mappings":"AAwBA,MAAM,MAAM,YAAY,GAAG;IACzB,wCAAwC;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,8CAA8C;IAC9C,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;CACd,CAAC;AAOF;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAavD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,CAc9E;
|
|
1
|
+
{"version":3,"file":"use-hotkey.d.ts","sourceRoot":"","sources":["../../src/hooks/use-hotkey.ts"],"names":[],"mappings":"AAwBA,MAAM,MAAM,YAAY,GAAG;IACzB,wCAAwC;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,8CAA8C;IAC9C,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;CACd,CAAC;AAOF;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAavD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,CAc9E;AA8DD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,gDAAgD;IAChD,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC5C,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAChC,OAAO,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,EACvC,OAAO,GAAE,gBAAqB,GAC7B,IAAI,CAsBN"}
|
package/dist/hooks/use-hotkey.js
CHANGED
|
@@ -46,12 +46,17 @@ function isFormElement(target) {
|
|
|
46
46
|
if (target.isContentEditable) return true;
|
|
47
47
|
return ["INPUT", "TEXTAREA", "SELECT"].includes(target.tagName);
|
|
48
48
|
}
|
|
49
|
+
function eventOrigin(event) {
|
|
50
|
+
var _a;
|
|
51
|
+
return ((_a = event.composedPath) == null ? void 0 : _a.call(event)[0]) ?? event.target;
|
|
52
|
+
}
|
|
49
53
|
function onKeyDown(event) {
|
|
50
54
|
if (event.defaultPrevented || event.isComposing) return;
|
|
55
|
+
const origin = eventOrigin(event);
|
|
51
56
|
let winner;
|
|
52
57
|
for (const registration of registrations) {
|
|
53
58
|
if (!matches(event, registration.combo)) continue;
|
|
54
|
-
if (!registration.enableOnFormElements && isFormElement(
|
|
59
|
+
if (!registration.enableOnFormElements && isFormElement(origin)) continue;
|
|
55
60
|
if (!winner || registration.priority >= winner.priority) winner = registration;
|
|
56
61
|
}
|
|
57
62
|
if (!winner) return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-hotkey.js","sources":["../../src/hooks/use-hotkey.ts"],"sourcesContent":["import { useEffect, useId, useRef } from \"react\";\n\n// A process-wide registry of global keyboard shortcuts, modeled on the escape\n// layer in ../overlay/modalStack. Bindings mount independently (no shared\n// provider), so the registry lives at module scope. Exactly ONE binding wins a\n// given key combo — the highest `priority`, breaking ties toward the most\n// recently mounted. Without that discipline every mounted component that binds\n// the same combo fires on one keypress, which is how two ⌘K search fields end\n// up racing to focus themselves.\n//\n// The listener is attached to `document`, matching modalStack, so hotkeys and\n// escape layers agree on event target and ordering.\n\ntype Registration = {\n id: string;\n combo: ParsedHotkey;\n priority: number;\n enableOnFormElements: boolean;\n run: (event: KeyboardEvent) => void;\n};\n\nconst registrations: Registration[] = [];\nlet boundDocument: Document | null = null;\n\nexport type ParsedHotkey = {\n /** Bare key, lower-cased (e.g. \"k\"). */\n key: string;\n /** Requires cmd on macOS / ctrl elsewhere. */\n mod: boolean;\n shift: boolean;\n alt: boolean;\n};\n\nfunction isMacPlatform(): boolean {\n if (typeof navigator === \"undefined\") return false;\n return /mac|iphone|ipad|ipod/i.test(navigator.platform || navigator.userAgent);\n}\n\n/**\n * Parses a combo string such as `\"mod+k\"` or `\"mod+shift+p\"`. `mod` means ⌘ on\n * macOS and Ctrl elsewhere. The last segment is the key; order is irrelevant.\n */\nexport function parseHotkey(combo: string): ParsedHotkey {\n const parts = combo\n .split(\"+\")\n .map((part) => part.trim().toLowerCase())\n .filter(Boolean);\n const key = parts[parts.length - 1];\n if (!key) throw new Error(`useHotkey: empty combo \"${combo}\"`);\n return {\n key,\n mod: parts.includes(\"mod\") || parts.includes(\"cmd\") || parts.includes(\"ctrl\"),\n shift: parts.includes(\"shift\"),\n alt: parts.includes(\"alt\") || parts.includes(\"option\"),\n };\n}\n\n/**\n * Renders a combo for display — `\"mod+k\"` becomes `\"⌘K\"` on macOS and `\"Ctrl+K\"`\n * elsewhere. Deriving the label from the combo (rather than hand-authoring the\n * label and reverse-engineering the key from it) keeps the two in sync.\n */\nexport function formatHotkey(combo: string, platform?: \"mac\" | \"other\"): string {\n const parsed = parseHotkey(combo);\n const mac = platform ? platform === \"mac\" : isMacPlatform();\n const key = parsed.key.length === 1 ? parsed.key.toUpperCase() : titleCase(parsed.key);\n if (mac) {\n return `${parsed.mod ? \"⌘\" : \"\"}${parsed.alt ? \"⌥\" : \"\"}${parsed.shift ? \"⇧\" : \"\"}${key}`;\n }\n const segments = [\n ...(parsed.mod ? [\"Ctrl\"] : []),\n ...(parsed.alt ? [\"Alt\"] : []),\n ...(parsed.shift ? [\"Shift\"] : []),\n key,\n ];\n return segments.join(\"+\");\n}\n\nfunction titleCase(value: string): string {\n return value.charAt(0).toUpperCase() + value.slice(1);\n}\n\nfunction matches(event: KeyboardEvent, combo: ParsedHotkey): boolean {\n if (event.key.toLowerCase() !== combo.key) return false;\n if (combo.mod !== (event.metaKey || event.ctrlKey)) return false;\n if (combo.shift !== event.shiftKey) return false;\n if (combo.alt !== event.altKey) return false;\n return true;\n}\n\nfunction isFormElement(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n if (target.isContentEditable) return true;\n return [\"INPUT\", \"TEXTAREA\", \"SELECT\"].includes(target.tagName);\n}\n\nfunction onKeyDown(event: KeyboardEvent) {\n if (event.defaultPrevented || event.isComposing) return;\n\n // Highest priority wins; ties go to the most recently registered, so a\n // transient surface layered over the page takes precedence over the chrome.\n let winner: Registration | undefined;\n for (const registration of registrations) {\n if (!matches(event, registration.combo)) continue;\n if (!registration.enableOnFormElements && isFormElement(
|
|
1
|
+
{"version":3,"file":"use-hotkey.js","sources":["../../src/hooks/use-hotkey.ts"],"sourcesContent":["import { useEffect, useId, useRef } from \"react\";\n\n// A process-wide registry of global keyboard shortcuts, modeled on the escape\n// layer in ../overlay/modalStack. Bindings mount independently (no shared\n// provider), so the registry lives at module scope. Exactly ONE binding wins a\n// given key combo — the highest `priority`, breaking ties toward the most\n// recently mounted. Without that discipline every mounted component that binds\n// the same combo fires on one keypress, which is how two ⌘K search fields end\n// up racing to focus themselves.\n//\n// The listener is attached to `document`, matching modalStack, so hotkeys and\n// escape layers agree on event target and ordering.\n\ntype Registration = {\n id: string;\n combo: ParsedHotkey;\n priority: number;\n enableOnFormElements: boolean;\n run: (event: KeyboardEvent) => void;\n};\n\nconst registrations: Registration[] = [];\nlet boundDocument: Document | null = null;\n\nexport type ParsedHotkey = {\n /** Bare key, lower-cased (e.g. \"k\"). */\n key: string;\n /** Requires cmd on macOS / ctrl elsewhere. */\n mod: boolean;\n shift: boolean;\n alt: boolean;\n};\n\nfunction isMacPlatform(): boolean {\n if (typeof navigator === \"undefined\") return false;\n return /mac|iphone|ipad|ipod/i.test(navigator.platform || navigator.userAgent);\n}\n\n/**\n * Parses a combo string such as `\"mod+k\"` or `\"mod+shift+p\"`. `mod` means ⌘ on\n * macOS and Ctrl elsewhere. The last segment is the key; order is irrelevant.\n */\nexport function parseHotkey(combo: string): ParsedHotkey {\n const parts = combo\n .split(\"+\")\n .map((part) => part.trim().toLowerCase())\n .filter(Boolean);\n const key = parts[parts.length - 1];\n if (!key) throw new Error(`useHotkey: empty combo \"${combo}\"`);\n return {\n key,\n mod: parts.includes(\"mod\") || parts.includes(\"cmd\") || parts.includes(\"ctrl\"),\n shift: parts.includes(\"shift\"),\n alt: parts.includes(\"alt\") || parts.includes(\"option\"),\n };\n}\n\n/**\n * Renders a combo for display — `\"mod+k\"` becomes `\"⌘K\"` on macOS and `\"Ctrl+K\"`\n * elsewhere. Deriving the label from the combo (rather than hand-authoring the\n * label and reverse-engineering the key from it) keeps the two in sync.\n */\nexport function formatHotkey(combo: string, platform?: \"mac\" | \"other\"): string {\n const parsed = parseHotkey(combo);\n const mac = platform ? platform === \"mac\" : isMacPlatform();\n const key = parsed.key.length === 1 ? parsed.key.toUpperCase() : titleCase(parsed.key);\n if (mac) {\n return `${parsed.mod ? \"⌘\" : \"\"}${parsed.alt ? \"⌥\" : \"\"}${parsed.shift ? \"⇧\" : \"\"}${key}`;\n }\n const segments = [\n ...(parsed.mod ? [\"Ctrl\"] : []),\n ...(parsed.alt ? [\"Alt\"] : []),\n ...(parsed.shift ? [\"Shift\"] : []),\n key,\n ];\n return segments.join(\"+\");\n}\n\nfunction titleCase(value: string): string {\n return value.charAt(0).toUpperCase() + value.slice(1);\n}\n\nfunction matches(event: KeyboardEvent, combo: ParsedHotkey): boolean {\n if (event.key.toLowerCase() !== combo.key) return false;\n if (combo.mod !== (event.metaKey || event.ctrlKey)) return false;\n if (combo.shift !== event.shiftKey) return false;\n if (combo.alt !== event.altKey) return false;\n return true;\n}\n\nfunction isFormElement(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n if (target.isContentEditable) return true;\n return [\"INPUT\", \"TEXTAREA\", \"SELECT\"].includes(target.tagName);\n}\n\n// Across a shadow boundary `event.target` is retargeted to the shadow HOST, so a\n// key typed into an input inside a shadow root looks like a bare keypress on a\n// <div> and would fire hotkeys that must not fire while typing. The composed\n// path's first entry is the true origin.\nfunction eventOrigin(event: KeyboardEvent): EventTarget | null {\n return event.composedPath?.()[0] ?? event.target;\n}\n\nfunction onKeyDown(event: KeyboardEvent) {\n if (event.defaultPrevented || event.isComposing) return;\n\n // Highest priority wins; ties go to the most recently registered, so a\n // transient surface layered over the page takes precedence over the chrome.\n const origin = eventOrigin(event);\n let winner: Registration | undefined;\n for (const registration of registrations) {\n if (!matches(event, registration.combo)) continue;\n if (!registration.enableOnFormElements && isFormElement(origin)) continue;\n if (!winner || registration.priority >= winner.priority) winner = registration;\n }\n if (!winner) return;\n\n event.preventDefault();\n winner.run(event);\n}\n\nfunction ensureListener() {\n if (boundDocument || typeof document === \"undefined\") return;\n boundDocument = document;\n boundDocument.addEventListener(\"keydown\", onKeyDown);\n}\n\nfunction unregister(id: string) {\n const index = registrations.findIndex((entry) => entry.id === id);\n if (index !== -1) registrations.splice(index, 1);\n\n if (registrations.length === 0 && boundDocument) {\n boundDocument.removeEventListener(\"keydown\", onKeyDown);\n boundDocument = null;\n }\n}\n\nexport type UseHotkeyOptions = {\n /** Register the binding. Defaults to `true`. */\n enabled?: boolean | undefined;\n /**\n * Ordering among bindings for the same combo. Higher wins; ties break toward\n * the most recently mounted. Defaults to `0`.\n */\n priority?: number | undefined;\n /**\n * Fire while focus sits in an input, textarea, select, or contenteditable.\n * Defaults to `true` for combos carrying a modifier (⌘K should work while\n * typing) and `false` for bare keys (which would swallow ordinary typing).\n */\n enableOnFormElements?: boolean | undefined;\n};\n\n/**\n * Binds a global keyboard shortcut for as long as the component is mounted and\n * `enabled`. Pass `null`/`undefined` as the combo to bind nothing. Only the\n * winning registration for a combo runs, so overlapping bindings cannot both\n * fire on a single keypress.\n */\nexport function useHotkey(\n combo: string | null | undefined,\n handler: (event: KeyboardEvent) => void,\n options: UseHotkeyOptions = {},\n): void {\n const id = useId();\n const handlerRef = useRef(handler);\n handlerRef.current = handler;\n\n const { enabled = true, priority = 0, enableOnFormElements } = options;\n\n useEffect(() => {\n if (!combo || !enabled) return;\n const parsed = parseHotkey(combo);\n\n ensureListener();\n registrations.push({\n id,\n combo: parsed,\n priority,\n enableOnFormElements: enableOnFormElements ?? parsed.mod,\n run: (event) => handlerRef.current(event),\n });\n\n return () => unregister(id);\n }, [combo, enabled, priority, enableOnFormElements, id]);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const react = require("react");
|
|
4
4
|
const TaskSnapshot = require("../data/TaskSnapshot.cjs");
|
|
5
|
+
const taskQueryKeys = require("../data/task-query-keys.cjs");
|
|
5
6
|
const DEFAULT_BASE = "/api/v1";
|
|
6
7
|
const DEFAULT_POLL_MS = 2e3;
|
|
7
8
|
function streamUrl(base, query) {
|
|
@@ -122,7 +123,7 @@ function useTaskRuns(options = {}) {
|
|
|
122
123
|
pollMs = DEFAULT_POLL_MS,
|
|
123
124
|
forcePoll = false
|
|
124
125
|
} = options;
|
|
125
|
-
const [
|
|
126
|
+
const [received, setReceived] = react.useState({ key: null, runs: [] });
|
|
126
127
|
const [status, setStatus] = react.useState("idle");
|
|
127
128
|
react.useEffect(() => {
|
|
128
129
|
if (!enabled) return;
|
|
@@ -131,6 +132,8 @@ function useTaskRuns(options = {}) {
|
|
|
131
132
|
if (statusFilter) params.set("status", statusFilter);
|
|
132
133
|
for (const [k, v] of Object.entries(labels ?? {})) params.append("label", `${k}=${v}`);
|
|
133
134
|
const query = params.toString();
|
|
135
|
+
const requestKey = taskQueryKeys.taskQueryKeys.runs({ basePath, kind, status: statusFilter, labels });
|
|
136
|
+
const receive = (next) => setReceived({ key: requestKey, runs: next });
|
|
134
137
|
if (forcePoll || !hasEventSource()) {
|
|
135
138
|
let stopped = false;
|
|
136
139
|
let timer;
|
|
@@ -140,7 +143,7 @@ function useTaskRuns(options = {}) {
|
|
|
140
143
|
headers: { Accept: "application/json" }
|
|
141
144
|
});
|
|
142
145
|
if (res.ok) {
|
|
143
|
-
|
|
146
|
+
receive(await res.json());
|
|
144
147
|
setStatus("polling");
|
|
145
148
|
}
|
|
146
149
|
} catch {
|
|
@@ -158,14 +161,14 @@ function useTaskRuns(options = {}) {
|
|
|
158
161
|
setStatus("connected");
|
|
159
162
|
es.addEventListener("runs", (e) => {
|
|
160
163
|
try {
|
|
161
|
-
|
|
164
|
+
receive(JSON.parse(e.data));
|
|
162
165
|
} catch {
|
|
163
166
|
}
|
|
164
167
|
});
|
|
165
168
|
es.onerror = () => setStatus("connection lost — retrying");
|
|
166
169
|
return () => es.close();
|
|
167
170
|
}, [kind, statusFilter, JSON.stringify(labels ?? {}), basePath, enabled, pollMs, forcePoll]);
|
|
168
|
-
return { runs, status };
|
|
171
|
+
return { runs: received.runs, status, runsKey: received.key };
|
|
169
172
|
}
|
|
170
173
|
exports.useTaskRun = useTaskRun;
|
|
171
174
|
exports.useTaskRuns = useTaskRuns;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-task-run.cjs","sources":["../../src/hooks/use-task-run.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport {\n allGroupsTerminal,\n type TaskRunMeta,\n type TaskSnapshot,\n} from \"../data/TaskSnapshot\";\n\n// use-task-run / use-task-runs are the generic clicky-ui task clients. They are\n// SSE-first: they subscribe to clicky's SSEHandler (event: task / event: done)\n// and fall back to polling the JSON endpoints only when EventSource is\n// unavailable. They speak only TaskSnapshot / TaskRunMeta — no app concepts.\n\nexport interface TaskTransportOptions {\n /** Base path of the clicky task API, e.g. \"/api/v1\". */\n basePath?: string | undefined;\n /** Disable the subscription entirely (e.g. before an id is known). */\n enabled?: boolean | undefined;\n /** Poll interval (ms) for the fallback / runs listing. */\n pollMs?: number | undefined;\n /** Force the polling transport even when EventSource exists (mainly tests). */\n forcePoll?: boolean | undefined;\n}\n\nconst DEFAULT_BASE = \"/api/v1\";\nconst DEFAULT_POLL_MS = 2_000;\n\nfunction streamUrl(base: string, query: string): string {\n return `${base}/tasks/stream${query ? `?${query}` : \"\"}`;\n}\n\nfunction hasEventSource(): boolean {\n return typeof globalThis !== \"undefined\" && typeof globalThis.EventSource !== \"undefined\";\n}\n\nexport interface UseTaskRunResult {\n snapshots: TaskSnapshot[];\n status: string;\n isComplete: boolean;\n}\n\nexport interface UseTaskRunOptions extends TaskTransportOptions {\n /** Stable run id to follow (drill-down). Mutually exclusive with kind. */\n id?: string | undefined;\n /** Follow every run of a kind. */\n kind?: string | undefined;\n}\n\n// useTaskRun follows one run (by id) or a kind, SSE-first. It accumulates the\n// latest snapshot per task/group id and reports completion once every group is\n// terminal.\nexport function useTaskRun(options: UseTaskRunOptions = {}): UseTaskRunResult {\n const {\n id,\n kind,\n basePath = DEFAULT_BASE,\n enabled = true,\n pollMs = DEFAULT_POLL_MS,\n forcePoll = false,\n } = options;\n\n const [byId, setById] = useState<Record<string, TaskSnapshot>>({});\n const [status, setStatus] = useState(\"idle\");\n const [isComplete, setIsComplete] = useState(false);\n // Reset accumulator whenever the subscription target changes.\n const targetKey = `${id ?? \"\"}|${kind ?? \"\"}|${enabled}`;\n const prevKey = useRef(targetKey);\n if (prevKey.current !== targetKey) {\n prevKey.current = targetKey;\n }\n\n useEffect(() => {\n if (!enabled || (!id && !kind)) {\n return;\n }\n setById({});\n setIsComplete(false);\n\n const params = new URLSearchParams();\n if (id) params.set(\"tasks\", id);\n if (kind) params.set(\"kind\", kind);\n const query = params.toString();\n\n const merge = (incoming: TaskSnapshot[]) => {\n setById((prev) => {\n const next = { ...prev };\n for (const snap of incoming) next[snap.id] = { ...next[snap.id], ...snap };\n return next;\n });\n };\n\n const mergeOutput = (delta: {\n id: string;\n stream: \"stdout\" | \"stderr\";\n data: string;\n reset?: boolean;\n truncated?: boolean;\n }) => {\n setById((prev) => {\n const snapshot = prev[delta.id];\n if (!snapshot) return prev;\n const value = delta.reset ? delta.data : `${snapshot[delta.stream] ?? \"\"}${delta.data}`;\n const truncatedField = delta.stream === \"stdout\" ? \"stdoutTruncated\" : \"stderrTruncated\";\n return {\n ...prev,\n [delta.id]: {\n ...snapshot,\n [delta.stream]: value,\n [truncatedField]: delta.truncated ?? snapshot[truncatedField],\n },\n };\n });\n };\n\n // Polling fallback transport.\n if (forcePoll || !hasEventSource()) {\n let stopped = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const tick = async () => {\n try {\n const res = await fetch(`${basePath}/tasks/${encodeURIComponent(id ?? \"\")}`, {\n headers: { Accept: \"application/json\" },\n });\n if (res.ok) {\n const snaps = (await res.json()) as TaskSnapshot[];\n merge(snaps);\n setStatus(\"polling\");\n if (allGroupsTerminal(snaps)) {\n setIsComplete(true);\n return; // stop polling\n }\n }\n } catch {\n setStatus(\"connection lost — retrying\");\n }\n if (!stopped) timer = setTimeout(tick, pollMs);\n };\n void tick();\n return () => {\n stopped = true;\n if (timer) clearTimeout(timer);\n };\n }\n\n // SSE transport (default).\n const es = new EventSource(streamUrl(basePath, query));\n setStatus(\"connected\");\n es.addEventListener(\"task\", (e) => {\n try {\n merge([JSON.parse((e as MessageEvent).data) as TaskSnapshot]);\n } catch {\n /* ignore malformed frame */\n }\n });\n es.addEventListener(\"output\", (e) => {\n try {\n mergeOutput(JSON.parse((e as MessageEvent).data) as Parameters<typeof mergeOutput>[0]);\n } catch {\n /* ignore malformed frame */\n }\n });\n es.addEventListener(\"done\", () => {\n setStatus(\"complete\");\n setIsComplete(true);\n es.close();\n });\n es.onerror = () => setStatus(\"connection lost — retrying\");\n return () => es.close();\n }, [id, kind, basePath, enabled, pollMs, forcePoll]);\n\n return { snapshots: Object.values(byId), status, isComplete };\n}\n\nexport interface UseTaskRunsOptions extends TaskTransportOptions {\n kind?: string | undefined;\n status?: string | undefined;\n /** Label equality filters (k=v). */\n labels?: Record<string, string> | undefined;\n}\n\nexport interface UseTaskRunsResult {\n runs: TaskRunMeta[];\n status: string;\n}\n\n// useTaskRuns lists all runs (TaskRunMeta) for the manager view. It is SSE-first:\n// it subscribes to clicky's runs stream (event: runs carrying the full listing)\n// and falls back to polling the JSON runs endpoint only when EventSource is\n// unavailable or forced off. The listing has no completion terminal of its own —\n// a manager view stays subscribed to observe new and changing runs.\nexport function useTaskRuns(options: UseTaskRunsOptions = {}): UseTaskRunsResult {\n const {\n kind,\n status: statusFilter,\n labels,\n basePath = DEFAULT_BASE,\n enabled = true,\n pollMs = DEFAULT_POLL_MS,\n forcePoll = false,\n } = options;\n\n const [runs, setRuns] = useState<TaskRunMeta[]>([]);\n const [status, setStatus] = useState(\"idle\");\n\n useEffect(() => {\n if (!enabled) return;\n\n const params = new URLSearchParams();\n if (kind) params.set(\"kind\", kind);\n if (statusFilter) params.set(\"status\", statusFilter);\n for (const [k, v] of Object.entries(labels ?? {})) params.append(\"label\", `${k}=${v}`);\n const query = params.toString();\n\n // Polling fallback transport.\n if (forcePoll || !hasEventSource()) {\n let stopped = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const tick = async () => {\n try {\n const res = await fetch(`${basePath}/tasks${query ? `?${query}` : \"\"}`, {\n headers: { Accept: \"application/json\" },\n });\n if (res.ok) {\n setRuns((await res.json()) as TaskRunMeta[]);\n setStatus(\"polling\");\n }\n } catch {\n setStatus(\"connection lost — retrying\");\n }\n if (!stopped) timer = setTimeout(tick, pollMs);\n };\n void tick();\n return () => {\n stopped = true;\n if (timer) clearTimeout(timer);\n };\n }\n\n // SSE transport (default).\n const es = new EventSource(`${basePath}/tasks/runs/stream${query ? `?${query}` : \"\"}`);\n setStatus(\"connected\");\n es.addEventListener(\"runs\", (e) => {\n try {\n setRuns(JSON.parse((e as MessageEvent).data) as TaskRunMeta[]);\n } catch {\n /* ignore malformed frame */\n }\n });\n es.onerror = () => setStatus(\"connection lost — retrying\");\n return () => es.close();\n }, [kind, statusFilter, JSON.stringify(labels ?? {}), basePath, enabled, pollMs, forcePoll]);\n\n return { runs, status };\n}\n"],"names":["useState","useRef","useEffect","allGroupsTerminal"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-task-run.cjs","sources":["../../src/hooks/use-task-run.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport {\n allGroupsTerminal,\n type TaskRunMeta,\n type TaskSnapshot,\n} from \"../data/TaskSnapshot\";\nimport { taskQueryKeys } from \"../data/task-query-keys\";\n\n// use-task-run / use-task-runs are the generic clicky-ui task clients. They are\n// SSE-first: they subscribe to clicky's SSEHandler (event: task / event: done)\n// and fall back to polling the JSON endpoints only when EventSource is\n// unavailable. They speak only TaskSnapshot / TaskRunMeta — no app concepts.\n\nexport interface TaskTransportOptions {\n /** Base path of the clicky task API, e.g. \"/api/v1\". */\n basePath?: string | undefined;\n /** Disable the subscription entirely (e.g. before an id is known). */\n enabled?: boolean | undefined;\n /** Poll interval (ms) for the fallback / runs listing. */\n pollMs?: number | undefined;\n /** Force the polling transport even when EventSource exists (mainly tests). */\n forcePoll?: boolean | undefined;\n}\n\nconst DEFAULT_BASE = \"/api/v1\";\nconst DEFAULT_POLL_MS = 2_000;\n\nfunction streamUrl(base: string, query: string): string {\n return `${base}/tasks/stream${query ? `?${query}` : \"\"}`;\n}\n\nfunction hasEventSource(): boolean {\n return typeof globalThis !== \"undefined\" && typeof globalThis.EventSource !== \"undefined\";\n}\n\nexport interface UseTaskRunResult {\n snapshots: TaskSnapshot[];\n status: string;\n isComplete: boolean;\n}\n\nexport interface UseTaskRunOptions extends TaskTransportOptions {\n /** Stable run id to follow (drill-down). Mutually exclusive with kind. */\n id?: string | undefined;\n /** Follow every run of a kind. */\n kind?: string | undefined;\n}\n\n// useTaskRun follows one run (by id) or a kind, SSE-first. It accumulates the\n// latest snapshot per task/group id and reports completion once every group is\n// terminal.\nexport function useTaskRun(options: UseTaskRunOptions = {}): UseTaskRunResult {\n const {\n id,\n kind,\n basePath = DEFAULT_BASE,\n enabled = true,\n pollMs = DEFAULT_POLL_MS,\n forcePoll = false,\n } = options;\n\n const [byId, setById] = useState<Record<string, TaskSnapshot>>({});\n const [status, setStatus] = useState(\"idle\");\n const [isComplete, setIsComplete] = useState(false);\n // Reset accumulator whenever the subscription target changes.\n const targetKey = `${id ?? \"\"}|${kind ?? \"\"}|${enabled}`;\n const prevKey = useRef(targetKey);\n if (prevKey.current !== targetKey) {\n prevKey.current = targetKey;\n }\n\n useEffect(() => {\n if (!enabled || (!id && !kind)) {\n return;\n }\n setById({});\n setIsComplete(false);\n\n const params = new URLSearchParams();\n if (id) params.set(\"tasks\", id);\n if (kind) params.set(\"kind\", kind);\n const query = params.toString();\n\n const merge = (incoming: TaskSnapshot[]) => {\n setById((prev) => {\n const next = { ...prev };\n for (const snap of incoming) next[snap.id] = { ...next[snap.id], ...snap };\n return next;\n });\n };\n\n const mergeOutput = (delta: {\n id: string;\n stream: \"stdout\" | \"stderr\";\n data: string;\n reset?: boolean;\n truncated?: boolean;\n }) => {\n setById((prev) => {\n const snapshot = prev[delta.id];\n if (!snapshot) return prev;\n const value = delta.reset ? delta.data : `${snapshot[delta.stream] ?? \"\"}${delta.data}`;\n const truncatedField = delta.stream === \"stdout\" ? \"stdoutTruncated\" : \"stderrTruncated\";\n return {\n ...prev,\n [delta.id]: {\n ...snapshot,\n [delta.stream]: value,\n [truncatedField]: delta.truncated ?? snapshot[truncatedField],\n },\n };\n });\n };\n\n // Polling fallback transport.\n if (forcePoll || !hasEventSource()) {\n let stopped = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const tick = async () => {\n try {\n const res = await fetch(`${basePath}/tasks/${encodeURIComponent(id ?? \"\")}`, {\n headers: { Accept: \"application/json\" },\n });\n if (res.ok) {\n const snaps = (await res.json()) as TaskSnapshot[];\n merge(snaps);\n setStatus(\"polling\");\n if (allGroupsTerminal(snaps)) {\n setIsComplete(true);\n return; // stop polling\n }\n }\n } catch {\n setStatus(\"connection lost — retrying\");\n }\n if (!stopped) timer = setTimeout(tick, pollMs);\n };\n void tick();\n return () => {\n stopped = true;\n if (timer) clearTimeout(timer);\n };\n }\n\n // SSE transport (default).\n const es = new EventSource(streamUrl(basePath, query));\n setStatus(\"connected\");\n es.addEventListener(\"task\", (e) => {\n try {\n merge([JSON.parse((e as MessageEvent).data) as TaskSnapshot]);\n } catch {\n /* ignore malformed frame */\n }\n });\n es.addEventListener(\"output\", (e) => {\n try {\n mergeOutput(JSON.parse((e as MessageEvent).data) as Parameters<typeof mergeOutput>[0]);\n } catch {\n /* ignore malformed frame */\n }\n });\n es.addEventListener(\"done\", () => {\n setStatus(\"complete\");\n setIsComplete(true);\n es.close();\n });\n es.onerror = () => setStatus(\"connection lost — retrying\");\n return () => es.close();\n }, [id, kind, basePath, enabled, pollMs, forcePoll]);\n\n return { snapshots: Object.values(byId), status, isComplete };\n}\n\nexport interface UseTaskRunsOptions extends TaskTransportOptions {\n kind?: string | undefined;\n status?: string | undefined;\n /** Label equality filters (k=v). */\n labels?: Record<string, string> | undefined;\n}\n\n/** The identity of the listing request that produced a given `runs` array. */\nexport type TaskRunsKey = ReturnType<typeof taskQueryKeys.runs>;\n\nexport interface UseTaskRunsResult {\n runs: TaskRunMeta[];\n status: string;\n /**\n * Query key of the request that actually produced `runs`, or null before the\n * first frame arrives. Changing `kind`/`status`/`labels` re-subscribes but\n * keeps the previous listing on screen until the new transport delivers, so\n * this key lags `taskQueryKeys.runs(options)` during that window. A consumer\n * mirroring `runs` into a cache must compare the two and skip the write while\n * they differ, or it publishes rows that do not match the requested filters.\n */\n runsKey: TaskRunsKey | null;\n}\n\n// useTaskRuns lists all runs (TaskRunMeta) for the manager view. It is SSE-first:\n// it subscribes to clicky's runs stream (event: runs carrying the full listing)\n// and falls back to polling the JSON runs endpoint only when EventSource is\n// unavailable or forced off. The listing has no completion terminal of its own —\n// a manager view stays subscribed to observe new and changing runs.\nexport function useTaskRuns(options: UseTaskRunsOptions = {}): UseTaskRunsResult {\n const {\n kind,\n status: statusFilter,\n labels,\n basePath = DEFAULT_BASE,\n enabled = true,\n pollMs = DEFAULT_POLL_MS,\n forcePoll = false,\n } = options;\n\n // Runs are stored together with the key of the request that delivered them, so\n // a stale listing can never be mistaken for the current filters' result.\n const [received, setReceived] = useState<{\n key: TaskRunsKey | null;\n runs: TaskRunMeta[];\n }>({ key: null, runs: [] });\n const [status, setStatus] = useState(\"idle\");\n\n useEffect(() => {\n if (!enabled) return;\n\n const params = new URLSearchParams();\n if (kind) params.set(\"kind\", kind);\n if (statusFilter) params.set(\"status\", statusFilter);\n for (const [k, v] of Object.entries(labels ?? {})) params.append(\"label\", `${k}=${v}`);\n const query = params.toString();\n const requestKey = taskQueryKeys.runs({ basePath, kind, status: statusFilter, labels });\n const receive = (next: TaskRunMeta[]) => setReceived({ key: requestKey, runs: next });\n\n // Polling fallback transport.\n if (forcePoll || !hasEventSource()) {\n let stopped = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const tick = async () => {\n try {\n const res = await fetch(`${basePath}/tasks${query ? `?${query}` : \"\"}`, {\n headers: { Accept: \"application/json\" },\n });\n if (res.ok) {\n receive((await res.json()) as TaskRunMeta[]);\n setStatus(\"polling\");\n }\n } catch {\n setStatus(\"connection lost — retrying\");\n }\n if (!stopped) timer = setTimeout(tick, pollMs);\n };\n void tick();\n return () => {\n stopped = true;\n if (timer) clearTimeout(timer);\n };\n }\n\n // SSE transport (default).\n const es = new EventSource(`${basePath}/tasks/runs/stream${query ? `?${query}` : \"\"}`);\n setStatus(\"connected\");\n es.addEventListener(\"runs\", (e) => {\n try {\n receive(JSON.parse((e as MessageEvent).data) as TaskRunMeta[]);\n } catch {\n /* ignore malformed frame */\n }\n });\n es.onerror = () => setStatus(\"connection lost — retrying\");\n return () => es.close();\n }, [kind, statusFilter, JSON.stringify(labels ?? {}), basePath, enabled, pollMs, forcePoll]);\n\n return { runs: received.runs, status, runsKey: received.key };\n}\n"],"names":["useState","useRef","useEffect","allGroupsTerminal","taskQueryKeys"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { TaskRunMeta, TaskSnapshot } from '../data/TaskSnapshot';
|
|
2
|
+
import { taskQueryKeys } from '../data/task-query-keys';
|
|
2
3
|
export interface TaskTransportOptions {
|
|
3
4
|
/** Base path of the clicky task API, e.g. "/api/v1". */
|
|
4
5
|
basePath?: string | undefined;
|
|
@@ -27,9 +28,20 @@ export interface UseTaskRunsOptions extends TaskTransportOptions {
|
|
|
27
28
|
/** Label equality filters (k=v). */
|
|
28
29
|
labels?: Record<string, string> | undefined;
|
|
29
30
|
}
|
|
31
|
+
/** The identity of the listing request that produced a given `runs` array. */
|
|
32
|
+
export type TaskRunsKey = ReturnType<typeof taskQueryKeys.runs>;
|
|
30
33
|
export interface UseTaskRunsResult {
|
|
31
34
|
runs: TaskRunMeta[];
|
|
32
35
|
status: string;
|
|
36
|
+
/**
|
|
37
|
+
* Query key of the request that actually produced `runs`, or null before the
|
|
38
|
+
* first frame arrives. Changing `kind`/`status`/`labels` re-subscribes but
|
|
39
|
+
* keeps the previous listing on screen until the new transport delivers, so
|
|
40
|
+
* this key lags `taskQueryKeys.runs(options)` during that window. A consumer
|
|
41
|
+
* mirroring `runs` into a cache must compare the two and skip the write while
|
|
42
|
+
* they differ, or it publishes rows that do not match the requested filters.
|
|
43
|
+
*/
|
|
44
|
+
runsKey: TaskRunsKey | null;
|
|
33
45
|
}
|
|
34
46
|
export declare function useTaskRuns(options?: UseTaskRunsOptions): UseTaskRunsResult;
|
|
35
47
|
//# sourceMappingURL=use-task-run.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-task-run.d.ts","sourceRoot":"","sources":["../../src/hooks/use-task-run.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,YAAY,EAClB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"use-task-run.d.ts","sourceRoot":"","sources":["../../src/hooks/use-task-run.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,YAAY,EAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAOxD,MAAM,WAAW,oBAAoB;IACnC,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,sEAAsE;IACtE,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,+EAA+E;IAC/E,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACjC;AAaD,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,iBAAkB,SAAQ,oBAAoB;IAC7D,0EAA0E;IAC1E,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AAKD,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,gBAAgB,CAwH5E;AAED,MAAM,WAAW,kBAAmB,SAAQ,oBAAoB;IAC9D,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;CAC7C;AAED,8EAA8E;AAC9E,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;AAEhE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,WAAW,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;;OAOG;IACH,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;CAC7B;AAOD,wBAAgB,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,iBAAiB,CAsE/E"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useState, useRef, useEffect } from "react";
|
|
2
2
|
import { allGroupsTerminal } from "../data/TaskSnapshot.js";
|
|
3
|
+
import { taskQueryKeys } from "../data/task-query-keys.js";
|
|
3
4
|
const DEFAULT_BASE = "/api/v1";
|
|
4
5
|
const DEFAULT_POLL_MS = 2e3;
|
|
5
6
|
function streamUrl(base, query) {
|
|
@@ -120,7 +121,7 @@ function useTaskRuns(options = {}) {
|
|
|
120
121
|
pollMs = DEFAULT_POLL_MS,
|
|
121
122
|
forcePoll = false
|
|
122
123
|
} = options;
|
|
123
|
-
const [
|
|
124
|
+
const [received, setReceived] = useState({ key: null, runs: [] });
|
|
124
125
|
const [status, setStatus] = useState("idle");
|
|
125
126
|
useEffect(() => {
|
|
126
127
|
if (!enabled) return;
|
|
@@ -129,6 +130,8 @@ function useTaskRuns(options = {}) {
|
|
|
129
130
|
if (statusFilter) params.set("status", statusFilter);
|
|
130
131
|
for (const [k, v] of Object.entries(labels ?? {})) params.append("label", `${k}=${v}`);
|
|
131
132
|
const query = params.toString();
|
|
133
|
+
const requestKey = taskQueryKeys.runs({ basePath, kind, status: statusFilter, labels });
|
|
134
|
+
const receive = (next) => setReceived({ key: requestKey, runs: next });
|
|
132
135
|
if (forcePoll || !hasEventSource()) {
|
|
133
136
|
let stopped = false;
|
|
134
137
|
let timer;
|
|
@@ -138,7 +141,7 @@ function useTaskRuns(options = {}) {
|
|
|
138
141
|
headers: { Accept: "application/json" }
|
|
139
142
|
});
|
|
140
143
|
if (res.ok) {
|
|
141
|
-
|
|
144
|
+
receive(await res.json());
|
|
142
145
|
setStatus("polling");
|
|
143
146
|
}
|
|
144
147
|
} catch {
|
|
@@ -156,14 +159,14 @@ function useTaskRuns(options = {}) {
|
|
|
156
159
|
setStatus("connected");
|
|
157
160
|
es.addEventListener("runs", (e) => {
|
|
158
161
|
try {
|
|
159
|
-
|
|
162
|
+
receive(JSON.parse(e.data));
|
|
160
163
|
} catch {
|
|
161
164
|
}
|
|
162
165
|
});
|
|
163
166
|
es.onerror = () => setStatus("connection lost — retrying");
|
|
164
167
|
return () => es.close();
|
|
165
168
|
}, [kind, statusFilter, JSON.stringify(labels ?? {}), basePath, enabled, pollMs, forcePoll]);
|
|
166
|
-
return { runs, status };
|
|
169
|
+
return { runs: received.runs, status, runsKey: received.key };
|
|
167
170
|
}
|
|
168
171
|
export {
|
|
169
172
|
useTaskRun,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-task-run.js","sources":["../../src/hooks/use-task-run.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport {\n allGroupsTerminal,\n type TaskRunMeta,\n type TaskSnapshot,\n} from \"../data/TaskSnapshot\";\n\n// use-task-run / use-task-runs are the generic clicky-ui task clients. They are\n// SSE-first: they subscribe to clicky's SSEHandler (event: task / event: done)\n// and fall back to polling the JSON endpoints only when EventSource is\n// unavailable. They speak only TaskSnapshot / TaskRunMeta — no app concepts.\n\nexport interface TaskTransportOptions {\n /** Base path of the clicky task API, e.g. \"/api/v1\". */\n basePath?: string | undefined;\n /** Disable the subscription entirely (e.g. before an id is known). */\n enabled?: boolean | undefined;\n /** Poll interval (ms) for the fallback / runs listing. */\n pollMs?: number | undefined;\n /** Force the polling transport even when EventSource exists (mainly tests). */\n forcePoll?: boolean | undefined;\n}\n\nconst DEFAULT_BASE = \"/api/v1\";\nconst DEFAULT_POLL_MS = 2_000;\n\nfunction streamUrl(base: string, query: string): string {\n return `${base}/tasks/stream${query ? `?${query}` : \"\"}`;\n}\n\nfunction hasEventSource(): boolean {\n return typeof globalThis !== \"undefined\" && typeof globalThis.EventSource !== \"undefined\";\n}\n\nexport interface UseTaskRunResult {\n snapshots: TaskSnapshot[];\n status: string;\n isComplete: boolean;\n}\n\nexport interface UseTaskRunOptions extends TaskTransportOptions {\n /** Stable run id to follow (drill-down). Mutually exclusive with kind. */\n id?: string | undefined;\n /** Follow every run of a kind. */\n kind?: string | undefined;\n}\n\n// useTaskRun follows one run (by id) or a kind, SSE-first. It accumulates the\n// latest snapshot per task/group id and reports completion once every group is\n// terminal.\nexport function useTaskRun(options: UseTaskRunOptions = {}): UseTaskRunResult {\n const {\n id,\n kind,\n basePath = DEFAULT_BASE,\n enabled = true,\n pollMs = DEFAULT_POLL_MS,\n forcePoll = false,\n } = options;\n\n const [byId, setById] = useState<Record<string, TaskSnapshot>>({});\n const [status, setStatus] = useState(\"idle\");\n const [isComplete, setIsComplete] = useState(false);\n // Reset accumulator whenever the subscription target changes.\n const targetKey = `${id ?? \"\"}|${kind ?? \"\"}|${enabled}`;\n const prevKey = useRef(targetKey);\n if (prevKey.current !== targetKey) {\n prevKey.current = targetKey;\n }\n\n useEffect(() => {\n if (!enabled || (!id && !kind)) {\n return;\n }\n setById({});\n setIsComplete(false);\n\n const params = new URLSearchParams();\n if (id) params.set(\"tasks\", id);\n if (kind) params.set(\"kind\", kind);\n const query = params.toString();\n\n const merge = (incoming: TaskSnapshot[]) => {\n setById((prev) => {\n const next = { ...prev };\n for (const snap of incoming) next[snap.id] = { ...next[snap.id], ...snap };\n return next;\n });\n };\n\n const mergeOutput = (delta: {\n id: string;\n stream: \"stdout\" | \"stderr\";\n data: string;\n reset?: boolean;\n truncated?: boolean;\n }) => {\n setById((prev) => {\n const snapshot = prev[delta.id];\n if (!snapshot) return prev;\n const value = delta.reset ? delta.data : `${snapshot[delta.stream] ?? \"\"}${delta.data}`;\n const truncatedField = delta.stream === \"stdout\" ? \"stdoutTruncated\" : \"stderrTruncated\";\n return {\n ...prev,\n [delta.id]: {\n ...snapshot,\n [delta.stream]: value,\n [truncatedField]: delta.truncated ?? snapshot[truncatedField],\n },\n };\n });\n };\n\n // Polling fallback transport.\n if (forcePoll || !hasEventSource()) {\n let stopped = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const tick = async () => {\n try {\n const res = await fetch(`${basePath}/tasks/${encodeURIComponent(id ?? \"\")}`, {\n headers: { Accept: \"application/json\" },\n });\n if (res.ok) {\n const snaps = (await res.json()) as TaskSnapshot[];\n merge(snaps);\n setStatus(\"polling\");\n if (allGroupsTerminal(snaps)) {\n setIsComplete(true);\n return; // stop polling\n }\n }\n } catch {\n setStatus(\"connection lost — retrying\");\n }\n if (!stopped) timer = setTimeout(tick, pollMs);\n };\n void tick();\n return () => {\n stopped = true;\n if (timer) clearTimeout(timer);\n };\n }\n\n // SSE transport (default).\n const es = new EventSource(streamUrl(basePath, query));\n setStatus(\"connected\");\n es.addEventListener(\"task\", (e) => {\n try {\n merge([JSON.parse((e as MessageEvent).data) as TaskSnapshot]);\n } catch {\n /* ignore malformed frame */\n }\n });\n es.addEventListener(\"output\", (e) => {\n try {\n mergeOutput(JSON.parse((e as MessageEvent).data) as Parameters<typeof mergeOutput>[0]);\n } catch {\n /* ignore malformed frame */\n }\n });\n es.addEventListener(\"done\", () => {\n setStatus(\"complete\");\n setIsComplete(true);\n es.close();\n });\n es.onerror = () => setStatus(\"connection lost — retrying\");\n return () => es.close();\n }, [id, kind, basePath, enabled, pollMs, forcePoll]);\n\n return { snapshots: Object.values(byId), status, isComplete };\n}\n\nexport interface UseTaskRunsOptions extends TaskTransportOptions {\n kind?: string | undefined;\n status?: string | undefined;\n /** Label equality filters (k=v). */\n labels?: Record<string, string> | undefined;\n}\n\nexport interface UseTaskRunsResult {\n runs: TaskRunMeta[];\n status: string;\n}\n\n// useTaskRuns lists all runs (TaskRunMeta) for the manager view. It is SSE-first:\n// it subscribes to clicky's runs stream (event: runs carrying the full listing)\n// and falls back to polling the JSON runs endpoint only when EventSource is\n// unavailable or forced off. The listing has no completion terminal of its own —\n// a manager view stays subscribed to observe new and changing runs.\nexport function useTaskRuns(options: UseTaskRunsOptions = {}): UseTaskRunsResult {\n const {\n kind,\n status: statusFilter,\n labels,\n basePath = DEFAULT_BASE,\n enabled = true,\n pollMs = DEFAULT_POLL_MS,\n forcePoll = false,\n } = options;\n\n const [runs, setRuns] = useState<TaskRunMeta[]>([]);\n const [status, setStatus] = useState(\"idle\");\n\n useEffect(() => {\n if (!enabled) return;\n\n const params = new URLSearchParams();\n if (kind) params.set(\"kind\", kind);\n if (statusFilter) params.set(\"status\", statusFilter);\n for (const [k, v] of Object.entries(labels ?? {})) params.append(\"label\", `${k}=${v}`);\n const query = params.toString();\n\n // Polling fallback transport.\n if (forcePoll || !hasEventSource()) {\n let stopped = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const tick = async () => {\n try {\n const res = await fetch(`${basePath}/tasks${query ? `?${query}` : \"\"}`, {\n headers: { Accept: \"application/json\" },\n });\n if (res.ok) {\n setRuns((await res.json()) as TaskRunMeta[]);\n setStatus(\"polling\");\n }\n } catch {\n setStatus(\"connection lost — retrying\");\n }\n if (!stopped) timer = setTimeout(tick, pollMs);\n };\n void tick();\n return () => {\n stopped = true;\n if (timer) clearTimeout(timer);\n };\n }\n\n // SSE transport (default).\n const es = new EventSource(`${basePath}/tasks/runs/stream${query ? `?${query}` : \"\"}`);\n setStatus(\"connected\");\n es.addEventListener(\"runs\", (e) => {\n try {\n setRuns(JSON.parse((e as MessageEvent).data) as TaskRunMeta[]);\n } catch {\n /* ignore malformed frame */\n }\n });\n es.onerror = () => setStatus(\"connection lost — retrying\");\n return () => es.close();\n }, [kind, statusFilter, JSON.stringify(labels ?? {}), basePath, enabled, pollMs, forcePoll]);\n\n return { runs, status };\n}\n"],"names":[],"mappings":";;AAuBA,MAAM,eAAe;AACrB,MAAM,kBAAkB;AAExB,SAAS,UAAU,MAAc,OAAuB;AACtD,SAAO,GAAG,IAAI,gBAAgB,QAAQ,IAAI,KAAK,KAAK,EAAE;AACxD;AAEA,SAAS,iBAA0B;AACjC,SAAO,OAAO,eAAe,eAAe,OAAO,WAAW,gBAAgB;AAChF;AAkBO,SAAS,WAAW,UAA6B,IAAsB;AAC5E,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,UAAU;AAAA,IACV,SAAS;AAAA,IACT,YAAY;AAAA,EAAA,IACV;AAEJ,QAAM,CAAC,MAAM,OAAO,IAAI,SAAuC,CAAA,CAAE;AACjE,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,MAAM;AAC3C,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAElD,QAAM,YAAY,GAAG,MAAM,EAAE,IAAI,QAAQ,EAAE,IAAI,OAAO;AACtD,QAAM,UAAU,OAAO,SAAS;AAChC,MAAI,QAAQ,YAAY,WAAW;AACjC,YAAQ,UAAU;AAAA,EACpB;AAEA,YAAU,MAAM;AACd,QAAI,CAAC,WAAY,CAAC,MAAM,CAAC,MAAO;AAC9B;AAAA,IACF;AACA,YAAQ,CAAA,CAAE;AACV,kBAAc,KAAK;AAEnB,UAAM,SAAS,IAAI,gBAAA;AACnB,QAAI,GAAI,QAAO,IAAI,SAAS,EAAE;AAC9B,QAAI,KAAM,QAAO,IAAI,QAAQ,IAAI;AACjC,UAAM,QAAQ,OAAO,SAAA;AAErB,UAAM,QAAQ,CAAC,aAA6B;AAC1C,cAAQ,CAAC,SAAS;AAChB,cAAM,OAAO,EAAE,GAAG,KAAA;AAClB,mBAAW,QAAQ,SAAU,MAAK,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,KAAK,EAAE,GAAG,GAAG,KAAA;AACpE,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAEA,UAAM,cAAc,CAAC,UAMf;AACJ,cAAQ,CAAC,SAAS;AAChB,cAAM,WAAW,KAAK,MAAM,EAAE;AAC9B,YAAI,CAAC,SAAU,QAAO;AACtB,cAAM,QAAQ,MAAM,QAAQ,MAAM,OAAO,GAAG,SAAS,MAAM,MAAM,KAAK,EAAE,GAAG,MAAM,IAAI;AACrF,cAAM,iBAAiB,MAAM,WAAW,WAAW,oBAAoB;AACvE,eAAO;AAAA,UACL,GAAG;AAAA,UACH,CAAC,MAAM,EAAE,GAAG;AAAA,YACV,GAAG;AAAA,YACH,CAAC,MAAM,MAAM,GAAG;AAAA,YAChB,CAAC,cAAc,GAAG,MAAM,aAAa,SAAS,cAAc;AAAA,UAAA;AAAA,QAC9D;AAAA,MAEJ,CAAC;AAAA,IACH;AAGA,QAAI,aAAa,CAAC,kBAAkB;AAClC,UAAI,UAAU;AACd,UAAI;AACJ,YAAM,OAAO,YAAY;AACvB,YAAI;AACF,gBAAM,MAAM,MAAM,MAAM,GAAG,QAAQ,UAAU,mBAAmB,MAAM,EAAE,CAAC,IAAI;AAAA,YAC3E,SAAS,EAAE,QAAQ,mBAAA;AAAA,UAAmB,CACvC;AACD,cAAI,IAAI,IAAI;AACV,kBAAM,QAAS,MAAM,IAAI,KAAA;AACzB,kBAAM,KAAK;AACX,sBAAU,SAAS;AACnB,gBAAI,kBAAkB,KAAK,GAAG;AAC5B,4BAAc,IAAI;AAClB;AAAA,YACF;AAAA,UACF;AAAA,QACF,QAAQ;AACN,oBAAU,4BAA4B;AAAA,QACxC;AACA,YAAI,CAAC,QAAS,SAAQ,WAAW,MAAM,MAAM;AAAA,MAC/C;AACA,WAAK,KAAA;AACL,aAAO,MAAM;AACX,kBAAU;AACV,YAAI,oBAAoB,KAAK;AAAA,MAC/B;AAAA,IACF;AAGA,UAAM,KAAK,IAAI,YAAY,UAAU,UAAU,KAAK,CAAC;AACrD,cAAU,WAAW;AACrB,OAAG,iBAAiB,QAAQ,CAAC,MAAM;AACjC,UAAI;AACF,cAAM,CAAC,KAAK,MAAO,EAAmB,IAAI,CAAiB,CAAC;AAAA,MAC9D,QAAQ;AAAA,MAER;AAAA,IACF,CAAC;AACD,OAAG,iBAAiB,UAAU,CAAC,MAAM;AACnC,UAAI;AACF,oBAAY,KAAK,MAAO,EAAmB,IAAI,CAAsC;AAAA,MACvF,QAAQ;AAAA,MAER;AAAA,IACF,CAAC;AACD,OAAG,iBAAiB,QAAQ,MAAM;AAChC,gBAAU,UAAU;AACpB,oBAAc,IAAI;AAClB,SAAG,MAAA;AAAA,IACL,CAAC;AACD,OAAG,UAAU,MAAM,UAAU,4BAA4B;AACzD,WAAO,MAAM,GAAG,MAAA;AAAA,EAClB,GAAG,CAAC,IAAI,MAAM,UAAU,SAAS,QAAQ,SAAS,CAAC;AAEnD,SAAO,EAAE,WAAW,OAAO,OAAO,IAAI,GAAG,QAAQ,WAAA;AACnD;AAmBO,SAAS,YAAY,UAA8B,IAAuB;AAC/E,QAAM;AAAA,IACJ;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA,WAAW;AAAA,IACX,UAAU;AAAA,IACV,SAAS;AAAA,IACT,YAAY;AAAA,EAAA,IACV;AAEJ,QAAM,CAAC,MAAM,OAAO,IAAI,SAAwB,CAAA,CAAE;AAClD,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,MAAM;AAE3C,YAAU,MAAM;AACd,QAAI,CAAC,QAAS;AAEd,UAAM,SAAS,IAAI,gBAAA;AACnB,QAAI,KAAM,QAAO,IAAI,QAAQ,IAAI;AACjC,QAAI,aAAc,QAAO,IAAI,UAAU,YAAY;AACnD,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,UAAU,CAAA,CAAE,UAAU,OAAO,SAAS,GAAG,CAAC,IAAI,CAAC,EAAE;AACrF,UAAM,QAAQ,OAAO,SAAA;AAGrB,QAAI,aAAa,CAAC,kBAAkB;AAClC,UAAI,UAAU;AACd,UAAI;AACJ,YAAM,OAAO,YAAY;AACvB,YAAI;AACF,gBAAM,MAAM,MAAM,MAAM,GAAG,QAAQ,SAAS,QAAQ,IAAI,KAAK,KAAK,EAAE,IAAI;AAAA,YACtE,SAAS,EAAE,QAAQ,mBAAA;AAAA,UAAmB,CACvC;AACD,cAAI,IAAI,IAAI;AACV,oBAAS,MAAM,IAAI,MAAwB;AAC3C,sBAAU,SAAS;AAAA,UACrB;AAAA,QACF,QAAQ;AACN,oBAAU,4BAA4B;AAAA,QACxC;AACA,YAAI,CAAC,QAAS,SAAQ,WAAW,MAAM,MAAM;AAAA,MAC/C;AACA,WAAK,KAAA;AACL,aAAO,MAAM;AACX,kBAAU;AACV,YAAI,oBAAoB,KAAK;AAAA,MAC/B;AAAA,IACF;AAGA,UAAM,KAAK,IAAI,YAAY,GAAG,QAAQ,qBAAqB,QAAQ,IAAI,KAAK,KAAK,EAAE,EAAE;AACrF,cAAU,WAAW;AACrB,OAAG,iBAAiB,QAAQ,CAAC,MAAM;AACjC,UAAI;AACF,gBAAQ,KAAK,MAAO,EAAmB,IAAI,CAAkB;AAAA,MAC/D,QAAQ;AAAA,MAER;AAAA,IACF,CAAC;AACD,OAAG,UAAU,MAAM,UAAU,4BAA4B;AACzD,WAAO,MAAM,GAAG,MAAA;AAAA,EAClB,GAAG,CAAC,MAAM,cAAc,KAAK,UAAU,UAAU,CAAA,CAAE,GAAG,UAAU,SAAS,QAAQ,SAAS,CAAC;AAE3F,SAAO,EAAE,MAAM,OAAA;AACjB;"}
|
|
1
|
+
{"version":3,"file":"use-task-run.js","sources":["../../src/hooks/use-task-run.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport {\n allGroupsTerminal,\n type TaskRunMeta,\n type TaskSnapshot,\n} from \"../data/TaskSnapshot\";\nimport { taskQueryKeys } from \"../data/task-query-keys\";\n\n// use-task-run / use-task-runs are the generic clicky-ui task clients. They are\n// SSE-first: they subscribe to clicky's SSEHandler (event: task / event: done)\n// and fall back to polling the JSON endpoints only when EventSource is\n// unavailable. They speak only TaskSnapshot / TaskRunMeta — no app concepts.\n\nexport interface TaskTransportOptions {\n /** Base path of the clicky task API, e.g. \"/api/v1\". */\n basePath?: string | undefined;\n /** Disable the subscription entirely (e.g. before an id is known). */\n enabled?: boolean | undefined;\n /** Poll interval (ms) for the fallback / runs listing. */\n pollMs?: number | undefined;\n /** Force the polling transport even when EventSource exists (mainly tests). */\n forcePoll?: boolean | undefined;\n}\n\nconst DEFAULT_BASE = \"/api/v1\";\nconst DEFAULT_POLL_MS = 2_000;\n\nfunction streamUrl(base: string, query: string): string {\n return `${base}/tasks/stream${query ? `?${query}` : \"\"}`;\n}\n\nfunction hasEventSource(): boolean {\n return typeof globalThis !== \"undefined\" && typeof globalThis.EventSource !== \"undefined\";\n}\n\nexport interface UseTaskRunResult {\n snapshots: TaskSnapshot[];\n status: string;\n isComplete: boolean;\n}\n\nexport interface UseTaskRunOptions extends TaskTransportOptions {\n /** Stable run id to follow (drill-down). Mutually exclusive with kind. */\n id?: string | undefined;\n /** Follow every run of a kind. */\n kind?: string | undefined;\n}\n\n// useTaskRun follows one run (by id) or a kind, SSE-first. It accumulates the\n// latest snapshot per task/group id and reports completion once every group is\n// terminal.\nexport function useTaskRun(options: UseTaskRunOptions = {}): UseTaskRunResult {\n const {\n id,\n kind,\n basePath = DEFAULT_BASE,\n enabled = true,\n pollMs = DEFAULT_POLL_MS,\n forcePoll = false,\n } = options;\n\n const [byId, setById] = useState<Record<string, TaskSnapshot>>({});\n const [status, setStatus] = useState(\"idle\");\n const [isComplete, setIsComplete] = useState(false);\n // Reset accumulator whenever the subscription target changes.\n const targetKey = `${id ?? \"\"}|${kind ?? \"\"}|${enabled}`;\n const prevKey = useRef(targetKey);\n if (prevKey.current !== targetKey) {\n prevKey.current = targetKey;\n }\n\n useEffect(() => {\n if (!enabled || (!id && !kind)) {\n return;\n }\n setById({});\n setIsComplete(false);\n\n const params = new URLSearchParams();\n if (id) params.set(\"tasks\", id);\n if (kind) params.set(\"kind\", kind);\n const query = params.toString();\n\n const merge = (incoming: TaskSnapshot[]) => {\n setById((prev) => {\n const next = { ...prev };\n for (const snap of incoming) next[snap.id] = { ...next[snap.id], ...snap };\n return next;\n });\n };\n\n const mergeOutput = (delta: {\n id: string;\n stream: \"stdout\" | \"stderr\";\n data: string;\n reset?: boolean;\n truncated?: boolean;\n }) => {\n setById((prev) => {\n const snapshot = prev[delta.id];\n if (!snapshot) return prev;\n const value = delta.reset ? delta.data : `${snapshot[delta.stream] ?? \"\"}${delta.data}`;\n const truncatedField = delta.stream === \"stdout\" ? \"stdoutTruncated\" : \"stderrTruncated\";\n return {\n ...prev,\n [delta.id]: {\n ...snapshot,\n [delta.stream]: value,\n [truncatedField]: delta.truncated ?? snapshot[truncatedField],\n },\n };\n });\n };\n\n // Polling fallback transport.\n if (forcePoll || !hasEventSource()) {\n let stopped = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const tick = async () => {\n try {\n const res = await fetch(`${basePath}/tasks/${encodeURIComponent(id ?? \"\")}`, {\n headers: { Accept: \"application/json\" },\n });\n if (res.ok) {\n const snaps = (await res.json()) as TaskSnapshot[];\n merge(snaps);\n setStatus(\"polling\");\n if (allGroupsTerminal(snaps)) {\n setIsComplete(true);\n return; // stop polling\n }\n }\n } catch {\n setStatus(\"connection lost — retrying\");\n }\n if (!stopped) timer = setTimeout(tick, pollMs);\n };\n void tick();\n return () => {\n stopped = true;\n if (timer) clearTimeout(timer);\n };\n }\n\n // SSE transport (default).\n const es = new EventSource(streamUrl(basePath, query));\n setStatus(\"connected\");\n es.addEventListener(\"task\", (e) => {\n try {\n merge([JSON.parse((e as MessageEvent).data) as TaskSnapshot]);\n } catch {\n /* ignore malformed frame */\n }\n });\n es.addEventListener(\"output\", (e) => {\n try {\n mergeOutput(JSON.parse((e as MessageEvent).data) as Parameters<typeof mergeOutput>[0]);\n } catch {\n /* ignore malformed frame */\n }\n });\n es.addEventListener(\"done\", () => {\n setStatus(\"complete\");\n setIsComplete(true);\n es.close();\n });\n es.onerror = () => setStatus(\"connection lost — retrying\");\n return () => es.close();\n }, [id, kind, basePath, enabled, pollMs, forcePoll]);\n\n return { snapshots: Object.values(byId), status, isComplete };\n}\n\nexport interface UseTaskRunsOptions extends TaskTransportOptions {\n kind?: string | undefined;\n status?: string | undefined;\n /** Label equality filters (k=v). */\n labels?: Record<string, string> | undefined;\n}\n\n/** The identity of the listing request that produced a given `runs` array. */\nexport type TaskRunsKey = ReturnType<typeof taskQueryKeys.runs>;\n\nexport interface UseTaskRunsResult {\n runs: TaskRunMeta[];\n status: string;\n /**\n * Query key of the request that actually produced `runs`, or null before the\n * first frame arrives. Changing `kind`/`status`/`labels` re-subscribes but\n * keeps the previous listing on screen until the new transport delivers, so\n * this key lags `taskQueryKeys.runs(options)` during that window. A consumer\n * mirroring `runs` into a cache must compare the two and skip the write while\n * they differ, or it publishes rows that do not match the requested filters.\n */\n runsKey: TaskRunsKey | null;\n}\n\n// useTaskRuns lists all runs (TaskRunMeta) for the manager view. It is SSE-first:\n// it subscribes to clicky's runs stream (event: runs carrying the full listing)\n// and falls back to polling the JSON runs endpoint only when EventSource is\n// unavailable or forced off. The listing has no completion terminal of its own —\n// a manager view stays subscribed to observe new and changing runs.\nexport function useTaskRuns(options: UseTaskRunsOptions = {}): UseTaskRunsResult {\n const {\n kind,\n status: statusFilter,\n labels,\n basePath = DEFAULT_BASE,\n enabled = true,\n pollMs = DEFAULT_POLL_MS,\n forcePoll = false,\n } = options;\n\n // Runs are stored together with the key of the request that delivered them, so\n // a stale listing can never be mistaken for the current filters' result.\n const [received, setReceived] = useState<{\n key: TaskRunsKey | null;\n runs: TaskRunMeta[];\n }>({ key: null, runs: [] });\n const [status, setStatus] = useState(\"idle\");\n\n useEffect(() => {\n if (!enabled) return;\n\n const params = new URLSearchParams();\n if (kind) params.set(\"kind\", kind);\n if (statusFilter) params.set(\"status\", statusFilter);\n for (const [k, v] of Object.entries(labels ?? {})) params.append(\"label\", `${k}=${v}`);\n const query = params.toString();\n const requestKey = taskQueryKeys.runs({ basePath, kind, status: statusFilter, labels });\n const receive = (next: TaskRunMeta[]) => setReceived({ key: requestKey, runs: next });\n\n // Polling fallback transport.\n if (forcePoll || !hasEventSource()) {\n let stopped = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const tick = async () => {\n try {\n const res = await fetch(`${basePath}/tasks${query ? `?${query}` : \"\"}`, {\n headers: { Accept: \"application/json\" },\n });\n if (res.ok) {\n receive((await res.json()) as TaskRunMeta[]);\n setStatus(\"polling\");\n }\n } catch {\n setStatus(\"connection lost — retrying\");\n }\n if (!stopped) timer = setTimeout(tick, pollMs);\n };\n void tick();\n return () => {\n stopped = true;\n if (timer) clearTimeout(timer);\n };\n }\n\n // SSE transport (default).\n const es = new EventSource(`${basePath}/tasks/runs/stream${query ? `?${query}` : \"\"}`);\n setStatus(\"connected\");\n es.addEventListener(\"runs\", (e) => {\n try {\n receive(JSON.parse((e as MessageEvent).data) as TaskRunMeta[]);\n } catch {\n /* ignore malformed frame */\n }\n });\n es.onerror = () => setStatus(\"connection lost — retrying\");\n return () => es.close();\n }, [kind, statusFilter, JSON.stringify(labels ?? {}), basePath, enabled, pollMs, forcePoll]);\n\n return { runs: received.runs, status, runsKey: received.key };\n}\n"],"names":[],"mappings":"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"}
|
package/dist/icons/index.d.ts
CHANGED
|
@@ -588,4 +588,5 @@ export { UiCloudUploadFilled } from './components/UiCloudUpload';
|
|
|
588
588
|
export type { IconProps, IconComponent } from './types';
|
|
589
589
|
export { changeIconAliases, getChangeIcon } from './changeIconAliases';
|
|
590
590
|
export type { ChangeIconEntry } from './changeIconAliases';
|
|
591
|
+
export { clickyIconProvider, iconsByConsumerName } from './registry';
|
|
591
592
|
//# sourceMappingURL=index.d.ts.map
|