import type { ViewModel, ViewModelInstance } from '../specs/ViewModel.nitro'; import type { RiveFile } from '../specs/RiveFile.nitro'; import type { RiveViewRef } from '../index'; interface UseViewModelInstanceBaseParams { /** * Create the instance via the async runtime APIs (off the JS thread). * While creation is in flight the hook reports `isLoading: true` with an * `undefined` instance. Will become the default in the next major. * * Must stay constant for the lifetime of the component — it selects * between two hook implementations. */ async?: boolean; /** * If true, throws an error when the instance cannot be obtained. * This is useful with Error Boundaries and ensures TypeScript knows * the return value is non-null. */ required?: boolean; /** * Called when a new instance is created, before the hook exposes it — * synchronously during render without `async: true`, or right after the * instance resolves (before it is published) with `async: true`. * Note: This callback is excluded from deps - changing it won't recreate the instance. */ onInit?: (instance: ViewModelInstance) => void; } interface UseViewModelInstanceFileBaseParams extends UseViewModelInstanceBaseParams { /** * The ViewModel instance name (uses `createInstanceByName()`). * If not provided, creates the default instance. */ instanceName?: string; } /** * Use the ViewModel assigned to the default artboard. */ interface UseViewModelInstanceFileDefault extends UseViewModelInstanceFileBaseParams { artboardName?: never; viewModelName?: never; } /** * Use the ViewModel assigned to a specific artboard. */ interface UseViewModelInstanceFileByArtboard extends UseViewModelInstanceFileBaseParams { /** * Get the ViewModel assigned to this artboard. */ artboardName: string; viewModelName?: never; } /** * Use a ViewModel by name (file-wide lookup). * ViewModels are defined at the file level, not per-artboard. */ interface UseViewModelInstanceFileByViewModelName extends UseViewModelInstanceFileBaseParams { artboardName?: never; /** * The name of the ViewModel to use (uses `viewModelByName()`). * ViewModels are defined at the file level and looked up by name across the entire file. */ viewModelName: string; } export type UseViewModelInstanceFileParams = UseViewModelInstanceFileDefault | UseViewModelInstanceFileByArtboard | UseViewModelInstanceFileByViewModelName; export interface UseViewModelInstanceViewModelParams extends UseViewModelInstanceBaseParams { /** * The ViewModel instance name (uses `createInstanceByName()`). * If not provided, creates the default instance. */ name?: string; /** * Create a new (blank) instance from the ViewModel. */ useNew?: boolean; } export type UseViewModelInstanceRefParams = UseViewModelInstanceBaseParams; export type UseViewModelInstanceResult = { instance: ViewModelInstance; isLoading: false; error: null; } | { instance: null; isLoading: false; error: Error; } | { instance: null; isLoading: false; error: null; } | { instance: undefined; isLoading: true; error: null; }; /** * Result of {@link useViewModelInstance} when `required: true` is set. * The `null` (error/absent) case is removed — instead the hook throws once the * instance resolves to `null`, leaving only the ready and loading states. */ export type UseViewModelInstanceRequiredResult = { instance: ViewModelInstance; isLoading: false; error: null; } | { instance: undefined; isLoading: true; error: null; }; /** * Hook for getting a ViewModelInstance from a RiveFile, ViewModel, or RiveViewRef. * * Pass `async: true` to create the instance via the async runtime APIs, * resolving off the JS thread. The instance is then not available on the * first render — guard on the result: * * ```tsx * const { riveFile, error: fileError } = useRiveFile(require('./animation.riv')); * const { instance, isLoading, error } = useViewModelInstance(riveFile, { async: true }); * if (fileError || error) return ; * if (isLoading || !instance) return ; * // ... * * ``` * * Without `async: true` (deprecated) the instance is created synchronously * during render via deprecated runtime APIs that block the JS thread. The * async path will become the default in the next major. * * In both modes, a `null` source settles to a terminal * `{ instance: null, isLoading: false }` while an `undefined` source keeps * the hook loading. This mirrors {@link useRiveFile} (`riveFile: undefined` * while loading, `null` on error) and `useRive` (`riveViewRef: undefined` * until the view is ready, `null` on failure) — so when chaining, check the * upstream hook's own `error`, since this hook cannot observe why the source * is absent. * * @param source - The RiveFile, ViewModel, or RiveViewRef to get an instance from * @param params - Configuration for which instance to retrieve * @returns An object with `instance`, `isLoading`, and `error` (discriminated union) * * @example * ```tsx * // From RiveFile (get default instance) * const { riveFile } = useRiveFile(require('./animation.riv')); * const { instance, isLoading } = useViewModelInstance(riveFile, { async: true }); * ``` * * @example * ```tsx * // From RiveFile with specific instance name * const { instance } = useViewModelInstance(riveFile, { async: true, instanceName: 'PersonInstance' }); * ``` * * @example * ```tsx * // From RiveFile with specific ViewModel name * const { instance } = useViewModelInstance(riveFile, { async: true, viewModelName: 'Settings' }); * ``` * * @example * ```tsx * // From RiveFile with specific artboard * const { instance } = useViewModelInstance(riveFile, { async: true, artboardName: 'MainArtboard' }); * ``` * * @example * ```tsx * // From RiveViewRef (waits for the view's auto-bound instance) * const { riveViewRef, setHybridRef } = useRive(); * const { instance } = useViewModelInstance(riveViewRef, { async: true }); * ``` * * @example * ```tsx * // Create a new blank instance from ViewModel * const { instance } = useViewModelInstance(viewModel, { async: true, useNew: true }); * ``` * * @example * ```tsx * // With required: true (throws once resolved to null, use with Error Boundary). * // Note: instance is still `undefined` while loading — guard on isLoading. * // The required-narrowed return type applies only when the source's TYPE is * // non-nullable; with a nullable source (e.g. straight from useRiveFile) the * // call resolves to the standard overload — the runtime throw still applies. * const { instance, isLoading } = useViewModelInstance(riveFile, { async: true, required: true }); * ``` * * @example * ```tsx * // With onInit to set initial values before the instance is exposed or bound * const { instance } = useViewModelInstance(riveFile, { * async: true, * onInit: (vmi) => { * vmi.numberProperty('count')?.set(initialCount); * } * }); * ``` */ export declare function useViewModelInstance(source: RiveFile, params: UseViewModelInstanceFileParams & { async: true; required: true; }): UseViewModelInstanceRequiredResult; export declare function useViewModelInstance(source: RiveFile | null | undefined, params: UseViewModelInstanceFileParams & { async: true; }): UseViewModelInstanceResult; /** @deprecated Pass `async: true` — without it the instance is created synchronously via deprecated runtime APIs that block the JS thread. `async: true` becomes the default in the next major. If your params object's `async` widened to `boolean`, re-pin it at the call site: `{ ...params, async: true }`. */ export declare function useViewModelInstance(source: RiveFile, params: UseViewModelInstanceFileParams & { required: true; }): UseViewModelInstanceRequiredResult; /** @deprecated Pass `async: true` — without it the instance is created synchronously via deprecated runtime APIs that block the JS thread. `async: true` becomes the default in the next major. If your params object's `async` widened to `boolean`, re-pin it at the call site: `{ ...params, async: true }`. */ export declare function useViewModelInstance(source: RiveFile | null | undefined, params?: UseViewModelInstanceFileParams): UseViewModelInstanceResult; export declare function useViewModelInstance(source: ViewModel, params: UseViewModelInstanceViewModelParams & { async: true; required: true; }): UseViewModelInstanceRequiredResult; export declare function useViewModelInstance(source: ViewModel | null | undefined, params: UseViewModelInstanceViewModelParams & { async: true; }): UseViewModelInstanceResult; /** @deprecated Pass `async: true` — without it the instance is created synchronously via deprecated runtime APIs that block the JS thread. `async: true` becomes the default in the next major. If your params object's `async` widened to `boolean`, re-pin it at the call site: `{ ...params, async: true }`. */ export declare function useViewModelInstance(source: ViewModel, params: UseViewModelInstanceViewModelParams & { required: true; }): UseViewModelInstanceRequiredResult; /** @deprecated Pass `async: true` — without it the instance is created synchronously via deprecated runtime APIs that block the JS thread. `async: true` becomes the default in the next major. If your params object's `async` widened to `boolean`, re-pin it at the call site: `{ ...params, async: true }`. */ export declare function useViewModelInstance(source: ViewModel | null | undefined, params?: UseViewModelInstanceViewModelParams): UseViewModelInstanceResult; export declare function useViewModelInstance(source: RiveViewRef, params: UseViewModelInstanceRefParams & { async: true; required: true; }): UseViewModelInstanceRequiredResult; export declare function useViewModelInstance(source: RiveViewRef | null | undefined, params: UseViewModelInstanceRefParams & { async: true; }): UseViewModelInstanceResult; /** @deprecated Pass `async: true` — without it the instance is created synchronously via deprecated runtime APIs that block the JS thread. `async: true` becomes the default in the next major. If your params object's `async` widened to `boolean`, re-pin it at the call site: `{ ...params, async: true }`. */ export declare function useViewModelInstance(source: RiveViewRef, params: UseViewModelInstanceRefParams & { required: true; }): UseViewModelInstanceRequiredResult; /** @deprecated Pass `async: true` — without it the instance is created synchronously via deprecated runtime APIs that block the JS thread. `async: true` becomes the default in the next major. If your params object's `async` widened to `boolean`, re-pin it at the call site: `{ ...params, async: true }`. */ export declare function useViewModelInstance(source: RiveViewRef | null | undefined, params?: UseViewModelInstanceRefParams): UseViewModelInstanceResult; export {}; //# sourceMappingURL=useViewModelInstance.d.ts.map