@ecopages/core 0.2.0-alpha.12 → 0.2.0-alpha.13
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 +7 -28
- package/README.md +5 -4
- package/package.json +2 -2
- package/src/adapters/bun/hmr-manager.js +2 -2
- package/src/adapters/node/node-hmr-manager.js +2 -2
- package/src/adapters/node/server-adapter.d.ts +2 -2
- package/src/adapters/node/server-adapter.js +5 -5
- package/src/build/build-adapter.d.ts +7 -6
- package/src/build/build-adapter.js +6 -7
- package/src/eco/eco.js +15 -6
- package/src/eco/eco.utils.d.ts +1 -1
- package/src/eco/eco.utils.js +5 -1
- package/src/hmr/hmr-strategy.d.ts +2 -2
- package/src/integrations/ghtml/ghtml-renderer.d.ts +6 -1
- package/src/integrations/ghtml/ghtml-renderer.js +29 -28
- package/src/plugins/integration-plugin.d.ts +1 -24
- package/src/plugins/integration-plugin.js +0 -14
- package/src/route-renderer/GRAPH.md +54 -84
- package/src/route-renderer/README.md +11 -22
- package/src/route-renderer/orchestration/component-render-context.d.ts +33 -84
- package/src/route-renderer/orchestration/component-render-context.js +30 -108
- package/src/route-renderer/orchestration/integration-renderer.d.ts +219 -96
- package/src/route-renderer/orchestration/integration-renderer.js +416 -236
- package/src/route-renderer/orchestration/queued-boundary-runtime.service.d.ts +93 -0
- package/src/route-renderer/orchestration/queued-boundary-runtime.service.js +155 -0
- package/src/route-renderer/orchestration/render-execution.service.d.ts +8 -71
- package/src/route-renderer/orchestration/render-execution.service.js +28 -115
- package/src/route-renderer/orchestration/render-output.utils.d.ts +6 -0
- package/src/route-renderer/orchestration/render-output.utils.js +25 -0
- package/src/route-renderer/orchestration/render-preparation.service.d.ts +0 -9
- package/src/route-renderer/orchestration/render-preparation.service.js +3 -34
- package/src/route-renderer/page-loading/dependency-resolver.js +6 -1
- package/src/route-renderer/page-loading/page-module-loader.d.ts +1 -2
- package/src/route-renderer/page-loading/page-module-loader.js +0 -2
- package/src/router/client/navigation-coordinator.js +2 -2
- package/src/router/server/fs-router-scanner.js +6 -1
- package/src/services/runtime-state/dev-graph.service.d.ts +5 -5
- package/src/services/runtime-state/dev-graph.service.js +10 -10
- package/src/types/public-types.d.ts +2 -5
- package/src/eco/component-render-context.d.ts +0 -2
- package/src/eco/component-render-context.js +0 -12
- package/src/route-renderer/component-graph/component-graph-executor.d.ts +0 -33
- package/src/route-renderer/component-graph/component-graph-executor.js +0 -30
- package/src/route-renderer/component-graph/component-graph.d.ts +0 -53
- package/src/route-renderer/component-graph/component-graph.js +0 -94
- package/src/route-renderer/component-graph/component-marker.d.ts +0 -52
- package/src/route-renderer/component-graph/component-marker.js +0 -44
- package/src/route-renderer/component-graph/component-reference.d.ts +0 -10
- package/src/route-renderer/component-graph/component-reference.js +0 -34
- package/src/route-renderer/component-graph/marker-graph-resolver.d.ts +0 -79
- package/src/route-renderer/component-graph/marker-graph-resolver.js +0 -117
package/CHANGELOG.md
CHANGED
|
@@ -8,39 +8,18 @@ All notable changes to `@ecopages/core` are documented here.
|
|
|
8
8
|
|
|
9
9
|
### Features
|
|
10
10
|
|
|
11
|
-
- Added
|
|
12
|
-
- Added the browser-safe `eco` export, semantic `eco.html()` and `eco.layout()` helpers, and the internal `.eco` work directory.
|
|
13
|
-
- Added the public `EcoPagesAppConfig` export for published integration packages.
|
|
11
|
+
- Added app-owned runtime and build ownership around `createApp()`, host module loading, the browser-safe `eco` export, `eco.html()`, `eco.layout()`, and the published `EcoPagesAppConfig` surface.
|
|
14
12
|
|
|
15
13
|
### Refactoring
|
|
16
14
|
|
|
17
15
|
- Consolidated runtime state around shared module-loading services, app-owned build execution, and the universal `createApp()` boundary.
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
- Refactored `eco` component factories to delegate deferred-boundary and lazy-output runtime behavior through component render context instead of coupling `eco.ts` directly to marker-graph internals.
|
|
21
|
-
- Moved component render-context implementation under route-renderer orchestration and left `eco` with a thin compatibility re-export.
|
|
22
|
-
- Moved lazy render-output helpers under route-renderer orchestration and left `eco/eco.utils` as a thin compatibility re-export so orchestration no longer depends on the `eco` implementation folder.
|
|
16
|
+
- Simplified route-renderer orchestration around renderer-owned boundary runtimes, shared string-boundary queue helpers, and a smaller component render context.
|
|
17
|
+
- Removed marker-era compatibility capture, the shared route-level fallback resolver, deprecated `@ecopages/core/node*` escape hatches, and other dead route-renderer internals.
|
|
23
18
|
|
|
24
19
|
### Bug Fixes
|
|
25
20
|
|
|
26
|
-
- Fixed
|
|
27
|
-
- Fixed
|
|
28
|
-
- Fixed Bun-backed browser asset output normalization to preserve concrete hashed filenames instead of leaking literal `[hash]` placeholders into emitted script URLs.
|
|
29
|
-
- Fixed generated module wrapper scripts to emit canonical named-import order so identical logical wrappers reuse the same bundled asset across routes.
|
|
30
|
-
- Fixed preview, static-generation, and browser bundle stability for esbuild-backed production paths.
|
|
31
|
-
- Fixed deep marker-graph resolution, watch-mode route refreshes, and duplicate-core fallback references in mixed-runtime rendering.
|
|
32
|
-
- Fixed deferred boundary child serialization to accept explicit template-shape payloads while ignoring unrelated plain-object props unless a renderer-specific serializer or node-like shape supports them.
|
|
33
|
-
- Fixed page-root and marker-graph rendering to preserve captured component graph context and render deferred foreign components under the correct integration context.
|
|
34
|
-
- Fixed npm package output to rewrite workspace dependency versions and publish built JavaScript and declaration artifacts.
|
|
35
|
-
- Fixed app build manifest collection to let integrations contribute browser-only build plugins without rewriting server static-page modules.
|
|
36
|
-
- Fixed Node-side page-module transpilation to target ES2022 so decorator-based server imports preserve modern ESM semantics during development and MDX loading.
|
|
37
|
-
- Fixed the public `EcoPageFile` type to include explicit `componentGraphContext` exports used by marker-graph page loading.
|
|
38
|
-
- Fixed cross-integration shell authoring to expose a shared public `EcoChildren` type instead of forcing local boundary-cast patterns in mixed JSX demos.
|
|
39
|
-
- Fixed object-form `dependencies.scripts` entries with `content` (no `src`) to emit as blocking inline script tags instead of being bundled into hashed external files.
|
|
40
|
-
- Fixed the shared foreign-JSX override build plugin to preserve JSX versus TSX loader behavior and relative-import resolution in host-owned browser bundles.
|
|
41
|
-
- Fixed deferred child serialization to preserve JSX node-like payloads without leaking `nodeType` digits into mixed-integration SSR output.
|
|
42
|
-
- Fixed deferred template-child serialization to preserve quoted Ecopages JSX attribute values when mixed-integration boundaries pass JSX output through foreign shells.
|
|
43
|
-
- Fixed fallback component references to prefer injected `__eco` metadata and share process-wide runtime ids across duplicate module instances without eager stack-based hint registration.
|
|
21
|
+
- Fixed mixed-integration page, layout, document, and component rendering to resolve foreign boundaries inside their owning renderer across the built-in integrations.
|
|
22
|
+
- Fixed host/runtime module loading, published build-helper exports, asset output normalization, explicit render flows, and static or preview build stability across Bun, Node, Vite, and Nitro.
|
|
44
23
|
|
|
45
24
|
### Documentation
|
|
46
25
|
|
|
@@ -48,12 +27,12 @@ All notable changes to `@ecopages/core` are documented here.
|
|
|
48
27
|
|
|
49
28
|
### Tests
|
|
50
29
|
|
|
51
|
-
- Added regression coverage for
|
|
30
|
+
- Added regression coverage for app-owned runtime services, Node fallback paths, and cross-runtime invalidation behavior.
|
|
52
31
|
|
|
53
32
|
---
|
|
54
33
|
|
|
55
34
|
## Migration Notes
|
|
56
35
|
|
|
57
|
-
- `createApp` is now the recommended entrypoint. Import it from `@ecopages/core`.
|
|
36
|
+
- `createApp` is now the recommended entrypoint. Import it from `@ecopages/core/create-app`.
|
|
58
37
|
- `defineApiHandler` keeps the same call shape, but the handler context is now explicitly runtime-agnostic.
|
|
59
38
|
- The old explicit `renderingMode` config option has been removed and full orchestration is always active.
|
package/README.md
CHANGED
|
@@ -134,7 +134,7 @@ export default config;
|
|
|
134
134
|
Start the application using `createApp`. It will choose the Bun adapter when Bun is available and fall back to Node otherwise.
|
|
135
135
|
|
|
136
136
|
```typescript
|
|
137
|
-
import { createApp } from '@ecopages/core';
|
|
137
|
+
import { createApp } from '@ecopages/core/create-app';
|
|
138
138
|
import appConfig from './eco.config';
|
|
139
139
|
|
|
140
140
|
const app = await createApp({ appConfig });
|
|
@@ -198,7 +198,7 @@ Attach the handler in your `app.ts` entry:
|
|
|
198
198
|
|
|
199
199
|
```typescript
|
|
200
200
|
// app.ts
|
|
201
|
-
import { createApp } from '@ecopages/core';
|
|
201
|
+
import { createApp } from '@ecopages/core/create-app';
|
|
202
202
|
import { helloWorld } from './handlers/hello';
|
|
203
203
|
import appConfig from './eco.config';
|
|
204
204
|
|
|
@@ -213,10 +213,11 @@ See the [official documentation](https://ecopages.app) for advanced usage, API h
|
|
|
213
213
|
|
|
214
214
|
## Import Structure
|
|
215
215
|
|
|
216
|
-
Use the root package
|
|
216
|
+
Use the `create-app` subpath for runtime startup and the root package for standard authoring helpers:
|
|
217
217
|
|
|
218
218
|
```ts
|
|
219
|
-
import { createApp
|
|
219
|
+
import { createApp } from '@ecopages/core/create-app';
|
|
220
|
+
import { defineApiHandler, defineGroupHandler, eco } from '@ecopages/core';
|
|
220
221
|
```
|
|
221
222
|
|
|
222
223
|
> [!NOTE]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ecopages/core",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.13",
|
|
4
4
|
"description": "Core package for Ecopages",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ecopages",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"directory": "packages/core"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@ecopages/file-system": "0.2.0-alpha.
|
|
20
|
+
"@ecopages/file-system": "0.2.0-alpha.13",
|
|
21
21
|
"@ecopages/logger": "^0.2.3",
|
|
22
22
|
"@ecopages/scripts-injector": "^0.1.3",
|
|
23
23
|
"@worker-tools/html-rewriter": "0.1.0-pre.19",
|
|
@@ -251,7 +251,7 @@ class HmrManager {
|
|
|
251
251
|
*/
|
|
252
252
|
async registerEntrypoint(entrypointPath) {
|
|
253
253
|
return await this.entrypointRegistrar.registerEntrypoint(entrypointPath, {
|
|
254
|
-
emit: async (normalizedEntrypoint
|
|
254
|
+
emit: async (normalizedEntrypoint) => await this.emitStrictEntrypoint(normalizedEntrypoint),
|
|
255
255
|
getMissingOutputError: (normalizedEntrypoint, outputPath) => new Error(
|
|
256
256
|
`[HMR] Integration failed to emit entrypoint ${normalizedEntrypoint} to ${outputPath}. Page entrypoints must be produced by their owning integration.`
|
|
257
257
|
)
|
|
@@ -278,7 +278,7 @@ class HmrManager {
|
|
|
278
278
|
* strategy processing without broadcasting, and then verifies that the owning
|
|
279
279
|
* integration emitted the expected file.
|
|
280
280
|
*/
|
|
281
|
-
async emitStrictEntrypoint(entrypointPath
|
|
281
|
+
async emitStrictEntrypoint(entrypointPath) {
|
|
282
282
|
await this.handleFileChange(entrypointPath, { broadcast: false });
|
|
283
283
|
}
|
|
284
284
|
/**
|
|
@@ -225,7 +225,7 @@ class NodeHmrManager {
|
|
|
225
225
|
*/
|
|
226
226
|
async registerEntrypoint(entrypointPath) {
|
|
227
227
|
return await this.entrypointRegistrar.registerEntrypoint(entrypointPath, {
|
|
228
|
-
emit: async (normalizedEntrypoint
|
|
228
|
+
emit: async (normalizedEntrypoint) => await this.emitStrictEntrypoint(normalizedEntrypoint),
|
|
229
229
|
getMissingOutputError: (normalizedEntrypoint, outputPath) => new Error(
|
|
230
230
|
`[HMR] Integration failed to emit entrypoint ${normalizedEntrypoint} to ${outputPath}. Page entrypoints must be produced by their owning integration.`
|
|
231
231
|
)
|
|
@@ -255,7 +255,7 @@ class NodeHmrManager {
|
|
|
255
255
|
* 3. Let the strategy chain try to emit the entrypoint without broadcasting.
|
|
256
256
|
* 4. Fail if the owning integration did not emit the expected output.
|
|
257
257
|
*/
|
|
258
|
-
async emitStrictEntrypoint(entrypointPath
|
|
258
|
+
async emitStrictEntrypoint(entrypointPath) {
|
|
259
259
|
await this.handleFileChange(entrypointPath, { broadcast: false });
|
|
260
260
|
}
|
|
261
261
|
/**
|
|
@@ -132,7 +132,7 @@ export declare class NodeServerAdapter extends SharedServerAdapter<NodeServerAda
|
|
|
132
132
|
* underlying socket closes early — into a 499 response so it does not
|
|
133
133
|
* incorrectly surface as a 500 in application logs.
|
|
134
134
|
*/
|
|
135
|
-
handleRequest(
|
|
135
|
+
handleRequest(request: Request): Promise<Response>;
|
|
136
136
|
/**
|
|
137
137
|
* Called once the HTTP server is bound and listening.
|
|
138
138
|
*
|
|
@@ -149,7 +149,7 @@ export declare class NodeServerAdapter extends SharedServerAdapter<NodeServerAda
|
|
|
149
149
|
* WebSocket upgrade requests that do not target `/_hmr` are rejected with an
|
|
150
150
|
* immediate socket destroy to prevent unhandled upgrade leaks.
|
|
151
151
|
*/
|
|
152
|
-
completeInitialization(
|
|
152
|
+
completeInitialization(server: NodeServerInstance): Promise<void>;
|
|
153
153
|
}
|
|
154
154
|
/**
|
|
155
155
|
* Factory function that creates and fully initialises a `NodeServerAdapter`.
|
|
@@ -269,12 +269,12 @@ class NodeServerAdapter extends SharedServerAdapter {
|
|
|
269
269
|
* underlying socket closes early — into a 499 response so it does not
|
|
270
270
|
* incorrectly surface as a 500 in application logs.
|
|
271
271
|
*/
|
|
272
|
-
async handleRequest(
|
|
272
|
+
async handleRequest(request) {
|
|
273
273
|
if (!this.initialized) {
|
|
274
274
|
throw new Error("Node server adapter is not initialized. Call createAdapter() first.");
|
|
275
275
|
}
|
|
276
276
|
try {
|
|
277
|
-
return await this.handleSharedRequest(
|
|
277
|
+
return await this.handleSharedRequest(request, {
|
|
278
278
|
apiHandlers: this.apiHandlers,
|
|
279
279
|
errorHandler: this.errorHandler,
|
|
280
280
|
serverInstance: this.serverInstance,
|
|
@@ -303,8 +303,8 @@ class NodeServerAdapter extends SharedServerAdapter {
|
|
|
303
303
|
* WebSocket upgrade requests that do not target `/_hmr` are rejected with an
|
|
304
304
|
* immediate socket destroy to prevent unhandled upgrade leaks.
|
|
305
305
|
*/
|
|
306
|
-
async completeInitialization(
|
|
307
|
-
this.serverInstance =
|
|
306
|
+
async completeInitialization(server) {
|
|
307
|
+
this.serverInstance = server;
|
|
308
308
|
if (this.options?.watch) {
|
|
309
309
|
const { NodeHmrManager } = await import("./node-hmr-manager.js");
|
|
310
310
|
const { WebSocketServer } = await import("ws");
|
|
@@ -313,7 +313,7 @@ class NodeServerAdapter extends SharedServerAdapter {
|
|
|
313
313
|
this.hmrManager = new NodeHmrManager({ appConfig: this.appConfig, bridge: this.bridge });
|
|
314
314
|
this.hmrManager.setEnabled(true);
|
|
315
315
|
await this.hmrManager.buildRuntime();
|
|
316
|
-
|
|
316
|
+
server.on("upgrade", (req, socket, head) => {
|
|
317
317
|
const url = new URL(req.url ?? "/", this.runtimeOrigin);
|
|
318
318
|
if (url.pathname === "/_hmr") {
|
|
319
319
|
wss.handleUpgrade(req, socket, head, (ws) => {
|
|
@@ -130,9 +130,10 @@ export declare function createBuildAdapter(options?: {
|
|
|
130
130
|
export declare const defaultBunBuildAdapter: BuildAdapter;
|
|
131
131
|
export declare const defaultViteHostBuildAdapter: BuildAdapter;
|
|
132
132
|
/**
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
133
|
+
* Bun-native fallback export for callsites that still resolve build state
|
|
134
|
+
* globally.
|
|
135
|
+
*
|
|
136
|
+
* New app-aware code should prefer `getAppBuildAdapter()`.
|
|
136
137
|
*/
|
|
137
138
|
export declare const defaultBuildAdapter: BuildAdapter;
|
|
138
139
|
export declare function getDefaultBuildAdapter(ownership?: BuildOwnership): BuildAdapter;
|
|
@@ -224,9 +225,9 @@ export declare function setAppBuildExecutor(appConfig: EcoPagesAppConfig, buildE
|
|
|
224
225
|
*/
|
|
225
226
|
export declare function build(options: BuildOptions, executor?: BuildExecutor): Promise<BuildResult>;
|
|
226
227
|
/**
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
228
|
+
* Bun-native fallback helper for callsites without app runtime context.
|
|
229
|
+
*
|
|
230
|
+
* New app-aware code should prefer `getAppTranspileOptions()`.
|
|
230
231
|
*/
|
|
231
232
|
export declare function getTranspileOptions(profile: BuildTranspileProfile): BuildTranspileOptions;
|
|
232
233
|
export declare function getAppTranspileOptions(appConfig: EcoPagesAppConfig, profile: BuildTranspileProfile): BuildTranspileOptions;
|
|
@@ -227,9 +227,7 @@ class BunBuildAdapter {
|
|
|
227
227
|
return void 0;
|
|
228
228
|
}
|
|
229
229
|
const basenamePattern = path.basename(outputPath);
|
|
230
|
-
const matcher = new RegExp(
|
|
231
|
-
`^${this.escapeRegExp(basenamePattern).replace(/\\\[hash\\\]/g, "(.+)")}$`
|
|
232
|
-
);
|
|
230
|
+
const matcher = new RegExp(`^${this.escapeRegExp(basenamePattern).replace(/\\\[hash\\\]/g, "(.+)")}$`);
|
|
233
231
|
const matches = fs.readdirSync(directory).filter((candidate) => matcher.test(candidate)).sort();
|
|
234
232
|
if (matches.length === 0) {
|
|
235
233
|
return void 0;
|
|
@@ -259,9 +257,7 @@ class BunBuildAdapter {
|
|
|
259
257
|
return path.join(outdir, resolvedPath);
|
|
260
258
|
}
|
|
261
259
|
const concreteRelativePath = path.relative(outdir, concreteOutputPath).split(path.sep).join("/");
|
|
262
|
-
const matcher = new RegExp(
|
|
263
|
-
`^${this.escapeRegExp(resolvedPath).replace(/\\\[hash\\\]/g, "(.+)")}$`
|
|
264
|
-
);
|
|
260
|
+
const matcher = new RegExp(`^${this.escapeRegExp(resolvedPath).replace(/\\\[hash\\\]/g, "(.+)")}$`);
|
|
265
261
|
const match = concreteRelativePath.match(matcher);
|
|
266
262
|
if (!match?.[1]) {
|
|
267
263
|
return concreteOutputPath;
|
|
@@ -293,7 +289,10 @@ class BunBuildAdapter {
|
|
|
293
289
|
continue;
|
|
294
290
|
}
|
|
295
291
|
normalizedOutputs[index] = {
|
|
296
|
-
path: this.relocateOutputFile(
|
|
292
|
+
path: this.relocateOutputFile(
|
|
293
|
+
concreteOutputPath ?? normalizedOutputs[index].path,
|
|
294
|
+
expectedOutputPath
|
|
295
|
+
)
|
|
297
296
|
};
|
|
298
297
|
}
|
|
299
298
|
return {
|
package/src/eco/eco.js
CHANGED
|
@@ -1,18 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
finalizeComponentRender,
|
|
3
|
+
interceptComponentBoundary
|
|
4
|
+
} from "../route-renderer/orchestration/component-render-context.js";
|
|
5
|
+
import { isThenable } from "../route-renderer/orchestration/render-output.utils.js";
|
|
2
6
|
function createComponentFactory(options) {
|
|
3
7
|
const integrationName = options.integration ?? options.__eco?.integration;
|
|
4
8
|
const comp = ((props) => {
|
|
5
9
|
const componentProps = props ?? {};
|
|
6
|
-
const
|
|
10
|
+
const renderInline = () => finalizeComponentRender(comp, options.render(props));
|
|
11
|
+
const boundaryRender = interceptComponentBoundary({
|
|
7
12
|
component: comp,
|
|
8
13
|
props: componentProps,
|
|
9
14
|
targetIntegration: integrationName
|
|
10
15
|
});
|
|
11
|
-
if (
|
|
12
|
-
return
|
|
16
|
+
if (isThenable(boundaryRender)) {
|
|
17
|
+
return boundaryRender.then(
|
|
18
|
+
(resolvedBoundaryRender) => resolvedBoundaryRender !== void 0 ? resolvedBoundaryRender : renderInline()
|
|
19
|
+
);
|
|
13
20
|
}
|
|
14
|
-
|
|
15
|
-
|
|
21
|
+
if (boundaryRender !== void 0) {
|
|
22
|
+
return boundaryRender;
|
|
23
|
+
}
|
|
24
|
+
return renderInline();
|
|
16
25
|
});
|
|
17
26
|
comp.config = {
|
|
18
27
|
__eco: options.__eco,
|
package/src/eco/eco.utils.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { addTriggerAttribute, isThenable, wrapWithScriptsInjector } from '../route-renderer/orchestration/render-output.utils.js';
|
|
1
|
+
export { addTriggerAttribute, isThenable, wrapWithScriptsInjector, } from '../route-renderer/orchestration/render-output.utils.js';
|
package/src/eco/eco.utils.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
addTriggerAttribute,
|
|
3
|
+
isThenable,
|
|
4
|
+
wrapWithScriptsInjector
|
|
5
|
+
} from "../route-renderer/orchestration/render-output.utils.js";
|
|
2
6
|
export {
|
|
3
7
|
addTriggerAttribute,
|
|
4
8
|
isThenable,
|
|
@@ -77,8 +77,8 @@ export interface HmrAction {
|
|
|
77
77
|
* whether they match the changed file path.
|
|
78
78
|
*
|
|
79
79
|
* @remarks
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
* Strategies are expected to be stateless and idempotent. The same file change
|
|
81
|
+
* should produce the same result when processed by the same strategy.
|
|
82
82
|
*
|
|
83
83
|
* @example
|
|
84
84
|
* ```typescript
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* This module contains the ghtml renderer
|
|
3
3
|
* @module
|
|
4
4
|
*/
|
|
5
|
-
import type { EcoComponent, EcoPagesElement, IntegrationRendererRenderOptions, RouteRendererBody } from '../../types/public-types.js';
|
|
5
|
+
import type { ComponentRenderInput, ComponentRenderResult, EcoComponent, EcoPagesElement, IntegrationRendererRenderOptions, RouteRendererBody } from '../../types/public-types.js';
|
|
6
6
|
import { IntegrationRenderer, type RenderToResponseContext } from '../../route-renderer/orchestration/integration-renderer.js';
|
|
7
7
|
/**
|
|
8
8
|
* A renderer for the ghtml integration.
|
|
@@ -10,6 +10,11 @@ import { IntegrationRenderer, type RenderToResponseContext } from '../../route-r
|
|
|
10
10
|
*/
|
|
11
11
|
export declare class GhtmlRenderer extends IntegrationRenderer<EcoPagesElement> {
|
|
12
12
|
name: string;
|
|
13
|
+
renderComponent(input: ComponentRenderInput): Promise<ComponentRenderResult>;
|
|
14
|
+
protected createComponentBoundaryRuntime(options: {
|
|
15
|
+
boundaryInput: ComponentRenderInput;
|
|
16
|
+
rendererCache: Map<string, IntegrationRenderer<any>>;
|
|
17
|
+
}): import("../../index.browser.js").ComponentBoundaryRuntime;
|
|
13
18
|
render({ params, query, props, locals, pageLocals, metadata, Page, Layout, HtmlTemplate, }: IntegrationRendererRenderOptions): Promise<RouteRendererBody>;
|
|
14
19
|
renderToResponse<P = Record<string, unknown>>(view: EcoComponent<P>, props: P, ctx: RenderToResponseContext): Promise<Response>;
|
|
15
20
|
}
|
|
@@ -4,6 +4,18 @@ import {
|
|
|
4
4
|
import { GHTML_PLUGIN_NAME } from "./ghtml.plugin.js";
|
|
5
5
|
class GhtmlRenderer extends IntegrationRenderer {
|
|
6
6
|
name = GHTML_PLUGIN_NAME;
|
|
7
|
+
async renderComponent(input) {
|
|
8
|
+
return this.renderStringComponentBoundaryWithQueuedForeignBoundaries(
|
|
9
|
+
input,
|
|
10
|
+
input.component
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
createComponentBoundaryRuntime(options) {
|
|
14
|
+
return this.createQueuedBoundaryRuntime({
|
|
15
|
+
boundaryInput: options.boundaryInput,
|
|
16
|
+
rendererCache: options.rendererCache
|
|
17
|
+
});
|
|
18
|
+
}
|
|
7
19
|
async render({
|
|
8
20
|
params,
|
|
9
21
|
query,
|
|
@@ -16,42 +28,31 @@ class GhtmlRenderer extends IntegrationRenderer {
|
|
|
16
28
|
HtmlTemplate
|
|
17
29
|
}) {
|
|
18
30
|
try {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
31
|
+
return await this.renderPageWithDocumentShell({
|
|
32
|
+
page: {
|
|
33
|
+
component: Page,
|
|
34
|
+
props: { params, query, ...props, locals: pageLocals }
|
|
35
|
+
},
|
|
36
|
+
layout: Layout ? {
|
|
37
|
+
component: Layout,
|
|
38
|
+
props: locals ? { locals } : {}
|
|
39
|
+
} : void 0,
|
|
40
|
+
htmlTemplate: HtmlTemplate,
|
|
22
41
|
metadata,
|
|
23
|
-
|
|
24
|
-
pageProps: props || {}
|
|
42
|
+
pageProps: props ?? {}
|
|
25
43
|
});
|
|
26
|
-
return this.DOC_TYPE + body;
|
|
27
44
|
} catch (error) {
|
|
28
45
|
throw this.createRenderError("Error rendering page", error);
|
|
29
46
|
}
|
|
30
47
|
}
|
|
31
48
|
async renderToResponse(view, props, ctx) {
|
|
32
49
|
try {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
} else {
|
|
40
|
-
const children = Layout ? await Layout({ children: pageContent }) : pageContent;
|
|
41
|
-
const HtmlTemplate = await this.getHtmlTemplate();
|
|
42
|
-
const metadata = view.metadata ? await view.metadata({
|
|
43
|
-
params: {},
|
|
44
|
-
query: {},
|
|
45
|
-
props,
|
|
46
|
-
appConfig: this.appConfig
|
|
47
|
-
}) : this.appConfig.defaultMetadata;
|
|
48
|
-
body = this.DOC_TYPE + await HtmlTemplate({
|
|
49
|
-
metadata,
|
|
50
|
-
children,
|
|
51
|
-
pageProps: props
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
return this.createHtmlResponse(body, ctx);
|
|
50
|
+
return await this.renderViewWithDocumentShell({
|
|
51
|
+
view,
|
|
52
|
+
props,
|
|
53
|
+
ctx,
|
|
54
|
+
layout: view.config?.layout
|
|
55
|
+
});
|
|
55
56
|
} catch (error) {
|
|
56
57
|
throw this.createRenderError("Error rendering view", error);
|
|
57
58
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { EcoBuildPlugin } from '../build/build-types.js';
|
|
2
2
|
import type { EcoPagesAppConfig, IHmrManager } from '../types/internal-types.js';
|
|
3
3
|
import type { HmrStrategy } from '../hmr/hmr-strategy.js';
|
|
4
|
-
import type {
|
|
4
|
+
import type { EcoPagesElement } from '../types/public-types.js';
|
|
5
5
|
import type { IntegrationRenderer } from '../route-renderer/orchestration/integration-renderer.js';
|
|
6
6
|
import { AssetProcessingService } from '../services/assets/asset-processing-service/asset-processing.service.js';
|
|
7
7
|
import type { AssetDefinition, ProcessedAsset } from '../services/assets/asset-processing-service/assets.types.js';
|
|
@@ -56,17 +56,6 @@ export interface IntegrationPluginConfig {
|
|
|
56
56
|
*/
|
|
57
57
|
jsxImportSource?: string;
|
|
58
58
|
}
|
|
59
|
-
/**
|
|
60
|
-
* Metadata used by integration-owned boundary policy.
|
|
61
|
-
*
|
|
62
|
-
* This payload describes the currently active integration pass together with the
|
|
63
|
-
* target component boundary being entered.
|
|
64
|
-
*/
|
|
65
|
-
export type ComponentBoundaryPolicyInput = {
|
|
66
|
-
currentIntegration: string;
|
|
67
|
-
targetIntegration?: string;
|
|
68
|
-
component: EcoComponent;
|
|
69
|
-
};
|
|
70
59
|
type RendererClass<C> = new (options: {
|
|
71
60
|
appConfig: EcoPagesAppConfig;
|
|
72
61
|
assetProcessingService: AssetProcessingService;
|
|
@@ -187,18 +176,6 @@ export declare abstract class IntegrationPlugin<C = EcoPagesElement> {
|
|
|
187
176
|
initializeRenderer(options?: {
|
|
188
177
|
rendererModules?: unknown;
|
|
189
178
|
}): IntegrationRenderer<C>;
|
|
190
|
-
/**
|
|
191
|
-
* Declares whether a component boundary targeting this integration should be
|
|
192
|
-
* deferred through the marker pipeline.
|
|
193
|
-
*
|
|
194
|
-
* The default implementation never defers. Integrations that require deferred
|
|
195
|
-
* subtree rendering can override this method and return `true` when their
|
|
196
|
-
* boundary must be resolved during the marker graph stage.
|
|
197
|
-
*
|
|
198
|
-
* @param input Boundary metadata for the current render pass.
|
|
199
|
-
* @returns `true` when the boundary should be deferred; otherwise `false`.
|
|
200
|
-
*/
|
|
201
|
-
shouldDeferComponentBoundary(_input: ComponentBoundaryPolicyInput): boolean;
|
|
202
179
|
/**
|
|
203
180
|
* Prepares build-facing contributions before the app build manifest is sealed.
|
|
204
181
|
*
|
|
@@ -140,20 +140,6 @@ class IntegrationPlugin {
|
|
|
140
140
|
}
|
|
141
141
|
return renderer;
|
|
142
142
|
}
|
|
143
|
-
/**
|
|
144
|
-
* Declares whether a component boundary targeting this integration should be
|
|
145
|
-
* deferred through the marker pipeline.
|
|
146
|
-
*
|
|
147
|
-
* The default implementation never defers. Integrations that require deferred
|
|
148
|
-
* subtree rendering can override this method and return `true` when their
|
|
149
|
-
* boundary must be resolved during the marker graph stage.
|
|
150
|
-
*
|
|
151
|
-
* @param input Boundary metadata for the current render pass.
|
|
152
|
-
* @returns `true` when the boundary should be deferred; otherwise `false`.
|
|
153
|
-
*/
|
|
154
|
-
shouldDeferComponentBoundary(_input) {
|
|
155
|
-
return false;
|
|
156
|
-
}
|
|
157
143
|
/**
|
|
158
144
|
* Prepares build-facing contributions before the app build manifest is sealed.
|
|
159
145
|
*
|