@ecopages/core 0.2.0-alpha.53 → 0.2.0-alpha.55

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 (58) hide show
  1. package/README.md +2 -3
  2. package/package.json +34 -14
  3. package/src/adapters/bun/server-adapter.d.ts +7 -0
  4. package/src/adapters/bun/server-adapter.js +8 -3
  5. package/src/adapters/node/server-adapter.d.ts +1 -1
  6. package/src/adapters/node/server-adapter.js +2 -4
  7. package/src/build/README.md +57 -73
  8. package/src/build/browser-runtime-plugin-helpers.d.ts +26 -0
  9. package/src/build/browser-runtime-plugin-helpers.js +14 -0
  10. package/src/build/browser-runtime-plugin.d.ts +78 -0
  11. package/src/build/{browser-runtime-import-rewrite-plugin.js → browser-runtime-plugin.js} +49 -42
  12. package/src/build/build-adapter.d.ts +350 -93
  13. package/src/build/build-adapter.js +61 -492
  14. package/src/build/build-manifest.js +3 -6
  15. package/src/build/build-types.d.ts +2 -2
  16. package/src/build/rolldown-build-adapter.d.ts +32 -0
  17. package/src/build/rolldown-build-adapter.js +260 -0
  18. package/src/build/rolldown-plugin-bridge.d.ts +50 -0
  19. package/src/build/rolldown-plugin-bridge.js +194 -0
  20. package/src/build/runtime-build-executor.d.ts +14 -7
  21. package/src/build/runtime-build-executor.js +8 -11
  22. package/src/build/runtime-build-output-normalizer.d.ts +3 -0
  23. package/src/build/runtime-build-output-normalizer.js +111 -0
  24. package/src/build/serialized-build-executor.d.ts +64 -0
  25. package/src/build/serialized-build-executor.js +63 -0
  26. package/src/build/server-side-css-shim-plugin.d.ts +41 -0
  27. package/src/build/server-side-css-shim-plugin.js +35 -0
  28. package/src/cache/index.d.ts +6 -0
  29. package/src/cache/index.js +6 -0
  30. package/src/cache/module-parse-cache.d.ts +65 -0
  31. package/src/cache/module-parse-cache.js +75 -0
  32. package/src/config/README.md +1 -1
  33. package/src/config/config-builder.d.ts +3 -3
  34. package/src/config/config-builder.js +5 -14
  35. package/src/eco/eco.types.d.ts +2 -5
  36. package/src/hmr/strategies/js-hmr-strategy.d.ts +2 -2
  37. package/src/hmr/strategies/js-hmr-strategy.js +2 -2
  38. package/src/plugins/alias-resolver-cache.d.ts +68 -0
  39. package/src/plugins/alias-resolver-cache.js +106 -0
  40. package/src/plugins/alias-resolver-plugin.d.ts +4 -1
  41. package/src/plugins/alias-resolver-plugin.js +9 -5
  42. package/src/plugins/eco-component-meta-plugin.js +2 -2
  43. package/src/plugins/foreign-jsx-override-plugin.d.ts +1 -1
  44. package/src/route-renderer/orchestration/render-output.utils.d.ts +1 -1
  45. package/src/services/assets/browser-bundle.service.d.ts +1 -1
  46. package/src/services/module-loading/app-module-loader.service.d.ts +1 -1
  47. package/src/services/module-loading/app-server-module-transpiler.service.js +8 -29
  48. package/src/services/module-loading/page-module-import.service.js +2 -0
  49. package/src/types/internal-types.d.ts +1 -1
  50. package/src/build/browser-runtime-import-rewrite-plugin.d.ts +0 -26
  51. package/src/build/dev-build-coordinator.d.ts +0 -72
  52. package/src/build/dev-build-coordinator.js +0 -154
  53. package/src/build/esbuild-build-adapter.d.ts +0 -79
  54. package/src/build/esbuild-build-adapter.js +0 -521
  55. package/src/build/runtime-specifier-alias-plugin.d.ts +0 -15
  56. package/src/build/runtime-specifier-alias-plugin.js +0 -31
  57. package/src/services/module-loading/node-bootstrap-plugin.d.ts +0 -38
  58. package/src/services/module-loading/node-bootstrap-plugin.js +0 -215
@@ -1,5 +1,6 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
2
  import path from "node:path";
3
+ import { AliasResolverCache } from "./alias-resolver-cache.js";
3
4
  const RESOLVABLE_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mdx", ".css", ".scss", ".sass", ".less"];
4
5
  function findResolvablePath(candidate) {
5
6
  if (path.extname(candidate)) {
@@ -41,16 +42,19 @@ function resolveAppSourceAliasPath(srcDir, specifier) {
41
42
  const resolved = findResolvablePath(candidate);
42
43
  return resolved ? resolveAliasedBarrelTarget(resolved) : void 0;
43
44
  }
44
- function createAliasResolverPlugin(srcDir) {
45
+ function createAliasResolverPlugin(srcDir, options) {
46
+ const cache = options?.cache ?? new AliasResolverCache();
45
47
  return {
46
48
  name: "ecopages-alias-resolver",
47
49
  setup(build) {
48
50
  build.onResolve({ filter: /^@\// }, (args) => {
49
- const resolved = resolveAppSourceAliasPath(srcDir, args.path);
50
- if (resolved) {
51
- return { path: resolved };
51
+ const cached = cache.get(srcDir, args.path);
52
+ if (cached.hit) {
53
+ return cached.resolved ? { path: cached.resolved } : {};
52
54
  }
53
- return {};
55
+ const resolved = resolveAppSourceAliasPath(srcDir, args.path);
56
+ cache.set(srcDir, args.path, resolved);
57
+ return resolved ? { path: resolved } : {};
54
58
  });
55
59
  }
56
60
  };
@@ -1,4 +1,4 @@
1
- import { parseSync } from "oxc-parser";
1
+ import { cachedParseSync } from "../cache/module-parse-cache.js";
2
2
  import { rapidhash } from "../utils/hash.js";
3
3
  import {
4
4
  createEcoBuildPluginFromSourceTransform,
@@ -145,7 +145,7 @@ function findInjectionPoints(node, insertions, injection, isInsideEcoComponent =
145
145
  }
146
146
  }
147
147
  function injectEcoMeta(contents, filePath, integration) {
148
- const result = parseSync(filePath, contents);
148
+ const result = cachedParseSync(filePath, contents);
149
149
  if (result.errors.length > 0) {
150
150
  console.warn(`[eco-component-meta-plugin] Parse errors in ${filePath}:`, result.errors);
151
151
  return contents;
@@ -20,7 +20,7 @@ export interface ForeignJsxOverrideOptions {
20
20
  * another JSX integration (e.g. `.kita.tsx`), that file inherits the project
21
21
  * `tsconfig` JSX runtime which produces the wrong output (HTML strings instead
22
22
  * of framework elements). This plugin rewrites the source to explicitly target
23
- * the host's JSX factory so esbuild compiles every JSX expression into the
23
+ * the host's JSX factory so the bundler compiles every JSX expression into the
24
24
  * correct element creation calls.
25
25
  *
26
26
  * The plugin is intentionally framework-agnostic: any integration that does
@@ -48,7 +48,7 @@ export declare function addTriggerAttribute<T extends MarkupNodeLikeShape>(conte
48
48
  export declare function addTriggerAttribute(content: unknown, triggerId: string): string | TemplateContentShape | MarkupNodeLikeShape;
49
49
  /**
50
50
  * Wraps rendered component output in a `<scripts-injector>` element that
51
- * carries an inline injector map for the legacy (non-global-injector) path.
51
+ * carries an inline injector map for the component's lazy script groups.
52
52
  *
53
53
  * @param content Rendered component HTML.
54
54
  * @param lazyGroups Resolved lazy script groups attached to the component config.
@@ -2,7 +2,7 @@ import type { BuildResult, BuildTranspileProfile } from '../../build/build-adapt
2
2
  import type { EcoBuildPlugin } from '../../build/build-types.js';
3
3
  import type { EcoPagesAppConfig } from '../../types/internal-types.js';
4
4
  export type BrowserBundleOptions = {
5
- entrypoints: string[];
5
+ entrypoints: string[] | Record<string, string>;
6
6
  outdir?: string;
7
7
  outbase?: string;
8
8
  naming?: string;
@@ -1,5 +1,5 @@
1
1
  import type { PageModuleBuildImportOptions } from './page-module-import.service.js';
2
- export type AppModuleLoaderOwner = 'bun' | 'host';
2
+ export type AppModuleLoaderOwner = 'app' | 'host';
3
3
  export interface AppModuleLoader {
4
4
  readonly owner: AppModuleLoaderOwner;
5
5
  importModule<T = unknown>(options: PageModuleBuildImportOptions): Promise<T>;
@@ -1,9 +1,8 @@
1
- import { getAppBuildExecutor } from "../../build/build-adapter.js";
2
- import path from "node:path";
1
+ import { getAppBuildExecutor, getAppServerBuildPlugins } from "../../build/build-adapter.js";
3
2
  import { createForeignJsxOverridePlugin } from "../../plugins/foreign-jsx-override-plugin.js";
3
+ import path from "node:path";
4
4
  import { DevelopmentInvalidationService } from "../invalidation/development-invalidation.service.js";
5
5
  import {} from "./app-module-loader.service.js";
6
- import { createAppNodeBootstrapPlugin } from "./node-bootstrap-plugin.js";
7
6
  import { PageModuleImportService } from "./page-module-import.service.js";
8
7
  import { supportsSourceModuleLoading } from "./source-module-support.js";
9
8
  import { ServerModuleTranspiler } from "./server-module-transpiler.service.js";
@@ -30,7 +29,7 @@ function getAppHostModuleLoader(appConfig) {
30
29
  return appConfig.runtime?.hostModuleLoader;
31
30
  }
32
31
  function getAppModuleLoaderOwner(appConfig) {
33
- return getAppHostModuleLoader(appConfig) ? "host" : "bun";
32
+ return getAppHostModuleLoader(appConfig) ? "host" : "app";
34
33
  }
35
34
  function setAppHostModuleLoader(appConfig, hostModuleLoader) {
36
35
  appConfig.runtime = {
@@ -38,12 +37,7 @@ function setAppHostModuleLoader(appConfig, hostModuleLoader) {
38
37
  hostModuleLoader
39
38
  };
40
39
  }
41
- function getOwningIntegration(appConfig, filePath) {
42
- return appConfig.integrations?.flatMap(
43
- (integration) => integration.extensions.filter((extension) => filePath.endsWith(extension)).map((extension) => ({ integration, extension }))
44
- ).sort((left, right) => right.extension.length - left.extension.length)[0]?.integration;
45
- }
46
- function getBunOwnedJsxPlugins(appConfig) {
40
+ function getJsxOwnershipPlugins(appConfig) {
47
41
  const jsxExtensions = (appConfig.integrations ?? []).filter((integration) => integration.jsxImportSource).flatMap(
48
42
  (integration) => integration.extensions.filter((extension) => extension.endsWith(".tsx") || extension.endsWith(".jsx")).map((extension) => ({ integration, extension }))
49
43
  ).sort((left, right) => right.extension.length - left.extension.length);
@@ -52,7 +46,7 @@ function getBunOwnedJsxPlugins(appConfig) {
52
46
  hostJsxImportSource: integration.jsxImportSource,
53
47
  foreignExtensions: [extension],
54
48
  excludeExtensions: jsxExtensions.filter((candidate) => candidate.extension.length > extension.length).filter((candidate) => candidate.extension.endsWith(extension)).map((candidate) => candidate.extension),
55
- name: `ecopages-bun-jsx-ownership-${integration.name}-${extension.replace(/[^a-zA-Z0-9]+/g, "-")}`
49
+ name: `ecopages-jsx-ownership-${integration.name}-${extension.replace(/[^a-zA-Z0-9]+/g, "-")}`
56
50
  })
57
51
  );
58
52
  }
@@ -62,9 +56,8 @@ function createAppModuleLoader(appConfig) {
62
56
  canLoadSourceModuleFromHost: (filePath) => shouldAppUseHostModuleLoader(appConfig, filePath),
63
57
  getHostModuleLoader: () => getAppHostModuleLoader(appConfig)
64
58
  });
65
- const getDefaultPlugins = typeof Bun === "undefined" && appConfig.rootDir ? () => [createAppNodeBootstrapPlugin(appConfig)] : () => [];
66
- const appLoaderPlugins = Array.from(appConfig.loaders?.values() ?? []);
67
- const bunOwnedJsxPlugins = typeof Bun !== "undefined" ? getBunOwnedJsxPlugins(appConfig) : [];
59
+ const appServerBuildPlugins = appConfig.runtime?.buildManifest ? getAppServerBuildPlugins(appConfig) : Array.from(appConfig.loaders?.values() ?? []);
60
+ const jsxOwnershipPlugins = getJsxOwnershipPlugins(appConfig);
68
61
  const appModuleLoader = {
69
62
  get owner() {
70
63
  return getAppModuleLoaderOwner(appConfig);
@@ -72,24 +65,10 @@ function createAppModuleLoader(appConfig) {
72
65
  pageModuleImportService,
73
66
  async importModule(options) {
74
67
  const invalidationVersion = options.invalidationVersion ?? invalidationService.getServerModuleInvalidationVersion();
75
- const owningIntegration = getOwningIntegration(appConfig, options.filePath);
76
- const owningJsxImportSource = owningIntegration?.jsxImportSource;
77
- const mergedPlugins = [
78
- ...getDefaultPlugins(),
79
- ...appLoaderPlugins,
80
- ...bunOwnedJsxPlugins,
81
- ...options.plugins ?? []
82
- ];
68
+ const mergedPlugins = [...appServerBuildPlugins, ...jsxOwnershipPlugins, ...options.plugins ?? []];
83
69
  return await pageModuleImportService.importModule({
84
70
  ...options,
85
71
  ...mergedPlugins.length > 0 ? { plugins: mergedPlugins } : {},
86
- ...typeof Bun !== "undefined" && owningJsxImportSource ? {
87
- jsx: {
88
- development: process.env.NODE_ENV === "development",
89
- importSource: owningJsxImportSource,
90
- runtime: "automatic"
91
- }
92
- } : {},
93
72
  buildExecutor: options.buildExecutor ?? getAppBuildExecutor(appConfig),
94
73
  invalidationVersion
95
74
  });
@@ -2,6 +2,7 @@ import path from "node:path";
2
2
  import { pathToFileURL } from "node:url";
3
3
  import { fileSystem } from "@ecopages/file-system";
4
4
  import { build } from "../../build/build-adapter.js";
5
+ import { normalizeNodeRuntimeBuildOutputFile } from "../../build/runtime-build-output-normalizer.js";
5
6
  import { supportsSourceModuleLoading } from "./source-module-support.js";
6
7
  class PageModuleImportService {
7
8
  dependencies;
@@ -135,6 +136,7 @@ class PageModuleImportService {
135
136
  if (!compiledOutput) {
136
137
  throw new Error(noOutputMessage(filePath));
137
138
  }
139
+ normalizeNodeRuntimeBuildOutputFile(compiledOutput, rootDir);
138
140
  const compiledOutputUrl = pathToFileURL(compiledOutput);
139
141
  if (shouldAddRuntimeUpdateQuery(invalidationVersion, cacheScope)) {
140
142
  compiledOutputUrl.searchParams.set(
@@ -129,7 +129,7 @@ export type EcoPagesAppConfig = {
129
129
  loaders: Map<string, EcoBuildPlugin>;
130
130
  /**
131
131
  * App-owned source transforms that can be adapted into Vite or other
132
- * transform-first bundlers without going through the legacy loader bridge.
132
+ * transform-first bundlers.
133
133
  */
134
134
  sourceTransforms: Map<string, EcoSourceTransform>;
135
135
  /**
@@ -1,26 +0,0 @@
1
- import type { EcoBuildPlugin } from './build-types.js';
2
- import { type BrowserRuntimeManifest } from './browser-runtime-manifest.js';
3
- export declare const DEFAULT_BROWSER_RUNTIME_IMPORT_REWRITE_PLUGIN_NAME = "browser-runtime-import-rewrite";
4
- export type CreateBrowserRuntimeImportRewritePluginOptions = {
5
- /** Stable build plugin name used for deduplication and selective exclusion. */
6
- name?: string;
7
- /** Manifest containing specifier-to-public-URL runtime asset mappings. */
8
- manifest: BrowserRuntimeManifest;
9
- };
10
- /**
11
- * Rewrites static ESM import/export specifiers and string-literal dynamic imports
12
- * from manifest-owned runtime specifiers to concrete browser public URLs.
13
- */
14
- export declare function rewriteBrowserRuntimeImports(code: string, specifierMap: ReadonlyMap<string, string>, filePath?: string): string;
15
- export declare function getBrowserRuntimeImportRewriteMap(plugin: EcoBuildPlugin): ReadonlyMap<string, string> | undefined;
16
- export declare function collectBrowserRuntimeImportRewriteMap(plugins: EcoBuildPlugin[] | undefined): ReadonlyMap<string, string>;
17
- /**
18
- * Creates a build plugin that applies browser runtime manifest import rewrites
19
- * before the bundler resolves source modules.
20
- *
21
- * @remarks
22
- * This is the migration path away from browser import-map-style runtime aliases:
23
- * generated and authored browser modules can keep importing manifest-owned
24
- * specifiers, while the build turns those specifiers into concrete public URLs.
25
- */
26
- export declare function createBrowserRuntimeImportRewritePlugin(options: CreateBrowserRuntimeImportRewritePluginOptions): EcoBuildPlugin | null;
@@ -1,72 +0,0 @@
1
- import { type BuildAdapter, type BuildExecutor, type BuildOptions, type BuildResult } from './build-adapter.js';
2
- import { EsbuildBuildAdapter } from './esbuild-build-adapter.js';
3
- import type { EcoBuildPlugin } from './build-types.js';
4
- export declare function withBuildExecutorPlugins(executor: BuildExecutor, getPlugins: () => EcoBuildPlugin[]): BuildExecutor;
5
- /**
6
- * Serialized build coordinator for the shared esbuild adapter.
7
- *
8
- * The underlying adapter remains responsible for plain build execution. This
9
- * coordinator owns the policy that must be shared across callers while Bun-native
10
- * execution still uses the shared esbuild compatibility backend:
11
- *
12
- * - serialized access to the shared esbuild service
13
- * - recovery from known esbuild worker protocol faults
14
- *
15
- * Unlike the previous design, the coordinator does not monkey-patch the adapter
16
- * or install process-level fault handlers. The owning app/runtime passes this
17
- * executor explicitly to build consumers that need coordinated builds.
18
- */
19
- export declare class DevBuildCoordinator implements BuildExecutor {
20
- private buildQueue;
21
- private esbuildSessionWarm;
22
- private esbuildModuleGeneration;
23
- private readonly adapter;
24
- constructor(adapter: EsbuildBuildAdapter);
25
- /**
26
- * Executes a build through the serialized development queue.
27
- *
28
- * If an esbuild protocol fault is detected, the coordinator resets the queue,
29
- * stops the corrupted service, increments the module generation, and retries
30
- * the build once.
31
- */
32
- build(options: BuildOptions): Promise<BuildResult>;
33
- /**
34
- * Attempts recovery from a known esbuild worker protocol fault.
35
- *
36
- * Returns `true` only when the error matches the protocol-fault signature and
37
- * the coordinator successfully reset its shared state.
38
- */
39
- recoverFromProtocolFault(error: unknown): Promise<boolean>;
40
- /**
41
- * Clears internal coordinator state for isolated tests.
42
- */
43
- resetForTests(): void;
44
- /**
45
- * Overrides the internal queue promise for fault-recovery tests.
46
- */
47
- setBuildQueueForTests(queue: Promise<void>): void;
48
- /**
49
- * Returns the current internal queue promise for fault-recovery tests.
50
- */
51
- getBuildQueueForTests(): Promise<void>;
52
- private runSerialized;
53
- }
54
- /**
55
- * Creates the appropriate build executor for one app/runtime instance.
56
- *
57
- * Bun-native esbuild execution always uses the compatibility coordinator so
58
- * preview/static generation and development flows share the same serialized
59
- * access and protocol-fault recovery policy. Host-owned execution stays on the
60
- * plain adapter boundary.
61
- */
62
- export declare function createAppBuildExecutor(options: {
63
- development: boolean;
64
- adapter?: BuildAdapter;
65
- getPlugins?: () => EcoBuildPlugin[];
66
- }): BuildExecutor;
67
- export declare function createOrReuseAppBuildExecutor(options: {
68
- development: boolean;
69
- adapter?: BuildAdapter;
70
- currentExecutor?: BuildExecutor;
71
- getPlugins?: () => EcoBuildPlugin[];
72
- }): BuildExecutor;
@@ -1,154 +0,0 @@
1
- import { appLogger } from "../global/app-logger.js";
2
- import {
3
- defaultBunBuildAdapter
4
- } from "./build-adapter.js";
5
- import { EsbuildBuildAdapter, ESBUILD_ADAPTER_BRAND } from "./esbuild-build-adapter.js";
6
- import { mergeEcoBuildPlugins } from "./build-manifest.js";
7
- function isEsbuildBuildAdapter(adapter) {
8
- return adapter instanceof EsbuildBuildAdapter || typeof adapter === "object" && adapter !== null && adapter[ESBUILD_ADAPTER_BRAND] === true;
9
- }
10
- function mergeBuildPlugins(options, appPlugins) {
11
- if (appPlugins.length === 0) {
12
- return options;
13
- }
14
- return {
15
- ...options,
16
- plugins: mergeEcoBuildPlugins(options.plugins, appPlugins)
17
- };
18
- }
19
- class BuildExecutorWithPlugins {
20
- executor;
21
- getPlugins;
22
- constructor(executor, getPlugins) {
23
- this.executor = executor;
24
- this.getPlugins = getPlugins;
25
- }
26
- async build(options) {
27
- return await this.executor.build(mergeBuildPlugins(options, this.getPlugins()));
28
- }
29
- unwrap() {
30
- return this.executor;
31
- }
32
- }
33
- function unwrapBuildExecutor(executor) {
34
- if (executor instanceof BuildExecutorWithPlugins) {
35
- return unwrapBuildExecutor(executor.unwrap());
36
- }
37
- return executor;
38
- }
39
- function withBuildExecutorPlugins(executor, getPlugins) {
40
- return new BuildExecutorWithPlugins(executor, getPlugins);
41
- }
42
- class DevBuildCoordinator {
43
- buildQueue = Promise.resolve();
44
- esbuildSessionWarm = false;
45
- esbuildModuleGeneration = 0;
46
- adapter;
47
- constructor(adapter) {
48
- this.adapter = adapter;
49
- }
50
- /**
51
- * Executes a build through the serialized development queue.
52
- *
53
- * If an esbuild protocol fault is detected, the coordinator resets the queue,
54
- * stops the corrupted service, increments the module generation, and retries
55
- * the build once.
56
- */
57
- async build(options) {
58
- return this.runSerialized(async () => {
59
- try {
60
- const result = await this.adapter.buildOrThrow(options, this.esbuildModuleGeneration);
61
- this.esbuildSessionWarm = true;
62
- return result;
63
- } catch (error) {
64
- if (await this.recoverFromProtocolFault(error)) {
65
- appLogger.warn("Recovered from esbuild protocol fault. Retrying build.");
66
- try {
67
- const retry = await this.adapter.buildOrThrow(options, this.esbuildModuleGeneration);
68
- this.esbuildSessionWarm = true;
69
- return retry;
70
- } catch (retryError) {
71
- return this.adapter.createFailureResult(retryError);
72
- }
73
- }
74
- return this.adapter.createFailureResult(error);
75
- }
76
- });
77
- }
78
- /**
79
- * Attempts recovery from a known esbuild worker protocol fault.
80
- *
81
- * Returns `true` only when the error matches the protocol-fault signature and
82
- * the coordinator successfully reset its shared state.
83
- */
84
- async recoverFromProtocolFault(error) {
85
- if (!this.adapter.isEsbuildProtocolError(error)) {
86
- return false;
87
- }
88
- this.buildQueue = Promise.resolve();
89
- this.esbuildSessionWarm = false;
90
- await this.adapter.stopEsbuildService(this.esbuildModuleGeneration);
91
- this.esbuildModuleGeneration += 1;
92
- return true;
93
- }
94
- /**
95
- * Clears internal coordinator state for isolated tests.
96
- */
97
- resetForTests() {
98
- this.buildQueue = Promise.resolve();
99
- this.esbuildSessionWarm = false;
100
- this.esbuildModuleGeneration = 0;
101
- }
102
- /**
103
- * Overrides the internal queue promise for fault-recovery tests.
104
- */
105
- setBuildQueueForTests(queue) {
106
- this.buildQueue = queue;
107
- }
108
- /**
109
- * Returns the current internal queue promise for fault-recovery tests.
110
- */
111
- getBuildQueueForTests() {
112
- return this.buildQueue;
113
- }
114
- async runSerialized(operation) {
115
- let releaseBuild;
116
- const currentBuild = new Promise((resolve) => {
117
- releaseBuild = resolve;
118
- });
119
- const previousBuild = this.buildQueue;
120
- this.buildQueue = previousBuild.catch(() => void 0).then(async () => await currentBuild);
121
- await previousBuild.catch(() => void 0);
122
- try {
123
- return await operation();
124
- } finally {
125
- releaseBuild?.();
126
- }
127
- }
128
- }
129
- function createAppBuildExecutor(options) {
130
- const adapter = options.adapter ?? defaultBunBuildAdapter;
131
- const baseExecutor = isEsbuildBuildAdapter(adapter) ? new DevBuildCoordinator(adapter) : adapter;
132
- if (!options.getPlugins) {
133
- return baseExecutor;
134
- }
135
- return new BuildExecutorWithPlugins(baseExecutor, options.getPlugins);
136
- }
137
- function createOrReuseAppBuildExecutor(options) {
138
- const adapter = options.adapter ?? defaultBunBuildAdapter;
139
- const currentBaseExecutor = options.currentExecutor ? unwrapBuildExecutor(options.currentExecutor) : void 0;
140
- const baseExecutor = options.development && currentBaseExecutor instanceof DevBuildCoordinator ? currentBaseExecutor : createAppBuildExecutor({
141
- development: options.development,
142
- adapter
143
- });
144
- if (!options.getPlugins) {
145
- return baseExecutor;
146
- }
147
- return withBuildExecutorPlugins(baseExecutor, options.getPlugins);
148
- }
149
- export {
150
- DevBuildCoordinator,
151
- createAppBuildExecutor,
152
- createOrReuseAppBuildExecutor,
153
- withBuildExecutorPlugins
154
- };
@@ -1,79 +0,0 @@
1
- import type { BuildAdapter, BuildOptions, BuildResult, BuildTranspileOptions, BuildTranspileProfile } from './build-adapter.js';
2
- /**
3
- * Node build adapter backed by esbuild.
4
- *
5
- * This adapter keeps Ecopages build plugin compatibility (`onResolve`, `onLoad`,
6
- * and `module`) while delegating bundling and TypeScript/decorator transforms to esbuild.
7
- */
8
- export declare const ESBUILD_ADAPTER_BRAND: unique symbol;
9
- export declare class EsbuildBuildAdapter implements BuildAdapter {
10
- readonly ownership: "bun-native";
11
- readonly [ESBUILD_ADAPTER_BRAND] = true;
12
- private getJavaScriptOutExtension;
13
- private collectWorkspaceNodePaths;
14
- private getFallbackNodePaths;
15
- private rewriteBrowserRuntimeImportsInOutputs;
16
- private escapeRegExp;
17
- private getPluginsForBuild;
18
- private normalizeEsbuildLoader;
19
- private inferEsbuildLoaderFromPath;
20
- private convertLoadResultToModuleSource;
21
- private convertPluginOnLoadResult;
22
- private resolvePluginPath;
23
- /**
24
- * Creates an esbuild plugin bridge compatible with the existing Ecopages
25
- * plugin API shape.
26
- *
27
- * **Plugin ordering is semantically significant.**
28
- *
29
- * Esbuild applies `onResolve` and `onLoad` hooks in the order they are
30
- * registered: the first handler whose filter matches wins for `onResolve`,
31
- * and the first handler that returns a non-`undefined` result wins for
32
- * `onLoad`. Because we call `plugin.setup(bridge)` sequentially here, the
33
- * position of each plugin in the `plugins` array determines its priority:
34
- *
35
- * - **Index 0** has the highest priority (its hooks run first).
36
- * - **Last index** has the lowest priority (its hooks only run if no earlier
37
- * plugin claimed the path).
38
- *
39
- * When adding new integrations or processors, ensure security-critical plugins
40
- * (e.g. `ecopages-client-graph-boundary`) are placed **before** general-purpose
41
- * loaders in the array so they always get first refusal on every source file.
42
- *
43
- * There is currently no priority system or validation — correct ordering is
44
- * the caller's responsibility.
45
- */
46
- private createEcoPluginBridge;
47
- private loadEsbuildModule;
48
- private isMockedEsbuildModule;
49
- /**
50
- * Detects the subset of runtime faults that indicate esbuild's worker
51
- * protocol is corrupted rather than a normal build error.
52
- */
53
- isEsbuildProtocolError(error: unknown): boolean;
54
- stopEsbuildService(moduleGeneration?: number): Promise<void>;
55
- buildOrThrow(options: BuildOptions, moduleGeneration?: number): Promise<BuildResult>;
56
- private mapEsbuildSourcemap;
57
- private mapEsbuildFormat;
58
- private hasTemplateTokens;
59
- private toEntryNamePattern;
60
- private normalizeMetafilePath;
61
- private extractDependencyGraph;
62
- /**
63
- * Normalizes esbuild errors into Ecopages `BuildLog` entries.
64
- */
65
- private toBuildLogs;
66
- createFailureResult(error: unknown): BuildResult;
67
- /**
68
- * Bundles entrypoints using esbuild for Node runtime builds.
69
- */
70
- build(options: BuildOptions): Promise<BuildResult>;
71
- /**
72
- * Resolves module specifiers from a project root.
73
- */
74
- resolve(importPath: string, rootDir: string): string;
75
- /**
76
- * Returns transpile defaults for a known transpile profile.
77
- */
78
- getTranspileOptions(profile: BuildTranspileProfile): BuildTranspileOptions;
79
- }