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 | 2x 2x 2x 2x 2x 1x 1x | /**
* Fastify integration for Coherent.js
* Provides plugins and utilities for using Coherent.js with Fastify
*/
import {
renderWithTemplate,
renderComponentFactory
} from '@coherent.js/core';
/**
* 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 {
// Use shared rendering utility
const finalHtml = renderWithTemplate(component, {
enablePerformanceMonitoring: renderPerformanceMonitoring,
template: renderTemplate
});
// 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 {
// Use shared rendering utility
const finalHtml = renderWithTemplate(payload, { enablePerformanceMonitoring, template });
// 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 createHandler(componentFactory, options = {}) {
return async (request, reply) => {
try {
// Use shared rendering utility
const finalHtml = await renderComponentFactory(
componentFactory,
[request, reply],
options
);
// 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 setupCoherent(fastify, options = {}) {
fastify.register(coherentFastify, options);
}
// Export plugin as default for Fastify's plugin system
export default coherentFastify;
|