@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,25 @@
1
+ function manageWindowScroll(newUrl, previousUrl, options) {
2
+ const { scrollBehavior, smoothScroll } = options;
3
+ if (newUrl.hash) {
4
+ const target = document.getElementById(newUrl.hash.slice(1));
5
+ target?.scrollIntoView({ behavior: smoothScroll ? "smooth" : "instant" });
6
+ return;
7
+ }
8
+ const behavior = smoothScroll ? "smooth" : "instant";
9
+ switch (scrollBehavior) {
10
+ case "preserve":
11
+ break;
12
+ case "auto":
13
+ if (newUrl.pathname !== previousUrl.pathname) {
14
+ window.scrollTo({ top: 0, left: 0, behavior });
15
+ }
16
+ break;
17
+ case "top":
18
+ default:
19
+ window.scrollTo({ top: 0, left: 0, behavior });
20
+ break;
21
+ }
22
+ }
23
+ export {
24
+ manageWindowScroll
25
+ };
@@ -0,0 +1,37 @@
1
+ import { afterEach, describe, expect, it, vi } from "vitest";
2
+ import { manageWindowScroll } from "./scroll.js";
3
+ const options = { scrollBehavior: "top", smoothScroll: false };
4
+ describe("manageWindowScroll", () => {
5
+ afterEach(() => {
6
+ history.replaceState({}, "", "/");
7
+ document.body.replaceChildren();
8
+ vi.restoreAllMocks();
9
+ });
10
+ it("scrolls to top by default", () => {
11
+ const scrollTo = vi.spyOn(window, "scrollTo").mockImplementation(() => {
12
+ });
13
+ manageWindowScroll(new URL("/next", window.location.origin), new URL("/prev", window.location.origin), options);
14
+ expect(scrollTo).toHaveBeenCalledWith({ top: 0, left: 0, behavior: "instant" });
15
+ });
16
+ it("preserves scroll when scrollBehavior is preserve", () => {
17
+ const scrollTo = vi.spyOn(window, "scrollTo").mockImplementation(() => {
18
+ });
19
+ manageWindowScroll(new URL("/next", window.location.origin), new URL("/prev", window.location.origin), {
20
+ ...options,
21
+ scrollBehavior: "preserve"
22
+ });
23
+ expect(scrollTo).not.toHaveBeenCalled();
24
+ });
25
+ it("scrolls to hash target by element id", () => {
26
+ const section = document.createElement("section");
27
+ section.id = "section";
28
+ section.scrollIntoView = vi.fn();
29
+ document.body.append(section);
30
+ manageWindowScroll(
31
+ new URL("/page#section", window.location.origin),
32
+ new URL("/page", window.location.origin),
33
+ options
34
+ );
35
+ expect(section.scrollIntoView).toHaveBeenCalledWith({ behavior: "instant" });
36
+ });
37
+ });
@@ -0,0 +1,16 @@
1
+ /**
2
+ * View Transition API helpers for `data-view-transition` markup.
3
+ * @module
4
+ */
5
+ /**
6
+ * Assigns `view-transition-name` from `data-view-transition` and injects morph styles.
7
+ *
8
+ * @remarks
9
+ * Elements without `data-view-transition-animate="fade"` get a geometric morph:
10
+ * the old snapshot is hidden so cross-fade ghosting does not appear.
11
+ */
12
+ export declare function applyViewTransitionNames(): void;
13
+ /**
14
+ * Clears inline transition names and dynamic morph styles after a transition ends.
15
+ */
16
+ export declare function clearViewTransitionNames(): void;
@@ -0,0 +1,63 @@
1
+ const VIEW_TRANSITION_ATTR = "data-view-transition";
2
+ const VIEW_TRANSITION_ANIMATE_ATTR = "data-view-transition-animate";
3
+ const VIEW_TRANSITION_DURATION_ATTR = "data-view-transition-duration";
4
+ const DYNAMIC_STYLES_ID = "eco-vt-dynamic-styles";
5
+ function applyViewTransitionNames() {
6
+ const elements = document.querySelectorAll(`[${VIEW_TRANSITION_ATTR}]`);
7
+ const morphNames = [];
8
+ const customDurations = [];
9
+ elements.forEach((el) => {
10
+ const name = el.getAttribute(VIEW_TRANSITION_ATTR);
11
+ if (!name) {
12
+ return;
13
+ }
14
+ el.style.viewTransitionName = name;
15
+ const animate = el.getAttribute(VIEW_TRANSITION_ANIMATE_ATTR);
16
+ if (animate !== "fade") {
17
+ morphNames.push(name);
18
+ }
19
+ const duration = el.getAttribute(VIEW_TRANSITION_DURATION_ATTR);
20
+ if (duration) {
21
+ customDurations.push({ name, duration });
22
+ }
23
+ });
24
+ if (morphNames.length > 0 || customDurations.length > 0) {
25
+ injectDynamicStyles(morphNames, customDurations);
26
+ }
27
+ }
28
+ function clearViewTransitionNames() {
29
+ const elements = document.querySelectorAll(`[${VIEW_TRANSITION_ATTR}]`);
30
+ elements.forEach((el) => {
31
+ el.style.viewTransitionName = "";
32
+ });
33
+ const styleEl = document.getElementById(DYNAMIC_STYLES_ID);
34
+ if (styleEl) {
35
+ styleEl.textContent = "";
36
+ }
37
+ }
38
+ function injectDynamicStyles(morphNames, customDurations) {
39
+ let styleEl = document.getElementById(DYNAMIC_STYLES_ID);
40
+ if (!styleEl) {
41
+ styleEl = document.createElement("style");
42
+ styleEl.id = DYNAMIC_STYLES_ID;
43
+ styleEl.setAttribute("data-eco-persist", "");
44
+ document.head.append(styleEl);
45
+ }
46
+ const morphCss = morphNames.map(
47
+ (name) => `
48
+ ::view-transition-old(${name}) { display: none !important; }
49
+ ::view-transition-new(${name}) { animation: none !important; opacity: 1 !important; }
50
+ `
51
+ ).join("\n");
52
+ const durationCss = customDurations.map(
53
+ ({ name, duration }) => `
54
+ ::view-transition-group(${name}) { animation-duration: ${duration} !important; }
55
+ `
56
+ ).join("\n");
57
+ styleEl.textContent = `${morphCss}
58
+ ${durationCss}`;
59
+ }
60
+ export {
61
+ applyViewTransitionNames,
62
+ clearViewTransitionNames
63
+ };
@@ -70,12 +70,7 @@ export declare class ConfigBuilder {
70
70
  *
71
71
  * - `'rolldown'` (default): Ecopages runs builds through
72
72
  * {@link RolldownBuildAdapter}, creating a new `rolldown()` instance
73
- * per build. Best for one-shot production builds and benchmarks.
74
- * - `'rolldown-dev'`: Ecopages runs builds through
75
- * {@link RolldownDevBuildAdapter}, which wraps Rolldown's experimental
76
- * `DevEngine` and reuses the cached module graph, resolver, and
77
- * transform cache across rebuilds. Best for HMR and watch mode where
78
- * the same entrypoints are rebuilt repeatedly.
73
+ * per build.
79
74
  * - `'vite-host'`: a host runtime owns the build. Ecopages exposes a
80
75
  * {@link ViteHostBuildAdapter} boundary marker that throws on direct
81
76
  * use. Select this only for host-driven compatibility flows where
@@ -250,7 +245,17 @@ export declare class ConfigBuilder {
250
245
  private compareVersions;
251
246
  /**
252
247
  * Initializes default loaders that are required for EcoPages to function.
253
- * This includes the eco-component-meta-plugin which auto-injects __eco metadata into component configs.
248
+ *
249
+ * @remarks
250
+ * `eco-component-meta` is registered twice on purpose:
251
+ *
252
+ * - `sourceTransforms` is the canonical browser/HMR path. The Rolldown bridge
253
+ * runs these after first-wins `onLoad` plugins rewrite module source.
254
+ * - `loaders` keeps the same transform available to server-oriented builds
255
+ * that still use competing `onLoad` handlers directly.
256
+ *
257
+ * Browser builds exclude the loader copy in {@link getAppBrowserBuildPlugins}
258
+ * when the transform name is already present in `sourceTransforms`.
254
259
  */
255
260
  private initializeDefaultLoaders;
256
261
  private reviewBaseUrl;
@@ -9,7 +9,6 @@ import {
9
9
  collectConfiguredAppBuildManifestContributions,
10
10
  createBuildAdapter,
11
11
  setAppBuildAdapter,
12
- setAppBuildExecutor,
13
12
  updateAppBuildManifest
14
13
  } from "../build/build-adapter.js";
15
14
  import { GHTML_PLUGIN_NAME } from "../integrations/ghtml/ghtml.constants.js";
@@ -112,12 +111,7 @@ class ConfigBuilder {
112
111
  *
113
112
  * - `'rolldown'` (default): Ecopages runs builds through
114
113
  * {@link RolldownBuildAdapter}, creating a new `rolldown()` instance
115
- * per build. Best for one-shot production builds and benchmarks.
116
- * - `'rolldown-dev'`: Ecopages runs builds through
117
- * {@link RolldownDevBuildAdapter}, which wraps Rolldown's experimental
118
- * `DevEngine` and reuses the cached module graph, resolver, and
119
- * transform cache across rebuilds. Best for HMR and watch mode where
120
- * the same entrypoints are rebuilt repeatedly.
114
+ * per build.
121
115
  * - `'vite-host'`: a host runtime owns the build. Ecopages exposes a
122
116
  * {@link ViteHostBuildAdapter} boundary marker that throws on direct
123
117
  * use. Select this only for host-driven compatibility flows where
@@ -547,7 +541,17 @@ class ConfigBuilder {
547
541
  }
548
542
  /**
549
543
  * Initializes default loaders that are required for EcoPages to function.
550
- * This includes the eco-component-meta-plugin which auto-injects __eco metadata into component configs.
544
+ *
545
+ * @remarks
546
+ * `eco-component-meta` is registered twice on purpose:
547
+ *
548
+ * - `sourceTransforms` is the canonical browser/HMR path. The Rolldown bridge
549
+ * runs these after first-wins `onLoad` plugins rewrite module source.
550
+ * - `loaders` keeps the same transform available to server-oriented builds
551
+ * that still use competing `onLoad` handlers directly.
552
+ *
553
+ * Browser builds exclude the loader copy in {@link getAppBrowserBuildPlugins}
554
+ * when the transform name is already present in `sourceTransforms`.
551
555
  */
552
556
  async initializeDefaultLoaders() {
553
557
  const componentMetaTransform = createEcoComponentMetaTransform({ config: this.config });
@@ -593,7 +597,6 @@ class ConfigBuilder {
593
597
  updateAppBuildManifest(this.config, await collectConfiguredAppBuildManifestContributions(this.config));
594
598
  setAppServerInvalidationState(this.config, new CounterServerInvalidationState());
595
599
  setAppEntrypointDependencyGraph(this.config, new NoopEntrypointDependencyGraph());
596
- setAppBuildExecutor(this.config, buildAdapter);
597
600
  return this.config;
598
601
  }
599
602
  }
@@ -0,0 +1,5 @@
1
+ import type { EcoPagesAppConfig } from '../types/public-types.js';
2
+ import type { IClientBridge } from '../types/public-types.js';
3
+ export declare function setAppDevClientBridge(appConfig: EcoPagesAppConfig, bridge: IClientBridge): void;
4
+ export declare function getAppDevClientBridge(appConfig: EcoPagesAppConfig): IClientBridge | undefined;
5
+ export declare function clearAppDevClientBridge(appConfig: EcoPagesAppConfig): void;
@@ -0,0 +1,15 @@
1
+ const appDevClientBridges = /* @__PURE__ */ new WeakMap();
2
+ function setAppDevClientBridge(appConfig, bridge) {
3
+ appDevClientBridges.set(appConfig, bridge);
4
+ }
5
+ function getAppDevClientBridge(appConfig) {
6
+ return appDevClientBridges.get(appConfig);
7
+ }
8
+ function clearAppDevClientBridge(appConfig) {
9
+ appDevClientBridges.delete(appConfig);
10
+ }
11
+ export {
12
+ clearAppDevClientBridge,
13
+ getAppDevClientBridge,
14
+ setAppDevClientBridge
15
+ };
@@ -0,0 +1,7 @@
1
+ import type { ApplicationRuntimeOptions } from '../adapters/abstract/application-adapter.js';
2
+ /**
3
+ * Returns whether the host dev server owns all browser dev-client bootstrap.
4
+ *
5
+ * When true, core must not inject the HMR runtime or signal full-page reloads.
6
+ */
7
+ export declare function hostOwnsDevClient(runtime?: ApplicationRuntimeOptions): boolean;
@@ -0,0 +1,6 @@
1
+ function hostOwnsDevClient(runtime) {
2
+ return runtime?.devClientOwner === "host" || runtime?.delegateBrowserReloadToHost === true;
3
+ }
4
+ export {
5
+ hostOwnsDevClient
6
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Per-app registry for the shared HMR manager used by host-owned dev clients.
3
+ */
4
+ import type { EcoPagesAppConfig } from '../types/public-types.js';
5
+ import type { IHmrManager } from '../types/public-types.js';
6
+ export declare function setAppHmrManager(appConfig: EcoPagesAppConfig, hmrManager: IHmrManager): void;
7
+ export declare function getAppHmrManager(appConfig: EcoPagesAppConfig): IHmrManager | undefined;
8
+ export declare function clearAppHmrManager(appConfig: EcoPagesAppConfig): void;
@@ -0,0 +1,15 @@
1
+ const appHmrManagers = /* @__PURE__ */ new WeakMap();
2
+ function setAppHmrManager(appConfig, hmrManager) {
3
+ appHmrManagers.set(appConfig, hmrManager);
4
+ }
5
+ function getAppHmrManager(appConfig) {
6
+ return appHmrManagers.get(appConfig);
7
+ }
8
+ function clearAppHmrManager(appConfig) {
9
+ appHmrManagers.delete(appConfig);
10
+ }
11
+ export {
12
+ clearAppHmrManager,
13
+ getAppHmrManager,
14
+ setAppHmrManager
15
+ };
@@ -1,10 +1,13 @@
1
1
  import type { EcoPagesAppConfig } from '../types/public-types.js';
2
2
  import { type DevelopmentInvalidationPlan } from '../services/invalidation/development-invalidation.service.js';
3
+ import type { ClientBridgeEvent } from '../types/public-types.js';
3
4
  export type HostRuntimeModuleLoader = (id: string) => Promise<unknown>;
4
5
  export interface DevelopmentHostRuntime {
5
6
  registerHostModuleLoader(loader: HostRuntimeModuleLoader): void;
6
7
  planFileChange(filePath: string): DevelopmentInvalidationPlan;
7
8
  invalidateServerModules(changedFiles?: string[]): void;
8
9
  resetRuntimeState(changedFiles?: string[]): void;
10
+ broadcastClientEvent(event: ClientBridgeEvent): void;
11
+ isServerRenderedTemplatePlan(plan: DevelopmentInvalidationPlan): boolean;
9
12
  }
10
13
  export declare function createDevelopmentHostRuntime(appConfig: EcoPagesAppConfig): DevelopmentHostRuntime;
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  DevelopmentInvalidationService
3
3
  } from "../services/invalidation/development-invalidation.service.js";
4
+ import { getAppDevClientBridge } from "./client-bridge-registry.js";
4
5
  import { setHostModuleLoader } from "../services/module-loading/host-module-loader-registry.js";
5
6
  function createDevelopmentHostRuntime(appConfig) {
6
7
  const invalidationService = new DevelopmentInvalidationService(appConfig);
@@ -16,6 +17,12 @@ function createDevelopmentHostRuntime(appConfig) {
16
17
  },
17
18
  resetRuntimeState(changedFiles) {
18
19
  invalidationService.resetRuntimeState(changedFiles);
20
+ },
21
+ broadcastClientEvent(event) {
22
+ getAppDevClientBridge(appConfig)?.broadcast(event);
23
+ },
24
+ isServerRenderedTemplatePlan(plan) {
25
+ return plan.category === "include-source" || plan.category === "explicit-server-view";
19
26
  }
20
27
  };
21
28
  }
@@ -0,0 +1,2 @@
1
+ export type EcopagesRuntimeLabel = 'Bun' | 'Node';
2
+ export declare function formatRuntimeServerStartedMessage(runtime: EcopagesRuntimeLabel, origin: string): string;
@@ -0,0 +1,6 @@
1
+ function formatRuntimeServerStartedMessage(runtime, origin) {
2
+ return `${runtime} server running at ${origin.replace(/\/$/, "")}`;
3
+ }
4
+ export {
5
+ formatRuntimeServerStartedMessage
6
+ };
package/src/eco/README.md CHANGED
@@ -279,6 +279,17 @@ export default eco.page({
279
279
  });
280
280
  ```
281
281
 
282
+ **Nested layouts (outer → inner):**
283
+
284
+ ```tsx
285
+ export default eco.page({
286
+ layout: [MarketingShell, DocsShell],
287
+ render: () => <h1>Hello</h1>,
288
+ });
289
+ ```
290
+
291
+ A single layout remains equivalent to a one-element array. Normalization stores the stack on `config.layouts` and `config.layoutEntries` at factory time.
292
+
282
293
  ### `eco.component()`
283
294
 
284
295
  Define a reusable component with dependencies.
@@ -0,0 +1,14 @@
1
+ import type { EcoDeclaredComponent } from '../types/public-types.js';
2
+ export { getUndeclaredComponentDependencyMessage } from '../errors/undeclared-component-dependency-error.js';
3
+ /**
4
+ * @remarks
5
+ * Declared components are produced by `eco.component()`, `eco.layout()`, and
6
+ * `eco.html()` after the component-meta plugin injects `config.__eco`.
7
+ */
8
+ export declare function isEcoDeclaredComponent(component: unknown): component is EcoDeclaredComponent;
9
+ /**
10
+ * @throws {UndeclaredComponentDependencyError} When the value lacks `config.__eco`.
11
+ */
12
+ export declare function assertEcoDeclaredComponent(component: unknown, context?: {
13
+ parentComponentFile?: string;
14
+ }): asserts component is EcoDeclaredComponent;
@@ -0,0 +1,16 @@
1
+ import { UndeclaredComponentDependencyError } from "../errors/undeclared-component-dependency-error.js";
2
+ import { getUndeclaredComponentDependencyMessage } from "../errors/undeclared-component-dependency-error.js";
3
+ function isEcoDeclaredComponent(component) {
4
+ return typeof component === "function" && typeof component.config?.__eco?.file === "string" && typeof component.config?.__eco?.integration === "string";
5
+ }
6
+ function assertEcoDeclaredComponent(component, context = {}) {
7
+ if (isEcoDeclaredComponent(component)) {
8
+ return;
9
+ }
10
+ throw new UndeclaredComponentDependencyError(context.parentComponentFile);
11
+ }
12
+ export {
13
+ assertEcoDeclaredComponent,
14
+ getUndeclaredComponentDependencyMessage,
15
+ isEcoDeclaredComponent
16
+ };
@@ -1,3 +1,4 @@
1
+ import { applyPageLayoutConfig, mergeLayoutDependencies, normalizePageLayouts } from "./page-layout-normalization.js";
1
2
  function createComponentFactory(options) {
2
3
  const component2 = ((props) => options.render(props));
3
4
  component2.config = {
@@ -32,17 +33,15 @@ function page(options) {
32
33
  requires,
33
34
  middleware
34
35
  } = options;
36
+ const layoutEntries = normalizePageLayouts(pageLayout);
35
37
  const pageComponent = createComponentFactory({
36
38
  __eco: options.__eco,
37
39
  integration: options.integration,
38
- dependencies: pageLayout ? {
39
- ...dependencies,
40
- components: [...dependencies?.components ?? [], pageLayout]
41
- } : dependencies,
40
+ dependencies: mergeLayoutDependencies(dependencies, layoutEntries),
42
41
  render
43
42
  });
44
- if (pageLayout && pageComponent.config) {
45
- pageComponent.config.layout = pageLayout;
43
+ if (pageComponent.config) {
44
+ applyPageLayoutConfig(pageComponent.config, layoutEntries);
46
45
  }
47
46
  if (staticPaths2) {
48
47
  pageComponent.staticPaths = staticPaths2;
package/src/eco/eco.js CHANGED
@@ -4,6 +4,7 @@ import {
4
4
  interceptForeignChild
5
5
  } from "../route-renderer/orchestration/component-render-context.js";
6
6
  import { isThenable } from "../route-renderer/orchestration/render-output.utils.js";
7
+ import { applyPageLayoutConfig, mergeLayoutDependencies, normalizePageLayouts } from "./page-layout-normalization.js";
7
8
  function createComponentFactory(options) {
8
9
  const integrationName = options.integration ?? options.__eco?.integration;
9
10
  const comp = ((props) => {
@@ -74,18 +75,16 @@ function layout(options) {
74
75
  }
75
76
  function page(options) {
76
77
  const { layout: layout2, dependencies, render, staticPaths: staticPaths2, staticProps: staticProps2, metadata: metadata2, cache, requires, middleware } = options;
78
+ const layoutEntries = normalizePageLayouts(layout2);
77
79
  const componentOptions = {
78
80
  __eco: options.__eco,
79
81
  integration: options.integration,
80
- dependencies: layout2 ? {
81
- ...dependencies,
82
- components: [...dependencies?.components || [], layout2]
83
- } : dependencies,
82
+ dependencies: mergeLayoutDependencies(dependencies, layoutEntries),
84
83
  render
85
84
  };
86
85
  const pageComponent = createComponentFactory(componentOptions);
87
- if (layout2 && pageComponent.config) {
88
- pageComponent.config.layout = layout2;
86
+ if (pageComponent.config) {
87
+ applyPageLayoutConfig(pageComponent.config, layoutEntries);
89
88
  }
90
89
  if (staticPaths2) pageComponent.staticPaths = staticPaths2;
91
90
  if (staticProps2) pageComponent.staticProps = staticProps2;
@@ -2,7 +2,7 @@
2
2
  * Type definitions for the eco namespace API
3
3
  * @module
4
4
  */
5
- import type { DependencyLazyTrigger, EcoComponent, EcoComponentDependencies, EcoHtmlComponent, EcoInjectedMeta, EcoLayoutComponent, EcoPageLayoutComponent, EcoPagesElement, FileRouteMiddleware, GetMetadata, GetStaticPaths, GetStaticProps, HtmlTemplateProps, LayoutProps, RequestLocals, RequestPageContext } from '../types/public-types.js';
5
+ import type { DependencyLazyTrigger, EcoComponent, EcoComponentDependencies, EcoHtmlComponent, EcoInjectedMeta, EcoLayoutComponent, EcoPageLayouts, EcoPagesElement, FileRouteMiddleware, GetMetadata, GetStaticPaths, GetStaticProps, HtmlTemplateProps, LayoutProps, RequestLocals, RequestPageContext } from '../types/public-types.js';
6
6
  import type { CacheStrategy } from '../services/cache/cache.types.js';
7
7
  /**
8
8
  * Extracts the props type from one eco component.
@@ -81,7 +81,7 @@ export interface PageOptionsBase<T, E = EcoPagesElement> {
81
81
  __eco?: EcoInjectedMeta;
82
82
  integration?: string;
83
83
  dependencies?: EcoComponentDependencies;
84
- layout?: EcoPageLayoutComponent<E>;
84
+ layout?: EcoPageLayouts<E>;
85
85
  /**
86
86
  * Define static paths for dynamic routes (e.g., [slug].tsx).
87
87
  * Returns all possible paths that should be pre-rendered at build time.
@@ -0,0 +1,21 @@
1
+ import type { EcoComponentConfig, EcoComponentDependencies, EcoPageLayoutEntry, EcoPageLayouts } from '../types/public-types.js';
2
+ /**
3
+ * Normalizes `layout` page options to an outer→inner stack of layout entries.
4
+ */
5
+ export declare function normalizePageLayouts<E>(layout?: EcoPageLayouts<E>): EcoPageLayoutEntry<E>[];
6
+ /**
7
+ * Merges layout components into `dependencies.components` without duplicates.
8
+ */
9
+ export declare function mergeLayoutDependencies(dependencies: EcoComponentDependencies | undefined, layoutEntries: EcoPageLayoutEntry[]): EcoComponentDependencies | undefined;
10
+ /**
11
+ * Writes normalized layout metadata onto a page `config`.
12
+ */
13
+ export declare function applyPageLayoutConfig(pageConfig: EcoComponentConfig, layoutEntries: EcoPageLayoutEntry[]): void;
14
+ /**
15
+ * Migrates MDX-exported `config.layout` values onto normalized layout metadata.
16
+ *
17
+ * @remarks
18
+ * `eco.page({ layout })` already normalizes at factory time. MDX modules that
19
+ * export `config.layout` directly still need this import-time migration.
20
+ */
21
+ export declare function ensurePageConfigLayouts(config: EcoComponentConfig | undefined): EcoComponentConfig | undefined;
@@ -0,0 +1,59 @@
1
+ function isLayoutSpecObject(spec) {
2
+ return typeof spec === "object" && spec !== null && "component" in spec;
3
+ }
4
+ function normalizePageLayouts(layout) {
5
+ if (!layout) {
6
+ return [];
7
+ }
8
+ const specs = Array.isArray(layout) ? layout : [layout];
9
+ return specs.map((spec) => {
10
+ if (isLayoutSpecObject(spec)) {
11
+ return {
12
+ component: spec.component,
13
+ props: spec.props
14
+ };
15
+ }
16
+ return {
17
+ component: spec
18
+ };
19
+ });
20
+ }
21
+ function mergeLayoutDependencies(dependencies, layoutEntries) {
22
+ if (layoutEntries.length === 0) {
23
+ return dependencies;
24
+ }
25
+ const mergedComponents = [...dependencies?.components ?? []];
26
+ for (const entry of layoutEntries) {
27
+ if (!mergedComponents.includes(entry.component)) {
28
+ mergedComponents.push(entry.component);
29
+ }
30
+ }
31
+ return {
32
+ ...dependencies,
33
+ components: mergedComponents
34
+ };
35
+ }
36
+ function applyPageLayoutConfig(pageConfig, layoutEntries) {
37
+ if (layoutEntries.length === 0) {
38
+ return;
39
+ }
40
+ pageConfig.layouts = layoutEntries.map((entry) => entry.component);
41
+ pageConfig.layoutEntries = layoutEntries;
42
+ }
43
+ function ensurePageConfigLayouts(config) {
44
+ if (!config || config.layouts && config.layouts.length > 0) {
45
+ return config;
46
+ }
47
+ const legacyLayout = config.layout;
48
+ if (!legacyLayout) {
49
+ return config;
50
+ }
51
+ applyPageLayoutConfig(config, normalizePageLayouts(legacyLayout));
52
+ return config;
53
+ }
54
+ export {
55
+ applyPageLayoutConfig,
56
+ ensurePageConfigLayouts,
57
+ mergeLayoutDependencies,
58
+ normalizePageLayouts
59
+ };
@@ -1,3 +1,4 @@
1
1
  export { HttpError } from './http-error.js';
2
2
  export type { HttpErrorDetails, HttpErrorJson } from './http-error.js';
3
3
  export { LocalsAccessError } from './locals-access-error.js';
4
+ export { UndeclaredComponentDependencyError, getUndeclaredComponentDependencyMessage, } from './undeclared-component-dependency-error.js';
@@ -1,6 +1,12 @@
1
1
  import { HttpError } from "./http-error.js";
2
2
  import { LocalsAccessError } from "./locals-access-error.js";
3
+ import {
4
+ UndeclaredComponentDependencyError,
5
+ getUndeclaredComponentDependencyMessage
6
+ } from "./undeclared-component-dependency-error.js";
3
7
  export {
4
8
  HttpError,
5
- LocalsAccessError
9
+ LocalsAccessError,
10
+ UndeclaredComponentDependencyError,
11
+ getUndeclaredComponentDependencyMessage
6
12
  };
@@ -0,0 +1,11 @@
1
+ export declare function getUndeclaredComponentDependencyMessage(parentComponentFile?: string): string;
2
+ /**
3
+ * Thrown when `dependencies.components` contains a plain function or component
4
+ * without plugin-injected `config.__eco` metadata.
5
+ */
6
+ export declare class UndeclaredComponentDependencyError extends Error {
7
+ name: string;
8
+ /** Parent component file path when the invalid entry was declared. */
9
+ readonly parentComponentFile?: string;
10
+ constructor(parentComponentFile?: string);
11
+ }
@@ -0,0 +1,17 @@
1
+ function getUndeclaredComponentDependencyMessage(parentComponentFile) {
2
+ const parentHint = parentComponentFile ? ` (declared by ${parentComponentFile})` : "";
3
+ return `[ecopages] dependencies.components entries must be eco.component(), eco.layout(), or eco.html() components with __eco metadata${parentHint}. Plain functions and untyped components are not valid dependency entries.`;
4
+ }
5
+ class UndeclaredComponentDependencyError extends Error {
6
+ name = "UndeclaredComponentDependencyError";
7
+ /** Parent component file path when the invalid entry was declared. */
8
+ parentComponentFile;
9
+ constructor(parentComponentFile) {
10
+ super(getUndeclaredComponentDependencyMessage(parentComponentFile));
11
+ this.parentComponentFile = parentComponentFile;
12
+ }
13
+ }
14
+ export {
15
+ UndeclaredComponentDependencyError,
16
+ getUndeclaredComponentDependencyMessage
17
+ };
@@ -12,7 +12,7 @@ import { getEcoNavigationRuntime } from "../../router/client/navigation-coordina
12
12
  socket.addEventListener("message", async (event) => {
13
13
  try {
14
14
  const payload = JSON.parse(event.data);
15
- handleMessage(payload);
15
+ await handleMessage(payload);
16
16
  } catch (e) {
17
17
  console.error("[ecopages] Invalid HMR message:", e);
18
18
  }
@@ -29,12 +29,15 @@ import { getEcoNavigationRuntime } from "../../router/client/navigation-coordina
29
29
  switch (payload.type) {
30
30
  case "reload":
31
31
  await waitForNavigationToSettle(navigationRuntime);
32
+ if (window.__ECOPAGES_HOST_OWNS_RELOAD__) {
33
+ break;
34
+ }
32
35
  location.reload();
33
36
  break;
34
37
  case "layout-update": {
35
38
  await waitForNavigationToSettle(navigationRuntime);
36
39
  if (await navigationRuntime.reloadCurrentPage({ clearCache: true, moduleUrl: getActiveHmrModuleUrl() })) {
37
- } else {
40
+ } else if (!window.__ECOPAGES_HOST_OWNS_RELOAD__) {
38
41
  location.reload();
39
42
  }
40
43
  break;