@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 +21 -0
- package/README.md +70 -0
- package/dist/fastify/coherent-fastify.d.ts +31 -0
- package/dist/fastify/coherent-fastify.d.ts.map +1 -0
- package/dist/fastify/coherent-fastify.js +133 -0
- package/dist/fastify/coherent-fastify.js.map +1 -0
- package/dist/index.cjs +1708 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.js +1669 -0
- package/dist/index.js.map +7 -0
- package/package.json +46 -0
- package/types/index.d.ts +362 -0
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
|
+
[](https://www.npmjs.com/package/@coherent.js/fastify)
|
|
4
|
+
[](../../LICENSE)
|
|
5
|
+
[](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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"}
|