Skip to main content

Viewer System API Reference

Overview

This document provides comprehensive API reference for the Bike4Mind viewer system, including component interfaces, hooks, utilities, and integration patterns.

Core Interfaces

ArtifactViewerProps

Base interface for all artifact viewer components.

interface ArtifactViewerProps<T extends Artifact = Artifact> {
/** The artifact to display */
artifact: T;

/** Called when viewer encounters an error */
onError?: (error: string) => void;

/** Called when artifact is edited (if applicable) */
onEdit?: (updatedArtifact: T) => void;

/** Called when viewer is closed */
onClose?: () => void;

/** Additional CSS class name */
className?: string;

/** Custom styling */
style?: React.CSSProperties;
}

Artifact Types

ReactArtifact

interface ReactArtifact extends Artifact {
type: 'react';
metadata: {
/** NPM dependencies used by the component */
dependencies: string[];

/** Component props schema */
props?: Record<string, unknown>;

/** Whether component has default export */
hasDefaultExport: boolean;

/** Whether to wrap in error boundary */
errorBoundary: boolean;
};
}

HtmlArtifact

interface HtmlArtifact extends Artifact {
type: 'html';
metadata: {
/** Allowed script sources */
allowedScripts: string[];

/** Custom CSP policy */
cspPolicy?: string;

/** Whether content has been sanitized */
sanitized: boolean;
};
}

SvgArtifact

interface SvgArtifact extends Artifact {
type: 'svg';
metadata: {
/** SVG viewBox attribute */
viewBox?: string;

/** Preferred width */
width?: number;

/** Preferred height */
height?: number;

/** Whether content has been sanitized */
sanitized: boolean;
};
}

MermaidArtifact

interface MermaidArtifact extends Artifact {
type: 'mermaid';
metadata: {
/** Type of Mermaid diagram */
chartType?: 'flowchart' | 'sequenceDiagram' | 'classDiagram' |
'stateDiagram' | 'entityRelationshipDiagram' |
'gantt' | 'pie' | 'mindmap';

/** Human-readable description */
description?: string;
};
}

Component APIs

KnowledgeViewer

Main orchestrator component for all content types.

interface KnowledgeViewerProps {
/** Optional custom class name */
className?: string;

/** Custom styling */
style?: React.CSSProperties;

/** Whether to show layout controls */
showLayoutControls?: boolean;

/** Initial layout mode */
initialLayout?: LayoutMode;
}

type LayoutMode = 'vertical' | 'horizontal' | 'pip' | 'noAI' | 'hide';

Usage:

import KnowledgeViewer from '@client/app/components/Knowledge/KnowledgeViewer';

const MyComponent = () => (
<KnowledgeViewer
showLayoutControls={true}
initialLayout="vertical"
/>
);

ReactArtifactViewer

Secure React component viewer with sandboxed execution.

interface ReactArtifactViewerProps extends ArtifactViewerProps<ReactArtifact> {
/** Custom allowed dependencies (overrides default) */
allowedDependencies?: string[];

/** Custom CSP policy for sandbox */
cspPolicy?: string;

/** Execution timeout in milliseconds */
executionTimeout?: number;

/** Whether to show code tab */
showCodeTab?: boolean;

/** Initial active tab */
initialTab?: 'preview' | 'code';
}

Default allowed dependencies:

const DEFAULT_ALLOWED_DEPENDENCIES = [
'react',
'lucide-react',
'recharts',
'mathjs',
'lodash',
'd3',
'papaparse',
'xlsx'
];

Usage:

import ReactArtifactViewer from '@client/app/components/Knowledge/ReactArtifactViewer';

const MyReactViewer = ({ artifact }: { artifact: ReactArtifact }) => (
<ReactArtifactViewer
artifact={artifact}
showCodeTab={true}
initialTab="preview"
executionTimeout={15000}
onError={(error) => console.error('Viewer error:', error)}
/>
);

ReactArtifactPreviewCard

Compact preview card for React artifacts.

interface ReactArtifactPreviewCardProps {
/** The React artifact to preview */
artifact: ReactArtifact;

/** Called when card is expanded */
onExpand?: () => void;

/** Whether to show complexity indicator */
showComplexity?: boolean;

/** Whether to show dependency count */
showDependencies?: boolean;

/** Custom actions to display */
customActions?: PreviewAction[];
}

interface PreviewAction {
icon: React.ReactNode;
label: string;
onClick: (artifact: ReactArtifact) => void;
tooltip?: string;
}

Usage:

import ReactArtifactPreviewCard from '@client/app/components/GenAI/ReactArtifactPreviewCard';

const MyPreview = ({ artifact }: { artifact: ReactArtifact }) => (
<ReactArtifactPreviewCard
artifact={artifact}
showComplexity={true}
showDependencies={true}
onExpand={() => console.log('Expanding artifact')}
customActions={[
{
icon: <CustomIcon />,
label: 'Custom Action',
onClick: (artifact) => handleCustomAction(artifact),
tooltip: 'Perform custom action'
}
]}
/>
);

Hooks

useSessionLayout

Manages viewer layout state and persistence.

interface SessionLayoutState {
/** Current layout mode */
layout: LayoutMode;

/** Currently displayed artifact data */
artifactData?: ArtifactData;

/** ID of selected artifact */
selectedArtifactId?: string;
}

interface ArtifactData {
type: 'questmaster' | 'code' | 'mermaid' | 'react' | 'html' | 'svg';
content: QuestMasterData | CodeArtifactData | string |
MermaidArtifact | ReactArtifact | HtmlArtifact | SvgArtifact;
mimeType: string;
id: string;
}

// Hook usage
const layout = useSessionLayout(state => state.layout);
const artifactData = useSessionLayout(state => state.artifactData);

// Update layout
import { setSessionLayout } from '@client/app/hooks/useSessionLayout';

setSessionLayout({
layout: 'vertical',
artifactData: {
type: 'react',
content: myReactArtifact,
mimeType: 'application/vnd.ant.react',
id: 'artifact-123'
}
});

useKnowledgeViewer

Manages KnowledgeViewer internal state.

interface KnowledgeViewerState {
/** Currently selected tab index */
selectedTabIndex: number;
}

// Hook usage
const { selectedTabIndex } = useKnowledgeViewer();

// Update state
import { setKnowledgeViewer } from '@client/app/components/Knowledge/KnowledgeViewer';

setKnowledgeViewer({ selectedTabIndex: 2 });

Utility Functions

validateArtifactContent

Validates and sanitizes artifact content for security.

function validateArtifactContent(
type: ArtifactType,
content: string
): ValidationResult;

interface ValidationResult {
isValid: boolean;
errors: string[];
warnings?: string[];
sanitizedContent?: string;
}

Usage:

import { validateArtifactContent } from '@client/app/utils/artifactParser';

const validation = validateArtifactContent('html', htmlContent);

if (validation.isValid) {
// Safe to render
renderContent(validation.sanitizedContent || content);
} else {
// Handle validation errors
console.error('Validation failed:', validation.errors);
}

getContentFromFabfile

Fetches content from FabFile with proper URL handling.

interface FabFileContentParams {
fileUrl?: string;
mimeType: string;
maxSize?: number;
}

function getContentFromFabfile(
params: FabFileContentParams
): Promise<string | null>;

Usage:

import { getContentFromFabfile } from '@client/app/utils/fabFileUtils';

const content = await getContentFromFabfile({
fileUrl: file.fileUrl,
mimeType: file.mimeType,
maxSize: 5 * 1024 * 1024 // 5MB limit
});

generateSandboxHTML

Creates secure sandbox HTML for component execution.

function generateSandboxHTML(
componentCode: string,
dependencies?: string[],
options?: SandboxOptions
): string;

interface SandboxOptions {
cspPolicy?: string;
executionTimeout?: number;
allowedGlobals?: string[];
customLibraries?: Record<string, string>;
}

Usage:

import { generateSandboxHTML } from '@client/app/components/Knowledge/ReactArtifactViewer';

const sandboxHTML = generateSandboxHTML(
reactCode,
['react', 'lucide-react'],
{
executionTimeout: 10000,
allowedGlobals: ['console', 'Math']
}
);

Security APIs

SecurityMonitor

Monitors and reports security violations in viewers.

class SecurityMonitor {
static getInstance(): SecurityMonitor;

recordViolation(violation: SecurityViolation): void;

addListener(listener: SecurityListener): () => void;

getViolationReport(): SecurityReport;
}

interface SecurityViolation {
type: 'xss_attempt' | 'code_injection' | 'resource_abuse' |
'csp_violation' | 'sandbox_escape';
severity: 'low' | 'medium' | 'high' | 'critical';
message: string;
source: string;
artifactId?: string;
timestamp?: number;
}

type SecurityListener = (violation: SecurityViolation) => void;

Usage:

import { SecurityMonitor } from '@client/app/utils/securityMonitor';

const monitor = SecurityMonitor.getInstance();

// Record a violation
monitor.recordViolation({
type: 'xss_attempt',
severity: 'high',
message: 'Script tag detected in HTML content',
source: 'html_viewer',
artifactId: 'artifact-123'
});

// Listen for violations
const removeListener = monitor.addListener((violation) => {
if (violation.severity === 'critical') {
alert('Critical security violation detected!');
}
});

Content Validation APIs

validateSecureContent

Comprehensive security validation for any content type.

function validateSecureContent(input: {
content: string;
type: 'html' | 'react' | 'svg' | 'markdown';
metadata?: {
allowedTags?: string[];
maxExecutionTime?: number;
};
}): ValidationResult;

validateReactComponent

Specialized validation for React components.

function validateReactComponent(code: string): ReactValidationResult;

interface ReactValidationResult {
isValid: boolean;
errors: string[];
warnings: string[];
hasSecurityIssues: boolean;
}

Usage:

import { validateReactComponent } from '@client/app/utils/securityValidation';

const validation = validateReactComponent(componentCode);

if (validation.hasSecurityIssues) {
console.error('Security issues found:', validation.errors);
return;
}

if (validation.isValid) {
// Safe to execute
executeReactComponent(componentCode);
}

Error Handling

ViewerErrorBoundary

React error boundary specifically for viewer components.

interface ViewerErrorBoundaryProps {
children: React.ReactNode;
fallback?: React.ReactNode;
onError?: (error: Error, errorInfo: React.ErrorInfo) => void;
resetKeys?: Array<string | number>;
}

class ViewerErrorBoundary extends React.Component<
ViewerErrorBoundaryProps
> {
// Implementation
}

Usage:

import ViewerErrorBoundary from '@client/app/components/Knowledge/ViewerErrorBoundary';

const SafeViewer = ({ artifact }: { artifact: ReactArtifact }) => (
<ViewerErrorBoundary
fallback={<div>Something went wrong</div>}
onError={(error, errorInfo) => logError(error, errorInfo)}
>
<ReactArtifactViewer artifact={artifact} />
</ViewerErrorBoundary>
);

File Support Matrix

Supported MIME Types

export const SupportedViewerMimeTypes = {
// Images
IMAGE_JPEG: 'image/jpeg',
IMAGE_PNG: 'image/png',
IMAGE_WEBP: 'image/webp',
IMAGE_GIF: 'image/gif',

// Documents
PDF: 'application/pdf',
DOCX: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
XLSX: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',

// Text formats
TEXT_PLAIN: 'text/plain',
TEXT_MARKDOWN: 'text/markdown',
TEXT_CSV: 'text/csv',
APPLICATION_JSON: 'application/json',

// Code files
JAVASCRIPT: 'application/javascript',
TYPESCRIPT: 'text/typescript',
PYTHON: 'text/x-python',
CSS: 'text/css',
HTML: 'text/html',

// Artifacts
REACT_ARTIFACT: 'application/vnd.ant.react',
HTML_ARTIFACT: 'text/html',
SVG_ARTIFACT: 'image/svg+xml',
MERMAID_ARTIFACT: 'application/vnd.ant.mermaid',
} as const;

File Type Detection

function getViewerForMimeType(mimeType: string): ViewerComponent | null;

function isSupportedMimeType(mimeType: string): boolean;

function getLanguageFromFileName(fileName: string): string;

Integration Examples

Custom Viewer Implementation

import React from 'react';
import { ArtifactViewerProps } from '@b4m-core/common/types/entities/ArtifactTypes';

interface CustomArtifact {
id: string;
type: 'custom';
title: string;
content: string;
metadata?: {
customProp: string;
};
}

const CustomViewer: React.FC<ArtifactViewerProps<CustomArtifact>> = ({
artifact,
onError,
onEdit,
className
}) => {
// Implementation
return (
<div className={className}>
<h2>{artifact.title}</h2>
<div>{artifact.content}</div>
</div>
);
};

export default CustomViewer;

Adding to KnowledgeViewer

// 1. Update type definitions
interface ICustomKnowledgeItem extends IBaseKnowledgeItem {
type: 'custom';
content: CustomArtifact;
}

type KnowledgeItem =
| IFileKnowledgeItem
| IQuestMasterKnowledgeItem
| ICustomKnowledgeItem; // Add here

// 2. Add dynamic import
const CustomViewer = dynamic(() => import('./CustomViewer'), {
ssr: false,
loading: () => <CircularProgress />
});

// 3. Add to switch statement
case 'custom':
return <CustomViewer artifact={item.content} />;

WebSocket Integration

const LiveViewer: React.FC<ArtifactViewerProps<LiveArtifact>> = ({ 
artifact
}) => {
const [content, setContent] = useState(artifact.content);
const { subscribeToAction } = useWebsocket();

useEffect(() => {
const unsubscribe = subscribeToAction('artifact_updated', (message) => {
if (message.artifactId === artifact.id) {
setContent(message.newContent);
}
});

return unsubscribe;
}, [artifact.id, subscribeToAction]);

return <ContentRenderer content={content} />;
};

Performance APIs

Resource Monitoring

interface PerformanceMetrics {
renderTime: number;
memoryUsage: number;
componentCount: number;
errorCount: number;
}

function usePerformanceMonitoring(
artifactId: string
): PerformanceMetrics;

Virtual Scrolling

import { FixedSizeList } from 'react-window';

interface VirtualizedViewerProps {
items: string[];
itemHeight: number;
height: number;
renderItem: (props: { index: number; style: React.CSSProperties }) => React.ReactNode;
}

const VirtualizedViewer: React.FC<VirtualizedViewerProps> = ({
items,
itemHeight,
height,
renderItem
}) => (
<FixedSizeList
height={height}
itemCount={items.length}
itemSize={itemHeight}
>
{renderItem}
</FixedSizeList>
);

Configuration

Environment Variables

# Security settings
VIEWER_MAX_EXECUTION_TIME=30000
VIEWER_MAX_CONTENT_SIZE=5242880 # 5MB
VIEWER_ENABLE_DEBUG_LOGGING=false

# Performance settings
VIEWER_ENABLE_VIRTUALIZATION=true
VIEWER_CHUNK_SIZE=1000

# Feature flags
VIEWER_ENABLE_COLLABORATION=false
VIEWER_ENABLE_REAL_TIME_UPDATES=true

Runtime Configuration

interface ViewerConfig {
security: {
maxExecutionTime: number;
maxContentSize: number;
allowedDomains: string[];
};
performance: {
enableVirtualization: boolean;
chunkSize: number;
};
features: {
enableCollaboration: boolean;
enableRealTimeUpdates: boolean;
};
}

// Configure at runtime
import { configureViewers } from '@client/app/utils/viewerConfig';

configureViewers({
security: {
maxExecutionTime: 15000,
maxContentSize: 10 * 1024 * 1024,
allowedDomains: ['trusted-domain.com']
}
});

This API reference provides comprehensive documentation for integrating with and extending the Bike4Mind viewer system.