@coherent.js/adapters 1.0.0-beta.6 → 1.0.0-beta.7
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/package.json +10 -3
- package/src/astro.js +66 -5
- package/src/index.js +3 -3
- package/src/remix.js +66 -9
- package/src/sveltekit.js +99 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coherent.js/adapters",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.7",
|
|
4
4
|
"description": "Framework adapters for Coherent.js (Astro, Remix, SvelteKit)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
],
|
|
29
29
|
"author": "Coherent.js Team",
|
|
30
30
|
"license": "MIT",
|
|
31
|
-
"
|
|
32
|
-
"@coherent.js/core": "1.0.0-beta.
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"@coherent.js/core": "1.0.0-beta.7"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"vitest": "^4.0.8"
|
|
@@ -38,10 +38,17 @@
|
|
|
38
38
|
"type": "git",
|
|
39
39
|
"url": "git+https://github.com/Tomdrouv1/coherent.js.git"
|
|
40
40
|
},
|
|
41
|
+
"homepage": "https://github.com/Tomdrouv1/coherent.js",
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/Tomdrouv1/coherent.js/issues"
|
|
44
|
+
},
|
|
41
45
|
"publishConfig": {
|
|
42
46
|
"access": "public",
|
|
43
47
|
"registry": "https://registry.npmjs.org/"
|
|
44
48
|
},
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=20.0.0"
|
|
51
|
+
},
|
|
45
52
|
"sideEffects": false,
|
|
46
53
|
"scripts": {
|
|
47
54
|
"build": "node build.mjs",
|
package/src/astro.js
CHANGED
|
@@ -1,23 +1,84 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Astro Integration for Coherent.js
|
|
3
|
+
*
|
|
4
|
+
* Provides server-side rendering of Coherent.js components within Astro projects.
|
|
3
5
|
*/
|
|
4
6
|
|
|
5
7
|
import { render } from '@coherent.js/core';
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Create an Astro integration for Coherent.js
|
|
11
|
+
*
|
|
12
|
+
* @param {Object} [options] - Integration options
|
|
13
|
+
* @param {boolean} [options.hydrate] - Enable client-side hydration
|
|
14
|
+
* @param {string} [options.hydrateScript] - Custom hydration script path
|
|
15
|
+
* @returns {Object} Astro integration configuration
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* // astro.config.mjs
|
|
19
|
+
* import { createAstroIntegration } from '@coherent.js/adapters/astro';
|
|
20
|
+
* export default { integrations: [createAstroIntegration()] };
|
|
21
|
+
*/
|
|
22
|
+
export function createAstroIntegration(options = {}) {
|
|
8
23
|
return {
|
|
9
24
|
name: 'coherent',
|
|
10
25
|
hooks: {
|
|
11
|
-
'astro:config:setup': ({ addRenderer }) => {
|
|
26
|
+
'astro:config:setup': ({ addRenderer, updateConfig }) => {
|
|
12
27
|
addRenderer({
|
|
13
28
|
name: '@coherent.js/adapters/astro',
|
|
14
|
-
serverEntrypoint: '@coherent.js/adapters/astro
|
|
29
|
+
serverEntrypoint: '@coherent.js/adapters/astro',
|
|
15
30
|
});
|
|
31
|
+
|
|
32
|
+
if (options.hydrate) {
|
|
33
|
+
updateConfig({
|
|
34
|
+
vite: {
|
|
35
|
+
optimizeDeps: {
|
|
36
|
+
include: ['@coherent.js/client']
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
'astro:build:done': ({ logger }) => {
|
|
43
|
+
logger?.info('Coherent.js components built successfully');
|
|
16
44
|
}
|
|
17
45
|
}
|
|
18
46
|
};
|
|
19
47
|
}
|
|
20
48
|
|
|
21
|
-
|
|
22
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Render a Coherent.js component to HTML string
|
|
51
|
+
*
|
|
52
|
+
* @param {Function|Object} Component - Coherent.js component
|
|
53
|
+
* @param {Object} [props] - Component props
|
|
54
|
+
* @param {Object} [renderOptions] - Rendering options
|
|
55
|
+
* @returns {string} Rendered HTML
|
|
56
|
+
*/
|
|
57
|
+
export function renderComponent(Component, props = {}, renderOptions = {}) {
|
|
58
|
+
const componentDef = typeof Component === 'function'
|
|
59
|
+
? Component(props)
|
|
60
|
+
: Component;
|
|
61
|
+
|
|
62
|
+
return render(componentDef, renderOptions);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Create a server-side component renderer for Astro
|
|
67
|
+
*
|
|
68
|
+
* @param {Object} [options] - Renderer options
|
|
69
|
+
* @returns {Object} Astro renderer configuration
|
|
70
|
+
*/
|
|
71
|
+
export function createRenderer(options = {}) {
|
|
72
|
+
return {
|
|
73
|
+
name: '@coherent.js/astro-renderer',
|
|
74
|
+
check(Component) {
|
|
75
|
+
// Check if this looks like a Coherent.js component (function or plain object with tag keys)
|
|
76
|
+
return typeof Component === 'function' ||
|
|
77
|
+
(typeof Component === 'object' && Component !== null && !Array.isArray(Component));
|
|
78
|
+
},
|
|
79
|
+
renderToStaticMarkup(Component, props) {
|
|
80
|
+
const html = renderComponent(Component, props, options);
|
|
81
|
+
return { html };
|
|
82
|
+
}
|
|
83
|
+
};
|
|
23
84
|
}
|
package/src/index.js
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
* Integrations for modern web frameworks
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
export { createAstroIntegration } from './astro.js';
|
|
7
|
-
export { createRemixAdapter } from './remix.js';
|
|
8
|
-
export { createSvelteKitAdapter } from './sveltekit.js';
|
|
6
|
+
export { createAstroIntegration, renderComponent, createRenderer } from './astro.js';
|
|
7
|
+
export { createRemixAdapter, withCoherent } from './remix.js';
|
|
8
|
+
export { createSvelteKitAdapter, createPreprocessor, createHandle } from './sveltekit.js';
|
package/src/remix.js
CHANGED
|
@@ -1,25 +1,82 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Remix Adapter for Coherent.js
|
|
3
|
+
*
|
|
4
|
+
* Provides SSR integration and loader utilities for Remix projects.
|
|
3
5
|
*/
|
|
4
6
|
|
|
5
7
|
import { render } from '@coherent.js/core';
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Create a Remix adapter for Coherent.js
|
|
11
|
+
*
|
|
12
|
+
* @param {Object} [options] - Adapter options
|
|
13
|
+
* @param {boolean} [options.hydrate] - Enable client-side hydration
|
|
14
|
+
* @returns {Object} Remix adapter utilities
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* const adapter = createRemixAdapter();
|
|
18
|
+
* const html = adapter.renderComponent(MyComponent, { title: 'Hello' });
|
|
19
|
+
*/
|
|
20
|
+
export function createRemixAdapter(options = {}) {
|
|
8
21
|
return {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Render a Coherent.js component to HTML
|
|
24
|
+
*/
|
|
25
|
+
renderComponent(component, props = {}) {
|
|
26
|
+
const def = typeof component === 'function' ? component(props) : component;
|
|
27
|
+
return render(def);
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Create a Remix loader that renders a Coherent.js component
|
|
32
|
+
*/
|
|
33
|
+
createLoader(component, getProps) {
|
|
34
|
+
return async ({ request, params, context }) => {
|
|
35
|
+
const props = getProps
|
|
36
|
+
? await getProps({ request, params, context })
|
|
37
|
+
: { request, params };
|
|
38
|
+
|
|
39
|
+
const def = typeof component === 'function' ? component(props) : component;
|
|
40
|
+
const html = render(def);
|
|
41
|
+
|
|
42
|
+
return new Response(html, {
|
|
43
|
+
headers: { 'Content-Type': 'text/html; charset=utf-8' }
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Create a Remix action handler that processes form data
|
|
50
|
+
* and renders a Coherent.js component with the result
|
|
51
|
+
*/
|
|
52
|
+
createAction(component, handler) {
|
|
53
|
+
return async ({ request, params, context }) => {
|
|
54
|
+
const formData = await request.formData();
|
|
55
|
+
const data = Object.fromEntries(formData);
|
|
56
|
+
const result = await handler({ data, request, params, context });
|
|
57
|
+
|
|
58
|
+
if (result instanceof Response) return result;
|
|
59
|
+
|
|
60
|
+
const def = typeof component === 'function' ? component(result) : component;
|
|
61
|
+
const html = render(def);
|
|
62
|
+
|
|
63
|
+
return new Response(html, {
|
|
64
|
+
headers: { 'Content-Type': 'text/html; charset=utf-8' }
|
|
65
|
+
});
|
|
16
66
|
};
|
|
17
67
|
}
|
|
18
68
|
};
|
|
19
69
|
}
|
|
20
70
|
|
|
71
|
+
/**
|
|
72
|
+
* HOC: Wrap a Coherent.js component for use in Remix routes
|
|
73
|
+
*
|
|
74
|
+
* @param {Function} Component - Coherent.js component function
|
|
75
|
+
* @returns {Function} Remix-compatible component
|
|
76
|
+
*/
|
|
21
77
|
export function withCoherent(Component) {
|
|
22
78
|
return function CoherentRemixComponent(props) {
|
|
23
|
-
|
|
79
|
+
const def = typeof Component === 'function' ? Component(props) : Component;
|
|
80
|
+
return render(def);
|
|
24
81
|
};
|
|
25
82
|
}
|
package/src/sveltekit.js
CHANGED
|
@@ -1,24 +1,117 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SvelteKit Adapter for Coherent.js
|
|
3
|
+
*
|
|
4
|
+
* Provides server-side rendering and preprocessor integration for SvelteKit projects.
|
|
3
5
|
*/
|
|
4
6
|
|
|
5
7
|
import { render } from '@coherent.js/core';
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Create a SvelteKit adapter for Coherent.js
|
|
11
|
+
*
|
|
12
|
+
* @param {Object} [options] - Adapter options
|
|
13
|
+
* @returns {Object} SvelteKit adapter utilities
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* const adapter = createSvelteKitAdapter();
|
|
17
|
+
* const html = adapter.renderComponent(MyComponent, { title: 'Hello' });
|
|
18
|
+
*/
|
|
19
|
+
export function createSvelteKitAdapter(options = {}) {
|
|
8
20
|
return {
|
|
9
21
|
name: '@coherent.js/sveltekit',
|
|
10
|
-
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Render a Coherent.js component to HTML
|
|
25
|
+
*/
|
|
26
|
+
renderComponent(component, props = {}) {
|
|
27
|
+
const def = typeof component === 'function' ? component(props) : component;
|
|
28
|
+
return render(def);
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Create a SvelteKit server load function
|
|
33
|
+
*/
|
|
34
|
+
createLoad(component, getProps) {
|
|
35
|
+
return async ({ params, url, fetch }) => {
|
|
36
|
+
const props = getProps
|
|
37
|
+
? await getProps({ params, url, fetch })
|
|
38
|
+
: { params };
|
|
39
|
+
|
|
40
|
+
const def = typeof component === 'function' ? component(props) : component;
|
|
41
|
+
const html = render(def);
|
|
42
|
+
|
|
43
|
+
return { html, props };
|
|
44
|
+
};
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Create a SvelteKit form action handler
|
|
49
|
+
*/
|
|
50
|
+
createAction(handler) {
|
|
51
|
+
return async ({ request, params }) => {
|
|
52
|
+
const formData = await request.formData();
|
|
53
|
+
const data = Object.fromEntries(formData);
|
|
54
|
+
return handler({ data, params });
|
|
55
|
+
};
|
|
56
|
+
}
|
|
11
57
|
};
|
|
12
58
|
}
|
|
13
59
|
|
|
14
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Create a Svelte preprocessor for Coherent.js templates
|
|
62
|
+
*
|
|
63
|
+
* Transforms inline Coherent.js object syntax within Svelte components.
|
|
64
|
+
*
|
|
65
|
+
* @param {Object} [options] - Preprocessor options
|
|
66
|
+
* @param {string} [options.tag] - Custom tag to process (default: 'coherent')
|
|
67
|
+
* @returns {Object} Svelte preprocessor
|
|
68
|
+
*/
|
|
69
|
+
export function createPreprocessor(options = {}) {
|
|
70
|
+
const tag = options.tag || 'coherent';
|
|
71
|
+
|
|
15
72
|
return {
|
|
16
73
|
name: 'coherent-preprocessor',
|
|
17
|
-
markup({ content,
|
|
18
|
-
//
|
|
74
|
+
markup({ content, filename }) {
|
|
75
|
+
// Find <coherent> blocks and render them to HTML
|
|
76
|
+
const regex = new RegExp(`<${tag}>(.*?)</${tag}>`, 'gs');
|
|
77
|
+
let transformed = content;
|
|
78
|
+
let match;
|
|
79
|
+
|
|
80
|
+
while ((match = regex.exec(content)) !== null) {
|
|
81
|
+
try {
|
|
82
|
+
// The content inside <coherent> tags should be a JS object literal
|
|
83
|
+
// This is a basic transform — production use should handle more cases
|
|
84
|
+
const objectStr = match[1].trim();
|
|
85
|
+
transformed = transformed.replace(match[0], `{@html coherentRender(${objectStr})}`);
|
|
86
|
+
} catch {
|
|
87
|
+
// Leave unchanged if parsing fails
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
19
91
|
return {
|
|
20
|
-
code:
|
|
92
|
+
code: transformed,
|
|
93
|
+
map: null
|
|
21
94
|
};
|
|
22
95
|
}
|
|
23
96
|
};
|
|
24
97
|
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* SvelteKit hooks integration
|
|
101
|
+
*
|
|
102
|
+
* @param {Object} [options] - Hook options
|
|
103
|
+
* @returns {Object} SvelteKit handle function
|
|
104
|
+
*/
|
|
105
|
+
export function createHandle(options = {}) {
|
|
106
|
+
return async ({ event, resolve }) => {
|
|
107
|
+
// Add Coherent.js render function to locals
|
|
108
|
+
event.locals.coherent = {
|
|
109
|
+
render(component, props = {}) {
|
|
110
|
+
const def = typeof component === 'function' ? component(props) : component;
|
|
111
|
+
return render(def);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
return resolve(event);
|
|
116
|
+
};
|
|
117
|
+
}
|