@morscherlab/mint-sdk 1.3.8 → 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.
Files changed (966) hide show
  1. package/README.md +152 -177
  2. package/dist/ActionMenu-CScINahU.js +445 -0
  3. package/dist/ActionMenu-CScINahU.js.map +1 -0
  4. package/dist/AppSidebar-BmiiPfz9.js +3514 -0
  5. package/dist/AppSidebar-BmiiPfz9.js.map +1 -0
  6. package/dist/{experiment-utils-DTANyVKV.js → BaseModal-DfRIuVoj.js} +74 -149
  7. package/dist/BaseModal-DfRIuVoj.js.map +1 -0
  8. package/dist/ConfirmDialog-CJ7hqYUP.js +102 -0
  9. package/dist/ConfirmDialog-CJ7hqYUP.js.map +1 -0
  10. package/dist/ExperimentPopover-C4sGw-is.js +359 -0
  11. package/dist/ExperimentPopover-C4sGw-is.js.map +1 -0
  12. package/dist/ExperimentSelectorModal-D-9z7cNx.js +527 -0
  13. package/dist/ExperimentSelectorModal-D-9z7cNx.js.map +1 -0
  14. package/dist/SegmentedControl-DERBN-Xd.js +129 -0
  15. package/dist/SegmentedControl-DERBN-Xd.js.map +1 -0
  16. package/dist/SettingsModal-CSLE31yg.js +666 -0
  17. package/dist/SettingsModal-CSLE31yg.js.map +1 -0
  18. package/dist/analysisArtifactTypes-Cy3D0Ipg.js.map +1 -1
  19. package/dist/auth-SliLnFre.js +65 -0
  20. package/dist/auth-SliLnFre.js.map +1 -0
  21. package/dist/components/ActionMenu.vue.d.ts +1 -1
  22. package/dist/components/AdductText.vue.d.ts +1 -1
  23. package/dist/components/AlertBox.vue.d.ts +3 -3
  24. package/dist/components/AppContainer.vue.d.ts +1 -1
  25. package/dist/components/AppSidebar.vue.d.ts +14 -94
  26. package/dist/components/AppTopBar.vue.d.ts +16 -70
  27. package/dist/components/ArtifactSaveDialog.vue.d.ts +4 -4
  28. package/dist/components/ArtifactSelectorModal.vue.d.ts +4 -4
  29. package/dist/components/AuditTrail.vue.d.ts +2 -2
  30. package/dist/components/BaseButton.vue.d.ts +11 -4
  31. package/dist/components/BaseCheckbox.vue.d.ts +9 -3
  32. package/dist/components/BaseInput.vue.d.ts +13 -9
  33. package/dist/components/BaseModal.vue.d.ts +4 -4
  34. package/dist/components/BasePill.vue.d.ts +15 -8
  35. package/dist/components/BaseRadioGroup.vue.d.ts +2 -2
  36. package/dist/components/BaseSelect.vue.d.ts +51 -19
  37. package/dist/components/BaseTabs.vue.d.ts +6 -5
  38. package/dist/components/BatchProgressList.vue.d.ts +2 -2
  39. package/dist/components/ChartContainer.vue.d.ts +2 -2
  40. package/dist/components/ChemicalFormula.vue.d.ts +2 -2
  41. package/dist/components/CollapsibleCard.vue.d.ts +3 -3
  42. package/dist/components/ComponentBindingRenderer.vue.d.ts +2 -3
  43. package/dist/components/ConcentrationInput.vue.d.ts +2 -2
  44. package/dist/components/ConfirmDialog.vue.d.ts +8 -7
  45. package/dist/components/DataFrame.vue.d.ts +32 -74
  46. package/dist/components/DatePicker.vue.d.ts +24 -2
  47. package/dist/components/DoseCalculator.vue.d.ts +1 -1
  48. package/dist/components/DoseCalculatorVolumeField.vue.d.ts +1 -1
  49. package/dist/components/EmptyState.vue.d.ts +3 -2
  50. package/dist/components/ExperimentSelectorModal.vue.d.ts +3 -3
  51. package/dist/components/FormBuilder.vue.d.ts +17 -74
  52. package/dist/components/FormulaInput.vue.d.ts +2 -2
  53. package/dist/components/GeneratedPluginView.vue.d.ts +1 -1
  54. package/dist/components/GeneratedResultRenderer.vue.d.ts +5 -1
  55. package/dist/components/{StatusIndicator.vue.d.ts → InstrumentStatusPanels.vue.d.ts} +8 -9
  56. package/dist/components/JobsStatusTray.vue.d.ts +2 -9
  57. package/dist/components/LoadingSpinner.vue.d.ts +3 -3
  58. package/dist/components/MoleculeInput.vue.d.ts +2 -2
  59. package/dist/components/NumberInput.vue.d.ts +19 -5
  60. package/dist/components/PlateEditor.vue.d.ts +11 -61
  61. package/dist/components/PlotlyChart.vue.d.ts +2 -2
  62. package/dist/components/PluginIcon.vue.d.ts +5 -1
  63. package/dist/components/PluginWorkspaceView.controls.d.ts +2 -9
  64. package/dist/components/PluginWorkspaceView.navigation.d.ts +1 -7
  65. package/dist/components/PluginWorkspaceView.props.d.ts +18 -137
  66. package/dist/components/PluginWorkspaceView.shell.d.ts +2 -10
  67. package/dist/components/PluginWorkspaceView.vue.d.ts +14 -84
  68. package/dist/components/PresenceAvatars.vue.d.ts +31 -0
  69. package/dist/components/ProgressBar.vue.d.ts +3 -2
  70. package/dist/components/ProtocolStep.presentation.d.ts +0 -1
  71. package/dist/components/SampleHierarchyTree.vue.d.ts +3 -3
  72. package/dist/components/SampleSelector.vue.d.ts +3 -3
  73. package/dist/components/ScheduleCalendar.vue.d.ts +1 -1
  74. package/dist/components/ScientificNumber.vue.d.ts +1 -1
  75. package/dist/components/SecretInput.vue.d.ts +2 -2
  76. package/dist/components/SegmentedControl.vue.d.ts +2 -2
  77. package/dist/components/SequenceInput.vue.d.ts +2 -2
  78. package/dist/components/SettingsModal.vue.d.ts +12 -20
  79. package/dist/components/SmartGroup.types.d.ts +0 -1
  80. package/dist/components/SmartGroupFieldRecipe.vue.d.ts +1 -1
  81. package/dist/components/StaleFormBanner.vue.d.ts +20 -0
  82. package/dist/components/TagsInput.vue.d.ts +4 -3
  83. package/dist/components/TimeRangeInput.vue.d.ts +2 -2
  84. package/dist/components/VersionConflictDialog.vue.d.ts +24 -0
  85. package/dist/components/WellPlate.geometry.d.ts +0 -6
  86. package/dist/components/WellPlate.rendering.d.ts +0 -2
  87. package/dist/components/WellPlate.vue.d.ts +7 -52
  88. package/dist/components/index.d.ts +0 -90
  89. package/dist/components/{AutoGroupModal.adapter.d.ts → internal/AutoGroupModalInternal.adapter.d.ts} +6 -6
  90. package/dist/components/{AutoGroupModal.vue.d.ts → internal/AutoGroupModalInternal.vue.d.ts} +6 -6
  91. package/dist/components/{BaseToggle.vue.d.ts → internal/CheckboxSwitchInternal.vue.d.ts} +2 -2
  92. package/dist/components/internal/DatePickerDateInternal.vue.d.ts +22 -0
  93. package/dist/components/{DateTimePicker.vue.d.ts → internal/DatePickerDateTimeInternal.vue.d.ts} +2 -2
  94. package/dist/components/{TimePicker.vue.d.ts → internal/DatePickerTimeInternal.vue.d.ts} +3 -3
  95. package/dist/components/internal/FilePickerListInternal.vue.d.ts +2 -2
  96. package/dist/components/internal/FormSchemaInternal.vue.d.ts +95 -0
  97. package/dist/components/{UnitInput.vue.d.ts → internal/NumberUnitInputInternal.vue.d.ts} +6 -14
  98. package/dist/components/internal/PlateEditorBindingInternal.vue.d.ts +3 -2
  99. package/dist/components/internal/ResourcePickerListInternal.vue.d.ts +3 -3
  100. package/dist/components/{MultiSelect.vue.d.ts → internal/SelectMultipleInternal.vue.d.ts} +11 -8
  101. package/dist/components/{SearchableSelect.vue.d.ts → internal/SelectSearchableInternal.vue.d.ts} +5 -2
  102. package/dist/components/internal/WorkspaceShellInternal.vue.d.ts +1 -15
  103. package/dist/components/internal/WorkspaceSidebarInternal.vue.d.ts +4 -4
  104. package/dist/{composables → components/internal}/autoGroup/classKey.d.ts +1 -1
  105. package/dist/{composables → components/internal}/autoGroup/classify.d.ts +1 -1
  106. package/dist/{composables → components/internal}/autoGroup/columns.d.ts +1 -1
  107. package/dist/{composables → components/internal}/autoGroup/compose.d.ts +1 -1
  108. package/dist/{composables → components/internal}/autoGroup/cooccurrence.d.ts +1 -1
  109. package/dist/{composables → components/internal}/autoGroup/csv-shim.d.ts +1 -1
  110. package/dist/{composables → components/internal}/autoGroup/fingerprint.d.ts +1 -1
  111. package/dist/{composables → components/internal}/autoGroup/template.d.ts +1 -1
  112. package/dist/{composables → components/internal}/autoGroup/tokenLength.d.ts +1 -1
  113. package/dist/components/internal/generatedJobsApi.d.ts +1 -1
  114. package/dist/{composables → components/internal}/useAutoGroup.d.ts +9 -18
  115. package/dist/composables/componentSpecs.d.ts +41 -0
  116. package/dist/composables/controlComponentBindings.d.ts +6 -0
  117. package/dist/composables/controlSchemaAdapters.d.ts +28 -2
  118. package/dist/composables/controlSchemaDoseDesign.d.ts +1 -1
  119. package/dist/composables/controlSchemaModel.d.ts +1 -1
  120. package/dist/composables/controlSchemaTypes.d.ts +35 -23
  121. package/dist/composables/{usePluginClient.d.ts → createClient.d.ts} +20 -49
  122. package/dist/composables/{useEventStream.d.ts → eventStream.d.ts} +2 -2
  123. package/dist/composables/experiment-utils.d.ts +1 -6
  124. package/dist/composables/index.d.ts +6 -59
  125. package/dist/composables/platformContextHelpers.d.ts +0 -11
  126. package/dist/composables/pluginEndpointBuilder.d.ts +2 -2
  127. package/dist/composables/pluginWorkspaceModel.d.ts +14 -97
  128. package/dist/composables/useApi.d.ts +1 -3
  129. package/dist/composables/useAppExperiment.d.ts +1 -1
  130. package/dist/composables/{useAnalysisArtifacts.d.ts → useArtifacts.d.ts} +6 -6
  131. package/dist/composables/useExperiment.d.ts +30 -0
  132. package/dist/composables/useFilePicker.d.ts +2 -2
  133. package/dist/composables/useJobCenter.d.ts +63 -0
  134. package/dist/composables/{useGeneratedAnalysis.d.ts → useJobsEndpoint.d.ts} +22 -23
  135. package/dist/composables/useMenuKeyboard.d.ts +1 -1
  136. package/dist/composables/usePlatform.d.ts +63 -0
  137. package/dist/composables/usePluginWorkspace.d.ts +6 -11
  138. package/dist/composables/usePresence.d.ts +41 -0
  139. package/dist/composables/useRackEditor.d.ts +2 -2
  140. package/dist/composables/useRealtime.d.ts +71 -0
  141. package/dist/composables/{useRequestSyncState.d.ts → useRequest.d.ts} +12 -17
  142. package/dist/composables/useToast.d.ts +7 -5
  143. package/dist/composables/useVersionedSave.d.ts +76 -0
  144. package/dist/controlSchemaModel-CP5-_nAj.js +95 -0
  145. package/dist/controlSchemaModel-CP5-_nAj.js.map +1 -0
  146. package/dist/data-C2PwI_dn.js +3811 -0
  147. package/dist/data-C2PwI_dn.js.map +1 -0
  148. package/dist/data.d.ts +32 -0
  149. package/dist/data.js +10 -0
  150. package/dist/deprecatedRootExports.d.ts +191 -0
  151. package/dist/experiment-43OJtH7R.js +673 -0
  152. package/dist/experiment-43OJtH7R.js.map +1 -0
  153. package/dist/experimentStatus-BZmU4czV.js +60 -0
  154. package/dist/experimentStatus-BZmU4czV.js.map +1 -0
  155. package/dist/host.d.ts +10 -0
  156. package/dist/host.js +26 -0
  157. package/dist/host.js.map +1 -0
  158. package/dist/index.d.ts +1 -12
  159. package/dist/index.js +65 -277
  160. package/dist/index.js.map +1 -1
  161. package/dist/install-DAID6c2-.js +668 -0
  162. package/dist/install-DAID6c2-.js.map +1 -0
  163. package/dist/install.d.ts +2 -1
  164. package/dist/install.js +1 -21
  165. package/dist/instrument.d.ts +0 -6
  166. package/dist/lab-DLwRl_Ql.js +7513 -0
  167. package/dist/lab-DLwRl_Ql.js.map +1 -0
  168. package/dist/lab.d.ts +42 -0
  169. package/dist/lab.js +4 -0
  170. package/dist/permissions.d.ts +0 -4
  171. package/dist/permissions.js +1 -20
  172. package/dist/permissions.js.map +1 -1
  173. package/dist/records-BzTcxekG.js +3070 -0
  174. package/dist/records-BzTcxekG.js.map +1 -0
  175. package/dist/runtime-D6gVat6r.js +1495 -0
  176. package/dist/runtime-D6gVat6r.js.map +1 -0
  177. package/dist/runtime.d.ts +25 -0
  178. package/dist/runtime.js +8 -0
  179. package/dist/shell-5ju97nOS.js +197 -0
  180. package/dist/shell-5ju97nOS.js.map +1 -0
  181. package/dist/shell.d.ts +16 -0
  182. package/dist/shell.js +8 -0
  183. package/dist/stores/auth.d.ts +13 -35
  184. package/dist/stores/experiment.d.ts +4 -0
  185. package/dist/stores/index.js +2 -2
  186. package/dist/styles.css +12030 -14845
  187. package/dist/types/analysisArtifactTypes.d.ts +1 -1
  188. package/dist/types/auth.d.ts +0 -8
  189. package/dist/types/componentLabTypes.d.ts +98 -34
  190. package/dist/types/componentWorkflowTypes.d.ts +0 -27
  191. package/dist/types/components.d.ts +145 -74
  192. package/dist/types/form-builder.d.ts +4 -0
  193. package/dist/types/generated/platformContext.d.ts +52 -0
  194. package/dist/types/generated-ui.d.ts +2 -2
  195. package/dist/types/index.d.ts +4 -5
  196. package/dist/types/instrument.d.ts +41 -0
  197. package/dist/types/platform.d.ts +20 -58
  198. package/dist/useDebouncedWatch-BPwyl6eS.js +73 -0
  199. package/dist/useDebouncedWatch-BPwyl6eS.js.map +1 -0
  200. package/dist/useExpansionSet-CvoNMZJi.js +68 -0
  201. package/dist/useExpansionSet-CvoNMZJi.js.map +1 -0
  202. package/dist/useExperimentSamples-CxcnxZ8h.js +366 -0
  203. package/dist/useExperimentSamples-CxcnxZ8h.js.map +1 -0
  204. package/dist/useListReorder-CcbEYxX-.js +5462 -0
  205. package/dist/useListReorder-CcbEYxX-.js.map +1 -0
  206. package/dist/useRackEditor-BD5NIo5s.js +5916 -0
  207. package/dist/useRackEditor-BD5NIo5s.js.map +1 -0
  208. package/dist/useRealtime-PalKue84.js +696 -0
  209. package/dist/useRealtime-PalKue84.js.map +1 -0
  210. package/dist/useRequest-D5JDfsgZ.js +76 -0
  211. package/dist/useRequest-D5JDfsgZ.js.map +1 -0
  212. package/dist/utils/color.d.ts +0 -5
  213. package/dist/{composables/useDoseCalculator.d.ts → utils/dose.d.ts} +10 -13
  214. package/dist/utils/experimentStatus.d.ts +9 -0
  215. package/dist/{composables/useChemicalFormula.d.ts → utils/formula.d.ts} +3 -6
  216. package/dist/utils/integrationHost.d.ts +18 -0
  217. package/dist/utils/plotlyTemplate.d.ts +2 -0
  218. package/dist/utils/pluginSecrets.d.ts +12 -12
  219. package/dist/utils/presenceAvatars.d.ts +30 -0
  220. package/dist/utils/records.d.ts +0 -2
  221. package/dist/{composables/useTimeUtils.d.ts → utils/time.d.ts} +0 -18
  222. package/package.json +20 -17
  223. package/src/__tests__/components/ActionMenu.test.ts +0 -13
  224. package/src/__tests__/components/AlertBox.test.ts +1 -1
  225. package/src/__tests__/components/AppSidebar.test.ts +119 -167
  226. package/src/__tests__/components/AppToastContainer.test.ts +2 -2
  227. package/src/__tests__/components/AppTopBar.test.ts +181 -176
  228. package/src/__tests__/components/ArtifactSaveDialog.test.ts +5 -3
  229. package/src/__tests__/components/ArtifactSelectorModal.test.ts +6 -4
  230. package/src/__tests__/components/AuditTrail.test.ts +1 -1
  231. package/src/__tests__/components/AutoGroupModal.adapter.test.ts +1 -1
  232. package/src/__tests__/components/AutoGroupModal.anatomy.test.ts +2 -2
  233. package/src/__tests__/components/AutoGroupModal.wiring.test.ts +2 -2
  234. package/src/__tests__/components/BaseButton.test.ts +51 -0
  235. package/src/__tests__/components/{BaseToggle.test.ts → BaseCheckbox.switch.test.ts} +8 -6
  236. package/src/__tests__/components/BaseInput.test.ts +13 -34
  237. package/src/__tests__/components/BaseModal.test.ts +6 -6
  238. package/src/__tests__/components/BasePill.test.ts +33 -39
  239. package/src/__tests__/components/{MultiSelect.test.ts → BaseSelect.multiple.test.ts} +16 -7
  240. package/src/__tests__/components/{SearchableSelect.test.ts → BaseSelect.searchable.test.ts} +19 -9
  241. package/src/__tests__/components/BaseSelect.test.ts +10 -0
  242. package/src/__tests__/components/BaseTabs.test.ts +13 -13
  243. package/src/__tests__/components/CollapsibleCard.test.ts +1 -1
  244. package/src/__tests__/components/ComponentBindingRenderer.test.ts +25 -73
  245. package/src/__tests__/components/ConcentrationInput.test.ts +3 -3
  246. package/src/__tests__/components/ConfirmDialog.test.ts +23 -0
  247. package/src/__tests__/components/DataFrame.test.ts +140 -142
  248. package/src/__tests__/components/DataStates.test.ts +6 -22
  249. package/src/__tests__/components/{DateTimePicker.test.ts → DatePicker.datetime.test.ts} +9 -7
  250. package/src/__tests__/components/{TimePicker.test.ts → DatePicker.time.test.ts} +18 -17
  251. package/src/__tests__/components/DoseCalculator.test.ts +12 -7
  252. package/src/__tests__/components/DoseCalculatorVolumeField.test.ts +6 -6
  253. package/src/__tests__/components/ExperimentSelectorModal.test.ts +15 -15
  254. package/src/__tests__/components/FormBuilder.test.ts +49 -167
  255. package/src/__tests__/components/FormSchemaInternal.test.ts +91 -0
  256. package/src/__tests__/components/GeneratedPathInput.test.ts +18 -13
  257. package/src/__tests__/components/GeneratedPluginView.test.ts +38 -24
  258. package/src/__tests__/components/GeneratedResultRenderer.test.ts +6 -4
  259. package/src/__tests__/components/InstrumentStatusPanels.test.ts +79 -0
  260. package/src/__tests__/components/JobsStatusTray.test.ts +4 -4
  261. package/src/__tests__/components/NumberInput.test.ts +28 -0
  262. package/src/__tests__/components/{UnitInput.test.ts → NumberInput.units.test.ts} +6 -6
  263. package/src/__tests__/components/PlateEditor.test.ts +108 -108
  264. package/src/__tests__/components/PlateEditorBindingInternal.test.ts +13 -13
  265. package/src/__tests__/components/PlotlyChart.test.ts +1 -1
  266. package/src/__tests__/components/PluginIcon.test.ts +9 -4
  267. package/src/__tests__/components/PluginWorkspaceView.controls.test.ts +16 -29
  268. package/src/__tests__/components/PluginWorkspaceView.internal.test.ts +28 -34
  269. package/src/__tests__/components/PluginWorkspaceView.navigation.test.ts +4 -19
  270. package/src/__tests__/components/PluginWorkspaceView.shell.test.ts +1 -6
  271. package/src/__tests__/components/PluginWorkspaceView.test.ts +176 -155
  272. package/src/__tests__/components/PresenceAvatars.test.ts +90 -0
  273. package/src/__tests__/components/ProtocolStep.presentation.test.ts +1 -3
  274. package/src/__tests__/components/ProtocolStepEditor.test.ts +10 -11
  275. package/src/__tests__/components/ProtocolStepParameterField.test.ts +8 -7
  276. package/src/__tests__/components/ResourcePickerListInternal.test.ts +2 -2
  277. package/src/__tests__/components/RetiredStyles.test.ts +0 -18
  278. package/src/__tests__/components/SampleSelector.test.ts +17 -17
  279. package/src/__tests__/components/SecretInput.test.ts +14 -19
  280. package/src/__tests__/components/SettingsModal.test.ts +76 -84
  281. package/src/__tests__/components/StaleFormBanner.test.ts +48 -0
  282. package/src/__tests__/components/ThemeToggle.test.ts +1 -1
  283. package/src/__tests__/components/WellPlate.decoration.test.ts +10 -8
  284. package/src/__tests__/components/WellPlate.interaction.test.ts +6 -7
  285. package/src/__tests__/components/WellPlate.keyboard.test.ts +2 -2
  286. package/src/__tests__/components/deprecationTags.test.ts +90 -0
  287. package/src/__tests__/composables/analysisArtifactTarget.test.ts +1 -12
  288. package/src/__tests__/composables/autoGroup/classKey.test.ts +1 -1
  289. package/src/__tests__/composables/autoGroup/classify.test.ts +1 -1
  290. package/src/__tests__/composables/autoGroup/columns.test.ts +1 -1
  291. package/src/__tests__/composables/autoGroup/compose.test.ts +1 -1
  292. package/src/__tests__/composables/autoGroup/cooccurrence.test.ts +1 -1
  293. package/src/__tests__/composables/autoGroup/fieldEdits.test.ts +1 -1
  294. package/src/__tests__/composables/autoGroup/fingerprint.test.ts +1 -1
  295. package/src/__tests__/composables/autoGroup/golden.test.ts +1 -1
  296. package/src/__tests__/composables/autoGroup/groupByOrder.test.ts +1 -1
  297. package/src/__tests__/composables/autoGroup/groupTree.test.ts +1 -1
  298. package/src/__tests__/composables/autoGroup/integration.test.ts +1 -1
  299. package/src/__tests__/composables/autoGroup/template.test.ts +1 -1
  300. package/src/__tests__/composables/autoGroup/tokenLength.test.ts +1 -1
  301. package/src/__tests__/composables/autoGroup/tokenize.test.ts +1 -1
  302. package/src/__tests__/composables/{usePluginClient.test.ts → createClient.test.ts} +84 -222
  303. package/src/__tests__/composables/{useEventStream.test.ts → eventStream.test.ts} +6 -6
  304. package/src/__tests__/composables/experiment-utils.test.ts +13 -14
  305. package/src/__tests__/composables/useApi.test.ts +32 -21
  306. package/src/__tests__/composables/useAppExperiment.test.ts +19 -2
  307. package/src/__tests__/composables/{useAnalysisArtifacts.test.ts → useArtifacts.test.ts} +19 -27
  308. package/src/__tests__/composables/useAutoGroup.test.ts +3 -13
  309. package/src/__tests__/composables/useControlSchema.test.ts +41 -99
  310. package/src/__tests__/composables/useExperiment.test.ts +63 -0
  311. package/src/__tests__/composables/useFileBrowser.test.ts +4 -6
  312. package/src/__tests__/composables/{useJobsStatusTray.test.ts → useJobCenter.test.ts} +31 -31
  313. package/src/__tests__/composables/{useGeneratedAnalysis.test.ts → useJobsEndpoint.test.ts} +213 -139
  314. package/src/__tests__/composables/usePlatform.test.ts +102 -0
  315. package/src/__tests__/composables/usePresence.test.ts +164 -0
  316. package/src/__tests__/composables/useRackEditor.test.ts +2 -2
  317. package/src/__tests__/composables/useRealtime.test.ts +196 -0
  318. package/src/__tests__/composables/{useRequestSyncState.test.ts → useRequest.test.ts} +32 -47
  319. package/src/__tests__/composables/useVersionedSave.test.ts +194 -0
  320. package/src/__tests__/docs/extractDocsComponents.test.ts +36 -0
  321. package/src/__tests__/docs/extractDocsParsing.test.ts +2 -2
  322. package/src/__tests__/docs/extractDocsTheme.test.ts +1 -46
  323. package/src/__tests__/docs/frontendDocsCatalog.test.ts +164 -84
  324. package/src/__tests__/styles/baseControlsRules.test.ts +1 -1
  325. package/src/__tests__/styles/darkModeRules.test.ts +0 -6
  326. package/src/__tests__/{composables/useChemicalFormula.test.ts → utils/formula.test.ts} +3 -5
  327. package/src/__tests__/utils/permissions.test.ts +1 -36
  328. package/src/__tests__/utils/plotlyTemplate.test.ts +16 -1
  329. package/src/__tests__/{composables/useTimeUtils.test.ts → utils/time.test.ts} +2 -9
  330. package/src/components/ActionMenu.vue +7 -13
  331. package/src/components/AlertBox.story.vue +25 -25
  332. package/src/components/AlertBox.vue +8 -8
  333. package/src/components/AppLayout.story.vue +33 -44
  334. package/src/components/AppLayout.vue +1 -1
  335. package/src/components/AppSidebar.story.vue +40 -73
  336. package/src/components/AppSidebar.vue +66 -147
  337. package/src/components/AppToastContainer.story.vue +1 -1
  338. package/src/components/AppTopBar.story.vue +51 -100
  339. package/src/components/AppTopBar.vue +74 -198
  340. package/src/components/ArtifactSaveDialog.story.vue +9 -9
  341. package/src/components/ArtifactSaveDialog.vue +23 -26
  342. package/src/components/ArtifactSelectorModal.story.vue +4 -4
  343. package/src/components/ArtifactSelectorModal.vue +10 -10
  344. package/src/components/AuditTrail.story.vue +4 -4
  345. package/src/components/AuditTrail.vue +3 -3
  346. package/src/components/Avatar.story.vue +2 -3
  347. package/src/components/Avatar.vue +1 -2
  348. package/src/components/BaseButton.story.vue +25 -0
  349. package/src/components/BaseButton.vue +39 -10
  350. package/src/components/BaseCheckbox.story.vue +2 -2
  351. package/src/components/{BaseToggle.story.vue → BaseCheckbox.switch.story.vue} +22 -19
  352. package/src/components/BaseCheckbox.vue +39 -7
  353. package/src/components/BaseInput.story.vue +3 -15
  354. package/src/components/{BaseTextarea.story.vue → BaseInput.textarea.story.vue} +14 -10
  355. package/src/components/BaseInput.vue +53 -26
  356. package/src/components/BaseModal.story.vue +11 -11
  357. package/src/components/BaseModal.vue +8 -8
  358. package/src/components/BasePill.story.vue +48 -28
  359. package/src/components/BasePill.vue +22 -11
  360. package/src/components/BaseRadioGroup.story.vue +4 -4
  361. package/src/components/BaseRadioGroup.vue +3 -3
  362. package/src/components/{MultiSelect.story.vue → BaseSelect.multiple.story.vue} +20 -14
  363. package/src/components/{SearchableSelect.story.vue → BaseSelect.searchable.story.vue} +4 -4
  364. package/src/components/BaseSelect.story.vue +2 -2
  365. package/src/components/BaseSelect.vue +117 -22
  366. package/src/components/BaseTabs.story.vue +20 -20
  367. package/src/components/BaseTabs.vue +17 -9
  368. package/src/components/BatchProgressList.vue +3 -3
  369. package/src/components/ChartContainer.story.vue +8 -13
  370. package/src/components/ChartContainer.vue +3 -3
  371. package/src/components/ChemicalFormula.vue +1 -2
  372. package/src/components/CollapsibleCard.vue +5 -4
  373. package/src/components/ComponentBindingRenderer.story.vue +0 -29
  374. package/src/components/ComponentBindingRenderer.vue +15 -39
  375. package/src/components/ConcentrationInput.story.vue +2 -2
  376. package/src/components/ConcentrationInput.vue +9 -9
  377. package/src/components/ConfirmDialog.story.vue +21 -21
  378. package/src/components/ConfirmDialog.vue +15 -14
  379. package/src/components/DataFrame.story.vue +28 -40
  380. package/src/components/DataFrame.vue +112 -128
  381. package/src/components/{DateTimePicker.story.vue → DatePicker.datetime.story.vue} +19 -14
  382. package/src/components/DatePicker.story.vue +2 -2
  383. package/src/components/{TimePicker.story.vue → DatePicker.time.story.vue} +15 -12
  384. package/src/components/DatePicker.vue +82 -220
  385. package/src/components/DoseCalculator.vue +13 -19
  386. package/src/components/DoseCalculatorVolumeField.vue +6 -6
  387. package/src/components/EmptyState.story.vue +17 -17
  388. package/src/components/EmptyState.vue +5 -4
  389. package/src/components/ExperimentPopover.story.vue +1 -1
  390. package/src/components/ExperimentPopover.vue +4 -4
  391. package/src/components/ExperimentSelectorModal.story.vue +5 -5
  392. package/src/components/ExperimentSelectorModal.vue +11 -13
  393. package/src/components/FilePicker.vue +1 -1
  394. package/src/components/FormBuilder.story.vue +9 -4
  395. package/src/components/FormBuilder.vue +46 -253
  396. package/src/components/FormField.story.vue +1 -2
  397. package/src/components/FormulaInput.story.vue +2 -2
  398. package/src/components/FormulaInput.vue +5 -6
  399. package/src/components/GeneratedPathInput.vue +8 -9
  400. package/src/components/GeneratedPluginView.story.vue +1 -1
  401. package/src/components/GeneratedPluginView.vue +23 -22
  402. package/src/components/GeneratedResultRenderer.vue +16 -17
  403. package/src/components/InstrumentStatusPanels.story.vue +64 -0
  404. package/src/components/InstrumentStatusPanels.vue +133 -0
  405. package/src/components/JobsStatusTray.story.vue +2 -2
  406. package/src/components/JobsStatusTray.vue +4 -19
  407. package/src/components/LoadingSpinner.story.vue +11 -11
  408. package/src/components/LoadingSpinner.vue +6 -4
  409. package/src/components/MoleculeInput.story.vue +2 -2
  410. package/src/components/MoleculeInput.vue +3 -3
  411. package/src/components/NumberInput.story.vue +55 -15
  412. package/src/components/NumberInput.vue +80 -18
  413. package/src/components/PlateEditor.story.vue +51 -43
  414. package/src/components/PlateEditor.vue +97 -128
  415. package/src/components/PlotlyChart.story.vue +1 -1
  416. package/src/components/PlotlyChart.vue +6 -4
  417. package/src/components/PluginIcon.story.vue +9 -6
  418. package/src/components/PluginIcon.vue +7 -2
  419. package/src/components/PluginWorkspaceView.controls.ts +9 -29
  420. package/src/components/PluginWorkspaceView.navigation.ts +2 -23
  421. package/src/components/PluginWorkspaceView.props.ts +17 -151
  422. package/src/components/PluginWorkspaceView.shell.ts +13 -24
  423. package/src/components/PluginWorkspaceView.story.vue +64 -62
  424. package/src/components/PluginWorkspaceView.vue +21 -78
  425. package/src/components/PresenceAvatars.story.vue +75 -0
  426. package/src/components/PresenceAvatars.vue +114 -0
  427. package/src/components/ProgressBar.story.vue +7 -7
  428. package/src/components/ProgressBar.vue +4 -3
  429. package/src/components/ProtocolStep.presentation.ts +0 -11
  430. package/src/components/ProtocolStepEditor.vue +6 -5
  431. package/src/components/ProtocolStepParameterField.vue +15 -12
  432. package/src/components/SampleSelector.colors.ts +1 -1
  433. package/src/components/SampleSelector.vue +6 -6
  434. package/src/components/ScheduleCalendar.vue +4 -4
  435. package/src/components/SecretInput.story.vue +1 -1
  436. package/src/components/SecretInput.vue +16 -25
  437. package/src/components/SegmentedControl.story.vue +7 -7
  438. package/src/components/SegmentedControl.vue +5 -3
  439. package/src/components/SequenceInput.story.vue +2 -2
  440. package/src/components/SequenceInput.vue +3 -3
  441. package/src/components/SettingsModal.story.vue +13 -14
  442. package/src/components/SettingsModal.vue +29 -47
  443. package/src/components/SmartGroup.types.ts +4 -6
  444. package/src/components/SmartGroupFieldRecipe.vue +7 -5
  445. package/src/components/StaleFormBanner.story.vue +90 -0
  446. package/src/components/StaleFormBanner.vue +83 -0
  447. package/src/components/TagsInput.story.vue +7 -7
  448. package/src/components/TagsInput.vue +7 -6
  449. package/src/components/ThemeToggle.vue +5 -30
  450. package/src/components/TimeRangeInput.story.vue +1 -1
  451. package/src/components/TimeRangeInput.vue +10 -8
  452. package/src/components/VersionConflictDialog.story.vue +60 -0
  453. package/src/components/VersionConflictDialog.vue +79 -0
  454. package/src/components/WellPlate.geometry.ts +0 -38
  455. package/src/components/WellPlate.rendering.ts +0 -13
  456. package/src/components/WellPlate.story.vue +61 -50
  457. package/src/components/WellPlate.vue +61 -87
  458. package/src/components/index.ts +3 -105
  459. package/src/components/{AutoGroupModal.adapter.ts → internal/AutoGroupModalInternal.adapter.ts} +8 -8
  460. package/src/components/{AutoGroupModal.vue → internal/AutoGroupModalInternal.vue} +23 -23
  461. package/src/components/{BaseToggle.vue → internal/CheckboxSwitchInternal.vue} +8 -8
  462. package/src/components/internal/DataStateInternal.vue +1 -1
  463. package/src/components/internal/DatePickerDateInternal.vue +243 -0
  464. package/src/components/{DateTimePicker.vue → internal/DatePickerDateTimeInternal.vue} +9 -9
  465. package/src/components/{TimePicker.vue → internal/DatePickerTimeInternal.vue} +7 -7
  466. package/src/components/internal/FilePickerListInternal.vue +8 -14
  467. package/src/components/{FormActions.vue → internal/FormActionsInternal.vue} +2 -2
  468. package/src/components/internal/FormFieldRendererInternal.vue +1 -1
  469. package/src/components/internal/FormSchemaInternal.vue +253 -0
  470. package/src/components/{UnitInput.vue → internal/NumberUnitInputInternal.vue} +28 -28
  471. package/src/components/internal/PlateEditorBindingInternal.vue +8 -7
  472. package/src/components/internal/ResourcePickerListInternal.vue +4 -4
  473. package/src/components/{MultiSelect.vue → internal/SelectMultipleInternal.vue} +21 -15
  474. package/src/components/{SearchableSelect.vue → internal/SelectSearchableInternal.vue} +24 -8
  475. package/src/components/internal/WellEditPopupInternal.vue +4 -9
  476. package/src/components/internal/WorkspaceShellInternal.vue +3 -36
  477. package/src/components/internal/WorkspaceSidebarInternal.vue +4 -25
  478. package/src/{composables → components/internal}/autoGroup/classKey.ts +1 -1
  479. package/src/{composables → components/internal}/autoGroup/classify.ts +1 -1
  480. package/src/{composables → components/internal}/autoGroup/columns.ts +1 -1
  481. package/src/{composables → components/internal}/autoGroup/compose.ts +3 -3
  482. package/src/{composables → components/internal}/autoGroup/cooccurrence.ts +1 -1
  483. package/src/{composables → components/internal}/autoGroup/csv-shim.ts +1 -1
  484. package/src/{composables → components/internal}/autoGroup/fingerprint.ts +1 -1
  485. package/src/{composables → components/internal}/autoGroup/index.ts +1 -2
  486. package/src/{composables → components/internal}/autoGroup/template.ts +1 -1
  487. package/src/{composables → components/internal}/autoGroup/tokenLength.ts +1 -1
  488. package/src/components/internal/generatedJobsApi.ts +1 -1
  489. package/src/{composables → components/internal}/useAutoGroup.ts +3 -57
  490. package/src/composables/componentSpecs.ts +62 -0
  491. package/src/composables/controlComponentBindings.ts +7 -0
  492. package/src/composables/controlSchemaAdapters.ts +45 -7
  493. package/src/composables/controlSchemaDoseDesign.ts +16 -5
  494. package/src/composables/controlSchemaModel.ts +1 -1
  495. package/src/composables/controlSchemaTypes.ts +31 -22
  496. package/src/composables/{usePluginClient.ts → createClient.ts} +52 -190
  497. package/src/composables/{useEventStream.ts → eventStream.ts} +3 -3
  498. package/src/composables/experiment-utils.ts +1 -39
  499. package/src/composables/formBuilderRegistry.ts +6 -12
  500. package/src/composables/index.ts +16 -480
  501. package/src/composables/platformContextHelpers.ts +0 -57
  502. package/src/composables/pluginEndpointBuilder.ts +8 -10
  503. package/src/composables/pluginWorkspaceModel.ts +14 -105
  504. package/src/composables/useApi.ts +18 -30
  505. package/src/composables/useAppExperiment.ts +6 -5
  506. package/src/composables/{useAnalysisArtifacts.ts → useArtifacts.ts} +18 -19
  507. package/src/composables/useControlSchema.ts +5 -9
  508. package/src/composables/useControlWorkspace.ts +4 -7
  509. package/src/composables/useExperiment.ts +49 -0
  510. package/src/composables/useExperimentData.ts +4 -4
  511. package/src/composables/useExperimentSelector.ts +5 -5
  512. package/src/composables/useFileBrowser.ts +5 -13
  513. package/src/composables/useFilePicker.ts +2 -2
  514. package/src/composables/useFormBuilder.ts +3 -4
  515. package/src/composables/useJobCenter.ts +324 -0
  516. package/src/composables/{useGeneratedAnalysis.ts → useJobsEndpoint.ts} +53 -67
  517. package/src/composables/useMenuKeyboard.ts +1 -1
  518. package/src/composables/usePlatform.ts +95 -0
  519. package/src/composables/usePlatformFilePickerAdapter.ts +2 -1
  520. package/src/composables/usePluginWorkspace.ts +62 -107
  521. package/src/composables/usePresence.ts +110 -0
  522. package/src/composables/useRackEditor.ts +3 -3
  523. package/src/composables/useRealtime.ts +194 -0
  524. package/src/composables/{useRequestSyncState.ts → useRequest.ts} +25 -48
  525. package/src/composables/useScheduleCalendarLayout.ts +1 -1
  526. package/src/composables/useToast.ts +14 -11
  527. package/src/composables/useVersionedSave.ts +165 -0
  528. package/src/data.ts +130 -0
  529. package/src/deprecatedRootExports.ts +226 -0
  530. package/src/generated/schema.ts +1 -0
  531. package/src/host.ts +27 -0
  532. package/src/index.ts +2 -71
  533. package/src/install.ts +15 -2
  534. package/src/instrument.ts +1 -6
  535. package/src/lab.ts +128 -0
  536. package/src/permissions.ts +0 -27
  537. package/src/runtime.ts +145 -0
  538. package/src/shell.ts +103 -0
  539. package/src/stores/auth.ts +26 -162
  540. package/src/stores/experiment.ts +27 -1
  541. package/src/styles/components/action-menu.css +0 -5
  542. package/src/styles/components/alert-box.css +18 -0
  543. package/src/styles/components/app-top-bar.css +7 -48
  544. package/src/styles/components/button.css +12 -0
  545. package/src/styles/components/checkbox.css +1 -1
  546. package/src/styles/components/collapsible-card.css +1 -1
  547. package/src/styles/components/confirm-dialog.css +18 -2
  548. package/src/styles/components/empty-state.css +4 -2
  549. package/src/styles/components/file-picker.css +1 -1
  550. package/src/styles/components/icon-button.css +1 -1
  551. package/src/styles/components/loading-spinner.css +9 -12
  552. package/src/styles/components/multi-select.css +6 -1
  553. package/src/styles/components/pill.css +40 -35
  554. package/src/styles/components/plugin-icon.css +9 -0
  555. package/src/styles/components/presence-avatars.css +194 -0
  556. package/src/styles/components/progress-bar.css +2 -0
  557. package/src/styles/components/searchable-select.css +3 -0
  558. package/src/styles/components/smart-group.css +1 -6
  559. package/src/styles/components/textarea.css +1 -1
  560. package/src/styles/components/toggle.css +2 -2
  561. package/src/styles/components/version-conflict.css +122 -0
  562. package/src/styles/components/well-plate.css +0 -7
  563. package/src/styles/index.css +2 -11
  564. package/src/styles/variables.css +1 -527
  565. package/src/types/analysisArtifactTypes.ts +1 -1
  566. package/src/types/auth.ts +0 -10
  567. package/src/types/componentLabTypes.ts +103 -53
  568. package/src/types/componentWorkflowTypes.ts +2 -33
  569. package/src/types/components.ts +148 -114
  570. package/src/types/form-builder.ts +4 -0
  571. package/src/types/generated/platformContext.ts +59 -0
  572. package/src/types/generated-ui.ts +2 -2
  573. package/src/types/index.ts +15 -53
  574. package/src/types/instrument.ts +27 -0
  575. package/src/types/platform.ts +25 -89
  576. package/src/utils/color.ts +1 -12
  577. package/src/utils/dose.ts +335 -0
  578. package/src/utils/experimentStatus.ts +43 -0
  579. package/src/utils/formula.ts +292 -0
  580. package/src/utils/integrationHost.ts +27 -0
  581. package/src/utils/plotlyTemplate.ts +6 -0
  582. package/src/utils/pluginSecrets.ts +23 -23
  583. package/src/utils/presenceAvatars.ts +53 -0
  584. package/src/utils/records.ts +0 -5
  585. package/src/{composables/useTimeUtils.ts → utils/time.ts} +0 -21
  586. package/dist/ResourcePickerListInternal-CFAw4vTZ.js +0 -605
  587. package/dist/ResourcePickerListInternal-CFAw4vTZ.js.map +0 -1
  588. package/dist/__tests__/composables/useBioTemplatePackWorkspace.test.d.ts +0 -1
  589. package/dist/__tests__/composables/useBioTemplatePresetWorkspace.test.d.ts +0 -1
  590. package/dist/__tests__/composables/useBioTemplateWorkspace.test.d.ts +0 -1
  591. package/dist/__tests__/composables/useChemicalFormula.test.d.ts +0 -1
  592. package/dist/__tests__/composables/useEventStream.test.d.ts +0 -1
  593. package/dist/__tests__/composables/useExperimentSave.test.d.ts +0 -1
  594. package/dist/__tests__/composables/useGeneratedAnalysis.test.d.ts +0 -1
  595. package/dist/__tests__/composables/useGroupAssignment.test.d.ts +0 -1
  596. package/dist/__tests__/composables/useJobsStatusTray.test.d.ts +0 -1
  597. package/dist/__tests__/composables/useMobileSupportGate.test.d.ts +0 -1
  598. package/dist/__tests__/composables/usePlatformContext.test.d.ts +0 -1
  599. package/dist/__tests__/composables/usePluginClient.test.d.ts +0 -1
  600. package/dist/__tests__/composables/usePresenceHeartbeat.test.d.ts +0 -1
  601. package/dist/__tests__/composables/useRequestSyncState.test.d.ts +0 -1
  602. package/dist/__tests__/composables/useRuntimeAlignment.test.d.ts +0 -1
  603. package/dist/__tests__/composables/useTemplateCollection.test.d.ts +0 -1
  604. package/dist/__tests__/composables/useTimeUtils.test.d.ts +0 -1
  605. package/dist/__tests__/docs/extractDocsTemplates.test.d.ts +0 -1
  606. package/dist/__tests__/templates/templates.test.d.ts +0 -1
  607. package/dist/__tests__/templates/templatesDeprecation.test.d.ts +0 -1
  608. package/dist/__tests__/utils/lcms.test.d.ts +0 -1
  609. package/dist/__tests__/utils/rack.test.d.ts +0 -1
  610. package/dist/components/AppAvatarMenu.vue.d.ts +0 -47
  611. package/dist/components/AppTopBar.navigation.d.ts +0 -10
  612. package/dist/components/BaseTextarea.vue.d.ts +0 -31
  613. package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +0 -112
  614. package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +0 -86
  615. package/dist/components/BioTemplatePresetWorkspaceView.vue.d.ts +0 -80
  616. package/dist/components/BioTemplateRenderer.vue.d.ts +0 -30
  617. package/dist/components/ControlWorkspaceView.vue.d.ts +0 -138
  618. package/dist/components/DoseDesignWorkspaceView.vue.d.ts +0 -140
  619. package/dist/components/ExperimentDataViewer.vue.d.ts +0 -54
  620. package/dist/components/ExperimentTimeline.vue.d.ts +0 -70
  621. package/dist/components/FitPanel.vue.d.ts +0 -56
  622. package/dist/components/GroupAssigner.vue.d.ts +0 -26
  623. package/dist/components/IconButton.vue.d.ts +0 -30
  624. package/dist/components/MobileSupportGate.vue.d.ts +0 -32
  625. package/dist/components/ReagentEditor.vue.d.ts +0 -31
  626. package/dist/components/ReagentList.presentation.d.ts +0 -17
  627. package/dist/components/ReagentList.vue.d.ts +0 -58
  628. package/dist/components/SampleLegend.vue.d.ts +0 -33
  629. package/dist/components/SmartGroupModal.vue.d.ts +0 -29
  630. package/dist/components/index.js +0 -5
  631. package/dist/components-BOA5e7kb.js +0 -23137
  632. package/dist/components-BOA5e7kb.js.map +0 -1
  633. package/dist/composables/flattenWorkspaceBindings.d.ts +0 -61
  634. package/dist/composables/index.js +0 -7
  635. package/dist/composables/useBioTemplateComponents.d.ts +0 -34
  636. package/dist/composables/useBioTemplateControls.d.ts +0 -10
  637. package/dist/composables/useBioTemplatePackWorkspace.d.ts +0 -56
  638. package/dist/composables/useBioTemplatePresetWorkspace.d.ts +0 -79
  639. package/dist/composables/useBioTemplateWorkspace.d.ts +0 -39
  640. package/dist/composables/useExperimentSave.d.ts +0 -69
  641. package/dist/composables/useGroupAssignment.d.ts +0 -35
  642. package/dist/composables/useJobsStatusTray.d.ts +0 -87
  643. package/dist/composables/useMobileSupportGate.d.ts +0 -14
  644. package/dist/composables/usePlatformContext.d.ts +0 -218
  645. package/dist/composables/usePresenceHeartbeat.d.ts +0 -49
  646. package/dist/composables/useRuntimeAlignment.d.ts +0 -44
  647. package/dist/composables/useTemplateCollection.d.ts +0 -62
  648. package/dist/composables/workspaceRecipes.d.ts +0 -189
  649. package/dist/composables-izSQH8Ky.js +0 -591
  650. package/dist/composables-izSQH8Ky.js.map +0 -1
  651. package/dist/experiment-D49y_Kro.js +0 -459
  652. package/dist/experiment-D49y_Kro.js.map +0 -1
  653. package/dist/experiment-utils-DTANyVKV.js.map +0 -1
  654. package/dist/install.js.map +0 -1
  655. package/dist/lcms.d.ts +0 -38
  656. package/dist/settings-BG6v13Zq.js +0 -341
  657. package/dist/settings-BG6v13Zq.js.map +0 -1
  658. package/dist/tailwind.preset.d.ts +0 -63
  659. package/dist/tailwind.preset.js +0 -71
  660. package/dist/tailwind.preset.js.map +0 -1
  661. package/dist/templates/adapters.d.ts +0 -19
  662. package/dist/templates/assayLookups.d.ts +0 -3
  663. package/dist/templates/assayMatrixAdapters.d.ts +0 -13
  664. package/dist/templates/assayMatrixBuilder.d.ts +0 -3
  665. package/dist/templates/assayNormalizers.d.ts +0 -4
  666. package/dist/templates/builderIdUtils.d.ts +0 -4
  667. package/dist/templates/builderPresetControls.d.ts +0 -11
  668. package/dist/templates/builderReadUtils.d.ts +0 -8
  669. package/dist/templates/builders.d.ts +0 -26
  670. package/dist/templates/calibrationCurveAdapters.d.ts +0 -7
  671. package/dist/templates/calibrationCurveBuilder.d.ts +0 -3
  672. package/dist/templates/calibrationNormalizers.d.ts +0 -5
  673. package/dist/templates/catalog.d.ts +0 -192
  674. package/dist/templates/componentBindingCatalog.d.ts +0 -25
  675. package/dist/templates/componentBindingHelpers.d.ts +0 -17
  676. package/dist/templates/componentBindings.d.ts +0 -97
  677. package/dist/templates/componentDoseResponseProps.d.ts +0 -3
  678. package/dist/templates/componentGenericProps.d.ts +0 -8
  679. package/dist/templates/componentPlateHelpers.d.ts +0 -11
  680. package/dist/templates/componentPlateMapProps.d.ts +0 -3
  681. package/dist/templates/componentPropsFactory.d.ts +0 -3
  682. package/dist/templates/componentQpcrPlateProps.d.ts +0 -3
  683. package/dist/templates/componentTargetResolvers.d.ts +0 -5
  684. package/dist/templates/componentTemplateProps.d.ts +0 -3
  685. package/dist/templates/controlSchemaClone.d.ts +0 -4
  686. package/dist/templates/controlSchemaConstants.d.ts +0 -10
  687. package/dist/templates/controlSchemaMerge.d.ts +0 -3
  688. package/dist/templates/controlSchemaTargets.d.ts +0 -17
  689. package/dist/templates/controlSchemaTypes.d.ts +0 -4
  690. package/dist/templates/controlSchemas.d.ts +0 -34
  691. package/dist/templates/defaultBioTemplateBuilder.d.ts +0 -3
  692. package/dist/templates/doseResponseAdapters.d.ts +0 -6
  693. package/dist/templates/doseResponseBuilder.d.ts +0 -3
  694. package/dist/templates/elisaAssayCollectionBuilder.d.ts +0 -3
  695. package/dist/templates/flowCytometryAssayCollectionBuilder.d.ts +0 -3
  696. package/dist/templates/flowCytometryPanelBuilder.d.ts +0 -3
  697. package/dist/templates/flowNormalizers.d.ts +0 -8
  698. package/dist/templates/flowPanelAdapters.d.ts +0 -7
  699. package/dist/templates/index.d.ts +0 -15
  700. package/dist/templates/index.js +0 -2
  701. package/dist/templates/instrumentRunAdapterHelpers.d.ts +0 -8
  702. package/dist/templates/instrumentRunAdapters.d.ts +0 -19
  703. package/dist/templates/instrumentRunBuilder.d.ts +0 -3
  704. package/dist/templates/lcmsBatchCollectionBuilder.d.ts +0 -3
  705. package/dist/templates/lookup.d.ts +0 -4
  706. package/dist/templates/packs.d.ts +0 -21
  707. package/dist/templates/plateMapAdapters.d.ts +0 -5
  708. package/dist/templates/plateMapBuilder.d.ts +0 -3
  709. package/dist/templates/presetControlSchemas.d.ts +0 -534
  710. package/dist/templates/presets.d.ts +0 -106
  711. package/dist/templates/protocolAdapters.d.ts +0 -9
  712. package/dist/templates/protocolNormalizers.d.ts +0 -6
  713. package/dist/templates/protocolStepsBuilder.d.ts +0 -3
  714. package/dist/templates/qpcrAdapters.d.ts +0 -9
  715. package/dist/templates/qpcrExpressionCollectionBuilder.d.ts +0 -3
  716. package/dist/templates/qpcrPlateBuilder.d.ts +0 -3
  717. package/dist/templates/reagentAdapters.d.ts +0 -9
  718. package/dist/templates/reagentListBuilder.d.ts +0 -3
  719. package/dist/templates/runNormalizers.d.ts +0 -10
  720. package/dist/templates/sampleNormalizers.d.ts +0 -4
  721. package/dist/templates/samplePrepAdapters.d.ts +0 -7
  722. package/dist/templates/samplePrepBuilder.d.ts +0 -3
  723. package/dist/templates/sampleSheetAdapters.d.ts +0 -9
  724. package/dist/templates/sampleSheetBuilder.d.ts +0 -3
  725. package/dist/templates/targetedMetabolomicsCollectionBuilder.d.ts +0 -3
  726. package/dist/templates/targetedMetabolomicsHelpers.d.ts +0 -5
  727. package/dist/templates/templateAdapterTypes.d.ts +0 -48
  728. package/dist/templates/templateControlSchemas.d.ts +0 -400
  729. package/dist/templates/templateCreateOptions.d.ts +0 -165
  730. package/dist/templates/templateEnvelopes.d.ts +0 -17
  731. package/dist/templates/templatePackCollectionBuilder.d.ts +0 -3
  732. package/dist/templates/templatePresetCollectionBuilder.d.ts +0 -20
  733. package/dist/templates/templateQpcrTypes.d.ts +0 -42
  734. package/dist/templates/templateValidators.d.ts +0 -25
  735. package/dist/templates/timeCourseAdapters.d.ts +0 -9
  736. package/dist/templates/timeCourseBuilder.d.ts +0 -3
  737. package/dist/templates/types.d.ts +0 -304
  738. package/dist/templates/wellPlateScreenCollectionBuilder.d.ts +0 -3
  739. package/dist/templates/westernBlotAssayCollectionBuilder.d.ts +0 -3
  740. package/dist/templates-B2DB0MCM.js +0 -12304
  741. package/dist/templates-B2DB0MCM.js.map +0 -1
  742. package/dist/utils/rack.d.ts +0 -63
  743. package/dist/validation-C_eH_vIg.js +0 -7999
  744. package/dist/validation-C_eH_vIg.js.map +0 -1
  745. package/src/__tests__/components/AppAvatarMenu.test.ts +0 -186
  746. package/src/__tests__/components/AppTopBar.navigation.test.ts +0 -68
  747. package/src/__tests__/components/AppTopBarPresence.test.ts +0 -47
  748. package/src/__tests__/components/BioTemplateExperimentWorkspaceView.test.ts +0 -159
  749. package/src/__tests__/components/BioTemplatePackWorkspaceView.test.ts +0 -192
  750. package/src/__tests__/components/BioTemplatePresetWorkspaceView.test.ts +0 -307
  751. package/src/__tests__/components/BioTemplateRenderer.test.ts +0 -96
  752. package/src/__tests__/components/ControlWorkspaceView.test.ts +0 -1100
  753. package/src/__tests__/components/DoseDesignWorkspaceView.test.ts +0 -183
  754. package/src/__tests__/components/ExperimentTimeline.test.ts +0 -108
  755. package/src/__tests__/components/FitPanel.test.ts +0 -96
  756. package/src/__tests__/components/GroupAssigner.test.ts +0 -101
  757. package/src/__tests__/components/MobileSupportGate.test.ts +0 -120
  758. package/src/__tests__/components/ReagentList.presentation.test.ts +0 -73
  759. package/src/__tests__/components/ReagentList.test.ts +0 -167
  760. package/src/__tests__/components/SampleLegend.test.ts +0 -18
  761. package/src/__tests__/components/SmartGroupModal.test.ts +0 -69
  762. package/src/__tests__/components/WellPlate.sampleTypeIndicator.test.ts +0 -58
  763. package/src/__tests__/components/iconButtonIconSizing.test.ts +0 -18
  764. package/src/__tests__/composables/useBioTemplatePackWorkspace.test.ts +0 -125
  765. package/src/__tests__/composables/useBioTemplatePresetWorkspace.test.ts +0 -199
  766. package/src/__tests__/composables/useBioTemplateWorkspace.test.ts +0 -104
  767. package/src/__tests__/composables/useExperimentSave.test.ts +0 -542
  768. package/src/__tests__/composables/useGroupAssignment.test.ts +0 -73
  769. package/src/__tests__/composables/useMobileSupportGate.test.ts +0 -74
  770. package/src/__tests__/composables/usePlatformContext.test.ts +0 -148
  771. package/src/__tests__/composables/usePresenceHeartbeat.test.ts +0 -164
  772. package/src/__tests__/composables/useRuntimeAlignment.test.ts +0 -145
  773. package/src/__tests__/composables/useTemplateCollection.test.ts +0 -147
  774. package/src/__tests__/docs/extractDocsTemplates.test.ts +0 -53
  775. package/src/__tests__/fixtures/templates/dose-response.json +0 -81
  776. package/src/__tests__/fixtures/templates/plate-map.json +0 -54
  777. package/src/__tests__/fixtures/templates/qpcr-plate.json +0 -96
  778. package/src/__tests__/fixtures/templates/sample-sheet.json +0 -71
  779. package/src/__tests__/templates/templates.test.ts +0 -1235
  780. package/src/__tests__/templates/templatesDeprecation.test.ts +0 -78
  781. package/src/__tests__/utils/lcms.test.ts +0 -73
  782. package/src/__tests__/utils/rack.test.ts +0 -120
  783. package/src/components/AppAvatarMenu.story.vue +0 -155
  784. package/src/components/AppAvatarMenu.vue +0 -154
  785. package/src/components/AppTopBar.navigation.ts +0 -60
  786. package/src/components/AutoGroupModal.story.vue +0 -458
  787. package/src/components/BaseTextarea.vue +0 -58
  788. package/src/components/BioTemplateExperimentWorkspaceView.story.vue +0 -123
  789. package/src/components/BioTemplateExperimentWorkspaceView.vue +0 -339
  790. package/src/components/BioTemplatePackWorkspaceView.story.vue +0 -107
  791. package/src/components/BioTemplatePackWorkspaceView.vue +0 -180
  792. package/src/components/BioTemplatePresetWorkspaceView.story.vue +0 -163
  793. package/src/components/BioTemplatePresetWorkspaceView.vue +0 -403
  794. package/src/components/BioTemplateRenderer.story.vue +0 -57
  795. package/src/components/BioTemplateRenderer.vue +0 -64
  796. package/src/components/ControlWorkspaceView.story.vue +0 -347
  797. package/src/components/ControlWorkspaceView.vue +0 -370
  798. package/src/components/DoseDesignWorkspaceView.story.vue +0 -77
  799. package/src/components/DoseDesignWorkspaceView.vue +0 -243
  800. package/src/components/ExperimentDataViewer.story.vue +0 -177
  801. package/src/components/ExperimentDataViewer.vue +0 -313
  802. package/src/components/ExperimentTimeline.story.vue +0 -208
  803. package/src/components/ExperimentTimeline.vue +0 -383
  804. package/src/components/FitPanel.story.vue +0 -191
  805. package/src/components/FitPanel.vue +0 -168
  806. package/src/components/FormActions.story.vue +0 -96
  807. package/src/components/GroupAssigner.story.vue +0 -83
  808. package/src/components/GroupAssigner.vue +0 -319
  809. package/src/components/IconButton.story.vue +0 -140
  810. package/src/components/IconButton.vue +0 -69
  811. package/src/components/MobileSupportGate.story.vue +0 -52
  812. package/src/components/MobileSupportGate.vue +0 -111
  813. package/src/components/ReagentEditor.story.vue +0 -153
  814. package/src/components/ReagentEditor.vue +0 -414
  815. package/src/components/ReagentList.presentation.ts +0 -106
  816. package/src/components/ReagentList.story.vue +0 -155
  817. package/src/components/ReagentList.vue +0 -438
  818. package/src/components/SampleLegend.story.vue +0 -91
  819. package/src/components/SampleLegend.vue +0 -121
  820. package/src/components/SmartGroupModal.story.vue +0 -61
  821. package/src/components/SmartGroupModal.vue +0 -61
  822. package/src/components/StatusIndicator.story.vue +0 -99
  823. package/src/components/StatusIndicator.vue +0 -36
  824. package/src/components/UnitInput.story.vue +0 -194
  825. package/src/composables/flattenWorkspaceBindings.ts +0 -104
  826. package/src/composables/useBioTemplateComponents.ts +0 -117
  827. package/src/composables/useBioTemplateControls.ts +0 -45
  828. package/src/composables/useBioTemplatePackWorkspace.ts +0 -201
  829. package/src/composables/useBioTemplatePresetWorkspace.ts +0 -329
  830. package/src/composables/useBioTemplateWorkspace.ts +0 -120
  831. package/src/composables/useChemicalFormula.ts +0 -301
  832. package/src/composables/useDoseCalculator.ts +0 -370
  833. package/src/composables/useExperimentSave.ts +0 -348
  834. package/src/composables/useGroupAssignment.ts +0 -152
  835. package/src/composables/useJobsStatusTray.ts +0 -493
  836. package/src/composables/useMobileSupportGate.ts +0 -80
  837. package/src/composables/usePlatformContext.ts +0 -299
  838. package/src/composables/usePresenceHeartbeat.ts +0 -201
  839. package/src/composables/useRuntimeAlignment.ts +0 -184
  840. package/src/composables/useTemplateCollection.ts +0 -233
  841. package/src/composables/workspaceRecipes.ts +0 -268
  842. package/src/lcms.ts +0 -119
  843. package/src/styles/components/app-avatar-menu.css +0 -121
  844. package/src/styles/components/experiment-data-viewer.css +0 -138
  845. package/src/styles/components/experiment-timeline.css +0 -572
  846. package/src/styles/components/fit-panel.css +0 -153
  847. package/src/styles/components/group-assigner.css +0 -198
  848. package/src/styles/components/mobile-support-gate.css +0 -117
  849. package/src/styles/components/reagent-editor.css +0 -501
  850. package/src/styles/components/reagent-list.css +0 -408
  851. package/src/styles/components/sample-legend.css +0 -212
  852. package/src/styles/components/status-indicator.css +0 -66
  853. package/src/styles/components/theme-toggle.css +0 -6
  854. package/src/tailwind.preset.ts +0 -66
  855. package/src/templates/adapters.ts +0 -141
  856. package/src/templates/assayLookups.ts +0 -33
  857. package/src/templates/assayMatrixAdapters.ts +0 -85
  858. package/src/templates/assayMatrixBuilder.ts +0 -60
  859. package/src/templates/assayNormalizers.ts +0 -34
  860. package/src/templates/builderIdUtils.ts +0 -20
  861. package/src/templates/builderPresetControls.ts +0 -166
  862. package/src/templates/builderReadUtils.ts +0 -55
  863. package/src/templates/builders.ts +0 -122
  864. package/src/templates/calibrationCurveAdapters.ts +0 -62
  865. package/src/templates/calibrationCurveBuilder.ts +0 -100
  866. package/src/templates/calibrationNormalizers.ts +0 -60
  867. package/src/templates/catalog.ts +0 -249
  868. package/src/templates/componentBindingCatalog.ts +0 -90
  869. package/src/templates/componentBindingHelpers.ts +0 -93
  870. package/src/templates/componentBindings.ts +0 -279
  871. package/src/templates/componentDoseResponseProps.ts +0 -41
  872. package/src/templates/componentGenericProps.ts +0 -77
  873. package/src/templates/componentPlateHelpers.ts +0 -52
  874. package/src/templates/componentPlateMapProps.ts +0 -34
  875. package/src/templates/componentPropsFactory.ts +0 -21
  876. package/src/templates/componentQpcrPlateProps.ts +0 -27
  877. package/src/templates/componentTargetResolvers.ts +0 -67
  878. package/src/templates/componentTemplateProps.ts +0 -78
  879. package/src/templates/controlSchemaClone.ts +0 -32
  880. package/src/templates/controlSchemaConstants.ts +0 -11
  881. package/src/templates/controlSchemaMerge.ts +0 -40
  882. package/src/templates/controlSchemaTargets.ts +0 -85
  883. package/src/templates/controlSchemaTypes.ts +0 -20
  884. package/src/templates/controlSchemas.ts +0 -113
  885. package/src/templates/defaultBioTemplateBuilder.ts +0 -125
  886. package/src/templates/doseResponseAdapters.ts +0 -36
  887. package/src/templates/doseResponseBuilder.ts +0 -45
  888. package/src/templates/elisaAssayCollectionBuilder.ts +0 -63
  889. package/src/templates/flowCytometryAssayCollectionBuilder.ts +0 -42
  890. package/src/templates/flowCytometryPanelBuilder.ts +0 -54
  891. package/src/templates/flowNormalizers.ts +0 -58
  892. package/src/templates/flowPanelAdapters.ts +0 -61
  893. package/src/templates/index.ts +0 -330
  894. package/src/templates/instrumentRunAdapterHelpers.ts +0 -94
  895. package/src/templates/instrumentRunAdapters.ts +0 -174
  896. package/src/templates/instrumentRunBuilder.ts +0 -98
  897. package/src/templates/lcmsBatchCollectionBuilder.ts +0 -39
  898. package/src/templates/lookup.ts +0 -18
  899. package/src/templates/packs.ts +0 -166
  900. package/src/templates/plateMapAdapters.ts +0 -38
  901. package/src/templates/plateMapBuilder.ts +0 -44
  902. package/src/templates/presetControlSchemas.ts +0 -258
  903. package/src/templates/presets.ts +0 -183
  904. package/src/templates/protocolAdapters.ts +0 -73
  905. package/src/templates/protocolNormalizers.ts +0 -37
  906. package/src/templates/protocolStepsBuilder.ts +0 -37
  907. package/src/templates/qpcrAdapters.ts +0 -108
  908. package/src/templates/qpcrExpressionCollectionBuilder.ts +0 -34
  909. package/src/templates/qpcrPlateBuilder.ts +0 -97
  910. package/src/templates/reagentAdapters.ts +0 -81
  911. package/src/templates/reagentListBuilder.ts +0 -31
  912. package/src/templates/runNormalizers.ts +0 -63
  913. package/src/templates/sampleNormalizers.ts +0 -58
  914. package/src/templates/samplePrepAdapters.ts +0 -66
  915. package/src/templates/samplePrepBuilder.ts +0 -52
  916. package/src/templates/sampleSheetAdapters.ts +0 -79
  917. package/src/templates/sampleSheetBuilder.ts +0 -24
  918. package/src/templates/targetedMetabolomicsCollectionBuilder.ts +0 -80
  919. package/src/templates/targetedMetabolomicsHelpers.ts +0 -102
  920. package/src/templates/templateAdapterTypes.ts +0 -58
  921. package/src/templates/templateControlSchemas.ts +0 -320
  922. package/src/templates/templateCreateOptions.ts +0 -208
  923. package/src/templates/templateEnvelopes.ts +0 -145
  924. package/src/templates/templatePackCollectionBuilder.ts +0 -24
  925. package/src/templates/templatePresetCollectionBuilder.ts +0 -141
  926. package/src/templates/templateQpcrTypes.ts +0 -48
  927. package/src/templates/templateValidators.ts +0 -426
  928. package/src/templates/timeCourseAdapters.ts +0 -77
  929. package/src/templates/timeCourseBuilder.ts +0 -65
  930. package/src/templates/types.ts +0 -493
  931. package/src/templates/wellPlateScreenCollectionBuilder.ts +0 -37
  932. package/src/templates/westernBlotAssayCollectionBuilder.ts +0 -69
  933. package/src/utils/rack.ts +0 -225
  934. /package/dist/__tests__/components/{AppAvatarMenu.test.d.ts → BaseButton.test.d.ts} +0 -0
  935. /package/dist/__tests__/components/{AppTopBar.navigation.test.d.ts → BaseCheckbox.switch.test.d.ts} +0 -0
  936. /package/dist/__tests__/components/{AppTopBarPresence.test.d.ts → BaseSelect.multiple.test.d.ts} +0 -0
  937. /package/dist/__tests__/components/{BaseToggle.test.d.ts → BaseSelect.searchable.test.d.ts} +0 -0
  938. /package/dist/__tests__/components/{BioTemplateExperimentWorkspaceView.test.d.ts → ConfirmDialog.test.d.ts} +0 -0
  939. /package/dist/__tests__/components/{BioTemplatePackWorkspaceView.test.d.ts → DatePicker.datetime.test.d.ts} +0 -0
  940. /package/dist/__tests__/components/{BioTemplatePresetWorkspaceView.test.d.ts → DatePicker.time.test.d.ts} +0 -0
  941. /package/dist/__tests__/components/{BioTemplateRenderer.test.d.ts → FormSchemaInternal.test.d.ts} +0 -0
  942. /package/dist/__tests__/components/{ControlWorkspaceView.test.d.ts → InstrumentStatusPanels.test.d.ts} +0 -0
  943. /package/dist/__tests__/components/{DateTimePicker.test.d.ts → NumberInput.units.test.d.ts} +0 -0
  944. /package/dist/__tests__/components/{DoseDesignWorkspaceView.test.d.ts → PresenceAvatars.test.d.ts} +0 -0
  945. /package/dist/__tests__/components/{ExperimentTimeline.test.d.ts → StaleFormBanner.test.d.ts} +0 -0
  946. /package/dist/__tests__/components/{FitPanel.test.d.ts → deprecationTags.test.d.ts} +0 -0
  947. /package/dist/__tests__/{components/GroupAssigner.test.d.ts → composables/createClient.test.d.ts} +0 -0
  948. /package/dist/__tests__/{components/MobileSupportGate.test.d.ts → composables/eventStream.test.d.ts} +0 -0
  949. /package/dist/__tests__/{components/MultiSelect.test.d.ts → composables/useArtifacts.test.d.ts} +0 -0
  950. /package/dist/__tests__/{components/ReagentList.presentation.test.d.ts → composables/useExperiment.test.d.ts} +0 -0
  951. /package/dist/__tests__/{components/ReagentList.test.d.ts → composables/useJobCenter.test.d.ts} +0 -0
  952. /package/dist/__tests__/{components/SampleLegend.test.d.ts → composables/useJobsEndpoint.test.d.ts} +0 -0
  953. /package/dist/__tests__/{components/SearchableSelect.test.d.ts → composables/usePlatform.test.d.ts} +0 -0
  954. /package/dist/__tests__/{components/SmartGroupModal.test.d.ts → composables/usePresence.test.d.ts} +0 -0
  955. /package/dist/__tests__/{components/TimePicker.test.d.ts → composables/useRealtime.test.d.ts} +0 -0
  956. /package/dist/__tests__/{components/UnitInput.test.d.ts → composables/useRequest.test.d.ts} +0 -0
  957. /package/dist/__tests__/{components/WellPlate.sampleTypeIndicator.test.d.ts → composables/useVersionedSave.test.d.ts} +0 -0
  958. /package/dist/__tests__/{components/iconButtonIconSizing.test.d.ts → utils/formula.test.d.ts} +0 -0
  959. /package/dist/__tests__/{composables/useAnalysisArtifacts.test.d.ts → utils/time.test.d.ts} +0 -0
  960. /package/dist/components/{FormActions.vue.d.ts → internal/FormActionsInternal.vue.d.ts} +0 -0
  961. /package/dist/{composables → components/internal}/autoGroup/colors.d.ts +0 -0
  962. /package/dist/{composables → components/internal}/autoGroup/index.d.ts +0 -0
  963. /package/dist/{composables → components/internal}/autoGroup/tokenize.d.ts +0 -0
  964. /package/src/{composables → components/internal}/autoGroup/colors.ts +0 -0
  965. /package/src/{composables → components/internal}/autoGroup/tokenize.ts +0 -0
  966. /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"}
@@ -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 './useConcentrationUnits';
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
- export interface UseDoseCalculatorReturn {
48
- volumeUnits: VolumeUnit[];
49
- calculateDilution: (params: DilutionParams) => DilutionResult;
50
- calculateSerialDilution: (params: SerialDilutionParams) => SerialDilutionResult;
51
- convertMassToMolar: (mass: number, massUnit: MassVolumeUnit, mw: number) => ConcentrationValue;
52
- convertMolarToMass: (molar: number, molarUnit: MolarityUnit, mw: number) => ConcentrationValue;
53
- convertVolume: (value: number, from: VolumeUnit, to: VolumeUnit) => number;
54
- formatVolume: (volume: VolumeValue, precision?: number) => string;
55
- generateWellConcentrations: (result: SerialDilutionResult, wellIds: string[]) => WellConcentration[];
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
- /** Parses and renders chemical formulas, computes molecular weight, and generates rich-text formula parts. */
18
- export declare function useChemicalFormula(): {
19
- parseFormula: (formula: string) => FormulaParseResult;
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 PLUGIN_SECRET_REF_KEY = "$secret";
18
+ export declare const REF_KEY = "$secret";
19
19
  /** Reserved payload key declaring which secret wire format a client speaks. */
20
- export declare const PLUGIN_SECRET_FORMAT_KEY = "secret_format";
20
+ export declare const FORMAT_KEY = "secret_format";
21
21
  /** Wire format published and understood by this SDK. */
22
- export declare const PLUGIN_SECRET_FORMAT_REF = "ref";
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 isPluginSecretRef(value: unknown): value is PluginSecretRef;
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 pluginSecretId(value: unknown): string | null;
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 pluginSecretState(value: unknown): PluginSecretState;
36
+ export declare function state(value: unknown): PluginSecretState;
37
37
  /** Human label for one secret field's state. */
38
- export declare function pluginSecretLabel(value: unknown): string;
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 isPluginSecretLocked(value: unknown): boolean;
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 keepPluginSecret(current: unknown): PluginSecretRef | null;
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 setPluginSecret(value: string): string;
49
+ export declare function set(value: string): string;
50
50
  /** Value to submit when the user cleared a secret. */
51
- export declare function clearPluginSecret(): null;
51
+ export declare function clear(): null;
52
52
  /** Whether a settings response declares the `$secret` reference wire format. */
53
- export declare function usesPluginSecretReferences(response: unknown): boolean;
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;
@@ -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.8",
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
- "./components": {
23
- "types": "./dist/components/index.d.ts",
24
- "import": "./dist/components/index.js"
22
+ "./lab": {
23
+ "types": "./dist/lab.d.ts",
24
+ "import": "./dist/lab.js"
25
25
  },
26
- "./composables": {
27
- "types": "./dist/composables/index.d.ts",
28
- "import": "./dist/composables/index.js"
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: { type: 'warning', actionLabel: 'Recalibrate' } })
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']),