@ecopages/react 0.2.0-alpha.9 → 0.2.0-beta.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/README.md +30 -13
- package/package.json +23 -12
- package/src/eco-embed.d.ts +11 -0
- package/src/eco-embed.js +11 -0
- package/src/react-hmr-strategy.d.ts +102 -18
- package/src/react-hmr-strategy.js +427 -50
- package/src/react-renderer.d.ts +100 -92
- package/src/react-renderer.js +356 -340
- package/src/react.constants.d.ts +1 -0
- package/src/react.constants.js +4 -0
- package/src/react.plugin.d.ts +25 -107
- package/src/react.plugin.js +109 -61
- package/src/react.types.d.ts +88 -0
- package/src/react.types.js +0 -0
- package/src/router-adapter.d.ts +7 -14
- package/src/runtime/use-sync-external-store-with-selector.d.ts +3 -0
- package/src/runtime/use-sync-external-store-with-selector.js +56 -0
- package/src/services/pages-index.d.ts +64 -0
- package/src/services/pages-index.js +73 -0
- package/src/services/react-bundle.service.d.ts +24 -9
- package/src/services/react-bundle.service.js +35 -24
- package/src/services/react-hmr-page-metadata-cache.d.ts +10 -1
- package/src/services/react-hmr-page-metadata-cache.js +18 -2
- package/src/services/react-hydration-asset.service.d.ts +28 -19
- package/src/services/react-hydration-asset.service.js +83 -64
- package/src/services/react-mdx-config-dependency.service.d.ts +36 -0
- package/src/services/react-mdx-config-dependency.service.js +122 -0
- package/src/services/react-page-module.service.d.ts +8 -3
- package/src/services/react-page-module.service.js +33 -26
- package/src/services/react-page-payload.service.d.ts +46 -0
- package/src/services/react-page-payload.service.js +67 -0
- package/src/services/react-runtime-bundle.service.d.ts +9 -2
- package/src/services/react-runtime-bundle.service.js +77 -16
- package/src/utils/client-graph-boundary-cache.d.ts +108 -0
- package/src/utils/client-graph-boundary-cache.js +116 -0
- package/src/utils/client-graph-boundary-plugin.d.ts +13 -5
- package/src/utils/client-graph-boundary-plugin.js +63 -5
- package/src/utils/component-config-traversal.d.ts +36 -0
- package/src/utils/component-config-traversal.js +54 -0
- package/src/utils/declared-modules.d.ts +1 -1
- package/src/utils/declared-modules.js +7 -16
- package/src/utils/dynamic.test.browser.d.ts +1 -0
- package/src/utils/dynamic.test.browser.js +33 -0
- package/src/utils/hydration-scripts.d.ts +9 -5
- package/src/utils/hydration-scripts.js +119 -34
- package/src/utils/hydration-scripts.test.browser.d.ts +1 -0
- package/src/utils/hydration-scripts.test.browser.js +198 -0
- package/src/utils/react-dom-runtime-interop-plugin.d.ts +1 -1
- package/src/utils/react-dom-runtime-interop-plugin.js +9 -0
- package/src/utils/react-mdx-loader-plugin.d.ts +1 -1
- package/src/utils/{react-runtime-specifier-map.d.ts → react-runtime-alias-map.d.ts} +3 -1
- package/src/utils/react-runtime-alias-map.js +90 -0
- package/CHANGELOG.md +0 -27
- package/src/react-hmr-strategy.ts +0 -386
- package/src/react-renderer.ts +0 -803
- package/src/react.plugin.ts +0 -276
- package/src/router-adapter.ts +0 -95
- package/src/services/react-bundle.service.ts +0 -108
- package/src/services/react-hmr-page-metadata-cache.ts +0 -24
- package/src/services/react-hydration-asset.service.ts +0 -263
- package/src/services/react-page-module.service.ts +0 -224
- package/src/services/react-runtime-bundle.service.ts +0 -172
- package/src/utils/client-graph-boundary-plugin.ts +0 -831
- package/src/utils/client-only.ts +0 -27
- package/src/utils/declared-modules.ts +0 -99
- package/src/utils/dynamic.ts +0 -27
- package/src/utils/hmr-scripts.ts +0 -47
- package/src/utils/html-boundary.ts +0 -66
- package/src/utils/hydration-scripts.ts +0 -459
- package/src/utils/reachability-analyzer.ts +0 -593
- package/src/utils/react-dom-runtime-interop-plugin.ts +0 -33
- package/src/utils/react-mdx-loader-plugin.ts +0 -63
- package/src/utils/react-runtime-specifier-map.js +0 -37
- package/src/utils/react-runtime-specifier-map.ts +0 -45
- package/src/utils/use-sync-external-store-shim-plugin.d.ts +0 -5
- package/src/utils/use-sync-external-store-shim-plugin.js +0 -41
- package/src/utils/use-sync-external-store-shim-plugin.ts +0 -45
package/src/react-renderer.d.ts
CHANGED
|
@@ -2,20 +2,23 @@
|
|
|
2
2
|
* This module contains the React renderer
|
|
3
3
|
* @module
|
|
4
4
|
*/
|
|
5
|
-
import type { ComponentRenderInput, ComponentRenderResult, EcoComponent,
|
|
6
|
-
import { IntegrationRenderer, type RenderToResponseContext } from '@ecopages/core/route-renderer/integration-renderer';
|
|
7
|
-
import type { ProcessedAsset } from '@ecopages/core/services/asset-processing-service';
|
|
8
|
-
import {
|
|
9
|
-
import type {
|
|
10
|
-
import type { ReactRouterAdapter } from './router-adapter.js';
|
|
5
|
+
import type { ComponentRenderInput, ComponentRenderResult, EcoComponent, EcoPageFile, IntegrationRendererRenderOptions, RouteRendererBody } from '@ecopages/core';
|
|
6
|
+
import { IntegrationRenderer, type HtmlDocumentContribution, type HtmlDocumentContributionContext, type PageBrowserGraphContributionContext, type RenderToResponseContext, type RouteModuleLoadOptions } from '@ecopages/core/route-renderer/integration-renderer';
|
|
7
|
+
import type { AssetDefinition, ProcessedAsset } from '@ecopages/core/services/asset-processing-service';
|
|
8
|
+
import type { ReactNode } from 'react';
|
|
9
|
+
import type { ReactRendererConfig } from './react.types.js';
|
|
11
10
|
import { ReactBundleService } from './services/react-bundle.service.js';
|
|
12
|
-
import {
|
|
11
|
+
import { ReactMdxConfigDependencyService } from './services/react-mdx-config-dependency.service.js';
|
|
13
12
|
import { ReactPageModuleService } from './services/react-page-module.service.js';
|
|
13
|
+
import { ReactPagePayloadService } from './services/react-page-payload.service.js';
|
|
14
14
|
import { ReactHydrationAssetService } from './services/react-hydration-asset.service.js';
|
|
15
|
-
type
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
export type { ReactRendererConfig } from './react.types.js';
|
|
16
|
+
type ReactRuntimeModules = {
|
|
17
|
+
react: Pick<typeof import('react'), 'createElement' | 'Fragment'>;
|
|
18
|
+
reactDomServer: Pick<typeof import('react-dom/server'), 'renderToReadableStream' | 'renderToString'>;
|
|
19
|
+
};
|
|
20
|
+
export type ReactRendererOptions = ConstructorParameters<typeof IntegrationRenderer>[0] & {
|
|
21
|
+
reactConfig?: ReactRendererConfig;
|
|
19
22
|
};
|
|
20
23
|
/**
|
|
21
24
|
* Error thrown when an error occurs while rendering a React component.
|
|
@@ -37,29 +40,29 @@ export declare class BundleError extends Error {
|
|
|
37
40
|
export declare class ReactRenderer extends IntegrationRenderer<ReactNode> {
|
|
38
41
|
name: string;
|
|
39
42
|
componentDirectory: string;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
private reactRuntimeModules?;
|
|
44
|
+
private readonly routerAdapter?;
|
|
45
|
+
private readonly mdxCompilerOptions?;
|
|
46
|
+
private readonly mdxExtensions;
|
|
47
|
+
private readonly hmrPageMetadataCache?;
|
|
44
48
|
/**
|
|
45
49
|
* Enables explicit graph behavior for React page-entry bundling.
|
|
46
50
|
*
|
|
47
51
|
* When true, page-entry bundles disable AST server-only stripping and rely
|
|
48
52
|
* on explicit dependency declarations for browser graph composition.
|
|
49
53
|
*/
|
|
50
|
-
|
|
54
|
+
private readonly explicitGraphEnabled;
|
|
51
55
|
/** @internal */
|
|
52
56
|
readonly bundleService: ReactBundleService;
|
|
53
57
|
/** @internal */
|
|
54
58
|
readonly pageModuleService: ReactPageModuleService;
|
|
55
59
|
/** @internal */
|
|
56
60
|
readonly hydrationAssetService: ReactHydrationAssetService;
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
});
|
|
61
|
+
/** @internal */
|
|
62
|
+
readonly pagePayloadService: ReactPagePayloadService;
|
|
63
|
+
/** @internal */
|
|
64
|
+
readonly mdxConfigDependencyService: ReactMdxConfigDependencyService;
|
|
65
|
+
constructor(options: ReactRendererOptions);
|
|
63
66
|
protected shouldRenderPageComponent(): boolean;
|
|
64
67
|
/**
|
|
65
68
|
* Reads the declared integration name for a component or layout.
|
|
@@ -77,14 +80,7 @@ export declare class ReactRenderer extends IntegrationRenderer<ReactNode> {
|
|
|
77
80
|
* already selected the React integration.
|
|
78
81
|
*/
|
|
79
82
|
private isReactManagedComponent;
|
|
80
|
-
|
|
81
|
-
* Creates the canonical page-props payload used by router hydration.
|
|
82
|
-
*
|
|
83
|
-
* React pages embedded in a non-React HTML shell still need to expose the same
|
|
84
|
-
* page-data contract as fully React-owned documents so navigation and hydration
|
|
85
|
-
* can read one marker consistently.
|
|
86
|
-
*/
|
|
87
|
-
private buildRouterPageDataScript;
|
|
83
|
+
private getComponentRequires;
|
|
88
84
|
private getRouterDocumentAttributes;
|
|
89
85
|
/**
|
|
90
86
|
* Commits a framework-agnostic component to React semantics.
|
|
@@ -103,27 +99,13 @@ export declare class ReactRenderer extends IntegrationRenderer<ReactNode> {
|
|
|
103
99
|
* by React, we call it directly and require serialized HTML back.
|
|
104
100
|
*/
|
|
105
101
|
private asNonReactShellComponent;
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
*
|
|
109
|
-
* The document payload is intentionally narrower than the full server render
|
|
110
|
-
* input: only routing data, public page props, and explicitly allowed locals are
|
|
111
|
-
* exposed to the browser.
|
|
112
|
-
*/
|
|
113
|
-
private buildSerializedPageProps;
|
|
102
|
+
protected resolveReactRuntimeModules(): ReactRuntimeModules;
|
|
103
|
+
private getReactRuntimeModules;
|
|
114
104
|
/**
|
|
115
105
|
* Appends route hydration assets for a concrete page/view file to the current
|
|
116
106
|
* HTML transformer state.
|
|
117
107
|
*/
|
|
118
108
|
private appendHydrationAssetsForFile;
|
|
119
|
-
/**
|
|
120
|
-
* Resolves metadata for direct `renderToResponse()` calls.
|
|
121
|
-
*
|
|
122
|
-
* View rendering bypasses the normal route-file pipeline, so metadata has to be
|
|
123
|
-
* evaluated here from either the component-level generator or the application
|
|
124
|
-
* default.
|
|
125
|
-
*/
|
|
126
|
-
private resolveViewMetadata;
|
|
127
109
|
/**
|
|
128
110
|
* Renders a non-React layout or HTML template and enforces that mixed shells
|
|
129
111
|
* return serialized HTML.
|
|
@@ -133,21 +115,69 @@ export declare class ReactRenderer extends IntegrationRenderer<ReactNode> {
|
|
|
133
115
|
*/
|
|
134
116
|
private renderNonReactShellComponent;
|
|
135
117
|
/**
|
|
136
|
-
*
|
|
118
|
+
* Renders one React component while preserving already-resolved child HTML.
|
|
119
|
+
*
|
|
120
|
+
* When nested foreign-subtree resolution has already produced child HTML for this
|
|
121
|
+
* component, the child payload must remain raw SSR output rather than a React
|
|
122
|
+
* string child, otherwise React would escape it. This helper renders a unique
|
|
123
|
+
* token through React and swaps that token back to the resolved HTML
|
|
124
|
+
* afterward.
|
|
125
|
+
*
|
|
126
|
+
* @param input Component render input for the current render step.
|
|
127
|
+
* @param context React-specific render context for stable token generation.
|
|
128
|
+
* @returns Serialized component HTML with resolved child markup preserved.
|
|
129
|
+
*/
|
|
130
|
+
private renderComponentHtml;
|
|
131
|
+
/**
|
|
132
|
+
* Restores raw child HTML that was temporarily replaced by a token during React SSR.
|
|
133
|
+
*
|
|
134
|
+
* Queued foreign-subtree resolution may render children through a fragment path before all
|
|
135
|
+
* nested integration tokens are resolved. When that happens, React must never see
|
|
136
|
+
* the resolved child HTML as a normal string child or it would escape it. The
|
|
137
|
+
* runtime context stores the placeholder token and the raw child HTML so the
|
|
138
|
+
* fragment render path can reinsert it before foreign-subtree tokens are handled.
|
|
139
|
+
*/
|
|
140
|
+
private restoreRuntimeChildHtml;
|
|
141
|
+
/**
|
|
142
|
+
* Renders queued child content through React and then resolves nested foreign-subtree tokens.
|
|
137
143
|
*
|
|
138
|
-
* This
|
|
139
|
-
*
|
|
140
|
-
*
|
|
144
|
+
* This path is only used for children that were deferred while React rendered the
|
|
145
|
+
* parent component. It first restores any raw child HTML placeholders owned by the
|
|
146
|
+
* current runtime context, then asks the shared queued foreign-subtree resolver to swap
|
|
147
|
+
* foreign integration tokens with their resolved HTML.
|
|
141
148
|
*/
|
|
142
|
-
private
|
|
149
|
+
private renderQueuedChildrenToHtml;
|
|
143
150
|
/**
|
|
144
|
-
*
|
|
151
|
+
* Resolves queued renderer-owned foreign-subtree tokens produced during React component rendering.
|
|
145
152
|
*
|
|
146
|
-
* React
|
|
147
|
-
*
|
|
148
|
-
*
|
|
153
|
+
* React components can enqueue nested foreign subtrees while the parent HTML is being
|
|
154
|
+
* rendered. This delegates to the shared renderer-owned queue resolver but keeps
|
|
155
|
+
* the React-specific child rendering behavior local so raw child HTML and React's
|
|
156
|
+
* fragment rendering semantics stay coordinated.
|
|
149
157
|
*/
|
|
150
|
-
private
|
|
158
|
+
private resolveQueuedForeignSubtreeHtml;
|
|
159
|
+
private buildHydrationProps;
|
|
160
|
+
/**
|
|
161
|
+
* Builds shared document html contributions for router-backed React pages rendered
|
|
162
|
+
* through a non-React HTML shell.
|
|
163
|
+
*/
|
|
164
|
+
private buildNonReactDocumentContributions;
|
|
165
|
+
/**
|
|
166
|
+
* Renders a foreign integration component that participates in React composition.
|
|
167
|
+
*
|
|
168
|
+
* Non-React components must resolve to serialized HTML so React can embed them as
|
|
169
|
+
* mixed-shell children. Any component-owned dependencies still need to flow
|
|
170
|
+
* through the shared dependency resolver before queued foreign-subtree tokens are finalized.
|
|
171
|
+
*/
|
|
172
|
+
private renderForeignComponentWithSerializedHtml;
|
|
173
|
+
/**
|
|
174
|
+
* Renders a React-owned component and attaches island hydration metadata when possible.
|
|
175
|
+
*
|
|
176
|
+
* This path keeps React-owned SSR, queued foreign-subtree resolution, and optional
|
|
177
|
+
* island hydration wiring together so the public `renderComponent()` method can
|
|
178
|
+
* read as orchestration rather than implementation detail.
|
|
179
|
+
*/
|
|
180
|
+
private renderReactManagedComponent;
|
|
151
181
|
/**
|
|
152
182
|
* Renders a React component for component-level orchestration.
|
|
153
183
|
*
|
|
@@ -156,35 +186,30 @@ export declare class ReactRenderer extends IntegrationRenderer<ReactNode> {
|
|
|
156
186
|
* - When an explicit component instance id is provided, a stable
|
|
157
187
|
* `data-eco-component-id` attribute is attached so island hydration can target it.
|
|
158
188
|
* - Without an explicit instance id, component renders remain plain SSR output.
|
|
189
|
+
* - When resolved child HTML is provided, that foreign subtree is treated as a pure SSR
|
|
190
|
+
* composition step and does not emit hydration assets for the parent wrapper.
|
|
159
191
|
*
|
|
160
192
|
* This preserves DOM shape for global CSS/layout selectors while keeping a
|
|
161
193
|
* deterministic mount target per component instance.
|
|
162
194
|
*/
|
|
163
195
|
renderComponent(input: ComponentRenderInput): Promise<ComponentRenderResult>;
|
|
196
|
+
protected createForeignChildRuntime(options: {
|
|
197
|
+
renderInput: ComponentRenderInput;
|
|
198
|
+
rendererCache: Map<string, IntegrationRenderer<any>>;
|
|
199
|
+
}): import("@ecopages/core").ForeignChildRuntime;
|
|
164
200
|
/**
|
|
165
201
|
* Checks if the given file path corresponds to an MDX file based on configured extensions.
|
|
166
202
|
* @param filePath - The file path to check
|
|
167
203
|
* @returns True if the file is an MDX file
|
|
168
204
|
*/
|
|
169
205
|
isMdxFile(filePath: string): boolean;
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
private collectDeclaredMdxSsrLazyDependencies;
|
|
178
|
-
buildRouteRenderAssets(pagePath: string): Promise<ProcessedAsset[]>;
|
|
179
|
-
/**
|
|
180
|
-
* Imports a page module while normalizing React MDX modules to the same shape
|
|
181
|
-
* as ordinary React page files.
|
|
182
|
-
*
|
|
183
|
-
* MDX page imports can expose `config` separately from the default export. The
|
|
184
|
-
* React renderer reattaches that config to the page component so downstream
|
|
185
|
-
* layout, dependency, and hydration logic can treat MDX and TSX pages the same.
|
|
186
|
-
*/
|
|
187
|
-
protected importPageFile(file: string): Promise<ReactPageModule>;
|
|
206
|
+
protected usesIntegrationPageImporter(file: string): boolean;
|
|
207
|
+
protected importIntegrationPageFile(file: string, options?: RouteModuleLoadOptions): Promise<EcoPageFile>;
|
|
208
|
+
protected normalizeImportedPageFile<TPageModule extends EcoPageFile>(file: string, pageModule: TPageModule): TPageModule;
|
|
209
|
+
protected collectPageBrowserGraphContribution(context: PageBrowserGraphContributionContext): Promise<{
|
|
210
|
+
dependencies?: AssetDefinition[];
|
|
211
|
+
assets?: ProcessedAsset[];
|
|
212
|
+
}>;
|
|
188
213
|
/**
|
|
189
214
|
* Renders a full route response for the filesystem page pipeline.
|
|
190
215
|
*
|
|
@@ -194,24 +219,8 @@ export declare class ReactRenderer extends IntegrationRenderer<ReactNode> {
|
|
|
194
219
|
* React shell tree, and hand the result back as a document body.
|
|
195
220
|
*/
|
|
196
221
|
render({ params, query, props, locals, pageLocals, metadata, Page, Layout, HtmlTemplate, pageProps, }: IntegrationRendererRenderOptions<ReactNode>): Promise<RouteRendererBody>;
|
|
222
|
+
protected getHtmlDocumentContributions(options: HtmlDocumentContributionContext<ReactNode>): HtmlDocumentContribution[] | undefined;
|
|
197
223
|
protected getDocumentAttributes(): Record<string, string> | undefined;
|
|
198
|
-
/**
|
|
199
|
-
* Safely extracts the declared subset of locals for client-side hydration.
|
|
200
|
-
*
|
|
201
|
-
* On dynamic pages with `cache: 'dynamic'`, middleware populates `locals` with
|
|
202
|
-
* request-scoped data (e.g., session). Only keys explicitly declared via
|
|
203
|
-
* `Page.requires` are serialized to the client so sensitive request-only data
|
|
204
|
-
* is not leaked into hydration payloads by default.
|
|
205
|
-
*
|
|
206
|
-
* On static pages, `locals` is a Proxy that throws `LocalsAccessError` on access
|
|
207
|
-
* to prevent accidental use. This method safely detects that case and returns
|
|
208
|
-
* `undefined` instead of throwing.
|
|
209
|
-
*
|
|
210
|
-
* @param locals - The locals object from the render context
|
|
211
|
-
* @param requiredLocals - Keys explicitly requested for client hydration
|
|
212
|
-
* @returns The filtered locals object if serializable, undefined otherwise
|
|
213
|
-
*/
|
|
214
|
-
private getSerializableLocals;
|
|
215
224
|
/**
|
|
216
225
|
* Renders an arbitrary React view through the application's HTML shell.
|
|
217
226
|
*
|
|
@@ -222,4 +231,3 @@ export declare class ReactRenderer extends IntegrationRenderer<ReactNode> {
|
|
|
222
231
|
*/
|
|
223
232
|
renderToResponse<P = Record<string, unknown>>(view: EcoComponent<P>, props: P, ctx: RenderToResponseContext): Promise<Response>;
|
|
224
233
|
}
|
|
225
|
-
export {};
|