@ecopages/kitajs 0.2.0-alpha.1
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/CHANGELOG.md +21 -0
- package/LICENSE +21 -0
- package/README.md +25 -0
- package/package.json +24 -0
- package/src/kitajs-renderer.d.ts +21 -0
- package/src/kitajs-renderer.js +85 -0
- package/src/kitajs-renderer.ts +130 -0
- package/src/kitajs.plugin.d.ts +20 -0
- package/src/kitajs.plugin.js +21 -0
- package/src/kitajs.plugin.ts +32 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@ecopages/kitajs` are documented here.
|
|
4
|
+
|
|
5
|
+
> **Note:** Changelog tracking begins at version `0.2.0`. Changes prior to this release are not recorded here but are available in the git history.
|
|
6
|
+
|
|
7
|
+
## [UNRELEASED] — TBD
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
- Aligned KitaJS renderer with full orchestration mode — removed legacy rendering path (`fc07bdb0`).
|
|
12
|
+
|
|
13
|
+
### Refactoring
|
|
14
|
+
|
|
15
|
+
- **Type safety improvements** — Enhanced type safety for component signatures; test component creation helpers are now more accurately typed (`574657eb`).
|
|
16
|
+
- Ambient module declarations cleaned up (`5f46ecc5`).
|
|
17
|
+
- Updated test suite for esbuild adapter and Node.js runtime compatibility (`31a44458`).
|
|
18
|
+
|
|
19
|
+
### Tests
|
|
20
|
+
|
|
21
|
+
- Updated integration tests to align with the new orchestration model.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-present Andrea Zanenghi
|
|
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,25 @@
|
|
|
1
|
+
# Ecopages KitaJs Integration Plugin
|
|
2
|
+
|
|
3
|
+
The `@ecopages/kitajs` package provides seamless integration with [Kita](https://kitajs.org/html/), enabling effortless rendering of JSX templates. This integration represents a minimalistic layer within the broader Ecopages integration plugin system, designed to enhance the platform's flexibility and ease of use.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bunx jsr add @ecopages/kitajs
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
Incorporating this integration into your project is straightforward. Simply import and include the `kitajsPlugin` in your Ecopages configuration as shown below:
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { ConfigBuilder } from '@ecopages/core';
|
|
17
|
+
import { kitajsPlugin } from '@ecopages/kitajs';
|
|
18
|
+
|
|
19
|
+
const config = await new ConfigBuilder()
|
|
20
|
+
.setBaseUrl(import.meta.env.ECOPAGES_BASE_URL)
|
|
21
|
+
.setIntegrations([kitajsPlugin()])
|
|
22
|
+
.build();
|
|
23
|
+
|
|
24
|
+
export default config;
|
|
25
|
+
```
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ecopages/kitajs",
|
|
3
|
+
"version": "0.2.0-alpha.1",
|
|
4
|
+
"description": "Kitajs plugin for Ecopages",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"ecopages",
|
|
7
|
+
"kitajs",
|
|
8
|
+
"plugin"
|
|
9
|
+
],
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"main": "./src/kitajs.plugin.js",
|
|
12
|
+
"types": "./src/kitajs.plugin.d.ts",
|
|
13
|
+
"type": "module",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/ecopages/ecopages.git",
|
|
17
|
+
"directory": "packages/integrations/kitajs"
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"@ecopages/core": "0.2.0-alpha.1",
|
|
21
|
+
"@kitajs/html": "^4.1.0",
|
|
22
|
+
"@kitajs/ts-html-plugin": "^4.0.1"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This module contains the Kita.js renderer
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
import type { ComponentRenderInput, ComponentRenderResult, EcoComponent, EcoPagesElement, IntegrationRendererRenderOptions, RouteRendererBody } from '@ecopages/core';
|
|
6
|
+
import { IntegrationRenderer, type RenderToResponseContext } from '@ecopages/core/route-renderer/integration-renderer';
|
|
7
|
+
/**
|
|
8
|
+
* A renderer for the Kita.js integration.
|
|
9
|
+
* It renders a page using the HtmlTemplate and Page components.
|
|
10
|
+
*/
|
|
11
|
+
export declare class KitaRenderer extends IntegrationRenderer<EcoPagesElement> {
|
|
12
|
+
name: string;
|
|
13
|
+
/**
|
|
14
|
+
* Renders a Kita component boundary for component-level orchestration.
|
|
15
|
+
*
|
|
16
|
+
* Includes component-scoped dependency assets when declared.
|
|
17
|
+
*/
|
|
18
|
+
renderComponent(input: ComponentRenderInput): Promise<ComponentRenderResult>;
|
|
19
|
+
render({ params, query, props, locals, pageLocals, metadata, Page, Layout, HtmlTemplate, }: IntegrationRendererRenderOptions): Promise<RouteRendererBody>;
|
|
20
|
+
renderToResponse<P = Record<string, unknown>>(view: EcoComponent<P>, props: P, ctx: RenderToResponseContext): Promise<Response>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { IntegrationRenderer } from "@ecopages/core/route-renderer/integration-renderer";
|
|
2
|
+
import { PLUGIN_NAME } from "./kitajs.plugin.js";
|
|
3
|
+
class KitaRenderer extends IntegrationRenderer {
|
|
4
|
+
name = PLUGIN_NAME;
|
|
5
|
+
/**
|
|
6
|
+
* Renders a Kita component boundary for component-level orchestration.
|
|
7
|
+
*
|
|
8
|
+
* Includes component-scoped dependency assets when declared.
|
|
9
|
+
*/
|
|
10
|
+
async renderComponent(input) {
|
|
11
|
+
const component = input.component;
|
|
12
|
+
const props = input.children === void 0 ? input.props : { ...input.props, children: input.children };
|
|
13
|
+
const content = await component(props);
|
|
14
|
+
const html = String(content);
|
|
15
|
+
const hasDependencies = Boolean(input.component.config?.dependencies);
|
|
16
|
+
const canResolveAssets = typeof this.assetProcessingService?.processDependencies === "function";
|
|
17
|
+
const assets = hasDependencies && canResolveAssets ? await this.processComponentDependencies([input.component]) : void 0;
|
|
18
|
+
return {
|
|
19
|
+
html,
|
|
20
|
+
canAttachAttributes: true,
|
|
21
|
+
rootTag: this.getRootTagName(html),
|
|
22
|
+
integrationName: this.name,
|
|
23
|
+
assets
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
async render({
|
|
27
|
+
params,
|
|
28
|
+
query,
|
|
29
|
+
props,
|
|
30
|
+
locals,
|
|
31
|
+
pageLocals,
|
|
32
|
+
metadata,
|
|
33
|
+
Page,
|
|
34
|
+
Layout,
|
|
35
|
+
HtmlTemplate
|
|
36
|
+
}) {
|
|
37
|
+
try {
|
|
38
|
+
const pageContent = await Page({ params, query, ...props, locals: pageLocals });
|
|
39
|
+
const children = Layout && typeof Layout === "function" ? await Layout({ children: pageContent, locals }) : pageContent;
|
|
40
|
+
const body = await HtmlTemplate({
|
|
41
|
+
metadata,
|
|
42
|
+
pageProps: props ?? {},
|
|
43
|
+
children
|
|
44
|
+
});
|
|
45
|
+
return this.DOC_TYPE + body;
|
|
46
|
+
} catch (error) {
|
|
47
|
+
throw this.createRenderError("Error rendering page", error);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async renderToResponse(view, props, ctx) {
|
|
51
|
+
try {
|
|
52
|
+
const Layout = view.config?.layout;
|
|
53
|
+
const viewFn = view;
|
|
54
|
+
const pageContent = await viewFn(props);
|
|
55
|
+
if (ctx.partial) {
|
|
56
|
+
return this.createHtmlResponse(pageContent, ctx);
|
|
57
|
+
}
|
|
58
|
+
const children = Layout ? await Layout({ children: pageContent }) : pageContent;
|
|
59
|
+
const HtmlTemplate = await this.getHtmlTemplate();
|
|
60
|
+
const metadata = view.metadata ? await view.metadata({
|
|
61
|
+
params: {},
|
|
62
|
+
query: {},
|
|
63
|
+
props,
|
|
64
|
+
appConfig: this.appConfig
|
|
65
|
+
}) : this.appConfig.defaultMetadata;
|
|
66
|
+
await this.prepareViewDependencies(view, Layout);
|
|
67
|
+
const html = this.DOC_TYPE + await HtmlTemplate({
|
|
68
|
+
metadata,
|
|
69
|
+
pageProps: props,
|
|
70
|
+
children: children ?? ""
|
|
71
|
+
});
|
|
72
|
+
const transformedResponse = await this.htmlTransformer.transform(
|
|
73
|
+
new Response(html, {
|
|
74
|
+
headers: { "Content-Type": "text/html" }
|
|
75
|
+
})
|
|
76
|
+
);
|
|
77
|
+
return this.createHtmlResponse(transformedResponse.body ?? "", ctx);
|
|
78
|
+
} catch (error) {
|
|
79
|
+
throw this.createRenderError("Error rendering view", error);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
export {
|
|
84
|
+
KitaRenderer
|
|
85
|
+
};
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This module contains the Kita.js renderer
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type {
|
|
7
|
+
ComponentRenderInput,
|
|
8
|
+
ComponentRenderResult,
|
|
9
|
+
EcoComponent,
|
|
10
|
+
EcoPagesElement,
|
|
11
|
+
IntegrationRendererRenderOptions,
|
|
12
|
+
RouteRendererBody,
|
|
13
|
+
} from '@ecopages/core';
|
|
14
|
+
import { IntegrationRenderer, type RenderToResponseContext } from '@ecopages/core/route-renderer/integration-renderer';
|
|
15
|
+
import { PLUGIN_NAME } from './kitajs.plugin.ts';
|
|
16
|
+
|
|
17
|
+
/** Narrows an EcoComponent to its KitaJS callable signature. */
|
|
18
|
+
type KitaViewFn<P> = (props: P) => Promise<EcoPagesElement> | EcoPagesElement;
|
|
19
|
+
|
|
20
|
+
/** KitaJS layout function signature. */
|
|
21
|
+
type KitaLayoutFn = (props: { children: EcoPagesElement } & Record<string, unknown>) => Promise<EcoPagesElement>;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* A renderer for the Kita.js integration.
|
|
25
|
+
* It renders a page using the HtmlTemplate and Page components.
|
|
26
|
+
*/
|
|
27
|
+
export class KitaRenderer extends IntegrationRenderer<EcoPagesElement> {
|
|
28
|
+
name = PLUGIN_NAME;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Renders a Kita component boundary for component-level orchestration.
|
|
32
|
+
*
|
|
33
|
+
* Includes component-scoped dependency assets when declared.
|
|
34
|
+
*/
|
|
35
|
+
override async renderComponent(input: ComponentRenderInput): Promise<ComponentRenderResult> {
|
|
36
|
+
const component = input.component as KitaViewFn<Record<string, unknown>>;
|
|
37
|
+
const props = input.children === undefined ? input.props : { ...input.props, children: input.children };
|
|
38
|
+
const content = await component(props);
|
|
39
|
+
const html = String(content);
|
|
40
|
+
const hasDependencies = Boolean(input.component.config?.dependencies);
|
|
41
|
+
const canResolveAssets = typeof this.assetProcessingService?.processDependencies === 'function';
|
|
42
|
+
const assets =
|
|
43
|
+
hasDependencies && canResolveAssets
|
|
44
|
+
? await this.processComponentDependencies([input.component])
|
|
45
|
+
: undefined;
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
html,
|
|
49
|
+
canAttachAttributes: true,
|
|
50
|
+
rootTag: this.getRootTagName(html),
|
|
51
|
+
integrationName: this.name,
|
|
52
|
+
assets,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async render({
|
|
57
|
+
params,
|
|
58
|
+
query,
|
|
59
|
+
props,
|
|
60
|
+
locals,
|
|
61
|
+
pageLocals,
|
|
62
|
+
metadata,
|
|
63
|
+
Page,
|
|
64
|
+
Layout,
|
|
65
|
+
HtmlTemplate,
|
|
66
|
+
}: IntegrationRendererRenderOptions): Promise<RouteRendererBody> {
|
|
67
|
+
try {
|
|
68
|
+
const pageContent = await Page({ params, query, ...props, locals: pageLocals });
|
|
69
|
+
const children =
|
|
70
|
+
Layout && typeof Layout === 'function' ? await Layout({ children: pageContent, locals }) : pageContent;
|
|
71
|
+
const body = await HtmlTemplate({
|
|
72
|
+
metadata,
|
|
73
|
+
pageProps: props ?? {},
|
|
74
|
+
children,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
return this.DOC_TYPE + body;
|
|
78
|
+
} catch (error) {
|
|
79
|
+
throw this.createRenderError('Error rendering page', error);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async renderToResponse<P = Record<string, unknown>>(
|
|
84
|
+
view: EcoComponent<P>,
|
|
85
|
+
props: P,
|
|
86
|
+
ctx: RenderToResponseContext,
|
|
87
|
+
): Promise<Response> {
|
|
88
|
+
try {
|
|
89
|
+
const Layout = view.config?.layout as KitaLayoutFn | undefined;
|
|
90
|
+
|
|
91
|
+
const viewFn = view as KitaViewFn<P>;
|
|
92
|
+
const pageContent = await viewFn(props);
|
|
93
|
+
|
|
94
|
+
if (ctx.partial) {
|
|
95
|
+
return this.createHtmlResponse(pageContent, ctx);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const children = Layout ? await Layout({ children: pageContent }) : pageContent;
|
|
99
|
+
|
|
100
|
+
const HtmlTemplate = await this.getHtmlTemplate();
|
|
101
|
+
const metadata = view.metadata
|
|
102
|
+
? await view.metadata({
|
|
103
|
+
params: {},
|
|
104
|
+
query: {},
|
|
105
|
+
props: props as Record<string, unknown>,
|
|
106
|
+
appConfig: this.appConfig,
|
|
107
|
+
})
|
|
108
|
+
: this.appConfig.defaultMetadata;
|
|
109
|
+
await this.prepareViewDependencies(view, Layout as EcoComponent | undefined);
|
|
110
|
+
|
|
111
|
+
const html =
|
|
112
|
+
this.DOC_TYPE +
|
|
113
|
+
(await HtmlTemplate({
|
|
114
|
+
metadata,
|
|
115
|
+
pageProps: props as Record<string, unknown>,
|
|
116
|
+
children: children ?? '',
|
|
117
|
+
}));
|
|
118
|
+
|
|
119
|
+
const transformedResponse = await this.htmlTransformer.transform(
|
|
120
|
+
new Response(html, {
|
|
121
|
+
headers: { 'Content-Type': 'text/html' },
|
|
122
|
+
}),
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
return this.createHtmlResponse(transformedResponse.body ?? '', ctx);
|
|
126
|
+
} catch (error) {
|
|
127
|
+
throw this.createRenderError('Error rendering view', error);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { IntegrationPlugin, type IntegrationPluginConfig } from '@ecopages/core/plugins/integration-plugin';
|
|
2
|
+
import { KitaRenderer } from './kitajs-renderer.js';
|
|
3
|
+
/**
|
|
4
|
+
* The name of the Kita.js plugin
|
|
5
|
+
*/
|
|
6
|
+
export declare const PLUGIN_NAME = "kitajs";
|
|
7
|
+
/**
|
|
8
|
+
* The Kita.js plugin class
|
|
9
|
+
* This plugin provides support for Kita.js components in Ecopages
|
|
10
|
+
*/
|
|
11
|
+
export declare class KitaHtmlPlugin extends IntegrationPlugin {
|
|
12
|
+
renderer: typeof KitaRenderer;
|
|
13
|
+
constructor(options?: Omit<IntegrationPluginConfig, 'name'>);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Factory function to create a Kita.js plugin instance.
|
|
17
|
+
* @param options Configuration options for the Kita.js plugin
|
|
18
|
+
* @returns A new KitaHtmlPlugin instance
|
|
19
|
+
*/
|
|
20
|
+
export declare function kitajsPlugin(options?: Omit<IntegrationPluginConfig, 'name'>): KitaHtmlPlugin;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { IntegrationPlugin } from "@ecopages/core/plugins/integration-plugin";
|
|
2
|
+
import { KitaRenderer } from "./kitajs-renderer.js";
|
|
3
|
+
const PLUGIN_NAME = "kitajs";
|
|
4
|
+
class KitaHtmlPlugin extends IntegrationPlugin {
|
|
5
|
+
renderer = KitaRenderer;
|
|
6
|
+
constructor(options) {
|
|
7
|
+
super({
|
|
8
|
+
name: PLUGIN_NAME,
|
|
9
|
+
extensions: [".kita.tsx"],
|
|
10
|
+
...options
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function kitajsPlugin(options) {
|
|
15
|
+
return new KitaHtmlPlugin(options);
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
KitaHtmlPlugin,
|
|
19
|
+
PLUGIN_NAME,
|
|
20
|
+
kitajsPlugin
|
|
21
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { IntegrationPlugin, type IntegrationPluginConfig } from '@ecopages/core/plugins/integration-plugin';
|
|
2
|
+
import { KitaRenderer } from './kitajs-renderer.ts';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The name of the Kita.js plugin
|
|
6
|
+
*/
|
|
7
|
+
export const PLUGIN_NAME = 'kitajs';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The Kita.js plugin class
|
|
11
|
+
* This plugin provides support for Kita.js components in Ecopages
|
|
12
|
+
*/
|
|
13
|
+
export class KitaHtmlPlugin extends IntegrationPlugin {
|
|
14
|
+
renderer = KitaRenderer;
|
|
15
|
+
|
|
16
|
+
constructor(options?: Omit<IntegrationPluginConfig, 'name'>) {
|
|
17
|
+
super({
|
|
18
|
+
name: PLUGIN_NAME,
|
|
19
|
+
extensions: ['.kita.tsx'],
|
|
20
|
+
...options,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Factory function to create a Kita.js plugin instance.
|
|
27
|
+
* @param options Configuration options for the Kita.js plugin
|
|
28
|
+
* @returns A new KitaHtmlPlugin instance
|
|
29
|
+
*/
|
|
30
|
+
export function kitajsPlugin(options?: Omit<IntegrationPluginConfig, 'name'>): KitaHtmlPlugin {
|
|
31
|
+
return new KitaHtmlPlugin(options);
|
|
32
|
+
}
|