@morscherlab/mint-sdk 1.3.9 → 1.4.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -1,1235 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
- import {
3
- assertTemplateEnvelope,
4
- bioTemplatePresetControlValuesToOptions,
5
- createBioTemplatePackCollection,
6
- createBioTemplatePresetCollection,
7
- createBioTemplatePresetCollectionFromControls,
8
- createAssayMatrixTemplate,
9
- createCalibrationCurveTemplate,
10
- createDoseResponseTemplate,
11
- createElisaAssayCollection,
12
- createFlowCytometryAssayCollection,
13
- createFlowCytometryPanelTemplate,
14
- createInstrumentRunTemplate,
15
- createLcmsBatchCollection,
16
- createPlateMapTemplate,
17
- createProtocolStepsTemplate,
18
- createQpcrExpressionCollection,
19
- createQpcrPlateTemplate,
20
- createReagentListTemplate,
21
- createSampleSheetTemplate,
22
- createSamplePrepTemplate,
23
- createTargetedMetabolomicsCollection,
24
- createDefaultBioTemplate,
25
- createTemplateCollection,
26
- createTimeCourseTemplate,
27
- createWellPlateScreenCollection,
28
- createWesternBlotAssayCollection,
29
- ensureTemplateEnvelope,
30
- ensureTemplateFromCollection,
31
- extractTemplateCollection,
32
- getBioTemplateComponentBindings,
33
- getBioTemplateComponentProps,
34
- getBioTemplateControlDefaults,
35
- getBioTemplateControlSchema,
36
- getBioTemplatePackInfo,
37
- getBioTemplatePresetInfo,
38
- getBioTemplateInfo,
39
- listBioTemplateCatalog,
40
- listBioTemplateComponentBindings,
41
- listBioTemplateControlSchemas,
42
- listBioTemplatePacks,
43
- listBioTemplatePresets,
44
- searchBioTemplatePacks,
45
- searchBioTemplateCatalog,
46
- searchBioTemplatePresets,
47
- toBioTemplateComponentBindings,
48
- toBioTemplateComponentBindingsById,
49
- toBioTemplateComponentImports,
50
- toBioTemplateComponentProps,
51
- toBioTemplateComponentPropsByComponent,
52
- toBioTemplateComponentPropsById,
53
- toBioTemplateComponentSnippets,
54
- toBioTemplateComponentUsage,
55
- toAssayMatrixColumns,
56
- toAssayMatrixDataFrame,
57
- toAssayMatrixRows,
58
- toAssayMatrixSampleOptions,
59
- toCalibrationCurveDataFrame,
60
- toCalibrationCurveRows,
61
- toDoseConditions,
62
- toDoseLayoutState,
63
- toFlowPanelDataFrame,
64
- toFlowPanelRows,
65
- toInstrumentRunDataFrame,
66
- toInstrumentRunRows,
67
- toInstrumentRunScheduleEvents,
68
- toInstrumentRunSteps,
69
- racksFromPlateState,
70
- toPlateMapEditorState,
71
- toProtocolDataFrame,
72
- toProtocolSteps,
73
- toQpcrDataFrame,
74
- toQpcrRows,
75
- toQpcrWellPlateWells,
76
- toReagentDataFrame,
77
- toReagentListItems,
78
- toSampleColumns,
79
- toSampleDataFrame,
80
- toSampleOptions,
81
- toSamplePrepDataFrame,
82
- toSamplePrepRows,
83
- toSampleRows,
84
- toTemplateDataFrame,
85
- toTimeCourseDataFrame,
86
- toTimeCourseRows,
87
- toTimeCourseSteps,
88
- toWellPlateWells,
89
- TEMPLATE_COLLECTION_KEY,
90
- } from '../../templates'
91
- import bioTemplateCatalogContract from '../../../../bio-template-catalog.contract.json'
92
- import bioTemplatePacksContract from '../../../../bio-template-packs.contract.json'
93
- import bioTemplatePresetsContract from '../../../../bio-template-presets.contract.json'
94
- import type {
95
- AssayMatrixTemplate,
96
- DoseResponseTemplate,
97
- FlowCytometryPanelTemplate,
98
- InstrumentRunTemplate,
99
- PlateMapTemplate,
100
- ProtocolStepsTemplate,
101
- QpcrPlateTemplate,
102
- ReagentListTemplate,
103
- SampleSheetTemplate,
104
- } from '../../templates'
105
- import doseResponseFixture from '../fixtures/templates/dose-response.json'
106
- import plateMapFixture from '../fixtures/templates/plate-map.json'
107
- import qpcrPlateFixture from '../fixtures/templates/qpcr-plate.json'
108
- import sampleSheetFixture from '../fixtures/templates/sample-sheet.json'
109
-
110
- describe('bio data templates', () => {
111
- it('exposes a discoverable template catalog', () => {
112
- const catalog = listBioTemplateCatalog()
113
-
114
- expect(catalog.map(entry => entry.name)).toEqual([
115
- 'plate-map',
116
- 'sample-sheet',
117
- 'sample-prep',
118
- 'dose-response',
119
- 'calibration-curve',
120
- 'time-course',
121
- 'protocol-steps',
122
- 'assay-matrix',
123
- 'reagent-list',
124
- 'flow-cytometry-panel',
125
- 'instrument-run',
126
- 'qpcr-plate',
127
- ])
128
- expect(getBioTemplateInfo('wellplate')?.template_id).toBe('plate-map')
129
- expect(getBioTemplateInfo('sample preparation')?.template_id).toBe('sample-prep')
130
- expect(getBioTemplateInfo('dose design')?.template_id).toBe('dose-response')
131
- expect(getBioTemplateInfo('dose-design')?.template_id).toBe('dose-response')
132
- expect(getBioTemplateInfo('dose calculator')?.template_id).toBe('dose-response')
133
- expect(getBioTemplateInfo('dose_calculator')?.template_id).toBe('dose-response')
134
- expect(getBioTemplateInfo('protocol')?.template_id).toBe('protocol-steps')
135
- expect(getBioTemplateInfo('standard curve')?.template_id).toBe('calibration-curve')
136
- expect(getBioTemplateInfo('omics matrix')?.template_id).toBe('assay-matrix')
137
- expect(getBioTemplateInfo('antibodies')?.template_id).toBe('reagent-list')
138
- expect(getBioTemplateInfo('facs panel')?.template_id).toBe('flow-cytometry-panel')
139
- expect(getBioTemplateInfo('run queue')?.template_id).toBe('instrument-run')
140
- expect(getBioTemplateInfo('gene expression')?.template_id).toBe('qpcr-plate')
141
- expect(searchBioTemplateCatalog('DoseCalculator')[0].name).toBe('dose-response')
142
- })
143
-
144
- it('matches the shared Python/frontend catalog contract', () => {
145
- expect(listBioTemplateCatalog()).toEqual(bioTemplateCatalogContract)
146
- })
147
-
148
- it('exposes discoverable template collection packs', () => {
149
- const packs = listBioTemplatePacks()
150
-
151
- expect(packs.map(entry => entry.name)).toEqual([
152
- 'cell-culture-screen',
153
- 'omics-assay',
154
- 'longitudinal-study',
155
- 'molecular-assay',
156
- ])
157
- expect(getBioTemplatePackInfo('cell culture')?.templates).toEqual([
158
- 'sample-sheet',
159
- 'sample-prep',
160
- 'plate-map',
161
- 'reagent-list',
162
- 'protocol-steps',
163
- 'dose-response',
164
- 'flow-cytometry-panel',
165
- ])
166
- expect(getBioTemplatePackInfo('metabolomics')?.name).toBe('omics-assay')
167
- expect(getBioTemplatePackInfo('metabolism')?.name).toBe('omics-assay')
168
- expect(getBioTemplatePackInfo('metabolite profiling')?.name).toBe('omics-assay')
169
- expect(getBioTemplatePackInfo('metabolomics')?.components).toContain('ExperimentTimeline')
170
- expect(getBioTemplatePackInfo('longitudinal')?.add_command).toBe('mint add data-template-pack longitudinal-study --page')
171
- expect(getBioTemplatePackInfo('gene expression')?.templates.at(-1)).toBe('qpcr-plate')
172
- expect(getBioTemplatePackInfo('gene-expression')?.templates.at(-1)).toBe('qpcr-plate')
173
- expect(searchBioTemplatePacks('WellPlate').map(entry => entry.name)).toEqual([
174
- 'cell-culture-screen',
175
- 'omics-assay',
176
- 'molecular-assay',
177
- ])
178
- })
179
-
180
- it('matches the shared Python/frontend pack contract', () => {
181
- expect(listBioTemplatePacks()).toEqual(bioTemplatePacksContract)
182
- })
183
-
184
- it('creates default template collections from curated packs', () => {
185
- const plate = createDefaultBioTemplate('wellplate') as PlateMapTemplate
186
- const pack = createBioTemplatePackCollection('cell culture')
187
- const templates = extractTemplateCollection(pack)
188
-
189
- expect(plate.template_id).toBe('plate-map')
190
- expect(pack.metadata?.pack).toBe('cell-culture-screen')
191
- expect(Object.keys(templates)).toEqual([
192
- 'sample-sheet',
193
- 'sample-prep',
194
- 'plate-map',
195
- 'reagent-list',
196
- 'protocol-steps',
197
- 'dose-response',
198
- 'flow-cytometry-panel',
199
- ])
200
- expect(toPlateMapEditorState(templates['plate-map'] as PlateMapTemplate).samples).toHaveLength(2)
201
- expect(toDoseConditions(templates['dose-response'] as DoseResponseTemplate)[0].label).toBe('Compound A')
202
- expect(getBioTemplateControlSchema('cell-culture-screen')?.sampleSheetSampleCount.default).toBe(2)
203
- expect(getBioTemplateComponentBindings('cell-culture-screen').map(binding => binding.component)).toContain('DoseCalculator')
204
- expect(() => createBioTemplatePackCollection('missing-pack')).toThrow("Unknown template pack 'missing-pack'.")
205
- })
206
-
207
- it('exposes discoverable template collection presets', () => {
208
- const presets = listBioTemplatePresets()
209
-
210
- expect(presets.map(entry => entry.name)).toEqual([
211
- 'wellplate-screen',
212
- 'qpcr-expression',
213
- 'lcms-batch',
214
- 'targeted-metabolomics',
215
- 'elisa-assay',
216
- 'flow-cytometry-assay',
217
- 'western-blot-assay',
218
- ])
219
- expect(getBioTemplatePresetInfo('wellplate')?.name).toBe('wellplate-screen')
220
- expect(getBioTemplatePresetInfo('dose planner')?.name).toBe('wellplate-screen')
221
- expect(getBioTemplatePresetInfo('dose-planner')?.name).toBe('wellplate-screen')
222
- expect(getBioTemplatePresetInfo('gene expression')?.templates).toEqual([
223
- 'sample-sheet',
224
- 'qpcr-plate',
225
- ])
226
- expect(searchBioTemplatePresets('run queue')[0].name).toBe('lcms-batch')
227
- expect(getBioTemplatePresetInfo('metabolomics')?.name).toBe('lcms-batch')
228
- expect(getBioTemplatePresetInfo('metabolism')?.name).toBe('lcms-batch')
229
- expect(getBioTemplatePresetInfo('metabolite profiling')?.name).toBe('lcms-batch')
230
- expect(getBioTemplatePresetInfo('targeted metabolomics')?.name).toBe('targeted-metabolomics')
231
- expect(searchBioTemplatePresets('internal standards')[0].name).toBe('targeted-metabolomics')
232
- expect(getBioTemplatePresetInfo('immunoassay')?.templates).toEqual([
233
- 'plate-map',
234
- 'sample-sheet',
235
- 'calibration-curve',
236
- 'assay-matrix',
237
- ])
238
- expect(getBioTemplatePresetInfo('facs')?.templates).toEqual([
239
- 'sample-sheet',
240
- 'flow-cytometry-panel',
241
- 'assay-matrix',
242
- ])
243
- expect(getBioTemplatePresetInfo('immunoblot')?.templates).toEqual([
244
- 'sample-sheet',
245
- 'reagent-list',
246
- 'protocol-steps',
247
- 'assay-matrix',
248
- ])
249
- })
250
-
251
- it('matches the shared Python/frontend preset contract', () => {
252
- expect(listBioTemplatePresets()).toEqual(bioTemplatePresetsContract)
253
- })
254
-
255
- it('should not recommend AutoGroupModal when it is scheduled for removal', () => {
256
- const components = listBioTemplateCatalog().flatMap(entry => entry.components)
257
-
258
- expect(components).not.toContain('AutoGroupModal')
259
- })
260
-
261
- it('prefers generic dataframe adapters in catalog entries', () => {
262
- const dataframeTemplates = listBioTemplateCatalog().filter(entry =>
263
- entry.components.includes('DataFrame')
264
- )
265
-
266
- expect(dataframeTemplates.map(entry => entry.name)).toEqual([
267
- 'sample-sheet',
268
- 'sample-prep',
269
- 'calibration-curve',
270
- 'time-course',
271
- 'protocol-steps',
272
- 'assay-matrix',
273
- 'reagent-list',
274
- 'flow-cytometry-panel',
275
- 'instrument-run',
276
- 'qpcr-plate',
277
- ])
278
- for (const entry of dataframeTemplates) {
279
- expect(entry.frontend_adapters[0]).toBe('toTemplateDataFrame')
280
- expect(entry.frontend_import).toContain('toTemplateDataFrame')
281
- }
282
- })
283
-
284
- it('exposes control schemas for built-in templates and presets', () => {
285
- const schemas = listBioTemplateControlSchemas()
286
- const plateSchema = getBioTemplateControlSchema('wellplate')
287
- const presetSchema = getBioTemplateControlSchema('wellplate-screen')
288
- const defaults = getBioTemplateControlDefaults('lcms-batch')
289
- const targetedDefaults = getBioTemplateControlDefaults('targeted-metabolomics')
290
- const elisaDefaults = getBioTemplateControlDefaults('elisa-assay')
291
- const flowDefaults = getBioTemplateControlDefaults('flow-cytometry-assay')
292
- const westernDefaults = getBioTemplateControlDefaults('western-blot-assay')
293
-
294
- expect(Object.keys(schemas)).toContain('plate-map')
295
- expect(plateSchema?.plateFormat.default).toBe(96)
296
- expect(presetSchema?.replicates.default).toBe(3)
297
- expect(defaults.instrument).toBe('LC-MS')
298
- expect(defaults.featureNames).toEqual(['Glucose', 'Lactate'])
299
- expect(targetedDefaults.metaboliteNames).toEqual(['Glucose', 'Lactate', 'Pyruvate'])
300
- expect(targetedDefaults.internalStandards).toEqual(['Stable isotope internal standard mix'])
301
- expect(targetedDefaults.method).toBe('Targeted metabolomics')
302
- expect(elisaDefaults.analyte).toBe('Analyte')
303
- expect(elisaDefaults.standardConcentrations).toEqual(['1000', '100', '10', '1'])
304
- expect(flowDefaults.markers).toEqual(['CD3', 'CD4', 'CD8'])
305
- expect(flowDefaults.includeDefaultControls).toBe(true)
306
- expect(westernDefaults.targets).toEqual(['Target protein'])
307
- expect(westernDefaults.loadingControl).toBe('ACTB')
308
- })
309
-
310
- it('exposes component bindings for template-driven frontend rendering', () => {
311
- const bindings = listBioTemplateComponentBindings()
312
- const wellplateBindings = getBioTemplateComponentBindings('wellplate-screen')
313
- const qpcrBindings = getBioTemplateComponentBindings('gene expression')
314
- const elisaBindings = getBioTemplateComponentBindings('elisa-assay')
315
- const flowBindings = getBioTemplateComponentBindings('flow-cytometry-assay')
316
- const lcmsBindings = getBioTemplateComponentBindings('lcms-batch')
317
- const targetedBindings = getBioTemplateComponentBindings('targeted-metabolomics')
318
- const westernBindings = getBioTemplateComponentBindings('western-blot-assay')
319
- const wellplateImports = toBioTemplateComponentImports('wellplate-screen')
320
-
321
- expect(bindings['plate-map'].map(binding => binding.component)).toEqual(['PlateEditor', 'WellPlate'])
322
- expect(wellplateBindings.map(binding => binding.component)).toContain('DoseCalculator')
323
- expect(wellplateBindings.map(binding => binding.component)).toContain('WellPlate')
324
- expect(qpcrBindings.map(binding => binding.component)).toContain('WellPlate')
325
- expect(qpcrBindings.map(binding => binding.component)).toContain('DataFrame')
326
- expect(elisaBindings.map(binding => binding.component)).toContain('PlateEditor')
327
- expect(elisaBindings.map(binding => binding.component)).toContain('DataFrame')
328
- expect(lcmsBindings.map(binding => binding.component)).toContain('ScheduleCalendar')
329
- expect(lcmsBindings.map(binding => binding.component)).toContain('ExperimentTimeline')
330
- expect(targetedBindings.map(binding => binding.component)).toContain('ReagentList')
331
- expect(targetedBindings.map(binding => binding.component)).toContain('DataFrame')
332
- expect(targetedBindings.map(binding => binding.component)).toContain('ScheduleCalendar')
333
- expect(flowBindings.map(binding => binding.template_id)).toEqual([
334
- 'sample-sheet',
335
- 'sample-sheet',
336
- 'flow-cytometry-panel',
337
- 'assay-matrix',
338
- 'assay-matrix',
339
- ])
340
- expect(westernBindings.map(binding => binding.component)).toContain('ReagentList')
341
- expect(westernBindings.map(binding => binding.component)).toContain('ExperimentTimeline')
342
- expect(wellplateImports).toEqual([
343
- {
344
- importPath: '@morscherlab/mint-sdk',
345
- components: ['PlateEditor', 'WellPlate', 'DataFrame', 'SampleSelector', 'DoseCalculator'],
346
- statement: "import { PlateEditor, WellPlate, DataFrame, SampleSelector, DoseCalculator } from '@morscherlab/mint-sdk'",
347
- },
348
- ])
349
- })
350
-
351
- it('creates plate-map envelopes and adapts them to plate editor state', () => {
352
- const template = createPlateMapTemplate({
353
- name: 'Drug screen plate',
354
- samples: ['DMSO', 'Drug A'],
355
- })
356
- const state = toPlateMapEditorState(template)
357
-
358
- expect(template.template_id).toBe('plate-map')
359
- expect(state.activePlateId).toBe('plate-1')
360
- expect(state.plates[0].format).toBe(96)
361
- expect(state.samples[1].id).toBe('drug-a')
362
- })
363
-
364
- it('should convert plate-map state into PlateEditor racks', () => {
365
- const state = toPlateMapEditorState(createPlateMapTemplate({ samples: ['DMSO'] }))
366
-
367
- expect(racksFromPlateState(state)[0]).toMatchObject({ id: 'plate-1', format: 96, slot: 'R' })
368
- })
369
-
370
- it('loads the shared plate-map fixture', () => {
371
- const state = toPlateMapEditorState(plateMapFixture as PlateMapTemplate)
372
- const wells = toWellPlateWells(plateMapFixture as PlateMapTemplate)
373
- const componentProps = toBioTemplateComponentProps(plateMapFixture as PlateMapTemplate)
374
- const componentBindings = toBioTemplateComponentBindings(plateMapFixture as PlateMapTemplate)
375
- const componentPropsById = toBioTemplateComponentPropsById(plateMapFixture as PlateMapTemplate)
376
- const componentBindingsById = toBioTemplateComponentBindingsById(plateMapFixture as PlateMapTemplate)
377
- const wellPlate = componentProps.find(binding => binding.component === 'WellPlate')
378
- const wellPlateBinding = componentBindings.find(binding => binding.component === 'WellPlate')
379
-
380
- expect(state.plates[0].name).toBe('Drug screen plate')
381
- expect(wells.A2.sampleType).toBe('drug-a')
382
- expect(wellPlate?.propsObject.format).toBe(96)
383
- expect((wellPlate?.propsObject.wells as Record<string, { sampleType?: string }>).A2.sampleType).toBe('drug-a')
384
- expect(wellPlateBinding?.props.format).toBe(96)
385
- expect(wellPlateBinding?.propNames).toContain('wells')
386
- expect(componentPropsById['plate-map:WellPlate']).toEqual(wellPlate?.propsObject)
387
- expect(componentBindingsById['plate-map:WellPlate'].component).toBe('WellPlate')
388
- expect(componentBindingsById['plate-map:WellPlate'].props).toEqual(wellPlate?.propsObject)
389
- expect((componentPropsById['plate-map:WellPlate'].wells as Record<string, { sampleType?: string }>).A2.sampleType).toBe('drug-a')
390
- })
391
-
392
- it('returns component props keyed by stable template component id', () => {
393
- const collection = createWellPlateScreenCollection({
394
- samples: ['Control', 'Treatment'],
395
- compounds: { 'Drug A': [10, 1] },
396
- })
397
- const propsById = toBioTemplateComponentPropsById(collection)
398
- const bindingsById = toBioTemplateComponentBindingsById(collection)
399
- const propsByComponent = toBioTemplateComponentPropsByComponent(collection)
400
- const doseCalculatorProps = getBioTemplateComponentProps(collection, 'DoseCalculator')
401
- const doseWellPlateProps = getBioTemplateComponentProps(collection, 'WellPlate', {
402
- templateId: 'dose-response',
403
- })
404
-
405
- expect(Object.keys(propsById)).toEqual([
406
- 'plate-map:PlateEditor',
407
- 'plate-map:WellPlate',
408
- 'sample-sheet:DataFrame',
409
- 'sample-sheet:SampleSelector',
410
- 'dose-response:DoseCalculator',
411
- 'dose-response:WellPlate',
412
- ])
413
- expect(propsById['dose-response:DoseCalculator'].mode).toBe('serial')
414
- expect(bindingsById['dose-response:DoseCalculator'].props.mode).toBe('serial')
415
- expect(bindingsById['dose-response:DoseCalculator'].propNames).toContain('mode')
416
- expect(propsById['plate-map:WellPlate'].wells).toBeDefined()
417
- expect(propsById['dose-response:WellPlate'].wells).toBeDefined()
418
- expect(propsByComponent.WellPlate).toHaveLength(2)
419
- expect(propsByComponent.DoseCalculator[0].mode).toBe('serial')
420
- expect(doseCalculatorProps?.mode).toBe('serial')
421
- expect(doseWellPlateProps?.wells).toBeDefined()
422
- expect(getBioTemplateComponentProps(collection, 'MissingWidget')).toBeUndefined()
423
- })
424
-
425
- it('creates ELISA assay preset collections with plate, standards, and readout matrix', () => {
426
- const collection = createElisaAssayCollection({
427
- samples: ['Control', 'Treatment'],
428
- analyte: 'IL-6',
429
- standardConcentrations: [1000, 100, 10, 1],
430
- unit: 'pg/mL',
431
- })
432
- const templates = extractTemplateCollection(collection)
433
- const componentPropsById = toBioTemplateComponentPropsById(collection)
434
-
435
- expect(Object.keys(templates)).toEqual([
436
- 'plate-map',
437
- 'sample-sheet',
438
- 'calibration-curve',
439
- 'assay-matrix',
440
- ])
441
- expect(collection.metadata?.preset).toBe('elisa-assay')
442
- expect(templates['calibration-curve'].data).toMatchObject({
443
- analyte: 'IL-6',
444
- model: 'four-parameter-logistic',
445
- xUnit: 'pg/mL',
446
- responseUnit: 'OD450',
447
- })
448
- expect(templates['assay-matrix'].data).toMatchObject({
449
- features: [{ id: 'il-6', name: 'IL-6', type: 'protein', unit: 'OD450', metadata: {} }],
450
- })
451
- expect(componentPropsById['plate-map:WellPlate'].wells).toBeDefined()
452
- expect(componentPropsById['calibration-curve:DataFrame'].data).toBeDefined()
453
- expect(componentPropsById['assay-matrix:DataFrame'].columns).toBeDefined()
454
- expect(componentPropsById['assay-matrix:SampleSelector'].samples).toEqual(['Control', 'Treatment'])
455
- })
456
-
457
- it('generates Vue snippets for concrete template component props', () => {
458
- const snippets = toBioTemplateComponentSnippets(plateMapFixture as PlateMapTemplate, {
459
- propsVariable: 'bindings',
460
- })
461
-
462
- expect(snippets.map(snippet => snippet.component)).toEqual(['PlateEditor', 'WellPlate'])
463
- expect(snippets.map(snippet => snippet.propsName)).toEqual([
464
- 'plateMapPlateEditorProps',
465
- 'plateMapWellPlateProps',
466
- ])
467
- expect(snippets[0].propsExpression).toBe('bindings[0].propsObject')
468
- expect(snippets[0].template).toBe('<PlateEditor v-bind="bindings[0].propsObject" />')
469
- expect(snippets[1].template).toBe('<WellPlate v-bind="bindings[1].propsObject" />')
470
- })
471
-
472
- it('generates a Vue usage bundle for concrete template component props', () => {
473
- const usage = toBioTemplateComponentUsage(plateMapFixture as PlateMapTemplate, {
474
- propsVariable: 'bindings',
475
- targetExpression: 'plateMap',
476
- })
477
-
478
- expect(usage.imports[0].statement).toBe(
479
- "import { PlateEditor, WellPlate } from '@morscherlab/mint-sdk'"
480
- )
481
- expect(usage.componentProps).toHaveLength(2)
482
- expect(usage.propsDeclarations).toEqual([
483
- 'const plateMapPlateEditorProps = bindings[0].propsObject',
484
- 'const plateMapWellPlateProps = bindings[1].propsObject',
485
- ])
486
- expect(usage.scriptSetup).toBe([
487
- 'const bindings = toBioTemplateComponentProps(plateMap)',
488
- 'const plateMapPlateEditorProps = bindings[0].propsObject',
489
- 'const plateMapWellPlateProps = bindings[1].propsObject',
490
- ].join('\n'))
491
- expect(usage.template).toBe([
492
- '<PlateEditor v-bind="plateMapPlateEditorProps" />',
493
- '<WellPlate v-bind="plateMapWellPlateProps" />',
494
- ].join('\n'))
495
- })
496
-
497
- it('generates a complete Vue SFC for concrete template component props', () => {
498
- const usage = toBioTemplateComponentUsage(plateMapFixture as PlateMapTemplate)
499
-
500
- expect(usage.scriptSetup).toContain(
501
- 'const props = defineProps<{ templateCollection: BioTemplateEnvelope<unknown> | TemplateCollectionEnvelope }>()'
502
- )
503
- expect(usage.sfc).toContain("import { PlateEditor, WellPlate } from '@morscherlab/mint-sdk'")
504
- expect(usage.sfc).toContain("import { toBioTemplateComponentProps } from '@morscherlab/mint-sdk/templates'")
505
- expect(usage.sfc).toContain('defineProps<{ templateCollection: BioTemplateEnvelope<unknown> | TemplateCollectionEnvelope }>()')
506
- expect(usage.sfc).toContain('<PlateEditor v-bind="plateMapPlateEditorProps" />')
507
- expect(usage.sfc).toContain('<WellPlate v-bind="plateMapWellPlateProps" />')
508
- expect(usage.sfc).toMatch(/^<script setup lang="ts">[\s\S]*<\/template>$/)
509
- })
510
-
511
- it('rejects mismatched template envelopes', () => {
512
- expect(() => assertTemplateEnvelope(plateMapFixture, 'sample-sheet')).toThrow(
513
- "Expected template_id 'sample-sheet'"
514
- )
515
- })
516
-
517
- it('returns validated typed template envelopes', () => {
518
- const template = ensureTemplateEnvelope<PlateMapTemplate>(plateMapFixture, 'plate-map')
519
-
520
- expect(template.data.plates[0].id).toBe('plate-1')
521
- expect(() => ensureTemplateEnvelope<SampleSheetTemplate>(plateMapFixture, 'sample-sheet')).toThrow(
522
- "Expected template_id 'sample-sheet'"
523
- )
524
- })
525
-
526
- it('builds and reads template collections', () => {
527
- const plate = createPlateMapTemplate({
528
- name: 'Drug screen plate',
529
- samples: ['DMSO', 'Drug A'],
530
- })
531
- const sampleSheet = createSampleSheetTemplate({
532
- samples: [
533
- { sampleId: 'S001', name: 'Control 1', group: 'Control' },
534
- ],
535
- })
536
- const collection = createTemplateCollection([plate, sampleSheet], { source: 'unit-test' })
537
- const extracted = extractTemplateCollection(collection)
538
- const typedPlate = ensureTemplateFromCollection<PlateMapTemplate>(collection, 'plate-map')
539
-
540
- expect(Object.keys(collection[TEMPLATE_COLLECTION_KEY])).toEqual(['plate-map', 'sample-sheet'])
541
- expect(collection.metadata?.source).toBe('unit-test')
542
- expect(extracted['sample-sheet'].template_id).toBe('sample-sheet')
543
- expect(typedPlate.data.plates[0].name).toBe('Drug screen plate')
544
- expect(extractTemplateCollection(plate)['plate-map'].template_id).toBe('plate-map')
545
- expect(() => ensureTemplateFromCollection<SampleSheetTemplate>(collection, 'sample-prep')).toThrow(
546
- "Template 'sample-prep' was not found"
547
- )
548
- expect(() => extractTemplateCollection({ templates: { 'sample-sheet': plate } })).toThrow(
549
- 'does not match envelope template_id'
550
- )
551
- expect(() => createTemplateCollection([plate, plate])).toThrow('Duplicate template_id')
552
- })
553
-
554
- it('creates ready-to-save template preset collections', () => {
555
- const wellplate = createWellPlateScreenCollection({
556
- samples: ['Control', 'Treatment'],
557
- compounds: { 'Drug A': [10, 1, 0.1] },
558
- unit: 'uM',
559
- })
560
- const qpcr = createQpcrExpressionCollection({
561
- samples: [{ sampleId: 'S001', name: 'Control', group: 'Control' }],
562
- targets: ['ACTB'],
563
- })
564
- const lcms = createLcmsBatchCollection({
565
- samples: ['S001', 'S002'],
566
- features: ['Glucose'],
567
- instrument: 'LC-MS',
568
- })
569
- const targeted = createTargetedMetabolomicsCollection({
570
- samples: ['S001', 'S002'],
571
- metabolites: ['Glucose', 'Lactate'],
572
- internalStandards: ['13C Glucose'],
573
- standardConcentrations: [0.1, 1, 10],
574
- instrument: 'Orbitrap',
575
- })
576
- const flow = createFlowCytometryAssayCollection({
577
- samples: ['Control', 'Treatment'],
578
- markers: ['CD3', 'CD4'],
579
- instrument: 'BD LSRFortessa',
580
- })
581
- const western = createWesternBlotAssayCollection({
582
- samples: ['Control', 'Treatment'],
583
- targets: ['pERK', 'ERK'],
584
- loadingControl: 'ACTB',
585
- })
586
-
587
- const wellplateTemplates = extractTemplateCollection(wellplate)
588
- const qpcrTemplates = extractTemplateCollection(qpcr)
589
- const lcmsTemplates = extractTemplateCollection(lcms)
590
- const targetedTemplates = extractTemplateCollection(targeted)
591
- const flowTemplates = extractTemplateCollection(flow)
592
- const westernTemplates = extractTemplateCollection(western)
593
- const wellplateComponentProps = toBioTemplateComponentProps(wellplate)
594
-
595
- expect(Object.keys(wellplateTemplates)).toEqual(['plate-map', 'sample-sheet', 'dose-response'])
596
- expect(wellplate.metadata?.preset).toBe('wellplate-screen')
597
- expect(toPlateMapEditorState(wellplateTemplates['plate-map'] as PlateMapTemplate).samples[1].id).toBe('treatment')
598
- expect(toDoseConditions(wellplateTemplates['dose-response'] as DoseResponseTemplate)[0].label).toBe('Drug A')
599
- expect(wellplateComponentProps.map(binding => binding.component)).toContain('PlateEditor')
600
- expect(wellplateComponentProps.map(binding => binding.component)).toContain('DoseCalculator')
601
- expect(Object.keys(qpcrTemplates)).toEqual(['sample-sheet', 'qpcr-plate'])
602
- expect(toQpcrRows(qpcrTemplates['qpcr-plate'] as QpcrPlateTemplate)[0].sampleId).toBe('S001')
603
- expect(Object.keys(lcmsTemplates)).toEqual(['sample-sheet', 'instrument-run', 'assay-matrix'])
604
- expect(toInstrumentRunRows(lcmsTemplates['instrument-run'] as InstrumentRunTemplate)[0].kind).toBe('blank')
605
- expect(toInstrumentRunRows(lcmsTemplates['instrument-run'] as InstrumentRunTemplate)[2].sampleId).toBe('s001')
606
- expect(toTemplateDataFrame(lcmsTemplates['assay-matrix']).columns.map(column => column.key)).toContain('glucose')
607
- expect(toAssayMatrixSampleOptions(lcmsTemplates['assay-matrix'] as AssayMatrixTemplate).map(option => option.label)).toEqual(['S001', 'S002'])
608
- expect(Object.keys(targetedTemplates)).toEqual([
609
- 'sample-sheet',
610
- 'sample-prep',
611
- 'reagent-list',
612
- 'instrument-run',
613
- 'calibration-curve',
614
- 'assay-matrix',
615
- ])
616
- expect(targeted.metadata?.preset).toBe('targeted-metabolomics')
617
- expect(toReagentDataFrame(targetedTemplates['reagent-list'] as ReagentListTemplate).data[0].kind).toBe('compound')
618
- expect(toTemplateDataFrame(targetedTemplates['calibration-curve']).data[0].role).toBe('blank')
619
- expect(toInstrumentRunRows(targetedTemplates['instrument-run'] as InstrumentRunTemplate).map(row => row.kind)).toEqual([
620
- 'blank',
621
- 'standard',
622
- 'standard',
623
- 'standard',
624
- 'qc',
625
- 'qc',
626
- 'sample',
627
- 'sample',
628
- ])
629
- expect(toTemplateDataFrame(targetedTemplates['assay-matrix']).columns.map(column => column.key)).toContain('lactate')
630
- expect(Object.keys(flowTemplates)).toEqual(['sample-sheet', 'flow-cytometry-panel', 'assay-matrix'])
631
- expect(flow.metadata?.preset).toBe('flow-cytometry-assay')
632
- expect(flowTemplates['flow-cytometry-panel'].data).toMatchObject({
633
- instrument: 'BD LSRFortessa',
634
- markers: [
635
- { id: 'cd3', marker: 'CD3' },
636
- { id: 'cd4', marker: 'CD4' },
637
- ],
638
- })
639
- expect(toTemplateDataFrame(flowTemplates['assay-matrix']).columns.map(column => column.key)).toContain('cd4')
640
- expect(Object.keys(westernTemplates)).toEqual(['sample-sheet', 'reagent-list', 'protocol-steps', 'assay-matrix'])
641
- expect(western.metadata?.preset).toBe('western-blot-assay')
642
- expect(toReagentDataFrame(westernTemplates['reagent-list'] as ReagentListTemplate).data[0].kind).toBe('antibody')
643
- expect(toProtocolDataFrame(westernTemplates['protocol-steps'] as ProtocolStepsTemplate).data[2].name).toBe('Transfer to membrane')
644
- expect(toTemplateDataFrame(westernTemplates['assay-matrix']).columns.map(column => column.key)).toContain('actb')
645
-
646
- const aliasCollection = createBioTemplatePresetCollection('wellplate', {
647
- samples: ['Control', 'Treatment'],
648
- compounds: { 'Drug A': [10, 1] },
649
- })
650
- expect(aliasCollection.metadata?.preset).toBe('wellplate-screen')
651
- expect(Object.keys(extractTemplateCollection(aliasCollection))).toEqual(['plate-map', 'sample-sheet', 'dose-response'])
652
- expect(createBioTemplatePresetCollection('facs').metadata?.preset).toBe('flow-cytometry-assay')
653
- expect(createBioTemplatePresetCollection('immunoblot').metadata?.preset).toBe('western-blot-assay')
654
- expect(createBioTemplatePresetCollection('targeted metabolomics').metadata?.preset).toBe('targeted-metabolomics')
655
- expect(() => createBioTemplatePresetCollection('unknown-preset')).toThrow("Unknown template preset 'unknown-preset'.")
656
- })
657
-
658
- it('maps preset control values into template collection previews', () => {
659
- const wellplateOptions = bioTemplatePresetControlValuesToOptions('wellplate-screen', {
660
- sampleNames: 'Vehicle, Drug A, Drug B',
661
- plateName: 'Custom screen',
662
- plateFormat: '384',
663
- unit: 'nM',
664
- replicates: '2',
665
- })
666
- const wellplate = createBioTemplatePresetCollectionFromControls('wellplate-screen', {
667
- sampleNames: 'Vehicle, Drug A, Drug B',
668
- plateName: 'Custom screen',
669
- plateFormat: '384',
670
- unit: 'nM',
671
- replicates: '2',
672
- })
673
- const wellplateTemplates = extractTemplateCollection(wellplate)
674
- const plate = wellplateTemplates['plate-map'] as PlateMapTemplate
675
- const dose = wellplateTemplates['dose-response'] as DoseResponseTemplate
676
-
677
- expect(wellplateOptions.samples).toEqual(['Vehicle', 'Drug A', 'Drug B'])
678
- expect(wellplateOptions.plateFormat).toBe(384)
679
- expect(wellplateOptions.replicates).toBe(2)
680
- expect(plate.data.plates[0].name).toBe('Custom screen')
681
- expect(plate.data.plates[0].format).toBe(384)
682
- expect(plate.data.samples.map(sample => sample.id)).toEqual(['vehicle', 'drug-a', 'drug-b'])
683
- expect(dose.data.unit).toBe('nM')
684
- expect(dose.data.replicates).toBe(2)
685
-
686
- const qpcrOptions = bioTemplatePresetControlValuesToOptions('qpcr-expression', {
687
- sampleNames: ['Control', 'Knockdown'],
688
- targets: 'ACTB, MYC',
689
- chemistry: 'taqman',
690
- plateFormat: 384,
691
- includeNoTemplateControls: false,
692
- replicates: 2,
693
- instrument: 'QuantStudio',
694
- })
695
- const qpcr = ensureTemplateFromCollection<QpcrPlateTemplate>(
696
- createBioTemplatePresetCollectionFromControls('qpcr-expression', {
697
- sampleNames: ['Control', 'Knockdown'],
698
- targets: 'ACTB, MYC',
699
- chemistry: 'taqman',
700
- plateFormat: 384,
701
- includeNoTemplateControls: false,
702
- replicates: 2,
703
- instrument: 'QuantStudio',
704
- }),
705
- 'qpcr-plate',
706
- )
707
-
708
- expect(qpcrOptions.targets).toEqual(['ACTB', 'MYC'])
709
- expect(qpcrOptions.includeNoTemplateControls).toBe(false)
710
- expect(qpcr.data.chemistry).toBe('taqman')
711
- expect(qpcr.data.format).toBe(384)
712
- expect(qpcr.data.instrument).toBe('QuantStudio')
713
- expect(qpcr.data.reactions).toHaveLength(8)
714
- expect(qpcr.data.reactions.some(reaction => reaction.controlKind === 'no-template')).toBe(false)
715
-
716
- const lcmsOptions = bioTemplatePresetControlValuesToOptions('lcms-batch', {
717
- sampleNames: 'S001, S002',
718
- featureNames: 'Glucose, Pyruvate',
719
- instrument: 'Orbitrap',
720
- method: 'Polar metabolites',
721
- includeQc: false,
722
- })
723
- const lcmsTemplates = extractTemplateCollection(
724
- createBioTemplatePresetCollectionFromControls('lcms-batch', {
725
- sampleNames: 'S001, S002',
726
- featureNames: 'Glucose, Pyruvate',
727
- instrument: 'Orbitrap',
728
- method: 'Polar metabolites',
729
- includeQc: false,
730
- }),
731
- )
732
- const run = lcmsTemplates['instrument-run'] as InstrumentRunTemplate
733
-
734
- expect(lcmsOptions.features).toEqual(['Glucose', 'Pyruvate'])
735
- expect(lcmsOptions.includeQc).toBe(false)
736
- expect(run.data.instrument).toBe('Orbitrap')
737
- expect(run.data.methods[0].name).toBe('Polar metabolites')
738
- expect(run.data.items.map(item => item.kind)).toEqual(['blank', 'sample', 'sample'])
739
- expect(toTemplateDataFrame(lcmsTemplates['assay-matrix']).columns.map(column => column.key)).toContain('pyruvate')
740
-
741
- const targetedOptions = bioTemplatePresetControlValuesToOptions('targeted-metabolomics', {
742
- sampleNames: 'QC Pool, Patient A',
743
- metaboliteNames: 'Glucose, Citrate',
744
- internalStandards: '13C Glucose',
745
- standardConcentrations: '0.5, 5, 50',
746
- concentrationUnit: 'nM',
747
- responseUnit: 'area ratio',
748
- instrument: 'Triple quadrupole',
749
- method: 'MRM panel',
750
- outputVolume: '25',
751
- includeQc: false,
752
- })
753
- const targetedTemplates = extractTemplateCollection(
754
- createBioTemplatePresetCollectionFromControls('targeted-metabolomics', {
755
- sampleNames: 'QC Pool, Patient A',
756
- metaboliteNames: 'Glucose, Citrate',
757
- internalStandards: '13C Glucose',
758
- standardConcentrations: '0.5, 5, 50',
759
- concentrationUnit: 'nM',
760
- responseUnit: 'area ratio',
761
- instrument: 'Triple quadrupole',
762
- method: 'MRM panel',
763
- outputVolume: '25',
764
- includeQc: false,
765
- }),
766
- )
767
- const targetedRun = targetedTemplates['instrument-run'] as InstrumentRunTemplate
768
-
769
- expect(targetedOptions.metabolites).toEqual(['Glucose', 'Citrate'])
770
- expect(targetedOptions.standardConcentrations).toEqual([0.5, 5, 50])
771
- expect(targetedOptions.outputVolume).toBe(25)
772
- expect(targetedRun.data.instrument).toBe('Triple quadrupole')
773
- expect(targetedRun.data.methods[0].name).toBe('MRM panel')
774
- expect(targetedRun.data.items.map(item => item.kind)).toEqual([
775
- 'blank',
776
- 'standard',
777
- 'standard',
778
- 'standard',
779
- 'sample',
780
- 'sample',
781
- ])
782
- expect(toTemplateDataFrame(targetedTemplates['assay-matrix']).columns.map(column => column.key)).toContain('citrate')
783
-
784
- const flowOptions = bioTemplatePresetControlValuesToOptions('flow-cytometry-assay', {
785
- sampleNames: 'Control, Treatment',
786
- markers: 'CD3, CD19',
787
- featureNames: 'T cells, B cells',
788
- instrument: 'Cytek Aurora',
789
- includeDefaultControls: false,
790
- })
791
- const flowTemplates = extractTemplateCollection(
792
- createBioTemplatePresetCollectionFromControls('flow-cytometry-assay', {
793
- sampleNames: 'Control, Treatment',
794
- markers: 'CD3, CD19',
795
- featureNames: 'T cells, B cells',
796
- instrument: 'Cytek Aurora',
797
- includeDefaultControls: false,
798
- }),
799
- )
800
- const flowPanel = flowTemplates['flow-cytometry-panel'] as FlowCytometryPanelTemplate
801
-
802
- expect(flowOptions.markers).toEqual(['CD3', 'CD19'])
803
- expect(flowOptions.features).toEqual(['T cells', 'B cells'])
804
- expect(flowPanel.data.instrument).toBe('Cytek Aurora')
805
- expect(flowPanel.data.controls).toEqual([])
806
- expect(toTemplateDataFrame(flowTemplates['assay-matrix']).columns.map(column => column.key)).toContain('b-cells')
807
-
808
- const westernOptions = bioTemplatePresetControlValuesToOptions('western-blot-assay', {
809
- sampleNames: 'Control, Treatment',
810
- targets: 'pERK, ERK',
811
- loadingControl: 'ACTB',
812
- })
813
- const westernTemplates = extractTemplateCollection(
814
- createBioTemplatePresetCollectionFromControls('western-blot-assay', {
815
- sampleNames: 'Control, Treatment',
816
- targets: 'pERK, ERK',
817
- loadingControl: 'ACTB',
818
- }),
819
- )
820
-
821
- expect(westernOptions.targets).toEqual(['pERK', 'ERK'])
822
- expect(westernOptions.loadingControl).toBe('ACTB')
823
- expect(toProtocolSteps(westernTemplates['protocol-steps'] as ProtocolStepsTemplate).map(step => step.name)).toContain('Run SDS-PAGE')
824
- expect(toTemplateDataFrame(westernTemplates['assay-matrix']).columns.map(column => column.key)).toContain('actb')
825
- })
826
-
827
- it('creates sample-sheet templates and adapts rows, columns, and options', () => {
828
- const template = createSampleSheetTemplate({
829
- samples: [
830
- {
831
- sampleId: 'S001',
832
- name: 'Control 1',
833
- group: 'Control',
834
- metadata: { cell_line: 'HCT116' },
835
- },
836
- {
837
- sampleId: 'S002',
838
- name: 'Control 2',
839
- group: 'Control',
840
- },
841
- ],
842
- columns: [
843
- { id: 'sampleId', label: 'Sample ID', type: 'string', required: true, groupable: false },
844
- { id: 'cell_line', label: 'Cell Line', type: 'string', required: false, groupable: true },
845
- ],
846
- })
847
-
848
- expect(toSampleRows(template)[0].cell_line).toBe('HCT116')
849
- expect(template.data.samples[1].metadata).toEqual({})
850
- expect(toSampleColumns(template)[0].key).toBe('sampleId')
851
- expect(toSampleColumns(template)[1].key).toBe('cell_line')
852
- const sampleFrame = toSampleDataFrame(template)
853
- expect(sampleFrame.rowKey).toBe('sampleId')
854
- expect(sampleFrame.data[0].cell_line).toBe('HCT116')
855
- expect(sampleFrame.columns.map(column => column.key)).toEqual(['sampleId', 'cell_line'])
856
- expect(toTemplateDataFrame(template).rowKey).toBe('sampleId')
857
- expect(toSampleOptions(template)[0].label).toBe('Control 1')
858
- })
859
-
860
- it('loads the shared sample-sheet fixture', () => {
861
- const rows = toSampleRows(sampleSheetFixture as SampleSheetTemplate)
862
- const columns = toSampleColumns(sampleSheetFixture as SampleSheetTemplate)
863
- const options = toSampleOptions(sampleSheetFixture as SampleSheetTemplate)
864
-
865
- expect(rows[1].group).toBe('Drug A')
866
- expect(columns[0].key).toBe('sampleId')
867
- expect(options[0].value).toBe('S001')
868
- })
869
-
870
- it('creates sample-prep templates and adapts prep steps', () => {
871
- const template = createSamplePrepTemplate({
872
- samples: ['S001', { name: 'Dilute S002', sourceSampleId: 'S002', type: 'dilution' }],
873
- prepType: 'extraction',
874
- outputVolume: 50,
875
- })
876
- const rows = toSamplePrepRows(template)
877
- const frame = toSamplePrepDataFrame(template)
878
-
879
- expect(template.template_id).toBe('sample-prep')
880
- expect(rows[0].sourceSampleId).toBe('s001')
881
- expect(rows[0].destinationSampleId).toBe('s001-prepared')
882
- expect(rows[0].outputVolume).toBe(50)
883
- expect(rows[1].id).toBe('dilute-s002')
884
- expect(frame.rowKey).toBe('id')
885
- expect(frame.columns.map(column => column.key)).toContain('status')
886
- expect(toTemplateDataFrame(template).data[1].type).toBe('dilution')
887
- })
888
-
889
- it('creates dose-response templates and adapts dose conditions', () => {
890
- const template = createDoseResponseTemplate({
891
- compounds: { 'Drug A': [0.1, 10, 1] },
892
- unit: 'uM',
893
- replicates: 2,
894
- })
895
- const conditions = toDoseConditions(template)
896
-
897
- expect(template.template_id).toBe('dose-response')
898
- expect(template.data.compounds[0].concentrations).toEqual([10, 1, 0.1])
899
- expect(conditions[0].unit).toBe('uM')
900
- expect(conditions[0].concentrations).toEqual([10, 1, 0.1])
901
- })
902
-
903
- it('defaults metadata for explicit template records', () => {
904
- const samplePrep = createSamplePrepTemplate({
905
- samples: [{ name: 'Extract S001', sourceSampleId: 'S001' }],
906
- })
907
- const doseResponse = createDoseResponseTemplate({
908
- compounds: [{ id: 'drug-a', name: 'Drug A', concentrations: [1, 0.1] }],
909
- unit: 'uM',
910
- controls: [{ id: 'vehicle', name: 'DMSO', role: 'vehicle' }],
911
- })
912
- const timeCourse = createTimeCourseTemplate({
913
- timepoints: [{ id: 't0-hour', label: '0 hour', value: 0, unit: 'hour' }],
914
- unit: 'hour',
915
- conditions: [{ id: 'control', name: 'Control' }],
916
- })
917
- const assayMatrix = createAssayMatrixTemplate({
918
- samples: [{ sampleId: 'S001', name: 'Control 1' }],
919
- features: [{ id: 'lactate', name: 'Lactate', type: 'metabolite' }],
920
- })
921
-
922
- expect(samplePrep.data.steps[0].metadata).toEqual({})
923
- expect(doseResponse.data.compounds[0].metadata).toEqual({})
924
- expect(doseResponse.data.controls[0].metadata).toEqual({})
925
- expect(timeCourse.data.timepoints[0].metadata).toEqual({})
926
- expect(timeCourse.data.conditions[0].metadata).toEqual({})
927
- expect(assayMatrix.data.samples[0].metadata).toEqual({})
928
- expect(assayMatrix.data.features[0].metadata).toEqual({})
929
- expect(toDoseConditions(doseResponse)[0].color).toBe('#3B82F6')
930
- expect(toTimeCourseRows(timeCourse)[0].sampleId).toBe('control-t0-hour-r1')
931
- expect(toAssayMatrixRows(assayMatrix)[0].sampleId).toBe('S001')
932
- })
933
-
934
- it('loads the shared dose-response fixture with layout', () => {
935
- const conditions = toDoseConditions(doseResponseFixture as DoseResponseTemplate)
936
- const layout = toDoseLayoutState(doseResponseFixture as DoseResponseTemplate)
937
- const componentProps = toBioTemplateComponentProps(doseResponseFixture as DoseResponseTemplate)
938
- const doseCalculator = componentProps.find(binding => binding.component === 'DoseCalculator')
939
- const wellPlate = componentProps.find(binding => binding.component === 'WellPlate')
940
-
941
- expect(conditions[0].label).toBe('Drug A')
942
- expect(layout?.plates[0].wells.A2.value).toBe(10)
943
- expect(doseCalculator?.propsObject.mode).toBe('serial')
944
- expect((doseCalculator?.propsObject.targetWells as string[])).toContain('A2')
945
- expect((wellPlate?.propsObject.wells as Record<string, { value?: number }>).A2.value).toBe(10)
946
- })
947
-
948
- it('rejects invalid dose-response data', () => {
949
- expect(() => createDoseResponseTemplate({
950
- compounds: { 'Drug A': [-1] },
951
- unit: 'uM',
952
- })).toThrow('negative concentration')
953
- })
954
-
955
- it('creates calibration-curve templates and adapts standard curves', () => {
956
- const template = createCalibrationCurveTemplate({
957
- concentrations: [0.1, { level: 'Standard 2', concentration: 1 }, 10],
958
- analyte: 'Glucose',
959
- unit: 'uM',
960
- })
961
- const rows = toCalibrationCurveRows(template)
962
- const frame = toCalibrationCurveDataFrame(template)
963
-
964
- expect(template.template_id).toBe('calibration-curve')
965
- expect(template.data.points.map(point => point.role)).toEqual([
966
- 'blank',
967
- 'standard',
968
- 'standard',
969
- 'standard',
970
- 'qc',
971
- 'qc',
972
- ])
973
- expect(rows[2].id).toBe('standard-2')
974
- expect(rows[2].analyte).toBe('Glucose')
975
- expect(frame.rowKey).toBe('id')
976
- expect(frame.columns.map(column => column.key)).toContain('status')
977
- expect(toTemplateDataFrame(template).data[0].role).toBe('blank')
978
- })
979
-
980
- it('creates time-course templates and adapts samples and steps', () => {
981
- const template = createTimeCourseTemplate({
982
- timepoints: [24, 0, 6],
983
- unit: 'hour',
984
- conditions: ['Control', 'Treatment'],
985
- replicates: 2,
986
- })
987
- const rows = toTimeCourseRows(template)
988
- const steps = toTimeCourseSteps(template)
989
-
990
- expect(template.template_id).toBe('time-course')
991
- expect(template.data.timepoints.map(timepoint => timepoint.id)).toEqual(['t0-hour', 't6-hour', 't24-hour'])
992
- expect(rows).toHaveLength(12)
993
- expect(toTimeCourseDataFrame(template).columns[0].key).toBe('sampleId')
994
- expect(toTemplateDataFrame(template).data).toHaveLength(12)
995
- expect(steps[0].type).toBe('measurement')
996
- })
997
-
998
- it('creates protocol-step templates and adapts timeline and dataframe props', () => {
999
- const template = createProtocolStepsTemplate({
1000
- steps: [
1001
- {
1002
- name: 'Measure readout',
1003
- type: 'measurement',
1004
- duration: 45,
1005
- order: 2,
1006
- },
1007
- 'Seed cells',
1008
- ],
1009
- })
1010
- const steps = toProtocolSteps(template)
1011
- const frame = toProtocolDataFrame(template)
1012
-
1013
- expect(template.template_id).toBe('protocol-steps')
1014
- expect(steps.map(step => step.name)).toEqual(['Seed cells', 'Measure readout'])
1015
- expect(steps[1].type).toBe('measurement')
1016
- expect(frame.rowKey).toBe('id')
1017
- expect(frame.columns.map(column => column.key)).toContain('duration')
1018
- expect(toTemplateDataFrame(template).data[0].id).toBe('seed-cells')
1019
- })
1020
-
1021
- it('creates assay-matrix templates and adapts pivoted rows and columns', () => {
1022
- const template = createAssayMatrixTemplate({
1023
- samples: ['S001', 'S002'],
1024
- features: ['Lactate', 'Glucose'],
1025
- values: {
1026
- s001: { lactate: 1.2, glucose: 5.4 },
1027
- s002: { lactate: 2.1, glucose: 4.8 },
1028
- },
1029
- })
1030
- const rows = toAssayMatrixRows(template)
1031
- const columns = toAssayMatrixColumns(template)
1032
-
1033
- expect(template.template_id).toBe('assay-matrix')
1034
- expect(rows[0].lactate).toBe(1.2)
1035
- expect(columns.map(column => column.key)).toContain('glucose')
1036
- const assayFrame = toAssayMatrixDataFrame(template)
1037
- expect(assayFrame.rowKey).toBe('sampleId')
1038
- expect(assayFrame.data[0].lactate).toBe(1.2)
1039
- expect(toAssayMatrixSampleOptions(template)).toEqual([
1040
- { value: 's001', label: 'S001', description: undefined },
1041
- { value: 's002', label: 'S002', description: undefined },
1042
- ])
1043
- expect(toTemplateDataFrame(template).columns.map(column => column.key)).toContain('glucose')
1044
- })
1045
-
1046
- it('creates reagent-list templates and adapts items and dataframe props', () => {
1047
- const template = createReagentListTemplate({
1048
- reagents: [
1049
- {
1050
- id: 'dmso',
1051
- name: 'DMSO',
1052
- kind: 'compound',
1053
- storageCondition: 'RT',
1054
- stockLevel: 80,
1055
- stockUnit: '%',
1056
- },
1057
- 'Anti-HA antibody',
1058
- ],
1059
- })
1060
- const items = toReagentListItems(template)
1061
- const frame = toReagentDataFrame(template)
1062
-
1063
- expect(template.template_id).toBe('reagent-list')
1064
- expect(items[0].name).toBe('DMSO')
1065
- expect(items[0].storageCondition).toBe('RT')
1066
- expect(template.data.reagents[1].id).toBe('anti-ha-antibody')
1067
- expect(frame.rowKey).toBe('id')
1068
- expect(frame.columns.map(column => column.key)).toContain('stockLevel')
1069
- expect(toTemplateDataFrame(template).data[0].kind).toBe('compound')
1070
- })
1071
-
1072
- it('creates flow-cytometry panel templates and adapts marker rows', () => {
1073
- const template = createFlowCytometryPanelTemplate({
1074
- markers: [
1075
- { id: 'cd3', marker: 'CD3', fluorophore: 'FITC', detector: 'B530/30' },
1076
- { id: 'cd4', marker: 'CD4', fluorophore: 'PE', detector: 'B585/42' },
1077
- ],
1078
- instrument: 'BD LSRFortessa',
1079
- })
1080
- const rows = toFlowPanelRows(template)
1081
- const frame = toFlowPanelDataFrame(template)
1082
-
1083
- expect(template.template_id).toBe('flow-cytometry-panel')
1084
- expect(template.data.controls.map(control => control.kind)).toContain('single-stain')
1085
- expect(rows[0].marker).toBe('CD3')
1086
- expect(rows[0].controls).toContain('CD3 single stain')
1087
- expect(frame.rowKey).toBe('id')
1088
- expect(frame.columns.map(column => column.key)).toContain('fluorophore')
1089
- expect(toTemplateDataFrame(template).data[1].detector).toBe('B585/42')
1090
- })
1091
-
1092
- it('creates instrument-run templates and adapts run queues', () => {
1093
- const template = createInstrumentRunTemplate({
1094
- items: ['S001', { name: 'S002', vial: 'A2' }],
1095
- instrument: 'LC-MS',
1096
- method: 'Default method',
1097
- })
1098
- const rows = toInstrumentRunRows(template)
1099
- const frame = toInstrumentRunDataFrame(template)
1100
- const steps = toInstrumentRunSteps(template)
1101
- const events = toInstrumentRunScheduleEvents(template)
1102
- const componentProps = toBioTemplateComponentProps(template)
1103
- const calendar = componentProps.find(binding => binding.component === 'ScheduleCalendar')
1104
- const timeline = componentProps.find(binding => binding.component === 'ExperimentTimeline')
1105
-
1106
- expect(template.template_id).toBe('instrument-run')
1107
- expect(template.data.items.map(item => item.kind)).toEqual(['blank', 'qc', 'sample', 'sample', 'qc'])
1108
- expect(rows[0].name).toBe('Blank start')
1109
- expect(rows[2].sampleId).toBe('s001')
1110
- expect(rows[3].vial).toBe('A2')
1111
- expect(frame.rowKey).toBe('id')
1112
- expect(frame.columns.map(column => column.key)).toContain('status')
1113
- expect(toTemplateDataFrame(template).data[3].sampleId).toBe('s002')
1114
- expect(steps[2]).toMatchObject({
1115
- id: 's001-run',
1116
- type: 'measurement',
1117
- name: 'S001',
1118
- status: 'pending',
1119
- order: 3,
1120
- })
1121
- expect(steps[2].parameters?.method).toBe('Default method')
1122
- expect(events[0]).toMatchObject({
1123
- id: 'blank-start',
1124
- title: 'Blank start',
1125
- start: '2024-01-01T08:00:00.000Z',
1126
- end: '2024-01-01T08:10:00.000Z',
1127
- status: 'pending',
1128
- })
1129
- expect(events[2].title).toBe('S001')
1130
- expect(calendar?.propsObject.modelValue).toBe(events[0].start)
1131
- expect(calendar?.propsObject.events).toEqual(events)
1132
- expect(timeline?.propsObject.modelValue).toEqual(steps)
1133
- })
1134
-
1135
- it('creates qPCR plate templates and adapts reactions to dataframe and wells', () => {
1136
- const template = createQpcrPlateTemplate({
1137
- samples: ['Control', 'Treatment'],
1138
- targets: ['ACTB', 'GAPDH'],
1139
- replicates: 2,
1140
- instrument: 'QuantStudio',
1141
- })
1142
- const rows = toQpcrRows(template)
1143
- const frame = toQpcrDataFrame(template)
1144
- const wells = toQpcrWellPlateWells(template)
1145
-
1146
- expect(template.template_id).toBe('qpcr-plate')
1147
- expect(template.data.reactions).toHaveLength(10)
1148
- expect(template.data.reactions.at(-1)?.controlKind).toBe('no-template')
1149
- expect(rows[0].sample).toBe('Control')
1150
- expect(rows[0].target).toBe('ACTB')
1151
- expect(frame.rowKey).toBe('id')
1152
- expect(frame.columns.map(column => column.key)).toContain('cq')
1153
- expect(wells.A1.sampleType).toBe('control')
1154
- expect(wells.A1.metadata?.targetId).toBe('actb')
1155
- expect(toTemplateDataFrame(template).data.at(-1)?.controlKind).toBe('no-template')
1156
- })
1157
-
1158
- it('loads the shared qPCR plate fixture', () => {
1159
- const template = ensureTemplateEnvelope<QpcrPlateTemplate>(qpcrPlateFixture, 'qpcr-plate')
1160
- const frame = toQpcrDataFrame(template)
1161
- const wells = toQpcrWellPlateWells(template)
1162
- const componentProps = toBioTemplateComponentProps(template)
1163
- const wellPlate = componentProps.find(binding => binding.component === 'WellPlate')
1164
- const table = componentProps.find(binding => binding.component === 'DataFrame')
1165
-
1166
- expect(template.data.chemistry).toBe('taqman')
1167
- expect(frame.data[2].flags).toBe('review')
1168
- expect(frame.data[3].sample).toBe('no-template')
1169
- expect(wells.A1.row).toBe(0)
1170
- expect(wells.A1.col).toBe(0)
1171
- expect(wells.A4.sampleType).toBe('no-template')
1172
- expect((wellPlate?.propsObject.wells as Record<string, { sampleType?: string }>).A4.sampleType).toBe('no-template')
1173
- expect((table?.propsObject.data as Record<string, unknown>[])[0].target).toBe('ACTB')
1174
- })
1175
-
1176
- it('rejects templates without a dataframe adapter', () => {
1177
- expect(() => toTemplateDataFrame(createPlateMapTemplate())).toThrow(
1178
- "Template 'plate-map' does not expose a DataFrame adapter."
1179
- )
1180
- expect(() => toTemplateDataFrame(createDoseResponseTemplate({
1181
- compounds: { 'Drug A': [1] },
1182
- unit: 'uM',
1183
- }))).toThrow("Template 'dose-response' does not expose a DataFrame adapter.")
1184
- })
1185
-
1186
- it('accepts assay-matrix display names for values', () => {
1187
- const template = createAssayMatrixTemplate({
1188
- samples: ['S001'],
1189
- features: ['Lactate'],
1190
- values: {
1191
- S001: { Lactate: 1.2 },
1192
- },
1193
- })
1194
-
1195
- expect(template.data.measurements[0].sampleId).toBe('s001')
1196
- expect(template.data.measurements[0].featureId).toBe('lactate')
1197
- })
1198
- })
1199
-
1200
- describe('plate-map PlateEditor binding (7a)', () => {
1201
- const editorProps = () =>
1202
- toBioTemplateComponentProps(plateMapFixture as PlateMapTemplate)
1203
- .find(binding => binding.component === 'PlateEditor')?.propsObject as Record<string, unknown>
1204
-
1205
- it('should pass the plates as racks with sequential slots', () => {
1206
- expect((editorProps().modelValue as Array<{ slot: string }>)[0].slot).toBe('R')
1207
- })
1208
-
1209
- it('should move the sample id of a well to its group', () => {
1210
- const racks = editorProps().modelValue as Array<{ wells: Record<string, { group?: string }> }>
1211
-
1212
- expect(racks[0].wells.A2.group).toBe('drug-a')
1213
- })
1214
-
1215
- it('should make a well with a sample id a sample', () => {
1216
- const racks = editorProps().modelValue as Array<{ wells: Record<string, { sampleType?: string }> }>
1217
-
1218
- expect(racks[0].wells.A2.sampleType).toBe('sample')
1219
- })
1220
-
1221
- it('should leave the stored plate-map wells unchanged', () => {
1222
- const template = structuredClone(plateMapFixture) as PlateMapTemplate
1223
- toBioTemplateComponentProps(template)
1224
-
1225
- expect(template).toEqual(plateMapFixture)
1226
- })
1227
-
1228
- it('should offer the template samples as groups', () => {
1229
- expect((editorProps().groups as Array<{ id: string }>).map(group => group.id)).toContain('drug-a')
1230
- })
1231
-
1232
- it('should pin the format to the plate format', () => {
1233
- expect(editorProps().formats).toEqual([96])
1234
- })
1235
- })