@morscherlab/mint-sdk 1.3.9 → 1.4.0-beta.1
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/README.md +152 -177
- package/dist/ActionMenu-CScINahU.js +445 -0
- package/dist/ActionMenu-CScINahU.js.map +1 -0
- package/dist/AppSidebar-BmiiPfz9.js +3514 -0
- package/dist/AppSidebar-BmiiPfz9.js.map +1 -0
- package/dist/{experiment-utils-DTANyVKV.js → BaseModal-DfRIuVoj.js} +74 -149
- package/dist/BaseModal-DfRIuVoj.js.map +1 -0
- package/dist/ConfirmDialog-CJ7hqYUP.js +102 -0
- package/dist/ConfirmDialog-CJ7hqYUP.js.map +1 -0
- package/dist/ExperimentPopover-C4sGw-is.js +359 -0
- package/dist/ExperimentPopover-C4sGw-is.js.map +1 -0
- package/dist/ExperimentSelectorModal-D-9z7cNx.js +527 -0
- package/dist/ExperimentSelectorModal-D-9z7cNx.js.map +1 -0
- package/dist/SegmentedControl-DERBN-Xd.js +129 -0
- package/dist/SegmentedControl-DERBN-Xd.js.map +1 -0
- package/dist/SettingsModal-CSLE31yg.js +666 -0
- package/dist/SettingsModal-CSLE31yg.js.map +1 -0
- package/dist/analysisArtifactTypes-Cy3D0Ipg.js.map +1 -1
- package/dist/auth-SliLnFre.js +65 -0
- package/dist/auth-SliLnFre.js.map +1 -0
- package/dist/components/ActionMenu.vue.d.ts +1 -1
- package/dist/components/AdductText.vue.d.ts +1 -1
- package/dist/components/AlertBox.vue.d.ts +3 -3
- package/dist/components/AppContainer.vue.d.ts +1 -1
- package/dist/components/AppSidebar.vue.d.ts +14 -94
- package/dist/components/AppTopBar.vue.d.ts +16 -70
- package/dist/components/ArtifactSaveDialog.vue.d.ts +4 -4
- package/dist/components/ArtifactSelectorModal.vue.d.ts +4 -4
- package/dist/components/AuditTrail.vue.d.ts +2 -2
- package/dist/components/BaseButton.vue.d.ts +11 -4
- package/dist/components/BaseCheckbox.vue.d.ts +9 -3
- package/dist/components/BaseInput.vue.d.ts +13 -9
- package/dist/components/BaseModal.vue.d.ts +4 -4
- package/dist/components/BasePill.vue.d.ts +15 -8
- package/dist/components/BaseRadioGroup.vue.d.ts +2 -2
- package/dist/components/BaseSelect.vue.d.ts +51 -19
- package/dist/components/BaseTabs.vue.d.ts +6 -5
- package/dist/components/BatchProgressList.vue.d.ts +2 -2
- package/dist/components/ChartContainer.vue.d.ts +2 -2
- package/dist/components/ChemicalFormula.vue.d.ts +2 -2
- package/dist/components/CollapsibleCard.vue.d.ts +3 -3
- package/dist/components/ComponentBindingRenderer.vue.d.ts +2 -3
- package/dist/components/ConcentrationInput.vue.d.ts +2 -2
- package/dist/components/ConfirmDialog.vue.d.ts +8 -7
- package/dist/components/DataFrame.vue.d.ts +32 -74
- package/dist/components/DatePicker.vue.d.ts +24 -2
- package/dist/components/DoseCalculator.vue.d.ts +1 -1
- package/dist/components/DoseCalculatorVolumeField.vue.d.ts +1 -1
- package/dist/components/EmptyState.vue.d.ts +3 -2
- package/dist/components/ExperimentSelectorModal.vue.d.ts +3 -3
- package/dist/components/FormBuilder.vue.d.ts +17 -74
- package/dist/components/FormulaInput.vue.d.ts +2 -2
- package/dist/components/GeneratedPluginView.vue.d.ts +1 -1
- package/dist/components/GeneratedResultRenderer.vue.d.ts +5 -1
- package/dist/components/{StatusIndicator.vue.d.ts → InstrumentStatusPanels.vue.d.ts} +8 -9
- package/dist/components/JobsStatusTray.vue.d.ts +2 -9
- package/dist/components/LoadingSpinner.vue.d.ts +3 -3
- package/dist/components/MoleculeInput.vue.d.ts +2 -2
- package/dist/components/NumberInput.vue.d.ts +19 -5
- package/dist/components/PlateEditor.vue.d.ts +11 -61
- package/dist/components/PlotlyChart.vue.d.ts +2 -2
- package/dist/components/PluginIcon.vue.d.ts +5 -1
- package/dist/components/PluginWorkspaceView.controls.d.ts +2 -9
- package/dist/components/PluginWorkspaceView.navigation.d.ts +1 -7
- package/dist/components/PluginWorkspaceView.props.d.ts +18 -137
- package/dist/components/PluginWorkspaceView.shell.d.ts +2 -10
- package/dist/components/PluginWorkspaceView.vue.d.ts +14 -84
- package/dist/components/PresenceAvatars.vue.d.ts +31 -0
- package/dist/components/ProgressBar.vue.d.ts +3 -2
- package/dist/components/ProtocolStep.presentation.d.ts +0 -1
- package/dist/components/SampleHierarchyTree.vue.d.ts +3 -3
- package/dist/components/SampleSelector.vue.d.ts +3 -3
- package/dist/components/ScheduleCalendar.vue.d.ts +1 -1
- package/dist/components/ScientificNumber.vue.d.ts +1 -1
- package/dist/components/SecretInput.vue.d.ts +2 -2
- package/dist/components/SegmentedControl.vue.d.ts +2 -2
- package/dist/components/SequenceInput.vue.d.ts +2 -2
- package/dist/components/SettingsModal.vue.d.ts +12 -20
- package/dist/components/SmartGroup.types.d.ts +0 -1
- package/dist/components/SmartGroupFieldRecipe.vue.d.ts +1 -1
- package/dist/components/StaleFormBanner.vue.d.ts +20 -0
- package/dist/components/TagsInput.vue.d.ts +4 -3
- package/dist/components/TimeRangeInput.vue.d.ts +2 -2
- package/dist/components/VersionConflictDialog.vue.d.ts +24 -0
- package/dist/components/WellPlate.geometry.d.ts +0 -6
- package/dist/components/WellPlate.rendering.d.ts +0 -2
- package/dist/components/WellPlate.vue.d.ts +7 -52
- package/dist/components/index.d.ts +0 -90
- package/dist/components/{AutoGroupModal.adapter.d.ts → internal/AutoGroupModalInternal.adapter.d.ts} +6 -6
- package/dist/components/{AutoGroupModal.vue.d.ts → internal/AutoGroupModalInternal.vue.d.ts} +6 -6
- package/dist/components/{BaseToggle.vue.d.ts → internal/CheckboxSwitchInternal.vue.d.ts} +2 -2
- package/dist/components/internal/DatePickerDateInternal.vue.d.ts +22 -0
- package/dist/components/{DateTimePicker.vue.d.ts → internal/DatePickerDateTimeInternal.vue.d.ts} +2 -2
- package/dist/components/{TimePicker.vue.d.ts → internal/DatePickerTimeInternal.vue.d.ts} +3 -3
- package/dist/components/internal/FilePickerListInternal.vue.d.ts +2 -2
- package/dist/components/internal/FormSchemaInternal.vue.d.ts +95 -0
- package/dist/components/{UnitInput.vue.d.ts → internal/NumberUnitInputInternal.vue.d.ts} +6 -14
- package/dist/components/internal/PlateEditorBindingInternal.vue.d.ts +3 -2
- package/dist/components/internal/ResourcePickerListInternal.vue.d.ts +3 -3
- package/dist/components/{MultiSelect.vue.d.ts → internal/SelectMultipleInternal.vue.d.ts} +11 -8
- package/dist/components/{SearchableSelect.vue.d.ts → internal/SelectSearchableInternal.vue.d.ts} +5 -2
- package/dist/components/internal/WorkspaceShellInternal.vue.d.ts +1 -15
- package/dist/components/internal/WorkspaceSidebarInternal.vue.d.ts +4 -4
- package/dist/{composables → components/internal}/autoGroup/classKey.d.ts +1 -1
- package/dist/{composables → components/internal}/autoGroup/classify.d.ts +1 -1
- package/dist/{composables → components/internal}/autoGroup/columns.d.ts +1 -1
- package/dist/{composables → components/internal}/autoGroup/compose.d.ts +1 -1
- package/dist/{composables → components/internal}/autoGroup/cooccurrence.d.ts +1 -1
- package/dist/{composables → components/internal}/autoGroup/csv-shim.d.ts +1 -1
- package/dist/{composables → components/internal}/autoGroup/fingerprint.d.ts +1 -1
- package/dist/{composables → components/internal}/autoGroup/template.d.ts +1 -1
- package/dist/{composables → components/internal}/autoGroup/tokenLength.d.ts +1 -1
- package/dist/components/internal/generatedJobsApi.d.ts +1 -1
- package/dist/{composables → components/internal}/useAutoGroup.d.ts +9 -18
- package/dist/composables/componentSpecs.d.ts +41 -0
- package/dist/composables/controlComponentBindings.d.ts +6 -0
- package/dist/composables/controlSchemaAdapters.d.ts +28 -2
- package/dist/composables/controlSchemaDoseDesign.d.ts +1 -1
- package/dist/composables/controlSchemaModel.d.ts +1 -1
- package/dist/composables/controlSchemaTypes.d.ts +35 -23
- package/dist/composables/{usePluginClient.d.ts → createClient.d.ts} +20 -49
- package/dist/composables/{useEventStream.d.ts → eventStream.d.ts} +2 -2
- package/dist/composables/experiment-utils.d.ts +1 -6
- package/dist/composables/index.d.ts +6 -59
- package/dist/composables/platformContextHelpers.d.ts +0 -11
- package/dist/composables/pluginEndpointBuilder.d.ts +2 -2
- package/dist/composables/pluginWorkspaceModel.d.ts +14 -97
- package/dist/composables/useApi.d.ts +1 -3
- package/dist/composables/useAppExperiment.d.ts +1 -1
- package/dist/composables/{useAnalysisArtifacts.d.ts → useArtifacts.d.ts} +6 -6
- package/dist/composables/useExperiment.d.ts +30 -0
- package/dist/composables/useFilePicker.d.ts +2 -2
- package/dist/composables/useJobCenter.d.ts +63 -0
- package/dist/composables/{useGeneratedAnalysis.d.ts → useJobsEndpoint.d.ts} +22 -23
- package/dist/composables/useMenuKeyboard.d.ts +1 -1
- package/dist/composables/usePlatform.d.ts +63 -0
- package/dist/composables/usePluginWorkspace.d.ts +6 -11
- package/dist/composables/usePresence.d.ts +41 -0
- package/dist/composables/useRackEditor.d.ts +2 -2
- package/dist/composables/useRealtime.d.ts +71 -0
- package/dist/composables/{useRequestSyncState.d.ts → useRequest.d.ts} +12 -17
- package/dist/composables/useToast.d.ts +7 -5
- package/dist/composables/useVersionedSave.d.ts +76 -0
- package/dist/controlSchemaModel-CP5-_nAj.js +95 -0
- package/dist/controlSchemaModel-CP5-_nAj.js.map +1 -0
- package/dist/data-C2PwI_dn.js +3811 -0
- package/dist/data-C2PwI_dn.js.map +1 -0
- package/dist/data.d.ts +32 -0
- package/dist/data.js +10 -0
- package/dist/deprecatedRootExports.d.ts +191 -0
- package/dist/experiment-43OJtH7R.js +673 -0
- package/dist/experiment-43OJtH7R.js.map +1 -0
- package/dist/experimentStatus-BZmU4czV.js +60 -0
- package/dist/experimentStatus-BZmU4czV.js.map +1 -0
- package/dist/host.d.ts +10 -0
- package/dist/host.js +26 -0
- package/dist/host.js.map +1 -0
- package/dist/index.d.ts +1 -12
- package/dist/index.js +65 -277
- package/dist/index.js.map +1 -1
- package/dist/install-DAID6c2-.js +668 -0
- package/dist/install-DAID6c2-.js.map +1 -0
- package/dist/install.d.ts +2 -1
- package/dist/install.js +1 -21
- package/dist/instrument.d.ts +0 -6
- package/dist/lab-DLwRl_Ql.js +7513 -0
- package/dist/lab-DLwRl_Ql.js.map +1 -0
- package/dist/lab.d.ts +42 -0
- package/dist/lab.js +4 -0
- package/dist/permissions.d.ts +0 -4
- package/dist/permissions.js +1 -20
- package/dist/permissions.js.map +1 -1
- package/dist/records-BzTcxekG.js +3070 -0
- package/dist/records-BzTcxekG.js.map +1 -0
- package/dist/runtime-D6gVat6r.js +1495 -0
- package/dist/runtime-D6gVat6r.js.map +1 -0
- package/dist/runtime.d.ts +25 -0
- package/dist/runtime.js +8 -0
- package/dist/shell-5ju97nOS.js +197 -0
- package/dist/shell-5ju97nOS.js.map +1 -0
- package/dist/shell.d.ts +16 -0
- package/dist/shell.js +8 -0
- package/dist/stores/auth.d.ts +13 -35
- package/dist/stores/experiment.d.ts +4 -0
- package/dist/stores/index.js +2 -2
- package/dist/styles.css +12030 -14845
- package/dist/types/analysisArtifactTypes.d.ts +1 -1
- package/dist/types/auth.d.ts +0 -8
- package/dist/types/componentLabTypes.d.ts +98 -34
- package/dist/types/componentWorkflowTypes.d.ts +0 -27
- package/dist/types/components.d.ts +145 -74
- package/dist/types/form-builder.d.ts +4 -0
- package/dist/types/generated/platformContext.d.ts +52 -0
- package/dist/types/generated-ui.d.ts +2 -2
- package/dist/types/index.d.ts +4 -5
- package/dist/types/instrument.d.ts +41 -0
- package/dist/types/platform.d.ts +20 -58
- package/dist/useDebouncedWatch-BPwyl6eS.js +73 -0
- package/dist/useDebouncedWatch-BPwyl6eS.js.map +1 -0
- package/dist/useExpansionSet-CvoNMZJi.js +68 -0
- package/dist/useExpansionSet-CvoNMZJi.js.map +1 -0
- package/dist/useExperimentSamples-CxcnxZ8h.js +366 -0
- package/dist/useExperimentSamples-CxcnxZ8h.js.map +1 -0
- package/dist/useListReorder-CcbEYxX-.js +5462 -0
- package/dist/useListReorder-CcbEYxX-.js.map +1 -0
- package/dist/useRackEditor-BD5NIo5s.js +5916 -0
- package/dist/useRackEditor-BD5NIo5s.js.map +1 -0
- package/dist/useRealtime-PalKue84.js +696 -0
- package/dist/useRealtime-PalKue84.js.map +1 -0
- package/dist/useRequest-D5JDfsgZ.js +76 -0
- package/dist/useRequest-D5JDfsgZ.js.map +1 -0
- package/dist/utils/color.d.ts +0 -5
- package/dist/{composables/useDoseCalculator.d.ts → utils/dose.d.ts} +10 -13
- package/dist/utils/experimentStatus.d.ts +9 -0
- package/dist/{composables/useChemicalFormula.d.ts → utils/formula.d.ts} +3 -6
- package/dist/utils/integrationHost.d.ts +18 -0
- package/dist/utils/plotlyTemplate.d.ts +2 -0
- package/dist/utils/pluginSecrets.d.ts +12 -12
- package/dist/utils/presenceAvatars.d.ts +30 -0
- package/dist/utils/records.d.ts +0 -2
- package/dist/{composables/useTimeUtils.d.ts → utils/time.d.ts} +0 -18
- package/package.json +20 -17
- package/src/__tests__/components/ActionMenu.test.ts +0 -13
- package/src/__tests__/components/AlertBox.test.ts +1 -1
- package/src/__tests__/components/AppSidebar.test.ts +119 -167
- package/src/__tests__/components/AppToastContainer.test.ts +2 -2
- package/src/__tests__/components/AppTopBar.test.ts +181 -176
- package/src/__tests__/components/ArtifactSaveDialog.test.ts +5 -3
- package/src/__tests__/components/ArtifactSelectorModal.test.ts +6 -4
- package/src/__tests__/components/AuditTrail.test.ts +1 -1
- package/src/__tests__/components/AutoGroupModal.adapter.test.ts +1 -1
- package/src/__tests__/components/AutoGroupModal.anatomy.test.ts +2 -2
- package/src/__tests__/components/AutoGroupModal.wiring.test.ts +2 -2
- package/src/__tests__/components/BaseButton.test.ts +51 -0
- package/src/__tests__/components/{BaseToggle.test.ts → BaseCheckbox.switch.test.ts} +8 -6
- package/src/__tests__/components/BaseInput.test.ts +13 -34
- package/src/__tests__/components/BaseModal.test.ts +6 -6
- package/src/__tests__/components/BasePill.test.ts +33 -39
- package/src/__tests__/components/{MultiSelect.test.ts → BaseSelect.multiple.test.ts} +16 -7
- package/src/__tests__/components/{SearchableSelect.test.ts → BaseSelect.searchable.test.ts} +19 -9
- package/src/__tests__/components/BaseSelect.test.ts +10 -0
- package/src/__tests__/components/BaseTabs.test.ts +13 -13
- package/src/__tests__/components/CollapsibleCard.test.ts +1 -1
- package/src/__tests__/components/ComponentBindingRenderer.test.ts +25 -73
- package/src/__tests__/components/ConcentrationInput.test.ts +3 -3
- package/src/__tests__/components/ConfirmDialog.test.ts +23 -0
- package/src/__tests__/components/DataFrame.test.ts +140 -142
- package/src/__tests__/components/DataStates.test.ts +6 -22
- package/src/__tests__/components/{DateTimePicker.test.ts → DatePicker.datetime.test.ts} +9 -7
- package/src/__tests__/components/{TimePicker.test.ts → DatePicker.time.test.ts} +18 -17
- package/src/__tests__/components/DoseCalculator.test.ts +12 -7
- package/src/__tests__/components/DoseCalculatorVolumeField.test.ts +6 -6
- package/src/__tests__/components/ExperimentSelectorModal.test.ts +15 -15
- package/src/__tests__/components/FormBuilder.test.ts +49 -167
- package/src/__tests__/components/FormSchemaInternal.test.ts +91 -0
- package/src/__tests__/components/GeneratedPathInput.test.ts +18 -13
- package/src/__tests__/components/GeneratedPluginView.test.ts +38 -24
- package/src/__tests__/components/GeneratedResultRenderer.test.ts +6 -4
- package/src/__tests__/components/InstrumentStatusPanels.test.ts +79 -0
- package/src/__tests__/components/JobsStatusTray.test.ts +4 -4
- package/src/__tests__/components/NumberInput.test.ts +28 -0
- package/src/__tests__/components/{UnitInput.test.ts → NumberInput.units.test.ts} +6 -6
- package/src/__tests__/components/PlateEditor.test.ts +108 -108
- package/src/__tests__/components/PlateEditorBindingInternal.test.ts +13 -13
- package/src/__tests__/components/PlotlyChart.test.ts +1 -1
- package/src/__tests__/components/PluginIcon.test.ts +9 -4
- package/src/__tests__/components/PluginWorkspaceView.controls.test.ts +16 -29
- package/src/__tests__/components/PluginWorkspaceView.internal.test.ts +28 -34
- package/src/__tests__/components/PluginWorkspaceView.navigation.test.ts +4 -19
- package/src/__tests__/components/PluginWorkspaceView.shell.test.ts +1 -6
- package/src/__tests__/components/PluginWorkspaceView.test.ts +176 -155
- package/src/__tests__/components/PresenceAvatars.test.ts +90 -0
- package/src/__tests__/components/ProtocolStep.presentation.test.ts +1 -3
- package/src/__tests__/components/ProtocolStepEditor.test.ts +10 -11
- package/src/__tests__/components/ProtocolStepParameterField.test.ts +8 -7
- package/src/__tests__/components/ResourcePickerListInternal.test.ts +2 -2
- package/src/__tests__/components/RetiredStyles.test.ts +0 -18
- package/src/__tests__/components/SampleSelector.test.ts +17 -17
- package/src/__tests__/components/SecretInput.test.ts +14 -19
- package/src/__tests__/components/SettingsModal.test.ts +76 -84
- package/src/__tests__/components/StaleFormBanner.test.ts +48 -0
- package/src/__tests__/components/ThemeToggle.test.ts +1 -1
- package/src/__tests__/components/WellPlate.decoration.test.ts +10 -8
- package/src/__tests__/components/WellPlate.interaction.test.ts +6 -7
- package/src/__tests__/components/WellPlate.keyboard.test.ts +2 -2
- package/src/__tests__/components/deprecationTags.test.ts +90 -0
- package/src/__tests__/composables/analysisArtifactTarget.test.ts +1 -12
- package/src/__tests__/composables/autoGroup/classKey.test.ts +1 -1
- package/src/__tests__/composables/autoGroup/classify.test.ts +1 -1
- package/src/__tests__/composables/autoGroup/columns.test.ts +1 -1
- package/src/__tests__/composables/autoGroup/compose.test.ts +1 -1
- package/src/__tests__/composables/autoGroup/cooccurrence.test.ts +1 -1
- package/src/__tests__/composables/autoGroup/fieldEdits.test.ts +1 -1
- package/src/__tests__/composables/autoGroup/fingerprint.test.ts +1 -1
- package/src/__tests__/composables/autoGroup/golden.test.ts +1 -1
- package/src/__tests__/composables/autoGroup/groupByOrder.test.ts +1 -1
- package/src/__tests__/composables/autoGroup/groupTree.test.ts +1 -1
- package/src/__tests__/composables/autoGroup/integration.test.ts +1 -1
- package/src/__tests__/composables/autoGroup/template.test.ts +1 -1
- package/src/__tests__/composables/autoGroup/tokenLength.test.ts +1 -1
- package/src/__tests__/composables/autoGroup/tokenize.test.ts +1 -1
- package/src/__tests__/composables/{usePluginClient.test.ts → createClient.test.ts} +84 -222
- package/src/__tests__/composables/{useEventStream.test.ts → eventStream.test.ts} +6 -6
- package/src/__tests__/composables/experiment-utils.test.ts +13 -14
- package/src/__tests__/composables/useApi.test.ts +32 -21
- package/src/__tests__/composables/useAppExperiment.test.ts +19 -2
- package/src/__tests__/composables/{useAnalysisArtifacts.test.ts → useArtifacts.test.ts} +19 -27
- package/src/__tests__/composables/useAutoGroup.test.ts +3 -13
- package/src/__tests__/composables/useControlSchema.test.ts +41 -99
- package/src/__tests__/composables/useExperiment.test.ts +63 -0
- package/src/__tests__/composables/useFileBrowser.test.ts +4 -6
- package/src/__tests__/composables/{useJobsStatusTray.test.ts → useJobCenter.test.ts} +31 -31
- package/src/__tests__/composables/{useGeneratedAnalysis.test.ts → useJobsEndpoint.test.ts} +213 -139
- package/src/__tests__/composables/usePlatform.test.ts +102 -0
- package/src/__tests__/composables/usePresence.test.ts +164 -0
- package/src/__tests__/composables/useRackEditor.test.ts +2 -2
- package/src/__tests__/composables/useRealtime.test.ts +196 -0
- package/src/__tests__/composables/{useRequestSyncState.test.ts → useRequest.test.ts} +32 -47
- package/src/__tests__/composables/useVersionedSave.test.ts +194 -0
- package/src/__tests__/docs/extractDocsComponents.test.ts +36 -0
- package/src/__tests__/docs/extractDocsParsing.test.ts +2 -2
- package/src/__tests__/docs/extractDocsTheme.test.ts +1 -46
- package/src/__tests__/docs/frontendDocsCatalog.test.ts +164 -84
- package/src/__tests__/styles/baseControlsRules.test.ts +1 -1
- package/src/__tests__/styles/darkModeRules.test.ts +0 -6
- package/src/__tests__/{composables/useChemicalFormula.test.ts → utils/formula.test.ts} +3 -5
- package/src/__tests__/utils/permissions.test.ts +1 -36
- package/src/__tests__/utils/plotlyTemplate.test.ts +16 -1
- package/src/__tests__/{composables/useTimeUtils.test.ts → utils/time.test.ts} +2 -9
- package/src/components/ActionMenu.vue +7 -13
- package/src/components/AlertBox.story.vue +25 -25
- package/src/components/AlertBox.vue +8 -8
- package/src/components/AppLayout.story.vue +33 -44
- package/src/components/AppLayout.vue +1 -1
- package/src/components/AppSidebar.story.vue +40 -73
- package/src/components/AppSidebar.vue +66 -147
- package/src/components/AppToastContainer.story.vue +1 -1
- package/src/components/AppTopBar.story.vue +51 -100
- package/src/components/AppTopBar.vue +74 -198
- package/src/components/ArtifactSaveDialog.story.vue +9 -9
- package/src/components/ArtifactSaveDialog.vue +23 -26
- package/src/components/ArtifactSelectorModal.story.vue +4 -4
- package/src/components/ArtifactSelectorModal.vue +10 -10
- package/src/components/AuditTrail.story.vue +4 -4
- package/src/components/AuditTrail.vue +3 -3
- package/src/components/Avatar.story.vue +2 -3
- package/src/components/Avatar.vue +1 -2
- package/src/components/BaseButton.story.vue +25 -0
- package/src/components/BaseButton.vue +39 -10
- package/src/components/BaseCheckbox.story.vue +2 -2
- package/src/components/{BaseToggle.story.vue → BaseCheckbox.switch.story.vue} +22 -19
- package/src/components/BaseCheckbox.vue +39 -7
- package/src/components/BaseInput.story.vue +3 -15
- package/src/components/{BaseTextarea.story.vue → BaseInput.textarea.story.vue} +14 -10
- package/src/components/BaseInput.vue +53 -26
- package/src/components/BaseModal.story.vue +11 -11
- package/src/components/BaseModal.vue +8 -8
- package/src/components/BasePill.story.vue +48 -28
- package/src/components/BasePill.vue +22 -11
- package/src/components/BaseRadioGroup.story.vue +4 -4
- package/src/components/BaseRadioGroup.vue +3 -3
- package/src/components/{MultiSelect.story.vue → BaseSelect.multiple.story.vue} +20 -14
- package/src/components/{SearchableSelect.story.vue → BaseSelect.searchable.story.vue} +4 -4
- package/src/components/BaseSelect.story.vue +2 -2
- package/src/components/BaseSelect.vue +117 -22
- package/src/components/BaseTabs.story.vue +20 -20
- package/src/components/BaseTabs.vue +17 -9
- package/src/components/BatchProgressList.vue +3 -3
- package/src/components/ChartContainer.story.vue +8 -13
- package/src/components/ChartContainer.vue +3 -3
- package/src/components/ChemicalFormula.vue +1 -2
- package/src/components/CollapsibleCard.vue +5 -4
- package/src/components/ComponentBindingRenderer.story.vue +0 -29
- package/src/components/ComponentBindingRenderer.vue +15 -39
- package/src/components/ConcentrationInput.story.vue +2 -2
- package/src/components/ConcentrationInput.vue +9 -9
- package/src/components/ConfirmDialog.story.vue +21 -21
- package/src/components/ConfirmDialog.vue +15 -14
- package/src/components/DataFrame.story.vue +28 -40
- package/src/components/DataFrame.vue +112 -128
- package/src/components/{DateTimePicker.story.vue → DatePicker.datetime.story.vue} +19 -14
- package/src/components/DatePicker.story.vue +2 -2
- package/src/components/{TimePicker.story.vue → DatePicker.time.story.vue} +15 -12
- package/src/components/DatePicker.vue +82 -220
- package/src/components/DoseCalculator.vue +13 -19
- package/src/components/DoseCalculatorVolumeField.vue +6 -6
- package/src/components/EmptyState.story.vue +17 -17
- package/src/components/EmptyState.vue +5 -4
- package/src/components/ExperimentPopover.story.vue +1 -1
- package/src/components/ExperimentPopover.vue +4 -4
- package/src/components/ExperimentSelectorModal.story.vue +5 -5
- package/src/components/ExperimentSelectorModal.vue +11 -13
- package/src/components/FilePicker.vue +1 -1
- package/src/components/FormBuilder.story.vue +9 -4
- package/src/components/FormBuilder.vue +46 -253
- package/src/components/FormField.story.vue +1 -2
- package/src/components/FormulaInput.story.vue +2 -2
- package/src/components/FormulaInput.vue +5 -6
- package/src/components/GeneratedPathInput.vue +8 -9
- package/src/components/GeneratedPluginView.story.vue +1 -1
- package/src/components/GeneratedPluginView.vue +23 -22
- package/src/components/GeneratedResultRenderer.vue +16 -17
- package/src/components/InstrumentStatusPanels.story.vue +64 -0
- package/src/components/InstrumentStatusPanels.vue +133 -0
- package/src/components/JobsStatusTray.story.vue +2 -2
- package/src/components/JobsStatusTray.vue +4 -19
- package/src/components/LoadingSpinner.story.vue +11 -11
- package/src/components/LoadingSpinner.vue +6 -4
- package/src/components/MoleculeInput.story.vue +2 -2
- package/src/components/MoleculeInput.vue +3 -3
- package/src/components/NumberInput.story.vue +55 -15
- package/src/components/NumberInput.vue +80 -18
- package/src/components/PlateEditor.story.vue +51 -43
- package/src/components/PlateEditor.vue +97 -128
- package/src/components/PlotlyChart.story.vue +1 -1
- package/src/components/PlotlyChart.vue +6 -4
- package/src/components/PluginIcon.story.vue +9 -6
- package/src/components/PluginIcon.vue +7 -2
- package/src/components/PluginWorkspaceView.controls.ts +9 -29
- package/src/components/PluginWorkspaceView.navigation.ts +2 -23
- package/src/components/PluginWorkspaceView.props.ts +17 -151
- package/src/components/PluginWorkspaceView.shell.ts +13 -24
- package/src/components/PluginWorkspaceView.story.vue +64 -62
- package/src/components/PluginWorkspaceView.vue +21 -78
- package/src/components/PresenceAvatars.story.vue +75 -0
- package/src/components/PresenceAvatars.vue +114 -0
- package/src/components/ProgressBar.story.vue +7 -7
- package/src/components/ProgressBar.vue +4 -3
- package/src/components/ProtocolStep.presentation.ts +0 -11
- package/src/components/ProtocolStepEditor.vue +6 -5
- package/src/components/ProtocolStepParameterField.vue +15 -12
- package/src/components/SampleSelector.colors.ts +1 -1
- package/src/components/SampleSelector.vue +6 -6
- package/src/components/ScheduleCalendar.vue +4 -4
- package/src/components/SecretInput.story.vue +1 -1
- package/src/components/SecretInput.vue +16 -25
- package/src/components/SegmentedControl.story.vue +7 -7
- package/src/components/SegmentedControl.vue +5 -3
- package/src/components/SequenceInput.story.vue +2 -2
- package/src/components/SequenceInput.vue +3 -3
- package/src/components/SettingsModal.story.vue +13 -14
- package/src/components/SettingsModal.vue +29 -47
- package/src/components/SmartGroup.types.ts +4 -6
- package/src/components/SmartGroupFieldRecipe.vue +7 -5
- package/src/components/StaleFormBanner.story.vue +90 -0
- package/src/components/StaleFormBanner.vue +83 -0
- package/src/components/TagsInput.story.vue +7 -7
- package/src/components/TagsInput.vue +7 -6
- package/src/components/ThemeToggle.vue +5 -30
- package/src/components/TimeRangeInput.story.vue +1 -1
- package/src/components/TimeRangeInput.vue +10 -8
- package/src/components/VersionConflictDialog.story.vue +60 -0
- package/src/components/VersionConflictDialog.vue +79 -0
- package/src/components/WellPlate.geometry.ts +0 -38
- package/src/components/WellPlate.rendering.ts +0 -13
- package/src/components/WellPlate.story.vue +61 -50
- package/src/components/WellPlate.vue +61 -87
- package/src/components/index.ts +3 -105
- package/src/components/{AutoGroupModal.adapter.ts → internal/AutoGroupModalInternal.adapter.ts} +8 -8
- package/src/components/{AutoGroupModal.vue → internal/AutoGroupModalInternal.vue} +23 -23
- package/src/components/{BaseToggle.vue → internal/CheckboxSwitchInternal.vue} +8 -8
- package/src/components/internal/DataStateInternal.vue +1 -1
- package/src/components/internal/DatePickerDateInternal.vue +243 -0
- package/src/components/{DateTimePicker.vue → internal/DatePickerDateTimeInternal.vue} +9 -9
- package/src/components/{TimePicker.vue → internal/DatePickerTimeInternal.vue} +7 -7
- package/src/components/internal/FilePickerListInternal.vue +8 -14
- package/src/components/{FormActions.vue → internal/FormActionsInternal.vue} +2 -2
- package/src/components/internal/FormFieldRendererInternal.vue +1 -1
- package/src/components/internal/FormSchemaInternal.vue +253 -0
- package/src/components/{UnitInput.vue → internal/NumberUnitInputInternal.vue} +28 -28
- package/src/components/internal/PlateEditorBindingInternal.vue +8 -7
- package/src/components/internal/ResourcePickerListInternal.vue +4 -4
- package/src/components/{MultiSelect.vue → internal/SelectMultipleInternal.vue} +21 -15
- package/src/components/{SearchableSelect.vue → internal/SelectSearchableInternal.vue} +24 -8
- package/src/components/internal/WellEditPopupInternal.vue +4 -9
- package/src/components/internal/WorkspaceShellInternal.vue +3 -36
- package/src/components/internal/WorkspaceSidebarInternal.vue +4 -25
- package/src/{composables → components/internal}/autoGroup/classKey.ts +1 -1
- package/src/{composables → components/internal}/autoGroup/classify.ts +1 -1
- package/src/{composables → components/internal}/autoGroup/columns.ts +1 -1
- package/src/{composables → components/internal}/autoGroup/compose.ts +3 -3
- package/src/{composables → components/internal}/autoGroup/cooccurrence.ts +1 -1
- package/src/{composables → components/internal}/autoGroup/csv-shim.ts +1 -1
- package/src/{composables → components/internal}/autoGroup/fingerprint.ts +1 -1
- package/src/{composables → components/internal}/autoGroup/index.ts +1 -2
- package/src/{composables → components/internal}/autoGroup/template.ts +1 -1
- package/src/{composables → components/internal}/autoGroup/tokenLength.ts +1 -1
- package/src/components/internal/generatedJobsApi.ts +1 -1
- package/src/{composables → components/internal}/useAutoGroup.ts +3 -57
- package/src/composables/componentSpecs.ts +62 -0
- package/src/composables/controlComponentBindings.ts +7 -0
- package/src/composables/controlSchemaAdapters.ts +45 -7
- package/src/composables/controlSchemaDoseDesign.ts +16 -5
- package/src/composables/controlSchemaModel.ts +1 -1
- package/src/composables/controlSchemaTypes.ts +31 -22
- package/src/composables/{usePluginClient.ts → createClient.ts} +52 -190
- package/src/composables/{useEventStream.ts → eventStream.ts} +3 -3
- package/src/composables/experiment-utils.ts +1 -39
- package/src/composables/formBuilderRegistry.ts +6 -12
- package/src/composables/index.ts +16 -480
- package/src/composables/platformContextHelpers.ts +0 -57
- package/src/composables/pluginEndpointBuilder.ts +8 -10
- package/src/composables/pluginWorkspaceModel.ts +14 -105
- package/src/composables/useApi.ts +18 -30
- package/src/composables/useAppExperiment.ts +6 -5
- package/src/composables/{useAnalysisArtifacts.ts → useArtifacts.ts} +18 -19
- package/src/composables/useControlSchema.ts +5 -9
- package/src/composables/useControlWorkspace.ts +4 -7
- package/src/composables/useExperiment.ts +49 -0
- package/src/composables/useExperimentData.ts +4 -4
- package/src/composables/useExperimentSelector.ts +5 -5
- package/src/composables/useFileBrowser.ts +5 -13
- package/src/composables/useFilePicker.ts +2 -2
- package/src/composables/useFormBuilder.ts +3 -4
- package/src/composables/useJobCenter.ts +324 -0
- package/src/composables/{useGeneratedAnalysis.ts → useJobsEndpoint.ts} +53 -67
- package/src/composables/useMenuKeyboard.ts +1 -1
- package/src/composables/usePlatform.ts +95 -0
- package/src/composables/usePlatformFilePickerAdapter.ts +2 -1
- package/src/composables/usePluginWorkspace.ts +62 -107
- package/src/composables/usePresence.ts +110 -0
- package/src/composables/useRackEditor.ts +3 -3
- package/src/composables/useRealtime.ts +194 -0
- package/src/composables/{useRequestSyncState.ts → useRequest.ts} +25 -48
- package/src/composables/useScheduleCalendarLayout.ts +1 -1
- package/src/composables/useToast.ts +14 -11
- package/src/composables/useVersionedSave.ts +165 -0
- package/src/data.ts +130 -0
- package/src/deprecatedRootExports.ts +226 -0
- package/src/generated/schema.ts +1 -0
- package/src/host.ts +27 -0
- package/src/index.ts +2 -71
- package/src/install.ts +15 -2
- package/src/instrument.ts +1 -6
- package/src/lab.ts +128 -0
- package/src/permissions.ts +0 -27
- package/src/runtime.ts +145 -0
- package/src/shell.ts +103 -0
- package/src/stores/auth.ts +26 -162
- package/src/stores/experiment.ts +27 -1
- package/src/styles/components/action-menu.css +0 -5
- package/src/styles/components/alert-box.css +18 -0
- package/src/styles/components/app-top-bar.css +7 -48
- package/src/styles/components/button.css +12 -0
- package/src/styles/components/checkbox.css +1 -1
- package/src/styles/components/collapsible-card.css +1 -1
- package/src/styles/components/confirm-dialog.css +18 -2
- package/src/styles/components/empty-state.css +4 -2
- package/src/styles/components/file-picker.css +1 -1
- package/src/styles/components/icon-button.css +1 -1
- package/src/styles/components/loading-spinner.css +9 -12
- package/src/styles/components/multi-select.css +6 -1
- package/src/styles/components/pill.css +40 -35
- package/src/styles/components/plugin-icon.css +9 -0
- package/src/styles/components/presence-avatars.css +194 -0
- package/src/styles/components/progress-bar.css +2 -0
- package/src/styles/components/searchable-select.css +3 -0
- package/src/styles/components/smart-group.css +1 -6
- package/src/styles/components/textarea.css +1 -1
- package/src/styles/components/toggle.css +2 -2
- package/src/styles/components/version-conflict.css +122 -0
- package/src/styles/components/well-plate.css +0 -7
- package/src/styles/index.css +2 -11
- package/src/styles/variables.css +1 -527
- package/src/types/analysisArtifactTypes.ts +1 -1
- package/src/types/auth.ts +0 -10
- package/src/types/componentLabTypes.ts +103 -53
- package/src/types/componentWorkflowTypes.ts +2 -33
- package/src/types/components.ts +148 -114
- package/src/types/form-builder.ts +4 -0
- package/src/types/generated/platformContext.ts +59 -0
- package/src/types/generated-ui.ts +2 -2
- package/src/types/index.ts +15 -53
- package/src/types/instrument.ts +27 -0
- package/src/types/platform.ts +25 -89
- package/src/utils/color.ts +1 -12
- package/src/utils/dose.ts +335 -0
- package/src/utils/experimentStatus.ts +43 -0
- package/src/utils/formula.ts +292 -0
- package/src/utils/integrationHost.ts +27 -0
- package/src/utils/plotlyTemplate.ts +6 -0
- package/src/utils/pluginSecrets.ts +23 -23
- package/src/utils/presenceAvatars.ts +53 -0
- package/src/utils/records.ts +0 -5
- package/src/{composables/useTimeUtils.ts → utils/time.ts} +0 -21
- package/dist/ResourcePickerListInternal-CFAw4vTZ.js +0 -605
- package/dist/ResourcePickerListInternal-CFAw4vTZ.js.map +0 -1
- package/dist/__tests__/composables/useBioTemplatePackWorkspace.test.d.ts +0 -1
- package/dist/__tests__/composables/useBioTemplatePresetWorkspace.test.d.ts +0 -1
- package/dist/__tests__/composables/useBioTemplateWorkspace.test.d.ts +0 -1
- package/dist/__tests__/composables/useChemicalFormula.test.d.ts +0 -1
- package/dist/__tests__/composables/useEventStream.test.d.ts +0 -1
- package/dist/__tests__/composables/useExperimentSave.test.d.ts +0 -1
- package/dist/__tests__/composables/useGeneratedAnalysis.test.d.ts +0 -1
- package/dist/__tests__/composables/useGroupAssignment.test.d.ts +0 -1
- package/dist/__tests__/composables/useJobsStatusTray.test.d.ts +0 -1
- package/dist/__tests__/composables/useMobileSupportGate.test.d.ts +0 -1
- package/dist/__tests__/composables/usePlatformContext.test.d.ts +0 -1
- package/dist/__tests__/composables/usePluginClient.test.d.ts +0 -1
- package/dist/__tests__/composables/usePresenceHeartbeat.test.d.ts +0 -1
- package/dist/__tests__/composables/useRequestSyncState.test.d.ts +0 -1
- package/dist/__tests__/composables/useRuntimeAlignment.test.d.ts +0 -1
- package/dist/__tests__/composables/useTemplateCollection.test.d.ts +0 -1
- package/dist/__tests__/composables/useTimeUtils.test.d.ts +0 -1
- package/dist/__tests__/docs/extractDocsTemplates.test.d.ts +0 -1
- package/dist/__tests__/templates/templates.test.d.ts +0 -1
- package/dist/__tests__/templates/templatesDeprecation.test.d.ts +0 -1
- package/dist/__tests__/utils/lcms.test.d.ts +0 -1
- package/dist/__tests__/utils/rack.test.d.ts +0 -1
- package/dist/components/AppAvatarMenu.vue.d.ts +0 -47
- package/dist/components/AppTopBar.navigation.d.ts +0 -10
- package/dist/components/BaseTextarea.vue.d.ts +0 -31
- package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +0 -112
- package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +0 -86
- package/dist/components/BioTemplatePresetWorkspaceView.vue.d.ts +0 -80
- package/dist/components/BioTemplateRenderer.vue.d.ts +0 -30
- package/dist/components/ControlWorkspaceView.vue.d.ts +0 -138
- package/dist/components/DoseDesignWorkspaceView.vue.d.ts +0 -140
- package/dist/components/ExperimentDataViewer.vue.d.ts +0 -54
- package/dist/components/ExperimentTimeline.vue.d.ts +0 -70
- package/dist/components/FitPanel.vue.d.ts +0 -56
- package/dist/components/GroupAssigner.vue.d.ts +0 -26
- package/dist/components/IconButton.vue.d.ts +0 -30
- package/dist/components/MobileSupportGate.vue.d.ts +0 -32
- package/dist/components/ReagentEditor.vue.d.ts +0 -31
- package/dist/components/ReagentList.presentation.d.ts +0 -17
- package/dist/components/ReagentList.vue.d.ts +0 -58
- package/dist/components/SampleLegend.vue.d.ts +0 -33
- package/dist/components/SmartGroupModal.vue.d.ts +0 -29
- package/dist/components/index.js +0 -5
- package/dist/components-BOA5e7kb.js +0 -23137
- package/dist/components-BOA5e7kb.js.map +0 -1
- package/dist/composables/flattenWorkspaceBindings.d.ts +0 -61
- package/dist/composables/index.js +0 -7
- package/dist/composables/useBioTemplateComponents.d.ts +0 -34
- package/dist/composables/useBioTemplateControls.d.ts +0 -10
- package/dist/composables/useBioTemplatePackWorkspace.d.ts +0 -56
- package/dist/composables/useBioTemplatePresetWorkspace.d.ts +0 -79
- package/dist/composables/useBioTemplateWorkspace.d.ts +0 -39
- package/dist/composables/useExperimentSave.d.ts +0 -69
- package/dist/composables/useGroupAssignment.d.ts +0 -35
- package/dist/composables/useJobsStatusTray.d.ts +0 -87
- package/dist/composables/useMobileSupportGate.d.ts +0 -14
- package/dist/composables/usePlatformContext.d.ts +0 -218
- package/dist/composables/usePresenceHeartbeat.d.ts +0 -49
- package/dist/composables/useRuntimeAlignment.d.ts +0 -44
- package/dist/composables/useTemplateCollection.d.ts +0 -62
- package/dist/composables/workspaceRecipes.d.ts +0 -189
- package/dist/composables-izSQH8Ky.js +0 -591
- package/dist/composables-izSQH8Ky.js.map +0 -1
- package/dist/experiment-D49y_Kro.js +0 -459
- package/dist/experiment-D49y_Kro.js.map +0 -1
- package/dist/experiment-utils-DTANyVKV.js.map +0 -1
- package/dist/install.js.map +0 -1
- package/dist/lcms.d.ts +0 -38
- package/dist/settings-BG6v13Zq.js +0 -341
- package/dist/settings-BG6v13Zq.js.map +0 -1
- package/dist/tailwind.preset.d.ts +0 -63
- package/dist/tailwind.preset.js +0 -71
- package/dist/tailwind.preset.js.map +0 -1
- package/dist/templates/adapters.d.ts +0 -19
- package/dist/templates/assayLookups.d.ts +0 -3
- package/dist/templates/assayMatrixAdapters.d.ts +0 -13
- package/dist/templates/assayMatrixBuilder.d.ts +0 -3
- package/dist/templates/assayNormalizers.d.ts +0 -4
- package/dist/templates/builderIdUtils.d.ts +0 -4
- package/dist/templates/builderPresetControls.d.ts +0 -11
- package/dist/templates/builderReadUtils.d.ts +0 -8
- package/dist/templates/builders.d.ts +0 -26
- package/dist/templates/calibrationCurveAdapters.d.ts +0 -7
- package/dist/templates/calibrationCurveBuilder.d.ts +0 -3
- package/dist/templates/calibrationNormalizers.d.ts +0 -5
- package/dist/templates/catalog.d.ts +0 -192
- package/dist/templates/componentBindingCatalog.d.ts +0 -25
- package/dist/templates/componentBindingHelpers.d.ts +0 -17
- package/dist/templates/componentBindings.d.ts +0 -97
- package/dist/templates/componentDoseResponseProps.d.ts +0 -3
- package/dist/templates/componentGenericProps.d.ts +0 -8
- package/dist/templates/componentPlateHelpers.d.ts +0 -11
- package/dist/templates/componentPlateMapProps.d.ts +0 -3
- package/dist/templates/componentPropsFactory.d.ts +0 -3
- package/dist/templates/componentQpcrPlateProps.d.ts +0 -3
- package/dist/templates/componentTargetResolvers.d.ts +0 -5
- package/dist/templates/componentTemplateProps.d.ts +0 -3
- package/dist/templates/controlSchemaClone.d.ts +0 -4
- package/dist/templates/controlSchemaConstants.d.ts +0 -10
- package/dist/templates/controlSchemaMerge.d.ts +0 -3
- package/dist/templates/controlSchemaTargets.d.ts +0 -17
- package/dist/templates/controlSchemaTypes.d.ts +0 -4
- package/dist/templates/controlSchemas.d.ts +0 -34
- package/dist/templates/defaultBioTemplateBuilder.d.ts +0 -3
- package/dist/templates/doseResponseAdapters.d.ts +0 -6
- package/dist/templates/doseResponseBuilder.d.ts +0 -3
- package/dist/templates/elisaAssayCollectionBuilder.d.ts +0 -3
- package/dist/templates/flowCytometryAssayCollectionBuilder.d.ts +0 -3
- package/dist/templates/flowCytometryPanelBuilder.d.ts +0 -3
- package/dist/templates/flowNormalizers.d.ts +0 -8
- package/dist/templates/flowPanelAdapters.d.ts +0 -7
- package/dist/templates/index.d.ts +0 -15
- package/dist/templates/index.js +0 -2
- package/dist/templates/instrumentRunAdapterHelpers.d.ts +0 -8
- package/dist/templates/instrumentRunAdapters.d.ts +0 -19
- package/dist/templates/instrumentRunBuilder.d.ts +0 -3
- package/dist/templates/lcmsBatchCollectionBuilder.d.ts +0 -3
- package/dist/templates/lookup.d.ts +0 -4
- package/dist/templates/packs.d.ts +0 -21
- package/dist/templates/plateMapAdapters.d.ts +0 -5
- package/dist/templates/plateMapBuilder.d.ts +0 -3
- package/dist/templates/presetControlSchemas.d.ts +0 -534
- package/dist/templates/presets.d.ts +0 -106
- package/dist/templates/protocolAdapters.d.ts +0 -9
- package/dist/templates/protocolNormalizers.d.ts +0 -6
- package/dist/templates/protocolStepsBuilder.d.ts +0 -3
- package/dist/templates/qpcrAdapters.d.ts +0 -9
- package/dist/templates/qpcrExpressionCollectionBuilder.d.ts +0 -3
- package/dist/templates/qpcrPlateBuilder.d.ts +0 -3
- package/dist/templates/reagentAdapters.d.ts +0 -9
- package/dist/templates/reagentListBuilder.d.ts +0 -3
- package/dist/templates/runNormalizers.d.ts +0 -10
- package/dist/templates/sampleNormalizers.d.ts +0 -4
- package/dist/templates/samplePrepAdapters.d.ts +0 -7
- package/dist/templates/samplePrepBuilder.d.ts +0 -3
- package/dist/templates/sampleSheetAdapters.d.ts +0 -9
- package/dist/templates/sampleSheetBuilder.d.ts +0 -3
- package/dist/templates/targetedMetabolomicsCollectionBuilder.d.ts +0 -3
- package/dist/templates/targetedMetabolomicsHelpers.d.ts +0 -5
- package/dist/templates/templateAdapterTypes.d.ts +0 -48
- package/dist/templates/templateControlSchemas.d.ts +0 -400
- package/dist/templates/templateCreateOptions.d.ts +0 -165
- package/dist/templates/templateEnvelopes.d.ts +0 -17
- package/dist/templates/templatePackCollectionBuilder.d.ts +0 -3
- package/dist/templates/templatePresetCollectionBuilder.d.ts +0 -20
- package/dist/templates/templateQpcrTypes.d.ts +0 -42
- package/dist/templates/templateValidators.d.ts +0 -25
- package/dist/templates/timeCourseAdapters.d.ts +0 -9
- package/dist/templates/timeCourseBuilder.d.ts +0 -3
- package/dist/templates/types.d.ts +0 -304
- package/dist/templates/wellPlateScreenCollectionBuilder.d.ts +0 -3
- package/dist/templates/westernBlotAssayCollectionBuilder.d.ts +0 -3
- package/dist/templates-B2DB0MCM.js +0 -12304
- package/dist/templates-B2DB0MCM.js.map +0 -1
- package/dist/utils/rack.d.ts +0 -63
- package/dist/validation-C_eH_vIg.js +0 -7999
- package/dist/validation-C_eH_vIg.js.map +0 -1
- package/src/__tests__/components/AppAvatarMenu.test.ts +0 -186
- package/src/__tests__/components/AppTopBar.navigation.test.ts +0 -68
- package/src/__tests__/components/AppTopBarPresence.test.ts +0 -47
- package/src/__tests__/components/BioTemplateExperimentWorkspaceView.test.ts +0 -159
- package/src/__tests__/components/BioTemplatePackWorkspaceView.test.ts +0 -192
- package/src/__tests__/components/BioTemplatePresetWorkspaceView.test.ts +0 -307
- package/src/__tests__/components/BioTemplateRenderer.test.ts +0 -96
- package/src/__tests__/components/ControlWorkspaceView.test.ts +0 -1100
- package/src/__tests__/components/DoseDesignWorkspaceView.test.ts +0 -183
- package/src/__tests__/components/ExperimentTimeline.test.ts +0 -108
- package/src/__tests__/components/FitPanel.test.ts +0 -96
- package/src/__tests__/components/GroupAssigner.test.ts +0 -101
- package/src/__tests__/components/MobileSupportGate.test.ts +0 -120
- package/src/__tests__/components/ReagentList.presentation.test.ts +0 -73
- package/src/__tests__/components/ReagentList.test.ts +0 -167
- package/src/__tests__/components/SampleLegend.test.ts +0 -18
- package/src/__tests__/components/SmartGroupModal.test.ts +0 -69
- package/src/__tests__/components/WellPlate.sampleTypeIndicator.test.ts +0 -58
- package/src/__tests__/components/iconButtonIconSizing.test.ts +0 -18
- package/src/__tests__/composables/useBioTemplatePackWorkspace.test.ts +0 -125
- package/src/__tests__/composables/useBioTemplatePresetWorkspace.test.ts +0 -199
- package/src/__tests__/composables/useBioTemplateWorkspace.test.ts +0 -104
- package/src/__tests__/composables/useExperimentSave.test.ts +0 -542
- package/src/__tests__/composables/useGroupAssignment.test.ts +0 -73
- package/src/__tests__/composables/useMobileSupportGate.test.ts +0 -74
- package/src/__tests__/composables/usePlatformContext.test.ts +0 -148
- package/src/__tests__/composables/usePresenceHeartbeat.test.ts +0 -164
- package/src/__tests__/composables/useRuntimeAlignment.test.ts +0 -145
- package/src/__tests__/composables/useTemplateCollection.test.ts +0 -147
- package/src/__tests__/docs/extractDocsTemplates.test.ts +0 -53
- package/src/__tests__/fixtures/templates/dose-response.json +0 -81
- package/src/__tests__/fixtures/templates/plate-map.json +0 -54
- package/src/__tests__/fixtures/templates/qpcr-plate.json +0 -96
- package/src/__tests__/fixtures/templates/sample-sheet.json +0 -71
- package/src/__tests__/templates/templates.test.ts +0 -1235
- package/src/__tests__/templates/templatesDeprecation.test.ts +0 -78
- package/src/__tests__/utils/lcms.test.ts +0 -73
- package/src/__tests__/utils/rack.test.ts +0 -120
- package/src/components/AppAvatarMenu.story.vue +0 -155
- package/src/components/AppAvatarMenu.vue +0 -154
- package/src/components/AppTopBar.navigation.ts +0 -60
- package/src/components/AutoGroupModal.story.vue +0 -458
- package/src/components/BaseTextarea.vue +0 -58
- package/src/components/BioTemplateExperimentWorkspaceView.story.vue +0 -123
- package/src/components/BioTemplateExperimentWorkspaceView.vue +0 -339
- package/src/components/BioTemplatePackWorkspaceView.story.vue +0 -107
- package/src/components/BioTemplatePackWorkspaceView.vue +0 -180
- package/src/components/BioTemplatePresetWorkspaceView.story.vue +0 -163
- package/src/components/BioTemplatePresetWorkspaceView.vue +0 -403
- package/src/components/BioTemplateRenderer.story.vue +0 -57
- package/src/components/BioTemplateRenderer.vue +0 -64
- package/src/components/ControlWorkspaceView.story.vue +0 -347
- package/src/components/ControlWorkspaceView.vue +0 -370
- package/src/components/DoseDesignWorkspaceView.story.vue +0 -77
- package/src/components/DoseDesignWorkspaceView.vue +0 -243
- package/src/components/ExperimentDataViewer.story.vue +0 -177
- package/src/components/ExperimentDataViewer.vue +0 -313
- package/src/components/ExperimentTimeline.story.vue +0 -208
- package/src/components/ExperimentTimeline.vue +0 -383
- package/src/components/FitPanel.story.vue +0 -191
- package/src/components/FitPanel.vue +0 -168
- package/src/components/FormActions.story.vue +0 -96
- package/src/components/GroupAssigner.story.vue +0 -83
- package/src/components/GroupAssigner.vue +0 -319
- package/src/components/IconButton.story.vue +0 -140
- package/src/components/IconButton.vue +0 -69
- package/src/components/MobileSupportGate.story.vue +0 -52
- package/src/components/MobileSupportGate.vue +0 -111
- package/src/components/ReagentEditor.story.vue +0 -153
- package/src/components/ReagentEditor.vue +0 -414
- package/src/components/ReagentList.presentation.ts +0 -106
- package/src/components/ReagentList.story.vue +0 -155
- package/src/components/ReagentList.vue +0 -438
- package/src/components/SampleLegend.story.vue +0 -91
- package/src/components/SampleLegend.vue +0 -121
- package/src/components/SmartGroupModal.story.vue +0 -61
- package/src/components/SmartGroupModal.vue +0 -61
- package/src/components/StatusIndicator.story.vue +0 -99
- package/src/components/StatusIndicator.vue +0 -36
- package/src/components/UnitInput.story.vue +0 -194
- package/src/composables/flattenWorkspaceBindings.ts +0 -104
- package/src/composables/useBioTemplateComponents.ts +0 -117
- package/src/composables/useBioTemplateControls.ts +0 -45
- package/src/composables/useBioTemplatePackWorkspace.ts +0 -201
- package/src/composables/useBioTemplatePresetWorkspace.ts +0 -329
- package/src/composables/useBioTemplateWorkspace.ts +0 -120
- package/src/composables/useChemicalFormula.ts +0 -301
- package/src/composables/useDoseCalculator.ts +0 -370
- package/src/composables/useExperimentSave.ts +0 -348
- package/src/composables/useGroupAssignment.ts +0 -152
- package/src/composables/useJobsStatusTray.ts +0 -493
- package/src/composables/useMobileSupportGate.ts +0 -80
- package/src/composables/usePlatformContext.ts +0 -299
- package/src/composables/usePresenceHeartbeat.ts +0 -201
- package/src/composables/useRuntimeAlignment.ts +0 -184
- package/src/composables/useTemplateCollection.ts +0 -233
- package/src/composables/workspaceRecipes.ts +0 -268
- package/src/lcms.ts +0 -119
- package/src/styles/components/app-avatar-menu.css +0 -121
- package/src/styles/components/experiment-data-viewer.css +0 -138
- package/src/styles/components/experiment-timeline.css +0 -572
- package/src/styles/components/fit-panel.css +0 -153
- package/src/styles/components/group-assigner.css +0 -198
- package/src/styles/components/mobile-support-gate.css +0 -117
- package/src/styles/components/reagent-editor.css +0 -501
- package/src/styles/components/reagent-list.css +0 -408
- package/src/styles/components/sample-legend.css +0 -212
- package/src/styles/components/status-indicator.css +0 -66
- package/src/styles/components/theme-toggle.css +0 -6
- package/src/tailwind.preset.ts +0 -66
- package/src/templates/adapters.ts +0 -141
- package/src/templates/assayLookups.ts +0 -33
- package/src/templates/assayMatrixAdapters.ts +0 -85
- package/src/templates/assayMatrixBuilder.ts +0 -60
- package/src/templates/assayNormalizers.ts +0 -34
- package/src/templates/builderIdUtils.ts +0 -20
- package/src/templates/builderPresetControls.ts +0 -166
- package/src/templates/builderReadUtils.ts +0 -55
- package/src/templates/builders.ts +0 -122
- package/src/templates/calibrationCurveAdapters.ts +0 -62
- package/src/templates/calibrationCurveBuilder.ts +0 -100
- package/src/templates/calibrationNormalizers.ts +0 -60
- package/src/templates/catalog.ts +0 -249
- package/src/templates/componentBindingCatalog.ts +0 -90
- package/src/templates/componentBindingHelpers.ts +0 -93
- package/src/templates/componentBindings.ts +0 -279
- package/src/templates/componentDoseResponseProps.ts +0 -41
- package/src/templates/componentGenericProps.ts +0 -77
- package/src/templates/componentPlateHelpers.ts +0 -52
- package/src/templates/componentPlateMapProps.ts +0 -34
- package/src/templates/componentPropsFactory.ts +0 -21
- package/src/templates/componentQpcrPlateProps.ts +0 -27
- package/src/templates/componentTargetResolvers.ts +0 -67
- package/src/templates/componentTemplateProps.ts +0 -78
- package/src/templates/controlSchemaClone.ts +0 -32
- package/src/templates/controlSchemaConstants.ts +0 -11
- package/src/templates/controlSchemaMerge.ts +0 -40
- package/src/templates/controlSchemaTargets.ts +0 -85
- package/src/templates/controlSchemaTypes.ts +0 -20
- package/src/templates/controlSchemas.ts +0 -113
- package/src/templates/defaultBioTemplateBuilder.ts +0 -125
- package/src/templates/doseResponseAdapters.ts +0 -36
- package/src/templates/doseResponseBuilder.ts +0 -45
- package/src/templates/elisaAssayCollectionBuilder.ts +0 -63
- package/src/templates/flowCytometryAssayCollectionBuilder.ts +0 -42
- package/src/templates/flowCytometryPanelBuilder.ts +0 -54
- package/src/templates/flowNormalizers.ts +0 -58
- package/src/templates/flowPanelAdapters.ts +0 -61
- package/src/templates/index.ts +0 -330
- package/src/templates/instrumentRunAdapterHelpers.ts +0 -94
- package/src/templates/instrumentRunAdapters.ts +0 -174
- package/src/templates/instrumentRunBuilder.ts +0 -98
- package/src/templates/lcmsBatchCollectionBuilder.ts +0 -39
- package/src/templates/lookup.ts +0 -18
- package/src/templates/packs.ts +0 -166
- package/src/templates/plateMapAdapters.ts +0 -38
- package/src/templates/plateMapBuilder.ts +0 -44
- package/src/templates/presetControlSchemas.ts +0 -258
- package/src/templates/presets.ts +0 -183
- package/src/templates/protocolAdapters.ts +0 -73
- package/src/templates/protocolNormalizers.ts +0 -37
- package/src/templates/protocolStepsBuilder.ts +0 -37
- package/src/templates/qpcrAdapters.ts +0 -108
- package/src/templates/qpcrExpressionCollectionBuilder.ts +0 -34
- package/src/templates/qpcrPlateBuilder.ts +0 -97
- package/src/templates/reagentAdapters.ts +0 -81
- package/src/templates/reagentListBuilder.ts +0 -31
- package/src/templates/runNormalizers.ts +0 -63
- package/src/templates/sampleNormalizers.ts +0 -58
- package/src/templates/samplePrepAdapters.ts +0 -66
- package/src/templates/samplePrepBuilder.ts +0 -52
- package/src/templates/sampleSheetAdapters.ts +0 -79
- package/src/templates/sampleSheetBuilder.ts +0 -24
- package/src/templates/targetedMetabolomicsCollectionBuilder.ts +0 -80
- package/src/templates/targetedMetabolomicsHelpers.ts +0 -102
- package/src/templates/templateAdapterTypes.ts +0 -58
- package/src/templates/templateControlSchemas.ts +0 -320
- package/src/templates/templateCreateOptions.ts +0 -208
- package/src/templates/templateEnvelopes.ts +0 -145
- package/src/templates/templatePackCollectionBuilder.ts +0 -24
- package/src/templates/templatePresetCollectionBuilder.ts +0 -141
- package/src/templates/templateQpcrTypes.ts +0 -48
- package/src/templates/templateValidators.ts +0 -426
- package/src/templates/timeCourseAdapters.ts +0 -77
- package/src/templates/timeCourseBuilder.ts +0 -65
- package/src/templates/types.ts +0 -493
- package/src/templates/wellPlateScreenCollectionBuilder.ts +0 -37
- package/src/templates/westernBlotAssayCollectionBuilder.ts +0 -69
- package/src/utils/rack.ts +0 -225
- /package/dist/__tests__/components/{AppAvatarMenu.test.d.ts → BaseButton.test.d.ts} +0 -0
- /package/dist/__tests__/components/{AppTopBar.navigation.test.d.ts → BaseCheckbox.switch.test.d.ts} +0 -0
- /package/dist/__tests__/components/{AppTopBarPresence.test.d.ts → BaseSelect.multiple.test.d.ts} +0 -0
- /package/dist/__tests__/components/{BaseToggle.test.d.ts → BaseSelect.searchable.test.d.ts} +0 -0
- /package/dist/__tests__/components/{BioTemplateExperimentWorkspaceView.test.d.ts → ConfirmDialog.test.d.ts} +0 -0
- /package/dist/__tests__/components/{BioTemplatePackWorkspaceView.test.d.ts → DatePicker.datetime.test.d.ts} +0 -0
- /package/dist/__tests__/components/{BioTemplatePresetWorkspaceView.test.d.ts → DatePicker.time.test.d.ts} +0 -0
- /package/dist/__tests__/components/{BioTemplateRenderer.test.d.ts → FormSchemaInternal.test.d.ts} +0 -0
- /package/dist/__tests__/components/{ControlWorkspaceView.test.d.ts → InstrumentStatusPanels.test.d.ts} +0 -0
- /package/dist/__tests__/components/{DateTimePicker.test.d.ts → NumberInput.units.test.d.ts} +0 -0
- /package/dist/__tests__/components/{DoseDesignWorkspaceView.test.d.ts → PresenceAvatars.test.d.ts} +0 -0
- /package/dist/__tests__/components/{ExperimentTimeline.test.d.ts → StaleFormBanner.test.d.ts} +0 -0
- /package/dist/__tests__/components/{FitPanel.test.d.ts → deprecationTags.test.d.ts} +0 -0
- /package/dist/__tests__/{components/GroupAssigner.test.d.ts → composables/createClient.test.d.ts} +0 -0
- /package/dist/__tests__/{components/MobileSupportGate.test.d.ts → composables/eventStream.test.d.ts} +0 -0
- /package/dist/__tests__/{components/MultiSelect.test.d.ts → composables/useArtifacts.test.d.ts} +0 -0
- /package/dist/__tests__/{components/ReagentList.presentation.test.d.ts → composables/useExperiment.test.d.ts} +0 -0
- /package/dist/__tests__/{components/ReagentList.test.d.ts → composables/useJobCenter.test.d.ts} +0 -0
- /package/dist/__tests__/{components/SampleLegend.test.d.ts → composables/useJobsEndpoint.test.d.ts} +0 -0
- /package/dist/__tests__/{components/SearchableSelect.test.d.ts → composables/usePlatform.test.d.ts} +0 -0
- /package/dist/__tests__/{components/SmartGroupModal.test.d.ts → composables/usePresence.test.d.ts} +0 -0
- /package/dist/__tests__/{components/TimePicker.test.d.ts → composables/useRealtime.test.d.ts} +0 -0
- /package/dist/__tests__/{components/UnitInput.test.d.ts → composables/useRequest.test.d.ts} +0 -0
- /package/dist/__tests__/{components/WellPlate.sampleTypeIndicator.test.d.ts → composables/useVersionedSave.test.d.ts} +0 -0
- /package/dist/__tests__/{components/iconButtonIconSizing.test.d.ts → utils/formula.test.d.ts} +0 -0
- /package/dist/__tests__/{composables/useAnalysisArtifacts.test.d.ts → utils/time.test.d.ts} +0 -0
- /package/dist/components/{FormActions.vue.d.ts → internal/FormActionsInternal.vue.d.ts} +0 -0
- /package/dist/{composables → components/internal}/autoGroup/colors.d.ts +0 -0
- /package/dist/{composables → components/internal}/autoGroup/index.d.ts +0 -0
- /package/dist/{composables → components/internal}/autoGroup/tokenize.d.ts +0 -0
- /package/src/{composables → components/internal}/autoGroup/colors.ts +0 -0
- /package/src/{composables → components/internal}/autoGroup/tokenize.ts +0 -0
- /package/src/{composables → components/internal}/autoGroup/vocab.json +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRealtime-PalKue84.js","names":[],"sources":["../src/composables/useJobCenter.ts","../src/components/JobsStatusTray.vue","../src/components/JobsStatusTray.vue","../src/composables/useRealtime.ts"],"sourcesContent":["import {\n computed,\n onMounted,\n onUnmounted,\n ref,\n shallowRef,\n toValue,\n type ComputedRef,\n type MaybeRefOrGetter,\n type Ref,\n type ShallowRef,\n} from 'vue'\n\nimport { isActiveJobStatus, normalizeJobState } from '../jobs'\nimport type {\n JobListPayload,\n JobState,\n JobStateInput,\n} from '../types/jobs'\n\nexport type JobsStatusTrayTab = 'active' | 'history'\n\n/**\n * The canonical owner of a collection of plugin jobs.\n *\n * Sources, rather than job-center UI, own polling, event streams, and all job\n * mutations. This keeps components and consumers on one reactive job graph.\n */\nexport interface PluginJobCenterSource {\n jobs: MaybeRefOrGetter<readonly JobStateInput[]>\n refresh?: () => Promise<JobListPayload | readonly JobStateInput[] | void>\n cancel?: (jobId: string) => Promise<JobStateInput | void>\n delete?: (jobId: string) => Promise<boolean | void>\n clear?: () => Promise<number | void>\n dispose?: () => void\n}\n\nexport interface CombinedPluginJobCenterSource extends PluginJobCenterSource {\n jobs: ComputedRef<readonly JobStateInput[]>\n}\n\n/**\n * Combines independent job runtimes without copying their reactive state.\n *\n * Job ids must be globally unique across the sources. A duplicate id throws\n * when jobs are read or an id-routed action is requested, rather than silently\n * dispatching a mutation to the wrong owner.\n */\nexport function combinePluginJobSources(\n sources: readonly PluginJobCenterSource[],\n): CombinedPluginJobCenterSource {\n const jobs = computed<readonly JobStateInput[]>(() => {\n const combined: JobStateInput[] = []\n const owners = new Set<string>()\n for (const source of sources) {\n for (const job of toValue(source.jobs)) {\n if (owners.has(job.job_id)) throw duplicatePluginJobId(job.job_id)\n owners.add(job.job_id)\n combined.push(job)\n }\n }\n return combined\n })\n\n function ownerFor(jobId: string): PluginJobCenterSource {\n let owner: PluginJobCenterSource | undefined\n for (const source of sources) {\n if (!toValue(source.jobs).some(job => job.job_id === jobId)) continue\n if (owner) throw duplicatePluginJobId(jobId)\n owner = source\n }\n if (!owner) throw new Error(`Unknown plugin job id: ${jobId}`)\n return owner\n }\n\n const combined: CombinedPluginJobCenterSource = { jobs }\n if (sources.some(source => source.refresh)) {\n combined.refresh = async () => {\n await Promise.all(sources.map(source => source.refresh?.()))\n return jobs.value\n }\n }\n if (sources.some(source => source.cancel)) {\n combined.cancel = async (jobId) => {\n const owner = ownerFor(jobId)\n if (!owner.cancel) throw new Error(`Job ${jobId} cannot be cancelled by its source`)\n return owner.cancel(jobId)\n }\n }\n if (sources.length > 0 && sources.every(source => source.delete)) {\n combined.delete = async (jobId) => {\n const owner = ownerFor(jobId)\n if (!owner.delete) throw new Error(`Job ${jobId} cannot be deleted by its source`)\n return owner.delete(jobId)\n }\n }\n // Never report a successful combined clear after mutating only a subset.\n // Without bulk support from every source, the job center can still fall\n // back to this source's id-routed delete method when all owners expose it.\n if (sources.length > 0 && sources.every(source => source.clear)) {\n combined.clear = async () => {\n const results = await Promise.all(\n sources.map(source => source.clear!()),\n )\n return results.every((result): result is number => typeof result === 'number')\n ? results.reduce((total, result) => total + result, 0)\n : undefined\n }\n }\n if (sources.some(source => source.dispose)) {\n combined.dispose = () => {\n const errors: unknown[] = []\n for (const source of sources) {\n try {\n source.dispose?.()\n } catch (cause) {\n errors.push(cause)\n }\n }\n if (errors.length === 1) throw errors[0]\n if (errors.length > 1) throw new PluginJobSourceDisposeError(errors)\n }\n }\n return combined\n}\n\nclass PluginJobSourceDisposeError extends Error {\n readonly cause: unknown\n readonly errors: readonly unknown[]\n\n constructor(errors: readonly unknown[]) {\n super('Failed to dispose plugin job sources')\n this.name = 'PluginJobSourceDisposeError'\n this.cause = errors[0]\n this.errors = Object.freeze([...errors])\n }\n}\n\nfunction duplicatePluginJobId(jobId: string): Error {\n return new Error(`Duplicate plugin job id across combined sources: ${jobId}`)\n}\n\nexport interface UseJobCenterOptions {\n source?: MaybeRefOrGetter<PluginJobCenterSource | undefined>\n loadOnMount?: boolean\n}\n\nexport interface UseJobCenterReturn {\n jobs: ComputedRef<JobState[]>\n activeJobs: ComputedRef<JobState[]>\n historyJobs: ComputedRef<JobState[]>\n deletableJobs: ComputedRef<JobState[]>\n featuredJob: ComputedRef<JobState | null>\n canRefresh: ComputedRef<boolean>\n canCancel: ComputedRef<boolean>\n canDelete: ComputedRef<boolean>\n canClearFinished: ComputedRef<boolean>\n isOpen: Ref<boolean>\n activeTab: Ref<JobsStatusTrayTab>\n isLoading: Ref<boolean>\n error: ShallowRef<string | null>\n pendingJobIds: Ref<Set<string>>\n open: () => void\n close: () => void\n toggle: () => void\n refresh: () => Promise<boolean>\n cancelJob: (job: JobState) => Promise<boolean>\n deleteJob: (job: JobState) => Promise<boolean>\n clearFinished: () => Promise<boolean>\n isPending: (job: JobState) => boolean\n}\n\nfunction errorMessage(error: unknown, fallback: string): string {\n return error instanceof Error ? error.message : fallback\n}\n\n/**\n * Headless controller for plugin job presentation and actions.\n *\n * Every job list is derived directly from the source. The controller never\n * mirrors source jobs into another ref.\n */\nexport function useJobCenter(\n options: UseJobCenterOptions = {},\n): UseJobCenterReturn {\n const isOpen = ref(false)\n const activeTab = ref<JobsStatusTrayTab>('active')\n const isLoading = ref(false)\n const error = shallowRef<string | null>(null)\n const pendingJobIds = ref(new Set<string>())\n let requestGeneration = 0\n let active = true\n const source = computed(() => toValue(options.source))\n\n const jobs = computed<JobState[]>(() => {\n const currentSource = source.value\n return currentSource ? [...toValue(currentSource.jobs)].map(normalizeJobState) : []\n })\n const activeJobs = computed(() => jobs.value.filter(job => isActiveJobStatus(job.status)))\n const historyJobs = computed(() => jobs.value.filter(job => !isActiveJobStatus(job.status)))\n const deletableJobs = computed(() => historyJobs.value.filter(job => job.can_delete))\n const featuredJob = computed(() => activeJobs.value[0] ?? historyJobs.value[0] ?? null)\n const canRefresh = computed(() => Boolean(source.value?.refresh))\n const canCancel = computed(() => Boolean(source.value?.cancel))\n const canDelete = computed(() => Boolean(source.value?.delete))\n const canClearFinished = computed(() => Boolean(\n source.value?.clear || source.value?.delete,\n ))\n\n function setPending(jobId: string, pending: boolean): void {\n const next = new Set(pendingJobIds.value)\n if (pending) next.add(jobId)\n else next.delete(jobId)\n pendingJobIds.value = next\n }\n\n async function refresh(): Promise<boolean> {\n const listJobs = source.value?.refresh\n if (!listJobs) return false\n const generation = ++requestGeneration\n isLoading.value = true\n error.value = null\n try {\n await listJobs()\n return active && generation === requestGeneration\n } catch (cause) {\n if (active && generation === requestGeneration) {\n error.value = errorMessage(cause, 'Failed to load jobs')\n }\n return false\n } finally {\n if (active && generation === requestGeneration) isLoading.value = false\n }\n }\n\n async function cancelJob(job: JobState): Promise<boolean> {\n const sourceCancel = source.value?.cancel\n if (!job.can_cancel || !sourceCancel || pendingJobIds.value.has(job.job_id)) {\n return false\n }\n setPending(job.job_id, true)\n error.value = null\n try {\n await sourceCancel(job.job_id)\n return active\n } catch (cause) {\n if (active) error.value = errorMessage(cause, 'Failed to cancel job')\n return false\n } finally {\n if (active) setPending(job.job_id, false)\n }\n }\n\n async function deleteJob(job: JobState): Promise<boolean> {\n const sourceDelete = source.value?.delete\n if (!job.can_delete || !sourceDelete || pendingJobIds.value.has(job.job_id)) {\n return false\n }\n setPending(job.job_id, true)\n error.value = null\n try {\n const deleted = await sourceDelete(job.job_id)\n return active && deleted !== false\n } catch (cause) {\n if (active) error.value = errorMessage(cause, 'Failed to delete job')\n return false\n } finally {\n if (active) setPending(job.job_id, false)\n }\n }\n\n async function clearFinished(): Promise<boolean> {\n const targets = deletableJobs.value\n if (targets.length === 0) return false\n error.value = null\n try {\n const currentSource = source.value\n if (currentSource?.clear) {\n const deleted = await currentSource.clear()\n if (!active) return false\n return typeof deleted !== 'number' || deleted === targets.length\n }\n if (!currentSource?.delete) return false\n const results = await Promise.all(targets.map(job => deleteJob(job)))\n return results.every(Boolean)\n } catch (cause) {\n if (active) error.value = errorMessage(cause, 'Failed to clear jobs')\n return false\n }\n }\n\n onMounted(() => {\n if (options.loadOnMount !== false) void refresh()\n })\n onUnmounted(() => {\n active = false\n requestGeneration += 1\n })\n\n return {\n jobs,\n activeJobs,\n historyJobs,\n deletableJobs,\n featuredJob,\n canRefresh,\n canCancel,\n canDelete,\n canClearFinished,\n isOpen,\n activeTab,\n isLoading,\n error,\n pendingJobIds,\n open: () => { isOpen.value = true },\n close: () => { isOpen.value = false },\n toggle: () => { isOpen.value = !isOpen.value },\n refresh,\n cancelJob,\n deleteJob,\n clearFinished,\n isPending: job => pendingJobIds.value.has(job.job_id),\n }\n}\n","<script setup lang=\"ts\">\n/**\n * Floating, source-driven job status tray for plugin and platform workflows.\n *\n * @example Recommended\n * ```vue\n * <JobsStatusTray :source=\"jobs\" />\n * ```\n */\nimport { computed, nextTick, ref, toRef, useId } from 'vue'\n\nimport {\n jobStatusLabel,\n normalizeJobPercent,\n} from '../jobs'\nimport {\n useJobCenter,\n type PluginJobCenterSource,\n} from '../composables/useJobCenter'\nimport type { JobState } from '../types/jobs'\n\ninterface Props {\n source?: PluginJobCenterSource\n loadOnMount?: boolean\n title?: string\n teleportTo?: string | HTMLElement | false\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n loadOnMount: true,\n title: 'Analysis jobs',\n teleportTo: 'body',\n})\n\nconst emit = defineEmits<{\n select: [job: JobState]\n error: [message: string]\n}>()\n\ndefineSlots<{\n /** Extra per-row actions, rendered before the built-in Cancel / Delete. */\n 'job-actions'?: (props: { job: JobState }) => unknown\n}>()\n\nconst panelId = `mint-jobs-tray-${useId().replace(/:/g, '')}`\nconst titleId = `${panelId}-title`\nconst triggerRef = ref<HTMLButtonElement | null>(null)\nconst panelRef = ref<HTMLElement | null>(null)\nconst teleportTarget = computed(() => props.teleportTo || 'body')\nconst tray = useJobCenter({\n source: toRef(props, 'source'),\n loadOnMount: props.loadOnMount,\n})\n// 2f: a job waiting for input is the only one that needs a person — pin it first.\nconst activeRows = computed(() => [\n ...tray.activeJobs.value.filter(job => job.status === 'awaiting_input'),\n ...tray.activeJobs.value.filter(job => job.status !== 'awaiting_input'),\n])\nconst subtitle = computed(() => {\n const count = (status: JobState['status']) => tray.activeJobs.value.filter(job => job.status === status).length\n const parts = [\n [count('running'), 'running'],\n [count('queued'), 'queued'],\n [count('awaiting_input'), 'waiting'],\n ].filter(([n]) => n).map(([n, word]) => `${n} ${word}`)\n return parts.length ? parts.join(' · ') : `${tray.jobs.value.length} total`\n})\nconst canClear = computed(() => (\n tray.deletableJobs.value.length > 0\n && tray.canClearFinished.value\n))\n\nasync function openTray(): Promise<void> {\n tray.open()\n await nextTick()\n panelRef.value?.focus()\n}\n\nasync function closeTray(): Promise<void> {\n tray.close()\n await nextTick()\n triggerRef.value?.focus()\n}\n\nasync function toggleTray(): Promise<void> {\n if (tray.isOpen.value) await closeTray()\n else await openTray()\n}\n\nfunction onPanelKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n void closeTray()\n return\n }\n if (event.key !== 'Tab' || !panelRef.value) return\n const focusable = Array.from(panelRef.value.querySelectorAll<HTMLElement>(\n 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])',\n ))\n if (focusable.length === 0) {\n event.preventDefault()\n panelRef.value.focus()\n return\n }\n const first = focusable[0]\n const last = focusable[focusable.length - 1]\n const activeElement = document.activeElement as HTMLElement | null\n if (!activeElement || !focusable.includes(activeElement)) {\n event.preventDefault()\n if (event.shiftKey) last?.focus()\n else first?.focus()\n } else if (event.shiftKey && activeElement === first) {\n event.preventDefault()\n last?.focus()\n } else if (!event.shiftKey && activeElement === last) {\n event.preventDefault()\n first?.focus()\n }\n}\n\nfunction progressText(job: JobState): string {\n if (job.status === 'awaiting_input') {\n return job.progress.message || 'Waiting for external input'\n }\n if (job.status === 'queued' && job.queue_position > 0) {\n return `Queue position ${job.queue_position}`\n }\n return job.progress.message || job.progress.stage || jobStatusLabel(job.status)\n}\n\nfunction formatTimestamp(value: string | null): string {\n if (!value) return ''\n const date = new Date(value)\n return Number.isNaN(date.getTime())\n ? ''\n : new Intl.DateTimeFormat(undefined, { dateStyle: 'medium', timeStyle: 'short' }).format(date)\n}\n\nfunction statusClass(job: JobState): string {\n return `mint-jobs-tray__status--${job.status.replace('_', '-')}`\n}\n\nfunction jobPercent(job: JobState): number {\n return Math.round(normalizeJobPercent(job.progress.percent))\n}\n\nasync function cancelJob(job: JobState): Promise<void> {\n const succeeded = await tray.cancelJob(job)\n if (!succeeded && tray.error.value) emit('error', tray.error.value)\n}\n\nasync function deleteJob(job: JobState): Promise<void> {\n const succeeded = await tray.deleteJob(job)\n if (!succeeded && tray.error.value) emit('error', tray.error.value)\n}\n\nasync function clearFinished(): Promise<void> {\n const succeeded = await tray.clearFinished()\n if (!succeeded && tray.error.value) emit('error', tray.error.value)\n}\n</script>\n\n<template>\n <Teleport :to=\"teleportTarget\" :disabled=\"teleportTo === false\">\n <div class=\"mint-jobs-tray\">\n <button\n ref=\"triggerRef\"\n type=\"button\"\n class=\"mint-jobs-tray__trigger\"\n aria-haspopup=\"dialog\"\n :aria-expanded=\"tray.isOpen.value\"\n :aria-controls=\"panelId\"\n @click=\"toggleTray\"\n >\n <svg\n class=\"mint-jobs-tray__trigger-icon\"\n :class=\"{ 'mint-jobs-tray__trigger-icon--active': tray.activeJobs.value.length > 0 }\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path d=\"M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2\" />\n <path d=\"M9 5a3 3 0 0 1 6 0v2H9V5Z\" />\n </svg>\n <span class=\"mint-jobs-tray__trigger-label\">\n {{ tray.featuredJob.value ? jobStatusLabel(tray.featuredJob.value.status) : 'Jobs' }}\n </span>\n <span\n v-if=\"tray.activeJobs.value.length > 0\"\n class=\"mint-jobs-tray__count\"\n aria-live=\"polite\"\n >\n {{ tray.activeJobs.value.length }}\n </span>\n </button>\n\n <Transition name=\"mint-jobs-tray-fade\">\n <div\n v-if=\"tray.isOpen.value\"\n class=\"mint-jobs-tray__backdrop\"\n aria-hidden=\"true\"\n @click=\"closeTray\"\n />\n </Transition>\n\n <Transition name=\"mint-jobs-tray-slide\">\n <section\n v-if=\"tray.isOpen.value\"\n :id=\"panelId\"\n ref=\"panelRef\"\n class=\"mint-jobs-tray__panel\"\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-labelledby=\"titleId\"\n tabindex=\"-1\"\n @keydown=\"onPanelKeydown\"\n >\n <header class=\"mint-jobs-tray__header\">\n <div>\n <h2 :id=\"titleId\" class=\"mint-jobs-tray__title\">{{ title }}</h2>\n <p class=\"mint-jobs-tray__subtitle\">{{ subtitle }}</p>\n </div>\n <div class=\"mint-jobs-tray__header-actions\">\n <button\n v-if=\"tray.canRefresh.value\"\n type=\"button\"\n class=\"mint-jobs-tray__icon-button\"\n aria-label=\"Refresh jobs\"\n :disabled=\"tray.isLoading.value\"\n @click=\"tray.refresh\"\n >\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M20 6v5h-5M4 18v-5h5\" />\n <path d=\"M18.4 9A7 7 0 0 0 6.1 6.1L4 8m2 7a7 7 0 0 0 11.9 2.9L20 16\" />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"mint-jobs-tray__icon-button\"\n aria-label=\"Close jobs\"\n @click=\"closeTray\"\n >\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path d=\"m6 6 12 12M18 6 6 18\" />\n </svg>\n </button>\n </div>\n </header>\n\n <div class=\"mint-jobs-tray__tabs\" role=\"tablist\" aria-label=\"Job groups\">\n <button\n type=\"button\"\n role=\"tab\"\n data-tab=\"active\"\n class=\"mint-jobs-tray__tab\"\n :class=\"{ 'mint-jobs-tray__tab--active': tray.activeTab.value === 'active' }\"\n :aria-selected=\"tray.activeTab.value === 'active'\"\n @click=\"tray.activeTab.value = 'active'\"\n >\n Active\n <span class=\"mint-jobs-tray__tab-count\">{{ tray.activeJobs.value.length }}</span>\n </button>\n <button\n type=\"button\"\n role=\"tab\"\n data-tab=\"history\"\n class=\"mint-jobs-tray__tab\"\n :class=\"{ 'mint-jobs-tray__tab--active': tray.activeTab.value === 'history' }\"\n :aria-selected=\"tray.activeTab.value === 'history'\"\n @click=\"tray.activeTab.value = 'history'\"\n >\n History\n <span class=\"mint-jobs-tray__tab-count\">{{ tray.historyJobs.value.length }}</span>\n </button>\n </div>\n\n <p v-if=\"tray.error.value\" class=\"mint-jobs-tray__error\" role=\"alert\">\n {{ tray.error.value }}\n </p>\n\n <div class=\"mint-jobs-tray__body\">\n <template v-if=\"tray.activeTab.value === 'active'\">\n <p v-if=\"tray.activeJobs.value.length === 0\" class=\"mint-jobs-tray__empty\">\n No active jobs\n </p>\n <article\n v-for=\"job in activeRows\"\n :key=\"job.job_id\"\n class=\"mint-jobs-tray__job\"\n :class=\"{ 'mint-jobs-tray__job--awaiting-input': job.status === 'awaiting_input' }\"\n >\n <div class=\"mint-jobs-tray__job-heading\">\n <div class=\"mint-jobs-tray__job-identity\">\n <button\n type=\"button\"\n class=\"mint-jobs-tray__job-select\"\n @click=\"emit('select', job)\"\n >\n {{ job.name }}\n </button>\n <span class=\"mint-jobs-tray__kind\">{{ job.kind }}</span>\n </div>\n <span class=\"mint-jobs-tray__status\" :class=\"statusClass(job)\">\n <span class=\"mint-jobs-tray__status-dot\" aria-hidden=\"true\" />\n {{ jobStatusLabel(job.status) }}\n </span>\n <span v-if=\"job.status === 'running'\" class=\"mint-jobs-tray__percent\">{{ jobPercent(job) }}%</span>\n </div>\n <div\n v-if=\"job.status === 'running'\"\n class=\"mint-jobs-tray__progress\"\n role=\"progressbar\"\n aria-label=\"Job progress\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n :aria-valuenow=\"jobPercent(job)\"\n >\n <span :style=\"{ width: `${jobPercent(job)}%` }\" />\n </div>\n <div class=\"mint-jobs-tray__job-footer\">\n <span>{{ progressText(job) }}</span>\n <div class=\"mint-jobs-tray__job-actions\">\n <slot name=\"job-actions\" :job=\"job\" />\n <button\n v-if=\"job.can_cancel && tray.canCancel.value\"\n type=\"button\"\n class=\"mint-jobs-tray__action mint-jobs-tray__action--danger\"\n aria-label=\"Cancel job\"\n :disabled=\"tray.isPending(job)\"\n @click=\"cancelJob(job)\"\n >\n Cancel\n </button>\n <button\n v-if=\"job.can_delete && tray.canDelete.value\"\n type=\"button\"\n class=\"mint-jobs-tray__icon-button mint-jobs-tray__icon-button--danger\"\n aria-label=\"Delete job\"\n :disabled=\"tray.isPending(job)\"\n @click=\"deleteJob(job)\"\n >\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M4 7h16M9 7V4h6v3m-8 0 1 13h8l1-13M10 11v5M14 11v5\" />\n </svg>\n </button>\n </div>\n </div>\n </article>\n </template>\n\n <template v-else>\n <div v-if=\"canClear\" class=\"mint-jobs-tray__clear-row\">\n <button\n type=\"button\"\n class=\"mint-jobs-tray__action mint-jobs-tray__action--danger\"\n @click=\"clearFinished\"\n >\n Clear finished\n </button>\n </div>\n <p v-if=\"tray.historyJobs.value.length === 0\" class=\"mint-jobs-tray__empty\">\n No job history\n </p>\n <article\n v-for=\"job in tray.historyJobs.value\"\n :key=\"job.job_id\"\n class=\"mint-jobs-tray__job\"\n >\n <div class=\"mint-jobs-tray__job-heading\">\n <div class=\"mint-jobs-tray__job-identity\">\n <button\n type=\"button\"\n class=\"mint-jobs-tray__job-select\"\n @click=\"emit('select', job)\"\n >\n {{ job.name }}\n </button>\n <span class=\"mint-jobs-tray__kind\">{{ job.kind }}</span>\n </div>\n <span class=\"mint-jobs-tray__status\" :class=\"statusClass(job)\">\n <span class=\"mint-jobs-tray__status-dot\" aria-hidden=\"true\" />\n {{ jobStatusLabel(job.status) }}\n </span>\n </div>\n <div class=\"mint-jobs-tray__job-footer\">\n <span>{{ formatTimestamp(job.completed_at || job.created_at) }}</span>\n <div class=\"mint-jobs-tray__job-actions\">\n <slot name=\"job-actions\" :job=\"job\" />\n <button\n v-if=\"job.can_delete && tray.canDelete.value\"\n type=\"button\"\n class=\"mint-jobs-tray__icon-button mint-jobs-tray__icon-button--danger\"\n aria-label=\"Delete job\"\n :disabled=\"tray.isPending(job)\"\n @click=\"deleteJob(job)\"\n >\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M4 7h16M9 7V4h6v3m-8 0 1 13h8l1-13M10 11v5M14 11v5\" />\n </svg>\n </button>\n </div>\n </div>\n </article>\n </template>\n </div>\n </section>\n </Transition>\n </div>\n </Teleport>\n</template>\n","<script setup lang=\"ts\">\n/**\n * Floating, source-driven job status tray for plugin and platform workflows.\n *\n * @example Recommended\n * ```vue\n * <JobsStatusTray :source=\"jobs\" />\n * ```\n */\nimport { computed, nextTick, ref, toRef, useId } from 'vue'\n\nimport {\n jobStatusLabel,\n normalizeJobPercent,\n} from '../jobs'\nimport {\n useJobCenter,\n type PluginJobCenterSource,\n} from '../composables/useJobCenter'\nimport type { JobState } from '../types/jobs'\n\ninterface Props {\n source?: PluginJobCenterSource\n loadOnMount?: boolean\n title?: string\n teleportTo?: string | HTMLElement | false\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n loadOnMount: true,\n title: 'Analysis jobs',\n teleportTo: 'body',\n})\n\nconst emit = defineEmits<{\n select: [job: JobState]\n error: [message: string]\n}>()\n\ndefineSlots<{\n /** Extra per-row actions, rendered before the built-in Cancel / Delete. */\n 'job-actions'?: (props: { job: JobState }) => unknown\n}>()\n\nconst panelId = `mint-jobs-tray-${useId().replace(/:/g, '')}`\nconst titleId = `${panelId}-title`\nconst triggerRef = ref<HTMLButtonElement | null>(null)\nconst panelRef = ref<HTMLElement | null>(null)\nconst teleportTarget = computed(() => props.teleportTo || 'body')\nconst tray = useJobCenter({\n source: toRef(props, 'source'),\n loadOnMount: props.loadOnMount,\n})\n// 2f: a job waiting for input is the only one that needs a person — pin it first.\nconst activeRows = computed(() => [\n ...tray.activeJobs.value.filter(job => job.status === 'awaiting_input'),\n ...tray.activeJobs.value.filter(job => job.status !== 'awaiting_input'),\n])\nconst subtitle = computed(() => {\n const count = (status: JobState['status']) => tray.activeJobs.value.filter(job => job.status === status).length\n const parts = [\n [count('running'), 'running'],\n [count('queued'), 'queued'],\n [count('awaiting_input'), 'waiting'],\n ].filter(([n]) => n).map(([n, word]) => `${n} ${word}`)\n return parts.length ? parts.join(' · ') : `${tray.jobs.value.length} total`\n})\nconst canClear = computed(() => (\n tray.deletableJobs.value.length > 0\n && tray.canClearFinished.value\n))\n\nasync function openTray(): Promise<void> {\n tray.open()\n await nextTick()\n panelRef.value?.focus()\n}\n\nasync function closeTray(): Promise<void> {\n tray.close()\n await nextTick()\n triggerRef.value?.focus()\n}\n\nasync function toggleTray(): Promise<void> {\n if (tray.isOpen.value) await closeTray()\n else await openTray()\n}\n\nfunction onPanelKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n void closeTray()\n return\n }\n if (event.key !== 'Tab' || !panelRef.value) return\n const focusable = Array.from(panelRef.value.querySelectorAll<HTMLElement>(\n 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])',\n ))\n if (focusable.length === 0) {\n event.preventDefault()\n panelRef.value.focus()\n return\n }\n const first = focusable[0]\n const last = focusable[focusable.length - 1]\n const activeElement = document.activeElement as HTMLElement | null\n if (!activeElement || !focusable.includes(activeElement)) {\n event.preventDefault()\n if (event.shiftKey) last?.focus()\n else first?.focus()\n } else if (event.shiftKey && activeElement === first) {\n event.preventDefault()\n last?.focus()\n } else if (!event.shiftKey && activeElement === last) {\n event.preventDefault()\n first?.focus()\n }\n}\n\nfunction progressText(job: JobState): string {\n if (job.status === 'awaiting_input') {\n return job.progress.message || 'Waiting for external input'\n }\n if (job.status === 'queued' && job.queue_position > 0) {\n return `Queue position ${job.queue_position}`\n }\n return job.progress.message || job.progress.stage || jobStatusLabel(job.status)\n}\n\nfunction formatTimestamp(value: string | null): string {\n if (!value) return ''\n const date = new Date(value)\n return Number.isNaN(date.getTime())\n ? ''\n : new Intl.DateTimeFormat(undefined, { dateStyle: 'medium', timeStyle: 'short' }).format(date)\n}\n\nfunction statusClass(job: JobState): string {\n return `mint-jobs-tray__status--${job.status.replace('_', '-')}`\n}\n\nfunction jobPercent(job: JobState): number {\n return Math.round(normalizeJobPercent(job.progress.percent))\n}\n\nasync function cancelJob(job: JobState): Promise<void> {\n const succeeded = await tray.cancelJob(job)\n if (!succeeded && tray.error.value) emit('error', tray.error.value)\n}\n\nasync function deleteJob(job: JobState): Promise<void> {\n const succeeded = await tray.deleteJob(job)\n if (!succeeded && tray.error.value) emit('error', tray.error.value)\n}\n\nasync function clearFinished(): Promise<void> {\n const succeeded = await tray.clearFinished()\n if (!succeeded && tray.error.value) emit('error', tray.error.value)\n}\n</script>\n\n<template>\n <Teleport :to=\"teleportTarget\" :disabled=\"teleportTo === false\">\n <div class=\"mint-jobs-tray\">\n <button\n ref=\"triggerRef\"\n type=\"button\"\n class=\"mint-jobs-tray__trigger\"\n aria-haspopup=\"dialog\"\n :aria-expanded=\"tray.isOpen.value\"\n :aria-controls=\"panelId\"\n @click=\"toggleTray\"\n >\n <svg\n class=\"mint-jobs-tray__trigger-icon\"\n :class=\"{ 'mint-jobs-tray__trigger-icon--active': tray.activeJobs.value.length > 0 }\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path d=\"M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2\" />\n <path d=\"M9 5a3 3 0 0 1 6 0v2H9V5Z\" />\n </svg>\n <span class=\"mint-jobs-tray__trigger-label\">\n {{ tray.featuredJob.value ? jobStatusLabel(tray.featuredJob.value.status) : 'Jobs' }}\n </span>\n <span\n v-if=\"tray.activeJobs.value.length > 0\"\n class=\"mint-jobs-tray__count\"\n aria-live=\"polite\"\n >\n {{ tray.activeJobs.value.length }}\n </span>\n </button>\n\n <Transition name=\"mint-jobs-tray-fade\">\n <div\n v-if=\"tray.isOpen.value\"\n class=\"mint-jobs-tray__backdrop\"\n aria-hidden=\"true\"\n @click=\"closeTray\"\n />\n </Transition>\n\n <Transition name=\"mint-jobs-tray-slide\">\n <section\n v-if=\"tray.isOpen.value\"\n :id=\"panelId\"\n ref=\"panelRef\"\n class=\"mint-jobs-tray__panel\"\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-labelledby=\"titleId\"\n tabindex=\"-1\"\n @keydown=\"onPanelKeydown\"\n >\n <header class=\"mint-jobs-tray__header\">\n <div>\n <h2 :id=\"titleId\" class=\"mint-jobs-tray__title\">{{ title }}</h2>\n <p class=\"mint-jobs-tray__subtitle\">{{ subtitle }}</p>\n </div>\n <div class=\"mint-jobs-tray__header-actions\">\n <button\n v-if=\"tray.canRefresh.value\"\n type=\"button\"\n class=\"mint-jobs-tray__icon-button\"\n aria-label=\"Refresh jobs\"\n :disabled=\"tray.isLoading.value\"\n @click=\"tray.refresh\"\n >\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M20 6v5h-5M4 18v-5h5\" />\n <path d=\"M18.4 9A7 7 0 0 0 6.1 6.1L4 8m2 7a7 7 0 0 0 11.9 2.9L20 16\" />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"mint-jobs-tray__icon-button\"\n aria-label=\"Close jobs\"\n @click=\"closeTray\"\n >\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path d=\"m6 6 12 12M18 6 6 18\" />\n </svg>\n </button>\n </div>\n </header>\n\n <div class=\"mint-jobs-tray__tabs\" role=\"tablist\" aria-label=\"Job groups\">\n <button\n type=\"button\"\n role=\"tab\"\n data-tab=\"active\"\n class=\"mint-jobs-tray__tab\"\n :class=\"{ 'mint-jobs-tray__tab--active': tray.activeTab.value === 'active' }\"\n :aria-selected=\"tray.activeTab.value === 'active'\"\n @click=\"tray.activeTab.value = 'active'\"\n >\n Active\n <span class=\"mint-jobs-tray__tab-count\">{{ tray.activeJobs.value.length }}</span>\n </button>\n <button\n type=\"button\"\n role=\"tab\"\n data-tab=\"history\"\n class=\"mint-jobs-tray__tab\"\n :class=\"{ 'mint-jobs-tray__tab--active': tray.activeTab.value === 'history' }\"\n :aria-selected=\"tray.activeTab.value === 'history'\"\n @click=\"tray.activeTab.value = 'history'\"\n >\n History\n <span class=\"mint-jobs-tray__tab-count\">{{ tray.historyJobs.value.length }}</span>\n </button>\n </div>\n\n <p v-if=\"tray.error.value\" class=\"mint-jobs-tray__error\" role=\"alert\">\n {{ tray.error.value }}\n </p>\n\n <div class=\"mint-jobs-tray__body\">\n <template v-if=\"tray.activeTab.value === 'active'\">\n <p v-if=\"tray.activeJobs.value.length === 0\" class=\"mint-jobs-tray__empty\">\n No active jobs\n </p>\n <article\n v-for=\"job in activeRows\"\n :key=\"job.job_id\"\n class=\"mint-jobs-tray__job\"\n :class=\"{ 'mint-jobs-tray__job--awaiting-input': job.status === 'awaiting_input' }\"\n >\n <div class=\"mint-jobs-tray__job-heading\">\n <div class=\"mint-jobs-tray__job-identity\">\n <button\n type=\"button\"\n class=\"mint-jobs-tray__job-select\"\n @click=\"emit('select', job)\"\n >\n {{ job.name }}\n </button>\n <span class=\"mint-jobs-tray__kind\">{{ job.kind }}</span>\n </div>\n <span class=\"mint-jobs-tray__status\" :class=\"statusClass(job)\">\n <span class=\"mint-jobs-tray__status-dot\" aria-hidden=\"true\" />\n {{ jobStatusLabel(job.status) }}\n </span>\n <span v-if=\"job.status === 'running'\" class=\"mint-jobs-tray__percent\">{{ jobPercent(job) }}%</span>\n </div>\n <div\n v-if=\"job.status === 'running'\"\n class=\"mint-jobs-tray__progress\"\n role=\"progressbar\"\n aria-label=\"Job progress\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n :aria-valuenow=\"jobPercent(job)\"\n >\n <span :style=\"{ width: `${jobPercent(job)}%` }\" />\n </div>\n <div class=\"mint-jobs-tray__job-footer\">\n <span>{{ progressText(job) }}</span>\n <div class=\"mint-jobs-tray__job-actions\">\n <slot name=\"job-actions\" :job=\"job\" />\n <button\n v-if=\"job.can_cancel && tray.canCancel.value\"\n type=\"button\"\n class=\"mint-jobs-tray__action mint-jobs-tray__action--danger\"\n aria-label=\"Cancel job\"\n :disabled=\"tray.isPending(job)\"\n @click=\"cancelJob(job)\"\n >\n Cancel\n </button>\n <button\n v-if=\"job.can_delete && tray.canDelete.value\"\n type=\"button\"\n class=\"mint-jobs-tray__icon-button mint-jobs-tray__icon-button--danger\"\n aria-label=\"Delete job\"\n :disabled=\"tray.isPending(job)\"\n @click=\"deleteJob(job)\"\n >\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M4 7h16M9 7V4h6v3m-8 0 1 13h8l1-13M10 11v5M14 11v5\" />\n </svg>\n </button>\n </div>\n </div>\n </article>\n </template>\n\n <template v-else>\n <div v-if=\"canClear\" class=\"mint-jobs-tray__clear-row\">\n <button\n type=\"button\"\n class=\"mint-jobs-tray__action mint-jobs-tray__action--danger\"\n @click=\"clearFinished\"\n >\n Clear finished\n </button>\n </div>\n <p v-if=\"tray.historyJobs.value.length === 0\" class=\"mint-jobs-tray__empty\">\n No job history\n </p>\n <article\n v-for=\"job in tray.historyJobs.value\"\n :key=\"job.job_id\"\n class=\"mint-jobs-tray__job\"\n >\n <div class=\"mint-jobs-tray__job-heading\">\n <div class=\"mint-jobs-tray__job-identity\">\n <button\n type=\"button\"\n class=\"mint-jobs-tray__job-select\"\n @click=\"emit('select', job)\"\n >\n {{ job.name }}\n </button>\n <span class=\"mint-jobs-tray__kind\">{{ job.kind }}</span>\n </div>\n <span class=\"mint-jobs-tray__status\" :class=\"statusClass(job)\">\n <span class=\"mint-jobs-tray__status-dot\" aria-hidden=\"true\" />\n {{ jobStatusLabel(job.status) }}\n </span>\n </div>\n <div class=\"mint-jobs-tray__job-footer\">\n <span>{{ formatTimestamp(job.completed_at || job.created_at) }}</span>\n <div class=\"mint-jobs-tray__job-actions\">\n <slot name=\"job-actions\" :job=\"job\" />\n <button\n v-if=\"job.can_delete && tray.canDelete.value\"\n type=\"button\"\n class=\"mint-jobs-tray__icon-button mint-jobs-tray__icon-button--danger\"\n aria-label=\"Delete job\"\n :disabled=\"tray.isPending(job)\"\n @click=\"deleteJob(job)\"\n >\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M4 7h16M9 7V4h6v3m-8 0 1 13h8l1-13M10 11v5M14 11v5\" />\n </svg>\n </button>\n </div>\n </div>\n </article>\n </template>\n </div>\n </section>\n </Transition>\n </div>\n </Teleport>\n</template>\n","import {\n getCurrentScope,\n onScopeDispose,\n readonly,\n ref,\n toValue,\n watch,\n type MaybeRefOrGetter,\n type Ref,\n} from 'vue'\n\n/**\n * One event of the platform's realtime stream (`GET /api/events`).\n *\n * Platform events carry no entity data: refetch the entity through REST.\n * `type` is `resync` (refetch everything you show), the audit action of a\n * committed write, such as `experiment.update` or `analysis.artifact_create`,\n * or the `\"<plugin>.<event>\"` name of a plugin event, which carries `payload`.\n * Only `usePresence` receives `presence.changed`.\n */\nexport interface RealtimeEvent {\n type: string\n id?: string\n /**\n * `experiment:{id}`, `project:{id}`, `experiments`, `user:{id}`, or a plugin's\n * `plugin:{name}` / `plugin:{name}:experiment:{id}`; absent on `resync`.\n */\n topic?: string\n /** A plugin event: the JSON payload the plugin published (at most 16 KiB). */\n payload?: unknown\n /** Changed fields of an update, when the write names them. */\n fields?: string[] | null\n actor_id?: string | null\n request_id?: string | null\n at?: string\n /** `presence.changed`: the topic's viewers (at most 20, `editing` first). */\n viewers?: { user_id: string, activity: string }[]\n /** `presence.changed`: the number of viewers, also those beyond `viewers`. */\n count?: number\n}\n\nexport type RealtimeHandler = (event: RealtimeEvent) => void\n\nexport interface UseRealtimeReturn {\n /** True while the shared stream is open. */\n connected: Readonly<Ref<boolean>>\n /** Unsubscribe; also runs when the calling component or effect scope is disposed. */\n stop: () => void\n}\n\nconst EVENTS_URL = '/api/events'\nconst RECONNECT_BASE_MS = 1_000\nconst RECONNECT_MAX_MS = 30_000\n/** Merges the subscriptions of components that mount together into one connection. */\nconst TOPIC_DEBOUNCE_MS = 50\nconst RESYNC: RealtimeEvent = { type: 'resync' }\n\ninterface Listener {\n topics: () => string[]\n handler: RealtimeHandler\n /** Receives `presence.changed`; a write listener would refetch on each viewer change. */\n presence: boolean\n}\n\nconst listeners = new Set<Listener>()\n/** The last `presence.changed` of each topic of the open stream; the server sends one per topic at open. */\nconst presence = new Map<string, RealtimeEvent>()\nconst connected = ref(false)\nlet source: EventSource | null = null\nlet sourceTopics = ''\nlet failures = 0\nlet syncTimer: ReturnType<typeof setTimeout> | null = null\nlet retryTimer: ReturnType<typeof setTimeout> | null = null\n\nfunction dispatch(event: RealtimeEvent): void {\n const isPresence = event.type === 'presence.changed'\n if (isPresence && event.topic) presence.set(event.topic, event)\n for (const listener of [...listeners]) {\n if (isPresence && !listener.presence) continue\n if (event.type === 'resync' || (event.topic && listener.topics().includes(event.topic))) {\n listener.handler(event)\n }\n }\n}\n\nfunction close(): void {\n source?.close()\n source = null\n sourceTopics = ''\n presence.clear()\n connected.value = false\n}\n\nfunction open(topics: string): void {\n const stream = new EventSource(`${EVENTS_URL}?topics=${encodeURIComponent(topics)}`)\n source = stream\n sourceTopics = topics\n stream.onopen = () => {\n connected.value = true\n // The server subscribes only now: a write between a caller's REST load (or\n // the close of the previous stream) and this point sent no event, so every caller refetches.\n dispatch(RESYNC)\n failures = 0\n }\n stream.onmessage = (message) => {\n dispatch(JSON.parse(message.data) as RealtimeEvent)\n }\n stream.onerror = () => {\n // EventSource retries a dropped connection itself but gives up after an\n // HTTP error, so one backoff path handles both.\n if (source !== stream) return\n close()\n // A topic change during the wait does not shorten it: the retry reads the topics when it runs.\n if (syncTimer !== null) clearTimeout(syncTimer)\n syncTimer = null\n retryTimer = setTimeout(() => {\n retryTimer = null\n sync()\n }, Math.min(RECONNECT_MAX_MS, RECONNECT_BASE_MS * 2 ** failures))\n failures += 1\n }\n}\n\nfunction sync(): void {\n syncTimer = null\n const topics = [...new Set([...listeners].flatMap(listener => listener.topics()))].sort().join(',')\n if (source && topics === sourceTopics) return\n close()\n if (topics) open(topics)\n}\n\nfunction schedule(): void {\n if (retryTimer !== null) return\n if (syncTimer !== null) clearTimeout(syncTimer)\n syncTimer = setTimeout(sync, TOPIC_DEBOUNCE_MS)\n}\n\n/**\n * Subscribe to topics of the platform's realtime stream.\n *\n * Every caller in a tab shares one `EventSource`, opened on the union of\n * their topics and reopened when that union changes. `handler` receives the\n * write events of the caller's own topics (not `presence.changed`, which goes\n * to `usePresence`) plus every `resync`: one comes from the\n * server when this tab fell behind, and one follows each open of the stream:\n * the first open, each reconnect (backoff from 1 s to 30 s) and each reopen for\n * a changed topic union. On `resync`, refetch. The union of all callers' topics\n * in a tab may hold at most 50 topics; the platform refuses a larger stream.\n *\n * The stream authenticates with the session cookie, so it works in the\n * platform and in plugin frontends served by it. It exists only when the\n * platform's `realtime` feature flag is on; check that flag first.\n *\n * A plugin topic reaches a caller whose role may use the plugin; an\n * experiment plugin topic also needs a caller who may view the experiment.\n *\n * @example\n * useRealtime(() => [`experiment:${id.value}`], () => refetch())\n * @example\n * useRealtime(['plugin:drp'], (event) => {\n * if (event.type === 'drp.run.progress') progress.value = event.payload as RunProgress\n * })\n */\nexport function useRealtime(\n topics: MaybeRefOrGetter<string[]>,\n handler: RealtimeHandler,\n): UseRealtimeReturn {\n return subscribeRealtime(topics, handler, false)\n}\n\n/** The last `presence.changed` of `topic` while the open stream views it (for `usePresence`). */\nexport function currentPresence(topic: string): RealtimeEvent | undefined {\n return presence.get(topic)\n}\n\n/** `useRealtime`, and with `withPresence` also the `presence.changed` events (for `usePresence`). */\nexport function subscribeRealtime(\n topics: MaybeRefOrGetter<string[]>,\n handler: RealtimeHandler,\n withPresence: boolean,\n): UseRealtimeReturn {\n const listener: Listener = { topics: () => toValue(topics), handler, presence: withPresence }\n listeners.add(listener)\n const stopWatch = watch(() => listener.topics().join(','), () => schedule())\n schedule()\n\n function stop(): void {\n stopWatch()\n if (listeners.delete(listener)) schedule()\n }\n\n if (getCurrentScope()) onScopeDispose(stop)\n return { connected: readonly(connected), stop }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { r as readErrorMessage } from "./experiment-43OJtH7R.js";
|
|
2
|
+
import { ref } from "vue";
|
|
3
|
+
//#region src/composables/useRequest.ts
|
|
4
|
+
/** Loading, error and timestamp state for one request at a time; `run()` drives it. */
|
|
5
|
+
function useRequest(defaultErrorMessage = "Request failed.") {
|
|
6
|
+
const isLoading = ref(false);
|
|
7
|
+
const error = ref(null);
|
|
8
|
+
const lastLoadedAt = ref(null);
|
|
9
|
+
const lastSavedAt = ref(null);
|
|
10
|
+
const lastRunAt = ref(null);
|
|
11
|
+
function clearError() {
|
|
12
|
+
error.value = null;
|
|
13
|
+
}
|
|
14
|
+
function readErrorMessage$1(value, fallback = defaultErrorMessage) {
|
|
15
|
+
return readErrorMessage(value, fallback);
|
|
16
|
+
}
|
|
17
|
+
function setError(value, fallback) {
|
|
18
|
+
const message = readErrorMessage$1(value, fallback);
|
|
19
|
+
error.value = message;
|
|
20
|
+
return message;
|
|
21
|
+
}
|
|
22
|
+
let runToken = 0;
|
|
23
|
+
let activeController = null;
|
|
24
|
+
function cancel() {
|
|
25
|
+
runToken += 1;
|
|
26
|
+
activeController?.abort();
|
|
27
|
+
activeController = null;
|
|
28
|
+
isLoading.value = false;
|
|
29
|
+
}
|
|
30
|
+
async function run(operation, options = {}) {
|
|
31
|
+
if (options.abortPrevious !== false) activeController?.abort();
|
|
32
|
+
const token = runToken += 1;
|
|
33
|
+
const controller = new AbortController();
|
|
34
|
+
activeController = controller;
|
|
35
|
+
const callerSignal = options.signal;
|
|
36
|
+
if (callerSignal) {
|
|
37
|
+
if (callerSignal.aborted) controller.abort(callerSignal.reason);
|
|
38
|
+
else callerSignal.addEventListener("abort", () => controller.abort(callerSignal.reason), { once: true });
|
|
39
|
+
}
|
|
40
|
+
const isCurrent = () => token === runToken;
|
|
41
|
+
isLoading.value = true;
|
|
42
|
+
clearError();
|
|
43
|
+
try {
|
|
44
|
+
const response = await operation(controller.signal);
|
|
45
|
+
if (isCurrent() && options.kind) {
|
|
46
|
+
const settledAt = /* @__PURE__ */ new Date();
|
|
47
|
+
if (options.kind === "load") lastLoadedAt.value = settledAt;
|
|
48
|
+
else if (options.kind === "save") lastSavedAt.value = settledAt;
|
|
49
|
+
else lastRunAt.value = settledAt;
|
|
50
|
+
}
|
|
51
|
+
return response;
|
|
52
|
+
} catch (err) {
|
|
53
|
+
if (isCurrent()) setError(err, options.errorMessage);
|
|
54
|
+
throw err;
|
|
55
|
+
} finally {
|
|
56
|
+
if (isCurrent()) isLoading.value = false;
|
|
57
|
+
if (activeController === controller) activeController = null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
isLoading,
|
|
62
|
+
error,
|
|
63
|
+
lastLoadedAt,
|
|
64
|
+
lastSavedAt,
|
|
65
|
+
lastRunAt,
|
|
66
|
+
clearError,
|
|
67
|
+
readErrorMessage: readErrorMessage$1,
|
|
68
|
+
setError,
|
|
69
|
+
run,
|
|
70
|
+
cancel
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
//#endregion
|
|
74
|
+
export { useRequest as t };
|
|
75
|
+
|
|
76
|
+
//# sourceMappingURL=useRequest-D5JDfsgZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRequest-D5JDfsgZ.js","names":[],"sources":["../src/composables/useRequest.ts"],"sourcesContent":["import { ref, type Ref } from 'vue'\nimport { readErrorMessage as readSharedErrorMessage } from '../utils/errors'\n\nexport type RequestKind = 'load' | 'save' | 'run'\n\n/**\n * The unit of work `run()` drives.\n *\n * It receives an `AbortSignal` that fires when the run is superseded by a\n * newer `run()` or by `cancel()`. Zero-argument operations stay valid and\n * simply ignore it.\n */\nexport type RequestOperation<T> = (signal: AbortSignal) => Promise<T>\n\nexport interface RequestRunOptions {\n /** Which timestamp a successful run moves: `lastLoadedAt`, `lastSavedAt` or `lastRunAt`. */\n kind?: RequestKind\n errorMessage?: string\n /**\n * Abort the previously started run when this one starts. Default `true`;\n * pass `false` to let overlapping runs finish their own work (the stale\n * guard on shared state still applies either way).\n */\n abortPrevious?: boolean\n /** Caller-owned signal; aborting it aborts this run's signal too. */\n signal?: AbortSignal\n}\n\nexport interface UseRequestReturn {\n /** Whether a request is in progress. */\n isLoading: Ref<boolean>\n /** Message from the last failed request, or null. */\n error: Ref<string | null>\n /** Timestamp of the last successful load operation, or null. */\n lastLoadedAt: Ref<Date | null>\n /** Timestamp of the last successful save operation, or null. */\n lastSavedAt: Ref<Date | null>\n /** Timestamp of the last successful run operation, or null. */\n lastRunAt: Ref<Date | null>\n /** Clear the current error without changing loading or timestamps. */\n clearError: () => void\n /** Convert thrown values into a developer-facing error message. */\n readErrorMessage: (value: unknown, fallback?: string) => string\n /** Store and return a normalized error message. */\n setError: (value: unknown, fallback?: string) => string\n /**\n * Run a request with shared loading/error handling and optional sync marking.\n *\n * ## Stale-response semantics\n *\n * Every call takes a monotonically increasing token. Starting a run\n * supersedes any run started before it, and a superseded run writes **no**\n * shared state when it finally settles: it does not clear `isLoading`, does not\n * set `error`, and does not move `lastLoadedAt` / `lastSavedAt` / `lastRunAt`.\n * Only the newest run owns those.\n *\n * The caller's own promise is untouched by the guard — a superseded run still\n * resolves with its value or rejects with its own error, exactly as the\n * operation did. The guard never invents a rejection, so a caller awaiting\n * `run()` never sees a \"superseded\" error it did not cause.\n *\n * The operation additionally receives an `AbortSignal` that fires when its\n * run is superseded or `cancel()` is called, so an operation that forwards\n * the signal (`fetch(url, { signal })`) stops work instead of racing.\n */\n run: <T>(operation: RequestOperation<T>, options?: RequestRunOptions) => Promise<T>\n /**\n * Abort the in-flight run and drop `isLoading`. The aborted run's completion\n * is treated as stale and writes no state.\n */\n cancel: () => void\n}\n\n/** Loading, error and timestamp state for one request at a time; `run()` drives it. */\nexport function useRequest(\n defaultErrorMessage = 'Request failed.',\n): UseRequestReturn {\n const isLoading = ref(false)\n const error = ref<string | null>(null)\n const lastLoadedAt = ref<Date | null>(null)\n const lastSavedAt = ref<Date | null>(null)\n const lastRunAt = ref<Date | null>(null)\n\n function clearError(): void {\n error.value = null\n }\n\n function readErrorMessage(value: unknown, fallback = defaultErrorMessage): string {\n return readSharedErrorMessage(value, fallback)\n }\n\n function setError(value: unknown, fallback?: string): string {\n const message = readErrorMessage(value, fallback)\n error.value = message\n return message\n }\n\n // Monotonic token guarding every write to the shared loading/error/timestamp\n // state. Overlapping runs settle in any order, and a superseded one must not\n // clear a newer run's loading flag or overwrite its error.\n let runToken = 0\n let activeController: AbortController | null = null\n\n function cancel(): void {\n runToken += 1\n activeController?.abort()\n activeController = null\n isLoading.value = false\n }\n\n async function run<T>(\n operation: RequestOperation<T>,\n options: RequestRunOptions = {},\n ): Promise<T> {\n if (options.abortPrevious !== false) {\n activeController?.abort()\n }\n\n const token = (runToken += 1)\n const controller = new AbortController()\n activeController = controller\n\n const callerSignal = options.signal\n if (callerSignal) {\n if (callerSignal.aborted) controller.abort(callerSignal.reason)\n else callerSignal.addEventListener(\n 'abort',\n () => controller.abort(callerSignal.reason),\n { once: true },\n )\n }\n\n const isCurrent = (): boolean => token === runToken\n\n isLoading.value = true\n clearError()\n try {\n const response = await operation(controller.signal)\n if (isCurrent() && options.kind) {\n const settledAt = new Date()\n if (options.kind === 'load') lastLoadedAt.value = settledAt\n else if (options.kind === 'save') lastSavedAt.value = settledAt\n else lastRunAt.value = settledAt\n }\n return response\n } catch (err) {\n if (isCurrent()) {\n setError(err, options.errorMessage)\n }\n throw err\n } finally {\n if (isCurrent()) {\n isLoading.value = false\n }\n if (activeController === controller) {\n activeController = null\n }\n }\n }\n\n return {\n isLoading,\n error,\n lastLoadedAt,\n lastSavedAt,\n lastRunAt,\n clearError,\n readErrorMessage,\n setError,\n run,\n cancel,\n }\n}\n"],"mappings":";;;;AA0EA,SAAgB,WACd,sBAAsB,mBACJ;CAClB,MAAM,YAAY,IAAI,KAAK;CAC3B,MAAM,QAAQ,IAAmB,IAAI;CACrC,MAAM,eAAe,IAAiB,IAAI;CAC1C,MAAM,cAAc,IAAiB,IAAI;CACzC,MAAM,YAAY,IAAiB,IAAI;CAEvC,SAAS,aAAmB;EAC1B,MAAM,QAAQ;CAChB;CAEA,SAAS,mBAAiB,OAAgB,WAAW,qBAA6B;EAChF,OAAO,iBAAuB,OAAO,QAAQ;CAC/C;CAEA,SAAS,SAAS,OAAgB,UAA2B;EAC3D,MAAM,UAAU,mBAAiB,OAAO,QAAQ;EAChD,MAAM,QAAQ;EACd,OAAO;CACT;CAKA,IAAI,WAAW;CACf,IAAI,mBAA2C;CAE/C,SAAS,SAAe;EACtB,YAAY;EACZ,kBAAkB,MAAM;EACxB,mBAAmB;EACnB,UAAU,QAAQ;CACpB;CAEA,eAAe,IACb,WACA,UAA6B,CAAC,GAClB;EACZ,IAAI,QAAQ,kBAAkB,OAC5B,kBAAkB,MAAM;EAG1B,MAAM,QAAS,YAAY;EAC3B,MAAM,aAAa,IAAI,gBAAgB;EACvC,mBAAmB;EAEnB,MAAM,eAAe,QAAQ;EAC7B,IAAI,cAAc;GAChB,IAAI,aAAa,SAAS,WAAW,MAAM,aAAa,MAAM;QACzD,aAAa,iBAChB,eACM,WAAW,MAAM,aAAa,MAAM,GAC1C,EAAE,MAAM,KAAK,CACf;EACF;EAEA,MAAM,kBAA2B,UAAU;EAE3C,UAAU,QAAQ;EAClB,WAAW;EACX,IAAI;GACF,MAAM,WAAW,MAAM,UAAU,WAAW,MAAM;GAClD,IAAI,UAAU,KAAK,QAAQ,MAAM;IAC/B,MAAM,4BAAY,IAAI,KAAK;IAC3B,IAAI,QAAQ,SAAS,QAAQ,aAAa,QAAQ;SAC7C,IAAI,QAAQ,SAAS,QAAQ,YAAY,QAAQ;SACjD,UAAU,QAAQ;GACzB;GACA,OAAO;EACT,SAAS,KAAK;GACZ,IAAI,UAAU,GACZ,SAAS,KAAK,QAAQ,YAAY;GAEpC,MAAM;EACR,UAAU;GACR,IAAI,UAAU,GACZ,UAAU,QAAQ;GAEpB,IAAI,qBAAqB,YACvB,mBAAmB;EAEvB;CACF;CAEA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA,kBAAA;EACA;EACA;EACA;CACF;AACF"}
|
package/dist/utils/color.d.ts
CHANGED
|
@@ -9,11 +9,6 @@ export declare const SAMPLE_COLOR_SCALE: readonly string[];
|
|
|
9
9
|
* `--mint-sample-8`; the 9th (gray) stays out of the group cycle.
|
|
10
10
|
*/
|
|
11
11
|
export declare const SAMPLE_GROUP_TOKENS: readonly string[];
|
|
12
|
-
/**
|
|
13
|
-
* Slot-position colors (R/G/B/Y rack positions).
|
|
14
|
-
* Mirrors `--mint-slot-r`, `--mint-slot-g`, `--mint-slot-b`, `--mint-slot-y`.
|
|
15
|
-
*/
|
|
16
|
-
export declare const SLOT_COLORS: Record<SlotPosition, string>;
|
|
17
12
|
/** Slot positions in their canonical display order. */
|
|
18
13
|
export declare const SLOT_ORDER: readonly SlotPosition[];
|
|
19
14
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ConcentrationValue, MolarityUnit, MassVolumeUnit } from '
|
|
1
|
+
import { ConcentrationValue, MolarityUnit, MassVolumeUnit } from '../composables/useConcentrationUnits';
|
|
2
2
|
export type VolumeUnit = 'µL' | 'mL' | 'L';
|
|
3
3
|
export interface VolumeValue {
|
|
4
4
|
value: number;
|
|
@@ -44,15 +44,12 @@ export interface WellConcentration {
|
|
|
44
44
|
concentration: ConcentrationValue;
|
|
45
45
|
volume?: VolumeValue;
|
|
46
46
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
/** Calculates single dilutions, serial dilution series, and plate-filling volumes for dose-response experiments. */
|
|
58
|
-
export declare function useDoseCalculator(): UseDoseCalculatorReturn;
|
|
47
|
+
/** Volume units, smallest first. */
|
|
48
|
+
export declare const volumeUnits: VolumeUnit[];
|
|
49
|
+
export declare function convertVolume(value: number, from: VolumeUnit, to: VolumeUnit): number;
|
|
50
|
+
export declare function formatVolume(volume: VolumeValue, precision?: number): string;
|
|
51
|
+
export declare function calculateDilution(params: DilutionParams): DilutionResult;
|
|
52
|
+
export declare function calculateSerialDilution(params: SerialDilutionParams): SerialDilutionResult;
|
|
53
|
+
export declare function convertMassToMolar(mass: number, massUnit: MassVolumeUnit, mw: number): ConcentrationValue;
|
|
54
|
+
export declare function convertMolarToMass(molar: number, molarUnit: MolarityUnit, mw: number): ConcentrationValue;
|
|
55
|
+
export declare function generateWellConcentrations(result: SerialDilutionResult, wellIds: string[]): WellConcentration[];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ExperimentStatus, Tone, SelectOption } from '../types';
|
|
2
|
+
/** Status filter options, led by "All statuses". */
|
|
3
|
+
export declare const OPTIONS: SelectOption<string>[];
|
|
4
|
+
export declare const TONES: Record<ExperimentStatus, Tone>;
|
|
5
|
+
export declare const LABELS: Record<ExperimentStatus, string>;
|
|
6
|
+
/** Label for a status; an unknown status is shown in sentence case. */
|
|
7
|
+
export declare function format(status?: ExperimentStatus | string | null): string;
|
|
8
|
+
/** Tone for a status; `neutral` for an unknown status. */
|
|
9
|
+
export declare function tone(status?: ExperimentStatus | string | null): Tone;
|
|
@@ -14,9 +14,6 @@ export interface FormulaPart {
|
|
|
14
14
|
text: string;
|
|
15
15
|
}
|
|
16
16
|
export declare const ATOMIC_WEIGHTS: Record<string, number>;
|
|
17
|
-
|
|
18
|
-
export declare function
|
|
19
|
-
|
|
20
|
-
calculateMW: (elements: Record<string, number>) => number;
|
|
21
|
-
renderFormulaParts: (formula: string) => FormulaPart[];
|
|
22
|
-
};
|
|
17
|
+
export declare function parseFormula(formula: string): FormulaParseResult;
|
|
18
|
+
export declare function calculateMW(elements: Record<string, number>): number;
|
|
19
|
+
export declare function renderFormulaParts(formula: string): FormulaPart[];
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** What the SDK experiment store gives the platform integration script. */
|
|
2
|
+
export interface ExperimentStoreBinding {
|
|
3
|
+
/** The experiment id the store holds, or `null`. */
|
|
4
|
+
currentId(): number | null;
|
|
5
|
+
/** Resolve the experiment from the platform and make it the current one. */
|
|
6
|
+
selectById(id: number): Promise<unknown>;
|
|
7
|
+
/** Call `listener` with the new id each time the current experiment changes. */
|
|
8
|
+
onChange(listener: (id: number | null) => void): void;
|
|
9
|
+
}
|
|
10
|
+
/** The platform side of the plugin page integration (`window.__MINT_INTEGRATION__`). */
|
|
11
|
+
export interface MintIntegrationHost {
|
|
12
|
+
/** Connect the experiment store: the host writes the experiment in the URL into it and writes its changes back to the URL. */
|
|
13
|
+
bindExperimentStore(binding: ExperimentStoreBinding): void;
|
|
14
|
+
/** Render the platform page selector into `element`. Returns the function that removes it. */
|
|
15
|
+
mountPageSelector(element: HTMLElement): () => void;
|
|
16
|
+
}
|
|
17
|
+
/** The integration host of this page, or `undefined` outside a platform-served plugin page. */
|
|
18
|
+
export declare function integrationHost(): MintIntegrationHost | undefined;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import { Template } from 'plotly.js-dist-min';
|
|
2
2
|
/** Resolve tokens from `element` (default: `<html>`), falling back to `<html>` for detached elements. */
|
|
3
3
|
export declare function mintPlotlyTemplate(element?: Element): Template;
|
|
4
|
+
/** Resolve a CSS `var()` color to its computed value on `element`; any other color passes through. */
|
|
5
|
+
export declare function resolveCssColor(color: string, element?: Element): string;
|
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
* a deliberate clear rather than the deprecated "unchanged" placeholder.
|
|
16
16
|
*/
|
|
17
17
|
/** Reserved marker key that references a stored secret. */
|
|
18
|
-
export declare const
|
|
18
|
+
export declare const REF_KEY = "$secret";
|
|
19
19
|
/** Reserved payload key declaring which secret wire format a client speaks. */
|
|
20
|
-
export declare const
|
|
20
|
+
export declare const FORMAT_KEY = "secret_format";
|
|
21
21
|
/** Wire format published and understood by this SDK. */
|
|
22
|
-
export declare const
|
|
22
|
+
export declare const FORMAT_REF = "ref";
|
|
23
23
|
/** One `$secret` marker as published by a settings response. */
|
|
24
24
|
export interface PluginSecretRef {
|
|
25
25
|
$secret: string | null;
|
|
@@ -29,25 +29,25 @@ export interface PluginSecretRef {
|
|
|
29
29
|
/** What a settings form should tell the user about one secret field. */
|
|
30
30
|
export type PluginSecretState = 'set' | 'unset' | 'environment';
|
|
31
31
|
/** Return whether one settings value is a `$secret` reference marker. */
|
|
32
|
-
export declare function
|
|
32
|
+
export declare function isRef(value: unknown): value is PluginSecretRef;
|
|
33
33
|
/** Return the stored secret id behind a marker, or `null` when nothing is stored. */
|
|
34
|
-
export declare function
|
|
34
|
+
export declare function id(value: unknown): string | null;
|
|
35
35
|
/** Classify one secret field for display: stored, unset, or environment-provided. */
|
|
36
|
-
export declare function
|
|
36
|
+
export declare function state(value: unknown): PluginSecretState;
|
|
37
37
|
/** Human label for one secret field's state. */
|
|
38
|
-
export declare function
|
|
38
|
+
export declare function label(value: unknown): string;
|
|
39
39
|
/** Whether a secret field is read-only because the environment supplies it. */
|
|
40
|
-
export declare function
|
|
40
|
+
export declare function isLocked(value: unknown): boolean;
|
|
41
41
|
/**
|
|
42
42
|
* Value to submit for an untouched secret field: the reference, unchanged.
|
|
43
43
|
*
|
|
44
44
|
* A locked marker round-trips too, which is how the platform keeps a stored
|
|
45
45
|
* value that an environment variable currently hides.
|
|
46
46
|
*/
|
|
47
|
-
export declare function
|
|
47
|
+
export declare function keep(current: unknown): PluginSecretRef | null;
|
|
48
48
|
/** Value to submit when the user typed a new secret. */
|
|
49
|
-
export declare function
|
|
49
|
+
export declare function set(value: string): string;
|
|
50
50
|
/** Value to submit when the user cleared a secret. */
|
|
51
|
-
export declare function
|
|
51
|
+
export declare function clear(): null;
|
|
52
52
|
/** Whether a settings response declares the `$secret` reference wire format. */
|
|
53
|
-
export declare function
|
|
53
|
+
export declare function usesReferences(response: unknown): boolean;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { PresenceActivity } from '../composables/usePresence';
|
|
2
|
+
/** One person on a presence topic, with the name to show. */
|
|
3
|
+
export interface PresencePerson {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
activity: PresenceActivity;
|
|
7
|
+
}
|
|
8
|
+
export interface PresenceArrangement {
|
|
9
|
+
/** Every other person, `editing` first. */
|
|
10
|
+
others: PresencePerson[];
|
|
11
|
+
/** The people that get an avatar. */
|
|
12
|
+
shown: PresencePerson[];
|
|
13
|
+
/** The other people without an avatar (the `+N`). */
|
|
14
|
+
overflow: number;
|
|
15
|
+
/** All other people, also those the platform did not list. */
|
|
16
|
+
total: number;
|
|
17
|
+
}
|
|
18
|
+
export declare const PRESENCE_ACTIVITY_LABELS: Record<PresenceActivity, string>;
|
|
19
|
+
/**
|
|
20
|
+
* Remove the current user, sort `editing` first (the sort is stable, so the
|
|
21
|
+
* platform order stays otherwise) and keep at most `max` avatars.
|
|
22
|
+
* `count` is the platform's total, the current user included.
|
|
23
|
+
*/
|
|
24
|
+
export declare function arrangePresence(people: readonly PresencePerson[], options?: {
|
|
25
|
+
selfId?: string | null;
|
|
26
|
+
count?: number;
|
|
27
|
+
max?: number;
|
|
28
|
+
}): PresenceArrangement;
|
|
29
|
+
/** "6 other people here: Alice Chen editing, Chen Li viewing design, and 4 more". */
|
|
30
|
+
export declare function presenceSummary({ shown, overflow, total }: PresenceArrangement): string;
|
package/dist/utils/records.d.ts
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
1
|
/** Narrow an unknown value to a plain object (arrays and null excluded). */
|
|
2
2
|
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
3
|
-
/** Narrow an unknown value to any non-null object, arrays included. */
|
|
4
|
-
export declare function isObjectLike(value: unknown): value is Record<string, unknown>;
|
|
@@ -17,21 +17,3 @@ export declare function compareTime(a: string, b: string): number;
|
|
|
17
17
|
export declare function findNearestTimeSlotIndex(time: string, slots: readonly string[]): number;
|
|
18
18
|
export declare function toMinutes(time: string): number;
|
|
19
19
|
export declare function fromMinutes(total: number): string;
|
|
20
|
-
/** Time utility helpers for parsing, formatting, comparing, and snapping HH:MM strings. */
|
|
21
|
-
export declare function useTimeUtils(): {
|
|
22
|
-
parseTime: typeof parseTime;
|
|
23
|
-
formatTime: typeof formatTime;
|
|
24
|
-
formatTimeSlot: typeof formatTimeSlot;
|
|
25
|
-
generateTimeSlots: typeof generateTimeSlots;
|
|
26
|
-
rangesOverlap: typeof rangesOverlap;
|
|
27
|
-
durationMinutes: typeof durationMinutes;
|
|
28
|
-
formatDuration: typeof formatDuration;
|
|
29
|
-
isTimeInRange: typeof isTimeInRange;
|
|
30
|
-
findAvailableSlots: typeof findAvailableSlots;
|
|
31
|
-
snapToSlot: typeof snapToSlot;
|
|
32
|
-
addMinutes: typeof addMinutes;
|
|
33
|
-
compareTime: typeof compareTime;
|
|
34
|
-
findNearestTimeSlotIndex: typeof findNearestTimeSlotIndex;
|
|
35
|
-
toMinutes: typeof toMinutes;
|
|
36
|
-
fromMinutes: typeof fromMinutes;
|
|
37
|
-
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@morscherlab/mint-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0-beta.1",
|
|
4
4
|
"description": "MINT Platform SDK — Vue 3 components, composables, and types for plugin development. MINT = Mass-spec INtegrated Toolkit.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -19,13 +19,25 @@
|
|
|
19
19
|
"types": "./dist/install.d.ts",
|
|
20
20
|
"import": "./dist/install.js"
|
|
21
21
|
},
|
|
22
|
-
"./
|
|
23
|
-
"types": "./dist/
|
|
24
|
-
"import": "./dist/
|
|
22
|
+
"./lab": {
|
|
23
|
+
"types": "./dist/lab.d.ts",
|
|
24
|
+
"import": "./dist/lab.js"
|
|
25
25
|
},
|
|
26
|
-
"./
|
|
27
|
-
"types": "./dist/
|
|
28
|
-
"import": "./dist/
|
|
26
|
+
"./shell": {
|
|
27
|
+
"types": "./dist/shell.d.ts",
|
|
28
|
+
"import": "./dist/shell.js"
|
|
29
|
+
},
|
|
30
|
+
"./data": {
|
|
31
|
+
"types": "./dist/data.d.ts",
|
|
32
|
+
"import": "./dist/data.js"
|
|
33
|
+
},
|
|
34
|
+
"./runtime": {
|
|
35
|
+
"types": "./dist/runtime.d.ts",
|
|
36
|
+
"import": "./dist/runtime.js"
|
|
37
|
+
},
|
|
38
|
+
"./host": {
|
|
39
|
+
"types": "./dist/host.d.ts",
|
|
40
|
+
"import": "./dist/host.js"
|
|
29
41
|
},
|
|
30
42
|
"./stores": {
|
|
31
43
|
"types": "./dist/stores/index.d.ts",
|
|
@@ -35,19 +47,11 @@
|
|
|
35
47
|
"types": "./dist/permissions.d.ts",
|
|
36
48
|
"import": "./dist/permissions.js"
|
|
37
49
|
},
|
|
38
|
-
"./templates": {
|
|
39
|
-
"types": "./dist/templates/index.d.ts",
|
|
40
|
-
"import": "./dist/templates/index.js"
|
|
41
|
-
},
|
|
42
50
|
"./types": {
|
|
43
51
|
"types": "./dist/types/index.d.ts",
|
|
44
52
|
"import": "./dist/types/index.js"
|
|
45
53
|
},
|
|
46
|
-
"./styles": "./dist/styles.css"
|
|
47
|
-
"./tailwind.preset": {
|
|
48
|
-
"types": "./dist/tailwind.preset.d.ts",
|
|
49
|
-
"import": "./dist/tailwind.preset.js"
|
|
50
|
-
}
|
|
54
|
+
"./styles": "./dist/styles.css"
|
|
51
55
|
},
|
|
52
56
|
"files": [
|
|
53
57
|
"dist",
|
|
@@ -68,7 +72,6 @@
|
|
|
68
72
|
},
|
|
69
73
|
"peerDependencies": {
|
|
70
74
|
"pinia": "^4.0.3",
|
|
71
|
-
"tailwindcss": "^4.3.3",
|
|
72
75
|
"vue": "^3.5.43",
|
|
73
76
|
"vue-router": "^5.3.1"
|
|
74
77
|
},
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { readFileSync } from 'node:fs'
|
|
2
|
-
import { resolve } from 'node:path'
|
|
3
1
|
import { enableAutoUnmount, mount } from '@vue/test-utils'
|
|
4
2
|
import { afterEach, describe, expect, it } from 'vitest'
|
|
5
3
|
import ActionMenu from '../../components/ActionMenu.vue'
|
|
@@ -34,17 +32,6 @@ describe('ActionMenu', () => {
|
|
|
34
32
|
expect(wrapper.find('svg.lucide-ellipsis').exists()).toBe(true)
|
|
35
33
|
})
|
|
36
34
|
|
|
37
|
-
it('should keep the default trigger icon at 16 pixels', () => {
|
|
38
|
-
const styles = readFileSync(
|
|
39
|
-
resolve(process.cwd(), 'src/styles/components/action-menu.css'),
|
|
40
|
-
'utf8',
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
expect(styles).toMatch(
|
|
44
|
-
/\.mint-action-menu__trigger-icon\s*\{[^}]*width:\s*1rem;[^}]*height:\s*1rem;/s,
|
|
45
|
-
)
|
|
46
|
-
})
|
|
47
|
-
|
|
48
35
|
it('should expose menu semantics on the square trigger', () => {
|
|
49
36
|
const wrapper = mount(ActionMenu, {
|
|
50
37
|
props: { label: 'More user actions', items },
|
|
@@ -4,7 +4,7 @@ import AlertBox from '../../components/AlertBox.vue'
|
|
|
4
4
|
|
|
5
5
|
describe('AlertBox', () => {
|
|
6
6
|
it('should render the action as a small secondary BaseButton when actionLabel is set (1h)', () => {
|
|
7
|
-
const wrapper = mount(AlertBox, { props: {
|
|
7
|
+
const wrapper = mount(AlertBox, { props: { tone: 'warning', actionLabel: 'Recalibrate' } })
|
|
8
8
|
|
|
9
9
|
expect(wrapper.get('.mint-alert__actions button').classes()).toEqual(
|
|
10
10
|
expect.arrayContaining(['mint-button', 'mint-button--secondary', 'mint-button--sm']),
|