@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,487 +1,38 @@
1
1
  import { mergeBrowserRuntimeManifests } from "./browser-runtime-manifest.js";
2
- import {
3
- collectBrowserRuntimeImportRewriteMap,
4
- rewriteBrowserRuntimeImports
5
- } from "./browser-runtime-import-rewrite-plugin.js";
2
+ import { normalizeNodeRuntimeBuildOutputs } from "./runtime-build-output-normalizer.js";
3
+ import { createForeignJsxOverridePlugin } from "../plugins/foreign-jsx-override-plugin.js";
6
4
  import {
7
5
  createAppBuildManifest,
8
6
  getBrowserBuildPlugins,
9
7
  getServerBuildPlugins
10
8
  } from "./build-manifest.js";
11
- import { EsbuildBuildAdapter } from "./esbuild-build-adapter.js";
12
- import { getBunRuntime } from "../utils/runtime.js";
13
- import fs from "node:fs";
14
- import path from "node:path";
15
- import { EsbuildBuildAdapter as EsbuildBuildAdapter2 } from "./esbuild-build-adapter.js";
16
- function transpileProfileToOptions(profile) {
17
- switch (profile) {
18
- case "browser-script":
19
- return {
20
- target: "browser",
21
- format: "esm",
22
- sourcemap: "none"
23
- };
24
- case "hmr-runtime":
25
- return {
26
- target: "browser",
27
- format: "esm",
28
- sourcemap: "none"
29
- };
30
- case "hmr-entrypoint":
31
- return {
32
- target: "browser",
33
- format: "esm",
34
- sourcemap: "none"
35
- };
36
- }
37
- }
38
- class BunBuildAdapter {
39
- ownership = "bun-native";
40
- fallbackAdapter = new EsbuildBuildAdapter();
41
- getPluginsForBuild(additionalPlugins) {
42
- const byName = /* @__PURE__ */ new Map();
43
- for (const plugin of additionalPlugins ?? []) {
44
- if (!byName.has(plugin.name)) {
45
- byName.set(plugin.name, plugin);
46
- }
47
- }
48
- return Array.from(byName.values());
49
- }
50
- escapeRegExp(value) {
51
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
52
- }
53
- resolvePluginPath(value, importer, contextRoot) {
54
- if (path.isAbsolute(value)) {
55
- return value;
56
- }
57
- if (value.startsWith(".") || value.startsWith("..")) {
58
- const baseDir = importer ? path.dirname(importer) : contextRoot;
59
- return path.resolve(baseDir, value);
60
- }
61
- return value;
62
- }
63
- inferLoaderFromPath(filePath) {
64
- const extension = path.extname(filePath).toLowerCase();
65
- switch (extension) {
66
- case ".ts":
67
- return "ts";
68
- case ".tsx":
69
- return "tsx";
70
- case ".jsx":
71
- return "jsx";
72
- case ".json":
73
- return "json";
74
- case ".css":
75
- return "css";
76
- default:
77
- return "js";
78
- }
79
- }
80
- normalizeBunLoader(loader) {
81
- switch (loader) {
82
- case "js":
83
- case "jsx":
84
- case "ts":
85
- case "tsx":
86
- case "json":
87
- case "toml":
88
- case "text":
89
- case "file":
90
- case "css":
91
- return loader;
92
- case "global-css":
93
- case "local-css":
94
- return "css";
95
- default:
96
- return void 0;
97
- }
98
- }
99
- convertLoadResultToModuleSource(result) {
100
- if (!result || typeof result !== "object") {
101
- return void 0;
102
- }
103
- const candidate = result;
104
- if (typeof candidate.contents === "string") {
105
- return candidate.contents;
106
- }
107
- if (candidate.loader === "object" && candidate.exports && typeof candidate.exports === "object") {
108
- return Object.entries(candidate.exports).map(
109
- ([key, value]) => key === "default" ? `export default ${JSON.stringify(value)};` : `export const ${key} = ${JSON.stringify(value)};`
110
- ).join("\n");
111
- }
112
- return void 0;
113
- }
114
- convertPluginOnLoadResult(args, result) {
115
- if (!result || typeof result !== "object") {
116
- return void 0;
117
- }
118
- const candidate = result;
119
- const sourceFromExports = candidate.loader === "object" && candidate.exports && typeof candidate.exports === "object" ? this.convertLoadResultToModuleSource(candidate) : void 0;
120
- if (sourceFromExports) {
121
- return {
122
- contents: sourceFromExports,
123
- loader: "js",
124
- ...typeof candidate.resolveDir === "string" ? { resolveDir: candidate.resolveDir } : {}
125
- };
126
- }
127
- if (typeof candidate.contents === "string" || candidate.contents instanceof Uint8Array) {
128
- return {
129
- contents: candidate.contents,
130
- loader: this.normalizeBunLoader(candidate.loader) ?? this.inferLoaderFromPath(args.path),
131
- ...typeof candidate.resolveDir === "string" ? { resolveDir: candidate.resolveDir } : {}
132
- };
133
- }
134
- return void 0;
135
- }
136
- createEcoPluginBridge(plugins, contextRoot) {
137
- return {
138
- name: "ecopages-plugin-bridge",
139
- setup: async (build2) => {
140
- let moduleCounter = 0;
141
- const bridge = {
142
- onResolve: (options, callback) => {
143
- build2.onResolve(options, async (args) => {
144
- const result = await callback({
145
- path: args.path,
146
- importer: args.importer,
147
- namespace: args.namespace
148
- });
149
- if (!result || typeof result !== "object") {
150
- return void 0;
151
- }
152
- return {
153
- ...typeof result.path === "string" ? { path: this.resolvePluginPath(result.path, args.importer, contextRoot) } : {},
154
- ...typeof result.namespace === "string" ? { namespace: result.namespace } : {},
155
- ...typeof result.external === "boolean" ? { external: result.external } : {}
156
- };
157
- });
158
- },
159
- onLoad: (options, callback) => {
160
- build2.onLoad(
161
- options,
162
- async (args) => this.convertPluginOnLoadResult(
163
- { path: args.path },
164
- await callback({
165
- path: args.path,
166
- namespace: args.namespace
167
- })
168
- )
169
- );
170
- },
171
- module: (specifier, callback) => {
172
- const namespace = `ecopages-module-${moduleCounter}`;
173
- moduleCounter += 1;
174
- const filter = new RegExp(`^${this.escapeRegExp(specifier)}$`);
175
- build2.onResolve({ filter }, async () => ({
176
- path: specifier,
177
- namespace
178
- }));
179
- build2.onLoad(
180
- { filter, namespace },
181
- async () => this.convertPluginOnLoadResult({ path: specifier }, await callback())
182
- );
183
- }
184
- };
185
- for (const plugin of plugins) {
186
- await plugin.setup(bridge);
187
- }
188
- }
189
- };
9
+ import { createRolldownBuildAdapter } from "./rolldown-build-adapter.js";
10
+ function mergeBuildExecutorPlugins(existing, appPlugins) {
11
+ if (!existing || existing.length === 0) {
12
+ return appPlugins;
190
13
  }
191
- toBuildLogs(error) {
192
- if (error instanceof Error) {
193
- return [{ message: error.message }];
194
- }
195
- return [{ message: "Unknown Bun build error" }];
196
- }
197
- mapBunTarget(value) {
198
- return value === "browser" ? "browser" : "bun";
199
- }
200
- mapBunFormat(value) {
201
- switch (value) {
202
- case "cjs":
203
- return "cjs";
204
- case "esm":
205
- default:
206
- return "esm";
207
- }
208
- }
209
- getOutputExtension(options, entrypointPath) {
210
- const entryExtension = path.extname(entrypointPath).toLowerCase();
211
- if (entryExtension === ".css") {
212
- return ".css";
213
- }
214
- if (entryExtension === ".json") {
215
- return ".json";
216
- }
217
- if (entryExtension === ".toml") {
218
- return ".toml";
219
- }
220
- if (options.target !== "browser") {
221
- if (options.format === "cjs") {
222
- return ".cjs";
223
- }
224
- if (options.format === "esm") {
225
- return ".mjs";
226
- }
227
- }
228
- return ".js";
14
+ const byName = /* @__PURE__ */ new Map();
15
+ for (const plugin of existing) {
16
+ byName.set(plugin.name, plugin);
229
17
  }
230
- resolveConcreteOutputPath(outputPath) {
231
- if (fs.existsSync(outputPath)) {
232
- return outputPath;
233
- }
234
- for (const extension of [".js", ".mjs", ".cjs"]) {
235
- const outputPathWithExtension = `${outputPath}${extension}`;
236
- if (fs.existsSync(outputPathWithExtension)) {
237
- return outputPathWithExtension;
238
- }
239
- }
240
- if (!outputPath.includes("[hash]")) {
241
- return outputPath;
242
- }
243
- const directory = path.dirname(outputPath);
244
- if (!fs.existsSync(directory)) {
245
- return void 0;
246
- }
247
- const basenamePattern = path.basename(outputPath);
248
- const matcher = new RegExp(`^${this.escapeRegExp(basenamePattern).replace(/\\\[hash\\\]/g, "(.+)")}$`);
249
- const matches = fs.readdirSync(directory).filter((candidate) => matcher.test(candidate)).sort();
250
- if (matches.length === 0) {
251
- return void 0;
252
- }
253
- return path.join(directory, matches[0]);
254
- }
255
- normalizePathForMatch(filePath) {
256
- return path.normalize(filePath).split(path.sep).join("/");
257
- }
258
- normalizeOutputPathForMatch(outputPath, templatePath) {
259
- const normalizedOutputPath = path.normalize(outputPath);
260
- const templateExtension = path.extname(templatePath);
261
- if (!templateExtension) {
262
- return normalizedOutputPath;
263
- }
264
- if (templateExtension === ".js") {
265
- if (this.hasJavaScriptExtension(normalizedOutputPath)) {
266
- return path.normalize(normalizedOutputPath.replace(/\.(?:[cm]?js)$/u, ".js"));
267
- }
268
- return path.normalize(`${normalizedOutputPath}.js`);
269
- }
270
- if (normalizedOutputPath.endsWith(templateExtension)) {
271
- return normalizedOutputPath;
272
- }
273
- return path.normalize(`${normalizedOutputPath}${templateExtension}`);
18
+ for (const plugin of appPlugins) {
19
+ byName.set(plugin.name, plugin);
274
20
  }
275
- extractTemplateHashTokens(templatePath, candidatePath) {
276
- const normalizedTemplatePath = this.normalizePathForMatch(templatePath);
277
- const normalizedCandidatePath = this.normalizePathForMatch(
278
- this.normalizeOutputPathForMatch(candidatePath, templatePath)
279
- );
280
- const matcher = new RegExp(
281
- `^${this.escapeRegExp(normalizedTemplatePath).replace(/\\\[hash\\\]/g, "([^/]+)")}$`
282
- );
283
- const match = normalizedCandidatePath.match(matcher);
284
- if (!match) {
285
- return void 0;
286
- }
287
- return match.slice(1);
288
- }
289
- applyTemplateHashTokens(templatePath, hashTokens) {
290
- const hashTokenCount = templatePath.match(/\[hash\]/g)?.length ?? 0;
291
- if (hashTokenCount !== hashTokens.length) {
292
- return void 0;
293
- }
294
- if (hashTokenCount === 0) {
295
- return templatePath;
296
- }
297
- let hashTokenIndex = 0;
298
- return templatePath.replace(/\[hash\]/g, () => hashTokens[hashTokenIndex++] ?? "");
299
- }
300
- resolveTemplatedOutputPath(options, entrypointPath) {
301
- if (!options.outdir) {
302
- return void 0;
303
- }
304
- const template = typeof options.naming === "string" ? options.naming : "[dir]/[name]";
305
- const outdir = path.resolve(options.outdir);
306
- const outputExtension = this.getOutputExtension(options, entrypointPath);
307
- const relativeBase = path.resolve(options.outbase ?? options.root ?? process.cwd());
308
- const relativeEntrypoint = path.relative(relativeBase, entrypointPath);
309
- const relativeDir = path.dirname(relativeEntrypoint);
310
- const dirToken = relativeDir === "." ? "" : relativeDir.split(path.sep).join("/");
311
- const nameToken = path.basename(relativeEntrypoint, path.extname(relativeEntrypoint));
312
- const extToken = outputExtension.replace(/^\./, "");
313
- let resolvedPath = template.replaceAll("[dir]", dirToken).replaceAll("[name]", nameToken).replaceAll("[ext]", extToken);
314
- if (outputExtension && !resolvedPath.endsWith(outputExtension)) {
315
- resolvedPath += outputExtension;
316
- }
317
- resolvedPath = resolvedPath.replace(/^\.\//, "");
318
- return path.join(outdir, resolvedPath);
319
- }
320
- relocateOutputFile(currentPath, targetPath) {
321
- if (currentPath === targetPath || !fs.existsSync(currentPath)) {
322
- return fs.existsSync(targetPath) ? targetPath : currentPath;
323
- }
324
- fs.mkdirSync(path.dirname(targetPath), { recursive: true });
325
- fs.rmSync(targetPath, { force: true });
326
- fs.renameSync(currentPath, targetPath);
327
- return targetPath;
328
- }
329
- hasJavaScriptExtension(outputPath) {
330
- return /\.(?:[cm]?js)$/u.test(outputPath);
331
- }
332
- rewriteBrowserRuntimeImportsInOutputs(result, plugins) {
333
- if (!result.success || result.outputs.length === 0) {
334
- return result;
335
- }
336
- const specifierMap = collectBrowserRuntimeImportRewriteMap(plugins);
337
- if (specifierMap.size === 0) {
338
- return result;
339
- }
340
- for (const output of result.outputs) {
341
- if (!this.hasJavaScriptExtension(output.path) || !fs.existsSync(output.path)) {
342
- continue;
343
- }
344
- const code = fs.readFileSync(output.path, "utf-8");
345
- const rewritten = rewriteBrowserRuntimeImports(code, specifierMap, output.path);
346
- if (rewritten !== code) {
347
- fs.writeFileSync(output.path, rewritten);
348
- }
349
- }
350
- return result;
351
- }
352
- findOutputMatchForEntrypoint(options, entrypointPath, outputs, usedOutputIndexes) {
353
- const expectedOutputPath = this.resolveTemplatedOutputPath(options, entrypointPath);
354
- if (!expectedOutputPath) {
355
- return void 0;
356
- }
357
- const expectedMatchPaths = [expectedOutputPath];
358
- if (options.outbase) {
359
- const bunRootRelativeOutputPath = this.resolveTemplatedOutputPath(
360
- { ...options, outbase: void 0 },
361
- entrypointPath
362
- );
363
- if (bunRootRelativeOutputPath && bunRootRelativeOutputPath !== expectedOutputPath) {
364
- expectedMatchPaths.push(bunRootRelativeOutputPath);
365
- }
366
- }
367
- for (const [outputIndex, output] of outputs.entries()) {
368
- if (usedOutputIndexes.has(outputIndex)) {
369
- continue;
370
- }
371
- for (const matchPath of expectedMatchPaths) {
372
- const hashTokens = this.extractTemplateHashTokens(matchPath, output.concretePath);
373
- if (!hashTokens) {
374
- continue;
375
- }
376
- const targetPath = this.applyTemplateHashTokens(expectedOutputPath, hashTokens);
377
- if (!targetPath) {
378
- continue;
379
- }
380
- usedOutputIndexes.add(outputIndex);
381
- return { outputIndex, targetPath };
382
- }
383
- }
384
- return void 0;
385
- }
386
- normalizeBunOutputs(result, options) {
387
- if (!result.success || result.outputs.length === 0) {
388
- return result;
389
- }
390
- const normalizedOutputs = result.outputs.map((output) => ({
391
- concretePath: this.resolveConcreteOutputPath(output.path) ?? output.path
392
- }));
393
- const matchedTargetsByIndex = /* @__PURE__ */ new Map();
394
- const usedOutputIndexes = /* @__PURE__ */ new Set();
395
- for (const entrypointPath of options.entrypoints) {
396
- const matchedOutput = this.findOutputMatchForEntrypoint(
397
- options,
398
- entrypointPath,
399
- normalizedOutputs,
400
- usedOutputIndexes
401
- );
402
- if (matchedOutput) {
403
- matchedTargetsByIndex.set(matchedOutput.outputIndex, matchedOutput.targetPath);
21
+ return Array.from(byName.values());
22
+ }
23
+ function withBuildExecutorPlugins(executor, getPlugins) {
24
+ return {
25
+ async build(options) {
26
+ const appPlugins = getPlugins();
27
+ if (appPlugins.length === 0) {
28
+ return executor.build(options);
404
29
  }
405
- }
406
- return {
407
- ...result,
408
- outputs: normalizedOutputs.map((output, index) => {
409
- const expectedOutputPath = matchedTargetsByIndex.get(index);
410
- const concreteOutputPath = output.concretePath;
411
- if (expectedOutputPath) {
412
- return {
413
- path: this.relocateOutputFile(concreteOutputPath, expectedOutputPath)
414
- };
415
- }
416
- if (this.hasJavaScriptExtension(concreteOutputPath)) {
417
- return {
418
- path: concreteOutputPath
419
- };
420
- }
421
- const normalizedPath = `${concreteOutputPath}.js`;
422
- return {
423
- path: this.relocateOutputFile(concreteOutputPath, normalizedPath)
424
- };
425
- })
426
- };
427
- }
428
- async build(options) {
429
- const bun = getBunRuntime();
430
- if (!bun) {
431
- return this.fallbackAdapter.build(options);
432
- }
433
- try {
434
- const contextRoot = options.root ? path.resolve(options.root) : process.cwd();
435
- const outdir = path.resolve(options.outdir ?? "dist/assets");
436
- const tsconfigPath = path.join(contextRoot, "tsconfig.json");
437
- const tsconfigExists = fs.existsSync(tsconfigPath);
438
- const plugins = this.getPluginsForBuild(options.plugins);
439
- const result = await bun.build({
440
- entrypoints: options.entrypoints,
441
- outdir,
442
- root: contextRoot,
443
- naming: typeof options.naming === "string" ? options.naming : void 0,
444
- define: options.define,
445
- external: options.external,
446
- format: this.mapBunFormat(options.format),
447
- target: this.mapBunTarget(options.target),
448
- sourcemap: options.sourcemap,
449
- splitting: !!options.splitting,
450
- minify: !!options.minify,
451
- packages: options.target !== "browser" && options.externalPackages !== false ? "external" : void 0,
452
- tsconfig: tsconfigExists ? tsconfigPath : void 0,
453
- jsx: options.jsx,
454
- plugins: plugins.length > 0 ? [this.createEcoPluginBridge(plugins, contextRoot)] : void 0
30
+ return executor.build({
31
+ ...options,
32
+ plugins: mergeBuildExecutorPlugins(options.plugins, appPlugins)
455
33
  });
456
- return this.rewriteBrowserRuntimeImportsInOutputs(
457
- this.normalizeBunOutputs(
458
- {
459
- success: result.success,
460
- logs: result.logs.map((log) => ({ message: log.message })),
461
- outputs: result.outputs.map((output) => ({ path: output.path }))
462
- },
463
- options
464
- ),
465
- plugins
466
- );
467
- } catch (error) {
468
- return {
469
- success: false,
470
- logs: this.toBuildLogs(error),
471
- outputs: []
472
- };
473
34
  }
474
- }
475
- resolve(importPath, rootDir) {
476
- const bun = getBunRuntime();
477
- if (!bun) {
478
- return this.fallbackAdapter.resolve(importPath, rootDir);
479
- }
480
- return bun.resolveSync(importPath, rootDir);
481
- }
482
- getTranspileOptions(profile) {
483
- return transpileProfileToOptions(profile);
484
- }
35
+ };
485
36
  }
486
37
  function createHostOwnedBuildError(methodName) {
487
38
  return new Error(
@@ -500,29 +51,26 @@ class ViteHostBuildAdapter {
500
51
  throw createHostOwnedBuildError("derive transpile options");
501
52
  }
502
53
  }
503
- function createBunBuildAdapter() {
504
- return new BunBuildAdapter();
505
- }
506
54
  function createViteHostBuildAdapter() {
507
55
  return new ViteHostBuildAdapter();
508
56
  }
509
57
  function createBuildAdapter(options) {
510
- switch (options?.ownership ?? "bun-native") {
58
+ switch (options?.ownership ?? "rolldown") {
511
59
  case "vite-host":
512
60
  return createViteHostBuildAdapter();
513
- case "bun-native":
61
+ case "rolldown":
514
62
  default:
515
- return createBunBuildAdapter();
63
+ return createRolldownBuildAdapter();
516
64
  }
517
65
  }
518
- const defaultBunBuildAdapter = createBuildAdapter({ ownership: "bun-native" });
66
+ const defaultRolldownBuildAdapter = createBuildAdapter({ ownership: "rolldown" });
519
67
  const defaultViteHostBuildAdapter = createBuildAdapter({ ownership: "vite-host" });
520
- const defaultBuildAdapter = defaultBunBuildAdapter;
521
- function getDefaultBuildAdapter(ownership = "bun-native") {
522
- return ownership === "vite-host" ? defaultViteHostBuildAdapter : defaultBunBuildAdapter;
68
+ const defaultBuildAdapter = defaultRolldownBuildAdapter;
69
+ function getDefaultBuildAdapter(ownership = "rolldown") {
70
+ return ownership === "vite-host" ? defaultViteHostBuildAdapter : defaultRolldownBuildAdapter;
523
71
  }
524
72
  function getBuildAdapterOwnership(buildAdapter) {
525
- return buildAdapter?.ownership ?? "bun-native";
73
+ return buildAdapter?.ownership ?? "rolldown";
526
74
  }
527
75
  function getAppBuildOwnership(appConfig) {
528
76
  return appConfig.runtime?.buildOwnership ?? getBuildAdapterOwnership(appConfig.runtime?.buildAdapter);
@@ -619,7 +167,22 @@ function getAppServerBuildPlugins(appConfig) {
619
167
  return getServerBuildPlugins(getAppBuildManifest(appConfig));
620
168
  }
621
169
  function getAppBrowserBuildPlugins(appConfig) {
622
- return getBrowserBuildPlugins(getAppBuildManifest(appConfig));
170
+ const manifest = getAppBuildManifest(appConfig);
171
+ const jsxOwnershipPlugins = collectJsxOwnershipPlugins(appConfig);
172
+ return [...getBrowserBuildPlugins(manifest), ...jsxOwnershipPlugins];
173
+ }
174
+ function collectJsxOwnershipPlugins(appConfig) {
175
+ const jsxExtensions = (appConfig.integrations ?? []).filter((integration) => integration.jsxImportSource).flatMap(
176
+ (integration) => integration.extensions.filter((extension) => extension.endsWith(".tsx") || extension.endsWith(".jsx")).map((extension) => ({ integration, extension }))
177
+ ).sort((left, right) => right.extension.length - left.extension.length);
178
+ return jsxExtensions.map(
179
+ ({ integration, extension }) => createForeignJsxOverridePlugin({
180
+ hostJsxImportSource: integration.jsxImportSource,
181
+ foreignExtensions: [extension],
182
+ excludeExtensions: jsxExtensions.filter((candidate) => candidate.extension.length > extension.length).filter((candidate) => candidate.extension.endsWith(extension)).map((candidate) => candidate.extension),
183
+ name: `ecopages-jsx-ownership-${integration.name}-${extension.replace(/[^a-zA-Z0-9]+/g, "-")}`
184
+ })
185
+ );
623
186
  }
624
187
  function getAppBuildExecutor(appConfig) {
625
188
  return appConfig.runtime?.buildExecutor ?? getAppBuildAdapter(appConfig);
@@ -630,27 +193,32 @@ function setAppBuildExecutor(appConfig, buildExecutor) {
630
193
  buildExecutor
631
194
  };
632
195
  }
633
- function build(options, executor = defaultBunBuildAdapter) {
634
- return executor.build(options);
196
+ function build(options, executor = defaultRolldownBuildAdapter) {
197
+ return executor.build(options).then((result) => {
198
+ if (result.success) {
199
+ normalizeNodeRuntimeBuildOutputs(
200
+ result.outputs.map((output) => output.path),
201
+ options.root ?? process.cwd()
202
+ );
203
+ }
204
+ return result;
205
+ });
635
206
  }
636
207
  function getTranspileOptions(profile) {
637
- return defaultBunBuildAdapter.getTranspileOptions(profile);
208
+ return defaultRolldownBuildAdapter.getTranspileOptions(profile);
638
209
  }
639
210
  function getAppTranspileOptions(appConfig, profile) {
640
211
  return getAppBuildAdapter(appConfig).getTranspileOptions(profile);
641
212
  }
642
213
  export {
643
- BunBuildAdapter,
644
- EsbuildBuildAdapter2 as EsbuildBuildAdapter,
645
214
  ViteHostBuildAdapter,
646
215
  build,
647
216
  collectConfiguredAppBuildManifestContributions,
648
217
  createBuildAdapter,
649
- createBunBuildAdapter,
650
218
  createConfiguredAppBuildManifest,
651
219
  createViteHostBuildAdapter,
652
220
  defaultBuildAdapter,
653
- defaultBunBuildAdapter,
221
+ defaultRolldownBuildAdapter,
654
222
  defaultViteHostBuildAdapter,
655
223
  getAppBrowserBuildPlugins,
656
224
  getAppBuildAdapter,
@@ -667,5 +235,6 @@ export {
667
235
  setAppBuildManifest,
668
236
  setAppBuildOwnership,
669
237
  setupAppRuntimePlugins,
670
- updateAppBuildManifest
238
+ updateAppBuildManifest,
239
+ withBuildExecutorPlugins
671
240
  };
@@ -1,7 +1,4 @@
1
- import {
2
- createBrowserRuntimeImportRewritePlugin,
3
- DEFAULT_BROWSER_RUNTIME_IMPORT_REWRITE_PLUGIN_NAME
4
- } from "./browser-runtime-import-rewrite-plugin.js";
1
+ import { createBrowserRuntimePlugin, DEFAULT_BROWSER_RUNTIME_PLUGIN_NAME } from "./browser-runtime-plugin.js";
5
2
  import {
6
3
  createBrowserRuntimeManifest,
7
4
  mergeBrowserRuntimeManifests
@@ -32,8 +29,8 @@ function getServerBuildPlugins(manifest) {
32
29
  return mergeEcoBuildPlugins(manifest.loaderPlugins, manifest.runtimePlugins);
33
30
  }
34
31
  function getBrowserBuildPlugins(manifest) {
35
- const runtimeRewritePlugin = createBrowserRuntimeImportRewritePlugin({
36
- name: DEFAULT_BROWSER_RUNTIME_IMPORT_REWRITE_PLUGIN_NAME,
32
+ const runtimeRewritePlugin = createBrowserRuntimePlugin({
33
+ name: DEFAULT_BROWSER_RUNTIME_PLUGIN_NAME,
37
34
  manifest: getBrowserRuntimeManifest(manifest)
38
35
  });
39
36
  return mergeEcoBuildPlugins(
@@ -22,7 +22,7 @@ export type EcoBuildOnLoadArgs = {
22
22
  namespace?: string;
23
23
  };
24
24
  /**
25
- * Loader kinds supported across Bun/esbuild bridge points.
25
+ * Loader kinds supported by the build plugin contract.
26
26
  */
27
27
  export type EcoBuildLoader = 'base64' | 'binary' | 'copy' | 'css' | 'dataurl' | 'empty' | 'file' | 'global-css' | 'js' | 'json' | 'jsx' | 'local-css' | 'object' | 'text' | 'ts' | 'tsx';
28
28
  /**
@@ -35,7 +35,7 @@ export type EcoBuildOnLoadResult = {
35
35
  resolveDir?: string;
36
36
  };
37
37
  /**
38
- * Shared plugin builder contract used by Ecopages across Bun and esbuild.
38
+ * Plugin builder contract consumed by build adapters.
39
39
  */
40
40
  export interface EcoBuildPluginBuilder {
41
41
  onResolve(options: {
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Bundler-backed build adapter.
3
+ *
4
+ * @remarks
5
+ * Implements {@link BuildAdapter} on top of the bundler. This is the
6
+ * default adapter installed by `ConfigBuilder` and the only adapter
7
+ * that issues real builds in production.
8
+ *
9
+ * Responsibilities:
10
+ *
11
+ * - Map {@link BuildOptions} to the bundler's native options and
12
+ * return a {@link BuildResult} (outputs + dependency graph).
13
+ * - Translate the runtime-agnostic `EcoBuildPlugin[]` via the bundled
14
+ * plugin bridge, preserving plugin-priority order by giving each
15
+ * plugin its own slot.
16
+ * - Run the browser-runtime-import rewriter against the emitted
17
+ * JavaScript outputs when the manifest declares a rewrite map.
18
+ *
19
+ * Module graph extraction: the bundler groups modules per chunk, so
20
+ * the per-chunk module list is read directly. The
21
+ * `BuildDependencyGraph.entrypoints` shape is preserved so HMR
22
+ * invalidation and the build manifest keep working without changes.
23
+ */
24
+ import type { BuildAdapter, BuildOptions, BuildResult, BuildTranspileOptions, BuildTranspileProfile } from './build-adapter.js';
25
+ export declare class RolldownBuildAdapter implements BuildAdapter {
26
+ readonly ownership: "rolldown";
27
+ buildOrThrow(options: BuildOptions): Promise<BuildResult>;
28
+ build(options: BuildOptions): Promise<BuildResult>;
29
+ resolve(importPath: string, rootDir: string): string;
30
+ getTranspileOptions(profile: BuildTranspileProfile): BuildTranspileOptions;
31
+ }
32
+ export declare function createRolldownBuildAdapter(): BuildAdapter;