import { computed, effectScope, getCurrentScope, onScopeDispose, shallowRef, watch, type ComputedRef, type EffectScope, type Ref, } from 'vue' import { createBioTemplatePackCollection, getBioTemplatePackInfo, type BioTemplatePackEntry, type TemplateCollectionEnvelope, type TemplatePackId, } from '../templates' import { useTemplateCollection, type UseTemplateCollectionOptions, type UseTemplateCollectionReturn, } from './useTemplateCollection' import { useBioTemplateWorkspace, type BioTemplateRendererBinding, type BioTemplateWorkspaceBindings, type UseBioTemplateWorkspaceReturn, } from './useBioTemplateWorkspace' import { liftWorkspaceComponentBindings, } from './flattenWorkspaceBindings' import type { BioTemplateComponentBinding, BioTemplateComponentBindingsById, BioTemplateComponentImport, BioTemplateComponentPropsByComponent, BioTemplateComponentPropsBinding, BioTemplateComponentPropsById, BioTemplateComponentSnippet, BioTemplateComponentUsage, } from './useBioTemplateComponents' export type UseBioTemplatePackWorkspaceOptions = UseTemplateCollectionOptions export interface UseBioTemplatePackWorkspaceReturn { packId: TemplatePackId pack: BioTemplatePackEntry collection: Ref templates: UseTemplateCollectionReturn['templates'] templateIds: UseTemplateCollectionReturn['templateIds'] currentExperimentId: UseTemplateCollectionReturn['currentExperimentId'] hasCurrentExperiment: UseTemplateCollectionReturn['hasCurrentExperiment'] loading: UseTemplateCollectionReturn['isLoading'] saving: UseTemplateCollectionReturn['isSaving'] error: UseTemplateCollectionReturn['error'] lastLoadedAt: UseTemplateCollectionReturn['lastLoadedAt'] lastSavedAt: UseTemplateCollectionReturn['lastSavedAt'] renderer: ComputedRef workspace: ComputedRef form: ComputedRef sidebar: ComputedRef topBar: ComputedRef pillNav: ComputedRef topBarSettings: ComputedRef bindings: ComputedRef componentBindings: ComputedRef componentBindingsById: ComputedRef componentImports: ComputedRef componentProps: ComputedRef componentPropsById: ComputedRef componentPropsByComponent: ComputedRef componentSnippets: ComputedRef componentUsage: ComputedRef getComponentProps: UseBioTemplateWorkspaceReturn['getComponentProps'] applyCollection: (value: unknown, metadata?: Record) => TemplateCollectionEnvelope resetToDefaultCollection: () => TemplateCollectionEnvelope save: UseTemplateCollectionReturn['save'] saveCurrent: UseTemplateCollectionReturn['saveCurrent'] load: UseTemplateCollectionReturn['load'] loadCurrent: UseTemplateCollectionReturn['loadCurrent'] requireCurrentExperimentId: UseTemplateCollectionReturn['requireCurrentExperimentId'] } /** * Create a complete workspace for a curated biology template pack from a single pack id. * * @example Recommended * ```ts * const pack = useBioTemplatePackWorkspace('cell-culture-screen') * await pack.loadCurrent() * ``` * * @deprecated Scheduled for removal in MINT 1.4; no SDK replacement. */ export function useBioTemplatePackWorkspace( packId: TemplatePackId | string, options: UseBioTemplatePackWorkspaceOptions = {}, ): UseBioTemplatePackWorkspaceReturn { const pack = getBioTemplatePackInfo(packId) if (!pack) { throw new Error(`Unknown template pack '${packId}'.`) } const resolvedPack = pack const templateCollection = useTemplateCollection({ ...options, initial: createDefaultCollection, }) const collection = templateCollection.templateCollection let workspaceScope: EffectScope | undefined function createWorkspace(value: TemplateCollectionEnvelope): UseBioTemplateWorkspaceReturn { workspaceScope?.stop() workspaceScope = effectScope() return workspaceScope.run(() => useBioTemplateWorkspace(value))! } const workspaceRef = shallowRef(createWorkspace(collection.value)) const workspace = computed(() => workspaceRef.value) const renderer = computed(() => ({ target: collection.value })) const form = computed(() => workspace.value.form) const sidebar = computed(() => workspace.value.sidebar) const topBar = computed(() => workspace.value.topBar.value) const pillNav = computed(() => workspace.value.pillNav) const topBarSettings = computed(() => workspace.value.topBarSettings) const bindings = computed(() => workspace.value.bindings) const { componentBindings, componentBindingsById, componentImports, componentProps, componentPropsById, componentPropsByComponent, componentSnippets, componentUsage, getComponentProps: getWorkspaceComponentProps, } = liftWorkspaceComponentBindings(workspace) watch(collection, value => { workspaceRef.value = createWorkspace(value) }) if (getCurrentScope()) { onScopeDispose(() => workspaceScope?.stop()) } function createDefaultCollection(): TemplateCollectionEnvelope { return createBioTemplatePackCollection(resolvedPack.name) } function applyCollection( value: unknown, metadata?: Record, ): TemplateCollectionEnvelope { return templateCollection.apply(value, metadata) } function resetToDefaultCollection(): TemplateCollectionEnvelope { return templateCollection.apply(createDefaultCollection()) } return { packId: resolvedPack.name, pack: resolvedPack, collection, templates: templateCollection.templates, templateIds: templateCollection.templateIds, currentExperimentId: templateCollection.currentExperimentId, hasCurrentExperiment: templateCollection.hasCurrentExperiment, loading: templateCollection.isLoading, saving: templateCollection.isSaving, error: templateCollection.error, lastLoadedAt: templateCollection.lastLoadedAt, lastSavedAt: templateCollection.lastSavedAt, renderer, workspace, form, sidebar, topBar, pillNav, topBarSettings, bindings, componentBindings, componentBindingsById, componentImports, componentProps, componentPropsById, componentPropsByComponent, componentSnippets, componentUsage, getComponentProps: getWorkspaceComponentProps, applyCollection, resetToDefaultCollection, save: templateCollection.save, saveCurrent: templateCollection.saveCurrent, load: templateCollection.load, loadCurrent: templateCollection.loadCurrent, requireCurrentExperimentId: templateCollection.requireCurrentExperimentId, } }