@ecopages/ecopages-jsx 0.2.1-beta.0 → 0.3.0
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/README.md +39 -16
- package/package.json +10 -6
- package/src/dev-transform/ecopages-jsx-dev-transform-contributor.d.ts +17 -0
- package/src/dev-transform/ecopages-jsx-dev-transform-contributor.js +21 -0
- package/src/eco-embed.js +8 -10
- package/src/ecopages-jsx-hmr-ownership.d.ts +43 -0
- package/src/ecopages-jsx-hmr-ownership.js +91 -0
- package/src/ecopages-jsx-hmr-strategy.d.ts +19 -0
- package/src/ecopages-jsx-hmr-strategy.js +67 -0
- package/src/ecopages-jsx-mdx.d.ts +22 -11
- package/src/ecopages-jsx-mdx.js +43 -108
- package/src/ecopages-jsx-radiant-ssr-policy.d.ts +12 -6
- package/src/ecopages-jsx-radiant-ssr-policy.js +116 -73
- package/src/ecopages-jsx-renderer.d.ts +10 -45
- package/src/ecopages-jsx-renderer.js +148 -233
- package/src/ecopages-jsx.constants.js +7 -4
- package/src/ecopages-jsx.plugin.d.ts +19 -23
- package/src/ecopages-jsx.plugin.js +137 -111
- package/src/ecopages-jsx.types.d.ts +4 -34
- package/src/ecopages-jsx.types.js +1 -0
- package/src/page-owned-content-script-grouping.d.ts +11 -0
- package/src/page-owned-content-script-grouping.js +57 -0
- package/src/radiant-registered-script-ssr-invalidation.d.ts +19 -0
- package/src/radiant-registered-script-ssr-invalidation.js +49 -0
- package/src/resolve-radiant-install-hydrator.d.ts +2 -0
- package/src/resolve-radiant-install-hydrator.js +3 -0
- package/src/ecopages-jsx-render-session.d.ts +0 -46
- package/src/ecopages-jsx-render-session.js +0 -93
|
@@ -1,240 +1,155 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
} from
|
|
4
|
-
import { createMarkupNodeLike } from
|
|
5
|
-
import { renderToString, withServerCustomElementRenderHook } from
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
} from
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
import { HttpError } from '@ecopages/core/errors';
|
|
2
|
+
import { createIntegrationRenderer, } from '@ecopages/core/integration';
|
|
3
|
+
import { resolveQueuedTokens } from '@ecopages/core/integration';
|
|
4
|
+
import { createMarkupNodeLike } from '@ecopages/jsx';
|
|
5
|
+
import { renderToString, withServerCustomElementRenderHook } from '@ecopages/jsx/server';
|
|
6
|
+
import { isMdxFile, normalizeMdxPageModule, } from './ecopages-jsx-mdx.js';
|
|
7
|
+
import { recordEjsxHmrOwnership, withEjsxHmrOwnershipScope } from './ecopages-jsx-hmr-ownership.js';
|
|
8
|
+
import { EcopagesJsxRadiantSsrPolicy } from './ecopages-jsx-radiant-ssr-policy.js';
|
|
9
|
+
import { CUSTOM_ELEMENT_SSR_PRELOAD_CACHE_SCOPES, CustomElementScriptPreloader } from '@ecopages/core/integration';
|
|
10
|
+
import { requireAppRuntime } from '@ecopages/core/integration';
|
|
11
|
+
import { createSharedServerModuleImporter } from '@ecopages/core/integration';
|
|
12
|
+
import { ECOPAGES_JSX_PLUGIN_NAME } from './ecopages-jsx.constants.js';
|
|
13
|
+
/** Creates the hook-based Ecopages JSX renderer for one plugin configuration. */
|
|
14
|
+
export function createEcopagesJsxRenderer(jsxConfig = {}) {
|
|
15
|
+
return createIntegrationRenderer(ECOPAGES_JSX_PLUGIN_NAME, createEcopagesJsxRendererHookFactory(jsxConfig));
|
|
16
|
+
}
|
|
17
|
+
/** Creates JSX renderer hooks that can also configure a custom renderer subclass. */
|
|
18
|
+
export function createEcopagesJsxRendererHookFactory(jsxConfig = {}) {
|
|
19
|
+
const mdxExtensions = jsxConfig.mdxExtensions ?? ['.mdx'];
|
|
20
|
+
return ({ appConfig, resolveComponentDependencies, resolveDependencyPath, }) => {
|
|
21
|
+
const radiantSsrPolicy = new EcopagesJsxRadiantSsrPolicy(jsxConfig.radiantSsrEnabled ?? false);
|
|
22
|
+
const ssrScriptPreloader = new CustomElementScriptPreloader({
|
|
23
|
+
cacheScope: CUSTOM_ELEMENT_SSR_PRELOAD_CACHE_SCOPES.ecopagesJsx,
|
|
24
|
+
preloadScopes: requireAppRuntime(appConfig).customElementSsrPreloadScopes,
|
|
25
|
+
collectForIntegration: ECOPAGES_JSX_PLUGIN_NAME,
|
|
26
|
+
enabled: jsxConfig.radiantSsrEnabled ?? false,
|
|
27
|
+
logLabel: 'ecopages-jsx',
|
|
28
|
+
resolveDependencyPath,
|
|
29
|
+
importServerModule: createSharedServerModuleImporter(appConfig),
|
|
30
|
+
});
|
|
31
|
+
const withCustomElementRenderHook = async (render) => await radiantSsrPolicy.withRuntime(() => withServerCustomElementRenderHook(({ instance, applyChildren, }) => instance ? radiantSsrPolicy.renderIntrinsicElementMarkup(instance, applyChildren) : undefined, render, { ownsChildren: true }));
|
|
32
|
+
const renderJsx = async (value) => await withCustomElementRenderHook(() => renderToString(value));
|
|
33
|
+
const normalizeForeignChildProps = (input) => {
|
|
34
|
+
if (!input.targetIntegration || input.targetIntegration === ECOPAGES_JSX_PLUGIN_NAME) {
|
|
35
|
+
return input.props;
|
|
36
|
+
}
|
|
37
|
+
return normalizeForeignChildren(input.props);
|
|
38
|
+
};
|
|
39
|
+
return {
|
|
40
|
+
beforeImportPageModule: async () => await radiantSsrPolicy.prepareRuntime(),
|
|
41
|
+
normalizePageModule: (file, module) => isMdxFile(file, mdxExtensions)
|
|
42
|
+
? normalizeMdxPageModule(file, module)
|
|
43
|
+
: module,
|
|
44
|
+
beforeRender: async (options) => {
|
|
45
|
+
await radiantSsrPolicy.prepareRuntime();
|
|
46
|
+
await ssrScriptPreloader.preloadSsrScripts([
|
|
47
|
+
options.Page,
|
|
48
|
+
options.Layout,
|
|
49
|
+
options.HtmlTemplate,
|
|
50
|
+
...(options.pageDependencyComponents ?? []),
|
|
51
|
+
]);
|
|
52
|
+
},
|
|
53
|
+
renderComponent: async (input) => {
|
|
54
|
+
await radiantSsrPolicy.prepareRuntime();
|
|
55
|
+
await ssrScriptPreloader.preloadSsrScripts([input.component]);
|
|
56
|
+
return await withEjsxHmrOwnershipScope(async () => {
|
|
57
|
+
try {
|
|
58
|
+
if (typeof input.component !== 'function') {
|
|
59
|
+
throw new TypeError('JSX renderer expected a callable component.');
|
|
60
|
+
}
|
|
61
|
+
const component = input.component;
|
|
62
|
+
const componentProps = input.children === undefined
|
|
63
|
+
? input.props
|
|
64
|
+
: {
|
|
65
|
+
...input.props,
|
|
66
|
+
children: typeof input.children === 'string'
|
|
67
|
+
? createMarkupNodeLike(input.children)
|
|
68
|
+
: input.children,
|
|
69
|
+
};
|
|
70
|
+
const content = await withCustomElementRenderHook(() => component(componentProps));
|
|
71
|
+
const html = await renderJsx(content);
|
|
72
|
+
const assets = input.component.config?.dependencies
|
|
73
|
+
? await resolveComponentDependencies([input.component])
|
|
74
|
+
: undefined;
|
|
75
|
+
recordEjsxHmrOwnership([input.component]);
|
|
76
|
+
return {
|
|
77
|
+
html,
|
|
78
|
+
canAttachAttributes: true,
|
|
79
|
+
integrationName: ECOPAGES_JSX_PLUGIN_NAME,
|
|
80
|
+
assets,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
throw createRenderError('Error rendering component', error);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
},
|
|
88
|
+
renderQueuedChildren: async (children, _runtimeContext, queuedResolutionsByToken, resolveToken) => {
|
|
89
|
+
if (children === undefined) {
|
|
90
|
+
return {};
|
|
91
|
+
}
|
|
92
|
+
const html = typeof children === 'string' ? children : await renderJsx(children);
|
|
93
|
+
return { html: await resolveQueuedTokens(html, queuedResolutionsByToken, resolveToken) };
|
|
94
|
+
},
|
|
95
|
+
normalizeForeignChildProps: (input) => normalizeForeignChildProps(input),
|
|
96
|
+
renderRoute: async (options, render) => await withEjsxHmrOwnershipScope(async () => {
|
|
97
|
+
const body = await render();
|
|
98
|
+
recordEjsxHmrOwnership([
|
|
99
|
+
options.Page,
|
|
100
|
+
options.Layout,
|
|
101
|
+
options.HtmlTemplate,
|
|
102
|
+
...(options.pageDependencyComponents ?? []),
|
|
103
|
+
]);
|
|
104
|
+
return body;
|
|
105
|
+
}),
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
export const EcopagesJsxRenderer = createEcopagesJsxRenderer();
|
|
110
|
+
function normalizeForeignChildren(props) {
|
|
111
|
+
if (!('children' in props)) {
|
|
112
|
+
return props;
|
|
21
113
|
}
|
|
22
114
|
const children = props.children;
|
|
23
|
-
if (children ===
|
|
24
|
-
|
|
115
|
+
if (children === undefined || typeof children === 'string') {
|
|
116
|
+
return props;
|
|
25
117
|
}
|
|
26
|
-
if (typeof children ===
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
118
|
+
if (typeof children === 'object' &&
|
|
119
|
+
children !== null &&
|
|
120
|
+
'nodeType' in children &&
|
|
121
|
+
typeof children.nodeType === 'number' &&
|
|
122
|
+
'outerHTML' in children &&
|
|
123
|
+
typeof children.outerHTML === 'string') {
|
|
124
|
+
return {
|
|
125
|
+
...props,
|
|
126
|
+
children: children.outerHTML,
|
|
127
|
+
};
|
|
31
128
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Re-renders queued JSX children inside the owning renderer so nested custom
|
|
39
|
-
* elements and queued foreign subtrees contribute assets to the same frame.
|
|
40
|
-
*/
|
|
41
|
-
async renderQueuedForeignSubtreeChildren(children, queuedResolutionsByToken, resolveToken) {
|
|
42
|
-
if (children === void 0) {
|
|
43
|
-
return { assets: [] };
|
|
129
|
+
if (isJsxSerializableForeignChild(children)) {
|
|
130
|
+
return {
|
|
131
|
+
...props,
|
|
132
|
+
children: renderToString(children),
|
|
133
|
+
};
|
|
44
134
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const renderedChildren = await this.renderJsx(children);
|
|
51
|
-
html = renderedChildren.html;
|
|
52
|
-
assets = renderedChildren.assets;
|
|
135
|
+
return props;
|
|
136
|
+
}
|
|
137
|
+
function isJsxSerializableForeignChild(children) {
|
|
138
|
+
if (Array.isArray(children)) {
|
|
139
|
+
return true;
|
|
53
140
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
* additional browser assets while also replacing placeholder tokens.
|
|
69
|
-
*/
|
|
70
|
-
async resolveOwnedForeignSubtreeHtml(html, runtimeContext) {
|
|
71
|
-
return this.foreignSubtreeExecutionService.resolveQueuedHtml({
|
|
72
|
-
currentIntegrationName: this.name,
|
|
73
|
-
html,
|
|
74
|
-
runtimeContext,
|
|
75
|
-
queueLabel: "Ecopages JSX",
|
|
76
|
-
getOwningRenderer: (integrationName, rendererCache) => this.getIntegrationRendererForName(integrationName, rendererCache),
|
|
77
|
-
applyAttributesToFirstElement: (resolvedHtml, attributes) => this.htmlTransformer.applyAttributesToFirstElement(resolvedHtml, attributes),
|
|
78
|
-
dedupeProcessedAssets: (assets) => this.htmlTransformer.dedupeProcessedAssets(assets),
|
|
79
|
-
renderQueuedChildren: async (children, _runtimeContext, queuedResolutionsByToken, resolveToken) => this.renderQueuedForeignSubtreeChildren(children, queuedResolutionsByToken, resolveToken)
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
createForeignChildRuntime(options) {
|
|
83
|
-
const runtime = super.createForeignChildRuntime(options);
|
|
84
|
-
const interceptForeignChild = runtime.interceptForeignChild;
|
|
85
|
-
const interceptForeignChildSync = runtime.interceptForeignChildSync;
|
|
86
|
-
const wrapInput = (input) => ({
|
|
87
|
-
...input,
|
|
88
|
-
props: input.targetIntegration && input.targetIntegration !== this.name ? this.normalizeForeignChildProps(input.props) : input.props
|
|
89
|
-
});
|
|
90
|
-
return {
|
|
91
|
-
interceptForeignChild: interceptForeignChild ? (input) => interceptForeignChild(wrapInput(input)) : void 0,
|
|
92
|
-
interceptForeignChildSync: interceptForeignChildSync ? (input) => interceptForeignChildSync(wrapInput(input)) : void 0
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
constructor({
|
|
96
|
-
appConfig,
|
|
97
|
-
assetProcessingService,
|
|
98
|
-
resolvedIntegrationDependencies,
|
|
99
|
-
jsxConfig,
|
|
100
|
-
runtimeOrigin
|
|
101
|
-
}) {
|
|
102
|
-
super({
|
|
103
|
-
appConfig,
|
|
104
|
-
assetProcessingService,
|
|
105
|
-
resolvedIntegrationDependencies,
|
|
106
|
-
runtimeOrigin
|
|
107
|
-
});
|
|
108
|
-
this.mdxExtensions = jsxConfig?.mdxExtensions ?? [".mdx"];
|
|
109
|
-
this.renderSession = new EcopagesJsxRenderSession(
|
|
110
|
-
(assets) => this.htmlTransformer.dedupeProcessedAssets(assets)
|
|
111
|
-
);
|
|
112
|
-
this.radiantSsrPolicy = jsxConfig?.radiantSsrPolicy ?? new EcopagesJsxRadiantSsrPolicy(jsxConfig?.radiantSsrEnabled ?? false);
|
|
113
|
-
}
|
|
114
|
-
/** Returns whether the requested page file should be treated as MDX. */
|
|
115
|
-
isMdxFile(filePath) {
|
|
116
|
-
return isMdxFile(filePath, this.mdxExtensions);
|
|
117
|
-
}
|
|
118
|
-
async importPageFile(file, options) {
|
|
119
|
-
return await this.withPreparedRadiantRuntime(async () => {
|
|
120
|
-
const module = await super.importPageFile(file, options);
|
|
121
|
-
return this.isMdxFile(file) ? normalizeMdxPageModule(file, module) : module;
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
async render(options) {
|
|
125
|
-
return await this.withPreparedRadiantRuntime(
|
|
126
|
-
() => this.renderSession.withActiveScope(async () => {
|
|
127
|
-
try {
|
|
128
|
-
return await this.renderPageWithDocumentShell({
|
|
129
|
-
page: {
|
|
130
|
-
component: options.Page,
|
|
131
|
-
props: {
|
|
132
|
-
...options.pageProps,
|
|
133
|
-
locals: options.pageLocals
|
|
134
|
-
}
|
|
135
|
-
},
|
|
136
|
-
layout: options.Layout ? {
|
|
137
|
-
component: options.Layout,
|
|
138
|
-
props: {
|
|
139
|
-
...options.pageProps,
|
|
140
|
-
locals: options.locals
|
|
141
|
-
}
|
|
142
|
-
} : void 0,
|
|
143
|
-
htmlTemplate: options.HtmlTemplate,
|
|
144
|
-
metadata: options.metadata,
|
|
145
|
-
pageProps: options.pageProps ?? {}
|
|
146
|
-
});
|
|
147
|
-
} catch (error) {
|
|
148
|
-
throw this.createRenderError("Error rendering page", error);
|
|
149
|
-
}
|
|
150
|
-
})
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
|
-
async renderComponent(input) {
|
|
154
|
-
return await this.withPreparedRadiantRuntime(
|
|
155
|
-
() => this.renderSession.withActiveScope(async () => {
|
|
156
|
-
const assetFrame = this.renderSession.beginCollectedAssetFrame();
|
|
157
|
-
try {
|
|
158
|
-
if (typeof input.component !== "function") {
|
|
159
|
-
throw new TypeError("JSX renderer expected a callable component.");
|
|
160
|
-
}
|
|
161
|
-
const component = input.component;
|
|
162
|
-
const componentProps = input.children === void 0 ? input.props : {
|
|
163
|
-
...input.props,
|
|
164
|
-
children: typeof input.children === "string" ? createMarkupNodeLike(input.children) : input.children
|
|
165
|
-
};
|
|
166
|
-
const content = await this.withCustomElementRenderHook(() => component(componentProps));
|
|
167
|
-
const rendered = await this.renderJsx(content);
|
|
168
|
-
const queuedForeignSubtreeResolution = await this.resolveOwnedForeignSubtreeHtml(
|
|
169
|
-
rendered.html,
|
|
170
|
-
this.getQueuedForeignSubtreeResolutionContext(
|
|
171
|
-
input
|
|
172
|
-
)
|
|
173
|
-
);
|
|
174
|
-
const componentAssets = input.component.config?.dependencies && typeof this.assetProcessingService?.processDependencies === "function" ? await this.processComponentDependencies([input.component]) : [];
|
|
175
|
-
const assets = this.htmlTransformer.dedupeProcessedAssets([
|
|
176
|
-
...this.renderSession.endCollectedAssetFrame(assetFrame),
|
|
177
|
-
...queuedForeignSubtreeResolution.assets,
|
|
178
|
-
...componentAssets
|
|
179
|
-
]);
|
|
180
|
-
return {
|
|
181
|
-
html: queuedForeignSubtreeResolution.html,
|
|
182
|
-
canAttachAttributes: true,
|
|
183
|
-
rootTag: this.getRootTagName(queuedForeignSubtreeResolution.html),
|
|
184
|
-
integrationName: this.name,
|
|
185
|
-
assets
|
|
186
|
-
};
|
|
187
|
-
} catch (error) {
|
|
188
|
-
this.renderSession.endCollectedAssetFrame(assetFrame);
|
|
189
|
-
throw this.createRenderError("Error rendering component", error);
|
|
190
|
-
}
|
|
191
|
-
})
|
|
192
|
-
);
|
|
193
|
-
}
|
|
194
|
-
async renderToResponse(view, props, ctx) {
|
|
195
|
-
return await this.withPreparedRadiantRuntime(
|
|
196
|
-
() => this.renderSession.withActiveScope(async () => {
|
|
197
|
-
try {
|
|
198
|
-
if (typeof view !== "function") {
|
|
199
|
-
throw new TypeError("JSX renderer expected a callable view component.");
|
|
200
|
-
}
|
|
201
|
-
const viewComponent = view;
|
|
202
|
-
return await this.renderViewWithDocumentShell({
|
|
203
|
-
view: viewComponent,
|
|
204
|
-
props,
|
|
205
|
-
ctx,
|
|
206
|
-
layout: viewComponent.config?.layout
|
|
207
|
-
});
|
|
208
|
-
} catch (error) {
|
|
209
|
-
throw this.createRenderError("Error rendering view", error);
|
|
210
|
-
}
|
|
211
|
-
})
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
async renderJsx(value) {
|
|
215
|
-
const collectedAssets = [];
|
|
216
|
-
const html = await this.withCustomElementRenderHook(() => renderToString(value));
|
|
217
|
-
const dedupedAssets = this.renderSession.recordCollectedAssets(collectedAssets);
|
|
218
|
-
return {
|
|
219
|
-
assets: dedupedAssets,
|
|
220
|
-
html
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
|
-
async withCustomElementRenderHook(render) {
|
|
224
|
-
return await this.radiantSsrPolicy.withRuntime(
|
|
225
|
-
() => withServerCustomElementRenderHook(this.createIntrinsicCustomElementRenderHook(), render)
|
|
226
|
-
);
|
|
227
|
-
}
|
|
228
|
-
async withPreparedRadiantRuntime(render) {
|
|
229
|
-
await this.radiantSsrPolicy.prepareRuntime();
|
|
230
|
-
return await render();
|
|
231
|
-
}
|
|
232
|
-
createIntrinsicCustomElementRenderHook() {
|
|
233
|
-
return ({ instance }) => {
|
|
234
|
-
return instance ? this.radiantSsrPolicy.renderIntrinsicElementMarkup(instance) : void 0;
|
|
235
|
-
};
|
|
236
|
-
}
|
|
141
|
+
if (children === null || typeof children !== 'object') {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
if ('$$typeof' in children) {
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
return 'strings' in children && Array.isArray(children.strings);
|
|
148
|
+
}
|
|
149
|
+
function createRenderError(message, cause) {
|
|
150
|
+
if (HttpError.isHttpError(cause)) {
|
|
151
|
+
return cause;
|
|
152
|
+
}
|
|
153
|
+
const errorMessage = cause instanceof Error ? `${message}: ${cause.message}` : message;
|
|
154
|
+
return HttpError.InternalServerError(errorMessage);
|
|
237
155
|
}
|
|
238
|
-
export {
|
|
239
|
-
EcopagesJsxRenderer
|
|
240
|
-
};
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Stable integration name shared by the JSX plugin and renderer.
|
|
3
|
+
*
|
|
4
|
+
* Ecopages uses this identifier to match route files, renderer instances, and
|
|
5
|
+
* cross-integration component boundaries.
|
|
6
|
+
*/
|
|
7
|
+
export const ECOPAGES_JSX_PLUGIN_NAME = 'ecopages-jsx';
|
|
@@ -1,38 +1,34 @@
|
|
|
1
|
-
import { IntegrationPlugin, type EcoBuildPlugin } from '@ecopages/core/
|
|
1
|
+
import { IntegrationPlugin, type IntegrationRendererBase, type IntegrationRuntimeContext, type EcoBuildPlugin } from '@ecopages/core/integration';
|
|
2
|
+
import { type AssetDefinition } from '@ecopages/core/integration';
|
|
2
3
|
import type { JsxRenderable } from '@ecopages/jsx';
|
|
3
4
|
import { EcopagesJsxRenderer } from './ecopages-jsx-renderer.js';
|
|
4
5
|
import type { EcopagesJsxPluginOptions } from './ecopages-jsx.types.js';
|
|
5
6
|
export type { EcopagesJsxMdxOptions, EcopagesJsxPluginOptions, EcopagesJsxRendererConfig, } from './ecopages-jsx.types.js';
|
|
6
7
|
/** JSX integration plugin for Ecopages, supporting `.tsx` templates and optional Radiant web components. */
|
|
7
8
|
export declare class EcopagesJsxPlugin extends IntegrationPlugin<JsxRenderable> {
|
|
8
|
-
renderer:
|
|
9
|
+
renderer: new (options: import("@ecopages/core/integration").IntegrationRendererOptions) => import("@ecopages/core/integration").IntegrationRenderer<JsxRenderable> & {
|
|
10
|
+
name: string;
|
|
11
|
+
};
|
|
12
|
+
readonly bundlesPageDependencies = true;
|
|
9
13
|
private includeRadiant;
|
|
10
|
-
private mdxEnabled;
|
|
11
14
|
private mdxCompilerOptions?;
|
|
12
15
|
private mdxExtensions;
|
|
13
|
-
private mdxLoaderPlugin?;
|
|
14
|
-
/** Returns the build plugins required by the JSX integration. */
|
|
15
|
-
get plugins(): EcoBuildPlugin[];
|
|
16
|
-
/** Creates the renderer instance with the resolved JSX integration runtime options. */
|
|
17
|
-
initializeRenderer(options?: {
|
|
18
|
-
rendererModules?: unknown;
|
|
19
|
-
}): EcopagesJsxRenderer;
|
|
20
|
-
constructor(options?: EcopagesJsxPluginOptions);
|
|
21
|
-
private getDependencies;
|
|
22
|
-
/** Ensures MDX build hooks are ready before Ecopages collects contributions. */
|
|
23
|
-
prepareBuildContributions(): Promise<void>;
|
|
24
|
-
/**
|
|
25
|
-
* Registers MDX tooling and completes the base integration setup.
|
|
26
|
-
*/
|
|
27
|
-
setup(): Promise<void>;
|
|
28
|
-
private ensureMdxLoaderPlugin;
|
|
29
16
|
/**
|
|
30
|
-
*
|
|
17
|
+
* Returns the build plugins required by the JSX integration.
|
|
31
18
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
19
|
+
* @remarks
|
|
20
|
+
* Returns a new loader declaration without registering or initializing it. The build manifest owns the
|
|
21
|
+
* resulting instance for the app runtime.
|
|
34
22
|
*/
|
|
35
|
-
|
|
23
|
+
plugins(app: IntegrationRuntimeContext['appConfig']): EcoBuildPlugin[];
|
|
24
|
+
/** Creates the renderer instance with the resolved JSX integration runtime options. */
|
|
25
|
+
createRenderer(base: IntegrationRendererBase): EcopagesJsxRenderer;
|
|
26
|
+
constructor(options?: EcopagesJsxPluginOptions);
|
|
27
|
+
private getDependencies;
|
|
28
|
+
/** Assigns grouped-build metadata for page-owned JSX content scripts. */
|
|
29
|
+
prepareAssetDependencies(dependencies: AssetDefinition[]): AssetDefinition[];
|
|
30
|
+
/** Registers JSX HMR strategy, dev-transform plugins, and Radiant SSR invalidation hooks. */
|
|
31
|
+
hmr(context: IntegrationRuntimeContext): void;
|
|
36
32
|
}
|
|
37
33
|
/**
|
|
38
34
|
* Creates the JSX integration plugin with resolved defaults.
|