@ecopages/core 0.2.0-rc.0 → 0.2.0-rc.2
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 -1
- package/package.json +11 -3
- package/src/adapters/bun/create-app.d.ts +2 -2
- package/src/adapters/shared/http/define-api-handler.d.ts +7 -49
- package/src/build/README.md +1 -1
- package/src/build/rolldown/rolldown-adapter-helpers.js +15 -6
- package/src/build/rolldown/runtime-build-output-normalizer.js +3 -29
- package/src/plugins/README.md +2 -1
- package/src/plugins/integration-plugin.d.ts +4 -9
- package/src/plugins/processor.d.ts +13 -0
- package/src/plugins/processor.js +21 -0
- package/src/route-renderer/README.md +1 -1
- package/src/route-renderer/orchestration/document-shell/layout-shell-props.service.d.ts +13 -1
- package/src/route-renderer/orchestration/document-shell/layout-shell-props.service.js +15 -0
- package/src/route-renderer/orchestration/integration-renderer.d.ts +2 -0
- package/src/route-renderer/orchestration/string-markup-renderer.d.ts +1 -1
- package/src/route-renderer/orchestration/string-markup-renderer.js +9 -8
- package/src/types/public-types.d.ts +2 -2
package/README.md
CHANGED
|
@@ -80,7 +80,7 @@ Use this package README as the top-level map, then drill into the focused subsys
|
|
|
80
80
|
|
|
81
81
|
- `src/config/README.md`: config finalization and app-owned runtime/build state
|
|
82
82
|
- `src/plugins/README.md`: integration and processor authoring contracts
|
|
83
|
-
- `src/build/README.md`: build adapter, executor,
|
|
83
|
+
- `src/build/README.md`: build adapter, executor, development build coordination, and standalone Node server packaging
|
|
84
84
|
- `src/services/README.md`: cross-cutting runtime services and orchestration helpers
|
|
85
85
|
- `src/adapters/README.md`: Bun, Node, and shared adapter boundaries
|
|
86
86
|
- `src/dev/README.md`: dev transform server and on-demand client delivery
|
|
@@ -298,6 +298,7 @@ Use these entrypoints when implementing integrations, processors, or source tran
|
|
|
298
298
|
- `@ecopages/core/plugins/processor`
|
|
299
299
|
- `@ecopages/core/plugins/source-transform`
|
|
300
300
|
- `@ecopages/core/route-renderer/orchestration/integration-renderer`
|
|
301
|
+
- `@ecopages/core/route-renderer/orchestration/document-shell/layout-shell-props.service`
|
|
301
302
|
- `@ecopages/core/services/asset-processing-service`
|
|
302
303
|
- `@ecopages/core/hmr/hmr-strategy`
|
|
303
304
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ecopages/core",
|
|
3
|
-
"version": "0.2.0-rc.
|
|
3
|
+
"version": "0.2.0-rc.2",
|
|
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-rc.
|
|
20
|
+
"@ecopages/file-system": "0.2.0-rc.2",
|
|
21
21
|
"@ecopages/logger": "^0.2.3",
|
|
22
22
|
"@ecopages/scripts-injector": "^0.1.5",
|
|
23
23
|
"@oxc-project/runtime": "0.141.0",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"@standard-schema/utils": "^0.3.0"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"@ecopages/dev-toolbar": "0.2.0-rc.
|
|
34
|
+
"@ecopages/dev-toolbar": "0.2.0-rc.2"
|
|
35
35
|
},
|
|
36
36
|
"peerDependenciesMeta": {
|
|
37
37
|
"@ecopages/dev-toolbar": {
|
|
@@ -75,6 +75,10 @@
|
|
|
75
75
|
"types": "./src/route-renderer/orchestration/document-shell/document-shell-render.service.d.ts",
|
|
76
76
|
"default": "./src/route-renderer/orchestration/document-shell/document-shell-render.service.js"
|
|
77
77
|
},
|
|
78
|
+
"./route-renderer/orchestration/document-shell/layout-shell-props.service": {
|
|
79
|
+
"types": "./src/route-renderer/orchestration/document-shell/layout-shell-props.service.d.ts",
|
|
80
|
+
"default": "./src/route-renderer/orchestration/document-shell/layout-shell-props.service.js"
|
|
81
|
+
},
|
|
78
82
|
"./route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils": {
|
|
79
83
|
"types": "./src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.d.ts",
|
|
80
84
|
"default": "./src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.js"
|
|
@@ -363,6 +367,10 @@
|
|
|
363
367
|
"types": "./src/route-renderer/orchestration/document-shell/document-shell-render.service.d.ts",
|
|
364
368
|
"default": "./src/route-renderer/orchestration/document-shell/document-shell-render.service.js"
|
|
365
369
|
},
|
|
370
|
+
"./route-renderer/orchestration/document-shell/layout-shell-props.service.ts": {
|
|
371
|
+
"types": "./src/route-renderer/orchestration/document-shell/layout-shell-props.service.d.ts",
|
|
372
|
+
"default": "./src/route-renderer/orchestration/document-shell/layout-shell-props.service.js"
|
|
373
|
+
},
|
|
366
374
|
"./route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.ts": {
|
|
367
375
|
"types": "./src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.d.ts",
|
|
368
376
|
"default": "./src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.js"
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* @module EcopagesApp
|
|
9
9
|
*/
|
|
10
10
|
import type { Server } from 'bun';
|
|
11
|
-
import type { ApiHandlerContext, RouteGroupBuilder } from '../../types/public-types.js';
|
|
11
|
+
import type { ApiHandlerContext, EcopagesRouteInfo, RouteGroupBuilder } from '../../types/public-types.js';
|
|
12
12
|
import { SharedApplicationAdapter } from '../shared/runtime/application-adapter.js';
|
|
13
13
|
import type { RuntimeHost } from '../shared/runtime/runtime-host.js';
|
|
14
14
|
import type { EcopagesAppOptions } from '../create-app.js';
|
|
@@ -55,7 +55,7 @@ export declare class BunEcopagesApp<WebSocketData = undefined> extends SharedApp
|
|
|
55
55
|
*/
|
|
56
56
|
protected bootServer(): Promise<Server<WebSocketData> | void>;
|
|
57
57
|
stop(force?: boolean): Promise<void>;
|
|
58
|
-
protected resolveAppRoutes(): Promise<
|
|
58
|
+
protected resolveAppRoutes(): Promise<EcopagesRouteInfo[]>;
|
|
59
59
|
}
|
|
60
60
|
/**
|
|
61
61
|
* Factory function to create a Bun application
|
|
@@ -12,55 +12,13 @@ export declare function defineApiHandler<TPath extends string, TSchema extends R
|
|
|
12
12
|
declare const defineApiMethod: <M extends ApiHandler["method"]>(method: M) => <const TPath extends string, TSchema extends RouteSchema | undefined = undefined, TContext extends UniversalContext = UniversalContext>(handler: DefineApiHandlerInput<TPath, TSchema, TContext> & {
|
|
13
13
|
path: TPath;
|
|
14
14
|
}) => ApiHandler<TPath, Request, unknown>;
|
|
15
|
-
export declare const defineGet: <
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
export declare const definePost: <const TPath extends string, TSchema extends RouteSchema | undefined = undefined, TContext extends UniversalContext = UniversalContext>(handler: Omit<ApiHandler<TPath, Request, unknown>, "middleware" | "method" | "schema" | "handler"> & {
|
|
23
|
-
handler: (context: SchemaHandlerContext<TSchema, TContext>) => Promise<Response> | Response;
|
|
24
|
-
middleware?: Middleware<Request, unknown, TContext>[] | undefined;
|
|
25
|
-
schema?: TSchema | undefined;
|
|
26
|
-
} & {
|
|
27
|
-
path: TPath;
|
|
28
|
-
}) => ApiHandler<TPath, Request, unknown>;
|
|
29
|
-
export declare const definePut: <const TPath extends string, TSchema extends RouteSchema | undefined = undefined, TContext extends UniversalContext = UniversalContext>(handler: Omit<ApiHandler<TPath, Request, unknown>, "middleware" | "method" | "schema" | "handler"> & {
|
|
30
|
-
handler: (context: SchemaHandlerContext<TSchema, TContext>) => Promise<Response> | Response;
|
|
31
|
-
middleware?: Middleware<Request, unknown, TContext>[] | undefined;
|
|
32
|
-
schema?: TSchema | undefined;
|
|
33
|
-
} & {
|
|
34
|
-
path: TPath;
|
|
35
|
-
}) => ApiHandler<TPath, Request, unknown>;
|
|
36
|
-
export declare const defineDelete: <const TPath extends string, TSchema extends RouteSchema | undefined = undefined, TContext extends UniversalContext = UniversalContext>(handler: Omit<ApiHandler<TPath, Request, unknown>, "middleware" | "method" | "schema" | "handler"> & {
|
|
37
|
-
handler: (context: SchemaHandlerContext<TSchema, TContext>) => Promise<Response> | Response;
|
|
38
|
-
middleware?: Middleware<Request, unknown, TContext>[] | undefined;
|
|
39
|
-
schema?: TSchema | undefined;
|
|
40
|
-
} & {
|
|
41
|
-
path: TPath;
|
|
42
|
-
}) => ApiHandler<TPath, Request, unknown>;
|
|
43
|
-
export declare const definePatch: <const TPath extends string, TSchema extends RouteSchema | undefined = undefined, TContext extends UniversalContext = UniversalContext>(handler: Omit<ApiHandler<TPath, Request, unknown>, "middleware" | "method" | "schema" | "handler"> & {
|
|
44
|
-
handler: (context: SchemaHandlerContext<TSchema, TContext>) => Promise<Response> | Response;
|
|
45
|
-
middleware?: Middleware<Request, unknown, TContext>[] | undefined;
|
|
46
|
-
schema?: TSchema | undefined;
|
|
47
|
-
} & {
|
|
48
|
-
path: TPath;
|
|
49
|
-
}) => ApiHandler<TPath, Request, unknown>;
|
|
50
|
-
export declare const defineOptions: <const TPath extends string, TSchema extends RouteSchema | undefined = undefined, TContext extends UniversalContext = UniversalContext>(handler: Omit<ApiHandler<TPath, Request, unknown>, "middleware" | "method" | "schema" | "handler"> & {
|
|
51
|
-
handler: (context: SchemaHandlerContext<TSchema, TContext>) => Promise<Response> | Response;
|
|
52
|
-
middleware?: Middleware<Request, unknown, TContext>[] | undefined;
|
|
53
|
-
schema?: TSchema | undefined;
|
|
54
|
-
} & {
|
|
55
|
-
path: TPath;
|
|
56
|
-
}) => ApiHandler<TPath, Request, unknown>;
|
|
57
|
-
export declare const defineHead: <const TPath extends string, TSchema extends RouteSchema | undefined = undefined, TContext extends UniversalContext = UniversalContext>(handler: Omit<ApiHandler<TPath, Request, unknown>, "middleware" | "method" | "schema" | "handler"> & {
|
|
58
|
-
handler: (context: SchemaHandlerContext<TSchema, TContext>) => Promise<Response> | Response;
|
|
59
|
-
middleware?: Middleware<Request, unknown, TContext>[] | undefined;
|
|
60
|
-
schema?: TSchema | undefined;
|
|
61
|
-
} & {
|
|
62
|
-
path: TPath;
|
|
63
|
-
}) => ApiHandler<TPath, Request, unknown>;
|
|
15
|
+
export declare const defineGet: ReturnType<typeof defineApiMethod<'GET'>>;
|
|
16
|
+
export declare const definePost: ReturnType<typeof defineApiMethod<'POST'>>;
|
|
17
|
+
export declare const definePut: ReturnType<typeof defineApiMethod<'PUT'>>;
|
|
18
|
+
export declare const defineDelete: ReturnType<typeof defineApiMethod<'DELETE'>>;
|
|
19
|
+
export declare const definePatch: ReturnType<typeof defineApiMethod<'PATCH'>>;
|
|
20
|
+
export declare const defineOptions: ReturnType<typeof defineApiMethod<'OPTIONS'>>;
|
|
21
|
+
export declare const defineHead: ReturnType<typeof defineApiMethod<'HEAD'>>;
|
|
64
22
|
export declare function json(data: unknown, options?: ResponseOptions): Response;
|
|
65
23
|
export declare function html(content: string, options?: ResponseOptions): Response;
|
|
66
24
|
export declare function redirect(url: string, status?: number): Response;
|
package/src/build/README.md
CHANGED
|
@@ -56,7 +56,7 @@ build/
|
|
|
56
56
|
- `runtime/build-request-policy.ts`: server/browser request constructors and plugin collision rules.
|
|
57
57
|
- `runtime/build-request-identity.ts` / `cache/cache-keys.ts`: canonical request identity and shared cache fingerprints.
|
|
58
58
|
- `contracts/build-types.ts`: the `EcoBuildPlugin` contract used by integrations and processors.
|
|
59
|
-
- `rolldown/rolldown-build-adapter.ts`: the production `BuildAdapter`. Wraps the bundler, normalizes Node output imports, and exposes a normalized `BuildResult`.
|
|
59
|
+
- `rolldown/rolldown-build-adapter.ts`: the production `BuildAdapter`. Wraps the bundler, normalizes Node output imports, and exposes a normalized `BuildResult`. App dependencies remain bare imports; Core-owned runtime packages that need CommonJS named-export interop are bundled, while other Core dependencies resolve to `file:` URLs. Generated server bundles therefore do not require app-level framework dependencies.
|
|
60
60
|
- `rolldown/rolldown-plugin-bridge.ts`: `EcoBuildPlugin[]` → bundler-plugin translation.
|
|
61
61
|
- `runtime/serialized-build-executor.ts`: FIFO queue primitive.
|
|
62
62
|
- `cache/server-entry-build-cache.ts`: production server-entry bundle cache (`.eco/.server-entry/.build-cache.json` + `dist/.server/manifest.json`).
|
|
@@ -20,6 +20,7 @@ import { isDeclaredAppPackageImport, isWorkspacePackageImport, normalizeNodeRunt
|
|
|
20
20
|
const corePackageRequire = createRequire(new URL('../../../package.json', import.meta.url));
|
|
21
21
|
const nodeBuiltinSpecifiers = new Set(builtinModules);
|
|
22
22
|
let corePackageNames;
|
|
23
|
+
const CORE_RUNTIME_BUNDLED_PACKAGES = new Set(['ws']);
|
|
23
24
|
/**
|
|
24
25
|
* Returns the set of packages declared as direct dependencies in core's own
|
|
25
26
|
* `package.json` (all dependency fields combined).
|
|
@@ -102,12 +103,12 @@ function getAppRootRequire(cache, contextRoot) {
|
|
|
102
103
|
* TypeScript or JSX file (source packages); pre-compiled packages are left
|
|
103
104
|
* external so the app's own resolver handles them at runtime.
|
|
104
105
|
* 3. **Everything else** (undeclared transitives) — split into two sub-cases:
|
|
105
|
-
* - A **direct dependency of core** that resolves to a compiled JS file
|
|
106
|
-
*
|
|
107
|
-
* `
|
|
108
|
-
*
|
|
109
|
-
* core's own `package.json`;
|
|
110
|
-
* core's `require` are excluded.
|
|
106
|
+
* - A **direct dependency of core** that resolves to a compiled JS file:
|
|
107
|
+
* externalized so the `runtime-build-output-normalizer` can rewrite the
|
|
108
|
+
* import to an absolute `file://` URL after the build. Runtime packages
|
|
109
|
+
* that require CommonJS named-export interop (currently `ws`) are
|
|
110
|
+
* bundled instead. "Direct" means declared in core's own `package.json`;
|
|
111
|
+
* transitives that merely *resolve through* core's `require` are excluded.
|
|
111
112
|
* - **Everything else** (true transitives like `lexical`, `@lexical/react`):
|
|
112
113
|
* bundled unconditionally. pnpm strict hoisting means these packages
|
|
113
114
|
* are unreachable as bare specifiers from output directories such as
|
|
@@ -128,6 +129,9 @@ function shouldBundlePackageImport(id, contextRoot, appRootRequireCache) {
|
|
|
128
129
|
return Boolean(appResolvedPath && /\.(?:[cm]?ts|tsx|jsx)$/u.test(appResolvedPath));
|
|
129
130
|
}
|
|
130
131
|
if (isCoreDeclaredPackageImport(id)) {
|
|
132
|
+
if (CORE_RUNTIME_BUNDLED_PACKAGES.has(getPackageName(id))) {
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
131
135
|
const coreResolvedPath = tryResolveModule(id, corePackageRequire);
|
|
132
136
|
if (coreResolvedPath && !/\.(?:[cm]?ts|tsx|jsx)$/u.test(coreResolvedPath)) {
|
|
133
137
|
return false;
|
|
@@ -135,6 +139,11 @@ function shouldBundlePackageImport(id, contextRoot, appRootRequireCache) {
|
|
|
135
139
|
}
|
|
136
140
|
return true;
|
|
137
141
|
}
|
|
142
|
+
function getPackageName(specifier) {
|
|
143
|
+
return specifier.startsWith('@')
|
|
144
|
+
? specifier.split('/').slice(0, 2).join('/')
|
|
145
|
+
: (specifier.split('/')[0] ?? specifier);
|
|
146
|
+
}
|
|
138
147
|
function createExternalMatcher(options, appRootRequireCache) {
|
|
139
148
|
const explicitExternals = new Set(options.external ?? []);
|
|
140
149
|
const externalPackages = options.externalPackages === true;
|
|
@@ -6,19 +6,6 @@ import { isBarePackageImportSpecifier } from '../../plugins/tsconfig-import-reso
|
|
|
6
6
|
const corePackageRequire = createRequire(new URL('../../../package.json', import.meta.url));
|
|
7
7
|
const appDeclaredPackageCache = new Map();
|
|
8
8
|
const appWorkspacePackageCache = new Map();
|
|
9
|
-
/**
|
|
10
|
-
* Core-owned packages that are part of the Node adapter's runtime surface and
|
|
11
|
-
* should therefore be preserved as bare specifiers in bundled output.
|
|
12
|
-
*
|
|
13
|
-
* Only list packages whose bare-specifier form will be resolvable from the
|
|
14
|
-
* app's Node.js runtime (i.e. they ship alongside the framework and do not
|
|
15
|
-
* need to be in the app's own package.json).
|
|
16
|
-
*
|
|
17
|
-
* Build-time tools (e.g. oxc-parser, rolldown) deliberately omitted — their
|
|
18
|
-
* imports in server-side output must be rewritten to absolute file: URLs so
|
|
19
|
-
* the bundler does not embed them in app code.
|
|
20
|
-
*/
|
|
21
|
-
const CORE_RUNTIME_BARE_SPECIFIER_PACKAGES = new Set(['ws']);
|
|
22
9
|
function tryResolveRuntimeImport(specifier, resolver) {
|
|
23
10
|
try {
|
|
24
11
|
return resolver.resolve(specifier);
|
|
@@ -143,24 +130,11 @@ export function isDeclaredAppPackageImport(specifier, rootDir) {
|
|
|
143
130
|
* Whether the given bare specifier should be left as-is (not rewritten to a
|
|
144
131
|
* file URL) in bundled output.
|
|
145
132
|
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
* 2. **Core runtime surface packages** — a curated subset of the framework's
|
|
150
|
-
* own dependencies that are part of its public Node adapter surface (e.g.
|
|
151
|
-
* `ws`). These ship alongside the framework and are resolvable from the
|
|
152
|
-
* bundled output's location even when the app has not declared them.
|
|
153
|
-
*
|
|
154
|
-
* Build-time packages declared by core (e.g. `oxc-parser`, `rolldown`) are
|
|
155
|
-
* intentionally *not* included here — their imports must still be rewritten
|
|
156
|
-
* to absolute `file:` URLs so they are not left as bare specifiers in app
|
|
157
|
-
* output.
|
|
133
|
+
* Only app-declared packages qualify: their resolver can find them from a
|
|
134
|
+
* generated server bundle. Core dependencies remain file URLs because a
|
|
135
|
+
* bundle in `dist/.server` is not inside Core's Node.js resolution chain.
|
|
158
136
|
*/
|
|
159
137
|
function isDeclaredInResolutionChain(specifier, rootDir) {
|
|
160
|
-
const packageName = getPackageNameFromSpecifier(specifier);
|
|
161
|
-
if (CORE_RUNTIME_BARE_SPECIFIER_PACKAGES.has(packageName)) {
|
|
162
|
-
return true;
|
|
163
|
-
}
|
|
164
138
|
return isDeclaredAppPackageImport(specifier, rootDir);
|
|
165
139
|
}
|
|
166
140
|
function rewriteRuntimeImportSpecifier(specifier, quote, rootDir) {
|
package/src/plugins/README.md
CHANGED
|
@@ -16,7 +16,8 @@ These contracts are responsible for:
|
|
|
16
16
|
## Main Files
|
|
17
17
|
|
|
18
18
|
- `integration-plugin.ts`: framework-semantics contract for render integrations
|
|
19
|
-
- `
|
|
19
|
+
- `define-integration.ts`: typed factory for integrations that only need declarative config and a renderer class
|
|
20
|
+
- `processor.ts`: asset-transformation contract for processors, including generated `@types` package helpers for virtual modules
|
|
20
21
|
- `runtime-capability.ts`: runtime compatibility declaration types
|
|
21
22
|
- `source-transform.ts`: bundler-neutral source-transform primitive with Ecopages adapters plus app-level Vite plugin composition helpers
|
|
22
23
|
- `eco-component-meta-plugin.ts`: component-identity attribution transform that uses a lexical `eco.` gate, then an Oxc `CallExpression` rewrite
|
|
@@ -64,13 +64,14 @@ export interface IntegrationPluginConfig {
|
|
|
64
64
|
*/
|
|
65
65
|
jsxImportSource?: string;
|
|
66
66
|
}
|
|
67
|
-
type
|
|
67
|
+
type IntegrationRendererConstructorOptions = {
|
|
68
68
|
appConfig: EcoPagesAppConfig;
|
|
69
69
|
assetProcessingService: AssetProcessingService;
|
|
70
70
|
resolvedIntegrationDependencies: ProcessedAsset[];
|
|
71
71
|
rendererModules?: unknown;
|
|
72
72
|
runtimeOrigin: string;
|
|
73
|
-
}
|
|
73
|
+
};
|
|
74
|
+
type RendererClass<C> = new (options: IntegrationRendererConstructorOptions) => IntegrationRenderer<C>;
|
|
74
75
|
/**
|
|
75
76
|
* Base class for framework integrations.
|
|
76
77
|
*
|
|
@@ -186,13 +187,7 @@ export declare abstract class IntegrationPlugin<C = EcoPagesElement> {
|
|
|
186
187
|
*/
|
|
187
188
|
protected createRendererOptions(options?: {
|
|
188
189
|
rendererModules?: unknown;
|
|
189
|
-
}):
|
|
190
|
-
appConfig: EcoPagesAppConfig;
|
|
191
|
-
assetProcessingService: AssetProcessingService;
|
|
192
|
-
resolvedIntegrationDependencies: ProcessedAsset[];
|
|
193
|
-
rendererModules: unknown;
|
|
194
|
-
runtimeOrigin: string;
|
|
195
|
-
};
|
|
190
|
+
}): IntegrationRendererConstructorOptions;
|
|
196
191
|
/**
|
|
197
192
|
* Attaches runtime-only services after a renderer instance has been created.
|
|
198
193
|
*/
|
|
@@ -13,6 +13,19 @@ export declare function resolveGeneratedPath(type: keyof typeof GENERATED_BASE_P
|
|
|
13
13
|
module: string;
|
|
14
14
|
subPath?: string;
|
|
15
15
|
}): string;
|
|
16
|
+
/**
|
|
17
|
+
* Serializes the TypeScript `@types` package manifest for generated virtual-module declarations.
|
|
18
|
+
*/
|
|
19
|
+
export declare function serializeGeneratedTypesPackage(packageName: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Writes the generated `@types` package manifest that TypeScript auto-loads from `node_modules`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function writeGeneratedTypesPackage(options: {
|
|
24
|
+
root: string;
|
|
25
|
+
module: string;
|
|
26
|
+
packageName: string;
|
|
27
|
+
writeFile: (filePath: string, content: string) => void;
|
|
28
|
+
}): void;
|
|
16
29
|
export interface ProcessorWatchContext {
|
|
17
30
|
path: string;
|
|
18
31
|
bridge: IClientBridge;
|
package/src/plugins/processor.js
CHANGED
|
@@ -14,6 +14,27 @@ export function resolveGeneratedPath(type, options) {
|
|
|
14
14
|
const parts = [root, GENERATED_BASE_PATHS[type], module, subPath].filter(Boolean);
|
|
15
15
|
return path.join(...parts);
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Serializes the TypeScript `@types` package manifest for generated virtual-module declarations.
|
|
19
|
+
*/
|
|
20
|
+
export function serializeGeneratedTypesPackage(packageName) {
|
|
21
|
+
return `${JSON.stringify({
|
|
22
|
+
name: packageName,
|
|
23
|
+
version: '0.0.0',
|
|
24
|
+
types: './index.d.js',
|
|
25
|
+
}, null, 2)}\n`;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Writes the generated `@types` package manifest that TypeScript auto-loads from `node_modules`.
|
|
29
|
+
*/
|
|
30
|
+
export function writeGeneratedTypesPackage(options) {
|
|
31
|
+
const packageManifestPath = resolveGeneratedPath('types', {
|
|
32
|
+
root: options.root,
|
|
33
|
+
module: options.module,
|
|
34
|
+
subPath: 'package.json',
|
|
35
|
+
});
|
|
36
|
+
options.writeFile(packageManifestPath, serializeGeneratedTypesPackage(options.packageName));
|
|
37
|
+
}
|
|
17
38
|
/**
|
|
18
39
|
* Base class for content and asset processors that contribute build plugins.
|
|
19
40
|
*
|
|
@@ -63,7 +63,7 @@ Domain folders:
|
|
|
63
63
|
|
|
64
64
|
- `ownership-graph/`: component graph walk/collect and up-front ownership validation
|
|
65
65
|
- `foreign-child/`: active render context, foreign-subtree execution, deferred template serialization
|
|
66
|
-
- `document-shell/`: shared page/layout/html shell composition and attribute stamping helpers
|
|
66
|
+
- `document-shell/`: shared page/layout/html shell composition, layout prop resolution, and attribute stamping helpers
|
|
67
67
|
- `route-pipeline/`: route preparation, final HTML capture, marker-artifact enforcement
|
|
68
68
|
- `page-browser-graph/`: browser asset graph build, session cache, and injector assets
|
|
69
69
|
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import type { EcoPageLayoutEntry, LayoutPropsContext } from '../../../types/public-types.js';
|
|
1
|
+
import type { EcoComponent, EcoPageLayoutEntry, LayoutPropsContext } from '../../../types/public-types.js';
|
|
2
|
+
import type { DocumentShellLayoutInput } from './document-shell-render.service.js';
|
|
2
3
|
export type LayoutShellPropsContext = LayoutPropsContext & {
|
|
3
4
|
pageProps?: Record<string, unknown>;
|
|
4
5
|
};
|
|
6
|
+
export type DocumentShellLayoutResolutionInput = LayoutShellPropsContext & {
|
|
7
|
+
layout?: EcoComponent;
|
|
8
|
+
layoutEntries?: EcoPageLayoutEntry[];
|
|
9
|
+
};
|
|
5
10
|
/**
|
|
6
11
|
* Resolves the default shell props passed to a layout tier during route render.
|
|
7
12
|
*/
|
|
@@ -10,6 +15,13 @@ export declare function resolveLayoutShellProps(context: LayoutShellPropsContext
|
|
|
10
15
|
* Resolves props for one layout entry, merging shell props with an optional factory.
|
|
11
16
|
*/
|
|
12
17
|
export declare function resolveLayoutEntryProps(entry: EcoPageLayoutEntry, context: LayoutShellPropsContext): Record<string, unknown>;
|
|
18
|
+
/**
|
|
19
|
+
* Resolves declarative layout entries into the document-shell inputs used during route render.
|
|
20
|
+
*
|
|
21
|
+
* @remarks Layout prop factories must be evaluated here so integrations do not
|
|
22
|
+
* silently fall back to the innermost layout and discard route-specific props.
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolveDocumentShellLayouts(input: DocumentShellLayoutResolutionInput): DocumentShellLayoutInput[];
|
|
13
25
|
/**
|
|
14
26
|
* Reads the normalized layout stack from a page component config.
|
|
15
27
|
*/
|
|
@@ -22,6 +22,21 @@ export function resolveLayoutEntryProps(entry, context) {
|
|
|
22
22
|
...entry.props(layoutPropsContext),
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Resolves declarative layout entries into the document-shell inputs used during route render.
|
|
27
|
+
*
|
|
28
|
+
* @remarks Layout prop factories must be evaluated here so integrations do not
|
|
29
|
+
* silently fall back to the innermost layout and discard route-specific props.
|
|
30
|
+
*/
|
|
31
|
+
export function resolveDocumentShellLayouts(input) {
|
|
32
|
+
if (input.layoutEntries && input.layoutEntries.length > 0) {
|
|
33
|
+
return input.layoutEntries.map((entry) => ({
|
|
34
|
+
component: entry.component,
|
|
35
|
+
props: resolveLayoutEntryProps(entry, input),
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
return input.layout ? [{ component: input.layout, props: resolveLayoutShellProps(input) }] : [];
|
|
39
|
+
}
|
|
25
40
|
/**
|
|
26
41
|
* Reads the normalized layout stack from a page component config.
|
|
27
42
|
*/
|
|
@@ -16,6 +16,7 @@ import { type ResolvedPageDependencies } from '../page-loading/resolved-page-dep
|
|
|
16
16
|
import { type GroupedGraphBuildPlan } from './page-browser-graph/grouped-graph-build-plan.js';
|
|
17
17
|
import type { ForeignChildRuntime } from './foreign-child/component-render-context.js';
|
|
18
18
|
import { ForeignSubtreeExecutionService } from './foreign-child/foreign-subtree-execution.service.js';
|
|
19
|
+
import { type DocumentShellLayoutInput } from './document-shell/document-shell-render.service.js';
|
|
19
20
|
/**
|
|
20
21
|
* Controls how one route module is loaded outside the normal render path.
|
|
21
22
|
*/
|
|
@@ -210,6 +211,7 @@ export declare abstract class IntegrationRenderer<C = EcoPagesElement> {
|
|
|
210
211
|
component: EcoComponent;
|
|
211
212
|
props?: Record<string, unknown>;
|
|
212
213
|
};
|
|
214
|
+
layouts?: DocumentShellLayoutInput[];
|
|
213
215
|
htmlTemplate: EcoComponent;
|
|
214
216
|
metadata: PageMetadataProps;
|
|
215
217
|
pageProps: Record<string, unknown>;
|
|
@@ -9,6 +9,6 @@ import { IntegrationRenderer, type RenderToResponseContext } from './integration
|
|
|
9
9
|
*/
|
|
10
10
|
export declare abstract class StringMarkupRenderer extends IntegrationRenderer<EcoPagesElement> {
|
|
11
11
|
renderComponent(input: ComponentRenderInput): Promise<ComponentRenderResult>;
|
|
12
|
-
render({ params, query, props, locals, pageLocals, metadata, Page, Layout, HtmlTemplate, pageProps, }: IntegrationRendererRenderOptions): Promise<RouteRendererBody>;
|
|
12
|
+
render({ params, query, props, locals, pageLocals, metadata, Page, Layout, layoutEntries, HtmlTemplate, pageProps, }: IntegrationRendererRenderOptions): Promise<RouteRendererBody>;
|
|
13
13
|
renderToResponse<P = Record<string, unknown>>(view: EcoComponent<P>, props: P, ctx: RenderToResponseContext): Promise<Response>;
|
|
14
14
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IntegrationRenderer } from './integration-renderer.js';
|
|
2
|
-
import { resolveInnermostPageLayout } from './document-shell/layout-shell-props.service.js';
|
|
2
|
+
import { resolveDocumentShellLayouts, resolveInnermostPageLayout, } from './document-shell/layout-shell-props.service.js';
|
|
3
3
|
/**
|
|
4
4
|
* Base renderer for integrations whose page output is string HTML markup.
|
|
5
5
|
*
|
|
@@ -14,19 +14,20 @@ export class StringMarkupRenderer extends IntegrationRenderer {
|
|
|
14
14
|
}
|
|
15
15
|
return this.renderStringComponentWithQueuedForeignSubtrees(input, input.component);
|
|
16
16
|
}
|
|
17
|
-
async render({ params, query, props, locals, pageLocals, metadata, Page, Layout, HtmlTemplate, pageProps, }) {
|
|
17
|
+
async render({ params, query, props, locals, pageLocals, metadata, Page, Layout, layoutEntries, HtmlTemplate, pageProps, }) {
|
|
18
18
|
try {
|
|
19
19
|
return await this.renderPageWithDocumentShell({
|
|
20
20
|
page: {
|
|
21
21
|
component: Page,
|
|
22
22
|
props: { params, query, ...props, locals: pageLocals },
|
|
23
23
|
},
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
layouts: resolveDocumentShellLayouts({
|
|
25
|
+
layout: Layout,
|
|
26
|
+
layoutEntries,
|
|
27
|
+
params,
|
|
28
|
+
query,
|
|
29
|
+
locals,
|
|
30
|
+
}),
|
|
30
31
|
htmlTemplate: HtmlTemplate,
|
|
31
32
|
metadata,
|
|
32
33
|
pageProps: pageProps ?? props ?? {},
|
|
@@ -603,8 +603,8 @@ export interface HtmlTemplateProps<T = EcoPagesElement> extends PageHeadProps<T>
|
|
|
603
603
|
* Request-scoped context available to layout prop factories on `eco.page`.
|
|
604
604
|
*/
|
|
605
605
|
export type LayoutPropsContext = {
|
|
606
|
-
params?:
|
|
607
|
-
query?:
|
|
606
|
+
params?: PageParams;
|
|
607
|
+
query?: PageQuery;
|
|
608
608
|
locals?: RequestLocals;
|
|
609
609
|
};
|
|
610
610
|
/**
|