@ecopages/core 0.2.0-beta.2 → 0.2.0-beta.20

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 (273) hide show
  1. package/README.md +1 -1
  2. package/package.json +163 -3
  3. package/src/adapters/abstract/application-adapter.d.ts +104 -5
  4. package/src/adapters/abstract/application-adapter.js +125 -1
  5. package/src/adapters/abstract/server-adapter.d.ts +6 -2
  6. package/src/adapters/abstract/ws-pattern-matcher.d.ts +60 -0
  7. package/src/adapters/abstract/ws-pattern-matcher.js +61 -0
  8. package/src/adapters/bun/client-bridge.d.ts +1 -0
  9. package/src/adapters/bun/client-bridge.js +3 -0
  10. package/src/adapters/bun/create-app.d.ts +6 -4
  11. package/src/adapters/bun/create-app.js +65 -43
  12. package/src/adapters/bun/hmr-manager.d.ts +2 -1
  13. package/src/adapters/bun/hmr-manager.js +2 -2
  14. package/src/adapters/bun/server-adapter.d.ts +90 -22
  15. package/src/adapters/bun/server-adapter.js +265 -84
  16. package/src/adapters/bun/static-preview-host.js +25 -20
  17. package/src/adapters/create-app.d.ts +13 -11
  18. package/src/adapters/create-app.js +2 -51
  19. package/src/adapters/index.d.ts +1 -1
  20. package/src/adapters/index.js +1 -2
  21. package/src/adapters/node/create-app.d.ts +5 -1
  22. package/src/adapters/node/create-app.js +51 -12
  23. package/src/adapters/node/node-client-bridge.d.ts +1 -0
  24. package/src/adapters/node/node-client-bridge.js +3 -0
  25. package/src/adapters/node/node-hmr-manager.d.ts +2 -1
  26. package/src/adapters/node/node-hmr-manager.js +2 -2
  27. package/src/adapters/node/server-adapter-dependencies.js +4 -0
  28. package/src/adapters/node/server-adapter.d.ts +62 -20
  29. package/src/adapters/node/server-adapter.js +161 -131
  30. package/src/adapters/node/static-content-server.d.ts +1 -0
  31. package/src/adapters/node/static-content-server.js +10 -2
  32. package/src/adapters/node/static-preview-host.js +27 -12
  33. package/src/adapters/shared/bun-user-websocket-lifecycle.d.ts +22 -0
  34. package/src/adapters/shared/bun-user-websocket-lifecycle.js +96 -0
  35. package/src/adapters/shared/copy-runtime-public-dir.d.ts +6 -0
  36. package/src/adapters/shared/copy-runtime-public-dir.js +24 -0
  37. package/src/adapters/shared/fs-server-response-matcher.d.ts +2 -0
  38. package/src/adapters/shared/fs-server-response-matcher.js +40 -18
  39. package/src/adapters/shared/hmr-entrypoint-registrar.d.ts +0 -2
  40. package/src/adapters/shared/hmr-entrypoint-registrar.js +3 -26
  41. package/src/adapters/shared/hmr-html-response.d.ts +1 -1
  42. package/src/adapters/shared/hmr-html-response.js +4 -1
  43. package/src/adapters/shared/node-http-websocket-upgrades.d.ts +21 -0
  44. package/src/adapters/shared/node-http-websocket-upgrades.js +100 -0
  45. package/src/adapters/shared/port-manager.d.ts +116 -0
  46. package/src/adapters/shared/port-manager.js +196 -0
  47. package/src/adapters/shared/runtime-app-bootstrap.d.ts +2 -1
  48. package/src/adapters/shared/runtime-app-bootstrap.js +3 -6
  49. package/src/adapters/shared/runtime-server-lifecycle.d.ts +38 -0
  50. package/src/adapters/shared/runtime-server-lifecycle.js +43 -0
  51. package/src/adapters/shared/server-adapter.d.ts +2 -1
  52. package/src/adapters/shared/server-adapter.js +13 -6
  53. package/src/adapters/shared/server-route-handler.d.ts +4 -1
  54. package/src/adapters/shared/server-route-handler.js +5 -2
  55. package/src/adapters/shared/server-static-builder.d.ts +23 -32
  56. package/src/adapters/shared/server-static-builder.js +97 -73
  57. package/src/adapters/shared/shared-hmr-manager.d.ts +28 -0
  58. package/src/adapters/shared/shared-hmr-manager.js +119 -9
  59. package/src/adapters/shared/static-preview-host.d.ts +5 -0
  60. package/src/adapters/shared/websocket-lifecycle.d.ts +24 -0
  61. package/src/adapters/shared/websocket-lifecycle.js +55 -0
  62. package/src/build/README.md +77 -14
  63. package/src/build/app-build-manifest-runtime.d.ts +10 -0
  64. package/src/build/app-build-manifest-runtime.js +90 -0
  65. package/src/build/build-adapter.d.ts +17 -319
  66. package/src/build/build-adapter.js +28 -94
  67. package/src/build/build-contracts.d.ts +97 -0
  68. package/src/build/build-contracts.js +0 -0
  69. package/src/build/build-input-fingerprint.d.ts +28 -0
  70. package/src/build/build-input-fingerprint.js +31 -0
  71. package/src/build/build-profile-options.d.ts +7 -0
  72. package/src/build/build-profile-options.js +37 -0
  73. package/src/build/build-runtime.d.ts +24 -0
  74. package/src/build/build-runtime.js +65 -0
  75. package/src/build/deduping-build-executor.d.ts +28 -0
  76. package/src/build/deduping-build-executor.js +56 -0
  77. package/src/build/jsx-ownership-plugins.d.ts +24 -0
  78. package/src/build/jsx-ownership-plugins.js +41 -0
  79. package/src/build/pages-unified-graph-build.d.ts +31 -0
  80. package/src/build/pages-unified-graph-build.js +206 -0
  81. package/src/build/parallel-build-executor.d.ts +21 -0
  82. package/src/build/parallel-build-executor.js +52 -0
  83. package/src/build/production-build-cache.d.ts +20 -0
  84. package/src/build/production-build-cache.js +63 -0
  85. package/src/build/rolldown-adapter-helpers.d.ts +3 -6
  86. package/src/build/rolldown-adapter-helpers.js +71 -6
  87. package/src/build/rolldown-build-adapter.d.ts +2 -6
  88. package/src/build/rolldown-build-adapter.js +3 -3
  89. package/src/build/rolldown-build-invocation-metrics.d.ts +12 -0
  90. package/src/build/rolldown-build-invocation-metrics.js +43 -0
  91. package/src/build/rolldown-plugin-bridge.d.ts +15 -1
  92. package/src/build/rolldown-plugin-bridge.js +20 -5
  93. package/src/build/rolldown-source-transform-pass.d.ts +15 -0
  94. package/src/build/rolldown-source-transform-pass.js +58 -0
  95. package/src/build/runtime-build-executor.d.ts +8 -15
  96. package/src/build/runtime-build-executor.js +12 -15
  97. package/src/build/runtime-build-output-normalizer.d.ts +7 -0
  98. package/src/build/runtime-build-output-normalizer.js +94 -2
  99. package/src/build/server-entry-build-cache.d.ts +44 -0
  100. package/src/build/server-entry-build-cache.js +161 -0
  101. package/src/client/navigation-scripts/classification.d.ts +16 -0
  102. package/src/client/navigation-scripts/classification.js +41 -0
  103. package/src/client/navigation-scripts/index.d.ts +3 -0
  104. package/src/client/navigation-scripts/index.js +23 -0
  105. package/src/client/navigation-scripts/navigation-scripts.test.browser.js +65 -0
  106. package/src/client/navigation-scripts/registry.d.ts +11 -0
  107. package/src/client/navigation-scripts/registry.js +12 -0
  108. package/src/client/navigation-scripts/rerun-queue.d.ts +37 -0
  109. package/src/client/navigation-scripts/rerun-queue.js +73 -0
  110. package/src/client/scroll.d.ts +17 -0
  111. package/src/client/scroll.js +25 -0
  112. package/src/client/scroll.test.browser.js +37 -0
  113. package/src/client/view-transitions.d.ts +16 -0
  114. package/src/client/view-transitions.js +63 -0
  115. package/src/config/config-builder.d.ts +12 -7
  116. package/src/config/config-builder.js +12 -9
  117. package/src/dev/client-bridge-registry.d.ts +5 -0
  118. package/src/dev/client-bridge-registry.js +15 -0
  119. package/src/dev/dev-client-ownership.d.ts +7 -0
  120. package/src/dev/dev-client-ownership.js +6 -0
  121. package/src/dev/hmr-manager-registry.d.ts +8 -0
  122. package/src/dev/hmr-manager-registry.js +15 -0
  123. package/src/dev/host-runtime.d.ts +3 -0
  124. package/src/dev/host-runtime.js +7 -0
  125. package/src/dev/runtime-server-started-message.d.ts +2 -0
  126. package/src/dev/runtime-server-started-message.js +6 -0
  127. package/src/eco/README.md +11 -0
  128. package/src/eco/eco-declared-component.d.ts +14 -0
  129. package/src/eco/eco-declared-component.js +16 -0
  130. package/src/eco/eco.browser.js +5 -6
  131. package/src/eco/eco.js +5 -6
  132. package/src/eco/eco.types.d.ts +2 -2
  133. package/src/eco/page-layout-normalization.d.ts +21 -0
  134. package/src/eco/page-layout-normalization.js +59 -0
  135. package/src/errors/index.d.ts +1 -0
  136. package/src/errors/index.js +7 -1
  137. package/src/errors/undeclared-component-dependency-error.d.ts +11 -0
  138. package/src/errors/undeclared-component-dependency-error.js +17 -0
  139. package/src/hmr/client/hmr-runtime.js +5 -2
  140. package/src/hmr/hmr-entrypoint-output.d.ts +28 -0
  141. package/src/hmr/hmr-entrypoint-output.js +58 -0
  142. package/src/hmr/strategies/js-hmr-strategy.d.ts +3 -0
  143. package/src/hmr/strategies/js-hmr-strategy.js +68 -18
  144. package/src/hmr/strategies/server-rendered-template-hmr-strategy.d.ts +17 -0
  145. package/src/hmr/strategies/server-rendered-template-hmr-strategy.js +29 -0
  146. package/src/integrations/ghtml/ghtml-renderer.d.ts +2 -6
  147. package/src/integrations/ghtml/ghtml-renderer.js +2 -51
  148. package/src/integrations/ghtml/ghtml.plugin.d.ts +3 -16
  149. package/src/integrations/ghtml/ghtml.plugin.js +7 -14
  150. package/src/plugins/define-integration.d.ts +26 -0
  151. package/src/plugins/define-integration.js +19 -0
  152. package/src/plugins/eco-component-meta-plugin.js +5 -8
  153. package/src/plugins/foreign-jsx-override-plugin.js +4 -6
  154. package/src/plugins/integration-plugin.d.ts +19 -9
  155. package/src/plugins/integration-plugin.js +7 -4
  156. package/src/plugins/jsx-import-source.utils.d.ts +8 -0
  157. package/src/plugins/jsx-import-source.utils.js +26 -0
  158. package/src/plugins/processor.d.ts +19 -4
  159. package/src/plugins/processor.js +22 -4
  160. package/src/plugins/source-transform.d.ts +31 -0
  161. package/src/plugins/source-transform.js +23 -1
  162. package/src/route-renderer/GRAPH.md +8 -8
  163. package/src/route-renderer/README.md +30 -28
  164. package/src/route-renderer/orchestration/component-graph-collectors.d.ts +10 -0
  165. package/src/route-renderer/orchestration/component-graph-collectors.js +143 -0
  166. package/src/route-renderer/orchestration/component-graph.d.ts +36 -0
  167. package/src/route-renderer/orchestration/component-graph.js +98 -0
  168. package/src/route-renderer/orchestration/component-render-context.d.ts +3 -10
  169. package/src/route-renderer/orchestration/component-render-context.js +3 -1
  170. package/src/route-renderer/orchestration/declared-ownership-graph.d.ts +1 -18
  171. package/src/route-renderer/orchestration/declared-ownership-graph.js +5 -31
  172. package/src/route-renderer/orchestration/document-shell-render.service.d.ts +90 -0
  173. package/src/route-renderer/orchestration/document-shell-render.service.js +120 -0
  174. package/src/route-renderer/orchestration/foreign-subtree-execution.service.d.ts +59 -29
  175. package/src/route-renderer/orchestration/foreign-subtree-execution.service.js +164 -35
  176. package/src/route-renderer/orchestration/global-injector-assets.service.d.ts +7 -0
  177. package/src/route-renderer/orchestration/global-injector-assets.service.js +32 -0
  178. package/src/route-renderer/orchestration/integration-renderer.d.ts +18 -54
  179. package/src/route-renderer/orchestration/integration-renderer.js +113 -195
  180. package/src/route-renderer/orchestration/integration-route-render-adapter.d.ts +38 -0
  181. package/src/route-renderer/orchestration/integration-route-render-adapter.js +27 -0
  182. package/src/route-renderer/orchestration/layout-shell-props.service.d.ts +20 -0
  183. package/src/route-renderer/orchestration/layout-shell-props.service.js +31 -0
  184. package/src/route-renderer/orchestration/ownership-validation.service.d.ts +5 -0
  185. package/src/route-renderer/orchestration/ownership-validation.service.js +29 -1
  186. package/src/route-renderer/orchestration/page-browser-graph-contribution.loader.d.ts +9 -0
  187. package/src/route-renderer/orchestration/page-browser-graph-contribution.loader.js +7 -0
  188. package/src/route-renderer/orchestration/page-browser-graph.service.d.ts +25 -0
  189. package/src/route-renderer/orchestration/page-browser-graph.service.js +174 -0
  190. package/src/route-renderer/orchestration/render-output.utils.d.ts +2 -0
  191. package/src/route-renderer/orchestration/render-output.utils.js +4 -0
  192. package/src/route-renderer/orchestration/route-html-finalization.service.d.ts +17 -0
  193. package/src/route-renderer/orchestration/route-html-finalization.service.js +26 -0
  194. package/src/route-renderer/orchestration/route-prepared-options.builder.d.ts +26 -0
  195. package/src/route-renderer/orchestration/route-prepared-options.builder.js +54 -0
  196. package/src/route-renderer/orchestration/route-prepared-options.utils.d.ts +4 -0
  197. package/src/route-renderer/orchestration/route-prepared-options.utils.js +33 -0
  198. package/src/route-renderer/orchestration/route-render-orchestrator.d.ts +8 -39
  199. package/src/route-renderer/orchestration/route-render-orchestrator.js +53 -461
  200. package/src/route-renderer/orchestration/string-markup-renderer.d.ts +14 -0
  201. package/src/route-renderer/orchestration/string-markup-renderer.js +55 -0
  202. package/src/route-renderer/page-loading/component-dependency-collection.js +5 -2
  203. package/src/router/client/link-intent.d.ts +11 -21
  204. package/src/router/client/link-intent.js +10 -0
  205. package/src/router/client/link-intent.test.browser.js +12 -1
  206. package/src/router/client/link-navigation-policy.d.ts +45 -0
  207. package/src/router/client/link-navigation-policy.js +101 -0
  208. package/src/router/client/link-navigation-policy.test.browser.d.ts +1 -0
  209. package/src/router/client/link-navigation-policy.test.browser.js +92 -0
  210. package/src/router/client/navigation-coordinator.d.ts +1 -1
  211. package/src/router/client/navigation-coordinator.js +12 -2
  212. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.d.ts +1 -0
  213. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.js +1 -0
  214. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.d.ts +4 -2
  215. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.js +27 -7
  216. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.js +36 -14
  217. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.js +17 -3
  218. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.d.ts +0 -3
  219. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +2 -31
  220. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.d.ts +0 -3
  221. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +2 -30
  222. package/src/services/assets/asset-processing-service/processors/stylesheet/stylesheet-processor-pipeline.d.ts +2 -0
  223. package/src/services/assets/asset-processing-service/processors/stylesheet/stylesheet-processor-pipeline.js +43 -0
  224. package/src/services/assets/browser-bundle.service.d.ts +3 -1
  225. package/src/services/assets/browser-bundle.service.js +17 -5
  226. package/src/services/html/html-transformer.service.d.ts +1 -1
  227. package/src/services/html/html-transformer.service.js +4 -4
  228. package/src/services/invalidation/development-invalidation.service.d.ts +20 -2
  229. package/src/services/invalidation/development-invalidation.service.js +56 -2
  230. package/src/services/module-loading/README.md +49 -0
  231. package/src/services/module-loading/app-server-module-transpiler.service.js +5 -17
  232. package/src/services/module-loading/page-module-import.service.d.ts +5 -1
  233. package/src/services/module-loading/page-module-import.service.js +97 -45
  234. package/src/services/module-loading/route-module-build-cache-registry.d.ts +24 -0
  235. package/src/services/module-loading/route-module-build-cache-registry.js +37 -0
  236. package/src/services/module-loading/route-module-build-cache.d.ts +4 -0
  237. package/src/services/module-loading/route-module-build-cache.js +38 -0
  238. package/src/services/module-loading/route-module-build-cache.store.d.ts +57 -0
  239. package/src/services/module-loading/route-module-build-cache.store.js +207 -0
  240. package/src/services/module-loading/route-module-build-manifest.d.ts +61 -0
  241. package/src/services/module-loading/route-module-build-manifest.js +116 -0
  242. package/src/services/module-loading/route-module-dependency-hasher.d.ts +81 -0
  243. package/src/services/module-loading/route-module-dependency-hasher.js +121 -0
  244. package/src/services/module-loading/server-module-transpiler.service.js +1 -1
  245. package/src/static-site-generator/README.md +33 -0
  246. package/src/static-site-generator/static-build-invalidation.d.ts +10 -0
  247. package/src/static-site-generator/static-build-invalidation.js +59 -0
  248. package/src/static-site-generator/static-export-context.d.ts +22 -0
  249. package/src/static-site-generator/static-export-context.js +0 -0
  250. package/src/static-site-generator/static-site-generator.d.ts +17 -20
  251. package/src/static-site-generator/static-site-generator.js +188 -85
  252. package/src/types/internal-types.d.ts +16 -9
  253. package/src/types/public-types.d.ts +138 -26
  254. package/src/utils/parse-cli-args.d.ts +2 -0
  255. package/src/utils/parse-cli-args.js +6 -0
  256. package/src/utils/server-utils.module.d.ts +3 -2
  257. package/src/utils/server-utils.module.js +5 -6
  258. package/src/utils/static-file-extensions.d.ts +12 -0
  259. package/src/utils/static-file-extensions.js +48 -0
  260. package/src/watchers/project-watcher-ignore.d.ts +11 -0
  261. package/src/watchers/project-watcher-ignore.js +16 -0
  262. package/src/watchers/project-watcher.d.ts +25 -2
  263. package/src/watchers/project-watcher.js +130 -23
  264. package/src/build/rolldown-dev-build-adapter.d.ts +0 -82
  265. package/src/build/rolldown-dev-build-adapter.js +0 -166
  266. package/src/hmr/hmr.postcss.test.e2e.js +0 -31
  267. package/src/hmr/hmr.test.e2e.js +0 -43
  268. package/src/route-renderer/orchestration/ownership-planning.service.d.ts +0 -24
  269. package/src/route-renderer/orchestration/ownership-planning.service.js +0 -63
  270. package/src/route-renderer/orchestration/queued-foreign-subtree-resolution.service.d.ts +0 -91
  271. package/src/route-renderer/orchestration/queued-foreign-subtree-resolution.service.js +0 -170
  272. /package/src/{hmr/hmr.postcss.test.e2e.d.ts → client/navigation-scripts/navigation-scripts.test.browser.d.ts} +0 -0
  273. /package/src/{hmr/hmr.test.e2e.d.ts → client/scroll.test.browser.d.ts} +0 -0
@@ -0,0 +1,98 @@
1
+ function walkComponentGraph(input) {
2
+ const seenComponents = /* @__PURE__ */ new Set();
3
+ const seenConfigs = /* @__PURE__ */ new Set();
4
+ const visitComponent = (component, parentIntegrationName, source) => {
5
+ if (!component) {
6
+ return;
7
+ }
8
+ const ecoComponent = component;
9
+ if (seenComponents.has(ecoComponent)) {
10
+ return;
11
+ }
12
+ seenComponents.add(ecoComponent);
13
+ const integrationName = ecoComponent.config?.integration ?? ecoComponent.config?.__eco?.integration ?? parentIntegrationName;
14
+ if (input.onConfig && ecoComponent.config && !seenConfigs.has(ecoComponent.config)) {
15
+ seenConfigs.add(ecoComponent.config);
16
+ input.onConfig(ecoComponent.config);
17
+ }
18
+ if (input.onComponent) {
19
+ const shouldContinue = input.onComponent({
20
+ component: ecoComponent,
21
+ parentIntegrationName,
22
+ source
23
+ });
24
+ if (shouldContinue === false) {
25
+ return;
26
+ }
27
+ }
28
+ if (input.visitLayout) {
29
+ for (const layout of ecoComponent.config?.layouts ?? []) {
30
+ if (layout?.config) {
31
+ visitConfig(layout.config, integrationName);
32
+ }
33
+ }
34
+ }
35
+ for (const child of ecoComponent.config?.dependencies?.components ?? []) {
36
+ visitComponent(child, integrationName, "dependency");
37
+ }
38
+ };
39
+ const visitConfig = (config, parentIntegrationName) => {
40
+ if (!config || seenConfigs.has(config)) {
41
+ return;
42
+ }
43
+ seenConfigs.add(config);
44
+ if (input.onConfig) {
45
+ input.onConfig(config);
46
+ }
47
+ if (input.visitLayout) {
48
+ for (const layout of config.layouts ?? []) {
49
+ if (layout?.config) {
50
+ visitConfig(layout.config, parentIntegrationName);
51
+ }
52
+ }
53
+ }
54
+ for (const child of config.dependencies?.components ?? []) {
55
+ visitComponent(child, parentIntegrationName, "dependency");
56
+ }
57
+ };
58
+ for (const root of input.roots) {
59
+ visitComponent(root.component, input.currentIntegrationName, root.source);
60
+ }
61
+ }
62
+ function mapComponentGraph(input) {
63
+ let nextSyntheticId = 0;
64
+ const mapComponent = (component, source, parentIntegrationName, lineage) => {
65
+ const integrationName = component.config?.integration ?? component.config?.__eco?.integration ?? parentIntegrationName;
66
+ const componentMeta = component.config?.__eco;
67
+ const isForeignToParent = integrationName !== parentIntegrationName;
68
+ const componentId = componentMeta?.id ?? componentMeta?.file ?? `${source}:${nextSyntheticId += 1}`;
69
+ const nextLineage = new Set(lineage);
70
+ nextLineage.add(component);
71
+ const children = (component.config?.dependencies?.components ?? []).flatMap((child) => {
72
+ if (!child || nextLineage.has(child)) {
73
+ return [];
74
+ }
75
+ return [mapComponent(child, "dependency", integrationName, nextLineage)];
76
+ });
77
+ return input.mapNode(
78
+ {
79
+ component,
80
+ source,
81
+ parentIntegrationName,
82
+ integrationName,
83
+ componentId,
84
+ isForeignToParent
85
+ },
86
+ children
87
+ );
88
+ };
89
+ return input.roots.map(
90
+ ({ component, source }) => mapComponent(component, source, input.currentIntegrationName, /* @__PURE__ */ new Set())
91
+ );
92
+ }
93
+ const mapDeclaredOwnershipGraph = mapComponentGraph;
94
+ export {
95
+ mapComponentGraph,
96
+ mapDeclaredOwnershipGraph,
97
+ walkComponentGraph
98
+ };
@@ -12,13 +12,6 @@ export type ForeignChildInterceptionResult = {
12
12
  } | {
13
13
  kind: 'resolved';
14
14
  value: unknown;
15
- };
16
- export type ForeignChildRenderInterception = {
17
- kind: 'inline';
18
- props?: Record<string, unknown>;
19
- } | {
20
- kind: 'resolved';
21
- value: unknown;
22
15
  } | undefined;
23
16
  /**
24
17
  * Foreign-child metadata passed into the active renderer-owned runtime.
@@ -44,7 +37,7 @@ export interface ForeignChildRuntime {
44
37
  * which decides whether the child stays inline or leaves the current renderer.
45
38
  */
46
39
  interceptForeignChild?(input: ForeignChildInterceptionInput): ForeignChildInterceptionResult | Promise<ForeignChildInterceptionResult>;
47
- interceptForeignChildSync?(input: ForeignChildInterceptionInput): ForeignChildInterceptionResult;
40
+ interceptForeignChildSync?(input: ForeignChildInterceptionInput): Exclude<ForeignChildInterceptionResult, undefined>;
48
41
  }
49
42
  type ForeignChildRenderInput = {
50
43
  component: EcoComponent;
@@ -58,7 +51,7 @@ type ForeignChildRenderInput = {
58
51
  export type ComponentRenderContext = {
59
52
  currentIntegration: string;
60
53
  foreignChildRuntime?: ForeignChildRuntime;
61
- interceptForeignChild(input: ForeignChildRenderInput): Promise<ForeignChildRenderInterception> | ForeignChildRenderInterception;
54
+ interceptForeignChild(input: ForeignChildRenderInput): Promise<ForeignChildInterceptionResult> | ForeignChildInterceptionResult;
62
55
  finalizeComponentRender<T>(component: EcoComponent, content: T): T;
63
56
  };
64
57
  /**
@@ -72,7 +65,7 @@ export declare function getComponentRenderContext(): ComponentRenderContext | un
72
65
  *
73
66
  * The active runtime may resolve the foreign child immediately or keep it inline.
74
67
  */
75
- export declare function interceptForeignChild(input: ForeignChildRenderInput): Promise<ForeignChildRenderInterception> | ForeignChildRenderInterception;
68
+ export declare function interceptForeignChild(input: ForeignChildRenderInput): Promise<ForeignChildInterceptionResult> | ForeignChildInterceptionResult;
76
69
  /**
77
70
  * Applies lazy trigger or injector wrapping to completed component output.
78
71
  *
@@ -51,7 +51,9 @@ class ContextualComponentRenderRuntime extends ComponentRenderOutputRuntime {
51
51
  const asyncInterception = this.context.foreignChildRuntime?.interceptForeignChild?.(foreignChildRuntimeInput);
52
52
  if (asyncInterception !== void 0) {
53
53
  if (isThenable(asyncInterception)) {
54
- return asyncInterception.then((result) => this.applyForeignChildInterceptionResult(result));
54
+ return asyncInterception.then(
55
+ (result) => result === void 0 ? void 0 : this.applyForeignChildInterceptionResult(result)
56
+ );
55
57
  }
56
58
  return this.applyForeignChildInterceptionResult(asyncInterception);
57
59
  }
@@ -1,18 +1 @@
1
- import type { EcoComponent, OwnershipPlanNodeSource } from '../../types/public-types.js';
2
- export type DeclaredOwnershipRoot = {
3
- component: EcoComponent;
4
- source: Extract<OwnershipPlanNodeSource, 'page' | 'layout' | 'html-template'>;
5
- };
6
- export type DeclaredOwnershipNodeInput = {
7
- component: EcoComponent;
8
- source: Exclude<OwnershipPlanNodeSource, 'route'>;
9
- parentIntegrationName: string;
10
- integrationName: string;
11
- componentId: string;
12
- isForeignToParent: boolean;
13
- };
14
- export declare function mapDeclaredOwnershipGraph<T>(input: {
15
- roots: DeclaredOwnershipRoot[];
16
- currentIntegrationName: string;
17
- mapNode: (node: DeclaredOwnershipNodeInput, children: T[]) => T;
18
- }): T[];
1
+ export { mapComponentGraph, mapDeclaredOwnershipGraph, type ComponentGraphRoot, type ComponentGraphWalkInput, type DeclaredOwnershipNodeInput, type DeclaredOwnershipRoot, } from './component-graph.js';
@@ -1,34 +1,8 @@
1
- function mapDeclaredOwnershipGraph(input) {
2
- let nextSyntheticId = 0;
3
- const mapComponent = (component, source, parentIntegrationName, lineage) => {
4
- const integrationName = component.config?.integration ?? component.config?.__eco?.integration ?? parentIntegrationName;
5
- const componentMeta = component.config?.__eco;
6
- const isForeignToParent = integrationName !== parentIntegrationName;
7
- const componentId = componentMeta?.id ?? componentMeta?.file ?? `${source}:${nextSyntheticId += 1}`;
8
- const nextLineage = new Set(lineage);
9
- nextLineage.add(component);
10
- const children = (component.config?.dependencies?.components ?? []).flatMap((child) => {
11
- if (!child || nextLineage.has(child)) {
12
- return [];
13
- }
14
- return [mapComponent(child, "dependency", integrationName, nextLineage)];
15
- });
16
- return input.mapNode(
17
- {
18
- component,
19
- source,
20
- parentIntegrationName,
21
- integrationName,
22
- componentId,
23
- isForeignToParent
24
- },
25
- children
26
- );
27
- };
28
- return input.roots.map(
29
- ({ component, source }) => mapComponent(component, source, input.currentIntegrationName, /* @__PURE__ */ new Set())
30
- );
31
- }
1
+ import {
2
+ mapComponentGraph,
3
+ mapDeclaredOwnershipGraph
4
+ } from "./component-graph.js";
32
5
  export {
6
+ mapComponentGraph,
33
7
  mapDeclaredOwnershipGraph
34
8
  };
@@ -0,0 +1,90 @@
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
+ export type DocumentShellLayoutInput = {
4
+ component: EcoComponent;
5
+ props?: Record<string, unknown>;
6
+ };
7
+ export type DocumentShellComposeChildrenContext = {
8
+ primaryComponent: EcoComponent;
9
+ primaryProps: Record<string, unknown>;
10
+ primaryRender?: ComponentRenderResult;
11
+ layouts: DocumentShellLayoutInput[];
12
+ rendererCache: BaseIntegrationContext['rendererCache'];
13
+ renderComponentWithForeignChildren: DocumentShellRenderDependencies['renderComponentWithForeignChildren'];
14
+ };
15
+ export type DocumentShellComposeChildrenResult = {
16
+ /** Serialized or element children passed to the HTML template shell. */
17
+ children: unknown;
18
+ layoutRenders: ComponentRenderResult[];
19
+ /**
20
+ * Primary/page render assets when the hook performs unified composition.
21
+ *
22
+ * @remarks
23
+ * Omit only when the default sequential string path runs (core renders primary first).
24
+ */
25
+ primaryRender?: ComponentRenderResult;
26
+ };
27
+ /**
28
+ * Optional hook that replaces default sequential string layout wrapping.
29
+ *
30
+ * @remarks
31
+ * When provided, core skips the initial primary render and expects the hook to return
32
+ * `children` for the HTML template. Supply `primaryRender` so dependency assets still merge.
33
+ */
34
+ export type DocumentShellComposeChildrenHook = (context: DocumentShellComposeChildrenContext) => Promise<DocumentShellComposeChildrenResult>;
35
+ export type DocumentShellComposeInput = {
36
+ primaryComponent: EcoComponent;
37
+ primaryProps: Record<string, unknown>;
38
+ layout?: DocumentShellLayoutInput;
39
+ layouts?: DocumentShellLayoutInput[];
40
+ composeChildren?: DocumentShellComposeChildrenHook;
41
+ htmlTemplate: EcoComponent;
42
+ documentProps: Record<string, unknown>;
43
+ };
44
+ export type DocumentShellPageRenderInput = {
45
+ page: {
46
+ component: EcoComponent;
47
+ props: Record<string, unknown>;
48
+ };
49
+ layout?: DocumentShellLayoutInput;
50
+ layouts?: DocumentShellLayoutInput[];
51
+ composeChildren?: DocumentShellComposeChildrenHook;
52
+ htmlTemplate: EcoComponent;
53
+ metadata: PageMetadataProps;
54
+ pageProps: Record<string, unknown>;
55
+ documentProps?: Record<string, unknown>;
56
+ transformDocumentHtml?: (html: string) => string;
57
+ };
58
+ export type DocumentShellRenderDependencies = {
59
+ renderComponentWithForeignChildren(input: ComponentRenderInput): Promise<ComponentRenderResult>;
60
+ appendProcessedDependencies(...assetGroups: Array<readonly ProcessedAsset[] | undefined>): ProcessedAsset[];
61
+ };
62
+ export type DocumentShellAttributeStamping = {
63
+ applyAttributesToFirstBodyElement(html: string, attributes: Record<string, string>): string;
64
+ applyAttributesToHtmlElement(html: string, attributes: Record<string, string>): string;
65
+ };
66
+ /**
67
+ * Default sequential string-child composition for document shell layers.
68
+ */
69
+ export declare function composeSequentialLayoutChildren(context: DocumentShellComposeChildrenContext): Promise<DocumentShellComposeChildrenResult>;
70
+ /**
71
+ * Composes page or view content through optional layout and document shells.
72
+ *
73
+ * One execution-scoped renderer cache is threaded through every shell layer so
74
+ * repeated foreign delegation reuses initialized renderers within one render pass.
75
+ */
76
+ export declare function composeDocumentShell(dependencies: DocumentShellRenderDependencies, input: DocumentShellComposeInput): Promise<{
77
+ documentHtml: string;
78
+ }>;
79
+ /**
80
+ * Applies optional component-root and document-root attribute stamping before HTML
81
+ * transformation runs on explicit renderer-owned paths.
82
+ */
83
+ export declare function applyDocumentShellAttributeStamping(html: string, stamping: DocumentShellAttributeStamping, options: {
84
+ componentRootAttributes?: Record<string, string>;
85
+ documentAttributes?: Record<string, string>;
86
+ }): string;
87
+ /**
88
+ * Builds the final serialized document HTML for one route page render.
89
+ */
90
+ export declare function renderPageDocumentShell(dependencies: DocumentShellRenderDependencies, input: DocumentShellPageRenderInput, docType: string): Promise<string>;
@@ -0,0 +1,120 @@
1
+ function resolveDocumentShellLayouts(input) {
2
+ if (input.layouts && input.layouts.length > 0) {
3
+ return input.layouts;
4
+ }
5
+ return input.layout ? [input.layout] : [];
6
+ }
7
+ function resolveComponentIntegrationName(component) {
8
+ return component.config?.integration ?? component.config?.__eco?.integration ?? "ecopages";
9
+ }
10
+ async function composeSequentialLayoutChildren(context) {
11
+ if (!context.primaryRender) {
12
+ throw new Error("[ecopages] composeSequentialLayoutChildren requires primaryRender.");
13
+ }
14
+ let children = context.primaryRender.html;
15
+ const layoutRenders = [];
16
+ for (const layout of [...context.layouts].reverse()) {
17
+ const layoutRender = await context.renderComponentWithForeignChildren({
18
+ component: layout.component,
19
+ props: layout.props ?? {},
20
+ children,
21
+ integrationContext: { rendererCache: context.rendererCache }
22
+ });
23
+ layoutRenders.push(layoutRender);
24
+ children = layoutRender.html;
25
+ }
26
+ return {
27
+ children,
28
+ layoutRenders
29
+ };
30
+ }
31
+ async function composeDocumentShell(dependencies, input) {
32
+ const rendererCache = /* @__PURE__ */ new Map();
33
+ const layouts = resolveDocumentShellLayouts(input);
34
+ const composeChildren = input.composeChildren ?? composeSequentialLayoutChildren;
35
+ const usesCustomComposeChildren = input.composeChildren !== void 0;
36
+ let primaryRender;
37
+ let children;
38
+ let layoutRenders;
39
+ if (usesCustomComposeChildren) {
40
+ const composed = await composeChildren({
41
+ primaryComponent: input.primaryComponent,
42
+ primaryProps: input.primaryProps,
43
+ layouts,
44
+ rendererCache,
45
+ renderComponentWithForeignChildren: dependencies.renderComponentWithForeignChildren
46
+ });
47
+ children = composed.children;
48
+ layoutRenders = composed.layoutRenders;
49
+ primaryRender = composed.primaryRender ?? {
50
+ html: typeof composed.children === "string" ? composed.children : "",
51
+ assets: [],
52
+ canAttachAttributes: true,
53
+ rootTag: "main",
54
+ integrationName: resolveComponentIntegrationName(input.primaryComponent)
55
+ };
56
+ } else {
57
+ primaryRender = await dependencies.renderComponentWithForeignChildren({
58
+ component: input.primaryComponent,
59
+ props: input.primaryProps,
60
+ integrationContext: { rendererCache }
61
+ });
62
+ const composed = await composeChildren({
63
+ primaryComponent: input.primaryComponent,
64
+ primaryProps: input.primaryProps,
65
+ primaryRender,
66
+ layouts,
67
+ rendererCache,
68
+ renderComponentWithForeignChildren: dependencies.renderComponentWithForeignChildren
69
+ });
70
+ children = composed.children;
71
+ layoutRenders = composed.layoutRenders;
72
+ }
73
+ const documentRender = await dependencies.renderComponentWithForeignChildren({
74
+ component: input.htmlTemplate,
75
+ props: input.documentProps,
76
+ children,
77
+ integrationContext: { rendererCache }
78
+ });
79
+ dependencies.appendProcessedDependencies(
80
+ primaryRender.assets,
81
+ ...layoutRenders.map((layoutRender) => layoutRender.assets),
82
+ documentRender.assets
83
+ );
84
+ return {
85
+ documentHtml: documentRender.html
86
+ };
87
+ }
88
+ function applyDocumentShellAttributeStamping(html, stamping, options) {
89
+ let nextHtml = html;
90
+ if (options.componentRootAttributes && Object.keys(options.componentRootAttributes).length > 0) {
91
+ nextHtml = stamping.applyAttributesToFirstBodyElement(nextHtml, options.componentRootAttributes);
92
+ }
93
+ if (options.documentAttributes && Object.keys(options.documentAttributes).length > 0) {
94
+ nextHtml = stamping.applyAttributesToHtmlElement(nextHtml, options.documentAttributes);
95
+ }
96
+ return nextHtml;
97
+ }
98
+ async function renderPageDocumentShell(dependencies, input, docType) {
99
+ const { documentHtml: composedDocumentHtml } = await composeDocumentShell(dependencies, {
100
+ primaryComponent: input.page.component,
101
+ primaryProps: input.page.props,
102
+ layout: input.layout,
103
+ layouts: input.layouts,
104
+ composeChildren: input.composeChildren,
105
+ htmlTemplate: input.htmlTemplate,
106
+ documentProps: {
107
+ metadata: input.metadata,
108
+ pageProps: input.pageProps,
109
+ ...input.documentProps ?? {}
110
+ }
111
+ });
112
+ const documentHtml = input.transformDocumentHtml ? input.transformDocumentHtml(composedDocumentHtml) : composedDocumentHtml;
113
+ return `${docType}${documentHtml}`;
114
+ }
115
+ export {
116
+ applyDocumentShellAttributeStamping,
117
+ composeDocumentShell,
118
+ composeSequentialLayoutChildren,
119
+ renderPageDocumentShell
120
+ };
@@ -1,11 +1,36 @@
1
1
  import type { ProcessedAsset } from '../../services/assets/asset-processing-service/index.js';
2
2
  import type { BaseIntegrationContext, ComponentRenderInput, ComponentRenderResult, EcoComponent, ForeignSubtreeRenderPayload } from '../../types/public-types.js';
3
3
  import { type ForeignChildRuntime } from './component-render-context.js';
4
- import { QueuedForeignSubtreeResolutionService, type QueuedForeignSubtreeResolution, type QueuedForeignSubtreeResolutionContext } from './queued-foreign-subtree-resolution.service.js';
4
+ export type QueuedForeignChildDecisionInput = {
5
+ currentIntegration: string;
6
+ targetIntegration?: string;
7
+ component: EcoComponent;
8
+ props: Record<string, unknown>;
9
+ };
10
+ export type QueuedForeignSubtreeResolution = {
11
+ token: string;
12
+ component: EcoComponent;
13
+ props: Record<string, unknown>;
14
+ componentInstanceId: string;
15
+ };
16
+ /**
17
+ * Shared mutable state for one renderer-owned queued foreign-subtree runtime.
18
+ */
19
+ export type QueuedForeignSubtreeResolutionContext = {
20
+ rendererCache: Map<string, unknown>;
21
+ componentInstanceScope?: string;
22
+ nextForeignSubtreeId: number;
23
+ queuedResolutions: QueuedForeignSubtreeResolution[];
24
+ };
25
+ type QueuedForeignSubtreeIntegrationContext = BaseIntegrationContext & Record<string, unknown>;
26
+ type QueuedForeignSubtreeChildRenderResult = {
27
+ assets: ProcessedAsset[];
28
+ html?: string;
29
+ children?: unknown;
30
+ };
5
31
  export interface ForeignSubtreeExecutionOwningRenderer {
6
32
  readonly name: string;
7
33
  renderComponentWithForeignChildren(input: ComponentRenderInput): Promise<ComponentRenderResult>;
8
- renderForeignSubtree(input: ComponentRenderInput): Promise<ForeignSubtreeRenderPayload>;
9
34
  }
10
35
  export interface ForeignSubtreeExecutionDecisionInput {
11
36
  currentIntegration: string;
@@ -54,34 +79,41 @@ export interface ForeignSubtreeQueuedHtmlOptions<TContext extends QueuedForeignS
54
79
  applyAttributesToFirstElement(html: string, attributes: Record<string, string>): string;
55
80
  dedupeProcessedAssets(assets: ProcessedAsset[]): ProcessedAsset[];
56
81
  }
82
+ export interface ResolveQueuedForeignSubtreeTokensOptions<TContext extends QueuedForeignSubtreeResolutionContext> {
83
+ html: string;
84
+ runtimeContext?: TContext;
85
+ queueLabel: string;
86
+ renderQueuedChildren: (children: unknown, runtimeContext: TContext, queuedResolutionsByToken: Map<string, QueuedForeignSubtreeResolution>, resolveToken: (token: string) => Promise<string>) => Promise<QueuedForeignSubtreeChildRenderResult>;
87
+ resolveForeignSubtree: (input: ComponentRenderInput, rendererCache: Map<string, unknown>) => Promise<ForeignSubtreeRenderPayload | undefined>;
88
+ applyAttributesToFirstElement: (html: string, attributes: Record<string, string>) => string;
89
+ dedupeProcessedAssets: (assets: ProcessedAsset[]) => ProcessedAsset[];
90
+ }
91
+ /**
92
+ * Maps one component render result into the foreign-subtree payload shape used by
93
+ * queue resolution and integration tests.
94
+ */
95
+ export declare function toForeignSubtreeRenderPayload(result: ComponentRenderResult): ForeignSubtreeRenderPayload;
57
96
  /**
58
97
  * Executes one component render tree under Foreign Child support.
59
98
  *
60
- * This service owns the execution policy for mixed-integration component trees:
61
- * it decides when a child stays inline, when it must delegate to an owning
62
- * renderer, how one render-pass renderer cache is reused, and how queued
63
- * Foreign Subtree tokens resolve back into final HTML.
99
+ * This service owns mixed-integration execution policy and the queued token
100
+ * mechanics renderers use when foreign children cannot resolve inline.
64
101
  */
65
102
  export declare class ForeignSubtreeExecutionService {
66
- private readonly queuedForeignSubtreeResolutionService;
67
- constructor(queuedForeignSubtreeResolutionService?: QueuedForeignSubtreeResolutionService);
68
103
  private requiresForeignChildRuntime;
69
- /**
70
- * Returns whether the current render pass must hand the child off to a foreign owner.
71
- */
72
104
  shouldDelegateForeignChild(input: ForeignSubtreeExecutionDecisionInput): boolean;
73
- /**
74
- * Creates the base runtime used when a renderer has not supplied its own queueing runtime.
75
- *
76
- * The runtime allows same-integration children to continue inline and fails fast
77
- * when execution crosses into a foreign owner without a renderer-owned handoff.
78
- */
79
105
  createFailFastRuntime(rendererName: string): ForeignChildRuntime;
80
106
  getQueuedRuntimeContext<TContext extends QueuedForeignSubtreeResolutionContext>(input: ComponentRenderInput, runtimeContextKey: string): TContext | undefined;
81
107
  createQueuedRuntime<TContext extends QueuedForeignSubtreeResolutionContext>(options: ForeignSubtreeQueuedRuntimeOptions<TContext>): ForeignChildRuntime;
82
- /**
83
- * Resolves a string-first renderer HTML fragment that may contain queued Foreign Subtree tokens.
84
- */
108
+ createQueueRuntime<TContext extends QueuedForeignSubtreeResolutionContext>(options: {
109
+ renderInput: ComponentRenderInput;
110
+ rendererCache: Map<string, unknown>;
111
+ runtimeContextKey: string;
112
+ tokenPrefix: string;
113
+ shouldQueueForeignChild: (input: QueuedForeignChildDecisionInput) => boolean;
114
+ createRuntimeContext?: (integrationContext: QueuedForeignSubtreeIntegrationContext, rendererCache: Map<string, unknown>) => TContext;
115
+ }): ForeignChildRuntime;
116
+ getRuntimeContext<TContext extends QueuedForeignSubtreeResolutionContext>(input: ComponentRenderInput, runtimeContextKey: string): TContext | undefined;
85
117
  resolveStringQueuedHtml<TContext extends QueuedForeignSubtreeResolutionContext>(options: ForeignSubtreeStringQueuedHtmlOptions): Promise<{
86
118
  assets: ProcessedAsset[];
87
119
  html: string;
@@ -90,21 +122,19 @@ export declare class ForeignSubtreeExecutionService {
90
122
  assets: ProcessedAsset[];
91
123
  html: string;
92
124
  }>;
93
- /**
94
- * Executes one component render with Foreign Child support under the current integration.
95
- */
125
+ resolveQueuedForeignSubtreeTokens<TContext extends QueuedForeignSubtreeResolutionContext>(options: ResolveQueuedForeignSubtreeTokensOptions<TContext>): Promise<{
126
+ assets: ProcessedAsset[];
127
+ html: string;
128
+ }>;
96
129
  executeComponentRender(options: ForeignSubtreeExecutionRenderOptions): Promise<ComponentRenderResult>;
97
130
  private getRendererCache;
98
131
  private withRendererCache;
99
- /**
100
- * Returns the delegatable owning renderer integration for one component.
101
- *
102
- * The pseudo `html` integration marks document-shell ownership only and does
103
- * not participate in component-level foreign subtree execution.
104
- */
105
132
  private getForeignOwnerIntegrationName;
106
133
  private resolveForeignChildInOwningRenderer;
107
134
  private resolveForeignSubtreeInOwningRenderer;
108
135
  private runInForeignOwningRenderer;
109
136
  resolveQueuedTokens(html: string, queuedResolutionsByToken: Map<string, QueuedForeignSubtreeResolution>, resolveToken: (token: string) => Promise<string>): Promise<string>;
137
+ private createForeignSubtreeToken;
138
+ private ensureRuntimeContext;
110
139
  }
140
+ export {};