All files / core/src/utils render-utils.js

52.63% Statements 10/19
46.66% Branches 7/15
60% Functions 3/5
52.63% Lines 10/19

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110                                          1x       1x         1x     1x                             1x   1x 1x                             1x       1x         1x                                                                    
/**
 * Shared rendering utilities for framework integrations
 * Eliminates code duplication across Express, Fastify, Koa, Next.js integrations
 */
 
import { render } from '../rendering/html-renderer.js';
import { performanceMonitor } from '../performance/monitor.js';
 
/**
 * Render a component with optional performance monitoring
 * This is the canonical rendering function used by all framework integrations
 * 
 * @param {Object} component - Coherent.js component to render
 * @param {Object} options - Rendering options
 * @param {boolean} options.enablePerformanceMonitoring - Enable performance tracking
 * @param {string} options.template - HTML template with {{content}} placeholder
 * @returns {string} Rendered HTML
 */
export function renderWithMonitoring(component, options = {}) {
  const {
    enablePerformanceMonitoring = false
  } = options;
 
  let html;
 
  Iif (enablePerformanceMonitoring) {
    const renderId = performanceMonitor.startRender();
    html = render(component);
    performanceMonitor.endRender(renderId);
  } else {
    html = render(component);
  }
 
  return html;
}
 
/**
 * Render a component and apply an HTML template
 * 
 * @param {Object} component - Coherent.js component to render
 * @param {Object} options - Rendering options
 * @param {boolean} options.enablePerformanceMonitoring - Enable performance tracking
 * @param {string} options.template - HTML template with {{content}} placeholder
 * @returns {string} Final HTML with template applied
 */
export function renderWithTemplate(component, options = {}) {
  const {
    template = '<!DOCTYPE html>\n{{content}}'
  } = options;
 
  const html = renderWithMonitoring(component, options);
  return template.replace('{{content}}', html);
}
 
/**
 * Create a component factory handler for framework integrations
 * Handles component creation, rendering, and error handling
 * 
 * @param {Function} componentFactory - Function that creates a component
 * @param {Object} factoryArgs - Arguments to pass to the component factory
 * @param {Object} options - Rendering options
 * @returns {Promise<string>} Rendered HTML
 * @throws {Error} If component factory returns null/undefined or rendering fails
 */
export async function renderComponentFactory(componentFactory, factoryArgs, options = {}) {
  // Create component with provided arguments
  const component = await Promise.resolve(
    componentFactory(...factoryArgs)
  );
 
  Iif (!component) {
    throw new Error('Component factory returned null/undefined');
  }
 
  // Render with template
  return renderWithTemplate(component, options);
}
 
/**
 * Check if an object is a Coherent.js component
 * A Coherent.js component is a plain object with a single key representing an HTML tag
 * 
 * @param {any} obj - Object to check
 * @returns {boolean} True if object is a Coherent.js component
 */
export function isCoherentComponent(obj) {
  if (!obj || typeof obj !== 'object' || Array.isArray(obj)) {
    return false;
  }
 
  const keys = Object.keys(obj);
  return keys.length === 1;
}
 
/**
 * Create a standardized error response for framework integrations
 * 
 * @param {Error} error - The error that occurred
 * @param {string} context - Context where the error occurred
 * @returns {Object} Error response object
 */
export function createErrorResponse(error, context = 'rendering') {
  return {
    error: 'Internal Server Error',
    message: error.message,
    context,
    timestamp: new Date().toISOString()
  };
}