@ecopages/core 0.2.0-beta.26 → 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 (177) hide show
  1. package/README.md +1 -1
  2. package/package.json +98 -74
  3. package/src/adapters/bun/server-adapter.js +2 -2
  4. package/src/adapters/node/server-adapter.js +2 -2
  5. package/src/adapters/shared/hmr-entrypoint-registrar.d.ts +10 -0
  6. package/src/adapters/shared/hmr-entrypoint-registrar.js +34 -10
  7. package/src/adapters/shared/runtime-server-lifecycle.js +1 -1
  8. package/src/adapters/shared/server-static-builder.d.ts +2 -1
  9. package/src/adapters/shared/server-static-builder.js +16 -14
  10. package/src/adapters/shared/shared-hmr-manager.d.ts +11 -4
  11. package/src/adapters/shared/shared-hmr-manager.js +22 -3
  12. package/src/build/README.md +92 -46
  13. package/src/build/app-build-manifest-runtime.d.ts +28 -2
  14. package/src/build/app-build-manifest-runtime.js +26 -10
  15. package/src/build/{browser-runtime-plugin.d.ts → browser/browser-runtime-plugin.d.ts} +1 -1
  16. package/src/build/{browser-runtime-plugin.js → browser/browser-runtime-plugin.js} +1 -1
  17. package/src/build/{jsx-ownership-plugins.d.ts → browser/jsx-ownership-plugins.d.ts} +2 -2
  18. package/src/build/{jsx-ownership-plugins.js → browser/jsx-ownership-plugins.js} +2 -2
  19. package/src/build/build-adapter.d.ts +18 -21
  20. package/src/build/build-adapter.js +8 -43
  21. package/src/build/{build-input-fingerprint.d.ts → cache/build-input-fingerprint.d.ts} +3 -3
  22. package/src/build/cache/cache-constants.d.ts +4 -0
  23. package/src/build/cache/cache-constants.js +6 -0
  24. package/src/build/cache/cache-keys.d.ts +22 -0
  25. package/src/build/cache/cache-keys.js +63 -0
  26. package/src/build/{dev-browser-script-cache.d.ts → cache/dev-browser-script-cache.d.ts} +2 -2
  27. package/src/build/{dev-browser-script-cache.js → cache/dev-browser-script-cache.js} +4 -4
  28. package/src/build/{pages-unified-graph-build.d.ts → cache/pages-unified-graph-build.d.ts} +1 -1
  29. package/src/build/{pages-unified-graph-build.js → cache/pages-unified-graph-build.js} +18 -26
  30. package/src/build/{production-build-cache.d.ts → cache/production-build-cache.d.ts} +1 -1
  31. package/src/build/{production-build-cache.js → cache/production-build-cache.js} +2 -2
  32. package/src/build/{server-entry-build-cache.d.ts → cache/server-entry-build-cache.d.ts} +3 -4
  33. package/src/build/{server-entry-build-cache.js → cache/server-entry-build-cache.js} +16 -12
  34. package/src/build/{build-contracts.d.ts → contracts/build-contracts.d.ts} +1 -2
  35. package/src/build/contracts/build-manifest.d.ts +90 -0
  36. package/src/build/{build-manifest.js → contracts/build-manifest.js} +2 -2
  37. package/src/build/{rolldown-adapter-helpers.d.ts → rolldown/rolldown-adapter-helpers.d.ts} +20 -3
  38. package/src/build/{rolldown-adapter-helpers.js → rolldown/rolldown-adapter-helpers.js} +26 -6
  39. package/src/build/{rolldown-build-adapter.d.ts → rolldown/rolldown-build-adapter.d.ts} +1 -1
  40. package/src/build/{rolldown-plugin-bridge.d.ts → rolldown/rolldown-plugin-bridge.d.ts} +2 -2
  41. package/src/build/{rolldown-plugin-bridge.js → rolldown/rolldown-plugin-bridge.js} +1 -1
  42. package/src/build/{rolldown-source-transform-pass.d.ts → rolldown/rolldown-source-transform-pass.d.ts} +1 -1
  43. package/src/build/{rolldown-source-transform-pass.js → rolldown/rolldown-source-transform-pass.js} +4 -1
  44. package/src/build/{runtime-build-output-normalizer.js → rolldown/runtime-build-output-normalizer.js} +2 -2
  45. package/src/build/{build-profile-options.d.ts → runtime/build-profile-options.d.ts} +2 -2
  46. package/src/build/runtime/build-request-identity.d.ts +17 -0
  47. package/src/build/runtime/build-request-identity.js +54 -0
  48. package/src/build/runtime/build-request-policy.d.ts +59 -0
  49. package/src/build/runtime/build-request-policy.js +46 -0
  50. package/src/build/{build-runtime.d.ts → runtime/build-runtime.d.ts} +8 -4
  51. package/src/build/{build-runtime.js → runtime/build-runtime.js} +11 -11
  52. package/src/build/{deduping-build-executor.d.ts → runtime/deduping-build-executor.d.ts} +2 -9
  53. package/src/build/runtime/deduping-build-executor.js +34 -0
  54. package/src/build/{parallel-build-executor.d.ts → runtime/parallel-build-executor.d.ts} +1 -1
  55. package/src/build/{serialized-build-executor.d.ts → runtime/serialized-build-executor.d.ts} +1 -1
  56. package/src/config/config-builder.d.ts +1 -1
  57. package/src/diagnostics/startup-trace.d.ts +49 -2
  58. package/src/diagnostics/startup-trace.js +140 -8
  59. package/src/eco/eco.js +2 -2
  60. package/src/eco/eco.utils.d.ts +1 -1
  61. package/src/eco/eco.utils.js +1 -1
  62. package/src/hmr/client/hmr-runtime.js +2 -2
  63. package/src/hmr/hmr-file-change-prep.d.ts +10 -0
  64. package/src/hmr/hmr-file-change-prep.js +17 -0
  65. package/src/plugins/alias-resolver-plugin.d.ts +1 -1
  66. package/src/plugins/eco-component-meta-plugin.d.ts +1 -1
  67. package/src/plugins/foreign-jsx-override-plugin.d.ts +1 -1
  68. package/src/plugins/integration-plugin.d.ts +16 -5
  69. package/src/plugins/integration-plugin.js +11 -1
  70. package/src/plugins/processor.d.ts +36 -8
  71. package/src/plugins/source-transform.d.ts +1 -1
  72. package/src/route-renderer/GRAPH.md +22 -28
  73. package/src/route-renderer/README.md +12 -7
  74. package/src/route-renderer/orchestration/{document-shell-render.service.d.ts → document-shell/document-shell-render.service.d.ts} +19 -2
  75. package/src/route-renderer/orchestration/{document-shell-render.service.js → document-shell/document-shell-render.service.js} +28 -0
  76. package/src/route-renderer/orchestration/{layout-shell-props.service.d.ts → document-shell/layout-shell-props.service.d.ts} +1 -1
  77. package/src/route-renderer/orchestration/{component-render-context.d.ts → foreign-child/component-render-context.d.ts} +5 -5
  78. package/src/route-renderer/orchestration/{component-render-context.js → foreign-child/component-render-context.js} +1 -1
  79. package/src/route-renderer/orchestration/{render-output.utils.d.ts → foreign-child/foreign-child-output.utils.d.ts} +15 -7
  80. package/src/route-renderer/orchestration/{render-output.utils.js → foreign-child/foreign-child-output.utils.js} +31 -26
  81. package/src/route-renderer/orchestration/{foreign-subtree-execution.service.d.ts → foreign-child/foreign-subtree-execution.service.d.ts} +5 -5
  82. package/src/route-renderer/orchestration/{foreign-subtree-execution.service.js → foreign-child/foreign-subtree-execution.service.js} +7 -3
  83. package/src/route-renderer/orchestration/foreign-child/owning-renderer-resolution.d.ts +19 -0
  84. package/src/route-renderer/orchestration/foreign-child/owning-renderer-resolution.js +35 -0
  85. package/src/route-renderer/orchestration/integration-renderer.d.ts +14 -97
  86. package/src/route-renderer/orchestration/integration-renderer.js +90 -247
  87. package/src/route-renderer/orchestration/integration-renderer.test-fixtures.d.ts +75 -0
  88. package/src/route-renderer/orchestration/integration-renderer.test-fixtures.js +177 -0
  89. package/src/route-renderer/orchestration/{component-graph-collectors.d.ts → ownership-graph/component-graph-collectors.d.ts} +4 -4
  90. package/src/route-renderer/orchestration/{component-graph-collectors.js → ownership-graph/component-graph-collectors.js} +1 -1
  91. package/src/route-renderer/orchestration/{component-graph.d.ts → ownership-graph/component-graph.d.ts} +1 -3
  92. package/src/route-renderer/orchestration/{component-graph.js → ownership-graph/component-graph.js} +0 -2
  93. package/src/route-renderer/orchestration/{ownership-validation.service.d.ts → ownership-graph/ownership-validation.service.d.ts} +2 -2
  94. package/src/route-renderer/orchestration/{ownership-validation.service.js → ownership-graph/ownership-validation.service.js} +3 -4
  95. package/src/route-renderer/orchestration/{global-injector-assets.service.d.ts → page-browser-graph/global-injector-assets.service.d.ts} +3 -3
  96. package/src/route-renderer/orchestration/{global-injector-assets.service.js → page-browser-graph/global-injector-assets.service.js} +2 -2
  97. package/src/route-renderer/orchestration/{page-browser-graph-contribution.loader.d.ts → page-browser-graph/page-browser-graph-contribution.loader.d.ts} +1 -1
  98. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.d.ts +12 -0
  99. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.js +29 -0
  100. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-session.d.ts +106 -0
  101. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-session.js +436 -0
  102. package/src/route-renderer/orchestration/{page-browser-graph.service.d.ts → page-browser-graph/page-browser-graph.service.d.ts} +12 -6
  103. package/src/route-renderer/orchestration/{page-browser-graph.service.js → page-browser-graph/page-browser-graph.service.js} +91 -42
  104. package/src/route-renderer/orchestration/{processed-asset-dedupe.d.ts → page-browser-graph/processed-asset-dedupe.d.ts} +1 -1
  105. package/src/route-renderer/orchestration/{integration-route-render-adapter.d.ts → route-pipeline/integration-route-render-adapter.d.ts} +3 -10
  106. package/src/route-renderer/orchestration/{integration-route-render-adapter.js → route-pipeline/integration-route-render-adapter.js} +1 -3
  107. package/src/route-renderer/orchestration/route-pipeline/marker-artifact.utils.d.ts +6 -0
  108. package/src/route-renderer/orchestration/route-pipeline/marker-artifact.utils.js +27 -0
  109. package/src/route-renderer/orchestration/{route-html-finalization.service.d.ts → route-pipeline/route-html-finalization.service.d.ts} +2 -3
  110. package/src/route-renderer/orchestration/route-pipeline/route-html-finalization.service.js +21 -0
  111. package/src/route-renderer/orchestration/{route-prepared-options.builder.d.ts → route-pipeline/route-prepared-options.builder.d.ts} +3 -4
  112. package/src/route-renderer/orchestration/{route-prepared-options.builder.js → route-pipeline/route-prepared-options.builder.js} +3 -12
  113. package/src/route-renderer/orchestration/{route-prepared-options.utils.js → route-pipeline/route-prepared-options.utils.js} +1 -1
  114. package/src/route-renderer/orchestration/{route-render-orchestrator.d.ts → route-pipeline/route-render-orchestrator.d.ts} +8 -17
  115. package/src/route-renderer/orchestration/{route-render-orchestrator.js → route-pipeline/route-render-orchestrator.js} +12 -19
  116. package/src/route-renderer/orchestration/string-markup-renderer.js +1 -1
  117. package/src/services/assets/asset-processing-service/asset-processing.service.js +1 -1
  118. package/src/services/assets/asset-processing-service/assets.types.d.ts +1 -1
  119. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.d.ts +1 -1
  120. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.d.ts +0 -2
  121. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.js +2 -15
  122. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.js +1 -1
  123. package/src/services/assets/browser-bundle.service.d.ts +27 -31
  124. package/src/services/assets/browser-bundle.service.js +12 -23
  125. package/src/services/html/html-transformer.service.js +1 -1
  126. package/src/services/invalidation/development-invalidation.service.d.ts +5 -0
  127. package/src/services/invalidation/development-invalidation.service.js +8 -9
  128. package/src/services/module-loading/app-server-module-transpiler.service.d.ts +8 -0
  129. package/src/services/module-loading/app-server-module-transpiler.service.js +1 -7
  130. package/src/services/module-loading/page-module-import.service.d.ts +1 -1
  131. package/src/services/module-loading/page-module-import.service.js +40 -28
  132. package/src/services/module-loading/route-module-build-cache.store.js +1 -1
  133. package/src/services/module-loading/route-module-build-manifest.d.ts +2 -9
  134. package/src/services/module-loading/route-module-build-manifest.js +12 -43
  135. package/src/services/module-loading/server-module-transpiler.service.d.ts +1 -1
  136. package/src/static-site-generator/README.md +1 -1
  137. package/src/static-site-generator/production-page-browser-graph-prebuild.d.ts +28 -0
  138. package/src/static-site-generator/production-page-browser-graph-prebuild.js +22 -0
  139. package/src/static-site-generator/static-build-invalidation.d.ts +2 -2
  140. package/src/static-site-generator/static-build-invalidation.js +3 -3
  141. package/src/static-site-generator/static-site-generator.js +23 -1
  142. package/src/types/internal-types.d.ts +10 -4
  143. package/src/types/public-types.d.ts +59 -10
  144. package/src/watchers/project-watcher.d.ts +3 -3
  145. package/src/watchers/project-watcher.js +15 -5
  146. package/src/build/build-manifest.d.ts +0 -33
  147. package/src/build/deduping-build-executor.js +0 -56
  148. package/src/build/runtime-build-executor.d.ts +0 -14
  149. package/src/build/runtime-build-executor.js +0 -16
  150. package/src/route-renderer/orchestration/declared-ownership-graph.d.ts +0 -1
  151. package/src/route-renderer/orchestration/declared-ownership-graph.js +0 -8
  152. package/src/route-renderer/orchestration/route-html-finalization.service.js +0 -26
  153. package/src/route-renderer/orchestration/template-serialization.d.ts +0 -38
  154. package/src/route-renderer/orchestration/template-serialization.js +0 -45
  155. /package/src/build/{browser-runtime-manifest.d.ts → browser/browser-runtime-manifest.d.ts} +0 -0
  156. /package/src/build/{browser-runtime-manifest.js → browser/browser-runtime-manifest.js} +0 -0
  157. /package/src/build/{browser-runtime-plugin-helpers.d.ts → browser/browser-runtime-plugin-helpers.d.ts} +0 -0
  158. /package/src/build/{browser-runtime-plugin-helpers.js → browser/browser-runtime-plugin-helpers.js} +0 -0
  159. /package/src/build/{lit-static-render-worker-context.d.ts → browser/lit-static-render-worker-context.d.ts} +0 -0
  160. /package/src/build/{lit-static-render-worker-context.js → browser/lit-static-render-worker-context.js} +0 -0
  161. /package/src/build/{build-input-fingerprint.js → cache/build-input-fingerprint.js} +0 -0
  162. /package/src/build/{build-contracts.js → contracts/build-contracts.js} +0 -0
  163. /package/src/build/{build-types.d.ts → contracts/build-types.d.ts} +0 -0
  164. /package/src/build/{build-types.js → contracts/build-types.js} +0 -0
  165. /package/src/build/{rolldown-build-adapter.js → rolldown/rolldown-build-adapter.js} +0 -0
  166. /package/src/build/{rolldown-build-invocation-metrics.d.ts → rolldown/rolldown-build-invocation-metrics.d.ts} +0 -0
  167. /package/src/build/{rolldown-build-invocation-metrics.js → rolldown/rolldown-build-invocation-metrics.js} +0 -0
  168. /package/src/build/{runtime-build-output-normalizer.d.ts → rolldown/runtime-build-output-normalizer.d.ts} +0 -0
  169. /package/src/build/{server-side-css-shim-plugin.d.ts → rolldown/server-side-css-shim-plugin.d.ts} +0 -0
  170. /package/src/build/{server-side-css-shim-plugin.js → rolldown/server-side-css-shim-plugin.js} +0 -0
  171. /package/src/build/{build-profile-options.js → runtime/build-profile-options.js} +0 -0
  172. /package/src/build/{parallel-build-executor.js → runtime/parallel-build-executor.js} +0 -0
  173. /package/src/build/{serialized-build-executor.js → runtime/serialized-build-executor.js} +0 -0
  174. /package/src/route-renderer/orchestration/{layout-shell-props.service.js → document-shell/layout-shell-props.service.js} +0 -0
  175. /package/src/route-renderer/orchestration/{page-browser-graph-contribution.loader.js → page-browser-graph/page-browser-graph-contribution.loader.js} +0 -0
  176. /package/src/route-renderer/orchestration/{processed-asset-dedupe.js → page-browser-graph/processed-asset-dedupe.js} +0 -0
  177. /package/src/route-renderer/orchestration/{route-prepared-options.utils.d.ts → route-pipeline/route-prepared-options.utils.d.ts} +0 -0
@@ -1,4 +1,6 @@
1
- import { createBrowserRuntimeManifest } from "../build/browser-runtime-manifest.js";
1
+ import {
2
+ createBrowserRuntimeManifest
3
+ } from "../build/browser/browser-runtime-manifest.js";
2
4
  import { AssetProcessingService } from "../services/assets/asset-processing-service/asset-processing.service.js";
3
5
  import { deepMerge } from "../utils/deep-merge.js";
4
6
  import { invariant } from "../utils/invariant.js";
@@ -23,6 +25,14 @@ class IntegrationPlugin {
23
25
  appConfig;
24
26
  assetProcessingService;
25
27
  hmrManager;
28
+ /**
29
+ * Returns build plugins shared by server-oriented and browser-oriented builds.
30
+ *
31
+ * @remarks
32
+ * Collected into {@link AppBuildManifest.runtimePlugins} during config finalization.
33
+ * MDX loaders, virtual-module resolvers, and other transforms that must run during
34
+ * route-module transpile belong here—not in {@link browserBuildPlugins}.
35
+ */
26
36
  get plugins() {
27
37
  return [];
28
38
  }
@@ -1,9 +1,9 @@
1
- import type { EcoBuildPlugin } from '../build/build-types.js';
1
+ import type { EcoBuildPlugin } from '../build/contracts/build-types.js';
2
2
  import type { EcoPagesAppConfig, IClientBridge } from '../types/internal-types.js';
3
3
  import { GENERATED_BASE_PATHS } from '../config/constants.js';
4
4
  import type { RuntimeCapabilityDeclaration } from './runtime-capability.js';
5
5
  export type { RuntimeCapabilityDeclaration, RuntimeCapabilityTag } from './runtime-capability.js';
6
- export type { EcoBuildLoader, EcoBuildOnLoadArgs, EcoBuildOnLoadResult, EcoBuildOnResolveArgs, EcoBuildOnResolveResult, EcoBuildPlugin, EcoBuildPluginBuilder, } from '../build/build-types.js';
6
+ export type { EcoBuildLoader, EcoBuildOnLoadArgs, EcoBuildOnLoadResult, EcoBuildOnResolveArgs, EcoBuildOnResolveResult, EcoBuildPlugin, EcoBuildPluginBuilder, } from '../build/contracts/build-types.js';
7
7
  export declare const PROCESSOR_ERRORS: {
8
8
  readonly CACHE_DIRECTORY_NOT_SET: "Cache directory not set in context";
9
9
  };
@@ -19,6 +19,14 @@ export interface ProcessorWatchContext {
19
19
  }
20
20
  export interface ProcessorWatchConfig {
21
21
  paths: string[];
22
+ /**
23
+ * File extensions that trigger watch callbacks (`onCreate`, `onChange`, `onDelete`).
24
+ *
25
+ * @remarks
26
+ * Watch extensions drive notifications only. They do not declare asset ownership.
27
+ * Ownership requires {@link ProcessorConfig.capabilities} and controls whether dev
28
+ * invalidation skips server modules and HMR for processor-handled assets.
29
+ */
22
30
  extensions?: string[];
23
31
  onCreate?: (ctx: ProcessorWatchContext) => Promise<void>;
24
32
  onChange?: (ctx: ProcessorWatchContext) => Promise<void>;
@@ -57,10 +65,17 @@ export interface ProcessorContext {
57
65
  cache?: string;
58
66
  }
59
67
  /**
60
- * Interface for processor build plugins
61
- * This is used to pass plugins to the build process directly from the processor
62
- * For instance it can become very handy when dealing with virtual modules that needs to be recognized by the bundler
63
- * i.e. @ecopages/image-processor
68
+ * Base class for content and asset processors that contribute build plugins.
69
+ *
70
+ * @remarks
71
+ * Processors declare plugins through two getters that map to
72
+ * {@link AppBuildManifest} buckets (names differ from integrations):
73
+ *
74
+ * - `plugins` → `runtimePlugins` (server **and** browser builds)
75
+ * - `buildPlugins` → `browserBundlePlugins` (browser bundles only)
76
+ *
77
+ * Virtual modules that must resolve during route-module transpile belong in
78
+ * `plugins`. Browser-only bundler hooks belong in `buildPlugins`.
64
79
  */
65
80
  export declare abstract class Processor<TOptions = Record<string, unknown>> {
66
81
  readonly name: string;
@@ -69,9 +84,22 @@ export declare abstract class Processor<TOptions = Record<string, unknown>> {
69
84
  protected watchConfig?: ProcessorWatchConfig;
70
85
  protected capabilities: ProcessorAssetCapability[];
71
86
  readonly runtimeCapability?: RuntimeCapabilityDeclaration;
72
- /** Plugins that are only used during the build process */
87
+ /**
88
+ * Browser-bundle-only plugins.
89
+ *
90
+ * @remarks
91
+ * Maps to {@link AppBuildManifest.browserBundlePlugins}. Integrations name the
92
+ * same bucket `browserBuildPlugins`.
93
+ */
73
94
  abstract buildPlugins?: EcoBuildPlugin[];
74
- /** Plugins that are used during runtime for file processing */
95
+ /**
96
+ * Shared build plugins for server-oriented and browser-oriented work.
97
+ *
98
+ * @remarks
99
+ * Maps to {@link AppBuildManifest.runtimePlugins}. Despite the name, these are
100
+ * bundler plugins—not dev-server file processors. Runtime-only setup stays in
101
+ * {@link setup}.
102
+ */
75
103
  abstract plugins?: EcoBuildPlugin[];
76
104
  constructor(config: ProcessorConfig<TOptions>);
77
105
  setContext(appConfig: EcoPagesAppConfig): void;
@@ -1,4 +1,4 @@
1
- import type { EcoBuildPlugin } from '../build/build-types.js';
1
+ import type { EcoBuildPlugin } from '../build/contracts/build-types.js';
2
2
  import type { EcoPagesAppConfig } from '../types/internal-types.js';
3
3
  export interface EcoSourceTransformResult {
4
4
  code: string;
@@ -42,23 +42,17 @@ flowchart TD
42
42
  C --> D[ownershipValidationService.validate]
43
43
  D --> E[resolvePageData]
44
44
  E --> F[ownershipValidationService.validate + throwIfOwnershipInvalid]
45
- F --> G[resolveDependencies]
46
- G --> H[buildPageBrowserGraph]
47
- H --> I{shouldRenderPageComponent?}
48
- I -- Yes --> J[renderPageComponent]
49
- I -- No --> K[skip page-root render]
50
- J --> L[merge component assets]
51
- K --> L
52
- L --> M[collect injector and eager SSR lazy assets]
53
- M --> N[build pagePackage and prepared render options]
54
- N --> O[callbacks.render]
55
- O --> P[capture rendered body as html]
56
- P --> Q[inspect unresolved marker artifacts]
57
- Q --> R{unresolved eco-marker remains?}
58
- R -- Yes --> S[throw unresolved artifact error]
59
- R -- No --> T[stamp root or document attributes when needed]
60
- T --> U[htmlTransformer transform]
61
- U --> V[final body and cache strategy]
45
+ F --> G[resolveDependencies + buildPageBrowserGraph]
46
+ G --> H[collect injector and eager SSR lazy assets]
47
+ H --> I[build pagePackage and prepared render options]
48
+ I --> J[IntegrationRenderer.render via document shell]
49
+ J --> K[capture rendered body as html]
50
+ K --> L[inspect unresolved marker artifacts]
51
+ L --> M{unresolved eco-marker remains?}
52
+ M -- Yes --> N[throw unresolved artifact error]
53
+ M -- No --> O[stamp document attributes when needed]
54
+ O --> P[htmlTransformer transform]
55
+ P --> Q[final body and cache strategy]
62
56
  ```
63
57
 
64
58
  ## 3) Mixed-Integration Render Model
@@ -91,7 +85,7 @@ flowchart TD
91
85
  B -- Yes --> C[return resolved renderer-owned output]
92
86
  B -- No --> D[queue foreign-subtree token]
93
87
  D --> E[finish current render pass]
94
- E --> F[QueuedForeignSubtreeResolutionService resolveQueuedHtml]
88
+ E --> F[ForeignSubtreeExecutionService resolveQueuedHtml]
95
89
  F --> G[resolve nested queued tokens first]
96
90
  G --> H[dispatch foreign subtree to owning renderer]
97
91
  H --> I[merge emitted assets and root attributes]
@@ -121,12 +115,12 @@ flowchart TD
121
115
  The most useful reading order is:
122
116
 
123
117
  1. `route-renderer.ts`
124
- 2. `orchestration/route-render-orchestrator.ts`
118
+ 2. `orchestration/route-pipeline/route-render-orchestrator.ts`
125
119
  3. `orchestration/integration-renderer.ts`
126
- 4. `orchestration/ownership-validation.service.ts`
127
- 5. `orchestration/ownership-planning.service.ts`
128
- 6. `orchestration/component-render-context.ts`
129
- 7. `orchestration/foreign-subtree-execution.service.ts`
120
+ 4. `orchestration/ownership-graph/ownership-validation.service.ts`
121
+ 5. `orchestration/ownership-graph/component-graph.ts`
122
+ 6. `orchestration/foreign-child/component-render-context.ts`
123
+ 7. `orchestration/foreign-child/foreign-subtree-execution.service.ts`
130
124
  8. `page-loading/page-module-loader.ts`
131
125
  9. `page-loading/dependency-resolver.ts`
132
126
  10. `eco/eco.ts`
@@ -134,12 +128,12 @@ The most useful reading order is:
134
128
  ## 7) Key Files
135
129
 
136
130
  - `packages/core/src/route-renderer/route-renderer.ts`
137
- - `packages/core/src/route-renderer/orchestration/route-render-orchestrator.ts`
131
+ - `packages/core/src/route-renderer/orchestration/route-pipeline/route-render-orchestrator.ts`
138
132
  - `packages/core/src/route-renderer/orchestration/integration-renderer.ts`
139
- - `packages/core/src/route-renderer/orchestration/ownership-validation.service.ts`
140
- - `packages/core/src/route-renderer/orchestration/ownership-planning.service.ts`
141
- - `packages/core/src/route-renderer/orchestration/component-render-context.ts`
142
- - `packages/core/src/route-renderer/orchestration/foreign-subtree-execution.service.ts`
133
+ - `packages/core/src/route-renderer/orchestration/ownership-graph/ownership-validation.service.ts`
134
+ - `packages/core/src/route-renderer/orchestration/ownership-graph/component-graph.ts`
135
+ - `packages/core/src/route-renderer/orchestration/foreign-child/component-render-context.ts`
136
+ - `packages/core/src/route-renderer/orchestration/foreign-child/foreign-subtree-execution.service.ts`
143
137
  - `packages/core/src/route-renderer/page-loading/page-module-loader.ts`
144
138
  - `packages/core/src/route-renderer/page-loading/dependency-resolver.ts`
145
139
  - `packages/core/src/eco/eco.ts`
@@ -50,13 +50,18 @@ See [`../build/README.md`](../build/README.md) for the JSX ownership helper spli
50
50
 
51
51
  ### `orchestration/`
52
52
 
53
- - `route-render-orchestrator.ts`: one route render from page-module loading through final HTML output
53
+ Root renderer classes:
54
+
54
55
  - `integration-renderer.ts`: abstract base class for route rendering, explicit view rendering, and foreign-child delegation
55
- - `ownership-validation.service.ts`: up-front ownership validation for route roots and declared descendants
56
- - `foreign-subtree-execution.service.ts`: foreign-child execution policy, queue token resolution, and `toForeignSubtreeRenderPayload()`
57
- - `document-shell-render.service.ts`: shared page/layout/html shell composition and attribute stamping helpers
58
- - `component-render-context.ts`: active render context used by `eco.component()` to intercept foreign children
59
- - `render-output.utils.ts`: unresolved artifact normalization and marker inspection
56
+ - `string-markup-renderer.ts`: shared base for string-markup integrations
57
+
58
+ Domain folders:
59
+
60
+ - `ownership-graph/`: component graph walk/collect and up-front ownership validation
61
+ - `foreign-child/`: active render context, foreign-subtree execution, deferred template serialization
62
+ - `document-shell/`: shared page/layout/html shell composition and attribute stamping helpers
63
+ - `route-pipeline/`: route preparation, final HTML capture, marker-artifact enforcement
64
+ - `page-browser-graph/`: browser asset graph build, session cache, and injector assets
60
65
 
61
66
  ### `page-loading/`
62
67
 
@@ -72,7 +77,7 @@ The route-render contract is:
72
77
  3. `RouteRenderOrchestrator.prepareRenderOptions()` loads the page module, validates ownership (fail-fast), resolves page data, resolves dependencies, and builds the page browser graph.
73
78
  4. The integration renderer performs page, layout, and document-shell rendering. When it encounters a foreign child, it delegates that child back to the owning renderer.
74
79
  5. If a renderer needs queued handoff, it emits internal foreign-subtree tokens and resolves them before returning final HTML.
75
- 6. `RouteRenderOrchestrator.executePrepared()` captures the final body, rejects unresolved `<eco-marker>` artifacts, stamps root or document attributes when needed, and runs the HTML transformer.
80
+ 6. `RouteRenderOrchestrator.executePrepared()` captures the final body, rejects unresolved `<eco-marker>` artifacts, stamps document attributes when needed, and runs the HTML transformer.
76
81
 
77
82
  Important:
78
83
 
@@ -1,5 +1,6 @@
1
- import type { BaseIntegrationContext, ComponentRenderInput, ComponentRenderResult, EcoComponent, PageMetadataProps } from '../../types/public-types.js';
2
- import type { ProcessedAsset } from '../../services/assets/asset-processing-service/index.js';
1
+ import type { BaseIntegrationContext, ComponentRenderInput, ComponentRenderResult, EcoComponent, PageMetadataProps } from '../../../types/public-types.js';
2
+ import type { ProcessedAsset } from '../../../services/assets/asset-processing-service/index.js';
3
+ import { HtmlTransformerService, type HtmlDocumentContribution } from '../../../services/html/html-transformer.service.js';
3
4
  export type DocumentShellLayoutInput = {
4
5
  component: EcoComponent;
5
6
  props?: Record<string, unknown>;
@@ -88,3 +89,19 @@ export declare function applyDocumentShellAttributeStamping(html: string, stampi
88
89
  * Builds the final serialized document HTML for one route page render.
89
90
  */
90
91
  export declare function renderPageDocumentShell(dependencies: DocumentShellRenderDependencies, input: DocumentShellPageRenderInput, docType: string): Promise<string>;
92
+ /**
93
+ * Finalizes already-resolved HTML for explicit renderer-owned paths.
94
+ *
95
+ * @remarks
96
+ * Callers append renderer bootstrap dependencies before invoking this helper.
97
+ * Stamps document/root attributes and runs HTML transformation after nested
98
+ * foreign-subtree resolution without routing back through shared route execution.
99
+ */
100
+ export declare function finalizeDocumentShellHtml(htmlTransformer: HtmlTransformerService, options: {
101
+ html: string;
102
+ partial?: boolean;
103
+ componentRootAttributes?: Record<string, string>;
104
+ documentAttributes?: Record<string, string>;
105
+ transformHtml?: boolean;
106
+ htmlContributions?: HtmlDocumentContribution[];
107
+ }): Promise<string>;
@@ -1,3 +1,6 @@
1
+ import {
2
+ HtmlTransformerService
3
+ } from "../../../services/html/html-transformer.service.js";
1
4
  function resolveDocumentShellLayouts(input) {
2
5
  if (input.layouts && input.layouts.length > 0) {
3
6
  return input.layouts;
@@ -112,9 +115,34 @@ async function renderPageDocumentShell(dependencies, input, docType) {
112
115
  const documentHtml = input.transformDocumentHtml ? input.transformDocumentHtml(composedDocumentHtml) : composedDocumentHtml;
113
116
  return `${docType}${documentHtml}`;
114
117
  }
118
+ async function finalizeDocumentShellHtml(htmlTransformer, options) {
119
+ const html = applyDocumentShellAttributeStamping(
120
+ options.html,
121
+ {
122
+ applyAttributesToFirstBodyElement: (nextHtml, attributes) => htmlTransformer.applyAttributesToFirstBodyElement(nextHtml, attributes),
123
+ applyAttributesToHtmlElement: (nextHtml, attributes) => htmlTransformer.applyAttributesToHtmlElement(nextHtml, attributes)
124
+ },
125
+ {
126
+ componentRootAttributes: options.componentRootAttributes,
127
+ documentAttributes: options.documentAttributes
128
+ }
129
+ );
130
+ const shouldTransform = options.transformHtml ?? !options.partial;
131
+ if (!shouldTransform) {
132
+ return html;
133
+ }
134
+ const transformedResponse = await htmlTransformer.transform(
135
+ new Response(html, {
136
+ headers: { "Content-Type": "text/html" }
137
+ }),
138
+ options.htmlContributions
139
+ );
140
+ return await transformedResponse.text();
141
+ }
115
142
  export {
116
143
  applyDocumentShellAttributeStamping,
117
144
  composeDocumentShell,
118
145
  composeSequentialLayoutChildren,
146
+ finalizeDocumentShellHtml,
119
147
  renderPageDocumentShell
120
148
  };
@@ -1,4 +1,4 @@
1
- import type { EcoPageLayoutEntry, LayoutPropsContext } from '../../types/public-types.js';
1
+ import type { EcoPageLayoutEntry, LayoutPropsContext } from '../../../types/public-types.js';
2
2
  export type LayoutShellPropsContext = LayoutPropsContext & {
3
3
  pageProps?: Record<string, unknown>;
4
4
  };
@@ -1,17 +1,17 @@
1
- import type { EcoComponent } from '../../types/public-types.js';
1
+ import type { EcoComponent } from '../../../types/public-types.js';
2
2
  /**
3
3
  * Result returned by a renderer-owned foreign-child runtime.
4
4
  *
5
- * `inline` keeps rendering inside the current integration. `resolved` returns a
6
- * renderer-owned value immediately, which can be final HTML or a renderer-local
7
- * transport token for later queue resolution.
5
+ * `inline` keeps rendering inside the current integration. `resolved.value` is
6
+ * the queue transport token string allocated by `createQueuedRuntime`; callers
7
+ * must not treat arbitrary objects as resolved output.
8
8
  */
9
9
  export type ForeignChildInterceptionResult = {
10
10
  kind: 'inline';
11
11
  props?: Record<string, unknown>;
12
12
  } | {
13
13
  kind: 'resolved';
14
- value: unknown;
14
+ value: string;
15
15
  } | undefined;
16
16
  /**
17
17
  * Foreign-child metadata passed into the active renderer-owned runtime.
@@ -1,4 +1,4 @@
1
- import { addTriggerAttribute, isThenable, wrapWithScriptsInjector } from "./render-output.utils.js";
1
+ import { addTriggerAttribute, isThenable, wrapWithScriptsInjector } from "./foreign-child-output.utils.js";
2
2
  class ComponentRenderOutputRuntime {
3
3
  finalizeComponentRender(component, content) {
4
4
  const lazyTriggers = component.config?._resolvedLazyTriggers;
@@ -1,4 +1,4 @@
1
- import type { EcoComponent } from '../../types/public-types.js';
1
+ import type { EcoComponent } from '../../../types/public-types.js';
2
2
  type ResolvedLazyScriptGroups = Readonly<NonNullable<EcoComponent['config']>['_resolvedLazyScripts']>;
3
3
  type TemplateContentShape = {
4
4
  strings: readonly string[];
@@ -23,6 +23,20 @@ type MarkupNodeLikeShape = {
23
23
  export declare function isThenable<T>(value: unknown): value is PromiseLike<T>;
24
24
  /** Returns whether a value looks like a DOM-like markup node from SSR integrations. */
25
25
  export declare function isMarkupNodeLike(value: unknown): value is MarkupNodeLikeShape;
26
+ /**
27
+ * Returns whether a value is a plain opaque object that string serializers would
28
+ * coerce via `String(value)` rather than render as markup.
29
+ *
30
+ * @remarks
31
+ * Template results (`strings`/`values`), markup nodes, arrays, and framework
32
+ * element markers (`$$typeof`) are not opaque. Cross-integration children that
33
+ * are only plain objects must use EcoEmbed or already-serialized HTML.
34
+ */
35
+ export declare function isOpaqueForeignChildValue(children: unknown): boolean;
36
+ /**
37
+ * Throws when foreign-path children would be coerced from an opaque object.
38
+ */
39
+ export declare function assertForeignChildrenNotOpaque(children: unknown, context: string): void;
26
40
  /**
27
41
  * Injects `data-eco-trigger` into the first real HTML element opening tag of
28
42
  * a component's rendered output string.
@@ -59,10 +73,4 @@ export declare function wrapWithScriptsInjector(content: string, lazyGroups: Res
59
73
  export declare function wrapWithScriptsInjector<T extends TemplateContentShape>(content: T, lazyGroups: ResolvedLazyScriptGroups): T | string;
60
74
  export declare function wrapWithScriptsInjector<T extends MarkupNodeLikeShape>(content: T, lazyGroups: ResolvedLazyScriptGroups): T;
61
75
  export declare function wrapWithScriptsInjector(content: unknown, lazyGroups: ResolvedLazyScriptGroups): string | TemplateContentShape | MarkupNodeLikeShape;
62
- export declare function decodeHtmlEntities(value: string): string;
63
- export declare function normalizeUnresolvedMarkerArtifactHtml(html: string): string;
64
- export declare function inspectUnresolvedMarkerArtifactHtml(html: string): {
65
- hasUnresolvedMarkerArtifacts: boolean;
66
- normalizedHtml: string;
67
- };
68
76
  export {};
@@ -1,4 +1,4 @@
1
- import { buildInjectorMapScript } from "../../eco/lazy-injector-map.js";
1
+ import { buildInjectorMapScript } from "../../../eco/lazy-injector-map.js";
2
2
  function cloneTemplateStrings(strings, firstString) {
3
3
  const nextStrings = [...strings];
4
4
  nextStrings[0] = firstString;
@@ -85,6 +85,34 @@ function isMarkupNodeLikeShape(value) {
85
85
  function isMarkupNodeLike(value) {
86
86
  return isMarkupNodeLikeShape(value);
87
87
  }
88
+ function isOpaqueForeignChildValue(children) {
89
+ if (children === null || typeof children !== "object") {
90
+ return false;
91
+ }
92
+ if (Array.isArray(children)) {
93
+ return false;
94
+ }
95
+ if ("$$typeof" in children) {
96
+ return false;
97
+ }
98
+ if ("strings" in children && Array.isArray(children.strings)) {
99
+ return false;
100
+ }
101
+ if (isMarkupNodeLikeShape(children)) {
102
+ return false;
103
+ }
104
+ const prototype = Object.getPrototypeOf(children);
105
+ return prototype === Object.prototype || prototype === null;
106
+ }
107
+ function assertForeignChildrenNotOpaque(children, context) {
108
+ if (!isOpaqueForeignChildValue(children)) {
109
+ return;
110
+ }
111
+ const childTag = Object.prototype.toString.call(children);
112
+ throw new TypeError(
113
+ `[ecopages] ${context} refused to coerce opaque foreign children (${childTag}). Use EcoEmbed for cross-integration children or pass already-serialized HTML.`
114
+ );
115
+ }
88
116
  function injectTriggerAttributeIntoString(content, triggerId) {
89
117
  const str = content;
90
118
  let i = 0;
@@ -142,34 +170,11 @@ function wrapWithScriptsInjector(content, lazyGroups) {
142
170
  }
143
171
  return wrapWithScriptsInjectorMarkup(String(content), injectorMapScript);
144
172
  }
145
- function decodeHtmlEntities(value) {
146
- let decoded = value;
147
- let previous;
148
- do {
149
- previous = decoded;
150
- decoded = decoded.replaceAll("&quot;", '"').replaceAll("&#39;", "'").replaceAll("&#x27;", "'").replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&amp;", "&");
151
- } while (decoded !== previous);
152
- return decoded;
153
- }
154
- function normalizeUnresolvedMarkerArtifactHtml(html) {
155
- return html.replace(
156
- /&(?:amp;)?lt;eco-marker\b[\s\S]*?&(?:amp;)?gt;&(?:amp;)?lt;\/eco-marker&(?:amp;)?gt;/g,
157
- (marker) => decodeHtmlEntities(marker)
158
- );
159
- }
160
- function inspectUnresolvedMarkerArtifactHtml(html) {
161
- const normalizedHtml = normalizeUnresolvedMarkerArtifactHtml(html);
162
- return {
163
- normalizedHtml,
164
- hasUnresolvedMarkerArtifacts: normalizedHtml.includes("<eco-marker")
165
- };
166
- }
167
173
  export {
168
174
  addTriggerAttribute,
169
- decodeHtmlEntities,
170
- inspectUnresolvedMarkerArtifactHtml,
175
+ assertForeignChildrenNotOpaque,
171
176
  isMarkupNodeLike,
177
+ isOpaqueForeignChildValue,
172
178
  isThenable,
173
- normalizeUnresolvedMarkerArtifactHtml,
174
179
  wrapWithScriptsInjector
175
180
  };
@@ -1,5 +1,5 @@
1
- import type { ProcessedAsset } from '../../services/assets/asset-processing-service/index.js';
2
- import type { BaseIntegrationContext, ComponentRenderInput, ComponentRenderResult, EcoComponent, ForeignSubtreeRenderPayload } from '../../types/public-types.js';
1
+ import type { ProcessedAsset } from '../../../services/assets/asset-processing-service/index.js';
2
+ import type { BaseIntegrationContext, ComponentRenderInput, ComponentRenderResult, EcoComponent, ForeignSubtreeRenderPayload } from '../../../types/public-types.js';
3
3
  import { type ForeignChildRuntime } from './component-render-context.js';
4
4
  export type QueuedForeignChildDecisionInput = {
5
5
  currentIntegration: string;
@@ -46,7 +46,7 @@ export interface ForeignSubtreeExecutionRenderOptions {
46
46
  renderInput: ComponentRenderInput;
47
47
  rendererCache: Map<string, ForeignSubtreeExecutionOwningRenderer>;
48
48
  }): ForeignChildRuntime;
49
- getOwningRenderer(integrationName: string, rendererCache: Map<string, ForeignSubtreeExecutionOwningRenderer>): ForeignSubtreeExecutionOwningRenderer;
49
+ getOwningRenderer(integrationName: string, rendererCache: Map<string, ForeignSubtreeExecutionOwningRenderer>): Promise<ForeignSubtreeExecutionOwningRenderer>;
50
50
  }
51
51
  export interface ForeignSubtreeQueuedRuntimeOptions<TContext extends QueuedForeignSubtreeResolutionContext> {
52
52
  renderInput: ComponentRenderInput;
@@ -61,7 +61,7 @@ export interface ForeignSubtreeStringQueuedHtmlOptions {
61
61
  html: string;
62
62
  runtimeContextKey: string;
63
63
  queueLabel: string;
64
- getOwningRenderer(integrationName: string, rendererCache: Map<string, ForeignSubtreeExecutionOwningRenderer>): ForeignSubtreeExecutionOwningRenderer;
64
+ getOwningRenderer(integrationName: string, rendererCache: Map<string, ForeignSubtreeExecutionOwningRenderer>): Promise<ForeignSubtreeExecutionOwningRenderer>;
65
65
  applyAttributesToFirstElement(html: string, attributes: Record<string, string>): string;
66
66
  dedupeProcessedAssets(assets: ProcessedAsset[]): ProcessedAsset[];
67
67
  }
@@ -75,7 +75,7 @@ export interface ForeignSubtreeQueuedHtmlOptions<TContext extends QueuedForeignS
75
75
  children?: unknown;
76
76
  html?: string;
77
77
  }>;
78
- getOwningRenderer(integrationName: string, rendererCache: Map<string, ForeignSubtreeExecutionOwningRenderer>): ForeignSubtreeExecutionOwningRenderer;
78
+ getOwningRenderer(integrationName: string, rendererCache: Map<string, ForeignSubtreeExecutionOwningRenderer>): Promise<ForeignSubtreeExecutionOwningRenderer>;
79
79
  applyAttributesToFirstElement(html: string, attributes: Record<string, string>): string;
80
80
  dedupeProcessedAssets(assets: ProcessedAsset[]): ProcessedAsset[];
81
81
  }
@@ -2,7 +2,7 @@ import {
2
2
  getComponentRenderContext,
3
3
  runWithComponentRenderContext
4
4
  } from "./component-render-context.js";
5
- import { isMarkupNodeLike } from "./render-output.utils.js";
5
+ import { assertForeignChildrenNotOpaque, isMarkupNodeLike } from "./foreign-child-output.utils.js";
6
6
  function toForeignSubtreeRenderPayload(result) {
7
7
  return {
8
8
  html: result.html,
@@ -69,6 +69,9 @@ class ForeignSubtreeExecutionService {
69
69
  props: { ...input.props }
70
70
  };
71
71
  }
72
+ if ("children" in input.props) {
73
+ assertForeignChildrenNotOpaque(input.props.children, "foreign-subtree queue");
74
+ }
72
75
  runtimeContext.nextForeignSubtreeId += 1;
73
76
  const foreignSubtreeId = runtimeContext.nextForeignSubtreeId;
74
77
  const token = this.createForeignSubtreeToken(options.tokenPrefix, runtimeContext, foreignSubtreeId);
@@ -108,10 +111,11 @@ class ForeignSubtreeExecutionService {
108
111
  return { assets: [], html: void 0 };
109
112
  }
110
113
  if (typeof children !== "string" && !isMarkupNodeLike(children)) {
114
+ assertForeignChildrenNotOpaque(children, options.queueLabel);
111
115
  return { assets: [], children };
112
116
  }
113
117
  const html = await this.resolveQueuedTokens(
114
- typeof children === "string" ? children : children.outerHTML ?? String(children ?? ""),
118
+ typeof children === "string" ? children : children.outerHTML ?? "",
115
119
  queuedResolutionsByToken,
116
120
  resolveToken
117
121
  );
@@ -309,7 +313,7 @@ class ForeignSubtreeExecutionService {
309
313
  if (!foreignOwnerIntegrationName) {
310
314
  return void 0;
311
315
  }
312
- const owningRenderer = options.getOwningRenderer(foreignOwnerIntegrationName, options.rendererCache);
316
+ const owningRenderer = await options.getOwningRenderer(foreignOwnerIntegrationName, options.rendererCache);
313
317
  if (owningRenderer.name === options.currentIntegrationName) {
314
318
  return void 0;
315
319
  }
@@ -0,0 +1,19 @@
1
+ import type { EcoPagesAppConfig } from '../../../types/internal-types.js';
2
+ import type { ForeignSubtreeExecutionOwningRenderer } from './foreign-subtree-execution.service.js';
3
+ export type OwningRendererResolutionInput = {
4
+ appConfig: EcoPagesAppConfig;
5
+ runtimeOrigin: string;
6
+ currentIntegrationName: string;
7
+ currentRenderer: ForeignSubtreeExecutionOwningRenderer;
8
+ integrationName: string;
9
+ cache: Map<string, ForeignSubtreeExecutionOwningRenderer>;
10
+ };
11
+ export declare function getForeignSubtreeTokenPrefix(integrationName: string): string;
12
+ export declare function getForeignSubtreeResolutionContextKey(integrationName: string): string;
13
+ /**
14
+ * Resolves an owning integration renderer for a foreign-child handoff.
15
+ *
16
+ * Reuses the execution-scoped cache, activates the target runtime when needed,
17
+ * and initializes the plugin renderer once per integration name.
18
+ */
19
+ export declare function resolveOwningIntegrationRenderer(input: OwningRendererResolutionInput): Promise<ForeignSubtreeExecutionOwningRenderer>;
@@ -0,0 +1,35 @@
1
+ import { ensureIntegrationRuntimeReady } from "../../../build/app-build-manifest-runtime.js";
2
+ import { invariant } from "../../../utils/invariant.js";
3
+ function getForeignSubtreeTokenPrefix(integrationName) {
4
+ return `__${integrationName}_foreign_subtree__`;
5
+ }
6
+ function getForeignSubtreeResolutionContextKey(integrationName) {
7
+ return `__${integrationName}_foreign_subtree_runtime__`;
8
+ }
9
+ async function resolveOwningIntegrationRenderer(input) {
10
+ const { integrationName, cache } = input;
11
+ if (cache.has(integrationName)) {
12
+ return cache.get(integrationName);
13
+ }
14
+ if (integrationName === input.currentIntegrationName) {
15
+ cache.set(integrationName, input.currentRenderer);
16
+ return input.currentRenderer;
17
+ }
18
+ await ensureIntegrationRuntimeReady({
19
+ appConfig: input.appConfig,
20
+ integrationName,
21
+ runtimeOrigin: input.runtimeOrigin
22
+ });
23
+ const integrationPlugin = input.appConfig.integrations.find((integration) => integration.name === integrationName);
24
+ invariant(!!integrationPlugin, `[ecopages] Integration not found for foreign owner: ${integrationName}`);
25
+ const renderer = integrationPlugin.initializeRenderer({
26
+ rendererModules: input.appConfig.runtime?.rendererModuleContext
27
+ });
28
+ cache.set(integrationName, renderer);
29
+ return renderer;
30
+ }
31
+ export {
32
+ getForeignSubtreeResolutionContextKey,
33
+ getForeignSubtreeTokenPrefix,
34
+ resolveOwningIntegrationRenderer
35
+ };