@morscherlab/mint-sdk 1.2.0-beta.15 → 1.2.0-beta.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -0
- package/dist/{ExperimentPopover-BIZKoRTT.js → ExperimentPopover-CJdNlCZb.js} +3 -3
- package/dist/{ExperimentPopover-BIZKoRTT.js.map → ExperimentPopover-CJdNlCZb.js.map} +1 -1
- package/dist/{ExperimentSelectorModal-BeEOomw_.js → ExperimentSelectorModal-CZ1f_K9I.js} +5 -5
- package/dist/{ExperimentSelectorModal-BeEOomw_.js.map → ExperimentSelectorModal-CZ1f_K9I.js.map} +1 -1
- package/dist/{SettingsModal-Dphh3RrI.js → SettingsModal-DQUcpT4T.js} +5 -5
- package/dist/{SettingsModal-Dphh3RrI.js.map → SettingsModal-DQUcpT4T.js.map} +1 -1
- package/dist/{Skeleton-DxtwJ5gt.js → Skeleton-JaDtC8-9.js} +3 -3
- package/dist/{Skeleton-DxtwJ5gt.js.map → Skeleton-JaDtC8-9.js.map} +1 -1
- package/dist/__tests__/apiErrors.test.d.ts +1 -0
- package/dist/__tests__/components/PlotlyChart.test.d.ts +1 -0
- package/dist/apiErrors.d.ts +26 -0
- package/dist/components/BaseInput.vue.d.ts +1 -1
- package/dist/components/BaseSelect.vue.d.ts +1 -1
- package/dist/components/BaseTextarea.vue.d.ts +1 -1
- package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +2 -2
- package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +2 -2
- package/dist/components/ConcentrationInput.vue.d.ts +1 -1
- package/dist/components/DatePicker.vue.d.ts +1 -1
- package/dist/components/DateTimePicker.vue.d.ts +1 -1
- package/dist/components/FileBrowserModal.vue.d.ts +1 -1
- package/dist/components/FilePicker.vue.d.ts +3 -3
- package/dist/components/FileUploader.vue.d.ts +5 -2
- package/dist/components/FormulaInput.vue.d.ts +1 -1
- package/dist/components/GeneratedPlotlyResult.vue.d.ts +1 -3
- package/dist/components/MobileSupportGate.vue.d.ts +1 -1
- package/dist/components/MoleculeInput.vue.d.ts +1 -1
- package/dist/components/NumberInput.vue.d.ts +1 -1
- package/dist/components/PlotlyChart.vue.d.ts +59 -0
- package/dist/components/ResourceCard.vue.d.ts +1 -1
- package/dist/components/SecretInput.vue.d.ts +1 -1
- package/dist/components/SequenceInput.vue.d.ts +1 -1
- package/dist/components/StatusIndicator.vue.d.ts +1 -1
- package/dist/components/TagsInput.vue.d.ts +1 -1
- package/dist/components/TimePicker.vue.d.ts +1 -1
- package/dist/components/TimeRangeInput.vue.d.ts +1 -1
- package/dist/components/UnitInput.vue.d.ts +1 -1
- package/dist/components/WellPlate.vue.d.ts +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +8 -8
- package/dist/{components-6IIxCSI8.js → components-DT6ggNrt.js} +580 -366
- package/dist/components-DT6ggNrt.js.map +1 -0
- package/dist/composables/filePicker/localFiles.d.ts +1 -1
- package/dist/composables/filePicker/usePickerNavigation.d.ts +4 -3
- package/dist/composables/index.js +9 -9
- package/dist/composables/useApi.d.ts +2 -0
- package/dist/composables/useFilePicker.d.ts +5 -6
- package/dist/{composables-hY2Q2xPI.js → composables-DmF_8iyX.js} +13 -10
- package/dist/{composables-hY2Q2xPI.js.map → composables-DmF_8iyX.js.map} +1 -1
- package/dist/{errors-_W0-LbA6.js → errors-DZDb1cIb.js} +66 -5
- package/dist/errors-DZDb1cIb.js.map +1 -0
- package/dist/{experiment-Cwl9AYxw.js → experiment-CHm_TwJy.js} +2 -2
- package/dist/{experiment-Cwl9AYxw.js.map → experiment-CHm_TwJy.js.map} +1 -1
- package/dist/{experiment-utils-DV3DrvE_.js → experiment-utils-CV2Wza3z.js} +1 -1
- package/dist/{experiment-utils-DV3DrvE_.js.map → experiment-utils-CV2Wza3z.js.map} +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +15 -15
- package/dist/install.js +2 -2
- package/dist/stores/index.js +2 -2
- package/dist/styles.css +29 -18
- package/dist/templates/index.js +2 -2
- package/dist/{templates-Qq113pyZ.js → templates-CXARYr6_.js} +2 -2
- package/dist/{templates-Qq113pyZ.js.map → templates-CXARYr6_.js.map} +1 -1
- package/dist/types/filePicker.d.ts +9 -1
- package/dist/{useControlSchema-aMZlb4Sc.js → useControlSchema-BAzmP1_y.js} +42 -37
- package/dist/useControlSchema-BAzmP1_y.js.map +1 -0
- package/dist/{useDropdownState-DitCtrTT.js → useDropdownState-C7hRiVQf.js} +2 -2
- package/dist/{useDropdownState-DitCtrTT.js.map → useDropdownState-C7hRiVQf.js.map} +1 -1
- package/dist/{useExperimentSelector-I8HC8hUu.js → useExperimentSelector-D_vobhnW.js} +4 -4
- package/dist/{useExperimentSelector-I8HC8hUu.js.map → useExperimentSelector-D_vobhnW.js.map} +1 -1
- package/dist/{useFormBuilder-TCxNnqeb.js → useFormBuilder-DEHejpiL.js} +2 -2
- package/dist/{useFormBuilder-TCxNnqeb.js.map → useFormBuilder-DEHejpiL.js.map} +1 -1
- package/dist/{validation-nBbSn1TI.js → validation-OuEr0iAS.js} +9 -8
- package/dist/{validation-nBbSn1TI.js.map → validation-OuEr0iAS.js.map} +1 -1
- package/package.json +1 -1
- package/src/__tests__/apiErrors.test.ts +81 -0
- package/src/__tests__/components/FilePicker.state.test.ts +128 -1
- package/src/__tests__/components/FilePicker.test.ts +146 -1
- package/src/__tests__/components/GeneratedPlotlyResult.test.ts +52 -5
- package/src/__tests__/components/PlotlyChart.test.ts +305 -0
- package/src/__tests__/components/SegmentedControl.test.ts +19 -0
- package/src/__tests__/composables/useApi.test.ts +82 -9
- package/src/__tests__/composables/useGeneratedAnalysis.test.ts +7 -2
- package/src/__tests__/composables/usePluginClient.test.ts +3 -0
- package/src/apiErrors.ts +85 -0
- package/src/components/FilePicker.story.vue +44 -0
- package/src/components/FilePicker.vue +23 -40
- package/src/components/FileUploader.vue +32 -14
- package/src/components/GeneratedPlotlyResult.vue +34 -69
- package/src/components/GeneratedResultRenderer.vue +0 -5
- package/src/components/PlotlyChart.story.vue +61 -0
- package/src/components/PlotlyChart.vue +233 -0
- package/src/components/SegmentedControl.vue +2 -2
- package/src/components/index.ts +1 -0
- package/src/composables/filePicker/localFiles.ts +6 -3
- package/src/composables/filePicker/usePickerNavigation.ts +29 -8
- package/src/composables/filePicker/usePickerSelection.ts +17 -4
- package/src/composables/filePicker/validation.ts +1 -0
- package/src/composables/useApi.ts +33 -4
- package/src/composables/useFilePicker.ts +41 -22
- package/src/composables/useGeneratedAnalysis.ts +10 -17
- package/src/composables/usePluginClient.ts +3 -0
- package/src/index.ts +3 -0
- package/src/styles/components/file-picker.css +6 -5
- package/src/types/filePicker.ts +9 -2
- package/dist/components-6IIxCSI8.js.map +0 -1
- package/dist/errors-_W0-LbA6.js.map +0 -1
- package/dist/useControlSchema-aMZlb4Sc.js.map +0 -1
|
@@ -14,6 +14,7 @@ import type {
|
|
|
14
14
|
} from './useJobsStatusTray'
|
|
15
15
|
import { useEventStream, type EventStreamMessage } from './useEventStream'
|
|
16
16
|
import { isActiveJobStatus, normalizeJobState } from '../jobs'
|
|
17
|
+
import { MintApiError, mintApiErrorFromResponse } from '../apiErrors'
|
|
17
18
|
import type {
|
|
18
19
|
GeneratedAnalysisJob,
|
|
19
20
|
GeneratedAnalysisJobInput,
|
|
@@ -129,16 +130,6 @@ type PluginJobStreamData = GeneratedAnalysisJobInput | {
|
|
|
129
130
|
jobs: GeneratedAnalysisJobInput[]
|
|
130
131
|
}
|
|
131
132
|
|
|
132
|
-
class GeneratedAnalysisRequestError extends Error {
|
|
133
|
-
constructor(
|
|
134
|
-
readonly status: number,
|
|
135
|
-
readonly detail: unknown,
|
|
136
|
-
) {
|
|
137
|
-
super(typeof detail === 'string' ? detail : `Request failed (${status})`)
|
|
138
|
-
this.name = 'GeneratedAnalysisRequestError'
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
133
|
export function createGeneratedAnalysisTransport(
|
|
143
134
|
options: GeneratedAnalysisTransportOptions = {},
|
|
144
135
|
): GeneratedAnalysisTransport {
|
|
@@ -838,7 +829,7 @@ function createPluginJobs(
|
|
|
838
829
|
job: GeneratedAnalysisJob,
|
|
839
830
|
cause: unknown,
|
|
840
831
|
): void {
|
|
841
|
-
if (cause instanceof
|
|
832
|
+
if (cause instanceof MintApiError) {
|
|
842
833
|
if (cause.status === 404 || cause.status === 410) {
|
|
843
834
|
discardCachedResult(job.job_id)
|
|
844
835
|
jobs.value = jobs.value.map(candidate => (
|
|
@@ -1037,8 +1028,10 @@ function createPluginJobs(
|
|
|
1037
1028
|
},
|
|
1038
1029
|
})
|
|
1039
1030
|
if (!response.ok) {
|
|
1040
|
-
const payload = await response.json().catch(() => null)
|
|
1041
|
-
throw
|
|
1031
|
+
const payload: unknown = await response.json().catch(() => null)
|
|
1032
|
+
throw mintApiErrorFromResponse(response.status, payload, {
|
|
1033
|
+
requestId: response.headers.get('X-Request-ID'),
|
|
1034
|
+
})
|
|
1042
1035
|
}
|
|
1043
1036
|
return await response.json() as T
|
|
1044
1037
|
}
|
|
@@ -1177,20 +1170,20 @@ function createGeneratedSessionStorage(candidate?: Storage): GeneratedSessionSto
|
|
|
1177
1170
|
}
|
|
1178
1171
|
|
|
1179
1172
|
function isSessionNotFoundError(error: unknown): boolean {
|
|
1180
|
-
return error instanceof
|
|
1173
|
+
return error instanceof MintApiError
|
|
1181
1174
|
&& error.status === 404
|
|
1182
|
-
&& error.detail === SESSION_NOT_FOUND_DETAIL
|
|
1175
|
+
&& (error.detail === SESSION_NOT_FOUND_DETAIL || error.message === SESSION_NOT_FOUND_DETAIL)
|
|
1183
1176
|
}
|
|
1184
1177
|
|
|
1185
1178
|
function isRetryableResultError(error: unknown): boolean {
|
|
1186
|
-
return !(error instanceof
|
|
1179
|
+
return !(error instanceof MintApiError)
|
|
1187
1180
|
|| error.status === 409
|
|
1188
1181
|
|| error.status === 429
|
|
1189
1182
|
|| error.status >= 500
|
|
1190
1183
|
}
|
|
1191
1184
|
|
|
1192
1185
|
function isRetryableJobLookupError(error: unknown): boolean {
|
|
1193
|
-
return !(error instanceof
|
|
1186
|
+
return !(error instanceof MintApiError)
|
|
1194
1187
|
|| error.status === 408
|
|
1195
1188
|
|| error.status === 429
|
|
1196
1189
|
|| error.status >= 500
|
|
@@ -423,6 +423,7 @@ export function createPluginClient<TClient extends object = GeneratedPluginClien
|
|
|
423
423
|
const api = useApi({
|
|
424
424
|
baseUrl: parts.baseUrl,
|
|
425
425
|
withAuth: endpoint.requiresAuth !== false,
|
|
426
|
+
typedErrors: true,
|
|
426
427
|
})
|
|
427
428
|
const config = endpointRequestConfig(endpoint, parts.query, callOptions)
|
|
428
429
|
|
|
@@ -469,6 +470,7 @@ export async function uploadPluginEndpoint<TResponse = unknown>(
|
|
|
469
470
|
const api = useApi({
|
|
470
471
|
baseUrl: parts.baseUrl,
|
|
471
472
|
withAuth: endpoint.requiresAuth !== false,
|
|
473
|
+
typedErrors: true,
|
|
472
474
|
})
|
|
473
475
|
const body = endpoint.hasBody
|
|
474
476
|
? requestBodyFromPayload(payload, parts.requestPayload, endpoint)
|
|
@@ -507,6 +509,7 @@ export async function downloadPluginEndpoint(
|
|
|
507
509
|
const api = useApi({
|
|
508
510
|
baseUrl: parts.baseUrl,
|
|
509
511
|
withAuth: endpoint.requiresAuth !== false,
|
|
512
|
+
typedErrors: true,
|
|
510
513
|
})
|
|
511
514
|
const config = {
|
|
512
515
|
...(endpointRequestConfig(endpoint, parts.query, { signal: options.signal }) ?? {}),
|
package/src/index.ts
CHANGED
|
@@ -386,17 +386,18 @@
|
|
|
386
386
|
gap: 8px;
|
|
387
387
|
flex-shrink: 0;
|
|
388
388
|
}
|
|
389
|
-
.mint-picker__local-
|
|
389
|
+
.mint-picker__local-upload {
|
|
390
390
|
display: flex;
|
|
391
|
-
|
|
391
|
+
flex-direction: column;
|
|
392
392
|
gap: 8px;
|
|
393
|
-
padding:
|
|
393
|
+
padding: 12px 18px;
|
|
394
394
|
flex-shrink: 0;
|
|
395
|
-
}
|
|
396
|
-
.mint-picker__local-actions > span {
|
|
397
395
|
color: var(--text-muted);
|
|
398
396
|
font-size: 11px;
|
|
399
397
|
}
|
|
398
|
+
.mint-picker__local-title {
|
|
399
|
+
flex: 1;
|
|
400
|
+
}
|
|
400
401
|
@media (max-width: 600px) {
|
|
401
402
|
.mint-picker-dialog .mint-file-browser-dialog__header {
|
|
402
403
|
padding: 10px;
|
package/src/types/filePicker.ts
CHANGED
|
@@ -27,6 +27,13 @@ export type PickerNode = PickerFolder | PickerFile
|
|
|
27
27
|
export interface PickerRequest {
|
|
28
28
|
signal?: AbortSignal
|
|
29
29
|
source?: PickerSource
|
|
30
|
+
/**
|
|
31
|
+
* Set only when the user pressed Refresh. Adapters that cache listings (or
|
|
32
|
+
* ask a server to bypass its own cache) should re-read the location then and
|
|
33
|
+
* serve cached data otherwise; the picker keeps folder contents while it is
|
|
34
|
+
* open and re-reads the current location on each open.
|
|
35
|
+
*/
|
|
36
|
+
refresh?: true
|
|
30
37
|
}
|
|
31
38
|
export interface PickerAdapter {
|
|
32
39
|
listRoot(request?: PickerRequest): Promise<PickerNode[]>
|
|
@@ -46,7 +53,7 @@ export interface PickerCapability {
|
|
|
46
53
|
}
|
|
47
54
|
export type PickerCapabilities = Partial<Record<PickerSource, PickerCapability>>
|
|
48
55
|
export type PickerExclusionReason =
|
|
49
|
-
'deselected' | 'unsupported' | 'tooLarge' | 'blank' | 'unreadable'
|
|
56
|
+
'deselected' | 'unsupported' | 'tooLarge' | 'blank' | 'unreadable' | 'forbidden'
|
|
50
57
|
export interface PickerExcluded {
|
|
51
58
|
/** Opaque identity prevents collisions between equal filenames in different folders. */
|
|
52
59
|
path: string
|
|
@@ -55,7 +62,7 @@ export interface PickerExcluded {
|
|
|
55
62
|
}
|
|
56
63
|
export type PickerSelection =
|
|
57
64
|
| { source: 'server'; folders: string[]; files: PickerFile[]; excluded: PickerExcluded[] }
|
|
58
|
-
| { source: 'localFile'; files: File[] }
|
|
65
|
+
| { source: 'localFile'; files: File[]; relativePaths?: string[] }
|
|
59
66
|
export interface PickerTreeRow {
|
|
60
67
|
node: PickerNode
|
|
61
68
|
depth: number
|