@ecopages/ecopages-jsx 0.2.0-beta.8 → 0.2.0-rc.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 +2 -0
- package/package.json +6 -5
- 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 +45 -0
- package/src/ecopages-jsx-hmr-ownership.js +77 -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 +2 -4
- package/src/ecopages-jsx-mdx.js +63 -106
- package/src/ecopages-jsx-radiant-ssr-policy.d.ts +7 -5
- package/src/ecopages-jsx-radiant-ssr-policy.js +107 -73
- package/src/ecopages-jsx-render-session.d.ts +5 -9
- package/src/ecopages-jsx-render-session.js +104 -86
- package/src/ecopages-jsx-renderer.d.ts +22 -9
- package/src/ecopages-jsx-renderer.js +278 -234
- package/src/ecopages-jsx.constants.js +7 -4
- package/src/ecopages-jsx.plugin.d.ts +17 -0
- package/src/ecopages-jsx.plugin.js +162 -111
- package/src/ecopages-jsx.types.js +1 -0
- package/src/page-owned-content-script-grouping.d.ts +12 -0
- package/src/page-owned-content-script-grouping.js +63 -0
- package/src/radiant-registered-script-ssr-invalidation.d.ts +18 -0
- package/src/radiant-registered-script-ssr-invalidation.js +47 -0
- package/src/resolve-radiant-install-hydrator.d.ts +2 -0
- package/src/resolve-radiant-install-hydrator.js +3 -0
|
@@ -1,79 +1,113 @@
|
|
|
1
|
-
import { createMarkupNodeLike } from
|
|
2
|
-
import { createServerHydrationBindingState, withServerHydrationBindingState } from
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
import { createMarkupNodeLike } from '@ecopages/jsx';
|
|
2
|
+
import { createServerHydrationBindingState, withServerHydrationBindingState } from '@ecopages/jsx/server';
|
|
3
|
+
/**
|
|
4
|
+
* Owns optional Radiant SSR runtime installation for the JSX integration.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* Radiant's server bridge and light-DOM shim are loaded lazily because most JSX
|
|
8
|
+
* renders do not need them. Resolved runtime modules are cached on the policy
|
|
9
|
+
* instance so repeated renders on the same renderer reuse one load without
|
|
10
|
+
* process-wide mutable class state. Light-DOM constructor installation remains
|
|
11
|
+
* process-global and idempotent via {@link ensureRadiantLightDomGlobals}; the
|
|
12
|
+
* Radiant installer also repairs incomplete DOM globals left by another runtime.
|
|
13
|
+
*/
|
|
14
|
+
export class EcopagesJsxRadiantSsrPolicy {
|
|
15
|
+
runtimeModules;
|
|
16
|
+
runtimeModulesPromise;
|
|
17
|
+
enabled;
|
|
18
|
+
constructor(enabled) {
|
|
19
|
+
this.enabled = enabled;
|
|
16
20
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Ensures the Radiant SSR runtime is installed before a render needs it.
|
|
23
|
+
*/
|
|
24
|
+
async prepareRuntime() {
|
|
25
|
+
if (!this.enabled) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
await this.ensureRuntimeInstalled();
|
|
25
29
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Runs one render inside Radiant's server runtime when the policy is enabled.
|
|
32
|
+
*/
|
|
33
|
+
async withRuntime(render) {
|
|
34
|
+
if (!this.enabled) {
|
|
35
|
+
return render();
|
|
36
|
+
}
|
|
37
|
+
const runtimeModules = await this.runtimeModulesPromise;
|
|
38
|
+
if (!runtimeModules) {
|
|
39
|
+
return render();
|
|
40
|
+
}
|
|
41
|
+
return runtimeModules.withServerRadiantElementSsrRuntime(render);
|
|
29
42
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Converts one Radiant custom-element instance into trusted SSR markup.
|
|
45
|
+
*
|
|
46
|
+
* @remarks
|
|
47
|
+
* The returned node-like wrapper lets the JSX server renderer preserve the
|
|
48
|
+
* generated host HTML without escaping it back into plain text.
|
|
49
|
+
*/
|
|
50
|
+
renderIntrinsicElementMarkup(instance) {
|
|
51
|
+
const renderBridge = this.runtimeModules?.resolveRadiantElementRenderBridge(instance);
|
|
52
|
+
if (!renderBridge) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
return createMarkupNodeLike(withServerHydrationBindingState(createServerHydrationBindingState(), () => renderBridge.renderHostToString({
|
|
56
|
+
mode: 'hydrate',
|
|
57
|
+
})));
|
|
43
58
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
resolveRadiantElementRenderBridge: radiantElementSsrRuntimeModule.resolveRadiantElementRenderBridge,
|
|
67
|
-
withServerRadiantElementSsrRuntime: radiantElementSsrRuntimeModule.withServerRadiantElementSsrRuntime
|
|
68
|
-
};
|
|
69
|
-
EcopagesJsxRadiantSsrPolicy.runtimeModules = modules;
|
|
70
|
-
return modules;
|
|
71
|
-
});
|
|
59
|
+
async ensureRuntimeInstalled() {
|
|
60
|
+
if (!this.runtimeModulesPromise) {
|
|
61
|
+
const radiantLightDomShimEntry = import.meta.resolve('@ecopages/radiant/server/light-dom-shim');
|
|
62
|
+
const radiantElementSsrRuntimeModuleUrl = new URL('./radiant-element-ssr-bridge.js', radiantLightDomShimEntry).href;
|
|
63
|
+
this.runtimeModulesPromise = (async () => {
|
|
64
|
+
const lightDomShimModule = await import(radiantLightDomShimEntry);
|
|
65
|
+
ensureRadiantLightDomGlobals(lightDomShimModule.ensureLightDomShim);
|
|
66
|
+
const radiantElementSsrRuntimeModule = (await import(radiantElementSsrRuntimeModuleUrl));
|
|
67
|
+
const modules = {
|
|
68
|
+
ensureLightDomShim: lightDomShimModule.ensureLightDomShim,
|
|
69
|
+
resolveRadiantElementRenderBridge: radiantElementSsrRuntimeModule.resolveRadiantElementRenderBridge,
|
|
70
|
+
withServerRadiantElementSsrRuntime: radiantElementSsrRuntimeModule.withServerRadiantElementSsrRuntime,
|
|
71
|
+
};
|
|
72
|
+
this.runtimeModules = modules;
|
|
73
|
+
return modules;
|
|
74
|
+
})();
|
|
75
|
+
}
|
|
76
|
+
await this.runtimeModulesPromise;
|
|
77
|
+
const lightDomShimModule = this.runtimeModules;
|
|
78
|
+
if (lightDomShimModule) {
|
|
79
|
+
ensureRadiantLightDomGlobals(lightDomShimModule.ensureLightDomShim);
|
|
80
|
+
}
|
|
72
81
|
}
|
|
73
|
-
const lightDomShimModule = await EcopagesJsxRadiantSsrPolicy.runtimeModulesPromise;
|
|
74
|
-
lightDomShimModule.installLightDomShim();
|
|
75
|
-
}
|
|
76
82
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
83
|
+
/**
|
|
84
|
+
* Installs Radiant light-DOM constructors on `globalThis` once.
|
|
85
|
+
*
|
|
86
|
+
* @remarks
|
|
87
|
+
* Custom-element constructors must be process-global; undoing them between tests
|
|
88
|
+
* is unsafe. Callers that clear globals for isolation must rely on a fresh policy
|
|
89
|
+
* instance so {@link EcopagesJsxRadiantSsrPolicy.prepareRuntime} re-runs the
|
|
90
|
+
* completeness check.
|
|
91
|
+
*/
|
|
92
|
+
function ensureRadiantLightDomGlobals(ensureLightDomShim) {
|
|
93
|
+
const window = ensureLightDomShim();
|
|
94
|
+
if (!window) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
Object.assign(globalThis, {
|
|
98
|
+
CSS: window.CSS,
|
|
99
|
+
CustomEvent: window.CustomEvent,
|
|
100
|
+
Document: window.Document,
|
|
101
|
+
Element: window.Element,
|
|
102
|
+
Event: window.Event,
|
|
103
|
+
EventTarget: window.EventTarget,
|
|
104
|
+
HTMLScriptElement: window.HTMLScriptElement,
|
|
105
|
+
HTMLElement: window.HTMLElement,
|
|
106
|
+
Node: window.Node,
|
|
107
|
+
document: window.document,
|
|
108
|
+
customElements: window.customElements,
|
|
109
|
+
requestAnimationFrame: window.requestAnimationFrame,
|
|
110
|
+
cancelAnimationFrame: window.cancelAnimationFrame,
|
|
111
|
+
window,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { EcoComponent } from '@ecopages/core';
|
|
1
2
|
import type { ProcessedAsset } from '@ecopages/core/services/asset-processing-service';
|
|
2
3
|
export declare const ECOPAGES_JSX_SSR_RENDER_STATE_KEY: unique symbol;
|
|
3
4
|
/**
|
|
@@ -21,18 +22,13 @@ export declare class EcopagesJsxRenderSession {
|
|
|
21
22
|
* mirrored back into the JSX SSR scope so nested `renderToString()` calls see
|
|
22
23
|
* the same asset frame stack. When no session exists yet, a new state is
|
|
23
24
|
* created and published through both the internal async-local store and the
|
|
24
|
-
* JSX SSR scope bridge.
|
|
25
|
+
* JSX SSR scope bridge. HMR ownership accumulated during the outer scope is
|
|
26
|
+
* published once when that scope completes.
|
|
25
27
|
*/
|
|
26
|
-
withActiveScope<T>(render: () => T): T
|
|
27
|
-
/**
|
|
28
|
-
* Runs work with the current page-level hydrate binding namespace attached to JSX SSR.
|
|
29
|
-
*
|
|
30
|
-
* This lets page, layout, and document renders participate in one client-owned
|
|
31
|
-
* hydration root even though Ecopages composes them through multiple sibling render calls.
|
|
32
|
-
*/
|
|
33
|
-
withHydrationBindingScope<T>(render: () => T): T;
|
|
28
|
+
withActiveScope<T>(render: () => T | Promise<T>): Promise<T>;
|
|
34
29
|
beginCollectedAssetFrame(): ProcessedAsset[];
|
|
35
30
|
endCollectedAssetFrame(frame: ProcessedAsset[]): ProcessedAsset[];
|
|
31
|
+
mergeHmrOwnership(components: ReadonlyArray<EcoComponent | undefined>): void;
|
|
36
32
|
recordCollectedAssets(collectedAssets: ProcessedAsset[]): ProcessedAsset[];
|
|
37
33
|
/**
|
|
38
34
|
* Resolves the current render-session state from the local async scope first.
|
|
@@ -1,93 +1,111 @@
|
|
|
1
|
-
import { AsyncLocalStorage } from
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
withActiveSsrScopeValue,
|
|
6
|
-
withServerHydrationBindingState
|
|
7
|
-
} from "@ecopages/jsx/server";
|
|
8
|
-
const ECOPAGES_JSX_SSR_RENDER_STATE_KEY = /* @__PURE__ */ Symbol.for("@ecopages/ecopages-jsx.ssr-render-state");
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
import { getActiveSsrScopeValue, withActiveSsrScopeValue } from '@ecopages/jsx/server';
|
|
3
|
+
import { mergeEjsxHmrOwnership, publishEjsxHmrOwnership } from './ecopages-jsx-hmr-ownership.js';
|
|
4
|
+
export const ECOPAGES_JSX_SSR_RENDER_STATE_KEY = Symbol.for('@ecopages/ecopages-jsx.ssr-render-state');
|
|
9
5
|
const renderStateStorage = new AsyncLocalStorage();
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
this.dedupeProcessedAssets = dedupeProcessedAssets;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Runs one render inside the active session scope.
|
|
17
|
-
*
|
|
18
|
-
* @remarks
|
|
19
|
-
* When a render is already active, the current session state is reused and
|
|
20
|
-
* mirrored back into the JSX SSR scope so nested `renderToString()` calls see
|
|
21
|
-
* the same asset frame stack. When no session exists yet, a new state is
|
|
22
|
-
* created and published through both the internal async-local store and the
|
|
23
|
-
* JSX SSR scope bridge.
|
|
24
|
-
*/
|
|
25
|
-
withActiveScope(render) {
|
|
26
|
-
const activeState = renderStateStorage.getStore();
|
|
27
|
-
if (activeState) {
|
|
28
|
-
return withActiveSsrScopeValue(ECOPAGES_JSX_SSR_RENDER_STATE_KEY, activeState, render);
|
|
6
|
+
function ensurePendingHmrFileOwners(state) {
|
|
7
|
+
if (!state.pendingHmrFileOwners) {
|
|
8
|
+
state.pendingHmrFileOwners = new Set();
|
|
29
9
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
10
|
+
return state.pendingHmrFileOwners;
|
|
11
|
+
}
|
|
12
|
+
function commitPendingHmrOwnership(state) {
|
|
13
|
+
const pending = state.pendingHmrFileOwners;
|
|
14
|
+
if (!pending || pending.size === 0) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
publishEjsxHmrOwnership(pending);
|
|
18
|
+
pending.clear();
|
|
19
|
+
}
|
|
20
|
+
async function runWithCommittedHmrOwnership(state, render) {
|
|
21
|
+
try {
|
|
22
|
+
return await render();
|
|
23
|
+
}
|
|
24
|
+
finally {
|
|
25
|
+
commitPendingHmrOwnership(state);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Tracks JSX SSR asset-collection state for one active render flow.
|
|
30
|
+
*
|
|
31
|
+
* @remarks
|
|
32
|
+
* The renderer still mirrors this state into `@ecopages/jsx/server` so nested
|
|
33
|
+
* JSX renders and existing SSR-scope probes can observe it, but it also keeps
|
|
34
|
+
* an internal async-local copy. That fallback avoids losing renderer state when
|
|
35
|
+
* host runtimes such as Vite end up loading separate module identities for the
|
|
36
|
+
* JSX server helpers.
|
|
37
|
+
*/
|
|
38
|
+
export class EcopagesJsxRenderSession {
|
|
39
|
+
dedupeProcessedAssets;
|
|
40
|
+
constructor(dedupeProcessedAssets) {
|
|
41
|
+
this.dedupeProcessedAssets = dedupeProcessedAssets;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Runs one render inside the active session scope.
|
|
45
|
+
*
|
|
46
|
+
* @remarks
|
|
47
|
+
* When a render is already active, the current session state is reused and
|
|
48
|
+
* mirrored back into the JSX SSR scope so nested `renderToString()` calls see
|
|
49
|
+
* the same asset frame stack. When no session exists yet, a new state is
|
|
50
|
+
* created and published through both the internal async-local store and the
|
|
51
|
+
* JSX SSR scope bridge. HMR ownership accumulated during the outer scope is
|
|
52
|
+
* published once when that scope completes.
|
|
53
|
+
*/
|
|
54
|
+
async withActiveScope(render) {
|
|
55
|
+
const activeState = renderStateStorage.getStore();
|
|
56
|
+
if (activeState) {
|
|
57
|
+
return await withActiveSsrScopeValue(ECOPAGES_JSX_SSR_RENDER_STATE_KEY, activeState, render);
|
|
58
|
+
}
|
|
59
|
+
const jsxScopeState = getActiveSsrScopeValue(ECOPAGES_JSX_SSR_RENDER_STATE_KEY);
|
|
60
|
+
if (jsxScopeState) {
|
|
61
|
+
ensurePendingHmrFileOwners(jsxScopeState);
|
|
62
|
+
return await runWithCommittedHmrOwnership(jsxScopeState, () => renderStateStorage.run(jsxScopeState, () => render()));
|
|
63
|
+
}
|
|
64
|
+
const state = {
|
|
65
|
+
collectedAssetFrames: [],
|
|
66
|
+
pendingHmrFileOwners: new Set(),
|
|
67
|
+
};
|
|
68
|
+
return await runWithCommittedHmrOwnership(state, () => renderStateStorage.run(state, () => withActiveSsrScopeValue(ECOPAGES_JSX_SSR_RENDER_STATE_KEY, state, render)));
|
|
69
|
+
}
|
|
70
|
+
beginCollectedAssetFrame() {
|
|
71
|
+
const state = this.getState();
|
|
72
|
+
const frame = [];
|
|
73
|
+
state.collectedAssetFrames.push(frame);
|
|
74
|
+
return frame;
|
|
75
|
+
}
|
|
76
|
+
endCollectedAssetFrame(frame) {
|
|
77
|
+
const activeFrame = this.getState().collectedAssetFrames.pop();
|
|
78
|
+
if (!activeFrame || activeFrame !== frame) {
|
|
79
|
+
return this.dedupeProcessedAssets(frame);
|
|
80
|
+
}
|
|
81
|
+
return this.dedupeProcessedAssets(activeFrame);
|
|
33
82
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
hydrationBindingState: createServerHydrationBindingState()
|
|
37
|
-
};
|
|
38
|
-
return renderStateStorage.run(
|
|
39
|
-
state,
|
|
40
|
-
() => withActiveSsrScopeValue(ECOPAGES_JSX_SSR_RENDER_STATE_KEY, state, render)
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Runs work with the current page-level hydrate binding namespace attached to JSX SSR.
|
|
45
|
-
*
|
|
46
|
-
* This lets page, layout, and document renders participate in one client-owned
|
|
47
|
-
* hydration root even though Ecopages composes them through multiple sibling render calls.
|
|
48
|
-
*/
|
|
49
|
-
withHydrationBindingScope(render) {
|
|
50
|
-
return withServerHydrationBindingState(this.getState().hydrationBindingState, render);
|
|
51
|
-
}
|
|
52
|
-
beginCollectedAssetFrame() {
|
|
53
|
-
const state = this.getState();
|
|
54
|
-
const frame = [];
|
|
55
|
-
state.collectedAssetFrames.push(frame);
|
|
56
|
-
return frame;
|
|
57
|
-
}
|
|
58
|
-
endCollectedAssetFrame(frame) {
|
|
59
|
-
const activeFrame = this.getState().collectedAssetFrames.pop();
|
|
60
|
-
if (!activeFrame || activeFrame !== frame) {
|
|
61
|
-
return this.dedupeProcessedAssets(frame);
|
|
83
|
+
mergeHmrOwnership(components) {
|
|
84
|
+
mergeEjsxHmrOwnership(ensurePendingHmrFileOwners(this.getState()), components);
|
|
62
85
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
86
|
+
recordCollectedAssets(collectedAssets) {
|
|
87
|
+
const dedupedAssets = this.dedupeProcessedAssets(collectedAssets);
|
|
88
|
+
const state = this.getState();
|
|
89
|
+
const activeFrame = state.collectedAssetFrames[state.collectedAssetFrames.length - 1];
|
|
90
|
+
if (activeFrame) {
|
|
91
|
+
activeFrame.push(...dedupedAssets);
|
|
92
|
+
}
|
|
93
|
+
return dedupedAssets;
|
|
71
94
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
95
|
+
/**
|
|
96
|
+
* Resolves the current render-session state from the local async scope first.
|
|
97
|
+
*
|
|
98
|
+
* @remarks
|
|
99
|
+
* The fallback read from `@ecopages/jsx/server` keeps compatibility with code
|
|
100
|
+
* that still inspects the public SSR scope directly, while the async-local
|
|
101
|
+
* store remains the authoritative source for renderer-owned bookkeeping.
|
|
102
|
+
*/
|
|
103
|
+
getState() {
|
|
104
|
+
const state = renderStateStorage.getStore() ??
|
|
105
|
+
getActiveSsrScopeValue(ECOPAGES_JSX_SSR_RENDER_STATE_KEY);
|
|
106
|
+
if (!state) {
|
|
107
|
+
throw new Error('Ecopages JSX SSR render state is unavailable outside the active render scope.');
|
|
108
|
+
}
|
|
109
|
+
return state;
|
|
86
110
|
}
|
|
87
|
-
return state;
|
|
88
|
-
}
|
|
89
111
|
}
|
|
90
|
-
export {
|
|
91
|
-
ECOPAGES_JSX_SSR_RENDER_STATE_KEY,
|
|
92
|
-
EcopagesJsxRenderSession
|
|
93
|
-
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ComponentRenderInput, ComponentRenderResult, EcoComponent, IntegrationRendererRenderOptions, RouteRendererBody } from '@ecopages/core';
|
|
2
|
-
import { IntegrationRenderer, type RenderToResponseContext, type RouteModuleLoadOptions } from '@ecopages/core/route-renderer/integration-renderer';
|
|
3
|
-
import type { ForeignChildRuntime } from '@ecopages/core/route-renderer/component-render-context';
|
|
2
|
+
import { IntegrationRenderer, type RenderToResponseContext, type RouteModuleLoadOptions } from '@ecopages/core/route-renderer/orchestration/integration-renderer';
|
|
3
|
+
import type { ForeignChildRuntime } from '@ecopages/core/route-renderer/orchestration/foreign-child/component-render-context';
|
|
4
4
|
import { type JsxRenderable } from '@ecopages/jsx';
|
|
5
5
|
import { type EcopagesJsxMdxPageModule } from './ecopages-jsx-mdx.js';
|
|
6
6
|
import type { EcopagesJsxRendererOptions } from './ecopages-jsx.types.js';
|
|
@@ -16,19 +16,26 @@ export declare class EcopagesJsxRenderer extends IntegrationRenderer<JsxRenderab
|
|
|
16
16
|
private readonly mdxExtensions;
|
|
17
17
|
private readonly renderSession;
|
|
18
18
|
private readonly radiantSsrPolicy;
|
|
19
|
+
/**
|
|
20
|
+
* Serializes foreign-child props for string-first boundaries.
|
|
21
|
+
*
|
|
22
|
+
* @remarks
|
|
23
|
+
* DOM nodes become `outerHTML`. JSX trees, arrays, and template results are
|
|
24
|
+
* stringified here. Other values are left for core foreign-child interception,
|
|
25
|
+
* which rejects opaque plain objects before queueing. Cross-integration
|
|
26
|
+
* children must use `EcoEmbed`.
|
|
27
|
+
*/
|
|
19
28
|
private normalizeForeignChildProps;
|
|
29
|
+
/**
|
|
30
|
+
* Returns whether children are a JSX/template shape this renderer can
|
|
31
|
+
* serialize before foreign-child queueing.
|
|
32
|
+
*/
|
|
33
|
+
private isJsxSerializableForeignChild;
|
|
20
34
|
/**
|
|
21
35
|
* Re-renders queued JSX children inside the owning renderer so nested custom
|
|
22
36
|
* elements and queued foreign subtrees contribute assets to the same frame.
|
|
23
37
|
*/
|
|
24
38
|
private renderQueuedForeignSubtreeChildren;
|
|
25
|
-
/**
|
|
26
|
-
* Resolves queued foreign subtrees after JSX has been stringified.
|
|
27
|
-
*
|
|
28
|
-
* JSX content needs one extra render pass because child foreign subtrees may emit
|
|
29
|
-
* additional browser assets while also replacing placeholder tokens.
|
|
30
|
-
*/
|
|
31
|
-
private resolveOwnedForeignSubtreeHtml;
|
|
32
39
|
protected createForeignChildRuntime(options: {
|
|
33
40
|
renderInput: ComponentRenderInput;
|
|
34
41
|
rendererCache: Map<string, IntegrationRenderer<any>>;
|
|
@@ -44,4 +51,10 @@ export declare class EcopagesJsxRenderer extends IntegrationRenderer<JsxRenderab
|
|
|
44
51
|
private withCustomElementRenderHook;
|
|
45
52
|
private withPreparedRadiantRuntime;
|
|
46
53
|
private createIntrinsicCustomElementRenderHook;
|
|
54
|
+
/**
|
|
55
|
+
* Records the source files that produced the current render so
|
|
56
|
+
* {@link EcopagesJsxHmrStrategy} can match later watcher events without
|
|
57
|
+
* re-walking the component tree.
|
|
58
|
+
*/
|
|
59
|
+
private recordHmrOwnership;
|
|
47
60
|
}
|