@morscherlab/mint-sdk 1.1.24 → 1.2.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 (74) hide show
  1. package/README.md +9 -7
  2. package/dist/{ExperimentSelectorModal-B6P2msT4.js → ExperimentSelectorModal-DyPAUCLw.js} +3 -3
  3. package/dist/{ExperimentSelectorModal-B6P2msT4.js.map → ExperimentSelectorModal-DyPAUCLw.js.map} +1 -1
  4. package/dist/{SettingsModal-DoS2fzyz.js → SettingsModal-BgKY93zh.js} +5 -4
  5. package/dist/SettingsModal-BgKY93zh.js.map +1 -0
  6. package/dist/__tests__/composables/useEventStream.test.d.ts +1 -0
  7. package/dist/components/AutoGroupModal.vue.d.ts +1 -1
  8. package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +1 -1
  9. package/dist/components/JobsStatusTray.vue.d.ts +29 -10
  10. package/dist/components/SampleLegend.vue.d.ts +1 -1
  11. package/dist/components/SampleSelector.vue.d.ts +1 -1
  12. package/dist/components/SettingsModal.vue.d.ts +1 -1
  13. package/dist/components/SmartGroupFieldRecipe.vue.d.ts +1 -1
  14. package/dist/components/index.js +4 -4
  15. package/dist/{components-CW3hE1T3.js → components-DkHddRMl.js} +39 -40
  16. package/dist/components-DkHddRMl.js.map +1 -0
  17. package/dist/composables/index.d.ts +2 -3
  18. package/dist/composables/index.js +8 -8
  19. package/dist/composables/useEventStream.d.ts +43 -0
  20. package/dist/composables/useGeneratedAnalysis.d.ts +1 -3
  21. package/dist/composables/useJobsStatusTray.d.ts +1 -25
  22. package/dist/composables/usePluginClient.d.ts +3 -18
  23. package/dist/{composables-CkXDe7nm.js → composables-C_i90sGS.js} +32 -308
  24. package/dist/composables-C_i90sGS.js.map +1 -0
  25. package/dist/{experiment-Y9Iz7KYi.js → experiment-Cq145oEW.js} +2 -2
  26. package/dist/{experiment-Y9Iz7KYi.js.map → experiment-Cq145oEW.js.map} +1 -1
  27. package/dist/index.js +12 -12
  28. package/dist/install.js +4 -4
  29. package/dist/stores/auth.d.ts +0 -6
  30. package/dist/stores/index.js +2 -2
  31. package/dist/templates/index.js +2 -2
  32. package/dist/{templates-CovvRZ-9.js → templates-DsP51i-S.js} +2 -2
  33. package/dist/{templates-CovvRZ-9.js.map → templates-DsP51i-S.js.map} +1 -1
  34. package/dist/types/auth.d.ts +0 -1
  35. package/dist/{useApi-CDBq6z23.js → useApi-J6zFkHmn.js} +1 -2
  36. package/dist/useApi-J6zFkHmn.js.map +1 -0
  37. package/dist/{useControlSchema-BhoJzWzx.js → useControlSchema-BDx2Olha.js} +239 -103
  38. package/dist/useControlSchema-BDx2Olha.js.map +1 -0
  39. package/dist/{useExperimentSelector-D0pjj9WH.js → useExperimentSelector-CV4iNfMS.js} +2 -2
  40. package/dist/{useExperimentSelector-D0pjj9WH.js.map → useExperimentSelector-CV4iNfMS.js.map} +1 -1
  41. package/dist/{useFormBuilder-DiEcDis2.js → useFormBuilder-BLxG3BOX.js} +2 -2
  42. package/dist/{useFormBuilder-DiEcDis2.js.map → useFormBuilder-BLxG3BOX.js.map} +1 -1
  43. package/dist/{useProtocolTemplates-DHwSveE6.js → useProtocolTemplates-CS_SQl6U.js} +22 -113
  44. package/dist/useProtocolTemplates-CS_SQl6U.js.map +1 -0
  45. package/package.json +1 -1
  46. package/src/__tests__/components/GeneratedPluginView.test.ts +0 -5
  47. package/src/__tests__/components/JobsStatusTray.test.ts +43 -19
  48. package/src/__tests__/composables/useAuth.test.ts +23 -0
  49. package/src/__tests__/composables/useEventStream.test.ts +140 -0
  50. package/src/__tests__/composables/useGeneratedAnalysis.test.ts +103 -0
  51. package/src/__tests__/composables/useJobsStatusTray.test.ts +25 -161
  52. package/src/__tests__/composables/usePluginClient.test.ts +8 -13
  53. package/src/__tests__/docs/frontendDocsCatalog.test.ts +22 -1
  54. package/src/components/JobsStatusTray.story.vue +16 -10
  55. package/src/components/JobsStatusTray.vue +22 -28
  56. package/src/components/SettingsModal.schema.ts +3 -0
  57. package/src/composables/index.ts +0 -7
  58. package/src/composables/useAuth.ts +0 -3
  59. package/src/composables/useEventStream.ts +314 -0
  60. package/src/composables/useGeneratedAnalysis.ts +40 -109
  61. package/src/composables/useJobsStatusTray.ts +17 -184
  62. package/src/composables/usePluginClient.ts +45 -249
  63. package/src/stores/auth.ts +0 -1
  64. package/src/types/auth.ts +0 -1
  65. package/dist/SettingsModal-DoS2fzyz.js.map +0 -1
  66. package/dist/__tests__/composables/usePluginConfig.test.d.ts +0 -15
  67. package/dist/components-CW3hE1T3.js.map +0 -1
  68. package/dist/composables/usePluginConfig.d.ts +0 -25
  69. package/dist/composables-CkXDe7nm.js.map +0 -1
  70. package/dist/useApi-CDBq6z23.js.map +0 -1
  71. package/dist/useControlSchema-BhoJzWzx.js.map +0 -1
  72. package/dist/useProtocolTemplates-DHwSveE6.js.map +0 -1
  73. package/src/__tests__/composables/usePluginConfig.test.ts +0 -497
  74. package/src/composables/usePluginConfig.ts +0 -250
@@ -25,7 +25,6 @@ export { useFormBuilder, evaluateCondition } from './useFormBuilder';
25
25
  export { createGeneratedAnalysisTransport, useGeneratedAnalysis, usePluginJobs, type GeneratedAnalysisTransport, type GeneratedAnalysisOptions, type PluginJobRequestOptions, type PluginJobWaitOptions, type UsePluginJobsOptions, type UsePluginJobsReturn, type UseGeneratedAnalysisReturn, } from './useGeneratedAnalysis';
26
26
  export { useAutoGroup, DEFAULT_COLORS, extractSamplesFromDesignData } from './useAutoGroup';
27
27
  export { useReagentSeries, generateDilutionSeries, DEFAULT_PRESETS, DEFAULT_UNITS, type LevelEntry, type DilutionPreset, type UseReagentSeriesReturn, } from './useReagentSeries';
28
- export { usePluginConfig, type UsePluginConfigReturn } from './usePluginConfig';
29
28
  export { useExperimentSelector, type UseExperimentSelectorOptions, type UseExperimentSelectorReturn, } from './useExperimentSelector';
30
29
  export { useAnalysisArtifacts, ANALYSIS_FILE_ARTIFACT_SCHEMA, type UseAnalysisArtifactsOptions, type UseAnalysisArtifactsReturn, } from './useAnalysisArtifacts';
31
30
  export { buildAnalysisArtifactTargetQuery, parseAnalysisArtifactTarget, } from './analysisArtifactTarget';
@@ -59,5 +58,5 @@ export { getBioTemplateComponentProps, getBioTemplateComponentBindings, toBioTem
59
58
  export { useBioTemplateWorkspace, type BioTemplateRendererBinding, type BioTemplateWorkspaceBindings, type BioTemplateWorkspaceTarget, type UseBioTemplateWorkspaceReturn, } from './useBioTemplateWorkspace';
60
59
  export { useBioTemplatePresetWorkspace, type BioTemplatePresetWorkspaceBindings, type UseBioTemplatePresetWorkspaceOptions, type UseBioTemplatePresetWorkspaceReturn, } from './useBioTemplatePresetWorkspace';
61
60
  export { useBioTemplatePackWorkspace, type UseBioTemplatePackWorkspaceOptions, type UseBioTemplatePackWorkspaceReturn, } from './useBioTemplatePackWorkspace';
62
- export { buildPluginEndpointUrl, createPluginClient, downloadBlob, downloadPluginEndpoint, getPluginPageSelectorItems, pluginFormDataFromPayload, resolvePluginBaseUrl, uploadPluginEndpoint, usePluginClient, usePluginEventStream, usePluginSettings, useCurrentExperiment, type BuildPluginEndpointUrlOptions, type DownloadBlobOptions, type DownloadPluginEndpointOptions, type PluginContract, type PluginContractSettings, type PluginClientRequestOptions, 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';
63
- export { combinePluginJobSources, usePluginJobCenter, useJobsStatusTray, type CombinedPluginJobCenterSource, type PluginJobCenterSource, type JobsStatusTrayAdapter, type JobsStatusTrayTab, type JobStreamMessage, type UsePluginJobCenterOptions, type UsePluginJobCenterReturn, type UseJobsStatusTrayOptions, type UseJobsStatusTrayReturn, } from './useJobsStatusTray';
61
+ export { buildPluginEndpointUrl, createPluginClient, downloadBlob, downloadPluginEndpoint, getPluginPageSelectorItems, pluginFormDataFromPayload, resolvePluginBaseUrl, uploadPluginEndpoint, usePluginEventStream, usePluginSettings, useCurrentExperiment, type BuildPluginEndpointUrlOptions, type DownloadBlobOptions, type DownloadPluginEndpointOptions, type PluginContract, type PluginContractSettings, type PluginClientRequestOptions, 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';
62
+ export { combinePluginJobSources, usePluginJobCenter, type CombinedPluginJobCenterSource, type PluginJobCenterSource, type JobsStatusTrayTab, type UsePluginJobCenterOptions, type UsePluginJobCenterReturn, } from './useJobsStatusTray';
@@ -1,11 +1,11 @@
1
1
  import { a as SORT_OPTIONS, c as formatExperimentDate, d as resolveExperimentCode, i as EXPERIMENT_STATUS_VARIANT_MAP, l as formatExperimentStatus, n as EXPERIMENT_STATUS_LABELS, o as datePresetToISO, p as useEventListener, r as EXPERIMENT_STATUS_OPTIONS, s as experimentIdFromRoute, t as DATE_PRESET_OPTIONS, u as getExperimentStatusVariant } from "../experiment-utils-CLnzPPq5.js";
2
2
  import { r as useRequestSyncState } from "../EmptyState-p90quq8Z.js";
3
- import { A as useConcentrationUnits, C as controlsToViewIds, D as getTypeDefault, E as getFieldRegistryEntry, Et as useSelectionLimit, F as ATOMIC_WEIGHTS, G as createGeneratedAnalysisTransport, I as useChemicalFormula, K as useGeneratedAnalysis, N as useSequenceUtils, S as controlsToTopBarSettingsConfig, St as useTimeUtils, T as getDefaultControlView, Tt as useListSelection, W as resolveCurrentPluginId, _ as controlsToFormSchema, _t as isTimeInRange, a as defineDoseCalculatorControlProps, b as controlsToSettingsSchema, bt as snapToSlot, c as defineWellPlateDoseComponentBindings, ct as compareTime, d as defineControlModel, dt as findNearestTimeSlotIndex, ft as formatDuration, gt as generateTimeSlots, h as controlValuesToComponentProps, ht as fromMinutes, i as useControlSchema, l as defineWellPlateDoseControlProps, lt as durationMinutes, m as controlValuesToComponentBindingsById, mt as formatTimeSlot, n as defineControls, o as defineDoseDesignControlModel, p as controlValuesToComponentBindings, pt as formatTime, q as usePluginJobs, r as getControlDefaults, s as defineWellPlateControlProps, st as addMinutes, t as defineControlComponentBindings, u as useControlWorkspace, ut as findAvailableSlots, v as controlsToSectionFormSchema, vt as parseTime, w as controlsToViewItems, x as controlsToSidebarPanels, xt as toMinutes, y as controlsToSectionFormSchemas, yt as rangesOverlap, z as useAnalysisArtifacts } from "../useControlSchema-BhoJzWzx.js";
4
- import { $ as useToast, A as useFileImport, B as useDoseCalculator, D as detectDelimiter, F as extractSampleNamesFromDesignData, G as useMobileSupportGate, H as useJobsStatusTray, I as extractSampleOptionsFromDesignData, J as getInjectedFrontendRevision, K as APP_EXPERIMENT_KEY, L as unwrapExperimentDesignData, M as extractSamplesFromDesignData, N as useAutoGroup, O as parseDelimitedText, Q as useTheme, R as DEFAULT_COLORS, U as usePluginJobCenter, V as combinePluginJobSources, W as DEFAULT_MOBILE_VIEWPORT_QUERY, X as getPresenceClientId, Y as useRuntimeAlignment, Z as usePresenceHeartbeat, _ as useScheduleDrag, a as useReagentSeries, b as useExpansionSet, c as useBioTemplatePresetWorkspace, d as getBioTemplateComponentProps, et as candidateMatchesSearch, f as toBioTemplateComponentPropsByComponent, g as useExperimentSave, h as useTemplateCollection, i as generateDilutionSeries, it as useSortedItems, j as validateImportFile, k as readFileAsText, l as useBioTemplatePackWorkspace, m as useBioTemplateControls, n as DEFAULT_PRESETS, nt as useTextSearch, o as useGroupAssignment, p as useBioTemplateComponents, q as useAppExperiment, r as DEFAULT_UNITS, rt as compareSortValues, s as useRackEditor, t as useProtocolTemplates, tt as normalizeSearchQuery, u as useBioTemplateWorkspace, v as useExperimentSamples, x as useSampleGroups, y as useExperimentData, z as useWellPlateEditor } from "../useProtocolTemplates-DHwSveE6.js";
5
- import { r as useApi, t as AuthenticationRequiredError } from "../useApi-CDBq6z23.js";
6
- import { i as usePlatformContext, n as evaluateCondition, r as useForm, t as useFormBuilder } from "../useFormBuilder-DiEcDis2.js";
3
+ import { A as useConcentrationUnits, C as controlsToViewIds, Ct as useTimeUtils, D as getTypeDefault, Dt as useSelectionLimit, E as getFieldRegistryEntry, Et as useListSelection, F as ATOMIC_WEIGHTS, G as createGeneratedAnalysisTransport, I as useChemicalFormula, K as useGeneratedAnalysis, N as useSequenceUtils, S as controlsToTopBarSettingsConfig, St as toMinutes, T as getDefaultControlView, W as resolveCurrentPluginId, _ as controlsToFormSchema, _t as generateTimeSlots, a as defineDoseCalculatorControlProps, b as controlsToSettingsSchema, bt as rangesOverlap, c as defineWellPlateDoseComponentBindings, ct as addMinutes, d as defineControlModel, dt as findAvailableSlots, ft as findNearestTimeSlotIndex, gt as fromMinutes, h as controlValuesToComponentProps, ht as formatTimeSlot, i as useControlSchema, l as defineWellPlateDoseControlProps, lt as compareTime, m as controlValuesToComponentBindingsById, mt as formatTime, n as defineControls, o as defineDoseDesignControlModel, p as controlValuesToComponentBindings, pt as formatDuration, q as usePluginJobs, r as getControlDefaults, s as defineWellPlateControlProps, t as defineControlComponentBindings, u as useControlWorkspace, ut as durationMinutes, v as controlsToSectionFormSchema, vt as isTimeInRange, w as controlsToViewItems, x as controlsToSidebarPanels, xt as snapToSlot, y as controlsToSectionFormSchemas, yt as parseTime, z as useAnalysisArtifacts } from "../useControlSchema-BDx2Olha.js";
4
+ import { $ as candidateMatchesSearch, A as useFileImport, B as useDoseCalculator, D as detectDelimiter, F as extractSampleNamesFromDesignData, G as APP_EXPERIMENT_KEY, H as usePluginJobCenter, I as extractSampleOptionsFromDesignData, J as useRuntimeAlignment, K as useAppExperiment, L as unwrapExperimentDesignData, M as extractSamplesFromDesignData, N as useAutoGroup, O as parseDelimitedText, Q as useToast, R as DEFAULT_COLORS, U as DEFAULT_MOBILE_VIEWPORT_QUERY, V as combinePluginJobSources, W as useMobileSupportGate, X as usePresenceHeartbeat, Y as getPresenceClientId, Z as useTheme, _ as useScheduleDrag, a as useReagentSeries, b as useExpansionSet, c as useBioTemplatePresetWorkspace, d as getBioTemplateComponentProps, et as normalizeSearchQuery, f as toBioTemplateComponentPropsByComponent, g as useExperimentSave, h as useTemplateCollection, i as generateDilutionSeries, j as validateImportFile, k as readFileAsText, l as useBioTemplatePackWorkspace, m as useBioTemplateControls, n as DEFAULT_PRESETS, nt as compareSortValues, o as useGroupAssignment, p as useBioTemplateComponents, q as getInjectedFrontendRevision, r as DEFAULT_UNITS, rt as useSortedItems, s as useRackEditor, t as useProtocolTemplates, tt as useTextSearch, u as useBioTemplateWorkspace, v as useExperimentSamples, x as useSampleGroups, y as useExperimentData, z as useWellPlateEditor } from "../useProtocolTemplates-CS_SQl6U.js";
5
+ import { r as useApi, t as AuthenticationRequiredError } from "../useApi-J6zFkHmn.js";
6
+ import { i as usePlatformContext, n as evaluateCondition, r as useForm, t as useFormBuilder } from "../useFormBuilder-BLxG3BOX.js";
7
7
  import { t as ANALYSIS_FILE_ARTIFACT_SCHEMA } from "../analysisArtifactTypes-DQ0MjwHZ.js";
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-CovvRZ-9.js";
9
- import { n as useDebouncedWatch, t as useExperimentSelector } from "../useExperimentSelector-D0pjj9WH.js";
10
- import { A as useAsync, C as createPluginResourceClient, D as buildAnalysisArtifactTargetQuery, E as useCommandHistory, M as resolvePluginFrontendBase, N as usePasskey, O as parseAnalysisArtifactTarget, P as useAuth, 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 useAsyncBatch, k as usePluginConfig, 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-CkXDe7nm.js";
11
- export { ANALYSIS_FILE_ARTIFACT_SCHEMA, APP_EXPERIMENT_KEY, ATOMIC_WEIGHTS, AuthenticationRequiredError, 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, buildAnalysisArtifactTargetQuery, buildPluginEndpointUrl, candidateMatchesSearch, combinePluginJobSources, compareSortValues, compareTime, controlValuesToComponentBindings, controlValuesToComponentBindingsById, controlValuesToComponentProps, controlsToFormSchema, controlsToSectionFormSchema, controlsToSectionFormSchemas, controlsToSettingsSchema, controlsToSidebarPanels, controlsToTopBarSettingsConfig, controlsToViewIds, controlsToViewItems, coordinateToWellId, createColumnConditions, createGeneratedAnalysisTransport, createPluginClient, createPluginResourceClient, createRowConditions, createWellPlateWells, datePresetToISO, defineControlComponentBindings, defineControlModel, defineControls, defineDoseCalculatorControlProps, defineDoseDesignControlModel, defineWellPlateControlProps, defineWellPlateDoseComponentBindings, defineWellPlateDoseControlProps, detectDelimiter, downloadBlob, downloadPluginEndpoint, durationMinutes, evaluateCondition, experimentIdFromRoute, extractSampleNamesFromDesignData, extractSampleOptionsFromDesignData, extractSamplesFromDesignData, findAvailableSlots, findNearestTimeSlotIndex, formatDuration, formatExperimentDate, formatExperimentStatus, formatTime, formatTimeSlot, fromMinutes, generateDilutionSeries, generateTimeSlots, getBioTemplateComponentBindings, getBioTemplateComponentProps, getBioTemplateControlSchema, getControlDefaults, getDefaultControlView, getExperimentStatusVariant, getFieldRegistryEntry, getInjectedFrontendRevision, getPluginPageSelectorItems, getPresenceClientId, getTypeDefault, isTimeInRange, normalizeSearchQuery, parseAnalysisArtifactTarget, parseDelimitedText, parseTime, pluginFormDataFromPayload, rangesOverlap, readFileAsText, requireBioTemplateControlSchema, resolveCurrentPluginId, resolveExperimentCode, resolvePluginBaseUrl, resolvePluginFrontendBase, runWellPlateValidation, snapToSlot, toBioTemplateComponentBindings, toBioTemplateComponentBindingsById, toBioTemplateComponentProps, toBioTemplateComponentPropsByComponent, toBioTemplateComponentPropsById, toMinutes, unwrapExperimentDesignData, uploadPluginEndpoint, useAnalysisArtifacts, 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, useGeneratedAnalysis, useGroupAssignment, useJobsStatusTray, useListSelection, useMobileSupportGate, useOptimisticMutation, usePasskey, usePlatformContext, usePluginClient, usePluginConfig, usePluginEventStream, usePluginJobCenter, usePluginJobs, usePluginSettings, usePresenceHeartbeat, useProtocolTemplates, useRackEditor, useReagentSeries, useRequestSyncState, useResourceCrud, useRuntimeAlignment, useSampleGroups, useScheduleDrag, useSelectionLimit, useSequenceUtils, useSortedItems, useTemplateCollection, useTextSearch, useTheme, useTimeUtils, useToast, useWellPainting, useWellPlateAdapter, useWellPlateEditor, useWellPlateValidation, validateImportFile, wellIdToCoordinate, wellIdsInRectangle };
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-DsP51i-S.js";
9
+ import { n as useDebouncedWatch, t as useExperimentSelector } from "../useExperimentSelector-CV4iNfMS.js";
10
+ import { A as resolvePluginFrontendBase, C as useResourceCrud, D as parseAnalysisArtifactTarget, E as buildAnalysisArtifactTargetQuery, M as useAuth, O as useAsync, S as createPluginResourceClient, T as useCommandHistory, _ as useWellPlateAdapter, a as pluginFormDataFromPayload, b as wellIdToCoordinate, c as usePluginEventStream, d as resolvePluginBaseUrl, f as runWellPlateValidation, g as createWellPlateWells, h as createRowConditions, i as getPluginPageSelectorItems, j as usePasskey, k as useAsyncBatch, l as usePluginSettings, m as createColumnConditions, n as downloadBlob, o as uploadPluginEndpoint, p as useWellPlateValidation, r as downloadPluginEndpoint, s as useCurrentExperiment, t as createPluginClient, u as buildPluginEndpointUrl, v as coordinateToWellId, w as useOptimisticMutation, x as wellIdsInRectangle, y as useWellPainting } from "../composables-C_i90sGS.js";
11
+ export { ANALYSIS_FILE_ARTIFACT_SCHEMA, APP_EXPERIMENT_KEY, ATOMIC_WEIGHTS, AuthenticationRequiredError, 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, buildAnalysisArtifactTargetQuery, buildPluginEndpointUrl, candidateMatchesSearch, combinePluginJobSources, compareSortValues, compareTime, controlValuesToComponentBindings, controlValuesToComponentBindingsById, controlValuesToComponentProps, controlsToFormSchema, controlsToSectionFormSchema, controlsToSectionFormSchemas, controlsToSettingsSchema, controlsToSidebarPanels, controlsToTopBarSettingsConfig, controlsToViewIds, controlsToViewItems, coordinateToWellId, createColumnConditions, createGeneratedAnalysisTransport, createPluginClient, createPluginResourceClient, createRowConditions, createWellPlateWells, datePresetToISO, defineControlComponentBindings, defineControlModel, defineControls, defineDoseCalculatorControlProps, defineDoseDesignControlModel, defineWellPlateControlProps, defineWellPlateDoseComponentBindings, defineWellPlateDoseControlProps, detectDelimiter, downloadBlob, downloadPluginEndpoint, durationMinutes, evaluateCondition, experimentIdFromRoute, extractSampleNamesFromDesignData, extractSampleOptionsFromDesignData, extractSamplesFromDesignData, findAvailableSlots, findNearestTimeSlotIndex, formatDuration, formatExperimentDate, formatExperimentStatus, formatTime, formatTimeSlot, fromMinutes, generateDilutionSeries, generateTimeSlots, getBioTemplateComponentBindings, getBioTemplateComponentProps, getBioTemplateControlSchema, getControlDefaults, getDefaultControlView, getExperimentStatusVariant, getFieldRegistryEntry, getInjectedFrontendRevision, getPluginPageSelectorItems, getPresenceClientId, getTypeDefault, isTimeInRange, normalizeSearchQuery, parseAnalysisArtifactTarget, parseDelimitedText, parseTime, pluginFormDataFromPayload, rangesOverlap, readFileAsText, requireBioTemplateControlSchema, resolveCurrentPluginId, resolveExperimentCode, resolvePluginBaseUrl, resolvePluginFrontendBase, runWellPlateValidation, snapToSlot, toBioTemplateComponentBindings, toBioTemplateComponentBindingsById, toBioTemplateComponentProps, toBioTemplateComponentPropsByComponent, toBioTemplateComponentPropsById, toMinutes, unwrapExperimentDesignData, uploadPluginEndpoint, useAnalysisArtifacts, 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, useGeneratedAnalysis, useGroupAssignment, useListSelection, useMobileSupportGate, useOptimisticMutation, usePasskey, usePlatformContext, usePluginEventStream, usePluginJobCenter, usePluginJobs, usePluginSettings, usePresenceHeartbeat, useProtocolTemplates, useRackEditor, useReagentSeries, useRequestSyncState, useResourceCrud, useRuntimeAlignment, useSampleGroups, useScheduleDrag, useSelectionLimit, useSequenceUtils, useSortedItems, useTemplateCollection, useTextSearch, useTheme, useTimeUtils, useToast, useWellPainting, useWellPlateAdapter, useWellPlateEditor, useWellPlateValidation, validateImportFile, wellIdToCoordinate, wellIdsInRectangle };
@@ -0,0 +1,43 @@
1
+ import { Ref } from 'vue';
2
+ export type EventStreamTransport = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
3
+ export interface EventStreamMessage<TData = string> {
4
+ event: string;
5
+ data: TData;
6
+ id?: string;
7
+ retry?: number;
8
+ raw: string;
9
+ }
10
+ export interface EventStreamOptions<TData = string> {
11
+ transport?: EventStreamTransport;
12
+ headers?: HeadersInit;
13
+ credentials?: RequestCredentials;
14
+ immediate?: boolean;
15
+ reconnect?: boolean;
16
+ reconnectDelayMs?: number;
17
+ parseJson?: boolean;
18
+ shouldReconnect?: (cause?: unknown) => boolean;
19
+ onOpen?: () => void;
20
+ onMessage?: (message: EventStreamMessage<TData>) => void;
21
+ onError?: (cause: unknown) => void;
22
+ onClose?: (cause?: unknown) => void;
23
+ errorLabel?: string;
24
+ }
25
+ export interface UseEventStreamReturn<TData = string> {
26
+ isConnected: Ref<boolean>;
27
+ isConnecting: Ref<boolean>;
28
+ error: Ref<string | null>;
29
+ lastMessage: Ref<EventStreamMessage<TData> | null>;
30
+ lastEventId: Ref<string | null>;
31
+ start: () => void;
32
+ stop: () => void;
33
+ }
34
+ interface ParsedEventStreamBlock<TData> {
35
+ message?: EventStreamMessage<TData>;
36
+ id?: string;
37
+ retry?: number;
38
+ }
39
+ /** Parse one complete SSE block without owning connection policy. */
40
+ export declare function parseEventStreamBlock<TData>(block: string, parseJson: boolean): ParsedEventStreamBlock<TData> | null;
41
+ /** Shared fetch-based SSE lifecycle with cancellation and reconnect safety. */
42
+ export declare function useEventStream<TData = string>(url: string | (() => string), options?: EventStreamOptions<TData>): UseEventStreamReturn<TData>;
43
+ export {};
@@ -1,5 +1,5 @@
1
1
  import { ComputedRef, Ref, ShallowRef } from 'vue';
2
- import { JobsStatusTrayAdapter, PluginJobCenterSource } from './useJobsStatusTray';
2
+ import { PluginJobCenterSource } from './useJobsStatusTray';
3
3
  import { GeneratedAnalysisJob, GeneratedAnalysisResult, GeneratedSession, GeneratedAnalysisManifest, PluginJobPathInput, PluginJobPathUpload, PluginJobStagedPartInput, PluginJobStagedPartUploadResult, PluginJobStaging, PluginJobStagingPagination } from '../types/generated-ui';
4
4
  export type GeneratedAnalysisTransport = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
5
5
  export interface GeneratedAnalysisTransportOptions {
@@ -53,8 +53,6 @@ export interface UsePluginJobsReturn extends PluginJobCenterSource {
53
53
  pause: () => void;
54
54
  resume: () => void;
55
55
  dispose: () => void;
56
- /** @deprecated Pass the runtime itself to SDK job UI as its source. */
57
- jobsAdapter: JobsStatusTrayAdapter;
58
56
  }
59
57
  export type UseGeneratedAnalysisReturn = UsePluginJobsReturn;
60
58
  export declare function createGeneratedAnalysisTransport(options?: GeneratedAnalysisTransportOptions): GeneratedAnalysisTransport;
@@ -1,6 +1,5 @@
1
1
  import { ComputedRef, MaybeRefOrGetter, Ref, ShallowRef } from 'vue';
2
- import { JobListPayload, JobState, JobStateInput, JobStreamData } from '../types/jobs';
3
- import { UsePluginEventStreamReturn } from './usePluginClient';
2
+ import { JobListPayload, JobState, JobStateInput } from '../types/jobs';
4
3
  export type JobsStatusTrayTab = 'active' | 'history';
5
4
  /**
6
5
  * The canonical owner of a collection of plugin jobs.
@@ -27,29 +26,10 @@ export interface CombinedPluginJobCenterSource extends PluginJobCenterSource {
27
26
  * dispatching a mutation to the wrong owner.
28
27
  */
29
28
  export declare function combinePluginJobSources(sources: readonly PluginJobCenterSource[]): CombinedPluginJobCenterSource;
30
- /** @deprecated Prefer a {@link PluginJobCenterSource}. */
31
- export interface JobsStatusTrayAdapter {
32
- listJobs?: () => Promise<JobListPayload | readonly JobStateInput[]>;
33
- cancelJob?: (job: JobState) => Promise<JobStateInput | void>;
34
- deleteJob?: (job: JobState) => Promise<boolean | void>;
35
- clearFinishedJobs?: (jobs: readonly JobState[]) => Promise<number | void>;
36
- }
37
29
  export interface UsePluginJobCenterOptions {
38
30
  source?: MaybeRefOrGetter<PluginJobCenterSource | undefined>;
39
- /** @deprecated Pass a source with its canonical jobs ref. */
40
- jobs?: MaybeRefOrGetter<readonly JobStateInput[] | undefined>;
41
- /** @deprecated Pass source actions instead. */
42
- adapter?: MaybeRefOrGetter<JobsStatusTrayAdapter | undefined>;
43
- /** @deprecated Event handling belongs to the source runtime. */
44
- eventStream?: MaybeRefOrGetter<UsePluginEventStreamReturn<JobStreamData> | undefined>;
45
31
  loadOnMount?: boolean;
46
32
  }
47
- export interface UseJobsStatusTrayOptions extends UsePluginJobCenterOptions {
48
- }
49
- export interface JobStreamMessage {
50
- event: string;
51
- data: JobStreamData;
52
- }
53
33
  export interface UsePluginJobCenterReturn {
54
34
  jobs: ComputedRef<JobState[]>;
55
35
  activeJobs: ComputedRef<JobState[]>;
@@ -69,13 +49,11 @@ export interface UsePluginJobCenterReturn {
69
49
  close: () => void;
70
50
  toggle: () => void;
71
51
  refresh: () => Promise<boolean>;
72
- applyStreamMessage: (message: JobStreamMessage) => void;
73
52
  cancelJob: (job: JobState) => Promise<boolean>;
74
53
  deleteJob: (job: JobState) => Promise<boolean>;
75
54
  clearFinished: () => Promise<boolean>;
76
55
  isPending: (job: JobState) => boolean;
77
56
  }
78
- export type UseJobsStatusTrayReturn = UsePluginJobCenterReturn;
79
57
  /**
80
58
  * Headless controller for plugin job presentation and actions.
81
59
  *
@@ -83,5 +61,3 @@ export type UseJobsStatusTrayReturn = UsePluginJobCenterReturn;
83
61
  * source. The controller never mirrors source jobs into another ref.
84
62
  */
85
63
  export declare function usePluginJobCenter(options?: UsePluginJobCenterOptions): UsePluginJobCenterReturn;
86
- /** Backward-compatible name for the plugin job-center controller. */
87
- export declare function useJobsStatusTray(options?: UseJobsStatusTrayOptions): UseJobsStatusTrayReturn;
@@ -1,4 +1,5 @@
1
1
  import { ComputedRef, Ref } from 'vue';
2
+ import { EventStreamMessage, UseEventStreamReturn } from './useEventStream';
2
3
  import { ExperimentSummary, GeneratedJobDefinition, PageSelectorItem, SettingsModalSchema, TopBarSettingsConfig } from '../types';
3
4
  export { buildPluginEndpointUrl, resolvePluginBaseUrl, } from './pluginEndpointBuilder';
4
5
  export type PluginHttpMethod = 'get' | 'post' | 'put' | 'patch' | 'delete';
@@ -147,13 +148,7 @@ export interface UsePluginSettingsReturn<TSettings = Record<string, unknown>> {
147
148
  save: (values?: Record<string, unknown>) => Promise<boolean>;
148
149
  reset: () => void;
149
150
  }
150
- export interface PluginEventStreamMessage<TData = string> {
151
- event: string;
152
- data: TData;
153
- id?: string;
154
- retry?: number;
155
- raw: string;
156
- }
151
+ export type PluginEventStreamMessage<TData = string> = EventStreamMessage<TData>;
157
152
  export interface PluginEventStreamOptions<TData = string> {
158
153
  /** Override the generated or platform-injected API base URL. */
159
154
  baseUrl?: string;
@@ -173,15 +168,7 @@ export interface PluginEventStreamOptions<TData = string> {
173
168
  onMessage?: (message: PluginEventStreamMessage<TData>) => void;
174
169
  onError?: (error: unknown) => void;
175
170
  }
176
- export interface UsePluginEventStreamReturn<TData = string> {
177
- isConnected: Ref<boolean>;
178
- isConnecting: Ref<boolean>;
179
- error: Ref<string | null>;
180
- lastMessage: Ref<PluginEventStreamMessage<TData> | null>;
181
- lastEventId: Ref<string | null>;
182
- start: () => void;
183
- stop: () => void;
184
- }
171
+ export type UsePluginEventStreamReturn<TData = string> = UseEventStreamReturn<TData>;
185
172
  export type PluginFormDataValue = string | number | boolean | Blob | null | undefined | Record<string, unknown>;
186
173
  export type PluginFormDataPayload = Record<string, PluginFormDataValue | PluginFormDataValue[]>;
187
174
  export interface UseCurrentExperimentOptions {
@@ -222,8 +209,6 @@ export declare function createPluginClient<TClient extends object = GeneratedPlu
222
209
  export declare function uploadPluginEndpoint<TResponse = unknown>(contract: PluginContract, endpoint: PluginEndpointDefinition, payload?: unknown, options?: PluginEndpointRequestOptions): Promise<TResponse>;
223
210
  /** Fetch a generated plugin endpoint as a Blob and optionally trigger a browser download. */
224
211
  export declare function downloadPluginEndpoint(contract: PluginContract, endpoint: PluginEndpointDefinition, payload?: unknown, options?: DownloadPluginEndpointOptions): Promise<Blob>;
225
- /** Return a generated plugin client from setup code with a stable typed identity. */
226
- export declare function usePluginClient<TClient>(client: TClient): TClient;
227
212
  /** Load, edit, and persist plugin settings from platform config or the plugin-local settings router. */
228
213
  export declare function usePluginSettings<TSettings = Record<string, unknown>>(options?: UsePluginSettingsOptions | string): UsePluginSettingsReturn<TSettings>;
229
214
  /** Consume a generated plugin SSE endpoint with auth headers, reconnect, and teardown. */
@@ -1,7 +1,7 @@
1
1
  import { r as useRequestSyncState } from "./EmptyState-p90quq8Z.js";
2
- import { B as currentExperimentFromContext, U as resolveCurrentExperimentId, V as getInjectedPlatformContext } from "./useControlSchema-BhoJzWzx.js";
3
- import { i as useAuthStore, n as authenticationRequiredError, o as useSettingsStore, r as useApi, t as AuthenticationRequiredError } from "./useApi-CDBq6z23.js";
4
- import { i as usePlatformContext } from "./useFormBuilder-DiEcDis2.js";
2
+ import { B as currentExperimentFromContext, U as resolveCurrentExperimentId, V as getInjectedPlatformContext, et as useEventStream } from "./useControlSchema-BDx2Olha.js";
3
+ import { i as useAuthStore, n as authenticationRequiredError, o as useSettingsStore, r as useApi, t as AuthenticationRequiredError } from "./useApi-J6zFkHmn.js";
4
+ import { i as usePlatformContext } from "./useFormBuilder-BLxG3BOX.js";
5
5
  import { computed, getCurrentInstance, onMounted, onUnmounted, ref, shallowRef, toValue, watch } from "vue";
6
6
  import axios from "axios";
7
7
  //#region src/composables/useAuth.ts
@@ -26,7 +26,6 @@ function useAuth() {
26
26
  passkeyEnabled: response.data.passkey_enabled,
27
27
  passkeyRegistered: response.data.passkey_registered ?? false,
28
28
  registrationEnabled: response.data.registration_enabled ?? false,
29
- databaseMode: response.data.database_mode ?? "none",
30
29
  experimentVisibilityMode: response.data.access?.experiment_visibility_mode ?? response.data.access?.experimentVisibilityMode ?? "open"
31
30
  };
32
31
  authStore.setAuthConfig(config);
@@ -38,7 +37,6 @@ function useAuth() {
38
37
  passkeyEnabled: false,
39
38
  passkeyRegistered: false,
40
39
  registrationEnabled: false,
41
- databaseMode: "none",
42
40
  experimentVisibilityMode: "open"
43
41
  };
44
42
  }
@@ -613,135 +611,6 @@ function useAsyncBatch(asyncFns) {
613
611
  };
614
612
  }
615
613
  //#endregion
616
- //#region src/composables/usePluginConfig.ts
617
- var PLATFORM_OWNED_SETTINGS_KEY$1 = "allowed_experiment_types";
618
- function cloneConfig(config) {
619
- return JSON.parse(JSON.stringify(config));
620
- }
621
- function hasOwnConfig(config, key) {
622
- return Object.prototype.hasOwnProperty.call(config, key);
623
- }
624
- function changedTopLevelKeys(current, saved) {
625
- return new Set([...new Set([...Object.keys(current), ...Object.keys(saved)])].filter((key) => JSON.stringify(current[key]) !== JSON.stringify(saved[key])));
626
- }
627
- function topLevelConfigPatch(current, keys) {
628
- return Object.fromEntries([...keys].map((key) => [key, hasOwnConfig(current, key) ? current[key] : null]));
629
- }
630
- function platformOwnedConfigPatch(config) {
631
- return { [PLATFORM_OWNED_SETTINGS_KEY$1]: hasOwnConfig(config, PLATFORM_OWNED_SETTINGS_KEY$1) ? config[PLATFORM_OWNED_SETTINGS_KEY$1] : null };
632
- }
633
- function responseConfigPayload(response) {
634
- return response.config ?? response.settings ?? {};
635
- }
636
- /** Loads, saves, and tracks dirty state for a plugin's persistent configuration via the platform API. */
637
- function usePluginConfig(pluginName) {
638
- const injectedContext = getInjectedPlatformContext();
639
- const { plugin } = usePlatformContext();
640
- const platformApi = useApi();
641
- const pluginApi = useApi({ baseUrl: injectedContext?.plugin?.api_prefix ?? plugin.value?.api_prefix });
642
- const resolvedName = computed(() => pluginName ?? plugin.value?.name ?? injectedContext?.plugin?.name ?? "");
643
- const usesPluginSettingsApi = computed(() => {
644
- const currentPlugin = injectedContext?.plugin ?? plugin.value;
645
- return currentPlugin?.settings_api === "plugin" && resolvedName.value === currentPlugin.name;
646
- });
647
- const config = ref({});
648
- const savedConfig = ref({});
649
- const revision = ref(null);
650
- const request = useRequestSyncState("Plugin config request failed.");
651
- const isLoading = ref(false);
652
- const isSaving = ref(false);
653
- const error = request.error;
654
- const lastLoadedAt = request.lastLoadedAt;
655
- const lastSavedAt = request.lastSavedAt;
656
- const isDirty = computed(() => {
657
- return JSON.stringify(config.value) !== JSON.stringify(savedConfig.value);
658
- });
659
- async function load() {
660
- const name = resolvedName.value;
661
- if (!name) return;
662
- isLoading.value = true;
663
- try {
664
- const response = usesPluginSettingsApi.value ? await request.run(() => pluginApi.get("/settings"), {
665
- success: "load",
666
- errorMessage: "Failed to load plugin config"
667
- }) : await request.run(() => platformApi.get(`/plugins/${encodeURIComponent(name)}/config`), {
668
- success: "load",
669
- errorMessage: "Failed to load plugin config"
670
- });
671
- const responseConfig = responseConfigPayload(response);
672
- config.value = cloneConfig(responseConfig);
673
- savedConfig.value = cloneConfig(responseConfig);
674
- revision.value = response.revision ?? null;
675
- } catch {} finally {
676
- isLoading.value = false;
677
- }
678
- }
679
- async function save() {
680
- const name = resolvedName.value;
681
- if (!name) return false;
682
- isSaving.value = true;
683
- try {
684
- const payload = cloneConfig(config.value);
685
- let response;
686
- let nextRevision = revision.value;
687
- if (usesPluginSettingsApi.value) {
688
- response = await request.run(() => pluginApi.put("/settings", payload, revision.value ? { headers: { "If-Match": `"${revision.value}"` } } : void 0), {
689
- success: "save",
690
- errorMessage: "Failed to save plugin config"
691
- });
692
- nextRevision = response.revision ?? nextRevision;
693
- } else {
694
- const dirtyKeys = changedTopLevelKeys(payload, savedConfig.value);
695
- const platformOwnedChanged = dirtyKeys.has(PLATFORM_OWNED_SETTINGS_KEY$1);
696
- const typedKeys = [...dirtyKeys].filter((key) => key !== PLATFORM_OWNED_SETTINGS_KEY$1);
697
- if (typedKeys.length) {
698
- response = await request.run(() => platformApi.patch(`/plugins/${encodeURIComponent(name)}/config`, { config: topLevelConfigPatch(payload, typedKeys) }), {
699
- success: "save",
700
- errorMessage: "Failed to save plugin config"
701
- });
702
- nextRevision = response.revision ?? nextRevision;
703
- }
704
- if (platformOwnedChanged) {
705
- response = await request.run(() => platformApi.patch(`/plugins/${encodeURIComponent(name)}/config`, { config: platformOwnedConfigPatch(payload) }), {
706
- success: "save",
707
- errorMessage: "Failed to save plugin config"
708
- });
709
- nextRevision = response.revision ?? nextRevision;
710
- }
711
- }
712
- if (!response) return true;
713
- const responseConfig = responseConfigPayload(response);
714
- config.value = cloneConfig(responseConfig);
715
- savedConfig.value = cloneConfig(responseConfig);
716
- revision.value = response.revision ?? nextRevision;
717
- return true;
718
- } catch {
719
- return false;
720
- } finally {
721
- isSaving.value = false;
722
- }
723
- }
724
- function reset() {
725
- config.value = cloneConfig(savedConfig.value);
726
- request.clearError();
727
- }
728
- onMounted(() => {
729
- load();
730
- });
731
- return {
732
- config,
733
- isLoading,
734
- isSaving,
735
- error,
736
- lastLoadedAt,
737
- lastSavedAt,
738
- isDirty,
739
- load,
740
- save,
741
- reset
742
- };
743
- }
744
- //#endregion
745
614
  //#region src/composables/analysisArtifactTarget.ts
746
615
  var EXPERIMENT_ID = "experiment_id";
747
616
  var ARTIFACT_PLUGIN_ID = "artifact_plugin_id";
@@ -1627,10 +1496,6 @@ async function downloadPluginEndpoint(contract, endpoint, payload, options = {})
1627
1496
  if (options.filename) downloadBlob(blob, options.filename, { revokeObjectUrlDelayMs: options.revokeObjectUrlDelayMs });
1628
1497
  return blob;
1629
1498
  }
1630
- /** Return a generated plugin client from setup code with a stable typed identity. */
1631
- function usePluginClient(client) {
1632
- return client;
1633
- }
1634
1499
  function normalizePluginSettingsOptions(options = {}) {
1635
1500
  return typeof options === "string" ? { pluginName: options } : options;
1636
1501
  }
@@ -1780,44 +1645,27 @@ function usePluginSettings(options = {}) {
1780
1645
  reset
1781
1646
  };
1782
1647
  }
1783
- function streamRequestAuth(options, policy) {
1784
- const headers = new Headers(options.headers);
1648
+ function streamRequestAuth(requestHeaders, policy) {
1649
+ const headers = new Headers(requestHeaders);
1785
1650
  const authStore = useAuthStore();
1786
1651
  if (!authStore.isInitialized) authStore.initialize();
1787
1652
  if (policy.requiresAuth && authStore.token && !headers.has("Authorization")) headers.set("Authorization", `Bearer ${authStore.token}`);
1788
- headers.set("Accept", "text/event-stream");
1789
1653
  const token = policy.requiresAuth ? authStore.token : void 0;
1790
1654
  return {
1791
1655
  headers,
1792
1656
  token: token && headers.get("Authorization") === `Bearer ${token}` ? token : void 0
1793
1657
  };
1794
1658
  }
1795
- function parseSseEvent(block, parseJson) {
1796
- let event = "message";
1797
- let id;
1798
- let retry;
1799
- const dataLines = [];
1800
- for (const line of block.split(/\r?\n/)) {
1801
- if (!line || line.startsWith(":")) continue;
1802
- const separator = line.indexOf(":");
1803
- const field = separator === -1 ? line : line.slice(0, separator);
1804
- const value = separator === -1 ? "" : line.slice(separator + 1).replace(/^ /, "");
1805
- if (field === "event") event = value || "message";
1806
- if (field === "data") dataLines.push(value);
1807
- if (field === "id") id = value;
1808
- if (field === "retry") {
1809
- const parsed = Number(value);
1810
- if (Number.isFinite(parsed)) retry = parsed;
1811
- }
1812
- }
1813
- if (!dataLines.length && !id && retry === void 0) return null;
1814
- const data = dataLines.join("\n");
1815
- return {
1816
- event,
1817
- data: parseJson && data ? JSON.parse(data) : data,
1818
- id,
1819
- retry,
1820
- raw: block
1659
+ function pluginEventStreamTransport(endpoint) {
1660
+ return async (url, init = {}) => {
1661
+ if (typeof fetch !== "function") throw new Error("[MINT SDK] fetch is required for plugin event streams.");
1662
+ const requestAuth = streamRequestAuth(init.headers, { requiresAuth: endpoint.requiresAuth !== false });
1663
+ const response = await fetch(url, {
1664
+ ...init,
1665
+ headers: requestAuth.headers
1666
+ });
1667
+ if (response.status === 401) throw authenticationRequiredError(response, requestAuth.token);
1668
+ return response;
1821
1669
  };
1822
1670
  }
1823
1671
  function looksLikeEventStreamOptions(value) {
@@ -1837,149 +1685,25 @@ function looksLikeEventStreamOptions(value) {
1837
1685
  ].some((key) => key in candidate);
1838
1686
  }
1839
1687
  function usePluginEventStream(contract, endpoint, payloadOrOptions, maybeOptions) {
1688
+ if (endpoint.method !== "get") throw new Error(`[MINT SDK] Plugin event streams must use GET; got ${endpoint.method}`);
1840
1689
  const payload = maybeOptions === void 0 && looksLikeEventStreamOptions(payloadOrOptions) ? void 0 : payloadOrOptions;
1841
1690
  const options = maybeOptions === void 0 && looksLikeEventStreamOptions(payloadOrOptions) ? payloadOrOptions : maybeOptions ?? {};
1842
- const isConnected = ref(false);
1843
- const isConnecting = ref(false);
1844
- const error = ref(null);
1845
- const lastMessage = shallowRef(null);
1846
- const lastEventId = ref(null);
1847
1691
  const responseType = endpoint.responseType?.trim();
1848
1692
  const parseJson = options.parseJson ?? Boolean(responseType && responseType !== "string");
1849
- let controller = null;
1850
- let reconnectTimer = null;
1851
- let stopped = true;
1852
- let generation = 0;
1853
- function clearReconnectTimer() {
1854
- if (reconnectTimer !== null) {
1855
- clearTimeout(reconnectTimer);
1856
- reconnectTimer = null;
1857
- }
1858
- }
1859
- function ownsConnection(connectionGeneration, connectionController) {
1860
- return !stopped && generation === connectionGeneration && controller === connectionController;
1861
- }
1862
- function scheduleReconnect(connectionGeneration) {
1863
- if (stopped || generation !== connectionGeneration || options.reconnect === false) return;
1864
- clearReconnectTimer();
1865
- reconnectTimer = setTimeout(() => {
1866
- reconnectTimer = null;
1867
- if (stopped || generation !== connectionGeneration) return;
1868
- connect(connectionGeneration);
1869
- }, options.reconnectDelayMs ?? 2e3);
1870
- }
1871
- async function connect(connectionGeneration) {
1872
- if (stopped || generation !== connectionGeneration) return;
1873
- if (endpoint.method !== "get") throw new Error(`[MINT SDK] Plugin event streams must use GET; got ${endpoint.method}`);
1874
- if (typeof fetch !== "function") throw new Error("[MINT SDK] fetch is required for plugin event streams.");
1875
- controller?.abort();
1876
- const connectionController = new AbortController();
1877
- controller = connectionController;
1878
- isConnecting.value = true;
1879
- if (!ownsConnection(connectionGeneration, connectionController)) return;
1880
- error.value = null;
1881
- if (!ownsConnection(connectionGeneration, connectionController)) return;
1882
- let authenticationFailed = false;
1883
- try {
1884
- const url = buildPluginEndpointUrl(contract, endpoint, payload, { baseUrl: options.baseUrl });
1885
- const requestAuth = streamRequestAuth(options, { requiresAuth: endpoint.requiresAuth !== false });
1886
- const response = await fetch(url, {
1887
- method: "GET",
1888
- headers: requestAuth.headers,
1889
- credentials: options.credentials ?? "same-origin",
1890
- signal: connectionController.signal
1891
- });
1892
- if (!ownsConnection(connectionGeneration, connectionController)) return;
1893
- if (!response.ok) {
1894
- if (response.status === 401) {
1895
- authenticationFailed = true;
1896
- throw authenticationRequiredError(response, requestAuth.token);
1897
- }
1898
- throw new Error(`Plugin event stream failed with HTTP ${response.status}`);
1899
- }
1900
- if (!response.body) throw new Error("Plugin event stream response did not include a readable body.");
1901
- isConnected.value = true;
1902
- if (!ownsConnection(connectionGeneration, connectionController)) return;
1903
- options.onOpen?.();
1904
- if (!ownsConnection(connectionGeneration, connectionController)) return;
1905
- const reader = response.body.getReader();
1906
- const decoder = new TextDecoder();
1907
- let buffer = "";
1908
- for (;;) {
1909
- const { value, done } = await reader.read();
1910
- if (!ownsConnection(connectionGeneration, connectionController)) return;
1911
- if (done) break;
1912
- buffer += decoder.decode(value, { stream: true });
1913
- let boundary = buffer.search(/\r?\n\r?\n/);
1914
- while (boundary !== -1) {
1915
- const block = buffer.slice(0, boundary);
1916
- buffer = buffer.slice(buffer[boundary] === "\r" ? boundary + 4 : boundary + 2);
1917
- const message = parseSseEvent(block, parseJson);
1918
- if (message) {
1919
- lastMessage.value = message;
1920
- if (!ownsConnection(connectionGeneration, connectionController)) return;
1921
- if (message.id !== void 0) {
1922
- lastEventId.value = message.id;
1923
- if (!ownsConnection(connectionGeneration, connectionController)) return;
1924
- }
1925
- if (message.retry !== void 0) options.reconnectDelayMs = message.retry;
1926
- if (!ownsConnection(connectionGeneration, connectionController)) return;
1927
- options.onMessage?.(message);
1928
- if (!ownsConnection(connectionGeneration, connectionController)) return;
1929
- }
1930
- boundary = buffer.search(/\r?\n\r?\n/);
1931
- }
1932
- }
1933
- } catch (err) {
1934
- if (err instanceof AuthenticationRequiredError) authenticationFailed = true;
1935
- if (ownsConnection(connectionGeneration, connectionController) && !(err instanceof DOMException && err.name === "AbortError")) {
1936
- error.value = err instanceof Error ? err.message : "Plugin event stream failed";
1937
- if (ownsConnection(connectionGeneration, connectionController)) options.onError?.(err);
1938
- }
1939
- } finally {
1940
- if (ownsConnection(connectionGeneration, connectionController)) {
1941
- isConnecting.value = false;
1942
- if (ownsConnection(connectionGeneration, connectionController)) {
1943
- isConnected.value = false;
1944
- if (ownsConnection(connectionGeneration, connectionController)) {
1945
- controller = null;
1946
- if (authenticationFailed) stopped = true;
1947
- else scheduleReconnect(connectionGeneration);
1948
- }
1949
- }
1950
- }
1951
- }
1952
- }
1953
- function start() {
1954
- if (!stopped) return;
1955
- stopped = false;
1956
- clearReconnectTimer();
1957
- generation += 1;
1958
- connect(generation);
1959
- }
1960
- function stop() {
1961
- if (stopped) return;
1962
- stopped = true;
1963
- generation += 1;
1964
- clearReconnectTimer();
1965
- controller?.abort();
1966
- controller = null;
1967
- isConnecting.value = false;
1968
- isConnected.value = false;
1969
- }
1970
- const currentInstance = getCurrentInstance();
1971
- if (currentInstance && options.immediate !== false && typeof window === "undefined") onMounted(start);
1972
- if (currentInstance) onUnmounted(stop);
1973
- if (options.immediate !== false && (typeof window !== "undefined" || !currentInstance)) start();
1974
- return {
1975
- isConnected,
1976
- isConnecting,
1977
- error,
1978
- lastMessage,
1979
- lastEventId,
1980
- start,
1981
- stop
1982
- };
1693
+ return useEventStream(() => buildPluginEndpointUrl(contract, endpoint, payload, { baseUrl: options.baseUrl }), {
1694
+ transport: pluginEventStreamTransport(endpoint),
1695
+ immediate: options.immediate,
1696
+ reconnect: options.reconnect,
1697
+ reconnectDelayMs: options.reconnectDelayMs,
1698
+ parseJson,
1699
+ credentials: options.credentials,
1700
+ headers: options.headers,
1701
+ shouldReconnect: (cause) => !(cause instanceof AuthenticationRequiredError),
1702
+ onOpen: options.onOpen,
1703
+ onMessage: options.onMessage,
1704
+ onError: options.onError,
1705
+ errorLabel: "Plugin event stream"
1706
+ });
1983
1707
  }
1984
1708
  /** Read and optionally load the current platform experiment for integrated plugin views. */
1985
1709
  function useCurrentExperiment(options = {}) {
@@ -2039,6 +1763,6 @@ function useCurrentExperiment(options = {}) {
2039
1763
  };
2040
1764
  }
2041
1765
  //#endregion
2042
- export { useAsync as A, createPluginResourceClient as C, buildAnalysisArtifactTargetQuery as D, useCommandHistory as E, resolvePluginFrontendBase as M, usePasskey as N, parseAnalysisArtifactTarget as O, useAuth as P, 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, useAsyncBatch as j, usePluginConfig 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 };
1766
+ export { resolvePluginFrontendBase as A, useResourceCrud as C, parseAnalysisArtifactTarget as D, buildAnalysisArtifactTargetQuery as E, useAuth as M, useAsync as O, createPluginResourceClient as S, useCommandHistory as T, useWellPlateAdapter as _, pluginFormDataFromPayload as a, wellIdToCoordinate as b, usePluginEventStream as c, resolvePluginBaseUrl as d, runWellPlateValidation as f, createWellPlateWells as g, createRowConditions as h, getPluginPageSelectorItems as i, usePasskey as j, useAsyncBatch as k, usePluginSettings as l, createColumnConditions as m, downloadBlob as n, uploadPluginEndpoint as o, useWellPlateValidation as p, downloadPluginEndpoint as r, useCurrentExperiment as s, createPluginClient as t, buildPluginEndpointUrl as u, coordinateToWellId as v, useOptimisticMutation as w, wellIdsInRectangle as x, useWellPainting as y };
2043
1767
 
2044
- //# sourceMappingURL=composables-CkXDe7nm.js.map
1768
+ //# sourceMappingURL=composables-C_i90sGS.js.map