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 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | /** * Fastify integration for Coherent.js * Provides plugins and utilities for using Coherent.js with Fastify */ import { renderToString } from '../rendering/html-renderer.js'; import { performanceMonitor } from '../performance/monitor.js'; /** * Fastify plugin for Coherent.js * Automatically renders Coherent.js components and handles errors * * @param {Object} fastify - Fastify instance * @param {Object} options - Plugin options * @param {boolean} options.enablePerformanceMonitoring - Enable performance monitoring * @param {string} options.template - HTML template with {{content}} placeholder * @param {Function} done - Callback to signal plugin registration completion */ export function coherentFastify(fastify, options, done) { const { enablePerformanceMonitoring = false, template = '<!DOCTYPE html>\n{{content}}' } = options; // Add decorator to check if an object is a Coherent.js component fastify.decorateReply('isCoherentObject', (obj) => { if (!obj || typeof obj !== 'object' || Array.isArray(obj)) { return false; } const keys = Object.keys(obj); return keys.length === 1; }); // Add decorator for rendering Coherent.js components fastify.decorateReply('coherent', function(component, renderOptions = {}) { const { enablePerformanceMonitoring: renderPerformanceMonitoring = enablePerformanceMonitoring, template: renderTemplate = template } = renderOptions; try { let html; if (renderPerformanceMonitoring) { const renderId = performanceMonitor.startRender(); html = renderToString(component); performanceMonitor.endRender(renderId); } else { html = renderToString(component); } // Apply template const finalHtml = renderTemplate.replace('{{content}}', html); // Set content type and send HTML this.header('Content-Type', 'text/html; charset=utf-8'); this.send(finalHtml); } catch (error) { console.error('Coherent.js rendering error:', error); this.status(500).send({ error: 'Internal Server Error', message: error.message }); } }); // Hook to automatically render Coherent.js objects fastify.addHook('onSend', async (request, reply, payload) => { // If payload is a Coherent.js object, render it if (reply.isCoherentObject(payload)) { try { let html; if (enablePerformanceMonitoring) { const renderId = performanceMonitor.startRender(); html = renderToString(payload); performanceMonitor.endRender(renderId); } else { html = renderToString(payload); } // Apply template const finalHtml = template.replace('{{content}}', html); // Set content type and return HTML reply.header('Content-Type', 'text/html; charset=utf-8'); return finalHtml; } catch (error) { console.error('Coherent.js rendering error:', error); throw error; } } // For non-Coherent.js data, return as-is return payload; }); done(); } /** * Create a Fastify route handler for Coherent.js components * * @param {Function} componentFactory - Function that returns a Coherent.js component * @param {Object} options - Handler options * @returns {Function} Fastify route handler */ export function createCoherentFastifyHandler(componentFactory, options = {}) { const { enablePerformanceMonitoring = false, template = '<!DOCTYPE html>\n{{content}}' } = options; return async (request, reply) => { try { // Create component with request data const component = await Promise.resolve( componentFactory(request, reply) ); if (!component) { throw new Error('Component factory returned null/undefined'); } // Render component let html; if (enablePerformanceMonitoring) { const renderId = performanceMonitor.startRender(); html = renderToString(component); performanceMonitor.endRender(renderId); } else { html = renderToString(component); } // Apply template const finalHtml = template.replace('{{content}}', html); // Send HTML response reply.header('Content-Type', 'text/html; charset=utf-8'); return finalHtml; } catch (error) { console.error('Coherent.js handler error:', error); throw error; } }; } /** * Setup Coherent.js with Fastify instance * * @param {Object} fastify - Fastify instance * @param {Object} options - Setup options */ export function setupCoherentFastify(fastify, options = {}) { fastify.register(coherentFastify, options); } // Export plugin as default for Fastify's plugin system export default coherentFastify; |