UNPKG

@vyuh/react-extension-content

Version:

Content extension for the Vyuh Framework

375 lines (363 loc) 11.7 kB
import * as react_jsx_runtime from 'react/jsx-runtime'; import { ContentItem, TypeDescriptor, LayoutConfiguration, SchemaItem, ExtensionDescriptor, ActionConfiguration, ConditionConfiguration, ContentModifierConfiguration, ExtensionBuilder, ItemType, ContentPlugin, ContentProvider } from '@vyuh/react-core'; import React, { ReactNode, Component, ErrorInfo } from 'react'; import { Observable } from 'rxjs'; /** * Props for the DocumentLoader component */ interface DocumentLoaderProps<TContent extends ContentItem> { /** * Function to fetch content * Returns either a Promise (one-time loading) or Observable (live updates) */ fetchContent: () => Promise<TContent | TContent[] | undefined> | Observable<TContent | TContent[] | undefined>; /** * Custom render function for the content * If not provided, uses the content plugin's render method */ renderContent?: (content: TContent | TContent[] | undefined) => React.ReactNode; /** * Whether to allow refreshing the document */ allowRefresh?: boolean; /** * Error title to display when content fetching fails */ errorTitle?: string; } /** * Component that loads and renders a document from the content provider */ declare function DocumentLoader<TContent extends ContentItem>({ fetchContent, renderContent: customRenderContent, allowRefresh, errorTitle, }: DocumentLoaderProps<TContent>): react_jsx_runtime.JSX.Element; /** * Creates a fetch function for fetching content by query */ declare function fetchSingleWithQuery<TContent extends ContentItem>(query: string, options?: { params?: Record<string, any>; live?: boolean; }): () => any; /** * Creates a fetch function for fetching content by query */ declare function fetchMultipleWithQuery<TContent extends ContentItem>(query: string, options?: { params?: Record<string, any>; live?: boolean; }): () => any; /** * Creates a fetch function for fetching content by ID */ declare function fetchWithId<TContent extends ContentItem>(documentId: string, options?: { live?: boolean; }): () => any; /** * Props for the RouteLoader component */ interface RouteLoaderProps { /** * The URL to fetch the route for */ url?: string; /** * The route ID to fetch the route for */ routeId?: string; /** * Whether to allow refreshing the route */ allowRefresh?: boolean; /** * Whether to use live updates (observable-based) instead of one-time loading */ live?: boolean; } /** * A component that loads and renders a route from a URL or route ID */ declare function RouteLoader({ url, routeId, allowRefresh, live, }: RouteLoaderProps): react_jsx_runtime.JSX.Element; /** * Props for AsyncContentContainer */ interface AsyncContentContainerProps<T> { /** * Async function that loads the content * Can return either a Promise or an Observable */ fetchContent: () => Promise<T | T[] | undefined> | Observable<T | T[] | undefined>; /** * Function to render the loaded content */ renderContent: (content: T | T[] | undefined) => React.ReactNode; /** * Error title to display when loading fails */ errorTitle?: string; /** * Callback function to invoke when retrying after an error */ onRetry?: () => void; } /** * Generic component for loading and rendering async content with error handling */ declare function AsyncContentContainer<T>({ fetchContent, renderContent, errorTitle, onRetry, }: AsyncContentContainerProps<T>): React.ReactNode; /** * Descriptor for content types in the Vyuh system. * * Content descriptors define: * - Metadata about a content type (schema type, title) * - Available layouts for a content type * * They are used by ContentBuilder to initialize content types * with their available configurations. */ declare class ContentDescriptor<TContent extends ContentItem = ContentItem> { /** * The schema type of the content */ readonly schemaType: string; /** * The title of the content */ readonly title: string; /** * Available layouts for this content type */ readonly layouts?: TypeDescriptor<LayoutConfiguration<TContent>>[]; /** * The feature that registered this content descriptor */ private _sourceFeature?; /** * Get the source feature */ get sourceFeature(): string | undefined; /** * Creates a new content descriptor */ constructor({ schemaType, title, layouts, }: { schemaType: string; title: string; layouts?: TypeDescriptor<LayoutConfiguration<TContent>>[]; }); /** * Set the source feature */ setSourceFeature(featureName?: string): void; /** * Creates a default content descriptor with standard conventions */ static createDefault<TContent extends ContentItem = ContentItem>({ schemaType, title, }: { schemaType: string; title: string; }): (layouts?: TypeDescriptor<LayoutConfiguration<TContent>>[]) => ContentDescriptor<TContent>; } /** * Builder for configuring and managing content types and their layouts. * * ContentBuilder is responsible for: * - Managing layout configurations for content types * - Building content widgets */ declare class ContentBuilder<TContent extends ContentItem = ContentItem> implements SchemaItem { /** * The schema type for this builder */ readonly schemaType: string; /** * The default layout for this content type */ private _defaultLayout; /** * Get the default layout */ get defaultLayout(): LayoutConfiguration; private readonly _defaultLayoutDescriptor; /** * Get the default layout descriptor */ get defaultLayoutDescriptor(): TypeDescriptor<LayoutConfiguration>; /** * The feature that registered this content builder */ private _sourceFeature?; /** * Get the source feature */ get sourceFeature(): string | undefined; /** * Set the source feature */ setSourceFeature(featureName?: string): void; /** * Creates a new content builder */ constructor({ schemaType, defaultLayout, defaultLayoutDescriptor, }: { schemaType: string; defaultLayout: LayoutConfiguration; defaultLayoutDescriptor: TypeDescriptor<LayoutConfiguration>; }); /** * Initialize this content builder with the given content descriptors * * This method: * 1. Collects all available layouts from descriptors * 2. Combines them with the default layout * 3. Registers any additional type descriptors * * @param descriptors Content descriptors for this content type */ init(descriptors: ContentDescriptor[]): void; getLayout(content: TContent): LayoutConfiguration | undefined; /** * Build a widget for the given content item */ render(content: TContent, layout: LayoutConfiguration | undefined): React.ReactNode; /** * Set the default layout for this content builder */ setDefaultLayout(layout: LayoutConfiguration): void; } /** * Descriptor for content extensions */ declare class ContentExtensionDescriptor extends ExtensionDescriptor { static readonly extensionType = "vyuh.extension.content"; readonly type: string; /** * Content descriptors */ readonly contents?: ContentDescriptor[]; /** * Content builders */ readonly contentBuilders?: ContentBuilder[]; /** * Action configurations */ readonly actions?: TypeDescriptor<ActionConfiguration>[]; /** * Condition configurations */ readonly conditions?: TypeDescriptor<ConditionConfiguration>[]; /** * Content modifier configurations */ readonly contentModifiers?: TypeDescriptor<ContentModifierConfiguration>[]; /** * Creates a new content extension descriptor */ constructor(props?: Partial<ContentExtensionDescriptor>); /** * Set the source feature for this extension descriptor * This is called by the FeatureDescriptor when the extension is registered */ setSourceFeature(featureName: string): void; } /** * Builder for content extensions */ declare class ContentExtensionBuilder extends ExtensionBuilder { private typeMap; constructor(); /** * Build the content extension */ build(descriptors: ExtensionDescriptor[]): void; registerItem<T extends SchemaItem>(itemType: ItemType<T>, descriptor: TypeDescriptor<T>): void; /** * Get a content builder by schema type */ getBuilder(schemaType: string): ContentBuilder | undefined; /** * Get an item by its schema type */ getItem<T extends SchemaItem>(itemType: ItemType<T>, schemaType: string | undefined): TypeDescriptor<T> | undefined; /** * Find the content plugin from the Vyuh store and attach to it */ private findAndAttachToContentPlugin; /** * Collect items of a specific type from extension descriptors */ private collectItems; /** * Initialize a type map for a specific item type */ private initTypeMap; } /** * Default implementation of ContentPlugin. */ declare class DefaultContentPlugin extends ContentPlugin { private extensionBuilder?; constructor(provider: ContentProvider); getItem<T extends SchemaItem>(itemType: ItemType<T>, schemaType: string): TypeDescriptor<T> | undefined; registerItem<T extends SchemaItem>(itemType: ItemType<T>, descriptor: TypeDescriptor<T>): void; /** * Build content from a JSON object */ render(json: Record<string, any> | ContentItem, options?: { layout: LayoutConfiguration; }): React.ReactNode; /** * Attach an extension builder to this plugin */ attach(extBuilder: ExtensionBuilder): void; dispose(): Promise<void>; init(): Promise<void>; } /** * Error Boundary component props */ interface ErrorBoundaryProps { children: ReactNode; title: string; onRetry?: () => void; FallbackComponent?: React.ComponentType<{ error: Error; onRetry?: () => void; }>; } /** * Error Boundary component state */ interface ErrorBoundaryState { hasError: boolean; error: Error | null; } /** * Error Boundary component to catch and handle errors in the component tree */ declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> { constructor(props: ErrorBoundaryProps); static getDerivedStateFromError(error: Error): ErrorBoundaryState; componentDidCatch(error: Error, info: ErrorInfo): void; private invokeRetry; render(): ReactNode; } /** * Base interface for all async resources */ interface IAsyncResource<T> { read(): T; dispose(): void; isLive(): boolean; } /** * Resource for suspense-based data fetching with Promises */ declare class AsyncResource<T> implements IAsyncResource<T> { private result; private error; private status; private promise; constructor(source: Promise<T>); private handlePromise; read(): T; dispose(): void; /** * Returns whether this resource is backed by an Observable (true) or a Promise (false) */ isLive(): boolean; } export { AsyncContentContainer, type AsyncContentContainerProps, AsyncResource, ContentBuilder, ContentDescriptor, ContentExtensionBuilder, ContentExtensionDescriptor, DefaultContentPlugin, DocumentLoader, type DocumentLoaderProps, ErrorBoundary, type ErrorBoundaryProps, RouteLoader, type RouteLoaderProps, fetchMultipleWithQuery, fetchSingleWithQuery, fetchWithId };