@morscherlab/mint-sdk 1.0.0-rc.2 → 1.0.0-rc.4

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 (178) hide show
  1. package/dist/components/AppSidebar.vue.d.ts +3 -3
  2. package/dist/components/ControlWorkspaceView.vue.d.ts +3 -3
  3. package/dist/components/DoseDesignWorkspaceView.vue.d.ts +1 -1
  4. package/dist/components/PluginWorkspaceView.vue.d.ts +3 -3
  5. package/dist/components/index.js +2 -2
  6. package/dist/{components-BhK-dW99.js → components-DafPc4rM.js} +3 -3
  7. package/dist/{components-BhK-dW99.js.map → components-DafPc4rM.js.map} +1 -1
  8. package/dist/composables/controlComponentBindings.d.ts +7 -0
  9. package/dist/composables/controlSchemaAdapters.d.ts +20 -0
  10. package/dist/composables/controlSchemaFormFields.d.ts +3 -0
  11. package/dist/composables/controlSchemaLayout.d.ts +7 -0
  12. package/dist/composables/controlSchemaNormalize.d.ts +15 -0
  13. package/dist/composables/controlSchemaUtils.d.ts +9 -0
  14. package/dist/composables/controlWorkspaceOptions.d.ts +2 -0
  15. package/dist/composables/index.js +3 -3
  16. package/dist/composables/useControlSchema.d.ts +4 -30
  17. package/dist/composables/useControlWorkspace.d.ts +5 -0
  18. package/dist/{composables-Bg7CFuNz.js → composables-BMkPQhVK.js} +2 -2
  19. package/dist/{composables-Bg7CFuNz.js.map → composables-BMkPQhVK.js.map} +1 -1
  20. package/dist/index.js +4 -4
  21. package/dist/install.js +2 -2
  22. package/dist/templates/adapters.d.ts +14 -47
  23. package/dist/templates/assayLookups.d.ts +3 -0
  24. package/dist/templates/assayMatrixAdapters.d.ts +6 -0
  25. package/dist/templates/assayMatrixBuilder.d.ts +2 -0
  26. package/dist/templates/assayNormalizers.d.ts +4 -0
  27. package/dist/templates/builderDefaults.d.ts +1 -0
  28. package/dist/templates/builderIdUtils.d.ts +4 -0
  29. package/dist/templates/builderPresetControls.d.ts +10 -0
  30. package/dist/templates/builderReadUtils.d.ts +8 -0
  31. package/dist/templates/builders.d.ts +26 -67
  32. package/dist/templates/calibrationCurveAdapters.d.ts +4 -0
  33. package/dist/templates/calibrationCurveBuilder.d.ts +2 -0
  34. package/dist/templates/calibrationNormalizers.d.ts +5 -0
  35. package/dist/templates/componentBindingCatalog.d.ts +25 -0
  36. package/dist/templates/componentBindingHelpers.d.ts +17 -0
  37. package/dist/templates/componentDoseResponseProps.d.ts +3 -0
  38. package/dist/templates/componentGenericProps.d.ts +8 -0
  39. package/dist/templates/componentPlateHelpers.d.ts +5 -0
  40. package/dist/templates/componentPlateMapProps.d.ts +3 -0
  41. package/dist/templates/componentPropsFactory.d.ts +3 -0
  42. package/dist/templates/componentQpcrPlateProps.d.ts +3 -0
  43. package/dist/templates/componentTargetResolvers.d.ts +5 -0
  44. package/dist/templates/componentTemplateProps.d.ts +3 -0
  45. package/dist/templates/controlSchemaClone.d.ts +4 -0
  46. package/dist/templates/controlSchemaConstants.d.ts +10 -0
  47. package/dist/templates/controlSchemaMerge.d.ts +3 -0
  48. package/dist/templates/controlSchemaTargets.d.ts +17 -0
  49. package/dist/templates/controlSchemaTypes.d.ts +4 -0
  50. package/dist/templates/controlSchemas.d.ts +4 -4
  51. package/dist/templates/defaultBioTemplateBuilder.d.ts +2 -0
  52. package/dist/templates/doseResponseAdapters.d.ts +4 -0
  53. package/dist/templates/doseResponseBuilder.d.ts +2 -0
  54. package/dist/templates/elisaAssayCollectionBuilder.d.ts +2 -0
  55. package/dist/templates/flowCytometryAssayCollectionBuilder.d.ts +2 -0
  56. package/dist/templates/flowCytometryPanelBuilder.d.ts +2 -0
  57. package/dist/templates/flowNormalizers.d.ts +8 -0
  58. package/dist/templates/flowPanelAdapters.d.ts +4 -0
  59. package/dist/templates/index.js +1 -1
  60. package/dist/templates/instrumentRunAdapterHelpers.d.ts +8 -0
  61. package/dist/templates/instrumentRunAdapters.d.ts +8 -0
  62. package/dist/templates/instrumentRunBuilder.d.ts +2 -0
  63. package/dist/templates/lcmsBatchCollectionBuilder.d.ts +2 -0
  64. package/dist/templates/plateGeometry.d.ts +4 -0
  65. package/dist/templates/plateMapAdapters.d.ts +3 -0
  66. package/dist/templates/plateMapBuilder.d.ts +2 -0
  67. package/dist/templates/presetControlSchemas.d.ts +534 -0
  68. package/dist/templates/protocolAdapters.d.ts +5 -0
  69. package/dist/templates/protocolNormalizers.d.ts +6 -0
  70. package/dist/templates/protocolStepsBuilder.d.ts +2 -0
  71. package/dist/templates/qpcrAdapters.d.ts +5 -0
  72. package/dist/templates/qpcrExpressionCollectionBuilder.d.ts +2 -0
  73. package/dist/templates/qpcrPlateBuilder.d.ts +2 -0
  74. package/dist/templates/reagentAdapters.d.ts +5 -0
  75. package/dist/templates/reagentListBuilder.d.ts +2 -0
  76. package/dist/templates/runNormalizers.d.ts +10 -0
  77. package/dist/templates/sampleNormalizers.d.ts +4 -0
  78. package/dist/templates/samplePrepAdapters.d.ts +4 -0
  79. package/dist/templates/samplePrepBuilder.d.ts +2 -0
  80. package/dist/templates/sampleSheetAdapters.d.ts +5 -0
  81. package/dist/templates/sampleSheetBuilder.d.ts +2 -0
  82. package/dist/templates/targetedMetabolomicsCollectionBuilder.d.ts +2 -0
  83. package/dist/templates/targetedMetabolomicsHelpers.d.ts +5 -0
  84. package/dist/templates/templateControlSchemas.d.ts +400 -0
  85. package/dist/templates/templateEnvelopes.d.ts +9 -0
  86. package/dist/templates/templatePackCollectionBuilder.d.ts +2 -0
  87. package/dist/templates/templatePresetCollectionBuilder.d.ts +18 -0
  88. package/dist/templates/templateValidators.d.ts +13 -0
  89. package/dist/templates/timeCourseAdapters.d.ts +5 -0
  90. package/dist/templates/timeCourseBuilder.d.ts +2 -0
  91. package/dist/templates/wellPlateScreenCollectionBuilder.d.ts +2 -0
  92. package/dist/templates/westernBlotAssayCollectionBuilder.d.ts +2 -0
  93. package/dist/{templates-BorLR_7p.js → templates-bUAWMn5L.js} +3574 -3428
  94. package/dist/templates-bUAWMn5L.js.map +1 -0
  95. package/dist/{useProtocolTemplates-n6AJqSqv.js → useProtocolTemplates-QZtHFFH2.js} +2 -2
  96. package/dist/{useProtocolTemplates-n6AJqSqv.js.map → useProtocolTemplates-QZtHFFH2.js.map} +1 -1
  97. package/package.json +1 -1
  98. package/src/composables/controlComponentBindings.ts +80 -0
  99. package/src/composables/controlSchemaAdapters.ts +196 -0
  100. package/src/composables/controlSchemaFormFields.ts +61 -0
  101. package/src/composables/controlSchemaLayout.ts +59 -0
  102. package/src/composables/controlSchemaNormalize.ts +101 -0
  103. package/src/composables/controlSchemaUtils.ts +36 -0
  104. package/src/composables/controlWorkspaceOptions.ts +21 -0
  105. package/src/composables/useControlSchema.ts +51 -628
  106. package/src/composables/useControlWorkspace.ts +207 -0
  107. package/src/templates/adapters.ts +89 -930
  108. package/src/templates/assayLookups.ts +33 -0
  109. package/src/templates/assayMatrixAdapters.ts +78 -0
  110. package/src/templates/assayMatrixBuilder.ts +59 -0
  111. package/src/templates/assayNormalizers.ts +34 -0
  112. package/src/templates/builderDefaults.ts +11 -0
  113. package/src/templates/builderIdUtils.ts +20 -0
  114. package/src/templates/builderPresetControls.ts +165 -0
  115. package/src/templates/builderReadUtils.ts +57 -0
  116. package/src/templates/builders.ts +122 -2350
  117. package/src/templates/calibrationCurveAdapters.ts +59 -0
  118. package/src/templates/calibrationCurveBuilder.ts +99 -0
  119. package/src/templates/calibrationNormalizers.ts +60 -0
  120. package/src/templates/componentBindingCatalog.ts +90 -0
  121. package/src/templates/componentBindingHelpers.ts +93 -0
  122. package/src/templates/componentBindings.ts +12 -461
  123. package/src/templates/componentDoseResponseProps.ts +42 -0
  124. package/src/templates/componentGenericProps.ts +77 -0
  125. package/src/templates/componentPlateHelpers.ts +29 -0
  126. package/src/templates/componentPlateMapProps.ts +32 -0
  127. package/src/templates/componentPropsFactory.ts +21 -0
  128. package/src/templates/componentQpcrPlateProps.ts +28 -0
  129. package/src/templates/componentTargetResolvers.ts +69 -0
  130. package/src/templates/componentTemplateProps.ts +78 -0
  131. package/src/templates/controlSchemaClone.ts +32 -0
  132. package/src/templates/controlSchemaConstants.ts +11 -0
  133. package/src/templates/controlSchemaMerge.ts +40 -0
  134. package/src/templates/controlSchemaTargets.ts +87 -0
  135. package/src/templates/controlSchemaTypes.ts +20 -0
  136. package/src/templates/controlSchemas.ts +22 -704
  137. package/src/templates/defaultBioTemplateBuilder.ts +124 -0
  138. package/src/templates/doseResponseAdapters.ts +45 -0
  139. package/src/templates/doseResponseBuilder.ts +44 -0
  140. package/src/templates/elisaAssayCollectionBuilder.ts +62 -0
  141. package/src/templates/flowCytometryAssayCollectionBuilder.ts +41 -0
  142. package/src/templates/flowCytometryPanelBuilder.ts +53 -0
  143. package/src/templates/flowNormalizers.ts +58 -0
  144. package/src/templates/flowPanelAdapters.ts +58 -0
  145. package/src/templates/instrumentRunAdapterHelpers.ts +94 -0
  146. package/src/templates/instrumentRunAdapters.ts +163 -0
  147. package/src/templates/instrumentRunBuilder.ts +97 -0
  148. package/src/templates/lcmsBatchCollectionBuilder.ts +38 -0
  149. package/src/templates/plateGeometry.ts +62 -0
  150. package/src/templates/plateMapAdapters.ts +36 -0
  151. package/src/templates/plateMapBuilder.ts +43 -0
  152. package/src/templates/presetControlSchemas.ts +258 -0
  153. package/src/templates/protocolAdapters.ts +69 -0
  154. package/src/templates/protocolNormalizers.ts +37 -0
  155. package/src/templates/protocolStepsBuilder.ts +36 -0
  156. package/src/templates/qpcrAdapters.ts +104 -0
  157. package/src/templates/qpcrExpressionCollectionBuilder.ts +33 -0
  158. package/src/templates/qpcrPlateBuilder.ts +96 -0
  159. package/src/templates/reagentAdapters.ts +77 -0
  160. package/src/templates/reagentListBuilder.ts +30 -0
  161. package/src/templates/runNormalizers.ts +63 -0
  162. package/src/templates/sampleNormalizers.ts +58 -0
  163. package/src/templates/samplePrepAdapters.ts +63 -0
  164. package/src/templates/samplePrepBuilder.ts +51 -0
  165. package/src/templates/sampleSheetAdapters.ts +75 -0
  166. package/src/templates/sampleSheetBuilder.ts +23 -0
  167. package/src/templates/targetedMetabolomicsCollectionBuilder.ts +79 -0
  168. package/src/templates/targetedMetabolomicsHelpers.ts +102 -0
  169. package/src/templates/templateControlSchemas.ts +320 -0
  170. package/src/templates/templateEnvelopes.ts +137 -0
  171. package/src/templates/templatePackCollectionBuilder.ts +23 -0
  172. package/src/templates/templatePresetCollectionBuilder.ts +139 -0
  173. package/src/templates/templateValidators.ts +414 -0
  174. package/src/templates/timeCourseAdapters.ts +73 -0
  175. package/src/templates/timeCourseBuilder.ts +64 -0
  176. package/src/templates/wellPlateScreenCollectionBuilder.ts +36 -0
  177. package/src/templates/westernBlotAssayCollectionBuilder.ts +68 -0
  178. package/dist/templates-BorLR_7p.js.map +0 -1
@@ -1,845 +1,107 @@
1
+ import type { Well } from '../types'
1
2
  import type {
2
- DataFrameColumn,
3
- PlateCondition,
4
- PlateMapEditorState,
5
- ProtocolStep,
6
- ProtocolStepStatus,
7
- ProtocolStepType,
8
- ScheduleEvent,
9
- ScheduleEventStatus,
10
- SelectOption,
11
- Well,
12
- } from '../types'
13
- import {
14
- getTemplateData,
15
- validateAssayMatrixData,
16
- validateCalibrationCurveData,
17
- validateDoseResponseData,
18
- validateFlowCytometryPanelData,
19
- validateInstrumentRunData,
20
- validatePlateMapData,
21
- validateProtocolStepsData,
22
- validateQpcrPlateData,
23
- validateReagentListData,
24
- validateSamplePrepData,
25
- validateSampleSheetData,
26
- validateTimeCourseData,
27
- } from './builders'
28
- import type {
29
- AssayMatrixColumnsAdapterResult,
30
- AssayMatrixDataFrameAdapterResult,
31
- AssayMatrixRowsAdapterResult,
32
- AssayMatrixSampleOptionsAdapterResult,
33
3
  AssayMatrixTemplate,
34
- AssayMatrixTemplateData,
35
4
  BioTemplateEnvelope,
36
- CalibrationCurveColumnsAdapterResult,
37
- CalibrationCurveDataFrameAdapterResult,
38
- CalibrationCurveRowsAdapterResult,
39
5
  CalibrationCurveTemplate,
40
- CalibrationCurveTemplateData,
41
6
  DataFrameTemplate,
42
- DoseConditionsAdapterResult,
43
- DoseResponseTemplate,
44
- DoseResponseTemplateData,
45
7
  FlowCytometryPanelTemplate,
46
- FlowCytometryPanelTemplateData,
47
- FlowPanelColumnsAdapterResult,
48
- FlowPanelDataFrameAdapterResult,
49
- FlowPanelRowsAdapterResult,
50
- InstrumentRunColumnsAdapterResult,
51
- InstrumentRunDataFrameAdapterResult,
52
- InstrumentRunRowsAdapterResult,
53
- InstrumentRunScheduleEventsAdapterResult,
54
- InstrumentRunStepsAdapterResult,
55
8
  InstrumentRunTemplate,
56
- InstrumentRunTemplateData,
57
- InstrumentRunItem,
58
- InstrumentRunItemKind,
59
- InstrumentRunStatus,
60
- PlateMapEditorAdapterResult,
61
- PlateMapTemplate,
62
- PlateMapTemplateData,
63
- ProtocolColumnsAdapterResult,
64
- ProtocolDataFrameAdapterResult,
65
- ProtocolRowsAdapterResult,
66
- ProtocolStepsAdapterResult,
67
9
  ProtocolStepsTemplate,
68
- ProtocolStepsTemplateData,
69
- QpcrColumnsAdapterResult,
70
- QpcrDataFrameAdapterResult,
71
10
  QpcrPlateTemplate,
72
- QpcrPlateTemplateData,
73
- QpcrRowsAdapterResult,
74
- QpcrWellMapAdapterResult,
75
- ReagentColumnsAdapterResult,
76
- ReagentDataFrameAdapterResult,
77
- ReagentListItemsAdapterResult,
78
11
  ReagentListTemplate,
79
- ReagentListTemplateData,
80
- ReagentRowsAdapterResult,
81
- SampleColumnsAdapterResult,
82
- SampleDataFrameAdapterResult,
83
- SampleOptionsAdapterResult,
84
- SamplePrepColumnsAdapterResult,
85
- SamplePrepDataFrameAdapterResult,
86
- SamplePrepRowsAdapterResult,
87
12
  SamplePrepTemplate,
88
- SamplePrepTemplateData,
89
- SampleRowsAdapterResult,
90
13
  SampleSheetTemplate,
91
- SampleSheetTemplateData,
92
- TimeCourseColumnsAdapterResult,
93
- TimeCourseDataFrameAdapterResult,
94
- TimeCourseRowsAdapterResult,
95
- TimeCourseStepsAdapterResult,
96
14
  TimeCourseTemplate,
97
- TimeCourseTemplateData,
98
15
  TemplateDataFrameAdapterResult,
99
- WellMapAdapterResult,
100
16
  } from './types'
101
-
102
- const CONDITION_COLORS = [
103
- '#3B82F6',
104
- '#10B981',
105
- '#EF4444',
106
- '#F59E0B',
107
- '#8B5CF6',
108
- '#F97316',
109
- '#06B6D4',
110
- '#14B8A6',
111
- '#6B7280',
112
- ]
113
-
114
- export function toPlateMapEditorState(
115
- template: PlateMapTemplate | PlateMapTemplateData
116
- ): PlateMapEditorAdapterResult {
117
- const data = getTemplateData(template, 'plate-map')
118
- validatePlateMapData(data)
119
- const activePlateId = data.activePlateId ?? data.plates[0].id
120
- return {
121
- plates: data.plates,
122
- activePlateId,
123
- samples: data.samples,
124
- selectedWells: data.selectedWells ?? [],
125
- activeSampleId: data.activeSampleId,
126
- } satisfies PlateMapEditorState
127
- }
128
-
129
- export function toWellPlateWells(
130
- template: PlateMapTemplate | PlateMapTemplateData,
131
- plateId?: string
132
- ): WellMapAdapterResult {
133
- const state = toPlateMapEditorState(template)
134
- const plate = state.plates.find(candidate => candidate.id === (plateId ?? state.activePlateId))
135
- ?? state.plates[0]
136
- return plate.wells
137
- }
138
-
139
- export function toSampleRows(
140
- template: SampleSheetTemplate | SampleSheetTemplateData
141
- ): SampleRowsAdapterResult {
142
- const data = getTemplateData(template, 'sample-sheet')
143
- validateSampleSheetData(data)
144
- return data.samples.map(sample => ({
145
- sampleId: sample.sampleId,
146
- name: sample.name,
147
- group: sample.group,
148
- batch: sample.batch,
149
- replicate: sample.replicate,
150
- plateId: sample.plateId,
151
- wellId: sample.wellId,
152
- ...(sample.metadata ?? {}),
153
- }))
154
- }
155
-
156
- export function toSampleColumns(
157
- template: SampleSheetTemplate | SampleSheetTemplateData
158
- ): SampleColumnsAdapterResult {
159
- const data = getTemplateData(template, 'sample-sheet')
160
- validateSampleSheetData(data)
161
- return data.columns.map((column): DataFrameColumn<Record<string, unknown>> => ({
162
- key: sampleColumnKey(column.id),
163
- label: column.label,
164
- sortable: true,
165
- align: column.type === 'number' || column.type === 'integer' ? 'right' : 'left',
166
- }))
167
- }
168
-
169
- export function toSampleDataFrame(
170
- template: SampleSheetTemplate | SampleSheetTemplateData
171
- ): SampleDataFrameAdapterResult {
172
- return {
173
- data: toSampleRows(template),
174
- columns: toSampleColumns(template),
175
- rowKey: 'sampleId',
176
- }
177
- }
178
-
179
- export function toSampleOptions(
180
- template: SampleSheetTemplate | SampleSheetTemplateData
181
- ): SampleOptionsAdapterResult {
182
- const data = getTemplateData(template, 'sample-sheet')
183
- validateSampleSheetData(data)
184
- return data.samples.map((sample): SelectOption<string> => ({
185
- value: sample.sampleId,
186
- label: sample.name ?? sample.sampleId,
187
- description: [sample.group, sample.batch].filter(Boolean).join(' / ') || undefined,
188
- }))
189
- }
190
-
191
- export function toSamplePrepRows(
192
- template: SamplePrepTemplate | SamplePrepTemplateData
193
- ): SamplePrepRowsAdapterResult {
194
- const data = getTemplateData(template, 'sample-prep')
195
- validateSamplePrepData(data)
196
- return [...data.steps]
197
- .sort((a, b) => a.order - b.order)
198
- .map(step => ({
199
- id: step.id,
200
- order: step.order,
201
- type: step.type,
202
- name: step.name,
203
- sourceSampleId: step.sourceSampleId,
204
- sourceWellId: step.sourceWellId,
205
- destinationSampleId: step.destinationSampleId,
206
- destinationWellId: step.destinationWellId,
207
- reagentId: step.reagentId,
208
- inputVolume: step.inputVolume,
209
- outputVolume: step.outputVolume,
210
- volumeUnit: step.volumeUnit,
211
- durationMin: step.durationMin,
212
- status: step.status,
213
- protocolName: data.protocolName,
214
- ...(step.metadata ?? {}),
215
- }))
216
- }
217
-
218
- export function toSamplePrepColumns(): SamplePrepColumnsAdapterResult {
219
- return [
220
- { key: 'order', label: 'Order', sortable: true, align: 'right' },
221
- { key: 'type', label: 'Type', sortable: true },
222
- { key: 'name', label: 'Step', sortable: true },
223
- { key: 'sourceSampleId', label: 'Source', sortable: true },
224
- { key: 'sourceWellId', label: 'Source well', sortable: true },
225
- { key: 'destinationSampleId', label: 'Destination', sortable: true },
226
- { key: 'destinationWellId', label: 'Destination well', sortable: true },
227
- { key: 'reagentId', label: 'Reagent', sortable: true },
228
- { key: 'inputVolume', label: 'Input', sortable: true, align: 'right' },
229
- { key: 'outputVolume', label: 'Output', sortable: true, align: 'right' },
230
- { key: 'volumeUnit', label: 'Unit', sortable: true },
231
- { key: 'status', label: 'Status', sortable: true },
232
- ]
233
- }
234
-
235
- export function toSamplePrepDataFrame(
236
- template: SamplePrepTemplate | SamplePrepTemplateData
237
- ): SamplePrepDataFrameAdapterResult {
238
- return {
239
- data: toSamplePrepRows(template),
240
- columns: toSamplePrepColumns(),
241
- rowKey: 'id',
242
- }
243
- }
244
-
245
- export function toDoseConditions(
246
- template: DoseResponseTemplate | DoseResponseTemplateData
247
- ): DoseConditionsAdapterResult {
248
- const data = getTemplateData(template, 'dose-response')
249
- validateDoseResponseData(data)
250
- return data.compounds.map((compound, index): PlateCondition => ({
251
- label: compound.name,
252
- color: String(compound.metadata?.color ?? CONDITION_COLORS[index % CONDITION_COLORS.length]),
253
- concentrations: compound.concentrations,
254
- unit: data.unit,
255
- }))
256
- }
257
-
258
- export function toDoseLayoutState(
259
- template: DoseResponseTemplate | DoseResponseTemplateData
260
- ): PlateMapEditorState | undefined {
261
- const data = getTemplateData(template, 'dose-response')
262
- validateDoseResponseData(data)
263
- return data.layout ? toPlateMapEditorState(data.layout) : undefined
264
- }
265
-
266
- export function toCalibrationCurveRows(
267
- template: CalibrationCurveTemplate | CalibrationCurveTemplateData
268
- ): CalibrationCurveRowsAdapterResult {
269
- const data = getTemplateData(template, 'calibration-curve')
270
- validateCalibrationCurveData(data)
271
- return [...data.points]
272
- .sort((a, b) => a.order - b.order)
273
- .map(point => ({
274
- id: point.id,
275
- order: point.order,
276
- role: point.role,
277
- level: point.level,
278
- concentration: point.concentration,
279
- unit: point.unit,
280
- expectedResponse: point.expectedResponse,
281
- response: point.response,
282
- replicate: point.replicate,
283
- include: point.include,
284
- status: point.status,
285
- analyte: data.analyte,
286
- model: data.model,
287
- ...(point.metadata ?? {}),
288
- }))
289
- }
290
-
291
- export function toCalibrationCurveColumns(): CalibrationCurveColumnsAdapterResult {
292
- return [
293
- { key: 'order', label: 'Order', sortable: true, align: 'right' },
294
- { key: 'role', label: 'Role', sortable: true },
295
- { key: 'level', label: 'Level', sortable: true },
296
- { key: 'concentration', label: 'Concentration', sortable: true, align: 'right' },
297
- { key: 'unit', label: 'Unit', sortable: true },
298
- { key: 'expectedResponse', label: 'Expected', sortable: true, align: 'right' },
299
- { key: 'response', label: 'Response', sortable: true, align: 'right' },
300
- { key: 'replicate', label: 'Replicate', sortable: true, align: 'right' },
301
- { key: 'include', label: 'Include', sortable: true },
302
- { key: 'status', label: 'Status', sortable: true },
303
- ]
304
- }
305
-
306
- export function toCalibrationCurveDataFrame(
307
- template: CalibrationCurveTemplate | CalibrationCurveTemplateData
308
- ): CalibrationCurveDataFrameAdapterResult {
309
- return {
310
- data: toCalibrationCurveRows(template),
311
- columns: toCalibrationCurveColumns(),
312
- rowKey: 'id',
313
- }
314
- }
315
-
316
- export function toTimeCourseRows(
317
- template: TimeCourseTemplate | TimeCourseTemplateData
318
- ): TimeCourseRowsAdapterResult {
319
- const data = getTemplateData(template, 'time-course')
320
- validateTimeCourseData(data)
321
- const timepoints = new Map(data.timepoints.map(timepoint => [timepoint.id, timepoint]))
322
- const conditions = new Map(data.conditions.map(condition => [condition.id, condition]))
323
-
324
- return data.samples.map(sample => {
325
- const timepoint = timepoints.get(sample.timepointId)
326
- const condition = conditions.get(sample.conditionId)
327
- return {
328
- sampleId: sample.sampleId,
329
- condition: condition?.name ?? sample.conditionId,
330
- timepoint: timepoint?.label ?? sample.timepointId,
331
- value: timepoint?.value,
332
- unit: timepoint?.unit,
333
- replicate: sample.replicate,
334
- ...(sample.metadata ?? {}),
335
- }
336
- })
337
- }
338
-
339
- export function toTimeCourseColumns(): TimeCourseColumnsAdapterResult {
340
- return [
341
- { key: 'sampleId', label: 'Sample ID', sortable: true },
342
- { key: 'condition', label: 'Condition', sortable: true },
343
- { key: 'timepoint', label: 'Time Point', sortable: true },
344
- { key: 'value', label: 'Value', sortable: true, align: 'right' },
345
- { key: 'unit', label: 'Unit', sortable: true },
346
- { key: 'replicate', label: 'Replicate', sortable: true, align: 'right' },
347
- ]
348
- }
349
-
350
- export function toTimeCourseDataFrame(
351
- template: TimeCourseTemplate | TimeCourseTemplateData
352
- ): TimeCourseDataFrameAdapterResult {
353
- return {
354
- data: toTimeCourseRows(template),
355
- columns: toTimeCourseColumns(),
356
- rowKey: 'sampleId',
357
- }
358
- }
359
-
360
- export function toTimeCourseSteps(
361
- template: TimeCourseTemplate | TimeCourseTemplateData
362
- ): TimeCourseStepsAdapterResult {
363
- const data = getTemplateData(template, 'time-course')
364
- validateTimeCourseData(data)
365
- return data.timepoints.map((timepoint, index) => ({
366
- id: timepoint.id,
367
- type: 'measurement',
368
- name: timepoint.label,
369
- description: `${data.conditions.length} condition${data.conditions.length === 1 ? '' : 's'}`,
370
- status: 'pending',
371
- order: index,
372
- parameters: {
373
- value: timepoint.value,
374
- unit: timepoint.unit,
375
- },
376
- }))
377
- }
378
-
379
- export function toProtocolSteps(
380
- template: ProtocolStepsTemplate | ProtocolStepsTemplateData
381
- ): ProtocolStepsAdapterResult {
382
- const data = getTemplateData(template, 'protocol-steps')
383
- validateProtocolStepsData(data)
384
- return [...data.steps]
385
- .sort((a, b) => a.order - b.order)
386
- .map(step => ({
387
- id: step.id,
388
- type: step.type,
389
- name: step.name,
390
- description: step.description,
391
- duration: step.duration,
392
- status: step.status,
393
- parameters: step.parameters,
394
- order: step.order,
395
- }))
396
- }
397
-
398
- export function toProtocolRows(
399
- template: ProtocolStepsTemplate | ProtocolStepsTemplateData
400
- ): ProtocolRowsAdapterResult {
401
- const data = getTemplateData(template, 'protocol-steps')
402
- validateProtocolStepsData(data)
403
- return [...data.steps]
404
- .sort((a, b) => a.order - b.order)
405
- .map(step => ({
406
- id: step.id,
407
- order: step.order,
408
- type: step.type,
409
- name: step.name,
410
- description: step.description,
411
- duration: step.duration,
412
- status: step.status,
413
- ...(step.metadata ?? {}),
414
- }))
415
- }
416
-
417
- export function toProtocolColumns(): ProtocolColumnsAdapterResult {
418
- return [
419
- { key: 'order', label: 'Order', sortable: true, align: 'right' },
420
- { key: 'name', label: 'Name', sortable: true },
421
- { key: 'type', label: 'Type', sortable: true },
422
- { key: 'duration', label: 'Duration', sortable: true, align: 'right' },
423
- { key: 'status', label: 'Status', sortable: true },
424
- { key: 'description', label: 'Description', sortable: true },
425
- ]
426
- }
427
-
428
- export function toProtocolDataFrame(
429
- template: ProtocolStepsTemplate | ProtocolStepsTemplateData
430
- ): ProtocolDataFrameAdapterResult {
431
- return {
432
- data: toProtocolRows(template),
433
- columns: toProtocolColumns(),
434
- rowKey: 'id',
435
- }
436
- }
437
-
438
- export function toAssayMatrixRows(
439
- template: AssayMatrixTemplate | AssayMatrixTemplateData
440
- ): AssayMatrixRowsAdapterResult {
441
- const data = getTemplateData(template, 'assay-matrix')
442
- validateAssayMatrixData(data)
443
- const measurements = new Map(
444
- data.measurements.map(measurement => [
445
- `${measurement.sampleId}:${measurement.featureId}`,
446
- measurement.value ?? null,
447
- ])
448
- )
449
-
450
- return data.samples.map(sample => {
451
- const row: Record<string, unknown> = {
452
- sampleId: sample.sampleId,
453
- name: sample.name,
454
- group: sample.group,
455
- ...(sample.metadata ?? {}),
456
- }
457
- for (const feature of data.features) {
458
- row[feature.id] = measurements.get(`${sample.sampleId}:${feature.id}`) ?? null
459
- }
460
- return row
461
- })
462
- }
463
-
464
- export function toAssayMatrixColumns(
465
- template: AssayMatrixTemplate | AssayMatrixTemplateData
466
- ): AssayMatrixColumnsAdapterResult {
467
- const data = getTemplateData(template, 'assay-matrix')
468
- validateAssayMatrixData(data)
469
- return [
470
- { key: 'sampleId', label: 'Sample ID', sortable: true },
471
- { key: 'name', label: 'Name', sortable: true },
472
- { key: 'group', label: 'Group', sortable: true },
473
- ...data.features.map(feature => ({
474
- key: feature.id,
475
- label: feature.unit ? `${feature.name} (${feature.unit})` : feature.name,
476
- sortable: true,
477
- align: 'right' as const,
478
- })),
479
- ]
480
- }
481
-
482
- export function toAssayMatrixDataFrame(
483
- template: AssayMatrixTemplate | AssayMatrixTemplateData
484
- ): AssayMatrixDataFrameAdapterResult {
485
- return {
486
- data: toAssayMatrixRows(template),
487
- columns: toAssayMatrixColumns(template),
488
- rowKey: 'sampleId',
489
- }
490
- }
491
-
492
- /** Convert an assay-matrix template into SampleSelector options derived from assay samples. */
493
- export function toAssayMatrixSampleOptions(
494
- template: AssayMatrixTemplate | AssayMatrixTemplateData
495
- ): AssayMatrixSampleOptionsAdapterResult {
496
- const data = getTemplateData(template, 'assay-matrix')
497
- validateAssayMatrixData(data)
498
- return data.samples.map((sample): SelectOption<string> => ({
499
- value: sample.sampleId,
500
- label: sample.name ?? sample.sampleId,
501
- description: sample.group,
502
- }))
503
- }
504
-
505
- export function toReagentListItems(
506
- template: ReagentListTemplate | ReagentListTemplateData
507
- ): ReagentListItemsAdapterResult {
508
- const data = getTemplateData(template, 'reagent-list')
509
- validateReagentListData(data)
510
- return data.reagents.map(reagent => ({
511
- id: reagent.id,
512
- name: reagent.name,
513
- catalogNumber: reagent.catalogNumber,
514
- lotNumber: reagent.lotNumber,
515
- expiryDate: reagent.expiryDate,
516
- storageCondition: reagent.storageCondition,
517
- location: reagent.location,
518
- stockLevel: reagent.stockLevel,
519
- stockUnit: reagent.stockUnit,
520
- supplier: reagent.supplier,
521
- url: reagent.url,
522
- }))
523
- }
524
-
525
- export function toReagentRows(
526
- template: ReagentListTemplate | ReagentListTemplateData
527
- ): ReagentRowsAdapterResult {
528
- const data = getTemplateData(template, 'reagent-list')
529
- validateReagentListData(data)
530
- return data.reagents.map(reagent => ({
531
- id: reagent.id,
532
- name: reagent.name,
533
- kind: reagent.kind,
534
- catalogNumber: reagent.catalogNumber,
535
- lotNumber: reagent.lotNumber,
536
- expiryDate: reagent.expiryDate,
537
- storageCondition: reagent.storageCondition,
538
- location: reagent.location,
539
- stockLevel: reagent.stockLevel,
540
- stockUnit: reagent.stockUnit,
541
- supplier: reagent.supplier,
542
- concentration: reagent.concentration,
543
- ...(reagent.metadata ?? {}),
544
- }))
545
- }
546
-
547
- export function toReagentColumns(): ReagentColumnsAdapterResult {
548
- return [
549
- { key: 'name', label: 'Name', sortable: true },
550
- { key: 'kind', label: 'Kind', sortable: true },
551
- { key: 'catalogNumber', label: 'Catalog', sortable: true },
552
- { key: 'lotNumber', label: 'Lot', sortable: true },
553
- { key: 'expiryDate', label: 'Expiry', sortable: true },
554
- { key: 'storageCondition', label: 'Storage', sortable: true },
555
- { key: 'location', label: 'Location', sortable: true },
556
- { key: 'stockLevel', label: 'Stock', sortable: true, align: 'right' },
557
- { key: 'stockUnit', label: 'Unit', sortable: true },
558
- { key: 'supplier', label: 'Supplier', sortable: true },
559
- ]
560
- }
561
-
562
- export function toReagentDataFrame(
563
- template: ReagentListTemplate | ReagentListTemplateData
564
- ): ReagentDataFrameAdapterResult {
565
- return {
566
- data: toReagentRows(template),
567
- columns: toReagentColumns(),
568
- rowKey: 'id',
569
- }
570
- }
571
-
572
- export function toFlowPanelRows(
573
- template: FlowCytometryPanelTemplate | FlowCytometryPanelTemplateData
574
- ): FlowPanelRowsAdapterResult {
575
- const data = getTemplateData(template, 'flow-cytometry-panel')
576
- validateFlowCytometryPanelData(data)
577
- return data.markers.map(marker => {
578
- const markerControls = data.controls
579
- .filter(control => control.markerId === marker.id)
580
- .map(control => control.name)
581
- .join(', ')
582
- return {
583
- id: marker.id,
584
- marker: marker.marker,
585
- fluorophore: marker.fluorophore,
586
- detector: marker.detector,
587
- clone: marker.clone,
588
- reagentId: marker.reagentId,
589
- purpose: marker.purpose,
590
- compensationRequired: marker.compensationRequired,
591
- controls: markerControls,
592
- instrument: data.instrument,
593
- ...(marker.metadata ?? {}),
594
- }
595
- })
596
- }
597
-
598
- export function toFlowPanelColumns(): FlowPanelColumnsAdapterResult {
599
- return [
600
- { key: 'marker', label: 'Marker', sortable: true },
601
- { key: 'fluorophore', label: 'Fluorophore', sortable: true },
602
- { key: 'detector', label: 'Detector', sortable: true },
603
- { key: 'clone', label: 'Clone', sortable: true },
604
- { key: 'purpose', label: 'Purpose', sortable: true },
605
- { key: 'compensationRequired', label: 'Compensation', sortable: true },
606
- { key: 'controls', label: 'Controls' },
607
- { key: 'instrument', label: 'Instrument', sortable: true },
608
- ]
609
- }
610
-
611
- export function toFlowPanelDataFrame(
612
- template: FlowCytometryPanelTemplate | FlowCytometryPanelTemplateData
613
- ): FlowPanelDataFrameAdapterResult {
614
- return {
615
- data: toFlowPanelRows(template),
616
- columns: toFlowPanelColumns(),
617
- rowKey: 'id',
618
- }
619
- }
620
-
621
- export function toInstrumentRunRows(
622
- template: InstrumentRunTemplate | InstrumentRunTemplateData
623
- ): InstrumentRunRowsAdapterResult {
624
- const data = getTemplateData(template, 'instrument-run')
625
- validateInstrumentRunData(data)
626
- const methods = new Map(data.methods.map(method => [method.id, method]))
627
- return [...data.items]
628
- .sort((a, b) => a.order - b.order)
629
- .map(item => {
630
- const method = methods.get(item.methodId)
631
- return {
632
- id: item.id,
633
- order: item.order,
634
- kind: item.kind,
635
- sampleId: item.sampleId,
636
- name: item.name ?? item.sampleId ?? item.kind,
637
- method: method?.name ?? item.methodId,
638
- vial: item.vial,
639
- plateId: item.plateId,
640
- wellId: item.wellId,
641
- injectionVolume: item.injectionVolume,
642
- expectedDurationMin: item.expectedDurationMin,
643
- status: item.status,
644
- instrument: data.instrument ?? method?.instrument,
645
- ...(item.metadata ?? {}),
646
- }
647
- })
648
- }
649
-
650
- export function toInstrumentRunColumns(): InstrumentRunColumnsAdapterResult {
651
- return [
652
- { key: 'order', label: 'Order', sortable: true, align: 'right' },
653
- { key: 'kind', label: 'Kind', sortable: true },
654
- { key: 'sampleId', label: 'Sample ID', sortable: true },
655
- { key: 'name', label: 'Name', sortable: true },
656
- { key: 'method', label: 'Method', sortable: true },
657
- { key: 'vial', label: 'Vial', sortable: true },
658
- { key: 'wellId', label: 'Well', sortable: true },
659
- { key: 'injectionVolume', label: 'Injection', sortable: true, align: 'right' },
660
- { key: 'expectedDurationMin', label: 'Duration', sortable: true, align: 'right' },
661
- { key: 'status', label: 'Status', sortable: true },
662
- { key: 'instrument', label: 'Instrument', sortable: true },
663
- ]
664
- }
665
-
666
- export function toInstrumentRunDataFrame(
667
- template: InstrumentRunTemplate | InstrumentRunTemplateData
668
- ): InstrumentRunDataFrameAdapterResult {
669
- return {
670
- data: toInstrumentRunRows(template),
671
- columns: toInstrumentRunColumns(),
672
- rowKey: 'id',
673
- }
674
- }
675
-
676
- /** Convert an instrument-run template into ExperimentTimeline protocol steps for acquisition queue previews. */
677
- export function toInstrumentRunSteps(
678
- template: InstrumentRunTemplate | InstrumentRunTemplateData
679
- ): InstrumentRunStepsAdapterResult {
680
- const data = getTemplateData(template, 'instrument-run')
681
- validateInstrumentRunData(data)
682
- const methods = new Map(data.methods.map(method => [method.id, method]))
683
- return [...data.items]
684
- .sort((a, b) => a.order - b.order)
685
- .map((item): ProtocolStep => {
686
- const method = methods.get(item.methodId)
687
- const name = item.name ?? item.sampleId ?? item.kind
688
- return {
689
- id: item.id,
690
- type: instrumentRunStepType(item.kind),
691
- name,
692
- description: [
693
- item.kind,
694
- method?.name,
695
- item.vial ? `Vial ${item.vial}` : undefined,
696
- item.wellId ? `Well ${item.wellId}` : undefined,
697
- ]
698
- .filter(Boolean)
699
- .join(' / '),
700
- duration: item.expectedDurationMin,
701
- status: instrumentRunStepStatus(item.status),
702
- parameters: {
703
- kind: item.kind,
704
- sampleId: item.sampleId,
705
- methodId: item.methodId,
706
- method: method?.name,
707
- vial: item.vial,
708
- plateId: item.plateId,
709
- wellId: item.wellId,
710
- injectionVolume: item.injectionVolume,
711
- instrument: data.instrument ?? method?.instrument,
712
- },
713
- order: item.order,
714
- }
715
- })
716
- }
717
-
718
- /** Convert an instrument-run template into readonly ScheduleCalendar events ordered by run queue timing. */
719
- export function toInstrumentRunScheduleEvents(
720
- template: InstrumentRunTemplate | InstrumentRunTemplateData
721
- ): InstrumentRunScheduleEventsAdapterResult {
722
- const data = getTemplateData(template, 'instrument-run')
723
- validateInstrumentRunData(data)
724
- const methods = new Map(data.methods.map(method => [method.id, method]))
725
- let cursor = dateFromMetadata(data.metadata, ['scheduledStart', 'runStart', 'start', 'startedAt'])
726
- ?? new Date('2024-01-01T08:00:00.000Z')
727
-
728
- return [...data.items]
729
- .sort((a, b) => a.order - b.order)
730
- .map((item): ScheduleEvent => {
731
- const method = methods.get(item.methodId)
732
- const start = dateFromMetadata(item.metadata, ['scheduledStart', 'start', 'startedAt']) ?? cursor
733
- const end = dateFromMetadata(item.metadata, ['scheduledEnd', 'end', 'completedAt'])
734
- ?? addMinutes(start, Math.max(item.expectedDurationMin ?? 10, 1))
735
- cursor = end
736
-
737
- return {
738
- id: item.id,
739
- title: item.name ?? item.sampleId ?? item.kind,
740
- start: start.toISOString(),
741
- end: end.toISOString(),
742
- color: instrumentRunScheduleColor(item.kind),
743
- status: instrumentRunScheduleStatus(item.status),
744
- draggable: false,
745
- resizable: false,
746
- metadata: {
747
- kind: item.kind,
748
- sampleId: item.sampleId,
749
- methodId: item.methodId,
750
- method: method?.name,
751
- vial: item.vial,
752
- plateId: item.plateId,
753
- wellId: item.wellId,
754
- injectionVolume: item.injectionVolume,
755
- instrument: data.instrument ?? method?.instrument,
756
- },
757
- }
758
- })
759
- }
760
-
761
- export function toQpcrRows(
762
- template: QpcrPlateTemplate | QpcrPlateTemplateData
763
- ): QpcrRowsAdapterResult {
764
- const data = getTemplateData(template, 'qpcr-plate')
765
- validateQpcrPlateData(data)
766
- const samples = new Map(data.samples.map(sample => [sample.sampleId, sample]))
767
- const targets = new Map(data.targets.map(target => [target.id, target]))
768
-
769
- return data.reactions.map(reaction => {
770
- const sample = reaction.sampleId ? samples.get(reaction.sampleId) : undefined
771
- const target = targets.get(reaction.targetId)
772
- return {
773
- id: reaction.id,
774
- wellId: reaction.wellId,
775
- sampleId: reaction.sampleId,
776
- sample: sample?.name ?? reaction.sampleId ?? reaction.controlKind,
777
- group: sample?.group,
778
- targetId: reaction.targetId,
779
- target: target?.name ?? reaction.targetId,
780
- replicate: reaction.replicate,
781
- controlKind: reaction.controlKind,
782
- cq: reaction.cq ?? null,
783
- quantity: reaction.quantity ?? null,
784
- flags: reaction.flags.join(', '),
785
- instrument: data.instrument,
786
- chemistry: data.chemistry,
787
- ...(reaction.metadata ?? {}),
788
- }
789
- })
790
- }
791
-
792
- export function toQpcrColumns(): QpcrColumnsAdapterResult {
793
- return [
794
- { key: 'wellId', label: 'Well', sortable: true },
795
- { key: 'sample', label: 'Sample', sortable: true },
796
- { key: 'group', label: 'Group', sortable: true },
797
- { key: 'target', label: 'Target', sortable: true },
798
- { key: 'replicate', label: 'Replicate', sortable: true, align: 'right' },
799
- { key: 'controlKind', label: 'Control', sortable: true },
800
- { key: 'cq', label: 'Cq', sortable: true, align: 'right' },
801
- { key: 'quantity', label: 'Quantity', sortable: true, align: 'right' },
802
- { key: 'flags', label: 'Flags' },
803
- ]
804
- }
805
-
806
- export function toQpcrDataFrame(
807
- template: QpcrPlateTemplate | QpcrPlateTemplateData
808
- ): QpcrDataFrameAdapterResult {
809
- return {
810
- data: toQpcrRows(template),
811
- columns: toQpcrColumns(),
812
- rowKey: 'id',
813
- }
814
- }
815
-
816
- export function toQpcrWellPlateWells(
817
- template: QpcrPlateTemplate | QpcrPlateTemplateData
818
- ): QpcrWellMapAdapterResult {
819
- const data = getTemplateData(template, 'qpcr-plate')
820
- validateQpcrPlateData(data)
821
- return Object.fromEntries(data.reactions.map(reaction => {
822
- const [row, col] = wellPositionFromId(reaction.wellId)
823
- return [
824
- reaction.wellId,
825
- {
826
- id: reaction.wellId,
827
- row,
828
- col,
829
- state: 'filled' as const,
830
- sampleType: reaction.sampleId ?? reaction.controlKind,
831
- value: reaction.cq ?? undefined,
832
- metadata: {
833
- reactionId: reaction.id,
834
- sampleId: reaction.sampleId,
835
- targetId: reaction.targetId,
836
- replicate: reaction.replicate,
837
- controlKind: reaction.controlKind,
838
- },
839
- } satisfies Well,
840
- ]
841
- }))
842
- }
17
+ import { toAssayMatrixDataFrame } from './assayMatrixAdapters'
18
+ import { toCalibrationCurveDataFrame } from './calibrationCurveAdapters'
19
+ import { toFlowPanelDataFrame } from './flowPanelAdapters'
20
+ import { toInstrumentRunDataFrame } from './instrumentRunAdapters'
21
+ import { toProtocolDataFrame } from './protocolAdapters'
22
+ import { toQpcrDataFrame } from './qpcrAdapters'
23
+ import { toReagentDataFrame } from './reagentAdapters'
24
+ import { toSamplePrepDataFrame } from './samplePrepAdapters'
25
+ import { toSampleDataFrame } from './sampleSheetAdapters'
26
+ import { toTimeCourseDataFrame } from './timeCourseAdapters'
27
+
28
+ export {
29
+ toAssayMatrixColumns,
30
+ toAssayMatrixDataFrame,
31
+ toAssayMatrixRows,
32
+ toAssayMatrixSampleOptions,
33
+ } from './assayMatrixAdapters'
34
+
35
+ export {
36
+ toCalibrationCurveColumns,
37
+ toCalibrationCurveDataFrame,
38
+ toCalibrationCurveRows,
39
+ } from './calibrationCurveAdapters'
40
+
41
+ export {
42
+ toDoseConditions,
43
+ toDoseLayoutState,
44
+ } from './doseResponseAdapters'
45
+
46
+ export {
47
+ toFlowPanelColumns,
48
+ toFlowPanelDataFrame,
49
+ toFlowPanelRows,
50
+ } from './flowPanelAdapters'
51
+
52
+ export {
53
+ toInstrumentRunColumns,
54
+ toInstrumentRunDataFrame,
55
+ toInstrumentRunRows,
56
+ toInstrumentRunScheduleEvents,
57
+ toInstrumentRunSteps,
58
+ } from './instrumentRunAdapters'
59
+
60
+ export {
61
+ toPlateMapEditorState,
62
+ toWellPlateWells,
63
+ } from './plateMapAdapters'
64
+
65
+ export {
66
+ toProtocolColumns,
67
+ toProtocolDataFrame,
68
+ toProtocolRows,
69
+ toProtocolSteps,
70
+ } from './protocolAdapters'
71
+
72
+ export {
73
+ toQpcrColumns,
74
+ toQpcrDataFrame,
75
+ toQpcrRows,
76
+ toQpcrWellPlateWells,
77
+ } from './qpcrAdapters'
78
+
79
+ export {
80
+ toReagentColumns,
81
+ toReagentDataFrame,
82
+ toReagentListItems,
83
+ toReagentRows,
84
+ } from './reagentAdapters'
85
+
86
+ export {
87
+ toSamplePrepColumns,
88
+ toSamplePrepDataFrame,
89
+ toSamplePrepRows,
90
+ } from './samplePrepAdapters'
91
+
92
+ export {
93
+ toSampleColumns,
94
+ toSampleDataFrame,
95
+ toSampleOptions,
96
+ toSampleRows,
97
+ } from './sampleSheetAdapters'
98
+
99
+ export {
100
+ toTimeCourseColumns,
101
+ toTimeCourseDataFrame,
102
+ toTimeCourseRows,
103
+ toTimeCourseSteps,
104
+ } from './timeCourseAdapters'
843
105
 
844
106
  export function toTemplateDataFrame(
845
107
  template: DataFrameTemplate | BioTemplateEnvelope<unknown>
@@ -873,106 +135,3 @@ export function toTemplateDataFrame(
873
135
  export function toWellMapArray(wells: Record<string, Well>): Well[] {
874
136
  return Object.values(wells)
875
137
  }
876
-
877
- function wellPositionFromId(wellId: string): [number, number] {
878
- const match = /^([A-Z]+)([1-9][0-9]*)$/.exec(wellId.toUpperCase())
879
- if (!match) {
880
- throw new Error(`Invalid well id '${wellId}'.`)
881
- }
882
- const row = [...match[1]].reduce((value, char) => value * 26 + char.charCodeAt(0) - 64, 0) - 1
883
- const col = Number(match[2]) - 1
884
- return [row, col]
885
- }
886
-
887
- function sampleColumnKey(columnId: string): string {
888
- const aliases: Record<string, string> = {
889
- sample_id: 'sampleId',
890
- plate_id: 'plateId',
891
- well_id: 'wellId',
892
- }
893
- return aliases[columnId] ?? columnId
894
- }
895
-
896
- function instrumentRunStepType(kind: InstrumentRunItemKind): ProtocolStepType {
897
- switch (kind) {
898
- case 'wash':
899
- return 'wash'
900
- case 'blank':
901
- case 'qc':
902
- case 'standard':
903
- case 'calibration':
904
- case 'sample':
905
- return 'measurement'
906
- default:
907
- return 'custom'
908
- }
909
- }
910
-
911
- function instrumentRunStepStatus(status: InstrumentRunStatus): ProtocolStepStatus {
912
- switch (status) {
913
- case 'running':
914
- return 'in_progress'
915
- case 'completed':
916
- return 'completed'
917
- case 'failed':
918
- return 'failed'
919
- case 'skipped':
920
- return 'skipped'
921
- case 'planned':
922
- case 'queued':
923
- default:
924
- return 'pending'
925
- }
926
- }
927
-
928
- function instrumentRunScheduleStatus(status: InstrumentRunStatus): ScheduleEventStatus {
929
- switch (status) {
930
- case 'running':
931
- return 'in-progress'
932
- case 'completed':
933
- return 'confirmed'
934
- case 'failed':
935
- case 'skipped':
936
- return 'cancelled'
937
- case 'planned':
938
- case 'queued':
939
- default:
940
- return 'pending'
941
- }
942
- }
943
-
944
- function instrumentRunScheduleColor(kind: InstrumentRunItem['kind']): string {
945
- switch (kind) {
946
- case 'blank':
947
- return '#64748b'
948
- case 'qc':
949
- return '#8b5cf6'
950
- case 'standard':
951
- case 'calibration':
952
- return '#f59e0b'
953
- case 'wash':
954
- return '#06b6d4'
955
- case 'sample':
956
- return '#2563eb'
957
- default:
958
- return '#475569'
959
- }
960
- }
961
-
962
- function dateFromMetadata(
963
- metadata: Record<string, unknown> | undefined,
964
- keys: readonly string[]
965
- ): Date | undefined {
966
- if (!metadata) return undefined
967
- for (const key of keys) {
968
- const value = metadata[key]
969
- if (!(typeof value === 'string' || value instanceof Date)) continue
970
- const date = new Date(value)
971
- if (!Number.isNaN(date.getTime())) return date
972
- }
973
- return undefined
974
- }
975
-
976
- function addMinutes(date: Date, minutes: number): Date {
977
- return new Date(date.getTime() + minutes * 60_000)
978
- }