@ecopages/core 0.2.0-beta.29 → 0.2.0-beta.30

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 (95) hide show
  1. package/README.md +36 -7
  2. package/package.json +2 -2
  3. package/src/adapters/README.md +6 -2
  4. package/src/adapters/abstract/segment-path-matcher.d.ts +6 -0
  5. package/src/adapters/abstract/segment-path-matcher.js +149 -0
  6. package/src/adapters/abstract/ws-pattern-matcher.d.ts +2 -50
  7. package/src/adapters/abstract/ws-pattern-matcher.js +5 -36
  8. package/src/adapters/{shared → bun}/bun-user-websocket-lifecycle.js +1 -1
  9. package/src/adapters/bun/create-app.d.ts +2 -2
  10. package/src/adapters/bun/create-app.js +2 -2
  11. package/src/adapters/bun/hmr-manager.d.ts +1 -1
  12. package/src/adapters/bun/hmr-manager.js +1 -1
  13. package/src/adapters/bun/index.d.ts +1 -1
  14. package/src/adapters/bun/index.js +25 -2
  15. package/src/adapters/bun/runtime-host.d.ts +1 -1
  16. package/src/adapters/bun/runtime-host.js +1 -1
  17. package/src/adapters/bun/server-adapter.d.ts +8 -25
  18. package/src/adapters/bun/server-adapter.js +21 -65
  19. package/src/adapters/bun/static-preview-host.d.ts +1 -1
  20. package/src/adapters/bun/static-preview-host.js +1 -1
  21. package/src/adapters/index.d.ts +1 -1
  22. package/src/adapters/index.js +25 -2
  23. package/src/adapters/node/create-app.d.ts +2 -2
  24. package/src/adapters/node/create-app.js +2 -2
  25. package/src/adapters/node/node-hmr-manager.d.ts +1 -1
  26. package/src/adapters/node/node-hmr-manager.js +1 -1
  27. package/src/adapters/node/runtime-host.d.ts +1 -1
  28. package/src/adapters/node/runtime-host.js +1 -1
  29. package/src/adapters/node/server-adapter.d.ts +2 -3
  30. package/src/adapters/node/server-adapter.js +15 -18
  31. package/src/adapters/node/static-preview-host.d.ts +1 -1
  32. package/src/adapters/node/static-preview-host.js +1 -1
  33. package/src/adapters/shared/{hmr-entrypoint-registrar.d.ts → hmr/hmr-entrypoint-registrar.d.ts} +1 -1
  34. package/src/adapters/shared/{hmr-entrypoint-registrar.js → hmr/hmr-entrypoint-registrar.js} +1 -1
  35. package/src/adapters/shared/{hmr-html-response.d.ts → hmr/hmr-html-response.d.ts} +1 -1
  36. package/src/adapters/shared/{shared-hmr-manager.d.ts → hmr/shared-hmr-manager.d.ts} +9 -8
  37. package/src/adapters/shared/{shared-hmr-manager.js → hmr/shared-hmr-manager.js} +41 -15
  38. package/src/adapters/shared/http/api-request-pipeline.d.ts +23 -0
  39. package/src/adapters/shared/http/api-request-pipeline.js +129 -0
  40. package/src/adapters/shared/{api-response.d.ts → http/api-response.d.ts} +1 -1
  41. package/src/adapters/shared/{api-response.js → http/api-response.js} +6 -23
  42. package/src/adapters/shared/http/create-body-response.d.ts +12 -0
  43. package/src/adapters/shared/http/create-body-response.js +23 -0
  44. package/src/adapters/shared/http/define-api-handler.d.ts +90 -0
  45. package/src/adapters/shared/http/define-api-handler.js +63 -0
  46. package/src/adapters/shared/{explicit-static-render-preparation.d.ts → http/explicit-static-render-preparation.d.ts} +3 -3
  47. package/src/adapters/shared/{explicit-static-route-matcher.d.ts → http/explicit-static-route-matcher.d.ts} +3 -9
  48. package/src/adapters/shared/{explicit-static-route-matcher.js → http/explicit-static-route-matcher.js} +3 -38
  49. package/src/adapters/shared/{file-route-middleware-pipeline.d.ts → http/file-route-middleware-pipeline.d.ts} +2 -2
  50. package/src/adapters/shared/{file-route-middleware-pipeline.js → http/file-route-middleware-pipeline.js} +10 -22
  51. package/src/adapters/shared/{fs-server-response-factory.d.ts → http/fs-server-response-factory.d.ts} +2 -2
  52. package/src/adapters/shared/{fs-server-response-factory.js → http/fs-server-response-factory.js} +2 -2
  53. package/src/adapters/shared/{fs-server-response-matcher.d.ts → http/fs-server-response-matcher.d.ts} +5 -5
  54. package/src/adapters/shared/{fs-server-response-matcher.js → http/fs-server-response-matcher.js} +5 -5
  55. package/src/adapters/shared/http/run-middleware-chain.d.ts +5 -0
  56. package/src/adapters/shared/http/run-middleware-chain.js +17 -0
  57. package/src/adapters/shared/{application-adapter.d.ts → runtime/application-adapter.d.ts} +2 -2
  58. package/src/adapters/shared/{application-adapter.js → runtime/application-adapter.js} +1 -1
  59. package/src/adapters/shared/{render-context.d.ts → runtime/render-context.d.ts} +2 -2
  60. package/src/adapters/shared/{render-context.js → runtime/render-context.js} +8 -17
  61. package/src/adapters/shared/{runtime-app-bootstrap.d.ts → runtime/runtime-app-bootstrap.d.ts} +2 -2
  62. package/src/adapters/shared/{runtime-app-bootstrap.js → runtime/runtime-app-bootstrap.js} +1 -1
  63. package/src/adapters/shared/{runtime-server-lifecycle.d.ts → runtime/runtime-server-lifecycle.d.ts} +13 -13
  64. package/src/adapters/shared/{runtime-server-lifecycle.js → runtime/runtime-server-lifecycle.js} +22 -15
  65. package/src/adapters/shared/{server-adapter.d.ts → runtime/server-adapter.d.ts} +20 -48
  66. package/src/adapters/shared/runtime/server-adapter.js +226 -0
  67. package/src/adapters/shared/{server-route-handler.d.ts → runtime/server-route-handler.d.ts} +6 -36
  68. package/src/adapters/shared/{server-route-handler.js → runtime/server-route-handler.js} +6 -47
  69. package/src/adapters/shared/{server-static-builder.d.ts → runtime/server-static-builder.d.ts} +6 -6
  70. package/src/adapters/shared/{server-static-builder.js → runtime/server-static-builder.js} +8 -8
  71. package/src/adapters/shared/{static-preview-host.d.ts → runtime/static-preview-host.d.ts} +1 -1
  72. package/src/adapters/shared/{node-http-websocket-upgrades.d.ts → ws/node-http-websocket-upgrades.d.ts} +1 -1
  73. package/src/adapters/shared/{node-http-websocket-upgrades.js → ws/node-http-websocket-upgrades.js} +2 -2
  74. package/src/adapters/shared/{websocket-lifecycle.d.ts → ws/websocket-lifecycle.d.ts} +1 -1
  75. package/src/adapters/shared/{websocket-lifecycle.js → ws/websocket-lifecycle.js} +1 -1
  76. package/src/build/app-build-manifest-runtime.d.ts +4 -0
  77. package/src/build/app-build-manifest-runtime.js +19 -9
  78. package/src/index.d.ts +1 -1
  79. package/src/index.js +24 -1
  80. package/src/static-site-generator/static-site-generator.js +1 -1
  81. package/src/types/internal-types.d.ts +8 -2
  82. package/src/types/public-types.d.ts +9 -1
  83. package/src/adapters/shared/define-api-handler.d.ts +0 -25
  84. package/src/adapters/shared/define-api-handler.js +0 -15
  85. package/src/adapters/shared/server-adapter.js +0 -452
  86. /package/src/adapters/{shared → bun}/bun-user-websocket-lifecycle.d.ts +0 -0
  87. /package/src/adapters/shared/{hmr-html-response.js → hmr/hmr-html-response.js} +0 -0
  88. /package/src/adapters/shared/{explicit-static-render-preparation.js → http/explicit-static-render-preparation.js} +0 -0
  89. /package/src/adapters/shared/{copy-runtime-public-dir.d.ts → runtime/copy-runtime-public-dir.d.ts} +0 -0
  90. /package/src/adapters/shared/{copy-runtime-public-dir.js → runtime/copy-runtime-public-dir.js} +0 -0
  91. /package/src/adapters/shared/{port-manager.d.ts → runtime/port-manager.d.ts} +0 -0
  92. /package/src/adapters/shared/{port-manager.js → runtime/port-manager.js} +0 -0
  93. /package/src/adapters/shared/{runtime-host.d.ts → runtime/runtime-host.d.ts} +0 -0
  94. /package/src/adapters/shared/{runtime-host.js → runtime/runtime-host.js} +0 -0
  95. /package/src/adapters/shared/{static-preview-host.js → runtime/static-preview-host.js} +0 -0
@@ -9,19 +9,19 @@ import { setupAppRuntimePlugins } from "../../build/build-adapter.js";
9
9
  import { installBuildRuntime } from "../../build/runtime/build-runtime.js";
10
10
  import { StaticSiteGenerator } from "../../static-site-generator/static-site-generator.js";
11
11
  import { ProjectWatcher } from "../../watchers/project-watcher.js";
12
- import { SharedServerAdapter } from "../shared/server-adapter.js";
13
- import { ApiResponseBuilder } from "../shared/api-response.js";
14
- import { ServerStaticBuilder } from "../shared/server-static-builder.js";
15
- import { attachNodeHttpWebSocketUpgrades } from "../shared/node-http-websocket-upgrades.js";
16
- import { createBunUserWebSocketLifecycle } from "../shared/bun-user-websocket-lifecycle.js";
17
- import { createEcopagesSocket } from "../shared/websocket-lifecycle.js";
18
- import { resolveServeRuntimeOrigin } from "../shared/runtime-app-bootstrap.js";
12
+ import { SharedServerAdapter } from "../shared/runtime/server-adapter.js";
13
+ import { ApiResponseBuilder } from "../shared/http/api-response.js";
14
+ import { ServerStaticBuilder } from "../shared/runtime/server-static-builder.js";
15
+ import { attachNodeHttpWebSocketUpgrades } from "../shared/ws/node-http-websocket-upgrades.js";
16
+ import { createBunUserWebSocketLifecycle } from "./bun-user-websocket-lifecycle.js";
17
+ import { createEcopagesSocket } from "../shared/ws/websocket-lifecycle.js";
18
+ import { resolveServeRuntimeOrigin } from "../shared/runtime/runtime-app-bootstrap.js";
19
19
  import {
20
20
  attachHmrToIntegrations,
21
21
  disposeDevResources,
22
- maybeInjectAdapterHmrHtmlResponse,
23
- prepareRuntimePublicDir
24
- } from "../shared/runtime-server-lifecycle.js";
22
+ prepareRuntimePublicDir,
23
+ startConfiguredIntegrationRuntimePrewarm
24
+ } from "../shared/runtime/runtime-server-lifecycle.js";
25
25
  import { ClientBridge } from "./client-bridge.js";
26
26
  import { setAppDevClientBridge } from "../../dev/client-bridge-registry.js";
27
27
  import { setAppHmrManager } from "../../dev/hmr-manager-registry.js";
@@ -137,21 +137,6 @@ class BunServerAdapter extends SharedServerAdapter {
137
137
  passthroughUnmatched: options?.passthroughUnmatched
138
138
  });
139
139
  }
140
- /**
141
- * Returns whether adapter-level HTML responses still need HMR runtime injection.
142
- *
143
- * @remarks
144
- * Filesystem-routed pages are wrapped later in the shared route layer. This
145
- * adapter-level check exists for explicit API handlers that return HTML and
146
- * would otherwise bypass the route wrapper entirely.
147
- */
148
- async maybeInjectHmrScript(response) {
149
- return maybeInjectAdapterHmrHtmlResponse(response, {
150
- watch: this.options?.watch === true,
151
- hmrManager: this.hmrManager,
152
- hostOwnsDevClient: this.hostOwnsDevClient
153
- });
154
- }
155
140
  /**
156
141
  * Initializes the server adapter's core runtime components.
157
142
  */
@@ -307,14 +292,13 @@ class BunServerAdapter extends SharedServerAdapter {
307
292
  }
308
293
  /**
309
294
  * @remarks
310
- * When `serveHmrEndpoints` is set, `/_hmr` and `/_hmr_runtime.js` are checked
311
- * before user websocket patterns so HMR upgrades are never captured by app routes.
295
+ * When `serveHmrEndpoints` is set, `/_hmr` is checked before user websocket
296
+ * patterns so HMR upgrades are never captured by app routes. Runtime assets are
297
+ * served by `SharedServerAdapter.handleSharedRequest` via `tryHandleAssetRequest`.
312
298
  * Production mode with only user handlers skips the HMR branch entirely.
313
299
  */
314
300
  wrapFetchWithWebSocketUpgrades(originalFetch, { serveHmrEndpoints }) {
315
301
  const matchRoute = (pathname) => findWebSocketRoute(this.websocketHandlers, pathname);
316
- const hmrManager = this.hmrManager;
317
- const waitForInit = this.waitForInitialization.bind(this);
318
302
  return async function(request, server) {
319
303
  const url = new URL(request.url);
320
304
  if (serveHmrEndpoints) {
@@ -322,20 +306,6 @@ class BunServerAdapter extends SharedServerAdapter {
322
306
  const success = this.upgrade(request, { data: { kind: "__hmr__", params: {}, search: {} } });
323
307
  return success ? void 0 : new Response("WebSocket upgrade failed", { status: 400 });
324
308
  }
325
- if (url.pathname === "/_hmr_runtime.js") {
326
- await waitForInit();
327
- const runtimeReady = await hmrManager.ensureRuntimeReady();
328
- const runtimePath = hmrManager.getRuntimePath();
329
- if (runtimeReady && fileSystem.exists(runtimePath)) {
330
- return new Response(fileSystem.readFileAsBuffer(runtimePath), {
331
- headers: { "Content-Type": "application/javascript" }
332
- });
333
- }
334
- appLogger.warn(
335
- `[HMR] Runtime script not found at ${runtimePath}; the HMR runtime build likely failed during startup.`
336
- );
337
- return new Response("Not Found", { status: 404 });
338
- }
339
309
  }
340
310
  const wsMatch = matchRoute(url.pathname);
341
311
  if (wsMatch && request.headers.get("upgrade")?.toLowerCase() === "websocket") {
@@ -352,22 +322,6 @@ class BunServerAdapter extends SharedServerAdapter {
352
322
  return res instanceof Response ? res : new Response("Not Found", { status: 404 });
353
323
  };
354
324
  }
355
- /**
356
- * Helper method to retrieve and parse the request body.
357
- * Handles JSON and plain text content types.
358
- * For FormData (multipart/form-data, x-www-form-urlencoded), use ctx.request.formData() directly.
359
- * Returns undefined for unsupported content types.
360
- */
361
- async retrieveBodyFromRequest(request) {
362
- const contentType = request.headers.get("Content-Type") || "";
363
- if (contentType.includes("application/json")) {
364
- return await request.json();
365
- }
366
- if (contentType.includes("text/plain")) {
367
- return await request.text();
368
- }
369
- return void 0;
370
- }
371
325
  /**
372
326
  * Composes the base Bun server settings that all runtime modes build from.
373
327
  *
@@ -517,6 +471,10 @@ class BunServerAdapter extends SharedServerAdapter {
517
471
  });
518
472
  if (this.options?.watch) {
519
473
  await this.hmrManager.ensureRuntimeReady();
474
+ startConfiguredIntegrationRuntimePrewarm({
475
+ appConfig: this.appConfig,
476
+ runtimeOrigin: this.runtimeOrigin
477
+ });
520
478
  }
521
479
  this.fullyInitialized = true;
522
480
  if (this.options?.watch) await this.watch();
@@ -568,11 +526,9 @@ class BunServerAdapter extends SharedServerAdapter {
568
526
  * Handles HTTP requests by passing them securely to the shared core router adapter.
569
527
  *
570
528
  * @remarks
571
- * Filesystem page responses are wrapped by `ServerRouteHandler`. This
572
- * adapter-level pass only covers HTML returned by explicit API handlers,
573
- * which bypass that route-layer wrapper and would otherwise miss the
574
- * dev HMR runtime — so the HMR script injection happens here, after
575
- * the shared handler runs.
529
+ * HMR HTML injection for API and page responses is owned by
530
+ * `SharedServerAdapter.handleSharedRequest`. This method only maps the
531
+ * request into the shared pipeline.
576
532
  */
577
533
  async handleRequest(request) {
578
534
  const response = await this.handleSharedRequest(request, {
@@ -581,7 +537,7 @@ class BunServerAdapter extends SharedServerAdapter {
581
537
  serverInstance: this.serverInstance,
582
538
  hmrManager: this.hmrManager
583
539
  });
584
- return await this.maybeInjectHmrScript(response);
540
+ return response;
585
541
  }
586
542
  /**
587
543
  * Ensures server initialization completes before request handling.
@@ -1,5 +1,5 @@
1
1
  import type { EcoPagesAppConfig } from '../../types/internal-types.js';
2
- import type { StaticPreviewHost, StaticPreviewHostStartOptions } from '../shared/static-preview-host.js';
2
+ import type { StaticPreviewHost, StaticPreviewHostStartOptions } from '../shared/runtime/static-preview-host.js';
3
3
  type BunStaticPreviewServer = {
4
4
  server: {
5
5
  port?: number;
@@ -1,6 +1,6 @@
1
1
  import { StaticContentServer } from "../../dev/sc-server.js";
2
2
  import { appLogger } from "../../global/app-logger.js";
3
- import { PortManager } from "../shared/port-manager.js";
3
+ import { PortManager } from "../shared/runtime/port-manager.js";
4
4
  class BunStaticPreviewHost {
5
5
  constructor(previewServerFactory = StaticContentServer, logger = appLogger) {
6
6
  this.previewServerFactory = previewServerFactory;
@@ -1,2 +1,2 @@
1
1
  export { createApp } from './create-app.js';
2
- export { defineApiHandler, defineGroupHandler, type GroupHandler } from './shared/define-api-handler.js';
2
+ export { defineApiHandler, defineGroupHandler, defineGet, definePost, definePut, defineDelete, definePatch, defineOptions, defineHead, json, html, redirect, type GroupHandler, } from './shared/http/define-api-handler.js';
@@ -1,7 +1,30 @@
1
1
  import { createApp } from "./create-app.js";
2
- import { defineApiHandler, defineGroupHandler } from "./shared/define-api-handler.js";
2
+ import {
3
+ defineApiHandler,
4
+ defineGroupHandler,
5
+ defineGet,
6
+ definePost,
7
+ definePut,
8
+ defineDelete,
9
+ definePatch,
10
+ defineOptions,
11
+ defineHead,
12
+ json,
13
+ html,
14
+ redirect
15
+ } from "./shared/http/define-api-handler.js";
3
16
  export {
4
17
  createApp,
5
18
  defineApiHandler,
6
- defineGroupHandler
19
+ defineDelete,
20
+ defineGet,
21
+ defineGroupHandler,
22
+ defineHead,
23
+ defineOptions,
24
+ definePatch,
25
+ definePost,
26
+ definePut,
27
+ html,
28
+ json,
29
+ redirect
7
30
  };
@@ -1,5 +1,5 @@
1
- import { SharedApplicationAdapter } from '../shared/application-adapter.js';
2
- import type { RuntimeHost } from '../shared/runtime-host.js';
1
+ import { SharedApplicationAdapter } from '../shared/runtime/application-adapter.js';
2
+ import type { RuntimeHost } from '../shared/runtime/runtime-host.js';
3
3
  import type { EcopagesAppOptions } from '../create-app.js';
4
4
  import { type NodeServerAdapterResult, createNodeServerAdapter } from './server-adapter.js';
5
5
  import type { NodeServerInstance } from './server-adapter.js';
@@ -1,6 +1,6 @@
1
1
  import { appLogger } from "../../global/app-logger.js";
2
- import { SharedApplicationAdapter } from "../shared/application-adapter.js";
3
- import { resolveRuntimeBinding, resolveStaticRuntimeMode } from "../shared/runtime-app-bootstrap.js";
2
+ import { SharedApplicationAdapter } from "../shared/runtime/application-adapter.js";
3
+ import { resolveRuntimeBinding, resolveStaticRuntimeMode } from "../shared/runtime/runtime-app-bootstrap.js";
4
4
  import { createNodeServerAdapter } from "./server-adapter.js";
5
5
  import { NodeHttpRequestBridge } from "./http-request-bridge.js";
6
6
  import { NodeRuntimeHost } from "./runtime-host.js";
@@ -1,6 +1,6 @@
1
1
  import type { EcoPagesAppConfig, IClientBridge } from '../../types/internal-types.js';
2
2
  import { InMemoryEntrypointDependencyGraph, type EntrypointDependencyGraph } from '../../services/runtime-state/entrypoint-dependency-graph.service.js';
3
- import { SharedHmrManager } from '../shared/shared-hmr-manager.js';
3
+ import { SharedHmrManager } from '../shared/hmr/shared-hmr-manager.js';
4
4
  export interface NodeHmrManagerParams {
5
5
  appConfig: EcoPagesAppConfig;
6
6
  bridge: IClientBridge;
@@ -2,7 +2,7 @@ import { appLogger } from "../../global/app-logger.js";
2
2
  import {
3
3
  InMemoryEntrypointDependencyGraph
4
4
  } from "../../services/runtime-state/entrypoint-dependency-graph.service.js";
5
- import { SharedHmrManager } from "../shared/shared-hmr-manager.js";
5
+ import { SharedHmrManager } from "../shared/hmr/shared-hmr-manager.js";
6
6
  class NodeHmrManager extends SharedHmrManager {
7
7
  /**
8
8
  * Creates the Node HMR manager over the shared coordination pipeline.
@@ -1,5 +1,5 @@
1
1
  import { createServer, type Server as NodeServerInstance } from 'node:http';
2
- import type { RuntimeHost, RuntimeHostStartOptions } from '../shared/runtime-host.js';
2
+ import type { RuntimeHost, RuntimeHostStartOptions } from '../shared/runtime/runtime-host.js';
3
3
  import { NodeHttpRequestBridge } from './http-request-bridge.js';
4
4
  type NodeServerFactory = typeof createServer;
5
5
  /**
@@ -1,7 +1,7 @@
1
1
  import { createServer } from "node:http";
2
2
  import { DEFAULT_ECOPAGES_HOSTNAME, DEFAULT_ECOPAGES_PORT } from "../../config/constants.js";
3
3
  import { appLogger } from "../../global/app-logger.js";
4
- import { resolveServeRuntimeOrigin } from "../shared/runtime-app-bootstrap.js";
4
+ import { resolveServeRuntimeOrigin } from "../shared/runtime/runtime-app-bootstrap.js";
5
5
  import { isNodeClientAbortError, NodeHttpRequestBridge } from "./http-request-bridge.js";
6
6
  class NodeRuntimeHost {
7
7
  /**
@@ -1,10 +1,10 @@
1
1
  import { type Server as NodeHttpServer } from 'node:http';
2
2
  import type { EcoPagesAppConfig } from '../../types/internal-types.js';
3
3
  import type { ApiHandler, ErrorHandler, StaticRoute, EcopagesWebSocketHandler } from '../../types/public-types.js';
4
- import { SharedServerAdapter } from '../shared/server-adapter.js';
4
+ import { SharedServerAdapter } from '../shared/runtime/server-adapter.js';
5
5
  import type { ServerAdapterResult } from '../abstract/server-adapter.js';
6
6
  import { NodeHttpRequestBridge } from './http-request-bridge.js';
7
- import type { StaticPreviewHost } from '../shared/static-preview-host.js';
7
+ import type { StaticPreviewHost } from '../shared/runtime/static-preview-host.js';
8
8
  import { type NodeServerDevRuntimeFactory } from './server-adapter-dependencies.js';
9
9
  export type NodeServerInstance = NodeHttpServer;
10
10
  export type NodeServeAdapterServerOptions = {
@@ -93,7 +93,6 @@ export declare class NodeServerAdapter extends SharedServerAdapter<NodeServerAda
93
93
  passthroughUnmatched?: boolean;
94
94
  }): void;
95
95
  private wireUserWebSocketUpgrades;
96
- private maybeInjectHmrScript;
97
96
  /**
98
97
  * @remarks
99
98
  * `previewHost`, `requestBridge`, and `devRuntimeFactory` are optional on the
@@ -9,18 +9,18 @@ import { NodeHmrManager } from "./node-hmr-manager.js";
9
9
  import { ProjectWatcher } from "../../watchers/project-watcher.js";
10
10
  import {
11
11
  attachNodeHttpWebSocketUpgrades
12
- } from "../shared/node-http-websocket-upgrades.js";
12
+ } from "../shared/ws/node-http-websocket-upgrades.js";
13
13
  import { StaticSiteGenerator } from "../../static-site-generator/static-site-generator.js";
14
- import { SharedServerAdapter } from "../shared/server-adapter.js";
15
- import { ServerStaticBuilder } from "../shared/server-static-builder.js";
14
+ import { SharedServerAdapter } from "../shared/runtime/server-adapter.js";
15
+ import { ServerStaticBuilder } from "../shared/runtime/server-static-builder.js";
16
16
  import { DEFAULT_ECOPAGES_HOSTNAME, DEFAULT_ECOPAGES_PORT } from "../../config/constants.js";
17
17
  import {
18
18
  attachHmrToIntegrations,
19
19
  disposeDevResources,
20
- maybeInjectAdapterHmrHtmlResponse,
21
- prepareRuntimePublicDir
22
- } from "../shared/runtime-server-lifecycle.js";
23
- import { resolveServeRuntimeOrigin } from "../shared/runtime-app-bootstrap.js";
20
+ prepareRuntimePublicDir,
21
+ startConfiguredIntegrationRuntimePrewarm
22
+ } from "../shared/runtime/runtime-server-lifecycle.js";
23
+ import { resolveServeRuntimeOrigin } from "../shared/runtime/runtime-app-bootstrap.js";
24
24
  import { NodeClientAbortError, NodeHttpRequestBridge } from "./http-request-bridge.js";
25
25
  import { NodeStaticPreviewHost } from "./static-preview-host.js";
26
26
  import { DefaultNodeServerDevRuntimeFactory } from "./server-adapter-dependencies.js";
@@ -69,13 +69,6 @@ class NodeServerAdapter extends SharedServerAdapter {
69
69
  preflight
70
70
  });
71
71
  }
72
- async maybeInjectHmrScript(response) {
73
- return maybeInjectAdapterHmrHtmlResponse(response, {
74
- watch: this.options?.watch === true,
75
- hmrManager: this.hmrManager ?? void 0,
76
- hostOwnsDevClient: this.hostOwnsDevClient
77
- });
78
- }
79
72
  /**
80
73
  * @remarks
81
74
  * `previewHost`, `requestBridge`, and `devRuntimeFactory` are optional on the
@@ -243,9 +236,9 @@ class NodeServerAdapter extends SharedServerAdapter {
243
236
  apiHandlers: this.apiHandlers,
244
237
  errorHandler: this.errorHandler,
245
238
  serverInstance: this.serverInstance,
246
- hmrManager: this.hmrManager
239
+ hmrManager: this.hmrManager ?? void 0
247
240
  });
248
- return await this.maybeInjectHmrScript(response);
241
+ return response;
249
242
  } catch (error) {
250
243
  if (error instanceof NodeClientAbortError) {
251
244
  return new Response(null, { status: 499 });
@@ -299,14 +292,18 @@ class NodeServerAdapter extends SharedServerAdapter {
299
292
  });
300
293
  }
301
294
  attachHmrToIntegrations(this.appConfig, this.hmrManager);
295
+ startConfiguredIntegrationRuntimePrewarm({
296
+ appConfig: this.appConfig,
297
+ runtimeOrigin: this.runtimeOrigin
298
+ });
302
299
  this.configureSharedResponseHandlers(this.staticRoutes, this.hmrManager);
303
300
  const watcher = new ProjectWatcher({
304
301
  config: this.appConfig,
305
302
  refreshRouterRoutesCallback: this.createSharedWatchRefreshCallback({
306
303
  staticRoutes: this.staticRoutes,
307
- hmrManager: this.hmrManager
304
+ hmrManager: this.hmrManager ?? void 0
308
305
  }),
309
- hmrManager: this.hmrManager,
306
+ hmrManager: this.hmrManager ?? void 0,
310
307
  bridge: this.bridge,
311
308
  hostOwnsDevClient: this.hostOwnsDevClient
312
309
  });
@@ -1,6 +1,6 @@
1
1
  import type { AddressInfo } from 'node:net';
2
2
  import type { EcoPagesAppConfig } from '../../types/internal-types.js';
3
- import type { StaticPreviewHost, StaticPreviewHostStartOptions } from '../shared/static-preview-host.js';
3
+ import type { StaticPreviewHost, StaticPreviewHostStartOptions } from '../shared/runtime/static-preview-host.js';
4
4
  type NodeStaticPreviewServer = {
5
5
  start(): Promise<{
6
6
  address(): AddressInfo | string | null;
@@ -1,5 +1,5 @@
1
1
  import { appLogger } from "../../global/app-logger.js";
2
- import { PortManager } from "../shared/port-manager.js";
2
+ import { PortManager } from "../shared/runtime/port-manager.js";
3
3
  import { NodeStaticContentServer } from "./static-content-server.js";
4
4
  class NodeStaticPreviewHost {
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { type ResolvedHmrEntrypoint } from '../../hmr/hmr-entrypoint-output.js';
1
+ import { type ResolvedHmrEntrypoint } from '../../../hmr/hmr-entrypoint-output.js';
2
2
  /**
3
3
  * Runtime-specific hooks required to materialize a single HMR entrypoint.
4
4
  */
@@ -3,7 +3,7 @@ import { fileSystem } from "@ecopages/file-system";
3
3
  import {
4
4
  removeStaleHmrEntrypointOutput,
5
5
  resolveHmrEntrypointOutputPaths
6
- } from "../../hmr/hmr-entrypoint-output.js";
6
+ } from "../../../hmr/hmr-entrypoint-output.js";
7
7
  class HmrEntrypointRegistrar {
8
8
  options;
9
9
  inFlight = /* @__PURE__ */ new Map();
@@ -1,4 +1,4 @@
1
- import type { IHmrManager } from '../../types/public-types.js';
1
+ import type { IHmrManager } from '../../../types/public-types.js';
2
2
  /**
3
3
  * Returns whether a response is HTML and therefore eligible for development HMR
4
4
  * runtime injection.
@@ -1,13 +1,13 @@
1
1
  import fs from 'node:fs';
2
- import { type ResolvedHmrEntrypoint } from '../../hmr/hmr-entrypoint-output.js';
3
- import type { DefaultHmrContext, EcoPagesAppConfig, IHmrManager, IClientBridge } from '../../types/internal-types.js';
4
- import { type HmrStrategy } from '../../hmr/hmr-strategy.js';
5
- import { DevelopmentInvalidationService } from '../../services/invalidation/development-invalidation.service.js';
6
- import type { ClientBridgeEvent, HmrFileChangeOptions } from '../../types/public-types.js';
2
+ import { type ResolvedHmrEntrypoint } from '../../../hmr/hmr-entrypoint-output.js';
3
+ import type { DefaultHmrContext, EcoPagesAppConfig, IHmrManager, IClientBridge } from '../../../types/internal-types.js';
4
+ import { type HmrStrategy } from '../../../hmr/hmr-strategy.js';
5
+ import { DevelopmentInvalidationService } from '../../../services/invalidation/development-invalidation.service.js';
6
+ import type { ClientBridgeEvent, HmrFileChangeOptions } from '../../../types/public-types.js';
7
7
  import { HmrEntrypointRegistrar } from './hmr-entrypoint-registrar.js';
8
- import { BrowserBundleService } from '../../services/assets/browser-bundle.service.js';
9
- import { type EntrypointDependencyGraph } from '../../services/runtime-state/entrypoint-dependency-graph.service.js';
10
- import type { ServerModuleTranspiler } from '../../services/module-loading/server-module-transpiler.service.js';
8
+ import { BrowserBundleService } from '../../../services/assets/browser-bundle.service.js';
9
+ import { type EntrypointDependencyGraph } from '../../../services/runtime-state/entrypoint-dependency-graph.service.js';
10
+ import type { ServerModuleTranspiler } from '../../../services/module-loading/server-module-transpiler.service.js';
11
11
  type HandleFileChangeOptions = HmrFileChangeOptions;
12
12
  type SharedHmrManagerParams = {
13
13
  appConfig: EcoPagesAppConfig;
@@ -88,6 +88,7 @@ export declare abstract class SharedHmrManager implements IHmrManager {
88
88
  */
89
89
  getResolvedScriptOutput(entrypointPath: string): ResolvedHmrEntrypoint | undefined;
90
90
  getWatchedFiles(): Map<string, string>;
91
+ tryHandleAssetRequest(request: Request): Response | null;
91
92
  getDistDir(): string;
92
93
  getDefaultContext(): DefaultHmrContext;
93
94
  stop(): void;
@@ -1,28 +1,28 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
- import { RESOLVED_ASSETS_DIR } from "../../config/constants.js";
4
+ import { RESOLVED_ASSETS_DIR } from "../../../config/constants.js";
5
5
  import {
6
6
  removeStaleHmrEntrypointOutput,
7
7
  isRegisteredScriptEntrypoint,
8
8
  isBrowserOnlyRegisteredScriptEntrypoint
9
- } from "../../hmr/hmr-entrypoint-output.js";
10
- import { requireBuildRuntime } from "../../build/runtime/build-runtime.js";
9
+ } from "../../../hmr/hmr-entrypoint-output.js";
10
+ import { requireBuildRuntime } from "../../../build/runtime/build-runtime.js";
11
11
  import { fileSystem } from "@ecopages/file-system";
12
- import { HmrStrategyType } from "../../hmr/hmr-strategy.js";
13
- import { DefaultHmrStrategy } from "../../hmr/strategies/default-hmr-strategy.js";
14
- import { JsHmrStrategy } from "../../hmr/strategies/js-hmr-strategy.js";
15
- import { ServerRenderedTemplateHmrStrategy } from "../../hmr/strategies/server-rendered-template-hmr-strategy.js";
16
- import { DevelopmentInvalidationService } from "../../services/invalidation/development-invalidation.service.js";
17
- import { appLogger } from "../../global/app-logger.js";
12
+ import { HmrStrategyType } from "../../../hmr/hmr-strategy.js";
13
+ import { DefaultHmrStrategy } from "../../../hmr/strategies/default-hmr-strategy.js";
14
+ import { JsHmrStrategy } from "../../../hmr/strategies/js-hmr-strategy.js";
15
+ import { ServerRenderedTemplateHmrStrategy } from "../../../hmr/strategies/server-rendered-template-hmr-strategy.js";
16
+ import { DevelopmentInvalidationService } from "../../../services/invalidation/development-invalidation.service.js";
17
+ import { appLogger } from "../../../global/app-logger.js";
18
18
  import { HmrEntrypointRegistrar } from "./hmr-entrypoint-registrar.js";
19
- import { BrowserBundleService } from "../../services/assets/browser-bundle.service.js";
20
- import { getAppServerModuleTranspiler } from "../../services/module-loading/app-server-module-transpiler.service.js";
19
+ import { BrowserBundleService } from "../../../services/assets/browser-bundle.service.js";
20
+ import { getAppServerModuleTranspiler } from "../../../services/module-loading/app-server-module-transpiler.service.js";
21
21
  import {
22
22
  getAppEntrypointDependencyGraph,
23
23
  setAppEntrypointDependencyGraph
24
- } from "../../services/runtime-state/entrypoint-dependency-graph.service.js";
25
- import { resolveInternalExecutionDir, resolveInternalWorkDir } from "../../utils/resolve-work-dir.js";
24
+ } from "../../../services/runtime-state/entrypoint-dependency-graph.service.js";
25
+ import { resolveInternalExecutionDir, resolveInternalWorkDir } from "../../../utils/resolve-work-dir.js";
26
26
  class SharedHmrManager {
27
27
  appConfig;
28
28
  bridge;
@@ -90,10 +90,9 @@ class SharedHmrManager {
90
90
  getEntrypointDependencyGraph: () => this.entrypointDependencyGraph,
91
91
  shouldProcessEntrypoint: (entrypointPath) => this.shouldJsStrategyProcessEntrypoint(entrypointPath)
92
92
  };
93
- const invalidationService = new DevelopmentInvalidationService(this.appConfig);
94
93
  this.strategies = [
95
94
  new JsHmrStrategy(jsContext),
96
- new ServerRenderedTemplateHmrStrategy(invalidationService),
95
+ new ServerRenderedTemplateHmrStrategy(this.invalidationService),
97
96
  new DefaultHmrStrategy()
98
97
  ];
99
98
  }
@@ -319,6 +318,33 @@ class SharedHmrManager {
319
318
  getWatchedFiles() {
320
319
  return this.entrypointRegistrar.getWatchedFiles();
321
320
  }
321
+ tryHandleAssetRequest(request) {
322
+ const url = new URL(request.url);
323
+ if (url.pathname === "/_hmr_runtime.js") {
324
+ const runtimePath = this.getRuntimePath();
325
+ if (fileSystem.exists(runtimePath)) {
326
+ return new Response(fileSystem.readFileAsBuffer(runtimePath), {
327
+ headers: {
328
+ "Content-Type": "application/javascript",
329
+ "Cache-Control": "no-store, must-revalidate"
330
+ }
331
+ });
332
+ }
333
+ }
334
+ if (url.pathname.startsWith("/assets/_hmr/")) {
335
+ const relativePath = url.pathname.slice("/assets/_hmr/".length);
336
+ const assetPath = path.join(this.distDir, relativePath);
337
+ if (fileSystem.exists(assetPath)) {
338
+ return new Response(fileSystem.readFileAsBuffer(assetPath), {
339
+ headers: {
340
+ "Content-Type": "application/javascript",
341
+ "Cache-Control": "no-store, must-revalidate"
342
+ }
343
+ });
344
+ }
345
+ }
346
+ return null;
347
+ }
322
348
  getDistDir() {
323
349
  return this.distDir;
324
350
  }
@@ -0,0 +1,23 @@
1
+ import type { SchemaValidationService } from '../../../services/validation/schema-validation-service.js';
2
+ import type { ApiHandler, CacheInvalidator, ErrorHandler, RenderContext } from '../../../types/public-types.js';
3
+ export type ApiRequestPipelineOptions = {
4
+ schemaValidator: SchemaValidationService;
5
+ getRenderContext: () => RenderContext;
6
+ getCacheService: () => CacheInvalidator | null;
7
+ };
8
+ export declare class ApiRequestPipeline<TRequest extends Request = Request, TServer = unknown> {
9
+ private readonly schemaValidator;
10
+ private readonly getRenderContext;
11
+ private readonly getCacheService;
12
+ constructor(options: ApiRequestPipelineOptions);
13
+ match(request: TRequest, apiHandlers: ApiHandler<string, TRequest, TServer>[]): {
14
+ routeConfig: ApiHandler<string, TRequest, TServer>;
15
+ params: Record<string, string | string[]>;
16
+ } | null;
17
+ tryHandle(request: TRequest, apiHandlers: ApiHandler<string, TRequest, TServer>[], serverInstance: TServer | undefined, errorHandler?: ErrorHandler<TRequest, TServer>): Promise<Response | null>;
18
+ execute(request: TRequest, params: Record<string, string | string[]>, routeConfig: ApiHandler<string, TRequest, TServer>, serverInstance: TServer | undefined, errorHandler?: ErrorHandler<TRequest, TServer>): Promise<Response>;
19
+ private createContext;
20
+ private normalizeParams;
21
+ private applyRequestSchema;
22
+ private runMiddlewareChain;
23
+ }