@coherent.js/fastify 1.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Thomas Drouvin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,70 @@
1
+ # @coherent.js/fastify
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@coherent.js/fastify.svg)](https://www.npmjs.com/package/@coherent.js/fastify)
4
+ [![license: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](../../LICENSE)
5
+ [![Node >= 20](https://img.shields.io/badge/node-%3E%3D20-brightgreen)](https://nodejs.org)
6
+
7
+ Fastify adapter for Coherent.js.
8
+
9
+ - ESM-only, Node 20+
10
+ - Works with `fastify@4.x`
11
+ - Designed to pair with `@coherent.js/core`
12
+
13
+ For a high-level overview and repository-wide instructions, see the root README: ../../README.md
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ pnpm add @coherent.js/fastify fastify @coherent.js/core
19
+ ```
20
+
21
+ Peer dependencies:
22
+ - `fastify` >= 4 < 6
23
+ - `@coherent.js/core`
24
+
25
+ ## Quick start
26
+
27
+ You can use `@coherent.js/core` rendering inside Fastify route handlers.
28
+
29
+ JavaScript (ESM):
30
+ ```js
31
+ import Fastify from 'fastify';
32
+ import { renderToString } from '@coherent.js/core';
33
+
34
+ const app = Fastify();
35
+
36
+ app.get('/', async (_req, reply) => {
37
+ const html = await renderToString({ div: { text: 'Hello from Fastify + Coherent' } });
38
+ reply.type('text/html').send(html);
39
+ });
40
+
41
+ app.listen({ port: 3000 });
42
+ ```
43
+
44
+ TypeScript:
45
+ ```ts
46
+ import Fastify, { FastifyRequest, FastifyReply } from 'fastify';
47
+ import { renderToString } from '@coherent.js/core';
48
+
49
+ const app = Fastify();
50
+
51
+ app.get('/', async (_req: FastifyRequest, reply: FastifyReply) => {
52
+ const html = await renderToString({ div: { text: 'Hello TS' } });
53
+ reply.type('text/html').send(html);
54
+ });
55
+
56
+ app.listen({ port: 3000 });
57
+ ```
58
+
59
+ ## Development
60
+
61
+ ```bash
62
+ pnpm --filter @coherent.js/fastify run test
63
+ pnpm --filter @coherent.js/fastify run test:watch
64
+ pnpm --filter @coherent.js/fastify run typecheck
65
+ pnpm --filter @coherent.js/fastify run build
66
+ ```
67
+
68
+ ## License
69
+
70
+ MIT © Coherent.js Team
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Fastify plugin for Coherent.js
3
+ * Automatically renders Coherent.js components and handles errors
4
+ *
5
+ * @param {Object} fastify - Fastify instance
6
+ * @param {Object} options - Plugin options
7
+ * @param {boolean} options.enablePerformanceMonitoring - Enable performance monitoring
8
+ * @param {string} options.template - HTML template with {{content}} placeholder
9
+ * @param {Function} done - Callback to signal plugin registration completion
10
+ */
11
+ export function coherentFastify(fastify: Object, options: {
12
+ enablePerformanceMonitoring: boolean;
13
+ template: string;
14
+ }, done: Function): void;
15
+ /**
16
+ * Create a Fastify route handler for Coherent.js components
17
+ *
18
+ * @param {Function} componentFactory - Function that returns a Coherent.js component
19
+ * @param {Object} options - Handler options
20
+ * @returns {Function} Fastify route handler
21
+ */
22
+ export function createCoherentFastifyHandler(componentFactory: Function, options?: Object): Function;
23
+ /**
24
+ * Setup Coherent.js with Fastify instance
25
+ *
26
+ * @param {Object} fastify - Fastify instance
27
+ * @param {Object} options - Setup options
28
+ */
29
+ export function setupCoherentFastify(fastify: Object, options?: Object): void;
30
+ export default coherentFastify;
31
+ //# sourceMappingURL=coherent-fastify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coherent-fastify.d.ts","sourceRoot":"","sources":["../../../../src/fastify/coherent-fastify.js"],"names":[],"mappings":"AAQA;;;;;;;;;GASG;AACH,yCANW,MAAM,WAEd;IAAyB,2BAA2B,EAA5C,OAAO;IACS,QAAQ,EAAxB,MAAM;CACd,wBAmFF;AAED;;;;;;GAMG;AACH,mFAHW,MAAM,YAyChB;AAED;;;;;GAKG;AACH,8CAHW,MAAM,YACN,MAAM,QAIhB"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Fastify integration for Coherent.js
3
+ * Provides plugins and utilities for using Coherent.js with Fastify
4
+ */
5
+ import { renderToString } from '../rendering/html-renderer.js';
6
+ import { performanceMonitor } from '../performance/monitor.js';
7
+ /**
8
+ * Fastify plugin for Coherent.js
9
+ * Automatically renders Coherent.js components and handles errors
10
+ *
11
+ * @param {Object} fastify - Fastify instance
12
+ * @param {Object} options - Plugin options
13
+ * @param {boolean} options.enablePerformanceMonitoring - Enable performance monitoring
14
+ * @param {string} options.template - HTML template with {{content}} placeholder
15
+ * @param {Function} done - Callback to signal plugin registration completion
16
+ */
17
+ export function coherentFastify(fastify, options, done) {
18
+ const { enablePerformanceMonitoring = false, template = '<!DOCTYPE html>\n{{content}}' } = options;
19
+ // Add decorator to check if an object is a Coherent.js component
20
+ fastify.decorateReply('isCoherentObject', (obj) => {
21
+ if (!obj || typeof obj !== 'object' || Array.isArray(obj)) {
22
+ return false;
23
+ }
24
+ const keys = Object.keys(obj);
25
+ return keys.length === 1;
26
+ });
27
+ // Add decorator for rendering Coherent.js components
28
+ fastify.decorateReply('coherent', function (component, renderOptions = {}) {
29
+ const { enablePerformanceMonitoring: renderPerformanceMonitoring = enablePerformanceMonitoring, template: renderTemplate = template } = renderOptions;
30
+ try {
31
+ let html;
32
+ if (renderPerformanceMonitoring) {
33
+ const renderId = performanceMonitor.startRender();
34
+ html = renderToString(component);
35
+ performanceMonitor.endRender(renderId);
36
+ }
37
+ else {
38
+ html = renderToString(component);
39
+ }
40
+ // Apply template
41
+ const finalHtml = renderTemplate.replace('{{content}}', html);
42
+ // Set content type and send HTML
43
+ this.header('Content-Type', 'text/html; charset=utf-8');
44
+ this.send(finalHtml);
45
+ }
46
+ catch (error) {
47
+ console.error('Coherent.js rendering error:', error);
48
+ this.status(500).send({
49
+ error: 'Internal Server Error',
50
+ message: error.message
51
+ });
52
+ }
53
+ });
54
+ // Hook to automatically render Coherent.js objects
55
+ fastify.addHook('onSend', async (request, reply, payload) => {
56
+ // If payload is a Coherent.js object, render it
57
+ if (reply.isCoherentObject(payload)) {
58
+ try {
59
+ let html;
60
+ if (enablePerformanceMonitoring) {
61
+ const renderId = performanceMonitor.startRender();
62
+ html = renderToString(payload);
63
+ performanceMonitor.endRender(renderId);
64
+ }
65
+ else {
66
+ html = renderToString(payload);
67
+ }
68
+ // Apply template
69
+ const finalHtml = template.replace('{{content}}', html);
70
+ // Set content type and return HTML
71
+ reply.header('Content-Type', 'text/html; charset=utf-8');
72
+ return finalHtml;
73
+ }
74
+ catch (error) {
75
+ console.error('Coherent.js rendering error:', error);
76
+ throw error;
77
+ }
78
+ }
79
+ // For non-Coherent.js data, return as-is
80
+ return payload;
81
+ });
82
+ done();
83
+ }
84
+ /**
85
+ * Create a Fastify route handler for Coherent.js components
86
+ *
87
+ * @param {Function} componentFactory - Function that returns a Coherent.js component
88
+ * @param {Object} options - Handler options
89
+ * @returns {Function} Fastify route handler
90
+ */
91
+ export function createCoherentFastifyHandler(componentFactory, options = {}) {
92
+ const { enablePerformanceMonitoring = false, template = '<!DOCTYPE html>\n{{content}}' } = options;
93
+ return async (request, reply) => {
94
+ try {
95
+ // Create component with request data
96
+ const component = await Promise.resolve(componentFactory(request, reply));
97
+ if (!component) {
98
+ throw new Error('Component factory returned null/undefined');
99
+ }
100
+ // Render component
101
+ let html;
102
+ if (enablePerformanceMonitoring) {
103
+ const renderId = performanceMonitor.startRender();
104
+ html = renderToString(component);
105
+ performanceMonitor.endRender(renderId);
106
+ }
107
+ else {
108
+ html = renderToString(component);
109
+ }
110
+ // Apply template
111
+ const finalHtml = template.replace('{{content}}', html);
112
+ // Send HTML response
113
+ reply.header('Content-Type', 'text/html; charset=utf-8');
114
+ return finalHtml;
115
+ }
116
+ catch (error) {
117
+ console.error('Coherent.js handler error:', error);
118
+ throw error;
119
+ }
120
+ };
121
+ }
122
+ /**
123
+ * Setup Coherent.js with Fastify instance
124
+ *
125
+ * @param {Object} fastify - Fastify instance
126
+ * @param {Object} options - Setup options
127
+ */
128
+ export function setupCoherentFastify(fastify, options = {}) {
129
+ fastify.register(coherentFastify, options);
130
+ }
131
+ // Export plugin as default for Fastify's plugin system
132
+ export default coherentFastify;
133
+ //# sourceMappingURL=coherent-fastify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coherent-fastify.js","sourceRoot":"","sources":["../../../../src/fastify/coherent-fastify.js"],"names":[],"mappings":"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"}