@morscherlab/mint-sdk 1.0.51 → 1.0.52
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/dist/__tests__/components/JobsStatusTray.test.d.ts +1 -0
- package/dist/__tests__/composables/useJobsStatusTray.test.d.ts +1 -0
- package/dist/__tests__/utils/jobs.test.d.ts +1 -0
- package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +1 -1
- package/dist/components/JobsStatusTray.vue.d.ts +26 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +2 -2
- package/dist/{components-C7UFkNIp.js → components-Lk_h_rON.js} +1663 -1339
- package/dist/components-Lk_h_rON.js.map +1 -0
- package/dist/composables/index.d.ts +1 -0
- package/dist/composables/index.js +3 -3
- package/dist/composables/useJobsStatusTray.d.ts +43 -0
- package/dist/composables/usePluginClient.d.ts +4 -1
- package/dist/{composables-CpBhNKHf.js → composables-DyfGpYZw.js} +50 -17
- package/dist/{composables-CpBhNKHf.js.map → composables-DyfGpYZw.js.map} +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4 -4
- package/dist/install.js +1 -1
- package/dist/jobs.d.ts +19 -0
- package/dist/styles.css +731 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/jobs.d.ts +49 -0
- package/dist/{useProtocolTemplates-C8-YlHj1.js → useJobsStatusTray-DAH999_N.js} +250 -2
- package/dist/useJobsStatusTray-DAH999_N.js.map +1 -0
- package/package.json +1 -1
- package/src/__tests__/components/JobsStatusTray.test.ts +141 -0
- package/src/__tests__/composables/useJobsStatusTray.test.ts +241 -0
- package/src/__tests__/composables/usePluginClient.test.ts +243 -0
- package/src/__tests__/utils/jobs.test.ts +95 -0
- package/src/components/JobsStatusTray.story.vue +120 -0
- package/src/components/JobsStatusTray.vue +385 -0
- package/src/components/index.ts +1 -0
- package/src/composables/index.ts +8 -0
- package/src/composables/useJobsStatusTray.ts +304 -0
- package/src/composables/usePluginClient.ts +65 -15
- package/src/index.ts +3 -0
- package/src/jobs.ts +75 -0
- package/src/styles/components/jobs-status-tray.css +420 -0
- package/src/styles/index.css +1 -0
- package/src/types/index.ts +10 -0
- package/src/types/jobs.ts +61 -0
- package/dist/components-C7UFkNIp.js.map +0 -1
- package/dist/useProtocolTemplates-C8-YlHj1.js.map +0 -1
|
@@ -53,3 +53,4 @@ export { useBioTemplateWorkspace, type BioTemplateRendererBinding, type BioTempl
|
|
|
53
53
|
export { useBioTemplatePresetWorkspace, type BioTemplatePresetWorkspaceBindings, type UseBioTemplatePresetWorkspaceOptions, type UseBioTemplatePresetWorkspaceReturn, } from './useBioTemplatePresetWorkspace';
|
|
54
54
|
export { useBioTemplatePackWorkspace, type UseBioTemplatePackWorkspaceOptions, type UseBioTemplatePackWorkspaceReturn, } from './useBioTemplatePackWorkspace';
|
|
55
55
|
export { buildPluginEndpointUrl, createPluginClient, downloadBlob, downloadPluginEndpoint, getPluginPageSelectorItems, pluginFormDataFromPayload, resolvePluginBaseUrl, uploadPluginEndpoint, usePluginClient, usePluginEventStream, usePluginSettings, useCurrentExperiment, type BuildPluginEndpointUrlOptions, type DownloadBlobOptions, type DownloadPluginEndpointOptions, type PluginContract, type PluginEndpointContract, type PluginEndpointDefinition, type PluginHttpMethod, type PluginNavItemContract, type PluginEndpointRequestOptions, type PluginEventStreamMessage, type PluginEventStreamOptions, type PluginFormDataPayload, type PluginFormDataValue, type CreatePluginClientOptions, type UseCurrentExperimentOptions, type UseCurrentExperimentReturn, type UsePluginEventStreamReturn, type UsePluginSettingsOptions, type UsePluginSettingsReturn, } from './usePluginClient';
|
|
56
|
+
export { useJobsStatusTray, type JobsStatusTrayAdapter, type JobsStatusTrayTab, type JobStreamMessage, type UseJobsStatusTrayOptions, type UseJobsStatusTrayReturn, } from './useJobsStatusTray';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import "../BaseSelect-ekgr9fDo.js";
|
|
2
2
|
import { $ as parseTime, A as useConcentrationUnits, C as controlsToViewIds, D as getTypeDefault, E as getFieldRegistryEntry, F as ATOMIC_WEIGHTS, G as findAvailableSlots, H as addMinutes, I as useChemicalFormula, J as formatTime, K as findNearestTimeSlotIndex, N as useSequenceUtils, Q as isTimeInRange, S as controlsToTopBarSettingsConfig, T as getDefaultControlView, U as compareTime, W as durationMinutes, X as fromMinutes, Y as formatTimeSlot, Z as generateTimeSlots, _ as controlsToFormSchema, a as defineDoseCalculatorControlProps, b as controlsToSettingsSchema, c as defineWellPlateDoseComponentBindings, d as defineControlModel, et as rangesOverlap, h as controlValuesToComponentProps, i as useControlSchema, l as defineWellPlateDoseControlProps, m as controlValuesToComponentBindingsById, n as defineControls, nt as toMinutes, o as defineDoseDesignControlModel, ot as useListSelection, p as controlValuesToComponentBindings, q as formatDuration, r as getControlDefaults, rt as useTimeUtils, s as defineWellPlateControlProps, st as useSelectionLimit, t as defineControlComponentBindings, tt as snapToSlot, u as useControlWorkspace, v as controlsToSectionFormSchema, w as controlsToViewItems, x as controlsToSidebarPanels, y as controlsToSectionFormSchemas } from "../useControlSchema-BZNdalmL.js";
|
|
3
3
|
import { t as useEventListener } from "../useEventListener-CfVkP9Xz.js";
|
|
4
|
-
import {
|
|
4
|
+
import { $ as useTheme, A as useExpansionSet, B as extractSamplesFromDesignData, C as useExperimentSave, E as useExperimentData, F as detectDelimiter, G as unwrapExperimentDesignData, I as parseDelimitedText, J as useDoseCalculator, K as DEFAULT_COLORS, L as readFileAsText, Q as useAppExperiment, R as useFileImport, S as useTemplateCollection, T as useExperimentSamples, U as extractSampleNamesFromDesignData, V as useAutoGroup, W as extractSampleOptionsFromDesignData, X as useMobileSupportGate, Y as DEFAULT_MOBILE_VIEWPORT_QUERY, Z as APP_EXPERIMENT_KEY, _ as useBioTemplateWorkspace, at as useSortedItems, b as useBioTemplateComponents, c as useProtocolTemplates, d as generateDilutionSeries, et as useToast, f as useReagentSeries, g as useBioTemplatePackWorkspace, h as useBioTemplatePresetWorkspace, it as compareSortValues, j as useSampleGroups, l as DEFAULT_PRESETS, m as useRackEditor, nt as normalizeSearchQuery, p as useGroupAssignment, q as useWellPlateEditor, rt as useTextSearch, t as useJobsStatusTray, tt as candidateMatchesSearch, u as DEFAULT_UNITS, v as getBioTemplateComponentProps, w as useScheduleDrag, x as useBioTemplateControls, y as toBioTemplateComponentPropsByComponent, z as validateImportFile } from "../useJobsStatusTray-DAH999_N.js";
|
|
5
5
|
import { i as usePlatformContext, n as evaluateCondition, r as useForm, t as useFormBuilder } from "../useFormBuilder-DKekvXRs.js";
|
|
6
6
|
import { a as SORT_OPTIONS, c as formatExperimentStatus, i as EXPERIMENT_STATUS_VARIANT_MAP, l as getExperimentStatusVariant, n as EXPERIMENT_STATUS_LABELS, o as datePresetToISO, r as EXPERIMENT_STATUS_OPTIONS, s as formatExperimentDate, t as DATE_PRESET_OPTIONS, u as resolveExperimentCode } from "../experiment-utils-Bfa7CwPU.js";
|
|
7
7
|
import { i as useApi, n as useDebouncedWatch, r as useRequestSyncState, t as useExperimentSelector } from "../useExperimentSelector-DdCy5VNv.js";
|
|
8
8
|
import { B as toBioTemplateComponentProps, H as toBioTemplateComponentPropsById, L as toBioTemplateComponentBindings, P as getBioTemplateComponentBindings, R as toBioTemplateComponentBindingsById, l as requireBioTemplateControlSchema, o as getBioTemplateControlSchema } from "../templates-CNbPQNID.js";
|
|
9
|
-
import { A as usePasskey, C as createPluginResourceClient, D as usePluginConfig, E as useCommandHistory, O as useAsync, S as wellIdsInRectangle, T as useOptimisticMutation, _ as createWellPlateWells, a as pluginFormDataFromPayload, b as useWellPainting, c as usePluginClient, d as buildPluginEndpointUrl, f as resolvePluginBaseUrl, g as createRowConditions, h as createColumnConditions, i as getPluginPageSelectorItems, j as useAuth, k as useAsyncBatch, l as usePluginEventStream, m as useWellPlateValidation, n as downloadBlob, o as uploadPluginEndpoint, p as runWellPlateValidation, r as downloadPluginEndpoint, s as useCurrentExperiment, t as createPluginClient, u as usePluginSettings, v as useWellPlateAdapter, w as useResourceCrud, x as wellIdToCoordinate, y as coordinateToWellId } from "../composables-
|
|
10
|
-
export { APP_EXPERIMENT_KEY, ATOMIC_WEIGHTS, DATE_PRESET_OPTIONS, DEFAULT_COLORS, DEFAULT_MOBILE_VIEWPORT_QUERY, DEFAULT_PRESETS, DEFAULT_UNITS, EXPERIMENT_STATUS_LABELS, EXPERIMENT_STATUS_OPTIONS, EXPERIMENT_STATUS_VARIANT_MAP, SORT_OPTIONS, addMinutes, buildPluginEndpointUrl, candidateMatchesSearch, compareSortValues, compareTime, controlValuesToComponentBindings, controlValuesToComponentBindingsById, controlValuesToComponentProps, controlsToFormSchema, controlsToSectionFormSchema, controlsToSectionFormSchemas, controlsToSettingsSchema, controlsToSidebarPanels, controlsToTopBarSettingsConfig, controlsToViewIds, controlsToViewItems, coordinateToWellId, createColumnConditions, createPluginClient, createPluginResourceClient, createRowConditions, createWellPlateWells, datePresetToISO, defineControlComponentBindings, defineControlModel, defineControls, defineDoseCalculatorControlProps, defineDoseDesignControlModel, defineWellPlateControlProps, defineWellPlateDoseComponentBindings, defineWellPlateDoseControlProps, detectDelimiter, downloadBlob, downloadPluginEndpoint, durationMinutes, evaluateCondition, extractSampleNamesFromDesignData, extractSampleOptionsFromDesignData, extractSamplesFromDesignData, findAvailableSlots, findNearestTimeSlotIndex, formatDuration, formatExperimentDate, formatExperimentStatus, formatTime, formatTimeSlot, fromMinutes, generateDilutionSeries, generateTimeSlots, getBioTemplateComponentBindings, getBioTemplateComponentProps, getBioTemplateControlSchema, getControlDefaults, getDefaultControlView, getExperimentStatusVariant, getFieldRegistryEntry, getPluginPageSelectorItems, getTypeDefault, isTimeInRange, normalizeSearchQuery, parseDelimitedText, parseTime, pluginFormDataFromPayload, rangesOverlap, readFileAsText, requireBioTemplateControlSchema, resolveExperimentCode, resolvePluginBaseUrl, runWellPlateValidation, snapToSlot, toBioTemplateComponentBindings, toBioTemplateComponentBindingsById, toBioTemplateComponentProps, toBioTemplateComponentPropsByComponent, toBioTemplateComponentPropsById, toMinutes, unwrapExperimentDesignData, uploadPluginEndpoint, useApi, useAppExperiment, useAsync, useAsyncBatch, useAuth, useAutoGroup, useBioTemplateComponents, useBioTemplateControls, useBioTemplatePackWorkspace, useBioTemplatePresetWorkspace, useBioTemplateWorkspace, useChemicalFormula, useCommandHistory, useConcentrationUnits, useControlSchema, useControlWorkspace, useCurrentExperiment, useDebouncedWatch, useDoseCalculator, useEventListener, useExpansionSet, useExperimentData, useExperimentSamples, useExperimentSave, useExperimentSelector, useFileImport, useForm, useFormBuilder, useGroupAssignment, useListSelection, useMobileSupportGate, useOptimisticMutation, usePasskey, usePlatformContext, usePluginClient, usePluginConfig, usePluginEventStream, usePluginSettings, useProtocolTemplates, useRackEditor, useReagentSeries, useRequestSyncState, useResourceCrud, useSampleGroups, useScheduleDrag, useSelectionLimit, useSequenceUtils, useSortedItems, useTemplateCollection, useTextSearch, useTheme, useTimeUtils, useToast, useWellPainting, useWellPlateAdapter, useWellPlateEditor, useWellPlateValidation, validateImportFile, wellIdToCoordinate, wellIdsInRectangle };
|
|
9
|
+
import { A as usePasskey, C as createPluginResourceClient, D as usePluginConfig, E as useCommandHistory, O as useAsync, S as wellIdsInRectangle, T as useOptimisticMutation, _ as createWellPlateWells, a as pluginFormDataFromPayload, b as useWellPainting, c as usePluginClient, d as buildPluginEndpointUrl, f as resolvePluginBaseUrl, g as createRowConditions, h as createColumnConditions, i as getPluginPageSelectorItems, j as useAuth, k as useAsyncBatch, l as usePluginEventStream, m as useWellPlateValidation, n as downloadBlob, o as uploadPluginEndpoint, p as runWellPlateValidation, r as downloadPluginEndpoint, s as useCurrentExperiment, t as createPluginClient, u as usePluginSettings, v as useWellPlateAdapter, w as useResourceCrud, x as wellIdToCoordinate, y as coordinateToWellId } from "../composables-DyfGpYZw.js";
|
|
10
|
+
export { APP_EXPERIMENT_KEY, ATOMIC_WEIGHTS, DATE_PRESET_OPTIONS, DEFAULT_COLORS, DEFAULT_MOBILE_VIEWPORT_QUERY, DEFAULT_PRESETS, DEFAULT_UNITS, EXPERIMENT_STATUS_LABELS, EXPERIMENT_STATUS_OPTIONS, EXPERIMENT_STATUS_VARIANT_MAP, SORT_OPTIONS, addMinutes, buildPluginEndpointUrl, candidateMatchesSearch, compareSortValues, compareTime, controlValuesToComponentBindings, controlValuesToComponentBindingsById, controlValuesToComponentProps, controlsToFormSchema, controlsToSectionFormSchema, controlsToSectionFormSchemas, controlsToSettingsSchema, controlsToSidebarPanels, controlsToTopBarSettingsConfig, controlsToViewIds, controlsToViewItems, coordinateToWellId, createColumnConditions, createPluginClient, createPluginResourceClient, createRowConditions, createWellPlateWells, datePresetToISO, defineControlComponentBindings, defineControlModel, defineControls, defineDoseCalculatorControlProps, defineDoseDesignControlModel, defineWellPlateControlProps, defineWellPlateDoseComponentBindings, defineWellPlateDoseControlProps, detectDelimiter, downloadBlob, downloadPluginEndpoint, durationMinutes, evaluateCondition, extractSampleNamesFromDesignData, extractSampleOptionsFromDesignData, extractSamplesFromDesignData, findAvailableSlots, findNearestTimeSlotIndex, formatDuration, formatExperimentDate, formatExperimentStatus, formatTime, formatTimeSlot, fromMinutes, generateDilutionSeries, generateTimeSlots, getBioTemplateComponentBindings, getBioTemplateComponentProps, getBioTemplateControlSchema, getControlDefaults, getDefaultControlView, getExperimentStatusVariant, getFieldRegistryEntry, getPluginPageSelectorItems, getTypeDefault, isTimeInRange, normalizeSearchQuery, parseDelimitedText, parseTime, pluginFormDataFromPayload, rangesOverlap, readFileAsText, requireBioTemplateControlSchema, resolveExperimentCode, resolvePluginBaseUrl, runWellPlateValidation, snapToSlot, toBioTemplateComponentBindings, toBioTemplateComponentBindingsById, toBioTemplateComponentProps, toBioTemplateComponentPropsByComponent, toBioTemplateComponentPropsById, toMinutes, unwrapExperimentDesignData, uploadPluginEndpoint, useApi, useAppExperiment, useAsync, useAsyncBatch, useAuth, useAutoGroup, useBioTemplateComponents, useBioTemplateControls, useBioTemplatePackWorkspace, useBioTemplatePresetWorkspace, useBioTemplateWorkspace, useChemicalFormula, useCommandHistory, useConcentrationUnits, useControlSchema, useControlWorkspace, useCurrentExperiment, useDebouncedWatch, useDoseCalculator, useEventListener, useExpansionSet, useExperimentData, useExperimentSamples, useExperimentSave, useExperimentSelector, useFileImport, useForm, useFormBuilder, useGroupAssignment, useJobsStatusTray, useListSelection, useMobileSupportGate, useOptimisticMutation, usePasskey, usePlatformContext, usePluginClient, usePluginConfig, usePluginEventStream, usePluginSettings, useProtocolTemplates, useRackEditor, useReagentSeries, useRequestSyncState, useResourceCrud, useSampleGroups, useScheduleDrag, useSelectionLimit, useSequenceUtils, useSortedItems, useTemplateCollection, useTextSearch, useTheme, useTimeUtils, useToast, useWellPainting, useWellPlateAdapter, useWellPlateEditor, useWellPlateValidation, validateImportFile, wellIdToCoordinate, wellIdsInRectangle };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ComputedRef, MaybeRefOrGetter, Ref, ShallowRef } from 'vue';
|
|
2
|
+
import { JobListPayload, JobState, JobStateInput, JobStreamData } from '../types/jobs';
|
|
3
|
+
import { UsePluginEventStreamReturn } from './usePluginClient';
|
|
4
|
+
export type JobsStatusTrayTab = 'active' | 'history';
|
|
5
|
+
export interface JobsStatusTrayAdapter {
|
|
6
|
+
listJobs?: () => Promise<JobListPayload | readonly JobStateInput[]>;
|
|
7
|
+
cancelJob?: (job: JobState) => Promise<JobStateInput | void>;
|
|
8
|
+
deleteJob?: (job: JobState) => Promise<boolean | void>;
|
|
9
|
+
clearFinishedJobs?: (jobs: readonly JobState[]) => Promise<number | void>;
|
|
10
|
+
}
|
|
11
|
+
export interface UseJobsStatusTrayOptions {
|
|
12
|
+
jobs?: MaybeRefOrGetter<readonly JobStateInput[] | undefined>;
|
|
13
|
+
adapter?: MaybeRefOrGetter<JobsStatusTrayAdapter | undefined>;
|
|
14
|
+
eventStream?: MaybeRefOrGetter<UsePluginEventStreamReturn<JobStreamData> | undefined>;
|
|
15
|
+
loadOnMount?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface JobStreamMessage {
|
|
18
|
+
event: string;
|
|
19
|
+
data: JobStreamData;
|
|
20
|
+
}
|
|
21
|
+
export interface UseJobsStatusTrayReturn {
|
|
22
|
+
jobs: ShallowRef<JobState[]>;
|
|
23
|
+
activeJobs: ComputedRef<JobState[]>;
|
|
24
|
+
historyJobs: ComputedRef<JobState[]>;
|
|
25
|
+
deletableJobs: ComputedRef<JobState[]>;
|
|
26
|
+
featuredJob: ComputedRef<JobState | null>;
|
|
27
|
+
isOpen: Ref<boolean>;
|
|
28
|
+
activeTab: Ref<JobsStatusTrayTab>;
|
|
29
|
+
isLoading: Ref<boolean>;
|
|
30
|
+
error: ShallowRef<string | null>;
|
|
31
|
+
pendingJobIds: Ref<Set<string>>;
|
|
32
|
+
open: () => void;
|
|
33
|
+
close: () => void;
|
|
34
|
+
toggle: () => void;
|
|
35
|
+
refresh: () => Promise<boolean>;
|
|
36
|
+
applyStreamMessage: (message: JobStreamMessage) => void;
|
|
37
|
+
cancelJob: (job: JobState) => Promise<boolean>;
|
|
38
|
+
deleteJob: (job: JobState) => Promise<boolean>;
|
|
39
|
+
clearFinished: () => Promise<boolean>;
|
|
40
|
+
isPending: (job: JobState) => boolean;
|
|
41
|
+
}
|
|
42
|
+
/** Headless state and action controller for the standard SDK jobs tray. */
|
|
43
|
+
export declare function useJobsStatusTray(options?: UseJobsStatusTrayOptions): UseJobsStatusTrayReturn;
|
|
@@ -10,6 +10,7 @@ export interface PluginEndpointContract {
|
|
|
10
10
|
queryParams?: PluginEndpointParamContract[];
|
|
11
11
|
requestType?: string | null;
|
|
12
12
|
responseType?: string | null;
|
|
13
|
+
eventStream?: boolean;
|
|
13
14
|
}
|
|
14
15
|
export interface PluginEndpointParamContract {
|
|
15
16
|
name: string;
|
|
@@ -57,6 +58,8 @@ export interface PluginEndpointDefinition {
|
|
|
57
58
|
pathParams?: PluginEndpointParamDefinition[];
|
|
58
59
|
queryParams?: PluginEndpointParamDefinition[];
|
|
59
60
|
hasBody?: boolean;
|
|
61
|
+
eventStream?: boolean;
|
|
62
|
+
responseType?: string | null;
|
|
60
63
|
}
|
|
61
64
|
export type PluginEndpointParamDefinition = string | {
|
|
62
65
|
name: string;
|
|
@@ -141,7 +144,7 @@ export interface PluginEventStreamOptions<TData = string> {
|
|
|
141
144
|
reconnect?: boolean;
|
|
142
145
|
/** Delay before reconnecting after a stream failure or close. Defaults to 2000ms. */
|
|
143
146
|
reconnectDelayMs?: number;
|
|
144
|
-
/** Parse `data:` as JSON
|
|
147
|
+
/** Parse `data:` as JSON. Defaults to true for typed endpoints and false otherwise. */
|
|
145
148
|
parseJson?: boolean;
|
|
146
149
|
/** Fetch credentials mode. Defaults to same-origin. */
|
|
147
150
|
credentials?: RequestCredentials;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { D as currentExperimentFromContext, O as getInjectedPlatformContext, k as resolveCurrentExperimentId } from "./useJobsStatusTray-DAH999_N.js";
|
|
2
2
|
import { r as useSettingsStore, t as useAuthStore } from "./auth-DZAwEeis.js";
|
|
3
3
|
import { i as usePlatformContext } from "./useFormBuilder-DKekvXRs.js";
|
|
4
4
|
import { i as useApi, r as useRequestSyncState } from "./useExperimentSelector-DdCy5VNv.js";
|
|
@@ -1624,80 +1624,113 @@ function usePluginEventStream(contract, endpoint, payloadOrOptions, maybeOptions
|
|
|
1624
1624
|
const error = ref(null);
|
|
1625
1625
|
const lastMessage = shallowRef(null);
|
|
1626
1626
|
const lastEventId = ref(null);
|
|
1627
|
+
const responseType = endpoint.responseType?.trim();
|
|
1628
|
+
const parseJson = options.parseJson ?? Boolean(responseType && responseType !== "string");
|
|
1627
1629
|
let controller = null;
|
|
1628
1630
|
let reconnectTimer = null;
|
|
1629
1631
|
let stopped = true;
|
|
1632
|
+
let generation = 0;
|
|
1630
1633
|
function clearReconnectTimer() {
|
|
1631
1634
|
if (reconnectTimer !== null) {
|
|
1632
1635
|
clearTimeout(reconnectTimer);
|
|
1633
1636
|
reconnectTimer = null;
|
|
1634
1637
|
}
|
|
1635
1638
|
}
|
|
1636
|
-
function
|
|
1637
|
-
|
|
1639
|
+
function ownsConnection(connectionGeneration, connectionController) {
|
|
1640
|
+
return !stopped && generation === connectionGeneration && controller === connectionController;
|
|
1641
|
+
}
|
|
1642
|
+
function scheduleReconnect(connectionGeneration) {
|
|
1643
|
+
if (stopped || generation !== connectionGeneration || options.reconnect === false) return;
|
|
1638
1644
|
clearReconnectTimer();
|
|
1639
1645
|
reconnectTimer = setTimeout(() => {
|
|
1640
|
-
|
|
1646
|
+
reconnectTimer = null;
|
|
1647
|
+
if (stopped || generation !== connectionGeneration) return;
|
|
1648
|
+
connect(connectionGeneration);
|
|
1641
1649
|
}, options.reconnectDelayMs ?? 2e3);
|
|
1642
1650
|
}
|
|
1643
|
-
async function connect() {
|
|
1651
|
+
async function connect(connectionGeneration) {
|
|
1652
|
+
if (stopped || generation !== connectionGeneration) return;
|
|
1644
1653
|
if (endpoint.method !== "get") throw new Error(`[MINT SDK] Plugin event streams must use GET; got ${endpoint.method}`);
|
|
1645
1654
|
if (typeof fetch !== "function") throw new Error("[MINT SDK] fetch is required for plugin event streams.");
|
|
1646
1655
|
controller?.abort();
|
|
1647
|
-
|
|
1656
|
+
const connectionController = new AbortController();
|
|
1657
|
+
controller = connectionController;
|
|
1648
1658
|
isConnecting.value = true;
|
|
1659
|
+
if (!ownsConnection(connectionGeneration, connectionController)) return;
|
|
1649
1660
|
error.value = null;
|
|
1661
|
+
if (!ownsConnection(connectionGeneration, connectionController)) return;
|
|
1650
1662
|
try {
|
|
1651
1663
|
const url = buildPluginEndpointUrl(contract, endpoint, payload, { baseUrl: options.baseUrl });
|
|
1652
1664
|
const response = await fetch(url, {
|
|
1653
1665
|
method: "GET",
|
|
1654
1666
|
headers: streamHeaders(options),
|
|
1655
1667
|
credentials: options.credentials ?? "same-origin",
|
|
1656
|
-
signal:
|
|
1668
|
+
signal: connectionController.signal
|
|
1657
1669
|
});
|
|
1670
|
+
if (!ownsConnection(connectionGeneration, connectionController)) return;
|
|
1658
1671
|
if (!response.ok) throw new Error(`Plugin event stream failed with HTTP ${response.status}`);
|
|
1659
1672
|
if (!response.body) throw new Error("Plugin event stream response did not include a readable body.");
|
|
1660
|
-
options.onOpen?.();
|
|
1661
1673
|
isConnected.value = true;
|
|
1674
|
+
if (!ownsConnection(connectionGeneration, connectionController)) return;
|
|
1675
|
+
options.onOpen?.();
|
|
1676
|
+
if (!ownsConnection(connectionGeneration, connectionController)) return;
|
|
1662
1677
|
const reader = response.body.getReader();
|
|
1663
1678
|
const decoder = new TextDecoder();
|
|
1664
1679
|
let buffer = "";
|
|
1665
1680
|
for (;;) {
|
|
1666
1681
|
const { value, done } = await reader.read();
|
|
1682
|
+
if (!ownsConnection(connectionGeneration, connectionController)) return;
|
|
1667
1683
|
if (done) break;
|
|
1668
1684
|
buffer += decoder.decode(value, { stream: true });
|
|
1669
1685
|
let boundary = buffer.search(/\r?\n\r?\n/);
|
|
1670
1686
|
while (boundary !== -1) {
|
|
1671
1687
|
const block = buffer.slice(0, boundary);
|
|
1672
1688
|
buffer = buffer.slice(buffer[boundary] === "\r" ? boundary + 4 : boundary + 2);
|
|
1673
|
-
const message = parseSseEvent(block,
|
|
1689
|
+
const message = parseSseEvent(block, parseJson);
|
|
1674
1690
|
if (message) {
|
|
1675
1691
|
lastMessage.value = message;
|
|
1676
|
-
if (
|
|
1692
|
+
if (!ownsConnection(connectionGeneration, connectionController)) return;
|
|
1693
|
+
if (message.id !== void 0) {
|
|
1694
|
+
lastEventId.value = message.id;
|
|
1695
|
+
if (!ownsConnection(connectionGeneration, connectionController)) return;
|
|
1696
|
+
}
|
|
1677
1697
|
if (message.retry !== void 0) options.reconnectDelayMs = message.retry;
|
|
1698
|
+
if (!ownsConnection(connectionGeneration, connectionController)) return;
|
|
1678
1699
|
options.onMessage?.(message);
|
|
1700
|
+
if (!ownsConnection(connectionGeneration, connectionController)) return;
|
|
1679
1701
|
}
|
|
1680
1702
|
boundary = buffer.search(/\r?\n\r?\n/);
|
|
1681
1703
|
}
|
|
1682
1704
|
}
|
|
1683
1705
|
} catch (err) {
|
|
1684
|
-
if (
|
|
1706
|
+
if (ownsConnection(connectionGeneration, connectionController) && !(err instanceof DOMException && err.name === "AbortError")) {
|
|
1685
1707
|
error.value = err instanceof Error ? err.message : "Plugin event stream failed";
|
|
1686
|
-
options.onError?.(err);
|
|
1708
|
+
if (ownsConnection(connectionGeneration, connectionController)) options.onError?.(err);
|
|
1687
1709
|
}
|
|
1688
1710
|
} finally {
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1711
|
+
if (ownsConnection(connectionGeneration, connectionController)) {
|
|
1712
|
+
isConnecting.value = false;
|
|
1713
|
+
if (ownsConnection(connectionGeneration, connectionController)) {
|
|
1714
|
+
isConnected.value = false;
|
|
1715
|
+
if (ownsConnection(connectionGeneration, connectionController)) {
|
|
1716
|
+
controller = null;
|
|
1717
|
+
scheduleReconnect(connectionGeneration);
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1692
1721
|
}
|
|
1693
1722
|
}
|
|
1694
1723
|
function start() {
|
|
1724
|
+
if (!stopped) return;
|
|
1695
1725
|
stopped = false;
|
|
1696
1726
|
clearReconnectTimer();
|
|
1697
|
-
|
|
1727
|
+
generation += 1;
|
|
1728
|
+
connect(generation);
|
|
1698
1729
|
}
|
|
1699
1730
|
function stop() {
|
|
1731
|
+
if (stopped) return;
|
|
1700
1732
|
stopped = true;
|
|
1733
|
+
generation += 1;
|
|
1701
1734
|
clearReconnectTimer();
|
|
1702
1735
|
controller?.abort();
|
|
1703
1736
|
controller = null;
|
|
@@ -1777,4 +1810,4 @@ function useCurrentExperiment(options = {}) {
|
|
|
1777
1810
|
//#endregion
|
|
1778
1811
|
export { usePasskey as A, createPluginResourceClient as C, usePluginConfig as D, useCommandHistory as E, useAsync as O, wellIdsInRectangle as S, useOptimisticMutation as T, createWellPlateWells as _, pluginFormDataFromPayload as a, useWellPainting as b, usePluginClient as c, buildPluginEndpointUrl as d, resolvePluginBaseUrl as f, createRowConditions as g, createColumnConditions as h, getPluginPageSelectorItems as i, useAuth as j, useAsyncBatch as k, usePluginEventStream as l, useWellPlateValidation as m, downloadBlob as n, uploadPluginEndpoint as o, runWellPlateValidation as p, downloadPluginEndpoint as r, useCurrentExperiment as s, createPluginClient as t, usePluginSettings as u, useWellPlateAdapter as v, useResourceCrud as w, wellIdToCoordinate as x, coordinateToWellId as y };
|
|
1779
1812
|
|
|
1780
|
-
//# sourceMappingURL=composables-
|
|
1813
|
+
//# sourceMappingURL=composables-DyfGpYZw.js.map
|