import { inject, type Reactive } from "vue"; import { pluginDataKey } from "../defineApp"; import type { PluginHandle, InferFactoryData, InferFactoryOutputs, InferFactoryUiServices, PluginFactoryLike, } from "@platforma-sdk/model"; /** Per-plugin reactive model exposed to consumers via usePlugin(). */ export interface PluginState< Data = unknown, Outputs = unknown, Services = Record, > { readonly model: Reactive<{ data: Data; outputs: Outputs extends Record ? { [K in keyof Outputs]: Outputs[K] | undefined } : Record; outputErrors: Outputs extends Record ? { [K in keyof Outputs]?: Error } : Record; }>; readonly services: Services; } /** Internal interface for plugin access — provided via Vue injection to usePlugin(). */ export interface PluginAccess { getOrCreatePluginState( handle: PluginHandle, ): PluginState, InferFactoryOutputs, InferFactoryUiServices>; } /** * Composable for accessing a plugin's reactive model: data, outputs, and outputErrors. * * Mirrors the `app.model` access pattern — `plugin.model.data` is reactive and deep-watched, * mutations are automatically queued and sent to storage. * * @param handle - Opaque plugin handle obtained from `app.plugins`. * @typeParam F - The plugin factory type (inferred from the handle) * * @example * ```vue * * ``` */ export function usePlugin(handle: PluginHandle) { const access = inject(pluginDataKey); if (!access) { throw new Error( "usePlugin requires a V3 block (BlockModelV3). " + "Make sure the block uses apiVersion 3 and the plugin is installed.", ); } return access.getOrCreatePluginState(handle); }