@ecopages/core 0.2.0-beta.27 → 0.2.0-beta.28

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.
Files changed (70) hide show
  1. package/README.md +1 -1
  2. package/package.json +42 -26
  3. package/src/eco/eco.js +2 -2
  4. package/src/eco/eco.utils.d.ts +1 -1
  5. package/src/eco/eco.utils.js +1 -1
  6. package/src/hmr/client/hmr-runtime.js +1 -1
  7. package/src/hmr/hmr-file-change-prep.d.ts +1 -1
  8. package/src/hmr/hmr-file-change-prep.js +1 -1
  9. package/src/plugins/processor.d.ts +8 -0
  10. package/src/route-renderer/GRAPH.md +11 -11
  11. package/src/route-renderer/README.md +11 -6
  12. package/src/route-renderer/orchestration/{document-shell-render.service.d.ts → document-shell/document-shell-render.service.d.ts} +19 -2
  13. package/src/route-renderer/orchestration/{document-shell-render.service.js → document-shell/document-shell-render.service.js} +28 -0
  14. package/src/route-renderer/orchestration/{layout-shell-props.service.d.ts → document-shell/layout-shell-props.service.d.ts} +1 -1
  15. package/src/route-renderer/orchestration/{component-render-context.d.ts → foreign-child/component-render-context.d.ts} +1 -1
  16. package/src/route-renderer/orchestration/{component-render-context.js → foreign-child/component-render-context.js} +1 -1
  17. package/src/route-renderer/orchestration/{render-output.utils.d.ts → foreign-child/foreign-child-output.utils.d.ts} +1 -7
  18. package/src/route-renderer/orchestration/{render-output.utils.js → foreign-child/foreign-child-output.utils.js} +1 -26
  19. package/src/route-renderer/orchestration/{foreign-subtree-execution.service.d.ts → foreign-child/foreign-subtree-execution.service.d.ts} +5 -5
  20. package/src/route-renderer/orchestration/{foreign-subtree-execution.service.js → foreign-child/foreign-subtree-execution.service.js} +2 -2
  21. package/src/route-renderer/orchestration/foreign-child/owning-renderer-resolution.d.ts +19 -0
  22. package/src/route-renderer/orchestration/foreign-child/owning-renderer-resolution.js +35 -0
  23. package/src/route-renderer/orchestration/integration-renderer.d.ts +4 -46
  24. package/src/route-renderer/orchestration/integration-renderer.js +53 -157
  25. package/src/route-renderer/orchestration/integration-renderer.test-fixtures.d.ts +75 -0
  26. package/src/route-renderer/orchestration/integration-renderer.test-fixtures.js +177 -0
  27. package/src/route-renderer/orchestration/{component-graph-collectors.d.ts → ownership-graph/component-graph-collectors.d.ts} +4 -4
  28. package/src/route-renderer/orchestration/{component-graph-collectors.js → ownership-graph/component-graph-collectors.js} +1 -1
  29. package/src/route-renderer/orchestration/{component-graph.d.ts → ownership-graph/component-graph.d.ts} +1 -3
  30. package/src/route-renderer/orchestration/{component-graph.js → ownership-graph/component-graph.js} +0 -2
  31. package/src/route-renderer/orchestration/{ownership-validation.service.d.ts → ownership-graph/ownership-validation.service.d.ts} +2 -2
  32. package/src/route-renderer/orchestration/{ownership-validation.service.js → ownership-graph/ownership-validation.service.js} +3 -4
  33. package/src/route-renderer/orchestration/{global-injector-assets.service.d.ts → page-browser-graph/global-injector-assets.service.d.ts} +3 -3
  34. package/src/route-renderer/orchestration/{global-injector-assets.service.js → page-browser-graph/global-injector-assets.service.js} +2 -2
  35. package/src/route-renderer/orchestration/{page-browser-graph-contribution.loader.d.ts → page-browser-graph/page-browser-graph-contribution.loader.d.ts} +1 -1
  36. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.d.ts +12 -0
  37. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.js +29 -0
  38. package/src/route-renderer/orchestration/{page-browser-graph-session.d.ts → page-browser-graph/page-browser-graph-session.d.ts} +3 -3
  39. package/src/route-renderer/orchestration/{page-browser-graph-session.js → page-browser-graph/page-browser-graph-session.js} +1 -1
  40. package/src/route-renderer/orchestration/{page-browser-graph.service.d.ts → page-browser-graph/page-browser-graph.service.d.ts} +3 -3
  41. package/src/route-renderer/orchestration/{page-browser-graph.service.js → page-browser-graph/page-browser-graph.service.js} +3 -3
  42. package/src/route-renderer/orchestration/{processed-asset-dedupe.d.ts → page-browser-graph/processed-asset-dedupe.d.ts} +1 -1
  43. package/src/route-renderer/orchestration/{integration-route-render-adapter.d.ts → route-pipeline/integration-route-render-adapter.d.ts} +3 -3
  44. package/src/route-renderer/orchestration/{integration-route-render-adapter.js → route-pipeline/integration-route-render-adapter.js} +1 -1
  45. package/src/route-renderer/orchestration/route-pipeline/marker-artifact.utils.d.ts +6 -0
  46. package/src/route-renderer/orchestration/route-pipeline/marker-artifact.utils.js +27 -0
  47. package/src/route-renderer/orchestration/{route-html-finalization.service.d.ts → route-pipeline/route-html-finalization.service.d.ts} +2 -2
  48. package/src/route-renderer/orchestration/{route-prepared-options.builder.d.ts → route-pipeline/route-prepared-options.builder.d.ts} +3 -3
  49. package/src/route-renderer/orchestration/{route-prepared-options.builder.js → route-pipeline/route-prepared-options.builder.js} +2 -2
  50. package/src/route-renderer/orchestration/{route-prepared-options.utils.js → route-pipeline/route-prepared-options.utils.js} +1 -1
  51. package/src/route-renderer/orchestration/{route-render-orchestrator.d.ts → route-pipeline/route-render-orchestrator.d.ts} +6 -6
  52. package/src/route-renderer/orchestration/{route-render-orchestrator.js → route-pipeline/route-render-orchestrator.js} +8 -5
  53. package/src/route-renderer/orchestration/string-markup-renderer.js +1 -1
  54. package/src/services/html/html-transformer.service.js +1 -1
  55. package/src/services/invalidation/development-invalidation.service.d.ts +5 -0
  56. package/src/services/invalidation/development-invalidation.service.js +8 -9
  57. package/src/static-site-generator/production-page-browser-graph-prebuild.js +1 -1
  58. package/src/types/internal-types.d.ts +1 -1
  59. package/src/types/public-types.d.ts +1 -1
  60. package/src/watchers/project-watcher.d.ts +3 -3
  61. package/src/watchers/project-watcher.js +4 -4
  62. package/src/route-renderer/orchestration/declared-ownership-graph.d.ts +0 -1
  63. package/src/route-renderer/orchestration/declared-ownership-graph.js +0 -8
  64. package/src/route-renderer/orchestration/template-serialization.d.ts +0 -38
  65. package/src/route-renderer/orchestration/template-serialization.js +0 -45
  66. /package/src/route-renderer/orchestration/{layout-shell-props.service.js → document-shell/layout-shell-props.service.js} +0 -0
  67. /package/src/route-renderer/orchestration/{page-browser-graph-contribution.loader.js → page-browser-graph/page-browser-graph-contribution.loader.js} +0 -0
  68. /package/src/route-renderer/orchestration/{processed-asset-dedupe.js → page-browser-graph/processed-asset-dedupe.js} +0 -0
  69. /package/src/route-renderer/orchestration/{route-html-finalization.service.js → route-pipeline/route-html-finalization.service.js} +0 -0
  70. /package/src/route-renderer/orchestration/{route-prepared-options.utils.d.ts → route-pipeline/route-prepared-options.utils.d.ts} +0 -0
@@ -1,4 +1,4 @@
1
- import type { EcoComponent, OwnershipPlanNodeSource } from '../../types/public-types.js';
1
+ import type { EcoComponent, OwnershipPlanNodeSource } from '../../../types/public-types.js';
2
2
  export type DeclaredOwnershipRoot = {
3
3
  component: EcoComponent;
4
4
  source: Extract<OwnershipPlanNodeSource, 'page' | 'layout' | 'html-template'>;
@@ -32,5 +32,3 @@ export declare function mapComponentGraph<T>(input: {
32
32
  currentIntegrationName: string;
33
33
  mapNode: (node: DeclaredOwnershipNodeInput, children: T[]) => T;
34
34
  }): T[];
35
- /** @deprecated Use `mapComponentGraph` from `component-graph.ts`. */
36
- export declare const mapDeclaredOwnershipGraph: typeof mapComponentGraph;
@@ -90,9 +90,7 @@ function mapComponentGraph(input) {
90
90
  ({ component, source }) => mapComponent(component, source, input.currentIntegrationName, /* @__PURE__ */ new Set())
91
91
  );
92
92
  }
93
- const mapDeclaredOwnershipGraph = mapComponentGraph;
94
93
  export {
95
94
  mapComponentGraph,
96
- mapDeclaredOwnershipGraph,
97
95
  walkComponentGraph
98
96
  };
@@ -1,5 +1,5 @@
1
- import type { EcoPagesAppConfig } from '../../types/internal-types.js';
2
- import type { OwnershipPlanNodeSource, OwnershipValidationError, EcoComponent } from '../../types/public-types.js';
1
+ import type { EcoPagesAppConfig } from '../../../types/internal-types.js';
2
+ import type { OwnershipPlanNodeSource, OwnershipValidationError, EcoComponent } from '../../../types/public-types.js';
3
3
  type OwnershipValidationInput = {
4
4
  currentIntegrationName: string;
5
5
  roots: Array<{
@@ -1,6 +1,5 @@
1
- import { assertEcoDeclaredComponent } from "../../eco/eco-declared-component.js";
2
- import { mapDeclaredOwnershipGraph } from "./declared-ownership-graph.js";
3
- import { walkComponentGraph } from "./component-graph.js";
1
+ import { assertEcoDeclaredComponent } from "../../../eco/eco-declared-component.js";
2
+ import { mapComponentGraph, walkComponentGraph } from "./component-graph.js";
4
3
  class OwnershipValidationService {
5
4
  appConfig;
6
5
  /**
@@ -14,7 +13,7 @@ class OwnershipValidationService {
14
13
  */
15
14
  validate(input) {
16
15
  this.assertDeclaredComponentDependencies(input);
17
- return mapDeclaredOwnershipGraph({
16
+ return mapComponentGraph({
18
17
  roots: input.roots,
19
18
  currentIntegrationName: input.currentIntegrationName,
20
19
  mapNode: ({ component, integrationName, componentId, isForeignToParent }, children) => {
@@ -1,6 +1,6 @@
1
- import type { EcoPagesAppConfig } from '../../types/internal-types.js';
2
- import type { ResolvedLazyTrigger } from '../../types/public-types.js';
3
- import { type AssetProcessingService, type ProcessedAsset } from '../../services/assets/asset-processing-service/index.js';
1
+ import type { EcoPagesAppConfig } from '../../../types/internal-types.js';
2
+ import type { ResolvedLazyTrigger } from '../../../types/public-types.js';
3
+ import { type AssetProcessingService, type ProcessedAsset } from '../../../services/assets/asset-processing-service/index.js';
4
4
  /**
5
5
  * Builds processed global-injector map and bootstrap assets for resolved lazy triggers.
6
6
  */
@@ -2,8 +2,8 @@ import { createRequire } from "node:module";
2
2
  import path from "node:path";
3
3
  import {
4
4
  AssetFactory
5
- } from "../../services/assets/asset-processing-service/index.js";
6
- import { buildGlobalInjectorBootstrapContent, buildGlobalInjectorMapScript } from "../../eco/global-injector-map.js";
5
+ } from "../../../services/assets/asset-processing-service/index.js";
6
+ import { buildGlobalInjectorBootstrapContent, buildGlobalInjectorMapScript } from "../../../eco/global-injector-map.js";
7
7
  async function buildGlobalInjectorAssets(appConfig, assetProcessingService, triggers, currentIntegrationName) {
8
8
  const appProjectDir = appConfig.rootDir ?? appConfig.absolutePaths?.projectDir ?? process.cwd();
9
9
  const appPackageRequire = createRequire(path.join(appProjectDir, "package.json"));
@@ -1,4 +1,4 @@
1
- import type { EcoPageFile, PageBrowserGraphContribution, PageBrowserGraphContributionContext } from '../../types/public-types.js';
1
+ import type { EcoPageFile, PageBrowserGraphContribution, PageBrowserGraphContributionContext } from '../../../types/public-types.js';
2
2
  /**
3
3
  * Loads a page module once and collects declarative browser-graph requirements.
4
4
  *
@@ -0,0 +1,12 @@
1
+ import { type ProcessedAsset } from '../../../services/assets/asset-processing-service/index.js';
2
+ import type { PageBrowserGraphResult, PagePackageResult } from '../../../types/public-types.js';
3
+ /**
4
+ * Merges a page browser graph into an existing page package (or processed dependencies).
5
+ *
6
+ * Deduplicates entry/chunk assets against the existing package and rebuilds the
7
+ * package so downstream HTML finalization sees one canonical graph.
8
+ */
9
+ export declare function mergePageBrowserGraph(currentPagePackage: PagePackageResult | undefined, processedDependencies: ProcessedAsset[], pageBrowserGraph: PageBrowserGraphResult): {
10
+ pagePackage: PagePackageResult;
11
+ mergedGraph: PageBrowserGraphResult;
12
+ };
@@ -0,0 +1,29 @@
1
+ import { createPagePackage } from "../../../services/assets/asset-processing-service/index.js";
2
+ import { buildProcessedAssetDedupeKey, dedupeProcessedAssets } from "./processed-asset-dedupe.js";
3
+ function mergePageBrowserGraph(currentPagePackage, processedDependencies, pageBrowserGraph) {
4
+ const mergedGraph = currentPagePackage?.pageBrowserGraph ? {
5
+ entryAssets: dedupeProcessedAssets([
6
+ ...currentPagePackage.pageBrowserGraph.entryAssets,
7
+ ...pageBrowserGraph.entryAssets
8
+ ]),
9
+ chunkAssets: dedupeProcessedAssets([
10
+ ...currentPagePackage.pageBrowserGraph.chunkAssets,
11
+ ...pageBrowserGraph.chunkAssets
12
+ ])
13
+ } : pageBrowserGraph;
14
+ const pageBrowserGraphAssetKeys = new Set(
15
+ [...mergedGraph.entryAssets, ...mergedGraph.chunkAssets].map((asset) => buildProcessedAssetDedupeKey(asset))
16
+ );
17
+ const baseAssets = currentPagePackage ? currentPagePackage.assets.filter(
18
+ (asset) => !pageBrowserGraphAssetKeys.has(buildProcessedAssetDedupeKey(asset))
19
+ ) : processedDependencies;
20
+ return {
21
+ pagePackage: createPagePackage(dedupeProcessedAssets(baseAssets), {
22
+ pageBrowserGraph: mergedGraph
23
+ }),
24
+ mergedGraph
25
+ };
26
+ }
27
+ export {
28
+ mergePageBrowserGraph
29
+ };
@@ -1,6 +1,6 @@
1
- import type { EcoPagesAppConfig } from '../../types/internal-types.js';
2
- import type { PageBrowserGraphContribution, PageBrowserGraphResult } from '../../types/public-types.js';
3
- import type { ProcessedAsset } from '../../services/assets/asset-processing-service/assets.types.js';
1
+ import type { EcoPagesAppConfig } from '../../../types/internal-types.js';
2
+ import type { PageBrowserGraphContribution, PageBrowserGraphResult } from '../../../types/public-types.js';
3
+ import type { ProcessedAsset } from '../../../services/assets/asset-processing-service/assets.types.js';
4
4
  export type GraphPolicy = 'development' | 'production';
5
5
  export type GraphKey = {
6
6
  integrationName: string;
@@ -1,6 +1,6 @@
1
1
  import path from "node:path";
2
2
  import { createHash } from "node:crypto";
3
- import { appLogger } from "../../global/app-logger.js";
3
+ import { appLogger } from "../../../global/app-logger.js";
4
4
  function isSkipCacheGroupedOutcome(outcome) {
5
5
  return "skipCache" in outcome;
6
6
  }
@@ -1,6 +1,6 @@
1
- import type { EcoPagesAppConfig } from '../../types/internal-types.js';
2
- import type { PageBrowserGraphContribution, PageBrowserGraphResult } from '../../types/public-types.js';
3
- import { type AssetProcessingService } from '../../services/assets/asset-processing-service/index.js';
1
+ import type { EcoPagesAppConfig } from '../../../types/internal-types.js';
2
+ import type { PageBrowserGraphContribution, PageBrowserGraphResult } from '../../../types/public-types.js';
3
+ import { type AssetProcessingService } from '../../../services/assets/asset-processing-service/index.js';
4
4
  import { type GraphPolicy } from './page-browser-graph-session.js';
5
5
  export type PageBrowserGraphResolveInput = {
6
6
  routeFile: string;
@@ -1,9 +1,9 @@
1
1
  import path from "node:path";
2
2
  import { fileSystem } from "@ecopages/file-system";
3
3
  import {
4
- } from "../../services/assets/asset-processing-service/index.js";
5
- import { appLogger } from "../../global/app-logger.js";
6
- import { startupTrace } from "../../diagnostics/startup-trace.js";
4
+ } from "../../../services/assets/asset-processing-service/index.js";
5
+ import { appLogger } from "../../../global/app-logger.js";
6
+ import { startupTrace } from "../../../diagnostics/startup-trace.js";
7
7
  import {
8
8
  collectPageBrowserGraphDependencyPaths,
9
9
  createPageBrowserGraphEntryFingerprint,
@@ -1,3 +1,3 @@
1
- import type { ProcessedAsset } from '../../services/assets/asset-processing-service/index.js';
1
+ import type { ProcessedAsset } from '../../../services/assets/asset-processing-service/index.js';
2
2
  export declare function buildProcessedAssetDedupeKey(asset: ProcessedAsset): string;
3
3
  export declare function dedupeProcessedAssets(assets: ProcessedAsset[]): ProcessedAsset[];
@@ -1,6 +1,6 @@
1
- import type { ProcessedAsset } from '../../services/assets/asset-processing-service/index.js';
2
- import type { HtmlDocumentContribution } from '../../services/html/html-transformer.service.js';
3
- import type { EcoComponent, EcoPageFile, IntegrationRendererRenderOptions, PageBrowserGraphContribution, PageBrowserGraphContributionContext, PagePackageResult, RouteRendererBody, RouteRendererOptions } from '../../types/public-types.js';
1
+ import type { ProcessedAsset } from '../../../services/assets/asset-processing-service/index.js';
2
+ import type { HtmlDocumentContribution } from '../../../services/html/html-transformer.service.js';
3
+ import type { EcoComponent, EcoPageFile, IntegrationRendererRenderOptions, PageBrowserGraphContribution, PageBrowserGraphContributionContext, PagePackageResult, RouteRendererBody, RouteRendererOptions } from '../../../types/public-types.js';
4
4
  import type { RouteHtmlFinalization, RouteRenderOrchestratorAdapter, RouteRenderOrchestratorResolvedInputs } from './route-render-orchestrator.js';
5
5
  /**
6
6
  * Host surface required to build the orchestrator adapter for one integration renderer.
@@ -1,4 +1,4 @@
1
- import { loadPageBrowserGraphContribution } from "./page-browser-graph-contribution.loader.js";
1
+ import { loadPageBrowserGraphContribution } from "../page-browser-graph/page-browser-graph-contribution.loader.js";
2
2
  import { buildRouteHtmlFinalization } from "./route-html-finalization.service.js";
3
3
  function createIntegrationRouteRenderAdapter(host) {
4
4
  return {
@@ -0,0 +1,6 @@
1
+ export declare function decodeHtmlEntities(value: string): string;
2
+ export declare function normalizeUnresolvedMarkerArtifactHtml(html: string): string;
3
+ export declare function inspectUnresolvedMarkerArtifactHtml(html: string): {
4
+ hasUnresolvedMarkerArtifacts: boolean;
5
+ normalizedHtml: string;
6
+ };
@@ -0,0 +1,27 @@
1
+ function decodeHtmlEntities(value) {
2
+ let decoded = value;
3
+ let previous;
4
+ do {
5
+ previous = decoded;
6
+ decoded = decoded.replaceAll("&quot;", '"').replaceAll("&#39;", "'").replaceAll("&#x27;", "'").replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&amp;", "&");
7
+ } while (decoded !== previous);
8
+ return decoded;
9
+ }
10
+ function normalizeUnresolvedMarkerArtifactHtml(html) {
11
+ return html.replace(
12
+ /&(?:amp;)?lt;eco-marker\b[\s\S]*?&(?:amp;)?gt;&(?:amp;)?lt;\/eco-marker&(?:amp;)?gt;/g,
13
+ (marker) => decodeHtmlEntities(marker)
14
+ );
15
+ }
16
+ function inspectUnresolvedMarkerArtifactHtml(html) {
17
+ const normalizedHtml = normalizeUnresolvedMarkerArtifactHtml(html);
18
+ return {
19
+ normalizedHtml,
20
+ hasUnresolvedMarkerArtifacts: normalizedHtml.includes("<eco-marker")
21
+ };
22
+ }
23
+ export {
24
+ decodeHtmlEntities,
25
+ inspectUnresolvedMarkerArtifactHtml,
26
+ normalizeUnresolvedMarkerArtifactHtml
27
+ };
@@ -1,5 +1,5 @@
1
- import type { HtmlDocumentContribution } from '../../services/html/html-transformer.service.js';
2
- import type { IntegrationRendererRenderOptions } from '../../types/public-types.js';
1
+ import type { HtmlDocumentContribution } from '../../../services/html/html-transformer.service.js';
2
+ import type { IntegrationRendererRenderOptions } from '../../../types/public-types.js';
3
3
  import type { RouteHtmlFinalization } from './route-render-orchestrator.js';
4
4
  export type RouteHtmlFinalizationContext<C> = {
5
5
  renderOptions: IntegrationRendererRenderOptions<C>;
@@ -1,6 +1,6 @@
1
- import type { EcoPagesAppConfig } from '../../types/internal-types.js';
2
- import type { EcoComponent, EcoPageComponent, EcoPageFile, HtmlTemplateProps, IntegrationRendererRenderOptions, PageBrowserGraphResult, PageMetadataProps, EcoPageLayoutEntry, RouteRendererOptions } from '../../types/public-types.js';
3
- import { type ProcessedAsset } from '../../services/assets/asset-processing-service/index.js';
1
+ import type { EcoPagesAppConfig } from '../../../types/internal-types.js';
2
+ import type { EcoComponent, EcoPageComponent, EcoPageFile, HtmlTemplateProps, IntegrationRendererRenderOptions, PageBrowserGraphResult, PageMetadataProps, EcoPageLayoutEntry, RouteRendererOptions } from '../../../types/public-types.js';
3
+ import { type ProcessedAsset } from '../../../services/assets/asset-processing-service/index.js';
4
4
  type PreparedRenderInputs = {
5
5
  Page: EcoPageFile['default'] | EcoPageComponent<any>;
6
6
  HtmlTemplate: EcoComponent<HtmlTemplateProps>;
@@ -1,5 +1,5 @@
1
- import { createPagePackage } from "../../services/assets/asset-processing-service/index.js";
2
- import { dedupeProcessedAssets } from "./processed-asset-dedupe.js";
1
+ import { createPagePackage } from "../../../services/assets/asset-processing-service/index.js";
2
+ import { dedupeProcessedAssets } from "../page-browser-graph/processed-asset-dedupe.js";
3
3
  import { createPageLocalsProxy } from "./route-prepared-options.utils.js";
4
4
  function buildPreparedRenderOptions(input) {
5
5
  const { routeOptions, resolvedInputs, resolvedDependencies, allDependencies, pageBrowserGraph, appConfig } = input;
@@ -1,4 +1,4 @@
1
- import { LocalsAccessError } from "../../errors/locals-access-error.js";
1
+ import { LocalsAccessError } from "../../../errors/locals-access-error.js";
2
2
  function createPageLocalsProxy(filePath) {
3
3
  const errorMessage = `[ecopages] Request locals are only available during request-time rendering with cache: 'dynamic'. Page: ${filePath}. If you meant to use locals here, set cache: 'dynamic' and provide locals from route middleware/handlers.`;
4
4
  return new Proxy(
@@ -1,9 +1,9 @@
1
- import type { EcoPagesAppConfig } from '../../types/internal-types.js';
2
- import type { EcoComponent, EcoPageComponent, EcoPageFile, HtmlTemplateProps, IntegrationRendererRenderOptions, PageBrowserGraphContribution, PageBrowserGraphResult, PageMetadataProps, RouteRendererBody, RouteRendererOptions, RouteRenderResult, EcoPageLayoutEntry } from '../../types/public-types.js';
3
- import type { AssetProcessingService, ProcessedAsset } from '../../services/assets/asset-processing-service/index.js';
4
- import type { HtmlDocumentContribution } from '../../services/html/html-transformer.service.js';
5
- import { OwnershipValidationService } from './ownership-validation.service.js';
6
- import { PageBrowserGraphService } from './page-browser-graph.service.js';
1
+ import type { EcoPagesAppConfig } from '../../../types/internal-types.js';
2
+ import type { EcoComponent, EcoPageComponent, EcoPageFile, HtmlTemplateProps, IntegrationRendererRenderOptions, PageBrowserGraphContribution, PageBrowserGraphResult, PageMetadataProps, RouteRendererBody, RouteRendererOptions, RouteRenderResult, EcoPageLayoutEntry } from '../../../types/public-types.js';
3
+ import type { AssetProcessingService, ProcessedAsset } from '../../../services/assets/asset-processing-service/index.js';
4
+ import type { HtmlDocumentContribution } from '../../../services/html/html-transformer.service.js';
5
+ import { OwnershipValidationService } from '../ownership-graph/ownership-validation.service.js';
6
+ import { PageBrowserGraphService } from '../page-browser-graph/page-browser-graph.service.js';
7
7
  export type RouteRenderOrchestratorResolvedInputs = {
8
8
  Page: EcoPageFile['default'] | EcoPageComponent<any>;
9
9
  HtmlTemplate: EcoComponent<HtmlTemplateProps>;
@@ -1,12 +1,15 @@
1
- import { inspectUnresolvedMarkerArtifactHtml } from "./render-output.utils.js";
2
- import { OwnershipValidationService, throwIfOwnershipInvalid } from "./ownership-validation.service.js";
1
+ import { inspectUnresolvedMarkerArtifactHtml } from "./marker-artifact.utils.js";
2
+ import {
3
+ OwnershipValidationService,
4
+ throwIfOwnershipInvalid
5
+ } from "../ownership-graph/ownership-validation.service.js";
3
6
  import {
4
7
  buildEagerSsrLazyAssetsFromGraph,
5
8
  collectResolvedLazyTriggersFromGraph,
6
9
  collectUsedIntegrationDependenciesFromGraph
7
- } from "./component-graph-collectors.js";
8
- import { buildGlobalInjectorAssets } from "./global-injector-assets.service.js";
9
- import { PageBrowserGraphService } from "./page-browser-graph.service.js";
10
+ } from "../ownership-graph/component-graph-collectors.js";
11
+ import { buildGlobalInjectorAssets } from "../page-browser-graph/global-injector-assets.service.js";
12
+ import { PageBrowserGraphService } from "../page-browser-graph/page-browser-graph.service.js";
10
13
  import { buildPreparedRenderOptions } from "./route-prepared-options.builder.js";
11
14
  class RouteRenderOrchestrator {
12
15
  appConfig;
@@ -1,5 +1,5 @@
1
1
  import { IntegrationRenderer } from "./integration-renderer.js";
2
- import { resolveInnermostPageLayout } from "./layout-shell-props.service.js";
2
+ import { resolveInnermostPageLayout } from "./document-shell/layout-shell-props.service.js";
3
3
  class StringMarkupRenderer extends IntegrationRenderer {
4
4
  async renderComponent(input) {
5
5
  if (typeof input.component !== "function") {
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  buildProcessedAssetDedupeKey,
6
6
  dedupeProcessedAssets
7
- } from "../../route-renderer/orchestration/processed-asset-dedupe.js";
7
+ } from "../../route-renderer/orchestration/page-browser-graph/processed-asset-dedupe.js";
8
8
  class HtmlTransformerService {
9
9
  processedDependencies = [];
10
10
  pagePackage;
@@ -87,6 +87,11 @@ export declare class DevelopmentInvalidationService {
87
87
  isServerModuleSourceFile(filePath: string): boolean;
88
88
  /**
89
89
  * Returns whether a processor owns the changed file as an asset input.
90
+ *
91
+ * @remarks
92
+ * Watch config drives processor notifications only. Asset ownership requires
93
+ * declared capabilities so dependency-only watches (for example content
94
+ * collection MDX scans) do not skip server invalidation and HMR.
90
95
  */
91
96
  isProcessorOwnedAsset(filePath: string): boolean;
92
97
  }
@@ -218,21 +218,20 @@ class DevelopmentInvalidationService {
218
218
  }
219
219
  /**
220
220
  * Returns whether a processor owns the changed file as an asset input.
221
+ *
222
+ * @remarks
223
+ * Watch config drives processor notifications only. Asset ownership requires
224
+ * declared capabilities so dependency-only watches (for example content
225
+ * collection MDX scans) do not skip server invalidation and HMR.
221
226
  */
222
227
  isProcessorOwnedAsset(filePath) {
223
228
  for (const processor of this.appConfig.processors.values()) {
224
229
  const capabilities = processor.getAssetCapabilities?.() ?? [];
225
- if (capabilities.length > 0) {
226
- const matchesConfiguredAsset = typeof processor.matchesFileFilter !== "function" || processor.matchesFileFilter(filePath);
227
- if (matchesConfiguredAsset && capabilities.some((capability) => processor.canProcessAsset?.(capability.kind, filePath))) {
228
- return true;
229
- }
230
+ if (capabilities.length === 0) {
230
231
  continue;
231
232
  }
232
- const watchConfig = processor.getWatchConfig();
233
- if (!watchConfig) continue;
234
- const { extensions = [] } = watchConfig;
235
- if (extensions.length && extensions.some((ext) => filePath.endsWith(ext))) {
233
+ const matchesConfiguredAsset = typeof processor.matchesFileFilter !== "function" || processor.matchesFileFilter(filePath);
234
+ if (matchesConfiguredAsset && capabilities.some((capability) => processor.canProcessAsset?.(capability.kind, filePath))) {
236
235
  return true;
237
236
  }
238
237
  }
@@ -1,5 +1,5 @@
1
1
  import path from "node:path";
2
- import { getAppPageBrowserGraphSession } from "../route-renderer/orchestration/page-browser-graph-session.js";
2
+ import { getAppPageBrowserGraphSession } from "../route-renderer/orchestration/page-browser-graph/page-browser-graph-session.js";
3
3
  function shouldPrebuildProductionPageBrowserGraphs() {
4
4
  return process.env.NODE_ENV === "production";
5
5
  }
@@ -12,7 +12,7 @@ import type { DevGraphService } from '../services/runtime-state/dev-graph.servic
12
12
  import type { AppModuleLoader } from '../services/module-loading/app-module-loader.service.js';
13
13
  import type { SourceModuleLoader } from '../services/module-loading/module-loading-types.js';
14
14
  import type { EntrypointDependencyGraph } from '../services/runtime-state/entrypoint-dependency-graph.service.js';
15
- import type { SessionPageBrowserGraphCache } from '../route-renderer/orchestration/page-browser-graph-session.js';
15
+ import type { SessionPageBrowserGraphCache } from '../route-renderer/orchestration/page-browser-graph/page-browser-graph-session.js';
16
16
  import type { ServerInvalidationState } from '../services/runtime-state/server-invalidation-state.service.js';
17
17
  import type { ServerModuleTranspiler } from '../services/module-loading/server-module-transpiler.service.js';
18
18
  import type { RouteModuleBuildCache } from '../services/module-loading/route-module-build-cache.store.js';
@@ -1,7 +1,7 @@
1
1
  import type { Readable } from 'node:stream';
2
2
  import type { ApiResponseBuilder } from '../adapters/shared/api-response.js';
3
3
  import type { BuildExecutor } from '../build/build-adapter.js';
4
- import type { ForeignChildRuntime } from '../route-renderer/orchestration/component-render-context.js';
4
+ import type { ForeignChildRuntime } from '../route-renderer/orchestration/foreign-child/component-render-context.js';
5
5
  import type { EcoPageComponent } from '../eco/eco.types.js';
6
6
  import type { EcoPagesAppConfig } from './internal-types.js';
7
7
  import type { HmrStrategy } from '../hmr/hmr-strategy.js';
@@ -116,9 +116,9 @@ export declare class ProjectWatcher {
116
116
  */
117
117
  private matchesAdditionalWatchPaths;
118
118
  /**
119
- * Checks if a file is handled by a processor.
120
- * Processors that declare asset capabilities own those file types.
121
- * Processors without capabilities fall back to checking watch extensions.
119
+ * Checks if a file is owned by a processor as an asset input.
120
+ * Ownership requires declared asset capabilities; watch config only drives
121
+ * {@link notifyProcessors} notifications.
122
122
  */
123
123
  private isHandledByProcessor;
124
124
  /**
@@ -6,7 +6,7 @@ import {
6
6
  DevelopmentInvalidationService
7
7
  } from "../services/invalidation/development-invalidation.service.js";
8
8
  import { prepareHmrFileChange } from "../hmr/hmr-file-change-prep.js";
9
- import { getAppPageBrowserGraphSession } from "../route-renderer/orchestration/page-browser-graph-session.js";
9
+ import { getAppPageBrowserGraphSession } from "../route-renderer/orchestration/page-browser-graph/page-browser-graph-session.js";
10
10
  import { isRegisteredScriptEntrypoint } from "../hmr/hmr-entrypoint-output.js";
11
11
  import { resolveInternalExecutionDir } from "../utils/resolve-work-dir.js";
12
12
  import { createProjectWatcherIgnorePredicate } from "./project-watcher-ignore.js";
@@ -275,9 +275,9 @@ class ProjectWatcher {
275
275
  return this.invalidationService.matchesAdditionalWatchPaths(filePath);
276
276
  }
277
277
  /**
278
- * Checks if a file is handled by a processor.
279
- * Processors that declare asset capabilities own those file types.
280
- * Processors without capabilities fall back to checking watch extensions.
278
+ * Checks if a file is owned by a processor as an asset input.
279
+ * Ownership requires declared asset capabilities; watch config only drives
280
+ * {@link notifyProcessors} notifications.
281
281
  */
282
282
  isHandledByProcessor(filePath) {
283
283
  return this.invalidationService.isProcessorOwnedAsset(filePath);
@@ -1 +0,0 @@
1
- export { mapComponentGraph, mapDeclaredOwnershipGraph, type ComponentGraphRoot, type ComponentGraphWalkInput, type DeclaredOwnershipNodeInput, type DeclaredOwnershipRoot, } from './component-graph.js';
@@ -1,8 +0,0 @@
1
- import {
2
- mapComponentGraph,
3
- mapDeclaredOwnershipGraph
4
- } from "./component-graph.js";
5
- export {
6
- mapComponentGraph,
7
- mapDeclaredOwnershipGraph
8
- };
@@ -1,38 +0,0 @@
1
- /**
2
- * Minimal template-result shape that core can serialize generically.
3
- *
4
- * @remarks
5
- * Core intentionally models only the transport shape used during deferred
6
- * cross-integration child passing: alternating static string segments plus
7
- * interpolated runtime values. Concrete runtime markers that identify a given
8
- * framework's template payload must stay outside core and be registered by the
9
- * owning integration package.
10
- */
11
- export type SerializableTemplateShape = {
12
- strings: readonly string[];
13
- values?: readonly unknown[];
14
- };
15
- /**
16
- * Integration-owned adapter that teaches core how to serialize one deferred
17
- * template payload shape.
18
- *
19
- * @remarks
20
- * The separation here is intentional: core owns the HTML serialization logic,
21
- * but integrations own runtime-shape detection. That keeps package-specific
22
- * markers such as framework template sentinels out of core while still letting
23
- * deferred children round-trip through mixed renderer boundaries.
24
- */
25
- export type DeferredTemplateSerializer<TTemplate extends SerializableTemplateShape = SerializableTemplateShape> = {
26
- matches(value: unknown): value is TTemplate;
27
- serialize(template: TTemplate, serializeValue: (value: unknown) => string | undefined): string;
28
- };
29
- /**
30
- * Serializes a generic template shape into HTML.
31
- *
32
- * @remarks
33
- * This handles only HTML reconstruction semantics: quoted attribute values,
34
- * boolean attributes, and omission of client-only event or property bindings.
35
- * It does not decide whether an arbitrary value belongs to a framework-specific
36
- * template runtime; integrations must make that decision before delegating here.
37
- */
38
- export declare function serializeTemplateShape(template: SerializableTemplateShape, serializeValue: (value: unknown) => string | undefined): string;
@@ -1,45 +0,0 @@
1
- import { escapeHtmlAttribute } from "../../utils/html-escaping.js";
2
- const ATTRIBUTE_TAIL_PATTERN = /(\s+)([@.?!]?)([^\s"'<>/=`@.?!]+)=$/;
3
- function getSerializableTemplateAttribute(stringPart) {
4
- const match = ATTRIBUTE_TAIL_PATTERN.exec(stringPart);
5
- if (!match) return void 0;
6
- return {
7
- leading: stringPart.slice(0, match.index),
8
- whitespace: match[1],
9
- prefix: match[2],
10
- name: match[3]
11
- };
12
- }
13
- function serializeTemplateShape(template, serializeValue) {
14
- const values = template.values ?? [];
15
- let html = "";
16
- for (let index = 0; index < values.length; index += 1) {
17
- const stringPart = template.strings[index] ?? "";
18
- const serializedValue = serializeValue(values[index]);
19
- const attribute = getSerializableTemplateAttribute(stringPart);
20
- if (!attribute) {
21
- html += stringPart;
22
- html += serializedValue ?? "";
23
- continue;
24
- }
25
- html += attribute.leading;
26
- if (attribute.prefix === "@" || attribute.prefix === "!" || attribute.prefix === ".") {
27
- continue;
28
- }
29
- if (attribute.prefix === "?") {
30
- if (serializedValue) {
31
- html += `${attribute.whitespace}${attribute.name}`;
32
- }
33
- continue;
34
- }
35
- if (serializedValue === void 0) {
36
- continue;
37
- }
38
- html += `${attribute.whitespace}${attribute.name}="${escapeHtmlAttribute(serializedValue)}"`;
39
- }
40
- html += template.strings[values.length] ?? "";
41
- return html;
42
- }
43
- export {
44
- serializeTemplateShape
45
- };